scenariomodel.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 ArmarXCore::core
19 * @author Cedric Seehausen (usdnr 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
25
26#include "scenariomodel.h"
27
28#include <QColor>
29#include <QDataStream>
30#include <QIODevice>
31#include <QMimeData>
32#include <QStringList>
33#include <QtGlobal>
34
37
38using namespace ScenarioManager;
39using namespace Data_Structure;
40using namespace armarx;
41
43{
44 rootItem =
45 new ScenarioItem(QList<QVariant>({"Scenarios", "Start", "Stop", "Restart", "Status"}));
46}
47
48QVariant
49ScenarioModel::data(const QModelIndex& index, int role) const
50{
51 if (!index.isValid())
52 {
53 return QVariant();
54 }
55
56 if (role == Qt::ForegroundRole)
57 {
58 ApplicationInstancePtr instance =
59 static_cast<ScenarioItem*>(index.internalPointer())->getApplicationInstance();
60 if (instance.get() != nullptr && !instance->getEnabled())
61 {
62 return QColor(Qt::lightGray);
63 }
64 if (index.column() == 4)
65 {
66 if (index.data().toString().toStdString() == ApplicationStatus::Missing)
67 {
68 return QColor(Qt::lightGray);
69 }
70 else if (index.data().toString().toStdString() == ApplicationStatus::Running)
71 {
72 return QColor(Qt::green);
73 }
74 else if (index.data().toString().toStdString() == ApplicationStatus::Stopped)
75 {
76 return QColor(Qt::red);
77 }
78 else if (index.data().toString().toStdString() == ApplicationStatus::Inactive)
79 {
80 return QColor(Qt::gray);
81 }
82 else if (index.data().toString().toStdString() == ApplicationStatus::Mixed)
83 {
84 return QColor(Qt::darkYellow);
85 }
86 else if (index.data().toString().toStdString() == ApplicationStatus::Waiting)
87 {
88 return QColor(Qt::blue);
89 }
90 else
91 {
92 return QColor(Qt::black);
93 }
94 }
95 }
96 else if (role == Qt::ToolTipRole)
97 {
98 const QAbstractItemModel* model = index.model();
99 QString appName =
100 model->data(model->index(index.row(), 0, index.parent()), Qt::DisplayRole).toString();
101
102 if (index.column() == 1)
103 {
104 return QVariant(QString("Start ") + appName);
105 }
106 else if (index.column() == 2)
107 {
108 return QVariant(QString("Stop ") + appName);
109 }
110 else if (index.column() == 3)
111 {
112 return QVariant(QString("Restart ") + appName);
113 }
114 }
115 else if (role == SCENARIOITEMSOURCE)
116 {
117 return QVariant::fromValue(reinterpret_cast<ScenarioItem*>(index.internalPointer()));
118 }
119 else if (role == SCENARIOITEMPENDINGINTENT)
120 {
121 return QVariant(
122 static_cast<int>(static_cast<ScenarioItem*>(index.internalPointer())->getPendingIntent()));
123 }
124 else if (role != Qt::DisplayRole)
125 {
126 return QVariant();
127 }
128
129 ScenarioItem* item = static_cast<ScenarioItem*>(index.internalPointer());
130 return item->data(index.column());
131}
132
133void
135{
136 delete rootItem;
137 rootItem =
138 new ScenarioItem(QList<QVariant>({"Scenarios", "Start", "Stop", "Restart", "Status"}));
139 reset();
140}
141
142Qt::DropActions
144{
145 return Qt::CopyAction;
146}
147
148Qt::ItemFlags
149ScenarioModel::flags(const QModelIndex& index) const
150{
151 Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index);
152
153 // if (index.data().toString().compare("Start") == 0 && !index.parent().isValid())
154 // {
155 // return Qt::ItemIsDropEnabled | Qt::ItemIsEditable | Qt::ItemIsUserCheckable | defaultFlags;
156 // }
157
158 return Qt::ItemIsDropEnabled | defaultFlags;
159}
160
161QStringList
163{
164 QStringList types;
165 types << "application/pointer";
166 return types;
167}
168
169bool
171 Qt::DropAction action,
172 int row,
173 int column,
174 const QModelIndex& parent)
175{
176 if (action == Qt::IgnoreAction)
177 {
178 return true;
179 }
180
181 if (!data->hasFormat("application/pointer"))
182 {
183 return false;
184 }
185
186 if (column > 0)
187 {
188 return false;
189 }
190
191 // int beginRow;
192
193 // if (row != -1)
194 // beginRow = row;
195 // else if (parent.isValid())
196 // beginRow = parent.row();
197 // else
198 // beginRow = rowCount(QModelIndex());
199
200 QByteArray encodedData = data->data("application/pointer");
201 QDataStream stream(&encodedData, QIODevice::ReadOnly);
202 QList<QPair<QString, ScenarioManager::Data_Structure::Application*>> result;
203 int rows = 0;
204
205 while (!stream.atEnd())
206 {
207 quint64 holder;
208 QString instanceName;
209 stream >> holder >> instanceName;
210
211 if (holder == 0)
212 {
213 continue;
214 }
215 result << qMakePair(instanceName,
216 reinterpret_cast<Data_Structure::Application*>(holder)); //
217 ++rows;
218 }
219
220 emit applicationsDrop(result, row, parent);
221 return true;
222}
223
224void
226{
227 updateSubtree(getRootItem(), QModelIndex());
228}
229
230void
231ScenarioModel::updateSubtree(ScenarioItem* item, const QModelIndex& itemIndex)
232{
233 const int rows = item->childCount();
234
235 // Bottom-up: a child is fully updated before its parent, so package items can aggregate the
236 // status of their children in the same pass.
237 std::vector<bool> childChanged(rows, false);
238 for (int row = 0; row < rows; row++)
239 {
240 ScenarioItem* child = static_cast<ScenarioItem*>(item->child(row));
241 updateSubtree(child, index(row, 0, itemIndex));
242 childChanged[row] = child->update();
243 }
244
245 // The previous implementation emitted a single dataChanged() spanning the top level rows only.
246 // A range like that carries no repaint obligation for the rows *below* those items, so an
247 // application whose status changed could keep its stale text on screen until something else
248 // happened to repaint it. Signal the rows that actually changed instead, at their own depth.
249 //
250 // Contiguous rows are coalesced into one emission because each one makes the view re-evaluate
251 // filters and re-layout the affected sections.
252 const int lastColumn = columnCount() - 1;
253 int rangeBegin = -1;
254 for (int row = 0; row <= rows; row++)
255 {
256 const bool changed = row < rows && childChanged[row];
257 if (changed && rangeBegin < 0)
258 {
259 rangeBegin = row;
260 }
261 else if (!changed && rangeBegin >= 0)
262 {
263 emit dataChanged(index(rangeBegin, 0, itemIndex),
264 index(row - 1, lastColumn, itemIndex));
265 rangeBegin = -1;
266 }
267 }
268}
269
272{
273 return static_cast<ScenarioItem*>(rootItem);
274}
275
277ScenarioModel::FindScenario(const QAbstractItemModel* model, const QString& scenarioName)
278{
279 ARMARX_CHECK_EXPRESSION(!scenarioName.isEmpty());
280 for (int i = 0; i < model->rowCount(); ++i)
281 {
282 auto index = model->index(i, 0);
283 auto currentScenarioName = index.data().toString();
284 if (currentScenarioName == scenarioName)
285 {
286 return index.data(SCENARIOITEMSOURCE).value<ScenarioItem*>();
287 break;
288 }
289 }
290 return NULL;
291}
292
293int
294ScenarioModel::FindScenarioIndex(const QAbstractItemModel* model, const QString& scenarioName)
295{
296 ARMARX_CHECK_EXPRESSION(!scenarioName.isEmpty());
297 for (int i = 0; i < model->rowCount(); ++i)
298 {
299 auto index = model->index(i, 0);
300 auto currentScenarioName = index.data().toString();
301 if (currentScenarioName == scenarioName)
302 {
303 return i;
304 break;
305 }
306 }
307 return -1;
308}
uint8_t index
TreeItem representing data contained in a Scenario or an Application.
ScenarioManager::Data_Structure::ApplicationInstancePtr getApplicationInstance()
If this item represents an Application, it is returned.
ScenarioManager::Data_Structure::Intent getPendingIntent() const
The operation this row is currently moving towards, or Intent::None when idle.
bool update()
Clears the item_data and parses the Scenario or Application for new data.
Class containing data about an application Provides methods to get and set the date contained in the ...
Definition Application.h:49
QStringList mimeTypes() const override
void applicationsDrop(QList< QPair< QString, ScenarioManager::Data_Structure::Application * > > applications, int row, const QModelIndex &parent)
static ScenarioItem * FindScenario(const QAbstractItemModel *model, const QString &scenarioName)
Qt::ItemFlags flags(const QModelIndex &index) const override
Returns the item flags of the item at the given index.
ScenarioItem * getRootItem()
static int FindScenarioIndex(const QAbstractItemModel *model, const QString &scenarioName)
void update()
Updates this model, emitting dataChanged() for every row whose displayed data changed.
Qt::DropActions supportedDropActions() const override
Returns the drop-Actions supported by this model.
QVariant data(const QModelIndex &index, int role) const override
Returns the data of the item at the given index based on the given role.
void clear() override
Clears and resets this model.
ScenarioModel()
Sets up the model.
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
int childCount() const
Definition treeitem.cpp:57
virtual QVariant data(int column) const
Definition treeitem.cpp:69
TreeItem * child(int row)
Definition treeitem.cpp:51
TreeItem * rootItem
Definition treemodel.h:69
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Definition treemodel.cpp:99
int columnCount(const QModelIndex &parent=QModelIndex()) const override
Definition treemodel.cpp:45
QModelIndex parent(const QModelIndex &index) const override
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
std::shared_ptr< ApplicationInstance > ApplicationInstancePtr
This file offers overloads of toIce() and fromIce() functions for STL container types.
@ SCENARIOITEMSOURCE
Definition treeitem.h:37
@ SCENARIOITEMPENDINGINTENT
ScenarioManager::Data_Structure::Intent of the row, as an int. See ScenarioItem::update().
Definition treeitem.h:46