1 /* This file is part of the KDE project
2  * Copyright (C) 2007, 2009 Thomas Zander <zander@kde.org>
3  * Copyright (C) 2011 Matus Hanzes <matus.hanzes@ixonos.com>
4  * Copyright (C) 2013 C. Boemann <cbo@boemann.dk>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 #ifndef KOSHAPEANCHOR_H
22 #define KOSHAPEANCHOR_H
23 
24 #include "flake_export.h"
25 
26 
27 class KoShape;
28 class KoXmlElement;
29 class KoShapeLoadingContext;
30 class KoShapeSavingContext;
31 class KoShapeAnchorPrivate;
32 
33 class QTextDocument;
34 class QPointF;
35 class QString;
36 
37 /**
38  * This class is the object that explains how a shape is anchored to something.
39  *
40  * The anchored shape will be positioned (in supporting applications) based on the properties
41  * defined in this class.
42  *
43  * This class can be used in three different ways:
44  *  -page anchor
45  *  -as-char
46  *  -char, paragraph anchor
47  *
48  * If it's a page anchor it just provide the info about how the shape relates to a page with a specific
49  * page number.
50  *
51  * For the other types of anchoring it has to have a TextLocation in a QTextDocument. This TextLocation
52  * can either be an inline character (type as-char) or a position (type char or paragraph) The
53  * KoShapeAnchor and TextLocation connects the anchored-shape to the text flow so the anchored shape
54  * can be repositioned on the canvas if new text is inserted or removed before the anchor character.
55  *
56  * For as-char, char and paragraph use cases:
57  * @see KoAnchorInlineObject
58  * @see KoAnchorTextRange
59  * which are both implemented as subclasses of TextLocation
60  *
61  * The position of the shape relative to the anchor is called the offset. It's loaded by loadOdf().
62  * @see PlacementStrategy for more information about the layout of anchors/shapes.
63  */
64 class FLAKE_EXPORT KoShapeAnchor
65 {
66 public:
67     /**
68     * This class is an interface that positions the shape linked to text anchor
69     */
70     class PlacementStrategy {
71     public:
PlacementStrategy()72         PlacementStrategy(){};
~PlacementStrategy()73         virtual ~PlacementStrategy(){};
74 
75         /**
76          * Reparent the anchored shape to not have a parent shape container (and model)
77          *
78          */
79         virtual void detachFromModel() = 0;
80 
81         /**
82          * Reparent the anchored shape under an appropriate shape container (and model)
83          *
84          * If needed, it changes the parent KoShapeContainerModel and KoShapeContainer of the anchored
85          * shape.
86          */
87         virtual void updateContainerModel() = 0;
88     };
89 
90     class TextLocation {
91     public:
TextLocation()92         TextLocation(){};
~TextLocation()93         virtual ~TextLocation(){};
94         virtual const QTextDocument *document() const = 0;
95         virtual int position() const = 0;
96     };
97 
98     enum HorizontalPos {
99         HCenter,
100         HFromInside,
101         HFromLeft,
102         HInside,
103         HLeft,
104         HOutside,
105         HRight
106     };
107 
108     enum HorizontalRel { //NOTE: update KWAnchoringProperties if you change this
109         HChar,
110         HPage,
111         HPageContent,
112         HPageStartMargin,
113         HPageEndMargin,
114         HFrame,
115         HFrameContent,
116         HFrameEndMargin,
117         HFrameStartMargin,
118         HParagraph,
119         HParagraphContent,
120         HParagraphEndMargin,
121         HParagraphStartMargin
122     };
123 
124     enum VerticalPos {
125         VBelow,
126         VBottom,
127         VFromTop,
128         VMiddle,
129         VTop
130     };
131 
132     enum VerticalRel { //NOTE: update KWAnchoringProperties if you change this
133         VBaseline,
134         VChar,
135         VFrame,
136         VFrameContent,
137         VLine,
138         VPage,
139         VPageContent,
140         VParagraph,
141         VParagraphContent,
142         VText
143     };
144 
145     enum AnchorType {
146         AnchorAsCharacter,
147         AnchorToCharacter,
148         AnchorParagraph,
149         AnchorPage
150     };
151 
152     /**
153      * Constructor for an in-place anchor.
154      * @param shape the anchored shape that this anchor links to.
155      */
156     explicit KoShapeAnchor(KoShape *shape);
157     virtual ~KoShapeAnchor();
158 
159     /**
160      * Return the shape that is linked to from the text anchor.
161      */
162     KoShape *shape() const;
163 
164     /**
165      * Returns the type of the anchor.
166      *
167      * The text:anchor-type attribute specifies how a frame is bound to a
168      * text document. The anchor position is the point at which a frame is
169      * bound to a text document. The defined values for the text:anchor-type
170      * attribute are;
171      *
172      * - as-char
173      *   There is no anchor position. The drawing shape behaves like a
174      *   character.
175      * - char
176      *   The character after the drawing shape element.
177      * - frame
178      *   The parent text box that the current drawing shape element is
179      *   contained in.
180      *  FIXME we don't support type frame
181      * - page
182      *   The page that has the same physical page number as the value of the
183      *   text:anchor-page-number attribute that is attached to the drawing
184      *   shape element.
185      * - paragraph
186      *   The paragraph that the current drawing shape element is contained in.
187      */
188     AnchorType anchorType() const;
189 
190     /**
191      * Set how the anchor behaves
192      */
193     void setAnchorType(AnchorType type);
194 
195     /// set the current vertical-pos
196     void setHorizontalPos(HorizontalPos);
197 
198     /// return the current vertical-pos
199     HorizontalPos horizontalPos() const;
200 
201     /// set the current vertical-rel
202     void setHorizontalRel(HorizontalRel);
203 
204     /// return the current vertical-rel
205     HorizontalRel horizontalRel() const;
206 
207     /// set the current horizontal-pos
208     void setVerticalPos(VerticalPos);
209 
210     /// return the current horizontal-pos
211     VerticalPos verticalPos() const;
212 
213     /// set the current horizontal-rel
214     void setVerticalRel(VerticalRel);
215 
216     /// return the current horizontal-rel
217     VerticalRel verticalRel() const;
218 
219     /// return the wrap influence on position
220     QString wrapInfluenceOnPosition() const;
221 
222     /// return if flow-with-text (odf attribute)
223     bool flowWithText() const;
224 
225     /// return the page number of the shape (valid with page anchoring, -1 indicates auto).
226     int pageNumber() const;
227 
228     /// return the offset of the shape from the anchor.
229     const QPointF &offset() const;
230 
231     /// set the new offset of the shape. Causes a new layout soon.
232     void setOffset(const QPointF &offset);
233 
234     /// Load the additional attributes.
235     /// This will also make the shape invisible so it doesn't mess up any layout
236     /// before it's ready to be placed where it belongs
237     /// The textlayout should make it visible again
238     bool loadOdf(const KoXmlElement &element, KoShapeLoadingContext &context);
239 
240     /// Save the additional attributes.
241     void saveOdf(KoShapeSavingContext &context) const;
242 
243     /// Get extra data structure that is what is actually inside a text document
244     TextLocation *textLocation() const;
245 
246     /// Set extra data structure that is what is actually inside a text document
247     /// We do NOT take ownership (may change in the future)
248     void setTextLocation(TextLocation *textLocation);
249 
250     /// Get placement strategy which is used to position shape linked to text anchor
251     PlacementStrategy *placementStrategy() const;
252 
253     /// Set placement strategy which is used to position shape linked to text anchor
254     /// We take owner ship and will make sure the strategy is deleted
255     void setPlacementStrategy(PlacementStrategy *placementStrategy);
256 
257 private:
258     class Private;
259     Private * const d;
260 };
261 
262 #endif
263