File indexing completed on 2024-10-27 04:07:33

0001 /*
0002  *  SPDX-FileCopyrightText: 2006 Boudewijn Rempt <boud@valdyas.org>
0003  *  SPDX-FileCopyrightText: 2007 Thomas Zander <zander@kde.org>
0004  *
0005  *  SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 #ifndef KIS_SHAPE_LAYER_H_
0009 #define KIS_SHAPE_LAYER_H_
0010 
0011 #include <KoShapeLayer.h>
0012 
0013 #include <kis_types.h>
0014 #include <kis_external_layer_iface.h>
0015 #include <kritaui_export.h>
0016 #include <KisDelayedUpdateNodeInterface.h>
0017 #include <KisCroppedOriginalLayerInterface.h>
0018 
0019 class QRect;
0020 class QIcon;
0021 class QRect;
0022 class QString;
0023 class KoShapeManager;
0024 class KoStore;
0025 class KoViewConverter;
0026 class KoShapeControllerBase;
0027 class KoDocumentResourceManager;
0028 class KisShapeLayerCanvasBase;
0029 class KoSelectedShapesProxy;
0030 
0031 const QString KIS_SHAPE_LAYER_ID = "KisShapeLayer";
0032 /**
0033    A KisShapeLayer contains any number of non-krita flakes, such as
0034    path shapes, text shapes and anything else people come up with.
0035 
0036    The KisShapeLayer has a shapemanager and a canvas of its own. The
0037    canvas paints onto the projection, and the projection is what we
0038    render in Krita. This means that no matter how many views you have,
0039    you cannot have a different view on your shapes per view.
0040 
0041    XXX: what about removing shapes?
0042 */
0043 class KRITAUI_EXPORT KisShapeLayer
0044         : public KisExternalLayer,
0045         public KoShapeLayer,
0046         public KisDelayedUpdateNodeInterface,
0047         public KisCroppedOriginalLayerInterface
0048 {
0049     Q_OBJECT
0050 
0051 public:
0052 
0053     KisShapeLayer(KoShapeControllerBase* shapeController, KisImageWSP image, const QString &name, quint8 opacity);
0054     KisShapeLayer(const KisShapeLayer& _rhs);
0055     KisShapeLayer(const KisShapeLayer& _rhs, KoShapeControllerBase* controller);
0056     KisShapeLayer(const KisShapeLayer& _rhs, KoShapeControllerBase* controller, std::function<KisShapeLayerCanvasBase*()> canvasFactory);
0057     /**
0058      * Merge constructor.
0059      *
0060      * Creates a new layer as a merge of two existing layers.
0061      *
0062      * This is used by createMergedLayer()
0063      */
0064     KisShapeLayer(const KisShapeLayer& _merge, const KisShapeLayer &_addShapes);
0065     ~KisShapeLayer() override;
0066 protected:
0067     KisShapeLayer(KoShapeControllerBase* shapeController, KisImageWSP image, const QString &name, quint8 opacity, std::function<KisShapeLayerCanvasBase *()> canvasFactory);
0068 private:
0069     void initShapeLayerImpl(KoShapeControllerBase* controller, KisShapeLayerCanvasBase *overrideCanvas);
0070 public:
0071     KisNodeSP clone() const override {
0072         return new KisShapeLayer(*this);
0073     }
0074     bool allowAsChild(KisNodeSP) const override;
0075 
0076 
0077     void setImage(KisImageWSP image) override;
0078 
0079     KisLayerSP createMergedLayerTemplate(KisLayerSP prevLayer) override;
0080     void fillMergedLayerTemplate(KisLayerSP dstLayer, KisLayerSP prevLayer, bool skipPaintingThisLayer) override;
0081 public:
0082 
0083     // KoShape overrides
0084     bool isSelectable() const {
0085         return false;
0086     }
0087 
0088     void setParent(KoShapeContainer *parent);
0089 
0090     // KisExternalLayer implementation
0091     QIcon icon() const override;
0092     void resetCache() override;
0093 
0094     KisPaintDeviceSP original() const override;
0095     KisPaintDeviceSP paintDevice() const override;
0096 
0097     QRect theoreticalBoundingRect() const override;
0098 
0099     qint32 x() const override;
0100     qint32 y() const override;
0101     void setX(qint32) override;
0102     void setY(qint32) override;
0103 
0104     bool accept(KisNodeVisitor&) override;
0105     void accept(KisProcessingVisitor &visitor, KisUndoAdapter *undoAdapter) override;
0106 
0107     KoShapeManager *shapeManager() const;
0108 
0109     static bool saveShapesToStore(KoStore *store, QList<KoShape*> shapes, const QSizeF &sizeInPt);
0110 
0111     static QList<KoShape *> createShapesFromSvg(QIODevice *device,
0112                                                 const QString &baseXmlDir,
0113                                                 const QRectF &rectInPixels,
0114                                                 qreal resolutionPPI,
0115                                                 KoDocumentResourceManager *resourceManager,
0116                                                 bool loadingFromKra,
0117                                                 QSizeF *fragmentSize,
0118                                                 QStringList *warnings = 0,
0119                                                 QStringList *errors = 0);
0120 
0121     bool saveLayer(KoStore * store) const;
0122     bool loadLayer(KoStore* store, QStringList *warnings = 0);
0123 
0124     KUndo2Command* crop(const QRect & rect) override;
0125     KUndo2Command* transform(const QTransform &transform) override;
0126     KUndo2Command* setProfile(const KoColorProfile *profile) override;
0127     KUndo2Command* convertTo(const KoColorSpace * dstColorSpace,
0128                                  KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(),
0129                                  KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags()) override;
0130 
0131 
0132     bool visible(bool recursive = false) const override;
0133     void setVisible(bool visible, bool isLoading = false) override;
0134 
0135     void setUserLocked(bool value) override;
0136 
0137     bool isShapeEditable(bool recursive) const override;
0138 
0139     /**
0140      * Forces a repaint of a shape layer without waiting for an event loop
0141      * calling a delayed timer update. If you want to see the result of the shape
0142      * layer right here and right now, you should do:
0143      *
0144      * shapeLayer->setDirty();
0145      * shapeLayer->image()->waitForDone();
0146      * shapeLayer->forceUpdateTimedNode();
0147      * shapeLayer->image()->waitForDone();
0148      *
0149      */
0150     void forceUpdateTimedNode() override;
0151 
0152     /**
0153      * \return true if there are any pending updates in the delayed queue
0154      */
0155     bool hasPendingTimedUpdates() const override;
0156 
0157     void forceUpdateHiddenAreaOnOriginal() override;
0158 
0159     /**
0160      * @brief selectedShapesProxy
0161      * @return returns the selectedShapesProxy of the KoCanvasBase of this layer,
0162      * used for certain undo commands.
0163      */
0164     KoSelectedShapesProxy* selectedShapesProxy();
0165 
0166 protected:
0167     using KoShape::isVisible;
0168 
0169     bool loadSvg(QIODevice *device, const QString &baseXmlDir, QStringList *warnings = 0);
0170 
0171 
0172     friend class ShapeLayerContainerModel;
0173     const KoViewConverter *converter() const;
0174 
0175     KoShapeControllerBase *shapeController() const;
0176     KisShapeLayerCanvasBase *canvas() const;
0177 
0178     friend class TransformShapeLayerDeferred;
0179 
0180 Q_SIGNALS:
0181     /**
0182      * These signals are forwarded from the local shape manager
0183      * This is done because we switch KoShapeManager and therefore
0184      * KoSelection in KisCanvas2, so we need to connect local managers
0185      * to the UI as well.
0186      *
0187      * \see comment in the constructor of KisCanvas2
0188      */
0189     void selectionChanged();
0190     void currentLayerChanged(const KoShapeLayer *layer);
0191 
0192 Q_SIGNALS:
0193     /**
0194      * A signal + slot to synchronize UI and image
0195      * threads. Image thread emits the signal, UI
0196      * thread performs the action
0197      */
0198     void sigMoveShapes(const QPointF &diff);
0199 
0200 private Q_SLOTS:
0201     void slotMoveShapes(const QPointF &diff);
0202     void slotTransformShapes(const QTransform &transform);
0203     void slotImageResolutionChanged();
0204 
0205 private:
0206     QList<KoShape*> shapesToBeTransformed();
0207 
0208 private:
0209     struct Private;
0210     Private * const m_d;
0211 };
0212 
0213 #endif