File indexing completed on 2024-05-12 15:56:54

0001 /* This file is part of the KDE project
0002  * SPDX-FileCopyrightText: 2006-2007, 2010 Thomas Zander <zander@kde.org>
0003  * SPDX-FileCopyrightText: 2011 Boudewijn Rempt <boud@valdyas.org>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 #ifndef SIMPLESHAPECONTAINERMODEL_H
0008 #define SIMPLESHAPECONTAINERMODEL_H
0009 
0010 #include "KoShapeContainerModel.h"
0011 #include <kis_debug.h>
0012 #include <KoShapeManager.h>
0013 
0014 /// \internal
0015 class SimpleShapeContainerModel: public KoShapeContainerModel
0016 {
0017 public:
0018     SimpleShapeContainerModel() {}
0019     ~SimpleShapeContainerModel() override {}
0020 
0021     SimpleShapeContainerModel(const SimpleShapeContainerModel &rhs)
0022         : KoShapeContainerModel(rhs),
0023           m_inheritsTransform(rhs.m_inheritsTransform),
0024           m_clipped(rhs.m_clipped)
0025     {
0026         Q_FOREACH (KoShape *shape, rhs.m_members) {
0027             KoShape *clone = shape->cloneShape();
0028             KIS_SAFE_ASSERT_RECOVER_NOOP(clone && "Copying this shape is not implemented!");
0029             if (clone) {
0030                 m_members << clone;
0031             }
0032         }
0033 
0034         KIS_ASSERT_RECOVER(m_members.size() == m_inheritsTransform.size() &&
0035                            m_members.size() == m_clipped.size())
0036         {
0037             qDeleteAll(m_members);
0038             m_members.clear();
0039             m_inheritsTransform.clear();
0040             m_clipped.clear();
0041         }
0042     }
0043 
0044     void add(KoShape *child) override {
0045         if (m_members.contains(child))
0046             return;
0047         m_members.append(child);
0048         m_clipped.append(false);
0049         m_inheritsTransform.append(true);
0050     }
0051     void setClipped(const KoShape *shape, bool value) override {
0052         const int index = indexOf(shape);
0053         KIS_SAFE_ASSERT_RECOVER_RETURN(index >= 0);
0054         m_clipped[index] = value;
0055     }
0056     bool isClipped(const KoShape *shape) const override {
0057         const int index = indexOf(shape);
0058         KIS_SAFE_ASSERT_RECOVER(index >= 0) { return false;}
0059         return m_clipped[index];
0060     }
0061     void remove(KoShape *shape) override {
0062         const int index = indexOf(shape);
0063         KIS_SAFE_ASSERT_RECOVER_RETURN(index >= 0);
0064 
0065         m_members.removeAt(index);
0066         m_clipped.removeAt(index);
0067         m_inheritsTransform.removeAt(index);
0068     }
0069     int count() const override {
0070         return m_members.count();
0071     }
0072     QList<KoShape*> shapes() const override {
0073         return QList<KoShape*>(m_members);
0074     }
0075     void containerChanged(KoShapeContainer *, KoShape::ChangeType) override { }
0076 
0077     void setInheritsTransform(const KoShape *shape, bool value) override {
0078         const int index = indexOf(shape);
0079         KIS_SAFE_ASSERT_RECOVER_RETURN(index >= 0);
0080         m_inheritsTransform[index] = value;
0081     }
0082     bool inheritsTransform(const KoShape *shape) const override {
0083         const int index = indexOf(shape);
0084         KIS_SAFE_ASSERT_RECOVER(index >= 0)  { return true;}
0085         return m_inheritsTransform[index];
0086     }
0087 
0088     void proposeMove(KoShape *shape, QPointF &move) override
0089     {
0090         KoShapeContainer *parent = shape->parent();
0091         bool allowedToMove = true;
0092         while (allowedToMove && parent) {
0093             allowedToMove = parent->isShapeEditable();
0094             parent = parent->parent();
0095         }
0096         if (! allowedToMove) {
0097             move.setX(0);
0098             move.setY(0);
0099         }
0100     }
0101 
0102     void shapeHasBeenAddedToHierarchy(KoShape *shape, KoShapeContainer *addedToSubtree) override {
0103         if (m_associatedRootShapeManager) {
0104             m_associatedRootShapeManager->addShape(shape);
0105         }
0106         KoShapeContainerModel::shapeHasBeenAddedToHierarchy(shape, addedToSubtree);
0107     }
0108 
0109     void shapeToBeRemovedFromHierarchy(KoShape *shape, KoShapeContainer *removedFromSubtree) override {
0110         if (m_associatedRootShapeManager) {
0111             m_associatedRootShapeManager->remove(shape);
0112         }
0113         KoShapeContainerModel::shapeToBeRemovedFromHierarchy(shape, removedFromSubtree);
0114     }
0115 
0116     KoShapeManager *associatedRootShapeManager() const {
0117         return m_associatedRootShapeManager;
0118     }
0119 
0120     /**
0121      * If the container is the root of shapes hierarchy, it should also track the content
0122      * of the shape manager. Add all added/removed shapes should be also
0123      * added to \p shapeManager.
0124      */
0125     void setAssociatedRootShapeManager(KoShapeManager *manager) {
0126         if (m_associatedRootShapeManager) {
0127             Q_FOREACH(KoShape *shape, this->shapes()) {
0128                 m_associatedRootShapeManager->remove(shape);
0129             }
0130         }
0131 
0132         m_associatedRootShapeManager = manager;
0133 
0134         if (m_associatedRootShapeManager) {
0135             Q_FOREACH(KoShape *shape, this->shapes()) {
0136                 m_associatedRootShapeManager->addShape(shape);
0137             }
0138         }
0139     }
0140 
0141 private:
0142     int indexOf(const KoShape *shape) const {
0143         // workaround indexOf constness!
0144         return m_members.indexOf(const_cast<KoShape*>(shape));
0145     }
0146 
0147 private: // members
0148     QList <KoShape *> m_members;
0149     QList <bool> m_inheritsTransform;
0150     QList <bool> m_clipped;
0151     KoShapeManager *m_associatedRootShapeManager = 0;
0152 };
0153 
0154 #endif