mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-12-27 18:28:18 +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 <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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
|
||||||
prevTorrentsFilterValue = value;
|
|
||||||
clearTimeout(torrentsFilterInputTimer);
|
clearTimeout(torrentsFilterInputTimer);
|
||||||
torrentsFilterInputTimer = setTimeout(function() {
|
torrentsFilterInputTimer = setTimeout(() => {
|
||||||
torrentsTable.updateTable(false);
|
torrentsFilterInputTimer = -1;
|
||||||
}, 400);
|
torrentsTable.updateTable();
|
||||||
}
|
}, window.qBittorrent.Misc.FILTER_INPUT_DELAY);
|
||||||
});
|
});
|
||||||
|
|
||||||
$('transfersTabLink').addEvent('click', showTransfersTab);
|
$('transfersTabLink').addEvent('click', showTransfersTab);
|
||||||
|
|
|
@ -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));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -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) {
|
|
||||||
prevTorrentFilesFilterValue = value;
|
|
||||||
torrentFilesTable.setFilter(value);
|
|
||||||
clearTimeout(torrentFilesFilterInputTimer);
|
clearTimeout(torrentFilesFilterInputTimer);
|
||||||
torrentFilesFilterInputTimer = setTimeout(function() {
|
|
||||||
|
const value = $('torrentFilesFilterInput').get("value");
|
||||||
|
torrentFilesTable.setFilter(value);
|
||||||
|
|
||||||
|
torrentFilesFilterInputTimer = setTimeout(() => {
|
||||||
|
torrentFilesFilterInputTimer = -1;
|
||||||
|
|
||||||
if (current_hash === "")
|
if (current_hash === "")
|
||||||
return;
|
return;
|
||||||
torrentFilesTable.updateTable(false);
|
|
||||||
|
torrentFilesTable.updateTable();
|
||||||
|
|
||||||
if (value.trim() === "")
|
if (value.trim() === "")
|
||||||
collapseAllNodes();
|
collapseAllNodes();
|
||||||
else
|
else
|
||||||
expandAllNodes();
|
expandAllNodes();
|
||||||
}, 400);
|
}, window.qBittorrent.Misc.FILTER_INPUT_DELAY);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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') {
|
||||||
|
|
|
@ -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) {
|
|
||||||
prevNameFilterValue = value;
|
|
||||||
clearTimeout(searchInNameFilterTimer);
|
clearTimeout(searchInNameFilterTimer);
|
||||||
searchInNameFilterTimer = setTimeout(function() {
|
searchInNameFilterTimer = setTimeout(() => {
|
||||||
|
searchInNameFilterTimer = -1;
|
||||||
|
|
||||||
|
const value = $('searchInNameFilter').get("value");
|
||||||
searchText.filterPattern = value;
|
searchText.filterPattern = value;
|
||||||
searchFilterChanged();
|
searchFilterChanged();
|
||||||
}, 400);
|
}, window.qBittorrent.Misc.FILTER_INPUT_DELAY);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
new Keyboard({
|
new Keyboard({
|
||||||
|
|
Loading…
Reference in a new issue