Initial commit of BudgetPro
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
#include "filtertableheader.h"
|
||||
#include "filtertableheader.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QTableView>
|
||||
#include <QScrollBar>
|
||||
|
||||
#include "utils/filterlineedit.h"
|
||||
|
||||
FilterTableHeader::FilterTableHeader(QTableView* parent) :
|
||||
QHeaderView(Qt::Horizontal, parent)
|
||||
{
|
||||
// Activate the click signals to allow sorting
|
||||
setSectionsClickable(true);
|
||||
|
||||
// But use our own indicators allowing multi-column sorting
|
||||
setSortIndicatorShown(false);
|
||||
|
||||
// Make sure to not automatically resize the columns according to the contents
|
||||
setSectionResizeMode(QHeaderView::Interactive);
|
||||
|
||||
// Highlight column headers of selected cells to emulate spreadsheet behaviour
|
||||
setHighlightSections(true);
|
||||
|
||||
// Do some connects: Basically just resize and reposition the input widgets whenever anything changes
|
||||
connect(this, &FilterTableHeader::sectionResized, this, &FilterTableHeader::adjustPositions);
|
||||
connect(this, &FilterTableHeader::sectionClicked, this, &FilterTableHeader::adjustPositions);
|
||||
connect(parent->horizontalScrollBar(), &QScrollBar::valueChanged, this, &FilterTableHeader::adjustPositions);
|
||||
connect(parent->verticalScrollBar(), &QScrollBar::valueChanged, this, &FilterTableHeader::adjustPositions);
|
||||
|
||||
// Set custom context menu handling
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
}
|
||||
|
||||
void FilterTableHeader::generateFilters(size_t number, size_t number_of_hidden_filters)
|
||||
{
|
||||
// Delete all the current filter widgets
|
||||
qDeleteAll(filterWidgets);
|
||||
filterWidgets.clear();
|
||||
|
||||
// And generate a bunch of new ones
|
||||
for(size_t i=0; i < number; ++i)
|
||||
{
|
||||
FilterLineEdit* l = new FilterLineEdit(this, &filterWidgets, i);
|
||||
l->setVisible(i >= number_of_hidden_filters);
|
||||
|
||||
// Set as focus proxy the first non-row-id visible filter-line.
|
||||
if(i!=0 && l->isVisible() && !focusProxy())
|
||||
setFocusProxy(l);
|
||||
|
||||
connect(l, &FilterLineEdit::delayedTextChanged, this, &FilterTableHeader::inputChanged);
|
||||
connect(l, &FilterLineEdit::filterFocused, this, [this](){emit filterFocused();});
|
||||
connect(l, &FilterLineEdit::addFilterAsCondFormat, this, &FilterTableHeader::addFilterAsCondFormat);
|
||||
connect(l, &FilterLineEdit::clearAllCondFormats, this, &FilterTableHeader::clearAllCondFormats);
|
||||
connect(l, &FilterLineEdit::editCondFormats, this, &FilterTableHeader::editCondFormats);
|
||||
filterWidgets.push_back(l);
|
||||
}
|
||||
|
||||
// Position them correctly
|
||||
updateGeometries();
|
||||
}
|
||||
|
||||
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() + 4); // The 4 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()
|
||||
{
|
||||
// The two adds some extra space between the header label and the input widget
|
||||
const int y = QHeaderView::sizeHint().height() + 2;
|
||||
// Loop through all widgets
|
||||
for(int i=0;i < static_cast<int>(filterWidgets.size()); ++i)
|
||||
{
|
||||
// Get the current widget, move it and resize it
|
||||
QWidget* w = filterWidgets.at(static_cast<size_t>(i));
|
||||
if (QApplication::layoutDirection() == Qt::RightToLeft)
|
||||
w->move(width() - (sectionPosition(i) + sectionSize(i) - offset()), y);
|
||||
else
|
||||
w->move(sectionPosition(i) - offset(), y);
|
||||
w->resize(sectionSize(i), w->sizeHint().height());
|
||||
}
|
||||
}
|
||||
|
||||
void FilterTableHeader::inputChanged(const QString& new_value)
|
||||
{
|
||||
adjustPositions();
|
||||
// Just get the column number and the new value and send them to anybody interested in filter changes
|
||||
emit filterChanged(sender()->property("column").toUInt(), new_value);
|
||||
}
|
||||
|
||||
void FilterTableHeader::addFilterAsCondFormat(const QString& filter)
|
||||
{
|
||||
// Just get the column number and the new value and send them to anybody interested in new conditional formatting
|
||||
emit addCondFormat(sender()->property("column").toUInt(), filter);
|
||||
}
|
||||
|
||||
void FilterTableHeader::clearAllCondFormats()
|
||||
{
|
||||
// Just get the column number and send it to anybody responsible or interested in clearing conditional formatting
|
||||
emit allCondFormatsCleared(sender()->property("column").toUInt());
|
||||
}
|
||||
|
||||
void FilterTableHeader::editCondFormats()
|
||||
{
|
||||
// Just get the column number and the new value and send them to anybody interested in editing conditional formatting
|
||||
emit condFormatsEdited(sender()->property("column").toUInt());
|
||||
}
|
||||
|
||||
void FilterTableHeader::clearFilters()
|
||||
{
|
||||
for(FilterLineEdit* filterLineEdit : filterWidgets)
|
||||
filterLineEdit->clear();
|
||||
}
|
||||
|
||||
void FilterTableHeader::setFilter(size_t column, const QString& value)
|
||||
{
|
||||
if(column < filterWidgets.size())
|
||||
filterWidgets.at(column)->setText(value);
|
||||
}
|
||||
|
||||
QString FilterTableHeader::filterValue(size_t column) const
|
||||
{
|
||||
return filterWidgets[column]->text();
|
||||
}
|
||||
|
||||
void FilterTableHeader::setFocusColumn(size_t column)
|
||||
{
|
||||
if(column < filterWidgets.size())
|
||||
filterWidgets.at(column)->setFocus();
|
||||
}
|
||||
Reference in New Issue
Block a user