StateItem.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 "StateItem.h"
25 #include "TransitionItem.h"
26 
27 #include "../StateScene.h"
28 #include "../model/State.h"
29 #include "../model/Transition.h"
30 #include "../model/stateinstance/StateInstance.h"
31 #include "../model/StateMimeData.h"
32 
34 
36 
37 #include <QGraphicsProxyWidget>
38 #include <QMenu>
39 #include <QPainter>
40 #include <QtGui>
41 #include <QStyleOptionGraphicsItem>
42 #include <QGraphicsSceneContextMenuEvent>
43 #include <QMessageBox>
44 
45 
46 #define MAXFONTSIZE 300.0f
47 
48 
49 
50 namespace armarx
51 {
53  RoundRectItem(QRectF(0, 0, state->getClassSize().width(), state->getClassSize().height()),
54  // QColor(Qt::blue).lighter(190),
55  QColor(),
56  parent),
57  MorphingItem(this),
58  state(state)
59  // QGraphicsWidget(parent)
60  {
61  // if(state && state->getStateClass())
62  setAcceptDrops(true);
63  // stateScene = dynamic_cast<StateScene*>(scene());
64  setup(parent);
65  connectSlots();
67  setStateColor();
68  setRimColor();
69  setZValue(10000);
70  updateToolTip();
71  if (state->getStateClass())
72  {
73  setEditable(state->getStateClass()->isEditable());
74  }
75  }
76 
78  {
79  // ARMARX_INFO << state->getInstanceName();
80  }
81 
82  void StateItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option,
83  QWidget* widget)
84  {
85  StateItem* parentState = qgraphicsitem_cast<StateItem*>(parentItem());
86  LevelOfDetail detail = getLevelOfDetailByParent(painter, parentState);
87 
88  if (detail == eHidden) // only use scale of parent so that all sub elements of parent (states, transitions) are hidden at once and not one after the other
89  {
90  return;
91  }
92 
93 
94 
95  statechartmodel::StatePtr stateClass = state->getStateClass();
96 
97  // Draw state rect
98  RoundRectItem::paint(painter, option, widget);
99 
100  // draw substate rect for debug purposes
101  // if(state->getStateClass())
102  // painter->drawRect(QRectF(state->getStateClass()->margin.topLeft(),
103  // QPointF(state->getStateClass()->getSize().width()-state->getStateClass()->margin.width(),
104  // state->getStateClass()->getSize().height()-state->getStateClass()->margin.height())));
105  /*
106  * There are three different cases which must be differentiated:
107  * 1. Class known & substates: Show both names at top
108  * 2. Class known & no substates: Show both names centered (instance label centered, class name below)
109  * 3. Class unknown & no substates: Show class name centered
110  * (Class unknown & substates: Not possible, substates are deduced from state class)
111  */
112 
113  bool showSubstates = detail != eNoSubstates && stateClass && !stateClass->getSubstates().empty();
114 
115  bool showStateClassName = stateClass && (instanceName != stateClass->getStateName() /*|| !showSubstates*/);
116 
117  const int renderFlags = Qt::TextSingleLine | Qt::AlignTop | Qt::AlignHCenter;
118 
119  QRectF textRect = bounds;
120 
121  float instanceNameWidthRelative = showSubstates ? 0.5f : 0.8f;
122 
123 
124  float instanceNameScaleFactor = textRect.width() * instanceNameWidthRelative / painter->fontMetrics().width(instanceName);
125 
126  if (showSubstates)
127  {
128  if (showStateClassName)
129  {
130  textRect.adjust(0, 10, 0, 0);
131  }
132  else
133  {
134  textRect.adjust(0, 20, 0, 0);
135  }
136  }
137  else
138  {
139  textRect.adjust(0, (bounds.height() - painter->fontMetrics().height() * instanceNameScaleFactor) / 2, 0, 0);
140 
141  }
142 
143  qreal lodT = QStyleOptionGraphicsItem::levelOfDetailFromTransform(painter->worldTransform());
144  QFont f = painter->font();
145  QRectF maxFsize(0, 0, 0, MAXFONTSIZE);
146  f.setPointSizeF(std::min<float>(f.pointSizeF() * instanceNameScaleFactor, (maxFsize).height() / lodT));
147  painter->setFont(f);
148  float textHeightScale = 0.8;
149 
150 
151  if (showSubstates && state->getStateClass() && painter->fontMetrics().height() > 0.5 * state->getStateClass()->margin.top())
152  {
153  float margin = state->getStateClass()->margin.top();
154  float height = painter->fontMetrics().height();
155  float size = f.pointSizeF();
156  textHeightScale = margin / height;
157  if (showStateClassName)
158  {
159  textHeightScale *= 0.45;
160  }
161  else
162  {
163  textHeightScale *= 0.7;
164  }
165  f.setPointSizeF(size * textHeightScale);
166  painter->setFont(f);
167  // ARMARX_INFO << "Text to high: " << textHeightScale;
168  }
169 
170  painter->setFont(f);
171  painter->drawText(textRect, renderFlags, instanceName);
172 
173  if (showStateClassName && !stateClass->getStateName().isEmpty())
174  {
175  QString classNameText = "[state: " + stateClass->getStateName() + "]";
176  float instanceNamePointSize = f.pointSizeF();
177  float classNameScaleFactor = textRect.width() * 0.8f / painter->fontMetrics().width(classNameText);
178 
179 
180 
181  textRect.adjust(0, painter->fontMetrics().height() * 1.0, 0, 0);
182 
183  lodT = QStyleOptionGraphicsItem::levelOfDetailFromTransform(painter->worldTransform());
184  QRectF maxFsize(0, 0, 0, MAXFONTSIZE);
185  float classNamePointSize = textHeightScale * std::min<float>(f.pointSizeF() * classNameScaleFactor, (maxFsize).height() / lodT);
186  classNamePointSize = std::min(classNamePointSize, instanceNamePointSize); // never bigger than instance name
187  f.setPointSizeF(classNamePointSize);
188  painter->setFont(f);
189 
190  painter->drawText(textRect, renderFlags, classNameText);
191  }
192  }
193 
195  {
197 
198  if (signalType == statechartmodel::eChanged)
199  {
200  updateToolTip();
201  setRimColor();
202  update();
203  setSize(state->getClassSize());
204  setInstanceName(state->getInstanceName());
205  // ARMARX_WARNING_S << "Resizing " << state->getInstanceName() << VAROUT(state->getClassSize());
206  update(bounds);
207 
208  }
209  }
210 
212  {
213 
214  switch (signalType)
215  {
217  {
218  // ARMARX_INFO << "substate added: " << substate->getInstanceName();
219  StateInstanceItemMap::iterator it = subStates.find(substate);
220 
221  if (it != subStates.end())
222  {
223  ARMARX_WARNING << "substate already in list";
224  return;
225  }
226 
227  StateItem* stateItem = new StateItem(substate, this);
228  subStates.insert(substate, stateItem);
229  connect(stateItem, SIGNAL(stateItemMoved(QPointF)), substate.get(), SLOT(setPosition(QPointF)));
230  connect(stateItem, SIGNAL(stateItemBoundingBoxChanged(float)), substate.get(), SLOT(setBoundingBox(float)));
231  stateItem->setInstanceName(substate->getInstanceName());
232  stateItem->setScale(substate->getScale());
233  // ARMARX_INFO_S << "topleft: " << substate->getTopLeft();
234  stateItem->setPos(substate->getTopLeft());
235  stateItem->setSize(substate->getClassSize());
236 
237 
238  stateItem->adjustSize();
239  update();
240  // ARMARX_INFO << "Added state " << stateName << " to Scene";
241  }
242  break;
243 
245  {
246  // ARMARX_INFO << "substate changed: " << substate->getInstanceName();
247  StateInstanceItemMap::iterator it = subStates.find(substate);
248 
249  if (it == subStates.end())
250  {
251  break;
252  }
253 
254  StateItem* substateItem = it.value();
255  substateItem->setPos(substate->getTopLeft());
256  substateItem->setSize(substate->getClassSize());
257  substateItem->setScale(substate->getScale());
258  substateItem->setInstanceName(substate->getInstanceName());
259  substateItem->setStateColor();
260  substateItem->setRimColor();
262 
263  }
264  break;
265 
267  {
268 
269  }
270  break;
271 
273  {
274  // ARMARX_INFO << "Removing state " << substate->getInstanceName() << " from Scene";
275  StateInstanceItemMap::iterator it = subStates.find(substate);
276 
277  if (it == subStates.end())
278  {
279  // ARMARX_INFO << "Could not find substate";
280  break;
281  }
282 
283  QPointer<StateItem> substateItem = it.value();
284  subStates.remove(substate);
285  if (substateItem)
286  {
287  substateItem->prepareGeometryChange();
288  QObject::disconnect(substateItem);
289  delete substateItem.data();
290  }
291  }
292  break;
293 
294  default:
295  // ARMARX_INFO << "Unhandled state changed";
296  break;
297  }
298 
299  }
300 
302  {
303  // ARMARX_INFO << "Transition Changed";
304  switch (signalType)
305  {
307  {
308  TransitionItem* t = new TransitionItem(transition, this);
309  transitions.insert(transition, t);
310  t->recalcPath();
311  connect(t, SIGNAL(transitionEndPlaced(statechartmodel::TransitionCPtr, QPointF)), this, SLOT(transitionMoved(statechartmodel::TransitionCPtr, QPointF)));
313  }
314  break;
315 
317  {
318  TransitionMap::iterator it = transitions.find(transition);
319 
320  if (it == transitions.end())
321  {
322  break;
323  }
324  TransitionItem* t = it.value();
325  t->updateLabel();
326  t->recalcPath();
327  }
328  break;
329 
331  {
332  TransitionMap::iterator it = transitions.find(transition);
333 
334  if (it == transitions.end())
335  {
336  break;
337  }
338  // ARMARX_DEBUG << "Removing transition " << transition->eventName;
339  TransitionItem* t = it.value();
340  QObject::disconnect(t);
341  transitions.remove(transition);
342  // t->prepareGeometryChange();
343  delete t;
344 
345  }
346  break;
348  {
349  TransitionMap::iterator it = transitions.find(transition);
350 
351  if (it == transitions.end())
352  {
353  break;
354  }
355  int highlightDuration = 10000;
356  TransitionItem* t = it.value();
357  t->highlightAnimation(highlightDuration);
358  }
359  break;
360  default:
361 
362  break;
363  }
364  }
365 
367  {
368  TransitionMap::iterator it = transitions.begin();
369 
370  for (; it != transitions.end(); it++)
371  {
372  auto t = it.key();
373 
374  if (t->sourceState == state || t->destinationState == state)
375  {
376  notifyTransitionChanged(t, signalType);
377  }
378  }
379  }
380 
381  void StateItem::forwardTransitionContextMenuRequested(statechartmodel::TransitionCPtr transition, QPoint mouseScreenPos, QPointF mouseItemPos)
382  {
383  emit transitionContextMenuRequested(transition, state->getStateClass(), mouseScreenPos, mouseItemPos);
384  }
385 
387  {
388  TransitionMap::iterator it = transitions.find(transition);
390 
391  StateInstanceItemMap::iterator itState = subStates.begin();
392 
393  for (; itState != subStates.end(); itState++)
394  {
395  StateItem* item = itState.value();
396  QPointF dropPointMapped = item->mapFromParent(dropPoint);
397 
398  if (item->contains(dropPointMapped))
399  {
400 
401  ARMARX_IMPORTANT << "dropped on " << item->getStateInstance()->getInstanceName();
402  QList<QPointF> suppPoint;
403  suppPoint.push_back(dropPoint);
404  state->getStateClass()->updateTransitionDestination(transition, item->getStateInstance(), suppPoint);
405  return;
406  }
407  }
408 
409  state->getStateClass()->detachTransitionDestination(transition, dropPoint);
410 
411  }
412 
413 
414 
416  {
417  // ui.substatesView->fitInView( substateScene->sceneRect(), Qt::KeepAspectRatio );
418  }
419 
421  {
422  if (parentItem())
423  {
424  // ARMARX_INFO << "adjusting size";
425  // state->setBoundingBox(100);
426  // bounds.setWidth(parentItem()->boundingRect().width()*0.3);
427  // bounds.setHeight(parentItem()->boundingRect().height()*0.3);
428  }
429  }
430 
431 
432 
433  void StateItem::setup(QGraphicsItem* parent)
434  {
435 
436 
437 
438 
439  }
440 
442  {
444 
445  if (state->getStateClass())
446  {
447  connect(state->getStateClass().get(), SIGNAL(stateChanged(statechartmodel::SignalType)), this, SLOT(notifyStateChanged(statechartmodel::SignalType)));
450  connect(this, SIGNAL(stateItemResized(QSizeF)), state->getStateClass().get(), SLOT(setSize(QSizeF)));
451 
452  }
453 
454  if (scene())
455  {
456  QVariant v;
457  v.setValue(scene());
458  itemChange(ItemSceneChange, v);
459  }
460 
461  }
462 
464  {
467 
468  if (!state->getStateClass())
469  {
470  return;
471  }
472 
473  const auto& ts = state->getStateClass()->getTransitions(true);
474 
475  for (int i = 0; i < ts.size(); i++)
476  {
478  }
479 
480  const auto& sl = state->getStateClass()->getSubstates();
481 
482  for (auto i = sl.begin(); i != sl.end(); i++)
483  {
485  }
486 
487 
488  }
489 
490 
491 
493  {
494  if (!state)
495  {
496  return;
497  }
498  int level = getInstanceLevel();
499  switch (state->getType())
500  {
501  case eNormalState:
502  {
503  QColor color(52, 152, 219);
504  if (level % 2 == 0)
505  {
506  color = color.lighter(130);
507  }
508  else
509  {
510  color = color.lighter(110);
511  }
512  setColor(color);
513  }
514  break;
515 
516  case eRemoteState:
517  {
518  QColor color(26, 188, 156);
519  if (level % 2 == 0)
520  {
521  color = color.lighter(130);
522  }
523  else
524  {
525  color = color.lighter(110);
526  }
527  setColor(color);
528  }
529  break;
530 
531  case eDynamicRemoteState:
532  setColor(QColor(155, 89, 182));
533  break;
534 
535  case eFinalState:
536  {
537  QColor color(241, 196, 15);
538  color = color.lighter(120);
539  setColor(color);
540  }
541 
542 
543  default:
544  break;
545 
546  }
547  }
548 
550  {
551  if ((state
552  && state->isActive()) || active)
553  {
554  setRimPen(QPen(Qt::red, 10));
555  }
556  else
557  {
558  setRimPen(QPen(Qt::black, 2));
559  }
560  update();
561  }
562 
564  {
565  QString tip;
566  if (state)
567  {
568  tip = "StateType: " + statechartmodel::State::StateTypeToString(state->getType());
569  if (state->getStateClass())
570  {
571  auto desc = state->getStateClass()->getDescription();
572  if (!desc.isEmpty())
573  {
574  tip += "\n" + desc;
575  }
576  }
577  }
578  setToolTip(tip);
579  }
580 
582  {
583  auto curScene = scene();
584  if (curScene)
585  {
586  for (auto& t : transitions)
587  {
588  // t->prepareGeometryChange();
589  curScene->removeItem(t);
590  }
591  }
592  for (auto& s : subStates)
593  {
594  s->prepareGeometryChange();
595  s->removeChildren();
596  if (curScene)
597  {
598  curScene->removeItem(s);
599  }
600  }
601  }
602 
604  {
605  int level = 0;
606  const QGraphicsItem* parent = this;
607  while (dynamic_cast<StateItem*>(parent->parentItem()))
608  {
609  parent = parent->parentItem();
610  level++;
611  }
612  return level;
613  }
614 
615  QPointF StateItem::adjustPosition(QPointF& newPos)
616  {
617  if (state)
618  {
619  return state->adjustPosition(newPos);
620  }
621  ARMARX_INFO << "state ptr is null";
622  return newPos;
623  }
624 
626  {
627  return maxShownSubstateLevel;
628  }
629 
631  {
633  for (auto& substate : subStates)
634  {
635  substate->setMaxShownSubstateLevel(value);
636  }
637  for (auto& item : childItems())
638  {
639  item->update();
640  }
641  }
642 
643  void StateItem::setActiveSubstate(const QString& substateName)
644  {
645  auto substates = getSubstateItems();
646  for (auto substate : substates)
647  {
648  bool active = (substate->getInstanceName() == substateName);
649  substate->setActiveState(active);
650  }
651  }
652 
654  {
655  auto substates = getSubstateItems();
656  for (auto substate : substates)
657  {
658  substate->setActiveState(false);
659  }
660  }
661 
663  {
664  QString path = instanceName;
665  StateItem* parent = qgraphicsitem_cast<StateItem*>(parentItem());
666  while (parent)
667  {
668  path = parent->getInstanceName() + "/" + path;
669  parent = qgraphicsitem_cast<StateItem*>(parent->parentItem());
670  }
671  return path;
672  }
673 
675  {
676  StateItem* parent = qgraphicsitem_cast<StateItem*>(parentItem());
677  return parent;
678  }
679 
680  QVector<StateItem*> StateItem::getSubstateItems() const
681  {
682  QVector<StateItem*> result;
683  for (QGraphicsItem* item : this->childItems())
684  {
685  StateItem* state = dynamic_cast<StateItem*>(item);
686  if (state)
687  {
688  result.push_back(state);
689  }
690  }
691  return result;
692  }
693 
694  QVector<TransitionItem*> StateItem::getTransitionItems() const
695  {
696  QVector<TransitionItem*> result;
697  for (QGraphicsItem* item : this->childItems())
698  {
699  TransitionItem* transition = dynamic_cast<TransitionItem*>(item);
700  if (transition)
701  {
702  result.push_back(transition);
703  }
704  }
705  return result;
706  }
707 
709  {
710  return instanceName;
711  }
712 
713  void StateItem::setInstanceName(const QString& value)
714  {
715  if (value != instanceName)
716  {
718  update();
719  }
720  }
721 
722  void StateItem::setActiveState(bool active)
723  {
724  this->active = active;
725  setRimColor();
726  }
727 
728  bool StateItem::itemResizing(const QRectF& oldSize, QRectF& proposedSize)
729  {
730  if (!state->getStateClass())
731  {
732  return false;
733  }
734 
735  return true;
736  }
737 
738 
739 
740  void StateItem::itemResized(const QRectF& oldSize, const QRectF& newSize)
741  {
742  if (oldSize != newSize)
743  {
744  emit stateItemResized(newSize.size());
745  }
746  }
747 
748  void StateItem::itemMoved(const QPointF& oldPos, const QPointF& newPos)
749  {
750  // ARMARX_INFO << VAROUT(oldPos) << " " << VAROUT(newPos);
751  if (oldPos != newPos)
752  {
753  // ARMARX_INFO << "Changed";
754  emit stateItemMoved(newPos);
755 
756  }
757  }
758 
759  void StateItem::itemBoundingBoxChanged(float oldSize, float size)
760  {
761 
762  if (oldSize != size)
763  {
764  // ARMARX_INFO << VAROUT(oldSize) << " newBB: " << size;
765  emit stateItemBoundingBoxChanged(size);
766  }
767  }
768 
769 
770  void StateItem::contextMenuEvent(QGraphicsSceneContextMenuEvent* event)
771  {
772  if (isLevelOfDetailLow(event))
773  {
774  event->ignore();
775  ARMARX_DEBUG << "Ignoring context menu event on " << state->getInstanceName();
776  return;
777  }
778  if (scene())
779  {
780  scene()->clearSelection();
781  }
782 
783  this->setSelected(true);
784  emit stateContextMenuRequested(state, event->screenPos(), event->pos());
785  event->accept();
786  }
787 
788 
789  QVariant StateItem::itemChange(GraphicsItemChange change, const QVariant& value)
790  {
791  if (change == ItemSelectedHasChanged && value.toBool() == true)
792  {
793  // ARMARX_IMPORTANT << state->getInstanceName() << " was selected with scale " << scale();
794  // setScale(scale()*1.1);
795  }
796  else if (change == ItemSelectedHasChanged && value.toBool() == false)
797  {
798  // ARMARX_IMPORTANT << state->getInstanceName() << " was UNselected";
799  // setScale(scale()*0.9);
800  }
801  else if (change == ItemScaleHasChanged)
802  {
803  emit stateItemBoundingBoxChanged(std::max(bounds.width(), bounds.height())*value.toFloat());
804  // itemBoundingBoxChanged(std::max(oldRect.width(), oldRect.height()),
805  // std::max(bounds.width(), bounds.height()));
806  // emit stateItemScaled(value.toFloat());
807  }
808  else if (change == ItemSceneChange)
809  {
810  StateScene* oldStateScene = dynamic_cast<StateScene*>(scene());
811 
812  if (oldStateScene)
813  {
814  disconnect(this, SIGNAL(stateContextMenuRequested(statechartmodel::StateInstancePtr, QPoint, QPointF)), oldStateScene, SIGNAL(stateContextMenuRequested(statechartmodel::StateInstancePtr, QPoint, QPointF)));
816  }
817 
818  StateScene* stateScene = dynamic_cast<StateScene*>(value.value<QGraphicsScene*>());
819 
820  if (stateScene)
821  {
822  // ARMARX_INFO_S << "scene OF " << state->getInstanceName() << " has changed - StateScene";
823  connect(this, SIGNAL(stateContextMenuRequested(statechartmodel::StateInstancePtr, QPoint, QPointF)),
827  }
828 
829  // else
830  // ARMARX_INFO_S << "scene OF " << state->getInstanceName() << " has changed - noScene";
831  }
832 
833  return RoundRectItem::itemChange(change, value);
834  }
835 
836  void StateItem::dragEnterEvent(QGraphicsSceneDragDropEvent* event)
837  {
838  // ARMARX_INFO << "Drag Enter event " << state->getInstanceName();
839  const AbstractStateMimeData* data = qobject_cast<const AbstractStateMimeData*>(event->mimeData());
840 
841  if (data && state && state->getStateClass() && data->getState() && state->getType() == eNormalState)
842  {
843  event->setDropAction(Qt::LinkAction);
844  }
845  else
846  {
847  event->setDropAction(Qt::IgnoreAction);
848  }
849 
850  event->accept();
851  }
852 
853  void StateItem::dragMoveEvent(QGraphicsSceneDragDropEvent* event)
854  {
855  dragEnterEvent(event);
856  }
857 
858 
859 
860  void StateItem::dropEvent(QGraphicsSceneDragDropEvent* event)
861  {
862  // ARMARX_INFO << "drop event " << state->getInstanceName();
863  if (event->proposedAction() == Qt::IgnoreAction)
864  {
865  return;
866  }
867 
868  const AbstractStateMimeData* data = qobject_cast<const AbstractStateMimeData*>(event->mimeData());
869  bool accept = true;
870  if (data && state && state->getStateClass() && data->getState()
871  && (state->getType() == eNormalState || state->getType() == eRemoteState))
872  {
873  int i = 2;
874  const QString newStateNameBase = data->getState()->getStateName();
875  QString newStateName = newStateNameBase;
876 
877  while (state->getStateClass()->getSubstates().find(newStateName) != state->getStateClass()->getSubstates().end())
878  {
879  newStateName = newStateNameBase + "_" + QString::number(i);
880  i++;
881  }
882 
883  if (hasAncestor(data->getState()) || data->getState()->hasDescendant(state->getStateClass()))
884  {
885  QMessageBox::warning(event->source(), "State drag'n'drop error", "State cycle detected - you must not insert a state which is also a parent state of the current state");
886  accept = false;
887  }
888  else if (data->getState()->getType() == eDynamicRemoteState && !data->isInSameGroup(state->getStateClass()))
889  {
890  QMessageBox::warning(event->source(), "State drag'n'drop error", "Dynamic Remote States can only be added in the same group.");
891  accept = false;
892  }
893  else if (data->isInSameGroup(state->getStateClass()))
894  {
895  if (data->getState()->getType() == eDynamicRemoteState)
896  {
897  state->getStateClass()->addDynamicRemoteSubstate(data->getState(), newStateName, event->pos());
898  }
899  else
900  {
901  state->getStateClass()->addSubstate(data->getState(), newStateName, event->pos());
902  }
903  }
904  else if (data->isPublic())
905  {
906  state->getStateClass()->addRemoteSubstate(data->getState(), data->getProxyName(), newStateName, event->pos());
907  }
908  else
909  {
910  QMessageBox::warning(event->source(), "State drag'n'drop error", "Only public states can be added as a Remote State.");
911  accept = false;
912  }
913 
914 
915  }
916  else
917  {
918  accept = false;
919  }
920 
921 
922  if (accept)
923  {
924  event->setDropAction(Qt::LinkAction);
925  event->accept();
926  }
927  else
928  {
929  event->setDropAction(Qt::IgnoreAction);
930  event->accept();
931  }
932  }
933 
935  {
936  if (!sC)
937  {
938  return false;
939  }
940 
941  StateItem* state = qgraphicsitem_cast<StateItem*>(parentItem());
942  if (!state)
943  {
944  return false;
945  }
946  if (!state->getStateInstance() || !state->getStateInstance()->getStateClass())
947  {
948  return false;
949  }
950 
951  if (state->getStateInstance()->getStateClass()->getUUID() == sC->getUUID())
952  {
953  return true;
954  }
955 
956  return state->hasAncestor(sC);
957  }
958 
960  {
961  if (!sC || !state->getStateClass())
962  {
963  return false;
964  }
965  return state->getStateClass()->hasDescendant(sC);
966 
967 
968  }
969  LevelOfDetail StateItem::getLevelOfDetail(float levelOfDetail) const
970  {
971  if (maxShownSubstateLevel >= 0) // only show X levels of substates
972  {
973  int level = getInstanceLevel();
974  if (level > maxShownSubstateLevel)
975  {
976  return eHidden;
977  }
978  else if (level >= maxShownSubstateLevel)
979  {
980  return eNoSubstates;
981  }
982  }
983  return MorphingItem::getLevelOfDetail(levelOfDetail);
984  }
985 }
armarx::AbstractStateMimeData
The AbstractStateMimeData class is used to transport state data from the treeview to the stateview an...
Definition: StateMimeData.h:36
armarx::AbstractStateMimeData::isInSameGroup
virtual bool isInSameGroup(statechartmodel::StatePtr state) const =0
RoundRectItem::isLevelOfDetailLow
bool isLevelOfDetailLow(QGraphicsSceneEvent *event) const
Definition: RoundRectItem.cpp:445
armarx::StateItem::viewAll
void viewAll()
Definition: StateItem.cpp:415
armarx::StateItem::dragEnterEvent
void dragEnterEvent(QGraphicsSceneDragDropEvent *event) override
Definition: StateItem.cpp:836
armarx::StateItem::StateItem
StateItem(statechartmodel::StateInstancePtr state, QGraphicsItem *parent=0)
Definition: StateItem.cpp:52
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:183
armarx::StateItem::getInstanceName
QString getInstanceName() const
Definition: StateItem.cpp:708
armarx::TransitionItem::updateLabel
void updateLabel()
Definition: TransitionItem.cpp:276
armarx::StateItem::state
statechartmodel::StateInstancePtr state
Definition: StateItem.h:126
armarx::MorphingItem::getLevelOfDetail
virtual LevelOfDetail getLevelOfDetail(QPainter *painter) const
Definition: MorphingItem.cpp:48
armarx::StateItem::setActiveSubstate
void setActiveSubstate(const QString &substateName)
Definition: StateItem.cpp:643
RoundRectItem::setEditable
void setEditable(bool editable)
Definition: RoundRectItem.cpp:483
armarx::StateItem::getLevelOfDetail
LevelOfDetail getLevelOfDetail(float levelOfDetail) const override
Definition: StateItem.cpp:969
armarx::AbstractStateMimeData::getState
statechartmodel::StatePtr getState() const
Definition: StateMimeData.cpp:78
armarx::StateItem::getStateInstance
statechartmodel::StateInstancePtr getStateInstance() const
Definition: StateItem.h:70
armarx::StateItem::itemBoundingBoxChanged
void itemBoundingBoxChanged(float oldSize, float size) override
Definition: StateItem.cpp:759
RoundRectItem::itemChange
QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override
Definition: RoundRectItem.cpp:488
StateItem.h
armarx::statechartmodel::eUnchanged
@ eUnchanged
Definition: SignalType.h:36
armarx::StateItem::setActiveState
void setActiveState(bool active)
Definition: StateItem.cpp:722
detail
Definition: OpenCVUtil.cpp:127
armarx::statechartmodel::State::StateTypeToString
static QString StateTypeToString(eStateType type)
Definition: State.cpp:1188
armarx::StateItem::notifyTransitionsChanged
void notifyTransitionsChanged(statechartmodel::StateInstancePtr transition, statechartmodel::SignalType signalType)
Definition: StateItem.cpp:366
armarx::StateItem::getInstanceLevel
int getInstanceLevel() const
Definition: StateItem.cpp:603
RoundRectItem::setRimPen
void setRimPen(QPen newPen)
Definition: RoundRectItem.cpp:73
armarx::MorphingItem
Definition: MorphingItem.h:39
armarx::StateItem::maxShownSubstateLevel
int maxShownSubstateLevel
Definition: StateItem.h:132
armarx::StateItem::~StateItem
~StateItem() override
Definition: StateItem.cpp:77
RoundRectItem::paint
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=0) override
Definition: RoundRectItem.cpp:110
armarx::StateItem::hasAncestor
bool hasAncestor(statechartmodel::StatePtr state) const
Definition: StateItem.cpp:934
armarx::StateItem::setRimColor
void setRimColor()
Definition: StateItem.cpp:549
armarx::statechartmodel::StateInstancePtr
std::shared_ptr< StateInstance > StateInstancePtr
Definition: StateInstance.h:138
armarx::StateItem::instanceName
QString instanceName
Definition: StateItem.h:129
armarx::TransitionItem::recalcPath
void recalcPath()
Definition: TransitionItem.cpp:129
armarx::StateItem::clearActiveSubstate
void clearActiveSubstate()
Definition: StateItem.cpp:653
armarx::eHidden
@ eHidden
Definition: MorphingItem.h:37
armarx::StateItem::stateScene
StateScene * stateScene
Definition: StateItem.h:125
armarx::StateItem::transitionContextMenuRequested
void transitionContextMenuRequested(statechartmodel::TransitionCPtr transition, statechartmodel::StatePtr state, QPoint mouseScreenPos, QPointF mouseItemPos)
armarx::StateItem::setMaxShownSubstateLevel
void setMaxShownSubstateLevel(int value)
Definition: StateItem.cpp:630
armarx::StateItem::getFullStatePath
QString getFullStatePath() const
Definition: StateItem.cpp:662
armarx::StateItem::getMaxShownSubstateLevel
int getMaxShownSubstateLevel() const
Definition: StateItem.cpp:625
armarx::StateItem::itemChange
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override
Definition: StateItem.cpp:789
armarx::StateItem::dropEvent
void dropEvent(QGraphicsSceneDragDropEvent *event) override
Definition: StateItem.cpp:860
armarx::StateItem::setStateColor
void setStateColor()
Definition: StateItem.cpp:492
armarx::TransitionItem::highlightAnimation
void highlightAnimation(int duration=5000)
Definition: TransitionItem.cpp:262
armarx::StateItem::removeChildren
void removeChildren()
Definition: StateItem.cpp:581
armarx::StateItem::stateItemMoved
void stateItemMoved(QPointF newPosition)
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::StateItem::stateItemBoundingBoxChanged
void stateItemBoundingBoxChanged(float newSquareBoundingBoxSize)
armarx::AbstractStateMimeData::getProxyName
const QString & getProxyName() const
Definition: StateMimeData.cpp:68
armarx::StateItem::subStates
StateInstanceItemMap subStates
Definition: StateItem.h:128
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
armarx::StateItem::transitions
TransitionMap transitions
Definition: StateItem.h:131
armarx::StateItem::adjustPosition
QPointF adjustPosition(QPointF &newPos) override
Definition: StateItem.cpp:615
armarx::StateItem::forwardTransitionContextMenuRequested
void forwardTransitionContextMenuRequested(statechartmodel::TransitionCPtr transition, QPoint mouseScreenPos, QPointF mouseItemPos)
Definition: StateItem.cpp:381
armarx::StateItem::getTransitionItems
QVector< TransitionItem * > getTransitionItems() const
Definition: StateItem.cpp:694
RoundRectItem::setColor
void setColor(QColor newColor)
Definition: RoundRectItem.cpp:63
max
T max(T t1, T t2)
Definition: gdiam.h:48
armarx::statechartmodel::eAdded
@ eAdded
Definition: SignalType.h:35
armarx::StateItem::setup
void setup(QGraphicsItem *parent)
Definition: StateItem.cpp:433
armarx::statechartmodel::eActivated
@ eActivated
Definition: SignalType.h:38
armarx::StateItem::paint
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
Definition: StateItem.cpp:82
armarx::StateItem::notifyStateChanged
void notifyStateChanged(statechartmodel::SignalType signalType)
Definition: StateItem.cpp:194
armarx::TransitionItem
Definition: TransitionItem.h:44
armarx::MorphingItem::getLevelOfDetailByParent
virtual LevelOfDetail getLevelOfDetailByParent(QPainter *painter, MorphingItem *parent) const
Definition: MorphingItem.cpp:77
armarx::armem::server::ltm::util::mongodb::detail::update
bool update(mongocxx::collection &coll, const nlohmann::json &query, const nlohmann::json &update)
Definition: mongodb.cpp:67
armarx::red
QColor red()
Definition: StyleSheets.h:76
TransitionItem.h
ExpressionException.h
armarx::StateItem::itemResizing
bool itemResizing(const QRectF &oldSize, QRectF &proposedSize) override
Definition: StateItem.cpp:728
option
#define option(type, fn)
armarx::StateItem::notifyTransitionChanged
void notifyTransitionChanged(statechartmodel::TransitionCPtr transition, statechartmodel::SignalType signalType)
Definition: StateItem.cpp:301
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
RoundRectItem
Definition: RoundRectItem.h:34
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
armarx::statechartmodel::eRemoved
@ eRemoved
Definition: SignalType.h:40
ArmarXWidgetController.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::StateItem::stateContextMenuRequested
void stateContextMenuRequested(statechartmodel::StateInstancePtr stateInstace, QPoint mouseScreenPos, QPointF mouseItemPos)
armarx::statechartmodel::SignalType
SignalType
The SignalType enum.
Definition: SignalType.h:33
armarx::StateItem::itemMoved
void itemMoved(const QPointF &oldPos, const QPointF &newPos) override
Definition: StateItem.cpp:748
RoundRectItem::bounds
QRectF bounds
Definition: RoundRectItem.h:78
armarx::StateItem::transitionMoved
void transitionMoved(statechartmodel::TransitionCPtr transition, QPointF dropPoint)
Definition: StateItem.cpp:386
armarx::statechartmodel::TransitionCPtr
std::shared_ptr< const Transition > TransitionCPtr
Definition: Transition.h:94
armarx::StateItem::dragMoveEvent
void dragMoveEvent(QGraphicsSceneDragDropEvent *event) override
Definition: StateItem.cpp:853
armarx::AbstractStateMimeData::isPublic
virtual bool isPublic() const =0
armarx::statechartmodel::StatePtr
std::shared_ptr< State > StatePtr
Definition: State.h:46
armarx::StateItem
Definition: StateItem.h:58
armarx::statechartmodel::eChanged
@ eChanged
Definition: SignalType.h:37
armarx::StateItem::updateToolTip
void updateToolTip()
Definition: StateItem.cpp:563
armarx::LevelOfDetail
LevelOfDetail
Definition: MorphingItem.h:33
armarx::StateItem::active
bool active
Definition: StateItem.h:133
min
T min(T t1, T t2)
Definition: gdiam.h:42
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::StateItem::hasDescendant
bool hasDescendant(statechartmodel::StatePtr state) const
Definition: StateItem.cpp:959
armarx::eNoSubstates
@ eNoSubstates
Definition: MorphingItem.h:36
MAXFONTSIZE
#define MAXFONTSIZE
Definition: StateItem.cpp:46
armarx::StateScene
Definition: StateScene.h:53
armarx::StateItem::setInstanceName
void setInstanceName(const QString &value)
Definition: StateItem.cpp:713
armarx::StateItem::adjustSize
void adjustSize()
Definition: StateItem.cpp:420
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::StateItem::connectSlots
void connectSlots()
Definition: StateItem.cpp:441
armarx::StateItem::getParentStateItem
StateItem * getParentStateItem() const
Definition: StateItem.cpp:674
armarx::StateItem::notifySubstateChanged
void notifySubstateChanged(statechartmodel::StateInstancePtr substate, statechartmodel::SignalType signalType)
Definition: StateItem.cpp:211
armarx::StateItem::contextMenuEvent
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override
Definition: StateItem.cpp:770
armarx::StateItem::getSubstateItems
QVector< StateItem * > getSubstateItems() const
Definition: StateItem.cpp:680
RoundRectItem::setSize
void setSize(const QSizeF &newSize)
Definition: RoundRectItem.cpp:96
armarx::StateItem::itemResized
void itemResized(const QRectF &oldSize, const QRectF &newSize) override
Definition: StateItem.cpp:740
armarx::StateItem::initialCreation
void initialCreation()
Definition: StateItem.cpp:463
armarx::StateItem::stateItemResized
void stateItemResized(QSizeF newSize)