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 
30 namespace 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
65  {
66  customFilters.push_back(function);
67  }
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
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:64
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:70
armarx::InfixFilterModel::InfixFilterModel
InfixFilterModel(QObject *parent=0)
Definition: InfixFilterModel.cpp:34
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:213
armarx::InfixFilterModel
This proxy model reimplements the filterAcceptsRow function with a new behavior: All elements that fi...
Definition: InfixFilterModel.h:42
armarx::InfixFilterModel::filterAcceptsRow
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
Definition: InfixFilterModel.cpp:117
Logging.h
armarx::InfixFilterModel::customFilters
std::vector< FilterFunc > customFilters
Definition: InfixFilterModel.h:63
armarx::InfixFilterModel::containsAll
static bool containsAll(const QString &text, const QStringList &searchParts)
Definition: InfixFilterModel.cpp:51
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:27