Krita Source Code Documentation
Loading...
Searching...
No Matches
KoShape.cpp
Go to the documentation of this file.
1/* This file is part of the KDE project
2 SPDX-FileCopyrightText: 2006 C. Boemann Rasmussen <cbo@boemann.dk>
3 SPDX-FileCopyrightText: 2006-2010 Thomas Zander <zander@kde.org>
4 SPDX-FileCopyrightText: 2006-2010 Thorsten Zachmann <zachmann@kde.org>
5 SPDX-FileCopyrightText: 2007-2009, 2011 Jan Hambrecht <jaham@gmx.net>
6 SPDX-FileCopyrightText: 2010 Boudewijn Rempt <boud@valdyas.org>
7
8 SPDX-License-Identifier: LGPL-2.0-or-later
9*/
10
11#include <limits>
12
13#include "KisMpl.h"
14#include "KoShape.h"
15#include "KoShape_p.h"
16#include "KoShapeContainer.h"
17#include "KoShapeLayer.h"
19#include "KoSelection.h"
20#include "KoPointerEvent.h"
21#include "KoInsets.h"
22#include "KoShapeStrokeModel.h"
23#include "KoShapeBackground.h"
24#include "KoColorBackground.h"
25#include "KoHatchBackground.h"
27#include "KoPatternBackground.h"
28#include "KoShapeManager.h"
29#include "KoShapeUserData.h"
32#include "KoViewConverter.h"
33#include "KoShapeStroke.h"
34#include "KoClipPath.h"
35#include "KoPathShape.h"
36#include <KoSnapData.h>
37
38#include <KoXmlWriter.h>
39#include <KoXmlNS.h>
40#include <KoUnit.h>
41
42#include <QPainter>
43#include <QVariant>
44#include <QPainterPath>
45#include <QList>
46#include <QMap>
47#include <FlakeDebug.h>
48
49#include "kis_assert.h"
50
52
53// KoShape::Private
54
56 : QSharedData()
57 , size(50, 50)
58 , transparency(0.0)
59 , zIndex(0)
60 , visible(true)
61 , printable(true)
62 , geometryProtected(false)
63 , keepAspect(false)
64 , selectable(true)
65 , protectContent(false)
66 , paintOrder(defaultPaintOrder())
67 , inheritPaintOrder(true)
68{ }
69
71 : QSharedData()
72 , size(rhs.size)
73 , shapeId(rhs.shapeId)
74 , name(rhs.name)
75 , localMatrix(rhs.localMatrix)
76 , userData(rhs.userData ? rhs.userData->clone() : 0)
77 , stroke(rhs.stroke)
78 , fill(rhs.fill)
81 , clipPath(rhs.clipPath ? rhs.clipPath->clone() : 0)
82 , clipMask(rhs.clipMask ? rhs.clipMask->clone() : 0)
83 , additionalAttributes(rhs.additionalAttributes)
84 , additionalStyleAttributes(rhs.additionalStyleAttributes)
86 , hyperLink(rhs.hyperLink)
87
88 , zIndex(rhs.zIndex)
89 , visible(rhs.visible)
90 , printable(rhs.visible)
91 , geometryProtected(rhs.geometryProtected)
92 , keepAspect(rhs.keepAspect)
93 , selectable(rhs.selectable)
94 , protectContent(rhs.protectContent)
95
98{
99}
100
104
106{
107 if (d->parent)
108 d->parent->model()->childChanged(this, type);
109
110 this->shapeChanged(type);
111
112 Q_FOREACH (KoShape * shape, d->dependees) {
113 shape->shapeChanged(type, this);
114 }
115
116 Q_FOREACH (KoShape::ShapeChangeListener *listener, d->listeners) {
117 listener->notifyShapeChangedImpl(type, this);
118 }
119}
120
122{
123 d->shapeManagers.insert(manager);
124}
125
127{
128 d->shapeManagers.remove(manager);
129}
130
131// ======== KoShape
132
133const qint16 KoShape::maxZIndex = std::numeric_limits<qint16>::max();
134const qint16 KoShape::minZIndex = std::numeric_limits<qint16>::min();
135
137 : d(new Private()),
138 s(new SharedData)
139{
141}
142
144 : d(new Private()),
145 s(rhs.s)
146{
147}
148
150{
152 d->listeners.clear();
161 KIS_SAFE_ASSERT_RECOVER (!d->parent) {
162 d->parent->removeShape(this);
163 }
164
165 KIS_SAFE_ASSERT_RECOVER (d->shapeManagers.isEmpty()) {
166 Q_FOREACH (KoShapeManager *manager, d->shapeManagers) {
167 manager->shapeInterface()->notifyShapeDestructed(this);
168 }
169 d->shapeManagers.clear();
170 }
171}
172
174{
175 KIS_SAFE_ASSERT_RECOVER_NOOP(0 && "not implemented!");
176 qWarning() << shapeId() << "cannot be cloned";
177 return 0;
178}
179
181{
182 KoShape *clonedShape = this->cloneShape();
183
188 KoShape *oldParentShape = this->parent();
189 if (oldParentShape && !oldParentShape->absoluteTransformation().isIdentity()) {
190 clonedShape->applyAbsoluteTransformation(oldParentShape->absoluteTransformation());
191 }
192
193 return clonedShape;
194}
195
196void KoShape::paintStroke(QPainter &painter) const
197{
198 if (stroke()) {
199 stroke()->paint(this, painter);
200 }
201}
202
203void KoShape::paintMarkers(QPainter &painter) const
204{
205 if (stroke()) {
206 stroke()->paintMarkers(this, painter);
207 }
208}
209
210void KoShape::scale(qreal sx, qreal sy)
211{
212 QPointF pos = position();
213 QTransform scaleMatrix;
214 scaleMatrix.translate(pos.x(), pos.y());
215 scaleMatrix.scale(sx, sy);
216 scaleMatrix.translate(-pos.x(), -pos.y());
217 s->localMatrix = s->localMatrix * scaleMatrix;
218
221}
222
223void KoShape::rotate(qreal angle)
224{
225 QPointF center = s->localMatrix.map(QPointF(0.5 * size().width(), 0.5 * size().height()));
226 QTransform rotateMatrix;
227 rotateMatrix.translate(center.x(), center.y());
228 rotateMatrix.rotate(angle);
229 rotateMatrix.translate(-center.x(), -center.y());
230 s->localMatrix = s->localMatrix * rotateMatrix;
231
234}
235
236void KoShape::shear(qreal sx, qreal sy)
237{
238 QPointF pos = position();
239 QTransform shearMatrix;
240 shearMatrix.translate(pos.x(), pos.y());
241 shearMatrix.shear(sx, sy);
242 shearMatrix.translate(-pos.x(), -pos.y());
243 s->localMatrix = s->localMatrix * shearMatrix;
244
247}
248
249void KoShape::setSize(const QSizeF &newSize)
250{
251 QSizeF oldSize(size());
252
253 // always set size, as d->size and size() may vary
254 setSizeImpl(newSize);
255
256 if (oldSize == newSize)
257 return;
258
261}
262
263void KoShape::setSizeImpl(const QSizeF &size) const
264{
265 s->size = size;
266}
267
268void KoShape::setPosition(const QPointF &newPosition)
269{
270 QPointF currentPos = position();
271 if (newPosition == currentPos)
272 return;
273 QTransform translateMatrix;
274 translateMatrix.translate(newPosition.x() - currentPos.x(), newPosition.y() - currentPos.y());
275 s->localMatrix = s->localMatrix * translateMatrix;
276
279}
280
281bool KoShape::hitTest(const QPointF &position) const
282{
283 if (d->parent && d->parent->isClipped(this) && !d->parent->hitTest(position))
284 return false;
285
286 QPointF point = absoluteTransformation().inverted().map(position);
287 QRectF bb = outlineRect();
288
289 if (s->stroke) {
290 KoInsets insets;
291 s->stroke->strokeInsets(this, insets);
292 bb.adjust(-insets.left, -insets.top, insets.right, insets.bottom);
293 }
294 if (bb.contains(point))
295 return true;
296
297 return false;
298}
299
301{
302 QTransform transform = absoluteTransformation();
303 QRectF bb = outlineRect();
304 if (s->stroke) {
305 KoInsets insets;
306 s->stroke->strokeInsets(this, insets);
307 bb.adjust(-insets.left, -insets.top, insets.right, insets.bottom);
308 }
309 bb = transform.mapRect(bb);
310 return bb;
311}
312
314{
315 return std::accumulate(shapes.begin(), shapes.end(), QRectF(),
317}
318
320{
321 return absoluteTransformation().map(outline()).boundingRect();
322}
323
325{
326 return std::accumulate(shapes.begin(), shapes.end(), QRectF(),
328}
329
331{
332 QTransform matrix;
333 // apply parents matrix to inherit any transformations done there.
334 KoShapeContainer * container = d->parent;
335 if (container) {
336 if (container->inheritsTransform(this)) {
337 matrix = container->absoluteTransformation();
338 } else {
339 QSizeF containerSize = container->size();
340 QPointF containerPos = container->absolutePosition() - QPointF(0.5 * containerSize.width(), 0.5 * containerSize.height());
341 matrix.translate(containerPos.x(), containerPos.y());
342 }
343 }
344
345 return s->localMatrix * matrix;
346}
347
348void KoShape::applyAbsoluteTransformation(const QTransform &matrix)
349{
350 QTransform globalMatrix = absoluteTransformation();
351 // the transformation is relative to the global coordinate system
352 // but we want to change the local matrix, so convert the matrix
353 // to be relative to the local coordinate system
354 QTransform transformMatrix = globalMatrix * matrix * globalMatrix.inverted();
355 applyTransformation(transformMatrix);
356}
357
358void KoShape::applyTransformation(const QTransform &matrix)
359{
360 const QTransform newLocalMatrix = matrix * s->localMatrix;
361
362 if (s->localMatrix != newLocalMatrix) {
363 s->localMatrix = newLocalMatrix;
366 }
367}
368
369void KoShape::setTransformation(const QTransform &matrix)
370{
371 if (s->localMatrix != matrix) {
372 s->localMatrix = matrix;
375 }
376}
377
378QTransform KoShape::transformation() const
379{
380 return s->localMatrix;
381}
382
387
389{
408 if (s1 == s2) return false;
409
410 KoShape *parentShapeS1 = s1->parent();
411 KoShape *parentShapeS2 = s2->parent();
412
413 // We basically walk up through the parents until we find a common base parent
414 // To do that we need two loops where the inner loop walks up through the parents
415 // of s2 every time we step up one parent level on s1
416 //
417 // We don't update the index value until after we have seen that it's not a common base
418 // That way we ensure that two children of a common base are sorted according to their respective
419 // z value
420 bool foundCommonParent = false;
421 int index1 = s1->zIndex();
422 int index2 = s2->zIndex();
423 parentShapeS1 = s1;
424 parentShapeS2 = s2;
425 while (parentShapeS1 && !foundCommonParent) {
426 parentShapeS2 = s2;
427 index2 = parentShapeS2->zIndex();
428 while (parentShapeS2) {
429 if (parentShapeS2 == parentShapeS1) {
430 foundCommonParent = true;
431 break;
432 }
433 if (parentShapeS2->childZOrderPolicy() == KoShape::ChildZParentChild) {
434 index2 = parentShapeS2->zIndex();
435 }
436 parentShapeS2 = parentShapeS2->parent();
437 }
438
439 if (!foundCommonParent) {
440 if (parentShapeS1->childZOrderPolicy() == KoShape::ChildZParentChild) {
441 index1 = parentShapeS1->zIndex();
442 }
443 parentShapeS1 = parentShapeS1->parent();
444 }
445 }
446
447 // If the one shape is a parent/child of the other then sort so.
448 if (s1 == parentShapeS2) {
449 return true;
450 }
451 if (s2 == parentShapeS1) {
452 return false;
453 }
454
455 // If we went that far then the z-Index is used for sorting.
456 return index1 < index2;
457}
458
460{
461
462 if (d->parent == parent) {
463 return;
464 }
465
466 if (d->parent) {
468 d->parent = 0;
469 }
470
471
473
474 if (parent && parent != this) {
475 d->parent = parent;
477 }
478
481}
482
483bool KoShape::inheritsTransformFromAny(const QList<KoShape *> ancestorsInQuestion) const
484{
485 bool result = false;
486
487 KoShape *shape = const_cast<KoShape*>(this);
488 while (shape) {
489 KoShapeContainer *parent = shape->parent();
490 if (parent && !parent->inheritsTransform(shape)) {
491 break;
492 }
493
494 if (ancestorsInQuestion.contains(shape)) {
495 result = true;
496 break;
497 }
498
499 shape = parent;
500 }
501
502 return result;
503}
504
505bool KoShape::hasCommonParent(const KoShape *shape) const
506{
507 const KoShape *thisShape = this;
508 while (thisShape) {
510 const KoShape *otherShape = shape;
511 while (otherShape) {
512 if (thisShape == otherShape) {
513 return true;
514 }
515 otherShape = otherShape->parent();
516 }
517
518 thisShape = thisShape->parent();
519 }
520
521 return false;
522}
523
524qint16 KoShape::zIndex() const
525{
526 return s->zIndex;
527}
528
529void KoShape::update() const
530{
531
532 if (!d->shapeManagers.empty()) {
533 const QRectF rect(boundingRect());
534 Q_FOREACH (KoShapeManager * manager, d->shapeManagers) {
535 manager->update(rect, this, true);
536 }
537 }
538}
539
540void KoShape::updateAbsolute(const QRectF &rect) const
541{
542 if (rect.isEmpty() && !rect.isNull()) {
543 return;
544 }
545
546
547 if (!d->shapeManagers.empty() && isVisible()) {
548 Q_FOREACH (KoShapeManager *manager, d->shapeManagers) {
549 manager->update(rect);
550 }
551 }
552}
553
554QPainterPath KoShape::outline() const
555{
556 QPainterPath path;
557 path.addRect(outlineRect());
558 return path;
559}
560
562{
563 const QSizeF s = size();
564 return QRectF(QPointF(0, 0), QSizeF(qMax(s.width(), qreal(0.0001)),
565 qMax(s.height(), qreal(0.0001))));
566}
567
569{
570 const QRectF rc = outlineRect();
571
572 QPointF point = rc.topLeft();
573
574 bool valid = false;
575 QPointF anchoredPoint = KoFlake::anchorToPoint(anchor, rc, &valid);
576 if (valid) {
577 point = anchoredPoint;
578 }
579
580 return absoluteTransformation().map(point);
581}
582
583void KoShape::setAbsolutePosition(const QPointF &newPosition, KoFlake::AnchorPosition anchor)
584{
585 QPointF currentAbsPosition = absolutePosition(anchor);
586 QPointF translate = newPosition - currentAbsPosition;
587 QTransform translateMatrix;
588 translateMatrix.translate(translate.x(), translate.y());
589 applyAbsoluteTransformation(translateMatrix);
592}
593
595{
596 s->size = shape->size();
597 s->zIndex = shape->zIndex();
598 s->visible = shape->isVisible(false);
599
600 // Ensure printable is true by default
601 if (!s->visible)
602 s->printable = true;
603 else
604 s->printable = shape->isPrintable();
605
606 s->geometryProtected = shape->isGeometryProtected();
607 s->protectContent = shape->isContentProtected();
608 s->selectable = shape->isSelectable();
609 s->keepAspect = shape->keepAspectRatio();
610 s->localMatrix = shape->s->localMatrix;
611}
612
614{
615 Q_FOREACH (KoShapeManager * manager, d->shapeManagers) {
616 manager->notifyShapeChanged(this);
617 }
618}
619
621{
622 s->userData.reset(userData);
623}
624
626{
627 return s->userData.data();
628}
629
631{
633
634 return !bg || bg->hasTransparency() || s->transparency > 0.0;
635}
636
637void KoShape::setTransparency(qreal transparency)
638{
639 s->transparency = qBound<qreal>(0.0, transparency, 1.0);
640
643}
644
645qreal KoShape::transparency(bool recursive) const
646{
647 if (!recursive || !parent()) {
648 return s->transparency;
649 } else {
650 const qreal parentOpacity = 1.0-parent()->transparency(recursive);
651 const qreal childOpacity = 1.0-s->transparency;
652 return 1.0-(parentOpacity*childOpacity);
653 }
654}
655
657{
658 KoInsets answer;
659 if (s->stroke)
660 s->stroke->strokeInsets(this, answer);
661 return answer;
662}
663
665{
666 KIS_SAFE_ASSERT_RECOVER_RETURN(first != second);
668
669 if (first != Fill) {
670 if (order.at(1) == first) {
671 order[1] = order[0];
672 order[0] = first;
673 } else if (order.at(2) == first) {
674 order[2] = order[0];
675 order[0] = first;
676 }
677 }
678 if (second != first && second != Stroke) {
679 if (order.at(2) == second) {
680 order[2] = order[1];
681 order[1] = second;
682 }
683 }
684 s->inheritPaintOrder = false;
685 s->paintOrder = order;
686}
687
689{
691 if (!s->inheritPaintOrder) {
692 order = s->paintOrder;
693 } else if (parent()) {
694 order = parent()->paintOrder();
695 }
696 return order;
697}
698
704
706{
707 s->inheritPaintOrder = value;
708}
709
711{
712 return s->inheritPaintOrder;
713}
714
715qreal KoShape::rotation() const
716{
717 // try to extract the rotation angle out of the local matrix
718 // if it is a pure rotation matrix
719
720 // check if the matrix has shearing mixed in
721 if (fabs(fabs(s->localMatrix.m12()) - fabs(s->localMatrix.m21())) > 1e-10)
722 return std::numeric_limits<qreal>::quiet_NaN();
723 // check if the matrix has scaling mixed in
724 if (fabs(s->localMatrix.m11() - s->localMatrix.m22()) > 1e-10)
725 return std::numeric_limits<qreal>::quiet_NaN();
726
727 // calculate the angle from the matrix elements
728 qreal angle = atan2(-s->localMatrix.m21(), s->localMatrix.m11()) * 180.0 / M_PI;
729 if (angle < 0.0)
730 angle += 360.0;
731
732 return angle;
733}
734
735QSizeF KoShape::size() const
736{
737 return s->size;
738}
739
740QPointF KoShape::position() const
741{
742 QPointF center = outlineRect().center();
743 return s->localMatrix.map(center) - center;
744}
745
747{
748 s->inheritBackground = false;
749 s->fill = fill;
752}
753
755{
756
758
759 if (!s->inheritBackground) {
760 bg = s->fill;
761 } else if (parent()) {
762 bg = parent()->background();
763 }
764
765 return bg;
766}
767
769{
770
771 s->inheritBackground = value;
772 if (s->inheritBackground) {
773 s->fill.clear();
774 }
775}
776
778{
779 return s->inheritBackground;
780}
781
782void KoShape::setZIndex(qint16 zIndex)
783{
784 if (s->zIndex == zIndex)
785 return;
786 s->zIndex = zIndex;
788}
789
791{
792 int _on = (on ? 1 : 0);
793 if (s->visible == _on) return;
794 s->visible = _on;
795}
796
797bool KoShape::isVisible(bool recursive) const
798{
799 if (!recursive)
800 return s->visible;
801
802 if (!s->visible)
803 return false;
804
805 KoShapeContainer * parentShape = parent();
806
807 if (parentShape) {
808 return parentShape->isVisible(true);
809 }
810
811 return true;
812}
813
815{
816 s->printable = on;
817}
818
820{
821 if (s->visible)
822 return s->printable;
823 else
824 return false;
825}
826
827void KoShape::setSelectable(bool selectable)
828{
829 s->selectable = selectable;
830}
831
833{
834 return s->selectable;
835}
836
838{
839 s->geometryProtected = on;
840}
841
843{
844 return s->geometryProtected;
845}
846
848{
849 s->protectContent = protect;
850}
851
853{
854 return s->protectContent;
855}
856
858{
859 return d->parent;
860}
861
862void KoShape::setKeepAspectRatio(bool keepAspect)
863{
864 s->keepAspect = keepAspect;
865
868}
869
871{
872 return s->keepAspect;
873}
874
875QString KoShape::shapeId() const
876{
877 return s->shapeId;
878}
879
880void KoShape::setShapeId(const QString &id)
881{
882 s->shapeId = id;
883}
884
886{
887
889
890 if (!s->inheritStroke) {
891 stroke = s->stroke;
892 } else if (parent()) {
893 stroke = parent()->stroke();
894 }
895
896 return stroke;
897}
898
900{
901
902 s->inheritStroke = false;
903 s->stroke = stroke;
906}
907
909{
910 s->inheritStroke = value;
911 if (s->inheritStroke) {
912 s->stroke.clear();
913 }
914}
915
917{
918 return s->inheritStroke;
919}
920
922{
923 s->clipPath.reset(clipPath);
926}
927
929{
930 return s->clipPath.data();
931}
932
934{
935 s->clipMask.reset(clipMask);
938}
939
941{
942 return s->clipMask.data();
943}
944
945QTransform KoShape::transform() const
946{
947 return s->localMatrix;
948}
949
950QString KoShape::name() const
951{
952 return s->name;
953}
954
955void KoShape::setName(const QString &name)
956{
957 s->name = name;
958}
959
960void KoShape::waitUntilReady(bool asynchronous) const
961{
962 Q_UNUSED(asynchronous);
963}
964
965bool KoShape::isShapeEditable(bool recursive) const
966{
967 if (!s->visible || s->geometryProtected)
968 return false;
969
970 if (recursive && d->parent) {
971 return d->parent->isShapeEditable(true);
972 }
973
974 return true;
975}
976
977KisHandlePainterHelper KoShape::createHandlePainterHelperView(QPainter *painter, KoShape *shape, const KoViewConverter &converter, qreal handleRadius, int decorationThickness)
978{
979 const QTransform originalPainterTransform = painter->transform();
980
981 painter->setTransform(shape->absoluteTransformation() *
982 converter.documentToView() *
983 painter->transform());
984
985 // move c-tor
986 return KisHandlePainterHelper(painter, originalPainterTransform, handleRadius, decorationThickness);
987}
988
989KisHandlePainterHelper KoShape::createHandlePainterHelperDocument(QPainter *painter, KoShape *shape, qreal handleRadius, int decorationThickness)
990{
991 const QTransform originalPainterTransform = painter->transform();
992
993 painter->setTransform(shape->absoluteTransformation() *
994 painter->transform());
995
996 // move c-tor
997 return KisHandlePainterHelper(painter, originalPainterTransform, handleRadius, decorationThickness);
998}
999
1000
1001QPointF KoShape::shapeToDocument(const QPointF &point) const
1002{
1003 return absoluteTransformation().map(point);
1004}
1005
1006QRectF KoShape::shapeToDocument(const QRectF &rect) const
1007{
1008 return absoluteTransformation().mapRect(rect);
1009}
1010
1011QPointF KoShape::documentToShape(const QPointF &point) const
1012{
1013 return absoluteTransformation().inverted().map(point);
1014}
1015
1016QRectF KoShape::documentToShape(const QRectF &rect) const
1017{
1018 return absoluteTransformation().inverted().mapRect(rect);
1019}
1020
1022{
1023 if (! shape)
1024 return false;
1025
1026 // refuse to establish a circular dependency
1027 if (shape->hasDependee(this))
1028 return false;
1029
1030 if (! d->dependees.contains(shape)) {
1031 d->dependees.append(shape);
1032 shape->addShapeChangeListener(&d->dependeesLifetimeListener);
1033 }
1034
1035 return true;
1036}
1037
1039{
1040 d->dependees.removeOne(shape);
1041 shape->removeShapeChangeListener(&d->dependeesLifetimeListener);
1042}
1043
1045{
1046 return d->dependees.contains(shape);
1047}
1048
1050{
1051 return d->dependees;
1052}
1053
1055{
1056 Q_UNUSED(type);
1057 Q_UNUSED(shape);
1058
1065}
1066
1068{
1069 return KoSnapData();
1070}
1071
1072void KoShape::setAdditionalAttribute(const QString &name, const QString &value)
1073{
1074 s->additionalAttributes.insert(name, value);
1075}
1076
1077void KoShape::removeAdditionalAttribute(const QString &name)
1078{
1079 s->additionalAttributes.remove(name);
1080}
1081
1082bool KoShape::hasAdditionalAttribute(const QString &name) const
1083{
1084 return s->additionalAttributes.contains(name);
1085}
1086
1087QString KoShape::additionalAttribute(const QString &name) const
1088{
1089 return s->additionalAttributes.value(name);
1090}
1091
1092void KoShape::setAdditionalStyleAttribute(const char *name, const QString &value)
1093{
1094 s->additionalStyleAttributes.insert(name, value);
1095}
1096
1098{
1099 s->additionalStyleAttributes.remove(name);
1100}
1101
1102QSet<KoShape*> KoShape::toolDelegates() const
1103{
1104 return d->toolDelegates;
1105}
1106
1107void KoShape::setToolDelegates(const QSet<KoShape*> &delegates)
1108{
1109 d->toolDelegates = delegates;
1110}
1111
1112QString KoShape::hyperLink () const
1113{
1114 return s->hyperLink;
1115}
1116
1117void KoShape::setHyperLink(const QString &hyperLink)
1118{
1119 s->hyperLink = hyperLink;
1120}
1121
1123{
1124 Q_FOREACH(KoShape *shape, m_registeredShapes) {
1125 shape->removeShapeChangeListener(this);
1126 }
1127}
1128
1130{
1131 KIS_SAFE_ASSERT_RECOVER_RETURN(!m_registeredShapes.contains(shape));
1132 m_registeredShapes.append(shape);
1133}
1134
1136{
1137 KIS_SAFE_ASSERT_RECOVER_RETURN(m_registeredShapes.contains(shape));
1138 m_registeredShapes.removeAll(shape);
1139}
1140
1142{
1143 KIS_SAFE_ASSERT_RECOVER_RETURN(m_registeredShapes.contains(shape));
1144
1145 notifyShapeChanged(type, shape);
1146
1147 if (type == KoShape::Deleted) {
1148 unregisterShape(shape);
1149 }
1150}
1151
1153{
1154
1155 KIS_SAFE_ASSERT_RECOVER_RETURN(!d->listeners.contains(listener));
1156 listener->registerShape(this);
1157 d->listeners.append(listener);
1158}
1159
1161{
1162
1163 KIS_SAFE_ASSERT_RECOVER_RETURN(d->listeners.contains(listener));
1164 d->listeners.removeAll(listener);
1165 listener->unregisterShape(this);
1166}
1167
1169{
1170 return d->listeners;
1171}
1172
1174{
1175 QList<KoShape *> result;
1176
1177 Q_FOREACH (KoShape *shape, shapes) {
1178 result << shape;
1179
1180 KoShapeContainer *container = dynamic_cast<KoShapeContainer*>(shape);
1181 if (container) {
1182 result << linearizeSubtree(container->shapes());
1183 }
1184 }
1185
1186 return result;
1187}
1188
1190{
1191 QList<KoShape*> sortedShapes = shapes;
1192 std::sort(sortedShapes.begin(), sortedShapes.end(), KoShape::compareShapeZIndex);
1193
1194 QList<KoShape *> result;
1195
1196 Q_FOREACH (KoShape *shape, sortedShapes) {
1197 result << shape;
1198
1199 KoShapeContainer *container = dynamic_cast<KoShapeContainer*>(shape);
1200 if (container) {
1201 result << linearizeSubtreeSorted(container->shapes());
1202 }
1203 }
1204
1205 return result;
1206}
1207
1208void KoShape::setResolution(qreal /*xRes*/, qreal /*yRes*/)
1209{
1210}
float value(const T *src, size_t ch)
QPointF s1
QPointF s2
The KisHandlePainterHelper class is a special helper for painting handles around objects....
Clip path used to clip shapes.
QPainterPath clipPath
the compiled clip path in shape coordinates of the clipped shape
KoShapeContainer::ShapeInterface shapeInterface
QList< KoShape * > shapes() const
bool inheritsTransform(const KoShape *shape) const
KoShapeManager::ShapeInterface shapeInterface
void update(const QRectF &rect, const KoShape *shape=0, bool selectionHandles=false)
void notifyShapeChanged(KoShape *shape)
virtual ~SharedData()
Definition KoShape.cpp:101
void setToolDelegates(const QSet< KoShape * > &delegates)
Definition KoShape.cpp:1107
virtual void setPaintOrder(PaintOrder first, PaintOrder second)
setPaintOrder set the paint order. As there's only three entries in any given paintorder,...
Definition KoShape.cpp:664
KoShapeUserData * userData() const
Definition KoShape.cpp:625
QScopedPointer< Private > d
Definition KoShape.h:974
virtual void paintStroke(QPainter &painter) const
paintStroke paints the shape's stroked outline
Definition KoShape.cpp:196
bool isContentProtected() const
Definition KoShape.cpp:852
virtual QSizeF size() const
Get the size of the shape in pt.
Definition KoShape.cpp:735
void setHyperLink(const QString &hyperLink)
Definition KoShape.cpp:1117
void setName(const QString &name)
Definition KoShape.cpp:955
virtual QRectF outlineRect() const
Definition KoShape.cpp:561
bool hasCommonParent(const KoShape *shape) const
Definition KoShape.cpp:505
static const qint16 minZIndex
Definition KoShape.h:388
void setContentProtected(bool protect)
Definition KoShape.cpp:847
void addShapeChangeListener(ShapeChangeListener *listener)
Definition KoShape.cpp:1152
void setInheritBackground(bool value)
setInheritBackground marks a shape as inheriting the background from the parent shape....
Definition KoShape.cpp:768
void setZIndex(qint16 zIndex)
Definition KoShape.cpp:782
QString shapeId() const
Definition KoShape.cpp:875
virtual QPainterPath outline() const
Definition KoShape.cpp:554
KoShapeAnchor * anchor() const
virtual QVector< PaintOrder > paintOrder() const
paintOrder
Definition KoShape.cpp:688
qreal rotation() const
Definition KoShape.cpp:715
KoShape * cloneShapeAndBakeAbsoluteTransform() const
creates a deep copy of the shape/shapes tree and bakes the absolute transform of this into the result...
Definition KoShape.cpp:180
void rotate(qreal angle)
Rotate the shape (relative)
Definition KoShape.cpp:223
virtual KoSnapData snapData() const
Returns additional snap data the shape wants to have snapping to.
Definition KoShape.cpp:1067
void setKeepAspectRatio(bool keepAspect)
Definition KoShape.cpp:862
KoShape()
Constructor.
Definition KoShape.cpp:136
bool isSelectable() const
Definition KoShape.cpp:832
QPointF shapeToDocument(const QPointF &point) const
Transforms point from shape coordinates to document coordinates.
Definition KoShape.cpp:1001
QPointF absolutePosition(KoFlake::AnchorPosition anchor=KoFlake::Center) const
Definition KoShape.cpp:568
void removeShapeChangeListener(ShapeChangeListener *listener)
Definition KoShape.cpp:1160
void setClipMask(KoClipMask *clipMask)
Sets a new clip mask, removing the old one. The mask is owned by the shape.
Definition KoShape.cpp:933
virtual bool isShapeEditable(bool recursive=true) const
checks recursively if the shape or one of its parents is not visible or locked
Definition KoShape.cpp:965
void addShapeManager(KoShapeManager *manager)
Definition KoShape.cpp:121
void setTransparency(qreal transparency)
Definition KoShape.cpp:637
static QVector< PaintOrder > defaultPaintOrder()
default paint order as per SVG specification
Definition KoShape.cpp:699
QList< KoShape * > dependees() const
Returns list of shapes depending on this shape.
Definition KoShape.cpp:1049
virtual KoShapeStrokeModelSP stroke() const
Definition KoShape.cpp:885
void applyAbsoluteTransformation(const QTransform &matrix)
Definition KoShape.cpp:348
virtual void setResolution(qreal xRes, qreal yRes)
Definition KoShape.cpp:1208
static bool compareShapeZIndex(KoShape *s1, KoShape *s2)
Definition KoShape.cpp:388
void setSizeImpl(const QSizeF &size) const
Definition KoShape.cpp:263
void setPrintable(bool on)
Definition KoShape.cpp:814
void copySettings(const KoShape *shape)
Definition KoShape.cpp:594
void removeAdditionalStyleAttribute(const char *name)
Definition KoShape.cpp:1097
bool isGeometryProtected() const
Definition KoShape.cpp:842
QString hyperLink() const
Definition KoShape.cpp:1112
QPointF documentToShape(const QPointF &point) const
Transforms point from document coordinates to shape coordinates.
Definition KoShape.cpp:1011
QSet< KoShape * > toolDelegates() const
Definition KoShape.cpp:1102
void shear(qreal sx, qreal sy)
Shear the shape The shape will be sheared using the zero-point which is the top-left corner.
Definition KoShape.cpp:236
QList< ShapeChangeListener * > listeners() const
Definition KoShape.cpp:1168
KoInsets strokeInsets() const
Definition KoShape.cpp:656
virtual QRectF boundingRect() const
Get the bounding box of the shape.
Definition KoShape.cpp:300
KoClipPath * clipPath() const
Returns the currently set clip path or 0 if there is no clip path set.
Definition KoShape.cpp:928
void setSelectable(bool selectable)
Definition KoShape.cpp:827
virtual void update() const
Definition KoShape.cpp:529
void applyTransformation(const QTransform &matrix)
Definition KoShape.cpp:358
QRectF absoluteOutlineRect() const
Definition KoShape.cpp:319
virtual void shapeChanged(ChangeType type, KoShape *shape=0)
Definition KoShape.cpp:1054
KoShapeContainer * parent() const
Definition KoShape.cpp:857
bool inheritStroke() const
inheritStroke shows if the shape inherits the stroke from its parent
Definition KoShape.cpp:916
void removeShapeManager(KoShapeManager *manager)
Definition KoShape.cpp:126
void shapeChangedPriv(KoShape::ChangeType type)
Definition KoShape.cpp:105
ChildZOrderPolicy
Used by compareShapeZIndex() to order shapes.
Definition KoShape.h:523
@ ChildZDefault
Definition KoShape.h:524
@ ChildZParentChild
normal parent/child ordering
Definition KoShape.h:525
virtual void setStroke(KoShapeStrokeModelSP stroke)
Definition KoShape.cpp:899
bool inheritBackground() const
inheritBackground shows if the shape inherits background from its parent
Definition KoShape.cpp:777
static QList< KoShape * > linearizeSubtreeSorted(const QList< KoShape * > &shapes)
Definition KoShape.cpp:1189
void setAdditionalAttribute(const QString &name, const QString &value)
Definition KoShape.cpp:1072
QTransform absoluteTransformation() const
Definition KoShape.cpp:330
virtual void paintMarkers(QPainter &painter) const
paintStroke paints the shape's markers
Definition KoShape.cpp:203
void setTransformation(const QTransform &matrix)
Definition KoShape.cpp:369
static KisHandlePainterHelper createHandlePainterHelperDocument(QPainter *painter, KoShape *shape, qreal handleRadius, int decorationThickness)
Definition KoShape.cpp:989
virtual void setBackground(QSharedPointer< KoShapeBackground > background)
Definition KoShape.cpp:746
void setClipPath(KoClipPath *clipPath)
Sets a new clip path, removing the old one.
Definition KoShape.cpp:921
static KisHandlePainterHelper createHandlePainterHelperView(QPainter *painter, KoShape *shape, const KoViewConverter &converter, qreal handleRadius=0.0, int decorationThickness=1)
Definition KoShape.cpp:977
bool hasAdditionalAttribute(const QString &name) const
Definition KoShape.cpp:1082
KoClipMask * clipMask() const
Returns the currently set clip mask or 0 if there is no clip mask set.
Definition KoShape.cpp:940
static QList< KoShape * > linearizeSubtree(const QList< KoShape * > &shapes)
Definition KoShape.cpp:1173
ChangeType
Used by shapeChanged() to select which change was made.
Definition KoShape.h:92
@ RotationChanged
used after a setRotation()
Definition KoShape.h:94
@ StrokeChanged
the shapes stroke has changed
Definition KoShape.h:102
@ PositionChanged
used after a setPosition()
Definition KoShape.h:93
@ TransparencyChanged
the shapetransparency value has changed
Definition KoShape.h:112
@ Deleted
the shape was deleted
Definition KoShape.h:101
@ ClipPathChanged
the shapes clip path has changed
Definition KoShape.h:110
@ ShearChanged
used after a shear()
Definition KoShape.h:96
@ ParentChanged
used after a setParent()
Definition KoShape.h:100
@ ClipMaskChanged
the shapes clip path has changed
Definition KoShape.h:111
@ BackgroundChanged
the shapes background has changed
Definition KoShape.h:103
@ ScaleChanged
used after a scale()
Definition KoShape.h:95
@ KeepAspectRatioChange
used after setKeepAspectRatio()
Definition KoShape.h:99
@ SizeChanged
used after a setSize()
Definition KoShape.h:97
@ GenericMatrixChange
used after the matrix was changed without knowing which property explicitly changed
Definition KoShape.h:98
virtual KoShape * cloneShape() const
creates a deep copy of the shape or shape's subtree
Definition KoShape.cpp:173
bool isPrintable() const
Definition KoShape.cpp:819
void scale(qreal sx, qreal sy)
Scale the shape using the zero-point which is the top-left corner.
Definition KoShape.cpp:210
void setUserData(KoShapeUserData *userData)
Definition KoShape.cpp:620
virtual QSharedPointer< KoShapeBackground > background() const
Definition KoShape.cpp:754
virtual ChildZOrderPolicy childZOrderPolicy()
Definition KoShape.cpp:383
QString additionalAttribute(const QString &name) const
Definition KoShape.cpp:1087
virtual bool hasTransparency() const
Definition KoShape.cpp:630
void removeDependee(KoShape *shape)
Definition KoShape.cpp:1038
QTransform transformation() const
Returns the shapes local transformation matrix.
Definition KoShape.cpp:378
bool inheritPaintOrder() const
inheritPaintOrder
Definition KoShape.cpp:710
virtual void setPosition(const QPointF &position)
Set the position of the shape in pt.
Definition KoShape.cpp:268
bool keepAspectRatio() const
Definition KoShape.cpp:870
virtual void updateAbsolute(const QRectF &rect) const
Definition KoShape.cpp:540
bool inheritsTransformFromAny(const QList< KoShape * > ancestorsInQuestion) const
inheritsTransformFromAny checks if the shape inherits transformation from any of the shapes listed in...
Definition KoShape.cpp:483
void setInheritStroke(bool value)
setInheritStroke marks a shape as inheriting the stroke from the parent shape. NOTE: The currently se...
Definition KoShape.cpp:908
@ Stroke
Definition KoShape.h:117
@ Markers
Definition KoShape.h:118
void setGeometryProtected(bool on)
Definition KoShape.cpp:837
QSharedDataPointer< SharedData > s
Definition KoShape.h:977
void setVisible(bool on)
Definition KoShape.cpp:790
void notifyChanged()
Definition KoShape.cpp:613
void setParent(KoShapeContainer *parent)
Definition KoShape.cpp:459
bool addDependee(KoShape *shape)
Definition KoShape.cpp:1021
virtual bool hitTest(const QPointF &position) const
Check if the shape is hit on position.
Definition KoShape.cpp:281
virtual ~KoShape()
Destructor.
Definition KoShape.cpp:149
void setShapeId(const QString &id)
Definition KoShape.cpp:880
qint16 zIndex() const
Definition KoShape.cpp:524
void removeAdditionalAttribute(const QString &name)
Definition KoShape.cpp:1077
void setAdditionalStyleAttribute(const char *name, const QString &value)
Definition KoShape.cpp:1092
QTransform transform() const
return the current matrix that contains the rotation/scale/position of this shape
Definition KoShape.cpp:945
void setInheritPaintOrder(bool value)
setInheritPaintOrder set inherit paint order.
Definition KoShape.cpp:705
QString name() const
Definition KoShape.cpp:950
bool hasDependee(KoShape *shape) const
Returns if the given shape is dependent on this shape.
Definition KoShape.cpp:1044
void setAbsolutePosition(const QPointF &newPosition, KoFlake::AnchorPosition anchor=KoFlake::Center)
Definition KoShape.cpp:583
static const qint16 maxZIndex
Definition KoShape.h:383
bool isVisible(bool recursive=true) const
Definition KoShape.cpp:797
qreal transparency(bool recursive=false) const
Definition KoShape.cpp:645
virtual void setSize(const QSizeF &size)
Resize the shape.
Definition KoShape.cpp:249
QPointF position() const
Get the position of the shape in pt.
Definition KoShape.cpp:740
virtual void waitUntilReady(bool asynchronous=true) const
Definition KoShape.cpp:960
virtual QPointF documentToView(const QPointF &documentPoint) const
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
#define M_PI
Definition kis_global.h:111
AnchorPosition
Definition KoFlake.h:85
KRITAFLAKE_EXPORT QPointF anchorToPoint(AnchorPosition anchor, const QRectF rect, bool *valid=0)
Definition KoFlake.cpp:329
auto mem_bit_or(MemType Class::*ptr)
mem_bit_or is a binary functor that applies a bitwise-or operator to member of an object and a given ...
Definition KisMpl.h:589
qreal bottom
Bottom inset.
Definition KoInsets.h:50
qreal right
Right inset.
Definition KoInsets.h:52
qreal top
Top inset.
Definition KoInsets.h:49
qreal left
Left inset.
Definition KoInsets.h:51
void notifyShapeDestructed(KoShape *shape)
QList< KoShape * > m_registeredShapes
Definition KoShape.h:945
void unregisterShape(KoShape *shape)
Definition KoShape.cpp:1135
void registerShape(KoShape *shape)
Definition KoShape.cpp:1129
void notifyShapeChangedImpl(ChangeType type, KoShape *shape)
Definition KoShape.cpp:1141