File indexing completed on 2024-05-19 04:26:57
0001 /* 0002 * SPDX-FileCopyrightText: 2017 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 #include "Shape.h" 0007 #include <kis_icon_utils.h> 0008 #include <SvgWriter.h> 0009 #include <SvgParser.h> 0010 #include <SvgSavingContext.h> 0011 #include <QBuffer> 0012 #include <KoDocumentResourceManager.h> 0013 #include <kis_processing_applicator.h> 0014 #include <KisPart.h> 0015 #include <KisView.h> 0016 #include <KisDocument.h> 0017 #include <kis_canvas2.h> 0018 #include <KisMainWindow.h> 0019 #include <KoShapeController.h> 0020 #include <KoSelection.h> 0021 0022 #include "Krita.h" 0023 #include "Document.h" 0024 #include "GroupShape.h" 0025 0026 struct Shape::Private { 0027 Private() {} 0028 KoShape *shape {0}; 0029 }; 0030 0031 Shape::Shape(KoShape *shape, QObject *parent) 0032 : QObject(parent) 0033 , d(new Private) 0034 { 0035 d->shape = shape; 0036 } 0037 0038 Shape::~Shape() 0039 { 0040 delete d; 0041 } 0042 0043 bool Shape::operator==(const Shape &other) const 0044 { 0045 return (d->shape == other.d->shape); 0046 } 0047 0048 bool Shape::operator!=(const Shape &other) const 0049 { 0050 return !(operator==(other)); 0051 } 0052 0053 QString Shape::name() const 0054 { 0055 return d->shape->name(); 0056 } 0057 0058 void Shape::setName(const QString &name) 0059 { 0060 d->shape->setName(name); 0061 } 0062 0063 QString Shape::type() const 0064 { 0065 return d->shape->shapeId(); 0066 } 0067 0068 int Shape::zIndex() const 0069 { 0070 return d->shape->zIndex(); 0071 } 0072 0073 void Shape::setZIndex(int zindex) 0074 { 0075 d->shape->setZIndex(zindex); 0076 } 0077 0078 bool Shape::selectable() const 0079 { 0080 return d->shape->isSelectable(); 0081 } 0082 0083 void Shape::setSelectable(bool selectable) 0084 { 0085 d->shape->setSelectable(selectable); 0086 } 0087 0088 bool Shape::geometryProtected() const 0089 { 0090 return d->shape->isGeometryProtected(); 0091 } 0092 0093 void Shape::setGeometryProtected(bool protect) 0094 { 0095 d->shape->setGeometryProtected(protect); 0096 } 0097 0098 bool Shape::visible() const 0099 { 0100 return d->shape->isVisible(); 0101 } 0102 0103 void Shape::setVisible(bool visible) 0104 { 0105 d->shape->setVisible(visible); 0106 } 0107 0108 QRectF Shape::boundingBox() const 0109 { 0110 return d->shape->boundingRect(); 0111 } 0112 0113 QPointF Shape::position() const 0114 { 0115 return d->shape->position(); 0116 } 0117 0118 void Shape::setPosition(QPointF point) 0119 { 0120 d->shape->setPosition(point); 0121 } 0122 0123 QTransform Shape::transformation() const 0124 { 0125 return d->shape->transformation(); 0126 } 0127 0128 void Shape::setTransformation(QTransform matrix) 0129 { 0130 d->shape->setTransformation(matrix); 0131 } 0132 0133 QTransform Shape::absoluteTransformation() const 0134 { 0135 return d->shape->absoluteTransformation(); 0136 } 0137 0138 void Shape::update() 0139 { 0140 return d->shape->update(); 0141 } 0142 0143 void Shape::updateAbsolute(QRectF box) 0144 { 0145 return d->shape->updateAbsolute(box); 0146 } 0147 0148 bool Shape::remove() 0149 { 0150 if (!d->shape) return false; 0151 if (!d->shape->parent()) return false; 0152 0153 bool removeStatus = false; 0154 Document *document = Krita::instance()->activeDocument(); 0155 0156 if (KisPart::instance()->viewCount(document->document()) > 0) { 0157 for (QPointer<KisView> view : KisPart::instance()->views()) { 0158 if (view && view->document() == document->document()) { 0159 KisProcessingApplicator::runSingleCommandStroke(view->image(), view->canvasBase()->shapeController()->removeShape(d->shape)); 0160 view->image()->waitForDone(); 0161 removeStatus = true; 0162 break; 0163 } 0164 } 0165 } 0166 0167 delete document; 0168 0169 return removeStatus; 0170 } 0171 0172 QString Shape::toSvg(bool prependStyles, bool stripTextMode) 0173 { 0174 QBuffer shapesBuffer; 0175 QBuffer stylesBuffer; 0176 0177 shapesBuffer.open(QIODevice::WriteOnly); 0178 stylesBuffer.open(QIODevice::WriteOnly); 0179 0180 { 0181 SvgSavingContext savingContext(shapesBuffer, stylesBuffer); 0182 savingContext.setStrippedTextMode(stripTextMode); 0183 SvgWriter writer({d->shape}); 0184 writer.saveDetached(savingContext); 0185 } 0186 0187 shapesBuffer.close(); 0188 stylesBuffer.close(); 0189 0190 return (prependStyles ? QString::fromUtf8(stylesBuffer.data()):"") + QString::fromUtf8(shapesBuffer.data()); 0191 } 0192 0193 void Shape::select() 0194 { 0195 if (!d->shape) return; 0196 0197 KisView *activeView = KisPart::instance()->currentMainwindow()->activeView(); 0198 KoSelection *selection = activeView->canvasBase()->shapeManager()->selection(); 0199 0200 selection->select(d->shape); 0201 } 0202 0203 void Shape::deselect() 0204 { 0205 if (!d->shape) return; 0206 0207 KisView *activeView = KisPart::instance()->currentMainwindow()->activeView(); 0208 KoSelection *selection = activeView->canvasBase()->shapeManager()->selection(); 0209 0210 selection->deselect(d->shape); 0211 } 0212 0213 bool Shape::isSelected() 0214 { 0215 if (!d->shape) return false; 0216 0217 KisView *activeView = KisPart::instance()->currentMainwindow()->activeView(); 0218 KoSelection *selection = activeView->canvasBase()->shapeManager()->selection(); 0219 0220 return selection->isSelected(d->shape); 0221 } 0222 0223 Shape* Shape::parentShape() const 0224 { 0225 if (!d->shape) return 0; 0226 if (!d->shape->parent()) return 0; 0227 0228 if (dynamic_cast<KoShapeGroup*>(d->shape->parent())) { 0229 return new GroupShape(dynamic_cast<KoShapeGroup*>(d->shape->parent())); 0230 } else { 0231 return 0; 0232 } 0233 } 0234 0235 0236 KoShape *Shape::shape() 0237 { 0238 return d->shape; 0239 }