initial commit, lordsawar source, slightly modified
[lordsawar] / src / editor / main-window.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 <iomanip>
22 #include <SDL_video.h>
23 #include <assert.h>
24
25 #include <sigc++/functors/mem_fun.h>
26 #include <sigc++/functors/ptr_fun.h>
27
28 #include <gtkmm.h>
29 #include "main-window.h"
30
31 #include "image-helpers.h"
32 #include "input-helpers.h"
33 #include "error-utils.h"
34
35 #include "ucompose.hpp"
36 #include "tileset.h"
37 #include "tilesetlist.h"
38 #include "GameMap.h"
39 #include "defs.h"
40 #include "sound.h"
41 #include "File.h"
42 #include "GraphicsCache.h"
43 #include "smallmap.h"
44 #include "GameScenario.h"
45 #include "CreateScenarioRandomize.h"
46 #include "armysetlist.h"
47 #include "Itemlist.h"
48 #include "playerlist.h"
49 #include "shieldsetlist.h"
50 #include "citysetlist.h"
51 #include "ai_dummy.h"
52
53 #include "stack.h"
54 #include "signpost.h"
55 #include "citylist.h"
56 #include "city.h"
57 #include "templelist.h"
58 #include "temple.h"
59 #include "ruinlist.h"
60 #include "ruin.h"
61 #include "signpostlist.h"
62 #include "signpost.h"
63 #include "roadlist.h"
64 #include "road.h"
65 #include "bridgelist.h"
66 #include "bridge.h"
67 #include "portlist.h"
68 #include "port.h"
69 #include "MapGenerator.h"
70 #include "counter.h"
71
72 #include "glade-helpers.h"
73 #include "editorbigmap.h"
74
75 #include "signpost-editor-dialog.h"
76 #include "temple-editor-dialog.h"
77 #include "ruin-editor-dialog.h"
78 #include "stack-editor-dialog.h"
79 #include "players-dialog.h"
80 #include "city-editor-dialog.h"
81 #include "map-info-dialog.h"
82 #include "new-map-dialog.h"
83 #include "switch-sets-dialog.h"
84 #include "itemlist-dialog.h"
85 #include "rewardlist-dialog.h"
86 #include "timed-message-dialog.h"
87 #include "backpack-editor-dialog.h"
88 #include "MapBackpack.h"
89
90
91 MainWindow::MainWindow(std::string load_filename)
92 {
93   d_load_filename = load_filename;
94   bigmap = NULL;
95   smallmap = NULL;
96   game_scenario = NULL;
97   d_create_scenario_names = NULL;
98   needs_saving = false;
99     Glib::RefPtr<Gtk::Builder> xml
100         = Gtk::Builder::create_from_file(get_glade_path() + "/main-window.ui");
101
102     xml->get_widget("window", window);
103     window->set_icon_from_file(File::getMiscFile("various/tileset_icon.png"));
104
105     window->signal_delete_event().connect(
106         sigc::mem_fun(*this, &MainWindow::on_delete_event));
107
108     // the map image
109     xml->get_widget("bigmap_drawingarea", bigmap_drawingarea);
110     //bigmap_drawingarea->set_double_buffered(false);
111     //bigmap_drawingarea->set_app_paintable(true);
112     bigmap_drawingarea->signal_expose_event().connect
113       (sigc::mem_fun(*this, &MainWindow::on_bigmap_exposed));
114     bigmap_drawingarea->signal_size_allocate().connect
115       (sigc::mem_fun(*this, &MainWindow::on_bigmap_surface_changed));
116     xml->get_widget("bigmap_eventbox", bigmap_eventbox);
117
118     bigmap_eventbox->add_events(Gdk::BUTTON_PRESS_MASK | 
119                                 Gdk::BUTTON_RELEASE_MASK | 
120                                 Gdk::POINTER_MOTION_MASK |
121                                 Gdk::KEY_PRESS_MASK);
122     bigmap_eventbox->signal_button_press_event().connect(
123         sigc::mem_fun(*this, &MainWindow::on_bigmap_mouse_button_event));
124     bigmap_eventbox->signal_button_release_event().connect(
125         sigc::mem_fun(*this, &MainWindow::on_bigmap_mouse_button_event));
126     bigmap_eventbox->signal_motion_notify_event().connect(
127         sigc::mem_fun(*this, &MainWindow::on_bigmap_mouse_motion_event));
128     bigmap_eventbox->signal_key_press_event().connect(
129         sigc::mem_fun(*this, &MainWindow::on_bigmap_key_event));
130     bigmap_eventbox->signal_leave_notify_event().connect(
131         sigc::mem_fun(*this, &MainWindow::on_bigmap_leave_event));
132     xml->get_widget("map_drawingarea", map_drawingarea);
133     map_drawingarea->signal_expose_event().connect
134       (sigc::mem_fun(*this, &MainWindow::on_smallmap_exposed));
135     Gtk::EventBox *map_eventbox;
136     xml->get_widget("map_eventbox", map_eventbox);
137     map_eventbox->add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK |
138                              Gdk::POINTER_MOTION_MASK);
139     map_eventbox->signal_button_press_event().connect(
140         sigc::mem_fun(*this, &MainWindow::on_smallmap_mouse_button_event));
141     map_eventbox->signal_button_release_event().connect(
142         sigc::mem_fun(*this, &MainWindow::on_smallmap_mouse_button_event));
143     map_eventbox->signal_motion_notify_event().connect(
144         sigc::mem_fun(*this, &MainWindow::on_smallmap_mouse_motion_event));
145
146     xml->get_widget("terrain_tile_style_hbox", terrain_tile_style_hbox);
147
148     // setup pointer radiobuttons
149     xml->get_widget("terrain_type_table", terrain_type_table);
150
151     setup_pointer_radiobutton(xml, "pointer", "button_selector",
152                               EditorBigMap::POINTER, 1);
153     setup_pointer_radiobutton(xml, "draw_1", "button_1x1",
154                               EditorBigMap::TERRAIN, 1);
155     setup_pointer_radiobutton(xml, "draw_2", "button_2x2",
156                               EditorBigMap::TERRAIN, 2);
157     setup_pointer_radiobutton(xml, "draw_3", "button_3x3",
158                               EditorBigMap::TERRAIN, 3);
159     setup_pointer_radiobutton(xml, "draw_6", "button_6x6",
160                               EditorBigMap::TERRAIN, 6);
161     setup_pointer_radiobutton(xml, "draw_stack", "button_stack",
162                               EditorBigMap::STACK, 1);
163     setup_pointer_radiobutton(xml, "draw_ruin", "button_ruin",
164                               EditorBigMap::RUIN, 1);
165     setup_pointer_radiobutton(xml, "draw_signpost", "button_signpost",
166                               EditorBigMap::SIGNPOST, 1);
167     setup_pointer_radiobutton(xml, "draw_temple", "button_temple",
168                               EditorBigMap::TEMPLE, 1);
169     setup_pointer_radiobutton(xml, "draw_road", "button_road",
170                               EditorBigMap::ROAD, 1);
171     setup_pointer_radiobutton(xml, "draw_city", "button_castle",
172                               EditorBigMap::CITY, 1);
173     setup_pointer_radiobutton(xml, "erase", "button_erase",
174                               EditorBigMap::ERASE, 1);
175     setup_pointer_radiobutton(xml, "move", "button_move",
176                               EditorBigMap::MOVE, 1);
177     setup_pointer_radiobutton(xml, "draw_port", "button_port",
178                               EditorBigMap::PORT, 1);
179     setup_pointer_radiobutton(xml, "draw_bridge", "button_bridge",
180                               EditorBigMap::BRIDGE, 1);
181     setup_pointer_radiobutton(xml, "draw_bag", "button_bag",
182                               EditorBigMap::BAG, 1);
183
184     xml->get_widget("players_hbox", players_hbox);
185     on_pointer_radiobutton_toggled();
186
187     xml->get_widget("mouse_position_label", mouse_position_label);
188     
189     
190     // connect callbacks for the menu
191     xml->get_widget("new_map_menuitem", new_map_menuitem);
192     new_map_menuitem->signal_activate().connect
193       (sigc::mem_fun(this, &MainWindow::on_new_map_activated));
194     xml->get_widget("load_map_menuitem", load_map_menuitem);
195     load_map_menuitem->signal_activate().connect
196       (sigc::mem_fun(this, &MainWindow::on_load_map_activated));
197     xml->get_widget("save_map_menuitem", save_map_menuitem);
198     save_map_menuitem->signal_activate().connect
199       (sigc::mem_fun(this, &MainWindow::on_save_map_activated));
200     xml->get_widget("save_map_as_menuitem", save_map_as_menuitem);
201     save_map_as_menuitem->signal_activate().connect
202       (sigc::mem_fun(this, &MainWindow::on_save_map_as_activated));
203     xml->get_widget("import_map_from_sav_menuitem", import_map_from_sav_menuitem);
204     import_map_from_sav_menuitem->signal_activate().connect
205       (sigc::mem_fun(this, &MainWindow::on_import_map_activated));
206     xml->get_widget("export_as_bitmap_menuitem", export_as_bitmap_menuitem);
207     export_as_bitmap_menuitem->signal_activate().connect
208       (sigc::mem_fun(this, &MainWindow::on_export_as_bitmap_activated));
209     xml->get_widget("export_as_bitmap_no_game_objects_menuitem",
210                     export_as_bitmap_no_game_objects_menuitem);
211     export_as_bitmap_no_game_objects_menuitem->signal_activate().connect
212       (sigc::mem_fun(this, &MainWindow::on_export_as_bitmap_no_game_objects_activated));
213     xml->get_widget("validate_menuitem", validate_menuitem);
214     validate_menuitem->signal_activate().connect
215       (sigc::mem_fun(this, &MainWindow::on_validate_activated));
216     xml->get_widget("quit_menuitem", quit_menuitem);
217     quit_menuitem->signal_activate().connect
218       (sigc::mem_fun(this, &MainWindow::on_quit_activated));
219
220     xml->get_widget("edit_players_menuitem", edit_players_menuitem);
221     edit_players_menuitem->signal_activate().connect
222       (sigc::mem_fun(this, &MainWindow::on_edit_players_activated));
223     xml->get_widget("edit_map_info_menuitem", edit_map_info_menuitem);
224     edit_map_info_menuitem->signal_activate().connect
225       (sigc::mem_fun(this, &MainWindow::on_edit_map_info_activated));
226     
227     xml->get_widget("fullscreen_menuitem", fullscreen_menuitem);
228     fullscreen_menuitem->signal_activate().connect
229       (sigc::mem_fun(this, &MainWindow::on_fullscreen_activated));
230     xml->get_widget("toggle_tile_graphics_menuitem", toggle_tile_graphics_menuitem);
231     toggle_tile_graphics_menuitem->signal_activate().connect
232       (sigc::mem_fun(this, &MainWindow::on_tile_graphics_toggled));
233     xml->get_widget("toggle_grid_menuitem", toggle_grid_menuitem);
234     toggle_grid_menuitem->signal_activate().connect
235       (sigc::mem_fun(this, &MainWindow::on_grid_toggled));
236     xml->get_widget("smooth_map_menuitem", smooth_map_menuitem);
237     smooth_map_menuitem->signal_activate().connect
238       (sigc::mem_fun(this, &MainWindow::on_smooth_map_activated));
239     xml->get_widget("switch_sets_menuitem", switch_sets_menuitem);
240     switch_sets_menuitem->signal_activate().connect
241       (sigc::mem_fun(this, &MainWindow::on_switch_sets_activated));
242     xml->get_widget("smooth_screen_menuitem", smooth_screen_menuitem);
243     smooth_screen_menuitem->signal_activate().connect
244       (sigc::mem_fun (this, &MainWindow::on_smooth_screen_activated));
245     xml->get_widget("edit_items_menuitem", edit_items_menuitem);
246     edit_items_menuitem->signal_activate().connect
247       (sigc::mem_fun(this, &MainWindow::on_edit_items_activated));
248     xml->get_widget("edit_rewards_menuitem", edit_rewards_menuitem);
249     edit_rewards_menuitem->signal_activate().connect
250       (sigc::mem_fun(this, &MainWindow::on_edit_rewards_activated));
251     xml->get_widget ("random_all_cities_menuitem", random_all_cities_menuitem);
252     random_all_cities_menuitem->signal_activate().connect
253       (sigc::mem_fun(this, &MainWindow::on_random_all_cities_activated));
254     xml->get_widget ("random_unnamed_cities_menuitem", 
255                      random_unnamed_cities_menuitem);
256     random_unnamed_cities_menuitem->signal_activate().connect
257       (sigc::mem_fun(this, &MainWindow::on_random_unnamed_cities_activated));
258     xml->get_widget ("random_all_ruins_menuitem", random_all_ruins_menuitem);
259     random_all_ruins_menuitem->signal_activate().connect
260       (sigc::mem_fun(this, &MainWindow::on_random_all_ruins_activated));
261     xml->get_widget ("random_unnamed_ruins_menuitem", 
262                      random_unnamed_ruins_menuitem);
263     random_unnamed_ruins_menuitem->signal_activate().connect
264       (sigc::mem_fun(this, &MainWindow::on_random_unnamed_ruins_activated));
265     xml->get_widget ("random_all_temples_menuitem", 
266                      random_all_temples_menuitem);
267     random_all_temples_menuitem->signal_activate().connect
268       (sigc::mem_fun(this, &MainWindow::on_random_all_temples_activated));
269     xml->get_widget ("random_unnamed_temples_menuitem", 
270                      random_unnamed_temples_menuitem);
271     random_unnamed_temples_menuitem->signal_activate().connect
272       (sigc::mem_fun(this, &MainWindow::on_random_unnamed_temples_activated));
273     xml->get_widget ("random_all_signs_menuitem", 
274                      random_all_signs_menuitem);
275     random_all_signs_menuitem->signal_activate().connect
276       (sigc::mem_fun(this, &MainWindow::on_random_all_signs_activated));
277     xml->get_widget ("random_unnamed_signs_menuitem", 
278                      random_unnamed_signs_menuitem);
279     random_unnamed_signs_menuitem->signal_activate().connect
280        (sigc::mem_fun(this, &MainWindow::on_random_unnamed_signs_activated));
281     xml->get_widget ("help_about_menuitem", help_about_menuitem);
282     help_about_menuitem->signal_activate().connect
283        (sigc::mem_fun(this, &MainWindow::on_help_about_activated));
284 }
285
286 MainWindow::~MainWindow()
287 {
288   delete bigmap;
289   delete smallmap;
290   delete game_scenario;
291   delete d_create_scenario_names;
292   delete window;
293 }
294
295 void MainWindow::setup_pointer_radiobutton(Glib::RefPtr<Gtk::Builder> xml,
296                                            std::string prefix,
297                                            std::string image_file,
298                                            EditorBigMap::Pointer pointer,
299                                            int size)
300 {
301     PointerItem item;
302     xml->get_widget(prefix + "_radiobutton", item.button);
303     if (prefix == "pointer")
304         pointer_radiobutton = item.button;
305     item.button->signal_toggled().connect(
306         sigc::mem_fun(this, &MainWindow::on_pointer_radiobutton_toggled));
307     item.pointer = pointer;
308     item.size = size;
309     pointer_items.push_back(item);
310
311     Gtk::Image *image;
312     xml->get_widget(prefix + "_image", image);
313     image->property_file() = File::getEditorFile(image_file);
314     item.button->property_draw_indicator() = false;
315 }
316
317 void MainWindow::setup_terrain_radiobuttons()
318 {
319     // get rid of old ones
320     terrain_type_table->children().erase(terrain_type_table->children().begin(),
321                                          terrain_type_table->children().end());
322
323     // then add new ones from the tile set
324     Tileset *tset = GameMap::getInstance()->getTileset();
325     Gtk::RadioButton::Group group;
326     bool group_set = false;
327     const int no_columns = 6;
328     for (unsigned int i = 0; i < tset->size(); ++i)
329     {
330         Tile *tile = (*tset)[i];
331         TerrainItem item;
332         item.button = manage(new Gtk::RadioButton);
333         if (group_set)
334             item.button->set_group(group);
335         else
336         {
337             group = item.button->get_group();
338             group_set = true;
339         }
340         item.button->property_draw_indicator() = false;
341
342         int row = i / no_columns, column = i % no_columns;
343         
344         terrain_type_table->attach(*item.button, column, column + 1,
345                                    row, row + 1, Gtk::SHRINK);
346         item.button->signal_toggled().connect(
347             sigc::mem_fun(this, &MainWindow::on_terrain_radiobutton_toggled));
348
349         Glib::RefPtr<Gdk::Pixbuf> pic;
350         PixMask *pix = (*(*(*tile).begin())->begin())->getImage()->copy();
351         PixMask::scale(pix, 20, 20);
352         item.button->add(*manage(new Gtk::Image(pix->to_pixbuf())));
353         delete pix;
354
355         item.terrain = tile->getType();
356         terrain_items.push_back(item);
357     }
358
359     terrain_type_table->show_all();
360 }
361
362 void MainWindow::show()
363 {
364   bigmap_drawingarea->show_all();
365   window->show();
366   on_bigmap_surface_changed(bigmap_drawingarea->get_allocation());
367 }
368
369 void MainWindow::on_bigmap_surface_changed(Gtk::Allocation box)
370 {
371   if (!bigmap)
372     return;
373   static Gtk::Allocation last_box = Gtk::Allocation(0,0,1,1);
374
375   if (box.get_width() != last_box.get_width() || box.get_height() != last_box.get_height())
376     {
377       bigmap->screen_size_changed(bigmap_drawingarea->get_allocation());
378       redraw();
379     }
380   last_box = box;
381 }
382 bool MainWindow::on_bigmap_exposed(GdkEventExpose *event)
383 {
384   Glib::RefPtr<Gdk::Window> window = bigmap_drawingarea->get_window();
385   if (window)
386     {
387       Glib::RefPtr<Gdk::Pixmap> surface = bigmap->get_surface();
388       window->draw_drawable(bigmap_drawingarea->get_style()->get_white_gc(),
389                              surface, event->area.x, event->area.y, 
390                              event->area.x, event->area.y, 
391                              event->area.width, event->area.height);
392     }
393   return true;
394 }
395 bool MainWindow::on_smallmap_exposed(GdkEventExpose *event)
396 {
397   Glib::RefPtr<Gdk::Window> window = map_drawingarea->get_window();
398   if (window)
399     {
400       Glib::RefPtr<Gdk::Pixmap> surface = smallmap->get_surface();
401       window->draw_drawable(map_drawingarea->get_style()->get_white_gc(),
402                              surface, event->area.x, event->area.y, 
403                              event->area.x, event->area.y, 
404                              event->area.width, event->area.height);
405     }
406   return true;
407 }
408
409 void MainWindow::init()
410 {
411   Armysetlist::getInstance()->instantiateImages();
412   Tilesetlist::getInstance()->instantiateImages();
413   Shieldsetlist::getInstance()->instantiateImages();
414   Citysetlist::getInstance()->instantiateImages();
415   show_initial_map();
416   Playerlist::getInstance()->setActiveplayer(Playerlist::getInstance()->getNeutral());
417   fill_players();
418 }
419
420 void MainWindow::hide()
421 {
422     window->hide();
423 }
424
425 bool MainWindow::on_delete_event(GdkEventAny *e)
426 {
427   return !quit();
428 }
429
430 void MainWindow::show_initial_map()
431 {
432   if (d_load_filename.empty() == false)
433     {
434       clear_map_state();
435
436       bool broken;
437       if (game_scenario)
438         delete game_scenario;
439       current_save_filename = d_load_filename;
440       game_scenario = new GameScenario(current_save_filename, broken);
441       if (d_create_scenario_names)
442         delete d_create_scenario_names;
443       d_create_scenario_names = new CreateScenarioRandomize();
444       if (broken == false)
445         {
446           init_map_state();
447           bigmap->screen_size_changed(bigmap_drawingarea->get_allocation()); 
448           setup_terrain_radiobuttons();
449           remove_tile_style_buttons();
450           setup_tile_style_buttons(Tile::GRASS);
451         }
452       else
453         {
454           d_load_filename = "";
455           show_initial_map();
456         }
457     }
458   else
459     {
460       set_filled_map(112, 156, Tile::WATER, "default", "default", "default",
461                      "default");
462       setup_terrain_radiobuttons();
463       remove_tile_style_buttons();
464       setup_tile_style_buttons(Tile::GRASS);
465     }
466 }
467
468 void MainWindow::set_filled_map(int width, int height, int fill_style, std::string tileset, std::string shieldset, std::string cityset, std::string armyset)
469 {
470     clear_map_state();
471     d_width = width;
472     d_height = height;
473
474     GameMap::deleteInstance();
475     GameMap::setWidth(width);
476     GameMap::setHeight(height);
477     GameMap::getInstance(tileset, shieldset, cityset);
478     Itemlist::createStandardInstance();
479
480     if (game_scenario)
481       delete game_scenario;
482     // sets up the lists
483     game_scenario = new GameScenario(_("Untitled"), _("No description"), true);
484     if (d_create_scenario_names)
485       delete d_create_scenario_names;
486     d_create_scenario_names = new CreateScenarioRandomize();
487     //zip past the player IDs (+1 for neutral)
488     for (unsigned int i = 0; i < MAX_PLAYERS + 1; i++)
489       fl_counter->getNextId();
490
491
492     // ...however we need to do some of the setup by hand. We need to create a
493     // neutral player to give cities a player upon creation...
494     guint32 armyset_id = 
495       Armysetlist::getInstance()->getArmyset(armyset)->getId();
496     Shieldsetlist *ssl = Shieldsetlist::getInstance();
497     Shieldset *ss = ssl->getShieldset(shieldset);
498     std::string name = d_create_scenario_names->getPlayerName(Shield::NEUTRAL);
499     Player* neutral = new AI_Dummy(name, armyset_id, 
500                                    ssl->getColor(ss->getId(), MAX_PLAYERS), 
501                                    width, height, MAX_PLAYERS);
502     neutral->setType(Player::AI_DUMMY);
503     Playerlist::getInstance()->add(neutral);
504     Playerlist::getInstance()->setNeutral(neutral);
505     Playerlist::getInstance()->nextPlayer();
506
507     // fill the map with tile type
508     Tileset* tset = GameMap::getInstance()->getTileset();
509     for (unsigned int i = 0; i < tset->size(); ++i)
510     {
511         if ((*tset)[i]->getType() == fill_style)
512         {
513             GameMap::getInstance()->fill(i);
514             break;
515         }
516     }
517
518     init_map_state();
519 }
520
521 void MainWindow::set_random_map(int width, int height,
522                                 int grass, int water, int swamp, int forest,
523                                 int hills, int mountains,
524                                 int cities, int ruins, int temples,
525                                 int signposts, std::string tileset,
526                                 std::string shieldset, std::string cityset,
527                                 std::string armyset)
528 {
529     clear_map_state();
530
531     GameMap::deleteInstance();
532     GameMap::setWidth(width);
533     GameMap::setHeight(height);
534     GameMap::getInstance(tileset, shieldset, cityset);
535
536     //zip past the player IDs
537     if (fl_counter)
538         delete fl_counter;
539     fl_counter = new FL_Counter(MAX_PLAYERS + 1);
540     
541     // We need to create a neutral player to give cities a player upon
542     // creation...
543     guint32 armyset_id = 
544       Armysetlist::getInstance()->getArmyset(armyset)->getId();
545     Citysetlist::getInstance();
546     Shieldsetlist *ssl = Shieldsetlist::getInstance();
547     Shieldset *ss = ssl->getShieldset(shieldset);
548     std::string name = d_create_scenario_names->getPlayerName(Shield::NEUTRAL);
549     Player* neutral = new AI_Dummy(name, armyset_id, 
550                                    ssl->getColor(ss->getId(), MAX_PLAYERS), 
551                                    width, height, MAX_PLAYERS);
552     neutral->setType(Player::AI_DUMMY);
553     Playerlist::getInstance()->add(neutral);
554     Playerlist::getInstance()->setNeutral(neutral);
555     Playerlist::getInstance()->nextPlayer();
556     
557     // create a random map
558     MapGenerator gen;
559         
560     // first, fill the generator with data
561     gen.setNoCities(cities);
562     gen.setNoRuins(ruins);
563     gen.setNoTemples(temples);
564     gen.setNoSignposts(signposts);
565     
566     // if sum > 100 (percent), divide everything by a factor, the numeric error
567     // is said to be grass
568     int sum = grass + water + forest + swamp + hills + mountains;
569
570     if (sum > 100)
571     {
572         double factor = 100 / static_cast<double>(sum);
573         water = static_cast<int>(water / factor);
574         forest = static_cast<int>(forest / factor);
575         swamp = static_cast<int>(swamp / factor);
576         hills = static_cast<int>(hills / factor);
577         mountains = static_cast<int>(mountains / factor);
578     }
579     
580     gen.setPercentages(water, forest, swamp, hills, mountains);
581     
582     gen.setCityset(GameMap::getInstance()->getCityset());
583     gen.makeMap(width, height, false);
584     GameMap::deleteInstance();
585     GameMap::setWidth(width);
586     GameMap::setHeight(height);
587     GameMap::getInstance(tileset, shieldset, cityset);
588     GameMap::getInstance()->fill(&gen);
589
590     Itemlist::createStandardInstance();
591     // sets up the lists
592     if (game_scenario)
593       delete game_scenario;
594     game_scenario = new GameScenario(_("Untitled"), _("No description"), true);
595     if (d_create_scenario_names)
596       delete d_create_scenario_names;
597     d_create_scenario_names = new CreateScenarioRandomize();
598     
599     Cityset *cs = Citysetlist::getInstance()->getCityset(cityset);
600     // now fill the lists
601     const Maptile::Building* build = gen.getBuildings(width, height);
602     for (int j = 0; j < height; j++)
603         for (int i = 0; i < width; i++)
604             switch(build[j * width + i])
605             {
606             case Maptile::CITY:
607                 Citylist::getInstance()->add
608                   (new City(Vector<int>(i,j), cs->getCityTileWidth()));
609                 (*Citylist::getInstance()->rbegin())->setOwner(
610                     Playerlist::getInstance()->getNeutral());
611                 break;
612             case Maptile::TEMPLE:
613                 Templelist::getInstance()->add
614                   (new Temple(Vector<int>(i,j), cs->getTempleTileWidth()));
615                 break;
616             case Maptile::RUIN:
617                 Ruinlist::getInstance()->add
618                   (new Ruin(Vector<int>(i,j), cs->getRuinTileWidth()));
619                 break;
620             case Maptile::SIGNPOST:
621                 Signpostlist::getInstance()->add(new Signpost(Vector<int>(i,j)));
622                 break;
623             case Maptile::ROAD:
624                 Roadlist::getInstance()->add(new Road(Vector<int>(i,j)));
625                 break;
626             case Maptile::BRIDGE:
627                 Bridgelist::getInstance()->add(new Bridge(Vector<int>(i,j)));
628                 break;
629             case Maptile::PORT:
630                 Portlist::getInstance()->add(new Port(Vector<int>(i,j)));
631                 break;
632             case Maptile::NONE:
633                 break;
634             }
635
636     init_map_state();
637 }
638
639 void MainWindow::clear_map_state()
640 {
641   if (bigmap)
642     {
643       delete bigmap;
644       bigmap = NULL;
645     }
646   if (smallmap)
647     {
648       delete smallmap;
649       smallmap = NULL;
650     }
651   if (game_scenario)
652     {
653       delete game_scenario;
654       game_scenario = NULL;
655     }
656   if (d_create_scenario_names)
657     {
658       delete d_create_scenario_names;
659       d_create_scenario_names = NULL;
660     }
661     GraphicsCache::deleteInstance();
662 }
663
664 void MainWindow::init_map_state()
665 {
666     pointer_radiobutton->set_active();
667     init_maps();
668 }
669
670
671 bool MainWindow::on_bigmap_mouse_button_event(GdkEventButton *e)
672 {
673     if (e->type != GDK_BUTTON_PRESS && e->type != GDK_BUTTON_RELEASE)
674         return true;    // useless event
675
676     if (bigmap)
677     {
678         button_event = e;       // save it for later use
679         bigmap->mouse_button_event(to_input_event(e));
680         if (smallmap)
681           smallmap->draw(Playerlist::getActiveplayer());
682         needs_saving = true;
683     }
684     
685     return true;
686 }
687
688 bool MainWindow::on_bigmap_mouse_motion_event(GdkEventMotion *e)
689 {
690   static guint prev = 0;
691   if (bigmap)
692     {
693       guint delta = e->time - prev;
694       if (delta > 40 || delta < 0)
695         {
696           bigmap->mouse_motion_event(to_input_event(e));
697           prev = e->time;
698         }
699     }
700     
701     return true;
702 }
703
704 bool MainWindow::on_bigmap_key_event(GdkEventKey *e)
705 {
706 #if 0
707     if (bigmap) {
708         KeyPressEvent k;
709         bigmap->key_press_event(k);
710     }
711 #endif
712     
713     return true;
714 }
715
716 bool MainWindow::on_bigmap_leave_event(GdkEventCrossing *e)
717 {
718     if (bigmap)
719     {
720         bigmap->mouse_leave_event();
721     }
722     
723     return true;
724 }
725
726 bool MainWindow::on_smallmap_mouse_button_event(GdkEventButton *e)
727 {
728     if (e->type != GDK_BUTTON_PRESS && e->type != GDK_BUTTON_RELEASE)
729         return true;    // useless event
730     
731     if (smallmap)
732         smallmap->mouse_button_event(to_input_event(e));
733     
734     return true;
735 }
736
737 bool MainWindow::on_smallmap_mouse_motion_event(GdkEventMotion *e)
738 {
739   static guint prev = 0;
740   if (smallmap)
741     {
742       guint delta = e->time - prev;
743       if (delta > 100 || delta < 0)
744         {
745           smallmap->mouse_motion_event(to_input_event(e));
746           prev = e->time;
747         }
748     }
749     
750     return true;
751 }
752
753 void MainWindow::on_new_map_activated()
754 {
755     current_save_filename = "";
756
757     NewMapDialog d;
758     d.set_parent_window(*window);
759     d.run();
760
761     if (d.map_set)
762     {
763         if (d.map.fill_style == -1)
764             set_random_map(d.map.width, d.map.height,
765                            d.map.grass, d.map.water, d.map.swamp, d.map.forest,
766                            d.map.hills, d.map.mountains,
767                            d.map.cities, d.map.ruins, d.map.temples, 
768                            d.map.signposts, d.map.tileset, 
769                            d.map.shieldset, d.map.cityset, d.map.armyset);
770         else
771             set_filled_map(d.map.width, d.map.height, d.map.fill_style, 
772                            d.map.tileset, d.map.shieldset, d.map.cityset,
773                            d.map.armyset);
774         needs_saving = true;
775     }
776 }
777
778 void MainWindow::on_load_map_activated()
779 {
780     Gtk::FileChooserDialog chooser(*window, _("Choose Map to Load"));
781     Gtk::FileFilter sav_filter;
782     sav_filter.add_pattern("*.map");
783     chooser.set_filter(sav_filter);
784     chooser.set_current_folder(File::getUserMapDir());
785
786     chooser.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
787     chooser.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
788     chooser.set_default_response(Gtk::RESPONSE_ACCEPT);
789         
790     chooser.show_all();
791     int res = chooser.run();
792     
793     if (res == Gtk::RESPONSE_ACCEPT)
794     {
795         current_save_filename = chooser.get_filename();
796         chooser.hide();
797
798         clear_map_state();
799
800         bool broken;
801         if (game_scenario)
802           delete game_scenario;
803         game_scenario = new GameScenario(current_save_filename, broken);
804         if (d_create_scenario_names)
805           delete d_create_scenario_names;
806         d_create_scenario_names = new CreateScenarioRandomize();
807
808         if (broken)
809         {
810             show_error(String::ucompose(_("Could not load map %1."),
811                                         current_save_filename));
812             current_save_filename = "";
813             return;
814         }
815
816         init_map_state();
817         bigmap->screen_size_changed(bigmap_drawingarea->get_allocation()); 
818     }
819 }
820
821 void MainWindow::on_save_map_activated()
822 {
823     if (current_save_filename.empty())
824         on_save_map_as_activated();
825     else
826     {
827         needs_saving = false;
828         bool success = game_scenario->saveGame(current_save_filename, "map");
829         if (!success)
830             show_error(_("Map was not saved!"));
831     }
832 }
833
834 void MainWindow::on_export_as_bitmap_activated()
835 {
836     Gtk::FileChooserDialog chooser(*window, _("Choose a Name"),
837                                    Gtk::FILE_CHOOSER_ACTION_SAVE);
838     Gtk::FileFilter sav_filter;
839     sav_filter.add_pattern("*.png");
840     chooser.set_filter(sav_filter);
841     chooser.set_current_folder(Glib::get_home_dir());
842     chooser.set_do_overwrite_confirmation();
843
844     chooser.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
845     chooser.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
846     chooser.set_default_response(Gtk::RESPONSE_ACCEPT);
847     
848     chooser.show_all();
849     int res = chooser.run();
850     
851     if (res == Gtk::RESPONSE_ACCEPT)
852     {
853         current_save_filename = chooser.get_filename();
854         chooser.hide();
855
856         bool success = bigmap->saveAsBitmap(current_save_filename);
857         if (!success)
858             show_error(_("Map was not exported!"));
859     }
860 }
861
862 void MainWindow::on_export_as_bitmap_no_game_objects_activated()
863 {
864     Gtk::FileChooserDialog chooser(*window, _("Choose a Name"),
865                                    Gtk::FILE_CHOOSER_ACTION_SAVE);
866     Gtk::FileFilter sav_filter;
867     sav_filter.add_pattern("*.png");
868     chooser.set_filter(sav_filter);
869     chooser.set_current_folder(Glib::get_home_dir());
870     chooser.set_do_overwrite_confirmation();
871
872     chooser.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
873     chooser.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
874     chooser.set_default_response(Gtk::RESPONSE_ACCEPT);
875     
876     chooser.show_all();
877     int res = chooser.run();
878     
879     if (res == Gtk::RESPONSE_ACCEPT)
880     {
881         current_save_filename = chooser.get_filename();
882         chooser.hide();
883
884         bool success = bigmap->saveUnderlyingMapAsBitmap(current_save_filename);
885         if (!success)
886             show_error(_("Map was not exported!"));
887     }
888 }
889
890 void MainWindow::on_save_map_as_activated()
891 {
892     Gtk::FileChooserDialog chooser(*window, _("Choose a Name"),
893                                    Gtk::FILE_CHOOSER_ACTION_SAVE);
894     Gtk::FileFilter sav_filter;
895     sav_filter.add_pattern("*.map");
896     chooser.set_filter(sav_filter);
897     chooser.set_current_folder(File::getUserMapDir());
898
899     chooser.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
900     chooser.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
901     chooser.set_default_response(Gtk::RESPONSE_ACCEPT);
902     
903     chooser.show_all();
904     int res = chooser.run();
905     
906     if (res == Gtk::RESPONSE_ACCEPT)
907     {
908         current_save_filename = chooser.get_filename();
909         chooser.hide();
910
911         bool success = game_scenario->saveGame(current_save_filename, "map");
912         if (!success)
913             show_error(_("Map was not saved!"));
914         needs_saving = false;
915     }
916 }
917
918 bool MainWindow::quit()
919 {
920   if (needs_saving)
921     {
922       Gtk::Dialog* dialog;
923       Glib::RefPtr<Gtk::Builder> xml
924         = Gtk::Builder::create_from_file(get_glade_path() + 
925                                          "/editor-quit-dialog.ui");
926       xml->get_widget("dialog", dialog);
927       dialog->set_transient_for(*window);
928       int response = dialog->run();
929       dialog->hide();
930       delete dialog;
931       
932       if (response == Gtk::RESPONSE_CANCEL) //we don't want to quit
933         return false;
934
935       else if (response == Gtk::RESPONSE_ACCEPT) // save and quit
936         on_save_map_activated();
937       //else if (Response == Gtk::CLOSE) // don't save just quit
938       window->hide();
939     }
940   else
941     window->hide();
942   return true;
943 }
944
945 void MainWindow::on_quit_activated()
946 {
947   quit();
948 }
949
950 void MainWindow::on_edit_players_activated()
951 {
952     PlayersDialog d(d_create_scenario_names, d_width, d_height);
953     d.set_parent_window(*window);
954     Player *active = Playerlist::getActiveplayer();
955     int response = d.run();
956     if (response == Gtk::RESPONSE_ACCEPT)
957       {
958         if (Playerlist::getInstance()->getPlayer(active->getId()))
959           Playerlist::getInstance()->setActiveplayer(active);
960         needs_saving = true;
961         fill_players();
962       }
963 }
964
965 void MainWindow::on_edit_map_info_activated()
966 {
967     MapInfoDialog d(game_scenario);
968     d.set_parent_window(*window);
969     int response = d.run();
970     if (response == Gtk::RESPONSE_ACCEPT)
971       needs_saving = true;
972 }
973
974 void MainWindow::on_fullscreen_activated()
975 {
976     if (fullscreen_menuitem->get_active())
977         window->fullscreen();
978     else
979         window->unfullscreen();
980 }
981                          
982 void MainWindow::on_tile_graphics_toggled()
983 {
984   bigmap->toggleViewStylesOrTypes();
985   bigmap->draw(Playerlist::getViewingplayer());
986 }
987 void MainWindow::on_grid_toggled()
988 {
989   bigmap->toggle_grid();
990 }
991
992
993 void MainWindow::remove_tile_style_buttons()
994 {
995   Glib::ListHandle<Gtk::Widget*> children = 
996     terrain_tile_style_hbox->get_children();
997   if (!children.empty()) 
998     {
999       Glib::ListHandle<Gtk::Widget*>::iterator child = children.begin();
1000       for (; child != children.end(); child++)
1001         terrain_tile_style_hbox->remove(**child);
1002     }
1003   tile_style_items.clear();
1004 }
1005
1006 void MainWindow::setup_tile_style_buttons(Tile::Type terrain)
1007 {
1008   Gtk::RadioButton::Group group;
1009   //iterate through tilestyles of a certain TERRAIN tile
1010   Tileset *tileset = GameMap::getInstance()->getTileset();
1011   guint32 index = tileset->getIndex(terrain);
1012   Tile *tile = (*tileset)[index];
1013   if (tile == NULL)
1014     return;
1015           
1016   TileStyleItem auto_item;
1017   auto_item.button = manage(new Gtk::RadioButton);
1018   terrain_tile_style_hbox->pack_start(*manage(auto_item.button), 
1019                                       Gtk::PACK_SHRINK, 0, 0);
1020   auto_item.button->set_label(_("Auto"));
1021   auto_item.button->property_draw_indicator() = false;
1022           
1023   auto_item.button->signal_toggled().connect
1024     (sigc::mem_fun(this, &MainWindow::on_tile_style_radiobutton_toggled));
1025
1026   auto_item.tile_style_id = -1;
1027   group = auto_item.button->get_group();
1028   tile_style_items.push_back(auto_item);
1029
1030   for (Tile::iterator it = tile->begin(); it != tile->end(); it++)
1031     {
1032       TileStyleSet *tilestyleset = *it;
1033       //loop through tile style sets
1034       for (unsigned int j = 0; j < tilestyleset->size(); j++)
1035         {
1036           //now loop through the tile styles
1037           TileStyle *tilestyle = (*tilestyleset)[j];
1038
1039           //let's make a button
1040           TileStyleItem item;
1041           item.button = manage(new Gtk::RadioButton);
1042           item.button->set_group(group);
1043           item.button->property_draw_indicator() = false;
1044
1045           terrain_tile_style_hbox->pack_start(*manage(item.button), 
1046                                               Gtk::PACK_SHRINK, 0, 0);
1047           item.button->signal_toggled().connect
1048             (sigc::mem_fun(this, 
1049                            &MainWindow::on_tile_style_radiobutton_toggled));
1050
1051           Glib::RefPtr<Gdk::Pixbuf> pic = tilestyle->getImage()->to_pixbuf();
1052           item.button->add(*manage(new Gtk::Image(pic)));
1053           item.tile_style_id = tilestyle->getId();
1054
1055           tile_style_items.push_back(item);
1056         }
1057     }
1058
1059   terrain_tile_style_hbox->show_all();
1060 }
1061
1062     
1063 void MainWindow::auto_select_appropriate_pointer()
1064 {
1065   switch (get_terrain())
1066     {
1067     case Tile::GRASS:
1068       //do 1x1
1069       pointer_items[1].button->set_active();
1070       break;
1071     case Tile::WATER:
1072     case Tile::FOREST:
1073     case Tile::SWAMP:
1074     case Tile::HILLS:
1075     case Tile::VOID:
1076         {
1077           Tileset *tileset = GameMap::getInstance()->getTileset();
1078           Tile *tile = (*tileset)[tileset->getIndex(get_terrain())];
1079           if (tile->consistsOnlyOfLoneAndOtherStyles())
1080             pointer_items[1].button->set_active();
1081           else
1082             pointer_items[2].button->set_active();
1083           break;
1084         }
1085     case Tile::MOUNTAIN:
1086         //do 6x6
1087       pointer_items[4].button->set_active();
1088       break;
1089     }
1090 }
1091
1092 void MainWindow::on_tile_style_radiobutton_toggled()
1093 {
1094   on_pointer_radiobutton_toggled();
1095       
1096   //was the first one (auto) clicked?  if so, we want 1x1
1097   if (get_tile_style_id() != -1)
1098     pointer_items[1].button->set_active();
1099   else
1100     auto_select_appropriate_pointer();
1101 }
1102
1103 void MainWindow::on_terrain_radiobutton_toggled()
1104 {
1105   remove_tile_style_buttons();
1106   setup_tile_style_buttons(get_terrain());
1107   on_pointer_radiobutton_toggled();
1108   auto_select_appropriate_pointer();
1109 }
1110
1111 void MainWindow::on_pointer_radiobutton_toggled()
1112 {
1113     EditorBigMap::Pointer pointer = EditorBigMap::POINTER;
1114     int size = 1;
1115     
1116     for (std::vector<PointerItem>::iterator i = pointer_items.begin(),
1117              end = pointer_items.end(); i != end; ++i)
1118     {
1119         if (i->button->get_active())
1120         {
1121             pointer = i->pointer;
1122             size = i->size;
1123             break;
1124         }
1125     }
1126     
1127     if (bigmap)
1128         bigmap->set_pointer(pointer, size, get_terrain(),
1129                             get_tile_style_id());
1130     terrain_type_table->set_sensitive(pointer == EditorBigMap::TERRAIN);
1131     terrain_tile_style_hbox->set_sensitive(pointer == EditorBigMap::TERRAIN);
1132
1133     players_hbox->set_sensitive (pointer == EditorBigMap::STACK || 
1134                                  pointer == EditorBigMap::CITY);
1135 }
1136
1137 Tile::Type MainWindow::get_terrain()
1138 {
1139     Tile::Type terrain = Tile::GRASS;
1140     for (std::vector<TerrainItem>::iterator i = terrain_items.begin(),
1141              end = terrain_items.end(); i != end; ++i)
1142     {
1143         if (i->button->get_active())
1144         {
1145             terrain = i->terrain;
1146             break;
1147         }
1148     }
1149
1150     return terrain;
1151 }
1152
1153 int MainWindow::get_tile_style_id()
1154 {
1155   int tile_style_id = -1;
1156   for (std::vector<TileStyleItem>::iterator i = tile_style_items.begin(),
1157        end = tile_style_items.end(); i != end; ++i)
1158     {
1159         if (i->button->get_active())
1160           {
1161             tile_style_id = i->tile_style_id;
1162             break;
1163           }
1164     }
1165
1166     return tile_style_id;
1167 }
1168
1169 void MainWindow::on_bigmap_changed(Glib::RefPtr<Gdk::Pixmap> map)
1170 {
1171   int width = 0;
1172   int height = 0;
1173   map->get_size(width, height);
1174   Glib::RefPtr<Gdk::Window> window = bigmap_drawingarea->get_window();
1175   if (window)
1176     {
1177       Gdk::Rectangle r = Gdk::Rectangle(0, 0, width, height);
1178       window->invalidate_rect(r, true);
1179     }
1180 }
1181 void MainWindow::on_smallmap_changed(Glib::RefPtr<Gdk::Pixmap> map, Gdk::Rectangle r)
1182 {
1183   int width = 0;
1184   int height = 0;
1185   map->get_size(width, height);
1186   map_drawingarea->property_width_request() = width;
1187   map_drawingarea->property_height_request() = height;
1188       
1189   Glib::RefPtr<Gdk::Window> window = map_drawingarea->get_window();
1190   if (window)
1191     {
1192       window->invalidate_rect(r, false);
1193     }
1194   //map_image->property_pixmap() = map;
1195   //map.clear();
1196   //still resides at smallmap->get_surface()
1197 }
1198
1199
1200 void MainWindow::init_maps()
1201 {
1202     // init the smallmap
1203     if (smallmap)
1204       delete smallmap;
1205     smallmap =new SmallMap;
1206     smallmap->resize();
1207     smallmap->map_changed.connect(
1208         sigc::mem_fun(this, &MainWindow::on_smallmap_changed));
1209
1210     // init the bigmap
1211     if (bigmap)
1212       delete bigmap;
1213     bigmap = new EditorBigMap;
1214     bigmap->mouse_on_tile.connect(
1215         sigc::mem_fun(this, &MainWindow::on_mouse_on_tile));
1216     bigmap->objects_selected.connect(
1217         sigc::mem_fun(this, &MainWindow::on_objects_selected));
1218     bigmap->map_changed.connect(
1219         sigc::mem_fun(this, &MainWindow::on_bigmap_changed));
1220
1221     // grid is on by default
1222     bigmap->toggle_grid();
1223     
1224     // connect the two maps
1225     bigmap->view_changed.connect(
1226         sigc::mem_fun(smallmap, &SmallMap::set_view));
1227     bigmap->map_tiles_changed.connect(
1228         sigc::mem_fun(smallmap, &SmallMap::redraw_tiles));
1229     smallmap->view_changed.connect(
1230         sigc::mem_fun(bigmap, &EditorBigMap::set_view));
1231
1232     //trigger the bigmap to resize the view box in the smallmap
1233     bigmap->screen_size_changed(bigmap_drawingarea->get_allocation()); 
1234 }
1235
1236 void MainWindow::on_mouse_on_tile(Vector<int> tile)
1237 {
1238     Glib::ustring str;
1239     if (tile.x > 0 && tile.y > 0)
1240         // note to translators: this is a coordinate pair (x, y)
1241         str = "<i>" + String::ucompose(_("(%1, %2)"), tile.x, tile.y) + "</i>";
1242     
1243     mouse_position_label->set_markup(str);
1244 }
1245
1246 void MainWindow::on_objects_selected(std::vector<UniquelyIdentified *> objects)
1247 {
1248     assert(!objects.empty());
1249
1250     if (objects.size() == 1)
1251     {
1252         popup_dialog_for_object(objects.front());
1253     }
1254     else
1255     {
1256         // show a popup
1257         Gtk::Menu *menu = manage(new Gtk::Menu);
1258         for (std::vector<UniquelyIdentified *>::iterator i = objects.begin(), end = objects.end();
1259              i != end; ++i)
1260         {
1261             Glib::ustring s;
1262             if (dynamic_cast<Stack *>(*i))
1263                 s = _("Stack");
1264             else if (dynamic_cast<City *>(*i))
1265                 s = _("City");
1266             else if (dynamic_cast<Ruin *>(*i))
1267                 s = _("Ruin");
1268             else if (dynamic_cast<Signpost *>(*i))
1269                 s = _("Signpost");
1270             else if (dynamic_cast<Temple *>(*i))
1271                 s = _("Temple");
1272             else if (dynamic_cast<MapBackpack*>(*i))
1273                 s = _("Bag");
1274             
1275             Gtk::MenuItem *item = manage(new Gtk::MenuItem(s));
1276             item->signal_activate().connect(
1277                 sigc::bind(sigc::mem_fun(this, &MainWindow::popup_dialog_for_object), *i));
1278             item->show();
1279             menu->add(*item);
1280         }
1281         menu->popup(button_event->button, button_event->time);
1282     }
1283 }
1284
1285 void MainWindow::popup_dialog_for_object(UniquelyIdentified *object)
1286 {
1287     if (Stack *o = dynamic_cast<Stack *>(object))
1288     {
1289         StackEditorDialog d(o);
1290         d.set_parent_window(*window);
1291         int response = d.run();
1292         if (response == Gtk::RESPONSE_ACCEPT)
1293           needs_saving = true;
1294
1295         // we might have changed something visible
1296         redraw();
1297     }
1298     else if (City *o = dynamic_cast<City *>(object))
1299     {
1300         CityEditorDialog d(o, d_create_scenario_names);
1301         d.set_parent_window(*window);
1302         int response = d.run();
1303         if (response == Gtk::RESPONSE_ACCEPT)
1304           needs_saving = true;
1305
1306         // we might have changed something visible
1307         redraw();
1308     }
1309     else if (Ruin *o = dynamic_cast<Ruin *>(object))
1310     {
1311         RuinEditorDialog d(o, d_create_scenario_names);
1312         d.set_parent_window(*window);
1313         int response = d.run();
1314         if (response == Gtk::RESPONSE_ACCEPT)
1315           needs_saving = true;
1316     }
1317     else if (Signpost *o = dynamic_cast<Signpost *>(object))
1318     {
1319         SignpostEditorDialog d(o, d_create_scenario_names);
1320         d.set_parent_window(*window);
1321         int response = d.run();
1322         if (response == Gtk::RESPONSE_ACCEPT)
1323           needs_saving = true;
1324     }
1325     else if (Temple *o = dynamic_cast<Temple *>(object))
1326     {
1327         TempleEditorDialog d(o, d_create_scenario_names);
1328         d.set_parent_window(*window);
1329         int response = d.run();
1330         if (response == Gtk::RESPONSE_ACCEPT)
1331           needs_saving = true;
1332
1333         // we might have changed something visible
1334         redraw();
1335     }
1336     else if (MapBackpack *b = dynamic_cast<MapBackpack*>(object))
1337       {
1338         BackpackEditorDialog d(b);
1339         int response = d.run();
1340         if (response == Gtk::RESPONSE_ACCEPT)
1341           needs_saving = true;
1342       }
1343 }
1344
1345 void MainWindow::on_smooth_map_activated()
1346 {
1347   GameMap::getInstance()->applyTileStyles(0, 0, GameMap::getHeight(), 
1348                                           GameMap::getWidth(), true);
1349   redraw();
1350 }
1351
1352 void MainWindow::on_smooth_screen_activated()
1353 {
1354   bigmap->smooth_view();
1355 }
1356
1357 void MainWindow::on_edit_items_activated()
1358 {
1359   ItemlistDialog d;
1360   d.set_parent_window(*window);
1361   int response = d.run();
1362   if (response == Gtk::RESPONSE_ACCEPT)
1363     needs_saving = true;
1364 }
1365
1366 void MainWindow::on_edit_rewards_activated()
1367 {
1368   RewardlistDialog d;
1369   d.set_parent_window(*window);
1370   int response = d.run();
1371   if (response == Gtk::RESPONSE_ACCEPT)
1372     needs_saving = true;
1373 }
1374
1375 void MainWindow::randomize_city(City *c)
1376 {
1377   std::string name = d_create_scenario_names->popRandomCityName();
1378   if (name != "")
1379     c->setName(name);
1380   c->setRandomArmytypes(true, 1);
1381 }
1382
1383 void MainWindow::on_random_all_cities_activated()
1384 {
1385   Citylist *cl = Citylist::getInstance();
1386   for (Citylist::iterator it = cl->begin(); it != cl->end(); it++)
1387     randomize_city(*it);
1388   needs_saving = true;
1389 }
1390
1391 void MainWindow::on_random_unnamed_cities_activated()
1392 {
1393   Citylist *cl = Citylist::getInstance();
1394   for (Citylist::iterator it = cl->begin(); it != cl->end(); it++)
1395     {
1396       if ((*it)->isUnnamed() == true)
1397         randomize_city(*it);
1398     }
1399   needs_saving = true;
1400 }
1401
1402 void MainWindow::randomize_ruin(Ruin *r)
1403 {
1404   std::string name = d_create_scenario_names->popRandomRuinName();
1405   if (name != "")
1406     {
1407       Location *l = r;
1408       RenamableLocation *renamable_ruin = static_cast<RenamableLocation*>(l);
1409       renamable_ruin->setName(name);
1410     }
1411 }
1412
1413 void MainWindow::on_random_all_ruins_activated()
1414 {
1415   Ruinlist *rl = Ruinlist::getInstance();
1416   for (Ruinlist::iterator it = rl->begin(); it != rl->end(); it++)
1417     randomize_ruin(*it);
1418   needs_saving = true;
1419 }
1420
1421 void MainWindow::on_random_unnamed_ruins_activated()
1422 {
1423   Ruinlist *rl = Ruinlist::getInstance();
1424   for (Ruinlist::iterator it = rl->begin(); it != rl->end(); it++)
1425     {
1426       if ((*it)->isUnnamed() == true)
1427         randomize_ruin(*it);
1428     }
1429   needs_saving = true;
1430 }
1431
1432 void MainWindow::on_random_all_temples_activated()
1433 {
1434   Templelist *tl = Templelist::getInstance();
1435   for (Templelist::iterator it = tl->begin(); it != tl->end(); it++)
1436     {
1437       std::string name = d_create_scenario_names->popRandomTempleName();
1438       if (name != "")
1439         {
1440           Location *l = *it;
1441           RenamableLocation *renamable_temple = 
1442             static_cast<RenamableLocation*>(l);
1443           renamable_temple->setName(name);
1444         }
1445     }
1446   needs_saving = true;
1447 }
1448
1449 void MainWindow::on_random_unnamed_temples_activated()
1450 {
1451   Templelist *tl = Templelist::getInstance();
1452   for (Templelist::iterator it = tl->begin(); it != tl->end(); it++)
1453     {
1454       if ((*it)->isUnnamed() == true)
1455         {
1456           std::string name = d_create_scenario_names->popRandomTempleName();
1457           if (name != "")
1458             {
1459               Location *l = *it;
1460               RenamableLocation *renamable_temple = 
1461                 static_cast<RenamableLocation*>(l);
1462               renamable_temple->setName(name);
1463             }
1464         }
1465     }
1466   needs_saving = true;
1467 }
1468
1469 void MainWindow::randomize_signpost(Signpost *signpost)
1470 {
1471   std::string name = "";
1472   if ((rand() % d_create_scenario_names->getNumSignposts())  == 0)
1473     name = d_create_scenario_names->popRandomSignpost();
1474   else
1475     name = d_create_scenario_names->getDynamicSignpost(signpost);
1476   if (name == "")
1477     name = d_create_scenario_names->popRandomSignpost();
1478   signpost->setName(name);
1479 }
1480
1481 void MainWindow::on_random_all_signs_activated()
1482 {
1483   Signpostlist *sl = Signpostlist::getInstance();
1484   for (Signpostlist::iterator it = sl->begin(); it != sl->end(); it++)
1485     randomize_signpost(*it);
1486   needs_saving = true;
1487 }
1488
1489 void MainWindow::on_random_unnamed_signs_activated()
1490 {
1491   Signpostlist *sl = Signpostlist::getInstance();
1492   for (Signpostlist::iterator it = sl->begin(); it != sl->end(); it++)
1493     {
1494       if ((*it)->getName() == DEFAULT_SIGNPOST)
1495         randomize_signpost(*it);
1496     }
1497   needs_saving = true;
1498 }
1499
1500 void MainWindow::on_help_about_activated()
1501 {
1502   Gtk::AboutDialog* dialog;
1503
1504   Glib::RefPtr<Gtk::Builder> xml
1505     = Gtk::Builder::create_from_file(get_glade_path() + "/../about-dialog.ui");
1506
1507   xml->get_widget("dialog", dialog);
1508   dialog->set_transient_for(*window);
1509   dialog->set_icon_from_file(File::getMiscFile("various/tileset_icon.png"));
1510
1511   dialog->set_version(PACKAGE_VERSION);
1512   dialog->set_logo(GraphicsCache::getMiscPicture("castle_icon.png")->to_pixbuf());
1513   dialog->show_all();
1514   dialog->run();
1515   delete dialog;
1516
1517   return;
1518 }
1519
1520 void MainWindow::on_validate_activated()
1521 {
1522   Glib::ustring s;
1523   std::list<std::string> errors;
1524   std::list<std::string> warnings;
1525   game_scenario->validate(errors, warnings);
1526   if (errors.size())
1527     s = errors.front();
1528   else
1529     {
1530       if (warnings.size())
1531         s = warnings.front();
1532       else
1533         s = _("No errors.");
1534     }
1535   if (errors.size() > 1)
1536     s += String::ucompose(ngettext("\nThere is %1 more error", "\nThere are %1 more errors", errors.size() - 1), errors.size() - 1);
1537   if (warnings.size())
1538     s += String::ucompose(ngettext("\nThere is %1 warning", "\nThere are %1 warnings", warnings.size()), warnings.size());
1539   TimedMessageDialog dialog(*window, s, 0);
1540   dialog.show_all();
1541   dialog.run();
1542   dialog.hide();
1543 }
1544       
1545         
1546 void MainWindow::clear_save_file_of_scenario_specific_data()
1547 {
1548   Playerlist *plist = Playerlist::getInstance();
1549   for (Playerlist::iterator i = plist->begin(); i != plist->end(); i++)
1550     {
1551       (*i)->clearActionlist();
1552       (*i)->clearHistorylist();
1553       (*i)->clearStacklist();
1554       (*i)->clearFogMap();
1555       (*i)->setGold(1000);
1556       (*i)->revive();
1557     }
1558 }
1559
1560 void MainWindow::on_import_map_activated()
1561 {
1562     Gtk::FileChooserDialog chooser(*window, _("Choose Game to Load Map from"));
1563     Gtk::FileFilter sav_filter;
1564     sav_filter.add_pattern("*.sav");
1565     chooser.set_filter(sav_filter);
1566     chooser.set_current_folder(File::getSavePath());
1567
1568     chooser.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1569     chooser.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
1570     chooser.set_default_response(Gtk::RESPONSE_ACCEPT);
1571         
1572     chooser.show_all();
1573     int res = chooser.run();
1574     
1575     if (res == Gtk::RESPONSE_ACCEPT)
1576     {
1577         std::string filename = chooser.get_filename();
1578         chooser.hide();
1579
1580         clear_map_state();
1581
1582         bool broken;
1583         if (game_scenario)
1584           delete game_scenario;
1585         game_scenario = new GameScenario(filename, broken);
1586
1587         if (broken)
1588         {
1589             show_error(String::ucompose(_("Could not load game %1."),
1590                                         filename));
1591             current_save_filename = "";
1592             return;
1593         }
1594
1595         if (d_create_scenario_names)
1596           delete d_create_scenario_names;
1597         d_create_scenario_names = new CreateScenarioRandomize();
1598
1599         //now lets get rid of stuff.
1600         clear_save_file_of_scenario_specific_data();
1601
1602         init_map_state();
1603         bigmap->screen_size_changed(bigmap_drawingarea->get_allocation()); 
1604     }
1605 }
1606       
1607 void MainWindow::redraw()
1608 {
1609   bigmap->draw(Playerlist::getViewingplayer());
1610   smallmap->draw(Playerlist::getActiveplayer());
1611 }
1612
1613 void MainWindow::on_switch_sets_activated()
1614 {
1615   SwitchSetsDialog d;
1616   int response = d.run();
1617   if (response == Gtk::RESPONSE_ACCEPT)
1618     {
1619       needs_saving = true;
1620       bigmap->screen_size_changed(bigmap_drawingarea->get_allocation()); 
1621       redraw();
1622       fill_players();
1623     }
1624 }
1625     
1626         
1627 void MainWindow::on_player_toggled(PlayerItem item)
1628 {
1629   Player *p = Playerlist::getInstance()->getPlayer(item.player_id);
1630   if (p)
1631     Playerlist::getInstance()->setActiveplayer(p);
1632   fill_players();
1633 }
1634
1635 void MainWindow::fill_players()
1636 {
1637   for (std::list<PlayerItem>::iterator it = player_buttons.begin();
1638        it != player_buttons.end(); it++)
1639     players_hbox->remove(dynamic_cast<Gtk::Widget&>(*(*it).button));
1640   player_buttons.clear();
1641   Playerlist *pl = Playerlist::getInstance();
1642 //  bool sensitive = players_hbox->get_sensitive();
1643   bool sensitive = false;
1644   if (!sensitive)
1645     players_hbox->set_sensitive(true);
1646   for (Playerlist::iterator it = pl->begin(); it != pl->end(); it++)
1647     {
1648       Gtk::ToggleButton *toggle = new Gtk::ToggleButton();
1649       toggle->foreach(sigc::mem_fun(toggle, &Gtk::Container::remove));
1650
1651       Gtk::Image *image = new Gtk::Image();
1652       image->property_pixbuf() = 
1653         GraphicsCache::getInstance()->getShieldPic(1, *it)->to_pixbuf();
1654       toggle->add(*manage(image));
1655       toggle->show_all();
1656       if (*it == pl->getActiveplayer())
1657         toggle->set_active(true);
1658
1659       struct PlayerItem item;
1660       item.button = toggle;
1661       item.player_id = (*it)->getId();
1662       player_buttons.push_back(item);
1663       toggle->set_tooltip_text((*it)->getName());
1664       players_hbox->pack_start(*manage(toggle), Gtk::PACK_SHRINK);
1665       toggle->signal_toggled().connect
1666         (sigc::bind(sigc::mem_fun(this, &MainWindow::on_player_toggled), item));
1667     }
1668   players_hbox->show_all();
1669   if (!sensitive)
1670     players_hbox->set_sensitive(false);
1671 }