File indexing completed on 2024-05-12 15:56:47

0001 /* This file is part of the KDE project
0002  * SPDX-FileCopyrightText: 2007, 2009 Thomas Zander <zander@kde.org>
0003  * SPDX-FileCopyrightText: 2011 Matus Hanzes <matus.hanzes@ixonos.com>
0004  * SPDX-FileCopyrightText: 2013 C. Boemann <cbo@boemann.dk>
0005  *
0006  * SPDX-License-Identifier: LGPL-2.0-or-later
0007  */
0008 #ifndef KOSHAPEANCHOR_H
0009 #define KOSHAPEANCHOR_H
0010 
0011 #include "kritaflake_export.h"
0012 
0013 
0014 class KoShape;
0015 #include <QDomDocument>
0016 class KoShapeLoadingContext;
0017 class KoShapeSavingContext;
0018 class KoShapeAnchorPrivate;
0019 
0020 class QTextDocument;
0021 class QPointF;
0022 class QString;
0023 
0024 /**
0025  * This class is the object that explains how a shape is anchored to something.
0026  *
0027  * The anchored shape will be positioned (in supporting applications) based on the properties
0028  * defined in this class.
0029  *
0030  * This class can be used in three different ways:
0031  *  -page anchor
0032  *  -as-char
0033  *  -char, paragraph anchor
0034  *
0035  * If it's a page anchor it just provide the info about how the shape relates to a page with a specific
0036  * page number.
0037  *
0038  * For the other types of anchoring it has to have a TextLocation in a QTextDocument. This TextLocation
0039  * can either be an inline character (type as-char) or a position (type char or paragraph) The
0040  * KoShapeAnchor and TextLocation connects the anchored-shape to the text flow so the anchored shape
0041  * can be repositioned on the canvas if new text is inserted or removed before the anchor character.
0042  *
0043  * For as-char, char and paragraph use cases:
0044  * @see KoAnchorInlineObject
0045  * @see KoAnchorTextRange
0046  * which are both implemented as subclasses of TextLocation
0047  *
0048  * The position of the shape relative to the anchor is called the offset.
0049  * @see PlacementStrategy for more information about the layout of anchors/shapes.
0050  */
0051 class KRITAFLAKE_EXPORT KoShapeAnchor
0052 {
0053 public:
0054     /**
0055     * This class is an interface that positions the shape linked to text anchor
0056     */
0057     class PlacementStrategy {
0058     public:
0059         PlacementStrategy(){};
0060         virtual ~PlacementStrategy(){};
0061 
0062         /**
0063          * Reparent the anchored shape to not have a parent shape container (and model)
0064          *
0065          */
0066         virtual void detachFromModel() = 0;
0067 
0068         /**
0069          * Reparent the anchored shape under an appropriate shape container (and model)
0070          *
0071          * If needed, it changes the parent KoShapeContainerModel and KoShapeContainer of the anchored
0072          * shape.
0073          */
0074         virtual void updateContainerModel() = 0;
0075     };
0076 
0077     class TextLocation {
0078     public:
0079         TextLocation(){};
0080         virtual ~TextLocation(){};
0081         virtual const QTextDocument *document() const = 0;
0082         virtual int position() const = 0;
0083     };
0084 
0085     enum HorizontalPos {
0086         HCenter,
0087         HFromInside,
0088         HFromLeft,
0089         HInside,
0090         HLeft,
0091         HOutside,
0092         HRight
0093     };
0094 
0095     enum HorizontalRel { //NOTE: update KWAnchoringProperties if you change this
0096         HChar,
0097         HPage,
0098         HPageContent,
0099         HPageStartMargin,
0100         HPageEndMargin,
0101         HFrame,
0102         HFrameContent,
0103         HFrameEndMargin,
0104         HFrameStartMargin,
0105         HParagraph,
0106         HParagraphContent,
0107         HParagraphEndMargin,
0108         HParagraphStartMargin
0109     };
0110 
0111     enum VerticalPos {
0112         VBelow,
0113         VBottom,
0114         VFromTop,
0115         VMiddle,
0116         VTop
0117     };
0118 
0119     enum VerticalRel { //NOTE: update KWAnchoringProperties if you change this
0120         VBaseline,
0121         VChar,
0122         VFrame,
0123         VFrameContent,
0124         VLine,
0125         VPage,
0126         VPageContent,
0127         VParagraph,
0128         VParagraphContent,
0129         VText
0130     };
0131 
0132     enum AnchorType {
0133         AnchorAsCharacter,
0134         AnchorToCharacter,
0135         AnchorParagraph,
0136         AnchorPage
0137     };
0138 
0139     /**
0140      * Constructor for an in-place anchor.
0141      * @param shape the anchored shape that this anchor links to.
0142      */
0143     explicit KoShapeAnchor(KoShape *shape);
0144     virtual ~KoShapeAnchor();
0145 
0146     /**
0147      * Return the shape that is linked to from the text anchor.
0148      */
0149     KoShape *shape() const;
0150 
0151     /**
0152      * Returns the type of the anchor.
0153      *
0154      * The text:anchor-type attribute specifies how a frame is bound to a
0155      * text document. The anchor position is the point at which a frame is
0156      * bound to a text document. The defined values for the text:anchor-type
0157      * attribute are;
0158      *
0159      * - as-char
0160      *   There is no anchor position. The drawing shape behaves like a
0161      *   character.
0162      * - char
0163      *   The character after the drawing shape element.
0164      * - frame
0165      *   The parent text box that the current drawing shape element is
0166      *   contained in.
0167      *  FIXME we don't support type frame
0168      * - page
0169      *   The page that has the same physical page number as the value of the
0170      *   text:anchor-page-number attribute that is attached to the drawing
0171      *   shape element.
0172      * - paragraph
0173      *   The paragraph that the current drawing shape element is contained in.
0174      */
0175     AnchorType anchorType() const;
0176 
0177     /**
0178      * Set how the anchor behaves
0179      */
0180     void setAnchorType(AnchorType type);
0181 
0182     /// set the current vertical-pos
0183     void setHorizontalPos(HorizontalPos);
0184 
0185     /// return the current vertical-pos
0186     HorizontalPos horizontalPos() const;
0187 
0188     /// set the current vertical-rel
0189     void setHorizontalRel(HorizontalRel);
0190 
0191     /// return the current vertical-rel
0192     HorizontalRel horizontalRel() const;
0193 
0194     /// set the current horizontal-pos
0195     void setVerticalPos(VerticalPos);
0196 
0197     /// return the current horizontal-pos
0198     VerticalPos verticalPos() const;
0199 
0200     /// set the current horizontal-rel
0201     void setVerticalRel(VerticalRel);
0202 
0203     /// return the current horizontal-rel
0204     VerticalRel verticalRel() const;
0205 
0206     /// return the wrap influence on position
0207     QString wrapInfluenceOnPosition() const;
0208 
0209     /// return if flow-with-text (odf attribute)
0210     bool flowWithText() const;
0211 
0212     /// return the page number of the shape (valid with page anchoring, -1 indicates auto).
0213     int pageNumber() const;
0214 
0215     /// return the offset of the shape from the anchor.
0216     const QPointF &offset() const;
0217 
0218     /// set the new offset of the shape. Causes a new layout soon.
0219     void setOffset(const QPointF &offset);
0220 
0221     /// Get extra data structure that is what is actually inside a text document
0222     TextLocation *textLocation() const;
0223 
0224     /// Set extra data structure that is what is actually inside a text document
0225     /// We do NOT take ownership (may change in the future)
0226     void setTextLocation(TextLocation *textLocation);
0227 
0228     /// Get placement strategy which is used to position shape linked to text anchor
0229     PlacementStrategy *placementStrategy() const;
0230 
0231     /// Set placement strategy which is used to position shape linked to text anchor
0232     /// We take owner ship and will make sure the strategy is deleted
0233     void setPlacementStrategy(PlacementStrategy *placementStrategy);
0234 
0235 private:
0236     class Private;
0237     Private * const d;
0238 };
0239 
0240 #endif