File indexing completed on 2024-05-12 15:58:51
0001 /* 0002 * SPDX-FileCopyrightText: 2021 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "KisInterstrokeDataTransactionWrapperFactory.h" 0008 0009 #include <kundo2command.h> 0010 0011 #include "KisInterstrokeData.h" 0012 #include "KisInterstrokeDataFactory.h" 0013 0014 #include <kis_paint_device.h> 0015 #include <kis_pointer_utils.h> 0016 #include <kis_command_utils.h> 0017 0018 0019 namespace { 0020 struct BeginInterstrokeDataTransactionCommand : public KUndo2Command 0021 { 0022 BeginInterstrokeDataTransactionCommand(KisPaintDeviceSP device, KisInterstrokeDataSP newData) 0023 : m_device(device), 0024 m_interstrokeData(newData) 0025 { 0026 } 0027 0028 void redo() override { 0029 if (m_firstRedo) { 0030 if (m_device->interstrokeData() != m_interstrokeData) { 0031 m_dataSwapCommand.reset(m_device->createChangeInterstrokeDataCommand(m_interstrokeData)); 0032 m_dataSwapCommand->redo(); 0033 } 0034 0035 if (m_interstrokeData) { 0036 m_interstrokeData->beginTransaction(); 0037 } 0038 0039 m_firstRedo = false; 0040 } else if (m_dataSwapCommand) { 0041 m_dataSwapCommand->redo(); 0042 0043 } 0044 } 0045 0046 void undo() override { 0047 if (m_dataSwapCommand) { 0048 m_dataSwapCommand->undo(); 0049 } 0050 } 0051 0052 private: 0053 bool m_firstRedo {true}; 0054 KisPaintDeviceSP m_device; 0055 KisInterstrokeDataSP m_interstrokeData; 0056 QScopedPointer<KUndo2Command> m_dataSwapCommand; 0057 }; 0058 0059 struct EndInterstrokeDataTransactionCommand : public KUndo2Command 0060 { 0061 EndInterstrokeDataTransactionCommand(KisPaintDeviceSP device) 0062 : m_device(device) 0063 { 0064 } 0065 0066 void redo() override { 0067 KisInterstrokeDataSP data = m_device->interstrokeData(); 0068 0069 if (!m_transactionCommand && data) { 0070 m_transactionCommand.reset(data->endTransaction()); 0071 } 0072 0073 if (m_transactionCommand) { 0074 m_transactionCommand->redo(); 0075 } 0076 } 0077 0078 void undo() override { 0079 if (m_transactionCommand) { 0080 m_transactionCommand->undo(); 0081 } 0082 } 0083 0084 private: 0085 KisPaintDeviceSP m_device; 0086 QScopedPointer<KUndo2Command> m_transactionCommand; 0087 }; 0088 0089 } 0090 0091 0092 struct KisInterstrokeDataTransactionWrapperFactory::Private 0093 { 0094 QScopedPointer<KisInterstrokeDataFactory> factory; 0095 KisPaintDeviceSP device; 0096 bool supportsContinuedInterstrokeData = true; 0097 }; 0098 0099 KisInterstrokeDataTransactionWrapperFactory::KisInterstrokeDataTransactionWrapperFactory(KisInterstrokeDataFactory *factory, bool supportsContinuedInterstrokeData) 0100 : m_d(new Private()) 0101 { 0102 m_d->factory.reset(factory); 0103 m_d->supportsContinuedInterstrokeData = supportsContinuedInterstrokeData; 0104 } 0105 0106 KisInterstrokeDataTransactionWrapperFactory::~KisInterstrokeDataTransactionWrapperFactory() 0107 { 0108 } 0109 0110 KUndo2Command *KisInterstrokeDataTransactionWrapperFactory::createBeginTransactionCommand(KisPaintDeviceSP device) 0111 { 0112 KisInterstrokeDataSP data = device->interstrokeData(); 0113 if (m_d->factory) { 0114 if (!m_d->supportsContinuedInterstrokeData || 0115 !data || 0116 !data->isStillCompatible() || 0117 !m_d->factory->isCompatible(data.data())) { 0118 0119 data = toQShared(m_d->factory->create(device)); 0120 } 0121 } else { 0122 data.clear(); 0123 } 0124 0125 KUndo2Command *cmd = 0; 0126 0127 if (device->interstrokeData() || data) { 0128 m_d->device = device; 0129 cmd = new BeginInterstrokeDataTransactionCommand(device, data); 0130 } 0131 0132 return cmd; 0133 } 0134 0135 KUndo2Command *KisInterstrokeDataTransactionWrapperFactory::createEndTransactionCommand() 0136 { 0137 KUndo2Command *result = 0; 0138 0139 if (m_d->device) { 0140 if (m_d->supportsContinuedInterstrokeData) { 0141 result = new EndInterstrokeDataTransactionCommand(m_d->device); 0142 } else { 0143 KisCommandUtils::CompositeCommand *composite 0144 = new KisCommandUtils::CompositeCommand(); 0145 0146 composite->addCommand(new EndInterstrokeDataTransactionCommand(m_d->device)); 0147 composite->addCommand(new BeginInterstrokeDataTransactionCommand(m_d->device, 0)); 0148 0149 result = composite; 0150 } 0151 } 0152 0153 return result; 0154 }