UI: Extract ProgramEditDialog from ProgramsWindow.

This commit is contained in:
Nodir Temirkhodjaev 2021-04-23 14:31:52 +03:00
parent 841efaeedd
commit 9bcb9e8fe4
14 changed files with 584 additions and 480 deletions

View File

@ -52,6 +52,7 @@ SOURCES += \
form/opt/pages/rulespage.cpp \
form/opt/pages/schedulepage.cpp \
form/opt/pages/statisticspage.cpp \
form/prog/programeditdialog.cpp \
form/prog/programscontroller.cpp \
form/prog/programswindow.cpp \
form/tray/traycontroller.cpp \
@ -177,6 +178,7 @@ HEADERS += \
form/opt/pages/rulespage.h \
form/opt/pages/schedulepage.h \
form/opt/pages/statisticspage.h \
form/prog/programeditdialog.h \
form/prog/programscontroller.h \
form/prog/programswindow.h \
form/tray/traycontroller.h \

View File

@ -86,10 +86,9 @@ void ConnectionsWindow::restoreWindowState()
void ConnectionsWindow::setupController()
{
connect(ctrl(), &ConnectionsController::retranslateUi, this,
&ConnectionsWindow::onRetranslateUi);
connect(ctrl(), &ConnectionsController::retranslateUi, this, &ConnectionsWindow::retranslateUi);
emit ctrl()->retranslateUi();
retranslateUi();
}
void ConnectionsWindow::setupStateWatcher()
@ -97,7 +96,7 @@ void ConnectionsWindow::setupStateWatcher()
m_stateWatcher->install(this);
}
void ConnectionsWindow::onRetranslateUi()
void ConnectionsWindow::retranslateUi()
{
this->unsetLocale();

View File

@ -33,13 +33,12 @@ public:
void saveWindowState();
void restoreWindowState();
protected slots:
void onRetranslateUi();
private:
void setupController();
void setupStateWatcher();
void retranslateUi();
void setupUi();
QLayout *setupHeader();
void setupLogOptions();

View File

@ -45,7 +45,7 @@ void OptionsWindow::setupController()
ctrl()->initialize();
connect(ctrl(), &OptionsController::editedChanged, this, &QWidget::setWindowModified);
connect(ctrl(), &OptionsController::retranslateUi, this, &OptionsWindow::onRetranslateUi);
connect(ctrl(), &OptionsController::retranslateUi, this, &OptionsWindow::retranslateUi);
emit ctrl()->retranslateUi();
}
@ -71,7 +71,7 @@ void OptionsWindow::keyPressEvent(QKeyEvent *event)
}
}
void OptionsWindow::onRetranslateUi()
void OptionsWindow::retranslateUi()
{
this->unsetLocale();

View File

@ -22,9 +22,6 @@ public:
void saveWindowState();
void restoreWindowState();
protected slots:
void onRetranslateUi();
protected:
void keyPressEvent(QKeyEvent *event) override;
@ -32,6 +29,8 @@ private:
void setupController();
void setupStateWatcher();
void retranslateUi();
void setupUi();
private:

View File

@ -0,0 +1,416 @@
#include "programeditdialog.h"
#include <QButtonGroup>
#include <QCheckBox>
#include <QComboBox>
#include <QDateTimeEdit>
#include <QFormLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QRadioButton>
#include <QSpinBox>
#include "../../conf/confmanager.h"
#include "../../fortmanager.h"
#include "../../util/app/appinfocache.h"
#include "../../util/iconcache.h"
#include "../controls/checkspincombo.h"
#include "../controls/controlutil.h"
#include "programscontroller.h"
namespace {
const ValuesList appBlockInHourValues = { 3, 1, 6, 12, 24, 24 * 7, 24 * 30 };
}
ProgramEditDialog::ProgramEditDialog(ProgramsController *ctrl, QWidget *parent) :
QDialog(parent), m_ctrl(ctrl)
{
setupUi();
setupController();
}
FortManager *ProgramEditDialog::fortManager() const
{
return ctrl()->fortManager();
}
ConfManager *ProgramEditDialog::confManager() const
{
return ctrl()->confManager();
}
AppListModel *ProgramEditDialog::appListModel() const
{
return fortManager()->appListModel();
}
AppInfoCache *ProgramEditDialog::appInfoCache() const
{
return appListModel()->appInfoCache();
}
void ProgramEditDialog::initialize(const AppRow &appRow, const QVector<qint64> &appIdList)
{
m_appRow = appRow;
m_appIdList = appIdList;
const bool isSingleSelection = (appIdList.size() <= 1);
const bool isPathEditable = isSingleSelection && appRow.appId == 0;
m_editPath->setText(isSingleSelection ? appRow.appPath : "*");
m_editPath->setReadOnly(!isPathEditable);
m_editPath->setClearButtonEnabled(isPathEditable);
m_editPath->setEnabled(isSingleSelection);
m_btSelectFile->setEnabled(isPathEditable);
m_editName->setText(isSingleSelection ? appRow.appName : QString());
m_editName->setEnabled(isSingleSelection);
m_editName->setClearButtonEnabled(isSingleSelection);
m_btGetName->setEnabled(isSingleSelection);
m_comboAppGroup->setCurrentIndex(appRow.groupIndex);
m_cbUseGroupPerm->setChecked(appRow.useGroupPerm);
m_rbAllowApp->setChecked(!appRow.blocked);
m_rbBlockApp->setChecked(appRow.blocked);
m_cscBlockAppIn->checkBox()->setChecked(false);
m_cscBlockAppIn->spinBox()->setValue(1);
m_cbBlockAppAt->setChecked(!appRow.endTime.isNull());
m_dteBlockAppAt->setDateTime(appRow.endTime);
m_dteBlockAppAt->setMinimumDateTime(QDateTime::currentDateTime());
m_cbBlockAppNone->setChecked(appRow.endTime.isNull());
if (isSingleSelection && appRow.appName.isEmpty()) {
m_btGetName->click(); // Auto-fill the name
}
}
void ProgramEditDialog::activate()
{
this->raise();
this->activateWindow();
m_editPath->selectAll();
m_editPath->setFocus();
}
void ProgramEditDialog::setupController()
{
connect(ctrl(), &ProgramsController::retranslateUi, this, &ProgramEditDialog::retranslateUi);
retranslateUi();
}
void ProgramEditDialog::retranslateUi()
{
this->unsetLocale();
m_labelEditPath->setText(tr("Program Path:"));
m_btSelectFile->setToolTip(tr("Select File"));
m_labelEditName->setText(tr("Program Name:"));
m_btGetName->setToolTip(tr("Get Program Name"));
m_labelAppGroup->setText(tr("Application Group:"));
m_cbUseGroupPerm->setText(tr("Use Application Group's Enabled State"));
m_rbAllowApp->setText(tr("Allow"));
m_rbBlockApp->setText(tr("Block"));
m_cscBlockAppIn->checkBox()->setText(tr("Block In:"));
retranslateAppBlockInHours();
m_cbBlockAppAt->setText(tr("Block At:"));
m_dteBlockAppAt->unsetLocale();
m_cbBlockAppNone->setText(tr("Forever"));
m_btOk->setText(tr("OK"));
m_btCancel->setText(tr("Cancel"));
this->setWindowTitle(tr("Edit Program"));
}
void ProgramEditDialog::retranslateAppBlockInHours()
{
const QStringList list = { tr("Custom"), tr("1 hour"), tr("6 hours"), tr("12 hours"), tr("Day"),
tr("Week"), tr("Month") };
m_cscBlockAppIn->setNames(list);
m_cscBlockAppIn->spinBox()->setSuffix(tr(" hour(s)"));
}
void ProgramEditDialog::setupUi()
{
// Form Layout
auto formLayout = setupAppLayout();
// Allow/Block
auto allowLayout = setupAllowLayout();
// Block at specified date & time
auto blockAtLayout = setupCheckDateTimeEdit();
// Eclusive End Time CheckBoxes Group
setupAllowEclusiveGroup();
// OK/Cancel
auto buttonsLayout = new QHBoxLayout();
m_btOk = ControlUtil::createButton(QString(), [&] {
if (save()) {
this->close();
}
});
m_btOk->setDefault(true);
m_btCancel = new QPushButton();
connect(m_btCancel, &QAbstractButton::clicked, this, &QWidget::close);
buttonsLayout->addWidget(m_btOk, 1, Qt::AlignRight);
buttonsLayout->addWidget(m_btCancel);
// Form
auto layout = new QVBoxLayout();
layout->addLayout(formLayout);
layout->addWidget(ControlUtil::createSeparator());
layout->addLayout(allowLayout);
layout->addWidget(m_cscBlockAppIn);
layout->addLayout(blockAtLayout);
layout->addWidget(m_cbBlockAppNone);
layout->addStretch();
layout->addWidget(ControlUtil::createSeparator());
layout->addLayout(buttonsLayout);
this->setLayout(layout);
// Font
this->setFont(QFont("Tahoma", 9));
// Modality & Size Grip
this->setWindowModality(Qt::WindowModal);
this->setSizeGripEnabled(true);
// Size
this->setMinimumWidth(500);
}
QLayout *ProgramEditDialog::setupAppLayout()
{
auto layout = new QFormLayout();
// App Path
auto pathLayout = setupAppPathLayout();
layout->addRow("Program Path:", pathLayout);
m_labelEditPath = qobject_cast<QLabel *>(layout->labelForField(pathLayout));
// App Name
auto nameLayout = setupAppNameLayout();
layout->addRow("Program Name:", nameLayout);
m_labelEditName = qobject_cast<QLabel *>(layout->labelForField(nameLayout));
// App Group
setupComboAppGroups();
layout->addRow("Application Group:", m_comboAppGroup);
m_labelAppGroup = qobject_cast<QLabel *>(layout->labelForField(m_comboAppGroup));
// Use Group Perm.
m_cbUseGroupPerm = new QCheckBox();
layout->addRow(QString(), m_cbUseGroupPerm);
return layout;
}
QLayout *ProgramEditDialog::setupAppPathLayout()
{
auto layout = new QHBoxLayout();
m_editPath = new QLineEdit();
m_btSelectFile = ControlUtil::createFlatButton(":/icons/folder-open.png", [&] {
const auto filePath = ControlUtil::getOpenFileName(
m_labelEditPath->text(), tr("Programs (*.exe);;All files (*.*)"));
if (!filePath.isEmpty()) {
m_editPath->setText(filePath);
m_btGetName->click(); // Auto-fill the name
}
});
layout->addWidget(m_editPath);
layout->addWidget(m_btSelectFile);
return layout;
}
QLayout *ProgramEditDialog::setupAppNameLayout()
{
auto layout = new QHBoxLayout();
m_editName = new QLineEdit();
const auto updateAppName = [&] {
const auto appPath = m_editPath->text();
if (appPath.isEmpty())
return;
const QString appName = appInfoCache()->appName(appPath);
m_editName->setText(appName);
};
m_btGetName = ControlUtil::createFlatButton(":/icons/sign-sync.png", updateAppName);
layout->addWidget(m_editName);
layout->addWidget(m_btGetName);
return layout;
}
void ProgramEditDialog::setupComboAppGroups()
{
m_comboAppGroup = new QComboBox();
const auto refreshComboAppGroups = [&](bool onlyFlags = false) {
if (onlyFlags)
return;
m_comboAppGroup->clear();
m_comboAppGroup->addItems(appListModel()->appGroupNames());
m_comboAppGroup->setCurrentIndex(0);
};
refreshComboAppGroups();
connect(confManager(), &ConfManager::confSaved, this, refreshComboAppGroups);
}
QLayout *ProgramEditDialog::setupAllowLayout()
{
auto allowLayout = new QHBoxLayout();
allowLayout->setSpacing(20);
m_rbAllowApp = new QRadioButton();
m_rbAllowApp->setIcon(IconCache::icon(":/icons/sign-check.png"));
m_rbAllowApp->setChecked(true);
m_rbBlockApp = new QRadioButton();
m_rbBlockApp->setIcon(IconCache::icon(":/icons/sign-ban.png"));
allowLayout->addWidget(m_rbAllowApp, 1, Qt::AlignRight);
allowLayout->addWidget(m_rbBlockApp, 1, Qt::AlignLeft);
// Block after N hours
m_cscBlockAppIn = new CheckSpinCombo();
m_cscBlockAppIn->spinBox()->setRange(1, 24 * 30 * 12); // ~Year
m_cscBlockAppIn->setValues(appBlockInHourValues);
m_cscBlockAppIn->setNamesByValues();
// Allow Forever
m_cbBlockAppNone = new QCheckBox();
connect(m_rbAllowApp, &QRadioButton::toggled, this, [&](bool checked) {
m_cbBlockAppNone->setEnabled(checked);
m_cscBlockAppIn->setEnabled(checked);
m_cbBlockAppAt->setEnabled(checked);
m_dteBlockAppAt->setEnabled(checked);
});
return allowLayout;
}
QLayout *ProgramEditDialog::setupCheckDateTimeEdit()
{
m_cbBlockAppAt = new QCheckBox();
m_dteBlockAppAt = new QDateTimeEdit();
m_dteBlockAppAt->setCalendarPopup(true);
return ControlUtil::createRowLayout(m_cbBlockAppAt, m_dteBlockAppAt);
}
void ProgramEditDialog::setupAllowEclusiveGroup()
{
auto group = new QButtonGroup(this);
group->setExclusive(true);
group->addButton(m_cscBlockAppIn->checkBox());
group->addButton(m_cbBlockAppAt);
group->addButton(m_cbBlockAppNone);
}
bool ProgramEditDialog::save()
{
const int appIdsCount = m_appIdList.size();
const bool isSingleSelection = (appIdsCount <= 1);
const QString appPath = m_editPath->text();
if (isSingleSelection && appPath.isEmpty()) {
m_editPath->setFocus();
return false;
}
const QString appName = m_editName->text();
if (isSingleSelection && appName.isEmpty()) {
m_editName->setFocus();
return false;
}
const int groupIndex = m_comboAppGroup->currentIndex();
const bool useGroupPerm = m_cbUseGroupPerm->isChecked();
const bool blocked = m_rbBlockApp->isChecked();
QDateTime endTime;
if (!blocked) {
if (m_cscBlockAppIn->checkBox()->isChecked()) {
const int hours = m_cscBlockAppIn->spinBox()->value();
endTime = QDateTime::currentDateTime().addSecs(hours * 60 * 60);
} else if (m_cbBlockAppAt->isChecked()) {
endTime = m_dteBlockAppAt->dateTime();
}
}
// Add new app or edit non-selected app
if (appIdsCount == 0) {
return appListModel()->addApp(appPath, appName, endTime, groupIndex, useGroupPerm, blocked);
}
// Edit selected app
if (isSingleSelection) {
return saveApp(appPath, appName, endTime, groupIndex, useGroupPerm, blocked);
}
// Edit selected apps
return saveMulti(endTime, groupIndex, useGroupPerm, blocked);
}
bool ProgramEditDialog::saveApp(const QString &appPath, const QString &appName,
const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked)
{
const bool appEdited = (appPath != m_appRow.appPath || groupIndex != m_appRow.groupIndex
|| useGroupPerm != m_appRow.useGroupPerm || blocked != m_appRow.blocked
|| endTime != m_appRow.endTime);
if (appEdited) {
return appListModel()->updateApp(
m_appRow.appId, appPath, appName, endTime, groupIndex, useGroupPerm, blocked);
}
if (appName == m_appRow.appName)
return true;
return appListModel()->updateAppName(m_appRow.appId, appName);
}
bool ProgramEditDialog::saveMulti(
const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked)
{
for (qint64 appId : m_appIdList) {
const auto appRow = appListModel()->appRowById(appId);
if (!appListModel()->updateApp(appId, appRow.appPath, appRow.appName, endTime, groupIndex,
useGroupPerm, blocked))
return false;
}
return true;
}

View File

@ -0,0 +1,84 @@
#ifndef PROGRAMEDITDIALOG_H
#define PROGRAMEDITDIALOG_H
#include <QDialog>
#include "../../model/applistmodel.h"
QT_FORWARD_DECLARE_CLASS(QCheckBox)
QT_FORWARD_DECLARE_CLASS(QComboBox)
QT_FORWARD_DECLARE_CLASS(QDateTimeEdit)
QT_FORWARD_DECLARE_CLASS(QLabel)
QT_FORWARD_DECLARE_CLASS(QLineEdit)
QT_FORWARD_DECLARE_CLASS(QPushButton)
QT_FORWARD_DECLARE_CLASS(QRadioButton)
class AppInfoCache;
class CheckSpinCombo;
class ConfManager;
class FortManager;
class ProgramsController;
class ProgramEditDialog : public QDialog
{
Q_OBJECT
public:
explicit ProgramEditDialog(ProgramsController *ctrl, QWidget *parent = nullptr);
ProgramsController *ctrl() const { return m_ctrl; }
FortManager *fortManager() const;
ConfManager *confManager() const;
AppListModel *appListModel() const;
AppInfoCache *appInfoCache() const;
void initialize(const AppRow &appRow, const QVector<qint64> &appIdList);
void activate();
private:
void setupController();
void retranslateUi();
void retranslateAppBlockInHours();
void setupUi();
QLayout *setupAppLayout();
QLayout *setupAppPathLayout();
QLayout *setupAppNameLayout();
void setupComboAppGroups();
QLayout *setupAllowLayout();
QLayout *setupCheckDateTimeEdit();
void setupAllowEclusiveGroup();
bool save();
bool saveApp(const QString &appPath, const QString &appName, const QDateTime &endTime,
int groupIndex, bool useGroupPerm, bool blocked);
bool saveMulti(const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked);
private:
ProgramsController *m_ctrl = nullptr;
QLabel *m_labelEditPath = nullptr;
QLineEdit *m_editPath = nullptr;
QPushButton *m_btSelectFile = nullptr;
QLabel *m_labelEditName = nullptr;
QLineEdit *m_editName = nullptr;
QPushButton *m_btGetName = nullptr;
QLabel *m_labelAppGroup = nullptr;
QComboBox *m_comboAppGroup = nullptr;
QCheckBox *m_cbUseGroupPerm = nullptr;
QRadioButton *m_rbAllowApp = nullptr;
QRadioButton *m_rbBlockApp = nullptr;
CheckSpinCombo *m_cscBlockAppIn = nullptr;
QCheckBox *m_cbBlockAppAt = nullptr;
QDateTimeEdit *m_dteBlockAppAt = nullptr;
QCheckBox *m_cbBlockAppNone = nullptr;
QPushButton *m_btOk = nullptr;
QPushButton *m_btCancel = nullptr;
AppRow m_appRow;
QVector<qint64> m_appIdList;
};
#endif // PROGRAMEDITDIALOG_H

View File

@ -1,22 +1,11 @@
#include "programswindow.h"
#include <QButtonGroup>
#include <QCheckBox>
#include <QComboBox>
#include <QDateTimeEdit>
#include <QDialog>
#include <QFormLayout>
#include <QHeaderView>
#include <QLabel>
#include <QLineEdit>
#include <QMenu>
#include <QPushButton>
#include <QRadioButton>
#include <QSpinBox>
#include <QVBoxLayout>
#include "../../conf/appgroup.h"
#include "../../conf/confmanager.h"
#include "../../conf/firewallconf.h"
#include "../../fortmanager.h"
#include "../../fortsettings.h"
@ -26,17 +15,15 @@
#include "../../util/iconcache.h"
#include "../../util/window/widgetwindowstatewatcher.h"
#include "../controls/appinforow.h"
#include "../controls/checkspincombo.h"
#include "../controls/controlutil.h"
#include "../controls/tableview.h"
#include "programeditdialog.h"
#include "programscontroller.h"
namespace {
#define APPS_HEADER_VERSION 3
const ValuesList appBlockInHourValues = { 3, 1, 6, 12, 24, 24 * 7, 24 * 30 };
}
ProgramsWindow::ProgramsWindow(FortManager *fortManager, QWidget *parent) :
@ -45,6 +32,7 @@ ProgramsWindow::ProgramsWindow(FortManager *fortManager, QWidget *parent) :
m_stateWatcher(new WidgetWindowStateWatcher(this))
{
setupUi();
setupAppEditForm();
setupController();
setupStateWatcher();
}
@ -59,11 +47,6 @@ FortSettings *ProgramsWindow::settings() const
return ctrl()->settings();
}
ConfManager *ProgramsWindow::confManager() const
{
return ctrl()->confManager();
}
FirewallConf *ProgramsWindow::conf() const
{
return ctrl()->conf();
@ -102,9 +85,9 @@ void ProgramsWindow::restoreWindowState()
void ProgramsWindow::setupController()
{
connect(ctrl(), &ProgramsController::retranslateUi, this, &ProgramsWindow::onRetranslateUi);
connect(ctrl(), &ProgramsController::retranslateUi, this, &ProgramsWindow::retranslateUi);
emit ctrl()->retranslateUi();
retranslateUi();
}
void ProgramsWindow::setupStateWatcher()
@ -112,7 +95,7 @@ void ProgramsWindow::setupStateWatcher()
m_stateWatcher->install(this);
}
void ProgramsWindow::onRetranslateUi()
void ProgramsWindow::retranslateUi()
{
this->unsetLocale();
@ -128,26 +111,6 @@ void ProgramsWindow::onRetranslateUi()
m_btBlockApp->setText(tr("Block"));
m_btRemoveApp->setText(tr("Remove"));
m_formAppEdit->unsetLocale();
m_formAppEdit->setWindowTitle(tr("Edit Program"));
m_labelEditPath->setText(tr("Program Path:"));
m_btSelectFile->setToolTip(tr("Select File"));
m_labelEditName->setText(tr("Program Name:"));
m_btGetName->setToolTip(tr("Get Program Name"));
m_labelAppGroup->setText(tr("Application Group:"));
m_cbUseGroupPerm->setText(tr("Use Application Group's Enabled State"));
m_rbAllowApp->setText(tr("Allow"));
m_rbBlockApp->setText(tr("Block"));
m_cscBlockAppIn->checkBox()->setText(tr("Block In:"));
retranslateAppBlockInHours();
m_cbBlockAppAt->setText(tr("Block At:"));
m_dteBlockAppAt->unsetLocale();
m_cbBlockAppNone->setText(tr("Forever"));
m_btEditOk->setText(tr("OK"));
m_btEditCancel->setText(tr("Cancel"));
m_btLogOptions->setText(tr("Options"));
m_cbLogBlocked->setText(tr("Collect New Blocked Programs"));
@ -158,23 +121,11 @@ void ProgramsWindow::onRetranslateUi()
this->setWindowTitle(tr("Programs"));
}
void ProgramsWindow::retranslateAppBlockInHours()
{
const QStringList list = { tr("Custom"), tr("1 hour"), tr("6 hours"), tr("12 hours"), tr("Day"),
tr("Week"), tr("Month") };
m_cscBlockAppIn->setNames(list);
m_cscBlockAppIn->spinBox()->setSuffix(tr(" hour(s)"));
}
void ProgramsWindow::setupUi()
{
auto layout = new QVBoxLayout();
layout->setContentsMargins(6, 6, 6, 6);
// App Add/Edit Form
setupAppEditForm();
// Header
auto header = setupHeader();
layout->addLayout(header);
@ -203,202 +154,6 @@ void ProgramsWindow::setupUi()
this->setMinimumSize(500, 400);
}
void ProgramsWindow::setupAppEditForm()
{
// Dialog
m_formAppEdit = new QDialog(this);
m_formAppEdit->setWindowModality(Qt::WindowModal);
m_formAppEdit->setSizeGripEnabled(true);
m_formAppEdit->setMinimumWidth(500);
// Form Layout
auto formLayout = setupAppEditFormAppLayout();
// Allow/Block
auto allowLayout = setupAppEditFormAllowLayout();
// Block at specified date & time
auto blockAtLayout = setupCheckDateTimeEdit();
// Eclusive End Time CheckBoxes Group
setupAllowEclusiveGroup();
// OK/Cancel
auto buttonsLayout = new QHBoxLayout();
m_btEditOk = ControlUtil::createButton(QString(), [&] {
if (saveAppEditForm()) {
m_formAppEdit->close();
}
});
m_btEditOk->setDefault(true);
m_btEditCancel = new QPushButton();
connect(m_btEditCancel, &QAbstractButton::clicked, m_formAppEdit, &QWidget::close);
buttonsLayout->addWidget(m_btEditOk, 1, Qt::AlignRight);
buttonsLayout->addWidget(m_btEditCancel);
// Form
auto layout = new QVBoxLayout();
layout->addLayout(formLayout);
layout->addWidget(ControlUtil::createSeparator());
layout->addLayout(allowLayout);
layout->addWidget(m_cscBlockAppIn);
layout->addLayout(blockAtLayout);
layout->addWidget(m_cbBlockAppNone);
layout->addStretch();
layout->addWidget(ControlUtil::createSeparator());
layout->addLayout(buttonsLayout);
m_formAppEdit->setLayout(layout);
}
QLayout *ProgramsWindow::setupAppEditFormAppLayout()
{
auto layout = new QFormLayout();
// App Path
auto pathLayout = setupAppEditFormAppPathLayout();
layout->addRow("Program Path:", pathLayout);
m_labelEditPath = qobject_cast<QLabel *>(layout->labelForField(pathLayout));
// App Name
auto nameLayout = setupAppEditFormAppNameLayout();
layout->addRow("Program Name:", nameLayout);
m_labelEditName = qobject_cast<QLabel *>(layout->labelForField(nameLayout));
// App Group
setupComboAppGroups();
layout->addRow("Application Group:", m_comboAppGroup);
m_labelAppGroup = qobject_cast<QLabel *>(layout->labelForField(m_comboAppGroup));
// Use Group Perm.
m_cbUseGroupPerm = new QCheckBox();
layout->addRow(QString(), m_cbUseGroupPerm);
return layout;
}
QLayout *ProgramsWindow::setupAppEditFormAppPathLayout()
{
auto layout = new QHBoxLayout();
m_editPath = new QLineEdit();
m_btSelectFile = ControlUtil::createFlatButton(":/icons/folder-open.png", [&] {
const auto filePath = ControlUtil::getOpenFileName(
m_labelEditPath->text(), tr("Programs (*.exe);;All files (*.*)"));
if (!filePath.isEmpty()) {
m_editPath->setText(filePath);
}
});
layout->addWidget(m_editPath);
layout->addWidget(m_btSelectFile);
return layout;
}
QLayout *ProgramsWindow::setupAppEditFormAppNameLayout()
{
auto layout = new QHBoxLayout();
m_editName = new QLineEdit();
const auto updateAppName = [&] {
const auto appPath = m_editPath->text();
if (appPath.isEmpty())
return;
const QString appName = appInfoCache()->appName(appPath);
m_editName->setText(appName);
};
m_btGetName = ControlUtil::createFlatButton(":/icons/sign-sync.png", updateAppName);
layout->addWidget(m_editName);
layout->addWidget(m_btGetName);
return layout;
}
void ProgramsWindow::setupComboAppGroups()
{
m_comboAppGroup = new QComboBox();
const auto refreshComboAppGroups = [&](bool onlyFlags = false) {
if (onlyFlags)
return;
m_comboAppGroup->clear();
m_comboAppGroup->addItems(appListModel()->appGroupNames());
m_comboAppGroup->setCurrentIndex(0);
};
refreshComboAppGroups();
connect(confManager(), &ConfManager::confSaved, this, refreshComboAppGroups);
}
QLayout *ProgramsWindow::setupAppEditFormAllowLayout()
{
auto allowLayout = new QHBoxLayout();
allowLayout->setSpacing(20);
m_rbAllowApp = new QRadioButton();
m_rbAllowApp->setIcon(IconCache::icon(":/icons/sign-check.png"));
m_rbAllowApp->setChecked(true);
m_rbBlockApp = new QRadioButton();
m_rbBlockApp->setIcon(IconCache::icon(":/icons/sign-ban.png"));
allowLayout->addWidget(m_rbAllowApp, 1, Qt::AlignRight);
allowLayout->addWidget(m_rbBlockApp, 1, Qt::AlignLeft);
// Block after N hours
m_cscBlockAppIn = new CheckSpinCombo();
m_cscBlockAppIn->spinBox()->setRange(1, 24 * 30 * 12); // ~Year
m_cscBlockAppIn->setValues(appBlockInHourValues);
m_cscBlockAppIn->setNamesByValues();
// Allow Forever
m_cbBlockAppNone = new QCheckBox();
connect(m_rbAllowApp, &QRadioButton::toggled, this, [&](bool checked) {
m_cbBlockAppNone->setEnabled(checked);
m_cscBlockAppIn->setEnabled(checked);
m_cbBlockAppAt->setEnabled(checked);
m_dteBlockAppAt->setEnabled(checked);
});
return allowLayout;
}
QLayout *ProgramsWindow::setupCheckDateTimeEdit()
{
m_cbBlockAppAt = new QCheckBox();
m_dteBlockAppAt = new QDateTimeEdit();
m_dteBlockAppAt->setCalendarPopup(true);
return ControlUtil::createRowLayout(m_cbBlockAppAt, m_dteBlockAppAt);
}
void ProgramsWindow::setupAllowEclusiveGroup()
{
auto group = new QButtonGroup(this);
group->setExclusive(true);
group->addButton(m_cscBlockAppIn->checkBox());
group->addButton(m_cbBlockAppAt);
group->addButton(m_cbBlockAppNone);
}
QLayout *ProgramsWindow::setupHeader()
{
auto layout = new QHBoxLayout();
@ -429,8 +184,8 @@ QLayout *ProgramsWindow::setupHeader()
connect(m_actAllowApp, &QAction::triggered, this, [&] { updateSelectedApps(false); });
connect(m_actBlockApp, &QAction::triggered, this, [&] { updateSelectedApps(true); });
connect(m_actAddApp, &QAction::triggered, this, [&] { updateAppEditForm(false); });
connect(m_actEditApp, &QAction::triggered, this, [&] { updateAppEditForm(true); });
connect(m_actAddApp, &QAction::triggered, this, &ProgramsWindow::addNewProgram);
connect(m_actEditApp, &QAction::triggered, this, &ProgramsWindow::editSelectedPrograms);
connect(m_actRemoveApp, &QAction::triggered, this, [&] {
if (fortManager()->showQuestionBox(tr("Are you sure to remove selected program(s)?"))) {
deleteSelectedApps();
@ -567,162 +322,57 @@ void ProgramsWindow::setupTableAppsChanged()
connect(m_appListView, &TableView::currentIndexChanged, this, refreshTableAppsChanged);
}
bool ProgramsWindow::openAppEditFormByPath(const QString &appPath)
void ProgramsWindow::setupAppEditForm()
{
m_formAppEdit = new ProgramEditDialog(ctrl(), this);
}
bool ProgramsWindow::editProgramByPath(const QString &appPath)
{
if (m_formAppEdit->isVisible()) {
activateAppEditForm();
m_formAppEdit->activate();
return false;
}
const auto appRow = appListModel()->appRowByPath(appPath);
openAppEditFormByRow(appRow, false, true);
openAppEditForm(appRow);
return true;
}
void ProgramsWindow::updateAppEditForm(bool editCurrentApp)
void ProgramsWindow::addNewProgram()
{
bool isSingleSelection = true;
AppRow appRow;
if (editCurrentApp) {
const auto rows = m_appListView->selectedRows();
if (rows.isEmpty())
return;
isSingleSelection = (rows.size() == 1);
const auto appIndex = appListCurrentIndex();
appRow = appListModel()->appRowAt(appIndex);
}
openAppEditFormByRow(appRow, editCurrentApp, isSingleSelection);
openAppEditForm({});
}
void ProgramsWindow::openAppEditFormByRow(
const AppRow &appRow, bool editCurrentApp, bool isSingleSelection)
{
const bool isPathEditable = isSingleSelection && appRow.appId == 0;
m_formAppForSelected = editCurrentApp;
m_editPath->setText(isSingleSelection ? appRow.appPath : "*");
m_editPath->setReadOnly(!isPathEditable);
m_editPath->setClearButtonEnabled(isPathEditable);
m_editPath->setEnabled(isSingleSelection);
m_btSelectFile->setEnabled(isPathEditable);
m_editName->setText(isSingleSelection ? appRow.appName : QString());
m_editName->setEnabled(isSingleSelection);
m_editName->setClearButtonEnabled(isSingleSelection);
m_btGetName->setEnabled(isSingleSelection);
m_comboAppGroup->setCurrentIndex(appRow.groupIndex);
m_cbUseGroupPerm->setChecked(appRow.useGroupPerm);
m_rbAllowApp->setChecked(!appRow.blocked);
m_rbBlockApp->setChecked(appRow.blocked);
m_cscBlockAppIn->checkBox()->setChecked(false);
m_cscBlockAppIn->spinBox()->setValue(1);
m_cbBlockAppAt->setChecked(!appRow.endTime.isNull());
m_dteBlockAppAt->setDateTime(appRow.endTime);
m_dteBlockAppAt->setMinimumDateTime(QDateTime::currentDateTime());
m_cbBlockAppNone->setChecked(appRow.endTime.isNull());
if (isSingleSelection && appRow.appName.isEmpty()) {
m_btGetName->click(); // Auto-fill name
}
m_formAppEdit->show();
activateAppEditForm();
}
void ProgramsWindow::activateAppEditForm()
{
m_formAppEdit->activateWindow();
m_editPath->selectAll();
m_editPath->setFocus();
}
bool ProgramsWindow::saveAppEditForm()
{
const QString appPath = m_editPath->text();
if (appPath.isEmpty()) {
m_editPath->setFocus();
return false;
}
const QString appName = m_editName->text();
if (appName.isEmpty()) {
m_editName->setFocus();
return false;
}
const int groupIndex = m_comboAppGroup->currentIndex();
const bool useGroupPerm = m_cbUseGroupPerm->isChecked();
const bool blocked = m_rbBlockApp->isChecked();
QDateTime endTime;
if (!blocked) {
if (m_cscBlockAppIn->checkBox()->isChecked()) {
const int hours = m_cscBlockAppIn->spinBox()->value();
endTime = QDateTime::currentDateTime().addSecs(hours * 60 * 60);
} else if (m_cbBlockAppAt->isChecked()) {
endTime = m_dteBlockAppAt->dateTime();
}
}
// Add new app or edit non-selected app
if (!m_formAppForSelected) {
return appListModel()->addApp(appPath, appName, endTime, groupIndex, useGroupPerm, blocked);
}
// Edit selected apps
return saveAppEditFormMulti(appPath, appName, endTime, groupIndex, useGroupPerm, blocked);
}
bool ProgramsWindow::saveAppEditFormMulti(const QString &appPath, const QString &appName,
const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked)
void ProgramsWindow::editSelectedPrograms()
{
const auto rows = m_appListView->selectedRows();
const bool isSingleSelection = (rows.size() == 1);
if (rows.isEmpty())
return;
if (isSingleSelection) {
bool ok;
if (!saveAppEditFormCheckEdited(
appPath, appName, endTime, groupIndex, useGroupPerm, blocked, ok))
return ok;
}
bool isFirstAppRow = true;
AppRow firstAppRow;
QVector<qint64> appIdList;
for (int row : rows) {
const auto appRow = appListModel()->appRowAt(row);
const auto rowAppPath = isSingleSelection ? appPath : appRow.appPath;
const auto rowAppName = isSingleSelection ? appName : appRow.appName;
if (!appListModel()->updateApp(appRow.appId, rowAppPath, rowAppName, endTime, groupIndex,
useGroupPerm, blocked))
return false;
if (isFirstAppRow) {
isFirstAppRow = false;
firstAppRow = appRow;
}
appIdList.append(appRow.appId);
}
return true;
openAppEditForm(firstAppRow, appIdList);
}
bool ProgramsWindow::saveAppEditFormCheckEdited(const QString &appPath, const QString &appName,
const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked, bool &ok)
void ProgramsWindow::openAppEditForm(const AppRow &appRow, const QVector<qint64> &appIdList)
{
const int appIndex = appListCurrentIndex();
const auto appRow = appListModel()->appRowAt(appIndex);
m_formAppEdit->initialize(appRow, appIdList);
const bool appNameEdited = (appName != appRow.appName);
const bool appEdited = (appPath != appRow.appPath || groupIndex != appRow.groupIndex
|| useGroupPerm != appRow.useGroupPerm || blocked != appRow.blocked
|| endTime != appRow.endTime);
if (appEdited)
return true;
ok = !appNameEdited || appListModel()->updateAppName(appRow.appId, appName);
return false;
m_formAppEdit->show();
m_formAppEdit->activate();
}
void ProgramsWindow::updateApp(int row, bool blocked)

View File

@ -4,22 +4,15 @@
#include "../../util/window/widgetwindow.h"
QT_FORWARD_DECLARE_CLASS(QCheckBox)
QT_FORWARD_DECLARE_CLASS(QComboBox)
QT_FORWARD_DECLARE_CLASS(QDateTimeEdit)
QT_FORWARD_DECLARE_CLASS(QDialog)
QT_FORWARD_DECLARE_CLASS(QLabel)
QT_FORWARD_DECLARE_CLASS(QLineEdit)
QT_FORWARD_DECLARE_CLASS(QPushButton)
QT_FORWARD_DECLARE_CLASS(QRadioButton)
class AppInfoCache;
class AppInfoRow;
class AppListModel;
class CheckSpinCombo;
class ConfManager;
class FirewallConf;
class FortManager;
class FortSettings;
class ProgramEditDialog;
class ProgramsController;
class TableView;
class WidgetWindowStateWatcher;
@ -36,7 +29,6 @@ public:
ProgramsController *ctrl() const { return m_ctrl; }
FortManager *fortManager() const;
FortSettings *settings() const;
ConfManager *confManager() const;
FirewallConf *conf() const;
AppListModel *appListModel() const;
AppInfoCache *appInfoCache() const;
@ -44,26 +36,15 @@ public:
void saveWindowState();
void restoreWindowState();
bool openAppEditFormByPath(const QString &appPath);
protected slots:
void onRetranslateUi();
bool editProgramByPath(const QString &appPath);
private:
void setupController();
void setupStateWatcher();
void retranslateAppBlockInHours();
void retranslateUi();
void setupUi();
void setupAppEditForm();
QLayout *setupAppEditFormAppLayout();
QLayout *setupAppEditFormAppPathLayout();
QLayout *setupAppEditFormAppNameLayout();
void setupComboAppGroups();
QLayout *setupAppEditFormAllowLayout();
QLayout *setupCheckDateTimeEdit();
void setupAllowEclusiveGroup();
QLayout *setupHeader();
void setupLogOptions();
void setupLogBlocked();
@ -72,15 +53,11 @@ private:
void setupAppInfoRow();
void setupTableAppsChanged();
void updateAppEditForm(bool editCurrentApp);
void openAppEditFormByRow(const AppRow &appRow, bool editCurrentApp, bool isSingleSelection);
void activateAppEditForm();
void setupAppEditForm();
bool saveAppEditForm();
bool saveAppEditFormMulti(const QString &appPath, const QString &appName,
const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked);
bool saveAppEditFormCheckEdited(const QString &appPath, const QString &appName,
const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked, bool &ok);
void addNewProgram();
void editSelectedPrograms();
void openAppEditForm(const AppRow &appRow, const QVector<qint64> &appIdList = {});
void updateApp(int row, bool blocked);
void deleteApp(int row);
@ -92,12 +69,9 @@ private:
QString appListCurrentPath() const;
private:
bool m_formAppForSelected = false;
ProgramsController *m_ctrl = nullptr;
WidgetWindowStateWatcher *m_stateWatcher = nullptr;
QPushButton *m_btEdit = nullptr;
QAction *m_actAllowApp = nullptr;
QAction *m_actBlockApp = nullptr;
QAction *m_actAddApp = nullptr;
@ -107,26 +81,10 @@ private:
QPushButton *m_btAllowApp = nullptr;
QPushButton *m_btBlockApp = nullptr;
QPushButton *m_btRemoveApp = nullptr;
QLabel *m_labelEditPath = nullptr;
QLineEdit *m_editPath = nullptr;
QPushButton *m_btSelectFile = nullptr;
QLabel *m_labelEditName = nullptr;
QLineEdit *m_editName = nullptr;
QPushButton *m_btGetName = nullptr;
QLabel *m_labelAppGroup = nullptr;
QComboBox *m_comboAppGroup = nullptr;
QCheckBox *m_cbUseGroupPerm = nullptr;
QRadioButton *m_rbAllowApp = nullptr;
QRadioButton *m_rbBlockApp = nullptr;
CheckSpinCombo *m_cscBlockAppIn = nullptr;
QCheckBox *m_cbBlockAppAt = nullptr;
QDateTimeEdit *m_dteBlockAppAt = nullptr;
QCheckBox *m_cbBlockAppNone = nullptr;
QPushButton *m_btEditOk = nullptr;
QPushButton *m_btEditCancel = nullptr;
QDialog *m_formAppEdit = nullptr;
QPushButton *m_btEdit = nullptr;
QPushButton *m_btLogOptions = nullptr;
QCheckBox *m_cbLogBlocked = nullptr;
ProgramEditDialog *m_formAppEdit = nullptr;
TableView *m_appListView = nullptr;
AppInfoRow *m_appInfoRow = nullptr;
};

View File

@ -131,7 +131,20 @@ void TrayIcon::updateTrayMenuFlags()
}
}
void TrayIcon::retranslateTrayMenu()
void TrayIcon::setupController()
{
connect(fortManager(), &FortManager::optWindowChanged, this, &TrayIcon::updateTrayMenuFlags);
connect(fortManager(), &FortManager::graphWindowChanged, m_graphWindowAction,
&QAction::setChecked);
connect(settings(), &FortSettings::passwordUnlockChanged, this, &TrayIcon::updateTrayMenuFlags);
connect(ctrl(), &TrayController::retranslateUi, this, &TrayIcon::retranslateUi);
retranslateUi();
}
void TrayIcon::retranslateUi()
{
m_programsAction->setText(tr("Programs"));
m_optionsAction->setText(tr("Options"));
@ -147,24 +160,6 @@ void TrayIcon::retranslateTrayMenu()
m_quitAction->setText(tr("Quit"));
}
void TrayIcon::onRetranslateUi()
{
retranslateTrayMenu();
}
void TrayIcon::setupController()
{
connect(fortManager(), &FortManager::optWindowChanged, this, &TrayIcon::updateTrayMenuFlags);
connect(fortManager(), &FortManager::graphWindowChanged, m_graphWindowAction,
&QAction::setChecked);
connect(settings(), &FortSettings::passwordUnlockChanged, this, &TrayIcon::updateTrayMenuFlags);
connect(ctrl(), &TrayController::retranslateUi, this, &TrayIcon::onRetranslateUi);
emit ctrl()->retranslateUi();
}
void TrayIcon::setupUi()
{
this->setToolTip(QApplication::applicationDisplayName());

View File

@ -33,15 +33,13 @@ public slots:
void updateTrayMenuFlags();
protected slots:
void retranslateTrayMenu();
void onRetranslateUi();
void saveTrayFlags();
private:
void setupController();
void retranslateUi();
void setupUi();
void setupTrayMenu();

View File

@ -428,7 +428,7 @@ bool FortManager::showProgramEditForm(const QString &appPath)
if (!(m_progWindow && m_progWindow->isVisible()))
return false; // May be not opened due to password checking
if (!m_progWindow->openAppEditFormByPath(appPath)) {
if (!m_progWindow->editProgramByPath(appPath)) {
showErrorBox(tr("Please close already opened Edit Program window and try again."));
return false;
}

View File

@ -294,13 +294,19 @@ const AppRow &AppListModel::appRowAt(int row) const
return m_appRow;
}
AppRow AppListModel::appRowById(qint64 appId) const
{
AppRow appRow;
updateAppRow(sqlBase() + " WHERE t.app_id = ?1;", { appId }, appRow);
return appRow;
}
AppRow AppListModel::appRowByPath(const QString &appPath) const
{
AppRow appRow;
appRow.appPath = appPath;
updateAppRow(sqlBase() + " WHERE path = ?1;", { appPath }, appRow);
if (!updateAppRow(sqlBase() + " WHERE t.path = ?1;", { appPath }, appRow)) {
appRow.appPath = appPath;
}
return appRow;
}
@ -321,11 +327,9 @@ bool AppListModel::addApp(const QString &appPath, const QString &appName, const
}
bool AppListModel::updateApp(qint64 appId, const QString &appPath, const QString &appName,
const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked,
bool updateDriver)
const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked)
{
if (updateDriver
&& !confManager()->updateDriverUpdateApp(appPath, groupIndex, useGroupPerm, blocked))
if (!confManager()->updateDriverUpdateApp(appPath, groupIndex, useGroupPerm, blocked))
return false;
const auto groupId = appGroupAt(groupIndex)->id();

View File

@ -54,13 +54,13 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
const AppRow &appRowAt(int row) const;
AppRow appRowById(qint64 appId) const;
AppRow appRowByPath(const QString &appPath) const;
bool addApp(const QString &appPath, const QString &appName, const QDateTime &endTime,
int groupIndex, bool useGroupPerm, bool blocked);
bool updateApp(qint64 appId, const QString &appPath, const QString &appName,
const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked,
bool updateDriver = true);
const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked);
bool updateAppName(qint64 appId, const QString &appName);
void deleteApp(qint64 appId, const QString &appPath, int row);
void purgeApps();