diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2019-06-15 17:58:23 -0400 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2019-07-02 10:10:16 -0400 |
| commit | 59e0c4aa34fec9048d064705863c3269aacd86b5 (patch) | |
| tree | 8e1c5859e68f2fd12ac4d2b6c7178feec031ae21 /src | |
| parent | 67bc0d83277b36397766d97218d5ed9b4e25640a (diff) | |
moved filerenamer to its own .cpp/.h pair
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | src/filerenamer.cpp | 189 | ||||
| -rw-r--r-- | src/filerenamer.h | 140 | ||||
| -rw-r--r-- | src/modinfodialog.cpp | 187 | ||||
| -rw-r--r-- | src/modinfodialog.h | 135 |
5 files changed, 333 insertions, 321 deletions
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 <QMessageBox> +#include <QFileInfo> + +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(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 <QWidget> + +/** +* 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<RenameFlags> 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<RenameFlags> 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<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(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 <http://www.gnu.org/licenses/>. #include "plugincontainer.h"
#include "organizercore.h"
#include "filterwidget.h"
+#include "filerenamer.h"
#include <QDialog>
#include <QSignalMapper>
@@ -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<RenameFlags> 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<RenameFlags> 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.
**/
|
