Krita Source Code Documentation
Loading...
Searching...
No Matches
KoShapeContainer.cpp
Go to the documentation of this file.
1/* This file is part of the KDE project
2 * SPDX-FileCopyrightText: 2006-2010 Thomas Zander <zander@kde.org>
3 * SPDX-FileCopyrightText: 2007 Jan Hambrecht <jaham@gmx.net>
4 *
5 * SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7#include "KoShapeContainer.h"
10#include "KoShapeStrokeModel.h"
13
14#include <QPainter>
15#include <QPainterPath>
16
17#include "kis_painting_tweaks.h"
18#include "kis_assert.h"
19
20KoShapeContainer::Private::Private(KoShapeContainer *q)
21 : shapeInterface(q)
22 , model(0)
23{
24}
25
26KoShapeContainer::Private::~Private()
27{
28 delete model;
29}
30
31KoShapeContainer::Private::Private(const KoShapeContainer::Private &rhs, KoShapeContainer *q)
32 : shapeInterface(q)
33 , model(0)
34{
35 Q_UNUSED(rhs);
36}
37
39 : KoShape()
40 , d(new Private(this))
41{
42 d->model = model;
43}
44
46 : KoShape(rhs)
47 , d(new Private(*(rhs.d.data()), this))
48{
49}
50
52{
53 if (d->model) {
54 d->model->deleteOwnedShapes();
55 }
56}
57
59{
60 shape->setParent(this);
61}
62
64{
65 shape->setParent(0);
66}
67
69{
70 if (d->model == 0)
71 return 0;
72 return d->model->count();
73}
74
75void KoShapeContainer::setClipped(const KoShape *child, bool clipping)
76{
77 if (d->model == 0)
78 return;
79 d->model->setClipped(child, clipping);
80}
81
82void KoShapeContainer::setInheritsTransform(const KoShape *shape, bool inherit)
83{
84 if (d->model == 0)
85 return;
86 d->model->setInheritsTransform(shape, inherit);
87}
88
90{
91 if (d->model == 0)
92 return false;
93 return d->model->inheritsTransform(shape);
94}
95
96void KoShapeContainer::paint(QPainter &painter) const
97{
98 // Shape container paints only its internal component part. All the children are rendered
99 // by the shape manager itself
100
101 painter.save();
102 paintComponent(painter);
103 painter.restore();
104}
105
107{
108 Q_UNUSED(shape);
109 if (d->model == 0)
110 return;
111 if (!(type == RotationChanged || type == ScaleChanged || type == ShearChanged
112 || type == SizeChanged || type == PositionChanged || type == GenericMatrixChange))
113 return;
114 d->model->containerChanged(this, type);
115 Q_FOREACH (KoShape *shape, d->model->shapes())
116 shape->notifyChanged();
117}
118
119bool KoShapeContainer::isClipped(const KoShape *child) const
120{
121 if (d->model == 0) // throw exception??
122 return false;
123 return d->model->isClipped(child);
124}
125
127{
129 if (d->model) {
130 Q_FOREACH (KoShape *shape, d->model->shapes()) {
131 shape->update();
132 }
133 }
134}
135
137{
138 if (d->model == 0)
139 return QList<KoShape*>();
140
141 return d->model->shapes();
142}
143
145{
146 return d->model;
147}
148
150{
151 d->model = model;
152}
153
155{
157 // HACK ALERT: the shapes are copied inside the model,
158 // but we still need to connect the to the
159 // hierarchy here!
160 if (d->model) {
161 Q_FOREACH (KoShape *shape, d->model->shapes()) {
162 if (shape) { // Note: shape can be 0 because not all shapes
163 // implement cloneShape, e.g. the text shape.
164 shape->setParent(this);
165 }
166 }
167 }
168}
169
171{
172 return &d->shapeInterface;
173}
174
179
181{
182 KoShapeContainer::Private * const d = q->d.data();
183
185
186 if (shape->parent() == q && q->shapes().contains(shape)) {
187 return;
188 }
189
190 // TODO add a method to create a default model depending on the shape container
191 if (!d->model) {
192 d->model = new SimpleShapeContainerModel();
193 }
194
195 if (shape->parent() && shape->parent() != q) {
196 shape->parent()->shapeInterface()->removeShape(shape);
197 }
198
199 d->model->add(shape);
200 d->model->shapeHasBeenAddedToHierarchy(shape, q);
201}
202
204{
205 KoShapeContainer::Private * const d = q->d.data();
206
209 KIS_SAFE_ASSERT_RECOVER_RETURN(d->model->shapes().contains(shape));
210
211 d->model->shapeToBeRemovedFromHierarchy(shape, q);
212 d->model->remove(shape);
213
214 KoShapeContainer *grandparent = q->parent();
215 if (grandparent) {
216 grandparent->model()->childChanged(q, KoShape::ChildChanged);
217 }
218}
virtual void childChanged(KoShape *shape, KoShape::ChangeType type)
void removeShape(KoShape *shape)
bool isClipped(const KoShape *child) const
KoShapeContainer::ShapeInterface shapeInterface
void setModelInit(KoShapeContainerModel *model)
~KoShapeContainer() override
void update() const override
reimplemented
QList< KoShape * > shapes() const
void paint(QPainter &painter) const override
reimplemented
void setModel(KoShapeContainerModel *model)
void addShape(KoShape *shape)
bool inheritsTransform(const KoShape *shape) const
KoShapeContainerModel * model
void setInheritsTransform(const KoShape *shape, bool inherit)
KoShapeContainer(KoShapeContainerModel *model=0)
QScopedPointer< Private > d
void setClipped(const KoShape *child, bool clipping)
virtual void paintComponent(QPainter &painter) const =0
Paint the component Implement this method to allow the shape to paint itself, just like the KoShape::...
void shapeChanged(ChangeType type, KoShape *shape=0) override
virtual void update() const
Definition KoShape.cpp:605
KoShapeContainer * parent() const
Definition KoShape.cpp:1039
ChangeType
Used by shapeChanged() to select which change was made.
Definition KoShape.h:95
@ RotationChanged
used after a setRotation()
Definition KoShape.h:97
@ PositionChanged
used after a setPosition()
Definition KoShape.h:96
@ ShearChanged
used after a shear()
Definition KoShape.h:99
@ ChildChanged
a child of a container was changed/removed. This is propagated to all parents
Definition KoShape.h:112
@ ScaleChanged
used after a scale()
Definition KoShape.h:98
@ SizeChanged
used after a setSize()
Definition KoShape.h:100
@ GenericMatrixChange
used after the matrix was changed without knowing which property explicitly changed
Definition KoShape.h:101
void notifyChanged()
Definition KoShape.cpp:698
void setParent(KoShapeContainer *parent)
Definition KoShape.cpp:535
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128