From c01aed8d9032c13225d6ced135add6895d0d8413 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Tue, 4 Jun 2019 00:14:57 +0800 Subject: [PATCH 01/11] Remove redundant disconnect() The dialog is going out-of-scope in these instance and the signal-slot connection will disconnect automatically. --- src/gui/addnewtorrentdialog.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index 759a17d1a..e3855cd25 100644 --- a/src/gui/addnewtorrentdialog.cpp +++ b/src/gui/addnewtorrentdialog.cpp @@ -615,9 +615,6 @@ void AddNewTorrentDialog::displayContentTreeMenu(const QPoint &) void AddNewTorrentDialog::accept() { - if (!m_hasMetadata) - disconnect(this, SLOT(updateMetadata(const BitTorrent::TorrentInfo&))); - // TODO: Check if destination actually exists m_torrentParams.skipChecking = m_ui->skipCheckingCheckBox->isChecked(); @@ -663,7 +660,6 @@ void AddNewTorrentDialog::accept() void AddNewTorrentDialog::reject() { if (!m_hasMetadata) { - disconnect(this, SLOT(updateMetadata(BitTorrent::TorrentInfo))); setMetadataProgressIndicator(false); BitTorrent::Session::instance()->cancelLoadMetadata(m_hash); } @@ -675,7 +671,8 @@ void AddNewTorrentDialog::updateMetadata(const BitTorrent::TorrentInfo &info) { if (info.hash() != m_hash) return; - disconnect(this, SLOT(updateMetadata(BitTorrent::TorrentInfo))); + disconnect(BitTorrent::Session::instance(), &BitTorrent::Session::metadataLoaded, this, &AddNewTorrentDialog::updateMetadata); + if (!info.isValid()) { RaisedMessageBox::critical(this, tr("I/O Error"), ("Invalid metadata.")); setMetadataProgressIndicator(false, tr("Invalid metadata")); From ec13d195f8e24fe4ef8a69b19a719423cb44a73d Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Wed, 5 Jun 2019 12:25:45 +0800 Subject: [PATCH 02/11] Fix unable to control add torrent dialogs when opened simultaneously --- src/gui/addnewtorrentdialog.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index e3855cd25..d942b633c 100644 --- a/src/gui/addnewtorrentdialog.cpp +++ b/src/gui/addnewtorrentdialog.cpp @@ -95,6 +95,7 @@ AddNewTorrentDialog::AddNewTorrentDialog(const BitTorrent::AddTorrentParams &inP // TODO: set dialog file properties using m_torrentParams.filePriorities m_ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); + m_ui->lblMetaLoading->setVisible(false); m_ui->progMetaLoading->setVisible(false); @@ -244,11 +245,7 @@ void AddNewTorrentDialog::show(QString source, const BitTorrent::AddTorrentParam ok = dlg->loadTorrent(source); if (ok) -#ifdef Q_OS_MAC - dlg->exec(); -#else - dlg->open(); -#endif + dlg->QDialog::show(); else delete dlg; } From 377f31085c8c5103644a30d124399973e277d31e Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Tue, 4 Jun 2019 14:00:42 +0800 Subject: [PATCH 03/11] Move renameSelectedFile(BitTorrent::TorrentHandle *) --- src/gui/properties/propertieswidget.cpp | 124 +--------------------- src/gui/properties/propertieswidget.h | 1 - src/gui/torrentcontenttreeview.cpp | 133 ++++++++++++++++++++++++ src/gui/torrentcontenttreeview.h | 7 ++ 4 files changed, 143 insertions(+), 122 deletions(-) diff --git a/src/gui/properties/propertieswidget.cpp b/src/gui/properties/propertieswidget.cpp index c0387a716..e3b4f1767 100644 --- a/src/gui/properties/propertieswidget.cpp +++ b/src/gui/properties/propertieswidget.cpp @@ -154,7 +154,8 @@ PropertiesWidget::PropertiesWidget(QWidget *parent, MainWindow *mainWindow, Tran connect(m_refreshTimer, &QTimer::timeout, this, &PropertiesWidget::loadDynamicData); m_refreshTimer->start(3000); // 3sec m_editHotkeyFile = new QShortcut(Qt::Key_F2, m_ui->filesList, nullptr, nullptr, Qt::WidgetShortcut); - connect(m_editHotkeyFile, &QShortcut::activated, this, &PropertiesWidget::renameSelectedFile); + connect(m_editHotkeyFile, &QShortcut::activated + , this, [this]() { m_ui->filesList->renameSelectedFile(m_torrent); }); m_editHotkeyWeb = new QShortcut(Qt::Key_F2, m_ui->listWebSeeds, nullptr, nullptr, Qt::WidgetShortcut); connect(m_editHotkeyWeb, &QShortcut::activated, this, &PropertiesWidget::editWebSeed); connect(m_ui->listWebSeeds, &QListWidget::doubleClicked, this, &PropertiesWidget::editWebSeed); @@ -619,7 +620,7 @@ void PropertiesWidget::displayFilesListMenu(const QPoint &) openFolder(index, true); } else if (act == actRename) { - renameSelectedFile(); + m_ui->filesList->renameSelectedFile(m_torrent); } else { BitTorrent::FilePriority prio = BitTorrent::FilePriority::Normal; @@ -671,125 +672,6 @@ void PropertiesWidget::displayWebSeedListMenu(const QPoint &) editWebSeed(); } -void PropertiesWidget::renameSelectedFile() -{ - if (!m_torrent) return; - - const QModelIndexList selectedIndexes = m_ui->filesList->selectionModel()->selectedRows(0); - if (selectedIndexes.size() != 1) return; - - const QModelIndex modelIndex = selectedIndexes.first(); - if (!modelIndex.isValid()) return; - - // Ask for new name - bool ok = false; - const bool isFile = (m_propListModel->itemType(modelIndex) == TorrentContentModelItem::FileType); - QString newName = AutoExpandableDialog::getText(this, tr("Renaming"), tr("New name:"), QLineEdit::Normal - , modelIndex.data().toString(), &ok, isFile).trimmed(); - if (!ok) return; - - if (newName.isEmpty() || !Utils::Fs::isValidFileSystemName(newName)) { - RaisedMessageBox::warning(this, tr("Rename error"), - tr("The name is empty or contains forbidden characters, please choose a different one."), - QMessageBox::Ok); - return; - } - - if (isFile) { - const int fileIndex = m_propListModel->getFileIndex(modelIndex); - - if (newName.endsWith(QB_EXT)) - newName.chop(QB_EXT.size()); - const QString oldFileName = m_torrent->fileName(fileIndex); - const QString oldFilePath = m_torrent->filePath(fileIndex); - - const bool useFilenameExt = BitTorrent::Session::instance()->isAppendExtensionEnabled() - && (m_torrent->filesProgress()[fileIndex] != 1); - const QString newFileName = newName + (useFilenameExt ? QB_EXT : QString()); - const QString newFilePath = oldFilePath.leftRef(oldFilePath.size() - oldFileName.size()) + newFileName; - - if (oldFileName == newFileName) { - qDebug("Name did not change: %s", qUtf8Printable(oldFileName)); - return; - } - - // check if that name is already used - for (int i = 0; i < m_torrent->filesCount(); ++i) { - if (i == fileIndex) continue; - if (Utils::Fs::sameFileNames(m_torrent->filePath(i), newFilePath)) { - RaisedMessageBox::warning(this, tr("Rename error"), - tr("This name is already in use in this folder. Please use a different name."), - QMessageBox::Ok); - return; - } - } - - qDebug("Renaming %s to %s", qUtf8Printable(oldFilePath), qUtf8Printable(newFilePath)); - m_torrent->renameFile(fileIndex, newFilePath); - - m_propListModel->setData(modelIndex, newName); - } - else { - // renaming a folder - QStringList pathItems; - pathItems << modelIndex.data().toString(); - QModelIndex parent = m_propListModel->parent(modelIndex); - while (parent.isValid()) { - pathItems.prepend(parent.data().toString()); - parent = m_propListModel->parent(parent); - } - const QString oldPath = pathItems.join('/'); - pathItems.removeLast(); - pathItems << newName; - QString newPath = pathItems.join('/'); - if (Utils::Fs::sameFileNames(oldPath, newPath)) { - qDebug("Name did not change"); - return; - } - if (!newPath.endsWith('/')) newPath += '/'; - // Check for overwriting - for (int i = 0; i < m_torrent->filesCount(); ++i) { - const QString currentName = m_torrent->filePath(i); -#if defined(Q_OS_UNIX) || defined(Q_WS_QWS) - if (currentName.startsWith(newPath, Qt::CaseSensitive)) { -#else - if (currentName.startsWith(newPath, Qt::CaseInsensitive)) { -#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."), - QMessageBox::Ok); - return; - } - } - bool forceRecheck = false; - // Replace path in all files - for (int i = 0; i < m_torrent->filesCount(); ++i) { - const QString currentName = m_torrent->filePath(i); - if (currentName.startsWith(oldPath)) { - QString newName = currentName; - newName.replace(0, oldPath.length(), newPath); - if (!forceRecheck && QDir(m_torrent->savePath(true)).exists(newName)) - forceRecheck = true; - newName = Utils::Fs::expandPath(newName); - qDebug("Rename %s to %s", qUtf8Printable(currentName), qUtf8Printable(newName)); - m_torrent->renameFile(i, newName); - } - } - // Force recheck - if (forceRecheck) m_torrent->forceRecheck(); - // Rename folder in torrent files model too - m_propListModel->setData(modelIndex, newName); - // Remove old folder - const QDir oldFolder(m_torrent->savePath(true) + '/' + oldPath); - int timeout = 10; - while (!QDir().rmpath(oldFolder.absolutePath()) && (timeout > 0)) { - // FIXME: We should not sleep here (freezes the UI for 1 second) - QThread::msleep(100); - --timeout; - } - } -} - void PropertiesWidget::openSelectedFile() { const QModelIndexList selectedIndexes = m_ui->filesList->selectionModel()->selectedRows(0); diff --git a/src/gui/properties/propertieswidget.h b/src/gui/properties/propertieswidget.h index 0da16226d..4f1d56609 100644 --- a/src/gui/properties/propertieswidget.h +++ b/src/gui/properties/propertieswidget.h @@ -103,7 +103,6 @@ protected slots: void filteredFilesChanged(); void showPiecesDownloaded(bool show); void showPiecesAvailability(bool show); - void renameSelectedFile(); void openSelectedFile(); private slots: diff --git a/src/gui/torrentcontenttreeview.cpp b/src/gui/torrentcontenttreeview.cpp index 972bf53a7..a829e6a5e 100644 --- a/src/gui/torrentcontenttreeview.cpp +++ b/src/gui/torrentcontenttreeview.cpp @@ -28,11 +28,22 @@ #include "torrentcontenttreeview.h" +#include #include #include +#include +#include #include #include +#include +#include "base/bittorrent/session.h" +#include "base/bittorrent/torrenthandle.h" +#include "base/global.h" +#include "base/utils/fs.h" +#include "autoexpandabledialog.h" +#include "raisedmessagebox.h" +#include "torrentcontentfiltermodel.h" #include "torrentcontentmodelitem.h" TorrentContentTreeView::TorrentContentTreeView(QWidget *parent) @@ -76,6 +87,128 @@ void TorrentContentTreeView::keyPressEvent(QKeyEvent *event) } } +void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentHandle *torrent) +{ + if (!torrent) return; + + const QModelIndexList selectedIndexes = selectionModel()->selectedRows(0); + if (selectedIndexes.size() != 1) return; + + const QModelIndex modelIndex = selectedIndexes.first(); + if (!modelIndex.isValid()) return; + + auto model = dynamic_cast(TorrentContentTreeView::model()); + if (!model) return; + + // Ask for new name + bool ok = false; + const bool isFile = (model->itemType(modelIndex) == TorrentContentModelItem::FileType); + QString newName = AutoExpandableDialog::getText(this, tr("Renaming"), tr("New name:"), QLineEdit::Normal + , modelIndex.data().toString(), &ok, isFile).trimmed(); + if (!ok) return; + + if (newName.isEmpty() || !Utils::Fs::isValidFileSystemName(newName)) { + RaisedMessageBox::warning(this, tr("Rename error"), + tr("The name is empty or contains forbidden characters, please choose a different one."), + QMessageBox::Ok); + return; + } + + if (isFile) { + const int fileIndex = model->getFileIndex(modelIndex); + + if (newName.endsWith(QB_EXT)) + newName.chop(QB_EXT.size()); + const QString oldFileName = torrent->fileName(fileIndex); + const QString oldFilePath = torrent->filePath(fileIndex); + + const bool useFilenameExt = BitTorrent::Session::instance()->isAppendExtensionEnabled() + && (torrent->filesProgress()[fileIndex] != 1); + const QString newFileName = newName + (useFilenameExt ? QB_EXT : QString()); + const QString newFilePath = oldFilePath.leftRef(oldFilePath.size() - oldFileName.size()) + newFileName; + + if (oldFileName == newFileName) { + qDebug("Name did not change: %s", qUtf8Printable(oldFileName)); + return; + } + + // check if that name is already used + for (int i = 0; i < torrent->filesCount(); ++i) { + if (i == fileIndex) continue; + if (Utils::Fs::sameFileNames(torrent->filePath(i), newFilePath)) { + RaisedMessageBox::warning(this, tr("Rename error"), + tr("This name is already in use in this folder. Please use a different name."), + QMessageBox::Ok); + return; + } + } + + qDebug("Renaming %s to %s", qUtf8Printable(oldFilePath), qUtf8Printable(newFilePath)); + torrent->renameFile(fileIndex, newFilePath); + + model->setData(modelIndex, newName); + } + else { + // renaming a folder + QStringList pathItems; + pathItems << modelIndex.data().toString(); + QModelIndex parent = model->parent(modelIndex); + while (parent.isValid()) { + pathItems.prepend(parent.data().toString()); + parent = model->parent(parent); + } + const QString oldPath = pathItems.join('/'); + pathItems.removeLast(); + pathItems << newName; + QString newPath = pathItems.join('/'); + if (Utils::Fs::sameFileNames(oldPath, newPath)) { + qDebug("Name did not change"); + return; + } + if (!newPath.endsWith('/')) newPath += '/'; + // Check for overwriting + for (int i = 0; i < torrent->filesCount(); ++i) { + const QString currentName = torrent->filePath(i); +#if defined(Q_OS_UNIX) || defined(Q_WS_QWS) + if (currentName.startsWith(newPath, Qt::CaseSensitive)) { +#else + if (currentName.startsWith(newPath, Qt::CaseInsensitive)) { +#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."), + QMessageBox::Ok); + return; + } + } + bool forceRecheck = false; + // Replace path in all files + for (int i = 0; i < torrent->filesCount(); ++i) { + const QString currentName = torrent->filePath(i); + if (currentName.startsWith(oldPath)) { + QString newName = currentName; + newName.replace(0, oldPath.length(), newPath); + if (!forceRecheck && QDir(torrent->savePath(true)).exists(newName)) + forceRecheck = true; + newName = Utils::Fs::expandPath(newName); + qDebug("Rename %s to %s", qUtf8Printable(currentName), qUtf8Printable(newName)); + torrent->renameFile(i, newName); + } + } + // Force recheck + if (forceRecheck) torrent->forceRecheck(); + // Rename folder in torrent files model too + model->setData(modelIndex, newName); + // Remove old folder + const QDir oldFolder(torrent->savePath(true) + '/' + oldPath); + int timeout = 10; + while (!QDir().rmpath(oldFolder.absolutePath()) && (timeout > 0)) { + // FIXME: We should not sleep here (freezes the UI for 1 second) + QThread::msleep(100); + --timeout; + } + } +} + QModelIndex TorrentContentTreeView::currentNameCell() { QModelIndex current = currentIndex(); diff --git a/src/gui/torrentcontenttreeview.h b/src/gui/torrentcontenttreeview.h index 62c1d4471..d2d75e25a 100644 --- a/src/gui/torrentcontenttreeview.h +++ b/src/gui/torrentcontenttreeview.h @@ -31,6 +31,11 @@ #include +namespace BitTorrent +{ + class TorrentHandle; +} + class TorrentContentTreeView : public QTreeView { Q_OBJECT @@ -39,6 +44,8 @@ public: explicit TorrentContentTreeView(QWidget *parent = nullptr); void keyPressEvent(QKeyEvent *event) override; + void renameSelectedFile(BitTorrent::TorrentHandle *torrent); + private: QModelIndex currentNameCell(); }; From e2f3dad7b8146478bb7655bb033089e63014cfec Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Tue, 4 Jun 2019 15:23:27 +0800 Subject: [PATCH 04/11] Move renameSelectedFile(BitTorrent::TorrentInfo &) --- src/gui/addnewtorrentdialog.cpp | 109 ++--------------------------- src/gui/addnewtorrentdialog.h | 1 - src/gui/torrentcontenttreeview.cpp | 105 +++++++++++++++++++++++++++ src/gui/torrentcontenttreeview.h | 2 + 4 files changed, 112 insertions(+), 105 deletions(-) diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index d942b633c..87754575e 100644 --- a/src/gui/addnewtorrentdialog.cpp +++ b/src/gui/addnewtorrentdialog.cpp @@ -154,8 +154,10 @@ AddNewTorrentDialog::AddNewTorrentDialog(const BitTorrent::AddTorrentParams &inP // Signal / slots connect(m_ui->doNotDeleteTorrentCheckBox, &QCheckBox::clicked, this, &AddNewTorrentDialog::doNotDeleteTorrentClicked); QShortcut *editHotkey = new QShortcut(Qt::Key_F2, m_ui->contentTreeView, nullptr, nullptr, Qt::WidgetShortcut); - connect(editHotkey, &QShortcut::activated, this, &AddNewTorrentDialog::renameSelectedFile); - connect(m_ui->contentTreeView, &QAbstractItemView::doubleClicked, this, &AddNewTorrentDialog::renameSelectedFile); + connect(editHotkey, &QShortcut::activated + , this, [this]() { m_ui->contentTreeView->renameSelectedFile(m_torrentInfo); }); + connect(m_ui->contentTreeView, &QAbstractItemView::doubleClicked + , this, [this]() { m_ui->contentTreeView->renameSelectedFile(m_torrentInfo); }); m_ui->buttonBox->button(QDialogButtonBox::Ok)->setFocus(); } @@ -450,107 +452,6 @@ void AddNewTorrentDialog::setSavePath(const QString &newPath) onSavePathChanged(newPath); } -void AddNewTorrentDialog::renameSelectedFile() -{ - const QModelIndexList selectedIndexes = m_ui->contentTreeView->selectionModel()->selectedRows(0); - if (selectedIndexes.size() != 1) return; - - const QModelIndex modelIndex = selectedIndexes.first(); - if (!modelIndex.isValid()) return; - - // Ask for new name - bool ok = false; - const bool isFile = (m_contentModel->itemType(modelIndex) == TorrentContentModelItem::FileType); - QString newName = AutoExpandableDialog::getText(this, tr("Renaming"), tr("New name:"), QLineEdit::Normal - , modelIndex.data().toString(), &ok, isFile).trimmed(); - if (!ok) return; - - if (newName.isEmpty() || !Utils::Fs::isValidFileSystemName(newName)) { - RaisedMessageBox::warning(this, tr("Rename error"), - tr("The name is empty or contains forbidden characters, please choose a different one."), - QMessageBox::Ok); - return; - } - - if (isFile) { - const int fileIndex = m_contentModel->getFileIndex(modelIndex); - - if (newName.endsWith(QB_EXT)) - newName.chop(QB_EXT.size()); - const QString oldFileName = m_torrentInfo.fileName(fileIndex); - const QString oldFilePath = m_torrentInfo.filePath(fileIndex); - const QString newFilePath = oldFilePath.leftRef(oldFilePath.size() - oldFileName.size()) + newName; - - if (oldFileName == newName) { - qDebug("Name did not change: %s", qUtf8Printable(oldFileName)); - return; - } - - // check if that name is already used - for (int i = 0; i < m_torrentInfo.filesCount(); ++i) { - if (i == fileIndex) continue; - if (Utils::Fs::sameFileNames(m_torrentInfo.filePath(i), newFilePath)) { - RaisedMessageBox::warning(this, tr("Rename error"), - tr("This name is already in use in this folder. Please use a different name."), - QMessageBox::Ok); - return; - } - } - - qDebug("Renaming %s to %s", qUtf8Printable(oldFilePath), qUtf8Printable(newFilePath)); - m_torrentInfo.renameFile(fileIndex, newFilePath); - - m_contentModel->setData(modelIndex, newName); - } - else { - // renaming a folder - QStringList pathItems; - pathItems << modelIndex.data().toString(); - QModelIndex parent = m_contentModel->parent(modelIndex); - while (parent.isValid()) { - pathItems.prepend(parent.data().toString()); - parent = m_contentModel->parent(parent); - } - const QString oldPath = pathItems.join('/'); - pathItems.removeLast(); - pathItems << newName; - QString newPath = pathItems.join('/'); - if (Utils::Fs::sameFileNames(oldPath, newPath)) { - qDebug("Name did not change"); - return; - } - if (!newPath.endsWith('/')) newPath += '/'; - // Check for overwriting - for (int i = 0; i < m_torrentInfo.filesCount(); ++i) { - const QString currentName = m_torrentInfo.filePath(i); -#if defined(Q_OS_UNIX) || defined(Q_WS_QWS) - if (currentName.startsWith(newPath, Qt::CaseSensitive)) { -#else - if (currentName.startsWith(newPath, Qt::CaseInsensitive)) { -#endif - 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."), - QMessageBox::Ok); - return; - } - } - // Replace path in all files - for (int i = 0; i < m_torrentInfo.filesCount(); ++i) { - const QString currentName = m_torrentInfo.filePath(i); - if (currentName.startsWith(oldPath)) { - QString newName = currentName; - newName.replace(0, oldPath.length(), newPath); - newName = Utils::Fs::expandPath(newName); - qDebug("Rename %s to %s", qUtf8Printable(currentName), qUtf8Printable(newName)); - m_torrentInfo.renameFile(i, newName); - } - } - - // Rename folder in torrent files model too - m_contentModel->setData(modelIndex, newName); - } -} - void AddNewTorrentDialog::populateSavePathComboBox() { m_ui->savePath->clear(); @@ -590,7 +491,7 @@ void AddNewTorrentDialog::displayContentTreeMenu(const QPoint &) QAction *act = myFilesLlistMenu.exec(QCursor::pos()); if (act) { if (act == actRename) { - renameSelectedFile(); + m_ui->contentTreeView->renameSelectedFile(m_torrentInfo); } else { BitTorrent::FilePriority prio = BitTorrent::FilePriority::Normal; diff --git a/src/gui/addnewtorrentdialog.h b/src/gui/addnewtorrentdialog.h index 38fc894a6..5b23aacdb 100644 --- a/src/gui/addnewtorrentdialog.h +++ b/src/gui/addnewtorrentdialog.h @@ -75,7 +75,6 @@ private slots: void displayContentTreeMenu(const QPoint &); void updateDiskSpaceLabel(); void onSavePathChanged(const QString &newPath); - void renameSelectedFile(); void updateMetadata(const BitTorrent::TorrentInfo &info); void handleDownloadFailed(const QString &url, const QString &reason); void handleRedirectedToMagnet(const QString &url, const QString &magnetUri); diff --git a/src/gui/torrentcontenttreeview.cpp b/src/gui/torrentcontenttreeview.cpp index a829e6a5e..806110ce2 100644 --- a/src/gui/torrentcontenttreeview.cpp +++ b/src/gui/torrentcontenttreeview.cpp @@ -39,6 +39,7 @@ #include "base/bittorrent/session.h" #include "base/bittorrent/torrenthandle.h" +#include "base/bittorrent/torrentinfo.h" #include "base/global.h" #include "base/utils/fs.h" #include "autoexpandabledialog.h" @@ -209,6 +210,110 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentHandle *torre } } +void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentInfo &torrent) +{ + const QModelIndexList selectedIndexes = selectionModel()->selectedRows(0); + if (selectedIndexes.size() != 1) return; + + const QModelIndex modelIndex = selectedIndexes.first(); + if (!modelIndex.isValid()) return; + + auto model = dynamic_cast(TorrentContentTreeView::model()); + if (!model) return; + + // Ask for new name + bool ok = false; + const bool isFile = (model->itemType(modelIndex) == TorrentContentModelItem::FileType); + QString newName = AutoExpandableDialog::getText(this, tr("Renaming"), tr("New name:"), QLineEdit::Normal + , modelIndex.data().toString(), &ok, isFile).trimmed(); + if (!ok) return; + + if (newName.isEmpty() || !Utils::Fs::isValidFileSystemName(newName)) { + RaisedMessageBox::warning(this, tr("Rename error"), + tr("The name is empty or contains forbidden characters, please choose a different one."), + QMessageBox::Ok); + return; + } + + if (isFile) { + const int fileIndex = model->getFileIndex(modelIndex); + + if (newName.endsWith(QB_EXT)) + newName.chop(QB_EXT.size()); + const QString oldFileName = torrent.fileName(fileIndex); + const QString oldFilePath = torrent.filePath(fileIndex); + const QString newFilePath = oldFilePath.leftRef(oldFilePath.size() - oldFileName.size()) + newName; + + if (oldFileName == newName) { + qDebug("Name did not change: %s", qUtf8Printable(oldFileName)); + return; + } + + // check if that name is already used + for (int i = 0; i < torrent.filesCount(); ++i) { + if (i == fileIndex) continue; + if (Utils::Fs::sameFileNames(torrent.filePath(i), newFilePath)) { + RaisedMessageBox::warning(this, tr("Rename error"), + tr("This name is already in use in this folder. Please use a different name."), + QMessageBox::Ok); + return; + } + } + + qDebug("Renaming %s to %s", qUtf8Printable(oldFilePath), qUtf8Printable(newFilePath)); + torrent.renameFile(fileIndex, newFilePath); + + model->setData(modelIndex, newName); + } + else { + // renaming a folder + QStringList pathItems; + pathItems << modelIndex.data().toString(); + QModelIndex parent = model->parent(modelIndex); + while (parent.isValid()) { + pathItems.prepend(parent.data().toString()); + parent = model->parent(parent); + } + const QString oldPath = pathItems.join('/'); + pathItems.removeLast(); + pathItems << newName; + QString newPath = pathItems.join('/'); + if (Utils::Fs::sameFileNames(oldPath, newPath)) { + qDebug("Name did not change"); + return; + } + if (!newPath.endsWith('/')) newPath += '/'; + // Check for overwriting + for (int i = 0; i < torrent.filesCount(); ++i) { + const QString currentName = torrent.filePath(i); +#if defined(Q_OS_UNIX) || defined(Q_WS_QWS) + if (currentName.startsWith(newPath, Qt::CaseSensitive)) { +#else + if (currentName.startsWith(newPath, Qt::CaseInsensitive)) { +#endif + 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."), + QMessageBox::Ok); + return; + } + } + // Replace path in all files + for (int i = 0; i < torrent.filesCount(); ++i) { + const QString currentName = torrent.filePath(i); + if (currentName.startsWith(oldPath)) { + QString newName = currentName; + newName.replace(0, oldPath.length(), newPath); + newName = Utils::Fs::expandPath(newName); + qDebug("Rename %s to %s", qUtf8Printable(currentName), qUtf8Printable(newName)); + torrent.renameFile(i, newName); + } + } + + // Rename folder in torrent files model too + model->setData(modelIndex, newName); + } +} + QModelIndex TorrentContentTreeView::currentNameCell() { QModelIndex current = currentIndex(); diff --git a/src/gui/torrentcontenttreeview.h b/src/gui/torrentcontenttreeview.h index d2d75e25a..b44c395af 100644 --- a/src/gui/torrentcontenttreeview.h +++ b/src/gui/torrentcontenttreeview.h @@ -34,6 +34,7 @@ namespace BitTorrent { class TorrentHandle; + class TorrentInfo; } class TorrentContentTreeView : public QTreeView @@ -45,6 +46,7 @@ public: void keyPressEvent(QKeyEvent *event) override; void renameSelectedFile(BitTorrent::TorrentHandle *torrent); + void renameSelectedFile(BitTorrent::TorrentInfo &torrent); private: QModelIndex currentNameCell(); From 06f503b5dfef92ac98ac87b3402dcaecf69066d2 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Tue, 4 Jun 2019 15:32:12 +0800 Subject: [PATCH 05/11] Fix unable to rename folder on Windows The bug occurs when the new path and old path only differ by letter case. --- src/gui/torrentcontenttreeview.cpp | 151 +++++++++++++++-------------- 1 file changed, 80 insertions(+), 71 deletions(-) diff --git a/src/gui/torrentcontenttreeview.cpp b/src/gui/torrentcontenttreeview.cpp index 806110ce2..3e65b70fd 100644 --- a/src/gui/torrentcontenttreeview.cpp +++ b/src/gui/torrentcontenttreeview.cpp @@ -101,9 +101,10 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentHandle *torre auto model = dynamic_cast(TorrentContentTreeView::model()); if (!model) return; + const bool isFile = (model->itemType(modelIndex) == TorrentContentModelItem::FileType); + // Ask for new name bool ok = false; - const bool isFile = (model->itemType(modelIndex) == TorrentContentModelItem::FileType); QString newName = AutoExpandableDialog::getText(this, tr("Renaming"), tr("New name:"), QLineEdit::Normal , modelIndex.data().toString(), &ok, isFile).trimmed(); if (!ok) return; @@ -151,62 +152,69 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentHandle *torre } else { // renaming a folder - QStringList pathItems; - pathItems << modelIndex.data().toString(); - QModelIndex parent = model->parent(modelIndex); - while (parent.isValid()) { - pathItems.prepend(parent.data().toString()); - parent = model->parent(parent); - } - const QString oldPath = pathItems.join('/'); - pathItems.removeLast(); - pathItems << newName; - QString newPath = pathItems.join('/'); - if (Utils::Fs::sameFileNames(oldPath, newPath)) { - qDebug("Name did not change"); - return; - } - if (!newPath.endsWith('/')) newPath += '/'; + + const QString oldName = modelIndex.data().toString(); + if (newName == oldName) + return; // Name did not change + + QString parentPath; + for (QModelIndex idx = model->parent(modelIndex); idx.isValid(); idx = model->parent(idx)) + parentPath.prepend(idx.data().toString() + '/'); + + const QString oldPath {parentPath + oldName + '/'}; + const QString newPath {parentPath + newName + '/'}; + // Check for overwriting - for (int i = 0; i < torrent->filesCount(); ++i) { - const QString currentName = torrent->filePath(i); -#if defined(Q_OS_UNIX) || defined(Q_WS_QWS) - if (currentName.startsWith(newPath, Qt::CaseSensitive)) { +#if defined(Q_OS_WIN) + const Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive; #else - if (currentName.startsWith(newPath, Qt::CaseInsensitive)) { + const Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive; #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."), - QMessageBox::Ok); + + 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"), + tr("This name is already in use. Please use a different name."), + QMessageBox::Ok); return; } } - bool forceRecheck = false; + // Replace path in all files + bool needForceRecheck = false; + for (int i = 0; i < torrent->filesCount(); ++i) { - const QString currentName = torrent->filePath(i); - if (currentName.startsWith(oldPath)) { - QString newName = currentName; - newName.replace(0, oldPath.length(), newPath); - if (!forceRecheck && QDir(torrent->savePath(true)).exists(newName)) - forceRecheck = true; - newName = Utils::Fs::expandPath(newName); - qDebug("Rename %s to %s", qUtf8Printable(currentName), qUtf8Printable(newName)); - torrent->renameFile(i, newName); + const QString currentPath = torrent->filePath(i); + + if (currentPath.startsWith(oldPath)) { + const QString path {newPath + currentPath.mid(oldPath.length())}; + + if (!needForceRecheck && QFile::exists(path)) + needForceRecheck = true; + + torrent->renameFile(i, path); } } + // Force recheck - if (forceRecheck) torrent->forceRecheck(); - // Rename folder in torrent files model too - model->setData(modelIndex, newName); + if (needForceRecheck) + torrent->forceRecheck(); + // Remove old folder - const QDir oldFolder(torrent->savePath(true) + '/' + oldPath); + const QString oldFullPath = torrent->savePath(true) + oldPath; 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) QThread::msleep(100); --timeout; } + + model->setData(modelIndex, newName); } } @@ -221,9 +229,10 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentInfo &torrent auto model = dynamic_cast(TorrentContentTreeView::model()); if (!model) return; + const bool isFile = (model->itemType(modelIndex) == TorrentContentModelItem::FileType); + // Ask for new name bool ok = false; - const bool isFile = (model->itemType(modelIndex) == TorrentContentModelItem::FileType); QString newName = AutoExpandableDialog::getText(this, tr("Renaming"), tr("New name:"), QLineEdit::Normal , modelIndex.data().toString(), &ok, isFile).trimmed(); if (!ok) return; @@ -267,49 +276,49 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentInfo &torrent } else { // renaming a folder - QStringList pathItems; - pathItems << modelIndex.data().toString(); - QModelIndex parent = model->parent(modelIndex); - while (parent.isValid()) { - pathItems.prepend(parent.data().toString()); - parent = model->parent(parent); - } - const QString oldPath = pathItems.join('/'); - pathItems.removeLast(); - pathItems << newName; - QString newPath = pathItems.join('/'); - if (Utils::Fs::sameFileNames(oldPath, newPath)) { - qDebug("Name did not change"); - return; - } - if (!newPath.endsWith('/')) newPath += '/'; + + const QString oldName = modelIndex.data().toString(); + if (newName == oldName) + return; // Name did not change + + QString parentPath; + for (QModelIndex idx = model->parent(modelIndex); idx.isValid(); idx = model->parent(idx)) + parentPath.prepend(idx.data().toString() + '/'); + + const QString oldPath {parentPath + oldName + '/'}; + const QString newPath {parentPath + newName + '/'}; + // Check for overwriting - for (int i = 0; i < torrent.filesCount(); ++i) { - const QString currentName = torrent.filePath(i); -#if defined(Q_OS_UNIX) || defined(Q_WS_QWS) - if (currentName.startsWith(newPath, Qt::CaseSensitive)) { +#if defined(Q_OS_WIN) + const Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive; #else - if (currentName.startsWith(newPath, Qt::CaseInsensitive)) { + const Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive; #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"), - 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); return; } } + // Replace path in all files for (int i = 0; i < torrent.filesCount(); ++i) { - const QString currentName = torrent.filePath(i); - if (currentName.startsWith(oldPath)) { - QString newName = currentName; - newName.replace(0, oldPath.length(), newPath); - newName = Utils::Fs::expandPath(newName); - qDebug("Rename %s to %s", qUtf8Printable(currentName), qUtf8Printable(newName)); - torrent.renameFile(i, newName); + const QString currentPath = torrent.filePath(i); + + if (currentPath.startsWith(oldPath)) { + const QString path {newPath + currentPath.mid(oldPath.length())}; + torrent.renameFile(i, path); } } - // Rename folder in torrent files model too model->setData(modelIndex, newName); } } From 01e417955536d221f25d55e19bc93bc25d81ed3a Mon Sep 17 00:00:00 2001 From: silverqx Date: Thu, 13 Jun 2019 17:31:54 +0200 Subject: [PATCH 06/11] Focus behavior row in Options dialog --- src/gui/optionsdialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/optionsdialog.ui b/src/gui/optionsdialog.ui index f6cdcc45c..7382975f0 100644 --- a/src/gui/optionsdialog.ui +++ b/src/gui/optionsdialog.ui @@ -45,7 +45,7 @@ QListView::IconMode - -1 + 0 From e329c41ef2952b7cc9db1a19bd69dd69356ca17d Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Tue, 4 Jun 2019 20:46:41 +0800 Subject: [PATCH 07/11] Properly remove empty leftover folders after rename TorrentInfo::origFilePath will return the very original path from .torrent file, not the most recent file path before the rename operation and thus the code would not be working as we expected. --- src/base/bittorrent/torrenthandle.cpp | 64 +++++++++++++++++---------- src/base/bittorrent/torrenthandle.h | 10 +++++ src/base/utils/string.cpp | 11 +++++ src/base/utils/string.h | 3 ++ src/gui/torrentcontenttreeview.cpp | 9 ---- 5 files changed, 64 insertions(+), 33 deletions(-) diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index 93aa75d60..2da728bcf 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -1402,6 +1402,7 @@ void TorrentHandle::setTrackerLogin(const QString &username, const QString &pass void TorrentHandle::renameFile(int index, const QString &name) { + m_oldPath[LTFileIndex {index}].push_back(filePath(index)); ++m_renameCount; qDebug() << Q_FUNC_INFO << index << name; m_nativeHandle.rename_file(index, Utils::Fs::toNativePath(name).toStdString()); @@ -1685,33 +1686,42 @@ void TorrentHandle::handleFastResumeRejectedAlert(const libtorrent::fastresume_r void TorrentHandle::handleFileRenamedAlert(const libtorrent::file_renamed_alert *p) { -#if LIBTORRENT_VERSION_NUM < 10100 - QString newName = Utils::Fs::fromNativePath(QString::fromStdString(p->name)); -#else - QString newName = Utils::Fs::fromNativePath(p->new_name()); -#endif - - // TODO: Check this! - if (filesCount() > 1) { - // Check if folders were renamed - QStringList oldPathParts = m_torrentInfo.origFilePath(p->index).split('/'); - oldPathParts.removeLast(); - QString oldPath = oldPathParts.join('/'); - QStringList newPathParts = newName.split('/'); - newPathParts.removeLast(); - QString newPath = newPathParts.join('/'); - if (!newPathParts.isEmpty() && (oldPath != newPath)) { - qDebug("oldPath(%s) != newPath(%s)", qUtf8Printable(oldPath), qUtf8Printable(newPath)); - oldPath = QString("%1/%2").arg(savePath(true), oldPath); - qDebug("Detected folder renaming, attempt to delete old folder: %s", qUtf8Printable(oldPath)); - QDir().rmpath(oldPath); - } - } - // We don't really need to call updateStatus() in this place. // All we need to do is make sure we have a valid instance of the TorrentInfo object. m_torrentInfo = TorrentInfo {m_nativeHandle.torrent_file()}; + // remove empty leftover folders + // for example renaming "a/b/c" to "d/b/c", then folders "a/b" and "a" will + // be removed if they are empty + const QString oldFilePath = m_oldPath[LTFileIndex {p->index}].takeFirst(); + const QString newFilePath = Utils::Fs::fromNativePath(p->new_name()); + + if (m_oldPath[LTFileIndex {p->index}].isEmpty()) + m_oldPath.remove(LTFileIndex {p->index}); + + QVector oldPathParts = oldFilePath.splitRef('/', QString::SkipEmptyParts); + oldPathParts.removeLast(); // drop file name part + QVector newPathParts = newFilePath.splitRef('/', QString::SkipEmptyParts); + newPathParts.removeLast(); // drop file name part + +#if defined(Q_OS_WIN) + const Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive; +#else + const Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive; +#endif + + int pathIdx = 0; + while ((pathIdx < oldPathParts.size()) && (pathIdx < newPathParts.size())) { + if (oldPathParts[pathIdx].compare(newPathParts[pathIdx], caseSensitivity) != 0) + break; + ++pathIdx; + } + + for (int i = (oldPathParts.size() - 1); i >= pathIdx; --i) { + QDir().rmdir(savePath() + Utils::String::join(oldPathParts, QLatin1String("/"))); + oldPathParts.removeLast(); + } + --m_renameCount; while (!isMoveInProgress() && (m_renameCount == 0) && !m_moveFinishedTriggers.isEmpty()) m_moveFinishedTriggers.takeFirst()(); @@ -1719,7 +1729,13 @@ void TorrentHandle::handleFileRenamedAlert(const libtorrent::file_renamed_alert void TorrentHandle::handleFileRenameFailedAlert(const libtorrent::file_rename_failed_alert *p) { - Q_UNUSED(p); + LogMsg(tr("File rename failed. Torrent: \"%1\", file: \"%2\", reason: \"%3\"") + .arg(name(), filePath(p->index) + , QString::fromStdString(p->error.message())), Log::WARNING); + + m_oldPath[LTFileIndex {p->index}].removeFirst(); + if (m_oldPath[LTFileIndex {p->index}].isEmpty()) + m_oldPath.remove(LTFileIndex {p->index}); --m_renameCount; while (!isMoveInProgress() && (m_renameCount == 0) && !m_moveFinishedTriggers.isEmpty()) diff --git a/src/base/bittorrent/torrenthandle.h b/src/base/bittorrent/torrenthandle.h index 425e688d4..c9d9d9a67 100644 --- a/src/base/bittorrent/torrenthandle.h +++ b/src/base/bittorrent/torrenthandle.h @@ -385,6 +385,12 @@ namespace BitTorrent private: typedef boost::function EventTrigger; +#if (LIBTORRENT_VERSION_NUM < 10200) + using LTFileIndex = int; +#else + using LTFileIndex = lt::file_index_t; +#endif + void updateStatus(); void updateStatus(const libtorrent::torrent_status &nativeStatus); void updateState(); @@ -446,6 +452,10 @@ namespace BitTorrent QQueue m_moveFinishedTriggers; int m_renameCount; + // Until libtorrent provide an "old_name" field in `file_renamed_alert` + // we will rely on this workaround to remove empty leftover folders + QHash> m_oldPath; + bool m_useAutoTMM; // Persistent data diff --git a/src/base/utils/string.cpp b/src/base/utils/string.cpp index 85b5b9191..59c07031b 100644 --- a/src/base/utils/string.cpp +++ b/src/base/utils/string.cpp @@ -213,3 +213,14 @@ TriStateBool Utils::String::parseTriStateBool(const QString &string) return TriStateBool::False; return TriStateBool::Undefined; } + +QString Utils::String::join(const QVector &strings, const QString &separator) +{ + if (strings.empty()) + return {}; + + QString ret = strings[0].toString(); + for (int i = 1; i < strings.count(); ++i) + ret += (separator + strings[i]); + return ret; +} diff --git a/src/base/utils/string.h b/src/base/utils/string.h index 5a1088622..3f15322da 100644 --- a/src/base/utils/string.h +++ b/src/base/utils/string.h @@ -31,6 +31,7 @@ #define UTILS_STRING_H #include +#include class QByteArray; class QLatin1String; @@ -70,6 +71,8 @@ namespace Utils bool parseBool(const QString &string, const bool defaultValue); TriStateBool parseTriStateBool(const QString &string); + + QString join(const QVector &strings, const QString &separator); } } diff --git a/src/gui/torrentcontenttreeview.cpp b/src/gui/torrentcontenttreeview.cpp index 3e65b70fd..285d3f568 100644 --- a/src/gui/torrentcontenttreeview.cpp +++ b/src/gui/torrentcontenttreeview.cpp @@ -205,15 +205,6 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentHandle *torre if (needForceRecheck) torrent->forceRecheck(); - // Remove old folder - const QString oldFullPath = torrent->savePath(true) + oldPath; - int timeout = 10; - while (!QDir().rmpath(oldFullPath) && (timeout > 0)) { - // FIXME: We should not sleep here (freezes the UI for 1 second) - QThread::msleep(100); - --timeout; - } - model->setData(modelIndex, newName); } } From d376d912b32c90f10dd897d898fa6baa9c41ea8d Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Tue, 11 Jun 2019 00:15:06 +0800 Subject: [PATCH 08/11] Don't remove parent directories QDir::rmpath removes *all* parent directories while QDir::rmdir removes the specified directory. --- src/base/bittorrent/session.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index bad167a31..1a056324b 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -1944,7 +1944,7 @@ bool Session::deleteTorrent(const QString &hash, bool deleteLocalFiles) Utils::Fs::forceRemove(unwantedFile); const QString parentFolder = Utils::Fs::branchPath(unwantedFile); qDebug("Attempt to remove parent folder (if empty): %s", qUtf8Printable(parentFolder)); - QDir().rmpath(parentFolder); + QDir().rmdir(parentFolder); } } From 3fdab88eb71fa5ee005611dc80df9c731a39e806 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Tue, 11 Jun 2019 02:11:28 +0800 Subject: [PATCH 09/11] Log save_resume_data_failed_alert --- src/base/bittorrent/torrenthandle.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index 2da728bcf..e3f0b8dce 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -1665,10 +1665,14 @@ void TorrentHandle::handleSaveResumeDataFailedAlert(const libtorrent::save_resum { // if torrent has no metadata we should save dummy fastresume data // containing Magnet URI and qBittorrent own resume data only - if (p->error.value() == libt::errors::no_metadata) + if (p->error.value() == libt::errors::no_metadata) { handleSaveResumeDataAlert(nullptr); - else + } + else { + LogMsg(tr("Save resume data failed. Torrent: \"%1\", error: \"%2\"") + .arg(name(), QString::fromStdString(p->error.message())), Log::CRITICAL); m_session->handleTorrentResumeDataFailed(this); + } } void TorrentHandle::handleFastResumeRejectedAlert(const libtorrent::fastresume_rejected_alert *p) From 8d26a221e0028b39b4632e760ca226a796d8965a Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Tue, 11 Jun 2019 11:59:08 +0800 Subject: [PATCH 10/11] Fix updated save path not saved for paused torrents --- src/base/bittorrent/torrenthandle.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index e3f0b8dce..13842b61d 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -1729,6 +1729,9 @@ void TorrentHandle::handleFileRenamedAlert(const libtorrent::file_renamed_alert --m_renameCount; while (!isMoveInProgress() && (m_renameCount == 0) && !m_moveFinishedTriggers.isEmpty()) m_moveFinishedTriggers.takeFirst()(); + + if (isPaused() && (m_renameCount == 0)) + saveResumeData(); // otherwise the new path will not be saved } void TorrentHandle::handleFileRenameFailedAlert(const libtorrent::file_rename_failed_alert *p) @@ -1744,6 +1747,9 @@ void TorrentHandle::handleFileRenameFailedAlert(const libtorrent::file_rename_fa --m_renameCount; while (!isMoveInProgress() && (m_renameCount == 0) && !m_moveFinishedTriggers.isEmpty()) m_moveFinishedTriggers.takeFirst()(); + + if (isPaused() && (m_renameCount == 0)) + saveResumeData(); // otherwise the new path will not be saved } void TorrentHandle::handleFileCompletedAlert(const libtorrent::file_completed_alert *p) From 74e52746b19f6065289f827ce0cb9d6beb0a28c6 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Wed, 12 Jun 2019 10:54:43 +0800 Subject: [PATCH 11/11] Reorder if conditions slightly --- src/base/bittorrent/session.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index 1a056324b..368059544 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -2377,9 +2377,13 @@ void Session::generateResumeData(bool final) { for (TorrentHandle *const torrent : asConst(m_torrents)) { if (!torrent->isValid()) continue; - if (torrent->isChecking() || torrent->isPaused()) continue; + if (!final && !torrent->needSaveResumeData()) continue; - if (torrent->hasMissingFiles() || torrent->hasError()) continue; + if (torrent->isChecking() + || torrent->isPaused() + || torrent->hasError() + || torrent->hasMissingFiles()) + continue; saveTorrentResumeData(torrent); }