[kde-doc-english] [trojita] src: GUI: systray support

Jan Kundrát jkt at flaska.net
Fri May 17 14:13:49 UTC 2013


Git commit 84b208885c6f23354b6cc9ecef7c268d417b1d53 by Jan Kundrát, on behalf of Stefan Kögl.
Committed on 17/05/2013 at 16:03.
Pushed by jkt into branch 'master'.

GUI: systray support

fixes #67
REVIEW: 110461

M  +1    -0    src/Common/SettingsNames.cpp
M  +1    -0    src/Common/SettingsNames.h
M  +4    -0    src/Gui/SettingsDialog.cpp
M  +7    -0    src/Gui/SettingsGeneralPage.ui
M  +92   -1    src/Gui/Window.cpp
M  +13   -1    src/Gui/Window.h

http://commits.kde.org/trojita/84b208885c6f23354b6cc9ecef7c268d417b1d53

diff --git a/src/Common/SettingsNames.cpp b/src/Common/SettingsNames.cpp
index e98f483..08e4d3d 100644
--- a/src/Common/SettingsNames.cpp
+++ b/src/Common/SettingsNames.cpp
@@ -81,6 +81,7 @@ QString SettingsNames::guiMainWindowLayout = QLatin1String("gui/mainWindow.layou
 QString SettingsNames::guiMainWindowLayoutCompact = QLatin1String("compact");
 QString SettingsNames::guiMainWindowLayoutWide = QLatin1String("wide");
 QString SettingsNames::guiPreferPlaintextRendering = QLatin1String("gui/preferPlaintextRendering");
+QString SettingsNames::guiShowSystray = QLatin1String("gui/showSystray");
 QString SettingsNames::appLoadHomepage = QLatin1String("app.updates.checkEnabled");
 QString SettingsNames::knownEmailsKey = QLatin1String("addressBook/knownEmails");
 
diff --git a/src/Common/SettingsNames.h b/src/Common/SettingsNames.h
index 9b46746..492c8db 100644
--- a/src/Common/SettingsNames.h
+++ b/src/Common/SettingsNames.h
@@ -46,6 +46,7 @@ struct SettingsNames {
     static QString guiPreferPlaintextRendering;
     static QString guiMainWindowLayout, guiMainWindowLayoutCompact, guiMainWindowLayoutWide;
     static QString appLoadHomepage;
+    static QString guiShowSystray;
     static QString knownEmailsKey;
 };
 
diff --git a/src/Gui/SettingsDialog.cpp b/src/Gui/SettingsDialog.cpp
index ce39034..e7e5c4b 100644
--- a/src/Gui/SettingsDialog.cpp
+++ b/src/Gui/SettingsDialog.cpp
@@ -139,6 +139,9 @@ GeneralPage::GeneralPage(QWidget *parent, QSettings &s, Composer::SenderIdentiti
                                         "<p>The remote server will receive the user's IP address and versions of Trojitá, the Qt library, "
                                         "and the underlying operating system. No private information, like account settings "
                                         "or IMAP server details, are collected.</p>"));
+
+    guiSystrayCheckbox->setChecked(s.value(Common::SettingsNames::guiShowSystray, QVariant(false)).toBool());
+
     preferPlaintextCheckbox->setChecked(s.value(Common::SettingsNames::guiPreferPlaintextRendering).toBool());
 
     connect(identityTabelView, SIGNAL(clicked(QModelIndex)), SLOT(updateWidgets()));
@@ -223,6 +226,7 @@ void GeneralPage::save(QSettings &s)
     m_identitiesModel->saveToSettings(s);
     s.setValue(Common::SettingsNames::appLoadHomepage, showHomepageCheckbox->isChecked());
     s.setValue(Common::SettingsNames::guiPreferPlaintextRendering, preferPlaintextCheckbox->isChecked());
+    s.setValue(Common::SettingsNames::guiShowSystray, guiSystrayCheckbox->isChecked());
 }
 
 EditIdentity::EditIdentity(QWidget *parent, Composer::SenderIdentitiesModel *identitiesModel, const QModelIndex &currentIndex):
diff --git a/src/Gui/SettingsGeneralPage.ui b/src/Gui/SettingsGeneralPage.ui
index b9f0b17..f92f4cd 100644
--- a/src/Gui/SettingsGeneralPage.ui
+++ b/src/Gui/SettingsGeneralPage.ui
@@ -139,6 +139,13 @@
       </property>
      </widget>
     </item>
+    <item row="6" column="0">
+     <widget class="QCheckBox" name="guiSystrayCheckbox">
+      <property name="text">
+       <string>Show system tray icon</string>
+      </property>
+     </widget>
+    </item>
    </layout>
   </widget>
  </widget>
diff --git a/src/Gui/Window.cpp b/src/Gui/Window.cpp
index 511f327..0aebdf9 100644
--- a/src/Gui/Window.cpp
+++ b/src/Gui/Window.cpp
@@ -91,7 +91,7 @@ Q_DECLARE_METATYPE(QList<QSslError>)
 namespace Gui
 {
 
-MainWindow::MainWindow(): QMainWindow(), model(0), m_actionSortNone(0), m_ignoreStoredPassword(false)
+MainWindow::MainWindow(): QMainWindow(), model(0), m_actionSortNone(0), m_ignoreStoredPassword(false), m_trayIcon(0)
 {
     qRegisterMetaType<QList<QSslCertificate> >();
     qRegisterMetaType<QList<QSslError> >();
@@ -117,6 +117,7 @@ MainWindow::MainWindow(): QMainWindow(), model(0), m_actionSortNone(0), m_ignore
     setupModels();
     createActions();
     createMenus();
+    slotToggleSysTray();
 
     // Please note that Qt 4.6.1 really requires passing the method signature this way, *not* using the SLOT() macro
     QDesktopServices::setUrlHandler(QLatin1String("mailto"), this, "slotComposeMailUrl");
@@ -714,6 +715,95 @@ void MainWindow::setupModels()
     m_addressBook = new AbookAddressbook();
 }
 
+void MainWindow::createSysTray()
+{
+    if (m_trayIcon) {
+        return;
+    }
+
+    m_trayIcon = new QSystemTrayIcon(this);
+
+    m_trayIcon->setIcon(QIcon(QLatin1String(":/icons/trojita.png")));
+
+    QAction* quitAction = new QAction(tr("&Quit"), m_trayIcon);
+    connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
+
+    QMenu *trayIconMenu = new QMenu(this);
+    trayIconMenu->addAction(quitAction);
+    m_trayIcon->setContextMenu(trayIconMenu);
+
+    // QMenu cannot be a child of QSystemTrayIcon, and we don't want the QMenu in MainWindow scope.
+    connect(m_trayIcon, SIGNAL(destroyed()),
+        trayIconMenu, SLOT(deleteLater()));
+
+    connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
+        this, SLOT(slotIconActivated(QSystemTrayIcon::ActivationReason)));
+    connect(model, SIGNAL(messageCountPossiblyChanged(QModelIndex)),
+        this, SLOT(handleTrayIconChange()));
+    m_trayIcon->setVisible(true);
+    m_trayIcon->show();
+}
+
+void MainWindow::removeSysTray() {
+    if (!m_trayIcon)
+        return;
+
+    m_trayIcon->hide();
+    delete m_trayIcon;
+    m_trayIcon = 0;
+}
+
+void MainWindow::slotToggleSysTray() {
+    QSettings s;
+    bool showSystray = s.value(Common::SettingsNames::guiShowSystray, QVariant(true)).toBool();
+    if (showSystray && !m_trayIcon) {
+        this->createSysTray();
+    } else if (!showSystray && m_trayIcon) {
+        this->removeSysTray();
+    }
+}
+
+void MainWindow::handleTrayIconChange() {
+    QModelIndex mailbox = model->index(1, 0, QModelIndex());
+
+    if (mailbox.isValid()) {
+        Q_ASSERT(mailbox.data(Imap::Mailbox::RoleMailboxName).toString() == QLatin1String("INBOX"));
+        QPixmap pixmap = QPixmap(QLatin1String(":/icons/trojita.png"));
+        if (mailbox.data(Imap::Mailbox::RoleUnreadMessageCount).toInt() > 0) {
+            QPainter painter(&pixmap);
+            QFont f;
+            f.setPixelSize(pixmap.height() / 2);
+            f.setWeight(QFont::Bold);
+            painter.setFont(f);
+            painter.setPen(Qt::blue);
+            painter.drawText(pixmap.rect(), Qt::AlignCenter, mailbox.data(Imap::Mailbox::RoleUnreadMessageCount).toString());
+        }
+        m_trayIcon->setIcon(QIcon(pixmap));
+    }
+}
+
+void MainWindow::closeEvent(QCloseEvent *event)
+{
+    if (m_trayIcon && m_trayIcon->isVisible()) {
+        hide();
+        event->ignore();
+    }
+}
+
+void MainWindow::slotIconActivated(QSystemTrayIcon::ActivationReason reason)
+{
+    switch (reason) {
+    case QSystemTrayIcon::Trigger:
+        setVisible(!isVisible());
+    case QSystemTrayIcon::DoubleClick:
+        break;
+    case QSystemTrayIcon::MiddleClick:
+        break;
+    default:
+        ;
+    }
+ }
+
 void MainWindow::msgListClicked(const QModelIndex &index)
 {
     Q_ASSERT(index.isValid());
@@ -907,6 +997,7 @@ void MainWindow::slotShowSettings()
         nukeModels();
         setupModels();
         connectModelActions();
+        slotToggleSysTray();
     }
 }
 
diff --git a/src/Gui/Window.h b/src/Gui/Window.h
index 2bf7ff3..38339e0 100644
--- a/src/Gui/Window.h
+++ b/src/Gui/Window.h
@@ -25,12 +25,14 @@
 
 #include <QMainWindow>
 #include <QModelIndex>
+#include <QSystemTrayIcon>
 
 #include "Composer/Recipients.h"
 #include "Imap/ConnectionState.h"
 #include "Imap/Model/Cache.h"
 
 class QAuthenticator;
+class QCloseEvent;
 class QItemSelection;
 class QModelIndex;
 class QScrollArea;
@@ -88,7 +90,8 @@ public:
 
     const AbstractAddressbook *addressBook() const { return m_addressBook; }
     Composer::SenderIdentitiesModel *senderIdentitiesModel() { return m_senderIdentities; }
-
+protected:
+    void closeEvent(QCloseEvent *event);
 private slots:
     void showContextMenuMboxTree(const QPoint &position);
     void showContextMenuMsgListTree(const QPoint &position);
@@ -125,6 +128,7 @@ private slots:
     void slotCreateMailboxBelowCurrent();
     void slotCreateTopMailbox();
     void slotDeleteCurrentMailbox();
+    void handleTrayIconChange();
 #ifdef XTUPLE_CONNECT
     void slotXtSyncCurrentMailbox();
 #endif
@@ -160,6 +164,8 @@ private slots:
     void slotLayoutCompact();
     void slotLayoutWide();
 
+    void slotIconActivated(QSystemTrayIcon::ActivationReason reason);
+    void slotToggleSysTray();
 private:
     void defineActions();
     void createMenus();
@@ -177,6 +183,8 @@ private:
     void migrateSettings();
 
     void recoverDrafts();
+    void createSysTray();
+    void removeSysTray();
 
     Imap::Mailbox::Model *model;
     Imap::Mailbox::MailboxModel *mboxModel;
@@ -260,6 +268,8 @@ private:
     QAction *m_actionSubscribeMailbox;
     QAction *m_actionShowOnlySubscribed;
 
+    QAction *m_quitAction;
+
     QToolBar *m_mainToolbar;
     QToolButton *m_replyButton;
     QMenu *m_replyMenu;
@@ -275,6 +285,8 @@ private:
 
     MainWindow(const MainWindow &); // don't implement
     MainWindow &operator=(const MainWindow &); // don't implement
+
+    QSystemTrayIcon *m_trayIcon;
 };
 
 }



More information about the kde-doc-english mailing list