File indexing completed on 2024-06-23 04:28:25

0001 /*
0002  *  SPDX-FileCopyrightText: 2013 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef __TRANSFORM_STROKE_STRATEGY_H
0008 #define __TRANSFORM_STROKE_STRATEGY_H
0009 
0010 #include <QObject>
0011 #include <QMutex>
0012 #include <KoUpdater.h>
0013 #include <kis_stroke_strategy_undo_command_based.h>
0014 #include <kis_types.h>
0015 #include "tool_transform_args.h"
0016 #include <kis_processing_visitor.h>
0017 #include <kritatooltransform_export.h>
0018 #include <boost/optional.hpp>
0019 #include "commands_new/KisUpdateCommandEx.h"
0020 
0021 class KisPostExecutionUndoAdapter;
0022 class TransformTransactionProperties;
0023 class KisUpdatesFacade;
0024 class KisDecoratedNodeInterface;
0025 
0026 
0027 class TransformStrokeStrategy : public QObject, public KisStrokeStrategyUndoCommandBased
0028 {
0029     Q_OBJECT
0030 public:
0031     struct TransformAllData : public KisStrokeJobData {
0032         TransformAllData(const ToolTransformArgs &_config)
0033             : KisStrokeJobData(SEQUENTIAL, NORMAL),
0034               config(_config) {}
0035 
0036         ToolTransformArgs config;
0037     };
0038 
0039 
0040     class TransformData : public KisStrokeJobData {
0041     public:
0042         enum Destination {
0043             PAINT_DEVICE,
0044             SELECTION,
0045         };
0046 
0047     public:
0048     TransformData(Destination _destination, const ToolTransformArgs &_config, KisNodeSP _node)
0049             : KisStrokeJobData(CONCURRENT, NORMAL),
0050             destination(_destination),
0051             config(_config),
0052             node(_node)
0053         {
0054         }
0055 
0056         Destination destination;
0057         ToolTransformArgs config;
0058         KisNodeSP node;
0059     };
0060 
0061     class ClearSelectionData : public KisStrokeJobData {
0062     public:
0063         ClearSelectionData(KisNodeSP _node)
0064             : KisStrokeJobData(SEQUENTIAL, EXCLUSIVE),
0065               node(_node)
0066         {
0067         }
0068         KisNodeSP node;
0069     };
0070 
0071     class PreparePreviewData : public KisStrokeJobData {
0072     public:
0073         PreparePreviewData()
0074             : KisStrokeJobData(BARRIER, NORMAL)
0075         {
0076         }
0077     };
0078 
0079 public:
0080     TransformStrokeStrategy(ToolTransformArgs::TransformMode mode,
0081                             const QString &filterId,
0082                             bool forceReset,
0083                             KisNodeList rootNodes,
0084                             KisSelectionSP selection,
0085                             KisStrokeUndoFacade *undoFacade, KisUpdatesFacade *updatesFacade);
0086 
0087     ~TransformStrokeStrategy() override;
0088 
0089     void initStrokeCallback() override;
0090     void finishStrokeCallback() override;
0091     void cancelStrokeCallback() override;
0092     void doStrokeCallback(KisStrokeJobData *data) override;
0093 
0094 Q_SIGNALS:
0095     void sigTransactionGenerated(TransformTransactionProperties transaction, ToolTransformArgs args, void *cookie);
0096     void sigPreviewDeviceReady(KisPaintDeviceSP device);
0097 
0098 protected:
0099     void postProcessToplevelCommand(KUndo2Command *command) override;
0100 
0101 private:
0102     KoUpdaterPtr fetchUpdater(KisNodeSP node);
0103 
0104     void clearSelection(KisPaintDeviceSP device);
0105 
0106     bool checkBelongsToSelection(KisPaintDeviceSP device) const;
0107 
0108     KisPaintDeviceSP createDeviceCache(KisPaintDeviceSP src);
0109 
0110     bool haveDeviceInCache(KisPaintDeviceSP src);
0111     void putDeviceCache(KisPaintDeviceSP src, KisPaintDeviceSP cache);
0112     KisPaintDeviceSP getDeviceCache(KisPaintDeviceSP src);
0113 
0114     void finishStrokeImpl(bool applyTransform,
0115                           const ToolTransformArgs &args);
0116 
0117 private:
0118     KisUpdatesFacade *m_updatesFacade;
0119     KisBatchNodeUpdateSP m_updateData;
0120     bool m_updatesDisabled = false;
0121     ToolTransformArgs::TransformMode m_mode;
0122     QString m_filterId;
0123     bool m_forceReset;
0124 
0125     KisSelectionSP m_selection;
0126 
0127     QMutex m_devicesCacheMutex;
0128     QHash<KisPaintDevice*, KisPaintDeviceSP> m_devicesCacheHash;
0129 
0130     KisTransformMaskSP writeToTransformMask;
0131 
0132     ToolTransformArgs m_initialTransformArgs;
0133     boost::optional<ToolTransformArgs> m_savedTransformArgs;
0134     KisNodeList m_rootNodes;
0135     KisNodeList m_processedNodes;
0136     int m_currentTime = -1;
0137     QList<KisSelectionSP> m_deactivatedSelections;
0138     QList<KisNodeSP> m_hiddenProjectionLeaves;
0139     QList<KisSelectionMaskSP> m_deactivatedOverlaySelectionMasks;
0140     QVector<KisDecoratedNodeInterface*> m_disabledDecoratedNodes;
0141 
0142     const KisSavedMacroCommand *m_overriddenCommand = 0;
0143     QVector<const KUndo2Command*> m_skippedWhileMergeCommands;
0144 
0145     bool m_finalizingActionsStarted = false;
0146 };
0147 
0148 #endif /* __TRANSFORM_STROKE_STRATEGY_H */