The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
context_manager.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2016 by David White <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 #define GETTEXT_DOMAIN "wesnoth-editor"
15 
16 #include "resources.hpp"
17 #include "team.hpp"
18 
19 #include "context_manager.hpp"
20 #include "display.hpp"
21 #include "filesystem.hpp"
22 #include "filechooser.hpp"
23 #include "formula/string_utils.hpp"
24 #include "gettext.hpp"
27 #include "map_context.hpp"
28 
29 #include "editor/action/action.hpp"
32 
37 #include "gui/dialogs/message.hpp"
39 #include "gui/widgets/window.hpp"
40 
43 
44 #include "terrain/translation.hpp"
45 
46 #include "wml_separators.hpp"
47 
48 namespace {
49 static std::vector<std::string> saved_windows_;
50 }
51 
52 namespace editor {
53 
55 
57  return current_labels;
58 }
59 
60 
61 /**
62  * Utility class to properly refresh the display when the map context object is replaced
63  * without duplicating code.
64  */
66 {
67 public:
69  : context_manager_(ec), size_changed_(!ec.get_map().same_size_as(other_mc.get_map())), refreshed_(false)
70  {
71  }
73  if (!refreshed_) refresh();
74  }
75  void refresh() {
77 
80 
81  // TODO register the tod_manager with the gui?
83 
85 
86 
89 
91 
93 
94  current_labels->enable(false);
95  current_labels = &context_manager_.get_map_context().get_labels();
96  current_labels->enable(true);
97 
98  refreshed_ = true;
99  }
100 private:
104 };
105 
107  switch (auto_update_transitions_) {
108 
110  return (item == "editor-auto-update-transitions");
112  return (item == "editor-partial-update-transitions");
114  return (item == "editor-no-update-transitions");
115  }
116  return true; //should not be reached
117 }
118 
120  std::vector<std::string> modified;
121  for (map_context* mc : map_contexts_) {
122  if (mc->modified()) {
123  if (!mc->get_filename().empty()) {
124  modified.push_back(mc->get_filename());
125  } else {
126  modified.push_back(_("(New Map)"));
127  }
128  }
129  }
130  for (std::string& str : modified) {
131  message += "\n" + std::string("• ") + str;
132  }
133  return modified.size();
134 }
135 
137  : gui_(gui)
138  , game_config_(game_config)
139  , default_dir_(preferences::editor::default_dir())
140  , map_generators_()
141  , last_map_generator_(nullptr)
142  , current_context_index_(0)
143  , auto_update_transitions_(preferences::editor::auto_update_transitions())
144  , map_contexts_()
145  , clipboard_()
146 {
147  if (default_dir_.empty()) {
149  }
151  init_map_generators(game_config);
152 }
153 
155 {
156  for (map_generator* m : map_generators_) {
157  delete m;
158  }
159  for (map_context* mc : map_contexts_) {
160  delete mc;
161  }
162 
163  // Restore default window title
165 }
166 
168 {
169  gui_.rebuild_all();
173  gui_.draw(false);
176 }
177 
179 {
180  default_dir_ = str;
181 }
182 
183 void context_manager::load_map_dialog(bool force_same_context /* = false */)
184 {
186  if (fn.empty()) {
187  fn = default_dir_;
188  }
189  int res = dialogs::show_file_chooser_dialog(gui_.video(), fn, _("Choose a File to Open"));
190  if (res == 0) {
191  load_map(fn, !force_same_context);
192  }
193 }
194 
195 void context_manager::load_mru_item(unsigned int index, bool force_same_context /* = false */)
196 {
197  const std::vector<std::string>& mru = preferences::editor::recent_files();
198 
199  if(mru.empty() || index >= mru.size()) {
200  return;
201  }
202 
203  load_map(mru[index], !force_same_context);
204 }
205 
207 {
208  team& t = get_map_context().get_teams()[side];
209 
210  //TODO
211  //t.support()
212 
213  team::CONTROLLER controller = t.controller();
214 
215  std::string user_team_name = t.user_team_name();
216  std::string team_name = t.team_name();
217 
218  int gold = t.gold();
219  int income = t.base_income();
220  int village_gold = t.village_gold();
222 
223  bool no_leader = t.no_leader();
224  bool hidden = t.hidden();
225  bool fog = t.uses_fog();
226  bool shroud = t.uses_shroud();
227 
228  team::SHARE_VISION share_vision = t.share_vision();
229 
230  bool ok = gui2::teditor_edit_side::execute(side +1, team_name, user_team_name,
231  gold, income, village_gold, village_support,
232  fog, shroud, share_vision,
233  controller, no_leader, hidden,
234  gui_.video());
235 
236  if (ok) {
237  get_map_context().set_side_setup(side, team_name, user_team_name,
238  gold, income, village_gold, village_support,
239  fog, shroud, share_vision, controller, hidden, no_leader);
240  }
241 }
242 
244 {
245  // TODO
246  //std::string fn = filesystem::directory_name(get_map_context().get_filename());
247 
250  std::string description = get_map_context().get_description();
251 
253  int xp_mod = get_map_context().get_xp_mod();
254 
255  bool victory = get_map_context().victory_defeated();
256  bool random = get_map_context().random_start_time();
257 
258  bool ok = gui2::teditor_edit_scenario::execute(id, name, description,
259  turns, xp_mod,
260  victory, random,
261  gui_.video());
262 
263  if (ok) {
264  get_map_context().set_scenario_setup(id, name, description,
265  turns, xp_mod,
266  victory, random);
267  }
268 }
269 
271 {
272  int w = get_map().w();
273  int h = get_map().h();
276  new_map(w, h, fill, true);
277  }
278 }
279 
281 {
282  int w = get_map().w();
283  int h = get_map().h();
286  new_scenario(w, h, fill, true);
287  }
288 }
289 
290 void context_manager::expand_open_maps_menu(std::vector<std::string>& items)
291 {
292  for (unsigned int i = 0; i < items.size(); ++i) {
293  if (items[i] == "editor-switch-map") {
294  items.erase(items.begin() + i);
295  std::vector<std::string> contexts;
296  for (size_t mci = 0; mci < map_contexts_.size(); ++mci) {
297  std::string filename = map_contexts_[mci]->get_filename();
298  bool changed = map_contexts_[mci]->modified();
299  bool pure_map = map_contexts_[mci]->is_pure_map();
300  if (filename.empty()) {
301  if (pure_map)
302  filename = _("(New Map)");
303  else
304  filename = _("(New Scenario)");
305  }
306  std::string label = "[" + std::to_string(mci) + "] "
307  + filename + (changed ? " [*]" : "");
308  if (map_contexts_[mci]->is_embedded()) {
309  label += " (E)";
310  }
311  contexts.push_back(label);
312  }
313  items.insert(items.begin() + i, contexts.begin(), contexts.end());
314  break;
315  }
316  }
317 }
318 
319 void context_manager::expand_load_mru_menu(std::vector<std::string>& items)
320 {
321  std::vector<std::string> mru = preferences::editor::recent_files();
322 
323  for (unsigned int i = 0; i < items.size(); ++i) {
324  if (items[i] != "EDITOR-LOAD-MRU-PLACEHOLDER") {
325  continue;
326  }
327 
328  items.erase(items.begin() + i);
329 
330  if(mru.empty()) {
331  items.insert(items.begin() + i, _("No Recent Files"));
332  continue;
333  }
334 
335  for (std::string& path : mru)
336  {
337  // TODO: add proper leading ellipsization instead, since otherwise
338  // it'll be impossible to tell apart files with identical names and
339  // different parent paths.
341  }
342 
343  items.insert(items.begin() + i, mru.begin(), mru.end());
344  break;
345  }
346 
347 }
348 
349 void context_manager::expand_areas_menu(std::vector<std::string>& items)
350 {
352 
353  if (!tod)
354  return;
355  for (unsigned int i = 0; i < items.size(); ++i) {
356  if (items[i] == "editor-switch-area") {
357  items.erase(items.begin() + i);
358  std::vector<std::string> area_entries;
359 
360  std::vector<std::string> area_ids =
361  tod->get_area_ids();
362 
363  for (size_t mci = 0; mci < area_ids.size(); ++mci) {
364 
365  const std::string& area = area_ids[mci];
366  std::stringstream label;
367  label << "[" << mci+1 << "] ";
368  label << (area.empty() ? _("(Unnamed Area)") : area);
369 
370  if (mci == static_cast<size_t>(get_map_context().get_active_area())
371  && tod->get_area_by_index(mci) != get_map_context().get_map().selection())
372  label << " [*]";
373 
374  area_entries.push_back(label.str());
375  }
376 
377  items.insert(items.begin() + i,
378  area_entries.begin(), area_entries.end());
379  break;
380  }
381  }
382 }
383 
384 void context_manager::expand_sides_menu(std::vector<std::string>& items)
385 {
386  for (unsigned int i = 0; i < items.size(); ++i) {
387  if (items[i] == "editor-switch-side") {
388  items.erase(items.begin() + i);
389  std::vector<std::string> contexts;
390 
391  for (size_t mci = 0; mci < get_map_context().get_teams().size(); ++mci) {
392 
393  const team& t = get_map_context().get_teams()[mci];
394  const std::string& teamname = t.user_team_name();
395  std::stringstream label;
396  label << "[" << mci+1 << "] ";
397  label << (teamname.empty() ? _("(New Side)") : teamname);
398  contexts.push_back(label.str());
399  }
400 
401  items.insert(items.begin() + i, contexts.begin(), contexts.end());
402  break;
403  }
404  }
405 }
406 
407 void context_manager::expand_time_menu(std::vector<std::string>& items)
408 {
409  for (unsigned int i = 0; i < items.size(); ++i) {
410  if (items[i] == "editor-switch-time") {
411  items.erase(items.begin() + i);
412  std::vector<std::string> times;
413 
415 
416  assert(tod_m != nullptr);
417 
418  for (const time_of_day& time : tod_m->times()) {
419 
420  std::stringstream label;
421  if (!time.image.empty())
422  label << IMAGE_PREFIX << time.image << IMG_TEXT_SEPARATOR;
423  label << time.name;
424  times.push_back(label.str());
425  }
426 
427  items.insert(items.begin() + i, times.begin(), times.end());
428  break;
429  }
430  }
431 }
432 
433 void context_manager::expand_local_time_menu(std::vector<std::string>& items)
434 {
435  for (unsigned int i = 0; i < items.size(); ++i) {
436  if (items[i] == "editor-assign-local-time") {
437  items.erase(items.begin() + i);
438  std::vector<std::string> times;
439 
441 
442  for (const time_of_day& time : tod_m->times(get_map_context().get_active_area())) {
443 
444  std::stringstream label;
445  if (!time.image.empty())
446  label << IMAGE_PREFIX << time.image << IMG_TEXT_SEPARATOR;
447  label << time.name;
448  times.push_back(label.str());
449  }
450 
451  items.insert(items.begin() + i, times.begin(), times.end());
452  break;
453  }
454  }
455 }
456 
458 {
460  if (fn.empty()) {
461  fn = default_dir_;
462  }
463  int res = dialogs::show_file_chooser_dialog(gui_.video(), fn, _("Choose a Mask to Apply"));
464  if (res == 0) {
465  try {
469  } catch (editor_map_load_exception& e) {
470  gui2::show_transient_message(gui_.video(), _("Error loading mask"), e.what());
471  return;
472  } catch (editor_action_exception& e) {
474  return;
475  }
476  }
477 }
478 
479 void context_manager::perform_refresh(const editor_action& action, bool drag_part /* =false */)
480 {
482  refresh_after_action(drag_part);
483 }
484 
486 {
487  int active_area = get_map_context().get_active_area();
489  if (gui2::tedit_text::execute(N_("Rename Area"), N_("Identifier:"), name, gui_.video())) {
490  get_map_context().get_time_manager()->set_area_id(active_area, name);
491  }
492 }
493 
495 {
497  if (fn.empty()) {
498  fn = default_dir_;
499  }
500  int res = dialogs::show_file_chooser_dialog(gui_.video(), fn, _("Choose Target Map"));
501  if (res == 0) {
502  try {
503  map_context map(game_config_, fn, gui_);
506  } catch (editor_map_load_exception& e) {
507  gui2::show_transient_message(gui_.video(), _("Error loading map"), e.what());
508  return;
509  } catch (editor_action_exception& e) {
511  return;
512  }
513  }
514 }
515 
517 {
518  if (get_map_context().needs_reload()) {
519  reload_map();
520  return;
521  } else {
522  const std::set<map_location>& changed_locs =
524 
525  if (get_map_context().needs_terrain_rebuild()) {
528  && (!drag_part || get_map_context().everything_changed()))) {
529  gui_.rebuild_all();
532  } else {
533  for (const map_location& loc : changed_locs) {
534  gui_.rebuild_terrain(loc);
535  }
536  gui_.invalidate(changed_locs);
537  }
538  } else {
539  if (get_map_context().everything_changed()) {
541  } else {
542  gui_.invalidate(changed_locs);
543  }
544  }
545  if (get_map_context().needs_labels_reset()) {
547  }
548  }
551 }
552 
554 {
555  int w = get_map().w();
556  int h = get_map().h();
558  bool copy = false;
559  if(gui2::teditor_resize_map::execute(w, h, dir, copy, gui_.video())) {
560 
561  if (w != get_map().w() || h != get_map().h()) {
563  if (copy) {
565  }
566  int x_offset = get_map().w() - w;
567  int y_offset = get_map().h() - h;
568  switch (dir) {
572  y_offset = 0;
573  break;
577  y_offset /= 2;
578  break;
582  break;
583  default:
584  y_offset = 0;
585  WRN_ED << "Unknown resize expand direction" << std::endl;
586  break;
587  }
588  switch (dir) {
592  x_offset = 0;
593  break;
597  x_offset /= 2;
598  break;
602  break;
603  default:
604  x_offset = 0;
605  break;
606  }
607  editor_action_resize_map a(w, h, x_offset, y_offset, fill);
608  perform_refresh(a);
609  }
610  }
611 }
612 
614 {
615  std::string input_name = get_map_context().get_filename();
616  if (input_name.empty()) {
617  input_name = filesystem::get_dir(default_dir_ + "/maps");
618  }
619  const std::string old_input_name = input_name;
620 
621  int overwrite_res = 1;
622  do {
623  input_name = old_input_name;
624  int res = dialogs::show_file_chooser_dialog_save(gui_.video(), input_name, _("Save the Map As"), ".map");
625  if (res == 0) {
626  if (filesystem::file_exists(input_name)) {
627  res = gui2::show_message(gui_.video(), "",
628  _("The file already exists. Do you want to overwrite it?"), gui2::tmessage::yes_no_buttons);
629  overwrite_res = gui2::twindow::CANCEL == res ? 1 : 0;
630  } else {
631  overwrite_res = 0;
632  }
633  } else {
634  return; //cancel pressed
635  }
636  } while (overwrite_res != 0);
637 
638  save_map_as(input_name);
639 }
640 
642 {
643  std::string input_name = get_map_context().get_filename();
644  if (input_name.empty()) {
645  input_name = filesystem::get_dir(default_dir_ + "/scenarios");
646  }
647  const std::string old_input_name = input_name;
648 
649  int overwrite_res = 1;
650  do {
651  input_name = old_input_name;
652  int res = dialogs::show_file_chooser_dialog_save(gui_.video(), input_name, _("Save the Scenario As"), ".cfg");
653  if (res == 0) {
654  if (filesystem::file_exists(input_name)) {
655  res = gui2::show_message(gui_.video(), "",
656  _("The file already exists. Do you want to overwrite it?"), gui2::tmessage::yes_no_buttons);
657  overwrite_res = gui2::twindow::CANCEL == res ? 1 : 0;
658  } else {
659  overwrite_res = 0;
660  }
661  } else {
662  return; //cancel pressed
663  }
664  } while (overwrite_res != 0);
665 
666  save_scenario_as(input_name);
667 }
668 
670 {
671  for (const config &i : game_config.child_range("multiplayer")) {
672 
673  if (!i["map_generation"].empty() || !i["scenario_generation"].empty()) {
674 
675  const config &generator_cfg = i.child("generator");
676  if (!generator_cfg) {
677  ERR_ED << "Scenario \"" << i["name"] << "\" with id " << i["id"]
678  << " has map_generation= but no [generator] tag";
679  } else {
680  map_generator* m = create_map_generator(i["map_generation"], generator_cfg);
681  map_generators_.push_back(m);
682  }
683  }
684  }
685 }
686 
688 {
689  if (map_generators_.empty()) {
691  _("No random map generators found."));
692  return;
693  }
697  dialog.show(gui_.video());
698  if (dialog.get_retval() == gui2::twindow::OK) {
699  std::string map_string;
701  try {
702  map_string = map_generator->create_map(dialog.get_seed());
703  } catch (mapgen_exception& e) {
704  gui2::show_transient_message(gui_.video(), _("Map creation failed."), e.what());
705  return;
706  }
707  if (map_string.empty()) {
708  gui2::show_transient_message(gui_.video(), "", _("Map creation failed."));
709  } else {
710  editor_map new_map(game_config_, map_string);
711  editor_action_whole_map a(new_map);
712  get_map_context().set_needs_labels_reset(); // Ensure Player Start labels are updated together with newly generated map
713  perform_refresh(a);
714  }
715  last_map_generator_ = map_generator;
716  }
717 }
718 
720 {
721  if (get_map_context().modified()) {
722  const int res = gui2::show_message(gui_.video(), _("Unsaved Changes"),
723  _("Do you want to discard all changes made to the map since the last save?"), gui2::tmessage::yes_no_buttons);
724  return gui2::twindow::CANCEL != res;
725  } else {
726  return true;
727  }
728 }
729 
731 {
732  map_contexts_.push_back(mc);
733  return map_contexts_.size() - 1;
734 }
735 
737 {
738  if(saved_windows_.empty()) {
739 
742  const config& default_schedule = game_config_.find_child("editor_times", "id", "default");
743  map_context* mc = new map_context(editor_map(game_config_, 44, 33, default_terrain), gui_, true, default_schedule);
744  add_map_context(mc);
745  } else {
746  for (const std::string& filename : saved_windows_) {
747  map_context* mc = new map_context(game_config_, filename, gui_);
748  add_map_context(mc);
749  }
750  saved_windows_.clear();
751  }
752 }
753 
755 {
758 }
759 
761 {
762  if (!confirm_discard()) return;
764  if (map_contexts_.size() == 1) {
766  map_contexts_.erase(map_contexts_.begin());
767  } else if (current_context_index_ == static_cast<int>(map_contexts_.size()) - 1) {
768  map_contexts_.pop_back();
770  } else {
772  }
773  map_context_refresher(*this, *current);
774  delete current;
775 
777 }
778 
779 void context_manager::save_all_maps(bool auto_save_windows)
780 {
781  int current = current_context_index_;
782  saved_windows_.clear();
783  for(size_t i = 0; i < map_contexts_.size(); ++i) {
784  switch_context(i);
786  if(auto_save_windows) {
787  if(name.empty() || filesystem::is_directory(name)) {
788  std::ostringstream s;
789  s << default_dir_ << "/" << "window_" << i;
790  name = s.str();
792  }
793  }
794  saved_windows_.push_back(name);
795  save_map();
796  }
797  switch_context(current);
798 }
799 
801 {
803  if (name.empty() || filesystem::is_directory(name)) {
806  else
808  } else {
809  if (get_map_context().is_pure_map())
810  write_map();
811  else
812  write_scenario();
813  }
814 }
815 
817 {
818  size_t is_open = check_open_map(filename);
819  if (is_open < map_contexts_.size()
820  && is_open != static_cast<unsigned>(current_context_index_)) {
821 
822  gui2::show_transient_message(gui_.video(), _("This scenario is already open."), filename);
823  return false;
824  }
825  std::string old_filename = get_map_context().get_filename();
826  bool embedded = get_map_context().is_embedded();
827  get_map_context().set_filename(filename);
828  get_map_context().set_embedded(false);
829  if (!write_scenario(true)) {
830  get_map_context().set_filename(old_filename);
831  get_map_context().set_embedded(embedded);
832  return false;
833  } else {
834  return true;
835  }
836 }
837 
839 {
840  size_t is_open = check_open_map(filename);
841  if (is_open < map_contexts_.size()
842  && is_open != static_cast<unsigned>(current_context_index_)) {
843 
844  gui2::show_transient_message(gui_.video(), _("This map is already open."), filename);
845  return false;
846  }
847  std::string old_filename = get_map_context().get_filename();
848  bool embedded = get_map_context().is_embedded();
849  get_map_context().set_filename(filename);
850  get_map_context().set_embedded(false);
851  if (!write_map(true)) {
852  get_map_context().set_filename(old_filename);
853  get_map_context().set_embedded(embedded);
854  return false;
855  } else {
856  return true;
857  }
858 }
859 
860 bool context_manager::write_scenario(bool display_confirmation)
861 {
862  try {
864  if (display_confirmation) {
865  gui2::show_transient_message(gui_.video(), "", _("Scenario saved."));
866  }
867  } catch (editor_map_save_exception& e) {
869  return false;
870  }
871  return true;
872 }
873 
874 bool context_manager::write_map(bool display_confirmation)
875 {
876  try {
878  if (display_confirmation) {
879  gui2::show_transient_message(gui_.video(), "", _("Map saved."));
880  }
881  } catch (editor_map_save_exception& e) {
883  return false;
884  }
885  return true;
886 }
887 
889 {
890  size_t i = 0;
891  while (i < map_contexts_.size() && map_contexts_[i]->get_filename() != fn) ++i;
892  return i;
893 }
894 
896 {
897  size_t i = check_open_map(fn);
898  if (i < map_contexts_.size()) {
899  gui2::show_transient_message(gui_.video(), _("This map is already open."), fn);
900  switch_context(i);
901  return true;
902  }
903  return false;
904 }
905 
906 void context_manager::load_map(const std::string& filename, bool new_context)
907 {
908  if (new_context && check_switch_open_map(filename)) return;
909  LOG_ED << "Load map: " << filename << (new_context ? " (new)" : " (same)") << "\n";
910  try {
912  if (mc->get_filename() != filename) {
913  if (new_context && check_switch_open_map(mc->get_filename())) return;
914  }
915  if (new_context) {
916  int new_id = add_map_context(mc.release());
917  switch_context(new_id);
918  } else {
920  }
921  if (get_map_context().is_embedded()) {
922  const std::string& msg = _("Loaded embedded map data");
923  gui2::show_transient_message(gui_.video(), _("Map loaded from scenario"), msg);
924  } else {
925  if (get_map_context().get_filename() != filename) {
926  if (get_map_context().get_map_data_key().empty()) {
927  ERR_ED << "Internal error, map context filename changed: "
928  << filename << " -> " << get_map_context().get_filename()
929  << " with no apparent scenario load\n";
930  } else {
931  utils::string_map symbols;
932  symbols["old"] = filename;
933  const std::string& msg = _("Loaded referenced map file:\n"
934  "$new");
935  symbols["new"] = get_map_context().get_filename();
936  symbols["map_data"] = get_map_context().get_map_data_key();
937  gui2::show_transient_message(gui_.video(), _("Map loaded from scenario"),
938  //TODO: msg is already translated does vgettext make sense ?
939  vgettext(msg.c_str(), symbols));
940  }
941  }
942  }
943  } catch (editor_map_load_exception& e) {
944  gui2::show_transient_message(gui_.video(), _("Error loading map"), e.what());
945  return;
946  }
947 }
948 
950 {
951  if (!confirm_discard()) return;
953  if (filename.empty()) {
954  ERR_ED << "Empty filename in map revert" << std::endl;
955  return;
956  }
957  load_map(filename, false);
958 }
959 
960 void context_manager::new_map(int width, int height, const t_translation::t_terrain & fill, bool new_context)
961 {
962  const config& default_schedule = game_config_.find_child("editor_times", "id", "default");
963  editor_map m(game_config_, width, height, fill);
964  if (new_context) {
965  int new_id = add_map_context(new map_context(m, gui_, true, default_schedule));
966  switch_context(new_id);
967  } else {
968  replace_map_context(new map_context(m, gui_, true, default_schedule));
969  }
970 }
971 
972 void context_manager::new_scenario(int width, int height, const t_translation::t_terrain & fill, bool new_context)
973 {
974  const config& default_schedule = game_config_.find_child("editor_times", "id", "default");
975  editor_map m(game_config_, width, height, fill);
976  if (new_context) {
977  int new_id = add_map_context(new map_context(m, gui_, false, default_schedule));
978  switch_context(new_id);
979  } else {
980  replace_map_context(new map_context(m, gui_, false, default_schedule));
981  }
982 }
983 
985 {
986  gui_.reload_map();
989  refresh_all();
990 }
991 
992 void context_manager::switch_context(const int index, const bool force)
993 {
994  if (index < 0 || static_cast<size_t>(index) >= map_contexts_.size()) {
995  WRN_ED << "Invalid index in switch map context: " << index << std::endl;
996  return;
997  }
998  if (index == current_context_index_ && !force) {
999  return;
1000  }
1001  map_context_refresher mcr(*this, *map_contexts_[index]);
1002  current_labels = &get_map_context().get_labels();
1004 
1005  set_window_title();
1006 }
1007 
1009 {
1010  boost::scoped_ptr<map_context> del(map_contexts_[current_context_index_]);
1011  map_context_refresher mcr(*this, *new_mc);
1013 
1014  set_window_title();
1015 }
1016 
1018 {
1020 
1021  if(map_name.empty()){
1022  map_name = get_map_context().is_pure_map() ? _("New Map") : _("New Scenario");
1023  }
1024 
1025  const std::string& wm_title_string = map_name + " - " + game_config::get_default_title_string();
1026  CVideo::get_singleton().set_window_title(wm_title_string);
1027 }
1028 
1029 } //Namespace editor
map_labels * get_current_labels()
bool write_scenario(bool display_confirmation=false)
bool uses_shroud() const
Definition: team.hpp:315
child_itors child_range(const std::string &key)
Definition: config.cpp:613
void expand_areas_menu(std::vector< std::string > &items)
Menu expanding for the map's defined areas.
int show_file_chooser_dialog_save(CVideo &video, std::string &filename, std::string const &title, const std::string &default_file_name, bool show_directory_buttons, const std::string &type_a_head, int xloc, int yloc)
Show a filechooser dialog in a "save" mode, that is, without relying on autocomplete to allow saving ...
Definition: filechooser.cpp:44
bool victory_defeated() const
void show_error_message(CVideo &video, const std::string &message, bool message_use_markup)
Shows an error message to the user.
Definition: message.cpp:198
char const IMG_TEXT_SEPARATOR
map_generator * get_selected_map_generator()
::tod_manager * tod_manager
Definition: resources.cpp:31
void apply_mask_dialog()
Display an apply mask dialog and process user input.
bool check_switch_open_map(const std::string &fn)
Check if a map is already open.
int auto_update_transitions_
Flag to rebuild terrain on every terrain change.
std::vector< std::string > recent_files()
Retrieves the list of recently opened files.
void edit_scenario_dialog()
Display a scenario edit dialog and process user input.
int get_retval() const
Definition: dialog.hpp:161
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
Definition: display.cpp:3536
int village_support
Definition: game_config.cpp:39
game_classification * classification
Definition: resources.cpp:37
int add_map_context(map_context *mc)
Add a map context.
const char * what() const
Definition: exceptions.hpp:35
void change_display_context(const display_context *dc)
Definition: display.cpp:493
void replace_map_context(map_context *new_mc)
Replace the current map context and refresh accordingly.
void set_map_generators(std::vector< map_generator * > mg)
void new_map(int width, int height, const t_translation::t_terrain &fill, bool new_context)
Create a new map.
const mp_game_settings * mp_settings
Definition: resources.cpp:38
void reload_map()
Reload the map after it has significantly changed (when e.g.
bool save_scenario()
Saves the scenario under the current filename.
void resize_map_dialog()
Display a load map dialog and process user input.
const t_terrain NONE_TERRAIN
Definition: translation.hpp:56
bool show(CVideo &video, const unsigned auto_close_time=0)
Shows the window.
Definition: dialog.cpp:34
bool hidden() const
Definition: team.hpp:344
void save_scenario_as_dialog()
Display a save map as dialog and process user input.
void rename_area_dialog()
Display an dialog to querry a new id for an [time_area].
static bool execute(std::string &id, std::string &name, std::string &description, int &turns, int &experience_modifier, bool &victory_when_enemies_defeated, bool &random_start_time, CVideo &video)
The execute function see tdialog for more information.
void refresh_after_action(bool drag_part=false)
Refresh the display after an action has been performed.
void init_flags()
Init the flag list and the team colors used by ~TC.
Definition: display.cpp:265
This file contains the window object, this object is a top level container which has the event manage...
void expand_time_menu(std::vector< std::string > &items)
Menu expanding for the map's defined areas.
void set_area_id(int area_index, const std::string &id)
context_manager(editor_display &gui, const config &game_config)
map_labels & get_labels()
void save_map()
Save the map, open dialog if not named yet.
#define LOG_ED
General purpose widgets.
std::string default_dir_
Default directory for map load/save as dialogs.
std::string get_default_title_string()
void perform_refresh(const editor_action &action, bool drag_part=false)
Perform an action on the current map_context, then refresh the display.
static CVideo & get_singleton()
Definition: video.hpp:75
void show_transient_message(CVideo &video, const std::string &title, const std::string &message, const std::string &image, const bool message_use_markup, const bool title_use_markup, const bool restore_background)
Shows a transient message to the user.
mp_game_settings & get_mp_settings()
#define h
size_t check_open_map(const std::string &fn) const
Check if a map is already open.
const std::string & get_filename() const
const std::vector< std::string > items
virtual void draw()
Draws invalidated items.
Definition: display.cpp:2706
Replace contents of the entire map, Useful as a fallback undo method when something else would be imp...
Definition: action.hpp:38
-file sdl_utils.hpp
bool confirm_discard()
Shows an are-you-sure dialog if the map was modified.
GLdouble GLdouble t
Definition: glew.h:1366
void set_default_dir(const std::string &str)
Set the default dir (where the filebrowser is pointing at when there is no map file opened) ...
t_terrain read_terrain_code(const std::string &str, const t_layer filler)
Reads a single terrain from a string.
void set_needs_reload(bool value=true)
Setter for the reload flag.
map_context & get_map_context()
Get the current map context object.
const std::string & get_description() const
int get_xp_mod() const
void refresh_all()
Refresh everything, i.e.
void set_scenario_setup(const std::string &id, const std::string &name, const std::string &description, int turns, int xp_mod, bool victory_defeated, bool random_time)
TODO.
void revert_map()
Revert the map by reloading it from disk.
char const IMAGE_PREFIX
const std::set< map_location > changed_locations() const
SHARE_VISION share_vision() const
Definition: team.hpp:388
void edit_side_dialog(int side)
TODO.
const editor_map & get_map() const
Get the map from the current map context object - const version.
void set_side_setup(int side, const std::string &id, const std::string &name, int gold, int income, int village_gold, int village_support, bool fog, bool shroud, team::SHARE_VISION share_vision, team::CONTROLLER controller, bool hidden, bool no_leader)
TODO.
#define WRN_ED
overlay_map & get_overlays()
game_classification & get_classification()
void set_window_title(const std::string &title)
Sets the title of the main window.
Definition: video.cpp:550
static map_labels * current_labels
Object which defines a time of day with associated bonuses, image, sounds etc.
Definition: time_of_day.hpp:48
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:50
void close_current_context()
Closes the active map context.
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
const std::string & get_name() const
tod_manager * get_time_manager()
static bool execute(const std::string &title, const std::string &label, std::string &text, CVideo &video)
Executes the dialog.
Definition: edit_text.hpp:51
GLsizei const char ** path
Definition: glew.h:4654
Dialog is closed with ok button.
Definition: window.hpp:125
std::vector< map_generator * > map_generators_
Available random map generators.
std::map< std::string, t_string > string_map
bool is_pure_map() const
std::vector< team > * teams
Definition: resources.cpp:29
int village_support() const
Definition: team.hpp:204
void expand_sides_menu(std::vector< std::string > &items)
Menu expanding for the map's player sides.
void load_map_dialog(bool force_same_context=false)
Display a load map dialog and process user input.
const t_string & user_team_name() const
Definition: team.hpp:298
std::string get_user_data_dir()
void select_map_generator(map_generator *mg)
void reset_starting_position_labels(display &disp)
void recalculate_minimap()
Schedule the minimap for recalculation.
Definition: display.hpp:623
Dialog is closed with the cancel button.
Definition: window.hpp:126
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1858
int base_income() const
Definition: team.hpp:196
std::string base_name(const std::string &file)
Returns the base filename of a file, with directory name stripped.
void set_embedded(bool v)
int w() const
Effective map width.
Definition: map.hpp:105
void show_message(CVideo &video, const std::string &title, const std::string &message, const std::string &button_caption, const bool auto_close, const bool message_use_markup)
Shows a message to the user.
Definition: message.cpp:143
editor_map & get_map()
Map accessor.
Definition: map_context.hpp:75
virtual std::string create_map(boost::optional< boost::uint32_t > randomseed=boost::none)=0
Creates a new map and returns it.
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:7319
The dialog for selecting which random generator to use in the editor.
void new_scenario_dialog()
Display a new map dialog and process user input.
bool is_directory(const std::string &fname)
Returns true if the given file is a directory.
Editor action classes.
const std::string & team_name() const
Definition: team.hpp:297
void expand_open_maps_menu(std::vector< std::string > &items)
Menu expanding for open maps list.
bool save_map()
Saves the map under the current filename.
void enable(bool is_enabled)
Definition: label.cpp:266
void expand_local_time_menu(std::vector< std::string > &items)
Menu expanding for the map's defined areas.
Modify, read and display user preferences.
bool no_leader() const
Definition: team.hpp:338
int show_file_chooser_dialog(CVideo &video, std::string &filename, std::string const &title, bool show_directory_buttons, const std::string &type_a_head, int xloc, int yloc)
Show a dialog where the user can navigate through files and select a file.
Definition: filechooser.cpp:30
map_display and display: classes which take care of displaying the map and game-data on the screen...
void create_buttons()
Definition: display.cpp:897
map_context_refresher(context_manager &ec, const map_context &other_mc)
Manage the empty-palette in the editor.
Definition: action.cpp:28
std::string default_terrain
Definition: game_config.cpp:49
void perform_action(const editor_action &action)
Performs an action (thus modifying the map).
void invalidate_all()
Function to invalidate all tiles.
Definition: display.cpp:3525
bool is_active_transitions_hotkey(const std::string &item)
Utility class to properly refresh the display when the map context object is replaced without duplica...
void switch_context(const int index, const bool force=false)
Switches the context to the one under the specified index.
std::string get_dir(const std::string &dir)
Paint the same terrain on a number of locations on the map.
Definition: action.hpp:244
void expand_load_mru_menu(std::vector< std::string > &items)
Menu expanding for most recent loaded list.
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:47
void load_map(const std::string &filename, bool new_context)
Load a map given the filename.
map_generator * create_map_generator(const std::string &name, const config &cfg)
Definition: map_create.cpp:31
void set_needs_terrain_rebuild(bool value=true)
Setter for the terrain rebuild flag.
Encapsulates the map of the game.
Definition: location.hpp:38
static bool execute(int &width, int &height, EXPAND_DIRECTION &expand_direction, bool &copy_edge_terrain, CVideo &video)
The execute function see tdialog for more information.
Definition: resize_map.hpp:74
void clear_changed_locations()
GLuint res
Definition: glew.h:9258
std::vector< team > & get_teams()
Get the team from the current map context object.
std::vector< map_context * > map_contexts_
The currently opened map context object.
std::vector< std::string > get_area_ids() const
This class adds extra editor-specific functionality to a normal gamemap.
Definition: editor_map.hpp:70
int h() const
Effective map height.
Definition: map.hpp:108
void fill_selection()
Fill the selection with the foreground terrain.
void save_map_as_dialog()
Display a save map as dialog and process user input.
bool write_map(bool display_confirmation=false)
Save the map under a given filename.
Game configuration data as global variables.
Definition: build_info.cpp:38
const t_translation::t_terrain & get_selected_bg_terrain()
void rebuild_terrain(const map_location &loc)
bool save_scenario_as(const std::string &filename)
unit_map & get_units()
Get the unit map from the current map context object.
GLuint index
Definition: glew.h:1782
editor_display & gui()
Base class for all editor actions.
Definition: action_base.hpp:41
const std::string & get_map_data_key() const
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:5910
const std::set< map_location > & get_area_by_index(int index) const
size_t i
Definition: function.cpp:1057
void save_all_maps(bool auto_save_windows=false)
Save all maps, open dialog if not named yet, except when using auto_save_windows which will name unna...
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:112
size_t modified_maps(std::string &modified)
void create_mask_to_dialog()
Display an apply mask dialog and process user input.
Declarations for File-IO.
bool random_start_time() const
This class wraps around a map to provide a concise interface for the editor to work with...
Definition: map_context.hpp:41
#define N_(String)
Definition: gettext.hpp:90
const std::set< map_location > & selection() const
Return the selection set.
Definition: editor_map.hpp:150
std::string vgettext(const char *msgid, const utils::string_map &symbols)
GLint GLint GLint GLint GLint GLint GLsizei GLsizei height
Definition: glew.h:1220
GLuint const GLchar * name
Definition: glew.h:1782
CONTROLLER controller() const
Definition: team.hpp:256
static std::string get_filename(const std::string &file_code)
map_generator * last_map_generator_
int gold() const
Definition: team.hpp:194
const GLdouble * m
Definition: glew.h:6968
void reload_map()
Updates internals that cache map size.
Definition: display.cpp:487
T * release()
Definition: util.hpp:448
bool uses_fog() const
Definition: team.hpp:316
void new_scenario(int width, int height, const t_translation::t_terrain &fill, bool new_context)
Create a new scenario.
#define ERR_ED
const std::vector< time_of_day > & times(const map_location &loc=map_location::null_location()) const
void set_needs_labels_reset(bool value=true)
Setter for the labels reset flag.
boost::optional< boost::uint32_t > get_seed()
config & find_child(const std::string &key, const std::string &name, const std::string &value)
Returns the first child of tag key with a name attribute containing value.
Definition: config.cpp:1010
CVideo & video()
Gets the underlying screen object.
Definition: display.hpp:202
void set_filename(const std::string &fn)
GLsizei GLenum GLuint GLuint GLsizei char * message
Definition: glew.h:2499
int get_active_area() const
void generate_map_dialog()
Display a generate random map dialog and process user input.
GLint GLint GLint GLint GLint GLint GLsizei width
Definition: glew.h:1220
void set_window_title()
Displays the specified map name in the window titlebar.
void create_default_context()
Creates a default map context object, used to ensure there is always at least one.
static bool execute(int &width, int &height, CVideo &video)
The execute function see tdialog for more information.
Definition: new_map.hpp:43
#define e
#define mask(n)
Definition: lbitlib.cpp:28
bool save_map_as(const std::string &filename)
Save the map under a given filename.
int village_gold() const
Definition: team.hpp:197
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
static bool execute(int side, std::string &team_name, std::string &user_team_name, int &gold, int &income, int &village_income, int &village_support, bool &fog, bool &shroud, team::SHARE_VISION &share_vision, team::CONTROLLER &controller, bool &no_leader, bool &hidden, CVideo &video)
The execute function see tdialog for more information.
Definition: edit_side.hpp:45
GLdouble s
Definition: glew.h:1358
void init_map_generators(const config &game_config)
init available random map generators
void load_mru_item(unsigned index, bool force_same_context=false)
Open the specified entry from the recent files list.
bool file_exists(const std::string &name)
Returns true if a file or directory with such name already exists.
GLsizei const GLcharARB ** string
Definition: glew.h:4503
bool is_embedded() const
unit_map * units
Definition: resources.cpp:35
Shows a yes and no button.
Definition: message.hpp:75
std::string directory_name(const std::string &file)
Returns the directory name of a file, with filename stripped.
void rebuild_all()
Rebuild all dynamic terrain.
Definition: display.cpp:482
int number_of_turns() const
void replace_overlay_map(overlay_map *overlays)
Definition: display.hpp:1175
void new_map_dialog()
Display a new map dialog and process user input.
const std::string & get_id() const