File indexing completed on 2025-02-02 04:16:07
0001 /* 0002 * SPDX-License-Identifier: GPL-3.0-or-later 0003 */ 0004 0005 #include "KisSelectionBasedProcessingHelper.h" 0006 0007 #include "kis_paint_device.h" 0008 #include "kis_painter.h" 0009 #include "kis_selection.h" 0010 #include "kis_transaction_based_command.h" 0011 #include "kis_transaction.h" 0012 #include "kis_undo_adapter.h" 0013 0014 KisSelectionBasedProcessingHelper::KisSelectionBasedProcessingHelper(KisSelectionSP selection, Functor func) 0015 : m_selection(selection), 0016 m_func(func) 0017 { 0018 } 0019 0020 void KisSelectionBasedProcessingHelper::setSelection(KisSelectionSP selection) 0021 { 0022 m_selection = selection; 0023 } 0024 0025 KUndo2Command *KisSelectionBasedProcessingHelper::createInitCommand(Functor func) 0026 { 0027 if (!m_selection) return 0; 0028 0029 struct ProcessSelectionCommand : KisTransactionBasedCommand { 0030 ProcessSelectionCommand(KisSelectionSP selection, 0031 KisSelectionSP cutSelection, 0032 std::function<void(KisPaintDeviceSP)> func) 0033 : m_selection(selection), 0034 m_cutSelection(cutSelection), 0035 m_func(func) 0036 { 0037 } 0038 0039 KUndo2Command* paint() override { 0040 m_cutSelection->pixelSelection()->makeCloneFromRough(m_selection->pixelSelection(), m_selection->selectedRect()); 0041 0042 KisTransaction t(m_selection->pixelSelection()); 0043 m_func(m_selection->pixelSelection()); 0044 0045 return t.endAndTake(); 0046 } 0047 0048 KisSelectionSP m_selection; 0049 KisSelectionSP m_cutSelection; 0050 Functor m_func; 0051 }; 0052 0053 m_cutSelection = new KisSelection(); 0054 return new ProcessSelectionCommand(m_selection, m_cutSelection, func); 0055 } 0056 0057 KUndo2Command *KisSelectionBasedProcessingHelper::createInitCommand() 0058 { 0059 return createInitCommand(m_func); 0060 } 0061 0062 void KisSelectionBasedProcessingHelper::transformPaintDevice(KisPaintDeviceSP device, KisUndoAdapter *undoAdapter) 0063 { 0064 transformPaintDevice(device, undoAdapter, m_func); 0065 } 0066 0067 void KisSelectionBasedProcessingHelper::transformPaintDevice(KisPaintDeviceSP device, KisUndoAdapter *undoAdapter, Functor func) 0068 { 0069 KIS_SAFE_ASSERT_RECOVER_RETURN(!!m_selection == !!m_cutSelection); 0070 0071 if (m_selection && m_cutSelection) { 0072 // we have already processed the selection in the init command so try to skip it 0073 if (device != static_cast<KisPaintDevice*>(m_selection->pixelSelection().data())) { 0074 KisTransaction transaction(device); 0075 0076 const QRect cutBounds = m_cutSelection->selectedExactRect(); 0077 const QRect pasteBounds = m_selection->selectedExactRect(); 0078 0079 0080 KisPaintDeviceSP tempDev = new KisPaintDevice(device->colorSpace()); 0081 tempDev->makeCloneFromRough(device, cutBounds); 0082 0083 func(tempDev); 0084 0085 device->clearSelection(m_cutSelection); 0086 KisPainter::copyAreaOptimized(pasteBounds.topLeft(), tempDev, device, pasteBounds, m_selection); 0087 transaction.commit(undoAdapter); 0088 } 0089 } else { 0090 KisTransaction transaction(device); 0091 func(device); 0092 transaction.commit(undoAdapter); 0093 } 0094 }