mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-07-14 01:03:08 -07:00
parent
f8536162f2
commit
b76054beba
6 changed files with 246 additions and 7 deletions
|
@ -655,6 +655,21 @@ void Preferences::setSearchEnabled(const bool enabled)
|
||||||
setValue(u"Preferences/Search/SearchEnabled"_s, enabled);
|
setValue(u"Preferences/Search/SearchEnabled"_s, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Preferences::searchHistoryLength() const
|
||||||
|
{
|
||||||
|
const int val = value(u"Search/HistoryLength"_s, 50);
|
||||||
|
return std::clamp(val, 0, 99);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Preferences::setSearchHistoryLength(const int length)
|
||||||
|
{
|
||||||
|
const int clampedLength = std::clamp(length, 0, 99);
|
||||||
|
if (clampedLength == searchHistoryLength())
|
||||||
|
return;
|
||||||
|
|
||||||
|
setValue(u"Search/HistoryLength"_s, clampedLength);
|
||||||
|
}
|
||||||
|
|
||||||
bool Preferences::storeOpenedSearchTabs() const
|
bool Preferences::storeOpenedSearchTabs() const
|
||||||
{
|
{
|
||||||
return value(u"Search/StoreOpenedSearchTabs"_s, false);
|
return value(u"Search/StoreOpenedSearchTabs"_s, false);
|
||||||
|
|
|
@ -173,6 +173,8 @@ public:
|
||||||
void setSearchEnabled(bool enabled);
|
void setSearchEnabled(bool enabled);
|
||||||
|
|
||||||
// Search UI
|
// Search UI
|
||||||
|
int searchHistoryLength() const;
|
||||||
|
void setSearchHistoryLength(int length);
|
||||||
bool storeOpenedSearchTabs() const;
|
bool storeOpenedSearchTabs() const;
|
||||||
void setStoreOpenedSearchTabs(bool enabled);
|
void setStoreOpenedSearchTabs(bool enabled);
|
||||||
bool storeOpenedSearchTabResults() const;
|
bool storeOpenedSearchTabResults() const;
|
||||||
|
|
|
@ -1281,9 +1281,11 @@ void OptionsDialog::loadSearchTabOptions()
|
||||||
|
|
||||||
m_ui->groupStoreOpenedTabs->setChecked(pref->storeOpenedSearchTabs());
|
m_ui->groupStoreOpenedTabs->setChecked(pref->storeOpenedSearchTabs());
|
||||||
m_ui->checkStoreTabsSearchResults->setChecked(pref->storeOpenedSearchTabResults());
|
m_ui->checkStoreTabsSearchResults->setChecked(pref->storeOpenedSearchTabResults());
|
||||||
|
m_ui->searchHistoryLengthSpinBox->setValue(pref->searchHistoryLength());
|
||||||
|
|
||||||
connect(m_ui->groupStoreOpenedTabs, &QGroupBox::toggled, this, &OptionsDialog::enableApplyButton);
|
connect(m_ui->groupStoreOpenedTabs, &QGroupBox::toggled, this, &OptionsDialog::enableApplyButton);
|
||||||
connect(m_ui->checkStoreTabsSearchResults, &QCheckBox::toggled, this, &OptionsDialog::enableApplyButton);
|
connect(m_ui->checkStoreTabsSearchResults, &QCheckBox::toggled, this, &OptionsDialog::enableApplyButton);
|
||||||
|
connect(m_ui->searchHistoryLengthSpinBox, qSpinBoxValueChanged, this, &OptionsDialog::enableApplyButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsDialog::saveSearchTabOptions() const
|
void OptionsDialog::saveSearchTabOptions() const
|
||||||
|
@ -1292,6 +1294,7 @@ void OptionsDialog::saveSearchTabOptions() const
|
||||||
|
|
||||||
pref->setStoreOpenedSearchTabs(m_ui->groupStoreOpenedTabs->isChecked());
|
pref->setStoreOpenedSearchTabs(m_ui->groupStoreOpenedTabs->isChecked());
|
||||||
pref->setStoreOpenedSearchTabResults(m_ui->checkStoreTabsSearchResults->isChecked());
|
pref->setStoreOpenedSearchTabResults(m_ui->checkStoreTabsSearchResults->isChecked());
|
||||||
|
pref->setSearchHistoryLength(m_ui->searchHistoryLengthSpinBox->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef DISABLE_WEBUI
|
#ifndef DISABLE_WEBUI
|
||||||
|
|
|
@ -3272,6 +3272,43 @@ Disable encryption: Only connect to peers without protocol encryption</string>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="searchHistoryLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="searchHistoryLengthLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>History length</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="searchHistoryLengthSpinBox">
|
||||||
|
<property name="buttonSymbols">
|
||||||
|
<enum>QAbstractSpinBox::ButtonSymbols::PlusMinus</enum>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>99</number>
|
||||||
|
</property>
|
||||||
|
<property name="stepType">
|
||||||
|
<enum>QAbstractSpinBox::StepType::DefaultStepType</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="searchHistoryLengthSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include <QCompleter>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
@ -48,6 +49,9 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QStringListModel>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
|
@ -56,6 +60,8 @@
|
||||||
#include "base/profile.h"
|
#include "base/profile.h"
|
||||||
#include "base/search/searchhandler.h"
|
#include "base/search/searchhandler.h"
|
||||||
#include "base/search/searchpluginmanager.h"
|
#include "base/search/searchpluginmanager.h"
|
||||||
|
#include "base/utils/bytearray.h"
|
||||||
|
#include "base/utils/compare.h"
|
||||||
#include "base/utils/datetime.h"
|
#include "base/utils/datetime.h"
|
||||||
#include "base/utils/fs.h"
|
#include "base/utils/fs.h"
|
||||||
#include "base/utils/foreignapps.h"
|
#include "base/utils/foreignapps.h"
|
||||||
|
@ -67,7 +73,12 @@
|
||||||
#include "searchjobwidget.h"
|
#include "searchjobwidget.h"
|
||||||
#include "ui_searchwidget.h"
|
#include "ui_searchwidget.h"
|
||||||
|
|
||||||
|
const int HISTORY_FILE_MAX_SIZE = 10 * 1024 * 1024;
|
||||||
|
const int SESSION_FILE_MAX_SIZE = 10 * 1024 * 1024;
|
||||||
|
const int RESULTS_FILE_MAX_SIZE = 10 * 1024 * 1024;
|
||||||
|
|
||||||
const QString DATA_FOLDER_NAME = u"SearchUI"_s;
|
const QString DATA_FOLDER_NAME = u"SearchUI"_s;
|
||||||
|
const QString HISTORY_FILE_NAME = u"History.txt"_s;
|
||||||
const QString SESSION_FILE_NAME = u"Session.json"_s;
|
const QString SESSION_FILE_NAME = u"Session.json"_s;
|
||||||
|
|
||||||
const QString KEY_SESSION_TABS = u"Tabs"_s;
|
const QString KEY_SESSION_TABS = u"Tabs"_s;
|
||||||
|
@ -86,6 +97,24 @@ const QString KEY_RESULT_PUBDATE = u"PubDate"_s;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
class SearchHistorySortModel final : public QSortFilterProxyModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY_MOVE(SearchHistorySortModel)
|
||||||
|
|
||||||
|
public:
|
||||||
|
using QSortFilterProxyModel::QSortFilterProxyModel;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override
|
||||||
|
{
|
||||||
|
const int result = m_naturalCompare(left.data(sortRole()).toString(), right.data(sortRole()).toString());
|
||||||
|
return result < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils::Compare::NaturalCompare<Qt::CaseInsensitive> m_naturalCompare;
|
||||||
|
};
|
||||||
|
|
||||||
struct TabData
|
struct TabData
|
||||||
{
|
{
|
||||||
QString tabID;
|
QString tabID;
|
||||||
|
@ -132,10 +161,27 @@ namespace
|
||||||
return tabName;
|
return tabName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nonstd::expected<QStringList, QString> loadHistory(const Path &filePath)
|
||||||
|
{
|
||||||
|
const auto readResult = Utils::IO::readFile(filePath, HISTORY_FILE_MAX_SIZE);
|
||||||
|
if (!readResult)
|
||||||
|
{
|
||||||
|
if (readResult.error().status == Utils::IO::ReadError::NotExist)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return nonstd::make_unexpected(readResult.error().message);
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList history;
|
||||||
|
for (const QByteArrayView line : asConst(Utils::ByteArray::splitToViews(readResult.value(), "\n")))
|
||||||
|
history.append(QString::fromUtf8(line));
|
||||||
|
|
||||||
|
return history;
|
||||||
|
}
|
||||||
|
|
||||||
nonstd::expected<SessionData, QString> loadSession(const Path &filePath)
|
nonstd::expected<SessionData, QString> loadSession(const Path &filePath)
|
||||||
{
|
{
|
||||||
const int fileMaxSize = 10 * 1024 * 1024;
|
const auto readResult = Utils::IO::readFile(filePath, SESSION_FILE_MAX_SIZE);
|
||||||
const auto readResult = Utils::IO::readFile(filePath, fileMaxSize);
|
|
||||||
if (!readResult)
|
if (!readResult)
|
||||||
{
|
{
|
||||||
if (readResult.error().status == Utils::IO::ReadError::NotExist)
|
if (readResult.error().status == Utils::IO::ReadError::NotExist)
|
||||||
|
@ -191,8 +237,7 @@ namespace
|
||||||
|
|
||||||
nonstd::expected<QList<SearchResult>, QString> loadSearchResults(const Path &filePath)
|
nonstd::expected<QList<SearchResult>, QString> loadSearchResults(const Path &filePath)
|
||||||
{
|
{
|
||||||
const int fileMaxSize = 10 * 1024 * 1024;
|
const auto readResult = Utils::IO::readFile(filePath, RESULTS_FILE_MAX_SIZE);
|
||||||
const auto readResult = Utils::IO::readFile(filePath, fileMaxSize);
|
|
||||||
if (!readResult)
|
if (!readResult)
|
||||||
{
|
{
|
||||||
if (readResult.error().status != Utils::IO::ReadError::NotExist)
|
if (readResult.error().status != Utils::IO::ReadError::NotExist)
|
||||||
|
@ -285,8 +330,12 @@ public:
|
||||||
void removeSession();
|
void removeSession();
|
||||||
void storeTab(const QString &tabID, const QList<SearchResult> &searchResults);
|
void storeTab(const QString &tabID, const QList<SearchResult> &searchResults);
|
||||||
void removeTab(const QString &tabID);
|
void removeTab(const QString &tabID);
|
||||||
|
void loadHistory();
|
||||||
|
void storeHistory(const QStringList &history);
|
||||||
|
void removeHistory();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void historyLoaded(const QStringList &history);
|
||||||
void sessionLoaded(const SessionData &sessionData);
|
void sessionLoaded(const SessionData &sessionData);
|
||||||
void tabLoaded(const QString &tabID, const QString &searchPattern, const QList<SearchResult> &searchResults);
|
void tabLoaded(const QString &tabID, const QString &searchPattern, const QList<SearchResult> &searchResults);
|
||||||
};
|
};
|
||||||
|
@ -295,7 +344,7 @@ SearchWidget::SearchWidget(IGUIApplication *app, QWidget *parent)
|
||||||
: GUIApplicationComponent(app, parent)
|
: GUIApplicationComponent(app, parent)
|
||||||
, m_ui {new Ui::SearchWidget()}
|
, m_ui {new Ui::SearchWidget()}
|
||||||
, m_ioThread {new QThread}
|
, m_ioThread {new QThread}
|
||||||
, m_dataStorage {new DataStorage(this)}
|
, m_dataStorage {new DataStorage}
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
|
@ -379,6 +428,7 @@ SearchWidget::SearchWidget(IGUIApplication *app, QWidget *parent)
|
||||||
const auto *focusSearchHotkeyAlternative = new QShortcut((Qt::CTRL | Qt::Key_E), this);
|
const auto *focusSearchHotkeyAlternative = new QShortcut((Qt::CTRL | Qt::Key_E), this);
|
||||||
connect(focusSearchHotkeyAlternative, &QShortcut::activated, this, &SearchWidget::toggleFocusBetweenLineEdits);
|
connect(focusSearchHotkeyAlternative, &QShortcut::activated, this, &SearchWidget::toggleFocusBetweenLineEdits);
|
||||||
|
|
||||||
|
m_historyLength = Preferences::instance()->searchHistoryLength();
|
||||||
m_storeOpenedTabs = Preferences::instance()->storeOpenedSearchTabs();
|
m_storeOpenedTabs = Preferences::instance()->storeOpenedSearchTabs();
|
||||||
m_storeOpenedTabsResults = Preferences::instance()->storeOpenedSearchTabResults();
|
m_storeOpenedTabsResults = Preferences::instance()->storeOpenedSearchTabResults();
|
||||||
connect(Preferences::instance(), &Preferences::changed, this, &SearchWidget::onPreferencesChanged);
|
connect(Preferences::instance(), &Preferences::changed, this, &SearchWidget::onPreferencesChanged);
|
||||||
|
@ -388,6 +438,7 @@ SearchWidget::SearchWidget(IGUIApplication *app, QWidget *parent)
|
||||||
m_ioThread->setObjectName("SearchWidget m_ioThread");
|
m_ioThread->setObjectName("SearchWidget m_ioThread");
|
||||||
m_ioThread->start();
|
m_ioThread->start();
|
||||||
|
|
||||||
|
loadHistory();
|
||||||
restoreSession();
|
restoreSession();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,7 +488,7 @@ void SearchWidget::onPreferencesChanged()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(m_dataStorage, [this] { m_dataStorage->removeSession(); });
|
QMetaObject::invokeMethod(m_dataStorage, &SearchWidget::DataStorage::removeSession);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,6 +520,36 @@ void SearchWidget::onPreferencesChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int historyLength = pref->searchHistoryLength();
|
||||||
|
if (historyLength != m_historyLength)
|
||||||
|
{
|
||||||
|
if (m_historyLength <= 0)
|
||||||
|
{
|
||||||
|
createSearchPatternCompleter();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (historyLength <= 0)
|
||||||
|
{
|
||||||
|
m_searchPatternCompleterModel->removeRows(0, m_searchPatternCompleterModel->rowCount());
|
||||||
|
QMetaObject::invokeMethod(m_dataStorage, &SearchWidget::DataStorage::removeHistory);
|
||||||
|
}
|
||||||
|
else if (historyLength < m_historyLength)
|
||||||
|
{
|
||||||
|
if (const int rowCount = m_searchPatternCompleterModel->rowCount(); rowCount > historyLength)
|
||||||
|
{
|
||||||
|
m_searchPatternCompleterModel->removeRows(0, (rowCount - historyLength));
|
||||||
|
QMetaObject::invokeMethod(m_dataStorage, [this]
|
||||||
|
{
|
||||||
|
m_dataStorage->storeHistory(m_searchPatternCompleterModel->stringList());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_historyLength = historyLength;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchWidget::fillCatCombobox()
|
void SearchWidget::fillCatCombobox()
|
||||||
|
@ -552,6 +633,54 @@ int SearchWidget::addTab(const QString &tabID, SearchJobWidget *searchJobWdget)
|
||||||
return m_ui->tabWidget->addTab(searchJobWdget, makeTabName(searchJobWdget));
|
return m_ui->tabWidget->addTab(searchJobWdget, makeTabName(searchJobWdget));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SearchWidget::updateHistory(const QString &newSearchPattern)
|
||||||
|
{
|
||||||
|
if (m_historyLength <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_searchPatternCompleterModel->stringList().contains(newSearchPattern))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const int rowNum = m_searchPatternCompleterModel->rowCount();
|
||||||
|
m_searchPatternCompleterModel->insertRow(rowNum);
|
||||||
|
m_searchPatternCompleterModel->setData(m_searchPatternCompleterModel->index(rowNum, 0), newSearchPattern);
|
||||||
|
if (m_searchPatternCompleterModel->rowCount() > m_historyLength)
|
||||||
|
m_searchPatternCompleterModel->removeRow(0);
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod(m_dataStorage, [this, history = m_searchPatternCompleterModel->stringList()]
|
||||||
|
{
|
||||||
|
m_dataStorage->storeHistory(history);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void SearchWidget::loadHistory()
|
||||||
|
{
|
||||||
|
if (m_historyLength <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
createSearchPatternCompleter();
|
||||||
|
|
||||||
|
connect(m_dataStorage, &DataStorage::historyLoaded, this, [this](const QStringList &storedHistory)
|
||||||
|
{
|
||||||
|
if (m_historyLength <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QStringList history = storedHistory;
|
||||||
|
for (const QString &newPattern : asConst(m_searchPatternCompleterModel->stringList()))
|
||||||
|
{
|
||||||
|
if (!history.contains(newPattern))
|
||||||
|
history.append(newPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (history.size() > m_historyLength)
|
||||||
|
history = history.mid(history.size() - m_historyLength);
|
||||||
|
|
||||||
|
m_searchPatternCompleterModel->setStringList(history);
|
||||||
|
});
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod(m_dataStorage, &SearchWidget::DataStorage::loadHistory);
|
||||||
|
}
|
||||||
|
|
||||||
void SearchWidget::saveSession() const
|
void SearchWidget::saveSession() const
|
||||||
{
|
{
|
||||||
if (!m_storeOpenedTabs)
|
if (!m_storeOpenedTabs)
|
||||||
|
@ -570,6 +699,20 @@ void SearchWidget::saveSession() const
|
||||||
QMetaObject::invokeMethod(m_dataStorage, [this, sessionData] { m_dataStorage->storeSession(sessionData); });
|
QMetaObject::invokeMethod(m_dataStorage, [this, sessionData] { m_dataStorage->storeSession(sessionData); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SearchWidget::createSearchPatternCompleter()
|
||||||
|
{
|
||||||
|
Q_ASSERT(!m_ui->lineEditSearchPattern->completer());
|
||||||
|
|
||||||
|
m_searchPatternCompleterModel = new QStringListModel(this);
|
||||||
|
auto *sortModel = new SearchHistorySortModel(this);
|
||||||
|
sortModel->setSourceModel(m_searchPatternCompleterModel);
|
||||||
|
sortModel->sort(0);
|
||||||
|
auto *completer = new QCompleter(sortModel, this);
|
||||||
|
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
|
||||||
|
m_ui->lineEditSearchPattern->setCompleter(completer);
|
||||||
|
}
|
||||||
|
|
||||||
void SearchWidget::restoreSession()
|
void SearchWidget::restoreSession()
|
||||||
{
|
{
|
||||||
if (!m_storeOpenedTabs)
|
if (!m_storeOpenedTabs)
|
||||||
|
@ -750,6 +893,7 @@ void SearchWidget::searchButtonClicked()
|
||||||
m_ui->tabWidget->setTabIcon(tabIndex, UIThemeManager::instance()->getIcon(statusIconName(newTab->status())));
|
m_ui->tabWidget->setTabIcon(tabIndex, UIThemeManager::instance()->getIcon(statusIconName(newTab->status())));
|
||||||
m_ui->tabWidget->setCurrentWidget(newTab);
|
m_ui->tabWidget->setCurrentWidget(newTab);
|
||||||
adjustSearchButton();
|
adjustSearchButton();
|
||||||
|
updateHistory(pattern);
|
||||||
saveSession();
|
saveSession();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -918,4 +1062,34 @@ void SearchWidget::DataStorage::removeTab(const QString &tabID)
|
||||||
Utils::Fs::removeFile(makeDataFilePath(tabID + u".json"));
|
Utils::Fs::removeFile(makeDataFilePath(tabID + u".json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SearchWidget::DataStorage::loadHistory()
|
||||||
|
{
|
||||||
|
const Path historyFilePath = makeDataFilePath(HISTORY_FILE_NAME);
|
||||||
|
const auto loadResult = ::loadHistory(historyFilePath);
|
||||||
|
if (!loadResult)
|
||||||
|
{
|
||||||
|
LogMsg(tr("Failed to load Search UI history. File: \"%1\". Error: \"%2\"")
|
||||||
|
.arg(historyFilePath.toString(), loadResult.error()), Log::WARNING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit historyLoaded(loadResult.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SearchWidget::DataStorage::storeHistory(const QStringList &history)
|
||||||
|
{
|
||||||
|
const Path filePath = makeDataFilePath(HISTORY_FILE_NAME);
|
||||||
|
const auto saveResult = Utils::IO::saveToFile(filePath, history.join(u'\n').toUtf8());
|
||||||
|
if (!saveResult)
|
||||||
|
{
|
||||||
|
LogMsg(tr("Failed to save search history. File: \"%1\". Error: \"%2\"")
|
||||||
|
.arg(filePath.toString(), saveResult.error()), Log::WARNING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SearchWidget::DataStorage::removeHistory()
|
||||||
|
{
|
||||||
|
Utils::Fs::removeFile(makeDataFilePath(HISTORY_FILE_NAME));
|
||||||
|
}
|
||||||
|
|
||||||
#include "searchwidget.moc"
|
#include "searchwidget.moc"
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
class QEvent;
|
class QEvent;
|
||||||
class QObject;
|
class QObject;
|
||||||
|
class QStringListModel;
|
||||||
|
|
||||||
class SearchJobWidget;
|
class SearchJobWidget;
|
||||||
|
|
||||||
|
@ -93,8 +94,12 @@ private:
|
||||||
QString generateTabID() const;
|
QString generateTabID() const;
|
||||||
int addTab(const QString &tabID, SearchJobWidget *searchJobWdget);
|
int addTab(const QString &tabID, SearchJobWidget *searchJobWdget);
|
||||||
|
|
||||||
void saveSession() const;
|
void loadHistory();
|
||||||
void restoreSession();
|
void restoreSession();
|
||||||
|
void updateHistory(const QString &newSearchPattern);
|
||||||
|
void saveSession() const;
|
||||||
|
|
||||||
|
void createSearchPatternCompleter();
|
||||||
|
|
||||||
Ui::SearchWidget *m_ui = nullptr;
|
Ui::SearchWidget *m_ui = nullptr;
|
||||||
QPointer<SearchJobWidget> m_currentSearchTab; // Selected tab
|
QPointer<SearchJobWidget> m_currentSearchTab; // Selected tab
|
||||||
|
@ -103,9 +108,12 @@ private:
|
||||||
|
|
||||||
bool m_storeOpenedTabs = false;
|
bool m_storeOpenedTabs = false;
|
||||||
bool m_storeOpenedTabsResults = false;
|
bool m_storeOpenedTabsResults = false;
|
||||||
|
int m_historyLength = 0;
|
||||||
|
|
||||||
Utils::Thread::UniquePtr m_ioThread;
|
Utils::Thread::UniquePtr m_ioThread;
|
||||||
|
|
||||||
class DataStorage;
|
class DataStorage;
|
||||||
DataStorage *m_dataStorage = nullptr;
|
DataStorage *m_dataStorage = nullptr;
|
||||||
|
|
||||||
|
QStringListModel *m_searchPatternCompleterModel = nullptr;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue