Sandboxie/SandboxiePlus/SandMan/Windows/OptionsWindow.cpp

1269 lines
42 KiB
C++
Raw Normal View History

2021-10-16 16:19:51 +01:00
#include "stdafx.h"
#include "OptionsWindow.h"
#include "SandMan.h"
#include "SettingsWindow.h"
#include "../MiscHelpers/Common/Settings.h"
#include "../MiscHelpers/Common/Common.h"
#include "../MiscHelpers/Common/ComboInputDialog.h"
#include "../MiscHelpers/Common/SettingsWidgets.h"
#include "Helpers/WinAdmin.h"
2023-03-31 20:51:45 +01:00
#include "../Wizards/TemplateWizard.h"
#include <qfontdialog.h>
2021-10-16 16:19:51 +01:00
2021-12-03 19:26:09 +00:00
class NoEditDelegate : public QStyledItemDelegate {
public:
NoEditDelegate(QObject* parent = 0) : QStyledItemDelegate(parent) {}
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const {
return NULL;
}
};
class QTreeWidgetHacker : public QTreeWidget
{
public:
friend class ProgramsDelegate;
//QModelIndex indexFromItem(const QTreeWidgetItem *item, int column = 0) const;
//QTreeWidgetItem *itemFromIndex(const QModelIndex &index) const;
};
2022-08-20 13:48:18 +01:00
//////////////////////////////////////////////////////////////////////////
// ProgramsDelegate
2021-12-03 19:26:09 +00:00
class ProgramsDelegate : public QStyledItemDelegate {
public:
2023-04-09 11:26:16 +01:00
ProgramsDelegate(COptionsWindow* pOptions, QTreeWidget* pTree, int Column, QObject* parent = 0) : QStyledItemDelegate(parent) {
m_pOptions = pOptions;
m_pTree = pTree;
m_Column = (m_Group = (Column == -2)) ? -1 : Column;
}
2021-12-03 19:26:09 +00:00
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const {
QTreeWidgetItem* pItem = ((QTreeWidgetHacker*)m_pTree)->itemFromIndex(index);
if (!pItem->data(index.column(), Qt::UserRole).isValid())
return NULL;
2023-04-09 11:26:16 +01:00
if(m_Group && !pItem->parent()) // for groups use simple edit
return QStyledItemDelegate::createEditor(parent, option, index);
2021-12-03 19:26:09 +00:00
if (m_Column == -1 || pItem->data(m_Column, Qt::UserRole).toInt() == COptionsWindow::eProcess) {
QComboBox* pBox = new QComboBox(parent);
pBox->setEditable(true);
foreach(const QString Group, m_pOptions->GetCurrentGroups()) {
QString GroupName = Group.mid(1, Group.length() - 2);
pBox->addItem(tr("Group: %1").arg(GroupName), Group);
}
foreach(const QString & Name, m_pOptions->GetPrograms())
pBox->addItem(Name, Name);
connect(pBox->lineEdit(), &QLineEdit::textEdited, [pBox](const QString& text){
/*if (pBox->currentIndex() != -1) {
int pos = pBox->lineEdit()->cursorPosition();
pBox->setCurrentIndex(-1);
pBox->setCurrentText(text);
pBox->lineEdit()->setCursorPosition(pos);
}*/
pBox->setProperty("value", text);
});
2022-10-26 09:37:30 +01:00
connect(pBox->lineEdit(), &QLineEdit::returnPressed, [pBox](){
/*if (pBox->currentIndex() != -1) {
int pos = pBox->lineEdit()->cursorPosition();
pBox->setCurrentIndex(-1);
pBox->setCurrentText(text);
pBox->lineEdit()->setCursorPosition(pos);
}*/
pBox->setProperty("value", pBox->lineEdit()->text());
});
2021-12-03 19:26:09 +00:00
connect(pBox, qOverload<int>(&QComboBox::currentIndexChanged), [pBox](int index){
2023-04-09 21:20:44 +01:00
if (index != -1) {
QString Program = pBox->itemData(index).toString();
pBox->setProperty("value", Program);
pBox->lineEdit()->setReadOnly(Program.left(1) == "<");
}
2021-12-03 19:26:09 +00:00
});
return pBox;
}
else if (pItem->data(0, Qt::UserRole).toInt() == COptionsWindow::ePath)
return QStyledItemDelegate::createEditor(parent, option, index);
else
return NULL;
}
virtual void setEditorData(QWidget* editor, const QModelIndex& index) const {
QComboBox* pBox = qobject_cast<QComboBox*>(editor);
if (pBox) {
QTreeWidgetItem* pItem = ((QTreeWidgetHacker*)m_pTree)->itemFromIndex(index);
QString Program = pItem->data(index.column(), Qt::UserRole).toString();
pBox->setProperty("value", Program);
2023-04-09 21:20:44 +01:00
pBox->lineEdit()->setReadOnly(Program.left(1) == "<");
2021-12-03 19:26:09 +00:00
int Index = pBox->findData(Program);
pBox->setCurrentIndex(Index);
if (Index == -1)
pBox->setCurrentText(Program);
}
else
QStyledItemDelegate::setEditorData(editor, index);
}
virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const {
2023-04-09 21:20:44 +01:00
QTreeWidgetItem* pItem = ((QTreeWidgetHacker*)m_pTree)->itemFromIndex(index);
2021-12-03 19:26:09 +00:00
QComboBox* pBox = qobject_cast<QComboBox*>(editor);
if (pBox) {
2023-04-09 21:20:44 +01:00
2021-12-03 19:26:09 +00:00
QString Value = pBox->property("value").toString();
pItem->setText(index.column(), pBox->currentText());
//QString Text = pBox->currentText();
//QVariant Data = pBox->currentData();
pItem->setData(index.column(), Qt::UserRole, Value);
}
QLineEdit* pEdit = qobject_cast<QLineEdit*>(editor);
if (pEdit) {
pItem->setText(index.column(), pEdit->text());
2023-04-09 11:26:16 +01:00
QString Value = pEdit->text();
if (m_Group) Value = "<" + Value + ">";
pItem->setData(index.column(), Qt::UserRole, Value);
2021-12-03 19:26:09 +00:00
}
}
2023-04-09 21:20:44 +01:00
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QSize size = QStyledItemDelegate::sizeHint(option, index);
if(size.height() < 20) size.setHeight(20); // ensure enough room for the combo box
2023-04-09 21:20:44 +01:00
return size;
}
2021-12-03 19:26:09 +00:00
protected:
COptionsWindow* m_pOptions;
QTreeWidget* m_pTree;
int m_Column;
2023-04-09 11:26:16 +01:00
bool m_Group;
2021-12-03 19:26:09 +00:00
};
2023-04-09 11:26:16 +01:00
2022-08-15 12:18:26 +01:00
//////////////////////////////////////////////////////////////////////////
// COptionsWindow
2021-10-16 16:19:51 +01:00
COptionsWindow::COptionsWindow(const QSharedPointer<CSbieIni>& pBox, const QString& Name, QWidget *parent)
2022-08-15 12:18:26 +01:00
: CConfigDialog(parent)
2021-10-16 16:19:51 +01:00
{
m_pBox = pBox;
m_Template = pBox->GetName().left(9).compare("Template_", Qt::CaseInsensitive) == 0;
bool ReadOnly = /*pBox->GetAPI()->IsConfigLocked() ||*/ (m_Template && pBox->GetName().mid(9, 6).compare("Local_", Qt::CaseInsensitive) != 0);
2021-11-13 08:28:32 +00:00
m_HoldChange = false;
2021-10-16 16:19:51 +01:00
QSharedPointer<CSandBoxPlus> pBoxPlus = m_pBox.objectCast<CSandBoxPlus>();
if (!pBoxPlus.isNull())
m_Programs = pBoxPlus->GetRecentPrograms();
2023-04-13 18:46:51 +01:00
m_Programs.insert("program.exe");
2021-10-16 16:19:51 +01:00
Qt::WindowFlags flags = windowFlags();
flags |= Qt::CustomizeWindowHint;
//flags &= ~Qt::WindowContextHelpButtonHint;
//flags &= ~Qt::WindowSystemMenuHint;
//flags &= ~Qt::WindowMinMaxButtonsHint;
flags |= Qt::WindowMinimizeButtonHint;
//flags &= ~Qt::WindowCloseButtonHint;
setWindowFlags(flags);
bool bAlwaysOnTop = theConf->GetBool("Options/AlwaysOnTop", false);
this->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop);
ui.setupUi(this);
2022-08-20 13:48:18 +01:00
this->setWindowTitle(tr("Sandboxie Plus - '%1' Options").arg(QString(Name).replace("_", " ")));
2021-10-16 16:19:51 +01:00
ui.tabs->setTabPosition(QTabWidget::West);
ui.tabs->tabBar()->setStyle(new CustomTabStyle(ui.tabs->tabBar()->style()));
2022-08-20 13:48:18 +01:00
ui.tabs->tabBar()->setProperty("isSidebar", true);
2021-10-16 16:19:51 +01:00
2022-09-29 17:28:48 +01:00
2023-01-25 11:54:41 +00:00
ui.tabs->setCurrentIndex(0);
2022-09-29 17:28:48 +01:00
ui.tabs->setTabIcon(0, CSandMan::GetIcon("Config"));
ui.tabs->setTabIcon(1, CSandMan::GetIcon("Security"));
ui.tabs->setTabIcon(2, CSandMan::GetIcon("Group"));
ui.tabs->setTabIcon(3, CSandMan::GetIcon("Control"));
ui.tabs->setTabIcon(4, CSandMan::GetIcon("Stop"));
ui.tabs->setTabIcon(5, CSandMan::GetIcon("Start"));
ui.tabs->setTabIcon(6, CSandMan::GetIcon("Ampel"));
ui.tabs->setTabIcon(7, CSandMan::GetIcon("Network"));
ui.tabs->setTabIcon(8, CSandMan::GetIcon("Recover"));
ui.tabs->setTabIcon(9, CSandMan::GetIcon("Settings"));
ui.tabs->setTabIcon(10, CSandMan::GetIcon("Advanced"));
2023-02-07 19:17:29 +00:00
ui.tabs->setTabIcon(11, CSandMan::GetIcon("Compatibility"));
2022-12-15 13:45:37 +00:00
ui.tabs->setTabIcon(12, CSandMan::GetIcon("Editor"));
2021-10-16 16:19:51 +01:00
2023-01-25 11:54:41 +00:00
ui.tabsGeneral->setCurrentIndex(0);
2022-08-20 20:56:53 +01:00
ui.tabsGeneral->setTabIcon(0, CSandMan::GetIcon("Box"));
2023-01-25 11:54:41 +00:00
ui.tabsGeneral->setTabIcon(1, CSandMan::GetIcon("Folder"));
ui.tabsGeneral->setTabIcon(2, CSandMan::GetIcon("Move"));
ui.tabsGeneral->setTabIcon(3, CSandMan::GetIcon("NoAccess"));
ui.tabsGeneral->setTabIcon(4, CSandMan::GetIcon("Run"));
2022-08-20 20:56:53 +01:00
2023-01-25 11:54:41 +00:00
ui.tabsSecurity->setCurrentIndex(0);
2022-09-29 17:28:48 +01:00
ui.tabsSecurity->setTabIcon(0, CSandMan::GetIcon("Shield7"));
2022-10-09 17:17:56 +01:00
ui.tabsSecurity->setTabIcon(1, CSandMan::GetIcon("Fence"));
2023-04-13 18:46:51 +01:00
ui.tabsSecurity->setTabIcon(2, CSandMan::GetIcon("Shield2"));
ui.tabsSecurity->setTabIcon(3, CSandMan::GetIcon("Shield12"));
2022-08-20 20:56:53 +01:00
2023-01-25 11:54:41 +00:00
ui.tabsForce->setCurrentIndex(0);
2022-09-29 17:28:48 +01:00
ui.tabsForce->setTabIcon(0, CSandMan::GetIcon("Force"));
ui.tabsForce->setTabIcon(1, CSandMan::GetIcon("Breakout"));
2022-08-20 20:56:53 +01:00
2023-01-25 11:54:41 +00:00
ui.tabsStop->setCurrentIndex(0);
2022-09-29 17:28:48 +01:00
ui.tabsStop->setTabIcon(0, CSandMan::GetIcon("Fail"));
ui.tabsStop->setTabIcon(1, CSandMan::GetIcon("Pass"));
2023-01-25 11:54:41 +00:00
ui.tabsInternet->setCurrentIndex(0);
2022-09-29 17:28:48 +01:00
ui.tabsInternet->setTabIcon(0, CSandMan::GetIcon("Program"));
ui.tabsInternet->setTabIcon(1, CSandMan::GetIcon("Wall"));
ui.tabsInternet->setTabIcon(2, CSandMan::GetIcon("DNS"));
ui.tabsInternet->setTabIcon(3, CSandMan::GetIcon("Proxy"));
2023-01-25 11:54:41 +00:00
ui.tabsAccess->setCurrentIndex(0);
2022-09-29 17:28:48 +01:00
ui.tabsAccess->setTabIcon(0, CSandMan::GetIcon("Folder"));
ui.tabsAccess->setTabIcon(1, CSandMan::GetIcon("RegEdit"));
ui.tabsAccess->setTabIcon(2, CSandMan::GetIcon("Port"));
ui.tabsAccess->setTabIcon(3, CSandMan::GetIcon("Window"));
ui.tabsAccess->setTabIcon(4, CSandMan::GetIcon("Objects"));
//ui.tabsAccess->setTabIcon(0, CSandMan::GetIcon("Rules"));
ui.tabsAccess->setTabIcon(5, CSandMan::GetIcon("Policy"));
2023-01-25 11:54:41 +00:00
ui.tabsRecovery->setCurrentIndex(0);
2022-09-29 17:28:48 +01:00
ui.tabsRecovery->setTabIcon(0, CSandMan::GetIcon("QuickRecovery"));
ui.tabsRecovery->setTabIcon(1, CSandMan::GetIcon("ImmidiateRecovery"));
2023-01-25 11:54:41 +00:00
ui.tabsAdvanced->setCurrentIndex(0);
2023-02-07 19:17:29 +00:00
ui.tabsAdvanced->setTabIcon(0, CSandMan::GetIcon("Presets"));
2022-09-29 17:28:48 +01:00
ui.tabsAdvanced->setTabIcon(1, CSandMan::GetIcon("Trigger"));
ui.tabsAdvanced->setTabIcon(2, CSandMan::GetIcon("Anon"));
ui.tabsAdvanced->setTabIcon(3, CSandMan::GetIcon("Users"));
ui.tabsAdvanced->setTabIcon(4, CSandMan::GetIcon("Presets"));
2022-08-20 20:56:53 +01:00
ui.tabsAdvanced->setTabIcon(5, CSandMan::GetIcon("SetLogging"));
ui.tabsAdvanced->setTabIcon(6, CSandMan::GetIcon("Bug"));
2023-01-25 11:54:41 +00:00
ui.tabsTemplates->setCurrentIndex(0);
2023-02-07 19:17:29 +00:00
ui.tabsTemplates->setTabIcon(0, CSandMan::GetIcon("Template"));
2022-08-20 20:56:53 +01:00
ui.tabsTemplates->setTabIcon(1, CSandMan::GetIcon("Explore"));
ui.tabsTemplates->setTabIcon(2, CSandMan::GetIcon("Accessibility"));
2022-09-29 17:28:48 +01:00
int iViewMode = theConf->GetInt("Options/ViewMode", 1);
int iOptionLayout = theConf->GetInt("Options/NewConfigLayout", 2);
if (iOptionLayout == 2)
2023-02-01 20:57:39 +00:00
iOptionLayout = 0;// iViewMode != 2 ? 1 : 0;
2022-09-29 17:28:48 +01:00
if ((QGuiApplication::queryKeyboardModifiers() & Qt::AltModifier) != 0)
iOptionLayout = !iOptionLayout;
2022-10-23 11:50:12 +01:00
QWidget* pDummy = new QWidget(this);
pDummy->setVisible(false);
2022-09-29 17:28:48 +01:00
ui.tabs->removeTab(9); // remove unused variouse options tab
2023-02-01 20:57:39 +00:00
// merge recovery tabs
QWidget* pWidget3 = new QWidget();
pWidget3->setLayout(ui.gridLayout_10);
ui.gridLayout_24->addWidget(pWidget3, 1, 0);
QWidget* pWidget4 = new QWidget();
pWidget4->setLayout(ui.gridLayout_56);
ui.gridLayout_24->addWidget(pWidget4, 2, 0);
delete ui.tabsRecovery;
ui.gridLayout_24->setContentsMargins(0, 0, 0, 0);
2023-02-03 07:05:10 +00:00
// collect file options on a new files tab
2023-02-01 20:57:39 +00:00
QWidget* pWidget = new QWidget();
QGridLayout* pLayout = new QGridLayout(pWidget);
QTabWidget* pTabWidget = new QTabWidget();
pLayout->addWidget(pTabWidget, 0, 0);
ui.tabs->insertTab(1, pWidget, tr("File Options"));
ui.tabs->setTabIcon(1, CSandMan::GetIcon("Folder"));
pTabWidget->addTab(ui.tabsGeneral->widget(1), ui.tabsGeneral->tabText(1));
pTabWidget->setTabIcon(0, CSandMan::GetIcon("Files"));
pTabWidget->addTab(ui.tabsGeneral->widget(1), ui.tabsGeneral->tabText(1));
pTabWidget->setTabIcon(1, CSandMan::GetIcon("Move"));
pTabWidget->addTab(ui.tabs->widget(9), ui.tabs->tabText(9));
pTabWidget->setTabIcon(2, CSandMan::GetIcon("Recover"));
//
2022-09-29 17:28:48 +01:00
// re structure the UI a bit
if (iOptionLayout == 1)
{
// merge stop tabs
QWidget* pWidget1 = new QWidget();
pWidget1->setLayout(ui.gridLayout_57);
ui.gridLayout_17->addWidget(pWidget1, 1, 0);
QWidget* pWidget2 = new QWidget();
pWidget2->setLayout(ui.gridLayout_61);
ui.gridLayout_17->addWidget(pWidget2, 2, 0);
delete ui.tabsStop;
ui.gridLayout_17->setContentsMargins(0, 0, 0, 0);
// move stop and restrictions to program tab
2023-02-01 20:57:39 +00:00
ui.tabsForce->addTab(ui.tabs->widget(5), ui.tabs->tabText(5));
2022-09-29 17:28:48 +01:00
ui.tabsForce->setTabIcon(2, CSandMan::GetIcon("Stop"));
2023-02-01 20:57:39 +00:00
ui.tabsForce->addTab(ui.tabs->widget(5), ui.tabs->tabText(5));
2022-09-29 17:28:48 +01:00
ui.tabsForce->setTabIcon(3, CSandMan::GetIcon("Start"));
ui.gridLayout_19->setContentsMargins(3, 6, 3, 3);
// move grouping to program tab
ui.tabsForce->insertTab(0, ui.tabGroups, tr("Grouping"));
ui.tabsForce->setTabIcon(0, CSandMan::GetIcon("Group"));
ui.tabsForce->setCurrentIndex(0);
ui.gridLayout_18->setContentsMargins(3, 6, 3, 3);
}
if (iViewMode != 1 && (QGuiApplication::queryKeyboardModifiers() & Qt::ControlModifier) == 0)
{
if (iOptionLayout == 1) {
//ui.tabs->removeTab(7); // ini edit
2022-10-23 11:50:12 +01:00
ui.tabAdvanced->setParent(pDummy); //ui.tabs->removeTab(5); // advanced
2022-09-29 17:28:48 +01:00
//ui.tabsForce->removeTab(2); // breakout
}
else {
//ui.tabs->removeTab(11); // ini edit
2022-10-23 11:50:12 +01:00
ui.tabAdvanced->setParent(pDummy); //ui.tabs->removeTab(9); // advanced
2022-09-29 17:28:48 +01:00
//ui.tabsForce->removeTab(1); // breakout
}
2022-10-23 11:50:12 +01:00
ui.tabPrivileges->setParent(pDummy); //ui.tabsSecurity->removeTab(3); // advanced security
ui.tabIsolation->setParent(pDummy); //ui.tabsSecurity->removeTab(1); // security isolation
2022-09-29 17:28:48 +01:00
//ui.tabsAccess->removeTab(5); // policy
ui.treeOptions = NULL;
}
foreach(QTreeWidget* pTree, this->findChildren<QTreeWidget*>()) {
if (pTree == ui.treeFolders) continue;
pTree->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Ignored);
pTree->setMinimumHeight(50);
}
int size = 16.0;
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
size *= (QApplication::desktop()->logicalDpiX() / 96.0); // todo Qt6
#endif
AddIconToLabel(ui.lblAppearance, CSandMan::GetIcon("Design").pixmap(size,size));
AddIconToLabel(ui.lblBoxType, CSandMan::GetIcon("Maintenance").pixmap(size,size));
AddIconToLabel(ui.lblStructure, CSandMan::GetIcon("Structure").pixmap(size,size));
AddIconToLabel(ui.lblMigration, CSandMan::GetIcon("Move").pixmap(size,size));
AddIconToLabel(ui.lblDelete, CSandMan::GetIcon("Erase").pixmap(size,size));
AddIconToLabel(ui.lblRawDisk, CSandMan::GetIcon("Disk").pixmap(size,size));
AddIconToLabel(ui.lblSecurity, CSandMan::GetIcon("Shield5").pixmap(size,size));
AddIconToLabel(ui.lblElevation, CSandMan::GetIcon("Shield9").pixmap(size,size));
AddIconToLabel(ui.lblNetwork, CSandMan::GetIcon("Network").pixmap(size,size));
AddIconToLabel(ui.lblPrinting, CSandMan::GetIcon("Printer").pixmap(size,size));
AddIconToLabel(ui.lblOther, CSandMan::GetIcon("NoAccess").pixmap(size,size));
AddIconToLabel(ui.lblMode, CSandMan::GetIcon("Anon").pixmap(size,size));
AddIconToLabel(ui.lblPolicy, CSandMan::GetIcon("Policy").pixmap(size,size));
AddIconToLabel(ui.lblCompatibility, CSandMan::GetIcon("Compatibility").pixmap(size,size));
//AddIconToLabel(ui.lblComRpc, CSandMan::GetIcon("Objects").pixmap(size,size));
2023-02-07 19:17:29 +00:00
AddIconToLabel(ui.lblPrivilege, CSandMan::GetIcon("Token").pixmap(size,size));
2022-09-29 17:28:48 +01:00
AddIconToLabel(ui.lblFence, CSandMan::GetIcon("BFance").pixmap(size,size));
AddIconToLabel(ui.lblToken, CSandMan::GetIcon("Sandbox").pixmap(size,size));
AddIconToLabel(ui.lblIsolation, CSandMan::GetIcon("Fence").pixmap(size,size));
AddIconToLabel(ui.lblAccess, CSandMan::GetIcon("NoAccess").pixmap(size,size));
2023-04-13 18:46:51 +01:00
AddIconToLabel(ui.lblProtection, CSandMan::GetIcon("EFence").pixmap(size,size));
2022-09-29 17:28:48 +01:00
AddIconToLabel(ui.lblMonitor, CSandMan::GetIcon("Monitor").pixmap(size,size));
AddIconToLabel(ui.lblTracing, CSandMan::GetIcon("SetLogging").pixmap(size,size));
2022-07-29 09:24:32 +01:00
if (theConf->GetBool("Options/AltRowColors", false)) {
2022-09-29 17:28:48 +01:00
foreach(QTreeWidget* pTree, this->findChildren<QTreeWidget*>())
pTree->setAlternatingRowColors(true);
2022-07-29 09:24:32 +01:00
}
2021-10-16 16:19:51 +01:00
CreateDebug();
if (m_Template)
{
2022-10-07 12:35:43 +01:00
//ui.tabGeneral->setEnabled(false);
//ui.tabStart->setEnabled(false);
//ui.tabInternet->setEnabled(false);
//ui.tabAdvanced->setEnabled(false);
//ui.tabOther->setEnabled(false);
//ui.tabTemplates->setEnabled(false);
//
//for (int i = 0; i < ui.tabs->count(); i++)
// ui.tabs->setTabEnabled(i, ui.tabs->widget(i)->isEnabled());
//ui.tabs->setCurrentIndex(ui.tabs->indexOf(ui.tabAccess));
ui.chkShowGroupTmpl->setEnabled(false);
2021-10-16 16:19:51 +01:00
ui.chkShowForceTmpl->setEnabled(false);
2022-10-07 12:35:43 +01:00
ui.chkShowBreakoutTmpl->setEnabled(false);
2021-10-16 16:19:51 +01:00
ui.chkShowStopTmpl->setEnabled(false);
2022-10-07 12:35:43 +01:00
ui.chkShowLeaderTmpl->setEnabled(false);
ui.chkShowStartTmpl->setEnabled(false);
2022-09-29 17:28:48 +01:00
ui.chkShowFilesTmpl->setEnabled(false);
ui.chkShowKeysTmpl->setEnabled(false);
ui.chkShowIPCTmpl->setEnabled(false);
ui.chkShowWndTmpl->setEnabled(false);
ui.chkShowCOMTmpl->setEnabled(false);
2022-10-07 12:35:43 +01:00
ui.chkShowNetFwTmpl->setEnabled(false);
2021-10-16 16:19:51 +01:00
ui.chkShowRecoveryTmpl->setEnabled(false);
2022-09-29 17:28:48 +01:00
ui.chkShowRecIgnoreTmpl->setEnabled(false);
ui.chkShowTriggersTmpl->setEnabled(false);
2022-10-07 12:35:43 +01:00
ui.chkShowHiddenProcTmpl->setEnabled(false);
ui.chkShowHostProcTmpl->setEnabled(false);
ui.chkShowOptionsTmpl->setEnabled(false);
2021-10-16 16:19:51 +01:00
//ui.chkWithTemplates->setEnabled(false);
}
2022-10-07 12:35:43 +01:00
ui.tabs->setCurrentIndex(m_Template ? ui.tabs->count()-1 : 0);
2021-10-16 16:19:51 +01:00
if(m_Template)
OnTab();
//connect(ui.chkWithTemplates, SIGNAL(clicked(bool)), this, SLOT(OnWithTemplates()));
m_ConfigDirty = true;
CreateGeneral();
2022-12-07 16:32:40 +00:00
// Groups
2021-10-16 16:19:51 +01:00
connect(ui.btnAddGroup, SIGNAL(clicked(bool)), this, SLOT(OnAddGroup()));
connect(ui.btnAddProg, SIGNAL(clicked(bool)), this, SLOT(OnAddProg()));
connect(ui.btnDelProg, SIGNAL(clicked(bool)), this, SLOT(OnDelProg()));
connect(ui.chkShowGroupTmpl, SIGNAL(clicked(bool)), this, SLOT(OnShowGroupTmpl()));
2023-04-09 11:26:16 +01:00
ui.treeGroups->setItemDelegateForColumn(0, new ProgramsDelegate(this, ui.treeGroups, -2, this));
2021-12-03 19:26:09 +00:00
connect(ui.treeGroups, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(OnGroupsChanged(QTreeWidgetItem *, int)));
2021-10-16 16:19:51 +01:00
//
// Force
connect(ui.btnForceProg, SIGNAL(clicked(bool)), this, SLOT(OnForceProg()));
2022-09-29 17:28:48 +01:00
QMenu* pFileBtnMenu = new QMenu(ui.btnForceProg);
pFileBtnMenu->addAction(tr("Browse for File"), this, SLOT(OnForceBrowse()));
ui.btnForceProg->setPopupMode(QToolButton::MenuButtonPopup);
ui.btnForceProg->setMenu(pFileBtnMenu);
2021-10-16 16:19:51 +01:00
connect(ui.btnForceDir, SIGNAL(clicked(bool)), this, SLOT(OnForceDir()));
connect(ui.btnDelForce, SIGNAL(clicked(bool)), this, SLOT(OnDelForce()));
connect(ui.chkShowForceTmpl, SIGNAL(clicked(bool)), this, SLOT(OnShowForceTmpl()));
2021-12-03 19:26:09 +00:00
//ui.treeForced->setEditTriggers(QAbstractItemView::DoubleClicked);
ui.treeForced->setItemDelegateForColumn(0, new NoEditDelegate(this));
2022-10-26 09:37:30 +01:00
ui.treeForced->setItemDelegateForColumn(1, new ProgramsDelegate(this, ui.treeForced, -1, this));
2023-04-23 19:08:25 +01:00
connect(ui.treeForced, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(OnForcedChanged()));
connect(ui.chkDisableForced, SIGNAL(clicked(bool)), this, SLOT(OnForcedChanged()));
2022-09-29 17:28:48 +01:00
connect(ui.btnBreakoutProg, SIGNAL(clicked(bool)), this, SLOT(OnBreakoutProg()));
QMenu* pFileBtnMenu2 = new QMenu(ui.btnBreakoutProg);
pFileBtnMenu2->addAction(tr("Browse for File"), this, SLOT(OnBreakoutBrowse()));
ui.btnBreakoutProg->setPopupMode(QToolButton::MenuButtonPopup);
ui.btnBreakoutProg->setMenu(pFileBtnMenu2);
connect(ui.btnBreakoutDir, SIGNAL(clicked(bool)), this, SLOT(OnBreakoutDir()));
connect(ui.btnDelBreakout, SIGNAL(clicked(bool)), this, SLOT(OnDelBreakout()));
connect(ui.chkShowBreakoutTmpl, SIGNAL(clicked(bool)), this, SLOT(OnShowBreakoutTmpl()));
//ui.treeBreakout->setEditTriggers(QAbstractItemView::DoubleClicked);
ui.treeBreakout->setItemDelegateForColumn(0, new NoEditDelegate(this));
2022-10-26 09:37:30 +01:00
ui.treeBreakout->setItemDelegateForColumn(1, new ProgramsDelegate(this, ui.treeBreakout, -1, this));
2022-09-29 17:28:48 +01:00
connect(ui.treeBreakout, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(OnForcedChanged(QTreeWidgetItem *, int)));
2021-10-16 16:19:51 +01:00
//
// Stop
connect(ui.btnAddLingering, SIGNAL(clicked(bool)), this, SLOT(OnAddLingering()));
connect(ui.btnDelStopProg, SIGNAL(clicked(bool)), this, SLOT(OnDelStopProg()));
connect(ui.chkShowStopTmpl, SIGNAL(clicked(bool)), this, SLOT(OnShowStopTmpl()));
2022-09-29 17:28:48 +01:00
ui.treeStop->setItemDelegateForColumn(0, new ProgramsDelegate(this, ui.treeStop, -1, this));
2021-12-03 19:26:09 +00:00
connect(ui.treeStop, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(OnStopChanged(QTreeWidgetItem *, int)));
2022-09-29 17:28:48 +01:00
connect(ui.btnAddLeader, SIGNAL(clicked(bool)), this, SLOT(OnAddLeader()));
connect(ui.btnDelLeader, SIGNAL(clicked(bool)), this, SLOT(OnDelLeader()));
connect(ui.chkShowLeaderTmpl, SIGNAL(clicked(bool)), this, SLOT(OnShowLeaderTmpl()));
ui.treeLeader->setItemDelegateForColumn(0, new ProgramsDelegate(this, ui.treeLeader, -1, this));
connect(ui.treeLeader, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(OnStopChanged(QTreeWidgetItem *, int)));
2021-10-16 16:19:51 +01:00
//
// Start
connect(ui.radStartAll, SIGNAL(clicked(bool)), this, SLOT(OnRestrictStart()));
connect(ui.radStartExcept, SIGNAL(clicked(bool)), this, SLOT(OnRestrictStart()));
connect(ui.radStartSelected, SIGNAL(clicked(bool)), this, SLOT(OnRestrictStart()));
connect(ui.btnAddStartProg, SIGNAL(clicked(bool)), this, SLOT(OnAddStartProg()));
connect(ui.btnDelStartProg, SIGNAL(clicked(bool)), this, SLOT(OnDelStartProg()));
2022-09-29 17:28:48 +01:00
//connect(ui.chkShowStartTmpl, SIGNAL(clicked(bool)), this, SLOT(OnShowStartTmpl()));
ui.chkShowStartTmpl->setVisible(false); // todo
2021-10-16 16:19:51 +01:00
connect(ui.chkStartBlockMsg, SIGNAL(clicked(bool)), this, SLOT(OnStartChanged()));
2021-12-03 19:26:09 +00:00
ui.treeStart->setItemDelegateForColumn(0, new ProgramsDelegate(this, ui.treeStart, -1, this));
connect(ui.treeStart, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(OnStartChanged(QTreeWidgetItem *, int)));
2021-10-16 16:19:51 +01:00
//
CreateNetwork();
CreateAccess();
// Recovery
connect(ui.chkAutoRecovery, SIGNAL(clicked(bool)), this, SLOT(OnRecoveryChanged()));
connect(ui.btnAddRecovery, SIGNAL(clicked(bool)), this, SLOT(OnAddRecFolder()));
connect(ui.btnDelRecovery, SIGNAL(clicked(bool)), this, SLOT(OnDelRecEntry()));
connect(ui.btnAddRecIgnore, SIGNAL(clicked(bool)), this, SLOT(OnAddRecIgnore()));
connect(ui.btnAddRecIgnoreExt, SIGNAL(clicked(bool)), this, SLOT(OnAddRecIgnoreExt()));
2022-09-29 17:28:48 +01:00
connect(ui.btnDelRecIgnore, SIGNAL(clicked(bool)), this, SLOT(OnDelRecIgnoreEntry()));
2021-10-16 16:19:51 +01:00
connect(ui.chkShowRecoveryTmpl, SIGNAL(clicked(bool)), this, SLOT(OnShowRecoveryTmpl()));
2022-09-29 17:28:48 +01:00
connect(ui.chkShowRecIgnoreTmpl, SIGNAL(clicked(bool)), this, SLOT(OnShowRecIgnoreTmpl()));
2021-10-16 16:19:51 +01:00
//
CreateAdvanced();
// Templates
connect(ui.cmbCategories, SIGNAL(currentIndexChanged(int)), this, SLOT(OnFilterTemplates()));
connect(ui.txtTemplates, SIGNAL(textChanged(const QString&)), this, SLOT(OnFilterTemplates()));
2021-10-19 22:35:59 +01:00
//connect(ui.treeTemplates, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(OnTemplateClicked(QTreeWidgetItem*, int)));
connect(ui.treeTemplates, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(OnTemplateClicked(QTreeWidgetItem*, int)));
2021-10-16 16:19:51 +01:00
connect(ui.treeTemplates, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(OnTemplateDoubleClicked(QTreeWidgetItem*, int)));
connect(ui.btnAddTemplate, SIGNAL(clicked(bool)), this, SLOT(OnAddTemplates()));
2023-03-31 20:51:45 +01:00
QMenu* pTmplBtnMenu = new QMenu(ui.btnAddTemplate);
for(int i = 1; i < CTemplateWizard::TmplMax; i++)
pTmplBtnMenu->addAction(tr("Add %1 Template").arg(CTemplateWizard::GetTemplateLabel((CTemplateWizard::ETemplateType)i)), this, SLOT(OnTemplateWizard()))->setData(i);
ui.btnAddTemplate->setPopupMode(QToolButton::MenuButtonPopup);
ui.btnAddTemplate->setMenu(pTmplBtnMenu);
2021-10-16 16:19:51 +01:00
connect(ui.btnDelTemplate, SIGNAL(clicked(bool)), this, SLOT(OnDelTemplates()));
connect(ui.chkScreenReaders, SIGNAL(clicked(bool)), this, SLOT(OnScreenReaders()));
//
connect(ui.tabs, SIGNAL(currentChanged(int)), this, SLOT(OnTab()));
// edit
ui.btnSelectIniEditFont->setIcon(CSandMan::GetIcon("Font"));
ui.btnResetIniEditFont->setIcon(CSandMan::GetIcon("ResetFont"));
ui.btnResetIniEditFont->setToolTip(tr("Reset font"));
ApplyIniEditFont();
connect(ui.btnSelectIniEditFont, SIGNAL(clicked(bool)), this, SLOT(OnSelectIniEditFont()));
connect(ui.btnResetIniEditFont, SIGNAL(clicked(bool)), this, SLOT(OnResetIniEditFont()));
2021-10-16 16:19:51 +01:00
connect(ui.btnEditIni, SIGNAL(clicked(bool)), this, SLOT(OnEditIni()));
connect(ui.btnSaveIni, SIGNAL(clicked(bool)), this, SLOT(OnSaveIni()));
connect(ui.btnCancelEdit, SIGNAL(clicked(bool)), this, SLOT(OnCancelEdit()));
2023-04-13 18:46:51 +01:00
connect(ui.txtIniSection, SIGNAL(textChanged()), this, SLOT(OnIniChanged()));
2021-11-13 08:28:32 +00:00
2021-10-16 16:19:51 +01:00
//
connect(ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked(bool)), this, SLOT(ok()));
connect(ui.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked(bool)), this, SLOT(apply()));
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(close()));
if (ReadOnly)
{
ui.btnEditIni->setEnabled(false);
ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
}
if (theAPI->IsRunningAsAdmin())
{
ui.chkDropRights->setEnabled(false);
ui.chkFakeElevation->setEnabled(false);
}
else
ui.lblAdmin->setVisible(false);
LoadConfig();
2022-10-28 19:36:58 +01:00
m_pCurrentTab = ui.tabGeneral;
2022-04-15 17:37:39 +01:00
UpdateCurrentTab();
2021-11-13 08:28:32 +00:00
ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
2023-01-25 11:54:41 +00:00
ui.treeCopy->viewport()->installEventFilter(this);
2021-10-16 16:19:51 +01:00
ui.treeINet->viewport()->installEventFilter(this);
ui.treeNetFw->viewport()->installEventFilter(this);
2022-09-29 17:28:48 +01:00
ui.treeFiles->viewport()->installEventFilter(this);
ui.treeKeys->viewport()->installEventFilter(this);
ui.treeIPC->viewport()->installEventFilter(this);
ui.treeWnd->viewport()->installEventFilter(this);
ui.treeCOM->viewport()->installEventFilter(this);
//ui.treeAccess->viewport()->installEventFilter(this);
if(ui.treeOptions) ui.treeOptions->viewport()->installEventFilter(this);
2022-08-15 10:58:39 +01:00
this->installEventFilter(this); // prevent enter from closing the dialog
2021-10-16 16:19:51 +01:00
restoreGeometry(theConf->GetBlob("OptionsWindow/Window_Geometry"));
2022-09-29 17:28:48 +01:00
foreach(QTreeWidget * pTree, this->findChildren<QTreeWidget*>()) {
QByteArray Columns = theConf->GetBlob("OptionsWindow/" + pTree->objectName() + "_Columns");
if (!Columns.isEmpty())
pTree->header()->restoreState(Columns);
}
2022-07-09 15:29:16 +01:00
2022-09-02 10:04:49 +01:00
if (theAPI->GetGlobalSettings()->GetBool("EditAdminOnly", false) && !IsAdminUser())
{
for (int I = 0; I < ui.tabs->count(); I++) {
QGridLayout* pGrid = qobject_cast<QGridLayout*>(ui.tabs->widget(I)->layout());
QTabWidget* pSubTabs = pGrid ? qobject_cast<QTabWidget*>(pGrid->itemAt(0)->widget()) : NULL;
if (!pSubTabs) {
ui.tabs->widget(I)->setEnabled(false);
}
else {
for (int J = 0; J < pSubTabs->count(); J++) {
pSubTabs->widget(J)->setEnabled(false);
}
}
}
}
2022-07-09 15:29:16 +01:00
int iOptionTree = theConf->GetInt("Options/OptionTree", 2);
if (iOptionTree == 2)
iOptionTree = iViewMode == 2 ? 1 : 0;
if (iOptionTree)
2022-08-15 12:18:26 +01:00
OnSetTree();
2022-07-09 15:29:16 +01:00
else {
2022-09-29 17:28:48 +01:00
//this->setMinimumHeight(490);
this->setMinimumHeight(390);
2022-08-15 18:32:38 +01:00
QWidget* pSearch = AddConfigSearch(ui.tabs);
ui.horizontalLayout->insertWidget(0, pSearch);
QTimer::singleShot(0, [this]() {
m_pSearch->setMaximumWidth(m_pTabs->tabBar()->width());
});
2022-09-29 17:28:48 +01:00
QAction* pSetTree = new QAction();
connect(pSetTree, SIGNAL(triggered()), this, SLOT(OnSetTree()));
pSetTree->setShortcut(QKeySequence("Ctrl+Alt+T"));
pSetTree->setShortcutContext(Qt::WidgetWithChildrenShortcut);
this->addAction(pSetTree);
2022-08-15 10:58:39 +01:00
}
2022-08-20 19:11:27 +01:00
m_pSearch->setPlaceholderText(tr("Search for options"));
2022-08-15 10:58:39 +01:00
}
void COptionsWindow::ApplyIniEditFont()
{
QFont font; // defaults to application font
auto fontName = theConf->GetString("UIConfig/IniFont", "").trimmed();
if (!fontName.isEmpty()) bool dummy = font.fromString(fontName); // ignore fromString() fail
ui.txtIniSection->setFont(font);
ui.btnSelectIniEditFont->setToolTip(tr("Select font (%1)").arg(font.family())); //tr: %1 = name of current font
}
void COptionsWindow::OnSelectIniEditFont()
{
bool ok;
auto newFont = QFontDialog::getFont(&ok, ui.txtIniSection->font(), this);
if (!ok) return;
theConf->SetValue("UIConfig/IniFont", newFont.toString());
ApplyIniEditFont();
}
void COptionsWindow::OnResetIniEditFont()
{
theConf->DelValue("UIConfig/IniFont");
ApplyIniEditFont();
}
2022-08-15 12:18:26 +01:00
void COptionsWindow::OnSetTree()
2022-07-09 15:29:16 +01:00
{
2022-08-15 12:18:26 +01:00
if (!ui.tabs) return;
QWidget* pAltView = ConvertToTree(ui.tabs);
ui.verticalLayout->replaceWidget(ui.tabs, pAltView);
ui.tabs->deleteLater();
ui.tabs = NULL;
2021-10-16 16:19:51 +01:00
}
2022-07-09 15:29:16 +01:00
void COptionsWindow::OnOptChanged()
{
2021-11-13 08:28:32 +00:00
if (m_HoldChange)
return;
ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true);
}
2021-10-16 16:19:51 +01:00
COptionsWindow::~COptionsWindow()
{
theConf->SetBlob("OptionsWindow/Window_Geometry",saveGeometry());
2022-09-29 17:28:48 +01:00
foreach(QTreeWidget * pTree, this->findChildren<QTreeWidget*>())
theConf->SetBlob("OptionsWindow/" + pTree->objectName() + "_Columns", pTree->header()->saveState());
2021-10-16 16:19:51 +01:00
}
void COptionsWindow::closeEvent(QCloseEvent *e)
{
emit Closed();
this->deleteLater();
}
bool COptionsWindow::eventFilter(QObject *source, QEvent *event)
{
if (event->type() == QEvent::KeyPress && ((QKeyEvent*)event)->key() == Qt::Key_Escape
2022-08-20 21:32:51 +01:00
&& ((QKeyEvent*)event)->modifiers() == Qt::NoModifier
2023-01-25 11:54:41 +00:00
&& (source == ui.treeCopy->viewport()
|| source == ui.treeINet->viewport() || source == ui.treeNetFw->viewport()
2022-09-29 17:28:48 +01:00
// || source == ui.treeAccess->viewport()
|| source == ui.treeFiles->viewport() || source == ui.treeKeys->viewport() || source == ui.treeIPC->viewport() || source == ui.treeWnd->viewport() || source == ui.treeCOM->viewport()
|| (ui.treeOptions && source == ui.treeOptions->viewport())))
2021-10-16 16:19:51 +01:00
{
2023-01-25 11:54:41 +00:00
CloseCopyEdit(false);
2021-10-16 16:19:51 +01:00
CloseINetEdit(false);
CloseNetFwEdit(false);
CloseAccessEdit(false);
2022-09-29 17:28:48 +01:00
CloseOptionEdit(false);
2021-10-16 16:19:51 +01:00
return true; // cancel event
}
if (event->type() == QEvent::KeyPress && (((QKeyEvent*)event)->key() == Qt::Key_Enter || ((QKeyEvent*)event)->key() == Qt::Key_Return)
2022-08-20 21:32:51 +01:00
&& (((QKeyEvent*)event)->modifiers() == Qt::NoModifier || ((QKeyEvent*)event)->modifiers() == Qt::KeypadModifier))
2021-10-16 16:19:51 +01:00
{
2023-01-25 11:54:41 +00:00
CloseCopyEdit(true);
2021-10-16 16:19:51 +01:00
CloseINetEdit(true);
CloseNetFwEdit(true);
CloseAccessEdit(true);
2022-09-29 17:28:48 +01:00
CloseOptionEdit(true);
2021-10-16 16:19:51 +01:00
return true; // cancel event
}
2023-01-25 11:54:41 +00:00
if (source == ui.treeCopy->viewport() && event->type() == QEvent::MouseButtonPress)
2021-10-16 16:19:51 +01:00
{
2023-01-25 11:54:41 +00:00
CloseCopyEdit();
2021-10-16 16:19:51 +01:00
}
if (source == ui.treeINet->viewport() && event->type() == QEvent::MouseButtonPress)
{
CloseINetEdit();
}
2023-01-25 11:54:41 +00:00
2021-10-16 16:19:51 +01:00
if (source == ui.treeNetFw->viewport() && event->type() == QEvent::MouseButtonPress)
{
CloseNetFwEdit();
}
2023-01-25 11:54:41 +00:00
if (//source == ui.treeAccess->viewport()
(source == ui.treeFiles->viewport() || source == ui.treeKeys->viewport() || source == ui.treeIPC->viewport() || source == ui.treeWnd->viewport() || source == ui.treeCOM->viewport())
&& event->type() == QEvent::MouseButtonPress)
{
CloseAccessEdit();
}
2022-09-29 17:28:48 +01:00
if ((ui.treeOptions && source == ui.treeOptions->viewport()) && event->type() == QEvent::MouseButtonPress)
{
CloseOptionEdit();
}
2021-10-16 16:19:51 +01:00
return QDialog::eventFilter(source, event);
}
//void COptionsWindow::OnWithTemplates()
//{
// m_Template = ui.chkWithTemplates->isChecked();
// ui.buttonBox->setEnabled(!m_Template);
// LoadConfig();
//}
void COptionsWindow::ReadAdvancedCheck(const QString& Name, QCheckBox* pCheck, const QString& Value)
{
2022-09-29 17:28:48 +01:00
QString Data = m_pBox->GetText(Name);
2021-10-16 16:19:51 +01:00
if (Data == Value) pCheck->setCheckState(Qt::Checked);
else if (Data.isEmpty()) pCheck->setCheckState(Qt::Unchecked);
else pCheck->setCheckState(Qt::PartiallyChecked);
}
2022-09-29 17:28:48 +01:00
int COptionsWindow__GetBoolConfig(const QString& Value)
{
QString temp = Value.left(1).toLower();
if (temp == "y")
return 1;
else if (temp == "n")
return 0;
return -1;
}
void COptionsWindow::ReadGlobalCheck(QCheckBox* pCheck, const QString& Setting, bool bDefault)
{
int iLocal = COptionsWindow__GetBoolConfig(m_pBox->GetText(Setting));
int iTemplate = COptionsWindow__GetBoolConfig(m_pBox->GetText(Setting, QString(), false, true, true));
int iGlobal = COptionsWindow__GetBoolConfig(m_pBox->GetText(Setting, QString(), true));
bool bTemplate = m_pBox->GetBool(Setting, bDefault, true, true);
if (iLocal != -1)
pCheck->setChecked(iLocal == 1);
else
pCheck->setChecked(iTemplate != -1 ? iTemplate == 1 : iGlobal != -1 ? iGlobal == 1 : bDefault);
QStringList Info;
Info.append(tr("Box: %1").arg(iLocal == 1 ? "y" : "n"));
if (iTemplate != -1) Info.append(tr("Template: %1").arg(iTemplate == 1 ? "y" : "n"));
if (iGlobal != -1) Info.append(tr("Global: %1").arg(iGlobal == 1 ? "y" : "n"));
Info.append(tr("Default: %1").arg(bDefault ? "y" : "n"));
pCheck->setToolTip(Info.join("\r\n"));
}
void COptionsWindow::WriteGlobalCheck(QCheckBox* pCheck, const QString& Setting, bool bDefault)
{
bool bLocal = pCheck->isChecked();
bool bPreset = m_pBox->GetBool(Setting, bDefault, true, true);
SB_STATUS Status;
if(bPreset == bLocal)
Status = m_pBox->DelValue(Setting);
else
Status = m_pBox->SetText(Setting, bLocal ? "y" : "n");
if (!Status)
throw Status;
}
2021-10-16 16:19:51 +01:00
void COptionsWindow::LoadConfig()
{
m_ConfigDirty = false;
2022-05-01 09:44:28 +01:00
m_HoldChange = true;
2023-05-20 20:56:15 +01:00
LoadTemplates();
2021-10-16 16:19:51 +01:00
LoadGeneral();
LoadGroups();
LoadForced();
LoadStop();
LoadStart();
LoadINetAccess();
LoadNetFwRules();
LoadAccessList();
LoadRecoveryList();
LoadAdvanced();
LoadDebug();
2021-11-13 08:28:32 +00:00
UpdateBoxType();
2022-05-01 09:44:28 +01:00
m_HoldChange = false;
2021-10-16 16:19:51 +01:00
}
void COptionsWindow::WriteAdvancedCheck(QCheckBox* pCheck, const QString& Name, const QString& Value)
{
SB_STATUS Status;
if (pCheck->checkState() == Qt::Checked)
Status = m_pBox->SetText(Name, Value);
else if (pCheck->checkState() == Qt::Unchecked)
Status = m_pBox->DelValue(Name);
if (!Status)
throw Status;
}
void COptionsWindow::WriteAdvancedCheck(QCheckBox* pCheck, const QString& Name, const QString& OnValue, const QString& OffValue)
{
//if (pCheck->checkState() == Qt::PartiallyChecked)
// return;
2021-11-13 08:28:32 +00:00
if (!pCheck->isEnabled())
return;
2022-12-06 09:33:17 +00:00
QString StrValue;
2021-10-16 16:19:51 +01:00
if (pCheck->checkState() == Qt::Checked)
{
2022-11-29 15:49:16 +00:00
if (!OnValue.isEmpty())
2022-12-06 09:33:17 +00:00
StrValue = OnValue;
2021-10-16 16:19:51 +01:00
}
else if (pCheck->checkState() == Qt::Unchecked)
{
if (!OffValue.isEmpty())
2022-12-06 09:33:17 +00:00
StrValue = OffValue;
2021-10-16 16:19:51 +01:00
}
2022-12-06 09:33:17 +00:00
QStringList Values = m_pBox->GetTextList(Name, false);
foreach(const QString & CurValue, Values) {
if (CurValue.contains(","))
continue;
if (!StrValue.isEmpty() && CurValue == StrValue)
StrValue.clear();
else
m_pBox->DelValue(Name, CurValue);
}
if (!StrValue.isEmpty()) {
SB_STATUS Status = m_pBox->InsertText(Name, StrValue);
if (!Status)
throw Status;
}
2021-10-16 16:19:51 +01:00
}
void COptionsWindow::WriteText(const QString& Name, const QString& Value)
{
SB_STATUS Status = m_pBox->SetText(Name, Value);
if (!Status)
throw Status;
}
void COptionsWindow::WriteTextList(const QString& Setting, const QStringList& List)
{
SB_STATUS Status = m_pBox->UpdateTextList(Setting, List, m_Template);
if (!Status)
throw Status;
}
void COptionsWindow::SaveConfig()
{
2022-01-29 09:18:22 +00:00
bool UpdatePaths = false;
2021-10-16 16:19:51 +01:00
m_pBox->SetRefreshOnChange(false);
try
{
if (m_GeneralChanged)
SaveGeneral();
2023-02-15 15:06:37 +00:00
if (m_CopyRulesChanged)
SaveCopyRules();
2021-10-16 16:19:51 +01:00
if (m_GroupsChanged)
SaveGroups();
if (m_ForcedChanged)
SaveForced();
if (m_StopChanged)
SaveStop();
if (m_StartChanged)
SaveStart();
if (m_INetBlockChanged)
SaveINetAccess();
if (m_NetFwRulesChanged)
SaveNetFwRules();
2022-01-29 09:18:22 +00:00
if (m_AccessChanged) {
2021-10-16 16:19:51 +01:00
SaveAccessList();
2022-01-29 09:18:22 +00:00
UpdatePaths = true;
}
2021-10-16 16:19:51 +01:00
if (m_RecoveryChanged)
SaveRecoveryList();
if (m_AdvancedChanged)
SaveAdvanced();
SaveDebug();
if (m_TemplatesChanged)
SaveTemplates();
if (m_FoldersChanged)
SaveFolders();
}
catch (SB_STATUS Status)
{
2023-07-01 17:54:53 +01:00
theGUI->CheckResults(QList<SB_STATUS>() << Status, this);
2021-10-16 16:19:51 +01:00
}
m_pBox->SetRefreshOnChange(true);
m_pBox->GetAPI()->CommitIniChanges();
2022-01-29 09:18:22 +00:00
if (UpdatePaths)
TriggerPathReload();
2021-10-16 16:19:51 +01:00
}
void COptionsWindow::apply()
{
if (m_pBox->GetText("Enabled").isEmpty() && !(m_Template && m_pBox->GetName().mid(9, 6).compare("Local_", Qt::CaseInsensitive) == 0)) {
QMessageBox::critical(this, "Sandboxie-Plus", tr("This sandbox has been deleted hence configuration can not be saved."));
return;
}
CloseINetEdit();
CloseNetFwEdit();
CloseAccessEdit();
2022-09-29 17:28:48 +01:00
CloseOptionEdit();
2021-10-16 16:19:51 +01:00
if (!ui.btnEditIni->isEnabled())
SaveIniSection();
else
SaveConfig();
LoadConfig();
UpdateCurrentTab();
2022-09-29 17:28:48 +01:00
//emit OptionsChanged();
2021-11-13 08:28:32 +00:00
ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
2021-10-16 16:19:51 +01:00
}
void COptionsWindow::ok()
{
apply();
this->close();
}
void COptionsWindow::reject()
{
if (m_GeneralChanged
2023-02-15 15:06:37 +00:00
|| m_CopyRulesChanged
2021-10-16 16:19:51 +01:00
|| m_GroupsChanged
|| m_ForcedChanged
|| m_StopChanged
|| m_StartChanged
// || m_RestrictionChanged
|| m_INetBlockChanged
2022-10-07 13:49:17 +01:00
|| m_NetFwRulesChanged
2021-10-16 16:19:51 +01:00
|| m_AccessChanged
|| m_TemplatesChanged
|| m_FoldersChanged
|| m_RecoveryChanged
|| m_AdvancedChanged)
{
if (QMessageBox("Sandboxie-Plus", tr("Some changes haven't been saved yet, do you really want to close this options window?")
, QMessageBox::Warning, QMessageBox::Yes | QMessageBox::Default, QMessageBox::No | QMessageBox::Escape, QMessageBox::NoButton, this).exec() != QMessageBox::Yes)
return;
}
this->close();
}
2023-04-13 18:46:51 +01:00
void COptionsWindow::SetProgramItem(QString Program, QTreeWidgetItem* pItem, int Column, const QString& Sufix, bool bList)
2021-10-16 16:19:51 +01:00
{
pItem->setData(Column, Qt::UserRole, Program);
if (Program.left(1) == "<")
Program = tr("Group: %1").arg(Program.mid(1, Program.length() - 2));
2022-09-29 17:28:48 +01:00
else if (Program.isEmpty() || Program == "*")
Program = tr("All Programs");
2023-04-13 18:46:51 +01:00
else if(bList)
2021-10-16 16:19:51 +01:00
m_Programs.insert(Program);
2022-09-29 17:28:48 +01:00
pItem->setText(Column, Program + Sufix);
2021-10-16 16:19:51 +01:00
}
QString COptionsWindow::SelectProgram(bool bOrGroup)
{
CComboInputDialog progDialog(this);
progDialog.setText(tr("Enter program:"));
progDialog.setEditable(true);
if (bOrGroup)
{
2021-11-13 08:28:32 +00:00
foreach(const QString Group, GetCurrentGroups()){
QString GroupName = Group.mid(1, Group.length() - 2);
2021-12-03 19:26:09 +00:00
progDialog.addItem(tr("Group: %1").arg(GroupName), Group);
2021-10-16 16:19:51 +01:00
}
}
foreach(const QString & Name, m_Programs)
progDialog.addItem(Name, Name);
progDialog.setValue("");
if (!progDialog.exec())
return QString();
// Note: pressing enter adds the value to the combo list !
QString Program = progDialog.value();
int Index = progDialog.findValue(Program);
if (Index != -1 && progDialog.data().isValid())
Program = progDialog.data().toString();
return Program;
}
2022-09-29 17:28:48 +01:00
void COptionsWindow::OnTab(QWidget* pTab)
2021-10-16 16:19:51 +01:00
{
2022-09-29 17:28:48 +01:00
m_pCurrentTab = pTab;
2022-07-09 15:29:16 +01:00
2022-09-29 17:28:48 +01:00
if (pTab == ui.tabEdit)
2021-10-16 16:19:51 +01:00
{
LoadIniSection();
2023-04-13 18:46:51 +01:00
//ui.txtIniSection->setReadOnly(true);
2021-10-16 16:19:51 +01:00
}
else
{
if (m_ConfigDirty)
LoadConfig();
UpdateCurrentTab();
}
}
void COptionsWindow::UpdateCurrentTab()
{
2022-10-28 19:36:58 +01:00
if (m_pCurrentTab == ui.tabRestrictions || m_pCurrentTab == ui.tabOptions || m_pCurrentTab == ui.tabGeneral)
2022-09-29 17:28:48 +01:00
{
2023-02-12 14:56:23 +00:00
ui.chkVmRead->setChecked(IsAccessEntrySet(eIPC, "", eReadOnly, "$:*"));
2022-10-28 19:36:58 +01:00
}
else if (m_pCurrentTab ==ui.tabPrivileges || m_pCurrentTab == ui.tabSecurity)
{
2023-02-12 14:56:23 +00:00
if (IsAccessEntrySet(eWnd, "", eOpen, "*"))
2022-09-29 17:28:48 +01:00
{
ui.chkAddToJob->setEnabled(false);
ui.chkAddToJob->setChecked(false);
}
else
{
ui.chkAddToJob->setEnabled(true);
ui.chkAddToJob->setChecked(!m_pBox->GetBool("NoAddProcessToJob", false));
}
2022-04-15 17:37:39 +01:00
}
2022-09-29 17:28:48 +01:00
else if (m_pCurrentTab == ui.tabStart || m_pCurrentTab == ui.tabForce)
2021-10-16 16:19:51 +01:00
{
2023-02-12 14:56:23 +00:00
if (IsAccessEntrySet(eIPC, "!<StartRunAccess>", eClosed, "*"))
2021-10-16 16:19:51 +01:00
ui.radStartSelected->setChecked(true);
2023-02-12 14:56:23 +00:00
else if (IsAccessEntrySet(eIPC, "<StartRunAccess>", eClosed, "*"))
2021-10-16 16:19:51 +01:00
ui.radStartExcept->setChecked(true);
else
ui.radStartAll->setChecked(true);
2021-12-03 19:26:09 +00:00
ui.treeStart->clear();
2021-10-16 16:19:51 +01:00
CopyGroupToList("<StartRunAccess>", ui.treeStart);
2021-12-03 19:26:09 +00:00
CopyGroupToList("<StartRunAccessDisabled>", ui.treeStart, true);
2021-10-16 16:19:51 +01:00
OnRestrictStart();
}
2022-09-29 17:28:48 +01:00
else if (m_pCurrentTab == ui.tabInternet || m_pCurrentTab == ui.tabINet)
2021-10-16 16:19:51 +01:00
{
LoadBlockINet();
}
2022-09-29 17:28:48 +01:00
else if (m_pCurrentTab == ui.tabCOM) {
2022-08-28 11:43:08 +01:00
CheckOpenCOM();
2022-09-29 17:28:48 +01:00
}
else if (m_pCurrentTab == ui.tabWnd)
{
2023-02-12 14:56:23 +00:00
if (IsAccessEntrySet(eWnd, "", eOpen, "*"))
2021-10-16 16:19:51 +01:00
{
ui.chkNoWindowRename->setEnabled(false);
ui.chkNoWindowRename->setChecked(true);
}
else
{
ui.chkNoWindowRename->setEnabled(true);
2023-02-12 14:56:23 +00:00
ui.chkNoWindowRename->setChecked(IsAccessEntrySet(eWnd, "", eOpen, "#"));
2021-10-16 16:19:51 +01:00
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2022-01-14 21:28:44 +00:00
// Raw section ini Editor
2021-10-16 16:19:51 +01:00
//
void COptionsWindow::SetIniEdit(bool bEnable)
{
2022-07-09 15:29:16 +01:00
if (m_pTree) {
m_pTree->setEnabled(!bEnable);
}
else {
for (int i = 0; i < ui.tabs->count() - 1; i++) {
bool Enabled = ui.tabs->widget(i)->isEnabled();
ui.tabs->setTabEnabled(i, !bEnable && Enabled);
ui.tabs->widget(i)->setEnabled(Enabled);
}
2021-10-16 16:19:51 +01:00
}
ui.btnSaveIni->setEnabled(bEnable);
ui.btnCancelEdit->setEnabled(bEnable);
2023-04-13 18:46:51 +01:00
//ui.txtIniSection->setReadOnly(!bEnable);
2021-10-16 16:19:51 +01:00
ui.btnEditIni->setEnabled(!bEnable);
}
void COptionsWindow::OnEditIni()
{
SetIniEdit(true);
}
void COptionsWindow::OnSaveIni()
{
SaveIniSection();
SetIniEdit(false);
}
2023-04-13 18:46:51 +01:00
void COptionsWindow::OnIniChanged()
{
if (m_HoldChange)
return;
if(ui.btnEditIni->isEnabled())
SetIniEdit(true);
ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true);
}
2021-10-16 16:19:51 +01:00
void COptionsWindow::OnCancelEdit()
{
SetIniEdit(false);
2023-04-13 18:46:51 +01:00
LoadIniSection();
2021-10-16 16:19:51 +01:00
}
void COptionsWindow::LoadIniSection()
{
QString Section;
2022-01-14 21:28:44 +00:00
// Note: the service only caches sandboxie.ini not templates.ini, hence for global templates we need to load the section through the driver
2021-10-16 17:24:16 +01:00
if (m_Template && m_pBox->GetName().mid(9, 6).compare("Local_", Qt::CaseInsensitive) != 0)
{
m_Settings = m_pBox->GetIniSection(NULL, m_Template);
2021-10-16 16:19:51 +01:00
2021-10-16 17:24:16 +01:00
for (QList<QPair<QString, QString>>::const_iterator I = m_Settings.begin(); I != m_Settings.end(); ++I)
Section += I->first + "=" + I->second + "\n";
}
else
Section = m_pBox->GetAPI()->SbieIniGetEx(m_pBox->GetName(), "");
2021-10-16 16:19:51 +01:00
2021-11-13 08:28:32 +00:00
m_HoldChange = true;
2021-10-16 16:19:51 +01:00
ui.txtIniSection->setPlainText(Section);
2021-11-13 08:28:32 +00:00
m_HoldChange = false;
2021-10-16 16:19:51 +01:00
}
void COptionsWindow::SaveIniSection()
{
m_ConfigDirty = true;
/*m_pBox->SetRefreshOnChange(false);
// Note: an incremental update would be more elegant but it would change the entry order in the ini,
// hence it's better for the user to fully rebuild the section each time.
//
for (QList<QPair<QString, QString>>::const_iterator I = m_Settings.begin(); I != m_Settings.end(); ++I)
m_pBox->DelValue(I->first, I->second);
//QList<QPair<QString, QString>> NewSettings;
//QList<QPair<QString, QString>> OldSettings = m_Settings;
QStringList Section = SplitStr(ui.txtIniSection->toPlainText(), "\n");
foreach(const QString& Line, Section)
{
if (Line.isEmpty())
return;
StrPair Settings = Split2(Line, "=");
//if (!OldSettings.removeOne(Settings))
// NewSettings.append(Settings);
m_pBox->InsertText(Settings.first, Settings.second);
}
//for (QList<QPair<QString, QString>>::const_iterator I = OldSettings.begin(); I != OldSettings.end(); ++I)
// m_pBox->DelValue(I->first, I->second);
//
//for (QList<QPair<QString, QString>>::const_iterator I = NewSettings.begin(); I != NewSettings.end(); ++I)
// m_pBox->InsertText(I->first, I->second);
m_pBox->SetRefreshOnChange(true);
m_pBox->GetAPI()->CommitIniChanges();*/
m_pBox->GetAPI()->SbieIniSet(m_pBox->GetName(), "", ui.txtIniSection->toPlainText());
LoadIniSection();
}
2022-01-29 09:18:22 +00:00
2022-06-08 16:23:19 +01:00
#include "OptionsAccess.cpp"
#include "OptionsAdvanced.cpp"
#include "OptionsForce.cpp"
#include "OptionsGeneral.cpp"
#include "OptionsGrouping.cpp"
#include "OptionsNetwork.cpp"
#include "OptionsRecovery.cpp"
#include "OptionsStart.cpp"
#include "OptionsStop.cpp"
#include "OptionsTemplates.cpp"
2022-01-29 09:18:22 +00:00
#include <windows.h>
void COptionsWindow::TriggerPathReload()
{
//
2022-12-07 16:32:40 +00:00
// this message makes all boxes reload their path presets
2022-01-29 09:18:22 +00:00
//
DWORD bsm_app = BSM_APPLICATIONS;
BroadcastSystemMessage(BSF_POSTMESSAGE, &bsm_app, WM_DEVICECHANGE, 'sb', 0);
2022-09-29 17:28:48 +01:00
}