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