|
|
@ -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
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|