InfixFilterModel.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package ArmarX
19 * @author Mirko Waechter( mirko.waechter at kit dot edu)
20 * @date 2016
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24#include "InfixFilterModel.h"
25
26#include <QTreeView>
27
29
30namespace armarx
31{
32
33
34 InfixFilterModel::InfixFilterModel(QObject* parent) : QSortFilterProxyModel(parent)
35 {
37 [this](QAbstractItemModel* model, int source_row, const QModelIndex& source_parent)
38 {
39 QModelIndex index0 = model->index(source_row, 0, source_parent);
40
41 QStringList searchParts =
42 this->filterRegExp().pattern().split(" ", QString::SkipEmptyParts);
43
44 auto result = containsAll(index0.data().toString(), searchParts);
45
46 return result;
47 });
48 }
49
50 bool
51 InfixFilterModel::containsAll(const QString& text, const QStringList& searchParts)
52 {
53 for (const QString& s : searchParts)
54 {
55 if (!text.contains(s, Qt::CaseInsensitive))
56 {
57 return false;
58 }
59 }
60 return true;
61 }
62
63 void
68
69 void
71 {
72 if (!treeView)
73 {
74 return;
75 }
76 treeView->collapseAll();
77 InfixFilterModel* proxyModel = qobject_cast<InfixFilterModel*>(treeView->model());
78 if (!proxyModel)
79 {
80 ARMARX_WARNING_S << "Could not cast treeview model to proxymodel!";
81 return;
82 }
83 QList<QModelIndex> indexList;
84 for (int i = 0; i < proxyModel->rowCount(); ++i)
85 {
86 indexList << proxyModel->index(i, 0);
87 }
88 // QStringList searchParts = proxyModel->filterRegExp().pattern().split(" ", QString::SkipEmptyParts);
89
90 while (indexList.size() > 0)
91 {
92 QModelIndex& index = indexList.front();
93 // ARMARX_INFO << "Checking of " << index.data().toString().toStdString() << VAROUT(index.row()) << " parent: " << index.parent().data().toString().toStdString();
94 auto sourceIndex = proxyModel->mapToSource(index);
95 if (proxyModel->filterAcceptsRow(sourceIndex.row(), sourceIndex.parent(), false))
96 {
97 // ARMARX_INFO << "Expanding parents of " << index.data().toString().toStdString();
98 QModelIndex current = index.parent();
99 while (current.isValid())
100 {
101 treeView->expand(current);
102 current = current.parent();
103 }
104 }
105 int i = 0;
106
107 while (index.child(i, 0).isValid())
108 {
109 indexList << index.child(i, 0);
110 i++;
111 }
112 indexList.pop_front();
113 }
114 }
115
116 bool
117 InfixFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
118 {
119 return filterAcceptsRow(source_row, source_parent, true);
120 }
121
122 bool
124 const QModelIndex& source_parent,
125 bool considerParents) const
126 {
127 QModelIndex index0 = sourceModel()->index(source_row, 0, source_parent);
128 QList<QModelIndex> indexList;
129 indexList << index0;
130 /*auto checkIndex = [this](QModelIndex index)
131 {
132 ARMARX_IMPORTANT << filterRegExp().pattern().toStdString();
133 QString text = sourceModel()->data(index).toString();
134 for (const QString& s : filterRegExp().pattern().split(" ", QString::SkipEmptyParts))
135 {
136 ARMARX_IMPORTANT << s.toStdString();
137 if (!text.contains(s, Qt::CaseInsensitive))
138 {
139 return false;
140 }
141 }
142 return true;
143 //return sourceModel()->data(index).toString().contains(filterRegExp());
144 };*/
145
146 auto checkRow = [this](int source_row, const QModelIndex& source_parent)
147 {
148 // QModelIndex index0 = sourceModel()->index(source_row, 0, source_parent);
149 bool accepted = true;
150 for (auto& f : this->customFilters)
151 {
152 accepted &= f(this->sourceModel(), source_row, source_parent);
153 if (!accepted)
154 {
155 break;
156 }
157 }
158 return accepted;
159 };
160
161 // QStringList searchParts = filterRegExp().pattern().split(" ", QString::SkipEmptyParts);
162 while (indexList.size() > 0)
163 {
164 QModelIndex& index = indexList.front();
165 // ARMARX_INFO << "Current: " << index.data().toString().toStdString();
166 bool accepted = checkRow(index.row(), index.parent());
167 // accepted = containsAll(sourceModel()->data(index).toString(), searchParts);
168
169
170 if (accepted)
171 {
172 // ARMARX_INFO << "Accepting " << index0.data().toString().toStdString();
173 return true;
174 }
175 int i = 0;
176
177 while (index.child(i, 0).isValid())
178 {
179 indexList << index.child(i, 0);
180 i++;
181 }
182 indexList.pop_front();
183 }
184 if (considerParents)
185 {
186 QModelIndex currentParent = source_parent;
187 // ARMARX_INFO << "Checking parent " << currentParent.data().toString().toStdString();
188 while (currentParent.isValid())
189 {
190
191 // if (sourceModel()->data(parent).toString().contains(filterRegExp()))
192 if (checkRow(currentParent.row(), currentParent.parent()))
193 {
194 return true;
195 }
196 currentParent = currentParent.parent();
197 }
198 }
199 return false;
200 }
201
202
203} // namespace armarx
uint8_t index
void addCustomFilter(FilterFunc function)
std::function< bool(QAbstractItemModel *, int, const QModelIndex &)> FilterFunc
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
std::vector< FilterFunc > customFilters
InfixFilterModel(QObject *parent=0)
static void ExpandFilterResults(QTreeView *treeView)
Expands the treeview that all items that match the filterstring are expanded and directly visible.
static bool containsAll(const QString &text, const QStringList &searchParts)
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:213
This file offers overloads of toIce() and fromIce() functions for STL container types.