00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #define GETTEXT_DOMAIN "wesnoth-lib"
00017
00018 #include "gui/dialogs/game_load.hpp"
00019
00020 #include "foreach.hpp"
00021 #include "formula_string_utils.hpp"
00022 #include "gettext.hpp"
00023 #include "game_config.hpp"
00024 #include "game_preferences.hpp"
00025 #include "gui/auxiliary/log.hpp"
00026 #include "gui/dialogs/field.hpp"
00027 #include "gui/dialogs/game_delete.hpp"
00028 #include "gui/dialogs/helper.hpp"
00029 #include "gui/widgets/button.hpp"
00030 #include "gui/widgets/image.hpp"
00031 #include "gui/widgets/label.hpp"
00032 #ifdef GUI2_EXPERIMENTAL_LISTBOX
00033 #include "gui/widgets/list.hpp"
00034 #else
00035 #include "gui/widgets/listbox.hpp"
00036 #endif
00037 #include "gui/widgets/minimap.hpp"
00038 #include "gui/widgets/settings.hpp"
00039 #include "gui/widgets/text_box.hpp"
00040 #include "gui/widgets/window.hpp"
00041 #include "language.hpp"
00042 #include "preferences_display.hpp"
00043
00044 #include <cctype>
00045 #include <boost/bind.hpp>
00046
00047 namespace gui2 {
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 REGISTER_DIALOG(game_load)
00092
00093 tgame_load::tgame_load(const config& cache_config)
00094 : txtFilter_(register_text("txtFilter", true))
00095 , chk_change_difficulty_(register_bool("change_difficulty", true))
00096 , chk_show_replay_(register_bool("show_replay", true))
00097 , chk_cancel_orders_(register_bool("cancel_orders", true))
00098 , filename_()
00099 , change_difficulty_(false)
00100 , show_replay_(false)
00101 , cancel_orders_(false)
00102 , games_()
00103 , cache_config_(cache_config)
00104 , last_words_()
00105 {
00106 }
00107
00108 void tgame_load::pre_show(CVideo& , twindow& window)
00109 {
00110 assert(txtFilter_);
00111
00112 find_widget<tminimap>(&window, "minimap", false).set_config(&cache_config_);
00113
00114 ttext_box* filter = find_widget<ttext_box>(
00115 &window, "txtFilter", false, true);
00116 window.keyboard_capture(filter);
00117 filter->set_text_changed_callback(boost::bind(
00118 &tgame_load::filter_text_changed, this, _1, _2));
00119
00120 tlistbox* list = find_widget<tlistbox>(
00121 &window, "savegame_list", false, true);
00122 window.keyboard_capture(list);
00123
00124 #ifdef GUI2_EXPERIMENTAL_LISTBOX
00125 connect_signal_notify_modified(*list, boost::bind(
00126 &tgame_load::list_item_clicked
00127 , *this
00128 , boost::ref(window)));
00129 #else
00130 list->set_callback_value_change(
00131 dialog_callback<tgame_load, &tgame_load::list_item_clicked>);
00132 #endif
00133
00134 {
00135 cursor::setter cur(cursor::WAIT);
00136 games_ = savegame::get_saves_list();
00137 }
00138 fill_game_list(window, games_);
00139
00140 connect_signal_mouse_left_click(
00141 find_widget<tbutton>(&window, "delete", false)
00142 , boost::bind(
00143 &tgame_load::delete_button_callback
00144 , this
00145 , boost::ref(window)));
00146
00147 display_savegame(window);
00148 }
00149
00150 void tgame_load::fill_game_list(twindow& window
00151 , std::vector<savegame::save_info>& games)
00152 {
00153 tlistbox& list = find_widget<tlistbox>(&window, "savegame_list", false);
00154 list.clear();
00155
00156 foreach(const savegame::save_info game, games) {
00157 std::map<std::string, string_map> data;
00158 string_map item;
00159
00160 item["label"] = game.name();
00161 data.insert(std::make_pair("filename", item));
00162
00163 item["label"] = game.format_time_summary();
00164 data.insert(std::make_pair("date", item));
00165
00166 list.add_row(data);
00167 }
00168 }
00169
00170 void tgame_load::list_item_clicked(twindow& window)
00171 {
00172 display_savegame(window);
00173 }
00174
00175 bool tgame_load::filter_text_changed(ttext_* textbox, const std::string& text)
00176 {
00177 twindow& window = *textbox->get_window();
00178
00179 tlistbox& list = find_widget<tlistbox>(&window, "savegame_list", false);
00180
00181 const std::vector<std::string> words = utils::split(text, ' ');
00182
00183 if (words == last_words_)
00184 return false;
00185 last_words_ = words;
00186
00187 std::vector<bool> show_items(list.get_item_count(), true);
00188
00189 if(!text.empty()) {
00190 for(unsigned int i = 0; i < list.get_item_count(); i++) {
00191 tgrid* row = list.get_row_grid(i);
00192
00193 tgrid::iterator it = row->begin();
00194 tlabel& filename_label =
00195 find_widget<tlabel>(*it, "filename", false);
00196
00197 bool found = false;
00198 foreach (const std::string& word, words){
00199 found = std::search(filename_label.label().str().begin()
00200 , filename_label.label().str().end()
00201 , word.begin(), word.end()
00202 , chars_equal_insensitive)
00203 != filename_label.label().str().end();
00204
00205 if (! found) {
00206
00207 break;
00208 }
00209 }
00210
00211 show_items[i] = found;
00212 }
00213 }
00214
00215 list.set_row_shown(show_items);
00216
00217 return false;
00218 }
00219
00220 void tgame_load::post_show(twindow& window)
00221 {
00222 change_difficulty_ = chk_change_difficulty_->get_widget_value(window);
00223 show_replay_ = chk_show_replay_->get_widget_value(window);
00224 cancel_orders_ = chk_cancel_orders_->get_widget_value(window);
00225 }
00226
00227 void tgame_load::display_savegame(twindow& window)
00228 {
00229 const int selected_row =
00230 find_widget<tlistbox>(&window, "savegame_list", false)
00231 .get_selected_row();
00232
00233 twidget& preview_pane =
00234 find_widget<twidget>(&window, "preview_pane", false);
00235
00236 if(selected_row == -1) {
00237 preview_pane.set_visible(twidget::HIDDEN);
00238 } else {
00239 preview_pane.set_visible(twidget::VISIBLE);
00240
00241 savegame::save_info& game = games_[selected_row];
00242 filename_ = game.name();
00243
00244 const config& summary = game.summary();
00245
00246 find_widget<timage>(&window, "imgLeader", false).
00247 set_label(summary["leader_image"]);
00248
00249 find_widget<tminimap>(&window, "minimap", false).
00250 set_map_data(summary["map_data"]);
00251
00252 find_widget<tlabel>(&window, "lblScenario", false).set_label(game.name());
00253
00254 std::stringstream str;
00255 str << game.format_time_local();
00256 evaluate_summary_string(str, summary);
00257
00258 find_widget<tlabel>(&window, "lblSummary", false).set_label(str.str());
00259
00260
00261 window.invalidate_layout();
00262 }
00263 }
00264
00265 void tgame_load::evaluate_summary_string(std::stringstream& str
00266 , const config& cfg_summary){
00267
00268 const std::string& campaign_type = cfg_summary["campaign_type"];
00269 if (cfg_summary["corrupt"].to_bool()) {
00270 str << "\n" << _("#(Invalid)");
00271 } else if (!campaign_type.empty()) {
00272 str << "\n";
00273
00274 if(campaign_type == "scenario") {
00275 const std::string campaign_id = cfg_summary["campaign"];
00276 const config *campaign = NULL;
00277 if (!campaign_id.empty()) {
00278 if (const config &c = cache_config_.find_child(
00279 "campaign", "id", campaign_id))
00280
00281 campaign = &c;
00282 }
00283 utils::string_map symbols;
00284 if (campaign != NULL) {
00285 symbols["campaign_name"] = (*campaign)["name"];
00286 } else {
00287
00288 symbols["campaign_name"] = "(" + campaign_id + ")";
00289 }
00290 str << vgettext("Campaign: $campaign_name", symbols);
00291
00292
00293 if (game_config::debug && (campaign != NULL)) {
00294 str << '\n' << "(" << campaign_id << ")";
00295 }
00296 } else if(campaign_type == "multiplayer") {
00297 str << _("Multiplayer");
00298 } else if(campaign_type == "tutorial") {
00299 str << _("Tutorial");
00300 } else if(campaign_type == "test") {
00301 str << _("Test scenario");
00302 } else {
00303 str << campaign_type;
00304 }
00305
00306 str << "\n";
00307
00308 if (cfg_summary["replay"].to_bool() && !cfg_summary["snapshot"].to_bool(true)) {
00309 str << _("Replay");
00310 } else if (!cfg_summary["turn"].empty()) {
00311 str << _("Turn") << " " << cfg_summary["turn"];
00312 } else {
00313 str << _("Scenario start");
00314 }
00315
00316 str << "\n" << _("Difficulty: ")
00317 << string_table[cfg_summary["difficulty"]];
00318
00319 if(!cfg_summary["version"].empty()) {
00320 str << "\n" << _("Version: ") << cfg_summary["version"];
00321 }
00322 }
00323 }
00324
00325 void tgame_load::delete_button_callback(twindow& window)
00326 {
00327 tlistbox& list = find_widget<tlistbox>(&window, "savegame_list", false);
00328
00329 const size_t index = size_t(list.get_selected_row());
00330 if(index < games_.size()) {
00331
00332
00333 if(preferences::ask_delete_saves()) {
00334 if(!gui2::tgame_delete::execute(window.video())) {
00335 return;
00336 }
00337 }
00338
00339
00340 savegame::delete_game(games_[index].name());
00341
00342
00343 games_.erase(games_.begin() + index);
00344 list.remove_row(index);
00345
00346 display_savegame(window);
00347 }
00348 }
00349
00350 }