forked from sqlitebrowser/sqlitebrowser
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFilterTableHeader.cpp
More file actions
131 lines (115 loc) · 4.35 KB
/
FilterTableHeader.cpp
File metadata and controls
131 lines (115 loc) · 4.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#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"));
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()));
}
void FilterTableHeader::generateFilters(int number, bool bKeepValues)
{
// Delete all the current filter widgets
QStringList oldvalues;
for(int i=0;i < filterWidgets.size(); ++i)
{
if(bKeepValues)
oldvalues << filterWidgets.at(i)->text();
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);
l->setVisible(i>0); // This hides the first input widget which belongs to the hidden rowid column
connect(l, SIGNAL(textChanged(QString)), this, SLOT(inputChanged(QString)));
if(bKeepValues && oldvalues.size() > i && !oldvalues[i].isEmpty()) // restore old values
l->setText(oldvalues[i]);
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 reisize 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();
}