File indexing completed on 2024-11-24 04:53:00
0001 /* Copyright (C) 2006 - 2014 Jan Kundrát <jkt@flaska.net> 0002 0003 This file is part of the Trojita Qt IMAP e-mail client, 0004 http://trojita.flaska.net/ 0005 0006 This program is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU General Public License as 0008 published by the Free Software Foundation; either version 2 of 0009 the License or (at your option) version 3 or any later version 0010 accepted by the membership of KDE e.V. (or its successor approved 0011 by the membership of KDE e.V.), which shall act as a proxy 0012 defined in Section 14 of version 3 of the license. 0013 0014 This program is distributed in the hope that it will be useful, 0015 but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0017 GNU General Public License for more details. 0018 0019 You should have received a copy of the GNU General Public License 0020 along with this program. If not, see <http://www.gnu.org/licenses/>. 0021 */ 0022 #include "EnvelopeView.h" 0023 #include <QFontMetrics> 0024 #include <QLabel> 0025 #include <QUrlQuery> 0026 #include <QGridLayout> 0027 #include <QLayoutItem> 0028 #include <QVBoxLayout> 0029 #include "Gui/AddressRowWidget.h" 0030 #include "Gui/MessageView.h" 0031 #include "Gui/Util.h" 0032 #include "Imap/Model/ItemRoles.h" 0033 #include "Imap/Model/MailboxTree.h" 0034 #include "Imap/Model/Model.h" 0035 #include "UiUtils/Formatting.h" 0036 0037 namespace Gui { 0038 0039 EnvelopeView::EnvelopeView(QWidget *parent, MessageView *messageView): QWidget(parent), m_messageView(messageView) 0040 { 0041 QVBoxLayout *lay = new QVBoxLayout(this); 0042 lay->setContentsMargins(0, 0, 0, 0); 0043 setLayout(lay); 0044 0045 } 0046 0047 #define SET_LABEL_OPTIONS(LBL) \ 0048 { \ 0049 LBL->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); \ 0050 LBL->setWordWrap(true); \ 0051 LBL->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse); \ 0052 } 0053 0054 #define ADD_ROW(LBL, WDG) \ 0055 { \ 0056 QLabel *l = new QLabel(LBL, this); \ 0057 l->setAlignment(Qt::AlignRight); \ 0058 form->addWidget(l, form->rowCount(), 0, Qt::AlignTop); \ 0059 form->addWidget(WDG, form->rowCount()-1, 1, Qt::AlignTop); \ 0060 } 0061 0062 /** @short */ 0063 void EnvelopeView::setMessage(const QModelIndex &index) 0064 { 0065 while (QLayoutItem *item = layout()->takeAt(0)) { 0066 if (item->widget()) { 0067 item->widget()->deleteLater(); 0068 } else if (item->layout()) { 0069 item->layout()->deleteLater(); 0070 } else { 0071 delete item; 0072 } 0073 } 0074 Q_FOREACH(QWidget *w, findChildren<QWidget*>()) { 0075 w->deleteLater(); 0076 } 0077 0078 if (!index.isValid()) { 0079 return; 0080 } 0081 0082 const Imap::Message::Envelope e = index.data(Imap::Mailbox::RoleMessageEnvelope).value<Imap::Message::Envelope>(); 0083 0084 // Subject & date 0085 QString subDate; 0086 // Date 0087 if (e.date.isValid()) { 0088 subDate = QStringLiteral("<table style=\"margin:0px; margin-left:4em; float:right;\"><tr style=\"margin:0px;\"><td style=\"margin:0px;\">%1</td></tr></table>") 0089 .arg(QLocale::system().toString(e.date.toLocalTime(), QLocale::LongFormat)); 0090 } 0091 subDate += QStringLiteral("<span style=\"font:bold large;\">%1</span>").arg(e.subject.toHtmlEscaped()); 0092 auto lbl = new QLabel(subDate, this); 0093 SET_LABEL_OPTIONS(lbl) 0094 layout()->addWidget(lbl); 0095 0096 QGridLayout *form = new QGridLayout(); 0097 form->setSpacing(0); 0098 form->setContentsMargins(0, 0, 0, 0); 0099 static_cast<QBoxLayout*>(layout())->addLayout(form); 0100 0101 // Sender 0102 AddressRowWidget *senderWidget = 0; 0103 QString senderLabel; 0104 if (!e.from.isEmpty()) { 0105 senderLabel = tr("From"); 0106 senderWidget = new AddressRowWidget(this, QString(), e.from, m_messageView); 0107 } 0108 if (!e.sender.isEmpty() && e.sender != e.from) { 0109 if (senderWidget) { 0110 senderWidget->addAddresses(QStringLiteral(" %1").arg(tr("sent via")), e.sender, m_messageView); 0111 } else { 0112 senderLabel = tr("Sender"); 0113 senderWidget = new AddressRowWidget(this, QString(), e.sender, m_messageView); 0114 } 0115 } 0116 if (!e.replyTo.isEmpty() && e.replyTo != e.from) { 0117 if (senderWidget) { 0118 senderWidget->addAddresses(QStringLiteral(", %1").arg(tr("replies to")), e.replyTo, m_messageView); 0119 } else { 0120 senderLabel = tr("Reply-To"); 0121 senderWidget = new AddressRowWidget(this, QString(), e.replyTo, m_messageView); 0122 } 0123 } 0124 if (senderWidget) 0125 ADD_ROW(senderLabel, senderWidget) 0126 0127 // Receiver 0128 AddressRowWidget *receiverWidget = 0; 0129 QString receiverLabel; 0130 if (!e.to.isEmpty()) { 0131 receiverLabel = tr("To"); 0132 receiverWidget = new AddressRowWidget(this, QString(), e.to, m_messageView); 0133 } 0134 if (!e.cc.isEmpty()) { 0135 if (receiverWidget) { 0136 receiverWidget->addAddresses(QStringLiteral(" %1").arg(tr("Cc'd to")), e.cc, m_messageView); 0137 } else { 0138 receiverLabel = tr("Cc"); 0139 receiverWidget = new AddressRowWidget(this, QString(), e.cc, m_messageView); 0140 } 0141 } 0142 if (!e.bcc.isEmpty()) { 0143 if (receiverWidget) { 0144 receiverWidget->addAddresses(QStringLiteral(" %1").arg(tr("Bcc'd to")), e.bcc, m_messageView); 0145 } else { 0146 receiverLabel = tr("Bcc"); 0147 receiverWidget = new AddressRowWidget(this, QString(), e.bcc, m_messageView); 0148 } 0149 } 0150 if (receiverWidget) 0151 ADD_ROW(receiverLabel, receiverWidget) 0152 0153 // Mailing list 0154 QVariantList headerListPost = index.data(Imap::Mailbox::RoleMessageHeaderListPost).toList(); 0155 if (!headerListPost.isEmpty()) { 0156 QStringList buf; 0157 bool elided = false; 0158 Q_FOREACH(const QVariant &item, headerListPost) { 0159 const QString scheme = item.toUrl().scheme().toLower(); 0160 const bool isMailTo = scheme == QLatin1String("mailto"); 0161 if (isMailTo || scheme == QLatin1String("http") || scheme == QLatin1String("https")) { 0162 QString target = item.toUrl().toString(); 0163 // eg. github uses reply+<some hash>@reply.github.com 0164 QString caption = isMailTo ? item.toUrl().toString(QUrl::RemoveScheme) : target; 0165 elided = elided || UiUtils::elideAddress(caption); 0166 target = target.toHtmlEscaped(); 0167 buf << tr("<a href=\"%1\">%2</a>").arg(target, caption.toHtmlEscaped()); 0168 } else { 0169 buf << item.toUrl().toString().toHtmlEscaped(); 0170 } 0171 } 0172 auto lbl = new QLabel(QString(QLatin1String("<html> %1</html>")).arg(buf.join(tr(", ")))); 0173 SET_LABEL_OPTIONS(lbl) 0174 lbl->setOpenExternalLinks(true); 0175 if (elided) 0176 connect(lbl, &QLabel::linkHovered, lbl, &QLabel::setToolTip); 0177 ADD_ROW(tr("Mailing List"), lbl) 0178 } 0179 0180 // separating the message 0181 QFrame *line = new QFrame(this); 0182 line->setFrameStyle(QFrame::HLine|QFrame::Plain); 0183 layout()->addWidget(line); 0184 } 0185 0186 0187 }