Implemented data filtering.
This commit is contained in:
@@ -9,14 +9,15 @@
|
|||||||
#include "define.h"
|
#include "define.h"
|
||||||
#include "core_global.h"
|
#include "core_global.h"
|
||||||
#include "exprevaluator.h"
|
#include "exprevaluator.h"
|
||||||
|
#include "itablemodel.h"
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
class AutoTableModel : public QAbstractTableModel
|
class AutoTableModel : public ITableModel
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AutoTableModel(QObject *parent = NULL)
|
explicit AutoTableModel(QObject *parent = NULL)
|
||||||
:QAbstractTableModel(parent)
|
:ITableModel(parent)
|
||||||
{
|
{
|
||||||
filtered = false;
|
filtered = false;
|
||||||
}
|
}
|
||||||
@@ -141,8 +142,8 @@ public:
|
|||||||
m_list = list;
|
m_list = list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public slots:
|
protected:
|
||||||
void filter(const QString &filter)
|
void handleFilter(const QString &filter) override
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
if (!filtered)
|
if (!filtered)
|
||||||
@@ -152,13 +153,13 @@ public slots:
|
|||||||
}
|
}
|
||||||
|
|
||||||
ExprEvaluator ev;
|
ExprEvaluator ev;
|
||||||
m_list.clear();
|
auto it = std::copy_if(ALL(m_fullList), m_list.begin(), [&filter, &ev](QSharedPointer<T> obj){ return ev.evaluate((QObject*)obj.data(), filter); });
|
||||||
std::copy_if(ALL(m_fullList), m_list.begin(), [&filter, &ev](QSharedPointer<T> obj){ return ev.evaluate((QObject*)obj.pointer, filter); });
|
m_list.erase(it, m_list.end());
|
||||||
|
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void restore()
|
void handleRestore() override
|
||||||
{
|
{
|
||||||
if (filtered)
|
if (filtered)
|
||||||
{
|
{
|
||||||
|
|||||||
+11
-3
@@ -38,7 +38,10 @@ SOURCES += \
|
|||||||
roles/rolesform.cpp \
|
roles/rolesform.cpp \
|
||||||
permissionservice.cpp \
|
permissionservice.cpp \
|
||||||
filterui.cpp \
|
filterui.cpp \
|
||||||
exprevaluator.cpp
|
exprevaluator.cpp \
|
||||||
|
savefilterdialog.cpp \
|
||||||
|
filterdialog.cpp \
|
||||||
|
itablemodel.cpp
|
||||||
|
|
||||||
HEADERS += core.h\
|
HEADERS += core.h\
|
||||||
core_global.h \
|
core_global.h \
|
||||||
@@ -73,7 +76,10 @@ HEADERS += core.h\
|
|||||||
roles/rolesform.h \
|
roles/rolesform.h \
|
||||||
permissionservice.h \
|
permissionservice.h \
|
||||||
filterui.h \
|
filterui.h \
|
||||||
exprevaluator.h
|
exprevaluator.h \
|
||||||
|
savefilterdialog.h \
|
||||||
|
filterdialog.h \
|
||||||
|
itablemodel.h
|
||||||
|
|
||||||
unix {
|
unix {
|
||||||
target.path = /usr/lib
|
target.path = /usr/lib
|
||||||
@@ -103,7 +109,9 @@ FORMS += \
|
|||||||
users/userform.ui \
|
users/userform.ui \
|
||||||
columndialog.ui \
|
columndialog.ui \
|
||||||
roles/rolesform.ui \
|
roles/rolesform.ui \
|
||||||
filterui.ui
|
filterui.ui \
|
||||||
|
savefilterdialog.ui \
|
||||||
|
filterdialog.ui
|
||||||
|
|
||||||
OTHER_FILES += \
|
OTHER_FILES += \
|
||||||
users/metaData.json \
|
users/metaData.json \
|
||||||
|
|||||||
+53
-2
@@ -13,6 +13,7 @@ ExprEvaluator::ExprEvaluator()
|
|||||||
|
|
||||||
m_operations["||"] = [](QVariant left, QVariant right) { return left.toBool() || right.toBool(); };
|
m_operations["||"] = [](QVariant left, QVariant right) { return left.toBool() || right.toBool(); };
|
||||||
m_operations["&&"] = [](QVariant left, QVariant right) { return left.toBool() && right.toBool(); };
|
m_operations["&&"] = [](QVariant left, QVariant right) { return left.toBool() && right.toBool(); };
|
||||||
|
m_caseSensitive = false;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
const QMap<QString, std::function<bool(QVariant, QVariant)> > ExprEvaluator::m_operations = {
|
const QMap<QString, std::function<bool(QVariant, QVariant)> > ExprEvaluator::m_operations = {
|
||||||
@@ -30,12 +31,62 @@ const QMap<QString, std::function<bool(QVariant, QVariant)> > ExprEvaluator::m_o
|
|||||||
|
|
||||||
ExprEvaluator::ExprEvaluator()
|
ExprEvaluator::ExprEvaluator()
|
||||||
{
|
{
|
||||||
|
m_caseSensitive = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
bool ExprEvaluator::evaluate(const QObject *data, const QString &expression)
|
bool ExprEvaluator::evaluate(QObject *object, const QString &exp)
|
||||||
{
|
{
|
||||||
return true;
|
if (exp.contains("&&") && exp.contains("||"))
|
||||||
|
{
|
||||||
|
if (exp.indexOf("&&") < exp.indexOf("||"))
|
||||||
|
{
|
||||||
|
return subEval("&&", exp, object);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return subEval("||", exp, object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (exp.contains("&&"))
|
||||||
|
{
|
||||||
|
return subEval("&&", exp, object);
|
||||||
|
}
|
||||||
|
else if (exp.contains("||"))
|
||||||
|
{
|
||||||
|
return subEval("||", exp, object);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QVariant value;
|
||||||
|
QString oper;
|
||||||
|
QVariant cond;
|
||||||
|
parseExpr(exp, value, oper, cond, object);
|
||||||
|
return m_operations[oper](value, cond);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExprEvaluator::setCaseSensitive(bool caseSensitive)
|
||||||
|
{
|
||||||
|
m_caseSensitive = caseSensitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExprEvaluator::subEval(const QString &oper, const QString &expresion, QObject *object)
|
||||||
|
{
|
||||||
|
QString ex = expresion.left(expresion.indexOf(oper));
|
||||||
|
QVariant value;
|
||||||
|
QString o;
|
||||||
|
QVariant cond;
|
||||||
|
parseExpr(ex, value, o, cond, object);
|
||||||
|
return m_operations[oper](m_operations[o](value, cond), evaluate(object, expresion.mid(expresion.indexOf(oper) + 2).trimmed()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExprEvaluator::parseExpr(const QString &exp, QVariant &value, QString &oper, QVariant &condition, QObject *object)
|
||||||
|
{
|
||||||
|
QStringList expCat = exp.trimmed().split(" ");
|
||||||
|
value = object->property(expCat[0].toStdString().c_str());
|
||||||
|
oper = expCat[1];
|
||||||
|
condition = expCat[2].replace("%20", " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ class ExprEvaluator
|
|||||||
public:
|
public:
|
||||||
ExprEvaluator();
|
ExprEvaluator();
|
||||||
|
|
||||||
bool evaluate(const QObject *data, const QString &expression);
|
bool evaluate(QObject *object, const QString &exp);
|
||||||
|
void setCaseSensitive(bool caseSensitive);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@@ -21,6 +22,9 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool m_caseSensitive;
|
bool m_caseSensitive;
|
||||||
|
|
||||||
|
bool subEval(const QString &oper, const QString &expresion, QObject *object);
|
||||||
|
void parseExpr(const QString &exp, QVariant &value, QString &oper, QVariant &condition, QObject *object);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EXPREVALUATOR_H
|
#endif // EXPREVALUATOR_H
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
#include "filterdialog.h"
|
||||||
|
#include "ui_filterdialog.h"
|
||||||
|
|
||||||
|
#include <QMap>
|
||||||
|
#include <QTableWidgetItem>
|
||||||
|
#include <QToolButton>
|
||||||
|
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
|
FilterDialog::FilterDialog(QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::FilterDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
FilterDialog::~FilterDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FilterDialog::pluginId() const
|
||||||
|
{
|
||||||
|
return m_pluginId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterDialog::setPluginId(const QString &pluginId)
|
||||||
|
{
|
||||||
|
m_pluginId = pluginId;
|
||||||
|
fillTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
QTableWidget *FilterDialog::table()
|
||||||
|
{
|
||||||
|
return ui->tableWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterDialog::fillTable()
|
||||||
|
{
|
||||||
|
ui->tableWidget->clear();
|
||||||
|
QMap<QString, QVariant> filters = Context::instance().settings()->value("filters/" + pluginId()).toMap();
|
||||||
|
|
||||||
|
int row = 0;
|
||||||
|
ui->tableWidget->setRowCount(filters.keys().size());
|
||||||
|
foreach (QString name, filters.keys()) {
|
||||||
|
QTableWidgetItem *itemName = new QTableWidgetItem(name);
|
||||||
|
ui->tableWidget->setItem(row, 0, itemName);
|
||||||
|
QTableWidgetItem *itemFilter = new QTableWidgetItem(filters[name].toString());
|
||||||
|
ui->tableWidget->setItem(row, 1, itemFilter);
|
||||||
|
|
||||||
|
QToolButton *btnRemove = new QToolButton();
|
||||||
|
btnRemove->setText("Remove");
|
||||||
|
ui->tableWidget->setCellWidget(row, 2, btnRemove);
|
||||||
|
connect(btnRemove, &QToolButton::clicked, [this, btnRemove](){
|
||||||
|
int rowToDel = ui->tableWidget->rowAt(btnRemove->y());
|
||||||
|
ui->tableWidget->removeRow(rowToDel);
|
||||||
|
});
|
||||||
|
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->tableWidget->setColumnWidth(1, 200);
|
||||||
|
ui->tableWidget->setHorizontalHeaderLabels(QStringList() << tr("Name") << tr("Filter") << "");
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef FILTERDIALOG_H
|
||||||
|
#define FILTERDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QString>
|
||||||
|
#include <QTableWidget>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class FilterDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class FilterDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FilterDialog(QWidget *parent = 0);
|
||||||
|
~FilterDialog();
|
||||||
|
|
||||||
|
QString pluginId() const;
|
||||||
|
void setPluginId(const QString &pluginId);
|
||||||
|
QTableWidget *table();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::FilterDialog *ui;
|
||||||
|
QString m_pluginId;
|
||||||
|
|
||||||
|
void fillTable();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FILTERDIALOG_H
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>FilterDialog</class>
|
||||||
|
<widget class="QDialog" name="FilterDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>556</width>
|
||||||
|
<height>370</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Manage filters</string>
|
||||||
|
</property>
|
||||||
|
<property name="modal">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTableWidget" name="tableWidget">
|
||||||
|
<property name="gridStyle">
|
||||||
|
<enum>Qt::SolidLine</enum>
|
||||||
|
</property>
|
||||||
|
<property name="columnCount">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<column/>
|
||||||
|
<column/>
|
||||||
|
<column/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>FilterDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>FilterDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
||||||
+165
-1
@@ -10,6 +10,13 @@
|
|||||||
#include <QDateTimeEdit>
|
#include <QDateTimeEdit>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
|
#include <QList>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
|
#include "savefilterdialog.h"
|
||||||
|
#include "filterdialog.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
FilterUi::FilterUi(QWidget *parent, QObject *entity) :
|
FilterUi::FilterUi(QWidget *parent, QObject *entity) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
@@ -17,6 +24,7 @@ FilterUi::FilterUi(QWidget *parent, QObject *entity) :
|
|||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
m_entity = entity;
|
m_entity = entity;
|
||||||
|
m_buildGrid = true;
|
||||||
|
|
||||||
if (entity == NULL)
|
if (entity == NULL)
|
||||||
{
|
{
|
||||||
@@ -100,6 +108,17 @@ void FilterUi::addRow(bool isOr)
|
|||||||
propertyChanged(row, oper, 0);
|
propertyChanged(row, oper, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString FilterUi::pluginId() const
|
||||||
|
{
|
||||||
|
return m_pluginId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterUi::setPluginId(const QString &pluginId)
|
||||||
|
{
|
||||||
|
m_pluginId = pluginId;
|
||||||
|
fillCombo();
|
||||||
|
}
|
||||||
|
|
||||||
QString FilterUi::buildExpression() const
|
QString FilterUi::buildExpression() const
|
||||||
{
|
{
|
||||||
QString expr;
|
QString expr;
|
||||||
@@ -122,7 +141,7 @@ QString FilterUi::buildExpression() const
|
|||||||
|
|
||||||
if (cellWidget != NULL)
|
if (cellWidget != NULL)
|
||||||
{
|
{
|
||||||
expr += " " + cellWidget->property(cellWidget->metaObject()->userProperty().name()).toString();
|
expr += " " + cellWidget->property(cellWidget->metaObject()->userProperty().name()).toString().replace(" ", "%20");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,3 +225,148 @@ void FilterUi::propertyChanged(int row, QComboBox *oper, int index)
|
|||||||
ui->tableWidget->setCellWidget(row, 3, cellWidget);
|
ui->tableWidget->setCellWidget(row, 3, cellWidget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FilterUi::fillCombo()
|
||||||
|
{
|
||||||
|
m_buildGrid = false;
|
||||||
|
ui->comboLoad->clear();
|
||||||
|
QMap<QString, QVariant> filter = Context::instance().settings()->value("filters/" + pluginId()).toMap();
|
||||||
|
|
||||||
|
ui->comboLoad->addItem("<<empty>>", "--");
|
||||||
|
foreach (QString key, filter.keys()) {
|
||||||
|
ui->comboLoad->addItem(key, filter[key]);
|
||||||
|
}
|
||||||
|
m_buildGrid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterUi::buildGrid(const QString &expr)
|
||||||
|
{
|
||||||
|
if (!isVisible() || !m_buildGrid)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->tableWidget->clear();
|
||||||
|
for (int i = 0; i < ui->tableWidget->rowCount(); i++)
|
||||||
|
{
|
||||||
|
ui->tableWidget->removeRow(i);
|
||||||
|
}
|
||||||
|
ui->tableWidget->setRowCount(0);
|
||||||
|
QStringList expList = expr.split(" ");
|
||||||
|
bool newLine = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < expList.count(); i++)
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
addRow(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rowIndex = ui->tableWidget->rowCount() - 1;
|
||||||
|
|
||||||
|
if (newLine)
|
||||||
|
{
|
||||||
|
QComboBox *prop = qobject_cast<QComboBox*>(ui->tableWidget->cellWidget(rowIndex, 1));
|
||||||
|
if (prop == NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < m_entity->metaObject()->propertyCount(); j++)
|
||||||
|
{
|
||||||
|
if (expList[i] == m_entity->metaObject()->property(j).name())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prop->setCurrentIndex(j - 1);
|
||||||
|
newLine = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expList[i] == "==" || expList[i] == "!=" || expList[i] == "%" || expList[i] == "<" || expList[i] == "<=" || expList[i] == ">" || expList[i] == ">=")
|
||||||
|
{
|
||||||
|
QComboBox *oper = qobject_cast<QComboBox*>(ui->tableWidget->cellWidget(rowIndex, 2));
|
||||||
|
for (int j = 0; j < oper->count(); j++)
|
||||||
|
{
|
||||||
|
oper->setCurrentIndex(j);
|
||||||
|
if (oper->itemText(j) == expList[i])
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expList[i] == "&&")
|
||||||
|
{
|
||||||
|
addRow(false);
|
||||||
|
newLine = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expList[i] == "||")
|
||||||
|
{
|
||||||
|
addRow(true);
|
||||||
|
newLine = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *cellWidget = ui->tableWidget->cellWidget(rowIndex, 3);
|
||||||
|
|
||||||
|
if (cellWidget != NULL)
|
||||||
|
{
|
||||||
|
cellWidget->setProperty(cellWidget->metaObject()->userProperty().name(), expList[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterUi::on_btnSave_clicked()
|
||||||
|
{
|
||||||
|
SaveFilterDialog *dlg = new SaveFilterDialog(this);
|
||||||
|
dlg->open();
|
||||||
|
connect(dlg, &SaveFilterDialog::accepted, [this, dlg]() {
|
||||||
|
QMap<QString, QVariant> filter = Context::instance().settings()->value("filters/" + pluginId()).toMap();
|
||||||
|
filter[dlg->filterName()] = buildExpression();
|
||||||
|
Context::instance().settings()->setValue("filters/" + pluginId(), QVariant::fromValue(filter));
|
||||||
|
fillCombo();
|
||||||
|
dlg->deleteLater();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterUi::on_comboLoad_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
if (ui->comboLoad->itemData(index).toString() == "--")
|
||||||
|
{
|
||||||
|
ui->tableWidget->clear();
|
||||||
|
for (int i = 0; i < ui->tableWidget->rowCount(); i++)
|
||||||
|
{
|
||||||
|
ui->tableWidget->removeRow(i);
|
||||||
|
}
|
||||||
|
ui->tableWidget->setRowCount(0);
|
||||||
|
|
||||||
|
addRow(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buildGrid(ui->comboLoad->itemData(index).toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterUi::on_btnManage_clicked()
|
||||||
|
{
|
||||||
|
FilterDialog *filterDialog = new FilterDialog(this);
|
||||||
|
filterDialog->setPluginId(pluginId());
|
||||||
|
filterDialog->open();
|
||||||
|
|
||||||
|
connect(filterDialog, &FilterDialog::accepted, [this, filterDialog](){
|
||||||
|
QMap<QString, QVariant> filters;
|
||||||
|
for (int i = 0; i < filterDialog->table()->rowCount(); i++)
|
||||||
|
{
|
||||||
|
filters[filterDialog->table()->item(i, 0)->text()] = filterDialog->table()->item(i, 1)->text();
|
||||||
|
}
|
||||||
|
Context::instance().settings()->setValue("filters/" + pluginId(), QVariant::fromValue(filters));
|
||||||
|
fillCombo();
|
||||||
|
filterDialog->deleteLater();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ public:
|
|||||||
explicit FilterUi(QWidget *parent = 0, QObject *entity = NULL);
|
explicit FilterUi(QWidget *parent = 0, QObject *entity = NULL);
|
||||||
~FilterUi();
|
~FilterUi();
|
||||||
|
|
||||||
|
QString pluginId() const;
|
||||||
|
void setPluginId(const QString &pluginId);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_actionAdd_condition_AND_triggered();
|
void on_actionAdd_condition_AND_triggered();
|
||||||
void on_actionAdd_condition_OR_triggered();
|
void on_actionAdd_condition_OR_triggered();
|
||||||
@@ -26,6 +29,12 @@ private slots:
|
|||||||
void on_actionRemove_condition_triggered();
|
void on_actionRemove_condition_triggered();
|
||||||
void on_btnGo_toggled(bool checked);
|
void on_btnGo_toggled(bool checked);
|
||||||
|
|
||||||
|
void on_btnSave_clicked();
|
||||||
|
|
||||||
|
void on_comboLoad_currentIndexChanged(int index);
|
||||||
|
|
||||||
|
void on_btnManage_clicked();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void applyFilter(const QString &filter);
|
void applyFilter(const QString &filter);
|
||||||
void restoreData();
|
void restoreData();
|
||||||
@@ -35,9 +44,13 @@ private:
|
|||||||
void addRow(bool isOr);
|
void addRow(bool isOr);
|
||||||
QObject *m_entity;
|
QObject *m_entity;
|
||||||
QMenu *m_contextMenu;
|
QMenu *m_contextMenu;
|
||||||
|
QString m_pluginId;
|
||||||
|
bool m_buildGrid;
|
||||||
|
|
||||||
QString buildExpression() const;
|
QString buildExpression() const;
|
||||||
void propertyChanged(int row, QComboBox *oper, int index);
|
void propertyChanged(int row, QComboBox *oper, int index);
|
||||||
|
void fillCombo();
|
||||||
|
void buildGrid(const QString &expr);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FILTERUI_H
|
#endif // FILTERUI_H
|
||||||
|
|||||||
+81
-7
@@ -65,6 +65,35 @@
|
|||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="btnGo">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Apply</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTipDuration">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Go</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset>
|
||||||
|
<normaloff>:/icons/ok.svg</normaloff>:/icons/ok.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -73,22 +102,67 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="comboLoad"/>
|
<widget class="QComboBox" name="comboLoad">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>150</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="btnGo">
|
<widget class="QToolButton" name="btnSave">
|
||||||
<property name="text">
|
<property name="toolTip">
|
||||||
<string>Go</string>
|
<string>Save</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable">
|
<property name="toolTipDuration">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Save</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset>
|
||||||
|
<normaloff>:/icons/save.svg</normaloff>:/icons/save.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="btnSave">
|
<widget class="QToolButton" name="btnManage">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Manage</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTipDuration">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Save</string>
|
<string>Manage</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset>
|
||||||
|
<normaloff>:/icons/list.svg</normaloff>:/icons/list.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ public:
|
|||||||
Q_ASSERT(m_tableModel == NULL);
|
Q_ASSERT(m_tableModel == NULL);
|
||||||
|
|
||||||
m_tableModel = tableModel;
|
m_tableModel = tableModel;
|
||||||
|
connect(m_filterUi, SIGNAL(applyFilter(QString)), m_tableModel, SLOT(filter(QString)));
|
||||||
|
connect(m_filterUi, SIGNAL(restoreData()), m_tableModel, SLOT(restore()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFormHandler(IFormHandler *handler) {
|
void setFormHandler(IFormHandler *handler) {
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" ?><svg clip-rule="evenodd" fill-rule="evenodd" image-rendering="optimizeQuality" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg"><defs><style type="text/css"><![CDATA[
|
||||||
|
.str0 {stroke:#434242;stroke-width:10}
|
||||||
|
.fil2 {fill:#434242}
|
||||||
|
.fil1 {fill:#FFFFFF}
|
||||||
|
.fil0 {fill:url(#id0)}
|
||||||
|
]]></style><linearGradient gradientUnits="userSpaceOnUse" id="id0" x1="449.998" x2="50" y1="250" y2="250"><stop offset="0" stop-color="#008BFF"/><stop offset="1" stop-color="#0af"/></linearGradient></defs><g id="Layer_x0020_1"><rect class="fil0 str0" height="420" rx="20" ry="20" width="400" x="50" y="40"/><path class="fil1 str0" d="M80 105h340c6 0 10 5 10 10v315c0 5-4 10-10 10h-340c-6 0-10-4-10-10v-315c0-5 4-10 10-10z"/><rect class="fil2" height="30" width="30" x="100" y="140"/><rect class="fil2" height="30" width="239.999" x="160" y="140"/><rect class="fil2" height="30" width="30" x="100" y="220"/><rect class="fil2" height="30" width="239.999" x="160" y="220"/><rect class="fil2" height="30" width="30" x="100" y="300"/><rect class="fil2" height="30" width="239.999" x="160" y="300"/><rect class="fil2" height="30" width="30" x="100" y="380"/><rect class="fil2" height="30" width="239.999" x="160" y="380"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" ?><svg clip-rule="evenodd" fill-rule="evenodd" image-rendering="optimizeQuality" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg"><defs><style type="text/css"><![CDATA[
|
||||||
|
.str0 {stroke:#434242;stroke-width:10}
|
||||||
|
.fil0 {fill:url(#id0)}
|
||||||
|
]]></style><linearGradient gradientUnits="userSpaceOnUse" id="id0" x1="457.572" x2="42.428" y1="42.428" y2="457.572"><stop offset="0" stop-color="#008BFF"/><stop offset="1" stop-color="#0af"/></linearGradient></defs><path class="fil0 str0" d="M34 240l59-59c5-5 14-5 20 0l78 79c5 5 15 5 20 0l176-177c6-5 15-5 20 0l59 59c5 5 5 14 0 20l-255 255c-6 5-14 6-20 0l-157-157c-5-6-5-14 0-20z" id="Layer_x0020_1"/></svg>
|
||||||
|
After Width: | Height: | Size: 752 B |
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" ?><svg clip-rule="evenodd" fill-rule="evenodd" image-rendering="optimizeQuality" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient gradientUnits="userSpaceOnUse" id="a" x1="249.999" x2="249.999" y1="30.694" y2="470.692"><stop offset="0" stop-color="#008BFF"/><stop offset="1" stop-color="#0af"/></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="b" x1="284.421" x2="215.575" y1="130.457" y2="70.929"><stop offset="0" stop-color="#EBECEC"/><stop offset="1" stop-color="#FEFEFE"/></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="c" x1="249.997" x2="249.997" y1="448.641" y2="272.235"><stop offset="0" stop-color="#EBECEC"/><stop offset="1" stop-color="#FEFEFE"/></linearGradient></defs><g><path d="M55 31h365l50 50v365c0 13-11 25-25 25h-390c-14 0-25-12-25-25v-390c0-14 11-25 25-25z" fill="url(#a)" stroke="#434242" stroke-linejoin="round" stroke-width="10"/><path d="M110 31h280v125c0 8-7 15-15 15h-250c-8 0-15-7-15-15v-125z" fill="url(#b)" stroke="#434242" stroke-linejoin="round" stroke-width="10"/><rect fill="url(#c)" height="221" stroke="#434242" stroke-linejoin="round" stroke-width="10" width="320" x="90" y="250"/><path d="M290 29h70v102c0 2-2 5-5 5h-60c-3 0-5-3-5-5v-102z" fill="#434242"/><line fill="none" stroke="#434242" stroke-linecap="round" stroke-width="15" x1="370" x2="130" y1="295" y2="295"/><line fill="none" stroke="#434242" stroke-linecap="round" stroke-width="15" x1="370" x2="130" y1="335" y2="335"/><line fill="none" stroke="#434242" stroke-linecap="round" stroke-width="15" x1="370" x2="130" y1="375" y2="375"/><line fill="none" stroke="#434242" stroke-linecap="round" stroke-width="15" x1="370" x2="130" y1="415" y2="415"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -26,6 +26,11 @@ IGridForm::~IGridForm()
|
|||||||
void IGridForm::setPluginId(const QString &pluginId)
|
void IGridForm::setPluginId(const QString &pluginId)
|
||||||
{
|
{
|
||||||
m_pluginId = pluginId;
|
m_pluginId = pluginId;
|
||||||
|
|
||||||
|
if (m_filterUi != NULL)
|
||||||
|
{
|
||||||
|
m_filterUi->setPluginId(pluginId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString IGridForm::pluginId()
|
QString IGridForm::pluginId()
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#include "itablemodel.h"
|
||||||
|
|
||||||
|
ITableModel::ITableModel(QObject *parent)
|
||||||
|
:QAbstractTableModel(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ITableModel::filter(const QString &filter)
|
||||||
|
{
|
||||||
|
handleFilter(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ITableModel::restore()
|
||||||
|
{
|
||||||
|
handleRestore();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef ITABLEMODEL_H
|
||||||
|
#define ITABLEMODEL_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QAbstractTableModel>
|
||||||
|
|
||||||
|
class ITableModel : public QAbstractTableModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ITableModel(QObject *parent = NULL);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void handleFilter(const QString &filter) = 0;
|
||||||
|
virtual void handleRestore() = 0;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void filter(const QString &filter);
|
||||||
|
void restore();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ITABLEMODEL_H
|
||||||
@@ -9,5 +9,8 @@
|
|||||||
<file>icons/remove.svg</file>
|
<file>icons/remove.svg</file>
|
||||||
<file>icons/filter.svg</file>
|
<file>icons/filter.svg</file>
|
||||||
<file>icons/print.svg</file>
|
<file>icons/print.svg</file>
|
||||||
|
<file>icons/save.svg</file>
|
||||||
|
<file>icons/ok.svg</file>
|
||||||
|
<file>icons/list.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#include "savefilterdialog.h"
|
||||||
|
#include "ui_savefilterdialog.h"
|
||||||
|
|
||||||
|
SaveFilterDialog::SaveFilterDialog(QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::SaveFilterDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveFilterDialog::~SaveFilterDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SaveFilterDialog::filterName()
|
||||||
|
{
|
||||||
|
return ui->filterName->text();
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef SAVEFILTERDIALOG_H
|
||||||
|
#define SAVEFILTERDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class SaveFilterDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SaveFilterDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SaveFilterDialog(QWidget *parent = 0);
|
||||||
|
~SaveFilterDialog();
|
||||||
|
|
||||||
|
QString filterName();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::SaveFilterDialog *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SAVEFILTERDIALOG_H
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>SaveFilterDialog</class>
|
||||||
|
<widget class="QDialog" name="SaveFilterDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>395</width>
|
||||||
|
<height>158</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Filter name</string>
|
||||||
|
</property>
|
||||||
|
<property name="modal">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Filter name</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="filterName"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="2">
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>SaveFilterDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>SaveFilterDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
||||||
Reference in New Issue
Block a user