diff --git a/SandboxiePlus/MiscHelpers/Common/ComboInputDialog.cpp b/SandboxiePlus/MiscHelpers/Common/ComboInputDialog.cpp index 8ee9706e..47c459d0 100644 --- a/SandboxiePlus/MiscHelpers/Common/ComboInputDialog.cpp +++ b/SandboxiePlus/MiscHelpers/Common/ComboInputDialog.cpp @@ -37,6 +37,9 @@ public: combo = new QComboBox(q); + infoLabel = new QLabel(q); + infoLabel->setVisible(false); + infoLabel->setWordWrap(true); buttonBox = new QDialogButtonBox(q); buttonBox->setOrientation(Qt::Horizontal); @@ -53,15 +56,18 @@ public: QVBoxLayout *verticalLayout_2 = new QVBoxLayout(q); verticalLayout_2->addLayout(horizontalLayout_2); verticalLayout_2->addWidget(combo); + verticalLayout_2->addWidget(infoLabel); verticalLayout_2->addItem(buttonSpacer); verticalLayout_2->addWidget(buttonBox); } QLabel *pixmapLabel; QLabel *messageLabel; + QLabel *infoLabel; QComboBox* combo; QDialogButtonBox *buttonBox; QAbstractButton *clickedButton; + QMap infos; }; CComboInputDialog::CComboInputDialog(QWidget *parent) : @@ -71,6 +77,7 @@ CComboInputDialog::CComboInputDialog(QWidget *parent) : setModal(true); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); d->combo->setFocus(); + connect(d->combo, SIGNAL(currentIndexChanged(int)), SLOT(onCmbIndex(int))); connect(d->buttonBox, SIGNAL(accepted()), SLOT(accept())); connect(d->buttonBox, SIGNAL(rejected()), SLOT(reject())); connect(d->buttonBox, SIGNAL(clicked(QAbstractButton*)), @@ -82,6 +89,14 @@ CComboInputDialog::~CComboInputDialog() delete d; } +void CComboInputDialog::onCmbIndex(int index) +{ + QString info = d->infos[index]; + if (!info.isEmpty()) + d->infoLabel->setVisible(true); + d->infoLabel->setText(info); +} + void CComboInputDialog::slotClicked(QAbstractButton *b) { d->clickedButton = b; @@ -109,9 +124,11 @@ void CComboInputDialog::setText(const QString &t) d->messageLabel->setText(t); } -void CComboInputDialog::addItem(const QString& t, const QVariant & v) +void CComboInputDialog::addItem(const QString& t, const QVariant & v, const QString& info) { d->combo->addItem(t, v); + if (!info.isEmpty()) + d->infos[d->combo->count() - 1] = info; } void CComboInputDialog::setEditable(bool b) diff --git a/SandboxiePlus/MiscHelpers/Common/ComboInputDialog.h b/SandboxiePlus/MiscHelpers/Common/ComboInputDialog.h index b2667c20..014a5b5b 100644 --- a/SandboxiePlus/MiscHelpers/Common/ComboInputDialog.h +++ b/SandboxiePlus/MiscHelpers/Common/ComboInputDialog.h @@ -23,7 +23,7 @@ public: QString text() const; void setText(const QString &); - void addItem(const QString&, const QVariant & = QVariant()); + void addItem(const QString&, const QVariant & = QVariant(), const QString& info = QString()); void setEditable(bool); QString value() const; @@ -52,6 +52,7 @@ public: private slots: void slotClicked(QAbstractButton *b); + void onCmbIndex(int index); private: CComboInputDialogPrivate *d; diff --git a/SandboxiePlus/MiscHelpers/Common/Common.cpp b/SandboxiePlus/MiscHelpers/Common/Common.cpp index 13298e38..9f9c54f3 100644 --- a/SandboxiePlus/MiscHelpers/Common/Common.cpp +++ b/SandboxiePlus/MiscHelpers/Common/Common.cpp @@ -96,7 +96,7 @@ quint64 GetRand64() { quint64 Rand64; #ifdef USE_OPENSSL - int Ret = RAND_bytes((byte*)&Rand64, sizeof(uint64)); + int Ret = RAND_bytes((byte*)&Rand64, sizeof(quint64)); ASSERT(Ret == 1); // An error occurs if the PRNG has not been seeded with enough randomness to ensure an unpredictable byte sequence. #else //CryptoPP::AutoSeededRandomPool rng; @@ -431,6 +431,15 @@ QAction* MakeAction(QActionGroup* pGroup, QMenu* pParent, const QString& Text, c return pAction; } +void SetPaleteTexture(QPalette& palette, QPalette::ColorRole role, const QImage& image) +{ + for (int i = 0; i < QPalette::NColorGroups; ++i) { + QBrush brush(image); + brush.setColor(palette.brush(QPalette::ColorGroup(i), role).color()); + palette.setBrush(QPalette::ColorGroup(i), role, brush); + } +} + ////////////////////////////////////////////////////////////////////////////////////////// // // diff --git a/SandboxiePlus/MiscHelpers/Common/Common.h b/SandboxiePlus/MiscHelpers/Common/Common.h index 21bc904a..bb05bafc 100644 --- a/SandboxiePlus/MiscHelpers/Common/Common.h +++ b/SandboxiePlus/MiscHelpers/Common/Common.h @@ -93,7 +93,7 @@ MISCHELPERS_EXPORT QAction* MakeAction(QToolBar* pParent, const QString& IconFil MISCHELPERS_EXPORT QMenu* MakeMenu(QMenu* pParent, const QString& Text, const QString& IconFile = ""); MISCHELPERS_EXPORT QAction* MakeAction(QMenu* pParent, const QString& Text, const QString& IconFile = ""); MISCHELPERS_EXPORT QAction* MakeAction(QActionGroup* pGroup, QMenu* pParent, const QString& Text, const QVariant& Data); - +MISCHELPERS_EXPORT void SetPaleteTexture(QPalette& palette, QPalette::ColorRole role, const QImage& image); #ifdef WIN32 MISCHELPERS_EXPORT bool InitConsole(bool bCreateIfNeeded = true); diff --git a/SandboxiePlus/MiscHelpers/Common/OtherFunctions.cpp b/SandboxiePlus/MiscHelpers/Common/OtherFunctions.cpp index 22aa4e3c..17bf7c0b 100644 --- a/SandboxiePlus/MiscHelpers/Common/OtherFunctions.cpp +++ b/SandboxiePlus/MiscHelpers/Common/OtherFunctions.cpp @@ -109,23 +109,26 @@ bool CopyDir(const QString& srcDirPath, const QString& destDirPath, bool bMove) return true; } -QStringList ListDir(const QString& srcDirPath) +QStringList ListDir(const QString& srcDirPath, const QStringList& NameFilter, bool bAndSubDirs) { QStringList FileList; QDir srcDir(srcDirPath); if (!srcDir.exists()) return FileList; - QStringList Files = srcDir.entryList(QDir::Files); + QStringList Files = !NameFilter.isEmpty() ? srcDir.entryList(NameFilter, QDir::Files | QDir::System) : srcDir.entryList(QDir::Files | QDir::System); foreach (const QString& FileName, Files) FileList.append(FileName); - QStringList Dirs = srcDir.entryList(QDir::Dirs); + if(!bAndSubDirs) + return FileList; + + QStringList Dirs = srcDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); foreach (const QString& DirName, Dirs) { - if (DirName.compare(".") == 0 || DirName.compare("..") == 0) - continue; - QStringList SubFiles = ListDir(srcDirPath + DirName + "/"); + //if (DirName.compare(".") == 0 || DirName.compare("..") == 0) + // continue; + QStringList SubFiles = ListDir(srcDirPath + "/" + DirName, NameFilter); foreach (const QString& FileName, SubFiles) FileList.append(DirName + "/" + FileName); diff --git a/SandboxiePlus/MiscHelpers/Common/OtherFunctions.h b/SandboxiePlus/MiscHelpers/Common/OtherFunctions.h index 90b6c496..81545454 100644 --- a/SandboxiePlus/MiscHelpers/Common/OtherFunctions.h +++ b/SandboxiePlus/MiscHelpers/Common/OtherFunctions.h @@ -117,7 +117,7 @@ MISCHELPERS_EXPORT bool WriteStringToFile(const QString& filename, const QStri MISCHELPERS_EXPORT bool CreateDir(const QString& path); MISCHELPERS_EXPORT bool DeleteDir(const QString& path, bool bEmpty = false); MISCHELPERS_EXPORT bool CopyDir(const QString& srcDirPath, const QString& destDirPath, bool bMove = false); -MISCHELPERS_EXPORT QStringList ListDir(const QString& srcDirPath); +MISCHELPERS_EXPORT QStringList ListDir(const QString& srcDirPath, const QStringList& NameFilter = QStringList(), bool bAndSubDirs = true); MISCHELPERS_EXPORT bool SafeRemove(const QString& path); MISCHELPERS_EXPORT QString GetRelativeSharedPath(const QString& fullPath, const QStringList& shared, QString& rootPath); diff --git a/SandboxiePlus/MiscHelpers/Common/Settings.cpp b/SandboxiePlus/MiscHelpers/Common/Settings.cpp index 55365a31..065d1e5c 100644 --- a/SandboxiePlus/MiscHelpers/Common/Settings.cpp +++ b/SandboxiePlus/MiscHelpers/Common/Settings.cpp @@ -12,9 +12,9 @@ bool TestWriteRight(const QString& Path) return TestFile.remove(); } -CSettings::CSettings(const QString& AppName, bool bShared, QMap DefaultValues, QObject* qObject) : QObject(qObject) +CSettings::CSettings(const QString& AppDir, const QString& AppName, bool bShared, QMap DefaultValues, QObject* qObject) : QObject(qObject) { - m_ConfigDir = QCoreApplication::applicationDirPath(); + m_ConfigDir = AppDir; if (!(m_bPortable = QFile::exists(m_ConfigDir + "/" + AppName + ".ini"))) { QStringList dirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); diff --git a/SandboxiePlus/MiscHelpers/Common/Settings.h b/SandboxiePlus/MiscHelpers/Common/Settings.h index edb874cf..21530967 100644 --- a/SandboxiePlus/MiscHelpers/Common/Settings.h +++ b/SandboxiePlus/MiscHelpers/Common/Settings.h @@ -97,7 +97,7 @@ public: virtual bool IsBlob() const {return true;} }; - CSettings(const QString& AppName, bool bShared = false, QMap DefaultValues = QMap(), QObject* qObject = NULL); + CSettings(const QString& AppDir, const QString& AppName, bool bShared = false, QMap DefaultValues = QMap(), QObject* qObject = NULL); virtual ~CSettings(); void DelValue(const QString& key); diff --git a/SandboxiePlus/QSbieAPI/SbieAPI.cpp b/SandboxiePlus/QSbieAPI/SbieAPI.cpp index 18c35a44..fbbf2fc1 100644 --- a/SandboxiePlus/QSbieAPI/SbieAPI.cpp +++ b/SandboxiePlus/QSbieAPI/SbieAPI.cpp @@ -291,14 +291,14 @@ SB_STATUS CSbieAPI::Connect(bool takeOver, bool withQueue) //m->lastRecordNum = 0; // Note: this lib is not using all functions hence it can be compatible with multiple driver ABI revisions - QStringList CompatVersions = QStringList () << "5.57.0"; - QString CurVersion = GetVersion(); - if (!CompatVersions.contains(CurVersion)) - { - NtClose(m->SbieApiHandle); - m->SbieApiHandle = INVALID_HANDLE_VALUE; - return SB_ERR(SB_Incompatible, QVariantList() << CurVersion << CompatVersions.join(", ")); - } + //QStringList CompatVersions = QStringList () << "5.55.0"; + //QString CurVersion = GetVersion(); + //if (!CompatVersions.contains(CurVersion)) + //{ + // NtClose(m->SbieApiHandle); + // m->SbieApiHandle = INVALID_HANDLE_VALUE; + // return SB_ERR(SB_Incompatible, QVariantList() << CurVersion << CompatVersions.join(", ")); + //} SB_STATUS Status = SB_OK; if (takeOver) { @@ -1055,6 +1055,7 @@ SB_STATUS CSbieAPI::RunStart(const QString& BoxName, const QString& Command, boo StartArgs += Command; + qint64 pid = 0; //wchar_t sysPath[MAX_PATH]; //GetSystemDirectoryW(sysPath, MAX_PATH); if (pProcess) { @@ -1064,6 +1065,7 @@ SB_STATUS CSbieAPI::RunStart(const QString& BoxName, const QString& Command, boo pProcess->setProgram(GetStartPath()); pProcess->setNativeArguments(StartArgs); pProcess->start(); + pid = pProcess->processId(); } else { QProcess process; @@ -1072,7 +1074,7 @@ SB_STATUS CSbieAPI::RunStart(const QString& BoxName, const QString& Command, boo process.setWorkingDirectory(WorkingDir); process.setProgram(GetStartPath()); process.setNativeArguments(StartArgs); - process.startDetached(); + process.startDetached(&pid); } /* @@ -1109,6 +1111,8 @@ SB_STATUS CSbieAPI::RunStart(const QString& BoxName, const QString& Command, boo CloseHandle( pi.hThread ); */ + if(pid == 0) + return SB_ERR(); return SB_OK; } diff --git a/SandboxiePlus/SandMan/Forms/SettingsWindow.ui b/SandboxiePlus/SandMan/Forms/SettingsWindow.ui index 8497c854..ee2fdc80 100644 --- a/SandboxiePlus/SandMan/Forms/SettingsWindow.ui +++ b/SandboxiePlus/SandMan/Forms/SettingsWindow.ui @@ -7,7 +7,7 @@ 0 0 634 - 451 + 464 @@ -54,7 +54,51 @@ - + + + + Count and display the disk space ocupied by each sandbox + + + + + + + Open urls from this ui sandboxed + + + true + + + + + + + Show Notifications for relevant log Messages + + + false + + + + + + + Watch Sandboxie.ini for changes + + + + + + + + + + Show recoverable files as notifications + + + + Qt::Vertical @@ -67,30 +111,14 @@ - - + + - Show Notifications for relevant log Messages - - - false + Show first recovery window when emptying sandboxes - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + @@ -104,6 +132,19 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -114,33 +155,13 @@ - + Run box operations asynchronously whenever possible (like content deletion) - - - - Open urls from this ui sandboxed - - - true - - - - - - - Show first recovery window when emptying sandboxes - - - - - - @@ -155,48 +176,31 @@ - - - - Use Dark Theme (fully applied after a restart) - - - true - - - - - - - Watch Sandboxie.ini for changes - - - - - - - Show recoverable files as notifications - - - - - - - Count and display the disk space occupied by each sandbox - - - - + Shell Integration + + + + + 75 + true + true + + + + Systray options + + + @@ -204,18 +208,35 @@ - - - - Qt::Horizontal + + + + + + + + + + On main window close: - - - 40 - 20 - + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + + + + + + Always use DefaultBox + + + + + + + Show a tray notification when automatic box operations are started + + @@ -230,15 +251,18 @@ - - - - On main window close: + + + + Qt::Horizontal - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 40 + 20 + - + @@ -247,19 +271,6 @@ - - - - Show boxes in tray list: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - @@ -274,13 +285,6 @@ - - - - Always use DefaultBox - - - @@ -288,22 +292,24 @@ - - - - - 75 - true - true - - + + + + + - Start Sandbox Manager + Show Icon in Systray: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true - - + + Qt::Horizontal @@ -315,10 +321,10 @@ - - + + - Show Icon in Systray: + Show boxes in tray list: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -335,38 +341,8 @@ - - - - Show a tray notification when automatic box operations are started - - - - - - - - 75 - true - true - - - - Systray options - - - - - - - - - - - - - - + + Qt::Horizontal @@ -378,6 +354,155 @@ + + + + + 75 + true + true + + + + Start Sandbox Manager + + + + + + + + + + Interface Config + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 75 + true + true + + + + Interface Options + + + + + + + Font Scaling + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + false + + + + + + + High DPI Scaling + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + (Restart required) + + + + + + + * indetermined means depanding on the view mode + + + + + + + + + + Use Dark Theme + + + true + + + + + + + Show Classic Background in box list* + + + true + + + + + + + Use large icons in box list * + + + true + + + + + + + Don't show icons in menus * + + + true + + + @@ -389,7 +514,34 @@ - + + + + + + + Separate user folders + + + + + + + Hook selected Win32k system calls to enable GPU acceleration (experimental) + + + + + + + Portable root folder + + + + + + + Qt::Horizontal @@ -402,7 +554,7 @@ - + Qt::Horizontal @@ -415,70 +567,13 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Portable root folder - - - - - - - Use Windows Filtering Platform to restrict network access - - - - - - - - + + - Separate user folders - - - - - - - - 23 - 16777215 - - - - ... - - - - - - - Activate Kernel Mode Object Filtering - - - - - - - Sandbox <a href="sbie://docs/ipcrootpath">ipc root</a>: + Sandbox <a href="sbie://docs/keyrootpath">registry root</a>: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -488,20 +583,6 @@ - - - - - 75 - true - true - - - - Sandbox default - - - @@ -516,21 +597,32 @@ - - + + + + + 23 + 16777215 + + - Sandbox <a href="sbie://docs/keyrootpath">registry root</a>: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true + ... - - + + + + + 75 + true + true + + + + Sandbox default + + @@ -545,7 +637,21 @@ - + + + + Activate Kernel Mode Object Filtering + + + + + + + Use Windows Filtering Platform to restrict network access + + + + Qt::Vertical @@ -558,10 +664,36 @@ - - + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + - Hook selected Win32k system calls to enable GPU acceleration (experimental) + Sandbox <a href="sbie://docs/ipcrootpath">ipc root</a>: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + + + + + Use a Sandboxie login instead of an anonymous token (experimental) @@ -652,7 +784,7 @@ - + Config Protection @@ -1013,7 +1145,6 @@ tabs uiLang - chkDarkTheme chkNotifications chkSandboxUrls chkShowRecovery diff --git a/SandboxiePlus/SandMan/Models/SbieModel.cpp b/SandboxiePlus/SandMan/Models/SbieModel.cpp index 41be72a2..20554e7c 100644 --- a/SandboxiePlus/SandMan/Models/SbieModel.cpp +++ b/SandboxiePlus/SandMan/Models/SbieModel.cpp @@ -5,8 +5,10 @@ #include "../SandMan.h" CSbieModel::CSbieModel(QObject *parent) -:CTreeItemModel(parent) +: CTreeItemModel(parent) { + m_LargeIcons = false; + //m_BoxEmpty = QIcon(":/BoxEmpty"); //m_BoxInUse = QIcon(":/BoxInUse"); m_ExeIcon = QIcon(":/exeIcon32"); @@ -137,7 +139,10 @@ QList CSbieModel::Sync(const QMap& BoxList, cons New[pNode->Path].append(pNode); Added.append(ID); - pNode->Icon = theGUI->GetBoxIcon(CSandBoxPlus::eDefault, false); + QIcon Icon = theGUI->GetBoxIcon(CSandBoxPlus::eDefault, false); + if (m_LargeIcons) // but not for boxes + Icon = QIcon(Icon.pixmap(QSize(32,32)).scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + pNode->Icon = Icon; pNode->IsBold = true; pNode->Values[eName].Raw = Group; @@ -210,17 +215,25 @@ QList CSbieModel::Sync(const QMap& BoxList, cons bool Busy = pBoxEx->IsBusy(); int boxType = pBoxEx->GetType(); + QIcon Icon; if (pNode->inUse != inUse || (pNode->busyState || Busy) || pNode->boxType != boxType) { pNode->inUse = inUse; pNode->boxType = boxType; - if(Busy) pNode->busyState = (pNode->busyState == 1) ? 2 : 1; // make it flach, the cheep way - else pNode->busyState = 0; //pNode->Icon = pNode->inUse ? m_BoxInUse : m_BoxEmpty; - pNode->Icon = theGUI->GetBoxIcon(boxType, inUse, pNode->busyState == 1); + Icon = theGUI->GetBoxIcon(boxType, inUse); + } + + if (!Icon.isNull()) { + if (Busy) Icon = theGUI->MakeIconBusy(Icon, pNode->busyState++); + else pNode->busyState = 0; + if (m_LargeIcons) // but not for boxes + Icon = QIcon(Icon.pixmap(QSize(32,32)).scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + pNode->Icon = Icon; Changed = 1; // set change for first column } + if (pNode->IsGray != !pBoxEx->IsEnabled()) { pNode->IsGray = !pBoxEx->IsEnabled(); @@ -495,6 +508,14 @@ QVariant CSbieModel::headerData(int section, Qt::Orientation orientation, int ro return g_ExeIcon; }*/ +QVariant CSbieModel::data(const QModelIndex &index, int role) const +{ + if(m_LargeIcons && role == Qt::SizeHintRole) + return QSize(32,32); + + return CTreeItemModel::data(index, role); +} + Qt::ItemFlags CSbieModel::flags(const QModelIndex& index) const { Qt::ItemFlags Flags = CTreeItemModel::flags(index); diff --git a/SandboxiePlus/SandMan/Models/SbieModel.h b/SandboxiePlus/SandMan/Models/SbieModel.h index 86ee5706..2f722761 100644 --- a/SandboxiePlus/SandMan/Models/SbieModel.h +++ b/SandboxiePlus/SandMan/Models/SbieModel.h @@ -16,6 +16,8 @@ public: QList Sync(const QMap& BoxList, const QMap& Groups = QMap(), bool ShowHidden = false); + void SetLargeIcons(bool bSet = true) { m_LargeIcons = bSet; } + CSandBoxPtr GetSandBox(const QModelIndex &index) const; CBoxedProcessPtr GetProcess(const QModelIndex &index) const; QString GetGroup(const QModelIndex &index) const; @@ -30,7 +32,8 @@ public: } GetType(const QModelIndex &index) const; Qt::DropActions supportedDropActions() const { return Qt::MoveAction; } - Qt::ItemFlags flags(const QModelIndex& index) const; + QVariant data(const QModelIndex &index, int role) const; + Qt::ItemFlags flags(const QModelIndex& index) const; QStringList mimeTypes() { return QStringList() << m_SbieModelMimeType; } QMimeData* mimeData(const QModelIndexList& indexes) const; bool canDropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) const { return true; } @@ -62,7 +65,7 @@ protected: struct SSandBoxNode: STreeNode { - SSandBoxNode(const QVariant& Id) : STreeNode(Id) { inUse = false; boxType = -1; OrderNumber = 0; } + SSandBoxNode(const QVariant& Id) : STreeNode(Id) { inUse = false; busyState = 0; boxType = -1; OrderNumber = 0; } CSandBoxPtr pBox; bool inUse; @@ -89,6 +92,7 @@ protected: private: + bool m_LargeIcons; //QIcon m_BoxEmpty; //QIcon m_BoxInUse; QIcon m_ExeIcon; diff --git a/SandboxiePlus/SandMan/Resources/Actions/GUI.png b/SandboxiePlus/SandMan/Resources/Actions/GUI.png new file mode 100644 index 00000000..6d43efa6 Binary files /dev/null and b/SandboxiePlus/SandMan/Resources/Actions/GUI.png differ diff --git a/SandboxiePlus/SandMan/Resources/Actions/PackBox.png b/SandboxiePlus/SandMan/Resources/Actions/PackBox.png new file mode 100644 index 00000000..42dd0fb4 Binary files /dev/null and b/SandboxiePlus/SandMan/Resources/Actions/PackBox.png differ diff --git a/SandboxiePlus/SandMan/Resources/Actions/UnPackBox.png b/SandboxiePlus/SandMan/Resources/Actions/UnPackBox.png new file mode 100644 index 00000000..58f0a69a Binary files /dev/null and b/SandboxiePlus/SandMan/Resources/Actions/UnPackBox.png differ diff --git a/SandboxiePlus/SandMan/Resources/Classic.png b/SandboxiePlus/SandMan/Resources/Classic.png new file mode 100644 index 00000000..af03b3ec Binary files /dev/null and b/SandboxiePlus/SandMan/Resources/Classic.png differ diff --git a/SandboxiePlus/SandMan/Resources/ClassicD.png b/SandboxiePlus/SandMan/Resources/ClassicD.png new file mode 100644 index 00000000..90ae9570 Binary files /dev/null and b/SandboxiePlus/SandMan/Resources/ClassicD.png differ diff --git a/SandboxiePlus/SandMan/Resources/SandMan.qrc b/SandboxiePlus/SandMan/Resources/SandMan.qrc index fecee6dd..f936b008 100644 --- a/SandboxiePlus/SandMan/Resources/SandMan.qrc +++ b/SandboxiePlus/SandMan/Resources/SandMan.qrc @@ -70,6 +70,9 @@ Actions/Monitor.png SideLogo.png Actions/Refresh.png + Actions/UnPackBox.png + Actions/PackBox.png + Actions/GUI.png Boxes/sandbox-b-empty.png @@ -93,5 +96,10 @@ AdvancedD.png Simple.png SimpleD.png + background.png + sandboxie-logo.png + sandboxie-back.png + Classic.png + ClassicD.png diff --git a/SandboxiePlus/SandMan/Resources/background.png b/SandboxiePlus/SandMan/Resources/background.png new file mode 100644 index 00000000..3f912b1e Binary files /dev/null and b/SandboxiePlus/SandMan/Resources/background.png differ diff --git a/SandboxiePlus/SandMan/Resources/sandboxie-back.png b/SandboxiePlus/SandMan/Resources/sandboxie-back.png new file mode 100644 index 00000000..c36af81b Binary files /dev/null and b/SandboxiePlus/SandMan/Resources/sandboxie-back.png differ diff --git a/SandboxiePlus/SandMan/Resources/sandboxie-logo.png b/SandboxiePlus/SandMan/Resources/sandboxie-logo.png new file mode 100644 index 00000000..550ff294 Binary files /dev/null and b/SandboxiePlus/SandMan/Resources/sandboxie-logo.png differ diff --git a/SandboxiePlus/SandMan/SandMan.cpp b/SandboxiePlus/SandMan/SandMan.cpp index 223ad476..343ec582 100644 --- a/SandboxiePlus/SandMan/SandMan.cpp +++ b/SandboxiePlus/SandMan/SandMan.cpp @@ -23,6 +23,8 @@ #include "../UGlobalHotkey/uglobalhotkeys.h" #include "Wizards/SetupWizard.h" #include "Helpers/WinAdmin.h" +#include "../MiscHelpers/Common/OtherFunctions.h" +#include "../MiscHelpers/Common/Common.h" CSbiePlusAPI* theAPI = NULL; @@ -85,24 +87,6 @@ CSandMan* theGUI = NULL; extern QString g_PendingMessage; -#include -class CTrayBoxesItemDelegate : public QStyledItemDelegate -{ - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const - { - QStyleOptionViewItem opt(option); - if ((opt.state & QStyle::State_MouseOver) != 0) - opt.state |= QStyle::State_Selected; - else if ((opt.state & QStyle::State_HasFocus) != 0 && m_Hold) - opt.state |= QStyle::State_Selected; - opt.state &= ~QStyle::State_HasFocus; - QStyledItemDelegate::paint(painter, opt, index); - } -public: - static bool m_Hold; -}; - -bool CTrayBoxesItemDelegate::m_Hold = false; CSandMan::CSandMan(QWidget *parent) : QMainWindow(parent) @@ -122,9 +106,9 @@ CSandMan::CSandMan(QWidget *parent) m_ThemeUpdatePending = false; m_DefaultStyle = QApplication::style()->objectName(); m_DefaultPalett = QApplication::palette(); + m_DefaultFontSize = QApplication::font().pointSizeF(); LoadLanguage(); - SetUITheme(); if (!theConf->IsWritable()) { QMessageBox::critical(this, "Sandboxie-Plus", tr("WARNING: Sandboxie-Plus.ini in %1 cannot be written to, settings will not be saved.").arg(theConf->GetConfigDir())); @@ -152,24 +136,11 @@ CSandMan::CSandMan(QWidget *parent) m_bConnectPending = false; m_bStopPending = false; - QTreeViewEx::m_ResetColumns = tr("Reset Columns"); - CPanelView::m_CopyCell = tr("Copy Cell"); - CPanelView::m_CopyRow = tr("Copy Row"); - CPanelView::m_CopyPanel = tr("Copy Panel"); + m_pMainWidget = new QWidget(this); + CreateUI(); + setCentralWidget(m_pMainWidget); - connect(menuBar(), SIGNAL(hovered(QAction*)), this, SLOT(OnMenuHover(QAction*))); - - CreateMenus(); - - m_pMainWidget = new QWidget(); - m_pMainLayout = new QVBoxLayout(m_pMainWidget); - m_pMainLayout->setMargin(2); - m_pMainLayout->setSpacing(0); - this->setCentralWidget(m_pMainWidget); - - CreateToolBar(); - - CreateView(); + SetUITheme(); m_pHotkeyManager = new UGlobalHotkeys(this); connect(m_pHotkeyManager, SIGNAL(activated(size_t)), SLOT(OnHotKey(size_t))); @@ -178,52 +149,12 @@ CSandMan::CSandMan(QWidget *parent) for (int i = 0; i < eMaxColor; i++) { m_BoxIcons[i].Empty = QIcon(QString(":/Boxes/Empty%1").arg(i)); m_BoxIcons[i].InUse= QIcon(QString(":/Boxes/Full%1").arg(i)); - - //QImage Image(QString(":/Boxes/Empty%1").arg(i)); - //Image.invertPixels(); - //m_BoxIcons[i].Busy = QIcon(QPixmap::fromImage(Image)); - - QPixmap base = QPixmap(QString(":/Boxes/Empty%1").arg(i)); - QPixmap overlay= QPixmap(":/Boxes/Busy"); - QPixmap result(base.width(), base.height()); - result.fill(Qt::transparent); // force alpha channel - QPainter painter(&result); - painter.drawPixmap(0, 0, base); - painter.drawPixmap(0, 0, overlay); - m_BoxIcons[i].Busy = QIcon(result); } - // Tray - m_pTrayIcon = new QSystemTrayIcon(GetTrayIcon(), this); - m_pTrayIcon->setToolTip(GetTrayText()); - connect(m_pTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(OnSysTray(QSystemTrayIcon::ActivationReason))); - m_bIconEmpty = true; - m_bIconDisabled = false; - m_bIconBusy = false; - m_iDeletingContent = 0; - - CreateTrayMenu(); - - bool bAutoRun = QApplication::arguments().contains("-autorun"); - - if(g_PendingMessage.isEmpty()){ - m_pTrayIcon->show(); // Note: qt bug; hide does not work if not showing first :/ - if(!bAutoRun && theConf->GetInt("Options/SysTrayIcon", 1) == 0) - m_pTrayIcon->hide(); - } - // + CreateTrayIcon(); LoadState(); - bool bAdvanced = theConf->GetBool("Options/AdvancedView", true); - foreach(QAction * pAction, m_pViewMode->actions()) - pAction->setChecked(pAction->data().toBool() == bAdvanced); - SetViewMode(bAdvanced); - - - m_pKeepTerminated->setChecked(theConf->GetBool("Options/KeepTerminated")); - m_pShowAllSessions->setChecked(theConf->GetBool("Options/ShowAllSessions")); - m_pProgressDialog = new CProgressDialog(""); m_pProgressDialog->setWindowModality(Qt::ApplicationModal); connect(m_pProgressDialog, SIGNAL(Cancel()), this, SLOT(OnCancelAsync())); @@ -232,7 +163,6 @@ CSandMan::CSandMan(QWidget *parent) m_pPopUpWindow = new CPopUpWindow(); bool bAlwaysOnTop = theConf->GetBool("Options/AlwaysOnTop", false); - m_pWndTopMost->setChecked(bAlwaysOnTop); this->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop); m_pPopUpWindow->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop); m_pProgressDialog->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop); @@ -247,6 +177,7 @@ CSandMan::CSandMan(QWidget *parent) m_uTimerID = startTimer(1000); + bool bAutoRun = QApplication::arguments().contains("-autorun"); if (!bAutoRun && g_PendingMessage.isEmpty()) SafeShow(this); @@ -265,7 +196,7 @@ CSandMan::~CSandMan() m_pPopUpWindow->close(); delete m_pPopUpWindow; - if(m_pEnableMonitoring->isChecked()) + if(theAPI->IsMonitoring()) theAPI->EnableMonitor(false); delete m_pBoxBorder; @@ -283,52 +214,78 @@ CSandMan::~CSandMan() void CSandMan::LoadState() { - setWindowState(Qt::WindowNoState); + setWindowState(Qt::WindowNoState); restoreGeometry(theConf->GetBlob("MainWindow/Window_Geometry")); restoreState(theConf->GetBlob("MainWindow/Window_State")); + //m_pBoxTree->restoreState(theConf->GetBlob("MainWindow/BoxTree_Columns")); - m_pMessageLog->GetView()->header()->restoreState(theConf->GetBlob("MainWindow/LogList_Columns")); - m_pRecoveryLog->GetView()->header()->restoreState(theConf->GetBlob("MainWindow/RecoveryLog_Columns")); - m_pLogSplitter->restoreState(theConf->GetBlob("MainWindow/Log_Splitter")); - m_pPanelSplitter->restoreState(theConf->GetBlob("MainWindow/Panel_Splitter")); - m_pLogTabs->setCurrentIndex(theConf->GetInt("MainWindow/LogTab", 0)); + if(m_pMessageLog) m_pMessageLog->GetView()->header()->restoreState(theConf->GetBlob("MainWindow/LogList_Columns")); + if(m_pRecoveryLog) m_pRecoveryLog->GetView()->header()->restoreState(theConf->GetBlob("MainWindow/RecoveryLog_Columns")); + if(m_pLogSplitter) m_pLogSplitter->restoreState(theConf->GetBlob("MainWindow/Log_Splitter")); + if(m_pPanelSplitter) m_pPanelSplitter->restoreState(theConf->GetBlob("MainWindow/Panel_Splitter")); + if(m_pLogTabs) m_pLogTabs->setCurrentIndex(theConf->GetInt("MainWindow/LogTab", 0)); } void CSandMan::StoreState() { theConf->SetBlob("MainWindow/Window_Geometry", saveGeometry()); theConf->SetBlob("MainWindow/Window_State", saveState()); + //theConf->SetBlob("MainWindow/BoxTree_Columns", m_pBoxTree->saveState()); - theConf->SetBlob("MainWindow/LogList_Columns", m_pMessageLog->GetView()->header()->saveState()); - theConf->SetBlob("MainWindow/RecoveryLog_Columns", m_pRecoveryLog->GetView()->header()->saveState()); - theConf->SetBlob("MainWindow/Log_Splitter", m_pLogSplitter->saveState()); - theConf->SetBlob("MainWindow/Panel_Splitter", m_pPanelSplitter->saveState()); - theConf->SetValue("MainWindow/LogTab", m_pLogTabs->currentIndex()); + if(m_pMessageLog) theConf->SetBlob("MainWindow/LogList_Columns", m_pMessageLog->GetView()->header()->saveState()); + if(m_pRecoveryLog) theConf->SetBlob("MainWindow/RecoveryLog_Columns", m_pRecoveryLog->GetView()->header()->saveState()); + if(m_pLogSplitter) theConf->SetBlob("MainWindow/Log_Splitter", m_pLogSplitter->saveState()); + if(m_pPanelSplitter) theConf->SetBlob("MainWindow/Panel_Splitter", m_pPanelSplitter->saveState()); + if(m_pLogTabs) theConf->SetValue("MainWindow/LogTab", m_pLogTabs->currentIndex()); } QIcon CSandMan::GetIcon(const QString& Name, bool bAction) { + int iNoIcons = theConf->GetInt("Options/NoIcons", 2); + if (iNoIcons == 2) + iNoIcons = theConf->GetInt("Options/ViewMode", 1) == 2 ? 1 : 0; + if(bAction && iNoIcons) + return QIcon(); + QString Path = QApplication::applicationDirPath() + "/Icons/" + Name + ".png"; if(QFile::exists(Path)) return QIcon(Path); return QIcon((bAction ? ":/Actions/" : ":/") + Name + ".png"); } -void CSandMan::CreateMenus() +void CSandMan::CreateUI() +{ + connect(menuBar(), SIGNAL(hovered(QAction*)), this, SLOT(OnMenuHover(QAction*))); + + int iViewMode = theConf->GetInt("Options/ViewMode", 1); + + if(iViewMode == 2) + CreateOldMenus(); + else + CreateMenus(iViewMode == 1); + + m_pMainLayout = new QVBoxLayout(m_pMainWidget); + m_pMainLayout->setMargin(2); + m_pMainLayout->setSpacing(0); + + if(iViewMode == 1) + CreateToolBar(); + + CreateView(iViewMode == 1); + + foreach(QAction * pAction, m_pViewMode->actions()) + pAction->setChecked(pAction->data().toInt() == iViewMode); + + statusBar()->setVisible(iViewMode == 1); + + if(m_pKeepTerminated) m_pKeepTerminated->setChecked(theConf->GetBool("Options/KeepTerminated")); + if(m_pShowAllSessions) m_pShowAllSessions->setChecked(theConf->GetBool("Options/ShowAllSessions")); + + m_pWndTopMost->setChecked(theConf->GetBool("Options/AlwaysOnTop", false)); +} + +void CSandMan::CreateMaintenanceMenu() { - m_pMenuFile = menuBar()->addMenu(tr("&Sandbox")); - m_pNewBox = m_pMenuFile->addAction(CSandMan::GetIcon("NewBox"), tr("Create New Box"), this, SLOT(OnNewBox())); - m_pNewGroup = m_pMenuFile->addAction(CSandMan::GetIcon("Group"), tr("Create Box Group"), this, SLOT(OnNewGroupe())); - m_pMenuFile->addSeparator(); - m_pEmptyAll = m_pMenuFile->addAction(CSandMan::GetIcon("EmptyAll"), tr("Terminate All Processes"), this, SLOT(OnEmptyAll())); - m_pWndFinder = m_pMenuFile->addAction(CSandMan::GetIcon("finder"), tr("Window Finder"), this, SLOT(OnWndFinder())); - m_pDisableForce = m_pMenuFile->addAction(tr("Pause Forcing Programs"), this, SLOT(OnDisableForce())); - m_pDisableForce->setCheckable(true); - m_pDisableRecovery = m_pMenuFile->addAction(tr("Disable File Recovery")); - m_pDisableRecovery->setCheckable(true); - m_pDisableMessages = m_pMenuFile->addAction(tr("Disable Message PopUp")); - m_pDisableMessages->setCheckable(true); - m_pMenuFile->addSeparator(); m_pMaintenance = m_pMenuFile->addMenu(CSandMan::GetIcon("Maintenance"), tr("&Maintenance")); m_pConnect = m_pMaintenance->addAction(CSandMan::GetIcon("Connect"), tr("Connect"), this, SLOT(OnMaintenance())); m_pDisconnect = m_pMaintenance->addAction(CSandMan::GetIcon("Disconnect"), tr("Disconnect"), this, SLOT(OnMaintenance())); @@ -346,9 +303,84 @@ void CSandMan::CreateMenus() m_pUninstallSvc = m_pMaintenanceItems->addAction(tr("Uninstall Service"), this, SLOT(OnMaintenance())); m_pMaintenance->addSeparator(); m_pSetupWizard = m_pMaintenance->addAction(CSandMan::GetIcon("Software"), tr("Setup Wizard"), this, SLOT(OnMaintenance())); - if(IsFullyPortable()) + if(theGUI->IsFullyPortable()) m_pUninstallAll = m_pMaintenance->addAction(CSandMan::GetIcon("Uninstall"), tr("Uninstall All"), this, SLOT(OnMaintenance())); - +} + +void CSandMan::CreateViewBaseMenu() +{ + m_pViewMode = new QActionGroup(m_pMenuView); + MakeAction(m_pViewMode, m_pMenuView, tr("Simple View"), 0); + MakeAction(m_pViewMode, m_pMenuView, tr("Advanced View"), 1); + MakeAction(m_pViewMode, m_pMenuView, tr("Classic View"), 2); + connect(m_pViewMode, SIGNAL(triggered(QAction*)), this, SLOT(OnViewMode(QAction*))); + + m_pMenuView->addSeparator(); + m_pWndTopMost = m_pMenuView->addAction(tr("Always on Top"), this, SLOT(OnAlwaysTop())); + m_pWndTopMost->setCheckable(true); +} + +void CSandMan::CreateHelpMenu(bool bAdvanced) +{ + m_pMenuHelp = menuBar()->addMenu(tr("&Help")); + //m_pMenuHelp->addAction(tr("Support Sandboxie-Plus on Patreon"), this, SLOT(OnHelp())); + m_pSupport = m_pMenuHelp->addAction(tr("Support Sandboxie-Plus with a Donation"), this, SLOT(OnHelp())); + if (!bAdvanced) { + m_pMenuHelp->removeAction(m_pSupport); + menuBar()->addAction(m_pSupport); + } + m_pForum = m_pMenuHelp->addAction(tr("Visit Support Forum"), this, SLOT(OnHelp())); + m_pManual = m_pMenuHelp->addAction(tr("Online Documentation"), this, SLOT(OnHelp())); + m_pMenuHelp->addSeparator(); + m_pUpdate = m_pMenuHelp->addAction(tr("Check for Updates"), this, SLOT(CheckForUpdates())); + m_pMenuHelp->addSeparator(); + m_pAboutQt = m_pMenuHelp->addAction(tr("About the Qt Framework"), this, SLOT(OnAbout())); + m_pAbout = m_pMenuHelp->addAction(CSandMan::GetIcon("IconFull", false), tr("About Sandboxie-Plus"), this, SLOT(OnAbout())); +} + +void CSandMan::CreateMenus(bool bAdvanced) +{ + menuBar()->clear(); + + m_pMenuFile = menuBar()->addMenu(tr("&Sandbox")); + m_pNewBox = m_pMenuFile->addAction(CSandMan::GetIcon("NewBox"), tr("Create New Box"), this, SLOT(OnSandBoxAction())); + m_pNewGroup = m_pMenuFile->addAction(CSandMan::GetIcon("Group"), tr("Create Box Group"), this, SLOT(OnSandBoxAction())); + m_pMenuFile->addSeparator(); + m_pEmptyAll = m_pMenuFile->addAction(CSandMan::GetIcon("EmptyAll"), tr("Terminate All Processes"), this, SLOT(OnEmptyAll())); + m_pDisableForce = m_pMenuFile->addAction(tr("Pause Forcing Programs"), this, SLOT(OnDisableForce())); + m_pDisableForce->setCheckable(true); + if(bAdvanced) { + m_pDisableRecovery = m_pMenuFile->addAction(tr("Disable File Recovery")); + m_pDisableRecovery->setCheckable(true); + m_pDisableMessages = m_pMenuFile->addAction(tr("Disable Message PopUp")); + m_pDisableMessages->setCheckable(true); + } + else { + m_pDisableRecovery = NULL; + m_pDisableMessages = NULL; + } + m_pMenuFile->addSeparator(); + m_pWndFinder = m_pMenuFile->addAction(CSandMan::GetIcon("finder"), tr("Is Window Sandboxed"), this, SLOT(OnWndFinder())); + + if(bAdvanced || theGUI->IsFullyPortable()) + CreateMaintenanceMenu(); + else { + m_pMaintenance = NULL; + m_pConnect = NULL; + m_pDisconnect = NULL; + m_pMaintenanceItems = NULL; + m_pInstallDrv = NULL; + m_pStartDrv = NULL; + m_pStopDrv = NULL; + m_pUninstallDrv = NULL; + m_pInstallSvc = NULL; + m_pStartSvc = NULL; + m_pStopSvc = NULL; + m_pUninstallSvc = NULL; + m_pStopAll = NULL; + m_pUninstallAll = NULL; + m_pSetupWizard = NULL; + } m_pMenuFile->addSeparator(); m_pExit = m_pMenuFile->addAction(CSandMan::GetIcon("Exit"), tr("Exit"), this, SLOT(OnExit())); @@ -356,22 +388,20 @@ void CSandMan::CreateMenus() m_pMenuView = menuBar()->addMenu(tr("&View")); - m_pViewMode = new QActionGroup(m_pMenuView); - MakeAction(m_pViewMode, m_pMenuView, tr("Simple View"), false); - MakeAction(m_pViewMode, m_pMenuView, tr("Advanced View"), true); - connect(m_pViewMode, SIGNAL(triggered(QAction*)), this, SLOT(OnViewMode(QAction*))); + CreateViewBaseMenu(); - m_pMenuView->addSeparator(); - m_pWndTopMost = m_pMenuView->addAction(tr("Always on Top"), this, SLOT(OnAlwaysTop())); - m_pWndTopMost->setCheckable(true); - - m_iMenuViewPos = m_pMenuView->actions().count(); + if(bAdvanced) { m_pMenuView->addSeparator(); m_pShowHidden = m_pMenuView->addAction(tr("Show Hidden Boxes")); m_pShowHidden->setCheckable(true); m_pShowAllSessions = m_pMenuView->addAction(tr("Show All Sessions"), this, SLOT(OnProcView())); m_pShowAllSessions->setCheckable(true); + } + else { + m_pShowHidden = NULL; + m_pShowAllSessions = NULL; + } m_pMenuView->addSeparator(); @@ -380,6 +410,7 @@ void CSandMan::CreateMenus() m_pRefreshAll->setShortcutContext(Qt::WidgetWithChildrenShortcut); this->addAction(m_pRefreshAll); + if(bAdvanced) { m_pCleanUpMenu = m_pMenuView->addMenu(CSandMan::GetIcon("Clean"), tr("Clean Up")); m_pCleanUpProcesses = m_pCleanUpMenu->addAction(tr("Cleanup Processes"), this, SLOT(OnCleanUp())); m_pCleanUpMenu->addSeparator(); @@ -389,7 +420,21 @@ void CSandMan::CreateMenus() m_pKeepTerminated = m_pMenuView->addAction(CSandMan::GetIcon("Keep"), tr("Keep terminated"), this, SLOT(OnProcView())); m_pKeepTerminated->setCheckable(true); + } + else { + m_pCleanUpMenu = NULL; + m_pCleanUpProcesses = NULL; + m_pCleanUpMsgLog = NULL; + m_pCleanUpTrace = NULL; + m_pCleanUpRecovery = NULL; + m_pKeepTerminated = NULL; + } + m_pMenuView->addSeparator(); + m_pEnableMonitoring = m_pMenuView->addAction(CSandMan::GetIcon("SetLogging"), tr("Trace Logging"), this, SLOT(OnMonitoring())); + if (bAdvanced) + m_pEnableMonitoring->setCheckable(true); + m_pMenuOptions = menuBar()->addMenu(tr("&Options")); m_pMenuSettings = m_pMenuOptions->addAction(CSandMan::GetIcon("Settings"), tr("Global Settings"), this, SLOT(OnSettings())); @@ -398,21 +443,109 @@ void CSandMan::CreateMenus() m_pMenuOptions->addSeparator(); m_pEditIni = m_pMenuOptions->addAction(CSandMan::GetIcon("EditIni"), tr("Edit ini file"), this, SLOT(OnEditIni())); m_pReloadIni = m_pMenuOptions->addAction(CSandMan::GetIcon("ReloadIni"), tr("Reload ini file"), this, SLOT(OnReloadIni())); - m_pMenuOptions->addSeparator(); - m_pEnableMonitoring = m_pMenuOptions->addAction(CSandMan::GetIcon("SetLogging"), tr("Trace Logging"), this, SLOT(OnSetMonitoring())); - m_pEnableMonitoring->setCheckable(true); - - m_pMenuHelp = menuBar()->addMenu(tr("&Help")); - //m_pMenuHelp->addAction(tr("Support Sandboxie-Plus on Patreon"), this, SLOT(OnHelp())); - m_pSupport = m_pMenuHelp->addAction(tr("Support Sandboxie-Plus with a Donation"), this, SLOT(OnHelp())); - m_pForum = m_pMenuHelp->addAction(tr("Visit Support Forum"), this, SLOT(OnHelp())); - m_pManual = m_pMenuHelp->addAction(tr("Online Documentation"), this, SLOT(OnHelp())); - m_pMenuHelp->addSeparator(); - m_pUpdate = m_pMenuHelp->addAction(tr("Check for Updates"), this, SLOT(CheckForUpdates())); - m_pMenuHelp->addSeparator(); - m_pAboutQt = m_pMenuHelp->addAction(tr("About the Qt Framework"), this, SLOT(OnAbout())); - m_pAbout = m_pMenuHelp->addAction(GetIcon("IconFull", false), tr("About Sandboxie-Plus"), this, SLOT(OnAbout())); + CreateHelpMenu(bAdvanced); + + // for old menu + m_pSandbox = NULL; +} + +void CSandMan::CreateOldMenus() +{ + menuBar()->clear(); + + m_pMenuFile = menuBar()->addMenu(tr("&File")); + m_pEmptyAll = m_pMenuFile->addAction(CSandMan::GetIcon("EmptyAll"), tr("Terminate All Processes"), this, SLOT(OnEmptyAll())); + m_pDisableForce = m_pMenuFile->addAction(tr("Pause Forcing Programs"), this, SLOT(OnDisableForce())); + m_pDisableForce->setCheckable(true); + //m_pDisableRecovery = m_pMenuFile->addAction(tr("Disable File Recovery")); + //m_pDisableRecovery->setCheckable(true); + m_pDisableRecovery = NULL; + //m_pDisableMessages = m_pMenuFile->addAction(tr("Disable Message PopUp")); + //m_pDisableMessages->setCheckable(true); + m_pDisableMessages = NULL; + m_pMenuFile->addSeparator(); + m_pWndFinder = m_pMenuFile->addAction(CSandMan::GetIcon("finder"), tr("Is Window Sandboxed"), this, SLOT(OnWndFinder())); + m_pEnableMonitoring = m_pMenuFile->addAction(CSandMan::GetIcon("SetLogging"), tr("Resource Access Monitor"), this, SLOT(OnMonitoring())); + + m_pMenuFile->addSeparator(); + + if(theGUI->IsFullyPortable()) + CreateMaintenanceMenu(); + else { + m_pMaintenance = NULL; + m_pConnect = NULL; + m_pDisconnect = NULL; + m_pMaintenanceItems = NULL; + m_pInstallDrv = NULL; + m_pStartDrv = NULL; + m_pStopDrv = NULL; + m_pUninstallDrv = NULL; + m_pInstallSvc = NULL; + m_pStartSvc = NULL; + m_pStopSvc = NULL; + m_pUninstallSvc = NULL; + m_pStopAll = NULL; + m_pUninstallAll = NULL; + m_pSetupWizard = NULL; + } + + m_pExit = m_pMenuFile->addAction(CSandMan::GetIcon("Exit"), tr("Exit"), this, SLOT(OnExit())); + + m_pMenuView = menuBar()->addMenu(tr("&View")); + + CreateViewBaseMenu(); + + m_pMenuView->addSeparator(); + m_pRefreshAll = m_pMenuView->addAction(CSandMan::GetIcon("Refresh"), tr("Refresh View"), this, SLOT(OnRefresh())); + m_pRefreshAll->setShortcut(QKeySequence("F5")); + m_pRefreshAll->setShortcutContext(Qt::WidgetWithChildrenShortcut); + this->addAction(m_pRefreshAll); + + m_pCleanUpMenu = NULL; + m_pCleanUpProcesses = NULL; + m_pCleanUpMsgLog = NULL; + m_pCleanUpTrace = NULL; + m_pCleanUpRecovery = NULL; + m_pKeepTerminated = NULL; + + m_pSandbox = menuBar()->addMenu(tr("&Sandbox")); + + m_pSandbox->addSeparator(); + m_pNewBox = m_pSandbox->addAction(CSandMan::GetIcon("NewBox"), tr("Create New Box"), this, SLOT(OnSandBoxAction())); + m_pNewGroup = m_pSandbox->addAction(CSandMan::GetIcon("Group"), tr("Create Box Group"), this, SLOT(OnSandBoxAction())); + m_pSandbox->addSeparator(); + + QAction* m_pSetContainer = m_pSandbox->addAction(CSandMan::GetIcon("Advanced"), tr("Set Container Folder"), this, SLOT(OnSandBoxAction())); + m_pSetContainer->setData(CSettingsWindow::eAdvanced); + + m_pShowHidden = m_pSandbox->addAction(tr("Reveal Hidden Boxes")); + m_pShowHidden->setCheckable(true); + //m_pShowAllSessions = m_pSandbox->addAction(tr("Show Boxes From All Sessions"), this, SLOT(OnProcView())); + //m_pShowAllSessions->setCheckable(true); + m_pShowAllSessions = NULL; + + m_pMenuOptions = menuBar()->addMenu(tr("&Configure")); + m_pMenuSettings = m_pMenuOptions->addAction(CSandMan::GetIcon("Settings"), tr("Global Settings"), this, SLOT(OnSettings())); + m_pMenuOptions->addSeparator(); + + QAction* m_pProgramAlert = m_pMenuOptions->addAction(CSandMan::GetIcon("Ampel"), tr("Program Alerts"), this, SLOT(OnSandBoxAction())); + m_pProgramAlert->setData(CSettingsWindow::eProgCtrl); + QAction* m_pWindowsShell = m_pMenuOptions->addAction(CSandMan::GetIcon("Shell"), tr("Windows Shell Integration"), this, SLOT(OnSandBoxAction())); + m_pWindowsShell->setData(CSettingsWindow::eShell); + QAction* m_pCompatibility = m_pMenuOptions->addAction(CSandMan::GetIcon("Compatibility"), tr("Software Compatibility"), this, SLOT(OnSandBoxAction())); + m_pCompatibility->setData(CSettingsWindow::eSoftCompat); + + m_pMenuResetMsgs = m_pMenuOptions->addAction(tr("Reset all hidden messages"), this, SLOT(OnResetMsgs())); + m_pMenuResetGUI = m_pMenuOptions->addAction(tr("Reset all GUI options"), this, SLOT(OnResetGUI())); + m_pMenuOptions->addSeparator(); + QAction* m_pConfigLock = m_pMenuOptions->addAction(CSandMan::GetIcon("Lock"), tr("Lock Configuration"), this, SLOT(OnSandBoxAction())); + m_pConfigLock->setData(CSettingsWindow::eConfigLock); + m_pEditIni = m_pMenuOptions->addAction(CSandMan::GetIcon("EditIni"), tr("Edit ini file"), this, SLOT(OnEditIni())); + m_pReloadIni = m_pMenuOptions->addAction(CSandMan::GetIcon("ReloadIni"), tr("Reload ini file"), this, SLOT(OnReloadIni())); + + CreateHelpMenu(false); + } void CSandMan::CreateToolBar() @@ -495,8 +628,26 @@ void CSandMan::UpdateLabel() m_pLabel->setToolTip(LabelTip); } -void CSandMan::CreateView() +void CSandMan::CreateView(bool bAdvanced) { + m_pBoxView = new CSbieView(); + + if (!bAdvanced) + { + m_pMainLayout->addWidget(m_pBoxView); + + m_pPanelSplitter = NULL; + m_pLogSplitter = NULL; + + m_pLogTabs = NULL; + + m_pMessageLog = NULL; + m_pTraceView = NULL; + m_pRecoveryLog = NULL; + + return; + } + m_pLogSplitter = new QSplitter(); m_pLogSplitter->setOrientation(Qt::Vertical); m_pMainLayout->addWidget(m_pLogSplitter); @@ -505,14 +656,11 @@ void CSandMan::CreateView() m_pPanelSplitter->setOrientation(Qt::Horizontal); m_pLogSplitter->addWidget(m_pPanelSplitter); - - m_pBoxView = new CSbieView(); m_pPanelSplitter->addWidget(m_pBoxView); - connect(m_pBoxView->GetTree()->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(OnSelectionChanged())); - //m_pPanelSplitter->addWidget(); + m_pLogTabs = new QTabWidget(); m_pLogSplitter->addWidget(m_pLogTabs); @@ -531,7 +679,7 @@ void CSandMan::CreateView() m_pLogTabs->addTab(m_pMessageLog, tr("Sbie Messages")); // - m_pTraceView = new CTraceView(this); + m_pTraceView = new CTraceView(false, this); m_pTraceView->AddAction(m_pCleanUpTrace); @@ -554,81 +702,7 @@ void CSandMan::CreateView() // } -void CSandMan::CreateTrayMenu() -{ - m_pTrayMenu = new QMenu(); - QAction* pShowHide = m_pTrayMenu->addAction(GetIcon("IconFull", false), tr("Show/Hide"), this, SLOT(OnShowHide())); - QFont f = pShowHide->font(); - f.setBold(true); - pShowHide->setFont(f); - m_pTrayMenu->addSeparator(); - - m_pTrayList = new QWidgetAction(m_pTrayMenu); - - QWidget* pWidget = new CActionWidget(); - QHBoxLayout* pLayout = new QHBoxLayout(); - pLayout->setMargin(0); - pWidget->setLayout(pLayout); - - m_pTrayBoxes = new QTreeWidget(); - - m_pTrayBoxes->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Maximum); - m_pTrayBoxes->setRootIsDecorated(false); - //m_pTrayBoxes->setHeaderLabels(tr(" Sandbox").split("|")); - m_pTrayBoxes->setHeaderHidden(true); - m_pTrayBoxes->setSelectionMode(QAbstractItemView::NoSelection); - //m_pTrayBoxes->setSelectionMode(QAbstractItemView::ExtendedSelection); - //m_pTrayBoxes->setStyleSheet("QTreeView::item:hover{background-color:#FFFF00;}"); - m_pTrayBoxes->setItemDelegate(new CTrayBoxesItemDelegate()); - - m_pTrayBoxes->setStyle(QStyleFactory::create(m_DefaultStyle)); - - pLayout->insertSpacing(0, 1);// 32); - - /*QFrame* vFrame = new QFrame; - vFrame->setFixedWidth(1); - vFrame->setFrameShape(QFrame::VLine); - vFrame->setFrameShadow(QFrame::Raised); - pLayout->addWidget(vFrame);*/ - - pLayout->addWidget(m_pTrayBoxes); - - m_pTrayList->setDefaultWidget(pWidget); - m_pTrayMenu->addAction(m_pTrayList); - - - m_pTrayBoxes->setContextMenuPolicy(Qt::CustomContextMenu); - connect(m_pTrayBoxes, SIGNAL(customContextMenuRequested( const QPoint& )), this, SLOT(OnBoxMenu(const QPoint &))); - connect(m_pTrayBoxes, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(OnBoxDblClick(QTreeWidgetItem*))); - //m_pBoxMenu - - m_pTraySeparator = m_pTrayMenu->addSeparator(); - m_pTrayMenu->addAction(m_pEmptyAll); - m_pDisableForce2 = m_pTrayMenu->addAction(tr("Pause Forcing Programs"), this, SLOT(OnDisableForce2())); - m_pDisableForce2->setCheckable(true); - m_pTrayMenu->addAction(m_pDisableRecovery); - m_pTrayMenu->addAction(m_pDisableMessages); - m_pTrayMenu->addSeparator(); - - /*QWidgetAction* pBoxWidget = new QWidgetAction(m_pTrayMenu); - - QWidget* pWidget = new QWidget(); - pWidget->setMaximumHeight(200); - QGridLayout* pLayout = new QGridLayout(); - pLayout->addWidget(pBar, 0, 0); - pWidget->setLayout(pLayout); - pBoxWidget->setDefaultWidget(pWidget);*/ - - /*QLabel* pLabel = new QLabel("test"); - pLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - pLabel->setAlignment(Qt::AlignCenter); - pBoxWidget->setDefaultWidget(pLabel);*/ - - //m_pTrayMenu->addAction(pBoxWidget); - //m_pTrayMenu->addSeparator(); - - m_pTrayMenu->addAction(m_pExit); -} +#include "SandManTray.cpp" void CSandMan::OnExit() { @@ -696,7 +770,7 @@ void CSandMan::closeEvent(QCloseEvent *e) QApplication::quit(); } -QIcon CSandMan::GetBoxIcon(int boxType, bool inUse, bool inBusy) +QIcon CSandMan::GetBoxIcon(int boxType, bool inUse)// , int iBusy) { EBoxColors color = eYellow; switch (boxType) { @@ -708,13 +782,31 @@ QIcon CSandMan::GetBoxIcon(int boxType, bool inUse, bool inBusy) case CSandBoxPlus::eAppBox: color = eGreen; break; case CSandBoxPlus::eInsecure: color = eMagenta; break; } - if (inBusy) - return m_BoxIcons[color].Busy; + //if (inBusy) + // return m_BoxIcons[color].Busy; if (inUse) return m_BoxIcons[color].InUse; return m_BoxIcons[color].Empty; } +QIcon CSandMan::MakeIconBusy(const QIcon& Icon, int Index) +{ + static QPixmap overlay; + if(overlay.isNull()) + overlay = QPixmap(":/Boxes/Busy"); + + QPixmap base = Icon.pixmap(32, 32); + QPixmap result(base.width(), base.height()); + result.fill(Qt::transparent); // force alpha channel + QPainter painter(&result); + painter.drawPixmap(0, 0, base); + + QMatrix rm; + rm.rotate(90 * (Index % 4)); + painter.drawPixmap(8, 8, overlay.transformed(rm)); + return QIcon(result); +} + QString CSandMan::GetBoxDescription(int boxType) { QString Info; @@ -833,62 +925,6 @@ void CSandMan::dropEvent(QDropEvent* e) RunSandboxed(Commands, "DefaultBox"); } -QIcon CSandMan::GetTrayIcon(bool isConnected) -{ - bool bClassic = (theConf->GetInt("Options/SysTrayIcon", 1) == 2); - - QString IconFile; - if (isConnected) { - if (m_bIconEmpty) - IconFile = "IconEmpty"; - else - IconFile = "IconFull"; - } else - IconFile = "IconOff"; - if (bClassic) IconFile += "C"; - - QSize size = QSize(16, 16); - QPixmap result(size); - result.fill(Qt::transparent); // force alpha channel - QPainter painter(&result); - QPixmap base = GetIcon(IconFile, false).pixmap(size); - QPixmap overlay; - - if (m_bIconBusy) { - IconFile = "IconBusy"; - if (bClassic) { // classic has a different icon instead of an overlay - IconFile += "C"; - base = GetIcon(IconFile, false).pixmap(size); - } - else - overlay = GetIcon(IconFile, false).pixmap(size); - } - - painter.drawPixmap(0, 0, base); - if(!overlay.isNull()) painter.drawPixmap(0, 0, overlay); - - if (m_bIconDisabled) { - IconFile = "IconDFP"; - if (bClassic) IconFile += "C"; - overlay = GetIcon(IconFile, false).pixmap(size); - painter.drawPixmap(0, 0, overlay); - } - - return QIcon(result); -} - -QString CSandMan::GetTrayText(bool isConnected) -{ - QString Text = "Sandboxie-Plus"; - - if(!isConnected) - Text += tr(" - Driver/Service NOT Running!"); - else if(m_iDeletingContent) - Text += tr(" - Deleting Sandbox Content"); - - return Text; -} - void CSandMan::timerEvent(QTimerEvent* pEvent) { if (pEvent->timerId() != m_uTimerID) @@ -902,22 +938,24 @@ void CSandMan::timerEvent(QTimerEvent* pEvent) { SB_STATUS Status = theAPI->ReloadBoxes(); - theAPI->UpdateProcesses(m_pKeepTerminated->isChecked(), m_pShowAllSessions->isChecked()); + theAPI->UpdateProcesses(KeepTerminated(), ShowAllSessions()); bForceProcessDisabled = theAPI->AreForceProcessDisabled(); m_pDisableForce->setChecked(bForceProcessDisabled); m_pDisableForce2->setChecked(bForceProcessDisabled); - - bool bIsMonitoring = theAPI->IsMonitoring(); - m_pEnableMonitoring->setChecked(bIsMonitoring); - if (!bIsMonitoring) // don't disable the view as logn as there are entries shown - bIsMonitoring = !theAPI->GetTrace().isEmpty(); - m_pTraceView->setEnabled(bIsMonitoring); + if (m_pTraceView) + { + bool bIsMonitoring = theAPI->IsMonitoring(); + m_pEnableMonitoring->setChecked(bIsMonitoring); + if (!bIsMonitoring) // don't disable the view as logn as there are entries shown + bIsMonitoring = !theAPI->GetTrace().isEmpty(); + m_pTraceView->setEnabled(bIsMonitoring); + } QMap Processes = theAPI->GetAllProcesses(); int ActiveProcesses = 0; - if (m_pKeepTerminated->isChecked()) { + if (KeepTerminated()) { foreach(const CBoxedProcessPtr & Process, Processes) { if (!Process->IsTerminated()) ActiveProcesses++; @@ -946,9 +984,6 @@ void CSandMan::timerEvent(QTimerEvent* pEvent) theAPI->UpdateWindowMap(); m_pBoxView->Refresh(); - m_pTraceView->Refresh(); - - OnSelectionChanged(); int iCheckUpdates = theConf->GetInt("Options/CheckForUpdates", 2); if (iCheckUpdates != 0) @@ -1031,7 +1066,7 @@ SB_STATUS CSandMan::DeleteBoxContent(const CSandBoxPtr& pBox, EDelMode Mode, boo if (Mode != eAuto) { Ret = pBox->TerminateAll(); - theAPI->UpdateProcesses(m_pKeepTerminated->isChecked(), m_pShowAllSessions->isChecked()); + theAPI->UpdateProcesses(KeepTerminated(), ShowAllSessions()); if (Ret.IsError()) goto finish; } @@ -1095,21 +1130,6 @@ void CSandMan::OnBoxClosed(const CSandBoxPtr& pBox) } } -void CSandMan::OnSelectionChanged() -{ - //QList Processes = m_pBoxView->GetSelectedProcesses(); - /*if (Processes.isEmpty()) - { - QListBoxes = m_pBoxView->GetSelectedBoxes(); - foreach(const CSandBoxPtr& pBox, Boxes) - Processes.append(pBox->GetProcessList().values()); - }*/ - - //QSet Pids; - //foreach(const CBoxedProcessPtr& pProcess, Processes) - // Pids.insert(pProcess->GetProcessId()); -} - void CSandMan::OnStatusChanged() { bool isConnected = theAPI->IsConnected(); @@ -1155,8 +1175,8 @@ void CSandMan::OnStatusChanged() if (m_SbieTemplates->RunCheck()) { CSettingsWindow* pSettingsWindow = new CSettingsWindow(this); - //connect(pSettingsWindow, SIGNAL(OptionsChanged()), this, SLOT(UpdateSettings())); - pSettingsWindow->showCompat(); + connect(pSettingsWindow, SIGNAL(OptionsChanged(bool)), this, SLOT(UpdateSettings(bool))); + pSettingsWindow->showTab(CSettingsWindow::eSoftCompat); } } @@ -1184,7 +1204,7 @@ void CSandMan::OnStatusChanged() { CSettingsWindow* pSettingsWindow = new CSettingsWindow(); //connect(pSettingsWindow, SIGNAL(OptionsChanged()), this, SLOT(UpdateSettings())); - pSettingsWindow->showSupport(); + pSettingsWindow->showTab(CSettingsWindow::eSupport); } } else { @@ -1248,7 +1268,7 @@ void CSandMan::OnStatusChanged() m_pEditIni->setEnabled(isConnected); m_pReloadIni->setEnabled(isConnected); - m_pEnableMonitoring->setEnabled(isConnected); + if(m_pEnableMonitoring) m_pEnableMonitoring->setEnabled(isConnected); } void CSandMan::OnMenuHover(QAction* action) @@ -1257,7 +1277,7 @@ void CSandMan::OnMenuHover(QAction* action) // return; // ignore sub menus - if (menuBar()->actions().at(0) == action) + if (menuBar()->actions().at(0) == action && m_pMaintenance) { bool bConnected = theAPI->IsConnected(); m_pConnect->setEnabled(!bConnected); @@ -1281,6 +1301,43 @@ void CSandMan::OnMenuHover(QAction* action) //m_pMenuStopAll - always enabled } + + static QMenu* pEmptyMenu = new QMenu(); + if (menuBar()->actions().at(2) == action && m_pSandbox) + { + while (!m_pSandbox->actions().first()->data().toString().isEmpty()) + m_pSandbox->removeAction(m_pSandbox->actions().first()); + + QMap Boxes = theAPI->GetAllBoxes(); + + QAction* pPos = m_pSandbox->actions().first(); + foreach(const CSandBoxPtr & pBox, Boxes) + { + if (!pBox->IsEnabled()) + continue; + + QAction* pBoxAction = new QAction(pBox->GetName().replace("_", " ")); + pBoxAction->setData(pBox->GetName()); + pBoxAction->setMenu(pEmptyMenu); + //pBoxAction->setIcon + //connect(pBoxAction, SIGNAL(triggered()), this, SLOT(OnBoxMenu())); + m_pSandbox->insertAction(pPos, pBoxAction); + } + } + + if (action->data().type() == QVariant::String) { + QString Name = action->data().toString(); + static QPointer pPrev = NULL; + if (pPrev.data() != action) { + if (!pPrev.isNull()) { + pPrev->menu()->close(); + pPrev->setMenu(new QMenu()); + } + pPrev = action; + QMenu* pMenu = theGUI->GetBoxView()->GetMenu(Name); + action->setMenu(pMenu); + } + } } #define HK_PANIC 1 @@ -1305,12 +1362,7 @@ void CSandMan::OnHotKey(size_t id) void CSandMan::OnLogMessage(const QString& Message, bool bNotify) { - QTreeWidgetItem* pItem = new QTreeWidgetItem(); // Time|Message - pItem->setText(0, QDateTime::currentDateTime().toString("hh:mm:ss.zzz")); - pItem->setText(1, Message); - m_pMessageLog->GetTree()->addTopLevelItem(pItem); - - m_pMessageLog->GetView()->verticalScrollBar()->setValue(m_pMessageLog->GetView()->verticalScrollBar()->maximum()); + AddLogMessage(Message); if (bNotify) { statusBar()->showMessage(Message); @@ -1318,11 +1370,24 @@ void CSandMan::OnLogMessage(const QString& Message, bool bNotify) } } +void CSandMan::AddLogMessage(const QString& Message) +{ + if (!m_pMessageLog) + return; + + QTreeWidgetItem* pItem = new QTreeWidgetItem(); // Time|Message + pItem->setText(0, QDateTime::currentDateTime().toString("hh:mm:ss.zzz")); + pItem->setText(1, Message); + m_pMessageLog->GetTree()->addTopLevelItem(pItem); + + m_pMessageLog->GetView()->verticalScrollBar()->setValue(m_pMessageLog->GetView()->verticalScrollBar()->maximum()); +} + void CSandMan::OnLogSbieMessage(quint32 MsgCode, const QStringList& MsgData, quint32 ProcessId) { if ((MsgCode & 0xFFFF) == 2198 ) // file migration progress { - if (!m_pDisableMessages->isChecked()) + if (!IsDisableMessages()) m_pPopUpWindow->ShowProgress(MsgCode, MsgData, ProcessId); return; } @@ -1385,7 +1450,7 @@ void CSandMan::OnLogSbieMessage(quint32 MsgCode, const QStringList& MsgData, qui if ((MsgCode & 0xFFFF) == 2111) // process open denided return; // dont pop that one up - if(MsgCode != 0 && theConf->GetBool("Options/ShowNotifications", true) && !m_pDisableMessages->isChecked()) + if(MsgCode != 0 && theConf->GetBool("Options/ShowNotifications", true) && !IsDisableMessages()) m_pPopUpWindow->AddLogMessage(Message, MsgCode, MsgData, ProcessId); } @@ -1437,161 +1502,7 @@ void CSandMan::OnQueuedRequest(quint32 ClientPid, quint32 ClientTid, quint32 Req m_pPopUpWindow->AddUserPrompt(RequestId, Data, ClientPid); } -void CSandMan::OnFileToRecover(const QString& BoxName, const QString& FilePath, const QString& BoxPath, quint32 ProcessId) -{ - CSandBoxPtr pBox = theAPI->GetBoxByName(BoxName); - if ((!pBox.isNull() && pBox.objectCast()->IsRecoverySuspended()) || m_pDisableRecovery->isChecked()) - return; - - if (theConf->GetBool("Options/InstantRecovery", true)) - { - CRecoveryWindow* pWnd = ShowRecovery(pBox, false); - - //if (!theConf->GetBool("Options/AlwaysOnTop", false)) { - // SetWindowPos((HWND)pWnd->winId(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - // QTimer::singleShot(100, this, [pWnd]() { - // SetWindowPos((HWND)pWnd->winId(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - // }); - //} - - pWnd->AddFile(FilePath, BoxPath); - } - else - m_pPopUpWindow->AddFileToRecover(FilePath, BoxPath, pBox, ProcessId); -} - -bool CSandMan::OpenRecovery(const CSandBoxPtr& pBox, bool& DeleteShapshots, bool bCloseEmpty) -{ - auto pBoxEx = pBox.objectCast(); - if (!pBoxEx) return false; - if (pBoxEx->m_pRecoveryWnd != NULL) { - pBoxEx->m_pRecoveryWnd->close(); - // todo: resuse window? - } - - CRecoveryWindow* pRecoveryWindow = new CRecoveryWindow(pBox, false, this); - if (pRecoveryWindow->FindFiles() == 0 && bCloseEmpty) { - delete pRecoveryWindow; - } - else if (pRecoveryWindow->exec() != 1) - return false; - DeleteShapshots = pRecoveryWindow->IsDeleteShapshots(); - return true; -} - -CRecoveryWindow* CSandMan::ShowRecovery(const CSandBoxPtr& pBox, bool bFind) -{ - auto pBoxEx = pBox.objectCast(); - if (!pBoxEx) return false; - if (pBoxEx->m_pRecoveryWnd == NULL) { - pBoxEx->m_pRecoveryWnd = new CRecoveryWindow(pBox, bFind == false); - connect(pBoxEx->m_pRecoveryWnd, &CRecoveryWindow::Closed, [pBoxEx]() { - pBoxEx->m_pRecoveryWnd = NULL; - }); - pBoxEx->m_pRecoveryWnd->show(); - } - /*else { - pBoxEx->m_pRecoveryWnd->setWindowState((pBoxEx->m_pRecoveryWnd->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); - //SetForegroundWindow((HWND)pBoxEx->m_pRecoveryWnd->winId()); - }*/ - if(bFind) - pBoxEx->m_pRecoveryWnd->FindFiles(); - return pBoxEx->m_pRecoveryWnd; -} - -SB_PROGRESS CSandMan::RecoverFiles(const QString& BoxName, const QList>& FileList, int Action) -{ - CSbieProgressPtr pProgress = CSbieProgressPtr(new CSbieProgress()); - QtConcurrent::run(CSandMan::RecoverFilesAsync, pProgress, BoxName, FileList, Action); - return SB_PROGRESS(OP_ASYNC, pProgress); -} - -void CSandMan::RecoverFilesAsync(const CSbieProgressPtr& pProgress, const QString& BoxName, const QList>& FileList, int Action) -{ - SB_STATUS Status = SB_OK; - - int OverwriteOnExist = -1; - - QStringList Unrecovered; - for (QList>::const_iterator I = FileList.begin(); I != FileList.end(); ++I) - { - QString BoxPath = I->first; - QString RecoveryPath = I->second; - QString FileName = BoxPath.mid(BoxPath.lastIndexOf("\\") + 1); - QString RecoveryFolder = RecoveryPath.left(RecoveryPath.lastIndexOf("\\") + 1); - - pProgress->ShowMessage(tr("Recovering file %1 to %2").arg(FileName).arg(RecoveryFolder)); - - QDir().mkpath(RecoveryFolder); - if (QFile::exists(RecoveryPath)) - { - int Overwrite = OverwriteOnExist; - if (Overwrite == -1) - { - bool forAll = false; - int retVal = 0; - QMetaObject::invokeMethod(theGUI, "ShowQuestion", Qt::BlockingQueuedConnection, // show this question using the GUI thread - Q_RETURN_ARG(int, retVal), - Q_ARG(QString, tr("The file %1 already exists, do you want to overwrite it?").arg(RecoveryPath)), - Q_ARG(QString, tr("Do this for all files!")), - Q_ARG(bool*, &forAll), - Q_ARG(int, QDialogButtonBox::Yes | QDialogButtonBox::No), - Q_ARG(int, QDialogButtonBox::No) - ); - - Overwrite = retVal == QDialogButtonBox::Yes ? 1 : 0; - if (forAll) - OverwriteOnExist = Overwrite; - } - if (Overwrite == 1) - QFile::remove(RecoveryPath); - } - - if (!QFile::rename(BoxPath, RecoveryPath)) - Unrecovered.append(BoxPath); - else { - QMetaObject::invokeMethod(theGUI, "OnFileRecovered", Qt::BlockingQueuedConnection, // show this question using the GUI thread - Q_ARG(QString, BoxName), - Q_ARG(QString, RecoveryPath), - Q_ARG(QString, BoxPath) - ); - } - } - - if (!Unrecovered.isEmpty()) - Status = SB_ERR(SB_Message, QVariantList () << (tr("Failed to recover some files: \n") + Unrecovered.join("\n"))); - else if(FileList.count() == 1 && Action != 0) - { - std::wstring path = FileList.first().second.toStdWString(); - switch (Action) - { - case 1: // open - ShellExecute(NULL, NULL, path.c_str(), NULL, NULL, SW_SHOWNORMAL); - break; - case 2: // explore - ShellExecute(NULL, NULL, L"explorer.exe", (L"/select,\"" + path + L"\"").c_str(), NULL, SW_SHOWNORMAL); - break; - } - } - - - pProgress->Finish(Status); -} - -void CSandMan::OnFileRecovered(const QString& BoxName, const QString& FilePath, const QString& BoxPath) -{ - QTreeWidgetItem* pItem = new QTreeWidgetItem(); // Time|Box|FilePath - pItem->setText(0, QDateTime::currentDateTime().toString("hh:mm:ss.zzz")); - pItem->setText(1, BoxName); - pItem->setText(2, FilePath); - m_pRecoveryLog->GetTree()->addTopLevelItem(pItem); - - m_pRecoveryLog->GetView()->verticalScrollBar()->setValue(m_pRecoveryLog->GetView()->verticalScrollBar()->maximum()); - - CSandBoxPtr pBox = theAPI->GetBoxByName(BoxName); - if (pBox) - pBox.objectCast()->UpdateSize(); -} +#include "SandManRecovery.cpp" int CSandMan::ShowQuestion(const QString& question, const QString& checkBoxText, bool* checkBoxSetting, int buttons, int defaultButton) { @@ -1645,14 +1556,23 @@ void CSandMan::OnBoxDblClick(QTreeWidgetItem* pItem) m_pBoxView->ShowOptions(pItem->data(0, Qt::UserRole).toString()); } -void CSandMan::OnNewBox() +void CSandMan::OnSandBoxAction() { - m_pBoxView->AddNewBox(); -} + QAction* pAction = qobject_cast(sender()); -void CSandMan::OnNewGroupe() -{ - m_pBoxView->AddNewGroup(); + if(pAction == m_pNewBox) + GetBoxView()->AddNewBox(); + else if(pAction == m_pNewGroup) + GetBoxView()->AddNewGroup(); + + // for old menu + else + { + CSettingsWindow* pSettingsWindow = new CSettingsWindow(this); + connect(pSettingsWindow, SIGNAL(OptionsChanged(bool)), this, SLOT(UpdateSettings(bool))); + int Tab = pAction->data().toInt(); + pSettingsWindow->showTab(Tab); + } } void CSandMan::OnEmptyAll() @@ -1873,9 +1793,9 @@ void CSandMan::HandleMaintenance(SB_RESULT(void*) Status) void CSandMan::OnViewMode(QAction* pAction) { - bool bAdvanced = pAction->data().toBool(); - theConf->SetValue("Options/AdvancedView", bAdvanced); - SetViewMode(bAdvanced); + int iViewMode = pAction->data().toInt(); + theConf->SetValue("Options/ViewMode", iViewMode); + UpdateSettings(true); } void CSandMan::OnAlwaysTop() @@ -1890,42 +1810,6 @@ void CSandMan::OnAlwaysTop() LoadState(); } -void CSandMan::SetViewMode(bool bAdvanced) -{ - if (bAdvanced) - { - for (int i = m_iMenuViewPos; i < m_pMenuView->actions().count(); i++) - m_pMenuView->actions().at(i)->setVisible(true); - - if (m_pMenuHelp->actions().first() != m_pSupport) { - m_pMenuHelp->insertAction(m_pMenuHelp->actions().first(), m_pSupport); - menuBar()->removeAction(m_pSupport); - } - - m_pToolBar->show(); - m_pLogTabs->show(); - if (theConf->GetBool("Options/NoStatusBar", false)) - statusBar()->hide(); - else { - statusBar()->show(); - //if (theConf->GetBool("Options/NoSizeGrip", false)) - // statusBar()->setSizeGripEnabled(false); - } - } - else - { - for (int i = m_iMenuViewPos; i < m_pMenuView->actions().count(); i++) - m_pMenuView->actions().at(i)->setVisible(false); - - m_pMenuHelp->removeAction(m_pSupport); - menuBar()->addAction(m_pSupport); - - m_pToolBar->hide(); - m_pLogTabs->hide(); - statusBar()->hide(); - } -} - void CSandMan::OnRefresh() { if (!theAPI->IsConnected()) @@ -1942,22 +1826,22 @@ void CSandMan::OnRefresh() void CSandMan::OnCleanUp() { if (sender() == m_pCleanUpMsgLog || sender() == m_pCleanUpButton) - m_pMessageLog->GetTree()->clear(); + if(m_pMessageLog) m_pMessageLog->GetTree()->clear(); if (sender() == m_pCleanUpTrace || sender() == m_pCleanUpButton) - m_pTraceView->Clear(); + if(m_pTraceView) m_pTraceView->Clear(); if (sender() == m_pCleanUpRecovery || sender() == m_pCleanUpButton) - m_pRecoveryLog->GetTree()->clear(); + if(m_pRecoveryLog) m_pRecoveryLog->GetTree()->clear(); if (sender() == m_pCleanUpProcesses || sender() == m_pCleanUpButton) - theAPI->UpdateProcesses(false, m_pShowAllSessions->isChecked()); + theAPI->UpdateProcesses(false, ShowAllSessions()); } void CSandMan::OnProcView() { - theConf->SetValue("Options/KeepTerminated", m_pKeepTerminated->isChecked()); - theConf->SetValue("Options/ShowAllSessions", m_pShowAllSessions->isChecked()); + if(m_pKeepTerminated) theConf->SetValue("Options/KeepTerminated", m_pKeepTerminated->isChecked()); + if(m_pShowAllSessions) theConf->SetValue("Options/ShowAllSessions", m_pShowAllSessions->isChecked()); } void CSandMan::OnSettings() @@ -1966,7 +1850,7 @@ void CSandMan::OnSettings() if (pSettingsWindow == NULL) { pSettingsWindow = new CSettingsWindow(); - connect(pSettingsWindow, SIGNAL(OptionsChanged()), this, SLOT(UpdateSettings())); + connect(pSettingsWindow, SIGNAL(OptionsChanged(bool)), this, SLOT(UpdateSettings(bool))); connect(pSettingsWindow, &CSettingsWindow::Closed, [this]() { pSettingsWindow = NULL; }); @@ -1974,13 +1858,11 @@ void CSandMan::OnSettings() } } -void CSandMan::UpdateSettings() +void CSandMan::UpdateSettings(bool bRebuildUI) { m_pTrayBoxes->clear(); // force refresh - SetUITheme(); - m_pTrayBoxes->setStyle(QStyleFactory::create(m_DefaultStyle)); - //m_pBoxView->UpdateRunMenu(); + //GetBoxView()->UpdateRunMenu(); SetupHotKeys(); @@ -1989,31 +1871,29 @@ void CSandMan::UpdateSettings() else m_pTrayIcon->hide(); - if (m_Language != theConf->GetString("Options/UiLanguage")) - { - theConf->SetBlob("MainWindow/Log_Splitter", m_pLogSplitter->saveState()); + if (bRebuildUI) + { LoadLanguage(); - QTreeViewEx::m_ResetColumns = tr("Reset Columns"); - CPanelView::m_CopyCell = tr("Copy Cell"); - CPanelView::m_CopyRow = tr("Copy Row"); - CPanelView::m_CopyPanel = tr("Copy Panel"); + StoreState(); - menuBar()->clear(); - CreateMenus(); - - m_pMainLayout->removeWidget(m_pLogSplitter); - m_pLogSplitter->deleteLater(); - CreateView(); - m_pBoxView->ReloadUserConfig(); + m_pMainWidget->deleteLater(); + m_pMainWidget = new QWidget(this); + CreateUI(); + setCentralWidget(m_pMainWidget); m_pTrayMenu->deleteLater(); CreateTrayMenu(); - UpdateLabel(); + LoadState(); - m_pLogSplitter->restoreState(theConf->GetBlob("MainWindow/Log_Splitter")); + GetBoxView()->ReloadUserConfig(); + + OnStatusChanged(); + + SetUITheme(); + m_pTrayBoxes->setStyle(QStyleFactory::create(m_DefaultStyle)); } } @@ -2148,14 +2028,31 @@ void CSandMan::OnIniReloaded() m_pPopUpWindow->ReloadHiddenMessages(); } -void CSandMan::OnSetMonitoring() +void CSandMan::OnMonitoring() { - theAPI->EnableMonitor(m_pEnableMonitoring->isChecked()); + if (m_pTraceView) + { + theAPI->EnableMonitor(m_pEnableMonitoring->isChecked()); - if(m_pEnableMonitoring->isChecked() && !m_pToolBar->isVisible()) - m_pLogTabs->show(); + if(m_pEnableMonitoring->isChecked() && !m_pToolBar->isVisible()) + m_pLogTabs->show(); - //m_pTraceView->setEnabled(m_pEnableMonitoring->isChecked()); + //m_pTraceView->setEnabled(m_pEnableMonitoring->isChecked()); + } + else + { + theAPI->EnableMonitor(true); + + static CTraceWindow* pTraceWindow = NULL; + if (!pTraceWindow) { + pTraceWindow = new CTraceWindow(); + //pTraceWindow->setAttribute(Qt::WA_DeleteOnClose); + connect(pTraceWindow, &CTraceWindow::Closed, [&]() { + pTraceWindow = NULL; + }); + SafeShow(pTraceWindow); + } + } } SB_STATUS CSandMan::AddAsyncOp(const CSbieProgressPtr& pProgress, bool bWait, const QString& InitialMsg) @@ -2292,138 +2189,6 @@ void CSandMan::CheckResults(QList Results) } } -void CSandMan::OnShowHide() -{ - if (isVisible()) { - StoreState(); - hide(); - } else - show(); -} - -void CSandMan::OnSysTray(QSystemTrayIcon::ActivationReason Reason) -{ - static bool TriggerSet = false; - static bool NullifyTrigger = false; - switch(Reason) - { - case QSystemTrayIcon::Context: - { - QMap Boxes = theAPI->GetAllBoxes(); - - int iSysTrayFilter = theConf->GetInt("Options/SysTrayFilter", 0); - - bool bAdded = false; - if (m_pTrayBoxes->topLevelItemCount() == 0) - bAdded = true; // triger size refresh - - QMap OldBoxes; - for(int i = 0; i < m_pTrayBoxes->topLevelItemCount(); ++i) - { - QTreeWidgetItem* pItem = m_pTrayBoxes->topLevelItem(i); - QString Name = pItem->data(0, Qt::UserRole).toString(); - OldBoxes.insert(Name,pItem); - } - - foreach(const CSandBoxPtr & pBox, Boxes) - { - if (!pBox->IsEnabled()) - continue; - - CSandBoxPlus* pBoxEx = qobject_cast(pBox.data()); - - if (iSysTrayFilter == 2) { // pinned only - if (!pBox->GetBool("PinToTray", false)) - continue; - } - else if (iSysTrayFilter == 1) { // active + pinned - if (pBoxEx->GetActiveProcessCount() == 0 && !pBox->GetBool("PinToTray", false)) - continue; - } - - QTreeWidgetItem* pItem = OldBoxes.take(pBox->GetName()); - if(!pItem) - { - pItem = new QTreeWidgetItem(); - pItem->setData(0, Qt::UserRole, pBox->GetName()); - pItem->setText(0, " " + pBox->GetName().replace("_", " ")); - m_pTrayBoxes->addTopLevelItem(pItem); - - bAdded = true; - } - - pItem->setData(0, Qt::DecorationRole, theGUI->GetBoxIcon(pBoxEx->GetType(), pBox->GetActiveProcessCount() != 0)); - } - - foreach(QTreeWidgetItem* pItem, OldBoxes) - delete pItem; - - if (!OldBoxes.isEmpty() || bAdded) - { - auto palette = m_pTrayBoxes->palette(); - palette.setColor(QPalette::Base, m_pTrayMenu->palette().color(m_DarkTheme ? QPalette::Base : QPalette::Window)); - m_pTrayBoxes->setPalette(palette); - m_pTrayBoxes->setFrameShape(QFrame::NoFrame); - - //const int FrameWidth = m_pTrayBoxes->style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - int Height = 0; //m_pTrayBoxes->header()->height() + (2 * FrameWidth); - - for (QTreeWidgetItemIterator AllIterator(m_pTrayBoxes, QTreeWidgetItemIterator::All); *AllIterator; ++AllIterator) - Height += m_pTrayBoxes->visualItemRect(*AllIterator).height(); - - QRect scrRect = this->screen()->availableGeometry(); - int MaxHeight = scrRect.height() / 2; - if (Height > MaxHeight) { - Height = MaxHeight; - if (Height < 64) - Height = 64; - } - - m_pTrayBoxes->setFixedHeight(Height); - - m_pTrayMenu->removeAction(m_pTrayList); - m_pTrayMenu->insertAction(m_pTraySeparator, m_pTrayList); - - m_pTrayBoxes->setFocus(); - } - - m_pTrayMenu->popup(QCursor::pos()); - break; - } - case QSystemTrayIcon::DoubleClick: - if (isVisible()) - { - if(TriggerSet) - NullifyTrigger = true; - - StoreState(); - hide(); - - if (theAPI->GetGlobalSettings()->GetBool("ForgetPassword", false)) - theAPI->ClearPassword(); - - break; - } - show(); - case QSystemTrayIcon::Trigger: - if (isVisible() && !TriggerSet) - { - TriggerSet = true; - QTimer::singleShot(100, [this]() { - TriggerSet = false; - if (NullifyTrigger) { - NullifyTrigger = false; - return; - } - this->setWindowState((this->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); - SetForegroundWindow(MainWndHandle); - } ); - } - m_pPopUpWindow->Poke(); - break; - } -} - void CSandMan::OpenUrl(const QUrl& url) { QString scheme = url.scheme(); @@ -2510,7 +2275,28 @@ void CSandMan::SetUITheme() QApplication::setPalette(m_DefaultPalett); } + QFont font = QApplication::font(); + double newFontSize = m_DefaultFontSize * theConf->GetInt("Options/FontScaling", 100) / 100.0; + if (newFontSize != font.pointSizeF()) { + font.setPointSizeF(newFontSize); + QApplication::setFont(font); + } + + int iUsePizza = theConf->GetInt("Options/UseBackground", 2); + if (iUsePizza == 2) + iUsePizza = theConf->GetInt("Options/ViewMode", 1) == 2 ? 1 : 0; + if (iUsePizza) + { + QPalette pizzaPalete = GetBoxView()->GetTree()->palette(); // QPalette pizzaPalete = QApplication::palette(); + SetPaleteTexture(pizzaPalete, QPalette::Base, QImage(":/Assets/background.png")); + GetBoxView()->GetTree()->setPalette(pizzaPalete); // QApplication::setPalette(pizzaPalete); + } + else + GetBoxView()->GetTree()->setPalette(QApplication::palette()); + + m_DarkTheme = bDark; + CTreeItemModel::SetDarkMode(bDark); CListItemModel::SetDarkMode(bDark); CPopUpWindow::SetDarkMode(bDark); @@ -2532,7 +2318,6 @@ void CSandMan::LoadLanguage() QString Lang = theConf->GetString("Options/UiLanguage"); if(Lang.isEmpty()) Lang = QLocale::system().name(); - m_Language = Lang; if (Lang.compare("native", Qt::CaseInsensitive) == 0) Lang.clear(); @@ -2543,6 +2328,12 @@ void CSandMan::LoadLanguage() LoadLanguage(Lang, "sandman", 0); LoadLanguage(Lang, "qt", 1); + + + QTreeViewEx::m_ResetColumns = tr("Reset Columns"); + CPanelView::m_CopyCell = tr("Copy Cell"); + CPanelView::m_CopyRow = tr("Copy Row"); + CPanelView::m_CopyPanel = tr("Copy Panel"); } void CSandMan::LoadLanguage(const QString& Lang, const QString& Module, int Index) @@ -2566,6 +2357,61 @@ void CSandMan::LoadLanguage(const QString& Lang, const QString& Module, int Inde } } +void CSandMan::OnHelp() +{ + if (sender() == m_pSupport) + QDesktopServices::openUrl(QUrl("https://sandboxie-plus.com/go.php?to=donate")); + else if (sender() == m_pForum) + QDesktopServices::openUrl(QUrl("https://sandboxie-plus.com/go.php?to=sbie-forum")); + else if (sender() == m_pManual) + QDesktopServices::openUrl(QUrl("https://sandboxie-plus.com/go.php?to=sbie-docs")); + else + QDesktopServices::openUrl(QUrl("https://sandboxie-plus.com/go.php?to=patreon")); +} + +void CSandMan::OnAbout() +{ + if (sender() == m_pAbout) + { + QString AboutCaption = tr( + "

About Sandboxie-Plus

" + "

Version %1

" + "

Copyright (c) 2020-2022 by DavidXanatos

" + ).arg(theGUI->GetVersion()); + + QString CertInfo; + if (!g_Certificate.isEmpty()) { + CertInfo = tr("This copy of Sandboxie+ is certified for: %1").arg(GetArguments(g_Certificate, L'\n', L':').value("NAME")); + } else { + CertInfo = tr("Sandboxie+ is free for personal and non-commercial use."); + } + + QString AboutText = tr( + "Sandboxie-Plus is an open source continuation of Sandboxie.
" + "Visit sandboxie-plus.com for more information.
" + "
" + "%3
" + "
" + "Driver version: %1
" + "Features: %2
" + "
" + "Icons from icons8.com" + ).arg(theAPI->GetVersion()).arg(theAPI->GetFeatureStr()).arg(CertInfo); + + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setAttribute(Qt::WA_DeleteOnClose); + msgBox->setWindowTitle(tr("About Sandboxie-Plus")); + msgBox->setText(AboutCaption); + msgBox->setInformativeText(AboutText); + + QIcon ico(QLatin1String(":/SandMan.png")); + msgBox->setIconPixmap(ico.pixmap(128, 128)); + + SafeExec(msgBox); + } + else if (sender() == m_pAboutQt) + QMessageBox::aboutQt(this); +} // Make sure that QPlatformTheme strings won't be marked as vanished in all .ts files, even after running lupdate diff --git a/SandboxiePlus/SandMan/SandMan.h b/SandboxiePlus/SandMan/SandMan.h index 99acb08c..1cdd105d 100644 --- a/SandboxiePlus/SandMan/SandMan.h +++ b/SandboxiePlus/SandMan/SandMan.h @@ -52,16 +52,18 @@ public: bool IsFullyPortable(); - bool IsShowHidden() { return m_pShowHidden->isChecked(); } - + bool IsShowHidden() { return m_pShowHidden && m_pShowHidden->isChecked(); } + bool KeepTerminated() { return m_pKeepTerminated && m_pKeepTerminated->isChecked(); } + bool ShowAllSessions() { return m_pShowAllSessions && m_pShowAllSessions->isChecked(); } + bool IsDisableRecovery() {return m_pDisableRecovery && m_pDisableRecovery->isChecked();} + bool IsDisableMessages() {return m_pDisableMessages && m_pDisableMessages->isChecked();} CSbieView* GetBoxView() { return m_pBoxView; } bool RunSandboxed(const QStringList& Commands, const QString& BoxName, const QString& WrkDir = QString()); - QIcon GetBoxIcon(int boxType, bool inUse = false, bool inBusy = false); + QIcon GetBoxIcon(int boxType, bool inUse = false);// , bool inBusy = false); + QIcon MakeIconBusy(const QIcon& Icon, int Index = 0); QString GetBoxDescription(int boxType); - - void SetViewMode(bool bAdvanced); bool CheckCertificate(); @@ -120,7 +122,7 @@ protected: struct SBoxIcon { QIcon Empty; QIcon InUse; - QIcon Busy; + //QIcon Busy; }; QMap m_BoxIcons; @@ -142,7 +144,7 @@ public slots: bool OpenRecovery(const CSandBoxPtr& pBox, bool& DeleteShapshots, bool bCloseEmpty = false); class CRecoveryWindow* ShowRecovery(const CSandBoxPtr& pBox, bool bFind = true); - void UpdateSettings(); + void UpdateSettings(bool bRebuildUI); void OnIniReloaded(); void SetupHotKeys(); @@ -168,12 +170,10 @@ public slots: void OnBoxDblClick(QTreeWidgetItem*); private slots: - void OnSelectionChanged(); void OnMenuHover(QAction* action); - void OnNewBox(); - void OnNewGroupe(); + void OnSandBoxAction(); void OnEmptyAll(); void OnWndFinder(); void OnDisableForce(); @@ -191,7 +191,7 @@ private slots: void OnResetGUI(); void OnEditIni(); void OnReloadIni(); - void OnSetMonitoring(); + void OnMonitoring(); void OnExit(); void OnHelp(); @@ -208,12 +208,23 @@ private slots: void SetUITheme(); + void AddLogMessage(const QString& Message); + void AddFileRecovered(const QString& BoxName, const QString& FilePath); + void UpdateLabel(); private: - void CreateMenus(); + + void CreateUI(); + + void CreateMenus(bool bAdvanced); + void CreateOldMenus(); + void CreateMaintenanceMenu(); + void CreateViewBaseMenu(); + void CreateHelpMenu(bool bAdvanced); void CreateToolBar(); - void CreateView(); + void CreateView(bool bAdvanced); + void CreateTrayIcon(); void CreateTrayMenu(); void HandleMaintenance(SB_RESULT(void*) Status); @@ -270,7 +281,6 @@ private: QActionGroup* m_pViewMode; QAction* m_pShowHidden; QAction* m_pWndTopMost; - int m_iMenuViewPos; QAction* m_pRefreshAll; QMenu* m_pCleanUpMenu; QAction* m_pCleanUpProcesses; @@ -300,6 +310,11 @@ private: QAction* m_pAbout; QAction* m_pAboutQt; + + // for old menu + QMenu* m_pSandbox; + + QSystemTrayIcon* m_pTrayIcon; QMenu* m_pTrayMenu; QAction* m_pTraySeparator; @@ -320,13 +335,13 @@ private: bool m_ThemeUpdatePending; QString m_DefaultStyle; QPalette m_DefaultPalett; + double m_DefaultFontSize; void LoadLanguage(); void LoadLanguage(const QString& Lang, const QString& Module, int Index); QTranslator m_Translator[2]; public: - QString m_Language; quint32 m_LanguageId; bool m_DarkTheme; }; diff --git a/SandboxiePlus/SandMan/SandMan.vcxproj b/SandboxiePlus/SandMan/SandMan.vcxproj index 7d748a3c..29683b16 100644 --- a/SandboxiePlus/SandMan/SandMan.vcxproj +++ b/SandboxiePlus/SandMan/SandMan.vcxproj @@ -208,6 +208,18 @@ + + true + true + true + true + + + true + true + true + true + true true @@ -361,6 +373,7 @@ + diff --git a/SandboxiePlus/SandMan/SandMan.vcxproj.filters b/SandboxiePlus/SandMan/SandMan.vcxproj.filters index 285595b6..0c47e9f2 100644 --- a/SandboxiePlus/SandMan/SandMan.vcxproj.filters +++ b/SandboxiePlus/SandMan/SandMan.vcxproj.filters @@ -168,6 +168,12 @@ SandMan + + SandMan + + + SandMan + @@ -348,6 +354,9 @@ Translation Files + + Translation Files + diff --git a/SandboxiePlus/SandMan/SandManRecovery.cpp b/SandboxiePlus/SandMan/SandManRecovery.cpp new file mode 100644 index 00000000..92a18aaf --- /dev/null +++ b/SandboxiePlus/SandMan/SandManRecovery.cpp @@ -0,0 +1,165 @@ + +void CSandMan::OnFileToRecover(const QString& BoxName, const QString& FilePath, const QString& BoxPath, quint32 ProcessId) +{ + CSandBoxPtr pBox = theAPI->GetBoxByName(BoxName); + if ((!pBox.isNull() && pBox.objectCast()->IsRecoverySuspended()) || IsDisableRecovery()) + return; + + if (theConf->GetBool("Options/InstantRecovery", true)) + { + CRecoveryWindow* pWnd = ShowRecovery(pBox, false); + + //if (!theConf->GetBool("Options/AlwaysOnTop", false)) { + // SetWindowPos((HWND)pWnd->winId(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + // QTimer::singleShot(100, this, [pWnd]() { + // SetWindowPos((HWND)pWnd->winId(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + // }); + //} + + pWnd->AddFile(FilePath, BoxPath); + } + else + m_pPopUpWindow->AddFileToRecover(FilePath, BoxPath, pBox, ProcessId); +} + +bool CSandMan::OpenRecovery(const CSandBoxPtr& pBox, bool& DeleteShapshots, bool bCloseEmpty) +{ + auto pBoxEx = pBox.objectCast(); + if (!pBoxEx) return false; + if (pBoxEx->m_pRecoveryWnd != NULL) { + pBoxEx->m_pRecoveryWnd->close(); + // todo: resuse window? + } + + CRecoveryWindow* pRecoveryWindow = new CRecoveryWindow(pBox, false, this); + if (pRecoveryWindow->FindFiles() == 0 && bCloseEmpty) { + delete pRecoveryWindow; + return true; + } + else if (pRecoveryWindow->exec() != 1) + return false; + DeleteShapshots = pRecoveryWindow->IsDeleteShapshots(); + return true; +} + +CRecoveryWindow* CSandMan::ShowRecovery(const CSandBoxPtr& pBox, bool bFind) +{ + auto pBoxEx = pBox.objectCast(); + if (!pBoxEx) return false; + if (pBoxEx->m_pRecoveryWnd == NULL) { + pBoxEx->m_pRecoveryWnd = new CRecoveryWindow(pBox, bFind == false); + connect(pBoxEx->m_pRecoveryWnd, &CRecoveryWindow::Closed, [pBoxEx]() { + pBoxEx->m_pRecoveryWnd = NULL; + }); + pBoxEx->m_pRecoveryWnd->show(); + } + /*else { + pBoxEx->m_pRecoveryWnd->setWindowState((pBoxEx->m_pRecoveryWnd->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); + //SetForegroundWindow((HWND)pBoxEx->m_pRecoveryWnd->winId()); + }*/ + if(bFind) + pBoxEx->m_pRecoveryWnd->FindFiles(); + return pBoxEx->m_pRecoveryWnd; +} + +SB_PROGRESS CSandMan::RecoverFiles(const QString& BoxName, const QList>& FileList, int Action) +{ + CSbieProgressPtr pProgress = CSbieProgressPtr(new CSbieProgress()); + QtConcurrent::run(CSandMan::RecoverFilesAsync, pProgress, BoxName, FileList, Action); + return SB_PROGRESS(OP_ASYNC, pProgress); +} + +void CSandMan::RecoverFilesAsync(const CSbieProgressPtr& pProgress, const QString& BoxName, const QList>& FileList, int Action) +{ + SB_STATUS Status = SB_OK; + + int OverwriteOnExist = -1; + + QStringList Unrecovered; + for (QList>::const_iterator I = FileList.begin(); I != FileList.end(); ++I) + { + QString BoxPath = I->first; + QString RecoveryPath = I->second; + QString FileName = BoxPath.mid(BoxPath.lastIndexOf("\\") + 1); + QString RecoveryFolder = RecoveryPath.left(RecoveryPath.lastIndexOf("\\") + 1); + + pProgress->ShowMessage(tr("Recovering file %1 to %2").arg(FileName).arg(RecoveryFolder)); + + QDir().mkpath(RecoveryFolder); + if (QFile::exists(RecoveryPath)) + { + int Overwrite = OverwriteOnExist; + if (Overwrite == -1) + { + bool forAll = false; + int retVal = 0; + QMetaObject::invokeMethod(theGUI, "ShowQuestion", Qt::BlockingQueuedConnection, // show this question using the GUI thread + Q_RETURN_ARG(int, retVal), + Q_ARG(QString, tr("The file %1 already exists, do you want to overwrite it?").arg(RecoveryPath)), + Q_ARG(QString, tr("Do this for all files!")), + Q_ARG(bool*, &forAll), + Q_ARG(int, QDialogButtonBox::Yes | QDialogButtonBox::No), + Q_ARG(int, QDialogButtonBox::No) + ); + + Overwrite = retVal == QDialogButtonBox::Yes ? 1 : 0; + if (forAll) + OverwriteOnExist = Overwrite; + } + if (Overwrite == 1) + QFile::remove(RecoveryPath); + } + + if (!QFile::rename(BoxPath, RecoveryPath)) + Unrecovered.append(BoxPath); + else { + QMetaObject::invokeMethod(theGUI, "OnFileRecovered", Qt::BlockingQueuedConnection, // show this question using the GUI thread + Q_ARG(QString, BoxName), + Q_ARG(QString, RecoveryPath), + Q_ARG(QString, BoxPath) + ); + } + } + + if (!Unrecovered.isEmpty()) + Status = SB_ERR(SB_Message, QVariantList () << (tr("Failed to recover some files: \n") + Unrecovered.join("\n"))); + else if(FileList.count() == 1 && Action != 0) + { + std::wstring path = FileList.first().second.toStdWString(); + switch (Action) + { + case 1: // open + ShellExecute(NULL, NULL, path.c_str(), NULL, NULL, SW_SHOWNORMAL); + break; + case 2: // explore + ShellExecute(NULL, NULL, L"explorer.exe", (L"/select,\"" + path + L"\"").c_str(), NULL, SW_SHOWNORMAL); + break; + } + } + + + pProgress->Finish(Status); +} + +void CSandMan::AddFileRecovered(const QString& BoxName, const QString& FilePath) +{ + if (!m_pRecoveryLog) + return; + + QTreeWidgetItem* pItem = new QTreeWidgetItem(); // Time|Box|FilePath + pItem->setText(0, QDateTime::currentDateTime().toString("hh:mm:ss.zzz")); + pItem->setText(1, BoxName); + pItem->setText(2, FilePath); + m_pRecoveryLog->GetTree()->addTopLevelItem(pItem); + + m_pRecoveryLog->GetView()->verticalScrollBar()->setValue(m_pRecoveryLog->GetView()->verticalScrollBar()->maximum()); +} + +void CSandMan::OnFileRecovered(const QString& BoxName, const QString& FilePath, const QString& BoxPath) +{ + AddFileRecovered(BoxName, FilePath); + + CSandBoxPtr pBox = theAPI->GetBoxByName(BoxName); + if (pBox) + pBox.objectCast()->UpdateSize(); +} diff --git a/SandboxiePlus/SandMan/SandManTray.cpp b/SandboxiePlus/SandMan/SandManTray.cpp new file mode 100644 index 00000000..c145ec33 --- /dev/null +++ b/SandboxiePlus/SandMan/SandManTray.cpp @@ -0,0 +1,305 @@ + +#include +class CTrayBoxesItemDelegate : public QStyledItemDelegate +{ + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const + { + QStyleOptionViewItem opt(option); + if ((opt.state & QStyle::State_MouseOver) != 0) + opt.state |= QStyle::State_Selected; + else if ((opt.state & QStyle::State_HasFocus) != 0 && m_Hold) + opt.state |= QStyle::State_Selected; + opt.state &= ~QStyle::State_HasFocus; + QStyledItemDelegate::paint(painter, opt, index); + } +public: + static bool m_Hold; +}; + +bool CTrayBoxesItemDelegate::m_Hold = false; + +void CSandMan::CreateTrayIcon() +{ + m_pTrayIcon = new QSystemTrayIcon(GetTrayIcon(), this); + m_pTrayIcon->setToolTip(GetTrayText()); + connect(m_pTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(OnSysTray(QSystemTrayIcon::ActivationReason))); + m_bIconEmpty = true; + m_bIconDisabled = false; + m_bIconBusy = false; + m_iDeletingContent = 0; + + CreateTrayMenu(); + + bool bAutoRun = QApplication::arguments().contains("-autorun"); + + if(g_PendingMessage.isEmpty()){ + m_pTrayIcon->show(); // Note: qt bug; hide does not work if not showing first :/ + if(!bAutoRun && theConf->GetInt("Options/SysTrayIcon", 1) == 0) + m_pTrayIcon->hide(); + } +} + +void CSandMan::CreateTrayMenu() +{ + m_pTrayMenu = new QMenu(); + QAction* pShowHide = m_pTrayMenu->addAction(GetIcon("IconFull", false), tr("Show/Hide"), this, SLOT(OnShowHide())); + QFont f = pShowHide->font(); + f.setBold(true); + pShowHide->setFont(f); + m_pTrayMenu->addSeparator(); + + m_pTrayList = new QWidgetAction(m_pTrayMenu); + + QWidget* pWidget = new CActionWidget(); + QHBoxLayout* pLayout = new QHBoxLayout(); + pLayout->setMargin(0); + pWidget->setLayout(pLayout); + + m_pTrayBoxes = new QTreeWidget(); + + m_pTrayBoxes->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Maximum); + m_pTrayBoxes->setRootIsDecorated(false); + //m_pTrayBoxes->setHeaderLabels(tr(" Sandbox").split("|")); + m_pTrayBoxes->setHeaderHidden(true); + m_pTrayBoxes->setSelectionMode(QAbstractItemView::NoSelection); + //m_pTrayBoxes->setSelectionMode(QAbstractItemView::ExtendedSelection); + //m_pTrayBoxes->setStyleSheet("QTreeView::item:hover{background-color:#FFFF00;}"); + m_pTrayBoxes->setItemDelegate(new CTrayBoxesItemDelegate()); + + m_pTrayBoxes->setStyle(QStyleFactory::create(m_DefaultStyle)); + + pLayout->insertSpacing(0, 1);// 32); + + /*QFrame* vFrame = new QFrame; + vFrame->setFixedWidth(1); + vFrame->setFrameShape(QFrame::VLine); + vFrame->setFrameShadow(QFrame::Raised); + pLayout->addWidget(vFrame);*/ + + pLayout->addWidget(m_pTrayBoxes); + + m_pTrayList->setDefaultWidget(pWidget); + m_pTrayMenu->addAction(m_pTrayList); + + + m_pTrayBoxes->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_pTrayBoxes, SIGNAL(customContextMenuRequested( const QPoint& )), this, SLOT(OnBoxMenu(const QPoint &))); + connect(m_pTrayBoxes, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(OnBoxDblClick(QTreeWidgetItem*))); + //m_pBoxMenu + + m_pTraySeparator = m_pTrayMenu->addSeparator(); + m_pTrayMenu->addAction(m_pEmptyAll); + m_pDisableForce2 = m_pTrayMenu->addAction(tr("Pause Forcing Programs"), this, SLOT(OnDisableForce2())); + m_pDisableForce2->setCheckable(true); + if(m_pDisableRecovery) m_pTrayMenu->addAction(m_pDisableRecovery); + if(m_pDisableMessages) m_pTrayMenu->addAction(m_pDisableMessages); + m_pTrayMenu->addSeparator(); + + /*QWidgetAction* pBoxWidget = new QWidgetAction(m_pTrayMenu); + + QWidget* pWidget = new QWidget(); + pWidget->setMaximumHeight(200); + QGridLayout* pLayout = new QGridLayout(); + pLayout->addWidget(pBar, 0, 0); + pWidget->setLayout(pLayout); + pBoxWidget->setDefaultWidget(pWidget);*/ + + /*QLabel* pLabel = new QLabel("test"); + pLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + pLabel->setAlignment(Qt::AlignCenter); + pBoxWidget->setDefaultWidget(pLabel);*/ + + //m_pTrayMenu->addAction(pBoxWidget); + //m_pTrayMenu->addSeparator(); + + m_pTrayMenu->addAction(m_pExit); +} + +QIcon CSandMan::GetTrayIcon(bool isConnected) +{ + bool bClassic = (theConf->GetInt("Options/SysTrayIcon", 1) == 2); + + QString IconFile; + if (isConnected) { + if (m_bIconEmpty) + IconFile = "IconEmpty"; + else + IconFile = "IconFull"; + } else + IconFile = "IconOff"; + if (bClassic) IconFile += "C"; + + QSize size = QSize(16, 16); + QPixmap result(size); + result.fill(Qt::transparent); // force alpha channel + QPainter painter(&result); + QPixmap base = GetIcon(IconFile, false).pixmap(size); + QPixmap overlay; + + if (m_bIconBusy) { + IconFile = "IconBusy"; + if (bClassic) { // classic has a different icon instead of an overlay + IconFile += "C"; + base = GetIcon(IconFile, false).pixmap(size); + } + else + overlay = GetIcon(IconFile, false).pixmap(size); + } + + painter.drawPixmap(0, 0, base); + if(!overlay.isNull()) painter.drawPixmap(0, 0, overlay); + + if (m_bIconDisabled) { + IconFile = "IconDFP"; + if (bClassic) IconFile += "C"; + overlay = GetIcon(IconFile, false).pixmap(size); + painter.drawPixmap(0, 0, overlay); + } + + return QIcon(result); +} + +QString CSandMan::GetTrayText(bool isConnected) +{ + QString Text = "Sandboxie-Plus"; + + if(!isConnected) + Text += tr(" - Driver/Service NOT Running!"); + else if(m_iDeletingContent) + Text += tr(" - Deleting Sandbox Content"); + + return Text; +} + +void CSandMan::OnShowHide() +{ + if (isVisible()) { + StoreState(); + hide(); + } else + show(); +} + +void CSandMan::OnSysTray(QSystemTrayIcon::ActivationReason Reason) +{ + static bool TriggerSet = false; + static bool NullifyTrigger = false; + switch(Reason) + { + case QSystemTrayIcon::Context: + { + QMap Boxes = theAPI->GetAllBoxes(); + + int iSysTrayFilter = theConf->GetInt("Options/SysTrayFilter", 0); + + bool bAdded = false; + if (m_pTrayBoxes->topLevelItemCount() == 0) + bAdded = true; // triger size refresh + + QMap OldBoxes; + for(int i = 0; i < m_pTrayBoxes->topLevelItemCount(); ++i) + { + QTreeWidgetItem* pItem = m_pTrayBoxes->topLevelItem(i); + QString Name = pItem->data(0, Qt::UserRole).toString(); + OldBoxes.insert(Name,pItem); + } + + foreach(const CSandBoxPtr & pBox, Boxes) + { + if (!pBox->IsEnabled()) + continue; + + CSandBoxPlus* pBoxEx = qobject_cast(pBox.data()); + + if (iSysTrayFilter == 2) { // pinned only + if (!pBox->GetBool("PinToTray", false)) + continue; + } + else if (iSysTrayFilter == 1) { // active + pinned + if (pBoxEx->GetActiveProcessCount() == 0 && !pBox->GetBool("PinToTray", false)) + continue; + } + + QTreeWidgetItem* pItem = OldBoxes.take(pBox->GetName()); + if(!pItem) + { + pItem = new QTreeWidgetItem(); + pItem->setData(0, Qt::UserRole, pBox->GetName()); + pItem->setText(0, " " + pBox->GetName().replace("_", " ")); + m_pTrayBoxes->addTopLevelItem(pItem); + + bAdded = true; + } + + QIcon Icon = theGUI->GetBoxIcon(pBoxEx->GetType(), pBox->GetActiveProcessCount() != 0); + pItem->setData(0, Qt::DecorationRole, Icon); + } + + foreach(QTreeWidgetItem* pItem, OldBoxes) + delete pItem; + + if (!OldBoxes.isEmpty() || bAdded) + { + auto palette = m_pTrayBoxes->palette(); + palette.setColor(QPalette::Base, m_pTrayMenu->palette().color(m_DarkTheme ? QPalette::Base : QPalette::Window)); + m_pTrayBoxes->setPalette(palette); + m_pTrayBoxes->setFrameShape(QFrame::NoFrame); + + //const int FrameWidth = m_pTrayBoxes->style()->pixelMetric(QStyle::PM_DefaultFrameWidth); + int Height = 0; //m_pTrayBoxes->header()->height() + (2 * FrameWidth); + + for (QTreeWidgetItemIterator AllIterator(m_pTrayBoxes, QTreeWidgetItemIterator::All); *AllIterator; ++AllIterator) + Height += m_pTrayBoxes->visualItemRect(*AllIterator).height(); + + QRect scrRect = this->screen()->availableGeometry(); + int MaxHeight = scrRect.height() / 2; + if (Height > MaxHeight) { + Height = MaxHeight; + if (Height < 64) + Height = 64; + } + + m_pTrayBoxes->setFixedHeight(Height); + + m_pTrayMenu->removeAction(m_pTrayList); + m_pTrayMenu->insertAction(m_pTraySeparator, m_pTrayList); + + m_pTrayBoxes->setFocus(); + } + + m_pTrayMenu->popup(QCursor::pos()); + break; + } + case QSystemTrayIcon::DoubleClick: + if (isVisible()) + { + if(TriggerSet) + NullifyTrigger = true; + + StoreState(); + hide(); + + if (theAPI->GetGlobalSettings()->GetBool("ForgetPassword", false)) + theAPI->ClearPassword(); + + break; + } + show(); + case QSystemTrayIcon::Trigger: + if (isVisible() && !TriggerSet) + { + TriggerSet = true; + QTimer::singleShot(100, [this]() { + TriggerSet = false; + if (NullifyTrigger) { + NullifyTrigger = false; + return; + } + this->setWindowState((this->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); + SetForegroundWindow(MainWndHandle); + } ); + } + m_pPopUpWindow->Poke(); + break; + } +} diff --git a/SandboxiePlus/SandMan/SandManUpdate.cpp b/SandboxiePlus/SandMan/SandManUpdate.cpp index ef6a6f9a..e6788d0c 100644 --- a/SandboxiePlus/SandMan/SandManUpdate.cpp +++ b/SandboxiePlus/SandMan/SandManUpdate.cpp @@ -286,62 +286,6 @@ void CSandMan::InstallUpdate() } } -void CSandMan::OnHelp() -{ - if (sender() == m_pSupport) - QDesktopServices::openUrl(QUrl("https://sandboxie-plus.com/go.php?to=donate")); - else if (sender() == m_pForum) - QDesktopServices::openUrl(QUrl("https://sandboxie-plus.com/go.php?to=sbie-forum")); - else if (sender() == m_pManual) - QDesktopServices::openUrl(QUrl("https://sandboxie-plus.com/go.php?to=sbie-docs")); - else - QDesktopServices::openUrl(QUrl("https://sandboxie-plus.com/go.php?to=patreon")); -} - -void CSandMan::OnAbout() -{ - if (sender() == m_pAbout) - { - QString AboutCaption = tr( - "

About Sandboxie-Plus

" - "

Version %1

" - "

Copyright (c) 2020-2022 by DavidXanatos

" - ).arg(GetVersion()); - - QString CertInfo; - if (!g_Certificate.isEmpty()) { - CertInfo = tr("This copy of Sandboxie+ is certified for: %1").arg(GetArguments(g_Certificate, L'\n', L':').value("NAME")); - } else { - CertInfo = tr("Sandboxie+ is free for personal and non-commercial use."); - } - - QString AboutText = tr( - "Sandboxie-Plus is an open source continuation of Sandboxie.
" - "Visit sandboxie-plus.com for more information.
" - "
" - "%3
" - "
" - "Driver version: %1
" - "Features: %2
" - "
" - "Icons from icons8.com" - ).arg(theAPI->GetVersion()).arg(theAPI->GetFeatureStr()).arg(CertInfo); - - QMessageBox *msgBox = new QMessageBox(this); - msgBox->setAttribute(Qt::WA_DeleteOnClose); - msgBox->setWindowTitle(tr("About Sandboxie-Plus")); - msgBox->setText(AboutCaption); - msgBox->setInformativeText(AboutText); - - QIcon ico(QLatin1String(":/SandMan.png")); - msgBox->setIconPixmap(ico.pixmap(128, 128)); - - SafeExec(msgBox); - } - else if (sender() == m_pAboutQt) - QMessageBox::aboutQt(this); -} - void CSandMan::UpdateCert() { QString UpdateKey; // for now only patreons can update the cert automatically @@ -417,4 +361,4 @@ void CSandMan::OnCertCheck() g_Certificate.clear(); g_CertInfo.State = 0; } -} \ No newline at end of file +} diff --git a/SandboxiePlus/SandMan/Views/SbieView.cpp b/SandboxiePlus/SandMan/Views/SbieView.cpp index 34918b46..409610e6 100644 --- a/SandboxiePlus/SandMan/Views/SbieView.cpp +++ b/SandboxiePlus/SandMan/Views/SbieView.cpp @@ -42,6 +42,15 @@ CSbieView::CSbieView(QWidget* parent) : CPanelView(parent) //m_pSbieTree->setItemDelegate(theGUI->GetItemDelegate()); m_pSbieTree->setModel(m_pSortProxy); + + int iViewMode = theConf->GetInt("Options/ViewMode", 1); + int iLargeIcons = theConf->GetInt("Options/LargeIcons", 2); + if (iLargeIcons == 2) + iLargeIcons = iViewMode == 2 ? 1 : 0; + if (iLargeIcons) { + m_pSbieModel->SetLargeIcons(); + m_pSbieTree->setIconSize(QSize(32, 32)); + } ((CSortFilterProxyModel*)m_pSortProxy)->setView(m_pSbieTree); m_pSbieTree->setDragDropMode(QAbstractItemView::InternalMove); @@ -78,132 +87,12 @@ CSbieView::CSbieView(QWidget* parent) : CPanelView(parent) connect(m_pSbieModel, SIGNAL(ToolTipCallback(const QVariant&, QString&)), this, SLOT(OnToolTipCallback(const QVariant&, QString&)), Qt::DirectConnection); - m_pNewBox = m_pMenu->addAction(CSandMan::GetIcon("NewBox"), tr("Create New Box"), this, SLOT(OnGroupAction())); - m_pAddGroupe = m_pMenu->addAction(CSandMan::GetIcon("Group"), tr("Create Box Group"), this, SLOT(OnGroupAction())); - m_pRenGroupe = m_pMenu->addAction(CSandMan::GetIcon("Rename"), tr("Rename Group"), this, SLOT(OnGroupAction())); - m_pDelGroupe = m_pMenu->addAction(CSandMan::GetIcon("Remove"), tr("Remove Group"), this, SLOT(OnGroupAction())); - m_pStopAsync = m_pMenu->addAction(CSandMan::GetIcon("Stop"), tr("Stop Operations"), this, SLOT(OnSandBoxAction())); - m_iMenuTop = m_pMenu->actions().count(); - //m_pMenu->addSeparator(); + if(iViewMode == 2) + CreateOldMenu(); + else + CreateMenu(); - m_pMenuRun = m_pMenu->addMenu(CSandMan::GetIcon("Start"), tr("Run")); - m_pMenuRunAny = m_pMenuRun->addAction(CSandMan::GetIcon("Run"), tr("Run Program"), this, SLOT(OnSandBoxAction())); - m_pMenuRunMenu = m_pMenuRun->addAction(CSandMan::GetIcon("StartMenu"), tr("Run from Start Menu"), this, SLOT(OnSandBoxAction())); - m_pMenuRunBrowser = m_pMenuRun->addAction(CSandMan::GetIcon("Internet"), tr("Default Web Browser"), this, SLOT(OnSandBoxAction())); - m_pMenuRunMailer = m_pMenuRun->addAction(CSandMan::GetIcon("Email"), tr("Default eMail Client"), this, SLOT(OnSandBoxAction())); - m_pMenuRunCmd = m_pMenuRun->addAction(CSandMan::GetIcon("Cmd"), tr("Command Prompt"), this, SLOT(OnSandBoxAction())); - m_pMenuRunTools = m_pMenuRun->addMenu(CSandMan::GetIcon("Maintenance"), tr("Boxed Tools")); - m_pMenuRunCmdAdmin = m_pMenuRunTools->addAction(CSandMan::GetIcon("Cmd"), tr("Command Prompt (as Admin)"), this, SLOT(OnSandBoxAction())); -#ifndef _WIN64 - if(CSbieAPI::IsWow64()) -#endif - m_pMenuRunCmd32 = m_pMenuRunTools->addAction(CSandMan::GetIcon("Cmd"), tr("Command Prompt (32-bit)"), this, SLOT(OnSandBoxAction())); - m_pMenuRunExplorer = m_pMenuRunTools->addAction(CSandMan::GetIcon("Explore"), tr("Windows Explorer"), this, SLOT(OnSandBoxAction())); - m_pMenuRunRegEdit = m_pMenuRunTools->addAction(CSandMan::GetIcon("RegEdit"), tr("Registry Editor"), this, SLOT(OnSandBoxAction())); - m_pMenuRunAppWiz = m_pMenuRunTools->addAction(CSandMan::GetIcon("Software"), tr("Programs and Features"), this, SLOT(OnSandBoxAction())); - m_pMenuAutoRun = m_pMenuRunTools->addAction(CSandMan::GetIcon("ReloadIni"), tr("Execute Autorun Entries"), this, SLOT(OnSandBoxAction())); - m_pMenuRun->addSeparator(); - m_iMenuRun = m_pMenuRun->actions().count(); - m_pMenuEmptyBox = m_pMenu->addAction(CSandMan::GetIcon("EmptyAll"), tr("Terminate All Programs"), this, SLOT(OnSandBoxAction())); - m_pMenu->addSeparator(); - m_pMenuBrowse = m_pMenu->addAction(CSandMan::GetIcon("Tree"), tr("Browse Content"), this, SLOT(OnSandBoxAction())); - m_pMenuContent = m_pMenu->addMenu(CSandMan::GetIcon("Compatibility"), tr("Box Content")); - m_pMenuMkLink = m_pMenuContent->addAction(CSandMan::GetIcon("MkLink"), tr("Create Shortcut"), this, SLOT(OnSandBoxAction())); - m_pMenuContent->addSeparator(); - m_pMenuExplore = m_pMenuContent->addAction(CSandMan::GetIcon("Explore"), tr("Explore Content"), this, SLOT(OnSandBoxAction())); - m_pMenuRegEdit = m_pMenuContent->addAction(CSandMan::GetIcon("RegEdit"), tr("Open Registry"), this, SLOT(OnSandBoxAction())); - m_pMenuRefresh = m_pMenu->addAction(CSandMan::GetIcon("Refresh"), tr("Refresh Info"), this, SLOT(OnSandBoxAction())); - m_pMenuSnapshots = m_pMenu->addAction(CSandMan::GetIcon("Snapshots"), tr("Snapshots Manager"), this, SLOT(OnSandBoxAction())); - m_pMenuRecover = m_pMenu->addAction(CSandMan::GetIcon("Recover"), tr("Recover Files"), this, SLOT(OnSandBoxAction())); - m_pMenuCleanUp = m_pMenu->addAction(CSandMan::GetIcon("Erase"), tr("Delete Content"), this, SLOT(OnSandBoxAction())); - m_pMenu->addSeparator(); - m_pMenuOptions = m_pMenu->addAction(CSandMan::GetIcon("Options"), tr("Sandbox Options"), this, SLOT(OnSandBoxAction())); - - m_pMenuPresets = m_pMenu->addMenu(CSandMan::GetIcon("Presets"), tr("Sandbox Presets")); - m_pMenuPresetsAdmin = new QActionGroup(m_pMenuPresets); - m_pMenuPresetsShowUAC = MakeAction(m_pMenuPresetsAdmin, m_pMenuPresets, tr("Ask for UAC Elevation"), 0); - m_pMenuPresetsNoAdmin = MakeAction(m_pMenuPresetsAdmin, m_pMenuPresets, tr("Drop Admin Rights"), 1); - m_pMenuPresetsFakeAdmin = MakeAction(m_pMenuPresetsAdmin, m_pMenuPresets, tr("Emulate Admin Rights"), 1 | 2); - if (theAPI->IsRunningAsAdmin()) { - m_pMenuPresetsNoAdmin->setEnabled(false); - m_pMenuPresetsFakeAdmin->setEnabled(false); - } - connect(m_pMenuPresetsAdmin, SIGNAL(triggered(QAction*)), this, SLOT(OnSandBoxAction(QAction*))); - - m_pMenuPresets->addSeparator(); - m_pMenuPresetsINet = m_pMenuPresets->addAction(tr("Block Internet Access"), this, SLOT(OnSandBoxAction())); - m_pMenuPresetsINet->setCheckable(true); - m_pMenuPresetsShares = m_pMenuPresets->addAction(tr("Allow Network Shares"), this, SLOT(OnSandBoxAction())); - m_pMenuPresetsShares->setCheckable(true); - - m_pMenuPresets->addSeparator(); - m_pMenuPresetsRecovery = m_pMenuPresets->addAction(tr("Immediate Recovery"), this, SLOT(OnSandBoxAction())); - m_pMenuPresetsRecovery->setCheckable(true); - - m_pMenuDuplicate = m_pMenu->addAction(CSandMan::GetIcon("Duplicate"), tr("Duplicate Sandbox"), this, SLOT(OnSandBoxAction())); - m_pMenuRename = m_pMenu->addAction(CSandMan::GetIcon("Rename"), tr("Rename Sandbox"), this, SLOT(OnSandBoxAction())); - m_iMoveTo = m_pMenu->actions().count(); - m_pMenuMoveTo = m_pMenu->addMenu(CSandMan::GetIcon("Group"), tr("Move Box/Group")); - m_pMenuMoveUp = m_pMenuMoveTo->addAction(CSandMan::GetIcon("Up"), tr("Move Up"), this, SLOT(OnGroupAction())); - m_pMenuMoveUp->setShortcut(QKeySequence("Alt+Up")); - m_pMenuMoveUp->setShortcutContext(Qt::WidgetWithChildrenShortcut); - this->addAction(m_pMenuMoveUp); - //m_pMenuMoveBy = m_pMenuMoveTo->addAction(tr("Move to Position"), this, SLOT(OnGroupAction())); // does not seam that intuitive for users - m_pMenuMoveDown = m_pMenuMoveTo->addAction(CSandMan::GetIcon("Down"), tr("Move Down"), this, SLOT(OnGroupAction())); - m_pMenuMoveDown->setShortcut(QKeySequence("Alt+Down")); - m_pMenuMoveDown->setShortcutContext(Qt::WidgetWithChildrenShortcut); - this->addAction(m_pMenuMoveDown); - m_pMenuMoveTo->addSeparator(); - m_pMenuRemove = m_pMenu->addAction(CSandMan::GetIcon("Remove"), tr("Remove Sandbox"), this, SLOT(OnSandBoxAction())); - m_iMenuBox = m_pMenu->actions().count(); - - //UpdateRunMenu(); - - m_pMenuTerminate = m_pMenu->addAction(CSandMan::GetIcon("Remove"), tr("Terminate"), this, SLOT(OnProcessAction())); - //m_pMenuTerminate->setShortcut(QKeySequence::Delete); - //m_pMenuTerminate->setShortcutContext(Qt::WidgetWithChildrenShortcut); - this->addAction(m_pMenuTerminate); - m_pMenuLinkTo = m_pMenu->addAction(CSandMan::GetIcon("MkLink"), tr("Create Shortcut"), this, SLOT(OnProcessAction())); - m_pMenuPreset = m_pMenu->addMenu(CSandMan::GetIcon("Presets"), tr("Preset")); - m_pMenuPinToRun = m_pMenuPreset->addAction(tr("Pin to Run Menu"), this, SLOT(OnProcessAction())); - m_pMenuPinToRun->setCheckable(true); - m_pMenuBlackList = m_pMenuPreset->addAction(tr("Block and Terminate"), this, SLOT(OnProcessAction())); - //m_pMenuBlackList->setShortcut(QKeySequence("Shift+Del")); - //m_pMenuBlackList->setShortcutContext(Qt::WidgetWithChildrenShortcut); - this->addAction(m_pMenuBlackList); - m_pMenuAllowInternet = m_pMenuPreset->addAction(tr("Allow internet access"), this, SLOT(OnProcessAction())); - m_pMenuAllowInternet->setCheckable(true); - m_pMenuMarkForced = m_pMenuPreset->addAction(tr("Force into this sandbox"), this, SLOT(OnProcessAction())); - m_pMenuMarkForced->setCheckable(true); - m_pMenuMarkLinger = m_pMenuPreset->addAction(tr("Set Linger Process"), this, SLOT(OnProcessAction())); - m_pMenuMarkLinger->setCheckable(true); - m_pMenuMarkLeader = m_pMenuPreset->addAction(tr("Set Leader Process"), this, SLOT(OnProcessAction())); - m_pMenuMarkLeader->setCheckable(true); - //m_pMenuSuspend = m_pMenu->addAction(tr("Suspend"), this, SLOT(OnProcessAction())); - //m_pMenuResume = m_pMenu->addAction(tr("Resume"), this, SLOT(OnProcessAction())); - m_iMenuProc = m_pMenu->actions().count(); - - m_pRemove = new QAction(this); - m_pRemove->setShortcut(QKeySequence::Delete); - m_pRemove->setShortcutContext(Qt::WidgetWithChildrenShortcut); - this->addAction(m_pRemove); - connect(m_pRemove, SIGNAL(triggered()), this, SLOT(OnRemoveItem())); - - - // menu for the tray - m_pMenu2 = new QMenu(); - m_pMenu2->addMenu(m_pMenuRun); - m_pMenu2->addAction(m_pMenuEmptyBox); - m_pMenu2->addSeparator(); - m_pMenu2->addAction(m_pMenuBrowse); - m_pMenu2->addAction(m_pMenuExplore); - m_pMenu2->addAction(m_pMenuRegEdit); - m_pMenu2->addAction(m_pMenuSnapshots); - m_pMenu2->addAction(m_pMenuRecover); - m_pMenu2->addAction(m_pMenuCleanUp); - m_pMenu2->addSeparator(); - m_pMenu2->addAction(m_pMenuOptions); - m_pMenu2->addMenu(m_pMenuPresets); + CreatTrayMenu(); QByteArray Columns = theConf->GetBlob("MainWindow/BoxTree_Columns"); if (Columns.isEmpty()) @@ -237,7 +126,246 @@ void CSbieView::Clear() m_pSbieModel->Clear(); } +void CSbieView::CreateMenu() +{ + m_pNewBox = m_pMenu->addAction(CSandMan::GetIcon("NewBox"), tr("Create New Box"), this, SLOT(OnGroupAction())); + m_pAddGroupe = m_pMenu->addAction(CSandMan::GetIcon("Group"), tr("Create Box Group"), this, SLOT(OnGroupAction())); + m_pMenu->addSeparator(); + m_pRenGroupe = m_pMenu->addAction(CSandMan::GetIcon("Rename"), tr("Rename Group"), this, SLOT(OnGroupAction())); + m_pDelGroupe = m_pMenu->addAction(CSandMan::GetIcon("Remove"), tr("Remove Group"), this, SLOT(OnGroupAction())); + m_pStopAsync = m_pMenu->addAction(CSandMan::GetIcon("Stop"), tr("Stop Operations"), this, SLOT(OnSandBoxAction())); + m_iMenuTop = m_pMenu->actions().count(); + //m_pMenu->addSeparator(); + m_pMenuRun = m_pMenu->addMenu(CSandMan::GetIcon("Start"), tr("Run")); + m_pMenuRunAny = m_pMenuRun->addAction(CSandMan::GetIcon("Run"), tr("Run Program"), this, SLOT(OnSandBoxAction())); + m_pMenuRunMenu = m_pMenuRun->addAction(CSandMan::GetIcon("StartMenu"), tr("Run from Start Menu"), this, SLOT(OnSandBoxAction())); + m_pMenuRunBrowser = m_pMenuRun->addAction(CSandMan::GetIcon("Internet"), tr("Default Web Browser"), this, SLOT(OnSandBoxAction())); + m_pMenuRunMailer = m_pMenuRun->addAction(CSandMan::GetIcon("Email"), tr("Default eMail Client"), this, SLOT(OnSandBoxAction())); + m_pMenuRunCmd = m_pMenuRun->addAction(CSandMan::GetIcon("Cmd"), tr("Command Prompt"), this, SLOT(OnSandBoxAction())); + m_pMenuRunTools = m_pMenuRun->addMenu(CSandMan::GetIcon("Maintenance"), tr("Boxed Tools")); + m_pMenuRunCmdAdmin = m_pMenuRunTools->addAction(CSandMan::GetIcon("Cmd"), tr("Command Prompt (as Admin)"), this, SLOT(OnSandBoxAction())); +#ifndef _WIN64 + if(CSbieAPI::IsWow64()) +#endif + m_pMenuRunCmd32 = m_pMenuRunTools->addAction(CSandMan::GetIcon("Cmd"), tr("Command Prompt (32-bit)"), this, SLOT(OnSandBoxAction())); + m_pMenuRunExplorer = m_pMenuRunTools->addAction(CSandMan::GetIcon("Explore"), tr("Windows Explorer"), this, SLOT(OnSandBoxAction())); + m_pMenuRunRegEdit = m_pMenuRunTools->addAction(CSandMan::GetIcon("RegEdit"), tr("Registry Editor"), this, SLOT(OnSandBoxAction())); + m_pMenuRunAppWiz = m_pMenuRunTools->addAction(CSandMan::GetIcon("Software"), tr("Programs and Features"), this, SLOT(OnSandBoxAction())); + m_pMenuAutoRun = m_pMenuRunTools->addAction(CSandMan::GetIcon("ReloadIni"), tr("Execute Autorun Entries"), this, SLOT(OnSandBoxAction())); + m_pMenuRun->addSeparator(); + m_iMenuRun = m_pMenuRun->actions().count(); + m_pMenuEmptyBox = m_pMenu->addAction(CSandMan::GetIcon("EmptyAll"), tr("Terminate All Programs"), this, SLOT(OnSandBoxAction())); + m_pMenu->addSeparator(); + m_pMenuBrowse = m_pMenu->addAction(CSandMan::GetIcon("Tree"), tr("Browse Content"), this, SLOT(OnSandBoxAction())); + m_pMenuContent = m_pMenu->addMenu(CSandMan::GetIcon("Compatibility"), tr("Box Content")); + m_pMenuRefresh = m_pMenuContent->addAction(CSandMan::GetIcon("Refresh"), tr("Refresh Info"), this, SLOT(OnSandBoxAction())); + m_pMenuMkLink = m_pMenuContent->addAction(CSandMan::GetIcon("MkLink"), tr("Create Shortcut"), this, SLOT(OnSandBoxAction())); + m_pMenuContent->addSeparator(); + m_pMenuExplore = m_pMenuContent->addAction(CSandMan::GetIcon("Explore"), tr("Explore Content"), this, SLOT(OnSandBoxAction())); + m_pMenuRegEdit = m_pMenuContent->addAction(CSandMan::GetIcon("RegEdit"), tr("Open Registry"), this, SLOT(OnSandBoxAction())); + m_pMenuSnapshots = m_pMenu->addAction(CSandMan::GetIcon("Snapshots"), tr("Snapshots Manager"), this, SLOT(OnSandBoxAction())); + m_pMenuRecover = m_pMenu->addAction(CSandMan::GetIcon("Recover"), tr("Recover Files"), this, SLOT(OnSandBoxAction())); + m_pMenuCleanUp = m_pMenu->addAction(CSandMan::GetIcon("Erase"), tr("Delete Content"), this, SLOT(OnSandBoxAction())); + m_pMenu->addSeparator(); + m_pMenuOptions = m_pMenu->addAction(CSandMan::GetIcon("Options"), tr("Sandbox Options"), this, SLOT(OnSandBoxAction())); + + m_pMenuPresets = m_pMenu->addMenu(CSandMan::GetIcon("Presets"), tr("Sandbox Presets")); + m_pMenuPresetsAdmin = new QActionGroup(m_pMenuPresets); + m_pMenuPresetsShowUAC = MakeAction(m_pMenuPresetsAdmin, m_pMenuPresets, tr("Ask for UAC Elevation"), 0); + m_pMenuPresetsNoAdmin = MakeAction(m_pMenuPresetsAdmin, m_pMenuPresets, tr("Drop Admin Rights"), 1); + m_pMenuPresetsFakeAdmin = MakeAction(m_pMenuPresetsAdmin, m_pMenuPresets, tr("Emulate Admin Rights"), 1 | 2); + if (theAPI->IsRunningAsAdmin()) { + m_pMenuPresetsNoAdmin->setEnabled(false); + m_pMenuPresetsFakeAdmin->setEnabled(false); + } + connect(m_pMenuPresetsAdmin, SIGNAL(triggered(QAction*)), this, SLOT(OnSandBoxAction(QAction*))); + + m_pMenuPresets->addSeparator(); + m_pMenuPresetsINet = m_pMenuPresets->addAction(tr("Block Internet Access"), this, SLOT(OnSandBoxAction())); + m_pMenuPresetsINet->setCheckable(true); + m_pMenuPresetsShares = m_pMenuPresets->addAction(tr("Allow Network Shares"), this, SLOT(OnSandBoxAction())); + m_pMenuPresetsShares->setCheckable(true); + + m_pMenuPresets->addSeparator(); + m_pMenuPresetsRecovery = m_pMenuPresets->addAction(tr("Immediate Recovery"), this, SLOT(OnSandBoxAction())); + m_pMenuPresetsRecovery->setCheckable(true); + + m_pMenuTools = m_pMenu->addMenu(CSandMan::GetIcon("Maintenance"), tr("Sandbox Tools")); + m_pMenuDuplicate = m_pMenuTools->addAction(CSandMan::GetIcon("Duplicate"), tr("Duplicate Box Config"), this, SLOT(OnSandBoxAction())); + + m_pMenuRename = m_pMenu->addAction(CSandMan::GetIcon("Rename"), tr("Rename Sandbox"), this, SLOT(OnSandBoxAction())); + m_iMoveTo = m_pMenu->actions().count(); + m_pMenuMoveTo = m_pMenu->addMenu(CSandMan::GetIcon("Group"), tr("Move Box/Group")); + m_pMenuMoveUp = m_pMenuMoveTo->addAction(CSandMan::GetIcon("Up"), tr("Move Up"), this, SLOT(OnGroupAction())); + m_pMenuMoveUp->setShortcut(QKeySequence("Alt+Up")); + m_pMenuMoveUp->setShortcutContext(Qt::WidgetWithChildrenShortcut); + this->addAction(m_pMenuMoveUp); + //m_pMenuMoveBy = m_pMenuMoveTo->addAction(tr("Move to Position"), this, SLOT(OnGroupAction())); // does not seam that intuitive for users + m_pMenuMoveDown = m_pMenuMoveTo->addAction(CSandMan::GetIcon("Down"), tr("Move Down"), this, SLOT(OnGroupAction())); + m_pMenuMoveDown->setShortcut(QKeySequence("Alt+Down")); + m_pMenuMoveDown->setShortcutContext(Qt::WidgetWithChildrenShortcut); + this->addAction(m_pMenuMoveDown); + m_pMenuMoveTo->addSeparator(); + m_pMenuRemove = m_pMenu->addAction(CSandMan::GetIcon("Remove"), tr("Remove Sandbox"), this, SLOT(OnSandBoxAction())); + m_iMenuBox = m_pMenu->actions().count(); + + + // Process Menu + m_pMenuTerminate = m_pMenu->addAction(CSandMan::GetIcon("Remove"), tr("Terminate"), this, SLOT(OnProcessAction())); + //m_pMenuTerminate->setShortcut(QKeySequence::Delete); + //m_pMenuTerminate->setShortcutContext(Qt::WidgetWithChildrenShortcut); + this->addAction(m_pMenuTerminate); + m_pMenuLinkTo = m_pMenu->addAction(CSandMan::GetIcon("MkLink"), tr("Create Shortcut"), this, SLOT(OnProcessAction())); + m_pMenuPreset = m_pMenu->addMenu(CSandMan::GetIcon("Presets"), tr("Preset")); + m_pMenuPinToRun = m_pMenuPreset->addAction(tr("Pin to Run Menu"), this, SLOT(OnProcessAction())); + m_pMenuPinToRun->setCheckable(true); + m_pMenuBlackList = m_pMenuPreset->addAction(tr("Block and Terminate"), this, SLOT(OnProcessAction())); + //m_pMenuBlackList->setShortcut(QKeySequence("Shift+Del")); + //m_pMenuBlackList->setShortcutContext(Qt::WidgetWithChildrenShortcut); + this->addAction(m_pMenuBlackList); + m_pMenuAllowInternet = m_pMenuPreset->addAction(tr("Allow internet access"), this, SLOT(OnProcessAction())); + m_pMenuAllowInternet->setCheckable(true); + m_pMenuMarkForced = m_pMenuPreset->addAction(tr("Force into this sandbox"), this, SLOT(OnProcessAction())); + m_pMenuMarkForced->setCheckable(true); + m_pMenuMarkLinger = m_pMenuPreset->addAction(tr("Set Linger Process"), this, SLOT(OnProcessAction())); + m_pMenuMarkLinger->setCheckable(true); + m_pMenuMarkLeader = m_pMenuPreset->addAction(tr("Set Leader Process"), this, SLOT(OnProcessAction())); + m_pMenuMarkLeader->setCheckable(true); + //m_pMenuSuspend = m_pMenu->addAction(tr("Suspend"), this, SLOT(OnProcessAction())); + //m_pMenuResume = m_pMenu->addAction(tr("Resume"), this, SLOT(OnProcessAction())); + m_iMenuProc = m_pMenu->actions().count(); + + + m_pRemove = new QAction(this); + m_pRemove->setShortcut(QKeySequence::Delete); + m_pRemove->setShortcutContext(Qt::WidgetWithChildrenShortcut); + this->addAction(m_pRemove); + connect(m_pRemove, SIGNAL(triggered()), this, SLOT(OnRemoveItem())); +} + +void CSbieView::CreateOldMenu() +{ + m_pNewBox = m_pMenu->addAction(CSandMan::GetIcon("NewBox"), tr("Create New Box"), this, SLOT(OnGroupAction())); + m_pAddGroupe = m_pMenu->addAction(CSandMan::GetIcon("Group"), tr("Create Box Group"), this, SLOT(OnGroupAction())); + m_pMenu->addSeparator(); + m_pRenGroupe = m_pMenu->addAction(CSandMan::GetIcon("Rename"), tr("Rename Group"), this, SLOT(OnGroupAction())); + m_pDelGroupe = m_pMenu->addAction(CSandMan::GetIcon("Remove"), tr("Remove Group"), this, SLOT(OnGroupAction())); + m_pStopAsync = m_pMenu->addAction(CSandMan::GetIcon("Stop"), tr("Stop Operations"), this, SLOT(OnSandBoxAction())); + m_iMenuTop = m_pMenu->actions().count(); + //m_pMenu->addSeparator(); + + m_pMenuRun = m_pMenu->addMenu(CSandMan::GetIcon("Start"), tr("Run Sandboxed")); + m_pMenuRunBrowser = m_pMenuRun->addAction(CSandMan::GetIcon("Internet"), tr("Run Web Browser"), this, SLOT(OnSandBoxAction())); + m_pMenuRunMailer = m_pMenuRun->addAction(CSandMan::GetIcon("Email"), tr("Run eMail Reader"), this, SLOT(OnSandBoxAction())); + m_pMenuRunAny = m_pMenuRun->addAction(CSandMan::GetIcon("Run"), tr("Run Any Program"), this, SLOT(OnSandBoxAction())); + m_pMenuRunMenu = m_pMenuRun->addAction(CSandMan::GetIcon("StartMenu"), tr("Run From Start Menu"), this, SLOT(OnSandBoxAction())); + m_pMenuRunExplorer = m_pMenuRun->addAction(CSandMan::GetIcon("Explore"), tr("Run Windows Explorer"), this, SLOT(OnSandBoxAction())); + m_pMenuRunCmd = NULL; + m_pMenuRunTools = NULL; + m_pMenuRunCmdAdmin = NULL; + m_pMenuRunCmd32 = NULL; + m_pMenuRunRegEdit = NULL; + m_pMenuRunAppWiz = NULL; + m_pMenuAutoRun = NULL; + m_pMenuRun->addSeparator(); + m_iMenuRun = m_pMenuRun->actions().count(); + + m_pMenu->addSeparator(); + m_pMenuEmptyBox = m_pMenu->addAction(CSandMan::GetIcon("EmptyAll"), tr("Terminate Programs"), this, SLOT(OnSandBoxAction())); + m_pMenuRecover = m_pMenu->addAction(CSandMan::GetIcon("Recover"), tr("Quick Recover"), this, SLOT(OnSandBoxAction())); + m_pMenuCleanUp = m_pMenu->addAction(CSandMan::GetIcon("Erase"), tr("Delete Content"), this, SLOT(OnSandBoxAction())); + m_pMenuExplore = m_pMenu->addAction(CSandMan::GetIcon("Explore"), tr("Explore Content"), this, SLOT(OnSandBoxAction())); + + m_pMenu->addSeparator(); + m_pMenuOptions = m_pMenu->addAction(CSandMan::GetIcon("Options"), tr("Sandbox Settings"), this, SLOT(OnSandBoxAction())); + + m_pMenuTools = m_pMenu->addMenu(CSandMan::GetIcon("Maintenance"), tr("Sandbox Tools")); + m_pMenuBrowse = m_pMenuTools->addAction(CSandMan::GetIcon("Tree"), tr("Browse Content"), this, SLOT(OnSandBoxAction())); + m_pMenuSnapshots = m_pMenuTools->addAction(CSandMan::GetIcon("Snapshots"), tr("Snapshots Manager"), this, SLOT(OnSandBoxAction())); + + m_pMenuTools->addSeparator(); + m_pMenuDuplicate = m_pMenuTools->addAction(CSandMan::GetIcon("Duplicate"), tr("Duplicate Box Config"), this, SLOT(OnSandBoxAction())); + + m_pMenuTools->addSeparator(); + m_pMenuRefresh = m_pMenuTools->addAction(CSandMan::GetIcon("Refresh"), tr("Refresh Info"), this, SLOT(OnSandBoxAction())); + m_pMenuMkLink = m_pMenuTools->addAction(CSandMan::GetIcon("MkLink"), tr("Create Shortcut"), this, SLOT(OnSandBoxAction())); + + m_pMenu->addSeparator(); + m_pMenuRename = m_pMenu->addAction(CSandMan::GetIcon("Rename"), tr("Rename Sandbox"), this, SLOT(OnSandBoxAction())); + m_iMoveTo = m_pMenu->actions().count(); + m_pMenuMoveTo = m_pMenu->addMenu(CSandMan::GetIcon("Group"), tr("Move Box/Group")); + m_pMenuMoveUp = m_pMenuMoveTo->addAction(CSandMan::GetIcon("Up"), tr("Move Up"), this, SLOT(OnGroupAction())); + m_pMenuMoveUp->setShortcut(QKeySequence("Alt+Up")); + m_pMenuMoveUp->setShortcutContext(Qt::WidgetWithChildrenShortcut); + this->addAction(m_pMenuMoveUp); + //m_pMenuMoveBy = m_pMenuMoveTo->addAction(tr("Move to Position"), this, SLOT(OnGroupAction())); // does not seam that intuitive for users + m_pMenuMoveDown = m_pMenuMoveTo->addAction(CSandMan::GetIcon("Down"), tr("Move Down"), this, SLOT(OnGroupAction())); + m_pMenuMoveDown->setShortcut(QKeySequence("Alt+Down")); + m_pMenuMoveDown->setShortcutContext(Qt::WidgetWithChildrenShortcut); + this->addAction(m_pMenuMoveDown); + m_pMenuMoveTo->addSeparator(); + m_pMenuRemove = m_pMenu->addAction(CSandMan::GetIcon("Remove"), tr("Remove Sandbox"), this, SLOT(OnSandBoxAction())); + m_iMenuBox = m_pMenu->actions().count(); + + + + m_pMenuContent = NULL; + m_pMenuRegEdit = NULL; + + m_pMenuPresets = NULL; + m_pMenuPresetsAdmin = NULL; + m_pMenuPresetsShowUAC = NULL; + m_pMenuPresetsNoAdmin = NULL; + m_pMenuPresetsFakeAdmin = NULL; + + m_pMenuPresetsINet = NULL; + m_pMenuPresetsShares = NULL; + + m_pMenuPresetsRecovery = NULL; + + + // Process Menu + m_pMenuTerminate = m_pMenu->addAction(CSandMan::GetIcon("Remove"), tr("Terminate"), this, SLOT(OnProcessAction())); + //m_pMenuTerminate->setShortcut(QKeySequence::Delete); + //m_pMenuTerminate->setShortcutContext(Qt::WidgetWithChildrenShortcut); + this->addAction(m_pMenuTerminate); + m_pMenuLinkTo = m_pMenu->addAction(CSandMan::GetIcon("MkLink"), tr("Create Shortcut"), this, SLOT(OnProcessAction())); + m_pMenuPreset = NULL; + m_pMenuPinToRun = NULL; + m_pMenuBlackList = NULL; + m_pMenuAllowInternet = NULL; + m_pMenuMarkForced = NULL; + m_pMenuMarkLinger = NULL; + m_pMenuMarkLeader = NULL; + m_iMenuProc = m_pMenu->actions().count(); + + + m_pRemove = new QAction(this); + m_pRemove->setShortcut(QKeySequence::Delete); + m_pRemove->setShortcutContext(Qt::WidgetWithChildrenShortcut); + this->addAction(m_pRemove); + connect(m_pRemove, SIGNAL(triggered()), this, SLOT(OnRemoveItem())); +} + +void CSbieView::CreatTrayMenu() +{ + m_pMenu2 = new QMenu(); + m_pMenu2->addMenu(m_pMenuRun); + m_pMenu2->addAction(m_pMenuEmptyBox); + m_pMenu2->addSeparator(); + m_pMenu2->addAction(m_pMenuBrowse); + m_pMenu2->addAction(m_pMenuExplore); + m_pMenu2->addAction(m_pMenuRegEdit); + m_pMenu2->addAction(m_pMenuSnapshots); + m_pMenu2->addAction(m_pMenuRecover); + m_pMenu2->addAction(m_pMenuCleanUp); + m_pMenu2->addSeparator(); + if (m_pMenuPresets) { + m_pMenu2->addAction(m_pMenuOptions); + m_pMenu2->addMenu(m_pMenuPresets); + } +} int CSbieView__ParseGroup(const QString& Grouping, QMap& m_Groups, const QString& Parent = "", int Index = 0) { @@ -382,7 +510,7 @@ void CSbieView::OnCustomSortByColumn(int column) } } -bool CSbieView::UpdateMenu() +bool CSbieView::UpdateMenu(const CSandBoxPtr &pBox, int iSandBoxeCount, bool bBoxBusy, const CBoxedProcessPtr &pProcess, int iProcessCount, int iGroupe) { QList MenuActions = m_pMenu->actions(); @@ -391,7 +519,112 @@ bool CSbieView::UpdateMenu() // foreach(QAction * pAction, MenuActions) // pAction->setEnabled(true); //} + + for (int i = 0; i < m_iMenuTop; i++) + MenuActions[i]->setVisible(!bBoxBusy && iSandBoxeCount == 0 && iProcessCount == 0); + m_pStopAsync->setVisible(bBoxBusy); + m_pRenGroupe->setVisible(iGroupe == 1 && iSandBoxeCount == 0 && iProcessCount == 0); + m_pDelGroupe->setVisible(iGroupe > 0 && iSandBoxeCount == 0 && iProcessCount == 0); + + for (int i = m_iMenuTop; i < m_iMenuBox; i++) + MenuActions[i]->setVisible(iSandBoxeCount != 0 && iProcessCount == 0); + m_pMenuRun->setEnabled(iSandBoxeCount == 1); + + MenuActions[m_iMoveTo]->setVisible((iGroupe > 0 || iSandBoxeCount > 0) && iProcessCount == 0); + + if(iSandBoxeCount == 1) + UpdateRunMenu(pBox); + + m_pMenuMkLink->setEnabled(iSandBoxeCount == 1); + m_pMenuTools->setEnabled(iSandBoxeCount == 1); + m_pMenuRename->setEnabled(iSandBoxeCount == 1); + m_pMenuRecover->setEnabled(iSandBoxeCount == 1); + + if (m_pMenuPresets) { + m_pMenuPresets->setEnabled(iSandBoxeCount == 1); + m_pMenuPresetsShowUAC->setChecked(pBox && !pBox->GetBool("DropAdminRights", false) && !pBox->GetBool("FakeAdminRights", false)); + m_pMenuPresetsNoAdmin->setChecked(pBox && pBox->GetBool("DropAdminRights", false) && !pBox->GetBool("FakeAdminRights", false)); + m_pMenuPresetsFakeAdmin->setChecked(pBox && pBox->GetBool("DropAdminRights", false) && pBox->GetBool("FakeAdminRights", false)); + m_pMenuPresetsINet->setChecked(pBox && pBox.objectCast()->IsINetBlocked()); + m_pMenuPresetsShares->setChecked(pBox && pBox.objectCast()->HasSharesAccess()); + m_pMenuPresetsRecovery->setChecked(pBox && pBox->GetBool("AutoRecover", false)); + } + + m_pMenuBrowse->setEnabled(iSandBoxeCount == 1); + m_pMenuExplore->setEnabled(iSandBoxeCount == 1); + if(m_pMenuRegEdit)m_pMenuRegEdit->setEnabled(iSandBoxeCount == 1); + m_pMenuOptions->setEnabled(iSandBoxeCount == 1); + m_pMenuSnapshots->setEnabled(iSandBoxeCount == 1); + + //m_pMenuMoveUp->setEnabled(m_pSortProxy->sortRole() == Qt::InitialSortOrderRole); + //m_pMenuMoveDown->setEnabled(m_pSortProxy->sortRole() == Qt::InitialSortOrderRole); + //m_pMenuMoveBy->setEnabled(m_pSortProxy->sortRole() == Qt::InitialSortOrderRole); + + for (int i = m_iMenuBox; i < m_iMenuProc; i++) + MenuActions[i]->setVisible(iProcessCount != 0 && iSandBoxeCount == 0); + + m_pMenuLinkTo->setEnabled(iProcessCount == 1); + + if (!pProcess.isNull()) { + CSandBoxPlus* pBoxPlus = pProcess.objectCast()->GetBox(); + QStringList RunOptions = pBoxPlus->GetTextList("RunCommand", true); + + QString FoundPin; + QString FileName = pProcess->GetFileName(); + foreach(const QString& RunOption, RunOptions) { + QString Cmd = Split2(RunOption, "|").second; + int pos = Cmd.indexOf(FileName); + if (pos == 0 || pos == 1) { // 1 for " + FoundPin = RunOption; + break; + } + } + if (FoundPin.isEmpty() && FileName.indexOf(pBoxPlus->GetFileRoot(), Qt::CaseInsensitive) == 0) { + FileName.remove(0, pBoxPlus->GetFileRoot().length()); + foreach(const QString& RunOption, RunOptions) { + if (Split2(RunOption, "|").second.indexOf(FileName) == 0) { + FoundPin = RunOption; + break; + } + } + } + + if (m_pMenuPreset) { + m_pMenuPinToRun->setChecked(!FoundPin.isEmpty()); + m_pMenuPinToRun->setData(FoundPin); + + m_pMenuAllowInternet->setChecked(pProcess.objectCast()->HasInternetAccess()); + + m_pMenuMarkForced->setChecked(pProcess.objectCast()->IsForcedProgram()); + + int isLingering = pProcess.objectCast()->IsLingeringProgram(); + m_pMenuMarkLinger->setChecked(isLingering != 0); + m_pMenuMarkLinger->setEnabled(isLingering != 2); + m_pMenuMarkLeader->setChecked(pProcess.objectCast()->IsLeaderProgram()); + } + } + + //m_pMenuSuspend->setEnabled(iProcessCount > iSuspendedCount); + //m_pMenuResume->setEnabled(iSuspendedCount > 0); + + //if (!isConnected) { + // foreach(QAction * pAction, MenuActions) + // pAction->setEnabled(false); + //} + + bool bCtrl = theConf->GetInt("Options/ViewMode", 1) == 1 + || (QGuiApplication::queryKeyboardModifiers() & Qt::ControlModifier) != 0; + + m_pCopyCell->setVisible(bCtrl); + m_pCopyRow->setVisible(bCtrl); + m_pCopyPanel->setVisible(bCtrl); + + return bBoxBusy == false; +} + +bool CSbieView::UpdateMenu() +{ CSandBoxPtr pBox; bool bBoxBusy = false; CBoxedProcessPtr pProcess; @@ -435,95 +668,7 @@ bool CSbieView::UpdateMenu() iGroupe = 0; } - for (int i = 0; i < m_iMenuTop; i++) - MenuActions[i]->setVisible(!bBoxBusy && iSandBoxeCount == 0 && iProcessCount == 0); - m_pStopAsync->setVisible(bBoxBusy); - m_pRenGroupe->setVisible(iGroupe == 1 && iSandBoxeCount == 0 && iProcessCount == 0); - m_pDelGroupe->setVisible(iGroupe > 0 && iSandBoxeCount == 0 && iProcessCount == 0); - - for (int i = m_iMenuTop; i < m_iMenuBox; i++) - MenuActions[i]->setVisible(iSandBoxeCount != 0 && iProcessCount == 0); - m_pMenuRun->setEnabled(iSandBoxeCount == 1); - - MenuActions[m_iMoveTo]->setVisible((iGroupe > 0 || iSandBoxeCount > 0) && iProcessCount == 0); - - if(iSandBoxeCount == 1) - UpdateRunMenu(pBox); - - m_pMenuMkLink->setEnabled(iSandBoxeCount == 1); - m_pMenuDuplicate->setEnabled(iSandBoxeCount == 1); - m_pMenuRename->setEnabled(iSandBoxeCount == 1); - m_pMenuRecover->setEnabled(iSandBoxeCount == 1); - - m_pMenuPresets->setEnabled(iSandBoxeCount == 1); - m_pMenuPresetsShowUAC->setChecked(pBox && !pBox->GetBool("DropAdminRights", false) && !pBox->GetBool("FakeAdminRights", false)); - m_pMenuPresetsNoAdmin->setChecked(pBox && pBox->GetBool("DropAdminRights", false) && !pBox->GetBool("FakeAdminRights", false)); - m_pMenuPresetsFakeAdmin->setChecked(pBox && pBox->GetBool("DropAdminRights", false) && pBox->GetBool("FakeAdminRights", false)); - m_pMenuPresetsINet->setChecked(pBox && pBox.objectCast()->IsINetBlocked()); - m_pMenuPresetsShares->setChecked(pBox && pBox.objectCast()->HasSharesAccess()); - m_pMenuPresetsRecovery->setChecked(pBox && pBox->GetBool("AutoRecover", false)); - - m_pMenuBrowse->setEnabled(iSandBoxeCount == 1); - m_pMenuExplore->setEnabled(iSandBoxeCount == 1); - m_pMenuRegEdit->setEnabled(iSandBoxeCount == 1); - m_pMenuOptions->setEnabled(iSandBoxeCount == 1); - m_pMenuSnapshots->setEnabled(iSandBoxeCount == 1); - - //m_pMenuMoveUp->setEnabled(m_pSortProxy->sortRole() == Qt::InitialSortOrderRole); - //m_pMenuMoveDown->setEnabled(m_pSortProxy->sortRole() == Qt::InitialSortOrderRole); - //m_pMenuMoveBy->setEnabled(m_pSortProxy->sortRole() == Qt::InitialSortOrderRole); - - for (int i = m_iMenuBox; i < m_iMenuProc; i++) - MenuActions[i]->setVisible(iProcessCount != 0 && iSandBoxeCount == 0); - - m_pMenuLinkTo->setEnabled(iProcessCount == 1); - - if (!pProcess.isNull()) { - CSandBoxPlus* pBoxPlus = pProcess.objectCast()->GetBox(); - QStringList RunOptions = pBoxPlus->GetTextList("RunCommand", true); - - QString FoundPin; - QString FileName = pProcess->GetFileName(); - foreach(const QString& RunOption, RunOptions) { - QString Cmd = Split2(RunOption, "|").second; - int pos = Cmd.indexOf(FileName); - if (pos == 0 || pos == 1) { // 1 for " - FoundPin = RunOption; - break; - } - } - if (FoundPin.isEmpty() && FileName.indexOf(pBoxPlus->GetFileRoot(), Qt::CaseInsensitive) == 0) { - FileName.remove(0, pBoxPlus->GetFileRoot().length()); - foreach(const QString& RunOption, RunOptions) { - if (Split2(RunOption, "|").second.indexOf(FileName) == 0) { - FoundPin = RunOption; - break; - } - } - } - - m_pMenuPinToRun->setChecked(!FoundPin.isEmpty()); - m_pMenuPinToRun->setData(FoundPin); - - m_pMenuAllowInternet->setChecked(pProcess.objectCast()->HasInternetAccess()); - - m_pMenuMarkForced->setChecked(pProcess.objectCast()->IsForcedProgram()); - - int isLingering = pProcess.objectCast()->IsLingeringProgram(); - m_pMenuMarkLinger->setChecked(isLingering != 0); - m_pMenuMarkLinger->setEnabled(isLingering != 2); - m_pMenuMarkLeader->setChecked(pProcess.objectCast()->IsLeaderProgram()); - } - - //m_pMenuSuspend->setEnabled(iProcessCount > iSuspendedCount); - //m_pMenuResume->setEnabled(iSuspendedCount > 0); - - //if (!isConnected) { - // foreach(QAction * pAction, MenuActions) - // pAction->setEnabled(false); - //} - - return bBoxBusy == false; + return UpdateMenu(pBox, iSandBoxeCount, bBoxBusy, pProcess, iProcessCount, iGroupe); } void CSbieView::OnMenu(const QPoint& Point) @@ -532,6 +677,7 @@ void CSbieView::OnMenu(const QPoint& Point) return; UpdateMenu(); + CPanelView::OnMenu(Point); } @@ -848,7 +994,7 @@ void CSbieView::OnSandBoxAction(QAction* Action) Results.append(SandBoxes.first()->RunStart("mail_agent")); else if (Action == m_pMenuRunExplorer) { - if (theConf->GetBool("Options/AdvancedView", true) == false && theConf->GetBool("Options/BoxedExplorerInfo", true)) + if (theConf->GetInt("Options/ViewMode", 1) != 1 && theConf->GetBool("Options/BoxedExplorerInfo", true)) { bool State = false; CCheckableMessageBox::question(this, "Sandboxie-Plus", @@ -895,33 +1041,9 @@ void CSbieView::OnSandBoxAction(QAction* Action) else if (Action == m_pMenuPresetsRecovery) m_pMenuPresetsRecovery->setChecked(SandBoxes.first()->SetBool("AutoRecover", m_pMenuPresetsRecovery->isChecked())); else if (Action == m_pMenuOptions) - { - OnDoubleClicked(m_pSbieTree->selectedRows().first()); - } + ShowOptions(SandBoxes.first()); else if (Action == m_pMenuBrowse) - { - if (SandBoxes.first()->IsEmpty()) { - QMessageBox("Sandboxie-Plus", tr("This Sandbox is empty."), QMessageBox::Information, QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton, this).exec(); - return; - } - - CSandBoxPtr pBox = SandBoxes.first(); - - static QMap FileBrowserWindows; - CFileBrowserWindow* pFileBrowserWindow = FileBrowserWindows.value(pBox.data()); - if (pFileBrowserWindow == NULL) { - pFileBrowserWindow = new CFileBrowserWindow(SandBoxes.first()); - FileBrowserWindows.insert(pBox.data(), pFileBrowserWindow); - connect(pFileBrowserWindow, &CFileBrowserWindow::Closed, [this, pBox]() { - FileBrowserWindows.remove(pBox.data()); - }); - SafeShow(pFileBrowserWindow); - } - else { - pFileBrowserWindow->setWindowState((pFileBrowserWindow->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); - SetForegroundWindow((HWND)pFileBrowserWindow->winId()); - } - } + ShowBrowse(SandBoxes.first()); else if (Action == m_pMenuRefresh) { foreach(const CSandBoxPtr& pBox, SandBoxes) @@ -936,7 +1058,7 @@ void CSbieView::OnSandBoxAction(QAction* Action) return; } - if (theConf->GetBool("Options/AdvancedView", true) == false && theConf->GetBool("Options/ExplorerInfo", true)) + if (theConf->GetInt("Options/ViewMode", 1) != 1 && theConf->GetBool("Options/ExplorerInfo", true)) { bool State = false; CCheckableMessageBox::question(this, "Sandboxie-Plus", @@ -1304,6 +1426,45 @@ void CSbieView::OnProcessAction(QAction* Action) CSandMan::CheckResults(Results); } +void CSbieView::ShowOptions(const CSandBoxPtr& pBox) +{ + auto pBoxEx = pBox.objectCast(); + if (pBoxEx->m_pOptionsWnd == NULL) { + pBoxEx->m_pOptionsWnd = new COptionsWindow(pBox, pBox->GetName()); + connect(pBoxEx->m_pOptionsWnd, &COptionsWindow::Closed, [pBoxEx]() { + pBoxEx->m_pOptionsWnd = NULL; + }); + SafeShow(pBoxEx->m_pOptionsWnd); + } + else { + pBoxEx->m_pOptionsWnd->setWindowState((pBoxEx->m_pOptionsWnd->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); + SetForegroundWindow((HWND)pBoxEx->m_pOptionsWnd->winId()); + } +} + +void CSbieView::ShowBrowse(const CSandBoxPtr& pBox) +{ + if (pBox->IsEmpty()) { + QMessageBox("Sandboxie-Plus", tr("This Sandbox is empty."), QMessageBox::Information, QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton, this).exec(); + return; + } + + static QMap FileBrowserWindows; + CFileBrowserWindow* pFileBrowserWindow = FileBrowserWindows.value(pBox.data()); + if (pFileBrowserWindow == NULL) { + pFileBrowserWindow = new CFileBrowserWindow(pBox); + FileBrowserWindows.insert(pBox.data(), pFileBrowserWindow); + connect(pFileBrowserWindow, &CFileBrowserWindow::Closed, [this, pBox]() { + FileBrowserWindows.remove(pBox.data()); + }); + SafeShow(pFileBrowserWindow); + } + else { + pFileBrowserWindow->setWindowState((pFileBrowserWindow->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); + SetForegroundWindow((HWND)pFileBrowserWindow->winId()); + } +} + void CSbieView::OnDoubleClicked(const QModelIndex& index) { QModelIndex ModelIndex = m_pSortProxy->mapToSource(index); @@ -1327,20 +1488,11 @@ void CSbieView::OnDoubleClicked(const QModelIndex& index) if (QMessageBox("Sandboxie-Plus", tr("This sandbox is disabled, do you want to enable it?"), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton, this).exec() != QMessageBox::Yes) return; pBox->SetText("Enabled", "y"); + return; } - - auto pBoxEx = pBox.objectCast(); - if (pBoxEx->m_pOptionsWnd == NULL) { - pBoxEx->m_pOptionsWnd = new COptionsWindow(pBox, pBox->GetName()); - connect(pBoxEx->m_pOptionsWnd, &COptionsWindow::Closed, [pBoxEx]() { - pBoxEx->m_pOptionsWnd = NULL; - }); - SafeShow(pBoxEx->m_pOptionsWnd); - } - else { - pBoxEx->m_pOptionsWnd->setWindowState((pBoxEx->m_pOptionsWnd->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); - SetForegroundWindow((HWND)pBoxEx->m_pOptionsWnd->winId()); - } + + + ShowOptions(pBox); } void CSbieView::ProcessSelection(const QItemSelection& selected, const QItemSelection& deselected) @@ -1461,14 +1613,22 @@ void CSbieView::SelectBox(const QString& Name) void CSbieView::PopUpMenu(const QString& Name) { - SelectBox(Name); - if (!UpdateMenu()) - return; + //SelectBox(Name); + CSandBoxPtr pBox = theAPI->GetBoxByName(Name); + if (pBox.isNull() || !UpdateMenu(pBox)) return; m_pMenu2->exec(QCursor::pos()); //m_pMenu2->popup(QCursor::pos()); //OnMenu(QCursor::pos()); } +QMenu* CSbieView::GetMenu(const QString& Name) +{ + CSandBoxPtr pBox = theAPI->GetBoxByName(Name); + if (pBox.isNull()) return NULL; + UpdateMenu(pBox); + return m_pMenu; +} + void CSbieView::ShowOptions(const QString& Name) { QModelIndex Index = m_pSbieModel->FindIndex(Name); diff --git a/SandboxiePlus/SandMan/Views/SbieView.h b/SandboxiePlus/SandMan/Views/SbieView.h index f39eb4ac..010f67fa 100644 --- a/SandboxiePlus/SandMan/Views/SbieView.h +++ b/SandboxiePlus/SandMan/Views/SbieView.h @@ -26,7 +26,10 @@ public: virtual void SelectBox(const QString& Name); virtual void PopUpMenu(const QString& Name); + virtual QMenu* GetMenu(const QString& Name); virtual void ShowOptions(const QString& Name); + virtual void ShowOptions(const CSandBoxPtr& pBox); + virtual void ShowBrowse(const CSandBoxPtr& pBox); QMap GetGroups() { return m_Groups; } @@ -71,6 +74,11 @@ protected: private: + void CreateMenu(); + void CreateOldMenu(); + void CreatTrayMenu(); + + bool UpdateMenu(const CSandBoxPtr &pBox, int iSandBoxeCount = 1, bool bBoxBusy = false, const CBoxedProcessPtr &pProcess = CBoxedProcessPtr(), int iProcessCount = 0, int iGroupe = 0); bool UpdateMenu(); void UpdateGroupMenu(); void RenameGroup(const QString OldName, const QString NewName); @@ -131,6 +139,7 @@ private: QAction* m_pMenuRecover; QAction* m_pMenuCleanUp; QAction* m_pMenuRemove; + QMenu* m_pMenuTools; QAction* m_pMenuDuplicate; QAction* m_pMenuMoveUp; //QAction* m_pMenuMoveBy; diff --git a/SandboxiePlus/SandMan/Views/TraceView.cpp b/SandboxiePlus/SandMan/Views/TraceView.cpp index 8678b869..13a2f10f 100644 --- a/SandboxiePlus/SandMan/Views/TraceView.cpp +++ b/SandboxiePlus/SandMan/Views/TraceView.cpp @@ -151,7 +151,7 @@ CMonitorList::~CMonitorList() //////////////////////////////////////////////////////////////////////////////////////// // CTraceView -CTraceView::CTraceView(QWidget* parent) : QWidget(parent) +CTraceView::CTraceView(bool bStandAlone, QWidget* parent) : QWidget(parent) { //m_pTreeList->setItemDelegate(theGUI->GetItemDelegate()); @@ -220,9 +220,13 @@ CTraceView::CTraceView(QWidget* parent) : QWidget(parent) connect(m_pTraceStatus, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSetFilter())); m_pTraceToolBar->addWidget(m_pTraceStatus); - m_pAllBoxes = m_pTraceToolBar->addAction(CSandMan::GetIcon("All"), tr("Show All Boxes"), this, SLOT(OnSetFilter())); - m_pAllBoxes->setCheckable(true); - m_pAllBoxes->setChecked(theConf->GetBool("Options/UseLogTree")); + if (bStandAlone) + m_pAllBoxes = NULL; + else { + m_pAllBoxes = m_pTraceToolBar->addAction(CSandMan::GetIcon("All"), tr("Show All Boxes"), this, SLOT(OnSetFilter())); + m_pAllBoxes->setCheckable(true); + m_pAllBoxes->setChecked(theConf->GetBool("Options/UseLogTree")); + } m_pTraceToolBar->addSeparator(); @@ -233,12 +237,19 @@ CTraceView::CTraceView(QWidget* parent) : QWidget(parent) m_pMainLayout->addWidget(m_pTraceToolBar); - m_pView = new QWidget(this); m_pLayout = new QStackedLayout(m_pView); m_pTrace = new CTraceTree(this); ((CTraceModel*)m_pTrace->GetModel())->SetTree(m_pTraceTree->isChecked()); + + if (bStandAlone) { + QAction* pAction = new QAction(tr("Cleanup Trace Log")); + connect(pAction, SIGNAL(triggered()), this, SLOT(Clear())); + m_pTrace->GetMenu()->insertAction(m_pTrace->GetMenu()->actions()[0], pAction); + m_pTrace->GetMenu()->insertSeparator(m_pTrace->GetMenu()->actions()[0]); + } + m_pLayout->addWidget(m_pTrace); QObject::connect(m_pTrace, SIGNAL(FilterSet(const QRegExp&, bool, int)), this, SLOT(SetFilter(const QRegExp&, bool, int))); @@ -249,14 +260,22 @@ CTraceView::CTraceView(QWidget* parent) : QWidget(parent) m_pView->setLayout(m_pLayout); m_pMainLayout->addWidget(m_pView); - OnSetMode(); - + + m_uTimerID = startTimer(1000); } CTraceView::~CTraceView() { - + killTimer(m_uTimerID); +} + +void CTraceView::timerEvent(QTimerEvent* pEvent) +{ + if (pEvent->timerId() != m_uTimerID) + return; + + Refresh(); } int CTraceView__Filter(const CTraceEntryPtr& pEntry, void* params) @@ -306,7 +325,7 @@ int CTraceView__Filter(const CTraceEntryPtr& pEntry, void* params) void CTraceView::Refresh() { QListBoxes; - if(!m_pAllBoxes->isChecked()) + if(m_pAllBoxes && !m_pAllBoxes->isChecked()) Boxes = theGUI->GetBoxView()->GetSelectedBoxes(); if (m_pCurrentBox != (Boxes.count() == 1 ? Boxes.first().data() : NULL)) { @@ -588,4 +607,45 @@ void CTraceView::SaveToFile() } File.close(); +} + + +//////////////////////////////////////////////////////////////////////////////////////// +// CTraceWindow + +CTraceWindow::CTraceWindow(QWidget *parent) + : QDialog(parent) +{ + Qt::WindowFlags flags = windowFlags(); + flags |= Qt::CustomizeWindowHint; + //flags &= ~Qt::WindowContextHelpButtonHint; + //flags &= ~Qt::WindowSystemMenuHint; + //flags &= ~Qt::WindowMinMaxButtonsHint; + //flags |= Qt::WindowMinimizeButtonHint; + //flags &= ~Qt::WindowCloseButtonHint; + flags &= ~Qt::WindowContextHelpButtonHint; + //flags &= ~Qt::WindowSystemMenuHint; + setWindowFlags(flags); + + this->setWindowTitle(tr("Sandboxie-Plus - Trace Monitor")); + + QGridLayout* pLayout = new QGridLayout(); + pLayout->setMargin(3); + pLayout->addWidget(new CTraceView(true, this), 0, 0); + this->setLayout(pLayout); + + restoreGeometry(theConf->GetBlob("TraceWindow/Window_Geometry")); +} + +CTraceWindow::~CTraceWindow() +{ + theConf->SetBlob("TraceWindow/Window_Geometry", saveGeometry()); + + theAPI->EnableMonitor(false); +} + +void CTraceWindow::closeEvent(QCloseEvent *e) +{ + emit Closed(); + this->deleteLater(); } \ No newline at end of file diff --git a/SandboxiePlus/SandMan/Views/TraceView.h b/SandboxiePlus/SandMan/Views/TraceView.h index facf40e2..d6c74182 100644 --- a/SandboxiePlus/SandMan/Views/TraceView.h +++ b/SandboxiePlus/SandMan/Views/TraceView.h @@ -44,15 +44,15 @@ class CTraceView : public QWidget { Q_OBJECT public: - CTraceView(QWidget* parent = 0); + CTraceView(bool bStandAlone, QWidget* parent = 0); ~CTraceView(); - void Refresh(); - void Clear(); - void AddAction(QAction* pAction); public slots: + void Refresh(); + void Clear(); + void OnSetTree(); void OnSetMode(); void OnSetPidFilter(); @@ -66,6 +66,9 @@ private slots: void SaveToFile(); protected: + void timerEvent(QTimerEvent* pEvent); + int m_uTimerID; + struct SProgInfo { QString Name; @@ -109,4 +112,19 @@ protected: QWidget* m_pView; QStackedLayout* m_pLayout; -}; \ No newline at end of file +}; + +class CTraceWindow : public QDialog +{ + Q_OBJECT + +public: + CTraceWindow(QWidget *parent = Q_NULLPTR); + ~CTraceWindow(); + +signals: + void Closed(); + +protected: + void closeEvent(QCloseEvent *e); +}; diff --git a/SandboxiePlus/SandMan/Windows/SettingsWindow.cpp b/SandboxiePlus/SandMan/Windows/SettingsWindow.cpp index f7e5b1e0..500f9af8 100644 --- a/SandboxiePlus/SandMan/Windows/SettingsWindow.cpp +++ b/SandboxiePlus/SandMan/Windows/SettingsWindow.cpp @@ -84,14 +84,15 @@ CSettingsWindow::CSettingsWindow(QWidget *parent) ui.tabs->setTabPosition(QTabWidget::West); ui.tabs->tabBar()->setStyle(new CustomTabStyle(ui.tabs->tabBar()->style())); - ui.tabs->setTabIcon(0, CSandMan::GetIcon("Options")); - ui.tabs->setTabIcon(1, CSandMan::GetIcon("Shell")); - ui.tabs->setTabIcon(2, CSandMan::GetIcon("Advanced")); - ui.tabs->setTabIcon(3, CSandMan::GetIcon("Ampel")); - ui.tabs->setTabIcon(4, CSandMan::GetIcon("Lock")); - ui.tabs->setTabIcon(5, CSandMan::GetIcon("Compatibility")); - ui.tabs->setTabIcon(6, CSandMan::GetIcon("EditIni")); - ui.tabs->setTabIcon(7, CSandMan::GetIcon("Support")); + ui.tabs->setTabIcon(eOptions, CSandMan::GetIcon("Options")); + ui.tabs->setTabIcon(eShell, CSandMan::GetIcon("Shell")); + ui.tabs->setTabIcon(eGuiConfig, CSandMan::GetIcon("GUI")); + ui.tabs->setTabIcon(eAdvanced, CSandMan::GetIcon("Advanced")); + ui.tabs->setTabIcon(eProgCtrl, CSandMan::GetIcon("Ampel")); + ui.tabs->setTabIcon(eConfigLock, CSandMan::GetIcon("Lock")); + ui.tabs->setTabIcon(eSoftCompat, CSandMan::GetIcon("Compatibility")); + ui.tabs->setTabIcon(eEditIni, CSandMan::GetIcon("EditIni")); + ui.tabs->setTabIcon(eSupport, CSandMan::GetIcon("Support")); ui.tabs->setCurrentIndex(0); @@ -106,6 +107,7 @@ CSettingsWindow::CSettingsWindow(QWidget *parent) QString Lang = Locale.nativeLanguageName(); ui.uiLang->addItem(Lang, Code); } + ui.uiLang->setCurrentIndex(ui.uiLang->findData(theConf->GetString("Options/UiLanguage"))); ui.cmbSysTray->addItem(tr("Don't show any icon")); ui.cmbSysTray->addItem(tr("Show Plus icon")); @@ -120,7 +122,13 @@ CSettingsWindow::CSettingsWindow(QWidget *parent) ui.cmbOnClose->addItem(tr("Close"), "Close"); - ui.uiLang->setCurrentIndex(ui.uiLang->findData(theConf->GetString("Options/UiLanguage"))); + ui.cmbDPI->addItem(tr("None"), 0); + ui.cmbDPI->addItem(tr("Native"), 1); + ui.cmbDPI->addItem(tr("Qt"), 2); + + 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 settings("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", QSettings::NativeFormat); if (settings.value("CurrentBuild").toInt() >= 22000) { // Windows 11 @@ -132,6 +140,17 @@ CSettingsWindow::CSettingsWindow(QWidget *parent) LoadSettings(); + connect(ui.uiLang, SIGNAL(currentIndexChanged(int)), this, SLOT(OnChangeGUI())); + + connect(ui.cmbDPI, SIGNAL(currentIndexChanged(int)), this, SLOT(OnChangeGUI())); + connect(ui.chkDarkTheme, 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.cmbFontScale, SIGNAL(currentIndexChanged(int)), this, SLOT(OnChangeGUI())); + + + m_bRebuildUI = false; connect(ui.cmbSysTray, SIGNAL(currentIndexChanged(int)), this, SLOT(OnChange())); connect(ui.cmbTrayBoxes, SIGNAL(currentIndexChanged(int)), this, SLOT(OnChange())); @@ -204,18 +223,15 @@ CSettingsWindow::~CSettingsWindow() theConf->SetBlob("SettingsWindow/Window_Geometry",saveGeometry()); } -void CSettingsWindow::showCompat() +void CSettingsWindow::showTab(int Tab) { - m_CompatLoaded = 2; - ui.tabs->setCurrentWidget(ui.tabCompat); - SafeShow(this); -} + if(Tab == CSettingsWindow::eSoftCompat) + m_CompatLoaded = 2; + else if(Tab == CSettingsWindow::eSupport) + ui.chkNoCheck->setVisible(true); -void CSettingsWindow::showSupport() -{ - ui.tabs->setCurrentWidget(ui.tabSupport); + ui.tabs->setCurrentIndex(Tab); SafeShow(this); - ui.chkNoCheck->setVisible(true); } void CSettingsWindow::closeEvent(QCloseEvent *e) @@ -299,7 +315,14 @@ void CSettingsWindow::LoadSettings() 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.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.cmbFontScale->setCurrentIndex(ui.cmbFontScale->findData(theConf->GetInt("Options/FontScaling", 100))); ui.chkNotifications->setChecked(theConf->GetBool("Options/ShowNotifications", true)); @@ -337,6 +360,7 @@ void CSettingsWindow::LoadSettings() 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", true)); ui.chkAdminOnly->setChecked(theAPI->GetGlobalSettings()->GetBool("EditAdminOnly", false)); ui.chkPassRequired->setChecked(!theAPI->GetGlobalSettings()->GetText("EditPassword", "").isEmpty()); @@ -362,6 +386,7 @@ void CSettingsWindow::LoadSettings() 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.chkAdminOnly->setEnabled(false); @@ -428,7 +453,14 @@ 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/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/FontScaling", ui.cmbFontScale->currentData()); AutorunEnable(ui.chkAutoStart->isChecked()); @@ -443,8 +475,10 @@ void CSettingsWindow::SaveSettings() if (ui.chkShellMenu->checkState() != CSettingsWindow__IsContextMenu()) { - if (ui.chkShellMenu->isChecked()) - CSettingsWindow__AddContextMenu(); + if (ui.chkShellMenu->isChecked()) { + CSecretCheckBox* SecretCheckBox = qobject_cast(ui.chkShellMenu); + CSettingsWindow__AddContextMenu(SecretCheckBox && SecretCheckBox->IsSecretSet()); + } else CSettingsWindow__RemoveContextMenu(); } @@ -503,6 +537,7 @@ void CSettingsWindow::SaveSettings() theAPI->GetGlobalSettings()->SetBool("NetworkEnableWFP", ui.chkWFP->isChecked()); theAPI->GetGlobalSettings()->SetBool("EnableObjectFiltering", ui.chkObjCb->isChecked()); theAPI->GetGlobalSettings()->SetBool("EnableWin32kHooks", ui.chkWin32k->isChecked()); + theAPI->GetGlobalSettings()->SetBool("SandboxieLogon", ui.chkSbieLogon->isChecked()); if (m_FeaturesChanged) { @@ -618,7 +653,7 @@ void CSettingsWindow::SaveSettings() theConf->SetValue("Options/NoSupportCheck", ui.chkNoCheck->isChecked()); - emit OptionsChanged(); + emit OptionsChanged(m_bRebuildUI); } bool CSettingsWindow::ApplyCertificate(const QByteArray &Certificate, QWidget* widget) @@ -934,13 +969,10 @@ void CSettingsWindow::CertChanged() ui.txtCertificate->setPalette(palette); } -void CSettingsWindow::LoadCertificate() +void CSettingsWindow::LoadCertificate(QString CertPath) { - QString CertPath; if (theAPI && theAPI->IsConnected()) CertPath = theAPI->GetSbiePath() + "\\Certificate.dat"; - else - CertPath = QCoreApplication::applicationDirPath() + "\\Certificate.dat"; QFile CertFile(CertPath); if (CertFile.open(QFile::ReadOnly)) { diff --git a/SandboxiePlus/SandMan/Windows/SettingsWindow.h b/SandboxiePlus/SandMan/Windows/SettingsWindow.h index fa275377..820e2b13 100644 --- a/SandboxiePlus/SandMan/Windows/SettingsWindow.h +++ b/SandboxiePlus/SandMan/Windows/SettingsWindow.h @@ -49,24 +49,36 @@ public: static bool ApplyCertificate(const QByteArray &Certificate, QWidget* widget); - static void LoadCertificate(); + static void LoadCertificate(QString CertPath = QString()); + + enum ETabs { + eOptions = 0, + eShell, + eGuiConfig, + eAdvanced, + eProgCtrl, + eConfigLock, + eSoftCompat, + eEditIni, + eSupport + }; signals: - void OptionsChanged(); + void OptionsChanged(bool bRebuildUI = false); void Closed(); public slots: void ok(); void apply(); - void showCompat(); - void showSupport(); + void showTab(int Tab); private slots: void OnChange(); void OnTab(); + void OnChangeGUI() { m_bRebuildUI = true; } void OnFeaturesChanged() { m_FeaturesChanged = true; } void OnBrowse(); @@ -103,6 +115,7 @@ protected: void LoadIniSection(); void SaveIniSection(); + bool m_bRebuildUI; int m_CompatLoaded; QString m_NewPassword; bool m_WarnProgsChanged; diff --git a/SandboxiePlus/SandMan/Wizards/SetupWizard.cpp b/SandboxiePlus/SandMan/Wizards/SetupWizard.cpp index 3a8bc4de..24e4233b 100644 --- a/SandboxiePlus/SandMan/Wizards/SetupWizard.cpp +++ b/SandboxiePlus/SandMan/Wizards/SetupWizard.cpp @@ -61,9 +61,11 @@ bool CSetupWizard::ShowWizard() //bool isEvaluate = wizard.field("isEvaluate").toBool(); if (wizard.field("useAdvanced").toBool()) - theConf->SetValue("Options/AdvancedView", true); + theConf->SetValue("Options/ViewMode", 1); else if (wizard.field("useSimple").toBool()) - theConf->SetValue("Options/AdvancedView", false); + theConf->SetValue("Options/ViewMode", 0); + else if (wizard.field("useClassic").toBool()) + theConf->SetValue("Options/ViewMode", 2); if (wizard.field("useBrightMode").toInt()) theConf->SetValue("Options/UseDarkTheme", 0); @@ -89,8 +91,7 @@ bool CSetupWizard::ShowWizard() theConf->SetValue("Options/WizardLevel", 1); - theGUI->SetViewMode(theConf->GetBool("Options/AdvancedView", true)); - theGUI->UpdateSettings(); + theGUI->UpdateSettings(true); return true; @@ -269,40 +270,46 @@ CUIPage::CUIPage(QWidget* parent) QGridLayout* layout = new QGridLayout; m_pAdvanced = new QRadioButton(tr("&Advanced UI for experts")); - m_pAdvanced->setChecked(theConf->GetBool("Options/AdvancedView", true)); + m_pAdvanced->setChecked(theConf->GetInt("Options/ViewMode", 1) == 1); layout->addWidget(m_pAdvanced, 0, 0); registerField("useAdvanced", m_pAdvanced); m_pSimple = new QRadioButton(tr("&Simple UI for beginners")); - m_pSimple->setChecked(!theConf->GetBool("Options/AdvancedView", true)); + m_pSimple->setChecked(theConf->GetInt("Options/ViewMode", 1) == 0); layout->addWidget(m_pSimple, 1, 0); registerField("useSimple", m_pSimple); + m_pClassic = new QRadioButton(tr("&Classic Sandboxie UI")); + m_pClassic->setChecked(theConf->GetInt("Options/ViewMode", 1) == 2); + layout->addWidget(m_pClassic, 2, 0); + registerField("useClassic", m_pClassic); + QButtonGroup *buttonGroup1 = new QButtonGroup(); buttonGroup1->addButton(m_pAdvanced, 0); buttonGroup1->addButton(m_pSimple, 1); + buttonGroup1->addButton(m_pClassic, 2); connect(buttonGroup1, SIGNAL(buttonClicked(int)), this, SLOT(UpdatePreview())); QLabel* pDummy = new QLabel(); pDummy->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - layout->addWidget(pDummy, 0, 1, 5, 4); + layout->addWidget(pDummy, 0, 1, 6, 4); pDummy->setStyleSheet("QLabel { background-color : " + QApplication::palette().color(QPalette::Base).name() + "; }"); m_pPreview = new QLabel(); m_pPreview->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); m_pPreview->setAlignment(Qt::AlignLeft | Qt::AlignTop); - layout->addWidget(m_pPreview, 0, 1, 5, 4); + layout->addWidget(m_pPreview, 0, 1, 6, 4); QWidget* pSpacer = new QWidget(); pSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - layout->addWidget(pSpacer, 2, 0); + layout->addWidget(pSpacer, 3, 0); m_pBrightMode = new QRadioButton(tr("Use Bright Mode")); - layout->addWidget(m_pBrightMode, 3, 0); + layout->addWidget(m_pBrightMode, 4, 0); registerField("useBrightMode", m_pBrightMode); m_pDarkMode = new QRadioButton(tr("Use Dark Mode")); - layout->addWidget(m_pDarkMode, 4, 0); + layout->addWidget(m_pDarkMode, 5, 0); registerField("useDarkMode", m_pDarkMode); QButtonGroup *buttonGroup2 = new QButtonGroup(); @@ -346,6 +353,10 @@ void CUIPage::UpdatePreview() preview = QPixmap::fromImage(QImage(":/Assets/Simple.png")); else if(m_pSimple->isChecked() && bDark) preview = QPixmap::fromImage(QImage(":/Assets/SimpleD.png")); + else if(m_pClassic->isChecked() && !bDark) + preview = QPixmap::fromImage(QImage(":/Assets/Classic.png")); + else if(m_pClassic->isChecked() && bDark) + preview = QPixmap::fromImage(QImage(":/Assets/ClassicD.png")); //QRect rect(0, 0, m_pPreview->width(), m_pPreview->height()); //m_pPreview->setPixmap(preview.scaled(preview.width()*5/10, preview.height()*5/10, Qt::KeepAspectRatio, Qt::SmoothTransformation).copy(rect)); @@ -394,6 +405,7 @@ CShellPage::CShellPage(QWidget *parent) int CShellPage::nextId() const { return CSetupWizard::Page_WFP; + //return CSetupWizard::Page_Finish; } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/SandboxiePlus/SandMan/Wizards/SetupWizard.h b/SandboxiePlus/SandMan/Wizards/SetupWizard.h index 33276fd1..500dac0c 100644 --- a/SandboxiePlus/SandMan/Wizards/SetupWizard.h +++ b/SandboxiePlus/SandMan/Wizards/SetupWizard.h @@ -86,6 +86,7 @@ private slots: private: QRadioButton *m_pSimple; QRadioButton *m_pAdvanced; + QRadioButton *m_pClassic; QLabel* m_pPreview; QRadioButton* m_pBrightMode; QRadioButton* m_pDarkMode; diff --git a/SandboxiePlus/SandMan/main.cpp b/SandboxiePlus/SandMan/main.cpp index 417aefa2..5dcc2f39 100644 --- a/SandboxiePlus/SandMan/main.cpp +++ b/SandboxiePlus/SandMan/main.cpp @@ -15,22 +15,43 @@ QString g_PendingMessage; int main(int argc, char *argv[]) { -#ifdef Q_OS_WIN - //SetProcessDPIAware(); - //SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE); - //SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE); - - typedef DPI_AWARENESS_CONTEXT(WINAPI* P_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT dpiContext); - P_SetThreadDpiAwarenessContext pSetThreadDpiAwarenessContext = (P_SetThreadDpiAwarenessContext)GetProcAddress(GetModuleHandle(L"user32.dll"), "SetThreadDpiAwarenessContext"); - if(pSetThreadDpiAwarenessContext) // not rpesent on windows 7 - pSetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE); - -#endif // Q_OS_WIN - //QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - //QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling); - qsrand(QTime::currentTime().msec()); + wchar_t szPath[MAX_PATH]; + GetModuleFileNameW(NULL, szPath, ARRAYSIZE(szPath)); + *wcsrchr(szPath, L'\\') = L'\0'; + QString AppDir = QString::fromWCharArray(szPath); + + if (QFile::exists(AppDir + "\\Certificate.dat")) { + CSettingsWindow::LoadCertificate(AppDir + "\\Certificate.dat"); + g_CertInfo.business = GetArguments(g_Certificate, L'\n', L':').value("TYPE").toUpper().contains("BUSINESS"); + } + + // use a shared setting location when used in a business environment for easier administration + theConf = new CSettings(AppDir, "Sandboxie-Plus", g_CertInfo.business); + + + // this must be done before we create QApplication + int DPI = theConf->GetInt("Options/DPIScaling", 1); + if (DPI == 1) { + //SetProcessDPIAware(); + //SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE); + //SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE); + typedef DPI_AWARENESS_CONTEXT(WINAPI* P_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT dpiContext); + P_SetThreadDpiAwarenessContext pSetThreadDpiAwarenessContext = (P_SetThreadDpiAwarenessContext)GetProcAddress(GetModuleHandle(L"user32.dll"), "SetThreadDpiAwarenessContext"); + if(pSetThreadDpiAwarenessContext) // not present on windows 7 + pSetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE); + else + SetProcessDPIAware(); + } + else if (DPI == 2) { + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + } + //else { + // QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling); + //} + + QtSingleApplication app(argc, argv); app.setQuitOnLastWindowClosed(false); @@ -98,15 +119,6 @@ int main(int argc, char *argv[]) else if (app.sendMessage("ShowWnd")) return 0; - - if (QFile::exists(QCoreApplication::applicationDirPath() + "\\Certificate.dat")) { - CSettingsWindow::LoadCertificate(); - g_CertInfo.business = GetArguments(g_Certificate, L'\n', L':').value("TYPE").toUpper().contains("BUSINESS"); - } - - // use a shared setting location when used in a business environment for easier administration - theConf = new CSettings("Sandboxie-Plus", g_CertInfo.business); - #ifndef _DEBUG InitMiniDumpWriter(QString("SandMan-v%1").arg(CSandMan::GetVersion()).toStdWString().c_str() , QString(theConf->GetConfigDir()).replace("/", "\\").toStdWString().c_str()); #endif diff --git a/SandboxiePlus/SandMan/sandman_sv_SE.ts b/SandboxiePlus/SandMan/sandman_sv_SE.ts index 5813eb16..ddb1f8e5 100644 --- a/SandboxiePlus/SandMan/sandman_sv_SE.ts +++ b/SandboxiePlus/SandMan/sandman_sv_SE.ts @@ -4,27 +4,27 @@ CCertificatePage - + Install your <b>Sandboxie-Plus</b> support certificate Installera ditt <b>Sandboxie-Plus</b> supportcertifikat - + If you have a supporter certificate, please fill it into the field below. Om du har ett supportercertifikat, vänligen ange det i fältet nedan. - + Start evaluation without a certificate for a limited period of time. Starta en evaluering utan ett certifikat för en begränsad tidsperiod. - + To use <b>Sandboxie-Plus</b> in a business setting, an appropriate <a href="https://sandboxie-plus.com/go.php?to=sbie-get-cert">support certificate</a> for business use is required. If you do not yet have the required certificate(s), you can get those from the <a href="https://xanasoft.com/shop/">xanasoft.com web shop</a>. För att använda <b>Sandboxie-Plus</b> i en affärsmiljö, krävs ett lämpligt <a href="https://sandboxie-plus.com/go.php?to=sbie-get-cert">supportcertifikat</a> för affärsanvändande. Om du ännu inte har det krävda certifikatet kan du skaffa det eller dessa från <a href="https://xanasoft.com/shop/">xanasoft.com webshop</a>. - + <b>Sandboxie-Plus</b> provides additional features and box types exclusively to <u>project supporters</u>. Boxes like the Privacy Enhanced boxes <b><font color='red'>protect user data from illicit access</font></b> by the sandboxed programs. If you are not yet a supporter, then please consider <a href="https://sandboxie-plus.com/go.php?to=sbie-get-cert">supporting the project</a> to ensure further development of Sandboxie and to receive a <a href="https://sandboxie-plus.com/go.php?to=sbie-cert">supporter certificate</a>. <b>Sandboxie-Plus</b> ger ytterligare funktioner och lådtyper exklusivt till <u>projektsupportrar</u>. Lådor likt de integritetsutökade lådorna <b><font color='red'>skyddar användardata från olaglig tillgång</font></b> av de sandlådade programmen. Om du ännu inte är en supporter, vänligen överväg då att <a href="https://sandboxie-plus.com/go.php?to=sbie-get-cert">supporta projektet</a> för att säkerställa fortsatt utveckling av Sandboxie och för att få ett <a href="https://sandboxie-plus.com/go.php?to=sbie-cert">supportercertifikat</a>. @@ -73,17 +73,17 @@ CFinishPage - + Complete your configuration Färdigställ din konfiguration - + Almost complete, click Finish to apply all selected options and conclude the wizard. Nästan färdigt, klicka på Avsluta för att tillämpa alla valda alternativ och avsluta guiden. - + Keep Sandboxie-Plus up to date. Håll Sandboxie-Plus uppdaterat. @@ -91,32 +91,32 @@ CIntroPage - + Introduction Introduktion - + Welcome to the Setup Wizard. This wizard will help you to configure your copy of <b>Sandboxie-Plus</b>. You can start this wizard at any time from the Sandbox->Maintenance menu if you do not wish to complete it now. Välkommen till installationsguiden. Denna guide hjälper dig att konfigurera din kopia av <b>Sandboxie-Plus</b>. Du kan starta denna guide närsomhelst från menyn Sandlåda->Underhåll, om du inte vill fullfölja den nu. - + Select how you would like to use Sandboxie-Plus Välj hur du skulle vilja använda Sandboxie-Plus - + &Personally, for private non-commercial use - Personligen, för privat icke-kommersiell användning + &Personligen, för privat icke-kommersiell användning - + &Commercially, for business or enterprise use - Kommersiellt, för affärs eller företagsanvändande + &Kommersiellt, för affärs eller företagsanvändande - + Note: this option is immutable Notera: Detta alternativ är oföränderligt @@ -212,29 +212,30 @@ COptionsWindow - Sandboxie-Plus - '%1' Options + Sandboxie Plus - '%1' Options + Sandboxie-Plus - '%1' Options Sandboxie-Plus - '%1' Alternativ - - + + Browse for File Bläddra efter fil - + This sandbox has been deleted hence configuration can not be saved. Denna sandlåda har blivit raderad därför kan konfigurationen inte sparas. - + Some changes haven't been saved yet, do you really want to close this options window? Vissa ändringar har inte sparats ännu, vill du verkligen stänga detta alternativsfönster? - + @@ -244,7 +245,7 @@ Grupp: %1 - + Enter program: Ange program: @@ -341,6 +342,8 @@ + + @@ -359,6 +362,7 @@ + @@ -367,57 +371,118 @@ + Template values can not be removed. Mallvärden kan inte tas bort. - - + + Enable the use of win32 hooks for selected processes. Note: You need to enable win32k syscall hook support globally first. + + + + + Enable crash dump creation in the sandbox folder + + + + + Always use ElevateCreateProcess fix, as sometimes applied by the Program Compatibility Assistant. + + + + + Enable special inconsistent PreferExternalManifest behavioure, as neede for some edge fixes + + + + + Set RpcMgmtSetComTimeout usage for specific processes + + + + + Makes a write open call to a file that won't be copied fail instead of turning it read-only. + + + + + Make specified processes think thay have admin permissions. + + + + + Force specified processes to wait for a debugger to attach. + + + + + Sandbox file system root + + + + + Sandbox registry root + + + + + Sandbox ipc root + + + + + Add special option: + + + + + On Start Vid start - - - + + + Run Command Kör kommando - + Start Service Starta tjänst - + On Init Vid start - + On Delete Vid raderande - - - + + + Please enter the command line to be executed Vänligen ange kommandoraden som ska verkställas - + Please enter a service identifier Vänligen ange en tjänstidentifierare - + Please enter a program file name Vänligen ange ett programfilsnamn - + %1 (%2) %1 (%2) @@ -992,27 +1057,27 @@ Full sökväg: %4 - + Select Directory Välj katalog - + Close until all programs stop in this box Stäng tills alla program stoppar i denna låda - + Close and Disable Immediate Recovery for this box Stäng och inaktivera omedelbart återställande för denna låda - + There are %1 new files available to recover. Det finns %1 nya filer tillgängliga att återställa. - + There are %1 files and %2 folders in the sandbox, occupying %3 of disk space. Det finns %1 filer och %2 mappar i sandlådan, som upptar %3 av diskutrymmet. @@ -1020,22 +1085,22 @@ Full sökväg: %4 CSandBox - + Waiting for folder: %1 Väntar på mapp: %1 - + Deleting folder: %1 Raderar mapp: %1 - + Merging folders: %1 &gt;&gt; %2 Sammanför mappar: %1 &gt;&gt; %2 - + Finishing Snapshot Merge... Slutför sammanförande av ögonblicksbilder... @@ -1043,57 +1108,57 @@ Full sökväg: %4 CSandBoxPlus - + Disabled Inaktiverad - + Application Compartment Applikationsutrymme - + NOT SECURE INTE SÄKER - + Reduced Isolation Reducerad isolering - + Enhanced Isolation Utökad isolering - + Privacy Enhanced Integritetsutökad - + API Log API-logg - + No INet Inget INet - + Net Share Nätdelning - + No Admin Ingen admin - + Normal Vanlig @@ -1101,364 +1166,434 @@ Full sökväg: %4 CSandMan - + Sandboxie Manager can not be run sandboxed! Sandboxies hanterare kan inte köras sandlådad! - + WARNING: Sandboxie-Plus.ini in %1 cannot be written to, settings will not be saved. VARNING: Sandboxie-Plus.ini:n i %1 kan inte skrivas till. Inställningarna kommer inte sparas. - - + + Sandboxie-Plus v%1 Sandboxie-Plus v%1 - - + Reset Columns Återställ kolumner - - + Copy Cell Kopiera cellen - - + Copy Row Kopiera raden - - + Copy Panel Kopiera panelen - + + &Sandbox &Sandlåda - + + Create New Box Skapa ny låda - + + Create Box Group Skapa lådgrupp - + + Terminate All Processes Avsluta alla processer - Window Finder - Fönsterfinnare + Fönsterfinnare - - + + + Pause Forcing Programs Pausa programtvingande - + Disable File Recovery Inaktivera filåterställande - + Disable Message PopUp Inaktivera meddelande-popup - + &Maintenance &Underhåll - + Connect Anslut - + Disconnect Koppla ifrån - + Stop All Stoppa alla - + &Advanced &Avancerad - + Install Driver Installera drivrutin - + Start Driver Starta drivrutin - + Stop Driver Stoppa drivrutin - + Uninstall Driver Avinstallera drivrutin - + Install Service Installera tjänst - + Start Service Starta tjänst - + Stop Service Stoppa tjänst - + Uninstall Service Avinstallera tjänst - + Setup Wizard Konfigureringsguide - + Uninstall All Avinstallera alla - + + Exit Avsluta - + + &View &Översikt - + Simple View Enkel översikt - + Advanced View Avancerad översikt - + + Classic View + Klassisk vy + + + Always on Top Alltid överst - + + + Import Box + Importera låda + + + + + Is Window Sandboxed + Är fönstret sandlådat + + + Show Hidden Boxes Visa dolda lådor - + Show All Sessions Visa alla sessioner - + + Refresh View Uppdatera översikten - + Clean Up Rensa - + Cleanup Processes Rensa processer - + Cleanup Message Log Rensa meddelandeloggen - + Cleanup Trace Log Rensa spårloggen - + Cleanup Recovery Log Rensa återställandeloggen - + Keep terminated Behåll avslutad - + &Options &Alternativ - + + Global Settings Globala inställningar - + + Reset all hidden messages Återställ alla dolda meddelanden - + + Reset all GUI options Återställ alla grafiska programpanelalternativ - + + Edit ini file Redigera ini-filen - + + Reload ini file Ladda om ini-filen - + Trace Logging Spårloggning - + &Help &Hjälp - + Support Sandboxie-Plus with a Donation Stöd Sandboxie-Plus med en donation - + Visit Support Forum Besök supportforum - + Online Documentation Internetdokumentation - + Check for Updates Sök efter uppdateringar - + About the Qt Framework Om Qt-ramverket - - + + About Sandboxie-Plus Om Sandboxie-Plus - + + &File + &fil + + + + Resource Access Monitor + Resurstillgångsövervakare + + + + Set Container Folder + Ange containermapp + + + + Reveal Hidden Boxes + Visa dolda lådor + + + + &Configure + &Konfigurera + + + + Program Alerts + Programlarm + + + + Windows Shell Integration + Windows skalintegrering + + + + Software Compatibility + Programkompatibilitet + + + + Lock Configuration + Lås konfigurationen + + + Cleanup Rensa - + <a href="sbie://update/package" style="color: red;">There is a new build of Sandboxie-Plus available</a> <a href="sbie://update/package" style="color: red;">Det finns en ny konstruktion av Sandboxie-Plus tillgänglig</a> - + Click to install update Klicka för att installera uppdateringen - + <a href="https://sandboxie-plus.com/go.php?to=patreon">Support Sandboxie-Plus on Patreon</a> <a href="https://sandboxie-plus.com/go.php?to=patreon">Stöd Sandboxie-Plus på Patreon</a> - + Click to open web browser Klicka för att öppna webläsare - + Time|Message Tid|Meddelande - + Sbie Messages Sbie-meddelanden - + Trace Log Spårlogg - + Time|Box Name|File Path Tid|Lådnamn|Filsökväg - + Recovery Log Återställandelogg - + Show/Hide Visa/Dölj - + Do you want to close Sandboxie Manager? Vill du stänga Sandboxies hanterare? - + Sandboxie-Plus was running in portable mode, now it has to clean up the created services. This will prompt for administrative privileges. Do you want to do the clean up? @@ -1467,32 +1602,32 @@ Do you want to do the clean up? Vill du göra rensningen? - - - - - - + + + + + + Don't show this message again. Visa inte detta meddelande igen. - + This box provides enhanced security isolation, it is suitable to test untrusted software. Denna låda ger utökad säkerhetsisolering, den är lämplig för att testa obetrodd programvara - + This box provides standard isolation, it is suitable to run your software to enhance security. Denna låda ger standardisolering, den är lämplig för att köra din programvara för att utöka säkerheten. - + This box does not enforce isolation, it is intended to be used as an application compartment for software virtualization only. Denna låda påtvingar inte isolering, den är endast avsedd att användas som ett applikationsutrymme för programvaruvirtualisering. - + This box prevents access to all user data locations, except explicitly granted in the Resource Access options. @@ -1501,87 +1636,87 @@ This box prevents access to all user data locations, except explicitly granted i Denna låda förhindrar tillgång till alla användardataplatser, förutom de uttryckligt tillåtna i resurstillgångsalternativen. - + Unknown operation '%1' requested via command line Okänd operation '%1' begärd via kommandolinje - + - Driver/Service NOT Running! - Drivrutin/Tjänst körs INTE! - + - Deleting Sandbox Content - Raderar sandlådeinnehåll - + Do you want to check if there is a new version of Sandboxie-Plus? Vill du kontrollera om det finns en ny version av Sandboxie-Plus? - + Some compatibility templates (%1) are missing, probably deleted, do you want to remove them from all boxes? Några kompatibilitetsmallar (%1) saknas, troligen raderade. Vill du ta bort dem från alla lådor? - + Cleaned up removed templates... Rensade borttagna mallar... - + Executing OnBoxDelete: %1 Verkställer Vidlådraderande: %1 - + Auto Deleting %1 Content Autoraderar %1 innehåll - + Removed Shortcut: %1 Tog bort genväg: %1 - + Added Shortcut to: %1 Lade till genväg till: %1 - + Auto deleting content of %1 Autoraderar innehåll i %1 - + Installation Directory: %1 Installationskatalog: %1 - + Sandboxie-Plus Version: %1 (%2) Sandboxie-Plus version: %1 (%2) - + Current Config: %1 Nuvarande konfiguration: %1 - + Data Directory: %1 Datakatalog: %1 - + - Portable - Portabel - + Sandboxie-Plus was started in portable mode, do you want to put the Sandbox folder into its parent directory? Yes will choose: %1 No will choose: %2 @@ -1590,371 +1725,416 @@ Ja väljer: %1 Nej väljer: %2 - + Default sandbox not found; creating: %1 Standardsandlådan hittades inte; skapar: %1 - + - NOT connected - INTE ansluten - + The program %1 started in box %2 will be terminated in 5 minutes because the box was configured to use features exclusively available to project supporters. Programmet %1 startat i låda %2 kommer att avslutas om 5 minuter för att lådan konfigurerades att använda funktioner exklusivt tillgängliga för projektsupportrar. - + The box %1 is configured to use features exclusively available to project supporters, these presets will be ignored. Lådan %1 är konfigurerad att använda funktioner exklusivt tillgängliga för projektsupportrar, dessa inställningar kommer ignoreras. - + <br /><a href="https://sandboxie-plus.com/go.php?to=sbie-get-cert">Become a project supporter</a>, and receive a <a href="https://sandboxie-plus.com/go.php?to=sbie-cert">supporter certificate</a> <br /><a href="https://sandboxie-plus.com/go.php?to=sbie-get-cert">Bli en projektsupporter</a>, och få ett <a href="https://sandboxie-plus.com/go.php?to=sbie-cert">supportercertifikat</a> - + PID %1: PID %1: - + %1 (%2): %1 (%2): - + The selected feature set is only available to project supporters. Processes started in a box with this feature set enabled without a supporter certificate will be terminated after 5 minutes.<br /><a href="https://sandboxie-plus.com/go.php?to=sbie-get-cert">Become a project supporter</a>, and receive a <a href="https://sandboxie-plus.com/go.php?to=sbie-cert">supporter certificate</a> Den valda funktionsuppsättningen är endast tillgänglig för projektsupportrar. Processer startade i en låda med denna funktionsuppsättning aktiverad utan ett supportercertifikat kommer att avslutas efter 5 minuter.<br /><a href="https://sandboxie-plus.com/go.php?to=sbie-get-cert">Bli en projektsupporter</a>, och få ett <a href="https://sandboxie-plus.com/go.php?to=sbie-cert">supportercertifikat</a> - + The evaluation periode has expired!!! Evalueringsperioden har utgått! - + The supporter certificate is not valid for this build, please get an updated certificate Supportercertifikatet är inte giltigt för denna konstruktion, vänligen skaffa ett uppdaterat certifikat - + The supporter certificate has expired%1, please get an updated certificate Supportercertifikatet har utgått%1, vänligen skaffa ett uppdaterat certifikat - + , but it remains valid for the current build , men det förblir giltigt för nuvarande konstruktion - + The supporter certificate will expire in %1 days, please get an updated certificate Supportercertifikatet utgår om %1 dagar, vänligen skaffa ett uppdaterat certifikat - + Recovering file %1 to %2 Återställer fil %1 till %2 - + The file %1 already exists, do you want to overwrite it? Filen %1 existerar redan, vill du skriva över den? - + Do this for all files! Gör detta för alla filer! - + Failed to recover some files: Misslyckades att återställa några filer: - + Only Administrators can change the config. Endast administratörer kan ändra konfigurationen. - + Please enter the configuration password. Vänligen ange konfigurationslösenordet. - + Login Failed: %1 Logga in misslyckades: %1 - + + Select file name + Välj filnamn + + + + 7-zip Archive (*.7z) + 7-zip arkiv (*.7z) + + + + This Name is already in use, please select an alternative box name + + + + + Importing: %1 + + + + Do you want to terminate all processes in all sandboxes? Vill du avsluta alla processer i alla sandlådor? - + Terminate all without asking Avsluta alla utan att fråga - + Please enter the duration, in seconds, for disabling Forced Programs rules. Vänligen ange varaktigheten, i sekunder, för inaktivering av tvingade programs regler. - + Sandboxie-Plus was started in portable mode and it needs to create necessary services. This will prompt for administrative privileges. Sandboxie-Plus startades i portabelt läge och det behöver skapa nödvändiga tjänster. Detta ger förfrågan om administrativa rättigheter. - + CAUTION: Another agent (probably SbieCtrl.exe) is already managing this Sandboxie session, please close it first and reconnect to take over. FÖRSIKTIG: En annan agent (troligen SbieCtrl.exe) hanterar redan denna Sandboxie-session, vänligen stäng den först och återanslut för att ta över. - - - + + + Sandboxie-Plus - Error Sandboxie-Plus - Fel - + Failed to stop all Sandboxie components Misslyckades att stoppa alla Sandboxie-komponenter - + Failed to start required Sandboxie components Misslyckades att starta krävda Sandboxie-komponenter - + Maintenance operation failed (%1) Underhållsoperation misslyckades (%1) - + Maintenance operation Successful Lyckad underhållsoperation - + Executing maintenance operation, please wait... Verkställer underhållsoperation, vänligen vänta... - + Do you also want to reset hidden message boxes (yes), or only all log messages (no)? Vill du också återställa dolda meddelandelådor (Ja), eller bara alla loggmeddelanden (Nej)? - + The changes will be applied automatically whenever the file gets saved. Ändringarna tillämpas automatiskt närhelst filen sparas. - + The changes will be applied automatically as soon as the editor is closed. Ändringarna tillämpas automatiskt så fort som redigeraren stängs. - + Sandboxie config has been reloaded Sandboxie-konfigurationen har laddats om - + Error Status: 0x%1 (%2) Felstatus: 0x%1 (%2) - + Unknown Okänd - + Administrator rights are required for this operation. Administratörsrättigheter krävs för denna operation. - + Failed to execute: %1 Misslyckades att verkställa: %1 - + Failed to connect to the driver Misslyckades att ansluta till drivrutinen - + Failed to communicate with Sandboxie Service: %1 Misslyckades att kommunicera med Sandboxies tjänst: %1 - + An incompatible Sandboxie %1 was found. Compatible versions: %2 En inkompatibel Sandboxie %1 hittades. Kompatibla versioner: %2 - + Can't find Sandboxie installation path. Kan inte finna Sandboxies installationssökväg - + Failed to copy configuration from sandbox %1: %2 Misslyckades att kopiera konfigurationen från sandlåda %1: %2 - + A sandbox of the name %1 already exists En sandlåda med namnet %1 existerar redan - + Failed to delete sandbox %1: %2 Misslyckades att radera sandlåda %1: %2 - + The sandbox name can not be longer than 32 characters. Sandlådenamnet kan inte vara längre än 32 tecken. - + The sandbox name can not be a device name. Sandlådenamnet kan inte vara en enhets namn. - + The sandbox name can contain only letters, digits and underscores which are displayed as spaces. Sandlådenamnet kan bara innehålla bokstäver, siffror och understrykningar vilka visas som utrymmen. - + Failed to terminate all processes Misslyckades att avsluta alla processer - + Delete protection is enabled for the sandbox Raderingsskydd är aktiverat för sandlådan - + All sandbox processes must be stopped before the box content can be deleted Alla sandlådeprocesser måste stoppas innan lådinnehållet kan raderas - + Error deleting sandbox folder: %1 Fel vid radering av sandlådemapp: %1 - + A sandbox must be emptied before it can be deleted. En sandlåda måste tömmas innan den kan raderas. - + Failed to move directory '%1' to '%2' Misslyckades att flytta katalog '%1' till '%2' - + This Snapshot operation can not be performed while processes are still running in the box. Denna ögonblicksbildoperation kan inte utföras medan processer fortfarande kör i lådan. - + Failed to create directory for new snapshot Misslyckades att skapa katalog för ny ögonblicksbild - + Failed to copy box data files Misslyckades att kopiera låddatafiler - + Snapshot not found Ögonblicksbild hittades inte - + Error merging snapshot directories '%1' with '%2', the snapshot has not been fully merged. Fel vid sammanförande av ögonblicksbildkataloger '%1' med '%2', ögonblicksbilden har inte helt sammanförts. - + Failed to remove old snapshot directory '%1' Misslyckades att ta bort gammal ögonblicksbildkatalog '%1' - + Can't remove a snapshot that is shared by multiple later snapshots Kan inte ta bort en ögonblicksbild som delas av flera senare ögonblicksbilder - + Failed to remove old box data files Misslyckades att ta bort gamla låddatafiler - + You are not authorized to update configuration in section '%1' Du är inte berättigad att uppdatera konfigurationen i sektion '%1' - + Failed to set configuration setting %1 in section %2: %3 Misslyckades att ange konfigurationsinställning %1 i sektion %2: %3 - + Can not create snapshot of an empty sandbox Kan inte skapa ögonblicksbild av en tom sandlåda - + A sandbox with that name already exists En sandlåda med det namnet existerar redan - + The config password must not be longer than 64 characters Konfigurationslösenordet får inte vara längre än 64 tecken - + The operation was canceled by the user Operationen ställdes in av användaren - + + Import/Export not available, 7z.dll could not be loaded + Importera/Exportera ej tillgängligt, 7z.dll kunde ej laddas + + + + Failed to Create Box Archive + Misslyckades att skapa lådarkiv + + + + Failed to open the 7z archive + Misslyckades att öppna 7z-arkivet + + + + Failed to Unpack Box Archive + Misslyckades att packa upp lådarkiv + + + + The sellected 7z file is NOT a Box Archive + Den valda 7z-filen är INTE ett lådarkiv + + + Unknown Error Status: 0x%1 Okänd felstatus: 0x%1 - + Operation failed for %1 item(s). Operationen misslyckades för %1 post(er). - + Do you want to open %1 in a sandboxed (yes) or unsandboxed (no) Web browser? Vill du öppna %1 i en sandlådad (Ja) eller osandlådad (Nej) webläsare? - + Remember choice for later. Kom ihåg valet till senare. @@ -2029,37 +2209,37 @@ Notera: Uppdateringskollen är ofta bakom senaste GitHub-utgivningen för att s <p>En Sandboxie-Plus uppdatering har nerladdats till följande plats:</p><p><a href="%2">%1</a></p><p>Vill du påbörja installationen? Om några program körs sandlådade, kommer de avslutas.</p> - + <h3>About Sandboxie-Plus</h3><p>Version %1</p><p>Copyright (c) 2020-2022 by DavidXanatos</p> <h3>Om Sandboxie-Plus</h3><p>Version %1</p><p>Upphovsrättigheter (c) 2020-2022 av DavidXanatos</p> - + This copy of Sandboxie+ is certified for: %1 Denna kopia av Sandboxie-Plus är certifierad för: %1 - + Sandboxie+ is free for personal and non-commercial use. Sandboxie-Plus är gratis för personlig och icke-kommersiell användning. - + Sandboxie-Plus is an open source continuation of Sandboxie.<br />Visit <a href="https://sandboxie-plus.com">sandboxie-plus.com</a> for more information.<br /><br />%3<br /><br />Driver version: %1<br />Features: %2<br /><br />Icons from <a href="https://icons8.com">icons8.com</a> Sandboxie-Plus är en öppen källa fortsättning av Sandboxie.<br />Besök <a href="https://sandboxie-plus.com">sandboxie-plus.com</a> för mer information.<br /><br />%3<br /><br />Drivrutinversion: %1<br />Funktioner: %2<br /><br />Ikoner från <a href="https://icons8.com">icons8.com</a> - + Checking for certificate... Kontroll av certifikat... - + No certificate found on server! Inget certifikat funnet på servern! - + There is no updated certificate available. Det finns inget uppdaterat certifikat tillgängligt. @@ -2087,42 +2267,42 @@ Notera: Uppdateringskollen är ofta bakom senaste GitHub-utgivningen för att s CSbieModel - + Box Group Lådgrupp - + Empty Tom - + Name Namn - + Process ID Process-ID - + Status Status - + Title Titel - + Info Info - + Path / Command Line Sökväg / Kommandolinje @@ -2272,7 +2452,8 @@ Notera: Uppdateringskollen är ofta bakom senaste GitHub-utgivningen för att s - Generic Mail Klient + Generic Mail Client + Generic Mail Klient Generisk e-postklient @@ -2309,432 +2490,540 @@ Notera: Uppdateringskollen är ofta bakom senaste GitHub-utgivningen för att s CSbieView - + + Create New Box Skapa ny låda - + + Create Box Group Skapa lådgrupp - + + Rename Group Nämnändra grupp - + + Remove Group Ta bort grupp - + + Stop Operations Stoppa operationer - + Run Kör - + Run Program Kör program - + + Start Menu Startmeny - + Run from Start Menu Kör från startmeny - + Default Web Browser Standardwebläsare - + Default eMail Client Standard e-postklient - + Command Prompt Kommandotolken - + Boxed Tools Lådade verktyg - + Command Prompt (as Admin) Kommandotolken (som admin) - + Command Prompt (32-bit) Kommandotolken (32-bit) - + Windows Explorer Windows utforskare - + Registry Editor Registerredigeraren - + Programs and Features Program och funktioner - + Execute Autorun Entries Verkställ autorun-poster - + Terminate All Programs Avsluta alla program - + + Browse Content Bläddra i innehåll - + Box Content Lådinnehåll - - + + + + Create Shortcut Skapa genväg - + + Explore Content Utforska innehåll - + Open Registry Öppna registret - + + Refresh Info Uppdatera info - + + Snapshots Manager Ögonblicksbildhanterare - + Recover Files Återställ filer - + + Delete Content Radera innehåll - + Sandbox Options Sandlådealternativ - + Sandbox Presets Sandlådeförval - + Ask for UAC Elevation Fråga om UAC-förhöjning - + Drop Admin Rights Skippa adminrättigheter - + Emulate Admin Rights Efterlikna adminrättigheter - + Block Internet Access Blockera internettillgång - + Allow Network Shares Tillåt nätverksdelningar - + Immediate Recovery Omedelbart återställande - Duplicate Sandbox - Kopiera sandlåda + Kopiera sandlåda - + + Rename Sandbox Nämnändra sandlåda - + + Move Box/Group Flytta låda/grupp - + + Move Up Flytta upp - + + Move Down Flytta ner - + + Remove Sandbox Ta bort sandlåda - + + Terminate Avsluta - + Preset Förval - + Pin to Run Menu Fäst på körmenyn - + Block and Terminate Blockera och avsluta - + Allow internet access Tillåt internettillgång - + Force into this sandbox Tvinga in i denna sandlåda - + Set Linger Process Ange kvardröjningsprocess - + Set Leader Process Ange ledarprocess - + File root: %1 Filrot: %1 - + Registry root: %1 Registerrot: %1 - IPC rot: %1 + + IPC-rot: %1 + + + + + + Sandbox Tools + Sandlådeverktyg + + + + + Duplicate Box Config + Kopiera lådkonfigurationen + + + + + Export Box + Exportera låda + + + + Run Sandboxed + Kör sandlådad + + + + Run Web Browser + + + + + Run eMail Reader + + + + + Run Any Program + + + + + Run From Start Menu + + + + + Run Windows Explorer + + + + + Terminate Programs + + + + + Quick Recover + + + + + Sandbox Settings + + + + + IPC root: %1 IPC-rot: %1 - + Options: Alternativ: - + - + [None] [Ingen] - + Please enter a new name for the Group. Vänligen ange ett nytt namn för gruppen. - + Do you really want to remove the selected group(s)? Vill du verkligen ta bort vald(a) grupp(er)? - + Move entries by (negative values move up, positive values move down): Flytta poster genom (negativa värden - upp, positiva värden - ner): - + A group can not be its own parent. En grupp kan inte vara sin egna förälder. - + Please enter a new group name Vänligen ange ett nytt gruppnamn - + This name is already used for a Box Group. Detta namn används redan för en lådgrupp. - + This name is already used for a Sandbox. Detta namn används redan för en sandlåda. - - + + + Don't show this message again. Visa inte detta meddelande igen. - - - + + + This Sandbox is empty. Denna sandlåda är tom. - + WARNING: The opened registry editor is not sandboxed, please be careful and only do changes to the pre-selected sandbox locations. VARNING: Den öppnade registerredigeraren är inte sandlådad, vänligen var försiktig och gör endast ändringar till de förvalda sandlådeplatserna. - + Don't show this warning in future Visa inte denna varning i framtiden - + Please enter a new name for the duplicated Sandbox. Vänligen ange ett nytt namn för den kopierade sandlådan. - + %1 Copy %1 kopiera - + + Select file name + Välj filnamn + + + + 7-zip Archive (*.7z) + 7-zip arkiv (*.7z) + + + + Exporting: %1 + Exporterar: %1 + + + Please enter a new name for the Sandbox. Vänligen ange ett nytt namn för sandlådan. - + Do you really want to remove the selected sandbox(es)?<br /><br />Warning: The box content will also be deleted! Vill du verkligen ta bort de(n) valda sandlåd(orna)(an)?<br /><br />Varning: Lådinnehåller kommer också raderas! - + This Sandbox is already empty. Denna sandlåda är redan tom. - + Do you want to delete the content of the selected sandbox? Vill du radera innehållet hos den valda sandlådan? - - + + Also delete all Snapshots Radera också alla ögonblicksbilder - + Do you really want to delete the content of all selected sandboxes? Vill du verkligen radera innehållet hos alla valda sandlådor? - + Do you want to terminate all processes in the selected sandbox(es)? Vill du avsluta alla processer i de(n) valda sandlåd(orna)(an)? - - + + Terminate without asking Avsluta utan att fråga - - + + The Sandboxie Start Menu will now be displayed. Select an application from the menu, and Sandboxie will create a newshortcut icon on your real desktop, which you can use to invoke the selected application under the supervision of Sandboxie. + + + + + Create Shortcut to sandbox %1 Skapa genväg till sandlåda %1 - + Do you want to %1 %2? Vill du %1 %2? - + the selected processes de valda processerna - + This box does not have Internet restrictions in place, do you want to enable them? Denna låda har inte internetbegränsningar på plats, vill du aktivera dem? - + This sandbox is disabled, do you want to enable it? Denna sandlåda är inaktiverad, vill du aktivera den? - + (Host) Start Menu (Värd) Startmeny @@ -2765,158 +3054,178 @@ Notera: Uppdateringskollen är ofta bakom senaste GitHub-utgivningen för att s Sandboxie-Plus - Inställningar - + Auto Detection Autoupptäckt - + No Translation Ingen översättning - + Don't integrate links Integrera inte länkar - + As sub group Som undergrupp - + Fully integrate Integrera fullt - + Don't show any icon Visa inte någon ikon - + Show Plus icon Visa Plus-ikon - + Show Classic icon Visa klassisk ikon - + All Boxes Alla lådor - + Active + Pinned Aktiv + Fästad - + Pinned Only Endast fästad - + Close to Tray Stäng till sys.fält - + Prompt before Close Fråga före stängande - + Close Stäng - + + None + Ingen + + + + Native + Ursprunglig + + + + Qt + Qt + + + + %1 % + %1 % + + + Run &Sandboxed Kör &sandlådad - + Sandboxed Web Browser Sandlådad webläsare - + This supporter certificate has expired, please <a href="sbie://update/cert">get an updated certificate</a>. Detta supportercertifikat har utgått, vänligen <a href="sbie://update/cert">skaffa ett uppdaterat certifikat</a>. - + This supporter certificate will <font color='red'>expire in %1 days</font>, please <a href="sbie://update/cert">get an updated certificate</a>. Detta supportercertifikat kommer <font color='red'>utgå om %1 dagar</font>, vänligen <a href="sbie://update/cert">skaffa ett uppdaterat certifikat</a>. - + Run &Un-Sandboxed Kör &osandlådad - + This does not look like a certificate. Please enter the entire certificate, not just a portion of it. Detta ser inte ut som ett certifikat. Vänligen ange hela certifikatet, inte bara en del av det. - + This certificate is unfortunately expired. Detta certifikat är tyvärr utgånget. - + This certificate is unfortunately outdated. Detta certifikat är tyvärr gammalt. - + Thank you for supporting the development of Sandboxie-Plus. Tack för att du stöder utvecklingen av Sandboxie-Plus. - + This support certificate is not valid. Detta supportcertifikat är inte giltigt. - - + + Select Directory Välj katalog - + Please enter the new configuration password. Vänligen ange det nya konfigurationslösenordet. - + Please re-enter the new configuration password. Vänligen återange det nya konfigurationslösenordet. - + Passwords did not match, please retry. Lösenorden stämde inte, vänligen försök igen. - + Process Process - + Folder Mapp - + Please enter a program file name Vänligen ange ett programfilsnamn @@ -2952,27 +3261,27 @@ Notera: Uppdateringskollen är ofta bakom senaste GitHub-utgivningen för att s CShellPage - + Configure <b>Sandboxie-Plus</b> shell integration Konfigurera <b>Sandboxie-Plus</b> skalintegration - + Configure how Sandboxie-Plus should integrate with your system. Konfigurera hur Sandboxie-Plus ska integrera med ditt system. - + Start UI with Windows Starta programpanelen med Windows - + Add 'Run Sandboxed' to the explorer context menu Lägg till - Kör sandlådad, till utforskarens snabbmeny - + Add desktop shortcut for starting Web browser under Sandboxie Lägg till skrivbordsgenväg för start av webläsare under Sandboxie-Plus @@ -3020,6 +3329,84 @@ Notera: Uppdateringskollen är ofta bakom senaste GitHub-utgivningen för att s Vill du verkligen radera den valda ögonblicksbilden? + + CSupportDialog + + + The installed supporter certificate <b>has expired %1 days ago</b> and <a href="https://sandboxie-plus.com/go.php?to=sbie-get-cert">must be renewed</a>.<br /><br /> + + + + + <b>You have installed Sandboxie-Plus more than %1 days ago.</b><br /><br /> + + + + + <u>Commercial use of Sandboxie past the evaluation period</u>, requires a valid <a href="https://sandboxie-plus.com/go.php?to=sbie-get-cert">support certificate</a>. + + + + + The installed supporter certificate is <b>outdated</b> and it is <u>not valid for<b> this version</b></u> of Sandboxie-Plus.<br /><br /> + + + + + The installed supporter certificate is <b>expired</b> and <u>should to be renewed</u>.<br /><br /> + + + + + <b>You have been using Sandboxie-Plus for more than %1 days now.</b><br /><br /> + + + + + Sandboxie on ARM64 requires a valid supporter certificate for continued use.<br /><br /> + + + + + Personal use of Sandboxie is free of charge on x86/x64, although some functionality is only available to project supporters.<br /><br /> + + + + + Please continue <a href="https://sandboxie-plus.com/go.php?to=sbie-get-cert">supporting the project</a> by renewing your <a href="https://sandboxie-plus.com/go.php?to=sbie-cert">supporter certificate</a> and continue using the <b>enhanced functionality</b> in new builds. + + + + + Sandboxie <u>without</u> a valid supporter certificate will sometimes <b><font color='red'>pause for a few seconds</font></b>, to give you time to contemplate the option of <a href="https://sandboxie-plus.com/go.php?to=sbie-get-cert">supporting the project</a>.<br /><br />A <a href="https://sandboxie-plus.com/go.php?to=sbie-cert">supporter certificate</a> not just removes this reminder, but also enables <b>exclusive enhanced functionality</b> providing better security and compatibility. + + + + + Sandboxie-Plus - Support Reminder + + + + + %1 + %1 + + + + Quit + + + + + Continue + + + + + Get Certificate + + + CTraceModel @@ -3081,9 +3468,9 @@ Notera: Uppdateringskollen är ofta bakom senaste GitHub-utgivningen för att s - - - + + + [All] [Alla] @@ -3123,70 +3510,88 @@ Notera: Uppdateringskollen är ofta bakom senaste GitHub-utgivningen för att s Annan - + Show All Boxes Visa alla lådor - + Save to file Spara till fil - + + Cleanup Trace Log + Rensa spårloggen + + + %1 (%2) %1 (%2) - + %1 %1 - + Save trace log to file Spara spårlogg till fil - + Failed to open log file for writing Misslyckades att öppna loggfil för skrivande - + Unknown Okänd + + CTraceWindow + + + Sandboxie-Plus - Trace Monitor + Sandboxie-Plus - Spårövervakare + + CUIPage - + Configure <b>Sandboxie-Plus</b> UI Konfigurera <b>Sandboxie-Plus</b> programpanel - + Select the user interface style you prefer. Välj programpanelstilen du föredrar. - + &Advanced UI for experts &Avancerad programpanel för experter - + &Simple UI for beginners - Enkel programpanel för nybörjare + &Enkel programpanel för nybörjare - + + &Classic Sandboxie UI + &Klassiskt Sandboxie UI + + + Use Bright Mode Använd ljust läge - + Use Dark Mode Använd mörkt läge @@ -3194,22 +3599,22 @@ Notera: Uppdateringskollen är ofta bakom senaste GitHub-utgivningen för att s CWFPPage - + Configure <b>Sandboxie-Plus</b> network filtering Konfigurera <b>Sandboxie-Plus</b> nätverksfiltrering - + Sandboxie can use the Windows Filtering Platform (WFP) to restrict network access. Sandboxie kan använda Windows filtreringsplattform (WFP) för att begränsa nätverkstillgång. - + Using WFP allows Sandboxie to reliably enforce IP/Port based rules for network access. Unlike system level application firewalls, Sandboxie can use different rules in each box for the same application. If you already have a good and reliable application firewall and do not need per box rules, you can leave this option unchecked. Without WFP enabled, Sandboxie will still be able to reliably and entirely block processes from accessing the network. However, this can cause the process to crash, as the driver blocks the required network device endpoints. Even with WFP disabled, Sandboxie offers to set IP/Port based rules, however these will be applied in user mode only and not be enforced by the driver. Hence, without WFP enabled, an intentionally malicious process could bypass those rules, but not the entire network block. Att använda WFP tillåter Sandboxie att tillförlitligt tvinga IP/Port-baserade regler för nätverkstillgång. Till skillnad från systemnivåbrandväggar, kan Sandboxie använda olika regler i varje låda för samma applikation. Om du redan har en bra och pålitlig brandvägg och inte behöver regler per låda, kan du lämna detta alternativ omarkerat. Utan WFP aktiverat, kan Sandboxie fortfarande tillförlitligt och fullständigt blockera processer från att tillgå nätverket. Hursom, detta kan orsaka att processen kraschar, då drivrutinen blockerar de krävda nätverkenhetsslutpunkterna. Även med WFP inaktiverad, erbjuder Sandboxie att ange IP/Port-baserade regler, fast de tillämpas endast i användarläge och påtvingas inte av drivrutinen. Därav, utan WFP aktiverad, kan en avsiktligt skadlig process passera dessa regler, men inte hela nätverksblockeringen. - + Enable Windows Filtering Platform (WFP) support Aktivera stöd för Windows filtreringsplattform (WFP) @@ -3404,8 +3809,7 @@ Notera: Uppdateringskollen är ofta bakom senaste GitHub-utgivningen för att s Protect the system from sandboxed processes - Skydda systemet från sandlådade processer - + Skydda systemet från sandlådade processer @@ -3418,6 +3822,7 @@ Notera: Uppdateringskollen är ofta bakom senaste GitHub-utgivningen för att s Säkerhetsnotering: Förhöjda applikationer körandes under övervakning av Sandboxie, med admin eller SYSTEM-tecken, har fler möjligheter att passera isoleringen och modifiera systemet utanför sandlådan. + Security Enhancements Säkerhetsutökning @@ -3428,7 +3833,8 @@ Notera: Uppdateringskollen är ofta bakom senaste GitHub-utgivningen för att s - Note: MSI Installer Exemptions should not be required, but if you encounter issues installing a msi package which you trust, this option may help the installation complete successfully. You can also try disabling drop admin rights. + Note: Msi Installer Exemptions should not be required, but if you encounter issues installing a msi package which you trust, this option may help the installation complete successfully. You can also try disabling drop admin rights. + Note: MSI Installer Exemptions should not be required, but if you encounter issues installing a msi package which you trust, this option may help the installation complete successfully. You can also try disabling drop admin rights. Notera: Undantag för MSI-installerare ska inte krävas, men om du stöter på besvär installerandes ett MSI-paket som är pålitligt, kan detta alternativ hjälpa installationen fullföljas framgångsrikt. Du kan också försöka inaktivera skippa adminrättigheter. @@ -3448,7 +3854,8 @@ Notera: Uppdateringskollen är ofta bakom senaste GitHub-utgivningen för att s - Restrict access driver/device access to approved once only + Restrict driver/device access to approved endpoints once + Restrict access driver/device access to approved once only Begränsa tillgå drivrutin/enhetstillgång till godkänd en gång endast @@ -3542,8 +3949,8 @@ Notera: Uppdateringskollen är ofta bakom senaste GitHub-utgivningen för att s - - + + Name Namn @@ -3564,8 +3971,9 @@ Notera: Uppdateringskollen är ofta bakom senaste GitHub-utgivningen för att s - - + + + Remove Ta bort @@ -3588,7 +3996,8 @@ Notera: Uppdateringskollen är ofta bakom senaste GitHub-utgivningen för att s - You can group programs together and give them a group name. Program groups can be used with some of the settings instead of program names. Groups defined for the box overwrite groups defined in templates. + You can group programs together and give them a group name. Program groups can be used with some of the settings instead of program names. Groups defined for the box overwrite groups defined in templates. + You can group programs together and give them a group name. Program groups can be used with some of the settings instead of program names. Groups defined for the box overwrite groups defined in templates. Du kan gruppera ihop program och ge dem ett gruppnamn. Programgrupper kan användas med några av inställningarna istället för programnamn. Grupper definierade för lådan överskriver grupper definierade i mallar. @@ -3599,7 +4008,8 @@ Notera: Uppdateringskollen är ofta bakom senaste GitHub-utgivningen för att s - + + Show Templates Visa mallar @@ -3797,12 +4207,13 @@ Om ledarprocesser är definierade, behandlas alla andra som kvardröjande progra + Program Program - + Action Aktion @@ -3883,7 +4294,7 @@ The process match level has a higher priority than the specificity and describes Processmatchningsnivån har en högre prioritet än säregenheten och beskriver hur en regel tillämpas för en given processs. Regler tillämpade genom processnamn eller grupp har den starkaste matchningsnivån, följt av matchningen genom förnekande (d.v.s regler tillämpade till alla processer förutom den givna), medans den lägsta matchningsnivån har globala matchningar, d.v.s regler som är tillämpliga på varje process. - + Prioritize rules based on their Specificity and Process Match Level Prioriterar regler baserat på deras säregenhet och processmatchningsnivå @@ -3909,7 +4320,8 @@ Processmatchningsnivån har en högre prioritet än säregenheten och beskriver - Apply Close...=!<program>,... rules also to all binaries located in the sandboxed. + Apply Close...=!<program>,... rules also to all binaries located in the sandboxe. + Apply Close...=!<program>,... rules also to all binaries located in the sandboxed. Tillämpa stäng...=!<program>,... regler även till alla binärer lokaliserade i sandlådan. @@ -3954,262 +4366,292 @@ Processmatchningsnivån har en högre prioritet än säregenheten och beskriver + Miscellaneous Options + Diverse alternativ + + + + Seite + + + + Advanced Options Avancerade alternativ - + Miscellaneous Övrigt - + Emulate sandboxed window station for all processes Efterlikna sandlådad fönsterstation för alla processer - + Drop critical privileges from processes running with a SYSTEM token Skippa kritiska privilegier från processer körandes med ett SYSTEM-tecken - + Add sandboxed processes to job objects (recommended) Lägg till sandlådade processer till jobbobjekt (rekommenderat) - + Do not start sandboxed services using a system token (recommended) Starta inte sandlådade tjänster användandes ett SYSTEM-tecken (rekommenderas) - + Protect sandboxed SYSTEM processes from unprivileged processes Skydda sandlådade SYSTEM-processer från opriviligerade processer - + Open access to COM infrastructure (not recommended) Öppen tillgång till COM-infrastruktur (rekommenderas inte) - + Allow only privileged processes to access the Service Control Manager Tillåt endast priviligerade processer att tillgå Service Control Manager - + Force usage of custom dummy Manifest files (legacy behaviour) Tvinga användandet av modellanpassade manifestfiler (legay beteende) - - + + (Security Critical) (Säkerhetskritisk) - + Start the sandboxed RpcSs as a SYSTEM process (not recommended) Starta den sandlådade RpcSs som en SYSTEM-process (rekommenderas inte) - + Don't alter window class names created by sandboxed programs Ändra inte fönsterklassnamn skapade av sandlådade program - + Compatibility Kompatibilitet - - - - + + + + Protect the sandbox integrity itself Skydda själva sandlådans integritet - + Sandbox isolation Sandlådeisolering - + COM/RPC COM/RPC - + Allow use of nested job objects (experimental, works on Windows 8 and later) Tillåt användande av kapslade jobbobjekt (experimentell, fungerar på Windows 8 och senare) - + Disable the use of RpcMgmtSetComTimeout by default (this may resolve compatibility issues) Inaktivera användandet av RpcMgmtSetComTimeout som standard (det kan lösa kompatibilitetsproblem) - + Isolation Isolering - + Security Isolation through the usage of a heavily restricted process token is Sandboxie's primary means of enforcing sandbox restrictions, when this is disabled the box is operated in the application compartment mode, i.e. it’s no longer providing reliable security, just simple application compartmentalization. Säkerhetsisolering genom användande av tungt begränsade processtecken är Sandboxies primära medel för att tvinga sandlådebegränsningar, när det är inaktiverat opereras lådan i applikationavdelningsläget, d.v.s den tillhandahåller inte längre tillförlitlig säkerhet, bara enkel uppdelning. - + Open access to Windows Local Security Authority Öppna tillgång till Windows Local Security Authority - + Allow sandboxed programs to manage Hardware/Devices Tillåt sandlådade program att hantera hårdvara/enheter - + Disable Security Isolation (experimental) Inaktivera säkerhetsisolering (experimentell) - + Various advanced isolation features can break compatibility with some applications. If you are using this sandbox <b>NOT for Security</b> but for simple application portability, by changing these options you can restore compatibility by sacrificing some security. Olika avancerade isoleringsfunktioner kan söndra kompatibiliteten med vissa applikationer. Om du INTE använder denna sandlåda <b>för säkerhet</b> utan för enkel applikationsportabilitet, genom att ändra dessa alternativ kan du återställa kompatibilitet genom att offra viss säkerhet. - + Open access to Windows Security Account Manager Öppna tillgång till Windows Security Account Manager - + Security Isolation & Filtering Säkerhetisoleringsfiltrering - + Disable Security Filtering (not recommended) Inaktivera säkerhetsisolering (rekommenderas inte) - + Security Filtering used by Sandboxie to enforce filesystem and registry access restrictions, as well as to restrict process access. Säkerhetsfiltrering används av Sandboxie för att påtvinga filsystem och registertillgångsbegränsningar, även såsom att begränsa processtillgång. - + The below options can be used safely when you don't grant admin rights. Nedan alternativ kan användas säkert när du inte beviljar adminrättigheter. - + Access isolation Tillgångsisolering - + + Advanced + Avancerad + + + + Add Option + Lägg till alternativ + + + + Here you can configure advanced per process options to improve compatibility and/or customize sand boxing behavior. + Här kan du konfigurera avancerade per process alternativ för förbättrande av kompatibiliteten och/eller anpassa sandlådningsbeteende. + + + + Option + Alternativ + + + Triggers Utlösare - + Event Händelse - - - + + + Run Command Kör kommando - + Start Service Starta tjänst - + These events are executed each time a box is started Dessa händelser verkställs varje gång en låda startas - + On Box Start Vid lådstart - + These commands are run UNBOXED just before the box content is deleted Dessa kommandon körs OLÅDADE precis innan lådinnehållet raderas - + On Box Delete Vid lådraderande - + These commands are executed only when a box is initialized. To make them run again, the box content must be deleted. Dessa kommandon verkställs endast när en låda påbörjas. För att köra dem igen, måste lådinnehållet raderas. - + On Box Init Vid lådstart - + Here you can specify actions to be executed automatically on various box events. Här kan du specificera aktioner att verkställas automatiskt vid varierande lådhändelser. - + Hide Processes Dölj processer - + Add Process Lägg till process - + Hide host processes from processes running in the sandbox. Dölj värdprocesser från processer körandes i sandlådan. - + Don't allow sandboxed processes to see processes running in other boxes Tillåt inte sandlådade processer att se processer körandes i andra lådor - + Users Användare - + Restrict Resource Access monitor to administrators only Begränsa resurstillgångsövervakning till administratörer endast - + Add User Lägg till användare - + Remove User Ta bort användare - + Add user accounts and user groups to the list below to limit use of the sandbox to only those accounts. If the list is empty, the sandbox can be used by all user accounts. Note: Forced Programs and Force Folders settings for a sandbox do not apply to user accounts which cannot use the sandbox. @@ -4218,32 +4660,36 @@ Note: Forced Programs and Force Folders settings for a sandbox do not apply to Notera: Inställningarna tvingade program och tvinga mappar, för en sandlåda, gäller inte för användarkonton som inte kan använda sandlådan. - + Tracing Spårning - + API call trace (requirers logapi to be installed in the sbie dir) API-anropsspår (kräver att logga-API är installerat i sbie dir) - + Pipe Trace Pipe-spår - + Log all SetError's to Trace log (creates a lot of output) Logga alla SetError's till spårloggen (skapar en massa utflöde) - + Log Debug Output to the Trace Log Logga Debug Output till spårloggen - + + To compensate for the lost protection, please consult the Drop Admin Rights settings on the Security tab on the General group. + För att kompensera för förlorat skydd, vänligen se inställningen Skippa adminrättigheter i säkerhetsfliken i den allmänna gruppen. + + Log all access events as seen by the driver to the resource access log. This options set the event mask to "*" - All access events @@ -4252,7 +4698,7 @@ You can customize the logging using the ini by specifying "D" - Denied accesses "I" - Ignore access requests instead of "*". - Logga alla tillgångshändelser som ses av drivrutinen till resurstillgångsloggen. + Logga alla tillgångshändelser som ses av drivrutinen till resurstillgångsloggen. Dessa alternativ anger händelsemasken till "*" - Alltillgångs-händelser Du kan anpassa loggningen användandes ini:n genom att specificera @@ -4262,117 +4708,117 @@ Du kan anpassa loggningen användandes ini:n genom att specificera istället för "*". - + Ntdll syscall Trace (creates a lot of output) Ntdll syscall-spår (skapar en massa utflöde) - + File Trace Filspår - + Disable Resource Access Monitor Inaktivera resurstillgångsövervakning - + IPC Trace IPC-spår - + GUI Trace GUI-spår - + Resource Access Monitor Resurstillgångsövervakare - + Access Tracing Tillgångsspårning - + COM Class Trace COM-class spår - + Key Trace Nyckelspår - + Network Firewall Nätverksbrandvägg - + Debug Felsök - + WARNING, these options can disable core security guarantees and break sandbox security!!! VARNING, dessa alternativ kan inaktivera kärnsäkerhetsgarantier och bryta sandlådesäkerhet!!! - + These options are intended for debugging compatibility issues, please do not use them in production use. Dessa alternativ är avsedda för felsökning av kompatibilitetsproblem, vänligen använd dem inte vid produktionsanvändning. - + App Templates Appmallar - + Compatibility Templates Kompatibilitetsmallar - + Filter Categories Filterkategorier - + Text Filter Textfilter - + Add Template Lägg till mall - + This list contains a large amount of sandbox compatibility enhancing templates Denna lista innehåller en stor mängd av sandlådekompatibilitetsutökande mallar - + Remove Template Ta bort mall - + Category Kategori - + Template Folders Mallmappar - + Configure the folder locations used by your other applications. Please note that this values are currently user specific and saved globally for all boxes. @@ -4381,47 +4827,66 @@ Please note that this values are currently user specific and saved globally for Vänligen notera att detta värde är för tillfället användarspecifikt och sparas globalt för alla lådor. - + + Value Värde - + + Log all access events as seen by the driver to the resource access log. + +This options set the event mask to "*" - All access events +You can customize the logging using the ini by specifying +"A" - Allowed accesses +"D" - Denied accesses +"I" - Ignore access requests +instead of "*". + Logga alla tillgångsevent som ses av drivrutinen till resurstillgångsloggen. + +Detta alternativ anger händelsemasken till "*" - Alltillgångshändelser +Du kan anpassa loggningen via ini:n genom att specificera +"A" - Tillåtna tillgångar +"D" - Nekade tillgångar +"I" - Ignorera tillgångsförfrågningar +istället för "*". + + + Accessibility Tillgänglighet - To compensate for the lost protection, please consult the Drop Rights settings page in the Restrictions settings group. - För att kompensera för det förlorade skyddet, vänligen konsultera inställningen skippa rättigheter i säkerhetsfliken i Allmänna alternativ. + För att kompensera för det förlorade skyddet, vänligen konsultera inställningen skippa rättigheter i säkerhetsfliken i Allmänna alternativ. - + Screen Readers: JAWS, NVDA, Window-Eyes, System Access Skärmläsare: JAWS, NVDA, Window-Eyes, Systemtillgång - + The following settings enable the use of Sandboxie in combination with accessibility software. Please note that some measure of Sandboxie protection is necessarily lost when these settings are in effect. Följande inställningar aktiverar användandet av Sandboxie i kombination med tillgänglighetsprogram. Vänligen notera att ett visst mått av Sandboxies skydd av nödvändighet förloras när dessa inställningar aktiveras. - + Edit ini Section Redigera ini-sektionen - + Edit ini Redigera ini:n - + Cancel Avbryt - + Save Spara @@ -4430,7 +4895,8 @@ Vänligen notera att detta värde är för tillfället användarspecifikt och sp PopUpWindow - Sandboxie-Plus Notifications + SandboxiePlus Notifications + Sandboxie-Plus Notifications Sandboxie-Plus aviseringar @@ -4445,35 +4911,39 @@ Vänligen notera att detta värde är för tillfället användarspecifikt och sp QObject - Drive: %1 - Disk: %1 + Disk: %1 + + + + Drive %1 + Disk %1 QPlatformTheme - + OK Ok - + Apply Tillämpa - + Cancel Avbryt - + &Yes &Ja - + &No &Nej @@ -4572,378 +5042,427 @@ Vänligen notera att detta värde är för tillfället användarspecifikt och sp Allmän konfigurering - + Show Notifications for relevant log Messages Visa aviseringar för relevanta loggmeddelanden - + Hotkey for terminating all boxed processes: Snabbtangent för att avsluta alla lådade processer: - + UI Language: - Programpanelspråk + Programpanelspråk: - + Run box operations asynchronously whenever possible (like content deletion) Kör lådoperationer asynkront närhelst möjligt (likt innehållsradering) - + Open urls from this ui sandboxed Öppna internetadresser från denna programpanel sandlådade - + Show first recovery window when emptying sandboxes Visa först återställningsfönstret vid tömning av sandlådor - + General Options Allmänna alternativ - Use Dark Theme (fully applied after a restart) - Använd mörkt tema (fullt tillämpat efter en omstart) + Använd mörkt tema (fullt tillämpat efter en omstart) - + Watch Sandboxie.ini for changes Ändringsbevaka Sandboxie.ini:n - + Show recoverable files as notifications Visa återställningsbara filer som aviseringar - + Count and display the disk space ocupied by each sandbox Räkna och visa diskutrymmet använt av varje sandlåda - + Shell Integration Skalintegrering - + Show Icon in Systray: Visa ikon i sys.fältet: - + Always use DefaultBox Använd alltid standardlåda - + Add 'Run Un-Sandboxed' to the context menu Lägg till - Kör osandlådad, till utforskarens snabbmeny - + Add 'Run Sandboxed' to the explorer context menu Lägg till - Kör sandlådad, till utforskarens snabbmeny - + Start UI when a sandboxed process is started Starta programpanelen när en sandlådad process startas - + Start Menu Integration Startmenyintegrering - + Show a tray notification when automatic box operations are started Visa en fältavisering när automatiska lådoperationer startas - + Run Sandboxed - Actions Kör sandlådad - aktioner - + Scan shell folders and offer links in run menu Skanna skalmappar och erbjud länkar i körmenyn - + On main window close: Vid huvudfönsterstängning: - + Systray options Sys.fältsalternativ - + Start UI with Windows Starta programpanelen med Windows - + Show boxes in tray list: Visa lådor i fältlistan: - + Start Sandbox Manager Starta sandlådehanteraren - + Integrate boxes with Host Start Menu Integrera lådor med värdens startmeny - + + Interface Config + Gränssnittskonfigurering + + + + Interface Options + Gränssnittsalternativ + + + + Font Scaling + Teckensnittsskalning + + + + High DPI Scaling + Hög DPI-skalning + + + + (Restart required) + (Omstart krävs) + + + + * indetermined means depanding on the view mode + * obestämd betyder beroende av vyläget + + + + Use Dark Theme + Använd mörkt tema + + + + Show Classic Background in box list* + Visa klassisk bakgrund i lådlistan* + + + + Use large icons in box list * + Använd stora ikoner i lådlistan * + + + + Don't show icons in menus * + Visa inte ikoner i menyer * + + + Advanced Config Avancerad konfiguration - + Separate user folders Separata användarmappar - + Hook selected Win32k system calls to enable GPU acceleration (experimental) Haka fast valda Win32k systemanrop för att aktivera GPU-accelerering (experimentell) - + Portable root folder Portabel rotkatalog - + Sandbox <a href="sbie://docs/keyrootpath">registry root</a>: Sandlåda <a href="sbie://dok/nyckelrotsökväg">registerroten</a>: - + Sandboxing features Sandlådefunktioner - + ... ... - + Sandbox default Sandlådestandard - + Sandbox <a href="sbie://docs/filerootpath">file system root</a>: Sandlåda <a href="sbie://dok/filrotsökvägen">filsystemroten</a>: - + Activate Kernel Mode Object Filtering Aktivera kernellägets objektfiltrering - + Use Windows Filtering Platform to restrict network access Använd Windows filtreringsplattform för att begränsa nätverkstillgång - + Sandbox <a href="sbie://docs/ipcrootpath">ipc root</a>: Sandlåda <a href="sbie://dok/IPC-rotsökväg">IPC-rot</a>: - + Use a Sandboxie login instead of an anonymous token (experimental) Använd en Sandboxie-inloggning istället för ett anonymt tecken (experimentellt) - + Program Control Programkontroll - - + + Name Namn - + Path Sökväg - + Remove Program Ta bort program - + Add Program Lägg till program - + When any of the following programs is launched outside any sandbox, Sandboxie will issue message SBIE1301. När något av de följande programm startas utanför någon sandlåda, kommer Sandboxie utfärda meddelande SBIE1301. - + Add Folder Lägg till mapp - + Prevent the listed programs from starting on this system Förhindra de listade programmen från att starta på detta system - + Issue message 1308 when a program fails to start Utfärda meddelande 1308 när ett program inte lyckas starta - + Config Protection Konfigurera skydd - + Config protection Konfigurera skydd - + Clear password when main window becomes hidden Rensa lösenord när huvudfönstret blir dolt - + Only Administrator user accounts can make changes Endast administratörsanvändarkonton kan göra ändringar - + Only Administrator user accounts can use Pause Forcing Programs command Endast administratörsanvändarkonton kan använda kommandot pausa programtvingande - + Password must be entered in order to make changes Lösenord måste anges för att kunna göra ändringar - + Change Password Ändra lösenord - + Compatibility Kompatibilitet - + In the future, don't check software compatibility Kontrollera inte programkompatibilitet i framtiden - + Enable Aktivera - + Disable Inaktivera - + Sandboxie has detected the following software applications in your system. Click OK to apply configuration settings, which will improve compatibility with these applications. These configuration settings will have effect in all existing sandboxes and in any new sandboxes. Sandboxie har upptäckt följande mjukvaruapplikationer i ditt system. Klicka på Ok för att tillämpa konfigurationsinställningarna, vilket kommer förbättra kompatibiliteten med dessa applikationer. Dessa konfigurationsinställningar kommer ha påverkan på alla existerande sandlådor samt även de nya. - + Edit ini Section Redigera ini-sektionen - + Save Spara - + Edit ini Redigera ini:n - + Cancel Avbryt - + Support Support - + Enter the support certificate here Ange supportcertifikatet här - + Install updates automatically Installera uppdateringar automatiskt - + Supporters of the Sandboxie-Plus project receive a <a href="https://sandboxie-plus.com/go.php?to=sbie-cert">supporter certificate</a>. It's like a license key but for awesome people using open source software. :-) Supportrar av Sandboxie-Plus projektet får ett <a href="https://sandboxie-plus.com/go.php?to=sbie-cert">supportercertifikat</a>. Det är som en licensnyckel men för fantastiska människor som använder öppen källa program. :-) - + Keeping Sandboxie up to date with the rolling releases of Windows and compatible with all web browsers is a never-ending endeavor. Please consider supporting this work with a donation.<br />You can support the development with a <a href="https://sandboxie-plus.com/go.php?to=donate">PayPal donation</a>, working also with credit cards.<br />Or you can provide continuous support with a <a href="https://sandboxie-plus.com/go.php?to=patreon">Patreon subscription</a>. Hålla Sandboxie uppdaterat med det rullande utgivandet av Windows och kompatibelt med alla webläsare är en aldrig upphörande strävan. Vänligen överväg att supporta detta arbete med en donation.<br />Du kan supporta utvecklingen med en <a href="https://sandboxie-plus.com/go.php?to=donate"gt;PayPal donation</a>, fungerar också med kreditkort.<br />Eller så kan du ge kontinuerlig support med en <a href="https://sandboxie-plus.com/go.php?to=patreon">Patreon prenumeration</a>. - + This supporter certificate has expired, please <a href="sbie://update/cert">get an updated certificate</a>. Detta supportercertifikat har utgått, vänligen <a href="sbie://update/cert">skaffa ett uppdaterat certifikat</a>. - + Support Settings Supportinställningar - + In the future, don't notify about certificate expiration Meddela inte om certifikatsutgång i framtiden - + Check periodically for updates of Sandboxie-Plus Sök periodvis efter uppdateringar av Sandboxie-Plus - + Download Updates automatically Nerladda uppdateringar automatiskt @@ -5001,4 +5520,4 @@ Vänligen notera att detta värde är för tillfället användarspecifikt och sp Gå till ögonblicksbild - \ No newline at end of file +