mirror of
https://github.com/sqlitebrowser/sqlitebrowser.git
synced 2026-01-19 18:40:13 -06:00
Delay applying a changed filter value
When changing a filter value delay the application of the new value on the table for a couple of milliseconds. This makes the filter process much smoother for fast typing users working on large tables. See issue #415.
This commit is contained in:
@@ -88,6 +88,7 @@ set(SQLB_MOC_HDR
|
||||
src/SqlUiLexer.h
|
||||
src/FileDialog.h
|
||||
src/ColumnDisplayFormatDialog.h
|
||||
src/FilterLineEdit.h
|
||||
)
|
||||
|
||||
set(SQLB_SRC
|
||||
@@ -118,6 +119,7 @@ set(SQLB_SRC
|
||||
src/SqlUiLexer.cpp
|
||||
src/FileDialog.cpp
|
||||
src/ColumnDisplayFormatDialog.cpp
|
||||
src/FilterLineEdit.cpp
|
||||
)
|
||||
|
||||
set(SQLB_FORMS
|
||||
|
||||
70
src/FilterLineEdit.cpp
Normal file
70
src/FilterLineEdit.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#include "FilterLineEdit.h"
|
||||
|
||||
#include <QTimer>
|
||||
#include <QKeyEvent>
|
||||
|
||||
FilterLineEdit::FilterLineEdit(QWidget* parent, QList<FilterLineEdit*>* filters, int columnnum) : QLineEdit(parent), filterList(filters), columnNumber(columnnum)
|
||||
{
|
||||
setPlaceholderText(tr("Filter"));
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
|
||||
setClearButtonEnabled(true);
|
||||
#endif
|
||||
setProperty("column", columnnum); // Store the column number for later use
|
||||
|
||||
// Introduce a timer for delaying the signal triggered whenever the user changes the filter value.
|
||||
// The idea here is that the textChanged() event isn't connected to the update filter slot directly anymore
|
||||
// but instead there this timer mechanism in between: whenever the user changes the filter the delay timer
|
||||
// is (re)started. As soon as the user stops typing the timer has a chance to trigger and call the
|
||||
// delayedSignalTimerTriggered() method which then stops the timer and emits the delayed signal.
|
||||
delaySignalTimer = new QTimer(this);
|
||||
delaySignalTimer->setInterval(300); // This is the milliseconds of not-typing we want to wait before triggering
|
||||
connect(this, SIGNAL(textChanged(QString)), delaySignalTimer, SLOT(start()));
|
||||
connect(delaySignalTimer, SIGNAL(timeout()), this, SLOT(delayedSignalTimerTriggered()));
|
||||
|
||||
// Immediately emit the delayed filter value changed signal if the user presses the enter or the return key or
|
||||
// the line edit widget loses focus
|
||||
connect(this, SIGNAL(editingFinished()), this, SLOT(delayedSignalTimerTriggered()));
|
||||
}
|
||||
|
||||
void FilterLineEdit::delayedSignalTimerTriggered()
|
||||
{
|
||||
// Stop the timer first to avoid triggering in intervals
|
||||
delaySignalTimer->stop();
|
||||
|
||||
// Emit the delayed signal using the current value
|
||||
emit delayedTextChanged(text());
|
||||
}
|
||||
|
||||
void FilterLineEdit::keyReleaseEvent(QKeyEvent* event)
|
||||
{
|
||||
if(event->key() == Qt::Key_Tab)
|
||||
{
|
||||
if(columnNumber < filterList->size() - 1)
|
||||
{
|
||||
filterList->at(columnNumber + 1)->setFocus();
|
||||
event->accept();
|
||||
}
|
||||
} else if(event->key() == Qt::Key_Backtab) {
|
||||
if(columnNumber > 0)
|
||||
{
|
||||
filterList->at(columnNumber - 1)->setFocus();
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FilterLineEdit::clear()
|
||||
{
|
||||
// When programatically clearing the line edit's value make sure the effects are applied immediately, i.e.
|
||||
// bypass the delayed signal timer
|
||||
QLineEdit::clear();
|
||||
delayedSignalTimerTriggered();
|
||||
}
|
||||
|
||||
void FilterLineEdit::setText(const QString& text)
|
||||
{
|
||||
// When programatically setting the line edit's value make sure the effects are applied immediately, i.e.
|
||||
// bypass the delayed signal timer
|
||||
QLineEdit::setText(text);
|
||||
delayedSignalTimerTriggered();
|
||||
}
|
||||
36
src/FilterLineEdit.h
Normal file
36
src/FilterLineEdit.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef FILTERLINEEDIT_H
|
||||
#define FILTERLINEEDIT_H
|
||||
|
||||
#include <QLineEdit>
|
||||
#include <QList>
|
||||
|
||||
class QTimer;
|
||||
class QKeyEvent;
|
||||
|
||||
class FilterLineEdit : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FilterLineEdit(QWidget* parent, QList<FilterLineEdit*>* filters, int columnnum);
|
||||
|
||||
// Override methods for programatically changing the value of the line edit
|
||||
void clear();
|
||||
void setText(const QString& text);
|
||||
|
||||
private slots:
|
||||
void delayedSignalTimerTriggered();
|
||||
|
||||
signals:
|
||||
void delayedTextChanged(QString text);
|
||||
|
||||
protected:
|
||||
void keyReleaseEvent(QKeyEvent* event);
|
||||
|
||||
private:
|
||||
QList<FilterLineEdit*>* filterList;
|
||||
int columnNumber;
|
||||
QTimer* delaySignalTimer;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,46 +1,8 @@
|
||||
#include "FilterTableHeader.h"
|
||||
#include "FilterLineEdit.h"
|
||||
|
||||
#include <QLineEdit>
|
||||
#include <QTableView>
|
||||
#include <QScrollBar>
|
||||
#include <QKeyEvent>
|
||||
#include <QDebug>
|
||||
|
||||
class FilterLineEdit : public QLineEdit
|
||||
{
|
||||
public:
|
||||
explicit FilterLineEdit(QWidget* parent, QList<FilterLineEdit*>* filters, int columnnum) : QLineEdit(parent), filterList(filters), columnNumber(columnnum)
|
||||
{
|
||||
setPlaceholderText(tr("Filter"));
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
|
||||
setClearButtonEnabled(true);
|
||||
#endif
|
||||
setProperty("column", columnnum); // Store the column number for later use
|
||||
}
|
||||
|
||||
protected:
|
||||
void keyReleaseEvent(QKeyEvent* event)
|
||||
{
|
||||
if(event->key() == Qt::Key_Tab)
|
||||
{
|
||||
if(columnNumber < filterList->size() - 1)
|
||||
{
|
||||
filterList->at(columnNumber + 1)->setFocus();
|
||||
event->accept();
|
||||
}
|
||||
} else if(event->key() == Qt::Key_Backtab) {
|
||||
if(columnNumber > 0)
|
||||
{
|
||||
filterList->at(columnNumber - 1)->setFocus();
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QList<FilterLineEdit*>* filterList;
|
||||
int columnNumber;
|
||||
};
|
||||
|
||||
FilterTableHeader::FilterTableHeader(QTableView* parent) :
|
||||
QHeaderView(Qt::Horizontal, parent)
|
||||
@@ -78,7 +40,7 @@ void FilterTableHeader::generateFilters(int number, bool showFirst)
|
||||
l->setVisible(false);
|
||||
else
|
||||
l->setVisible(true);
|
||||
connect(l, SIGNAL(textChanged(QString)), this, SLOT(inputChanged(QString)));
|
||||
connect(l, SIGNAL(delayedTextChanged(QString)), this, SLOT(inputChanged(QString)));
|
||||
filterWidgets.push_back(l);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,8 @@ HEADERS += \
|
||||
ExportSqlDialog.h \
|
||||
SqlUiLexer.h \
|
||||
FileDialog.h \
|
||||
ColumnDisplayFormatDialog.h
|
||||
ColumnDisplayFormatDialog.h \
|
||||
FilterLineEdit.h
|
||||
|
||||
SOURCES += \
|
||||
sqlitedb.cpp \
|
||||
@@ -80,7 +81,8 @@ SOURCES += \
|
||||
ExportSqlDialog.cpp \
|
||||
SqlUiLexer.cpp \
|
||||
FileDialog.cpp \
|
||||
ColumnDisplayFormatDialog.cpp
|
||||
ColumnDisplayFormatDialog.cpp \
|
||||
FilterLineEdit.cpp
|
||||
|
||||
RESOURCES += icons/icons.qrc \
|
||||
translations/flags/flags.qrc \
|
||||
|
||||
Reference in New Issue
Block a user