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