3232
3333#include " utils.h"
3434
35+ #include < QCloseEvent>
3536#include < QDebug>
3637#include < QLabel>
3738#include < QMenuBar>
@@ -61,6 +62,7 @@ struct PlatformStat
6162MainWindow::MainWindow (QWidget *parent)
6263 : QMainWindow(parent)
6364 , m_view(nullptr )
65+ , m_systemTrayIcon(nullptr )
6466{
6567 QIcon appIcon = QIcon ();
6668 appIcon.addFile (QStringLiteral (" :/images/128-apps-icemon.png" ), QSize (128 , 128 ));
@@ -81,8 +83,32 @@ MainWindow::MainWindow(QWidget *parent)
8183 m_jobStatsWidget = new QLabel;
8284 m_jobStatsWidget->setVisible (false );
8385 statusBar ()->addPermanentWidget (m_jobStatsWidget);
86+
87+ QAction *action = nullptr ;
8488
85- QAction *action = fileMenu->addAction (tr (" &Quit" ), this , SLOT (close ()), tr (" Ctrl+Q" ));
89+ if (QSystemTrayIcon::isSystemTrayAvailable ())
90+ {
91+ action = fileMenu->addAction (tr (" Show in System Tray" ));
92+ action->setIcon (QIcon::fromTheme (QStringLiteral (" systemtray" )));
93+ action->setCheckable (true );
94+ connect (action, &QAction::triggered, this , &MainWindow::updateSystemTrayVisible);
95+ m_showInSystemTrayAction = action;
96+
97+ QMenu *systrayMenu = new QMenu (this );
98+ QAction *quitAction = systrayMenu->addAction (tr (" &Quit" ), this , SLOT (quit ()), tr (" Ctrl+Q" ));
99+ quitAction->setIcon (QIcon::fromTheme (QStringLiteral (" application-exit" )));
100+ quitAction->setMenuRole (QAction::QuitRole);
101+
102+ m_systemTrayIcon = new QSystemTrayIcon (this );
103+ m_systemTrayIcon->setIcon (appIcon);
104+ m_systemTrayIcon->setToolTip (windowTitle ());
105+ m_systemTrayIcon->setContextMenu (systrayMenu);
106+ connect (m_systemTrayIcon, &QSystemTrayIcon::activated, this , &MainWindow::systemTrayIconActivated);
107+
108+ fileMenu->addSeparator ();
109+ }
110+
111+ action = fileMenu->addAction (tr (" &Quit" ), this , SLOT (quit ()), tr (" Ctrl+Q" ));
86112 action->setIcon (QIcon::fromTheme (QStringLiteral (" application-exit" )));
87113 action->setMenuRole (QAction::QuitRole);
88114
@@ -146,6 +172,25 @@ MainWindow::~MainWindow()
146172
147173void MainWindow::closeEvent (QCloseEvent *e)
148174{
175+ if (m_systemTrayIcon->isVisible ())
176+ {
177+ QSettings settings;
178+ const bool shownBefore = settings.value (QStringLiteral (" programWillKeepRunningWarningShown" )).toBool ();
179+ if (!shownBefore) {
180+ QMessageBox::information (this , tr (" Systray" ),
181+ tr (" The program will keep running in the "
182+ " system tray. To terminate the program, "
183+ " choose <b>Quit</b> in the context menu "
184+ " of the system tray entry." ));
185+ settings.setValue (QStringLiteral (" programWillKeepRunningWarningShown" ), true );
186+ settings.sync ();
187+ }
188+
189+ hide ();
190+ e->ignore ();
191+ return ;
192+ }
193+
149194 writeSettings ();
150195
151196 QMainWindow::closeEvent (e);
@@ -156,17 +201,22 @@ void MainWindow::readSettings()
156201 QSettings settings;
157202 restoreGeometry (settings.value (QStringLiteral (" geometry" )).toByteArray ());
158203 restoreState (settings.value (QStringLiteral (" windowState" )).toByteArray ());
204+ bool showSystemTray = settings.value (QStringLiteral (" showSystemTray" )).toBool ();
159205 QString viewId = settings.value (QStringLiteral (" currentView" )).toString ();
160206
161207 auto view = StatusViewFactory::create (viewId, this );
162208 setView (view);
209+
210+ m_showInSystemTrayAction->setChecked (showSystemTray);
211+ updateSystemTrayVisible ();
163212}
164213
165214void MainWindow::writeSettings ()
166215{
167216 QSettings settings;
168217 settings.setValue (QStringLiteral (" geometry" ), saveGeometry ());
169218 settings.setValue (QStringLiteral (" windowState" ), saveState ());
219+ settings.setValue (QStringLiteral (" showSystemTray" ), m_systemTrayIcon->isVisible ());
170220 settings.setValue (QStringLiteral (" currentView" ), (m_view ? m_view->id () : QString ()));
171221 settings.sync ();
172222}
@@ -247,6 +297,44 @@ void MainWindow::configureView()
247297 m_view->configureView ();
248298}
249299
300+ void MainWindow::updateSystemTrayVisible ()
301+ {
302+ if (m_showInSystemTrayAction->isChecked ()) {
303+ m_systemTrayIcon->show ();
304+ } else {
305+ m_systemTrayIcon->hide ();
306+ }
307+ }
308+
309+ void MainWindow::quit ()
310+ {
311+ writeSettings ();
312+ qApp->quit ();
313+ }
314+
315+ void MainWindow::systemTrayIconActivated (QSystemTrayIcon::ActivationReason reason)
316+ {
317+ switch (reason) {
318+ case QSystemTrayIcon::Trigger:
319+ if (isVisible ()) {
320+ if (isMinimized ()) {
321+ showMaximized ();
322+ } else {
323+ hide ();
324+ }
325+ } else {
326+ show ();
327+ }
328+ break ;
329+
330+ case QSystemTrayIcon::DoubleClick:
331+ case QSystemTrayIcon::MiddleClick:
332+ case QSystemTrayIcon::Unknown:
333+ default :
334+ ;
335+ }
336+ }
337+
250338void MainWindow::about ()
251339{
252340 QString about = tr (" <p><strong>%1</strong><br/>"
@@ -306,6 +394,7 @@ void MainWindow::updateJobStats()
306394 if (!m_monitor->schedulerState ()) {
307395 m_jobStatsWidget->clear ();
308396 m_jobStatsWidget->setVisible (false );
397+ m_systemTrayIcon->setToolTip (tr (" Scheduler is offline." ));
309398 return ;
310399 }
311400
@@ -337,6 +426,7 @@ void MainWindow::updateJobStats()
337426
338427 // Compose the text
339428 QString text;
429+ QString textNoHTML;
340430 foreach (auto pair, statistics) {
341431 const QString& platform = pair.first ;
342432 const PlatformStat& stat = pair.second ;
@@ -346,13 +436,16 @@ void MainWindow::updateJobStats()
346436
347437 if (!text.isEmpty ()) {
348438 text.append (QStringLiteral (" - " ));
439+ textNoHTML.append (QStringLiteral (" - " ));
349440 }
350441
351442 text.append (QStringLiteral (" <strong>%2/%3</strong> on %1" ).arg (platform).arg (stat.jobs ).arg (stat.maxJobs ));
443+ textNoHTML.append (QStringLiteral (" %2/%3 on %1" ).arg (platform).arg (stat.jobs ).arg (stat.maxJobs ));
352444 }
353445
354446 m_jobStatsWidget->setText (tr (" | Active jobs: %1" ).arg (text));
355447 m_jobStatsWidget->setVisible (true );
448+ m_systemTrayIcon->setToolTip (tr (" Active jobs: %1" ).arg (textNoHTML));
356449}
357450
358451void MainWindow::setCurrentNet (const QByteArray &netname)
0 commit comments