diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2019-05-19 07:21:41 -0400 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2019-05-19 07:21:41 -0400 |
| commit | b0c5cf146c2d8eeb1e6dc945b069ed16b05154f8 (patch) | |
| tree | d36dc6f1f5cda1f9ae405b483063e410f5717538 /src/modinfodialog.cpp | |
| parent | 0232435e0a2fed46c864cf241fb2c42d9682bfed (diff) | |
added new FileRenamer class to handle user confirmations when hiding/unhiding files
conflict tree hooked up
filetree shows the new dialogs, but doesn't handle buttons correctly yet
Diffstat (limited to 'src/modinfodialog.cpp')
| -rw-r--r-- | src/modinfodialog.cpp | 318 |
1 files changed, 258 insertions, 60 deletions
diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index 9f35fc59..cbfa02fd 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -74,6 +74,193 @@ static bool operator<(const ModFileListWidget &LHS, const ModFileListWidget &RHS } +FileRenamer::FileRenamer(QWidget* parent, QFlags<RenameFlags> flags) + : m_parent(parent), m_flags(flags) +{ + // sanity check for flags + if ((m_flags & (HIDE|UNHIDE)) == 0) { + qCritical("renameFile() missing hide flag"); + // doesn't really matter, it's just for text + m_flags = HIDE; + } +} + +FileRenamer::RenameResults FileRenamer::rename(const QString& oldName, const QString& newName) +{ + qDebug().nospace() << "renaming " << oldName << " to " << newName; + + if (QFileInfo(newName).exists()) { + qDebug().nospace() << newName << " already exists"; + + // target file already exists, confirm replacement + auto answer = confirmReplace(); + + switch (answer) { + case DECISION_SKIP: { + // user wants to skip this file + qDebug().nospace() << "skipping " << oldName; + return RESULT_SKIP; + } + + case DECISION_REPLACE: { + qDebug().nospace() << "removing " << newName; + // user wants to replace the file, so remove it + if (!QFile(newName).remove()) { + qWarning().nospace() << "failed to remove " << newName; + // removal failed, warn the user and allow canceling + if (!removeFailed(newName)) { + qDebug().nospace() << "canceling " << oldName; + // user wants to cancel + return RESULT_CANCEL; + } + + // ignore this file and continue on + qDebug().nospace() << "skipping " << oldName; + return RESULT_SKIP; + } + + break; + } + + case DECISION_CANCEL: // fall-through + default: { + // user wants to stop + qDebug().nospace() << "canceling"; + return RESULT_CANCEL; + } + } + } + + // target either didn't exist or was removed correctly + + if (!QFile::rename(oldName, newName)) { + qWarning().nospace() << "failed to rename " << oldName << " to " << newName; + + // renaming failed, warn the user and allow canceling + if (!renameFailed(oldName, newName)) { + // user wants to cancel + qDebug().nospace() << "canceling"; + return RESULT_CANCEL; + } + + // ignore this file and continue on + qDebug().nospace() << "skipping " << oldName; + return RESULT_SKIP; + } + + // everything worked + qDebug().nospace() << "successfully renamed " << oldName << " to " << newName; + return RESULT_OK; +} + +FileRenamer::RenameDecision FileRenamer::confirmReplace() +{ + if (m_flags & REPLACE_ALL) { + // user wants to silently replace all + qDebug().nospace() << "user has selected replace all"; + return DECISION_REPLACE; + } + else if (m_flags & REPLACE_NONE) { + // user wants to silently skip all + qDebug().nospace() << "user has selected replace none"; + return DECISION_SKIP; + } + + QString text; + + if (m_flags & HIDE) { + text = QObject::tr("There already is a hidden version of this file. Replace it?"); + } + else if (m_flags & UNHIDE) { + text = QObject::tr("There already is a visible version of this file. Replace it?"); + } + + auto buttons = QMessageBox::Yes | QMessageBox::No; + if (m_flags & MULTIPLE) { + // only show these buttons when there are multiple files to replace + buttons |= QMessageBox::YesToAll | QMessageBox::NoToAll | QMessageBox::Cancel; + } + + const auto answer = QMessageBox::question( + m_parent, QObject::tr("Replace file?"), text, buttons); + + switch (answer) { + case QMessageBox::Yes: + qDebug().nospace() << "user wants to replace"; + return DECISION_REPLACE; + + case QMessageBox::No: + qDebug().nospace() << "user wants to skip"; + return DECISION_SKIP; + + case QMessageBox::YesToAll: + qDebug().nospace() << "user wants to replace all"; + // remember the answer + m_flags |= REPLACE_ALL; + return DECISION_REPLACE; + + case QMessageBox::NoToAll: + qDebug().nospace() << "user wants to replace none"; + // remember the answer + m_flags |= REPLACE_NONE; + return DECISION_SKIP; + + case QMessageBox::Cancel: // fall-through + default: + qDebug().nospace() << "user wants to cancel"; + return DECISION_CANCEL; + } +} + +bool FileRenamer::removeFailed(const QString& name) +{ + QMessageBox::StandardButtons buttons = QMessageBox::Ok; + if (m_flags & MULTIPLE) { + // only show cancel for multiple files + buttons |= QMessageBox::Cancel; + } + + const auto answer = QMessageBox::critical( + m_parent, QObject::tr("File operation failed"), + QObject::tr("Failed to remove \"%1\". Maybe you lack the required file permissions?").arg(name), + buttons); + + if (answer == QMessageBox::Cancel) { + // user wants to stop + qDebug().nospace() << "user wants to cancel"; + return false; + } + + // skip this one and continue + qDebug().nospace() << "user wants to skip"; + return true; +} + +bool FileRenamer::renameFailed(const QString& oldName, const QString& newName) +{ + QMessageBox::StandardButtons buttons = QMessageBox::Ok; + if (m_flags & MULTIPLE) { + // only show cancel for multiple files + buttons |= QMessageBox::Cancel; + } + + const auto answer = QMessageBox::critical( + m_parent, QObject::tr("File operation failed"), + QObject::tr("failed to rename %1 to %2").arg(oldName).arg(QDir::toNativeSeparators(newName)), + buttons); + + if (answer == QMessageBox::Cancel) { + // user wants to stop + qDebug().nospace() << "user wants to cancel"; + return false; + } + + // skip this one and continue + qDebug().nospace() << "user wants to skip"; + return true; +} + + ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directory, bool unmanaged, OrganizerCore *organizerCore, PluginContainer *pluginContainer, QWidget *parent) : TutorableDialog("ModInfoDialog", parent), ui(new Ui::ModInfoDialog), m_ModInfo(modInfo), m_ThumbnailMapper(this), m_RequestStarted(false), @@ -1026,11 +1213,14 @@ void ModInfoDialog::renameTriggered() void ModInfoDialog::hideTriggered() { + QFlags<FileRenamer::RenameFlags> flags = FileRenamer::HIDE; + FileRenamer renamer(this, flags); + for (QModelIndexList::const_iterator iter = m_FileSelection.constBegin(); iter != m_FileSelection.constEnd(); ++iter) { QString path = m_FileSystemModel->filePath(*iter); if (!path.endsWith(ModInfo::s_HiddenExt)) { - hideFile(path); + hideFile(renamer, path); } } } @@ -1038,11 +1228,14 @@ void ModInfoDialog::hideTriggered() void ModInfoDialog::unhideTriggered() { + QFlags<FileRenamer::RenameFlags> flags = FileRenamer::UNHIDE; + FileRenamer renamer(this, flags); + for (QModelIndexList::const_iterator iter = m_FileSelection.constBegin(); iter != m_FileSelection.constEnd(); ++iter) { QString path = m_FileSystemModel->filePath(*iter); if (path.endsWith(ModInfo::s_HiddenExt)) { - unhideFile(path); + unhideFile(renamer, path); } } } @@ -1184,90 +1377,95 @@ void ModInfoDialog::on_overwriteTree_itemDoubleClicked(QTreeWidgetItem *item, in emit modOpen(item->data(1, Qt::UserRole).toString(), TAB_CONFLICTS); } +FileRenamer::RenameResults ModInfoDialog::hideFile(FileRenamer& renamer, const QString &oldName) +{ + const QString newName = oldName + ModInfo::s_HiddenExt; + return renamer.rename(oldName, newName); +} -bool ModInfoDialog::hideFile(const QString &oldName) +FileRenamer::RenameResults ModInfoDialog::unhideFile(FileRenamer& renamer, const QString &oldName) { - QString newName = oldName + ModInfo::s_HiddenExt; + QString newName = oldName.left(oldName.length() - ModInfo::s_HiddenExt.length()); + return renamer.rename(oldName, newName); +} - if (QFileInfo(newName).exists()) { - if (QMessageBox::question(this, tr("Replace file?"), tr("There already is a hidden version of this file. Replace it?"), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - if (!QFile(newName).remove()) { - QMessageBox::critical(this, tr("File operation failed"), tr("Failed to remove \"%1\". Maybe you lack the required file permissions?").arg(newName)); - return false; - } - } else { - return false; - } - } +void ModInfoDialog::changeConflictFiles(bool hide) +{ + bool changed = false; + bool stop = false; - if (QFile::rename(oldName, newName)) { - return true; - } else { - reportError(tr("failed to rename %1 to %2").arg(oldName).arg(QDir::toNativeSeparators(newName))); - return false; + const auto items = ui->overwriteTree->selectedItems(); + + qDebug().nospace() + << (hide ? "hiding" : "unhiding") << " " + << items.size() << " conflict files"; + + QFlags<FileRenamer::RenameFlags> flags = (hide ? FileRenamer::HIDE : FileRenamer::UNHIDE); + if (items.size() > 1) { + flags |= FileRenamer::MULTIPLE; } -} + FileRenamer renamer(this, flags); -bool ModInfoDialog::unhideFile(const QString &oldName) -{ - QString newName = oldName.left(oldName.length() - ModInfo::s_HiddenExt.length()); - if (QFileInfo(newName).exists()) { - if (QMessageBox::question(this, tr("Replace file?"), tr("There already is a visible version of this file. Replace it?"), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - if (!QFile(newName).remove()) { - QMessageBox::critical(this, tr("File operation failed"), tr("Failed to remove \"%1\". Maybe you lack the required file permissions?").arg(newName)); - return false; + for (const auto* item : items) { + if (stop) { + break; + } + + auto result = FileRenamer::RESULT_CANCEL; + + if (hide) { + if (!canHide(item)) { + qDebug().nospace() << "cannot hide " << item->text(0) << ", skipping"; + continue; } + result = hideFile(renamer, item->data(0, Qt::UserRole).toString()); + } else { - return false; + if (!canUnhide(item)) { + qDebug().nospace() << "cannot unhide " << item->text(0) << ", skipping"; + continue; + } + result = unhideFile(renamer, item->data(0, Qt::UserRole).toString()); } - } - if (QFile::rename(oldName, newName)) { - return true; - } else { - reportError(tr("failed to rename %1 to %2").arg(QDir::toNativeSeparators(oldName)).arg(QDir::toNativeSeparators(newName))); - return false; - } -} + switch (result) { + case FileRenamer::RESULT_OK: { + // will trigger a refresh at the end + changed = true; + break; + } -void ModInfoDialog::hideConflictFiles() -{ - bool changed = false; + case FileRenamer::RESULT_SKIP: { + // nop + break; + } - for (const auto* item : ui->overwriteTree->selectedItems()) { - if (canHide(item)) { - if (hideFile(item->data(0, Qt::UserRole).toString())) { - changed = true; + case FileRenamer::RESULT_CANCEL: { + // stop right now, but make sure to refresh if needed + stop = true; + break; } } } + qDebug().nospace() << (hide ? "hiding" : "unhiding") << " conflict files done"; + if (changed) { + qDebug().nospace() << "triggering refresh"; emit originModified(m_Origin->getID()); refreshLists(); } } +void ModInfoDialog::hideConflictFiles() +{ + changeConflictFiles(true); +} void ModInfoDialog::unhideConflictFiles() { - bool changed = false; - - for (const auto* item : ui->overwriteTree->selectedItems()) { - if (canUnhide(item)) { - if (unhideFile(item->data(0, Qt::UserRole).toString())) { - changed = true; - } - } - } - - if (changed) { - emit originModified(m_Origin->getID()); - refreshLists(); - } + changeConflictFiles(false); } int ModInfoDialog::getBinaryExecuteInfo(const QFileInfo &targetInfo, QFileInfo &binaryInfo, QString &arguments) |
