##// END OF EJS Templates
Merge branch 'feature/DataSourceFilter' into develop
Alexandre Leroux -
r441:5cdac9f101d7 merge
parent child
Show More
@@ -0,0 +1,23
1 #ifndef SCIQLOP_DATASOURCETREEWIDGETHELPER_H
2 #define SCIQLOP_DATASOURCETREEWIDGETHELPER_H
3
4 #include <functional>
5
6 class DataSourceTreeWidgetItem;
7 class QTreeWidget;
8
9 class DataSourceTreeWidgetHelper {
10 public:
11 /// Signature of the function associated to the filtering action
12 using FilterFunction = std::function<bool(const DataSourceTreeWidgetItem &dataSourceItem)>;
13
14 /**
15 * Filters a tree widget according to a function. If an item is valid according to this
16 * function, all of its ancestors and children are shown
17 * @param treeWidget the widget to filter
18 * @param fun the filter function
19 */
20 static void filter(QTreeWidget &treeWidget, FilterFunction fun) noexcept;
21 };
22
23 #endif // SCIQLOP_DATASOURCETREEWIDGETHELPER_H
@@ -0,0 +1,36
1 #include "DataSource/DataSourceTreeWidgetHelper.h"
2 #include "DataSource/DataSourceTreeWidgetItem.h"
3
4 namespace {
5
6 bool filterTreeItem(DataSourceTreeWidgetItem &treeItem,
7 DataSourceTreeWidgetHelper::FilterFunction fun, bool parentValid = false)
8 {
9 auto selfValid = parentValid || fun(treeItem);
10
11 auto childValid = false;
12 auto childCount = treeItem.childCount();
13 for (auto i = 0; i < childCount; ++i) {
14 if (auto childItem = dynamic_cast<DataSourceTreeWidgetItem *>(treeItem.child(i))) {
15 childValid |= filterTreeItem(*childItem, fun, selfValid);
16 }
17 }
18
19 auto valid = selfValid || childValid;
20
21 treeItem.setHidden(!valid);
22
23 return valid;
24 }
25
26 } // namespace
27
28 void DataSourceTreeWidgetHelper::filter(QTreeWidget &treeWidget, FilterFunction fun) noexcept
29 {
30 auto itemCount = treeWidget.topLevelItemCount();
31 for (auto i = 0; i < itemCount; ++i) {
32 if (auto item = dynamic_cast<DataSourceTreeWidgetItem *>(treeWidget.topLevelItem(i))) {
33 filterTreeItem(*item, fun);
34 }
35 }
36 }
@@ -21,6 +21,8 public:
21 21 explicit DataSourceTreeWidgetItem(QTreeWidget *parent, const DataSourceItem *data,
22 22 int type = Type);
23 23
24 const DataSourceItem *data() const;
25
24 26 virtual QVariant data(int column, int role) const override;
25 27 virtual void setData(int column, int role, const QVariant &value) override;
26 28
@@ -32,6 +32,9 private:
32 32 Ui::DataSourceWidget *ui;
33 33
34 34 private slots:
35 /// Slot called when the filtering text has changed
36 void filterChanged(const QString &text) noexcept;
37
35 38 /// Slot called when right clicking on an item in the tree (displays a menu)
36 39 void onTreeMenuRequested(const QPoint &pos) noexcept;
37 40 };
@@ -131,6 +131,11 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(QTreeWidget *parent, const Da
131 131 std::back_inserter(impl->m_Actions), createTreeAction);
132 132 }
133 133
134 const DataSourceItem *DataSourceTreeWidgetItem::data() const
135 {
136 return impl->m_Data;
137 }
138
134 139 QVariant DataSourceTreeWidgetItem::data(int column, int role) const
135 140 {
136 141 if (role == Qt::DisplayRole) {
@@ -3,6 +3,7
3 3 #include <ui_DataSourceWidget.h>
4 4
5 5 #include <DataSource/DataSourceItem.h>
6 #include <DataSource/DataSourceTreeWidgetHelper.h>
6 7 #include <DataSource/DataSourceTreeWidgetItem.h>
7 8
8 9 #include <QMenu>
@@ -47,6 +48,9 DataSourceWidget::DataSourceWidget(QWidget *parent) : QWidget{parent}, ui{new Ui
47 48 // Connection to show a menu when right clicking on the tree
48 49 connect(ui->treeWidget, &QTreeWidget::customContextMenuRequested, this,
49 50 &DataSourceWidget::onTreeMenuRequested);
51
52 // Connection to filter tree
53 connect(ui->filterLineEdit, &QLineEdit::textChanged, this, &DataSourceWidget::filterChanged);
50 54 }
51 55
52 56 DataSourceWidget::~DataSourceWidget() noexcept
@@ -63,6 +67,25 void DataSourceWidget::addDataSource(DataSourceItem *dataSource) noexcept
63 67 }
64 68 }
65 69
70 void DataSourceWidget::filterChanged(const QString &text) noexcept
71 {
72 auto validateItem = [&text](const DataSourceTreeWidgetItem &item) {
73 auto regExp = QRegExp{text, Qt::CaseInsensitive, QRegExp::Wildcard};
74
75 // An item is valid if any of its metadata validates the text filter
76 auto itemMetadata = item.data()->data();
77 auto itemMetadataEnd = itemMetadata.cend();
78 auto acceptFilter
79 = [&regExp](const auto &variant) { return variant.toString().contains(regExp); };
80
81 return std::find_if(itemMetadata.cbegin(), itemMetadataEnd, acceptFilter)
82 != itemMetadataEnd;
83 };
84
85 // Applies filter on tree widget
86 DataSourceTreeWidgetHelper::filter(*ui->treeWidget, validateItem);
87 }
88
66 89 void DataSourceWidget::onTreeMenuRequested(const QPoint &pos) noexcept
67 90 {
68 91 // Retrieves the selected item in the tree, and build the menu from its actions
@@ -14,19 +14,10
14 14 <string>Data sources</string>
15 15 </property>
16 16 <layout class="QGridLayout" name="gridLayout">
17 <property name="topMargin">
18 <number>0</number>
19 </property>
20 <property name="rightMargin">
21 <number>0</number>
22 </property>
23 <property name="bottomMargin">
24 <number>0</number>
25 </property>
26 <property name="spacing">
27 <number>0</number>
28 </property>
29 17 <item row="0" column="0">
18 <widget class="QLineEdit" name="filterLineEdit"/>
19 </item>
20 <item row="1" column="0">
30 21 <widget class="QTreeWidget" name="treeWidget">
31 22 <column>
32 23 <property name="text">
General Comments 0
You need to be logged in to leave comments. Login now