qBittorrent
AddNewTorrentDialog Class Referencefinal

#include <addnewtorrentdialog.h>

Inheritance diagram for AddNewTorrentDialog:
Collaboration diagram for AddNewTorrentDialog:

Public Member Functions

 ~AddNewTorrentDialog () override
 

Static Public Member Functions

static bool isEnabled ()
 
static void setEnabled (bool value)
 
static bool isTopLevel ()
 
static void setTopLevel (bool value)
 
static int savePathHistoryLength ()
 
static void setSavePathHistoryLength (int value)
 
static void show (const QString &source, const BitTorrent::AddTorrentParams &inParams, QWidget *parent)
 
static void show (const QString &source, QWidget *parent)
 

Static Public Attributes

static const int minPathHistoryLength = 0
 
static const int maxPathHistoryLength = 99
 

Private Slots

void displayContentTreeMenu (const QPoint &)
 
void updateDiskSpaceLabel ()
 
void onSavePathChanged (const QString &newPath)
 
void onDownloadPathChanged (const QString &newPath)
 
void onUseDownloadPathChanged (bool checked)
 
void updateMetadata (const BitTorrent::TorrentInfo &metadata)
 
void handleDownloadFinished (const Net::DownloadResult &downloadResult)
 
void TMMChanged (int index)
 
void categoryChanged (int index)
 
void contentLayoutChanged (int index)
 
void doNotDeleteTorrentClicked (bool checked)
 
void renameSelectedFile ()
 
void accept () override
 
void reject () override
 

Private Member Functions

 AddNewTorrentDialog (const BitTorrent::AddTorrentParams &inParams, QWidget *parent)
 
bool loadTorrentFile (const QString &torrentPath)
 
bool loadTorrentImpl ()
 
bool loadMagnet (const BitTorrent::MagnetUri &magnetUri)
 
void populateSavePaths ()
 
void loadState ()
 
void saveState ()
 
void setMetadataProgressIndicator (bool visibleIndicator, const QString &labelText={})
 
void setupTreeview ()
 
void saveTorrentFile ()
 
bool hasMetadata () const
 
void showEvent (QShowEvent *event) override
 

Private Attributes

Ui::AddNewTorrentDialog * m_ui
 
TorrentContentFilterModelm_contentModel = nullptr
 
PropListDelegatem_contentDelegate = nullptr
 
BitTorrent::MagnetUri m_magnetURI
 
BitTorrent::TorrentInfo m_torrentInfo
 
int m_savePathIndex = -1
 
int m_downloadPathIndex = -1
 
bool m_useDownloadPath = false
 
std::unique_ptr< TorrentFileGuardm_torrentGuard
 
BitTorrent::AddTorrentParams m_torrentParams
 
SettingValue< QSize > m_storeDialogSize
 
SettingValue< QString > m_storeDefaultCategory
 
SettingValue< bool > m_storeRememberLastSavePath
 
SettingValue< QByteArray > m_storeTreeHeaderState
 
SettingValue< QByteArray > m_storeSplitterState
 

Detailed Description

Definition at line 59 of file addnewtorrentdialog.h.

Constructor & Destructor Documentation

◆ ~AddNewTorrentDialog()

AddNewTorrentDialog::~AddNewTorrentDialog ( )
override

Definition at line 249 of file addnewtorrentdialog.cpp.

250 {
251  saveState();
252 
253  delete m_contentDelegate;
254  delete m_ui;
255 }
Ui::AddNewTorrentDialog * m_ui
PropListDelegate * m_contentDelegate

References m_contentDelegate, m_ui, and saveState().

Here is the call graph for this function:

◆ AddNewTorrentDialog()

AddNewTorrentDialog::AddNewTorrentDialog ( const BitTorrent::AddTorrentParams inParams,
QWidget *  parent 
)
explicitprivate

Definition at line 167 of file addnewtorrentdialog.cpp.

168  : QDialog(parent)
169  , m_ui(new Ui::AddNewTorrentDialog)
170  , m_torrentParams(inParams)
171  , m_storeDialogSize(SETTINGS_KEY("DialogSize"))
172  , m_storeDefaultCategory(SETTINGS_KEY("DefaultCategory"))
173  , m_storeRememberLastSavePath(SETTINGS_KEY("RememberLastSavePath"))
174 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
175  , m_storeTreeHeaderState("GUI/Qt6/" SETTINGS_KEY("TreeHeaderState"))
176  , m_storeSplitterState("GUI/Qt6/" SETTINGS_KEY("SplitterState"))
177 #else
178  , m_storeTreeHeaderState(SETTINGS_KEY("TreeHeaderState"))
179  , m_storeSplitterState(SETTINGS_KEY("SplitterState"))
180 #endif
181 {
182  // TODO: set dialog file properties using m_torrentParams.filePriorities
183  m_ui->setupUi(this);
184  setAttribute(Qt::WA_DeleteOnClose);
185 
186  m_ui->lblMetaLoading->setVisible(false);
187  m_ui->progMetaLoading->setVisible(false);
188  m_ui->buttonSave->setVisible(false);
189  connect(m_ui->buttonSave, &QPushButton::clicked, this, &AddNewTorrentDialog::saveTorrentFile);
190 
191  m_ui->savePath->setMode(FileSystemPathEdit::Mode::DirectorySave);
192  m_ui->savePath->setDialogCaption(tr("Choose save path"));
193  m_ui->savePath->setMaxVisibleItems(20);
194 
195  const auto *session = BitTorrent::Session::instance();
196 
197  m_ui->downloadPath->setMode(FileSystemPathEdit::Mode::DirectorySave);
198  m_ui->downloadPath->setDialogCaption(tr("Choose save path"));
199  m_ui->downloadPath->setMaxVisibleItems(20);
200 
201  m_ui->startTorrentCheckBox->setChecked(!m_torrentParams.addPaused.value_or(session->isAddTorrentPaused()));
202 
203  m_ui->comboTTM->blockSignals(true); // the TreeView size isn't correct if the slot does it job at this point
204  m_ui->comboTTM->setCurrentIndex(session->isAutoTMMDisabledByDefault() ? 0 : 1);
205  m_ui->comboTTM->blockSignals(false);
206 
209  connect(m_ui->groupBoxDownloadPath, &QGroupBox::toggled, this, &AddNewTorrentDialog::onUseDownloadPathChanged);
210 
211  m_ui->checkBoxRememberLastSavePath->setChecked(m_storeRememberLastSavePath);
212 
213  m_ui->contentLayoutComboBox->setCurrentIndex(
214  static_cast<int>(m_torrentParams.contentLayout.value_or(session->torrentContentLayout())));
215  connect(m_ui->contentLayoutComboBox, &QComboBox::currentIndexChanged, this, &AddNewTorrentDialog::contentLayoutChanged);
216 
217  m_ui->sequentialCheckBox->setChecked(m_torrentParams.sequential);
218  m_ui->firstLastCheckBox->setChecked(m_torrentParams.firstLastPiecePriority);
219 
220  m_ui->skipCheckingCheckBox->setChecked(m_torrentParams.skipChecking);
221  m_ui->doNotDeleteTorrentCheckBox->setVisible(TorrentFileGuard::autoDeleteMode() != TorrentFileGuard::Never);
222 
223  // Load categories
224  QStringList categories = session->categories();
225  std::sort(categories.begin(), categories.end(), Utils::Compare::NaturalLessThan<Qt::CaseInsensitive>());
226  const QString defaultCategory = m_storeDefaultCategory;
227 
228  if (!m_torrentParams.category.isEmpty())
229  m_ui->categoryComboBox->addItem(m_torrentParams.category);
230  if (!defaultCategory.isEmpty())
231  m_ui->categoryComboBox->addItem(defaultCategory);
232  m_ui->categoryComboBox->addItem("");
233 
234  for (const QString &category : asConst(categories))
235  if (category != defaultCategory && category != m_torrentParams.category)
236  m_ui->categoryComboBox->addItem(category);
237 
238  m_ui->contentTreeView->header()->setSortIndicator(0, Qt::AscendingOrder);
239  loadState();
240  // Signal / slots
241  connect(m_ui->doNotDeleteTorrentCheckBox, &QCheckBox::clicked, this, &AddNewTorrentDialog::doNotDeleteTorrentClicked);
242  QShortcut *editHotkey = new QShortcut(Qt::Key_F2, m_ui->contentTreeView, nullptr, nullptr, Qt::WidgetShortcut);
243  connect(editHotkey, &QShortcut::activated, this, &AddNewTorrentDialog::renameSelectedFile);
244  connect(m_ui->contentTreeView, &QAbstractItemView::doubleClicked, this, &AddNewTorrentDialog::renameSelectedFile);
245 
246  m_ui->buttonBox->button(QDialogButtonBox::Ok)->setFocus();
247 }
#define SETTINGS_KEY(name)
void onDownloadPathChanged(const QString &newPath)
void doNotDeleteTorrentClicked(bool checked)
BitTorrent::AddTorrentParams m_torrentParams
SettingValue< QSize > m_storeDialogSize
void contentLayoutChanged(int index)
SettingValue< QByteArray > m_storeTreeHeaderState
SettingValue< bool > m_storeRememberLastSavePath
void onUseDownloadPathChanged(bool checked)
void onSavePathChanged(const QString &newPath)
SettingValue< QString > m_storeDefaultCategory
SettingValue< QByteArray > m_storeSplitterState
static Session * instance()
Definition: session.cpp:997
@ DirectorySave
selecting directories for saving
void selectedPathChanged(const QString &path)
static AutoDeleteMode autoDeleteMode()
constexpr std::add_const_t< T > & asConst(T &t) noexcept
Definition: global.h:42
std::optional< bool > addPaused
std::optional< BitTorrent::TorrentContentLayout > contentLayout

References BitTorrent::AddTorrentParams::addPaused, asConst(), TorrentFileGuard::autoDeleteMode(), BitTorrent::AddTorrentParams::category, BitTorrent::AddTorrentParams::contentLayout, contentLayoutChanged(), FileSystemPathEdit::DirectorySave, doNotDeleteTorrentClicked(), BitTorrent::AddTorrentParams::firstLastPiecePriority, BitTorrent::Session::instance(), loadState(), m_storeDefaultCategory, m_storeRememberLastSavePath, m_torrentParams, m_ui, TorrentFileGuard::Never, onDownloadPathChanged(), onSavePathChanged(), onUseDownloadPathChanged(), renameSelectedFile(), saveTorrentFile(), FileSystemPathEdit::selectedPathChanged(), BitTorrent::AddTorrentParams::sequential, and BitTorrent::AddTorrentParams::skipChecking.

Referenced by show().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Function Documentation

◆ accept

void AddNewTorrentDialog::accept ( )
overrideprivateslot

Definition at line 758 of file addnewtorrentdialog.cpp.

759 {
760  // TODO: Check if destination actually exists
761  m_torrentParams.skipChecking = m_ui->skipCheckingCheckBox->isChecked();
762 
763  // Category
764  m_torrentParams.category = m_ui->categoryComboBox->currentText();
765  if (m_ui->defaultCategoryCheckbox->isChecked())
767 
768  m_storeRememberLastSavePath = m_ui->checkBoxRememberLastSavePath->isChecked();
769 
770  // Save file priorities
771  if (m_contentModel)
773 
774  m_torrentParams.addPaused = !m_ui->startTorrentCheckBox->isChecked();
775  m_torrentParams.contentLayout = static_cast<BitTorrent::TorrentContentLayout>(m_ui->contentLayoutComboBox->currentIndex());
776 
777  m_torrentParams.sequential = m_ui->sequentialCheckBox->isChecked();
778  m_torrentParams.firstLastPiecePriority = m_ui->firstLastCheckBox->isChecked();
779 
780  const bool useAutoTMM = (m_ui->comboTTM->currentIndex() == 1); // 1 is Automatic mode. Handle all non 1 values as manual mode.
781  m_torrentParams.useAutoTMM = useAutoTMM;
782  if (!useAutoTMM)
783  {
784  const QString savePath = m_ui->savePath->selectedPath();
785  m_torrentParams.savePath = savePath;
787 
788  m_torrentParams.useDownloadPath = m_ui->groupBoxDownloadPath->isChecked();
790  {
791  const QString downloadPath = m_ui->downloadPath->selectedPath();
792  m_torrentParams.downloadPath = downloadPath;
794  }
795  }
796 
797  setEnabled(!m_ui->checkBoxNeverShow->isChecked());
798 
799  // Add torrent
800  if (!hasMetadata())
802  else
804 
805  m_torrentGuard->markAsAddedToSession();
806  QDialog::accept();
807 }
static void setEnabled(bool value)
BitTorrent::MagnetUri m_magnetURI
TorrentContentFilterModel * m_contentModel
static int savePathHistoryLength()
std::unique_ptr< TorrentFileGuard > m_torrentGuard
BitTorrent::TorrentInfo m_torrentInfo
bool addTorrent(const QString &source, const AddTorrentParams &params=AddTorrentParams())
Definition: session.cpp:2007
TorrentContentModel * model() const
QVector< BitTorrent::DownloadPriority > getFilePriorities() const
void updatePathHistory(const QString &settingsKey, const QString &path, const int maxLength)
QVector< DownloadPriority > filePriorities
std::optional< bool > useDownloadPath
std::optional< bool > useAutoTMM

References BitTorrent::AddTorrentParams::addPaused, BitTorrent::Session::addTorrent(), BitTorrent::AddTorrentParams::category, BitTorrent::AddTorrentParams::contentLayout, BitTorrent::AddTorrentParams::downloadPath, BitTorrent::AddTorrentParams::filePriorities, BitTorrent::AddTorrentParams::firstLastPiecePriority, TorrentContentModel::getFilePriorities(), hasMetadata(), BitTorrent::Session::instance(), anonymous_namespace{addnewtorrentdialog.cpp}::KEY_DOWNLOADPATHHISTORY, anonymous_namespace{addnewtorrentdialog.cpp}::KEY_SAVEPATHHISTORY, m_contentModel, m_magnetURI, m_storeDefaultCategory, m_storeRememberLastSavePath, m_torrentGuard, m_torrentInfo, m_torrentParams, m_ui, TorrentContentFilterModel::model(), BitTorrent::AddTorrentParams::savePath, savePathHistoryLength(), BitTorrent::AddTorrentParams::sequential, setEnabled(), BitTorrent::AddTorrentParams::skipChecking, anonymous_namespace{addnewtorrentdialog.cpp}::updatePathHistory(), BitTorrent::AddTorrentParams::useAutoTMM, and BitTorrent::AddTorrentParams::useDownloadPath.

Here is the call graph for this function:

◆ categoryChanged

void AddNewTorrentDialog::categoryChanged ( int  index)
privateslot

Definition at line 510 of file addnewtorrentdialog.cpp.

511 {
512  Q_UNUSED(index);
513 
514  if (m_ui->comboTTM->currentIndex() == 1)
515  {
516  const auto *btSession = BitTorrent::Session::instance();
517  const QString categoryName = m_ui->categoryComboBox->currentText();
518 
519  const QString savePath = btSession->categorySavePath(categoryName);
520  m_ui->savePath->setSelectedPath(Utils::Fs::toNativePath(savePath));
521 
522  const QString downloadPath = btSession->categoryDownloadPath(categoryName);
523  m_ui->downloadPath->setSelectedPath(Utils::Fs::toNativePath(downloadPath));
524 
525  m_ui->groupBoxDownloadPath->setChecked(!m_ui->downloadPath->selectedPath().isEmpty());
526 
528  }
529 }
QString toNativePath(const QString &path)
Definition: fs.cpp:64

References BitTorrent::Session::instance(), m_ui, Utils::Fs::toNativePath(), and updateDiskSpaceLabel().

Here is the call graph for this function:

◆ contentLayoutChanged

void AddNewTorrentDialog::contentLayoutChanged ( int  index)
privateslot

Definition at line 531 of file addnewtorrentdialog.cpp.

532 {
533  if (!hasMetadata())
534  return;
535 
536  const auto filePriorities = m_contentModel->model()->getFilePriorities();
537  m_contentModel->model()->clear();
538 
539  Q_ASSERT(!m_torrentParams.filePaths.isEmpty());
540  const auto contentLayout = ((index == 0)
542  : static_cast<BitTorrent::TorrentContentLayout>(index));
545  m_contentModel->model()->updateFilesPriorities(filePriorities);
546 
547  // Expand single-item folders recursively
548  QModelIndex currentIndex;
549  while (m_contentModel->rowCount(currentIndex) == 1)
550  {
551  currentIndex = m_contentModel->index(0, 0, currentIndex);
552  m_ui->contentTreeView->setExpanded(currentIndex, true);
553  }
554 }
QStringList filePaths() const
void updateFilesPriorities(const QVector< BitTorrent::DownloadPriority > &fprio)
void setupModelData(const BitTorrent::AbstractFileStorage &info)
TorrentContentLayout detectContentLayout(const QStringList &filePaths)
void applyContentLayout(QStringList &filePaths, TorrentContentLayout contentLayout, const QString &rootFolder={})
QString findRootFolder(const QStringList &filePaths)
Definition: fs.cpp:403

References BitTorrent::applyContentLayout(), TorrentContentModel::clear(), BitTorrent::detectContentLayout(), BitTorrent::AddTorrentParams::filePaths, BitTorrent::TorrentInfo::filePaths(), Utils::Fs::findRootFolder(), TorrentContentModel::getFilePriorities(), hasMetadata(), m_contentModel, m_torrentInfo, m_torrentParams, m_ui, TorrentContentFilterModel::model(), TorrentContentModel::setupModelData(), and TorrentContentModel::updateFilesPriorities().

Referenced by AddNewTorrentDialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ displayContentTreeMenu

void AddNewTorrentDialog::displayContentTreeMenu ( const QPoint &  )
privateslot

Definition at line 659 of file addnewtorrentdialog.cpp.

660 {
661  const QModelIndexList selectedRows = m_ui->contentTreeView->selectionModel()->selectedRows(0);
662 
663  const auto applyPriorities = [this](const BitTorrent::DownloadPriority prio)
664  {
665  const QModelIndexList selectedRows = m_ui->contentTreeView->selectionModel()->selectedRows(0);
666  for (const QModelIndex &index : selectedRows)
667  {
668  m_contentModel->setData(index.sibling(index.row(), PRIORITY)
669  , static_cast<int>(prio));
670  }
671  };
672  const auto applyPrioritiesByOrder = [this]()
673  {
674  // Equally distribute the selected items into groups and for each group assign
675  // a download priority that will apply to each item. The number of groups depends on how
676  // many "download priority" are available to be assigned
677 
678  const QModelIndexList selectedRows = m_ui->contentTreeView->selectionModel()->selectedRows(0);
679 
680  const qsizetype priorityGroups = 3;
681  const auto priorityGroupSize = std::max<qsizetype>((selectedRows.length() / priorityGroups), 1);
682 
683  for (qsizetype i = 0; i < selectedRows.length(); ++i)
684  {
686  switch (i / priorityGroupSize)
687  {
688  case 0:
690  break;
691  case 1:
693  break;
694  default:
695  case 2:
697  break;
698  }
699 
700  const QModelIndex &index = selectedRows[i];
701  m_contentModel->setData(index.sibling(index.row(), PRIORITY)
702  , static_cast<int>(priority));
703  }
704  };
705 
706  QMenu *menu = new QMenu(this);
707  menu->setAttribute(Qt::WA_DeleteOnClose);
708  if (selectedRows.size() == 1)
709  {
710  menu->addAction(UIThemeManager::instance()->getIcon("edit-rename"), tr("Rename..."), this, &AddNewTorrentDialog::renameSelectedFile);
711  menu->addSeparator();
712 
713  QMenu *priorityMenu = menu->addMenu(tr("Priority"));
714  priorityMenu->addAction(tr("Do not download"), priorityMenu, [applyPriorities]()
715  {
716  applyPriorities(BitTorrent::DownloadPriority::Ignored);
717  });
718  priorityMenu->addAction(tr("Normal"), priorityMenu, [applyPriorities]()
719  {
720  applyPriorities(BitTorrent::DownloadPriority::Normal);
721  });
722  priorityMenu->addAction(tr("High"), priorityMenu, [applyPriorities]()
723  {
724  applyPriorities(BitTorrent::DownloadPriority::High);
725  });
726  priorityMenu->addAction(tr("Maximum"), priorityMenu, [applyPriorities]()
727  {
728  applyPriorities(BitTorrent::DownloadPriority::Maximum);
729  });
730  priorityMenu->addSeparator();
731  priorityMenu->addAction(tr("By shown file order"), priorityMenu, applyPrioritiesByOrder);
732  }
733  else
734  {
735  menu->addAction(tr("Do not download"), menu, [applyPriorities]()
736  {
737  applyPriorities(BitTorrent::DownloadPriority::Ignored);
738  });
739  menu->addAction(tr("Normal priority"), menu, [applyPriorities]()
740  {
741  applyPriorities(BitTorrent::DownloadPriority::Normal);
742  });
743  menu->addAction(tr("High priority"), menu, [applyPriorities]()
744  {
745  applyPriorities(BitTorrent::DownloadPriority::High);
746  });
747  menu->addAction(tr("Maximum priority"), menu, [applyPriorities]()
748  {
749  applyPriorities(BitTorrent::DownloadPriority::Maximum);
750  });
751  menu->addSeparator();
752  menu->addAction(tr("Priority by shown file order"), menu, applyPrioritiesByOrder);
753  }
754 
755  menu->popup(QCursor::pos());
756 }
static UIThemeManager * instance()
@ PRIORITY

References BitTorrent::High, BitTorrent::Ignored, UIThemeManager::instance(), m_contentModel, m_ui, BitTorrent::Maximum, BitTorrent::Normal, PRIORITY, and renameSelectedFile().

Referenced by setupTreeview().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ doNotDeleteTorrentClicked

void AddNewTorrentDialog::doNotDeleteTorrentClicked ( bool  checked)
privateslot

Definition at line 972 of file addnewtorrentdialog.cpp.

973 {
974  m_torrentGuard->setAutoRemove(!checked);
975 }

References m_torrentGuard.

Referenced by AddNewTorrentDialog().

Here is the caller graph for this function:

◆ handleDownloadFinished

void AddNewTorrentDialog::handleDownloadFinished ( const Net::DownloadResult downloadResult)
privateslot

Definition at line 906 of file addnewtorrentdialog.cpp.

907 {
908  switch (downloadResult.status)
909  {
911  {
912  const nonstd::expected<BitTorrent::TorrentInfo, QString> result = BitTorrent::TorrentInfo::load(downloadResult.data);
913  if (!result)
914  {
915  RaisedMessageBox::critical(this, tr("Invalid torrent"), tr("Failed to load from URL: %1.\nError: %2")
916  .arg(downloadResult.url, result.error()));
917  return;
918  }
919 
920  m_torrentInfo = result.value();
921  m_torrentGuard = std::make_unique<TorrentFileGuard>();
922 
923  if (loadTorrentImpl())
924  open();
925  else
926  deleteLater();
927  }
928  break;
930  if (loadMagnet(BitTorrent::MagnetUri(downloadResult.magnet)))
931  open();
932  else
933  deleteLater();
934  break;
935  default:
936  RaisedMessageBox::critical(this, tr("Download Error"),
937  tr("Cannot download '%1': %2").arg(downloadResult.url, downloadResult.errorString));
938  deleteLater();
939  }
940 }
bool loadMagnet(const BitTorrent::MagnetUri &magnetUri)
static nonstd::expected< TorrentInfo, QString > load(const QByteArray &data) noexcept
Definition: torrentinfo.cpp:89
static QMessageBox::StandardButton critical(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons=QMessageBox::Ok, QMessageBox::StandardButton defaultButton=QMessageBox::NoButton)
DownloadStatus status

References RaisedMessageBox::critical(), Net::DownloadResult::data, Net::DownloadResult::errorString, BitTorrent::TorrentInfo::load(), loadMagnet(), loadTorrentImpl(), m_torrentGuard, m_torrentInfo, Net::DownloadResult::magnet, Net::RedirectedToMagnet, Net::DownloadResult::status, Net::Success, and Net::DownloadResult::url.

Referenced by show().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ hasMetadata()

bool AddNewTorrentDialog::hasMetadata ( ) const
private

Definition at line 580 of file addnewtorrentdialog.cpp.

581 {
582  return m_torrentInfo.isValid();
583 }

References BitTorrent::TorrentInfo::isValid(), and m_torrentInfo.

Referenced by accept(), contentLayoutChanged(), reject(), renameSelectedFile(), saveTorrentFile(), setupTreeview(), and updateDiskSpaceLabel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ isEnabled()

◆ isTopLevel()

bool AddNewTorrentDialog::isTopLevel ( )
static

Definition at line 267 of file addnewtorrentdialog.cpp.

268 {
269  return settings()->loadValue(KEY_TOPLEVEL, true);
270 }

References anonymous_namespace{addnewtorrentdialog.cpp}::KEY_TOPLEVEL, SettingsStorage::loadValue(), and anonymous_namespace{addnewtorrentdialog.cpp}::settings().

Referenced by OptionsDialog::loadOptions(), and showEvent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ loadMagnet()

bool AddNewTorrentDialog::loadMagnet ( const BitTorrent::MagnetUri magnetUri)
private

Definition at line 396 of file addnewtorrentdialog.cpp.

397 {
398  if (!magnetUri.isValid())
399  {
400  RaisedMessageBox::critical(this, tr("Invalid magnet link"), tr("This magnet link was not recognized"));
401  return false;
402  }
403 
404  m_torrentGuard = std::make_unique<TorrentFileGuard>();
405 
406  const auto torrentID = BitTorrent::TorrentID::fromInfoHash(magnetUri.infoHash());
407  // Prevent showing the dialog if download is already present
408  if (BitTorrent::Session::instance()->isKnownTorrent(torrentID))
409  {
410  BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(torrentID);
411  if (torrent)
412  {
413  if (torrent->isPrivate())
414  {
415  RaisedMessageBox::warning(this, tr("Torrent is already present"), tr("Torrent '%1' is already in the transfer list. Trackers haven't been merged because it is a private torrent.").arg(torrent->name()), QMessageBox::Ok);
416  }
417  else
418  {
419  torrent->addTrackers(magnetUri.trackers());
420  torrent->addUrlSeeds(magnetUri.urlSeeds());
421  RaisedMessageBox::information(this, tr("Torrent is already present"), tr("Magnet link '%1' is already in the transfer list. Trackers have been merged.").arg(torrent->name()), QMessageBox::Ok);
422  }
423  }
424  else
425  {
426  RaisedMessageBox::information(this, tr("Torrent is already present"), tr("Magnet link is already queued for processing."), QMessageBox::Ok);
427  }
428  return false;
429  }
430 
432 
433  // Set dialog title
434  const QString torrentName = magnetUri.name();
435  setWindowTitle(torrentName.isEmpty() ? tr("Magnet link") : torrentName);
436 
437  setupTreeview();
438  TMMChanged(m_ui->comboTTM->currentIndex());
439 
441  setMetadataProgressIndicator(true, tr("Retrieving metadata..."));
442  m_ui->labelInfohash1Data->setText(magnetUri.infoHash().v1().isValid() ? magnetUri.infoHash().v1().toString() : tr("N/A"));
443  m_ui->labelInfohash2Data->setText(magnetUri.infoHash().v2().isValid() ? magnetUri.infoHash().v2().toString() : tr("N/A"));
444 
445  m_magnetURI = magnetUri;
446  return true;
447 }
void setMetadataProgressIndicator(bool visibleIndicator, const QString &labelText={})
void updateMetadata(const BitTorrent::TorrentInfo &metadata)
SHA1Hash v1() const
Definition: infohash.cpp:44
SHA256Hash v2() const
Definition: infohash.cpp:53
QVector< TrackerEntry > trackers() const
Definition: magneturi.cpp:125
bool isValid() const
Definition: magneturi.cpp:110
InfoHash infoHash() const
Definition: magneturi.cpp:115
QString name() const
Definition: magneturi.cpp:120
QVector< QUrl > urlSeeds() const
Definition: magneturi.cpp:130
void metadataDownloaded(const TorrentInfo &info)
bool downloadMetadata(const MagnetUri &magnetUri)
Definition: session.cpp:2283
Torrent * findTorrent(const TorrentID &id) const
Definition: session.cpp:1742
virtual void addUrlSeeds(const QVector< QUrl > &urlSeeds)=0
virtual void addTrackers(const QVector< TrackerEntry > &trackers)=0
virtual bool isPrivate() const =0
virtual QString name() const =0
static TorrentID fromInfoHash(const InfoHash &infoHash)
Definition: infohash.cpp:81
QString toString() const
Definition: digest32.h:85
bool isValid() const
Definition: digest32.h:58
static QMessageBox::StandardButton information(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons=QMessageBox::Ok, QMessageBox::StandardButton defaultButton=QMessageBox::NoButton)
static QMessageBox::StandardButton warning(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons=QMessageBox::Ok, QMessageBox::StandardButton defaultButton=QMessageBox::NoButton)

References BitTorrent::Torrent::addTrackers(), BitTorrent::Torrent::addUrlSeeds(), RaisedMessageBox::critical(), BitTorrent::Session::downloadMetadata(), BitTorrent::Session::findTorrent(), BitTorrent::TorrentID::fromInfoHash(), BitTorrent::MagnetUri::infoHash(), RaisedMessageBox::information(), BitTorrent::Session::instance(), BitTorrent::Torrent::isPrivate(), BitTorrent::MagnetUri::isValid(), Digest32< N >::isValid(), m_magnetURI, m_torrentGuard, m_ui, BitTorrent::Session::metadataDownloaded(), BitTorrent::MagnetUri::name(), BitTorrent::Torrent::name(), setMetadataProgressIndicator(), setupTreeview(), TMMChanged(), Digest32< N >::toString(), BitTorrent::MagnetUri::trackers(), updateMetadata(), BitTorrent::MagnetUri::urlSeeds(), BitTorrent::InfoHash::v1(), BitTorrent::InfoHash::v2(), and RaisedMessageBox::warning().

Referenced by handleDownloadFinished().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ loadState()

void AddNewTorrentDialog::loadState ( )
private

Definition at line 296 of file addnewtorrentdialog.cpp.

297 {
299  m_ui->splitter->restoreState(m_storeSplitterState);;
300 }
void resize(QWidget *widget, const QSize &newSize={})
Definition: utils.cpp:54

References m_storeDialogSize, m_storeSplitterState, m_ui, and Utils::Gui::resize().

Referenced by AddNewTorrentDialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ loadTorrentFile()

bool AddNewTorrentDialog::loadTorrentFile ( const QString &  torrentPath)
private

Definition at line 339 of file addnewtorrentdialog.cpp.

340 {
341  const QString decodedPath = torrentPath.startsWith("file://", Qt::CaseInsensitive)
342  ? QUrl::fromEncoded(torrentPath.toLocal8Bit()).toLocalFile()
343  : torrentPath;
344 
345  const nonstd::expected<BitTorrent::TorrentInfo, QString> result = BitTorrent::TorrentInfo::loadFromFile(decodedPath);
346  if (!result)
347  {
348  RaisedMessageBox::critical(this, tr("Invalid torrent")
349  , tr("Failed to load the torrent: %1.\nError: %2", "Don't remove the '\n' characters. They insert a newline.")
350  .arg(Utils::Fs::toNativePath(decodedPath), result.error()));
351  return false;
352  }
353 
354  m_torrentInfo = result.value();
355  m_torrentGuard = std::make_unique<TorrentFileGuard>(decodedPath);
356 
357  return loadTorrentImpl();
358 }
static nonstd::expected< TorrentInfo, QString > loadFromFile(const QString &path) noexcept

References RaisedMessageBox::critical(), BitTorrent::TorrentInfo::loadFromFile(), loadTorrentImpl(), m_torrentGuard, m_torrentInfo, and Utils::Fs::toNativePath().

Here is the call graph for this function:

◆ loadTorrentImpl()

bool AddNewTorrentDialog::loadTorrentImpl ( )
private

Definition at line 360 of file addnewtorrentdialog.cpp.

361 {
363 
364  // Prevent showing the dialog if download is already present
365  if (BitTorrent::Session::instance()->isKnownTorrent(torrentID))
366  {
367  BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(torrentID);
368  if (torrent)
369  {
370  if (torrent->isPrivate() || m_torrentInfo.isPrivate())
371  {
372  RaisedMessageBox::warning(this, tr("Torrent is already present"), tr("Torrent '%1' is already in the transfer list. Trackers haven't been merged because it is a private torrent.").arg(torrent->name()), QMessageBox::Ok);
373  }
374  else
375  {
376  torrent->addTrackers(m_torrentInfo.trackers());
377  torrent->addUrlSeeds(m_torrentInfo.urlSeeds());
378  RaisedMessageBox::information(this, tr("Torrent is already present"), tr("Torrent '%1' is already in the transfer list. Trackers have been merged.").arg(torrent->name()), QMessageBox::Ok);
379  }
380  }
381  else
382  {
383  RaisedMessageBox::information(this, tr("Torrent is already present"), tr("Torrent is already queued for processing."), QMessageBox::Ok);
384  }
385  return false;
386  }
387 
388  m_ui->labelInfohash1Data->setText(m_torrentInfo.infoHash().v1().isValid() ? m_torrentInfo.infoHash().v1().toString() : tr("N/A"));
389  m_ui->labelInfohash2Data->setText(m_torrentInfo.infoHash().v2().isValid() ? m_torrentInfo.infoHash().v2().toString() : tr("N/A"));
390  setupTreeview();
391  TMMChanged(m_ui->comboTTM->currentIndex());
392 
393  return true;
394 }
QVector< QUrl > urlSeeds() const
QVector< TrackerEntry > trackers() const
InfoHash infoHash() const

References BitTorrent::Torrent::addTrackers(), BitTorrent::Torrent::addUrlSeeds(), BitTorrent::Session::findTorrent(), BitTorrent::TorrentID::fromInfoHash(), BitTorrent::TorrentInfo::infoHash(), RaisedMessageBox::information(), BitTorrent::Session::instance(), BitTorrent::TorrentInfo::isPrivate(), BitTorrent::Torrent::isPrivate(), Digest32< N >::isValid(), m_torrentInfo, m_ui, BitTorrent::Torrent::name(), setupTreeview(), TMMChanged(), Digest32< N >::toString(), BitTorrent::TorrentInfo::trackers(), BitTorrent::TorrentInfo::urlSeeds(), BitTorrent::InfoHash::v1(), BitTorrent::InfoHash::v2(), and RaisedMessageBox::warning().

Referenced by handleDownloadFinished(), and loadTorrentFile().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ onDownloadPathChanged

void AddNewTorrentDialog::onDownloadPathChanged ( const QString &  newPath)
privateslot

Definition at line 495 of file addnewtorrentdialog.cpp.

496 {
497  Q_UNUSED(newPath);
498  // Remember index
499  const int currentPathIndex = m_ui->downloadPath->currentIndex();
500  if (currentPathIndex >= 0)
501  m_downloadPathIndex = m_ui->downloadPath->currentIndex();
502 }

References m_downloadPathIndex, and m_ui.

Referenced by AddNewTorrentDialog().

Here is the caller graph for this function:

◆ onSavePathChanged

void AddNewTorrentDialog::onSavePathChanged ( const QString &  newPath)
privateslot

Definition at line 487 of file addnewtorrentdialog.cpp.

488 {
489  Q_UNUSED(newPath);
490  // Remember index
491  m_savePathIndex = m_ui->savePath->currentIndex();
493 }

References m_savePathIndex, m_ui, and updateDiskSpaceLabel().

Referenced by AddNewTorrentDialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ onUseDownloadPathChanged

void AddNewTorrentDialog::onUseDownloadPathChanged ( bool  checked)
privateslot

Definition at line 504 of file addnewtorrentdialog.cpp.

505 {
506  m_useDownloadPath = checked;
507  m_ui->downloadPath->setCurrentIndex(checked ? m_downloadPathIndex : -1);
508 }

References m_downloadPathIndex, m_ui, and m_useDownloadPath.

Referenced by AddNewTorrentDialog().

Here is the caller graph for this function:

◆ populateSavePaths()

void AddNewTorrentDialog::populateSavePaths ( )
private

Definition at line 585 of file addnewtorrentdialog.cpp.

586 {
587  const auto *btSession = BitTorrent::Session::instance();
588 
589  m_ui->savePath->blockSignals(true);
590  m_ui->savePath->clear();
591  const auto savePathHistory = settings()->loadValue<QStringList>(KEY_SAVEPATHHISTORY);
592  if (savePathHistory.size() > 0)
593  {
594  for (const QString &path : savePathHistory)
595  m_ui->savePath->addItem(path);
596  }
597  else
598  {
599  m_ui->savePath->addItem(btSession->savePath());
600  }
601 
602  if (m_savePathIndex >= 0)
603  {
604  m_ui->savePath->setCurrentIndex(std::min(m_savePathIndex, (m_ui->savePath->count() - 1)));
605  }
606  else
607  {
608  if (!m_torrentParams.savePath.isEmpty())
609  setPath(m_ui->savePath, m_torrentParams.savePath);
610  else if (!m_storeRememberLastSavePath)
611  setPath(m_ui->savePath, btSession->savePath());
612  else
613  m_ui->savePath->setCurrentIndex(0);
614 
615  m_savePathIndex = m_ui->savePath->currentIndex();
616  }
617 
618  m_ui->savePath->blockSignals(false);
619 
620  m_ui->downloadPath->blockSignals(true);
621  m_ui->downloadPath->clear();
622  const auto downloadPathHistory = settings()->loadValue<QStringList>(KEY_DOWNLOADPATHHISTORY);
623  if (downloadPathHistory.size() > 0)
624  {
625  for (const QString &path : downloadPathHistory)
626  m_ui->downloadPath->addItem(path);
627  }
628  else
629  {
630  m_ui->downloadPath->addItem(btSession->downloadPath());
631  }
632 
633  if (m_downloadPathIndex >= 0)
634  {
635  m_ui->downloadPath->setCurrentIndex(m_useDownloadPath ? std::min(m_downloadPathIndex, (m_ui->downloadPath->count() - 1)) : -1);
636  m_ui->groupBoxDownloadPath->setChecked(m_useDownloadPath);
637  }
638  else
639  {
640  const bool useDownloadPath = m_torrentParams.useDownloadPath.value_or(btSession->isDownloadPathEnabled());
641  m_ui->groupBoxDownloadPath->setChecked(useDownloadPath);
642 
643  if (!m_torrentParams.downloadPath.isEmpty())
644  setPath(m_ui->downloadPath, m_torrentParams.downloadPath);
645  else if (!m_storeRememberLastSavePath)
646  setPath(m_ui->downloadPath, btSession->downloadPath());
647  else
648  m_ui->downloadPath->setCurrentIndex(0);
649 
650  m_downloadPathIndex = m_ui->downloadPath->currentIndex();
651  if (!useDownloadPath)
652  m_ui->downloadPath->setCurrentIndex(-1);
653  }
654 
655  m_ui->downloadPath->blockSignals(false);
656  m_ui->groupBoxDownloadPath->blockSignals(false);
657 }
void setPath(FileSystemPathComboEdit *fsPathEdit, const QString &newPath)

References BitTorrent::AddTorrentParams::downloadPath, BitTorrent::Session::instance(), anonymous_namespace{addnewtorrentdialog.cpp}::KEY_DOWNLOADPATHHISTORY, anonymous_namespace{addnewtorrentdialog.cpp}::KEY_SAVEPATHHISTORY, SettingsStorage::loadValue(), m_downloadPathIndex, m_savePathIndex, m_storeRememberLastSavePath, m_torrentParams, m_ui, m_useDownloadPath, BitTorrent::AddTorrentParams::savePath, anonymous_namespace{addnewtorrentdialog.cpp}::setPath(), anonymous_namespace{addnewtorrentdialog.cpp}::settings(), and BitTorrent::AddTorrentParams::useDownloadPath.

Referenced by TMMChanged().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reject

void AddNewTorrentDialog::reject ( )
overrideprivateslot

Definition at line 809 of file addnewtorrentdialog.cpp.

810 {
811  if (!hasMetadata())
812  {
815  }
816 
817  QDialog::reject();
818 }
TorrentID toTorrentID() const
Definition: infohash.cpp:62
bool cancelDownloadMetadata(const TorrentID &id)
Definition: session.cpp:1850

References BitTorrent::Session::cancelDownloadMetadata(), hasMetadata(), BitTorrent::MagnetUri::infoHash(), BitTorrent::Session::instance(), m_magnetURI, setMetadataProgressIndicator(), and BitTorrent::InfoHash::toTorrentID().

Here is the call graph for this function:

◆ renameSelectedFile

void AddNewTorrentDialog::renameSelectedFile ( )
privateslot

Definition at line 977 of file addnewtorrentdialog.cpp.

978 {
979  if (hasMetadata())
980  {
981  FileStorageAdaptor fileStorageAdaptor {m_torrentInfo, m_torrentParams.filePaths};
982  m_ui->contentTreeView->renameSelectedFile(fileStorageAdaptor);
983  }
984 }

References BitTorrent::AddTorrentParams::filePaths, hasMetadata(), m_torrentInfo, m_torrentParams, and m_ui.

Referenced by AddNewTorrentDialog(), and displayContentTreeMenu().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ savePathHistoryLength()

int AddNewTorrentDialog::savePathHistoryLength ( )
static

Definition at line 277 of file addnewtorrentdialog.cpp.

278 {
279  const int defaultHistoryLength = 8;
280  const int value = settings()->loadValue(KEY_SAVEPATHHISTORYLENGTH, defaultHistoryLength);
281  return std::clamp(value, minPathHistoryLength, maxPathHistoryLength);
282 }
static const int minPathHistoryLength
static const int maxPathHistoryLength
T value(const QString &key, const T &defaultValue={})
Definition: preferences.cpp:64

References anonymous_namespace{addnewtorrentdialog.cpp}::KEY_SAVEPATHHISTORYLENGTH, SettingsStorage::loadValue(), maxPathHistoryLength, minPathHistoryLength, anonymous_namespace{addnewtorrentdialog.cpp}::settings(), and anonymous_namespace{preferences.cpp}::value().

Referenced by accept(), AdvancedSettings::loadAdvancedSettings(), and setSavePathHistoryLength().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ saveState()

void AddNewTorrentDialog::saveState ( )
private

Definition at line 302 of file addnewtorrentdialog.cpp.

303 {
304  m_storeDialogSize = size();
305  m_storeSplitterState = m_ui->splitter->saveState();
306  if (m_contentModel)
307  m_storeTreeHeaderState = m_ui->contentTreeView->header()->saveState();
308 }

References m_contentModel, m_storeDialogSize, m_storeSplitterState, m_storeTreeHeaderState, and m_ui.

Referenced by ~AddNewTorrentDialog().

Here is the caller graph for this function:

◆ saveTorrentFile()

void AddNewTorrentDialog::saveTorrentFile ( )
private

Definition at line 556 of file addnewtorrentdialog.cpp.

557 {
558  Q_ASSERT(hasMetadata());
559 
560  const QString torrentFileExtension {C_TORRENT_FILE_EXTENSION};
561  const QString filter {tr("Torrent file (*%1)").arg(torrentFileExtension)};
562 
563  QString path = QFileDialog::getSaveFileName(
564  this, tr("Save as torrent file")
565  , QDir::home().absoluteFilePath(m_torrentInfo.name() + torrentFileExtension)
566  , filter);
567  if (path.isEmpty()) return;
568 
569  if (!path.endsWith(torrentFileExtension, Qt::CaseInsensitive))
570  path += torrentFileExtension;
571 
572  const nonstd::expected<void, QString> result = m_torrentInfo.saveToFile(path);
573  if (!result)
574  {
575  QMessageBox::critical(this, tr("I/O Error")
576  , tr("Couldn't export torrent metadata file '%1'. Reason: %2.").arg(path, result.error()));
577  }
578 }
QString name() const
nonstd::expected< void, QString > saveToFile(const QString &path) const
const char C_TORRENT_FILE_EXTENSION[]
Definition: global.h:38

References C_TORRENT_FILE_EXTENSION, hasMetadata(), m_torrentInfo, BitTorrent::TorrentInfo::name(), and BitTorrent::TorrentInfo::saveToFile().

Referenced by AddNewTorrentDialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setEnabled()

void AddNewTorrentDialog::setEnabled ( bool  value)
static

Definition at line 262 of file addnewtorrentdialog.cpp.

263 {
265 }
void storeValue(const QString &key, const T &value)

References anonymous_namespace{addnewtorrentdialog.cpp}::KEY_ENABLED, anonymous_namespace{addnewtorrentdialog.cpp}::settings(), SettingsStorage::storeValue(), and anonymous_namespace{preferences.cpp}::value().

Referenced by accept(), and OptionsDialog::saveOptions().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setMetadataProgressIndicator()

void AddNewTorrentDialog::setMetadataProgressIndicator ( bool  visibleIndicator,
const QString &  labelText = {} 
)
private

Definition at line 844 of file addnewtorrentdialog.cpp.

845 {
846  // Always show info label when waiting for metadata
847  m_ui->lblMetaLoading->setVisible(true);
848  m_ui->lblMetaLoading->setText(labelText);
849  m_ui->progMetaLoading->setVisible(visibleIndicator);
850 }

References m_ui.

Referenced by loadMagnet(), reject(), and updateMetadata().

Here is the caller graph for this function:

◆ setSavePathHistoryLength()

void AddNewTorrentDialog::setSavePathHistoryLength ( int  value)
static

Definition at line 284 of file addnewtorrentdialog.cpp.

285 {
286  const int clampedValue = qBound(minPathHistoryLength, value, maxPathHistoryLength);
287  const int oldValue = savePathHistoryLength();
288  if (clampedValue == oldValue)
289  return;
290 
293  , QStringList(settings()->loadValue<QStringList>(KEY_SAVEPATHHISTORY).mid(0, clampedValue)));
294 }

References anonymous_namespace{addnewtorrentdialog.cpp}::KEY_SAVEPATHHISTORY, anonymous_namespace{addnewtorrentdialog.cpp}::KEY_SAVEPATHHISTORYLENGTH, maxPathHistoryLength, minPathHistoryLength, savePathHistoryLength(), anonymous_namespace{addnewtorrentdialog.cpp}::settings(), SettingsStorage::storeValue(), and anonymous_namespace{preferences.cpp}::value().

Referenced by AdvancedSettings::saveAdvancedSettings().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setTopLevel()

void AddNewTorrentDialog::setTopLevel ( bool  value)
static

Definition at line 272 of file addnewtorrentdialog.cpp.

273 {
275 }

References anonymous_namespace{addnewtorrentdialog.cpp}::KEY_TOPLEVEL, anonymous_namespace{addnewtorrentdialog.cpp}::settings(), SettingsStorage::storeValue(), and anonymous_namespace{preferences.cpp}::value().

Referenced by OptionsDialog::saveOptions().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setupTreeview()

void AddNewTorrentDialog::setupTreeview ( )
private

Definition at line 852 of file addnewtorrentdialog.cpp.

853 {
854  if (!hasMetadata())
855  {
856  m_ui->labelCommentData->setText(tr("Not Available", "This comment is unavailable"));
857  m_ui->labelDateData->setText(tr("Not Available", "This date is unavailable"));
858  }
859  else
860  {
861  // Set dialog title
862  setWindowTitle(m_torrentInfo.name());
863 
864  // Set torrent information
865  m_ui->labelCommentData->setText(Utils::Misc::parseHtmlLinks(m_torrentInfo.comment().toHtmlEscaped()));
866  m_ui->labelDateData->setText(!m_torrentInfo.creationDate().isNull() ? QLocale().toString(m_torrentInfo.creationDate(), QLocale::ShortFormat) : tr("Not available"));
867 
868  // Prepare content tree
871  m_ui->contentTreeView->setModel(m_contentModel);
872  m_contentDelegate = new PropListDelegate(nullptr);
873  m_ui->contentTreeView->setItemDelegate(m_contentDelegate);
874  connect(m_ui->contentTreeView, &QAbstractItemView::clicked, m_ui->contentTreeView
875  , qOverload<const QModelIndex &>(&QAbstractItemView::edit));
876  connect(m_ui->contentTreeView, &QWidget::customContextMenuRequested, this, &AddNewTorrentDialog::displayContentTreeMenu);
877 
878  const auto contentLayout = ((m_ui->contentLayoutComboBox->currentIndex() == 0)
880  : static_cast<BitTorrent::TorrentContentLayout>(m_ui->contentLayoutComboBox->currentIndex()));
881  if (m_torrentParams.filePaths.isEmpty())
884  // List files in torrent
886  if (const QByteArray state = m_storeTreeHeaderState; !state.isEmpty())
887  m_ui->contentTreeView->header()->restoreState(state);
888 
889  // Hide useless columns after loading the header state
890  m_ui->contentTreeView->hideColumn(PROGRESS);
891  m_ui->contentTreeView->hideColumn(REMAINING);
892  m_ui->contentTreeView->hideColumn(AVAILABILITY);
893 
894  // Expand single-item folders recursively
895  QModelIndex currentIndex;
896  while (m_contentModel->rowCount(currentIndex) == 1)
897  {
898  currentIndex = m_contentModel->index(0, 0, currentIndex);
899  m_ui->contentTreeView->setExpanded(currentIndex, true);
900  }
901  }
902 
904 }
void displayContentTreeMenu(const QPoint &)
QString comment() const
QDateTime creationDate() const
QString parseHtmlLinks(const QString &rawText)
Definition: misc.cpp:404
QString toString(const lt::socket_type_t socketType)
Definition: session.cpp:183
@ AVAILABILITY
@ REMAINING
@ PROGRESS

References BitTorrent::applyContentLayout(), AVAILABILITY, BitTorrent::TorrentInfo::comment(), BitTorrent::TorrentInfo::creationDate(), BitTorrent::detectContentLayout(), displayContentTreeMenu(), BitTorrent::AddTorrentParams::filePaths, BitTorrent::TorrentInfo::filePaths(), TorrentContentModel::filteredFilesChanged(), Utils::Fs::findRootFolder(), hasMetadata(), m_contentDelegate, m_contentModel, m_storeTreeHeaderState, m_torrentInfo, m_torrentParams, m_ui, TorrentContentFilterModel::model(), BitTorrent::TorrentInfo::name(), Utils::Misc::parseHtmlLinks(), PROGRESS, REMAINING, TorrentContentModel::setupModelData(), anonymous_namespace{session.cpp}::toString(), and updateDiskSpaceLabel().

Referenced by loadMagnet(), loadTorrentImpl(), and updateMetadata().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ show() [1/2]

void AddNewTorrentDialog::show ( const QString &  source,
const BitTorrent::AddTorrentParams inParams,
QWidget *  parent 
)
static

Definition at line 310 of file addnewtorrentdialog.cpp.

311 {
312  auto *dlg = new AddNewTorrentDialog(inParams, parent);
313 
315  {
316  // Launch downloader
320  return;
321  }
322 
323  const BitTorrent::MagnetUri magnetUri(source);
324  const bool isLoaded = magnetUri.isValid()
325  ? dlg->loadMagnet(magnetUri)
326  : dlg->loadTorrentFile(source);
327 
328  if (isLoaded)
329  dlg->QDialog::show();
330  else
331  delete dlg;
332 }
AddNewTorrentDialog(const BitTorrent::AddTorrentParams &inParams, QWidget *parent)
void handleDownloadFinished(const Net::DownloadResult &downloadResult)
static bool hasSupportedScheme(const QString &url)
DownloadHandler * download(const DownloadRequest &downloadRequest)
static DownloadManager * instance()
const int MAX_TORRENT_SIZE
Definition: global.h:39

References AddNewTorrentDialog(), Net::DownloadManager::download(), handleDownloadFinished(), Net::DownloadManager::hasSupportedScheme(), Net::DownloadManager::instance(), BitTorrent::MagnetUri::isValid(), MAX_TORRENT_SIZE, and anonymous_namespace{misc.cpp}::source.

Referenced by SearchJobWidget::addTorrentToSession(), MainWindow::downloadFromURLList(), RSSWidget::downloadSelectedTorrents(), MainWindow::dropEvent(), MainWindow::keyPressEvent(), MainWindow::on_actionOpen_triggered(), Application::processParams(), and show().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ show() [2/2]

void AddNewTorrentDialog::show ( const QString &  source,
QWidget *  parent 
)
static

Definition at line 334 of file addnewtorrentdialog.cpp.

335 {
337 }
static void show(const QString &source, const BitTorrent::AddTorrentParams &inParams, QWidget *parent)

References show(), and anonymous_namespace{misc.cpp}::source.

Here is the call graph for this function:

◆ showEvent()

void AddNewTorrentDialog::showEvent ( QShowEvent *  event)
overrideprivate

Definition at line 449 of file addnewtorrentdialog.cpp.

450 {
451  QDialog::showEvent(event);
452  if (!isTopLevel()) return;
453 
454  activateWindow();
455  raise();
456 }

References isTopLevel().

Here is the call graph for this function:

◆ TMMChanged

void AddNewTorrentDialog::TMMChanged ( int  index)
privateslot

Definition at line 942 of file addnewtorrentdialog.cpp.

943 {
944  if (index != 1)
945  { // 0 is Manual mode and 1 is Automatic mode. Handle all non 1 values as manual mode.
947  m_ui->groupBoxSavePath->setEnabled(true);
948  }
949  else
950  {
951  const auto *session = BitTorrent::Session::instance();
952 
953  m_ui->groupBoxSavePath->setEnabled(false);
954 
955  m_ui->savePath->blockSignals(true);
956  m_ui->savePath->clear();
957  const QString savePath = session->categorySavePath(m_ui->categoryComboBox->currentText());
958  m_ui->savePath->addItem(savePath);
959 
960  m_ui->downloadPath->blockSignals(true);
961  m_ui->downloadPath->clear();
962  const QString downloadPath = session->categoryDownloadPath(m_ui->categoryComboBox->currentText());
963  m_ui->downloadPath->addItem(downloadPath);
964 
965  m_ui->groupBoxDownloadPath->blockSignals(true);
966  m_ui->groupBoxDownloadPath->setChecked(!downloadPath.isEmpty());
967 
969  }
970 }

References BitTorrent::Session::instance(), m_ui, populateSavePaths(), and updateDiskSpaceLabel().

Referenced by loadMagnet(), and loadTorrentImpl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateDiskSpaceLabel

void AddNewTorrentDialog::updateDiskSpaceLabel ( )
privateslot

Definition at line 458 of file addnewtorrentdialog.cpp.

459 {
460  // Determine torrent size
461  qlonglong torrentSize = 0;
462 
463  if (hasMetadata())
464  {
465  if (m_contentModel)
466  {
467  const QVector<BitTorrent::DownloadPriority> priorities = m_contentModel->model()->getFilePriorities();
468  Q_ASSERT(priorities.size() == m_torrentInfo.filesCount());
469  for (int i = 0; i < priorities.size(); ++i)
470  {
471  if (priorities[i] > BitTorrent::DownloadPriority::Ignored)
472  torrentSize += m_torrentInfo.fileSize(i);
473  }
474  }
475  else
476  {
477  torrentSize = m_torrentInfo.totalSize();
478  }
479  }
480 
481  const QString sizeString = tr("%1 (Free space on disk: %2)").arg(
482  ((torrentSize > 0) ? Utils::Misc::friendlyUnit(torrentSize) : tr("Not available", "This size is unavailable."))
483  , Utils::Misc::friendlyUnit(Utils::Fs::freeDiskSpaceOnPath(m_ui->savePath->selectedPath())));
484  m_ui->labelSizeData->setText(sizeString);
485 }
qlonglong totalSize() const
qlonglong fileSize(int index) const
qint64 freeDiskSpaceOnPath(const QString &path)
Definition: fs.cpp:271
QString friendlyUnit(qint64 bytes, bool isSpeed=false)
Definition: misc.cpp:261

References BitTorrent::TorrentInfo::filesCount(), BitTorrent::TorrentInfo::fileSize(), Utils::Fs::freeDiskSpaceOnPath(), Utils::Misc::friendlyUnit(), TorrentContentModel::getFilePriorities(), hasMetadata(), BitTorrent::Ignored, m_contentModel, m_torrentInfo, m_ui, TorrentContentFilterModel::model(), and BitTorrent::TorrentInfo::totalSize().

Referenced by categoryChanged(), onSavePathChanged(), setupTreeview(), and TMMChanged().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateMetadata

void AddNewTorrentDialog::updateMetadata ( const BitTorrent::TorrentInfo metadata)
privateslot

Definition at line 820 of file addnewtorrentdialog.cpp.

821 {
822  Q_ASSERT(metadata.isValid());
823 
824  if (metadata.infoHash() != m_magnetURI.infoHash()) return;
825 
827 
828  // Good to go
829  m_torrentInfo = metadata;
830  setMetadataProgressIndicator(true, tr("Parsing metadata..."));
831 
832  // Update UI
833  setupTreeview();
834  setMetadataProgressIndicator(false, tr("Metadata retrieval complete"));
835 
836  m_ui->buttonSave->setVisible(true);
837  if (m_torrentInfo.infoHash().v2().isValid())
838  {
839  m_ui->buttonSave->setEnabled(false);
840  m_ui->buttonSave->setToolTip(tr("Cannot create v2 torrent until its data is fully downloaded."));
841  }
842 }

References BitTorrent::MagnetUri::infoHash(), BitTorrent::TorrentInfo::infoHash(), BitTorrent::Session::instance(), BitTorrent::TorrentInfo::isValid(), Digest32< N >::isValid(), m_magnetURI, m_torrentInfo, m_ui, BitTorrent::Session::metadataDownloaded(), setMetadataProgressIndicator(), setupTreeview(), and BitTorrent::InfoHash::v2().

Referenced by loadMagnet().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ m_contentDelegate

PropListDelegate* AddNewTorrentDialog::m_contentDelegate = nullptr
private

Definition at line 114 of file addnewtorrentdialog.h.

Referenced by setupTreeview(), and ~AddNewTorrentDialog().

◆ m_contentModel

TorrentContentFilterModel* AddNewTorrentDialog::m_contentModel = nullptr
private

◆ m_downloadPathIndex

int AddNewTorrentDialog::m_downloadPathIndex = -1
private

◆ m_magnetURI

BitTorrent::MagnetUri AddNewTorrentDialog::m_magnetURI
private

Definition at line 115 of file addnewtorrentdialog.h.

Referenced by accept(), loadMagnet(), reject(), and updateMetadata().

◆ m_savePathIndex

int AddNewTorrentDialog::m_savePathIndex = -1
private

Definition at line 117 of file addnewtorrentdialog.h.

Referenced by onSavePathChanged(), and populateSavePaths().

◆ m_storeDefaultCategory

SettingValue<QString> AddNewTorrentDialog::m_storeDefaultCategory
private

Definition at line 124 of file addnewtorrentdialog.h.

Referenced by accept(), and AddNewTorrentDialog().

◆ m_storeDialogSize

SettingValue<QSize> AddNewTorrentDialog::m_storeDialogSize
private

Definition at line 123 of file addnewtorrentdialog.h.

Referenced by loadState(), and saveState().

◆ m_storeRememberLastSavePath

SettingValue<bool> AddNewTorrentDialog::m_storeRememberLastSavePath
private

Definition at line 125 of file addnewtorrentdialog.h.

Referenced by accept(), AddNewTorrentDialog(), and populateSavePaths().

◆ m_storeSplitterState

SettingValue<QByteArray> AddNewTorrentDialog::m_storeSplitterState
private

Definition at line 127 of file addnewtorrentdialog.h.

Referenced by loadState(), and saveState().

◆ m_storeTreeHeaderState

SettingValue<QByteArray> AddNewTorrentDialog::m_storeTreeHeaderState
private

Definition at line 126 of file addnewtorrentdialog.h.

Referenced by saveState(), and setupTreeview().

◆ m_torrentGuard

std::unique_ptr<TorrentFileGuard> AddNewTorrentDialog::m_torrentGuard
private

◆ m_torrentInfo

◆ m_torrentParams

BitTorrent::AddTorrentParams AddNewTorrentDialog::m_torrentParams
private

◆ m_ui

◆ m_useDownloadPath

bool AddNewTorrentDialog::m_useDownloadPath = false
private

Definition at line 119 of file addnewtorrentdialog.h.

Referenced by onUseDownloadPathChanged(), and populateSavePaths().

◆ maxPathHistoryLength

const int AddNewTorrentDialog::maxPathHistoryLength = 99
static

◆ minPathHistoryLength

const int AddNewTorrentDialog::minPathHistoryLength = 0
static

The documentation for this class was generated from the following files: