StateItemModel.cpp
Go to the documentation of this file.
1 /* * This file is part of ArmarX.
2 *
3 * ArmarX is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as
5 * published by the Free Software Foundation.
6 *
7 * ArmarX is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *
15 * @package ArmarX::Gui
16 * @author Mirko Waechter (waechter@kit.edu)
17 * @copyright 2012 Humanoids Group, IAIM, IFA
18 * @license http://www.gnu.org/licenses/gpl-2.0.txt
19 * GNU General Public License
20 */
21 
22 
23 #include "StateItemModel.h"
24 
26 
27 
28 using namespace armarx;
29 
30 StateItemModel::StateItemModel(QObject* parent) : QStandardItemModel(0, 1, parent)
31 {
32  // QStandardItem* item = new QStandardItem(FilterableTreeView::DefaultFilterStr);
33  // appendRow(item);
34 }
35 
36 void
37 StateItemModel::updateModel(const std::string& componentName,
38  const std::vector<StateIceBasePtr>& topLevelBaseStates,
39  const std::vector<StateIceBasePtr>& topLevelRequestedStates)
40 {
41  if (componentName.empty())
42  {
43  return;
44  }
45 
46  requestedInstanceList[componentName] = topLevelRequestedStates;
47 
48  // mark all elements for deletion
49  markAllForDelete(invisibleRootItem());
50 
51  // insert observer
52  QStandardItem* componentItem = updateComponent(componentName);
53 
54  // update states
55  updateStates(componentItem->child(0), topLevelBaseStates, componentName, eBaseStateItem);
56  updateStates(
57  componentItem->child(1), topLevelRequestedStates, componentName, eInstanceStateItem);
58 
59 
60  // delete not updated items
61  deleteUnusedItems(componentItem);
62 }
63 
64 StateIceBasePtr
65 StateItemModel::getState(std::string componentName, const std::string& globalStateIdStr)
66 {
67  std::map<std::string, std::vector<StateIceBasePtr>>::iterator it =
68  requestedInstanceList.find(componentName);
69 
70  if (it == requestedInstanceList.end())
71  {
72  return NULL;
73  }
74 
75  StateIceBasePtr result = NULL;
76 
77  for (unsigned int i = 0; i < it->second.size(); i++)
78  {
79  if (it->second[i]->globalStateIdentifier == globalStateIdStr)
80  {
81  return it->second[i];
82  }
83 
84  findSubstate(it->second[i], globalStateIdStr, result);
85 
86  if (result)
87  {
88  return result;
89  }
90  }
91 
92  return result;
93 }
94 
95 void
96 StateItemModel::findSubstate(StateIceBasePtr state,
97  const std::string& globalStateIdStr,
98  StateIceBasePtr& resultState)
99 {
100  for (unsigned int i = 0; i < state->subStateList.size(); ++i)
101  {
102  StateIceBasePtr curState = StateIceBasePtr::dynamicCast(state->subStateList[i]);
103 
104  if (curState->globalStateIdentifier == globalStateIdStr)
105  {
106  resultState = curState;
107  return;
108  }
109 
110  findSubstate(curState, globalStateIdStr, resultState);
111 
112  if (resultState)
113  {
114  return;
115  }
116  }
117 }
118 
119 QStandardItem*
120 StateItemModel::updateComponent(std::string componentName)
121 {
122  QStandardItem* componentItem = new QStandardItem(QString(componentName.c_str()));
123  componentItem->setData(QVariant(eComponentItem), STATE_ITEM_TYPE);
124  componentItem->setData(QVariant(componentName.c_str()), STATE_GLOBALSTATEID);
125  componentItem->setData(QVariant(eUndefined), STATE_TYPE);
126 
127  componentItem = updateOrInsertItem(invisibleRootItem(), componentItem);
128 
129  // insert item for BaseStates
130  QStandardItem* baseStateItem = new QStandardItem(QString(ARMARXGUI_BASEINSTANCE_STR));
131  baseStateItem->setData(QVariant(ePlaceHolderItem), STATE_ITEM_TYPE);
132  baseStateItem->setData(QVariant(ARMARXGUI_BASEINSTANCE_STR), STATE_GLOBALSTATEID);
133  baseStateItem->setData(QVariant(eUndefined), STATE_TYPE);
134  baseStateItem = updateOrInsertItem(componentItem, baseStateItem);
135 
136  // insert item for the requested state instances
137  QStandardItem* requestedStateItem = new QStandardItem(QString(ARMARXGUI_REQUESTEDINSTANCE_STR));
138  requestedStateItem->setData(QVariant(ePlaceHolderItem), STATE_ITEM_TYPE);
139  requestedStateItem->setData(QVariant(ARMARXGUI_REQUESTEDINSTANCE_STR), STATE_GLOBALSTATEID);
140  requestedStateItem->setData(QVariant(eUndefined), STATE_TYPE);
141  requestedStateItem = updateOrInsertItem(componentItem, requestedStateItem);
142 
143  return componentItem;
144 }
145 
146 void
147 StateItemModel::updateStates(QStandardItem* componentItem,
148  const std::vector<StateIceBasePtr>& topLevelStates,
149  std::string componentName,
150  eItemType itemType)
151 {
152 
153  for (unsigned int i = 0; i < topLevelStates.size(); ++i)
154  {
155 
156 
157  insertSubstates(componentItem, topLevelStates[i], componentName, itemType);
158  }
159 }
160 
161 QStandardItem*
162 StateItemModel::updateOrInsertItem(QStandardItem* parent, QStandardItem* insert)
163 {
164  // loop through childs and compare data
165  for (int r = 0; r < parent->rowCount(); r++)
166  {
167  QStandardItem* item = parent->child(r);
168 
169  //ARMARX_LOG_S << "insert data: " << insert->data(STATE_GLOBALSTATEID).toString().toStdString();
170  if (item->data(STATE_GLOBALSTATEID) == insert->data(STATE_GLOBALSTATEID))
171  {
172  delete insert;
173  item->setData(QVariant(false), STATE_ITEM_DELETE);
174  return item;
175  }
176  }
177 
178  parent->appendRow(insert);
179 
180  insert->setData(QVariant(false), STATE_ITEM_DELETE);
181  return insert;
182 }
183 
184 QVariant
185 StateItemModel::data(const QModelIndex& index, int role) const
186 {
187 
188 
189  if (role == Qt::BackgroundColorRole)
190  {
191  if (not(itemData(index)[STATE_ITEM_TYPE].toInt() == eInstanceStateItem ||
192  itemData(index)[STATE_ITEM_TYPE].toInt() == eBaseStateItem))
193  {
194  return QStandardItemModel::data(index, role);
195  }
196 
197  QBrush brush;
198  eStateType type = eStateType(itemData(index)[STATE_TYPE].toInt());
199 
200  switch (type)
201  {
202  case eNormalState:
203  brush.setColor(Qt::white);
204  break;
205 
206  case eRemoteState:
207  brush.setColor(Qt::blue);
208  break;
209 
210  case eDynamicRemoteState:
211  brush.setColor(Qt::blue);
212  brush.setColor(brush.color().lighter(120));
213  break;
214 
215  case eFinalState:
216  brush.setColor(Qt::yellow);
217  break;
218 
219  default:
220  brush.setColor(Qt::white);
221  }
222 
223  brush.setColor(brush.color().lighter(170));
224 
225  return qVariantFromValue(brush.color());
226  }
227  else if (role == Qt::ToolTipRole)
228  {
229  eStateType type = eStateType(itemData(index)[STATE_TYPE].toInt());
230  QString componentName = itemData(index)[STATE_COMPONENT_NAME].toString();
231  QString globalId = itemData(index)[STATE_GLOBALSTATEID].toString();
232 
233  QString description;
234 
235  switch (type)
236  {
237  case eNormalState:
238  description = "Normal State";
239  break;
240 
241  case eRemoteState:
242  description = "Remote State";
243  break;
244 
245  case eDynamicRemoteState:
246  description = "Dynamic Remote State";
247  break;
248 
249  case eFinalState:
250  description = "Final State";
251  break;
252 
253  case eUndefined:
254  description = "";
255  break;
256 
257  default:
258  description = "Unknown State Type";
259  }
260 
261  if (description.length() > 0)
262  {
263  description += "; Id: " + globalId + "; Component Name: " + componentName;
264  }
265 
266  return qVariantFromValue(description);
267  }
268  else
269  {
270  return QStandardItemModel::data(index, role);
271  }
272 }
273 
274 // mark all elements for deletion
275 void
276 StateItemModel::markAllForDelete(QStandardItem* stateItem)
277 {
278  int nCount = 0;
279  std::list<QStandardItem*> markList;
280  markList.push_back(stateItem);
281 
282  while (markList.size() > 0)
283  {
284  QStandardItem* current = markList.front();
285  markList.pop_front();
286  current->setData(QVariant(true), STATE_ITEM_DELETE);
287  nCount++;
288 
289  if (current->hasChildren())
290  {
291  for (int r = 0; r < current->rowCount(); r++)
292  {
293  markList.push_back(current->child(r));
294  }
295  }
296  }
297 }
298 
299 void
300 StateItemModel::deleteUnusedItems(QStandardItem* stateItem)
301 {
302  std::list<QStandardItem*> searchList;
303  std::vector<int> removeRows;
304 
305  searchList.push_back(stateItem);
306 
307  while (searchList.size() > 0)
308  {
309  QStandardItem* current = searchList.front();
310  searchList.pop_front();
311 
312  if (current->hasChildren())
313  {
314  removeRows.clear();
315 
316  for (int r = 0; r < current->rowCount(); r++)
317  {
318  if (current->child(r)->data(STATE_ITEM_DELETE).toBool())
319  {
320  removeRows.push_back(r);
321  }
322  else
323  {
324  searchList.push_back(current->child(r));
325  }
326  }
327 
328  // remove unused rows
329  std::vector<int>::iterator iter = removeRows.begin();
330 
331  while (iter != removeRows.end())
332  {
333  current->removeRow(*iter);
334  iter++;
335  }
336  }
337  }
338 }
339 
340 void
341 StateItemModel::insertSubstates(QStandardItem* parentStateItem,
342  StateIceBasePtr state,
343  std::string componentName,
344  eItemType itemType)
345 {
346 
347  // create item for substate
348  QStandardItem* stateItem = new QStandardItem(QString(state->stateName.c_str()));
349  //ARMARX_INFO_S << "Inserting " << state->stateName << " with " << state->globalStateIdentifier << flush;
350  stateItem->setData(QVariant(itemType), STATE_ITEM_TYPE);
351  stateItem->setData(QVariant(QString(state->globalStateIdentifier.c_str())),
353  stateItem->setData(QVariant(state->stateType), STATE_TYPE);
354  RemoteStatePtr remoteState = RemoteStatePtr::dynamicCast(state);
355 
356  if (remoteState)
357  {
358  // ARMARX_INFO_S << remoteState->stateName << " is remote state" << flush;
359  componentName = remoteState->proxyName;
360  // ARMARX_INFO_S << "substatelist size: " << remoteState->subStateList.size() << flush;
361  }
362 
363  stateItem->setData(QVariant(componentName.c_str()), STATE_COMPONENT_NAME);
364 
365  // insert state item into treeview
366  stateItem = updateOrInsertItem(parentStateItem, stateItem);
367 
368  for (unsigned int i = 0; i < state->subStateList.size(); ++i)
369  {
370  StateIceBasePtr curState = StateIceBasePtr::dynamicCast(state->subStateList[i]);
371  insertSubstates(stateItem, curState, componentName, itemType);
372  }
373 }
374 
375 bool
376 armarx::StateItemModel::setData(const QModelIndex& index, const QVariant& value, int role)
377 {
378  if (index.row() == 0 && index.parent() == invisibleRootItem()->index())
379  {
380  if (role == Qt::EditRole)
381  {
382  // if(value.toString().length() > 0)
383  // searchString = value.toString();
384  // else
385  // searchString = DEFAULT_FILTER_CONTENT;
386  // emit dataChanged(index, index);
387  }
388  }
389 
390  return true;
391 }
392 
393 //Qt::ItemFlags armarx::StateItemModel::flags(const QModelIndex &index) const
394 //{
395 // if(index.row() == 0 && index.parent() == invisibleRootItem()->index() )
396 // {
397 // return Qt::ItemIsEnabled | Qt::ItemIsEditable;
398 // }
399 // else
400 // return Qt::ItemIsEnabled | Qt::ItemIsSelectable ;
401 // //QStandardItemModel::flags(index);
402 
403 //}
index
uint8_t index
Definition: EtherCATFrame.h:59
STATE_COMPONENT_NAME
#define STATE_COMPONENT_NAME
Definition: StateItemModel.h:36
armarx::toInt
int toInt(const std::string &input)
Definition: StringHelpers.cpp:111
STATE_GLOBALSTATEID
#define STATE_GLOBALSTATEID
Definition: StateItemModel.h:39
armarx::StateItemModel::updateModel
void updateModel(const std::string &componentName, const std::vector< StateIceBasePtr > &topLevelBaseStates, const std::vector< StateIceBasePtr > &topLevelRequestedStates)
Definition: StateItemModel.cpp:37
FilterableTreeView.h
armarx::StateItemModel::setData
bool setData(const QModelIndex &index, const QVariant &value, int role) override
Definition: StateItemModel.cpp:376
IceInternal::Handle
Definition: forward_declarations.h:8
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:855
armarx::StateItemModel::findSubstate
void findSubstate(StateIceBasePtr state, const std::string &globalStateIdStr, StateIceBasePtr &resultState)
Definition: StateItemModel.cpp:96
StateItemModel.h
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
ARMARXGUI_BASEINSTANCE_STR
#define ARMARXGUI_BASEINSTANCE_STR
Definition: StateItemModel.h:41
armarx::armem::server::ltm::util::mongodb::detail::insert
bool insert(mongocxx::collection &coll, const nlohmann::json &value)
Definition: mongodb.cpp:44
STATE_ITEM_DELETE
#define STATE_ITEM_DELETE
Definition: StateItemModel.h:37
armarx::StateItemModel::eBaseStateItem
@ eBaseStateItem
Definition: StateItemModel.h:62
armarx::StateItemModel::eInstanceStateItem
@ eInstanceStateItem
Definition: StateItemModel.h:63
STATE_TYPE
#define STATE_TYPE
Definition: StateItemModel.h:38
armarx::StateItemModel::getState
StateIceBasePtr getState(std::string componentName, const std::string &globalStateIdStr)
Definition: StateItemModel.cpp:65
armarx::StateItemModel::eComponentItem
@ eComponentItem
Definition: StateItemModel.h:60
armarx::StateItemModel::ePlaceHolderItem
@ ePlaceHolderItem
Definition: StateItemModel.h:61
armarx::StateItemModel::StateItemModel
StateItemModel(QObject *parent=0)
Definition: StateItemModel.cpp:30
ARMARXGUI_REQUESTEDINSTANCE_STR
#define ARMARXGUI_REQUESTEDINSTANCE_STR
Definition: StateItemModel.h:42
STATE_ITEM_TYPE
#define STATE_ITEM_TYPE
Definition: StateItemModel.h:34
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27