Browse Source

Fix unable to rename folder on Windows

The bug occurs when the new path and old path only differ by letter case.
adaptive-webui-19844
Chocobo1 6 years ago
parent
commit
eabcae1018
No known key found for this signature in database
GPG Key ID: 210D9C873253A68C
  1. 151
      src/gui/torrentcontenttreeview.cpp

151
src/gui/torrentcontenttreeview.cpp

@ -100,9 +100,10 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentHandle *torre
auto model = dynamic_cast<TorrentContentFilterModel *>(TorrentContentTreeView::model()); auto model = dynamic_cast<TorrentContentFilterModel *>(TorrentContentTreeView::model());
if (!model) return; if (!model) return;
const bool isFile = (model->itemType(modelIndex) == TorrentContentModelItem::FileType);
// Ask for new name // Ask for new name
bool ok = false; bool ok = false;
const bool isFile = (model->itemType(modelIndex) == TorrentContentModelItem::FileType);
QString newName = AutoExpandableDialog::getText(this, tr("Renaming"), tr("New name:"), QLineEdit::Normal QString newName = AutoExpandableDialog::getText(this, tr("Renaming"), tr("New name:"), QLineEdit::Normal
, modelIndex.data().toString(), &ok, isFile).trimmed(); , modelIndex.data().toString(), &ok, isFile).trimmed();
if (!ok) return; if (!ok) return;
@ -150,62 +151,69 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentHandle *torre
} }
else { else {
// renaming a folder // renaming a folder
QStringList pathItems;
pathItems << modelIndex.data().toString(); const QString oldName = modelIndex.data().toString();
QModelIndex parent = model->parent(modelIndex); if (newName == oldName)
while (parent.isValid()) { return; // Name did not change
pathItems.prepend(parent.data().toString());
parent = model->parent(parent); QString parentPath;
} for (QModelIndex idx = model->parent(modelIndex); idx.isValid(); idx = model->parent(idx))
const QString oldPath = pathItems.join('/'); parentPath.prepend(idx.data().toString() + '/');
pathItems.removeLast();
pathItems << newName; const QString oldPath {parentPath + oldName + '/'};
QString newPath = pathItems.join('/'); const QString newPath {parentPath + newName + '/'};
if (Utils::Fs::sameFileNames(oldPath, newPath)) {
qDebug("Name did not change");
return;
}
if (!newPath.endsWith('/')) newPath += '/';
// Check for overwriting // Check for overwriting
for (int i = 0; i < torrent->filesCount(); ++i) { #if defined(Q_OS_WIN)
const QString currentName = torrent->filePath(i); const Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive;
#if defined(Q_OS_UNIX) || defined(Q_WS_QWS)
if (currentName.startsWith(newPath, Qt::CaseSensitive)) {
#else #else
if (currentName.startsWith(newPath, Qt::CaseInsensitive)) { const Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive;
#endif #endif
QMessageBox::warning(this, tr("The folder could not be renamed"),
tr("This name is already in use in this folder. Please use a different name."), for (int i = 0; i < torrent->filesCount(); ++i) {
QMessageBox::Ok); const QString currentPath = torrent->filePath(i);
if (currentPath.startsWith(oldPath))
continue;
if (currentPath.startsWith(newPath, caseSensitivity)) {
RaisedMessageBox::warning(this, tr("The folder could not be renamed"),
tr("This name is already in use. Please use a different name."),
QMessageBox::Ok);
return; return;
} }
} }
bool forceRecheck = false;
// Replace path in all files // Replace path in all files
bool needForceRecheck = false;
for (int i = 0; i < torrent->filesCount(); ++i) { for (int i = 0; i < torrent->filesCount(); ++i) {
const QString currentName = torrent->filePath(i); const QString currentPath = torrent->filePath(i);
if (currentName.startsWith(oldPath)) {
QString newName = currentName; if (currentPath.startsWith(oldPath)) {
newName.replace(0, oldPath.length(), newPath); const QString path {newPath + currentPath.mid(oldPath.length())};
if (!forceRecheck && QDir(torrent->savePath(true)).exists(newName))
forceRecheck = true; if (!needForceRecheck && QFile::exists(path))
newName = Utils::Fs::expandPath(newName); needForceRecheck = true;
qDebug("Rename %s to %s", qUtf8Printable(currentName), qUtf8Printable(newName));
torrent->renameFile(i, newName); torrent->renameFile(i, path);
} }
} }
// Force recheck // Force recheck
if (forceRecheck) torrent->forceRecheck(); if (needForceRecheck)
// Rename folder in torrent files model too torrent->forceRecheck();
model->setData(modelIndex, newName);
// Remove old folder // Remove old folder
const QDir oldFolder(torrent->savePath(true) + '/' + oldPath); const QString oldFullPath = torrent->savePath(true) + oldPath;
int timeout = 10; int timeout = 10;
while (!QDir().rmpath(oldFolder.absolutePath()) && (timeout > 0)) { while (!QDir().rmpath(oldFullPath) && (timeout > 0)) {
// FIXME: We should not sleep here (freezes the UI for 1 second) // FIXME: We should not sleep here (freezes the UI for 1 second)
QThread::msleep(100); QThread::msleep(100);
--timeout; --timeout;
} }
model->setData(modelIndex, newName);
} }
} }
@ -220,9 +228,10 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentInfo &torrent
auto model = dynamic_cast<TorrentContentFilterModel *>(TorrentContentTreeView::model()); auto model = dynamic_cast<TorrentContentFilterModel *>(TorrentContentTreeView::model());
if (!model) return; if (!model) return;
const bool isFile = (model->itemType(modelIndex) == TorrentContentModelItem::FileType);
// Ask for new name // Ask for new name
bool ok = false; bool ok = false;
const bool isFile = (model->itemType(modelIndex) == TorrentContentModelItem::FileType);
QString newName = AutoExpandableDialog::getText(this, tr("Renaming"), tr("New name:"), QLineEdit::Normal QString newName = AutoExpandableDialog::getText(this, tr("Renaming"), tr("New name:"), QLineEdit::Normal
, modelIndex.data().toString(), &ok, isFile).trimmed(); , modelIndex.data().toString(), &ok, isFile).trimmed();
if (!ok) return; if (!ok) return;
@ -266,49 +275,49 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentInfo &torrent
} }
else { else {
// renaming a folder // renaming a folder
QStringList pathItems;
pathItems << modelIndex.data().toString(); const QString oldName = modelIndex.data().toString();
QModelIndex parent = model->parent(modelIndex); if (newName == oldName)
while (parent.isValid()) { return; // Name did not change
pathItems.prepend(parent.data().toString());
parent = model->parent(parent); QString parentPath;
} for (QModelIndex idx = model->parent(modelIndex); idx.isValid(); idx = model->parent(idx))
const QString oldPath = pathItems.join('/'); parentPath.prepend(idx.data().toString() + '/');
pathItems.removeLast();
pathItems << newName; const QString oldPath {parentPath + oldName + '/'};
QString newPath = pathItems.join('/'); const QString newPath {parentPath + newName + '/'};
if (Utils::Fs::sameFileNames(oldPath, newPath)) {
qDebug("Name did not change");
return;
}
if (!newPath.endsWith('/')) newPath += '/';
// Check for overwriting // Check for overwriting
for (int i = 0; i < torrent.filesCount(); ++i) { #if defined(Q_OS_WIN)
const QString currentName = torrent.filePath(i); const Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive;
#if defined(Q_OS_UNIX) || defined(Q_WS_QWS)
if (currentName.startsWith(newPath, Qt::CaseSensitive)) {
#else #else
if (currentName.startsWith(newPath, Qt::CaseInsensitive)) { const Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive;
#endif #endif
for (int i = 0; i < torrent.filesCount(); ++i) {
const QString currentPath = torrent.filePath(i);
if (currentPath.startsWith(oldPath))
continue;
if (currentPath.startsWith(newPath, caseSensitivity)) {
RaisedMessageBox::warning(this, tr("The folder could not be renamed"), RaisedMessageBox::warning(this, tr("The folder could not be renamed"),
tr("This name is already in use in this folder. Please use a different name."), tr("This name is already in use. Please use a different name."),
QMessageBox::Ok); QMessageBox::Ok);
return; return;
} }
} }
// Replace path in all files // Replace path in all files
for (int i = 0; i < torrent.filesCount(); ++i) { for (int i = 0; i < torrent.filesCount(); ++i) {
const QString currentName = torrent.filePath(i); const QString currentPath = torrent.filePath(i);
if (currentName.startsWith(oldPath)) {
QString newName = currentName; if (currentPath.startsWith(oldPath)) {
newName.replace(0, oldPath.length(), newPath); const QString path {newPath + currentPath.mid(oldPath.length())};
newName = Utils::Fs::expandPath(newName); torrent.renameFile(i, path);
qDebug("Rename %s to %s", qUtf8Printable(currentName), qUtf8Printable(newName));
torrent.renameFile(i, newName);
} }
} }
// Rename folder in torrent files model too
model->setData(modelIndex, newName); model->setData(modelIndex, newName);
} }
} }

Loading…
Cancel
Save