diff --git a/src/data/action/value.cpp b/src/data/action/value.cpp index de85cd79..aa2ea199 100644 --- a/src/data/action/value.cpp +++ b/src/data/action/value.cpp @@ -17,6 +17,7 @@ #include #include #include +#include // for ValueActionPerformer // ----------------------------------------------------------------------------- : ValueAction @@ -24,6 +25,10 @@ String ValueAction::getName(bool to_undo) const { return _ACTION_1_("change", valueP->fieldP->name); } +void ValueAction::isOnCard(Card* card) { + const_cast(this)->card = card; +} + // ----------------------------------------------------------------------------- : Simple /// Swap the value in a Value object with a new one @@ -42,8 +47,8 @@ inline void swap_value(MultipleChoiceValue& a, MultipleChoiceValue::ValueType& b template class SimpleValueAction : public ValueAction { public: - inline SimpleValueAction(const Card* card, const intrusive_ptr& value, const typename T::ValueType& new_value) - : ValueAction(card, value), new_value(new_value) + inline SimpleValueAction(const intrusive_ptr& value, const typename T::ValueType& new_value) + : ValueAction(value), new_value(new_value) {} virtual void perform(bool to_undo) { @@ -67,21 +72,21 @@ class SimpleValueAction : public ValueAction { typename T::ValueType new_value; }; -ValueAction* value_action(const Card* card, const ChoiceValueP& value, const Defaultable& new_value) { return new SimpleValueAction (card, value, new_value); } -ValueAction* value_action(const Card* card, const ColorValueP& value, const Defaultable& new_value) { return new SimpleValueAction (card, value, new_value); } -ValueAction* value_action(const Card* card, const ImageValueP& value, const FileName& new_value) { return new SimpleValueAction(card, value, new_value); } -ValueAction* value_action(const Card* card, const SymbolValueP& value, const FileName& new_value) { return new SimpleValueAction(card, value, new_value); } -ValueAction* value_action(const Card* card, const PackageChoiceValueP& value, const String& new_value) { return new SimpleValueAction(card, value, new_value); } -ValueAction* value_action(const Card* card, const MultipleChoiceValueP& value, const Defaultable& new_value, const String& last_change) { +ValueAction* value_action(const ChoiceValueP& value, const Defaultable& new_value) { return new SimpleValueAction (value, new_value); } +ValueAction* value_action(const ColorValueP& value, const Defaultable& new_value) { return new SimpleValueAction (value, new_value); } +ValueAction* value_action(const ImageValueP& value, const FileName& new_value) { return new SimpleValueAction(value, new_value); } +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(card, value, v); + return new SimpleValueAction(value, v); } // ----------------------------------------------------------------------------- : Text -TextValueAction::TextValueAction(const Card* card, const TextValueP& value, size_t start, size_t end, size_t new_end, const Defaultable& new_value, const String& name) - : ValueAction(card, value) +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) @@ -111,7 +116,7 @@ TextValue& TextValueAction::value() const { } -TextValueAction* toggle_format_action(const Card* card, const TextValueP& value, const String& tag, size_t start_i, size_t end_i, size_t start, size_t end, const String& action_name) { +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); @@ -144,11 +149,11 @@ TextValueAction* toggle_format_action(const Card* card, const TextValueP& value, if (value->value() == new_value) { return nullptr; // no changes } else { - return new TextValueAction(card, value, start, end, end, new_value, action_name); + return new TextValueAction(value, start, end, end, new_value, action_name); } } -TextValueAction* typing_action(const Card* card, const TextValueP& value, size_t start_i, size_t end_i, size_t start, size_t end, const String& replacement, const String& 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); @@ -160,17 +165,17 @@ TextValueAction* typing_action(const Card* card, const TextValueP& value, size_t return nullptr; } else { if (reverse) { - return new TextValueAction(card, value, end, start, start+untag(replacement).size(), new_value, action_name); + return new TextValueAction(value, end, start, start+untag(replacement).size(), new_value, action_name); } else { - return new TextValueAction(card, value, start, end, start+untag(replacement).size(), new_value, action_name); + return new TextValueAction(value, start, end, start+untag(replacement).size(), new_value, action_name); } } } // ----------------------------------------------------------------------------- : Reminder text -TextToggleReminderAction::TextToggleReminderAction(const Card* card, const TextValueP& value, size_t pos_in) - : ValueAction(card, value) +TextToggleReminderAction::TextToggleReminderAction(const TextValueP& value, size_t pos_in) + : ValueAction(value) { pos = in_tag(value->value(), _("isOnCard(card); + set->actions.addAction(action); +} + +Package& ValueActionPerformer::getLocalPackage() { + return *set; +} diff --git a/src/data/action/value.hpp b/src/data/action/value.hpp index 10119884..9cf23076 100644 --- a/src/data/action/value.hpp +++ b/src/data/action/value.hpp @@ -20,6 +20,7 @@ class Card; class StyleSheet; +DECLARE_POINTER_TYPE(Set); DECLARE_POINTER_TYPE(Value); DECLARE_POINTER_TYPE(Style); DECLARE_POINTER_TYPE(TextValue); @@ -35,10 +36,13 @@ DECLARE_POINTER_TYPE(PackageChoiceValue); /// An Action the changes a Value class ValueAction : public Action { public: - inline ValueAction(const Card* card, const ValueP& value) : valueP(value), card(card) {} + inline ValueAction(const ValueP& value) : valueP(value), card(nullptr) {} virtual String getName(bool to_undo) const; + /// 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 }; @@ -46,19 +50,19 @@ class ValueAction : public Action { // ----------------------------------------------------------------------------- : Simple /// Action that updates a Value to a new value -ValueAction* value_action(const Card* card, const ChoiceValueP& value, const Defaultable& new_value); -ValueAction* value_action(const Card* card, const MultipleChoiceValueP& value, const Defaultable& new_value, const String& last_change); -ValueAction* value_action(const Card* card, const ColorValueP& value, const Defaultable& new_value); -ValueAction* value_action(const Card* card, const ImageValueP& value, const FileName& new_value); -ValueAction* value_action(const Card* card, const SymbolValueP& value, const FileName& new_value); -ValueAction* value_action(const Card* card, const PackageChoiceValueP& value, const String& new_value); +ValueAction* value_action(const ChoiceValueP& value, const Defaultable& new_value); +ValueAction* value_action(const MultipleChoiceValueP& value, const Defaultable& new_value, const String& last_change); +ValueAction* value_action(const ColorValueP& value, const Defaultable& new_value); +ValueAction* value_action(const ImageValueP& value, const FileName& new_value); +ValueAction* value_action(const SymbolValueP& value, const FileName& new_value); +ValueAction* value_action(const PackageChoiceValueP& value, const String& new_value); // ----------------------------------------------------------------------------- : Text /// An action that changes a TextValue class TextValueAction : public ValueAction { public: - TextValueAction(const Card* card, const TextValueP& value, size_t start, size_t end, size_t new_end, const Defaultable& new_value, const String& name); + 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); @@ -77,18 +81,18 @@ class TextValueAction : public ValueAction { }; /// Action for toggling some formating tag on or off in some range -TextValueAction* toggle_format_action(const Card* card, const TextValueP& value, const String& tag, size_t start_i, size_t end_i, size_t start, size_t end, const String& action_name); +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); /// Typing in a TextValue, replace the selection [start...end) with replacement /** start and end are cursor positions, start_i and end_i are indices*/ -TextValueAction* typing_action(const Card* card, const TextValueP& value, size_t start_i, size_t end_i, size_t start, size_t end, const String& replacement, const String& 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); // ----------------------------------------------------------------------------- : Reminder text /// Toggle reminder text for a keyword on or off class TextToggleReminderAction : public ValueAction { public: - TextToggleReminderAction(const Card* card, const TextValueP& value, size_t pos); + TextToggleReminderAction(const TextValueP& value, size_t pos); virtual String getName(bool to_undo) const; virtual void perform(bool to_undo); @@ -150,5 +154,24 @@ class ScriptStyleEvent : public Action { const Style* style; ///< The modified style }; + +// ----------------------------------------------------------------------------- : Action performer + +/// A loose object for performing ValueActions on a certain value. +/** 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(); + private: + Card* card; ///< Card the value is on (if any) + SetP set; ///< Set for the actions +}; + // ----------------------------------------------------------------------------- : EOF #endif diff --git a/src/data/locale.cpp b/src/data/locale.cpp index 6ade651a..8e0b26f3 100644 --- a/src/data/locale.cpp +++ b/src/data/locale.cpp @@ -96,6 +96,7 @@ String tr(LocaleCategory cat, const String& key, DefaultLocaleFun def) { return loc->tr(subcat, key, def); \ } +IMPLEMENT_TR_TYPE(Package, game_translations) //%% TODO! IMPLEMENT_TR_TYPE(Game, game_translations) IMPLEMENT_TR_TYPE(StyleSheet, stylesheet_translations) IMPLEMENT_TR_TYPE(SymbolFont, symbol_font_translations) diff --git a/src/data/set.hpp b/src/data/set.hpp index 0fdedb41..25799b39 100644 --- a/src/data/set.hpp +++ b/src/data/set.hpp @@ -149,7 +149,7 @@ class SetView : public ActionListener { ~SetView(); /// Get the set that is currently being viewed - inline SetP getSet() { return set; } + //inline SetP getSet() const { return set; } /// Change the set that is being viewed void setSet(const SetP& set); diff --git a/src/gui/control/card_editor.cpp b/src/gui/control/card_editor.cpp index 8c168f1a..f045b691 100644 --- a/src/gui/control/card_editor.cpp +++ b/src/gui/control/card_editor.cpp @@ -60,6 +60,10 @@ ValueViewer* DataEditor::focusedViewer() const { return FindFocus() == this ? current_viewer : nullptr; } +void DataEditor::addAction(Action* action) { + set->actions.addAction(action); +} + // ----------------------------------------------------------------------------- : Selection bool DataEditor::AcceptsFocus() const { diff --git a/src/gui/control/card_editor.hpp b/src/gui/control/card_editor.hpp index 76266bd7..0466f78b 100644 --- a/src/gui/control/card_editor.hpp +++ b/src/gui/control/card_editor.hpp @@ -22,7 +22,7 @@ class DataEditor : public CardViewer { public: DataEditor(Window* parent, int id, long style = 0); - // --------------------------------------------------- : Utility for ValueViewers + // --------------------------------------------------- : Utility for ValueViewers/Editors virtual bool drawBorders() const; virtual bool drawEditing() const; @@ -30,6 +30,9 @@ class DataEditor : public CardViewer { virtual wxPen borderPen(bool active) const; virtual ValueViewer* focusedViewer() const; + virtual void addAction(Action* action); + inline SetP getSetForActions() { return set; } + // --------------------------------------------------- : Selection /// Select the given viewer, sends focus events diff --git a/src/gui/control/card_list.cpp b/src/gui/control/card_list.cpp index 1ed39646..0467dded 100644 --- a/src/gui/control/card_list.cpp +++ b/src/gui/control/card_list.cpp @@ -162,7 +162,7 @@ bool CardListBase::doPaste() { ok = data.getCards(set, new_cards); if (!ok) return false; // add card to set - set->actions.add(new AddCardAction(ADD, *set, new_cards)); + set->actions.addAction(new AddCardAction(ADD, *set, new_cards)); return true; } bool CardListBase::doDelete() { @@ -176,7 +176,7 @@ bool CardListBase::doDelete() { } if (cards_to_delete.empty()) return false; // delete cards - set->actions.add(new AddCardAction(REMOVE, *set, cards_to_delete)); + set->actions.addAction(new AddCardAction(REMOVE, *set, cards_to_delete)); return true; } @@ -345,7 +345,7 @@ void CardListBase::onDrag(wxMouseEvent& ev) { findSelectedItemPos(); if (item != selected_item_pos) { // move card in the set - set->actions.add(new ReorderCardsAction(*set, item, selected_item_pos)); + set->actions.addAction(new ReorderCardsAction(*set, item, selected_item_pos)); } } } diff --git a/src/gui/control/keyword_list.cpp b/src/gui/control/keyword_list.cpp index b1e9098f..d5864adc 100644 --- a/src/gui/control/keyword_list.cpp +++ b/src/gui/control/keyword_list.cpp @@ -96,9 +96,9 @@ void KeywordList::updateUsageStatistics() { // ----------------------------------------------------------------------------- : Clipboard -bool KeywordList::canCopy() const { return !!selected_item; } -bool KeywordList::canCut() const { return canCopy() && !getKeyword()->fixed; } -bool KeywordList::canPaste() const { +bool KeywordList::canDelete() const { return !getKeyword()->fixed; } +bool KeywordList::canCopy() const { return !!selected_item; } +bool KeywordList::canPaste() const { return wxTheClipboard->IsSupported(KeywordDataObject::format); } @@ -127,14 +127,14 @@ bool KeywordList::doPaste() { // add keyword to set KeywordP keyword = data.getKeyword(set); if (keyword) { - set->actions.add(new AddKeywordAction(ADD, *set, keyword)); + set->actions.addAction(new AddKeywordAction(ADD, *set, keyword)); return true; } else { return false; } } bool KeywordList::doDelete() { - set->actions.add(new AddKeywordAction(REMOVE, *set, getKeyword())); + set->actions.addAction(new AddKeywordAction(REMOVE, *set, getKeyword())); return true; } diff --git a/src/gui/control/keyword_list.hpp b/src/gui/control/keyword_list.hpp index 92057bcc..46440e85 100644 --- a/src/gui/control/keyword_list.hpp +++ b/src/gui/control/keyword_list.hpp @@ -53,9 +53,9 @@ class KeywordList : public ItemList, public SetView { // --------------------------------------------------- : Clipboard - bool canCut() const; - bool canCopy() const; - bool canPaste() const; + bool canDelete() const; + bool canCopy() const; + bool canPaste() const; // Try to perform a clipboard operation, return success bool doCut(); bool doCopy(); diff --git a/src/gui/control/native_look_editor.cpp b/src/gui/control/native_look_editor.cpp index e36a6c57..ea40c6ab 100644 --- a/src/gui/control/native_look_editor.cpp +++ b/src/gui/control/native_look_editor.cpp @@ -205,6 +205,12 @@ void SetInfoEditor::onChangeSet() { setData(set->data); } +Package& SetInfoEditor::getStylePackage() const { + return DataEditor::getStylePackage(); + // TODO: Use the game + //return getGame(); +} + // ----------------------------------------------------------------------------- : StylingEditor StylingEditor::StylingEditor(Window* parent, int id, long style) @@ -232,7 +238,11 @@ ExportOptionsEditor::ExportOptionsEditor(Window* parent, int id, long style) {} void ExportOptionsEditor::showExport(const ExportTemplateP& export_template) { + this->export_template = export_template; setStyles(set->stylesheet, export_template->option_style); setData(settings.exportOptionsFor(*export_template)); } +Package& ExportOptionsEditor::getStylePackage() const { + return *export_template; +} diff --git a/src/gui/control/native_look_editor.hpp b/src/gui/control/native_look_editor.hpp index 111e5e75..951c3c37 100644 --- a/src/gui/control/native_look_editor.hpp +++ b/src/gui/control/native_look_editor.hpp @@ -58,6 +58,8 @@ class NativeLookEditor : public DataEditor { class SetInfoEditor : public NativeLookEditor { public: SetInfoEditor(Window* parent, int id, long style = 0); + + virtual Package& getStylePackage() const; protected: virtual void onChangeSet(); }; @@ -73,7 +75,6 @@ class StylingEditor : public NativeLookEditor { void showStylesheet(const StyleSheetP& stylesheet); /// Show the styling for given card void showCard(const CardP& card); - protected: virtual void onChangeSet(); }; @@ -87,6 +88,10 @@ class ExportOptionsEditor : public NativeLookEditor { /// Show the options for given export template void showExport(const ExportTemplateP& export_template); + + virtual Package& getStylePackage() const; + private: + ExportTemplateP export_template; }; // ----------------------------------------------------------------------------- : EOF diff --git a/src/gui/set/cards_panel.cpp b/src/gui/set/cards_panel.cpp index 7e84d553..bf8e238c 100644 --- a/src/gui/set/cards_panel.cpp +++ b/src/gui/set/cards_panel.cpp @@ -207,7 +207,7 @@ void CardsPanel::onCommand(int id) { card_list->selectNext(); break; case ID_CARD_ADD: - set->actions.add(new AddCardAction(*set)); + set->actions.addAction(new AddCardAction(*set)); break; case ID_CARD_REMOVE: card_list->doDelete(); diff --git a/src/gui/set/keywords_panel.cpp b/src/gui/set/keywords_panel.cpp index b1ebb795..fbab9459 100644 --- a/src/gui/set/keywords_panel.cpp +++ b/src/gui/set/keywords_panel.cpp @@ -154,12 +154,12 @@ void KeywordsPanel::onCommand(int id) { list->selectNext(); break; case ID_KEYWORD_ADD: - set->actions.add(new AddKeywordAction(*set)); + set->actions.addAction(new AddKeywordAction(*set)); break; case ID_KEYWORD_REMOVE: - if (!list->getKeyword()->fixed) { + if (list->canDelete()) { // only remove set keywords - set->actions.add(new AddKeywordAction(REMOVE, *set, list->getKeyword())); + list->doDelete(); } break; case ID_KEYWORD_ADD_PARAM: { @@ -336,7 +336,7 @@ void KeywordsPanel::onModeChange(wxCommandEvent& ev) { if (!list->getKeyword()) return; int sel = mode->GetSelection(); if (sel >= 0 && (size_t)sel < set->game->keyword_modes.size()) { - set->actions.add(new ChangeKeywordModeAction(*list->getKeyword(), set->game->keyword_modes[sel]->name)); + set->actions.addAction(new ChangeKeywordModeAction(*list->getKeyword(), set->game->keyword_modes[sel]->name)); } } diff --git a/src/gui/set/random_pack_panel.cpp b/src/gui/set/random_pack_panel.cpp new file mode 100644 index 00000000..0dd1170b --- /dev/null +++ b/src/gui/set/random_pack_panel.cpp @@ -0,0 +1,58 @@ +//+----------------------------------------------------------------------------+ +//| Description: Magic Set Editor - Program to make Magic (tm) cards | +//| Copyright: (C) 2001 - 2008 Twan van Laarhoven and "coppro" | +//| License: GNU General Public License 2 or later (see file COPYING) | +//+----------------------------------------------------------------------------+ + +// ----------------------------------------------------------------------------- : Includes + +#include +#include +#include +#include + +// ----------------------------------------------------------------------------- : RandomPackPanel + +RandomPackPanel::RandomPackPanel(Window* parent, int id) + : SetWindowPanel(parent, id) +{ + // init controls + preview = new CardViewer(this, wxID_ANY); + card_list = new FilteredCardList(this, wxID_ANY); + // init sizer + wxSizer* s = new wxBoxSizer(wxHORIZONTAL); + s->Add(preview, 0, wxRIGHT, 2); + wxSizer* s2 = new wxBoxSizer(wxVERTICAL); + s2->Add(card_list, 1, wxEXPAND | wxTOP, 4); + s->Add(s2, 1, wxEXPAND, 8); + s->SetSizeHints(this); + SetSizer(s); +} + +void RandomPackPanel::onChangeSet() { + preview ->setSet(set); + card_list->setSet(set); +} + +// ----------------------------------------------------------------------------- : UI + +void RandomPackPanel::initUI(wxToolBar* tb, wxMenuBar* mb) { + // ? +} + +void RandomPackPanel::destroyUI(wxToolBar* tb, wxMenuBar* mb) { + // ? +} + +void RandomPackPanel::onUpdateUI(wxUpdateUIEvent& ev) { + // ? +} + +void RandomPackPanel::onCommand(int id) { + // ? +} + +// ----------------------------------------------------------------------------- : Clipboard + +bool RandomPackPanel::canCopy() const { return card_list->canCopy(); } +void RandomPackPanel::doCopy() { card_list->doCopy(); } diff --git a/src/gui/set/random_pack_panel.hpp b/src/gui/set/random_pack_panel.hpp new file mode 100644 index 00000000..5f98f8a4 --- /dev/null +++ b/src/gui/set/random_pack_panel.hpp @@ -0,0 +1,45 @@ +//+----------------------------------------------------------------------------+ +//| Description: Magic Set Editor - Program to make Magic (tm) cards | +//| Copyright: (C) 2001 - 2008 Twan van Laarhoven and "coppro" | +//| License: GNU General Public License 2 or later (see file COPYING) | +//+----------------------------------------------------------------------------+ + +#ifndef HEADER_GUI_SET_RANDOM_PACK_PANEL +#define HEADER_GUI_SET_RANDOM_PACK_PANEL + +// ----------------------------------------------------------------------------- : Includes + +#include +#include + +class CardViewer; +class FilteredCardList; + +// ----------------------------------------------------------------------------- : RandomPackPanel + +/// A SetWindowPanel for creating random booster packs +class RandomPackPanel : public SetWindowPanel { + public: + RandomPackPanel(Window* parent, int id); + + // --------------------------------------------------- : UI + + virtual void onChangeSet(); + + virtual void initUI (wxToolBar* tb, wxMenuBar* mb); + virtual void destroyUI(wxToolBar* tb, wxMenuBar* mb); + virtual void onUpdateUI(wxUpdateUIEvent&); + virtual void onCommand(int id); + + // --------------------------------------------------- : Clipboard + + virtual bool canCopy() const; + virtual void doCopy(); + + private: + CardViewer* preview; ///< Card preview + FilteredCardList* card_list; ///< The list of cards +}; + +// ----------------------------------------------------------------------------- : EOF +#endif diff --git a/src/gui/set/style_panel.cpp b/src/gui/set/style_panel.cpp index 4f1770a2..3a80ba34 100644 --- a/src/gui/set/style_panel.cpp +++ b/src/gui/set/style_panel.cpp @@ -131,18 +131,18 @@ void StylePanel::onStyleSelect(wxCommandEvent&) { // select no special style when selecting the same style as the set default stylesheet = StyleSheetP(); } - set->actions.add(new ChangeCardStyleAction(card, stylesheet)); + set->actions.addAction(new ChangeCardStyleAction(card, stylesheet)); Layout(); } } void StylePanel::onUseForAll(wxCommandEvent&) { - set->actions.add(new ChangeSetStyleAction(*set, card)); + set->actions.addAction(new ChangeSetStyleAction(*set, card)); Layout(); } void StylePanel::onUseCustom(wxCommandEvent&) { - set->actions.add(new ChangeCardHasStylingAction(*set, card)); + set->actions.addAction(new ChangeCardHasStylingAction(*set, card)); } BEGIN_EVENT_TABLE(StylePanel, wxPanel) diff --git a/src/gui/symbol/basic_shape_editor.cpp b/src/gui/symbol/basic_shape_editor.cpp index c191836b..1f2f6e7f 100644 --- a/src/gui/symbol/basic_shape_editor.cpp +++ b/src/gui/symbol/basic_shape_editor.cpp @@ -100,7 +100,7 @@ void SymbolBasicShapeEditor::onLeftDown (const Vector2D& pos, wxMouseEvent& ev void SymbolBasicShapeEditor::onLeftUp (const Vector2D& pos, wxMouseEvent& ev) { if (drawing && shape) { // Finalize the shape - getSymbol()->actions.add(new AddSymbolPartAction(*getSymbol(), shape)); + addAction(new AddSymbolPartAction(*getSymbol(), shape)); // Select the part control.selectPart(shape); // no need to clean up, this editor is replaced diff --git a/src/gui/symbol/editor.cpp b/src/gui/symbol/editor.cpp index 0e6abfef..58ac0a77 100644 --- a/src/gui/symbol/editor.cpp +++ b/src/gui/symbol/editor.cpp @@ -15,3 +15,7 @@ void SymbolEditorBase::SetStatusText(const String& text) { control.parent->SetStatusText(text); } + +void SymbolEditorBase::addAction(Action* action, bool allow_merge) { + getSymbol()->actions.addAction(action, allow_merge); +} diff --git a/src/gui/symbol/editor.hpp b/src/gui/symbol/editor.hpp index c4f758c4..4affb580 100644 --- a/src/gui/symbol/editor.hpp +++ b/src/gui/symbol/editor.hpp @@ -28,6 +28,10 @@ class SymbolEditorBase : public IntrusivePtrVirtualBase { SymbolControl& control; inline SymbolP getSymbol() { return control.getSymbol(); } + + /// Perform an action + void addAction(Action* action, bool allow_merge = true); + void SetStatusText(const String& text); public: diff --git a/src/gui/symbol/part_list.cpp b/src/gui/symbol/part_list.cpp index c0d536f6..c53d619c 100644 --- a/src/gui/symbol/part_list.cpp +++ b/src/gui/symbol/part_list.cpp @@ -166,9 +166,9 @@ void SymbolPartList::onLeftUp(wxMouseEvent& ev) { if (par != drop_parent && par->parts.size() == 1 && !par->isSymbolSymmetry()) { // this leaves a group without elements, remove it findParent(*par, par, drag_position); // parent of the group - symbol->actions.add(new UngroupReorderSymbolPartsAction(*par, drag_position, *drop_parent, drop_position)); + symbol->actions.addAction(new UngroupReorderSymbolPartsAction(*par, drag_position, *drop_parent, drop_position)); } else { - symbol->actions.add(new ReorderSymbolPartsAction(*par, drag_position, *drop_parent, drop_position)); + symbol->actions.addAction(new ReorderSymbolPartsAction(*par, drag_position, *drop_parent, drop_position)); } } else { Refresh(false); @@ -253,14 +253,14 @@ void SymbolPartList::onChar(wxKeyEvent& ev) { if (cursor > 0 && cursor <= typing_in->name.size()) { String new_name = typing_in->name; new_name.erase(cursor - 1, 1); - symbol->actions.add(new SymbolPartNameAction(typing_in, new_name, cursor, cursor - 1)); + symbol->actions.addAction(new SymbolPartNameAction(typing_in, new_name, cursor, cursor - 1)); } break; case WXK_DELETE: if (cursor < typing_in->name.size()) { String new_name = typing_in->name; new_name.erase(cursor, 1); - symbol->actions.add(new SymbolPartNameAction(typing_in, new_name, cursor, cursor)); + symbol->actions.addAction(new SymbolPartNameAction(typing_in, new_name, cursor, cursor)); } break; default: @@ -277,7 +277,7 @@ void SymbolPartList::onChar(wxKeyEvent& ev) { #endif String new_name = typing_in->name; new_name.insert(cursor, 1, key); - symbol->actions.add(new SymbolPartNameAction(typing_in, new_name, cursor, cursor + 1)); + symbol->actions.addAction(new SymbolPartNameAction(typing_in, new_name, cursor, cursor + 1)); } } } diff --git a/src/gui/symbol/point_editor.cpp b/src/gui/symbol/point_editor.cpp index 4165d878..8aeee361 100644 --- a/src/gui/symbol/point_editor.cpp +++ b/src/gui/symbol/point_editor.cpp @@ -254,7 +254,7 @@ void SymbolPointEditor::onLeftDClick(const Vector2D& pos, wxMouseEvent& ev) { if (hovering == SELECTED_NEW_POINT) { // Add point ControlPointAddAction* act = new ControlPointAddAction(part, hover_line_1_idx, hover_line_t); - getSymbol()->actions.add(act); + addAction(act); // select the new point selectPoint(act->getNewPoint(), false); selection = SELECTED_POINTS; @@ -262,7 +262,7 @@ void SymbolPointEditor::onLeftDClick(const Vector2D& pos, wxMouseEvent& ev) { // Delete point selected_points.clear(); selectPoint(hover_handle.point, false); - getSymbol()->actions.add(control_point_remove_action(part, selected_points)); + addAction(control_point_remove_action(part, selected_points)); selected_points.clear(); selection = SELECTED_NONE; } @@ -288,7 +288,7 @@ void SymbolPointEditor::onMouseDrag(const Vector2D& from, const Vector2D& to, wx if (controlPointMoveAction) controlPointMoveAction = 0; if (!curveDragAction) { curveDragAction = new CurveDragAction(selected_line1, selected_line2); - getSymbol()->actions.add(curveDragAction); + addAction(curveDragAction); } curveDragAction->move(delta, selected_line_t); control.Refresh(false); @@ -298,7 +298,7 @@ void SymbolPointEditor::onMouseDrag(const Vector2D& from, const Vector2D& to, wx if (!controlPointMoveAction) { // create action we can add this movement to controlPointMoveAction = new ControlPointMoveAction(selected_points); - getSymbol()->actions.add(controlPointMoveAction); + addAction(controlPointMoveAction); } controlPointMoveAction->constrain = ev.ControlDown(); // ctrl constrains controlPointMoveAction->snap = snap(ev); @@ -309,7 +309,7 @@ void SymbolPointEditor::onMouseDrag(const Vector2D& from, const Vector2D& to, wx // Move the selected handle if (!handleMoveAction) { handleMoveAction = new HandleMoveAction(selected_handle); - getSymbol()->actions.add(handleMoveAction); + addAction(handleMoveAction); } handleMoveAction->constrain = ev.ControlDown(); // ctrl constrains handleMoveAction->snap = snap(ev); @@ -368,14 +368,14 @@ void SymbolPointEditor::onChar(wxKeyEvent& ev) { if (selection == SELECTED_POINTS || selection == SELECTED_LINE) { // Move all selected points controlPointMoveAction = new ControlPointMoveAction(selected_points); - getSymbol()->actions.add(controlPointMoveAction); + addAction(controlPointMoveAction); controlPointMoveAction->move(delta); new_point += delta; control.Refresh(false); } else if (selection == SELECTED_HANDLE) { // Move the selected handle handleMoveAction = new HandleMoveAction(selected_handle); - getSymbol()->actions.add(handleMoveAction); + addAction(handleMoveAction); handleMoveAction->move(delta); control.Refresh(false); } @@ -466,7 +466,7 @@ void SymbolPointEditor::resetActions() { void SymbolPointEditor::deleteSelection() { if (!selected_points.empty()) { - getSymbol()->actions.add(control_point_remove_action(part, selected_points)); + addAction(control_point_remove_action(part, selected_points)); selected_points.clear(); resetActions(); control.Refresh(false); @@ -477,12 +477,12 @@ void SymbolPointEditor::onChangeSegment(SegmentMode mode) { assert(selected_line1); assert(selected_line2); if (selected_line1->segment_after == mode) return; - getSymbol()->actions.add(new SegmentModeAction(selected_line1, selected_line2, mode)); + addAction(new SegmentModeAction(selected_line1, selected_line2, mode)); control.Refresh(false); } void SymbolPointEditor::onChangeLock(LockMode mode) { - getSymbol()->actions.add(new LockModeAction(*selected_points.begin(), mode)); + addAction(new LockModeAction(*selected_points.begin(), mode)); control.Refresh(false); } diff --git a/src/gui/symbol/select_editor.cpp b/src/gui/symbol/select_editor.cpp index bdcdc6ec..e68896e9 100644 --- a/src/gui/symbol/select_editor.cpp +++ b/src/gui/symbol/select_editor.cpp @@ -173,22 +173,22 @@ void SymbolSelectEditor::onUpdateUI(wxUpdateUIEvent& ev) { void SymbolSelectEditor::onCommand(int id) { if (id >= ID_SYMBOL_COMBINE && id < ID_SYMBOL_COMBINE_MAX) { // change combine mode - getSymbol()->actions.add(new CombiningModeAction( + addAction(new CombiningModeAction( control.selected_parts.get(), static_cast(id - ID_SYMBOL_COMBINE) )); control.Refresh(false); } else if (id == ID_EDIT_DUPLICATE && !isEditing()) { // duplicate selection, not when dragging - getSymbol()->actions.add(new DuplicateSymbolPartsAction(*getSymbol(), control.selected_parts.get())); + addAction(new DuplicateSymbolPartsAction(*getSymbol(), control.selected_parts.get())); control.Refresh(false); } else if (id == ID_EDIT_GROUP && !isEditing()) { // group selection, not when dragging - getSymbol()->actions.add(new GroupSymbolPartsAction(*getSymbol(), control.selected_parts.get(), new_intrusive())); + addAction(new GroupSymbolPartsAction(*getSymbol(), control.selected_parts.get(), new_intrusive())); control.Refresh(false); } else if (id == ID_EDIT_UNGROUP && !isEditing()) { // ungroup selection, not when dragging - getSymbol()->actions.add(new UngroupSymbolPartsAction(*getSymbol(), control.selected_parts.get())); + addAction(new UngroupSymbolPartsAction(*getSymbol(), control.selected_parts.get())); control.Refresh(false); } } @@ -313,23 +313,23 @@ void SymbolSelectEditor::onMouseDrag (const Vector2D& from, const Vector2D& to, if (scaleX == 0 || scaleY == 0) { // shear, center/fixed point on the opposite side shearAction = new SymbolPartShearAction(control.selected_parts.get(), handlePos(-scaleX, -scaleY)); - getSymbol()->actions.add(shearAction); + addAction(shearAction); } else { // rotate rotateAction = new SymbolPartRotateAction(control.selected_parts.get(), center); - getSymbol()->actions.add(rotateAction); + addAction(rotateAction); startAngle = angleTo(to); } } else { // we are on a handle; start scaling scaleAction = new SymbolPartScaleAction(control.selected_parts.get(), scaleX, scaleY); - getSymbol()->actions.add(scaleAction); + addAction(scaleAction); } } else { // move click_mode = CLICK_MOVE; moveAction = new SymbolPartMoveAction(control.selected_parts.get()); - getSymbol()->actions.add(moveAction); + addAction(moveAction); } } @@ -399,7 +399,7 @@ void SymbolSelectEditor::onKeyChange (wxKeyEvent& ev) { void SymbolSelectEditor::onChar(wxKeyEvent& ev) { if (ev.GetKeyCode() == WXK_DELETE) { // delete selected parts - getSymbol()->actions.add(new RemoveSymbolPartsAction(*getSymbol(), control.selected_parts.get())); + addAction(new RemoveSymbolPartsAction(*getSymbol(), control.selected_parts.get())); if (control.selected_parts.selected(highlightPart)) highlightPart = SymbolPartP(); // deleted it control.selected_parts.clear(); resetActions(); @@ -416,7 +416,7 @@ void SymbolSelectEditor::onChar(wxKeyEvent& ev) { ev.Skip(); return; } - getSymbol()->actions.add(new SymbolPartMoveAction(control.selected_parts.get(), delta)); + addAction(new SymbolPartMoveAction(control.selected_parts.get(), delta)); } } diff --git a/src/gui/symbol/symmetry_editor.cpp b/src/gui/symbol/symmetry_editor.cpp index 2dac5ee3..2659c8fe 100644 --- a/src/gui/symbol/symmetry_editor.cpp +++ b/src/gui/symbol/symmetry_editor.cpp @@ -107,13 +107,13 @@ void SymbolSymmetryEditor::onCommand(int id) { if (id >= ID_SYMMETRY && id < ID_SYMMETRY_MAX) { SymbolSymmetryType kind = id == ID_SYMMETRY_ROTATION ? SYMMETRY_ROTATION : SYMMETRY_REFLECTION; if (symmetry && symmetry->kind != kind) { - getSymbol()->actions.add(new SymmetryTypeAction(*symmetry, kind)); + addAction(new SymmetryTypeAction(*symmetry, kind)); control.Refresh(false); } resetActions(); } else if (id == ID_COPIES) { if (symmetry && symmetry->copies != copies->GetValue()) { - getSymbol()->actions.add(new SymmetryCopiesAction(*symmetry, copies->GetValue())); + addAction(new SymmetryCopiesAction(*symmetry, copies->GetValue())); control.Refresh(false); } resetActions(); @@ -124,11 +124,11 @@ void SymbolSymmetryEditor::onCommand(int id) { symmetry->center = Vector2D(0.5,0.5); symmetry->handle = Vector2D(0.2,0); symmetry->name = symmetry->expectedName(); - getSymbol()->actions.add(new GroupSymbolPartsAction(*getSymbol(), control.selected_parts.get(), symmetry)); + addAction(new GroupSymbolPartsAction(*getSymbol(), control.selected_parts.get(), symmetry)); control.selected_parts.select(symmetry); control.Refresh(false); } else if (id == ID_REMOVE_SYMMETRY) { - getSymbol()->actions.add(new UngroupSymbolPartsAction(*getSymbol(), control.selected_parts.get())); + addAction(new UngroupSymbolPartsAction(*getSymbol(), control.selected_parts.get())); symmetry = SymbolSymmetryP(); control.Refresh(false); } @@ -158,7 +158,7 @@ void SymbolSymmetryEditor::onMouseDrag (const Vector2D& from, const Vector2D& t symmetryMoveAction = new SymmetryMoveAction(*symmetry, selection == SELECTION_HANDLE); symmetryMoveAction->constrain = ev.ControlDown(); symmetryMoveAction->snap = ev.ShiftDown() != settings.symbol_grid_snap ? settings.symbol_grid_size : 0; - getSymbol()->actions.add(symmetryMoveAction); + addAction(symmetryMoveAction); } symmetryMoveAction->move(to - from); control.Refresh(false); diff --git a/src/gui/symbol/window.cpp b/src/gui/symbol/window.cpp index 0091b144..1ee90155 100644 --- a/src/gui/symbol/window.cpp +++ b/src/gui/symbol/window.cpp @@ -12,23 +12,28 @@ #include #include #include -#include #include #include #include +#include // :( #include #include +#include #include #include #include // ----------------------------------------------------------------------------- : Constructor -SymbolWindow::SymbolWindow(Window* parent) { +SymbolWindow::SymbolWindow(Window* parent) + : performer(nullptr) +{ init(parent, default_symbol()); } -SymbolWindow::SymbolWindow(Window* parent, const String& filename) { +SymbolWindow::SymbolWindow(Window* parent, const String& filename) + : performer(nullptr) +{ // open file Reader reader(new_shared1(filename), nullptr, filename); SymbolP symbol; @@ -36,15 +41,17 @@ SymbolWindow::SymbolWindow(Window* parent, const String& filename) { init(parent, symbol); } -SymbolWindow::SymbolWindow(Window* parent, const SetP& set, const Card* card, const SymbolValueP& value) - : value(value), card(card), set(set) +SymbolWindow::SymbolWindow(Window* parent, ValueActionPerformer* performer) + : performer(performer) { // attempt to load symbol SymbolP symbol; + SymbolValueP value = static_pointer_cast(performer->value); if (!value->filename.empty()) { try { // load symbol - symbol = set->readFile(value->filename); + Package& package = performer->getLocalPackage(); + symbol = package.readFile(value->filename); } catch (const Error& e) { handle_error(e); } @@ -52,6 +59,9 @@ SymbolWindow::SymbolWindow(Window* parent, const SetP& set, const Card* card, co if (!symbol) symbol = default_symbol(); init(parent, symbol); } +SymbolWindow::~SymbolWindow() { + delete performer; +} void SymbolWindow::init(Window* parent, SymbolP symbol) { Create(parent, wxID_ANY, _TITLE_("symbol editor"), wxDefaultPosition, wxSize(650,600), wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE); @@ -233,11 +243,13 @@ void SymbolWindow::onFileSaveAs(wxCommandEvent& ev) { } void SymbolWindow::onFileStore(wxCommandEvent& ev) { - if (value) { - FileName new_filename = set->newFileName(value->field().name,_(".mse-symbol")); // a new unique name in the package - Writer writer(set->openOut(new_filename)); + if (performer) { + SymbolValueP value = static_pointer_cast(performer->value); + Package& package = performer->getLocalPackage(); + FileName new_filename = package.newFileName(value->field().name,_(".mse-symbol")); // a new unique name in the package + Writer writer(package.openOut(new_filename)); writer.handle(control->getSymbol()); - set->actions.add(value_action(card, value, new_filename)); + performer->addAction(value_action(value, new_filename)); } } @@ -273,7 +285,7 @@ void SymbolWindow::onUpdateUI(wxUpdateUIEvent& ev) { switch(ev.GetId()) { // file menu case ID_FILE_STORE: { - ev.Enable(value); + ev.Enable(performer); break; // undo/redo } case ID_EDIT_UNDO: { diff --git a/src/gui/symbol/window.hpp b/src/gui/symbol/window.hpp index bb2cdaeb..05478bab 100644 --- a/src/gui/symbol/window.hpp +++ b/src/gui/symbol/window.hpp @@ -15,9 +15,7 @@ class SymbolControl; class SymbolPartList; -class Card; -DECLARE_POINTER_TYPE(SymbolValue); -DECLARE_POINTER_TYPE(Set); +DECLARE_POINTER_TYPE(ValueActionPerformer); // ----------------------------------------------------------------------------- : SymbolWindow @@ -29,7 +27,8 @@ class SymbolWindow : public Frame { /// Construct a SymbolWindow showing a symbol from a file SymbolWindow(Window* parent, const String& filename); /// Construct a SymbolWindow showing a symbol value in a set - SymbolWindow(Window* parent, const SetP& set, const Card* card, const SymbolValueP& value); + SymbolWindow(Window* parent, ValueActionPerformer* performer); + ~SymbolWindow(); private: // --------------------------------------------------- : Children @@ -41,9 +40,7 @@ class SymbolWindow : public Frame { SymbolPartList* parts; ///< A list of parts in the symbol // when editing a symbol field - SymbolValueP value; - const Card* card; - SetP set; + ValueActionPerformer* performer; // --------------------------------------------------- : Event handling DECLARE_EVENT_TABLE(); diff --git a/src/gui/value/choice.cpp b/src/gui/value/choice.cpp index 2a81237a..add51cd1 100644 --- a/src/gui/value/choice.cpp +++ b/src/gui/value/choice.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include