32 #include <QApplication>
34 #include <QDesktopServices>
35 #include <QHeaderView>
39 #include <QStandardItemModel>
55 #include "ui_searchjobwidget.h"
60 , m_searchHandler(searchHandler)
67 unused.setVerticalHeader(
m_ui->resultsBrowser->header());
68 m_ui->resultsBrowser->header()->setParent(
m_ui->resultsBrowser);
69 unused.setVerticalHeader(
new QHeaderView(Qt::Horizontal));
73 header()->setStretchLastSection(
false);
74 header()->setTextElideMode(Qt::ElideRight);
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);
104 bool atLeastOne =
false;
107 if (!
m_ui->resultsBrowser->isColumnHidden(i))
119 if ((
m_ui->resultsBrowser->columnWidth(i) <= 0) && !
m_ui->resultsBrowser->isColumnHidden(i))
120 m_ui->resultsBrowser->resizeColumnToContents(i);
122 header()->setContextMenuPolicy(Qt::CustomContextMenu);
139 connect(
m_ui->filterMode, qOverload<int>(&QComboBox::currentIndexChanged)
142 connect(
m_ui->minSeeds, qOverload<int>(&QSpinBox::valueChanged)
145 connect(
m_ui->maxSeeds, qOverload<int>(&QSpinBox::valueChanged)
148 connect(
m_ui->minSize, qOverload<double>(&QDoubleSpinBox::valueChanged)
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)
163 connect(
this, &QObject::destroyed, searchHandler, &QObject::deleteLater);
181 return m_ui->resultsBrowser->header();
216 const QModelIndexList rows {
m_ui->resultsBrowser->selectionModel()->selectedRows()};
217 for (
const QModelIndex &rowIndex : rows)
223 const QModelIndexList rows {
m_ui->resultsBrowser->selectionModel()->selectedRows()};
224 for (
const QModelIndex &rowIndex : rows)
228 if (!descrLink.isEmpty())
229 QDesktopServices::openUrl(QUrl::fromEncoded(descrLink.toUtf8()));
250 const QModelIndexList rows {
m_ui->resultsBrowser->selectionModel()->selectedRows()};
253 for (
const QModelIndex &rowIndex : rows)
256 m_proxyModel->index(rowIndex.row(), column)).toString();
257 if (!field.isEmpty())
262 QApplication::clipboard()->setText(list.join(
'\n'));
281 if (torrentUrl.startsWith(
"magnet:", Qt::CaseInsensitive))
292 setRowColor(rowIndex.row(), QApplication::palette().color(QPalette::LinkVisited));
297 if (
source.isEmpty())
return;
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));
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));
347 m_ui->minSizeUnit->clear();
348 m_ui->maxSizeUnit->clear();
349 m_ui->minSizeUnit->addItems(unitStrings);
350 m_ui->maxSizeUnit->addItems(unitStrings);
352 m_ui->minSize->setValue(0);
353 m_ui->minSizeUnit->setCurrentIndex(
static_cast<int>(SizeUnit::MebiByte));
355 m_ui->maxSize->setValue(-1);
356 m_ui->maxSizeUnit->setCurrentIndex(
static_cast<int>(SizeUnit::GibiByte));
358 m_ui->filterMode->clear();
364 int index =
m_ui->filterMode->findData(selectedMode);
365 m_ui->filterMode->setCurrentIndex((index == -1) ? 0 : index);
372 m_proxyModel->setFilterRegularExpression(QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption));
381 menu->setAttribute(Qt::WA_DeleteOnClose);
382 menu->addSeparator();
384 QAction *useRegexAct = menu->addAction(tr(
"Use regular expressions"));
385 useRegexAct->setCheckable(
true);
390 menu->popup(QCursor::pos());
395 auto *menu =
new QMenu(
this);
396 menu->setAttribute(Qt::WA_DeleteOnClose);
402 menu->addSeparator();
406 QMenu *copySubMenu = menu->addMenu(
416 menu->popup(event->globalPos());
424 return tr(
"Searching...");
426 return tr(
"Search has finished");
428 return tr(
"Search aborted");
430 return tr(
"An error occurred during search...");
432 return tr(
"Search returned no results");
455 auto menu =
new QMenu(
this);
456 menu->setAttribute(Qt::WA_DeleteOnClose);
457 menu->setTitle(tr(
"Column visibility"));
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));
467 connect(menu, &QMenu::triggered,
this, [
this](
const QAction *
action)
472 if (!
m_ui->resultsBrowser->isColumnHidden(i))
479 const int col =
action->data().toInt();
481 if ((!
m_ui->resultsBrowser->isColumnHidden(col)) && (visibleCols == 1))
484 m_ui->resultsBrowser->setColumnHidden(col, !
m_ui->resultsBrowser->isColumnHidden(col));
486 if ((!
m_ui->resultsBrowser->isColumnHidden(col)) && (
m_ui->resultsBrowser->columnWidth(col) <= 5))
487 m_ui->resultsBrowser->resizeColumnToContents(col);
492 menu->popup(QCursor::pos());
518 const auto setModelData = [
this, row] (
const int column,
const QString &displayData
519 ,
const QVariant &underlyingData,
const Qt::Alignment textAlignmentData = {})
521 const QMap<int, QVariant> data =
523 {Qt::DisplayRole, displayData},
525 {Qt::TextAlignmentRole, QVariant {textAlignmentData}}
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));
550 switch (event->key())
557 QWidget::keyPressEvent(event);
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
static void show(const QString &source, const BitTorrent::AddTorrentParams &inParams, QWidget *parent)
static Session * instance()
bool addTorrent(const QString &source, const AddTorrentParams ¶ms=AddTorrentParams())
static Preferences * instance()
void setRegexAsFilteringPatternForSearchJob(bool checked)
void setSearchTabHeaderState(const QByteArray &state)
bool getRegexAsFilteringPatternForSearchJob() const
void downloadFinished(const QString &path)
SearchPluginManager * manager() const
void searchFinished(bool cancelled=false)
void newSearchResults(const QVector< SearchResult > &results)
SearchDownloadHandler * downloadTorrent(const QString &siteUrl, const QString &url)
void setNameFilter(const QString &searchTerm={})
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.
static UIThemeManager * instance()
QIcon getIcon(const QString &iconId, const QString &fallback={}) const
QString unitString(SizeUnit unit, bool isSpeed=false)
qint64 sizeInBytes(qreal size, SizeUnit unit)
QString friendlyUnit(qint64 bytes, bool isSpeed=false)
QString wildcardToRegexPattern(const QString &pattern)
T value(const QString &key, const T &defaultValue={})