templateparserjob.cpp 66.9 KB
Newer Older
1
/*
Laurent Montel's avatar
Laurent Montel committed
2
   Copyright (C) 2017-2019 Laurent Montel <montel@kde.org>
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

   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 "templateparserjob.h"
Yuri Chornoivan's avatar
Yuri Chornoivan committed
21
#include "templateparserjob_p.h"
22
#include "templateparserextracthtmlinfo.h"
Laurent Montel's avatar
Laurent Montel committed
23 24 25 26
#include "globalsettings_templateparser.h"
#include "customtemplates_kfg.h"
#include "templatesconfiguration_kfg.h"
#include "templatesconfiguration.h"
Laurent Montel's avatar
Laurent Montel committed
27
#include "templatesutil.h"
28

Laurent Montel's avatar
Laurent Montel committed
29 30
#include <MessageCore/ImageCollector>
#include <MessageCore/StringUtil>
31

Laurent Montel's avatar
Laurent Montel committed
32
#include <MimeTreeParser/ObjectTreeParser>
33
#include <MimeTreeParser/MessagePart>
34
#include <MimeTreeParser/SimpleObjectTreeSource>
Laurent Montel's avatar
Laurent Montel committed
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51

#include <KIdentityManagement/Identity>
#include <KIdentityManagement/IdentityManager>

#include <KCharsets>
#include <KLocalizedString>
#include <KMessageBox>
#include <KProcess>
#include <KShell>
#include "templateparser_debug.h"

#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QTextCodec>
#include <QLocale>

Laurent Montel's avatar
Laurent Montel committed
52
namespace {
Laurent Montel's avatar
Laurent Montel committed
53 54
Q_DECL_CONSTEXPR inline int pipeTimeout()
{
Laurent Montel's avatar
Laurent Montel committed
55
    return 15 * 1000;
Laurent Montel's avatar
Laurent Montel committed
56
}
Laurent Montel's avatar
Laurent Montel committed
57

Laurent Montel's avatar
Laurent Montel committed
58 59 60 61 62 63
static QTextCodec *selectCharset(const QStringList &charsets, const QString &text)
{
    for (const QString &name : charsets) {
        // We use KCharsets::codecForName() instead of QTextCodec::codecForName() here, because
        // the former knows us-ascii is latin1.
        bool ok = true;
Laurent Montel's avatar
Laurent Montel committed
64
        QTextCodec *codec = nullptr;
Laurent Montel's avatar
Laurent Montel committed
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
        if (name == QLatin1String("locale")) {
            codec = QTextCodec::codecForLocale();
        } else {
            codec = KCharsets::charsets()->codecForName(name, ok);
        }
        if (!ok || !codec) {
            qCWarning(TEMPLATEPARSER_LOG) << "Could not get text codec for charset" << name;
            continue;
        }
        if (codec->canEncode(text)) {
            // Special check for us-ascii (needed because us-ascii is not exactly latin1).
            if (name == QLatin1String("us-ascii") && !KMime::isUsAscii(text)) {
                continue;
            }
            qCDebug(TEMPLATEPARSER_LOG) << "Chosen charset" << name << codec->name();
            return codec;
        }
    }
    qCDebug(TEMPLATEPARSER_LOG) << "No appropriate charset found.";
    return KCharsets::charsets()->codecForName(QStringLiteral("utf-8"));
}
86
}
87

88
using namespace TemplateParser;
Laurent Montel's avatar
Laurent Montel committed
89

90 91 92
TemplateParserJobPrivate::TemplateParserJobPrivate(const KMime::Message::Ptr &amsg, const TemplateParserJob::Mode amode)
    : mMsg(amsg)
    , mMode(amode)
93
{
94 95
    mEmptySource = new MimeTreeParser::SimpleObjectTreeSource;
    mEmptySource->setDecryptMessage(mAllowDecryption);
96

Laurent Montel's avatar
Laurent Montel committed
97 98
    mOtp = new MimeTreeParser::ObjectTreeParser(mEmptySource);
    mOtp->setAllowAsync(false);
99 100
}

101
TemplateParserJobPrivate::~TemplateParserJobPrivate()
102
{
Laurent Montel's avatar
Laurent Montel committed
103 104 105 106
    delete mEmptySource;
    delete mOtp;
}

107 108 109 110 111 112
void TemplateParserJobPrivate::setAllowDecryption(const bool allowDecryption)
{
    mAllowDecryption = allowDecryption;
    mEmptySource->setDecryptMessage(mAllowDecryption);
}

Laurent Montel's avatar
Laurent Montel committed
113 114 115
TemplateParserJob::TemplateParserJob(const KMime::Message::Ptr &amsg, const Mode amode, QObject *parent)
    : QObject(parent)
    , d(new TemplateParserJobPrivate(amsg, amode))
116 117 118 119 120
{
}

TemplateParserJob::~TemplateParserJob() = default;

Laurent Montel's avatar
Laurent Montel committed
121 122
void TemplateParserJob::setSelection(const QString &selection)
{
123
    d->mSelection = selection;
Laurent Montel's avatar
Laurent Montel committed
124 125 126 127
}

void TemplateParserJob::setAllowDecryption(const bool allowDecryption)
{
128
    d->setAllowDecryption(allowDecryption);
Laurent Montel's avatar
Laurent Montel committed
129 130 131 132 133
}

bool TemplateParserJob::shouldStripSignature() const
{
    // Only strip the signature when replying, it should be preserved when forwarding
134
    return (d->mMode == Reply || d->mMode == ReplyAll) && TemplateParserSettings::self()->stripSignature();
Laurent Montel's avatar
Laurent Montel committed
135 136 137 138
}

void TemplateParserJob::setIdentityManager(KIdentityManagement::IdentityManager *ident)
{
139
    d->m_identityManager = ident;
Laurent Montel's avatar
Laurent Montel committed
140 141 142 143
}

void TemplateParserJob::setCharsets(const QStringList &charsets)
{
144
    d->mCharsets = charsets;
Laurent Montel's avatar
Laurent Montel committed
145 146
}

Laurent Montel's avatar
Laurent Montel committed
147
int TemplateParserJob::parseQuotes(const QString &prefix, const QString &str, QString &quote)
Laurent Montel's avatar
Laurent Montel committed
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
{
    int pos = prefix.length();
    int len;
    const int str_len = str.length();

    // Also allow the german lower double-quote sign as quote separator, not only
    // the standard ASCII quote ("). This fixes bug 166728.
    const QList< QChar > quoteChars = {QLatin1Char('"'), 0x201C};

    QChar prev(QChar::Null);

    pos++;
    len = pos;

    while (pos < str_len) {
        const QChar c = str[pos];

        pos++;
        len++;

        if (!prev.isNull()) {
            quote.append(c);
            prev = QChar::Null;
        } else {
            if (c == QLatin1Char('\\')) {
                prev = c;
            } else if (quoteChars.contains(c)) {
                break;
            } else {
                quote.append(c);
            }
        }
    }

    return len;
}

Laurent Montel's avatar
Laurent Montel committed
185
void TemplateParserJob::process(const KMime::Message::Ptr &aorig_msg, qint64 afolder)
Laurent Montel's avatar
Laurent Montel committed
186 187 188
{
    if (aorig_msg == nullptr) {
        qCDebug(TEMPLATEPARSER_LOG) << "aorig_msg == 0!";
189
        Q_EMIT parsingDone(d->mForceCursorPosition);
Laurent Montel's avatar
Laurent Montel committed
190
        deleteLater();
Laurent Montel's avatar
Laurent Montel committed
191 192 193
        return;
    }

194 195
    d->mOrigMsg = aorig_msg;
    d->mFolder = afolder;
Laurent Montel's avatar
Laurent Montel committed
196 197
    const QString tmpl = findTemplate();
    if (tmpl.isEmpty()) {
198
        Q_EMIT parsingDone(d->mForceCursorPosition);
Laurent Montel's avatar
Laurent Montel committed
199
        deleteLater();
Laurent Montel's avatar
Laurent Montel committed
200 201 202 203 204
        return;
    }
    processWithTemplate(tmpl);
}

Laurent Montel's avatar
Laurent Montel committed
205
void TemplateParserJob::process(const QString &tmplName, const KMime::Message::Ptr &aorig_msg, qint64 afolder)
Laurent Montel's avatar
Laurent Montel committed
206
{
207 208 209
    d->mForceCursorPosition = false;
    d->mOrigMsg = aorig_msg;
    d->mFolder = afolder;
Laurent Montel's avatar
Laurent Montel committed
210 211 212 213
    const QString tmpl = findCustomTemplate(tmplName);
    processWithTemplate(tmpl);
}

Laurent Montel's avatar
Laurent Montel committed
214
void TemplateParserJob::processWithIdentity(uint uoid, const KMime::Message::Ptr &aorig_msg, qint64 afolder)
Laurent Montel's avatar
Laurent Montel committed
215
{
216
    d->mIdentity = uoid;
Laurent Montel's avatar
Laurent Montel committed
217 218 219
    process(aorig_msg, afolder);
}

220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
MimeTreeParser::MessagePart::Ptr toplevelTextNode(MimeTreeParser::MessagePart::Ptr messageTree)
{
    foreach (const auto &mp, messageTree->subParts()) {
        auto text = mp.dynamicCast<MimeTreeParser::TextMessagePart>();
        const auto attach = mp.dynamicCast<MimeTreeParser::AttachmentMessagePart>();
        if (text && !attach) {
            // TextMessagePart can have several subparts cause of PGP inline, we search for the first part with content
            foreach (const auto &sub, mp->subParts()) {
                if (!sub->text().trimmed().isEmpty()) {
                    return sub;
                }
            }
            return text;
        } else if (const auto html = mp.dynamicCast<MimeTreeParser::HtmlMessagePart>()) {
            return html;
        } else if (const auto alternative = mp.dynamicCast<MimeTreeParser::AlternativeMessagePart>()) {
            return alternative;
        } else {
            auto ret = toplevelTextNode(mp);
            if (ret) {
                return ret;
            }
        }
    }
    return MimeTreeParser::MessagePart::Ptr();
}

Laurent Montel's avatar
Laurent Montel committed
247 248
void TemplateParserJob::processWithTemplate(const QString &tmpl)
{
249
    d->mOtp->parseObjectTree(d->mOrigMsg.data());
Laurent Montel's avatar
Laurent Montel committed
250

251
    const auto mp = toplevelTextNode(d->mOtp->parsedPart());
Laurent Montel's avatar
Laurent Montel committed
252

253 254
    QString plainText = mp->plaintextContent();
    QString htmlElement;
Laurent Montel's avatar
Laurent Montel committed
255

256 257 258 259 260 261 262
    if (mp->isHtml()) {
        htmlElement = d->mOtp->htmlContent();
        if (plainText.isEmpty()) {   //HTML-only mails
            plainText = htmlElement;
        }
    } else {   //plain mails only
        QString htmlReplace = plainText.toHtmlEscaped();
263
        htmlReplace.replace(QLatin1Char('\n'), QStringLiteral("<br />"));
264
        htmlElement = QStringLiteral("<html><head></head><body>%1</body></html>\n").arg(htmlReplace);
Laurent Montel's avatar
Laurent Montel committed
265 266
    }

267 268 269 270 271 272
    TemplateParserExtractHtmlInfo *job = new TemplateParserExtractHtmlInfo(this);
    connect(job, &TemplateParserExtractHtmlInfo::finished, this, &TemplateParserJob::slotExtractInfoDone);

    job->setHtmlForExtractingTextPlain(plainText);
    job->setTemplate(tmpl);

273
    job->setHtmlForExtractionHeaderAndBody(htmlElement);
Laurent Montel's avatar
Laurent Montel committed
274 275 276 277 278
    job->start();
}

void TemplateParserJob::slotExtractInfoDone(const TemplateParserExtractHtmlInfoResult &result)
{
279 280
    d->mExtractHtmlInfoResult = result;
    const QString tmpl = d->mExtractHtmlInfoResult.mTemplate;
Laurent Montel's avatar
Laurent Montel committed
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
    const int tmpl_len = tmpl.length();
    QString plainBody, htmlBody;

    bool dnl = false;
    auto definedLocale = QLocale();
    for (int i = 0; i < tmpl_len; ++i) {
        QChar c = tmpl[i];
        // qCDebug(TEMPLATEPARSER_LOG) << "Next char: " << c;
        if (c == QLatin1Char('%')) {
            const QString cmd = tmpl.mid(i + 1);

            if (cmd.startsWith(QLatin1Char('-'))) {
                // dnl
                qCDebug(TEMPLATEPARSER_LOG) << "Command: -";
                dnl = true;
                i += 1;
Laurent Montel's avatar
Laurent Montel committed
297
            } else if (cmd.startsWith(QLatin1String("REM="))) {
Laurent Montel's avatar
Laurent Montel committed
298 299 300 301 302
                // comments
                qCDebug(TEMPLATEPARSER_LOG) << "Command: REM=";
                QString q;
                const int len = parseQuotes(QStringLiteral("REM="), cmd, q);
                i += len;
Laurent Montel's avatar
Laurent Montel committed
303
            } else if (cmd.startsWith(QLatin1String("LANGUAGE="))) {
Laurent Montel's avatar
Laurent Montel committed
304 305 306 307 308 309
                QString q;
                const int len = parseQuotes(QStringLiteral("LANGUAGE="), cmd, q);
                i += len;
                if (!q.isEmpty()) {
                    definedLocale = QLocale(q);
                }
Laurent Montel's avatar
Laurent Montel committed
310
            } else if (cmd.startsWith(QLatin1String("DICTIONARYLANGUAGE="))) {
Laurent Montel's avatar
Laurent Montel committed
311 312 313 314 315 316
                QString q;
                const int len = parseQuotes(QStringLiteral("DICTIONARYLANGUAGE="), cmd, q);
                i += len;
                if (!q.isEmpty()) {
                    KMime::Headers::Generic *header = new KMime::Headers::Generic("X-KMail-Dictionary");
                    header->fromUnicodeString(q, "utf-8");
317
                    d->mMsg->setHeader(header);
Laurent Montel's avatar
Laurent Montel committed
318
                }
Laurent Montel's avatar
Laurent Montel committed
319
            } else if (cmd.startsWith(QLatin1String("INSERT=")) || cmd.startsWith(QLatin1String("PUT="))) {
Laurent Montel's avatar
Laurent Montel committed
320 321
                QString q;
                int len = 0;
Laurent Montel's avatar
Laurent Montel committed
322
                if (cmd.startsWith(QLatin1String("INSERT="))) {
Laurent Montel's avatar
Laurent Montel committed
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
                    // insert content of specified file as is
                    qCDebug(TEMPLATEPARSER_LOG) << "Command: INSERT=";
                    len = parseQuotes(QStringLiteral("INSERT="), cmd, q);
                } else {
                    // insert content of specified file as is
                    qCDebug(TEMPLATEPARSER_LOG) << "Command: PUT=";
                    len = parseQuotes(QStringLiteral("PUT="), cmd, q);
                }
                i += len;
                QString path = KShell::tildeExpand(q);
                QFileInfo finfo(path);
                if (finfo.isRelative()) {
                    path = QDir::homePath() + QLatin1Char('/') + q;
                }
                QFile file(path);
                if (file.open(QIODevice::ReadOnly)) {
                    const QByteArray content = file.readAll();
                    const QString str = QString::fromLocal8Bit(content.constData(), content.size());
                    plainBody.append(str);
                    const QString body = plainToHtml(str);
                    htmlBody.append(body);
344
                } else if (d->mDebug) {
Laurent Montel's avatar
Laurent Montel committed
345 346 347 348 349
                    KMessageBox::error(
                        nullptr,
                        i18nc("@info",
                              "Cannot insert content from file %1: %2", path, file.errorString()));
                }
Laurent Montel's avatar
Laurent Montel committed
350
            } else if (cmd.startsWith(QLatin1String("SYSTEM="))) {
Laurent Montel's avatar
Laurent Montel committed
351 352 353 354 355 356 357 358 359 360
                // insert content of specified file as is
                qCDebug(TEMPLATEPARSER_LOG) << "Command: SYSTEM=";
                QString q;
                const int len = parseQuotes(QStringLiteral("SYSTEM="), cmd, q);
                i += len;
                const QString pipe_cmd = q;
                const QString str = pipe(pipe_cmd, QString());
                plainBody.append(str);
                const QString body = plainToHtml(str);
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
361
            } else if (cmd.startsWith(QLatin1String("QUOTEPIPE="))) {
Laurent Montel's avatar
Laurent Montel committed
362 363 364 365 366 367
                // pipe message body through command and insert it as quotation
                qCDebug(TEMPLATEPARSER_LOG) << "Command: QUOTEPIPE=";
                QString q;
                const int len = parseQuotes(QStringLiteral("QUOTEPIPE="), cmd, q);
                i += len;
                const QString pipe_cmd = q;
368
                if (d->mOrigMsg) {
Laurent Montel's avatar
Laurent Montel committed
369 370
                    const QString plainStr
                        = pipe(pipe_cmd, plainMessageText(shouldStripSignature(), NoSelectionAllowed));
Laurent Montel's avatar
Laurent Montel committed
371 372 373 374 375 376
                    QString plainQuote = quotedPlainText(plainStr);
                    if (plainQuote.endsWith(QLatin1Char('\n'))) {
                        plainQuote.chop(1);
                    }
                    plainBody.append(plainQuote);

Laurent Montel's avatar
Laurent Montel committed
377 378
                    const QString htmlStr
                        = pipe(pipe_cmd, htmlMessageText(shouldStripSignature(), NoSelectionAllowed));
Laurent Montel's avatar
Laurent Montel committed
379 380 381
                    const QString htmlQuote = quotedHtmlText(htmlStr);
                    htmlBody.append(htmlQuote);
                }
Laurent Montel's avatar
Laurent Montel committed
382
            } else if (cmd.startsWith(QLatin1String("QUOTE"))) {
Laurent Montel's avatar
Laurent Montel committed
383 384
                qCDebug(TEMPLATEPARSER_LOG) << "Command: QUOTE";
                i += strlen("QUOTE");
385
                if (d->mOrigMsg) {
Laurent Montel's avatar
Laurent Montel committed
386 387
                    QString plainQuote
                        = quotedPlainText(plainMessageText(shouldStripSignature(), SelectionAllowed));
Laurent Montel's avatar
Laurent Montel committed
388 389 390 391 392
                    if (plainQuote.endsWith(QLatin1Char('\n'))) {
                        plainQuote.chop(1);
                    }
                    plainBody.append(plainQuote);

Laurent Montel's avatar
Laurent Montel committed
393 394
                    const QString htmlQuote
                        = quotedHtmlText(htmlMessageText(shouldStripSignature(), SelectionAllowed));
Laurent Montel's avatar
Laurent Montel committed
395 396
                    htmlBody.append(htmlQuote);
                }
Laurent Montel's avatar
Laurent Montel committed
397
            } else if (cmd.startsWith(QLatin1String("FORCEDPLAIN"))) {
Laurent Montel's avatar
Laurent Montel committed
398
                qCDebug(TEMPLATEPARSER_LOG) << "Command: FORCEDPLAIN";
399
                d->mQuotes = ReplyAsPlain;
Laurent Montel's avatar
Laurent Montel committed
400
                i += strlen("FORCEDPLAIN");
Laurent Montel's avatar
Laurent Montel committed
401
            } else if (cmd.startsWith(QLatin1String("FORCEDHTML"))) {
Laurent Montel's avatar
Laurent Montel committed
402
                qCDebug(TEMPLATEPARSER_LOG) << "Command: FORCEDHTML";
403
                d->mQuotes = ReplyAsHtml;
Laurent Montel's avatar
Laurent Montel committed
404
                i += strlen("FORCEDHTML");
Laurent Montel's avatar
Laurent Montel committed
405
            } else if (cmd.startsWith(QLatin1String("QHEADERS"))) {
Laurent Montel's avatar
Laurent Montel committed
406 407
                qCDebug(TEMPLATEPARSER_LOG) << "Command: QHEADERS";
                i += strlen("QHEADERS");
408
                if (d->mOrigMsg) {
Laurent Montel's avatar
Laurent Montel committed
409
                    QString plainQuote
410
                        = quotedPlainText(QString::fromLatin1(MessageCore::StringUtil::headerAsSendableString(d->mOrigMsg)));
Laurent Montel's avatar
Laurent Montel committed
411 412 413 414 415
                    if (plainQuote.endsWith(QLatin1Char('\n'))) {
                        plainQuote.chop(1);
                    }
                    plainBody.append(plainQuote);

Laurent Montel's avatar
Laurent Montel committed
416
                    const QString htmlQuote
417
                        = quotedHtmlText(QString::fromLatin1(MessageCore::StringUtil::headerAsSendableString(d->mOrigMsg)));
Laurent Montel's avatar
Laurent Montel committed
418 419 420
                    const QString str = plainToHtml(htmlQuote);
                    htmlBody.append(str);
                }
Laurent Montel's avatar
Laurent Montel committed
421
            } else if (cmd.startsWith(QLatin1String("HEADERS"))) {
Laurent Montel's avatar
Laurent Montel committed
422 423
                qCDebug(TEMPLATEPARSER_LOG) << "Command: HEADERS";
                i += strlen("HEADERS");
424 425
                if (d->mOrigMsg) {
                    const QString str = QString::fromLatin1(MessageCore::StringUtil::headerAsSendableString(d->mOrigMsg));
Laurent Montel's avatar
Laurent Montel committed
426 427 428 429
                    plainBody.append(str);
                    const QString body = plainToHtml(str);
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
430
            } else if (cmd.startsWith(QLatin1String("TEXTPIPE="))) {
Laurent Montel's avatar
Laurent Montel committed
431 432 433 434 435 436
                // pipe message body through command and insert it as is
                qCDebug(TEMPLATEPARSER_LOG) << "Command: TEXTPIPE=";
                QString q;
                const int len = parseQuotes(QStringLiteral("TEXTPIPE="), cmd, q);
                i += len;
                const QString pipe_cmd = q;
437
                if (d->mOrigMsg) {
Laurent Montel's avatar
Laurent Montel committed
438 439
                    const QString plainStr
                        = pipe(pipe_cmd, plainMessageText(shouldStripSignature(), NoSelectionAllowed));
Laurent Montel's avatar
Laurent Montel committed
440 441
                    plainBody.append(plainStr);

Laurent Montel's avatar
Laurent Montel committed
442 443
                    const QString htmlStr
                        = pipe(pipe_cmd, htmlMessageText(shouldStripSignature(), NoSelectionAllowed));
Laurent Montel's avatar
Laurent Montel committed
444 445
                    htmlBody.append(htmlStr);
                }
Laurent Montel's avatar
Laurent Montel committed
446
            } else if (cmd.startsWith(QLatin1String("MSGPIPE="))) {
Laurent Montel's avatar
Laurent Montel committed
447 448 449 450 451
                // pipe full message through command and insert result as is
                qCDebug(TEMPLATEPARSER_LOG) << "Command: MSGPIPE=";
                QString q;
                const int len = parseQuotes(QStringLiteral("MSGPIPE="), cmd, q);
                i += len;
452
                if (d->mOrigMsg) {
Laurent Montel's avatar
Laurent Montel committed
453
                    QString pipe_cmd = q;
454
                    const QString str = pipe(pipe_cmd, QString::fromLatin1(d->mOrigMsg->encodedContent()));
Laurent Montel's avatar
Laurent Montel committed
455 456 457 458 459
                    plainBody.append(str);

                    const QString body = plainToHtml(str);
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
460
            } else if (cmd.startsWith(QLatin1String("BODYPIPE="))) {
Laurent Montel's avatar
Laurent Montel committed
461 462 463 464 465 466 467 468 469 470 471 472
                // pipe message body generated so far through command and insert result as is
                qCDebug(TEMPLATEPARSER_LOG) << "Command: BODYPIPE=";
                QString q;
                const int len = parseQuotes(QStringLiteral("BODYPIPE="), cmd, q);
                i += len;
                const QString pipe_cmd = q;
                const QString plainStr = pipe(pipe_cmd, plainBody);
                plainBody.append(plainStr);

                const QString htmlStr = pipe(pipe_cmd, htmlBody);
                const QString body = plainToHtml(htmlStr);
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
473
            } else if (cmd.startsWith(QLatin1String("CLEARPIPE="))) {
Laurent Montel's avatar
Laurent Montel committed
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488
                // pipe message body generated so far through command and
                // insert result as is replacing current body
                qCDebug(TEMPLATEPARSER_LOG) << "Command: CLEARPIPE=";
                QString q;
                const int len = parseQuotes(QStringLiteral("CLEARPIPE="), cmd, q);
                i += len;
                const QString pipe_cmd = q;
                const QString plainStr = pipe(pipe_cmd, plainBody);
                plainBody = plainStr;

                const QString htmlStr = pipe(pipe_cmd, htmlBody);
                htmlBody = htmlStr;

                KMime::Headers::Generic *header = new KMime::Headers::Generic("X-KMail-CursorPos");
                header->fromUnicodeString(QString::number(0), "utf-8");
489
                d->mMsg->setHeader(header);
Laurent Montel's avatar
Laurent Montel committed
490
            } else if (cmd.startsWith(QLatin1String("TEXT"))) {
Laurent Montel's avatar
Laurent Montel committed
491 492
                qCDebug(TEMPLATEPARSER_LOG) << "Command: TEXT";
                i += strlen("TEXT");
493
                if (d->mOrigMsg) {
Laurent Montel's avatar
Laurent Montel committed
494 495 496 497 498 499
                    const QString plainStr = plainMessageText(shouldStripSignature(), NoSelectionAllowed);
                    plainBody.append(plainStr);

                    const QString htmlStr = htmlMessageText(shouldStripSignature(), NoSelectionAllowed);
                    htmlBody.append(htmlStr);
                }
Laurent Montel's avatar
Laurent Montel committed
500
            } else if (cmd.startsWith(QLatin1String("OTEXTSIZE"))) {
Laurent Montel's avatar
Laurent Montel committed
501 502
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OTEXTSIZE";
                i += strlen("OTEXTSIZE");
503 504
                if (d->mOrigMsg) {
                    const QString str = QStringLiteral("%1").arg(d->mOrigMsg->body().length());
Laurent Montel's avatar
Laurent Montel committed
505 506 507 508
                    plainBody.append(str);
                    const QString body = plainToHtml(str);
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
509
            } else if (cmd.startsWith(QLatin1String("OTEXT"))) {
Laurent Montel's avatar
Laurent Montel committed
510 511
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OTEXT";
                i += strlen("OTEXT");
512
                if (d->mOrigMsg) {
Laurent Montel's avatar
Laurent Montel committed
513 514 515 516 517 518
                    const QString plainStr = plainMessageText(shouldStripSignature(), NoSelectionAllowed);
                    plainBody.append(plainStr);

                    const QString htmlStr = htmlMessageText(shouldStripSignature(), NoSelectionAllowed);
                    htmlBody.append(htmlStr);
                }
Laurent Montel's avatar
Laurent Montel committed
519
            } else if (cmd.startsWith(QLatin1String("OADDRESSEESADDR"))) {
Laurent Montel's avatar
Laurent Montel committed
520 521
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OADDRESSEESADDR";
                i += strlen("OADDRESSEESADDR");
522 523 524
                if (d->mOrigMsg) {
                    const QString to = d->mOrigMsg->to()->asUnicodeString();
                    const QString cc = d->mOrigMsg->cc()->asUnicodeString();
Laurent Montel's avatar
Laurent Montel committed
525
                    if (!to.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
526
                        const QString toLine = i18nc("@item:intext email To", "To:") + QLatin1Char(' ') + to;
Laurent Montel's avatar
Laurent Montel committed
527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
                        plainBody.append(toLine);
                        const QString body = plainToHtml(toLine);
                        htmlBody.append(body);
                    }
                    if (!to.isEmpty() && !cc.isEmpty()) {
                        plainBody.append(QLatin1Char('\n'));
                        const QString str = plainToHtml(QString(QLatin1Char('\n')));
                        htmlBody.append(str);
                    }
                    if (!cc.isEmpty()) {
                        const QString ccLine = i18nc("@item:intext email CC", "CC:") + QLatin1Char(' ') +  cc;
                        plainBody.append(ccLine);
                        const QString str = plainToHtml(ccLine);
                        htmlBody.append(str);
                    }
                }
Laurent Montel's avatar
Laurent Montel committed
543
            } else if (cmd.startsWith(QLatin1String("CCADDR"))) {
Laurent Montel's avatar
Laurent Montel committed
544 545
                qCDebug(TEMPLATEPARSER_LOG) << "Command: CCADDR";
                i += strlen("CCADDR");
546
                const QString str = d->mMsg->cc()->asUnicodeString();
Laurent Montel's avatar
Laurent Montel committed
547 548 549
                plainBody.append(str);
                const QString body = plainToHtml(str);
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
550
            } else if (cmd.startsWith(QLatin1String("CCNAME"))) {
Laurent Montel's avatar
Laurent Montel committed
551 552
                qCDebug(TEMPLATEPARSER_LOG) << "Command: CCNAME";
                i += strlen("CCNAME");
553
                const QString str = d->mMsg->cc()->displayString();
Laurent Montel's avatar
Laurent Montel committed
554 555 556
                plainBody.append(str);
                const QString body = plainToHtml(str);
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
557
            } else if (cmd.startsWith(QLatin1String("CCFNAME"))) {
Laurent Montel's avatar
Laurent Montel committed
558 559
                qCDebug(TEMPLATEPARSER_LOG) << "Command: CCFNAME";
                i += strlen("CCFNAME");
560
                const QString str = d->mMsg->cc()->displayString();
Laurent Montel's avatar
Laurent Montel committed
561 562 563
                const QString firstNameFromEmail = TemplateParser::Util::getFirstNameFromEmail(str);
                plainBody.append(firstNameFromEmail);
                const QString body = plainToHtml(firstNameFromEmail);
Laurent Montel's avatar
Laurent Montel committed
564
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
565
            } else if (cmd.startsWith(QLatin1String("CCLNAME"))) {
Laurent Montel's avatar
Laurent Montel committed
566 567
                qCDebug(TEMPLATEPARSER_LOG) << "Command: CCLNAME";
                i += strlen("CCLNAME");
568
                const QString str = d->mMsg->cc()->displayString();
Laurent Montel's avatar
Laurent Montel committed
569 570
                plainBody.append(TemplateParser::Util::getLastNameFromEmail(str));
                const QString body = plainToHtml(TemplateParser::Util::getLastNameFromEmail(str));
Laurent Montel's avatar
Laurent Montel committed
571
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
572
            } else if (cmd.startsWith(QLatin1String("TOADDR"))) {
Laurent Montel's avatar
Laurent Montel committed
573 574
                qCDebug(TEMPLATEPARSER_LOG) << "Command: TOADDR";
                i += strlen("TOADDR");
575
                const QString str = d->mMsg->to()->asUnicodeString();
Laurent Montel's avatar
Laurent Montel committed
576 577 578
                plainBody.append(str);
                const QString body = plainToHtml(str);
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
579
            } else if (cmd.startsWith(QLatin1String("TONAME"))) {
Laurent Montel's avatar
Laurent Montel committed
580 581
                qCDebug(TEMPLATEPARSER_LOG) << "Command: TONAME";
                i += strlen("TONAME");
582
                const QString str = (d->mMsg->to()->displayString());
Laurent Montel's avatar
Laurent Montel committed
583 584 585
                plainBody.append(str);
                const QString body = plainToHtml(str);
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
586
            } else if (cmd.startsWith(QLatin1String("TOFNAME"))) {
Laurent Montel's avatar
Laurent Montel committed
587 588
                qCDebug(TEMPLATEPARSER_LOG) << "Command: TOFNAME";
                i += strlen("TOFNAME");
589
                const QString str = d->mMsg->to()->displayString();
Laurent Montel's avatar
Laurent Montel committed
590 591 592
                const QString firstNameFromEmail = TemplateParser::Util::getFirstNameFromEmail(str);
                plainBody.append(firstNameFromEmail);
                const QString body = plainToHtml(firstNameFromEmail);
Laurent Montel's avatar
Laurent Montel committed
593
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
594
            } else if (cmd.startsWith(QLatin1String("TOLNAME"))) {
Laurent Montel's avatar
Laurent Montel committed
595 596
                qCDebug(TEMPLATEPARSER_LOG) << "Command: TOLNAME";
                i += strlen("TOLNAME");
597
                const QString str = d->mMsg->to()->displayString();
Laurent Montel's avatar
Laurent Montel committed
598 599
                plainBody.append(TemplateParser::Util::getLastNameFromEmail(str));
                const QString body = plainToHtml(TemplateParser::Util::getLastNameFromEmail(str));
Laurent Montel's avatar
Laurent Montel committed
600
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
601
            } else if (cmd.startsWith(QLatin1String("TOLIST"))) {
Laurent Montel's avatar
Laurent Montel committed
602 603
                qCDebug(TEMPLATEPARSER_LOG) << "Command: TOLIST";
                i += strlen("TOLIST");
604
                const QString str = d->mMsg->to()->asUnicodeString();
Laurent Montel's avatar
Laurent Montel committed
605 606 607
                plainBody.append(str);
                const QString body = plainToHtml(str);
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
608
            } else if (cmd.startsWith(QLatin1String("FROMADDR"))) {
Laurent Montel's avatar
Laurent Montel committed
609 610
                qCDebug(TEMPLATEPARSER_LOG) << "Command: FROMADDR";
                i += strlen("FROMADDR");
611
                const QString str = d->mMsg->from()->asUnicodeString();
Laurent Montel's avatar
Laurent Montel committed
612 613 614
                plainBody.append(str);
                const QString body = plainToHtml(str);
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
615
            } else if (cmd.startsWith(QLatin1String("FROMNAME"))) {
Laurent Montel's avatar
Laurent Montel committed
616 617
                qCDebug(TEMPLATEPARSER_LOG) << "Command: FROMNAME";
                i += strlen("FROMNAME");
618
                const QString str = d->mMsg->from()->displayString();
Laurent Montel's avatar
Laurent Montel committed
619 620 621
                plainBody.append(str);
                const QString body = plainToHtml(str);
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
622
            } else if (cmd.startsWith(QLatin1String("FROMFNAME"))) {
Laurent Montel's avatar
Laurent Montel committed
623 624
                qCDebug(TEMPLATEPARSER_LOG) << "Command: FROMFNAME";
                i += strlen("FROMFNAME");
625
                const QString str = d->mMsg->from()->displayString();
Laurent Montel's avatar
Laurent Montel committed
626 627 628
                const QString firstNameFromEmail = TemplateParser::Util::getFirstNameFromEmail(str);
                plainBody.append(firstNameFromEmail);
                const QString body = plainToHtml(firstNameFromEmail);
Laurent Montel's avatar
Laurent Montel committed
629
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
630
            } else if (cmd.startsWith(QLatin1String("FROMLNAME"))) {
Laurent Montel's avatar
Laurent Montel committed
631 632
                qCDebug(TEMPLATEPARSER_LOG) << "Command: FROMLNAME";
                i += strlen("FROMLNAME");
633
                const QString str = d->mMsg->from()->displayString();
Laurent Montel's avatar
Laurent Montel committed
634 635
                plainBody.append(TemplateParser::Util::getLastNameFromEmail(str));
                const QString body = plainToHtml(TemplateParser::Util::getLastNameFromEmail(str));
Laurent Montel's avatar
Laurent Montel committed
636
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
637 638
            } else if (cmd.startsWith(QLatin1String("FULLSUBJECT")) || cmd.startsWith(QLatin1String("FULLSUBJ"))) {
                if (cmd.startsWith(QLatin1String("FULLSUBJ"))) {
Laurent Montel's avatar
Laurent Montel committed
639 640 641 642 643 644
                    qCDebug(TEMPLATEPARSER_LOG) << "Command: FULLSUBJ";
                    i += strlen("FULLSUBJ");
                } else {
                    qCDebug(TEMPLATEPARSER_LOG) << "Command: FULLSUBJECT";
                    i += strlen("FULLSUBJECT");
                }
645
                const QString str = d->mMsg->subject()->asUnicodeString();
Laurent Montel's avatar
Laurent Montel committed
646 647 648
                plainBody.append(str);
                const QString body = plainToHtml(str);
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
649
            } else if (cmd.startsWith(QLatin1String("MSGID"))) {
Laurent Montel's avatar
Laurent Montel committed
650 651
                qCDebug(TEMPLATEPARSER_LOG) << "Command: MSGID";
                i += strlen("MSGID");
652
                const QString str = d->mMsg->messageID()->asUnicodeString();
Laurent Montel's avatar
Laurent Montel committed
653 654 655
                plainBody.append(str);
                const QString body = plainToHtml(str);
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
656
            } else if (cmd.startsWith(QLatin1String("OHEADER="))) {
Laurent Montel's avatar
Laurent Montel committed
657 658 659 660 661
                // insert specified content of header from original message
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OHEADER=";
                QString q;
                const int len = parseQuotes(QStringLiteral("OHEADER="), cmd, q);
                i += len;
662
                if (d->mOrigMsg) {
Laurent Montel's avatar
Laurent Montel committed
663 664
                    const QString hdr = q;
                    QString str;
665
                    if (auto hrdMsgOrigin = d->mOrigMsg->headerByType(hdr.toLocal8Bit().constData())) {
Laurent Montel's avatar
Laurent Montel committed
666 667 668 669 670 671
                        str = hrdMsgOrigin->asUnicodeString();
                    }
                    plainBody.append(str);
                    const QString body = plainToHtml(str);
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
672
            } else if (cmd.startsWith(QLatin1String("HEADER="))) {
Laurent Montel's avatar
Laurent Montel committed
673 674 675 676 677 678 679
                // insert specified content of header from current message
                qCDebug(TEMPLATEPARSER_LOG) << "Command: HEADER=";
                QString q;
                const int len = parseQuotes(QStringLiteral("HEADER="), cmd, q);
                i += len;
                const QString hdr = q;
                QString str;
680
                if (auto hrdMsgOrigin = d->mOrigMsg->headerByType(hdr.toLocal8Bit().constData())) {
Laurent Montel's avatar
Laurent Montel committed
681 682 683 684 685
                    str = hrdMsgOrigin->asUnicodeString();
                }
                plainBody.append(str);
                const QString body = plainToHtml(str);
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
686
            } else if (cmd.startsWith(QLatin1String("HEADER( "))) {
Laurent Montel's avatar
Laurent Montel committed
687 688 689 690 691 692 693 694 695 696
                // insert specified content of header from current message
                qCDebug(TEMPLATEPARSER_LOG) << "Command: HEADER(";
                QRegExp re = QRegExp(QLatin1String("^HEADER\\((.+)\\)"));
                re.setMinimal(true);
                int res = re.indexIn(cmd);
                if (res != 0) {
                    // something wrong
                    i += strlen("HEADER( ");
                } else {
                    i += re.matchedLength();
697
                    const QString hdr = re.cap(1).trimmed();
Laurent Montel's avatar
Laurent Montel committed
698
                    QString str;
699
                    if (auto hrdMsgOrigin = d->mOrigMsg->headerByType(hdr.toLocal8Bit().constData())) {
Laurent Montel's avatar
Laurent Montel committed
700 701 702 703 704 705
                        str = hrdMsgOrigin->asUnicodeString();
                    }
                    plainBody.append(str);
                    const QString body = plainToHtml(str);
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
706
            } else if (cmd.startsWith(QLatin1String("OCCADDR"))) {
Laurent Montel's avatar
Laurent Montel committed
707 708
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OCCADDR";
                i += strlen("OCCADDR");
709 710
                if (d->mOrigMsg) {
                    const QString str = d->mOrigMsg->cc()->asUnicodeString();
Laurent Montel's avatar
Laurent Montel committed
711 712 713 714
                    plainBody.append(str);
                    const QString body = plainToHtml(str);
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
715
            } else if (cmd.startsWith(QLatin1String("OCCNAME"))) {
Laurent Montel's avatar
Laurent Montel committed
716 717
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OCCNAME";
                i += strlen("OCCNAME");
718 719
                if (d->mOrigMsg) {
                    const QString str = d->mOrigMsg->cc()->displayString();
Laurent Montel's avatar
Laurent Montel committed
720 721 722 723
                    plainBody.append(str);
                    const QString body = plainToHtml(str);
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
724
            } else if (cmd.startsWith(QLatin1String("OCCFNAME"))) {
Laurent Montel's avatar
Laurent Montel committed
725 726
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OCCFNAME";
                i += strlen("OCCFNAME");
727 728
                if (d->mOrigMsg) {
                    const QString str = d->mOrigMsg->cc()->displayString();
Laurent Montel's avatar
Laurent Montel committed
729 730 731
                    const QString firstNameFromEmail = TemplateParser::Util::getFirstNameFromEmail(str);
                    plainBody.append(firstNameFromEmail);
                    const QString body = plainToHtml(firstNameFromEmail);
Laurent Montel's avatar
Laurent Montel committed
732 733
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
734
            } else if (cmd.startsWith(QLatin1String("OCCLNAME"))) {
Laurent Montel's avatar
Laurent Montel committed
735 736
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OCCLNAME";
                i += strlen("OCCLNAME");
737 738
                if (d->mOrigMsg) {
                    const QString str = d->mOrigMsg->cc()->displayString();
Laurent Montel's avatar
Laurent Montel committed
739 740
                    plainBody.append(TemplateParser::Util::getLastNameFromEmail(str));
                    const QString body = plainToHtml(TemplateParser::Util::getLastNameFromEmail(str));
Laurent Montel's avatar
Laurent Montel committed
741 742
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
743
            } else if (cmd.startsWith(QLatin1String("OTOADDR"))) {
Laurent Montel's avatar
Laurent Montel committed
744 745
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OTOADDR";
                i += strlen("OTOADDR");
746 747
                if (d->mOrigMsg) {
                    const QString str = d->mOrigMsg->to()->asUnicodeString();
Laurent Montel's avatar
Laurent Montel committed
748 749 750 751
                    plainBody.append(str);
                    const QString body = plainToHtml(str);
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
752
            } else if (cmd.startsWith(QLatin1String("OTONAME"))) {
Laurent Montel's avatar
Laurent Montel committed
753 754
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OTONAME";
                i += strlen("OTONAME");
755 756
                if (d->mOrigMsg) {
                    const QString str = d->mOrigMsg->to()->displayString();
Laurent Montel's avatar
Laurent Montel committed
757 758 759 760
                    plainBody.append(str);
                    const QString body = plainToHtml(str);
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
761
            } else if (cmd.startsWith(QLatin1String("OTOFNAME"))) {
Laurent Montel's avatar
Laurent Montel committed
762 763
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OTOFNAME";
                i += strlen("OTOFNAME");
764 765
                if (d->mOrigMsg) {
                    const QString str = d->mOrigMsg->to()->displayString();
Laurent Montel's avatar
Laurent Montel committed
766 767 768
                    const QString firstNameFromEmail = TemplateParser::Util::getFirstNameFromEmail(str);
                    plainBody.append(firstNameFromEmail);
                    const QString body = plainToHtml(firstNameFromEmail);
Laurent Montel's avatar
Laurent Montel committed
769 770
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
771
            } else if (cmd.startsWith(QLatin1String("OTOLNAME"))) {
Laurent Montel's avatar
Laurent Montel committed
772 773
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OTOLNAME";
                i += strlen("OTOLNAME");
774 775
                if (d->mOrigMsg) {
                    const QString str = d->mOrigMsg->to()->displayString();
Laurent Montel's avatar
Laurent Montel committed
776 777
                    plainBody.append(TemplateParser::Util::getLastNameFromEmail(str));
                    const QString body = plainToHtml(TemplateParser::Util::getLastNameFromEmail(str));
Laurent Montel's avatar
Laurent Montel committed
778 779
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
780
            } else if (cmd.startsWith(QLatin1String("OTOLIST"))) {
Laurent Montel's avatar
Laurent Montel committed
781 782
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OTOLIST";
                i += strlen("OTOLIST");
783 784
                if (d->mOrigMsg) {
                    const QString str = d->mOrigMsg->to()->asUnicodeString();
Laurent Montel's avatar
Laurent Montel committed
785 786 787 788
                    plainBody.append(str);
                    const QString body = plainToHtml(str);
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
789
            } else if (cmd.startsWith(QLatin1String("OTO"))) {
Laurent Montel's avatar
Laurent Montel committed
790 791
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OTO";
                i += strlen("OTO");
792 793
                if (d->mOrigMsg) {
                    const QString str = d->mOrigMsg->to()->asUnicodeString();
Laurent Montel's avatar
Laurent Montel committed
794 795 796 797
                    plainBody.append(str);
                    const QString body = plainToHtml(str);
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
798
            } else if (cmd.startsWith(QLatin1String("OFROMADDR"))) {
Laurent Montel's avatar
Laurent Montel committed
799 800
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OFROMADDR";
                i += strlen("OFROMADDR");
801 802
                if (d->mOrigMsg) {
                    const QString str = d->mOrigMsg->from()->asUnicodeString();
Laurent Montel's avatar
Laurent Montel committed
803 804 805 806
                    plainBody.append(str);
                    const QString body = plainToHtml(str);
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
807
            } else if (cmd.startsWith(QLatin1String("OFROMNAME"))) {
Laurent Montel's avatar
Laurent Montel committed
808 809
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OFROMNAME";
                i += strlen("OFROMNAME");
810 811
                if (d->mOrigMsg) {
                    const QString str = d->mOrigMsg->from()->displayString();
Laurent Montel's avatar
Laurent Montel committed
812 813 814 815
                    plainBody.append(str);
                    const QString body = plainToHtml(str);
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
816
            } else if (cmd.startsWith(QLatin1String("OFROMFNAME"))) {
Laurent Montel's avatar
Laurent Montel committed
817 818
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OFROMFNAME";
                i += strlen("OFROMFNAME");
819 820
                if (d->mOrigMsg) {
                    const QString str = d->mOrigMsg->from()->displayString();
Laurent Montel's avatar
Laurent Montel committed
821 822 823
                    const QString firstNameFromEmail = TemplateParser::Util::getFirstNameFromEmail(str);
                    plainBody.append(firstNameFromEmail);
                    const QString body = plainToHtml(firstNameFromEmail);
Laurent Montel's avatar
Laurent Montel committed
824 825
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
826
            } else if (cmd.startsWith(QLatin1String("OFROMLNAME"))) {
Laurent Montel's avatar
Laurent Montel committed
827 828
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OFROMLNAME";
                i += strlen("OFROMLNAME");
829 830
                if (d->mOrigMsg) {
                    const QString str = d->mOrigMsg->from()->displayString();
Laurent Montel's avatar
Laurent Montel committed
831 832
                    plainBody.append(TemplateParser::Util::getLastNameFromEmail(str));
                    const QString body = plainToHtml(TemplateParser::Util::getLastNameFromEmail(str));
Laurent Montel's avatar
Laurent Montel committed
833 834
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
835 836
            } else if (cmd.startsWith(QLatin1String("OFULLSUBJECT")) || cmd.startsWith(QLatin1String("OFULLSUBJ"))) {
                if (cmd.startsWith(QLatin1String("OFULLSUBJECT"))) {
Laurent Montel's avatar
Laurent Montel committed
837 838 839 840 841 842
                    qCDebug(TEMPLATEPARSER_LOG) << "Command: OFULLSUBJECT";
                    i += strlen("OFULLSUBJECT");
                } else {
                    qCDebug(TEMPLATEPARSER_LOG) << "Command: OFULLSUBJ";
                    i += strlen("OFULLSUBJ");
                }
843 844
                if (d->mOrigMsg) {
                    const QString str = d->mOrigMsg->subject()->asUnicodeString();
Laurent Montel's avatar
Laurent Montel committed
845 846 847 848
                    plainBody.append(str);
                    const QString body = plainToHtml(str);
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
849
            } else if (cmd.startsWith(QLatin1String("OMSGID"))) {
Laurent Montel's avatar
Laurent Montel committed
850 851
                qCDebug(TEMPLATEPARSER_LOG) << "Command: OMSGID";
                i += strlen("OMSGID");
852 853
                if (d->mOrigMsg) {
                    const QString str = d->mOrigMsg->messageID()->asUnicodeString();
Laurent Montel's avatar
Laurent Montel committed
854 855 856 857
                    plainBody.append(str);
                    const QString body = plainToHtml(str);
                    htmlBody.append(body);
                }
Laurent Montel's avatar
Laurent Montel committed
858
            } else if (cmd.startsWith(QLatin1String("DATEEN"))) {
Laurent Montel's avatar
Laurent Montel committed
859 860 861 862 863 864 865 866
                qCDebug(TEMPLATEPARSER_LOG) << "Command: DATEEN";
                i += strlen("DATEEN");
                const QDateTime date = QDateTime::currentDateTime();
                QLocale locale(QLocale::C);
                const QString str = locale.toString(date.date(), QLocale::LongFormat);
                plainBody.append(str);
                const QString body = plainToHtml(str);
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
867
            } else if (cmd.startsWith(QLatin1String("DATESHORT"))) {
Laurent Montel's avatar
Laurent Montel committed
868 869 870 871 872 873 874
                qCDebug(TEMPLATEPARSER_LOG) << "Command: DATESHORT";
                i += strlen("DATESHORT");
                const QDateTime date = QDateTime::currentDateTime();
                const QString str = definedLocale.toString(date.date(), QLocale::ShortFormat);
                plainBody.append(str);
                const QString body = plainToHtml(str);
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
875
            } else if (cmd.startsWith(QLatin1String("DATE"))) {
Laurent Montel's avatar
Laurent Montel committed
876 877 878 879 880 881 882
                qCDebug(TEMPLATEPARSER_LOG) << "Command: DATE";
                i += strlen("DATE");
                const QDateTime date = QDateTime::currentDateTime();
                const QString str = definedLocale.toString(date.date(), QLocale::LongFormat);
                plainBody.append(str);
                const QString body = plainToHtml(str);
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
883
            } else if (cmd.startsWith(QLatin1String("DOW"))) {
Laurent Montel's avatar
Laurent Montel committed
884 885 886 887 888 889 890
                qCDebug(TEMPLATEPARSER_LOG) << "Command: DOW";
                i += strlen("DOW");
                const QDateTime date = QDateTime::currentDateTime();
                const QString str = definedLocale.dayName(date.date().dayOfWeek(), QLocale::LongFormat);
                plainBody.append(str);
                const QString body = plainToHtml(str);
                htmlBody.append(body);
Laurent Montel's avatar
Laurent Montel committed
891
            } else if (cmd.startsWith(QLatin1String("TIMELONGEN"))) {
Laurent Montel's avatar
Laurent Montel committed
892 <