initial commit, lordsawar source, slightly modified
[lordsawar] / src / gui / load-scenario-dialog.cpp
1 //  Copyright (C) 2007 Ole Laursen
2 //  Copyright (C) 2007, 2008, 2009 Ben Asselstine
3 //
4 //  This program is free software; you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation; either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU Library General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program; if not, write to the Free Software
16 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
17 //  02110-1301, USA.
18
19 #include <config.h>
20 #include <list>
21 #include <fstream>
22 #include <sigc++/functors/mem_fun.h>
23 #include <gtkmm.h>
24
25 #include "load-scenario-dialog.h"
26 #include "glade-helpers.h"
27 #include "ucompose.hpp"
28 #include "defs.h"
29 #include "Configuration.h"
30 #include "File.h"
31 #include "GameScenario.h"
32
33 LoadScenarioDialog::LoadScenarioDialog()
34 {
35   Glib::RefPtr<Gtk::Builder> xml
36     = Gtk::Builder::create_from_file(get_glade_path()
37                                 + "/load-scenario-dialog.ui");
38
39   xml->get_widget("dialog", dialog);
40   decorate(dialog);
41   window_closed.connect(sigc::mem_fun(dialog, &Gtk::Dialog::hide));
42
43   xml->get_widget("description_textview", description_textview);
44   xml->get_widget("load_button", load_button);
45   xml->get_widget("num_players_label", num_players_label);
46   xml->get_widget("num_cities_label", num_cities_label);
47
48   scenarios_list = Gtk::ListStore::create(scenarios_columns);
49   xml->get_widget("treeview", scenarios_treeview);
50   scenarios_treeview->set_model(scenarios_list);
51   scenarios_treeview->append_column("", scenarios_columns.name);
52
53   xml->get_widget("add_scenario_button", add_scenario_button);
54   add_scenario_button->signal_clicked().connect
55     (sigc::mem_fun(*this, &LoadScenarioDialog::on_add_scenario_clicked));
56   xml->get_widget("remove_scenario_button", remove_scenario_button);
57   remove_scenario_button->signal_clicked().connect
58     (sigc::mem_fun(*this, &LoadScenarioDialog::on_remove_scenario_clicked));
59
60   scenarios_treeview->get_selection()->signal_changed()
61     .connect(sigc::mem_fun(this, &LoadScenarioDialog::on_selection_changed));
62   // add the scenarios
63   add_scenario("random.map");
64   std::list<std::string> lm = File::scanMaps();
65   for (std::list<std::string>::iterator i = lm.begin(), end = lm.end();
66        i != end; ++i)
67     add_scenario(File::getMapFile(*i));
68   lm.clear();
69   lm = File::scanUserMaps();
70   for (std::list<std::string>::iterator i = lm.begin(), end = lm.end();
71        i != end; ++i)
72     add_scenario(File::getUserMapFile(*i));
73
74
75   Gtk::TreeModel::Row row;
76   row = scenarios_treeview->get_model()->children()[0];
77   if(row)
78     scenarios_treeview->get_selection()->select(row);
79 }
80
81 LoadScenarioDialog::~LoadScenarioDialog()
82 {
83   delete dialog;
84 }
85
86 void LoadScenarioDialog::set_parent_window(Gtk::Window &parent)
87 {
88   dialog->set_transient_for(parent);
89   //dialog->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
90 }
91
92 void LoadScenarioDialog::hide()
93 {
94   dialog->hide();
95 }
96
97 void LoadScenarioDialog::run()
98 {
99   static int width = -1;
100   static int height = -1;
101
102   if (width != -1 && height != -1)
103     dialog->set_default_size(width, height);
104
105   dialog->show();
106   int response = dialog->run();
107   if (response != Gtk::RESPONSE_ACCEPT)
108     selected_filename = "";
109
110   dialog->get_size(width, height);
111 }
112
113 std::string LoadScenarioDialog::get_scenario_filename() 
114 {
115   return selected_filename;
116 }
117
118 void LoadScenarioDialog::add_scenario(std::string filename)
119 {
120   Gtk::TreeIter i = scenarios_list->append();
121   (*i)[scenarios_columns.filename] = filename;
122   if (filename == "random.map") 
123     {
124       (*i)[scenarios_columns.name] = _("Random Scenario");
125       return;
126     }
127   bool broken = false;
128   std::string name = "", comment = "";
129   guint32 player_count = 0, city_count = 0;
130   selected_filename = std::string((*i)[scenarios_columns.filename]);
131   GameScenario::loadDetails(selected_filename, broken, player_count, city_count, name, comment);
132   if (broken == false)
133     (*i)[scenarios_columns.name] = name;
134 }
135
136 void LoadScenarioDialog::on_selection_changed()
137 {
138   Gtk::TreeIter i = scenarios_treeview->get_selection()->get_selected();
139
140   if (i)
141     {
142       std::string filename = (*i)[scenarios_columns.filename];
143       if (filename == "random.map")
144         {
145           load_button->set_sensitive(true);
146           description_textview->get_buffer()->set_text(_("Play a new scenario with a random map.  You get to decide the number of players, and number of cities on the map.  You can also control the amount of the map that is covered in forest, water, swamps and mountains."));
147           num_players_label->set_markup (String::ucompose("<b>--</b>", ""));
148           num_cities_label->set_markup(String::ucompose("<b>--</b>", ""));
149           remove_scenario_button->set_sensitive(false);
150           load_button->set_sensitive(true);
151           selected_filename = filename;
152           return;
153         }
154
155       selected_filename = filename;
156       bool broken = false;
157       std::string name, comment;
158       guint32 player_count = 0, city_count = 0;
159       GameScenario::loadDetails(filename, broken, player_count, city_count, name, comment);
160
161       if (broken == true)
162         {
163           std::cerr << "Error: Could not parse " << selected_filename << std::endl;
164           load_button->set_sensitive(false);
165           return;
166         }
167           
168       remove_scenario_button->set_sensitive(true);
169       load_button->set_sensitive(true);
170       num_players_label->set_markup 
171         ("<b>" + String::ucompose("%1", player_count - 1) + "</b>");
172       num_cities_label->set_markup 
173         ("<b>" + String::ucompose("%1", city_count) + "</b>");
174       description_textview->get_buffer()->set_text(comment);
175     }
176   else
177     load_button->set_sensitive(false);
178 }
179
180 void LoadScenarioDialog::on_add_scenario_clicked() 
181 {
182   // go get a .map file from somewhere.
183   Gtk::FileChooserDialog *load_map_filechooser = new 
184     Gtk::FileChooserDialog(_("Select a scenario file to add to the library"), 
185                            Gtk::FILE_CHOOSER_ACTION_OPEN);
186   load_map_filechooser->add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
187   load_map_filechooser->add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
188   load_map_filechooser->set_default_response(Gtk::RESPONSE_ACCEPT);
189   
190   Gtk::FileFilter map_filter;
191   map_filter.add_pattern("*.map");
192   map_filter.set_name(_("LordsAWar map files (*.map)"));
193   load_map_filechooser->set_current_folder(Glib::get_home_dir ());
194   load_map_filechooser->set_filter(map_filter);
195   int res = load_map_filechooser->run();
196   load_map_filechooser->hide();
197   if (res == Gtk::RESPONSE_ACCEPT) 
198     {
199       std::string filename = load_map_filechooser->get_filename();
200       std::string mapname = Glib::path_get_basename (filename);
201       // copy it into our ~/.lordsawar/ dir.
202       File::copy (filename, File::getUserMapFile(mapname));
203       // add it to the list
204       add_scenario(File::getUserMapFile(mapname));
205     }
206   delete load_map_filechooser;
207 }
208
209 void LoadScenarioDialog::on_remove_scenario_clicked() 
210 {
211   //remove THIS scenario.
212   //only highlight this button when we have something selected.
213
214   //erase the selected row from the treeview
215   //remove the scenario from the list of scenarios 
216   //delete the file, if we can.
217   Gtk::TreeIter i = scenarios_treeview->get_selection()->get_selected();
218   if (i)
219     {
220       std::string filename = (*i)[scenarios_columns.filename];
221       if (filename == "random.map")
222         return;
223       if (remove (filename.c_str()) == 0)
224         {
225           scenarios_list->erase(i);
226           description_textview->get_buffer()->set_text("");
227           num_players_label->set_text ("");
228           num_cities_label->set_text ("");
229         }
230     }
231   return;
232 }