UI: AppListModel: Extract AppListModelData

This commit is contained in:
Nodir Temirkhodjaev 2024-07-04 13:30:02 +05:00
parent 4ca88c8b9d
commit 790eee2237
4 changed files with 387 additions and 310 deletions

View File

@ -132,6 +132,7 @@ SOURCES += \
manager/translationmanager.cpp \
manager/windowmanager.cpp \
model/applistmodel.cpp \
model/applistmodeldata.cpp \
model/appstatmodel.cpp \
model/connblocklistmodel.cpp \
model/rulelistmodel.cpp \
@ -353,6 +354,7 @@ HEADERS += \
manager/translationmanager.h \
manager/windowmanager.h \
model/applistmodel.h \
model/applistmodeldata.h \
model/appstatmodel.h \
model/connblocklistmodel.h \
model/rulelistmodel.h \

View File

@ -12,301 +12,13 @@
#include <conf/confappmanager.h>
#include <conf/confmanager.h>
#include <conf/firewallconf.h>
#include <util/bitutil.h>
#include <util/conf/confutil.h>
#include <util/dateutil.h>
#include <util/guiutil.h>
#include <util/iconcache.h>
#include <util/ioc/ioccontainer.h>
#include <util/net/netutil.h>
namespace {
const auto alertColor = QColor("orange");
const auto allowColor = QColor("green");
const auto blockColor = QColor("red");
const auto killProcessColor = QColor("magenta");
const auto inactiveColor = QColor("slategray");
QString appActionIconPath(const AppRow &appRow)
{
if (appRow.alerted)
return ":/icons/error.png";
if (appRow.killProcess)
return ":/icons/scull.png";
if (appRow.blocked)
return ":/icons/deny.png";
if (appRow.lanOnly)
return ":/icons/hostname.png";
return ":/icons/accept.png";
}
QString appScheduleIconPath(const AppRow &appRow)
{
switch (appRow.scheduleAction) {
case App::ScheduleBlock:
return ":/icons/deny.png";
case App::ScheduleAllow:
return ":/icons/accept.png";
case App::ScheduleRemove:
return ":/icons/delete.png";
case App::ScheduleKillProcess:
return ":/icons/scull.png";
}
return {};
}
QColor appActionColor(const AppRow &appRow)
{
if (appRow.killProcess)
return killProcessColor;
if (appRow.blocked)
return blockColor;
return allowColor;
}
QVariant appGroupColor(const AppRow &appRow)
{
if (!appRow.useGroupPerm)
return inactiveColor;
const FirewallConf *conf = IoC<ConfAppManager>()->conf();
const AppGroup *appGroup = conf->appGroupAt(appRow.groupIndex);
if (!appGroup->enabled())
return blockColor;
return {};
}
QIcon appIcon(const AppRow &appRow)
{
if (appRow.isWildcard) {
return IconCache::icon(":/icons/coding.png");
}
return IoC<AppInfoCache>()->appIcon(appRow.appPath);
}
QIcon appZonesIcon(const AppRow &appRow)
{
return appRow.hasZone() ? IconCache::icon(":/icons/ip_class.png") : QIcon();
}
QIcon appRuleIcon(const AppRow &appRow)
{
return (appRow.ruleId != 0) ? IconCache::icon(":/icons/script.png") : QIcon();
}
QIcon appScheduledIcon(const AppRow &appRow)
{
if (appRow.scheduleTime.isNull())
return QIcon();
return IconCache::icon(appScheduleIconPath(appRow));
}
QIcon appActionIcon(const AppRow &appRow)
{
return IconCache::icon(appActionIconPath(appRow));
}
using dataDecorationIcon_func = QIcon (*)(const AppRow &appRow);
static const dataDecorationIcon_func dataDecorationIcon_funcList[] = {
&appIcon,
&appZonesIcon,
&appRuleIcon,
&appScheduledIcon,
&appActionIcon,
};
inline QVariant dataDecorationIcon(int column, const AppRow &appRow)
{
if (column < 0 || column >= std::size(dataDecorationIcon_funcList))
return QVariant();
const dataDecorationIcon_func func = dataDecorationIcon_funcList[column];
return func(appRow);
}
QVariant headerDataDisplayName(int /*role*/)
{
return AppListModel::tr("Name");
}
QVariant headerDataDisplayZones(int role)
{
return (role == Qt::ToolTipRole) ? AppListModel::tr("Zones") : QString();
}
QVariant headerDataDisplayRule(int role)
{
return (role == Qt::ToolTipRole) ? AppListModel::tr("Rule") : QString();
}
QVariant headerDataDisplayScheduled(int role)
{
return (role == Qt::ToolTipRole) ? AppListModel::tr("Scheduled") : QString();
}
QVariant headerDataDisplayAction(int /*role*/)
{
return AppListModel::tr("Action");
}
QVariant headerDataDisplayGroup(int /*role*/)
{
return AppListModel::tr("Group");
}
QVariant headerDataDisplayFilePath(int /*role*/)
{
return AppListModel::tr("File Path");
}
QVariant headerDataDisplayCreationTime(int /*role*/)
{
return AppListModel::tr("Creation Time");
}
using headerDataDisplay_func = QVariant (*)(int role);
static const headerDataDisplay_func headerDataDisplay_funcList[] = {
&headerDataDisplayName,
&headerDataDisplayZones,
&headerDataDisplayRule,
&headerDataDisplayScheduled,
&headerDataDisplayAction,
&headerDataDisplayGroup,
&headerDataDisplayFilePath,
&headerDataDisplayCreationTime,
};
inline QVariant headerDataDisplay(int column, int role)
{
const headerDataDisplay_func func = headerDataDisplay_funcList[column];
return func(role);
}
inline QVariant headerDataDecoration(int column)
{
switch (column) {
case 1:
return IconCache::icon(":/icons/ip_class.png");
case 2:
return IconCache::icon(":/icons/script.png");
case 3:
return IconCache::icon(":/icons/time.png");
}
return QVariant();
}
QVariant dataDisplayName(const AppRow &appRow, int role)
{
return appRow.appName
+ (role == Qt::ToolTipRole && !appRow.notes.isEmpty() ? "\n\n" + appRow.notes
: QString());
}
QVariant dataDisplayAction(const AppRow &appRow, int role)
{
if (appRow.killProcess)
return AppListModel::tr("Kill Process");
if (appRow.blocked)
return AppListModel::tr("Block");
if (role == Qt::ToolTipRole && appRow.lanOnly)
return AppListModel::tr("Block Internet Traffic");
return AppListModel::tr("Allow");
}
QVariant dataDisplayZones(const AppRow &appRow, int role)
{
if (role != Qt::ToolTipRole)
return QString();
QString countText;
if (appRow.acceptZones != 0) {
const int acceptZonesCount = BitUtil::bitCount(appRow.acceptZones);
countText += QString::number(acceptZonesCount);
}
if (appRow.rejectZones != 0) {
const int rejectZonesCount = BitUtil::bitCount(appRow.rejectZones);
countText += '^' + QString::number(rejectZonesCount);
}
return countText;
}
QVariant dataDisplayRule(const AppRow &appRow, int role)
{
if (role != Qt::ToolTipRole)
return QString();
return appRow.ruleName;
}
QVariant dataDisplayScheduled(const AppRow &appRow, int role)
{
if (role != Qt::ToolTipRole || appRow.scheduleTime.isNull())
return QString();
return DateUtil::localeDateTime(appRow.scheduleTime);
}
QVariant dataDisplayGroup(const AppRow &appRow, int /*role*/)
{
const FirewallConf *conf = IoC<ConfAppManager>()->conf();
const AppGroup *appGroup = conf->appGroupAt(appRow.groupIndex);
return appGroup->name();
}
QVariant dataDisplayFilePath(const AppRow &appRow, int /*role*/)
{
return appRow.appOriginPath;
}
QVariant dataDisplayCreationTime(const AppRow &appRow, int /*role*/)
{
return appRow.creatTime;
}
using dataDisplay_func = QVariant (*)(const AppRow &appRow, int role);
static const dataDisplay_func dataDisplay_funcList[] = {
&dataDisplayName,
&dataDisplayZones,
&dataDisplayRule,
&dataDisplayScheduled,
&dataDisplayAction,
&dataDisplayGroup,
&dataDisplayFilePath,
&dataDisplayCreationTime,
};
inline QVariant dataDisplayRow(const AppRow &appRow, int column, int role)
{
const dataDisplay_func func = dataDisplay_funcList[column];
Q_ASSERT(func);
return func(appRow, role);
}
}
#include "applistmodeldata.h"
AppListModel::AppListModel(QObject *parent) : FtsTableSqlModel(parent) { }
@ -390,20 +102,20 @@ QVariant AppListModel::headerData(int section, Qt::Orientation orientation, int
// Label
case Qt::DisplayRole:
case Qt::ToolTipRole:
return headerDataDisplay(section, role);
return AppListModelData::headerDataDisplay(section, role);
// Icon
case Qt::DecorationRole:
return headerDataDecoration(section);
return AppListModelData::headerDataDecoration(section);
}
}
return QVariant();
return {};
}
QVariant AppListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
return {};
switch (role) {
// Label
@ -424,48 +136,46 @@ QVariant AppListModel::data(const QModelIndex &index, int role) const
return dataTextAlignment(index);
}
return QVariant();
return {};
}
QVariant AppListModel::dataDisplay(const QModelIndex &index, int role) const
{
const int row = index.row();
const int column = index.column();
const auto &appRow = appRowAt(row);
if (appRow.isNull())
return QVariant();
return {};
return dataDisplayRow(appRow, column, role);
const AppListModelData data(appRow, index, role);
return data.dataDisplayRow();
}
QVariant AppListModel::dataDecoration(const QModelIndex &index) const
{
const int row = index.row();
const int column = index.column();
const auto &appRow = appRowAt(row);
if (appRow.isNull())
return QVariant();
return {};
return dataDecorationIcon(column, appRow);
const AppListModelData data(appRow, index);
return data.dataDecorationIcon();
}
QVariant AppListModel::dataForeground(const QModelIndex &index) const
{
const int column = index.column();
const int row = index.row();
const auto &appRow = appRowAt(row);
if (appRow.isNull())
return {};
switch (column) {
case 4:
return appActionColor(appRow);
case 5:
return appGroupColor(appRow);
}
const AppListModelData data(appRow, index);
return QVariant();
return data.dataForeground();
}
QVariant AppListModel::dataTextAlignment(const QModelIndex &index) const
@ -476,7 +186,7 @@ QVariant AppListModel::dataTextAlignment(const QModelIndex &index) const
return int(Qt::AlignHCenter | Qt::AlignVCenter);
}
return QVariant();
return {};
}
bool AppListModel::updateAppRow(const QString &sql, const QVariantHash &vars, AppRow &appRow) const

View File

@ -0,0 +1,319 @@
#include "applistmodeldata.h"
#include <QFont>
#include <QIcon>
#include <appinfo/appinfocache.h>
#include <conf/app.h>
#include <conf/appgroup.h>
#include <conf/confappmanager.h>
#include <conf/firewallconf.h>
#include <util/bitutil.h>
#include <util/dateutil.h>
#include <util/iconcache.h>
#include <util/ioc/ioccontainer.h>
#include "applistmodel.h"
namespace {
const auto alertColor = QColor("orange");
const auto allowColor = QColor("green");
const auto blockColor = QColor("red");
const auto killProcessColor = QColor("magenta");
const auto inactiveColor = QColor("slategray");
QVariant dataDisplayName(const App &app, int role)
{
return app.appName
+ (role == Qt::ToolTipRole && !app.notes.isEmpty() ? "\n\n" + app.notes : QString());
}
QVariant dataDisplayAction(const App &app, int role)
{
if (app.killProcess)
return AppListModel::tr("Kill Process");
if (app.blocked)
return AppListModel::tr("Block");
if (role == Qt::ToolTipRole && app.lanOnly)
return AppListModel::tr("Block Internet Traffic");
return AppListModel::tr("Allow");
}
QVariant dataDisplayZones(const App &app, int role)
{
if (role != Qt::ToolTipRole)
return QString();
QString countText;
if (app.acceptZones != 0) {
const int acceptZonesCount = BitUtil::bitCount(app.acceptZones);
countText += QString::number(acceptZonesCount);
}
if (app.rejectZones != 0) {
const int rejectZonesCount = BitUtil::bitCount(app.rejectZones);
countText += '^' + QString::number(rejectZonesCount);
}
return countText;
}
QVariant dataDisplayRule(const App &app, int role)
{
if (role != Qt::ToolTipRole)
return QString();
return app.ruleName;
}
QVariant dataDisplayScheduled(const App &app, int role)
{
if (role != Qt::ToolTipRole || app.scheduleTime.isNull())
return QString();
return DateUtil::localeDateTime(app.scheduleTime);
}
QVariant dataDisplayGroup(const App &app, int /*role*/)
{
const FirewallConf *conf = IoC<ConfAppManager>()->conf();
const AppGroup *appGroup = conf->appGroupAt(app.groupIndex);
return appGroup->name();
}
QVariant dataDisplayFilePath(const App &app, int /*role*/)
{
return app.appOriginPath;
}
QVariant dataDisplayCreationTime(const App &app, int /*role*/)
{
return app.creatTime;
}
using dataDisplay_func = QVariant (*)(const App &app, int role);
static const dataDisplay_func dataDisplay_funcList[] = {
&dataDisplayName,
&dataDisplayZones,
&dataDisplayRule,
&dataDisplayScheduled,
&dataDisplayAction,
&dataDisplayGroup,
&dataDisplayFilePath,
&dataDisplayCreationTime,
};
QVariant headerDataDisplayName(int /*role*/)
{
return AppListModel::tr("Name");
}
QVariant headerDataDisplayZones(int role)
{
return (role == Qt::ToolTipRole) ? AppListModel::tr("Zones") : QString();
}
QVariant headerDataDisplayRule(int role)
{
return (role == Qt::ToolTipRole) ? AppListModel::tr("Rule") : QString();
}
QVariant headerDataDisplayScheduled(int role)
{
return (role == Qt::ToolTipRole) ? AppListModel::tr("Scheduled") : QString();
}
QVariant headerDataDisplayAction(int /*role*/)
{
return AppListModel::tr("Action");
}
QVariant headerDataDisplayGroup(int /*role*/)
{
return AppListModel::tr("Group");
}
QVariant headerDataDisplayFilePath(int /*role*/)
{
return AppListModel::tr("File Path");
}
QVariant headerDataDisplayCreationTime(int /*role*/)
{
return AppListModel::tr("Creation Time");
}
using headerDataDisplay_func = QVariant (*)(int role);
static const headerDataDisplay_func headerDataDisplay_funcList[] = {
&headerDataDisplayName,
&headerDataDisplayZones,
&headerDataDisplayRule,
&headerDataDisplayScheduled,
&headerDataDisplayAction,
&headerDataDisplayGroup,
&headerDataDisplayFilePath,
&headerDataDisplayCreationTime,
};
}
AppListModelData::AppListModelData(const App &app, const QModelIndex &index, int role) :
m_role(role), m_index(index), m_app(app)
{
}
QString AppListModelData::appActionIconPath() const
{
if (app().alerted)
return ":/icons/error.png";
if (app().killProcess)
return ":/icons/scull.png";
if (app().blocked)
return ":/icons/deny.png";
if (app().lanOnly)
return ":/icons/hostname.png";
return ":/icons/accept.png";
}
QString AppListModelData::appScheduleIconPath() const
{
switch (app().scheduleAction) {
case App::ScheduleBlock:
return ":/icons/deny.png";
case App::ScheduleAllow:
return ":/icons/accept.png";
case App::ScheduleRemove:
return ":/icons/delete.png";
case App::ScheduleKillProcess:
return ":/icons/scull.png";
}
return {};
}
QColor AppListModelData::appActionColor() const
{
if (app().killProcess)
return killProcessColor;
if (app().blocked)
return blockColor;
return allowColor;
}
QVariant AppListModelData::appGroupColor() const
{
if (!app().useGroupPerm)
return inactiveColor;
const FirewallConf *conf = IoC<ConfAppManager>()->conf();
const AppGroup *appGroup = conf->appGroupAt(app().groupIndex);
if (!appGroup->enabled())
return blockColor;
return {};
}
QIcon AppListModelData::appIcon() const
{
if (app().isWildcard) {
return IconCache::icon(":/icons/coding.png");
}
return IoC<AppInfoCache>()->appIcon(app().appPath);
}
QIcon AppListModelData::appZonesIcon() const
{
return app().hasZone() ? IconCache::icon(":/icons/ip_class.png") : QIcon();
}
QIcon AppListModelData::appRuleIcon() const
{
return (app().ruleId != 0) ? IconCache::icon(":/icons/script.png") : QIcon();
}
QIcon AppListModelData::appScheduledIcon() const
{
if (app().scheduleTime.isNull())
return QIcon();
const AppListModelData data(app());
return IconCache::icon(data.appScheduleIconPath());
}
QIcon AppListModelData::appActionIcon() const
{
return IconCache::icon(appActionIconPath());
}
QVariant AppListModelData::dataDecorationIcon() const
{
switch (column()) {
case 0:
return appIcon();
case 1:
return appZonesIcon();
case 2:
return appRuleIcon();
case 3:
return appScheduledIcon();
case 4:
return appActionIcon();
}
return {};
}
QVariant AppListModelData::dataForeground() const
{
switch (column()) {
case 4:
return appActionColor();
case 5:
return appGroupColor();
}
return {};
}
QVariant AppListModelData::dataDisplayRow() const
{
const dataDisplay_func func = dataDisplay_funcList[column()];
return func(app(), role());
}
QVariant AppListModelData::headerDataDisplay(int column, int role)
{
const headerDataDisplay_func func = headerDataDisplay_funcList[column];
return func(role);
}
QVariant AppListModelData::headerDataDecoration(int column)
{
switch (column) {
case 1:
return IconCache::icon(":/icons/ip_class.png");
case 2:
return IconCache::icon(":/icons/script.png");
case 3:
return IconCache::icon(":/icons/time.png");
}
return {};
}

View File

@ -0,0 +1,46 @@
#ifndef APPLISTMODELDATA_H
#define APPLISTMODELDATA_H
#include <QModelIndex>
#include <QObject>
class App;
class AppListModelData
{
public:
explicit AppListModelData(
const App &app, const QModelIndex &index = {}, int role = Qt::DisplayRole);
int role() const { return m_role; }
const QModelIndex &index() const { return m_index; }
const App &app() const { return m_app; }
int column() const { return index().column(); }
QString appActionIconPath() const;
QString appScheduleIconPath() const;
QColor appActionColor() const;
QVariant appGroupColor() const;
QIcon appIcon() const;
QIcon appZonesIcon() const;
QIcon appRuleIcon() const;
QIcon appScheduledIcon() const;
QIcon appActionIcon() const;
QVariant dataDecorationIcon() const;
QVariant dataForeground() const;
QVariant dataDisplayRow() const;
static QVariant headerDataDisplay(int column, int role);
static QVariant headerDataDecoration(int column);
private:
int m_role = Qt::DisplayRole;
const QModelIndex &m_index;
const App &m_app;
};
#endif // APPLISTMODELDATA_H