gui/dialogs/game_load.cpp

Go to the documentation of this file.
00001 /* $Id: game_load.cpp 54210 2012-05-18 20:11:11Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2008 - 2012 by Jörg Hinrichs <joerg.hinrichs@alice-dsl.de>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
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 /*WIKI
00050  * @page = GUIWindowDefinitionWML
00051  * @order = 2_game_load
00052  *
00053  * == Load a game ==
00054  *
00055  * This shows the dialog to select and load a savegame file.
00056  *
00057  * @begin{table}{dialog_widgets}
00058  *
00059  * txtFilter & & text & m &
00060  *         The filter for the listbox items. $
00061  *
00062  * savegame_list & & listbox & m &
00063  *         List of savegames. $
00064  *
00065  * -filename & & control & m &
00066  *         Name of the savegame. $
00067  *
00068  * -date & & control & o &
00069  *         Date the savegame was created. $
00070  *
00071  * preview_pane & & widget & m &
00072  *         Container widget or grid that contains the items for a preview. The
00073  *         visible status of this container depends on whether or not something
00074  *         is selected. $
00075  *
00076  * -minimap & & minimap & m &
00077  *         Minimap of the selected savegame. $
00078  *
00079  * -imgLeader & & image & m &
00080  *         The image of the leader in the selected savegame. $
00081  *
00082  * -lblScenario & & label & m &
00083  *         The name of the scenario of the selected savegame. $
00084  *
00085  * -lblSummary & & label & m &
00086  *         Summary of the selected savegame. $
00087  *
00088  * @end{table}
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& /*video*/, 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                     // one word doesn't match, we don't reach words.end()
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         // FIXME: Find a better way to change the label width
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                 // Fallback to nontranslatable campaign id.
00288                 symbols["campaign_name"] = "(" + campaign_id + ")";
00289             }
00290             str << vgettext("Campaign: $campaign_name", symbols);
00291 
00292             // Display internal id for debug purposes if we didn't above
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         // See if we should ask the user for deletion confirmation
00333         if(preferences::ask_delete_saves()) {
00334             if(!gui2::tgame_delete::execute(window.video())) {
00335                 return;
00336             }
00337         }
00338 
00339         // Delete the file
00340         savegame::delete_game(games_[index].name());
00341 
00342         // Remove it from the list of saves
00343         games_.erase(games_.begin() + index);
00344         list.remove_row(index);
00345 
00346         display_savegame(window);
00347     }
00348 }
00349 
00350 } // namespace gui2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:02:58 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs