diff --git a/src/ui/conf/firewallconf.cpp b/src/ui/conf/firewallconf.cpp index 96094b8f..0f83e973 100644 --- a/src/ui/conf/firewallconf.cpp +++ b/src/ui/conf/firewallconf.cpp @@ -101,6 +101,37 @@ void FirewallConf::setAppAllowAll(bool appAllowAll) m_appAllowAll = appAllowAll; } +int FirewallConf::filterModeIndex() const +{ + return m_appBlockAll ? 0 : (m_appAllowAll ? 1 : 2); +} + +void FirewallConf::setFilterModeIndex(int index) +{ + m_appBlockAll = false; + m_appAllowAll = false; + + switch (index) { + case 0: { + m_appBlockAll = true; + } break; + case 1: { + m_appAllowAll = true; + } break; + } +} + +QStringList FirewallConf::filterModeNames() +{ + return { tr("Block, if not allowed"), tr("Allow, if not blocked"), + tr("Ignore, if not blocked or allowed") }; +} + +QStringList FirewallConf::filterModeIconPaths() +{ + return { ":/icons/deny.png", ":/icons/accept.png", ":/icons/error.png" }; +} + void FirewallConf::setActivePeriodEnabled(bool activePeriodEnabled) { m_activePeriodEnabled = activePeriodEnabled; diff --git a/src/ui/conf/firewallconf.h b/src/ui/conf/firewallconf.h index 58ebc1dc..f82d40ab 100644 --- a/src/ui/conf/firewallconf.h +++ b/src/ui/conf/firewallconf.h @@ -81,6 +81,12 @@ public: bool appAllowAll() const { return m_appAllowAll; } void setAppAllowAll(bool appAllowAll); + int filterModeIndex() const; + void setFilterModeIndex(int index); + + static QStringList filterModeNames(); + static QStringList filterModeIconPaths(); + bool activePeriodEnabled() const { return m_activePeriodEnabled; } void setActivePeriodEnabled(bool activePeriodEnabled); diff --git a/src/ui/form/opt/pages/applicationspage.cpp b/src/ui/form/opt/pages/applicationspage.cpp index 48a17314..bdee00cf 100644 --- a/src/ui/form/opt/pages/applicationspage.cpp +++ b/src/ui/form/opt/pages/applicationspage.cpp @@ -76,9 +76,6 @@ void ApplicationsPage::onRetranslateUi() m_btAddGroup->setText(tr("Add Group")); m_btRenameGroup->setText(tr("Rename Group")); - m_cbBlockAll->setText(tr("Block All")); - m_cbAllowAll->setText(tr("Allow All")); - m_btGroupOptions->setText(tr("Options")); m_cbApplyChild->setText(tr("Apply same rules to child processes")); @@ -177,14 +174,10 @@ QLayout *ApplicationsPage::setupHeader() setupAddGroup(); setupRenameGroup(); - setupBlockAllowAll(); - layout->addWidget(m_editGroupName); layout->addWidget(m_btAddGroup); layout->addWidget(m_btRenameGroup); layout->addStretch(); - layout->addWidget(m_cbBlockAll); - layout->addWidget(m_cbAllowAll); return layout; } @@ -239,34 +232,6 @@ void ApplicationsPage::setupRenameGroup() }); } -void ApplicationsPage::setupBlockAllowAll() -{ - m_cbBlockAll = ControlUtil::createCheckBox(conf()->appBlockAll(), [&](bool checked) { - conf()->setAppBlockAll(checked); - ctrl()->setFlagsEdited(); - }); - m_cbBlockAll->setIcon(IconCache::icon(":/icons/deny.png")); - - m_cbAllowAll = ControlUtil::createCheckBox(conf()->appAllowAll(), [&](bool checked) { - conf()->setAppAllowAll(checked); - ctrl()->setFlagsEdited(); - }); - m_cbAllowAll->setIcon(IconCache::icon(":/icons/accept.png")); - - const auto refreshBlockAllowAllEnabled = [&] { - const bool blockAll = m_cbBlockAll->isChecked(); - const bool allowAll = m_cbAllowAll->isChecked(); - - m_cbBlockAll->setEnabled(blockAll || !allowAll); - m_cbAllowAll->setEnabled(!blockAll || allowAll); - }; - - refreshBlockAllowAllEnabled(); - - connect(m_cbBlockAll, &QCheckBox::toggled, this, refreshBlockAllowAllEnabled); - connect(m_cbAllowAll, &QCheckBox::toggled, this, refreshBlockAllowAllEnabled); -} - void ApplicationsPage::setupTabBar() { m_tabBar = new TabBar(); diff --git a/src/ui/form/opt/pages/applicationspage.h b/src/ui/form/opt/pages/applicationspage.h index 8b340923..37e18cde 100644 --- a/src/ui/form/opt/pages/applicationspage.h +++ b/src/ui/form/opt/pages/applicationspage.h @@ -39,7 +39,6 @@ private: QLayout *setupHeader(); void setupAddGroup(); void setupRenameGroup(); - void setupBlockAllowAll(); void setupTabBar(); int addTab(const QString &text); QLayout *setupGroupHeader(); @@ -75,8 +74,6 @@ private: QLineEdit *m_editGroupName = nullptr; QPushButton *m_btAddGroup = nullptr; QPushButton *m_btRenameGroup = nullptr; - QCheckBox *m_cbBlockAll = nullptr; - QCheckBox *m_cbAllowAll = nullptr; TabBar *m_tabBar = nullptr; QCheckBox *m_cbGroupEnabled = nullptr; CheckTimePeriod *m_ctpGroupPeriod = nullptr; diff --git a/src/ui/form/opt/pages/optionspage.cpp b/src/ui/form/opt/pages/optionspage.cpp index 87f6bfb4..90079de5 100644 --- a/src/ui/form/opt/pages/optionspage.cpp +++ b/src/ui/form/opt/pages/optionspage.cpp @@ -170,6 +170,9 @@ void OptionsPage::onRetranslateUi() m_cbStopInetTraffic->setText(tr("Stop Internet Traffic")); m_cbAllowAllNew->setText(tr("Auto-Allow New Programs")); + m_labelFilterMode->setText(tr("Filter Mode:")); + retranslateComboFilterMode(); + m_cbExplorerMenu->setText(tr("Windows Explorer integration")); m_cbHotKeys->setText(tr("Hot Keys")); @@ -238,6 +241,22 @@ void OptionsPage::retranslateComboStartMode() } } +void OptionsPage::retranslateComboFilterMode() +{ + int index = 0; + const QStringList iconPaths = FirewallConf::filterModeIconPaths(); + for (const QString &name : FirewallConf::filterModeNames()) { + const QString iconPath = iconPaths.at(index); + + m_comboFilterMode->setItemText(index, name); + m_comboFilterMode->setItemIcon(index, IconCache::icon(iconPath)); + + ++index; + } + + m_comboFilterMode->setCurrentIndex(conf()->filterModeIndex()); +} + void OptionsPage::retranslateEditPassword() { m_editPassword->setPlaceholderText( @@ -400,17 +419,36 @@ void OptionsPage::setupTrafficBox() ctrl()->setFlagsEdited(); }); + auto filterModeLayout = setupFilterModeLayout(); + auto layout = new QVBoxLayout(); layout->addWidget(m_cbFilterEnabled); layout->addWidget(m_cbFilterLocals); layout->addWidget(m_cbStopTraffic); layout->addWidget(m_cbStopInetTraffic); layout->addWidget(m_cbAllowAllNew); + layout->addLayout(filterModeLayout); m_gbTraffic = new QGroupBox(this); m_gbTraffic->setLayout(layout); } +QLayout *OptionsPage::setupFilterModeLayout() +{ + m_labelFilterMode = ControlUtil::createLabel(); + + m_comboFilterMode = + ControlUtil::createComboBox(FirewallConf::filterModeNames(), [&](int index) { + if (conf()->filterModeIndex() != index) { + conf()->setFilterModeIndex(index); + ctrl()->emitEdited(); + } + }); + m_comboFilterMode->setFixedWidth(200); + + return ControlUtil::createRowLayout(m_labelFilterMode, m_comboFilterMode); +} + void OptionsPage::setupGlobalBox() { m_cbExplorerMenu = ControlUtil::createCheckBox(ini()->explorerIntegrated(), [&](bool checked) { diff --git a/src/ui/form/opt/pages/optionspage.h b/src/ui/form/opt/pages/optionspage.h index 5b45d2dc..f60248b2 100644 --- a/src/ui/form/opt/pages/optionspage.h +++ b/src/ui/form/opt/pages/optionspage.h @@ -24,6 +24,7 @@ private: void saveService(bool isService); void retranslateComboStartMode(); + void retranslateComboFilterMode(); void retranslateEditPassword(); void retranslateComboTrayEvent(); void retranslateComboTrayAction(); @@ -36,6 +37,7 @@ private: void setupStartupBox(); QLayout *setupStartModeLayout(); void setupTrafficBox(); + QLayout *setupFilterModeLayout(); void setupGlobalBox(); QLayout *setupPasswordLayout(); void setupEditPassword(); @@ -76,6 +78,8 @@ private: QCheckBox *m_cbStopTraffic = nullptr; QCheckBox *m_cbStopInetTraffic = nullptr; QCheckBox *m_cbAllowAllNew = nullptr; + QLabel *m_labelFilterMode = nullptr; + QComboBox *m_comboFilterMode = nullptr; QCheckBox *m_cbExplorerMenu = nullptr; QCheckBox *m_cbHotKeys = nullptr; QCheckBox *m_cbPassword = nullptr; diff --git a/src/ui/form/tray/trayicon.cpp b/src/ui/form/tray/trayicon.cpp index cc73a358..47f468c7 100644 --- a/src/ui/form/tray/trayicon.cpp +++ b/src/ui/form/tray/trayicon.cpp @@ -1,5 +1,6 @@ #include "trayicon.h" +#include #include #include #include @@ -287,9 +288,21 @@ void TrayIcon::retranslateUi() m_stopInetTrafficAction->setText(tr("Stop Internet Traffic")); m_autoAllowProgsAction->setText(tr("Auto-Allow New Programs")); + m_filterModeMenu->setTitle(tr("Filter Mode")); + retranslateFilterModeActions(); + m_quitAction->setText(tr("Quit")); } +void TrayIcon::retranslateFilterModeActions() +{ + int index = 0; + for (const QString &name : FirewallConf::filterModeNames()) { + QAction *a = m_filterModeActions->actions().at(index++); + a->setText(name); + } +} + void TrayIcon::setupUi() { this->setToolTip(QApplication::applicationDisplayName()); @@ -344,10 +357,14 @@ void TrayIcon::setupTrayMenu() addAction(m_menu, QIcon(), QString(), this, SLOT(switchTrayFlag(bool)), true); addHotKey(m_autoAllowProgsAction, iniUser()->hotKeyAllowAllNew()); + setupTrayMenuFilterMode(); + m_menu->addMenu(m_filterModeMenu); + m_menu->addSeparator(); for (int i = 0; i < MAX_APP_GROUP_COUNT; ++i) { - QAction *a = addAction(m_menu, QIcon(), QString(), this, SLOT(switchTrayFlag(bool)), true); + QAction *a = addAction( + m_menu, QIcon(), QString(), this, SLOT(switchTrayFlag(bool)), /*checkable=*/true); if (i < 12) { const QString shortcutText = @@ -365,20 +382,47 @@ void TrayIcon::setupTrayMenu() addHotKey(m_quitAction, iniUser()->hotKeyQuit()); } +void TrayIcon::setupTrayMenuFilterMode() +{ + m_filterModeMenu = new QMenu(m_menu); + + m_filterModeActions = new QActionGroup(m_filterModeMenu); + + int index = 0; + const QStringList iconPaths = FirewallConf::filterModeIconPaths(); + for (const QString &name : FirewallConf::filterModeNames()) { + const QString iconPath = iconPaths.at(index); + + QAction *a = addAction(m_filterModeMenu, IconCache::icon(iconPath), name, + /*receiver=*/nullptr, + /*member=*/nullptr, /*checkable=*/true); + + m_filterModeActions->addAction(a); + ++index; + } + + connect(m_filterModeActions, &QActionGroup::triggered, this, &TrayIcon::switchFilterMode); +} + void TrayIcon::updateTrayMenuFlags() { const bool editEnabled = (!settings()->isPasswordRequired() && !windowManager()->optWindow()); m_filterEnabledAction->setEnabled(editEnabled); - m_stopTrafficAction->setEnabled(editEnabled); - m_stopInetTrafficAction->setEnabled(editEnabled); - m_autoAllowProgsAction->setEnabled(editEnabled); - m_filterEnabledAction->setChecked(conf()->filterEnabled()); + + m_stopTrafficAction->setEnabled(editEnabled); m_stopTrafficAction->setChecked(conf()->stopTraffic()); + + m_stopInetTrafficAction->setEnabled(editEnabled); m_stopInetTrafficAction->setChecked(conf()->stopInetTraffic()); + + m_autoAllowProgsAction->setEnabled(editEnabled); m_autoAllowProgsAction->setChecked(conf()->allowAllNew()); + m_filterModeMenu->setEnabled(editEnabled); + m_filterModeActions->actions().at(conf()->filterModeIndex())->setChecked(true); + int appGroupIndex = 0; for (QAction *action : qAsConst(m_appGroupActions)) { if (!action->isVisible()) @@ -418,6 +462,8 @@ void TrayIcon::saveTrayFlags() conf()->setStopTraffic(m_stopTrafficAction->isChecked()); conf()->setStopInetTraffic(m_stopInetTrafficAction->isChecked()); conf()->setAllowAllNew(m_autoAllowProgsAction->isChecked()); + conf()->setFilterModeIndex( + m_filterModeActions->actions().indexOf(m_filterModeActions->checkedAction())); int i = 0; for (AppGroup *appGroup : conf()->appGroups()) { @@ -444,6 +490,23 @@ void TrayIcon::switchTrayFlag(bool checked) saveTrayFlags(); } +void TrayIcon::switchFilterMode(QAction *action) +{ + const int index = m_filterModeActions->actions().indexOf(action); + if (index < 0 || index == conf()->filterModeIndex()) + return; + + if (iniUser()->confirmTrayFlags() + && !windowManager()->showQuestionBox( + tr("Are you sure to select the \"%1\"?").arg(action->text()))) { + action = m_filterModeActions->actions().at(conf()->filterModeIndex()); + action->setChecked(true); + return; + } + + saveTrayFlags(); +} + void TrayIcon::quitProgram() { if (iniUser()->confirmQuit()) { diff --git a/src/ui/form/tray/trayicon.h b/src/ui/form/tray/trayicon.h index 378ec420..1a1aab44 100644 --- a/src/ui/form/tray/trayicon.h +++ b/src/ui/form/tray/trayicon.h @@ -4,6 +4,7 @@ #include QT_FORWARD_DECLARE_CLASS(QAction) +QT_FORWARD_DECLARE_CLASS(QActionGroup) class ConfManager; class FirewallConf; @@ -60,15 +61,18 @@ protected slots: void saveTrayFlags(); void switchTrayFlag(bool checked); + void switchFilterMode(QAction *action); void quitProgram(); private: void setupController(); void retranslateUi(); + void retranslateFilterModeActions(); void setupUi(); void setupTrayMenu(); + void setupTrayMenuFilterMode(); void updateTrayMenuFlags(); void updateAppGroupActions(); @@ -97,6 +101,8 @@ private: QAction *m_stopTrafficAction = nullptr; QAction *m_stopInetTrafficAction = nullptr; QAction *m_autoAllowProgsAction = nullptr; + QMenu *m_filterModeMenu = nullptr; + QActionGroup *m_filterModeActions = nullptr; QAction *m_quitAction = nullptr; QList m_appGroupActions;