diff --git a/messageviewer/src/header/autotests/data/allheaders.mbox.html b/messageviewer/src/header/autotests/data/allheaders.mbox.html --- a/messageviewer/src/header/autotests/data/allheaders.mbox.html +++ b/messageviewer/src/header/autotests/data/allheaders.mbox.html @@ -49,13 +49,12 @@
21 May 2018 16:52:43
-
Spam Status:
+
Spam Status:
Spamassassin NBSP_ENTITY_PLACEHOLDER
-
-
+
diff --git a/messageviewer/src/header/autotests/data/empty.html b/messageviewer/src/header/autotests/data/empty.html --- a/messageviewer/src/header/autotests/data/empty.html +++ b/messageviewer/src/header/autotests/data/empty.html @@ -19,9 +19,8 @@
Unknown
-
-
+
diff --git a/messageviewer/src/header/autotests/data/resentFromtest.tmpl b/messageviewer/src/header/autotests/data/resentFromtest.tmpl new file mode 100644 --- /dev/null +++ b/messageviewer/src/header/autotests/data/resentFromtest.tmpl @@ -0,0 +1,7 @@ +
nameOnly: {{ header.resentFrom.nameOnly|safe }}
+
isSet: {{ header.resentFrom.isSet|safe }}
+
fullAddress: {{ header.resentFrom.fullAddress|safe }}
+
str: {{ header.resentFrom.str }}
+
expandable: {{ header.resentFrom.expandableResentFrom|safe }}
+
expandableTO: {{ header.resentFrom.expandableTO|safe }}
+
invalid: {{ header.resentFrom.invalid|safe }}
diff --git a/messageviewer/src/header/autotests/data/resentFromtest.tmpl.html b/messageviewer/src/header/autotests/data/resentFromtest.tmpl.html --- a/messageviewer/src/header/autotests/data/resentFromtest.tmpl.html +++ b/messageviewer/src/header/autotests/data/resentFromtest.tmpl.html @@ -4,12 +4,12 @@
-
nameOnly:
-
isSet:
+
nameOnly: resent-from@example.org, resent-from2@example.org, resent-from3@example.org, resent-from4@example.org, resent-to5@example.org, resent-to6@example.org
+
isSet: true
fullAddress: resent-from@example.org, resent-from2@example.org, resent-from3@example.org, resent-from4@example.org, resent-to5@example.org, resent-to6@example.org
-
str:
-
expandable:
-
expandableTO:
+
str: resent-from@example.org, resent-from2@example.org, resent-from3@example.org, resent-from4@example.org, resent-to5@example.org, resent-to6@example.org
+
expandable: resent-from@example.org, resent-from2@example.org, resent-from3@example.org, resent-from4@example.orgresent-from@example.org, resent-from2@example.org, resent-from3@example.org, resent-from4@example.org, resent-to5@example.org, resent-to6@example.org
+
expandableTO: resent-from@example.org, resent-from2@example.org, resent-from3@example.org, resent-from4@example.orgresent-from@example.org, resent-from2@example.org, resent-from3@example.org, resent-from4@example.org, resent-to5@example.org, resent-to6@example.org
invalid:
diff --git a/messageviewer/src/header/autotests/data/resentTotest.tmpl b/messageviewer/src/header/autotests/data/resentTotest.tmpl new file mode 100644 --- /dev/null +++ b/messageviewer/src/header/autotests/data/resentTotest.tmpl @@ -0,0 +1,7 @@ +
nameOnly: {{ header.resentTo.nameOnly|safe }}
+
isSet: {{ header.resentTo.isSet|safe }}
+
fullAddress: {{ header.resentTo.fullAddress|safe }}
+
str: {{ header.resentTo.str }}
+
expandable: {{ header.resentTo.expandableResentto|safe }}
+
expandableTO: {{ header.resentTo.expandableTO|safe }}
+
invalid: {{ header.resentTo.invalid|safe }}
diff --git a/messageviewer/src/header/autotests/data/resentTotest.tmpl.html b/messageviewer/src/header/autotests/data/resentTotest.tmpl.html --- a/messageviewer/src/header/autotests/data/resentTotest.tmpl.html +++ b/messageviewer/src/header/autotests/data/resentTotest.tmpl.html @@ -4,12 +4,12 @@
-
nameOnly:
-
isSet:
+
nameOnly: resent-to@example.org, resent-to2@example.org, resent-to3@example.org, resent-to4@example.org, resent-to5@example.org, resent-to6@example.org
+
isSet: true
fullAddress: resent-to@example.org, resent-to2@example.org, resent-to3@example.org, resent-to4@example.org, resent-to5@example.org, resent-to6@example.org
-
str:
-
expandable:
-
expandableTO:
+
str: resent-to@example.org, resent-to2@example.org, resent-to3@example.org, resent-to4@example.org, resent-to5@example.org, resent-to6@example.org
+
expandable: resent-to@example.org, resent-to2@example.org, resent-to3@example.org, resent-to4@example.orgresent-to@example.org, resent-to2@example.org, resent-to3@example.org, resent-to4@example.org, resent-to5@example.org, resent-to6@example.org
+
expandableTO: resent-to@example.org, resent-to2@example.org, resent-to3@example.org, resent-to4@example.orgresent-to@example.org, resent-to2@example.org, resent-to3@example.org, resent-to4@example.org, resent-to5@example.org, resent-to6@example.org
invalid:
diff --git a/messageviewer/src/header/autotests/data/resentfromtest.tmpl b/messageviewer/src/header/autotests/data/resentfromtest.tmpl deleted file mode 100644 --- a/messageviewer/src/header/autotests/data/resentfromtest.tmpl +++ /dev/null @@ -1,7 +0,0 @@ -
nameOnly: {{ header.resentfrom.nameOnly|safe }}
-
isSet: {{ header.resentfrom.isSet|safe }}
-
fullAddress: {{ header.resentfrom.fullAddress|safe }}
-
str: {{ header.resentfrom.str }}
-
expandable: {{ header.resentfrom.expandableResentFrom|safe }}
-
expandableTO: {{ header.resentfrom.expandableTO|safe }}
-
invalid: {{ header.resentfrom.invalid|safe }}
diff --git a/messageviewer/src/header/autotests/data/resentfromtest.tmpl.html b/messageviewer/src/header/autotests/data/resentfromtest.tmpl.html deleted file mode 100644 --- a/messageviewer/src/header/autotests/data/resentfromtest.tmpl.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - -
-
-
nameOnly: resent-from@example.org, resent-from2@example.org, resent-from3@example.org, resent-from4@example.org, resent-to5@example.org, resent-to6@example.org
-
isSet: true
-
fullAddress: resent-from@example.org, resent-from2@example.org, resent-from3@example.org, resent-from4@example.org, resent-to5@example.org, resent-to6@example.org
-
str: resent-from@example.org, resent-from2@example.org, resent-from3@example.org, resent-from4@example.org, resent-to5@example.org, resent-to6@example.org
-
expandable: resent-from@example.org, resent-from2@example.org, resent-from3@example.org, resent-from4@example.orgresent-from@example.org, resent-from2@example.org, resent-from3@example.org, resent-from4@example.org, resent-to5@example.org, resent-to6@example.org
-
expandableTO: resent-from@example.org, resent-from2@example.org, resent-from3@example.org, resent-from4@example.orgresent-from@example.org, resent-from2@example.org, resent-from3@example.org, resent-from4@example.org, resent-to5@example.org, resent-to6@example.org
-
invalid:
-
-
- - diff --git a/messageviewer/src/header/autotests/data/resenttotest.tmpl b/messageviewer/src/header/autotests/data/resenttotest.tmpl deleted file mode 100644 --- a/messageviewer/src/header/autotests/data/resenttotest.tmpl +++ /dev/null @@ -1,7 +0,0 @@ -
nameOnly: {{ header.resentto.nameOnly|safe }}
-
isSet: {{ header.resentto.isSet|safe }}
-
fullAddress: {{ header.resentto.fullAddress|safe }}
-
str: {{ header.resentto.str }}
-
expandable: {{ header.resentto.expandableResentto|safe }}
-
expandableTO: {{ header.resentto.expandableTO|safe }}
-
invalid: {{ header.resentto.invalid|safe }}
diff --git a/messageviewer/src/header/autotests/data/resenttotest.tmpl.html b/messageviewer/src/header/autotests/data/resenttotest.tmpl.html deleted file mode 100644 --- a/messageviewer/src/header/autotests/data/resenttotest.tmpl.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - -
-
-
nameOnly: resent-to@example.org, resent-to2@example.org, resent-to3@example.org, resent-to4@example.org, resent-to5@example.org, resent-to6@example.org
-
isSet: true
-
fullAddress: resent-to@example.org, resent-to2@example.org, resent-to3@example.org, resent-to4@example.org, resent-to5@example.org, resent-to6@example.org
-
str: resent-to@example.org, resent-to2@example.org, resent-to3@example.org, resent-to4@example.org, resent-to5@example.org, resent-to6@example.org
-
expandable: resent-to@example.org, resent-to2@example.org, resent-to3@example.org, resent-to4@example.orgresent-to@example.org, resent-to2@example.org, resent-to3@example.org, resent-to4@example.org, resent-to5@example.org, resent-to6@example.org
-
expandableTO: resent-to@example.org, resent-to2@example.org, resent-to3@example.org, resent-to4@example.orgresent-to@example.org, resent-to2@example.org, resent-to3@example.org, resent-to4@example.org, resent-to5@example.org, resent-to6@example.org
-
invalid:
-
-
- - diff --git a/messageviewer/src/header/autotests/data/vcard.html b/messageviewer/src/header/autotests/data/vcard.html --- a/messageviewer/src/header/autotests/data/vcard.html +++ b/messageviewer/src/header/autotests/data/vcard.html @@ -21,9 +21,8 @@
Unknown
-
-
+
diff --git a/messageviewer/src/header/grantleeheaderformatter.cpp b/messageviewer/src/header/grantleeheaderformatter.cpp --- a/messageviewer/src/header/grantleeheaderformatter.cpp +++ b/messageviewer/src/header/grantleeheaderformatter.cpp @@ -144,6 +144,116 @@ } } +class Q_DECL_HIDDEN HeaderFormatter +{ +public: + virtual ~HeaderFormatter(){} + virtual QVariant format(KMime::Message *message, MimeTreeParser::NodeHelper *nodeHelper) = 0; + virtual QString i18nName() = 0; +}; + +class DefaultHeaderFormatter: public HeaderFormatter +{ +public: + DefaultHeaderFormatter(const QByteArray &h) + : header(h) + { + } + + QString i18nName() override { + if (header == "list-id") { + return i18n("List-Id:"); + } else { + return QString(); + } + } + + QVariant format(KMime::Message *message, MimeTreeParser::NodeHelper *nodeHelper) override { + return nodeHelper->mailHeaderAsBase(header.constData(), message)->asUnicodeString(); + } +private: + QByteArray header; +}; + +class SubjectFormatter: public HeaderFormatter +{ +public: + QString i18nName() override { + return i18n("Subject:"); + } + + QVariant format(KMime::Message *message, MimeTreeParser::NodeHelper *nodeHelper) override { + KTextToHTML::Options flags = KTextToHTML::PreserveSpaces; + // TODO: somehow, we need to get settings from format method. + //if (showEmoticons) { + // flags |= KTextToHTML::ReplaceSmileys; + //} + auto subjectStr = nodeHelper->mailHeaderAsBase("subject", message)->asUnicodeString(); + + if (subjectStr.isEmpty()) { + return i18n("No Subject"); + } + + return HeaderStyleUtil::strToHtml(subjectStr, flags); + } +}; + +class DateFormatter: public HeaderFormatter +{ +public: + QString i18nName() override { + return i18n("Date:"); + } + + QVariant format(KMime::Message *message, MimeTreeParser::NodeHelper *nodeHelper) override { + const auto value = nodeHelper->dateHeader(message); + return value; + } +}; + + + +class AddressHeaderFormatter: public HeaderFormatter +{ +public: + AddressHeaderFormatter(const QByteArray &h) + : header(h) + { + } + + QString i18nName() override { + if (header == "to") { + return i18n("To:"); + } else if (header == "Reply-To") { + return i18n("Reply To:"); + } else if (header == "replyFrom") { + return i18n("Reply From:"); + } else if (header == "cc") { + return i18n("CC:"); + } else if (header == "bcc") { + return i18n("BCC:"); + } else if (header == "from") { + return i18n("From:"); + } else if (header == "sender") { + return i18n("Sender:"); + } else if (header == "Resent-From") { + return i18n("resent from:"); + } else if (header == "Resent-To") { + return i18n("resent to:"); + } else { + return QString(); + } + } + + QVariant format(KMime::Message *message, MimeTreeParser::NodeHelper *nodeHelper) override { + const auto value = nodeHelper->mailHeaderAsAddressList(header.constData(), message); + return QVariant::fromValue(static_cast(value)); + } + +protected: + QByteArray header; +}; + class Q_DECL_HIDDEN MessageViewer::GrantleeHeaderFormatter::Private { public: @@ -158,14 +268,29 @@ templateLoader = QSharedPointer( new Grantlee::FileSystemTemplateLoader); engine->addTemplateLoader(templateLoader); + + QVector addressHeaders; + addressHeaders << "to" << "reply-To" << "reply-From" << "cc" << "bcc" << "from" << "sender" << "resent-From" << "resent-To"; + + for (const auto &header: addressHeaders) { + registerHeaderFormatter(header, QSharedPointer(new AddressHeaderFormatter(header))); + } + + registerHeaderFormatter("subject", QSharedPointer(new SubjectFormatter())); + registerHeaderFormatter("date", QSharedPointer(new DateFormatter())); } ~Private() { delete engine; } + void registerHeaderFormatter(const QByteArray &header, QSharedPointer formatter) { + headerFormatter[header] = formatter; + } + QSharedPointer templateLoader; + QMap> headerFormatter; Grantlee::Engine *engine = nullptr; MessageViewer::HeaderStyleUtil headerStyleUtil; int iconSize; @@ -226,88 +351,39 @@ headerObject.insert(QStringLiteral("applicationDir"), QApplication::isRightToLeft() ? QStringLiteral("rtl") : QStringLiteral( "ltr")); + + // TODO: use correct subject from nodeHelper->mailHeader headerObject.insert(QStringLiteral("subjectDir"), d->headerStyleUtil.subjectDirectionString(message)); - headerObject.insert(QStringLiteral("subjecti18n"), i18n("Subject:")); - KTextToHTML::Options flags = KTextToHTML::PreserveSpaces; - if (showEmoticons) { - flags |= KTextToHTML::ReplaceSmileys; - } - - headerObject.insert(QStringLiteral("subject"), - d->headerStyleUtil.subjectString(message, flags)); - - if (nodeHelper->hasMailHeader("to", message)) { - const auto value = nodeHelper->mailHeaderAsAddressList("to",message); - headerObject.insert(QStringLiteral("toi18n"), i18n("To:")); - headerObject.insert(QStringLiteral("to"), QVariant::fromValue(static_cast(value))); - } - - if (nodeHelper->hasMailHeader("replyTo", message)) { - const auto value = nodeHelper->mailHeaderAsAddressList("replyTo",message); - headerObject.insert(QStringLiteral("replyToi18n"), i18n("Reply to:")); - headerObject.insert(QStringLiteral("replyTo"), QVariant::fromValue(static_cast(value))); - } - - if (nodeHelper->hasMailHeader("cc", message)) { - const auto value = nodeHelper->mailHeaderAsAddressList("cc",message); - headerObject.insert(QStringLiteral("cci18n"), i18n("CC:")); - headerObject.insert(QStringLiteral("cc"), QVariant::fromValue(static_cast(value))); - } - - if (nodeHelper->hasMailHeader("bcc", message)) { - const auto value = nodeHelper->mailHeaderAsAddressList("bcc",message); - headerObject.insert(QStringLiteral("bcci18n"), i18n("BCC:")); - headerObject.insert(QStringLiteral("bcc"), QVariant::fromValue(static_cast(value))); - } - - { - const auto value = nodeHelper->mailHeaderAsAddressList("from",message); - headerObject.insert(QStringLiteral("fromi18n"), i18n("From:")); - headerObject.insert(QStringLiteral("from"), QVariant::fromValue(static_cast(value))); - } - //Sender - headerObject.insert(QStringLiteral("senderi18n"), i18n("Sender:")); - headerObject.insert(QStringLiteral("sender"), - HeaderStyleUtil::strToHtml(nodeHelper->mailHeaderAsBase("sender", message)->asUnicodeString())); - headerObject.insert(QStringLiteral("listidi18n"), i18n("List-Id:")); - - if (nodeHelper->hasMailHeader("List-Id", message)) { - const auto value = nodeHelper->mailHeaderAsAddressList("List-Id", message); - headerObject.insert(QStringLiteral("listid"), value->asUnicodeString()); + QVector defaultHeaders; + defaultHeaders << "to" << "reply-To" << "reply-From" << "cc" << "bcc" << "from" << "sender" << "resent-From" << "resent-To" << "subject" << "organization" << "list-id" << "date"; + + for (const auto &header: defaultHeaders) { + qDebug() << "add Header" << header; + QSharedPointer formatter; + if (d->headerFormatter.contains(header)) { + formatter = d->headerFormatter.value(header); + } else { + formatter = QSharedPointer(new DefaultHeaderFormatter(header)); + } + const auto i18nName = formatter->i18nName(); + const auto objectName = QString::fromUtf8(header).remove(QLatin1Char('-')); + if (nodeHelper->hasMailHeader(header.constData(), message)) { + const auto value = formatter->format(message, nodeHelper); + headerObject.insert(objectName, value); + } + if (!i18nName.isEmpty()) { + headerObject.insert(objectName+QStringLiteral("i18n"), i18nName); + } } const QString spamHtml = d->headerStyleUtil.spamStatus(message); if (!spamHtml.isEmpty()) { headerObject.insert(QStringLiteral("spamstatusi18n"), i18n("Spam Status:")); headerObject.insert(QStringLiteral("spamHTML"), spamHtml); } - { - const auto value = nodeHelper->dateHeader(message); - headerObject.insert(QStringLiteral("datei18n"), i18n("Date:")); - headerObject.insert(QStringLiteral("date"), QVariant::fromValue(message->date()->dateTime())); - } - - if (nodeHelper->hasMailHeader("Resent-From", message)) { - const auto value = nodeHelper->mailHeaderAsAddressList("Resent-From", message); - headerObject.insert(QStringLiteral("resentfromi18n"), i18n("resent from")); - headerObject.insert(QStringLiteral("resentfrom"), QVariant::fromValue(static_cast(value))); - } - - if (nodeHelper->hasMailHeader("Resent-To", message)) { - const auto resentTo = nodeHelper->mailHeaderAsAddressList("Resent-From", message); - headerObject.insert(QStringLiteral("resenttoi18n"), - i18np("receiver was", "receivers were", resentTo->mailboxes().count())); - headerObject.insert(QStringLiteral("resentto"), QVariant::fromValue(static_cast(resentTo))); - } - - if (auto organization = message->organization(false)) { - headerObject.insert(QStringLiteral("organization"), - HeaderStyleUtil::strToHtml(organization->asUnicodeString())); - } - if (!style->vCardName().isEmpty()) { headerObject.insert(QStringLiteral("vcardname"), style->vCardName()); } diff --git a/messageviewer/src/messageviewerheaderplugins/defaultgrantleeheaderstyleplugin/theme/5.2/header.html b/messageviewer/src/messageviewerheaderplugins/defaultgrantleeheaderstyleplugin/theme/5.2/header.html --- a/messageviewer/src/messageviewerheaderplugins/defaultgrantleeheaderstyleplugin/theme/5.2/header.html +++ b/messageviewer/src/messageviewerheaderplugins/defaultgrantleeheaderstyleplugin/theme/5.2/header.html @@ -43,10 +43,10 @@
{{ header.bcc.fullAddress|safe }}
{% endif %} - {% if header.sender %} + {% if header.sender.isSet %}
{{ header.senderi18n }}
-
{{ header.sender|safe }}
+
{{ header.sender.fullAddress|safe }}
{% endif %} {% if header.listid %}