/* 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 "overwriteinfodialog.h" #include "report.h" #include "ui_overwriteinfodialog.h" #include "utility.h" #include #include #include #include using namespace MOBase; OverwriteInfoDialog::OverwriteInfoDialog(ModInfo::Ptr modInfo, OrganizerCore& organizer, QWidget* parent) : QDialog(parent), m_Organizer(organizer), ui(new Ui::OverwriteInfoDialog), m_FileSystemModel(nullptr), m_DeleteAction(nullptr), m_RenameAction(nullptr), m_OpenAction(nullptr) { ui->setupUi(this); this->setWindowModality(Qt::NonModal); m_FileSystemModel = new OverwriteFileSystemModel(this, organizer); m_FileSystemModel->setReadOnly(false); setModInfo(modInfo); ui->filesView->setModel(m_FileSystemModel); ui->filesView->setRootIndex(m_FileSystemModel->index(modInfo->absolutePath())); ui->filesView->setColumnWidth(0, 250); m_DeleteAction = new QAction(tr("&Delete"), ui->filesView); m_RenameAction = new QAction(tr("&Rename"), ui->filesView); m_OpenAction = new QAction(tr("&Open"), ui->filesView); m_NewFolderAction = new QAction(tr("&New Folder"), ui->filesView); new QShortcut(QKeySequence::Delete, this, SLOT(delete_activated())); QObject::connect(m_DeleteAction, SIGNAL(triggered()), this, SLOT(deleteTriggered())); QObject::connect(m_RenameAction, SIGNAL(triggered()), this, SLOT(renameTriggered())); QObject::connect(m_OpenAction, SIGNAL(triggered()), this, SLOT(openTriggered())); QObject::connect(m_NewFolderAction, SIGNAL(triggered()), this, SLOT(createDirectoryTriggered())); } OverwriteInfoDialog::~OverwriteInfoDialog() { delete ui; } void OverwriteInfoDialog::showEvent(QShowEvent* e) { const auto& s = Settings::instance(); s.geometry().restoreGeometry(this); if (!s.geometry().restoreState(ui->filesView->header())) { ui->filesView->sortByColumn(0, Qt::AscendingOrder); } QDialog::showEvent(e); } void OverwriteInfoDialog::done(int r) { auto& s = Settings::instance(); s.geometry().saveGeometry(this); s.geometry().saveState(ui->filesView->header()); QDialog::done(r); } void OverwriteInfoDialog::setModInfo(ModInfo::Ptr modInfo) { m_ModInfo = modInfo; if (QDir(modInfo->absolutePath()).exists()) { m_FileSystemModel->setRootPath(modInfo->absolutePath()); } else { throw MyException( tr("mod not found: %1").arg(qUtf8Printable(modInfo->absolutePath()))); } } bool OverwriteInfoDialog::recursiveDelete(const QModelIndex& index) { for (int childRow = 0; childRow < m_FileSystemModel->rowCount(index); ++childRow) { QModelIndex childIndex = m_FileSystemModel->index(childRow, 0, index); if (m_FileSystemModel->isDir(childIndex)) { if (!recursiveDelete(childIndex)) { log::error("failed to delete {}", m_FileSystemModel->fileName(childIndex)); return false; } } else { if (!m_FileSystemModel->remove(childIndex)) { log::error("failed to delete {}", m_FileSystemModel->fileName(childIndex)); return false; } } } if (!m_FileSystemModel->remove(index)) { log::error("failed to delete {}", m_FileSystemModel->fileName(index)); return false; } return true; } void OverwriteInfoDialog::deleteFile(const QModelIndex& index) { bool res = m_FileSystemModel->isDir(index) ? recursiveDelete(index) : m_FileSystemModel->remove(index); if (!res) { QString fileName = m_FileSystemModel->fileName(index); reportError(tr("Failed to delete \"%1\"").arg(fileName)); } } void OverwriteInfoDialog::delete_activated() { if (ui->filesView->hasFocus()) { QItemSelectionModel* selection = ui->filesView->selectionModel(); if (selection->hasSelection() && selection->selectedRows().count() >= 1) { auto root = m_FileSystemModel->rootDirectory(); if (selection->selectedRows().count() == 0) { return; } else if (selection->selectedRows().count() == 1) { for (auto modDir : m_Organizer.managedGame()->getModMappings().keys()) { if (root.absoluteFilePath(modDir).compare( m_FileSystemModel->filePath(selection->selectedRows().at(0)), Qt::CaseInsensitive) == 0) { return; } } QString fileName = m_FileSystemModel->fileName(selection->selectedRows().at(0)); if (QMessageBox::question( this, tr("Confirm"), tr("Are you sure you want to delete \"%1\"?").arg(fileName), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) { return; } } else { if (QMessageBox::question( this, tr("Confirm"), tr("Are you sure you want to delete the selected files?"), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) { return; } } foreach (QModelIndex index, selection->selectedRows()) { for (auto modDir : m_Organizer.managedGame()->getModMappings().keys()) { if (root.absoluteFilePath(modDir).compare(m_FileSystemModel->filePath(index), Qt::CaseInsensitive) == 0) { return; } } deleteFile(index); } } } } void OverwriteInfoDialog::deleteTriggered() { auto root = m_FileSystemModel->rootDirectory(); if (m_FileSelection.count() == 0) { return; } else if (m_FileSelection.count() == 1) { for (auto modDir : m_Organizer.managedGame()->getModMappings().keys()) { if (root.absoluteFilePath(modDir).compare( m_FileSystemModel->filePath(m_FileSelection.at(0)), Qt::CaseInsensitive) == 0) { return; } } QString fileName = m_FileSystemModel->fileName(m_FileSelection.at(0)); if (QMessageBox::question( this, tr("Confirm"), tr("Are you sure you want to delete \"%1\"?").arg(fileName), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) { return; } } else { if (QMessageBox::question(this, tr("Confirm"), tr("Are you sure you want to delete the selected files?"), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) { return; } } foreach (QModelIndex index, m_FileSelection) { for (auto modDir : m_Organizer.managedGame()->getModMappings().keys()) { if (root.absoluteFilePath(modDir).compare(m_FileSystemModel->filePath(index), Qt::CaseInsensitive) == 0) { return; } } deleteFile(index); } } void OverwriteInfoDialog::renameTriggered() { auto root = m_FileSystemModel->rootDirectory(); QModelIndex selection = m_FileSelection.at(0); QModelIndex index = selection.sibling(selection.row(), 0); if (!index.isValid() || m_FileSystemModel->isReadOnly()) { return; } for (auto modDir : m_Organizer.managedGame()->getModMappings().keys()) { if (root.absoluteFilePath(modDir).compare(m_FileSystemModel->filePath(selection), Qt::CaseInsensitive) == 0) { return; } } ui->filesView->edit(index); } void OverwriteInfoDialog::openFile(const QModelIndex& index) { shell::Open(m_FileSystemModel->filePath(index)); } void OverwriteInfoDialog::openTriggered() { foreach (QModelIndex idx, m_FileSelection) { openFile(idx); } } void OverwriteInfoDialog::createDirectoryTriggered() { QModelIndex selection = m_FileSelection.at(0); QModelIndex index = m_FileSystemModel->isDir(selection) ? selection : selection.parent(); index = index.sibling(index.row(), 0); QString name = tr("New Folder"); QString path = m_FileSystemModel->filePath(index).append("/"); QModelIndex existingIndex = m_FileSystemModel->index(path + name); int suffix = 1; while (existingIndex.isValid()) { name = tr("New Folder") + QString::number(suffix++); existingIndex = m_FileSystemModel->index(path + name); } QModelIndex newIndex = m_FileSystemModel->mkdir(index, name); if (!newIndex.isValid()) { reportError(tr("Failed to create \"%1\"").arg(name)); return; } ui->filesView->setCurrentIndex(newIndex); ui->filesView->edit(newIndex); } void OverwriteInfoDialog::on_explorerButton_clicked() { shell::Explore(m_ModInfo->absolutePath()); } void OverwriteInfoDialog::on_filesView_customContextMenuRequested(const QPoint& pos) { QItemSelectionModel* selectionModel = ui->filesView->selectionModel(); m_FileSelection = selectionModel->selectedRows(0); QMenu menu(ui->filesView); menu.addAction(m_NewFolderAction); bool hasFiles = false; foreach (QModelIndex idx, m_FileSelection) { if (m_FileSystemModel->fileInfo(idx).isFile()) { hasFiles = true; break; } } if (selectionModel->hasSelection()) { if (hasFiles) { menu.addAction(m_OpenAction); } menu.addAction(m_RenameAction); menu.addAction(m_DeleteAction); } else { m_FileSelection.clear(); m_FileSelection.append(m_FileSystemModel->index(m_FileSystemModel->rootPath(), 0)); } menu.exec(ui->filesView->viewport()->mapToGlobal(pos)); }