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"
26 #include <QTreeView>
27 
28 namespace armarx
29 {
30 
31 
32  InfixFilterModel::InfixFilterModel(QObject* parent) : QSortFilterProxyModel(parent)
33  {
34  addCustomFilter([this](QAbstractItemModel * model, int source_row, const QModelIndex & source_parent)
35  {
36  QModelIndex index0 = model->index(source_row, 0, source_parent);
37 
38  QStringList searchParts = this->filterRegExp().pattern().split(" ", QString::SkipEmptyParts);
39 
40  auto result = containsAll(index0.data().toString(), searchParts);
41 
42  return result;
43  });
44  }
45 
46  bool InfixFilterModel::containsAll(const QString& text, const QStringList& searchParts)
47  {
48  for (const QString& s : searchParts)
49  {
50  if (!text.contains(s, Qt::CaseInsensitive))
51  {
52  return false;
53  }
54  }
55  return true;
56  }
57 
59  {
60  customFilters.push_back(function);
61  }
62 
63  void InfixFilterModel::ExpandFilterResults(QTreeView* treeView)
64  {
65  if (!treeView)
66  {
67  return;
68  }
69  treeView->collapseAll();
70  InfixFilterModel* proxyModel = qobject_cast<InfixFilterModel*>(treeView->model());
71  if (!proxyModel)
72  {
73  ARMARX_WARNING_S << "Could not cast treeview model to proxymodel!";
74  return;
75  }
76  QList<QModelIndex> indexList;
77  for (int i = 0; i < proxyModel->rowCount(); ++i)
78  {
79  indexList << proxyModel->index(i, 0);
80  }
81  // QStringList searchParts = proxyModel->filterRegExp().pattern().split(" ", QString::SkipEmptyParts);
82 
83  while (indexList.size() > 0)
84  {
85  QModelIndex& index = indexList.front();
86  // ARMARX_INFO << "Checking of " << index.data().toString().toStdString() << VAROUT(index.row()) << " parent: " << index.parent().data().toString().toStdString();
87  auto sourceIndex = proxyModel->mapToSource(index);
88  if (proxyModel->filterAcceptsRow(sourceIndex.row(), sourceIndex.parent(), false))
89  {
90  // ARMARX_INFO << "Expanding parents of " << index.data().toString().toStdString();
91  QModelIndex current = index.parent();
92  while (current.isValid())
93  {
94  treeView->expand(current);
95  current = current.parent();
96  }
97  }
98  int i = 0;
99 
100  while (index.child(i, 0).isValid())
101  {
102  indexList << index.child(i, 0);
103  i++;
104  }
105  indexList.pop_front();
106  }
107  }
108 
109  bool InfixFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
110  {
111  return filterAcceptsRow(source_row, source_parent, true);
112  }
113 
114  bool InfixFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent, bool considerParents) const
115  {
116  QModelIndex index0 = sourceModel()->index(source_row, 0, source_parent);
117  QList<QModelIndex> indexList;
118  indexList << index0;
119  /*auto checkIndex = [this](QModelIndex index)
120  {
121  ARMARX_IMPORTANT << filterRegExp().pattern().toStdString();
122  QString text = sourceModel()->data(index).toString();
123  for (const QString& s : filterRegExp().pattern().split(" ", QString::SkipEmptyParts))
124  {
125  ARMARX_IMPORTANT << s.toStdString();
126  if (!text.contains(s, Qt::CaseInsensitive))
127  {
128  return false;
129  }
130  }
131  return true;
132  //return sourceModel()->data(index).toString().contains(filterRegExp());
133  };*/
134 
135  auto checkRow = [this](int source_row, const QModelIndex & source_parent)
136  {
137  // QModelIndex index0 = sourceModel()->index(source_row, 0, source_parent);
138  bool accepted = true;
139  for (auto& f : this->customFilters)
140  {
141  accepted &= f(this->sourceModel(), source_row, source_parent);
142  if (!accepted)
143  {
144  break;
145  }
146  }
147  return accepted;
148  };
149 
150  // QStringList searchParts = filterRegExp().pattern().split(" ", QString::SkipEmptyParts);
151  while (indexList.size() > 0)
152  {
153  QModelIndex& index = indexList.front();
154  // ARMARX_INFO << "Current: " << index.data().toString().toStdString();
155  bool accepted = checkRow(index.row(), index.parent());
156  // accepted = containsAll(sourceModel()->data(index).toString(), searchParts);
157 
158 
159  if (accepted)
160  {
161  // ARMARX_INFO << "Accepting " << index0.data().toString().toStdString();
162  return true;
163  }
164  int i = 0;
165 
166  while (index.child(i, 0).isValid())
167  {
168  indexList << index.child(i, 0);
169  i++;
170  }
171  indexList.pop_front();
172  }
173  if (considerParents)
174  {
175  QModelIndex currentParent = source_parent;
176  // ARMARX_INFO << "Checking parent " << currentParent.data().toString().toStdString();
177  while (currentParent.isValid())
178  {
179 
180  // if (sourceModel()->data(parent).toString().contains(filterRegExp()))
181  if (checkRow(currentParent.row(), currentParent.parent()))
182  {
183  return true;
184  }
185  currentParent = currentParent.parent();
186 
187  }
188  }
189  return false;
190  }
191 
192 
193 } // namespace armarx
armarx::InfixFilterModel::FilterFunc
std::function< bool(QAbstractItemModel *, int, const QModelIndex &)> FilterFunc
Definition: InfixFilterModel.h:46
index
uint8_t index
Definition: EtherCATFrame.h:59
InfixFilterModel.h
armarx::InfixFilterModel::addCustomFilter
void addCustomFilter(FilterFunc function)
Definition: InfixFilterModel.cpp:58
armarx::InfixFilterModel::ExpandFilterResults
static void ExpandFilterResults(QTreeView *treeView)
Expands the treeview that all items that match the filterstring are expanded and directly visible.
Definition: InfixFilterModel.cpp:63
armarx::InfixFilterModel::InfixFilterModel
InfixFilterModel(QObject *parent=0)
Definition: InfixFilterModel.cpp:32
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:206
armarx::InfixFilterModel
This proxy model reimplements the filterAcceptsRow function with a new behavior: All elements that fi...
Definition: InfixFilterModel.h:41
armarx::InfixFilterModel::filterAcceptsRow
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
Definition: InfixFilterModel.cpp:109
Logging.h
armarx::InfixFilterModel::customFilters
std::vector< FilterFunc > customFilters
Definition: InfixFilterModel.h:60
armarx::InfixFilterModel::containsAll
static bool containsAll(const QString &text, const QStringList &searchParts)
Definition: InfixFilterModel.cpp:46
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28