File indexing completed on 2024-05-12 15:56:46
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 /** 0146 * @brief Constructor 0147 */ 0148 KoShape(); 0149 0150 /** 0151 * @brief Destructor 0152 */ 0153 virtual ~KoShape(); 0154 0155 /** 0156 * @brief creates a deep copy of the shape or shape's subtree 0157 * @return a cloned shape 0158 */ 0159 virtual KoShape* cloneShape() const; 0160 0161 /** 0162 * @brief Paint the shape fill 0163 * The class extending this one is responsible for painting itself. \p painter is expected 0164 * to be preconfigured to work in "document" pixels. 0165 * 0166 * @param painter used for painting the shape 0167 */ 0168 virtual void paint(QPainter &painter) const = 0; 0169 0170 /** 0171 * @brief paintStroke paints the shape's stroked outline 0172 * @param painter used for painting the shape 0173 * @see applyConversion() 0174 */ 0175 virtual void paintStroke(QPainter &painter) const; 0176 0177 /** 0178 * @brief Scale the shape using the zero-point which is the top-left corner. 0179 * @see position() 0180 * 0181 * @param sx scale in x direction 0182 * @param sy scale in y direction 0183 */ 0184 void scale(qreal sx, qreal sy); 0185 0186 /** 0187 * @brief Rotate the shape (relative) 0188 * 0189 * The shape will be rotated from the current rotation using the center of the shape using the size() 0190 * 0191 * @param angle change the angle of rotation increasing it with 'angle' degrees 0192 */ 0193 void rotate(qreal angle); 0194 0195 /** 0196 * Return the current rotation in degrees. 0197 * It returns NaN if the shape has a shearing or scaling transformation applied. 0198 */ 0199 qreal rotation() const; 0200 0201 /** 0202 * @brief Shear the shape 0203 * The shape will be sheared using the zero-point which is the top-left corner. 0204 * @see position() 0205 * 0206 * @param sx shear in x direction 0207 * @param sy shear in y direction 0208 */ 0209 void shear(qreal sx, qreal sy); 0210 0211 /** 0212 * @brief Resize the shape 0213 * 0214 * @param size the new size of the shape. This is different from scaling as 0215 * scaling is a so called secondary operation which is comparable to zooming in 0216 * instead of changing the size of the basic shape. 0217 * Easiest example of this difference is that using this method will not distort the 0218 * size of pattern-fills and strokes. 0219 */ 0220 virtual void setSize(const QSizeF &size); 0221 0222 /** 0223 * @brief Get the size of the shape in pt. 0224 * 0225 * The size is in shape coordinates. 0226 * 0227 * @return the size of the shape as set by setSize() 0228 */ 0229 virtual QSizeF size() const; 0230 0231 /** 0232 * @brief Set the position of the shape in pt 0233 * 0234 * @param position the new position of the shape 0235 */ 0236 virtual void setPosition(const QPointF &position); 0237 0238 /** 0239 * @brief Get the position of the shape in pt 0240 * 0241 * @return the position of the shape 0242 */ 0243 QPointF position() const; 0244 0245 /** 0246 * @brief Check if the shape is hit on position 0247 * @param position the position where the user clicked. 0248 * @return true when it hits. 0249 */ 0250 virtual bool hitTest(const QPointF &position) const; 0251 0252 /** 0253 * @brief Get the bounding box of the shape 0254 * 0255 * This includes the line width and the shadow of the shape 0256 * 0257 * @return the bounding box of the shape 0258 */ 0259 virtual QRectF boundingRect() const; 0260 0261 /** 0262 * Get the united bounding box of a group of shapes. This is a utility 0263 * function used in many places in Krita. 0264 */ 0265 static QRectF boundingRect(const QList<KoShape*> &shapes); 0266 0267 /** 0268 * @return the bounding rect of the outline of the shape measured 0269 * in absolute coordinate system. Please note that in contrast to 0270 * boundingRect() this rect doesn't include the stroke and other 0271 * insets. 0272 */ 0273 QRectF absoluteOutlineRect() const; 0274 0275 /** 0276 * Same as a member function, but applies to a list of shapes and returns a 0277 * united rect. 0278 */ 0279 static QRectF absoluteOutlineRect(const QList<KoShape*> &shapes); 0280 0281 /** 0282 * Return the side text should flow around this shape. This implements the ODF style:wrap 0283 * attribute that specifies how text is displayed around a frame or graphic object. 0284 */ 0285 TextRunAroundSide textRunAroundSide() const; 0286 0287 /** 0288 * Set the side text should flow around this shape. 0289 * @param side the requested side 0290 * @param runThrough run through the foreground or background or... 0291 */ 0292 void setTextRunAroundSide(TextRunAroundSide side, RunThroughLevel runThrough = Background); 0293 0294 /** 0295 * The space between this shape's left edge and text that runs around this shape. 0296 * @return the space around this shape to keep free from text 0297 */ 0298 qreal textRunAroundDistanceLeft() const; 0299 0300 /** 0301 * Set the space between this shape's left edge and the text that run around this shape. 0302 * @param distance the space around this shape to keep free from text 0303 */ 0304 void setTextRunAroundDistanceLeft(qreal distance); 0305 0306 /** 0307 * The space between this shape's top edge and text that runs around this shape. 0308 * @return the space around this shape to keep free from text 0309 */ 0310 qreal textRunAroundDistanceTop() const; 0311 0312 /** 0313 * Set the space between this shape's top edge and the text that run around this shape. 0314 * @param distance the space around this shape to keep free from text 0315 */ 0316 void setTextRunAroundDistanceTop(qreal distance); 0317 0318 /** 0319 * The space between this shape's right edge and text that runs around this shape. 0320 * @return the space around this shape to keep free from text 0321 */ 0322 qreal textRunAroundDistanceRight() const; 0323 0324 /** 0325 * Set the space between this shape's right edge and the text that run around this shape. 0326 * @param distance the space around this shape to keep free from text 0327 */ 0328 void setTextRunAroundDistanceRight(qreal distance); 0329 0330 /** 0331 * The space between this shape's bottom edge and text that runs around this shape. 0332 * @return the space around this shape to keep free from text 0333 */ 0334 qreal textRunAroundDistanceBottom() const; 0335 0336 /** 0337 * Set the space between this shape's bottom edge and the text that run around this shape. 0338 * @param distance the space around this shape to keep free from text 0339 */ 0340 void setTextRunAroundDistanceBottom(qreal distance); 0341 0342 /** 0343 * Return the threshold above which text should flow around this shape. 0344 * The text will not flow around the shape on a side unless the space available on that side 0345 * is above this threshold. Only used when the text run around side is EnoughRunAroundSide. 0346 * @return threshold the threshold 0347 */ 0348 qreal textRunAroundThreshold() const; 0349 0350 /** 0351 * Set the threshold above which text should flow around this shape. 0352 * The text will not flow around the shape on a side unless the space available on that side 0353 * is above this threshold. Only used when the text run around side is EnoughRunAroundSide. 0354 * @param threshold the new threshold 0355 */ 0356 void setTextRunAroundThreshold(qreal threshold); 0357 0358 /** 0359 * Return the how tight text run around is done around this shape. 0360 * @return the contour 0361 */ 0362 TextRunAroundContour textRunAroundContour() const; 0363 0364 /** 0365 * Set how tight text run around is done around this shape. 0366 * @param contour the new contour 0367 */ 0368 void setTextRunAroundContour(TextRunAroundContour contour); 0369 0370 /** 0371 * Set the KoShapeAnchor 0372 */ 0373 void setAnchor(KoShapeAnchor *anchor); 0374 0375 /** 0376 * Return the KoShapeAnchor, or 0 0377 */ 0378 KoShapeAnchor *anchor() const; 0379 0380 /** 0381 * Set the minimum height of the shape. 0382 * Currently it's not respected but only for informational purpose 0383 * @param height the minimum height of the frame. 0384 */ 0385 void setMinimumHeight(qreal height); 0386 0387 /** 0388 * Return the minimum height of the shape. 0389 * @return the minimum height of the shape. Default is 0.0. 0390 */ 0391 qreal minimumHeight() const; 0392 0393 0394 /** 0395 * Set the background of the shape. 0396 * A shape background can be a plain color, a gradient, a pattern, be fully transparent 0397 * or have a complex fill. 0398 * Setting such a background will allow the shape to be filled and will be able to tell 0399 * if it is transparent or not. 0400 * 0401 * If the shape inherited the background from its parent, its stops inheriting it, that 0402 * is inheritBackground property resets to false. 0403 * 0404 * @param background the new shape background. 0405 */ 0406 void setBackground(QSharedPointer<KoShapeBackground> background); 0407 0408 /** 0409 * return the brush used to paint te background of this shape with. 0410 * A QBrush can have a plain color, be fully transparent or have a complex fill. 0411 * setting such a brush will allow the shape to fill itself using that brush and 0412 * will be able to tell if its transparent or not. 0413 * @return the background-brush 0414 */ 0415 QSharedPointer<KoShapeBackground> background() const; 0416 0417 /** 0418 * @brief setInheritBackground marks a shape as inhiriting the background 0419 * from the parent shape. NOTE: The currently selected background is destroyed. 0420 * @param value true if the shape should inherit the filling background 0421 */ 0422 void setInheritBackground(bool value); 0423 0424 /** 0425 * @brief inheritBackground shows if the shape inherits background from its parent 0426 * @return true if the shape inherits the fill 0427 */ 0428 bool inheritBackground() const; 0429 0430 /** 0431 * Returns true if there is some transparency, false if the shape is fully opaque. 0432 * The default implementation will just return if the background has some transparency, 0433 * you should override it and always return true if your shape is not square. 0434 * @return if the shape is (partly) transparent. 0435 */ 0436 virtual bool hasTransparency() const; 0437 0438 /** 0439 * Sets shape level transparency. 0440 * @param transparency the new shape level transparency 0441 */ 0442 void setTransparency(qreal transparency); 0443 0444 /** 0445 * Returns the shape level transparency. 0446 * @param recursive when true takes the parents transparency into account 0447 */ 0448 qreal transparency(bool recursive=false) const; 0449 0450 /** 0451 * Retrieve the z-coordinate of this shape. 0452 * The zIndex property is used to determine which shape lies on top of other objects. 0453 * An shape with a higher z-order is on top, and can obscure another shape. 0454 * @return the z-index of this shape. 0455 * @see setZIndex() 0456 */ 0457 qint16 zIndex() const; 0458 0459 /** 0460 * Set the z-coordinate of this shape. 0461 * The zIndex property is used to determine which shape lies on top of other objects. 0462 * An shape with a higher z-order is on top, and can obscure, another shape. 0463 * <p>Just like two objects having the same x or y coordinate will make them 'touch', 0464 * so will two objects with the same z-index touch on the z plane. In layering the 0465 * shape this, however, can cause a little confusion as one always has to be on top. 0466 * The layering if two overlapping objects have the same index is implementation dependent 0467 * and probably depends on the order in which they are added to the shape manager. 0468 * @param zIndex the new z-index; 0469 */ 0470 void setZIndex(qint16 zIndex); 0471 0472 /** 0473 * Maximum value of z-index 0474 */ 0475 static const qint16 maxZIndex; 0476 0477 /** 0478 * Minimum value of z-index 0479 */ 0480 static const qint16 minZIndex; 0481 0482 /** 0483 * Retrieve the run through property of this shape. 0484 * The run through property is used to determine if the shape is behind, inside or before text. 0485 * @return the run through of this shape. 0486 */ 0487 int runThrough() const; 0488 0489 /** 0490 * Set the run through property of this shape. 0491 * The run through property is used to determine if the shape is behind, inside or before text. 0492 * @param runThrough the new run through; 0493 */ 0494 virtual void setRunThrough(short int runThrough); 0495 0496 /** 0497 * Changes the Shape to be visible or invisible. 0498 * Being visible means being painted, as well as being used for 0499 * things like guidelines or searches. 0500 * @param on when true; set the shape to be visible. 0501 * @see setGeometryProtected(), setContentProtected(), setSelectable() 0502 */ 0503 void setVisible(bool on); 0504 /** 0505 * Returns current visibility state of this shape. 0506 * Being visible means being painted, as well as being used for 0507 * things like guidelines or searches. 0508 * @param recursive when true, checks visibility recursively 0509 * @return current visibility state of this shape. 0510 * @see isGeometryProtected(), isContentProtected(), isSelectable() 0511 */ 0512 bool isVisible(bool recursive = true) const; 0513 0514 /** 0515 * Changes the shape to be printable or not. The default is true. 0516 * 0517 * If a Shape's print flag is true, the shape will be printed. If 0518 * false, the shape will not be printed. If a shape is not visible (@see isVisible), 0519 * it isPrinted will return false, too. 0520 */ 0521 void setPrintable(bool on); 0522 0523 /** 0524 * Returns the current printable state of this shape. 0525 * 0526 * A shape can be visible but not printable, not printable and not visible 0527 * or visible and printable, but not invisible and still printable. 0528 * 0529 * @return current printable state of this shape. 0530 */ 0531 bool isPrintable() const; 0532 0533 /** 0534 * Makes it possible for the user to select this shape. 0535 * This parameter defaults to true. 0536 * @param selectable when true; set the shape to be selectable by the user. 0537 * @see setGeometryProtected(), setContentProtected(), setVisible() 0538 */ 0539 void setSelectable(bool selectable); 0540 0541 /** 0542 * Returns if this shape can be selected by the user. 0543 * @return true only when the object is selectable. 0544 * @see isGeometryProtected(), isContentProtected(), isVisible() 0545 */ 0546 bool isSelectable() const; 0547 0548 /** 0549 * Tells the shape to have its position/rotation and size protected from user-changes. 0550 * The geometry being protected means the user can not change shape or position of the 0551 * shape. This includes any matrix operation such as rotation. 0552 * @param on when true; set the shape to have its geometry protected. 0553 * @see setContentProtected(), setSelectable(), setVisible() 0554 */ 0555 void setGeometryProtected(bool on); 0556 0557 /** 0558 * Returns current geometry protection state of this shape. 0559 * The geometry being protected means the user can not change shape or position of the 0560 * shape. This includes any matrix operation such as rotation. 0561 * @return current geometry protection state of this shape. 0562 * @see isContentProtected(), isSelectable(), isVisible() 0563 */ 0564 bool isGeometryProtected() const; 0565 0566 /** 0567 * Marks the shape to have its content protected against editing. 0568 * Content protection is a hint for tools to disallow the user editing the content. 0569 * @param protect when true set the shapes content to be protected from user modification. 0570 * @see setGeometryProtected(), setSelectable(), setVisible() 0571 */ 0572 void setContentProtected(bool protect); 0573 0574 /** 0575 * Returns current content protection state of this shape. 0576 * Content protection is a hint for tools to disallow the user editing the content. 0577 * @return current content protection state of this shape. 0578 * @see isGeometryProtected(), isSelectable(), isVisible() 0579 */ 0580 bool isContentProtected() const; 0581 0582 /** 0583 * Returns the parent, or 0 if there is no parent. 0584 * @return the parent, or 0 if there is no parent. 0585 */ 0586 KoShapeContainer *parent() const; 0587 0588 /** 0589 * Set the parent of this shape. 0590 * @param parent the new parent of this shape. Can be 0 if the shape has no parent anymore. 0591 */ 0592 void setParent(KoShapeContainer *parent); 0593 0594 0595 /** 0596 * @brief inheritsTransformFromAny checks if the shape inherits transformation from 0597 * any of the shapes listed in \p ancestorsInQuestion. The inheritance is checked 0598 * in recursive way. 0599 * @return true if there is a (transitive) transformation-wise parent found in \p ancestorsInQuestion 0600 */ 0601 bool inheritsTransformFromAny(const QList<KoShape*> ancestorsInQuestion) const; 0602 0603 /** 0604 * @return true if this shape has a common parent with \p shape 0605 */ 0606 bool hasCommonParent(const KoShape *shape) const; 0607 0608 /** 0609 * Request a repaint to be queued. 0610 * The repaint will be of the entire Shape, including its selection handles should this 0611 * shape be selected. 0612 * <p>This method will return immediately and only request a repaint. Successive calls 0613 * will be merged into an appropriate repaint action. 0614 */ 0615 virtual void update() const; 0616 0617 /** 0618 * Request a repaint to be queued. 0619 * The repaint will be restricted to the parameters rectangle, which is expected to be 0620 * in absolute coordinates of the canvas and it is expected to be 0621 * normalized. 0622 * <p>This method will return immediately and only request a repaint. Successive calls 0623 * will be merged into an appropriate repaint action. 0624 * @param rect the rectangle (in pt) to queue for repaint. 0625 */ 0626 virtual void updateAbsolute(const QRectF &rect) const; 0627 0628 /// Used by compareShapeZIndex() to order shapes 0629 enum ChildZOrderPolicy { 0630 ChildZDefault, 0631 ChildZParentChild = ChildZDefault, ///< normal parent/child ordering 0632 ChildZPassThrough ///< children are considered equal to this shape 0633 }; 0634 0635 /** 0636 * Returns if during compareShapeZIndex() how this shape portrays the values 0637 * of its children. The default behaviour is to let this shape's z values take 0638 * the place of its childrens values, so you get a parent/child relationship. 0639 * The children are naturally still ordered relatively to their z values 0640 * 0641 * But for special cases (like Calligra's TextShape) it can be overloaded to return 0642 * ChildZPassThrough which means the children keep their own z values 0643 * @returns the z order policy of this shape 0644 */ 0645 virtual ChildZOrderPolicy childZOrderPolicy(); 0646 0647 /** 0648 * This is a method used to sort a list using the STL sorting methods. 0649 * @param s1 the first shape 0650 * @param s2 the second shape 0651 */ 0652 static bool compareShapeZIndex(KoShape *s1, KoShape *s2); 0653 0654 /** 0655 * returns the outline of the shape in the form of a path. 0656 * The outline returned will always be relative to the position() of the shape, so 0657 * moving the shape will not alter the result. The outline is used to draw the stroke 0658 * on, for example. 0659 * @returns the outline of the shape in the form of a path. 0660 */ 0661 virtual QPainterPath outline() const; 0662 0663 /** 0664 * returns the outline of the shape in the form of a rect. 0665 * The outlineRect returned will always be relative to the position() of the shape, so 0666 * moving the shape will not alter the result. The outline is used to calculate 0667 * the boundingRect. 0668 * @returns the outline of the shape in the form of a rect. 0669 */ 0670 virtual QRectF outlineRect() const; 0671 0672 /** 0673 * returns the outline of the shape in the form of a path for the use of painting a shadow. 0674 * 0675 * Normally this would be the same as outline() if there is a fill (background) set on the 0676 * shape and empty if not. However, a shape could reimplement this to return an outline 0677 * even if no fill is defined. A typical example of this would be the picture shape 0678 * which has a picture but almost never a background. 0679 * 0680 * @returns the outline of the shape in the form of a path. 0681 */ 0682 virtual QPainterPath shadowOutline() const; 0683 0684 /** 0685 * Returns the currently set stroke, or 0 if there is no stroke. 0686 * @return the currently set stroke, or 0 if there is no stroke. 0687 */ 0688 KoShapeStrokeModelSP stroke() const; 0689 0690 /** 0691 * Set a new stroke, removing the old one. The stroke inheritance becomes disabled. 0692 * @param stroke the new stroke, or 0 if there should be no stroke. 0693 */ 0694 void setStroke(KoShapeStrokeModelSP stroke); 0695 0696 /** 0697 * @brief setInheritStroke marks a shape as inhiriting the stroke 0698 * from the parent shape. NOTE: The currently selected stroke is destroyed. 0699 * @param value true if the shape should inherit the stroke style 0700 */ 0701 void setInheritStroke(bool value); 0702 0703 /** 0704 * @brief inheritStroke shows if the shape inherits the stroke from its parent 0705 * @return true if the shape inherits the stroke style 0706 */ 0707 bool inheritStroke() const; 0708 0709 /** 0710 * Return the insets of the stroke. 0711 * Convenience method for KoShapeStrokeModel::strokeInsets() 0712 */ 0713 KoInsets strokeInsets() const; 0714 0715 /// Sets the new shadow, removing the old one 0716 void setShadow(KoShapeShadow *shadow); 0717 0718 /// Returns the currently set shadow or 0 if there is no shadow set 0719 KoShapeShadow *shadow() const; 0720 0721 /// Sets a new clip path, removing the old one 0722 void setClipPath(KoClipPath *clipPath); 0723 0724 /// Returns the currently set clip path or 0 if there is no clip path set 0725 KoClipPath * clipPath() const; 0726 0727 /// Sets a new clip mask, removing the old one. The mask is owned by the shape. 0728 void setClipMask(KoClipMask *clipMask); 0729 0730 /// Returns the currently set clip mask or 0 if there is no clip mask set 0731 KoClipMask* clipMask() const; 0732 0733 /** 0734 * Setting the shape to keep its aspect-ratio has the effect that user-scaling will 0735 * keep the width/height ratio intact so as not to distort shapes that rely on that 0736 * ratio. 0737 * @param keepAspect the new value 0738 */ 0739 void setKeepAspectRatio(bool keepAspect); 0740 0741 /** 0742 * Setting the shape to keep its aspect-ratio has the effect that user-scaling will 0743 * keep the width/height ratio intact so as not to distort shapes that rely on that 0744 * ratio. 0745 * @return whether to keep aspect ratio of this shape 0746 */ 0747 bool keepAspectRatio() const; 0748 0749 /** 0750 * Return the position of this shape regardless of rotation/skew/scaling and regardless of 0751 * this shape having a parent (being in a group) or not.<br> 0752 * @param anchor The place on the (unaltered) shape that you want the position of. 0753 * @return the point that is the absolute, centered position of this shape. 0754 */ 0755 QPointF absolutePosition(KoFlake::AnchorPosition anchor = KoFlake::Center) const; 0756 0757 /** 0758 * Move this shape to an absolute position where the end location will be the same 0759 * regardless of the shape's rotation/skew/scaling and regardless of this shape having 0760 * a parent (being in a group) or not.<br> 0761 * The newPosition is going to be the center of the shape. 0762 * This has the convenient effect that: <pre> 0763 shape->setAbsolutePosition(QPointF(0,0)); 0764 shape->rotate(45);</pre> 0765 Will result in the same visual position of the shape as the opposite:<pre> 0766 shape->rotate(45); 0767 shape->setAbsolutePosition(QPointF(0,0));</pre> 0768 * @param newPosition the new absolute center of the shape. 0769 * @param anchor The place on the (unaltered) shape that you set the position of. 0770 */ 0771 void setAbsolutePosition(const QPointF &newPosition, KoFlake::AnchorPosition anchor = KoFlake::Center); 0772 0773 /** 0774 * Set a data object on the shape to be used by an application. 0775 * This is specifically useful when a shape is created in a plugin and that data from that 0776 * shape should be accessible outside the plugin. 0777 * @param userData the new user data, or 0 to delete the current one. 0778 */ 0779 void setUserData(KoShapeUserData *userData); 0780 /** 0781 * Return the current userData. 0782 */ 0783 KoShapeUserData *userData() const; 0784 0785 /** 0786 * Return the Id of this shape, identifying the type of shape by the id of the factory. 0787 * @see KoShapeFactoryBase::shapeId() 0788 * @return the id of the shape-type 0789 */ 0790 QString shapeId() const; 0791 0792 /** 0793 * Set the Id of this shape. A shapeFactory is expected to set the Id at creation 0794 * so applications can find out what kind of shape this is. 0795 * @see KoShapeFactoryBase::shapeId() 0796 * @param id the ID from the factory that created this shape 0797 */ 0798 void setShapeId(const QString &id); 0799 0800 /** 0801 * Create a matrix that describes all the transformations done on this shape. 0802 * 0803 * The absolute transformation is the combined transformation of this shape 0804 * and all its parents and grandparents. 0805 */ 0806 QTransform absoluteTransformation() const; 0807 0808 /** 0809 * Applies a transformation to this shape. 0810 * 0811 * The transformation given is relative to the global coordinate system, i.e. the document. 0812 * This is a convenience function to apply a global transformation to this shape. 0813 * @see applyTransformation 0814 * 0815 * @param matrix the transformation matrix to apply 0816 */ 0817 void applyAbsoluteTransformation(const QTransform &matrix); 0818 0819 /** 0820 * Sets a new transformation matrix describing the local transformations on this shape. 0821 * @param matrix the new transformation matrix 0822 */ 0823 void setTransformation(const QTransform &matrix); 0824 0825 /// Returns the shapes local transformation matrix 0826 QTransform transformation() const; 0827 0828 /** 0829 * Applies a transformation to this shape. 0830 * 0831 * The transformation given is relative to the shape coordinate system. 0832 * 0833 * @param matrix the transformation matrix to apply 0834 */ 0835 void applyTransformation(const QTransform &matrix); 0836 0837 /** 0838 * Copy all the settings from the parameter shape and apply them to this shape. 0839 * Settings like the position and rotation to visible and locked. The parent 0840 * is a notable exclusion. 0841 * @param shape the shape to use as original 0842 */ 0843 void copySettings(const KoShape *shape); 0844 0845 /** 0846 * A convenience method that creates a handles helper with applying transformations at 0847 * the same time. Please note that you shouldn't save/restore additionally. All the work 0848 * on restoring original painter's transformations is done by the helper. 0849 */ 0850 static KisHandlePainterHelper createHandlePainterHelperView(QPainter *painter, KoShape *shape, const KoViewConverter &converter, qreal handleRadius = 0.0); 0851 static KisHandlePainterHelper createHandlePainterHelperDocument(QPainter *painter, KoShape *shape, qreal handleRadius); 0852 0853 /** 0854 * @brief Transforms point from shape coordinates to document coordinates 0855 * @param point in shape coordinates 0856 * @return point in document coordinates 0857 */ 0858 QPointF shapeToDocument(const QPointF &point) const; 0859 0860 /** 0861 * @brief Transforms rect from shape coordinates to document coordinates 0862 * @param rect in shape coordinates 0863 * @return rect in document coordinates 0864 */ 0865 QRectF shapeToDocument(const QRectF &rect) const; 0866 0867 /** 0868 * @brief Transforms point from document coordinates to shape coordinates 0869 * @param point in document coordinates 0870 * @return point in shape coordinates 0871 */ 0872 QPointF documentToShape(const QPointF &point) const; 0873 0874 /** 0875 * @brief Transform rect from document coordinates to shape coordinates 0876 * @param rect in document coordinates 0877 * @return rect in shape coordinates 0878 */ 0879 QRectF documentToShape(const QRectF &rect) const; 0880 0881 /** 0882 * Returns the name of the shape. 0883 * @return the shapes name 0884 */ 0885 QString name() const; 0886 0887 /** 0888 * Sets the name of the shape. 0889 * @param name the new shape name 0890 */ 0891 void setName(const QString &name); 0892 0893 /** 0894 * Update the position of the shape in the tree of the KoShapeManager. 0895 */ 0896 void notifyChanged(); 0897 0898 /** 0899 * A shape can be in a state that it is doing processing data like loading or text layout. 0900 * In this case it can be shown on screen probably partially but it should really not be printed 0901 * until it is fully done processing. 0902 * Warning! This method can be blocking for a long time 0903 * @param asynchronous If set to true the processing will can take place in a different thread and the 0904 * function will not block until the shape is finished. 0905 * In case of printing Flake will call this method from a non-main thread and only 0906 * start printing it when the in case of printing method returned. 0907 * If set to false the processing needs to be done synchronously and will 0908 * block until the result is finished. 0909 */ 0910 virtual void waitUntilReady(bool asynchronous = true) const; 0911 0912 /// checks recursively if the shape or one of its parents is not visible or locked 0913 virtual bool isShapeEditable(bool recursive = true) const; 0914 0915 /** 0916 * Adds a shape which depends on this shape. 0917 * Making a shape dependent on this one means it will get shapeChanged() called 0918 * on each update of this shape. 0919 * 0920 * If this shape already depends on the given shape, establishing the 0921 * dependency is refused to prevent circular dependencies. 0922 * 0923 * @param shape the shape which depends on this shape 0924 * @return true if dependency could be established, otherwise false 0925 * @see removeDependee(), hasDependee() 0926 */ 0927 bool addDependee(KoShape *shape); 0928 0929 /** 0930 * Removes as shape depending on this shape. 0931 * @see addDependee(), hasDependee() 0932 */ 0933 void removeDependee(KoShape *shape); 0934 0935 /// Returns if the given shape is dependent on this shape 0936 bool hasDependee(KoShape *shape) const; 0937 0938 /// Returns list of shapes depending on this shape 0939 QList<KoShape*> dependees() const; 0940 0941 /// Returns additional snap data the shape wants to have snapping to 0942 virtual KoSnapData snapData() const; 0943 0944 /** 0945 * Set additional attribute 0946 * 0947 * This can be used to attach additional attributes to a shape for attributes 0948 * that are application specific like presentation:placeholder 0949 * 0950 * @param name The name of the attribute in the following form prefix:tag e.g. presentation:placeholder 0951 * @param value The value of the attribute 0952 */ 0953 void setAdditionalAttribute(const QString &name, const QString &value); 0954 0955 /** 0956 * Remove additional attribute 0957 * 0958 * @param name The name of the attribute in the following form prefix:tag e.g. presentation:placeholder 0959 */ 0960 void removeAdditionalAttribute(const QString &name); 0961 0962 /** 0963 * Check if additional attribute is set 0964 * 0965 * @param name The name of the attribute in the following form prefix:tag e.g. presentation:placeholder 0966 * 0967 * @return true if there is a attribute with prefix:tag set, false otherwise 0968 */ 0969 bool hasAdditionalAttribute(const QString &name) const; 0970 0971 /** 0972 * Get additional attribute 0973 * 0974 * @param name The name of the attribute in the following form prefix:tag e.g. presentation:placeholder 0975 * 0976 * @return The value of the attribute if it exists or a null string if not found. 0977 */ 0978 QString additionalAttribute(const QString &name) const; 0979 0980 void setAdditionalStyleAttribute(const char *name, const QString &value); 0981 0982 void removeAdditionalStyleAttribute(const char *name); 0983 0984 /** 0985 * Returns the filter effect stack of the shape 0986 * 0987 * @return the list of filter effects applied on the shape when rendering. 0988 */ 0989 KoFilterEffectStack *filterEffectStack() const; 0990 0991 /// Sets the new filter effect stack, removing the old one 0992 void setFilterEffectStack(KoFilterEffectStack *filterEffectStack); 0993 0994 /** 0995 * Return the tool delegates for this shape. 0996 * In Flake a shape being selected will cause the tool manager to make available all tools that 0997 * can edit the selected shapes. In some cases selecting one shape should allow the tool to 0998 * edit a related shape be available too. The tool delegates allows this to happen by taking 0999 * all the shapes in the set into account on tool selection. 1000 * Notice that if the set is non-empty 'this' shape is no longer looked at. You can choose 1001 * to add itself to the set too. 1002 */ 1003 QSet<KoShape*> toolDelegates() const; 1004 1005 /** 1006 * Set the tool delegates. 1007 * @param delegates the new delegates. 1008 * @see toolDelegates() 1009 */ 1010 void setToolDelegates(const QSet<KoShape*> &delegates); 1011 1012 /** 1013 * Return the hyperlink for this shape. 1014 */ 1015 QString hyperLink () const; 1016 1017 /** 1018 * Set hyperlink for this shape. 1019 * @param hyperLink name. 1020 */ 1021 void setHyperLink(const QString &hyperLink); 1022 1023 public: 1024 1025 struct KRITAFLAKE_EXPORT ShapeChangeListener { 1026 virtual ~ShapeChangeListener(); 1027 virtual void notifyShapeChanged(ChangeType type, KoShape *shape) = 0; 1028 1029 private: 1030 friend class KoShape; 1031 void registerShape(KoShape *shape); 1032 void unregisterShape(KoShape *shape); 1033 void notifyShapeChangedImpl(ChangeType type, KoShape *shape); 1034 1035 QList<KoShape*> m_registeredShapes; 1036 }; 1037 1038 void addShapeChangeListener(ShapeChangeListener *listener); 1039 void removeShapeChangeListener(ShapeChangeListener *listener); 1040 1041 protected: 1042 QList<ShapeChangeListener *> listeners() const; 1043 void setSizeImpl(const QSizeF &size) const; 1044 1045 public: 1046 static QList<KoShape*> linearizeSubtree(const QList<KoShape*> &shapes); 1047 static QList<KoShape *> linearizeSubtreeSorted(const QList<KoShape *> &shapes); 1048 protected: 1049 KoShape(const KoShape &rhs); 1050 1051 /** 1052 * A hook that allows inheriting classes to do something after a KoShape property changed 1053 * This is called whenever the shape, position rotation or scale properties were altered. 1054 * @param type an indicator which type was changed. 1055 * @param shape the shape. 1056 */ 1057 virtual void shapeChanged(ChangeType type, KoShape *shape = 0); 1058 1059 /// return the current matrix that contains the rotation/scale/position of this shape 1060 QTransform transform() const; 1061 1062 private: 1063 class Private; 1064 QScopedPointer<Private> d; 1065 1066 class SharedData; 1067 QSharedDataPointer<SharedData> s; 1068 1069 1070 protected: 1071 /** 1072 * Notify the shape that a change was done. To be used by inheriting shapes. 1073 * @param type the change type 1074 */ 1075 void shapeChangedPriv(KoShape::ChangeType type); 1076 1077 private: 1078 void addShapeManager(KoShapeManager *manager); 1079 void removeShapeManager(KoShapeManager *manager); 1080 friend class KoShapeManager; 1081 }; 1082 1083 Q_DECLARE_METATYPE(KoShape*) 1084 1085 #endif