[kde-doc-english] [trojita] src/Gui: GUI: refactor the message envelope widget into a standalone class
Jan Kundrát
jkt at flaska.net
Fri May 3 14:08:13 UTC 2013
Git commit 4566a329aeb79adbcfe745c678c2dbdb16499754 by Jan Kundrát.
Committed on 03/05/2013 at 15:30.
Pushed by jkt into branch 'master'.
GUI: refactor the message envelope widget into a standalone class
A +139 -0 src/Gui/EnvelopeView.cpp [License: GPL (v2/3)]
A +51 -0 src/Gui/EnvelopeView.h [License: GPL (v2/3)]
M +4 -2 src/Gui/Gui.pro
M +7 -108 src/Gui/MessageView.cpp
M +2 -3 src/Gui/MessageView.h
http://commits.kde.org/trojita/4566a329aeb79adbcfe745c678c2dbdb16499754
diff --git a/src/Gui/EnvelopeView.cpp b/src/Gui/EnvelopeView.cpp
new file mode 100644
index 0000000..4322deb
--- /dev/null
+++ b/src/Gui/EnvelopeView.cpp
@@ -0,0 +1,139 @@
+/* Copyright (C) 2006 - 2013 Jan Kundrát <jkt at flaska.net>
+
+ This file is part of the Trojita Qt IMAP e-mail client,
+ http://trojita.flaska.net/
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License or (at your option) version 3 or any later version
+ accepted by the membership of KDE e.V. (or its successor approved
+ by the membership of KDE e.V.), which shall act as a proxy
+ defined in Section 14 of version 3 of the license.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "EnvelopeView.h"
+#include <QHeaderView>
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+# include <QTextDocument>
+#else
+# include <QUrlQuery>
+#endif
+#include "Imap/Model/ItemRoles.h"
+#include "Imap/Model/MailboxTree.h"
+#include "Imap/Model/Model.h"
+
+namespace Gui {
+
+EnvelopeView::EnvelopeView(QWidget *parent): QLabel(parent)
+{
+ // we create a dummy header, pass it through the style and the use it's color roles so we
+ // know what headers in general look like in the system
+ QHeaderView helpingHeader(Qt::Horizontal);
+ helpingHeader.ensurePolished();
+
+ setBackgroundRole(helpingHeader.backgroundRole());
+ setForegroundRole(helpingHeader.foregroundRole());
+ setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse);
+ setIndent(5);
+ setWordWrap(true);
+ connect(this, SIGNAL(linkHovered(QString)), this, SLOT(onLinkHovered(QString)));
+}
+
+/** @short */
+void EnvelopeView::setMessage(const QModelIndex &index)
+{
+ setText(headerText(index));
+}
+
+QString EnvelopeView::headerText(const QModelIndex &index)
+{
+ if (!index.isValid())
+ return QString();
+
+ const Imap::Message::Envelope e = index.data(Imap::Mailbox::RoleMessageEnvelope).value<Imap::Message::Envelope>();
+
+ QString res;
+ if (!e.from.isEmpty())
+ res += tr("<b>From:</b> %1<br/>").arg(Imap::Message::MailAddress::prettyList(e.from, Imap::Message::MailAddress::FORMAT_CLICKABLE));
+ if (!e.sender.isEmpty() && e.sender != e.from)
+ res += tr("<b>Sender:</b> %1<br/>").arg(Imap::Message::MailAddress::prettyList(e.sender, Imap::Message::MailAddress::FORMAT_CLICKABLE));
+ if (!e.replyTo.isEmpty() && e.replyTo != e.from)
+ res += tr("<b>Reply-To:</b> %1<br/>").arg(Imap::Message::MailAddress::prettyList(e.replyTo, Imap::Message::MailAddress::FORMAT_CLICKABLE));
+ QVariantList headerListPost = index.data(Imap::Mailbox::RoleMessageHeaderListPost).toList();
+ if (!headerListPost.isEmpty()) {
+ QStringList buf;
+ Q_FOREACH(const QVariant &item, headerListPost) {
+ const QString scheme = item.toUrl().scheme().toLower();
+ if (scheme == QLatin1String("http") || scheme == QLatin1String("https") || scheme == QLatin1String("mailto")) {
+ QString target = item.toUrl().toString();
+ QString caption = item.toUrl().toString(scheme == QLatin1String("mailto") ? QUrl::RemoveScheme : QUrl::None);
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ target = Qt::escape(target);
+ caption = Qt::escape(caption);
+#else
+ target = target.toHtmlEscaped();
+ caption = caption.toHtmlEscaped();
+#endif
+ buf << tr("<a href=\"%1\">%2</a>").arg(target, caption);
+ } else {
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ buf << Qt::escape(item.toUrl().toString());
+#else
+ buf << item.toUrl().toString().toHtmlEscaped();
+#endif
+ }
+ }
+ res += tr("<b>List-Post:</b> %1<br/>").arg(buf.join(tr(", ")));
+ }
+ if (!e.to.isEmpty())
+ res += tr("<b>To:</b> %1<br/>").arg(Imap::Message::MailAddress::prettyList(e.to, Imap::Message::MailAddress::FORMAT_CLICKABLE));
+ if (!e.cc.isEmpty())
+ res += tr("<b>Cc:</b> %1<br/>").arg(Imap::Message::MailAddress::prettyList(e.cc, Imap::Message::MailAddress::FORMAT_CLICKABLE));
+ if (!e.bcc.isEmpty())
+ res += tr("<b>Bcc:</b> %1<br/>").arg(Imap::Message::MailAddress::prettyList(e.bcc, Imap::Message::MailAddress::FORMAT_CLICKABLE));
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ res += tr("<b>Subject:</b> %1").arg(Qt::escape(e.subject));
+#else
+ res += tr("<b>Subject:</b> %1").arg(e.subject.toHtmlEscaped());
+#endif
+ if (e.date.isValid())
+ res += tr("<br/><b>Date:</b> %1").arg(e.date.toLocalTime().toString(Qt::SystemLocaleLongDate));
+ return res;
+}
+
+void EnvelopeView::onLinkHovered(const QString &target)
+{
+ QUrl url(target);
+
+ if (target.isEmpty() || url.scheme().toLower() != QLatin1String("mailto")) {
+ setToolTip(QString());
+ return;
+ }
+
+ QString frontOfAtSign, afterAtSign;
+ if (url.path().indexOf(QLatin1String("@")) != -1) {
+ QStringList chunks = url.path().split(QLatin1String("@"));
+ frontOfAtSign = chunks[0];
+ afterAtSign = QStringList(chunks.mid(1)).join(QLatin1String("@"));
+ }
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Imap::Message::MailAddress addr(url.queryItemValue(QLatin1String("X-Trojita-DisplayName")), QString(),
+ frontOfAtSign, afterAtSign);
+ setToolTip(Qt::escape(addr.prettyName(Imap::Message::MailAddress::FORMAT_READABLE)));
+#else
+ QUrlQuery q(url);
+ Imap::Message::MailAddress addr(q.queryItemValue(QLatin1String("X-Trojita-DisplayName")), QString(),
+ frontOfAtSign, afterAtSign);
+ setToolTip(addr.prettyName(Imap::Message::MailAddress::FORMAT_READABLE).toHtmlEscaped());
+#endif
+}
+
+}
diff --git a/src/Gui/EnvelopeView.h b/src/Gui/EnvelopeView.h
new file mode 100644
index 0000000..699825b
--- /dev/null
+++ b/src/Gui/EnvelopeView.h
@@ -0,0 +1,51 @@
+/* Copyright (C) 2006 - 2013 Jan Kundrát <jkt at flaska.net>
+
+ This file is part of the Trojita Qt IMAP e-mail client,
+ http://trojita.flaska.net/
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License or (at your option) version 3 or any later version
+ accepted by the membership of KDE e.V. (or its successor approved
+ by the membership of KDE e.V.), which shall act as a proxy
+ defined in Section 14 of version 3 of the license.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef GUI_ENVELOPEVIEW_H
+#define GUI_ENVELOPEVIEW_H
+
+#include <QModelIndex>
+#include <QLabel>
+
+namespace Gui {
+
+/** @short Widget displaying the message envelope */
+class EnvelopeView : public QLabel
+{
+ Q_OBJECT
+public:
+ explicit EnvelopeView(QWidget *parent=0);
+
+ void setMessage(const QModelIndex &index);
+
+private slots:
+ void onLinkHovered(const QString &target);
+
+private:
+ QString headerText(const QModelIndex &index);
+
+ EnvelopeView(const EnvelopeView &); // don't implement
+ EnvelopeView &operator=(const EnvelopeView &); // don't implement
+};
+
+}
+
+#endif // GUI_ENVELOPEVIEW_H
diff --git a/src/Gui/Gui.pro b/src/Gui/Gui.pro
index 25c01b3..2cb70b9 100644
--- a/src/Gui/Gui.pro
+++ b/src/Gui/Gui.pro
@@ -57,7 +57,8 @@ SOURCES += \
LineEdit.cpp \
PasswordDialog.cpp \
ProgressPopUp.cpp \
- OverlayWidget.cpp
+ OverlayWidget.cpp \
+ EnvelopeView.cpp
HEADERS += \
../Imap/Model/ModelTest/modeltest.h \
ComposeWidget.h \
@@ -100,7 +101,8 @@ HEADERS += \
LineEdit.h \
PasswordDialog.h \
ProgressPopUp.h \
- OverlayWidget.h
+ OverlayWidget.h \
+ EnvelopeView.h
FORMS += CreateMailboxDialog.ui \
ComposeWidget.ui \
SettingsImapPage.ui \
diff --git a/src/Gui/MessageView.cpp b/src/Gui/MessageView.cpp
index d6fa19d..08f89dc 100644
--- a/src/Gui/MessageView.cpp
+++ b/src/Gui/MessageView.cpp
@@ -23,15 +23,10 @@
#include <QDesktopServices>
#include <QHeaderView>
#include <QKeyEvent>
-#include <QLabel>
#include <QMenu>
#include <QMessageBox>
-#include <QTextDocument>
#include <QTimer>
#include <QUrl>
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
-#include <QUrlQuery>
-#endif
#include <QVBoxLayout>
#include <QWebFrame>
#include <QWebHistory>
@@ -42,6 +37,7 @@
#include "AbstractPartWidget.h"
#include "Composer/SubjectMangling.h"
#include "EmbeddedWebView.h"
+#include "EnvelopeView.h"
#include "ExternalElementsWidget.h"
#include "PartWidgetFactory.h"
#include "SimplePartWidget.h"
@@ -93,14 +89,8 @@ MessageView::MessageView(QWidget *parent): QWidget(parent)
headerSection->setAutoFillBackground(true);
// the actual mail header
- header = new QLabel(headerSection);
- header->setBackgroundRole(helpingHeader.backgroundRole());
- header->setForegroundRole(helpingHeader.foregroundRole());
- header->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse);
- header->setIndent(5);
- header->setWordWrap(true);
- connect(header, SIGNAL(linkHovered(QString)), this, SLOT(linkInTitleHovered(QString)));
- connect(header, SIGNAL(linkActivated(QString)), this, SLOT(headerLinkActivated(QString)));
+ m_envelope = new EnvelopeView(headerSection);
+ connect(m_envelope, SIGNAL(linkActivated(QString)), this, SLOT(headerLinkActivated(QString)));
// the tag bar
tags = new TagListWidget(headerSection);
@@ -117,7 +107,7 @@ MessageView::MessageView(QWidget *parent): QWidget(parent)
// layout the header
layout = new QVBoxLayout(headerSection);
- layout->addWidget(header, 1);
+ layout->addWidget(m_envelope, 1);
layout->addWidget(tags, 3);
layout->addWidget(externalElements, 1);
@@ -170,7 +160,7 @@ MessageView::~MessageView()
void MessageView::setEmpty()
{
markAsReadTimer->stop();
- header->setText(QString());
+ m_envelope->setMessage(QModelIndex());
headerSection->hide();
message = QModelIndex();
disconnect(this, SLOT(handleDataChanged(QModelIndex,QModelIndex)));
@@ -229,7 +219,7 @@ void MessageView::setMessage(const QModelIndex &index)
viewer->setParent(this);
layout->addWidget(viewer);
viewer->show();
- header->setText(headerText());
+ m_envelope->setMessage(message);
tags->show();
tags->setTagList(messageIndex.data(Imap::Mailbox::RoleMessageFlags).toStringList());
@@ -289,70 +279,6 @@ bool MessageView::eventFilter(QObject *object, QEvent *event)
}
}
-Imap::Message::Envelope MessageView::envelope() const
-{
- // Accessing the envelope via QVariant is just too much work here; it's way easier to just get the raw pointer
- Imap::Mailbox::Model *model = dynamic_cast<Imap::Mailbox::Model *>(const_cast<QAbstractItemModel *>(message.model()));
- Imap::Mailbox::TreeItemMessage *messagePtr = dynamic_cast<Imap::Mailbox::TreeItemMessage *>(static_cast<Imap::Mailbox::TreeItem *>(message.internalPointer()));
- return messagePtr->envelope(model);
-}
-
-QString MessageView::headerText()
-{
- if (!message.isValid())
- return QString();
-
- const Imap::Message::Envelope &e = envelope();
-
- QString res;
- if (!e.from.isEmpty())
- res += tr("<b>From:</b> %1<br/>").arg(Imap::Message::MailAddress::prettyList(e.from, Imap::Message::MailAddress::FORMAT_CLICKABLE));
- if (!e.sender.isEmpty() && e.sender != e.from)
- res += tr("<b>Sender:</b> %1<br/>").arg(Imap::Message::MailAddress::prettyList(e.sender, Imap::Message::MailAddress::FORMAT_CLICKABLE));
- if (!e.replyTo.isEmpty() && e.replyTo != e.from)
- res += tr("<b>Reply-To:</b> %1<br/>").arg(Imap::Message::MailAddress::prettyList(e.replyTo, Imap::Message::MailAddress::FORMAT_CLICKABLE));
- QVariantList headerListPost = message.data(Imap::Mailbox::RoleMessageHeaderListPost).toList();
- if (!headerListPost.isEmpty()) {
- QStringList buf;
- Q_FOREACH(const QVariant &item, headerListPost) {
- const QString scheme = item.toUrl().scheme().toLower();
- if (scheme == QLatin1String("http") || scheme == QLatin1String("https") || scheme == QLatin1String("mailto")) {
- QString target = item.toUrl().toString();
- QString caption = item.toUrl().toString(scheme == QLatin1String("mailto") ? QUrl::RemoveScheme : QUrl::None);
-#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
- target = Qt::escape(target);
- caption = Qt::escape(caption);
-#else
- target = target.toHtmlEscaped();
- caption = caption.toHtmlEscaped();
-#endif
- buf << tr("<a href=\"%1\">%2</a>").arg(target, caption);
- } else {
-#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
- buf << Qt::escape(item.toUrl().toString());
-#else
- buf << item.toUrl().toString().toHtmlEscaped();
-#endif
- }
- }
- res += tr("<b>List-Post:</b> %1<br/>").arg(buf.join(tr(", ")));
- }
- if (!e.to.isEmpty())
- res += tr("<b>To:</b> %1<br/>").arg(Imap::Message::MailAddress::prettyList(e.to, Imap::Message::MailAddress::FORMAT_CLICKABLE));
- if (!e.cc.isEmpty())
- res += tr("<b>Cc:</b> %1<br/>").arg(Imap::Message::MailAddress::prettyList(e.cc, Imap::Message::MailAddress::FORMAT_CLICKABLE));
- if (!e.bcc.isEmpty())
- res += tr("<b>Bcc:</b> %1<br/>").arg(Imap::Message::MailAddress::prettyList(e.bcc, Imap::Message::MailAddress::FORMAT_CLICKABLE));
-#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
- res += tr("<b>Subject:</b> %1").arg(Qt::escape(e.subject));
-#else
- res += tr("<b>Subject:</b> %1").arg(e.subject.toHtmlEscaped());
-#endif
- if (e.date.isValid())
- res += tr("<br/><b>Date:</b> %1").arg(e.date.toLocalTime().toString(Qt::SystemLocaleLongDate));
- return res;
-}
-
QString MessageView::quoteText() const
{
if (const AbstractPartWidget *w = dynamic_cast<const AbstractPartWidget *>(viewer)) {
@@ -408,7 +334,7 @@ QString MessageView::quoteText() const
}
quote << quotemarks + line->mid(lastSpace);
}
- const Imap::Message::Envelope &e = envelope();
+ const Imap::Message::Envelope &e = message.data(Imap::Mailbox::RoleMessageEnvelope).value<Imap::Message::Envelope>();
QString sender;
if (!e.from.isEmpty())
sender = e.from[0].prettyName(Imap::Message::MailAddress::FORMAT_JUST_NAME);
@@ -476,33 +402,6 @@ void MessageView::externalsEnabled()
w->reloadContents();
}
-void MessageView::linkInTitleHovered(const QString &target)
-{
- QUrl url(target);
-
- if (target.isEmpty() || url.scheme().toLower() != QLatin1String("mailto")) {
- header->setToolTip(QString());
- return;
- }
-
- QString frontOfAtSign, afterAtSign;
- if (url.path().indexOf(QLatin1String("@")) != -1) {
- QStringList chunks = url.path().split(QLatin1String("@"));
- frontOfAtSign = chunks[0];
- afterAtSign = QStringList(chunks.mid(1)).join(QLatin1String("@"));
- }
-#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
- Imap::Message::MailAddress addr(url.queryItemValue(QLatin1String("X-Trojita-DisplayName")), QString(),
- frontOfAtSign, afterAtSign);
- header->setToolTip(Qt::escape(addr.prettyName(Imap::Message::MailAddress::FORMAT_READABLE)));
-#else
- QUrlQuery q(url);
- Imap::Message::MailAddress addr(q.queryItemValue(QLatin1String("X-Trojita-DisplayName")), QString(),
- frontOfAtSign, afterAtSign);
- header->setToolTip(addr.prettyName(Imap::Message::MailAddress::FORMAT_READABLE).toHtmlEscaped());
-#endif
-}
-
void MessageView::newLabelAction(const QString &tag)
{
if (!message.isValid())
diff --git a/src/Gui/MessageView.h b/src/Gui/MessageView.h
index 41dcf15..bdbad36 100644
--- a/src/Gui/MessageView.h
+++ b/src/Gui/MessageView.h
@@ -48,6 +48,7 @@ class Envelope;
namespace Gui
{
+class EnvelopeView;
class MainWindow;
class PartWidgetFactory;
class ExternalElementsWidget;
@@ -78,7 +79,6 @@ private slots:
void markAsRead();
void externalsRequested(const QUrl &url);
void externalsEnabled();
- void linkInTitleHovered(const QString &target);
void newLabelAction(const QString &tag);
void deleteLabelAction(const QString &tag);
void handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
@@ -93,12 +93,11 @@ signals:
private:
bool eventFilter(QObject *object, QEvent *event);
Imap::Message::Envelope envelope() const;
- QString headerText();
QString quoteText() const;
QWidget *viewer;
QWidget *headerSection;
- QLabel *header;
+ EnvelopeView *m_envelope;
ExternalElementsWidget *externalElements;
QBoxLayout *layout;
TagListWidget *tags;
More information about the kde-doc-english
mailing list