2022-07-09 10:46:07 +01:00
|
|
|
|
|
|
|
#include <QStyledItemDelegate>
|
|
|
|
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;
|
2023-01-07 15:57:55 +00:00
|
|
|
m_iIconDisabled = -1;
|
2022-07-09 10:46:07 +01:00
|
|
|
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();
|
2022-11-05 13:53:44 +00:00
|
|
|
QAction* pShowHide = m_pTrayMenu->addAction(GetIcon("IconFull", 2), tr("Show/Hide"), this, SLOT(OnShowHide()));
|
2022-07-09 10:46:07 +01:00
|
|
|
QFont f = pShowHide->font();
|
|
|
|
f.setBold(true);
|
|
|
|
pShowHide->setFont(f);
|
|
|
|
m_pTrayMenu->addSeparator();
|
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
m_iTrayPos = m_pTrayMenu->actions().count();
|
2022-07-09 10:46:07 +01:00
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
if (!theConf->GetBool("Options/CompactTray", false))
|
|
|
|
{
|
|
|
|
m_pTrayBoxes = NULL;
|
|
|
|
connect(m_pTrayMenu, SIGNAL(hovered(QAction*)), this, SLOT(OnBoxMenuHover(QAction*)));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_pTrayList = new QWidgetAction(m_pTrayMenu);
|
2022-07-09 10:46:07 +01:00
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
QWidget* pWidget = new CActionWidget();
|
|
|
|
QHBoxLayout* pLayout = new QHBoxLayout();
|
2022-09-29 17:28:48 +01:00
|
|
|
pLayout->setContentsMargins(0,0,0,0);
|
2022-07-10 17:28:10 +01:00
|
|
|
pWidget->setLayout(pLayout);
|
2022-07-09 10:46:07 +01:00
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
m_pTrayBoxes = new QTreeWidget();
|
2022-07-09 10:46:07 +01:00
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
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());
|
2022-07-09 10:46:07 +01:00
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
m_pTrayBoxes->setStyle(QStyleFactory::create(m_DefaultStyle));
|
2022-07-09 10:46:07 +01:00
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
pLayout->insertSpacing(0, 1);// 32);
|
2022-07-09 10:46:07 +01:00
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
//QFrame* vFrame = new QFrame;
|
|
|
|
//vFrame->setFixedWidth(1);
|
|
|
|
//vFrame->setFrameShape(QFrame::VLine);
|
|
|
|
//vFrame->setFrameShadow(QFrame::Raised);
|
|
|
|
//pLayout->addWidget(vFrame);
|
2022-07-09 10:46:07 +01:00
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
pLayout->addWidget(m_pTrayBoxes);
|
2022-07-09 10:46:07 +01:00
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
m_pTrayList->setDefaultWidget(pWidget);
|
|
|
|
m_pTrayMenu->addAction(m_pTrayList);
|
2022-07-09 10:46:07 +01:00
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
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_pTrayMenu->addSeparator();
|
2022-07-09 10:46:07 +01:00
|
|
|
m_pTrayMenu->addAction(m_pEmptyAll);
|
2023-08-24 17:39:00 +01:00
|
|
|
m_pTrayMenu->addAction(m_pLockAll);
|
2023-06-04 20:11:24 +01:00
|
|
|
m_pTrayMenu->addSeparator();
|
2023-06-04 15:27:49 +01:00
|
|
|
m_pTrayMenu->addAction(m_pDisableForce2);
|
2022-07-09 10:46:07 +01:00
|
|
|
if(m_pDisableRecovery) m_pTrayMenu->addAction(m_pDisableRecovery);
|
|
|
|
if(m_pDisableMessages) m_pTrayMenu->addAction(m_pDisableMessages);
|
2023-05-18 08:32:44 +01:00
|
|
|
m_pDismissUpdate = m_pTrayMenu->addAction(tr("Dismiss Update Notification"), this, SLOT(OnDismissUpdate()));
|
|
|
|
m_pDismissUpdate->setCheckable(true);
|
|
|
|
m_pDismissUpdate->setVisible(false);
|
2022-07-09 10:46:07 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2023-02-07 20:50:06 +00:00
|
|
|
QIcon CSandMan::GetTrayIcon(bool isConnected, bool bSun)
|
2022-07-09 10:46:07 +01:00
|
|
|
{
|
|
|
|
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);
|
2022-11-05 13:53:44 +00:00
|
|
|
QPixmap base = GetIcon(IconFile, 0).pixmap(size);
|
2022-07-09 10:46:07 +01:00
|
|
|
QPixmap overlay;
|
|
|
|
|
|
|
|
if (m_bIconBusy) {
|
|
|
|
IconFile = "IconBusy";
|
|
|
|
if (bClassic) { // classic has a different icon instead of an overlay
|
|
|
|
IconFile += "C";
|
2022-11-05 13:53:44 +00:00
|
|
|
base = GetIcon(IconFile, 0).pixmap(size);
|
2022-07-09 10:46:07 +01:00
|
|
|
}
|
|
|
|
else
|
2022-11-05 13:53:44 +00:00
|
|
|
overlay = GetIcon(IconFile, 0).pixmap(size);
|
2022-07-09 10:46:07 +01:00
|
|
|
}
|
2023-02-07 20:50:06 +00:00
|
|
|
else if(bSun)
|
|
|
|
overlay = GetIcon("IconSun", 0).pixmap(size);
|
2022-07-09 10:46:07 +01:00
|
|
|
|
|
|
|
painter.drawPixmap(0, 0, base);
|
|
|
|
if(!overlay.isNull()) painter.drawPixmap(0, 0, overlay);
|
|
|
|
|
2023-01-07 15:57:55 +00:00
|
|
|
if (m_iIconDisabled == 1) {
|
2022-07-09 10:46:07 +01:00
|
|
|
IconFile = "IconDFP";
|
|
|
|
if (bClassic) IconFile += "C";
|
2022-11-05 13:53:44 +00:00
|
|
|
overlay = GetIcon(IconFile, 0).pixmap(size);
|
2022-07-09 10:46:07 +01:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2022-08-17 19:45:06 +01:00
|
|
|
QMenu* CSandMan__GetBoxParent(const QMap<QString, QStringList>& Groups, QMap<QString, QMenu*>& GroupItems, const QIcon& Icon, int iNoIcons, QMenu* pMenu, QAction* pPos, const QString& Name, int Depth = 0)
|
2022-07-10 17:28:10 +01:00
|
|
|
{
|
2022-08-17 19:45:06 +01:00
|
|
|
if (Depth > 100)
|
|
|
|
return NULL;
|
|
|
|
for (auto I = Groups.constBegin(); I != Groups.constEnd(); ++I) {
|
|
|
|
if (I->contains(Name)) {
|
|
|
|
if (I.key().isEmpty())
|
|
|
|
return NULL; // global group
|
|
|
|
QMenu*& pParent = GroupItems[I.key()];
|
|
|
|
if (!pParent) {
|
|
|
|
pParent = new QMenu(I.key());
|
|
|
|
if(!iNoIcons) pParent->setIcon(Icon);
|
|
|
|
QAction* pMenuAction = NULL;
|
|
|
|
if (QMenu* pParent2 = CSandMan__GetBoxParent(Groups, GroupItems, Icon, iNoIcons, pMenu, pPos, I.key(), ++Depth))
|
|
|
|
pMenuAction = pParent2->addMenu(pParent);
|
|
|
|
else
|
|
|
|
pMenuAction = pMenu->insertMenu(pPos, pParent);
|
|
|
|
pMenuAction->setData("group:" + I.key());
|
|
|
|
QFont fnt = pMenuAction->font();
|
|
|
|
fnt.setBold(true);
|
|
|
|
pMenuAction->setFont(fnt);
|
|
|
|
}
|
|
|
|
return pParent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
double CSandMan__GetBoxOrder(const QMap<QString, QStringList>& Groups, const QString& Name, double value = 0.0, int Depth = 0)
|
|
|
|
{
|
|
|
|
if (Depth > 100)
|
|
|
|
return 1000000000;
|
|
|
|
for (auto I = Groups.constBegin(); I != Groups.constEnd(); ++I) {
|
|
|
|
int Pos = I->indexOf(Name);
|
|
|
|
if (Pos != -1) {
|
|
|
|
value = double(Pos) + value / 10.0;
|
|
|
|
if (I.key().isEmpty())
|
|
|
|
return value;
|
|
|
|
return CSandMan__GetBoxOrder(Groups, I.key(), value, ++Depth);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 1000000000;
|
|
|
|
}
|
2022-07-10 17:28:10 +01:00
|
|
|
|
2022-08-17 19:45:06 +01:00
|
|
|
QAction* CSandMan__MakeBoxEntry(QMenu* pMenu, CSandBoxPlus* pBoxEx, QFileIconProvider& IconProvider, int iNoIcons, bool ColorIcons)
|
|
|
|
{
|
2022-07-10 17:28:10 +01:00
|
|
|
static QMenu* pEmptyMenu = new QMenu();
|
|
|
|
|
2022-08-17 19:45:06 +01:00
|
|
|
QAction* pBoxAction = new QAction(pBoxEx->GetName().replace("_", " "));
|
|
|
|
if (!iNoIcons) {
|
|
|
|
QIcon Icon;
|
2022-09-29 17:28:48 +01:00
|
|
|
QString Action = pBoxEx->GetText("DblClickAction");
|
|
|
|
if (!Action.isEmpty() && Action.left(1) != "!")
|
|
|
|
Icon = IconProvider.icon(QFileInfo(pBoxEx->GetCommandFile(Action)));
|
|
|
|
else if (ColorIcons)
|
2022-08-17 19:45:06 +01:00
|
|
|
Icon = theGUI->GetColorIcon(pBoxEx->GetColor(), pBoxEx->GetActiveProcessCount());
|
|
|
|
else
|
|
|
|
Icon = theGUI->GetBoxIcon(pBoxEx->GetType(), pBoxEx->GetActiveProcessCount() != 0);
|
|
|
|
pBoxAction->setIcon(Icon);
|
|
|
|
}
|
|
|
|
pBoxAction->setData("box:" + pBoxEx->GetName());
|
|
|
|
pBoxAction->setMenu(pEmptyMenu);
|
|
|
|
//pBoxAction->setIcon
|
|
|
|
//connect(pBoxAction, SIGNAL(triggered()), this, SLOT(OnBoxMenu()));
|
|
|
|
return pBoxAction;
|
|
|
|
}
|
2022-07-10 17:28:10 +01:00
|
|
|
|
2022-08-17 19:45:06 +01:00
|
|
|
void CSandMan::CreateBoxMenu(QMenu* pMenu, int iOffset, int iSysTrayFilter)
|
|
|
|
{
|
2022-07-10 17:28:10 +01:00
|
|
|
int iNoIcons = theConf->GetInt("Options/NoIcons", 2);
|
|
|
|
if (iNoIcons == 2)
|
|
|
|
iNoIcons = theConf->GetInt("Options/ViewMode", 1) == 2 ? 1 : 0;
|
|
|
|
QFileIconProvider IconProvider;
|
|
|
|
bool ColorIcons = theConf->GetBool("Options/ColorBoxIcons", false);
|
|
|
|
|
2022-08-17 19:45:06 +01:00
|
|
|
while (!pMenu->actions().at(iOffset)->data().toString().isEmpty())
|
|
|
|
pMenu->removeAction(pMenu->actions().at(iOffset));
|
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
QAction* pPos = pMenu->actions().at(iOffset);
|
2022-08-17 19:45:06 +01:00
|
|
|
|
|
|
|
bool bPlus = (theAPI->GetFeatureFlags() & CSbieAPI::eSbieFeatureCert) != 0;
|
|
|
|
QIcon Icon = QIcon(bPlus ? ":/Boxes/Group2" : ":/Boxes/Group"); // theGUI->GetBoxIcon(CSandBoxPlus::eDefault, false);
|
|
|
|
|
|
|
|
QList<CSandBoxPtr> Boxes = theAPI->GetAllBoxes().values(); // map is sorted by key (box name)
|
|
|
|
QMap<QString, QStringList> Groups = theGUI->GetBoxView()->GetGroups();
|
|
|
|
|
|
|
|
if (theConf->GetBool("MainWindow/BoxTree_UseOrder", false)) {
|
|
|
|
QMultiMap<double, CSandBoxPtr> Boxes2;
|
|
|
|
foreach(const CSandBoxPtr &pBox, Boxes) {
|
|
|
|
Boxes2.insertMulti(CSandMan__GetBoxOrder(Groups, pBox->GetName()), pBox);
|
|
|
|
}
|
|
|
|
Boxes = Boxes2.values();
|
|
|
|
}
|
|
|
|
|
|
|
|
QMap<QString, QMenu*> GroupItems;
|
|
|
|
foreach(const CSandBoxPtr &pBox, Boxes)
|
2022-07-10 17:28:10 +01:00
|
|
|
{
|
|
|
|
if (!pBox->IsEnabled())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
CSandBoxPlus* pBoxEx = qobject_cast<CSandBoxPlus*>(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;
|
|
|
|
}
|
|
|
|
|
2022-08-17 19:45:06 +01:00
|
|
|
QMenu* pSubMenu = CSandMan__GetBoxParent(Groups, GroupItems, Icon, iNoIcons, pMenu, pPos, pBox->GetName());
|
|
|
|
|
|
|
|
QAction* pBoxAction = CSandMan__MakeBoxEntry(pMenu, pBoxEx, IconProvider, iNoIcons, ColorIcons);
|
|
|
|
if (pSubMenu)
|
|
|
|
pSubMenu->addAction(pBoxAction);
|
|
|
|
else
|
|
|
|
pMenu->insertAction(pPos, pBoxAction);
|
2022-07-10 17:28:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSandMan::OnBoxMenuHover(QAction* action)
|
|
|
|
{
|
|
|
|
if (action->data().type() != QVariant::String)
|
|
|
|
return;
|
|
|
|
QString Str = action->data().toString();
|
|
|
|
if (Str.left(4) != "box:")
|
|
|
|
return;
|
|
|
|
|
|
|
|
QString Name = Str.mid(4);
|
|
|
|
static QPointer<QAction> 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-09 10:46:07 +01:00
|
|
|
void CSandMan::OnSysTray(QSystemTrayIcon::ActivationReason Reason)
|
|
|
|
{
|
|
|
|
static bool TriggerSet = false;
|
|
|
|
static bool NullifyTrigger = false;
|
2023-09-02 09:50:25 +01:00
|
|
|
|
|
|
|
if (theConf->GetBool("Options/TraySingleClick", false) && Reason == QSystemTrayIcon::Trigger)
|
|
|
|
Reason = QSystemTrayIcon::DoubleClick;
|
|
|
|
|
2022-07-09 10:46:07 +01:00
|
|
|
switch(Reason)
|
|
|
|
{
|
|
|
|
case QSystemTrayIcon::Context:
|
|
|
|
{
|
|
|
|
int iSysTrayFilter = theConf->GetInt("Options/SysTrayFilter", 0);
|
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
if(!m_pTrayBoxes)
|
|
|
|
CreateBoxMenu(m_pTrayMenu, m_iTrayPos, iSysTrayFilter);
|
|
|
|
else
|
2022-07-09 10:46:07 +01:00
|
|
|
{
|
2022-08-17 19:45:06 +01:00
|
|
|
QFileIconProvider IconProvider;
|
|
|
|
bool ColorIcons = theConf->GetBool("Options/ColorBoxIcons", false);
|
|
|
|
|
|
|
|
/**/
|
|
|
|
m_pTrayBoxes->clear();
|
|
|
|
|
|
|
|
QList<CSandBoxPtr> Boxes = theAPI->GetAllBoxes().values(); // map is sorted by key (box name)
|
|
|
|
QMap<QString, QStringList> Groups = theGUI->GetBoxView()->GetGroups();
|
|
|
|
|
|
|
|
if (theConf->GetBool("MainWindow/BoxTree_UseOrder", false)) {
|
|
|
|
QMultiMap<double, CSandBoxPtr> Boxes2;
|
|
|
|
foreach(const CSandBoxPtr &pBox, Boxes) {
|
2023-07-01 17:54:53 +01:00
|
|
|
Boxes2.insertMulti(CBoxPicker::GetBoxOrder(Groups, pBox->GetName()), pBox);
|
2022-08-17 19:45:06 +01:00
|
|
|
}
|
|
|
|
Boxes = Boxes2.values();
|
|
|
|
}
|
|
|
|
|
|
|
|
QMap<QString, QTreeWidgetItem*> GroupItems;
|
|
|
|
foreach(const CSandBoxPtr &pBox, Boxes)
|
|
|
|
{
|
|
|
|
if (!pBox->IsEnabled())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
CSandBoxPlus* pBoxEx = qobject_cast<CSandBoxPlus*>(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;
|
|
|
|
}
|
|
|
|
|
2023-07-01 17:54:53 +01:00
|
|
|
QTreeWidgetItem* pParent = CBoxPicker::GetBoxParent(Groups, GroupItems, m_pTrayBoxes, pBox->GetName());
|
2022-08-17 19:45:06 +01:00
|
|
|
|
|
|
|
QTreeWidgetItem* pItem = new QTreeWidgetItem();
|
|
|
|
pItem->setText(0, pBox->GetName().replace("_", " "));
|
|
|
|
pItem->setData(0, Qt::UserRole, pBox->GetName());
|
|
|
|
QIcon Icon;
|
|
|
|
QString Action = pBox->GetText("DblClickAction");
|
2022-09-29 17:28:48 +01:00
|
|
|
if (!Action.isEmpty() && Action.left(1) != "!")
|
|
|
|
Icon = IconProvider.icon(QFileInfo(pBoxEx->GetCommandFile(Action)));
|
|
|
|
else if(ColorIcons)
|
2022-08-17 19:45:06 +01:00
|
|
|
Icon = theGUI->GetColorIcon(pBoxEx->GetColor(), pBox->GetActiveProcessCount());
|
|
|
|
else
|
|
|
|
Icon = theGUI->GetBoxIcon(pBoxEx->GetType(), pBox->GetActiveProcessCount() != 0);
|
|
|
|
pItem->setData(0, Qt::DecorationRole, Icon);
|
|
|
|
if (pParent)
|
|
|
|
pParent->addChild(pItem);
|
|
|
|
else
|
|
|
|
m_pTrayBoxes->addTopLevelItem(pItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_pTrayBoxes->expandAll();
|
|
|
|
/**/
|
|
|
|
|
|
|
|
/*/
|
2022-07-10 17:28:10 +01:00
|
|
|
QMap<QString, CSandBoxPtr> Boxes = theAPI->GetAllBoxes();
|
2022-07-09 10:46:07 +01:00
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
bool bAdded = false;
|
|
|
|
if (m_pTrayBoxes->topLevelItemCount() == 0)
|
2022-12-07 16:32:40 +00:00
|
|
|
bAdded = true; // trigger size refresh
|
2022-07-09 10:46:07 +01:00
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
QMap<QString, QTreeWidgetItem*> 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);
|
2022-07-09 10:46:07 +01:00
|
|
|
}
|
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
foreach(const CSandBoxPtr & pBox, Boxes)
|
2022-07-09 10:46:07 +01:00
|
|
|
{
|
2022-07-10 17:28:10 +01:00
|
|
|
if (!pBox->IsEnabled())
|
|
|
|
continue;
|
2022-07-09 10:46:07 +01:00
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
CSandBoxPlus* pBoxEx = qobject_cast<CSandBoxPlus*>(pBox.data());
|
2022-07-09 10:46:07 +01:00
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
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;
|
|
|
|
}
|
2022-07-09 10:46:07 +01:00
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
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);
|
2022-07-09 10:46:07 +01:00
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
bAdded = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
QIcon Icon;
|
2022-08-17 19:45:06 +01:00
|
|
|
QString Action = pBox->GetText("DblClickAction");
|
|
|
|
if (!Action.isEmpty() && Action.left(1) != "!")
|
|
|
|
Icon = IconProvider.icon(QFileInfo(pBoxEx->GetCommandFile(Action)));
|
|
|
|
else if (ColorIcons)
|
2022-07-10 17:28:10 +01:00
|
|
|
Icon = theGUI->GetColorIcon(pBoxEx->GetColor(), pBox->GetActiveProcessCount());
|
|
|
|
else
|
|
|
|
Icon = theGUI->GetBoxIcon(pBoxEx->GetType(), pBox->GetActiveProcessCount() != 0);
|
|
|
|
pItem->setData(0, Qt::DecorationRole, Icon);
|
2022-07-09 10:46:07 +01:00
|
|
|
}
|
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
foreach(QTreeWidgetItem * pItem, OldBoxes)
|
|
|
|
delete pItem;
|
2022-08-17 19:45:06 +01:00
|
|
|
/*/
|
2022-07-10 17:28:10 +01:00
|
|
|
|
2022-08-17 19:45:06 +01:00
|
|
|
//if (!OldBoxes.isEmpty() || bAdded)
|
2022-07-10 17:28:10 +01:00
|
|
|
{
|
|
|
|
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() / 3;
|
|
|
|
if (Height > MaxHeight) {
|
|
|
|
Height = MaxHeight;
|
|
|
|
if (Height < 64)
|
|
|
|
Height = 64;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_pTrayBoxes->setFixedHeight(Height);
|
2022-07-09 10:46:07 +01:00
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
m_pTrayMenu->removeAction(m_pTrayList);
|
|
|
|
m_pTrayMenu->insertAction(m_pTrayMenu->actions().at(m_iTrayPos), m_pTrayList);
|
2022-07-09 10:46:07 +01:00
|
|
|
|
2022-07-10 17:28:10 +01:00
|
|
|
m_pTrayBoxes->setFocus();
|
|
|
|
}
|
2022-07-09 10:46:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2022-08-09 17:19:46 +01:00
|
|
|
CheckSupport();
|
2022-07-09 10:46:07 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2022-07-10 17:28:10 +01:00
|
|
|
|
|
|
|
void CSandMan::OnBoxMenu(const QPoint & point)
|
|
|
|
{
|
2023-05-15 18:34:15 +01:00
|
|
|
QTreeWidgetItem* pItem = m_pTrayBoxes->currentItem();
|
2022-07-10 17:28:10 +01:00
|
|
|
if (!pItem)
|
|
|
|
return;
|
|
|
|
CTrayBoxesItemDelegate::m_Hold = true;
|
|
|
|
m_pBoxView->PopUpMenu(pItem->data(0, Qt::UserRole).toString());
|
|
|
|
CTrayBoxesItemDelegate::m_Hold = false;
|
2023-05-15 18:34:15 +01:00
|
|
|
}
|