diff --git a/src/ui/FortFirewall.pro b/src/ui/FortFirewall.pro index fad8ce49..8738e2a5 100644 --- a/src/ui/FortFirewall.pro +++ b/src/ui/FortFirewall.pro @@ -24,6 +24,7 @@ SOURCES += \ form/controls/labelcolor.cpp \ form/controls/labelspin.cpp \ form/controls/labelspincombo.cpp \ + form/controls/listview.cpp \ form/controls/spincombo.cpp \ form/controls/tabbar.cpp \ form/controls/textarea2splitter.cpp \ @@ -38,7 +39,6 @@ SOURCES += \ form/opt/pages/applicationspage.cpp \ form/opt/pages/apps/appscolumn.cpp \ form/opt/pages/basepage.cpp \ - form/opt/pages/log/applistview.cpp \ form/opt/pages/mainpage.cpp \ form/opt/pages/optionspage.cpp \ form/opt/pages/schedulepage.cpp \ @@ -121,6 +121,7 @@ HEADERS += \ form/controls/labelcolor.h \ form/controls/labelspin.h \ form/controls/labelspincombo.h \ + form/controls/listview.h \ form/controls/spincombo.h \ form/controls/tabbar.h \ form/controls/textarea2splitter.h \ @@ -135,7 +136,6 @@ HEADERS += \ form/opt/pages/applicationspage.h \ form/opt/pages/apps/appscolumn.h \ form/opt/pages/basepage.h \ - form/opt/pages/log/applistview.h \ form/opt/pages/mainpage.h \ form/opt/pages/optionspage.h \ form/opt/pages/schedulepage.h \ diff --git a/src/ui/conf/firewallconf.cpp b/src/ui/conf/firewallconf.cpp index 24c7a7bb..daababf3 100644 --- a/src/ui/conf/firewallconf.cpp +++ b/src/ui/conf/firewallconf.cpp @@ -22,7 +22,7 @@ FirewallConf::FirewallConf(QObject *parent) : m_trafHourKeepDays(DEFAULT_TRAF_HOUR_KEEP_DAYS), m_trafDayKeepDays(DEFAULT_TRAF_DAY_KEEP_DAYS), m_trafMonthKeepMonths(DEFAULT_TRAF_MONTH_KEEP_MONTHS), - m_trafUnit(UnitAdaptive), + m_trafUnit(0), m_quotaDayMb(0), m_quotaMonthMb(0) { @@ -168,7 +168,7 @@ void FirewallConf::setTrafMonthKeepMonths(int trafMonthKeepMonths) void FirewallConf::setTrafUnit(int trafUnit) { if (m_trafUnit != trafUnit) { - m_trafUnit = static_cast(trafUnit); + m_trafUnit = trafUnit; emit trafUnitChanged(); } } diff --git a/src/ui/conf/firewallconf.h b/src/ui/conf/firewallconf.h index f7d1c17d..1c580940 100644 --- a/src/ui/conf/firewallconf.h +++ b/src/ui/conf/firewallconf.h @@ -40,16 +40,6 @@ class FirewallConf : public QObject Q_CLASSINFO("DefaultProperty", "appGroups") public: - enum TrafUnit { - UnitAdaptive = 0, - UnitBytes, - UnitKB, - UnitMB, - UnitGB, - UnitTB - }; - Q_ENUM(TrafUnit) - explicit FirewallConf(QObject *parent = nullptr); bool provBoot() const { return m_provBoot; } @@ -193,7 +183,7 @@ private: int m_trafDayKeepDays; int m_trafMonthKeepMonths; - TrafUnit m_trafUnit; + int m_trafUnit; quint32 m_quotaDayMb; quint32 m_quotaMonthMb; diff --git a/src/ui/form/controls/listview.cpp b/src/ui/form/controls/listview.cpp new file mode 100644 index 00000000..479fe86d --- /dev/null +++ b/src/ui/form/controls/listview.cpp @@ -0,0 +1,14 @@ +#include "listview.h" + +ListView::ListView(QWidget *parent) : + QListView(parent) +{ +} + +void ListView::currentChanged(const QModelIndex ¤t, + const QModelIndex &previous) +{ + QListView::currentChanged(current, previous); + + emit currentIndexChanged(current); +} diff --git a/src/ui/form/controls/listview.h b/src/ui/form/controls/listview.h new file mode 100644 index 00000000..349e9fd1 --- /dev/null +++ b/src/ui/form/controls/listview.h @@ -0,0 +1,21 @@ +#ifndef LISTVIEW_H +#define LISTVIEW_H + +#include + +class ListView : public QListView +{ + Q_OBJECT + +public: + explicit ListView(QWidget *parent = nullptr); + +signals: + void currentIndexChanged(const QModelIndex &index); + +protected: + void currentChanged(const QModelIndex ¤t, + const QModelIndex &previous) override; +}; + +#endif // LISTVIEW_H diff --git a/src/ui/form/opt/pages/applicationspage.cpp b/src/ui/form/opt/pages/applicationspage.cpp index b9ecea9e..9dd8bb3e 100644 --- a/src/ui/form/opt/pages/applicationspage.cpp +++ b/src/ui/form/opt/pages/applicationspage.cpp @@ -51,6 +51,16 @@ void ApplicationsPage::setAppGroup(AppGroup *v) } } +void ApplicationsPage::onSaveWindowState() +{ + settings()->setOptWindowAppsSplit(m_splitter->saveState()); +} + +void ApplicationsPage::onRestoreWindowState() +{ + m_splitter->restoreState(settings()->optWindowAppsSplit()); +} + void ApplicationsPage::onRetranslateUi() { m_editGroupName->setPlaceholderText(tr("Group Name")); @@ -99,16 +109,6 @@ void ApplicationsPage::retranslateGroupLimits() m_cscLimitOut->setNames(list); } -void ApplicationsPage::onSaveWindowState() -{ - settings()->setOptWindowAppsSplit(m_splitter->saveState()); -} - -void ApplicationsPage::onRestoreWindowState() -{ - m_splitter->restoreState(settings()->optWindowAppsSplit()); -} - void ApplicationsPage::setupUi() { auto layout = new QVBoxLayout(); diff --git a/src/ui/form/opt/pages/applicationspage.h b/src/ui/form/opt/pages/applicationspage.h index 9c25f63b..b9cb829d 100644 --- a/src/ui/form/opt/pages/applicationspage.h +++ b/src/ui/form/opt/pages/applicationspage.h @@ -25,11 +25,11 @@ signals: void appGroupChanged(); protected slots: - void onRetranslateUi() override; - void onSaveWindowState() override; void onRestoreWindowState() override; + void onRetranslateUi() override; + private: void retranslateGroupLimits(); diff --git a/src/ui/form/opt/pages/basepage.cpp b/src/ui/form/opt/pages/basepage.cpp index e267e794..f26a563b 100644 --- a/src/ui/form/opt/pages/basepage.cpp +++ b/src/ui/form/opt/pages/basepage.cpp @@ -52,10 +52,10 @@ void BasePage::setupController() connect(ctrl(), &OptionsController::aboutToSave, this, &BasePage::onAboutToSave); connect(ctrl(), &OptionsController::saved, this, &BasePage::onSaved); - connect(ctrl(), &OptionsController::retranslateUi, this, &BasePage::onRetranslateUi); - connect(fortManager(), &FortManager::afterSaveOptWindowState, this, &BasePage::onSaveWindowState); connect(fortManager(), &FortManager::afterRestoreOptWindowState, this, &BasePage::onRestoreWindowState); + + connect(ctrl(), &OptionsController::retranslateUi, this, &BasePage::onRetranslateUi); } bool BasePage::openUrlExternally(const QUrl &url) diff --git a/src/ui/form/opt/pages/basepage.h b/src/ui/form/opt/pages/basepage.h index 08933fec..3b213150 100644 --- a/src/ui/form/opt/pages/basepage.h +++ b/src/ui/form/opt/pages/basepage.h @@ -43,11 +43,11 @@ protected slots: virtual void onAboutToSave() {} virtual void onSaved() {} - virtual void onRetranslateUi() {} - virtual void onSaveWindowState() {} virtual void onRestoreWindowState() {} + virtual void onRetranslateUi() {} + bool openUrlExternally(const QUrl &url); void onLinkClicked(); diff --git a/src/ui/form/opt/pages/log/applistview.cpp b/src/ui/form/opt/pages/log/applistview.cpp deleted file mode 100644 index 2633c364..00000000 --- a/src/ui/form/opt/pages/log/applistview.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "applistview.h" - -AppListView::AppListView(QWidget *parent) : - QListView(parent) -{ - setupUi(); -} - -void AppListView::setupUi() -{ - this->setFlow(QListView::TopToBottom); - this->setViewMode(QListView::ListMode); - this->setItemAlignment(Qt::AlignLeft); - this->setIconSize(QSize(24, 24)); - this->setUniformItemSizes(true); - this->setAlternatingRowColors(true); -} diff --git a/src/ui/form/opt/pages/log/applistview.h b/src/ui/form/opt/pages/log/applistview.h deleted file mode 100644 index 5f99302e..00000000 --- a/src/ui/form/opt/pages/log/applistview.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef APPLISTVIEW_H -#define APPLISTVIEW_H - -#include - -class AppListView : public QListView -{ - Q_OBJECT - -public: - explicit AppListView(QWidget *parent = nullptr); - -private: - void setupUi(); -}; - -#endif // APPLISTVIEW_H diff --git a/src/ui/form/opt/pages/statisticspage.cpp b/src/ui/form/opt/pages/statisticspage.cpp index 88caf1c8..05fd885e 100644 --- a/src/ui/form/opt/pages/statisticspage.cpp +++ b/src/ui/form/opt/pages/statisticspage.cpp @@ -4,10 +4,14 @@ #include #include #include +#include #include #include #include #include +#include +#include +#include #include #include @@ -17,14 +21,17 @@ #include "../../../log/logmanager.h" #include "../../../log/model/appstatmodel.h" #include "../../../log/model/traflistmodel.h" +#include "../../../util/app/appinfocache.h" +#include "../../../util/guiutil.h" #include "../../../util/net/netutil.h" +#include "../../../util/osutil.h" #include "../../controls/checktimeperiod.h" #include "../../controls/controlutil.h" #include "../../controls/labelcolor.h" #include "../../controls/labelspin.h" #include "../../controls/labelspincombo.h" +#include "../../controls/listview.h" #include "../optionscontroller.h" -#include "log/applistview.h" namespace { @@ -56,6 +63,22 @@ AppStatModel *StatisticsPage::appStatModel() const return fortManager()->logManager()->appStatModel(); } +AppInfoCache *StatisticsPage::appInfoCache() const +{ + return appStatModel()->appInfoCache(); +} + +void StatisticsPage::setGraphEdited(bool v) +{ + if (m_graphEdited != v) { + m_graphEdited = v; + + if (graphEdited()) { + ctrl()->setOthersEdited(true); + } + } +} + void StatisticsPage::onEditResetted() { setGraphEdited(false); @@ -85,15 +108,14 @@ void StatisticsPage::onSaved() fortManager()->updateGraphWindow(); } -void StatisticsPage::setGraphEdited(bool v) +void StatisticsPage::onSaveWindowState() { - if (m_graphEdited != v) { - m_graphEdited = v; + settings()->setOptWindowStatSplit(m_splitter->saveState()); +} - if (graphEdited()) { - ctrl()->setOthersEdited(true); - } - } +void StatisticsPage::onRestoreWindowState() +{ + m_splitter->restoreState(settings()->optWindowStatSplit()); } void StatisticsPage::onRetranslateUi() @@ -141,6 +163,10 @@ void StatisticsPage::onRetranslateUi() retranslateTrafUnitNames(); m_cbLogStat->setText(tr("Collect Traffic Statistics")); + + retranslateTabBar(); + + m_btAppCopyPath->setToolTip(tr("Copy Path")); } void StatisticsPage::retranslateTrafKeepDayNames() @@ -194,13 +220,27 @@ void StatisticsPage::retranslateTrafUnitNames() 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::retranslateAppOpenFolder() +{ + m_btAppOpenFolder->setToolTip(tr("Open Folder") + ' ' + + m_btAppOpenFolder->text()); +} + void StatisticsPage::setupTrafListModel() { m_trafListModel = appStatModel()->trafListModel(); - -// m_trafListModel->setType(static_cast(tabBar.currentIndex)); -// m_trafListModel->setAppId(appStatModel()->appIdByRow(appListView.currentIndex)); -// m_trafListModel->reset(); } void StatisticsPage::setupUi() @@ -212,9 +252,36 @@ void StatisticsPage::setupUi() layout->addLayout(header); // Content - setupAppListView(); + m_splitter = new QSplitter(); - layout->addWidget(m_appListView, 1); + setupAppListView(); + m_splitter->addWidget(m_appListView); + + // Tab Bar + auto trafLayout = new QVBoxLayout(); + trafLayout->setMargin(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(); + setupAppInfoVersion(); + layout->addWidget(m_appInfoRow); + + // Actions on app list view's current changed + setupAppListViewChanged(); this->setLayout(layout); } @@ -260,7 +327,7 @@ void StatisticsPage::setupClearMenu() if (!fortManager()->showQuestionBox(tr("Are you sure to remove statistics for selected application?"))) return; - //appStatModel()->remove(appListView.currentIndex); + appStatModel()->remove(appListCurrentIndex()); }); connect(m_actResetTotal, &QAction::triggered, [&] { if (!fortManager()->showQuestionBox(tr("Are you sure to reset total statistics?"))) @@ -272,7 +339,7 @@ void StatisticsPage::setupClearMenu() if (!fortManager()->showQuestionBox(tr("Are you sure to clear all statistics?"))) return; - //appListView.currentIndex = 0; + m_appListView->clearSelection(); appStatModel()->clear(); }); @@ -521,8 +588,6 @@ void StatisticsPage::setupTrafUnits() conf()->setTrafUnit(index); fortManager()->applyConfImmediateFlags(); - - trafListModel()->refresh(); }); } @@ -542,11 +607,140 @@ void StatisticsPage::setupLogStat() void StatisticsPage::setupAppListView() { - m_appListView = new AppListView(); + 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 StatisticsPage::setupTabBar() +{ + m_tabBar = new QTabBar(); + m_tabBar->setShape(QTabBar::TriangularNorth); + + for (int n = 4; --n >= 0; ) { + m_tabBar->addTab(QString()); + } +} + +void StatisticsPage::setupTableTraf() +{ + m_tableTraf = new QTableView(); + m_tableTraf->setSelectionMode(QAbstractItemView::SingleSelection); + m_tableTraf->setSelectionBehavior(QAbstractItemView::SelectItems); + + m_tableTraf->setModel(trafListModel()); + + const auto resetTableTraf = [&] { + trafListModel()->setType(static_cast(m_tabBar->currentIndex())); + trafListModel()->setAppId(appStatModel()->appIdByRow(appListCurrentIndex())); + trafListModel()->reset(); + }; + + resetTableTraf(); + + connect(m_tabBar, &QTabBar::currentChanged, this, resetTableTraf); + connect(m_appListView, &ListView::currentIndexChanged, this, resetTableTraf); + + const auto refreshTableTraf = [&] { + trafListModel()->setUnit(static_cast(conf()->trafUnit())); + trafListModel()->refresh(); + }; + + refreshTableTraf(); + + connect(conf(), &FirewallConf::trafUnitChanged, this, refreshTableTraf); +} + +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, qMin(qRound(hh->width() * 0.3), 180)); + }; + + refreshTableTrafHeader(); + + connect(header, &QHeaderView::geometriesChanged, this, refreshTableTrafHeader); +} + +void StatisticsPage::setupAppInfoRow() +{ + auto layout = new QHBoxLayout(); + layout->setMargin(0); + + m_btAppCopyPath = ControlUtil::createLinkButton(":/images/page_copy.png"); + m_btAppOpenFolder = ControlUtil::createLinkButton(QString()); + + m_labelAppProductName = new QLabel(); + m_labelAppProductName->setFont(ControlUtil::createFont(QFont::DemiBold)); + + m_labelAppCompanyName = new QLabel(); + + connect(m_btAppCopyPath, &QAbstractButton::clicked, [&] { + GuiUtil::setClipboardData(appListCurrentPath()); + }); + connect(m_btAppOpenFolder, &QAbstractButton::clicked, [&] { + OsUtil::openFolder(appListCurrentPath()); + }); + + layout->addWidget(m_btAppCopyPath); + layout->addWidget(m_btAppOpenFolder, 1, Qt::AlignLeft); + layout->addWidget(m_labelAppProductName); + layout->addWidget(m_labelAppCompanyName); + + m_appInfoRow = new QWidget(); + m_appInfoRow->setLayout(layout); +} + +void StatisticsPage::setupAppInfoVersion() +{ + const auto refreshAppInfoVersion = [&] { + const auto appPath = appListCurrentPath(); + const auto appInfo = appInfoCache()->appInfo(appPath); + + m_labelAppProductName->setVisible(!appInfo.productName.isEmpty()); + m_labelAppProductName->setText(appInfo.productName + " v" + appInfo.productVersion); + + m_labelAppCompanyName->setVisible(!appInfo.companyName.isEmpty()); + m_labelAppCompanyName->setText(appInfo.companyName); + }; + + refreshAppInfoVersion(); + + connect(m_appListView, &ListView::currentIndexChanged, this, refreshAppInfoVersion); + connect(appInfoCache(), &AppInfoCache::cacheChanged, this, refreshAppInfoVersion); +} + +void StatisticsPage::setupAppListViewChanged() +{ + const auto refreshAppListViewChanged = [&] { + const bool appSelected = (m_appListView->currentIndex().row() > 0); + m_actRemoveApp->setEnabled(appSelected); + m_appInfoRow->setVisible(appSelected); + + if (appSelected) { + m_btAppOpenFolder->setText(appListCurrentPath()); + retranslateAppOpenFolder(); + } + }; + + refreshAppListViewChanged(); + + connect(m_appListView, &ListView::currentIndexChanged, this , refreshAppListViewChanged); +} + void StatisticsPage::updatePage() { m_pageUpdating = true; @@ -593,6 +787,16 @@ void StatisticsPage::updateTrafUnit() m_comboTrafUnit->setCurrentIndex(conf()->trafUnit()); } +int StatisticsPage::appListCurrentIndex() const +{ + return m_appListView->currentIndex().row(); +} + +QString StatisticsPage::appListCurrentPath() const +{ + return appStatModel()->appPathByRow(appListCurrentIndex()); +} + LabelSpinCombo *StatisticsPage::createSpinCombo(int min, int max, const QString &suffix) { diff --git a/src/ui/form/opt/pages/statisticspage.h b/src/ui/form/opt/pages/statisticspage.h index 250ae714..c43881dc 100644 --- a/src/ui/form/opt/pages/statisticspage.h +++ b/src/ui/form/opt/pages/statisticspage.h @@ -3,14 +3,18 @@ #include "basepage.h" -QT_FORWARD_DECLARE_CLASS(AppListView) +QT_FORWARD_DECLARE_CLASS(AppInfoCache) QT_FORWARD_DECLARE_CLASS(AppStatModel) QT_FORWARD_DECLARE_CLASS(CheckTimePeriod) QT_FORWARD_DECLARE_CLASS(LabelColor) QT_FORWARD_DECLARE_CLASS(LabelSpin) QT_FORWARD_DECLARE_CLASS(LabelSpinCombo) +QT_FORWARD_DECLARE_CLASS(ListView) QT_FORWARD_DECLARE_CLASS(TrafListModel) +QT_FORWARD_DECLARE_CLASS(QSplitter) +QT_FORWARD_DECLARE_CLASS(QTableView) + class StatisticsPage : public BasePage { Q_OBJECT @@ -20,12 +24,16 @@ public: QWidget *parent = nullptr); AppStatModel *appStatModel() const; + AppInfoCache *appInfoCache() const; TrafListModel *trafListModel() const { return m_trafListModel; } protected slots: void onEditResetted() override; void onSaved() override; + void onSaveWindowState() override; + void onRestoreWindowState() override; + void onRetranslateUi() override; private: @@ -36,6 +44,8 @@ private: void retranslateTrafKeepMonthNames(); void retranslateQuotaNames(); void retranslateTrafUnitNames(); + void retranslateTabBar(); + void retranslateAppOpenFolder(); void setupTrafListModel(); @@ -54,9 +64,18 @@ private: void setupTrafUnits(); void setupLogStat(); void setupAppListView(); + void setupTabBar(); + void setupTableTraf(); + void setupTableTrafHeader(); + void setupAppInfoRow(); + void setupAppInfoVersion(); + void setupAppListViewChanged(); void updatePage(); void updateTrafUnit(); + int appListCurrentIndex() const; + QString appListCurrentPath() const; + static LabelSpinCombo *createSpinCombo(int min, int max, const QString &suffix = QString()); static LabelSpin *createSpin(int min, int max, @@ -101,7 +120,15 @@ private: QLabel *m_traphUnits = nullptr; QComboBox *m_comboTrafUnit = nullptr; QCheckBox *m_cbLogStat = nullptr; - AppListView *m_appListView = nullptr; + QSplitter *m_splitter = nullptr; + ListView *m_appListView = nullptr; + QTabBar *m_tabBar = nullptr; + QTableView *m_tableTraf = nullptr; + QWidget *m_appInfoRow = nullptr; + QPushButton *m_btAppCopyPath = nullptr; + QPushButton *m_btAppOpenFolder = nullptr; + QLabel *m_labelAppProductName = nullptr; + QLabel *m_labelAppCompanyName = nullptr; }; #endif // STATISTICSPAGE_H diff --git a/src/ui/fortsettings.h b/src/ui/fortsettings.h index 50a878a7..b7eec046 100644 --- a/src/ui/fortsettings.h +++ b/src/ui/fortsettings.h @@ -86,6 +86,9 @@ public: QByteArray optWindowAppsSplit() const { return iniByteArray("optWindow/appsSplit"); } void setOptWindowAppsSplit(const QByteArray &v) { setIniValue("optWindow/appsSplit", v); } + QByteArray optWindowStatSplit() const { return iniByteArray("optWindow/statSplit"); } + void setOptWindowStatSplit(const QByteArray &v) { setIniValue("optWindow/statSplit", v); } + bool graphWindowVisible() const { return iniBool("graphWindow/visible"); } void setGraphWindowVisible(bool on) { setIniValue("graphWindow/visible", on); } diff --git a/src/ui/log/model/appstatmodel.cpp b/src/ui/log/model/appstatmodel.cpp index d8b6a5fc..1e0b8e90 100644 --- a/src/ui/log/model/appstatmodel.cpp +++ b/src/ui/log/model/appstatmodel.cpp @@ -5,6 +5,7 @@ #include "../../stat/statmanager.h" #include "../../util/app/appinfo.h" #include "../../util/app/appinfocache.h" +#include "../../util/fileutil.h" #include "../logentryprocnew.h" #include "../logentrystattraf.h" #include "traflistmodel.h" @@ -26,8 +27,7 @@ void AppStatModel::setAppInfoCache(AppInfoCache *v) m_appInfoCache = v; - connect(appInfoCache(), &AppInfoCache::cacheChanged, - this, &AppStatModel::reset); + connect(appInfoCache(), &AppInfoCache::cacheChanged, this, &AppStatModel::reset); } void AppStatModel::initialize() @@ -47,6 +47,7 @@ void AppStatModel::clear() void AppStatModel::remove(int row) { row = adjustRow(row); + Q_ASSERT(row > 0); beginRemoveRows(QModelIndex(), row, row); @@ -98,6 +99,20 @@ qint64 AppStatModel::appIdByRow(int row) const ? 0 : m_appIds.at(row); } +QString AppStatModel::appPathByRow(int row) const +{ + return (row <= 0 || row >= list().size()) + ? QString() : list().at(row); +} + +Qt::ItemFlags AppStatModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::NoItemFlags; + + return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren; +} + QVariant AppStatModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) @@ -109,7 +124,13 @@ QVariant AppStatModel::data(const QModelIndex &index, int role) const if (row == 0) return tr("All"); - return list().at(row); + const auto appPath = list().at(row); + const auto appInfo = appInfoCache()->appInfo(appPath); + if (!appInfo.fileDescription.isEmpty()) { + return appInfo.fileDescription; + } + + return FileUtil::fileName(appPath); } // Icon diff --git a/src/ui/log/model/appstatmodel.h b/src/ui/log/model/appstatmodel.h index b2726ba5..fb8bd5d5 100644 --- a/src/ui/log/model/appstatmodel.h +++ b/src/ui/log/model/appstatmodel.h @@ -28,7 +28,9 @@ public: void handleStatTraf(const LogEntryStatTraf &statTrafEntry); qint64 appIdByRow(int row) const; + QString appPathByRow(int row) const; + Qt::ItemFlags flags(const QModelIndex &index) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; public slots: diff --git a/src/ui/log/model/traflistmodel.cpp b/src/ui/log/model/traflistmodel.cpp index 2bf2293a..8259a645 100644 --- a/src/ui/log/model/traflistmodel.cpp +++ b/src/ui/log/model/traflistmodel.cpp @@ -2,7 +2,6 @@ #include -#include "../../conf/firewallconf.h" #include "../../stat/statmanager.h" #include "../../stat/statsql.h" #include "../../util/dateutil.h" @@ -12,6 +11,7 @@ TrafListModel::TrafListModel(StatManager *statManager, QObject *parent) : QAbstractItemModel(parent), m_isEmpty(false), + m_unit(UnitAdaptive), m_type(TrafHourly), m_appId(0), m_minTrafTime(0), @@ -21,6 +21,11 @@ TrafListModel::TrafListModel(StatManager *statManager, { } +void TrafListModel::setUnit(TrafListModel::TrafUnit unit) +{ + m_unit = unit; +} + void TrafListModel::setType(TrafListModel::TrafType type) { m_type = type; @@ -70,9 +75,26 @@ bool TrafListModel::hasChildren(const QModelIndex &parent) const return !parent.isValid() && rowCount() > 0; } +QVariant TrafListModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal + && role == Qt::DisplayRole) { + switch (section) { + case 0: return tr("Date"); + case 1: return tr("Download"); + case 2: return tr("Upload"); + case 3: return tr("Sum"); + } + } + return QVariant(); +} + QVariant TrafListModel::data(const QModelIndex &index, int role) const { - if (index.isValid() && role == Qt::DisplayRole) { + if (!index.isValid()) + return QVariant(); + + if (role == Qt::DisplayRole) { const int row = index.row(); const int column = index.column(); @@ -87,6 +109,7 @@ QVariant TrafListModel::data(const QModelIndex &index, int role) const case 3: return formatTrafUnit(m_rowCache.inBytes + m_rowCache.outBytes); } } + return QVariant(); } @@ -176,15 +199,13 @@ QString TrafListModel::formatTrafUnit(qint64 bytes) const return QLatin1String("0"); } - const FirewallConf *conf = m_statManager->firewallConf(); - const int trafUnit = conf ? conf->trafUnit() : 0; - const int trafPrec = (trafUnit == FirewallConf::UnitBytes) ? 0 : 2; + const int trafPrec = (unit() == UnitBytes) ? 0 : 2; - if (trafUnit == FirewallConf::UnitAdaptive) { + if (unit() == UnitAdaptive) { return NetUtil::formatDataSize(bytes, trafPrec); } - const qint64 unitMult = unitMults.at(trafUnit); + const qint64 unitMult = unitMults.at(unit()); return QLocale::c().toString(qreal(bytes) / unitMult, 'f', trafPrec); } diff --git a/src/ui/log/model/traflistmodel.h b/src/ui/log/model/traflistmodel.h index 25faa533..79f51c86 100644 --- a/src/ui/log/model/traflistmodel.h +++ b/src/ui/log/model/traflistmodel.h @@ -20,6 +20,16 @@ class TrafListModel : public QAbstractItemModel Q_OBJECT public: + enum TrafUnit { + UnitAdaptive = 0, + UnitBytes, + UnitKB, + UnitMB, + UnitGB, + UnitTB + }; + Q_ENUM(TrafUnit) + enum TrafType { TrafHourly = 0, TrafDaily, @@ -31,6 +41,9 @@ public: explicit TrafListModel(StatManager *statManager, QObject *parent = nullptr); + TrafListModel::TrafUnit unit() const { return m_unit; } + void setUnit(TrafListModel::TrafUnit unit); + TrafListModel::TrafType type() const { return m_type; } void setType(TrafListModel::TrafType type); @@ -47,12 +60,12 @@ public: int columnCount(const QModelIndex &parent = QModelIndex()) const override; bool hasChildren(const QModelIndex &parent = QModelIndex()) const override; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; -signals: - public slots: void clear(); @@ -80,6 +93,7 @@ private: private: bool m_isEmpty; + TrafUnit m_unit; TrafType m_type; qint64 m_appId; diff --git a/src/ui/util/app/appinfocache.cpp b/src/ui/util/app/appinfocache.cpp index 22b05148..2639c547 100644 --- a/src/ui/util/app/appinfocache.cpp +++ b/src/ui/util/app/appinfocache.cpp @@ -12,8 +12,7 @@ AppInfoCache::AppInfoCache(QObject *parent) : m_triggerTimer.setSingleShot(true); m_triggerTimer.setInterval(200); - connect(&m_triggerTimer, &QTimer::timeout, - this, &AppInfoCache::cacheChanged); + connect(&m_triggerTimer, &QTimer::timeout, this, &AppInfoCache::cacheChanged); } void AppInfoCache::setManager(AppInfoManager *manager) @@ -33,6 +32,9 @@ QImage AppInfoCache::appIcon(const AppInfo &info) const AppInfo AppInfoCache::appInfo(const QString &appPath) { + if (appPath.isEmpty()) + return AppInfo(); + AppInfo *appInfo = m_cache.object(appPath); bool lookupRequired = false; diff --git a/src/ui/util/app/appinfomanager.cpp b/src/ui/util/app/appinfomanager.cpp index dba69987..35787f10 100644 --- a/src/ui/util/app/appinfomanager.cpp +++ b/src/ui/util/app/appinfomanager.cpp @@ -182,6 +182,9 @@ bool AppInfoManager::loadInfoFromDb(const QString &appPath, AppInfo &appInfo) QImage AppInfoManager::loadIconFromDb(qint64 iconId) { + if (iconId == 0) + return {}; + QMutexLocker locker(&m_mutex); const QVariant icon = m_sqliteDb->executeEx( diff --git a/src/ui/util/app/appinfoworker.cpp b/src/ui/util/app/appinfoworker.cpp index d86d6384..f45feefb 100644 --- a/src/ui/util/app/appinfoworker.cpp +++ b/src/ui/util/app/appinfoworker.cpp @@ -5,6 +5,7 @@ #include "appinfo.h" #include "appinfomanager.h" #include "appinfojob.h" +#include "apputil.h" AppInfoWorker::AppInfoWorker(AppInfoManager *manager) : WorkerObject(manager) @@ -16,6 +17,15 @@ AppInfoManager *AppInfoWorker::manager() const return static_cast(WorkerObject::manager()); } +void AppInfoWorker::run() +{ + AppUtil::initThread(); + + WorkerObject::run(); + + AppUtil::doneThread(); +} + void AppInfoWorker::doJob(WorkerJob *workerJob) { auto job = static_cast(workerJob); diff --git a/src/ui/util/app/appinfoworker.h b/src/ui/util/app/appinfoworker.h index 43cc2e1d..3bd96de7 100644 --- a/src/ui/util/app/appinfoworker.h +++ b/src/ui/util/app/appinfoworker.h @@ -13,6 +13,8 @@ public: AppInfoManager *manager() const; + void run() override; + protected: void doJob(WorkerJob *workerJob) override; }; diff --git a/src/ui/util/app/apputil.cpp b/src/ui/util/app/apputil.cpp index 407622fa..27e98237 100644 --- a/src/ui/util/app/apputil.cpp +++ b/src/ui/util/app/apputil.cpp @@ -162,3 +162,13 @@ QDateTime AppUtil::getModTime(const QString &appPath) QFileInfo fi(appPath); return fi.lastModified(); } + +void AppUtil::initThread() +{ + CoInitialize(nullptr); +} + +void AppUtil::doneThread() +{ + CoUninitialize(); +} diff --git a/src/ui/util/app/apputil.h b/src/ui/util/app/apputil.h index d75020f5..4062d458 100644 --- a/src/ui/util/app/apputil.h +++ b/src/ui/util/app/apputil.h @@ -13,6 +13,9 @@ public: static bool getInfo(const QString &appPath, AppInfo &appInfo); static QImage getIcon(const QString &appPath); static QDateTime getModTime(const QString &appPath); + + static void initThread(); + static void doneThread(); }; #endif // APPUTIL_H