qBittorrent
SearchWidget Class Reference

#include <searchwidget.h>

Inheritance diagram for SearchWidget:
Collaboration diagram for SearchWidget:

Public Member Functions

 SearchWidget (MainWindow *mainWindow)
 
 ~SearchWidget () override
 
void giveFocusToSearchInput ()
 

Private Slots

void on_searchButton_clicked ()
 
void on_pluginsButton_clicked ()
 

Private Member Functions

bool eventFilter (QObject *object, QEvent *event) override
 
void tabChanged (int index)
 
void closeTab (int index)
 
void closeAllTabs ()
 
void tabStatusChanged (QWidget *tab)
 
void selectMultipleBox (int index)
 
void toggleFocusBetweenLineEdits ()
 
void fillCatCombobox ()
 
void fillPluginComboBox ()
 
void selectActivePage ()
 
void searchTextEdited (const QString &)
 
QString selectedCategory () const
 
QString selectedPlugin () const
 

Private Attributes

Ui::SearchWidget * m_ui
 
QPointer< SearchJobWidgetm_currentSearchTab
 
QPointer< SearchJobWidgetm_activeSearchTab
 
QList< SearchJobWidget * > m_allTabs
 
MainWindowm_mainWindow
 
bool m_isNewQueryString
 

Detailed Description

Definition at line 49 of file searchwidget.h.

Constructor & Destructor Documentation

◆ SearchWidget()

SearchWidget::SearchWidget ( MainWindow mainWindow)
explicit

Definition at line 87 of file searchwidget.cpp.

88  : QWidget(mainWindow)
89  , m_ui(new Ui::SearchWidget())
90  , m_mainWindow(mainWindow)
91  , m_isNewQueryString(false)
92 {
93  m_ui->setupUi(this);
94  m_ui->tabWidget->tabBar()->installEventFilter(this);
95 
96  QString searchPatternHint;
97  QTextStream stream(&searchPatternHint, QIODevice::WriteOnly);
98  stream << "<html><head/><body><p>"
99  << tr("A phrase to search for.") << "<br>"
100  << tr("Spaces in a search term may be protected by double quotes.")
101  << "</p><p>"
102  << tr("Example:", "Search phrase example")
103  << "<br>"
104  << tr("<b>foo bar</b>: search for <b>foo</b> and <b>bar</b>",
105  "Search phrase example, illustrates quotes usage, a pair of "
106  "space delimited words, individal words are highlighted")
107  << "<br>"
108  << tr("<b>&quot;foo bar&quot;</b>: search for <b>foo bar</b>",
109  "Search phrase example, illustrates quotes usage, double quoted"
110  "pair of space delimited words, the whole pair is highlighted")
111  << "</p></body></html>";
112  m_ui->lineEditSearchPattern->setToolTip(searchPatternHint);
113 
114 #ifndef Q_OS_MACOS
115  // Icons
116  m_ui->searchButton->setIcon(UIThemeManager::instance()->getIcon("edit-find"));
117  m_ui->pluginsButton->setIcon(UIThemeManager::instance()->getIcon("preferences-system-network"));
118 #else
119  // On macOS the icons overlap the text otherwise
120  QSize iconSize = m_ui->tabWidget->iconSize();
121  iconSize.setWidth(iconSize.width() + 16);
122  m_ui->tabWidget->setIconSize(iconSize);
123 #endif
124  connect(m_ui->tabWidget, &QTabWidget::tabCloseRequested, this, &SearchWidget::closeTab);
125  connect(m_ui->tabWidget, &QTabWidget::currentChanged, this, &SearchWidget::tabChanged);
126 
127  const auto *searchManager = SearchPluginManager::instance();
128  const auto onPluginChanged = [this]()
129  {
131  fillCatCombobox();
133  };
134  connect(searchManager, &SearchPluginManager::pluginInstalled, this, onPluginChanged);
135  connect(searchManager, &SearchPluginManager::pluginUninstalled, this, onPluginChanged);
136  connect(searchManager, &SearchPluginManager::pluginUpdated, this, onPluginChanged);
137  connect(searchManager, &SearchPluginManager::pluginEnabled, this, onPluginChanged);
138 
139  // Fill in category combobox
140  onPluginChanged();
141 
142  connect(m_ui->lineEditSearchPattern, &LineEdit::returnPressed, m_ui->searchButton, &QPushButton::click);
143  connect(m_ui->lineEditSearchPattern, &LineEdit::textEdited, this, &SearchWidget::searchTextEdited);
144  connect(m_ui->selectPlugin, qOverload<int>(&QComboBox::currentIndexChanged)
146  connect(m_ui->selectPlugin, qOverload<int>(&QComboBox::currentIndexChanged)
148 
149  const auto focusSearchHotkey = new QShortcut(QKeySequence::Find, this);
150  connect(focusSearchHotkey, &QShortcut::activated, this, &SearchWidget::toggleFocusBetweenLineEdits);
151 }
void pluginUpdated(const QString &name)
void pluginEnabled(const QString &name, bool enabled)
void pluginInstalled(const QString &name)
void pluginUninstalled(const QString &name)
static SearchPluginManager * instance()
void fillPluginComboBox()
void closeTab(int index)
void fillCatCombobox()
MainWindow * m_mainWindow
Definition: searchwidget.h:85
void selectActivePage()
Ui::SearchWidget * m_ui
Definition: searchwidget.h:81
void selectMultipleBox(int index)
void searchTextEdited(const QString &)
void toggleFocusBetweenLineEdits()
bool m_isNewQueryString
Definition: searchwidget.h:86
void tabChanged(int index)
static UIThemeManager * instance()

References closeTab(), fillCatCombobox(), fillPluginComboBox(), SearchPluginManager::instance(), UIThemeManager::instance(), m_ui, SearchPluginManager::pluginEnabled(), SearchPluginManager::pluginInstalled(), SearchPluginManager::pluginUninstalled(), SearchPluginManager::pluginUpdated(), searchTextEdited(), selectActivePage(), selectMultipleBox(), tabChanged(), and toggleFocusBetweenLineEdits().

Here is the call graph for this function:

◆ ~SearchWidget()

SearchWidget::~SearchWidget ( )
override

Definition at line 253 of file searchwidget.cpp.

254 {
255  qDebug("Search destruction");
256  delete m_ui;
257 }

References m_ui.

Member Function Documentation

◆ closeAllTabs()

void SearchWidget::closeAllTabs ( )
private

Definition at line 397 of file searchwidget.cpp.

398 {
399  for (int i = (m_allTabs.size() - 1); i >= 0; --i)
400  closeTab(i);
401 }
QList< SearchJobWidget * > m_allTabs
Definition: searchwidget.h:84

References closeTab(), and m_allTabs.

Referenced by eventFilter().

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

◆ closeTab()

void SearchWidget::closeTab ( int  index)
private

Definition at line 388 of file searchwidget.cpp.

389 {
390  SearchJobWidget *tab = m_allTabs.takeAt(index);
391  if (tab == m_activeSearchTab)
392  m_ui->searchButton->setText(tr("Search"));
393 
394  delete tab;
395 }
QPointer< SearchJobWidget > m_activeSearchTab
Definition: searchwidget.h:83

References m_activeSearchTab, m_allTabs, and m_ui.

Referenced by closeAllTabs(), eventFilter(), and SearchWidget().

Here is the caller graph for this function:

◆ eventFilter()

bool SearchWidget::eventFilter ( QObject *  object,
QEvent *  event 
)
overrideprivate

Definition at line 153 of file searchwidget.cpp.

154 {
155  if (object == m_ui->tabWidget->tabBar())
156  {
157  // Close tabs when middle-clicked
158  if (event->type() != QEvent::MouseButtonRelease)
159  return false;
160 
161  const auto mouseEvent = static_cast<QMouseEvent *>(event);
162  const int tabIndex = m_ui->tabWidget->tabBar()->tabAt(mouseEvent->pos());
163  if ((mouseEvent->button() == Qt::MiddleButton) && (tabIndex >= 0))
164  {
165  closeTab(tabIndex);
166  return true;
167  }
168  if (mouseEvent->button() == Qt::RightButton)
169  {
170  QMenu *menu = new QMenu(this);
171  menu->setAttribute(Qt::WA_DeleteOnClose);
172  menu->addAction(tr("Close tab"), this, [this, tabIndex]() { closeTab(tabIndex); });
173  menu->addAction(tr("Close all tabs"), this, &SearchWidget::closeAllTabs);
174  menu->popup(QCursor::pos());
175  return true;
176  }
177  return false;
178  }
179  return QWidget::eventFilter(object, event);
180 }
void closeAllTabs()

References closeAllTabs(), closeTab(), and m_ui.

Here is the call graph for this function:

◆ fillCatCombobox()

void SearchWidget::fillCatCombobox ( )
private

Definition at line 182 of file searchwidget.cpp.

183 {
184  m_ui->comboCategory->clear();
185  m_ui->comboCategory->addItem(SearchPluginManager::categoryFullName("all"), "all");
186 
187  using QStrPair = std::pair<QString, QString>;
188  QVector<QStrPair> tmpList;
190  tmpList << std::make_pair(SearchPluginManager::categoryFullName(cat), cat);
191  std::sort(tmpList.begin(), tmpList.end(), [](const QStrPair &l, const QStrPair &r) { return (QString::localeAwareCompare(l.first, r.first) < 0); });
192 
193  for (const QStrPair &p : asConst(tmpList))
194  {
195  qDebug("Supported category: %s", qUtf8Printable(p.second));
196  m_ui->comboCategory->addItem(p.first, p.second);
197  }
198 
199  if (m_ui->comboCategory->count() > 1)
200  m_ui->comboCategory->insertSeparator(1);
201 }
static QString categoryFullName(const QString &categoryName)
QString selectedPlugin() const
constexpr std::add_const_t< T > & asConst(T &t) noexcept
Definition: global.h:42
QJsonArray getPluginCategories(QStringList categories)

References asConst(), SearchPluginManager::categoryFullName(), anonymous_namespace{searchcontroller.cpp}::getPluginCategories(), SearchPluginManager::instance(), m_ui, and selectedPlugin().

Referenced by SearchWidget().

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

◆ fillPluginComboBox()

void SearchWidget::fillPluginComboBox ( )
private

Definition at line 203 of file searchwidget.cpp.

204 {
205  m_ui->selectPlugin->clear();
206  m_ui->selectPlugin->addItem(tr("Only enabled"), "enabled");
207  m_ui->selectPlugin->addItem(tr("All plugins"), "all");
208  m_ui->selectPlugin->addItem(tr("Select..."), "multi");
209 
210  using QStrPair = std::pair<QString, QString>;
211  QVector<QStrPair> tmpList;
212  for (const QString &name : asConst(SearchPluginManager::instance()->enabledPlugins()))
213  tmpList << std::make_pair(SearchPluginManager::instance()->pluginFullName(name), name);
214  std::sort(tmpList.begin(), tmpList.end(), [](const QStrPair &l, const QStrPair &r) { return (l.first < r.first); } );
215 
216  for (const QStrPair &p : asConst(tmpList))
217  m_ui->selectPlugin->addItem(p.first, p.second);
218 
219  if (m_ui->selectPlugin->count() > 3)
220  m_ui->selectPlugin->insertSeparator(3);
221 }

References asConst(), SearchPluginManager::instance(), and m_ui.

Referenced by SearchWidget().

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

◆ giveFocusToSearchInput()

void SearchWidget::giveFocusToSearchInput ( )

Definition at line 299 of file searchwidget.cpp.

300 {
301  m_ui->lineEditSearchPattern->setFocus();
302 }

References m_ui.

◆ on_pluginsButton_clicked

void SearchWidget::on_pluginsButton_clicked ( )
privateslot

Definition at line 287 of file searchwidget.cpp.

References SearchPluginManager::instance().

Referenced by selectMultipleBox().

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

◆ on_searchButton_clicked

void SearchWidget::on_searchButton_clicked ( )
privateslot

Definition at line 305 of file searchwidget.cpp.

306 {
307  if (!Utils::ForeignApps::pythonInfo().isValid())
308  {
309  m_mainWindow->showNotificationBalloon(tr("Search Engine"), tr("Please install Python to use the Search Engine."));
310  return;
311  }
312 
313  if (m_activeSearchTab)
314  {
315  m_activeSearchTab->cancelSearch();
316  if (!m_isNewQueryString)
317  {
318  m_ui->searchButton->setText(tr("Search"));
319  return;
320  }
321  }
322 
323  m_isNewQueryString = false;
324 
325  const QString pattern = m_ui->lineEditSearchPattern->text().trimmed();
326  // No search pattern entered
327  if (pattern.isEmpty())
328  {
329  QMessageBox::critical(this, tr("Empty search pattern"), tr("Please type a search pattern first"));
330  return;
331  }
332 
333  QStringList plugins;
334  if (selectedPlugin() == "all")
336  else if (selectedPlugin() == "enabled")
338  else if (selectedPlugin() == "multi")
340  else
341  plugins << selectedPlugin();
342 
343  qDebug("Search with category: %s", qUtf8Printable(selectedCategory()));
344 
345  // Launch search
346  auto *searchHandler = SearchPluginManager::instance()->startSearch(pattern, selectedCategory(), plugins);
347 
348  // Tab Addition
349  auto *newTab = new SearchJobWidget(searchHandler, this);
350  m_allTabs.append(newTab);
351 
352  QString tabName = pattern;
353  tabName.replace(QRegularExpression("&{1}"), "&&");
354  m_ui->tabWidget->addTab(newTab, tabName);
355  m_ui->tabWidget->setCurrentWidget(newTab);
356 
357  connect(newTab, &SearchJobWidget::statusChanged, this, [this, newTab]() { tabStatusChanged(newTab); });
358 
359  m_ui->searchButton->setText(tr("Stop"));
360  m_activeSearchTab = newTab;
361  tabStatusChanged(newTab);
362 }
void showNotificationBalloon(const QString &title, const QString &msg) const
void statusChanged()
QStringList enabledPlugins() const
SearchHandler * startSearch(const QString &pattern, const QString &category, const QStringList &usedPlugins)
QStringList allPlugins() const
void tabStatusChanged(QWidget *tab)
QString selectedCategory() const
PythonInfo pythonInfo()

References SearchPluginManager::allPlugins(), SearchPluginManager::enabledPlugins(), SearchPluginManager::instance(), m_activeSearchTab, m_allTabs, m_isNewQueryString, m_mainWindow, m_ui, Utils::ForeignApps::pythonInfo(), selectedCategory(), selectedPlugin(), MainWindow::showNotificationBalloon(), SearchPluginManager::startSearch(), SearchJobWidget::statusChanged(), and tabStatusChanged().

Here is the call graph for this function:

◆ searchTextEdited()

void SearchWidget::searchTextEdited ( const QString &  )
private

Definition at line 292 of file searchwidget.cpp.

293 {
294  // Enable search button
295  m_ui->searchButton->setText(tr("Search"));
296  m_isNewQueryString = true;
297 }

References m_isNewQueryString, and m_ui.

Referenced by SearchWidget().

Here is the caller graph for this function:

◆ selectActivePage()

void SearchWidget::selectActivePage ( )
private

Definition at line 233 of file searchwidget.cpp.

234 {
235  if (SearchPluginManager::instance()->allPlugins().isEmpty())
236  {
237  m_ui->stackedPages->setCurrentWidget(m_ui->emptyPage);
238  m_ui->lineEditSearchPattern->setEnabled(false);
239  m_ui->comboCategory->setEnabled(false);
240  m_ui->selectPlugin->setEnabled(false);
241  m_ui->searchButton->setEnabled(false);
242  }
243  else
244  {
245  m_ui->stackedPages->setCurrentWidget(m_ui->searchPage);
246  m_ui->lineEditSearchPattern->setEnabled(true);
247  m_ui->comboCategory->setEnabled(true);
248  m_ui->selectPlugin->setEnabled(true);
249  m_ui->searchButton->setEnabled(true);
250  }
251 }

References SearchPluginManager::instance(), and m_ui.

Referenced by SearchWidget().

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

◆ selectedCategory()

QString SearchWidget::selectedCategory ( ) const
private

Definition at line 223 of file searchwidget.cpp.

224 {
225  return m_ui->comboCategory->itemData(m_ui->comboCategory->currentIndex()).toString();
226 }

References m_ui.

Referenced by on_searchButton_clicked().

Here is the caller graph for this function:

◆ selectedPlugin()

QString SearchWidget::selectedPlugin ( ) const
private

Definition at line 228 of file searchwidget.cpp.

229 {
230  return m_ui->selectPlugin->itemData(m_ui->selectPlugin->currentIndex()).toString();
231 }

References m_ui.

Referenced by fillCatCombobox(), on_searchButton_clicked(), and selectMultipleBox().

Here is the caller graph for this function:

◆ selectMultipleBox()

void SearchWidget::selectMultipleBox ( int  index)
private

Definition at line 266 of file searchwidget.cpp.

267 {
268  Q_UNUSED(index);
269  if (selectedPlugin() == "multi")
271 }
void on_pluginsButton_clicked()

References on_pluginsButton_clicked(), and selectedPlugin().

Referenced by SearchWidget().

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

◆ tabChanged()

void SearchWidget::tabChanged ( int  index)
private

Definition at line 259 of file searchwidget.cpp.

260 {
261  // when we switch from a tab that is not empty to another that is empty
262  // the download button doesn't have to be available
263  m_currentSearchTab = ((index < 0) ? nullptr : m_allTabs.at(m_ui->tabWidget->currentIndex()));
264 }
QPointer< SearchJobWidget > m_currentSearchTab
Definition: searchwidget.h:82

References m_allTabs, m_currentSearchTab, and m_ui.

Referenced by SearchWidget().

Here is the caller graph for this function:

◆ tabStatusChanged()

void SearchWidget::tabStatusChanged ( QWidget *  tab)
private

Definition at line 364 of file searchwidget.cpp.

365 {
366  const int tabIndex = m_ui->tabWidget->indexOf(tab);
367  m_ui->tabWidget->setTabToolTip(tabIndex, tab->statusTip());
368  m_ui->tabWidget->setTabIcon(tabIndex, UIThemeManager::instance()->getIcon(
369  statusIconName(static_cast<SearchJobWidget *>(tab)->status())));
370 
372  {
374 
376  {
378  m_mainWindow->showNotificationBalloon(tr("Search Engine"), tr("Search has failed"));
379  else
380  m_mainWindow->showNotificationBalloon(tr("Search Engine"), tr("Search has finished"));
381  }
382 
383  m_activeSearchTab = nullptr;
384  m_ui->searchButton->setText(tr("Search"));
385  }
386 }
QWidget * currentTabWidget() const
bool isNotificationsEnabled() const
Definition: mainwindow.cpp:506
QString statusIconName(SearchJobWidget::Status st)

References MainWindow::currentTabWidget(), SearchJobWidget::Error, UIThemeManager::instance(), MainWindow::isNotificationsEnabled(), m_activeSearchTab, m_mainWindow, m_ui, SearchJobWidget::Ongoing, MainWindow::showNotificationBalloon(), and anonymous_namespace{searchwidget.cpp}::statusIconName().

Referenced by on_searchButton_clicked().

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

◆ toggleFocusBetweenLineEdits()

void SearchWidget::toggleFocusBetweenLineEdits ( )
private

Definition at line 273 of file searchwidget.cpp.

274 {
275  if (m_ui->lineEditSearchPattern->hasFocus() && m_currentSearchTab)
276  {
277  m_currentSearchTab->lineEditSearchResultsFilter()->setFocus();
278  m_currentSearchTab->lineEditSearchResultsFilter()->selectAll();
279  }
280  else
281  {
282  m_ui->lineEditSearchPattern->setFocus();
283  m_ui->lineEditSearchPattern->selectAll();
284  }
285 }

References m_currentSearchTab, and m_ui.

Referenced by SearchWidget().

Here is the caller graph for this function:

Member Data Documentation

◆ m_activeSearchTab

QPointer<SearchJobWidget> SearchWidget::m_activeSearchTab
private

Definition at line 83 of file searchwidget.h.

Referenced by closeTab(), on_searchButton_clicked(), and tabStatusChanged().

◆ m_allTabs

QList<SearchJobWidget *> SearchWidget::m_allTabs
private

Definition at line 84 of file searchwidget.h.

Referenced by closeAllTabs(), closeTab(), on_searchButton_clicked(), and tabChanged().

◆ m_currentSearchTab

QPointer<SearchJobWidget> SearchWidget::m_currentSearchTab
private

Definition at line 82 of file searchwidget.h.

Referenced by tabChanged(), and toggleFocusBetweenLineEdits().

◆ m_isNewQueryString

bool SearchWidget::m_isNewQueryString
private

Definition at line 86 of file searchwidget.h.

Referenced by on_searchButton_clicked(), and searchTextEdited().

◆ m_mainWindow

MainWindow* SearchWidget::m_mainWindow
private

Definition at line 85 of file searchwidget.h.

Referenced by on_searchButton_clicked(), and tabStatusChanged().

◆ m_ui


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