1 /* This file is part of the KDE project
2  * Copyright (C) 2006-2009 Thomas Zander <zander@kde.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 #ifndef KOINLINEOBJECTBASE_H
20 #define KOINLINEOBJECTBASE_H
21 
22 #include "kotext_export.h"
23 #include <KoXmlReaderForward.h>
24 
25 #include <QObject>
26 #include <QTextInlineObject>
27 
28 class QVariant;
29 class QTextDocument;
30 class QTextCharFormat;
31 class QPaintDevice;
32 class QPainter;
33 class QRectF;
34 
35 class KoInlineTextObjectManager;
36 class KoInlineObjectPrivate;
37 class KoShapeSavingContext;
38 class KoTextInlineRdf;
39 class KoShapeLoadingContext;
40 
41 /**
42  * Base class for all inline-text-objects.
43  *
44  * In a TextShape you can insert objects that move with the text.
45  * They are essentially anchored to a specific position in the text, as
46  * one character.
47  *
48  * @see KoInlineTextObjectManager
49  */
50 class KOTEXT_EXPORT KoInlineObject : public QObject
51 {
52     Q_OBJECT
53 public:
54     enum Property {
55         DocumentURL,
56         PageCount,
57         AuthorName,
58         SenderEmail,
59         SenderCompany,
60         SenderPhoneWork,
61         SenderPhonePrivate,
62         SenderFax,
63         SenderCountry,
64         Title,
65         Keywords,
66         Subject,
67         Description,
68         Comments,
69         SenderPostalCode,
70         SenderCity,
71         SenderStreet,
72         SenderTitle,
73         SenderFirstname,
74         SenderLastname,
75         SenderPosition,
76         AuthorInitials,
77         Chapter, ///< Chapter (number, name, number and name, plain number, plain number and name) variables.
78 
79         KarbonStart = 1000,      ///< Base number for Karbon specific values.
80         KexiStart = 2000,        ///< Base number for Kexi specific values.
81         FlowStart = 3000,        ///< Base number for Flow specific values.
82         PlanStart = 4000,        ///< Base number for Plan specific values.
83         StageStart = 5000,       ///< Base number for Stage specific values.
84         WordsStart = 6000,       ///< Base number for Words specific values.
85         VariableManagerStart = 7000, ///< Start of numbers reserved for the KoVariableManager
86         UserGet = 12000,         ///< User defined variable user-field-get
87         UserInput = 12001        ///< User defined variable user-field-input
88     };
89 
90     /**
91      * constructor
92      * @param propertyChangeListener if set to true this instance will be notified of changes of properties.
93      * @see KoInlineTextObjectManager::setProperty()
94      * @see propertyChangeListener()
95      */
96     explicit KoInlineObject(bool propertyChangeListener = false);
97     ~KoInlineObject() override;
98 
99     /**
100      * Will be called by the manager when this variable is added.
101      * Remember that inheriting classes should not use the manager() in the constructor, since it will be 0
102      * @param manager the object manager for this object.
103      */
104     void setManager(KoInlineTextObjectManager *manager);
105 
106     /**
107      * Return the object manager set on this inline object.
108      */
109     KoInlineTextObjectManager *manager() const;
110 
111     /**
112      * Just prior to the first time this object will be shown this method will be called.
113      * The object plugin should reimplement this to initialize the object after the manager
114      * has been set, but before the text has been layouted.
115      * The default implementation does nothing.
116      */
setup()117     virtual void setup() {}
118 
119     /**
120      * Save this inlineObject as ODF
121      * @param context the context for saving.
122      */
123     virtual void saveOdf(KoShapeSavingContext &context) = 0;
124 
125     /**
126      * Update position of the inline object.
127      * This is called each time the paragraph this inline object is in is re-layouted giving you the opportunity
128      * to reposition your object based on the new information.
129      * @param document the text document this inline object is operating on.
130      * @param posInDocument the character position in the document (param document) this inline object is at.
131      * @param format the character format for the inline object.
132      */
133     virtual void updatePosition(const QTextDocument *document, int posInDocument, const QTextCharFormat &format) = 0;
134 
135     /**
136      * Update the size of the inline object.
137      * Each time the text is painted, as well as when the paragraph this variable is in, this method
138      * is called. You should alter the size of the object if the content has changed.
139      * Altering the size is done by altering the 'object' parameter using QTextInlineObject::setWidth(),
140      * QTextInlineObject::setAscent() and QTextInlineObject::setDescent() methods.
141      * Note that this method is called while painting; and thus is time sensitive; avoid doing anything time
142      * consuming.
143      * Note make sure that the width is 0 when there is nothing to be shown for the object.
144      * @param document the text document this inline object is operating on.
145      * @param object the inline object properties
146      * @param posInDocument the character position in the document (param document) this inline object is at.
147      * @param format the character format for the inline object.
148      * @param pd the postscript-paintdevice that all text is rendered on. Use this for QFont and related
149      *  classes so the inline object can be reused on any paintdevice.
150      */
151     virtual void resize(const QTextDocument *document, QTextInlineObject &object,
152                         int posInDocument, const QTextCharFormat &format, QPaintDevice *pd) = 0;
153 
154     /**
155      * Paint the inline-object-base using the provided painter within the rectangle specified by rect.
156      * @param document the text document this inline object is operating on.
157      * @param object the inline object properties
158      * @param posInDocument the character position in the document (param document) this inline object is at.
159      * @param format the character format for the inline object.
160      * @param pd the postscript-paintdevice that all text is rendered on. Use this for QFont and related
161      *  classes so the inline object can be reused on any paintdevice.
162      * @param painter the painting object to paint on.  Note that unline many places in calligra painting
163      *    should happen at the position indicated by the rect, not at top-left.
164      * @param rect the rectangle inside which the variable can paint itself.  Painting outside the rect
165      *    will give various problems with regards to repainting issues.
166      */
167     virtual void paint(QPainter &painter, QPaintDevice *pd, const QTextDocument *document,
168                        const QRectF &rect, const QTextInlineObject &object, int posInDocument, const QTextCharFormat &format) = 0;
169 
170     /**
171      * Overwrite this if you are interested in propertychanges.
172      * @param property the property id that has been changed, one from the Property enum.
173      *    You should ignore all properties you don't use as new properties can be added at any time.
174      * @param value the new value of the property wrapped in a QVariant.  Properties can be a lot of
175      *     different class types. Ints, bools, QStrings etc.
176      * example:
177      * @code
178      *  void KoDateVariable::propertyChanged(Property key, const QVariant &value) {
179      *      if(key == KoInlineObject::PageCount)
180      *          setValue(QString::number(value.toInt()));
181      *  }
182      * @endcode
183      * @see propertyChangeListener()
184      */
185     virtual void propertyChanged(Property property, const QVariant &value);
186 
187     /// return the inline-object Id that is assigned for this object.
188     int id() const;
189 
190     /// Set the inline-object Id that is assigned for this object by the KoInlineTextObjectManager.
191     void setId(int id);
192 
193     /**
194      * When true, notify this object of property changes.
195      * Each inlineObject can use properties like the PageCount or the document name.
196      * Only objects that actually have a need for such information be a listener to avoid unneeded
197      * overhead.
198      * When this returns true, the propertyChanged() method will be called.
199      * @see KoInlineTextObjectManager::setProperty()
200      */
201     bool propertyChangeListener() const;
202 
203     /**
204      * An inline object might have some Rdf metadata associated with it
205      * in content.xml
206      * Ownership of the rdf object is taken by this object, you should not
207      * delete it.
208      */
209     void setInlineRdf(KoTextInlineRdf *rdf);
210     /**
211      * Get any Rdf which was stored in content.xml for this inline object
212      * This object continues to own the object, do not delete it.
213      */
214     KoTextInlineRdf *inlineRdf() const;
215 
216     /**
217      * Load a variable from odf.
218      *
219      * @param element element which represents the shape in odf
220      * @param context the KoShapeLoadingContext used for loading
221      *
222      * @return false if loading failed
223      */
224     virtual bool loadOdf(const KoXmlElement &element, KoShapeLoadingContext &context) =  0;
225 
226 protected:
227     explicit KoInlineObject(KoInlineObjectPrivate &, bool propertyChangeListener = false);
228 
229     KoInlineObjectPrivate *d_ptr;
230 
231 private:
232     Q_DECLARE_PRIVATE(KoInlineObject)
233     friend KOTEXT_EXPORT QDebug operator<<(QDebug, const KoInlineObject *);
234 };
235 
236 KOTEXT_EXPORT QDebug operator<<(QDebug dbg, const KoInlineObject *o);
237 
238 #endif
239