#include "stdafx.h" #include "SnapshotsWindow.h" #include "SandMan.h" #include "../MiscHelpers/Common/Settings.h" #include "../MiscHelpers/Common/TreeItemModel.h" CSnapshotsWindow::CSnapshotsWindow(const CSandBoxPtr& pBox, 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; setWindowFlags(flags); bool bAlwaysOnTop = theConf->GetBool("Options/AlwaysOnTop", false); this->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop); ui.setupUi(this); this->setWindowTitle(tr("%1 - Snapshots").arg(pBox->GetName())); ui.treeSnapshots->setAlternatingRowColors(theConf->GetBool("Options/AltRowColors", false)); m_pBox = pBox; m_SaveInfoPending = 0; QStyle* pStyle = QStyleFactory::create("windows"); ui.treeSnapshots->setStyle(pStyle); ui.treeSnapshots->setItemDelegate(new CTreeItemDelegate()); ui.treeSnapshots->setExpandsOnDoubleClick(false); m_pSnapshotModel = new CSimpleTreeModel(this); m_pSnapshotModel->AddColumn(tr("Snapshot"), "Name"); /*m_pSortProxy = new CSortFilterProxyModel(this); m_pSortProxy->setSortRole(Qt::EditRole); m_pSortProxy->setSourceModel(m_pSnapshotModel); m_pSortProxy->setDynamicSortFilter(true);*/ //ui.treeSnapshots->setItemDelegate(theGUI->GetItemDelegate()); //ui.treeSnapshots->setModel(m_pSortProxy); ui.treeSnapshots->setModel(m_pSnapshotModel); connect(ui.treeSnapshots, SIGNAL(clicked(const QModelIndex&)), this, SLOT(UpdateSnapshot(const QModelIndex&))); connect(ui.treeSnapshots->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(UpdateSnapshot(const QModelIndex&))); connect(ui.treeSnapshots, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(OnSelectSnapshot())); QMenu* pSelMenu = new QMenu(ui.btnSelect); pSelMenu->addAction(tr("Revert to empty box"), this, SLOT(OnSelectEmpty())); ui.btnSelect->setPopupMode(QToolButton::MenuButtonPopup); ui.btnSelect->setMenu(pSelMenu); connect(ui.btnTake, SIGNAL(clicked(bool)), this, SLOT(OnTakeSnapshot())); connect(ui.btnSelect, SIGNAL(clicked(bool)), this, SLOT(OnSelectSnapshot())); connect(ui.btnRemove, SIGNAL(clicked(bool)), this, SLOT(OnRemoveSnapshot())); connect(ui.txtName, SIGNAL(textEdited(const QString&)), this, SLOT(SaveInfo())); connect(ui.chkDefault, SIGNAL(clicked(bool)), this, SLOT(OnChangeDefault())); connect(ui.txtInfo, SIGNAL(textChanged()), this, SLOT(SaveInfo())); ui.groupBox->setEnabled(false); ui.btnSelect->setEnabled(false); ui.btnRemove->setEnabled(false); //statusBar(); restoreGeometry(theConf->GetBlob("SnapshotsWindow/Window_Geometry")); for (int i = 0; i < m_pSnapshotModel->columnCount(); i++) m_pSnapshotModel->SetColumnEnabled(i, true); UpdateSnapshots(true); } CSnapshotsWindow::~CSnapshotsWindow() { theConf->SetBlob("SnapshotsWindow/Window_Geometry",saveGeometry()); } void CSnapshotsWindow::closeEvent(QCloseEvent *e) { emit Closed(); this->deleteLater(); } void CSnapshotsWindow::UpdateSnapshots(bool AndSelect) { m_SnapshotMap.clear(); QList SnapshotList = m_pBox->GetSnapshots(&m_CurSnapshot, &m_DefaultSnapshot); foreach(const SBoxSnapshot& Snapshot, SnapshotList) { QVariantMap BoxSnapshot; BoxSnapshot["ID"] = Snapshot.ID; BoxSnapshot["ParentID"] = Snapshot.Parent; if(m_DefaultSnapshot == Snapshot.ID) BoxSnapshot["Name"] = Snapshot.NameStr + tr(" (default)"); else BoxSnapshot["Name"] = Snapshot.NameStr; BoxSnapshot["Info"] = Snapshot.InfoStr; BoxSnapshot["Date"] = Snapshot.SnapDate; if(m_CurSnapshot == Snapshot.ID) BoxSnapshot["IsBold"] = true; m_SnapshotMap.insert(Snapshot.ID, BoxSnapshot); } m_pSnapshotModel->Sync(m_SnapshotMap); ui.treeSnapshots->expandAll(); if (AndSelect) { QModelIndex CurIndex = m_pSnapshotModel->FindIndex(m_CurSnapshot); if (CurIndex.isValid()) { ui.treeSnapshots->selectionModel()->select(CurIndex, QItemSelectionModel::ClearAndSelect); UpdateSnapshot(CurIndex); } } } void CSnapshotsWindow::UpdateSnapshot(const QModelIndex& Index) { if (Index.isValid()) { ui.groupBox->setEnabled(true); ui.btnSelect->setEnabled(true); ui.btnRemove->setEnabled(true); } //QModelIndex Index = ui.treeSnapshots->currentIndex(); //QModelIndex ModelIndex = m_pSortProxy->mapToSource(Index); //QVariant ID = m_pSnapshotModel->GetItemID(ModelIndex); QVariant ID = m_pSnapshotModel->GetItemID(Index); OnSaveInfo(); m_SellectedID = ID; QVariantMap BoxSnapshot = m_SnapshotMap[ID]; m_SaveInfoPending = -1; ui.txtName->setText(BoxSnapshot["Name"].toString()); ui.chkDefault->setChecked(ID == m_DefaultSnapshot); ui.txtInfo->setPlainText(BoxSnapshot["Info"].toString()); m_SaveInfoPending = 0; //statusBar()->showMessage(tr("Snapshot: %1 taken: %2").arg(BoxSnapshot["Name"].toString()).arg(BoxSnapshot["Date"].toDateTime().toString())); } void CSnapshotsWindow::SaveInfo() { if (m_SaveInfoPending) return; m_SaveInfoPending = 1; QTimer::singleShot(500, this, SLOT(OnSaveInfo())); } void CSnapshotsWindow::OnSaveInfo() { if (m_SaveInfoPending != 1) return; m_SaveInfoPending = 0; m_pBox->SetSnapshotInfo(m_SellectedID.toString(), ui.txtName->text(), ui.txtInfo->toPlainText()); UpdateSnapshots(); } void CSnapshotsWindow::OnTakeSnapshot() { QString Value = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please enter a name for the new Snapshot."), QLineEdit::Normal, tr("New Snapshot")); if (Value.isEmpty()) return; HandleResult(m_pBox->TakeSnapshot(Value)); UpdateSnapshots(true); } void CSnapshotsWindow::OnSelectSnapshot() { QVariant ID = GetCurrentItem(); SelectSnapshot(ID.toString()); } void CSnapshotsWindow::OnSelectEmpty() { SelectSnapshot(QString()); } void CSnapshotsWindow::SelectSnapshot(const QString& ID) { if (QMessageBox("Sandboxie-Plus", tr("Do you really want to switch the active snapshot? Doing so will delete the current state!"), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton, this).exec() != QMessageBox::Yes) return; HandleResult(m_pBox->SelectSnapshot(ID)); } void CSnapshotsWindow::OnChangeDefault() { QVariant ID = GetCurrentItem(); if (ui.chkDefault->isChecked()) m_DefaultSnapshot = ID.toString(); else m_DefaultSnapshot.clear(); m_pBox->SetDefaultSnapshot(m_DefaultSnapshot); UpdateSnapshots(); } QVariant CSnapshotsWindow::GetCurrentItem() { QModelIndex Index = ui.treeSnapshots->currentIndex(); if (!Index.isValid() && !ui.treeSnapshots->selectionModel()->selectedIndexes().isEmpty()) Index = ui.treeSnapshots->selectionModel()->selectedIndexes().first(); //QModelIndex ModelIndex = m_pSortProxy->mapToSource(Index); //QVariant ID = m_pSnapshotModel->GetItemID(ModelIndex); return m_pSnapshotModel->GetItemID(Index); } void CSnapshotsWindow::OnRemoveSnapshot() { QVariant ID = GetCurrentItem(); if (QMessageBox("Sandboxie-Plus", tr("Do you really want to delete the selected snapshot?"), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton, this).exec() != QMessageBox::Yes) return; ui.groupBox->setEnabled(false); ui.btnSelect->setEnabled(false); ui.btnRemove->setEnabled(false); HandleResult(m_pBox->RemoveSnapshot(ID.toString())); } void CSnapshotsWindow::HandleResult(SB_PROGRESS Status) { if (Status.GetStatus() == OP_ASYNC) { connect(Status.GetValue().data(), SIGNAL(Finished()), this, SLOT(UpdateSnapshots())); theGUI->AddAsyncOp(Status.GetValue()); } else if (Status.IsError()) CSandMan::CheckResults(QList() << Status); UpdateSnapshots(); }