qBittorrent
SearchJobWidget Class Referencefinal

#include <searchjobwidget.h>

Inheritance diagram for SearchJobWidget:
Collaboration diagram for SearchJobWidget:

Public Types

enum class  NameFilteringMode { Everywhere , OnlyNames }
 
enum class  Status {
  Ongoing , Finished , Error , Aborted ,
  NoResults
}
 

Signals

void resultsCountUpdated ()
 
void statusChanged ()
 

Public Member Functions

 SearchJobWidget (SearchHandler *searchHandler, QWidget *parent=nullptr)
 
 ~SearchJobWidget () override
 
Status status () const
 
int visibleResultsCount () const
 
LineEditlineEditSearchResultsFilter () const
 
void cancelSearch ()
 

Protected Member Functions

void keyPressEvent (QKeyEvent *event) override
 

Private Types

enum class  AddTorrentOption { Default , ShowDialog , SkipDialog }
 

Private Member Functions

void loadSettings ()
 
void saveSettings () const
 
void updateFilter ()
 
void filterSearchResults (const QString &name)
 
void showFilterContextMenu (const QPoint &)
 
void contextMenuEvent (QContextMenuEvent *event) override
 
void displayToggleColumnsMenu (const QPoint &)
 
void onItemDoubleClicked (const QModelIndex &index)
 
void searchFinished (bool cancelled)
 
void searchFailed ()
 
void appendSearchResults (const QVector< SearchResult > &results)
 
void updateResultsCount ()
 
void setStatus (Status value)
 
void downloadTorrent (const QModelIndex &rowIndex, AddTorrentOption option=AddTorrentOption::Default)
 
void addTorrentToSession (const QString &source, AddTorrentOption option=AddTorrentOption::Default)
 
void fillFilterComboBoxes ()
 
NameFilteringMode filteringMode () const
 
QHeaderView * header () const
 
void setRowColor (int row, const QColor &color)
 
void downloadTorrents (AddTorrentOption option=AddTorrentOption::Default)
 
void openTorrentPages () const
 
void copyTorrentURLs () const
 
void copyTorrentDownloadLinks () const
 
void copyTorrentNames () const
 
void copyField (int column) const
 

Static Private Member Functions

static QString statusText (Status st)
 
static SettingValue< NameFilteringMode > & nameFilteringModeSetting ()
 

Private Attributes

Ui::SearchJobWidget * m_ui
 
SearchHandlerm_searchHandler
 
QStandardItemModel * m_searchListModel
 
SearchSortModelm_proxyModel
 
LineEditm_lineEditSearchResultsFilter
 
Status m_status = Status::Ongoing
 
bool m_noSearchResults = true
 

Detailed Description

Definition at line 53 of file searchjobwidget.h.

Member Enumeration Documentation

◆ AddTorrentOption

Enumerator
Default 
ShowDialog 
SkipDialog 

Definition at line 92 of file searchjobwidget.h.

93  {
94  Default,
95  ShowDialog,
96  SkipDialog,
97  };

◆ NameFilteringMode

Enumerator
Everywhere 
OnlyNames 

Definition at line 59 of file searchjobwidget.h.

60  {
61  Everywhere,
62  OnlyNames
63  };

◆ Status

Enumerator
Ongoing 
Finished 
Error 
Aborted 
NoResults 

Definition at line 66 of file searchjobwidget.h.

67  {
68  Ongoing,
69  Finished,
70  Error,
71  Aborted,
72  NoResults
73  };

Constructor & Destructor Documentation

◆ SearchJobWidget()

SearchJobWidget::SearchJobWidget ( SearchHandler searchHandler,
QWidget *  parent = nullptr 
)
explicit

Definition at line 57 of file searchjobwidget.cpp.

58  : QWidget(parent)
59  , m_ui(new Ui::SearchJobWidget)
60  , m_searchHandler(searchHandler)
61 {
62  m_ui->setupUi(this);
63 
64  // This hack fixes reordering of first column with Qt5.
65  // https://github.com/qtproject/qtbase/commit/e0fc088c0c8bc61dbcaf5928b24986cd61a22777
66  QTableView unused;
67  unused.setVerticalHeader(m_ui->resultsBrowser->header());
68  m_ui->resultsBrowser->header()->setParent(m_ui->resultsBrowser);
69  unused.setVerticalHeader(new QHeaderView(Qt::Horizontal));
70 
71  loadSettings();
72 
73  header()->setStretchLastSection(false);
74  header()->setTextElideMode(Qt::ElideRight);
75 
76  // Set Search results list model
77  m_searchListModel = new QStandardItemModel(0, SearchSortModel::NB_SEARCH_COLUMNS, this);
78  m_searchListModel->setHeaderData(SearchSortModel::NAME, Qt::Horizontal, tr("Name", "i.e: file name"));
79  m_searchListModel->setHeaderData(SearchSortModel::SIZE, Qt::Horizontal, tr("Size", "i.e: file size"));
80  m_searchListModel->setHeaderData(SearchSortModel::SEEDS, Qt::Horizontal, tr("Seeders", "i.e: Number of full sources"));
81  m_searchListModel->setHeaderData(SearchSortModel::LEECHES, Qt::Horizontal, tr("Leechers", "i.e: Number of partial sources"));
82  m_searchListModel->setHeaderData(SearchSortModel::ENGINE_URL, Qt::Horizontal, tr("Search engine"));
83  // Set columns text alignment
84  m_searchListModel->setHeaderData(SearchSortModel::SIZE, Qt::Horizontal, QVariant(Qt::AlignRight | Qt::AlignVCenter), Qt::TextAlignmentRole);
85  m_searchListModel->setHeaderData(SearchSortModel::SEEDS, Qt::Horizontal, QVariant(Qt::AlignRight | Qt::AlignVCenter), Qt::TextAlignmentRole);
86  m_searchListModel->setHeaderData(SearchSortModel::LEECHES, Qt::Horizontal, QVariant(Qt::AlignRight | Qt::AlignVCenter), Qt::TextAlignmentRole);
87 
88  m_proxyModel = new SearchSortModel(this);
89  m_proxyModel->setDynamicSortFilter(true);
90  m_proxyModel->setSourceModel(m_searchListModel);
91  m_proxyModel->setNameFilter(searchHandler->pattern());
92  m_ui->resultsBrowser->setModel(m_proxyModel);
93 
94  m_ui->resultsBrowser->hideColumn(SearchSortModel::DL_LINK); // Hide url column
95  m_ui->resultsBrowser->hideColumn(SearchSortModel::DESC_LINK);
96 
97  m_ui->resultsBrowser->setSelectionMode(QAbstractItemView::ExtendedSelection);
98  m_ui->resultsBrowser->setRootIsDecorated(false);
99  m_ui->resultsBrowser->setAllColumnsShowFocus(true);
100  m_ui->resultsBrowser->setSortingEnabled(true);
101  m_ui->resultsBrowser->setEditTriggers(QAbstractItemView::NoEditTriggers);
102 
103  // Ensure that at least one column is visible at all times
104  bool atLeastOne = false;
105  for (int i = 0; i < SearchSortModel::DL_LINK; ++i)
106  {
107  if (!m_ui->resultsBrowser->isColumnHidden(i))
108  {
109  atLeastOne = true;
110  break;
111  }
112  }
113  if (!atLeastOne)
114  m_ui->resultsBrowser->setColumnHidden(SearchSortModel::NAME, false);
115  // To also mitigate the above issue, we have to resize each column when
116  // its size is 0, because explicitly 'showing' the column isn't enough
117  // in the above scenario.
118  for (int i = 0; i < SearchSortModel::DL_LINK; ++i)
119  if ((m_ui->resultsBrowser->columnWidth(i) <= 0) && !m_ui->resultsBrowser->isColumnHidden(i))
120  m_ui->resultsBrowser->resizeColumnToContents(i);
121 
122  header()->setContextMenuPolicy(Qt::CustomContextMenu);
123  connect(header(), &QWidget::customContextMenuRequested, this, &SearchJobWidget::displayToggleColumnsMenu);
124  connect(header(), &QHeaderView::sectionResized, this, &SearchJobWidget::saveSettings);
125  connect(header(), &QHeaderView::sectionMoved, this, &SearchJobWidget::saveSettings);
126  connect(header(), &QHeaderView::sortIndicatorChanged, this, &SearchJobWidget::saveSettings);
127 
129 
130  updateFilter();
131 
133  m_lineEditSearchResultsFilter->setPlaceholderText(tr("Filter search results..."));
134  m_lineEditSearchResultsFilter->setContextMenuPolicy(Qt::CustomContextMenu);
135  connect(m_lineEditSearchResultsFilter, &QWidget::customContextMenuRequested, this, &SearchJobWidget::showFilterContextMenu);
136  m_ui->horizontalLayout->insertWidget(0, m_lineEditSearchResultsFilter);
137 
138  connect(m_lineEditSearchResultsFilter, &LineEdit::textChanged, this, &SearchJobWidget::filterSearchResults);
139  connect(m_ui->filterMode, qOverload<int>(&QComboBox::currentIndexChanged)
141  connect(m_ui->minSeeds, &QAbstractSpinBox::editingFinished, this, &SearchJobWidget::updateFilter);
142  connect(m_ui->minSeeds, qOverload<int>(&QSpinBox::valueChanged)
144  connect(m_ui->maxSeeds, &QAbstractSpinBox::editingFinished, this, &SearchJobWidget::updateFilter);
145  connect(m_ui->maxSeeds, qOverload<int>(&QSpinBox::valueChanged)
147  connect(m_ui->minSize, &QAbstractSpinBox::editingFinished, this, &SearchJobWidget::updateFilter);
148  connect(m_ui->minSize, qOverload<double>(&QDoubleSpinBox::valueChanged)
150  connect(m_ui->maxSize, &QAbstractSpinBox::editingFinished, this, &SearchJobWidget::updateFilter);
151  connect(m_ui->maxSize, qOverload<double>(&QDoubleSpinBox::valueChanged)
153  connect(m_ui->minSizeUnit, qOverload<int>(&QComboBox::currentIndexChanged)
155  connect(m_ui->maxSizeUnit, qOverload<int>(&QComboBox::currentIndexChanged)
157 
158  connect(m_ui->resultsBrowser, &QAbstractItemView::doubleClicked, this, &SearchJobWidget::onItemDoubleClicked);
159 
161  connect(searchHandler, &SearchHandler::searchFinished, this, &SearchJobWidget::searchFinished);
162  connect(searchHandler, &SearchHandler::searchFailed, this, &SearchJobWidget::searchFailed);
163  connect(this, &QObject::destroyed, searchHandler, &QObject::deleteLater);
164 
165  setStatusTip(statusText(m_status));
166 }
QString pattern() const
void searchFinished(bool cancelled=false)
void searchFailed()
void newSearchResults(const QVector< SearchResult > &results)
SearchSortModel * m_proxyModel
LineEdit * m_lineEditSearchResultsFilter
static QString statusText(Status st)
QHeaderView * header() const
void displayToggleColumnsMenu(const QPoint &)
void appendSearchResults(const QVector< SearchResult > &results)
void showFilterContextMenu(const QPoint &)
void saveSettings() const
void filterSearchResults(const QString &name)
void searchFinished(bool cancelled)
SearchHandler * m_searchHandler
QStandardItemModel * m_searchListModel
Ui::SearchJobWidget * m_ui
void onItemDoubleClicked(const QModelIndex &index)
void setNameFilter(const QString &searchTerm={})

References appendSearchResults(), SearchSortModel::DESC_LINK, displayToggleColumnsMenu(), SearchSortModel::DL_LINK, SearchSortModel::ENGINE_URL, fillFilterComboBoxes(), filterSearchResults(), header(), SearchSortModel::LEECHES, loadSettings(), m_lineEditSearchResultsFilter, m_proxyModel, m_searchListModel, m_status, m_ui, SearchSortModel::NAME, SearchSortModel::NB_SEARCH_COLUMNS, SearchHandler::newSearchResults(), onItemDoubleClicked(), SearchHandler::pattern(), saveSettings(), SearchHandler::searchFailed(), searchFailed(), searchFinished(), SearchHandler::searchFinished(), SearchSortModel::SEEDS, SearchSortModel::setNameFilter(), showFilterContextMenu(), SearchSortModel::SIZE, statusText(), and updateFilter().

Here is the call graph for this function:

◆ ~SearchJobWidget()

SearchJobWidget::~SearchJobWidget ( )
override

Definition at line 168 of file searchjobwidget.cpp.

169 {
170  saveSettings();
171  delete m_ui;
172 }

References m_ui, and saveSettings().

Here is the call graph for this function:

Member Function Documentation

◆ addTorrentToSession()

void SearchJobWidget::addTorrentToSession ( const QString &  source,
AddTorrentOption  option = AddTorrentOption::Default 
)
private

Definition at line 295 of file searchjobwidget.cpp.

296 {
297  if (source.isEmpty()) return;
298 
301  else
303 }
static void show(const QString &source, const BitTorrent::AddTorrentParams &inParams, QWidget *parent)
static Session * instance()
Definition: session.cpp:997
bool addTorrent(const QString &source, const AddTorrentParams &params=AddTorrentParams())
Definition: session.cpp:2007

References BitTorrent::Session::addTorrent(), Default, BitTorrent::Session::instance(), AddNewTorrentDialog::isEnabled(), AddNewTorrentDialog::show(), ShowDialog, and anonymous_namespace{misc.cpp}::source.

Referenced by downloadTorrent().

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

◆ appendSearchResults()

void SearchJobWidget::appendSearchResults ( const QVector< SearchResult > &  results)
private

Definition at line 510 of file searchjobwidget.cpp.

511 {
512  for (const SearchResult &result : results)
513  {
514  // Add item to search result list
515  int row = m_searchListModel->rowCount();
516  m_searchListModel->insertRow(row);
517 
518  const auto setModelData = [this, row] (const int column, const QString &displayData
519  , const QVariant &underlyingData, const Qt::Alignment textAlignmentData = {})
520  {
521  const QMap<int, QVariant> data =
522  {
523  {Qt::DisplayRole, displayData},
524  {SearchSortModel::UnderlyingDataRole, underlyingData},
525  {Qt::TextAlignmentRole, QVariant {textAlignmentData}}
526  };
527  m_searchListModel->setItemData(m_searchListModel->index(row, column), data);
528  };
529 
530  setModelData(SearchSortModel::NAME, result.fileName, result.fileName);
531  setModelData(SearchSortModel::DL_LINK, result.fileUrl, result.fileUrl);
532  setModelData(SearchSortModel::ENGINE_URL, result.siteUrl, result.siteUrl);
533  setModelData(SearchSortModel::DESC_LINK, result.descrLink, result.descrLink);
534  setModelData(SearchSortModel::SIZE, Utils::Misc::friendlyUnit(result.fileSize), result.fileSize, (Qt::AlignRight | Qt::AlignVCenter));
535  setModelData(SearchSortModel::SEEDS, QString::number(result.nbSeeders), result.nbSeeders, (Qt::AlignRight | Qt::AlignVCenter));
536  setModelData(SearchSortModel::LEECHES, QString::number(result.nbLeechers), result.nbLeechers, (Qt::AlignRight | Qt::AlignVCenter));
537  }
538 
540 }
QString friendlyUnit(qint64 bytes, bool isSpeed=false)
Definition: misc.cpp:261

References SearchSortModel::DESC_LINK, SearchSortModel::DL_LINK, SearchSortModel::ENGINE_URL, Utils::Misc::friendlyUnit(), SearchSortModel::LEECHES, m_searchListModel, SearchSortModel::NAME, SearchSortModel::SEEDS, SearchSortModel::SIZE, SearchSortModel::UnderlyingDataRole, and updateResultsCount().

Referenced by SearchJobWidget().

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

◆ cancelSearch()

void SearchJobWidget::cancelSearch ( )

Definition at line 209 of file searchjobwidget.cpp.

210 {
212 }

References SearchHandler::cancelSearch(), and m_searchHandler.

Here is the call graph for this function:

◆ contextMenuEvent()

void SearchJobWidget::contextMenuEvent ( QContextMenuEvent *  event)
overrideprivate

Definition at line 393 of file searchjobwidget.cpp.

394 {
395  auto *menu = new QMenu(this);
396  menu->setAttribute(Qt::WA_DeleteOnClose);
397 
398  menu->addAction(UIThemeManager::instance()->getIcon("download"), tr("Open download window")
399  , this, [this]() { downloadTorrents(AddTorrentOption::ShowDialog); });
400  menu->addAction(UIThemeManager::instance()->getIcon("download"), tr("Download")
401  , this, [this]() { downloadTorrents(AddTorrentOption::SkipDialog); });
402  menu->addSeparator();
403  menu->addAction(UIThemeManager::instance()->getIcon("application-x-mswinurl"), tr("Open description page")
405 
406  QMenu *copySubMenu = menu->addMenu(
407  UIThemeManager::instance()->getIcon("edit-copy"), tr("Copy"));
408 
409  copySubMenu->addAction(UIThemeManager::instance()->getIcon("edit-copy"), tr("Name")
411  copySubMenu->addAction(UIThemeManager::instance()->getIcon("edit-copy"), tr("Download link")
413  copySubMenu->addAction(UIThemeManager::instance()->getIcon("edit-copy"), tr("Description page URL")
415 
416  menu->popup(event->globalPos());
417 }
void openTorrentPages() const
void copyTorrentURLs() const
void copyTorrentNames() const
void downloadTorrents(AddTorrentOption option=AddTorrentOption::Default)
void copyTorrentDownloadLinks() const
static UIThemeManager * instance()
QIcon getIcon(const QString &iconId, const QString &fallback={}) const

References copyTorrentDownloadLinks(), copyTorrentNames(), copyTorrentURLs(), downloadTorrents(), UIThemeManager::getIcon(), UIThemeManager::instance(), openTorrentPages(), ShowDialog, and SkipDialog.

Here is the call graph for this function:

◆ copyField()

void SearchJobWidget::copyField ( int  column) const
private

Definition at line 248 of file searchjobwidget.cpp.

249 {
250  const QModelIndexList rows {m_ui->resultsBrowser->selectionModel()->selectedRows()};
251  QStringList list;
252 
253  for (const QModelIndex &rowIndex : rows)
254  {
255  const QString field = m_proxyModel->data(
256  m_proxyModel->index(rowIndex.row(), column)).toString();
257  if (!field.isEmpty())
258  list << field;
259  }
260 
261  if (!list.empty())
262  QApplication::clipboard()->setText(list.join('\n'));
263 }

References m_proxyModel, and m_ui.

Referenced by copyTorrentDownloadLinks(), copyTorrentNames(), and copyTorrentURLs().

Here is the caller graph for this function:

◆ copyTorrentDownloadLinks()

void SearchJobWidget::copyTorrentDownloadLinks ( ) const
private

Definition at line 238 of file searchjobwidget.cpp.

239 {
241 }
void copyField(int column) const

References copyField(), and SearchSortModel::DL_LINK.

Referenced by contextMenuEvent().

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

◆ copyTorrentNames()

void SearchJobWidget::copyTorrentNames ( ) const
private

Definition at line 243 of file searchjobwidget.cpp.

244 {
246 }

References copyField(), and SearchSortModel::NAME.

Referenced by contextMenuEvent().

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

◆ copyTorrentURLs()

void SearchJobWidget::copyTorrentURLs ( ) const
private

Definition at line 233 of file searchjobwidget.cpp.

234 {
236 }

References copyField(), and SearchSortModel::DESC_LINK.

Referenced by contextMenuEvent().

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

◆ displayToggleColumnsMenu()

void SearchJobWidget::displayToggleColumnsMenu ( const QPoint &  )
private

Definition at line 453 of file searchjobwidget.cpp.

454 {
455  auto menu = new QMenu(this);
456  menu->setAttribute(Qt::WA_DeleteOnClose);
457  menu->setTitle(tr("Column visibility"));
458 
459  for (int i = 0; i < SearchSortModel::DL_LINK; ++i)
460  {
461  QAction *myAct = menu->addAction(m_searchListModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString());
462  myAct->setCheckable(true);
463  myAct->setChecked(!m_ui->resultsBrowser->isColumnHidden(i));
464  myAct->setData(i);
465  }
466 
467  connect(menu, &QMenu::triggered, this, [this](const QAction *action)
468  {
469  int visibleCols = 0;
470  for (int i = 0; i < SearchSortModel::DL_LINK; ++i)
471  {
472  if (!m_ui->resultsBrowser->isColumnHidden(i))
473  ++visibleCols;
474 
475  if (visibleCols > 1)
476  break;
477  }
478 
479  const int col = action->data().toInt();
480 
481  if ((!m_ui->resultsBrowser->isColumnHidden(col)) && (visibleCols == 1))
482  return;
483 
484  m_ui->resultsBrowser->setColumnHidden(col, !m_ui->resultsBrowser->isColumnHidden(col));
485 
486  if ((!m_ui->resultsBrowser->isColumnHidden(col)) && (m_ui->resultsBrowser->columnWidth(col) <= 5))
487  m_ui->resultsBrowser->resizeColumnToContents(col);
488 
489  saveSettings();
490  });
491 
492  menu->popup(QCursor::pos());
493 }
QBITTORRENT_HAS_EXECINFO_H if(NOT QBITTORRENT_HAS_EXECINFO_H) message(FATAL_ERROR "execinfo.h header file not found.\n" "Please either disable the STACKTRACE feature or use a libc that has this header file
action
Definition: tstool.py:143

References tstool::action, SearchSortModel::DL_LINK, if(), m_searchListModel, m_ui, and saveSettings().

Referenced by SearchJobWidget().

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

◆ downloadTorrent()

void SearchJobWidget::downloadTorrent ( const QModelIndex &  rowIndex,
AddTorrentOption  option = AddTorrentOption::Default 
)
private

Definition at line 274 of file searchjobwidget.cpp.

275 {
276  const QString torrentUrl = m_proxyModel->data(
277  m_proxyModel->index(rowIndex.row(), SearchSortModel::DL_LINK)).toString();
278  const QString siteUrl = m_proxyModel->data(
279  m_proxyModel->index(rowIndex.row(), SearchSortModel::ENGINE_URL)).toString();
280 
281  if (torrentUrl.startsWith("magnet:", Qt::CaseInsensitive))
282  {
283  addTorrentToSession(torrentUrl, option);
284  }
285  else
286  {
287  SearchDownloadHandler *downloadHandler = m_searchHandler->manager()->downloadTorrent(siteUrl, torrentUrl);
288  connect(downloadHandler, &SearchDownloadHandler::downloadFinished
289  , this, [this, option](const QString &source) { addTorrentToSession(source, option); });
290  connect(downloadHandler, &SearchDownloadHandler::downloadFinished, downloadHandler, &SearchDownloadHandler::deleteLater);
291  }
292  setRowColor(rowIndex.row(), QApplication::palette().color(QPalette::LinkVisited));
293 }
void downloadFinished(const QString &path)
SearchPluginManager * manager() const
void setRowColor(int row, const QColor &color)
void addTorrentToSession(const QString &source, AddTorrentOption option=AddTorrentOption::Default)
SearchDownloadHandler * downloadTorrent(const QString &siteUrl, const QString &url)

References addTorrentToSession(), SearchSortModel::DL_LINK, SearchDownloadHandler::downloadFinished(), SearchPluginManager::downloadTorrent(), SearchSortModel::ENGINE_URL, m_proxyModel, m_searchHandler, SearchHandler::manager(), setRowColor(), and anonymous_namespace{misc.cpp}::source.

Referenced by downloadTorrents(), and onItemDoubleClicked().

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

◆ downloadTorrents()

void SearchJobWidget::downloadTorrents ( AddTorrentOption  option = AddTorrentOption::Default)
private

Definition at line 214 of file searchjobwidget.cpp.

215 {
216  const QModelIndexList rows {m_ui->resultsBrowser->selectionModel()->selectedRows()};
217  for (const QModelIndex &rowIndex : rows)
218  downloadTorrent(rowIndex, option);
219 }
void downloadTorrent(const QModelIndex &rowIndex, AddTorrentOption option=AddTorrentOption::Default)

References downloadTorrent(), and m_ui.

Referenced by contextMenuEvent(), and keyPressEvent().

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

◆ fillFilterComboBoxes()

void SearchJobWidget::fillFilterComboBoxes ( )
private

Definition at line 333 of file searchjobwidget.cpp.

334 {
335  using Utils::Misc::SizeUnit;
337 
338  QStringList unitStrings;
339  unitStrings.append(unitString(SizeUnit::Byte));
340  unitStrings.append(unitString(SizeUnit::KibiByte));
341  unitStrings.append(unitString(SizeUnit::MebiByte));
342  unitStrings.append(unitString(SizeUnit::GibiByte));
343  unitStrings.append(unitString(SizeUnit::TebiByte));
344  unitStrings.append(unitString(SizeUnit::PebiByte));
345  unitStrings.append(unitString(SizeUnit::ExbiByte));
346 
347  m_ui->minSizeUnit->clear();
348  m_ui->maxSizeUnit->clear();
349  m_ui->minSizeUnit->addItems(unitStrings);
350  m_ui->maxSizeUnit->addItems(unitStrings);
351 
352  m_ui->minSize->setValue(0);
353  m_ui->minSizeUnit->setCurrentIndex(static_cast<int>(SizeUnit::MebiByte));
354 
355  m_ui->maxSize->setValue(-1);
356  m_ui->maxSizeUnit->setCurrentIndex(static_cast<int>(SizeUnit::GibiByte));
357 
358  m_ui->filterMode->clear();
359 
360  m_ui->filterMode->addItem(tr("Torrent names only"), static_cast<int>(NameFilteringMode::OnlyNames));
361  m_ui->filterMode->addItem(tr("Everywhere"), static_cast<int>(NameFilteringMode::Everywhere));
362 
363  QVariant selectedMode = static_cast<int>(nameFilteringModeSetting().get(NameFilteringMode::OnlyNames));
364  int index = m_ui->filterMode->findData(selectedMode);
365  m_ui->filterMode->setCurrentIndex((index == -1) ? 0 : index);
366 }
static SettingValue< NameFilteringMode > & nameFilteringModeSetting()
SizeUnit
Definition: misc.h:49
QString unitString(SizeUnit unit, bool isSpeed=false)
Definition: misc.cpp:252

References Everywhere, m_ui, nameFilteringModeSetting(), OnlyNames, and Utils::Misc::unitString().

Referenced by SearchJobWidget().

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

◆ filteringMode()

SearchJobWidget::NameFilteringMode SearchJobWidget::filteringMode ( ) const
private

Definition at line 438 of file searchjobwidget.cpp.

439 {
440  return static_cast<NameFilteringMode>(m_ui->filterMode->itemData(m_ui->filterMode->currentIndex()).toInt());
441 }

References m_ui.

Referenced by updateFilter().

Here is the caller graph for this function:

◆ filterSearchResults()

void SearchJobWidget::filterSearchResults ( const QString &  name)
private

Definition at line 368 of file searchjobwidget.cpp.

369 {
372  m_proxyModel->setFilterRegularExpression(QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption));
374 }
static Preferences * instance()
bool getRegexAsFilteringPatternForSearchJob() const
QString wildcardToRegexPattern(const QString &pattern)
Definition: string.cpp:57

References Preferences::getRegexAsFilteringPatternForSearchJob(), Preferences::instance(), m_proxyModel, updateResultsCount(), and Utils::String::wildcardToRegexPattern().

Referenced by SearchJobWidget(), and showFilterContextMenu().

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

◆ header()

QHeaderView * SearchJobWidget::header ( ) const
private

Definition at line 179 of file searchjobwidget.cpp.

180 {
181  return m_ui->resultsBrowser->header();
182 }

References m_ui.

Referenced by loadSettings(), saveSettings(), and SearchJobWidget().

Here is the caller graph for this function:

◆ keyPressEvent()

void SearchJobWidget::keyPressEvent ( QKeyEvent *  event)
overrideprotected

Definition at line 548 of file searchjobwidget.cpp.

549 {
550  switch (event->key())
551  {
552  case Qt::Key_Enter:
553  case Qt::Key_Return:
555  break;
556  default:
557  QWidget::keyPressEvent(event);
558  }
559 }

References downloadTorrents().

Here is the call graph for this function:

◆ lineEditSearchResultsFilter()

LineEdit * SearchJobWidget::lineEditSearchResultsFilter ( ) const

Definition at line 204 of file searchjobwidget.cpp.

205 {
207 }

References m_lineEditSearchResultsFilter.

◆ loadSettings()

void SearchJobWidget::loadSettings ( )
private

Definition at line 443 of file searchjobwidget.cpp.

444 {
445  header()->restoreState(Preferences::instance()->getSearchTabHeaderState());
446 }

References header(), and Preferences::instance().

Referenced by SearchJobWidget().

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

◆ nameFilteringModeSetting()

SettingValue< SearchJobWidget::NameFilteringMode > & SearchJobWidget::nameFilteringModeSetting ( )
staticprivate

Definition at line 542 of file searchjobwidget.cpp.

543 {
544  static SettingValue<NameFilteringMode> setting {"Search/FilteringMode"};
545  return setting;
546 }

Referenced by fillFilterComboBoxes(), and updateFilter().

Here is the caller graph for this function:

◆ onItemDoubleClicked()

void SearchJobWidget::onItemDoubleClicked ( const QModelIndex &  index)
private

Definition at line 174 of file searchjobwidget.cpp.

175 {
176  downloadTorrent(index);
177 }

References downloadTorrent().

Referenced by SearchJobWidget().

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

◆ openTorrentPages()

void SearchJobWidget::openTorrentPages ( ) const
private

Definition at line 221 of file searchjobwidget.cpp.

222 {
223  const QModelIndexList rows {m_ui->resultsBrowser->selectionModel()->selectedRows()};
224  for (const QModelIndex &rowIndex : rows)
225  {
226  const QString descrLink = m_proxyModel->data(
227  m_proxyModel->index(rowIndex.row(), SearchSortModel::DESC_LINK)).toString();
228  if (!descrLink.isEmpty())
229  QDesktopServices::openUrl(QUrl::fromEncoded(descrLink.toUtf8()));
230  }
231 }

References SearchSortModel::DESC_LINK, m_proxyModel, and m_ui.

Referenced by contextMenuEvent().

Here is the caller graph for this function:

◆ resultsCountUpdated

void SearchJobWidget::resultsCountUpdated ( )
signal

Referenced by updateResultsCount().

Here is the caller graph for this function:

◆ saveSettings()

void SearchJobWidget::saveSettings ( ) const
private

Definition at line 448 of file searchjobwidget.cpp.

449 {
451 }
void setSearchTabHeaderState(const QByteArray &state)

References header(), Preferences::instance(), and Preferences::setSearchTabHeaderState().

Referenced by displayToggleColumnsMenu(), SearchJobWidget(), and ~SearchJobWidget().

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

◆ searchFailed()

void SearchJobWidget::searchFailed ( )
private

Definition at line 505 of file searchjobwidget.cpp.

506 {
508 }
void setStatus(Status value)

References Error, and setStatus().

Referenced by SearchJobWidget().

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

◆ searchFinished()

void SearchJobWidget::searchFinished ( bool  cancelled)
private

Definition at line 495 of file searchjobwidget.cpp.

References Aborted, Finished, m_noSearchResults, NoResults, and setStatus().

Referenced by SearchJobWidget().

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

◆ setRowColor()

void SearchJobWidget::setRowColor ( int  row,
const QColor &  color 
)
private

Definition at line 185 of file searchjobwidget.cpp.

186 {
187  m_proxyModel->setDynamicSortFilter(false);
188  for (int i = 0; i < m_proxyModel->columnCount(); ++i)
189  m_proxyModel->setData(m_proxyModel->index(row, i), color, Qt::ForegroundRole);
190 
191  m_proxyModel->setDynamicSortFilter(true);
192 }

References m_proxyModel.

Referenced by downloadTorrent().

Here is the caller graph for this function:

◆ setStatus()

void SearchJobWidget::setStatus ( Status  value)
private

Definition at line 265 of file searchjobwidget.cpp.

266 {
267  if (m_status == value) return;
268 
269  m_status = value;
270  setStatusTip(statusText(value));
271  emit statusChanged();
272 }
void statusChanged()
T value(const QString &key, const T &defaultValue={})
Definition: preferences.cpp:64

References m_status, statusChanged(), statusText(), and anonymous_namespace{preferences.cpp}::value().

Referenced by searchFailed(), and searchFinished().

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

◆ showFilterContextMenu()

void SearchJobWidget::showFilterContextMenu ( const QPoint &  )
private

Definition at line 376 of file searchjobwidget.cpp.

377 {
378  const Preferences *pref = Preferences::instance();
379 
380  QMenu *menu = m_lineEditSearchResultsFilter->createStandardContextMenu();
381  menu->setAttribute(Qt::WA_DeleteOnClose);
382  menu->addSeparator();
383 
384  QAction *useRegexAct = menu->addAction(tr("Use regular expressions"));
385  useRegexAct->setCheckable(true);
386  useRegexAct->setChecked(pref->getRegexAsFilteringPatternForSearchJob());
387  connect(useRegexAct, &QAction::toggled, pref, &Preferences::setRegexAsFilteringPatternForSearchJob);
388  connect(useRegexAct, &QAction::toggled, this, [this]() { filterSearchResults(m_lineEditSearchResultsFilter->text()); });
389 
390  menu->popup(QCursor::pos());
391 }
void setRegexAsFilteringPatternForSearchJob(bool checked)

References filterSearchResults(), Preferences::getRegexAsFilteringPatternForSearchJob(), Preferences::instance(), m_lineEditSearchResultsFilter, and Preferences::setRegexAsFilteringPatternForSearchJob().

Referenced by SearchJobWidget().

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

◆ status()

SearchJobWidget::Status SearchJobWidget::status ( ) const

Definition at line 194 of file searchjobwidget.cpp.

195 {
196  return m_status;
197 }

References m_status.

◆ statusChanged

void SearchJobWidget::statusChanged ( )
signal

Referenced by SearchWidget::on_searchButton_clicked(), and setStatus().

Here is the caller graph for this function:

◆ statusText()

QString SearchJobWidget::statusText ( SearchJobWidget::Status  st)
staticprivate

Definition at line 419 of file searchjobwidget.cpp.

420 {
421  switch (st)
422  {
423  case Status::Ongoing:
424  return tr("Searching...");
425  case Status::Finished:
426  return tr("Search has finished");
427  case Status::Aborted:
428  return tr("Search aborted");
429  case Status::Error:
430  return tr("An error occurred during search...");
431  case Status::NoResults:
432  return tr("Search returned no results");
433  default:
434  return {};
435  }
436 }

References Aborted, Error, Finished, NoResults, and Ongoing.

Referenced by SearchJobWidget(), and setStatus().

Here is the caller graph for this function:

◆ updateFilter()

void SearchJobWidget::updateFilter ( )
private

Definition at line 316 of file searchjobwidget.cpp.

317 {
318  using Utils::Misc::SizeUnit;
319 
321  // we update size and seeds filter parameters in the model even if they are disabled
322  m_proxyModel->setSeedsFilter(m_ui->minSeeds->value(), m_ui->maxSeeds->value());
324  sizeInBytes(m_ui->minSize->value(), static_cast<SizeUnit>(m_ui->minSizeUnit->currentIndex())),
325  sizeInBytes(m_ui->maxSize->value(), static_cast<SizeUnit>(m_ui->maxSizeUnit->currentIndex())));
326 
328 
329  m_proxyModel->invalidate();
331 }
NameFilteringMode filteringMode() const
void enableNameFilter(bool enabled)
void setSeedsFilter(int minSeeds, int maxSeeds)
Sets parameters for filtering by seeds number.
void setSizeFilter(qint64 minSize, qint64 maxSize)
Sets parameters for filtering by size.
qint64 sizeInBytes(qreal size, SizeUnit unit)
Definition: misc.cpp:288

References SearchSortModel::enableNameFilter(), filteringMode(), m_proxyModel, m_ui, nameFilteringModeSetting(), OnlyNames, SearchSortModel::setSeedsFilter(), SearchSortModel::setSizeFilter(), Utils::Misc::sizeInBytes(), and updateResultsCount().

Referenced by SearchJobWidget().

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

◆ updateResultsCount()

void SearchJobWidget::updateResultsCount ( )
private

Definition at line 305 of file searchjobwidget.cpp.

306 {
307  const int totalResults = m_searchListModel->rowCount();
308  const int filteredResults = m_proxyModel->rowCount();
309  m_ui->resultsLbl->setText(tr("Results (showing <i>%1</i> out of <i>%2</i>):", "i.e: Search results")
310  .arg(filteredResults).arg(totalResults));
311 
312  m_noSearchResults = (totalResults == 0);
313  emit resultsCountUpdated();
314 }
void resultsCountUpdated()

References m_noSearchResults, m_proxyModel, m_searchListModel, m_ui, and resultsCountUpdated().

Referenced by appendSearchResults(), filterSearchResults(), and updateFilter().

Here is the caller graph for this function:

◆ visibleResultsCount()

int SearchJobWidget::visibleResultsCount ( ) const

Definition at line 199 of file searchjobwidget.cpp.

200 {
201  return m_proxyModel->rowCount();
202 }

References m_proxyModel.

Member Data Documentation

◆ m_lineEditSearchResultsFilter

LineEdit* SearchJobWidget::m_lineEditSearchResultsFilter
private

◆ m_noSearchResults

bool SearchJobWidget::m_noSearchResults = true
private

Definition at line 135 of file searchjobwidget.h.

Referenced by searchFinished(), and updateResultsCount().

◆ m_proxyModel

◆ m_searchHandler

SearchHandler* SearchJobWidget::m_searchHandler
private

Definition at line 130 of file searchjobwidget.h.

Referenced by cancelSearch(), and downloadTorrent().

◆ m_searchListModel

QStandardItemModel* SearchJobWidget::m_searchListModel
private

◆ m_status

Status SearchJobWidget::m_status = Status::Ongoing
private

Definition at line 134 of file searchjobwidget.h.

Referenced by SearchJobWidget(), setStatus(), and status().

◆ m_ui


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