Allow multiple simultaneous searches

PR #22127.
This commit is contained in:
Vladimir Golovnev 2025-01-11 09:53:40 +03:00 committed by GitHub
commit 5875d8bff3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 62 additions and 35 deletions

View file

@ -739,7 +739,7 @@ void MainWindow::displaySearchTab(bool enable)
if (!m_searchWidget) if (!m_searchWidget)
{ {
m_searchWidget = new SearchWidget(app(), this); m_searchWidget = new SearchWidget(app(), this);
connect(m_searchWidget, &SearchWidget::activeSearchFinished, this, [this](const bool failed) connect(m_searchWidget, &SearchWidget::searchFinished, this, [this](const bool failed)
{ {
if (app()->desktopIntegration()->isNotificationsEnabled() && (currentTabWidget() != m_searchWidget)) if (app()->desktopIntegration()->isNotificationsEnabled() && (currentTabWidget() != m_searchWidget))
{ {

View file

@ -88,6 +88,8 @@ SearchWidget::SearchWidget(IGUIApplication *app, QWidget *parent)
, m_ui {new Ui::SearchWidget()} , m_ui {new Ui::SearchWidget()}
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
m_ui->stopButton->hide();
m_ui->tabWidget->tabBar()->installEventFilter(this); m_ui->tabWidget->tabBar()->installEventFilter(this);
const QString searchPatternHint = u"<html><head/><body><p>" const QString searchPatternHint = u"<html><head/><body><p>"
@ -134,6 +136,9 @@ SearchWidget::SearchWidget(IGUIApplication *app, QWidget *parent)
// Fill in category combobox // Fill in category combobox
onPluginChanged(); onPluginChanged();
connect(m_ui->pluginsButton, &QPushButton::clicked, this, &SearchWidget::pluginsButtonClicked);
connect(m_ui->searchButton, &QPushButton::clicked, this, &SearchWidget::searchButtonClicked);
connect(m_ui->stopButton, &QPushButton::clicked, this, &SearchWidget::stopButtonClicked);
connect(m_ui->lineEditSearchPattern, &LineEdit::returnPressed, m_ui->searchButton, &QPushButton::click); connect(m_ui->lineEditSearchPattern, &LineEdit::returnPressed, m_ui->searchButton, &QPushButton::click);
connect(m_ui->lineEditSearchPattern, &LineEdit::textEdited, this, &SearchWidget::searchTextEdited); connect(m_ui->lineEditSearchPattern, &LineEdit::textEdited, this, &SearchWidget::searchTextEdited);
connect(m_ui->selectPlugin, qOverload<int>(&QComboBox::currentIndexChanged) connect(m_ui->selectPlugin, qOverload<int>(&QComboBox::currentIndexChanged)
@ -268,13 +273,27 @@ void SearchWidget::tabChanged(const int index)
m_currentSearchTab = (index >= 0) m_currentSearchTab = (index >= 0)
? static_cast<SearchJobWidget *>(m_ui->tabWidget->widget(index)) ? static_cast<SearchJobWidget *>(m_ui->tabWidget->widget(index))
: nullptr; : nullptr;
if (!m_isNewQueryString)
{
if (m_currentSearchTab && (m_currentSearchTab->status() == SearchJobWidget::Status::Ongoing))
{
m_ui->searchButton->hide();
m_ui->stopButton->show();
}
else
{
m_ui->stopButton->hide();
m_ui->searchButton->show();
}
}
} }
void SearchWidget::selectMultipleBox([[maybe_unused]] const int index) void SearchWidget::selectMultipleBox([[maybe_unused]] const int index)
{ {
const auto itemText = m_ui->selectPlugin->itemData(m_ui->selectPlugin->currentIndex()).toString(); const auto itemText = m_ui->selectPlugin->itemData(m_ui->selectPlugin->currentIndex()).toString();
if (itemText == u"multi") if (itemText == u"multi")
on_pluginsButton_clicked(); pluginsButtonClicked();
} }
void SearchWidget::toggleFocusBetweenLineEdits() void SearchWidget::toggleFocusBetweenLineEdits()
@ -299,9 +318,13 @@ void SearchWidget::showTabMenu(const int index)
searchJobWidget->status() != SearchJobWidget::Status::Ongoing) searchJobWidget->status() != SearchJobWidget::Status::Ongoing)
{ {
menu->addAction(tr("Refresh"), this, [this, searchJobWidget] { refreshTab(searchJobWidget); }); menu->addAction(tr("Refresh"), this, [this, searchJobWidget] { refreshTab(searchJobWidget); });
menu->addSeparator(); }
else
{
menu->addAction(tr("Stop"), this, [searchJobWidget] { searchJobWidget->cancelSearch(); });
} }
menu->addSeparator();
menu->addAction(tr("Close tab"), this, [this, index] { closeTab(index); }); menu->addAction(tr("Close tab"), this, [this, index] { closeTab(index); });
menu->addAction(tr("Close all tabs"), this, &SearchWidget::closeAllTabs); menu->addAction(tr("Close all tabs"), this, &SearchWidget::closeAllTabs);
@ -309,7 +332,7 @@ void SearchWidget::showTabMenu(const int index)
menu->popup(QCursor::pos()); menu->popup(QCursor::pos());
} }
void SearchWidget::on_pluginsButton_clicked() void SearchWidget::pluginsButtonClicked()
{ {
auto *dlg = new PluginSelectDialog(SearchPluginManager::instance(), this); auto *dlg = new PluginSelectDialog(SearchPluginManager::instance(), this);
dlg->setAttribute(Qt::WA_DeleteOnClose); dlg->setAttribute(Qt::WA_DeleteOnClose);
@ -329,18 +352,8 @@ void SearchWidget::giveFocusToSearchInput()
} }
// Function called when we click on search button // Function called when we click on search button
void SearchWidget::on_searchButton_clicked() void SearchWidget::searchButtonClicked()
{ {
if (m_activeSearchTab)
{
m_activeSearchTab->cancelSearch();
if (!m_isNewQueryString)
{
m_ui->searchButton->setText(tr("Search"));
return;
}
}
m_isNewQueryString = false; m_isNewQueryString = false;
const QString pattern = m_ui->lineEditSearchPattern->text().trimmed(); const QString pattern = m_ui->lineEditSearchPattern->text().trimmed();
@ -372,33 +385,38 @@ void SearchWidget::on_searchButton_clicked()
connect(newTab, &SearchJobWidget::statusChanged, this, [this, newTab]() { tabStatusChanged(newTab); }); connect(newTab, &SearchJobWidget::statusChanged, this, [this, newTab]() { tabStatusChanged(newTab); });
m_ui->searchButton->setText(tr("Stop"));
m_activeSearchTab = newTab;
tabStatusChanged(newTab); tabStatusChanged(newTab);
} }
void SearchWidget::tabStatusChanged(QWidget *tab) void SearchWidget::stopButtonClicked()
{
m_currentSearchTab->cancelSearch();
m_ui->stopButton->hide();
m_ui->searchButton->show();
}
void SearchWidget::tabStatusChanged(SearchJobWidget *tab)
{ {
const int tabIndex = m_ui->tabWidget->indexOf(tab); const int tabIndex = m_ui->tabWidget->indexOf(tab);
m_ui->tabWidget->setTabToolTip(tabIndex, tab->statusTip()); m_ui->tabWidget->setTabToolTip(tabIndex, tab->statusTip());
m_ui->tabWidget->setTabIcon(tabIndex, UIThemeManager::instance()->getIcon( m_ui->tabWidget->setTabIcon(tabIndex, UIThemeManager::instance()->getIcon(
statusIconName(static_cast<SearchJobWidget *>(tab)->status()))); statusIconName(static_cast<SearchJobWidget *>(tab)->status())));
if ((tab == m_activeSearchTab) && (m_activeSearchTab->status() != SearchJobWidget::Status::Ongoing)) if (tab->status() != SearchJobWidget::Status::Ongoing)
{ {
emit activeSearchFinished(m_activeSearchTab->status() == SearchJobWidget::Status::Error); if (tab == m_currentSearchTab)
{
m_ui->stopButton->hide();
m_ui->searchButton->show();
}
m_activeSearchTab = nullptr; emit searchFinished(tab->status() == SearchJobWidget::Status::Error);
m_ui->searchButton->setText(tr("Search"));
} }
} }
void SearchWidget::closeTab(const int index) void SearchWidget::closeTab(const int index)
{ {
const QWidget *tab = m_ui->tabWidget->widget(index); const QWidget *tab = m_ui->tabWidget->widget(index);
if (tab == m_activeSearchTab)
m_ui->searchButton->setText(tr("Search"));
delete tab; delete tab;
} }
@ -419,8 +437,10 @@ void SearchWidget::refreshTab(SearchJobWidget *searchJobWidget)
// Re-launch search // Re-launch search
auto *searchHandler = SearchPluginManager::instance()->startSearch(searchJobWidget->searchPattern(), selectedCategory(), selectedPlugins()); auto *searchHandler = SearchPluginManager::instance()->startSearch(searchJobWidget->searchPattern(), selectedCategory(), selectedPlugins());
searchJobWidget->assignSearchHandler(searchHandler); searchJobWidget->assignSearchHandler(searchHandler);
if (!m_isNewQueryString) if (!m_isNewQueryString && (m_ui->tabWidget->currentWidget() == searchJobWidget))
m_ui->searchButton->setText(tr("Stop")); {
m_activeSearchTab = searchJobWidget; m_ui->searchButton->hide();
m_ui->stopButton->show();
}
tabStatusChanged(searchJobWidget); tabStatusChanged(searchJobWidget);
} }

View file

@ -57,16 +57,17 @@ public:
void giveFocusToSearchInput(); void giveFocusToSearchInput();
signals: signals:
void activeSearchFinished(bool failed); void searchFinished(bool failed);
private slots:
void on_searchButton_clicked();
void on_pluginsButton_clicked();
private: private:
bool eventFilter(QObject *object, QEvent *event) override; bool eventFilter(QObject *object, QEvent *event) override;
void pluginsButtonClicked();
void searchButtonClicked();
void stopButtonClicked();
void tabChanged(int index); void tabChanged(int index);
void tabStatusChanged(QWidget *tab); void tabStatusChanged(SearchJobWidget *tab);
void closeTab(int index); void closeTab(int index);
void closeAllTabs(); void closeAllTabs();
@ -86,6 +87,5 @@ private:
Ui::SearchWidget *m_ui = nullptr; Ui::SearchWidget *m_ui = nullptr;
QPointer<SearchJobWidget> m_currentSearchTab; // Selected tab QPointer<SearchJobWidget> m_currentSearchTab; // Selected tab
QPointer<SearchJobWidget> m_activeSearchTab; // Tab with running search
bool m_isNewQueryString = false; bool m_isNewQueryString = false;
}; };

View file

@ -52,6 +52,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="stopButton">
<property name="text">
<string>Stop</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>