mirror of
https://github.com/sqlitebrowser/sqlitebrowser.git
synced 2026-01-20 02:50:46 -06:00
See issue #408. This isn't working reliably yet on my system: If you enable the fix restoring the previous settings when going back to a table doesn't work and if you disable it that very way is the only way to change the option. Don't know what's going on there :(
140 lines
4.5 KiB
C++
140 lines
4.5 KiB
C++
#include "FilterTableHeader.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)
|
|
{
|
|
// Activate the click signals to allow sorting
|
|
#if QT_VERSION >= 0x050000
|
|
setSectionsClickable(true);
|
|
#else
|
|
setClickable(true);
|
|
#endif
|
|
|
|
setSortIndicatorShown(true);
|
|
|
|
// Do some connects: Basically just resize and reposition the input widgets whenever anything changes
|
|
connect(this, SIGNAL(sectionResized(int,int,int)), this, SLOT(adjustPositions()));
|
|
connect(parent->horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(adjustPositions()));
|
|
connect(parent->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(adjustPositions()));
|
|
|
|
// Set custom context menu handling
|
|
setContextMenuPolicy(Qt::CustomContextMenu);
|
|
}
|
|
|
|
void FilterTableHeader::generateFilters(int number, bool showFirst)
|
|
{
|
|
// Delete all the current filter widgets
|
|
for(int i=0;i < filterWidgets.size(); ++i)
|
|
delete filterWidgets.at(i);
|
|
filterWidgets.clear();
|
|
|
|
// And generate a bunch of new ones
|
|
for(int i=0;i < number; ++i)
|
|
{
|
|
FilterLineEdit* l = new FilterLineEdit(this, &filterWidgets, i);
|
|
if(!showFirst && i == 0) // This hides the first input widget which belongs to the hidden rowid column
|
|
l->setVisible(false);
|
|
else
|
|
l->setVisible(true);
|
|
connect(l, SIGNAL(textChanged(QString)), this, SLOT(inputChanged(QString)));
|
|
filterWidgets.push_back(l);
|
|
}
|
|
|
|
// Position them correctly
|
|
adjustPositions();
|
|
}
|
|
|
|
QSize FilterTableHeader::sizeHint() const
|
|
{
|
|
// For the size hint just take the value of the standard implementation and add the height of a input widget to it if necessary
|
|
QSize s = QHeaderView::sizeHint();
|
|
if(filterWidgets.size())
|
|
s.setHeight(s.height() + filterWidgets.at(0)->sizeHint().height() + 5); // The 5 adds just adds some extra space
|
|
return s;
|
|
}
|
|
|
|
void FilterTableHeader::updateGeometries()
|
|
{
|
|
// If there are any input widgets add a viewport margin to the header to generate some empty space for them which is not affected by scrolling
|
|
if(filterWidgets.size())
|
|
setViewportMargins(0, 0, 0, filterWidgets.at(0)->sizeHint().height());
|
|
else
|
|
setViewportMargins(0, 0, 0, 0);
|
|
|
|
// Now just call the parent implementation and reposition the input widgets
|
|
QHeaderView::updateGeometries();
|
|
adjustPositions();
|
|
}
|
|
|
|
void FilterTableHeader::adjustPositions()
|
|
{
|
|
// Loop through all widgets
|
|
for(int i=0;i < filterWidgets.size(); ++i)
|
|
{
|
|
// Get the current widget, move it and resize it
|
|
QWidget* w = filterWidgets.at(i);
|
|
w->move(sectionPosition(i) - offset(), filterWidgets.at(i)->sizeHint().height() + 2); // The two adds some extra space between the header label and the input widget
|
|
w->resize(sectionSize(i), filterWidgets.at(i)->sizeHint().height());
|
|
}
|
|
}
|
|
|
|
void FilterTableHeader::inputChanged(const QString& new_value)
|
|
{
|
|
// Just get the column number and the new value and send them to anybody interested in filter changes
|
|
emit filterChanged(sender()->property("column").toInt(), new_value);
|
|
}
|
|
|
|
void FilterTableHeader::clearFilters()
|
|
{
|
|
foreach (FilterLineEdit* filterLineEdit, filterWidgets)
|
|
filterLineEdit->clear();
|
|
}
|
|
|
|
void FilterTableHeader::setFilter(int column, const QString& value)
|
|
{
|
|
if(column < filterWidgets.size())
|
|
filterWidgets.at(column)->setText(value);
|
|
}
|