diff --git a/src/tests/db/test.cpp b/src/tests/db/test.cpp
index ec0d8af1..fe64f9df 100644
--- a/src/tests/db/test.cpp
+++ b/src/tests/db/test.cpp
@@ -132,6 +132,26 @@ void Test::debugStatTrafStep(SqliteDb *sqliteDb, const char *name,
qDebug() << "--";
}
+void Test::activePeriod()
+{
+ const QDate d1(2018, 8, 31);
+ const QTime t1(15, 35, 24);
+ const QDateTime dt1(d1, t1);
+
+ const qint64 unixTime = dt1.toSecsSinceEpoch();
+ const qint32 unixDay = DateUtil::getUnixDay(unixTime);
+ const qint32 unixHour = DateUtil::getUnixHour(unixTime);
+
+ QVERIFY(DateUtil::isHourBetween(unixHour, unixDay, 0, 24));
+ QVERIFY(DateUtil::isHourBetween(unixHour, unixDay, 15, 15));
+ QVERIFY(DateUtil::isHourBetween(unixHour, unixDay, 15, 16));
+ QVERIFY(DateUtil::isHourBetween(unixHour, unixDay, 15, 10));
+ QVERIFY(DateUtil::isHourBetween(unixHour, unixDay, 16, 15));
+ QVERIFY(!DateUtil::isHourBetween(unixHour, unixDay, 24, 0));
+ QVERIFY(!DateUtil::isHourBetween(unixHour, unixDay, 16, 14));
+ QVERIFY(!DateUtil::isHourBetween(unixHour, unixDay, 16, 24));
+}
+
void Test::monthStart()
{
const QDate d1(2018, 1, 8);
diff --git a/src/tests/db/test.h b/src/tests/db/test.h
index 3bc4cf9e..b6c5592b 100644
--- a/src/tests/db/test.h
+++ b/src/tests/db/test.h
@@ -11,6 +11,7 @@ class Test : public QObject
private slots:
void dbWriteRead();
+ void activePeriod();
void monthStart();
private:
diff --git a/src/ui/conf/firewallconf.cpp b/src/ui/conf/firewallconf.cpp
index cdf55d13..267e6ccf 100644
--- a/src/ui/conf/firewallconf.cpp
+++ b/src/ui/conf/firewallconf.cpp
@@ -18,6 +18,9 @@ FirewallConf::FirewallConf(QObject *parent) :
m_logStat(false),
m_appBlockAll(true),
m_appAllowAll(false),
+ m_activePeriodEnabled(false),
+ m_activePeriodFrom(0),
+ m_activePeriodTo(0),
m_monthStart(DEFAULT_MONTH_START),
m_trafHourKeepDays(DEFAULT_TRAF_HOUR_KEEP_DAYS),
m_trafDayKeepDays(DEFAULT_TRAF_DAY_KEEP_DAYS),
@@ -110,6 +113,30 @@ void FirewallConf::setAppAllowAll(bool appAllowAll)
}
}
+void FirewallConf::setActivePeriodEnabled(bool activePeriodEnabled)
+{
+ if (m_activePeriodEnabled != activePeriodEnabled) {
+ m_activePeriodEnabled = activePeriodEnabled;
+ emit activePeriodEnabledChanged();
+ }
+}
+
+void FirewallConf::setActivePeriodFrom(int activePeriodFrom)
+{
+ if (m_activePeriodFrom != activePeriodFrom) {
+ m_activePeriodFrom = uint(activePeriodFrom);
+ emit activePeriodFromChanged();
+ }
+}
+
+void FirewallConf::setActivePeriodTo(int activePeriodTo)
+{
+ if (m_activePeriodTo != activePeriodTo) {
+ m_activePeriodTo = uint(activePeriodTo);
+ emit activePeriodToChanged();
+ }
+}
+
void FirewallConf::setMonthStart(int monthStart)
{
if (m_monthStart != monthStart) {
@@ -263,6 +290,10 @@ void FirewallConf::copyFlags(const FirewallConf &o)
setPasswordHash(o.passwordHash());
setAppGroupBits(o.appGroupBits());
+ setActivePeriodEnabled(o.activePeriodEnabled());
+ setActivePeriodFrom(o.activePeriodFrom());
+ setActivePeriodTo(o.activePeriodTo());
+
setMonthStart(o.monthStart());
setTrafHourKeepDays(o.trafHourKeepDays());
setTrafDayKeepDays(o.trafDayKeepDays());
diff --git a/src/ui/conf/firewallconf.h b/src/ui/conf/firewallconf.h
index 66c6bfca..de093166 100644
--- a/src/ui/conf/firewallconf.h
+++ b/src/ui/conf/firewallconf.h
@@ -27,6 +27,9 @@ class FirewallConf : public QObject
Q_PROPERTY(bool logStat READ logStat WRITE setLogStat NOTIFY logStatChanged)
Q_PROPERTY(bool appBlockAll READ appBlockAll WRITE setAppBlockAll NOTIFY appBlockAllChanged)
Q_PROPERTY(bool appAllowAll READ appAllowAll WRITE setAppAllowAll NOTIFY appAllowAllChanged)
+ Q_PROPERTY(bool activePeriodEnabled READ activePeriodEnabled WRITE setActivePeriodEnabled NOTIFY activePeriodEnabledChanged)
+ Q_PROPERTY(int activePeriodFrom READ activePeriodFrom WRITE setActivePeriodFrom NOTIFY activePeriodFromChanged)
+ Q_PROPERTY(int activePeriodTo READ activePeriodTo WRITE setActivePeriodTo NOTIFY activePeriodToChanged)
Q_PROPERTY(int monthStart READ monthStart WRITE setMonthStart NOTIFY monthStartChanged)
Q_PROPERTY(int trafHourKeepDays READ trafHourKeepDays WRITE setTrafHourKeepDays NOTIFY trafHourKeepDaysChanged)
Q_PROPERTY(int trafDayKeepDays READ trafDayKeepDays WRITE setTrafDayKeepDays NOTIFY trafDayKeepDaysChanged)
@@ -84,6 +87,15 @@ public:
bool appAllowAll() const { return m_appAllowAll; }
void setAppAllowAll(bool appAllowAll);
+ bool activePeriodEnabled() const { return m_activePeriodEnabled; }
+ void setActivePeriodEnabled(bool activePeriodEnabled);
+
+ int activePeriodFrom() const { return m_activePeriodFrom; }
+ void setActivePeriodFrom(int activePeriodFrom);
+
+ int activePeriodTo() const { return m_activePeriodTo; }
+ void setActivePeriodTo(int activePeriodTo);
+
int monthStart() const { return m_monthStart; }
void setMonthStart(int monthStart);
@@ -142,6 +154,9 @@ signals:
void logStatChanged();
void appBlockAllChanged();
void appAllowAllChanged();
+ void activePeriodEnabledChanged();
+ void activePeriodFromChanged();
+ void activePeriodToChanged();
void monthStartChanged();
void trafHourKeepDaysChanged();
void trafDayKeepDaysChanged();
@@ -174,6 +189,10 @@ private:
uint m_appBlockAll : 1;
uint m_appAllowAll : 1;
+ uint m_activePeriodEnabled : 1;
+ uint m_activePeriodFrom : 5;
+ uint m_activePeriodTo : 5;
+
uint m_monthStart : 5;
int m_trafHourKeepDays;
diff --git a/src/ui/db/databasemanager.cpp b/src/ui/db/databasemanager.cpp
index 030b1f0a..a907c8d4 100644
--- a/src/ui/db/databasemanager.cpp
+++ b/src/ui/db/databasemanager.cpp
@@ -182,7 +182,8 @@ void DatabaseManager::logProcNew(quint32 pid, const QString &appPath)
qint64 appId = getAppId(appPath);
if (appId == INVALID_APP_ID) {
- appId = createAppId(appPath);
+ const qint64 unixTime = DateUtil::getUnixTime();
+ appId = createAppId(appPath, unixTime);
}
m_sqliteDb->commitTransaction();
@@ -235,69 +236,77 @@ void DatabaseManager::logStatTraf(quint16 procCount, const quint32 *procTrafByte
m_sqliteDb->beginTransaction();
- // Insert Statemets
- const QStmtList insertTrafAppStmts = QStmtList()
- << getTrafficStmt(DatabaseSql::sqlInsertTrafAppHour, trafHour)
- << getTrafficStmt(DatabaseSql::sqlInsertTrafAppDay, trafDay)
- << getTrafficStmt(DatabaseSql::sqlInsertTrafAppMonth, trafMonth)
- << getTrafficStmt(DatabaseSql::sqlUpdateTrafAppTotal, -1);
+ // Store the data
+ const bool isActivePeriod = !m_conf->activePeriodEnabled()
+ || DateUtil::isHourBetween(trafHour, trafDay,
+ m_conf->activePeriodFrom(),
+ m_conf->activePeriodTo());
- const QStmtList insertTrafStmts = QStmtList()
- << getTrafficStmt(DatabaseSql::sqlInsertTrafHour, trafHour)
- << getTrafficStmt(DatabaseSql::sqlInsertTrafDay, trafDay)
- << getTrafficStmt(DatabaseSql::sqlInsertTrafMonth, trafMonth);
+ if (isActivePeriod) {
+ // Insert Statements
+ const QStmtList insertTrafAppStmts = QStmtList()
+ << getTrafficStmt(DatabaseSql::sqlInsertTrafAppHour, trafHour)
+ << getTrafficStmt(DatabaseSql::sqlInsertTrafAppDay, trafDay)
+ << getTrafficStmt(DatabaseSql::sqlInsertTrafAppMonth, trafMonth)
+ << getTrafficStmt(DatabaseSql::sqlUpdateTrafAppTotal, -1);
- // Update Statemets
- const QStmtList updateTrafAppStmts = QStmtList()
- << getTrafficStmt(DatabaseSql::sqlUpdateTrafAppHour, trafHour)
- << getTrafficStmt(DatabaseSql::sqlUpdateTrafAppDay, trafDay)
- << getTrafficStmt(DatabaseSql::sqlUpdateTrafAppMonth, trafMonth)
- << getTrafficStmt(DatabaseSql::sqlUpdateTrafAppTotal, -1);
+ const QStmtList insertTrafStmts = QStmtList()
+ << getTrafficStmt(DatabaseSql::sqlInsertTrafHour, trafHour)
+ << getTrafficStmt(DatabaseSql::sqlInsertTrafDay, trafDay)
+ << getTrafficStmt(DatabaseSql::sqlInsertTrafMonth, trafMonth);
- const QStmtList updateTrafStmts = QStmtList()
- << getTrafficStmt(DatabaseSql::sqlUpdateTrafHour, trafHour)
- << getTrafficStmt(DatabaseSql::sqlUpdateTrafDay, trafDay)
- << getTrafficStmt(DatabaseSql::sqlUpdateTrafMonth, trafMonth);
+ // Update Statements
+ const QStmtList updateTrafAppStmts = QStmtList()
+ << getTrafficStmt(DatabaseSql::sqlUpdateTrafAppHour, trafHour)
+ << getTrafficStmt(DatabaseSql::sqlUpdateTrafAppDay, trafDay)
+ << getTrafficStmt(DatabaseSql::sqlUpdateTrafAppMonth, trafMonth)
+ << getTrafficStmt(DatabaseSql::sqlUpdateTrafAppTotal, -1);
- for (int i = 0; i < procCount; ++i) {
- quint32 pid = *procTrafBytes++;
- const bool inactive = (pid & 1) != 0;
- const quint32 inBytes = *procTrafBytes++;
- const quint32 outBytes = *procTrafBytes++;
+ const QStmtList updateTrafStmts = QStmtList()
+ << getTrafficStmt(DatabaseSql::sqlUpdateTrafHour, trafHour)
+ << getTrafficStmt(DatabaseSql::sqlUpdateTrafDay, trafDay)
+ << getTrafficStmt(DatabaseSql::sqlUpdateTrafMonth, trafMonth);
- if (inactive) {
- pid ^= 1;
- }
+ for (int i = 0; i < procCount; ++i) {
+ quint32 pid = *procTrafBytes++;
+ const bool inactive = (pid & 1) != 0;
+ const quint32 inBytes = *procTrafBytes++;
+ const quint32 outBytes = *procTrafBytes++;
- const int procIndex = m_appIndexes.value(pid, INVALID_APP_INDEX);
- if (procIndex == INVALID_APP_INDEX) {
- qCritical(CLOG_DATABASE_MANAGER()) << "UI & Driver's states mismatch.";
- abort();
- }
-
- if (inBytes || outBytes) {
- qint64 appId = m_appIds.at(procIndex);
-
- // Was the app cleared?
- if (appId == INVALID_APP_ID) {
- appId = createAppId(m_appPaths.at(procIndex));
- replaceAppIdAt(procIndex, appId);
+ if (inactive) {
+ pid ^= 1;
}
- // Update or insert app bytes
- updateTrafficList(insertTrafAppStmts, updateTrafAppStmts,
- inBytes, outBytes, appId);
+ const int procIndex = m_appIndexes.value(pid, INVALID_APP_INDEX);
+ if (procIndex == INVALID_APP_INDEX) {
+ qCritical(CLOG_DATABASE_MANAGER()) << "UI & Driver's states mismatch.";
+ abort();
+ }
- // Update or insert total bytes
- updateTrafficList(insertTrafStmts, updateTrafStmts,
- inBytes, outBytes);
+ if (inBytes || outBytes) {
+ qint64 appId = m_appIds.at(procIndex);
- // Update quota traffic bytes
- m_quotaManager->addTraf(inBytes);
- }
+ // Was the app cleared?
+ if (appId == INVALID_APP_ID) {
+ appId = createAppId(m_appPaths.at(procIndex), unixTime);
+ replaceAppIdAt(procIndex, appId);
+ }
- if (inactive) {
- logClearApp(pid, procIndex);
+ // Update or insert app bytes
+ updateTrafficList(insertTrafAppStmts, updateTrafAppStmts,
+ inBytes, outBytes, appId);
+
+ // Update or insert total bytes
+ updateTrafficList(insertTrafStmts, updateTrafStmts,
+ inBytes, outBytes);
+
+ // Update quota traffic bytes
+ m_quotaManager->addTraf(inBytes);
+ }
+
+ if (inactive) {
+ logClearApp(pid, procIndex);
+ }
}
}
@@ -361,7 +370,7 @@ void DatabaseManager::deleteApp(qint64 appId)
{
clearAppId(appId);
- // Delete Statemets
+ // Delete Statements
const QStmtList deleteAppStmts = QStmtList()
<< getAppStmt(DatabaseSql::sqlDeleteAppTrafHour, appId)
<< getAppStmt(DatabaseSql::sqlDeleteAppTrafDay, appId)
@@ -401,12 +410,11 @@ qint64 DatabaseManager::getAppId(const QString &appPath)
return appId;
}
-qint64 DatabaseManager::createAppId(const QString &appPath)
+qint64 DatabaseManager::createAppId(const QString &appPath, qint64 unixTime)
{
qint64 appId = INVALID_APP_ID;
SqliteStmt *stmt = getSqliteStmt(DatabaseSql::sqlInsertAppId);
- const qint64 unixTime = DateUtil::getUnixTime();
stmt->bindText(1, appPath);
stmt->bindInt64(2, unixTime);
diff --git a/src/ui/db/databasemanager.h b/src/ui/db/databasemanager.h
index 8a6cc002..02a9b4bb 100644
--- a/src/ui/db/databasemanager.h
+++ b/src/ui/db/databasemanager.h
@@ -67,7 +67,7 @@ private:
void logClearApp(quint32 pid, int index);
qint64 getAppId(const QString &appPath);
- qint64 createAppId(const QString &appPath);
+ qint64 createAppId(const QString &appPath, qint64 unixTime);
void updateTrafficList(const QStmtList &insertStmtList,
const QStmtList &updateStmtList,
diff --git a/src/ui/fort_qml.qrc b/src/ui/fort_qml.qrc
index 6e83e669..6a3379b4 100644
--- a/src/ui/fort_qml.qrc
+++ b/src/ui/fort_qml.qrc
@@ -9,6 +9,8 @@
qml/controls/ScrollBarControl.qml
qml/controls/SpinCombo.qml
qml/controls/SpinComboRow.qml
+ qml/controls/SpinDouble.qml
+ qml/controls/SpinDoubleRow.qml
qml/controls/SwipeViewControl.qml
qml/controls/TextAreaFrame.qml
qml/controls/TextContextMenu.qml
diff --git a/src/ui/fortsettings.cpp b/src/ui/fortsettings.cpp
index bc8a6a78..819f8417 100644
--- a/src/ui/fortsettings.cpp
+++ b/src/ui/fortsettings.cpp
@@ -238,6 +238,9 @@ bool FortSettings::readConfIni(FirewallConf &conf) const
m_ini->endGroup();
m_ini->beginGroup("stat");
+ conf.setActivePeriodEnabled(iniBool("activePeriodEnabled"));
+ conf.setActivePeriodFrom(iniInt("activePeriodFrom"));
+ conf.setActivePeriodTo(iniInt("activePeriodTo"));
conf.setMonthStart(iniInt("monthStart", DEFAULT_MONTH_START));
conf.setTrafHourKeepDays(iniInt("trafHourKeepDays", DEFAULT_TRAF_HOUR_KEEP_DAYS));
conf.setTrafDayKeepDays(iniInt("trafDayKeepDays", DEFAULT_TRAF_DAY_KEEP_DAYS));
@@ -270,6 +273,9 @@ bool FortSettings::writeConfIni(const FirewallConf &conf)
m_ini->endGroup();
m_ini->beginGroup("stat");
+ setIniValue("activePeriodEnabled", conf.activePeriodEnabled());
+ setIniValue("activePeriodFrom", conf.activePeriodFrom());
+ setIniValue("activePeriodTo", conf.activePeriodTo());
setIniValue("monthStart", conf.monthStart(), DEFAULT_MONTH_START);
setIniValue("trafHourKeepDays", conf.trafHourKeepDays(), DEFAULT_TRAF_HOUR_KEEP_DAYS);
setIniValue("trafDayKeepDays", conf.trafDayKeepDays(), DEFAULT_TRAF_DAY_KEEP_DAYS);
diff --git a/src/ui/i18n/i18n_ru.qm b/src/ui/i18n/i18n_ru.qm
index edbe33e0..401bb8ab 100644
Binary files a/src/ui/i18n/i18n_ru.qm and b/src/ui/i18n/i18n_ru.qm differ
diff --git a/src/ui/i18n/i18n_ru.ts b/src/ui/i18n/i18n_ru.ts
index 54fe128b..1f57a93c 100644
--- a/src/ui/i18n/i18n_ru.ts
+++ b/src/ui/i18n/i18n_ru.ts
@@ -88,17 +88,17 @@
FortSettings
-
+
Не удалось записать .ini файл
-
+
Не удалось создать .conf файл
-
+
Не удалось создать бэкап .conf файла
@@ -158,12 +158,12 @@
TaskInfo
-
+
Проверка обновлений
-
+
Загрузчик TAS-IX адресов
@@ -511,32 +511,37 @@
3 года
-
+
+
+ Активный период, часы
+
+
+
Месяц начинается с:
-
+
Хранить дней для 'Почасовая':
-
+
Хранить дней для 'Ежедневная':
-
+
Хранить месяцев для 'Ежемесячная':
-
+
Квота на день
-
+
Квота на месяц
diff --git a/src/ui/qml/controls/SpinDouble.qml b/src/ui/qml/controls/SpinDouble.qml
new file mode 100644
index 00000000..a9366456
--- /dev/null
+++ b/src/ui/qml/controls/SpinDouble.qml
@@ -0,0 +1,33 @@
+import QtQuick 2.12
+import QtQuick.Controls 2.5
+import QtQuick.Layouts 1.3
+
+RowLayout {
+
+ readonly property alias field1: field1
+ readonly property alias field2: field2
+
+ property real fieldPreferredWidth
+
+ SpinBox {
+ id: field1
+ Layout.fillWidth: true
+ Layout.preferredWidth: fieldPreferredWidth
+ Layout.minimumWidth: fieldPreferredWidth
+
+ editable: true
+ from: 0
+ to: 9999
+ }
+
+ SpinBox {
+ id: field2
+ Layout.fillWidth: true
+ Layout.preferredWidth: fieldPreferredWidth
+ Layout.minimumWidth: fieldPreferredWidth
+
+ editable: true
+ from: 0
+ to: 9999
+ }
+}
diff --git a/src/ui/qml/controls/SpinDoubleRow.qml b/src/ui/qml/controls/SpinDoubleRow.qml
new file mode 100644
index 00000000..51e45f1e
--- /dev/null
+++ b/src/ui/qml/controls/SpinDoubleRow.qml
@@ -0,0 +1,25 @@
+import QtQuick 2.12
+import QtQuick.Controls 2.5
+import QtQuick.Layouts 1.3
+import com.fortfirewall 1.0
+
+RowLayout {
+
+ Layout.fillWidth: true
+
+ readonly property alias checkBox: checkBox
+ readonly property alias field1: spinDouble.field1
+ readonly property alias field2: spinDouble.field2
+
+ CheckBox {
+ id: checkBox
+ Layout.fillWidth: true
+ }
+
+ SpinDouble {
+ id: spinDouble
+ Layout.maximumWidth: implicitWidth
+
+ fieldPreferredWidth: 140
+ }
+}
diff --git a/src/ui/qml/pages/log/TrafOptionsButton.qml b/src/ui/qml/pages/log/TrafOptionsButton.qml
index 8e55c549..b96abeb1 100644
--- a/src/ui/qml/pages/log/TrafOptionsButton.qml
+++ b/src/ui/qml/pages/log/TrafOptionsButton.qml
@@ -62,6 +62,51 @@ ButtonPopup {
}
ColumnLayout {
+ SpinDoubleRow {
+ checkBox {
+ text: translationManager.trTrigger
+ && qsTranslate("qml", "Active period, hours:")
+ checked: firewallConf.activePeriodEnabled
+ onCheckedChanged: {
+ const value = checkBox.checked;
+ if (firewallConf.activePeriodEnabled == value)
+ return;
+
+ firewallConf.activePeriodEnabled = value;
+
+ setConfFlagsEdited();
+ }
+ }
+ field1 {
+ from: 0
+ to: 24
+ value: firewallConf.activePeriodFrom
+ onValueChanged: {
+ const value = field1.value;
+ if (firewallConf.activePeriodFrom == value)
+ return;
+
+ firewallConf.activePeriodFrom = value;
+
+ setConfFlagsEdited();
+ }
+ }
+ field2 {
+ from: 0
+ to: 24
+ value: firewallConf.activePeriodTo
+ onValueChanged: {
+ const value = field2.value;
+ if (firewallConf.activePeriodTo == value)
+ return;
+
+ firewallConf.activePeriodTo = value;
+
+ setConfFlagsEdited();
+ }
+ }
+ }
+
SpinComboRow {
values: {
var arr = [];
diff --git a/src/ui/util/dateutil.cpp b/src/ui/util/dateutil.cpp
index 6c45d0b6..83eeac65 100644
--- a/src/ui/util/dateutil.cpp
+++ b/src/ui/util/dateutil.cpp
@@ -80,3 +80,13 @@ QString DateUtil::formatDateTime(qint64 unixTime, const QString &format)
const QDateTime dt = QDateTime::fromSecsSinceEpoch(unixTime);
return QLocale().toString(dt, format);
}
+
+bool DateUtil::isHourBetween(qint32 unixHour, qint32 unixDay,
+ int fromHour, int toHour)
+{
+ const int hour = unixHour - unixDay;
+
+ return fromHour <= toHour
+ ? (hour >= fromHour && hour <= toHour)
+ : (hour == 0 || hour >= fromHour || hour <= toHour);
+}
diff --git a/src/ui/util/dateutil.h b/src/ui/util/dateutil.h
index 47e020c7..5bb112f5 100644
--- a/src/ui/util/dateutil.h
+++ b/src/ui/util/dateutil.h
@@ -29,6 +29,9 @@ public:
static QString formatMonth(qint64 unixTime);
static QString formatDateTime(qint64 unixTime, const QString &format);
+
+ static bool isHourBetween(qint32 unixHour, qint32 unixDay,
+ int fromHour, int toHour);
};
#endif // DATEUTIL_H