signature.h 8.94 KB
Newer Older
1
/*
2
3
4
    SPDX-FileCopyrightText: 2002-2004 Marc Mutz <mutz@kde.org>
    SPDX-FileCopyrightText: 2007 Tom Albers <tomalbers@kde.nl>
    SPDX-FileCopyrightText: 2009 Thomas McGuire <mcguire@kde.org>
5
6
    Author: Stefan Taferner <taferner@kde.org>

7
    SPDX-License-Identifier: LGPL-2.0-or-later
8
9
*/

10
#pragma once
11

Laurent Montel's avatar
Laurent Montel committed
12
#include "kidentitymanagement_export.h"
13

Laurent Montel's avatar
Laurent Montel committed
14
#include <QHash>
Laurent Montel's avatar
Laurent Montel committed
15
#include <QImage>
Laurent Montel's avatar
Laurent Montel committed
16
17
#include <QList>
#include <QString>
18

Laurent Montel's avatar
Laurent Montel committed
19
20
namespace KIdentityManagement
{
Laurent Montel's avatar
Laurent Montel committed
21
22
class Signature;
class Identity;
23
24
25
}
class KConfigGroup;

Laurent Montel's avatar
Laurent Montel committed
26
27
namespace KPIMTextEdit
{
Laurent Montel's avatar
Laurent Montel committed
28
class RichTextComposer;
29
30
}

Laurent Montel's avatar
Laurent Montel committed
31
32
namespace KIdentityManagement
{
33
class SignaturePrivate;
Laurent Montel's avatar
Laurent Montel committed
34
35
KIDENTITYMANAGEMENT_EXPORT QDataStream &operator<<(QDataStream &stream, const KIdentityManagement::Signature &sig);
KIDENTITYMANAGEMENT_EXPORT QDataStream &operator>>(QDataStream &stream, KIdentityManagement::Signature &sig);
Laurent Montel's avatar
Laurent Montel committed
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

/**
 * @short Abstraction of a signature (aka "footer").
 *
 * The signature can either be plain text, HTML text, text returned from a command or text stored
 * in a file.
 *
 * In case of HTML text, the signature can contain images.
 * Since you set the HTML source with setText(), there also needs to be a way to add the images
 * to the signature, as the HTML source contains only the img tags that reference those images.
 * To add the image to the signature, call addImage(). The name given there must match the name
 * of the img tag in the HTML source.
 *
 * The images need to be stored somewhere. The Signature class handles that by storing all images
 * in a directory. You must set that directory with setImageLocation(), before calling addImage().
 * The images added with addImage() are then saved to that directory when calling writeConfig().
 * When loading a signature, readConfig() automatically loads the images as well.
 * To actually add the images to a text edit, call insertIntoTextEdit().
 *
 * Example of creating a HTML signature and then inserting it into a text edit:
 * @code
 * Signature htmlSig;
 * htmlSig.setText( "<img src=\"hello.png\"> World" );
 * htmlSig.setInlinedHtml( true );
 * htmlSig.setImageLocation( KStandardDirs::locateLocal( "data", "emailidentities/example/" );
 * QImage image = ...;
 * htmlSig.addImage( image, "hello.png" );
 * ...
 * KTextEdit edit;
Laurent Montel's avatar
Laurent Montel committed
65
66
 * htmlSig.insertIntoTextEdit( KIdentityManagement::Signature::End,
 *                             KIdentityManagement::Signature::AddSeparator, &edit );
Laurent Montel's avatar
Laurent Montel committed
67
68
 * @endcode
 */
Laurent Montel's avatar
Laurent Montel committed
69
class KIDENTITYMANAGEMENT_EXPORT Signature
Laurent Montel's avatar
Laurent Montel committed
70
71
72
{
    friend class Identity;

Laurent Montel's avatar
Laurent Montel committed
73
74
    friend KIDENTITYMANAGEMENT_EXPORT QDataStream &operator<<(QDataStream &stream, const Signature &sig);
    friend KIDENTITYMANAGEMENT_EXPORT QDataStream &operator>>(QDataStream &stream, Signature &sig);
Laurent Montel's avatar
Laurent Montel committed
75
76
77

public:
    /** Type of signature (ie. way to obtain the signature text) */
Laurent Montel's avatar
Laurent Montel committed
78
    enum Type { Disabled = 0, Inlined = 1, FromFile = 2, FromCommand = 3 };
79

Laurent Montel's avatar
Laurent Montel committed
80
81
82
83
84
    /**
     * Describes the placement of the signature text when it is to be inserted into a
     * text edit
     */
    enum Placement {
Laurent Montel's avatar
Laurent Montel committed
85
86
87
        Start, ///< The signature is placed at the start of the textedit
        End, ///< The signature is placed at the end of the textedit
        AtCursor ///< The signature is placed at the current cursor position
Laurent Montel's avatar
Laurent Montel committed
88
89
    };

Laurent Montel's avatar
Laurent Montel committed
90
91
92
93
    struct EmbeddedImage {
        QImage image;
        QString name;
    };
Laurent Montel's avatar
Laurent Montel committed
94
    using EmbeddedImagePtr = QSharedPointer<EmbeddedImage>;
Laurent Montel's avatar
Laurent Montel committed
95

Laurent Montel's avatar
Laurent Montel committed
96
    /** Used for comparison */
Laurent Montel's avatar
Laurent Montel committed
97
    bool operator==(const Signature &other) const;
Laurent Montel's avatar
Laurent Montel committed
98
99
100
101

    /** Constructor for disabled signature */
    Signature();
    /** Constructor for inline text */
102
    Signature(const QString &text);
Laurent Montel's avatar
Laurent Montel committed
103
    /** Constructor for text from a file or from output of a command */
Laurent Montel's avatar
Fix api    
Laurent Montel committed
104
    Signature(const QString &path, bool isExecutable);
Laurent Montel's avatar
Laurent Montel committed
105
106
107
    /** Copy constructor */
    Signature(const Signature &that);
    /** Assignment operator */
Laurent Montel's avatar
Laurent Montel committed
108
    Signature &operator=(const Signature &that);
Laurent Montel's avatar
Laurent Montel committed
109
110
111
112
113
114
    /** Destructor */
    ~Signature();

    /** @return the raw signature text as entered resp. read from file.
        @param ok set to @c true if reading succeeded
     */
Laurent Montel's avatar
Laurent Montel committed
115
    Q_REQUIRED_RESULT QString rawText(bool *ok = nullptr) const;
Laurent Montel's avatar
Laurent Montel committed
116
117
118
119
120

    /** @return the signature text with a "-- \n" separator added, if
        necessary. A newline will not be appended or prepended.
        @param ok set to @c true if reading succeeded
     */
Laurent Montel's avatar
Laurent Montel committed
121
    Q_REQUIRED_RESULT QString withSeparator(bool *ok = nullptr) const;
Laurent Montel's avatar
Laurent Montel committed
122
123
124
125

    /** Set the signature text and mark this signature as being of
        "inline text" type. */
    void setText(const QString &text);
Laurent Montel's avatar
Laurent Montel committed
126
    Q_REQUIRED_RESULT QString text() const;
Laurent Montel's avatar
Laurent Montel committed
127
128
129
130
131
132

    /**
     * Returns the text of the signature. If the signature is HTML, the HTML
     * tags will be stripped.
     * @since 4.4
     */
Laurent Montel's avatar
Laurent Montel committed
133
    Q_REQUIRED_RESULT QString toPlainText() const;
Laurent Montel's avatar
Laurent Montel committed
134
135
136

    /** Set the signature URL and mark this signature as being of
        "from file" resp. "from output of command" type. */
Laurent Montel's avatar
Fix api    
Laurent Montel committed
137
    void setPath(const QString &path, bool isExecutable = false);
Laurent Montel's avatar
Laurent Montel committed
138
    Q_REQUIRED_RESULT QString path() const;
Laurent Montel's avatar
Laurent Montel committed
139
140

    /// @return the type of signature (ie. way to obtain the signature text)
Laurent Montel's avatar
Laurent Montel committed
141
    Q_REQUIRED_RESULT Type type() const;
Laurent Montel's avatar
Laurent Montel committed
142
143
144
145
146
147
148
149
150
151
152
153
154
    void setType(Type type);

    /**
     * Sets the inlined signature to text or html
     * @param isHtml sets the inlined signature to html
     * @since 4.1
     */
    void setInlinedHtml(bool isHtml);

    /**
     * @return boolean whether the inlined signature is html
     * @since 4.1
     */
Laurent Montel's avatar
Laurent Montel committed
155
    Q_REQUIRED_RESULT bool isInlinedHtml() const;
Laurent Montel's avatar
Laurent Montel committed
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

    /**
     * Sets the location where the copies of the signature images will be stored.
     * The images will be stored there when calling writeConfig(). The image location
     * is stored in the config, so the next readConfig() call knows where to look for
     * images.
     * It is recommended to use KStandardDirs::locateLocal( "data", "emailidentities/%1" )
     * for the location, where %1 is the unique identifier of the identity.
     *
     * @warning readConfig will delete all other PNG files in this directory, as they could
     *          be stale inline image files
     *
     * Like with addImage(), the SignatureConfigurator will handle this for you.
     * @param path the path to set as image location
     * @since 4.4
     */
    void setImageLocation(const QString &path);
Laurent Montel's avatar
Laurent Montel committed
173
    Q_REQUIRED_RESULT QString imageLocation() const;
Laurent Montel's avatar
Laurent Montel committed
174

Laurent Montel's avatar
Laurent Montel committed
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
    /**
     * Adds the given image to the signature.
     * This is needed if you use setText() to set some HTML source that references images. Those
     * referenced images needed to be added by calling this function. The @imageName has to match
     * the src attribute of the img tag.
     *
     * If you use SignatureConfigurator, you don't need to call this function, as the configurator
     * will handle this for you.
     * setImageLocation() needs to be called once before.
     * @since 4.4
     */
    void addImage(const QImage &image, const QString &imageName);

    /**
     * @brief setEnabledSignature
     * @param enabled enables signature if set as @c true
     * @since 4.9
     */
    void setEnabledSignature(bool enabled);
Laurent Montel's avatar
Laurent Montel committed
194
    Q_REQUIRED_RESULT bool isEnabledSignature() const;
Laurent Montel's avatar
Laurent Montel committed
195
196

    enum AddedTextFlag {
Laurent Montel's avatar
Laurent Montel committed
197
198
        AddNothing = 0, ///< Don't add any text to the signature
        AddSeparator = 1 << 0, ///< The separator '-- \n' will be added in front
Laurent Montel's avatar
Laurent Montel committed
199
        ///  of the signature
Laurent Montel's avatar
Laurent Montel committed
200
201
        AddNewLines = 1 << 1 ///< Add a newline character in front or after the signature,
                             ///  depending on the placement
Laurent Montel's avatar
Laurent Montel committed
202
203
204
    };

    /// Describes which additional parts should be added to the signature
Laurent Montel's avatar
Laurent Montel committed
205
    using AddedText = QFlags<AddedTextFlag>;
Laurent Montel's avatar
Laurent Montel committed
206
207

    /** Inserts this signature into the given text edit.
Laurent Montel's avatar
Laurent Montel committed
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
     * If the signature is inserted at the beginning, a couple of new
     * lines will be inserted before it, and the cursor is moved to
     * the beginning. Otherwise, the cursor position is preserved.
     * For undo/redo, this is treated as one operation.
     *
     * Rich text mode of the text edit will be enabled if the signature is in
     * inlined HTML format.
     *
     * If this signature uses images, they will be added automatically.
     *
     * @param placement defines where in the text edit the signature should be
     *                  inserted.
     * @param addedText defines which other texts should be added to the signature
     * @param textEdit the signature will be inserted into this text edit.
     *
     * @since 4.9
     */
Laurent Montel's avatar
Laurent Montel committed
225
226
    // TODO: KDE5: BIC: Reorder parameters, the order here is a workaround for ambiguous parameters
    //                  with the deprecated method
Laurent Montel's avatar
Laurent Montel committed
227
    void insertIntoTextEdit(Placement placement, AddedText addedText, KPIMTextEdit::RichTextComposer *textEdit, bool forceDisplay = false) const;
Laurent Montel's avatar
Laurent Montel committed
228

Laurent Montel's avatar
Laurent Montel committed
229
230
    Q_REQUIRED_RESULT QVector<Signature::EmbeddedImagePtr> embeddedImages() const;
    void setEmbeddedImages(const QVector<EmbeddedImagePtr> &embedded);
Laurent Montel's avatar
Laurent Montel committed
231

Laurent Montel's avatar
Laurent Montel committed
232
233
234
235
236
237
protected:
    // TODO: KDE5: BIC: Move all to private class
    void writeConfig(KConfigGroup &config) const;
    void readConfig(const KConfigGroup &config);

private:
Laurent Montel's avatar
Laurent Montel committed
238
    //@cond PRIVATE
239
    SignaturePrivate *const d;
Laurent Montel's avatar
Laurent Montel committed
240
    //@endcond
Laurent Montel's avatar
Laurent Montel committed
241
242
243
};

Q_DECLARE_OPERATORS_FOR_FLAGS(Signature::AddedText)
244
245
}