diff --git a/CMakeLists.txt b/CMakeLists.txt index 19dfe11e..cb3fe812 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,93 +1,93 @@ cmake_minimum_required(VERSION 3.5) -set(PIM_VERSION "5.14.40") +set(PIM_VERSION "5.14.41") project(KIdentityManagement VERSION ${PIM_VERSION}) # ECM setup set(KF5_MIN_VERSION "5.70.0") find_package(ECM ${KF5_MIN_VERSION} CONFIG REQUIRED) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) include(KDEInstallDirs) include(KDECMakeSettings) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(GenerateExportHeader) include(ECMGenerateHeaders) include(ECMGeneratePriFile) include(ECMSetupVersion) include(FeatureSummary) include(ECMQtDeclareLoggingCategory) set(KIDENTITYMANAGEMENT_LIB_VERSION ${PIM_VERSION}) set(PIMTEXTEDIT_LIB_VERSION "5.14.40") ecm_setup_version(PROJECT VARIABLE_PREFIX KIDENTITYMANAGEMENT VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/kidentitymanagement_version.h" PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5IdentityManagementConfigVersion.cmake" SOVERSION 5 ) ########### Find packages ########### find_package(Qt5Network NO_MODULE REQUIRED) find_package(KF5CoreAddons ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5TextWidgets ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5XmlGui ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5KIO ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5Config ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5Codecs ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5IconThemes ${KF5_MIN_VERSION} CONFIG REQUIRED) find_package(KF5PimTextEdit ${PIMTEXTEDIT_LIB_VERSION} CONFIG REQUIRED) add_definitions(-DTRANSLATION_DOMAIN=\"libkpimidentities5\") if (EXISTS "${CMAKE_SOURCE_DIR}/.git") add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050f00) add_definitions(-DKF_DISABLE_DEPRECATED_BEFORE_AND_AT=0x054700) endif() add_definitions(-DQT_NO_FOREACH) add_definitions(-DQT_NO_KEYWORDS) ########### Targets ########### add_subdirectory(src) if(BUILD_TESTING) add_subdirectory(autotests) endif() ########### CMake Config Files ########### set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/KF5IdentityManagement") configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/KF5IdentityManagementConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/KF5IdentityManagementConfig.cmake" INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/KF5IdentityManagementConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/KF5IdentityManagementConfigVersion.cmake" DESTINATION "${CMAKECONFIG_INSTALL_DIR}" COMPONENT Devel ) install(EXPORT KF5IdentityManagementTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE KF5IdentityManagementTargets.cmake NAMESPACE KF5:: ) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/kidentitymanagement_version.h DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5} COMPONENT Devel ) feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/src/signature.cpp b/src/signature.cpp index 1cee5eda..33aec581 100644 --- a/src/signature.cpp +++ b/src/signature.cpp @@ -1,659 +1,656 @@ /* Copyright (c) 2002-2004 Marc Mutz Copyright (c) 2007 Tom Albers Copyright (c) 2009 Thomas McGuire This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "signature.h" #include "kidentitymanagement_debug.h" #include #include #include #include #include #include #include #include #include #include #include using namespace KIdentityManagement; class Q_DECL_HIDDEN KIdentityManagement::SignaturePrivate { public: SignaturePrivate(Signature *qq) - : type(Signature::Disabled) - , enabled(false) - , inlinedHtml(false) - , q(qq) + : q(qq) { } void assignFrom(const KIdentityManagement::Signature &that); void cleanupImages(); void saveImages() const; - QString textFromFile(bool *ok) const; - QString textFromCommand(bool *ok) const; + Q_REQUIRED_RESULT QString textFromFile(bool *ok) const; + Q_REQUIRED_RESULT QString textFromCommand(bool *ok) const; void insertSignatureText(Signature::Placement placement, Signature::AddedText addedText, KPIMTextEdit::RichTextComposer *textEdit, bool forceDisplay) const; /// List of images that belong to this signature. Either added by addImage() or /// by readConfig(). - QList embeddedImages; + QVector embeddedImages; /// The directory where the images will be saved to. QString saveLocation; QString path; QString text; - Signature::Type type; + Signature::Type type = Signature::Disabled; bool enabled = false; bool inlinedHtml = false; Signature *q = nullptr; }; static bool isCursorAtEndOfLine(const QTextCursor &cursor) { QTextCursor testCursor = cursor; testCursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); return !testCursor.hasSelection(); } static void insertSignatureHelper(const QString &signature, KPIMTextEdit::RichTextComposer *textEdit, Signature::Placement placement, bool isHtml, bool addNewlines) { if (!signature.isEmpty()) { // Save the modified state of the document, as inserting a signature // shouldn't change this. Restore it at the end of this function. bool isModified = textEdit->document()->isModified(); // Move to the desired position, where the signature should be inserted QTextCursor cursor = textEdit->textCursor(); QTextCursor oldCursor = cursor; cursor.beginEditBlock(); if (placement == Signature::End) { cursor.movePosition(QTextCursor::End); } else if (placement == Signature::Start) { cursor.movePosition(QTextCursor::Start); } else if (placement == Signature::AtCursor) { cursor.movePosition(QTextCursor::StartOfLine); } textEdit->setTextCursor(cursor); QString lineSep; if (addNewlines) { if (isHtml) { lineSep = QStringLiteral("
"); } else { lineSep = QLatin1Char('\n'); } } // Insert the signature and newlines depending on where it was inserted. int newCursorPos = -1; QString headSep; QString tailSep; if (placement == Signature::End) { // There is one special case when re-setting the old cursor: The cursor // was at the end. In this case, QTextEdit has no way to know // if the signature was added before or after the cursor, and just // decides that it was added before (and the cursor moves to the end, // but it should not when appending a signature). See bug 167961 if (oldCursor.position() == textEdit->toPlainText().length()) { newCursorPos = oldCursor.position(); } headSep = lineSep; } else if (placement == Signature::Start) { // When prepending signatures, add a couple of new lines before // the signature, and move the cursor to the beginning of the QTextEdit. // People tends to insert new text there. newCursorPos = 0; headSep = lineSep + lineSep; if (!isCursorAtEndOfLine(cursor)) { tailSep = lineSep; } } else if (placement == Signature::AtCursor) { if (!isCursorAtEndOfLine(cursor)) { tailSep = lineSep; } } const QString full_signature = headSep + signature + tailSep; if (isHtml) { textEdit->insertHtml(full_signature); } else { textEdit->insertPlainText(full_signature); } cursor.endEditBlock(); if (newCursorPos != -1) { oldCursor.setPosition(newCursorPos); } textEdit->setTextCursor(oldCursor); textEdit->ensureCursorVisible(); textEdit->document()->setModified(isModified); if (isHtml) { textEdit->activateRichText(); } } } // Returns the names of all images in the HTML code static QStringList findImageNames(const QString &htmlCode) { QStringList ret; // To complicated for us, so cheat and let a text edit do the hard work KPIMTextEdit::RichTextComposer edit; edit.setHtml(htmlCode); const QList images = edit.composerControler()->composerImages()->imagesWithName(); ret.reserve(images.count()); for (const KPIMTextEdit::ImageWithNamePtr &image : images) { ret << image->name; } return ret; } void SignaturePrivate::assignFrom(const KIdentityManagement::Signature &that) { path = that.path(); inlinedHtml = that.isInlinedHtml(); text = that.text(); type = that.type(); enabled = that.isEnabledSignature(); saveLocation = that.imageLocation(); embeddedImages = that.embeddedImages(); } void SignaturePrivate::cleanupImages() { // Remove any images from the internal structure that are no longer there if (inlinedHtml) { auto it = std::remove_if(embeddedImages.begin(), embeddedImages.end(), [this](const Signature::EmbeddedImagePtr &imageInList){ const QStringList lstImage = findImageNames(text); for (const QString &imageInHtml : lstImage) { if (imageInHtml == imageInList->name) { return false; } } return true; }); embeddedImages.erase(it, embeddedImages.end()); } // Delete all the old image files if (!saveLocation.isEmpty()) { QDir dir(saveLocation); const QStringList lst = dir.entryList(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks); for (const QString &fileName : lst) { if (fileName.endsWith(QLatin1String(".png"), Qt::CaseInsensitive)) { qCDebug(KIDENTITYMANAGEMENT_LOG) << "Deleting old image" << dir.path() + fileName; dir.remove(fileName); } } } } void SignaturePrivate::saveImages() const { if (inlinedHtml && !saveLocation.isEmpty()) { for (const Signature::EmbeddedImagePtr &image : qAsConst(embeddedImages)) { QString location = saveLocation + QLatin1Char('/') + image->name; if (!image->image.save(location, "PNG")) { qCWarning(KIDENTITYMANAGEMENT_LOG) << "Failed to save image" << location; } } } } QString SignaturePrivate::textFromFile(bool *ok) const { assert(type == Signature::FromFile); QFile f(path); if (!f.open(QIODevice::ReadOnly)) { qCWarning(KIDENTITYMANAGEMENT_LOG) << "Failed to open" << path << ":" << f.errorString(); if (ok) { *ok = false; } return QString(); } if (ok) { *ok = true; } const QByteArray ba = f.readAll(); return QString::fromLocal8Bit(ba.data(), ba.size()); } QString SignaturePrivate::textFromCommand(bool *ok) const { assert(type == Signature::FromCommand); // handle pathological cases: if (path.isEmpty()) { if (ok) { *ok = true; } return QString(); } // create a shell process: KProcess proc; proc.setOutputChannelMode(KProcess::SeparateChannels); proc.setShellCommand(path); int rc = proc.execute(); // handle errors, if any: if (rc != 0) { if (ok) { *ok = false; } const QString wmsg = i18n("Failed to execute signature script

%1:

" "

%2

", path, QString::fromUtf8(proc.readAllStandardError())); KMessageBox::error(nullptr, wmsg); return QString(); } // no errors: if (ok) { *ok = true; } // get output: QByteArray output = proc.readAllStandardOutput(); // TODO: hmm, should we allow other encodings, too? return QString::fromLocal8Bit(output.data(), output.size()); } void SignaturePrivate::insertSignatureText(Signature::Placement placement, Signature::AddedText addedText, KPIMTextEdit::RichTextComposer *textEdit, bool forceDisplay) const { if (!forceDisplay) { if (!enabled) { return; } } QString signature; if (addedText & Signature::AddSeparator) { signature = q->withSeparator(); } else { signature = q->rawText(); } insertSignatureHelper(signature, textEdit, placement, (inlinedHtml && type == KIdentityManagement::Signature::Inlined), (addedText & Signature::AddNewLines)); // We added the text of the signature above, now it is time to add the images as well. if (inlinedHtml) { for (const Signature::EmbeddedImagePtr &image : qAsConst(embeddedImages)) { textEdit->composerControler()->composerImages()->loadImage(image->image, image->name, image->name); } } } QDataStream &operator<<(QDataStream &stream, const KIdentityManagement::Signature::EmbeddedImagePtr &img) { return stream << img->image << img->name; } QDataStream &operator>>(QDataStream &stream, KIdentityManagement::Signature::EmbeddedImagePtr &img) { return stream >> img->image >> img->name; } Signature::Signature() : d(new SignaturePrivate(this)) { d->type = Disabled; d->inlinedHtml = false; } Signature::Signature(const QString &text) : d(new SignaturePrivate(this)) { d->type = Inlined; d->inlinedHtml = false; d->text = text; } Signature::Signature(const QString &path, bool isExecutable) : d(new SignaturePrivate(this)) { d->type = isExecutable ? FromCommand : FromFile; d->path = path; } Signature::Signature(const Signature &that) : d(new SignaturePrivate(this)) { d->assignFrom(that); } Signature &Signature::operator=(const KIdentityManagement::Signature &that) { if (this == &that) { return *this; } d->assignFrom(that); return *this; } Signature::~Signature() { delete d; } QString Signature::rawText(bool *ok) const { switch (d->type) { case Disabled: if (ok) { *ok = true; } return QString(); case Inlined: if (ok) { *ok = true; } return d->text; case FromFile: return d->textFromFile(ok); case FromCommand: return d->textFromCommand(ok); } qCritical() << "Signature::type() returned unknown value!"; return QString(); // make compiler happy } QString Signature::withSeparator(bool *ok) const { QString signature = rawText(ok); if (ok && (*ok) == false) { return QString(); } if (signature.isEmpty()) { return signature; // don't add a separator in this case } const bool htmlSig = (isInlinedHtml() && d->type == Inlined); QString newline = htmlSig ? QStringLiteral("
") : QStringLiteral("\n"); if (htmlSig && signature.startsWith(QLatin1String("path = path; d->type = isExecutable ? FromCommand : FromFile; } void Signature::setInlinedHtml(bool isHtml) { d->inlinedHtml = isHtml; } bool Signature::isInlinedHtml() const { return d->inlinedHtml; } // config keys and values: static const char sigTypeKey[] = "Signature Type"; static const char sigTypeInlineValue[] = "inline"; static const char sigTypeFileValue[] = "file"; static const char sigTypeCommandValue[] = "command"; static const char sigTypeDisabledValue[] = "disabled"; static const char sigTextKey[] = "Inline Signature"; static const char sigFileKey[] = "Signature File"; static const char sigCommandKey[] = "Signature Command"; static const char sigTypeInlinedHtmlKey[] = "Inlined Html"; static const char sigImageLocation[] = "Image Location"; static const char sigEnabled[] = "Signature Enabled"; void Signature::readConfig(const KConfigGroup &config) { QString sigType = config.readEntry(sigTypeKey); if (sigType == QLatin1String(sigTypeInlineValue)) { d->type = Inlined; d->inlinedHtml = config.readEntry(sigTypeInlinedHtmlKey, false); } else if (sigType == QLatin1String(sigTypeFileValue)) { d->type = FromFile; d->path = config.readPathEntry(sigFileKey, QString()); } else if (sigType == QLatin1String(sigTypeCommandValue)) { d->type = FromCommand; d->path = config.readPathEntry(sigCommandKey, QString()); } else if (sigType == QLatin1String(sigTypeDisabledValue)) { d->enabled = false; } if (d->type != Disabled) { d->enabled = config.readEntry(sigEnabled, true); } d->text = config.readEntry(sigTextKey); d->saveLocation = config.readEntry(sigImageLocation); if (isInlinedHtml() && !d->saveLocation.isEmpty()) { QDir dir(d->saveLocation); const QStringList lst = dir.entryList(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks); for (const QString &fileName : lst) { if (fileName.endsWith(QLatin1String(".png"), Qt::CaseInsensitive)) { QImage image; if (image.load(dir.path() + QLatin1Char('/') + fileName)) { addImage(image, fileName); } else { qCWarning(KIDENTITYMANAGEMENT_LOG) << "Unable to load image" << dir.path() + QLatin1Char('/') + fileName; } } } } } void Signature::writeConfig(KConfigGroup &config) const { switch (d->type) { case Inlined: config.writeEntry(sigTypeKey, sigTypeInlineValue); config.writeEntry(sigTypeInlinedHtmlKey, d->inlinedHtml); break; case FromFile: config.writeEntry(sigTypeKey, sigTypeFileValue); config.writePathEntry(sigFileKey, d->path); break; case FromCommand: config.writeEntry(sigTypeKey, sigTypeCommandValue); config.writePathEntry(sigCommandKey, d->path); break; default: break; } config.writeEntry(sigTextKey, d->text); config.writeEntry(sigImageLocation, d->saveLocation); config.writeEntry(sigEnabled, d->enabled); d->cleanupImages(); d->saveImages(); } void Signature::insertIntoTextEdit(Placement placement, AddedText addedText, KPIMTextEdit::RichTextComposer *textEdit, bool forceDisplay) const { d->insertSignatureText(placement, addedText, textEdit, forceDisplay); } -QList Signature::embeddedImages() const +QVector Signature::embeddedImages() const { return d->embeddedImages; } -void Signature::setEmbeddedImages(const QList &embedded) +void Signature::setEmbeddedImages(const QVector &embedded) { d->embeddedImages = embedded; } // --------------------- Operators -------------------// QDataStream &KIdentityManagement::operator<< (QDataStream &stream, const KIdentityManagement::Signature &sig) { return stream << static_cast(sig.type()) << sig.path() << sig.text() << sig.imageLocation() << sig.embeddedImages() << sig.isEnabledSignature(); } QDataStream &KIdentityManagement::operator>> (QDataStream &stream, KIdentityManagement::Signature &sig) { quint8 s; QString path; QString text; QString saveLocation; - QList lst; + QVector lst; bool enabled; stream >> s >> path >> text >> saveLocation >> lst >> enabled; sig.setText(text); sig.setPath(path); sig.setImageLocation(saveLocation); sig.setEmbeddedImages(lst); sig.setEnabledSignature(enabled); sig.setType(static_cast(s)); return stream; } bool Signature::operator==(const Signature &other) const { if (d->type != other.type()) { return false; } if (d->enabled != other.isEnabledSignature()) { return false; } if (d->type == Inlined && d->inlinedHtml) { if (d->saveLocation != other.imageLocation()) { return false; } if (d->embeddedImages != other.embeddedImages()) { return false; } } switch (d->type) { case Inlined: return d->text == other.text(); case FromFile: case FromCommand: return d->path == other.path(); default: case Disabled: return true; } } QString Signature::toPlainText() const { QString sigText = rawText(); if (!sigText.isEmpty() && isInlinedHtml() && type() == Inlined) { // Use a QTextDocument as a helper, it does all the work for us and // strips all HTML tags. QTextDocument helper; QTextCursor helperCursor(&helper); helperCursor.insertHtml(sigText); sigText = helper.toPlainText(); } return sigText; } void Signature::addImage(const QImage &imageData, const QString &imageName) { Q_ASSERT(!(d->saveLocation.isEmpty())); Signature::EmbeddedImagePtr image(new Signature::EmbeddedImage()); image->image = imageData; image->name = imageName; d->embeddedImages.append(image); } void Signature::setImageLocation(const QString &path) { d->saveLocation = path; } QString Signature::imageLocation() const { return d->saveLocation; } // --------------- Getters -----------------------// QString Signature::text() const { return d->text; } QString Signature::path() const { return d->path; } Signature::Type Signature::type() const { return d->type; } // --------------- Setters -----------------------// void Signature::setText(const QString &text) { d->text = text; d->type = Inlined; } void Signature::setType(Type type) { d->type = type; } void Signature::setEnabledSignature(bool enabled) { d->enabled = enabled; } bool Signature::isEnabledSignature() const { return d->enabled; } diff --git a/src/signature.h b/src/signature.h index 7c489272..06e47746 100644 --- a/src/signature.h +++ b/src/signature.h @@ -1,263 +1,263 @@ /* Copyright (c) 2002-2004 Marc Mutz Copyright (c) 2007 Tom Albers Copyright (c) 2009 Thomas McGuire Author: Stefan Taferner This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KIDENTITYMANAGER_SIGNATURE_H #define KIDENTITYMANAGER_SIGNATURE_H #include "kidentitymanagement_export.h" #include #include #include #include namespace KIdentityManagement { class Signature; class Identity; } class KConfigGroup; namespace KPIMTextEdit { class RichTextComposer; } namespace KIdentityManagement { class SignaturePrivate; KIDENTITYMANAGEMENT_EXPORT QDataStream &operator<<(QDataStream &stream, const KIdentityManagement::Signature &sig); KIDENTITYMANAGEMENT_EXPORT QDataStream &operator>>(QDataStream &stream, KIdentityManagement::Signature &sig); /** * @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( " World" ); * htmlSig.setInlinedHtml( true ); * htmlSig.setImageLocation( KStandardDirs::locateLocal( "data", "emailidentities/example/" ); * QImage image = ...; * htmlSig.addImage( image, "hello.png" ); * ... * KTextEdit edit; * htmlSig.insertIntoTextEdit( KIdentityManagement::Signature::End, * KIdentityManagement::Signature::AddSeparator, &edit ); * @endcode */ class KIDENTITYMANAGEMENT_EXPORT Signature { friend class Identity; friend KIDENTITYMANAGEMENT_EXPORT QDataStream &operator<<(QDataStream &stream, const Signature &sig); friend KIDENTITYMANAGEMENT_EXPORT QDataStream &operator>>(QDataStream &stream, Signature &sig); public: /** Type of signature (ie. way to obtain the signature text) */ enum Type { Disabled = 0, Inlined = 1, FromFile = 2, FromCommand = 3 }; /** * Describes the placement of the signature text when it is to be inserted into a * text edit */ enum Placement { 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 }; struct EmbeddedImage { QImage image; QString name; }; typedef QSharedPointer EmbeddedImagePtr; /** Used for comparison */ bool operator==(const Signature &other) const; /** Constructor for disabled signature */ Signature(); /** Constructor for inline text */ Signature(const QString &text); /** Constructor for text from a file or from output of a command */ Signature(const QString &path, bool isExecutable); /** Copy constructor */ Signature(const Signature &that); /** Assignment operator */ Signature &operator=(const Signature &that); /** Destructor */ ~Signature(); /** @return the raw signature text as entered resp. read from file. @param ok set to @c true if reading succeeded */ Q_REQUIRED_RESULT QString rawText(bool *ok = nullptr) const; /** @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 */ Q_REQUIRED_RESULT QString withSeparator(bool *ok = nullptr) const; /** Set the signature text and mark this signature as being of "inline text" type. */ void setText(const QString &text); Q_REQUIRED_RESULT QString text() const; /** * Returns the text of the signature. If the signature is HTML, the HTML * tags will be stripped. * @since 4.4 */ Q_REQUIRED_RESULT QString toPlainText() const; /** Set the signature URL and mark this signature as being of "from file" resp. "from output of command" type. */ void setPath(const QString &path, bool isExecutable = false); Q_REQUIRED_RESULT QString path() const; /// @return the type of signature (ie. way to obtain the signature text) Q_REQUIRED_RESULT Type type() const; 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 */ Q_REQUIRED_RESULT bool isInlinedHtml() const; /** * 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); Q_REQUIRED_RESULT QString imageLocation() const; /** * 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); Q_REQUIRED_RESULT bool isEnabledSignature() const; enum AddedTextFlag { AddNothing = 0, ///< Don't add any text to the signature AddSeparator = 1 << 0, ///< The separator '-- \n' will be added in front /// of the signature AddNewLines = 1 << 1 ///< Add a newline character in front or after the signature, /// depending on the placement }; /// Describes which additional parts should be added to the signature typedef QFlags AddedText; /** Inserts this signature into the given text edit. * 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 */ // TODO: KDE5: BIC: Reorder parameters, the order here is a workaround for ambiguous parameters // with the deprecated method void insertIntoTextEdit(Placement placement, AddedText addedText, KPIMTextEdit::RichTextComposer *textEdit, bool forceDisplay = false) const; - Q_REQUIRED_RESULT QList embeddedImages() const; - void setEmbeddedImages(const QList &embedded); + Q_REQUIRED_RESULT QVector embeddedImages() const; + void setEmbeddedImages(const QVector &embedded); protected: // TODO: KDE5: BIC: Move all to private class void writeConfig(KConfigGroup &config) const; void readConfig(const KConfigGroup &config); private: //@cond PRIVATE SignaturePrivate *const d; //@endcond }; Q_DECLARE_OPERATORS_FOR_FLAGS(Signature::AddedText) } #endif /*kpim_signature_h*/