/* 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 "report.h" #include "utility.h" #include "installationtester.h" #include #include #include using namespace MOBase; InstallDialog::InstallDialog(DirectoryTree *tree, const QString &modName, QWidget *parent) : TutorableDialog("InstallDialog", parent), ui(new Ui::InstallDialog), m_DataTree(tree), m_TreeRoot(NULL), m_DataRoot(NULL), m_TreeSelection(NULL), m_Updating(false) { ui->setupUi(this); QLineEdit *editName = findChild("editName"); editName->setText(modName); m_Tree = findChild("treeContent"); m_ProblemLabel = findChild("problemLabel"); connect(m_Tree, SIGNAL(changed()), this, SLOT(treeChanged())); updatePreview(); } InstallDialog::~InstallDialog() { delete ui; } QString InstallDialog::getModName() const { QLineEdit *editName = findChild("editName"); return editName->text(); } void InstallDialog::mapDataNode(DirectoryTree::Node *node, QTreeWidgetItem *baseItem) const { for (int i = 0; i < baseItem->childCount(); ++i) { QTreeWidgetItem *currentItem = baseItem->child(i); if (currentItem->checkState(0) != Qt::Unchecked) { if (currentItem->data(0, Qt::UserRole).isNull()) { DirectoryTree::Node *newNode = new DirectoryTree::Node; newNode->setData(currentItem->text(0)); mapDataNode(newNode, currentItem); node->addNode(newNode, true); } else { node->addLeaf(FileTreeInformation(currentItem->text(0), currentItem->data(0, Qt::UserRole).toInt())); } } } } DirectoryTree *InstallDialog::getDataTree() const { DirectoryTree *base = new DirectoryTree; mapDataNode(base, m_Tree->topLevelItem(0)); return base; } QString InstallDialog::getFullPath(const DirectoryTree::Node *node) { QString result(node->getData().name); const DirectoryTree::Node *parent = node->getParent(); while (parent != NULL) { if (parent->getParent() != NULL) { result.prepend("\\"); } result.prepend(parent->getData().name); parent = parent->getParent(); } return result; } void InstallDialog::addDataToTree(DirectoryTree::Node *node, QTreeWidgetItem *treeItem) { QString path = getFullPath(node); // add directory elements for (DirectoryTree::node_iterator iter = node->nodesBegin(); iter != node->nodesEnd(); ++iter) { QStringList fields((*iter)->getData().name); QTreeWidgetItem *newNodeItem = new QTreeWidgetItem(treeItem, fields); newNodeItem->setFlags(newNodeItem->flags() | Qt::ItemIsUserCheckable | Qt::ItemIsTristate); newNodeItem->setCheckState(0, Qt::Checked); addDataToTree(*iter, newNodeItem); treeItem->addChild(newNodeItem); } // add file elements for (DirectoryTree::leaf_iterator iter = node->leafsBegin(); iter != node->leafsEnd(); ++iter) { QStringList fields(iter->getName()); QTreeWidgetItem *newLeafItem = new QTreeWidgetItem(treeItem, fields); newLeafItem->setFlags(newLeafItem->flags() | Qt::ItemIsUserCheckable); newLeafItem->setCheckState(0, Qt::Checked); if (path.size() != 0) { newLeafItem->setToolTip(0, path.mid(0).append("\\").append(iter->getName())); } else { newLeafItem->setToolTip(0, iter->getName()); } newLeafItem->setData(0, Qt::UserRole, iter->getIndex()); treeItem->addChild(newLeafItem); } } void InstallDialog::updatePreview() { m_Updating = true; m_Tree->clear(); delete m_TreeRoot; m_TreeRoot = new QTreeWidgetItem(m_Tree, QStringList("")); addDataToTree(m_DataTree, m_TreeRoot); setDataRoot(m_TreeRoot); m_Updating = false; updateProblems(); } bool InstallDialog::testForProblem() { bool ok = false; QTreeWidgetItem *tlWidget = m_Tree->topLevelItem(0); for (int i = 0; i < tlWidget->childCount(); ++i) { QTreeWidgetItem *widget = tlWidget->child(i); if (widget->checkState(0) == Qt::Unchecked) { continue; } if (widget->data(0, Qt::UserRole).isValid()) { // file if (InstallationTester::isTopLevelSuffix(widget->text(0))) { ok = true; break; } } else { // directory if (InstallationTester::isTopLevelDirectory(widget->text(0))) { ok = true; break; } } } return ok; } void InstallDialog::updateProblems() { if (testForProblem()) { m_ProblemLabel->setText(tr("Looks good")); m_ProblemLabel->setToolTip(tr("No problem detected")); m_ProblemLabel->setStyleSheet("color: darkGreen;"); } else { m_ProblemLabel->setText(tr("No game data on top level")); m_ProblemLabel->setToolTip(tr("There is no esp/esm file or asset directory (textures, meshes, interface, ...) " "on the top level.")); m_ProblemLabel->setStyleSheet("color: red;"); } } void InstallDialog::setDataRoot(QTreeWidgetItem* root) { if (root != NULL) { m_DataRoot = root; m_Tree->takeTopLevelItem(0); QTreeWidgetItem *temp = root->clone(); // temp->setCheckState(0, Qt::Checked); temp->setFlags(temp->flags() & ~(Qt::ItemIsUserCheckable | Qt::ItemIsTristate)); temp->setText(0, ""); temp->setData(0, Qt::CheckStateRole, QVariant()); m_Tree->addTopLevelItem(temp); temp->setExpanded(true); } else { m_Tree->takeTopLevelItem(0); } updateProblems(); } void InstallDialog::use_as_data() { if (m_TreeSelection != NULL) { setDataRoot(m_TreeSelection); m_TreeSelection = NULL; } updateProblems(); } void InstallDialog::unset_data() { m_TreeSelection = NULL; setDataRoot(m_TreeRoot); updateProblems(); } void InstallDialog::create_directory() { bool ok = false; QString result = QInputDialog::getText(this, tr("Enter a directory name"), tr("Name"), QLineEdit::Normal, QString(), &ok); if (ok && !result.isEmpty()) { for (int i = 0; i < m_TreeSelection->childCount(); ++i) { if (m_TreeSelection->child(i)->text(0) == result) { reportError(tr("A directory with that name exists")); return; } } QStringList fields(result); QTreeWidgetItem *newItem = new QTreeWidgetItem(m_TreeSelection, fields); newItem->setFlags(newItem->flags() | Qt::ItemIsUserCheckable); newItem->setCheckState(0, Qt::Checked); m_TreeSelection->addChild(newItem); updateProblems(); } } void InstallDialog::open_file() { emit openFile(m_TreeSelection->toolTip(0)); } void InstallDialog::on_treeContent_customContextMenuRequested(QPoint pos) { m_TreeSelection = m_Tree->itemAt(pos); if (m_TreeSelection == 0) { return; } QMenu menu; menu.addAction(tr("Set data directory"), this, SLOT(use_as_data())); menu.addAction(tr("Unset data directory"), this, SLOT(unset_data())); if (m_TreeSelection->data(0, Qt::UserRole).isNull()) { menu.addAction(tr("Create directory..."), this, SLOT(create_directory())); } else { menu.addAction(tr("&Open"), this, SLOT(open_file())); } menu.exec(m_Tree->mapToGlobal(pos)); } void InstallDialog::treeChanged() { updateProblems(); } 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. Really continue?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) { return; } } this->accept(); } void InstallDialog::on_cancelButton_clicked() { this->reject(); }