From d2c635f73902d4b9d8e6addb5e1088555d9e0687 Mon Sep 17 00:00:00 2001 From: Lymia Aluysia Date: Wed, 18 Jan 2017 08:43:21 -0600 Subject: [PATCH] Change tabs to two spaces. --- src/cli/cli_main.cpp | 372 +-- src/cli/cli_main.hpp | 52 +- src/cli/text_io_handler.cpp | 226 +- src/cli/text_io_handler.hpp | 64 +- src/cli/win32_cli_wrapper.cpp | 422 ++-- src/data/action/generic.hpp | 122 +- src/data/action/keyword.cpp | 296 +-- src/data/action/keyword.hpp | 80 +- src/data/action/set.cpp | 134 +- src/data/action/set.hpp | 132 +- src/data/action/symbol.cpp | 668 +++--- src/data/action/symbol.hpp | 322 +-- src/data/action/symbol_part.cpp | 622 ++--- src/data/action/symbol_part.hpp | 194 +- src/data/action/value.cpp | 272 +-- src/data/action/value.hpp | 144 +- src/data/add_cards_script.cpp | 52 +- src/data/add_cards_script.hpp | 22 +- src/data/card.cpp | 98 +- src/data/card.hpp | 128 +- src/data/draw_what.hpp | 16 +- src/data/export_template.cpp | 30 +- src/data/export_template.hpp | 48 +- src/data/field.cpp | 360 +-- src/data/field.hpp | 392 +-- src/data/field/boolean.cpp | 30 +- src/data/field/boolean.hpp | 36 +- src/data/field/choice.cpp | 388 +-- src/data/field/choice.hpp | 234 +- src/data/field/color.cpp | 98 +- src/data/field/color.hpp | 70 +- src/data/field/image.cpp | 20 +- src/data/field/image.hpp | 26 +- src/data/field/information.cpp | 58 +- src/data/field/information.hpp | 46 +- src/data/field/multiple_choice.cpp | 138 +- src/data/field/multiple_choice.hpp | 66 +- src/data/field/package_choice.cpp | 68 +- src/data/field/package_choice.hpp | 50 +- src/data/field/symbol.cpp | 28 +- src/data/field/symbol.hpp | 52 +- src/data/field/text.cpp | 230 +- src/data/field/text.hpp | 136 +- src/data/filter.hpp | 102 +- src/data/font.cpp | 190 +- src/data/font.hpp | 84 +- src/data/format/apprentice.cpp | 1088 ++++----- src/data/format/clipboard.cpp | 152 +- src/data/format/clipboard.hpp | 40 +- src/data/format/formats.cpp | 74 +- src/data/format/formats.hpp | 44 +- src/data/format/image.cpp | 102 +- src/data/format/image_to_symbol.cpp | 700 +++--- src/data/format/mse1.cpp | 266 +-- src/data/format/mse2.cpp | 54 +- src/data/format/mtg_editor.cpp | 450 ++-- src/data/format/mws.cpp | 140 +- src/data/game.cpp | 148 +- src/data/game.hpp | 84 +- src/data/graph_type.hpp | 22 +- src/data/installer.cpp | 896 +++---- src/data/installer.hpp | 188 +- src/data/keyword.cpp | 1176 ++++----- src/data/keyword.hpp | 258 +- src/data/locale.cpp | 318 +-- src/data/locale.hpp | 48 +- src/data/pack.cpp | 676 +++--- src/data/pack.hpp | 176 +- src/data/set.cpp | 388 +-- src/data/set.hpp | 222 +- src/data/settings.cpp | 388 +-- src/data/settings.hpp | 282 +-- src/data/statistics.cpp | 180 +- src/data/statistics.hpp | 70 +- src/data/stylesheet.cpp | 190 +- src/data/stylesheet.hpp | 88 +- src/data/symbol.cpp | 444 ++-- src/data/symbol.hpp | 388 +-- src/data/symbol_font.cpp | 876 +++---- src/data/symbol_font.hpp | 236 +- src/data/word_list.cpp | 42 +- src/data/word_list.hpp | 34 +- src/gfx/bezier.cpp | 330 +-- src/gfx/bezier.hpp | 36 +- src/gfx/blend_image.cpp | 168 +- src/gfx/color.cpp | 140 +- src/gfx/color.hpp | 74 +- src/gfx/combine_image.cpp | 224 +- src/gfx/generated_image.cpp | 640 ++--- src/gfx/generated_image.hpp | 386 +-- src/gfx/gfx.hpp | 140 +- src/gfx/image_effects.cpp | 152 +- src/gfx/mask_image.cpp | 230 +- src/gfx/polynomial.cpp | 118 +- src/gfx/resample_image.cpp | 426 ++-- src/gfx/resample_text.cpp | 338 +-- src/gfx/rotate_image.cpp | 172 +- src/gui/about_window.cpp | 236 +- src/gui/about_window.hpp | 120 +- src/gui/auto_replace_window.cpp | 398 ++-- src/gui/auto_replace_window.hpp | 54 +- src/gui/card_select_window.cpp | 204 +- src/gui/card_select_window.hpp | 100 +- src/gui/control/card_editor.cpp | 570 ++--- src/gui/control/card_editor.hpp | 238 +- src/gui/control/card_list.cpp | 534 ++--- src/gui/control/card_list.hpp | 200 +- src/gui/control/card_list_column_select.cpp | 200 +- src/gui/control/card_list_column_select.hpp | 64 +- src/gui/control/card_viewer.cpp | 170 +- src/gui/control/card_viewer.hpp | 74 +- src/gui/control/filter_ctrl.cpp | 176 +- src/gui/control/filter_ctrl.hpp | 68 +- src/gui/control/filtered_card_list.cpp | 18 +- src/gui/control/filtered_card_list.hpp | 24 +- src/gui/control/gallery_list.cpp | 514 ++-- src/gui/control/gallery_list.hpp | 202 +- src/gui/control/graph.cpp | 1962 +++++++-------- src/gui/control/graph.hpp | 422 ++-- src/gui/control/image_card_list.cpp | 154 +- src/gui/control/image_card_list.hpp | 52 +- src/gui/control/item_list.cpp | 346 +-- src/gui/control/item_list.hpp | 166 +- src/gui/control/keyword_list.cpp | 304 +-- src/gui/control/keyword_list.hpp | 140 +- src/gui/control/native_look_editor.cpp | 316 +-- src/gui/control/native_look_editor.hpp | 90 +- src/gui/control/package_list.cpp | 142 +- src/gui/control/package_list.hpp | 100 +- src/gui/control/select_card_list.cpp | 128 +- src/gui/control/select_card_list.hpp | 46 +- src/gui/control/text_ctrl.cpp | 150 +- src/gui/control/text_ctrl.hpp | 74 +- src/gui/control/tree_list.cpp | 494 ++-- src/gui/control/tree_list.hpp | 162 +- src/gui/drop_down_list.cpp | 802 +++---- src/gui/drop_down_list.hpp | 202 +- src/gui/html_export_window.cpp | 148 +- src/gui/html_export_window.hpp | 22 +- src/gui/icon_menu.cpp | 122 +- src/gui/icon_menu.hpp | 20 +- src/gui/image_slice_window.cpp | 1024 ++++---- src/gui/image_slice_window.hpp | 282 +-- src/gui/images_export_window.cpp | 86 +- src/gui/images_export_window.hpp | 16 +- src/gui/new_window.cpp | 250 +- src/gui/new_window.hpp | 98 +- src/gui/package_update_list.cpp | 446 ++-- src/gui/package_update_list.hpp | 110 +- src/gui/packages_window.cpp | 648 ++--- src/gui/packages_window.hpp | 60 +- src/gui/preferences_window.cpp | 496 ++-- src/gui/preferences_window.hpp | 12 +- src/gui/print_window.cpp | 302 +-- src/gui/print_window.hpp | 58 +- src/gui/profiler_window.cpp | 226 +- src/gui/set/cards_panel.cpp | 738 +++--- src/gui/set/cards_panel.hpp | 132 +- src/gui/set/console_panel.cpp | 780 +++--- src/gui/set/console_panel.hpp | 82 +- src/gui/set/keywords_panel.cpp | 578 ++--- src/gui/set/keywords_panel.hpp | 100 +- src/gui/set/panel.cpp | 6 +- src/gui/set/panel.hpp | 110 +- src/gui/set/random_pack_panel.cpp | 914 +++---- src/gui/set/random_pack_panel.hpp | 124 +- src/gui/set/set_info_panel.cpp | 84 +- src/gui/set/set_info_panel.hpp | 42 +- src/gui/set/stats_panel.cpp | 862 +++---- src/gui/set/stats_panel.hpp | 84 +- src/gui/set/style_panel.cpp | 226 +- src/gui/set/style_panel.hpp | 78 +- src/gui/set/window.cpp | 1226 +++++----- src/gui/set/window.hpp | 282 +-- src/gui/symbol/basic_shape_editor.cpp | 444 ++-- src/gui/symbol/basic_shape_editor.hpp | 94 +- src/gui/symbol/control.cpp | 438 ++-- src/gui/symbol/control.hpp | 138 +- src/gui/symbol/editor.cpp | 4 +- src/gui/symbol/editor.hpp | 128 +- src/gui/symbol/part_list.cpp | 888 +++---- src/gui/symbol/part_list.hpp | 144 +- src/gui/symbol/point_editor.cpp | 822 +++---- src/gui/symbol/point_editor.hpp | 272 +-- src/gui/symbol/select_editor.cpp | 750 +++--- src/gui/symbol/select_editor.hpp | 184 +- src/gui/symbol/selection.cpp | 168 +- src/gui/symbol/selection.hpp | 108 +- src/gui/symbol/symmetry_editor.cpp | 274 +-- src/gui/symbol/symmetry_editor.hpp | 94 +- src/gui/symbol/window.cpp | 512 ++-- src/gui/symbol/window.hpp | 90 +- src/gui/thumbnail_thread.cpp | 374 +-- src/gui/thumbnail_thread.hpp | 78 +- src/gui/update_checker.cpp | 236 +- src/gui/util.cpp | 514 ++-- src/gui/value/choice.cpp | 398 ++-- src/gui/value/choice.hpp | 112 +- src/gui/value/color.cpp | 180 +- src/gui/value/color.hpp | 32 +- src/gui/value/editor.cpp | 8 +- src/gui/value/editor.hpp | 222 +- src/gui/value/image.cpp | 108 +- src/gui/value/image.hpp | 32 +- src/gui/value/information.cpp | 2 +- src/gui/value/information.hpp | 8 +- src/gui/value/multiple_choice.cpp | 232 +- src/gui/value/multiple_choice.hpp | 40 +- src/gui/value/package_choice.cpp | 106 +- src/gui/value/package_choice.hpp | 28 +- src/gui/value/symbol.cpp | 146 +- src/gui/value/symbol.hpp | 40 +- src/gui/value/text.cpp | 2358 +++++++++---------- src/gui/value/text.hpp | 308 +-- src/gui/welcome_window.cpp | 226 +- src/gui/welcome_window.hpp | 58 +- src/main.cpp | 462 ++-- src/render/card/viewer.cpp | 312 +-- src/render/card/viewer.hpp | 150 +- src/render/symbol/filter.cpp | 194 +- src/render/symbol/filter.hpp | 120 +- src/render/symbol/viewer.cpp | 598 ++--- src/render/symbol/viewer.hpp | 134 +- src/render/text/compound.cpp | 54 +- src/render/text/element.cpp | 450 ++-- src/render/text/element.hpp | 186 +- src/render/text/font.cpp | 64 +- src/render/text/symbol.cpp | 18 +- src/render/text/viewer.cpp | 1328 +++++------ src/render/text/viewer.hpp | 232 +- src/render/value/choice.cpp | 176 +- src/render/value/choice.hpp | 10 +- src/render/value/color.cpp | 124 +- src/render/value/color.hpp | 8 +- src/render/value/image.cpp | 210 +- src/render/value/image.hpp | 26 +- src/render/value/information.cpp | 44 +- src/render/value/information.hpp | 6 +- src/render/value/multiple_choice.cpp | 118 +- src/render/value/multiple_choice.hpp | 14 +- src/render/value/package_choice.cpp | 86 +- src/render/value/package_choice.hpp | 24 +- src/render/value/symbol.cpp | 62 +- src/render/value/symbol.hpp | 12 +- src/render/value/text.cpp | 32 +- src/render/value/text.hpp | 20 +- src/render/value/viewer.cpp | 80 +- src/render/value/viewer.hpp | 148 +- src/script/context.cpp | 948 ++++---- src/script/context.hpp | 198 +- src/script/dependency.cpp | 654 ++--- src/script/dependency.hpp | 66 +- src/script/functions/basic.cpp | 1074 ++++----- src/script/functions/construction.cpp | 60 +- src/script/functions/editor.cpp | 622 ++--- src/script/functions/english.cpp | 502 ++-- src/script/functions/export.cpp | 698 +++--- src/script/functions/functions.hpp | 16 +- src/script/functions/image.cpp | 294 +-- src/script/functions/regex.cpp | 370 +-- src/script/functions/spelling.cpp | 288 +-- src/script/functions/util.hpp | 236 +- src/script/image.cpp | 294 +-- src/script/image.hpp | 182 +- src/script/parser.cpp | 1366 +++++------ src/script/profiler.cpp | 132 +- src/script/profiler.hpp | 136 +- src/script/script.cpp | 536 ++--- src/script/script.hpp | 272 +-- src/script/script_manager.cpp | 660 +++--- src/script/script_manager.hpp | 128 +- src/script/scriptable.cpp | 106 +- src/script/scriptable.hpp | 202 +- src/script/to_value.hpp | 440 ++-- src/script/value.cpp | 584 ++--- src/script/value.hpp | 164 +- src/util/action_stack.cpp | 140 +- src/util/action_stack.hpp | 172 +- src/util/age.hpp | 56 +- src/util/alignment.cpp | 148 +- src/util/alignment.hpp | 56 +- src/util/angle.hpp | 24 +- src/util/atomic.hpp | 180 +- src/util/defaultable.hpp | 102 +- src/util/delayed_index_maps.hpp | 58 +- src/util/dynamic_arg.hpp | 156 +- src/util/error.cpp | 138 +- src/util/error.hpp | 114 +- src/util/file_utils.cpp | 292 +-- src/util/find_replace.hpp | 42 +- src/util/for_each.hpp | 134 +- src/util/index_map.hpp | 196 +- src/util/io/get_member.cpp | 4 +- src/util/io/get_member.hpp | 214 +- src/util/io/package.cpp | 842 +++---- src/util/io/package.hpp | 342 +-- src/util/io/package_manager.cpp | 742 +++--- src/util/io/package_manager.hpp | 338 +-- src/util/io/reader.cpp | 664 +++--- src/util/io/reader.hpp | 432 ++-- src/util/io/writer.cpp | 172 +- src/util/io/writer.hpp | 210 +- src/util/locale.hpp | 62 +- src/util/order_cache.hpp | 88 +- src/util/platform.hpp | 10 +- src/util/prec.hpp | 60 +- src/util/real_point.hpp | 248 +- src/util/reflect.hpp | 136 +- src/util/regex.cpp | 38 +- src/util/regex.hpp | 246 +- src/util/rotation.cpp | 502 ++-- src/util/rotation.hpp | 310 +-- src/util/smart_ptr.hpp | 210 +- src/util/spec_sort.cpp | 574 ++--- src/util/spell_checker.cpp | 184 +- src/util/spell_checker.hpp | 42 +- src/util/string.cpp | 592 ++--- src/util/string.hpp | 72 +- src/util/tagged_string.cpp | 1016 ++++---- src/util/tagged_string.hpp | 14 +- src/util/vcs.cpp | 36 +- src/util/vcs.hpp | 26 +- src/util/vcs/subversion.cpp | 72 +- src/util/vcs/subversion.hpp | 10 +- src/util/vector2d.hpp | 210 +- src/util/version.cpp | 38 +- src/util/version.hpp | 38 +- src/util/window_id.hpp | 474 ++-- src/win32-cli-wrapper.vcproj | 189 -- 329 files changed, 41307 insertions(+), 41496 deletions(-) delete mode 100644 src/win32-cli-wrapper.vcproj diff --git a/src/cli/cli_main.cpp b/src/cli/cli_main.cpp index 978d10fe..747a1646 100644 --- a/src/cli/cli_main.cpp +++ b/src/cli/cli_main.cpp @@ -20,227 +20,227 @@ DECLARE_TYPEOF_COLLECTION(ScriptParseError); // ----------------------------------------------------------------------------- : Command line interface CLISetInterface::CLISetInterface(const SetP& set, bool quiet) - : quiet(quiet) - , our_context(nullptr) + : quiet(quiet) + , our_context(nullptr) { - if (!cli.haveConsole()) { - throw Error(_("Can not run command line interface without a console;\nstart MSE with \"mse.com --cli\"")); - } - ei.allow_writes_outside = true; - setExportInfoCwd(); - setSet(set); - run(); + if (!cli.haveConsole()) { + throw Error(_("Can not run command line interface without a console;\nstart MSE with \"mse.com --cli\"")); + } + ei.allow_writes_outside = true; + setExportInfoCwd(); + setSet(set); + run(); } CLISetInterface::~CLISetInterface() { - delete our_context; + delete our_context; } Context& CLISetInterface::getContext() { - if (set) { - return set->getContext(); - } else { - if (!our_context) { - our_context = new Context(); - init_script_functions(*our_context); - } - return *our_context; - } + if (set) { + return set->getContext(); + } else { + if (!our_context) { + our_context = new Context(); + init_script_functions(*our_context); + } + return *our_context; + } } void CLISetInterface::onBeforeChangeSet() { - if (set || our_context) { - Context& ctx = getContext(); - ctx.closeScope(scope); - } + if (set || our_context) { + Context& ctx = getContext(); + ctx.closeScope(scope); + } } void CLISetInterface::onChangeSet() { - Context& ctx = getContext(); - scope = ctx.openScope(); - ei.set = set; + Context& ctx = getContext(); + scope = ctx.openScope(); + ei.set = set; } void CLISetInterface::setExportInfoCwd() { - // write to the current directory - ei.directory_relative = ei.directory_absolute = wxGetCwd(); - // read from the current directory - ei.export_template = intrusive(new Package()); - ei.export_template->open(ei.directory_absolute, true); + // write to the current directory + ei.directory_relative = ei.directory_absolute = wxGetCwd(); + // read from the current directory + ei.export_template = intrusive(new Package()); + ei.export_template->open(ei.directory_absolute, true); } // ----------------------------------------------------------------------------- : Running void CLISetInterface::run() { - // show welcome logo - if (!quiet) showWelcome(); - print_pending_errors(); - // loop - running = true; - while (running) { - // show prompt - if (!quiet) { - cli << GRAY << _("> ") << NORMAL; - cli.flush(); - } - // read line from stdin - String command = cli.getLine(); - if (command.empty() && !cli.canGetLine()) break; - handleCommand(command); - print_pending_errors(); - cli.flush(); - cli.flushRaw(); - } + // show welcome logo + if (!quiet) showWelcome(); + print_pending_errors(); + // loop + running = true; + while (running) { + // show prompt + if (!quiet) { + cli << GRAY << _("> ") << NORMAL; + cli.flush(); + } + // read line from stdin + String command = cli.getLine(); + if (command.empty() && !cli.canGetLine()) break; + handleCommand(command); + print_pending_errors(); + cli.flush(); + cli.flushRaw(); + } } void CLISetInterface::showWelcome() { - cli << _(" ___ \n") - _(" __ __ _ ___ _ ___ _ _ _ |__ \\ \n") - _(" | \\/ |__ _ __ _(_)__ / __|___| |_ | __|__| (_) |_ ___ _ _ ) |\n") - _(" | |\\/| / _` / _` | / _| \\__ | -_) _| | _|/ _` | | _/ _ \\ '_| / / \n") - _(" |_| |_\\__,_\\__, |_\\__| |___|___|\\__| |___\\__,_|_|\\__\\___/_| / /_ \n") - _(" |___/ |____|\n\n"); - cli.flush(); + cli << _(" ___ \n") + _(" __ __ _ ___ _ ___ _ _ _ |__ \\ \n") + _(" | \\/ |__ _ __ _(_)__ / __|___| |_ | __|__| (_) |_ ___ _ _ ) |\n") + _(" | |\\/| / _` / _` | / _| \\__ | -_) _| | _|/ _` | | _/ _ \\ '_| / / \n") + _(" |_| |_\\__,_\\__, |_\\__| |___|___|\\__| |___\\__,_|_|\\__\\___/_| / /_ \n") + _(" |___/ |____|\n\n"); + cli.flush(); } void CLISetInterface::showUsage() { - cli << _(" Commands available from the prompt:\n\n"); - cli << _(" Execute a script expression, display the result\n"); - cli << _(" :help Show this help page.\n"); - cli << _(" :load Load a different set file.\n"); - cli << _(" :quit Exit the MSE command line interface.\n"); - cli << _(" :reset Clear all local variable definitions.\n"); - cli << _(" :pwd Print the current working directory.\n"); - cli << _(" :cd Change the working directory.\n"); - cli << _(" :! Perform a shell command.\n"); - cli << _("\n Commands can be abreviated to their first letter if there is no ambiguity.\n\n"); + cli << _(" Commands available from the prompt:\n\n"); + cli << _(" Execute a script expression, display the result\n"); + cli << _(" :help Show this help page.\n"); + cli << _(" :load Load a different set file.\n"); + cli << _(" :quit Exit the MSE command line interface.\n"); + cli << _(" :reset Clear all local variable definitions.\n"); + cli << _(" :pwd Print the current working directory.\n"); + cli << _(" :cd Change the working directory.\n"); + cli << _(" :! Perform a shell command.\n"); + cli << _("\n Commands can be abreviated to their first letter if there is no ambiguity.\n\n"); } void CLISetInterface::handleCommand(const String& command) { - try { - if (command.empty()) { - // empty, ignore - } else if (command.GetChar(0) == _(':')) { - // :something - size_t space = min(command.find_first_of(_(' ')), command.size()); - String before = command.substr(0,space); - String arg = space + 1 < command.size() ? command.substr(space+1) : wxEmptyString; - if (before == _(":q") || before == _(":quit")) { - if (!quiet) { - cli << _("Goodbye\n"); - } - running = false; - } else if (before == _(":?") || before == _(":h") || before == _(":help")) { - showUsage(); - } else if (before == _(":l") || before == _(":load")) { - if (arg.empty()) { - cli.show_message(MESSAGE_ERROR,_("Give a filename to open.")); - } else { - setSet(import_set(arg)); - } - } else if (before == _(":r") || before == _(":reset")) { - Context& ctx = getContext(); - ei.exported_images.clear(); - ctx.closeScope(scope); - scope = ctx.openScope(); - } else if (before == _(":i") || before == _(":info")) { - if (set) { - cli << _("set: ") << set->identification() << ENDL; - cli << _("filename: ") << set->absoluteFilename() << ENDL; - cli << _("relative: ") << set->relativeFilename() << ENDL; - cli << String::Format(_("#cards: %d"), set->cards.size()) << ENDL; - } else { - cli << _("No set loaded") << ENDL; - } - } else if (before == _(":c") || before == _(":cd")) { - if (arg.empty()) { - cli.show_message(MESSAGE_ERROR,_("Give a new working directory.")); - } else { - if (!wxSetWorkingDirectory(arg)) { - cli.show_message(MESSAGE_ERROR,_("Can't change working directory to ")+arg); - } else { - setExportInfoCwd(); - } - } - } else if (before == _(":pwd") || before == _(":p")) { - cli << ei.directory_absolute << ENDL; - } else if (before == _(":!")) { - if (arg.empty()) { - cli.show_message(MESSAGE_ERROR,_("Give a shell command to execute.")); - } else { - #ifdef UNICODE - #ifdef __WXMSW__ - _wsystem(arg.c_str()); // TODO: is this function available on other platforms? - #else - wxCharBuffer buf = arg.fn_str(); - system(buf); - #endif - #else - system(arg.c_str()); - #endif - } - #if USE_SCRIPT_PROFILING - } else if (before == _(":profile")) { - if (arg == _("full")) { - showProfilingStats(profile_root); - } else { - long level = 1; - arg.ToLong(&level); - showProfilingStats(profile_aggregated(level)); - } - #endif - } else { - cli.show_message(MESSAGE_ERROR,_("Unknown command, type :help for help.")); - } - } else if (command == _("exit") || command == _("quit")) { - cli << _("Use :quit to quit\n"); - } else if (command == _("help")) { - cli << _("Use :help for help\n"); - } else { - // parse command - vector errors; - ScriptP script = parse(command,nullptr,false,errors); - if (!errors.empty()) { - FOR_EACH(error,errors) cli.show_message(MESSAGE_ERROR,error.what()); - return; - } - // execute command - WITH_DYNAMIC_ARG(export_info, &ei); - Context& ctx = getContext(); - ScriptValueP result = ctx.eval(*script,false); - // show result - cli << result->toCode() << ENDL; - } - } catch (const Error& e) { - cli.show_message(MESSAGE_ERROR,e.what()); - } + try { + if (command.empty()) { + // empty, ignore + } else if (command.GetChar(0) == _(':')) { + // :something + size_t space = min(command.find_first_of(_(' ')), command.size()); + String before = command.substr(0,space); + String arg = space + 1 < command.size() ? command.substr(space+1) : wxEmptyString; + if (before == _(":q") || before == _(":quit")) { + if (!quiet) { + cli << _("Goodbye\n"); + } + running = false; + } else if (before == _(":?") || before == _(":h") || before == _(":help")) { + showUsage(); + } else if (before == _(":l") || before == _(":load")) { + if (arg.empty()) { + cli.show_message(MESSAGE_ERROR,_("Give a filename to open.")); + } else { + setSet(import_set(arg)); + } + } else if (before == _(":r") || before == _(":reset")) { + Context& ctx = getContext(); + ei.exported_images.clear(); + ctx.closeScope(scope); + scope = ctx.openScope(); + } else if (before == _(":i") || before == _(":info")) { + if (set) { + cli << _("set: ") << set->identification() << ENDL; + cli << _("filename: ") << set->absoluteFilename() << ENDL; + cli << _("relative: ") << set->relativeFilename() << ENDL; + cli << String::Format(_("#cards: %d"), set->cards.size()) << ENDL; + } else { + cli << _("No set loaded") << ENDL; + } + } else if (before == _(":c") || before == _(":cd")) { + if (arg.empty()) { + cli.show_message(MESSAGE_ERROR,_("Give a new working directory.")); + } else { + if (!wxSetWorkingDirectory(arg)) { + cli.show_message(MESSAGE_ERROR,_("Can't change working directory to ")+arg); + } else { + setExportInfoCwd(); + } + } + } else if (before == _(":pwd") || before == _(":p")) { + cli << ei.directory_absolute << ENDL; + } else if (before == _(":!")) { + if (arg.empty()) { + cli.show_message(MESSAGE_ERROR,_("Give a shell command to execute.")); + } else { + #ifdef UNICODE + #ifdef __WXMSW__ + _wsystem(arg.c_str()); // TODO: is this function available on other platforms? + #else + wxCharBuffer buf = arg.fn_str(); + system(buf); + #endif + #else + system(arg.c_str()); + #endif + } + #if USE_SCRIPT_PROFILING + } else if (before == _(":profile")) { + if (arg == _("full")) { + showProfilingStats(profile_root); + } else { + long level = 1; + arg.ToLong(&level); + showProfilingStats(profile_aggregated(level)); + } + #endif + } else { + cli.show_message(MESSAGE_ERROR,_("Unknown command, type :help for help.")); + } + } else if (command == _("exit") || command == _("quit")) { + cli << _("Use :quit to quit\n"); + } else if (command == _("help")) { + cli << _("Use :help for help\n"); + } else { + // parse command + vector errors; + ScriptP script = parse(command,nullptr,false,errors); + if (!errors.empty()) { + FOR_EACH(error,errors) cli.show_message(MESSAGE_ERROR,error.what()); + return; + } + // execute command + WITH_DYNAMIC_ARG(export_info, &ei); + Context& ctx = getContext(); + ScriptValueP result = ctx.eval(*script,false); + // show result + cli << result->toCode() << ENDL; + } + } catch (const Error& e) { + cli.show_message(MESSAGE_ERROR,e.what()); + } } #if USE_SCRIPT_PROFILING - DECLARE_TYPEOF_COLLECTION(FunctionProfileP); - void CLISetInterface::showProfilingStats(const FunctionProfile& item, int level) { - // show parent - if (level == 0) { - cli << GRAY << _("Time(s) Avg (ms) Calls Function") << ENDL; - cli << _("======== ======== ====== ===============================") << NORMAL << ENDL; - } else { - for (int i = 1 ; i < level ; ++i) cli << _(" "); - cli << String::Format(_("%8.5f %8.5f %6d %s"), item.total_time(), 1000 * item.avg_time(), item.calls, item.name.c_str()) << ENDL; - } - // show children - vector children; - item.get_children(children); - FOR_EACH_REVERSE(c, children) { - showProfilingStats(*c, level + 1); - } - } + DECLARE_TYPEOF_COLLECTION(FunctionProfileP); + void CLISetInterface::showProfilingStats(const FunctionProfile& item, int level) { + // show parent + if (level == 0) { + cli << GRAY << _("Time(s) Avg (ms) Calls Function") << ENDL; + cli << _("======== ======== ====== ===============================") << NORMAL << ENDL; + } else { + for (int i = 1 ; i < level ; ++i) cli << _(" "); + cli << String::Format(_("%8.5f %8.5f %6d %s"), item.total_time(), 1000 * item.avg_time(), item.calls, item.name.c_str()) << ENDL; + } + // show children + vector children; + item.get_children(children); + FOR_EACH_REVERSE(c, children) { + showProfilingStats(*c, level + 1); + } + } #endif void CLISetInterface::print_pending_errors() { - MessageType type; - String msg; - while (get_queued_message(type,msg)) { - cli.show_message(type,msg); - } + MessageType type; + String msg; + while (get_queued_message(type,msg)) { + cli.show_message(type,msg); + } } diff --git a/src/cli/cli_main.hpp b/src/cli/cli_main.hpp index e461cfcd..1aa939ce 100644 --- a/src/cli/cli_main.hpp +++ b/src/cli/cli_main.hpp @@ -18,34 +18,34 @@ class CLISetInterface : public SetView { public: - /// The set is optional - CLISetInterface(const SetP& set, bool quiet = false); - ~CLISetInterface(); + /// The set is optional + CLISetInterface(const SetP& set, bool quiet = false); + ~CLISetInterface(); protected: - virtual void onAction(const Action&, bool) {} - virtual void onChangeSet(); - virtual void onBeforeChangeSet(); + virtual void onAction(const Action&, bool) {} + virtual void onChangeSet(); + virtual void onBeforeChangeSet(); private: - bool quiet; ///< Supress prompts and other non-vital stuff - bool running; ///< Still running? - - void run(); - void showWelcome(); - void showUsage(); - void handleCommand(const String& command); - #if USE_SCRIPT_PROFILING - void showProfilingStats(const FunctionProfile& parent, int level = 0); - #endif - void print_pending_errors(); - - /// our own context, when no set is loaded - Context& getContext(); - Context* our_context; - size_t scope; - - // export info, so we can write files - ExportInfo ei; - void setExportInfoCwd(); + bool quiet; ///< Supress prompts and other non-vital stuff + bool running; ///< Still running? + + void run(); + void showWelcome(); + void showUsage(); + void handleCommand(const String& command); + #if USE_SCRIPT_PROFILING + void showProfilingStats(const FunctionProfile& parent, int level = 0); + #endif + void print_pending_errors(); + + /// our own context, when no set is loaded + Context& getContext(); + Context* our_context; + size_t scope; + + // export info, so we can write files + ExportInfo ei; + void setExportInfoCwd(); }; // ----------------------------------------------------------------------------- : EOF diff --git a/src/cli/text_io_handler.cpp b/src/cli/text_io_handler.cpp index f86fc5e1..2ff6e48d 100644 --- a/src/cli/text_io_handler.cpp +++ b/src/cli/text_io_handler.cpp @@ -24,155 +24,155 @@ const Char* ENDL = _("\n"); TextIOHandler cli; #ifdef __WXMSW__ - bool StdHandleOk(DWORD std_handle) { - // GetStdHandle sometimes returns an invalid handle instead of INVALID_HANDLE_VALUE - // check with GetHandleInformation - HANDLE h = GetStdHandle(std_handle); - DWORD flags; - return GetHandleInformation(h,&flags); - } + bool StdHandleOk(DWORD std_handle) { + // GetStdHandle sometimes returns an invalid handle instead of INVALID_HANDLE_VALUE + // check with GetHandleInformation + HANDLE h = GetStdHandle(std_handle); + DWORD flags; + return GetHandleInformation(h,&flags); + } #endif void TextIOHandler::init() { - bool have_stderr; - #if defined(__WXMSW__) - have_console = false; - escapes = false; - // Detect whether to use console output - have_console = StdHandleOk(STD_OUTPUT_HANDLE); - have_stderr = StdHandleOk(STD_ERROR_HANDLE); - // Detect the --color flag, indicating we should allow escapes - if (have_console) { - for (int i = 1 ; i < wxTheApp->argc ; ++i) { - if (String(wxTheApp->argv[i]) == _("--color")) { - escapes = true; - break; - } - } - } - #else - // TODO: detect console on linux? - have_console = false; - have_stderr = false; - // Use console mode if one of the cli flags is passed - static const Char* redirect_flags[] = {_("-?"),_("--help"),_("-v"),_("--version"),_("--cli"),_("-c"),_("--export"),_("--create-installer")}; - for (int i = 1 ; i < wxTheApp->argc ; ++i) { - for (int j = 0 ; j < sizeof(redirect_flags)/sizeof(redirect_flags[0]) ; ++j) { - if (String(wxTheApp->argv[i]) == redirect_flags[j]) { - have_console = true; - have_stderr = true; - break; - } - } - } - escapes = true; // TODO: detect output redirection - #endif - // write to standard output - stream = stdout; - raw_mode = false; - // always write to stderr if possible - if (have_console) { - write_errors_to_cli = true; - } + bool have_stderr; + #if defined(__WXMSW__) + have_console = false; + escapes = false; + // Detect whether to use console output + have_console = StdHandleOk(STD_OUTPUT_HANDLE); + have_stderr = StdHandleOk(STD_ERROR_HANDLE); + // Detect the --color flag, indicating we should allow escapes + if (have_console) { + for (int i = 1 ; i < wxTheApp->argc ; ++i) { + if (String(wxTheApp->argv[i]) == _("--color")) { + escapes = true; + break; + } + } + } + #else + // TODO: detect console on linux? + have_console = false; + have_stderr = false; + // Use console mode if one of the cli flags is passed + static const Char* redirect_flags[] = {_("-?"),_("--help"),_("-v"),_("--version"),_("--cli"),_("-c"),_("--export"),_("--create-installer")}; + for (int i = 1 ; i < wxTheApp->argc ; ++i) { + for (int j = 0 ; j < sizeof(redirect_flags)/sizeof(redirect_flags[0]) ; ++j) { + if (String(wxTheApp->argv[i]) == redirect_flags[j]) { + have_console = true; + have_stderr = true; + break; + } + } + } + escapes = true; // TODO: detect output redirection + #endif + // write to standard output + stream = stdout; + raw_mode = false; + // always write to stderr if possible + if (have_console) { + write_errors_to_cli = true; + } } bool TextIOHandler::haveConsole() const { - return have_console; + return have_console; } // ----------------------------------------------------------------------------- : Output TextIOHandler& TextIOHandler::operator << (const Char* str) { - if ((escapes && !raw_mode) || str[0] != 27) { - if (have_console && !raw_mode) { - IF_UNICODE(fwprintf,fprintf)(stream,str); - } else { - buffer += str; - } - } - return *this; + if ((escapes && !raw_mode) || str[0] != 27) { + if (have_console && !raw_mode) { + IF_UNICODE(fwprintf,fprintf)(stream,str); + } else { + buffer += str; + } + } + return *this; } TextIOHandler& TextIOHandler::operator << (const String& str) { - return *this << static_cast(str.c_str()); + return *this << static_cast(str.c_str()); } void TextIOHandler::flush() { - if (raw_mode) return; - if (have_console) { - fflush(stream); - } else if (!buffer.empty()) { - // Show message box - wxMessageBox(buffer, _("Magic Set Editor"), wxOK | wxICON_INFORMATION); - buffer.clear(); - } + if (raw_mode) return; + if (have_console) { + fflush(stream); + } else if (!buffer.empty()) { + // Show message box + wxMessageBox(buffer, _("Magic Set Editor"), wxOK | wxICON_INFORMATION); + buffer.clear(); + } } // ----------------------------------------------------------------------------- : Input String TextIOHandler::getLine() { - String result; - Char buffer[2048]; - while (!feof(stdin)) { - if (!IF_UNICODE(fgetws,fgets)(buffer, 2048, stdin)) { - return result; // error - } - result += buffer; - if (result.GetChar(result.size()-1) == _('\n')) { - // drop newline, done - result.resize(result.size() - 1); - return result; - } - } - return result; + String result; + Char buffer[2048]; + while (!feof(stdin)) { + if (!IF_UNICODE(fgetws,fgets)(buffer, 2048, stdin)) { + return result; // error + } + result += buffer; + if (result.GetChar(result.size()-1) == _('\n')) { + // drop newline, done + result.resize(result.size() - 1); + return result; + } + } + return result; } bool TextIOHandler::canGetLine() { - return !feof(stdin); + return !feof(stdin); } // ----------------------------------------------------------------------------- : Raw mode void TextIOHandler::enableRaw() { - raw_mode = true; - raw_mode_status = 0; + raw_mode = true; + raw_mode_status = 0; } void TextIOHandler::flushRaw() { - if (!raw_mode) return; - // always end in a newline - if (!buffer.empty() && buffer.GetChar(buffer.size()-1) != _('\n')) { - buffer += _('\n'); - } - // count newlines - int newline_count = 0; - FOR_EACH_CONST(c,buffer) if (c==_('\n')) newline_count++; - // write record - printf("%d\n%d\n", raw_mode_status, newline_count); - if (!buffer.empty()) { - #ifdef UNICODE - wxCharBuffer buf = buffer.mb_str(wxConvUTF8); - fputs(buf,stdout); - #else - fputs(buffer.c_str(),stdout); - #endif - } - fflush(stdout); - // clear - buffer.clear(); - raw_mode_status = 0; + if (!raw_mode) return; + // always end in a newline + if (!buffer.empty() && buffer.GetChar(buffer.size()-1) != _('\n')) { + buffer += _('\n'); + } + // count newlines + int newline_count = 0; + FOR_EACH_CONST(c,buffer) if (c==_('\n')) newline_count++; + // write record + printf("%d\n%d\n", raw_mode_status, newline_count); + if (!buffer.empty()) { + #ifdef UNICODE + wxCharBuffer buf = buffer.mb_str(wxConvUTF8); + fputs(buf,stdout); + #else + fputs(buffer.c_str(),stdout); + #endif + } + fflush(stdout); + // clear + buffer.clear(); + raw_mode_status = 0; } // ----------------------------------------------------------------------------- : Errors void TextIOHandler::show_message(MessageType type, String const& message) { - stream = stdout; - if (type == MESSAGE_WARNING) { - *this << YELLOW << _("WARNING: ") << NORMAL << replace_all(message,_("\n"),_("\n ")) << ENDL; - } else { - *this << RED << _("ERROR: ") << NORMAL << replace_all(message,_("\n"),_("\n ")) << ENDL; - } - flush(); - stream = stdout; - if (raw_mode) raw_mode_status = max(raw_mode_status, type == MESSAGE_WARNING ? 1 : 2); + stream = stdout; + if (type == MESSAGE_WARNING) { + *this << YELLOW << _("WARNING: ") << NORMAL << replace_all(message,_("\n"),_("\n ")) << ENDL; + } else { + *this << RED << _("ERROR: ") << NORMAL << replace_all(message,_("\n"),_("\n ")) << ENDL; + } + flush(); + stream = stdout; + if (raw_mode) raw_mode_status = max(raw_mode_status, type == MESSAGE_WARNING ? 1 : 2); } diff --git a/src/cli/text_io_handler.hpp b/src/cli/text_io_handler.hpp index 57196204..0189f669 100644 --- a/src/cli/text_io_handler.hpp +++ b/src/cli/text_io_handler.hpp @@ -19,39 +19,39 @@ extern const Char *BRIGHT, *NORMAL, *PARAM, *FILE_EXT, *GRAY, *RED, *ENDL; /// Command line input / output handler class TextIOHandler { public: - void init(); - - /// Do we have a console to read/write from/to? - bool haveConsole() const; - - /// Output text to the console - TextIOHandler& operator << (const Char*); - TextIOHandler& operator << (const String&); - - /// Read a line from stdin - String getLine(); - /// Can another line be got? - bool canGetLine(); - - /// Flush output - void flush(); - - /// Show an error or warning message - void show_message(MessageType type, String const& message); - - /// Enable raw mode - void enableRaw(); - /// Output a single raw-mode record - /// Has no effect unless enableRaw() was called - void flushRaw(); - + void init(); + + /// Do we have a console to read/write from/to? + bool haveConsole() const; + + /// Output text to the console + TextIOHandler& operator << (const Char*); + TextIOHandler& operator << (const String&); + + /// Read a line from stdin + String getLine(); + /// Can another line be got? + bool canGetLine(); + + /// Flush output + void flush(); + + /// Show an error or warning message + void show_message(MessageType type, String const& message); + + /// Enable raw mode + void enableRaw(); + /// Output a single raw-mode record + /// Has no effect unless enableRaw() was called + void flushRaw(); + private: - bool have_console; - bool escapes; - FILE* stream; - String buffer; ///< Buffer when not writing to console - bool raw_mode; - int raw_mode_status; + bool have_console; + bool escapes; + FILE* stream; + String buffer; ///< Buffer when not writing to console + bool raw_mode; + int raw_mode_status; }; /// The global TextIOHandler object diff --git a/src/cli/win32_cli_wrapper.cpp b/src/cli/win32_cli_wrapper.cpp index 418e08b2..514db433 100644 --- a/src/cli/win32_cli_wrapper.cpp +++ b/src/cli/win32_cli_wrapper.cpp @@ -37,8 +37,8 @@ /// How to transfer data from one handle to another struct Transfer { - HANDLE from, &to; - bool escapes; + HANDLE from, &to; + bool escapes; }; DWORD WINAPI TransferThread(Transfer*); @@ -60,181 +60,181 @@ HANDLE err_mine, err_theirs, err_real; const char* redirect_flags[] = {"-?","--help","-v","--version","--cli","-c","--export","--create-installer"}; int main(int argc, char** argv) { - // determine whether we need to wrap console i/o - bool need_redirection = false; - for (int i = 1 ; i < argc ; ++i) { - for (int j = 0 ; j < sizeof(redirect_flags)/sizeof(redirect_flags[0]) ; ++j) { - if (strcmp(argv[i],redirect_flags[j]) == 0) { - need_redirection = true; - goto break_2; - } - } - } - break_2: - - // command line - TCHAR* command_line = GetCommandLine(); - if (need_redirection) { - // update command line : add --color flag - TCHAR* my_command_line = command_line; - command_line = new TCHAR[_tcsclen(command_line) + 10]; - _tcscpy(command_line, my_command_line); - _tcscat(command_line, _T(" --color")); - } - - // application name - TCHAR app_path[2048]; - GetModuleFileName(NULL/*current process*/, app_path, sizeof(app_path)/sizeof(TCHAR)); - size_t app_path_length = _tcsclen(app_path); - if (app_path_length > 4 && _tcsicmp(app_path + app_path_length - 4, _T(".com")) == 0) { - // replace ".com" with ".exe" - _tcscpy(app_path + app_path_length - 4, _T(".exe")); - } else { - // not a .com file, error message - fprintf(stderr, "This executable should be named .com\n"); - } - - // win32 structures for child program - STARTUPINFO child_startup_info; - memset(&child_startup_info, 0, sizeof(child_startup_info)); - memset(&child_process_info, 0, sizeof(child_process_info)); - child_startup_info.cb = sizeof(child_startup_info); - - // setup redirection - if (need_redirection) { - // Ctrl+C handler - SetConsoleCtrlHandler(HandleCtrlEvent, TRUE); - - // create pipes - CreatePipe(&in_theirs, &in_mine, NULL, 0); - CreatePipe(&out_mine, &out_theirs, NULL, 0); - CreatePipe(&err_mine, &err_theirs, NULL, 0); - - // the actual handles - in_real = GetStdHandle(STD_INPUT_HANDLE); - out_real = GetStdHandle(STD_OUTPUT_HANDLE); - err_real = GetStdHandle(STD_ERROR_HANDLE); - InitEscapeTranslation(out_real); - - // start threads - Transfer tranfer_in = {in_real, in_mine, false}; - Transfer tranfer_out = {out_mine, out_real, true}; - Transfer tranfer_err = {err_mine, err_real, true}; - CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TransferThread,&tranfer_in, 0,NULL); - CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TransferThread,&tranfer_out,0,NULL); - CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TransferThread,&tranfer_err,0,NULL); - - // give (inheritable copies of) handles to child process - HANDLE me = GetCurrentProcess(); - DuplicateHandle(me,in_theirs, me,&child_startup_info.hStdInput, 0,TRUE,DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS); - DuplicateHandle(me,out_theirs,me,&child_startup_info.hStdOutput,0,TRUE,DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS); - DuplicateHandle(me,err_theirs,me,&child_startup_info.hStdError, 0,TRUE,DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS); - child_startup_info.dwFlags = STARTF_USESTDHANDLES; - } - - // start the child program - if (!CreateProcess(app_path,command_line,NULL,NULL,TRUE,0,NULL,NULL,&child_startup_info,&child_process_info)) { - ExitProcess(1); - } - - // wait for program to terminate - DWORD exit_code = 0; - if (need_redirection) { - delete [] command_line; - WaitForSingleObject(child_process_info.hProcess, INFINITE); - GetExitCodeProcess(child_process_info.hProcess, &exit_code); - } - - // That's all folks! - return exit_code; + // determine whether we need to wrap console i/o + bool need_redirection = false; + for (int i = 1 ; i < argc ; ++i) { + for (int j = 0 ; j < sizeof(redirect_flags)/sizeof(redirect_flags[0]) ; ++j) { + if (strcmp(argv[i],redirect_flags[j]) == 0) { + need_redirection = true; + goto break_2; + } + } + } + break_2: + + // command line + TCHAR* command_line = GetCommandLine(); + if (need_redirection) { + // update command line : add --color flag + TCHAR* my_command_line = command_line; + command_line = new TCHAR[_tcsclen(command_line) + 10]; + _tcscpy(command_line, my_command_line); + _tcscat(command_line, _T(" --color")); + } + + // application name + TCHAR app_path[2048]; + GetModuleFileName(NULL/*current process*/, app_path, sizeof(app_path)/sizeof(TCHAR)); + size_t app_path_length = _tcsclen(app_path); + if (app_path_length > 4 && _tcsicmp(app_path + app_path_length - 4, _T(".com")) == 0) { + // replace ".com" with ".exe" + _tcscpy(app_path + app_path_length - 4, _T(".exe")); + } else { + // not a .com file, error message + fprintf(stderr, "This executable should be named .com\n"); + } + + // win32 structures for child program + STARTUPINFO child_startup_info; + memset(&child_startup_info, 0, sizeof(child_startup_info)); + memset(&child_process_info, 0, sizeof(child_process_info)); + child_startup_info.cb = sizeof(child_startup_info); + + // setup redirection + if (need_redirection) { + // Ctrl+C handler + SetConsoleCtrlHandler(HandleCtrlEvent, TRUE); + + // create pipes + CreatePipe(&in_theirs, &in_mine, NULL, 0); + CreatePipe(&out_mine, &out_theirs, NULL, 0); + CreatePipe(&err_mine, &err_theirs, NULL, 0); + + // the actual handles + in_real = GetStdHandle(STD_INPUT_HANDLE); + out_real = GetStdHandle(STD_OUTPUT_HANDLE); + err_real = GetStdHandle(STD_ERROR_HANDLE); + InitEscapeTranslation(out_real); + + // start threads + Transfer tranfer_in = {in_real, in_mine, false}; + Transfer tranfer_out = {out_mine, out_real, true}; + Transfer tranfer_err = {err_mine, err_real, true}; + CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TransferThread,&tranfer_in, 0,NULL); + CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TransferThread,&tranfer_out,0,NULL); + CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TransferThread,&tranfer_err,0,NULL); + + // give (inheritable copies of) handles to child process + HANDLE me = GetCurrentProcess(); + DuplicateHandle(me,in_theirs, me,&child_startup_info.hStdInput, 0,TRUE,DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS); + DuplicateHandle(me,out_theirs,me,&child_startup_info.hStdOutput,0,TRUE,DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS); + DuplicateHandle(me,err_theirs,me,&child_startup_info.hStdError, 0,TRUE,DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS); + child_startup_info.dwFlags = STARTF_USESTDHANDLES; + } + + // start the child program + if (!CreateProcess(app_path,command_line,NULL,NULL,TRUE,0,NULL,NULL,&child_startup_info,&child_process_info)) { + ExitProcess(1); + } + + // wait for program to terminate + DWORD exit_code = 0; + if (need_redirection) { + delete [] command_line; + WaitForSingleObject(child_process_info.hProcess, INFINITE); + GetExitCodeProcess(child_process_info.hProcess, &exit_code); + } + + // That's all folks! + return exit_code; } // ----------------------------------------------------------------------------- : Terminating /// Handle Ctrl+C BOOL WINAPI HandleCtrlEvent(DWORD type) { - DWORD exit_code = 1; - // try to exit child process cleanly - // TODO: don't exit child on Ctrl+C - bool wait = false; - if (in_mine != INVALID_HANDLE_VALUE) { - CopyFileBuffer(in_mine,":quit\n",6); - CopyFileBuffer(out_real,":quit\n",6); - wait = true; - } - if (wait && WaitForSingleObject(child_process_info.hProcess,100) == WAIT_OBJECT_0) { - GetExitCodeProcess(child_process_info.hProcess, &exit_code); - } else { - TerminateProcess(child_process_info.hProcess,1); - } - // exit this process - ExitProcess(exit_code); - return TRUE; + DWORD exit_code = 1; + // try to exit child process cleanly + // TODO: don't exit child on Ctrl+C + bool wait = false; + if (in_mine != INVALID_HANDLE_VALUE) { + CopyFileBuffer(in_mine,":quit\n",6); + CopyFileBuffer(out_real,":quit\n",6); + wait = true; + } + if (wait && WaitForSingleObject(child_process_info.hProcess,100) == WAIT_OBJECT_0) { + GetExitCodeProcess(child_process_info.hProcess, &exit_code); + } else { + TerminateProcess(child_process_info.hProcess,1); + } + // exit this process + ExitProcess(exit_code); + return TRUE; } // ----------------------------------------------------------------------------- : I/O redirection /// Copy a buffer to an output handle void CopyFileBuffer(HANDLE output, char* buffer, DWORD size) { - DWORD pos = 0, bytes_written; - while (pos < size) { - WriteFile(output, buffer + pos, size - pos, &bytes_written, NULL); - pos += bytes_written; - } + DWORD pos = 0, bytes_written; + while (pos < size) { + WriteFile(output, buffer + pos, size - pos, &bytes_written, NULL); + pos += bytes_written; + } } /// Copy a buffer to an output handle, handling escape code void CopyFileBufferWithEscape(HANDLE output, char* buffer, DWORD size, bool handle_escapes) { - if (!handle_escapes) { - CopyFileBuffer(output, buffer, size); - return; - } - DWORD pos = 0; - while (pos < size) { - // find next escape code, "\x1B[" - DWORD next_pos = pos; - while (next_pos < size && - (buffer[next_pos] != '\x1B' || - (next_pos + 1 >= size || buffer[next_pos+1] != '['))) ++next_pos; - // copy part before next escape - CopyFileBuffer(output, buffer+pos, next_pos-pos); - pos = next_pos; - // is this an escape code? - if (pos + 1 < size) { - // handle escape code - int argv[10] = {0}, argc = 1; - for (pos += 2 ; pos < size ; ++pos) { - if (buffer[pos] == ';') { - ++argc; - } else if (buffer[pos] >= '0' && buffer[pos] <= '9') { - argv[argc-1] = 10 * argv[argc-1] + buffer[pos] - '0'; - } else { - PerformEscapeCode(output, buffer[pos], argc, argv); - pos++; - break; - } - } - } - } + if (!handle_escapes) { + CopyFileBuffer(output, buffer, size); + return; + } + DWORD pos = 0; + while (pos < size) { + // find next escape code, "\x1B[" + DWORD next_pos = pos; + while (next_pos < size && + (buffer[next_pos] != '\x1B' || + (next_pos + 1 >= size || buffer[next_pos+1] != '['))) ++next_pos; + // copy part before next escape + CopyFileBuffer(output, buffer+pos, next_pos-pos); + pos = next_pos; + // is this an escape code? + if (pos + 1 < size) { + // handle escape code + int argv[10] = {0}, argc = 1; + for (pos += 2 ; pos < size ; ++pos) { + if (buffer[pos] == ';') { + ++argc; + } else if (buffer[pos] >= '0' && buffer[pos] <= '9') { + argv[argc-1] = 10 * argv[argc-1] + buffer[pos] - '0'; + } else { + PerformEscapeCode(output, buffer[pos], argc, argv); + pos++; + break; + } + } + } + } } /// Thread to transfer text from one handle to another DWORD WINAPI TransferThread(Transfer* transfer) { - while (true) { - // read - char buffer[1024]; - DWORD bytes_read; - BOOL ok = ReadFile(transfer->from, buffer, sizeof(buffer), &bytes_read, NULL); - if (ok && bytes_read == 0) { - // end of file: close handle - CloseHandle(transfer->to); - transfer->to = INVALID_HANDLE_VALUE; - break; - } - // write - CopyFileBufferWithEscape(transfer->to, buffer, bytes_read, transfer->escapes); - } - return 0; + while (true) { + // read + char buffer[1024]; + DWORD bytes_read; + BOOL ok = ReadFile(transfer->from, buffer, sizeof(buffer), &bytes_read, NULL); + if (ok && bytes_read == 0) { + // end of file: close handle + CloseHandle(transfer->to); + transfer->to = INVALID_HANDLE_VALUE; + break; + } + // write + CopyFileBufferWithEscape(transfer->to, buffer, bytes_read, transfer->escapes); + } + return 0; } // ----------------------------------------------------------------------------- : Escape codes @@ -246,64 +246,64 @@ WORD original_attributes; /// Initialization for escape translation void InitEscapeTranslation(HANDLE console) { - CONSOLE_SCREEN_BUFFER_INFO screen_buffer; - GetConsoleScreenBufferInfo(console, &screen_buffer); - original_attributes = screen_buffer.wAttributes; + CONSOLE_SCREEN_BUFFER_INFO screen_buffer; + GetConsoleScreenBufferInfo(console, &screen_buffer); + original_attributes = screen_buffer.wAttributes; } /// Perform an escape code void PerformEscapeCode(HANDLE console, char command, int argc, int argv[]) { - switch (command) { - case 'm': { - CONSOLE_SCREEN_BUFFER_INFO screen_buffer; - GetConsoleScreenBufferInfo(console, &screen_buffer); - WORD attributes = screen_buffer.wAttributes; - for (int i = 0 ; i < argc ; ++i) { - int major = argv[i] / 10, minor = argv[i] % 10; - if (argv[i] == 0) { // reset - attributes = original_attributes; - } else if (argv[i] == 1) { // bold - attributes |= FOREGROUND_INTENSITY; - } else if (argv[i] == 7) { // reverse - #if BACKGROUND_RED != FOREGROUND_RED << 4 - #error Color codes are not what I expected them to be - #endif - attributes = (attributes & (FOREGROUND_COLOR | FOREGROUND_INTENSITY)) << 4 - | (attributes & (BACKGROUND_COLOR | BACKGROUND_INTENSITY)) >> 4; - } else if (argv[i] == 21 || argv[i] == 22) { // not bold - attributes &= ~FOREGROUND_INTENSITY; - } else if (major == 3) { - // foreground color - attributes &= ~FOREGROUND_COLOR; - if (minor == 9) { // reset - attributes |= original_attributes & FOREGROUND_COLOR; - } else { - attributes |= (minor & 1 ? FOREGROUND_RED : 0) - | (minor & 2 ? FOREGROUND_GREEN : 0) - | (minor & 4 ? FOREGROUND_BLUE : 0); - } - } else if (major == 4) { - // background color - attributes &= ~BACKGROUND_COLOR; - if (minor == 9) { // reset - attributes |= original_attributes & BACKGROUND_COLOR; - } else { - attributes |= (minor & 1 ? BACKGROUND_RED : 0) - | (minor & 2 ? BACKGROUND_GREEN : 0) - | (minor & 4 ? BACKGROUND_BLUE : 0); - } - } else { - // other, ignore - } - } - if (attributes != screen_buffer.wAttributes) { - SetConsoleTextAttribute(console, attributes); - } - break; - } - default: - break; // unsupported command, ignore - } + switch (command) { + case 'm': { + CONSOLE_SCREEN_BUFFER_INFO screen_buffer; + GetConsoleScreenBufferInfo(console, &screen_buffer); + WORD attributes = screen_buffer.wAttributes; + for (int i = 0 ; i < argc ; ++i) { + int major = argv[i] / 10, minor = argv[i] % 10; + if (argv[i] == 0) { // reset + attributes = original_attributes; + } else if (argv[i] == 1) { // bold + attributes |= FOREGROUND_INTENSITY; + } else if (argv[i] == 7) { // reverse + #if BACKGROUND_RED != FOREGROUND_RED << 4 + #error Color codes are not what I expected them to be + #endif + attributes = (attributes & (FOREGROUND_COLOR | FOREGROUND_INTENSITY)) << 4 + | (attributes & (BACKGROUND_COLOR | BACKGROUND_INTENSITY)) >> 4; + } else if (argv[i] == 21 || argv[i] == 22) { // not bold + attributes &= ~FOREGROUND_INTENSITY; + } else if (major == 3) { + // foreground color + attributes &= ~FOREGROUND_COLOR; + if (minor == 9) { // reset + attributes |= original_attributes & FOREGROUND_COLOR; + } else { + attributes |= (minor & 1 ? FOREGROUND_RED : 0) + | (minor & 2 ? FOREGROUND_GREEN : 0) + | (minor & 4 ? FOREGROUND_BLUE : 0); + } + } else if (major == 4) { + // background color + attributes &= ~BACKGROUND_COLOR; + if (minor == 9) { // reset + attributes |= original_attributes & BACKGROUND_COLOR; + } else { + attributes |= (minor & 1 ? BACKGROUND_RED : 0) + | (minor & 2 ? BACKGROUND_GREEN : 0) + | (minor & 4 ? BACKGROUND_BLUE : 0); + } + } else { + // other, ignore + } + } + if (attributes != screen_buffer.wAttributes) { + SetConsoleTextAttribute(console, attributes); + } + break; + } + default: + break; // unsupported command, ignore + } } // ----------------------------------------------------------------------------- : EOF diff --git a/src/data/action/generic.hpp b/src/data/action/generic.hpp index 1a2d6bb3..c6799f5f 100644 --- a/src/data/action/generic.hpp +++ b/src/data/action/generic.hpp @@ -25,91 +25,91 @@ enum AddingOrRemoving {ADD, REMOVE}; template class GenericAddAction { public: - GenericAddAction(AddingOrRemoving, const T& item, const vector& container); - GenericAddAction(AddingOrRemoving, const vector& items, const vector& container); - - String getName() const; - void perform(vector& container, bool to_undo) const; - - /// A step of removing/adding - struct Step { - inline Step(size_t pos, const T& item) : pos(pos), item(item) {} - size_t pos; - T item; - }; - bool adding; ///< Were objects added? (as opposed to removed) - vector steps; ///< Added/removed objects, sorted by ascending pos + GenericAddAction(AddingOrRemoving, const T& item, const vector& container); + GenericAddAction(AddingOrRemoving, const vector& items, const vector& container); + + String getName() const; + void perform(vector& container, bool to_undo) const; + + /// A step of removing/adding + struct Step { + inline Step(size_t pos, const T& item) : pos(pos), item(item) {} + size_t pos; + T item; + }; + bool adding; ///< Were objects added? (as opposed to removed) + vector steps; ///< Added/removed objects, sorted by ascending pos }; // ----------------------------------------------------------------------------- : Implementation template bool contains(const vector& items, const T& item) { - return find(items.begin(), items.end(), item) != items.end(); + return find(items.begin(), items.end(), item) != items.end(); } template GenericAddAction::GenericAddAction(AddingOrRemoving ar, const T& item, const vector& container) - : adding(ar == ADD) + : adding(ar == ADD) { - if (ar == ADD) { - size_t pos = container.size(); - steps.push_back(Step(pos, item)); - } else { - for (size_t pos = 0 ; pos < container.size() ; ++pos) { - if (container[pos] == item) { - steps.push_back(Step(pos, item)); - return; - } - } - throw InternalError(_("Item to remove not found in container")); - } + if (ar == ADD) { + size_t pos = container.size(); + steps.push_back(Step(pos, item)); + } else { + for (size_t pos = 0 ; pos < container.size() ; ++pos) { + if (container[pos] == item) { + steps.push_back(Step(pos, item)); + return; + } + } + throw InternalError(_("Item to remove not found in container")); + } } template GenericAddAction::GenericAddAction(AddingOrRemoving ar, const vector& items, const vector& container) - : adding(ar == ADD) + : adding(ar == ADD) { - if (ar == ADD) { - size_t pos = container.size(); - for (typename vector::const_iterator it = items.begin() ; it != items.end() ; ++it) { - steps.push_back(Step(pos++, *it)); - } - } else { - for (size_t pos = 0 ; pos < container.size() ; ++pos) { - if (contains(items, container[pos])) { - steps.push_back(Step(pos, container[pos])); - } - } - if (steps.size() != items.size()) { - throw InternalError(_("Item to remove not found in container")); - } - } + if (ar == ADD) { + size_t pos = container.size(); + for (typename vector::const_iterator it = items.begin() ; it != items.end() ; ++it) { + steps.push_back(Step(pos++, *it)); + } + } else { + for (size_t pos = 0 ; pos < container.size() ; ++pos) { + if (contains(items, container[pos])) { + steps.push_back(Step(pos, container[pos])); + } + } + if (steps.size() != items.size()) { + throw InternalError(_("Item to remove not found in container")); + } + } } template String GenericAddAction::getName() const { - String type = type_name(steps.front().item) + (steps.size() == 1 ? _("") : _("s")); - return adding ? _ACTION_1_("add item", type) : _ACTION_1_("remove item", type); + String type = type_name(steps.front().item) + (steps.size() == 1 ? _("") : _("s")); + return adding ? _ACTION_1_("add item", type) : _ACTION_1_("remove item", type); } template void GenericAddAction::perform(vector& container, bool to_undo) const { - if (adding != to_undo) { - // (re)insert the items - // ascending order, this is the reverse of removal - FOR_EACH_CONST(s, steps) { - assert(s.pos <= container.size()); - container.insert(container.begin() + s.pos, s.item); - } - } else { - // remove the items - // descending order, because earlier removals shift the rest of the vector - FOR_EACH_CONST_REVERSE(s, steps) { - assert(s.pos < container.size()); - container.erase(container.begin() + s.pos); - } - } + if (adding != to_undo) { + // (re)insert the items + // ascending order, this is the reverse of removal + FOR_EACH_CONST(s, steps) { + assert(s.pos <= container.size()); + container.insert(container.begin() + s.pos, s.item); + } + } else { + // remove the items + // descending order, because earlier removals shift the rest of the vector + FOR_EACH_CONST_REVERSE(s, steps) { + assert(s.pos < container.size()); + container.erase(container.begin() + s.pos); + } + } } // ----------------------------------------------------------------------------- : EOF diff --git a/src/data/action/keyword.cpp b/src/data/action/keyword.cpp index f45e694a..9775fe6c 100644 --- a/src/data/action/keyword.cpp +++ b/src/data/action/keyword.cpp @@ -20,191 +20,191 @@ DECLARE_TYPEOF_COLLECTION(KeywordModeP); // ----------------------------------------------------------------------------- : Add Keyword AddKeywordAction::AddKeywordAction(Set& set) - : KeywordListAction(set) - , action(ADD, intrusive(new Keyword()), set.keywords) + : KeywordListAction(set) + , action(ADD, intrusive(new Keyword()), set.keywords) { - Keyword& keyword = *action.steps.front().item; - // find default mode - FOR_EACH(mode, set.game->keyword_modes) { - if (mode->is_default) { - keyword.mode = mode->name; - break; - } - } + Keyword& keyword = *action.steps.front().item; + // find default mode + FOR_EACH(mode, set.game->keyword_modes) { + if (mode->is_default) { + keyword.mode = mode->name; + break; + } + } } AddKeywordAction::AddKeywordAction(AddingOrRemoving ar, Set& set, const KeywordP& keyword) - : KeywordListAction(set) - , action(ar, keyword, set.keywords) + : KeywordListAction(set) + , action(ar, keyword, set.keywords) {} /*AddKeywordAction::AddKeywordAction(AddingOrRemoving ar, Set& set, const vector& keyword) - : KeywordListAction(set) - , action(ar, keywords, set.keywords) + : KeywordListAction(set) + , action(ar, keywords, set.keywords) {}*/ String AddKeywordAction::getName(bool to_undo) const { - return action.getName(); + return action.getName(); } void AddKeywordAction::perform(bool to_undo) { - action.perform(set.keywords, to_undo); - set.keyword_db.clear(); + action.perform(set.keywords, to_undo); + set.keyword_db.clear(); } // ----------------------------------------------------------------------------- : Changing keywords KeywordReminderTextValue::KeywordReminderTextValue(Set& set, const TextFieldP& field, Keyword* keyword, bool editable) - : KeywordTextValue(field, keyword, &keyword->reminder.getMutableUnparsed(), editable) - , set(set) - , keyword(*keyword) + : KeywordTextValue(field, keyword, &keyword->reminder.getMutableUnparsed(), editable) + , set(set) + , keyword(*keyword) {} void KeywordReminderTextValue::store() { - if (!editable) { - retrieve(); - return; - } - // new value - String new_value = untag(value); - // Try to parse the script - vector parse_errors; - ScriptP new_script = parse(new_value, nullptr, true, parse_errors); - if (parse_errors.empty()) { - // parsed okay - if (checkScript(new_script)) { - // also runs okay, assign - keyword.reminder.setScriptP(new_script); - keyword.reminder.setUnparsed(new_value); - } - } else { - // parse errors, report - errors = ScriptParseErrors(parse_errors).what(); - } - // re-highlight input, show errors - highlight(new_value, parse_errors); + if (!editable) { + retrieve(); + return; + } + // new value + String new_value = untag(value); + // Try to parse the script + vector parse_errors; + ScriptP new_script = parse(new_value, nullptr, true, parse_errors); + if (parse_errors.empty()) { + // parsed okay + if (checkScript(new_script)) { + // also runs okay, assign + keyword.reminder.setScriptP(new_script); + keyword.reminder.setUnparsed(new_value); + } + } else { + // parse errors, report + errors = ScriptParseErrors(parse_errors).what(); + } + // re-highlight input, show errors + highlight(new_value, parse_errors); } void KeywordReminderTextValue::retrieve() { - vector no_errors; - highlight(*underlying, no_errors); + vector no_errors; + highlight(*underlying, no_errors); } void KeywordReminderTextValue::highlight(const String& code, const vector& errors) { - // Add tags to indicate code / syntax highlight - // i.e. bla {if code "x" } bla - // becomes: - // bla {if code "x" } bla - String new_value; - vector in_brace; // types of braces we are in, 0 for code brace, 1 for string escapes - bool in_string = true; - vector::const_iterator error = errors.begin(); - for (size_t pos = 0 ; pos < code.size() ; ) { - // error underlining - while (error != errors.end() && error->start == error->end) ++error; - if (error != errors.end()) { - if (error->start == pos) { - new_value += _(""); - } - if (error->end == pos) { - ++error; - if (error == errors.end() || error->start > pos) { - new_value += _(""); - } else { - // immediatly open again - } - } - } - // process a character - Char c = code.GetChar(pos); - if (c == _('<')) { - new_value += _('\1'); // escape - ++pos; - } else if (c == _('{')) { - if (in_string) { - new_value += _(""); - in_brace.push_back(1); - in_string = false; - } else { - in_brace.push_back(0); - } - new_value += c; - ++pos; - } else if (c == _('}') && !in_string) { - new_value += c; - if (!in_brace.empty() && in_brace.back() == 1) { - new_value += _(""); - in_string = true; - } - if (!in_brace.empty()) in_brace.pop_back(); - ++pos; - } else if (c == _('"')) { - if (in_string) { - in_string = false; - new_value += _("\""); - } else { - in_string = true; - new_value += _("\""); - } - ++pos; - } else if (c == _('\\') && in_string && pos + 1 < code.size()) { - new_value += c + code.GetChar(pos + 1); // escape code - pos += 2; - } else if (is_substr(code, pos, _("if ")) && !in_string) { - new_value += _("if "); - pos += 3; - } else if (is_substr(code, pos, _("then ")) && !in_string) { - new_value += _("then "); - pos += 5; - } else if (is_substr(code, pos, _("else ")) && !in_string) { - new_value += _("else "); - pos += 5; - } else if (is_substr(code, pos, _("for ")) && !in_string) { - new_value += _("for "); - pos += 4; - } else if (is_substr(code, pos, _("param")) && !in_string) { - // parameter reference - size_t end = code.find_first_not_of(_("0123456789"), pos + 5); - if (end == String::npos) end = code.size(); - String param = code.substr(pos, end-pos); - new_value += _("") + param + _(""); - pos = end; - } else { - new_value += c; - ++pos; - } - } - // set - value = new_value; + // Add tags to indicate code / syntax highlight + // i.e. bla {if code "x" } bla + // becomes: + // bla {if code "x" } bla + String new_value; + vector in_brace; // types of braces we are in, 0 for code brace, 1 for string escapes + bool in_string = true; + vector::const_iterator error = errors.begin(); + for (size_t pos = 0 ; pos < code.size() ; ) { + // error underlining + while (error != errors.end() && error->start == error->end) ++error; + if (error != errors.end()) { + if (error->start == pos) { + new_value += _(""); + } + if (error->end == pos) { + ++error; + if (error == errors.end() || error->start > pos) { + new_value += _(""); + } else { + // immediatly open again + } + } + } + // process a character + Char c = code.GetChar(pos); + if (c == _('<')) { + new_value += _('\1'); // escape + ++pos; + } else if (c == _('{')) { + if (in_string) { + new_value += _(""); + in_brace.push_back(1); + in_string = false; + } else { + in_brace.push_back(0); + } + new_value += c; + ++pos; + } else if (c == _('}') && !in_string) { + new_value += c; + if (!in_brace.empty() && in_brace.back() == 1) { + new_value += _(""); + in_string = true; + } + if (!in_brace.empty()) in_brace.pop_back(); + ++pos; + } else if (c == _('"')) { + if (in_string) { + in_string = false; + new_value += _("\""); + } else { + in_string = true; + new_value += _("\""); + } + ++pos; + } else if (c == _('\\') && in_string && pos + 1 < code.size()) { + new_value += c + code.GetChar(pos + 1); // escape code + pos += 2; + } else if (is_substr(code, pos, _("if ")) && !in_string) { + new_value += _("if "); + pos += 3; + } else if (is_substr(code, pos, _("then ")) && !in_string) { + new_value += _("then "); + pos += 5; + } else if (is_substr(code, pos, _("else ")) && !in_string) { + new_value += _("else "); + pos += 5; + } else if (is_substr(code, pos, _("for ")) && !in_string) { + new_value += _("for "); + pos += 4; + } else if (is_substr(code, pos, _("param")) && !in_string) { + // parameter reference + size_t end = code.find_first_not_of(_("0123456789"), pos + 5); + if (end == String::npos) end = code.size(); + String param = code.substr(pos, end-pos); + new_value += _("") + param + _(""); + pos = end; + } else { + new_value += c; + ++pos; + } + } + // set + value = new_value; } bool KeywordReminderTextValue::checkScript(const ScriptP& script) { - try { - Context& ctx = set.cards.empty() ? set.getContext() : set.getContext(set.cards.front()); - LocalScope scope(ctx); - for (size_t i = 0 ; i < keyword.parameters.size() ; ++i) { - const KeywordParam& kwp = *keyword.parameters[i]; - String param_name = String(_("param")) << (int)(i+1); - String param_value = _("") + (kwp.placeholder.empty() ? kwp.name : kwp.placeholder) + _(""); - ctx.setVariable(param_name, intrusive(new KeywordParamValue(kwp.name, _(""), _(""), param_value))); - } - script->eval(ctx); - errors.clear(); - return true; - } catch (const Error& e) { - errors = e.what(); - return false; - } + try { + Context& ctx = set.cards.empty() ? set.getContext() : set.getContext(set.cards.front()); + LocalScope scope(ctx); + for (size_t i = 0 ; i < keyword.parameters.size() ; ++i) { + const KeywordParam& kwp = *keyword.parameters[i]; + String param_name = String(_("param")) << (int)(i+1); + String param_value = _("") + (kwp.placeholder.empty() ? kwp.name : kwp.placeholder) + _(""); + ctx.setVariable(param_name, intrusive(new KeywordParamValue(kwp.name, _(""), _(""), param_value))); + } + script->eval(ctx); + errors.clear(); + return true; + } catch (const Error& e) { + errors = e.what(); + return false; + } } // ----------------------------------------------------------------------------- : Changing keywords : mode ChangeKeywordModeAction::ChangeKeywordModeAction(Keyword& keyword, const String& new_mode) - : keyword(keyword), mode(new_mode) + : keyword(keyword), mode(new_mode) {} String ChangeKeywordModeAction::getName(bool to_undo) const { - return _("Keyword mode"); + return _("Keyword mode"); } void ChangeKeywordModeAction::perform(bool to_undo) { - swap(keyword.mode, mode); + swap(keyword.mode, mode); } diff --git a/src/data/action/keyword.hpp b/src/data/action/keyword.hpp index 960a1c06..c555d74e 100644 --- a/src/data/action/keyword.hpp +++ b/src/data/action/keyword.hpp @@ -29,23 +29,23 @@ DECLARE_TYPEOF_COLLECTION(GenericAddAction::Step); /// An Action the changes the keyword list of a set class KeywordListAction : public Action { public: - inline KeywordListAction(Set& set) : set(set) {} - + inline KeywordListAction(Set& set) : set(set) {} + protected: - Set& set; // the set owns this action, so the set will not be destroyed before this - // therefore we don't need a smart pointer + Set& set; // the set owns this action, so the set will not be destroyed before this + // therefore we don't need a smart pointer }; /// Adding or removing a keyword from a set class AddKeywordAction : public KeywordListAction { public: - AddKeywordAction(Set& set); - AddKeywordAction(AddingOrRemoving, Set& set, const KeywordP& keyword); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - - const GenericAddAction action; + AddKeywordAction(Set& set); + AddKeywordAction(AddingOrRemoving, Set& set, const KeywordP& keyword); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + + const GenericAddAction action; }; // ----------------------------------------------------------------------------- : Changing keywords @@ -59,46 +59,46 @@ class AddKeywordAction : public KeywordListAction { */ class KeywordTextValue : public FakeTextValue { public: - KeywordTextValue(const TextFieldP& field, Keyword* keyword, String* underlying, bool editable, bool untagged = false) - : FakeTextValue(field, underlying, editable, untagged) - , keyword(*keyword) - {} - - Keyword& keyword; ///< The keyword that is being edited + KeywordTextValue(const TextFieldP& field, Keyword* keyword, String* underlying, bool editable, bool untagged = false) + : FakeTextValue(field, underlying, editable, untagged) + , keyword(*keyword) + {} + + Keyword& keyword; ///< The keyword that is being edited }; /// A FakeTextValue that is used to edit reminder text scripts class KeywordReminderTextValue : public KeywordTextValue { public: - KeywordReminderTextValue(Set& set, const TextFieldP& field, Keyword* keyword, bool editable); - - String errors; ///< Errors in the script - Set& set; ///< Set this keyword is in (for script checking) - Keyword& keyword; ///< The keyword we are the reminder text of - - /// Try to compile the script - virtual void store(); - /// Add some tags, so the script looks nice - virtual void retrieve(); - - /// Syntax highlight, and store in value - void highlight(const String& code, const vector& errors); - - /// Check the script for errors - bool checkScript(const ScriptP& script); + KeywordReminderTextValue(Set& set, const TextFieldP& field, Keyword* keyword, bool editable); + + String errors; ///< Errors in the script + Set& set; ///< Set this keyword is in (for script checking) + Keyword& keyword; ///< The keyword we are the reminder text of + + /// Try to compile the script + virtual void store(); + /// Add some tags, so the script looks nice + virtual void retrieve(); + + /// Syntax highlight, and store in value + void highlight(const String& code, const vector& errors); + + /// Check the script for errors + bool checkScript(const ScriptP& script); }; /// Changing the mode of a keyword class ChangeKeywordModeAction : public Action { public: - ChangeKeywordModeAction(Keyword& keyword, const String& new_mode); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - + ChangeKeywordModeAction(Keyword& keyword, const String& new_mode); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + //private: - Keyword& keyword; - String mode; + Keyword& keyword; + String mode; }; // ----------------------------------------------------------------------------- : EOF diff --git a/src/data/action/set.cpp b/src/data/action/set.cpp index 86399b9e..0b6fc741 100644 --- a/src/data/action/set.cpp +++ b/src/data/action/set.cpp @@ -22,147 +22,147 @@ DECLARE_TYPEOF_COLLECTION(int); // ----------------------------------------------------------------------------- : Add card AddCardAction::AddCardAction(Set& set) - : CardListAction(set) - , action(ADD, intrusive(new Card(*set.game)), set.cards) + : CardListAction(set) + , action(ADD, intrusive(new Card(*set.game)), set.cards) {} AddCardAction::AddCardAction(AddingOrRemoving ar, Set& set, const CardP& card) - : CardListAction(set) - , action(ar, card, set.cards) + : CardListAction(set) + , action(ar, card, set.cards) {} AddCardAction::AddCardAction(AddingOrRemoving ar, Set& set, const vector& cards) - : CardListAction(set) - , action(ar, cards, set.cards) + : CardListAction(set) + , action(ar, cards, set.cards) {} String AddCardAction::getName(bool to_undo) const { - return action.getName(); + return action.getName(); } void AddCardAction::perform(bool to_undo) { - action.perform(set.cards, to_undo); + action.perform(set.cards, to_undo); } // ----------------------------------------------------------------------------- : Reorder cards ReorderCardsAction::ReorderCardsAction(Set& set, size_t card_id1, size_t card_id2) - : CardListAction(set), card_id1(card_id1), card_id2(card_id2) + : CardListAction(set), card_id1(card_id1), card_id2(card_id2) {} String ReorderCardsAction::getName(bool to_undo) const { - return _("Reorder cards"); + return _("Reorder cards"); } void ReorderCardsAction::perform(bool to_undo) { - #ifdef _DEBUG - assert(card_id1 < set.cards.size()); - assert(card_id2 < set.cards.size()); - #endif - if (card_id1 >= set.cards.size() || card_id2 < set.cards.size()) { - // TODO : Too lazy to fix this right now. - return; - } - swap(set.cards[card_id1], set.cards[card_id2]); + #ifdef _DEBUG + assert(card_id1 < set.cards.size()); + assert(card_id2 < set.cards.size()); + #endif + if (card_id1 >= set.cards.size() || card_id2 < set.cards.size()) { + // TODO : Too lazy to fix this right now. + return; + } + swap(set.cards[card_id1], set.cards[card_id2]); } // ----------------------------------------------------------------------------- : Change stylesheet String DisplayChangeAction::getName(bool to_undo) const { - assert(false); - return _(""); + assert(false); + return _(""); } void DisplayChangeAction::perform(bool to_undo) { - assert(false); + assert(false); } ChangeCardStyleAction::ChangeCardStyleAction(const CardP& card, const StyleSheetP& stylesheet) - : card(card), stylesheet(stylesheet), has_styling(false) // styling_data(empty) + : card(card), stylesheet(stylesheet), has_styling(false) // styling_data(empty) {} String ChangeCardStyleAction::getName(bool to_undo) const { - return _("Change style"); + return _("Change style"); } void ChangeCardStyleAction::perform(bool to_undo) { - swap(card->stylesheet, stylesheet); - swap(card->has_styling, has_styling); - swap(card->styling_data, styling_data); + swap(card->stylesheet, stylesheet); + swap(card->has_styling, has_styling); + swap(card->styling_data, styling_data); } ChangeSetStyleAction::ChangeSetStyleAction(Set& set, const CardP& card) - : set(set), card(card) + : set(set), card(card) {} String ChangeSetStyleAction::getName(bool to_undo) const { - return _("Change style (all cards)"); + return _("Change style (all cards)"); } void ChangeSetStyleAction::perform(bool to_undo) { - if (!to_undo) { - // backup has_styling - has_styling.clear(); - FOR_EACH(card, set.cards) { - has_styling.push_back(card->has_styling); - if (!card->stylesheet) { - card->has_styling = false; // this card has custom style options for the default stylesheet - } - } - stylesheet = set.stylesheet; - set.stylesheet = card->stylesheet; - card->stylesheet = StyleSheetP(); - } else { - card->stylesheet = set.stylesheet; - set.stylesheet = stylesheet; - // restore has_styling - FOR_EACH_2(card, set.cards, has, has_styling) { - card->has_styling = has; - } - } + if (!to_undo) { + // backup has_styling + has_styling.clear(); + FOR_EACH(card, set.cards) { + has_styling.push_back(card->has_styling); + if (!card->stylesheet) { + card->has_styling = false; // this card has custom style options for the default stylesheet + } + } + stylesheet = set.stylesheet; + set.stylesheet = card->stylesheet; + card->stylesheet = StyleSheetP(); + } else { + card->stylesheet = set.stylesheet; + set.stylesheet = stylesheet; + // restore has_styling + FOR_EACH_2(card, set.cards, has, has_styling) { + card->has_styling = has; + } + } } ChangeCardHasStylingAction::ChangeCardHasStylingAction(Set& set, const CardP& card) - : set(set), card(card) + : set(set), card(card) { - if (!card->has_styling) { - // copy of the set's styling data - styling_data.cloneFrom( set.stylingDataFor(set.stylesheetFor(card)) ); - } else { - // the new styling data is empty - } + if (!card->has_styling) { + // copy of the set's styling data + styling_data.cloneFrom( set.stylingDataFor(set.stylesheetFor(card)) ); + } else { + // the new styling data is empty + } } String ChangeCardHasStylingAction::getName(bool to_undo) const { - return _("Use custom style"); + return _("Use custom style"); } void ChangeCardHasStylingAction::perform(bool to_undo) { - card->has_styling = !card->has_styling; - swap(card->styling_data, styling_data); + card->has_styling = !card->has_styling; + swap(card->styling_data, styling_data); } // ----------------------------------------------------------------------------- : Pack types AddPackAction::AddPackAction(AddingOrRemoving ar, Set& set, const PackTypeP& pack) - : PackTypesAction(set) - , action(ar, pack, set.pack_types) + : PackTypesAction(set) + , action(ar, pack, set.pack_types) {} String AddPackAction::getName(bool to_undo) const { - return action.getName(); + return action.getName(); } void AddPackAction::perform(bool to_undo) { - action.perform(set.pack_types, to_undo); + action.perform(set.pack_types, to_undo); } ChangePackAction::ChangePackAction(Set& set, size_t pos, const PackTypeP& pack) - : PackTypesAction(set) - , pack(pack), pos(pos) + : PackTypesAction(set) + , pack(pack), pos(pos) {} String ChangePackAction::getName(bool to_undo) const { - return _ACTION_1_("change",type_name(pack)); + return _ACTION_1_("change",type_name(pack)); } void ChangePackAction::perform(bool to_undo) { - swap(set.pack_types.at(pos), pack); + swap(set.pack_types.at(pos), pack); } diff --git a/src/data/action/set.hpp b/src/data/action/set.hpp index ddc101c8..44e1d23d 100644 --- a/src/data/action/set.hpp +++ b/src/data/action/set.hpp @@ -32,25 +32,25 @@ DECLARE_TYPEOF_COLLECTION(GenericAddAction::Step); /// An Action the changes the card list of a set class CardListAction : public Action { public: - inline CardListAction(Set& set) : set(set) {} - + inline CardListAction(Set& set) : set(set) {} + protected: - Set& set; // the set owns this action, so the set will not be destroyed before this - // therefore we don't need a smart pointer + Set& set; // the set owns this action, so the set will not be destroyed before this + // therefore we don't need a smart pointer }; /// Adding a new card to a set class AddCardAction : public CardListAction { public: - /// Add a newly allocated card - AddCardAction(Set& set); - AddCardAction(AddingOrRemoving, Set& set, const CardP& card); - AddCardAction(AddingOrRemoving, Set& set, const vector& cards); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - - const GenericAddAction action; + /// Add a newly allocated card + AddCardAction(Set& set); + AddCardAction(AddingOrRemoving, Set& set, const CardP& card); + AddCardAction(AddingOrRemoving, Set& set, const vector& cards); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + + const GenericAddAction action; }; // ----------------------------------------------------------------------------- : Reorder cards @@ -58,13 +58,13 @@ class AddCardAction : public CardListAction { /// Change the position of a card in the card list by swapping two cards class ReorderCardsAction : public CardListAction { public: - ReorderCardsAction(Set& set, size_t card_id1, size_t card_id2); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - + ReorderCardsAction(Set& set, size_t card_id1, size_t card_id2); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + //private: - const size_t card_id1, card_id2; ///< Positions of the two cards to swap + const size_t card_id1, card_id2; ///< Positions of the two cards to swap }; // ----------------------------------------------------------------------------- : Change stylesheet @@ -72,53 +72,53 @@ class ReorderCardsAction : public CardListAction { /// An action that affects the rendering/display/look of a set or cards in the set class DisplayChangeAction : public Action { public: - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); }; /// Changing the style of a a card class ChangeCardStyleAction : public DisplayChangeAction { public: - ChangeCardStyleAction(const CardP& card, const StyleSheetP& stylesheet); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - + ChangeCardStyleAction(const CardP& card, const StyleSheetP& stylesheet); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + //private: - CardP card; ///< The affected card - StyleSheetP stylesheet; ///< Its old stylesheet - bool has_styling; ///< Its old has_styling - IndexMap styling_data; ///< Its old styling data + CardP card; ///< The affected card + StyleSheetP stylesheet; ///< Its old stylesheet + bool has_styling; ///< Its old has_styling + IndexMap styling_data; ///< Its old styling data }; /// Changing the style of a set to that of a card class ChangeSetStyleAction : public DisplayChangeAction { public: - ChangeSetStyleAction(Set& set, const CardP& card); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - + ChangeSetStyleAction(Set& set, const CardP& card); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + private: - Set& set; ///< The affected set - CardP card; ///< The card whos stylesheet is copied to the set - StyleSheetP stylesheet; ///< The old stylesheet of the set - vector has_styling; ///< The old has_styling values of all cards (vector is evil) + Set& set; ///< The affected set + CardP card; ///< The card whos stylesheet is copied to the set + StyleSheetP stylesheet; ///< The old stylesheet of the set + vector has_styling; ///< The old has_styling values of all cards (vector is evil) }; /// Changing the styling of a card to become custom/non-custom /** i.e. toggle card->has_styling */ class ChangeCardHasStylingAction : public DisplayChangeAction { public: - ChangeCardHasStylingAction(Set& set, const CardP& card); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - + ChangeCardHasStylingAction(Set& set, const CardP& card); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + //private: - Set& set; ///< The set to copy styling from - CardP card; ///< The affected card - IndexMap styling_data; ///< The old styling of the card + Set& set; ///< The set to copy styling from + CardP card; ///< The affected card + IndexMap styling_data; ///< The old styling of the card }; // ----------------------------------------------------------------------------- : Pack types @@ -126,37 +126,37 @@ class ChangeCardHasStylingAction : public DisplayChangeAction { /// An Action the changes the pack types of a set class PackTypesAction : public Action { public: - inline PackTypesAction(Set& set) : set(set) {} - + inline PackTypesAction(Set& set) : set(set) {} + protected: - Set& set; // the set owns this action, so the set will not be destroyed before this - // therefore we don't need a smart pointer + Set& set; // the set owns this action, so the set will not be destroyed before this + // therefore we don't need a smart pointer }; /// Adding/removing a pack from a Set class AddPackAction : public PackTypesAction { public: - /// Add a newly allocated card - AddPackAction(AddingOrRemoving, Set& set, const PackTypeP& pack); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - - const GenericAddAction action; + /// Add a newly allocated card + AddPackAction(AddingOrRemoving, Set& set, const PackTypeP& pack); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + + const GenericAddAction action; }; /// Updating a pack in a Set class ChangePackAction : public PackTypesAction { public: - /// Add a newly allocated card - ChangePackAction(Set& set, size_t pos, const PackTypeP& new_pack); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - + /// Add a newly allocated card + ChangePackAction(Set& set, size_t pos, const PackTypeP& new_pack); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + private: - PackTypeP pack; - size_t pos; + PackTypeP pack; + size_t pos; }; // ----------------------------------------------------------------------------- : EOF diff --git a/src/data/action/symbol.cpp b/src/data/action/symbol.cpp index b4b48324..b991c933 100644 --- a/src/data/action/symbol.cpp +++ b/src/data/action/symbol.cpp @@ -20,173 +20,173 @@ DECLARE_TYPEOF_COLLECTION(ControlPointP); // ----------------------------------------------------------------------------- : Utility String action_name_for(const set& parts, const String& action) { - return format_string(action, parts.size() == 1 ? (*parts.begin())->name : _TYPE_("shapes")); + return format_string(action, parts.size() == 1 ? (*parts.begin())->name : _TYPE_("shapes")); } SymbolPartsAction::SymbolPartsAction(const set& parts) - : parts(parts) + : parts(parts) {} // ----------------------------------------------------------------------------- : Moving symbol parts SymbolPartMoveAction::SymbolPartMoveAction(const set& parts, const Vector2D& delta) - : SymbolPartsAction(parts) - , delta(delta), moved(-delta) - , constrain(false) - , snap(0) + : SymbolPartsAction(parts) + , delta(delta), moved(-delta) + , constrain(false) + , snap(0) { - // Determine min/max_pos - FOR_EACH(p, parts) { - bounds.update(p->bounds); - } + // Determine min/max_pos + FOR_EACH(p, parts) { + bounds.update(p->bounds); + } } String SymbolPartMoveAction::getName(bool to_undo) const { - return action_name_for(parts, _ACTION_("move")); + return action_name_for(parts, _ACTION_("move")); } void SymbolPartMoveAction::perform(bool to_undo) { - // move the points back - FOR_EACH(p, parts) { - movePart(*p); - } - moved = -moved; + // move the points back + FOR_EACH(p, parts) { + movePart(*p); + } + moved = -moved; } void SymbolPartMoveAction::movePart(SymbolPart& part) { - part.bounds.min -= moved; - part.bounds.max -= moved; - if (SymbolShape* s = part.isSymbolShape()) { - FOR_EACH(pnt, s->points) { - pnt->pos -= moved; - } - } else if (SymbolSymmetry* s = part.isSymbolSymmetry()) { - s->center -= moved; - } - if (SymbolGroup* g = part.isSymbolGroup()) { - FOR_EACH(p, g->parts) { - movePart(*p); - } - } + part.bounds.min -= moved; + part.bounds.max -= moved; + if (SymbolShape* s = part.isSymbolShape()) { + FOR_EACH(pnt, s->points) { + pnt->pos -= moved; + } + } else if (SymbolSymmetry* s = part.isSymbolSymmetry()) { + s->center -= moved; + } + if (SymbolGroup* g = part.isSymbolGroup()) { + FOR_EACH(p, g->parts) { + movePart(*p); + } + } } void SymbolPartMoveAction::move(const Vector2D& deltaDelta) { - delta += deltaDelta; - // Determine actual delta, possibly constrained and snapped - Vector2D d = constrain_snap_vector_offset(bounds.min, bounds.max, delta, constrain, snap); - Vector2D dd = d - moved; // move this much more - // Move each point by d - moved = -dd; - perform(false); // (ab)use perform to move by +dd - moved = d; + delta += deltaDelta; + // Determine actual delta, possibly constrained and snapped + Vector2D d = constrain_snap_vector_offset(bounds.min, bounds.max, delta, constrain, snap); + Vector2D dd = d - moved; // move this much more + // Move each point by d + moved = -dd; + perform(false); // (ab)use perform to move by +dd + moved = d; } // ----------------------------------------------------------------------------- : Rotating symbol parts SymbolPartMatrixAction::SymbolPartMatrixAction(const set& parts, const Vector2D& center) - : SymbolPartsAction(parts) - , center(center) + : SymbolPartsAction(parts) + , center(center) {} void SymbolPartMatrixAction::transform(const Matrix2D& m) { - // Transform each part - FOR_EACH(p, parts) { - transform(*p, m); - p->updateBounds(); - } + // Transform each part + FOR_EACH(p, parts) { + transform(*p, m); + p->updateBounds(); + } } void SymbolPartMatrixAction::transform(SymbolPart& part, const Matrix2D& m) { - if (SymbolShape* s = part.isSymbolShape()) { - FOR_EACH(pnt, s->points) { - pnt->pos = ((pnt->pos - center) * m) + center; - pnt->delta_before = pnt->delta_before * m; - pnt->delta_after = pnt->delta_after * m; - } - } else if (SymbolSymmetry* s = part.isSymbolSymmetry()) { - s->center = (s->center - center) * m + center; - s->handle = s->handle * m; - } - if (SymbolGroup* g = part.isSymbolGroup()) { - FOR_EACH(p, g->parts) { - transform(*p, m); - } - } + if (SymbolShape* s = part.isSymbolShape()) { + FOR_EACH(pnt, s->points) { + pnt->pos = ((pnt->pos - center) * m) + center; + pnt->delta_before = pnt->delta_before * m; + pnt->delta_after = pnt->delta_after * m; + } + } else if (SymbolSymmetry* s = part.isSymbolSymmetry()) { + s->center = (s->center - center) * m + center; + s->handle = s->handle * m; + } + if (SymbolGroup* g = part.isSymbolGroup()) { + FOR_EACH(p, g->parts) { + transform(*p, m); + } + } } SymbolPartRotateAction::SymbolPartRotateAction(const set& parts, const Vector2D& center) - : SymbolPartMatrixAction(parts, center) - , angle(0) - , constrain(false) + : SymbolPartMatrixAction(parts, center) + , angle(0) + , constrain(false) {} String SymbolPartRotateAction::getName(bool to_undo) const { - return action_name_for(parts, _ACTION_("rotate")); + return action_name_for(parts, _ACTION_("rotate")); } void SymbolPartRotateAction::perform(bool to_undo) { - // move the points back - rotateBy(-angle); - angle = -angle; + // move the points back + rotateBy(-angle); + angle = -angle; } void SymbolPartRotateAction::rotateTo(Radians newAngle) { - Radians oldAngle = angle; - angle = newAngle; - // constrain? - if (constrain) { - // multiples of 2pi/24 i.e. 24 stops - double mult = (2 * M_PI) / 24; - angle = floor(angle / mult + 0.5) * mult; - } - if (oldAngle != angle) rotateBy(angle - oldAngle); + Radians oldAngle = angle; + angle = newAngle; + // constrain? + if (constrain) { + // multiples of 2pi/24 i.e. 24 stops + double mult = (2 * M_PI) / 24; + angle = floor(angle / mult + 0.5) * mult; + } + if (oldAngle != angle) rotateBy(angle - oldAngle); } void SymbolPartRotateAction::rotateBy(Radians deltaAngle) { - // Rotation 'matrix' - transform( - Matrix2D(cos(deltaAngle), -sin(deltaAngle) - ,sin(deltaAngle), cos(deltaAngle)) - ); + // Rotation 'matrix' + transform( + Matrix2D(cos(deltaAngle), -sin(deltaAngle) + ,sin(deltaAngle), cos(deltaAngle)) + ); } // ----------------------------------------------------------------------------- : Shearing symbol parts SymbolPartShearAction::SymbolPartShearAction(const set& parts, const Vector2D& center) - : SymbolPartMatrixAction(parts, center) -// , constrain(false) - , snap(0) + : SymbolPartMatrixAction(parts, center) +// , constrain(false) + , snap(0) {} String SymbolPartShearAction::getName(bool to_undo) const { - return action_name_for(parts, _ACTION_("shear")); + return action_name_for(parts, _ACTION_("shear")); } void SymbolPartShearAction::perform(bool to_undo) { - // move the points back - // the vector shear = (x,y) is used as: - // <1 x> - // - // inverse is: - // <1 -x> / - // <-y 1> / (1 - xy) - // we have: xy = 0 => (1 - xy) = 1 - shearBy(-moved); + // move the points back + // the vector shear = (x,y) is used as: + // <1 x> + // + // inverse is: + // <1 -x> / + // <-y 1> / (1 - xy) + // we have: xy = 0 => (1 - xy) = 1 + shearBy(-moved); } void SymbolPartShearAction::move(const Vector2D& deltaShear) { - shear += deltaShear; - Vector2D d = snap_vector(shear - moved, snap); - shearBy(d); - moved += d; + shear += deltaShear; + Vector2D d = snap_vector(shear - moved, snap); + shearBy(d); + moved += d; } void SymbolPartShearAction::shearBy(const Vector2D& shear) { - // Shear 'matrix' - transform( - Matrix2D(1, shear.x - ,shear.y, 1) - ); + // Shear 'matrix' + transform( + Matrix2D(1, shear.x + ,shear.y, 1) + ); } @@ -194,366 +194,366 @@ void SymbolPartShearAction::shearBy(const Vector2D& shear) { SymbolPartScaleAction::SymbolPartScaleAction(const set& parts, int scaleX, int scaleY) - : SymbolPartsAction(parts) - , scaleX(scaleX), scaleY(scaleY) - , constrain(false) - , snap(0) + : SymbolPartsAction(parts) + , scaleX(scaleX), scaleY(scaleY) + , constrain(false) + , snap(0) { - // Find min and max coordinates - Bounds bounds; - FOR_EACH(p, parts) { - bounds.update(p->bounds); - } - // new == old - new_min = new_real_min = old_min = bounds.min; - new_size = new_real_size = old_size = bounds.max - bounds.min; + // Find min and max coordinates + Bounds bounds; + FOR_EACH(p, parts) { + bounds.update(p->bounds); + } + // new == old + new_min = new_real_min = old_min = bounds.min; + new_size = new_real_size = old_size = bounds.max - bounds.min; } String SymbolPartScaleAction::getName(bool to_undo) const { - return action_name_for(parts, _ACTION_("scale")); + return action_name_for(parts, _ACTION_("scale")); } void SymbolPartScaleAction::perform(bool to_undo) { - swap(old_min, new_min); - swap(old_size, new_size); - transformAll(); + swap(old_min, new_min); + swap(old_size, new_size); + transformAll(); } void SymbolPartScaleAction::move(const Vector2D& delta_min, const Vector2D& delta_max) { - new_real_min += delta_min; - new_real_size += delta_max - delta_min; - update(); + new_real_min += delta_min; + new_real_size += delta_max - delta_min; + update(); } void SymbolPartScaleAction::update() { - // Move each point so the range [old_min...old_max] maps to [new_min...new_max] - // we have already moved to the current [new_min...new_max] - Vector2D tmp_min = old_min, tmp_size = old_size; // the size before any scaling - old_min = new_min; old_size = new_size; // the size before this move - // the size after the move - new_min = new_real_min; new_size = new_real_size; - if (constrain && scaleX != 0 && scaleY != 0) { - Vector2D scale = new_size.div(tmp_size); - scale = constrain_vector(scale, true, true); - new_size = tmp_size.mul(scale); - new_min += (new_real_size - new_size).mul(Vector2D(scaleX == -1 ? 1 : 0, scaleY == -1 ? 1 : 0)); - // TODO : snapping - } else if (snap >= 0) { - if (scaleX + scaleY < 0) { - new_min = snap_vector(new_min, snap); - new_size += new_real_min - new_min; - } else { - Vector2D new_max = snap_vector(new_min + new_size, snap); - new_size = new_max - new_min; - } - } - // now move all points - transformAll(); - // restore old_min/size - old_min = tmp_min; old_size = tmp_size; + // Move each point so the range [old_min...old_max] maps to [new_min...new_max] + // we have already moved to the current [new_min...new_max] + Vector2D tmp_min = old_min, tmp_size = old_size; // the size before any scaling + old_min = new_min; old_size = new_size; // the size before this move + // the size after the move + new_min = new_real_min; new_size = new_real_size; + if (constrain && scaleX != 0 && scaleY != 0) { + Vector2D scale = new_size.div(tmp_size); + scale = constrain_vector(scale, true, true); + new_size = tmp_size.mul(scale); + new_min += (new_real_size - new_size).mul(Vector2D(scaleX == -1 ? 1 : 0, scaleY == -1 ? 1 : 0)); + // TODO : snapping + } else if (snap >= 0) { + if (scaleX + scaleY < 0) { + new_min = snap_vector(new_min, snap); + new_size += new_real_min - new_min; + } else { + Vector2D new_max = snap_vector(new_min + new_size, snap); + new_size = new_max - new_min; + } + } + // now move all points + transformAll(); + // restore old_min/size + old_min = tmp_min; old_size = tmp_size; } void SymbolPartScaleAction::transformAll() { - FOR_EACH(p, parts) { - transformPart(*p); - } + FOR_EACH(p, parts) { + transformPart(*p); + } } void SymbolPartScaleAction::transformPart(SymbolPart& part) { - // update bounds - part.bounds.min = transform(part.bounds.min); - part.bounds.max = transform(part.bounds.max); - // make sure that max >= min - if (part.bounds.min.x > part.bounds.max.x) swap(part.bounds.min.x, part.bounds.max.x); - if (part.bounds.min.y > part.bounds.max.y) swap(part.bounds.min.y, part.bounds.max.y); - if (SymbolShape* s = part.isSymbolShape()) { - // scale all points - Vector2D scale = new_size.div(old_size); - FOR_EACH(pnt, s->points) { - pnt->pos = transform(pnt->pos); - // also scale handles - pnt->delta_before = pnt->delta_before.mul(scale); - pnt->delta_after = pnt->delta_after .mul(scale); - } - } else if (SymbolSymmetry* s = part.isSymbolSymmetry()) { - transform(s->center); - s->handle.mul(new_size.div(old_size)); - } - if (SymbolGroup* g = part.isSymbolGroup()) { - FOR_EACH(p, g->parts) { - transformPart(*p); - } - } + // update bounds + part.bounds.min = transform(part.bounds.min); + part.bounds.max = transform(part.bounds.max); + // make sure that max >= min + if (part.bounds.min.x > part.bounds.max.x) swap(part.bounds.min.x, part.bounds.max.x); + if (part.bounds.min.y > part.bounds.max.y) swap(part.bounds.min.y, part.bounds.max.y); + if (SymbolShape* s = part.isSymbolShape()) { + // scale all points + Vector2D scale = new_size.div(old_size); + FOR_EACH(pnt, s->points) { + pnt->pos = transform(pnt->pos); + // also scale handles + pnt->delta_before = pnt->delta_before.mul(scale); + pnt->delta_after = pnt->delta_after .mul(scale); + } + } else if (SymbolSymmetry* s = part.isSymbolSymmetry()) { + transform(s->center); + s->handle.mul(new_size.div(old_size)); + } + if (SymbolGroup* g = part.isSymbolGroup()) { + FOR_EACH(p, g->parts) { + transformPart(*p); + } + } } Vector2D SymbolPartScaleAction::transform(const Vector2D& v) { - // TODO: prevent div by 0 - return (v - old_min).div(old_size).mul(new_size) + new_min; + // TODO: prevent div by 0 + return (v - old_min).div(old_size).mul(new_size) + new_min; } // ----------------------------------------------------------------------------- : Change combine mode CombiningModeAction::CombiningModeAction(const set& parts, SymbolShapeCombine mode) - : SymbolPartsAction(parts) + : SymbolPartsAction(parts) { - FOR_EACH(p, parts) { - add(p,mode); - } + FOR_EACH(p, parts) { + add(p,mode); + } } void CombiningModeAction::add(const SymbolPartP& part, SymbolShapeCombine mode) { - if (part->isSymbolShape()) { - this->parts.push_back(make_pair(static_pointer_cast(part),mode)); - } else if (SymbolGroup* g = part->isSymbolGroup()) { - FOR_EACH(p, g->parts) add(p, mode); - } + if (part->isSymbolShape()) { + this->parts.push_back(make_pair(static_pointer_cast(part),mode)); + } else if (SymbolGroup* g = part->isSymbolGroup()) { + FOR_EACH(p, g->parts) add(p, mode); + } } String CombiningModeAction::getName(bool to_undo) const { - return _ACTION_("change combine mode"); + return _ACTION_("change combine mode"); } void CombiningModeAction::perform(bool to_undo) { - FOR_EACH(pm, parts) { - swap(pm.first->combine, pm.second); - } + FOR_EACH(pm, parts) { + swap(pm.first->combine, pm.second); + } } // ----------------------------------------------------------------------------- : Change name SymbolPartNameAction::SymbolPartNameAction(const SymbolPartP& part, const String& name, size_t old_cursor, size_t new_cursor) - : part(part), part_name(name) - , old_cursor(new_cursor), new_cursor(old_cursor) // will be swapped + : part(part), part_name(name) + , old_cursor(new_cursor), new_cursor(old_cursor) // will be swapped {} String SymbolPartNameAction::getName(bool to_undo) const { - return _ACTION_("change shape name"); + return _ACTION_("change shape name"); } bool SymbolPartNameAction::merge(const Action& action) { - TYPE_CASE(action, SymbolPartNameAction) { - if (action.part == part) { - // adjacent actions on the same part, discard the other one, - // because it only keeps an intermediate value - return true; - } - } - return false; + TYPE_CASE(action, SymbolPartNameAction) { + if (action.part == part) { + // adjacent actions on the same part, discard the other one, + // because it only keeps an intermediate value + return true; + } + } + return false; } void SymbolPartNameAction::perform(bool to_undo) { - swap(part->name, part_name); - swap(old_cursor, new_cursor); + swap(part->name, part_name); + swap(old_cursor, new_cursor); } // ----------------------------------------------------------------------------- : Add symbol part AddSymbolPartAction::AddSymbolPartAction(Symbol& symbol, const SymbolPartP& part) - : symbol(symbol), part(part) + : symbol(symbol), part(part) {} String AddSymbolPartAction::getName(bool to_undo) const { - return _ACTION_1_("add item", part->name); + return _ACTION_1_("add item", part->name); } void AddSymbolPartAction::perform(bool to_undo) { - if (to_undo) { - assert(!symbol.parts.empty()); - symbol.parts.erase (symbol.parts.begin()); - } else { - symbol.parts.insert(symbol.parts.begin(), part); - } + if (to_undo) { + assert(!symbol.parts.empty()); + symbol.parts.erase (symbol.parts.begin()); + } else { + symbol.parts.insert(symbol.parts.begin(), part); + } } // ----------------------------------------------------------------------------- : Remove symbol part RemoveSymbolPartsAction::RemoveSymbolPartsAction(Symbol& symbol, const set& parts) - : symbol(symbol) + : symbol(symbol) { - check(symbol, parts); + check(symbol, parts); } void RemoveSymbolPartsAction::check(SymbolGroup& group, const set& parts) { - size_t index = 0; - size_t removed = 0; - FOR_EACH(p, group.parts) { - if (parts.find(p) != parts.end()) { - removals.push_back(Removal(group, index, p)); // remove this part - ++ removed; - } else if (SymbolGroup* g = p->isSymbolGroup()) { - check(*g, parts); - } - ++index; - } - if (!group.isSymbolSymmetry() && &group != &symbol) { - // remove empty groups - // TODO - } + size_t index = 0; + size_t removed = 0; + FOR_EACH(p, group.parts) { + if (parts.find(p) != parts.end()) { + removals.push_back(Removal(group, index, p)); // remove this part + ++ removed; + } else if (SymbolGroup* g = p->isSymbolGroup()) { + check(*g, parts); + } + ++index; + } + if (!group.isSymbolSymmetry() && &group != &symbol) { + // remove empty groups + // TODO + } } String RemoveSymbolPartsAction::getName(bool to_undo) const { - return _ACTION_1_("remove item", removals.size() == 1 ? _TYPE_("shape") : _TYPE_("shapes")); + return _ACTION_1_("remove item", removals.size() == 1 ? _TYPE_("shape") : _TYPE_("shapes")); } void RemoveSymbolPartsAction::perform(bool to_undo) { - if (to_undo) { - // reinsert the parts - // ascending order, this is the reverse of removal - FOR_EACH(r, removals) { - assert(r.pos <= r.parent->parts.size()); - r.parent->parts.insert(r.parent->parts.begin() + r.pos, r.removed); - } - } else { - // remove the parts - // descending order, because earlier removals shift the rest of the vector - FOR_EACH_REVERSE(r, removals) { - assert(r.pos < r.parent->parts.size()); - r.parent->parts.erase(r.parent->parts.begin() + r.pos); - } - } + if (to_undo) { + // reinsert the parts + // ascending order, this is the reverse of removal + FOR_EACH(r, removals) { + assert(r.pos <= r.parent->parts.size()); + r.parent->parts.insert(r.parent->parts.begin() + r.pos, r.removed); + } + } else { + // remove the parts + // descending order, because earlier removals shift the rest of the vector + FOR_EACH_REVERSE(r, removals) { + assert(r.pos < r.parent->parts.size()); + r.parent->parts.erase(r.parent->parts.begin() + r.pos); + } + } } // ----------------------------------------------------------------------------- : Duplicate symbol parts DuplicateSymbolPartsAction::DuplicateSymbolPartsAction(Symbol& symbol, const set& parts) - : symbol(symbol) + : symbol(symbol) { - UInt index = 0; - FOR_EACH(p, symbol.parts) { - index += 1; - if (parts.find(p) != parts.end()) { - // duplicate this part - duplications.push_back(make_pair(p->clone(), index)); - index += 1; // the clone also takes up space on the vector - } - } + UInt index = 0; + FOR_EACH(p, symbol.parts) { + index += 1; + if (parts.find(p) != parts.end()) { + // duplicate this part + duplications.push_back(make_pair(p->clone(), index)); + index += 1; // the clone also takes up space on the vector + } + } } String DuplicateSymbolPartsAction::getName(bool to_undo) const { - return _ACTION_1_("duplicate", duplications.size() == 1 ? _TYPE_("shape") : _TYPE_("shapes")); + return _ACTION_1_("duplicate", duplications.size() == 1 ? _TYPE_("shape") : _TYPE_("shapes")); } void DuplicateSymbolPartsAction::perform(bool to_undo) { - if (to_undo) { - // remove the clones - // walk in reverse order, otherwise we will shift the vector - FOR_EACH_REVERSE(d, duplications) { - assert(d.second < symbol.parts.size()); - symbol.parts.erase(symbol.parts.begin() + d.second); - } - } else { - // insert the clones - FOR_EACH(d, duplications) { - assert(d.second <= symbol.parts.size()); - symbol.parts.insert(symbol.parts.begin() + d.second, d.first); - } - } + if (to_undo) { + // remove the clones + // walk in reverse order, otherwise we will shift the vector + FOR_EACH_REVERSE(d, duplications) { + assert(d.second < symbol.parts.size()); + symbol.parts.erase(symbol.parts.begin() + d.second); + } + } else { + // insert the clones + FOR_EACH(d, duplications) { + assert(d.second <= symbol.parts.size()); + symbol.parts.insert(symbol.parts.begin() + d.second, d.first); + } + } } void DuplicateSymbolPartsAction::getParts(set& parts) { - parts.clear(); - FOR_EACH(d, duplications) { - parts.insert(d.first); - } + parts.clear(); + FOR_EACH(d, duplications) { + parts.insert(d.first); + } } // ----------------------------------------------------------------------------- : Reorder symbol parts ReorderSymbolPartsAction::ReorderSymbolPartsAction(SymbolGroup& old_parent, size_t old_position, SymbolGroup& new_parent, size_t new_position) - : old_parent(&old_parent), new_parent(&new_parent) - , old_position(old_position), new_position(new_position) + : old_parent(&old_parent), new_parent(&new_parent) + , old_position(old_position), new_position(new_position) {} String ReorderSymbolPartsAction::getName(bool to_undo) const { - return _ACTION_("reorder parts"); + return _ACTION_("reorder parts"); } void ReorderSymbolPartsAction::perform(bool to_undo) { - // remove from old - assert(old_position < old_parent->parts.size()); - SymbolPartP part = old_parent->parts.at(old_position); - old_parent->parts.erase( old_parent->parts.begin() + old_position); - // add to new - assert(new_position <= new_parent->parts.size()); - new_parent->parts.insert(new_parent->parts.begin() + new_position, part); - // next time the other way around - swap(old_parent, new_parent); - swap(old_position, new_position); + // remove from old + assert(old_position < old_parent->parts.size()); + SymbolPartP part = old_parent->parts.at(old_position); + old_parent->parts.erase( old_parent->parts.begin() + old_position); + // add to new + assert(new_position <= new_parent->parts.size()); + new_parent->parts.insert(new_parent->parts.begin() + new_position, part); + // next time the other way around + swap(old_parent, new_parent); + swap(old_position, new_position); } UngroupReorderSymbolPartsAction::UngroupReorderSymbolPartsAction(SymbolGroup& group_parent, size_t group_pos, SymbolGroup& target_parent, size_t target_pos) - : group_parent(group_parent), group_pos(group_pos) - , target_parent(target_parent), target_pos(target_pos) + : group_parent(group_parent), group_pos(group_pos) + , target_parent(target_parent), target_pos(target_pos) { - group = dynamic_pointer_cast(group_parent.parts.at(group_pos)); - assert(group); + group = dynamic_pointer_cast(group_parent.parts.at(group_pos)); + assert(group); } String UngroupReorderSymbolPartsAction::getName(bool to_undo) const { - return _ACTION_("reorder parts"); + return _ACTION_("reorder parts"); } void UngroupReorderSymbolPartsAction::perform(bool to_undo) { - if (!to_undo) { - group_parent.parts.erase(group_parent.parts.begin() + group_pos); - target_parent.parts.insert(target_parent.parts.begin() + target_pos, group->parts.begin(), group->parts.end()); - } else { - target_parent.parts.erase(target_parent.parts.begin() + target_pos, target_parent.parts.begin() + target_pos + group->parts.size()); - group_parent.parts.insert(group_parent.parts.begin() + group_pos, group); - } + if (!to_undo) { + group_parent.parts.erase(group_parent.parts.begin() + group_pos); + target_parent.parts.insert(target_parent.parts.begin() + target_pos, group->parts.begin(), group->parts.end()); + } else { + target_parent.parts.erase(target_parent.parts.begin() + target_pos, target_parent.parts.begin() + target_pos + group->parts.size()); + group_parent.parts.insert(group_parent.parts.begin() + group_pos, group); + } } // ----------------------------------------------------------------------------- : Group symbol parts GroupSymbolPartsActionBase::GroupSymbolPartsActionBase(SymbolGroup& root) - : root(root) + : root(root) {} void GroupSymbolPartsActionBase::perform(bool to_undo) { - swap(root.parts, old_part_list); + swap(root.parts, old_part_list); } GroupSymbolPartsAction::GroupSymbolPartsAction(SymbolGroup& root, const set& parts, const SymbolGroupP& group) - : GroupSymbolPartsActionBase(root) - , group(group) + : GroupSymbolPartsActionBase(root) + , group(group) { - // group parts in the old parts list - bool done = false; - FOR_EACH(p, root.parts) { - assert(p != group); - if (parts.find(p) != parts.end()) { - // add to group instead - group->parts.push_back(p); - if (!done) { - done = true; - old_part_list.push_back(group); - } - } else { - // not affected - old_part_list.push_back(p); - } - } - group->updateBounds(); + // group parts in the old parts list + bool done = false; + FOR_EACH(p, root.parts) { + assert(p != group); + if (parts.find(p) != parts.end()) { + // add to group instead + group->parts.push_back(p); + if (!done) { + done = true; + old_part_list.push_back(group); + } + } else { + // not affected + old_part_list.push_back(p); + } + } + group->updateBounds(); } String GroupSymbolPartsAction::getName(bool to_undo) const { - return group->isSymbolSymmetry() ? _ACTION_("add symmetry") : _ACTION_("group parts"); + return group->isSymbolSymmetry() ? _ACTION_("add symmetry") : _ACTION_("group parts"); } UngroupSymbolPartsAction::UngroupSymbolPartsAction(SymbolGroup& root, const set& parts) - : GroupSymbolPartsActionBase(root) + : GroupSymbolPartsActionBase(root) { - // break up the parts in the old parts list - FOR_EACH(p, root.parts) { - if (parts.find(p) != parts.end() && p->isSymbolGroup()) { - // break up the group - SymbolGroup* g = p->isSymbolGroup(); - FOR_EACH(p, g->parts) { - old_part_list.push_back(p); - } - } else { - // not affected - old_part_list.push_back(p); - } - } + // break up the parts in the old parts list + FOR_EACH(p, root.parts) { + if (parts.find(p) != parts.end() && p->isSymbolGroup()) { + // break up the group + SymbolGroup* g = p->isSymbolGroup(); + FOR_EACH(p, g->parts) { + old_part_list.push_back(p); + } + } else { + // not affected + old_part_list.push_back(p); + } + } } String UngroupSymbolPartsAction::getName(bool to_undo) const { - return _ACTION_("ungroup parts"); + return _ACTION_("ungroup parts"); } diff --git a/src/data/action/symbol.hpp b/src/data/action/symbol.hpp index 4e79654c..3de9d8e8 100644 --- a/src/data/action/symbol.hpp +++ b/src/data/action/symbol.hpp @@ -26,9 +26,9 @@ class SymbolPartAction : public Action {}; /// Anything that changes a set of parts class SymbolPartsAction : public SymbolPartAction { public: - SymbolPartsAction(const set& parts); - - const set parts; ///< Affected parts + SymbolPartsAction(const set& parts); + + const set parts; ///< Affected parts }; /// Anything that changes a part as displayed in the part list @@ -39,23 +39,23 @@ class SymbolPartListAction : public SymbolPartAction {}; /// Move some symbol parts class SymbolPartMoveAction : public SymbolPartsAction { public: - SymbolPartMoveAction(const set& parts, const Vector2D& delta = Vector2D()); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - - /// Update this action to move some more - void move(const Vector2D& delta); - + SymbolPartMoveAction(const set& parts, const Vector2D& delta = Vector2D()); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + + /// Update this action to move some more + void move(const Vector2D& delta); + private: - Vector2D delta; ///< How much to move - Vector2D moved; ///< How much has been moved - Bounds bounds; ///< Bounding box of the thing we are moving - - void movePart(SymbolPart& part); ///< Move a single part + Vector2D delta; ///< How much to move + Vector2D moved; ///< How much has been moved + Bounds bounds; ///< Bounding box of the thing we are moving + + void movePart(SymbolPart& part); ///< Move a single part public: - bool constrain; ///< Constrain movement? - int snap; ///< Snap to grid? + bool constrain; ///< Constrain movement? + int snap; ///< Snap to grid? }; // ----------------------------------------------------------------------------- : Rotating symbol parts @@ -63,37 +63,37 @@ class SymbolPartMoveAction : public SymbolPartsAction { /// Transforming symbol parts using a matrix class SymbolPartMatrixAction : public SymbolPartsAction { public: - SymbolPartMatrixAction(const set& parts, const Vector2D& center); - - /// Update this action to move some more - void move(const Vector2D& delta); - + SymbolPartMatrixAction(const set& parts, const Vector2D& center); + + /// Update this action to move some more + void move(const Vector2D& delta); + protected: - /// Perform the transformation using the given matrix - void transform(const Matrix2D& m); - void transform(SymbolPart& part, const Matrix2D& m); - - Vector2D center; ///< Center to transform around + /// Perform the transformation using the given matrix + void transform(const Matrix2D& m); + void transform(SymbolPart& part, const Matrix2D& m); + + Vector2D center; ///< Center to transform around }; /// Rotate some symbol parts class SymbolPartRotateAction : public SymbolPartMatrixAction { public: - SymbolPartRotateAction(const set& parts, const Vector2D& center); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - - /// Update this action to rotate to a different angle - void rotateTo(Radians newAngle); - - /// Update this action to rotate by a deltaAngle - void rotateBy(Radians deltaAngle); - + SymbolPartRotateAction(const set& parts, const Vector2D& center); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + + /// Update this action to rotate to a different angle + void rotateTo(Radians newAngle); + + /// Update this action to rotate by a deltaAngle + void rotateBy(Radians deltaAngle); + private: - Radians angle; ///< How much to rotate? + Radians angle; ///< How much to rotate? public: - bool constrain; ///< Constrain movement? + bool constrain; ///< Constrain movement? }; @@ -102,21 +102,21 @@ class SymbolPartRotateAction : public SymbolPartMatrixAction { /// Shear some symbol parts class SymbolPartShearAction : public SymbolPartMatrixAction { public: - SymbolPartShearAction(const set& parts, const Vector2D& center); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - - /// Change shear by a given amount - void move(const Vector2D& deltaShear); - + SymbolPartShearAction(const set& parts, const Vector2D& center); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + + /// Change shear by a given amount + void move(const Vector2D& deltaShear); + private: - Vector2D shear; ///< Shearing, shear.x == 0 || shear.y == 0 - Vector2D moved; - void shearBy(const Vector2D& shear); + Vector2D shear; ///< Shearing, shear.x == 0 || shear.y == 0 + Vector2D moved; + void shearBy(const Vector2D& shear); public: -// bool constrain; ///< Constrain movement? - int snap; ///< Snap to grid? +// bool constrain; ///< Constrain movement? + int snap; ///< Snap to grid? }; @@ -125,29 +125,29 @@ class SymbolPartShearAction : public SymbolPartMatrixAction { /// Scale some symbol parts class SymbolPartScaleAction : public SymbolPartsAction { public: - SymbolPartScaleAction(const set& parts, int scaleX, int scaleY); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - - /// Change min and max coordinates - void move(const Vector2D& delta_min, const Vector2D& delta_max); - /// Update the action's effect - void update(); - + SymbolPartScaleAction(const set& parts, int scaleX, int scaleY); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + + /// Change min and max coordinates + void move(const Vector2D& delta_min, const Vector2D& delta_max); + /// Update the action's effect + void update(); + private: - Vector2D old_min, old_size; ///< the original pos/size - Vector2D new_real_min, new_real_size; ///< the target pos/sizevoid shearBy(const Vector2D& shear) - Vector2D new_min, new_size; ///< the target pos/size after applying constrains - int scaleX, scaleY; ///< to what corner are we attached? - /// Transform everything in the parts - void transformAll(); - void transformPart(SymbolPart&); - /// Transform a single vector - inline Vector2D transform(const Vector2D& v); + Vector2D old_min, old_size; ///< the original pos/size + Vector2D new_real_min, new_real_size; ///< the target pos/sizevoid shearBy(const Vector2D& shear) + Vector2D new_min, new_size; ///< the target pos/size after applying constrains + int scaleX, scaleY; ///< to what corner are we attached? + /// Transform everything in the parts + void transformAll(); + void transformPart(SymbolPart&); + /// Transform a single vector + inline Vector2D transform(const Vector2D& v); public: - bool constrain; ///< Constrain movement? - int snap; ///< Snap to grid? + bool constrain; ///< Constrain movement? + int snap; ///< Snap to grid? }; // ----------------------------------------------------------------------------- : Change combine mode @@ -155,15 +155,15 @@ class SymbolPartScaleAction : public SymbolPartsAction { /// Change the name of a symbol part class CombiningModeAction : public SymbolPartsAction { public: - // All parts must be SymbolParts - CombiningModeAction(const set& parts, SymbolShapeCombine mode); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - + // All parts must be SymbolParts + CombiningModeAction(const set& parts, SymbolShapeCombine mode); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + private: - void add(const SymbolPartP&, SymbolShapeCombine mode); - vector > parts; ///< Affected parts with new combining modes + void add(const SymbolPartP&, SymbolShapeCombine mode); + vector > parts; ///< Affected parts with new combining modes }; // ----------------------------------------------------------------------------- : Change name @@ -171,17 +171,17 @@ class CombiningModeAction : public SymbolPartsAction { /// Change the name of a symbol part class SymbolPartNameAction : public SymbolPartAction { public: - SymbolPartNameAction(const SymbolPartP& part, const String& name, size_t old_cursor, size_t new_cursor); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - virtual bool merge(const Action& action); - + SymbolPartNameAction(const SymbolPartP& part, const String& name, size_t old_cursor, size_t new_cursor); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + virtual bool merge(const Action& action); + public: - SymbolPartP part; ///< Affected part - String part_name; ///< New name - size_t old_cursor; ///< Cursor position - size_t new_cursor; ///< Cursor position + SymbolPartP part; ///< Affected part + String part_name; ///< New name + size_t old_cursor; ///< Cursor position + size_t new_cursor; ///< Cursor position }; // ----------------------------------------------------------------------------- : Add symbol part @@ -189,14 +189,14 @@ class SymbolPartNameAction : public SymbolPartAction { /// Adding a part to a symbol, added at the front of the list (drawn on top) class AddSymbolPartAction : public SymbolPartListAction { public: - AddSymbolPartAction(Symbol& symbol, const SymbolPartP& part); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - + AddSymbolPartAction(Symbol& symbol, const SymbolPartP& part); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + private: - Symbol& symbol; ///< Symbol to add the part to - SymbolPartP part; ///< Part to add + Symbol& symbol; ///< Symbol to add the part to + SymbolPartP part; ///< Part to add }; // ----------------------------------------------------------------------------- : Remove symbol part @@ -204,28 +204,28 @@ class AddSymbolPartAction : public SymbolPartListAction { /// Removing parts from a symbol class RemoveSymbolPartsAction : public SymbolPartListAction { public: - RemoveSymbolPartsAction(Symbol& symbol, const set& parts); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - + RemoveSymbolPartsAction(Symbol& symbol, const set& parts); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + private: - Symbol& symbol; - /// Check for removals in a group - void check(SymbolGroup& group, const set& parts); + Symbol& symbol; + /// Check for removals in a group + void check(SymbolGroup& group, const set& parts); public: - /// A removal step - struct Removal { - inline Removal(SymbolGroup& parent, size_t pos, const SymbolPartP& removed) - : parent(&parent), pos(pos), removed(removed) - {} - SymbolGroup* parent; - size_t pos; - SymbolPartP removed; - }; + /// A removal step + struct Removal { + inline Removal(SymbolGroup& parent, size_t pos, const SymbolPartP& removed) + : parent(&parent), pos(pos), removed(removed) + {} + SymbolGroup* parent; + size_t pos; + SymbolPartP removed; + }; private: - /// Removed parts, sorted by ascending pos - vector removals; + /// Removed parts, sorted by ascending pos + vector removals; }; // ----------------------------------------------------------------------------- : Duplicate symbol parts @@ -233,18 +233,18 @@ class RemoveSymbolPartsAction : public SymbolPartListAction { /// Duplicating parts in a symbol class DuplicateSymbolPartsAction : public SymbolPartListAction { public: - DuplicateSymbolPartsAction(Symbol& symbol, const set& parts); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - - /// Fill a set with all the new parts - void getParts(set& parts); - + DuplicateSymbolPartsAction(Symbol& symbol, const set& parts); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + + /// Fill a set with all the new parts + void getParts(set& parts); + private: - Symbol& symbol; - /// Duplicates of parts and their positions, sorted by ascending pos - vector > duplications; + Symbol& symbol; + /// Duplicates of parts and their positions, sorted by ascending pos + vector > duplications; }; @@ -253,32 +253,32 @@ class DuplicateSymbolPartsAction : public SymbolPartListAction { /// Change the position of a part in a symbol, by moving a part. class ReorderSymbolPartsAction : public SymbolPartListAction { public: - ReorderSymbolPartsAction(SymbolGroup& old_parent, size_t old_position, SymbolGroup& new_parent, size_t new_position); + ReorderSymbolPartsAction(SymbolGroup& old_parent, size_t old_position, SymbolGroup& new_parent, size_t new_position); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - private: - SymbolGroup* old_parent, *new_parent;///< Parents to move from and to + SymbolGroup* old_parent, *new_parent;///< Parents to move from and to public: - size_t old_position, new_position; ///< Positions to move from and to + size_t old_position, new_position; ///< Positions to move from and to }; /// Break up a single group, and put its contents at a specific position class UngroupReorderSymbolPartsAction : public SymbolPartListAction { public: - /// Remove all the given groups - UngroupReorderSymbolPartsAction(SymbolGroup& group_parent, size_t group_pos, SymbolGroup& target_parent, size_t target_pos); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - + /// Remove all the given groups + UngroupReorderSymbolPartsAction(SymbolGroup& group_parent, size_t group_pos, SymbolGroup& target_parent, size_t target_pos); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + private: - SymbolGroup& group_parent; - size_t group_pos; - SymbolGroupP group; ///< Group to destroy - SymbolGroup& target_parent; - size_t target_pos; + SymbolGroup& group_parent; + size_t group_pos; + SymbolGroupP group; ///< Group to destroy + SymbolGroup& target_parent; + size_t target_pos; }; // ----------------------------------------------------------------------------- : Group symbol parts @@ -286,32 +286,32 @@ class UngroupReorderSymbolPartsAction : public SymbolPartListAction { /// Group multiple symbol parts together class GroupSymbolPartsActionBase : public SymbolPartListAction { public: - GroupSymbolPartsActionBase(SymbolGroup& root); - - virtual void perform(bool to_undo); - + GroupSymbolPartsActionBase(SymbolGroup& root); + + virtual void perform(bool to_undo); + protected: - SymbolGroup& root; ///< Symbol or group to group stuff in - vector old_part_list; ///< Old part list of the symbol + SymbolGroup& root; ///< Symbol or group to group stuff in + vector old_part_list; ///< Old part list of the symbol }; /// Group multiple symbol parts together class GroupSymbolPartsAction : public GroupSymbolPartsActionBase { public: - GroupSymbolPartsAction(SymbolGroup& root, const set& parts, const SymbolGroupP& group); - - virtual String getName(bool to_undo) const; + GroupSymbolPartsAction(SymbolGroup& root, const set& parts, const SymbolGroupP& group); + + virtual String getName(bool to_undo) const; private: - SymbolGroupP group; + SymbolGroupP group; }; /// Break up one or more SymbolGroups class UngroupSymbolPartsAction : public GroupSymbolPartsActionBase { public: - /// Remove all the given groups - UngroupSymbolPartsAction(SymbolGroup& root, const set& groups); - - virtual String getName(bool to_undo) const; + /// Remove all the given groups + UngroupSymbolPartsAction(SymbolGroup& root, const set& groups); + + virtual String getName(bool to_undo) const; }; // ----------------------------------------------------------------------------- : EOF diff --git a/src/data/action/symbol_part.cpp b/src/data/action/symbol_part.cpp index 9a08c03f..4511ad3e 100644 --- a/src/data/action/symbol_part.cpp +++ b/src/data/action/symbol_part.cpp @@ -18,270 +18,270 @@ DECLARE_TYPEOF_COLLECTION(ControlPointP); inline double sgn(double v) { return v > 0 ? 1 : -1; } Vector2D constrain_vector(const Vector2D& v, bool constrain, bool only_diagonal) { - if (!constrain) return v; - double ax = fabs(v.x), ay = fabs(v.y); - if (ax * 2 < ay && !only_diagonal) { - return Vector2D(0, v.y); // vertical - } else if(ay * 2 < ax && !only_diagonal) { - return Vector2D(v.x, 0); // horizontal - } else { - return Vector2D( // diagonal - sgn(v.x) * (ax + ay) / 2, - sgn(v.y) * (ax + ay) / 2 - ); - } + if (!constrain) return v; + double ax = fabs(v.x), ay = fabs(v.y); + if (ax * 2 < ay && !only_diagonal) { + return Vector2D(0, v.y); // vertical + } else if(ay * 2 < ax && !only_diagonal) { + return Vector2D(v.x, 0); // horizontal + } else { + return Vector2D( // diagonal + sgn(v.x) * (ax + ay) / 2, + sgn(v.y) * (ax + ay) / 2 + ); + } } inline double snap(double x, int steps) { - return steps <= 0 ? x : floor(x * steps + 0.5) / steps; + return steps <= 0 ? x : floor(x * steps + 0.5) / steps; } Vector2D snap_vector(const Vector2D& v, int steps) { - return Vector2D(snap(v.x, steps), snap(v.y, steps)); + return Vector2D(snap(v.x, steps), snap(v.y, steps)); } Vector2D constrain_snap_vector(const Vector2D& v, const Vector2D& d, bool constrain, int steps) { - if (!constrain) return snap_vector(v+d, steps); - double ax = fabs(d.x), ay = fabs(d.y); - if (ax * 2 < ay) { - return Vector2D(v.x, snap(d.y + v.y, steps)); // vertical - } else if(ay * 2 < ax) { - return Vector2D(snap(d.x + v.x, steps), v.y); // horizontal - } else { - double dc = (ax + ay) / 2; // delta in both directions - double dxs = snap(v.x + dc, steps) - v.x; // snapped to x - double dys = snap(v.y + dc, steps) - v.y; // snapped to y - if (fabs(dxs-dc) < fabs(dys-dc)) { - // take the one that is closest to the unsnaped delta - return Vector2D(v.x + sgn(d.x) * dxs, v.y + sgn(d.y) * dxs); - } else { - return Vector2D(v.x + sgn(d.x) * dys, v.y + sgn(d.y) * dys); - } - } + if (!constrain) return snap_vector(v+d, steps); + double ax = fabs(d.x), ay = fabs(d.y); + if (ax * 2 < ay) { + return Vector2D(v.x, snap(d.y + v.y, steps)); // vertical + } else if(ay * 2 < ax) { + return Vector2D(snap(d.x + v.x, steps), v.y); // horizontal + } else { + double dc = (ax + ay) / 2; // delta in both directions + double dxs = snap(v.x + dc, steps) - v.x; // snapped to x + double dys = snap(v.y + dc, steps) - v.y; // snapped to y + if (fabs(dxs-dc) < fabs(dys-dc)) { + // take the one that is closest to the unsnaped delta + return Vector2D(v.x + sgn(d.x) * dxs, v.y + sgn(d.y) * dxs); + } else { + return Vector2D(v.x + sgn(d.x) * dys, v.y + sgn(d.y) * dys); + } + } } Vector2D constrain_snap_vector_offset(const Vector2D& off1, const Vector2D& d, bool constrain, int steps) { - return constrain_snap_vector(off1, d, constrain, steps) - off1; + return constrain_snap_vector(off1, d, constrain, steps) - off1; } // calculate constrained delta for the given offset, store in output if it is better void constrain_snap_vector_offset_(const Vector2D& off, const Vector2D& d, bool constrain, int steps, Vector2D& best, double& best_length) { - Vector2D d2 = constrain_snap_vector_offset(off, d, constrain, steps); - double l2 = d2.lengthSqr(); - if (l2 < best_length) { - best_length = l2; - best = d2; - } + Vector2D d2 = constrain_snap_vector_offset(off, d, constrain, steps); + double l2 = d2.lengthSqr(); + if (l2 < best_length) { + best_length = l2; + best = d2; + } } Vector2D constrain_snap_vector_offset(const Vector2D& off1, const Vector2D& off2, const Vector2D& d, bool constrain, int steps) { - Vector2D dd; double l = numeric_limits::infinity(); - constrain_snap_vector_offset_(off1, d, constrain, steps, dd, l); - constrain_snap_vector_offset_(off2, d, constrain, steps, dd, l); - constrain_snap_vector_offset_(Vector2D(off1.x,off2.y), d, constrain, steps, dd, l); - constrain_snap_vector_offset_(Vector2D(off2.x,off1.y), d, constrain, steps, dd, l); - return dd; + Vector2D dd; double l = numeric_limits::infinity(); + constrain_snap_vector_offset_(off1, d, constrain, steps, dd, l); + constrain_snap_vector_offset_(off2, d, constrain, steps, dd, l); + constrain_snap_vector_offset_(Vector2D(off1.x,off2.y), d, constrain, steps, dd, l); + constrain_snap_vector_offset_(Vector2D(off2.x,off1.y), d, constrain, steps, dd, l); + return dd; } String action_name_for(const set& points, const String& action) { - return format_string(action, points.size() == 1 ? _TYPE_("point") : _TYPE_("points")); + return format_string(action, points.size() == 1 ? _TYPE_("point") : _TYPE_("points")); } // ----------------------------------------------------------------------------- : Move control point ControlPointMoveAction::ControlPointMoveAction(const set& points) - : points(points) - , constrain(false) - , snap(0) + : points(points) + , constrain(false) + , snap(0) { - oldValues.reserve(points.size()); - FOR_EACH(p, points) { - oldValues.push_back(p->pos); - } + oldValues.reserve(points.size()); + FOR_EACH(p, points) { + oldValues.push_back(p->pos); + } } String ControlPointMoveAction::getName(bool to_undo) const { - return action_name_for(points, _ACTION_("move")); + return action_name_for(points, _ACTION_("move")); } void ControlPointMoveAction::perform(bool to_undo) { - FOR_EACH_2(p,points, op,oldValues) { - swap(p->pos, op); - } + FOR_EACH_2(p,points, op,oldValues) { + swap(p->pos, op); + } } void ControlPointMoveAction::move (const Vector2D& deltaDelta) { - delta += deltaDelta; - // Move each point by delta, possibly constrained - set::const_iterator it = points.begin(); - vector ::iterator it2 = oldValues.begin(); - for( ; it != points.end() && it2 != oldValues.end() ; ++it, ++it2) { - (*it)->pos = constrain_snap_vector(*it2, delta, constrain, snap); - } + delta += deltaDelta; + // Move each point by delta, possibly constrained + set::const_iterator it = points.begin(); + vector ::iterator it2 = oldValues.begin(); + for( ; it != points.end() && it2 != oldValues.end() ; ++it, ++it2) { + (*it)->pos = constrain_snap_vector(*it2, delta, constrain, snap); + } } // ----------------------------------------------------------------------------- : Move handle HandleMoveAction::HandleMoveAction(const SelectedHandle& handle) - : handle(handle) - , old_handle(handle.getHandle()) - , old_other (handle.getOther()) - , constrain(false) - , snap(0) + : handle(handle) + , old_handle(handle.getHandle()) + , old_other (handle.getOther()) + , constrain(false) + , snap(0) {} String HandleMoveAction::getName(bool to_undo) const { - return _ACTION_("move handle"); + return _ACTION_("move handle"); } void HandleMoveAction::perform(bool to_undo) { - swap(old_handle, handle.getHandle()); - swap(old_other, handle.getOther()); + swap(old_handle, handle.getHandle()); + swap(old_other, handle.getOther()); } void HandleMoveAction::move(const Vector2D& deltaDelta) { - delta += deltaDelta; - handle.getHandle() = constrain_snap_vector_offset(handle.point->pos, old_handle + delta, constrain, snap); - handle.getOther() = old_other; - handle.onUpdateHandle(); + delta += deltaDelta; + handle.getHandle() = constrain_snap_vector_offset(handle.point->pos, old_handle + delta, constrain, snap); + handle.getOther() = old_other; + handle.onUpdateHandle(); } // ----------------------------------------------------------------------------- : Segment mode ControlPointUpdate::ControlPointUpdate(const ControlPointP& pnt) - : other(*pnt) - , point(pnt) + : other(*pnt) + , point(pnt) {} void ControlPointUpdate::perform() { - swap(other, *point); + swap(other, *point); } SegmentModeAction::SegmentModeAction(const ControlPointP& p1, const ControlPointP& p2, SegmentMode mode) - : point1(p1), point2(p2) + : point1(p1), point2(p2) { - if (p1->segment_after == mode) return; - point1.other.segment_after = point2.other.segment_before = mode; - if (mode == SEGMENT_LINE) { - point1.other.delta_after = Vector2D(0,0); - point2.other.delta_before = Vector2D(0,0); - point1.other.lock = LOCK_FREE; - point2.other.lock = LOCK_FREE; - } else if (mode == SEGMENT_CURVE) { - point1.other.delta_after = (p2->pos - p1->pos) / 3.0f; - point2.other.delta_before = (p1->pos - p2->pos) / 3.0f; - } + if (p1->segment_after == mode) return; + point1.other.segment_after = point2.other.segment_before = mode; + if (mode == SEGMENT_LINE) { + point1.other.delta_after = Vector2D(0,0); + point2.other.delta_before = Vector2D(0,0); + point1.other.lock = LOCK_FREE; + point2.other.lock = LOCK_FREE; + } else if (mode == SEGMENT_CURVE) { + point1.other.delta_after = (p2->pos - p1->pos) / 3.0f; + point2.other.delta_before = (p1->pos - p2->pos) / 3.0f; + } } String SegmentModeAction::getName(bool to_undo) const { - SegmentMode mode = to_undo ? point1.point->segment_after : point1.other.segment_after; - if (mode == SEGMENT_LINE) return _ACTION_("convert to line"); - else return _ACTION_("convert to curve"); + SegmentMode mode = to_undo ? point1.point->segment_after : point1.other.segment_after; + if (mode == SEGMENT_LINE) return _ACTION_("convert to line"); + else return _ACTION_("convert to curve"); } void SegmentModeAction::perform(bool to_undo) { - point1.perform(); - point2.perform(); + point1.perform(); + point2.perform(); } // ----------------------------------------------------------------------------- : Locking mode LockModeAction::LockModeAction(const ControlPointP& p, LockMode lock) - : point(p) + : point(p) { - point.other.lock = lock; - point.other.onUpdateLock(); + point.other.lock = lock; + point.other.onUpdateLock(); } String LockModeAction::getName(bool to_undo) const { - return _ACTION_("lock point"); + return _ACTION_("lock point"); } void LockModeAction::perform(bool to_undo) { - point.perform(); + point.perform(); } // ----------------------------------------------------------------------------- : Move curve CurveDragAction::CurveDragAction(const ControlPointP& point1, const ControlPointP& point2) - : SegmentModeAction(point1, point2, SEGMENT_CURVE) + : SegmentModeAction(point1, point2, SEGMENT_CURVE) {} String CurveDragAction::getName(bool to_undo) const { - return _ACTION_("move curve"); + return _ACTION_("move curve"); } void CurveDragAction::perform(bool to_undo) { - SegmentModeAction::perform(to_undo); + SegmentModeAction::perform(to_undo); } void CurveDragAction::move(const Vector2D& delta, double t) { - // Logic: - // Assuming old point is p, new point is p' - // Point on old bezier curve is: - // p = a t^3 + 3b (1-t) t^2 + 3c (1-t)^2 t + d (1-t)^2 - // Point on new bezier curve is: - // p_(' = a t^3 + 3b') (1-t) t^2 + 3c' (1-t)^2 t + d (1-t)^2 - // We now want to change control points b and c, the closer we are to b (t close to 0) - // the more effect we have on b, so we substitute: - // b' = b + x t - // c' = c + x (1-t) - // Solving for x we get: - // x = (p'-p) / ( t (1-t) ( t^2 + (1-t)^2) ) - // Naming: - // delta = p' - p - // pointDelta = x * t * (1-t) - Vector2D pointDelta = delta / (3 * (t * t + (1-t) * (1-t))); - point1.point->delta_after += pointDelta / t; - point2.point->delta_before += pointDelta / (1-t); - point1.point->onUpdateHandle(HANDLE_AFTER); - point2.point->onUpdateHandle(HANDLE_BEFORE); + // Logic: + // Assuming old point is p, new point is p' + // Point on old bezier curve is: + // p = a t^3 + 3b (1-t) t^2 + 3c (1-t)^2 t + d (1-t)^2 + // Point on new bezier curve is: + // p_(' = a t^3 + 3b') (1-t) t^2 + 3c' (1-t)^2 t + d (1-t)^2 + // We now want to change control points b and c, the closer we are to b (t close to 0) + // the more effect we have on b, so we substitute: + // b' = b + x t + // c' = c + x (1-t) + // Solving for x we get: + // x = (p'-p) / ( t (1-t) ( t^2 + (1-t)^2) ) + // Naming: + // delta = p' - p + // pointDelta = x * t * (1-t) + Vector2D pointDelta = delta / (3 * (t * t + (1-t) * (1-t))); + point1.point->delta_after += pointDelta / t; + point2.point->delta_before += pointDelta / (1-t); + point1.point->onUpdateHandle(HANDLE_AFTER); + point2.point->onUpdateHandle(HANDLE_BEFORE); } // ----------------------------------------------------------------------------- : Add control point ControlPointAddAction::ControlPointAddAction(const SymbolShapeP& shape, UInt insert_after, double t) - : shape(shape) - , new_point(new ControlPoint()) - , insert_after(insert_after) - , point1(shape->getPoint(insert_after)) - , point2(shape->getPoint(insert_after + 1)) + : shape(shape) + , new_point(new ControlPoint()) + , insert_after(insert_after) + , point1(shape->getPoint(insert_after)) + , point2(shape->getPoint(insert_after + 1)) { - // calculate new point - if (point1.other.segment_after == SEGMENT_CURVE) { - // calculate new handles using de Casteljau's subdivision algorithm - deCasteljau(point1.other, point2.other, t, *new_point); - // unlock if needed - if (point1.other.lock == LOCK_SIZE) point1.other.lock = LOCK_DIR; - if (point2.other.lock == LOCK_SIZE) point2.other.lock = LOCK_DIR; - new_point->lock = LOCK_DIR; - new_point->segment_before = SEGMENT_CURVE; - new_point->segment_after = SEGMENT_CURVE; - } else { - new_point->pos = point1.other.pos * (1 - t) + point2.other.pos * t; - new_point->lock = LOCK_FREE; - new_point->segment_before = SEGMENT_LINE; - new_point->segment_after = SEGMENT_LINE; - } + // calculate new point + if (point1.other.segment_after == SEGMENT_CURVE) { + // calculate new handles using de Casteljau's subdivision algorithm + deCasteljau(point1.other, point2.other, t, *new_point); + // unlock if needed + if (point1.other.lock == LOCK_SIZE) point1.other.lock = LOCK_DIR; + if (point2.other.lock == LOCK_SIZE) point2.other.lock = LOCK_DIR; + new_point->lock = LOCK_DIR; + new_point->segment_before = SEGMENT_CURVE; + new_point->segment_after = SEGMENT_CURVE; + } else { + new_point->pos = point1.other.pos * (1 - t) + point2.other.pos * t; + new_point->lock = LOCK_FREE; + new_point->segment_before = SEGMENT_LINE; + new_point->segment_after = SEGMENT_LINE; + } } String ControlPointAddAction::getName(bool to_undo) const { - return _ACTION_("add control point"); + return _ACTION_("add control point"); } void ControlPointAddAction::perform(bool to_undo) { - if (to_undo) { // remove the point - shape->points.erase( shape->points.begin() + insert_after + 1); - } else { - shape->points.insert(shape->points.begin() + insert_after + 1, new_point); - } - // update points before/after - point1.perform(); - point2.perform(); + if (to_undo) { // remove the point + shape->points.erase( shape->points.begin() + insert_after + 1); + } else { + shape->points.insert(shape->points.begin() + insert_after + 1, new_point); + } + // update points before/after + point1.perform(); + point2.perform(); } // ----------------------------------------------------------------------------- : Remove control point @@ -289,89 +289,89 @@ void ControlPointAddAction::perform(bool to_undo) { /// Sqaure root that caries the sign over the root /// or formally: ssqrt(x) = Re - Im = x / sqrt(|x|) double ssqrt(double x) { - if (x > 0) return sqrt(x); - else return -sqrt(-x); + if (x > 0) return sqrt(x); + else return -sqrt(-x); } // Remove a single control point class SinglePointRemoveAction : public Action, public IntrusivePtrBase { public: - SinglePointRemoveAction(const SymbolShapeP& shape, UInt position); - - virtual String getName(bool to_undo) const { return _("Delete point"); } - virtual void perform(bool to_undo); - + SinglePointRemoveAction(const SymbolShapeP& shape, UInt position); + + virtual String getName(bool to_undo) const { return _("Delete point"); } + virtual void perform(bool to_undo); + private: - SymbolShapeP shape; - UInt position; - ControlPointP point; ///< Removed point - ControlPointUpdate point1, point2; ///< Points before/after + SymbolShapeP shape; + UInt position; + ControlPointP point; ///< Removed point + ControlPointUpdate point1, point2; ///< Points before/after }; SinglePointRemoveAction::SinglePointRemoveAction(const SymbolShapeP& shape, UInt position) - : shape(shape) - , position(position) - , point (shape->getPoint(position)) - , point1(shape->getPoint(position - 1)) - , point2(shape->getPoint(position + 1)) + : shape(shape) + , position(position) + , point (shape->getPoint(position)) + , point1(shape->getPoint(position - 1)) + , point2(shape->getPoint(position + 1)) { - if (point1.other.segment_after == SEGMENT_CURVE || point2.other.segment_before == SEGMENT_CURVE) { - // try to preserve curve - Vector2D before = point->delta_before; - Vector2D after = point->delta_after; - - // convert both segments to curves first - if (point1.other.segment_after != SEGMENT_CURVE) { - before = (point1.other.pos - point->pos) / 3.0; - point1.other.delta_after = -before; - point1.other.segment_after = SEGMENT_CURVE; - } - if (point2.other.segment_before != SEGMENT_CURVE) { - after = (point2.other.pos - point->pos) / 3.0; - point2.other.delta_before = -after; - point2.other.segment_before = SEGMENT_CURVE; - } - - // The inverse of adding a point, reconstruct the original handles - // before being subdivided using de Casteljau's algorithm - // length of handles - double bl = before.length() + 0.00000001; // prevent division by 0 - double al = after .length() + 0.00000001; - double totl = bl + al; - // set new handle sizes - point1.other.delta_after *= totl / bl; - point2.other.delta_before *= totl / al; - - // Also take in acount cases where the point does not correspond to a freshly added point. - // distance from the point to the curve as it would be in the above case can be used, - // in the case of a point just added this distance = 0 - BezierCurve c(point1.other, point2.other); - double t = bl / totl; - Vector2D p = c.pointAt(t); - Vector2D distP = point->pos - p; - // adjust handle sizes - point1.other.delta_after *= ssqrt(dot(distP, point1.other.delta_after) /point1.other.delta_after.lengthSqr()) + 1; - point2.other.delta_before *= ssqrt(dot(distP, point2.other.delta_before)/point2.other.delta_before.lengthSqr()) + 1; - - // unlock if needed - if (point1.other.lock == LOCK_SIZE) point1.other.lock = LOCK_DIR; - if (point2.other.lock == LOCK_SIZE) point2.other.lock = LOCK_DIR; - } else { - // just lines, keep it that way - } + if (point1.other.segment_after == SEGMENT_CURVE || point2.other.segment_before == SEGMENT_CURVE) { + // try to preserve curve + Vector2D before = point->delta_before; + Vector2D after = point->delta_after; + + // convert both segments to curves first + if (point1.other.segment_after != SEGMENT_CURVE) { + before = (point1.other.pos - point->pos) / 3.0; + point1.other.delta_after = -before; + point1.other.segment_after = SEGMENT_CURVE; + } + if (point2.other.segment_before != SEGMENT_CURVE) { + after = (point2.other.pos - point->pos) / 3.0; + point2.other.delta_before = -after; + point2.other.segment_before = SEGMENT_CURVE; + } + + // The inverse of adding a point, reconstruct the original handles + // before being subdivided using de Casteljau's algorithm + // length of handles + double bl = before.length() + 0.00000001; // prevent division by 0 + double al = after .length() + 0.00000001; + double totl = bl + al; + // set new handle sizes + point1.other.delta_after *= totl / bl; + point2.other.delta_before *= totl / al; + + // Also take in acount cases where the point does not correspond to a freshly added point. + // distance from the point to the curve as it would be in the above case can be used, + // in the case of a point just added this distance = 0 + BezierCurve c(point1.other, point2.other); + double t = bl / totl; + Vector2D p = c.pointAt(t); + Vector2D distP = point->pos - p; + // adjust handle sizes + point1.other.delta_after *= ssqrt(dot(distP, point1.other.delta_after) /point1.other.delta_after.lengthSqr()) + 1; + point2.other.delta_before *= ssqrt(dot(distP, point2.other.delta_before)/point2.other.delta_before.lengthSqr()) + 1; + + // unlock if needed + if (point1.other.lock == LOCK_SIZE) point1.other.lock = LOCK_DIR; + if (point2.other.lock == LOCK_SIZE) point2.other.lock = LOCK_DIR; + } else { + // just lines, keep it that way + } } void SinglePointRemoveAction::perform(bool to_undo) { - if (to_undo) { - // reinsert the point - shape->points.insert(shape->points.begin() + position, point); - } else { - // remove the point - shape->points.erase( shape->points.begin() + position); - } - // update points around removed point - point1.perform(); - point2.perform(); + if (to_undo) { + // reinsert the point + shape->points.insert(shape->points.begin() + position, point); + } else { + // remove the point + shape->points.erase( shape->points.begin() + position); + } + // update points around removed point + point1.perform(); + point2.perform(); } DECLARE_POINTER_TYPE(SinglePointRemoveAction); @@ -383,50 +383,50 @@ DECLARE_TYPEOF_COLLECTION(SinglePointRemoveActionP); // Not all points mat be removed, at least two points must remain. class ControlPointRemoveAction : public Action { public: - ControlPointRemoveAction(const SymbolShapeP& shape, const set& to_delete); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - + ControlPointRemoveAction(const SymbolShapeP& shape, const set& to_delete); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + private: - vector removals; + vector removals; }; ControlPointRemoveAction::ControlPointRemoveAction(const SymbolShapeP& shape, const set& to_delete) { - int index = 0; - // find points to remove, in reverse order - FOR_EACH(point, shape->points) { - if (to_delete.find(point) != to_delete.end()) { - // remove this point - removals.push_back(intrusive(new SinglePointRemoveAction(shape, index))); - } - ++index; - } + int index = 0; + // find points to remove, in reverse order + FOR_EACH(point, shape->points) { + if (to_delete.find(point) != to_delete.end()) { + // remove this point + removals.push_back(intrusive(new SinglePointRemoveAction(shape, index))); + } + ++index; + } } String ControlPointRemoveAction::getName(bool to_undo) const { - return removals.size() == 1 ? _ACTION_("delete point") : _ACTION_("delete points"); + return removals.size() == 1 ? _ACTION_("delete point") : _ACTION_("delete points"); } void ControlPointRemoveAction::perform(bool to_undo) { - if (to_undo) { - FOR_EACH(r, removals) r->perform(to_undo); - } else { - // in reverse order, because positions of later points will - // change after removal of earlier points. - FOR_EACH_REVERSE(r, removals) r->perform(to_undo); - } + if (to_undo) { + FOR_EACH(r, removals) r->perform(to_undo); + } else { + // in reverse order, because positions of later points will + // change after removal of earlier points. + FOR_EACH_REVERSE(r, removals) r->perform(to_undo); + } } Action* control_point_remove_action(const SymbolShapeP& shape, const set& to_delete) { - if (shape->points.size() - to_delete.size() < 2) { - // TODO : remove part? - //intrusive(new ControlPointRemoveAllAction(part)); - return 0; // no action - } else { - return new ControlPointRemoveAction(shape, to_delete); - } + if (shape->points.size() - to_delete.size() < 2) { + // TODO : remove part? + //intrusive(new ControlPointRemoveAllAction(part)); + return 0; // no action + } else { + return new ControlPointRemoveAction(shape, to_delete); + } } @@ -434,95 +434,95 @@ Action* control_point_remove_action(const SymbolShapeP& shape, const set symmetry.copies) copies++; - else copies--; - } - // update name? - if (old_name == symmetry.expectedName()) { - swap(symmetry.copies, copies); - old_name = symmetry.expectedName(); - swap(symmetry.copies, copies); - } + if (symmetry.kind == SYMMETRY_REFLECTION && copies % 2 == 1) { + // make sure it is a multiple of two + if (copies > symmetry.copies) copies++; + else copies--; + } + // update name? + if (old_name == symmetry.expectedName()) { + swap(symmetry.copies, copies); + old_name = symmetry.expectedName(); + swap(symmetry.copies, copies); + } } String SymmetryCopiesAction::getName(bool to_undo) const { - return _ACTION_("change symmetry copies"); + return _ACTION_("change symmetry copies"); } void SymmetryCopiesAction::perform(bool to_undo) { - swap(symmetry.copies, copies); - swap(symmetry.name, old_name); + swap(symmetry.copies, copies); + swap(symmetry.name, old_name); } diff --git a/src/data/action/symbol_part.hpp b/src/data/action/symbol_part.hpp index 0e4c0d08..85567037 100644 --- a/src/data/action/symbol_part.hpp +++ b/src/data/action/symbol_part.hpp @@ -45,21 +45,21 @@ Vector2D constrain_snap_vector_offset(const Vector2D& off1, const Vector2D& off2 /// Moving a control point in a symbol class ControlPointMoveAction : public Action { public: - ControlPointMoveAction(const set& points); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - - /// Update this action to move some more - void move(const Vector2D& delta); - + ControlPointMoveAction(const set& points); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + + /// Update this action to move some more + void move(const Vector2D& delta); + private: - set points; ///< Points to move - vector oldValues; ///< Their old positions - Vector2D delta; ///< Amount we moved + set points; ///< Points to move + vector oldValues; ///< Their old positions + Vector2D delta; ///< Amount we moved public: - bool constrain; ///< Constrain movement? - int snap; ///< Snap to grid? + bool constrain; ///< Constrain movement? + int snap; ///< Snap to grid? }; // ----------------------------------------------------------------------------- : Move handle @@ -67,22 +67,22 @@ class ControlPointMoveAction : public Action { /// Moving a handle(before/after) of a control point in a symbol class HandleMoveAction : public Action { public: - HandleMoveAction(const SelectedHandle& handle); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - - /// Update this action to move some more - void move(const Vector2D& delta); - + HandleMoveAction(const SelectedHandle& handle); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + + /// Update this action to move some more + void move(const Vector2D& delta); + private: - SelectedHandle handle; ///< The handle to move - Vector2D old_handle; ///< Old value of this handle - Vector2D old_other; ///< Old value of other handle, needed for contraints - Vector2D delta; ///< Amount we moved + SelectedHandle handle; ///< The handle to move + Vector2D old_handle; ///< Old value of this handle + Vector2D old_other; ///< Old value of other handle, needed for contraints + Vector2D delta; ///< Amount we moved public: - bool constrain; ///< Constrain movement? - int snap; ///< Snap to grid? + bool constrain; ///< Constrain movement? + int snap; ///< Snap to grid? }; // ----------------------------------------------------------------------------- : Segment mode @@ -90,29 +90,29 @@ class HandleMoveAction : public Action { /// Utility class to update a control point class ControlPointUpdate { public: - ControlPointUpdate(const ControlPointP& pnt); - - /// Perform or undo an update on this control point - void perform(); - - /// Other value that is swapped with the current one. - /// Should be changed to make perform have an effect - ControlPoint other; - /// The point that is to be changed, should not be updated before perform() - ControlPointP point; + ControlPointUpdate(const ControlPointP& pnt); + + /// Perform or undo an update on this control point + void perform(); + + /// Other value that is swapped with the current one. + /// Should be changed to make perform have an effect + ControlPoint other; + /// The point that is to be changed, should not be updated before perform() + ControlPointP point; }; /// Changing a line to a curve and vice versa class SegmentModeAction : public Action { public: - SegmentModeAction(const ControlPointP& p1, const ControlPointP& p2, SegmentMode mode); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - + SegmentModeAction(const ControlPointP& p1, const ControlPointP& p2, SegmentMode mode); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + protected: - ControlPointUpdate point1, point2; + ControlPointUpdate point1, point2; }; // ----------------------------------------------------------------------------- : Locking mode @@ -120,13 +120,13 @@ class SegmentModeAction : public Action { /// Locking a control point class LockModeAction : public Action { public: - LockModeAction(const ControlPointP& p, LockMode mode); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - + LockModeAction(const ControlPointP& p, LockMode mode); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + private: - ControlPointUpdate point; ///< The affected point + ControlPointUpdate point; ///< The affected point }; // ----------------------------------------------------------------------------- : Move curve @@ -136,13 +136,13 @@ class LockModeAction : public Action { */ class CurveDragAction : public SegmentModeAction { public: - CurveDragAction(const ControlPointP& point1, const ControlPointP& point2); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - - // Move the curve by this much, it is grabbed at time t - void move(const Vector2D& delta, double t); + CurveDragAction(const ControlPointP& point1, const ControlPointP& point2); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + + // Move the curve by this much, it is grabbed at time t + void move(const Vector2D& delta, double t); }; // ----------------------------------------------------------------------------- : Add control point @@ -150,19 +150,19 @@ class CurveDragAction : public SegmentModeAction { /// Insert a new point in a symbol shape class ControlPointAddAction : public Action { public: - /// Insert a new point in shape, after position insertAfter_, at the time t on the segment - ControlPointAddAction(const SymbolShapeP& shape, UInt insert_after, double t); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - - inline ControlPointP getNewPoint() const { return new_point; } - + /// Insert a new point in shape, after position insertAfter_, at the time t on the segment + ControlPointAddAction(const SymbolShapeP& shape, UInt insert_after, double t); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + + inline ControlPointP getNewPoint() const { return new_point; } + private: - SymbolShapeP shape; ///< SymbolShape we are in - ControlPointP new_point; ///< The point to insert - UInt insert_after; ///< Insert after index .. in the array - ControlPointUpdate point1, point2; ///< Update the points around the new point + SymbolShapeP shape; ///< SymbolShape we are in + ControlPointP new_point; ///< The point to insert + UInt insert_after; ///< Insert after index .. in the array + ControlPointUpdate point1, point2; ///< Update the points around the new point }; // ----------------------------------------------------------------------------- : Remove control point @@ -179,22 +179,22 @@ Action* control_point_remove_action(const SymbolShapeP& shape, const setfieldP->name); + return _ACTION_1_("change", valueP->fieldP->name); } void ValueAction::perform(bool to_undo) { - if (card) { - swap(const_cast(card)->time_modified, old_time_modified); - } + if (card) { + swap(const_cast(card)->time_modified, old_time_modified); + } } void ValueAction::isOnCard(Card* card) { - this->card = card; + this->card = card; } // ----------------------------------------------------------------------------- : Simple @@ -46,38 +46,38 @@ inline void swap_value(SymbolValue& a, SymbolValue ::ValueType& b inline void swap_value(TextValue& a, TextValue ::ValueType& b) { swap(a.value, b); a.last_update.update(); } inline void swap_value(PackageChoiceValue& a, PackageChoiceValue ::ValueType& b) { swap(a.package_name, b); } inline void swap_value(MultipleChoiceValue& a, MultipleChoiceValue::ValueType& b) { - swap(a.value, b.value); - swap(a.last_change, b.last_change); + swap(a.value, b.value); + swap(a.last_change, b.last_change); } /// A ValueAction that swaps between old and new values template class SimpleValueAction : public ValueAction { public: - inline SimpleValueAction(const intrusive_ptr& value, const typename T::ValueType& new_value) - : ValueAction(value), new_value(new_value) - {} - - virtual void perform(bool to_undo) { - ValueAction::perform(to_undo); - swap_value(static_cast(*valueP), new_value); - valueP->onAction(*this, to_undo); // notify value - } - - virtual bool merge(const Action& action) { - if (!ALLOW_MERGE) return false; - TYPE_CASE(action, SimpleValueAction) { - if (action.valueP == valueP) { - // adjacent actions on the same value, discard the other one, - // because it only keeps an intermediate value - return true; - } - } - return false; - } - + inline SimpleValueAction(const intrusive_ptr& value, const typename T::ValueType& new_value) + : ValueAction(value), new_value(new_value) + {} + + virtual void perform(bool to_undo) { + ValueAction::perform(to_undo); + swap_value(static_cast(*valueP), new_value); + valueP->onAction(*this, to_undo); // notify value + } + + virtual bool merge(const Action& action) { + if (!ALLOW_MERGE) return false; + TYPE_CASE(action, SimpleValueAction) { + if (action.valueP == valueP) { + // adjacent actions on the same value, discard the other one, + // because it only keeps an intermediate value + return true; + } + } + return false; + } + private: - typename T::ValueType new_value; + typename T::ValueType new_value; }; ValueAction* value_action(const ChoiceValueP& value, const Defaultable& new_value) { return new SimpleValueAction (value, new_value); } @@ -86,171 +86,171 @@ ValueAction* value_action(const ImageValueP& value, const FileName& ValueAction* value_action(const SymbolValueP& value, const FileName& new_value) { return new SimpleValueAction(value, new_value); } ValueAction* value_action(const PackageChoiceValueP& value, const String& new_value) { return new SimpleValueAction(value, new_value); } ValueAction* value_action(const MultipleChoiceValueP& value, const Defaultable& new_value, const String& last_change) { - MultipleChoiceValue::ValueType v = { new_value, last_change }; - return new SimpleValueAction(value, v); + MultipleChoiceValue::ValueType v = { new_value, last_change }; + return new SimpleValueAction(value, v); } // ----------------------------------------------------------------------------- : Text TextValueAction::TextValueAction(const TextValueP& value, size_t start, size_t end, size_t new_end, const Defaultable& new_value, const String& name) - : ValueAction(value) - , selection_start(start), selection_end(end), new_selection_end(new_end) - , new_value(new_value) - , name(name) + : ValueAction(value) + , selection_start(start), selection_end(end), new_selection_end(new_end) + , new_value(new_value) + , name(name) {} String TextValueAction::getName(bool to_undo) const { return name; } void TextValueAction::perform(bool to_undo) { - ValueAction::perform(to_undo); - swap_value(value(), new_value); - swap(selection_end, new_selection_end); - valueP->onAction(*this, to_undo); // notify value + ValueAction::perform(to_undo); + swap_value(value(), new_value); + swap(selection_end, new_selection_end); + valueP->onAction(*this, to_undo); // notify value } bool TextValueAction::merge(const Action& action) { - TYPE_CASE(action, TextValueAction) { - if (&action.value() == &value() && action.name == name) { - if (action.selection_start == selection_end) { - // adjacent edits, keep old value of this, it is older - selection_end = action.selection_end; - return true; - } else if (action.new_selection_end == selection_start && name == _ACTION_("backspace")) { - // adjacent backspaces - selection_start = action.selection_start; - selection_end = action.selection_end; - return true; - } - } - } - return false; + TYPE_CASE(action, TextValueAction) { + if (&action.value() == &value() && action.name == name) { + if (action.selection_start == selection_end) { + // adjacent edits, keep old value of this, it is older + selection_end = action.selection_end; + return true; + } else if (action.new_selection_end == selection_start && name == _ACTION_("backspace")) { + // adjacent backspaces + selection_start = action.selection_start; + selection_end = action.selection_end; + return true; + } + } + } + return false; } TextValue& TextValueAction::value() const { - return static_cast(*valueP); + return static_cast(*valueP); } TextValueAction* toggle_format_action(const TextValueP& value, const String& tag, size_t start_i, size_t end_i, size_t start, size_t end, const String& action_name) { - if (start > end) { - swap(start, end); - swap(start_i, end_i); - } - String new_value; - const String& str = value->value(); - // Are we inside the tag we are toggling? - if (!is_in_tag(str, _("<") + tag, start_i, end_i)) { - // we are not inside this tag, add it - new_value = str.substr(0, start_i); - new_value += _("<") + tag + _(">"); - new_value += str.substr(start_i, end_i - start_i); - new_value += _(""); - new_value += str.substr(end_i); - } else { - // we are inside this tag, 'remove' it - new_value = str.substr(0, start_i); - new_value += _(""); - new_value += str.substr(start_i, end_i - start_i); - new_value += _("<") + tag + _(">"); - new_value += str.substr(end_i); - } - // Build action - if (start != end) { - // don't simplify if start == end, this way we insert , allowing the - // user to press Ctrl+B and start typing bold text - new_value = simplify_tagged(new_value); - } - if (value->value() == new_value) { - return nullptr; // no changes - } else { - return new TextValueAction(value, start, end, end, new_value, action_name); - } + if (start > end) { + swap(start, end); + swap(start_i, end_i); + } + String new_value; + const String& str = value->value(); + // Are we inside the tag we are toggling? + if (!is_in_tag(str, _("<") + tag, start_i, end_i)) { + // we are not inside this tag, add it + new_value = str.substr(0, start_i); + new_value += _("<") + tag + _(">"); + new_value += str.substr(start_i, end_i - start_i); + new_value += _(""); + new_value += str.substr(end_i); + } else { + // we are inside this tag, 'remove' it + new_value = str.substr(0, start_i); + new_value += _(""); + new_value += str.substr(start_i, end_i - start_i); + new_value += _("<") + tag + _(">"); + new_value += str.substr(end_i); + } + // Build action + if (start != end) { + // don't simplify if start == end, this way we insert , allowing the + // user to press Ctrl+B and start typing bold text + new_value = simplify_tagged(new_value); + } + if (value->value() == new_value) { + return nullptr; // no changes + } else { + return new TextValueAction(value, start, end, end, new_value, action_name); + } } TextValueAction* typing_action(const TextValueP& value, size_t start_i, size_t end_i, size_t start, size_t end, const String& replacement, const String& action_name) { - bool reverse = start > end; - if (reverse) { - swap(start, end); - swap(start_i, end_i); - } - String new_value = tagged_substr_replace(value->value(), start_i, end_i, replacement); - if (value->value() == new_value) { - // no change - return nullptr; - } else { - if (reverse) { - return new TextValueAction(value, end, start, start+untag(replacement).size(), new_value, action_name); - } else { - return new TextValueAction(value, start, end, start+untag(replacement).size(), new_value, action_name); - } - } + bool reverse = start > end; + if (reverse) { + swap(start, end); + swap(start_i, end_i); + } + String new_value = tagged_substr_replace(value->value(), start_i, end_i, replacement); + if (value->value() == new_value) { + // no change + return nullptr; + } else { + if (reverse) { + return new TextValueAction(value, end, start, start+untag(replacement).size(), new_value, action_name); + } else { + return new TextValueAction(value, start, end, start+untag(replacement).size(), new_value, action_name); + } + } } // ----------------------------------------------------------------------------- : Reminder text TextToggleReminderAction::TextToggleReminderAction(const TextValueP& value, size_t pos_in) - : ValueAction(value) + : ValueAction(value) { - pos = in_tag(value->value(), _("value().GetChar(pos + 4); - enable = !(c == _('1') || c == _('A')); // if it was not enabled, then enable it - old = enable ? _('1') : _('0'); + pos = in_tag(value->value(), _("value().GetChar(pos + 4); + enable = !(c == _('1') || c == _('A')); // if it was not enabled, then enable it + old = enable ? _('1') : _('0'); } String TextToggleReminderAction::getName(bool to_undo) const { - return enable ? _("Show reminder text") : _("Hide reminder text"); + return enable ? _("Show reminder text") : _("Hide reminder text"); } void TextToggleReminderAction::perform(bool to_undo) { - ValueAction::perform(to_undo); - TextValue& value = static_cast(*valueP); - String& val = value.value.mutate(); - assert(pos + 4 < val.size()); - size_t end = match_close_tag(val, pos); - Char& c = val[pos + 4]; - swap(c, old); - if (end != String::npos && end + 5 < val.size()) { - val[end + 5] = c; // - } - value.last_update.update(); - value.onAction(*this, to_undo); // notify value + ValueAction::perform(to_undo); + TextValue& value = static_cast(*valueP); + String& val = value.value.mutate(); + assert(pos + 4 < val.size()); + size_t end = match_close_tag(val, pos); + Char& c = val[pos + 4]; + swap(c, old); + if (end != String::npos && end + 5 < val.size()) { + val[end + 5] = c; // + } + value.last_update.update(); + value.onAction(*this, to_undo); // notify value } // ----------------------------------------------------------------------------- : Event String ScriptValueEvent::getName(bool) const { - assert(false); // this action is just an event, getName shouldn't be called - throw InternalError(_("ScriptValueEvent::getName")); + assert(false); // this action is just an event, getName shouldn't be called + throw InternalError(_("ScriptValueEvent::getName")); } void ScriptValueEvent::perform(bool) { - assert(false); // this action is just an event, it should not be performed + assert(false); // this action is just an event, it should not be performed } String ScriptStyleEvent::getName(bool) const { - assert(false); // this action is just an event, getName shouldn't be called - throw InternalError(_("ScriptStyleEvent::getName")); + assert(false); // this action is just an event, getName shouldn't be called + throw InternalError(_("ScriptStyleEvent::getName")); } void ScriptStyleEvent::perform(bool) { - assert(false); // this action is just an event, it should not be performed + assert(false); // this action is just an event, it should not be performed } // ----------------------------------------------------------------------------- : Action performer ValueActionPerformer::ValueActionPerformer(const ValueP& value, Card* card, const SetP& set) - : value(value), card(card), set(set) + : value(value), card(card), set(set) {} ValueActionPerformer::~ValueActionPerformer() {} void ValueActionPerformer::addAction(ValueAction* action) { - action->isOnCard(card); - set->actions.addAction(action); + action->isOnCard(card); + set->actions.addAction(action); } Package& ValueActionPerformer::getLocalPackage() { - return *set; + return *set; } diff --git a/src/data/action/value.hpp b/src/data/action/value.hpp index 09bec709..b0f113f5 100644 --- a/src/data/action/value.hpp +++ b/src/data/action/value.hpp @@ -36,20 +36,20 @@ DECLARE_POINTER_TYPE(PackageChoiceValue); /// An Action the changes a Value class ValueAction : public Action { public: - inline ValueAction(const ValueP& value) - : valueP(value), card(nullptr), old_time_modified(wxDateTime::Now()) - {} - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - - /// We know that the value is on the given card, add that information - void isOnCard(Card* card); - - const ValueP valueP; ///< The modified value - const Card* card; ///< The card the value is on, or null if it is not a card value + inline ValueAction(const ValueP& value) + : valueP(value), card(nullptr), old_time_modified(wxDateTime::Now()) + {} + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + + /// We know that the value is on the given card, add that information + void isOnCard(Card* card); + + const ValueP valueP; ///< The modified value + const Card* card; ///< The card the value is on, or null if it is not a card value private: - wxDateTime old_time_modified; + wxDateTime old_time_modified; }; // ----------------------------------------------------------------------------- : Simple @@ -67,22 +67,22 @@ ValueAction* value_action(const PackageChoiceValueP& value, const String& /// An action that changes a TextValue class TextValueAction : public ValueAction { public: - TextValueAction(const TextValueP& value, size_t start, size_t end, size_t new_end, const Defaultable& new_value, const String& name); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - virtual bool merge(const Action& action); - - inline const String& newValue() const { return new_value(); } - - /// The modified selection - size_t selection_start, selection_end; + TextValueAction(const TextValueP& value, size_t start, size_t end, size_t new_end, const Defaultable& new_value, const String& name); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + virtual bool merge(const Action& action); + + inline const String& newValue() const { return new_value(); } + + /// The modified selection + size_t selection_start, selection_end; private: - inline TextValue& value() const; - - size_t new_selection_end; - Defaultable new_value; - String name; + inline TextValue& value() const; + + size_t new_selection_end; + Defaultable new_value; + String name; }; /// Action for toggling some formating tag on or off in some range @@ -97,15 +97,15 @@ TextValueAction* typing_action(const TextValueP& value, size_t start_i, size_t e /// Toggle reminder text for a keyword on or off class TextToggleReminderAction : public ValueAction { public: - TextToggleReminderAction(const TextValueP& value, size_t pos); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - - private: - size_t pos; ///< Position of "& new_value); - virtual void perform(bool to_undo); - bool merge(const SimpleTextValueAction& action); + SimpleTextValueAction(const Card* card, const TextValueP& value, const Defaultable& new_value); + virtual void perform(bool to_undo); + bool merge(const SimpleTextValueAction& action); private: - Defaultable new_value; + Defaultable new_value; }; /// An action from "Replace All"; just a bunch of value actions performed in sequence class ReplaceAllAction : public Action { public: - ~ReplaceAllAction(); - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - - vector actions; + ~ReplaceAllAction(); + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + + vector actions; }; // ----------------------------------------------------------------------------- : Event @@ -136,27 +136,27 @@ class ReplaceAllAction : public Action { /// Notification that a script caused a value to change class ScriptValueEvent : public Action { public: - inline ScriptValueEvent(const Card* card, const Value* value) : card(card), value(value) {} - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - - const Card* card; ///< Card the value is on - const Value* value; ///< The modified value + inline ScriptValueEvent(const Card* card, const Value* value) : card(card), value(value) {} + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + + const Card* card; ///< Card the value is on + const Value* value; ///< The modified value }; /// Notification that a script caused a style to change class ScriptStyleEvent : public Action { public: - inline ScriptStyleEvent(const StyleSheet* stylesheet, const Style* style) - : stylesheet(stylesheet), style(style) - {} - - virtual String getName(bool to_undo) const; - virtual void perform(bool to_undo); - - const StyleSheet* stylesheet; ///< StyleSheet the style is for - const Style* style; ///< The modified style + inline ScriptStyleEvent(const StyleSheet* stylesheet, const Style* style) + : stylesheet(stylesheet), style(style) + {} + + virtual String getName(bool to_undo) const; + virtual void perform(bool to_undo); + + const StyleSheet* stylesheet; ///< StyleSheet the style is for + const Style* style; ///< The modified style }; @@ -166,16 +166,16 @@ class ScriptStyleEvent : public Action { /** Used to reduce coupling */ class ValueActionPerformer { public: - ValueActionPerformer(const ValueP& value, Card* card, const SetP& set); - ~ValueActionPerformer(); - /// Perform an action. The performer takes ownerwhip of the action. - void addAction(ValueAction* action); - - const ValueP value; ///< The value - Package& getLocalPackage(); + ValueActionPerformer(const ValueP& value, Card* card, const SetP& set); + ~ValueActionPerformer(); + /// Perform an action. The performer takes ownerwhip of the action. + void addAction(ValueAction* action); + + const ValueP value; ///< The value + Package& getLocalPackage(); private: - Card* card; ///< Card the value is on (if any) - SetP set; ///< Set for the actions + Card* card; ///< Card the value is on (if any) + SetP set; ///< Set for the actions }; // ----------------------------------------------------------------------------- : EOF diff --git a/src/data/add_cards_script.cpp b/src/data/add_cards_script.cpp index bbcaea54..0e6bfff7 100644 --- a/src/data/add_cards_script.cpp +++ b/src/data/add_cards_script.cpp @@ -16,37 +16,37 @@ // ----------------------------------------------------------------------------- : AddCardsScript IMPLEMENT_REFLECTION_NO_SCRIPT(AddCardsScript) { - REFLECT(name); - REFLECT(description); - REFLECT(enabled); - REFLECT(script); + REFLECT(name); + REFLECT(description); + REFLECT(enabled); + REFLECT(script); } void AddCardsScript::perform(Set& set, vector& out) { - // Perform script - Context& ctx = set.getContext(); - ScriptValueP result = script.invoke(ctx); - // Add cards to out - ScriptValueP it = result->makeIterator(result); - while (ScriptValueP item = it->next()) { - CardP card = from_script(item); - // is this a new card? - if (contains(set.cards,card) || contains(out,card)) { - // make copy - card = intrusive(new Card(*card)); - } - out.push_back(card); - } + // Perform script + Context& ctx = set.getContext(); + ScriptValueP result = script.invoke(ctx); + // Add cards to out + ScriptValueP it = result->makeIterator(result); + while (ScriptValueP item = it->next()) { + CardP card = from_script(item); + // is this a new card? + if (contains(set.cards,card) || contains(out,card)) { + // make copy + card = intrusive(new Card(*card)); + } + out.push_back(card); + } } void AddCardsScript::perform(Set& set) { - // Perform script - vector cards; - perform(set,cards); - // Add to set - if (!cards.empty()) { - // TODO: change the name of the action somehow - set.actions.addAction(new AddCardAction(ADD, set, cards)); - } + // Perform script + vector cards; + perform(set,cards); + // Add to set + if (!cards.empty()) { + // TODO: change the name of the action somehow + set.actions.addAction(new AddCardAction(ADD, set, cards)); + } } diff --git a/src/data/add_cards_script.hpp b/src/data/add_cards_script.hpp index 019bded5..dd403f47 100644 --- a/src/data/add_cards_script.hpp +++ b/src/data/add_cards_script.hpp @@ -20,17 +20,17 @@ DECLARE_POINTER_TYPE(Card); /// A script to add one or more cards to a set class AddCardsScript : public IntrusivePtrBase { public: - String name; - String description; - Scriptable enabled; - OptionalScript script; - - /// Perform the script; return the cards (if any) - void perform(Set& set, vector& out); - /// Perform the script; add cards to the set - void perform(Set& set); - - DECLARE_REFLECTION(); + String name; + String description; + Scriptable enabled; + OptionalScript script; + + /// Perform the script; return the cards (if any) + void perform(Set& set, vector& out); + /// Perform the script; add cards to the set + void perform(Set& set); + + DECLARE_REFLECTION(); }; diff --git a/src/data/card.cpp b/src/data/card.cpp index e63c1f54..fb3a5ea0 100644 --- a/src/data/card.cpp +++ b/src/data/card.cpp @@ -21,73 +21,73 @@ DECLARE_TYPEOF_NO_REV(IndexMap); // ----------------------------------------------------------------------------- : Card Card::Card() - // for files made before we saved these times, set the time to 'yesterday' - : time_created (wxDateTime::Now().Subtract(wxDateSpan::Day()).ResetTime()) - , time_modified(wxDateTime::Now().Subtract(wxDateSpan::Day()).ResetTime()) - , has_styling(false) + // for files made before we saved these times, set the time to 'yesterday' + : time_created (wxDateTime::Now().Subtract(wxDateSpan::Day()).ResetTime()) + , time_modified(wxDateTime::Now().Subtract(wxDateSpan::Day()).ResetTime()) + , has_styling(false) { - if (!game_for_reading()) { - throw InternalError(_("game_for_reading not set")); - } - data.init(game_for_reading()->card_fields); + if (!game_for_reading()) { + throw InternalError(_("game_for_reading not set")); + } + data.init(game_for_reading()->card_fields); } Card::Card(const Game& game) - : time_created (wxDateTime::Now()) - , time_modified(wxDateTime::Now()) - , has_styling(false) + : time_created (wxDateTime::Now()) + , time_modified(wxDateTime::Now()) + , has_styling(false) { - data.init(game.card_fields); + data.init(game.card_fields); } String Card::identification() const { - // an identifying field - FOR_EACH_CONST(v, data) { - if (v->fieldP->identifying) { - return v->toString(); - } - } - // otherwise the first field - if (!data.empty()) { - return data.at(0)->toString(); - } else { - return wxEmptyString; - } + // an identifying field + FOR_EACH_CONST(v, data) { + if (v->fieldP->identifying) { + return v->toString(); + } + } + // otherwise the first field + if (!data.empty()) { + return data.at(0)->toString(); + } else { + return wxEmptyString; + } } bool Card::contains(String const& query) const { - FOR_EACH_CONST(v, data) { - if (find_i(v->toString(),query) != String::npos) return true; - } - if (find_i(notes,query) != String::npos) return true; - return false; + FOR_EACH_CONST(v, data) { + if (find_i(v->toString(),query) != String::npos) return true; + } + if (find_i(notes,query) != String::npos) return true; + return false; } IndexMap& Card::extraDataFor(const StyleSheet& stylesheet) { - return extra_data.get(stylesheet.name(), stylesheet.extra_card_fields); + return extra_data.get(stylesheet.name(), stylesheet.extra_card_fields); } void mark_dependency_member(const Card& card, const String& name, const Dependency& dep) { - mark_dependency_member(card.data, name, dep); + mark_dependency_member(card.data, name, dep); } IMPLEMENT_REFLECTION(Card) { - REFLECT(stylesheet); - REFLECT(has_styling); - if (has_styling) { - if (stylesheet) { - REFLECT_IF_READING styling_data.init(stylesheet->styling_fields); - REFLECT(styling_data); - } else if (stylesheet_for_reading()) { - REFLECT_IF_READING styling_data.init(stylesheet_for_reading()->styling_fields); - REFLECT(styling_data); - } else if (tag.reading()) { - has_styling = false; // We don't know the style, this can be because of copy/pasting - } - } - REFLECT(notes); - REFLECT(time_created); - REFLECT(time_modified); - REFLECT(extra_data); // don't allow scripts to depend on style specific data - REFLECT_NAMELESS(data); + REFLECT(stylesheet); + REFLECT(has_styling); + if (has_styling) { + if (stylesheet) { + REFLECT_IF_READING styling_data.init(stylesheet->styling_fields); + REFLECT(styling_data); + } else if (stylesheet_for_reading()) { + REFLECT_IF_READING styling_data.init(stylesheet_for_reading()->styling_fields); + REFLECT(styling_data); + } else if (tag.reading()) { + has_styling = false; // We don't know the style, this can be because of copy/pasting + } + } + REFLECT(notes); + REFLECT(time_created); + REFLECT(time_modified); + REFLECT(extra_data); // don't allow scripts to depend on style specific data + REFLECT_NAMELESS(data); } diff --git a/src/data/card.hpp b/src/data/card.hpp index eaf68558..a88ca21e 100644 --- a/src/data/card.hpp +++ b/src/data/card.hpp @@ -27,75 +27,75 @@ DECLARE_POINTER_TYPE(StyleSheet); /// A card from a card Set class Card : public IntrusivePtrVirtualBase { public: - /// Default constructor, uses game_for_new_cards to make the game - Card(); - /// Creates a card using the given game - Card(const Game& game); - - /// The values on the fields of the card. - /** The indices should correspond to the card_fields in the Game */ - IndexMap data; - /// Notes for this card - String notes; - /// Time the card was created/last modified - wxDateTime time_created, time_modified; - /// Alternative style to use for this card - /** Optional; if not set use the card style from the set */ - StyleSheetP stylesheet; - /// Alternative options to use for this card, for this card's stylesheet - /** Optional; if not set use the styling data from the set. - * If stylesheet is set then contains data for the this->stylesheet, otherwise for set->stylesheet - */ - IndexMap styling_data; - /// Is the styling_data set? - bool has_styling; - - /// Extra values for specitic stylesheets, indexed by stylesheet name - DelayedIndexMaps extra_data; - /// Styling information for a particular stylesheet - IndexMap& extraDataFor(const StyleSheet& stylesheet); - - /// Keyword usage statistics - vector > keyword_usage; - - /// Get the identification of this card, an identification is something like a name, title, etc. - /** May return "" */ - String identification() const; - /// Does any field contains the given query string? - bool contains(String const& query) const; - /// Does this card contain each of the words in the query string? - bool contains_words(String const& query) const; - - /// Find a value in the data by name and type - template T& value(const String& name) { - for(IndexMap::iterator it = data.begin() ; it != data.end() ; ++it) { - if ((*it)->fieldP->name == name) { - T* ret = dynamic_cast(it->get()); - if (!ret) throw InternalError(_("Card field with name '")+name+_("' doesn't have the right type")); - return *ret; - } - } - throw InternalError(_("Expected a card field with name '")+name+_("'")); - } - template const T& value(const String& name) const { - for(IndexMap::const_iterator it = data.begin() ; it != data.end() ; ++it) { - if ((*it)->fieldP->name == name) { - const T* ret = dynamic_cast(it->get()); - if (!ret) throw InternalError(_("Card field with name '")+name+_("' doesn't have the right type")); - return *ret; - } - } - throw InternalError(_("Expected a card field with name '")+name+_("'")); - } - - DECLARE_REFLECTION(); + /// Default constructor, uses game_for_new_cards to make the game + Card(); + /// Creates a card using the given game + Card(const Game& game); + + /// The values on the fields of the card. + /** The indices should correspond to the card_fields in the Game */ + IndexMap data; + /// Notes for this card + String notes; + /// Time the card was created/last modified + wxDateTime time_created, time_modified; + /// Alternative style to use for this card + /** Optional; if not set use the card style from the set */ + StyleSheetP stylesheet; + /// Alternative options to use for this card, for this card's stylesheet + /** Optional; if not set use the styling data from the set. + * If stylesheet is set then contains data for the this->stylesheet, otherwise for set->stylesheet + */ + IndexMap styling_data; + /// Is the styling_data set? + bool has_styling; + + /// Extra values for specitic stylesheets, indexed by stylesheet name + DelayedIndexMaps extra_data; + /// Styling information for a particular stylesheet + IndexMap& extraDataFor(const StyleSheet& stylesheet); + + /// Keyword usage statistics + vector > keyword_usage; + + /// Get the identification of this card, an identification is something like a name, title, etc. + /** May return "" */ + String identification() const; + /// Does any field contains the given query string? + bool contains(String const& query) const; + /// Does this card contain each of the words in the query string? + bool contains_words(String const& query) const; + + /// Find a value in the data by name and type + template T& value(const String& name) { + for(IndexMap::iterator it = data.begin() ; it != data.end() ; ++it) { + if ((*it)->fieldP->name == name) { + T* ret = dynamic_cast(it->get()); + if (!ret) throw InternalError(_("Card field with name '")+name+_("' doesn't have the right type")); + return *ret; + } + } + throw InternalError(_("Expected a card field with name '")+name+_("'")); + } + template const T& value(const String& name) const { + for(IndexMap::const_iterator it = data.begin() ; it != data.end() ; ++it) { + if ((*it)->fieldP->name == name) { + const T* ret = dynamic_cast(it->get()); + if (!ret) throw InternalError(_("Card field with name '")+name+_("' doesn't have the right type")); + return *ret; + } + } + throw InternalError(_("Expected a card field with name '")+name+_("'")); + } + + DECLARE_REFLECTION(); }; inline String type_name(const Card&) { - return _TYPE_("card"); + return _TYPE_("card"); } inline String type_name(const vector&) { - return _TYPE_("cards"); // not actually used, only for locale.pl script + return _TYPE_("cards"); // not actually used, only for locale.pl script } void mark_dependency_member(const Card& value, const String& name, const Dependency& dep); diff --git a/src/data/draw_what.hpp b/src/data/draw_what.hpp index bd72098e..4a8b0483 100644 --- a/src/data/draw_what.hpp +++ b/src/data/draw_what.hpp @@ -15,14 +15,14 @@ /// What should be drawn? enum DrawWhat -{ DRAW_NOTHING = 0x00 -, DRAW_NORMAL = 0x01 // draw normal things, like the text -, DRAW_BORDERS = 0x10 // draw editor stuff, such as borders/lines, can be disabled. -, DRAW_BOXES = 0x20 // draw editor stuff, such as borders/lines, can be disabled. -, DRAW_EDITING = 0x40 // draw other editor stuff, can be disabled. -, DRAW_ERRORS = 0x80 // draw error indicators, can't be disabled -, DRAW_ACTIVE = 0x100 // draw active editor stuff, such as hidden separators and atom highlights -, DRAW_NATIVELOOK = 0x200 // use a native look +{ DRAW_NOTHING = 0x00 +, DRAW_NORMAL = 0x01 // draw normal things, like the text +, DRAW_BORDERS = 0x10 // draw editor stuff, such as borders/lines, can be disabled. +, DRAW_BOXES = 0x20 // draw editor stuff, such as borders/lines, can be disabled. +, DRAW_EDITING = 0x40 // draw other editor stuff, can be disabled. +, DRAW_ERRORS = 0x80 // draw error indicators, can't be disabled +, DRAW_ACTIVE = 0x100 // draw active editor stuff, such as hidden separators and atom highlights +, DRAW_NATIVELOOK = 0x200 // use a native look }; // ----------------------------------------------------------------------------- : EOF diff --git a/src/data/export_template.cpp b/src/data/export_template.cpp index 34b1d5df..8d5f3544 100644 --- a/src/data/export_template.cpp +++ b/src/data/export_template.cpp @@ -15,8 +15,8 @@ // ----------------------------------------------------------------------------- : Export template, basics ExportTemplate::ExportTemplate() - : file_type(_("HTML files (*.html)|*.html")) - , create_directory(false) + : file_type(_("HTML files (*.html)|*.html")) + , create_directory(false) {} String ExportTemplate::typeNameStatic() { return _("export-template"); } @@ -24,23 +24,23 @@ String ExportTemplate::typeName() const { return _("export-template"); } Version ExportTemplate::fileVersion() const { return file_version_export_template; } void ExportTemplate::validate(Version) { - if (!game) { - throw Error(_ERROR_1_("no game specified",_TYPE_("export template"))); - } - // an export template depends on the game it is made for - requireDependency(game.get()); + if (!game) { + throw Error(_ERROR_1_("no game specified",_TYPE_("export template"))); + } + // an export template depends on the game it is made for + requireDependency(game.get()); } IMPLEMENT_REFLECTION(ExportTemplate) { - REFLECT_BASE(Packaged); - REFLECT(game); - REFLECT(file_type); - REFLECT(create_directory); - REFLECT(option_fields); - REFLECT_IF_READING option_style.init(option_fields); - REFLECT(option_style); - REFLECT(script); + REFLECT_BASE(Packaged); + REFLECT(game); + REFLECT(file_type); + REFLECT(create_directory); + REFLECT(option_fields); + REFLECT_IF_READING option_style.init(option_fields); + REFLECT(option_style); + REFLECT(script); } // ----------------------------------------------------------------------------- : ExportInfo diff --git a/src/data/export_template.hpp b/src/data/export_template.hpp index a7395b92..c8f26a8a 100644 --- a/src/data/export_template.hpp +++ b/src/data/export_template.hpp @@ -25,37 +25,37 @@ DECLARE_POINTER_TYPE(Package); /// A template for exporting sets to HTML or text format class ExportTemplate : public Packaged { public: - ExportTemplate(); - - GameP game; ///< Game this template is for - String file_type; ///< Type of the created file, in "name|*.ext" format - bool create_directory; ///< The export creates a directory for additional data files - vector option_fields; ///< Options for exporting - IndexMap option_style; ///< Style of the options - OptionalScript script; ///< Export script, for multi file templates and initialization - - static String typeNameStatic(); - virtual String typeName() const; - Version fileVersion() const; - virtual void validate(Version = app_version); + ExportTemplate(); + + GameP game; ///< Game this template is for + String file_type; ///< Type of the created file, in "name|*.ext" format + bool create_directory; ///< The export creates a directory for additional data files + vector option_fields; ///< Options for exporting + IndexMap option_style; ///< Style of the options + OptionalScript script; ///< Export script, for multi file templates and initialization + + static String typeNameStatic(); + virtual String typeName() const; + Version fileVersion() const; + virtual void validate(Version = app_version); private: - DECLARE_REFLECTION(); + DECLARE_REFLECTION(); }; // ----------------------------------------------------------------------------- : ExportInfo /// Information that can be used by export functions struct ExportInfo { - ExportInfo(); - - SetP set; ///< The set that is being exported - PackageP export_template; ///< The export template used - /// When using the CLI, this can be a fake package to allow reading from the cwd - String directory_relative; ///< The directory for storing extra files (or "" if !export->create_directory) - /// This is just the directory name - String directory_absolute; ///< The absolute path of the directory - map exported_images; ///< Images (from symbol font) already exported, and their size - bool allow_writes_outside; ///< Can files outside the directory be written to? + ExportInfo(); + + SetP set; ///< The set that is being exported + PackageP export_template; ///< The export template used + /// When using the CLI, this can be a fake package to allow reading from the cwd + String directory_relative; ///< The directory for storing extra files (or "" if !export->create_directory) + /// This is just the directory name + String directory_absolute; ///< The absolute path of the directory + map exported_images; ///< Images (from symbol font) already exported, and their size + bool allow_writes_outside; ///< Can files outside the directory be written to? }; DECLARE_DYNAMIC_ARG(ExportInfo*, export_info); diff --git a/src/data/field.cpp b/src/data/field.cpp index f2082bf7..bc829ae4 100644 --- a/src/data/field.cpp +++ b/src/data/field.cpp @@ -24,239 +24,239 @@ DECLARE_TYPEOF_COLLECTION(StyleListener*); // ----------------------------------------------------------------------------- : Field Field::Field() - : index (0) // sensible default? - , editable (true) - , save_value (true) - , show_statistics (true) - , position_hint (0) - , identifying (false) - , card_list_column (100) - , card_list_width (100) - , card_list_visible(false) - , card_list_allow (true) - , card_list_align (ALIGN_LEFT) - , tab_index (0) + : index (0) // sensible default? + , editable (true) + , save_value (true) + , show_statistics (true) + , position_hint (0) + , identifying (false) + , card_list_column (100) + , card_list_width (100) + , card_list_visible(false) + , card_list_allow (true) + , card_list_align (ALIGN_LEFT) + , tab_index (0) {} Field::~Field() {} void Field::initDependencies(Context& ctx, const Dependency& dep) const { - sort_script.initDependencies(ctx, dep); + sort_script.initDependencies(ctx, dep); } IMPLEMENT_REFLECTION(Field) { - REFLECT_IF_NOT_READING { - String type = typeName(); - REFLECT(type); - } - REFLECT(name); - REFLECT_IF_READING name = canonical_name_form(name); - REFLECT(description); - REFLECT_N("icon", icon_filename); - REFLECT(editable); - REFLECT(save_value); - REFLECT(show_statistics); - REFLECT(position_hint); - REFLECT(identifying); - REFLECT(card_list_column); - REFLECT(card_list_width); - REFLECT(card_list_visible); - REFLECT(card_list_allow); - REFLECT(card_list_name); - REFLECT(sort_script); - REFLECT_IF_READING if(card_list_name.empty()) card_list_name = name; - REFLECT_N("card_list_alignment", card_list_align); - REFLECT(tab_index); + REFLECT_IF_NOT_READING { + String type = typeName(); + REFLECT(type); + } + REFLECT(name); + REFLECT_IF_READING name = canonical_name_form(name); + REFLECT(description); + REFLECT_N("icon", icon_filename); + REFLECT(editable); + REFLECT(save_value); + REFLECT(show_statistics); + REFLECT(position_hint); + REFLECT(identifying); + REFLECT(card_list_column); + REFLECT(card_list_width); + REFLECT(card_list_visible); + REFLECT(card_list_allow); + REFLECT(card_list_name); + REFLECT(sort_script); + REFLECT_IF_READING if(card_list_name.empty()) card_list_name = name; + REFLECT_N("card_list_alignment", card_list_align); + REFLECT(tab_index); } template <> intrusive_ptr read_new(Reader& reader) { - // there must be a type specified - String type; - reader.handle(_("type"), type); - if (type == _("text")) return intrusive(new TextField()); - else if (type == _("choice")) return intrusive(new ChoiceField()); - else if (type == _("multiple choice")) return intrusive(new MultipleChoiceField()); - else if (type == _("boolean")) return intrusive(new BooleanField()); - else if (type == _("image")) return intrusive(new ImageField()); - else if (type == _("symbol")) return intrusive(new SymbolField()); - else if (type == _("color")) return intrusive(new ColorField()); - else if (type == _("info")) return intrusive(new InfoField()); - else if (type == _("package choice")) return intrusive(new PackageChoiceField()); - else if (type.empty()) { - reader.warning(_ERROR_1_("expected key", _("type"))); - throw ParseError(_ERROR_("aborting parsing")); - } else { - reader.warning(_ERROR_1_("unsupported field type", type)); - throw ParseError(_ERROR_("aborting parsing")); - } + // there must be a type specified + String type; + reader.handle(_("type"), type); + if (type == _("text")) return intrusive(new TextField()); + else if (type == _("choice")) return intrusive(new ChoiceField()); + else if (type == _("multiple choice")) return intrusive(new MultipleChoiceField()); + else if (type == _("boolean")) return intrusive(new BooleanField()); + else if (type == _("image")) return intrusive(new ImageField()); + else if (type == _("symbol")) return intrusive(new SymbolField()); + else if (type == _("color")) return intrusive(new ColorField()); + else if (type == _("info")) return intrusive(new InfoField()); + else if (type == _("package choice")) return intrusive(new PackageChoiceField()); + else if (type.empty()) { + reader.warning(_ERROR_1_("expected key", _("type"))); + throw ParseError(_ERROR_("aborting parsing")); + } else { + reader.warning(_ERROR_1_("unsupported field type", type)); + throw ParseError(_ERROR_("aborting parsing")); + } } // ----------------------------------------------------------------------------- : Style Style::Style(const FieldP& field) - : fieldP(field) - , z_index(0) - , left (1000000), top (1000000) - , width(0), height(0) - , right(1000000), bottom(1000000) - , angle(0) - , visible(true) - , automatic_side(AUTO_UNKNOWN) - , content_dependent(false) + : fieldP(field) + , z_index(0) + , left (1000000), top (1000000) + , width(0), height(0) + , right(1000000), bottom(1000000) + , angle(0) + , visible(true) + , automatic_side(AUTO_UNKNOWN) + , content_dependent(false) {} Style::~Style() {} IMPLEMENT_REFLECTION(Style) { - REFLECT(z_index); - REFLECT(left); - REFLECT(width); - REFLECT(right); - REFLECT(top); - REFLECT(height); - REFLECT(bottom); - REFLECT(angle); - REFLECT(visible); - REFLECT(mask); + REFLECT(z_index); + REFLECT(left); + REFLECT(width); + REFLECT(right); + REFLECT(top); + REFLECT(height); + REFLECT(bottom); + REFLECT(angle); + REFLECT(visible); + REFLECT(mask); } void init_object(const FieldP& field, StyleP& style) { - if (!style) style = field->newStyle(field); + if (!style) style = field->newStyle(field); } template <> StyleP read_new