File indexing completed on 2025-03-09 04:54:33
0001 /* 0002 SPDX-FileCopyrightText: 2013-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "plainheaderstyle.h" 0008 #include "header/headerstyle_util.h" 0009 #include "messageviewer/messageviewersettings.h" 0010 0011 #include "header/headerstrategy.h" 0012 0013 #include <MessageCore/StringUtil> 0014 0015 #include <KLocalizedString> 0016 #include <KMime/KMimeMessage> 0017 #include <QApplication> 0018 0019 using namespace MessageCore; 0020 0021 using namespace MessageViewer; 0022 0023 class MessageViewer::PlainHeaderStylePrivate 0024 { 0025 public: 0026 PlainHeaderStylePrivate() = default; 0027 0028 [[nodiscard]] QString formatAllMessageHeaders(KMime::Message *message) const; 0029 MessageViewer::HeaderStyleUtil mHeaderStyleUtil; 0030 }; 0031 0032 QString PlainHeaderStylePrivate::formatAllMessageHeaders(KMime::Message *message) const 0033 { 0034 QByteArray head = message->head(); 0035 QByteArrayView headView(head); 0036 auto header = KMime::HeaderParsing::parseNextHeader(headView); 0037 QString result; 0038 while (header) { 0039 result += mHeaderStyleUtil.strToHtml(QLatin1StringView(header->type()) + QLatin1StringView(": ") + header->asUnicodeString()); 0040 result += QLatin1StringView("<br />\n"); 0041 header = KMime::HeaderParsing::parseNextHeader(headView); 0042 } 0043 0044 return result; 0045 } 0046 0047 PlainHeaderStyle::PlainHeaderStyle() 0048 : HeaderStyle() 0049 , d(new MessageViewer::PlainHeaderStylePrivate) 0050 { 0051 } 0052 0053 PlainHeaderStyle::~PlainHeaderStyle() = default; 0054 0055 // 0056 // PlainHeaderStyle: 0057 // show every header field on a line by itself, 0058 // show subject larger 0059 // 0060 QString PlainHeaderStyle::format(KMime::Message *message) const 0061 { 0062 if (!message) { 0063 return {}; 0064 } 0065 const HeaderStrategy *strategy = headerStrategy(); 0066 // The direction of the header is determined according to the direction 0067 // of the application layout. 0068 0069 const QString dir = QApplication::isRightToLeft() ? QStringLiteral("rtl") : QStringLiteral("ltr"); 0070 0071 // However, the direction of the message subject within the header is 0072 // determined according to the contents of the subject itself. Since 0073 // the "Re:" and "Fwd:" prefixes would always cause the subject to be 0074 // considered left-to-right, they are ignored when determining its 0075 // direction. 0076 0077 const QString subjectDir = d->mHeaderStyleUtil.subjectDirectionString(message); 0078 QString headerStr; 0079 0080 if (strategy->headersToDisplay().isEmpty() && strategy->defaultPolicy() == HeaderStrategy::Display) { 0081 // crude way to emulate "all" headers - Note: no strings have 0082 // i18n(), so direction should always be ltr. 0083 headerStr = QStringLiteral("<div class=\"header\" dir=\"ltr\">"); 0084 headerStr += d->formatAllMessageHeaders(message); 0085 return headerStr + QLatin1StringView("</div>"); 0086 } 0087 0088 headerStr = QStringLiteral("<div class=\"header\" dir=\"%1\">").arg(dir); 0089 0090 // case HdrLong: 0091 if (strategy->showHeader(QStringLiteral("subject"))) { 0092 KTextToHTML::Options flags = KTextToHTML::PreserveSpaces; 0093 if (showEmoticons()) { 0094 flags |= KTextToHTML::ReplaceSmileys; 0095 } 0096 0097 headerStr += QStringLiteral("<div dir=\"%1\"><b style=\"font-size:130%\">").arg(subjectDir) + d->mHeaderStyleUtil.subjectString(message, flags) 0098 + QLatin1StringView("</b></div>\n"); 0099 } 0100 0101 if (strategy->showHeader(QStringLiteral("date"))) { 0102 const auto dateFormat = isPrinting() ? MessageViewer::HeaderStyleUtil::ShortDate : MessageViewer::HeaderStyleUtil::CustomDate; 0103 headerStr.append(i18n("Date: ") + HeaderStyleUtil::strToHtml(HeaderStyleUtil::dateString(message, dateFormat)) + QLatin1StringView("<br/>\n")); 0104 } 0105 0106 if (strategy->showHeader(QStringLiteral("from"))) { 0107 headerStr.append(i18n("From: ") + StringUtil::emailAddrAsAnchor(message->from(), StringUtil::DisplayFullAddress, QString(), StringUtil::ShowLink)); 0108 if (!vCardName().isEmpty()) { 0109 headerStr.append(QLatin1StringView(" <a href=\"") + vCardName() + QLatin1StringView("\">") + i18n("[vCard]") 0110 + QLatin1StringView("</a>")); 0111 } 0112 0113 if (strategy->showHeader(QStringLiteral("organization")) && message->organization(false)) { 0114 headerStr.append(QLatin1StringView(" (") + d->mHeaderStyleUtil.strToHtml(message->organization()->asUnicodeString()) + QLatin1Char(')')); 0115 } 0116 headerStr.append(QLatin1StringView("<br/>\n")); 0117 } 0118 0119 if (strategy->showHeader(QStringLiteral("to"))) { 0120 headerStr.append(i18nc("To-field of the mailheader.", "To: ") + StringUtil::emailAddrAsAnchor(message->to(), StringUtil::DisplayFullAddress) 0121 + QLatin1StringView("<br/>\n")); 0122 } 0123 0124 if (strategy->showHeader(QStringLiteral("cc")) && message->cc(false)) { 0125 const QString str = StringUtil::emailAddrAsAnchor(message->cc(), StringUtil::DisplayFullAddress); 0126 if (!str.isEmpty()) { 0127 headerStr.append(i18n("CC: ") + str + QLatin1StringView("<br/>\n")); 0128 } 0129 } 0130 0131 if (strategy->showHeader(QStringLiteral("bcc")) && message->bcc(false)) { 0132 const QString str = StringUtil::emailAddrAsAnchor(message->bcc(), StringUtil::DisplayFullAddress); 0133 if (!str.isEmpty()) { 0134 headerStr.append(i18n("BCC: ") + str + QLatin1StringView("<br/>\n")); 0135 } 0136 } 0137 0138 if (strategy->showHeader(QStringLiteral("reply-to")) && message->replyTo(false)) { 0139 headerStr.append(i18n("Reply to: ") + StringUtil::emailAddrAsAnchor(message->replyTo(), StringUtil::DisplayFullAddress) + QLatin1StringView("<br/>\n")); 0140 } 0141 0142 headerStr += QLatin1StringView("</div>\n"); 0143 0144 return headerStr; 0145 } 0146 0147 const char *MessageViewer::PlainHeaderStyle::name() const 0148 { 0149 return "plain"; 0150 }