initial commit, lordsawar source, slightly modified
[lordsawar] / src / editor / ruin-editor-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
21 #include <sigc++/functors/mem_fun.h>
22 #include <gtkmm.h>
23
24 #include "ruin-editor-dialog.h"
25
26 #include "glade-helpers.h"
27 #include "ucompose.hpp"
28 #include "playerlist.h"
29 #include "CreateScenarioRandomize.h"
30 #include "defs.h"
31 #include "ruin.h"
32 #include "stack.h"
33 #include "army.h"
34 #include "reward.h"
35
36 #include "select-army-dialog.h"
37 #include "select-reward-dialog.h"
38 #include "reward-editor-dialog.h"
39 #include "RenamableLocation.h"
40
41 RuinEditorDialog::RuinEditorDialog(Ruin *r, CreateScenarioRandomize *randomizer)
42 {
43     d_randomizer = randomizer;
44     ruin = r;
45     reward = NULL;
46     
47     // copy occupant to be able to undo if the dialog is cancelled
48     Stack *occupant = ruin->getOccupant();
49     if (occupant)
50         keeper = new Stack(*occupant);
51     else
52         keeper = new Stack(0, ruin->getPos());
53     
54     Glib::RefPtr<Gtk::Builder> xml
55         = Gtk::Builder::create_from_file(get_glade_path()
56                                     + "/ruin-editor-dialog.ui");
57
58     xml->get_widget("dialog", dialog);
59
60     xml->get_widget("name_entry", name_entry);
61     name_entry->set_text(ruin->getName());
62     xml->get_widget("description_entry", description_entry);
63     description_entry->set_text(ruin->getDescription());
64
65     xml->get_widget("type_entry", type_entry);
66     type_entry->set_value(ruin->getType());
67
68     xml->get_widget("keeper_button", keeper_button);
69     keeper_button->signal_clicked().connect(
70         sigc::mem_fun(this, &RuinEditorDialog::on_keeper_clicked));
71
72     xml->get_widget("clear_keeper_button", clear_keeper_button);
73     clear_keeper_button->signal_clicked().connect(
74         sigc::mem_fun(this, &RuinEditorDialog::on_clear_keeper_clicked));
75
76     xml->get_widget("randomize_name_button", randomize_name_button);
77     randomize_name_button->signal_clicked().connect(
78         sigc::mem_fun(this, &RuinEditorDialog::on_randomize_name_clicked));
79
80     xml->get_widget("randomize_keeper_button", randomize_keeper_button);
81     randomize_keeper_button->signal_clicked().connect(
82         sigc::mem_fun(this, &RuinEditorDialog::on_randomize_keeper_clicked));
83
84     set_keeper_name();
85     xml->get_widget("sage_checkbutton", sage_button);
86     sage_button->set_active(ruin->hasSage());
87    
88     xml->get_widget("hidden_checkbutton", hidden_button);
89     hidden_button->set_active(ruin->isHidden());
90     hidden_button->signal_toggled().connect(
91             sigc::mem_fun(this, &RuinEditorDialog::on_hidden_toggled));
92     // setup the player combo
93     player_combobox = manage(new Gtk::ComboBoxText);
94
95     int c = 0, player_no = 0;
96     for (Playerlist::iterator i = Playerlist::getInstance()->begin(),
97              end = Playerlist::getInstance()->end(); i != end; ++i, ++c)
98     {
99         Player *player = *i;
100         player_combobox->append_text(player->getName());
101         if (player == ruin->getOwner())
102             player_no = c;
103     }
104
105     player_combobox->set_active(player_no);
106
107
108     Gtk::Alignment *alignment;
109     xml->get_widget("player_alignment", alignment);
110     alignment->add(*player_combobox);
111     on_hidden_toggled();
112
113     xml->get_widget("new_reward_hbox", new_reward_hbox);
114     xml->get_widget("new_reward_radiobutton", new_reward_radiobutton);
115     new_reward_radiobutton->signal_toggled().connect(
116         sigc::mem_fun(*this, &RuinEditorDialog::on_new_reward_toggled));
117     xml->get_widget("random_reward_radiobutton", random_reward_radiobutton);
118     random_reward_radiobutton->signal_toggled().connect(
119         sigc::mem_fun(*this, &RuinEditorDialog::on_random_reward_toggled));
120
121     xml->get_widget("reward_button", reward_button);
122     reward_button->signal_clicked().connect(
123         sigc::mem_fun(this, &RuinEditorDialog::on_reward_clicked));
124
125     xml->get_widget("clear_reward_button", clear_reward_button);
126     clear_reward_button->signal_clicked().connect(
127         sigc::mem_fun(this, &RuinEditorDialog::on_clear_reward_clicked));
128
129     xml->get_widget("randomize_reward_button", randomize_reward_button);
130     randomize_reward_button->signal_clicked().connect(
131         sigc::mem_fun(this, &RuinEditorDialog::on_randomize_reward_clicked));
132
133     xml->get_widget("reward_list_button", reward_list_button);
134     reward_list_button->signal_clicked().connect(
135         sigc::mem_fun(this, &RuinEditorDialog::on_reward_list_clicked));
136
137     if (ruin->getReward() == NULL)
138       random_reward_radiobutton->set_active(true);
139     else
140       {
141         reward = ruin->getReward();
142         new_reward_radiobutton->set_active(true);
143       }
144
145     set_reward_name();
146 }
147
148 RuinEditorDialog::~RuinEditorDialog()
149 {
150   delete dialog;
151 }
152 void RuinEditorDialog::set_parent_window(Gtk::Window &parent)
153 {
154     dialog->set_transient_for(parent);
155     //dialog->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
156 }
157
158 int RuinEditorDialog::run()
159 {
160     dialog->show_all();
161     int response = dialog->run();
162
163     if (response == Gtk::RESPONSE_ACCEPT)       // accepted
164     {
165         Location *l = ruin;
166         RenamableLocation *renamable_ruin = static_cast<RenamableLocation*>(l);
167         renamable_ruin->setName(name_entry->get_text());
168         renamable_ruin->setDescription(description_entry->get_text());
169         ruin->setType(type_entry->get_value_as_int());
170
171         // get rid of old occupant and insert new
172         Stack *occupant = ruin->getOccupant();
173         if (occupant)
174             delete occupant;
175
176         if (keeper->empty())
177         {
178             delete keeper;
179             keeper = 0;
180         }
181
182         ruin->setSage(sage_button->get_active());
183         if (sage_button->get_active() == false)
184           ruin->setOccupant(keeper);
185         ruin->setHidden(hidden_button->get_active());
186         if (hidden_button->get_active())
187           {
188             // set owner
189             int c = 0, row = player_combobox->get_active_row_number();
190             Player *player = Playerlist::getInstance()->getNeutral();
191             for (Playerlist::iterator i = Playerlist::getInstance()->begin(),
192                      end = Playerlist::getInstance()->end(); i != end; ++i, ++c)
193                 if (c == row)
194                 {
195                     player = *i;
196                     break;
197                 }
198             ruin->setOwner(player);
199           }
200         else
201           ruin->setOwner(NULL);
202         keeper = 0;
203       ruin->setReward(reward);
204     }
205     else
206     {
207         //put the ruin name back.
208         if (name_entry->get_text() != Ruin::getDefaultName())
209           d_randomizer->pushRandomRuinName(name_entry->get_text());
210         delete keeper;
211         keeper = 0;
212     }
213     return response;
214 }
215
216 void RuinEditorDialog::set_keeper_name()
217 {
218     Glib::ustring name;
219     if (keeper && !keeper->empty())
220         name = keeper->getStrongestArmy()->getName();
221     else
222         name = _("No keeper");
223     
224     keeper_button->set_label(name);
225 }
226
227 void RuinEditorDialog::on_hidden_toggled()
228 {
229   if (hidden_button->get_active())
230     player_combobox->set_sensitive (true);
231   else
232     player_combobox->set_sensitive (false);
233 }
234
235 void RuinEditorDialog::on_clear_keeper_clicked()
236 {
237   keeper->flClear();
238   set_keeper_name();
239 }
240
241 void RuinEditorDialog::on_keeper_clicked()
242 {
243     Player *neutral = Playerlist::getInstance()->getNeutral();
244     SelectArmyDialog d(neutral, false, true);
245     d.set_parent_window(*dialog);
246     d.run();
247
248     const ArmyProto *army = d.get_selected_army();
249     if (army)
250       {
251         keeper->flClear();
252         Army *a = new Army(*army);
253         keeper->push_back(a);
254       }
255
256     set_keeper_name();
257 }
258
259 void RuinEditorDialog::on_randomize_name_clicked()
260 {
261   std::string existing_name = name_entry->get_text();
262   if (existing_name == Ruin::getDefaultName())
263     name_entry->set_text(d_randomizer->popRandomRuinName());
264   else
265     {
266       name_entry->set_text(d_randomizer->popRandomRuinName());
267       d_randomizer->pushRandomRuinName(existing_name);
268     }
269 }
270
271 void RuinEditorDialog::on_randomize_keeper_clicked()
272 {
273   keeper->flClear();
274   Army *a = d_randomizer->getRandomRuinKeeper
275     (Playerlist::getInstance()->getNeutral());
276   keeper->push_back(a);
277   set_keeper_name();
278 }
279
280 void RuinEditorDialog::on_new_reward_toggled()
281 {
282   new_reward_hbox->set_sensitive(true);
283 }
284
285 void RuinEditorDialog::on_random_reward_toggled()
286 {
287   new_reward_hbox->set_sensitive(false);
288 }
289
290 void RuinEditorDialog::on_reward_list_clicked()
291 {
292   SelectRewardDialog d;
293   d.set_parent_window(*dialog);
294   d.run();
295   const Reward *picked_reward = d.get_selected_reward();
296   if (picked_reward)
297     {
298       on_clear_reward_clicked();
299       reward = Reward::copy(picked_reward);
300     }
301
302     set_reward_name();
303 }
304
305 void RuinEditorDialog::on_reward_clicked()
306 {
307   RewardEditorDialog d(keeper->getOwner(), false, NULL);
308   d.run();
309   if (d.get_reward())
310     {
311       on_clear_reward_clicked();
312       reward = d.get_reward();
313       set_reward_name();
314     }
315 }
316
317 void RuinEditorDialog::on_clear_reward_clicked()
318 {
319   if (reward)
320     {
321       delete reward;
322       reward = NULL;
323     }
324   set_reward_name();
325 }
326
327 void RuinEditorDialog::on_randomize_reward_clicked()
328 {
329   on_clear_reward_clicked();
330   reward = d_randomizer->getNewRandomReward(false);
331   set_reward_name();
332 }
333
334 void RuinEditorDialog::set_reward_name()
335 {
336   Glib::ustring name;
337   if (reward)
338     name = reward->getName();
339   else
340     name = _("No reward");
341
342   reward_button->set_label(name);
343 }
344