1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #pragma once
27 
28 #include "transitionwarningitem.h"
29 #include <QGraphicsSceneMouseEvent>
30 #include <QKeyEvent>
31 #include <QPen>
32 #include <QPointF>
33 #include <QPolygon>
34 #include <QRectF>
35 #include <QVector>
36 
37 namespace ScxmlEditor {
38 
39 namespace PluginInterface {
40 
41 class CornerGrabberItem;
42 class TagTextItem;
43 class ConnectableItem;
44 
45 /**
46  * @brief The TransitionItem class provides the item to connect two Connectable-items.
47  */
48 class TransitionItem : public BaseItem
49 {
50     Q_OBJECT
51 
52 public:
53     explicit TransitionItem(BaseItem *parent = nullptr);
54     ~TransitionItem() override;
55 
56     enum TransitionTargetType {
57         InternalSameTarget = 0,
58         InternalNoTarget,
59         ExternalNoTarget,
60         ExternalTarget
61     };
62 
63     enum TransitionPoint {
64         Start = 0,
65         End
66     };
67 
68     /**
69      * @brief type - return tye type of the item.
70      */
type()71     int type() const override
72     {
73         return TransitionType;
74     }
75 
76     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
77     QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
78     bool sceneEventFilter(QGraphicsItem *watched, QEvent *event) override;
79 
80     void disconnectItem(ConnectableItem *item);
81     void setStartItem(ConnectableItem *item);
82     void setEndItem(ConnectableItem *item, bool fixValue = true);
83 
84     void startTransitionFrom(ConnectableItem *item, const QPointF &mouseScenePos);
85     void setEndPos(const QPointF &endPos, bool snap = true);
86     void connectToTopItem(const QPointF &pos, TransitionPoint p, ItemType targetType);
87 
88     bool isStartItem(const ConnectableItem *item) const;
89     bool isEndItem(const ConnectableItem *item) const;
90     ConnectableItem *connectedItem(const ConnectableItem *other) const;
91 
92     bool hasStartItem() const;
93     bool hasEndItem() const;
94 
95     void init(ScxmlTag *tag, BaseItem *parentItem = nullptr, bool initChildren = true, bool blockUpdates = false) override;
96     void updateEditorInfo(bool allChilds = true) override;
97     void updateAttributes() override;
98     void updateTarget(bool fixValue = true);
99     void finalizeCreation() override;
100     void checkVisibility(double scaleFactor) override;
101     bool containsScenePoint(const QPointF &p) const override;
102 
103     void updateUIProperties() override;
104     void updateTargetType();
105     void setTag(ScxmlTag *tag) override;
106     qreal textWidth() const;
107     QRectF wholeBoundingRect() const;
108 
targetType()109     TransitionTargetType targetType() const
110     {
111         return m_targetType;
112     }
113 
114     void grabMouse(ItemType targetType);
115     void storeGeometry(bool block = false);
116     void storeValues(bool block = false);
117     void updateComponents();
118     void textItemPositionChanged();
119 
120 protected:
121     void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
122     void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
123     void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
124     void keyPressEvent(QKeyEvent *event) override;
125     void updateToolTip();
126     void readUISpecifiedProperties(const ScxmlTag *tag) override;
127     void checkSelectionBeforeContextMenu(QGraphicsSceneMouseEvent *e) override;
128     void createContextMenu(QMenu *menu) override;
129     void selectedMenuAction(const QAction *action) override;
130 
131 private:
132     void textHasChanged(const QString &text);
133     void checkWarningItems();
134     void storeMovePoint(bool block = false);
135     void storeTargetFactors(bool block = false);
136     void updateZValue();
137     void removeUnnecessaryPoints();
138     void findEndItem();
139     void updateEventName();
140     void createGrabbers();
141     void removeGrabbers();
142     void updateGrabberPositions();
143     void removeTransition(TransitionPoint p);
144     void snapToAnyPoint(int index, const QPointF &newPoint, int diff = 8);
145     void snapPointToPoint(int index, const QPointF &newPoint, int diff = 8);
146     QPointF loadPoint(const QString &name);
147     void savePoint(const QPointF &p, const QString &name);
148     QPointF calculateTargetFactor(ConnectableItem *item, const QPointF &pos);
149     QPointF sceneTargetPoint(TransitionPoint p);
150     QPointF findIntersectionPoint(ConnectableItem *item, const QLineF &line, const QPointF &defaultPoint);
151     QVector<CornerGrabberItem*> m_cornerGrabbers;
152     CornerGrabberItem *m_selectedCornerGrabber = nullptr;
153 
154     QPolygonF m_cornerPoints;
155 
156     ConnectableItem *m_startItem = nullptr;
157     ConnectableItem *m_oldStartItem = nullptr;
158     ConnectableItem *m_endItem = nullptr;
159 
160     QPolygonF m_arrow;
161     qreal m_arrowSize = 10;
162     qreal m_arrowAngle;
163     QPen m_pen;
164     QPen m_highlightPen;
165     bool m_lineSelected = false;
166 
167     TagTextItem *m_eventTagItem;
168     TransitionWarningItem *m_warningItem = nullptr;
169     TransitionTargetType m_targetType = ExternalTarget;
170     bool m_movingFirstPoint = false;
171     bool m_movingLastPoint = false;
172     bool m_mouseGrabbed = false;
173     ItemType m_grabbedTargetType = UnknownType;
174     int m_selectedGrabberIndex = -1;
175     QPointF m_startTargetFactor;
176     QPointF m_endTargetFactor;
177 };
178 
179 } // namespace PluginInterface
180 } // namespace ScxmlEditor
181