From ce729a4ef6b4481170ba3d120f64c37e2e391e6c Mon Sep 17 00:00:00 2001 From: DavidXanatos Date: Fri, 16 Dec 2022 13:08:49 +0100 Subject: [PATCH] 1.6.1b --- CHANGELOG.md | 1 + SandboxiePlus/SandMan/Helpers/WinHelper.cpp | 24 ++++ SandboxiePlus/SandMan/Helpers/WinHelper.h | 5 + SandboxiePlus/SandMan/Models/SbieModel.cpp | 18 ++- SandboxiePlus/SandMan/Models/SbieModel.h | 2 +- SandboxiePlus/SandMan/SandMan.pri | 2 + SandboxiePlus/SandMan/SandMan.vcxproj | 2 + SandboxiePlus/SandMan/SandMan.vcxproj.filters | 6 + .../SandMan/Windows/OptionsGeneral.cpp | 119 +++++++++++++++++- SandboxiePlus/SandMan/Windows/OptionsWindow.h | 8 ++ 10 files changed, 178 insertions(+), 9 deletions(-) create mode 100644 SandboxiePlus/SandMan/Helpers/WinHelper.cpp create mode 100644 SandboxiePlus/SandMan/Helpers/WinHelper.h diff --git a/CHANGELOG.md b/CHANGELOG.md index a89a1cd5..fc8ed8d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Added - added game/presentation mode [#2534](https://github.com/sandboxie-plus/Sandboxie/issues/2534) +- added option to pick a custom box icon ### Fixed - fixed support settign page not showing version updates properly diff --git a/SandboxiePlus/SandMan/Helpers/WinHelper.cpp b/SandboxiePlus/SandMan/Helpers/WinHelper.cpp new file mode 100644 index 00000000..ecabef25 --- /dev/null +++ b/SandboxiePlus/SandMan/Helpers/WinHelper.cpp @@ -0,0 +1,24 @@ +#include "stdafx.h" +#include "WinHelper.h" + +#include +#include +#include + +QImage LoadWindowsIcon(const QString& Path, quint32 Index) +{ + std::wstring path = QString(Path).replace("/", "\\").toStdWString(); + HICON icon = ExtractIconW(NULL, path.c_str(), Index); + QImage Icon = QImage::fromHICON(icon); + DestroyIcon(icon); + return Icon; +} + +bool PickWindowsIcon(QWidget* pParent, QString& Path, quint32& Index) +{ + wchar_t iconPath[MAX_PATH] = { 0 }; + Path.toWCharArray(iconPath); + BOOL Ret = PickIconDlg((HWND)pParent->window()->winId(), iconPath, MAX_PATH, (int*)&Index); + Path = QString::fromWCharArray(iconPath); + return !!Ret; +} \ No newline at end of file diff --git a/SandboxiePlus/SandMan/Helpers/WinHelper.h b/SandboxiePlus/SandMan/Helpers/WinHelper.h new file mode 100644 index 00000000..adf04552 --- /dev/null +++ b/SandboxiePlus/SandMan/Helpers/WinHelper.h @@ -0,0 +1,5 @@ +#pragma once + +QImage LoadWindowsIcon(const QString& Path, quint32 Index); + +bool PickWindowsIcon(QWidget* pParent, QString& Path, quint32& Index); \ No newline at end of file diff --git a/SandboxiePlus/SandMan/Models/SbieModel.cpp b/SandboxiePlus/SandMan/Models/SbieModel.cpp index 3b1e860a..ea59f315 100644 --- a/SandboxiePlus/SandMan/Models/SbieModel.cpp +++ b/SandboxiePlus/SandMan/Models/SbieModel.cpp @@ -2,6 +2,7 @@ #include "SbieModel.h" #include "../../MiscHelpers/Common/Common.h" #include "../SandMan.h" +#include "../Helpers/WinHelper.h" CSbieModel::CSbieModel(QObject *parent) : CTreeItemModel(parent) @@ -223,12 +224,17 @@ QList CSbieModel::Sync(const QMap& BoxList, cons int boxColor = pBoxEx->GetColor(); QIcon Icon; - QString Action = pBox->GetText("DblClickAction"); - if (!Action.isEmpty() && Action.left(1) != "!") + QString BoxIcon = pBox->GetText("BoxIcon"); + if (!BoxIcon.isEmpty()) { - if (pNode->Action != Action || (pNode->busyState || Busy) || pNode->boxDel != boxDel) { - Icon = m_IconProvider.icon(QFileInfo(pBoxEx->GetCommandFile(Action))); - pNode->Action = Action; + if (pNode->BoxIcon != BoxIcon || (pNode->busyState || Busy) || pNode->boxDel != boxDel) + { + StrPair PathIndex = Split2(BoxIcon, ","); + if (!PathIndex.second.isEmpty() && !PathIndex.second.contains(".")) + Icon = QIcon(QPixmap::fromImage(LoadWindowsIcon(PathIndex.first, PathIndex.second.toInt()))); + else + Icon = QIcon(QPixmap(BoxIcon)); + pNode->BoxIcon = BoxIcon; } } else if (pNode->inUse != inUse || pNode->bOpen != bOpen || (pNode->busyState || Busy) || pNode->boxType != boxType || pNode->boxColor != boxColor || pNode->boxDel != boxDel) @@ -243,7 +249,7 @@ QList CSbieModel::Sync(const QMap& BoxList, cons Icon = theGUI->GetColorIcon(boxColor, inUse); else Icon = theGUI->GetBoxIcon(boxType, inUse); - pNode->Action.clear(); + pNode->BoxIcon.clear(); } if (!Icon.isNull()) diff --git a/SandboxiePlus/SandMan/Models/SbieModel.h b/SandboxiePlus/SandMan/Models/SbieModel.h index 9b426328..401cef08 100644 --- a/SandboxiePlus/SandMan/Models/SbieModel.h +++ b/SandboxiePlus/SandMan/Models/SbieModel.h @@ -77,7 +77,7 @@ protected: bool boxDel; int boxColor; int OrderNumber; - QString Action; + QString BoxIcon; CBoxedProcessPtr pProcess; }; diff --git a/SandboxiePlus/SandMan/SandMan.pri b/SandboxiePlus/SandMan/SandMan.pri index 014a7e8a..e63129d4 100644 --- a/SandboxiePlus/SandMan/SandMan.pri +++ b/SandboxiePlus/SandMan/SandMan.pri @@ -19,6 +19,7 @@ HEADERS += ./stdafx.h \ ./Helpers/FindTool.h \ ./Helpers/FullScreen.h \ ./Helpers/WinAdmin.h \ + ./Helpers/WinHelper.h \ ./Helpers/ReadDirectoryChanges.h \ ./Helpers/ReadDirectoryChangesPrivate.h \ ./Windows/NewBoxWindow.h \ @@ -49,6 +50,7 @@ SOURCES += ./main.cpp \ ./Helpers/FindTool.cpp \ ./Helpers/FullScreen.cpp \ ./Helpers/WinAdmin.cpp \ + ./Helpers/WinHelper.cpp \ ./Helpers/ReadDirectoryChanges.cpp \ ./Helpers/ReadDirectoryChangesPrivate.cpp \ ./Helpers/WindowFromPointEx.cpp \ diff --git a/SandboxiePlus/SandMan/SandMan.vcxproj b/SandboxiePlus/SandMan/SandMan.vcxproj index 04b57e9c..73c429fa 100644 --- a/SandboxiePlus/SandMan/SandMan.vcxproj +++ b/SandboxiePlus/SandMan/SandMan.vcxproj @@ -212,6 +212,7 @@ + @@ -345,6 +346,7 @@ + diff --git a/SandboxiePlus/SandMan/SandMan.vcxproj.filters b/SandboxiePlus/SandMan/SandMan.vcxproj.filters index fb3e4f5f..22d5d4b0 100644 --- a/SandboxiePlus/SandMan/SandMan.vcxproj.filters +++ b/SandboxiePlus/SandMan/SandMan.vcxproj.filters @@ -180,6 +180,9 @@ Helpers + + Helpers + @@ -209,6 +212,9 @@ Helpers + + Helpers + diff --git a/SandboxiePlus/SandMan/Windows/OptionsGeneral.cpp b/SandboxiePlus/SandMan/Windows/OptionsGeneral.cpp index e626375c..71e5f9f7 100644 --- a/SandboxiePlus/SandMan/Windows/OptionsGeneral.cpp +++ b/SandboxiePlus/SandMan/Windows/OptionsGeneral.cpp @@ -7,6 +7,7 @@ #include "../MiscHelpers/Common/ComboInputDialog.h" #include "../MiscHelpers/Common/SettingsWidgets.h" #include "Helpers/WinAdmin.h" +#include "Helpers/WinHelper.h" class CCertBadge: public QLabel { @@ -98,12 +99,27 @@ void COptionsWindow::CreateGeneral() ui.btnBorderColor->setPopupMode(QToolButton::MenuButtonPopup); QMenu* pColorMenu = new QMenu(this); + + QWidgetAction* pActionWidget = new QWidgetAction(this); + QWidget* pIconWidget = new QWidget(this); + QHBoxLayout* pIconLayout = new QHBoxLayout(pIconWidget); + pIconLayout->setContentsMargins(0, 0, 0, 0); + m_pUseIcon = new QCheckBox(tr("Custom icon")); + connect(m_pUseIcon, SIGNAL(clicked(bool)), this, SLOT(OnUseIcon(bool))); + pIconLayout->addWidget(m_pUseIcon); + m_pPickIcon = new QToolButton(this); + m_pPickIcon->setText("..."); + connect(m_pPickIcon, SIGNAL(clicked(bool)), this, SLOT(OnPickIcon())); + pIconLayout->addWidget(m_pPickIcon); + pActionWidget->setDefaultWidget(pIconWidget); + pColorMenu->addAction(pActionWidget); + pColorMenu->addSeparator(); m_pColorSlider = new QSlider(Qt::Horizontal, this); m_pColorSlider->setMinimum(0); m_pColorSlider->setMaximum(359); m_pColorSlider->setMinimumHeight(16); connect(m_pColorSlider, SIGNAL(valueChanged(int)), this, SLOT(OnColorSlider(int))); - QWidgetAction* pActionWidget = new QWidgetAction(this); + pActionWidget = new QWidgetAction(this); pActionWidget->setDefaultWidget(m_pColorSlider); pColorMenu->addAction(pActionWidget); ui.btnBorderColor->setMenu(pColorMenu); @@ -115,7 +131,7 @@ void COptionsWindow::CreateGeneral() connect(ui.chkShowForRun, SIGNAL(clicked(bool)), this, SLOT(OnGeneralChanged())); connect(ui.chkPinToTray, SIGNAL(clicked(bool)), this, SLOT(OnGeneralChanged())); - connect(ui.cmbDblClick, SIGNAL(currentIndexChanged(int)), this, SLOT(OnGeneralChanged())); + connect(ui.cmbDblClick, SIGNAL(currentIndexChanged(int)), this, SLOT(OnActionChanged())); connect(ui.chkBlockNetShare, SIGNAL(clicked(bool)), this, SLOT(OnGeneralChanged())); connect(ui.chkBlockNetParam, SIGNAL(clicked(bool)), this, SLOT(OnGeneralChanged())); @@ -174,6 +190,18 @@ void COptionsWindow::LoadGeneral() if (!BorderWidth) BorderWidth = 6; ui.spinBorderWidth->setValue(BorderWidth); + m_BoxIcon = m_pBox->GetText("BoxIcon"); + m_pUseIcon->setChecked(!m_BoxIcon.isEmpty()); + m_pPickIcon->setEnabled(!m_BoxIcon.isEmpty()); + StrPair PathIndex = Split2(m_BoxIcon, ","); + if (!PathIndex.second.isEmpty() && !PathIndex.second.contains(".")) + ui.btnBorderColor->setIcon(QPixmap::fromImage(LoadWindowsIcon(PathIndex.first, PathIndex.second.toInt()))); + else if (!m_BoxIcon.isEmpty()) + ui.btnBorderColor->setIcon(QPixmap(m_BoxIcon)); + else + ui.btnBorderColor->setIcon(QIcon()); + + ui.chkShowForRun->setChecked(m_pBox->GetBool("ShowForRunIn", true)); ui.chkPinToTray->setChecked(m_pBox->GetBool("PinToTray", false)); @@ -255,6 +283,12 @@ void COptionsWindow::SaveGeneral() BorderCfg.append(QString::number(ui.spinBorderWidth->value())); WriteText("BorderColor", BorderCfg.join(",")); + if(m_pUseIcon->isChecked()) + WriteText("BoxIcon", m_BoxIcon); + else + m_pBox->DelValue("BoxIcon"); + + WriteAdvancedCheck(ui.chkShowForRun, "ShowForRunIn", "", "n"); WriteAdvancedCheck(ui.chkPinToTray, "PinToTray", "y", ""); @@ -370,6 +404,53 @@ void COptionsWindow::OnSecurityMode() OnAccessChanged(); // for rule specificity } +void COptionsWindow::OnUseIcon(bool bUse) +{ + if (bUse) { + if (m_BoxIcon.isEmpty()) { + QString ActionFile = GetActionFile(); + if (!ActionFile.isEmpty()) { + ui.btnBorderColor->setIcon(QPixmap::fromImage(LoadWindowsIcon(ActionFile, 0))); + m_BoxIcon = QString("%1,0").arg(ActionFile); + } + } + if (m_BoxIcon.isEmpty()) { + if (!OnPickIcon()) + m_pUseIcon->setChecked(false); + } + } + else + ui.btnBorderColor->setIcon(QPixmap()); + + m_pPickIcon->setEnabled(m_pUseIcon->isChecked()); + + m_GeneralChanged = true; + OnOptChanged(); +} + +bool COptionsWindow::OnPickIcon() +{ + QString Path; + quint32 Index = 0; + + StrPair PathIndex = Split2(m_BoxIcon, ","); + if (!PathIndex.second.isEmpty() && !PathIndex.second.contains(".")) { + Path = PathIndex.first; + Index = PathIndex.second.toInt(); + } + + if (!PickWindowsIcon(this, Path, Index)) + return false; + + ui.btnBorderColor->setIcon(QPixmap::fromImage(LoadWindowsIcon(Path, Index))); + m_BoxIcon = QString("%1,%2").arg(Path).arg(Index); + + m_GeneralChanged = true; + OnOptChanged(); + + return true; +} + void COptionsWindow::OnPickColor() { QColor color = QColorDialog::getColor(m_BorderColor, this, tr("Select color")); @@ -409,6 +490,40 @@ void COptionsWindow::UpdateBoxColor() ui.btnBorderColor->setStyleSheet("background-color: " + m_BorderColor.name()); } +QString COptionsWindow::GetActionFile() +{ + QString Action = ui.cmbDblClick->currentData().toString(); + if (Action.isEmpty()) Action = ui.cmbDblClick->currentText(); + if (!Action.isEmpty() && Action.left(1) != "!") { + CSandBoxPlus* pBoxEx = qobject_cast(m_pBox.data()); + if (pBoxEx) { + QString Path = pBoxEx->GetCommandFile(Action); + ui.btnBorderColor->setIcon(QPixmap::fromImage(LoadWindowsIcon(Path, 0))); + return Path; + } + } + return QString(); +} + +void COptionsWindow::OnActionChanged() +{ + if (m_HoldChange) + return; + + QString ActionFile = GetActionFile(); + if (!ActionFile.isEmpty()) { + ui.btnBorderColor->setIcon(QPixmap::fromImage(LoadWindowsIcon(ActionFile, 0))); + m_BoxIcon = QString("%1,0").arg(ActionFile); + } + else { + ui.btnBorderColor->setIcon(QPixmap()); + m_BoxIcon.clear(); + } + + m_GeneralChanged = true; + OnOptChanged(); +} + void COptionsWindow::OnBrowsePath() { QString Value = QFileDialog::getOpenFileName(this, tr("Select Program"), "", tr("Executables (*.exe *.cmd)")).replace("/", "\\"); diff --git a/SandboxiePlus/SandMan/Windows/OptionsWindow.h b/SandboxiePlus/SandMan/Windows/OptionsWindow.h index a4b21acb..e0ff0bf4 100644 --- a/SandboxiePlus/SandMan/Windows/OptionsWindow.h +++ b/SandboxiePlus/SandMan/Windows/OptionsWindow.h @@ -46,6 +46,8 @@ private slots: void OnOptChanged(); + void OnUseIcon(bool bUse); + bool OnPickIcon(); void OnPickColor(); void OnColorSlider(int value); @@ -193,6 +195,7 @@ private slots: void OnGeneralChanged(); void OnPSTChanged(); + void OnActionChanged(); void OnSecurityMode(); void OnStartChanged() { m_StartChanged = true; OnOptChanged(); } //void OnRestrictionChanged() { m_RestrictionChanged = true; OnOptChanged(); } @@ -301,6 +304,8 @@ protected: void SetBoxColor(const QColor& color); void UpdateBoxColor(); + QString GetActionFile(); + void SetProgramItem(QString Program, QTreeWidgetItem* pItem, int Column, const QString& Sufix = QString()); QString SelectProgram(bool bOrGroup = true); @@ -451,6 +456,7 @@ protected: bool m_ConfigDirty; QColor m_BorderColor; + QString m_BoxIcon; bool m_HoldBoxType; @@ -510,6 +516,8 @@ private: void WriteTextList(const QString& Setting, const QStringList& List); Ui::OptionsWindow ui; + QCheckBox* m_pUseIcon; + QToolButton* m_pPickIcon; QSlider* m_pColorSlider; struct SDbgOpt {