1/*
2 Copyright (c) 2002-2004 Marc Mutz <mutz@kde.org>
3 Copyright (c) 2007 Tom Albers <tomalbers@kde.nl>
4 Copyright (c) 2009 Thomas McGuire <mcguire@kde.org>
5 Author: Stefan Taferner <taferner@kde.org>
6
7 This library is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Library General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or (at your
10 option) any later version.
11
12 This library is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
15 License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA.
21*/
22
23#ifndef KPIMIDENTITIES_SIGNATURE_H
24#define KPIMIDENTITIES_SIGNATURE_H
25
26#include "kpimidentities_export.h"
27
28#include <kdemacros.h>
29
30#include <QtCore/QString>
31#include <QtCore/QStringList>
32#include <QtCore/QList>
33#include <QtCore/QHash>
34#include <QtCore/QVariant>
35
36namespace KPIMIdentities
37{
38 class Signature;
39 class Identity;
40}
41class KConfigGroup;
42class KRichTextEdit;
43
44namespace KPIMTextEdit
45{
46 class TextEdit;
47}
48
49namespace KPIMIdentities
50{
51
52 KPIMIDENTITIES_EXPORT QDataStream &operator<<
53 ( QDataStream &stream, const KPIMIdentities::Signature &sig );
54 KPIMIDENTITIES_EXPORT QDataStream &operator>>
55 ( QDataStream &stream, KPIMIdentities::Signature &sig );
56
57 /**
58 * @short Abstraction of a signature (aka "footer").
59 *
60 * The signature can either be plain text, HTML text, text returned from a command or text stored
61 * in a file.
62 *
63 * In case of HTML text, the signature can contain images.
64 * Since you set the HTML source with setText(), there also needs to be a way to add the images
65 * to the signature, as the HTML source contains only the img tags that reference those images.
66 * To add the image to the signature, call addImage(). The name given there must match the name
67 * of the img tag in the HTML source.
68 *
69 * The images need to be stored somewhere. The Signature class handles that by storing all images
70 * in a directory. You must set that directory with setImageLocation(), before calling addImage().
71 * The images added with addImage() are then saved to that directory when calling writeConfig().
72 * When loading a signature, readConfig() automatically loads the images as well.
73 * To actually add the images to a text edit, call insertIntoTextEdit().
74 *
75 * Example of creating a HTML signature and then inserting it into a text edit:
76 * @code
77 * Signature htmlSig;
78 * htmlSig.setText( "<img src=\"hello.png\"> World" );
79 * htmlSig.setInlinedHtml( true );
80 * htmlSig.setImageLocation( KStandardDirs::locateLocal( "data", "emailidentities/example/" );
81 * QImage image = ...;
82 * htmlSig.addImage( image, "hello.png" );
83 * ...
84 * KTextEdit edit;
85 * htmlSig.insertIntoTextEdit( KPIMIdentities::Signature::End,
86 * KPIMIdentities::Signature::AddSeparator, &edit );
87 * @endcode
88 */
89 class KPIMIDENTITIES_EXPORT Signature
90 {
91 friend class Identity;
92
93 friend KPIMIDENTITIES_EXPORT QDataStream &operator<< ( QDataStream &stream, const Signature &sig );
94 friend KPIMIDENTITIES_EXPORT QDataStream &operator>> ( QDataStream &stream, Signature &sig );
95
96 public:
97 /** Type of signature (ie. way to obtain the signature text) */
98 enum Type {
99 Disabled = 0,
100 Inlined = 1,
101 FromFile = 2,
102 FromCommand = 3
103 };
104
105 /**
106 * Describes the placement of the signature text when it is to be inserted into a
107 * text edit
108 */
109 enum Placement {
110 Start, ///< The signature is placed at the start of the textedit
111 End, ///< The signature is placed at the end of the textedit
112 AtCursor ///< The signature is placed at the current cursor position
113 };
114
115 /** Used for comparison */
116 bool operator== ( const Signature &other ) const;
117
118 /** Constructor for disabled signature */
119 Signature();
120 /** Constructor for inline text */
121 Signature( const QString &text );
122 /** Constructor for text from a file or from output of a command */
123 Signature( const QString &url, bool isExecutable );
124 /** Copy constructor */
125 Signature( const Signature &that );
126 /** Assignment operator */
127 Signature& operator= ( const Signature &that );
128 /** Destructor */
129 ~Signature();
130
131 /** @return the raw signature text as entered resp. read from file.
132 @param ok set to @c true if reading succeeded
133 */
134 QString rawText( bool *ok=0 ) const;
135
136 /** @return the signature text with a "-- \n" separator added, if
137 necessary. A newline will not be appended or prepended.
138 @param ok set to @c true if reading succeeded
139 */
140 QString withSeparator( bool *ok=0 ) const;
141
142 /** Set the signature text and mark this signature as being of
143 "inline text" type. */
144 void setText( const QString &text );
145 QString text() const;
146
147 /**
148 * Returns the text of the signature. If the signature is HTML, the HTML
149 * tags will be stripped.
150 * @since 4.4
151 */
152 QString toPlainText() const;
153
154 /** Set the signature URL and mark this signature as being of
155 "from file" resp. "from output of command" type. */
156 void setUrl( const QString &url, bool isExecutable=false );
157 QString url() const;
158
159 /// @return the type of signature (ie. way to obtain the signature text)
160 Type type() const;
161 void setType( Type type );
162
163 /**
164 * Sets the inlined signature to text or html
165 * @param isHtml sets the inlined signature to html
166 * @since 4.1
167 */
168 void setInlinedHtml( bool isHtml );
169
170 /**
171 * @return boolean whether the inlined signature is html
172 * @since 4.1
173 */
174 bool isInlinedHtml() const;
175
176 /**
177 * Sets the location where the copies of the signature images will be stored.
178 * The images will be stored there when calling writeConfig(). The image location
179 * is stored in the config, so the next readConfig() call knows where to look for
180 * images.
181 * It is recommended to use KStandardDirs::locateLocal( "data", "emailidentities/%1" )
182 * for the location, where %1 is the unique identifier of the identity.
183 *
184 * @warning readConfig will delete all other PNG files in this directory, as they could
185 * be stale inline image files
186 *
187 * Like with addImage(), the SignatureConfigurator will handle this for you.
188 * @param path the path to set as image location
189 * @since 4.4
190 */
191 void setImageLocation( const QString &path );
192
193 /**
194 * Adds the given image to the signature.
195 * This is needed if you use setText() to set some HTML source that references images. Those
196 * referenced images needed to be added by calling this function. The @imageName has to match
197 * the src attribute of the img tag.
198 *
199 * If you use SignatureConfigurator, you don't need to call this function, as the configurator
200 * will handle this for you.
201 * setImageLocation() needs to be called once before.
202 * @since 4.4
203 */
204 void addImage( const QImage &image, const QString &imageName );
205
206
207 /**
208 * @brief setEnabledSignature
209 * @param enabled enables signature if set as @c true
210 * @since 4.9
211 */
212 void setEnabledSignature(bool enabled);
213 bool isEnabledSignature() const;
214
215 /**
216 * @since 4.3
217 * @deprecated Use the other overload of insertIntoTextEdit() instead. This one doesn't
218 * support inline images and always adds newline characters.
219 */
220 void KPIMIDENTITIES_DEPRECATED insertIntoTextEdit( KRichTextEdit *textEdit,
221 Placement placement = End, bool addSeparator = true );
222
223 enum AddedTextFlag {
224 AddNothing = 0, ///< Don't add any text to the signature
225 AddSeparator = 1 << 0, ///< The separator '-- \n' will be added in front
226 /// of the signature
227 AddNewLines = 1 << 1 ///< Add a newline character in front or after the signature,
228 /// depending on the placement
229 };
230
231 /// Describes which additional parts should be added to the signature
232 typedef QFlags<AddedTextFlag> AddedText;
233
234 /** Inserts this signature into the given text edit.
235 * The cursor position is preserved.
236 * For undo/redo, this is treated as one operation.
237 *
238 * Rich text mode of the text edit will be enabled if the signature is in
239 * inlined HTML format.
240 *
241 * If this signature uses images, they will be added automatically.
242 *
243 * @param placement defines where in the text edit the signature should be
244 * inserted.
245 * @param addedText defines which other texts should be added to the signature
246 * @param textEdit the signature will be inserted into this text edit.
247 *
248 * @since 4.4
249 */
250 // TODO: KDE5: BIC: Reorder parameters, the order here is a workaround for ambiguous parameters
251 // with the deprecated method
252 void insertIntoTextEdit( Placement placement, AddedText addedText,
253 KPIMTextEdit::TextEdit *textEdit ) const;
254
255 /**
256 * @since 4.9
257 **/
258 //TODO; KDE5 merge with previous method
259 void insertIntoTextEdit( Placement placement, AddedText addedText,
260 KPIMTextEdit::TextEdit *textEdit, bool forceDisplay ) const;
261
262 /**
263 * Inserts this given signature into the given text edit.
264 * The cursor position is preserved.
265 * A leading or trailing newline is also added automatically, depending on
266 * the placement.
267 * For undo/redo, this is treated as one operation.
268 * A separator is not added.
269 *
270 * Use the insertIntoTextEdit() function if possible, as it has support
271 * for separators and does HTML detection automatically.
272 *
273 * Rich text mode of the text edit will be enabled if @p isHtml is true.
274 *
275 * @param signature the signature, either as plain text or as HTML
276 * @param textEdit the text edit to insert the signature into
277 * @param placement defines where in the textedit the signature should be
278 * inserted.
279 * @param isHtml defines whether the signature should be inserted as text or html
280 *
281 * @since 4.3
282 * @deprecated Use the non-static insertIntoTextEdit() instead
283 */
284 static void KPIMIDENTITIES_DEPRECATED insertPlainSignatureIntoTextEdit( const QString &signature,
285 KRichTextEdit *textEdit,
286 Placement placement = End,
287 bool isHtml = false );
288
289 protected:
290
291 // TODO: KDE5: BIC: Move all to private class
292 void writeConfig( KConfigGroup &config ) const;
293 void readConfig( const KConfigGroup &config );
294
295 private:
296 void insertSignatureText(Placement placement, AddedText addedText, KPIMTextEdit::TextEdit *textEdit, bool forceDisplay) const;
297
298 // TODO: KDE5: BIC: Move all to private class
299
300 /**
301 * Helper used for the copy constructor and the assignment operator
302 */
303 void assignFrom( const Signature &that );
304
305 /**
306 * Clean up unused images from our internal list and delete all images
307 * from the file system
308 */
309 void cleanupImages() const;
310
311 /**
312 * Saves all images from our internal list to the file system.
313 */
314 void saveImages() const;
315
316 QString textFromFile( bool *ok ) const;
317 QString textFromCommand( bool *ok ) const;
318
319 // TODO: KDE5: BIC: Add a d-pointer!!!
320 // There is already a pseude private class in the .cpp, using a hash.
321 QString mUrl;
322 QString mText;
323 Type mType;
324 bool mInlinedHtml;
325 };
326
327 Q_DECLARE_OPERATORS_FOR_FLAGS( Signature::AddedText )
328
329}
330
331#endif /*kpim_signature_h*/
332