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->setAbsolutePosition(QPointF(0,0)); 0820 shape->rotate(45);</pre> 0821 Will result in the same visual position of the shape as the opposite:<pre> 0822 shape->rotate(45); 0823 shape->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