From 4b2d8a7941bd75a54345bf748258de9c47acd8ed Mon Sep 17 00:00:00 2001 From: sledgehammer999 Date: Sat, 7 Nov 2015 20:44:53 +0200 Subject: [PATCH] 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());