File indexing completed on 2024-05-19 04:24:55

0001 /* This file is part of the KDE project
0002    SPDX-FileCopyrightText: 2006-2008 Thorsten Zachmann <zachmann@kde.org>
0003    SPDX-FileCopyrightText: 2006, 2008 C. Boemann <cbo@boemann.dk>
0004    SPDX-FileCopyrightText: 2006-2010 Thomas Zander <zander@kde.org>
0005    SPDX-FileCopyrightText: 2007-2009, 2011 Jan Hambrecht <jaham@gmx.net>
0006 
0007    SPDX-License-Identifier: LGPL-2.0-or-later
0008 */
0009 
0010 #ifndef KOSHAPE_H
0011 #define KOSHAPE_H
0012 
0013 #include "KoFlake.h"
0014 #include "KoFlakeTypes.h"
0015 
0016 #include <QSharedPointer>
0017 #include <QSet>
0018 #include <QMap>
0019 #include <QMetaType>
0020 #include <QSharedDataPointer>
0021 
0022 #include <QDomDocument>
0023 
0024 #include "kritaflake_export.h"
0025 
0026 class QPainter;
0027 class QRectF;
0028 class QPainterPath;
0029 class QTransform;
0030 
0031 class KoShapeContainer;
0032 class KoShapeStrokeModel;
0033 class KoShapeUserData;
0034 class KoViewConverter;
0035 class KoShapeApplicationData;
0036 class KoShapeSavingContext;
0037 class KoShapeLoadingContext;
0038 class KoShapeShadow;
0039 class KoFilterEffectStack;
0040 class KoSnapData;
0041 class KoClipPath;
0042 class KoClipMask;
0043 class KoShapeAnchor;
0044 struct KoInsets;
0045 class KoShapeBackground;
0046 class KisHandlePainterHelper;
0047 class KoShapeManager;
0048 
0049 /**
0050  * Base class for all flake shapes. Shapes extend this class
0051  * to allow themselves to be manipulated. This class just represents
0052  * a graphical shape in the document and can be manipulated by some default
0053  * tools in this library.
0054  *
0055  * Due to the limited responsibility of this class, the extending object
0056  * can have any data backend and is responsible for painting itself.
0057  *
0058  * We strongly suggest that any extending class will use a Model View
0059  * Controller (MVC) design where the View part is all in this class, as well
0060  * as the one that inherits from this one.  This allows the data that rests
0061  * in the model to be reused in different parts of the document. For example
0062  * by having two flake objects that show that same data. Or each showing a section of it.
0063  *
0064  * The KoShape data is completely in postscript-points (pt) (see KoUnit
0065  * for conversion methods to and from points).
0066  * This image will explain the real-world use of the shape and its options.
0067  * <img src="../flake_shape_coords.png" align=center><br>
0068  *  The Rotation center can be returned with absolutePosition()
0069  *
0070  * <p>Flake objects can be created in three ways:
0071  * <ul>
0072  *   <li>a simple new KoDerivedFlake(),
0073  *   <li>through an associated tool,
0074  *   <li>through a factory
0075  * </ul>
0076  *
0077  * <h1>Shape interaction notifications</h1>
0078  * We had several notification methods that allow your shape to be notified of changes in other
0079  * shapes positions or rotation etc.
0080  * <ol><li>The most general is KoShape::shapeChanged().<br>
0081  * a virtual method that you can use to check various changed to your shape made by tools or otherwise.</li>
0082  * <li>for shape hierarchies the parent may receive a notification when a child was modified.
0083  *  This is done though KoShapeContainerModel::childChanged()</li>
0084  * <li>any shape that is at a similar position as another shape there is collision detection.
0085  * You can register your shape to be sensitive to any changes like moving or whatever to
0086  * <b>other</b> shapes that intersect yours.
0087  * Such changes will then be notified to your shape using the method from (1) You should call
0088  * KoShape::setCollisionDetection(bool) to enable this.
0089  * </ol>
0090  */
0091 class KRITAFLAKE_EXPORT KoShape
0092 {
0093 public:
0094     /// Used by shapeChanged() to select which change was made
0095     enum ChangeType {
0096         PositionChanged, ///< used after a setPosition()
0097         RotationChanged, ///< used after a setRotation()
0098         ScaleChanged,   ///< used after a scale()
0099         ShearChanged,   ///< used after a shear()
0100         SizeChanged,    ///< used after a setSize()
0101         GenericMatrixChange,    ///< used after the matrix was changed without knowing which property explicitly changed
0102         KeepAspectRatioChange, ///< used after setKeepAspectRatio()
0103         ParentChanged,   ///< used after a setParent()
0104         Deleted, ///< the shape was deleted
0105         StrokeChanged, ///< the shapes stroke has changed
0106         BackgroundChanged, ///< the shapes background has changed
0107         ShadowChanged, ///< the shapes shadow has changed
0108         BorderChanged, ///< the shapes border has changed
0109         ParameterChanged, ///< the shapes parameter has changed (KoParameterShape only)
0110         ContentChanged, ///< the content of the shape changed e.g. a new image inside a pixmap/text change inside a textshape
0111         TextRunAroundChanged, ///< used after a setTextRunAroundSide()
0112         ChildChanged, ///< a child of a container was changed/removed. This is propagated to all parents
0113         ConnectionPointChanged, ///< a connection point has changed
0114         ClipPathChanged, ///< the shapes clip path has changed
0115         ClipMaskChanged, ///< the shapes clip path has changed
0116         TransparencyChanged ///< the shapetransparency value has changed
0117     };
0118 
0119     /// The behavior text should do when intersecting this shape.
0120     enum TextRunAroundSide {
0121         BiggestRunAroundSide,   ///< Run other text around the side that has the most space
0122         LeftRunAroundSide,      ///< Run other text around the left side of the frame
0123         RightRunAroundSide,     ///< Run other text around the right side of the frame
0124         EnoughRunAroundSide,      ///< Run other text dynamically around both sides of the shape, provided there is sufficient space left
0125         BothRunAroundSide,      ///< Run other text around both sides of the shape
0126         NoRunAround,            ///< The text will be completely avoiding the frame by keeping the horizontal space that this frame occupies blank.
0127         RunThrough              ///< The text will completely ignore the frame and layout as if it was not there
0128     };
0129 
0130     /// The behavior text should do when intersecting this shape.
0131     enum TextRunAroundContour {
0132         ContourBox,     /// Run other text around a bounding rect of the outline
0133         ContourFull,   ///< Run other text around also on the inside
0134         ContourOutside   ///< Run other text around only on the outside
0135     };
0136 
0137     /**
0138      * TODO
0139      */
0140     enum RunThroughLevel {
0141         Background,
0142         Foreground
0143     };
0144 
0145     enum PaintOrder {
0146         Fill,
0147         Stroke,
0148         Markers
0149     };
0150 
0151     /**
0152      * @brief Constructor
0153      */
0154     KoShape();
0155 
0156     /**
0157      * @brief Destructor
0158      */
0159     virtual ~KoShape();
0160 
0161     /**
0162      * @brief creates a deep copy of the shape or shape's subtree
0163      * @return a cloned shape
0164      */
0165     virtual KoShape* cloneShape() const;
0166 
0167     /**
0168      * @brief creates a deep copy of the shape/shapes tree and bakes
0169      * the absolute transform of `this` into the resulting shape.
0170      *
0171      * After cloning clonedShape->transformation() is equal to
0172      * this->absoluteTransformation(), even though the new shape
0173      * has no parents.
0174      *
0175      * This is just a convenience wrapper for cloneShape()
0176      *
0177      * @return cloned shape
0178      */
0179     KoShape* cloneShapeAndBakeAbsoluteTransform() const;
0180 
0181     /**
0182      * @brief Paint the shape fill
0183      * The class extending this one is responsible for painting itself. \p painter is expected
0184      * to be preconfigured to work in "document" pixels.
0185      *
0186      * @param painter used for painting the shape
0187      */
0188     virtual void paint(QPainter &painter) const = 0;
0189 
0190     /**
0191      * @brief paintStroke paints the shape's stroked outline
0192      * @param painter used for painting the shape
0193      * @see applyConversion()
0194      */
0195     virtual void paintStroke(QPainter &painter) const;
0196 
0197     /**
0198      * @brief paintStroke paints the shape's markers
0199      * @param painter used for painting the shape
0200      * @see applyConversion()
0201      */
0202     virtual void paintMarkers(QPainter &painter) const;
0203 
0204     /**
0205      * @brief Scale the shape using the zero-point which is the top-left corner.
0206      * @see position()
0207      *
0208      * @param sx scale in x direction
0209      * @param sy scale in y direction
0210      */
0211     void scale(qreal sx, qreal sy);
0212 
0213     /**
0214      * @brief Rotate the shape (relative)
0215      *
0216      * The shape will be rotated from the current rotation using the center of the shape using the size()
0217      *
0218      * @param angle change the angle of rotation increasing it with 'angle' degrees
0219      */
0220     void rotate(qreal angle);
0221 
0222     /**
0223      * Return the current rotation in degrees.
0224      * It returns NaN if the shape has a shearing or scaling transformation applied.
0225      */
0226     qreal rotation() const;
0227 
0228     /**
0229      * @brief Shear the shape
0230      * The shape will be sheared using the zero-point which is the top-left corner.
0231      * @see position()
0232      *
0233      * @param sx shear in x direction
0234      * @param sy shear in y direction
0235      */
0236     void shear(qreal sx, qreal sy);
0237 
0238     /**
0239      * @brief Resize the shape
0240      *
0241      * @param size the new size of the shape.  This is different from scaling as
0242      * scaling is a so called secondary operation which is comparable to zooming in
0243      * instead of changing the size of the basic shape.
0244      * Easiest example of this difference is that using this method will not distort the
0245      * size of pattern-fills and strokes.
0246      */
0247     virtual void setSize(const QSizeF &size);
0248 
0249     /**
0250      * @brief Get the size of the shape in pt.
0251      *
0252      * The size is in shape coordinates.
0253      *
0254      * @return the size of the shape as set by setSize()
0255      */
0256     virtual QSizeF size() const;
0257 
0258     /**
0259      * @brief Set the position of the shape in pt
0260      *
0261      * @param position the new position of the shape
0262      */
0263     virtual void setPosition(const QPointF &position);
0264 
0265     /**
0266      * @brief Get the position of the shape in pt
0267      *
0268      * @return the position of the shape
0269      */
0270     QPointF position() const;
0271 
0272     /**
0273      * @brief Check if the shape is hit on position
0274      * @param position the position where the user clicked.
0275      * @return true when it hits.
0276      */
0277     virtual bool hitTest(const QPointF &position) const;
0278 
0279     /**
0280      * @brief Get the bounding box of the shape
0281      *
0282      * This includes the line width and the shadow of the shape
0283      *
0284      * @return the bounding box of the shape
0285      */
0286     virtual QRectF boundingRect() const;
0287 
0288     /**
0289      * Get the united bounding box of a group of shapes. This is a utility
0290      * function used in many places in Krita.
0291      */
0292     static QRectF boundingRect(const QList<KoShape*> &shapes);
0293 
0294     /**
0295      * @return the bounding rect of the outline of the shape measured
0296      *         in absolute coordinate system. Please note that in contrast to
0297      *         boundingRect() this rect doesn't include the stroke and other
0298      *         insets.
0299      */
0300     QRectF absoluteOutlineRect() const;
0301 
0302     /**
0303      * Same as a member function, but applies to a list of shapes and returns a
0304      * united rect.
0305      */
0306     static QRectF absoluteOutlineRect(const QList<KoShape*> &shapes);
0307 
0308     /**
0309      * Return the side text should flow around this shape. This implements the ODF style:wrap
0310      * attribute that specifies how text is displayed around a frame or graphic object.
0311      */
0312     TextRunAroundSide textRunAroundSide() const;
0313 
0314     /**
0315      * Set the side text should flow around this shape.
0316      * @param side the requested side
0317      * @param runThrough run through the foreground or background or...
0318      */
0319     void setTextRunAroundSide(TextRunAroundSide side, RunThroughLevel runThrough = Background);
0320 
0321     /**
0322      * The space between this shape's left edge and text that runs around this shape.
0323      * @return the space around this shape to keep free from text
0324      */
0325     qreal textRunAroundDistanceLeft() const;
0326 
0327     /**
0328      * Set the space between this shape's left edge and the text that run around this shape.
0329      * @param distance the space around this shape to keep free from text
0330      */
0331     void setTextRunAroundDistanceLeft(qreal distance);
0332 
0333     /**
0334      * The space between this shape's top edge and text that runs around this shape.
0335      * @return the space around this shape to keep free from text
0336      */
0337     qreal textRunAroundDistanceTop() const;
0338 
0339     /**
0340      * Set the space between this shape's top edge and the text that run around this shape.
0341      * @param distance the space around this shape to keep free from text
0342      */
0343     void setTextRunAroundDistanceTop(qreal distance);
0344 
0345     /**
0346      * The space between this shape's right edge and text that runs around this shape.
0347      * @return the space around this shape to keep free from text
0348      */
0349     qreal textRunAroundDistanceRight() const;
0350 
0351     /**
0352      * Set the space between this shape's right edge and the text that run around this shape.
0353      * @param distance the space around this shape to keep free from text
0354      */
0355     void setTextRunAroundDistanceRight(qreal distance);
0356 
0357     /**
0358      * The space between this shape's bottom edge and text that runs around this shape.
0359      * @return the space around this shape to keep free from text
0360      */
0361     qreal textRunAroundDistanceBottom() const;
0362 
0363     /**
0364      * Set the space between this shape's bottom edge and the text that run around this shape.
0365      * @param distance the space around this shape to keep free from text
0366      */
0367     void setTextRunAroundDistanceBottom(qreal distance);
0368 
0369     /**
0370      * Return the threshold above which text should flow around this shape.
0371      * The text will not flow around the shape on a side unless the space available on that side
0372      * is above this threshold. Only used when the text run around side is EnoughRunAroundSide.
0373      * @return threshold the threshold
0374      */
0375     qreal textRunAroundThreshold() const;
0376 
0377     /**
0378      * Set the threshold above which text should flow around this shape.
0379      * The text will not flow around the shape on a side unless the space available on that side
0380      * is above this threshold. Only used when the text run around side is EnoughRunAroundSide.
0381      * @param threshold the new threshold
0382      */
0383     void setTextRunAroundThreshold(qreal threshold);
0384 
0385     /**
0386      * Return the how tight text run around is done around this shape.
0387      * @return the contour
0388      */
0389     TextRunAroundContour textRunAroundContour() const;
0390 
0391     /**
0392      * Set how tight text run around is done around this shape.
0393      * @param contour the new contour
0394      */
0395     void setTextRunAroundContour(TextRunAroundContour contour);
0396 
0397     /**
0398      * Set the KoShapeAnchor
0399      */
0400     void setAnchor(KoShapeAnchor *anchor);
0401 
0402     /**
0403      * Return the KoShapeAnchor, or 0
0404      */
0405     KoShapeAnchor *anchor() const;
0406 
0407     /**
0408      * Set the minimum height of the shape.
0409      * Currently it's not respected but only for informational purpose
0410      * @param height the minimum height of the frame.
0411      */
0412     void setMinimumHeight(qreal height);
0413 
0414     /**
0415      * Return the minimum height of the shape.
0416      * @return the minimum height of the shape. Default is 0.0.
0417      */
0418     qreal minimumHeight() const;
0419 
0420 
0421     /**
0422      * Set the background of the shape.
0423      * A shape background can be a plain color, a gradient, a pattern, be fully transparent
0424      * or have a complex fill.
0425      * Setting such a background will allow the shape to be filled and will be able to tell
0426      * if it is transparent or not.
0427      *
0428      * If the shape inherited the background from its parent, its stops inheriting it, that
0429      * is inheritBackground property resets to false.
0430      *
0431      * @param background the new shape background.
0432      */
0433     virtual void setBackground(QSharedPointer<KoShapeBackground> background);
0434 
0435     /**
0436      * return the brush used to paint te background of this shape with.
0437      * A QBrush can have a plain color, be fully transparent or have a complex fill.
0438      * setting such a brush will allow the shape to fill itself using that brush and
0439      * will be able to tell if its transparent or not.
0440      * @return the background-brush
0441      */
0442     virtual QSharedPointer<KoShapeBackground> background() const;
0443 
0444     /**
0445      * @brief setInheritBackground marks a shape as inheriting the background
0446      * from the parent shape. NOTE: The currently selected background is destroyed.
0447      * @param value true if the shape should inherit the filling background
0448      */
0449     void setInheritBackground(bool value);
0450 
0451     /**
0452      * @brief inheritBackground shows if the shape inherits background from its parent
0453      * @return true if the shape inherits the fill
0454      */
0455     bool inheritBackground() const;
0456 
0457     /**
0458      * Returns true if there is some transparency, false if the shape is fully opaque.
0459      * The default implementation will just return if the background has some transparency,
0460      * you should override it and always return true if your shape is not square.
0461      * @return if the shape is (partly) transparent.
0462      */
0463     virtual bool hasTransparency() const;
0464 
0465     /**
0466      * Sets shape level transparency.
0467      * @param transparency the new shape level transparency
0468      */
0469     void setTransparency(qreal transparency);
0470 
0471     /**
0472      * Returns the shape level transparency.
0473      * @param recursive when true takes the parents transparency into account
0474      */
0475     qreal transparency(bool recursive=false) const;
0476 
0477     /**
0478      * Retrieve the z-coordinate of this shape.
0479      * The zIndex property is used to determine which shape lies on top of other objects.
0480      * An shape with a higher z-order is on top, and can obscure another shape.
0481      * @return the z-index of this shape.
0482      * @see setZIndex()
0483      */
0484     qint16 zIndex() const;
0485 
0486     /**
0487      * Set the z-coordinate of this shape.
0488      * The zIndex property is used to determine which shape lies on top of other objects.
0489      * An shape with a higher z-order is on top, and can obscure, another shape.
0490      * <p>Just like two objects having the same x or y coordinate will make them 'touch',
0491      * so will two objects with the same z-index touch on the z plane.  In layering the
0492      * shape this, however, can cause a little confusion as one always has to be on top.
0493      * The layering if two overlapping objects have the same index is implementation dependent
0494      * and probably depends on the order in which they are added to the shape manager.
0495      * @param zIndex the new z-index;
0496      */
0497     void setZIndex(qint16 zIndex);
0498 
0499     /**
0500      * Maximum value of z-index
0501      */
0502     static const qint16 maxZIndex;
0503 
0504     /**
0505      * Minimum value of z-index
0506      */
0507     static const qint16 minZIndex;
0508 
0509     /**
0510      * Retrieve the run through property of this shape.
0511      * The run through property is used to determine if the shape is behind, inside or before text.
0512      * @return the run through of this shape.
0513      */
0514     int runThrough() const;
0515 
0516     /**
0517      * Set the run through property of this shape.
0518      * The run through property is used to determine if the shape is behind, inside or before text.
0519      * @param runThrough the new run through;
0520      */
0521     virtual void setRunThrough(short int runThrough);
0522 
0523     /**
0524      * Changes the Shape to be visible or invisible.
0525      * Being visible means being painted, as well as being used for
0526      *   things like guidelines or searches.
0527      * @param on when true; set the shape to be visible.
0528      * @see setGeometryProtected(), setContentProtected(), setSelectable()
0529      */
0530     void setVisible(bool on);
0531     /**
0532      * Returns current visibility state of this shape.
0533      * Being visible means being painted, as well as being used for
0534      *   things like guidelines or searches.
0535      * @param recursive when true, checks visibility recursively
0536      * @return current visibility state of this shape.
0537      * @see isGeometryProtected(), isContentProtected(), isSelectable()
0538      */
0539     bool isVisible(bool recursive = true) const;
0540 
0541     /**
0542      * Changes the shape to be printable or not. The default is true.
0543      *
0544      * If a Shape's print flag is true, the shape will be printed. If
0545      * false, the shape will not be printed. If a shape is not visible (@see isVisible),
0546      * it isPrinted will return false, too.
0547      */
0548     void setPrintable(bool on);
0549 
0550     /**
0551      * Returns the current printable state of this shape.
0552      *
0553      * A shape can be visible but not printable, not printable and not visible
0554      * or visible and printable, but not invisible and still printable.
0555      *
0556      * @return current printable state of this shape.
0557      */
0558     bool isPrintable() const;
0559 
0560     /**
0561      * Makes it possible for the user to select this shape.
0562      * This parameter defaults to true.
0563      * @param selectable when true; set the shape to be selectable by the user.
0564      * @see setGeometryProtected(), setContentProtected(), setVisible()
0565      */
0566     void setSelectable(bool selectable);
0567 
0568     /**
0569      * Returns if this shape can be selected by the user.
0570      * @return true only when the object is selectable.
0571      * @see isGeometryProtected(), isContentProtected(), isVisible()
0572      */
0573     bool isSelectable() const;
0574 
0575     /**
0576      * Tells the shape to have its position/rotation and size protected from user-changes.
0577      * The geometry being protected means the user can not change shape or position of the
0578      * shape. This includes any matrix operation such as rotation.
0579      * @param on when true; set the shape to have its geometry protected.
0580      * @see setContentProtected(), setSelectable(), setVisible()
0581      */
0582     void setGeometryProtected(bool on);
0583 
0584     /**
0585      * Returns current geometry protection state of this shape.
0586      * The geometry being protected means the user can not change shape or position of the
0587      * shape. This includes any matrix operation such as rotation.
0588      * @return current geometry protection state of this shape.
0589      * @see isContentProtected(), isSelectable(), isVisible()
0590      */
0591     bool isGeometryProtected() const;
0592 
0593     /**
0594      * Marks the shape to have its content protected against editing.
0595      * Content protection is a hint for tools to disallow the user editing the content.
0596      * @param protect when true set the shapes content to be protected from user modification.
0597      * @see setGeometryProtected(), setSelectable(), setVisible()
0598      */
0599     void setContentProtected(bool protect);
0600 
0601     /**
0602      * Returns current content protection state of this shape.
0603      * Content protection is a hint for tools to disallow the user editing the content.
0604      * @return current content protection state of this shape.
0605      * @see isGeometryProtected(), isSelectable(), isVisible()
0606      */
0607     bool isContentProtected() const;
0608 
0609     /**
0610      * Returns the parent, or 0 if there is no parent.
0611      * @return the parent, or 0 if there is no parent.
0612      */
0613     KoShapeContainer *parent() const;
0614 
0615     /**
0616      * Set the parent of this shape.
0617      * @param parent the new parent of this shape. Can be 0 if the shape has no parent anymore.
0618      */
0619     void setParent(KoShapeContainer *parent);
0620 
0621 
0622     /**
0623      * @brief inheritsTransformFromAny checks if the shape inherits transformation from
0624      *        any of the shapes listed in \p ancestorsInQuestion. The inheritance is checked
0625      *        in recursive way.
0626      * @return true if there is a (transitive) transformation-wise parent found in \p ancestorsInQuestion
0627      */
0628     bool inheritsTransformFromAny(const QList<KoShape*> ancestorsInQuestion) const;
0629 
0630     /**
0631      * @return true if this shape has a common parent with \p shape
0632      */
0633     bool hasCommonParent(const KoShape *shape) const;
0634 
0635     /**
0636      * Request a repaint to be queued.
0637      * The repaint will be of the entire Shape, including its selection handles should this
0638      * shape be selected.
0639      * <p>This method will return immediately and only request a repaint. Successive calls
0640      * will be merged into an appropriate repaint action.
0641      */
0642     virtual void update() const;
0643 
0644     /**
0645      * Request a repaint to be queued.
0646      * The repaint will be restricted to the parameters rectangle, which is expected to be
0647      * in absolute coordinates of the canvas and it is expected to be
0648      * normalized.
0649      * <p>This method will return immediately and only request a repaint. Successive calls
0650      * will be merged into an appropriate repaint action.
0651      * @param rect the rectangle (in pt) to queue for repaint.
0652      */
0653     virtual void updateAbsolute(const QRectF &rect) const;
0654 
0655     /// Used by compareShapeZIndex() to order shapes
0656     enum ChildZOrderPolicy {
0657         ChildZDefault,
0658         ChildZParentChild = ChildZDefault, ///< normal parent/child ordering
0659         ChildZPassThrough ///< children are considered equal to this shape
0660     };
0661 
0662    /**
0663     * Returns if during compareShapeZIndex() how this shape portrays the values
0664     * of its children. The default behaviour is to let this shape's z values take
0665     * the place of its children's values, so you get a parent/child relationship.
0666     * The children are naturally still ordered relatively to their z values
0667     *
0668     * But for special cases (like Calligra's TextShape) it can be overloaded to return
0669     * ChildZPassThrough which means the children keep their own z values
0670     * @returns the z order policy of this shape
0671     */
0672     virtual ChildZOrderPolicy childZOrderPolicy();
0673 
0674     /**
0675      * This is a method used to sort a list using the STL sorting methods.
0676      * @param s1 the first shape
0677      * @param s2 the second shape
0678      */
0679     static bool compareShapeZIndex(KoShape *s1, KoShape *s2);
0680 
0681     /**
0682      * returns the outline of the shape in the form of a path.
0683      * The outline returned will always be relative to the position() of the shape, so
0684      * moving the shape will not alter the result.  The outline is used to draw the stroke
0685      * on, for example.
0686      * @returns the outline of the shape in the form of a path.
0687      */
0688     virtual QPainterPath outline() const;
0689 
0690     /**
0691      * returns the outline of the shape in the form of a rect.
0692      * The outlineRect returned will always be relative to the position() of the shape, so
0693      * moving the shape will not alter the result.  The outline is used to calculate
0694      * the boundingRect.
0695      * @returns the outline of the shape in the form of a rect.
0696      */
0697     virtual QRectF outlineRect() const;
0698 
0699     /**
0700      * returns the outline of the shape in the form of a path for the use of painting a shadow.
0701      *
0702      * Normally this would be the same as outline() if there is a fill (background) set on the
0703      * shape and empty if not.  However, a shape could reimplement this to return an outline
0704      * even if no fill is defined. A typical example of this would be the picture shape
0705      * which has a picture but almost never a background.
0706      *
0707      * @returns the outline of the shape in the form of a path.
0708      */
0709     virtual QPainterPath shadowOutline() const;
0710 
0711     /**
0712      * Returns the currently set stroke, or 0 if there is no stroke.
0713      * @return the currently set stroke, or 0 if there is no stroke.
0714      */
0715     virtual KoShapeStrokeModelSP stroke() const;
0716 
0717     /**
0718      * Set a new stroke, removing the old one. The stroke inheritance becomes disabled.
0719      * @param stroke the new stroke, or 0 if there should be no stroke.
0720      */
0721     virtual void setStroke(KoShapeStrokeModelSP stroke);
0722 
0723     /**
0724      * @brief setInheritStroke marks a shape as inheriting the stroke
0725      * from the parent shape. NOTE: The currently selected stroke is destroyed.
0726      * @param value true if the shape should inherit the stroke style
0727      */
0728     void setInheritStroke(bool value);
0729 
0730     /**
0731      * @brief inheritStroke shows if the shape inherits the stroke from its parent
0732      * @return true if the shape inherits the stroke style
0733      */
0734     bool inheritStroke() const;
0735 
0736     /**
0737      * Return the insets of the stroke.
0738      * Convenience method for KoShapeStrokeModel::strokeInsets()
0739      */
0740     KoInsets strokeInsets() const;
0741 
0742     /**
0743      * @brief setPaintOrder
0744      * set the paint order. As there's only three entries in any given paintorder,
0745      * you only need to have the first
0746      * and second entry to set it.
0747      * @param first first thing to paint
0748      * @param second second thing to paint.
0749      */
0750     virtual void setPaintOrder(PaintOrder first, PaintOrder second);
0751 
0752     /**
0753      * @brief paintOrder
0754      * @return vector of paint orders, will always be 3 big and contain a fill, stroke and marker entry.
0755      */
0756     virtual QVector<PaintOrder> paintOrder() const;
0757 
0758     /**
0759      * @brief setInheritPaintOrder
0760      * set inherit paint order.
0761      * @param value
0762      */
0763     void setInheritPaintOrder(bool value);
0764 
0765     /**
0766      * @brief inheritPaintOrder
0767      * @return whether the paint order is inherited. By default it is.
0768      */
0769     bool inheritPaintOrder() const;
0770 
0771     /// Sets the new shadow, removing the old one
0772     void setShadow(KoShapeShadow *shadow);
0773 
0774     /// Returns the currently set shadow or 0 if there is no shadow set
0775     KoShapeShadow *shadow() const;
0776 
0777     /// Sets a new clip path, removing the old one
0778     void setClipPath(KoClipPath *clipPath);
0779 
0780     /// Returns the currently set clip path or 0 if there is no clip path set
0781     KoClipPath * clipPath() const;
0782 
0783     /// Sets a new clip mask, removing the old one. The mask is owned by the shape.
0784     void setClipMask(KoClipMask *clipMask);
0785 
0786     /// Returns the currently set clip mask or 0 if there is no clip mask set
0787     KoClipMask* clipMask() const;
0788 
0789     /**
0790      * Setting the shape to keep its aspect-ratio has the effect that user-scaling will
0791      * keep the width/height ratio intact so as not to distort shapes that rely on that
0792      * ratio.
0793      * @param keepAspect the new value
0794      */
0795     void setKeepAspectRatio(bool keepAspect);
0796 
0797     /**
0798      * Setting the shape to keep its aspect-ratio has the effect that user-scaling will
0799      * keep the width/height ratio intact so as not to distort shapes that rely on that
0800      * ratio.
0801      * @return whether to keep aspect ratio of this shape
0802      */
0803     bool keepAspectRatio() const;
0804 
0805     /**
0806      * Return the position of this shape regardless of rotation/skew/scaling and regardless of
0807      * this shape having a parent (being in a group) or not.<br>
0808      * @param anchor The place on the (unaltered) shape that you want the position of.
0809      * @return the point that is the absolute, centered position of this shape.
0810      */
0811     QPointF absolutePosition(KoFlake::AnchorPosition anchor = KoFlake::Center) const;
0812 
0813     /**
0814      * Move this shape to an absolute position where the end location will be the same
0815      * regardless of the shape's rotation/skew/scaling and regardless of this shape having
0816      * a parent (being in a group) or not.<br>
0817      * The newPosition is going to be the center of the shape.
0818      * This has the convenient effect that: <pre>
0819     shape-&gt;setAbsolutePosition(QPointF(0,0));
0820     shape-&gt;rotate(45);</pre>
0821         Will result in the same visual position of the shape as the opposite:<pre>
0822     shape-&gt;rotate(45);
0823     shape-&gt;setAbsolutePosition(QPointF(0,0));</pre>
0824      * @param newPosition the new absolute center of the shape.
0825      * @param anchor The place on the (unaltered) shape that you set the position of.
0826      */
0827     void setAbsolutePosition(const QPointF &newPosition, KoFlake::AnchorPosition anchor = KoFlake::Center);
0828 
0829     /**
0830      * Set a data object on the shape to be used by an application.
0831      * This is specifically useful when a shape is created in a plugin and that data from that
0832      * shape should be accessible outside the plugin.
0833      * @param userData the new user data, or 0 to delete the current one.
0834      */
0835     void setUserData(KoShapeUserData *userData);
0836     /**
0837      * Return the current userData.
0838      */
0839     KoShapeUserData *userData() const;
0840 
0841     /**
0842      * Return the Id of this shape, identifying the type of shape by the id of the factory.
0843      * @see KoShapeFactoryBase::shapeId()
0844      * @return the id of the shape-type
0845      */
0846     QString shapeId() const;
0847 
0848     /**
0849      * Set the Id of this shape.  A shapeFactory is expected to set the Id at creation
0850      * so applications can find out what kind of shape this is.
0851      * @see KoShapeFactoryBase::shapeId()
0852      * @param id the ID from the factory that created this shape
0853      */
0854     void setShapeId(const QString &id);
0855 
0856     /**
0857      * Create a matrix that describes all the transformations done on this shape.
0858      *
0859      * The absolute transformation is the combined transformation of this shape
0860      * and all its parents and grandparents.
0861      */
0862     QTransform absoluteTransformation() const;
0863 
0864     /**
0865      * Applies a transformation to this shape.
0866      *
0867      * The transformation given is relative to the global coordinate system, i.e. the document.
0868      * This is a convenience function to apply a global transformation to this shape.
0869      * @see applyTransformation
0870      *
0871      * @param matrix the transformation matrix to apply
0872      */
0873     void applyAbsoluteTransformation(const QTransform &matrix);
0874 
0875     /**
0876      * Sets a new transformation matrix describing the local transformations on this shape.
0877      * @param matrix the new transformation matrix
0878      */
0879     void setTransformation(const QTransform &matrix);
0880 
0881     /// Returns the shapes local transformation matrix
0882     QTransform transformation() const;
0883 
0884     /**
0885      * Applies a transformation to this shape.
0886      *
0887      * The transformation given is relative to the shape coordinate system.
0888      *
0889      * @param matrix the transformation matrix to apply
0890      */
0891     void applyTransformation(const QTransform &matrix);
0892 
0893     /**
0894      * Copy all the settings from the parameter shape and apply them to this shape.
0895      * Settings like the position and rotation to visible and locked.  The parent
0896      * is a notable exclusion.
0897      * @param shape the shape to use as original
0898      */
0899     void copySettings(const KoShape *shape);
0900 
0901     /**
0902      * A convenience method that creates a handles helper with applying transformations at
0903      * the same time. Please note that you shouldn't save/restore additionally. All the work
0904      * on restoring original painter's transformations is done by the helper.
0905      */
0906     static KisHandlePainterHelper createHandlePainterHelperView(QPainter *painter, KoShape *shape, const KoViewConverter &converter, qreal handleRadius = 0.0, int decorationThickness = 1);
0907     static KisHandlePainterHelper createHandlePainterHelperDocument(QPainter *painter, KoShape *shape, qreal handleRadius, int decorationThickness);
0908 
0909     /**
0910      * @brief Transforms point from shape coordinates to document coordinates
0911      * @param point in shape coordinates
0912      * @return point in document coordinates
0913      */
0914     QPointF shapeToDocument(const QPointF &point) const;
0915 
0916     /**
0917      * @brief Transforms rect from shape coordinates to document coordinates
0918      * @param rect in shape coordinates
0919      * @return rect in document coordinates
0920      */
0921     QRectF shapeToDocument(const QRectF &rect) const;
0922 
0923     /**
0924      * @brief Transforms point from document coordinates to shape coordinates
0925      * @param point in document coordinates
0926      * @return point in shape coordinates
0927      */
0928     QPointF documentToShape(const QPointF &point) const;
0929 
0930     /**
0931      * @brief Transform rect from document coordinates to shape coordinates
0932      * @param rect in document coordinates
0933      * @return rect in shape coordinates
0934      */
0935     QRectF documentToShape(const QRectF &rect) const;
0936 
0937     /**
0938      * Returns the name of the shape.
0939      * @return the shapes name
0940      */
0941     QString name() const;
0942 
0943     /**
0944      * Sets the name of the shape.
0945      * @param name the new shape name
0946      */
0947     void setName(const QString &name);
0948 
0949     /**
0950      * Update the position of the shape in the tree of the KoShapeManager.
0951      */
0952     void notifyChanged();
0953 
0954     /**
0955      * A shape can be in a state that it is doing processing data like loading or text layout.
0956      * In this case it can be shown on screen probably partially but it should really not be printed
0957      * until it is fully done processing.
0958      * Warning! This method can be blocking for a long time
0959      * @param asynchronous If set to true the processing will can take place in a different thread and the
0960      *                     function will not block until the shape is finished.
0961      *                     In case of printing Flake will call this method from a non-main thread and only
0962      *                     start printing it when the in case of printing method returned.
0963      *                     If set to false the processing needs to be done synchronously and will
0964      *                     block until the result is finished.
0965      */
0966     virtual void waitUntilReady(bool asynchronous = true) const;
0967 
0968     /// checks recursively if the shape or one of its parents is not visible or locked
0969     virtual bool isShapeEditable(bool recursive = true) const;
0970 
0971     /**
0972      * Adds a shape which depends on this shape.
0973      * Making a shape dependent on this one means it will get shapeChanged() called
0974      * on each update of this shape.
0975      *
0976      * If this shape already depends on the given shape, establishing the
0977      * dependency is refused to prevent circular dependencies.
0978      *
0979      * @param shape the shape which depends on this shape
0980      * @return true if dependency could be established, otherwise false
0981      * @see removeDependee(), hasDependee()
0982      */
0983     bool addDependee(KoShape *shape);
0984 
0985     /**
0986      * Removes as shape depending on this shape.
0987      * @see addDependee(), hasDependee()
0988      */
0989     void removeDependee(KoShape *shape);
0990 
0991     /// Returns if the given shape is dependent on this shape
0992     bool hasDependee(KoShape *shape) const;
0993 
0994     /// Returns list of shapes depending on this shape
0995     QList<KoShape*> dependees() const;
0996 
0997     /// Returns additional snap data the shape wants to have snapping to
0998     virtual KoSnapData snapData() const;
0999 
1000     /**
1001      * Set additional attribute
1002      *
1003      * This can be used to attach additional attributes to a shape for attributes
1004      * that are application specific like presentation:placeholder
1005      *
1006      * @param name The name of the attribute in the following form prefix:tag e.g. presentation:placeholder
1007      * @param value The value of the attribute
1008      */
1009     void setAdditionalAttribute(const QString &name, const QString &value);
1010 
1011     /**
1012      * Remove additional attribute
1013      *
1014      * @param name The name of the attribute in the following form prefix:tag e.g. presentation:placeholder
1015      */
1016     void removeAdditionalAttribute(const QString &name);
1017 
1018     /**
1019      * Check if additional attribute is set
1020      *
1021      * @param name The name of the attribute in the following form prefix:tag e.g. presentation:placeholder
1022      *
1023      * @return true if there is a attribute with prefix:tag set, false otherwise
1024      */
1025     bool hasAdditionalAttribute(const QString &name) const;
1026 
1027     /**
1028      * Get additional attribute
1029      *
1030      * @param name The name of the attribute in the following form prefix:tag e.g. presentation:placeholder
1031      *
1032      * @return The value of the attribute if it exists or a null string if not found.
1033      */
1034     QString additionalAttribute(const QString &name) const;
1035 
1036     void setAdditionalStyleAttribute(const char *name, const QString &value);
1037 
1038     void removeAdditionalStyleAttribute(const char *name);
1039 
1040     /**
1041      * Returns the filter effect stack of the shape
1042      *
1043      * @return the list of filter effects applied on the shape when rendering.
1044      */
1045     KoFilterEffectStack *filterEffectStack() const;
1046 
1047     /// Sets the new filter effect stack, removing the old one
1048     void setFilterEffectStack(KoFilterEffectStack *filterEffectStack);
1049 
1050     /**
1051      * Return the tool delegates for this shape.
1052      * In Flake a shape being selected will cause the tool manager to make available all tools that
1053      * can edit the selected shapes.  In some cases selecting one shape should allow the tool to
1054      * edit a related shape be available too.  The tool delegates allows this to happen by taking
1055      * all the shapes in the set into account on tool selection.
1056      * Notice that if the set is non-empty 'this' shape is no longer looked at. You can choose
1057      * to add itself to the set too.
1058      */
1059     QSet<KoShape*> toolDelegates() const;
1060 
1061     /**
1062      * Set the tool delegates.
1063      * @param delegates the new delegates.
1064      * @see toolDelegates()
1065      */
1066     void setToolDelegates(const QSet<KoShape*> &delegates);
1067 
1068     /**
1069      * Return the hyperlink for this shape.
1070      */
1071     QString hyperLink () const;
1072 
1073     /**
1074      * Set hyperlink for this shape.
1075      * @param hyperLink name.
1076      */
1077     void setHyperLink(const QString &hyperLink);
1078 
1079     /**
1080      * Update the image resolution in pixels per inch. Shapes should override
1081      * this if they need to know the image resolution.
1082      *
1083      * @param xRes
1084      * @param yRes
1085      */
1086     virtual void setResolution(qreal xRes, qreal yRes);
1087 
1088 public:
1089 
1090     struct KRITAFLAKE_EXPORT ShapeChangeListener {
1091         virtual ~ShapeChangeListener();
1092         virtual void notifyShapeChanged(ChangeType type, KoShape *shape) = 0;
1093 
1094     private:
1095         friend class KoShape;
1096         void registerShape(KoShape *shape);
1097         void unregisterShape(KoShape *shape);
1098         void notifyShapeChangedImpl(ChangeType type, KoShape *shape);
1099 
1100         QList<KoShape*> m_registeredShapes;
1101     };
1102 
1103     void addShapeChangeListener(ShapeChangeListener *listener);
1104     void removeShapeChangeListener(ShapeChangeListener *listener);
1105 
1106 protected:
1107     QList<ShapeChangeListener *> listeners() const;
1108     void setSizeImpl(const QSizeF &size) const;
1109 
1110 public:
1111     static QList<KoShape*> linearizeSubtree(const QList<KoShape*> &shapes);
1112     static QList<KoShape *> linearizeSubtreeSorted(const QList<KoShape *> &shapes);
1113 protected:
1114     KoShape(const KoShape &rhs);
1115 
1116      /**
1117      * A hook that allows inheriting classes to do something after a KoShape property changed
1118      * This is called whenever the shape, position rotation or scale properties were altered.
1119      * @param type an indicator which type was changed.
1120      * @param shape the shape.
1121      */
1122     virtual void shapeChanged(ChangeType type, KoShape *shape = 0);
1123 
1124     /// return the current matrix that contains the rotation/scale/position of this shape
1125     QTransform transform() const;
1126 
1127 private:
1128     class Private;
1129     QScopedPointer<Private> d;
1130 
1131     class SharedData;
1132     QSharedDataPointer<SharedData> s;
1133 
1134 
1135 protected:
1136     /**
1137      * Notify the shape that a change was done. To be used by inheriting shapes.
1138      * @param type the change type
1139      */
1140     void shapeChangedPriv(KoShape::ChangeType type);
1141 
1142 private:
1143     void addShapeManager(KoShapeManager *manager);
1144     void removeShapeManager(KoShapeManager *manager);
1145     friend class KoShapeManager;
1146 };
1147 
1148 Q_DECLARE_METATYPE(KoShape*)
1149 Q_DECLARE_METATYPE(QVector<KoShape::PaintOrder>)
1150 
1151 #endif