From 6d7e22b1da9db5f69701e295e2abebfed6785890 Mon Sep 17 00:00:00 2001 From: Nodir Temirkhodjaev Date: Tue, 18 May 2021 17:42:23 +0300 Subject: [PATCH] UI: Options: Move Statistics page to Statistics window as Traffic page. --- src/ui/FortFirewallUI.pro | 16 +- src/ui/form/controls/controlutil.cpp | 1 + src/ui/form/opt/optionswindow.cpp | 4 +- src/ui/form/opt/optionswindow.h | 4 +- src/ui/form/opt/pages/addressespage.cpp | 2 +- src/ui/form/opt/pages/addressespage.h | 4 +- src/ui/form/opt/pages/applicationspage.cpp | 2 +- src/ui/form/opt/pages/applicationspage.h | 4 +- src/ui/form/opt/pages/basepage.cpp | 88 --- src/ui/form/opt/pages/optbasepage.cpp | 89 +++ .../opt/pages/{basepage.h => optbasepage.h} | 10 +- src/ui/form/opt/pages/optionspage.cpp | 8 +- src/ui/form/opt/pages/optionspage.h | 4 +- .../pages/{mainpage.cpp => optmainpage.cpp} | 22 +- .../opt/pages/{mainpage.h => optmainpage.h} | 12 +- src/ui/form/opt/pages/rulespage.cpp | 2 +- src/ui/form/opt/pages/rulespage.h | 4 +- src/ui/form/opt/pages/schedulepage.cpp | 2 +- src/ui/form/opt/pages/schedulepage.h | 4 +- src/ui/form/opt/pages/statisticspage.cpp | 742 +++++------------- src/ui/form/opt/pages/statisticspage.h | 99 +-- src/ui/form/stat/pages/connectionspage.cpp | 327 ++++++++ src/ui/form/stat/pages/connectionspage.h | 73 ++ src/ui/form/stat/pages/statbasepage.cpp | 56 ++ src/ui/form/stat/pages/statbasepage.h | 53 ++ src/ui/form/stat/pages/statmainpage.cpp | 46 ++ src/ui/form/stat/pages/statmainpage.h | 26 + src/ui/form/stat/pages/trafficpage.cpp | 319 ++++++++ src/ui/form/stat/pages/trafficpage.h | 68 ++ src/ui/form/stat/statisticscontroller.h | 3 + src/ui/form/stat/statisticswindow.cpp | 325 +------- src/ui/form/stat/statisticswindow.h | 50 +- src/ui/user/iniuser.h | 6 +- src/ui/user/usersettings.cpp | 5 +- 34 files changed, 1375 insertions(+), 1105 deletions(-) delete mode 100644 src/ui/form/opt/pages/basepage.cpp create mode 100644 src/ui/form/opt/pages/optbasepage.cpp rename src/ui/form/opt/pages/{basepage.h => optbasepage.h} (89%) rename src/ui/form/opt/pages/{mainpage.cpp => optmainpage.cpp} (86%) rename src/ui/form/opt/pages/{mainpage.h => optmainpage.h} (71%) create mode 100644 src/ui/form/stat/pages/connectionspage.cpp create mode 100644 src/ui/form/stat/pages/connectionspage.h create mode 100644 src/ui/form/stat/pages/statbasepage.cpp create mode 100644 src/ui/form/stat/pages/statbasepage.h create mode 100644 src/ui/form/stat/pages/statmainpage.cpp create mode 100644 src/ui/form/stat/pages/statmainpage.h create mode 100644 src/ui/form/stat/pages/trafficpage.cpp create mode 100644 src/ui/form/stat/pages/trafficpage.h diff --git a/src/ui/FortFirewallUI.pro b/src/ui/FortFirewallUI.pro index 7944d212..f7e970de 100644 --- a/src/ui/FortFirewallUI.pro +++ b/src/ui/FortFirewallUI.pro @@ -51,15 +51,19 @@ SOURCES += \ form/opt/pages/addressespage.cpp \ form/opt/pages/applicationspage.cpp \ form/opt/pages/apps/appscolumn.cpp \ - form/opt/pages/basepage.cpp \ - form/opt/pages/mainpage.cpp \ + form/opt/pages/optbasepage.cpp \ form/opt/pages/optionspage.cpp \ + form/opt/pages/optmainpage.cpp \ form/opt/pages/rulespage.cpp \ form/opt/pages/schedulepage.cpp \ form/opt/pages/statisticspage.cpp \ form/prog/programeditdialog.cpp \ form/prog/programscontroller.cpp \ form/prog/programswindow.cpp \ + form/stat/pages/connectionspage.cpp \ + form/stat/pages/statbasepage.cpp \ + form/stat/pages/statmainpage.cpp \ + form/stat/pages/trafficpage.cpp \ form/stat/statisticscontroller.cpp \ form/stat/statisticswindow.cpp \ form/tray/traycontroller.cpp \ @@ -191,15 +195,19 @@ HEADERS += \ form/opt/pages/addressespage.h \ form/opt/pages/applicationspage.h \ form/opt/pages/apps/appscolumn.h \ - form/opt/pages/basepage.h \ - form/opt/pages/mainpage.h \ + form/opt/pages/optbasepage.h \ form/opt/pages/optionspage.h \ + form/opt/pages/optmainpage.h \ form/opt/pages/rulespage.h \ form/opt/pages/schedulepage.h \ form/opt/pages/statisticspage.h \ form/prog/programeditdialog.h \ form/prog/programscontroller.h \ form/prog/programswindow.h \ + form/stat/pages/connectionspage.h \ + form/stat/pages/statbasepage.h \ + form/stat/pages/statmainpage.h \ + form/stat/pages/trafficpage.h \ form/stat/statisticscontroller.h \ form/stat/statisticswindow.h \ form/tray/traycontroller.h \ diff --git a/src/ui/form/controls/controlutil.cpp b/src/ui/form/controls/controlutil.cpp index ccdee2fb..e3524a38 100644 --- a/src/ui/form/controls/controlutil.cpp +++ b/src/ui/form/controls/controlutil.cpp @@ -142,6 +142,7 @@ QBoxLayout *ControlUtil::createLayoutByWidgets(const QList &widgets, { auto layout = new QBoxLayout(o == Qt::Vertical ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight); + for (auto w : widgets) { if (!w) { layout->addStretch(); diff --git a/src/ui/form/opt/optionswindow.cpp b/src/ui/form/opt/optionswindow.cpp index 124680d3..df27ecd4 100644 --- a/src/ui/form/opt/optionswindow.cpp +++ b/src/ui/form/opt/optionswindow.cpp @@ -9,7 +9,7 @@ #include "../../util/guiutil.h" #include "../../util/window/widgetwindowstatewatcher.h" #include "optionscontroller.h" -#include "pages/mainpage.h" +#include "pages/optmainpage.h" OptionsWindow::OptionsWindow(FortManager *fortManager, QWidget *parent) : WidgetWindow(parent), @@ -109,7 +109,7 @@ void OptionsWindow::setupUi() auto layout = new QVBoxLayout(); layout->setContentsMargins(0, 0, 0, 0); - m_mainPage = new MainPage(ctrl()); + m_mainPage = new OptMainPage(ctrl()); layout->addWidget(m_mainPage); this->setLayout(layout); diff --git a/src/ui/form/opt/optionswindow.h b/src/ui/form/opt/optionswindow.h index 5b99f33d..f2190d03 100644 --- a/src/ui/form/opt/optionswindow.h +++ b/src/ui/form/opt/optionswindow.h @@ -8,7 +8,7 @@ class FirewallConf; class FortManager; class IniOptions; class IniUser; -class MainPage; +class OptMainPage; class OptionsController; class WidgetWindowStateWatcher; @@ -45,7 +45,7 @@ private: OptionsController *m_ctrl = nullptr; WidgetWindowStateWatcher *m_stateWatcher = nullptr; - MainPage *m_mainPage = nullptr; + OptMainPage *m_mainPage = nullptr; }; #endif // OPTIONSWINDOW_H diff --git a/src/ui/form/opt/pages/addressespage.cpp b/src/ui/form/opt/pages/addressespage.cpp index 42d93db1..fda733d4 100644 --- a/src/ui/form/opt/pages/addressespage.cpp +++ b/src/ui/form/opt/pages/addressespage.cpp @@ -28,7 +28,7 @@ #include "../optionscontroller.h" #include "addresses/addressescolumn.h" -AddressesPage::AddressesPage(OptionsController *ctrl, QWidget *parent) : BasePage(ctrl, parent) +AddressesPage::AddressesPage(OptionsController *ctrl, QWidget *parent) : OptBasePage(ctrl, parent) { setupUi(); diff --git a/src/ui/form/opt/pages/addressespage.h b/src/ui/form/opt/pages/addressespage.h index 9c188b02..dca7552b 100644 --- a/src/ui/form/opt/pages/addressespage.h +++ b/src/ui/form/opt/pages/addressespage.h @@ -1,13 +1,13 @@ #ifndef ADDRESSESPAGE_H #define ADDRESSESPAGE_H -#include "basepage.h" +#include "optbasepage.h" class AddressGroup; class AddressesColumn; class TextArea2Splitter; -class AddressesPage : public BasePage +class AddressesPage : public OptBasePage { Q_OBJECT diff --git a/src/ui/form/opt/pages/applicationspage.cpp b/src/ui/form/opt/pages/applicationspage.cpp index 93cf05e6..5b214214 100644 --- a/src/ui/form/opt/pages/applicationspage.cpp +++ b/src/ui/form/opt/pages/applicationspage.cpp @@ -37,7 +37,7 @@ const ValuesList speedLimitValues = { 10, 0, 20, 30, 50, 75, 100, 150, 200, 300, } ApplicationsPage::ApplicationsPage(OptionsController *ctrl, QWidget *parent) : - BasePage(ctrl, parent) + OptBasePage(ctrl, parent) { setupUi(); diff --git a/src/ui/form/opt/pages/applicationspage.h b/src/ui/form/opt/pages/applicationspage.h index b36a15cf..9a661e0b 100644 --- a/src/ui/form/opt/pages/applicationspage.h +++ b/src/ui/form/opt/pages/applicationspage.h @@ -1,7 +1,7 @@ #ifndef APPLICATIONSPAGE_H #define APPLICATIONSPAGE_H -#include "basepage.h" +#include "optbasepage.h" class AppGroup; class AppsColumn; @@ -10,7 +10,7 @@ class CheckTimePeriod; class TabBar; class TextArea2Splitter; -class ApplicationsPage : public BasePage +class ApplicationsPage : public OptBasePage { Q_OBJECT diff --git a/src/ui/form/opt/pages/basepage.cpp b/src/ui/form/opt/pages/basepage.cpp deleted file mode 100644 index aafd3feb..00000000 --- a/src/ui/form/opt/pages/basepage.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "basepage.h" - -#include - -#include "../../../conf/firewallconf.h" -#include "../../../fortmanager.h" -#include "../../../user/iniuser.h" -#include "../../../util/osutil.h" -#include "../optionscontroller.h" - -BasePage::BasePage(OptionsController *ctrl, QWidget *parent) : QFrame(parent), m_ctrl(ctrl) -{ - setupController(); -} - -FortManager *BasePage::fortManager() const -{ - return ctrl()->fortManager(); -} - -FortSettings *BasePage::settings() const -{ - return ctrl()->settings(); -} - -ConfManager *BasePage::confManager() const -{ - return ctrl()->confManager(); -} - -FirewallConf *BasePage::conf() const -{ - return ctrl()->conf(); -} - -IniOptions *BasePage::ini() const -{ - return &conf()->ini(); -} - -IniUser *BasePage::iniUser() const -{ - return ctrl()->iniUser(); -} - -DriverManager *BasePage::driverManager() const -{ - return ctrl()->driverManager(); -} - -TranslationManager *BasePage::translationManager() const -{ - return ctrl()->translationManager(); -} - -TaskManager *BasePage::taskManager() const -{ - return ctrl()->taskManager(); -} - -ZoneListModel *BasePage::zoneListModel() const -{ - return ctrl()->zoneListModel(); -} - -void BasePage::setupController() -{ - Q_ASSERT(ctrl()); - - connect(ctrl(), &OptionsController::aboutToSave, this, &BasePage::onAboutToSave); - connect(ctrl(), &OptionsController::editResetted, this, &BasePage::onEditResetted); - - connect(ctrl(), &OptionsController::cancelChanges, this, &BasePage::onCancelChanges); - - connect(ctrl(), &OptionsController::afterSaveWindowState, this, &BasePage::onSaveWindowState); - connect(ctrl(), &OptionsController::afterRestoreWindowState, this, - &BasePage::onRestoreWindowState); - - connect(ctrl(), &OptionsController::retranslateUi, this, &BasePage::onRetranslateUi); -} - -void BasePage::onLinkClicked() -{ - auto button = qobject_cast(sender()); - if (button) { - OsUtil::openUrlOrFolder(button->windowFilePath()); - } -} diff --git a/src/ui/form/opt/pages/optbasepage.cpp b/src/ui/form/opt/pages/optbasepage.cpp new file mode 100644 index 00000000..adbe46c3 --- /dev/null +++ b/src/ui/form/opt/pages/optbasepage.cpp @@ -0,0 +1,89 @@ +#include "optbasepage.h" + +#include + +#include "../../../conf/firewallconf.h" +#include "../../../fortmanager.h" +#include "../../../user/iniuser.h" +#include "../../../util/osutil.h" +#include "../optionscontroller.h" + +OptBasePage::OptBasePage(OptionsController *ctrl, QWidget *parent) : QFrame(parent), m_ctrl(ctrl) +{ + setupController(); +} + +FortManager *OptBasePage::fortManager() const +{ + return ctrl()->fortManager(); +} + +FortSettings *OptBasePage::settings() const +{ + return ctrl()->settings(); +} + +ConfManager *OptBasePage::confManager() const +{ + return ctrl()->confManager(); +} + +FirewallConf *OptBasePage::conf() const +{ + return ctrl()->conf(); +} + +IniOptions *OptBasePage::ini() const +{ + return &conf()->ini(); +} + +IniUser *OptBasePage::iniUser() const +{ + return ctrl()->iniUser(); +} + +DriverManager *OptBasePage::driverManager() const +{ + return ctrl()->driverManager(); +} + +TranslationManager *OptBasePage::translationManager() const +{ + return ctrl()->translationManager(); +} + +TaskManager *OptBasePage::taskManager() const +{ + return ctrl()->taskManager(); +} + +ZoneListModel *OptBasePage::zoneListModel() const +{ + return ctrl()->zoneListModel(); +} + +void OptBasePage::setupController() +{ + Q_ASSERT(ctrl()); + + connect(ctrl(), &OptionsController::aboutToSave, this, &OptBasePage::onAboutToSave); + connect(ctrl(), &OptionsController::editResetted, this, &OptBasePage::onEditResetted); + + connect(ctrl(), &OptionsController::cancelChanges, this, &OptBasePage::onCancelChanges); + + connect(ctrl(), &OptionsController::afterSaveWindowState, this, + &OptBasePage::onSaveWindowState); + connect(ctrl(), &OptionsController::afterRestoreWindowState, this, + &OptBasePage::onRestoreWindowState); + + connect(ctrl(), &OptionsController::retranslateUi, this, &OptBasePage::onRetranslateUi); +} + +void OptBasePage::onLinkClicked() +{ + auto button = qobject_cast(sender()); + if (button) { + OsUtil::openUrlOrFolder(button->windowFilePath()); + } +} diff --git a/src/ui/form/opt/pages/basepage.h b/src/ui/form/opt/pages/optbasepage.h similarity index 89% rename from src/ui/form/opt/pages/basepage.h rename to src/ui/form/opt/pages/optbasepage.h index 4960f570..7b8b3df4 100644 --- a/src/ui/form/opt/pages/basepage.h +++ b/src/ui/form/opt/pages/optbasepage.h @@ -1,5 +1,5 @@ -#ifndef BASEPAGE_H -#define BASEPAGE_H +#ifndef OPTBASEPAGE_H +#define OPTBASEPAGE_H #include #include @@ -26,12 +26,12 @@ class TaskManager; class TranslationManager; class ZoneListModel; -class BasePage : public QFrame +class OptBasePage : public QFrame { Q_OBJECT public: - explicit BasePage(OptionsController *ctrl, QWidget *parent = nullptr); + explicit OptBasePage(OptionsController *ctrl, QWidget *parent = nullptr); protected: OptionsController *ctrl() const { return m_ctrl; } @@ -66,4 +66,4 @@ private: OptionsController *m_ctrl = nullptr; }; -#endif // BASEPAGE_H +#endif // OPTBASEPAGE_H diff --git a/src/ui/form/opt/pages/optionspage.cpp b/src/ui/form/opt/pages/optionspage.cpp index 50336b54..5aef664d 100644 --- a/src/ui/form/opt/pages/optionspage.cpp +++ b/src/ui/form/opt/pages/optionspage.cpp @@ -58,7 +58,7 @@ void moveProfile(const QString &profilePath, const QString &newProfilePath) } -OptionsPage::OptionsPage(OptionsController *ctrl, QWidget *parent) : BasePage(ctrl, parent) +OptionsPage::OptionsPage(OptionsController *ctrl, QWidget *parent) : OptBasePage(ctrl, parent) { setupStartup(); setupUi(); @@ -489,13 +489,15 @@ QLayout *OptionsPage::setupColumn2() auto layout = new QVBoxLayout(); layout->setSpacing(10); + // Driver Group Box setupDriverBox(); + layout->addWidget(m_gbDriver); + // New Version Group Box setupNewVersionBox(); setupNewVersionUpdate(); - - layout->addWidget(m_gbDriver); layout->addWidget(m_gbNewVersion); + layout->addStretch(); return layout; diff --git a/src/ui/form/opt/pages/optionspage.h b/src/ui/form/opt/pages/optionspage.h index b9e47e76..f1a32e50 100644 --- a/src/ui/form/opt/pages/optionspage.h +++ b/src/ui/form/opt/pages/optionspage.h @@ -1,9 +1,9 @@ #ifndef OPTIONSPAGE_H #define OPTIONSPAGE_H -#include "basepage.h" +#include "optbasepage.h" -class OptionsPage : public BasePage +class OptionsPage : public OptBasePage { Q_OBJECT diff --git a/src/ui/form/opt/pages/mainpage.cpp b/src/ui/form/opt/pages/optmainpage.cpp similarity index 86% rename from src/ui/form/opt/pages/mainpage.cpp rename to src/ui/form/opt/pages/optmainpage.cpp index 236b6ad5..716271d9 100644 --- a/src/ui/form/opt/pages/mainpage.cpp +++ b/src/ui/form/opt/pages/optmainpage.cpp @@ -1,4 +1,4 @@ -#include "mainpage.h" +#include "optmainpage.h" #include #include @@ -20,12 +20,12 @@ #include "schedulepage.h" #include "statisticspage.h" -MainPage::MainPage(OptionsController *ctrl, QWidget *parent) : BasePage(ctrl, parent) +OptMainPage::OptMainPage(OptionsController *ctrl, QWidget *parent) : OptBasePage(ctrl, parent) { setupUi(); } -void MainPage::onRetranslateUi() +void OptMainPage::onRetranslateUi() { m_tabBar->setTabText(0, tr("Options")); m_tabBar->setTabText(1, tr("IPv4 Addresses")); @@ -44,7 +44,7 @@ void MainPage::onRetranslateUi() m_btCancel->setText(tr("Cancel")); } -void MainPage::setupUi() +void OptMainPage::setupUi() { auto layout = new QVBoxLayout(); layout->setContentsMargins(6, 6, 6, 6); @@ -60,7 +60,7 @@ void MainPage::setupUi() this->setLayout(layout); } -void MainPage::setupTabBar() +void OptMainPage::setupTabBar() { auto optionsPage = ControlUtil::wrapToScrollArea(new OptionsPage(ctrl())); auto addressesPage = new AddressesPage(ctrl()); @@ -82,7 +82,7 @@ void MainPage::setupTabBar() #endif } -QLayout *MainPage::setupDialogButtons() +QLayout *OptMainPage::setupDialogButtons() { auto buttonsLayout = new QHBoxLayout(); @@ -92,10 +92,10 @@ QLayout *MainPage::setupDialogButtons() m_btStat = ControlUtil::createLinkButton(":/icons/folder-open.png", settings()->statPath()); m_btReleases = ControlUtil::createLinkButton(":/icons/github.png", APP_UPDATES_URL); - connect(m_btLogs, &QAbstractButton::clicked, this, &MainPage::onLinkClicked); - connect(m_btProfile, &QAbstractButton::clicked, this, &MainPage::onLinkClicked); - connect(m_btStat, &QAbstractButton::clicked, this, &MainPage::onLinkClicked); - connect(m_btReleases, &QAbstractButton::clicked, this, &MainPage::onLinkClicked); + connect(m_btLogs, &QAbstractButton::clicked, this, &OptMainPage::onLinkClicked); + connect(m_btProfile, &QAbstractButton::clicked, this, &OptMainPage::onLinkClicked); + connect(m_btStat, &QAbstractButton::clicked, this, &OptMainPage::onLinkClicked); + connect(m_btReleases, &QAbstractButton::clicked, this, &OptMainPage::onLinkClicked); buttonsLayout->addWidget(m_btLogs); buttonsLayout->addWidget(m_btProfile); @@ -121,7 +121,7 @@ QLayout *MainPage::setupDialogButtons() return buttonsLayout; } -void MainPage::setupOkApplyButtons() +void OptMainPage::setupOkApplyButtons() { const auto refreshOkApplyButtons = [&](bool anyEdited) { m_btOk->setEnabled(anyEdited); diff --git a/src/ui/form/opt/pages/mainpage.h b/src/ui/form/opt/pages/optmainpage.h similarity index 71% rename from src/ui/form/opt/pages/mainpage.h rename to src/ui/form/opt/pages/optmainpage.h index cf6f112f..b3418f55 100644 --- a/src/ui/form/opt/pages/mainpage.h +++ b/src/ui/form/opt/pages/optmainpage.h @@ -1,16 +1,16 @@ -#ifndef MAINPAGE_H -#define MAINPAGE_H +#ifndef OPTMAINPAGE_H +#define OPTMAINPAGE_H -#include "basepage.h" +#include "optbasepage.h" QT_FORWARD_DECLARE_CLASS(QTabWidget) -class MainPage : public BasePage +class OptMainPage : public OptBasePage { Q_OBJECT public: - explicit MainPage(OptionsController *ctrl = nullptr, QWidget *parent = nullptr); + explicit OptMainPage(OptionsController *ctrl = nullptr, QWidget *parent = nullptr); protected slots: void onRetranslateUi() override; @@ -34,4 +34,4 @@ private: QPushButton *m_btCancel = nullptr; }; -#endif // MAINPAGE_H +#endif // OPTMAINPAGE_H diff --git a/src/ui/form/opt/pages/rulespage.cpp b/src/ui/form/opt/pages/rulespage.cpp index 76aeac0f..7ad179c6 100644 --- a/src/ui/form/opt/pages/rulespage.cpp +++ b/src/ui/form/opt/pages/rulespage.cpp @@ -1,6 +1,6 @@ #include "rulespage.h" -RulesPage::RulesPage(OptionsController *ctrl, QWidget *parent) : BasePage(ctrl, parent) +RulesPage::RulesPage(OptionsController *ctrl, QWidget *parent) : OptBasePage(ctrl, parent) { setupUi(); } diff --git a/src/ui/form/opt/pages/rulespage.h b/src/ui/form/opt/pages/rulespage.h index cfffb914..1ac44dc6 100644 --- a/src/ui/form/opt/pages/rulespage.h +++ b/src/ui/form/opt/pages/rulespage.h @@ -1,9 +1,9 @@ #ifndef RULESPAGE_H #define RULESPAGE_H -#include "basepage.h" +#include "optbasepage.h" -class RulesPage : public BasePage +class RulesPage : public OptBasePage { Q_OBJECT diff --git a/src/ui/form/opt/pages/schedulepage.cpp b/src/ui/form/opt/pages/schedulepage.cpp index 23c1dc7c..20e30a0b 100644 --- a/src/ui/form/opt/pages/schedulepage.cpp +++ b/src/ui/form/opt/pages/schedulepage.cpp @@ -25,7 +25,7 @@ const ValuesList taskIntervalHourValues = { 3, 1, 6, 12, 24, 24 * 7, 24 * 30 }; } SchedulePage::SchedulePage(OptionsController *ctrl, QWidget *parent) : - BasePage(ctrl, parent), m_taskListModel(new TaskListModel(taskManager(), this)) + OptBasePage(ctrl, parent), m_taskListModel(new TaskListModel(taskManager(), this)) { setupUi(); } diff --git a/src/ui/form/opt/pages/schedulepage.h b/src/ui/form/opt/pages/schedulepage.h index 42f9d432..e642496e 100644 --- a/src/ui/form/opt/pages/schedulepage.h +++ b/src/ui/form/opt/pages/schedulepage.h @@ -1,7 +1,7 @@ #ifndef SCHEDULEPAGE_H #define SCHEDULEPAGE_H -#include "basepage.h" +#include "optbasepage.h" QT_FORWARD_DECLARE_CLASS(QTableView) @@ -10,7 +10,7 @@ class TableView; class TaskInfo; class TaskListModel; -class SchedulePage : public BasePage +class SchedulePage : public OptBasePage { Q_OBJECT diff --git a/src/ui/form/opt/pages/statisticspage.cpp b/src/ui/form/opt/pages/statisticspage.cpp index c99a6daa..b7dde577 100644 --- a/src/ui/form/opt/pages/statisticspage.cpp +++ b/src/ui/form/opt/pages/statisticspage.cpp @@ -1,38 +1,21 @@ #include "statisticspage.h" -#include #include -#include +#include #include -#include #include -#include -#include -#include #include -#include -#include -#include #include #include -#include "../../../appinfo/appinfocache.h" -#include "../../../conf/confmanager.h" #include "../../../conf/firewallconf.h" -#include "../../../fortmanager.h" -#include "../../../fortsettings.h" -#include "../../../model/appstatmodel.h" -#include "../../../model/traflistmodel.h" -#include "../../../user/iniuser.h" #include "../../../util/iconcache.h" #include "../../../util/net/netutil.h" -#include "../../controls/appinforow.h" #include "../../controls/checktimeperiod.h" #include "../../controls/controlutil.h" #include "../../controls/labelcolor.h" #include "../../controls/labelspin.h" #include "../../controls/labelspincombo.h" -#include "../../controls/listview.h" #include "../optionscontroller.h" namespace { @@ -44,54 +27,54 @@ const ValuesList logIpKeepCountValues = { 3000, 1000, 5000, 10000, 50000, 100000 const ValuesList quotaValues = { 10, 0, 100, 500, 1024, 8 * 1024, 10 * 1024, 30 * 1024, 50 * 1024, 100 * 1024 }; +LabelSpinCombo *createSpinCombo( + int v, int min, int max, const ValuesList &values = {}, const QString &suffix = {}) +{ + auto c = new LabelSpinCombo(); + c->spinBox()->setValue(v); + c->spinBox()->setRange(min, max); + c->spinBox()->setSuffix(suffix); + c->setValues(values); + return c; } -StatisticsPage::StatisticsPage(OptionsController *ctrl, QWidget *parent) : - BasePage(ctrl, parent), m_isPageUpdating(false) +LabelSpin *createSpin(int v, int min, int max, const QString &suffix = {}) { - setupTrafListModel(); + auto c = new LabelSpin(); + c->spinBox()->setValue(v); + c->spinBox()->setRange(min, max); + c->spinBox()->setSuffix(suffix); + return c; +} +LabelColor *createLabelColor( + const QColor &v, const std::function &onColorChanged) +{ + auto c = new LabelColor(); + c->setColor(v); + + c->connect(c, &LabelColor::colorChanged, onColorChanged); + + return c; +} + +QString formatQuota(int mbytes) +{ + return NetUtil::formatDataSize1(qint64(mbytes) * 1024 * 1024); +} + +} + +StatisticsPage::StatisticsPage(OptionsController *ctrl, QWidget *parent) : OptBasePage(ctrl, parent) +{ setupUi(); - updatePage(); -} - -AppStatModel *StatisticsPage::appStatModel() const -{ - return fortManager()->appStatModel(); -} - -AppInfoCache *StatisticsPage::appInfoCache() const -{ - return appStatModel()->appInfoCache(); -} - -void StatisticsPage::setIniEdited() -{ - if (!m_isPageUpdating) { - ctrl()->setIniEdited(); - } -} - -void StatisticsPage::onSaveWindowState(IniUser *ini) -{ - ini->setOptWindowStatSplit(m_splitter->saveState()); -} - -void StatisticsPage::onRestoreWindowState(IniUser *ini) -{ - m_splitter->restoreState(ini->optWindowStatSplit()); } void StatisticsPage::onRetranslateUi() { - m_btRefresh->setText(tr("Refresh")); - m_btClear->setText(tr("Clear")); + m_gbTraffic->setTitle(tr("Traffic")); + m_gbGraph->setTitle(tr("Graph")); - m_actRemoveApp->setText(tr("Remove Application")); - m_actResetTotal->setText(tr("Reset Total")); - m_actClearAll->setText(tr("Clear All")); - - m_btTrafOptions->setText(tr("Options")); m_cbLogStat->setText(tr("Collect Traffic Statistics")); m_cbLogStatNoFilter->setText(tr("Collect Traffic, when Filter Disabled")); m_ctpActivePeriod->checkBox()->setText(tr("Active time period:")); @@ -115,7 +98,6 @@ void StatisticsPage::onRetranslateUi() retranslateQuotaNames(); retranslateIpKeepCountNames(); - m_btGraphOptions->setText(tr("Graph")); m_cbGraphAlwaysOnTop->setText(tr("Always on top")); m_cbGraphFrameless->setText(tr("Frameless")); m_cbGraphClickThrough->setText(tr("Click through")); @@ -130,13 +112,6 @@ void StatisticsPage::onRetranslateUi() m_graphTickLabelColor->label()->setText(tr("Tick label:")); m_graphLabelColor->label()->setText(tr("Label:")); m_graphGridColor->label()->setText(tr("Grid:")); - - m_traphUnits->setText(tr("Units:")); - retranslateTrafUnitNames(); - - retranslateTabBar(); - - m_appInfoRow->retranslateUi(); } void StatisticsPage::retranslateTrafKeepDayNames() @@ -183,283 +158,39 @@ void StatisticsPage::retranslateIpKeepCountNames() m_lscBlockedIpKeepCount->setNames(list); } -void StatisticsPage::retranslateTrafUnitNames() -{ - const QStringList list = { tr("Adaptive"), tr("Bytes"), "KiB", "MiB", "GiB", "TiB" }; - - m_comboTrafUnit->clear(); - m_comboTrafUnit->addItems(list); - - updateTrafUnit(); -} - -void StatisticsPage::retranslateTabBar() -{ - const QStringList list = { tr("Hourly"), tr("Daily"), tr("Monthly"), tr("Total") }; - - int index = 0; - for (const auto &v : list) { - m_tabBar->setTabText(index++, v); - } -} - -void StatisticsPage::setupTrafListModel() -{ - m_trafListModel = appStatModel()->trafListModel(); -} - void StatisticsPage::setupUi() { - auto layout = new QVBoxLayout(); + // Column #1 + auto colLayout1 = setupColumn1(); - // Header - auto header = setupHeader(); - layout->addLayout(header); + // Column #2 + auto colLayout2 = setupColumn2(); - // Content - m_splitter = new QSplitter(); - - setupAppListView(); - m_splitter->addWidget(m_appListView); - - // Tab Bar - auto trafLayout = new QVBoxLayout(); - trafLayout->setContentsMargins(0, 0, 0, 0); - - setupTabBar(); - trafLayout->addWidget(m_tabBar); - - // Traf Table - setupTableTraf(); - setupTableTrafHeader(); - trafLayout->addWidget(m_tableTraf); - - auto trafWidget = new QWidget(); - trafWidget->setLayout(trafLayout); - m_splitter->addWidget(trafWidget); - - layout->addWidget(m_splitter, 1); - - // App Info Row - setupAppInfoRow(); - layout->addWidget(m_appInfoRow); - - // Actions on app list view's current changed - setupAppListViewChanged(); + // Main layout + auto layout = new QHBoxLayout(); + layout->addLayout(colLayout1); + layout->addStretch(); + layout->addLayout(colLayout2); + layout->addStretch(); this->setLayout(layout); } -QLayout *StatisticsPage::setupHeader() +QLayout *StatisticsPage::setupColumn1() { - auto layout = new QHBoxLayout(); + auto layout = new QVBoxLayout(); + layout->setSpacing(10); - m_btRefresh = - ControlUtil::createButton(":/icons/sign-sync.png", [&] { trafListModel()->reset(); }); + // Traffic Group Box + setupTrafficBox(); + layout->addWidget(m_gbTraffic); - setupClearMenu(); - setupTrafUnits(); - setupGraphOptionsMenu(); - setupTrafOptionsMenu(); - - layout->addWidget(m_btRefresh); - layout->addWidget(m_btClear); - layout->addWidget(ControlUtil::createSeparator(Qt::Vertical)); - layout->addWidget(m_traphUnits); - layout->addWidget(m_comboTrafUnit); layout->addStretch(); - layout->addWidget(m_btGraphOptions); - layout->addWidget(m_btTrafOptions); return layout; } -void StatisticsPage::setupClearMenu() -{ - auto menu = new QMenu(this); - - m_actRemoveApp = menu->addAction(IconCache::icon(":/icons/sign-delete.png"), QString()); - m_actRemoveApp->setShortcut(Qt::Key_Delete); - - m_actResetTotal = menu->addAction(QString()); - m_actClearAll = menu->addAction(QString()); - - connect(m_actRemoveApp, &QAction::triggered, this, [&] { - if (!fortManager()->showQuestionBox( - tr("Are you sure to remove statistics for selected application?"))) - return; - - appStatModel()->remove(appListCurrentIndex()); - }); - connect(m_actResetTotal, &QAction::triggered, this, [&] { - if (!fortManager()->showQuestionBox(tr("Are you sure to reset total statistics?"))) - return; - - trafListModel()->resetAppTotals(); - }); - connect(m_actClearAll, &QAction::triggered, this, [&] { - if (!fortManager()->showQuestionBox(tr("Are you sure to clear all statistics?"))) - return; - - m_appListView->clearSelection(); - appStatModel()->clear(); - }); - - m_btClear = ControlUtil::createButton(":/icons/trashcan-full.png"); - m_btClear->setMenu(menu); -} - -void StatisticsPage::setupTrafUnits() -{ - m_traphUnits = ControlUtil::createLabel(); - - m_comboTrafUnit = ControlUtil::createComboBox(QStringList(), [&](int index) { - if (iniUser()->statTrafUnit() == index) - return; - - iniUser()->setStatTrafUnit(index); - updateTableTrafUnit(); - - confManager()->saveIniUser(); - }); -} - -void StatisticsPage::setupGraphOptionsMenu() -{ - setupGraphCheckboxes(); - setupGraphOptions(); - setupGraphColors(); - - // Menu - auto colLayout1 = ControlUtil::createLayoutByWidgets({ m_cbGraphAlwaysOnTop, m_cbGraphFrameless, - m_cbGraphClickThrough, m_cbGraphHideOnHover, ControlUtil::createSeparator(), - m_graphOpacity, m_graphHoverOpacity, m_graphMaxSeconds, nullptr }); - auto colLayout2 = - ControlUtil::createLayoutByWidgets({ m_graphColor, m_graphColorIn, m_graphColorOut, - m_graphAxisColor, m_graphTickLabelColor, m_graphLabelColor, m_graphGridColor }); - auto layout = new QHBoxLayout(); - layout->addLayout(colLayout1); - layout->addWidget(ControlUtil::createSeparator(Qt::Vertical)); - layout->addLayout(colLayout2); - - auto menu = ControlUtil::createMenuByLayout(layout, this); - - m_btGraphOptions = ControlUtil::createButton(":/icons/line-graph.png"); - m_btGraphOptions->setMenu(menu); -} - -void StatisticsPage::setupGraphCheckboxes() -{ - m_cbGraphAlwaysOnTop = ControlUtil::createCheckBox(false, [&](bool checked) { - if (ini()->graphWindowAlwaysOnTop() != checked) { - ini()->setGraphWindowAlwaysOnTop(checked); - setIniEdited(); - } - }); - m_cbGraphFrameless = ControlUtil::createCheckBox(false, [&](bool checked) { - if (ini()->graphWindowFrameless() != checked) { - ini()->setGraphWindowFrameless(checked); - setIniEdited(); - } - }); - m_cbGraphClickThrough = ControlUtil::createCheckBox(false, [&](bool checked) { - if (ini()->graphWindowClickThrough() != checked) { - ini()->setGraphWindowClickThrough(checked); - setIniEdited(); - } - }); - m_cbGraphHideOnHover = ControlUtil::createCheckBox(false, [&](bool checked) { - if (ini()->graphWindowHideOnHover() != checked) { - ini()->setGraphWindowHideOnHover(checked); - setIniEdited(); - } - }); -} - -void StatisticsPage::setupGraphOptions() -{ - m_graphOpacity = createSpin(0, 100, " %"); - m_graphHoverOpacity = createSpin(0, 100, " %"); - m_graphMaxSeconds = createSpin(0, 9999); - - connect(m_graphOpacity->spinBox(), QOverload::of(&QSpinBox::valueChanged), this, - [&](int v) { - if (ini()->graphWindowOpacity() != v) { - ini()->setGraphWindowOpacity(v); - setIniEdited(); - } - }); - connect(m_graphHoverOpacity->spinBox(), QOverload::of(&QSpinBox::valueChanged), this, - [&](int v) { - if (ini()->graphWindowHoverOpacity() != v) { - ini()->setGraphWindowHoverOpacity(v); - setIniEdited(); - } - }); - connect(m_graphMaxSeconds->spinBox(), QOverload::of(&QSpinBox::valueChanged), this, - [&](int v) { - if (ini()->graphWindowMaxSeconds() != v) { - ini()->setGraphWindowMaxSeconds(v); - setIniEdited(); - } - }); -} - -void StatisticsPage::setupGraphColors() -{ - m_graphColor = new LabelColor(); - m_graphColorIn = new LabelColor(); - m_graphColorOut = new LabelColor(); - m_graphAxisColor = new LabelColor(); - m_graphTickLabelColor = new LabelColor(); - m_graphLabelColor = new LabelColor(); - m_graphGridColor = new LabelColor(); - - connect(m_graphColor, &LabelColor::colorChanged, this, [&](const QColor &v) { - if (ini()->graphWindowColor() != v) { - ini()->setGraphWindowColor(v); - setIniEdited(); - } - }); - connect(m_graphColorIn, &LabelColor::colorChanged, this, [&](const QColor &v) { - if (ini()->graphWindowColorIn() != v) { - ini()->setGraphWindowColorIn(v); - setIniEdited(); - } - }); - connect(m_graphColorOut, &LabelColor::colorChanged, this, [&](const QColor &v) { - if (ini()->graphWindowColorOut() != v) { - ini()->setGraphWindowColorOut(v); - setIniEdited(); - } - }); - connect(m_graphAxisColor, &LabelColor::colorChanged, this, [&](const QColor &v) { - if (ini()->graphWindowAxisColor() != v) { - ini()->setGraphWindowAxisColor(v); - setIniEdited(); - } - }); - connect(m_graphTickLabelColor, &LabelColor::colorChanged, this, [&](const QColor &v) { - if (ini()->graphWindowTickLabelColor() != v) { - ini()->setGraphWindowTickLabelColor(v); - setIniEdited(); - } - }); - connect(m_graphLabelColor, &LabelColor::colorChanged, this, [&](const QColor &v) { - if (ini()->graphWindowLabelColor() != v) { - ini()->setGraphWindowLabelColor(v); - setIniEdited(); - } - }); - connect(m_graphGridColor, &LabelColor::colorChanged, this, [&](const QColor &v) { - if (ini()->graphWindowGridColor() != v) { - ini()->setGraphWindowGridColor(v); - setIniEdited(); - } - }); -} - -void StatisticsPage::setupTrafOptionsMenu() +void StatisticsPage::setupTrafficBox() { setupLogStat(); setupLogStatNoFilter(); @@ -473,23 +204,20 @@ void StatisticsPage::setupTrafOptionsMenu() setupAllowedIpKeepCount(); setupBlockedIpKeepCount(); - // Menu - const QList menuWidgets = { m_cbLogStat, m_cbLogStatNoFilter, m_ctpActivePeriod, - m_lscMonthStart, ControlUtil::createSeparator(), m_lscTrafHourKeepDays, - m_lscTrafDayKeepDays, m_lscTrafMonthKeepMonths, ControlUtil::createSeparator(), - m_lscQuotaDayMb, m_lscQuotaMonthMb, ControlUtil::createSeparator(), m_lscAllowedIpKeepCount, - m_lscBlockedIpKeepCount }; - auto layout = ControlUtil::createLayoutByWidgets(menuWidgets); + // Layout + auto layout = ControlUtil::createLayoutByWidgets({ m_cbLogStat, m_cbLogStatNoFilter, + m_ctpActivePeriod, m_lscMonthStart, ControlUtil::createSeparator(), + m_lscTrafHourKeepDays, m_lscTrafDayKeepDays, m_lscTrafMonthKeepMonths, + ControlUtil::createSeparator(), m_lscQuotaDayMb, m_lscQuotaMonthMb, + ControlUtil::createSeparator(), m_lscAllowedIpKeepCount, m_lscBlockedIpKeepCount }); - auto menu = ControlUtil::createMenuByLayout(layout, this); - - m_btTrafOptions = ControlUtil::createButton(":/icons/wrench.png"); - m_btTrafOptions->setMenu(menu); + m_gbTraffic = new QGroupBox(this); + m_gbTraffic->setLayout(layout); } void StatisticsPage::setupLogStat() { - m_cbLogStat = ControlUtil::createCheckBox(false, [&](bool checked) { + m_cbLogStat = ControlUtil::createCheckBox(conf()->logStat(), [&](bool checked) { if (conf()->logStat() == checked) return; @@ -503,7 +231,7 @@ void StatisticsPage::setupLogStat() void StatisticsPage::setupLogStatNoFilter() { - m_cbLogStatNoFilter = ControlUtil::createCheckBox(false, [&](bool checked) { + m_cbLogStatNoFilter = ControlUtil::createCheckBox(conf()->logStatNoFilter(), [&](bool checked) { if (conf()->logStatNoFilter() == checked) return; @@ -516,6 +244,9 @@ void StatisticsPage::setupLogStatNoFilter() void StatisticsPage::setupActivePeriod() { m_ctpActivePeriod = new CheckTimePeriod(); + m_ctpActivePeriod->checkBox()->setChecked(conf()->activePeriodEnabled()); + m_ctpActivePeriod->timeEdit1()->setTime(CheckTimePeriod::toTime(conf()->activePeriodFrom())); + m_ctpActivePeriod->timeEdit2()->setTime(CheckTimePeriod::toTime(conf()->activePeriodTo())); connect(m_ctpActivePeriod->checkBox(), &QCheckBox::toggled, this, [&](bool checked) { if (conf()->activePeriodEnabled() == checked) @@ -551,7 +282,7 @@ void StatisticsPage::setupActivePeriod() void StatisticsPage::setupMonthStart() { - m_lscMonthStart = createSpinCombo(1, 31); + m_lscMonthStart = createSpinCombo(ini()->monthStart(), 1, 31); // Days list { @@ -568,288 +299,251 @@ void StatisticsPage::setupMonthStart() [&](int value) { if (ini()->monthStart() != value) { ini()->setMonthStart(value); - setIniEdited(); + ctrl()->setIniEdited(); } }); } void StatisticsPage::setupTrafHourKeepDays() { - m_lscTrafHourKeepDays = createSpinCombo(-1, 9999); - m_lscTrafHourKeepDays->setValues(trafKeepDayValues); + m_lscTrafHourKeepDays = createSpinCombo(ini()->trafHourKeepDays(), -1, 9999, trafKeepDayValues); connect(m_lscTrafHourKeepDays->spinBox(), QOverload::of(&QSpinBox::valueChanged), this, [&](int value) { if (ini()->trafHourKeepDays() != value) { ini()->setTrafHourKeepDays(value); - setIniEdited(); + ctrl()->setIniEdited(); } }); } void StatisticsPage::setupTrafDayKeepDays() { - m_lscTrafDayKeepDays = createSpinCombo(-1, 9999); - m_lscTrafDayKeepDays->setValues(trafKeepDayValues); + m_lscTrafDayKeepDays = createSpinCombo(ini()->trafDayKeepDays(), -1, 9999, trafKeepDayValues); connect(m_lscTrafDayKeepDays->spinBox(), QOverload::of(&QSpinBox::valueChanged), this, [&](int value) { if (ini()->trafDayKeepDays() != value) { ini()->setTrafDayKeepDays(value); - setIniEdited(); + ctrl()->setIniEdited(); } }); } void StatisticsPage::setupTrafMonthKeepMonths() { - m_lscTrafMonthKeepMonths = createSpinCombo(-1, 9999); - m_lscTrafMonthKeepMonths->setValues(trafKeepMonthValues); + m_lscTrafMonthKeepMonths = + createSpinCombo(ini()->trafMonthKeepMonths(), -1, 9999, trafKeepMonthValues); connect(m_lscTrafMonthKeepMonths->spinBox(), QOverload::of(&QSpinBox::valueChanged), this, [&](int value) { if (ini()->trafMonthKeepMonths() != value) { ini()->setTrafMonthKeepMonths(value); - setIniEdited(); + ctrl()->setIniEdited(); } }); } void StatisticsPage::setupQuotaDayMb() { - m_lscQuotaDayMb = createSpinCombo(0, 1024 * 1024, " MiB"); - m_lscQuotaDayMb->setValues(quotaValues); + m_lscQuotaDayMb = + createSpinCombo(int(ini()->quotaDayMb()), 0, 1024 * 1024, quotaValues, " MiB"); connect(m_lscQuotaDayMb->spinBox(), QOverload::of(&QSpinBox::valueChanged), this, [&](int value) { const quint32 mbytes = quint32(value); if (ini()->quotaDayMb() != mbytes) { ini()->setQuotaDayMb(mbytes); - setIniEdited(); + ctrl()->setIniEdited(); } }); } void StatisticsPage::setupQuotaMonthMb() { - m_lscQuotaMonthMb = createSpinCombo(0, 1024 * 1024, " MiB"); - m_lscQuotaMonthMb->setValues(quotaValues); + m_lscQuotaMonthMb = + createSpinCombo(int(ini()->quotaMonthMb()), 0, 1024 * 1024, quotaValues, " MiB"); connect(m_lscQuotaMonthMb->spinBox(), QOverload::of(&QSpinBox::valueChanged), this, [&](int value) { const quint32 mbytes = quint32(value); if (ini()->quotaMonthMb() != mbytes) { ini()->setQuotaMonthMb(mbytes); - setIniEdited(); + ctrl()->setIniEdited(); } }); } void StatisticsPage::setupAllowedIpKeepCount() { - m_lscAllowedIpKeepCount = new LabelSpinCombo(); - m_lscAllowedIpKeepCount->spinBox()->setRange(0, 999999999); - m_lscAllowedIpKeepCount->setValues(logIpKeepCountValues); + m_lscAllowedIpKeepCount = + createSpinCombo(ini()->allowedIpKeepCount(), 0, 999999999, logIpKeepCountValues); connect(m_lscAllowedIpKeepCount->spinBox(), QOverload::of(&QSpinBox::valueChanged), this, [&](int value) { if (ini()->allowedIpKeepCount() != value) { ini()->setAllowedIpKeepCount(value); - setIniEdited(); + ctrl()->setIniEdited(); } }); } void StatisticsPage::setupBlockedIpKeepCount() { - m_lscBlockedIpKeepCount = new LabelSpinCombo(); - m_lscBlockedIpKeepCount->spinBox()->setRange(0, 999999999); - m_lscBlockedIpKeepCount->setValues(logIpKeepCountValues); + m_lscBlockedIpKeepCount = + createSpinCombo(ini()->blockedIpKeepCount(), 0, 999999999, logIpKeepCountValues); connect(m_lscBlockedIpKeepCount->spinBox(), QOverload::of(&QSpinBox::valueChanged), this, [&](int value) { if (ini()->blockedIpKeepCount() != value) { ini()->setBlockedIpKeepCount(value); - setIniEdited(); + ctrl()->setIniEdited(); } }); } -void StatisticsPage::setupAppListView() +QLayout *StatisticsPage::setupColumn2() { - m_appListView = new ListView(); - m_appListView->setFlow(QListView::TopToBottom); - m_appListView->setViewMode(QListView::ListMode); - m_appListView->setIconSize(QSize(24, 24)); - m_appListView->setUniformItemSizes(true); - m_appListView->setAlternatingRowColors(true); + auto layout = new QVBoxLayout(); + layout->setSpacing(10); - m_appListView->setModel(appStatModel()); + // Graph Group Box + setupGraphBox(); + layout->addWidget(m_gbGraph); + + layout->addStretch(); + + return layout; } -void StatisticsPage::setupTabBar() +void StatisticsPage::setupGraphBox() { - m_tabBar = new QTabBar(); - m_tabBar->setShape(QTabBar::TriangularNorth); + setupGraphCheckboxes(); + setupGraphOptions(); + setupGraphColors(); - for (int n = 4; --n >= 0;) { - m_tabBar->addTab(QString()); - } + // Layout + auto colLayout1 = ControlUtil::createLayoutByWidgets({ m_cbGraphAlwaysOnTop, m_cbGraphFrameless, + m_cbGraphClickThrough, m_cbGraphHideOnHover, ControlUtil::createSeparator(), + m_graphOpacity, m_graphHoverOpacity, m_graphMaxSeconds, nullptr }); + + auto colLayout2 = + ControlUtil::createLayoutByWidgets({ m_graphColor, m_graphColorIn, m_graphColorOut, + m_graphAxisColor, m_graphTickLabelColor, m_graphLabelColor, m_graphGridColor }); + + auto layout = new QHBoxLayout(); + layout->addLayout(colLayout1); + layout->addWidget(ControlUtil::createSeparator(Qt::Vertical)); + layout->addLayout(colLayout2); + + m_gbGraph = new QGroupBox(this); + m_gbGraph->setLayout(layout); } -void StatisticsPage::setupTableTraf() +void StatisticsPage::setupGraphCheckboxes() { - m_tableTraf = new QTableView(); - m_tableTraf->setSelectionMode(QAbstractItemView::SingleSelection); - m_tableTraf->setSelectionBehavior(QAbstractItemView::SelectItems); - - m_tableTraf->setModel(trafListModel()); - - const auto resetTableTraf = [&] { - trafListModel()->setType(static_cast(m_tabBar->currentIndex())); - trafListModel()->setAppId(appStatModel()->appIdByRow(appListCurrentIndex())); - trafListModel()->resetTraf(); - }; - - resetTableTraf(); - - connect(m_tabBar, &QTabBar::currentChanged, this, resetTableTraf); - connect(m_appListView, &ListView::currentIndexChanged, this, resetTableTraf); + m_cbGraphAlwaysOnTop = + ControlUtil::createCheckBox(ini()->graphWindowAlwaysOnTop(), [&](bool checked) { + if (ini()->graphWindowAlwaysOnTop() != checked) { + ini()->setGraphWindowAlwaysOnTop(checked); + ctrl()->setIniEdited(); + } + }); + m_cbGraphFrameless = + ControlUtil::createCheckBox(ini()->graphWindowFrameless(), [&](bool checked) { + if (ini()->graphWindowFrameless() != checked) { + ini()->setGraphWindowFrameless(checked); + ctrl()->setIniEdited(); + } + }); + m_cbGraphClickThrough = + ControlUtil::createCheckBox(ini()->graphWindowClickThrough(), [&](bool checked) { + if (ini()->graphWindowClickThrough() != checked) { + ini()->setGraphWindowClickThrough(checked); + ctrl()->setIniEdited(); + } + }); + m_cbGraphHideOnHover = + ControlUtil::createCheckBox(ini()->graphWindowHideOnHover(), [&](bool checked) { + if (ini()->graphWindowHideOnHover() != checked) { + ini()->setGraphWindowHideOnHover(checked); + ctrl()->setIniEdited(); + } + }); } -void StatisticsPage::setupTableTrafHeader() +void StatisticsPage::setupGraphOptions() { - auto header = m_tableTraf->horizontalHeader(); + m_graphOpacity = createSpin(ini()->graphWindowOpacity(), 0, 100, " %"); + m_graphHoverOpacity = createSpin(ini()->graphWindowHoverOpacity(), 0, 100, " %"); + m_graphMaxSeconds = createSpin(ini()->graphWindowMaxSeconds(), 0, 9999); - header->setSectionResizeMode(0, QHeaderView::Fixed); - header->setSectionResizeMode(1, QHeaderView::Stretch); - header->setSectionResizeMode(2, QHeaderView::Stretch); - header->setSectionResizeMode(3, QHeaderView::Stretch); - - const auto refreshTableTrafHeader = [&] { - auto hh = m_tableTraf->horizontalHeader(); - hh->resizeSection(0, qBound(150, qRound(hh->width() * 0.3), 180)); - }; - - refreshTableTrafHeader(); - - connect(header, &QHeaderView::geometriesChanged, this, refreshTableTrafHeader); + connect(m_graphOpacity->spinBox(), QOverload::of(&QSpinBox::valueChanged), this, + [&](int v) { + if (ini()->graphWindowOpacity() != v) { + ini()->setGraphWindowOpacity(v); + ctrl()->setIniEdited(); + } + }); + connect(m_graphHoverOpacity->spinBox(), QOverload::of(&QSpinBox::valueChanged), this, + [&](int v) { + if (ini()->graphWindowHoverOpacity() != v) { + ini()->setGraphWindowHoverOpacity(v); + ctrl()->setIniEdited(); + } + }); + connect(m_graphMaxSeconds->spinBox(), QOverload::of(&QSpinBox::valueChanged), this, + [&](int v) { + if (ini()->graphWindowMaxSeconds() != v) { + ini()->setGraphWindowMaxSeconds(v); + ctrl()->setIniEdited(); + } + }); } -void StatisticsPage::setupAppInfoRow() +void StatisticsPage::setupGraphColors() { - m_appInfoRow = new AppInfoRow(); - - const auto refreshAppInfoVersion = [&] { - m_appInfoRow->refreshAppInfoVersion(appListCurrentPath(), appInfoCache()); - }; - - refreshAppInfoVersion(); - - connect(m_appListView, &ListView::currentIndexChanged, this, refreshAppInfoVersion); - connect(appInfoCache(), &AppInfoCache::cacheChanged, this, refreshAppInfoVersion); -} - -void StatisticsPage::setupAppListViewChanged() -{ - const auto refreshAppListViewChanged = [&] { - const bool appSelected = (appListCurrentIndex() > 0); - m_actRemoveApp->setEnabled(appSelected); - m_appInfoRow->setVisible(appSelected); - }; - - refreshAppListViewChanged(); - - connect(m_appListView, &ListView::currentIndexChanged, this, refreshAppListViewChanged); -} - -void StatisticsPage::updatePage() -{ - m_isPageUpdating = true; - - m_cbLogStat->setChecked(conf()->logStat()); - m_cbLogStatNoFilter->setChecked(conf()->logStatNoFilter()); - - m_ctpActivePeriod->checkBox()->setChecked(conf()->activePeriodEnabled()); - m_ctpActivePeriod->timeEdit1()->setTime(CheckTimePeriod::toTime(conf()->activePeriodFrom())); - m_ctpActivePeriod->timeEdit2()->setTime(CheckTimePeriod::toTime(conf()->activePeriodTo())); - - m_lscMonthStart->spinBox()->setValue(ini()->monthStart()); - m_lscTrafHourKeepDays->spinBox()->setValue(ini()->trafHourKeepDays()); - m_lscTrafDayKeepDays->spinBox()->setValue(ini()->trafDayKeepDays()); - m_lscTrafMonthKeepMonths->spinBox()->setValue(ini()->trafMonthKeepMonths()); - - m_lscQuotaDayMb->spinBox()->setValue(int(ini()->quotaDayMb())); - m_lscQuotaMonthMb->spinBox()->setValue(int(ini()->quotaMonthMb())); - - m_lscAllowedIpKeepCount->spinBox()->setValue(ini()->allowedIpKeepCount()); - m_lscBlockedIpKeepCount->spinBox()->setValue(ini()->blockedIpKeepCount()); - - m_cbGraphAlwaysOnTop->setChecked(ini()->graphWindowAlwaysOnTop()); - m_cbGraphFrameless->setChecked(ini()->graphWindowFrameless()); - m_cbGraphClickThrough->setChecked(ini()->graphWindowClickThrough()); - m_cbGraphHideOnHover->setChecked(ini()->graphWindowHideOnHover()); - - m_graphOpacity->spinBox()->setValue(ini()->graphWindowOpacity()); - m_graphHoverOpacity->spinBox()->setValue(ini()->graphWindowHoverOpacity()); - m_graphMaxSeconds->spinBox()->setValue(ini()->graphWindowMaxSeconds()); - - m_graphColor->setColor(ini()->graphWindowColor()); - m_graphColorIn->setColor(ini()->graphWindowColorIn()); - m_graphColorOut->setColor(ini()->graphWindowColorOut()); - m_graphAxisColor->setColor(ini()->graphWindowAxisColor()); - m_graphTickLabelColor->setColor(ini()->graphWindowTickLabelColor()); - m_graphLabelColor->setColor(ini()->graphWindowLabelColor()); - m_graphGridColor->setColor(ini()->graphWindowGridColor()); - - updateTrafUnit(); - updateTableTrafUnit(); - - m_isPageUpdating = false; -} - -void StatisticsPage::updateTrafUnit() -{ - m_comboTrafUnit->setCurrentIndex(iniUser()->statTrafUnit()); -} - -void StatisticsPage::updateTableTrafUnit() -{ - const auto trafUnit = static_cast(iniUser()->statTrafUnit()); - - if (trafListModel()->unit() != trafUnit) { - trafListModel()->setUnit(trafUnit); - trafListModel()->refresh(); - } -} - -int StatisticsPage::appListCurrentIndex() const -{ - return m_appListView->currentRow(); -} - -QString StatisticsPage::appListCurrentPath() const -{ - return appStatModel()->appPathByRow(appListCurrentIndex()); -} - -LabelSpinCombo *StatisticsPage::createSpinCombo(int min, int max, const QString &suffix) -{ - auto c = new LabelSpinCombo(); - c->spinBox()->setRange(min, max); - c->spinBox()->setSuffix(suffix); - return c; -} - -LabelSpin *StatisticsPage::createSpin(int min, int max, const QString &suffix) -{ - auto c = new LabelSpin(); - c->spinBox()->setRange(min, max); - c->spinBox()->setSuffix(suffix); - return c; -} - -QString StatisticsPage::formatQuota(int mbytes) -{ - return NetUtil::formatDataSize1(qint64(mbytes) * 1024 * 1024); + m_graphColor = createLabelColor(ini()->graphWindowColor(), [&](const QColor &v) { + if (ini()->graphWindowColor() != v) { + ini()->setGraphWindowColor(v); + ctrl()->setIniEdited(); + } + }); + m_graphColorIn = createLabelColor(ini()->graphWindowColorIn(), [&](const QColor &v) { + if (ini()->graphWindowColorIn() != v) { + ini()->setGraphWindowColorIn(v); + ctrl()->setIniEdited(); + } + }); + m_graphColorOut = createLabelColor(ini()->graphWindowColorOut(), [&](const QColor &v) { + if (ini()->graphWindowColorOut() != v) { + ini()->setGraphWindowColorOut(v); + ctrl()->setIniEdited(); + } + }); + m_graphAxisColor = createLabelColor(ini()->graphWindowAxisColor(), [&](const QColor &v) { + if (ini()->graphWindowAxisColor() != v) { + ini()->setGraphWindowAxisColor(v); + ctrl()->setIniEdited(); + } + }); + m_graphTickLabelColor = + createLabelColor(ini()->graphWindowTickLabelColor(), [&](const QColor &v) { + if (ini()->graphWindowTickLabelColor() != v) { + ini()->setGraphWindowTickLabelColor(v); + ctrl()->setIniEdited(); + } + }); + m_graphLabelColor = createLabelColor(ini()->graphWindowLabelColor(), [&](const QColor &v) { + if (ini()->graphWindowLabelColor() != v) { + ini()->setGraphWindowLabelColor(v); + ctrl()->setIniEdited(); + } + }); + m_graphGridColor = createLabelColor(ini()->graphWindowGridColor(), [&](const QColor &v) { + if (ini()->graphWindowGridColor() != v) { + ini()->setGraphWindowGridColor(v); + ctrl()->setIniEdited(); + } + }); } diff --git a/src/ui/form/opt/pages/statisticspage.h b/src/ui/form/opt/pages/statisticspage.h index 42a3cec7..ffbaef69 100644 --- a/src/ui/form/opt/pages/statisticspage.h +++ b/src/ui/form/opt/pages/statisticspage.h @@ -1,38 +1,21 @@ #ifndef STATISTICSPAGE_H #define STATISTICSPAGE_H -#include "basepage.h" +#include "optbasepage.h" -QT_FORWARD_DECLARE_CLASS(QSplitter) -QT_FORWARD_DECLARE_CLASS(QTableView) - -class AppInfoCache; -class AppInfoRow; -class AppStatModel; class CheckTimePeriod; class LabelColor; class LabelSpin; class LabelSpinCombo; -class ListView; -class TrafListModel; -class StatisticsPage : public BasePage +class StatisticsPage : public OptBasePage { Q_OBJECT public: explicit StatisticsPage(OptionsController *ctrl = nullptr, QWidget *parent = nullptr); - AppStatModel *appStatModel() const; - AppInfoCache *appInfoCache() const; - TrafListModel *trafListModel() const { return m_trafListModel; } - - void setIniEdited(); - protected slots: - void onSaveWindowState(IniUser *ini) override; - void onRestoreWindowState(IniUser *ini) override; - void onRetranslateUi() override; private: @@ -40,20 +23,10 @@ private: void retranslateTrafKeepMonthNames(); void retranslateQuotaNames(); void retranslateIpKeepCountNames(); - void retranslateTrafUnitNames(); - void retranslateTabBar(); - - void setupTrafListModel(); void setupUi(); - QLayout *setupHeader(); - void setupClearMenu(); - void setupTrafUnits(); - void setupGraphOptionsMenu(); - void setupGraphCheckboxes(); - void setupGraphOptions(); - void setupGraphColors(); - void setupTrafOptionsMenu(); + QLayout *setupColumn1(); + void setupTrafficBox(); void setupLogStat(); void setupLogStatNoFilter(); void setupActivePeriod(); @@ -65,37 +38,26 @@ private: void setupQuotaMonthMb(); void setupAllowedIpKeepCount(); void setupBlockedIpKeepCount(); - void setupAppListView(); - void setupTabBar(); - void setupTableTraf(); - void setupTableTrafHeader(); - void setupAppInfoRow(); - void setupAppListViewChanged(); - void updatePage(); - void updateTrafUnit(); - void updateTableTrafUnit(); - - int appListCurrentIndex() const; - QString appListCurrentPath() const; - - static LabelSpinCombo *createSpinCombo(int min, int max, const QString &suffix = QString()); - static LabelSpin *createSpin(int min, int max, const QString &suffix = QString()); - - static QString formatQuota(int mbytes); + QLayout *setupColumn2(); + void setupGraphBox(); + void setupGraphCheckboxes(); + void setupGraphOptions(); + void setupGraphColors(); private: - bool m_isPageUpdating : 1; - - TrafListModel *m_trafListModel = nullptr; - - QPushButton *m_btRefresh = nullptr; - QPushButton *m_btClear = nullptr; - QAction *m_actRemoveApp = nullptr; - QAction *m_actResetTotal = nullptr; - QAction *m_actClearAll = nullptr; - QLabel *m_traphUnits = nullptr; - QComboBox *m_comboTrafUnit = nullptr; - QPushButton *m_btGraphOptions = nullptr; + QGroupBox *m_gbTraffic = nullptr; + QGroupBox *m_gbGraph = nullptr; + QCheckBox *m_cbLogStat = nullptr; + QCheckBox *m_cbLogStatNoFilter = nullptr; + CheckTimePeriod *m_ctpActivePeriod = nullptr; + LabelSpinCombo *m_lscMonthStart = nullptr; + LabelSpinCombo *m_lscTrafHourKeepDays = nullptr; + LabelSpinCombo *m_lscTrafDayKeepDays = nullptr; + LabelSpinCombo *m_lscTrafMonthKeepMonths = nullptr; + LabelSpinCombo *m_lscQuotaDayMb = nullptr; + LabelSpinCombo *m_lscQuotaMonthMb = nullptr; + LabelSpinCombo *m_lscAllowedIpKeepCount = nullptr; + LabelSpinCombo *m_lscBlockedIpKeepCount = nullptr; QCheckBox *m_cbGraphAlwaysOnTop = nullptr; QCheckBox *m_cbGraphFrameless = nullptr; QCheckBox *m_cbGraphClickThrough = nullptr; @@ -110,23 +72,6 @@ private: LabelColor *m_graphTickLabelColor = nullptr; LabelColor *m_graphLabelColor = nullptr; LabelColor *m_graphGridColor = nullptr; - QPushButton *m_btTrafOptions = nullptr; - QCheckBox *m_cbLogStat = nullptr; - QCheckBox *m_cbLogStatNoFilter = nullptr; - CheckTimePeriod *m_ctpActivePeriod = nullptr; - LabelSpinCombo *m_lscMonthStart = nullptr; - LabelSpinCombo *m_lscTrafHourKeepDays = nullptr; - LabelSpinCombo *m_lscTrafDayKeepDays = nullptr; - LabelSpinCombo *m_lscTrafMonthKeepMonths = nullptr; - LabelSpinCombo *m_lscQuotaDayMb = nullptr; - LabelSpinCombo *m_lscQuotaMonthMb = nullptr; - LabelSpinCombo *m_lscAllowedIpKeepCount = nullptr; - LabelSpinCombo *m_lscBlockedIpKeepCount = nullptr; - QSplitter *m_splitter = nullptr; - ListView *m_appListView = nullptr; - QTabBar *m_tabBar = nullptr; - QTableView *m_tableTraf = nullptr; - AppInfoRow *m_appInfoRow = nullptr; }; #endif // STATISTICSPAGE_H diff --git a/src/ui/form/stat/pages/connectionspage.cpp b/src/ui/form/stat/pages/connectionspage.cpp new file mode 100644 index 00000000..be52516b --- /dev/null +++ b/src/ui/form/stat/pages/connectionspage.cpp @@ -0,0 +1,327 @@ +#include "connectionspage.h" + +#include +#include +#include +#include +#include + +#include "../../../appinfo/appinfocache.h" +#include "../../../conf/confmanager.h" +#include "../../../conf/firewallconf.h" +#include "../../../fortmanager.h" +#include "../../../fortsettings.h" +#include "../../../model/connlistmodel.h" +#include "../../../user/iniuser.h" +#include "../../../util/guiutil.h" +#include "../../../util/iconcache.h" +#include "../../controls/appinforow.h" +#include "../../controls/controlutil.h" +#include "../../controls/tableview.h" +#include "../statisticscontroller.h" + +namespace { + +#define CONN_LIST_HEADER_VERSION 1 + +} + +ConnectionsPage::ConnectionsPage(StatisticsController *ctrl, QWidget *parent) : + StatBasePage(ctrl, parent) +{ + setupUi(); +} + +ConnListModel *ConnectionsPage::connListModel() const +{ + return fortManager()->connListModel(); +} + +AppInfoCache *ConnectionsPage::appInfoCache() const +{ + return connListModel()->appInfoCache(); +} + +void ConnectionsPage::onSaveWindowState(IniUser *ini) +{ + auto header = m_connListView->horizontalHeader(); + ini->setConnListHeader(header->saveState()); + ini->setConnListHeaderVersion(CONN_LIST_HEADER_VERSION); +} + +void ConnectionsPage::onRestoreWindowState(IniUser *ini) +{ + if (ini->connListHeaderVersion() == CONN_LIST_HEADER_VERSION) { + auto header = m_connListView->horizontalHeader(); + header->restoreState(ini->connListHeader()); + } +} + +void ConnectionsPage::onRetranslateUi() +{ + m_btEdit->setText(tr("Edit")); + m_actCopy->setText(tr("Copy")); + m_actAddProgram->setText(tr("Add Program")); + m_actRemoveConn->setText(tr("Remove")); + m_actClearConns->setText(tr("Clear All")); + + m_btLogOptions->setText(tr("Options")); + m_cbLogAllowedIp->setText(tr("Collect allowed connections")); + m_cbLogBlockedIp->setText(tr("Collect blocked connections")); + m_cbAutoScroll->setText(tr("Auto scroll")); + m_cbShowHostNames->setText(tr("Show host names")); + + connListModel()->refresh(); + + m_appInfoRow->retranslateUi(); +} + +void ConnectionsPage::setupUi() +{ + auto layout = new QVBoxLayout(); + layout->setContentsMargins(6, 6, 6, 6); + + // Header + auto header = setupHeader(); + layout->addLayout(header); + + // Table + setupTableConnList(); + setupTableConnListHeader(); + layout->addWidget(m_connListView, 1); + + // App Info Row + setupAppInfoRow(); + layout->addWidget(m_appInfoRow); + + // Actions on conns table's current changed + setupTableConnsChanged(); + + this->setLayout(layout); +} + +QLayout *ConnectionsPage::setupHeader() +{ + auto layout = new QHBoxLayout(); + + // Edit Menu + auto editMenu = new QMenu(this); + + m_actCopy = editMenu->addAction(IconCache::icon(":/icons/copy.png"), QString()); + m_actCopy->setShortcut(Qt::Key_Copy); + + m_actAddProgram = editMenu->addAction(IconCache::icon(":/icons/window.png"), QString()); + m_actAddProgram->setShortcut(Qt::Key_Insert); + + m_actRemoveConn = editMenu->addAction(IconCache::icon(":/icons/sign-delete.png"), QString()); + m_actRemoveConn->setShortcut(Qt::Key_Delete); + + m_actClearConns = editMenu->addAction(IconCache::icon(":/icons/trashcan-full.png"), QString()); + + connect(m_actCopy, &QAction::triggered, this, + [&] { GuiUtil::setClipboardData(m_connListView->selectedText()); }); + connect(m_actAddProgram, &QAction::triggered, this, [&] { + const auto connIndex = connListCurrentIndex(); + const auto connRow = connListModel()->connRowAt(connIndex); + + fortManager()->showProgramEditForm(connRow.appPath); + }); + connect(m_actRemoveConn, &QAction::triggered, this, [&] { + if (fortManager()->showQuestionBox( + tr("Are you sure to remove connections till this row?"))) { + deleteConn(m_connListView->currentRow()); + } + }); + connect(m_actClearConns, &QAction::triggered, this, [&] { + if (fortManager()->showQuestionBox(tr("Are you sure to remove all connections?"))) { + connListModel()->clear(); + } + }); + + m_btEdit = ControlUtil::createButton(":/icons/pencil.png"); + m_btEdit->setMenu(editMenu); + + // Log Options + setupLogOptions(); + + layout->addWidget(m_btEdit); + layout->addStretch(); + layout->addWidget(m_btLogOptions); + + return layout; +} + +void ConnectionsPage::setupLogOptions() +{ + setupLogAllowedIp(); + setupLogBlockedIp(); + setupAutoScroll(); + setupShowHostNames(); + + // Menu + const QList menuWidgets = { m_cbLogAllowedIp, m_cbLogBlockedIp, + ControlUtil::createSeparator(), m_cbAutoScroll, m_cbShowHostNames }; + auto layout = ControlUtil::createLayoutByWidgets(menuWidgets); + + auto menu = ControlUtil::createMenuByLayout(layout, this); + + m_btLogOptions = ControlUtil::createButton(":/icons/wrench.png"); + m_btLogOptions->setMenu(menu); +} + +void ConnectionsPage::setupLogAllowedIp() +{ + m_cbLogAllowedIp = ControlUtil::createCheckBox(conf()->logAllowedIp(), [&](bool checked) { + if (conf()->logAllowedIp() == checked) + return; + + conf()->setLogAllowedIp(checked); + + confManager()->saveFlags(); + }); + + m_cbLogAllowedIp->setVisible(false); // TODO: Collect allowed connections +} + +void ConnectionsPage::setupLogBlockedIp() +{ + m_cbLogBlockedIp = ControlUtil::createCheckBox(conf()->logBlockedIp(), [&](bool checked) { + if (conf()->logBlockedIp() == checked) + return; + + conf()->setLogBlockedIp(checked); + + confManager()->saveFlags(); + }); +} + +void ConnectionsPage::setupAutoScroll() +{ + m_cbAutoScroll = ControlUtil::createCheckBox(iniUser()->statAutoScroll(), [&](bool checked) { + if (iniUser()->statAutoScroll() == checked) + return; + + iniUser()->setStatAutoScroll(checked); + confManager()->saveIniUser(); + + syncAutoScroll(); + }); +} + +void ConnectionsPage::setupShowHostNames() +{ + m_cbShowHostNames = + ControlUtil::createCheckBox(iniUser()->statShowHostNames(), [&](bool checked) { + if (iniUser()->statShowHostNames() == checked) + return; + + iniUser()->setStatShowHostNames(checked); + confManager()->saveIniUser(); + + syncShowHostNames(); + }); +} + +void ConnectionsPage::setupTableConnList() +{ + m_connListView = new TableView(); + m_connListView->setAlternatingRowColors(true); + m_connListView->setSelectionMode(QAbstractItemView::ExtendedSelection); + m_connListView->setSelectionBehavior(QAbstractItemView::SelectItems); + + // TODO: Select the allowed/blocked mode from UI + connListModel()->setBlockedMode(true); + + m_connListView->setModel(connListModel()); + + m_connListView->setMenu(m_btEdit->menu()); +} + +void ConnectionsPage::setupTableConnListHeader() +{ + auto header = m_connListView->horizontalHeader(); + + header->setSectionResizeMode(0, QHeaderView::Interactive); + header->setSectionResizeMode(1, QHeaderView::Interactive); + header->setSectionResizeMode(2, QHeaderView::Interactive); + header->setSectionResizeMode(3, QHeaderView::Interactive); + header->setSectionResizeMode(4, QHeaderView::Interactive); + header->setSectionResizeMode(5, QHeaderView::Fixed); + header->setSectionResizeMode(6, QHeaderView::Stretch); + + header->resizeSection(0, 430); + header->resizeSection(1, 50); + header->resizeSection(2, 60); + header->resizeSection(3, 140); + header->resizeSection(4, 140); + header->resizeSection(5, 60); + + // header->setSectionsClickable(true); + // header->setSortIndicatorShown(true); + // header->setSortIndicator(4, Qt::DescendingOrder); +} + +void ConnectionsPage::setupAppInfoRow() +{ + m_appInfoRow = new AppInfoRow(); + + const auto refreshAppInfoVersion = [&] { + m_appInfoRow->refreshAppInfoVersion(connListCurrentPath(), appInfoCache()); + }; + + refreshAppInfoVersion(); + + connect(m_connListView, &TableView::currentIndexChanged, this, refreshAppInfoVersion); + connect(appInfoCache(), &AppInfoCache::cacheChanged, this, refreshAppInfoVersion); +} + +void ConnectionsPage::setupTableConnsChanged() +{ + const auto refreshTableConnsChanged = [&] { + const int connIndex = connListCurrentIndex(); + const bool connSelected = (connIndex >= 0); + m_actCopy->setEnabled(connSelected); + m_actAddProgram->setEnabled(connSelected); + m_actRemoveConn->setEnabled(connSelected); + m_appInfoRow->setVisible(connSelected); + }; + + refreshTableConnsChanged(); + + connect(m_connListView, &TableView::currentIndexChanged, this, refreshTableConnsChanged); +} + +void ConnectionsPage::syncAutoScroll() +{ + if (iniUser()->statAutoScroll()) { + connect(connListModel(), &QAbstractItemModel::rowsInserted, m_connListView, + &QAbstractItemView::scrollToBottom); + + m_connListView->scrollToBottom(); + } else { + disconnect(connListModel(), &QAbstractItemModel::rowsInserted, m_connListView, + &QAbstractItemView::scrollToBottom); + } +} + +void ConnectionsPage::syncShowHostNames() +{ + connListModel()->setResolveAddress(iniUser()->statShowHostNames()); +} + +void ConnectionsPage::deleteConn(int row) +{ + const auto connRow = connListModel()->connRowAt(row); + connListModel()->deleteConn(connRow.rowId, connRow.blocked, row); +} + +int ConnectionsPage::connListCurrentIndex() const +{ + return m_connListView->currentRow(); +} + +QString ConnectionsPage::connListCurrentPath() const +{ + const auto connRow = connListModel()->connRowAt(connListCurrentIndex()); + return connRow.appPath; +} diff --git a/src/ui/form/stat/pages/connectionspage.h b/src/ui/form/stat/pages/connectionspage.h new file mode 100644 index 00000000..0ddd2d56 --- /dev/null +++ b/src/ui/form/stat/pages/connectionspage.h @@ -0,0 +1,73 @@ +#ifndef CONNECTIONSPAGE_H +#define CONNECTIONSPAGE_H + +#include "statbasepage.h" + +QT_FORWARD_DECLARE_CLASS(QCheckBox) +QT_FORWARD_DECLARE_CLASS(QPushButton) + +class AppInfoCache; +class AppInfoRow; +class ConfManager; +class ConnListModel; +class FirewallConf; +class FortManager; +class FortSettings; +class IniOptions; +class IniUser; +class StatisticsController; +class TableView; + +class ConnectionsPage : public StatBasePage +{ + Q_OBJECT + +public: + explicit ConnectionsPage(StatisticsController *ctrl = nullptr, QWidget *parent = nullptr); + + ConnListModel *connListModel() const; + AppInfoCache *appInfoCache() const; + +protected slots: + void onSaveWindowState(IniUser *ini) override; + void onRestoreWindowState(IniUser *ini) override; + + void onRetranslateUi() override; + +private: + void setupUi(); + QLayout *setupHeader(); + void setupLogOptions(); + void setupLogAllowedIp(); + void setupLogBlockedIp(); + void setupAutoScroll(); + void setupShowHostNames(); + void setupTableConnList(); + void setupTableConnListHeader(); + void setupAppInfoRow(); + void setupTableConnsChanged(); + + void syncAutoScroll(); + void syncShowHostNames(); + + void deleteConn(int row); + + int connListCurrentIndex() const; + QString connListCurrentPath() const; + +private: + QPushButton *m_btEdit = nullptr; + QAction *m_actCopy = nullptr; + QAction *m_actAddProgram = nullptr; + QAction *m_actRemoveConn = nullptr; + QAction *m_actClearConns = nullptr; + QPushButton *m_btLogOptions = nullptr; + QCheckBox *m_cbLogAllowedIp = nullptr; + QCheckBox *m_cbLogBlockedIp = nullptr; + QCheckBox *m_cbAutoScroll = nullptr; + QCheckBox *m_cbShowHostNames = nullptr; + TableView *m_connListView = nullptr; + AppInfoRow *m_appInfoRow = nullptr; +}; + +#endif // CONNECTIONSPAGE_H diff --git a/src/ui/form/stat/pages/statbasepage.cpp b/src/ui/form/stat/pages/statbasepage.cpp new file mode 100644 index 00000000..d406239e --- /dev/null +++ b/src/ui/form/stat/pages/statbasepage.cpp @@ -0,0 +1,56 @@ +#include "statbasepage.h" + +#include + +#include "../../../conf/firewallconf.h" +#include "../../../fortmanager.h" +#include "../../../user/iniuser.h" +#include "../statisticscontroller.h" + +StatBasePage::StatBasePage(StatisticsController *ctrl, QWidget *parent) : + QFrame(parent), m_ctrl(ctrl) +{ + setupController(); +} + +FortManager *StatBasePage::fortManager() const +{ + return ctrl()->fortManager(); +} + +FortSettings *StatBasePage::settings() const +{ + return ctrl()->settings(); +} + +ConfManager *StatBasePage::confManager() const +{ + return ctrl()->confManager(); +} + +FirewallConf *StatBasePage::conf() const +{ + return ctrl()->conf(); +} + +IniUser *StatBasePage::iniUser() const +{ + return ctrl()->iniUser(); +} + +TranslationManager *StatBasePage::translationManager() const +{ + return ctrl()->translationManager(); +} + +void StatBasePage::setupController() +{ + Q_ASSERT(ctrl()); + + connect(ctrl(), &StatisticsController::afterSaveWindowState, this, + &StatBasePage::onSaveWindowState); + connect(ctrl(), &StatisticsController::afterRestoreWindowState, this, + &StatBasePage::onRestoreWindowState); + + connect(ctrl(), &StatisticsController::retranslateUi, this, &StatBasePage::onRetranslateUi); +} diff --git a/src/ui/form/stat/pages/statbasepage.h b/src/ui/form/stat/pages/statbasepage.h new file mode 100644 index 00000000..2061bacd --- /dev/null +++ b/src/ui/form/stat/pages/statbasepage.h @@ -0,0 +1,53 @@ +#ifndef STATBASEPAGE_H +#define STATBASEPAGE_H + +#include + +QT_FORWARD_DECLARE_CLASS(QAction) +QT_FORWARD_DECLARE_CLASS(QCheckBox) +QT_FORWARD_DECLARE_CLASS(QComboBox) +QT_FORWARD_DECLARE_CLASS(QGroupBox) +QT_FORWARD_DECLARE_CLASS(QLabel) +QT_FORWARD_DECLARE_CLASS(QLineEdit) +QT_FORWARD_DECLARE_CLASS(QMenu) +QT_FORWARD_DECLARE_CLASS(QPushButton) +QT_FORWARD_DECLARE_CLASS(QTabBar) + +class ConfManager; +class FirewallConf; +class FortManager; +class FortSettings; +class IniUser; +class StatisticsController; +class TranslationManager; + +class StatBasePage : public QFrame +{ + Q_OBJECT + +public: + explicit StatBasePage(StatisticsController *ctrl, QWidget *parent = nullptr); + +protected: + StatisticsController *ctrl() const { return m_ctrl; } + FortManager *fortManager() const; + FortSettings *settings() const; + ConfManager *confManager() const; + FirewallConf *conf() const; + IniUser *iniUser() const; + TranslationManager *translationManager() const; + +protected slots: + virtual void onSaveWindowState(IniUser * /*ini*/) { } + virtual void onRestoreWindowState(IniUser * /*ini*/) { } + + virtual void onRetranslateUi() { } + +private: + void setupController(); + +private: + StatisticsController *m_ctrl = nullptr; +}; + +#endif // STATBASEPAGE_H diff --git a/src/ui/form/stat/pages/statmainpage.cpp b/src/ui/form/stat/pages/statmainpage.cpp new file mode 100644 index 00000000..ddf5194f --- /dev/null +++ b/src/ui/form/stat/pages/statmainpage.cpp @@ -0,0 +1,46 @@ +#include "statmainpage.h" + +#include +#include +#include +#include + +#include "../../../fortsettings.h" +#include "../../../util/iconcache.h" +#include "../../controls/controlutil.h" +#include "../statisticscontroller.h" +#include "connectionspage.h" +#include "trafficpage.h" + +StatMainPage::StatMainPage(StatisticsController *ctrl, QWidget *parent) : StatBasePage(ctrl, parent) +{ + setupUi(); +} + +void StatMainPage::onRetranslateUi() +{ + m_tabBar->setTabText(0, tr("Traffic")); + m_tabBar->setTabText(1, tr("Connections")); +} + +void StatMainPage::setupUi() +{ + auto layout = new QVBoxLayout(); + layout->setContentsMargins(6, 6, 6, 6); + + // Main Tab Bar + setupTabBar(); + layout->addWidget(m_tabBar); + + this->setLayout(layout); +} + +void StatMainPage::setupTabBar() +{ + auto statisticsPage = new TrafficPage(ctrl()); + auto connectionsPage = new ConnectionsPage(ctrl()); + + m_tabBar = new QTabWidget(); + m_tabBar->addTab(statisticsPage, IconCache::icon(":/icons/line-bar.png"), QString()); + m_tabBar->addTab(connectionsPage, IconCache::icon(":/icons/connect.png"), QString()); +} diff --git a/src/ui/form/stat/pages/statmainpage.h b/src/ui/form/stat/pages/statmainpage.h new file mode 100644 index 00000000..9c0c7221 --- /dev/null +++ b/src/ui/form/stat/pages/statmainpage.h @@ -0,0 +1,26 @@ +#ifndef STATMAINPAGE_H +#define STATMAINPAGE_H + +#include "statbasepage.h" + +QT_FORWARD_DECLARE_CLASS(QTabWidget) + +class StatMainPage : public StatBasePage +{ + Q_OBJECT + +public: + explicit StatMainPage(StatisticsController *ctrl = nullptr, QWidget *parent = nullptr); + +protected slots: + void onRetranslateUi() override; + +private: + void setupUi(); + void setupTabBar(); + +private: + QTabWidget *m_tabBar = nullptr; +}; + +#endif // STATMAINPAGE_H diff --git a/src/ui/form/stat/pages/trafficpage.cpp b/src/ui/form/stat/pages/trafficpage.cpp new file mode 100644 index 00000000..03c3feec --- /dev/null +++ b/src/ui/form/stat/pages/trafficpage.cpp @@ -0,0 +1,319 @@ +#include "trafficpage.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../../appinfo/appinfocache.h" +#include "../../../conf/confmanager.h" +#include "../../../fortmanager.h" +#include "../../../model/appstatmodel.h" +#include "../../../model/traflistmodel.h" +#include "../../../user/iniuser.h" +#include "../../../util/iconcache.h" +#include "../../controls/appinforow.h" +#include "../../controls/controlutil.h" +#include "../../controls/listview.h" +#include "../statisticscontroller.h" + +TrafficPage::TrafficPage(StatisticsController *ctrl, QWidget *parent) : StatBasePage(ctrl, parent) +{ + setupUi(); +} + +AppStatModel *TrafficPage::appStatModel() const +{ + return fortManager()->appStatModel(); +} + +AppInfoCache *TrafficPage::appInfoCache() const +{ + return appStatModel()->appInfoCache(); +} + +TrafListModel *TrafficPage::trafListModel() const +{ + return appStatModel()->trafListModel(); +} + +void TrafficPage::onSaveWindowState(IniUser *ini) +{ + ini->setStatWindowTrafSplit(m_splitter->saveState()); +} + +void TrafficPage::onRestoreWindowState(IniUser *ini) +{ + m_splitter->restoreState(ini->statWindowTrafSplit()); +} + +void TrafficPage::onRetranslateUi() +{ + m_btRefresh->setText(tr("Refresh")); + m_btClear->setText(tr("Clear")); + + m_actRemoveApp->setText(tr("Remove Application")); + m_actResetTotal->setText(tr("Reset Total")); + m_actClearAll->setText(tr("Clear All")); + + m_traphUnits->setText(tr("Units:")); + retranslateTrafUnitNames(); + + retranslateTabBar(); + + m_appInfoRow->retranslateUi(); +} + +void TrafficPage::retranslateTrafUnitNames() +{ + const QStringList list = { tr("Adaptive"), tr("Bytes"), "KiB", "MiB", "GiB", "TiB" }; + + m_comboTrafUnit->clear(); + m_comboTrafUnit->addItems(list); + + updateTrafUnit(); + updateTableTrafUnit(); +} + +void TrafficPage::retranslateTabBar() +{ + const QStringList list = { tr("Hourly"), tr("Daily"), tr("Monthly"), tr("Total") }; + + int index = 0; + for (const auto &v : list) { + m_tabBar->setTabText(index++, v); + } +} + +void TrafficPage::setupUi() +{ + auto layout = new QVBoxLayout(); + + // Header + auto header = setupHeader(); + layout->addLayout(header); + + // Content + m_splitter = new QSplitter(); + + setupAppListView(); + m_splitter->addWidget(m_appListView); + + // Tab Bar + auto trafLayout = new QVBoxLayout(); + trafLayout->setContentsMargins(0, 0, 0, 0); + + setupTabBar(); + trafLayout->addWidget(m_tabBar); + + // Traf Table + setupTableTraf(); + setupTableTrafHeader(); + trafLayout->addWidget(m_tableTraf); + + auto trafWidget = new QWidget(); + trafWidget->setLayout(trafLayout); + m_splitter->addWidget(trafWidget); + + layout->addWidget(m_splitter, 1); + + // App Info Row + setupAppInfoRow(); + layout->addWidget(m_appInfoRow); + + // Actions on app list view's current changed + setupAppListViewChanged(); + + this->setLayout(layout); +} + +QLayout *TrafficPage::setupHeader() +{ + auto layout = new QHBoxLayout(); + + m_btRefresh = + ControlUtil::createButton(":/icons/sign-sync.png", [&] { trafListModel()->reset(); }); + + setupClearMenu(); + setupTrafUnits(); + + layout->addWidget(m_btRefresh); + layout->addWidget(m_btClear); + layout->addWidget(ControlUtil::createSeparator(Qt::Vertical)); + layout->addWidget(m_traphUnits); + layout->addWidget(m_comboTrafUnit); + layout->addStretch(); + + return layout; +} + +void TrafficPage::setupClearMenu() +{ + auto menu = new QMenu(this); + + m_actRemoveApp = menu->addAction(IconCache::icon(":/icons/sign-delete.png"), QString()); + m_actRemoveApp->setShortcut(Qt::Key_Delete); + + m_actResetTotal = menu->addAction(QString()); + m_actClearAll = menu->addAction(QString()); + + connect(m_actRemoveApp, &QAction::triggered, this, [&] { + if (!fortManager()->showQuestionBox( + tr("Are you sure to remove statistics for selected application?"))) + return; + + appStatModel()->remove(appListCurrentIndex()); + }); + connect(m_actResetTotal, &QAction::triggered, this, [&] { + if (!fortManager()->showQuestionBox(tr("Are you sure to reset total statistics?"))) + return; + + trafListModel()->resetAppTotals(); + }); + connect(m_actClearAll, &QAction::triggered, this, [&] { + if (!fortManager()->showQuestionBox(tr("Are you sure to clear all statistics?"))) + return; + + m_appListView->clearSelection(); + appStatModel()->clear(); + }); + + m_btClear = ControlUtil::createButton(":/icons/trashcan-full.png"); + m_btClear->setMenu(menu); +} + +void TrafficPage::setupTrafUnits() +{ + m_traphUnits = ControlUtil::createLabel(); + + m_comboTrafUnit = ControlUtil::createComboBox(QStringList(), [&](int index) { + if (iniUser()->statTrafUnit() == index) + return; + + iniUser()->setStatTrafUnit(index); + updateTableTrafUnit(); + + confManager()->saveIniUser(); + }); +} + +void TrafficPage::setupAppListView() +{ + m_appListView = new ListView(); + m_appListView->setFlow(QListView::TopToBottom); + m_appListView->setViewMode(QListView::ListMode); + m_appListView->setIconSize(QSize(24, 24)); + m_appListView->setUniformItemSizes(true); + m_appListView->setAlternatingRowColors(true); + + m_appListView->setModel(appStatModel()); +} + +void TrafficPage::setupTabBar() +{ + m_tabBar = new QTabBar(); + m_tabBar->setShape(QTabBar::TriangularNorth); + + for (int n = 4; --n >= 0;) { + m_tabBar->addTab(QString()); + } +} + +void TrafficPage::setupTableTraf() +{ + m_tableTraf = new QTableView(); + m_tableTraf->setSelectionMode(QAbstractItemView::SingleSelection); + m_tableTraf->setSelectionBehavior(QAbstractItemView::SelectItems); + + m_tableTraf->setModel(trafListModel()); + + const auto resetTableTraf = [&] { + trafListModel()->setType(static_cast(m_tabBar->currentIndex())); + trafListModel()->setAppId(appStatModel()->appIdByRow(appListCurrentIndex())); + trafListModel()->resetTraf(); + }; + + resetTableTraf(); + + connect(m_tabBar, &QTabBar::currentChanged, this, resetTableTraf); + connect(m_appListView, &ListView::currentIndexChanged, this, resetTableTraf); +} + +void TrafficPage::setupTableTrafHeader() +{ + auto header = m_tableTraf->horizontalHeader(); + + header->setSectionResizeMode(0, QHeaderView::Fixed); + header->setSectionResizeMode(1, QHeaderView::Stretch); + header->setSectionResizeMode(2, QHeaderView::Stretch); + header->setSectionResizeMode(3, QHeaderView::Stretch); + + const auto refreshTableTrafHeader = [&] { + auto hh = m_tableTraf->horizontalHeader(); + hh->resizeSection(0, qBound(150, qRound(hh->width() * 0.3), 180)); + }; + + refreshTableTrafHeader(); + + connect(header, &QHeaderView::geometriesChanged, this, refreshTableTrafHeader); +} + +void TrafficPage::setupAppInfoRow() +{ + m_appInfoRow = new AppInfoRow(); + + const auto refreshAppInfoVersion = [&] { + m_appInfoRow->refreshAppInfoVersion(appListCurrentPath(), appInfoCache()); + }; + + refreshAppInfoVersion(); + + connect(m_appListView, &ListView::currentIndexChanged, this, refreshAppInfoVersion); + connect(appInfoCache(), &AppInfoCache::cacheChanged, this, refreshAppInfoVersion); +} + +void TrafficPage::setupAppListViewChanged() +{ + const auto refreshAppListViewChanged = [&] { + const bool appSelected = (appListCurrentIndex() > 0); + m_actRemoveApp->setEnabled(appSelected); + m_appInfoRow->setVisible(appSelected); + }; + + refreshAppListViewChanged(); + + connect(m_appListView, &ListView::currentIndexChanged, this, refreshAppListViewChanged); +} + +void TrafficPage::updateTrafUnit() +{ + m_comboTrafUnit->setCurrentIndex(iniUser()->statTrafUnit()); +} + +void TrafficPage::updateTableTrafUnit() +{ + const auto trafUnit = static_cast(iniUser()->statTrafUnit()); + + if (trafListModel()->unit() != trafUnit) { + trafListModel()->setUnit(trafUnit); + trafListModel()->refresh(); + } +} + +int TrafficPage::appListCurrentIndex() const +{ + return m_appListView->currentRow(); +} + +QString TrafficPage::appListCurrentPath() const +{ + return appStatModel()->appPathByRow(appListCurrentIndex()); +} diff --git a/src/ui/form/stat/pages/trafficpage.h b/src/ui/form/stat/pages/trafficpage.h new file mode 100644 index 00000000..1e20652b --- /dev/null +++ b/src/ui/form/stat/pages/trafficpage.h @@ -0,0 +1,68 @@ +#ifndef TRAFFICPAGE_H +#define TRAFFICPAGE_H + +#include "statbasepage.h" + +QT_FORWARD_DECLARE_CLASS(QSplitter) +QT_FORWARD_DECLARE_CLASS(QTableView) + +class AppInfoCache; +class AppInfoRow; +class AppStatModel; +class ListView; +class TrafListModel; + +class TrafficPage : public StatBasePage +{ + Q_OBJECT + +public: + explicit TrafficPage(StatisticsController *ctrl = nullptr, QWidget *parent = nullptr); + + AppStatModel *appStatModel() const; + AppInfoCache *appInfoCache() const; + TrafListModel *trafListModel() const; + +protected slots: + void onSaveWindowState(IniUser *ini) override; + void onRestoreWindowState(IniUser *ini) override; + + void onRetranslateUi() override; + +private: + void retranslateTrafUnitNames(); + void retranslateTabBar(); + + void setupUi(); + QLayout *setupHeader(); + void setupClearMenu(); + void setupTrafUnits(); + void setupAppListView(); + void setupTabBar(); + void setupTableTraf(); + void setupTableTrafHeader(); + void setupAppInfoRow(); + void setupAppListViewChanged(); + + void updateTrafUnit(); + void updateTableTrafUnit(); + + int appListCurrentIndex() const; + QString appListCurrentPath() const; + +private: + QPushButton *m_btRefresh = nullptr; + QPushButton *m_btClear = nullptr; + QAction *m_actRemoveApp = nullptr; + QAction *m_actResetTotal = nullptr; + QAction *m_actClearAll = nullptr; + QLabel *m_traphUnits = nullptr; + QComboBox *m_comboTrafUnit = nullptr; + QSplitter *m_splitter = nullptr; + ListView *m_appListView = nullptr; + QTabBar *m_tabBar = nullptr; + QTableView *m_tableTraf = nullptr; + AppInfoRow *m_appInfoRow = nullptr; +}; + +#endif // TRAFFICPAGE_H diff --git a/src/ui/form/stat/statisticscontroller.h b/src/ui/form/stat/statisticscontroller.h index 66392e2c..2986529b 100644 --- a/src/ui/form/stat/statisticscontroller.h +++ b/src/ui/form/stat/statisticscontroller.h @@ -29,6 +29,9 @@ public: TranslationManager *translationManager() const; signals: + void afterSaveWindowState(IniUser *ini); + void afterRestoreWindowState(IniUser *ini); + void retranslateUi(); private: diff --git a/src/ui/form/stat/statisticswindow.cpp b/src/ui/form/stat/statisticswindow.cpp index f66e4aa0..e5e293bf 100644 --- a/src/ui/form/stat/statisticswindow.cpp +++ b/src/ui/form/stat/statisticswindow.cpp @@ -1,32 +1,14 @@ #include "statisticswindow.h" -#include -#include -#include -#include #include -#include "../../appinfo/appinfocache.h" #include "../../conf/confmanager.h" -#include "../../conf/firewallconf.h" -#include "../../fortmanager.h" -#include "../../fortsettings.h" -#include "../../model/connlistmodel.h" #include "../../user/iniuser.h" #include "../../util/guiutil.h" -#include "../../util/iconcache.h" #include "../../util/window/widgetwindowstatewatcher.h" -#include "../controls/appinforow.h" -#include "../controls/controlutil.h" -#include "../controls/tableview.h" +#include "pages/statmainpage.h" #include "statisticscontroller.h" -namespace { - -#define CONN_LIST_HEADER_VERSION 1 - -} - StatisticsWindow::StatisticsWindow(FortManager *fortManager, QWidget *parent) : WidgetWindow(parent), m_ctrl(new StatisticsController(fortManager, this)), @@ -35,19 +17,6 @@ StatisticsWindow::StatisticsWindow(FortManager *fortManager, QWidget *parent) : setupUi(); setupController(); setupStateWatcher(); - - syncAutoScroll(); - syncShowHostNames(); -} - -FortManager *StatisticsWindow::fortManager() const -{ - return ctrl()->fortManager(); -} - -FortSettings *StatisticsWindow::settings() const -{ - return ctrl()->settings(); } ConfManager *StatisticsWindow::confManager() const @@ -55,39 +24,17 @@ ConfManager *StatisticsWindow::confManager() const return ctrl()->confManager(); } -FirewallConf *StatisticsWindow::conf() const -{ - return ctrl()->conf(); -} - -IniOptions *StatisticsWindow::ini() const -{ - return ctrl()->ini(); -} - IniUser *StatisticsWindow::iniUser() const { return ctrl()->iniUser(); } -ConnListModel *StatisticsWindow::connListModel() const -{ - return fortManager()->connListModel(); -} - -AppInfoCache *StatisticsWindow::appInfoCache() const -{ - return connListModel()->appInfoCache(); -} - void StatisticsWindow::saveWindowState() { iniUser()->setStatWindowGeometry(m_stateWatcher->geometry()); iniUser()->setStatWindowMaximized(m_stateWatcher->maximized()); - auto header = m_connListView->horizontalHeader(); - iniUser()->setConnListHeader(header->saveState()); - iniUser()->setConnListHeaderVersion(CONN_LIST_HEADER_VERSION); + emit ctrl()->afterSaveWindowState(iniUser()); confManager()->saveIniUser(); } @@ -97,17 +44,14 @@ void StatisticsWindow::restoreWindowState() m_stateWatcher->restore(this, QSize(1024, 768), iniUser()->statWindowGeometry(), iniUser()->statWindowMaximized()); - if (iniUser()->connListHeaderVersion() == CONN_LIST_HEADER_VERSION) { - auto header = m_connListView->horizontalHeader(); - header->restoreState(iniUser()->connListHeader()); - } + emit ctrl()->afterRestoreWindowState(iniUser()); } void StatisticsWindow::setupController() { connect(ctrl(), &StatisticsController::retranslateUi, this, &StatisticsWindow::retranslateUi); - retranslateUi(); + emit ctrl()->retranslateUi(); } void StatisticsWindow::setupStateWatcher() @@ -119,45 +63,16 @@ void StatisticsWindow::retranslateUi() { this->unsetLocale(); - m_btEdit->setText(tr("Edit")); - m_actCopy->setText(tr("Copy")); - m_actAddProgram->setText(tr("Add Program")); - m_actRemoveConn->setText(tr("Remove")); - m_actClearConns->setText(tr("Clear All")); - - m_btLogOptions->setText(tr("Options")); - m_cbLogAllowedIp->setText(tr("Collect allowed connections")); - m_cbLogBlockedIp->setText(tr("Collect blocked connections")); - m_cbAutoScroll->setText(tr("Auto scroll")); - m_cbShowHostNames->setText(tr("Show host names")); - - connListModel()->refresh(); - - m_appInfoRow->retranslateUi(); - this->setWindowTitle(tr("Statistics")); } void StatisticsWindow::setupUi() { auto layout = new QVBoxLayout(); - layout->setContentsMargins(6, 6, 6, 6); + layout->setContentsMargins(0, 0, 0, 0); - // Header - auto header = setupHeader(); - layout->addLayout(header); - - // Table - setupTableConnList(); - setupTableConnListHeader(); - layout->addWidget(m_connListView, 1); - - // App Info Row - setupAppInfoRow(); - layout->addWidget(m_appInfoRow); - - // Actions on conns table's current changed - setupTableConnsChanged(); + m_mainPage = new StatMainPage(ctrl()); + layout->addWidget(m_mainPage); this->setLayout(layout); @@ -170,229 +85,3 @@ void StatisticsWindow::setupUi() // Size this->setMinimumSize(500, 400); } - -QLayout *StatisticsWindow::setupHeader() -{ - auto layout = new QHBoxLayout(); - - // Edit Menu - auto editMenu = new QMenu(this); - - m_actCopy = editMenu->addAction(IconCache::icon(":/icons/copy.png"), QString()); - m_actCopy->setShortcut(Qt::Key_Copy); - - m_actAddProgram = editMenu->addAction(IconCache::icon(":/icons/window.png"), QString()); - m_actAddProgram->setShortcut(Qt::Key_Insert); - - m_actRemoveConn = editMenu->addAction(IconCache::icon(":/icons/sign-delete.png"), QString()); - m_actRemoveConn->setShortcut(Qt::Key_Delete); - - m_actClearConns = editMenu->addAction(IconCache::icon(":/icons/trashcan-full.png"), QString()); - - connect(m_actCopy, &QAction::triggered, this, - [&] { GuiUtil::setClipboardData(m_connListView->selectedText()); }); - connect(m_actAddProgram, &QAction::triggered, this, [&] { - const auto connIndex = connListCurrentIndex(); - const auto connRow = connListModel()->connRowAt(connIndex); - - fortManager()->showProgramEditForm(connRow.appPath); - }); - connect(m_actRemoveConn, &QAction::triggered, this, [&] { - if (fortManager()->showQuestionBox( - tr("Are you sure to remove connections till this row?"))) { - deleteConn(m_connListView->currentRow()); - } - }); - connect(m_actClearConns, &QAction::triggered, this, [&] { - if (fortManager()->showQuestionBox(tr("Are you sure to remove all connections?"))) { - connListModel()->clear(); - } - }); - - m_btEdit = ControlUtil::createButton(":/icons/pencil.png"); - m_btEdit->setMenu(editMenu); - - // Log Options - setupLogOptions(); - - layout->addWidget(m_btEdit); - layout->addStretch(); - layout->addWidget(m_btLogOptions); - - return layout; -} - -void StatisticsWindow::setupLogOptions() -{ - setupLogAllowedIp(); - setupLogBlockedIp(); - setupAutoScroll(); - setupShowHostNames(); - - // Menu - const QList menuWidgets = { m_cbLogAllowedIp, m_cbLogBlockedIp, - ControlUtil::createSeparator(), m_cbAutoScroll, m_cbShowHostNames }; - auto layout = ControlUtil::createLayoutByWidgets(menuWidgets); - - auto menu = ControlUtil::createMenuByLayout(layout, this); - - m_btLogOptions = ControlUtil::createButton(":/icons/wrench.png"); - m_btLogOptions->setMenu(menu); -} - -void StatisticsWindow::setupLogAllowedIp() -{ - m_cbLogAllowedIp = ControlUtil::createCheckBox(conf()->logAllowedIp(), [&](bool checked) { - if (conf()->logAllowedIp() == checked) - return; - - conf()->setLogAllowedIp(checked); - - confManager()->saveFlags(); - }); - - m_cbLogAllowedIp->setVisible(false); // TODO: Collect allowed connections -} - -void StatisticsWindow::setupLogBlockedIp() -{ - m_cbLogBlockedIp = ControlUtil::createCheckBox(conf()->logBlockedIp(), [&](bool checked) { - if (conf()->logBlockedIp() == checked) - return; - - conf()->setLogBlockedIp(checked); - - confManager()->saveFlags(); - }); -} - -void StatisticsWindow::setupAutoScroll() -{ - m_cbAutoScroll = ControlUtil::createCheckBox(iniUser()->statAutoScroll(), [&](bool checked) { - if (iniUser()->statAutoScroll() == checked) - return; - - iniUser()->setStatAutoScroll(checked); - confManager()->saveIniUser(); - - syncAutoScroll(); - }); -} - -void StatisticsWindow::setupShowHostNames() -{ - m_cbShowHostNames = - ControlUtil::createCheckBox(iniUser()->statShowHostNames(), [&](bool checked) { - if (iniUser()->statShowHostNames() == checked) - return; - - iniUser()->setStatShowHostNames(checked); - confManager()->saveIniUser(); - - syncShowHostNames(); - }); -} - -void StatisticsWindow::setupTableConnList() -{ - m_connListView = new TableView(); - m_connListView->setAlternatingRowColors(true); - m_connListView->setSelectionMode(QAbstractItemView::ExtendedSelection); - m_connListView->setSelectionBehavior(QAbstractItemView::SelectItems); - - // TODO: Select the allowed/blocked mode from UI - connListModel()->setBlockedMode(true); - - m_connListView->setModel(connListModel()); - - m_connListView->setMenu(m_btEdit->menu()); -} - -void StatisticsWindow::setupTableConnListHeader() -{ - auto header = m_connListView->horizontalHeader(); - - header->setSectionResizeMode(0, QHeaderView::Interactive); - header->setSectionResizeMode(1, QHeaderView::Interactive); - header->setSectionResizeMode(2, QHeaderView::Interactive); - header->setSectionResizeMode(3, QHeaderView::Interactive); - header->setSectionResizeMode(4, QHeaderView::Interactive); - header->setSectionResizeMode(5, QHeaderView::Fixed); - header->setSectionResizeMode(6, QHeaderView::Stretch); - - header->resizeSection(0, 430); - header->resizeSection(1, 50); - header->resizeSection(2, 60); - header->resizeSection(3, 140); - header->resizeSection(4, 140); - header->resizeSection(5, 60); - - // header->setSectionsClickable(true); - // header->setSortIndicatorShown(true); - // header->setSortIndicator(4, Qt::DescendingOrder); -} - -void StatisticsWindow::setupAppInfoRow() -{ - m_appInfoRow = new AppInfoRow(); - - const auto refreshAppInfoVersion = [&] { - m_appInfoRow->refreshAppInfoVersion(connListCurrentPath(), appInfoCache()); - }; - - refreshAppInfoVersion(); - - connect(m_connListView, &TableView::currentIndexChanged, this, refreshAppInfoVersion); - connect(appInfoCache(), &AppInfoCache::cacheChanged, this, refreshAppInfoVersion); -} - -void StatisticsWindow::setupTableConnsChanged() -{ - const auto refreshTableConnsChanged = [&] { - const int connIndex = connListCurrentIndex(); - const bool connSelected = (connIndex >= 0); - m_actCopy->setEnabled(connSelected); - m_actAddProgram->setEnabled(connSelected); - m_actRemoveConn->setEnabled(connSelected); - m_appInfoRow->setVisible(connSelected); - }; - - refreshTableConnsChanged(); - - connect(m_connListView, &TableView::currentIndexChanged, this, refreshTableConnsChanged); -} - -void StatisticsWindow::syncAutoScroll() -{ - if (iniUser()->statAutoScroll()) { - connect(connListModel(), &QAbstractItemModel::rowsInserted, m_connListView, - &QAbstractItemView::scrollToBottom); - - m_connListView->scrollToBottom(); - } else { - disconnect(connListModel(), &QAbstractItemModel::rowsInserted, m_connListView, - &QAbstractItemView::scrollToBottom); - } -} - -void StatisticsWindow::syncShowHostNames() -{ - connListModel()->setResolveAddress(iniUser()->statShowHostNames()); -} - -void StatisticsWindow::deleteConn(int row) -{ - const auto connRow = connListModel()->connRowAt(row); - connListModel()->deleteConn(connRow.rowId, connRow.blocked, row); -} - -int StatisticsWindow::connListCurrentIndex() const -{ - return m_connListView->currentRow(); -} - -QString StatisticsWindow::connListCurrentPath() const -{ - const auto connRow = connListModel()->connRowAt(connListCurrentIndex()); - return connRow.appPath; -} diff --git a/src/ui/form/stat/statisticswindow.h b/src/ui/form/stat/statisticswindow.h index 5310b403..8d4e7da7 100644 --- a/src/ui/form/stat/statisticswindow.h +++ b/src/ui/form/stat/statisticswindow.h @@ -3,20 +3,11 @@ #include "../../util/window/widgetwindow.h" -QT_FORWARD_DECLARE_CLASS(QCheckBox) -QT_FORWARD_DECLARE_CLASS(QPushButton) - -class AppInfoCache; -class AppInfoRow; class ConfManager; -class ConnListModel; -class StatisticsController; -class FirewallConf; class FortManager; -class FortSettings; -class IniOptions; class IniUser; -class TableView; +class StatMainPage; +class StatisticsController; class WidgetWindowStateWatcher; class StatisticsWindow : public WidgetWindow @@ -27,14 +18,8 @@ public: explicit StatisticsWindow(FortManager *fortManager, QWidget *parent = nullptr); StatisticsController *ctrl() const { return m_ctrl; } - FortManager *fortManager() const; - FortSettings *settings() const; ConfManager *confManager() const; - FirewallConf *conf() const; - IniOptions *ini() const; IniUser *iniUser() const; - ConnListModel *connListModel() const; - AppInfoCache *appInfoCache() const; void saveWindowState(); void restoreWindowState(); @@ -46,41 +31,12 @@ private: void retranslateUi(); void setupUi(); - QLayout *setupHeader(); - void setupLogOptions(); - void setupLogAllowedIp(); - void setupLogBlockedIp(); - void setupAutoScroll(); - void setupShowHostNames(); - void setupTableConnList(); - void setupTableConnListHeader(); - void setupAppInfoRow(); - void setupTableConnsChanged(); - - void syncAutoScroll(); - void syncShowHostNames(); - - void deleteConn(int row); - - int connListCurrentIndex() const; - QString connListCurrentPath() const; private: StatisticsController *m_ctrl = nullptr; WidgetWindowStateWatcher *m_stateWatcher = nullptr; - QPushButton *m_btEdit = nullptr; - QAction *m_actCopy = nullptr; - QAction *m_actAddProgram = nullptr; - QAction *m_actRemoveConn = nullptr; - QAction *m_actClearConns = nullptr; - QPushButton *m_btLogOptions = nullptr; - QCheckBox *m_cbLogAllowedIp = nullptr; - QCheckBox *m_cbLogBlockedIp = nullptr; - QCheckBox *m_cbAutoScroll = nullptr; - QCheckBox *m_cbShowHostNames = nullptr; - TableView *m_connListView = nullptr; - AppInfoRow *m_appInfoRow = nullptr; + StatMainPage *m_mainPage = nullptr; }; #endif // STATISTICSWINDOW_H diff --git a/src/ui/user/iniuser.h b/src/ui/user/iniuser.h index f588fa38..6e146dcc 100644 --- a/src/ui/user/iniuser.h +++ b/src/ui/user/iniuser.h @@ -62,9 +62,6 @@ public: QByteArray optWindowAppsSplit() const { return valueByteArray("optWindow/appsSplit"); } void setOptWindowAppsSplit(const QByteArray &v) { setValue("optWindow/appsSplit", v); } - QByteArray optWindowStatSplit() const { return valueByteArray("optWindow/statSplit"); } - void setOptWindowStatSplit(const QByteArray &v) { setValue("optWindow/statSplit", v); } - QRect zoneWindowGeometry() const { return value("zoneWindow/geometry").toRect(); } void setZoneWindowGeometry(const QRect &v) { setValue("zoneWindow/geometry", v); } @@ -95,6 +92,9 @@ public: int statTrafUnit() const { return valueInt("statWindow/trafUnit"); } void setStatTrafUnit(int v) { setValue("statWindow/trafUnit", v); } + QByteArray statWindowTrafSplit() const { return valueByteArray("statWindow/trafSplit"); } + void setStatWindowTrafSplit(const QByteArray &v) { setValue("statWindow/trafSplit", v); } + int connListHeaderVersion() const { return valueInt("statWindow/connListHeaderVersion"); } void setConnListHeaderVersion(int v) { setValue("statWindow/connListHeaderVersion", v); } diff --git a/src/ui/user/usersettings.cpp b/src/ui/user/usersettings.cpp index 43e585db..a5cf2552 100644 --- a/src/ui/user/usersettings.cpp +++ b/src/ui/user/usersettings.cpp @@ -22,6 +22,7 @@ void UserSettings::migrateIniOnStartup() // COMPAT: v3.4.0: .ini ~> .user.ini if (version < 0x030400) { setCacheValue("statWindow/trafUnit", ini()->value("stat/trafUnit")); + setCacheValue("statWindow/trafSplit", ini()->value("optWindow/statSplit")); setCacheValue("statWindow/geometry", ini()->value("connWindow/geometry")); setCacheValue("statWindow/connListHeader", ini()->value("connWindow/connListHeader")); setCacheValue("statWindow/connListHeaderVersion", @@ -62,9 +63,11 @@ void UserSettings::migrateIniOnWrite() removeIniKey("graphWindow/tickLabelColor"); removeIniKey("graphWindow/labelColor"); removeIniKey("graphWindow/gridColor"); + removeIniKey("optWindow/statSplit"); removeIniKey("connWindow"); - ini()->setValue("statWindow/trafUnit", cacheValue("statWindow/trafUnit")); ini()->setValue("statWindow/geometry", cacheValue("statWindow/geometry")); + ini()->setValue("statWindow/trafUnit", cacheValue("statWindow/trafUnit")); + ini()->setValue("statWindow/trafSplit", cacheValue("statWindow/trafSplit")); ini()->setValue("statWindow/connListHeader", cacheValue("statWindow/connListHeader")); ini()->setValue( "statWindow/connListHeaderVersion", cacheValue("statWindow/connListHeaderVersion"));