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 ¤tIndex): 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; }; }
