UI: Options: Move Statistics page to Statistics window as Traffic page.

This commit is contained in:
Nodir Temirkhodjaev 2021-05-18 17:42:23 +03:00
parent c0c9846e9e
commit 6d7e22b1da
34 changed files with 1375 additions and 1105 deletions

View File

@ -51,15 +51,19 @@ SOURCES += \
form/opt/pages/addressespage.cpp \ form/opt/pages/addressespage.cpp \
form/opt/pages/applicationspage.cpp \ form/opt/pages/applicationspage.cpp \
form/opt/pages/apps/appscolumn.cpp \ form/opt/pages/apps/appscolumn.cpp \
form/opt/pages/basepage.cpp \ form/opt/pages/optbasepage.cpp \
form/opt/pages/mainpage.cpp \
form/opt/pages/optionspage.cpp \ form/opt/pages/optionspage.cpp \
form/opt/pages/optmainpage.cpp \
form/opt/pages/rulespage.cpp \ form/opt/pages/rulespage.cpp \
form/opt/pages/schedulepage.cpp \ form/opt/pages/schedulepage.cpp \
form/opt/pages/statisticspage.cpp \ form/opt/pages/statisticspage.cpp \
form/prog/programeditdialog.cpp \ form/prog/programeditdialog.cpp \
form/prog/programscontroller.cpp \ form/prog/programscontroller.cpp \
form/prog/programswindow.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/statisticscontroller.cpp \
form/stat/statisticswindow.cpp \ form/stat/statisticswindow.cpp \
form/tray/traycontroller.cpp \ form/tray/traycontroller.cpp \
@ -191,15 +195,19 @@ HEADERS += \
form/opt/pages/addressespage.h \ form/opt/pages/addressespage.h \
form/opt/pages/applicationspage.h \ form/opt/pages/applicationspage.h \
form/opt/pages/apps/appscolumn.h \ form/opt/pages/apps/appscolumn.h \
form/opt/pages/basepage.h \ form/opt/pages/optbasepage.h \
form/opt/pages/mainpage.h \
form/opt/pages/optionspage.h \ form/opt/pages/optionspage.h \
form/opt/pages/optmainpage.h \
form/opt/pages/rulespage.h \ form/opt/pages/rulespage.h \
form/opt/pages/schedulepage.h \ form/opt/pages/schedulepage.h \
form/opt/pages/statisticspage.h \ form/opt/pages/statisticspage.h \
form/prog/programeditdialog.h \ form/prog/programeditdialog.h \
form/prog/programscontroller.h \ form/prog/programscontroller.h \
form/prog/programswindow.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/statisticscontroller.h \
form/stat/statisticswindow.h \ form/stat/statisticswindow.h \
form/tray/traycontroller.h \ form/tray/traycontroller.h \

View File

@ -142,6 +142,7 @@ QBoxLayout *ControlUtil::createLayoutByWidgets(const QList<QWidget *> &widgets,
{ {
auto layout = auto layout =
new QBoxLayout(o == Qt::Vertical ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight); new QBoxLayout(o == Qt::Vertical ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight);
for (auto w : widgets) { for (auto w : widgets) {
if (!w) { if (!w) {
layout->addStretch(); layout->addStretch();

View File

@ -9,7 +9,7 @@
#include "../../util/guiutil.h" #include "../../util/guiutil.h"
#include "../../util/window/widgetwindowstatewatcher.h" #include "../../util/window/widgetwindowstatewatcher.h"
#include "optionscontroller.h" #include "optionscontroller.h"
#include "pages/mainpage.h" #include "pages/optmainpage.h"
OptionsWindow::OptionsWindow(FortManager *fortManager, QWidget *parent) : OptionsWindow::OptionsWindow(FortManager *fortManager, QWidget *parent) :
WidgetWindow(parent), WidgetWindow(parent),
@ -109,7 +109,7 @@ void OptionsWindow::setupUi()
auto layout = new QVBoxLayout(); auto layout = new QVBoxLayout();
layout->setContentsMargins(0, 0, 0, 0); layout->setContentsMargins(0, 0, 0, 0);
m_mainPage = new MainPage(ctrl()); m_mainPage = new OptMainPage(ctrl());
layout->addWidget(m_mainPage); layout->addWidget(m_mainPage);
this->setLayout(layout); this->setLayout(layout);

View File

@ -8,7 +8,7 @@ class FirewallConf;
class FortManager; class FortManager;
class IniOptions; class IniOptions;
class IniUser; class IniUser;
class MainPage; class OptMainPage;
class OptionsController; class OptionsController;
class WidgetWindowStateWatcher; class WidgetWindowStateWatcher;
@ -45,7 +45,7 @@ private:
OptionsController *m_ctrl = nullptr; OptionsController *m_ctrl = nullptr;
WidgetWindowStateWatcher *m_stateWatcher = nullptr; WidgetWindowStateWatcher *m_stateWatcher = nullptr;
MainPage *m_mainPage = nullptr; OptMainPage *m_mainPage = nullptr;
}; };
#endif // OPTIONSWINDOW_H #endif // OPTIONSWINDOW_H

View File

@ -28,7 +28,7 @@
#include "../optionscontroller.h" #include "../optionscontroller.h"
#include "addresses/addressescolumn.h" #include "addresses/addressescolumn.h"
AddressesPage::AddressesPage(OptionsController *ctrl, QWidget *parent) : BasePage(ctrl, parent) AddressesPage::AddressesPage(OptionsController *ctrl, QWidget *parent) : OptBasePage(ctrl, parent)
{ {
setupUi(); setupUi();

View File

@ -1,13 +1,13 @@
#ifndef ADDRESSESPAGE_H #ifndef ADDRESSESPAGE_H
#define ADDRESSESPAGE_H #define ADDRESSESPAGE_H
#include "basepage.h" #include "optbasepage.h"
class AddressGroup; class AddressGroup;
class AddressesColumn; class AddressesColumn;
class TextArea2Splitter; class TextArea2Splitter;
class AddressesPage : public BasePage class AddressesPage : public OptBasePage
{ {
Q_OBJECT Q_OBJECT

View File

@ -37,7 +37,7 @@ const ValuesList speedLimitValues = { 10, 0, 20, 30, 50, 75, 100, 150, 200, 300,
} }
ApplicationsPage::ApplicationsPage(OptionsController *ctrl, QWidget *parent) : ApplicationsPage::ApplicationsPage(OptionsController *ctrl, QWidget *parent) :
BasePage(ctrl, parent) OptBasePage(ctrl, parent)
{ {
setupUi(); setupUi();

View File

@ -1,7 +1,7 @@
#ifndef APPLICATIONSPAGE_H #ifndef APPLICATIONSPAGE_H
#define APPLICATIONSPAGE_H #define APPLICATIONSPAGE_H
#include "basepage.h" #include "optbasepage.h"
class AppGroup; class AppGroup;
class AppsColumn; class AppsColumn;
@ -10,7 +10,7 @@ class CheckTimePeriod;
class TabBar; class TabBar;
class TextArea2Splitter; class TextArea2Splitter;
class ApplicationsPage : public BasePage class ApplicationsPage : public OptBasePage
{ {
Q_OBJECT Q_OBJECT

View File

@ -1,88 +0,0 @@
#include "basepage.h"
#include <QAbstractButton>
#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<QAbstractButton *>(sender());
if (button) {
OsUtil::openUrlOrFolder(button->windowFilePath());
}
}

View File

@ -0,0 +1,89 @@
#include "optbasepage.h"
#include <QAbstractButton>
#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<QAbstractButton *>(sender());
if (button) {
OsUtil::openUrlOrFolder(button->windowFilePath());
}
}

View File

@ -1,5 +1,5 @@
#ifndef BASEPAGE_H #ifndef OPTBASEPAGE_H
#define BASEPAGE_H #define OPTBASEPAGE_H
#include <QFrame> #include <QFrame>
#include <QUrl> #include <QUrl>
@ -26,12 +26,12 @@ class TaskManager;
class TranslationManager; class TranslationManager;
class ZoneListModel; class ZoneListModel;
class BasePage : public QFrame class OptBasePage : public QFrame
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit BasePage(OptionsController *ctrl, QWidget *parent = nullptr); explicit OptBasePage(OptionsController *ctrl, QWidget *parent = nullptr);
protected: protected:
OptionsController *ctrl() const { return m_ctrl; } OptionsController *ctrl() const { return m_ctrl; }
@ -66,4 +66,4 @@ private:
OptionsController *m_ctrl = nullptr; OptionsController *m_ctrl = nullptr;
}; };
#endif // BASEPAGE_H #endif // OPTBASEPAGE_H

View File

@ -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(); setupStartup();
setupUi(); setupUi();
@ -489,13 +489,15 @@ QLayout *OptionsPage::setupColumn2()
auto layout = new QVBoxLayout(); auto layout = new QVBoxLayout();
layout->setSpacing(10); layout->setSpacing(10);
// Driver Group Box
setupDriverBox(); setupDriverBox();
layout->addWidget(m_gbDriver);
// New Version Group Box
setupNewVersionBox(); setupNewVersionBox();
setupNewVersionUpdate(); setupNewVersionUpdate();
layout->addWidget(m_gbDriver);
layout->addWidget(m_gbNewVersion); layout->addWidget(m_gbNewVersion);
layout->addStretch(); layout->addStretch();
return layout; return layout;

View File

@ -1,9 +1,9 @@
#ifndef OPTIONSPAGE_H #ifndef OPTIONSPAGE_H
#define OPTIONSPAGE_H #define OPTIONSPAGE_H
#include "basepage.h" #include "optbasepage.h"
class OptionsPage : public BasePage class OptionsPage : public OptBasePage
{ {
Q_OBJECT Q_OBJECT

View File

@ -1,4 +1,4 @@
#include "mainpage.h" #include "optmainpage.h"
#include <QIcon> #include <QIcon>
#include <QPushButton> #include <QPushButton>
@ -20,12 +20,12 @@
#include "schedulepage.h" #include "schedulepage.h"
#include "statisticspage.h" #include "statisticspage.h"
MainPage::MainPage(OptionsController *ctrl, QWidget *parent) : BasePage(ctrl, parent) OptMainPage::OptMainPage(OptionsController *ctrl, QWidget *parent) : OptBasePage(ctrl, parent)
{ {
setupUi(); setupUi();
} }
void MainPage::onRetranslateUi() void OptMainPage::onRetranslateUi()
{ {
m_tabBar->setTabText(0, tr("Options")); m_tabBar->setTabText(0, tr("Options"));
m_tabBar->setTabText(1, tr("IPv4 Addresses")); m_tabBar->setTabText(1, tr("IPv4 Addresses"));
@ -44,7 +44,7 @@ void MainPage::onRetranslateUi()
m_btCancel->setText(tr("Cancel")); m_btCancel->setText(tr("Cancel"));
} }
void MainPage::setupUi() void OptMainPage::setupUi()
{ {
auto layout = new QVBoxLayout(); auto layout = new QVBoxLayout();
layout->setContentsMargins(6, 6, 6, 6); layout->setContentsMargins(6, 6, 6, 6);
@ -60,7 +60,7 @@ void MainPage::setupUi()
this->setLayout(layout); this->setLayout(layout);
} }
void MainPage::setupTabBar() void OptMainPage::setupTabBar()
{ {
auto optionsPage = ControlUtil::wrapToScrollArea(new OptionsPage(ctrl())); auto optionsPage = ControlUtil::wrapToScrollArea(new OptionsPage(ctrl()));
auto addressesPage = new AddressesPage(ctrl()); auto addressesPage = new AddressesPage(ctrl());
@ -82,7 +82,7 @@ void MainPage::setupTabBar()
#endif #endif
} }
QLayout *MainPage::setupDialogButtons() QLayout *OptMainPage::setupDialogButtons()
{ {
auto buttonsLayout = new QHBoxLayout(); auto buttonsLayout = new QHBoxLayout();
@ -92,10 +92,10 @@ QLayout *MainPage::setupDialogButtons()
m_btStat = ControlUtil::createLinkButton(":/icons/folder-open.png", settings()->statPath()); m_btStat = ControlUtil::createLinkButton(":/icons/folder-open.png", settings()->statPath());
m_btReleases = ControlUtil::createLinkButton(":/icons/github.png", APP_UPDATES_URL); m_btReleases = ControlUtil::createLinkButton(":/icons/github.png", APP_UPDATES_URL);
connect(m_btLogs, &QAbstractButton::clicked, this, &MainPage::onLinkClicked); connect(m_btLogs, &QAbstractButton::clicked, this, &OptMainPage::onLinkClicked);
connect(m_btProfile, &QAbstractButton::clicked, this, &MainPage::onLinkClicked); connect(m_btProfile, &QAbstractButton::clicked, this, &OptMainPage::onLinkClicked);
connect(m_btStat, &QAbstractButton::clicked, this, &MainPage::onLinkClicked); connect(m_btStat, &QAbstractButton::clicked, this, &OptMainPage::onLinkClicked);
connect(m_btReleases, &QAbstractButton::clicked, this, &MainPage::onLinkClicked); connect(m_btReleases, &QAbstractButton::clicked, this, &OptMainPage::onLinkClicked);
buttonsLayout->addWidget(m_btLogs); buttonsLayout->addWidget(m_btLogs);
buttonsLayout->addWidget(m_btProfile); buttonsLayout->addWidget(m_btProfile);
@ -121,7 +121,7 @@ QLayout *MainPage::setupDialogButtons()
return buttonsLayout; return buttonsLayout;
} }
void MainPage::setupOkApplyButtons() void OptMainPage::setupOkApplyButtons()
{ {
const auto refreshOkApplyButtons = [&](bool anyEdited) { const auto refreshOkApplyButtons = [&](bool anyEdited) {
m_btOk->setEnabled(anyEdited); m_btOk->setEnabled(anyEdited);

View File

@ -1,16 +1,16 @@
#ifndef MAINPAGE_H #ifndef OPTMAINPAGE_H
#define MAINPAGE_H #define OPTMAINPAGE_H
#include "basepage.h" #include "optbasepage.h"
QT_FORWARD_DECLARE_CLASS(QTabWidget) QT_FORWARD_DECLARE_CLASS(QTabWidget)
class MainPage : public BasePage class OptMainPage : public OptBasePage
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit MainPage(OptionsController *ctrl = nullptr, QWidget *parent = nullptr); explicit OptMainPage(OptionsController *ctrl = nullptr, QWidget *parent = nullptr);
protected slots: protected slots:
void onRetranslateUi() override; void onRetranslateUi() override;
@ -34,4 +34,4 @@ private:
QPushButton *m_btCancel = nullptr; QPushButton *m_btCancel = nullptr;
}; };
#endif // MAINPAGE_H #endif // OPTMAINPAGE_H

View File

@ -1,6 +1,6 @@
#include "rulespage.h" #include "rulespage.h"
RulesPage::RulesPage(OptionsController *ctrl, QWidget *parent) : BasePage(ctrl, parent) RulesPage::RulesPage(OptionsController *ctrl, QWidget *parent) : OptBasePage(ctrl, parent)
{ {
setupUi(); setupUi();
} }

View File

@ -1,9 +1,9 @@
#ifndef RULESPAGE_H #ifndef RULESPAGE_H
#define RULESPAGE_H #define RULESPAGE_H
#include "basepage.h" #include "optbasepage.h"
class RulesPage : public BasePage class RulesPage : public OptBasePage
{ {
Q_OBJECT Q_OBJECT

View File

@ -25,7 +25,7 @@ const ValuesList taskIntervalHourValues = { 3, 1, 6, 12, 24, 24 * 7, 24 * 30 };
} }
SchedulePage::SchedulePage(OptionsController *ctrl, QWidget *parent) : 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(); setupUi();
} }

View File

@ -1,7 +1,7 @@
#ifndef SCHEDULEPAGE_H #ifndef SCHEDULEPAGE_H
#define SCHEDULEPAGE_H #define SCHEDULEPAGE_H
#include "basepage.h" #include "optbasepage.h"
QT_FORWARD_DECLARE_CLASS(QTableView) QT_FORWARD_DECLARE_CLASS(QTableView)
@ -10,7 +10,7 @@ class TableView;
class TaskInfo; class TaskInfo;
class TaskListModel; class TaskListModel;
class SchedulePage : public BasePage class SchedulePage : public OptBasePage
{ {
Q_OBJECT Q_OBJECT

View File

@ -1,38 +1,21 @@
#include "statisticspage.h" #include "statisticspage.h"
#include <QAction>
#include <QCheckBox> #include <QCheckBox>
#include <QComboBox> #include <QGroupBox>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QHeaderView>
#include <QLabel> #include <QLabel>
#include <QLineEdit>
#include <QMenu>
#include <QPushButton>
#include <QSpinBox> #include <QSpinBox>
#include <QSplitter>
#include <QTabBar>
#include <QTableView>
#include <QTimeEdit> #include <QTimeEdit>
#include <QVBoxLayout> #include <QVBoxLayout>
#include "../../../appinfo/appinfocache.h"
#include "../../../conf/confmanager.h"
#include "../../../conf/firewallconf.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/iconcache.h"
#include "../../../util/net/netutil.h" #include "../../../util/net/netutil.h"
#include "../../controls/appinforow.h"
#include "../../controls/checktimeperiod.h" #include "../../controls/checktimeperiod.h"
#include "../../controls/controlutil.h" #include "../../controls/controlutil.h"
#include "../../controls/labelcolor.h" #include "../../controls/labelcolor.h"
#include "../../controls/labelspin.h" #include "../../controls/labelspin.h"
#include "../../controls/labelspincombo.h" #include "../../controls/labelspincombo.h"
#include "../../controls/listview.h"
#include "../optionscontroller.h" #include "../optionscontroller.h"
namespace { 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, const ValuesList quotaValues = { 10, 0, 100, 500, 1024, 8 * 1024, 10 * 1024, 30 * 1024, 50 * 1024,
100 * 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) : LabelSpin *createSpin(int v, int min, int max, const QString &suffix = {})
BasePage(ctrl, parent), m_isPageUpdating(false)
{ {
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<void(const QColor &color)> &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(); 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() void StatisticsPage::onRetranslateUi()
{ {
m_btRefresh->setText(tr("Refresh")); m_gbTraffic->setTitle(tr("Traffic"));
m_btClear->setText(tr("Clear")); 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_cbLogStat->setText(tr("Collect Traffic Statistics"));
m_cbLogStatNoFilter->setText(tr("Collect Traffic, when Filter Disabled")); m_cbLogStatNoFilter->setText(tr("Collect Traffic, when Filter Disabled"));
m_ctpActivePeriod->checkBox()->setText(tr("Active time period:")); m_ctpActivePeriod->checkBox()->setText(tr("Active time period:"));
@ -115,7 +98,6 @@ void StatisticsPage::onRetranslateUi()
retranslateQuotaNames(); retranslateQuotaNames();
retranslateIpKeepCountNames(); retranslateIpKeepCountNames();
m_btGraphOptions->setText(tr("Graph"));
m_cbGraphAlwaysOnTop->setText(tr("Always on top")); m_cbGraphAlwaysOnTop->setText(tr("Always on top"));
m_cbGraphFrameless->setText(tr("Frameless")); m_cbGraphFrameless->setText(tr("Frameless"));
m_cbGraphClickThrough->setText(tr("Click through")); m_cbGraphClickThrough->setText(tr("Click through"));
@ -130,13 +112,6 @@ void StatisticsPage::onRetranslateUi()
m_graphTickLabelColor->label()->setText(tr("Tick label:")); m_graphTickLabelColor->label()->setText(tr("Tick label:"));
m_graphLabelColor->label()->setText(tr("Label:")); m_graphLabelColor->label()->setText(tr("Label:"));
m_graphGridColor->label()->setText(tr("Grid:")); m_graphGridColor->label()->setText(tr("Grid:"));
m_traphUnits->setText(tr("Units:"));
retranslateTrafUnitNames();
retranslateTabBar();
m_appInfoRow->retranslateUi();
} }
void StatisticsPage::retranslateTrafKeepDayNames() void StatisticsPage::retranslateTrafKeepDayNames()
@ -183,283 +158,39 @@ void StatisticsPage::retranslateIpKeepCountNames()
m_lscBlockedIpKeepCount->setNames(list); 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() void StatisticsPage::setupUi()
{ {
auto layout = new QVBoxLayout(); // Column #1
auto colLayout1 = setupColumn1();
// Header // Column #2
auto header = setupHeader(); auto colLayout2 = setupColumn2();
layout->addLayout(header);
// Content // Main layout
m_splitter = new QSplitter(); auto layout = new QHBoxLayout();
layout->addLayout(colLayout1);
setupAppListView(); layout->addStretch();
m_splitter->addWidget(m_appListView); layout->addLayout(colLayout2);
layout->addStretch();
// 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); this->setLayout(layout);
} }
QLayout *StatisticsPage::setupHeader() QLayout *StatisticsPage::setupColumn1()
{ {
auto layout = new QHBoxLayout(); auto layout = new QVBoxLayout();
layout->setSpacing(10);
m_btRefresh = // Traffic Group Box
ControlUtil::createButton(":/icons/sign-sync.png", [&] { trafListModel()->reset(); }); 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->addStretch();
layout->addWidget(m_btGraphOptions);
layout->addWidget(m_btTrafOptions);
return layout; return layout;
} }
void StatisticsPage::setupClearMenu() void StatisticsPage::setupTrafficBox()
{
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<int>::of(&QSpinBox::valueChanged), this,
[&](int v) {
if (ini()->graphWindowOpacity() != v) {
ini()->setGraphWindowOpacity(v);
setIniEdited();
}
});
connect(m_graphHoverOpacity->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), this,
[&](int v) {
if (ini()->graphWindowHoverOpacity() != v) {
ini()->setGraphWindowHoverOpacity(v);
setIniEdited();
}
});
connect(m_graphMaxSeconds->spinBox(), QOverload<int>::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()
{ {
setupLogStat(); setupLogStat();
setupLogStatNoFilter(); setupLogStatNoFilter();
@ -473,23 +204,20 @@ void StatisticsPage::setupTrafOptionsMenu()
setupAllowedIpKeepCount(); setupAllowedIpKeepCount();
setupBlockedIpKeepCount(); setupBlockedIpKeepCount();
// Menu // Layout
const QList<QWidget *> menuWidgets = { m_cbLogStat, m_cbLogStatNoFilter, m_ctpActivePeriod, auto layout = ControlUtil::createLayoutByWidgets({ m_cbLogStat, m_cbLogStatNoFilter,
m_lscMonthStart, ControlUtil::createSeparator(), m_lscTrafHourKeepDays, m_ctpActivePeriod, m_lscMonthStart, ControlUtil::createSeparator(),
m_lscTrafDayKeepDays, m_lscTrafMonthKeepMonths, ControlUtil::createSeparator(), m_lscTrafHourKeepDays, m_lscTrafDayKeepDays, m_lscTrafMonthKeepMonths,
m_lscQuotaDayMb, m_lscQuotaMonthMb, ControlUtil::createSeparator(), m_lscAllowedIpKeepCount, ControlUtil::createSeparator(), m_lscQuotaDayMb, m_lscQuotaMonthMb,
m_lscBlockedIpKeepCount }; ControlUtil::createSeparator(), m_lscAllowedIpKeepCount, m_lscBlockedIpKeepCount });
auto layout = ControlUtil::createLayoutByWidgets(menuWidgets);
auto menu = ControlUtil::createMenuByLayout(layout, this); m_gbTraffic = new QGroupBox(this);
m_gbTraffic->setLayout(layout);
m_btTrafOptions = ControlUtil::createButton(":/icons/wrench.png");
m_btTrafOptions->setMenu(menu);
} }
void StatisticsPage::setupLogStat() void StatisticsPage::setupLogStat()
{ {
m_cbLogStat = ControlUtil::createCheckBox(false, [&](bool checked) { m_cbLogStat = ControlUtil::createCheckBox(conf()->logStat(), [&](bool checked) {
if (conf()->logStat() == checked) if (conf()->logStat() == checked)
return; return;
@ -503,7 +231,7 @@ void StatisticsPage::setupLogStat()
void StatisticsPage::setupLogStatNoFilter() void StatisticsPage::setupLogStatNoFilter()
{ {
m_cbLogStatNoFilter = ControlUtil::createCheckBox(false, [&](bool checked) { m_cbLogStatNoFilter = ControlUtil::createCheckBox(conf()->logStatNoFilter(), [&](bool checked) {
if (conf()->logStatNoFilter() == checked) if (conf()->logStatNoFilter() == checked)
return; return;
@ -516,6 +244,9 @@ void StatisticsPage::setupLogStatNoFilter()
void StatisticsPage::setupActivePeriod() void StatisticsPage::setupActivePeriod()
{ {
m_ctpActivePeriod = new CheckTimePeriod(); 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) { connect(m_ctpActivePeriod->checkBox(), &QCheckBox::toggled, this, [&](bool checked) {
if (conf()->activePeriodEnabled() == checked) if (conf()->activePeriodEnabled() == checked)
@ -551,7 +282,7 @@ void StatisticsPage::setupActivePeriod()
void StatisticsPage::setupMonthStart() void StatisticsPage::setupMonthStart()
{ {
m_lscMonthStart = createSpinCombo(1, 31); m_lscMonthStart = createSpinCombo(ini()->monthStart(), 1, 31);
// Days list // Days list
{ {
@ -568,288 +299,251 @@ void StatisticsPage::setupMonthStart()
[&](int value) { [&](int value) {
if (ini()->monthStart() != value) { if (ini()->monthStart() != value) {
ini()->setMonthStart(value); ini()->setMonthStart(value);
setIniEdited(); ctrl()->setIniEdited();
} }
}); });
} }
void StatisticsPage::setupTrafHourKeepDays() void StatisticsPage::setupTrafHourKeepDays()
{ {
m_lscTrafHourKeepDays = createSpinCombo(-1, 9999); m_lscTrafHourKeepDays = createSpinCombo(ini()->trafHourKeepDays(), -1, 9999, trafKeepDayValues);
m_lscTrafHourKeepDays->setValues(trafKeepDayValues);
connect(m_lscTrafHourKeepDays->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), this, connect(m_lscTrafHourKeepDays->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), this,
[&](int value) { [&](int value) {
if (ini()->trafHourKeepDays() != value) { if (ini()->trafHourKeepDays() != value) {
ini()->setTrafHourKeepDays(value); ini()->setTrafHourKeepDays(value);
setIniEdited(); ctrl()->setIniEdited();
} }
}); });
} }
void StatisticsPage::setupTrafDayKeepDays() void StatisticsPage::setupTrafDayKeepDays()
{ {
m_lscTrafDayKeepDays = createSpinCombo(-1, 9999); m_lscTrafDayKeepDays = createSpinCombo(ini()->trafDayKeepDays(), -1, 9999, trafKeepDayValues);
m_lscTrafDayKeepDays->setValues(trafKeepDayValues);
connect(m_lscTrafDayKeepDays->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), this, connect(m_lscTrafDayKeepDays->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), this,
[&](int value) { [&](int value) {
if (ini()->trafDayKeepDays() != value) { if (ini()->trafDayKeepDays() != value) {
ini()->setTrafDayKeepDays(value); ini()->setTrafDayKeepDays(value);
setIniEdited(); ctrl()->setIniEdited();
} }
}); });
} }
void StatisticsPage::setupTrafMonthKeepMonths() void StatisticsPage::setupTrafMonthKeepMonths()
{ {
m_lscTrafMonthKeepMonths = createSpinCombo(-1, 9999); m_lscTrafMonthKeepMonths =
m_lscTrafMonthKeepMonths->setValues(trafKeepMonthValues); createSpinCombo(ini()->trafMonthKeepMonths(), -1, 9999, trafKeepMonthValues);
connect(m_lscTrafMonthKeepMonths->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), this, connect(m_lscTrafMonthKeepMonths->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), this,
[&](int value) { [&](int value) {
if (ini()->trafMonthKeepMonths() != value) { if (ini()->trafMonthKeepMonths() != value) {
ini()->setTrafMonthKeepMonths(value); ini()->setTrafMonthKeepMonths(value);
setIniEdited(); ctrl()->setIniEdited();
} }
}); });
} }
void StatisticsPage::setupQuotaDayMb() void StatisticsPage::setupQuotaDayMb()
{ {
m_lscQuotaDayMb = createSpinCombo(0, 1024 * 1024, " MiB"); m_lscQuotaDayMb =
m_lscQuotaDayMb->setValues(quotaValues); createSpinCombo(int(ini()->quotaDayMb()), 0, 1024 * 1024, quotaValues, " MiB");
connect(m_lscQuotaDayMb->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), this, connect(m_lscQuotaDayMb->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), this,
[&](int value) { [&](int value) {
const quint32 mbytes = quint32(value); const quint32 mbytes = quint32(value);
if (ini()->quotaDayMb() != mbytes) { if (ini()->quotaDayMb() != mbytes) {
ini()->setQuotaDayMb(mbytes); ini()->setQuotaDayMb(mbytes);
setIniEdited(); ctrl()->setIniEdited();
} }
}); });
} }
void StatisticsPage::setupQuotaMonthMb() void StatisticsPage::setupQuotaMonthMb()
{ {
m_lscQuotaMonthMb = createSpinCombo(0, 1024 * 1024, " MiB"); m_lscQuotaMonthMb =
m_lscQuotaMonthMb->setValues(quotaValues); createSpinCombo(int(ini()->quotaMonthMb()), 0, 1024 * 1024, quotaValues, " MiB");
connect(m_lscQuotaMonthMb->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), this, connect(m_lscQuotaMonthMb->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), this,
[&](int value) { [&](int value) {
const quint32 mbytes = quint32(value); const quint32 mbytes = quint32(value);
if (ini()->quotaMonthMb() != mbytes) { if (ini()->quotaMonthMb() != mbytes) {
ini()->setQuotaMonthMb(mbytes); ini()->setQuotaMonthMb(mbytes);
setIniEdited(); ctrl()->setIniEdited();
} }
}); });
} }
void StatisticsPage::setupAllowedIpKeepCount() void StatisticsPage::setupAllowedIpKeepCount()
{ {
m_lscAllowedIpKeepCount = new LabelSpinCombo(); m_lscAllowedIpKeepCount =
m_lscAllowedIpKeepCount->spinBox()->setRange(0, 999999999); createSpinCombo(ini()->allowedIpKeepCount(), 0, 999999999, logIpKeepCountValues);
m_lscAllowedIpKeepCount->setValues(logIpKeepCountValues);
connect(m_lscAllowedIpKeepCount->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), this, connect(m_lscAllowedIpKeepCount->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), this,
[&](int value) { [&](int value) {
if (ini()->allowedIpKeepCount() != value) { if (ini()->allowedIpKeepCount() != value) {
ini()->setAllowedIpKeepCount(value); ini()->setAllowedIpKeepCount(value);
setIniEdited(); ctrl()->setIniEdited();
} }
}); });
} }
void StatisticsPage::setupBlockedIpKeepCount() void StatisticsPage::setupBlockedIpKeepCount()
{ {
m_lscBlockedIpKeepCount = new LabelSpinCombo(); m_lscBlockedIpKeepCount =
m_lscBlockedIpKeepCount->spinBox()->setRange(0, 999999999); createSpinCombo(ini()->blockedIpKeepCount(), 0, 999999999, logIpKeepCountValues);
m_lscBlockedIpKeepCount->setValues(logIpKeepCountValues);
connect(m_lscBlockedIpKeepCount->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), this, connect(m_lscBlockedIpKeepCount->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), this,
[&](int value) { [&](int value) {
if (ini()->blockedIpKeepCount() != value) { if (ini()->blockedIpKeepCount() != value) {
ini()->setBlockedIpKeepCount(value); ini()->setBlockedIpKeepCount(value);
setIniEdited(); ctrl()->setIniEdited();
} }
}); });
} }
void StatisticsPage::setupAppListView() QLayout *StatisticsPage::setupColumn2()
{ {
m_appListView = new ListView(); auto layout = new QVBoxLayout();
m_appListView->setFlow(QListView::TopToBottom); layout->setSpacing(10);
m_appListView->setViewMode(QListView::ListMode);
m_appListView->setIconSize(QSize(24, 24));
m_appListView->setUniformItemSizes(true);
m_appListView->setAlternatingRowColors(true);
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(); setupGraphCheckboxes();
m_tabBar->setShape(QTabBar::TriangularNorth); setupGraphOptions();
setupGraphColors();
for (int n = 4; --n >= 0;) { // Layout
m_tabBar->addTab(QString()); 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::setupGraphCheckboxes()
{
m_cbGraphAlwaysOnTop =
ControlUtil::createCheckBox(ini()->graphWindowAlwaysOnTop(), [&](bool checked) {
if (ini()->graphWindowAlwaysOnTop() != checked) {
ini()->setGraphWindowAlwaysOnTop(checked);
ctrl()->setIniEdited();
} }
} });
m_cbGraphFrameless =
void StatisticsPage::setupTableTraf() ControlUtil::createCheckBox(ini()->graphWindowFrameless(), [&](bool checked) {
{ if (ini()->graphWindowFrameless() != checked) {
m_tableTraf = new QTableView(); ini()->setGraphWindowFrameless(checked);
m_tableTraf->setSelectionMode(QAbstractItemView::SingleSelection); ctrl()->setIniEdited();
m_tableTraf->setSelectionBehavior(QAbstractItemView::SelectItems);
m_tableTraf->setModel(trafListModel());
const auto resetTableTraf = [&] {
trafListModel()->setType(static_cast<TrafListModel::TrafType>(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 StatisticsPage::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 StatisticsPage::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 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<TrafListModel::TrafUnit>(iniUser()->statTrafUnit());
if (trafListModel()->unit() != trafUnit) {
trafListModel()->setUnit(trafUnit);
trafListModel()->refresh();
} }
});
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();
}
});
} }
int StatisticsPage::appListCurrentIndex() const void StatisticsPage::setupGraphOptions()
{ {
return m_appListView->currentRow(); m_graphOpacity = createSpin(ini()->graphWindowOpacity(), 0, 100, " %");
m_graphHoverOpacity = createSpin(ini()->graphWindowHoverOpacity(), 0, 100, " %");
m_graphMaxSeconds = createSpin(ini()->graphWindowMaxSeconds(), 0, 9999);
connect(m_graphOpacity->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), this,
[&](int v) {
if (ini()->graphWindowOpacity() != v) {
ini()->setGraphWindowOpacity(v);
ctrl()->setIniEdited();
}
});
connect(m_graphHoverOpacity->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), this,
[&](int v) {
if (ini()->graphWindowHoverOpacity() != v) {
ini()->setGraphWindowHoverOpacity(v);
ctrl()->setIniEdited();
}
});
connect(m_graphMaxSeconds->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), this,
[&](int v) {
if (ini()->graphWindowMaxSeconds() != v) {
ini()->setGraphWindowMaxSeconds(v);
ctrl()->setIniEdited();
}
});
} }
QString StatisticsPage::appListCurrentPath() const void StatisticsPage::setupGraphColors()
{ {
return appStatModel()->appPathByRow(appListCurrentIndex()); m_graphColor = createLabelColor(ini()->graphWindowColor(), [&](const QColor &v) {
} if (ini()->graphWindowColor() != v) {
ini()->setGraphWindowColor(v);
LabelSpinCombo *StatisticsPage::createSpinCombo(int min, int max, const QString &suffix) ctrl()->setIniEdited();
{ }
auto c = new LabelSpinCombo(); });
c->spinBox()->setRange(min, max); m_graphColorIn = createLabelColor(ini()->graphWindowColorIn(), [&](const QColor &v) {
c->spinBox()->setSuffix(suffix); if (ini()->graphWindowColorIn() != v) {
return c; ini()->setGraphWindowColorIn(v);
} ctrl()->setIniEdited();
}
LabelSpin *StatisticsPage::createSpin(int min, int max, const QString &suffix) });
{ m_graphColorOut = createLabelColor(ini()->graphWindowColorOut(), [&](const QColor &v) {
auto c = new LabelSpin(); if (ini()->graphWindowColorOut() != v) {
c->spinBox()->setRange(min, max); ini()->setGraphWindowColorOut(v);
c->spinBox()->setSuffix(suffix); ctrl()->setIniEdited();
return c; }
} });
m_graphAxisColor = createLabelColor(ini()->graphWindowAxisColor(), [&](const QColor &v) {
QString StatisticsPage::formatQuota(int mbytes) if (ini()->graphWindowAxisColor() != v) {
{ ini()->setGraphWindowAxisColor(v);
return NetUtil::formatDataSize1(qint64(mbytes) * 1024 * 1024); 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();
}
});
} }

View File

@ -1,38 +1,21 @@
#ifndef STATISTICSPAGE_H #ifndef STATISTICSPAGE_H
#define 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 CheckTimePeriod;
class LabelColor; class LabelColor;
class LabelSpin; class LabelSpin;
class LabelSpinCombo; class LabelSpinCombo;
class ListView;
class TrafListModel;
class StatisticsPage : public BasePage class StatisticsPage : public OptBasePage
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit StatisticsPage(OptionsController *ctrl = nullptr, QWidget *parent = nullptr); explicit StatisticsPage(OptionsController *ctrl = nullptr, QWidget *parent = nullptr);
AppStatModel *appStatModel() const;
AppInfoCache *appInfoCache() const;
TrafListModel *trafListModel() const { return m_trafListModel; }
void setIniEdited();
protected slots: protected slots:
void onSaveWindowState(IniUser *ini) override;
void onRestoreWindowState(IniUser *ini) override;
void onRetranslateUi() override; void onRetranslateUi() override;
private: private:
@ -40,20 +23,10 @@ private:
void retranslateTrafKeepMonthNames(); void retranslateTrafKeepMonthNames();
void retranslateQuotaNames(); void retranslateQuotaNames();
void retranslateIpKeepCountNames(); void retranslateIpKeepCountNames();
void retranslateTrafUnitNames();
void retranslateTabBar();
void setupTrafListModel();
void setupUi(); void setupUi();
QLayout *setupHeader(); QLayout *setupColumn1();
void setupClearMenu(); void setupTrafficBox();
void setupTrafUnits();
void setupGraphOptionsMenu();
void setupGraphCheckboxes();
void setupGraphOptions();
void setupGraphColors();
void setupTrafOptionsMenu();
void setupLogStat(); void setupLogStat();
void setupLogStatNoFilter(); void setupLogStatNoFilter();
void setupActivePeriod(); void setupActivePeriod();
@ -65,37 +38,26 @@ private:
void setupQuotaMonthMb(); void setupQuotaMonthMb();
void setupAllowedIpKeepCount(); void setupAllowedIpKeepCount();
void setupBlockedIpKeepCount(); void setupBlockedIpKeepCount();
void setupAppListView(); QLayout *setupColumn2();
void setupTabBar(); void setupGraphBox();
void setupTableTraf(); void setupGraphCheckboxes();
void setupTableTrafHeader(); void setupGraphOptions();
void setupAppInfoRow(); void setupGraphColors();
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);
private: private:
bool m_isPageUpdating : 1; QGroupBox *m_gbTraffic = nullptr;
QGroupBox *m_gbGraph = nullptr;
TrafListModel *m_trafListModel = nullptr; QCheckBox *m_cbLogStat = nullptr;
QCheckBox *m_cbLogStatNoFilter = nullptr;
QPushButton *m_btRefresh = nullptr; CheckTimePeriod *m_ctpActivePeriod = nullptr;
QPushButton *m_btClear = nullptr; LabelSpinCombo *m_lscMonthStart = nullptr;
QAction *m_actRemoveApp = nullptr; LabelSpinCombo *m_lscTrafHourKeepDays = nullptr;
QAction *m_actResetTotal = nullptr; LabelSpinCombo *m_lscTrafDayKeepDays = nullptr;
QAction *m_actClearAll = nullptr; LabelSpinCombo *m_lscTrafMonthKeepMonths = nullptr;
QLabel *m_traphUnits = nullptr; LabelSpinCombo *m_lscQuotaDayMb = nullptr;
QComboBox *m_comboTrafUnit = nullptr; LabelSpinCombo *m_lscQuotaMonthMb = nullptr;
QPushButton *m_btGraphOptions = nullptr; LabelSpinCombo *m_lscAllowedIpKeepCount = nullptr;
LabelSpinCombo *m_lscBlockedIpKeepCount = nullptr;
QCheckBox *m_cbGraphAlwaysOnTop = nullptr; QCheckBox *m_cbGraphAlwaysOnTop = nullptr;
QCheckBox *m_cbGraphFrameless = nullptr; QCheckBox *m_cbGraphFrameless = nullptr;
QCheckBox *m_cbGraphClickThrough = nullptr; QCheckBox *m_cbGraphClickThrough = nullptr;
@ -110,23 +72,6 @@ private:
LabelColor *m_graphTickLabelColor = nullptr; LabelColor *m_graphTickLabelColor = nullptr;
LabelColor *m_graphLabelColor = nullptr; LabelColor *m_graphLabelColor = nullptr;
LabelColor *m_graphGridColor = 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 #endif // STATISTICSPAGE_H

View File

@ -0,0 +1,327 @@
#include "connectionspage.h"
#include <QCheckBox>
#include <QHeaderView>
#include <QMenu>
#include <QPushButton>
#include <QVBoxLayout>
#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<QWidget *> 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;
}

View File

@ -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

View File

@ -0,0 +1,56 @@
#include "statbasepage.h"
#include <QAbstractButton>
#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);
}

View File

@ -0,0 +1,53 @@
#ifndef STATBASEPAGE_H
#define STATBASEPAGE_H
#include <QFrame>
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

View File

@ -0,0 +1,46 @@
#include "statmainpage.h"
#include <QIcon>
#include <QPushButton>
#include <QTabWidget>
#include <QVBoxLayout>
#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());
}

View File

@ -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

View File

@ -0,0 +1,319 @@
#include "trafficpage.h"
#include <QAction>
#include <QComboBox>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QLabel>
#include <QMenu>
#include <QPushButton>
#include <QSplitter>
#include <QTabBar>
#include <QTableView>
#include <QTimeEdit>
#include <QVBoxLayout>
#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<TrafListModel::TrafType>(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<TrafListModel::TrafUnit>(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());
}

View File

@ -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

View File

@ -29,6 +29,9 @@ public:
TranslationManager *translationManager() const; TranslationManager *translationManager() const;
signals: signals:
void afterSaveWindowState(IniUser *ini);
void afterRestoreWindowState(IniUser *ini);
void retranslateUi(); void retranslateUi();
private: private:

View File

@ -1,32 +1,14 @@
#include "statisticswindow.h" #include "statisticswindow.h"
#include <QCheckBox>
#include <QHeaderView>
#include <QMenu>
#include <QPushButton>
#include <QVBoxLayout> #include <QVBoxLayout>
#include "../../appinfo/appinfocache.h"
#include "../../conf/confmanager.h" #include "../../conf/confmanager.h"
#include "../../conf/firewallconf.h"
#include "../../fortmanager.h"
#include "../../fortsettings.h"
#include "../../model/connlistmodel.h"
#include "../../user/iniuser.h" #include "../../user/iniuser.h"
#include "../../util/guiutil.h" #include "../../util/guiutil.h"
#include "../../util/iconcache.h"
#include "../../util/window/widgetwindowstatewatcher.h" #include "../../util/window/widgetwindowstatewatcher.h"
#include "../controls/appinforow.h" #include "pages/statmainpage.h"
#include "../controls/controlutil.h"
#include "../controls/tableview.h"
#include "statisticscontroller.h" #include "statisticscontroller.h"
namespace {
#define CONN_LIST_HEADER_VERSION 1
}
StatisticsWindow::StatisticsWindow(FortManager *fortManager, QWidget *parent) : StatisticsWindow::StatisticsWindow(FortManager *fortManager, QWidget *parent) :
WidgetWindow(parent), WidgetWindow(parent),
m_ctrl(new StatisticsController(fortManager, this)), m_ctrl(new StatisticsController(fortManager, this)),
@ -35,19 +17,6 @@ StatisticsWindow::StatisticsWindow(FortManager *fortManager, QWidget *parent) :
setupUi(); setupUi();
setupController(); setupController();
setupStateWatcher(); setupStateWatcher();
syncAutoScroll();
syncShowHostNames();
}
FortManager *StatisticsWindow::fortManager() const
{
return ctrl()->fortManager();
}
FortSettings *StatisticsWindow::settings() const
{
return ctrl()->settings();
} }
ConfManager *StatisticsWindow::confManager() const ConfManager *StatisticsWindow::confManager() const
@ -55,39 +24,17 @@ ConfManager *StatisticsWindow::confManager() const
return ctrl()->confManager(); return ctrl()->confManager();
} }
FirewallConf *StatisticsWindow::conf() const
{
return ctrl()->conf();
}
IniOptions *StatisticsWindow::ini() const
{
return ctrl()->ini();
}
IniUser *StatisticsWindow::iniUser() const IniUser *StatisticsWindow::iniUser() const
{ {
return ctrl()->iniUser(); return ctrl()->iniUser();
} }
ConnListModel *StatisticsWindow::connListModel() const
{
return fortManager()->connListModel();
}
AppInfoCache *StatisticsWindow::appInfoCache() const
{
return connListModel()->appInfoCache();
}
void StatisticsWindow::saveWindowState() void StatisticsWindow::saveWindowState()
{ {
iniUser()->setStatWindowGeometry(m_stateWatcher->geometry()); iniUser()->setStatWindowGeometry(m_stateWatcher->geometry());
iniUser()->setStatWindowMaximized(m_stateWatcher->maximized()); iniUser()->setStatWindowMaximized(m_stateWatcher->maximized());
auto header = m_connListView->horizontalHeader(); emit ctrl()->afterSaveWindowState(iniUser());
iniUser()->setConnListHeader(header->saveState());
iniUser()->setConnListHeaderVersion(CONN_LIST_HEADER_VERSION);
confManager()->saveIniUser(); confManager()->saveIniUser();
} }
@ -97,17 +44,14 @@ void StatisticsWindow::restoreWindowState()
m_stateWatcher->restore(this, QSize(1024, 768), iniUser()->statWindowGeometry(), m_stateWatcher->restore(this, QSize(1024, 768), iniUser()->statWindowGeometry(),
iniUser()->statWindowMaximized()); iniUser()->statWindowMaximized());
if (iniUser()->connListHeaderVersion() == CONN_LIST_HEADER_VERSION) { emit ctrl()->afterRestoreWindowState(iniUser());
auto header = m_connListView->horizontalHeader();
header->restoreState(iniUser()->connListHeader());
}
} }
void StatisticsWindow::setupController() void StatisticsWindow::setupController()
{ {
connect(ctrl(), &StatisticsController::retranslateUi, this, &StatisticsWindow::retranslateUi); connect(ctrl(), &StatisticsController::retranslateUi, this, &StatisticsWindow::retranslateUi);
retranslateUi(); emit ctrl()->retranslateUi();
} }
void StatisticsWindow::setupStateWatcher() void StatisticsWindow::setupStateWatcher()
@ -119,45 +63,16 @@ void StatisticsWindow::retranslateUi()
{ {
this->unsetLocale(); 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")); this->setWindowTitle(tr("Statistics"));
} }
void StatisticsWindow::setupUi() void StatisticsWindow::setupUi()
{ {
auto layout = new QVBoxLayout(); auto layout = new QVBoxLayout();
layout->setContentsMargins(6, 6, 6, 6); layout->setContentsMargins(0, 0, 0, 0);
// Header m_mainPage = new StatMainPage(ctrl());
auto header = setupHeader(); layout->addWidget(m_mainPage);
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); this->setLayout(layout);
@ -170,229 +85,3 @@ void StatisticsWindow::setupUi()
// Size // Size
this->setMinimumSize(500, 400); 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<QWidget *> 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;
}

View File

@ -3,20 +3,11 @@
#include "../../util/window/widgetwindow.h" #include "../../util/window/widgetwindow.h"
QT_FORWARD_DECLARE_CLASS(QCheckBox)
QT_FORWARD_DECLARE_CLASS(QPushButton)
class AppInfoCache;
class AppInfoRow;
class ConfManager; class ConfManager;
class ConnListModel;
class StatisticsController;
class FirewallConf;
class FortManager; class FortManager;
class FortSettings;
class IniOptions;
class IniUser; class IniUser;
class TableView; class StatMainPage;
class StatisticsController;
class WidgetWindowStateWatcher; class WidgetWindowStateWatcher;
class StatisticsWindow : public WidgetWindow class StatisticsWindow : public WidgetWindow
@ -27,14 +18,8 @@ public:
explicit StatisticsWindow(FortManager *fortManager, QWidget *parent = nullptr); explicit StatisticsWindow(FortManager *fortManager, QWidget *parent = nullptr);
StatisticsController *ctrl() const { return m_ctrl; } StatisticsController *ctrl() const { return m_ctrl; }
FortManager *fortManager() const;
FortSettings *settings() const;
ConfManager *confManager() const; ConfManager *confManager() const;
FirewallConf *conf() const;
IniOptions *ini() const;
IniUser *iniUser() const; IniUser *iniUser() const;
ConnListModel *connListModel() const;
AppInfoCache *appInfoCache() const;
void saveWindowState(); void saveWindowState();
void restoreWindowState(); void restoreWindowState();
@ -46,41 +31,12 @@ private:
void retranslateUi(); void retranslateUi();
void setupUi(); 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: private:
StatisticsController *m_ctrl = nullptr; StatisticsController *m_ctrl = nullptr;
WidgetWindowStateWatcher *m_stateWatcher = nullptr; WidgetWindowStateWatcher *m_stateWatcher = nullptr;
QPushButton *m_btEdit = nullptr; StatMainPage *m_mainPage = 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 // STATISTICSWINDOW_H #endif // STATISTICSWINDOW_H

View File

@ -62,9 +62,6 @@ public:
QByteArray optWindowAppsSplit() const { return valueByteArray("optWindow/appsSplit"); } QByteArray optWindowAppsSplit() const { return valueByteArray("optWindow/appsSplit"); }
void setOptWindowAppsSplit(const QByteArray &v) { setValue("optWindow/appsSplit", v); } 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(); } QRect zoneWindowGeometry() const { return value("zoneWindow/geometry").toRect(); }
void setZoneWindowGeometry(const QRect &v) { setValue("zoneWindow/geometry", v); } void setZoneWindowGeometry(const QRect &v) { setValue("zoneWindow/geometry", v); }
@ -95,6 +92,9 @@ public:
int statTrafUnit() const { return valueInt("statWindow/trafUnit"); } int statTrafUnit() const { return valueInt("statWindow/trafUnit"); }
void setStatTrafUnit(int v) { setValue("statWindow/trafUnit", v); } 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"); } int connListHeaderVersion() const { return valueInt("statWindow/connListHeaderVersion"); }
void setConnListHeaderVersion(int v) { setValue("statWindow/connListHeaderVersion", v); } void setConnListHeaderVersion(int v) { setValue("statWindow/connListHeaderVersion", v); }

View File

@ -22,6 +22,7 @@ void UserSettings::migrateIniOnStartup()
// COMPAT: v3.4.0: .ini ~> .user.ini // COMPAT: v3.4.0: .ini ~> .user.ini
if (version < 0x030400) { if (version < 0x030400) {
setCacheValue("statWindow/trafUnit", ini()->value("stat/trafUnit")); setCacheValue("statWindow/trafUnit", ini()->value("stat/trafUnit"));
setCacheValue("statWindow/trafSplit", ini()->value("optWindow/statSplit"));
setCacheValue("statWindow/geometry", ini()->value("connWindow/geometry")); setCacheValue("statWindow/geometry", ini()->value("connWindow/geometry"));
setCacheValue("statWindow/connListHeader", ini()->value("connWindow/connListHeader")); setCacheValue("statWindow/connListHeader", ini()->value("connWindow/connListHeader"));
setCacheValue("statWindow/connListHeaderVersion", setCacheValue("statWindow/connListHeaderVersion",
@ -62,9 +63,11 @@ void UserSettings::migrateIniOnWrite()
removeIniKey("graphWindow/tickLabelColor"); removeIniKey("graphWindow/tickLabelColor");
removeIniKey("graphWindow/labelColor"); removeIniKey("graphWindow/labelColor");
removeIniKey("graphWindow/gridColor"); removeIniKey("graphWindow/gridColor");
removeIniKey("optWindow/statSplit");
removeIniKey("connWindow"); removeIniKey("connWindow");
ini()->setValue("statWindow/trafUnit", cacheValue("statWindow/trafUnit"));
ini()->setValue("statWindow/geometry", cacheValue("statWindow/geometry")); 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/connListHeader", cacheValue("statWindow/connListHeader"));
ini()->setValue( ini()->setValue(
"statWindow/connListHeaderVersion", cacheValue("statWindow/connListHeaderVersion")); "statWindow/connListHeaderVersion", cacheValue("statWindow/connListHeaderVersion"));