497 lines
14 KiB
C++
497 lines
14 KiB
C++
#pragma once
|
|
|
|
#include <QtWidgets/QMainWindow>
|
|
#include "ui_PopUpWindow.h"
|
|
#include "../SbiePlusAPI.h"
|
|
#include "../SbieProcess.h"
|
|
#include "../SandMan.h"
|
|
|
|
class CPopUpEntry: public QWidget
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
CPopUpEntry(const QString& Message, QWidget* parent = 0) : QWidget(parent)
|
|
{
|
|
m_Message = Message;
|
|
|
|
m_pMainLayout = new QGridLayout(this);
|
|
m_pMainLayout->setContentsMargins(6, 0, 6, 0);
|
|
this->setLayout(m_pMainLayout);
|
|
}
|
|
virtual ~CPopUpEntry() {}
|
|
|
|
virtual QString GetMessageText() { return m_Message; }
|
|
|
|
protected:
|
|
|
|
QGridLayout* m_pMainLayout;
|
|
QString m_Message;
|
|
};
|
|
|
|
class CPopUpMessage : public CPopUpEntry
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
CPopUpMessage(const QString& Message, const QString& Link, quint32 MsgCode, const QStringList& MsgData, const QString& ProcessName, const QString& BoxName, QWidget* parent = 0) : CPopUpEntry(Message, parent)
|
|
{
|
|
m_Message = Message;
|
|
m_MsgCode = MsgCode;
|
|
m_MsgData = MsgData;
|
|
m_ProcessName = ProcessName;
|
|
m_BoxName = BoxName;
|
|
m_Count = 1;
|
|
|
|
m_pLabel = new QLabel(Message);
|
|
m_pLabel->setToolTip(Message);
|
|
m_pLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Maximum);
|
|
connect(m_pLabel, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&)));
|
|
m_pMainLayout->addWidget(m_pLabel, 0, 0);
|
|
|
|
if (MsgCode != 0)
|
|
{
|
|
QToolButton* pHelp = new QToolButton();
|
|
pHelp->setText(tr("?"));
|
|
pHelp->setToolTip(tr("Visit %1 for a detailed explanation.").arg(Link));
|
|
pHelp->setMaximumWidth(16);
|
|
pHelp->setProperty("url", Link);
|
|
QObject::connect(pHelp, SIGNAL(clicked(bool)), this, SLOT(OnHelp()));
|
|
m_pMainLayout->addWidget(pHelp, 0, 1);
|
|
|
|
QToolButton* pFix = new QToolButton();
|
|
QFont fnt = pFix->font();
|
|
fnt.setBold(true);
|
|
//fnt.setWeight(QFont::DemiBold);
|
|
pFix->setFont(fnt);
|
|
pFix->setText(tr("Troubleshooting"));
|
|
pFix->setToolTip(tr("Start troubleshooting wizard"));
|
|
QObject::connect(pFix, SIGNAL(clicked(bool)), this, SLOT(OnTryFix()));
|
|
m_pMainLayout->addWidget(pFix, 0, 2);
|
|
|
|
QToolButton* pDismiss = new QToolButton();
|
|
pDismiss->setText(tr("Dismiss"));
|
|
pDismiss->setToolTip(tr("Remove this message from the list"));
|
|
pDismiss->setPopupMode(QToolButton::MenuButtonPopup);
|
|
QMenu* pMenu = new QMenu();
|
|
pMenu->addAction(tr("Hide all such messages"), this, SIGNAL(Hide()));
|
|
pDismiss->setMenu(pMenu);
|
|
//QObject::connect(pDismiss, SIGNAL(triggered(QAction*)), , SLOT());
|
|
QObject::connect(pDismiss, SIGNAL(clicked(bool)), this, SIGNAL(Dismiss()));
|
|
m_pMainLayout->addWidget(pDismiss, 0, 3);
|
|
}
|
|
}
|
|
|
|
quint32 GetMsgCode() { return m_MsgCode; }
|
|
quint32 GetMsgId() { return m_MsgCode & 0xFFFF; }
|
|
QStringList GetMsgData() { return m_MsgData; }
|
|
QString GetMsgData(int Index) { return m_MsgData.size() <= Index ? QString() : m_MsgData[Index]; }
|
|
|
|
QString GetMsgString() { return m_Message; }
|
|
void Repeat() { m_Count++; m_pLabel->setText(m_Message + tr(" (%1)").arg(m_Count)); }
|
|
|
|
signals:
|
|
void Dismiss();
|
|
void Hide();
|
|
|
|
private slots:
|
|
void OnHelp() { QDesktopServices::openUrl(QUrl(sender()->property("url").toString())); }
|
|
void OnTryFix()
|
|
{
|
|
theGUI->TryFix(m_MsgCode, m_MsgData, m_ProcessName, m_BoxName);
|
|
}
|
|
|
|
protected:
|
|
QString m_Message;
|
|
quint32 m_MsgCode;
|
|
QStringList m_MsgData;
|
|
QString m_ProcessName;
|
|
QString m_BoxName;
|
|
QLabel* m_pLabel;
|
|
int m_Count;
|
|
};
|
|
|
|
class CPopUpPrompt : public CPopUpEntry
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
CPopUpPrompt(const QString& Message, quint32 RequestId, QVariantMap Result, const CBoxedProcessPtr& pProcess, QWidget* parent = 0) : CPopUpEntry(Message, parent)
|
|
{
|
|
m_RequestId = RequestId;
|
|
m_Result = Result;
|
|
m_pProcess = pProcess;
|
|
m_bAddToList = false;
|
|
|
|
m_pLabel = new QLabel(Message);
|
|
m_pLabel->setToolTip(Message);
|
|
m_pLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Maximum);
|
|
connect(m_pLabel, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&)));
|
|
m_pMainLayout->addWidget(m_pLabel, 0, 0, 1, 5);
|
|
|
|
m_pRemember = new QCheckBox(tr("Remember for this process"));
|
|
m_pRemember->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
|
|
m_pMainLayout->addWidget(m_pRemember, 1, 0);
|
|
|
|
m_pTimeOut = new QLabel();
|
|
//m_pTimeOut->setStyleSheet("background-color:red;");
|
|
m_pMainLayout->addWidget(m_pTimeOut, 1, 1);
|
|
|
|
|
|
m_pYes = new QToolButton();
|
|
m_pYes->setText(tr("Yes"));
|
|
connect(m_pYes, SIGNAL(clicked(bool)), this, SLOT(OnAccepted()));
|
|
m_pMainLayout->addWidget(m_pYes, 1, 2);
|
|
|
|
m_pNo = new QToolButton();
|
|
m_pNo->setText(tr("No"));
|
|
connect(m_pNo, SIGNAL(clicked(bool)), this, SLOT(OnRejected()));
|
|
m_pMainLayout->addWidget(m_pNo, 1, 3);
|
|
|
|
m_pTerminate = new QToolButton();
|
|
m_pTerminate->setText(tr("Terminate"));
|
|
connect(m_pTerminate, SIGNAL(clicked(bool)), this, SLOT(OnTerminate()));
|
|
m_pMainLayout->addWidget(m_pTerminate, 1, 4);
|
|
|
|
|
|
m_iTimeOutSec = 60; // todo: communicate the actual value from dll or have a setting for that
|
|
|
|
if (RequestId == 0)
|
|
m_uTimerID = -1;
|
|
else
|
|
m_uTimerID = startTimer(1000);
|
|
}
|
|
~CPopUpPrompt() {
|
|
if(m_uTimerID != -1)
|
|
killTimer(m_uTimerID);
|
|
}
|
|
|
|
void AddAddToList()
|
|
{
|
|
m_pYes->setPopupMode(QToolButton::MenuButtonPopup);
|
|
QMenu* pMenu = new QMenu();
|
|
pMenu->addAction(tr("Yes and add to allowed programs"), this, SLOT(OnAcceptedAlways()));
|
|
m_pYes->setMenu(pMenu);
|
|
}
|
|
|
|
signals:
|
|
void PromptResult(int retval);
|
|
|
|
private slots:
|
|
void OnAcceptedAlways() { m_bAddToList = true; emit PromptResult(1); }
|
|
void OnAccepted() { emit PromptResult(1); }
|
|
void OnRejected() { emit PromptResult(0); }
|
|
void OnTerminate() { emit PromptResult(-1); }
|
|
|
|
protected:
|
|
friend class CPopUpWindow;
|
|
|
|
void timerEvent(QTimerEvent* pEvent)
|
|
{
|
|
if (pEvent->timerId() != m_uTimerID)
|
|
return;
|
|
if (m_iTimeOutSec > 0)
|
|
{
|
|
m_iTimeOutSec--;
|
|
|
|
extern bool CPopUpWindow__DarkMode;
|
|
if (CPopUpWindow__DarkMode) {
|
|
QPalette palette = m_pLabel->palette();
|
|
palette.setColor(QPalette::Text, Qt::red);
|
|
m_pLabel->setPalette(palette);
|
|
}
|
|
else
|
|
repaint();
|
|
}
|
|
|
|
if (m_pProcess->IsTerminated()) {
|
|
m_pTimeOut->setText(tr("Requesting process terminated"));
|
|
m_pYes->setEnabled(false);
|
|
m_pTerminate->setEnabled(false);
|
|
}
|
|
else if (m_iTimeOutSec > 0)
|
|
m_pTimeOut->setText(tr("Request will time out in %1 sec").arg(m_iTimeOutSec));
|
|
else {
|
|
m_pTimeOut->setText(tr("Request timed out").arg(m_iTimeOutSec));
|
|
m_pYes->setEnabled(false);
|
|
}
|
|
}
|
|
int m_uTimerID;
|
|
|
|
virtual void paintEvent(QPaintEvent *event)
|
|
{
|
|
QWidget::paintEvent(event);
|
|
|
|
extern bool CPopUpWindow__DarkMode;
|
|
if (!CPopUpWindow__DarkMode && (m_iTimeOutSec % 2) != 0)
|
|
{
|
|
QPainter p(this);
|
|
p.fillRect(2, 1, width() - 4, height() - 2, QColor(0xFF, 0xCC, 0xCC));
|
|
}
|
|
}
|
|
|
|
quint32 m_RequestId;
|
|
QVariantMap m_Result;
|
|
CBoxedProcessPtr m_pProcess;
|
|
bool m_bAddToList;
|
|
|
|
QLabel* m_pLabel;
|
|
QCheckBox* m_pRemember;
|
|
qint32 m_iTimeOutSec;
|
|
QLabel* m_pTimeOut;
|
|
QToolButton* m_pYes;
|
|
QToolButton* m_pNo;
|
|
QToolButton* m_pTerminate;
|
|
};
|
|
|
|
class CPopUpRecovery : public CPopUpEntry
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
CPopUpRecovery(const QString& Message, const QString& FilePath, const QString& BoxPath, const QString& BoxName, QWidget* parent = 0) : CPopUpEntry(Message, parent)
|
|
{
|
|
m_BoxName = BoxName;
|
|
m_FilePath = FilePath;
|
|
m_BoxPath = BoxPath;
|
|
|
|
QLabel* pLabel = new QLabel(Message);
|
|
pLabel->setToolTip(Message);
|
|
pLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Maximum);
|
|
//pLabel->setWordWrap(true);
|
|
extern bool CPopUpWindow__DarkMode;
|
|
if(CPopUpWindow__DarkMode) {
|
|
QPalette palette = pLabel->palette();
|
|
palette.setColor(QPalette::Text, Qt::green);
|
|
pLabel->setPalette(palette);
|
|
}
|
|
m_pMainLayout->addWidget(pLabel, 0, 0, 2, 4);
|
|
|
|
m_pMainLayout->addWidget(new QLabel(tr("Recover to:")), 2, 0);
|
|
m_pTarget = new QComboBox();
|
|
|
|
m_LastTargetIndex = 0;
|
|
m_pTarget->addItem(m_FilePath.left(m_FilePath.lastIndexOf("\\")));
|
|
m_pTarget->addItem(tr("Browse"), 1);
|
|
m_pTarget->addItem(tr("Clear folder list"), -1);
|
|
m_ListCleared = false;
|
|
connect(m_pTarget, SIGNAL(currentIndexChanged(int)), this, SLOT(OnTargetChanged()));
|
|
|
|
m_pTarget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
m_pMainLayout->addWidget(m_pTarget, 2, 1);
|
|
|
|
QToolButton* pRecover = new QToolButton();
|
|
pRecover->setText(tr("Recover"));
|
|
pRecover->setToolTip(tr("Recover the file to original location"));
|
|
pRecover->setPopupMode(QToolButton::MenuButtonPopup);
|
|
QMenu* pRecMenu = new QMenu();
|
|
pRecMenu->addAction(tr("Recover && Explore"), this, SLOT(OnRecoverExp()));
|
|
pRecMenu->addAction(tr("Recover && Open/Run"), this, SLOT(OnRecoverRun()));
|
|
pRecMenu->addSeparator();
|
|
pRecMenu->addAction(tr("Open file recovery for this box"), this, SIGNAL(OpenRecovery()));
|
|
pRecover->setMenu(pRecMenu);
|
|
//QObject::connect(pRecover, SIGNAL(triggered(QAction*)), , SLOT());
|
|
QObject::connect(pRecover, SIGNAL(clicked(bool)), this, SLOT(OnRecover()));
|
|
m_pMainLayout->addWidget(pRecover, 2, 2);
|
|
|
|
|
|
QToolButton* pDismiss = new QToolButton();
|
|
pDismiss->setText(tr("Dismiss"));
|
|
pDismiss->setToolTip(tr("Don't recover this file right now"));
|
|
pDismiss->setPopupMode(QToolButton::MenuButtonPopup);
|
|
QMenu* pMenu = new QMenu();
|
|
pMenu->addAction(tr("Dismiss all from this box"), this, SLOT(OnDismissAll()));
|
|
pMenu->addAction(tr("Disable quick recovery until the box restarts"), this, SLOT(OnDisable()));
|
|
pDismiss->setMenu(pMenu);
|
|
//QObject::connect(pDismiss, SIGNAL(triggered(QAction*)), , SLOT());
|
|
QObject::connect(pDismiss, SIGNAL(clicked(bool)), this, SIGNAL(Dismiss()));
|
|
m_pMainLayout->addWidget(pDismiss, 2, 3);
|
|
}
|
|
|
|
signals:
|
|
void Dismiss(int iFlag = 0);
|
|
void RecoverFile(int Action = 0);
|
|
void OpenRecovery();
|
|
|
|
private slots:
|
|
void OnDisable() { emit Dismiss(0x03); }
|
|
void OnDismissAll() { emit Dismiss(0x01); }
|
|
void OnRecover() { emit RecoverFile(); }
|
|
void OnRecoverRun() { emit RecoverFile(1); }
|
|
void OnRecoverExp() { emit RecoverFile(2); }
|
|
|
|
void OnTargetChanged()
|
|
{
|
|
int op = m_pTarget->currentData().toInt();
|
|
if (op == 1)
|
|
{
|
|
QString Folder = QFileDialog::getExistingDirectory(this, tr("Select Directory")).replace("/", "\\");
|
|
if (Folder.isEmpty()) {
|
|
m_pTarget->setCurrentIndex(m_LastTargetIndex);
|
|
return;
|
|
}
|
|
m_LastTargetIndex = m_pTarget->count() - 1;
|
|
m_pTarget->insertItem(m_LastTargetIndex, Folder);
|
|
m_pTarget->setCurrentIndex(m_LastTargetIndex);
|
|
}
|
|
else if (op == -1)
|
|
{
|
|
while (m_pTarget->count() > 3)
|
|
m_pTarget->removeItem(2);
|
|
m_pTarget->setCurrentIndex(0);
|
|
m_ListCleared = true;
|
|
}
|
|
}
|
|
|
|
protected:
|
|
friend class CPopUpWindow;
|
|
|
|
virtual void paintEvent(QPaintEvent *event)
|
|
{
|
|
QWidget::paintEvent(event);
|
|
|
|
extern bool CPopUpWindow__DarkMode;
|
|
if (!CPopUpWindow__DarkMode) {
|
|
QPainter p(this);
|
|
p.fillRect(2, 1, width() - 4, height() - 2, QColor(0xCC, 0xFF, 0xCC));
|
|
}
|
|
}
|
|
|
|
QString m_FilePath;
|
|
QString m_BoxPath;
|
|
QString m_BoxName;
|
|
QComboBox* m_pTarget;
|
|
int m_LastTargetIndex;
|
|
bool m_ListCleared;
|
|
};
|
|
|
|
class CPopUpProgress : public CPopUpEntry
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
CPopUpProgress(const QString& Message, const QString& ID, quint64 Total, QWidget* parent = 0) : CPopUpEntry(Message, parent)
|
|
{
|
|
m_ID = ID;
|
|
m_Total = Total;
|
|
|
|
m_pLabel = new QLabel(Message);
|
|
m_pLabel->setToolTip(Message);
|
|
m_pLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Maximum);
|
|
m_pMainLayout->addWidget(m_pLabel, 0, 0, 1, 3);
|
|
|
|
m_pProgressBar = new QProgressBar();
|
|
m_pProgressBar->setTextVisible(false);
|
|
m_pProgressBar->setMaximum(m_Total != 0? 100 : 0);
|
|
m_pProgressBar->setMinimum(0);
|
|
m_pProgressBar->setFixedHeight(16);
|
|
|
|
m_pMainLayout->addWidget(m_pProgressBar, 1, 0, 1, 2);
|
|
|
|
QToolButton* pDismiss = new QToolButton();
|
|
pDismiss->setText(tr("Dismiss"));
|
|
pDismiss->setToolTip(tr("Remove this progress indicator from the list"));
|
|
//pDismiss->setPopupMode(QToolButton::MenuButtonPopup);
|
|
//QMenu* pMenu = new QMenu();
|
|
//pMenu->addAction(tr("Hide this progress for this process"), this, SIGNAL(Hide()));
|
|
//pDismiss->setMenu(pMenu);
|
|
//QObject::connect(pDismiss, SIGNAL(triggered(QAction*)), , SLOT());
|
|
QObject::connect(pDismiss, SIGNAL(clicked(bool)), this, SIGNAL(Dismiss()));
|
|
m_pMainLayout->addWidget(pDismiss, 1, 2);
|
|
|
|
m_iTimeOutSec = 5;
|
|
|
|
m_uTimerID = startTimer(1000);
|
|
}
|
|
~CPopUpProgress() {
|
|
if (m_uTimerID != -1)
|
|
killTimer(m_uTimerID);
|
|
}
|
|
|
|
void UpdateProgress(const QString& Message, quint64 Value)
|
|
{
|
|
if(m_Total != 0)
|
|
m_pProgressBar->setValue(100 - (100 * Value / m_Total));
|
|
m_pLabel->setText(Message);
|
|
m_iTimeOutSec = 5;
|
|
}
|
|
|
|
signals:
|
|
void Dismiss(bool bHide = true);
|
|
//void Hide();
|
|
|
|
protected:
|
|
friend class CPopUpWindow;
|
|
|
|
void timerEvent(QTimerEvent* pEvent)
|
|
{
|
|
if (pEvent->timerId() != m_uTimerID)
|
|
return;
|
|
if (m_iTimeOutSec > 0)
|
|
{
|
|
if (--m_iTimeOutSec == 0)
|
|
emit Dismiss(false);
|
|
}
|
|
}
|
|
int m_uTimerID;
|
|
|
|
QString m_ID;
|
|
quint64 m_Total;
|
|
|
|
QLabel* m_pLabel;
|
|
QProgressBar* m_pProgressBar;
|
|
qint32 m_iTimeOutSec;
|
|
};
|
|
|
|
|
|
class CPopUpWindow : public QMainWindow
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
CPopUpWindow(QWidget* parent = 0);
|
|
~CPopUpWindow();
|
|
|
|
virtual void AddLogMessage(quint32 MsgCode, const QStringList& MsgData, quint32 ProcessId);
|
|
virtual void AddUserPrompt(quint32 RequestId, const QVariantMap& Data, quint32 ProcessId);
|
|
virtual void AddFileToRecover(const QString& FilePath, QString BoxPath, const CSandBoxPtr& pBox, quint32 ProcessId);
|
|
virtual void ShowProgress(quint32 MsgCode, const QStringList& MsgData, quint32 ProcessId);
|
|
|
|
static void SetDarkMode(bool bDark) { extern bool CPopUpWindow__DarkMode; CPopUpWindow__DarkMode = bDark; }
|
|
|
|
public slots:
|
|
virtual void Show();
|
|
virtual void Poke();
|
|
|
|
virtual void ReloadHiddenMessages();
|
|
private slots:
|
|
virtual void OnDismissMessage();
|
|
virtual void OnHideMessage();
|
|
|
|
virtual void OnPromptResult(int retval);
|
|
|
|
virtual void OnDismiss(int iFlag);
|
|
virtual void OnRecoverFile(int Action);
|
|
virtual void OnOpenRecovery();
|
|
|
|
virtual void OnDismissProgress(bool bHide);
|
|
|
|
virtual void OnCopy();
|
|
|
|
protected:
|
|
virtual void closeEvent(QCloseEvent *e);
|
|
|
|
void timerEvent(QTimerEvent* pEvent);
|
|
|
|
virtual void AddEntry(CPopUpEntry* pEntry);
|
|
virtual void RemoveEntry(CPopUpEntry* pEntry);
|
|
|
|
virtual bool IsMessageHidden(quint32 MsgCode, const QStringList& MsgData);
|
|
|
|
virtual void SendPromptResult(CPopUpPrompt* pEntry, int retval);
|
|
|
|
QMultiMap<quint32, QString> m_HiddenMessages;
|
|
bool m_HideAllMessages;
|
|
|
|
private:
|
|
bool m_ResetPosition;
|
|
QAction* m_pActionCopy;
|
|
int m_uTimerID;
|
|
int m_iTopMost;
|
|
Ui::PopUpWindow ui;
|
|
};
|