File indexing completed on 2024-05-19 05:17:28

0001 /*
0002     SPDX-FileCopyrightText: 2002-2004 Marc Mutz <mutz@kde.org>
0003     SPDX-FileCopyrightText: 2007 Tom Albers <tomalbers@kde.nl>
0004     SPDX-FileCopyrightText: 2009 Thomas McGuire <mcguire@kde.org>
0005     Author: Stefan Taferner <taferner@kde.org>
0006 
0007     SPDX-License-Identifier: LGPL-2.0-or-later
0008 */
0009 
0010 #pragma once
0011 
0012 #include "kidentitymanagementcore_export.h"
0013 
0014 #include <QImage>
0015 #include <QSharedPointer>
0016 #include <QString>
0017 #include <memory>
0018 
0019 class KConfigGroup;
0020 namespace KIdentityManagementCore
0021 {
0022 class Signature;
0023 class Identity;
0024 class SignaturePrivate;
0025 KIDENTITYMANAGEMENTCORE_EXPORT QDataStream &operator<<(QDataStream &stream, const KIdentityManagementCore::Signature &sig);
0026 KIDENTITYMANAGEMENTCORE_EXPORT QDataStream &operator>>(QDataStream &stream, KIdentityManagementCore::Signature &sig);
0027 
0028 /**
0029  * @short Abstraction of a signature (aka "footer").
0030  *
0031  * The signature can either be plain text, HTML text, text returned from a command or text stored
0032  * in a file.
0033  *
0034  * In case of HTML text, the signature can contain images.
0035  * Since you set the HTML source with setText(), there also needs to be a way to add the images
0036  * to the signature, as the HTML source contains only the img tags that reference those images.
0037  * To add the image to the signature, call addImage(). The name given there must match the name
0038  * of the img tag in the HTML source.
0039  *
0040  * The images need to be stored somewhere. The Signature class handles that by storing all images
0041  * in a directory. You must set that directory with setImageLocation(), before calling addImage().
0042  * The images added with addImage() are then saved to that directory when calling writeConfig().
0043  * When loading a signature, readConfig() automatically loads the images as well.
0044  * To actually add the images to a text edit, call insertIntoTextEdit().
0045  *
0046  * Example of creating a HTML signature and then inserting it into a text edit:
0047  * @code
0048  * Signature htmlSig;
0049  * htmlSig.setText( "<img src=\"hello.png\"> World" );
0050  * htmlSig.setInlinedHtml( true );
0051  * htmlSig.setImageLocation( KStandardDirs::locateLocal( "data", "emailidentities/example/" );
0052  * QImage image = ...;
0053  * htmlSig.addImage( image, "hello.png" );
0054  * ...
0055  * KTextEdit edit;
0056  * htmlSig.insertIntoTextEdit( KIdentityManagementCore::Signature::End,
0057  *                             KIdentityManagementCore::Signature::AddSeparator, &edit );
0058  * @endcode
0059  */
0060 class KIDENTITYMANAGEMENTCORE_EXPORT Signature
0061 {
0062     friend class Identity;
0063 
0064     friend KIDENTITYMANAGEMENTCORE_EXPORT QDataStream &operator<<(QDataStream &stream, const Signature &sig);
0065     friend KIDENTITYMANAGEMENTCORE_EXPORT QDataStream &operator>>(QDataStream &stream, Signature &sig);
0066 
0067 public:
0068     /** Type of signature (ie. way to obtain the signature text) */
0069     enum Type { Disabled = 0, Inlined = 1, FromFile = 2, FromCommand = 3 };
0070 
0071     /**
0072      * Describes the placement of the signature text when it is to be inserted into a
0073      * text edit
0074      */
0075     enum Placement {
0076         Start, ///< The signature is placed at the start of the textedit
0077         End, ///< The signature is placed at the end of the textedit
0078         AtCursor ///< The signature is placed at the current cursor position
0079     };
0080 
0081     struct EmbeddedImage {
0082         QImage image;
0083         QString name;
0084     };
0085     using EmbeddedImagePtr = QSharedPointer<EmbeddedImage>;
0086 
0087     /** Used for comparison */
0088     bool operator==(const Signature &other) const;
0089 
0090     /** Constructor for disabled signature */
0091     Signature();
0092     /** Constructor for inline text */
0093     Signature(const QString &text);
0094     /** Constructor for text from a file or from output of a command */
0095     Signature(const QString &path, bool isExecutable);
0096     /** Copy constructor */
0097     Signature(const Signature &that);
0098     /** Assignment operator */
0099     Signature &operator=(const Signature &that);
0100     /** Destructor */
0101     ~Signature();
0102 
0103     /** @return the raw signature text as entered resp. read from file.
0104         @param ok set to @c true if reading succeeded
0105         @param errorMessage If available, contains a human readable explanation for @p ok being @c false.
0106      */
0107     [[nodiscard]] QString rawText(bool *ok = nullptr, QString *errorMessage = nullptr) const;
0108 
0109     /** @return the signature text with a "-- \n" separator added, if
0110         necessary. A newline will not be appended or prepended.
0111         @param ok set to @c true if reading succeeded
0112         @param errorMessage If available, contains a human readable explanation for @p ok being @c false.
0113      */
0114     [[nodiscard]] QString withSeparator(bool *ok = nullptr, QString *errorMessage = nullptr) const;
0115 
0116     /** Set the signature text and mark this signature as being of
0117         "inline text" type. */
0118     void setText(const QString &text);
0119     [[nodiscard]] QString text() const;
0120 
0121     /**
0122      * Returns the text of the signature. If the signature is HTML, the HTML
0123      * tags will be stripped.
0124      * @since 4.4
0125      */
0126     [[nodiscard]] QString toPlainText() const;
0127 
0128     /** Set the signature URL and mark this signature as being of
0129         "from file" resp. "from output of command" type. */
0130     void setPath(const QString &path, bool isExecutable = false);
0131     [[nodiscard]] QString path() const;
0132 
0133     /// @return the type of signature (ie. way to obtain the signature text)
0134     [[nodiscard]] Type type() const;
0135     void setType(Type type);
0136 
0137     /**
0138      * Sets the inlined signature to text or html
0139      * @param isHtml sets the inlined signature to html
0140      * @since 4.1
0141      */
0142     void setInlinedHtml(bool isHtml);
0143 
0144     /**
0145      * @return boolean whether the inlined signature is html
0146      * @since 4.1
0147      */
0148     [[nodiscard]] bool isInlinedHtml() const;
0149 
0150     /**
0151      * Sets the location where the copies of the signature images will be stored.
0152      * The images will be stored there when calling writeConfig(). The image location
0153      * is stored in the config, so the next readConfig() call knows where to look for
0154      * images.
0155      * It is recommended to use KStandardDirs::locateLocal( "data", "emailidentities/%1" )
0156      * for the location, where %1 is the unique identifier of the identity.
0157      *
0158      * @warning readConfig will delete all other PNG files in this directory, as they could
0159      *          be stale inline image files
0160      *
0161      * Like with addImage(), the SignatureConfigurator will handle this for you.
0162      * @param path the path to set as image location
0163      * @since 4.4
0164      */
0165     void setImageLocation(const QString &path);
0166     [[nodiscard]] QString imageLocation() const;
0167 
0168     /**
0169      * Adds the given image to the signature.
0170      * This is needed if you use setText() to set some HTML source that references images. Those
0171      * referenced images needed to be added by calling this function. The @imageName has to match
0172      * the src attribute of the img tag.
0173      *
0174      * If you use SignatureConfigurator, you don't need to call this function, as the configurator
0175      * will handle this for you.
0176      * setImageLocation() needs to be called once before.
0177      * @since 4.4
0178      */
0179     void addImage(const QImage &image, const QString &imageName);
0180 
0181     /**
0182      * @brief setEnabledSignature
0183      * @param enabled enables signature if set as @c true
0184      * @since 4.9
0185      */
0186     void setEnabledSignature(bool enabled);
0187     [[nodiscard]] bool isEnabledSignature() const;
0188 
0189     enum AddedTextFlag {
0190         AddNothing = 0, ///< Don't add any text to the signature
0191         AddSeparator = 1 << 0, ///< The separator '-- \n' will be added in front
0192         ///  of the signature
0193         AddNewLines = 1 << 1 ///< Add a newline character in front or after the signature,
0194                              ///  depending on the placement
0195     };
0196 
0197     /// Describes which additional parts should be added to the signature
0198     using AddedText = QFlags<AddedTextFlag>;
0199 
0200     [[nodiscard]] QList<Signature::EmbeddedImagePtr> embeddedImages() const;
0201     void setEmbeddedImages(const QList<EmbeddedImagePtr> &embedded);
0202 
0203 protected:
0204     // TODO: KDE5: BIC: Move all to private class
0205     void writeConfig(KConfigGroup &config) const;
0206     void readConfig(const KConfigGroup &config);
0207 
0208 private:
0209     //@cond PRIVATE
0210     std::unique_ptr<SignaturePrivate> const d;
0211     //@endcond
0212 };
0213 
0214 Q_DECLARE_OPERATORS_FOR_FLAGS(Signature::AddedText)
0215 }