From 4b2d8a7941bd75a54345bf748258de9c47acd8ed Mon Sep 17 00:00:00 2001 From: sledgehammer999 Date: Sat, 7 Nov 2015 20:44:53 +0200 Subject: [PATCH 1/4] Setting for creating subfolder on multifile torrents. Closes #588. --- src/base/bittorrent/session.cpp | 5 +++++ src/base/bittorrent/session.h | 1 + src/base/bittorrent/torrenthandle.cpp | 4 ++++ src/base/bittorrent/torrenthandle.h | 1 + src/base/bittorrent/torrentinfo.cpp | 18 ++++++++++++++++++ src/base/bittorrent/torrentinfo.h | 4 ++++ src/base/preferences.cpp | 10 ++++++++++ src/base/preferences.h | 2 ++ src/gui/addnewtorrentdialog.cpp | 8 +++++--- src/gui/addnewtorrentdialog.ui | 20 ++++++++++++++++++++ src/gui/optionsdlg.cpp | 3 +++ src/gui/optionsdlg.ui | 10 ++++++++++ src/gui/properties/propertieswidget.cpp | 7 +++++-- 13 files changed, 88 insertions(+), 5 deletions(-) diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index 56474550e..62e8ee5b6 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -1652,6 +1652,11 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri p = magnetUri.addTorrentParams(); } else if (torrentInfo.isValid()) { + if (!addData.resumed && !addData.createSubfolder && torrentInfo.filesCount() > 1) { + libtorrent::file_storage files = torrentInfo.files(); + files.set_name(""); + torrentInfo.remapFiles(files); + } // Metadata if (!addData.resumed && !addData.hasSeedStatus) findIncompleteFiles(torrentInfo, savePath); diff --git a/src/base/bittorrent/session.h b/src/base/bittorrent/session.h index adeae914a..86c0a3973 100644 --- a/src/base/bittorrent/session.h +++ b/src/base/bittorrent/session.h @@ -147,6 +147,7 @@ namespace BitTorrent QVector filePriorities; // used if TorrentInfo is set bool ignoreShareRatio = false; bool skipChecking = false; + bool createSubfolder = true; }; struct TorrentStatusReport diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index 607551d7b..4a220f37f 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -152,6 +152,7 @@ TorrentState::operator int() const return m_value; } + , createSubfolder(in.createSubfolder) // TorrentHandle const qreal TorrentHandle::USE_GLOBAL_RATIO = -2.; @@ -230,6 +231,9 @@ QString TorrentHandle::name() const if (name.isEmpty()) name = QString::fromStdString(m_nativeStatus.name); + if (name.isEmpty()) + name = QString::fromStdString(m_torrentInfo.origFiles().name()); + if (name.isEmpty()) name = m_hash; diff --git a/src/base/bittorrent/torrenthandle.h b/src/base/bittorrent/torrenthandle.h index a0837d09f..e43f0cf50 100644 --- a/src/base/bittorrent/torrenthandle.h +++ b/src/base/bittorrent/torrenthandle.h @@ -98,6 +98,7 @@ namespace BitTorrent bool sequential; bool hasSeedStatus; bool skipChecking; + bool createSubfolder; TriStateBool addForced; TriStateBool addPaused; // for new torrents diff --git a/src/base/bittorrent/torrentinfo.cpp b/src/base/bittorrent/torrentinfo.cpp index 6cf53124f..db23445f7 100644 --- a/src/base/bittorrent/torrentinfo.cpp +++ b/src/base/bittorrent/torrentinfo.cpp @@ -276,6 +276,18 @@ TorrentInfo::PieceRange TorrentInfo::filePieces(int fileIndex) const static_cast((firstOffset + fileSize - 1) / pieceLength())); } +libtorrent::file_storage TorrentInfo::files() const +{ + if (!isValid()) return libtorrent::file_storage(); + return m_nativeInfo->files(); +} + +libtorrent::file_storage TorrentInfo::origFiles() const +{ + if (!isValid()) return libtorrent::file_storage(); + return m_nativeInfo->orig_files(); +} + void TorrentInfo::renameFile(uint index, const QString &newPath) { if (!isValid()) return; @@ -293,6 +305,12 @@ int BitTorrent::TorrentInfo::fileIndex(const QString& fileName) const return -1; } +void TorrentInfo::remapFiles(libtorrent::file_storage const &fileStorage) +{ + if (!isValid()) return; + m_nativeInfo->remap_files(fileStorage); +} + TorrentInfo::NativePtr TorrentInfo::nativeInfo() const { return m_nativeInfo; diff --git a/src/base/bittorrent/torrentinfo.h b/src/base/bittorrent/torrentinfo.h index 9a148add0..9c371fc4f 100644 --- a/src/base/bittorrent/torrentinfo.h +++ b/src/base/bittorrent/torrentinfo.h @@ -98,8 +98,12 @@ namespace BitTorrent PieceRange filePieces(const QString &file) const; PieceRange filePieces(int fileIndex) const; + libtorrent::file_storage files() const; + libtorrent::file_storage origFiles() const; + void renameFile(uint index, const QString &newPath); + void remapFiles(libtorrent::file_storage const &fileStorage); NativePtr nativeInfo() const; private: diff --git a/src/base/preferences.cpp b/src/base/preferences.cpp index 630dbe4f8..3f34c84b7 100644 --- a/src/base/preferences.cpp +++ b/src/base/preferences.cpp @@ -263,6 +263,16 @@ void Preferences::setLastLocationPath(const QString &path) setValue("Preferences/Downloads/LastLocationPath", Utils::Fs::fromNativePath(path)); } +bool Preferences::getTorrentCreateSubfolder() const +{ + return value("Preferences/Downloads/CreateSubfolder", true).toBool(); +} + +void Preferences::setTorrentCreateSubfolder(bool b) +{ + setValue("Preferences/Downloads/CreateSubfolder", b); +} + QVariantHash Preferences::getScanDirs() const { return value("Preferences/Downloads/ScanDirsV2").toHash(); diff --git a/src/base/preferences.h b/src/base/preferences.h index ec328f264..4b06ae3d5 100644 --- a/src/base/preferences.h +++ b/src/base/preferences.h @@ -138,6 +138,8 @@ public: void setLastLocationPath(const QString &path); QVariantHash getScanDirs() const; void setScanDirs(const QVariantHash &dirs); + bool getTorrentCreateSubfolder() const; + void setTorrentCreateSubfolder(bool b); QString getScanDirsLastPath() const; void setScanDirsLastPath(const QString &path); bool isMailNotificationEnabled() const; diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index c773a9cbd..ff3d4c789 100644 --- a/src/gui/addnewtorrentdialog.cpp +++ b/src/gui/addnewtorrentdialog.cpp @@ -35,6 +35,7 @@ #include #include +#include "base/preferences.h" #include "base/settingsstorage.h" #include "base/net/downloadmanager.h" #include "base/net/downloadhandler.h" @@ -95,6 +96,7 @@ AddNewTorrentDialog::AddNewTorrentDialog(QWidget *parent) connect(ui->savePathComboBox, SIGNAL(currentIndexChanged(int)), SLOT(onSavePathChanged(int))); connect(ui->browseButton, SIGNAL(clicked()), SLOT(browseButton_clicked())); ui->defaultSavePathCheckBox->setVisible(false); // Default path is selected by default + ui->createSubfolderComboBox->setChecked(Preferences::instance()->getTorrentCreateSubfolder()); ui->doNotDeleteTorrentCheckBox->setVisible(TorrentFileGuard::autoDeleteMode() != TorrentFileGuard::Never); @@ -624,9 +626,8 @@ void AddNewTorrentDialog::accept() BitTorrent::AddTorrentParams params; - if (ui->skip_check_cb->isChecked()) - // TODO: Check if destination actually exists - params.skipChecking = true; + // TODO: Check if destination actually exists + params.skipChecking = ui->skip_check_cb->isChecked(); // Category params.category = ui->categoryComboBox->currentText(); @@ -639,6 +640,7 @@ void AddNewTorrentDialog::accept() params.filePriorities = m_contentModel->model()->getFilePriorities(); params.addPaused = !ui->startTorrentCheckBox->isChecked(); + params.createSubfolder = ui->createSubfolderComboBox->isChecked(); QString savePath = ui->savePathComboBox->itemData(ui->savePathComboBox->currentIndex()).toString(); if (ui->comboTTM->currentIndex() != 1) { // 0 is Manual mode and 1 is Automatic mode. Handle all non 1 values as manual mode. diff --git a/src/gui/addnewtorrentdialog.ui b/src/gui/addnewtorrentdialog.ui index e214b2aa6..5aff7281b 100644 --- a/src/gui/addnewtorrentdialog.ui +++ b/src/gui/addnewtorrentdialog.ui @@ -192,6 +192,26 @@ + + + + Start torrent + + + true + + + + + + + Create subfolder + + + true + + + diff --git a/src/gui/optionsdlg.cpp b/src/gui/optionsdlg.cpp index d4cb9cb5a..78f488bc7 100644 --- a/src/gui/optionsdlg.cpp +++ b/src/gui/optionsdlg.cpp @@ -214,6 +214,7 @@ OptionsDialog::OptionsDialog(QWidget *parent) connect(m_ui->checkAdditionDialog, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); connect(m_ui->checkAdditionDialogFront, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); connect(m_ui->checkStartPaused, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); + connect(m_ui->checkCreateSubfolder, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); connect(m_ui->deleteTorrentBox, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); connect(m_ui->deleteCancelledTorrentBox, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); connect(m_ui->checkExportDir, SIGNAL(toggled(bool)), this, SLOT(enableApplyButton())); @@ -515,6 +516,7 @@ void OptionsDialog::saveOptions() AddNewTorrentDialog::setEnabled(useAdditionDialog()); AddNewTorrentDialog::setTopLevel(m_ui->checkAdditionDialogFront->isChecked()); session->setAddTorrentPaused(addTorrentsInPause()); + pref->setTorrentCreateSubfolder(m_ui->checkCreateSubfolder->isChecked()); ScanFoldersModel::instance()->removeFromFSWatcher(removedScanDirs); ScanFoldersModel::instance()->addToFSWatcher(addedScanDirs); ScanFoldersModel::instance()->makePersistent(); @@ -716,6 +718,7 @@ void OptionsDialog::loadOptions() m_ui->checkAdditionDialog->setChecked(AddNewTorrentDialog::isEnabled()); m_ui->checkAdditionDialogFront->setChecked(AddNewTorrentDialog::isTopLevel()); m_ui->checkStartPaused->setChecked(session->isAddTorrentPaused()); + m_ui->checkCreateSubfolder->setChecked(pref->getTorrentCreateSubfolder()); const TorrentFileGuard::AutoDeleteMode autoDeleteMode = TorrentFileGuard::autoDeleteMode(); m_ui->deleteTorrentBox->setChecked(autoDeleteMode != TorrentFileGuard::Never); m_ui->deleteCancelledTorrentBox->setChecked(autoDeleteMode == TorrentFileGuard::Always); diff --git a/src/gui/optionsdlg.ui b/src/gui/optionsdlg.ui index 8b41e7546..82854e831 100644 --- a/src/gui/optionsdlg.ui +++ b/src/gui/optionsdlg.ui @@ -709,6 +709,16 @@ + + + + Create subfolder for torrents with multiple files + + + true + + + diff --git a/src/gui/properties/propertieswidget.cpp b/src/gui/properties/propertieswidget.cpp index 9015b2a33..2a53fceb5 100644 --- a/src/gui/properties/propertieswidget.cpp +++ b/src/gui/properties/propertieswidget.cpp @@ -315,8 +315,11 @@ void PropertiesWidget::loadTorrentInfos(BitTorrent::TorrentHandle *const torrent label_created_by_val->setText(m_torrent->creator().toHtmlEscaped()); // List files in torrent - PropListModel->model()->setupModelData(m_torrent->info()); - filesList->setExpanded(PropListModel->index(0, 0), true); + BitTorrent::TorrentInfo info = m_torrent->info(); + libtorrent::file_storage files = info.files(); + PropListModel->model()->setupModelData(info); + if (!(info.filesCount() > 1 && files.name().empty())) + filesList->setExpanded(PropListModel->index(0, 0), true); // Load file priorities PropListModel->model()->updateFilesPriorities(m_torrent->filePriorities()); From d413bc65eff957aec03fb7fa4e12e6e8f5ca6e91 Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Mon, 4 Jan 2016 16:00:50 +0300 Subject: [PATCH 2/4] Improve strip torrent root folder Fix issue when you rename the "root item" in the "Add New Torrent" dialog and uncheck "Create subfolder", it will create the subfolder with the renamed name. Fix PropertiesWidget first folder is expanded after app restart. Strip root folder if torrent was added via magnet link. Fix crash when you get name of torrent without metadata. --- src/base/bittorrent/session.cpp | 9 ++++--- src/base/bittorrent/torrenthandle.cpp | 24 +++++++++++++++---- src/base/bittorrent/torrenthandle.h | 7 ++++-- src/base/bittorrent/torrentinfo.cpp | 32 ++++++++++++------------- src/base/bittorrent/torrentinfo.h | 5 +--- src/gui/properties/propertieswidget.cpp | 6 ++--- 6 files changed, 48 insertions(+), 35 deletions(-) diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index 62e8ee5b6..ea6e8cf15 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -1652,11 +1652,9 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri p = magnetUri.addTorrentParams(); } else if (torrentInfo.isValid()) { - if (!addData.resumed && !addData.createSubfolder && torrentInfo.filesCount() > 1) { - libtorrent::file_storage files = torrentInfo.files(); - files.set_name(""); - torrentInfo.remapFiles(files); - } + if (!addData.resumed && !addData.hasRootFolder) + torrentInfo.stripRootFolder(); + // Metadata if (!addData.resumed && !addData.hasSeedStatus) findIncompleteFiles(torrentInfo, savePath); @@ -3651,6 +3649,7 @@ namespace torrentData.name = QString::fromStdString(fast.dict_find_string_value("qBt-name")); torrentData.hasSeedStatus = fast.dict_find_int_value("qBt-seedStatus"); torrentData.disableTempPath = fast.dict_find_int_value("qBt-tempPathDisabled"); + torrentData.hasRootFolder = fast.dict_find_int_value("qBt-hasRootFolder"); magnetUri = MagnetUri(QString::fromStdString(fast.dict_find_string_value("qBt-magnetUri"))); torrentData.addPaused = fast.dict_find_int_value("qBt-paused"); diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index 4a220f37f..05788a8db 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -89,6 +89,7 @@ AddTorrentData::AddTorrentData(const AddTorrentParams ¶ms) , sequential(params.sequential) , hasSeedStatus(params.skipChecking) // do not react on 'torrent_finished_alert' when skipping , skipChecking(params.skipChecking) + , hasRootFolder(params.createSubfolder) , addForced(params.addForced) , addPaused(params.addPaused) , filePriorities(params.filePriorities) @@ -152,7 +153,6 @@ TorrentState::operator int() const return m_value; } - , createSubfolder(in.createSubfolder) // TorrentHandle const qreal TorrentHandle::USE_GLOBAL_RATIO = -2.; @@ -200,6 +200,7 @@ TorrentHandle::TorrentHandle(Session *session, const libtorrent::torrent_handle , m_ratioLimit(data.ratioLimit) , m_tempPathDisabled(data.disableTempPath) , m_hasMissingFiles(false) + , m_hasRootFolder(data.hasRootFolder) , m_pauseAfterRecheck(false) , m_needSaveResumeData(false) { @@ -209,8 +210,13 @@ TorrentHandle::TorrentHandle(Session *session, const libtorrent::torrent_handle updateStatus(); m_hash = InfoHash(m_nativeStatus.info_hash); - if (!data.resumed) + if (!data.resumed) { setSequentialDownload(data.sequential); + if (hasMetadata()) { + if (filesCount() == 1) + m_hasRootFolder = false; + } + } } TorrentHandle::~TorrentHandle() {} @@ -231,8 +237,8 @@ QString TorrentHandle::name() const if (name.isEmpty()) name = QString::fromStdString(m_nativeStatus.name); - if (name.isEmpty()) - name = QString::fromStdString(m_torrentInfo.origFiles().name()); + if (name.isEmpty() && hasMetadata()) + name = QString::fromStdString(m_torrentInfo.nativeInfo()->orig_files().name()); if (name.isEmpty()) name = m_hash; @@ -338,6 +344,11 @@ void TorrentHandle::setAutoTMMEnabled(bool enabled) move_impl(m_session->categorySavePath(m_category)); } +bool TorrentHandle::hasRootFolder() const +{ + return m_hasRootFolder; +} + QString TorrentHandle::nativeActualSavePath() const { return QString::fromStdString(m_nativeStatus.save_path); @@ -1493,6 +1504,7 @@ void TorrentHandle::handleSaveResumeDataAlert(libtorrent::save_resume_data_alert resumeData["qBt-seedStatus"] = m_hasSeedStatus; resumeData["qBt-tempPathDisabled"] = m_tempPathDisabled; resumeData["qBt-queuePosition"] = queuePosition(); + resumeData["qBt-hasRootFolder"] = m_hasRootFolder; m_session->handleTorrentResumeDataReady(this, resumeData); } @@ -1594,6 +1606,10 @@ void TorrentHandle::handleMetadataReceivedAlert(libt::metadata_received_alert *p updateStatus(); if (m_session->isAppendExtensionEnabled()) manageIncompleteFiles(); + if (!m_hasRootFolder) + m_torrentInfo.stripRootFolder(); + if (filesCount() == 1) + m_hasRootFolder = false; m_session->handleTorrentMetadataReceived(this); if (isPaused()) { diff --git a/src/base/bittorrent/torrenthandle.h b/src/base/bittorrent/torrenthandle.h index e43f0cf50..4d1360f61 100644 --- a/src/base/bittorrent/torrenthandle.h +++ b/src/base/bittorrent/torrenthandle.h @@ -98,7 +98,7 @@ namespace BitTorrent bool sequential; bool hasSeedStatus; bool skipChecking; - bool createSubfolder; + bool hasRootFolder; TriStateBool addForced; TriStateBool addPaused; // for new torrents @@ -236,6 +236,8 @@ namespace BitTorrent bool belongsToCategory(const QString &category) const; bool setCategory(const QString &category); + bool hasRootFolder() const; + int filesCount() const; int piecesCount() const; int piecesHave() const; @@ -396,7 +398,7 @@ namespace BitTorrent Session *const m_session; libtorrent::torrent_handle m_nativeHandle; libtorrent::torrent_status m_nativeStatus; - TorrentState m_state; + TorrentState m_state; TorrentInfo m_torrentInfo; SpeedMonitor m_speedMonitor; @@ -422,6 +424,7 @@ namespace BitTorrent qreal m_ratioLimit; bool m_tempPathDisabled; bool m_hasMissingFiles; + bool m_hasRootFolder; bool m_pauseAfterRecheck; bool m_needSaveResumeData; diff --git a/src/base/bittorrent/torrentinfo.cpp b/src/base/bittorrent/torrentinfo.cpp index db23445f7..357378bd2 100644 --- a/src/base/bittorrent/torrentinfo.cpp +++ b/src/base/bittorrent/torrentinfo.cpp @@ -276,22 +276,10 @@ TorrentInfo::PieceRange TorrentInfo::filePieces(int fileIndex) const static_cast((firstOffset + fileSize - 1) / pieceLength())); } -libtorrent::file_storage TorrentInfo::files() const -{ - if (!isValid()) return libtorrent::file_storage(); - return m_nativeInfo->files(); -} - -libtorrent::file_storage TorrentInfo::origFiles() const -{ - if (!isValid()) return libtorrent::file_storage(); - return m_nativeInfo->orig_files(); -} - void TorrentInfo::renameFile(uint index, const QString &newPath) { if (!isValid()) return; - nativeInfo()->rename_file(index, newPath.toStdString()); + nativeInfo()->rename_file(index, Utils::Fs::toNativePath(newPath).toStdString()); } int BitTorrent::TorrentInfo::fileIndex(const QString& fileName) const @@ -305,10 +293,22 @@ int BitTorrent::TorrentInfo::fileIndex(const QString& fileName) const return -1; } -void TorrentInfo::remapFiles(libtorrent::file_storage const &fileStorage) +void TorrentInfo::stripRootFolder() { - if (!isValid()) return; - m_nativeInfo->remap_files(fileStorage); + if (filesCount() <= 1) return; + + libtorrent::file_storage files = m_nativeInfo->files(); + + // Solution for case of renamed root folder + std::string testName = filePath(0).split('/').value(0).toStdString(); + if (files.name() != testName) { + files.set_name(testName); + for (int i = 0; i < files.num_files(); ++i) + files.rename_file(i, files.file_path(i)); + } + + files.set_name(""); + m_nativeInfo->remap_files(files); } TorrentInfo::NativePtr TorrentInfo::nativeInfo() const diff --git a/src/base/bittorrent/torrentinfo.h b/src/base/bittorrent/torrentinfo.h index 9c371fc4f..8f918087b 100644 --- a/src/base/bittorrent/torrentinfo.h +++ b/src/base/bittorrent/torrentinfo.h @@ -98,12 +98,9 @@ namespace BitTorrent PieceRange filePieces(const QString &file) const; PieceRange filePieces(int fileIndex) const; - libtorrent::file_storage files() const; - libtorrent::file_storage origFiles() const; - void renameFile(uint index, const QString &newPath); + void stripRootFolder(); - void remapFiles(libtorrent::file_storage const &fileStorage); NativePtr nativeInfo() const; private: diff --git a/src/gui/properties/propertieswidget.cpp b/src/gui/properties/propertieswidget.cpp index 2a53fceb5..06fccc1b8 100644 --- a/src/gui/properties/propertieswidget.cpp +++ b/src/gui/properties/propertieswidget.cpp @@ -315,10 +315,8 @@ void PropertiesWidget::loadTorrentInfos(BitTorrent::TorrentHandle *const torrent label_created_by_val->setText(m_torrent->creator().toHtmlEscaped()); // List files in torrent - BitTorrent::TorrentInfo info = m_torrent->info(); - libtorrent::file_storage files = info.files(); - PropListModel->model()->setupModelData(info); - if (!(info.filesCount() > 1 && files.name().empty())) + PropListModel->model()->setupModelData(m_torrent->info()); + if ((m_torrent->filesCount() > 1) && (PropListModel->model()->rowCount() == 1)) filesList->setExpanded(PropListModel->index(0, 0), true); // Load file priorities From 6d7d566cdf6dbe1922a77bc8f3939582808b97d9 Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Wed, 6 Jan 2016 10:26:57 +0300 Subject: [PATCH 3/4] Fix TorrentHandle rootPath() and contentPath() methods --- src/base/bittorrent/session.cpp | 4 +++- src/base/bittorrent/torrenthandle.cpp | 7 ++++++- src/base/bittorrent/torrenthandle.h | 4 ++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index ea6e8cf15..47972500c 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -1405,7 +1405,9 @@ bool Session::deleteTorrent(const QString &hash, bool deleteLocalFiles) // Remove it from session if (deleteLocalFiles) { - m_savePathsToRemove[torrent->hash()] = torrent->rootPath(true); + QString rootPath = torrent->rootPath(true); + if (!rootPath.isEmpty()) + m_savePathsToRemove[torrent->hash()] = rootPath; m_nativeSession->remove_torrent(torrent->nativeHandle(), libt::session::delete_files); } else { diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index 05788a8db..41f3fbf4a 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -312,6 +312,9 @@ QString TorrentHandle::savePath(bool actual) const QString TorrentHandle::rootPath(bool actual) const { + if ((filesCount() > 1) && !hasRootFolder()) + return QString(); + QString firstFilePath = filePath(0); const int slashIndex = firstFilePath.indexOf("/"); if (slashIndex >= 0) @@ -324,8 +327,10 @@ QString TorrentHandle::contentPath(bool actual) const { if (filesCount() == 1) return QDir(savePath(actual)).absoluteFilePath(filePath(0)); - else + else if (hasRootFolder()) return rootPath(actual); + else + return savePath(actual); } bool TorrentHandle::isAutoTMMEnabled() const diff --git a/src/base/bittorrent/torrenthandle.h b/src/base/bittorrent/torrenthandle.h index 4d1360f61..f8226bcb1 100644 --- a/src/base/bittorrent/torrenthandle.h +++ b/src/base/bittorrent/torrenthandle.h @@ -207,6 +207,9 @@ namespace BitTorrent // file4 // // + // Torrent A* (Torrent A in "strip root folder" mode) + // + // // Torrent B (singlefile) // // torrentB/ @@ -223,6 +226,7 @@ namespace BitTorrent // | | rootPath | contentPath | // |---|------------------------------|--------------------------------------------| // | A | /home/user/torrents/torrentA | /home/user/torrents/torrentA | + // | A*| | /home/user/torrents | // | B | /home/user/torrents/torrentB | /home/user/torrents/torrentB/subdir1/file1 | // | C | /home/user/torrents/file1 | /home/user/torrents/file1 | From 22178f9997d3840d36cd069d5ee4024af93c3901 Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Sat, 15 Apr 2017 17:21:24 +0300 Subject: [PATCH 4/4] Fix strip torrent root folder --- src/base/bittorrent/session.cpp | 11 +++++++++++ src/base/bittorrent/session.h | 3 +++ src/base/preferences.cpp | 10 ---------- src/base/preferences.h | 2 -- src/gui/addnewtorrentdialog.cpp | 6 +++--- src/gui/addnewtorrentdialog.ui | 12 ++++++------ src/gui/optionsdlg.cpp | 4 ++-- 7 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index 47972500c..c6a489933 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -244,6 +244,7 @@ Session::Session(QObject *parent) , m_additionalTrackers(BITTORRENT_SESSION_KEY("AdditionalTrackers")) , m_globalMaxRatio(BITTORRENT_SESSION_KEY("GlobalMaxRatio"), -1, [](qreal r) { return r < 0 ? -1. : r;}) , m_isAddTorrentPaused(BITTORRENT_SESSION_KEY("AddTorrentPaused"), false) + , m_isCreateTorrentSubfolder(BITTORRENT_SESSION_KEY("CreateTorrentSubfolder"), true) , m_isAppendExtensionEnabled(BITTORRENT_SESSION_KEY("AddExtensionToIncompleteFiles"), false) , m_refreshInterval(BITTORRENT_SESSION_KEY("RefreshInterval"), 1500) , m_isPreallocationEnabled(BITTORRENT_SESSION_KEY("Preallocation"), false) @@ -3253,6 +3254,16 @@ void Session::getPendingAlerts(std::vector &out, ulong time) #endif } +bool Session::isCreateTorrentSubfolder() const +{ + return m_isCreateTorrentSubfolder; +} + +void Session::setCreateTorrentSubfolder(bool value) +{ + m_isCreateTorrentSubfolder = value; +} + // Read alerts sent by the BitTorrent session void Session::readAlerts() { diff --git a/src/base/bittorrent/session.h b/src/base/bittorrent/session.h index 86c0a3973..0af2500ca 100644 --- a/src/base/bittorrent/session.h +++ b/src/base/bittorrent/session.h @@ -222,6 +222,8 @@ namespace BitTorrent void setPeXEnabled(bool enabled); bool isAddTorrentPaused() const; void setAddTorrentPaused(bool value); + bool isCreateTorrentSubfolder() const; + void setCreateTorrentSubfolder(bool value); bool isTrackerEnabled() const; void setTrackerEnabled(bool enabled); bool isAppendExtensionEnabled() const; @@ -539,6 +541,7 @@ namespace BitTorrent CachedSettingValue m_additionalTrackers; CachedSettingValue m_globalMaxRatio; CachedSettingValue m_isAddTorrentPaused; + CachedSettingValue m_isCreateTorrentSubfolder; CachedSettingValue m_isAppendExtensionEnabled; CachedSettingValue m_refreshInterval; CachedSettingValue m_isPreallocationEnabled; diff --git a/src/base/preferences.cpp b/src/base/preferences.cpp index 3f34c84b7..630dbe4f8 100644 --- a/src/base/preferences.cpp +++ b/src/base/preferences.cpp @@ -263,16 +263,6 @@ void Preferences::setLastLocationPath(const QString &path) setValue("Preferences/Downloads/LastLocationPath", Utils::Fs::fromNativePath(path)); } -bool Preferences::getTorrentCreateSubfolder() const -{ - return value("Preferences/Downloads/CreateSubfolder", true).toBool(); -} - -void Preferences::setTorrentCreateSubfolder(bool b) -{ - setValue("Preferences/Downloads/CreateSubfolder", b); -} - QVariantHash Preferences::getScanDirs() const { return value("Preferences/Downloads/ScanDirsV2").toHash(); diff --git a/src/base/preferences.h b/src/base/preferences.h index 4b06ae3d5..ec328f264 100644 --- a/src/base/preferences.h +++ b/src/base/preferences.h @@ -138,8 +138,6 @@ public: void setLastLocationPath(const QString &path); QVariantHash getScanDirs() const; void setScanDirs(const QVariantHash &dirs); - bool getTorrentCreateSubfolder() const; - void setTorrentCreateSubfolder(bool b); QString getScanDirsLastPath() const; void setScanDirsLastPath(const QString &path); bool isMailNotificationEnabled() const; diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index ff3d4c789..7cecb3ec7 100644 --- a/src/gui/addnewtorrentdialog.cpp +++ b/src/gui/addnewtorrentdialog.cpp @@ -96,7 +96,7 @@ AddNewTorrentDialog::AddNewTorrentDialog(QWidget *parent) connect(ui->savePathComboBox, SIGNAL(currentIndexChanged(int)), SLOT(onSavePathChanged(int))); connect(ui->browseButton, SIGNAL(clicked()), SLOT(browseButton_clicked())); ui->defaultSavePathCheckBox->setVisible(false); // Default path is selected by default - ui->createSubfolderComboBox->setChecked(Preferences::instance()->getTorrentCreateSubfolder()); + ui->createSubfolderCheckBox->setChecked(session->isCreateTorrentSubfolder()); ui->doNotDeleteTorrentCheckBox->setVisible(TorrentFileGuard::autoDeleteMode() != TorrentFileGuard::Never); @@ -627,7 +627,7 @@ void AddNewTorrentDialog::accept() BitTorrent::AddTorrentParams params; // TODO: Check if destination actually exists - params.skipChecking = ui->skip_check_cb->isChecked(); + params.skipChecking = ui->skipCheckingCheckBox->isChecked(); // Category params.category = ui->categoryComboBox->currentText(); @@ -640,7 +640,7 @@ void AddNewTorrentDialog::accept() params.filePriorities = m_contentModel->model()->getFilePriorities(); params.addPaused = !ui->startTorrentCheckBox->isChecked(); - params.createSubfolder = ui->createSubfolderComboBox->isChecked(); + params.createSubfolder = ui->createSubfolderCheckBox->isChecked(); QString savePath = ui->savePathComboBox->itemData(ui->savePathComboBox->currentIndex()).toString(); if (ui->comboTTM->currentIndex() != 1) { // 0 is Manual mode and 1 is Automatic mode. Handle all non 1 values as manual mode. diff --git a/src/gui/addnewtorrentdialog.ui b/src/gui/addnewtorrentdialog.ui index 5aff7281b..e010403b0 100644 --- a/src/gui/addnewtorrentdialog.ui +++ b/src/gui/addnewtorrentdialog.ui @@ -170,7 +170,7 @@ - + Skip hash check @@ -193,7 +193,7 @@ - + Start torrent @@ -203,7 +203,7 @@ - + Create subfolder @@ -305,8 +305,8 @@ 0 0 - 308 - 74 + 321 + 69 @@ -423,7 +423,7 @@ never_show_cb adv_button startTorrentCheckBox - skip_check_cb + skipCheckingCheckBox categoryComboBox defaultCategoryCheckbox scrollArea diff --git a/src/gui/optionsdlg.cpp b/src/gui/optionsdlg.cpp index 78f488bc7..03abb20be 100644 --- a/src/gui/optionsdlg.cpp +++ b/src/gui/optionsdlg.cpp @@ -516,7 +516,7 @@ void OptionsDialog::saveOptions() AddNewTorrentDialog::setEnabled(useAdditionDialog()); AddNewTorrentDialog::setTopLevel(m_ui->checkAdditionDialogFront->isChecked()); session->setAddTorrentPaused(addTorrentsInPause()); - pref->setTorrentCreateSubfolder(m_ui->checkCreateSubfolder->isChecked()); + session->setCreateTorrentSubfolder(m_ui->checkCreateSubfolder->isChecked()); ScanFoldersModel::instance()->removeFromFSWatcher(removedScanDirs); ScanFoldersModel::instance()->addToFSWatcher(addedScanDirs); ScanFoldersModel::instance()->makePersistent(); @@ -718,7 +718,7 @@ void OptionsDialog::loadOptions() m_ui->checkAdditionDialog->setChecked(AddNewTorrentDialog::isEnabled()); m_ui->checkAdditionDialogFront->setChecked(AddNewTorrentDialog::isTopLevel()); m_ui->checkStartPaused->setChecked(session->isAddTorrentPaused()); - m_ui->checkCreateSubfolder->setChecked(pref->getTorrentCreateSubfolder()); + m_ui->checkCreateSubfolder->setChecked(session->isCreateTorrentSubfolder()); const TorrentFileGuard::AutoDeleteMode autoDeleteMode = TorrentFileGuard::autoDeleteMode(); m_ui->deleteTorrentBox->setChecked(autoDeleteMode != TorrentFileGuard::Never); m_ui->deleteCancelledTorrentBox->setChecked(autoDeleteMode == TorrentFileGuard::Always);