File indexing completed on 2024-05-19 04:24:18

0001 /*
0002  *  SPDX-FileCopyrightText: 2015 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "kis_command_utils.h"
0008 
0009 namespace KisCommandUtils
0010 {
0011     AggregateCommand::AggregateCommand(KUndo2Command *parent)
0012         : KUndo2Command(parent),
0013           m_firstRedo(true) {}
0014 
0015     AggregateCommand::AggregateCommand(const KUndo2MagicString &text, KUndo2Command *parent)
0016         : KUndo2Command(text, parent),
0017           m_firstRedo(true) {}
0018 
0019     void AggregateCommand::redo()
0020     {
0021         if (m_firstRedo) {
0022             m_firstRedo = false;
0023 
0024             populateChildCommands();
0025         }
0026 
0027         m_store.redoAll();
0028     }
0029 
0030     void AggregateCommand::undo()
0031     {
0032         m_store.undoAll();
0033     }
0034 
0035     void AggregateCommand::addCommand(KUndo2Command *cmd)
0036     {
0037         if (!cmd) return;
0038         m_store.addCommand(cmd);
0039     }
0040 
0041     LambdaCommand::LambdaCommand(std::function<KUndo2Command*()> createCommandFunc)
0042         : m_createCommandFunc(createCommandFunc)
0043     {
0044 
0045     }
0046 
0047     LambdaCommand::LambdaCommand(const KUndo2MagicString &text,
0048                                  std::function<KUndo2Command*()> createCommandFunc)
0049         : AggregateCommand(text),
0050           m_createCommandFunc(createCommandFunc)
0051     {
0052 
0053     }
0054 
0055     LambdaCommand::LambdaCommand(const KUndo2MagicString &text,
0056                                  KUndo2Command *parent,
0057                                  std::function<KUndo2Command*()> createCommandFunc)
0058         : AggregateCommand(text, parent),
0059           m_createCommandFunc(createCommandFunc)
0060     {
0061     }
0062 
0063     LambdaCommand::LambdaCommand(KUndo2Command *parent,
0064                                  std::function<KUndo2Command*()> createCommandFunc)
0065         : AggregateCommand(parent),
0066           m_createCommandFunc(createCommandFunc)
0067     {
0068     }
0069 
0070     void LambdaCommand::populateChildCommands()
0071     {
0072         if (m_createCommandFunc) {
0073             addCommand(m_createCommandFunc());
0074 
0075             /**
0076              *  We should release all the potential resources owned
0077              *  by the attached lambda
0078              */
0079             m_createCommandFunc = {};
0080         }
0081     }
0082 
0083     SkipFirstRedoWrapper::SkipFirstRedoWrapper(KUndo2Command *child, KUndo2Command *parent)
0084         : KUndo2Command(child ? child->text() : kundo2_noi18n("<bug: unnamed command>"), parent), m_firstRedo(true), m_child(child) {}
0085 
0086     void SkipFirstRedoWrapper::redo()
0087     {
0088         if (m_firstRedo) {
0089             m_firstRedo = false;
0090         } else {
0091             if (m_child) {
0092                 m_child->redo();
0093             }
0094             KUndo2Command::redo();
0095         }
0096     }
0097 
0098     void SkipFirstRedoWrapper::undo()
0099     {
0100         KUndo2Command::undo();
0101         if (m_child) {
0102             m_child->undo();
0103         }
0104     }
0105 
0106     SkipFirstRedoBase::SkipFirstRedoBase(bool skipFirstRedo, KUndo2Command *parent)
0107         : KUndo2Command(parent),
0108           m_firstRedo(skipFirstRedo)
0109     {
0110     }
0111 
0112     SkipFirstRedoBase::SkipFirstRedoBase(bool skipFirstRedo, const KUndo2MagicString &text, KUndo2Command *parent)
0113         : KUndo2Command(text, parent),
0114           m_firstRedo(skipFirstRedo)
0115     {
0116     }
0117 
0118     void SkipFirstRedoBase::redo()
0119     {
0120         if (m_firstRedo) {
0121             m_firstRedo = false;
0122         } else {
0123             redoImpl();
0124             KUndo2Command::redo();
0125         }
0126     }
0127 
0128     void SkipFirstRedoBase::undo()
0129     {
0130         KUndo2Command::undo();
0131         undoImpl();
0132     }
0133 
0134     void SkipFirstRedoBase::setSkipOneRedo(bool value)
0135     {
0136         m_firstRedo = value;
0137     }
0138 
0139     FlipFlopCommand::FlipFlopCommand(bool finalizing, KUndo2Command *parent)
0140         : KUndo2Command(parent)
0141     {
0142         m_currentState = finalizing ? State::FINALIZING : State::INITIALIZING;
0143     }
0144 
0145     FlipFlopCommand::FlipFlopCommand(State initialState, KUndo2Command *parent)
0146         : KUndo2Command(parent),
0147           m_currentState(initialState)
0148     {}
0149 
0150     void FlipFlopCommand::redo()
0151     {
0152         if (m_currentState == FlipFlopCommand::State::INITIALIZING) {
0153             partA();
0154         } else {
0155             partB();
0156         }
0157 
0158         m_firstRedo = false;
0159     }
0160 
0161     void FlipFlopCommand::undo()
0162     {
0163         if (m_currentState == FlipFlopCommand::State::FINALIZING) {
0164             partA();
0165         } else {
0166             partB();
0167         }
0168     }
0169 
0170     void FlipFlopCommand::partA() {}
0171     void FlipFlopCommand::partB() {}
0172 
0173     CompositeCommand::CompositeCommand(KUndo2Command *parent)
0174         : KUndo2Command(parent) {}
0175 
0176     CompositeCommand::~CompositeCommand() {
0177         qDeleteAll(m_commands);
0178     }
0179 
0180     void CompositeCommand::addCommand(KUndo2Command *cmd) {
0181         if (cmd) {
0182             m_commands << cmd;
0183         }
0184     }
0185 
0186     void CompositeCommand::redo() {
0187         KUndo2Command::redo();
0188         Q_FOREACH (KUndo2Command *cmd, m_commands) {
0189             cmd->redo();
0190         }
0191     }
0192 
0193     void CompositeCommand::undo() {
0194         for (auto it = m_commands.rbegin(); it != m_commands.rend(); ++it) {
0195             (*it)->undo();
0196         }
0197         KUndo2Command::undo();
0198     }
0199 
0200 }