TransitionMappingTable.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
19 * @author
20 * @date
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
25
26using namespace armarx;
27
28#include <QComboBox>
29#include <QHeaderView>
30#include <QLineEdit>
31
33
36
39
40class NoWheelComboBox : public QComboBox
41{
42public:
43 NoWheelComboBox(QWidget* parent = NULL) : QComboBox(parent)
44 {
45 }
46
47 // QWidget interface
48protected:
49 void
50 wheelEvent(QWheelEvent* e) override
51 {
52 e->ignore();
53 }
54};
55
56TransitionMappingTable::TransitionMappingTable(QWidget* parent) : QTableWidget(parent)
57{
58}
59
60void
62 const statechartmodel::ParameterMappingList& sourceMapping,
65 QStringList profileNames,
67 VariantInfoPtr variantInfo)
68{
69 this->ic = ic;
70 this->variantInfo = variantInfo;
71 destDict = targetDict;
72 this->transition = transition;
73 parentState = state;
74 oldSourceMapping = sourceMapping;
75 this->profileNames = profileNames;
76 setColumnCount(5);
77
78 if (!transition->destinationState->getStateClass() &&
79 transition->destinationState->getType() != eFinalState)
80 {
81 return;
82 }
83
84 setRowCount(destDict.size());
85 setHorizontalHeaderLabels(
86 QString("Target parameter;Value Type;Mapping Required;Source Type;Source Parameter;")
87 .split(";"));
88 horizontalHeaderItem(eMappingRequired)
89 ->setToolTip("Checked if this parameter has no default value and is not optional, so a "
90 "mapping is required.");
91 setColumnWidth(eDestKey, 180);
92 setColumnWidth(eDestType, 200);
93 setColumnWidth(eSource, 100);
94 setColumnWidth(eMappingRequired, 25);
95 hideColumn(eMappingRequired);
96 horizontalHeader()->setStretchLastSection(true);
97
98 QStringList mappingSources;
99 mappingSources << "Parent input";
100 mappingSources << "State output";
101 mappingSources << "Datafield"
102 << "Event";
103 mappingSources << "Value";
104
105 int row = 0;
106 statechartmodel::StateParameterMap::const_iterator it = destDict.begin();
107
108 for (; it != destDict.end(); it++) //for every input
109 {
110 QString keyInput = it.key();
111
113 transition->findMapping(keyInput, sourceMapping);
114
115 if (!mapping)
116 {
117 ARMARX_VERBOSE_S << "No mapping found for " << keyInput;
118 }
119
120 QString typeInput = it.value()->type;
121 auto destKeyItem = new QTableWidgetItem(keyInput);
122 setItem(row, eDestKey, destKeyItem);
123 destKeyItem->setToolTip((it.value()->description.isEmpty() ? "" : "Description:\n") +
124 it.value()->description);
125 item(row, eDestKey)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
126
127 setItem(row, eMappingRequired, new QTableWidgetItem());
128 item(row, eMappingRequired)
129 ->setCheckState(!it.value()->optional && !it.value()->getDefaultValue()
130 ? Qt::Checked
131 : Qt::Unchecked);
132 item(row, eMappingRequired)->setFlags(Qt::ItemIsEnabled);
133
134
135 QComboBox* comboBoxMappingSource = new NoWheelComboBox(this);
136
137 setCellWidget(row, eSource, comboBoxMappingSource);
138 comboBoxMappingSource->addItems(mappingSources);
139
140
141 if (mapping)
142 {
143 // ARMARX_VERBOSE_S << "Setting source type to " << (int)mapping->source << " and output to " << mapping->sourceKey;
144 comboBoxMappingSource->setCurrentIndex(mapping->source);
145 setSourceSpecificMappingParameters((int)mapping->source, row, mapping->sourceKey);
146 }
147 else
148 {
149 int mappingSource = transition->sourceState ? 1 : 0;
150 comboBoxMappingSource->setCurrentIndex(mappingSource);
151 setSourceSpecificMappingParameters(mappingSource, row);
152 }
153
154 connect(comboBoxMappingSource,
155 SIGNAL(currentIndexChanged(int)),
156 this,
158
159
160 // this disables the combobox entries
161 if (!transition->sourceState)
162 {
163
164 comboBoxMappingSource->setItemData(1, QVariant(0), Qt::UserRole - 1);
165 }
166 comboBoxMappingSource->setItemData(2, QVariant(0), Qt::UserRole - 1);
167 comboBoxMappingSource->setItemData(3, QVariant(0), Qt::UserRole - 1);
168
169
170 auto humanType = QString::fromUtf8(
171 variantInfo->getNestedHumanNameFromBaseName(typeInput.toUtf8().data()).c_str());
172 setItem(row, eDestType, new QTableWidgetItem(humanType));
173 item(row, eDestType)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
174 item(row, eDestType)->setToolTip(typeInput);
175 row++;
176 }
177}
178
181{
183
184 for (int row = 0; row < rowCount(); row++)
185 {
187 mapping->destinationKey = item(row, eDestKey)->text();
188 QComboBox* combo = qobject_cast<QComboBox*>(cellWidget(row, eSource));
189
190 if (combo)
191 {
192 mapping->source = (MappingSource)combo->currentIndex();
193 }
194
195 QComboBox* sourceCombo = qobject_cast<QComboBox*>(cellWidget(row, eSourceKey));
196
197 if (sourceCombo)
198 {
199 mapping->sourceKey = sourceCombo->currentText();
200 }
201 if (!mapping->sourceKey.isEmpty() && mapping->sourceKey != "none")
202 {
203 result.append(mapping);
204 }
205
206
208 qobject_cast<MultiProfileDefaultValueEditWidget*>(cellWidget(row, eSourceKey)))
209 {
210 mapping->profileValues = valueEdit->getJsonMap();
211 result.append(mapping);
212 }
213 }
214
215 return result;
216}
217
218QList<std::pair<QString, QString>>
220 std::function<std::pair<bool, float>(QString, QString)> compare)
221{
222 QList<std::pair<QString, QString>> mappedRows;
223 for (int row = 0; row < rowCount(); row++)
224 {
225 QComboBox* comboSourceType = qobject_cast<QComboBox*>(cellWidget(row, eSource));
226 int oldIndex = comboSourceType->currentIndex();
227 bool found = false;
228 for (int type = 1; type >= 0; type--)
229 {
230 // if (comboSourceType->itemData(type, Qt::UserRole - 1).toInt() == 0)
231 // {
232 // continue;
233 // }
234 if (found)
235 {
236 break;
237 }
238
239 QComboBox* combo = qobject_cast<QComboBox*>(cellWidget(row, eSourceKey));
240
241 if (combo && combo->currentIndex() > 0) // only map values that are not set already
242 {
243 break;
244 }
245
246 comboSourceType->setCurrentIndex(type);
247 if (comboSourceType->currentIndex() != type)
248 {
249 continue;
250 }
251 auto destinationKey = item(row, eDestKey)->text();
252
253
254 combo = qobject_cast<QComboBox*>(cellWidget(row, eSourceKey));
255
256 if (combo && combo->currentIndex() <= 0) // only map values that are not set already
257 {
258 int bestIndex = -1;
259 float smallestError = std::numeric_limits<float>::max();
260 for (int i = 0; i < combo->count(); i++)
261 {
262 ARMARX_DEBUG << combo->itemText(i) << " <-> " << destinationKey;
263 auto [success, error] = compare(combo->itemText(i), destinationKey);
264 if (success && error < smallestError)
265 {
266 bestIndex = i;
267 smallestError = error;
268 }
269 }
270 if (bestIndex >= 0)
271 {
272 combo->setCurrentIndex(bestIndex);
273 ARMARX_DEBUG << " setting to " << bestIndex << " of source key "
274 << combo->itemText(bestIndex);
275 found = true;
276 mappedRows.push_back(std::make_pair(destinationKey,
277 comboSourceType->currentText() + "." +
278 combo->itemText(bestIndex)));
279 }
280 }
281 }
282 if (!found)
283 {
284 comboSourceType->setCurrentIndex(oldIndex);
285 }
286 }
287 return mappedRows;
288}
289
290void
292 int tableRow,
293 QString initialValue)
294{
295 // const statechartmodel::StateParameterMap& destDict = transition->destinationState->getStateClass()->getInputParameters();
296 statechartmodel::StateParameterMap::const_iterator it = destDict.begin();
297
298 if (tableRow == -1)
299 {
300 QWidget* wid = qobject_cast<QWidget*>(sender());
301
302 if (!wid)
303 {
304 throw LocalException("Could not get row of table");
305 }
306
307 QModelIndex mIndex = indexAt(wid->pos());
308 tableRow = mIndex.row();
309 }
310
311 for (int i = 0; i < tableRow; ++i, it++)
312 {
313 }
314
316 if (index == 0)
317 {
318 QComboBox* parentInput = new NoWheelComboBox();
319
320 auto selection = getFilteredParams(parentState->getInputAndLocalParameters(), *it.value());
321 int i = 0;
322 for (auto it = selection.begin(); it != selection.end(); ++it, i++)
323 {
324 parentInput->addItem(it->first);
325 parentInput->setItemData(
326 i, it->second.isEmpty() ? "" : "Description:\n" + it->second, Qt::ToolTipRole);
327 }
328 if (initialValue.length() > 0)
329 {
330 parentInput->setCurrentIndex(parentInput->findText(initialValue));
331 }
332
333 setCellWidget(tableRow, eSourceKey, parentInput);
334 }
335 else if (index == 1)
336 {
337 if (transition->sourceState)
338 {
339 QComboBox* box = getFilteredOutputItems(it.key(), transition);
340
341 if (initialValue.length() > 0)
342 {
343 box->setCurrentIndex(box->findText(initialValue));
344 }
345
346 setCellWidget(tableRow, eSourceKey, box);
347 }
348 else
349 {
350 setCellWidget(tableRow, eSourceKey, new QWidget());
351 }
352 }
353 else if (index == 4 && ic)
354 {
355 auto destType = getInputTypeString(tableRow);
356 ARMARX_INFO_S << VAROUT(destType);
357
358 int i = 0;
359 for (statechartmodel::ParameterMappingPtr m : oldSourceMapping)
360 {
361 if (m->destinationKey == it.key())
362 {
363 break;
364 }
365 i++;
366 }
367 QMap<QString, QString> values;
368 if (i < oldSourceMapping.size())
369 {
370 statechartmodel::ParameterMappingPtr mappingEntry = oldSourceMapping[i];
371 if (mappingEntry)
372 {
373 values = mappingEntry->profileValues;
374 }
375 }
377 new MultiProfileDefaultValueEditWidget(destType, profileNames, values, ic, this);
378 setCellWidget(tableRow, eSourceKey, w);
379
380
381 // connect(datafieldInput,SIGNAL(itemSelected(QModelIndex)), this, SLOT(verifySelectedField(QModelIndex)));
382 }
383 else
384 {
385 // setCellWidget(tableRow, eSourceKey , NULL);
386 setCellWidget(tableRow, eSourceKey, new QLineEdit(initialValue));
387 // setItem(tableRow, eSourceKey, new QTableWidgetItem(initialValue));
388 }
389}
390
391QList<QPair<QString, QString>>
392TransitionMappingTable::getFilteredParams(
394 const statechartmodel::StateParameter& argumentToMatch) const
395{
396 QList<QPair<QString, QString>> items;
397
398 statechartmodel::StateParameterMap::const_iterator it = source.begin();
399
400 for (; it != source.end(); it++)
401 {
402 if (it.value()->type == argumentToMatch.type)
403 {
404 items.append(qMakePair(it.key(), it.value()->description));
405 }
406 }
407
408
409 // if (argumentToMatch.optional)
410 {
411 items.insert(0, qMakePair(tr("none"), QString("")));
412 }
413 return items;
414}
415
416QString
417TransitionMappingTable::getInputTypeString(int row)
418{
419 statechartmodel::StateParameterMap::const_iterator it = destDict.begin();
420
421 if (row == -1)
422 {
423 QWidget* wid = qobject_cast<QWidget*>(sender());
424
425 if (!wid)
426 {
427 throw LocalException("Could not get row of table");
428 }
429
430 QModelIndex mIndex = indexAt(wid->pos());
431 row = mIndex.row();
432 }
433
434 for (int i = 0; i < row; ++i, it++)
435 {
436 }
437 if (it != destDict.end())
438 {
439 return it.value()->type;
440 }
441 return "";
442}
443
444QComboBox*
445TransitionMappingTable::getFilteredOutputItems(QString key,
447{
448 QList<QString> items;
449
450 QComboBox* cbo = new NoWheelComboBox(this);
451
452 if (!transition->sourceState)
453 {
454 ARMARX_ERROR_S << ("The sourceState of the transition with event ") << transition->eventName
455 << " is NULL - output parameters are not loaded";
456 return cbo;
457 }
458
459 if (!transition->sourceState->getStateClass())
460 {
461 ARMARX_ERROR_S << ("The stateClass pointer of the sourceState named '")
462 << transition->sourceState->getInstanceName()
463 << "' of the transition is NULL - output parameters of state '"
464 << transition->sourceState->getInstanceName() << "' are not loaded";
465 return cbo;
466 }
467
469 transition->sourceState->getStateClass()->getOutputParameters();
470 // const statechartmodel::StateParameterMap& destDict = transition->destinationState->getStateClass()->getInputParameters();
471 statechartmodel::StateParameterPtr param = destDict[key];
472 statechartmodel::StateParameterMap::const_iterator it = source.begin();
473 ARMARX_DEBUG_S << "key: " << key;
474
475 if (!param)
476 {
477 return cbo;
478 }
479
480 // if (param && param->optional)
481 {
482 items.insert(0, tr("none"));
483 }
484
485 for (; it != source.end(); it++)
486 {
487 if (it.value()->type == param->type)
488 {
489 items.append(it.key());
490 }
491 }
492
493 for (auto s : items)
494 {
495 ARMARX_DEBUG_S << s;
496 }
497
498 cbo->addItems(items);
499
500 return cbo;
501}
uint8_t index
#define VAROUT(x)
void wheelEvent(QWheelEvent *e) override
NoWheelComboBox(QWidget *parent=NULL)
statechartmodel::ParameterMappingList getMapping() const
void setSourceSpecificMappingParameters(int index, int tablerow=-1, QString initialValue="")
void setup(const statechartmodel::StateParameterMap &targetDict, const statechartmodel::ParameterMappingList &sourceMapping, statechartmodel::TransitionCPtr transition, statechartmodel::StatePtr state, QStringList profileNames, Ice::CommunicatorPtr ic=NULL, VariantInfoPtr variantInfo=VariantInfoPtr())
QList< std::pair< QString, QString > > mapByCriteria(std::function< std::pair< bool, float >(QString, QString)> compare)
#define ARMARX_DEBUG_S
The logging level for output that is only interesting while debugging.
Definition Logging.h:205
#define ARMARX_ERROR_S
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:216
#define ARMARX_INFO_S
Definition Logging.h:202
#define ARMARX_VERBOSE_S
Definition Logging.h:207
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
::IceInternal::Handle<::Ice::Communicator > CommunicatorPtr
Definition IceManager.h:49
double s(double t, double s0, double v0, double a0, double j)
Definition CtrlUtil.h:33
std::shared_ptr< State > StatePtr
Definition State.h:48
QMap< QString, StateParameterPtr > StateParameterMap
std::shared_ptr< StateParameter > StateParameterPtr
QList< ParameterMappingPtr > ParameterMappingList
Definition XmlWriter.h:49
std::shared_ptr< const Transition > TransitionCPtr
Definition Transition.h:91
std::shared_ptr< ParameterMapping > ParameterMappingPtr
Definition XmlWriter.h:48
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::vector< std::string > split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
std::shared_ptr< VariantInfo > VariantInfoPtr
Definition VariantInfo.h:39
Vertex source(const detail::edge_base< Directed, Vertex > &e, const PCG &)