File indexing completed on 2024-05-12 15:56:13

0001 /*
0002  *  SPDX-FileCopyrightText: 2015 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef __KIS_COMMAND_UTILS_H
0008 #define __KIS_COMMAND_UTILS_H
0009 
0010 #include "kundo2command.h"
0011 #include "kis_undo_stores.h"
0012 #include "kritacommand_export.h"
0013 #include <functional>
0014 
0015 namespace KisCommandUtils
0016 {
0017 
0018     /**
0019      * @brief The AggregateCommand struct is a command with delayed
0020      * initialization. On first redo() populateChildCommands() is called
0021      * and the descendants add the desired commands to the internal list.
0022      * After that, the added commands are executed on every undo()/redo().
0023      *
0024      * This structure is used when the commands should be populated from
0025      * the context of the stroke, not from the GUI thread.
0026      */
0027     struct KRITACOMMAND_EXPORT AggregateCommand : public KUndo2Command {
0028         AggregateCommand(KUndo2Command *parent = 0);
0029         AggregateCommand(const KUndo2MagicString &text,
0030                          KUndo2Command *parent = 0);
0031 
0032         void redo() override;
0033         void undo() override;
0034 
0035     protected:
0036         virtual void populateChildCommands() = 0;
0037         void addCommand(KUndo2Command *cmd);
0038 
0039     private:
0040         bool m_firstRedo;
0041         KisSurrogateUndoStore m_store;
0042     };
0043 
0044     /**
0045      * @brief The LambdaCommand struct is a shorthand for creation of
0046      * AggregateCommand commands using C++ lambda feature. Just pass
0047      * a lambda object into a command and it will be called from within
0048      * the context of the strokes thread to populate the command content.
0049      */
0050     struct KRITACOMMAND_EXPORT LambdaCommand : public AggregateCommand {
0051         LambdaCommand(std::function<KUndo2Command*()> createCommandFunc);
0052         LambdaCommand(const KUndo2MagicString &text,
0053                       std::function<KUndo2Command*()> createCommandFunc);
0054         LambdaCommand(const KUndo2MagicString &text,
0055                       KUndo2Command *parent,
0056                       std::function<KUndo2Command*()> createCommandFunc);
0057         LambdaCommand(KUndo2Command *parent,
0058                       std::function<KUndo2Command*()> createCommandFunc);
0059 
0060     protected:
0061         void populateChildCommands() override;
0062 
0063     private:
0064         std::function<KUndo2Command*()> m_createCommandFunc;
0065     };
0066 
0067 
0068     struct KRITACOMMAND_EXPORT SkipFirstRedoWrapper : public KUndo2Command {
0069         SkipFirstRedoWrapper(KUndo2Command *child = 0, KUndo2Command *parent = 0);
0070         void redo() override;
0071         void undo() override;
0072 
0073     private:
0074         bool m_firstRedo;
0075         QScopedPointer<KUndo2Command> m_child;
0076     };
0077 
0078 
0079     struct KRITACOMMAND_EXPORT SkipFirstRedoBase : public KUndo2Command {
0080         SkipFirstRedoBase(bool skipFirstRedo, KUndo2Command *parent = 0);
0081         SkipFirstRedoBase(bool skipFirstRedo, const KUndo2MagicString &text, KUndo2Command *parent = 0);
0082 
0083         void redo() override final;
0084         void undo() override final;
0085 
0086         void setSkipOneRedo(bool value);
0087 
0088     protected:
0089         virtual void redoImpl() = 0;
0090         virtual void undoImpl() = 0;
0091 
0092     private:
0093         bool m_firstRedo;
0094     };
0095 
0096 
0097     struct KRITACOMMAND_EXPORT FlipFlopCommand : public KUndo2Command {
0098         enum State {
0099             INITIALIZING, // Before redo; after undo.
0100             FINALIZING    // After redo; before undo.
0101         };
0102 
0103         FlipFlopCommand(State initialState, KUndo2Command *parent = 0);
0104         FlipFlopCommand(bool finalizing = false, KUndo2Command *parent = 0);
0105 
0106         void redo() override; // partA -> redo command -> partB
0107         void undo() override; // partB -> undo command -> partA
0108 
0109     protected:
0110         virtual void partA();
0111         virtual void partB();
0112 
0113         State getState() const { return m_currentState; }
0114         bool isFirstRedo() const { return m_firstRedo; }
0115 
0116     private:
0117         State m_currentState;
0118         bool m_firstRedo {true};
0119     };
0120 
0121     struct KRITACOMMAND_EXPORT CompositeCommand : public KUndo2Command {
0122         CompositeCommand(KUndo2Command *parent = 0);
0123         ~CompositeCommand() override;
0124 
0125         void addCommand(KUndo2Command *cmd);
0126 
0127         void redo() override;
0128         void undo() override;
0129 
0130     private:
0131         QVector<KUndo2Command*> m_commands;
0132     };
0133 }
0134 
0135 #endif /* __KIS_COMMAND_UTILS_H */