mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-12-26 17:58:19 +03:00
Add a small delay before processing the key input of search boxes
PR #20465. Closes #20025. Closes #20235.
This commit is contained in:
parent
6805922521
commit
7567f71c55
14 changed files with 88 additions and 51 deletions
|
@ -33,6 +33,7 @@
|
|||
#include <functional>
|
||||
|
||||
#include <QAction>
|
||||
#include <QByteArray>
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
|
@ -41,6 +42,7 @@
|
|||
#include <QPushButton>
|
||||
#include <QScreen>
|
||||
#include <QShortcut>
|
||||
#include <QSize>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
#include <QVector>
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
#include "base/path.h"
|
||||
#include "base/settingvalue.h"
|
||||
|
||||
class LineEdit;
|
||||
class TorrentFileGuard;
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
class InfoHash;
|
||||
|
@ -54,9 +57,6 @@ namespace Ui
|
|||
class AddNewTorrentDialog;
|
||||
}
|
||||
|
||||
class LineEdit;
|
||||
class TorrentFileGuard;
|
||||
|
||||
class AddNewTorrentDialog final : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
|
@ -29,20 +29,41 @@
|
|||
|
||||
#include "lineedit.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include <QAction>
|
||||
#include <QKeyEvent>
|
||||
#include <QTimer>
|
||||
|
||||
#include "base/global.h"
|
||||
#include "uithememanager.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace
|
||||
{
|
||||
const std::chrono::milliseconds FILTER_INPUT_DELAY {400};
|
||||
}
|
||||
|
||||
LineEdit::LineEdit(QWidget *parent)
|
||||
: QLineEdit(parent)
|
||||
, m_delayedTextChangedTimer {new QTimer(this)}
|
||||
{
|
||||
auto *action = new QAction(UIThemeManager::instance()->getIcon(u"edit-find"_s), QString(), this);
|
||||
addAction(action, QLineEdit::LeadingPosition);
|
||||
|
||||
setClearButtonEnabled(true);
|
||||
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)
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
|
||||
#include <QLineEdit>
|
||||
|
||||
class QKeyEvent;
|
||||
class QTimer;
|
||||
|
||||
class LineEdit final : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -39,6 +42,11 @@ class LineEdit final : public QLineEdit
|
|||
public:
|
||||
explicit LineEdit(QWidget *parent = nullptr);
|
||||
|
||||
signals:
|
||||
void textChanged(const QString &text);
|
||||
|
||||
private:
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
|
||||
QTimer *m_delayedTextChangedTimer = nullptr;
|
||||
};
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include <QShortcut>
|
||||
#include <QSplitter>
|
||||
#include <QStatusBar>
|
||||
#include <QString>
|
||||
#include <QtGlobal>
|
||||
#include <QTimer>
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ class QCloseEvent;
|
|||
class QComboBox;
|
||||
class QFileSystemWatcher;
|
||||
class QSplitter;
|
||||
class QString;
|
||||
class QTabWidget;
|
||||
class QTimer;
|
||||
|
||||
|
|
|
@ -128,9 +128,9 @@ SearchJobWidget::SearchJobWidget(SearchHandler *searchHandler, QWidget *parent)
|
|||
m_lineEditSearchResultsFilter->setPlaceholderText(tr("Filter search results..."));
|
||||
m_lineEditSearchResultsFilter->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(m_lineEditSearchResultsFilter, &QWidget::customContextMenuRequested, this, &SearchJobWidget::showFilterContextMenu);
|
||||
connect(m_lineEditSearchResultsFilter, &LineEdit::textChanged, this, &SearchJobWidget::filterSearchResults);
|
||||
m_ui->horizontalLayout->insertWidget(0, m_lineEditSearchResultsFilter);
|
||||
|
||||
connect(m_lineEditSearchResultsFilter, &LineEdit::textChanged, this, &SearchJobWidget::filterSearchResults);
|
||||
connect(m_ui->filterMode, qOverload<int>(&QComboBox::currentIndexChanged)
|
||||
, this, &SearchJobWidget::updateFilter);
|
||||
connect(m_ui->minSeeds, &QAbstractSpinBox::editingFinished, this, &SearchJobWidget::updateFilter);
|
||||
|
|
|
@ -658,6 +658,8 @@ window.addEvent('load', function() {
|
|||
$('error_div').set('html', '');
|
||||
if (response) {
|
||||
clearTimeout(torrentsFilterInputTimer);
|
||||
torrentsFilterInputTimer = -1;
|
||||
|
||||
let torrentsTableSelectedRows;
|
||||
let update_categories = false;
|
||||
let updateTags = false;
|
||||
|
@ -1357,18 +1359,14 @@ window.addEvent('load', function() {
|
|||
$('torrentFilesFilterToolbar').addClass("invisible");
|
||||
};
|
||||
|
||||
let prevTorrentsFilterValue;
|
||||
let torrentsFilterInputTimer = null;
|
||||
// listen for changes to torrentsFilterInput
|
||||
$('torrentsFilterInput').addEvent('input', function() {
|
||||
const value = $('torrentsFilterInput').get("value");
|
||||
if (value !== prevTorrentsFilterValue) {
|
||||
prevTorrentsFilterValue = value;
|
||||
clearTimeout(torrentsFilterInputTimer);
|
||||
torrentsFilterInputTimer = setTimeout(function() {
|
||||
torrentsTable.updateTable(false);
|
||||
}, 400);
|
||||
}
|
||||
let torrentsFilterInputTimer = -1;
|
||||
$('torrentsFilterInput').addEvent('input', () => {
|
||||
clearTimeout(torrentsFilterInputTimer);
|
||||
torrentsFilterInputTimer = setTimeout(() => {
|
||||
torrentsFilterInputTimer = -1;
|
||||
torrentsTable.updateTable();
|
||||
}, window.qBittorrent.Misc.FILTER_INPUT_DELAY);
|
||||
});
|
||||
|
||||
$('transfersTabLink').addEvent('click', showTransfersTab);
|
||||
|
|
|
@ -175,12 +175,14 @@ window.qBittorrent.ContextMenu = (function() {
|
|||
|
||||
const touchstartEvent = e;
|
||||
this.touchstartTimer = setTimeout(function() {
|
||||
this.touchstartTimer = -1;
|
||||
this.triggerMenu(touchstartEvent, elem);
|
||||
}.bind(this), this.options.touchTimer);
|
||||
}.bind(this));
|
||||
elem.addEvent('touchend', function(e) {
|
||||
e.preventDefault();
|
||||
clearTimeout(this.touchstartTimer);
|
||||
this.touchstartTimer = -1;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
|
|
|
@ -701,10 +701,7 @@ window.qBittorrent.DynamicTable = (function() {
|
|||
return null;
|
||||
},
|
||||
|
||||
updateTable: function(fullUpdate) {
|
||||
if (fullUpdate === undefined)
|
||||
fullUpdate = false;
|
||||
|
||||
updateTable: function(fullUpdate = false) {
|
||||
const rows = this.getFilteredAndSortedRows();
|
||||
|
||||
for (let i = 0; i < this.selectedRows.length; ++i)
|
||||
|
|
|
@ -46,6 +46,8 @@ window.qBittorrent.Misc = (function() {
|
|||
toFixedPointString: toFixedPointString,
|
||||
containsAllTerms: containsAllTerms,
|
||||
sleep: sleep,
|
||||
// variables
|
||||
FILTER_INPUT_DELAY: 400,
|
||||
MAX_ETA: 8640000
|
||||
};
|
||||
};
|
||||
|
|
|
@ -366,6 +366,7 @@ window.qBittorrent.PropFiles = (function() {
|
|||
},
|
||||
onSuccess: function(files) {
|
||||
clearTimeout(torrentFilesFilterInputTimer);
|
||||
torrentFilesFilterInputTimer = -1;
|
||||
|
||||
if (files.length === 0) {
|
||||
torrentFilesTable.clear();
|
||||
|
@ -640,26 +641,27 @@ window.qBittorrent.PropFiles = (function() {
|
|||
if (torrentFilesTable.getSortedColumn() === null)
|
||||
torrentFilesTable.setSortedColumn('name');
|
||||
|
||||
let prevTorrentFilesFilterValue;
|
||||
let torrentFilesFilterInputTimer = null;
|
||||
// listen for changes to torrentFilesFilterInput
|
||||
$('torrentFilesFilterInput').addEvent('input', function() {
|
||||
const value = $('torrentFilesFilterInput').get("value");
|
||||
if (value !== prevTorrentFilesFilterValue) {
|
||||
prevTorrentFilesFilterValue = value;
|
||||
torrentFilesTable.setFilter(value);
|
||||
clearTimeout(torrentFilesFilterInputTimer);
|
||||
torrentFilesFilterInputTimer = setTimeout(function() {
|
||||
if (current_hash === "")
|
||||
return;
|
||||
torrentFilesTable.updateTable(false);
|
||||
let torrentFilesFilterInputTimer = -1;
|
||||
$('torrentFilesFilterInput').addEvent('input', () => {
|
||||
clearTimeout(torrentFilesFilterInputTimer);
|
||||
|
||||
if (value.trim() === "")
|
||||
collapseAllNodes();
|
||||
else
|
||||
expandAllNodes();
|
||||
}, 400);
|
||||
}
|
||||
const value = $('torrentFilesFilterInput').get("value");
|
||||
torrentFilesTable.setFilter(value);
|
||||
|
||||
torrentFilesFilterInputTimer = setTimeout(() => {
|
||||
torrentFilesFilterInputTimer = -1;
|
||||
|
||||
if (current_hash === "")
|
||||
return;
|
||||
|
||||
torrentFilesTable.updateTable();
|
||||
|
||||
if (value.trim() === "")
|
||||
collapseAllNodes();
|
||||
else
|
||||
expandAllNodes();
|
||||
}, window.qBittorrent.Misc.FILTER_INPUT_DELAY);
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
@ -183,7 +183,7 @@
|
|||
};
|
||||
|
||||
let customSyncLogDataInterval = null;
|
||||
let logFilterTimer;
|
||||
let logFilterTimer = -1;
|
||||
let inputtedFilterText = "";
|
||||
let selectBox;
|
||||
let selectedLogLevels = JSON.parse(LocalPreferences.get('qbt_selected_log_levels')) || ['1', '2', '4', '8'];
|
||||
|
@ -297,9 +297,11 @@
|
|||
const logFilterChanged = () => {
|
||||
clearTimeout(logFilterTimer);
|
||||
logFilterTimer = setTimeout((curTab) => {
|
||||
logFilterTimer = -1;
|
||||
|
||||
tableInfo[curTab].instance.updateTable(false);
|
||||
updateLabelCount(curTab);
|
||||
}, 400, currentSelectedTab);
|
||||
}, window.qBittorrent.Misc.FILTER_INPUT_DELAY, currentSelectedTab);
|
||||
};
|
||||
|
||||
const setCurrentTab = (tab) => {
|
||||
|
@ -321,6 +323,7 @@
|
|||
}
|
||||
|
||||
clearTimeout(logFilterTimer);
|
||||
logFilterTimer = -1;
|
||||
load();
|
||||
|
||||
if (tableInfo[currentSelectedTab].instance.filterText !== getFilterText()) {
|
||||
|
@ -377,6 +380,8 @@
|
|||
|
||||
if (response.length > 0) {
|
||||
clearTimeout(logFilterTimer);
|
||||
logFilterTimer = -1;
|
||||
|
||||
for (let i = 0; i < response.length; ++i) {
|
||||
let row;
|
||||
if (curTab === 'main') {
|
||||
|
|
|
@ -233,7 +233,6 @@
|
|||
max: 0.00,
|
||||
maxUnit: 3
|
||||
};
|
||||
let prevNameFilterValue;
|
||||
let selectedCategory = "QBT_TR(All categories)QBT_TR[CONTEXT=SearchEngineWidget]";
|
||||
let selectedPlugin = "all";
|
||||
let prevSelectedPlugin;
|
||||
|
@ -258,18 +257,17 @@
|
|||
searchResultsTable.setup('searchResultsTableDiv', 'searchResultsTableFixedHeaderDiv', searchResultsTableContextMenu);
|
||||
getPlugins();
|
||||
|
||||
let searchInNameFilterTimer = null;
|
||||
// listen for changes to searchInNameFilter
|
||||
$('searchInNameFilter').addEvent('input', function() {
|
||||
const value = $('searchInNameFilter').get("value");
|
||||
if (value !== prevNameFilterValue) {
|
||||
prevNameFilterValue = value;
|
||||
clearTimeout(searchInNameFilterTimer);
|
||||
searchInNameFilterTimer = setTimeout(function() {
|
||||
searchText.filterPattern = value;
|
||||
searchFilterChanged();
|
||||
}, 400);
|
||||
}
|
||||
let searchInNameFilterTimer = -1;
|
||||
$('searchInNameFilter').addEvent('input', () => {
|
||||
clearTimeout(searchInNameFilterTimer);
|
||||
searchInNameFilterTimer = setTimeout(() => {
|
||||
searchInNameFilterTimer = -1;
|
||||
|
||||
const value = $('searchInNameFilter').get("value");
|
||||
searchText.filterPattern = value;
|
||||
searchFilterChanged();
|
||||
}, window.qBittorrent.Misc.FILTER_INPUT_DELAY);
|
||||
});
|
||||
|
||||
new Keyboard({
|
||||
|
|
Loading…
Reference in a new issue