#include "stdafx.h" #include "SettingsWindow.h" #include "SandMan.h" #include "../MiscHelpers/Common/Settings.h" #include "../MiscHelpers/Common/Common.h" #include "../MiscHelpers/Common/OtherFunctions.h" #include "Helpers/WinAdmin.h" #include "../QSbieAPI/Sandboxie/SbieTemplates.h" #include "../QSbieAPI/SbieUtils.h" #include "OptionsWindow.h" #include "../OnlineUpdater.h" #include "../MiscHelpers/Archive/ArchiveFS.h" #include #include "../Helpers/StorageInfo.h" #include "../Wizards/TemplateWizard.h" #include "../AddonManager.h" #include #include #include #include #include void FixTriStateBoxPallete(QWidget* pWidget) { if (QApplication::style()->objectName() == "windows") { // // the built in "windows" theme of Qt does not properly rendered PartiallyChecked // checkboxes, to remedi this issue we connect to the stateChanged slot // and change the pattern to improve the rendering. // foreach(QCheckBox* pCheck, pWidget->findChildren()) { QObject::connect(pCheck, &QCheckBox::stateChanged, [pCheck](int state) { if (pCheck->isTristate()) { QPalette palette = QApplication::palette(); if (state == Qt::PartiallyChecked) palette.setColor(QPalette::Base, Qt::darkGray); pCheck->setPalette(palette); } }); } } } void AddIconToLabel(QLabel* pLabel, const QPixmap& Pixmap) { QWidget* pParent = pLabel->parentWidget(); QWidget* pWidget = new QWidget(pParent); pParent->layout()->replaceWidget(pLabel, pWidget); QHBoxLayout* pLayout = new QHBoxLayout(pWidget); pLayout->setContentsMargins(0, 0, 0, 0); pLayout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); pLayout->setSpacing(1); QLabel* pIcon = new QLabel(); pIcon = new QLabel(); pIcon->setPixmap(Pixmap); pLayout->addWidget(pIcon); pLayout->addWidget(pLabel); } int CSettingsWindow__Chk2Int(Qt::CheckState state) { switch (state) { case Qt::Unchecked: return 0; case Qt::Checked: return 1; default: case Qt::PartiallyChecked: return 2; } } Qt::CheckState CSettingsWindow__Int2Chk(int state) { switch (state) { case 0: return Qt::Unchecked; case 1: return Qt::Checked; default: case 2: return Qt::PartiallyChecked; } } quint32 g_FeatureFlags = 0; QByteArray g_Certificate; SCertInfo g_CertInfo = { 0 }; void COptionsWindow__AddCertIcon(QWidget* pOriginalWidget, bool bAdvanced = false); CSettingsWindow::CSettingsWindow(QWidget* parent) : CConfigDialog(parent) { Qt::WindowFlags flags = windowFlags(); flags |= Qt::CustomizeWindowHint; //flags &= ~Qt::WindowContextHelpButtonHint; //flags &= ~Qt::WindowSystemMenuHint; //flags &= ~Qt::WindowMinMaxButtonsHint; flags |= Qt::WindowMinimizeButtonHint; //flags &= ~Qt::WindowCloseButtonHint; setWindowFlags(flags); this->setWindowFlag(Qt::WindowStaysOnTopHint, theGUI->IsAlwaysOnTop()); ui.setupUi(this); this->setWindowTitle(tr("Sandboxie Plus - Global Settings")); if (theConf->GetBool("Options/AltRowColors", false)) { foreach(QTreeWidget* pTree, this->findChildren()) pTree->setAlternatingRowColors(true); } FixTriStateBoxPallete(this); ui.tabs->setTabPosition(QTabWidget::West); ui.tabs->setCurrentIndex(0); ui.tabs->setTabIcon(0, CSandMan::GetIcon("Config")); ui.tabs->setTabIcon(1, CSandMan::GetIcon("Shell")); ui.tabs->setTabIcon(2, CSandMan::GetIcon("Design")); ui.tabs->setTabIcon(3, CSandMan::GetIcon("Plugins")); ui.tabs->setTabIcon(4, CSandMan::GetIcon("Support")); ui.tabs->setTabIcon(5, CSandMan::GetIcon("Advanced")); ui.tabs->setTabIcon(6, CSandMan::GetIcon("Control")); ui.tabs->setTabIcon(7, CSandMan::GetIcon("Compatibility")); ui.tabs->setTabIcon(8, CSandMan::GetIcon("Editor")); ui.tabsGeneral->setCurrentIndex(0); ui.tabsGeneral->setTabIcon(0, CSandMan::GetIcon("Presets")); ui.tabsGeneral->setTabIcon(1, CSandMan::GetIcon("Notification")); ui.tabsShell->setCurrentIndex(0); ui.tabsShell->setTabIcon(0, CSandMan::GetIcon("Windows")); ui.tabsShell->setTabIcon(1, CSandMan::GetIcon("TaskBar")); ui.tabsShell->setTabIcon(2, CSandMan::GetIcon("Run")); ui.tabsGUI->setCurrentIndex(0); ui.tabsGUI->setTabIcon(0, CSandMan::GetIcon("Interface")); ui.tabsGUI->setTabIcon(1, CSandMan::GetIcon("Monitor")); ui.tabsAddons->setCurrentIndex(0); ui.tabsAddons->setTabIcon(0, CSandMan::GetIcon("Plugin")); ui.tabsAddons->setTabIcon(1, CSandMan::GetIcon("Qube")); ui.tabsSupport->setCurrentIndex(0); ui.tabsSupport->setTabIcon(0, CSandMan::GetIcon("Cert")); ui.tabsSupport->setTabIcon(1, CSandMan::GetIcon("ReloadIni")); ui.tabsAdvanced->setCurrentIndex(0); ui.tabsAdvanced->setTabIcon(0, CSandMan::GetIcon("Options")); ui.tabsAdvanced->setTabIcon(1, CSandMan::GetIcon("EditIni")); ui.tabsControl->setCurrentIndex(0); ui.tabsControl->setTabIcon(0, CSandMan::GetIcon("Alarm")); ui.tabsControl->setTabIcon(1, CSandMan::GetIcon("USB")); ui.tabsTemplates->setCurrentIndex(0); ui.tabsTemplates->setTabIcon(0, CSandMan::GetIcon("Program")); ui.tabsTemplates->setTabIcon(1, CSandMan::GetIcon("Template")); int size = 16.0; #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) size *= (QApplication::desktop()->logicalDpiX() / 96.0); // todo Qt6 #endif AddIconToLabel(ui.lblGeneral, CSandMan::GetIcon("Options").pixmap(size,size)); AddIconToLabel(ui.lblRecovery, CSandMan::GetIcon("Recover").pixmap(size,size)); AddIconToLabel(ui.lblNotify, CSandMan::GetIcon("Notification").pixmap(size,size)); AddIconToLabel(ui.lblMessages, CSandMan::GetIcon("Email").pixmap(size,size)); //AddIconToLabel(ui.lblMessages, CSandMan::GetIcon("Filter").pixmap(size,size)); AddIconToLabel(ui.lblStartUp, CSandMan::GetIcon("Start").pixmap(size,size)); AddIconToLabel(ui.lblRunBoxed, CSandMan::GetIcon("Run").pixmap(size,size)); AddIconToLabel(ui.lblStartMenu, CSandMan::GetIcon("StartMenu").pixmap(size,size)); AddIconToLabel(ui.lblSysTray, CSandMan::GetIcon("Maintenance").pixmap(size,size)); AddIconToLabel(ui.lblInterface, CSandMan::GetIcon("GUI").pixmap(size,size)); AddIconToLabel(ui.lblDisplay, CSandMan::GetIcon("Advanced").pixmap(size,size)); AddIconToLabel(ui.lblIni, CSandMan::GetIcon("EditIni").pixmap(size,size)); AddIconToLabel(ui.lblDiskImage, CSandMan::GetIcon("Disk").pixmap(size,size)); AddIconToLabel(ui.lblBoxRoot, CSandMan::GetIcon("Sandbox").pixmap(size,size)); AddIconToLabel(ui.lblBoxFeatures, CSandMan::GetIcon("Miscellaneous").pixmap(size,size)); AddIconToLabel(ui.lblProtection, CSandMan::GetIcon("Lock").pixmap(size,size)); AddIconToLabel(ui.lblUpdates, CSandMan::GetIcon("Update").pixmap(size,size)); int iViewMode = theConf->GetInt("Options/ViewMode", 1); /*if (iViewMode == 0) { if (iOptionLayout == 1) ui.tabs->removeTab(6); // ini edit else ui.tabs->removeTab(7); // ini edit }*/ ui.tabs->setCurrentIndex(0); { ui.uiLang->addItem(tr("Auto Detection"), ""); ui.uiLang->addItem(tr("No Translation"), "native"); QString langDir; C7zFileEngineHandler LangFS("lang", this); if (LangFS.Open(QApplication::applicationDirPath() + "/translations.7z")) langDir = LangFS.Prefix() + "/"; else langDir = QApplication::applicationDirPath() + "/translations/"; foreach(const QString & langFile, QDir(langDir).entryList(QStringList("sandman_*.qm"), QDir::Files)) { QString Code = langFile.mid(8, langFile.length() - 8 - 3); QLocale Locale(Code); QString Lang = Locale.nativeLanguageName(); ui.uiLang->addItem(Lang, Code); } ui.uiLang->setCurrentIndex(ui.uiLang->findData(theConf->GetString("Options/UiLanguage"))); } ui.cmbIntegrateMenu->addItem(tr("Don't integrate links")); ui.cmbIntegrateMenu->addItem(tr("As sub group")); ui.cmbIntegrateMenu->addItem(tr("Fully integrate")); ui.cmbIntegrateDesk->addItem(tr("Don't integrate links")); ui.cmbIntegrateDesk->addItem(tr("As sub group")); ui.cmbIntegrateDesk->addItem(tr("Fully integrate")); ui.cmbSysTray->addItem(tr("Don't show any icon")); ui.cmbSysTray->addItem(tr("Show Plus icon")); ui.cmbSysTray->addItem(tr("Show Classic icon")); ui.cmbTrayBoxes->addItem(tr("All Boxes")); ui.cmbTrayBoxes->addItem(tr("Active + Pinned")); ui.cmbTrayBoxes->addItem(tr("Pinned Only")); ui.cmbOnClose->addItem(tr("Close to Tray"), "ToTray"); ui.cmbOnClose->addItem(tr("Prompt before Close"), "Prompt"); ui.cmbOnClose->addItem(tr("Close"), "Close"); ui.cmbDPI->addItem(tr("None"), 0); ui.cmbDPI->addItem(tr("Native"), 1); ui.cmbDPI->addItem(tr("Qt"), 2); ui.cmbInterval->addItem(tr("Every Day"), 1 * 24 * 60 * 60); ui.cmbInterval->addItem(tr("Every Week"), 7 * 24 * 60 * 60); ui.cmbInterval->addItem(tr("Every 2 Weeks"), 14 * 24 * 60 * 60); ui.cmbInterval->addItem(tr("Every 30 days"), 30 * 24 * 60 * 60); ui.cmbUpdate->addItem(tr("Ignore"), "ignore"); ui.cmbUpdate->addItem(tr("Notify"), "notify"); ui.cmbUpdate->addItem(tr("Download & Notify"), "download"); ui.cmbUpdate->addItem(tr("Download & Install"), "install"); //ui.cmbRelease->addItem(tr("Ignore"), "ignore"); ui.cmbRelease->addItem(tr("Notify"), "notify"); ui.cmbRelease->addItem(tr("Download & Notify"), "download"); ui.cmbRelease->addItem(tr("Download & Install"), "install"); int FontScales[] = { 75,100,125,150,175,200,225,250,275,300,350,400, 0 }; for (int* pFontScales = FontScales; *pFontScales != 0; pFontScales++) ui.cmbFontScale->addItem(tr("%1").arg(*pFontScales), *pFontScales); QSettings CurrentVersion("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", QSettings::NativeFormat); if (CurrentVersion.value("CurrentBuild").toInt() >= 22000) { // Windows 11 QCheckBox* SecretCheckBox = new CSecretCheckBox(ui.chkShellMenu->text()); ((QGridLayout*)((QWidget*)ui.chkShellMenu->parent())->layout())->replaceWidget(ui.chkShellMenu, SecretCheckBox); ui.chkShellMenu->deleteLater(); ui.chkShellMenu = SecretCheckBox; } m_HoldChange = false; CPathEdit* pEditor = new CPathEdit(); ui.txtEditor->parentWidget()->layout()->replaceWidget(ui.txtEditor, pEditor); ui.txtEditor->deleteLater(); ui.txtEditor = pEditor->GetEdit(); LoadSettings(); ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); connect(theGUI, SIGNAL(DrivesChanged()), this, SLOT(UpdateDrives())); // General Config connect(ui.uiLang, SIGNAL(currentIndexChanged(int)), this, SLOT(OnChangeGUI())); connect(ui.chkSandboxUrls, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.chkMonitorSize, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.chkPanic, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.keyPanic, SIGNAL(keySequenceChanged(const QKeySequence &)), this, SLOT(OnOptChanged())); connect(ui.chkTop, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.keyTop, SIGNAL(keySequenceChanged(const QKeySequence &)), this, SLOT(OnOptChanged())); connect(ui.chkPauseForce, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.keyPauseForce, SIGNAL(keySequenceChanged(const QKeySequence &)), this, SLOT(OnOptChanged())); connect(ui.chkAsyncBoxOps, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.chkSilentMode, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.chkCopyProgress, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.chkNoMessages, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.btnAddMessage, SIGNAL(clicked(bool)), this, SLOT(OnAddMessage())); connect(ui.btnDelMessage, SIGNAL(clicked(bool)), this, SLOT(OnDelMessage())); connect(ui.treeMessages, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(OnMessageChanged())); m_MessagesChanged = false; connect(ui.chkNotifyRecovery, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.chkShowRecovery, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.chkRecoveryTop, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); // // Shell Integration connect(ui.chkAutoStart, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.chkSvcStart, SIGNAL(stateChanged(int)), this, SLOT(OnGeneralChanged())); connect(ui.chkShellMenu, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.chkAlwaysDefault, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.chkShellMenu2, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.chkScanMenu, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.cmbIntegrateMenu, SIGNAL(currentIndexChanged(int)), this, SLOT(OnOptChanged())); connect(ui.cmbIntegrateDesk, SIGNAL(currentIndexChanged(int)), this, SLOT(OnOptChanged())); connect(ui.cmbSysTray, SIGNAL(currentIndexChanged(int)), this, SLOT(OnOptChanged())); connect(ui.cmbTrayBoxes, SIGNAL(currentIndexChanged(int)), this, SLOT(OnOptChanged())); connect(ui.chkCompactTray, SIGNAL(stateChanged(int)), this, SLOT(OnChangeGUI())); connect(ui.cmbOnClose, SIGNAL(currentIndexChanged(int)), this, SLOT(OnOptChanged())); connect(ui.chkBoxOpsNotify, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.chkMinimize, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.chkSingleShow, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); // // Interface Config connect(ui.cmbDPI, SIGNAL(currentIndexChanged(int)), this, SLOT(OnChangeGUI())); connect(ui.chkDarkTheme, SIGNAL(stateChanged(int)), this, SLOT(OnChangeGUI())); connect(ui.chkFusionTheme, SIGNAL(stateChanged(int)), this, SLOT(OnChangeGUI())); connect(ui.chkAltRows, SIGNAL(stateChanged(int)), this, SLOT(OnChangeGUI())); connect(ui.chkBackground, SIGNAL(stateChanged(int)), this, SLOT(OnChangeGUI())); connect(ui.chkLargeIcons, SIGNAL(stateChanged(int)), this, SLOT(OnChangeGUI())); connect(ui.chkNoIcons, SIGNAL(stateChanged(int)), this, SLOT(OnChangeGUI())); connect(ui.chkOptTree, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.chkNewLayout, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.chkColorIcons, SIGNAL(stateChanged(int)), this, SLOT(OnChangeGUI())); connect(ui.chkOverlayIcons, SIGNAL(stateChanged(int)), this, SLOT(OnChangeGUI())); connect(ui.chkHideCore, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); connect(ui.cmbFontScale, SIGNAL(currentIndexChanged(int)), this, SLOT(OnChangeGUI())); connect(ui.cmbFontScale, SIGNAL(currentTextChanged(const QString&)), this, SLOT(OnChangeGUI())); connect(ui.txtEditor, SIGNAL(textChanged(const QString&)), this, SLOT(OnOptChanged())); m_bRebuildUI = false; // // Run tab connect(ui.btnAddCmd, SIGNAL(clicked(bool)), this, SLOT(OnAddCommand())); QMenu* pRunBtnMenu = new QMenu(ui.btnAddCmd); pRunBtnMenu->addAction(tr("Browse for Program"), this, SLOT(OnBrowsePath())); ui.btnAddCmd->setPopupMode(QToolButton::MenuButtonPopup); ui.btnAddCmd->setMenu(pRunBtnMenu); connect(ui.btnCmdUp, SIGNAL(clicked(bool)), this, SLOT(OnCommandUp())); connect(ui.btnCmdDown, SIGNAL(clicked(bool)), this, SLOT(OnCommandDown())); connect(ui.btnDelCmd, SIGNAL(clicked(bool)), this, SLOT(OnDelCommand())); connect(ui.treeRun, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(OnRunChanged())); m_RunChanged = false; // // Addons QObject::connect(theGUI->GetAddonManager(), &CAddonManager::DataUpdated, this, [=]() { ui.lblUpdateAddons->setVisible(false); OnLoadAddon(); }); connect(ui.btnInstallAddon, SIGNAL(clicked(bool)), this, SLOT(OnInstallAddon())); connect(ui.btnRemoveAddon, SIGNAL(clicked(bool)), this, SLOT(OnRemoveAddon())); connect(ui.lblUpdateAddons, &QLabel::linkActivated, this, [=]() { theGUI->GetAddonManager()->UpdateAddons(); }); connect(ui.chkRamDisk, SIGNAL(stateChanged(int)), this, SLOT(OnRamDiskChange())); connect(ui.lblImDisk, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&))); QObject::connect(theGUI->GetAddonManager(), &CAddonManager::AddonInstalled, this, [=] { if (!theGUI->GetAddonManager()->GetAddon("ImDisk", CAddonManager::eInstalled).isNull()) { ui.lblImDisk->setVisible(false); ui.chkRamDisk->setEnabled(true); OnRamDiskChange(); } }); connect(ui.txtRamLimit, SIGNAL(textChanged(const QString&)), this, SLOT(OnRamDiskChange())); connect(ui.chkRamLetter, SIGNAL(stateChanged(int)), this, SLOT(OnRamDiskChange())); connect(ui.cmbRamLetter, SIGNAL(currentIndexChanged(int)), this, SLOT(OnGeneralChanged())); DWORD logical_drives = GetLogicalDrives(); for (CHAR search = 'D'; search <= 'Z'; search++) { if ((logical_drives & (1 << (search - 'A'))) == 0) ui.cmbRamLetter->addItem(QString("%1:\\").arg(QChar(search))); } // // Advanced Config connect(ui.cmbDefault, SIGNAL(currentIndexChanged(int)), this, SLOT(OnGeneralChanged())); connect(ui.chkAutoRoot, SIGNAL(stateChanged(int)), this, SLOT(OnRootChanged())); // not sbie ini connect(ui.fileRoot, SIGNAL(textChanged(const QString&)), this, SLOT(OnGeneralChanged())); connect(ui.regRoot, SIGNAL(textChanged(const QString&)), this, SLOT(OnGeneralChanged())); connect(ui.ipcRoot, SIGNAL(textChanged(const QString&)), this, SLOT(OnGeneralChanged())); connect(ui.chkWFP, SIGNAL(stateChanged(int)), this, SLOT(OnFeaturesChanged())); connect(ui.chkObjCb, SIGNAL(stateChanged(int)), this, SLOT(OnFeaturesChanged())); if (CurrentVersion.value("CurrentBuild").toInt() < 14393) // Windows 10 RS1 and later ui.chkWin32k->setEnabled(false); //connect(ui.chkWin32k, SIGNAL(stateChanged(int)), this, SLOT(OnFeaturesChanged())); m_FeaturesChanged = false; connect(ui.chkWin32k, SIGNAL(stateChanged(int)), this, SLOT(OnGeneralChanged())); connect(ui.chkSbieLogon, SIGNAL(stateChanged(int)), this, SLOT(OnGeneralChanged())); m_GeneralChanged = false; connect(ui.chkWatchConfig, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); // not sbie ini connect(ui.chkAdminOnly, SIGNAL(stateChanged(int)), this, SLOT(OnProtectionChange())); connect(ui.chkPassRequired, SIGNAL(stateChanged(int)), this, SLOT(OnProtectionChange())); connect(ui.btnSetPassword, SIGNAL(clicked(bool)), this, SLOT(OnSetPassword())); connect(ui.chkAdminOnlyFP, SIGNAL(stateChanged(int)), this, SLOT(OnProtectionChange())); connect(ui.chkClearPass, SIGNAL(stateChanged(int)), this, SLOT(OnProtectionChange())); m_ProtectionChanged = false; // // Program Control connect(ui.chkStartBlock, SIGNAL(stateChanged(int)), this, SLOT(OnWarnChanged())); connect(ui.chkStartBlockMsg, SIGNAL(stateChanged(int)), this, SLOT(OnWarnChanged())); connect(ui.chkNotForcedMsg, SIGNAL(stateChanged(int)), this, SLOT(OnWarnChanged())); connect(ui.btnAddWarnProg, SIGNAL(clicked(bool)), this, SLOT(OnAddWarnProg())); connect(ui.btnAddWarnFolder, SIGNAL(clicked(bool)), this, SLOT(OnAddWarnFolder())); connect(ui.btnDelWarnProg, SIGNAL(clicked(bool)), this, SLOT(OnDelWarnProg())); connect(ui.btnBrowse, SIGNAL(clicked(bool)), this, SLOT(OnBrowse())); m_WarnProgsChanged = false; // // USB connect(ui.chkSandboxUsb, SIGNAL(stateChanged(int)), this, SLOT(OnVolumeChanged())); connect(ui.cmbUsbSandbox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnVolumeChanged())); connect(ui.treeVolumes, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(OnVolumeChanged())); m_VolumeChanged = false; // // Templates connect(ui.btnAddCompat, SIGNAL(clicked(bool)), this, SLOT(OnAddCompat())); connect(ui.btnDelCompat, SIGNAL(clicked(bool)), this, SLOT(OnDelCompat())); m_CompatLoaded = 0; m_CompatChanged = false; ui.chkNoCompat->setChecked(!theConf->GetBool("Options/AutoRunSoftCompat", true)); connect(ui.treeCompat, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(OnTemplateClicked(QTreeWidgetItem*, int))); connect(ui.treeCompat, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(OnTemplateDoubleClicked(QTreeWidgetItem*, int))); connect(ui.txtTemplates, SIGNAL(textChanged(const QString&)), this, SLOT(OnFilterTemplates())); //connect(ui.treeTemplates, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(OnTemplateClicked(QTreeWidgetItem*, int))); connect(ui.treeTemplates, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(OnTemplateClicked(QTreeWidgetItem*, int))); connect(ui.treeTemplates, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(OnTemplateDoubleClicked(QTreeWidgetItem*, int))); connect(ui.btnAddTemplate, SIGNAL(clicked(bool)), this, SLOT(OnAddTemplates())); 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); connect(ui.btnDelTemplate, SIGNAL(clicked(bool)), this, SLOT(OnDelTemplates())); // // Support connect(ui.lblSupport, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&))); connect(ui.lblSupportCert, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&))); connect(ui.lblCertExp, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&))); connect(ui.lblInsiderInfo, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&))); m_CertChanged = false; connect(ui.txtCertificate, SIGNAL(textChanged()), this, SLOT(CertChanged())); connect(theGUI, SIGNAL(CertUpdated()), this, SLOT(UpdateCert())); ui.txtCertificate->setPlaceholderText( "NAME: User Name\n" "TYPE: ULTIMATE\n" "DATE: dd.mm.yyyy\n" "UPDATEKEY: 00000000000000000000000000000000\n" "SIGNATURE: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" ); if (g_CertInfo.active) { QString Text = ui.lblSerial->text(); ui.lblSerial->setText(QString("%1").arg(Text)); ui.txtSerial->setVisible(false); ui.btnGetCert->setVisible(false); connect(ui.lblSerial, &QLabel::linkActivated, this, [=]() { ui.lblSerial->setText(Text); ui.txtSerial->setVisible(true); ui.btnGetCert->setVisible(true); }); } connect(ui.btnGetCert, SIGNAL(clicked(bool)), this, SLOT(OnGetCert())); connect(ui.chkNoCheck, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged())); // connect(ui.lblCurrent, SIGNAL(linkActivated(const QString&)), this, SLOT(OnUpdate(const QString&))); connect(ui.lblStable, SIGNAL(linkActivated(const QString&)), this, SLOT(OnUpdate(const QString&))); connect(ui.lblPreview, SIGNAL(linkActivated(const QString&)), this, SLOT(OnUpdate(const QString&))); connect(ui.lblInsider, SIGNAL(linkActivated(const QString&)), this, SLOT(OnUpdate(const QString&))); //connect(ui.lblInsiderInfo, SIGNAL(linkActivated(const QString&)), this, SLOT(OnUpdate(const QString&))); connect(ui.chkAutoUpdate, SIGNAL(toggled(bool)), this, SLOT(UpdateUpdater())); connect(ui.cmbInterval, SIGNAL(currentIndexChanged(int)), this, SLOT(OnOptChanged())); connect(ui.radStable, SIGNAL(toggled(bool)), this, SLOT(UpdateUpdater())); connect(ui.radPreview, SIGNAL(toggled(bool)), this, SLOT(UpdateUpdater())); connect(ui.radInsider, SIGNAL(toggled(bool)), this, SLOT(UpdateUpdater())); connect(ui.cmbUpdate, SIGNAL(currentIndexChanged(int)), this, SLOT(OnOptChanged())); connect(ui.cmbRelease, SIGNAL(currentIndexChanged(int)), this, SLOT(OnOptChanged())); connect(ui.chkUpdateIssues, SIGNAL(toggled(bool)), this, SLOT(OnOptChanged())); connect(ui.chkUpdateAddons, SIGNAL(toggled(bool)), this, SLOT(OnOptChanged())); // connect(ui.tabs, SIGNAL(currentChanged(int)), this, SLOT(OnTab())); // Ini Edit ui.btnSelectIniFont->setIcon(CSandMan::GetIcon("Font")); ui.btnSelectIniFont->setToolTip(tr("Select font")); ui.btnResetIniFont->setIcon(CSandMan::GetIcon("ResetFont")); ui.btnResetIniFont->setToolTip(tr("Reset font")); ApplyIniEditFont(); connect(ui.btnSelectIniFont, SIGNAL(clicked(bool)), this, SLOT(OnSelectIniEditFont())); connect(ui.btnResetIniFont, SIGNAL(clicked(bool)), this, SLOT(OnResetIniEditFont())); 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())); connect(ui.txtIniSection, SIGNAL(textChanged()), this, SLOT(OnIniChanged())); // 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(reject())); if (!CERT_IS_LEVEL(g_CertInfo, eCertStandard)) { //COptionsWindow__AddCertIcon(ui.chkUpdateTemplates); COptionsWindow__AddCertIcon(ui.chkUpdateIssues); COptionsWindow__AddCertIcon(ui.chkRamDisk); COptionsWindow__AddCertIcon(ui.chkSandboxUsb); } this->installEventFilter(this); // prevent enter from closing the dialog restoreGeometry(theConf->GetBlob("SettingsWindow/Window_Geometry")); foreach(QTreeWidget * pTree, this->findChildren()) { QByteArray Columns = theConf->GetBlob("SettingsWindow/" + pTree->objectName() + "_Columns"); if (!Columns.isEmpty()) pTree->header()->restoreState(Columns); } int iOptionTree = theConf->GetInt("Options/OptionTree", 2); if (iOptionTree == 2) iOptionTree = iViewMode == 2 ? 1 : 0; if (iOptionTree) OnSetTree(); else { QWidget* pSearch = AddConfigSearch(ui.tabs); ui.horizontalLayout->insertWidget(0, pSearch); QTimer::singleShot(0, [this]() { m_pSearch->setMaximumWidth(m_pTabs->tabBar()->width()); }); QAction* pSetTree = new QAction(); connect(pSetTree, SIGNAL(triggered()), this, SLOT(OnSetTree())); pSetTree->setShortcut(QKeySequence("Ctrl+Alt+T")); pSetTree->setShortcutContext(Qt::WidgetWithChildrenShortcut); this->addAction(pSetTree); } m_pSearch->setPlaceholderText(tr("Search for settings")); } void CSettingsWindow::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.lblIniEditFont->setText(tr("%0, %1 pt").arg(font.family()).arg(font.pointSizeF())); // tr: example: "Calibri, 9.5 pt" } void CSettingsWindow::OnSelectIniEditFont() { bool ok; auto newFont = QFontDialog::getFont(&ok, ui.txtIniSection->font(), this); if (!ok) return; theConf->SetValue("UIConfig/IniFont", newFont.toString()); ApplyIniEditFont(); } void CSettingsWindow::OnResetIniEditFont() { theConf->DelValue("UIConfig/IniFont"); ApplyIniEditFont(); } void CSettingsWindow::OnSetTree() { if (!ui.tabs) return; QWidget* pAltView = ConvertToTree(ui.tabs); ui.verticalLayout->replaceWidget(ui.tabs, pAltView); ui.tabs->deleteLater(); ui.tabs = NULL; } CSettingsWindow::~CSettingsWindow() { theConf->SetBlob("SettingsWindow/Window_Geometry",saveGeometry()); foreach(QTreeWidget * pTree, this->findChildren()) theConf->SetBlob("SettingsWindow/" + pTree->objectName() + "_Columns", pTree->header()->saveState()); } void CSettingsWindow::showTab(const QString& Name, bool bExclusive) { QWidget* pWidget = this->findChild("tab" + Name); if (ui.tabs) { for (int i = 0; i < ui.tabs->count(); i++) { QGridLayout* pGrid = qobject_cast(ui.tabs->widget(i)->layout()); QTabWidget* pSubTabs = pGrid ? qobject_cast(pGrid->itemAt(0)->widget()) : NULL; if(ui.tabs->widget(i) == pWidget) ui.tabs->setCurrentIndex(i); else if(pSubTabs) { for (int j = 0; j < pSubTabs->count(); j++) { if (pSubTabs->widget(j) == pWidget) { ui.tabs->setCurrentIndex(i); pSubTabs->setCurrentIndex(j); } } } } } else m_pStack->setCurrentWidget(pWidget); if(pWidget == ui.tabCompat) m_CompatLoaded = 2; if(pWidget == ui.tabSupport) ui.chkNoCheck->setVisible(true); if (bExclusive) { if (ui.tabs) ui.tabs->tabBar()->setVisible(false); else { m_pTree->setVisible(false); m_pSearch->setVisible(false); } } SafeShow(this); } void CSettingsWindow::closeEvent(QCloseEvent *e) { emit Closed(); this->deleteLater(); } bool CSettingsWindow::eventFilter(QObject *source, QEvent *event) { //if (event->type() == QEvent::KeyPress && ((QKeyEvent*)event)->key() == Qt::Key_Escape // && ((QKeyEvent*)event)->modifiers() == Qt::NoModifier) //{ // return true; // cancel event //} if (event->type() == QEvent::KeyPress && (((QKeyEvent*)event)->key() == Qt::Key_Enter || ((QKeyEvent*)event)->key() == Qt::Key_Return) && (((QKeyEvent*)event)->modifiers() == Qt::NoModifier || ((QKeyEvent*)event)->modifiers() == Qt::KeypadModifier)) { return true; // cancel event } return QDialog::eventFilter(source, event); } void CSettingsWindow::OnAddMessage() { QString Value = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please enter message"), QLineEdit::Normal); if (Value.isEmpty()) return; StrPair IdText = Split2(Value, ","); AddMessageItem(IdText.first, IdText.second); OnMessageChanged(); } void CSettingsWindow::AddMessageItem(const QString& ID, const QString& Text) { QTreeWidgetItem* pItem = new QTreeWidgetItem(); pItem->setText(0, ID); pItem->setText(1, Text); pItem->setFlags(pItem->flags() | Qt::ItemIsEditable); ui.treeMessages->addTopLevelItem(pItem); } void CSettingsWindow::OnDelMessage() { QTreeWidgetItem* pItem = ui.treeMessages->currentItem(); if (!pItem) return; delete pItem; OnMessageChanged(); } void CSettingsWindow::OnBrowsePath() { QString Value = QFileDialog::getOpenFileName(this, tr("Select Program"), "", tr("Executables (*.exe *.cmd)")).replace("/", "\\"); if (Value.isEmpty()) return; QString Name = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please enter a menu title"), QLineEdit::Normal); if (Name.isEmpty()) return; QVariantMap Entry; Entry["Name"] = Name; Entry["Command"] = "\"" + Value + "\""; AddRunItem(ui.treeRun, Entry); } void CSettingsWindow::OnAddCommand() { QString Value = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please enter a command"), QLineEdit::Normal); if (Value.isEmpty()) return; QString Name = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please enter a menu title"), QLineEdit::Normal); if (Name.isEmpty()) return; QVariantMap Entry; Entry["Name"] = Name; Entry["Command"] = Value; AddRunItem(ui.treeRun, Entry); OnRunChanged(); } void CSettingsWindow::OnCommandUp() { int index = ui.treeRun->indexOfTopLevelItem(ui.treeRun->currentItem()); if (index > 0) { QTreeWidgetItem* pItem = ui.treeRun->takeTopLevelItem(index); ui.treeRun->insertTopLevelItem(index - 1, pItem); ui.treeRun->setCurrentItem(pItem); OnRunChanged(); } } void CSettingsWindow::OnCommandDown() { int index = ui.treeRun->indexOfTopLevelItem(ui.treeRun->currentItem()); if (index < ui.treeRun->topLevelItemCount()-1) { QTreeWidgetItem* pItem = ui.treeRun->takeTopLevelItem(index); ui.treeRun->insertTopLevelItem(index + 1, pItem); ui.treeRun->setCurrentItem(pItem); OnRunChanged(); } } void CSettingsWindow::OnDelCommand() { QTreeWidgetItem* pItem = ui.treeRun->currentItem(); if (!pItem) return; delete pItem; OnRunChanged(); } Qt::CheckState CSettingsWindow::IsContextMenu() { //QSettings Package("HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\PackagedCom\\Package", QSettings::NativeFormat); QSettings Package("HKEY_CURRENT_USER\\Software\\Classes\\PackagedCom\\Package", QSettings::NativeFormat); foreach(const QString & Key, Package.childGroups()) { if (Key.indexOf("SandboxieShell") == 0) return Qt::Checked; } QString cmd = CSbieUtils::GetContextMenuStartCmd(); if (cmd.contains("SandMan.exe", Qt::CaseInsensitive)) return Qt::Checked; // set up and sandman if (!cmd.isEmpty()) // ... probably sbiectrl.exe return Qt::PartiallyChecked; return Qt::Unchecked; // not set up } void CSettingsWindow::AddContextMenu(bool bAlwaysClassic) { QSettings CurrentVersion("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", QSettings::NativeFormat); if (CurrentVersion.value("CurrentBuild").toInt() >= 22000 && !bAlwaysClassic) // Windows 11 { QSettings MyReg("HKEY_CURRENT_USER\\SOFTWARE\\Xanasoft\\Sandboxie-Plus\\SbieShellExt\\Lang", QSettings::NativeFormat); MyReg.setValue("Open Sandboxed", CSettingsWindow::tr("Run &Sandboxed")); MyReg.setValue("Explore Sandboxed", CSettingsWindow::tr("Run &Sandboxed")); QDir::setCurrent(QCoreApplication::applicationDirPath()); QProcess Proc; Proc.execute("rundll32.exe", QStringList() << "SbieShellExt.dll,RegisterPackage"); Proc.waitForFinished(); return; } CSbieUtils::AddContextMenu(QApplication::applicationDirPath().replace("/", "\\") + "\\SandMan.exe", CSettingsWindow::tr("Run &Sandboxed"), //CSettingsWindow::tr("Explore &Sandboxed"), QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe"); } void CSettingsWindow::RemoveContextMenu() { QSettings CurrentVersion("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", QSettings::NativeFormat); if (CurrentVersion.value("CurrentBuild").toInt() >= 22000) // Windows 11 { QDir::setCurrent(QCoreApplication::applicationDirPath()); QProcess Proc; Proc.execute("rundll32.exe", QStringList() << "SbieShellExt.dll,RemovePackage"); Proc.waitForFinished(); } CSbieUtils::RemoveContextMenu(); } bool CSettingsWindow::AddBrowserIcon() { QString Path = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation).replace("/", "\\"); Path += "\\" + CSettingsWindow::tr("Sandboxed Web Browser") + ".lnk"; QString StartExe = theAPI->GetSbiePath() + "\\SandMan.exe"; QString BoxName = theAPI->GetGlobalSettings()->GetText("DefaultBox", "DefaultBox"); return CSbieUtils::CreateShortcut(StartExe, Path, "", BoxName, "default_browser"); } void CSettingsWindow::LoadSettings() { ui.uiLang->setCurrentIndex(ui.uiLang->findData(theConf->GetString("Options/UiLanguage"))); ui.chkAutoStart->setChecked(IsAutorunEnabled()); if (theAPI->IsConnected()) { if (theAPI->GetUserSettings()->GetBool("SbieCtrl_EnableAutoStart", true)) { if (theAPI->GetUserSettings()->GetText("SbieCtrl_AutoStartAgent", "") != "SandMan.exe") ui.chkSvcStart->setCheckState(Qt::PartiallyChecked); else ui.chkSvcStart->setChecked(true); } else ui.chkSvcStart->setChecked(false); } else { ui.chkSvcStart->setEnabled(false); } ui.chkShellMenu->setCheckState(IsContextMenu()); ui.chkShellMenu2->setChecked(CSbieUtils::HasContextMenu2()); ui.chkAlwaysDefault->setChecked(theConf->GetBool("Options/RunInDefaultBox", false)); ui.cmbDPI->setCurrentIndex(theConf->GetInt("Options/DPIScaling", 1)); ui.chkDarkTheme->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/UseDarkTheme", 2))); ui.chkFusionTheme->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/UseFusionTheme", 2))); ui.chkAltRows->setChecked(theConf->GetBool("Options/AltRowColors", false)); ui.chkBackground->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/UseBackground", 2))); ui.chkLargeIcons->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/LargeIcons", 2))); ui.chkNoIcons->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/NoIcons", 2))); ui.chkOptTree->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/OptionTree", 2))); ui.chkNewLayout->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/NewConfigLayout", 2))); ui.chkColorIcons->setChecked(theConf->GetBool("Options/ColorBoxIcons", false)); ui.chkOverlayIcons->setChecked(theConf->GetBool("Options/UseOverlayIcons", true)); ui.chkHideCore->setChecked(theConf->GetBool("Options/HideSbieProcesses", false)); //ui.cmbFontScale->setCurrentIndex(ui.cmbFontScale->findData(theConf->GetInt("Options/FontScaling", 100))); ui.cmbFontScale->setCurrentText(QString::number(theConf->GetInt("Options/FontScaling", 100))); ui.txtEditor->setText(theConf->GetString("Options/Editor", "notepad.exe")); ui.chkSilentMode->setChecked(theConf->GetBool("Options/CheckSilentMode", true)); ui.chkCopyProgress->setChecked(theConf->GetBool("Options/ShowMigrationProgress", true)); ui.chkNoMessages->setChecked(!theConf->GetBool("Options/ShowNotifications", true)); ui.chkSandboxUrls->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/OpenUrlsSandboxed", 2))); ui.chkShowRecovery->setChecked(theConf->GetBool("Options/ShowRecovery", false)); ui.chkNotifyRecovery->setChecked(!theConf->GetBool("Options/InstantRecovery", true)); ui.chkRecoveryTop->setChecked(theConf->GetBool("Options/RecoveryOnTop", true)); ui.chkAsyncBoxOps->setChecked(theConf->GetBool("Options/UseAsyncBoxOps", false)); ui.chkPanic->setChecked(theConf->GetBool("Options/EnablePanicKey", false)); ui.keyPanic->setKeySequence(QKeySequence(theConf->GetString("Options/PanicKeySequence", "Shift+Pause"))); ui.chkTop->setChecked(theConf->GetBool("Options/EnableTopMostKey", false)); ui.keyTop->setKeySequence(QKeySequence(theConf->GetString("Options/TopMostKeySequence", "Alt+Pause"))); ui.chkPauseForce->setChecked(theConf->GetBool("Options/EnablePauseForceKey", false)); ui.keyPauseForce->setKeySequence(QKeySequence(theConf->GetString("Options/PauseForceKeySequence", "Ctrl+Alt+F"))); ui.chkMonitorSize->setChecked(theConf->GetBool("Options/WatchBoxSize", false)); ui.chkWatchConfig->setChecked(theConf->GetBool("Options/WatchIni", true)); ui.chkScanMenu->setChecked(theConf->GetBool("Options/ScanStartMenu", true)); ui.cmbIntegrateMenu->setCurrentIndex(theConf->GetInt("Options/IntegrateStartMenu", 0)); ui.cmbIntegrateDesk->setCurrentIndex(theConf->GetInt("Options/IntegrateDesktop", 0)); ui.cmbSysTray->setCurrentIndex(theConf->GetInt("Options/SysTrayIcon", 1)); ui.cmbTrayBoxes->setCurrentIndex(theConf->GetInt("Options/SysTrayFilter", 0)); ui.chkCompactTray->setChecked(theConf->GetBool("Options/CompactTray", false)); ui.chkBoxOpsNotify->setChecked(theConf->GetBool("Options/AutoBoxOpsNotify", false)); ui.cmbOnClose->setCurrentIndex(ui.cmbOnClose->findData(theConf->GetString("Options/OnClose", "ToTray"))); ui.chkMinimize->setChecked(theConf->GetBool("Options/MinimizeToTray", false)); ui.chkSingleShow->setChecked(theConf->GetBool("Options/TraySingleClick", false)); OnLoadAddon(); bool bImDiskReady = theGUI->IsImDiskReady(); ui.lblImDisk->setVisible(!bImDiskReady); if (theAPI->IsConnected()) { ui.treeMessages->clear(); foreach(const QString & Value, theAPI->GetUserSettings()->GetTextList("SbieCtrl_HideMessage", false)) { StrPair NameIcon = Split2(Value, ","); AddMessageItem(NameIcon.first, NameIcon.second); } m_MessagesChanged = false; ui.treeRun->clear(); foreach(const QString& Value, theAPI->GetGlobalSettings()->GetTextList("RunCommand", false)) AddRunItem(ui.treeRun, GetRunEntry(Value)); m_RunChanged = false; ui.cmbDefault->clear(); foreach(const CSandBoxPtr & pBox, theAPI->GetAllBoxes()) ui.cmbDefault->addItem(pBox->GetName().replace("_", " "), pBox->GetName()); int pos = ui.cmbDefault->findData(theAPI->GetGlobalSettings()->GetText("DefaultBox", "DefaultBox")); if(pos == -1) pos = ui.cmbDefault->findData("DefaultBox"); ui.cmbDefault->setCurrentIndex(pos); QString FileRootPath_Default = "\\??\\%SystemDrive%\\Sandbox\\%USER%\\%SANDBOX%"; QString KeyRootPath_Default = "\\REGISTRY\\USER\\Sandbox_%USER%_%SANDBOX%"; QString IpcRootPath_Default = "\\Sandbox\\%USER%\\%SANDBOX%\\Session_%SESSION%"; ui.fileRoot->setText(theAPI->GetGlobalSettings()->GetText("FileRootPath", FileRootPath_Default)); //ui.chkSeparateUserFolders->setChecked(theAPI->GetGlobalSettings()->GetBool("SeparateUserFolders", true)); ui.regRoot->setText(theAPI->GetGlobalSettings()->GetText("KeyRootPath", KeyRootPath_Default)); ui.ipcRoot->setText(theAPI->GetGlobalSettings()->GetText("IpcRootPath", IpcRootPath_Default)); ui.chkRamDisk->setEnabled(bImDiskReady); quint32 uDiskLimit = theAPI->GetGlobalSettings()->GetNum64("RamDiskSizeKb"); ui.chkRamDisk->setChecked(uDiskLimit > 0); if(uDiskLimit > 0) ui.txtRamLimit->setText(QString::number(uDiskLimit)); QString RamLetter = theAPI->GetGlobalSettings()->GetText("RamDiskLetter"); ui.chkRamLetter->setChecked(!RamLetter.isEmpty()); ui.cmbRamLetter->setCurrentText(RamLetter); m_HoldChange = true; OnRamDiskChange(); m_HoldChange = false; ui.chkWFP->setChecked(theAPI->GetGlobalSettings()->GetBool("NetworkEnableWFP", false)); ui.chkObjCb->setChecked(theAPI->GetGlobalSettings()->GetBool("EnableObjectFiltering", true)); ui.chkWin32k->setChecked(theAPI->GetGlobalSettings()->GetBool("EnableWin32kHooks", true)); ui.chkSbieLogon->setChecked(theAPI->GetGlobalSettings()->GetBool("SandboxieLogon", false)); ui.chkAdminOnly->setChecked(theAPI->GetGlobalSettings()->GetBool("EditAdminOnly", false)); ui.chkAdminOnly->setEnabled(IsAdminUser()); ui.chkPassRequired->setChecked(!theAPI->GetGlobalSettings()->GetText("EditPassword", "").isEmpty()); ui.chkAdminOnlyFP->setChecked(theAPI->GetGlobalSettings()->GetBool("ForceDisableAdminOnly", false)); ui.chkClearPass->setChecked(theAPI->GetGlobalSettings()->GetBool("ForgetPassword", false)); m_HoldChange = true; OnProtectionChange(); m_HoldChange = false; m_GeneralChanged = false; ui.chkStartBlock->setChecked(theAPI->GetGlobalSettings()->GetBool("StartRunAlertDenied", false)); ui.chkStartBlockMsg->setChecked(theAPI->GetGlobalSettings()->GetBool("AlertStartRunAccessDenied", true)); ui.chkNotForcedMsg->setChecked(theAPI->GetGlobalSettings()->GetBool("NotifyForceProcessDisabled", false)); ui.treeWarnProgs->clear(); foreach(const QString& Value, theAPI->GetGlobalSettings()->GetTextList("AlertProcess", false)) AddWarnEntry(Value, 1); foreach(const QString& Value, theAPI->GetGlobalSettings()->GetTextList("AlertFolder", false)) AddWarnEntry(Value, 2); m_WarnProgsChanged = false; ui.chkSandboxUsb->setChecked(theAPI->GetGlobalSettings()->GetBool("ForceUsbDrives", false)); ui.cmbUsbSandbox->clear(); foreach(const CSandBoxPtr & pBox, theAPI->GetAllBoxes()) ui.cmbUsbSandbox->addItem(pBox->GetName().replace("_", " ")); ui.cmbUsbSandbox->setCurrentText(theAPI->GetGlobalSettings()->GetText("UsbSandbox", "USB_Box").replace("_", " ")); ui.cmbUsbSandbox->setEnabled(ui.chkSandboxUsb->isChecked() && g_CertInfo.active); ui.treeVolumes->setEnabled(ui.chkSandboxUsb->isChecked() && g_CertInfo.active); UpdateDrives(); m_VolumeChanged = false; } if(!theAPI->IsConnected() || (theAPI->GetGlobalSettings()->GetBool("EditAdminOnly", false) && !IsAdminUser())) { ui.cmbDefault->setEnabled(false); ui.fileRoot->setEnabled(false); //ui.chkSeparateUserFolders->setEnabled(false); ui.chkAutoRoot->setEnabled(false); ui.chkWFP->setEnabled(false); ui.chkObjCb->setEnabled(false); ui.chkWin32k->setEnabled(false); ui.chkSbieLogon->setEnabled(false); ui.regRoot->setEnabled(false); ui.ipcRoot->setEnabled(false); ui.chkRamDisk->setEnabled(false); ui.txtRamLimit->setEnabled(false); ui.lblRamLimit->setEnabled(false); ui.chkAdminOnly->setEnabled(false); ui.chkPassRequired->setEnabled(false); ui.chkAdminOnlyFP->setEnabled(false); ui.chkClearPass->setEnabled(false); ui.btnSetPassword->setEnabled(false); ui.treeWarnProgs->setEnabled(false); ui.btnAddWarnProg->setEnabled(false); ui.btnDelWarnProg->setEnabled(false); ui.chkSandboxUsb->setEnabled(false); ui.cmbUsbSandbox->setEnabled(false); ui.treeVolumes->setEnabled(false); ui.treeCompat->setEnabled(false); ui.btnAddCompat->setEnabled(false); ui.btnDelCompat->setEnabled(false); ui.treeTemplates->setEnabled(false); ui.btnAddTemplate->setEnabled(false); ui.btnDelTemplate->setEnabled(false); ui.btnEditIni->setEnabled(false); } if (theGUI->IsFullyPortable()) { ui.chkAutoRoot->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/PortableRootDir", 2))); m_HoldChange = true; OnRootChanged(); m_HoldChange = false; } else ui.chkAutoRoot->setVisible(false); UpdateCert(); ui.chkNoCheck->setChecked(theConf->GetBool("Options/NoSupportCheck", false)); if(ui.chkNoCheck->isCheckable() && !g_CertInfo.expired) ui.chkNoCheck->setVisible(false); // hide if not relevant ui.chkAutoUpdate->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/CheckForUpdates", 2))); int UpdateInterval = theConf->GetInt("Options/UpdateInterval", UPDATE_INTERVAL); int pos = ui.cmbInterval->findData(UpdateInterval); if (pos == -1) ui.cmbInterval->setCurrentText(QString::number(UpdateInterval)); else ui.cmbInterval->setCurrentIndex(pos); QString ReleaseChannel = theConf->GetString("Options/ReleaseChannel", "stable"); ui.radStable->setChecked(ReleaseChannel == "stable"); ui.radPreview->setChecked(ReleaseChannel == "preview"); ui.radInsider->setChecked(ReleaseChannel == "insider"); m_HoldChange = true; UpdateUpdater(); m_HoldChange = false; ui.cmbUpdate->setCurrentIndex(ui.cmbUpdate->findData(theConf->GetString("Options/OnNewUpdate", "ignore"))); ui.cmbRelease->setCurrentIndex(ui.cmbRelease->findData(theConf->GetString("Options/OnNewRelease", "download"))); //ui.chkUpdateTemplates->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/CheckForTemplates", 2))); ui.chkUpdateAddons->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/CheckForAddons", 2))); ui.chkUpdateIssues->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/CheckForIssues", 2))); //ui.chkUpdateTemplates->setEnabled(g_CertInfo.active && !g_CertInfo.expired); ui.chkUpdateIssues->setEnabled(g_CertInfo.active && !g_CertInfo.expired); } void CSettingsWindow::OnRamDiskChange() { if (sender() == ui.chkRamDisk) { if (ui.chkRamDisk->isChecked()) theGUI->CheckCertificate(this, 2); } if (ui.chkRamDisk->isChecked() && ui.txtRamLimit->text().isEmpty()) ui.txtRamLimit->setText(QString::number(2 * 1024 * 1024)); bool bEnabled = ui.chkRamDisk->isChecked() && ui.chkRamDisk->isEnabled(); ui.lblRamDisk->setEnabled(bEnabled); ui.txtRamLimit->setEnabled(bEnabled); ui.lblRamLimit->setEnabled(bEnabled); ui.lblRamLimit->setText(tr("kilobytes (%1)").arg(FormatSize(ui.txtRamLimit->text().toULongLong() * 1024))); ui.chkRamLetter->setEnabled(bEnabled); ui.cmbRamLetter->setEnabled(bEnabled && ui.chkRamLetter->isChecked()); ui.lblRamLetter->setEnabled(bEnabled && ui.chkRamLetter->isChecked()); OnGeneralChanged(); } void CSettingsWindow::OnVolumeChanged() { if (sender() == ui.chkSandboxUsb) { if (ui.chkSandboxUsb->isChecked()) theGUI->CheckCertificate(this, 2); } ui.cmbUsbSandbox->setEnabled(ui.chkSandboxUsb->isChecked() && g_CertInfo.active); ui.treeVolumes->setEnabled(ui.chkSandboxUsb->isChecked() && g_CertInfo.active); if (!g_CertInfo.active) return; m_VolumeChanged = true; OnOptChanged(); } void CSettingsWindow::UpdateDrives() { if (!theAPI->IsConnected()) return; ui.treeVolumes->clear(); QStringList DisabledForceVolume = theAPI->GetGlobalSettings()->GetTextList("DisabledForceVolume", false); auto volumes = ListAllVolumes(); auto drives = ListAllDrives(); for (auto I = volumes.begin(); I != volumes.end(); ++I) { QStringList Devices; bool bOnUSB = false; for (auto J = I->disks.begin(); J != I->disks.end(); ++J) { SDriveInfo& info = drives[J->deviceName]; if (info.Enum == L"USBSTOR") bOnUSB = true; Devices.append(QString::fromStdWString(info.Name)); } if (bOnUSB) { QTreeWidgetItem* pItem = new QTreeWidgetItem(); ui.treeVolumes->addTopLevelItem(pItem); QString Info = Devices.join("|"); QStringList Mounts; for (auto J = I->mountPoints.begin(); J != I->mountPoints.end(); ++J) Mounts.append(QString::fromStdWString(*J)); Info += " (" + Mounts.join(", ") + ")"; std::wstring label; quint32 sn = CSbieAPI::GetVolumeSN(I->deviceName.c_str(), &label); QString SN = QString("%1-%2").arg((ushort)HIWORD(sn), 4, 16, QChar('0')).arg((ushort)LOWORD(sn), 4, 16, QChar('0')).toUpper(); if (!label.empty()) Info += " [" + QString::fromStdWString(label) + "]"; pItem->setText(0, SN); if(DisabledForceVolume.removeAll(SN)) pItem->setCheckState(0, Qt::Unchecked); else pItem->setCheckState(0, Qt::Checked); pItem->setText(1, Info); } } foreach(const QString & SN, DisabledForceVolume) { QTreeWidgetItem* pItem = new QTreeWidgetItem(); ui.treeVolumes->addTopLevelItem(pItem); pItem->setText(0, SN); pItem->setCheckState(0, Qt::Unchecked); pItem->setText(1, tr("Volume not attached")); } } //void ScanForSeats(); //int CountSeats(); void CSettingsWindow::UpdateCert() { ui.lblCertExp->setVisible(false); //ui.lblCertLevel->setVisible(!g_Certificate.isEmpty()); if (!g_Certificate.isEmpty()) { ui.txtCertificate->setPlainText(g_Certificate); //ui.lblSupport->setVisible(false); QPalette palette = QApplication::palette(); if (theGUI->m_DarkTheme) palette.setColor(QPalette::Text, Qt::black); if (g_CertInfo.expired) { palette.setColor(QPalette::Base, QColor(255, 255, 192)); QString infoMsg = tr("This supporter certificate has expired, please get an updated certificate."); if (g_CertInfo.active) { if (g_CertInfo.grace_period) infoMsg.append(tr("
Plus features will be disabled in %1 days.").arg((g_CertInfo.expirers_in_sec + 30*60*60*24) / (60*60*24))); else if (!g_CertInfo.outdated) // must be an expiren medium or large cert on an old build infoMsg.append(tr("
For the current build Plus features remain enabled, but you no longer have access to Sandboxie-Live services, including compatibility updates and the troubleshooting database.")); } else infoMsg.append(tr("
Plus features are no longer enabled.")); ui.lblCertExp->setText(infoMsg); ui.lblCertExp->setVisible(true); } else { if (g_CertInfo.expirers_in_sec > 0 && g_CertInfo.expirers_in_sec < (60 * 60 * 24 * 30)) { ui.lblCertExp->setText(tr("This supporter certificate will expire in %1 days, please get an updated certificate.").arg(g_CertInfo.expirers_in_sec / (60*60*24))); ui.lblCertExp->setVisible(true); } /*#ifdef _DEBUG else { ui.lblCertExp->setText(tr("This supporter certificate is valid, check for an updated certificate.")); ui.lblCertExp->setVisible(true); } #endif*/ palette.setColor(QPalette::Base, QColor(192, 255, 192)); } ui.txtCertificate->setPalette(palette); //ui.lblCertLevel->setText(tr("Feature Level: %1").arg(GetCertLevel())); // //QStringList Infos; //Infos += tr("Type: %1").arg(GetCertType()); //if (CERT_IS_INSIDER(g_CertInfo)) // Infos += tr("Insider release capable"); //ui.lblCertLevel->setToolTip(Infos.join("\n")); //if (CERT_IS_TYPE(g_CertInfo, eCertBusiness)) { // ScanForSeats(); // QTimer::singleShot(1000, this, [=]() { // QString CntInfo = QString::number(CountSeats()); // QString Amount = GetArguments(g_Certificate, L'\n', L':').value("AMOUNT"); // if (!Amount.isEmpty()) // CntInfo += "/" + Amount; // ui.lblCertCount->setText(CntInfo); // ui.lblCertCount->setToolTip(tr("Count of certificates in use")); // }); //} } ui.radInsider->setEnabled(CERT_IS_INSIDER(g_CertInfo)); } void CSettingsWindow::OnGetCert() { SB_PROGRESS Status = theGUI->m_pUpdater->GetSupportCert(ui.txtSerial->text(), this, SLOT(OnCertData(const QByteArray&, const QVariantMap&))); if (Status.GetStatus() == OP_ASYNC) { theGUI->AddAsyncOp(Status.GetValue()); Status.GetValue()->ShowMessage(tr("Retrieving certificate...")); } } void CSettingsWindow::OnCertData(const QByteArray& Certificate, const QVariantMap& Params) { ui.txtCertificate->setPlainText(Certificate); ApplyCert(); } void CSettingsWindow::ApplyCert() { if (!theAPI->IsConnected()) return; QByteArray Certificate = ui.txtCertificate->toPlainText().toUtf8(); if (g_Certificate != Certificate) { QPalette palette = QApplication::palette(); if (theGUI->m_DarkTheme) palette.setColor(QPalette::Text, Qt::black); ui.lblCertExp->setVisible(false); bool bRet = ApplyCertificate(Certificate, this); if (Certificate.isEmpty()) palette.setColor(QPalette::Base, Qt::white); else if (!bRet) palette.setColor(QPalette::Base, QColor(255, 192, 192)); else palette.setColor(QPalette::Base, QColor(192, 255, 192)); ui.txtCertificate->setPalette(palette); } m_CertChanged = false; } QString CSettingsWindow::GetCertType() { QString CertType; if (CERT_IS_TYPE(g_CertInfo, eCertContributor)) CertType = tr("Contributor"); else if (CERT_IS_TYPE(g_CertInfo, eCertEternal)) CertType = tr("Eternal"); else if (CERT_IS_TYPE(g_CertInfo, eCertBusiness)) CertType = tr("Business"); else if (CERT_IS_TYPE(g_CertInfo, eCertPersonal)) CertType = tr("Personal"); else if (g_CertInfo.type == eCertGreatPatreon) CertType = tr("Great Patreon"); else if (CERT_IS_TYPE(g_CertInfo, eCertPatreon)) CertType = tr("Patreon"); else if (g_CertInfo.type == eCertFamily) CertType = tr("Family"); else if (CERT_IS_TYPE(g_CertInfo, eCertHome)) CertType = tr("Home"); else if (CERT_IS_TYPE(g_CertInfo, eCertEvaluation)) CertType = tr("Evaluation"); else CertType = tr("Type %1").arg(g_CertInfo.type); return CertType; } QColor CSettingsWindow::GetCertColor() { if (CERT_IS_TYPE(g_CertInfo, eCertEternal)) return QColor(135, 0, 255, 255); else if (CERT_IS_TYPE(g_CertInfo, eCertBusiness)) return QColor(211, 0, 0, 255); else if (CERT_IS_TYPE(g_CertInfo, eCertPersonal)) return QColor(38, 127, 0, 255); else if (CERT_IS_TYPE(g_CertInfo, eCertPatreon)) return QColor(38, 127, 0, 255); else if (g_CertInfo.type == eCertFamily) return QColor(0, 38, 255, 255); else if (CERT_IS_TYPE(g_CertInfo, eCertHome)) return QColor(255, 106, 0, 255); else if (CERT_IS_TYPE(g_CertInfo, eCertEvaluation)) return Qt::gray; else return Qt::black; } QString CSettingsWindow::GetCertLevel() { QString CertLevel; if (g_CertInfo.level == eCertAdvanced) CertLevel = tr("Advanced"); else if (g_CertInfo.level == eCertMaxLevel) CertLevel = tr("Max Level"); else if (g_CertInfo.level != eCertStandard && g_CertInfo.level != eCertStandard2) CertLevel = tr("Level %1").arg(g_CertInfo.level); return CertLevel; } void CSettingsWindow::UpdateUpdater() { bool bOk = (g_CertInfo.active && !g_CertInfo.expired); //ui.radLive->setEnabled(false); if (!ui.chkAutoUpdate->isChecked()) { ui.cmbInterval->setEnabled(false); ui.cmbUpdate->setEnabled(false); ui.cmbRelease->setEnabled(false); ui.lblRevision->setText(QString()); ui.lblRelease->setText(QString()); } else { ui.cmbInterval->setEnabled(true); bool bAllowAuto; if (ui.radStable->isChecked() && !bOk) { ui.cmbUpdate->setEnabled(false); ui.cmbUpdate->setCurrentIndex(ui.cmbUpdate->findData("ignore")); ui.lblRevision->setText(tr("Supporter certificate required for access")); bAllowAuto = false; } else { ui.cmbUpdate->setEnabled(true); ui.lblRevision->setText(QString()); bAllowAuto = true; } ui.cmbRelease->setEnabled(true); QStandardItemModel* model = qobject_cast(ui.cmbRelease->model()); for (int i = 1; i < ui.cmbRelease->count(); i++) { QStandardItem* item = model->item(i); item->setFlags(bAllowAuto ? (item->flags() | Qt::ItemIsEnabled) : (item->flags() & ~Qt::ItemIsEnabled)); } if(!bAllowAuto) ui.lblRelease->setText(tr("Supporter certificate required for automation")); else ui.lblRelease->setText(QString()); } OnOptChanged(); } void CSettingsWindow::WriteAdvancedCheck(QCheckBox* pCheck, const QString& Name, const QString& OnValue, const QString& OffValue) { //if (pCheck->checkState() == Qt::PartiallyChecked) // return; if (!pCheck->isEnabled()) return; SB_STATUS Status; if (pCheck->checkState() == Qt::Checked) { if(!OnValue.isEmpty()) Status = theAPI->GetGlobalSettings()->SetText(Name, OnValue); else Status = theAPI->GetGlobalSettings()->DelValue(Name); } else if (pCheck->checkState() == Qt::Unchecked) { if (!OffValue.isEmpty()) Status = theAPI->GetGlobalSettings()->SetText(Name, OffValue); else Status = theAPI->GetGlobalSettings()->DelValue(Name); } if (!Status) throw Status; } void CSettingsWindow::WriteText(const QString& Name, const QString& Value) { SB_STATUS Status; if(Value.isEmpty()) Status = theAPI->GetGlobalSettings()->DelValue(Name); else Status = theAPI->GetGlobalSettings()->SetText(Name, Value); if (!Status) throw Status; } void CSettingsWindow::WriteTextList(const QString& Setting, const QStringList& List) { SB_STATUS Status = theAPI->GetGlobalSettings()->UpdateTextList(Setting, List, false); if (!Status) throw Status; } void CSettingsWindow::SaveSettings() { theConf->SetValue("Options/UiLanguage", ui.uiLang->currentData()); theConf->SetValue("Options/DPIScaling", ui.cmbDPI->currentData()); theConf->SetValue("Options/UseDarkTheme", CSettingsWindow__Chk2Int(ui.chkDarkTheme->checkState())); theConf->SetValue("Options/UseFusionTheme", CSettingsWindow__Chk2Int(ui.chkFusionTheme->checkState())); theConf->SetValue("Options/AltRowColors", ui.chkAltRows->isChecked()); theConf->SetValue("Options/UseBackground", CSettingsWindow__Chk2Int(ui.chkBackground->checkState())); theConf->SetValue("Options/LargeIcons", CSettingsWindow__Chk2Int(ui.chkLargeIcons->checkState())); theConf->SetValue("Options/NoIcons", CSettingsWindow__Chk2Int(ui.chkNoIcons->checkState())); theConf->SetValue("Options/OptionTree", CSettingsWindow__Chk2Int(ui.chkOptTree->checkState())); theConf->SetValue("Options/NewConfigLayout", CSettingsWindow__Chk2Int(ui.chkNewLayout->checkState())); theConf->SetValue("Options/ColorBoxIcons", ui.chkColorIcons->isChecked()); theConf->SetValue("Options/UseOverlayIcons", ui.chkOverlayIcons->isChecked()); theConf->SetValue("Options/HideSbieProcesses", ui.chkHideCore->isChecked()); int Scaling = ui.cmbFontScale->currentText().toInt(); if (Scaling < 75) Scaling = 75; else if (Scaling > 500) Scaling = 500; theConf->SetValue("Options/FontScaling", Scaling); theConf->SetValue("Options/Editor", ui.txtEditor->text()); AutorunEnable(ui.chkAutoStart->isChecked()); if (theAPI->IsConnected()) { if (ui.chkSvcStart->checkState() == Qt::Checked) { theAPI->GetUserSettings()->SetBool("SbieCtrl_EnableAutoStart", true); theAPI->GetUserSettings()->SetText("SbieCtrl_AutoStartAgent", "SandMan.exe"); } else if (ui.chkSvcStart->checkState() == Qt::Unchecked) theAPI->GetUserSettings()->SetBool("SbieCtrl_EnableAutoStart", false); } if (ui.chkShellMenu->checkState() != IsContextMenu()) { if (ui.chkShellMenu->isChecked()) { CSecretCheckBox* SecretCheckBox = qobject_cast(ui.chkShellMenu); AddContextMenu(SecretCheckBox && SecretCheckBox->IsSecretSet()); } else RemoveContextMenu(); } if (ui.chkShellMenu2->isChecked() != CSbieUtils::HasContextMenu2()) { if (ui.chkShellMenu2->isChecked()) { CSbieUtils::AddContextMenu2(QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe", tr("Run &Un-Sandboxed"), QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe"); } else CSbieUtils::RemoveContextMenu2(); } theConf->SetValue("Options/RunInDefaultBox", ui.chkAlwaysDefault->isChecked()); theConf->SetValue("Options/CheckSilentMode", ui.chkSilentMode->isChecked()); theConf->SetValue("Options/ShowMigrationProgress", ui.chkCopyProgress->isChecked()); theConf->SetValue("Options/ShowNotifications", !ui.chkNoMessages->isChecked()); theConf->SetValue("Options/OpenUrlsSandboxed", CSettingsWindow__Chk2Int(ui.chkSandboxUrls->checkState())); theConf->SetValue("Options/ShowRecovery", ui.chkShowRecovery->isChecked()); theConf->SetValue("Options/InstantRecovery", !ui.chkNotifyRecovery->isChecked()); theConf->SetValue("Options/RecoveryOnTop", ui.chkRecoveryTop->isChecked()); theConf->SetValue("Options/UseAsyncBoxOps", ui.chkAsyncBoxOps->isChecked()); theConf->SetValue("Options/EnablePanicKey", ui.chkPanic->isChecked()); theConf->SetValue("Options/PanicKeySequence", ui.keyPanic->keySequence().toString()); theConf->SetValue("Options/EnableTopMostKey", ui.chkTop->isChecked()); theConf->SetValue("Options/TopMostKeySequence", ui.keyTop->keySequence().toString()); theConf->SetValue("Options/EnablePauseForceKey", ui.chkPauseForce->isChecked()); theConf->SetValue("Options/PauseForceKeySequence", ui.keyPauseForce->keySequence().toString()); theConf->SetValue("Options/WatchBoxSize", ui.chkMonitorSize->isChecked()); theConf->SetValue("Options/WatchIni", ui.chkWatchConfig->isChecked()); theConf->SetValue("Options/ScanStartMenu", ui.chkScanMenu->isChecked()); int OldIntegrateStartMenu = theConf->GetInt("Options/IntegrateStartMenu", 0); theConf->SetValue("Options/IntegrateStartMenu", ui.cmbIntegrateMenu->currentIndex()); int OldIntegrateDesktop = theConf->GetInt("Options/IntegrateDesktop", 0); theConf->SetValue("Options/IntegrateDesktop", ui.cmbIntegrateDesk->currentIndex()); if (ui.cmbIntegrateDesk->currentIndex() != OldIntegrateDesktop || ui.cmbIntegrateMenu->currentIndex() != OldIntegrateStartMenu) { theGUI->ClearStartMenu(); theGUI->SyncStartMenu(); } theConf->SetValue("Options/SysTrayIcon", ui.cmbSysTray->currentIndex()); theConf->SetValue("Options/SysTrayFilter", ui.cmbTrayBoxes->currentIndex()); theConf->SetValue("Options/CompactTray", ui.chkCompactTray->isChecked()); theConf->SetValue("Options/AutoBoxOpsNotify", ui.chkBoxOpsNotify->isChecked()); theConf->SetValue("Options/OnClose", ui.cmbOnClose->currentData()); theConf->SetValue("Options/MinimizeToTray", ui.chkMinimize->isChecked()); theConf->SetValue("Options/TraySingleClick", ui.chkSingleShow->isChecked()); if (theAPI->IsConnected()) { try { if (m_MessagesChanged) { m_MessagesChanged = false; QStringList HiddenMessages; for (int i = 0; i < ui.treeMessages->topLevelItemCount(); i++) { QTreeWidgetItem* pItem = ui.treeMessages->topLevelItem(i); if (!pItem->text(1).isEmpty()) HiddenMessages.append(pItem->text(0) + "," + pItem->text(1)); else HiddenMessages.append(pItem->text(0)); } theAPI->GetUserSettings()->UpdateTextList("SbieCtrl_HideMessage", HiddenMessages, false); } if (m_RunChanged) { m_RunChanged = false; QStringList RunCommands; for (int i = 0; i < ui.treeRun->topLevelItemCount(); i++) RunCommands.prepend(MakeRunEntry(ui.treeRun->topLevelItem(i))); //WriteTextList("RunCommand", RunCommands); theAPI->GetGlobalSettings()->DelValue("RunCommand"); foreach(const QString & Value, RunCommands) theAPI->GetGlobalSettings()->InsertText("RunCommand", Value); } if (m_GeneralChanged) { m_GeneralChanged = false; WriteText("DefaultBox", ui.cmbDefault->currentData().toString()); WriteText("FileRootPath", ui.fileRoot->text()); //ui.fileRoot->setText("\\??\\%SystemDrive%\\Sandbox\\%USER%\\%SANDBOX%"); //WriteAdvancedCheck(ui.chkSeparateUserFolders, "SeparateUserFolders", "", "n"); WriteText("KeyRootPath", ui.regRoot->text()); //ui.regRoot->setText("\\REGISTRY\\USER\\Sandbox_%USER%_%SANDBOX%"); WriteText("IpcRootPath", ui.ipcRoot->text()); //ui.ipcRoot->setText("\\Sandbox\\%USER%\\%SANDBOX%\\Session_%SESSION%"); WriteText("RamDiskSizeKb", ui.chkRamDisk->isChecked() ? ui.txtRamLimit->text() : ""); WriteText("RamDiskLetter", ui.chkRamLetter->isChecked() ? ui.cmbRamLetter->currentText() : ""); WriteAdvancedCheck(ui.chkWFP, "NetworkEnableWFP", "y", ""); WriteAdvancedCheck(ui.chkObjCb, "EnableObjectFiltering", "", "n"); WriteAdvancedCheck(ui.chkWin32k, "EnableWin32kHooks", "", "n"); WriteAdvancedCheck(ui.chkSbieLogon, "SandboxieLogon", "y", ""); if (m_FeaturesChanged) { m_FeaturesChanged = false; theAPI->ReloadConfig(true); } } if (m_ProtectionChanged) { m_ProtectionChanged = false; WriteAdvancedCheck(ui.chkAdminOnly, "EditAdminOnly", "y", ""); bool isPassSet = !theAPI->GetGlobalSettings()->GetText("EditPassword", "").isEmpty(); if (ui.chkPassRequired->isChecked()) { if (!isPassSet && m_NewPassword.isEmpty()) OnSetPassword(); // request password entry if it wasn't entered already if (!m_NewPassword.isEmpty()) { theAPI->LockConfig(m_NewPassword); // set new/changed password m_NewPassword.clear(); } } else if (isPassSet) theAPI->LockConfig(QString()); // clear password WriteAdvancedCheck(ui.chkAdminOnlyFP, "ForceDisableAdminOnly", "y", ""); WriteAdvancedCheck(ui.chkClearPass, "ForgetPassword", "y", ""); } if (m_WarnProgsChanged) { m_WarnProgsChanged = false; WriteAdvancedCheck(ui.chkStartBlock, "StartRunAlertDenied", "y", ""); WriteAdvancedCheck(ui.chkStartBlockMsg, "AlertStartRunAccessDenied", "", "n"); WriteAdvancedCheck(ui.chkNotForcedMsg, "NotifyForceProcessDisabled", "y", ""); QStringList AlertProcess; QStringList AlertFolder; for (int i = 0; i < ui.treeWarnProgs->topLevelItemCount(); i++) { QTreeWidgetItem* pItem = ui.treeWarnProgs->topLevelItem(i); int Type = pItem->data(0, Qt::UserRole).toInt(); switch (Type) { case 1: AlertProcess.append(pItem->data(1, Qt::UserRole).toString()); break; case 2: AlertFolder.append(pItem->data(1, Qt::UserRole).toString()); break; } } WriteTextList("AlertProcess", AlertProcess); WriteTextList("AlertFolder", AlertFolder); } if (m_VolumeChanged) { m_VolumeChanged = false; WriteAdvancedCheck(ui.chkSandboxUsb, "ForceUsbDrives", "y", ""); QString UsbSandbox = ui.cmbUsbSandbox->currentText().replace(" ", "_"); SB_STATUS Status = theAPI->ValidateName(UsbSandbox); if (Status.IsError()) QMessageBox::warning(this, "Sandboxie-Plus", theGUI->FormatError(Status)); else WriteText("UsbSandbox", UsbSandbox); QStringList DisabledForceVolume; for (int i = 0; i < ui.treeVolumes->topLevelItemCount(); i++) { QTreeWidgetItem* pItem = ui.treeVolumes->topLevelItem(i); if (pItem->checkState(0) == Qt::Unchecked) { DisabledForceVolume.append(pItem->text(0)); } } WriteTextList("DisabledForceVolume", DisabledForceVolume); theGUI->UpdateForceUSB(); } if (m_CompatChanged) { m_CompatChanged = false; QStringList Used; QStringList Rejected; for (int i = 0; i < ui.treeCompat->topLevelItemCount(); i++) { QTreeWidgetItem* pItem = ui.treeCompat->topLevelItem(i); QString Template = pItem->data(0, Qt::UserRole).toString().mid(9); if (pItem->checkState(0) == Qt::Unchecked) Rejected.append(Template); else Used.append(Template); } // retain local templates foreach(const QString& Template, theAPI->GetGlobalSettings()->GetTextList("Template", false)) { if (Template.left(6) == "Local_") { Used.append(Template); } } WriteTextList("Template", Used); WriteTextList("TemplateReject", Rejected); } } catch (SB_STATUS Status) { theGUI->CheckResults(QList() << Status, theGUI); } } if (ui.chkAutoRoot->isVisible()) theConf->SetValue("Options/PortableRootDir", CSettingsWindow__Chk2Int(ui.chkAutoRoot->checkState())); theConf->SetValue("Options/AutoRunSoftCompat", !ui.chkNoCompat->isChecked()); if(m_CertChanged) ApplyCert(); theConf->SetValue("Options/NoSupportCheck", ui.chkNoCheck->isChecked()); theConf->SetValue("Options/CheckForUpdates", CSettingsWindow__Chk2Int(ui.chkAutoUpdate->checkState())); int UpdateInterval = ui.cmbInterval->currentData().toInt(); if (!UpdateInterval) UpdateInterval = ui.cmbInterval->currentText().toInt(); if (!UpdateInterval) UpdateInterval = UPDATE_INTERVAL; theConf->SetValue("Options/UpdateInterval", UpdateInterval); QString ReleaseChannel; if (ui.radStable->isChecked()) ReleaseChannel = "stable"; else if (ui.radPreview->isChecked()) ReleaseChannel = "preview"; else if (ui.radInsider->isChecked()) ReleaseChannel = "insider"; if(!ReleaseChannel.isEmpty()) theConf->SetValue("Options/ReleaseChannel", ReleaseChannel); theConf->SetValue("Options/OnNewUpdate", ui.cmbUpdate->currentData()); theConf->SetValue("Options/OnNewRelease", ui.cmbRelease->currentData()); //theConf->SetValue("Options/CheckForTemplates", CSettingsWindow__Chk2Int(ui.chkUpdateTemplates->checkState())); theConf->SetValue("Options/CheckForAddons", CSettingsWindow__Chk2Int(ui.chkUpdateAddons->checkState())); theConf->SetValue("Options/CheckForIssues", CSettingsWindow__Chk2Int(ui.chkUpdateIssues->checkState())); emit OptionsChanged(m_bRebuildUI); } bool CSettingsWindow::ApplyCertificate(const QByteArray &Certificate, QWidget* widget) { QString CertPath = theAPI->GetSbiePath() + "\\Certificate.dat"; if (!Certificate.isEmpty()) { auto Args = GetArguments(Certificate, L'\n', L':'); bool bLooksOk = true; if (Args.value("NAME").isEmpty()) // mandatory bLooksOk = false; //if (Args.value("UPDATEKEY").isEmpty()) // bLooksOk = false; if (Args.value("SIGNATURE").isEmpty()) // absolutely mandatory bLooksOk = false; if (bLooksOk) { QString TempPath = QDir::tempPath() + "/Sbie+Certificate.dat"; QFile CertFile(TempPath); if (CertFile.open(QFile::WriteOnly)) { CertFile.write(Certificate); CertFile.close(); } WindowsMoveFile(TempPath.replace("/", "\\"), CertPath.replace("/", "\\")); } else { QMessageBox::critical(widget, "Sandboxie-Plus", tr("This does not look like a certificate. Please enter the entire certificate, not just a portion of it.")); return false; } } else if(!g_Certificate.isEmpty()){ g_Certificate.clear(); WindowsMoveFile(CertPath.replace("/", "\\"), ""); } if (Certificate.isEmpty()) return false; if (!theGUI->ReloadCert(widget).IsError()) { g_FeatureFlags = theAPI->GetFeatureFlags(); g_Certificate = Certificate; theGUI->UpdateCertState(); if (g_CertInfo.expired || g_CertInfo.outdated) { if(g_CertInfo.outdated) QMessageBox::information(widget, "Sandboxie-Plus", tr("This certificate is unfortunately not valid for the current build, you need to get a new certificate or downgrade to an earlier build.")); else if(g_CertInfo.active && !g_CertInfo.grace_period) QMessageBox::information(widget, "Sandboxie-Plus", tr("Although this certificate has expired, for the currently installed version plus features remain enabled. However, you will no longer have access to Sandboxie-Live services, including compatibility updates and the online troubleshooting database.")); else QMessageBox::information(widget, "Sandboxie-Plus", tr("This certificate has unfortunately expired, you need to get a new certificate.")); } else { QMessageBox::information(widget, "Sandboxie-Plus", tr("Thank you for supporting the development of Sandboxie-Plus.")); } return true; } else { g_CertInfo.State = 0; g_Certificate.clear(); return false; } } void CSettingsWindow::apply() { if (!ui.btnEditIni->isEnabled()) SaveIniSection(); else SaveSettings(); LoadSettings(); } void CSettingsWindow::ok() { apply(); this->close(); } void CSettingsWindow::reject() { this->close(); } void CSettingsWindow::OnOptChanged() { QStandardItemModel *model = qobject_cast(ui.cmbOnClose->model()); QStandardItem *item = model->item(0); item->setFlags((ui.cmbSysTray->currentIndex() == 0) ? item->flags() & ~Qt::ItemIsEnabled : item->flags() | Qt::ItemIsEnabled); if (m_HoldChange) return; ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true); } void CSettingsWindow::OnLoadAddon() { ui.treeAddons->clear(); foreach(const CAddonInfoPtr pAddon, theGUI->GetAddonManager()->GetAddons()) { QTreeWidgetItem* pItem = new QTreeWidgetItem; pItem->setText(0, pAddon->GetLocalizedEntry("name")); if(!pAddon->Data["mandatory"].toBool()) pItem->setData(0, Qt::UserRole, pAddon->Id); pItem->setIcon(0, pAddon->Data.contains("icon") ? CSandMan::GetIcon(pAddon->Data["icon"].toString()) : CSandMan::GetIcon("Addon")); if (pAddon->Installed) { if(!pAddon->UpdateVersion.isEmpty()) pItem->setText(1, tr("Update Available")); else pItem->setText(1, tr("Installed")); } pItem->setText(2, pAddon->Data["version"].toString()); QString Maker = pAddon->Data["maintainer"].toString(); if(!Maker.isEmpty()) pItem->setToolTip(2, tr("by %1").arg(Maker)); //pItem->setText(3, ); ui.treeAddons->addTopLevelItem(pItem); QString Info = pAddon->GetLocalizedEntry("description"); QString infoUrl = pAddon->Data["infoUrl"].toString(); if (!infoUrl.isEmpty()) Info += " " + tr("(info website)") + ""; QLabel* pLabel = new QLabel(Info); //pLabel->setToolTip(tr("by %1").arg(pAddon->Data["maintainer"].toString())); connect(pLabel, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&))); ui.treeAddons->setItemWidget(pItem, 3, pLabel); } } void CSettingsWindow::OnInstallAddon() { QTreeWidgetItem* pItem = ui.treeAddons->currentItem(); if (!pItem) return; QString Id = pItem->data(0, Qt::UserRole).toString(); SB_PROGRESS Status = theGUI->GetAddonManager()->TryInstallAddon(Id, this); if (Status.GetStatus() == OP_ASYNC) connect(Status.GetValue().data(), SIGNAL(Finished()), this, SLOT(OnLoadAddon())); } void CSettingsWindow::OnRemoveAddon() { QTreeWidgetItem* pItem = ui.treeAddons->currentItem(); if (!pItem) return; QString Id = pItem->data(0, Qt::UserRole).toString(); if (Id.isEmpty()) { QMessageBox::warning(this, "Sandboxie-Plus", tr("This Add-on is mandatory and can not be removed.")); return; } SB_PROGRESS Status = theGUI->GetAddonManager()->TryRemoveAddon(Id, this); if (Status.GetStatus() == OP_ASYNC) connect(Status.GetValue().data(), SIGNAL(Finished()), this, SLOT(OnLoadAddon())); } void CSettingsWindow::OnBrowse() { QString Value = QFileDialog::getExistingDirectory(this, tr("Select Directory")).replace("/", "\\"); if (Value.isEmpty()) return; ui.fileRoot->setText(Value + "\\%SANDBOX%"); } void CSettingsWindow::OnRootChanged() { if (ui.chkAutoRoot->isVisible()) ui.fileRoot->setEnabled(ui.chkAutoRoot->checkState() != Qt::Checked); OnOptChanged(); } void CSettingsWindow::OnTab() { OnTab(ui.tabs->currentWidget()); } void CSettingsWindow::OnTab(QWidget* pTab) { m_pCurrentTab = pTab; if (pTab == ui.tabSupport) { if (ui.lblCurrent->text().isEmpty()) { if (ui.chkAutoUpdate->checkState()) GetUpdates(); else ui.lblCurrent->setText(tr("Check Now")); } } else if (pTab == ui.tabAddons) { if (theConf->GetInt("Options/CheckForAddons", 2) == 1) { ui.lblUpdateAddons->setVisible(false); theGUI->GetAddonManager()->UpdateAddonsWhenNotCached(); } } else if (pTab == ui.tabEdit) { LoadIniSection(); //ui.txtIniSection->setReadOnly(true); } else if (pTab == ui.tabCompat && m_CompatLoaded != 1 && theAPI->IsConnected()) { if(m_CompatLoaded == 0) theGUI->CheckCompat(this, "OnCompat"); } } void CSettingsWindow::OnCompat() { ui.treeCompat->clear(); bool bNew = false; QMap Templates = theGUI->GetCompat()->GetTemplates(); for (QMap::iterator I = Templates.begin(); I != Templates.end(); ++I) { if (I.value() == CSbieTemplates::eNone) continue; QSharedPointer pTemplate = QSharedPointer(new CSbieIni("Template_" + I.key(), theAPI)); QString Title = pTemplate->GetText("Tmpl.Title", "", false, true, true); if (Title.left(1) == "#") { int End = Title.mid(1).indexOf(","); if (End == -1) End = Title.length() - 1; int MsgNum = Title.mid(1, End).toInt(); Title = theAPI->GetSbieMsgStr(MsgNum, theGUI->m_LanguageId).arg(Title.mid(End + 2)).arg(""); } //if (Title.isEmpty()) Title = Name; QTreeWidgetItem* pItem = new QTreeWidgetItem(); pItem->setText(0, Title); pItem->setData(0, Qt::UserRole, "Template_" + I.key()); if((I.value() & CSbieTemplates::eDisabled) != 0) pItem->setCheckState(0, Qt::Unchecked); else if((I.value() & CSbieTemplates::eEnabled) != 0) pItem->setCheckState(0, Qt::Checked); else { pItem->setCheckState(0, Qt::PartiallyChecked); bNew = true; } ui.treeCompat->addTopLevelItem(pItem); } m_CompatLoaded = 1; if(bNew) OnCompatChanged(); LoadTemplates(); } void CSettingsWindow::OnProtectionChange() { ui.btnSetPassword->setEnabled(ui.chkPassRequired->isChecked()); m_ProtectionChanged = true; OnOptChanged(); } void CSettingsWindow::OnSetPassword() { retry: QString Value1 = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please enter the new configuration password."), QLineEdit::Password); if (Value1.isEmpty()) return; QString Value2 = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please re-enter the new configuration password."), QLineEdit::Password); if (Value2.isEmpty()) return; if (Value1 != Value2) { QMessageBox::warning(this, "Sandboxie-Plus", tr("Passwords did not match, please retry.")); goto retry; } m_NewPassword = Value1; m_ProtectionChanged = true; OnOptChanged(); } void CSettingsWindow::AddWarnEntry(const QString& Name, int type) { QTreeWidgetItem* pItem = new QTreeWidgetItem(); pItem->setText(0, (type == 1 ? tr("Process") : tr("Folder"))); pItem->setData(0, Qt::UserRole, type); pItem->setData(1, Qt::UserRole, Name); pItem->setText(1, Name); ui.treeWarnProgs->addTopLevelItem(pItem); } void CSettingsWindow::OnAddWarnProg() { QString Value = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please enter a program file name")); if (Value.isEmpty()) return; AddWarnEntry(Value, 1); OnWarnChanged(); } void CSettingsWindow::OnAddWarnFolder() { QString Value = QFileDialog::getExistingDirectory(this, tr("Select Directory")).replace("/", "\\"); if (Value.isEmpty()) return; AddWarnEntry(Value, 2); OnWarnChanged(); } void CSettingsWindow::OnDelWarnProg() { QTreeWidgetItem* pItem = ui.treeWarnProgs->currentItem(); if (!pItem) return; delete pItem; OnWarnChanged(); } void CSettingsWindow::OnTemplateClicked(QTreeWidgetItem* pItem, int Column) { if (sender() == ui.treeCompat) { // todo: check if really changed OnCompatChanged(); } } void CSettingsWindow::OnAddCompat() { QTreeWidgetItem* pItem = ui.treeCompat->currentItem(); if (!pItem) return; pItem->setCheckState(0, Qt::Checked); OnCompatChanged(); } void CSettingsWindow::OnDelCompat() { QTreeWidgetItem* pItem = ui.treeCompat->currentItem(); if (!pItem) return; pItem->setCheckState(0, Qt::Unchecked); OnCompatChanged(); } void CSettingsWindow::OnTemplateDoubleClicked(QTreeWidgetItem* pItem, int Column) { QSharedPointer pTemplate = QSharedPointer(new CSbieIni(pItem->data(0, Qt::UserRole).toString(), theAPI)); COptionsWindow OptionsWindow(pTemplate, pItem->text(0)); QPoint ParentPos = mapToGlobal(rect().topLeft()); OptionsWindow.move(ParentPos.x() + 30, ParentPos.y() + 10); OptionsWindow.exec(); // todo update name if it changed } void CSettingsWindow::OnAddTemplates() { QString Value = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please enter the template identifier"), QLineEdit::Normal); if (Value.isEmpty()) return; QString Name = QString(Value).replace(" ", "_"); SB_STATUS Status = theAPI->ValidateName(Name); if (Status.IsError()) { QMessageBox::critical(this, "Sandboxie-Plus", tr("Error: %1").arg(CSandMan::FormatError(Status))); return; } QSharedPointer pTemplate = QSharedPointer(new CSbieIni("Template_Local_" + Name, theAPI)); pTemplate->SetText("Tmpl.Title", Value); pTemplate->SetText("Tmpl.Class", "Local"); COptionsWindow OptionsWindow(pTemplate, Value); OptionsWindow.exec(); LoadTemplates(); } void CSettingsWindow::OnTemplateWizard() { CTemplateWizard::ETemplateType Type = (CTemplateWizard::ETemplateType)((QAction*)sender())->data().toInt(); if (CTemplateWizard::CreateNewTemplate(NULL, Type, this)) { LoadTemplates(); } } void CSettingsWindow::OnDelTemplates() { if (QMessageBox("Sandboxie-Plus", tr("Do you really want to delete the selected local template(s)?"), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton, this).exec() != QMessageBox::Yes) return; foreach(QTreeWidgetItem * pItem, ui.treeTemplates->selectedItems()) { QString Section = pItem->data(0, Qt::UserRole).toString(); delete pItem; // delete section theAPI->SbieIniSet(Section, "*", ""); } } void CSettingsWindow::LoadTemplates() { QStringList Templates; for (int index = 0; ; index++) { QString Value = theAPI->SbieIniGet2("", "", index); if (Value.isNull()) break; Templates.append(Value); } ui.treeTemplates->clear(); QString TextFilter = ui.txtTemplates->text(); foreach(const QString& Name, Templates) { if (Name.left(9).compare("Template_", Qt::CaseInsensitive) != 0) continue; if (Name.indexOf(TextFilter, 0, Qt::CaseInsensitive) == -1) continue; QString Title = theAPI->SbieIniGet2(Name, "Tmpl.Title"); if (Title.left(1) == "#") { int End = Title.mid(1).indexOf(","); if (End == -1) End = Title.length() - 1; int MsgNum = Title.mid(1, End).toInt(); Title = theAPI->GetSbieMsgStr(MsgNum, theGUI->m_LanguageId).arg(Title.mid(End + 2)).arg(""); } if (Title.isEmpty()) Title = Name; QTreeWidgetItem* pItem = new QTreeWidgetItem(); pItem->setData(0, Qt::UserRole, Name); pItem->setText(0, Title); ui.treeTemplates->addTopLevelItem(pItem); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Raw section ini Editor // void CSettingsWindow::SetIniEdit(bool bEnable) { if (m_pTree) { m_pTree->setEnabled(!bEnable); } else { for (int i = 4; 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); } } ui.btnSaveIni->setEnabled(bEnable); ui.btnCancelEdit->setEnabled(bEnable); //ui.txtIniSection->setReadOnly(!bEnable); ui.btnEditIni->setEnabled(!bEnable); } void CSettingsWindow::OnEditIni() { SetIniEdit(true); } void CSettingsWindow::OnSaveIni() { SaveIniSection(); SetIniEdit(false); LoadSettings(); } void CSettingsWindow::OnIniChanged() { if (m_HoldChange) return; if(ui.btnEditIni->isEnabled()) SetIniEdit(true); ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true); } void CSettingsWindow::OnCancelEdit() { SetIniEdit(false); LoadIniSection(); } void CSettingsWindow::LoadIniSection() { QString Section; if(theAPI->IsConnected()) Section = theAPI->SbieIniGetEx("GlobalSettings", ""); m_HoldChange = true; ui.txtIniSection->setPlainText(Section); m_HoldChange = false; } void CSettingsWindow::SaveIniSection() { if(theAPI->IsConnected()) theAPI->SbieIniSet("GlobalSettings", "", ui.txtIniSection->toPlainText()); LoadIniSection(); } QVariantMap GetRunEntry(const QString& sEntry) { QVariantMap Entry; if (sEntry.left(1) == "{") { Entry = QJsonDocument::fromJson(sEntry.toUtf8()).toVariant().toMap(); } else { StrPair NameCmd = Split2(sEntry, "|"); StrPair NameIcon = Split2(NameCmd.first, ","); Entry["Name"] = NameIcon.first; Entry["Icon"] = NameIcon.second; Entry["Command"] = NameCmd.second; } return Entry; } void AddRunItem(QTreeWidget* treeRun, const QVariantMap& Entry) { QTreeWidgetItem* pItem = new QTreeWidgetItem(); pItem->setText(0, Entry["Name"].toString()); pItem->setData(0, Qt::UserRole, Entry); pItem->setText(1, Entry["Command"].toString()); pItem->setFlags(pItem->flags() | Qt::ItemIsEditable); treeRun->addTopLevelItem(pItem); } QString MakeRunEntry(QTreeWidgetItem* pItem) { QVariantMap Entry = pItem->data(0, Qt::UserRole).toMap(); Entry["Name"] = pItem->text(0); Entry["Command"] = pItem->text(1); return MakeRunEntry(Entry); } QString MakeRunEntry(const QVariantMap& Entry) { if (!Entry["WorkingDir"].toString().isEmpty() || !Entry["Icon"].toString().isEmpty()) { QJsonDocument doc(QJsonValue::fromVariant(Entry).toObject()); QString sEntry = QString::fromUtf8(doc.toJson(QJsonDocument::Compact)); return sEntry; } //if(!Entry["Icon"].toString().isEmpty()) // return Entry["Name"].toString() + "," + Entry["Icon"].toString() + "|" + Entry["Command"].toString(); return Entry["Name"].toString() + "|" + Entry["Command"].toString(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Update // void CSettingsWindow::GetUpdates() { QVariantMap Params; Params["channel"] = "all"; theGUI->m_pUpdater->GetUpdates(this, SLOT(OnUpdateData(const QVariantMap&, const QVariantMap&)), Params); } QString CSettingsWindow__MkVersion(const QString& Name, const QVariantMap& Releases) { QVariantMap Release = Releases[Name].toMap(); QString Version = Release.value("version").toString(); //if (Release["build"].type() != QVariant::Invalid) int iUpdate = Release["update"].toInt(); if(iUpdate) Version += QChar('a' + (iUpdate - 1)); return QString("%2").arg(Name, Version); } void CSettingsWindow::OnUpdateData(const QVariantMap& Data, const QVariantMap& Params) { if (Data.isEmpty() || Data["error"].toBool()) return; QString Version = QString::number(VERSION_MJR) + "." + QString::number(VERSION_MIN) + "." + QString::number(VERSION_REV); int iUpdate = COnlineUpdater::GetCurrentUpdate(); if(iUpdate) Version += QChar('a' + (iUpdate - 1)); m_UpdateData = Data; QVariantMap Releases = m_UpdateData["releases"].toMap(); ui.lblCurrent->setText(tr("%1 (Current)").arg(Version)); ui.lblStable->setText(CSettingsWindow__MkVersion("stable", Releases)); ui.lblPreview->setText(CSettingsWindow__MkVersion("preview", Releases)); if(ui.radInsider->isEnabled()) ui.lblInsider->setText(CSettingsWindow__MkVersion("insider", Releases)); } void CSettingsWindow::OnUpdate(const QString& Channel) { if (Channel == "check") { GetUpdates(); return; } QVariantMap Releases = m_UpdateData["releases"].toMap(); QVariantMap Release = Releases[Channel].toMap(); QString VersionStr = Release["version"].toString(); if (VersionStr.isEmpty()) return; QVariantMap Installer = Releases["installer"].toMap(); QString DownloadUrl = Installer["downloadUrl"].toString(); //QString DownloadSig = Installer["signature"].toString(); // todo xxx //if (!DownloadUrl.isEmpty() /*&& !DownloadSig.isEmpty()*/) //{ // // todo: signature // if (QMessageBox("Sandboxie-Plus", tr("Do you want to download the installer for v%1?").arg(VersionStr), QMessageBox::Question, QMessageBox::Yes | QMessageBox::Default, QMessageBox::No | QMessageBox::Escape, QMessageBox::NoButton, this).exec() == QMessageBox::Yes) // COnlineUpdater::Instance()->DownloadInstaller(DownloadUrl, true); //} //else { QString InfoUrl = Release["infoUrl"].toString(); if (InfoUrl.isEmpty()) InfoUrl = "https://sandboxie-plus.com/go.php?to=sbie-get"; QDesktopServices::openUrl(InfoUrl); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Support // void CSettingsWindow::CertChanged() { m_CertChanged = true; QPalette palette = QApplication::palette(); ui.txtCertificate->setPalette(palette); OnOptChanged(); } void CSettingsWindow::LoadCertificate(QString CertPath) { if (theAPI && theAPI->IsConnected()) CertPath = theAPI->GetSbiePath() + "\\Certificate.dat"; QFile CertFile(CertPath); if (CertFile.open(QFile::ReadOnly)) { g_Certificate = CertFile.readAll(); CertFile.close(); } } void WindowsMoveFile(const QString& From, const QString& To) { std::wstring from = From.toStdWString(); from.append(L"\0", 1); std::wstring to = To.toStdWString(); to.append(L"\0", 1); SHFILEOPSTRUCT SHFileOp; memset(&SHFileOp, 0, sizeof(SHFILEOPSTRUCT)); SHFileOp.hwnd = NULL; SHFileOp.wFunc = To.isEmpty() ? FO_DELETE : FO_MOVE; SHFileOp.pFrom = from.c_str(); SHFileOp.pTo = to.c_str(); SHFileOp.fFlags = NULL; //The Copying Function SHFileOperation(&SHFileOp); }