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
28using namespace armarx;
29
30StateItemModel::StateItemModel(QObject* parent) : QStandardItemModel(0, 1, parent)
31{
32 // QStandardItem* item = new QStandardItem(FilterableTreeView::DefaultFilterStr);
33 // appendRow(item);
34}
35
36void
37StateItemModel::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
64StateIceBasePtr
65StateItemModel::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
95void
96StateItemModel::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
119QStandardItem*
120StateItemModel::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
146void
147StateItemModel::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
161QStandardItem*
162StateItemModel::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
184QVariant
185StateItemModel::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
275void
276StateItemModel::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
299void
300StateItemModel::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
340void
341StateItemModel::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
375bool
376armarx::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//}
uint8_t index
#define STATE_ITEM_DELETE
#define ARMARXGUI_BASEINSTANCE_STR
#define STATE_GLOBALSTATEID
#define STATE_TYPE
#define STATE_COMPONENT_NAME
#define ARMARXGUI_REQUESTEDINSTANCE_STR
#define STATE_ITEM_TYPE
void findSubstate(StateIceBasePtr state, const std::string &globalStateIdStr, StateIceBasePtr &resultState)
void updateModel(const std::string &componentName, const std::vector< StateIceBasePtr > &topLevelBaseStates, const std::vector< StateIceBasePtr > &topLevelRequestedStates)
bool setData(const QModelIndex &index, const QVariant &value, int role) override
StateItemModel(QObject *parent=0)
StateIceBasePtr getState(std::string componentName, const std::string &globalStateIdStr)
bool insert(mongocxx::collection &coll, const nlohmann::json &value)
Definition mongodb.cpp:44
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< RemoteState > RemoteStatePtr
Definition RemoteState.h:47
int toInt(const std::string &input)