/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see .
*/
#include "installdialog.h"
#include "ui_installdialog.h"
#include
#include
#include
#include
#include
#include
#include
#include
using namespace MOBase;
InstallDialog::InstallDialog(
std::shared_ptr tree, const GuessedValue& modName,
std::shared_ptr modDataChecker,
const QString& dataName, QWidget* parent)
: TutorableDialog("InstallDialog", parent), ui(new Ui::InstallDialog),
m_Checker(modDataChecker), m_DataFolderName(dataName)
{
ui->setupUi(this);
for (auto iter = modName.variants().begin(); iter != modName.variants().end();
++iter) {
ui->nameCombo->addItem(*iter);
}
ui->nameCombo->setCurrentIndex(ui->nameCombo->findText(modName));
ui->nameCombo->completer()->setCaseSensitivity(Qt::CaseSensitive);
m_ProblemLabel = ui->problemLabel;
m_Tree = ui->treeContent;
m_TreeRoot = new ArchiveTreeWidgetItem(tree);
m_Tree->setup(m_DataFolderName);
connect(m_Tree, &ArchiveTreeWidget::treeChanged, [this] {
updateProblems();
});
m_Tree->setDataRoot(m_TreeRoot);
}
InstallDialog::~InstallDialog()
{
delete ui;
}
QString InstallDialog::getModName() const
{
return ui->nameCombo->currentText();
}
/**
* @brief Retrieve the user-modified directory structure.
*
* @return the new tree represented by this dialog, which can be a new
* tree or a subtree of the original tree.
**/
std::shared_ptr InstallDialog::getModifiedTree() const
{
return m_Tree->root()->entry()->astree();
}
bool InstallDialog::testForProblem()
{
if (!m_Checker) {
return true;
}
return m_Checker->dataLooksValid(m_Tree->root()->entry()->astree()) ==
ModDataChecker::CheckReturn::VALID;
}
void InstallDialog::updateProblems()
{
if (!m_Checker) {
m_Tree->setStyleSheet("QTreeWidget { border: none; }");
m_ProblemLabel->setText(
tr("Cannot check the content of <%1>.").arg(m_DataFolderName));
m_ProblemLabel->setToolTip(tr("The plugin for the current game does not provide a "
"way to check the content of <%1>.")
.arg(m_DataFolderName));
m_ProblemLabel->setStyleSheet("color: darkYellow;");
} else if (testForProblem()) {
m_Tree->setStyleSheet(
"QTreeWidget { border: 1px solid darkGreen; border-radius: 2px; }");
m_ProblemLabel->setText(
tr("The content of <%1> looks valid.").arg(m_DataFolderName));
m_ProblemLabel->setToolTip(
tr("The content of <%1> seems valid for the current game.")
.arg(m_DataFolderName));
m_ProblemLabel->setStyleSheet("color: darkGreen;");
} else {
m_Tree->setStyleSheet("QTreeWidget { border: 1px solid red; border-radius: 2px; }");
m_ProblemLabel->setText(
tr("The content of <%1> does not look valid.").arg(m_DataFolderName));
m_ProblemLabel->setToolTip(
tr("The content of <%1> is probably not valid for the current game.")
.arg(m_DataFolderName));
m_ProblemLabel->setStyleSheet("color: red;");
}
}
void InstallDialog::createDirectoryUnder(ArchiveTreeWidgetItem* item)
{
// Should never happen if we customize the context menu depending
// on the item:
if (!item->entry()->isDir()) {
reportError(tr("Cannot create directory under a file."));
return;
}
// Retrieve the directory:
auto fileTree = item->entry()->astree();
bool ok = false;
QString result = QInputDialog::getText(this, tr("Enter a directory name"), tr("Name"),
QLineEdit::Normal, QString(), &ok);
result = result.trimmed();
if (ok && !result.isEmpty()) {
// If a file with this name already exists:
if (fileTree->exists(result)) {
reportError(tr("A directory or file with that name already exists."));
return;
}
item->setExpanded(true);
auto* newItem = m_Tree->addDirectory(item, result);
m_Tree->scrollToItem(newItem);
}
}
void InstallDialog::on_treeContent_customContextMenuRequested(QPoint pos)
{
ArchiveTreeWidgetItem* selectedItem =
static_cast(m_Tree->itemAt(pos));
if (selectedItem == nullptr) {
return;
}
QMenu menu;
if (selectedItem != m_Tree->root() && selectedItem->entry()->isDir()) {
menu.addAction(tr("Set as <%1> directory").arg(m_DataFolderName),
[this, selectedItem]() {
m_Tree->setDataRoot(selectedItem);
});
}
if (m_Tree->root()->entry() != m_TreeRoot->entry()) {
menu.addAction(tr("Unset <%1> directory").arg(m_DataFolderName), [this]() {
m_Tree->setDataRoot(m_TreeRoot);
});
}
// Add a separator if not empty:
if (!menu.isEmpty()) {
menu.addSeparator();
}
if (selectedItem->entry()->isDir()) {
menu.addAction(tr("Create directory..."), [this, selectedItem]() {
createDirectoryUnder(selectedItem);
});
} else {
menu.addAction(tr("&Open"), [this, selectedItem]() {
emit openFile(selectedItem->entry().get());
});
}
menu.exec(m_Tree->mapToGlobal(pos));
}
void InstallDialog::on_okButton_clicked()
{
if (!testForProblem()) {
if (QMessageBox::question(
this, tr("Continue?"),
tr("This mod was probably NOT set up correctly, most likely it will NOT "
"work. "
"You should first correct the directory layout using the content-tree."),
QMessageBox::Ignore | QMessageBox::Cancel,
QMessageBox::Cancel) == QMessageBox::Cancel) {
return;
}
}
this->accept();
}
void InstallDialog::on_cancelButton_clicked()
{
this->reject();
}