Add a small delay before processing the key input of search boxes

PR #20465.
Closes #20025.
Closes #20235.
This commit is contained in:
Chocobo1 2024-02-27 12:57:55 +08:00 committed by sledgehammer999
parent 6805922521
commit 7567f71c55
No known key found for this signature in database
GPG key ID: 6E4A2D025B7CC9A2
14 changed files with 88 additions and 51 deletions

View file

@ -33,6 +33,7 @@
#include <functional> #include <functional>
#include <QAction> #include <QAction>
#include <QByteArray>
#include <QDateTime> #include <QDateTime>
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
@ -41,6 +42,7 @@
#include <QPushButton> #include <QPushButton>
#include <QScreen> #include <QScreen>
#include <QShortcut> #include <QShortcut>
#include <QSize>
#include <QString> #include <QString>
#include <QUrl> #include <QUrl>
#include <QVector> #include <QVector>

View file

@ -39,6 +39,9 @@
#include "base/path.h" #include "base/path.h"
#include "base/settingvalue.h" #include "base/settingvalue.h"
class LineEdit;
class TorrentFileGuard;
namespace BitTorrent namespace BitTorrent
{ {
class InfoHash; class InfoHash;
@ -54,9 +57,6 @@ namespace Ui
class AddNewTorrentDialog; class AddNewTorrentDialog;
} }
class LineEdit;
class TorrentFileGuard;
class AddNewTorrentDialog final : public QDialog class AddNewTorrentDialog final : public QDialog
{ {
Q_OBJECT Q_OBJECT

View file

@ -29,20 +29,41 @@
#include "lineedit.h" #include "lineedit.h"
#include <chrono>
#include <QAction> #include <QAction>
#include <QKeyEvent> #include <QKeyEvent>
#include <QTimer>
#include "base/global.h" #include "base/global.h"
#include "uithememanager.h" #include "uithememanager.h"
using namespace std::chrono_literals;
namespace
{
const std::chrono::milliseconds FILTER_INPUT_DELAY {400};
}
LineEdit::LineEdit(QWidget *parent) LineEdit::LineEdit(QWidget *parent)
: QLineEdit(parent) : QLineEdit(parent)
, m_delayedTextChangedTimer {new QTimer(this)}
{ {
auto *action = new QAction(UIThemeManager::instance()->getIcon(u"edit-find"_s), QString(), this); auto *action = new QAction(UIThemeManager::instance()->getIcon(u"edit-find"_s), QString(), this);
addAction(action, QLineEdit::LeadingPosition); addAction(action, QLineEdit::LeadingPosition);
setClearButtonEnabled(true); setClearButtonEnabled(true);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
m_delayedTextChangedTimer->setSingleShot(true);
connect(m_delayedTextChangedTimer, &QTimer::timeout, this, [this]
{
emit textChanged(text());
});
connect(this, &QLineEdit::textChanged, this, [this]
{
m_delayedTextChangedTimer->start(FILTER_INPUT_DELAY);
});
} }
void LineEdit::keyPressEvent(QKeyEvent *event) void LineEdit::keyPressEvent(QKeyEvent *event)

View file

@ -31,6 +31,9 @@
#include <QLineEdit> #include <QLineEdit>
class QKeyEvent;
class QTimer;
class LineEdit final : public QLineEdit class LineEdit final : public QLineEdit
{ {
Q_OBJECT Q_OBJECT
@ -39,6 +42,11 @@ class LineEdit final : public QLineEdit
public: public:
explicit LineEdit(QWidget *parent = nullptr); explicit LineEdit(QWidget *parent = nullptr);
signals:
void textChanged(const QString &text);
private: private:
void keyPressEvent(QKeyEvent *event) override; void keyPressEvent(QKeyEvent *event) override;
QTimer *m_delayedTextChangedTimer = nullptr;
}; };

View file

@ -57,6 +57,7 @@
#include <QShortcut> #include <QShortcut>
#include <QSplitter> #include <QSplitter>
#include <QStatusBar> #include <QStatusBar>
#include <QString>
#include <QtGlobal> #include <QtGlobal>
#include <QTimer> #include <QTimer>

View file

@ -42,6 +42,7 @@ class QCloseEvent;
class QComboBox; class QComboBox;
class QFileSystemWatcher; class QFileSystemWatcher;
class QSplitter; class QSplitter;
class QString;
class QTabWidget; class QTabWidget;
class QTimer; class QTimer;

View file

@ -128,9 +128,9 @@ SearchJobWidget::SearchJobWidget(SearchHandler *searchHandler, QWidget *parent)
m_lineEditSearchResultsFilter->setPlaceholderText(tr("Filter search results...")); m_lineEditSearchResultsFilter->setPlaceholderText(tr("Filter search results..."));
m_lineEditSearchResultsFilter->setContextMenuPolicy(Qt::CustomContextMenu); m_lineEditSearchResultsFilter->setContextMenuPolicy(Qt::CustomContextMenu);
connect(m_lineEditSearchResultsFilter, &QWidget::customContextMenuRequested, this, &SearchJobWidget::showFilterContextMenu); connect(m_lineEditSearchResultsFilter, &QWidget::customContextMenuRequested, this, &SearchJobWidget::showFilterContextMenu);
connect(m_lineEditSearchResultsFilter, &LineEdit::textChanged, this, &SearchJobWidget::filterSearchResults);
m_ui->horizontalLayout->insertWidget(0, m_lineEditSearchResultsFilter); m_ui->horizontalLayout->insertWidget(0, m_lineEditSearchResultsFilter);
connect(m_lineEditSearchResultsFilter, &LineEdit::textChanged, this, &SearchJobWidget::filterSearchResults);
connect(m_ui->filterMode, qOverload<int>(&QComboBox::currentIndexChanged) connect(m_ui->filterMode, qOverload<int>(&QComboBox::currentIndexChanged)
, this, &SearchJobWidget::updateFilter); , this, &SearchJobWidget::updateFilter);
connect(m_ui->minSeeds, &QAbstractSpinBox::editingFinished, this, &SearchJobWidget::updateFilter); connect(m_ui->minSeeds, &QAbstractSpinBox::editingFinished, this, &SearchJobWidget::updateFilter);

View file

@ -658,6 +658,8 @@ window.addEvent('load', function() {
$('error_div').set('html', ''); $('error_div').set('html', '');
if (response) { if (response) {
clearTimeout(torrentsFilterInputTimer); clearTimeout(torrentsFilterInputTimer);
torrentsFilterInputTimer = -1;
let torrentsTableSelectedRows; let torrentsTableSelectedRows;
let update_categories = false; let update_categories = false;
let updateTags = false; let updateTags = false;
@ -1357,18 +1359,14 @@ window.addEvent('load', function() {
$('torrentFilesFilterToolbar').addClass("invisible"); $('torrentFilesFilterToolbar').addClass("invisible");
}; };
let prevTorrentsFilterValue;
let torrentsFilterInputTimer = null;
// listen for changes to torrentsFilterInput // listen for changes to torrentsFilterInput
$('torrentsFilterInput').addEvent('input', function() { let torrentsFilterInputTimer = -1;
const value = $('torrentsFilterInput').get("value"); $('torrentsFilterInput').addEvent('input', () => {
if (value !== prevTorrentsFilterValue) { clearTimeout(torrentsFilterInputTimer);
prevTorrentsFilterValue = value; torrentsFilterInputTimer = setTimeout(() => {
clearTimeout(torrentsFilterInputTimer); torrentsFilterInputTimer = -1;
torrentsFilterInputTimer = setTimeout(function() { torrentsTable.updateTable();
torrentsTable.updateTable(false); }, window.qBittorrent.Misc.FILTER_INPUT_DELAY);
}, 400);
}
}); });
$('transfersTabLink').addEvent('click', showTransfersTab); $('transfersTabLink').addEvent('click', showTransfersTab);

View file

@ -175,12 +175,14 @@ window.qBittorrent.ContextMenu = (function() {
const touchstartEvent = e; const touchstartEvent = e;
this.touchstartTimer = setTimeout(function() { this.touchstartTimer = setTimeout(function() {
this.touchstartTimer = -1;
this.triggerMenu(touchstartEvent, elem); this.triggerMenu(touchstartEvent, elem);
}.bind(this), this.options.touchTimer); }.bind(this), this.options.touchTimer);
}.bind(this)); }.bind(this));
elem.addEvent('touchend', function(e) { elem.addEvent('touchend', function(e) {
e.preventDefault(); e.preventDefault();
clearTimeout(this.touchstartTimer); clearTimeout(this.touchstartTimer);
this.touchstartTimer = -1;
}.bind(this)); }.bind(this));
}, },

View file

@ -701,10 +701,7 @@ window.qBittorrent.DynamicTable = (function() {
return null; return null;
}, },
updateTable: function(fullUpdate) { updateTable: function(fullUpdate = false) {
if (fullUpdate === undefined)
fullUpdate = false;
const rows = this.getFilteredAndSortedRows(); const rows = this.getFilteredAndSortedRows();
for (let i = 0; i < this.selectedRows.length; ++i) for (let i = 0; i < this.selectedRows.length; ++i)

View file

@ -46,6 +46,8 @@ window.qBittorrent.Misc = (function() {
toFixedPointString: toFixedPointString, toFixedPointString: toFixedPointString,
containsAllTerms: containsAllTerms, containsAllTerms: containsAllTerms,
sleep: sleep, sleep: sleep,
// variables
FILTER_INPUT_DELAY: 400,
MAX_ETA: 8640000 MAX_ETA: 8640000
}; };
}; };

View file

@ -366,6 +366,7 @@ window.qBittorrent.PropFiles = (function() {
}, },
onSuccess: function(files) { onSuccess: function(files) {
clearTimeout(torrentFilesFilterInputTimer); clearTimeout(torrentFilesFilterInputTimer);
torrentFilesFilterInputTimer = -1;
if (files.length === 0) { if (files.length === 0) {
torrentFilesTable.clear(); torrentFilesTable.clear();
@ -640,26 +641,27 @@ window.qBittorrent.PropFiles = (function() {
if (torrentFilesTable.getSortedColumn() === null) if (torrentFilesTable.getSortedColumn() === null)
torrentFilesTable.setSortedColumn('name'); torrentFilesTable.setSortedColumn('name');
let prevTorrentFilesFilterValue;
let torrentFilesFilterInputTimer = null;
// listen for changes to torrentFilesFilterInput // listen for changes to torrentFilesFilterInput
$('torrentFilesFilterInput').addEvent('input', function() { let torrentFilesFilterInputTimer = -1;
const value = $('torrentFilesFilterInput').get("value"); $('torrentFilesFilterInput').addEvent('input', () => {
if (value !== prevTorrentFilesFilterValue) { clearTimeout(torrentFilesFilterInputTimer);
prevTorrentFilesFilterValue = value;
torrentFilesTable.setFilter(value);
clearTimeout(torrentFilesFilterInputTimer);
torrentFilesFilterInputTimer = setTimeout(function() {
if (current_hash === "")
return;
torrentFilesTable.updateTable(false);
if (value.trim() === "") const value = $('torrentFilesFilterInput').get("value");
collapseAllNodes(); torrentFilesTable.setFilter(value);
else
expandAllNodes(); torrentFilesFilterInputTimer = setTimeout(() => {
}, 400); torrentFilesFilterInputTimer = -1;
}
if (current_hash === "")
return;
torrentFilesTable.updateTable();
if (value.trim() === "")
collapseAllNodes();
else
expandAllNodes();
}, window.qBittorrent.Misc.FILTER_INPUT_DELAY);
}); });
/** /**

View file

@ -183,7 +183,7 @@
}; };
let customSyncLogDataInterval = null; let customSyncLogDataInterval = null;
let logFilterTimer; let logFilterTimer = -1;
let inputtedFilterText = ""; let inputtedFilterText = "";
let selectBox; let selectBox;
let selectedLogLevels = JSON.parse(LocalPreferences.get('qbt_selected_log_levels')) || ['1', '2', '4', '8']; let selectedLogLevels = JSON.parse(LocalPreferences.get('qbt_selected_log_levels')) || ['1', '2', '4', '8'];
@ -297,9 +297,11 @@
const logFilterChanged = () => { const logFilterChanged = () => {
clearTimeout(logFilterTimer); clearTimeout(logFilterTimer);
logFilterTimer = setTimeout((curTab) => { logFilterTimer = setTimeout((curTab) => {
logFilterTimer = -1;
tableInfo[curTab].instance.updateTable(false); tableInfo[curTab].instance.updateTable(false);
updateLabelCount(curTab); updateLabelCount(curTab);
}, 400, currentSelectedTab); }, window.qBittorrent.Misc.FILTER_INPUT_DELAY, currentSelectedTab);
}; };
const setCurrentTab = (tab) => { const setCurrentTab = (tab) => {
@ -321,6 +323,7 @@
} }
clearTimeout(logFilterTimer); clearTimeout(logFilterTimer);
logFilterTimer = -1;
load(); load();
if (tableInfo[currentSelectedTab].instance.filterText !== getFilterText()) { if (tableInfo[currentSelectedTab].instance.filterText !== getFilterText()) {
@ -377,6 +380,8 @@
if (response.length > 0) { if (response.length > 0) {
clearTimeout(logFilterTimer); clearTimeout(logFilterTimer);
logFilterTimer = -1;
for (let i = 0; i < response.length; ++i) { for (let i = 0; i < response.length; ++i) {
let row; let row;
if (curTab === 'main') { if (curTab === 'main') {

View file

@ -233,7 +233,6 @@
max: 0.00, max: 0.00,
maxUnit: 3 maxUnit: 3
}; };
let prevNameFilterValue;
let selectedCategory = "QBT_TR(All categories)QBT_TR[CONTEXT=SearchEngineWidget]"; let selectedCategory = "QBT_TR(All categories)QBT_TR[CONTEXT=SearchEngineWidget]";
let selectedPlugin = "all"; let selectedPlugin = "all";
let prevSelectedPlugin; let prevSelectedPlugin;
@ -258,18 +257,17 @@
searchResultsTable.setup('searchResultsTableDiv', 'searchResultsTableFixedHeaderDiv', searchResultsTableContextMenu); searchResultsTable.setup('searchResultsTableDiv', 'searchResultsTableFixedHeaderDiv', searchResultsTableContextMenu);
getPlugins(); getPlugins();
let searchInNameFilterTimer = null;
// listen for changes to searchInNameFilter // listen for changes to searchInNameFilter
$('searchInNameFilter').addEvent('input', function() { let searchInNameFilterTimer = -1;
const value = $('searchInNameFilter').get("value"); $('searchInNameFilter').addEvent('input', () => {
if (value !== prevNameFilterValue) { clearTimeout(searchInNameFilterTimer);
prevNameFilterValue = value; searchInNameFilterTimer = setTimeout(() => {
clearTimeout(searchInNameFilterTimer); searchInNameFilterTimer = -1;
searchInNameFilterTimer = setTimeout(function() {
searchText.filterPattern = value; const value = $('searchInNameFilter').get("value");
searchFilterChanged(); searchText.filterPattern = value;
}, 400); searchFilterChanged();
} }, window.qBittorrent.Misc.FILTER_INPUT_DELAY);
}); });
new Keyboard({ new Keyboard({