diff --git a/src/ui/form/opt/pages/optionspage.cpp b/src/ui/form/opt/pages/optionspage.cpp index 39c2dfaa..4b12b5e3 100644 --- a/src/ui/form/opt/pages/optionspage.cpp +++ b/src/ui/form/opt/pages/optionspage.cpp @@ -184,6 +184,7 @@ void OptionsPage::onRetranslateUi() m_labelLanguage->setText(tr("Language:")); + m_cbTrayAnimateAlert->setText(tr("Animate Alert Icon")); m_labelTrayEvent->setText(tr("Event:")); m_labelTrayAction->setText(tr("Action:")); retranslateComboTrayEvent(); @@ -571,11 +572,19 @@ void OptionsPage::setupComboLanguage() void OptionsPage::setupTrayBox() { + m_cbTrayAnimateAlert = + ControlUtil::createCheckBox(iniUser()->trayAnimateAlert(), [&](bool checked) { + iniUser()->setTrayAnimateAlert(checked); + confManager()->saveIniUser(true); + }); + // Tray Event & Action Rows auto eventLayout = setupTrayEventLayout(); auto actionLayout = setupTrayActionLayout(); auto layout = new QVBoxLayout(); + layout->addWidget(m_cbTrayAnimateAlert); + layout->addWidget(ControlUtil::createSeparator()); layout->addLayout(eventLayout); layout->addLayout(actionLayout); diff --git a/src/ui/form/opt/pages/optionspage.h b/src/ui/form/opt/pages/optionspage.h index f60248b2..b2de4df2 100644 --- a/src/ui/form/opt/pages/optionspage.h +++ b/src/ui/form/opt/pages/optionspage.h @@ -87,6 +87,7 @@ private: QToolButton *m_btPasswordLock = nullptr; QLabel *m_labelLanguage = nullptr; QComboBox *m_comboLanguage = nullptr; + QCheckBox *m_cbTrayAnimateAlert = nullptr; QLabel *m_labelTrayEvent = nullptr; QComboBox *m_comboTrayEvent = nullptr; QLabel *m_labelTrayAction = nullptr; diff --git a/src/ui/form/tray/trayicon.cpp b/src/ui/form/tray/trayicon.cpp index 34edfc1d..c66a24ad 100644 --- a/src/ui/form/tray/trayicon.cpp +++ b/src/ui/form/tray/trayicon.cpp @@ -149,7 +149,10 @@ QAction *addAction(QWidget *widget, const QIcon &icon, const QString &text, } TrayIcon::TrayIcon(QObject *parent) : - QSystemTrayIcon(parent), m_trayTriggered(false), m_ctrl(new TrayController(this)) + QSystemTrayIcon(parent), + m_trayTriggered(false), + m_animatedAlert(false), + m_ctrl(new TrayController(this)) { setupUi(); setupController(); @@ -214,10 +217,9 @@ void TrayIcon::onTrayActivated(QSystemTrayIcon::ActivationReason reason) void TrayIcon::updateTrayIcon(bool alerted) { - const auto icon = alerted ? GuiUtil::overlayIcon(":/icons/sheild-96.png", ":/icons/error.png") - : IconCache::icon(":/icons/sheild-96.png"); + updateAnimatedTrayIcon(alerted); - this->setIcon(icon); + updateAlertTimer(alerted); } void TrayIcon::showTrayMenu(const QPoint &pos) @@ -445,6 +447,40 @@ void TrayIcon::updateAppGroupActions() } } +void TrayIcon::updateAlertTimer(bool alerted) +{ + if (!iniUser()->trayAnimateAlert()) + return; + + if (!m_alertTimer) { + m_alertTimer = new QTimer(this); + m_alertTimer->setInterval(1000); + + connect(m_alertTimer, &QTimer::timeout, this, [&] { + m_animatedAlert = !m_animatedAlert; + updateAnimatedTrayIcon(/*alerted=*/true, m_animatedAlert); + }); + } + + m_animatedAlert = alerted; + + if (alerted) { + m_alertTimer->start(); + } else { + m_alertTimer->stop(); + } +} + +void TrayIcon::updateAnimatedTrayIcon(bool alerted, bool animated) +{ + const auto icon = alerted + ? (animated ? IconCache::icon(":/icons/error.png") + : GuiUtil::overlayIcon(":/icons/sheild-96.png", ":/icons/error.png")) + : IconCache::icon(":/icons/sheild-96.png"); + + this->setIcon(icon); +} + void TrayIcon::saveTrayFlags() { conf()->setFilterEnabled(m_filterEnabledAction->isChecked()); diff --git a/src/ui/form/tray/trayicon.h b/src/ui/form/tray/trayicon.h index 2bf60974..ae9f0a1f 100644 --- a/src/ui/form/tray/trayicon.h +++ b/src/ui/form/tray/trayicon.h @@ -5,6 +5,7 @@ QT_FORWARD_DECLARE_CLASS(QAction) QT_FORWARD_DECLARE_CLASS(QActionGroup) +QT_FORWARD_DECLARE_CLASS(QTimer) class ConfManager; class FirewallConf; @@ -85,6 +86,9 @@ private: void updateTrayMenuFlags(); void updateAppGroupActions(); + void updateAlertTimer(bool alerted); + void updateAnimatedTrayIcon(bool alerted, bool animated = false); + void addHotKey(QAction *action, const QString &shortcutText); void updateHotKeys(); void removeHotKeys(); @@ -103,6 +107,7 @@ private: private: bool m_trayTriggered : 1; + bool m_animatedAlert : 1; TrayController *m_ctrl = nullptr; @@ -123,6 +128,8 @@ private: QList m_appGroupActions; QAction *m_clickActions[ClickTypeCount] = { nullptr }; + + QTimer *m_alertTimer = nullptr; }; #endif // TRAYICON_H diff --git a/src/ui/user/iniuser.h b/src/ui/user/iniuser.h index a514ea15..f31feafc 100644 --- a/src/ui/user/iniuser.h +++ b/src/ui/user/iniuser.h @@ -32,6 +32,9 @@ public: } QString hotKeyQuit() const { return valueText("hotKey/quit"); } + bool trayAnimateAlert() const { return valueBool("tray/animateAlert"); } + void setTrayAnimateAlert(bool v) { setValue("tray/animateAlert", v); } + QString trayAction(const QString &event) const { return valueText("tray/" + event); } void setTrayAction(const QString &event, const QString &v) { setValue("tray/" + event, v); }