Browse Source

Merge pull request #818 from Gelmir/metadata2

Load magnet metadata inside AddNewTorrentDialog
adaptive-webui-19844
sledgehammer999 11 years ago
parent
commit
4f99b04a42
  1. 181
      src/addnewtorrentdialog.cpp
  2. 12
      src/addnewtorrentdialog.h
  3. 10
      src/addnewtorrentdialog.ui

181
src/addnewtorrentdialog.cpp

@ -58,9 +58,16 @@ AddNewTorrentDialog::AddNewTorrentDialog(QWidget *parent) :
m_contentModel(0), m_contentModel(0),
m_contentDelegate(0), m_contentDelegate(0),
m_isMagnet(false), m_isMagnet(false),
m_hasMetadata(false),
m_convertingMagnet(false),
m_hasRenamedFile(false) m_hasRenamedFile(false)
{ {
ui->setupUi(this); ui->setupUi(this);
m_progress = new QProgressBar(this);
m_progress->setMinimum(0);
m_progress->setMaximum(0);
ui->lblMetaLoading->setVisible(false);
ui->buttonsHLayout->insertWidget(ui->buttonsHLayout->indexOf(ui->lblMetaLoading), m_progress);
QIniSettings settings; QIniSettings settings;
Preferences pref; Preferences pref;
@ -89,6 +96,7 @@ AddNewTorrentDialog::AddNewTorrentDialog(QWidget *parent) :
AddNewTorrentDialog::~AddNewTorrentDialog() AddNewTorrentDialog::~AddNewTorrentDialog()
{ {
saveState(); saveState();
delete m_progress;
delete ui; delete ui;
if (m_contentModel) if (m_contentModel)
delete m_contentModel; delete m_contentModel;
@ -141,8 +149,8 @@ void AddNewTorrentDialog::showAdvancedSettings(bool show)
if (show) { if (show) {
ui->adv_button->setText(QString::fromUtf8("")); ui->adv_button->setText(QString::fromUtf8(""));
ui->settings_group->setVisible(true); ui->settings_group->setVisible(true);
ui->info_group->setVisible(!m_isMagnet); ui->info_group->setVisible(!m_isMagnet || (m_isMagnet && m_hasMetadata));
if (!m_isMagnet && (m_torrentInfo->num_files() > 1)) { if ( (!m_isMagnet || (m_isMagnet && m_hasMetadata)) && (m_torrentInfo->num_files() > 1)) {
ui->content_tree->setVisible(true); ui->content_tree->setVisible(true);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
} else { } else {
@ -243,6 +251,7 @@ bool AddNewTorrentDialog::loadTorrent(const QString& torrent_path, const QString
bool AddNewTorrentDialog::loadMagnet(const QString &magnet_uri) bool AddNewTorrentDialog::loadMagnet(const QString &magnet_uri)
{ {
connect(QBtSession::instance(), SIGNAL(metadataReceived(const QTorrentHandle&)), SLOT(updateMetadata(const QTorrentHandle&)));
m_isMagnet = true; m_isMagnet = true;
m_url = magnet_uri; m_url = magnet_uri;
m_hash = misc::magnetUriToHash(m_url); m_hash = misc::magnetUriToHash(m_url);
@ -251,6 +260,13 @@ bool AddNewTorrentDialog::loadMagnet(const QString &magnet_uri)
return false; return false;
} }
// Prevent showing the dialog if download is already present
if (QBtSession::instance()->getTorrentHandle(m_hash).is_valid()) {
QMessageBox::information(0, tr("Already in download list"), tr("Magnet link is already in download list."), QMessageBox::Ok);
QBtSession::instance()->addMagnetUri(m_url, false);
return false;
}
// Set dialog title // Set dialog title
QString torrent_name = misc::magnetUriToName(m_url); QString torrent_name = misc::magnetUriToName(m_url);
setWindowTitle(torrent_name.isEmpty() ? tr("Magnet link") : torrent_name); setWindowTitle(torrent_name.isEmpty() ? tr("Magnet link") : torrent_name);
@ -260,6 +276,22 @@ bool AddNewTorrentDialog::loadMagnet(const QString &magnet_uri)
// Set dialog position // Set dialog position
setdialogPosition(); setdialogPosition();
Preferences pref;
// Override save path
TorrentTempData::setSavePath(m_hash, QString(QDir::tempPath() + QDir::separator() + m_hash).replace("\\", "/"));
// Temporary override of addInPause setting
bool old_addInPause = pref.addTorrentsInPause();
pref.addTorrentsInPause(!ui->start_torrent_cb->isChecked());
pref.sync();
QBtSession::instance()->addMagnetUri(m_url, false);
QBtSession::instance()->resumeTorrent(m_hash);
setMetadataProgressIndicator(true, tr("Retrieving metadata..."));
// Restore addInPause setting
pref.addTorrentsInPause(old_addInPause);
return true; return true;
} }
@ -304,7 +336,7 @@ void AddNewTorrentDialog::updateFileNameInSavePaths(const QString &new_filename)
void AddNewTorrentDialog::updateDiskSpaceLabel() void AddNewTorrentDialog::updateDiskSpaceLabel()
{ {
Q_ASSERT(!m_isMagnet); Q_ASSERT((m_isMagnet&m_hasMetadata)||!m_isMagnet);
// Determine torrent size // Determine torrent size
qulonglong torrent_size = 0; qulonglong torrent_size = 0;
if (m_contentModel) { if (m_contentModel) {
@ -378,7 +410,7 @@ void AddNewTorrentDialog::onSavePathChanged(int index)
relayout(); relayout();
// Remember index // Remember index
old_index = ui->save_path_combo->currentIndex(); old_index = ui->save_path_combo->currentIndex();
if (!m_isMagnet) if (m_isMagnet && m_hasMetadata)
updateDiskSpaceLabel(); updateDiskSpaceLabel();
} }
@ -560,8 +592,20 @@ void AddNewTorrentDialog::displayContentTreeMenu(const QPoint&) {
} }
} }
void AddNewTorrentDialog::on_buttonBox_accepted() void AddNewTorrentDialog::accept()
{ {
if (m_isMagnet) {
if (m_convertingMagnet) {
QMessageBox::information(0, tr("Processing metadata..."), tr("Please wait while parsing metadata"), QMessageBox::Ok);
return;
}
disconnect(this, SLOT(updateMetadata(const QTorrentHandle&)));
}
if (m_isMagnet && !m_hasMetadata) {
// Metadata retrival was cancelled
// Kill existing handle and make a new one
QBtSession::instance()->deleteTorrent(m_hash, true);
}
Preferences pref; Preferences pref;
// Save Temporary data about torrent // Save Temporary data about torrent
QString save_path = ui->save_path_combo->itemData(ui->save_path_combo->currentIndex()).toString(); QString save_path = ui->save_path_combo->itemData(ui->save_path_combo->currentIndex()).toString();
@ -590,7 +634,7 @@ void AddNewTorrentDialog::on_buttonBox_accepted()
pref.sync(); pref.sync();
// Add torrent // Add torrent
if (m_isMagnet) if (m_isMagnet && !m_hasMetadata)
QBtSession::instance()->addMagnetUri(m_url, false); QBtSession::instance()->addMagnetUri(m_url, false);
else else
QBtSession::instance()->addTorrent(m_filePath, false, m_url); QBtSession::instance()->addTorrent(m_filePath, false, m_url);
@ -605,4 +649,129 @@ void AddNewTorrentDialog::on_buttonBox_accepted()
pref.setSavePath(ui->save_path_combo->itemData(ui->save_path_combo->currentIndex()).toString()); pref.setSavePath(ui->save_path_combo->itemData(ui->save_path_combo->currentIndex()).toString());
QBtSession::instance()->setDefaultSavePath(pref.getSavePath()); QBtSession::instance()->setDefaultSavePath(pref.getSavePath());
} }
QDialog::accept();
}
void AddNewTorrentDialog::reject() {
if (m_isMagnet) {
disconnect(this, SLOT(updateMetadata(const QTorrentHandle&)));
while (true) { // Force cancel
if (!m_convertingMagnet)
break;
}
setMetadataProgressIndicator(false);
QBtSession::instance()->deleteTorrent(m_hash, true);
}
QDialog::reject();
}
void AddNewTorrentDialog::updateMetadata(const QTorrentHandle &h) {
try {
if (h.hash() != m_hash)
return;
m_convertingMagnet = true;
Q_ASSERT(h.has_metadata());
h.pause();
// Try to convert magnet to torrent with full metadata
m_filePath = QDir::tempPath() + h.hash() + ".torrent";
h.save_torrent_file(m_filePath);
if (!QFile::exists(m_filePath)) {
QMessageBox::warning(0, tr("I/O Error"), tr("Failed to save metadata.\nFile list will be unavailable."));
m_convertingMagnet = false;
setMetadataProgressIndicator(false, tr("Failed to save metadata"));
return;
}
try {
m_torrentInfo = new torrent_info(m_filePath.toUtf8().data());
Q_ASSERT(m_hash == misc::toQString(m_torrentInfo->info_hash()));
} catch(const std::exception&) {
QMessageBox::critical(0, tr("Invalid metadata"), tr("Metadata corrupted.\nFile list will be unavailable."));
m_convertingMagnet = false;
setMetadataProgressIndicator(false, tr("Invalid metadata"));
return;
}
QBtSession::instance()->deleteTorrent(m_hash, true);
// Good to go
m_hasMetadata = true;
setMetadataProgressIndicator(true, tr("Parsing metadata..."));
// Update UI
// Set dialog title
setWindowTitle(misc::toQStringU(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_NUM >= 001600
file_storage fs = m_torrentInfo->files();
#endif
// Populate m_filesList
for (int i = 0; i < m_torrentInfo->num_files(); ++i) {
#if LIBTORRENT_VERSION_NUM >= 001600
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 TorrentContentFilterModel(this);
connect(m_contentModel->model(), 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->model()->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_NUM >= 001600
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, fsutils::toDisplayPath(QDir(ui->save_path_combo->itemText(i)).absoluteFilePath(single_file_relpath)));
}
}
QIniSettings settings;
showAdvancedSettings(settings.value("AddNewTorrentDialog/expanded").toBool());
// Set dialog position
setdialogPosition();
m_convertingMagnet = false;
setMetadataProgressIndicator(false, tr("Metadata retrieval complete"));
} catch (invalid_handle&) {
QMessageBox::critical(0, tr("I/O Error"), ("Unknown error."));
setMetadataProgressIndicator(false, tr("Unknown error"));
return;
}
}
void AddNewTorrentDialog::setMetadataProgressIndicator(bool enabled, const QString &labelText) {
// Always show info label when waiting for metadata
ui->lblMetaLoading->setVisible(true);
ui->lblMetaLoading->setText(labelText);
if (enabled)
m_progress->setEnabled(enabled);
else {
m_progress->setMaximum(1);
m_progress->setValue(1);
m_progress->setTextVisible(false); // Don't display %% completed
}
} }

12
src/addnewtorrentdialog.h

@ -35,6 +35,8 @@
#include <QDialog> #include <QDialog>
#include <QUrl> #include <QUrl>
#include <libtorrent/torrent_info.hpp> #include <libtorrent/torrent_info.hpp>
#include "qtorrenthandle.h"
#include <QProgressBar>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
namespace Ui { namespace Ui {
@ -58,12 +60,16 @@ public:
private slots: private slots:
void showAdvancedSettings(bool show); void showAdvancedSettings(bool show);
void displayContentTreeMenu(const QPoint&); void displayContentTreeMenu(const QPoint&);
void on_buttonBox_accepted();
void updateDiskSpaceLabel(); void updateDiskSpaceLabel();
void onSavePathChanged(int); void onSavePathChanged(int);
void relayout(); void relayout();
void renameSelectedFile(); void renameSelectedFile();
void setdialogPosition(); void setdialogPosition();
void updateMetadata(const QTorrentHandle& h);
protected slots:
virtual void accept();
virtual void reject();
private: private:
explicit AddNewTorrentDialog(QWidget *parent = 0); explicit AddNewTorrentDialog(QWidget *parent = 0);
@ -75,12 +81,15 @@ private:
void updateFileNameInSavePaths(const QString& new_filename); void updateFileNameInSavePaths(const QString& new_filename);
void loadState(); void loadState();
void saveState(); void saveState();
void setMetadataProgressIndicator(bool enabled, const QString &labelText = QString());
private: private:
Ui::AddNewTorrentDialog *ui; Ui::AddNewTorrentDialog *ui;
TorrentContentFilterModel *m_contentModel; TorrentContentFilterModel *m_contentModel;
PropListDelegate *m_contentDelegate; PropListDelegate *m_contentDelegate;
bool m_isMagnet; bool m_isMagnet;
bool m_hasMetadata;
bool m_convertingMagnet;
QString m_filePath; QString m_filePath;
QString m_url; QString m_url;
QString m_hash; QString m_hash;
@ -88,6 +97,7 @@ private:
QStringList m_filesPath; QStringList m_filesPath;
bool m_hasRenamedFile; bool m_hasRenamedFile;
QShortcut *editHotkey; QShortcut *editHotkey;
QProgressBar *m_progress;
}; };
#endif // ADDNEWTORRENTDIALOG_H #endif // ADDNEWTORRENTDIALOG_H

10
src/addnewtorrentdialog.ui

@ -186,6 +186,16 @@
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="buttonsHLayout"> <layout class="QHBoxLayout" name="buttonsHLayout">
<item>
<widget class="QLabel" name="lblMetaLoading">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item> <item>
<spacer name="horizontalSpacer"> <spacer name="horizontalSpacer">
<property name="orientation"> <property name="orientation">

Loading…
Cancel
Save