diff --git a/src/base/preferences.cpp b/src/base/preferences.cpp index ed9ecd316dc1..6a6b143edf70 100644 --- a/src/base/preferences.cpp +++ b/src/base/preferences.cpp @@ -655,6 +655,32 @@ void Preferences::setSearchEnabled(const bool enabled) setValue(u"Preferences/Search/SearchEnabled"_s, enabled); } +bool Preferences::storeOpenedSearchTabs() const +{ + return value(u"Search/StoreOpenedSearchTabs"_s, false); +} + +void Preferences::setStoreOpenedSearchTabs(const bool enabled) +{ + if (enabled == storeOpenedSearchTabs()) + return; + + setValue(u"Search/StoreOpenedSearchTabs"_s, enabled); +} + +bool Preferences::storeOpenedSearchTabResults() const +{ + return value(u"Search/StoreOpenedSearchTabResults"_s, false); +} + +void Preferences::setStoreOpenedSearchTabResults(const bool enabled) +{ + if (enabled == storeOpenedSearchTabResults()) + return; + + setValue(u"Search/StoreOpenedSearchTabResults"_s, enabled); +} + bool Preferences::isWebUIEnabled() const { #ifdef DISABLE_GUI diff --git a/src/base/preferences.h b/src/base/preferences.h index b1a912477bda..7e07446d6541 100644 --- a/src/base/preferences.h +++ b/src/base/preferences.h @@ -172,6 +172,12 @@ class Preferences final : public QObject bool isSearchEnabled() const; void setSearchEnabled(bool enabled); + // Search UI + bool storeOpenedSearchTabs() const; + void setStoreOpenedSearchTabs(bool enabled); + bool storeOpenedSearchTabResults() const; + void setStoreOpenedSearchTabResults(bool enabled); + // HTTP Server bool isWebUIEnabled() const; void setWebUIEnabled(bool enabled); diff --git a/src/gui/optionsdialog.cpp b/src/gui/optionsdialog.cpp index 676612146589..ba4ee232c8a3 100644 --- a/src/gui/optionsdialog.cpp +++ b/src/gui/optionsdialog.cpp @@ -164,6 +164,7 @@ OptionsDialog::OptionsDialog(IGUIApplication *app, QWidget *parent) m_ui->tabSelection->item(TAB_DOWNLOADS)->setIcon(UIThemeManager::instance()->getIcon(u"download"_s, u"folder-download"_s)); m_ui->tabSelection->item(TAB_SPEED)->setIcon(UIThemeManager::instance()->getIcon(u"speedometer"_s, u"chronometer"_s)); m_ui->tabSelection->item(TAB_RSS)->setIcon(UIThemeManager::instance()->getIcon(u"application-rss"_s, u"application-rss+xml"_s)); + m_ui->tabSelection->item(TAB_SEARCH)->setIcon(UIThemeManager::instance()->getIcon(u"edit-find"_s)); #ifdef DISABLE_WEBUI m_ui->tabSelection->item(TAB_WEBUI)->setHidden(true); #else @@ -190,6 +191,7 @@ OptionsDialog::OptionsDialog(IGUIApplication *app, QWidget *parent) loadSpeedTabOptions(); loadBittorrentTabOptions(); loadRSSTabOptions(); + loadSearchTabOptions(); #ifndef DISABLE_WEBUI loadWebUITabOptions(); #endif @@ -1273,6 +1275,25 @@ void OptionsDialog::saveRSSTabOptions() const autoDownloader->setDownloadRepacks(m_ui->checkSmartFilterDownloadRepacks->isChecked()); } +void OptionsDialog::loadSearchTabOptions() +{ + const auto *pref = Preferences::instance(); + + m_ui->groupStoreOpenedTabs->setChecked(pref->storeOpenedSearchTabs()); + m_ui->checkStoreTabsSearchResults->setChecked(pref->storeOpenedSearchTabResults()); + + connect(m_ui->groupStoreOpenedTabs, &QGroupBox::toggled, this, &OptionsDialog::enableApplyButton); + connect(m_ui->checkStoreTabsSearchResults, &QCheckBox::toggled, this, &OptionsDialog::enableApplyButton); +} + +void OptionsDialog::saveSearchTabOptions() const +{ + auto *pref = Preferences::instance(); + + pref->setStoreOpenedSearchTabs(m_ui->groupStoreOpenedTabs->isChecked()); + pref->setStoreOpenedSearchTabResults(m_ui->checkStoreTabsSearchResults->isChecked()); +} + #ifndef DISABLE_WEBUI void OptionsDialog::loadWebUITabOptions() { @@ -1465,6 +1486,7 @@ void OptionsDialog::saveOptions() const saveSpeedTabOptions(); saveBittorrentTabOptions(); saveRSSTabOptions(); + saveSearchTabOptions(); #ifndef DISABLE_WEBUI saveWebUITabOptions(); #endif diff --git a/src/gui/optionsdialog.h b/src/gui/optionsdialog.h index 534ca4078ef8..795ec3bf36a8 100644 --- a/src/gui/optionsdialog.h +++ b/src/gui/optionsdialog.h @@ -74,6 +74,7 @@ class OptionsDialog final : public GUIApplicationComponent TAB_SPEED, TAB_BITTORRENT, TAB_RSS, + TAB_SEARCH, TAB_WEBUI, TAB_ADVANCED }; @@ -136,6 +137,9 @@ private slots: void loadRSSTabOptions(); void saveRSSTabOptions() const; + void loadSearchTabOptions(); + void saveSearchTabOptions() const; + #ifndef DISABLE_WEBUI void loadWebUITabOptions(); void saveWebUITabOptions() const; diff --git a/src/gui/optionsdialog.ui b/src/gui/optionsdialog.ui index 16484c71705e..140e4c31d84c 100644 --- a/src/gui/optionsdialog.ui +++ b/src/gui/optionsdialog.ui @@ -77,6 +77,11 @@ RSS + + + Search + + WebUI @@ -3404,6 +3409,85 @@ Disable encryption: Only connect to peers without protocol encryption + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + + 0 + 0 + 521 + 541 + + + + + + + Search UI + + + + + + Store opened tabs + + + true + + + false + + + + + + Also store search results + + + + + + + + + + + + + Qt::Orientation::Vertical + + + + 20 + 422 + + + + + + + + + + diff --git a/src/gui/search/searchwidget.cpp b/src/gui/search/searchwidget.cpp index 6e1a43c07733..2c23d5fdfe31 100644 --- a/src/gui/search/searchwidget.cpp +++ b/src/gui/search/searchwidget.cpp @@ -34,10 +34,6 @@ #include -#ifdef Q_OS_WIN -#include -#endif - #include #include #include @@ -55,6 +51,7 @@ #include "base/global.h" #include "base/logger.h" +#include "base/preferences.h" #include "base/profile.h" #include "base/search/searchhandler.h" #include "base/search/searchpluginmanager.h" @@ -257,6 +254,9 @@ SearchWidget::SearchWidget(IGUIApplication *app, QWidget *parent) const auto *focusSearchHotkeyAlternative = new QShortcut((Qt::CTRL | Qt::Key_E), this); connect(focusSearchHotkeyAlternative, &QShortcut::activated, this, &SearchWidget::toggleFocusBetweenLineEdits); + configure(); + connect(Preferences::instance(), &Preferences::changed, this, &SearchWidget::configure); + restoreState(); } @@ -291,6 +291,44 @@ bool SearchWidget::eventFilter(QObject *object, QEvent *event) return QWidget::eventFilter(object, event); } +void SearchWidget::configure() +{ + const auto *pref = Preferences::instance(); + + const bool storeOpenedTabs = pref->storeOpenedSearchTabs(); + const bool isStoreOpenedTabsChanged = storeOpenedTabs != m_storeOpenedTabs; + if (isStoreOpenedTabsChanged) + { + m_storeOpenedTabs = storeOpenedTabs; + if (m_storeOpenedTabs) + { + // TODO: Store all tabs. + } + else + { + // TODO: Delete all stored tabs. + } + } + + + const bool storeOpenedTabsResults = pref->storeOpenedSearchTabResults(); + const bool isStoreOpenedTabsResultsChanged = storeOpenedTabsResults != m_storeOpenedTabsResults; + if (isStoreOpenedTabsResultsChanged) + m_storeOpenedTabsResults = storeOpenedTabsResults; + + if (isStoreOpenedTabsResultsChanged || isStoreOpenedTabsChanged) + { + if (m_storeOpenedTabsResults) + { + // TODO: Store all tabs results. + } + else + { + // TODO: Delete all stored tabs results. + } + } +} + void SearchWidget::fillCatCombobox() { m_ui->comboCategory->clear(); @@ -411,6 +449,9 @@ void SearchWidget::saveSearchResults(SearchJobWidget *searchJobWidget) const void SearchWidget::saveState() const { + if (!m_storeOpenedTabs) + return; + QJsonArray tabsList; for (int tabIndex = 0; tabIndex < m_ui->tabWidget->count(); ++tabIndex) { @@ -437,6 +478,9 @@ void SearchWidget::saveState() const void SearchWidget::restoreState() { + if (!m_storeOpenedTabs) + return; + const int fileMaxSize = 10 * 1024 * 1024; const Path stateFilePath = makeDataFilePath(STATE_FILE_NAME); const auto readResult = Utils::IO::readFile(stateFilePath, fileMaxSize); @@ -519,15 +563,18 @@ void SearchWidget::restoreState() { QList searchResults; - const Path tabStateFilePath = makeDataFilePath(tabID + u".json"); - if (const auto loadTabStateResult = loadSearchResults(tabStateFilePath)) + if (m_storeOpenedTabsResults) { - searchResults = loadTabStateResult.value(); - } - else - { - LogMsg(tr("Failed to load saved search results. Tab: \"%1\". File: \"%2\". Error: \"%3\"") - .arg(searchPattern, tabStateFilePath.toString(), loadTabStateResult.error()), Log::WARNING); + const Path tabStateFilePath = makeDataFilePath(tabID + u".json"); + if (const auto loadTabStateResult = loadSearchResults(tabStateFilePath)) + { + searchResults = loadTabStateResult.value(); + } + else + { + LogMsg(tr("Failed to load saved search results. Tab: \"%1\". File: \"%2\". Error: \"%3\"") + .arg(searchPattern, tabStateFilePath.toString(), loadTabStateResult.error()), Log::WARNING); + } } auto *restoredTab = new SearchJobWidget(tabID, searchPattern, searchResults, app(), this); @@ -715,7 +762,8 @@ void SearchWidget::tabStatusChanged(SearchJobWidget *tab) emit searchFinished(tab->status() == SearchJobWidget::Status::Error); - saveSearchResults(tab); + if (m_storeOpenedTabsResults) + saveSearchResults(tab); } } diff --git a/src/gui/search/searchwidget.h b/src/gui/search/searchwidget.h index d2aa1524355a..cc4e19245727 100644 --- a/src/gui/search/searchwidget.h +++ b/src/gui/search/searchwidget.h @@ -64,6 +64,8 @@ class SearchWidget : public GUIApplicationComponent private: bool eventFilter(QObject *object, QEvent *event) override; + void configure(); + void pluginsButtonClicked(); void searchButtonClicked(); void stopButtonClicked(); @@ -100,4 +102,7 @@ class SearchWidget : public GUIApplicationComponent QPointer m_currentSearchTab; // Selected tab bool m_isNewQueryString = false; QSet m_tabIDs; + + bool m_storeOpenedTabs = false; + bool m_storeOpenedTabsResults = false; };