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