From 59e0c4aa34fec9048d064705863c3269aacd86b5 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sat, 15 Jun 2019 17:58:23 -0400 Subject: moved filerenamer to its own .cpp/.h pair --- src/CMakeLists.txt | 3 + src/filerenamer.cpp | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/filerenamer.h | 140 +++++++++++++++++++++++++++++++++++++ src/modinfodialog.cpp | 187 ------------------------------------------------- src/modinfodialog.h | 135 +----------------------------------- 5 files changed, 333 insertions(+), 321 deletions(-) create mode 100644 src/filerenamer.cpp create mode 100644 src/filerenamer.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 645a5a73..f654f9b4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -118,6 +118,7 @@ SET(organizer_SRCS filterwidget.cpp statusbar.cpp apiuseraccount.cpp + filerenamer.cpp shared/windows_error.cpp shared/error_report.cpp @@ -217,6 +218,7 @@ SET(organizer_HDRS filterwidget.h statusbar.h apiuseraccount.h + filerenamer.h shared/windows_error.h shared/error_report.h @@ -402,6 +404,7 @@ set(utilities set(widgets descriptionpage genericicondelegate + filerenamer filterwidget icondelegate lcdnumber diff --git a/src/filerenamer.cpp b/src/filerenamer.cpp new file mode 100644 index 00000000..c5c6782b --- /dev/null +++ b/src/filerenamer.cpp @@ -0,0 +1,189 @@ +#include "filerenamer.h" +#include +#include + +FileRenamer::FileRenamer(QWidget* parent, QFlags 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(newName); + + 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(const QString& newName) +{ + 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("The hidden file \"%1\" already exists. Replace it?").arg(newName); + } + else if (m_flags & UNHIDE) { + text = QObject::tr("The visible file \"%1\" already exists. Replace it?").arg(newName); + } + + 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; +} diff --git a/src/filerenamer.h b/src/filerenamer.h new file mode 100644 index 00000000..cd57244c --- /dev/null +++ b/src/filerenamer.h @@ -0,0 +1,140 @@ +#ifndef FILERENAMER_H +#define FILERENAMER_H + +#include + +/** +* Renames individual files and handles dialog boxes to confirm replacements and +* failures with the user +**/ +class FileRenamer +{ +public: + /** + * controls appearance and replacement behaviour; if RENAME_REPLACE_ALL and + * RENAME_REPLACE_NONE are not provided, the user will have the option to + * choose on the first replacement + **/ + enum RenameFlags + { + /** + * this renamer will be used on multiple files, so display additional + * buttons to replace all and for canceling + **/ + MULTIPLE = 0x01, + + /** + * customizes some of the text shown on dialog to mention that files are + * being hidden + **/ + HIDE = 0x02, + + /** + * customizes some of the text shown on dialog to mention that files are + * being unhidden + **/ + UNHIDE = 0x04, + + /** + * silently replaces all existing files + **/ + REPLACE_ALL = 0x08, + + /** + * silently skips all existing files + **/ + REPLACE_NONE = 0x10, + }; + + + /** result of a single rename + * + **/ + enum RenameResults + { + /** + * the user skipped this file + */ + RESULT_SKIP, + + /** + * the file was successfully renamed + */ + RESULT_OK, + + /** + * the user wants to cancel + */ + RESULT_CANCEL + }; + + + /** + * @param parent Parent widget for dialog boxes + **/ + FileRenamer(QWidget* parent, QFlags flags); + + /** + * renames the given file + * @param oldName current filename + * @param newName new filename + * @return whether the file was renamed, skipped or the user wants to cancel + **/ + RenameResults rename(const QString& oldName, const QString& newName); + +private: + /** + *user's decision when replacing + **/ + enum RenameDecision + { + /** + * replace the file + **/ + DECISION_REPLACE, + + /** + * skip the file + **/ + DECISION_SKIP, + + /** + * cancel the whole thing + **/ + DECISION_CANCEL + }; + + /** + * parent widget for dialog boxes + **/ + QWidget* m_parent; + + /** + * flags + **/ + QFlags m_flags; + + /** + * asks the user to replace an existing file, may return early if the user + * has already selected to replace all/none + * @return whether to replace, skip or cancel + **/ + RenameDecision confirmReplace(const QString& newName); + + /** + * removal of a file failed, ask the user to continue or cancel + * @param name The name of the file that failed to be removed + * @return true to continue, false to stop + **/ + bool removeFailed(const QString& name); + + /** + * renaming a file failed, ask the user to continue or cancel + * @param oldName current filename + * @param newName new filename + * @return true to continue, false to stop + **/ + bool renameFailed(const QString& oldName, const QString& newName); +}; + +#endif // FILERENAMER_H diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index 44934544..f553a7be 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -78,193 +78,6 @@ static bool operator<(const ModFileListWidget &LHS, const ModFileListWidget &RHS const int max_scan_for_context_menu = 50; -FileRenamer::FileRenamer(QWidget* parent, QFlags 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(newName); - - 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(const QString& newName) -{ - 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("The hidden file \"%1\" already exists. Replace it?").arg(newName); - } - else if (m_flags & UNHIDE) { - text = QObject::tr("The visible file \"%1\" already exists. Replace it?").arg(newName); - } - - 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; -} - - ExpanderWidget::ExpanderWidget() : m_button(nullptr), m_content(nullptr), opened_(false) { diff --git a/src/modinfodialog.h b/src/modinfodialog.h index c4f65d8a..b3ce3d07 100644 --- a/src/modinfodialog.h +++ b/src/modinfodialog.h @@ -26,6 +26,7 @@ along with Mod Organizer. If not, see . #include "plugincontainer.h" #include "organizercore.h" #include "filterwidget.h" +#include "filerenamer.h" #include #include @@ -49,140 +50,6 @@ class QFileSystemModel; class QTreeView; class CategoryFactory; -/** -* Renames individual files and handles dialog boxes to confirm replacements and -* failures with the user -**/ -class FileRenamer -{ -public: - /** - * controls appearance and replacement behaviour; if RENAME_REPLACE_ALL and - * RENAME_REPLACE_NONE are not provided, the user will have the option to - * choose on the first replacement - **/ - enum RenameFlags - { - /** - * this renamer will be used on multiple files, so display additional - * buttons to replace all and for canceling - **/ - MULTIPLE = 0x01, - - /** - * customizes some of the text shown on dialog to mention that files are - * being hidden - **/ - HIDE = 0x02, - - /** - * customizes some of the text shown on dialog to mention that files are - * being unhidden - **/ - UNHIDE = 0x04, - - /** - * silently replaces all existing files - **/ - REPLACE_ALL = 0x08, - - /** - * silently skips all existing files - **/ - REPLACE_NONE = 0x10, - }; - - - /** result of a single rename - * - **/ - enum RenameResults - { - /** - * the user skipped this file - */ - RESULT_SKIP, - - /** - * the file was successfully renamed - */ - RESULT_OK, - - /** - * the user wants to cancel - */ - RESULT_CANCEL - }; - - - /** - * @param parent Parent widget for dialog boxes - **/ - FileRenamer(QWidget* parent, QFlags flags); - - /** - * renames the given file - * @param oldName current filename - * @param newName new filename - * @return whether the file was renamed, skipped or the user wants to cancel - **/ - RenameResults rename(const QString& oldName, const QString& newName); - -private: - /** - *user's decision when replacing - **/ - enum RenameDecision - { - /** - * replace the file - **/ - DECISION_REPLACE, - - /** - * skip the file - **/ - DECISION_SKIP, - - /** - * cancel the whole thing - **/ - DECISION_CANCEL - }; - - /** - * parent widget for dialog boxes - **/ - QWidget* m_parent; - - /** - * flags - **/ - QFlags m_flags; - - /** - * asks the user to replace an existing file, may return early if the user - * has already selected to replace all/none - * @return whether to replace, skip or cancel - **/ - RenameDecision confirmReplace(const QString& newName); - - /** - * removal of a file failed, ask the user to continue or cancel - * @param name The name of the file that failed to be removed - * @return true to continue, false to stop - **/ - bool removeFailed(const QString& name); - - /** - * renaming a file failed, ask the user to continue or cancel - * @param oldName current filename - * @param newName new filename - * @return true to continue, false to stop - **/ - bool renameFailed(const QString& oldName, const QString& newName); -}; - /* Takes a QToolButton and a widget and creates an expandable widget. **/ -- cgit v1.3.1