UI: Rules: Rule id per type

This commit is contained in:
Nodir Temirkhodjaev 2024-03-09 12:49:23 +03:00
parent e609352940
commit c1421f00b1
11 changed files with 117 additions and 35 deletions

View File

@ -18,17 +18,19 @@ namespace {
const QLoggingCategory LC("confRule");
const char *const sqlInsertRule = "INSERT INTO rule(rule_id, enabled, blocked, exclusive, name,"
" notes, rule_text, accept_zones, reject_zones, mod_time)"
" VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10);";
const char *const sqlInsertRule = "INSERT INTO rule(rule_id, enabled, blocked, exclusive,"
" name, notes, rule_text, rule_type,"
" accept_zones, reject_zones, mod_time)"
" VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11);";
const char *const sqlUpdateRule = "UPDATE rule"
" SET enabled = ?2, blocked = ?3, exclusive = ?4,"
" name = ?5, notes = ?6, rule_text = ?7,"
" accept_zones = ?8, reject_zones = ?9, mod_time = ?10"
" name = ?5, notes = ?6, rule_text = ?7, rule_type = ?8,"
" accept_zones = ?9, reject_zones = ?10, mod_time = ?11"
" WHERE rule_id = ?1;";
const char *const sqlSelectRuleIds = "SELECT rule_id FROM rule ORDER BY rule_id;";
const char *const sqlSelectRuleIds = "SELECT rule_id FROM rule"
" WHERE rule_id >= ?1 ORDER BY rule_id;";
const char *const sqlDeleteRule = "DELETE FROM rule WHERE rule_id = ?1;";
@ -83,7 +85,8 @@ bool ConfRuleManager::addOrUpdateRule(Rule &rule)
const bool isNew = (rule.ruleId == 0);
if (isNew) {
rule.ruleId = DbUtil::getFreeId(sqliteDb(), sqlSelectRuleIds, ConfUtil::ruleMaxCount(), ok);
const auto range = Rule::getRuleIdRangeByType(rule.ruleType);
rule.ruleId = DbUtil::getFreeId(sqliteDb(), sqlSelectRuleIds, range.minId, range.maxId, ok);
} else {
updateDriverRuleFlag(rule.ruleId, rule.enabled);
}
@ -96,6 +99,7 @@ bool ConfRuleManager::addOrUpdateRule(Rule &rule)
rule.ruleName,
rule.notes,
rule.ruleText,
rule.ruleType,
rule.acceptZones,
rule.rejectZones,
DateUtil::now(),

View File

@ -27,7 +27,8 @@ const char *const sqlUpdateZone = "UPDATE zone"
" form_data = ?7, text_inline = ?8"
" WHERE zone_id = ?1;";
const char *const sqlSelectZoneIds = "SELECT zone_id FROM zone ORDER BY zone_id;";
const char *const sqlSelectZoneIds = "SELECT zone_id FROM zone"
" WHERE zone_id >= ?1 ORDER BY zone_id;";
const char *const sqlDeleteZone = "DELETE FROM zone WHERE zone_id = ?1;";
@ -99,7 +100,8 @@ bool ConfZoneManager::addOrUpdateZone(Zone &zone)
const bool isNew = (zone.zoneId == 0);
if (isNew) {
zone.zoneId = DbUtil::getFreeId(sqliteDb(), sqlSelectZoneIds, ConfUtil::zoneMaxCount(), ok);
zone.zoneId = DbUtil::getFreeId(sqliteDb(), sqlSelectZoneIds, /*minId=*/1,
/*maxId=*/ConfUtil::zoneMaxCount() - 1, ok);
} else {
updateDriverZoneFlag(zone.zoneId, zone.enabled);
}

View File

@ -92,7 +92,7 @@ CREATE TABLE rule(
name TEXT NOT NULL,
notes TEXT,
rule_text TEXT NOT NULL,
rule_type INTEGER NOT NULL, -- app rules (1..64), global before/after apps (65..96, 97..128), preset rules (129..255)
rule_type INTEGER NOT NULL, -- app rules, global before/after apps, preset rules
accept_zones INTEGER NOT NULL DEFAULT 0, -- zone indexes bit mask
reject_zones INTEGER NOT NULL DEFAULT 0, -- zone indexes bit mask
mod_time INTEGER NOT NULL

View File

@ -11,3 +11,26 @@ bool Rule::isOptionsEqual(const Rule &o) const
&& acceptZones == o.acceptZones && rejectZones == o.rejectZones
&& ruleName == o.ruleName && notes == o.notes && ruleText == o.ruleText;
}
Rule::RuleType Rule::getRuleTypeById(int ruleId)
{
for (int i = 0; i < RuleTypeCount; ++i) {
const auto ruleType = RuleType(i);
const auto range = getRuleIdRangeByType(ruleType);
if (ruleId >= range.minId && ruleId <= range.maxId)
return ruleType;
}
Q_UNREACHABLE();
return AppRule;
}
RuleIdRange Rule::getRuleIdRangeByType(RuleType ruleType)
{
static const RuleIdRange ruleIdRanges[] = { { 1, 64 }, { 65, 96 }, { 97, 128 }, { 129, 255 } };
Q_ASSERT(ruleType >= 0 && ruleType < RuleTypeCount);
return ruleIdRanges[ruleType];
}

View File

@ -4,16 +4,35 @@
#include <QDateTime>
#include <QObject>
struct RuleIdRange
{
int minId;
int maxId;
};
class Rule
{
public:
enum RuleType : qint8 {
AppRule = 0, // 1..64
GlobalBeforeAppsRule, // 65..96
GlobalAfterAppsRule, // 97..128
PresetRule, // 129..255
RuleTypeCount
};
bool isNameEqual(const Rule &o) const;
bool isOptionsEqual(const Rule &o) const;
static RuleType getRuleTypeById(int ruleId);
static RuleIdRange getRuleIdRangeByType(RuleType ruleType);
public:
bool enabled = true;
bool blocked = false;
bool exclusive = false;
bool enabled : 1 = true;
bool blocked : 1 = false;
bool exclusive : 1 = false;
RuleType ruleType = AppRule;
int ruleId = 0;

View File

@ -37,11 +37,15 @@ void RuleEditDialog::initialize(const RuleRow &ruleRow)
retranslateUi();
m_editName->setText(m_ruleRow.ruleName);
m_editName->setText(ruleRow.ruleName);
m_editName->setClearButtonEnabled(true);
m_editNotes->setText(m_ruleRow.notes);
m_labelEditNotes->setPixmap(IconCache::file(":/icons/script.png"));
m_editNotes->setText(ruleRow.notes);
m_labelRuleType->setText(tr("Type:"));
m_comboRuleType->setCurrentIndex(ruleRow.ruleType);
m_comboRuleType->setEnabled(isEmpty());
m_cbEnabled->setChecked(ruleRow.enabled);
@ -75,6 +79,9 @@ void RuleEditDialog::retranslateUi()
m_labelEditName->setText(tr("Name:"));
m_editNotes->setPlaceholderText(tr("Notes"));
retranslateComboRuleType();
m_cbEnabled->setText(tr("Enabled"));
m_rbAllow->setText(tr("Allow"));
@ -89,6 +96,15 @@ void RuleEditDialog::retranslateUi()
this->setWindowTitle(tr("Edit Rule"));
}
void RuleEditDialog::retranslateComboRuleType()
{
const QStringList list = { tr("Application Rules"),
tr("Global Rules, applied before App Rules"), tr("Global Rules, applied after App Rules"),
tr("Preset Rules") };
ControlUtil::setComboBoxTexts(m_comboRuleType, list);
}
void RuleEditDialog::setupUi()
{
// Main Layout
@ -105,7 +121,7 @@ void RuleEditDialog::setupUi()
this->setSizeGripEnabled(true);
// Size
this->setMinimumSize(500, 300);
this->setMinimumWidth(400);
}
QLayout *RuleEditDialog::setupMainLayout()
@ -143,6 +159,7 @@ QLayout *RuleEditDialog::setupMainLayout()
QLayout *RuleEditDialog::setupFormLayout()
{
auto layout = new QFormLayout();
layout->setHorizontalSpacing(10);
// Name
m_editName = new QLineEdit();
@ -160,6 +177,13 @@ QLayout *RuleEditDialog::setupFormLayout()
m_labelEditNotes->setScaledContents(true);
m_labelEditNotes->setFixedSize(32, 32);
// Rule Type
m_comboRuleType = ControlUtil::createComboBox();
m_comboRuleType->setMinimumWidth(100);
layout->addRow("Type:", m_comboRuleType);
m_labelRuleType = ControlUtil::formRowLabel(layout, m_comboRuleType);
// Enabled
m_cbEnabled = new QCheckBox();
@ -268,6 +292,8 @@ bool RuleEditDialog::validateFields() const
void RuleEditDialog::fillRule(Rule &rule) const
{
rule.ruleType = Rule::RuleType(m_comboRuleType->currentIndex());
rule.enabled = m_cbEnabled->isChecked();
rule.blocked = !m_rbAllow->isChecked();
rule.exclusive = m_cbExclusive->isChecked();

View File

@ -6,6 +6,7 @@
#include <model/rulelistmodel.h>
QT_FORWARD_DECLARE_CLASS(QCheckBox)
QT_FORWARD_DECLARE_CLASS(QComboBox)
QT_FORWARD_DECLARE_CLASS(QLabel)
QT_FORWARD_DECLARE_CLASS(QLineEdit)
QT_FORWARD_DECLARE_CLASS(QPushButton)
@ -37,6 +38,7 @@ private:
void setupController();
void retranslateUi();
void retranslateComboRuleType();
void setupUi();
QLayout *setupMainLayout();
@ -59,6 +61,8 @@ private:
QLineEdit *m_editName = nullptr;
QLabel *m_labelEditNotes = nullptr;
PlainTextEdit *m_editNotes = nullptr;
QLabel *m_labelRuleType = nullptr;
QComboBox *m_comboRuleType = nullptr;
QCheckBox *m_cbEnabled = nullptr;
QRadioButton *m_rbAllow = nullptr;
QRadioButton *m_rbBlock = nullptr;

View File

@ -208,9 +208,10 @@ bool RuleListModel::updateRuleRow(
ruleRow.ruleName = stmt.columnText(4);
ruleRow.notes = stmt.columnText(5);
ruleRow.ruleText = stmt.columnText(6);
ruleRow.acceptZones = stmt.columnUInt(7);
ruleRow.rejectZones = stmt.columnUInt(8);
ruleRow.modTime = stmt.columnDateTime(9);
ruleRow.ruleType = Rule::RuleType(stmt.columnInt(7));
ruleRow.acceptZones = stmt.columnUInt(8);
ruleRow.rejectZones = stmt.columnUInt(9);
ruleRow.modTime = stmt.columnDateTime(10);
return true;
}
@ -225,6 +226,7 @@ QString RuleListModel::sqlBase() const
" name,"
" notes,"
" rule_text,"
" rule_type,"
" accept_zones,"
" reject_zones,"
" mod_time"

View File

@ -94,8 +94,8 @@ bool ConfRuleManagerRpc::updateRuleEnabled(int ruleId, bool enabled)
QVariantList ConfRuleManagerRpc::ruleToVarList(const Rule &rule)
{
return { rule.enabled, rule.blocked, rule.exclusive, rule.ruleId, rule.acceptZones,
rule.rejectZones, rule.ruleName, rule.notes, rule.ruleText };
return { rule.enabled, rule.blocked, rule.exclusive, rule.ruleType, rule.ruleId,
rule.acceptZones, rule.rejectZones, rule.ruleName, rule.notes, rule.ruleText };
}
Rule ConfRuleManagerRpc::varListToRule(const QVariantList &v)
@ -104,12 +104,13 @@ Rule ConfRuleManagerRpc::varListToRule(const QVariantList &v)
rule.enabled = v.value(0).toBool();
rule.blocked = v.value(1).toBool();
rule.exclusive = v.value(2).toBool();
rule.ruleId = v.value(3).toInt();
rule.acceptZones = v.value(4).toUInt();
rule.rejectZones = v.value(5).toUInt();
rule.ruleName = v.value(6).toString();
rule.notes = v.value(7).toString();
rule.ruleText = v.value(8).toString();
rule.ruleType = Rule::RuleType(v.value(3).toInt());
rule.ruleId = v.value(4).toInt();
rule.acceptZones = v.value(5).toUInt();
rule.rejectZones = v.value(6).toUInt();
rule.ruleName = v.value(7).toString();
rule.notes = v.value(8).toString();
rule.ruleText = v.value(9).toString();
return rule;
}

View File

@ -3,22 +3,22 @@
#include <sqlite/sqlitedb.h>
#include <sqlite/sqlitestmt.h>
int DbUtil::getFreeId(SqliteDb *sqliteDb, const char *sqlSelectIds, int maxCount, bool &ok)
int DbUtil::getFreeId(SqliteDb *sqliteDb, const char *sqlSelectIds, int minId, int maxId, bool &ok)
{
int freeId = 1;
SqliteStmt stmt;
if (stmt.prepare(sqliteDb->db(), sqlSelectIds)) {
stmt.bindInt(1, minId);
while (stmt.step() == SqliteStmt::StepRow) {
const int id = stmt.columnInt(0);
if (freeId < id)
if (minId < id || id >= maxId)
break;
freeId = id + 1;
minId = id + 1;
}
}
ok = (freeId < maxCount);
ok = (minId <= maxId);
return freeId;
return minId;
}

View File

@ -8,7 +8,8 @@ class SqliteDb;
class DbUtil
{
public:
static int getFreeId(SqliteDb *sqliteDb, const char *sqlSelectIds, int maxCount, bool &ok);
static int getFreeId(
SqliteDb *sqliteDb, const char *sqlSelectIds, int minId, int maxId, bool &ok);
};
#endif // DBUTIL_H