File indexing completed on 2024-05-12 15:58:45

0001 /*
0002  *  SPDX-FileCopyrightText: 2010 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef KIS_TRANSACTION_H_
0008 #define KIS_TRANSACTION_H_
0009 
0010 #include <kundo2command.h>
0011 
0012 #include "kis_types.h"
0013 
0014 #include "kis_transaction_data.h"
0015 #include "kis_paint_device.h"
0016 #include "kis_pixel_selection.h"
0017 #include "kis_image_config.h"
0018 
0019 #include "kis_undo_adapter.h"
0020 #include "kis_post_execution_undo_adapter.h"
0021 
0022 class KisTransactionWrapperFactory;
0023 
0024 class KisTransaction
0025 {
0026 public:
0027     enum Flag {
0028         None = 0x0,
0029         SuppressUpdates = 0x1
0030     };
0031     Q_DECLARE_FLAGS(Flags, Flag)
0032 
0033 public:
0034     KisTransaction(const KUndo2MagicString& name, KisPaintDeviceSP device, KUndo2Command* parent = 0,int timedID = -1, KisTransactionWrapperFactory *interstrokeDataFactory = 0, Flags flags = None) {
0035         m_transactionData = new KisTransactionData(name, device, true, interstrokeDataFactory, parent, flags & SuppressUpdates);
0036         m_transactionData->setTimedID(timedID);
0037     }
0038 
0039     KisTransaction(KisPaintDeviceSP device, KUndo2Command* parent = 0, int timedID = -1, KisTransactionWrapperFactory *interstrokeDataFactory = 0, Flags flags = None)
0040         : KisTransaction(KUndo2MagicString(), device, parent, timedID, interstrokeDataFactory, flags)
0041     {
0042     }
0043 
0044     virtual ~KisTransaction() {
0045         delete m_transactionData;
0046     }
0047 
0048     KUndo2Command* undoCommand() {
0049         return m_transactionData;
0050     }
0051 
0052     void commit(KisUndoAdapter* undoAdapter) {
0053         KIS_ASSERT_X(m_transactionData,
0054                      "KisTransaction::commit()",
0055                      "the transaction has been tried to be committed twice");
0056 
0057         m_transactionData->endTransaction();
0058         undoAdapter->addCommand(m_transactionData);
0059         m_transactionData = 0;
0060     }
0061 
0062     void commit(KisPostExecutionUndoAdapter* undoAdapter) {
0063         KIS_ASSERT_X(m_transactionData,
0064                      "KisTransaction::commit()",
0065                      "the transaction has been tried to be committed twice");
0066 
0067         m_transactionData->endTransaction();
0068         m_transactionData->redo();
0069         undoAdapter->addCommand(KUndo2CommandSP(m_transactionData));
0070         m_transactionData = 0;
0071     }
0072 
0073     KUndo2Command* endAndTake() {
0074         KIS_ASSERT_X(m_transactionData,
0075                      "KisTransaction::endAndTake()",
0076                      "the transaction has been tried to be committed twice");
0077 
0078         m_transactionData->endTransaction();
0079         KisTransactionData *transactionData = m_transactionData;
0080         m_transactionData = 0;
0081 
0082         return transactionData;
0083     }
0084 
0085     void end() {
0086         KIS_ASSERT_X(m_transactionData, "KisTransaction::end()", "nothing to end!");
0087         /**
0088          * We will not call endTransaction for m_transactionData,
0089          * we'll just kill it, and it'll report about it's death to
0090          * the memento manager, so no commit will be made
0091          */
0092         delete m_transactionData;
0093         m_transactionData = 0;
0094     }
0095 
0096     void revert() {
0097         KIS_ASSERT_X(m_transactionData,
0098                      "KisTransaction::reverted()",
0099                      "the transaction is tried to be reverted()"
0100                      "after it has already been added to undo adapter");
0101 
0102         m_transactionData->endTransaction();
0103         /**
0104          * FIXME: Should we emulate first redo() here?
0105          */
0106         m_transactionData->undo();
0107         delete m_transactionData;
0108         m_transactionData = 0;
0109     }
0110 
0111     KUndo2MagicString text() const {
0112         KIS_ASSERT_X(m_transactionData,
0113                      "KisTransaction::text()",
0114                      "the name has been requested after the transaction"
0115                      "has already been ended");
0116         return m_transactionData->text();
0117     }
0118 
0119 protected:
0120     Q_DISABLE_COPY(KisTransaction);
0121 
0122     KisTransaction() : m_transactionData(0) {}
0123     KisTransactionData* m_transactionData;
0124 };
0125 
0126 Q_DECLARE_OPERATORS_FOR_FLAGS(KisTransaction::Flags)
0127 
0128 class KisSelectionTransaction : public KisTransaction
0129 {
0130 public:
0131     KisSelectionTransaction(KisPixelSelectionSP pixelSelection, KUndo2Command* parent = 0)
0132     {
0133         m_transactionData = new KisTransactionData(KUndo2MagicString(), pixelSelection, false, 0, parent, false);
0134     }
0135 
0136     KisSelectionTransaction(const KUndo2MagicString& name, KisPixelSelectionSP pixelSelection, KUndo2Command* parent = 0)
0137     {
0138         m_transactionData = new KisTransactionData(name, pixelSelection, false, 0, parent, false);
0139     }
0140 };
0141 
0142 #endif /* KIS_TRANSACTION_H_ */
0143