11#include "kidentitymanagementcore_debug.h"
12#include <KConfigGroup>
13#include <KLocalizedString>
18#include <QTextDocument>
22using namespace KIdentityManagementCore;
25class KIdentityManagementCore::SignaturePrivate
28 explicit SignaturePrivate(Signature *qq)
33 void assignFrom(
const KIdentityManagementCore::Signature &that);
35 void saveImages()
const;
36 [[nodiscard]] QString textFromFile(
bool *ok)
const;
37 [[nodiscard]] QString textFromCommand(
bool *ok, QString *errorMessage)
const;
41 QList<Signature::EmbeddedImagePtr> embeddedImages;
49 bool inlinedHtml =
false;
59 for (
auto block = doc.
begin(); block.
isValid(); block = block.next()) {
60 for (
auto it = block.begin(); !it.atEnd(); ++it) {
61 const auto fragment = it.fragment();
62 if (fragment.isValid()) {
63 const auto imageFormat = fragment.charFormat().toImageFormat();
64 if (imageFormat.isValid() && !imageFormat.name().startsWith(
"http"_L1) && !imageNames.
contains(imageFormat.name())) {
79 enabled = that.isEnabledSignature();
80 saveLocation = that.imageLocation();
81 embeddedImages = that.embeddedImages();
84void SignaturePrivate::cleanupImages()
88 auto it = std::remove_if(embeddedImages.begin(), embeddedImages.end(), [
this](
const Signature::EmbeddedImagePtr &imageInList) {
89 const QStringList lstImage = findImageNames(text);
90 for (const QString &imageInHtml : lstImage) {
91 if (imageInHtml == imageInList->name) {
97 embeddedImages.erase(it, embeddedImages.end());
101 if (!saveLocation.isEmpty()) {
102 QDir
dir(saveLocation);
104 for (
const QString &fileName : lst) {
106 qCDebug(KIDENTITYMANAGEMENT_LOG) <<
"Deleting old image" <<
dir.path() + fileName;
113void SignaturePrivate::saveImages()
const
115 if (inlinedHtml && !saveLocation.isEmpty()) {
116 for (
const Signature::EmbeddedImagePtr &image : std::as_const(embeddedImages)) {
117 const QString
location = saveLocation + QLatin1Char(
'/') + image->name;
118 if (!image->image.save(location,
"PNG")) {
119 qCWarning(KIDENTITYMANAGEMENT_LOG) <<
"Failed to save image" <<
location;
125QString SignaturePrivate::textFromFile(
bool *ok)
const
127 assert(type == Signature::FromFile);
131 qCWarning(KIDENTITYMANAGEMENT_LOG) <<
"Failed to open" << path <<
":" << f.errorString();
141 const QByteArray ba = f.readAll();
145QString SignaturePrivate::textFromCommand(
bool *ok, QString *errorMessage)
const
147 assert(type == Signature::FromCommand);
150 if (path.isEmpty()) {
170 "<qt>Failed to execute signature script<p><b>%1</b>:</p>"
190QDataStream &operator<<(QDataStream &stream,
const KIdentityManagementCore::Signature::EmbeddedImagePtr &img)
192 return stream << img->image << img->name;
195QDataStream &operator>>(QDataStream &stream,
const KIdentityManagementCore::Signature::EmbeddedImagePtr &img)
197 return stream >> img->image >> img->name;
201 : d(new SignaturePrivate(this))
204 d->inlinedHtml =
false;
208 : d(new SignaturePrivate(this))
211 d->inlinedHtml =
false;
216 : d(new SignaturePrivate(this))
218 d->type = isExecutable ? FromCommand : FromFile;
223 : d(new SignaturePrivate(this))
254 return d->textFromFile(ok);
256 return d->textFromCommand(ok, errorMessage);
258 qCritical() <<
"Signature::type() returned unknown value!";
265 if (ok && (*ok) ==
false) {
273 const bool htmlSig = (
isInlinedHtml() && d->type == Inlined);
274 QString newline = htmlSig ? QStringLiteral(
"<br>") : QStringLiteral(
"\n");
275 if (htmlSig && signature.
startsWith(
"<p"_L1)) {
279 if (signature.
startsWith(
"-- "_L1 + newline) || (signature.
indexOf(newline +
"-- "_L1 + newline) != -1)) {
284 return "-- "_L1 + newline + signature;
291 d->type = isExecutable ? FromCommand : FromFile;
296 d->inlinedHtml = isHtml;
301 return d->inlinedHtml;
305static const char sigTypeKey[] =
"Signature Type";
306static const char sigTypeInlineValue[] =
"inline";
307static const char sigTypeFileValue[] =
"file";
308static const char sigTypeCommandValue[] =
"command";
309static const char sigTypeDisabledValue[] =
"disabled";
310static const char sigTextKey[] =
"Inline Signature";
311static const char sigFileKey[] =
"Signature File";
312static const char sigCommandKey[] =
"Signature Command";
313static const char sigTypeInlinedHtmlKey[] =
"Inlined Html";
314static const char sigImageLocation[] =
"Image Location";
315static const char sigEnabled[] =
"Signature Enabled";
322 d->inlinedHtml = config.
readEntry(sigTypeInlinedHtmlKey,
false);
326 }
else if (sigType == QLatin1StringView(sigTypeCommandValue)) {
327 d->type = FromCommand;
329 }
else if (sigType == QLatin1StringView(sigTypeDisabledValue)) {
332 if (d->type != Disabled) {
333 d->enabled = config.
readEntry(sigEnabled,
true);
337 d->saveLocation = config.
readEntry(sigImageLocation);
340 QDir
dir(d->saveLocation);
342 for (
const QString &fileName : lst) {
345 if (image.
load(
dir.path() + QLatin1Char(
'/') + fileName)) {
348 qCWarning(KIDENTITYMANAGEMENT_LOG) <<
"Unable to load image" <<
dir.path() + QLatin1Char(
'/') + fileName;
355void Signature::writeConfig(KConfigGroup &config)
const
359 config.
writeEntry(sigTypeKey, sigTypeInlineValue);
360 config.
writeEntry(sigTypeInlinedHtmlKey, d->inlinedHtml);
363 config.
writeEntry(sigTypeKey, sigTypeFileValue);
367 config.
writeEntry(sigTypeKey, sigTypeCommandValue);
374 config.
writeEntry(sigImageLocation, d->saveLocation);
381QList<Signature::EmbeddedImagePtr> Signature::embeddedImages()
const
383 return d->embeddedImages;
386void Signature::setEmbeddedImages(
const QList<Signature::EmbeddedImagePtr> &embedded)
388 d->embeddedImages = embedded;
393QDataStream &KIdentityManagementCore::operator<<(QDataStream &stream,
const KIdentityManagementCore::Signature &sig)
395 return stream << static_cast<quint8>(sig.
type()) << sig.path() << sig.text() << sig.imageLocation() << sig.embeddedImages() << sig.isEnabledSignature();
398QDataStream &KIdentityManagementCore::operator>>(QDataStream &stream, KIdentityManagementCore::Signature &sig)
403 QString saveLocation;
404 QList<Signature::EmbeddedImagePtr> lst;
406 stream >> s >>
path >> text >> saveLocation >> lst >> enabled;
410 sig.setEmbeddedImages(lst);
418 if (d->type != other.
type()) {
422 if (d->enabled != other.isEnabledSignature()) {
426 if (d->type == Inlined && d->inlinedHtml) {
427 if (d->saveLocation != other.imageLocation()) {
430 if (d->embeddedImages != other.embeddedImages()) {
437 return d->text == other.text();
440 return d->path == other.path();
463 Q_ASSERT(!(d->saveLocation.isEmpty()));
464 Signature::EmbeddedImagePtr image(
new Signature::EmbeddedImage());
465 image->image = imageData;
466 image->name = imageName;
467 d->embeddedImages.
append(image);
472 d->saveLocation = path;
475QString Signature::imageLocation()
const
477 return d->saveLocation;
487QString Signature::path()
const
505void Signature::setType(Type type)
512 d->enabled = enabled;
515bool Signature::isEnabledSignature()
const
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
void writePathEntry(const char *Key, const QString &path, WriteConfigFlags pFlags=Normal)
QString readPathEntry(const char *key, const QString &aDefault) const
QString readEntry(const char *key, const char *aDefault=nullptr) const
Abstraction of a signature (aka "footer").
bool operator==(const Signature &other) const
Used for comparison.
void setPath(const QString &path, bool isExecutable=false)
Set the signature URL and mark this signature as being of "from file" resp.
void setText(const QString &text)
Set the signature text and mark this signature as being of "inline text" type.
void setImageLocation(const QString &path)
Sets the location where the copies of the signature images will be stored.
void setInlinedHtml(bool isHtml)
Sets the inlined signature to text or html.
bool isInlinedHtml() const
QString rawText(bool *ok=nullptr, QString *errorMessage=nullptr) const
Signature()
Constructor for disabled signature.
void setEnabledSignature(bool enabled)
setEnabledSignature
QString toPlainText() const
Returns the text of the signature.
QString withSeparator(bool *ok=nullptr, QString *errorMessage=nullptr) const
Type
Type of signature (ie.
void addImage(const QImage &image, const QString &imageName)
Adds the given image to the signature.
Signature & operator=(const Signature &that)
Assignment operator.
void setShellCommand(const QString &cmd)
void setOutputChannelMode(OutputChannelMode mode)
int execute(int msecs=-1)
QString i18n(const char *text, const TYPE &arg...)
KCALUTILS_EXPORT QString errorMessage(const KCalendarCore::Exception &exception)
QVariant location(const QVariant &res)
QString path(const QString &relativePath)
KIOCORE_EXPORT QString dir(const QString &fileClass)
qsizetype size() const const
bool load(QIODevice *device, const char *format)
void push_back(parameter_type value)
QByteArray readAllStandardError()
QByteArray readAllStandardOutput()
QString & append(QChar ch)
QString fromLocal8Bit(QByteArrayView str)
QString fromUtf8(QByteArrayView str)
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString & remove(QChar ch, Qt::CaseSensitivity cs)
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
bool isValid() const const
void insertHtml(const QString &html)
QTextBlock begin() const const
void setHtml(const QString &html)
QString toPlainText() const const