Sandboxie/SandboxiePlus/SandMan/Windows/OptionsTemplates.cpp

342 lines
11 KiB
C++

#include "stdafx.h"
#include "OptionsWindow.h"
#include "SandMan.h"
#include "SettingsWindow.h"
#include "../MiscHelpers/Common/Settings.h"
#include "../MiscHelpers/Common/Common.h"
#include "../MiscHelpers/Common/ComboInputDialog.h"
#include "../MiscHelpers/Common/SettingsWidgets.h"
#include "Helpers/WinAdmin.h"
void COptionsWindow::LoadTemplates()
{
m_AllTemplates.clear();
//ui.cmbCategories->clear();
QStringList Templates;
for (int index = 0; ; index++)
{
QString Value = m_pBox->GetAPI()->SbieIniGet2("", "", index, false, true, true);
if (Value.isNull())
break;
Templates.append(Value);
}
foreach(const QString& Name, Templates)
{
if (Name.left(9).compare("Template_", Qt::CaseInsensitive) != 0)
continue;
QString Category = m_pBox->GetAPI()->SbieIniGet2(Name, "Tmpl.Class", 0, false, true, true);
QString Title = m_pBox->GetAPI()->SbieIniGet2(Name, "Tmpl.Title", 0, false, true, true);
QString Hide = m_pBox->GetAPI()->SbieIniGet2(Name, "Tmpl.Hide", 0, false, true, true);
if (Hide == "y" || Hide == "Y")
continue;
if (Name == "Template_ScreenReader" || Name == "Template_KnownConflicts")
continue;
if (Title.left(1) == "#")
{
int End = Title.mid(1).indexOf(",");
if (End == -1) End = Title.length() - 1;
int MsgNum = Title.mid(1, End).toInt();
Title = m_pBox->GetAPI()->GetSbieMsgStr(MsgNum, theGUI->m_LanguageId).arg(Title.mid(End + 2)).arg("");
}
if (Title.isEmpty()) Title = Name;
//else Title += " (" + Name + ")";
if (Title == "-")
continue; // skip separators
m_AllTemplates.insertMulti(Category, qMakePair(Name, Title));
}
if (ui.cmbCategories->count() == 0)
{
ui.cmbCategories->addItem(tr("All Categories"), "");
ui.cmbCategories->setCurrentIndex(0);
foreach(const QString & Category, m_AllTemplates.uniqueKeys())
{
if (Category.isEmpty())
continue;
ui.cmbCategories->addItem(GetCategoryName(Category), Category);
}
}
m_GlobalTemplates = m_pBox->GetAPI()->GetGlobalSettings()->GetTextList("Template", false);
m_BoxTemplates = m_pBox->GetTextList("Template", false);
LoadFolders();
ui.chkScreenReaders->setChecked(m_BoxTemplates.contains("ScreenReader"));
ShowTemplates();
m_TemplatesChanged = false;
}
void COptionsWindow::SetTemplate(const QString& Template, bool bEnabled)
{
if(bEnabled)
m_BoxTemplates.append(Template);
else
m_BoxTemplates.removeAll(Template);
m_TemplatesChanged = true;
OnOptChanged();
}
void COptionsWindow::OnScreenReaders()
{
SetTemplate("ScreenReader", ui.chkScreenReaders->isChecked());
}
QString COptionsWindow::GetCategoryName(const QString& Category)
{
if (Category.compare("Local", Qt::CaseInsensitive) == 0) return tr("Custom Templates");
if (Category.compare("EmailReader", Qt::CaseInsensitive) == 0) return tr("Email Reader");
if (Category.compare("Print", Qt::CaseInsensitive) == 0) return tr("PDF/Print");
if (Category.compare("Security", Qt::CaseInsensitive) == 0) return tr("Security/Privacy");
if (Category.compare("Desktop", Qt::CaseInsensitive) == 0) return tr("Desktop Utilities");
if (Category.compare("Download", Qt::CaseInsensitive) == 0) return tr("Download Managers");
if (Category.compare("Misc", Qt::CaseInsensitive) == 0) return tr("Miscellaneous");
if (Category.compare("WebBrowser", Qt::CaseInsensitive) == 0) return tr("Web Browser");
if (Category.compare("MediaPlayer", Qt::CaseInsensitive) == 0) return tr("Media Player");
if (Category.compare("TorrentClient", Qt::CaseInsensitive) == 0) return tr("Torrent Client");
return Category;
}
void COptionsWindow::ShowTemplates()
{
ui.treeTemplates->clear();
QString CategoryFilter = ui.cmbCategories->currentData().toString();
QString TextFilter = ui.txtTemplates->text();
for (QMultiMap<QString, QPair<QString, QString>>::iterator I = m_AllTemplates.begin(); I != m_AllTemplates.end(); ++I)
{
if (!CategoryFilter.isEmpty() && I.key().compare(CategoryFilter, Qt::CaseInsensitive) != 0)
continue;
if (I.value().second.indexOf(TextFilter, 0, Qt::CaseInsensitive) == -1)
continue;
if (I.key().isEmpty())
continue; // don't show templates without a category (these are usually deprecated templates)
QString Name = I.value().first.mid(9);
QTreeWidgetItem* pItem = new QTreeWidgetItem();
pItem->setData(0, Qt::UserRole, I.key());
pItem->setText(0, GetCategoryName(I.key()));
pItem->setData(1, Qt::UserRole, I.value().first);
pItem->setText(1, I.value().second);
//pItem->setFlags(pItem->flags() | Qt::ItemIsUserCheckable);
if(m_GlobalTemplates.contains(Name))
pItem->setCheckState(1, Qt::PartiallyChecked);
else if (m_BoxTemplates.contains(Name))
pItem->setCheckState(1, Qt::Checked);
else
pItem->setCheckState(1, Qt::Unchecked);
ui.treeTemplates->addTopLevelItem(pItem);
}
ShowFolders();
}
void COptionsWindow::OnTemplateClicked(QTreeWidgetItem* pItem, int Column)
{
QString Name = pItem->data(1, Qt::UserRole).toString().mid(9);
if (m_GlobalTemplates.contains(Name)) {
if (pItem->checkState(1) != Qt::PartiallyChecked) {
QMessageBox::warning(this, "SandboxiePlus", tr("This template is enabled globally. To configure it, use the global options."));
pItem->setCheckState(1, Qt::PartiallyChecked);
}
return;
}
if (pItem->checkState(1) == Qt::Checked) {
if (!m_BoxTemplates.contains(Name)) {
m_BoxTemplates.append(Name);
m_TemplatesChanged = true;
OnOptChanged();
}
}
else if (pItem->checkState(1) == Qt::Unchecked) {
if (m_BoxTemplates.contains(Name)) {
m_BoxTemplates.removeAll(Name);
m_TemplatesChanged = true;
OnOptChanged();
}
}
}
void COptionsWindow::OnTemplateDoubleClicked(QTreeWidgetItem* pItem, int Column)
{
QSharedPointer<CSbieIni> pTemplate = QSharedPointer<CSbieIni>(new CSbieIni(pItem->data(1, Qt::UserRole).toString(), m_pBox->GetAPI()));
COptionsWindow OptionsWindow(pTemplate, pItem->text(1));
QPoint ParentPos = mapToGlobal(rect().topLeft());
OptionsWindow.move(ParentPos.x() + 30, ParentPos.y() + 10);
OptionsWindow.exec();
// todo update name if it changed
}
void COptionsWindow::OnAddTemplates()
{
QString Value = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please enter the template identifier"), QLineEdit::Normal);
if (Value.isEmpty())
return;
QString Name = QString(Value).replace(" ", "_");
SB_STATUS Status = m_pBox->GetAPI()->ValidateName(Name);
if (Status.IsError()) {
QMessageBox::critical(this, "Sandboxie-Plus", tr("Error: %1").arg(CSandMan::FormatError(Status)));
return;
}
QSharedPointer<CSbieIni> pTemplate = QSharedPointer<CSbieIni>(new CSbieIni("Template_Local_" + Name, m_pBox->GetAPI()));
pTemplate->SetText("Tmpl.Title", Value);
pTemplate->SetText("Tmpl.Class", "Local");
COptionsWindow OptionsWindow(pTemplate, Value);
OptionsWindow.exec();
LoadTemplates();
}
void COptionsWindow::OnTemplateWizard()
{
CTemplateWizard::ETemplateType Type = (CTemplateWizard::ETemplateType)((QAction*)sender())->data().toInt();
if (CSandBox* pBox = qobject_cast<CSandBox*>(m_pBox.data())) {
if (CTemplateWizard::CreateNewTemplate(pBox, Type, this)) {
LoadTemplates();
}
}
}
void COptionsWindow::OnOpenTemplate()
{
QTreeWidgetItem* pItem = ui.treeTemplates->currentItem();
if (pItem)
OnTemplateDoubleClicked(pItem, 0);
}
void COptionsWindow::OnDelTemplates()
{
if (QMessageBox("Sandboxie-Plus", tr("Do you really want to delete the selected local template(s)?"), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton, this).exec() != QMessageBox::Yes)
return;
foreach(QTreeWidgetItem * pItem, ui.treeTemplates->selectedItems())
{
if (!pItem || pItem->data(0, Qt::UserRole).toString() != "Local") {
QMessageBox::critical(this, "Sandboxie-Plus", tr("Only local templates can be removed!"));
break;
}
// delete section
m_pBox->GetAPI()->SbieIniSet(pItem->data(1, Qt::UserRole).toString(), "*", "");
}
LoadTemplates();
}
void COptionsWindow::SaveTemplates()
{
WriteTextList("Template", m_BoxTemplates);
m_TemplatesChanged = false;
}
void COptionsWindow::LoadFolders()
{
m_BoxFolders.clear();
foreach(const QString &Name, m_BoxTemplates)
{
QSharedPointer<CSbieIni> pTemplate = QSharedPointer<CSbieIni>(new CSbieIni("Template_" + Name, m_pBox->GetAPI()));
QList<QPair<QString, QString>> AllValues = pTemplate->GetIniSection(NULL, true);
for (QList<QPair<QString, QString>>::const_iterator I = AllValues.begin(); I != AllValues.end(); ++I)
{
QString Value = I->second;
int begin = Value.indexOf("%Tmpl.");
if (begin == -1) continue;
int end = Value.indexOf("%", begin + 6);
if (end == -1) continue;
QString Tmpl = Value.mid(begin + 1, end - begin - 1);
if (!m_BoxFolders.contains(Tmpl))
m_BoxFolders.append(Tmpl);
}
}
m_FoldersChanged = false;
}
void COptionsWindow::OnFolderChanged()
{
CPathEdit* pEdit = (CPathEdit*)sender();
QSharedPointer<CSbieIni> pTemplateSettings = QSharedPointer<CSbieIni>(new CSbieIni("TemplateSettings", m_pBox->GetAPI()));
QString Folder = pEdit->property("key").toString();
QString Test = pTemplateSettings->GetText(Folder + ":ExpectFile", "", false, true, true);
QString Path = pEdit->GetText();
if (!Test.isEmpty() && !Path.isEmpty())
{
if (!QFile::exists(Path + "\\" + Test))
QMessageBox::warning(this, "Sandboxie-Plus", tr("An alternate location for '%1'\nshould contain the following file:\n\n%2\n\nThe selected location does not contain this file.\nPlease select a folder which contains this file.").arg(Folder).arg(Test));
}
m_FoldersChanged = true;
OnOptChanged();
}
void COptionsWindow::ShowFolders()
{
QSharedPointer<CSbieIni> pTemplateSettings = QSharedPointer<CSbieIni>(new CSbieIni("TemplateSettings", m_pBox->GetAPI()));
QString UserName = m_pBox->GetAPI()->GetCurrentUserName();
ui.treeFolders->clear();
foreach(const QString &Folder, m_BoxFolders)
{
QTreeWidgetItem* pItem = new QTreeWidgetItem();
pItem->setText(0, Folder);
ui.treeFolders->addTopLevelItem(pItem);
CPathEdit* pEdit = new CPathEdit(true);
pEdit->SetWindowsPaths();
pEdit->SetDefault(pTemplateSettings->GetText(Folder, "", false, true, true));
pEdit->SetText(pTemplateSettings->GetText(Folder + "." + UserName));
pEdit->setProperty("key", Folder);
connect(pEdit, SIGNAL(textChanged(const QString&)), this, SLOT(OnFolderChanged()));
ui.treeFolders->setItemWidget(pItem, 1, pEdit);
}
}
void COptionsWindow::SaveFolders()
{
QSharedPointer<CSbieIni> pTemplateSettings = QSharedPointer<CSbieIni>(new CSbieIni("TemplateSettings", m_pBox->GetAPI()));
QString UserName = m_pBox->GetAPI()->GetCurrentUserName();
for (int i = 0; i < ui.treeFolders->topLevelItemCount(); i++)
{
QTreeWidgetItem* pItem = ui.treeFolders->topLevelItem(i);
QString Folder = pItem->text(0);
CPathEdit* pEdit = (CPathEdit*)ui.treeFolders->itemWidget(pItem, 1);
QString Path = pEdit->GetText();
if (Path.isEmpty())
pTemplateSettings->DelValue(Folder + "." + UserName);
else
pTemplateSettings->SetText(Folder + "." + UserName, Path);
}
m_FoldersChanged = false;
}