diff --git a/src/data/action/value.cpp b/src/data/action/value.cpp index 363a00d7..2cd5bb55 100644 --- a/src/data/action/value.cpp +++ b/src/data/action/value.cpp @@ -7,17 +7,10 @@ // ----------------------------------------------------------------------------- : Includes #include +#include #include #include -#include -#include -#include -#include -#include -#include -#include #include -#include #include // for ValueActionPerformer #include @@ -44,48 +37,6 @@ void ValueAction::setCard(CardP const& card) { // ----------------------------------------------------------------------------- : Simple -/// Swap the value in a Value object with a new one -inline void swap_value(ChoiceValue& a, ChoiceValue ::ValueType& b) { swap(a.value, b); } -inline void swap_value(ColorValue& a, ColorValue ::ValueType& b) { swap(a.value, b); } -inline void swap_value(ImageValue& a, ImageValue ::ValueType& b) { swap(a.filename, b); a.last_update.update(); } -inline void swap_value(SymbolValue& a, SymbolValue ::ValueType& b) { swap(a.filename, b); a.last_update.update(); } -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); -} - -/// 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) - {} - - void perform(bool to_undo) override { - ValueAction::perform(to_undo); - swap_value(static_cast(*valueP), new_value); - valueP->onAction(*this, to_undo); // notify value - } - - bool merge(const Action& action) override { - 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; -}; - unique_ptr value_action(const ChoiceValueP& value, const Defaultable& new_value) { return make_unique>(value, new_value); } diff --git a/src/data/action/value.hpp b/src/data/action/value.hpp index 5a448d39..3a5c736f 100644 --- a/src/data/action/value.hpp +++ b/src/data/action/value.hpp @@ -16,6 +16,13 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include class StyleSheet; class LocalFileName; @@ -53,6 +60,47 @@ private: // ----------------------------------------------------------------------------- : Simple +/// Swap the value in a Value object with a new one +inline void swap_value(ChoiceValue& a, ChoiceValue ::ValueType& b) { swap(a.value, b); } +inline void swap_value(ColorValue& a, ColorValue ::ValueType& b) { swap(a.value, b); } +inline void swap_value(ImageValue& a, ImageValue ::ValueType& b) { swap(a.filename, b); a.last_update.update(); } +inline void swap_value(SymbolValue& a, SymbolValue ::ValueType& b) { swap(a.filename, b); a.last_update.update(); } +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); +} + +/// 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) + {} + + void perform(bool to_undo) override { + ValueAction::perform(to_undo); + swap_value(static_cast(*valueP), new_value); + valueP->onAction(*this, to_undo); // notify value + } + + bool merge(const Action& action) override { + 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; + } + + typename T::ValueType new_value; +}; + /// Action that updates a Value to a new value unique_ptr value_action(const ChoiceValueP& value, const Defaultable& new_value); unique_ptr value_action(const MultipleChoiceValueP& value, const Defaultable& new_value, const String& last_change); diff --git a/src/data/set.cpp b/src/data/set.cpp index b1ae3da8..b4d4ac07 100644 --- a/src/data/set.cpp +++ b/src/data/set.cpp @@ -16,6 +16,9 @@ #include #include // for 0.2.7 fix #include +#include +#include +#include #include // for 0.2.7 fix #include #include @@ -104,6 +107,28 @@ IndexMap& Set::stylingDataFor(const CardP& card) { else return stylingDataFor(stylesheetFor(card)); } +void Set::referenceActionStackFiles() { + referenceActionStackFiles(true); + referenceActionStackFiles(false); +} +void Set::referenceActionStackFiles(bool undo) { + for (auto&& action : undo ? actions.undo_actions : actions.redo_actions) { + try { + SimpleValueAction& v = dynamic_cast&>(*action); + if (ImageValue* v2 = dynamic_cast(v.valueP.get())) { + referenceFile(v.new_value.toStringForWriting()); + referenceFile(v2->filename.toStringForWriting()); + } + } catch (...) { try { + SimpleValueAction& v = dynamic_cast&>(*action); + if (SymbolValue* v2 = dynamic_cast(v.valueP.get())) { + referenceFile(v.new_value.toStringForWriting()); + referenceFile(v2->filename.toStringForWriting()); + } + } catch (...) {} } + } +} + String Set::identification() const { // an identifying field FOR_EACH_CONST(v, data) { diff --git a/src/data/set.hpp b/src/data/set.hpp index a46895af..e6b24af7 100644 --- a/src/data/set.hpp +++ b/src/data/set.hpp @@ -89,8 +89,13 @@ public: /// Styling information for a particular stylesheet IndexMap& stylingDataFor(const StyleSheet&); /// Styling information for a particular card - IndexMap& stylingDataFor(const CardP& card); - + IndexMap& stylingDataFor(const CardP& card); + + /// Make sure the image and symbol files from + /// the ActionStack are saved so we can undo + void referenceActionStackFiles(); + void referenceActionStackFiles(bool undo); + /// Get the identification of this set, an identification is something like a name, title, etc. /** May return "" */ String identification() const; diff --git a/src/util/action_stack.hpp b/src/util/action_stack.hpp index 5770232c..b95a21b7 100644 --- a/src/util/action_stack.hpp +++ b/src/util/action_stack.hpp @@ -103,11 +103,12 @@ public: /// Tell all listeners about an action void tellListeners(const Action&, bool undone); -private: /// Actions to be undone. vector> undo_actions; /// Actions to be redone - vector> redo_actions; + vector> redo_actions; + +private: /// Point at which the file was saved, corresponds to the top of the undo stack at that point const Action* save_point; /// Was the last thing the user did addAction? (as opposed to undo/redo) diff --git a/src/util/error.cpp b/src/util/error.cpp index e7778e9f..7e7bae0e 100644 --- a/src/util/error.cpp +++ b/src/util/error.cpp @@ -110,10 +110,12 @@ String Error::what() const { InternalError::InternalError(const String& str) : Error( - _("An internal error occured:\n\n") + - str + _("\n") - _("Please save your work (use 'save as' to so you don't overwrite things)\n") - _("and restart Magic Set Editor.\n\n") + _("An internal error occurred:\n\n") + + str + _("\n\n") + _("Please save your work (use 'save as' so you don't overwrite things)\n") + _("and restart Magic Set Editor.\n") + _("You can also find a backup of your set in the same folder as your set file\n") + _("called 'SETNAME.mse-set.bak'. Rename it to 'SETNAME-backup.mse-set' to open it.\n") _("You should leave a bug report on https://github.com/twanvl/MagicSetEditor2/issues/\n") _("Press Ctrl+C to copy this message to the clipboard.") ) diff --git a/src/util/io/package.cpp b/src/util/io/package.cpp index cefe35a8..fa807c03 100644 --- a/src/util/io/package.cpp +++ b/src/util/io/package.cpp @@ -12,6 +12,7 @@ #include #include