The Battle for Wesnoth  1.13.11+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 - 2018 by David White <dave@whitevine.net>
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 "display.hpp"
22 #include "filesystem.hpp"
23 #include "formula/string_utils.hpp"
24 #include "game_board.hpp"
27 #include "gettext.hpp"
28 
29 #include "editor/action/action.hpp"
31 #include "preferences/editor.hpp"
32 
38 #include "gui/dialogs/message.hpp"
40 #include "gui/widgets/window.hpp"
41 
44 
45 #include "terrain/translation.hpp"
46 
47 #include <memory>
48 
49 namespace editor {
50 
51 static std::vector<std::string> saved_windows_;
52 
53 static const std::string get_menu_marker(const bool changed)
54 {
55  std::ostringstream ss;
56  ss << "[<span ";
57 
58  if(changed) {
59  ss << "color='#f00' ";
60  }
61 
62  ss << "size='large'>" << font::unicode_bullet << "</span>]";
63  return ss.str();
64 }
65 
67  : gui_(gui)
68  , game_config_(game_config)
69  , default_dir_(preferences::editor::default_dir())
70  , map_generators_()
71  , last_map_generator_(nullptr)
72  , current_context_index_(0)
73  , auto_update_transitions_(preferences::editor::auto_update_transitions())
74  , map_contexts_()
75  , clipboard_()
76 {
77  resources::filter_con = this;
78 
79  if(default_dir_.empty()) {
81  }
82 
84  init_map_generators(game_config);
85 }
86 
88 {
89  // Restore default window title
91 
92  resources::filter_con = nullptr;
93 }
94 
96 {
98 
99  // TODO register the tod_manager with the gui?
101 
102  gui().replace_overlay_map(&get_map_context().get_overlays());
103 
105 
106  gui().init_flags();
107 
108  reload_map();
109 
110  // Enable the labels of the current context;
112 
114 }
115 
117 {
118  gui_.rebuild_all();
124 }
125 
127 {
128  gui_.reload_map();
131  refresh_all();
132 }
133 
135 {
136  switch (auto_update_transitions_) {
138  return (item == "editor-auto-update-transitions");
140  return (item == "editor-partial-update-transitions");
142  return (item == "editor-no-update-transitions");
143  }
144 
145  return true; //should not be reached
146 }
147 
149 {
152 
154  return true;
155  }
156 
157  return false;
158 }
159 
161 {
162  std::vector<std::string> modified;
163  for(auto& mc : map_contexts_) {
164  if(mc->modified()) {
165  if(!mc->get_name().empty()) {
166  modified.push_back(mc->get_name());
167  } else if(!mc->get_filename().empty()) {
168  modified.push_back(mc->get_filename());
169  } else {
170  modified.push_back(mc->get_default_context_name());
171  }
172  }
173  }
174 
175  for(std::string& str : modified) {
176  message += "\n" + font::unicode_bullet + " " + str;
177  }
178 
179  return modified.size();
180 }
181 
182 void context_manager::load_map_dialog(bool force_same_context /* = false */)
183 {
185  if(fn.empty()) {
186  fn = default_dir_;
187  }
188 
190 
191  dlg.set_title(_("Load Map"))
192  .set_path(fn);
193 
194  if(dlg.show()) {
195  load_map(dlg.path(), !force_same_context);
196  }
197 }
198 
199 void context_manager::load_mru_item(unsigned int index, bool force_same_context /* = false */)
200 {
201  const std::vector<std::string>& mru = preferences::editor::recent_files();
202  if(mru.empty() || index >= mru.size()) {
203  return;
204  }
205 
206  load_map(mru[index], !force_same_context);
207 }
208 
210 {
211  team& t = get_map_context().teams()[side_index];
212 
213  editor_team_info team_info(t);
214 
215  if(gui2::dialogs::editor_edit_side::execute(team_info)) {
216  get_map_context().set_side_setup(team_info);
217  }
218 }
219 
221 {
222  map_context& context = get_map_context();
223 
224  // TODO
225  //std::string fn = filesystem::directory_name(context.get_filename());
226 
227  std::string id = context.get_id();
228  std::string name = context.get_name();
229  std::string description = context.get_description();
230 
231  int turns = context.get_time_manager()->number_of_turns();
232  int xp_mod = context.get_xp_mod();
233 
234  bool victory = context.victory_defeated();
235  bool random = context.random_start_time();
236 
237  const bool ok = gui2::dialogs::editor_edit_scenario::execute(
238  id, name, description, turns, xp_mod, victory, random
239  );
240 
241  if(!ok) {
242  return;
243  }
244 
245  context.set_scenario_setup(id, name, description, turns, xp_mod, victory, random);
246 
247  if(!name.empty()) {
249  }
250 }
251 
253 {
254  const editor_map& map = get_map_context().map();
255 
256  int w = map.w();
257  int h = map.h();
258 
259  if(gui2::dialogs::editor_new_map::execute(_("New Map"), w, h)) {
261  new_map(w, h, fill, true);
262  }
263 }
264 
266 {
267  const editor_map& map = get_map_context().map();
268 
269  int w = map.w();
270  int h = map.h();
271 
272  if(gui2::dialogs::editor_new_map::execute(_("New Scenario"), w, h)) {
274  new_scenario(w, h, fill, true);
275  }
276 }
277 
278 void context_manager::expand_open_maps_menu(std::vector<config>& items, int i)
279 {
280  auto pos = items.erase(items.begin() + i);
281  std::vector<config> contexts;
282 
283  for(size_t mci = 0; mci < map_contexts_.size(); ++mci) {
284  map_context& mc = *map_contexts_[mci];
285 
286  std::string filename;
287  if(mc.is_pure_map()) {
288  filename = filesystem::base_name(mc.get_filename());
289  } else {
290  filename = mc.get_name();
291  }
292 
293  if(filename.empty()) {
294  filename = mc.get_default_context_name();
295  }
296 
297  std::ostringstream ss;
298  ss << "[" << mci + 1 << "] ";
299 
300  const bool changed = mc.modified();
301 
302  if(changed) {
303  ss << "<i>" << filename << "</i>";
304  } else {
305  ss << filename;
306  }
307 
308  if(mc.is_embedded()) {
309  ss << " (E)";
310  }
311 
312  const std::string label = ss.str();
313  const std::string details = get_menu_marker(changed);
314 
315  contexts.emplace_back(config {"label", label, "details", details});
316  }
317 
318  items.insert(pos, contexts.begin(), contexts.end());
319 }
320 
321 void context_manager::expand_load_mru_menu(std::vector<config>& items, int i)
322 {
323  std::vector<std::string> mru = preferences::editor::recent_files();
324 
325  auto pos = items.erase(items.begin() + i);
326 
327  if(mru.empty()) {
328  items.insert(pos, config {"label", _("No Recent Files")});
329  return;
330  }
331 
332  for(std::string& path : mru) {
333  // TODO: add proper leading ellipsization instead, since otherwise
334  // it'll be impossible to tell apart files with identical names and
335  // different parent paths.
337  }
338 
339  std::vector<config> temp;
340  std::transform(mru.begin(), mru.end(), std::back_inserter(temp), [](const std::string& str) {
341  return config {"label", str};
342  });
343 
344  items.insert(pos, temp.begin(), temp.end());
345 }
346 
347 void context_manager::expand_areas_menu(std::vector<config>& items, int i)
348 {
350  if(!tod) {
351  return;
352  }
353 
354  auto pos = items.erase(items.begin() + i);
355  std::vector<config> area_entries;
356 
357  std::vector<std::string> area_ids = tod->get_area_ids();
358 
359  for(size_t mci = 0; mci < area_ids.size(); ++mci) {
360  const std::string& area = area_ids[mci];
361 
362  std::stringstream ss;
363  ss << "[" << mci + 1 << "] ";\
364 
365  if(area.empty()) {
366  ss << "<i>" << _("Unnamed Area") << "</i>";
367  } else {
368  ss << area;
369  }
370 
371  const bool changed =
372  mci == static_cast<size_t>(get_map_context().get_active_area())
373  && tod->get_area_by_index(mci) != get_map_context().map().selection();
374 
375  const std::string label = ss.str();
376  const std::string details = get_menu_marker(changed);
377 
378  area_entries.emplace_back(config {"label", label, "details", details});
379  }
380 
381  items.insert(pos, area_entries.begin(), area_entries.end());
382 }
383 
384 void context_manager::expand_sides_menu(std::vector<config>& items, int i)
385 {
386  auto pos = items.erase(items.begin() + i);
387  std::vector<config> contexts;
388 
389  for(size_t mci = 0; mci < get_map_context().teams().size(); ++mci) {
390 
391  const team& t = get_map_context().teams()[mci];
392  const std::string& teamname = t.user_team_name();
393  std::stringstream label;
394  label << "[" << mci+1 << "] ";
395 
396  if(teamname.empty()) {
397  label << "<i>" << _("New Side") << "</i>";
398  } else {
399  label << teamname;
400  }
401 
402  contexts.emplace_back(config {"label", label.str()});
403  }
404 
405  items.insert(pos, contexts.begin(), contexts.end());
406 }
407 
408 void context_manager::expand_time_menu(std::vector<config>& items, int i)
409 {
410  auto pos = items.erase(items.begin() + i);
411  std::vector<config> times;
412 
414 
415  assert(tod_m != nullptr);
416 
417  for(const time_of_day& time : tod_m->times()) {
418  times.emplace_back(config {
419  "details", time.name, // Use 'details' field here since the image will take the first column
420  "image", time.image,
421  });
422  }
423 
424  items.insert(pos, times.begin(), times.end());
425 }
426 
427 void context_manager::expand_local_time_menu(std::vector<config>& items, int i)
428 {
429  auto pos = items.erase(items.begin() + i);
430  std::vector<config> times;
431 
433 
434  for(const time_of_day& time : tod_m->times(get_map_context().get_active_area())) {
435  times.emplace_back(config {
436  "details", time.name, // Use 'details' field here since the image will take the first column
437  "image", time.image,
438  });
439  }
440 
441  items.insert(pos, times.begin(), times.end());
442 }
443 
445 {
447  if(fn.empty()) {
448  fn = default_dir_;
449  }
450 
452 
453  dlg.set_title(_("Apply Mask"))
454  .set_path(fn);
455 
456  if(dlg.show()) {
457  try {
458  map_context mask(game_config_, dlg.path());
459  editor_action_apply_mask a(mask.map());
461  } catch (editor_map_load_exception& e) {
462  gui2::show_transient_message(_("Error loading mask"), e.what());
463  return;
464  } catch (editor_action_exception& e) {
466  return;
467  }
468  }
469 }
470 
471 void context_manager::perform_refresh(const editor_action& action, bool drag_part /* =false */)
472 {
474  refresh_after_action(drag_part);
475 }
476 
478 {
479  int active_area = get_map_context().get_active_area();
481 
482  if(gui2::dialogs::edit_text::execute(N_("Rename Area"), N_("Identifier:"), name)) {
483  get_map_context().get_time_manager()->set_area_id(active_area, name);
484  }
485 }
486 
488 {
490  if(fn.empty()) {
491  fn = default_dir_;
492  }
493 
495 
496  dlg.set_title(_("Choose Target Map"))
497  .set_path(fn);
498 
499  if(dlg.show()) {
500  try {
501  map_context map(game_config_, dlg.path());
502  editor_action_create_mask a(map.map());
504  } catch (editor_map_load_exception& e) {
505  gui2::show_transient_message(_("Error loading map"), e.what());
506  return;
507  } catch (editor_action_exception& e) {
509  return;
510  }
511  }
512 }
513 
515 {
516  if(get_map_context().needs_reload()) {
517  reload_map();
518  return;
519  }
520 
521  const std::set<map_location>& changed_locs = get_map_context().changed_locations();
522 
523  if(get_map_context().needs_terrain_rebuild()) {
526  && (!drag_part || get_map_context().everything_changed())))
527  {
528  gui_.rebuild_all();
531  } else {
532  for(const map_location& loc : changed_locs) {
533  gui_.rebuild_terrain(loc);
534  }
535  gui_.invalidate(changed_locs);
536  }
537  } else {
538  if(get_map_context().everything_changed()) {
540  } else {
541  gui_.invalidate(changed_locs);
542  }
543  }
544 
545  if(get_map_context().needs_labels_reset()) {
547  }
548 
551 }
552 
554 {
555  const editor_map& map = get_map_context().map();
556 
557  int w = map.w();
558  int h = map.h();
559 
561  bool copy = false;
562 
563  if(!gui2::dialogs::editor_resize_map::execute(w, h, dir, copy)) {
564  return;
565  }
566 
567  if(w != map.w() || h != map.h()) {
569  if(copy) {
571  }
572 
573  int x_offset = map.w() - w;
574  int y_offset = map.h() - h;
575 
576  switch (dir) {
580  y_offset = 0;
581  break;
585  y_offset /= 2;
586  break;
590  break;
591  default:
592  y_offset = 0;
593  WRN_ED << "Unknown resize expand direction" << std::endl;
594  break;
595  }
596 
597  switch (dir) {
601  x_offset = 0;
602  break;
606  x_offset /= 2;
607  break;
611  break;
612  default:
613  x_offset = 0;
614  break;
615  }
616 
617  editor_action_resize_map a(w, h, x_offset, y_offset, fill);
618  perform_refresh(a);
619  }
620 }
621 
623 {
624  std::string input_name = get_map_context().get_filename();
625  if(input_name.empty()) {
626  input_name = filesystem::get_dir(default_dir_ + "/maps");
627  }
628 
630 
631  dlg.set_title(_("Save Map As"))
632  .set_save_mode(true)
633  .set_path(input_name)
634  .set_extension(".map");
635 
636  if(!dlg.show()) {
637  return;
638  }
639 
640  save_map_as(dlg.path());
641 }
642 
644 {
645  std::string input_name = get_map_context().get_filename();
646  if(input_name.empty()) {
647  input_name = filesystem::get_dir(default_dir_ + "/scenarios");
648  }
649 
651 
652  dlg.set_title(_("Save Scenario As"))
653  .set_save_mode(true)
654  .set_path(input_name)
655  .set_extension(".cfg");
656 
657  if(!dlg.show()) {
658  return;
659  }
660 
661  save_scenario_as(dlg.path());
662 }
663 
665 {
666  for(const config& i : game_config.child_range("multiplayer")) {
667  if(i["map_generation"].empty() && i["scenario_generation"].empty()) {
668  continue;
669  }
670 
671  const config& generator_cfg = i.child("generator");
672  if(!generator_cfg) {
673  ERR_ED << "Scenario \"" << i["name"] << "\" with id " << i["id"]
674  << " has map_generation= but no [generator] tag" << std::endl;
675  } else {
676  map_generators_.emplace_back(create_map_generator(i["map_generation"], generator_cfg));
677  }
678  }
679 }
680 
682 {
683  if(map_generators_.empty()) {
684  gui2::show_error_message(_("No random map generators found."));
685  return;
686  }
687 
690  dialog.show();
691 
692  if(dialog.get_retval() == gui2::window::OK) {
693  std::string map_string;
695  try {
696  map_string = map_generator->create_map(dialog.get_seed());
697  } catch (mapgen_exception& e) {
698  gui2::show_transient_message(_("Map creation failed."), e.what());
699  return;
700  }
701 
702  if(map_string.empty()) {
703  gui2::show_transient_message("", _("Map creation failed."));
704  } else {
705  editor_map new_map(game_config_, map_string);
706  editor_action_whole_map a(new_map);
707  get_map_context().set_needs_labels_reset(); // Ensure Player Start labels are updated together with newly generated map
708  perform_refresh(a);
709  }
710 
711  last_map_generator_ = map_generator;
712  }
713 }
714 
716 {
717  if(get_map_context().modified()) {
718  const int res = gui2::show_message(_("Unsaved Changes"),
719  _("Do you want to discard all changes made to the map since the last save?"), gui2::dialogs::message::yes_no_buttons);
720  return gui2::window::CANCEL != res;
721  }
722 
723  return true;
724 }
725 
727 {
729 }
730 
731 void context_manager::save_all_maps(bool auto_save_windows)
732 {
733  int current = current_context_index_;
734  saved_windows_.clear();
735  for(size_t i = 0; i < map_contexts_.size(); ++i) {
736  switch_context(i);
738  if(auto_save_windows) {
739  if(name.empty() || filesystem::is_directory(name)) {
740  std::ostringstream s;
741  s << default_dir_ << "/" << "window_" << i + 1;
742  name = s.str();
744  }
745  }
746  saved_windows_.push_back(name);
747  save_map();
748  }
749 
750  switch_context(current);
751 }
752 
754 {
756  if(name.empty() || filesystem::is_directory(name)) {
757  if(get_map_context().is_pure_map()) {
759  } else {
761  }
762  } else {
763  if(get_map_context().is_pure_map()) {
764  write_map();
765  } else {
766  write_scenario();
767  }
768  }
769 }
770 
772 {
773  size_t is_open = check_open_map(filename);
774  if(is_open < map_contexts_.size() && is_open != static_cast<unsigned>(current_context_index_)) {
775  gui2::show_transient_message(_("This scenario is already open."), filename);
776  return false;
777  }
778 
779  std::string old_filename = get_map_context().get_filename();
780  bool embedded = get_map_context().is_embedded();
781 
782  get_map_context().set_filename(filename);
783  get_map_context().set_embedded(false);
784 
785  if(!write_scenario(true)) {
786  get_map_context().set_filename(old_filename);
787  get_map_context().set_embedded(embedded);
788  return false;
789  }
790 
791  return true;
792 }
793 
795 {
796  size_t is_open = check_open_map(filename);
797  if(is_open < map_contexts_.size() && is_open != static_cast<unsigned>(current_context_index_)) {
798  gui2::show_transient_message(_("This map is already open."), filename);
799  return false;
800  }
801 
802  std::string old_filename = get_map_context().get_filename();
803  bool embedded = get_map_context().is_embedded();
804 
805  get_map_context().set_filename(filename);
806  get_map_context().set_embedded(false);
807 
808  if(!write_map(true)) {
809  get_map_context().set_filename(old_filename);
810  get_map_context().set_embedded(embedded);
811  return false;
812  }
813 
814  return true;
815 }
816 
817 bool context_manager::write_scenario(bool display_confirmation)
818 {
819  try {
821  if(display_confirmation) {
822  gui2::show_transient_message("", _("Scenario saved."));
823  }
824  } catch (editor_map_save_exception& e) {
826  return false;
827  }
828 
829  return true;
830 }
831 
832 bool context_manager::write_map(bool display_confirmation)
833 {
834  try {
836  if(display_confirmation) {
837  gui2::show_transient_message("", _("Map saved."));
838  }
839  } catch (editor_map_save_exception& e) {
841  return false;
842  }
843 
844  return true;
845 }
846 
848 {
849  size_t i = 0;
850  while(i < map_contexts_.size() && map_contexts_[i]->get_filename() != fn) {
851  ++i;
852  }
853 
854  return i;
855 }
856 
858 {
859  size_t i = check_open_map(fn);
860  if(i < map_contexts_.size()) {
861  gui2::show_transient_message(_("This map is already open."), fn);
862  switch_context(i);
863  return true;
864  }
865 
866  return false;
867 }
868 
869 void context_manager::load_map(const std::string& filename, bool new_context)
870 {
871  if(new_context && check_switch_open_map(filename)) {
872  return;
873  }
874 
875  LOG_ED << "Load map: " << filename << (new_context ? " (new)" : " (same)") << "\n";
876  try {
877  {
878  context_ptr mc(new map_context(game_config_, filename));
879  if(mc->get_filename() != filename) {
880  if(new_context && check_switch_open_map(mc->get_filename())) {
881  return;
882  }
883  }
884 
885  if(new_context) {
886  int new_id = add_map_context_of(std::move(mc));
887  switch_context(new_id);
888  } else {
889  replace_map_context_with(std::move(mc));
890  }
891  }
892 
893  if(get_map_context().is_embedded()) {
894  const std::string& msg = _("Loaded embedded map data");
895  gui2::show_transient_message(_("Map loaded from scenario"), msg);
896  } else {
897  if(get_map_context().get_filename() != filename) {
898  if(get_map_context().get_map_data_key().empty()) {
899  ERR_ED << "Internal error, map context filename changed: "
900  << filename << " -> " << get_map_context().get_filename()
901  << " with no apparent scenario load\n";
902  } else {
903  utils::string_map symbols;
904  symbols["old"] = filename;
905  const std::string& msg = _("Loaded referenced map file:\n$new");
906  symbols["new"] = get_map_context().get_filename();
907  symbols["map_data"] = get_map_context().get_map_data_key();
908  gui2::show_transient_message(_("Map loaded from scenario"),
909  //TODO: msg is already translated does vgettext make sense?
910  vgettext(msg.c_str(), symbols));
911  }
912  }
913  }
914  } catch (editor_map_load_exception& e) {
915  gui2::show_transient_message(_("Error loading map"), e.what());
916  return;
917  }
918 }
919 
921 {
922  if(!confirm_discard()) {
923  return;
924  }
925 
927  if(filename.empty()) {
928  ERR_ED << "Empty filename in map revert" << std::endl;
929  return;
930  }
931 
932  load_map(filename, false);
933 }
934 
935 void context_manager::new_map(int width, int height, const t_translation::terrain_code& fill, bool new_context)
936 {
937  const config& default_schedule = game_config_.find_child("editor_times", "id", "default");
938  editor_map m(game_config_, width, height, fill);
939 
940  if(new_context) {
941  int new_id = add_map_context(m, true, default_schedule);
942  switch_context(new_id);
943  } else {
944  replace_map_context(m, true, default_schedule);
945  }
946 }
947 
948 void context_manager::new_scenario(int width, int height, const t_translation::terrain_code& fill, bool new_context)
949 {
950  const config& default_schedule = game_config_.find_child("editor_times", "id", "default");
951  editor_map m(game_config_, width, height, fill);
952 
953  if(new_context) {
954  int new_id = add_map_context(m, false, default_schedule);
955  switch_context(new_id);
956  } else {
957  replace_map_context(m, false, default_schedule);
958  }
959 
960  // Give the new scenario an initial side.
962  gui_.init_flags();
963 }
964 
965 //
966 // Context manipulation
967 //
968 
969 template<typename... T>
970 int context_manager::add_map_context(const T&... args)
971 {
972  map_contexts_.emplace_back(new map_context(args...));
973  return map_contexts_.size() - 1;
974 }
975 
977 {
978  map_contexts_.emplace_back(std::move(mc));
979  return map_contexts_.size() - 1;
980 }
981 
982 template<typename... T>
984 {
985  context_ptr new_mc(new map_context(args...));
986  replace_map_context_with(std::move(new_mc));
987 }
988 
990 {
993 }
994 
996 {
997  if(saved_windows_.empty()) {
1000 
1001  const config& default_schedule = game_config_.find_child("editor_times", "id", "default");
1002  add_map_context(editor_map(game_config_, 44, 33, default_terrain), true, default_schedule);
1003  } else {
1004  for(const std::string& filename : saved_windows_) {
1005  add_map_context(game_config_, filename);
1006  }
1007 
1008  saved_windows_.clear();
1009  }
1010 }
1011 
1013 {
1014  if(!confirm_discard()) return;
1015 
1016  if(map_contexts_.size() == 1) {
1018  map_contexts_.erase(map_contexts_.begin());
1019  } else if(current_context_index_ == static_cast<int>(map_contexts_.size()) - 1) {
1020  map_contexts_.pop_back();
1022  } else {
1024  }
1025 
1027 }
1028 
1029 void context_manager::switch_context(const int index, const bool force)
1030 {
1031  if(index < 0 || static_cast<size_t>(index) >= map_contexts_.size()) {
1032  WRN_ED << "Invalid index in switch map context: " << index << std::endl;
1033  return;
1034  }
1035 
1036  if(index == current_context_index_ && !force) {
1037  return;
1038  }
1039 
1040  // Disable the labels of the current context before switching.
1041  // The refresher handles enabling the new ones.
1042  get_map_context().get_labels().enable(false);
1043 
1045 
1047 }
1048 
1050 {
1052 
1053  if(name.empty()) {
1055  }
1056 
1057  if(name.empty()){
1059  }
1060 
1061  const std::string& wm_title_string = name + " - " + game_config::get_default_title_string();
1062  CVideo::get_singleton().set_window_title(wm_title_string);
1063 }
1064 
1065 } //Namespace editor
int auto_update_transitions()
Definition: editor.cpp:24
bool write_scenario(bool display_confirmation=false)
void set_side_setup(editor_team_info &info)
TODO.
bool victory_defeated() const
void show_message(const std::string &title, const std::string &msg, const std::string &button_caption, const bool auto_close, const bool message_use_markup, const bool title_use_markup)
Shows a message to the user.
Definition: message.cpp:152
Dialog is closed with ok button.
Definition: window.hpp:101
boost::optional< uint32_t > get_seed()
::tod_manager * tod_manager
Definition: resources.cpp:29
const char * what() const NOEXCEPT
Definition: exceptions.hpp:37
void apply_mask_dialog()
Display an apply mask dialog and process user input.
std::vector< char_t > string
bool check_switch_open_map(const std::string &fn)
Check if a map is already open.
std::unique_ptr< map_context > context_ptr
size_t index(const utf8::string &str, const size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:71
int auto_update_transitions_
Flag to rebuild terrain on every terrain change.
const t_translation::terrain_code & get_selected_bg_terrain()
std::vector< std::string > recent_files()
Retrieves the list of recently opened files.
Definition: editor.cpp:118
const terrain_code NONE_TERRAIN
Definition: translation.hpp:58
void edit_scenario_dialog()
Display a scenario edit dialog and process user input.
std::map< std::string, t_string > string_map
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
Definition: display.cpp:3020
file_dialog & set_extension(const std::string &value)
Sets the default file extension for file names in save mode.
game_classification * classification
Definition: resources.cpp:34
file_dialog & set_path(const std::string &value)
Sets the initial file selection.
void change_display_context(const display_context *dc)
Definition: display.cpp:496
void replace_map_context_with(context_ptr &&mc)
std::vector< context_ptr > map_contexts_
The currently opened map context object.
config & find_child(config_key_type 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:782
void new_side()
Adds a new side to the map.
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.
#define a
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].
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:287
This file contains the window object, this object is a top level container which has the event manage...
child_itors child_range(config_key_type key)
Definition: config.cpp:362
void show_transient_message(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.
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.
bool modified() const
#define LOG_ED
General purpose widgets.
std::string default_dir_
Default directory for map load/save as dialogs.
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:49
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.
file_dialog & set_save_mode(bool value)
Sets the dialog's behavior on non-existent file name inputs.
static CVideo & get_singleton()
Definition: video.hpp:43
#define h
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:109
size_t check_open_map(const std::string &fn) const
Check if a map is already open.
std::string path() const
Gets the current file selection.
const std::string & get_filename() const
const std::vector< std::string > items
Replace contents of the entire map, Useful as a fallback undo method when something else would be imp...
Definition: action.hpp:37
-file sdl_utils.hpp
bool show(const unsigned auto_close_time=0)
Shows the window.
bool confirm_discard()
Shows an are-you-sure dialog if the map was modified.
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.
int add_map_context_of(context_ptr &&mc)
map_generator * get_selected_map_generator()
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.
const std::set< map_location > changed_locations() const
void expand_areas_menu(std::vector< config > &items, int i)
Menu expanding for the map's defined areas.
std::string default_dir()
Definition: editor.cpp:32
#define WRN_ED
const t_string get_default_context_name() const
game_classification & get_classification()
void set_window_title(const std::string &title)
Sets the title of the main window.
Definition: video.cpp:358
Object which defines a time of day with associated bonuses, image, sounds etc.
Definition: time_of_day.hpp:57
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:44
int add_map_context(const T &...args)
Add a map context.
void close_current_context()
Closes the active map context.
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:89
const std::string & get_name() const
bool is_pure_map() const
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:295
std::string get_user_data_dir()
void reset_starting_position_labels(display &disp)
void recalculate_minimap()
Schedule the minimap for recalculation.
Definition: display.hpp:612
void select_map_generator(map_generator *mg)
filter_context * filter_con
Definition: resources.cpp:23
void replace_map_context(const T &...args)
Replace the current map context and refresh accordingly.
void set_embedded(bool v)
int w() const
Effective map width.
Definition: map.hpp:90
void set_auto_update_transitions(int value)
Definition: editor.cpp:28
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.
bool save_map()
Saves the map under the current filename.
void enable(bool is_enabled)
Definition: label.cpp:253
std::string path
Definition: game_config.cpp:56
Modify, read and display user preferences.
Shows a yes and no button.
Definition: message.hpp:79
map_display and display: classes which take care of displaying the map and game-data on the screen...
void refresh_on_context_change()
Performs the necessary housekeeping necessary when switching contexts.
if(win_locale=="af") win_locale
void create_buttons()
Definition: display.cpp:891
Manage the empty-palette in the editor.
Definition: action.cpp:29
std::string default_terrain
Definition: game_config.cpp:86
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:3010
bool is_active_transitions_hotkey(const std::string &item)
void switch_context(const int index, const bool force=false)
Switches the context to the one under the specified index.
void new_scenario(int width, int height, const t_translation::terrain_code &fill, bool new_context)
Create a new scenario.
std::string get_dir(const std::string &dir)
Paint the same terrain on a number of locations on the map.
Definition: action.hpp:284
void new_map(int width, int height, const t_translation::terrain_code &fill, bool new_context)
Create a new map.
void load_map(const std::string &filename, bool new_context)
Load a map given the filename.
virtual std::string create_map(boost::optional< uint32_t > randomseed=boost::none)=0
Creates a new map and returns it.
map_generator * create_map_generator(const std::string &name, const config &cfg)
Definition: map_create.cpp:28
void set_needs_terrain_rebuild(bool value=true)
Setter for the terrain rebuild flag.
Encapsulates the map of the game.
Definition: location.hpp:42
void clear_changed_locations()
std::vector< std::string > get_area_ids() const
This class adds extra editor-specific functionality to a normal gamemap.
Definition: editor_map.hpp:69
int h() const
Effective map height.
Definition: map.hpp:93
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:53
void expand_local_time_menu(std::vector< config > &items, int i)
Menu expanding for the map's defined areas.
void rebuild_terrain(const map_location &loc)
bool save_scenario_as(const std::string &filename)
static map_location::DIRECTION s
editor_display & gui()
Base class for all editor actions.
Definition: action_base.hpp:40
const std::string & get_map_data_key() const
const std::set< map_location > & get_area_by_index(int index) const
size_t i
Definition: function.cpp:933
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...
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
int w
This class wraps around a map to provide a concise interface for the editor to work with...
Definition: map_context.hpp:55
#define N_(String)
Definition: gettext.hpp:97
const std::string unicode_bullet
Definition: constants.cpp:42
const std::set< map_location > & selection() const
Return the selection set.
Definition: editor_map.hpp:149
std::string vgettext(const char *msgid, const utils::string_map &symbols)
std::string base_name(const std::string &file, const bool remove_extension=false)
Returns the base filename of a file, with directory name stripped.
void expand_sides_menu(std::vector< config > &items, int i)
Menu expanding for the map's player sides.
static std::string get_filename(const std::string &file_code)
map_generator * last_map_generator_
int turns()
Definition: game.cpp:560
void edit_side_dialog(int side_index)
Display a side edit dialog and process user input.
double t
Definition: astarsearch.cpp:64
void reload_map()
Updates internals that cache map size.
Definition: display.cpp:490
virtual const editor_map & map() const override
Const map accessor.
#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.
std::vector< std::unique_ptr< map_generator > > map_generators_
Available random map generators.
void set_filename(const std::string &fn)
int get_active_area() const
void expand_load_mru_menu(std::vector< config > &items, int i)
Menu expanding for most recent loaded list.
static const char * name(const std::vector< SDL_Joystick * > &joysticks, const size_t index)
Definition: joystick.cpp:48
const tod_manager * get_time_manager() const
void show_error_message(const std::string &msg, bool message_use_markup)
Shows an error message to the user.
Definition: message.cpp:205
void generate_map_dialog()
Display a generate random map dialog and process user input.
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.
The dialog for selecting which random generator to use in the editor.
#define e
bool save_map_as(const std::string &filename)
Save the map under a given filename.
void expand_time_menu(std::vector< config > &items, int i)
Menu expanding for the map's defined areas.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:93
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.
virtual const std::vector< team > & teams() const override
Const teams accessor.
static std::vector< std::string > saved_windows_
static const std::string get_menu_marker(const bool changed)
Dialog is closed with the cancel button.
Definition: window.hpp:102
bool is_embedded() const
void expand_open_maps_menu(std::vector< config > &items, int i)
Menu expanding for open maps list.
std::string directory_name(const std::string &file)
Returns the directory name of a file, with filename stripped.
terrain_code read_terrain_code(const std::string &str, const ter_layer filler)
Reads a single terrain from a string.
void rebuild_all()
Rebuild all dynamic terrain.
Definition: display.cpp:485
int number_of_turns() const
void replace_overlay_map(overlay_map *overlays)
Definition: display.hpp:1063
void new_map_dialog()
Display a new map dialog and process user input.
file_dialog & set_title(const std::string &value)
Sets the current dialog title text.
Definition: file_dialog.hpp:56
const std::string & get_id() const