diff --git a/src/ui/conf/confmanager.cpp b/src/ui/conf/confmanager.cpp index f632bdfd..a71109c9 100644 --- a/src/ui/conf/confmanager.cpp +++ b/src/ui/conf/confmanager.cpp @@ -135,14 +135,29 @@ const char * const sqlSelectAppByIndex = const char * const sqlSelectApps = "SELECT g.order_index as group_index," - " t.blocked," - " (alert.app_id IS NOT NULL) as alerted," - " t.path" + " t.path, t.blocked," + " (alert.app_id IS NOT NULL) as alerted" " FROM app t" " JOIN app_group g ON g.app_group_id = t.app_group_id" " LEFT JOIN app_alert alert ON alert.app_id = t.app_id;" ; +const char * const sqlSelectEndAppsCount = + "SELECT COUNT(*) FROM app" + " WHERE end_time IS NOT NULL AND end_time != 0;" + ; + +const char * const sqlSelectEndedApps = + "SELECT t.app_id," + " g.order_index as group_index," + " t.path," + " (alert.app_id IS NOT NULL) as alerted" + " FROM app t" + " JOIN app_group g ON g.app_group_id = t.app_group_id" + " LEFT JOIN app_alert alert ON alert.app_id = t.app_id" + " WHERE end_time <= ?1;" + ; + const char * const sqlInsertApp = "INSERT INTO app(app_group_id, path, blocked," " creat_time, end_time)" @@ -187,6 +202,8 @@ ConfManager::ConfManager(const QString &filePath, m_fortSettings(fortSettings), m_sqliteDb(new SqliteDb(filePath)) { + m_appEndTimer.setInterval(5 * 60 * 1000); // 5 minutes + connect(&m_appEndTimer, &QTimer::timeout, this, &ConfManager::checkAppEndTimes); } ConfManager::~ConfManager() @@ -220,6 +237,8 @@ bool ConfManager::initialize() return false; } + m_appEndTimer.start(); + return true; } @@ -372,7 +391,7 @@ bool ConfManager::addApp(const QString &appPath, const QDateTime &endTime, << appPath << blocked << QDateTime::currentDateTime() - << endTime + << (!endTime.isNull() ? endTime : QVariant()) ; m_sqliteDb->executeEx(sqlInsertApp, vars, 0, &ok); @@ -394,6 +413,10 @@ end: m_sqliteDb->endTransaction(ok); + if (ok && !endTime.isNull()) { + m_appEndTimer.start(); + } + return ok; } @@ -431,7 +454,7 @@ bool ConfManager::updateApp(qint64 appId, const QDateTime &endTime, << appId << appGroupIdByIndex(groupIndex) << blocked - << endTime + << (!endTime.isNull() ? endTime : QVariant()) ; m_sqliteDb->executeEx(sqlUpdateApp, vars, 0, &ok); @@ -446,6 +469,10 @@ end: m_sqliteDb->endTransaction(ok); + if (ok && !endTime.isNull()) { + m_appEndTimer.start(); + } + return ok; } @@ -457,10 +484,10 @@ bool ConfManager::walkApps(std::function func) while (stmt.step() == SqliteStmt::StepRow) { const int groupIndex = stmt.columnInt(0); + const QString appPath = stmt.columnText(1); const bool useGroupPerm = false; - const bool blocked = stmt.columnBool(1); - const bool alerted = stmt.columnBool(2); - const QString appPath = stmt.columnText(3); + const bool blocked = stmt.columnBool(2); + const bool alerted = stmt.columnBool(3); if (!func(groupIndex, useGroupPerm, blocked, alerted, appPath)) return false; @@ -469,6 +496,53 @@ bool ConfManager::walkApps(std::function func) return true; } +int ConfManager::appEndsCount() +{ + SqliteStmt stmt; + if (!stmt.prepare(m_sqliteDb->db(), sqlSelectEndAppsCount) + || stmt.step() != SqliteStmt::StepRow) + return 0; + + return stmt.columnInt(0); +} + +void ConfManager::updateAppEndTimes() +{ + SqliteStmt stmt; + if (!stmt.prepare(m_sqliteDb->db(), sqlSelectEndedApps)) + return; + + stmt.bindDateTime(1, QDateTime::currentDateTime()); + + bool isAppEndTimesUpdated = false; + + while (stmt.step() == SqliteStmt::StepRow) { + const qint64 appId = stmt.columnInt64(0); + const int groupIndex = stmt.columnInt(1); + const QString appPath = stmt.columnText(3); + const bool alerted = stmt.columnBool(4); + + if (updateDriverUpdateApp(appPath, groupIndex, + false, true, alerted) + && updateApp(appId, QDateTime(), groupIndex, true)) { + isAppEndTimesUpdated = true; + } + } + + if (isAppEndTimesUpdated) { + emit appEndTimesUpdated(); + } +} + +void ConfManager::checkAppEndTimes() +{ + if (appEndsCount() == 0) { + m_appEndTimer.stop(); + } else { + updateAppEndTimes(); + } +} + bool ConfManager::updateDriverConf(const FirewallConf &conf, bool onlyFlags) { return onlyFlags diff --git a/src/ui/conf/confmanager.h b/src/ui/conf/confmanager.h index 21a166a9..71818515 100644 --- a/src/ui/conf/confmanager.h +++ b/src/ui/conf/confmanager.h @@ -2,6 +2,7 @@ #define CONFMANAGER_H #include +#include #include @@ -49,6 +50,7 @@ public: QString &appGroupName, QString &appPath, QDateTime &endTime, int row); qint64 appGroupIdByIndex(int index = 0); + bool addApp(const QString &appPath, const QDateTime &endTime, int groupIndex, bool blocked, bool alerted); bool deleteApp(qint64 appId); @@ -56,6 +58,10 @@ public: int groupIndex, bool blocked); bool walkApps(std::function func); + int appEndsCount(); + void updateAppEndTimes(); + void checkAppEndTimes(); + bool updateDriverConf(const FirewallConf &conf, bool onlyFlags = false); bool updateDriverDeleteApp(const QString &appPath); bool updateDriverUpdateApp(const QString &appPath, @@ -67,6 +73,7 @@ public: signals: void errorMessageChanged(); void confSaved(); + void appEndTimesUpdated(); private: void setErrorMessage(const QString &errorMessage); @@ -88,6 +95,8 @@ private: EnvManager *m_envManager = nullptr; FortSettings *m_fortSettings = nullptr; SqliteDb *m_sqliteDb = nullptr; + + QTimer m_appEndTimer; }; #endif // CONFMANAGER_H diff --git a/src/ui/form/prog/programswindow.cpp b/src/ui/form/prog/programswindow.cpp index 49f836ae..e7f4b1fc 100644 --- a/src/ui/form/prog/programswindow.cpp +++ b/src/ui/form/prog/programswindow.cpp @@ -175,31 +175,22 @@ QLayout *ProgramsWindow::setupHeader() m_btBlockApp = ControlUtil::createLinkButton(":/images/stop.png"); connect(m_btAddApp, &QAbstractButton::clicked, [&] { - const AppRow appRow; - updateAppEditForm(appRow); + updateAppEditForm(false); }); connect(m_btEditApp, &QAbstractButton::clicked, [&] { - const auto appIndex = appListCurrentIndex(); - if (appIndex >= 0) { - const auto appRow = appListModel()->appRow(appIndex); - updateAppEditForm(appRow); - } + updateAppEditForm(true); }); connect(m_btDeleteApp, &QAbstractButton::clicked, [&] { - if (!fortManager()->showQuestionBox(tr("Are you sure to remove the selected program?"))) - return; - - const int appIndex = appListCurrentIndex(); - appListModel()->deleteApp(appIndex); + if (fortManager()->showQuestionBox(tr("Are you sure to remove the selected program?"))) { + deleteCurrentApp(); + } }); connect(m_btAllowApp, &QAbstractButton::clicked, [&] { - const int appIndex = appListCurrentIndex(); - appListModel()->updateApp(appIndex, 0, false); + updateCurrentApp(false); }); connect(m_btBlockApp, &QAbstractButton::clicked, [&] { - const int appIndex = appListCurrentIndex(); - appListModel()->updateApp(appIndex, 0, true); + updateCurrentApp(true); }); setupLogBlocked(); @@ -310,8 +301,8 @@ void ProgramsWindow::setupAppEditForm() .addSecs(hours * 60 * 60); } - if (m_formAppIsEditing - ? appListModel()->updateApp(appListCurrentIndex(), + if (m_formAppId != 0 + ? appListModel()->updateApp(m_formAppId, appPath, groupIndex, blocked, endTime) : appListModel()->addApp(appPath, groupIndex, blocked, endTime)) { m_formAppEdit->close(); @@ -449,13 +440,22 @@ void ProgramsWindow::setupTableAppsChanged() connect(m_appListView, &TableView::currentIndexChanged, this, refreshTableAppsChanged); } -void ProgramsWindow::updateAppEditForm(const AppRow &appRow) +void ProgramsWindow::updateAppEditForm(bool editCurrentApp) { - m_formAppIsEditing = !appRow.appPath.isEmpty(); + AppRow appRow; + if (editCurrentApp) { + const auto appIndex = appListCurrentIndex(); + if (appIndex < 0) return; + + appRow = appListModel()->appRow(appIndex); + m_formAppId = appRow.appId; + } else { + m_formAppId = 0; + } m_editPath->setText(appRow.appPath); - m_editPath->setReadOnly(m_formAppIsEditing); - m_btSelectFile->setEnabled(!m_formAppIsEditing); + m_editPath->setReadOnly(editCurrentApp); + m_btSelectFile->setEnabled(!editCurrentApp); m_comboAppGroup->setCurrentIndex(appRow.groupIndex); m_rbAllowApp->setChecked(!appRow.blocked()); m_rbBlockApp->setChecked(appRow.blocked()); @@ -464,6 +464,25 @@ void ProgramsWindow::updateAppEditForm(const AppRow &appRow) m_formAppEdit->show(); } +void ProgramsWindow::updateCurrentApp(bool blocked) +{ + const int appIndex = appListCurrentIndex(); + if (appIndex >= 0) { + const auto appRow = appListModel()->appRow(appIndex); + appListModel()->updateApp(appRow.appId, appRow.appPath, + appRow.groupIndex, blocked); + } +} + +void ProgramsWindow::deleteCurrentApp() +{ + const int appIndex = appListCurrentIndex(); + if (appIndex >= 0) { + const auto appRow = appListModel()->appRow(appIndex); + appListModel()->deleteApp(appRow.appId, appRow.appPath); + } +} + int ProgramsWindow::appListCurrentIndex() const { return m_appListView->currentIndex().row(); diff --git a/src/ui/form/prog/programswindow.h b/src/ui/form/prog/programswindow.h index 3ea7fd1b..56f3c2c7 100644 --- a/src/ui/form/prog/programswindow.h +++ b/src/ui/form/prog/programswindow.h @@ -55,7 +55,10 @@ private: void setupAppInfoRow(); void setupAppInfoVersion(); void setupTableAppsChanged(); - void updateAppEditForm(const AppRow &appRow); + + void updateAppEditForm(bool editCurrentApp); + void updateCurrentApp(bool blocked); + void deleteCurrentApp(); int appListCurrentIndex() const; QString appListCurrentPath() const; @@ -68,7 +71,7 @@ private: AppInfoCache *appInfoCache() const; private: - bool m_formAppIsEditing = false; + qint64 m_formAppId = 0; ProgramsController *m_ctrl = nullptr; diff --git a/src/ui/log/model/applistmodel.cpp b/src/ui/log/model/applistmodel.cpp index 0c057fc4..54ef7213 100644 --- a/src/ui/log/model/applistmodel.cpp +++ b/src/ui/log/model/applistmodel.cpp @@ -16,6 +16,7 @@ AppListModel::AppListModel(ConfManager *confManager, m_confManager(confManager) { connect(m_confManager, &ConfManager::confSaved, this, &AppListModel::reset); + connect(m_confManager, &ConfManager::appEndTimesUpdated, this, &AppListModel::refresh); } void AppListModel::setAppInfoCache(AppInfoCache *v) @@ -170,44 +171,36 @@ bool AppListModel::addApp(const QString &appPath, int groupIndex, bool blocked, return false; } -bool AppListModel::updateApp(int row, int groupIndex, bool blocked, +bool AppListModel::updateApp(qint64 appId, const QString &appPath, + int groupIndex, bool blocked, const QDateTime &endTime) { - updateRowCache(row); - - const qint64 appId = m_rowCache.appId; - const QString appPath = m_rowCache.appPath; - if (confManager()->updateDriverUpdateApp(appPath, groupIndex, false, blocked, false) && confManager()->updateApp(appId, endTime, groupIndex, blocked)) { - const auto itemIndex = index(row, 3); - invalidateRowCache(); - emit dataChanged(itemIndex, itemIndex); + refresh(); return true; } return false; } -void AppListModel::deleteApp(int row) +void AppListModel::deleteApp(qint64 appId, const QString &appPath) { - updateRowCache(row); - - const qint64 appId = m_rowCache.appId; - const QString appPath = m_rowCache.appPath; - if (confManager()->updateDriverDeleteApp(appPath) && confManager()->deleteApp(appId)) { - beginRemoveRows(QModelIndex(), row, row); - invalidateRowCache(); - endRemoveRows(); + reset(); } } void AppListModel::reset() { - beginResetModel(); invalidateRowCache(); - endResetModel(); + TableItemModel::reset(); +} + +void AppListModel::refresh() +{ + invalidateRowCache(); + TableItemModel::refresh(); } void AppListModel::invalidateRowCache() diff --git a/src/ui/log/model/applistmodel.h b/src/ui/log/model/applistmodel.h index 2988dfd9..5d1d6cdd 100644 --- a/src/ui/log/model/applistmodel.h +++ b/src/ui/log/model/applistmodel.h @@ -63,12 +63,14 @@ public: bool addApp(const QString &appPath, int groupIndex, bool blocked, const QDateTime &endTime = QDateTime()); - bool updateApp(int row, int groupIndex, bool blocked, + bool updateApp(qint64 appId, const QString &appPath, + int groupIndex, bool blocked, const QDateTime &endTime = QDateTime()); - void deleteApp(int row); + void deleteApp(qint64 appId, const QString &appPath); public slots: void reset(); + void refresh(); private: void invalidateRowCache();