diff --git a/src/ui/FortFirewallUI.pro b/src/ui/FortFirewallUI.pro index 663eca68..734f8e7f 100644 --- a/src/ui/FortFirewallUI.pro +++ b/src/ui/FortFirewallUI.pro @@ -53,6 +53,8 @@ SOURCES += \ form/opt/pages/statisticspage.cpp \ form/prog/programscontroller.cpp \ form/prog/programswindow.cpp \ + form/tray/traycontroller.cpp \ + form/tray/trayicon.cpp \ form/zone/zonescontroller.cpp \ form/zone/zoneswindow.cpp \ fortcommon.cpp \ @@ -177,6 +179,8 @@ HEADERS += \ form/opt/pages/statisticspage.h \ form/prog/programscontroller.h \ form/prog/programswindow.h \ + form/tray/traycontroller.h \ + form/tray/trayicon.h \ form/zone/zonescontroller.h \ form/zone/zoneswindow.h \ fortcommon.h \ diff --git a/src/ui/conf/appgroup.h b/src/ui/conf/appgroup.h index b6a70909..ac95f0f7 100644 --- a/src/ui/conf/appgroup.h +++ b/src/ui/conf/appgroup.h @@ -4,6 +4,8 @@ #include #include +#define MAX_APP_GROUP_COUNT 16 + class AppGroup : public QObject { Q_OBJECT diff --git a/src/ui/form/conn/connectionswindow.cpp b/src/ui/form/conn/connectionswindow.cpp index e57da20e..2b4e688a 100644 --- a/src/ui/form/conn/connectionswindow.cpp +++ b/src/ui/form/conn/connectionswindow.cpp @@ -36,9 +36,6 @@ ConnectionsWindow::ConnectionsWindow(FortManager *fortManager, QWidget *parent) void ConnectionsWindow::setupController() { - connect(ctrl(), &ConnectionsController::retranslateUi, this, - &ConnectionsWindow::onRetranslateUi); - connect(this, &ConnectionsWindow::aboutToClose, fortManager(), &FortManager::closeConnectionsWindow); @@ -47,6 +44,9 @@ void ConnectionsWindow::setupController() connect(fortManager(), &FortManager::afterRestoreConnWindowState, this, &ConnectionsWindow::onRestoreWindowState); + connect(ctrl(), &ConnectionsController::retranslateUi, this, + &ConnectionsWindow::onRetranslateUi); + emit ctrl()->retranslateUi(); } diff --git a/src/ui/form/opt/pages/applicationspage.cpp b/src/ui/form/opt/pages/applicationspage.cpp index fe33dcb2..230da05a 100644 --- a/src/ui/form/opt/pages/applicationspage.cpp +++ b/src/ui/form/opt/pages/applicationspage.cpp @@ -200,7 +200,9 @@ void ApplicationsPage::setupAddGroup() ctrl()->setConfEdited(true); }); - const auto refreshAddGroup = [&] { m_btAddGroup->setEnabled(appGroupsCount() < 16); }; + const auto refreshAddGroup = [&] { + m_btAddGroup->setEnabled(appGroupsCount() < MAX_APP_GROUP_COUNT); + }; refreshAddGroup(); diff --git a/src/ui/form/prog/programswindow.cpp b/src/ui/form/prog/programswindow.cpp index fda27491..cb5ce0ea 100644 --- a/src/ui/form/prog/programswindow.cpp +++ b/src/ui/form/prog/programswindow.cpp @@ -47,8 +47,6 @@ ProgramsWindow::ProgramsWindow(FortManager *fortManager, QWidget *parent) : void ProgramsWindow::setupController() { - connect(ctrl(), &ProgramsController::retranslateUi, this, &ProgramsWindow::onRetranslateUi); - connect(this, &ProgramsWindow::aboutToClose, fortManager(), &FortManager::closeProgramsWindow); connect(fortManager(), &FortManager::afterSaveProgWindowState, this, @@ -56,6 +54,8 @@ void ProgramsWindow::setupController() connect(fortManager(), &FortManager::afterRestoreProgWindowState, this, &ProgramsWindow::onRestoreWindowState); + connect(ctrl(), &ProgramsController::retranslateUi, this, &ProgramsWindow::onRetranslateUi); + emit ctrl()->retranslateUi(); } diff --git a/src/ui/form/tray/traycontroller.cpp b/src/ui/form/tray/traycontroller.cpp new file mode 100644 index 00000000..658e37f1 --- /dev/null +++ b/src/ui/form/tray/traycontroller.cpp @@ -0,0 +1,31 @@ +#include "traycontroller.h" + +#include "../../fortmanager.h" +#include "../../translationmanager.h" + +TrayController::TrayController(FortManager *fortManager, QObject *parent) : + QObject(parent), m_fortManager(fortManager) +{ + connect(translationManager(), &TranslationManager::languageChanged, this, + &TrayController::retranslateUi); +} + +FortSettings *TrayController::settings() const +{ + return fortManager()->settings(); +} + +FirewallConf *TrayController::conf() const +{ + return fortManager()->conf(); +} + +HotKeyManager *TrayController::hotKeyManager() const +{ + return fortManager()->hotKeyManager(); +} + +TranslationManager *TrayController::translationManager() const +{ + return TranslationManager::instance(); +} diff --git a/src/ui/form/tray/traycontroller.h b/src/ui/form/tray/traycontroller.h new file mode 100644 index 00000000..99614756 --- /dev/null +++ b/src/ui/form/tray/traycontroller.h @@ -0,0 +1,32 @@ +#ifndef TRAYCONTROLLER_H +#define TRAYCONTROLLER_H + +#include + +class FirewallConf; +class FortManager; +class FortSettings; +class HotKeyManager; +class TranslationManager; + +class TrayController : public QObject +{ + Q_OBJECT + +public: + explicit TrayController(FortManager *fortManager, QObject *parent = nullptr); + + FortManager *fortManager() const { return m_fortManager; } + FortSettings *settings() const; + FirewallConf *conf() const; + HotKeyManager *hotKeyManager() const; + TranslationManager *translationManager() const; + +signals: + void retranslateUi(); + +private: + FortManager *m_fortManager = nullptr; +}; + +#endif // TRAYCONTROLLER_H diff --git a/src/ui/form/tray/trayicon.cpp b/src/ui/form/tray/trayicon.cpp new file mode 100644 index 00000000..00b699b3 --- /dev/null +++ b/src/ui/form/tray/trayicon.cpp @@ -0,0 +1,295 @@ +#include "trayicon.h" + +#include +#include +#include +#include + +#include "../../conf/addressgroup.h" +#include "../../conf/appgroup.h" +#include "../../conf/firewallconf.h" +#include "../../fortcompat.h" +#include "../../fortmanager.h" +#include "../../fortsettings.h" +#include "../../util/guiutil.h" +#include "../../util/hotkeymanager.h" +#include "../../util/iconcache.h" +#include "../controls/mainwindow.h" +#include "traycontroller.h" + +namespace { + +void setActionCheckable(QAction *action, bool checked = false, const QObject *receiver = nullptr, + const char *member = nullptr) +{ + action->setCheckable(true); + action->setChecked(checked); + + if (receiver) { + QObject::connect(action, SIGNAL(toggled(bool)), receiver, member); + } +} + +QAction *addAction(QWidget *widget, const QIcon &icon, const QString &text, + const QObject *receiver = nullptr, const char *member = nullptr, bool checkable = false, + bool checked = false) +{ + auto action = new QAction(icon, text, widget); + + if (receiver) { + QObject::connect(action, SIGNAL(triggered(bool)), receiver, member); + } + if (checkable) { + setActionCheckable(action, checked); + } + + widget->addAction(action); + + return action; +} + +} + +TrayIcon::TrayIcon(FortManager *fortManager, QObject *parent) : + QSystemTrayIcon(parent), m_ctrl(new TrayController(fortManager, this)) +{ + setupUi(); + setupController(); +} + +void TrayIcon::updateTrayIcon(bool alerted) +{ + const auto icon = alerted + ? GuiUtil::overlayIcon(":/images/sheild-96.png", ":/icons/sign-warning.png") + : IconCache::icon(":/images/sheild-96.png"); + + this->setIcon(icon); +} + +void TrayIcon::showTrayMenu(QMouseEvent *event) +{ + QMenu *menu = this->contextMenu(); + if (!menu) + return; + + menu->popup(mouseEventGlobalPos(event)); +} + +void TrayIcon::updateTrayMenu(bool onlyFlags) +{ + if (!onlyFlags) { + updateAppGroupActions(); + } + + updateTrayMenuFlags(); + updateHotKeys(); +} + +void TrayIcon::updateTrayMenuFlags() +{ + const bool editEnabled = (!settings()->isPasswordRequired() && !fortManager()->optWindow()); + + m_filterEnabledAction->setEnabled(editEnabled); + m_stopTrafficAction->setEnabled(editEnabled); + m_stopInetTrafficAction->setEnabled(editEnabled); + m_allowAllNewAction->setEnabled(editEnabled); + + m_filterEnabledAction->setChecked(conf()->filterEnabled()); + m_stopTrafficAction->setChecked(conf()->stopTraffic()); + m_stopInetTrafficAction->setChecked(conf()->stopInetTraffic()); + m_allowAllNewAction->setChecked(conf()->allowAllNew()); + + int appGroupIndex = 0; + for (QAction *action : qAsConst(m_appGroupActions)) { + if (!action->isVisible()) + break; + + const auto appGroup = conf()->appGroups().at(appGroupIndex++); + + action->setEnabled(editEnabled); + action->setChecked(appGroup->enabled()); + } +} + +void TrayIcon::retranslateTrayMenu() +{ + m_programsAction->setText(tr("Programs")); + m_optionsAction->setText(tr("Options")); + m_zonesAction->setText(tr("Zones")); + m_graphWindowAction->setText(tr("Traffic Graph")); + m_connectionsAction->setText(tr("Connections")); + + m_filterEnabledAction->setText(tr("Filter Enabled")); + m_stopTrafficAction->setText(tr("Stop Traffic")); + m_stopInetTrafficAction->setText(tr("Stop Internet Traffic")); + m_allowAllNewAction->setText(tr("Auto-Allow New Programs")); + + m_quitAction->setText(tr("Quit")); +} + +void TrayIcon::onRetranslateUi() +{ + retranslateTrayMenu(); +} + +void TrayIcon::setupController() +{ + connect(fortManager(), &FortManager::optWindowChanged, this, &TrayIcon::updateTrayMenuFlags); + connect(fortManager(), &FortManager::graphWindowChanged, m_graphWindowAction, + &QAction::setChecked); + + connect(settings(), &FortSettings::passwordUnlockChanged, this, &TrayIcon::updateTrayMenuFlags); + + connect(ctrl(), &TrayController::retranslateUi, this, &TrayIcon::onRetranslateUi); + + emit ctrl()->retranslateUi(); +} + +void TrayIcon::setupUi() +{ + this->setToolTip(QApplication::applicationDisplayName()); + + setupTrayMenu(); + updateAppGroupActions(); + updateTrayMenuFlags(); + updateHotKeys(); + + updateTrayIcon(); +} + +void TrayIcon::setupTrayMenu() +{ + QMenu *menu = new QMenu(fortManager()->mainWindow()); + + m_programsAction = addAction(menu, IconCache::icon(":/icons/window.png"), QString(), + fortManager(), SLOT(showProgramsWindow())); + addHotKey(m_programsAction, settings()->hotKeyPrograms()); + + m_optionsAction = addAction(menu, IconCache::icon(":/icons/cog.png"), QString(), fortManager(), + SLOT(showOptionsWindow())); + addHotKey(m_optionsAction, settings()->hotKeyOptions()); + + m_zonesAction = addAction(menu, IconCache::icon(":/icons/map-map-marker.png"), QString(), + fortManager(), SLOT(showZonesWindow())); + addHotKey(m_zonesAction, settings()->hotKeyZones()); + + m_graphWindowAction = addAction(menu, IconCache::icon(":/icons/line-graph.png"), QString(), + fortManager(), SLOT(switchGraphWindow()), true, !!fortManager()->graphWindow()); + addHotKey(m_graphWindowAction, settings()->hotKeyGraph()); + + m_connectionsAction = addAction(menu, IconCache::icon(":/icons/connect.png"), QString(), + fortManager(), SLOT(showConnectionsWindow())); + addHotKey(m_connectionsAction, settings()->hotKeyConnections()); + + menu->addSeparator(); + + m_filterEnabledAction = addAction(menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true); + addHotKey(m_filterEnabledAction, settings()->hotKeyFilter()); + + m_stopTrafficAction = addAction(menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true); + addHotKey(m_stopTrafficAction, settings()->hotKeyStopTraffic()); + + m_stopInetTrafficAction = + addAction(menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true); + addHotKey(m_stopInetTrafficAction, settings()->hotKeyStopInetTraffic()); + + m_allowAllNewAction = addAction(menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true); + addHotKey(m_allowAllNewAction, settings()->hotKeyAllowAllNew()); + + menu->addSeparator(); + + for (int i = 0; i < MAX_APP_GROUP_COUNT; ++i) { + QAction *a = addAction(menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true); + + if (i < 12) { + const QString shortcutText = + settings()->hotKeyAppGroupModifiers() + "+F" + QString::number(i + 1); + + addHotKey(a, shortcutText); + } + + m_appGroupActions.append(a); + } + + menu->addSeparator(); + m_quitAction = addAction(menu, QIcon(), tr("Quit"), fortManager(), SLOT(quitByCheckPassword())); + addHotKey(m_quitAction, settings()->hotKeyQuit()); + + this->setContextMenu(menu); +} + +void TrayIcon::updateAppGroupActions() +{ + const int appGroupsCount = conf()->appGroups().count(); + + for (int i = 0; i < MAX_APP_GROUP_COUNT; ++i) { + QAction *action = m_appGroupActions.at(i); + QString menuLabel; + bool visible = false; + + if (i < appGroupsCount) { + const AppGroup *appGroup = conf()->appGroups().at(i); + menuLabel = appGroup->menuLabel(); + visible = true; + } + + action->setText(menuLabel); + action->setVisible(visible); + action->setEnabled(visible); + } +} + +void TrayIcon::saveTrayFlags() +{ + conf()->setFilterEnabled(m_filterEnabledAction->isChecked()); + conf()->setStopTraffic(m_stopTrafficAction->isChecked()); + conf()->setStopInetTraffic(m_stopInetTrafficAction->isChecked()); + conf()->setAllowAllNew(m_allowAllNewAction->isChecked()); + + int i = 0; + for (AppGroup *appGroup : conf()->appGroups()) { + const QAction *action = m_appGroupActions.at(i++); + appGroup->setEnabled(action->isChecked()); + } + + fortManager()->saveOriginConf(QString(), true); +} + +void TrayIcon::addHotKey(QAction *action, const QString &shortcutText) +{ + if (shortcutText.isEmpty()) + return; + + const QKeySequence shortcut = QKeySequence::fromString(shortcutText); + hotKeyManager()->addAction(action, shortcut); +} + +void TrayIcon::updateHotKeys() +{ + hotKeyManager()->setEnabled(settings()->hotKeyEnabled()); +} + +void TrayIcon::removeHotKeys() +{ + hotKeyManager()->removeActions(); +} + +FortManager *TrayIcon::fortManager() const +{ + return ctrl()->fortManager(); +} + +FortSettings *TrayIcon::settings() const +{ + return ctrl()->settings(); +} + +FirewallConf *TrayIcon::conf() const +{ + return ctrl()->conf(); +} + +HotKeyManager *TrayIcon::hotKeyManager() const +{ + return ctrl()->hotKeyManager(); +} diff --git a/src/ui/form/tray/trayicon.h b/src/ui/form/tray/trayicon.h new file mode 100644 index 00000000..6b337bbd --- /dev/null +++ b/src/ui/form/tray/trayicon.h @@ -0,0 +1,70 @@ +#ifndef TRAYICON_H +#define TRAYICON_H + +#include + +QT_FORWARD_DECLARE_CLASS(QAction) +QT_FORWARD_DECLARE_CLASS(QMouseEvent) + +class FirewallConf; +class FortManager; +class FortSettings; +class HotKeyManager; +class TrayController; + +class TrayIcon : public QSystemTrayIcon +{ + Q_OBJECT + +public: + explicit TrayIcon(FortManager *fortManager, QObject *parent = nullptr); + +public slots: + void updateTrayIcon(bool alerted = false); + + void showTrayMenu(QMouseEvent *event); + void updateTrayMenu(bool onlyFlags = false); + void updateTrayMenuFlags(); + +protected slots: + void retranslateTrayMenu(); + + void onRetranslateUi(); + + void saveTrayFlags(); + +private: + void setupController(); + + void setupUi(); + void setupTrayMenu(); + + void updateAppGroupActions(); + + void addHotKey(QAction *action, const QString &shortcutText); + void updateHotKeys(); + void removeHotKeys(); + + TrayController *ctrl() const { return m_ctrl; } + FortManager *fortManager() const; + FortSettings *settings() const; + FirewallConf *conf() const; + HotKeyManager *hotKeyManager() const; + +private: + QAction *m_programsAction = nullptr; + QAction *m_optionsAction = nullptr; + QAction *m_zonesAction = nullptr; + QAction *m_graphWindowAction = nullptr; + QAction *m_connectionsAction = nullptr; + QAction *m_filterEnabledAction = nullptr; + QAction *m_stopTrafficAction = nullptr; + QAction *m_stopInetTrafficAction = nullptr; + QAction *m_allowAllNewAction = nullptr; + QAction *m_quitAction = nullptr; + QList m_appGroupActions; + + TrayController *m_ctrl = nullptr; +}; + +#endif // TRAYICON_H diff --git a/src/ui/fortmanager.cpp b/src/ui/fortmanager.cpp index 90cf1498..3d040d68 100644 --- a/src/ui/fortmanager.cpp +++ b/src/ui/fortmanager.cpp @@ -1,19 +1,14 @@ #include "fortmanager.h" #include -#include #include #include #include -#include #include -#include #include #include -#include "conf/addressgroup.h" -#include "conf/appgroup.h" #include "conf/confmanager.h" #include "conf/firewallconf.h" #include "driver/drivermanager.h" @@ -23,6 +18,7 @@ #include "form/graph/graphwindow.h" #include "form/opt/optionswindow.h" #include "form/prog/programswindow.h" +#include "form/tray/trayicon.h" #include "form/zone/zoneswindow.h" #include "fortsettings.h" #include "log/logmanager.h" @@ -43,9 +39,7 @@ #include "util/dateutil.h" #include "util/envmanager.h" #include "util/fileutil.h" -#include "util/guiutil.h" #include "util/hotkeymanager.h" -#include "util/iconcache.h" #include "util/logger.h" #include "util/nativeeventfilter.h" #include "util/net/hostinfocache.h" @@ -297,24 +291,14 @@ void FortManager::setupHotKeyManager() void FortManager::setupTrayIcon() { - m_trayIcon = new QSystemTrayIcon(this); - m_trayIcon->setToolTip(QGuiApplication::applicationDisplayName()); + m_trayIcon = new TrayIcon(this); connect(m_trayIcon, &QSystemTrayIcon::activated, this, &FortManager::onTrayActivated); connect(m_trayIcon, &QSystemTrayIcon::messageClicked, this, &FortManager::onTrayMessageClicked); - connect(this, &FortManager::optWindowChanged, this, &FortManager::updateTrayMenuFlags); - connect(settings(), &FortSettings::passwordUnlockChanged, this, - &FortManager::updateTrayMenuFlags); - - connect(confManager(), &ConfManager::confSaved, this, &FortManager::updateTrayMenu); - connect(confManager(), &ConfManager::alertedAppAdded, this, [&] { updateTrayIcon(true); }); - - connect(TranslationManager::instance(), &TranslationManager::languageChanged, this, - &FortManager::retranslateTrayMenu); - - updateTrayIcon(); - updateTrayMenu(); + connect(confManager(), &ConfManager::confSaved, m_trayIcon, &TrayIcon::updateTrayMenu); + connect(confManager(), &ConfManager::alertedAppAdded, m_trayIcon, + [&] { m_trayIcon->updateTrayIcon(true); }); } void FortManager::setupProgramsWindow() @@ -324,7 +308,8 @@ void FortManager::setupProgramsWindow() m_progWindowState = new WidgetWindowStateWatcher(this); m_progWindowState->install(m_progWindow); - connect(m_progWindow, &ProgramsWindow::activationChanged, this, [&] { updateTrayIcon(false); }); + connect(m_progWindow, &ProgramsWindow::activationChanged, m_trayIcon, + [&] { m_trayIcon->updateTrayIcon(false); }); } void FortManager::setupOptionsWindow() @@ -351,7 +336,7 @@ void FortManager::setupGraphWindow() m_graphWindowState->install(m_graphWindow); connect(m_graphWindow, &GraphWindow::aboutToClose, this, [&] { closeGraphWindow(); }); - connect(m_graphWindow, &GraphWindow::mouseRightClick, this, &FortManager::showTrayMenu); + connect(m_graphWindow, &GraphWindow::mouseRightClick, m_trayIcon, &TrayIcon::showTrayMenu); connect(m_statManager, &StatManager::trafficAdded, m_graphWindow, &GraphWindow::addTraffic); } @@ -403,15 +388,6 @@ void FortManager::showTrayMessage(const QString &message, FortManager::TrayMessa m_trayIcon->showMessage(QGuiApplication::applicationDisplayName(), message); } -void FortManager::showTrayMenu(QMouseEvent *event) -{ - QMenu *menu = m_trayIcon->contextMenu(); - if (!menu) - return; - - menu->popup(mouseEventGlobalPos(event)); -} - void FortManager::showProgramsWindow() { if (!(m_progWindow && m_progWindow->isVisible()) && !checkPassword()) @@ -464,7 +440,7 @@ void FortManager::showOptionsWindow() setupOptionsWindow(); restoreOptWindowState(); - emit optWindowChanged(); + emit optWindowChanged(true); } m_optWindow->show(); @@ -486,7 +462,7 @@ void FortManager::closeOptionsWindow() confManager()->setConfToEdit(nullptr); - emit optWindowChanged(); + emit optWindowChanged(false); } void FortManager::showZonesWindow() @@ -525,7 +501,7 @@ void FortManager::showGraphWindow() m_graphWindow->show(); - m_graphWindowAction->setChecked(true); + emit graphWindowChanged(true); restoreGraphWindowState(); } @@ -544,7 +520,7 @@ void FortManager::closeGraphWindow(bool storeVisibility) m_graphWindow->deleteLater(); m_graphWindow = nullptr; - m_graphWindowAction->setChecked(false); + emit graphWindowChanged(false); } void FortManager::switchGraphWindow() @@ -680,7 +656,11 @@ bool FortManager::saveOriginConf(const QString &message, bool onlyFlags) return false; closeOptionsWindow(); - showTrayMessage(message); + + if (!message.isEmpty()) { + showTrayMessage(message); + } + return true; } @@ -761,23 +741,6 @@ void FortManager::updateStatManager(FirewallConf *conf) m_statManager->setFirewallConf(conf); } -void FortManager::saveTrayFlags() -{ - conf()->setFilterEnabled(m_filterEnabledAction->isChecked()); - conf()->setStopTraffic(m_stopTrafficAction->isChecked()); - conf()->setStopInetTraffic(m_stopInetTrafficAction->isChecked()); - conf()->setAllowAllNew(m_allowAllNewAction->isChecked()); - - int i = 0; - for (AppGroup *appGroup : conf()->appGroups()) { - const QAction *action = m_appGroupActions.at(i); - appGroup->setEnabled(action->isChecked()); - ++i; - } - - saveConf(conf(), true); -} - void FortManager::saveProgWindowState() { settings()->setProgWindowGeometry(m_progWindowState->geometry()); @@ -855,138 +818,6 @@ void FortManager::restoreConnWindowState() emit afterRestoreConnWindowState(); } -void FortManager::updateTrayIcon(bool alerted) -{ - if (!m_trayIcon) - return; - - const auto icon = alerted - ? GuiUtil::overlayIcon(":/images/sheild-96.png", ":/icons/sign-warning.png") - : IconCache::icon(":/images/sheild-96.png"); - - m_trayIcon->setIcon(icon); -} - -void FortManager::updateTrayMenu(bool onlyFlags) -{ - QMenu *oldMenu = m_trayIcon->contextMenu(); - if (oldMenu && !onlyFlags) { - oldMenu->deleteLater(); - oldMenu = nullptr; - - removeHotKeys(); - } - - if (!oldMenu) { - createTrayMenu(); - retranslateTrayMenu(); - } - - updateTrayMenuFlags(); - updateHotKeys(); -} - -void FortManager::createTrayMenu() -{ - QMenu *menu = new QMenu(m_mainWindow); - - m_programsAction = addAction(menu, IconCache::icon(":/icons/window.png"), QString(), this, - SLOT(showProgramsWindow())); - addHotKey(m_programsAction, settings()->hotKeyPrograms()); - - m_optionsAction = addAction( - menu, IconCache::icon(":/icons/cog.png"), QString(), this, SLOT(showOptionsWindow())); - addHotKey(m_optionsAction, settings()->hotKeyOptions()); - - m_zonesAction = addAction(menu, IconCache::icon(":/icons/map-map-marker.png"), QString(), this, - SLOT(showZonesWindow())); - addHotKey(m_zonesAction, settings()->hotKeyZones()); - - m_graphWindowAction = addAction(menu, IconCache::icon(":/icons/line-graph.png"), QString(), - this, SLOT(switchGraphWindow()), true, (m_graphWindow != nullptr)); - addHotKey(m_graphWindowAction, settings()->hotKeyGraph()); - - m_connectionsAction = addAction(menu, IconCache::icon(":/icons/connect.png"), QString(), this, - SLOT(showConnectionsWindow())); - addHotKey(m_connectionsAction, settings()->hotKeyConnections()); - - menu->addSeparator(); - - m_filterEnabledAction = addAction(menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true); - addHotKey(m_filterEnabledAction, settings()->hotKeyFilter()); - - m_stopTrafficAction = addAction(menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true); - addHotKey(m_stopTrafficAction, settings()->hotKeyStopTraffic()); - - m_stopInetTrafficAction = - addAction(menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true); - addHotKey(m_stopInetTrafficAction, settings()->hotKeyStopInetTraffic()); - - m_allowAllNewAction = addAction(menu, QIcon(), QString(), this, SLOT(saveTrayFlags()), true); - addHotKey(m_allowAllNewAction, settings()->hotKeyAllowAllNew()); - - menu->addSeparator(); - - m_appGroupActions.clear(); - int appGroupIndex = 0; - for (const AppGroup *appGroup : conf()->appGroups()) { - QAction *a = - addAction(menu, QIcon(), appGroup->menuLabel(), this, SLOT(saveTrayFlags()), true); - - const QString shortcutText = - settings()->hotKeyAppGroupModifiers() + "+F" + QString::number(++appGroupIndex); - - addHotKey(a, shortcutText); - - m_appGroupActions.append(a); - } - - menu->addSeparator(); - m_quitAction = addAction(menu, QIcon(), tr("Quit"), this, SLOT(quitByCheckPassword())); - addHotKey(m_quitAction, settings()->hotKeyQuit()); - - m_trayIcon->setContextMenu(menu); -} - -void FortManager::updateTrayMenuFlags() -{ - const bool editEnabled = (!settings()->isPasswordRequired() && !m_optWindow); - - m_filterEnabledAction->setEnabled(editEnabled); - m_stopTrafficAction->setEnabled(editEnabled); - m_stopInetTrafficAction->setEnabled(editEnabled); - m_allowAllNewAction->setEnabled(editEnabled); - - m_filterEnabledAction->setChecked(conf()->filterEnabled()); - m_stopTrafficAction->setChecked(conf()->stopTraffic()); - m_stopInetTrafficAction->setChecked(conf()->stopInetTraffic()); - m_allowAllNewAction->setChecked(conf()->allowAllNew()); - - int appGroupIndex = 0; - for (QAction *action : qAsConst(m_appGroupActions)) { - const auto appGroup = conf()->appGroups().at(appGroupIndex++); - - action->setEnabled(editEnabled); - action->setChecked(appGroup->enabled()); - } -} - -void FortManager::retranslateTrayMenu() -{ - m_programsAction->setText(tr("Programs")); - m_optionsAction->setText(tr("Options")); - m_zonesAction->setText(tr("Zones")); - m_graphWindowAction->setText(tr("Traffic Graph")); - m_connectionsAction->setText(tr("Connections")); - - m_filterEnabledAction->setText(tr("Filter Enabled")); - m_stopTrafficAction->setText(tr("Stop Traffic")); - m_stopInetTrafficAction->setText(tr("Stop Internet Traffic")); - m_allowAllNewAction->setText(tr("Auto-Allow New Programs")); - - m_quitAction->setText(tr("Quit")); -} - void FortManager::onTrayActivated(int reason) { switch (reason) { @@ -1024,55 +855,8 @@ void FortManager::onTrayMessageClicked() } } -void FortManager::addHotKey(QAction *action, const QString &shortcutText) -{ - if (shortcutText.isEmpty()) - return; - - const QKeySequence shortcut = QKeySequence::fromString(shortcutText); - m_hotKeyManager->addAction(action, shortcut); -} - -void FortManager::updateHotKeys() -{ - m_hotKeyManager->setEnabled(settings()->hotKeyEnabled()); -} - -void FortManager::removeHotKeys() -{ - m_hotKeyManager->removeActions(); -} - -QWidget *FortManager::focusWidget() +QWidget *FortManager::focusWidget() const { auto w = QApplication::focusWidget(); return w ? w : m_mainWindow; } - -QAction *FortManager::addAction(QWidget *widget, const QIcon &icon, const QString &text, - const QObject *receiver, const char *member, bool checkable, bool checked) -{ - auto action = new QAction(icon, text, widget); - - if (receiver) { - connect(action, SIGNAL(triggered(bool)), receiver, member); - } - if (checkable) { - setActionCheckable(action, checked); - } - - widget->addAction(action); - - return action; -} - -void FortManager::setActionCheckable( - QAction *action, bool checked, const QObject *receiver, const char *member) -{ - action->setCheckable(true); - action->setChecked(checked); - - if (receiver) { - connect(action, SIGNAL(toggled(bool)), receiver, member); - } -} diff --git a/src/ui/fortmanager.h b/src/ui/fortmanager.h index d6b5b0ea..3b6ed937 100644 --- a/src/ui/fortmanager.h +++ b/src/ui/fortmanager.h @@ -5,10 +5,6 @@ #include "util/classhelpers.h" -QT_FORWARD_DECLARE_CLASS(QAction) -QT_FORWARD_DECLARE_CLASS(QMouseEvent) -QT_FORWARD_DECLARE_CLASS(QSystemTrayIcon) - class AppInfoCache; class AppListModel; class AppStatModel; @@ -30,6 +26,7 @@ class ProgramsWindow; class QuotaManager; class StatManager; class TaskManager; +class TrayIcon; class WidgetWindowStateWatcher; class ZoneListModel; class ZonesWindow; @@ -50,6 +47,15 @@ public: void initialize(); + MainWindow *mainWindow() const { return m_mainWindow; } + HotKeyManager *hotKeyManager() const { return m_hotKeyManager; } + + ProgramsWindow *progWindow() const { return m_progWindow; } + OptionsWindow *optWindow() const { return m_optWindow; } + ZonesWindow *zoneWindow() const { return m_zoneWindow; } + GraphWindow *graphWindow() const { return m_graphWindow; } + ConnectionsWindow *connWindow() const { return m_connWindow; } + FirewallConf *conf() const; FirewallConf *confToEdit() const; @@ -65,7 +71,8 @@ public: ConnListModel *connListModel() const { return m_connListModel; } signals: - void optWindowChanged(); + void optWindowChanged(bool visible); + void graphWindowChanged(bool visible); void afterSaveProgWindowState(); void afterRestoreProgWindowState(); @@ -88,7 +95,6 @@ public slots: void showTrayIcon(); void showTrayMessage( const QString &message, FortManager::TrayMessageType type = MessageOptions); - void showTrayMenu(QMouseEvent *event); void showProgramsWindow(); void closeProgramsWindow(); @@ -126,9 +132,6 @@ public slots: bool applyConf(bool onlyFlags = false); bool applyConfImmediateFlags(); -private slots: - void saveTrayFlags(); - private: void setupTranslationManager(); @@ -189,27 +192,10 @@ private: void saveConnWindowState(); void restoreConnWindowState(); - void updateTrayIcon(bool alerted = false); - - void updateTrayMenu(bool onlyFlags = false); - void createTrayMenu(); - void updateTrayMenuFlags(); - void retranslateTrayMenu(); - void onTrayActivated(int reason); void onTrayMessageClicked(); - void addHotKey(QAction *action, const QString &shortcutText); - void updateHotKeys(); - void removeHotKeys(); - - QWidget *focusWidget(); - - static QAction *addAction(QWidget *widget, const QIcon &icon, const QString &text, - const QObject *receiver = nullptr, const char *member = nullptr, bool checkable = false, - bool checked = false); - static void setActionCheckable(QAction *action, bool checked = false, - const QObject *receiver = nullptr, const char *member = nullptr); + QWidget *focusWidget() const; private: bool m_trayTriggered : 1; @@ -220,7 +206,10 @@ private: MainWindow *m_mainWindow = nullptr; // dummy window for tray icon - QSystemTrayIcon *m_trayIcon = nullptr; + NativeEventFilter *m_nativeEventFilter = nullptr; + HotKeyManager *m_hotKeyManager = nullptr; + + TrayIcon *m_trayIcon = nullptr; ProgramsWindow *m_progWindow = nullptr; WidgetWindowStateWatcher *m_progWindowState = nullptr; @@ -237,21 +226,6 @@ private: ConnectionsWindow *m_connWindow = nullptr; WidgetWindowStateWatcher *m_connWindowState = nullptr; - NativeEventFilter *m_nativeEventFilter = nullptr; - HotKeyManager *m_hotKeyManager = nullptr; - - QAction *m_programsAction = nullptr; - QAction *m_optionsAction = nullptr; - QAction *m_zonesAction = nullptr; - QAction *m_graphWindowAction = nullptr; - QAction *m_connectionsAction = nullptr; - QAction *m_filterEnabledAction = nullptr; - QAction *m_stopTrafficAction = nullptr; - QAction *m_stopInetTrafficAction = nullptr; - QAction *m_allowAllNewAction = nullptr; - QAction *m_quitAction = nullptr; - QList m_appGroupActions; - FortSettings *m_settings = nullptr; EnvManager *m_envManager = nullptr; QuotaManager *m_quotaManager = nullptr;