1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Designer of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29//
30// W A R N I N G
31// -------------
32//
33// This file is not part of the Qt API. It exists for the convenience
34// of Qt Designer. This header
35// file may change from version to version without notice, or even be removed.
36//
37// We mean it.
38//
39
40
41#ifndef CONNECTIONEDIT_H
42#define CONNECTIONEDIT_H
43
44#include "shared_global_p.h"
45
46#include <QtCore/qhash.h>
47#include <QtCore/qlist.h>
48#include <QtCore/qvector.h>
49#include <QtCore/qpointer.h>
50
51#include <QtWidgets/qwidget.h>
52#include <QtGui/qpixmap.h>
53#include <QtGui/qpolygon.h>
54
55#include <QtWidgets/qundostack.h>
56
57QT_BEGIN_NAMESPACE
58
59class QDesignerFormWindowInterface;
60class QUndoStack;
61class QMenu;
62
63namespace qdesigner_internal {
64
65class Connection;
66class ConnectionEdit;
67
68class QDESIGNER_SHARED_EXPORT CETypes
69{
70public:
71 using ConnectionList = QVector<Connection *>;
72 using ConnectionSet = QHash<Connection*, Connection*> ;
73 using WidgetSet = QHash<QWidget*, QWidget*>;
74
75 class EndPoint {
76 public:
77 enum Type { Source, Target };
78 explicit EndPoint(Connection *_con = nullptr, Type _type = Source) : con(_con), type(_type) {}
79 bool isNull() const { return con == nullptr; }
80 bool operator == (const EndPoint &other) const { return con == other.con && type == other.type; }
81 bool operator != (const EndPoint &other) const { return !operator == (other); }
82 Connection *con;
83 Type type;
84 };
85 enum LineDir { UpDir = 0, DownDir, RightDir, LeftDir };
86};
87
88class QDESIGNER_SHARED_EXPORT Connection : public CETypes
89{
90public:
91 explicit Connection(ConnectionEdit *edit);
92 explicit Connection(ConnectionEdit *edit, QObject *source, QObject *target);
93 virtual ~Connection() = default;
94
95 QObject *object(EndPoint::Type type) const
96 {
97 return (type == EndPoint::Source ? m_source : m_target);
98 }
99
100 QWidget *widget(EndPoint::Type type) const
101 {
102 return qobject_cast<QWidget*>(o: object(type));
103 }
104
105 QPoint endPointPos(EndPoint::Type type) const;
106 QRect endPointRect(EndPoint::Type) const;
107 void setEndPoint(EndPoint::Type type, QObject *w, const QPoint &pos)
108 { type == EndPoint::Source ? setSource(source: w, pos) : setTarget(target: w, pos); }
109
110 bool isVisible() const;
111 virtual void updateVisibility();
112 void setVisible(bool b);
113
114 virtual QRegion region() const;
115 bool contains(const QPoint &pos) const;
116 virtual void paint(QPainter *p) const;
117
118 void update(bool update_widgets = true) const;
119 void checkWidgets();
120
121 QString label(EndPoint::Type type) const
122 { return type == EndPoint::Source ? m_source_label : m_target_label; }
123 void setLabel(EndPoint::Type type, const QString &text);
124 QRect labelRect(EndPoint::Type type) const;
125 QPixmap labelPixmap(EndPoint::Type type) const
126 { return type == EndPoint::Source ? m_source_label_pm : m_target_label_pm; }
127
128 ConnectionEdit *edit() const { return m_edit; }
129
130 virtual void inserted() {}
131 virtual void removed() {}
132
133private:
134 QPoint m_source_pos, m_target_pos;
135 QObject *m_source, *m_target;
136 QVector<QPoint> m_knee_list;
137 QPolygonF m_arrow_head;
138 ConnectionEdit *m_edit;
139 QString m_source_label, m_target_label;
140 QPixmap m_source_label_pm, m_target_label_pm;
141 QRect m_source_rect, m_target_rect;
142 bool m_visible;
143
144 void setSource(QObject *source, const QPoint &pos);
145 void setTarget(QObject *target, const QPoint &pos);
146 void updateKneeList();
147 void trimLine();
148 void updatePixmap(EndPoint::Type type);
149 LineDir labelDir(EndPoint::Type type) const;
150 bool ground() const;
151 QRect groundRect() const;
152};
153
154class QDESIGNER_SHARED_EXPORT ConnectionEdit : public QWidget, public CETypes
155{
156 Q_OBJECT
157public:
158 ConnectionEdit(QWidget *parent, QDesignerFormWindowInterface *form);
159 ~ConnectionEdit() override;
160
161 inline const QPointer<QWidget> &background() const { return m_bg_widget; }
162
163 void setSelected(Connection *con, bool sel);
164 bool selected(const Connection *con) const;
165
166 int connectionCount() const { return m_con_list.size(); }
167 Connection *connection(int i) const { return m_con_list.at(i); }
168 int indexOfConnection(Connection *con) const { return m_con_list.indexOf(t: con); }
169
170 virtual void setSource(Connection *con, const QString &obj_name);
171 virtual void setTarget(Connection *con, const QString &obj_name);
172
173 QUndoStack *undoStack() const { return m_undo_stack; }
174
175 void clear();
176
177 void showEvent(QShowEvent * /*e*/) override
178 {
179 updateBackground();
180 }
181
182signals:
183 void aboutToAddConnection(int idx);
184 void connectionAdded(Connection *con);
185 void aboutToRemoveConnection(Connection *con);
186 void connectionRemoved(int idx);
187 void connectionSelected(Connection *con);
188 void widgetActivated(QWidget *wgt);
189 void connectionChanged(Connection *con);
190
191public slots:
192 void selectNone();
193 void selectAll();
194 virtual void deleteSelected();
195 virtual void setBackground(QWidget *background);
196 virtual void updateBackground();
197 virtual void widgetRemoved(QWidget *w);
198 virtual void objectRemoved(QObject *o);
199
200 void updateLines();
201 void enableUpdateBackground(bool enable);
202
203protected:
204 void paintEvent(QPaintEvent *e) override;
205 void mouseMoveEvent(QMouseEvent *e) override;
206 void mousePressEvent(QMouseEvent *e) override;
207 void mouseReleaseEvent(QMouseEvent *e) override;
208 void keyPressEvent(QKeyEvent *e) override;
209 void mouseDoubleClickEvent(QMouseEvent *e) override;
210 void resizeEvent(QResizeEvent *e) override;
211 void contextMenuEvent(QContextMenuEvent * event) override;
212
213 virtual Connection *createConnection(QWidget *source, QWidget *target);
214 virtual void modifyConnection(Connection *con);
215
216 virtual QWidget *widgetAt(const QPoint &pos) const;
217 virtual void createContextMenu(QMenu &menu);
218 void addConnection(Connection *con);
219 QRect widgetRect(QWidget *w) const;
220
221 enum State { Editing, Connecting, Dragging };
222 State state() const;
223
224 virtual void endConnection(QWidget *target, const QPoint &pos);
225
226 const ConnectionList &connectionList() const { return m_con_list; }
227 const ConnectionSet &selection() const { return m_sel_con_set; }
228 Connection *takeConnection(Connection *con);
229 Connection *newlyAddedConnection() { return m_tmp_con; }
230 void clearNewlyAddedConnection();
231
232 void findObjectsUnderMouse(const QPoint &pos);
233
234private:
235 void startConnection(QWidget *source, const QPoint &pos);
236 void continueConnection(QWidget *target, const QPoint &pos);
237 void abortConnection();
238
239 void startDrag(const EndPoint &end_point, const QPoint &pos);
240 void continueDrag(const QPoint &pos);
241 void endDrag(const QPoint &pos);
242 void adjustHotSopt(const EndPoint &end_point, const QPoint &pos);
243 Connection *connectionAt(const QPoint &pos) const;
244 EndPoint endPointAt(const QPoint &pos) const;
245 void paintConnection(QPainter *p, Connection *con,
246 WidgetSet *heavy_highlight_set,
247 WidgetSet *light_highlight_set) const;
248 void paintLabel(QPainter *p, EndPoint::Type type, Connection *con);
249
250
251 QPointer<QWidget> m_bg_widget;
252 QUndoStack *m_undo_stack;
253 bool m_enable_update_background;
254
255 Connection *m_tmp_con; // the connection we are currently editing
256 ConnectionList m_con_list;
257 bool m_start_connection_on_drag;
258 EndPoint m_end_point_under_mouse;
259 QPointer<QWidget> m_widget_under_mouse;
260
261 EndPoint m_drag_end_point;
262 QPoint m_old_source_pos, m_old_target_pos;
263 ConnectionSet m_sel_con_set;
264 const QColor m_inactive_color;
265 const QColor m_active_color;
266
267private:
268 friend class Connection;
269 friend class AddConnectionCommand;
270 friend class DeleteConnectionsCommand;
271 friend class SetEndPointCommand;
272};
273
274class QDESIGNER_SHARED_EXPORT CECommand : public QUndoCommand, public CETypes
275{
276public:
277 explicit CECommand(ConnectionEdit *edit)
278 : m_edit(edit) {}
279
280 bool mergeWith(const QUndoCommand *) override { return false; }
281
282 ConnectionEdit *edit() const { return m_edit; }
283
284private:
285 ConnectionEdit *m_edit;
286};
287
288class QDESIGNER_SHARED_EXPORT AddConnectionCommand : public CECommand
289{
290public:
291 AddConnectionCommand(ConnectionEdit *edit, Connection *con);
292 void redo() override;
293 void undo() override;
294private:
295 Connection *m_con;
296};
297
298class QDESIGNER_SHARED_EXPORT DeleteConnectionsCommand : public CECommand
299{
300public:
301 DeleteConnectionsCommand(ConnectionEdit *edit, const ConnectionList &con_list);
302 void redo() override;
303 void undo() override;
304private:
305 ConnectionList m_con_list;
306};
307
308} // namespace qdesigner_internal
309
310QT_END_NAMESPACE
311
312#endif // CONNECTIONEDIT_H
313

source code of qttools/src/designer/src/lib/shared/connectionedit_p.h