#include "filerenamer.h"
#include <QFileInfo>
#include <QMessageBox>
#include <log.h>
#include <utility.h>
using namespace MOBase;
FileRenamer::FileRenamer(QWidget* parent, QFlags<RenameFlags> flags)
: m_parent(parent), m_flags(flags)
{
if ((m_flags & (HIDE | UNHIDE)) == 0) {
log::error("renameFile() missing hide flag");
m_flags = HIDE;
}
}
FileRenamer::RenameResults FileRenamer::rename(const QString& oldName,
const QString& newName)
{
log::debug("renaming {} to {}", oldName, newName);
if (QFileInfo(newName).exists()) {
log::debug("{} already exists", newName);
auto answer = confirmReplace(newName);
switch (answer) {
case DECISION_SKIP: {
log::debug("skipping {}", oldName);
return RESULT_SKIP;
}
case DECISION_REPLACE: {
log::debug("removing {}", newName);
const auto r = shell::Delete(QFileInfo(newName));
if (!r.success()) {
log::error("failed to remove '{}': {}", newName, r.toString());
if (!removeFailed(newName, r)) {
log::debug("canceling {}", oldName);
return RESULT_CANCEL;
}
log::debug("skipping {}", oldName);
return RESULT_SKIP;
}
break;
}
case DECISION_CANCEL:
default: {
log::debug("canceling");
return RESULT_CANCEL;
}
}
}
const auto r = shell::Rename(QFileInfo(oldName), QFileInfo(newName));
if (!r.success()) {
log::error("failed to rename '{}' to '{}': {}", oldName, newName, r.toString());
if (!renameFailed(oldName, newName, r)) {
log::debug("canceling");
return RESULT_CANCEL;
}
log::debug("skipping {}", oldName);
return RESULT_SKIP;
}
log::debug("successfully renamed {} to {}", oldName, newName);
return RESULT_OK;
}
FileRenamer::RenameDecision FileRenamer::confirmReplace(const QString& newName)
{
if (m_flags & REPLACE_ALL) {
log::debug("user has selected replace all");
return DECISION_REPLACE;
} else if (m_flags & REPLACE_NONE) {
log::debug("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) {
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:
log::debug("user wants to replace");
return DECISION_REPLACE;
case QMessageBox::No:
log::debug("user wants to skip");
return DECISION_SKIP;
case QMessageBox::YesToAll:
log::debug("user wants to replace all");
m_flags |= REPLACE_ALL;
return DECISION_REPLACE;
case QMessageBox::NoToAll:
log::debug("user wants to replace none");
m_flags |= REPLACE_NONE;
return DECISION_SKIP;
case QMessageBox::Cancel:
default:
log::debug("user wants to cancel");
return DECISION_CANCEL;
}
}
bool FileRenamer::removeFailed(const QString& name, const shell::Result& r)
{
QMessageBox::StandardButtons buttons = QMessageBox::Ok;
if (m_flags & MULTIPLE) {
buttons |= QMessageBox::Cancel;
}
const auto answer = QMessageBox::critical(
m_parent, QObject::tr("File operation failed"),
QObject::tr("Failed to remove \"%1\": %2").arg(name).arg(r.toString()), buttons);
if (answer == QMessageBox::Cancel) {
log::debug("user wants to cancel");
return false;
}
log::debug("user wants to skip");
return true;
}
bool FileRenamer::renameFailed(const QString& oldName, const QString& newName,
const shell::Result& r)
{
QMessageBox::StandardButtons buttons = QMessageBox::Ok;
if (m_flags & MULTIPLE) {
buttons |= QMessageBox::Cancel;
}
const auto answer =
QMessageBox::critical(m_parent, QObject::tr("File operation failed"),
QObject::tr("Failed to rename file: %1.\r\n\r\n"
"Source:\r\n\"%2\"\r\n\r\n"
"Destination:\r\n\"%3\"")
.arg(r.toString())
.arg(QDir::toNativeSeparators(oldName))
.arg(QDir::toNativeSeparators(newName)),
buttons);
if (answer == QMessageBox::Cancel) {
log::debug("user wants to cancel");
return false;
}
log::debug("user wants to skip");
return true;
}