[kde-doc-english] [trojita] src/Gui: GUI: make it possible to inline-search a message

Jan Kundrát jkt at flaska.net
Thu Feb 21 19:48:34 UTC 2013


Git commit 93c40eae89cc5f919750ae0d15800bd2a6cd02a8 by Jan Kundrát.
Committed on 21/02/2013 at 20:17.
Pushed by jkt into branch 'master'.

GUI: make it possible to inline-search a message

A  +58   -0    src/Gui/CompleteMessageWidget.cpp     [License: GPL (v2/3)]
A  +57   -0    src/Gui/CompleteMessageWidget.h     [License: GPL (v2/3)]
M  +4    -2    src/Gui/Gui.pro
M  +5    -0    src/Gui/MessageView.cpp
M  +2    -0    src/Gui/MessageView.h
M  +8    -1    src/Gui/SimplePartWidget.cpp
M  +2    -0    src/Gui/SimplePartWidget.h
M  +26   -31   src/Gui/Window.cpp
M  +2    -2    src/Gui/Window.h

http://commits.kde.org/trojita/93c40eae89cc5f919750ae0d15800bd2a6cd02a8

diff --git a/src/Gui/CompleteMessageWidget.cpp b/src/Gui/CompleteMessageWidget.cpp
new file mode 100644
index 0000000..6eb25d1
--- /dev/null
+++ b/src/Gui/CompleteMessageWidget.cpp
@@ -0,0 +1,58 @@
+/* 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 "CompleteMessageWidget.h"
+#include <QScrollArea>
+#include <QVBoxLayout>
+#include "FindBar.h"
+#include "MessageView.h"
+
+namespace Gui {
+
+CompleteMessageWidget::CompleteMessageWidget(QWidget *parent): QWidget(parent)
+{
+    messageView = new MessageView();
+    area = new QScrollArea();
+    area->setWidget(messageView);
+    area->setWidgetResizable(true);
+    QVBoxLayout *layout = new QVBoxLayout(this);
+    layout->setContentsMargins(0, 0, 0, 0);
+    layout->addWidget(area);
+
+    m_findBar = new FindBar(this);
+    layout->addWidget(m_findBar);
+
+    connect(messageView, SIGNAL(searchRequestedBy(QWebView*)), this, SLOT(searchRequestedBy(QWebView*)));
+}
+
+void CompleteMessageWidget::searchRequestedBy(QWebView *webView)
+{
+    if (m_findBar->isVisible() || !webView) {
+        m_findBar->setAssociatedWebView(0);
+        m_findBar->hide();
+    } else {
+        m_findBar->setAssociatedWebView(webView);
+        m_findBar->show();
+    }
+}
+
+}
diff --git a/src/Gui/CompleteMessageWidget.h b/src/Gui/CompleteMessageWidget.h
new file mode 100644
index 0000000..1d662d6
--- /dev/null
+++ b/src/Gui/CompleteMessageWidget.h
@@ -0,0 +1,57 @@
+/* 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_COMPLETEMESSAGEWIDGET_H
+#define GUI_COMPLETEMESSAGEWIDGET_H
+
+#include <QWidget>
+
+class QScrollArea;
+class QWebView;
+
+namespace Gui
+{
+
+class FindBar;
+class MessageView;
+
+class CompleteMessageWidget: public QWidget
+{
+    Q_OBJECT
+public:
+    explicit CompleteMessageWidget(QWidget *parent=0);
+
+    MessageView *messageView;
+    QScrollArea *area;
+
+private slots:
+    void searchRequestedBy(QWebView *webView);
+
+private:
+    CompleteMessageWidget(const CompleteMessageWidget &); // don't implement
+    CompleteMessageWidget &operator=(const CompleteMessageWidget &); // don't implement
+
+    FindBar *m_findBar;
+};
+
+}
+
+#endif // GUI_COMPLETEMESSAGEWIDGET_H
diff --git a/src/Gui/Gui.pro b/src/Gui/Gui.pro
index d2e55b0..08bde9f 100644
--- a/src/Gui/Gui.pro
+++ b/src/Gui/Gui.pro
@@ -49,7 +49,8 @@ SOURCES += \
     ComposerAttachments.cpp \
     FromAddressProxyModel.cpp \
     MessageSourceWidget.cpp \
-    FindBar.cpp
+    FindBar.cpp \
+    CompleteMessageWidget.cpp
 HEADERS += \
     ../Imap/Model/ModelTest/modeltest.h \
     ComposeWidget.h \
@@ -84,7 +85,8 @@ HEADERS += \
     ComposerAttachments.h \
     FromAddressProxyModel.h \
     MessageSourceWidget.h \
-    FindBar.h
+    FindBar.h \
+    CompleteMessageWidget.h
 FORMS += CreateMailboxDialog.ui \
     ComposeWidget.ui \
     SettingsImapPage.ui \
diff --git a/src/Gui/MessageView.cpp b/src/Gui/MessageView.cpp
index 343bf61..27abc4f 100644
--- a/src/Gui/MessageView.cpp
+++ b/src/Gui/MessageView.cpp
@@ -573,6 +573,11 @@ void MessageView::partLinkHovered(const QString &link, const QString &title, con
     emit linkHovered(link);
 }
 
+void MessageView::triggerSearchDialog()
+{
+    emit searchRequestedBy(qobject_cast<QWebView*>(sender()));
+}
+
 QModelIndex MessageView::currentMessage() const
 {
     return message;
diff --git a/src/Gui/MessageView.h b/src/Gui/MessageView.h
index 62f0adb..41dcf15 100644
--- a/src/Gui/MessageView.h
+++ b/src/Gui/MessageView.h
@@ -85,9 +85,11 @@ private slots:
     void headerLinkActivated(QString);
     void partContextMenuRequested(const QPoint &point);
     void partLinkHovered(const QString &link, const QString &title, const QString &textContent);
+    void triggerSearchDialog();
 signals:
     void messageChanged();
     void linkHovered(const QString &url);
+    void searchRequestedBy(QWebView *webView);
 private:
     bool eventFilter(QObject *object, QEvent *event);
     Imap::Message::Envelope envelope() const;
diff --git a/src/Gui/SimplePartWidget.cpp b/src/Gui/SimplePartWidget.cpp
index 0610243..b4c0a0b 100644
--- a/src/Gui/SimplePartWidget.cpp
+++ b/src/Gui/SimplePartWidget.cpp
@@ -57,6 +57,11 @@ SimplePartWidget::SimplePartWidget(QWidget *parent, Imap::Network::MsgPartNetAcc
     connect(saveAction, SIGNAL(triggered()), fileDownloadManager, SLOT(slotDownloadNow()));
     this->addAction(saveAction);
 
+    m_findAction = new QAction(tr("Search..."), this);
+    m_findAction->setShortcut(tr("Ctrl+F"));
+    connect(m_findAction, SIGNAL(triggered()), this, SIGNAL(searchDialogRequested()));
+    addAction(m_findAction);
+
     setContextMenuPolicy(Qt::CustomContextMenu);
 }
 
@@ -143,7 +148,7 @@ void SimplePartWidget::reloadContents()
 
 QList<QAction *> SimplePartWidget::contextMenuSpecificActions() const
 {
-    return QList<QAction*>() << saveAction;
+    return QList<QAction*>() << saveAction << m_findAction;
 }
 
 /** @short Connect various signals which require a certain reaction from the rest of the GUI */
@@ -156,6 +161,8 @@ void SimplePartWidget::connectGuiInteractionEvents(QObject *guiInteractionTarget
     connect(page(), SIGNAL(linkHovered(QString,QString,QString)), this, SIGNAL(linkHovered(QString,QString,QString)));
     connect(this, SIGNAL(linkHovered(QString,QString,QString)),
             guiInteractionTarget, SLOT(partLinkHovered(QString,QString,QString)));
+
+    connect(this, SIGNAL(searchDialogRequested()), guiInteractionTarget, SLOT(triggerSearchDialog()));
 }
 
 }
diff --git a/src/Gui/SimplePartWidget.h b/src/Gui/SimplePartWidget.h
index 36a5532..ee25246 100644
--- a/src/Gui/SimplePartWidget.h
+++ b/src/Gui/SimplePartWidget.h
@@ -64,8 +64,10 @@ private slots:
     void slotMarkupPlainText();
 signals:
     void linkHovered(const QString &link, const QString &title, const QString &textContent);
+    void searchDialogRequested();
 private:
     QAction *saveAction;
+    QAction *m_findAction;
     Imap::Network::FileDownloadManager *fileDownloadManager;
     Composer::Util::FlowedFormat flowedFormat;
 
diff --git a/src/Gui/Window.cpp b/src/Gui/Window.cpp
index 89b5d7d..07fed94 100644
--- a/src/Gui/Window.cpp
+++ b/src/Gui/Window.cpp
@@ -59,6 +59,7 @@
 #include "Imap/Model/Utils.h"
 #include "Imap/Network/FileDownloadManager.h"
 #include "AbookAddressbook.h"
+#include "CompleteMessageWidget.h"
 #include "ComposeWidget.h"
 #include "IconLoader.h"
 #include "MailBoxTreeView.h"
@@ -225,13 +226,13 @@ void MainWindow::createActions()
     m_nextMessage = new QAction(tr("Next Unread Message"), this);
     m_nextMessage->setShortcut(Qt::Key_N);
     msgListWidget->tree->addAction(m_nextMessage);
-    msgView->addAction(m_nextMessage);
+    m_messageWidget->messageView->addAction(m_nextMessage);
     connect(m_nextMessage, SIGNAL(triggered()), this, SLOT(slotNextUnread()));
 
     m_previousMessage = new QAction(tr("Previous Unread Message"), this);
     m_previousMessage->setShortcut(Qt::Key_P);
     msgListWidget->tree->addAction(m_previousMessage);
-    msgView->addAction(m_previousMessage);
+    m_messageWidget->messageView->addAction(m_previousMessage);
     connect(m_previousMessage, SIGNAL(triggered()), this, SLOT(slotPreviousUnread()));
 
     markAsDeleted = new QAction(loadIcon(QLatin1String("list-remove")),  tr("Mark as Deleted"), this);
@@ -496,23 +497,20 @@ void MainWindow::createWidgets()
     connect(msgListWidget->tree, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(msgListDoubleClicked(const QModelIndex &)));
     connect(msgListWidget, SIGNAL(requestingSearch(QStringList)), this, SLOT(slotSearchRequested(QStringList)));
 
-    msgView = new MessageView();
-    area = new QScrollArea();
-    area->setWidget(msgView);
-    area->setWidgetResizable(true);
-    connect(msgView, SIGNAL(messageChanged()), this, SLOT(scrollMessageUp()));
-    connect(msgView, SIGNAL(messageChanged()), this, SLOT(slotUpdateMessageActions()));
-    connect(msgView, SIGNAL(linkHovered(QString)), this, SLOT(slotShowLinkTarget(QString)));
+    m_messageWidget = new CompleteMessageWidget(this);
+    connect(m_messageWidget->messageView, SIGNAL(messageChanged()), this, SLOT(scrollMessageUp()));
+    connect(m_messageWidget->messageView, SIGNAL(messageChanged()), this, SLOT(slotUpdateMessageActions()));
+    connect(m_messageWidget->messageView, SIGNAL(linkHovered(QString)), this, SLOT(slotShowLinkTarget(QString)));
     if (QSettings().value(Common::SettingsNames::appLoadHomepage, QVariant(true)).toBool() &&
         !QSettings().value(Common::SettingsNames::imapStartOffline).toBool()) {
-        msgView->setHomepageUrl(QUrl(QString::fromUtf8("http://welcome.trojita.flaska.net/%1").arg(QCoreApplication::applicationVersion())));
+        m_messageWidget->messageView->setHomepageUrl(QUrl(QString::fromUtf8("http://welcome.trojita.flaska.net/%1").arg(QCoreApplication::applicationVersion())));
     }
 
     m_mainHSplitter = new QSplitter();
     m_mainVSplitter = new QSplitter();
     m_mainVSplitter->setOrientation(Qt::Vertical);
     m_mainVSplitter->addWidget(msgListWidget);
-    m_mainVSplitter->addWidget(area);
+    m_mainVSplitter->addWidget(m_messageWidget);
     m_mainHSplitter->addWidget(mboxTree);
     m_mainHSplitter->addWidget(m_mainVSplitter);
 
@@ -718,7 +716,7 @@ void MainWindow::msgListActivated(const QModelIndex &index)
         return;
 
     if (index.column() != Imap::Mailbox::MsgListModel::SEEN) {
-        msgView->setMessage(index);
+        m_messageWidget->messageView->setMessage(index);
         msgListWidget->tree->setCurrentIndex(index);
     }
 }
@@ -751,19 +749,16 @@ void MainWindow::msgListDoubleClicked(const QModelIndex &index)
     if (! index.data(Imap::Mailbox::RoleMessageUid).isValid())
         return;
 
-    MessageView *newView = new MessageView(0);
     QModelIndex realIndex;
     const Imap::Mailbox::Model *realModel;
     Imap::Mailbox::TreeItemMessage *message = dynamic_cast<Imap::Mailbox::TreeItemMessage *>(
                 Imap::Mailbox::Model::realTreeItem(index, &realModel, &realIndex));
     Q_ASSERT(message);
     Q_ASSERT(realModel == model);
-    newView->setMessage(index);
 
-    QScrollArea *widget = new QScrollArea();
+    CompleteMessageWidget *widget = new CompleteMessageWidget();
+    widget->messageView->setMessage(index);
     widget->setFocusPolicy(Qt::StrongFocus);
-    widget->setWidget(newView);
-    widget->setWidgetResizable(true);
     widget->setWindowTitle(message->envelope(model).subject);
     widget->setAttribute(Qt::WA_DeleteOnClose);
     widget->resize(800, 600);
@@ -989,7 +984,7 @@ void MainWindow::sslErrors(const QList<QSslCertificate> &certificateChain, const
 
 void MainWindow::nukeModels()
 {
-    msgView->setEmpty();
+    m_messageWidget->messageView->setEmpty();
     mboxTree->setModel(0);
     msgListWidget->tree->setModel(0);
     allTree->setModel(0);
@@ -1076,7 +1071,7 @@ void MainWindow::slotNextUnread()
     bool wrapped = false;
     while (current.isValid()) {
         if (!current.data(Imap::Mailbox::RoleMessageIsMarkedRead).toBool() && msgListWidget->tree->currentIndex() != current) {
-            msgView->setMessage(current);
+            m_messageWidget->messageView->setMessage(current);
             msgListWidget->tree->setCurrentIndex(current);
             return;
         }
@@ -1112,7 +1107,7 @@ void MainWindow::slotPreviousUnread()
     bool wrapped = false;
     while (current.isValid()) {
         if (!current.data(Imap::Mailbox::RoleMessageIsMarkedRead).toBool() && msgListWidget->tree->currentIndex() != current) {
-            msgView->setMessage(current);
+            m_messageWidget->messageView->setMessage(current);
             msgListWidget->tree->setCurrentIndex(current);
             return;
         }
@@ -1253,13 +1248,13 @@ void MainWindow::slotUpdateMessageActions()
 {
     Composer::RecipientList dummy;
     m_replyPrivate->setEnabled(Composer::Util::replyRecipientList(Composer::REPLY_PRIVATE, senderIdentitiesModel(),
-                                                                  msgView->currentMessage(), dummy));
+                                                                  m_messageWidget->messageView->currentMessage(), dummy));
     m_replyAllButMe->setEnabled(Composer::Util::replyRecipientList(Composer::REPLY_ALL_BUT_ME, senderIdentitiesModel(),
-                                                                   msgView->currentMessage(), dummy));
+                                                                   m_messageWidget->messageView->currentMessage(), dummy));
     m_replyAll->setEnabled(Composer::Util::replyRecipientList(Composer::REPLY_ALL, senderIdentitiesModel(),
-                                                              msgView->currentMessage(), dummy));
+                                                              m_messageWidget->messageView->currentMessage(), dummy));
     m_replyList->setEnabled(Composer::Util::replyRecipientList(Composer::REPLY_LIST, senderIdentitiesModel(),
-                                                               msgView->currentMessage(), dummy));
+                                                               m_messageWidget->messageView->currentMessage(), dummy));
     m_replyGuess->setEnabled(m_replyPrivate->isEnabled() || m_replyAllButMe->isEnabled()
                              || m_replyAll->isEnabled() || m_replyList->isEnabled());
 
@@ -1276,27 +1271,27 @@ void MainWindow::slotUpdateMessageActions()
 
 void MainWindow::scrollMessageUp()
 {
-    area->ensureVisible(0, 0, 0, 0);
+    m_messageWidget->area->ensureVisible(0, 0, 0, 0);
 }
 
 void MainWindow::slotReplyTo()
 {
-    msgView->reply(this, Composer::REPLY_PRIVATE);
+    m_messageWidget->messageView->reply(this, Composer::REPLY_PRIVATE);
 }
 
 void MainWindow::slotReplyAll()
 {
-    msgView->reply(this, Composer::REPLY_ALL);
+    m_messageWidget->messageView->reply(this, Composer::REPLY_ALL);
 }
 
 void MainWindow::slotReplyAllButMe()
 {
-    msgView->reply(this, Composer::REPLY_ALL_BUT_ME);
+    m_messageWidget->messageView->reply(this, Composer::REPLY_ALL_BUT_ME);
 }
 
 void MainWindow::slotReplyList()
 {
-    msgView->reply(this, Composer::REPLY_LIST);
+    m_messageWidget->messageView->reply(this, Composer::REPLY_LIST);
 }
 
 void MainWindow::slotReplyGuess()
@@ -1833,14 +1828,14 @@ void MainWindow::slotUpdateWindowTitle()
 
 void MainWindow::slotLayoutCompact()
 {
-    m_mainVSplitter->addWidget(area);
+    m_mainVSplitter->addWidget(m_messageWidget);
     QSettings().setValue(Common::SettingsNames::guiMainWindowLayout, Common::SettingsNames::guiMainWindowLayoutCompact);
     setMinimumWidth(800);
 }
 
 void MainWindow::slotLayoutWide()
 {
-    m_mainHSplitter->addWidget(area);
+    m_mainHSplitter->addWidget(m_messageWidget);
     m_mainHSplitter->setStretchFactor(0, 0);
     m_mainHSplitter->setStretchFactor(1, 1);
     m_mainHSplitter->setStretchFactor(2, 1);
diff --git a/src/Gui/Window.h b/src/Gui/Window.h
index a1b2c37..25ba905 100644
--- a/src/Gui/Window.h
+++ b/src/Gui/Window.h
@@ -63,6 +63,7 @@ namespace Gui
 {
 
 class AbstractAddressbook;
+class CompleteMessageWidget;
 class ComposeWidget;
 class MailBoxTreeView;
 class MessageView;
@@ -189,12 +190,11 @@ private:
     MailBoxTreeView *mboxTree;
     MessageListWidget *msgListWidget;
     QTreeView *allTree;
-    MessageView *msgView;
     QDockWidget *allDock;
     QTreeView *taskTree;
     QDockWidget *taskDock;
 
-    QScrollArea *area;
+    CompleteMessageWidget *m_messageWidget;
 
     ProtocolLoggerWidget *imapLogger;
     QDockWidget *imapLoggerDock;



More information about the kde-doc-english mailing list