[kde-doc-english] [trojita] src/Gui: GUI: move the "mark as reply" selector to the row of buttons

Jan Kundrát jkt at flaska.net
Sat Jan 4 14:21:22 UTC 2014


Git commit b19141b9bfabf727d771f7ac8ee9588194af39e5 by Jan Kundrát.
Committed on 02/01/2014 at 20:30.
Pushed by jkt into branch 'master'.

GUI: move the "mark as reply" selector to the row of buttons

There's a GCI task for changing various replying modes from within the composer
(think reply-to-all vs. reply-privately). That change needs a button to be added
somewhere, so it makes sense to use a button for the feature which Thomas added
yesterday. Besides, it seems to me that it is a bit easier to discover this way.

This is best viewed as a diff from commit
944a49e33562bd508a2af6e0dcfc938ba2769f1b; that way it is clearer what has
changed compared to the standalone-checkbox approach.

v2 changes:
- Hide the button altogether when not replying instead of just disabling it.
- Pretty formatting of the tooltips and sanitization of HTML input
- Better captions

Thanks to Thomas Lübking for his comments.

v3 changes:
- Enable quick toggling via a default action, without expanding the menu
- Fix restoring of v2 drafts

v4 changes:
- Removed one superfluous QAction::trigger
- Better identifiers for the slots for updating & processing the quick toggle
action
- Changed the caption of the threaded reply marking action
- Some inline comments

REVIEW: 114815

M  +73   -26   src/Gui/ComposeWidget.cpp
M  +9    -2    src/Gui/ComposeWidget.h
M  +6    -36   src/Gui/ComposeWidget.ui

http://commits.kde.org/trojita/b19141b9bfabf727d771f7ac8ee9588194af39e5

diff --git a/src/Gui/ComposeWidget.cpp b/src/Gui/ComposeWidget.cpp
index 1b98081..3b0ef6d 100644
--- a/src/Gui/ComposeWidget.cpp
+++ b/src/Gui/ComposeWidget.cpp
@@ -32,6 +32,7 @@
 #include <QPushButton>
 #include <QSettings>
 #include <QTimer>
+#include <QToolButton>
 
 #include "ui_ComposeWidget.h"
 #include "Composer/MessageComposer.h"
@@ -60,7 +61,6 @@
 namespace
 {
 enum { OFFSET_OF_FIRST_ADDRESSEE = 1, MIN_MAX_VISIBLE_RECIPIENTS = 4 };
-enum { IN_REPLY_TO = 0, SUBJECT = 1 };
 }
 
 namespace Gui
@@ -123,7 +123,34 @@ ComposeWidget::ComposeWidget(MainWindow *mainWindow, QSettings *settings, MSA::M
     ui->recipientSlider->setVisible(false);
     ui->envelopeWidget->installEventFilter(this);
 
-    connect(ui->markAsReply, SIGNAL(currentIndexChanged(int)), this, SLOT(toggleInReplyTo(int)));
+    m_markButton = new QToolButton(ui->buttonBox);
+    m_markButton->setPopupMode(QToolButton::MenuButtonPopup);
+    m_markButton->setToolButtonStyle(Qt::ToolButtonTextOnly);
+    m_markAsReply = new QActionGroup(m_markButton);
+    m_markAsReply->setExclusive(true);
+    auto *asReplyMenu = new QMenu(m_markButton);
+    m_markButton->setMenu(asReplyMenu);
+    m_actionStandalone = asReplyMenu->addAction(tr("Standalone"));
+    m_actionStandalone->setActionGroup(m_markAsReply);
+    m_actionStandalone->setCheckable(true);
+    m_actionStandalone->setToolTip(tr("This mail will be sent as a standalone message.<hr/>Change to preserve the reply hierarchy."));
+    m_actionInReplyTo = asReplyMenu->addAction(tr("Threaded"));
+    m_actionInReplyTo->setActionGroup(m_markAsReply);
+    m_actionInReplyTo->setCheckable(true);
+
+    // This is a "quick shortcut action". It shows the UI bits of the current option, but when the user clicks it,
+    // the *other* action is triggered.
+    m_actionToggleMarking = new QAction(m_markButton);
+    connect(m_actionToggleMarking, SIGNAL(triggered()), this, SLOT(toggleReplyMarking()));
+    m_markButton->setDefaultAction(m_actionToggleMarking);
+
+    // Unfortunately, there's no signal for toggled(QAction*), so we'll have to call QAction::trigger() to have this working
+    connect(m_markAsReply, SIGNAL(triggered(QAction*)), this, SLOT(updateReplyMarkingAction()));
+    m_actionStandalone->trigger();
+    // We want to have the button aligned to the left; the only "portable" way of this is the ResetRole
+    // (thanks to TL for mentioning this, and for the Qt's doc for providing pretty pictures on different platforms)
+    ui->buttonBox->addButton(m_markButton, QDialogButtonBox::ResetRole);
+    m_markButton->hide();
 
     ui->mailText->setFont(Gui::Util::systemMonospaceFont());
 
@@ -294,7 +321,7 @@ bool ComposeWidget::buildMessageData()
     }
     m_submission->composer()->setText(ui->mailText->toPlainText());
 
-    if (ui->markAsReply->currentIndex() == IN_REPLY_TO) {
+    if (m_actionInReplyTo->isChecked()) {
         m_submission->composer()->setInReplyTo(m_inReplyTo);
         m_submission->composer()->setReferences(m_references);
         m_submission->composer()->setReplyingToMessage(m_replyingToMessage);
@@ -365,15 +392,20 @@ void ComposeWidget::setData(const QList<QPair<Composer::RecipientKind, QString>
     m_references = references;
     m_replyingToMessage = replyingToMessage;
     if (m_replyingToMessage.isValid()) {
-        QVariant replySubject = m_replyingToMessage.data(Imap::Mailbox::RoleMessageSubject);
-        ui->markAsReply->setProperty("tooltip", replySubject);
-        ui->markAsReply->setToolTip(replySubject.toString());
-        ui->subjectLabel->hide();
-        ui->markAsReply->show();
-        ui->markAsReply->setCurrentIndex(IN_REPLY_TO);
+        m_markButton->show();
+        // Got to use trigger() so that the default action of the QToolButton is updated
+        m_actionInReplyTo->setToolTip(tr("This mail will be marked as a response<hr/>%1").arg(
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+                                          m_replyingToMessage.data(Imap::Mailbox::RoleMessageSubject).toString().toHtmlEscaped()
+#else
+                                          Qt::escape(m_replyingToMessage.data(Imap::Mailbox::RoleMessageSubject).toString())
+#endif
+                                          ));
+        m_actionInReplyTo->trigger();
     } else {
-        ui->markAsReply->hide();
-        ui->subjectLabel->show();
+        m_markButton->hide();
+        m_actionInReplyTo->setToolTip(QString());
+        m_actionStandalone->trigger();
     }
 
     int row = -1;
@@ -1008,7 +1040,7 @@ void ComposeWidget::saveDraft(const QString &path)
         stream << m_recipients.at(i).second->text();
     }
     stream << m_submission->composer()->timestamp() << m_inReplyTo << m_references;
-    stream << bool(ui->markAsReply->currentIndex() == IN_REPLY_TO);
+    stream << m_actionInReplyTo->isChecked();
     stream << ui->subject->text();
     stream << ui->mailText->toPlainText();
     // we spare attachments
@@ -1060,12 +1092,8 @@ void ComposeWidget::loadDraft(const QString &path)
         QDateTime timestamp;
         stream >> timestamp >> m_inReplyTo >> m_references;
         m_submission->composer()->setTimestamp(timestamp);
-        if (m_inReplyTo.isEmpty()) {
-            ui->markAsReply->hide();
-            ui->subjectLabel->show();
-        } else {
-            ui->subjectLabel->hide();
-            ui->markAsReply->show();
+        if (!m_inReplyTo.isEmpty()) {
+            m_markButton->show();
 
             // We do not have the message index at this point, but we can at least show the Message-Id here
             QStringList inReplyTo;
@@ -1073,13 +1101,28 @@ void ComposeWidget::loadDraft(const QString &path)
                 // There's no HTML escaping to worry about
                 inReplyTo << QLatin1Char('<') + QString::fromUtf8(item.constData()) + QLatin1Char('>');
             }
-            ui->markAsReply->setProperty("tooltip", tr("In-Reply-To: %1").arg(inReplyTo.join(tr(", "))));
+            m_actionInReplyTo->setToolTip(tr("This mail will be marked as a response<hr/>%1").arg(
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+                                              inReplyTo.join(tr("<br/>")).toHtmlEscaped()
+#else
+                                              Qt::escape(inReplyTo.join(tr("<br/>")))
+#endif
+                                              ));
+            if (version == 2) {
+                // it is always marked as a reply in v2
+                m_actionInReplyTo->trigger();
+            }
         }
     }
     if (version >= 3) {
         bool replyChecked;
         stream >> replyChecked;
-        ui->markAsReply->setCurrentIndex(replyChecked ? IN_REPLY_TO : SUBJECT);
+        // Got to use trigger() so that the default action of the QToolButton is updated
+        if (replyChecked) {
+            m_actionInReplyTo->trigger();
+        } else {
+            m_actionStandalone->trigger();
+        }
     }
     stream >> string;
     ui->subject->setText(string);
@@ -1111,13 +1154,17 @@ void ComposeWidget::updateWindowTitle()
     }
 }
 
-void ComposeWidget::toggleInReplyTo(int mode)
+void ComposeWidget::toggleReplyMarking()
 {
-    if (mode == IN_REPLY_TO) {
-        ui->markAsReply->setToolTip(ui->markAsReply->property("tooltip").toString());
-    } else {
-        ui->markAsReply->setToolTip(tr("Change to preserve reply hierarchy"));
-    }
+    (m_actionInReplyTo->isChecked() ? m_actionStandalone : m_actionInReplyTo)->trigger();
+}
+
+void ComposeWidget::updateReplyMarkingAction()
+{
+    auto action = m_markAsReply->checkedAction();
+    m_actionToggleMarking->setText(action->text());
+    m_actionToggleMarking->setIcon(action->icon());
+    m_actionToggleMarking->setToolTip(action->toolTip());
 }
 
 }
diff --git a/src/Gui/ComposeWidget.h b/src/Gui/ComposeWidget.h
index af3d03d..d556af4 100644
--- a/src/Gui/ComposeWidget.h
+++ b/src/Gui/ComposeWidget.h
@@ -36,11 +36,13 @@ class ComposeWidget;
 }
 
 class QAbstractListModel;
+class QActionGroup;
 class QComboBox;
 class QLineEdit;
 class QMenu;
 class QPushButton;
 class QSettings;
+class QToolButton;
 
 namespace Composer {
 class Submission;
@@ -111,8 +113,8 @@ private slots:
     void setUiWidgetsEnabled(const bool enabled);
 
     void passwordRequested(const QString &user, const QString &host);
-
-    void toggleInReplyTo(int mode);
+    void toggleReplyMarking();
+    void updateReplyMarkingAction();
 
 private:
     static QByteArray extractMailAddress(const QString &text, bool &ok);
@@ -130,6 +132,11 @@ private:
     Ui::ComposeWidget *ui;
     QPushButton *sendButton;
     QPushButton *cancelButton;
+    QToolButton *m_markButton;
+    QActionGroup *m_markAsReply;
+    QAction *m_actionStandalone;
+    QAction *m_actionInReplyTo;
+    QAction *m_actionToggleMarking;
     typedef QPair<QComboBox*, QLineEdit*> Recipient;
     QList<Recipient> m_recipients;
     QTimer *m_recipientListUpdateTimer;
diff --git a/src/Gui/ComposeWidget.ui b/src/Gui/ComposeWidget.ui
index f2f6cdc..559a849 100644
--- a/src/Gui/ComposeWidget.ui
+++ b/src/Gui/ComposeWidget.ui
@@ -72,44 +72,14 @@
            </widget>
           </item>
           <item row="1" column="0">
-           <layout class="QHBoxLayout" name="horizontalLayout1">
-            <property name="spacing">
-             <number>0</number>
+           <widget class="QLabel" name="subjectLabel">
+            <property name="text">
+             <string>Subject</string>
             </property>
-            <property name="margin">
-             <number>0</number>
+            <property name="buddy">
+             <cstring>subject</cstring>
             </property>
-            <item>
-             <widget class="QLabel" name="subjectLabel">
-              <property name="text">
-               <string>Subject</string>
-              </property>
-              <property name="buddy">
-               <cstring>subject</cstring>
-              </property>
-             </widget>
-            </item>
-            <item>
-             <widget class="QComboBox" name="markAsReply">
-              <property name="sizePolicy">
-               <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-                <horstretch>0</horstretch>
-                <verstretch>0</verstretch>
-               </sizepolicy>
-              </property>
-              <item>
-               <property name="text">
-                <string>Reply to</string>
-               </property>
-              </item>
-              <item>
-               <property name="text">
-                <string>Subject</string>
-               </property>
-              </item>
-             </widget>
-            </item>
-           </layout>
+           </widget>
           </item>
           <item row="1" column="1">
            <widget class="LineEdit" name="subject"/>



More information about the kde-doc-english mailing list