File indexing completed on 2024-10-27 04:07:34
0001 /* 0002 * SPDX-FileCopyrightText: 2007 Sven Langkamp <sven.langkamp@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_shape_selection_model.h" 0008 #include "kis_debug.h" 0009 0010 #include <KoShapeContainer.h> 0011 #include <KoShapeBackground.h> 0012 #include <KoShapeManager.h> 0013 0014 #include "kis_shape_selection.h" 0015 #include "kis_selection.h" 0016 #include "kis_image.h" 0017 #include "kis_update_selection_job.h" 0018 0019 0020 KisShapeSelectionModel::KisShapeSelectionModel(KisImageResolutionProxySP resolutionProxy, KisSelectionWSP selection, KisShapeSelection* shapeSelection) 0021 : m_resolutionProxy(resolutionProxy) 0022 , m_parentSelection(selection) 0023 , m_shapeSelection(shapeSelection) 0024 , m_updatesEnabled(true) 0025 { 0026 } 0027 0028 KisShapeSelectionModel::~KisShapeSelectionModel() 0029 { 0030 m_parentSelection = 0; 0031 } 0032 0033 void KisShapeSelectionModel::requestUpdate(const QRect &updateRect) 0034 { 0035 m_shapeSelection->recalculateOutlineCache(); 0036 0037 if (m_updatesEnabled) { 0038 m_parentSelection->requestCompressedProjectionUpdate(updateRect); 0039 } 0040 } 0041 0042 void KisShapeSelectionModel::setResolutionProxy(KisImageResolutionProxySP newResolutionProxy) 0043 { 0044 const bool resolutionChanged = !m_resolutionProxy->compareResolution(*newResolutionProxy); 0045 0046 m_resolutionProxy = newResolutionProxy; 0047 0048 if (resolutionChanged) { 0049 requestUpdate(QRect()); 0050 } 0051 } 0052 0053 KisImageResolutionProxySP KisShapeSelectionModel::resolutionProxy() const 0054 { 0055 return m_resolutionProxy; 0056 } 0057 0058 void KisShapeSelectionModel::add(KoShape *child) 0059 { 0060 if (!m_shapeSelection) return; 0061 0062 if (m_shapeMap.contains(child)) 0063 return; 0064 0065 child->setStroke(KoShapeStrokeModelSP()); 0066 child->setBackground( QSharedPointer<KoShapeBackground>(0)); 0067 m_shapeMap.insert(child, child->boundingRect()); 0068 m_shapeSelection->shapeManager()->addShape(child); 0069 0070 QRect updateRect = child->boundingRect().toAlignedRect(); 0071 QTransform matrix; 0072 matrix.scale(m_resolutionProxy->xRes(), m_resolutionProxy->yRes()); 0073 updateRect = matrix.mapRect(updateRect); 0074 0075 if (m_shapeMap.count() == 1) { 0076 // The shape is the first one, so the shape selection just got created 0077 // Pixel selection provides no longer the datamanager of the selection 0078 // so update the whole selection 0079 requestUpdate(QRect()); 0080 } else { 0081 requestUpdate(updateRect); 0082 } 0083 } 0084 0085 void KisShapeSelectionModel::remove(KoShape *child) 0086 { 0087 if (!m_shapeMap.contains(child)) return; 0088 0089 QRect updateRect = child->boundingRect().toAlignedRect(); 0090 m_shapeMap.remove(child); 0091 0092 if (m_shapeSelection) { 0093 m_shapeSelection->shapeManager()->remove(child); 0094 } 0095 QTransform matrix; 0096 matrix.scale(m_resolutionProxy->xRes(), m_resolutionProxy->yRes()); 0097 updateRect = matrix.mapRect(updateRect); 0098 if (m_shapeSelection) { // No m_shapeSelection indicates the selection is being deleted 0099 requestUpdate(updateRect); 0100 } 0101 } 0102 0103 void KisShapeSelectionModel::setUpdatesEnabled(bool enabled) 0104 { 0105 m_updatesEnabled = enabled; 0106 } 0107 0108 bool KisShapeSelectionModel::updatesEnabled() const 0109 { 0110 return m_updatesEnabled; 0111 } 0112 0113 void KisShapeSelectionModel::setClipped(const KoShape *child, bool clipping) 0114 { 0115 Q_UNUSED(child); 0116 Q_UNUSED(clipping); 0117 } 0118 0119 bool KisShapeSelectionModel::isClipped(const KoShape *child) const 0120 { 0121 Q_UNUSED(child); 0122 return false; 0123 } 0124 0125 void KisShapeSelectionModel::setInheritsTransform(const KoShape *shape, bool inherit) 0126 { 0127 Q_UNUSED(shape); 0128 Q_UNUSED(inherit); 0129 } 0130 0131 bool KisShapeSelectionModel::inheritsTransform(const KoShape *shape) const 0132 { 0133 Q_UNUSED(shape); 0134 return false; 0135 } 0136 0137 int KisShapeSelectionModel::count() const 0138 { 0139 return m_shapeMap.count(); 0140 } 0141 0142 QList<KoShape*> KisShapeSelectionModel::shapes() const 0143 { 0144 return QList<KoShape*>(m_shapeMap.keys()); 0145 } 0146 void KisShapeSelectionModel::containerChanged(KoShapeContainer *, KoShape::ChangeType) 0147 { 0148 } 0149 0150 void KisShapeSelectionModel::childChanged(KoShape * child, KoShape::ChangeType type) 0151 { 0152 if (!m_shapeSelection) return; 0153 0154 // TODO: check if still needed 0155 if (type == KoShape::ParentChanged) return; 0156 0157 QRectF changedRect = m_shapeMap[child]; 0158 changedRect = changedRect.united(child->boundingRect()); 0159 m_shapeMap[child] = child->boundingRect(); 0160 0161 QTransform matrix; 0162 matrix.scale(m_resolutionProxy->xRes(), m_resolutionProxy->yRes()); 0163 changedRect = matrix.mapRect(changedRect); 0164 0165 requestUpdate(changedRect.toAlignedRect()); 0166 } 0167 0168 void KisShapeSelectionModel::setShapeSelection(KisShapeSelection* selection) 0169 { 0170 m_shapeSelection = selection; 0171 }