Files
sqlitebrowser/src/FilterTableHeader.cpp
Martin Kleusberg 1ebecbbc9d Add option for showing the rowid column
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 :(
2015-09-11 13:30:24 +02:00

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);
}