Browse Source

Brand new torrent addition dialog

adaptive-webui-19844
Christophe Dumez 13 years ago
parent
commit
c502edf9e1
  1. 1
      Changelog
  2. 548
      src/addnewtorrentdialog.cpp
  3. 87
      src/addnewtorrentdialog.h
  4. 274
      src/addnewtorrentdialog.ui
  5. 69
      src/mainwindow.cpp
  6. 115
      src/misc.cpp
  7. 20
      src/misc.h
  8. 4
      src/preferences/preferences.h
  9. 3
      src/properties/propertieswidget.cpp
  10. 83
      src/qtlibtorrent/qbtsession.cpp
  11. 4
      src/qtlibtorrent/qbtsession.h
  12. 27
      src/qtlibtorrent/qtorrenthandle.cpp
  13. 12
      src/src.pro
  14. 811
      src/torrentadditiondlg.cpp
  15. 364
      src/torrentadditiondlg.ui
  16. 5
      src/torrentcreator/torrentcreatordlg.cpp
  17. 2
      src/torrentimportdlg.cpp
  18. 16
      src/torrentpersistentdata.h

1
Changelog

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
* Unreleased - Christophe Dumez <chris@qbittorrent.org> - v3.0.0
- FEATURE: Brand new torrent addition dialog
- FEATURE: Add the ability to choose the save path when using magnet links (mutoso)
- OTHER: Drop support for libtorrent v0.14.x
- OTHER: Drop support for Qt 4.5

548
src/addnewtorrentdialog.cpp

@ -0,0 +1,548 @@ @@ -0,0 +1,548 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2012 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
#include "addnewtorrentdialog.h"
#include "ui_addnewtorrentdialog.h"
#include "proplistdelegate.h"
#include "torrentcontentmodel.h"
#include "preferences.h"
#include "qinisettings.h"
#include "torrentpersistentdata.h"
#include "qbtsession.h"
#include "iconprovider.h"
#include <QString>
#include <QFile>
#include <QInputDialog>
#include <QUrl>
#include <QMenu>
#include <QMessageBox>
#include <QTimer>
#include <QFileDialog>
#include <libtorrent/version.hpp>
using namespace libtorrent;
AddNewTorrentDialog::AddNewTorrentDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::AddNewTorrentDialog),
m_contentModel(0),
m_contentDelegate(0),
m_isMagnet(false),
m_hasRenamedFile(false)
{
ui->setupUi(this);
Preferences pref;
ui->start_torrent_cb->setChecked(!pref.addTorrentsInPause());
ui->save_path_combo->addItem(misc::toDisplayPath(pref.getSavePath()));
loadSavePathHistory();
ui->save_path_combo->insertSeparator(ui->save_path_combo->count());
ui->save_path_combo->addItem(tr("Other...", "Other save path..."));
connect(ui->save_path_combo, SIGNAL(currentIndexChanged(int)), SLOT(onSavePathChanged(int)));
ui->default_save_path_cb->setVisible(false); // Default path is selected by default
// Signal / slots
connect(ui->adv_button, SIGNAL(clicked(bool)), SLOT(showAdvancedSettings(bool)));
// Load labels
QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
const QStringList customLabels = settings.value("TransferListFilters/customLabels", QStringList()).toStringList();
ui->label_combo->addItem("");
foreach (const QString& label, customLabels) {
ui->label_combo->addItem(label);
}
showAdvancedSettings(false);
QTimer::singleShot(0, this, SLOT(setdialogPosition()));
}
AddNewTorrentDialog::~AddNewTorrentDialog()
{
delete ui;
if (m_contentModel)
delete m_contentModel;
}
void AddNewTorrentDialog::showTorrent(const QString &torrent_path, const QString& from_url)
{
AddNewTorrentDialog dlg;
if (dlg.loadTorrent(torrent_path, from_url))
dlg.exec();
}
void AddNewTorrentDialog::showMagnet(const QString& link)
{
AddNewTorrentDialog dlg;
if (dlg.loadMagnet(link))
dlg.exec();
}
void AddNewTorrentDialog::showAdvancedSettings(bool show)
{
if (show) {
ui->adv_button->setText(QString::fromUtf8(""));
ui->settings_group->setVisible(true);
ui->info_group->setVisible(!m_isMagnet);
if (!m_isMagnet && (m_torrentInfo->num_files() > 1)) {
ui->content_tree->setVisible(true);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
} else {
ui->content_tree->setVisible(false);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
}
static_cast<QVBoxLayout*>(layout())->insertWidget(layout()->indexOf(ui->never_show_cb)+1, ui->adv_button);
} else {
ui->adv_button->setText(QString::fromUtf8(""));
ui->settings_group->setVisible(false);
ui->info_group->setVisible(false);
ui->buttonsHLayout->insertWidget(0, layout()->takeAt(layout()->indexOf(ui->never_show_cb)+1)->widget());
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
}
QTimer::singleShot(0, this, SLOT(relayout()));
}
bool AddNewTorrentDialog::loadTorrent(const QString& torrent_path, const QString& from_url)
{
m_isMagnet = false;
m_url = from_url;
if (torrent_path.startsWith("file://", Qt::CaseInsensitive))
m_filePath = QUrl::fromEncoded(torrent_path.toLocal8Bit()).toLocalFile();
else
m_filePath = torrent_path;
if (!QFile::exists(m_filePath)) {
QMessageBox::critical(0, tr("I/O Error"), tr("The torrent file does not exist."));
return false;
}
try {
m_torrentInfo = new torrent_info(m_filePath.toUtf8().data());
m_hash = misc::toQString(m_torrentInfo->info_hash());
} catch(const std::exception& e) {
QMessageBox::critical(0, tr("Invalid torrent"), tr("Failed to load the torrent: &1").arg(e.what()));
return false;
}
// Set dialog title
setWindowTitle(misc::toQString(m_torrentInfo->name()));
// Set torrent information
QString comment = misc::toQString(m_torrentInfo->comment());
ui->comment_lbl->setText(comment.replace('\n', ' '));
ui->date_lbl->setText(m_torrentInfo->creation_date() ? misc::toQString(*m_torrentInfo->creation_date()) : tr("Not available"));
updateDiskSpaceLabel();
#if LIBTORRENT_VERSION_MINOR >= 16
file_storage fs = m_torrentInfo->files();
#endif
// Populate m_filesList
for (int i = 0; i < m_torrentInfo->num_files(); ++i) {
#if LIBTORRENT_VERSION_MINOR >= 16
m_filesPath << misc::toQStringU(fs.file_path(m_torrentInfo->file_at(i)));
#else
m_filesPath << misc::toQStringU(m_torrentInfo->file_at(i).path.string());
#endif
}
// Prepare content tree
if (m_torrentInfo->num_files() > 1) {
m_contentModel = new TorrentContentModel(this);
connect(m_contentModel, SIGNAL(filteredFilesChanged()), SLOT(updateDiskSpaceLabel()));
ui->content_tree->setModel(m_contentModel);
ui->content_tree->hideColumn(PROGRESS);
m_contentDelegate = new PropListDelegate();
ui->content_tree->setItemDelegate(m_contentDelegate);
connect(ui->content_tree, SIGNAL(clicked(const QModelIndex&)), ui->content_tree, SLOT(edit(const QModelIndex&)));
connect(ui->content_tree, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayContentTreeMenu(const QPoint&)));
// List files in torrent
m_contentModel->setupModelData(*m_torrentInfo);
// Expand root folder
ui->content_tree->setExpanded(m_contentModel->index(0, 0), true);
ui->content_tree->header()->setResizeMode(0, QHeaderView::Stretch);
} else {
// Update save paths (append file name to them)
#if LIBTORRENT_VERSION_MINOR >= 16
QString single_file_relpath = misc::toQStringU(fs.file_path(m_torrentInfo->file_at(0)));
#else
QString single_file_relpath = misc::toQStringU(m_torrentInfo->file_at(0).path.string());
#endif
for (int i=0; i<ui->save_path_combo->count()-1; ++i) {
ui->save_path_combo->setItemText(i, QDir(ui->save_path_combo->itemText(i)).absoluteFilePath(single_file_relpath));
}
}
return true;
}
bool AddNewTorrentDialog::loadMagnet(const QString &magnet_uri)
{
m_isMagnet = true;
m_url = magnet_uri;
m_hash = misc::magnetUriToHash(m_url);
if (m_hash.isEmpty()) {
QMessageBox::critical(0, tr("Invalid magnet link"), tr("This magnet link was not recognized"));
return false;
}
// Set dialog title
QString torrent_name = misc::magnetUriToName(m_url);
setWindowTitle(torrent_name.isEmpty() ? tr("Magnet link") : torrent_name);
return true;
}
void AddNewTorrentDialog::saveSavePathHistory() const
{
QDir selected_save_path(ui->save_path_combo->itemData(ui->save_path_combo->currentIndex()).toString());
QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
// Get current history
QStringList history = settings.value("TorrentAdditionDlg/save_path_history").toStringList();
QList<QDir> history_dirs;
foreach(const QString dir, history)
history_dirs << QDir(dir);
if (!history_dirs.contains(selected_save_path)) {
// Add save path to history
history << selected_save_path.absolutePath();
// Limit list size
if (history.size() > 8)
history.removeFirst();
// Save history
settings.setValue("TorrentAdditionDlg/save_path_history", history);
}
}
// save_path is a folder, not an absolute file path
int AddNewTorrentDialog::indexOfSavePath(const QString &save_path)
{
QDir saveDir(save_path);
for(int i=0; i<ui->save_path_combo->count()-1; ++i) {
if (QDir(ui->save_path_combo->itemData(i).toString()) == saveDir)
return i;
}
return -1;
}
void AddNewTorrentDialog::updateFileNameInSavePaths(const QString &new_filename)
{
for(int i=0; i<ui->save_path_combo->count()-1; ++i) {
const QDir folder(ui->save_path_combo->itemData(i).toString());
ui->save_path_combo->setItemText(i, misc::toDisplayPath(folder.absoluteFilePath(new_filename)));
}
}
void AddNewTorrentDialog::updateDiskSpaceLabel()
{
Q_ASSERT(!m_isMagnet);
// Determine torrent size
qulonglong torrent_size = 0;
if (m_contentModel) {
const std::vector<int> priorities = m_contentModel->getFilesPriorities();
Q_ASSERT(priorities.size() == (uint) m_torrentInfo->num_files());
for (uint i=0; i<priorities.size(); ++i) {
if (priorities[i] > 0)
torrent_size += m_torrentInfo->file_at(i).size;
}
} else {
torrent_size = m_torrentInfo->total_size();
}
QString size_string = misc::friendlyUnit(torrent_size);
size_string += " (";
size_string += tr("Disk space: %1").arg(misc::friendlyUnit(misc::freeDiskSpaceOnPath(ui->save_path_combo->currentText())));
size_string += ")";
ui->size_lbl->setText(size_string);
}
void AddNewTorrentDialog::onSavePathChanged(int index)
{
static int old_index = 0;
static QDir defaultSaveDir(ui->save_path_combo->itemData(0).toString());
if (index == (ui->save_path_combo->count() - 1)) {
disconnect(ui->save_path_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(onSavePathChanged(int)));
// User is asking for a new save path
QString cur_save_path = ui->save_path_combo->itemText(old_index);
QString new_path, old_filename, new_filename;
if (m_torrentInfo && m_torrentInfo->num_files() == 1) {
misc::branchPath(cur_save_path, &old_filename);
new_path = QFileDialog::getSaveFileName(this, tr("Choose save path"), cur_save_path, QString(), 0, QFileDialog::DontConfirmOverwrite);
if (!new_path.isEmpty())
new_path = misc::branchPath(new_path, &new_filename);
qDebug() << "new_path: " << new_path;
qDebug() << "new_filename: " << new_filename;
} else {
if (!cur_save_path.isEmpty() && QDir(cur_save_path).exists())
new_path = QFileDialog::getExistingDirectory(this, tr("Choose save path"), cur_save_path);
else
new_path = QFileDialog::getExistingDirectory(this, tr("Choose save path"), QDir::homePath());
}
if (!new_path.isEmpty()) {
const int existing_index = indexOfSavePath(new_path);
if (existing_index >= 0)
ui->save_path_combo->setCurrentIndex(existing_index);
else {
// New path, prepend to combo box
if (!new_filename.isEmpty())
ui->save_path_combo->insertItem(0, misc::toDisplayPath(QDir(new_path).absoluteFilePath(new_filename)), new_path);
else
ui->save_path_combo->insertItem(0, misc::toDisplayPath(new_path), new_path);
ui->save_path_combo->setCurrentIndex(0);
}
// Update file name in all save_paths
if (!new_filename.isEmpty() && !misc::sameFileNames(old_filename, new_filename)) {
m_hasRenamedFile = true;
m_filesPath[0] = new_filename;
updateFileNameInSavePaths(new_filename);
}
} else {
// Restore index
ui->save_path_combo->setCurrentIndex(old_index);
}
connect(ui->save_path_combo, SIGNAL(currentIndexChanged(int)), SLOT(onSavePathChanged(int)));
}
// Toggle default save path setting checkbox visibility
ui->default_save_path_cb->setVisible(QDir(ui->save_path_combo->itemData(ui->save_path_combo->currentIndex()).toString()) != defaultSaveDir);
QTimer::singleShot(0, this, SLOT(relayout()));
// Remember index
old_index = ui->save_path_combo->currentIndex();
}
void AddNewTorrentDialog::relayout()
{
int min_width = minimumWidth();
setMinimumWidth(width());
adjustSize();
setMinimumWidth(min_width);
}
void AddNewTorrentDialog::renameSelectedFile()
{
const QModelIndexList selectedIndexes = ui->content_tree->selectionModel()->selectedRows(0);
Q_ASSERT(selectedIndexes.size() == 1);
const QModelIndex &index = selectedIndexes.first();
// Ask for new name
bool ok;
const QString new_name_last = QInputDialog::getText(this, tr("Rename the file"),
tr("New name:"), QLineEdit::Normal,
index.data().toString(), &ok);
if (ok && !new_name_last.isEmpty()) {
if (!misc::isValidFileSystemName(new_name_last)) {
QMessageBox::warning(this, tr("The file could not be renamed"),
tr("This file name contains forbidden characters, please choose a different one."),
QMessageBox::Ok);
return;
}
if (m_contentModel->getType(index) == TorrentContentModelItem::TFILE) {
// File renaming
const int file_index = m_contentModel->getFileIndex(index);
QString old_name = m_filesPath.at(file_index);
old_name.replace("\\", "/");
qDebug("Old name: %s", qPrintable(old_name));
QStringList path_items = old_name.split("/");
path_items.removeLast();
path_items << new_name_last;
QString new_name = path_items.join("/");
if (misc::sameFileNames(old_name, new_name)) {
qDebug("Name did not change");
return;
}
new_name = QDir::cleanPath(new_name);
qDebug("New name: %s", qPrintable(new_name));
// Check if that name is already used
for (int i=0; i<m_torrentInfo->num_files(); ++i) {
if (i == file_index) continue;
if (misc::sameFileNames(m_filesPath.at(i), new_name)) {
// Display error message
QMessageBox::warning(this, tr("The file could not be renamed"),
tr("This name is already in use in this folder. Please use a different name."),
QMessageBox::Ok);
return;
}
}
new_name = QDir::cleanPath(new_name);
qDebug("Renaming %s to %s", qPrintable(old_name), qPrintable(new_name));
// Rename file in files_path
m_filesPath.replace(file_index, new_name);
m_hasRenamedFile = true;
// Rename in torrent files model too
m_contentModel->setData(index, new_name_last);
} else {
// Folder renaming
QStringList path_items;
path_items << index.data().toString();
QModelIndex parent = m_contentModel->parent(index);
while(parent.isValid()) {
path_items.prepend(parent.data().toString());
parent = m_contentModel->parent(parent);
}
const QString old_path = path_items.join("/");
path_items.removeLast();
path_items << new_name_last;
QString new_path = path_items.join("/");
if (!new_path.endsWith("/")) new_path += "/";
// Check for overwriting
for (int i=0; i<m_torrentInfo->num_files(); ++i) {
const QString &current_name = m_filesPath.at(i);
#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
if (current_name.startsWith(new_path, Qt::CaseSensitive)) {
#else
if (current_name.startsWith(new_path, 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;
}
}
// Replace path in all files
for (int i=0; i<m_torrentInfo->num_files(); ++i) {
const QString &current_name = m_filesPath.at(i);
if (current_name.startsWith(old_path)) {
QString new_name = current_name;
new_name.replace(0, old_path.length(), new_path);
new_name = QDir::cleanPath(new_name);
qDebug("Rename %s to %s", qPrintable(current_name), qPrintable(new_name));
// Rename in files_path
m_filesPath.replace(i, new_name);
}
}
m_hasRenamedFile = true;
// Rename folder in torrent files model too
m_contentModel->setData(index, new_name_last);
}
}
}
void AddNewTorrentDialog::setdialogPosition()
{
move(QPoint(misc::screenCenter(this).x(), 0));
}
void AddNewTorrentDialog::loadSavePathHistory()
{
QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QDir default_save_path(Preferences().getSavePath());
// Load save path history
QStringList raw_path_history = settings.value("TorrentAdditionDlg/save_path_history").toStringList();
foreach (const QString &sp, raw_path_history) {
if (QDir(sp) != default_save_path)
ui->save_path_combo->addItem(misc::toDisplayPath(sp), sp);
}
}
void AddNewTorrentDialog::displayContentTreeMenu(const QPoint&) {
QMenu myFilesLlistMenu;
const QModelIndexList selectedRows = ui->content_tree->selectionModel()->selectedRows(0);
QAction *actRename = 0;
if (selectedRows.size() == 1 && m_torrentInfo->num_files() > 1) {
actRename = myFilesLlistMenu.addAction(IconProvider::instance()->getIcon("edit-rename"), tr("Rename..."));
myFilesLlistMenu.addSeparator();
}
QMenu subMenu;
subMenu.setTitle(tr("Priority"));
subMenu.addAction(ui->actionNot_downloaded);
subMenu.addAction(ui->actionNormal);
subMenu.addAction(ui->actionHigh);
subMenu.addAction(ui->actionMaximum);
myFilesLlistMenu.addMenu(&subMenu);
// Call menu
QAction *act = myFilesLlistMenu.exec(QCursor::pos());
if (act) {
if (act == actRename) {
renameSelectedFile();
} else {
int prio = prio::NORMAL;
if (act == ui->actionHigh)
prio = prio::HIGH;
else {
if (act == ui->actionMaximum) {
prio = prio::MAXIMUM;
} else {
if (act == ui->actionNot_downloaded)
prio = prio::IGNORED;
}
}
qDebug("Setting files priority");
foreach (const QModelIndex &index, selectedRows) {
qDebug("Setting priority(%d) for file at row %d", prio, index.row());
m_contentModel->setData(m_contentModel->index(index.row(), PRIORITY, index.parent()), prio);
}
}
}
}
void AddNewTorrentDialog::on_buttonBox_accepted()
{
Preferences pref;
// Save Temporary data about torrent
QString save_path = ui->save_path_combo->itemData(ui->save_path_combo->currentIndex()).toString();
TorrentTempData::setSavePath(m_hash, save_path);
if (ui->skip_check_cb->isChecked()) {
// TODO: Check if destination actually exists
TorrentTempData::setSeedingMode(m_hash, true);
}
// Label
const QString label = ui->label_combo->currentText();
if (!label.isEmpty())
TorrentTempData::setLabel(m_hash, label);
// Save file priorities
if (m_contentModel)
TorrentTempData::setFilesPriority(m_hash, m_contentModel->getFilesPriorities());
// Rename files if necessary
if (m_hasRenamedFile)
TorrentTempData::setFilesPath(m_hash, m_filesPath);
// Temporary override of addInPause setting
bool old_addInPause = pref.addTorrentsInPause();
pref.addTorrentsInPause(!ui->start_torrent_cb->isChecked());
pref.sync();
// Add torrent
if (m_isMagnet)
QBtSession::instance()->addMagnetUri(m_url, false);
else
QBtSession::instance()->addTorrent(m_filePath, false, m_url);
// Restore addInPause setting
pref.addTorrentsInPause(old_addInPause);
saveSavePathHistory();
// Save settings
pref.useAdditionDialog(!ui->never_show_cb->isChecked());
if (ui->default_save_path_cb->isVisible() && ui->default_save_path_cb->isChecked())
pref.setSavePath(ui->save_path_combo->itemData(ui->save_path_combo->currentIndex()).toString());
}

87
src/torrentadditiondlg.h → src/addnewtorrentdialog.h

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2006 Christophe Dumez
* Copyright (C) 2012 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -28,70 +28,59 @@ @@ -28,70 +28,59 @@
* Contact : chris@qbittorrent.org
*/
#ifndef TORRENTADDITION_H
#define TORRENTADDITION_H
#include <QStringList>
#include "ui_torrentadditiondlg.h"
#ifndef ADDNEWTORRENTDIALOG_H
#define ADDNEWTORRENTDIALOG_H
#include <QDialog>
#include <QUrl>
#include <libtorrent/torrent_info.hpp>
class TorrentContentFilterModel;
namespace Ui {
class AddNewTorrentDialog;
}
class TorrentContentModel;
class PropListDelegate;
class torrentAdditionDialog : public QDialog, private Ui_addTorrentDialog{
class AddNewTorrentDialog : public QDialog
{
Q_OBJECT
public:
torrentAdditionDialog(QWidget *parent);
~torrentAdditionDialog();
void showLoadMagnetURI(const QString& magnet_uri);
void showLoadTorrent(const QString& filePath, const QString& fromUrl = QString());
QString getCurrentTruncatedSavePath(QString* root_folder_or_file_name = 0) const;
QString getTruncatedSavePath(QString save_path, QString* root_folder_or_file_name = 0) const;
bool allFiltered() const;
~AddNewTorrentDialog();
public slots:
void displayContentListMenu(const QPoint&);
void renameSelectedFile();
void updateDiskSpaceLabels();
void on_browseButton_clicked();
void on_CancelButton_clicked();
void savePiecesPriorities();
void on_OkButton_clicked();
void hideTorrentContent();
void limitDialogWidth();
void saveTruncatedPathHistory();
void loadSavePathHistory();
void updateLabelInSavePath(QString label);
void updateSavePathCurrentText();
void resetComboLabelIndex(QString text);
static void showTorrent(const QString& torrent_path, const QString& from_url = QString());
static void showMagnet(const QString& torrent_link);
protected:
void closeEvent(QCloseEvent *event);
private slots:
void showAdvancedSettings(bool show);
void displayContentTreeMenu(const QPoint&);
void on_buttonBox_accepted();
void updateDiskSpaceLabel();
void onSavePathChanged(int);
void relayout();
void renameSelectedFile();
void setdialogPosition();
private:
void readSettings();
void saveSettings();
explicit AddNewTorrentDialog(QWidget *parent = 0);
bool loadTorrent(const QString& torrent_path, const QString& from_url);
bool loadMagnet(const QString& magnet_uri);
void loadSavePathHistory();
void saveSavePathHistory() const;
int indexOfSavePath(const QString& save_path);
void updateFileNameInSavePaths(const QString& new_filename);
private:
QString m_fileName;
QString m_hash;
Ui::AddNewTorrentDialog *ui;
TorrentContentModel *m_contentModel;
PropListDelegate *m_contentDelegate;
bool m_isMagnet;
QString m_filePath;
QString m_fromUrl;
QString m_defaultSavePath;
QString m_oldLabel;
bool m_appendLabelToSavePath;
TorrentContentFilterModel *m_propListModel;
PropListDelegate *m_propListDelegate;
unsigned int m_nbFiles;
QString m_url;
QString m_hash;
boost::intrusive_ptr<libtorrent::torrent_info> m_torrentInfo;
QStringList m_filesPath;
bool m_isMagnet;
int m_hiddenHeight;
QStringList m_pathHistory;
bool m_showContentList;
bool m_hasRenamedFile;
};
#endif
#endif // ADDNEWTORRENTDIALOG_H

274
src/addnewtorrentdialog.ui

@ -0,0 +1,274 @@ @@ -0,0 +1,274 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AddNewTorrentDialog</class>
<widget class="QDialog" name="AddNewTorrentDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>414</width>
<height>590</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>400</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>800</width>
<height>16777215</height>
</size>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Save as</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QComboBox" name="save_path_combo">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="default_save_path_cb">
<property name="text">
<string>Set as default save path</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="never_show_cb">
<property name="text">
<string>Never show again</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="adv_button">
<property name="text">
<string>▼</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="settings_group">
<property name="title">
<string>Torrent settings</string>
</property>
<layout class="QGridLayout" name="gridLayout_3" columnstretch="1,1">
<item row="0" column="0">
<widget class="QCheckBox" name="start_torrent_cb">
<property name="text">
<string>Start torrent</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,1">
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Label:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="label_combo">
<property name="editable">
<bool>true</bool>
</property>
<property name="insertPolicy">
<enum>QComboBox::InsertAtTop</enum>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="skip_check_cb">
<property name="text">
<string>Skip hash check</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="info_group">
<property name="title">
<string>Torrent Information</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0" columnstretch="0,1">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Size:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="size_lbl">
<property name="text">
<string notr="true">xx GB (xx GB available)</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Comment:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="comment_lbl">
<property name="text">
<string notr="true">comment</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Date:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="date_lbl">
<property name="text">
<string notr="true">02/03/2012 20:30</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTreeView" name="content_tree">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="headerStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="buttonsHLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
<action name="actionNormal">
<property name="text">
<string>Normal</string>
</property>
</action>
<action name="actionHigh">
<property name="text">
<string>High</string>
</property>
</action>
<action name="actionMaximum">
<property name="text">
<string>Maximum</string>
</property>
</action>
<action name="actionNot_downloaded">
<property name="text">
<string>Do not download</string>
</property>
</action>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>AddNewTorrentDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>AddNewTorrentDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

69
src/mainwindow.cpp

@ -50,7 +50,7 @@ @@ -50,7 +50,7 @@
#include "misc.h"
#include "torrentcreatordlg.h"
#include "downloadfromurldlg.h"
#include "torrentadditiondlg.h"
#include "addnewtorrentdialog.h"
#include "searchengine.h"
#include "rss_imp.h"
#include "qbtsession.h"
@ -875,22 +875,16 @@ void MainWindow::dropEvent(QDropEvent *event) { @@ -875,22 +875,16 @@ void MainWindow::dropEvent(QDropEvent *event) {
file = misc::bcLinkToMagnet(file);
}
if (file.startsWith("magnet:", Qt::CaseInsensitive)) {
if (useTorrentAdditionDialog) {
torrentAdditionDialog *dialog = new torrentAdditionDialog(this);
dialog->showLoadMagnetURI(file);
} else {
if (useTorrentAdditionDialog)
AddNewTorrentDialog::showMagnet(file);
else
QBtSession::instance()->addMagnetUri(file);
}
continue;
}
// Local file
if (useTorrentAdditionDialog) {
torrentAdditionDialog *dialog = new torrentAdditionDialog(this);
if (file.startsWith("file:", Qt::CaseInsensitive))
file = QUrl(file).toLocalFile();
dialog->showLoadTorrent(file);
}else{
QBtSession::instance()->addTorrent(file);
} else {
// Local file
if (useTorrentAdditionDialog)
AddNewTorrentDialog::showTorrent(file);
else
QBtSession::instance()->addTorrent(file);
}
}
}
@ -925,12 +919,10 @@ void MainWindow::on_actionOpen_triggered() { @@ -925,12 +919,10 @@ void MainWindow::on_actionOpen_triggered() {
const bool useTorrentAdditionDialog = pref.useAdditionDialog();
const uint listSize = pathsList.size();
for (uint i=0; i<listSize; ++i) {
if (useTorrentAdditionDialog) {
torrentAdditionDialog *dialog = new torrentAdditionDialog(this);
dialog->showLoadTorrent(pathsList.at(i));
}else{
if (useTorrentAdditionDialog)
AddNewTorrentDialog::showTorrent(pathsList.at(i));
else
QBtSession::instance()->addTorrent(pathsList.at(i));
}
}
// Save last dir to remember it
QStringList top_dir = pathsList.at(0).split(QDir::separator());
@ -960,19 +952,15 @@ void MainWindow::processParams(const QStringList& params) { @@ -960,19 +952,15 @@ void MainWindow::processParams(const QStringList& params) {
param = misc::bcLinkToMagnet(param);
}
if (param.startsWith("magnet:", Qt::CaseInsensitive)) {
if (useTorrentAdditionDialog) {
torrentAdditionDialog *dialog = new torrentAdditionDialog(this);
dialog->showLoadMagnetURI(param);
} else {
if (useTorrentAdditionDialog)
AddNewTorrentDialog::showMagnet(param);
else
QBtSession::instance()->addMagnetUri(param);
}
} else {
if (useTorrentAdditionDialog) {
torrentAdditionDialog *dialog = new torrentAdditionDialog(this);
dialog->showLoadTorrent(param);
}else{
if (useTorrentAdditionDialog)
AddNewTorrentDialog::showTorrent(param);
else
QBtSession::instance()->addTorrent(param);
}
}
}
}
@ -985,12 +973,10 @@ void MainWindow::addTorrent(QString path) { @@ -985,12 +973,10 @@ void MainWindow::addTorrent(QString path) {
void MainWindow::processDownloadedFiles(QString path, QString url) {
QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
const bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool();
if (useTorrentAdditionDialog) {
torrentAdditionDialog *dialog = new torrentAdditionDialog(this);
dialog->showLoadTorrent(path, url);
}else{
if (useTorrentAdditionDialog)
AddNewTorrentDialog::showTorrent(path, url);
else
QBtSession::instance()->addTorrent(path, false, url);
}
}
void MainWindow::optionsSaved() {
@ -1164,15 +1150,12 @@ void MainWindow::downloadFromURLList(const QStringList& url_list) { @@ -1164,15 +1150,12 @@ void MainWindow::downloadFromURLList(const QStringList& url_list) {
url = misc::bcLinkToMagnet(url);
}
if (url.startsWith("magnet:", Qt::CaseInsensitive)) {
if (useTorrentAdditionDialog) {
torrentAdditionDialog *dialog = new torrentAdditionDialog(this);
dialog->showLoadMagnetURI(url);
} else {
if (useTorrentAdditionDialog)
AddNewTorrentDialog::showMagnet(url);
else
QBtSession::instance()->addMagnetUri(url);
}
} else {
} else
QBtSession::instance()->downloadFromUrl(url);
}
}
}

115
src/misc.cpp

@ -408,67 +408,6 @@ QString misc::fixFileNames(QString path) { @@ -408,67 +408,6 @@ QString misc::fixFileNames(QString path) {
return parts.join("/");
}
QString misc::truncateRootFolder(boost::intrusive_ptr<torrent_info> t) {
if (t->num_files() == 1) {
// Single file torrent
#if LIBTORRENT_VERSION_MINOR > 15
QString path = QString::fromUtf8(t->file_at(0).path.c_str());
#else
QString path = QString::fromUtf8(t->file_at(0).path.string().c_str());
#endif
// Remove possible subfolders
path = fixFileNames(fileName(path));
t->rename_file(0, path.toUtf8().data());
return QString();
}
QString root_folder;
for (int i=0; i<t->num_files(); ++i) {
#if LIBTORRENT_VERSION_MINOR > 15
QString path = QString::fromUtf8(t->file_at(i).path.c_str());
#else
QString path = QString::fromUtf8(t->file_at(i).path.string().c_str());
#endif
QStringList path_parts = path.split("/", QString::SkipEmptyParts);
if (path_parts.size() > 1) {
root_folder = path_parts.takeFirst();
}
path = fixFileNames(path_parts.join("/"));
t->rename_file(i, path.toUtf8().data());
}
return root_folder;
}
QString misc::truncateRootFolder(libtorrent::torrent_handle h) {
torrent_info t = h.get_torrent_info();
if (t.num_files() == 1) {
// Single file torrent
// Remove possible subfolders
#if LIBTORRENT_VERSION_MINOR > 15
QString path = QString::fromUtf8(t.file_at(0).path.c_str());
#else
QString path = QString::fromUtf8(t.file_at(0).path.string().c_str());
#endif
path = fixFileNames(fileName(path));
t.rename_file(0, path.toUtf8().data());
return QString();
}
QString root_folder;
for (int i=0; i<t.num_files(); ++i) {
#if LIBTORRENT_VERSION_MINOR > 15
QString path = QString::fromUtf8(t.file_at(i).path.c_str());
#else
QString path = QString::fromUtf8(t.file_at(i).path.string().c_str());
#endif
QStringList path_parts = path.split("/", QString::SkipEmptyParts);
if (path_parts.size() > 1) {
root_folder = path_parts.takeFirst();
}
path = fixFileNames(path_parts.join("/"));
h.rename_file(i, path.toUtf8().data());
}
return root_folder;
}
bool misc::sameFiles(const QString &path1, const QString &path2) {
QFile f1(path1), f2(path2);
if (!f1.exists() || !f2.exists()) return false;
@ -837,21 +776,27 @@ bool misc::isValidTorrentFile(const QString &torrent_path) { @@ -837,21 +776,27 @@ bool misc::isValidTorrentFile(const QString &torrent_path) {
return true;
}
/**
* Returns a path constructed from all the elements of file_path except the last.
* A typical use is to obtain the parent path for a path supplied by the user.
*/
QString misc::branchPath(QString file_path, bool uses_slashes)
QString misc::branchPath(const QString& file_path, QString* removed)
{
if (!uses_slashes)
file_path.replace("\\", "/");
Q_ASSERT(!file_path.contains("\\"));
if (file_path.endsWith("/"))
file_path.chop(1); // Remove trailing slash
qDebug() << Q_FUNC_INFO << "before:" << file_path;
if (file_path.contains("/"))
return file_path.left(file_path.lastIndexOf('/'));
return "";
QString ret = file_path;
if (ret.endsWith("/") || ret.endsWith("\\"))
ret.chop(1);
const int slashIndex = ret.lastIndexOf(QRegExp("[/\\\\]"));
if (slashIndex >= 0) {
if (removed)
*removed = ret.mid(slashIndex + 1);
ret = ret.left(slashIndex);
}
return ret;
}
bool misc::sameFileNames(const QString &first, const QString &second)
{
#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
return QString::compare(first, second, Qt::CaseSensitive) == 0;
#else
return QString::compare(first, second, Qt::CaseInsensitive) == 0;
#endif
}
bool misc::isUrl(const QString &s)
@ -929,3 +874,23 @@ QString misc::parseHtmlLinks(const QString &raw_text) @@ -929,3 +874,23 @@ QString misc::parseHtmlLinks(const QString &raw_text)
return result;
}
#if LIBTORRENT_VERSION_MINOR < 16
QString misc::toQString(const boost::posix_time::ptime& boostDate) {
if (boostDate.is_not_a_date_time()) return "";
struct std::tm tm;
try {
tm = boost::posix_time::to_tm(boostDate);
} catch(std::exception e) {
return "";
}
const time_t t = mktime(&tm);
const QDateTime dt = QDateTime::fromTime_t(t);
return dt.toString(Qt::DefaultLocaleLongDate);
}
#else
QString misc::toQString(time_t t)
{
return QDateTime::fromTime_t(t).toString(Qt::DefaultLocaleLongDate);
}
#endif

20
src/misc.h

@ -78,6 +78,15 @@ public: @@ -78,6 +78,15 @@ public:
return QString(out);
}
static inline QString toDisplayPath(const QString& path) {
#if defined(Q_WS_WIN) || defined(Q_OS_OS2)
QString ret = path;
return ret.replace("/", "\\");
#else
return path;
#endif
}
static inline QString file_extension(const QString &filename) {
QString extension;
int point_index = filename.lastIndexOf(".");
@ -95,8 +104,6 @@ public: @@ -95,8 +104,6 @@ public:
static quint64 computePathSize(QString path);
static QString truncateRootFolder(boost::intrusive_ptr<libtorrent::torrent_info> t);
static QString truncateRootFolder(libtorrent::torrent_handle h);
static QString fixFileNames(QString path);
static QString updateLabelInSavePath(QString defaultSavePath, QString save_path, const QString &old_label, const QString &new_label);
@ -127,7 +134,8 @@ public: @@ -127,7 +134,8 @@ public:
// value must be given in bytes
static QString friendlyUnit(qreal val);
static bool isPreviewable(QString extension);
static QString branchPath(QString file_path, bool uses_slashes=false);
static QString branchPath(const QString& file_path, QString* removed = 0);
static bool sameFileNames(const QString& first, const QString& second);
static QString fileName(QString file_path);
static QString magnetUriToName(QString magnet_uri);
static QString magnetUriToHash(QString magnet_uri);
@ -145,6 +153,12 @@ public: @@ -145,6 +153,12 @@ public:
static QList<bool> boolListfromStringList(const QStringList &l);
static bool isValidTorrentFile(const QString &path);
#if LIBTORRENT_VERSION_MINOR < 16
static QString toQString(const boost::posix_time::ptime& boostDate);
#else
static QString toQString(time_t t);
#endif
};
// Trick to get a portable sleep() function

4
src/preferences/preferences.h

@ -242,11 +242,11 @@ public: @@ -242,11 +242,11 @@ public:
}
bool useAdditionDialog() const {
return value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), false).toBool();
return value(QString::fromUtf8("Preferences/Downloads/NewAdditionDialog"), true).toBool();
}
void useAdditionDialog(bool b) {
setValue("Preferences/Downloads/AdditionDialog", b);
setValue("Preferences/Downloads/NewAdditionDialog", b);
}
bool addTorrentsInPause() const {

3
src/properties/propertieswidget.cpp

@ -680,8 +680,7 @@ void PropertiesWidget::on_changeSavePathButton_clicked() { @@ -680,8 +680,7 @@ void PropertiesWidget::on_changeSavePathButton_clicked() {
QString save_path_dir = new_path.replace("\\", "/");
QString new_file_name;
if (h.has_metadata() && h.num_files() == 1) {
new_file_name = misc::fileName(save_path_dir); // New file name
save_path_dir = misc::branchPath(save_path_dir, true); // Skip file name
save_path_dir = misc::branchPath(save_path_dir, &new_file_name); // Skip file name
}
QDir savePath(misc::expandPath(save_path_dir));
// Actually move storage

83
src/qtlibtorrent/qbtsession.cpp

@ -152,7 +152,7 @@ static bool smartRemoveEmptyFolderTree(const QString& dir_path) @@ -152,7 +152,7 @@ static bool smartRemoveEmptyFolderTree(const QString& dir_path)
// Main constructor
QBtSession::QBtSession()
: m_scanFolders(ScanFoldersModel::instance(this)),
preAllocateAll(false), addInPause(false), global_ratio_limit(-1),
preAllocateAll(false), global_ratio_limit(-1),
LSDEnabled(false),
DHTEnabled(false), current_dht_port(0), queueingEnabled(false),
torrentExport(false)
@ -319,10 +319,6 @@ void QBtSession::handleDownloadFailure(QString url, QString reason) { @@ -319,10 +319,6 @@ void QBtSession::handleDownloadFailure(QString url, QString reason) {
savepathLabel_fromurl.remove(qurl);
}
void QBtSession::startTorrentsInPause(bool b) {
addInPause = b;
}
void QBtSession::setQueueingEnabled(bool enable) {
if (queueingEnabled != enable) {
qDebug("Queueing system is changing state...");
@ -354,7 +350,6 @@ void QBtSession::configureSession() { @@ -354,7 +350,6 @@ void QBtSession::configureSession() {
setAppendLabelToSavePath(pref.appendTorrentLabel());
setAppendqBExtension(pref.useIncompleteFilesExtension());
preAllocateAllFiles(pref.preAllocateAllFiles());
startTorrentsInPause(pref.addTorrentsInPause());
// * Export Dir
const bool newTorrentExport = pref.isTorrentExportEnabled();
if (torrentExport != newTorrentExport) {
@ -929,6 +924,7 @@ void QBtSession::loadTorrentSettings(QTorrentHandle& h) { @@ -929,6 +924,7 @@ void QBtSession::loadTorrentSettings(QTorrentHandle& h) {
}
QTorrentHandle QBtSession::addMagnetUri(QString magnet_uri, bool resumed) {
Preferences pref;
QTorrentHandle h;
const QString hash(misc::magnetUriToHash(magnet_uri));
if (hash.isEmpty()) {
@ -999,7 +995,7 @@ QTorrentHandle QBtSession::addMagnetUri(QString magnet_uri, bool resumed) { @@ -999,7 +995,7 @@ QTorrentHandle QBtSession::addMagnetUri(QString magnet_uri, bool resumed) {
if (!resumed) {
loadTorrentTempData(h, savePath, true);
}
if (!addInPause || (Preferences().useAdditionDialog())) {
if (!pref.addTorrentsInPause()) {
// Start torrent because it was added in paused state
h.resume();
}
@ -1012,6 +1008,7 @@ QTorrentHandle QBtSession::addMagnetUri(QString magnet_uri, bool resumed) { @@ -1012,6 +1008,7 @@ QTorrentHandle QBtSession::addMagnetUri(QString magnet_uri, bool resumed) {
// Add a torrent to the Bittorrent session
QTorrentHandle QBtSession::addTorrent(QString path, bool fromScanDir, QString from_url, bool resumed) {
QTorrentHandle h;
Preferences pref;
// Check if BT_backup directory exists
const QDir torrentBackup(misc::BTBackupLocation());
@ -1102,9 +1099,6 @@ QTorrentHandle QBtSession::addTorrent(QString path, bool fromScanDir, QString fr @@ -1102,9 +1099,6 @@ QTorrentHandle QBtSession::addTorrent(QString path, bool fromScanDir, QString fr
}
// Actually add the torrent
QString root_folder = misc::truncateRootFolder(t);
qDebug("Truncated root folder: %s", qPrintable(root_folder));
add_torrent_params p = initializeAddTorrentParams(hash);
p.ti = t;
@ -1139,21 +1133,17 @@ QTorrentHandle QBtSession::addTorrent(QString path, bool fromScanDir, QString fr @@ -1139,21 +1133,17 @@ QTorrentHandle QBtSession::addTorrent(QString path, bool fromScanDir, QString fr
// Enforcing the save path defined before URL download (from RSS for example)
QPair<QString, QString> savePath_label = savepathLabel_fromurl.take(QUrl::fromEncoded(from_url.toUtf8()));
if (savePath_label.first.isEmpty())
savePath = getSavePath(hash, fromScanDir, path, root_folder);
savePath = getSavePath(hash, fromScanDir, path);
else
savePath = savePath_label.first;
// Remember label
TorrentTempData::setLabel(hash, savePath_label.second);
} else {
savePath = getSavePath(hash, fromScanDir, path, root_folder);
savePath = getSavePath(hash, fromScanDir, path);
}
if (!defaultTempPath.isEmpty() && !TorrentPersistentData::isSeed(hash) && resumed) {
qDebug("addTorrent::Temp folder is enabled.");
QString torrent_tmp_path = defaultTempPath.replace("\\", "/");
if (!root_folder.isEmpty()) {
if (!torrent_tmp_path.endsWith("/")) torrent_tmp_path += "/";
torrent_tmp_path += root_folder;
}
p.save_path = torrent_tmp_path.toUtf8().constData();
// Check if save path exists, creating it otherwise
if (!QDir(torrent_tmp_path).exists()) QDir().mkpath(torrent_tmp_path);
@ -1178,8 +1168,6 @@ QTorrentHandle QBtSession::addTorrent(QString path, bool fromScanDir, QString fr @@ -1178,8 +1168,6 @@ QTorrentHandle QBtSession::addTorrent(QString path, bool fromScanDir, QString fr
QFile::remove(path);
return h;
}
// Remember root folder
TorrentPersistentData::setRootFolder(hash, root_folder);
// If temp path is enabled, move torrent
// XXX: The torrent is moved after the torrent_checked_alert
@ -1213,7 +1201,7 @@ QTorrentHandle QBtSession::addTorrent(QString path, bool fromScanDir, QString fr @@ -1213,7 +1201,7 @@ QTorrentHandle QBtSession::addTorrent(QString path, bool fromScanDir, QString fr
exportTorrentFile(h);
}
if (!fastResume && (!addInPause || (Preferences().useAdditionDialog() && !fromScanDir))) {
if (!fastResume && !pref.addTorrentsInPause()) {
// Start torrent because it was added in paused state
h.resume();
}
@ -1229,19 +1217,10 @@ QTorrentHandle QBtSession::addTorrent(QString path, bool fromScanDir, QString fr @@ -1229,19 +1217,10 @@ QTorrentHandle QBtSession::addTorrent(QString path, bool fromScanDir, QString fr
else
addConsoleMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(from_url));
}else{
#if defined(Q_WS_WIN) || defined(Q_OS_OS2)
QString displayed_path = path;
displayed_path.replace("/", "\\");
if (fastResume)
addConsoleMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(displayed_path));
addConsoleMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(misc::toDisplayPath(path)));
else
addConsoleMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(displayed_path));
#else
if (fastResume)
addConsoleMessage(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(path));
else
addConsoleMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(path));
#endif
addConsoleMessage(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(misc::toDisplayPath(path)));
}
// Send torrent addition signal
@ -1794,12 +1773,7 @@ void QBtSession::setDefaultTempPath(QString temppath) { @@ -1794,12 +1773,7 @@ void QBtSession::setDefaultTempPath(QString temppath) {
QTorrentHandle h = QTorrentHandle(*torrentIT);
if (!h.is_valid()) continue;
if (!h.is_seed()) {
QString root_folder = TorrentPersistentData::getRootFolder(h.hash());
QString torrent_tmp_path = temppath.replace("\\", "/");
if (!root_folder.isEmpty()) {
if (!torrent_tmp_path.endsWith("/")) torrent_tmp_path += "/";
torrent_tmp_path += root_folder;
}
qDebug("Moving torrent to its temp save path: %s", qPrintable(torrent_tmp_path));
h.move_storage(torrent_tmp_path);
}
@ -2391,26 +2365,7 @@ void QBtSession::readAlerts() { @@ -2391,26 +2365,7 @@ void QBtSession::readAlerts() {
// Append .!qB to incomplete files
if (appendqBExtension)
appendqBextensionToTorrent(h, true);
// Truncate root folder
const QString root_folder = misc::truncateRootFolder(p->handle);
TorrentPersistentData::setRootFolder(h.hash(), root_folder);
qDebug() << "magnet root folder is:" << root_folder;
// Move to a subfolder corresponding to the torrent root folder if necessary
if (!root_folder.isEmpty()) {
if (!h.is_seed() && !defaultTempPath.isEmpty()) {
qDebug("Incomplete torrent in temporary folder case");
QString torrent_tmp_path = defaultTempPath.replace("\\", "/");
if (!torrent_tmp_path.endsWith("/")) torrent_tmp_path += "/";
torrent_tmp_path += root_folder;
qDebug() << "Moving torrent to" << torrent_tmp_path;
h.move_storage(torrent_tmp_path);
} else {
qDebug() << "Incomplete torrent in destination folder case";
QString save_path = h.save_path();
h.move_storage(QDir(save_path).absoluteFilePath(root_folder));
}
}
emit metadataReceived(h);
if (h.is_paused()) {
// XXX: Unfortunately libtorrent-rasterbar does not send a torrent_paused_alert
@ -2570,12 +2525,7 @@ void QBtSession::readAlerts() { @@ -2570,12 +2525,7 @@ void QBtSession::readAlerts() {
const QDir save_dir(getSavePath(h.hash()));
if (current_dir == save_dir) {
qDebug("Moving the torrent to the temp directory...");
QString root_folder = TorrentPersistentData::getRootFolder(hash);
QString torrent_tmp_path = defaultTempPath.replace("\\", "/");
if (!root_folder.isEmpty()) {
if (!torrent_tmp_path.endsWith("/")) torrent_tmp_path += "/";
torrent_tmp_path += root_folder;
}
h.move_storage(torrent_tmp_path);
}
}
@ -2617,7 +2567,7 @@ session_status QBtSession::getSessionStatus() const { @@ -2617,7 +2567,7 @@ session_status QBtSession::getSessionStatus() const {
return s->status();
}
QString QBtSession::getSavePath(const QString &hash, bool fromScanDir, QString filePath, QString root_folder) {
QString QBtSession::getSavePath(const QString &hash, bool fromScanDir, QString filePath) {
QString savePath;
if (TorrentTempData::hasTempData(hash)) {
savePath = TorrentTempData::getSavePath(hash);
@ -2635,14 +2585,12 @@ QString QBtSession::getSavePath(const QString &hash, bool fromScanDir, QString f @@ -2635,14 +2585,12 @@ QString QBtSession::getSavePath(const QString &hash, bool fromScanDir, QString f
} else {
savePath = TorrentPersistentData::getSavePath(hash);
qDebug("SavePath got from persistant data is %s", qPrintable(savePath));
bool append_root_folder = false;
if (savePath.isEmpty()) {
if (fromScanDir && m_scanFolders->downloadInTorrentFolder(filePath)) {
savePath = QFileInfo(filePath).dir().path();
} else {
savePath = defaultSavePath;
}
append_root_folder = true;
}
if (!fromScanDir && appendLabelToSavePath) {
const QString label = TorrentPersistentData::getLabel(hash);
@ -2651,12 +2599,6 @@ QString QBtSession::getSavePath(const QString &hash, bool fromScanDir, QString f @@ -2651,12 +2599,6 @@ QString QBtSession::getSavePath(const QString &hash, bool fromScanDir, QString f
savePath = misc::updateLabelInSavePath(defaultSavePath, savePath, "", label);
}
}
if (append_root_folder && !root_folder.isEmpty()) {
// Append torrent root folder to the save path
savePath = QDir(savePath).absoluteFilePath(root_folder);
qDebug("Torrent root folder is %s", qPrintable(root_folder));
TorrentPersistentData::saveSavePath(hash, savePath);
}
qDebug("getSavePath, got save_path from persistent data: %s", qPrintable(savePath));
}
// Clean path
@ -2702,6 +2644,7 @@ void QBtSession::downloadUrlAndSkipDialog(QString url, QString save_path, QStrin @@ -2702,6 +2644,7 @@ void QBtSession::downloadUrlAndSkipDialog(QString url, QString save_path, QStrin
// Add to Bittorrent session the downloaded torrent file
void QBtSession::processDownloadedFile(QString url, QString file_path) {
Preferences pref;
const int index = url_skippingDlg.indexOf(QUrl::fromEncoded(url.toUtf8()));
if (index < 0) {
// Add file to torrent download list
@ -2723,7 +2666,7 @@ void QBtSession::processDownloadedFile(QString url, QString file_path) { @@ -2723,7 +2666,7 @@ void QBtSession::processDownloadedFile(QString url, QString file_path) {
url_skippingDlg.removeAt(index);
QTorrentHandle h = addTorrent(file_path, false, url, false);
// Pause torrent if necessary
if (h.is_valid() && addInPause && Preferences().useAdditionDialog())
if (h.is_valid() && pref.addTorrentsInPause() && Preferences().useAdditionDialog())
h.pause();
}
}

4
src/qtlibtorrent/qbtsession.h

@ -141,7 +141,6 @@ public slots: @@ -141,7 +141,6 @@ public slots:
void setDHTPort(int dht_port);
void setProxySettings(libtorrent::proxy_settings proxySettings);
void setSessionSettings(const libtorrent::session_settings &sessionSettings);
void startTorrentsInPause(bool b);
void setDefaultTempPath(QString temppath);
void setAppendLabelToSavePath(bool append);
void appendLabelToTorrentSavePath(const QTorrentHandle &h);
@ -168,7 +167,7 @@ public slots: @@ -168,7 +167,7 @@ public slots:
void recursiveTorrentDownload(const QTorrentHandle &h);
private:
QString getSavePath(const QString &hash, bool fromScanDir = false, QString filePath = QString::null, QString root_folder=QString::null);
QString getSavePath(const QString &hash, bool fromScanDir = false, QString filePath = QString::null);
bool loadFastResumeData(const QString &hash, std::vector<char> &buf);
void loadTorrentSettings(QTorrentHandle &h);
void loadTorrentTempData(QTorrentHandle &h, QString savePath, bool magnet);
@ -235,7 +234,6 @@ private: @@ -235,7 +234,6 @@ private:
QStringList peerBanMessages;
// Settings
bool preAllocateAll;
bool addInPause;
qreal global_ratio_limit;
int high_ratio_action;
bool LSDEnabled;

27
src/qtlibtorrent/qtorrenthandle.cpp

@ -54,21 +54,6 @@ @@ -54,21 +54,6 @@
using namespace libtorrent;
using namespace std;
#if LIBTORRENT_VERSION_MINOR < 16
static QString boostTimeToQString(const boost::posix_time::ptime &boostDate) {
if (boostDate.is_not_a_date_time()) return "";
struct std::tm tm;
try {
tm = boost::posix_time::to_tm(boostDate);
} catch(std::exception e) {
return "";
}
const time_t t = mktime(&tm);
const QDateTime dt = QDateTime::fromTime_t(t);
return dt.toString(Qt::DefaultLocaleLongDate);
}
#endif
static QPair<int, int> get_file_extremity_pieces(const torrent_info& t, int file_index)
{
const int num_pieces = t.num_pieces();
@ -109,15 +94,10 @@ QString QTorrentHandle::name() const { @@ -109,15 +94,10 @@ QString QTorrentHandle::name() const {
QString QTorrentHandle::creation_date() const {
#if LIBTORRENT_VERSION_MINOR > 15
boost::optional<time_t> t = torrent_handle::get_torrent_info().creation_date();
if (t)
return QDateTime::fromTime_t(*t).toString(Qt::DefaultLocaleLongDate);
return "";
return t ? misc::toQString(*t) : "";
#else
boost::optional<boost::posix_time::ptime> boostDate = torrent_handle::get_torrent_info().creation_date();
if (boostDate) {
return boostTimeToQString(*boostDate);
}
return "";
return boostDate ? misc::boostTimeToQString(*boostDate) : "";
#endif
}
@ -777,9 +757,6 @@ void QTorrentHandle::prioritize_files(const vector<int> &files) const { @@ -777,9 +757,6 @@ void QTorrentHandle::prioritize_files(const vector<int> &files) const {
const Preferences pref;
if (pref.isTempPathEnabled()) {
QString tmp_path = pref.getTempPath();
QString root_folder = TorrentPersistentData::getRootFolder(hash());
if (!root_folder.isEmpty())
tmp_path = QDir(tmp_path).absoluteFilePath(root_folder);
qDebug() << "tmp folder is enabled, move torrent to " << tmp_path << " from " << save_path();
move_storage(tmp_path);
}

12
src/src.pro

@ -131,7 +131,6 @@ nox { @@ -131,7 +131,6 @@ nox {
previewselect.h \
previewlistdelegate.h \
downloadfromurldlg.h \
torrentadditiondlg.h \
trackerlogin.h \
hidabletabwidget.h \
sessionapplication.h \
@ -139,7 +138,8 @@ nox { @@ -139,7 +138,8 @@ nox {
executionlog.h \
iconprovider.h \
updownratiodlg.h \
loglistwidget.h
loglistwidget.h \
addnewtorrentdialog.h
SOURCES += mainwindow.cpp \
ico.cpp \
@ -147,14 +147,14 @@ nox { @@ -147,14 +147,14 @@ nox {
torrentcontentmodel.cpp \
torrentcontentmodelitem.cpp \
torrentcontentfiltermodel.cpp \
torrentadditiondlg.cpp \
sessionapplication.cpp \
torrentimportdlg.cpp \
executionlog.cpp \
previewselect.cpp \
iconprovider.cpp \
updownratiodlg.cpp \
loglistwidget.cpp
loglistwidget.cpp \
addnewtorrentdialog.cpp
win32 {
HEADERS += programupdater.h
@ -174,12 +174,12 @@ nox { @@ -174,12 +174,12 @@ nox {
preview.ui \
login.ui \
downloadfromurldlg.ui \
torrentadditiondlg.ui \
bandwidth_limit.ui \
updownratiodlg.ui \
confirmdeletiondlg.ui \
torrentimportdlg.ui \
executionlog.ui
executionlog.ui \
addnewtorrentdialog.ui
}
DESTDIR = .

811
src/torrentadditiondlg.cpp

@ -1,811 +0,0 @@ @@ -1,811 +0,0 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
#include <QDir>
#include <QFileDialog>
#include <QFile>
#include <fstream>
#include <QMessageBox>
#include <QMenu>
#include <QHeaderView>
#include <QApplication>
#include <QDesktopWidget>
#include <QInputDialog>
#include <QDebug>
#include <libtorrent/version.hpp>
#include <libtorrent/session.hpp>
#include <libtorrent/bencode.hpp>
#include "qbtsession.h"
#include "torrentcontentfiltermodel.h"
#include "torrentcontentmodel.h"
#include "preferences.h"
#include "transferlistwidget.h"
#include "qinisettings.h"
#include "misc.h"
#include "proplistdelegate.h"
#include "torrentpersistentdata.h"
#include "iconprovider.h"
#include "torrentadditiondlg.h"
#include "lineedit.h"
using namespace libtorrent;
torrentAdditionDialog::torrentAdditionDialog(QWidget *parent) :
QDialog(parent), m_oldLabel(""), m_hiddenHeight(0), m_showContentList(true) {
Preferences pref;
setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
// Icons
CancelButton->setIcon(IconProvider::instance()->getIcon("dialog-cancel"));
OkButton->setIcon(IconProvider::instance()->getIcon("list-add"));
// Set Properties list model
m_propListModel = new TorrentContentFilterModel(this);
connect(m_propListModel, SIGNAL(filteredFilesChanged()), SLOT(updateDiskSpaceLabels()));
torrentContentList->setModel(m_propListModel);
torrentContentList->hideColumn(PROGRESS);
m_propListDelegate = new PropListDelegate();
torrentContentList->setItemDelegate(m_propListDelegate);
connect(torrentContentList, SIGNAL(clicked(const QModelIndex&)), torrentContentList, SLOT(edit(const QModelIndex&)));
connect(torrentContentList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayContentListMenu(const QPoint&)));
connect(selectAllButton, SIGNAL(clicked()), m_propListModel, SLOT(selectAll()));
connect(selectNoneButton, SIGNAL(clicked()), m_propListModel, SLOT(selectNone()));
connect(comboLabel, SIGNAL(editTextChanged(QString)), this, SLOT(resetComboLabelIndex(QString)));
connect(comboLabel, SIGNAL(editTextChanged(QString)), this, SLOT(updateLabelInSavePath(QString)));
connect(comboLabel, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateLabelInSavePath(QString)));
LineEdit *contentFilterLine = new LineEdit(this);
connect(contentFilterLine, SIGNAL(textChanged(QString)), m_propListModel, SLOT(setFilterFixedString(QString)));
contentFilterLayout->insertWidget(1, contentFilterLine);
// Important: as a default, it inserts at the bottom which is not desirable
savePathTxt->setInsertPolicy(QComboBox::InsertAtCurrent);
//torrentContentList->header()->setResizeMode(0, QHeaderView::Stretch);
m_defaultSavePath = pref.getSavePath();
//In case of the LastLocationPath doesn't exist anymore, empty the string
m_appendLabelToSavePath = pref.appendTorrentLabel();
QString display_path = m_defaultSavePath.replace("\\", "/");
if (!display_path.endsWith("/"))
display_path += "/";
m_pathHistory << display_path;
#if defined(Q_WS_WIN) || defined(Q_OS_OS2)
display_path.replace("/", "\\");
#endif
savePathTxt->addItem(display_path);
if (pref.addTorrentsInPause()) {
addInPause->setChecked(true);
//addInPause->setEnabled(false);
}
// Load custom labels
QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
settings.beginGroup(QString::fromUtf8("TransferListFilters"));
const QStringList customLabels = settings.value("customLabels", QStringList()).toStringList();
comboLabel->addItem("");
foreach (const QString& label, customLabels) {
comboLabel->addItem(label);
}
// Set Add button as default
OkButton->setDefault(true);
}
torrentAdditionDialog::~torrentAdditionDialog() {
delete m_propListDelegate;
delete m_propListModel;
}
void torrentAdditionDialog::closeEvent(QCloseEvent *event)
{
qDebug() << Q_FUNC_INFO;
saveSettings();
QDialog::closeEvent(event);
}
void torrentAdditionDialog::readSettings() {
// The window should NOT be shown before calling this method
Q_ASSERT(!isVisible());
QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QString mode = m_showContentList ? "Full" : "Short";
qDebug() << Q_FUNC_INFO << "mode:" << mode;
if (!restoreGeometry(settings.value("TorrentAdditionDlg/geometry" + mode).toByteArray())) {
qDebug() << Q_FUNC_INFO << "Failed to load last known dialog geometry";
if (!m_showContentList) {
qDebug() << Q_FUNC_INFO << "Short mode: adapting default size";
resize(width(), height() - 220); // Default size is for full mode
}
}
if (m_showContentList) {
if (!torrentContentList->header()->restoreState(settings.value("TorrentAdditionDlg/ContentHeaderState").toByteArray())) {
qDebug() << Q_FUNC_INFO << "First executation, resize first section to 400px...";
torrentContentList->header()->resizeSection(0, 400); // Default
}
}
}
void torrentAdditionDialog::saveSettings() {
QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QString mode = m_showContentList ? "Full" : "Short";
settings.setValue("TorrentAdditionDlg/geometry" + mode, saveGeometry());
if (m_showContentList) {
settings.setValue("TorrentAdditionDlg/ContentHeaderState", torrentContentList->header()->saveState());
}
}
void torrentAdditionDialog::limitDialogWidth() {
int scrn = 0;
const QWidget *w = this->window();
if (w)
scrn = QApplication::desktop()->screenNumber(w);
else if (QApplication::desktop()->isVirtualDesktop())
scrn = QApplication::desktop()->screenNumber(QCursor::pos());
else
scrn = QApplication::desktop()->screenNumber(this);
QRect desk(QApplication::desktop()->availableGeometry(scrn));
int max_width = desk.width();
if (max_width > 0)
setMaximumWidth(max_width);
}
void torrentAdditionDialog::hideTorrentContent() {
// Disable useless widgets
torrentContentList->setVisible(false);
//torrentContentLbl->setVisible(false);
for (int i=0; i<selectionBtnsLayout->count(); ++i) {
if (selectionBtnsLayout->itemAt(i)->widget())
selectionBtnsLayout->itemAt(i)->widget()->setVisible(false);
}
for (int i=0; i<contentFilterLayout->count(); ++i) {
if (contentFilterLayout->itemAt(i)->widget())
contentFilterLayout->itemAt(i)->widget()->setVisible(false);
}
contentFilterLayout->update();
m_showContentList = false;
}
void torrentAdditionDialog::showLoadMagnetURI(const QString& magnet_uri) {
m_isMagnet = true;
this->m_fromUrl = magnet_uri;
checkLastFolder->setEnabled(false);
// Get torrent hash
m_hash = misc::magnetUriToHash(magnet_uri);
if (m_hash.isEmpty()) {
QBtSession::instance()->addConsoleMessage(tr("Unable to decode magnet link:")+QString::fromUtf8(" '")+m_fromUrl+QString::fromUtf8("'"), QString::fromUtf8("red"));
return;
}
// Set torrent name
m_fileName = misc::magnetUriToName(magnet_uri);
if (m_fileName.isEmpty()) {
m_fileName = tr("Magnet Link");
}
fileNameLbl->setText(QString::fromUtf8("<center><b>")+m_fileName+QString::fromUtf8("</b></center>"));
// Update display
updateDiskSpaceLabels();
// No need to display torrent content
hideTorrentContent();
// Remember dialog geometry
readSettings();
// Limit dialog width
limitDialogWidth();
// Display dialog
show();
}
void torrentAdditionDialog::showLoadTorrent(const QString& filePath, const QString& from_url) {
m_isMagnet = false;
// This is an URL to a local file, switch to local path
if (filePath.startsWith("file:", Qt::CaseInsensitive))
m_filePath = QUrl::fromEncoded(filePath.toLocal8Bit()).toLocalFile();
else
m_filePath = filePath;
if (!QFile::exists(m_filePath)) {
close();
return;
}
qDebug() << Q_FUNC_INFO << filePath;
this->m_fromUrl = from_url;
// Getting torrent file informations
try {
m_torrentInfo = new torrent_info(m_filePath.toUtf8().data());
if (!m_torrentInfo->is_valid())
throw std::exception();
} catch(std::exception&) {
qDebug("Caught error loading torrent");
if (!from_url.isNull()) {
QBtSession::instance()->addConsoleMessage(tr("Unable to decode torrent file:")+QString::fromUtf8(" '")+from_url+QString::fromUtf8("'"), QString::fromUtf8("red"));
QFile::remove(m_filePath);
}else{
QBtSession::instance()->addConsoleMessage(tr("Unable to decode torrent file:")+QString::fromUtf8(" '")+m_filePath+QString::fromUtf8("'"), QString::fromUtf8("red"));
}
close();
return;
}
m_nbFiles = m_torrentInfo->num_files();
if (m_nbFiles == 0) {
// Empty torrent file!?
close();
return;
}
#if LIBTORRENT_VERSION_MINOR >= 16
file_storage fs = m_torrentInfo->files();
#endif
// Truncate root folder
QString root_folder = misc::truncateRootFolder(m_torrentInfo);
// Setting file name
m_fileName = misc::toQStringU(m_torrentInfo->name());
m_hash = misc::toQString(m_torrentInfo->info_hash());
// Use left() to remove .old extension
QString newFileName;
if (m_fileName.endsWith(QString::fromUtf8(".old"))) {
newFileName = m_fileName.left(m_fileName.size()-4);
}else{
newFileName = m_fileName;
}
fileNameLbl->setText(QString::fromUtf8("<center><b>")+newFileName+QString::fromUtf8("</b></center>"));
if (m_torrentInfo->num_files() > 1) {
// List files in torrent
m_propListModel->model()->setupModelData(*m_torrentInfo);
connect(m_propListDelegate, SIGNAL(filteredFilesChanged()), this, SLOT(updateDiskSpaceLabels()));
// Loads files path in the torrent
for (uint i=0; i<m_nbFiles; ++i) {
#if LIBTORRENT_VERSION_MINOR >= 16
m_filesPath << misc::toQStringU(fs.file_path(m_torrentInfo->file_at(i)));
#else
m_filesPath << misc::toQStringU(m_torrentInfo->file_at(i).path.string());
#endif
}
}
// Load save path history
loadSavePathHistory();
// Connect slots
connect(savePathTxt->lineEdit(), SIGNAL(editingFinished()), this, SLOT(updateDiskSpaceLabels()));
connect(savePathTxt->lineEdit(), SIGNAL(editingFinished()), this, SLOT(updateSavePathCurrentText()));
QString save_path = savePathTxt->currentText();
#if defined(Q_WS_WIN) || defined(Q_OS_OS2)
save_path.replace("/", "\\");
#endif
if (!save_path.endsWith(QDir::separator()))
save_path += QDir::separator();
// If the torrent has a root folder, append it to the save path
if (!root_folder.isEmpty()) {
save_path += root_folder;
}
if (m_nbFiles == 1) {
// single file torrent
#if LIBTORRENT_VERSION_MINOR >= 16
QString single_file_relpath = misc::toQStringU(fs.file_path(m_torrentInfo->file_at(0)));
#else
QString single_file_relpath = misc::toQStringU(m_torrentInfo->file_at(0).path.string());
#endif
#if defined(Q_WS_WIN) || defined(Q_OS_OS2)
single_file_relpath.replace("/", "\\");
#endif
save_path += single_file_relpath;
}
savePathTxt->setEditText(save_path);
// Update size labels
updateDiskSpaceLabels();
// Hide useless widgets
if (m_torrentInfo->num_files() <= 1)
hideTorrentContent();
// Remember dialog geometry
readSettings();
// Limit dialog width
limitDialogWidth();
// Show the dialog
show();
}
void torrentAdditionDialog::displayContentListMenu(const QPoint&) {
Q_ASSERT(!m_isMagnet && m_torrentInfo->num_files() > 1);
QMenu myFilesLlistMenu;
const QModelIndexList selectedRows = torrentContentList->selectionModel()->selectedRows(0);
QAction *actRename = 0;
if (selectedRows.size() == 1 && m_torrentInfo->num_files() > 1) {
actRename = myFilesLlistMenu.addAction(IconProvider::instance()->getIcon("edit-rename"), tr("Rename..."));
myFilesLlistMenu.addSeparator();
}
QMenu subMenu;
subMenu.setTitle(tr("Priority"));
subMenu.addAction(actionNot_downloaded);
subMenu.addAction(actionNormal);
subMenu.addAction(actionHigh);
subMenu.addAction(actionMaximum);
myFilesLlistMenu.addMenu(&subMenu);
// Call menu
QAction *act = myFilesLlistMenu.exec(QCursor::pos());
if (act) {
if (act == actRename) {
renameSelectedFile();
} else {
int prio = 1;
if (act == actionHigh) {
prio = prio::HIGH;
} else {
if (act == actionMaximum) {
prio = prio::MAXIMUM;
} else {
if (act == actionNot_downloaded) {
prio = prio::IGNORED;
}
}
}
qDebug("Setting files priority");
foreach (const QModelIndex &index, selectedRows) {
qDebug("Setting priority(%d) for file at row %d", prio, index.row());
m_propListModel->setData(m_propListModel->index(index.row(), PRIORITY, index.parent()), prio);
}
}
}
}
void torrentAdditionDialog::renameSelectedFile() {
Q_ASSERT(!m_isMagnet && m_torrentInfo->num_files() > 1);
const QModelIndexList selectedIndexes = torrentContentList->selectionModel()->selectedRows(0);
Q_ASSERT(selectedIndexes.size() == 1);
const QModelIndex &index = selectedIndexes.first();
// Ask for new name
bool ok;
const QString new_name_last = QInputDialog::getText(this, tr("Rename the file"),
tr("New name:"), QLineEdit::Normal,
index.data().toString(), &ok);
if (ok && !new_name_last.isEmpty()) {
if (!misc::isValidFileSystemName(new_name_last)) {
QMessageBox::warning(this, tr("The file could not be renamed"),
tr("This file name contains forbidden characters, please choose a different one."),
QMessageBox::Ok);
return;
}
if (m_propListModel->getType(index) == TorrentContentModelItem::TFILE) {
// File renaming
const uint file_index = m_propListModel->getFileIndex(index);
QString old_name = m_filesPath.at(file_index);
old_name.replace("\\", "/");
qDebug("Old name: %s", qPrintable(old_name));
QStringList path_items = old_name.split("/");
path_items.removeLast();
path_items << new_name_last;
QString new_name = path_items.join("/");
if (old_name == new_name) {
qDebug("Name did not change");
return;
}
new_name = QDir::cleanPath(new_name);
qDebug("New name: %s", qPrintable(new_name));
// Check if that name is already used
for (uint i=0; i<m_nbFiles; ++i) {
if (i == file_index) continue;
#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
if (m_filesPath.at(i).compare(new_name, Qt::CaseSensitive) == 0) {
#else
if (m_filesPath.at(i).compare(new_name, Qt::CaseInsensitive) == 0) {
#endif
// Display error message
QMessageBox::warning(this, tr("The file could not be renamed"),
tr("This name is already in use in this folder. Please use a different name."),
QMessageBox::Ok);
return;
}
}
new_name = QDir::cleanPath(new_name);
qDebug("Renaming %s to %s", qPrintable(old_name), qPrintable(new_name));
// Rename file in files_path
m_filesPath.replace(file_index, new_name);
// Rename in torrent files model too
m_propListModel->setData(index, new_name_last);
} else {
// Folder renaming
QStringList path_items;
path_items << index.data().toString();
QModelIndex parent = m_propListModel->parent(index);
while(parent.isValid()) {
path_items.prepend(parent.data().toString());
parent = m_propListModel->parent(parent);
}
const QString old_path = path_items.join("/");
path_items.removeLast();
path_items << new_name_last;
QString new_path = path_items.join("/");
if (!new_path.endsWith("/")) new_path += "/";
// Check for overwriting
for (uint i=0; i<m_nbFiles; ++i) {
const QString &current_name = m_filesPath.at(i);
#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
if (current_name.startsWith(new_path, Qt::CaseSensitive)) {
#else
if (current_name.startsWith(new_path, 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;
}
}
// Replace path in all files
for (uint i=0; i<m_nbFiles; ++i) {
const QString &current_name = m_filesPath.at(i);
if (current_name.startsWith(old_path)) {
QString new_name = current_name;
new_name.replace(0, old_path.length(), new_path);
new_name = QDir::cleanPath(new_name);
qDebug("Rename %s to %s", qPrintable(current_name), qPrintable(new_name));
// Rename in files_path
m_filesPath.replace(i, new_name);
}
}
// Rename folder in torrent files model too
m_propListModel->setData(index, new_name_last);
}
}
}
void torrentAdditionDialog::updateDiskSpaceLabels() {
qDebug("Updating disk space label...");
const long long available = misc::freeDiskSpaceOnPath(misc::expandPath(savePathTxt->currentText()));
lbl_disk_space->setText(misc::friendlyUnit(available));
if (!m_isMagnet) {
// Determine torrent size
qulonglong torrent_size = 0;
if (m_torrentInfo->num_files() > 1) {
const std::vector<int> priorities = m_propListModel->model()->getFilesPriorities();
Q_ASSERT(priorities.size() == m_torrentInfo->num_files());
for (unsigned int i=0; i<priorities.size(); ++i) {
if (priorities[i] > 0)
torrent_size += m_torrentInfo->file_at(i).size;
}
} else {
torrent_size = m_torrentInfo->total_size();
}
lbl_torrent_size->setText(misc::friendlyUnit(torrent_size));
// Check if free space is sufficient
if (available > 0) {
if ((unsigned long long)available > torrent_size) {
// Space is sufficient
label_space_msg->setText(tr("(%1 left after torrent download)", "e.g. (100MiB left after torrent download)").arg(misc::friendlyUnit(available-torrent_size)));
} else {
// Space is unsufficient
label_space_msg->setText("<font color=\"red\">"+tr("(%1 more are required to download)", "e.g. (100MiB more are required to download)").arg(misc::friendlyUnit(torrent_size-available))+"</font>");
}
} else {
// Available disk space is unknown
label_space_msg->setText("");
}
}
}
void torrentAdditionDialog::on_browseButton_clicked() {
QString new_path;
QString root_folder;
const QString label_name = comboLabel->currentText();
if (!m_isMagnet && m_torrentInfo->num_files() == 1) {
new_path = QFileDialog::getSaveFileName(this, tr("Choose save path"), savePathTxt->currentText(), QString(), 0, QFileDialog::DontConfirmOverwrite);
if (!new_path.isEmpty()) {
QStringList path_parts = new_path.replace("\\", "/").split("/");
const QString filename = path_parts.takeLast();
// Append label
if (QDir(path_parts.join(QDir::separator())) == QDir(m_defaultSavePath) && !label_name.isEmpty())
path_parts << label_name;
// Append file name
path_parts << filename;
// Construct new_path
new_path = path_parts.join(QDir::separator());
}
} else {
QString truncated_path = getCurrentTruncatedSavePath(&root_folder);
if (!truncated_path.isEmpty() && QDir(truncated_path).exists()) {
new_path = QFileDialog::getExistingDirectory(this, tr("Choose save path"), truncated_path);
}else{
new_path = QFileDialog::getExistingDirectory(this, tr("Choose save path"), QDir::homePath());
}
if (!new_path.isEmpty()) {
QStringList path_parts = new_path.replace("\\", "/").split("/");
if (path_parts.last().isEmpty())
path_parts.removeLast();
// Append label
if (QDir(new_path) == QDir(m_defaultSavePath) && !label_name.isEmpty())
path_parts << label_name;
// Append root folder
if (!root_folder.isEmpty())
path_parts << root_folder;
// Construct new_path
new_path = path_parts.join(QDir::separator());
}
}
if (!new_path.isEmpty()) {
// Check if this new path already exists in the list
QString new_truncated_path = getTruncatedSavePath(new_path);
#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
const int cur_index = m_pathHistory.indexOf(QRegExp(new_truncated_path, Qt::CaseInsensitive));
#else
const int cur_index = m_pathHistory.indexOf(QRegExp(new_truncated_path, Qt::CaseSensitive));
#endif
if (cur_index >= 0) {
savePathTxt->setCurrentIndex(cur_index);
}
#if defined(Q_WS_WIN) || defined(Q_OS_OS2)
new_path.replace("/", "\\");
#endif
savePathTxt->setEditText(new_path);
}
}
void torrentAdditionDialog::on_CancelButton_clicked() {
close();
}
bool torrentAdditionDialog::allFiltered() const {
Q_ASSERT(!m_isMagnet);
return m_propListModel->model()->allFiltered();
}
void torrentAdditionDialog::savePiecesPriorities() {
qDebug("Saving pieces priorities");
Q_ASSERT(!m_isMagnet);
const std::vector<int> priorities = m_propListModel->model()->getFilesPriorities();
TorrentTempData::setFilesPriority(m_hash, priorities);
}
void torrentAdditionDialog::on_OkButton_clicked() {
Preferences pref;
qDebug() << "void torrentAdditionDialog::on_OkButton_clicked() - ENTER";
if (savePathTxt->currentText().trimmed().isEmpty()) {
QMessageBox::critical(0, tr("Empty save path"), tr("Please enter a save path"));
return;
}
QString save_path = savePathTxt->currentText();
#if defined(Q_WS_WIN) || defined(Q_OS_OS2)
save_path.replace("\\", "/");
#endif
save_path = misc::expandPath(save_path);
qDebug("Save path is %s", qPrintable(save_path));
if (!m_isMagnet && m_torrentInfo->num_files() == 1) {
// Remove file name
QStringList parts = save_path.split("/");
const QString single_file_name = parts.takeLast();
Q_ASSERT(m_filesPath.isEmpty());
m_filesPath << single_file_name;
save_path = parts.join("/");
}
qDebug("Save path dir is %s", qPrintable(save_path));
QDir savePath(save_path);
const QString current_label = comboLabel->currentText().trimmed();
if (!current_label.isEmpty() && !misc::isValidFileSystemName(current_label)) {
QMessageBox::warning(this, tr("Invalid label name"), tr("Please don't use any special characters in the label name."));
return;
}
// Save savepath
qDebug("Saving save path to temp data: %s", qPrintable(savePath.absolutePath()));
TorrentTempData::setSavePath(m_hash, savePath.absolutePath());
qDebug("Torrent label is: %s", qPrintable(comboLabel->currentText().trimmed()));
if (!current_label.isEmpty())
TorrentTempData::setLabel(m_hash, current_label);
// Is download sequential?
TorrentTempData::setSequential(m_hash, checkIncrementalDL->isChecked());
// Save files path
// Loads files path in the torrent
if (!m_isMagnet) {
bool path_changed = false;
for (uint i=0; i<m_nbFiles; ++i) {
#if LIBTORRENT_VERSION_MINOR >= 16
file_storage fs = m_torrentInfo->files();
QString old_path = misc::toQStringU(fs.file_path(m_torrentInfo->file_at(i)));
#else
QString old_path = misc::toQStringU(m_torrentInfo->file_at(i).path.string());
#endif
#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
if (m_filesPath.at(i).compare(old_path, Qt::CaseSensitive) != 0) {
#else
if (m_filesPath.at(i).compare(old_path, Qt::CaseInsensitive) != 0) {
#endif
path_changed = true;
break;
}
}
if (path_changed) {
qDebug("Changing files paths");
TorrentTempData::setFilesPath(m_hash, m_filesPath);
}
}
// Skip file checking and directly start seeding
if (addInSeed->isChecked()) {
// Check if local file(s) actually exist
if (m_isMagnet || QFile::exists(savePathTxt->currentText())) {
TorrentTempData::setSeedingMode(m_hash, true);
} else {
QMessageBox::warning(0, tr("Seeding mode error"), tr("You chose to skip file checking. However, local files do not seem to exist in the current destionation folder. Please disable this feature or update the save path."));
return;
}
}
// Check if there is at least one selected file
if (!m_isMagnet && m_torrentInfo->num_files() > 1 && allFiltered()) {
QMessageBox::warning(0, tr("Invalid file selection"), tr("You must select at least one file in the torrent"));
return;
}
// Save path history
saveTruncatedPathHistory();
// Set as default save path if necessary
if (checkLastFolder->isChecked())
pref.setSavePath(getCurrentTruncatedSavePath());
// Check if savePath exists
if (!savePath.exists()) {
if (!savePath.mkpath(savePath.path())) {
QMessageBox::critical(0, tr("Save path creation error"), tr("Could not create the save path"));
return;
}
}
// save filtered files
if (!m_isMagnet && m_torrentInfo->num_files() > 1)
savePiecesPriorities();
// Add to download list
QTorrentHandle h;
if (m_isMagnet)
h = QBtSession::instance()->addMagnetUri(m_fromUrl, false);
else
h = QBtSession::instance()->addTorrent(m_filePath, false, m_fromUrl);
if (addInPause->isChecked() && h.is_valid()) {
h.pause();
}
// Close the dialog
qDebug("Closing torrent addition dialog...");
close();
qDebug("Closed");
}
void torrentAdditionDialog::resetComboLabelIndex(QString text) {
// Select first index
if (text != comboLabel->itemText(comboLabel->currentIndex())) {
comboLabel->setItemText(0, text);
comboLabel->setCurrentIndex(0);
}
}
void torrentAdditionDialog::updateLabelInSavePath(QString label) {
if (m_appendLabelToSavePath) {
// Update Label in combobox
savePathTxt->setItemText(0, misc::updateLabelInSavePath(m_defaultSavePath, savePathTxt->itemText(0), m_oldLabel, label));
// update edit text
savePathTxt->setEditText(misc::updateLabelInSavePath(m_defaultSavePath, savePathTxt->currentText(), m_oldLabel, label));
m_oldLabel = label;
}
}
void torrentAdditionDialog::updateSavePathCurrentText() {
qDebug("updateSavePathCurrentText() - ENTER");
savePathTxt->setItemText(savePathTxt->currentIndex(), savePathTxt->currentText());
qDebug("path_history.size() == %d", m_pathHistory.size());
qDebug("savePathTxt->currentIndex() == %d", savePathTxt->currentIndex());
m_pathHistory.replace(savePathTxt->currentIndex(), getCurrentTruncatedSavePath());
QString root_folder_or_file_name = "";
getCurrentTruncatedSavePath(&root_folder_or_file_name);
// Update other combo items
for (int i=0; i<savePathTxt->count(); ++i) {
if (i == savePathTxt->currentIndex()) continue;
QString item_path = m_pathHistory.at(i);
if (item_path.isEmpty()) continue;
// Append label
if (i == 0 && m_appendLabelToSavePath && QDir(item_path) == QDir(m_defaultSavePath) && !comboLabel->currentText().isEmpty())
item_path += comboLabel->currentText() + "/";
// Append root_folder or filename
if (!root_folder_or_file_name.isEmpty())
item_path += root_folder_or_file_name;
#if defined(Q_WS_WIN) || defined(Q_OS_OS2)
item_path.replace("/", "\\");
#endif
savePathTxt->setItemText(i, item_path);
}
}
QString torrentAdditionDialog::getCurrentTruncatedSavePath(QString* root_folder_or_file_name) const {
QString save_path = savePathTxt->currentText();
return getTruncatedSavePath(save_path, root_folder_or_file_name);
}
// Get current save path without the torrent root folder nor the label label
QString torrentAdditionDialog::getTruncatedSavePath(QString save_path, QString* root_folder_or_file_name) const {
// Expand and clean path (~, .., .)
save_path = misc::expandPath(save_path);
QStringList parts = save_path.replace("\\", "/").split("/");
// Remove torrent root folder
if (!QDir(save_path).exists() || (!m_isMagnet && m_torrentInfo->num_files() == 1)) {
QString tmp = parts.takeLast();
if (root_folder_or_file_name)
*root_folder_or_file_name = tmp;
}
// Remove label
if (m_appendLabelToSavePath && savePathTxt->currentIndex() == 0 && parts.last() == comboLabel->currentText()) {
parts.removeLast();
}
QString truncated_path = parts.join("/");
if (!truncated_path.endsWith("/"))
truncated_path += "/";
qDebug("Truncated save path: %s", qPrintable(truncated_path));
return truncated_path;
}
void torrentAdditionDialog::saveTruncatedPathHistory() {
QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
const QString current_save_path = getCurrentTruncatedSavePath();
// Get current history
QStringList history = settings.value("TorrentAdditionDlg/save_path_history").toStringList();
#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
if (!history.contains(current_save_path, Qt::CaseSensitive)) {
#else
if (!history.contains(current_save_path, Qt::CaseInsensitive)) {
#endif
// Add save path to history
history << current_save_path;
// Limit list size
if (history.size() > 8)
history.removeFirst();
// Save history
settings.setValue("TorrentAdditionDlg/save_path_history", history);
}
}
void torrentAdditionDialog::loadSavePathHistory() {
QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
// Load save path history
QStringList raw_path_history = settings.value("TorrentAdditionDlg/save_path_history").toStringList();
foreach (const QString &sp, raw_path_history) {
if (QDir(sp) != QDir(m_defaultSavePath)) {
QString dsp = sp;
#if defined(Q_WS_WIN) || defined(Q_OS_OS2)
dsp.replace("/", "\\");
#endif
m_pathHistory << sp;
savePathTxt->addItem(dsp);
}
}
}

364
src/torrentadditiondlg.ui

@ -1,364 +0,0 @@ @@ -1,364 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>addTorrentDialog</class>
<widget class="QDialog" name="addTorrentDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>434</width>
<height>598</height>
</rect>
</property>
<property name="windowTitle">
<string>Torrent addition dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="fileNameLbl">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="savePathLbl">
<property name="text">
<string>Save path:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QComboBox" name="savePathTxt">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="browseButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkLastFolder">
<property name="text">
<string>Set as default save path</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Torrent size:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lbl_torrent_size">
<property name="text">
<string>Unknown</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Free disk space:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lbl_disk_space">
<property name="text">
<string>Unknown</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_space_msg">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Label:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboLabel">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="editable">
<bool>true</bool>
</property>
<property name="frame">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="contentFilterLayout">
<item>
<widget class="QLabel" name="torrentContentLbl">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Torrent content:</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QTreeView" name="torrentContentList">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="selectionBtnsLayout">
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="selectAllButton">
<property name="text">
<string>Select All</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="selectNoneButton">
<property name="text">
<string>Select None</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkIncrementalDL">
<property name="text">
<string>Download in sequential order (slower but good for previewing)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="addInSeed">
<property name="text">
<string>Skip file checking and start seeding immediately</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="addInPause">
<property name="text">
<string>Add to download list in paused state</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="OkButton">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="CancelButton">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
<action name="actionNormal">
<property name="text">
<string>Normal</string>
</property>
</action>
<action name="actionHigh">
<property name="text">
<string>High</string>
</property>
</action>
<action name="actionMaximum">
<property name="text">
<string>Maximum</string>
</property>
</action>
<action name="actionNot_downloaded">
<property name="text">
<string>Do not download</string>
</property>
<property name="toolTip">
<string>Do not download</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>

5
src/torrentcreator/torrentcreatordlg.cpp

@ -155,21 +155,16 @@ void TorrentCreatorDlg::handleCreationSuccess(QString path, QString branch_path) @@ -155,21 +155,16 @@ void TorrentCreatorDlg::handleCreationSuccess(QString path, QString branch_path)
// Remove busy cursor
setCursor(QCursor(Qt::ArrowCursor));
if (checkStartSeeding->isChecked()) {
QString root_folder;
// Create save path temp data
boost::intrusive_ptr<torrent_info> t;
try {
t = new torrent_info(path.toUtf8().data());
root_folder = misc::truncateRootFolder(t);
} catch(std::exception&) {
QMessageBox::critical(0, tr("Torrent creation"), tr("Created torrent file is invalid. It won't be added to download list."));
return;
}
QString hash = misc::toQString(t->info_hash());
QString save_path = branch_path;
if (!root_folder.isEmpty()) {
save_path = QDir(save_path).absoluteFilePath(root_folder);
}
TorrentTempData::setSavePath(hash, save_path);
// Enable seeding mode (do not recheck the files)
TorrentTempData::setSeedingMode(hash, true);

2
src/torrentimportdlg.cpp

@ -233,8 +233,6 @@ void TorrentImportDlg::loadTorrent(const QString &torrent_path) @@ -233,8 +233,6 @@ void TorrentImportDlg::loadTorrent(const QString &torrent_path)
QMessageBox::warning(this, tr("Invalid torrent file"), tr("This is not a valid torrent file."));
return;
}
// The torrent file is valid
misc::truncateRootFolder(t);
// Update display
#if defined(Q_WS_WIN) || defined(Q_OS_OS2)
QString tmp = torrent_path;

16
src/torrentpersistentdata.h

@ -254,22 +254,6 @@ public: @@ -254,22 +254,6 @@ public:
return data.value("has_error", false).toBool();
}
static void setRootFolder(QString hash, QString root_folder) {
QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
QHash<QString, QVariant> all_data = settings.value("torrents").toHash();
QHash<QString, QVariant> data = all_data.value(hash).toHash();
data["root_folder"] = root_folder;
all_data[hash] = data;
settings.setValue("torrents", all_data);
}
static QString getRootFolder(QString hash) {
QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
const QHash<QString, QVariant> all_data = settings.value("torrents").toHash();
const QHash<QString, QVariant> data = all_data.value(hash).toHash();
return data.value("root_folder").toString();
}
static void setPreviousSavePath(QString hash, QString previous_path) {
QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
QHash<QString, QVariant> all_data = settings.value("torrents").toHash();

Loading…
Cancel
Save