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 void setResolution(qreal xRes, qreal yRes) {
106 if (!qFuzzyCompare(m_xRes, xRes) || !qFuzzyCompare(m_yRes, yRes)) {
107 m_xRes = xRes;
108 m_yRes = yRes;
109 Q_FOREACH (KoShape *shape, shapes()) {
110 shape->setResolution(xRes, yRes);
111 }
112 }
113 }
114
115private:
117 qreal m_xRes{72.0};
118 qreal m_yRes{72.0};
119};
120
121
141
142
144 KisImageWSP image,
145 const QString &name,
146 quint8 opacity)
147 : KisShapeLayer(controller, image, name, opacity,
148 [&] () { return new KisShapeLayerCanvas(image->colorSpace(), new KisDefaultBounds(image), this);})
149{
150}
151
153 : KisShapeLayer(rhs,
154 rhs.m_d->controller)
155{
156}
157
159 : KisShapeLayer(rhs,
160 controller,
161 [&] () {
162 const KisShapeLayerCanvas* shapeLayerCanvas = dynamic_cast<const KisShapeLayerCanvas*>(rhs.m_d->canvas);
163 KIS_ASSERT(shapeLayerCanvas);
164 return new KisShapeLayerCanvas(*shapeLayerCanvas, this);})
165{
166}
167
169 std::function<KisShapeLayerCanvasBase *()> canvasFactory)
170 : KisExternalLayer(_rhs)
171 , KoShapeLayer(new ShapeLayerContainerModel(this)) //no _rhs here otherwise both layer have the same KoShapeContainerModel
172 , m_d(new Private())
173{
174 initShapeLayerImpl(controller, canvasFactory());
176
181 const QTransform thisInvertedTransform = this->absoluteTransformation().inverted();
182
184
185 Q_FOREACH (KoShape *shape, _rhs.shapes()) {
186 KoShape *clonedShape = shape->cloneShape();
187 KIS_SAFE_ASSERT_RECOVER(clonedShape) { continue; }
188 clonedShape->setTransformation(shape->absoluteTransformation() * thisInvertedTransform);
189 addShape(clonedShape);
190 }
191
193}
194
195KisShapeLayer::KisShapeLayer(const KisShapeLayer& baseTemplate, const QList<KoShape*> &newShapes)
196 : KisExternalLayer(baseTemplate)
197 , KoShapeLayer(new ShapeLayerContainerModel(this)) //no _merge here otherwise both layer have the same KoShapeContainerModel
198 , m_d(new Private())
199{
200 // Make sure our new layer is visible otherwise the shapes cannot be painted.
201 setVisible(true);
202
203 m_d->isAntialiased = baseTemplate.m_d->isAntialiased;
204
205 const KisShapeLayerCanvas* shapeLayerCanvas = dynamic_cast<const KisShapeLayerCanvas*>(baseTemplate.canvas());
206 KIS_ASSERT(shapeLayerCanvas);
207 initShapeLayerImpl(baseTemplate.m_d->controller, new KisShapeLayerCanvas(*shapeLayerCanvas, this));
208
214 const QTransform thisInvertedTransform = this->absoluteTransformation().inverted();
215
216 QList<KoShape *> clonedShapes;
217
218 // copy all the new shapes; we expect them to be sorted and homogenized
219
220 const bool isSorted = std::is_sorted(newShapes.begin(), newShapes.end(), KoShape::compareShapeZIndex);
222
223 Q_FOREACH (KoShape *shape, newShapes) {
224 KoShape *clonedShape = shape->cloneShape();
225 KIS_SAFE_ASSERT_RECOVER(clonedShape) { continue; }
226 clonedShape->setTransformation(shape->absoluteTransformation() * thisInvertedTransform);
227 clonedShapes.append(clonedShape);
228 }
229
230 Q_FOREACH (KoShape *shape, clonedShapes) {
231 addShape(shape);
232 }
233}
234
236 KisImageWSP image,
237 const QString &name,
238 quint8 opacity,
239 std::function<KisShapeLayerCanvasBase *()> canvasFactory)
240 : KisExternalLayer(image, name, opacity)
242 , m_d(new Private())
243{
244 initShapeLayerImpl(controller, canvasFactory());
245}
246
248{
253
254 Q_FOREACH (KoShape *shape, shapes()) {
255 shape->setParent(0);
256 delete shape;
257 }
258
259 delete m_d->canvas;
260 delete m_d;
261}
262
265{
266 setSupportsLodMoves(false);
268
270
272
273 m_d->canvas = canvas;
274 m_d->canvas->moveToThread(this->thread());
275 m_d->controller = controller;
276
277 m_d->canvas->shapeManager()->selection()->disconnect(this);
278
279 connect(m_d->canvas->selectedShapesProxy(), SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
281 this, SIGNAL(currentLayerChanged(const KoShapeLayer*)));
282
283 connect(this, SIGNAL(sigMoveShapes(QPointF)), SLOT(slotMoveShapes(QPointF)));
284
287 model->setAssociatedRootShapeManager(m_d->canvas->shapeManager());
288
289 if (this->image()) {
290 m_d->imageConnections.addUniqueConnection(this->image(), SIGNAL(sigResolutionChanged(double, double)), this, SLOT(slotImageResolutionChanged()));
292 }
293}
294
296{
297 return node->inherits("KisMask");
298}
299
301{
303 KisLayer::setImage(_image);
304 m_d->canvas->setImage(_image);
305 if (m_d->paintDevice) {
307 }
308 if (_image) {
309 m_d->imageConnections.addUniqueConnection(_image, SIGNAL(sigResolutionChanged(double, double)), this, SLOT(slotImageResolutionChanged()));
311 }
312}
313
314
323
325{
326 Q_FOREACH (const KisBaseNode::Property &property, properties) {
327 if (property.name == i18n("Anti-aliasing")) {
328 setAntialiased(property.state.toBool());
329 }
330 }
331
333}
334
336{
337 // NOTE: layers.first() may possibly point to `this`!
338
339 QList<KisShapeLayer*> shapeLayers;
340 Q_FOREACH(KisLayerSP layer, layers) {
341 KisShapeLayer *shapeLayer = dynamic_cast<KisShapeLayer*>(layer.data());
342 if (!shapeLayer) return nullptr;
343
344 shapeLayers << shapeLayer;
345 }
346
347 QList<KoShape*> allShapes;
349 Q_FOREACH(KisShapeLayer *layer, shapeLayers) {
350 QList<KoShape*> shapes = layer->shapes();
351 std::sort(shapes.begin(), shapes.end(), KoShape::compareShapeZIndex);
352
353 Q_FOREACH(KoShape *shape, shapes) {
354 allShapes << shape;
355 allIndexedShapes << shape;
356 }
357 }
358
359 allIndexedShapes = KoShapeReorderCommand::homogenizeZIndexesLazy(allIndexedShapes);
360
361 KoShapeReorderCommand cmd(allIndexedShapes);
362 cmd.redo();
363
364 KisLayerSP newLayer = new KisShapeLayer(*this, allShapes);
365
366 newLayer->setCompositeOpId(this->compositeOpId());
367 if (!this->channelFlags().isEmpty()) {
368 newLayer->setChannelFlags(this->channelFlags());
369 }
370
371 newLayer->setCompositeOpId(this->compositeOpId());
372 newLayer->setPinnedToTimeline(this->isPinnedToTimeline());
373 newLayer->setColorLabelIndex(this->colorLabelIndex());
374
375 return newLayer;
376}
377
379{
380 KisLayerSP newLayer;
381
382 KisShapeLayer *prevShape = dynamic_cast<KisShapeLayer*>(prevLayer.data());
383 if (prevShape) {
384 newLayer = tryCreateInternallyMergedLayerFromMutipleLayers({prevLayer, this});
386 }
387
388 return newLayer ? newLayer : KisExternalLayer::createMergedLayerTemplate(prevLayer);
389}
390
391void KisShapeLayer::fillMergedLayerTemplate(KisLayerSP dstLayer, KisLayerSP prevLayer, bool skipPaintingThisLayer)
392{
393 if (!dynamic_cast<KisShapeLayer*>(dstLayer.data())) {
394 KisLayer::fillMergedLayerTemplate(dstLayer, prevLayer, skipPaintingThisLayer);
395 }
396}
397
399{
400 Q_UNUSED(parent);
402}
403
405{
406 return KisIconUtils::loadIcon("vectorLayer");
407}
408
413
415{
416 return 0;
417}
418
420{
421 return kisGrowRect(m_d->canvas->viewConverter()->documentToView(this->boundingRect()).toAlignedRect(), 1);
422}
423
424qint32 KisShapeLayer::x() const
425{
426 return m_d->x;
427}
428
429qint32 KisShapeLayer::y() const
430{
431 return m_d->y;
432}
433
435{
436 qint32 delta = x - this->x();
437 QPointF diff = QPointF(m_d->canvas->viewConverter()->viewToDocumentX(delta), 0);
438 Q_EMIT sigMoveShapes(diff);
439
440 // Save new value to satisfy LSP
441 m_d->x = x;
442}
443
445{
446 qint32 delta = y - this->y();
447 QPointF diff = QPointF(0, m_d->canvas->viewConverter()->viewToDocumentY(delta));
448 Q_EMIT sigMoveShapes(diff);
449
450 // Save new value to satisfy LSP
451 m_d->y = y;
452}
453namespace {
454void filterTransformableShapes(QList<KoShape*> &shapes)
455{
456 auto it = shapes.begin();
457 while (it != shapes.end()) {
458 if (shapes.size() == 1) break;
459
460 if ((*it)->inheritsTransformFromAny(shapes)) {
461 it = shapes.erase(it);
462 } else {
463 ++it;
464 }
465 }
466}
467}
468
470{
472
473 // We expect that **all** the shapes inherit the transform from its parent
474
475 // SANITY_CHECK: we expect all the shapes inside the
476 // shape layer to inherit transform!
477 Q_FOREACH (KoShape *shape, shapes) {
478 if (shape->parent()) {
480 break;
481 }
482 }
483 }
484
485 shapes << this;
486 filterTransformableShapes(shapes);
487 return shapes;
488}
489
490void KisShapeLayer::slotMoveShapes(const QPointF &diff)
491{
493 if (shapes.isEmpty()) return;
494
495 KoShapeMoveCommand cmd(shapes, diff);
496 cmd.redo();
497}
498
499void KisShapeLayer::slotTransformShapes(const QTransform &newTransform)
500{
501 KoShapeTransformCommand cmd({this}, {transformation()}, {newTransform});
502 cmd.redo();
503}
504
506{
507 return visitor.visit(this);
508}
509
511{
512 return visitor.visit(this, undoAdapter);
513}
514
519
521{
522 return m_d->canvas->viewConverter();
523}
524
525bool KisShapeLayer::visible(bool recursive) const
526{
527 return KisExternalLayer::visible(recursive);
528}
529
530void KisShapeLayer::setVisible(bool visible, bool isLoading)
531{
532 const bool oldVisible = this->visible(false);
533
536
537 if (visible && !oldVisible &&
539
541 }
542}
543
549
550bool KisShapeLayer::isShapeEditable(bool recursive) const
551{
552 return KoShapeLayer::isShapeEditable(recursive) && isEditable(true);
553}
554
555// we do not override KoShape::setGeometryProtected() as we consider
556// the user not being able to access the layer shape from Krita UI!
557
562
567
572
577
578bool KisShapeLayer::saveShapesToStore(KoStore *store, QList<KoShape *> shapes, const QSizeF &sizeInPt)
579{
580 if (!store->open("content.svg")) {
581 return false;
582 }
583
584 KoStoreDevice storeDev(store);
585 storeDev.open(QIODevice::WriteOnly);
586
587 std::sort(shapes.begin(), shapes.end(), KoShape::compareShapeZIndex);
588
589 SvgWriter writer(shapes);
590 writer.save(storeDev, sizeInPt);
591
592 if (!store->close()) {
593 return false;
594 }
595
596 return true;
597}
598
599QList<KoShape *> KisShapeLayer::createShapesFromSvg(QIODevice *device, const QString &baseXmlDir, const QRectF &rectInPixels, qreal resolutionPPI, KoDocumentResourceManager *resourceManager, bool loadingFromKra, QSizeF *fragmentSize, QStringList *warnings, QStringList *errors)
600{
601
602 QString errorMsg;
603 int errorLine = 0;
604 int errorColumn;
605
606 QDomDocument doc = SvgParser::createDocumentFromSvg(device, &errorMsg, &errorLine, &errorColumn);
607 if (doc.isNull()) {
608 errKrita << "Parsing error in contents.svg! Aborting!" << Qt::endl
609 << " In line: " << errorLine << ", column: " << errorColumn << Qt::endl
610 << " Error message: " << errorMsg << Qt::endl;
611
612 if (errors) {
613 *errors << i18n("Parsing error in the main document at line %1, column %2\nError message: %3"
614 , errorLine , errorColumn , errorMsg);
615 }
616 return QList<KoShape*>();
617 }
618
619 SvgParser parser(resourceManager);
620 parser.setXmlBaseDir(baseXmlDir);
621 parser.setResolution(rectInPixels /* px */, resolutionPPI /* ppi */);
622
623 if (loadingFromKra) {
632 parser.setDefaultKraTextVersion(1);
633 }
634
635 QList<KoShape *> result = parser.parseSvg(doc.documentElement(), fragmentSize);
636
637 if (warnings) {
638 *warnings = parser.warnings();
639 }
640
641 return result;
642}
643
644
646{
647 // FIXME: we handle xRes() only!
648
649 const QSizeF sizeInPx = image()->bounds().size();
650 const QSizeF sizeInPt(sizeInPx.width() / image()->xRes(), sizeInPx.height() / image()->yRes());
651
652 return saveShapesToStore(store, this->shapes(), sizeInPt);
653}
654
655bool KisShapeLayer::loadSvg(QIODevice *device, const QString &baseXmlDir, QStringList *warnings)
656{
657 QSizeF fragmentSize; // unused!
658 KisImageSP image = this->image();
659
660 // FIXME: we handle xRes() only!
662 const qreal resolutionPPI = 72.0 * image->xRes();
663
665 createShapesFromSvg(device, baseXmlDir,
666 image->bounds(), resolutionPPI,
668 true,
669 &fragmentSize,
670 warnings);
671
672 Q_FOREACH (KoShape *shape, shapes) {
673 addShape(shape);
674 }
675
676 return true;
677}
678
680{
681 if (!store) {
682 warnKrita << "No store backend";
683 return false;
684 }
685
686 if (store->open("content.svg")) {
687 KoStoreDevice storeDev(store);
688 storeDev.open(QIODevice::ReadOnly);
689
690 loadSvg(&storeDev, "", warnings);
691
692 store->close();
693
694 return true;
695 }
696
697 return false;
698
699}
700
702{
704}
705
707{
708 QPoint oldPos(x(), y());
709 QPoint newPos = oldPos - rect.topLeft();
710
711 return new KisNodeMoveCommand2(this, oldPos, newPos);
712}
713
715{
716public:
717 TransformShapeLayerDeferred(KisShapeLayer *shapeLayer, const QTransform &globalDocTransform)
718 : m_shapeLayer(shapeLayer),
719 m_globalDocTransform(globalDocTransform),
720 m_blockingConnection(std::bind(&KisShapeLayer::slotTransformShapes, shapeLayer, std::placeholders::_1))
721 {
722 }
723
724 void undo() override
725 {
726 KIS_SAFE_ASSERT_RECOVER_NOOP(QThread::currentThread() != qApp->thread());
728 }
729
730 void redo() override
731 {
733
734 const QTransform globalTransform = m_shapeLayer->absoluteTransformation();
735 const QTransform localTransform = globalTransform * m_globalDocTransform * globalTransform.inverted();
736
737 KIS_SAFE_ASSERT_RECOVER_NOOP(QThread::currentThread() != qApp->thread());
739 }
740
741private:
746};
747
748
749KUndo2Command* KisShapeLayer::transform(const QTransform &transform)
750{
752 if (shapes.isEmpty()) return 0;
753 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(shapes.size() == 1 && shapes.first() == this, 0);
754
759 const KisImageViewConverter *converter = dynamic_cast<const KisImageViewConverter*>(this->converter());
760 KIS_ASSERT(converter);
761 QTransform docSpaceTransform = converter->documentToView() *
763
764 return new TransformShapeLayerDeferred(this, docSpaceTransform);
765}
766
768{
769 using namespace KisDoSomethingCommandOps;
770
771 KUndo2Command *cmd = new KUndo2Command();
773 m_d->paintDevice->setProfile(profile, cmd);
775
776 return cmd;
777}
778
779KUndo2Command *KisShapeLayer::convertTo(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)
780{
781 using namespace KisDoSomethingCommandOps;
782
783 KUndo2Command *cmd = new KUndo2Command();
785 m_d->paintDevice->convertTo(dstColorSpace, renderingIntent, conversionFlags, cmd);
787 return cmd;
788}
789
794
799
801{
804 if (this->image()) {
805 model->setResolution(image()->xRes() * 72.0, image()->yRes() * 72.0);
806 }
807}
808
809
811{
812 return m_d->isAntialiased;
813}
814
815void KisShapeLayer::setAntialiased(const bool antialiased)
816{
817 const bool oldAntialiased = m_d->isAntialiased;
818
819 if (antialiased != oldAntialiased) {
821 // is it the best way to rerender the vector layer?
823 }
824}
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:970
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
KoShapeContainer * parent() const
Definition KoShape.cpp:862
QTransform absoluteTransformation() const
Definition KoShape.cpp:335
void setTransformation(const QTransform &matrix)
Definition KoShape.cpp:374
virtual KoShape * cloneShape() const
creates a deep copy of the shape or shape's subtree
Definition KoShape.cpp:172
QTransform transformation() const
Returns the shapes local transformation matrix.
Definition KoShape.cpp:383
void setGeometryProtected(bool on)
Definition KoShape.cpp:842
void setVisible(bool on)
Definition KoShape.cpp:795
void setParent(KoShapeContainer *parent)
Definition KoShape.cpp:464
void setShapeId(const QString &id)
Definition KoShape.cpp:885
QTransform transform() const
return the current matrix that contains the rotation/scale/position of this shape
Definition KoShape.cpp:950
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
void setResolution(qreal xRes, qreal yRes)
ShapeLayerContainerModel(KisShapeLayer *parent)
void add(KoShape *child) override
QList< KoShape * > shapes() const 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:107
#define warnKrita
Definition kis_debug.h:87
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