Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

KoShape.h 27.3 KB
Newer Older
Thomas Zander's avatar
Thomas Zander committed
1
/* This file is part of the KDE project
2
   Copyright (C) 2006-2007 Thorsten Zachmann <zachmann@kde.org>
Thomas Zander's avatar
Thomas Zander committed
3 4
   Copyright (C) 2006 Casper Boemann Rasmussen <cbr@boemann.dk>
   Copyright (C) 2006 Thomas Zander <zander@kde.org>
5
   Copyright (C) 2007 Jan Hambrecht <jaham@gmx.net>
Thomas Zander's avatar
Thomas Zander committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
*/

Thomas Zander's avatar
Thomas Zander committed
23 24
#ifndef KOSHAPE_H
#define KOSHAPE_H
Thomas Zander's avatar
Thomas Zander committed
25

26
#include "KoInsets.h"
27
#include "KoFlake.h"
28

Thomas Zander's avatar
Thomas Zander committed
29 30
#include <QMatrix>
#include <QVector>
31
#include <QSet>
Thomas Zander's avatar
Thomas Zander committed
32 33
#include <QBrush>

34 35
#include <KoXmlReaderForward.h>

36 37
#include "flake_export.h"

Thomas Zander's avatar
Thomas Zander committed
38 39 40 41 42
class QPainter;
class QRectF;
class QPainterPath;

class KoShapeContainer;
43
class KoShapeConnection;
Thomas Zander's avatar
Thomas Zander committed
44
class KoShapeBorderModel;
45
class KoShapeManager;
46
class KoShapeUserData;
47
class KoViewConverter;
48
class KoShapeApplicationData;
49
class KoShapeSavingContext;
50
class KoCanvasBase;
51
class KoShapeLoadingContext;
52
class KoGenStyle;
Thomas Zander's avatar
Thomas Zander committed
53 54

/**
55
 *
56
 * Base class for all flake shapes. Shapes extend this class
Thomas Zander's avatar
Thomas Zander committed
57 58 59
 * to allow themselves to be manipulated. This class just represents
 * a graphical shape in the document and can be manipulated by some default
 * tools in this library.
60
 *
61
 * Due to the limited responsibility of this class, the extending object
Thomas Zander's avatar
Thomas Zander committed
62
 * can have any data backend and is responsible for painting itself.
63
 *
64
 * We strongly suggest that any extending class will use a Model View
Thomas Zander's avatar
Thomas Zander committed
65
 * Controller (MVC) design where the View part is all in this class, as well
66
 * as the one that inherits from this one.  This allows the data that rests
Thomas Zander's avatar
Thomas Zander committed
67
 * in the model to be reused in different parts of the document. For example
68
 * by having two flake objects that show that same data. Or each showing a section of it.
69
 *
70 71 72 73 74
 * The KoShape data is completely in postscript-points (pt) (see KoUnit
 * for conversion methods to and from points).
 * This image will explain the real-world use of the shape and its options.
 * <img src="../flake_shape_coords.png" align=center><br>
 *  The Rotation center can be returned with absolutePosition()
75
 *
76
 * <p>Flake objects can be created in three ways:
77 78 79 80 81
 * <ul>
 *   <li>a simple new KoDerivedFlake(),
 *   <li>through an associated tool,
 *   <li>through a factory
 * </ul>
Thomas Zander's avatar
Thomas Zander committed
82
 */
83
class FLAKE_EXPORT KoShape
Thomas Zander's avatar
Thomas Zander committed
84 85
{
public:
86 87 88
    /// Used by shapeChanged() to select which change was made
    enum ChangeType {
        PositionChanged, ///< used after a setPosition()
89 90 91 92
        RotationChanged, ///< used after a setRotation()
        ScaleChanged,   ///< used after a setScale()
        ShearChanged,   ///< used after a setShear()
        SizeChanged,    ///< used after a setSize()
93
        GenericMatrixChange,    ///< used after the matrix was changed without knowing which property explicitly changed
94 95 96 97
        ParentChanged,   ///< used after a setParent()
        CollisionDetected ///< used when another shape moved in our boundingrect
    };

Thomas Zander's avatar
Thomas Zander committed
98 99 100 101 102 103 104 105 106 107 108 109 110 111
    /**
     * @brief Constructor
     */
    KoShape();

    /**
     * @brief Destructor
     */
    virtual ~KoShape();

    /**
     * @brief Paint the shape
     * The class extending this one is responsible for painting itself.  Since we do not
     * assume the shape is square the paint must also clear its background if it will draw
112
     * something transparent on top.
Thomas Zander's avatar
Thomas Zander committed
113 114 115 116
     * This can be done with a method like:
     * <code>
       painter.fillRect(converter.normalToView(QRectF(QPointF(0.0,0.0), size())), background());</code>
     * Or equavalent for non-square objects.
117 118
     * Do note that a shape's top-left is always at coordinate 0,0. Even if the shape itself is rotated
     * or translated.
Thomas Zander's avatar
Thomas Zander committed
119 120 121 122
     * @param painter used for painting the shape
     * @param converter to convert between internal and view coordinates.
     * @see applyConversion()
     */
123
    virtual void paint(QPainter &painter, const KoViewConverter &converter) = 0;
Thomas Zander's avatar
Thomas Zander committed
124 125 126 127 128 129 130

    /**
     * Paint non-print decorations specific for this type of shape.
     * The default implementation is empty.
     *
     * @param painter used for painting the shape
     * @param converter to convert between internal and view coordinates.
Thomas Zander's avatar
Thomas Zander committed
131 132
     * @param canvas the canvas that requested this paint.  This can be used to retrieve canvas specific properties
     *      like selection and get a reference to the KoCanvasResourceProvider.
Thomas Zander's avatar
Thomas Zander committed
133
     */
134
    virtual void paintDecorations(QPainter &painter, const KoViewConverter &converter, const KoCanvasBase *canvas);
Thomas Zander's avatar
Thomas Zander committed
135

136 137 138 139 140 141
    /**
     * Load a shape from odf
     *
     * @param context the KoShapeLoadingContext used for loading
     * @param element element which represents the shape in odf
     *
142
     * @return false if loading failed
143
     */
144
    virtual bool loadOdf( const KoXmlElement & element, KoShapeLoadingContext &context ) = 0;
145

146
    /**
147 148 149
     * @brief store the shape data as ODF XML.
     * This is the method that will be called when saving a shape as a described in¬
     * OpenDocument 9.2 Drawing Shapes.
Thorsten Zachmann's avatar
Thorsten Zachmann committed
150
     * @see saveOdfAttributes
151
     */
152
    virtual void saveOdf( KoShapeSavingContext & context ) const = 0;
153 154

    /**
155 156 157
     * When saving this shape to ODF, you may nest it in a 'draw:frame' and shape properties should be
     * saved as attributes on that element instead of on the normal shape.  After starting to write such
     * an element you can call this method to write all relevant properties.
158
     */
159
    void saveOdfFrameAttributes( KoShapeSavingContext & context ) const;
160

Thomas Zander's avatar
Thomas Zander committed
161 162 163 164 165 166 167
    /**
     * @brief Scale the shape using the zero-point which is the top-left corner.
     * @see position()
     *
     * @param sx scale in x direction
     * @param sy scale in y direction
     */
168
    void setScale( double sx, double sy );
Thomas Zander's avatar
Thomas Zander committed
169 170 171 172

    /**
     * Return the current scaling adjustment over the X axis.
     */
173
    KDE_DEPRECATED double scaleX() const;
Thomas Zander's avatar
Thomas Zander committed
174 175 176 177

    /**
     * Return the current scaling adjustment over the Y axis.
     */
178
    KDE_DEPRECATED double scaleY() const;
Thomas Zander's avatar
Thomas Zander committed
179 180

    /**
181
     * @brief Rotate the shape (relative)
Thomas Zander's avatar
Thomas Zander committed
182
     *
183
     * The shape will be rotated from the current rotation using the center of the shape using the size()
Thomas Zander's avatar
Thomas Zander committed
184
     *
185
     * @param angle change the angle of rotation increasing it with 'angle' degrees
Thomas Zander's avatar
Thomas Zander committed
186 187 188 189 190
     */
    void rotate( double angle );

    /**
     * Return the current rotation in degrees.
191
     * It returns NaN if the shape has a shearing or scaling transformation applied.
Thomas Zander's avatar
Thomas Zander committed
192
     */
193
    double rotation() const;
Thomas Zander's avatar
Thomas Zander committed
194 195 196 197 198 199 200 201 202

    /**
     * @brief Shear the shape
     * The shape will be sheared using the zero-point which is the top-left corner.
     * @see position()
     *
     * @param sx shear in x direction
     * @param sy shear in y direction
     */
203
    void setShear( double sx, double sy );
Thomas Zander's avatar
Thomas Zander committed
204

Thomas Zander's avatar
Thomas Zander committed
205 206 207 208
    /**
     * Return the current horizontal shearing angle for this shape.
     * @return the current horizontal shearing angle for this shape.
     */
209
    KDE_DEPRECATED double shearX() const;
Thomas Zander's avatar
Thomas Zander committed
210

Thomas Zander's avatar
Thomas Zander committed
211 212 213 214
    /**
     * Return the current vertical shearing angle for this shape.
     * @return the current vertical shearing angle for this shape.
     */
215
    KDE_DEPRECATED double shearY() const;
Thomas Zander's avatar
Thomas Zander committed
216

Thomas Zander's avatar
Thomas Zander committed
217 218 219
    /**
     * @brief Resize the shape
     *
220
     * @param size the new size of the shape.  This is different from scaling as
Jan Hambrecht's avatar
Jan Hambrecht committed
221
     * scaling is a so called secondary operation which is comparable to zooming in
Thomas Zander's avatar
Thomas Zander committed
222 223 224 225
     * instead of changing the size of the basic shape.
     * Easiest example of this difference is that using this method will not distort the
     * size of pattern-fills and borders.
     */
226
    virtual void setSize( const QSizeF &size );
Thomas Zander's avatar
Thomas Zander committed
227 228 229 230

    /**
     * @brief Get the size of the shape in pt.
     *
Thorsten Zachmann's avatar
Thorsten Zachmann committed
231 232
     * The size is in shape coordinates.
     *
Thomas Zander's avatar
Thomas Zander committed
233 234
     * @return the size of the shape as set by resize()
     */
Thomas Zander's avatar
Thomas Zander committed
235
    virtual QSizeF size() const;
Thomas Zander's avatar
Thomas Zander committed
236 237 238 239 240 241 242 243 244 245 246 247 248

    /**
     * @brief Set the position of the shape in pt
     *
     * @param position the new position of the shape
     */
    virtual void setPosition( const QPointF &position );

    /**
     * @brief Get the position of the shape in pt
     *
     * @return the position of the shape
     */
Thomas Zander's avatar
Thomas Zander committed
249
    virtual QPointF position() const;
Thomas Zander's avatar
Thomas Zander committed
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264

    /**
     * @brief Check if the shape is hit on position
     * @param position the position where the user clicked.
     * @return true when it hits.
     */
    virtual bool hitTest( const QPointF &position ) const;

    /**
     * @brief Get the bounding box of the shape
     *
     * This includes the line width but not the shadow of the shape
     *
     * @return the bounding box of the shape
     */
265
    virtual QRectF boundingRect() const;
Thomas Zander's avatar
Thomas Zander committed
266 267 268 269 270 271 272 273 274 275 276

    /**
     * @brief Add a connector point to the shape
     * A connector is a place on the shape that allows a graphical connection to be made
     * using a line, for example.
     *
     * @param point the position where to place the connector. The points coordinate system
     *   are based around the zero-pos which is the top-left of the shape
     *   The point does not have to be inside the boundings rectangle.  The point is in pt,
     *   just like the rest of the KoShape class uses.
     */
Thomas Zander's avatar
Thomas Zander committed
277
    void addConnectionPoint( const QPointF &point );
Thomas Zander's avatar
Thomas Zander committed
278

Thomas Zander's avatar
Thomas Zander committed
279
    /**
280
     * Return a list of the connection points that have been added to this shape.
Thomas Zander's avatar
Thomas Zander committed
281 282
     * @return a list of the connectors that have been added to this shape.
     */
283 284
    KDE_DEPRECATED QList<QPointF> connectors() const;
    QList<QPointF> connectionPoints() const;
Thomas Zander's avatar
Thomas Zander committed
285

Thomas Zander's avatar
Thomas Zander committed
286 287
    /**
     * Set the background of the shape.
288
     * A QBrush can have a plain color, be fully transparent or have a complex fill.
Thomas Zander's avatar
Thomas Zander committed
289
     * setting such a brush will allow the shape to fill itself using that brush and
290
     * will be able to tell if its transparent or not.
Thomas Zander's avatar
Thomas Zander committed
291 292
     * @param brush the brush for the background.
     */
Thomas Zander's avatar
Thomas Zander committed
293
    void setBackground ( const QBrush & brush );
Thomas Zander's avatar
Thomas Zander committed
294 295 296

    /**
     * return the brush used to paint te background of this shape with.
297
     * A QBrush can have a plain color, be fully transparent or have a complex fill.
Thomas Zander's avatar
Thomas Zander committed
298
     * setting such a brush will allow the shape to fill itself using that brush and
299
     * will be able to tell if its transparent or not.
Thomas Zander's avatar
Thomas Zander committed
300 301
     * @return the background-brush
     */
302
    QBrush background() const;
Thomas Zander's avatar
Thomas Zander committed
303 304

    /**
305 306
     * Returns true if there is some transparency, false if the shape is fully opaque.
     * The default implementation will just return if the background has some transparency,
Thomas Zander's avatar
Thomas Zander committed
307
     * you should override it and always return true if your shape is not square.
308
     * @return if the shape is (partly) transparent.
Thomas Zander's avatar
Thomas Zander committed
309
     */
310
    virtual bool hasTransparency();
Thomas Zander's avatar
Thomas Zander committed
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327

    /**
     * Retrieve the z-coordinate of this shape.
     * The zIndex property is used to determine which shape lies on top of other objects.
     * An shape with a higher z-order is on top, and can obscure another shape.
     * @return the z-index of this shape.
     * @see setZIndex()
     */
    int zIndex() const;

    /**
     * Set the z-coordinate of this shape.
     * The zIndex property is used to determine which shape lies on top of other objects.
     * An shape with a higher z-order is on top, and can obscure, another shape.
     * <p>Just like two objects having the same x or y coordinate will make them 'touch',
     * so will two objects with the same z-index touch on the z plane.  In layering the
     * shape this, however, can cause a little confusion as one always has to be on top.
328
     * The layering if two overlapping objects have the same index is implementation dependent
Thomas Zander's avatar
Thomas Zander committed
329 330 331
     * and probably depends on the order in which they are added to the shape manager.
     * @param zIndex the new z-index;
     */
Thomas Zander's avatar
Thomas Zander committed
332
    void setZIndex(int zIndex);
Thomas Zander's avatar
Thomas Zander committed
333 334 335 336 337 338 339

    /**
     * Changes the Shape to be visible or invisible.
     * Being visible means being painted and printed, as well as being used for
     *   things like guidelines or searches.
     * @param on when true; set the shape to be visible.
     */
Thomas Zander's avatar
Thomas Zander committed
340
    void setVisible(bool on);
Thomas Zander's avatar
Thomas Zander committed
341 342 343 344 345 346
    /**
     * Returns current visibility state of this shape.
     * Being visible means being painted and printed, as well as being used for
     *   things like guidelines or searches.
     * @return current visibility state of this shape.
     */
Thomas Zander's avatar
Thomas Zander committed
347
    bool isVisible() const;
Thomas Zander's avatar
Thomas Zander committed
348

349 350 351
    /**
     * Makes it possible for the user to select this shape.
     * This parameter defaults to true.
Thomas Zander's avatar
Thomas Zander committed
352
     * @param selectable when true; set the shape to be selectable.
353
     */
Thomas Zander's avatar
Thomas Zander committed
354
    void setSelectable(bool selectable);
355 356 357 358
    /**
     * Returns wheather this shape can be selected by the user.
     * @return true only when the object is selectable.
     */
Thomas Zander's avatar
Thomas Zander committed
359
    bool isSelectable() const;
360

Thomas Zander's avatar
Thomas Zander committed
361 362 363 364 365
    /**
     * Changes the Shape to be locked in place.
     * Being locked means the shape can no longer change shape or position.
     * @param locked when true; set the shape to be locked.
     */
Thomas Zander's avatar
Thomas Zander committed
366
    void setLocked(bool locked);
Thomas Zander's avatar
Thomas Zander committed
367 368 369 370 371
    /**
     * Returns current locked state of this shape.
     * Being locked means the shape can no longer change shape or position.
     * @return current locked state of this shape.
     */
Thomas Zander's avatar
Thomas Zander committed
372
    bool isLocked() const;
Thomas Zander's avatar
Thomas Zander committed
373 374 375 376 377

    /**
     * Returns the parent, or 0 if there is no parent.
     * @return the parent, or 0 if there is no parent.
     */
Thomas Zander's avatar
Thomas Zander committed
378
    KoShapeContainer *parent() const;
Thomas Zander's avatar
Thomas Zander committed
379 380 381 382 383 384 385 386 387 388 389 390 391 392

    /**
     * Set the parent of this shape.
     * @param parent the new parent of this shape. Can be 0 if the shape has no parent anymore.
     */
    void setParent(KoShapeContainer *parent);

    /**
     * Request a repaint to be queued.
     * The repaint will be of the entire Shape, including its selection handles should this
     * shape be selected.
     * <p>This method will return immediately and only request a repaint. Successive calls
     * will be merged into an appropriate repaint action.
     */
393
    virtual void update() const;
Thomas Zander's avatar
Thomas Zander committed
394 395 396 397 398 399 400 401 402 403

    /**
     * Request a repaint to be queued.
     * The repaint will be restricted to the parameters rectangle, which is expected to be
     * in points (the internal coordinates system of KoShape) and it is expected to be
     * normalized.
     * <p>This method will return immediately and only request a repaint. Successive calls
     * will be merged into an appropriate repaint action.
     * @param shape the rectangle (in pt) to queue for repaint.
     */
404
    void update(const QRectF &shape) const;
Thomas Zander's avatar
Thomas Zander committed
405 406 407

    /**
     * This is a method used to sort a list using the STL sorting methods.
408 409
     * @param s1 the first shape
     * @param s2 the second shape
Thomas Zander's avatar
Thomas Zander committed
410
     */
411
    static bool compareShapeZIndex(KoShape *s1, KoShape *s2);
Thomas Zander's avatar
Thomas Zander committed
412 413 414 415 416 417 418 419 420 421 422 423 424 425

    /**
     * returns the outline of the shape in the form of a path.
     * The outline returned will always have the position() of the shape as the origin, so
     * moving the shape will not alter the result.  The outline is used to draw the border
     * on, for example.
     * @returns the outline of the shape in the form of a path.
     */
    virtual const QPainterPath outline() const;

    /**
     * Returns the currently set border, or 0 if there is no border.
     * @return the currently set border, or 0 if there is no border.
     */
426
    KoShapeBorderModel *border() const;
Thomas Zander's avatar
Thomas Zander committed
427 428 429 430 431

    /**
     * Set a new border, removing the old one.
     * @param border the new border, or 0 if there should be no border.
     */
432
    void setBorder(KoShapeBorderModel *border);
Thomas Zander's avatar
Thomas Zander committed
433

434 435 436 437 438 439
    /**
     * Return the insets of the border.
     * Convenience method for KoShapeBorderModel::borderInsets()
     */
    KoInsets borderInsets() const;

Thomas Zander's avatar
Thomas Zander committed
440 441 442 443 444 445
    /**
     * Setting the shape to keep its aspect-ratio has the effect that user-scaling will
     * keep the width/hight ratio intact so as not to distort shapes that rely on that
     * ratio.
     * @param keepAspect the new value
     */
Thomas Zander's avatar
Thomas Zander committed
446
    void setKeepAspectRatio(bool keepAspect);
447

Thomas Zander's avatar
Thomas Zander committed
448 449 450 451 452 453
    /**
     * Setting the shape to keep its aspect-ratio has the effect that user-scaling will
     * keep the width/hight ratio intact so as not to distort shapes that rely on that
     * ratio.
     * @return whether to keep aspect ratio of this shape
     */
Thomas Zander's avatar
Thomas Zander committed
454
    bool keepAspectRatio() const;
Thomas Zander's avatar
Thomas Zander committed
455 456 457 458

    /**
     * Return the position of this shape regardless of rotation/skew/scaling and regardless of
     * this shape having a parent (being in a group) or not.<br>
459
     * @param anchor The place on the (unaltered) shape that you want the position of.
Thomas Zander's avatar
Thomas Zander committed
460 461
     * @return the point that is the absolute, centered position of this shape.
     */
Jan Hambrecht's avatar
Jan Hambrecht committed
462
    QPointF absolutePosition(KoFlake::Position anchor = KoFlake::CenteredPosition) const;
463

Thomas Zander's avatar
Thomas Zander committed
464 465 466 467 468 469 470 471 472 473 474 475
    /**
     * Move this shape to an absolute position where the end location will be the same
     * regardless of the shape's rotation/skew/scaling and regardless of this shape having
     * a parent (being in a group) or not.<br>
     * The newPosition is going to be the center of the shape.
     * This has the convenient effect that: <pre>
    shape-&gt;setAbsolutePosition(QPointF(0,0));
    shape-&gt;rotate(45);</pre>
        Will result in the same visual position of the shape as the opposite:<pre>
    shape-&gt;rotate(45);
    shape-&gt;setAbsolutePosition(QPointF(0,0));</pre>
     * @param newPosition the new absolute center of the shape.
Thomas Zander's avatar
Thomas Zander committed
476
     * @param anchor The place on the (unaltered) shape that you set the position of.
Thomas Zander's avatar
Thomas Zander committed
477
     */
Jan Hambrecht's avatar
Jan Hambrecht committed
478
    void setAbsolutePosition(QPointF newPosition, KoFlake::Position anchor = KoFlake::CenteredPosition);
Thomas Zander's avatar
Thomas Zander committed
479

480 481
    /**
     * Set a data object on the shape to be used by an application.
482
     * This is specifically useful when a shape is created in a plugin and that data from that
483 484 485 486 487 488 489 490 491
     * shape should be accessible outside the plugin.
     * @param userData the new user data, or 0 to delete the current one.
     */
    void setUserData(KoShapeUserData *userData);
    /**
     * Return the current userData.
     */
    KoShapeUserData *userData() const;

492 493 494 495 496 497 498 499 500 501 502 503
    /**
     * Set a data object on the shape to be used by an application.
     * This is specifically useful when an application wants to have data that is per shape
     * and should be deleted when the shape is destructed.
     * @param applicationData the new application data, or 0 to delete the current one.
     */
    void setApplicationData(KoShapeApplicationData *applicationData);
    /**
     * Return the current applicationData.
     */
    KoShapeApplicationData *applicationData() const;

504
    /**
Marijn Kruisselbrink's avatar
Marijn Kruisselbrink committed
505
     * Return the Id of this shape, identifying the type of shape by the id of the factory.
506 507 508
     * @see KoShapeFactory::shapeId()
     * @return the id of the shape-type
     */
Thomas Zander's avatar
Thomas Zander committed
509
    const QString & shapeId() const;
510 511 512 513 514 515
    /**
     * Set the Id of this shape.  A shapeFactory is expected to set the Id at creation
     * so applications can find out what kind of shape this is.
     * @see KoShapeFactory::shapeId()
     * @param id the ID from the factory that created this shape
     */
Thomas Zander's avatar
Thomas Zander committed
516
    void setShapeId(const QString &id);
517

Thomas Zander's avatar
Thomas Zander committed
518 519
    /**
     * Create a matrix that describes all the transformations done on this shape.
520 521 522 523
     *
     * The absolute transformation is the combined transformation of this shape
     * and all its parents and grandparents.
     *
Thomas Zander's avatar
Thomas Zander committed
524 525 526
     * @param converter if not null, this method uses the converter to mark the right
     *        offsets in the current view.
     */
527
    QMatrix absoluteTransformation(const KoViewConverter *converter) const;
Thomas Zander's avatar
Thomas Zander committed
528

529 530 531 532
    /**
     * Applies a transformation to this shape.
     *
     * The transformation given is relative to the global coordinate system, i.e. the document.
533 534
     * This is a convenience function to apply a global transformation to this shape.
     * @see applyTransformation
535 536 537
     *
     * @param matrix the transformation matrix to apply
     */
538
    void applyAbsoluteTransformation(const QMatrix &matrix );
539 540 541 542 543 544 545

    /**
     * Sets a new transformation matrix describing the local transformations on this shape.
     * @param matrix the new transformation matrix
     */
    void setTransformation( const QMatrix &matrix );

546
    /// Returns the shapes local transformation matrix
547 548 549 550 551 552 553 554 555 556
    QMatrix transformation() const;

    /**
     * Applies a transformation to this shape.
     *
     * The transformation given is relative to the shape coordinate system.
     *
     * @param matrix the transformation matrix to apply
     */
    void applyTransformation( const QMatrix &matrix );
557

Thomas Zander's avatar
Thomas Zander committed
558 559 560 561 562 563 564 565
    /**
     * Copy all the settings from the parameter shape and apply them to this shape.
     * Settings like the position and rotation to visible and locked.  The parent
     * is a notable exclusion.
     * @param shape the shape to use as original
     */
    virtual void copySettings(const KoShape *shape);

Thomas Zander's avatar
Thomas Zander committed
566 567 568 569 570 571 572 573 574
    /**
     * Convenience method that allows people implementing paint() to use the shape
     * internal coordinate system directly to paint itself instead of considering the
     * views zoom.
     * @param painter the painter to alter the zoom level of.
     * @param converter the converter for the current views zoom.
     */
    static void applyConversion(QPainter &painter, const KoViewConverter &converter);

Thomas Zander's avatar
Thomas Zander committed
575 576 577
    /**
     * Return all the connections made to or from this shape.
     */
578 579
    QList<KoShapeConnection*> connections() const;

580 581 582 583
    /**
     * Returns the name of the shape.
     * @return the shapes name
     */
584
    QString name() const;
585 586 587 588 589 590 591

    /**
     * Sets the name of the shape.
     * @param name the new shape name
     */
    void setName( const QString & name );

592 593 594 595 596
    /**
     * Update the position of the shape in the tree of the KoShapeManager.
     */
    void notifyChanged();

597 598 599 600 601 602 603 604 605
    /**
     * A shape can be in a state that its doing loading or text layout or similar in which case
     * it can be shown on screen just fine (probably partially) but it should really not be printed
     * until its fully done.
     * Flake will call this method from a non-main thread and only start printing it when the
     * method returned.
     * Warning!  This method can be blocking for a long time, never call it on the gui-thread!
     */
    virtual void waitUntilReady() const {}
606

Thomas Zander's avatar
api dox  
Thomas Zander committed
607 608 609 610 611 612 613 614
    /**
     * Schedule the shape for thread-safe deletion.
     * After calling this method will self-delete in the main threads event loop.
     * If deleting a shape can possibly be done in a separate thread, you should delete it
     * using this method.  If you delete a shape from another thread then its possible the main
     * thread will use it after its been removed, while painting for example.
     * Note that in contrary to the equivalent method on QObject, you can not call this more than ones!
     */
615
    void deleteLater();
616

617 618 619
    /// checks recursively if the shape or one of its parents is not visible or locked
    bool isEditable() const;

620
protected:
621 622

/* ** loading saving helper methods */
623 624 625 626 627 628 629
    /// attributes from ODF 1.1 chapter 9.2.15 Common Drawing Shape Attributes
    enum OdfAttribute {
        OdfTransformation = 1,  ///< Store transformation information
        OdfSize = 2,            ///< Store size information
        OdfPosition = 4,        ///< Store position of shape
        OdfMandatories = 8,     ///< Id, z-index, layer and style

Thomas Zander's avatar
Thomas Zander committed
630
        /// A mask for all the attributes a 'draw:frame' requires
631 632
        FrameAttributes = OdfMandatories | OdfSize | OdfPosition | OdfTransformation
    };
633

634 635 636 637 638 639 640 641
    /**
     * This method is used during loading of the shape to load common attributes
     *
     * @param context the KoShapeLoadingContext used for loading
     * @param element element which represents the shape in odf
     * @param attributes a number of OdfAttribute items to state which attributes to load.
     */
    bool loadOdfAttributes( const KoXmlElement & element, KoShapeLoadingContext &context, int attributes );
642

Jan Hambrecht's avatar
 
Jan Hambrecht committed
643 644 645 646 647 648 649
    /**
     * Parses the transformation attribute from the given string
     * @param transform the transform attribute string
     * @return the resulting transformation matrix
     */
    QMatrix parseOdfTransform( const QString &transform );

650
    /**
651 652
     * This method can be used while saving the shape as ODF to add the data
     * stored on this shape to the current element.
653
     *
654 655 656
     * @param context the context for the current save.
     * @param attributes a number of OdfAttribute items to state which attributes to save.
     * @see saveOdf
657
     */
658
    void saveOdfAttributes( KoShapeSavingContext &context, int attributes ) const;
659

660
    /**
661
     * Add a new draw-glue-point element for each connections() present on this shape.
662
     */
663
    void saveOdfConnections( KoShapeSavingContext &context ) const;
664

665
    /**
666
     * @brief Saves the style used for the shape
667
     *
668 669
     * This method fills the given style object with the border and
     * background properties and then adds the style to the context.
670
     *
671
     * @param style the style object to fill
672 673 674
     * @param context used for saving
     * @return the name of the style
     * @see saveOdf
675
     */
676 677 678 679 680 681 682 683 684
    virtual QString saveStyle( KoGenStyle &style, KoShapeSavingContext &context ) const;

    /**
     * Loads the stroke and fill style from the given element.
     *
     * @param element the xml element to  load the style from
     * @param context the loading context used for loading
     */
    virtual void loadStyle( const KoXmlElement & element, KoShapeLoadingContext &context );
685

686 687 688
    /// Loads the fill style
    QBrush loadOdfFill( const KoXmlElement & element, KoShapeLoadingContext & context );

689 690 691
    /// Loads the stroke style
    KoShapeBorderModel * loadOdfStroke( const KoXmlElement & element, KoShapeLoadingContext & context );

692 693 694 695 696
    /**
     * Fills the style stack and returns the value of the given style property (e.g fill, stroke).
     */
    QString getStyleProperty( const char *property, const KoXmlElement & element, KoShapeLoadingContext & context );

697 698
/* ** end loading saving */

699

700 701 702 703 704 705 706
    /**
     * A hook that allows inheriting classes to do something after a KoShape property changed
     * This is called whenever the shape, position rotation or scale properties were altered.
     * @param type an indicator which type was changed.
     */
    virtual void shapeChanged(ChangeType type) { Q_UNUSED(type); }

Thomas Zander's avatar
Thomas Zander committed
707 708 709 710 711 712
    /**
     * Set the property collision detection.
     * Setting this to true will result in calls to shapeChanged() with the CollisionDetected
     * parameter whenever either this or another shape is moved/rotated etc and intersects this shape.
     * @param detect if true detect collisions.
     */
Thomas Zander's avatar
Thomas Zander committed
713
    void setCollisionDetection(bool detect);
Thomas Zander's avatar
Thomas Zander committed
714 715 716 717
    /**
     * get the property collision detection.
     * @returns true if collision detection is on.
     */
Thomas Zander's avatar
Thomas Zander committed
718
    bool collisionDetection();
Thomas Zander's avatar
Thomas Zander committed
719

Thomas Zander's avatar
Thomas Zander committed
720
    /// return the current matrix that contains the rotation/scale/position of this shape
721 722
    const QMatrix& matrix() const;

723
    friend class KoShapeConnection;
Thomas Zander's avatar
Thomas Zander committed
724 725 726 727
    /**
     * Add a connection to the list of connections of this shape.
     * This is typically called only from the constructor of the KoShapeConnection class.
     */
728
    void addConnection(KoShapeConnection *connection);
Thomas Zander's avatar
Thomas Zander committed
729 730 731 732
    /**
     * Remove a connection to the list of connections of this shape.
     * This is typically called only from the destructor of the KoShapeConnection class.
     */
733 734
    void removeConnection(KoShapeConnection *connection);

735
    /// Removes connection point with given index
736
    void removeConnectionPoint( int index );
737

Thomas Zander's avatar
Thomas Zander committed
738 739
private:
    friend class KoShapeManager;
Thomas Zander's avatar
Thomas Zander committed
740 741 742
    void addShapeManager( KoShapeManager * manager );
    void removeShapeManager( KoShapeManager * manager );

743 744 745
    class Private;
    friend class Private;
    Private * const d;
Thomas Zander's avatar
Thomas Zander committed
746 747
};

Thomas Zander's avatar
Thomas Zander committed
748
#endif