Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_shape_layer.cc
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2008 Boudewijn Rempt <boud@valdyas.org>
3 * SPDX-FileCopyrightText: 2007 Thomas Zander <zander@kde.org>
4 * SPDX-FileCopyrightText: 2009 Cyrille Berger <cberger@cberger.net>
5 * SPDX-FileCopyrightText: 2011 Jan Hambrecht <jaham@gmx.net>
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10#include "kis_shape_layer.h"
11
12#include <QPainter>
13#include <QPainterPath>
14#include <QRect>
15#include <QDomElement>
16#include <QDomDocument>
17#include <QString>
18#include <QList>
19#include <QMap>
20#include <kis_debug.h>
21#include <kundo2command.h>
23#include <QMimeData>
24
25#include <kis_icon.h>
26#include <KoColorSpace.h>
27#include <KoCompositeOp.h>
28#include <KisDocument.h>
29#include <KoUnit.h>
30#include <KoShapeContainer.h>
31#include <KoShapeLayer.h>
32#include <KoShapeGroup.h>
34#include <KoShapeManager.h>
36#include <KoShapeRegistry.h>
38#include <KoStore.h>
40#include <KoStoreDevice.h>
41#include <KoViewConverter.h>
42#include <KoXmlNS.h>
43#include <KoXmlWriter.h>
44#include <KoSelection.h>
45#include <KoShapeMoveCommand.h>
47
48#include "SvgWriter.h"
49#include "SvgParser.h"
50
51#include <kis_types.h>
52#include <kis_image.h>
53#include "kis_default_bounds.h"
54#include <kis_paint_device.h>
57#include <kis_painter.h>
58#include "kis_node_visitor.h"
60#include "kis_effect_mask.h"
65#include <QThread>
66#include <QApplication>
67
69
70
73{
74public:
76 : q(parent)
77 {
78 }
79
80 void add(KoShape *child) override {
82
88 if (inheritsTransform(child)) {
89 QTransform parentTransform = q->absoluteTransformation();
90 child->applyAbsoluteTransformation(parentTransform.inverted());
91 }
93 }
94
95 void remove(KoShape *child) override {
97 if (inheritsTransform(child)) {
98 QTransform parentTransform = q->absoluteTransformation();
99 child->applyAbsoluteTransformation(parentTransform);
100 }
101
103 }
104
105 bool setResolution(qreal xRes, qreal yRes) {
106 if (!qFuzzyCompare(m_xRes, xRes) || !qFuzzyCompare(m_yRes, yRes)) {
107 m_xRes = xRes;
108 m_yRes = yRes;
109 return true;
110 }
111 return false;
112 }
113
114private:
116 qreal m_xRes{72.0};
117 qreal m_yRes{72.0};
118};
119
120
140
141
143 KisImageWSP image,
144 const QString &name,
145 quint8 opacity)
146 : KisShapeLayer(controller, image, name, opacity,
147 [&] () { return new KisShapeLayerCanvas(image->colorSpace(), new KisDefaultBounds(image), this);})
148{
149}
150
152 : KisShapeLayer(rhs,
153 rhs.m_d->controller)
154{
155}
156
158 : KisShapeLayer(rhs,
159 controller,
160 [&] () {
161 const KisShapeLayerCanvas* shapeLayerCanvas = dynamic_cast<const KisShapeLayerCanvas*>(rhs.m_d->canvas);
162 KIS_ASSERT(shapeLayerCanvas);
163 return new KisShapeLayerCanvas(*shapeLayerCanvas, this);})
164{
165}
166
168 std::function<KisShapeLayerCanvasBase *()> canvasFactory)
169 : KisExternalLayer(_rhs)
170 , KoShapeLayer(new ShapeLayerContainerModel(this)) //no _rhs here otherwise both layer have the same KoShapeContainerModel
171 , m_d(new Private())
172{
173 initShapeLayerImpl(controller, canvasFactory());
175
180 const QTransform thisInvertedTransform = this->absoluteTransformation().inverted();
181
183
184 Q_FOREACH (KoShape *shape, _rhs.shapes()) {
185 KoShape *clonedShape = shape->cloneShape();
186 KIS_SAFE_ASSERT_RECOVER(clonedShape) { continue; }
187 clonedShape->setTransformation(shape->absoluteTransformation() * thisInvertedTransform);
188 addShape(clonedShape);
189 }
190
192}
193
194KisShapeLayer::KisShapeLayer(const KisShapeLayer& baseTemplate, const QList<KoShape*> &newShapes)
195 : KisExternalLayer(baseTemplate)
196 , KoShapeLayer(new ShapeLayerContainerModel(this)) //no _merge here otherwise both layer have the same KoShapeContainerModel
197 , m_d(new Private())
198{
199 // Make sure our new layer is visible otherwise the shapes cannot be painted.
200 setVisible(true);
201
202 m_d->isAntialiased = baseTemplate.m_d->isAntialiased;
203
204 const KisShapeLayerCanvas* shapeLayerCanvas = dynamic_cast<const KisShapeLayerCanvas*>(baseTemplate.canvas());
205 KIS_ASSERT(shapeLayerCanvas);
206 initShapeLayerImpl(baseTemplate.m_d->controller, new KisShapeLayerCanvas(*shapeLayerCanvas, this));
207
213 const QTransform thisInvertedTransform = this->absoluteTransformation().inverted();
214
215 QList<KoShape *> clonedShapes;
216
217 // copy all the new shapes; we expect them to be sorted and homogenized
218
219 const bool isSorted = std::is_sorted(newShapes.begin(), newShapes.end(), KoShape::compareShapeZIndex);
221
222 Q_FOREACH (KoShape *shape, newShapes) {
223 KoShape *clonedShape = shape->cloneShape();
224 KIS_SAFE_ASSERT_RECOVER(clonedShape) { continue; }
225 clonedShape->setTransformation(shape->absoluteTransformation() * thisInvertedTransform);
226 clonedShapes.append(clonedShape);
227 }
228
229 Q_FOREACH (KoShape *shape, clonedShapes) {
230 addShape(shape);
231 }
232}
233
235 KisImageWSP image,
236 const QString &name,
237 quint8 opacity,
238 std::function<KisShapeLayerCanvasBase *()> canvasFactory)
239 : KisExternalLayer(image, name, opacity)
241 , m_d(new Private())
242{
243 initShapeLayerImpl(controller, canvasFactory());
244}
245
247{
252
253 Q_FOREACH (KoShape *shape, shapes()) {
254 shape->setParent(0);
255 delete shape;
256 }
257
258 delete m_d->canvas;
259 delete m_d;
260}
261
264{
265 setSupportsLodMoves(false);
267
269
271
272 m_d->canvas = canvas;
273 m_d->canvas->moveToThread(this->thread());
274 m_d->controller = controller;
275
276 m_d->canvas->shapeManager()->selection()->disconnect(this);
277
278 connect(m_d->canvas->selectedShapesProxy(), SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
280 this, SIGNAL(currentLayerChanged(const KoShapeLayer*)));
281
282 connect(this, SIGNAL(sigMoveShapes(QPointF)), SLOT(slotMoveShapes(QPointF)));
283
286 model->setAssociatedRootShapeManager(m_d->canvas->shapeManager());
287
288 if (this->image()) {
289 m_d->imageConnections.addUniqueConnection(this->image(), SIGNAL(sigResolutionChanged(double, double)), this, SLOT(slotImageResolutionChanged()));
291 }
292}
293
295{
296 return node->inherits("KisMask");
297}
298
300{
302 KisLayer::setImage(_image);
303 m_d->canvas->setImage(_image);
304 if (m_d->paintDevice) {
306 }
307 if (_image) {
308 m_d->imageConnections.addUniqueConnection(_image, SIGNAL(sigResolutionChanged(double, double)), this, SLOT(slotImageResolutionChanged()));
310 }
311}
312
313
322
324{
325 Q_FOREACH (const KisBaseNode::Property &property, properties) {
326 if (property.name == i18n("Anti-aliasing")) {
327 setAntialiased(property.state.toBool());
328 }
329 }
330
332}
333
335{
336 // NOTE: layers.first() may possibly point to `this`!
337
338 QList<KisShapeLayer*> shapeLayers;
339 Q_FOREACH(KisLayerSP layer, layers) {
340 KisShapeLayer *shapeLayer = dynamic_cast<KisShapeLayer*>(layer.data());
341 if (!shapeLayer) return nullptr;
342
343 shapeLayers << shapeLayer;
344 }
345
346 QList<KoShape*> allShapes;
348 Q_FOREACH(KisShapeLayer *layer, shapeLayers) {
349 QList<KoShape*> shapes = layer->shapes();
350 std::sort(shapes.begin(), shapes.end(), KoShape::compareShapeZIndex);
351
352 Q_FOREACH(KoShape *shape, shapes) {
353 allShapes << shape;
354 allIndexedShapes << shape;
355 }
356 }
357
358 allIndexedShapes = KoShapeReorderCommand::homogenizeZIndexesLazy(allIndexedShapes);
359
360 KoShapeReorderCommand cmd(allIndexedShapes);
361 cmd.redo();
362
363 KisLayerSP newLayer = new KisShapeLayer(*this, allShapes);
364
365 newLayer->setCompositeOpId(this->compositeOpId());
366 if (!this->channelFlags().isEmpty()) {
367 newLayer->setChannelFlags(this->channelFlags());
368 }
369
370 newLayer->setCompositeOpId(this->compositeOpId());
371 newLayer->setPinnedToTimeline(this->isPinnedToTimeline());
372 newLayer->setColorLabelIndex(this->colorLabelIndex());
373
374 return newLayer;
375}
376
378{
379 KisLayerSP newLayer;
380
381 KisShapeLayer *prevShape = dynamic_cast<KisShapeLayer*>(prevLayer.data());
382 if (prevShape) {
383 newLayer = tryCreateInternallyMergedLayerFromMutipleLayers({prevLayer, this});
385 }
386
387 return newLayer ? newLayer : KisExternalLayer::createMergedLayerTemplate(prevLayer);
388}
389
390void KisShapeLayer::fillMergedLayerTemplate(KisLayerSP dstLayer, KisLayerSP prevLayer, bool skipPaintingThisLayer)
391{
392 if (!dynamic_cast<KisShapeLayer*>(dstLayer.data())) {
393 KisLayer::fillMergedLayerTemplate(dstLayer, prevLayer, skipPaintingThisLayer);
394 }
395}
396
398{
399 Q_UNUSED(parent);
401}
402
404{
405 return KisIconUtils::loadIcon("vectorLayer");
406}
407
412
414{
415 return 0;
416}
417
419{
420 return kisGrowRect(m_d->canvas->viewConverter()->documentToView(this->boundingRect()).toAlignedRect(), 1);
421}
422
423qint32 KisShapeLayer::x() const
424{
425 return m_d->x;
426}
427
428qint32 KisShapeLayer::y() const
429{
430 return m_d->y;
431}
432
434{
435 qint32 delta = x - this->x();
436 QPointF diff = QPointF(m_d->canvas->viewConverter()->viewToDocumentX(delta), 0);
437 Q_EMIT sigMoveShapes(diff);
438
439 // Save new value to satisfy LSP
440 m_d->x = x;
441}
442
444{
445 qint32 delta = y - this->y();
446 QPointF diff = QPointF(0, m_d->canvas->viewConverter()->viewToDocumentY(delta));
447 Q_EMIT sigMoveShapes(diff);
448
449 // Save new value to satisfy LSP
450 m_d->y = y;
451}
452namespace {
453void filterTransformableShapes(QList<KoShape*> &shapes)
454{
455 auto it = shapes.begin();
456 while (it != shapes.end()) {
457 if (shapes.size() == 1) break;
458
459 if ((*it)->inheritsTransformFromAny(shapes)) {
460 it = shapes.erase(it);
461 } else {
462 ++it;
463 }
464 }
465}
466}
467
469{
471
472 // We expect that **all** the shapes inherit the transform from its parent
473
474 // SANITY_CHECK: we expect all the shapes inside the
475 // shape layer to inherit transform!
476 Q_FOREACH (KoShape *shape, shapes) {
477 if (shape->parent()) {
479 break;
480 }
481 }
482 }
483
484 shapes << this;
485 filterTransformableShapes(shapes);
486 return shapes;
487}
488
489void KisShapeLayer::slotMoveShapes(const QPointF &diff)
490{
492 if (shapes.isEmpty()) return;
493
494 KoShapeMoveCommand cmd(shapes, diff);
495 cmd.redo();
496}
497
498void KisShapeLayer::slotTransformShapes(const QTransform &newTransform)
499{
500 KoShapeTransformCommand cmd({this}, {transformation()}, {newTransform});
501 cmd.redo();
502}
503
505{
506 return visitor.visit(this);
507}
508
510{
511 return visitor.visit(this, undoAdapter);
512}
513
518
520{
521 return m_d->canvas->viewConverter();
522}
523
524bool KisShapeLayer::visible(bool recursive) const
525{
526 return KisExternalLayer::visible(recursive);
527}
528
529void KisShapeLayer::setVisible(bool visible, bool isLoading)
530{
531 const bool oldVisible = this->visible(false);
532
535
536 if (visible && !oldVisible &&
538
540 }
541}
542
548
549bool KisShapeLayer::isShapeEditable(bool recursive) const
550{
551 return KoShapeLayer::isShapeEditable(recursive) && isEditable(true);
552}
553
554// we do not override KoShape::setGeometryProtected() as we consider
555// the user not being able to access the layer shape from Krita UI!
556
561
566
571
576
577bool KisShapeLayer::saveShapesToStore(KoStore *store, QList<KoShape *> shapes, const QSizeF &sizeInPt)
578{
579 if (!store->open("content.svg")) {
580 return false;
581 }
582
583 KoStoreDevice storeDev(store);
584 storeDev.open(QIODevice::WriteOnly);
585
586 std::sort(shapes.begin(), shapes.end(), KoShape::compareShapeZIndex);
587
588 SvgWriter writer(shapes);
589 writer.save(storeDev, sizeInPt);
590
591 if (!store->close()) {
592 return false;
593 }
594
595 return true;
596}
597
598QList<KoShape *> KisShapeLayer::createShapesFromSvg(QIODevice *device, const QString &baseXmlDir, const QRectF &rectInPixels, qreal resolutionPPI, KoDocumentResourceManager *resourceManager, bool loadingFromKra, QSizeF *fragmentSize, QStringList *warnings, QStringList *errors)
599{
600
601 QString errorMsg;
602 int errorLine = 0;
603 int errorColumn;
604
605 QDomDocument doc = SvgParser::createDocumentFromSvg(device, &errorMsg, &errorLine, &errorColumn);
606 if (doc.isNull()) {
607 errKrita << "Parsing error in contents.svg! Aborting!" << Qt::endl
608 << " In line: " << errorLine << ", column: " << errorColumn << Qt::endl
609 << " Error message: " << errorMsg << Qt::endl;
610
611 if (errors) {
612 *errors << i18n("Parsing error in the main document at line %1, column %2\nError message: %3"
613 , errorLine , errorColumn , errorMsg);
614 }
615 return QList<KoShape*>();
616 }
617
618 SvgParser parser(resourceManager);
619 parser.setXmlBaseDir(baseXmlDir);
620 parser.setResolution(rectInPixels /* px */, resolutionPPI /* ppi */);
621
622 if (loadingFromKra) {
631 parser.setDefaultKraTextVersion(1);
632 }
633
634 QList<KoShape *> result = parser.parseSvg(doc.documentElement(), fragmentSize);
635
636 if (warnings) {
637 *warnings = parser.warnings();
638 }
639
640 return result;
641}
642
643
645{
646 // FIXME: we handle xRes() only!
647
648 const QSizeF sizeInPx = image()->bounds().size();
649 const QSizeF sizeInPt(sizeInPx.width() / image()->xRes(), sizeInPx.height() / image()->yRes());
650
651 return saveShapesToStore(store, this->shapes(), sizeInPt);
652}
653
654bool KisShapeLayer::loadSvg(QIODevice *device, const QString &baseXmlDir, QStringList *warnings)
655{
656 QSizeF fragmentSize; // unused!
657 KisImageSP image = this->image();
658
659 // FIXME: we handle xRes() only!
661 const qreal resolutionPPI = 72.0 * image->xRes();
662
664 createShapesFromSvg(device, baseXmlDir,
665 image->bounds(), resolutionPPI,
667 true,
668 &fragmentSize,
669 warnings);
670
671 Q_FOREACH (KoShape *shape, shapes) {
672 addShape(shape);
673 }
674
675 return true;
676}
677
679{
680 if (!store) {
681 warnKrita << "No store backend";
682 return false;
683 }
684
685 if (store->open("content.svg")) {
686 KoStoreDevice storeDev(store);
687 storeDev.open(QIODevice::ReadOnly);
688
689 loadSvg(&storeDev, "", warnings);
690
691 store->close();
692
693 return true;
694 }
695
696 return false;
697
698}
699
701{
703}
704
706{
707 QPoint oldPos(x(), y());
708 QPoint newPos = oldPos - rect.topLeft();
709
710 return new KisNodeMoveCommand2(this, oldPos, newPos);
711}
712
714{
715public:
716 TransformShapeLayerDeferred(KisShapeLayer *shapeLayer, const QTransform &globalDocTransform)
717 : m_shapeLayer(shapeLayer),
718 m_globalDocTransform(globalDocTransform),
719 m_blockingConnection(std::bind(&KisShapeLayer::slotTransformShapes, shapeLayer, std::placeholders::_1))
720 {
721 }
722
723 void undo() override
724 {
725 KIS_SAFE_ASSERT_RECOVER_NOOP(QThread::currentThread() != qApp->thread());
727 }
728
729 void redo() override
730 {
732
733 const QTransform globalTransform = m_shapeLayer->absoluteTransformation();
734 const QTransform localTransform = globalTransform * m_globalDocTransform * globalTransform.inverted();
735
736 KIS_SAFE_ASSERT_RECOVER_NOOP(QThread::currentThread() != qApp->thread());
738 }
739
740private:
745};
746
747
748KUndo2Command* KisShapeLayer::transform(const QTransform &transform)
749{
751 if (shapes.isEmpty()) return 0;
752 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(shapes.size() == 1 && shapes.first() == this, 0);
753
758 const KisImageViewConverter *converter = dynamic_cast<const KisImageViewConverter*>(this->converter());
759 KIS_ASSERT(converter);
760 QTransform docSpaceTransform = converter->documentToView() *
762
763 return new TransformShapeLayerDeferred(this, docSpaceTransform);
764}
765
767{
768 using namespace KisDoSomethingCommandOps;
769
770 KUndo2Command *cmd = new KUndo2Command();
772 m_d->paintDevice->setProfile(profile, cmd);
774
775 return cmd;
776}
777
778KUndo2Command *KisShapeLayer::convertTo(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)
779{
780 using namespace KisDoSomethingCommandOps;
781
782 KUndo2Command *cmd = new KUndo2Command();
784 m_d->paintDevice->convertTo(dstColorSpace, renderingIntent, conversionFlags, cmd);
786 return cmd;
787}
788
793
798
800{
803 if (this->image()) {
804 if (model->setResolution(image()->xRes() * 72.0, image()->yRes() * 72.0)) {
805 resetCache(nullptr);
806 }
807 }
808}
809
810
812{
813 return m_d->isAntialiased;
814}
815
816void KisShapeLayer::setAntialiased(const bool antialiased)
817{
818 const bool oldAntialiased = m_d->isAntialiased;
819
820 if (antialiased != oldAntialiased) {
822 // is it the best way to rerender the vector layer?
824 }
825}
float value(const T *src, size_t ch)
const KoColorSpace * colorSpace() const
double xRes() const
double yRes() const
QRect bounds() const override
static KisBaseNode::Property getProperty(const KoID &id, bool state)
virtual bool visit(KisNode *node)=0
void setDefaultBounds(KisDefaultBoundsBaseSP bounds)
bool setProfile(const KoColorProfile *profile, KUndo2Command *parentCommand)
void convertTo(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags(), KUndo2Command *parentCommand=nullptr, KoUpdater *progressUpdater=nullptr)
virtual void visit(KisNode *node, KisUndoAdapter *undoAdapter)=0
virtual KisPaintDeviceSP projection() const =0
virtual bool hasPendingUpdates() const =0
const KoViewConverter * viewConverter() const override
virtual void setImage(KisImageWSP image)
virtual void resetCache(const KoColorSpace *colorSpace)=0
virtual void forceRepaint()=0
virtual void rerenderAfterBeingInvisible()=0
KoShapeManager * shapeManager() const override
virtual void forceRepaintWithHiddenAreas()
KoSelectedShapesProxy * selectedShapesProxy() const override
selectedShapesProxy() is a special interface for keeping a persistent connections to selectionChanged...
QRect theoreticalBoundingRect() const override
KUndo2Command * crop(const QRect &rect) override
KisLayerSP createMergedLayerTemplate(KisLayerSP prevLayer) override
void setSectionModelProperties(const KisBaseNode::PropertyList &properties) override
bool antialiased() const
void fillMergedLayerTemplate(KisLayerSP dstLayer, KisLayerSP prevLayer, bool skipPaintingThisLayer) override
void slotMoveShapes(const QPointF &diff)
bool saveLayer(KoStore *store) const
void setVisible(bool visible, bool isLoading=false) override
KoShapeManager * shapeManager() const
void selectionChanged()
void setY(qint32) override
void setParent(KoShapeContainer *parent)
bool accept(KisNodeVisitor &) override
Private *const m_d
void setX(qint32) override
QList< KoShape * > shapesToBeTransformed()
bool loadLayer(KoStore *store, QStringList *warnings=0)
qint32 y() const override
bool isShapeEditable(bool recursive) const override
checks recursively if the shape or one of its parents is not visible or locked
static QList< KoShape * > createShapesFromSvg(QIODevice *device, const QString &baseXmlDir, const QRectF &rectInPixels, qreal resolutionPPI, KoDocumentResourceManager *resourceManager, bool loadingFromKra, QSizeF *fragmentSize, QStringList *warnings=0, QStringList *errors=0)
void slotTransformShapes(const QTransform &transform)
void resetCache(const KoColorSpace *colorSpace) override
KisPaintDeviceSP original() const override
KisShapeLayer(KoShapeControllerBase *shapeController, KisImageWSP image, const QString &name, quint8 opacity)
KisPaintDeviceSP paintDevice() const override
friend class TransformShapeLayerDeferred
void initShapeLayerImpl(KoShapeControllerBase *controller, KisShapeLayerCanvasBase *overrideCanvas)
KoSelectedShapesProxy * selectedShapesProxy()
selectedShapesProxy
void setUserLocked(bool value) override
static bool saveShapesToStore(KoStore *store, QList< KoShape * > shapes, const QSizeF &sizeInPt)
void currentLayerChanged(const KoShapeLayer *layer)
bool hasPendingTimedUpdates() const override
KUndo2Command * convertTo(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags()) override
void slotImageResolutionChanged()
QIcon icon() const override
void sigMoveShapes(const QPointF &diff)
KUndo2Command * setProfile(const KoColorProfile *profile) override
KisShapeLayerCanvasBase * canvas() const
KoShapeControllerBase * shapeController() const
KisLayerSP tryCreateInternallyMergedLayerFromMutipleLayers(QList< KisLayerSP > layers) override
KisBaseNode::PropertyList sectionModelProperties() const override
qint32 x() const override
bool allowAsChild(KisNodeSP) const override
void setImage(KisImageWSP image) override
const KoViewConverter * converter() const
bool visible(bool recursive=false) const override
~KisShapeLayer() override
void setAntialiased(const bool antialiased)
bool loadSvg(QIODevice *device, const QString &baseXmlDir, QStringList *warnings=0)
void forceUpdateHiddenAreaOnOriginal() override
void forceUpdateTimedNode() override
void addUniqueConnection(Sender sender, Signal signal, Receiver receiver, Method method)
The KoSelectedShapesProxy class is a special interface of KoCanvasBase to have a stable connection to...
QList< KoShape * > shapes() const
void addShape(KoShape *shape)
bool inheritsTransform(const KoShape *shape) const
KoShapeContainerModel * model
virtual KoDocumentResourceManager * resourceManager() const
QList< KoShape * > shapes
void setUpdatesBlocked(bool value)
KoSelection * selection
The undo / redo command for shape moving.
void redo() override
redo the command
This command allows you to change the zIndex of a number of shapes.
void redo() override
redo the command
static QList< KoShapeReorderCommand::IndexedShape > homogenizeZIndexesLazy(QList< IndexedShape > shapes)
void redo() override
redo the command
KoShapeContainer * parent
Definition KoShape_p.h:95
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 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
KoShapeContainer * parent() const
Definition KoShape.cpp:857
QTransform absoluteTransformation() const
Definition KoShape.cpp:330
void setTransformation(const QTransform &matrix)
Definition KoShape.cpp:369
virtual KoShape * cloneShape() const
creates a deep copy of the shape or shape's subtree
Definition KoShape.cpp:173
QTransform transformation() const
Returns the shapes local transformation matrix.
Definition KoShape.cpp:378
void setGeometryProtected(bool on)
Definition KoShape.cpp:837
void setVisible(bool on)
Definition KoShape.cpp:790
void setParent(KoShapeContainer *parent)
Definition KoShape.cpp:459
void setShapeId(const QString &id)
Definition KoShape.cpp:880
QTransform transform() const
return the current matrix that contains the rotation/scale/position of this shape
Definition KoShape.cpp:945
bool open(OpenMode m) override
bool close()
Definition KoStore.cpp:156
bool open(const QString &name)
Definition KoStore.cpp:109
virtual qreal viewToDocumentY(qreal viewY) const
virtual qreal viewToDocumentX(qreal viewX) const
virtual QPointF viewToDocument(const QPointF &viewPoint) const
virtual QPointF documentToView(const QPointF &documentPoint) const
void add(KoShape *child) override
void remove(KoShape *child) override
ShapeLayerContainerModel(KisShapeLayer *parent)
bool setResolution(qreal xRes, qreal yRes)
void add(KoShape *child) override
void remove(KoShape *shape) override
bool inheritsTransform(const KoShape *shape) const override
static QDomDocument createDocumentFromSvg(QIODevice *device, QString *errorMsg=0, int *errorLine=0, int *errorColumn=0)
void setXmlBaseDir(const QString &baseDir)
Sets the initial xml base directory (the directory form where the file is read)
QStringList warnings() const
QList< KoShape * > parseSvg(const QDomElement &e, QSizeF *fragmentSize=0)
Parses a svg fragment, returning the list of top level child shapes.
void setResolution(const QRectF boundsInPixels, qreal pixelsPerInch)
void setDefaultKraTextVersion(int version)
Implements exporting shapes to SVG.
Definition SvgWriter.h:33
bool save(QIODevice &outputDevice, const QSizeF &pageSize)
Writes svg to specified output device.
Definition SvgWriter.cpp:82
TransformShapeLayerDeferred(KisShapeLayer *shapeLayer, const QTransform &globalDocTransform)
KisSafeBlockingQueueConnectionProxy< QTransform > m_blockingConnection
static bool qFuzzyCompare(half p1, half p2)
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
#define KIS_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:75
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
#define KIS_ASSERT(cond)
Definition kis_assert.h:33
#define errKrita
Definition kis_debug.h:115
#define warnKrita
Definition kis_debug.h:94
T kisGrowRect(const T &rect, U offset)
Definition kis_global.h:186
const QString KIS_SHAPE_LAYER_ID
QIcon loadIcon(const QString &name)
void setPinnedToTimeline(bool pinned)
void setSupportsLodMoves(bool value)
virtual void setUserLocked(bool l)
const QString & compositeOpId() const
bool isEditable(bool checkVisibility=true) const
virtual void setVisible(bool visible, bool loading=false)
bool isPinnedToTimeline() const
KoProperties properties
void setColorLabelIndex(int index)
KisImageWSP image
int colorLabelIndex() const
void setCompositeOpId(const QString &compositeOpId)
virtual bool visible(bool recursive=false) const
void setImage(KisImageWSP image) override
Definition kis_layer.cc:378
virtual void fillMergedLayerTemplate(KisLayerSP dstLayer, KisLayerSP prevLayer, bool skipPaintingThisLayer=false)
Definition kis_layer.cc:422
virtual KisLayerSP createMergedLayerTemplate(KisLayerSP prevLayer)
Definition kis_layer.cc:407
QBitArray channelFlags
Definition kis_layer.cc:167
const KoColorSpace * colorSpace() const override
returns the image's colorSpace or null, if there is no image
Definition kis_layer.cc:225
void setSectionModelProperties(const KisBaseNode::PropertyList &properties) override
Definition kis_layer.cc:297
virtual void setChannelFlags(const QBitArray &channelFlags)
Definition kis_layer.cc:342
KisBaseNode::PropertyList sectionModelProperties() const override
Definition kis_layer.cc:272
KisShapeLayerCanvasBase * canvas
KisSignalAutoConnectionsStore imageConnections
KisPaintDeviceSP paintDevice
KoShapeControllerBase * controller