File indexing completed on 2024-05-12 15:58:43
0001 /* 0002 * SPDX-FileCopyrightText: 2011 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef __KIS_STROKE_STRATEGY_UNDO_COMMAND_BASED_H 0008 #define __KIS_STROKE_STRATEGY_UNDO_COMMAND_BASED_H 0009 0010 #include <kundo2command.h> 0011 #include <QVector> 0012 #include <QMutex> 0013 0014 #include "kis_types.h" 0015 #include "kis_simple_stroke_strategy.h" 0016 #include "KisRunnableBasedStrokeStrategy.h" 0017 0018 0019 class KisStrokeJob; 0020 class KisSavedMacroCommand; 0021 class KisStrokeUndoFacade; 0022 class KisStrokesQueueMutatedJobInterface; 0023 0024 0025 class KRITAIMAGE_EXPORT KisStrokeStrategyUndoCommandBased : public KisRunnableBasedStrokeStrategy 0026 { 0027 public: 0028 struct MutatedCommandInterface 0029 { 0030 virtual ~MutatedCommandInterface() {} 0031 0032 void setRunnableJobsInterface(KisRunnableStrokeJobsInterface *interface) { 0033 m_mutatedJobsInterface = interface; 0034 } 0035 0036 KisRunnableStrokeJobsInterface* runnableJobsInterface() const { 0037 return m_mutatedJobsInterface; 0038 } 0039 0040 private: 0041 KisRunnableStrokeJobsInterface *m_mutatedJobsInterface; 0042 }; 0043 0044 0045 class KRITAIMAGE_EXPORT Data : public KisStrokeJobData { 0046 public: 0047 Data(KUndo2CommandSP _command, 0048 bool _undo = false, 0049 Sequentiality _sequentiality = SEQUENTIAL, 0050 Exclusivity _exclusivity = NORMAL, 0051 bool _shouldGoToHistory = true) 0052 : KisStrokeJobData(_sequentiality, _exclusivity), 0053 command(_command), 0054 undo(_undo), 0055 shouldGoToHistory(_shouldGoToHistory) 0056 { 0057 } 0058 0059 Data(KUndo2Command *_command, 0060 bool _undo = false, 0061 Sequentiality _sequentiality = SEQUENTIAL, 0062 Exclusivity _exclusivity = NORMAL, 0063 bool _shouldGoToHistory = true) 0064 : KisStrokeJobData(_sequentiality, _exclusivity), 0065 command(_command), 0066 undo(_undo), 0067 shouldGoToHistory(_shouldGoToHistory) 0068 { 0069 } 0070 0071 ~Data() override; 0072 0073 KUndo2CommandSP command; 0074 bool undo; 0075 bool shouldGoToHistory = true; 0076 }; 0077 0078 public: 0079 KisStrokeStrategyUndoCommandBased(const KUndo2MagicString &name, 0080 bool undo, 0081 KisStrokeUndoFacade *undoFacade, 0082 KUndo2CommandSP initCommand = KUndo2CommandSP(0), 0083 KUndo2CommandSP finishCommand = KUndo2CommandSP(0)); 0084 0085 using KisSimpleStrokeStrategy::setExclusive; 0086 0087 void initStrokeCallback() override; 0088 void finishStrokeCallback() override; 0089 void cancelStrokeCallback() override; 0090 void doStrokeCallback(KisStrokeJobData *data) override; 0091 0092 /** 0093 * Set extra data that will be assigned to the command 0094 * representing this action. Using extra data has the following 0095 * restrictions: 0096 * 0097 * 1) The \p data must be set *before* the stroke has been started. 0098 * Setting the \p data after the stroke has been started with 0099 * image->startStroke(strokeId) leads to an undefined behaviour. 0100 * 0101 * 2) \p data becomes owned by the strategy/command right after 0102 * setting it. Don't try to change it afterwards. 0103 */ 0104 void setCommandExtraData(KUndo2CommandExtraData *data); 0105 0106 /** 0107 * Sets the id of this action. Will be used for merging the undo commands 0108 * 0109 * The \p value must be set *before* the stroke has been started. 0110 * Setting the \p value after the stroke has been started with 0111 * image->startStroke(strokeId) leads to an undefined behaviour. 0112 */ 0113 void setMacroId(int value); 0114 0115 /** 0116 * The undo-command-based is a low-level strategy, so it allows 0117 * changing its wraparound mode status. 0118 * 0119 * WARNING: the switch must be called *before* the stroke has been 0120 * started! Otherwise the mode will not be activated. 0121 */ 0122 using KisStrokeStrategy::setSupportsWrapAroundMode; 0123 0124 void setUsedWhileUndoRedo(bool value); 0125 0126 protected: 0127 void runAndSaveCommand(KUndo2CommandSP command, 0128 KisStrokeJobData::Sequentiality sequentiality, 0129 KisStrokeJobData::Exclusivity exclusivity); 0130 void notifyCommandDone(KUndo2CommandSP command, 0131 KisStrokeJobData::Sequentiality sequentiality, 0132 KisStrokeJobData::Exclusivity exclusivity); 0133 0134 KisStrokeStrategyUndoCommandBased(const KisStrokeStrategyUndoCommandBased &rhs); 0135 0136 /** 0137 * @brief Applies some modifications (e.g. assigning extra data) to the toplevel command 0138 */ 0139 virtual void postProcessToplevelCommand(KUndo2Command *command); 0140 0141 KisStrokeUndoFacade* undoFacade() const; 0142 0143 protected: 0144 void executeCommand(KUndo2CommandSP command, bool undo); 0145 void cancelStrokeCallbackImpl(QVector<KisStrokeJobData*> &mutatedJobs); 0146 private: 0147 bool m_undo; 0148 KUndo2CommandSP m_initCommand; 0149 KUndo2CommandSP m_finishCommand; 0150 KisStrokeUndoFacade *m_undoFacade {nullptr}; 0151 0152 QScopedPointer<KUndo2CommandExtraData> m_commandExtraData; 0153 int m_macroId; 0154 0155 // protects done commands only 0156 QMutex m_mutex; 0157 KisSavedMacroCommand *m_macroCommand {nullptr}; 0158 }; 0159 0160 #endif /* __KIS_STROKE_STRATEGY_UNDO_COMMAND_BASED_H */