I think it's better to test if the cast success. For that you need a dynamic_cast
@@ -1,42 +1,67 | |||||
1 | #ifndef DRAGDROPHELPER_H |
|
1 | #ifndef DRAGDROPHELPER_H | |
2 | #define DRAGDROPHELPER_H |
|
2 | #define DRAGDROPHELPER_H | |
3 |
|
3 | |||
4 | #include <Common/spimpl.h> |
|
4 | #include <Common/spimpl.h> | |
5 | #include <QWidget> |
|
5 | #include <QWidget> | |
6 |
|
6 | |||
7 | class QVBoxLayout; |
|
7 | class QVBoxLayout; | |
8 | class QScrollArea; |
|
8 | class QScrollArea; | |
9 | class VisualizationDragWidget; |
|
9 | class VisualizationDragWidget; | |
10 | class QMimeData; |
|
10 | class QMimeData; | |
11 |
|
11 | |||
12 | /** |
|
12 | /** | |
|
13 | * @brief Event filter class which manage the scroll of QScrollArea during a drag&drop operation. | |||
|
14 | * @note A QScrollArea inside an other QScrollArea is not fully supported. | |||
|
15 | */ | |||
|
16 | class DragDropScroller : public QObject | |||
|
17 | { | |||
|
18 | Q_OBJECT | |||
|
19 | ||||
|
20 | public: | |||
|
21 | DragDropScroller(QObject* parent = nullptr); | |||
|
22 | ||||
|
23 | void addScrollArea(QScrollArea* scrollArea); | |||
|
24 | void removeScrollArea(QScrollArea* scrollArea); | |||
|
25 | ||||
|
26 | protected: | |||
|
27 | bool eventFilter(QObject *obj, QEvent *event); | |||
|
28 | ||||
|
29 | private: | |||
|
30 | class DragDropScrollerPrivate; | |||
|
31 | spimpl::unique_impl_ptr<DragDropScrollerPrivate> impl; | |||
|
32 | ||||
|
33 | private slots: | |||
|
34 | void onTimer(); | |||
|
35 | }; | |||
|
36 | ||||
|
37 | /** | |||
13 | * @brief Helper class for drag&drop operations. |
|
38 | * @brief Helper class for drag&drop operations. | |
14 | */ |
|
39 | */ | |
15 | class DragDropHelper |
|
40 | class DragDropHelper | |
16 | { |
|
41 | { | |
17 | public: |
|
42 | public: | |
18 | DragDropHelper(); |
|
43 | DragDropHelper(); | |
19 | ~DragDropHelper(); |
|
44 | ~DragDropHelper(); | |
20 |
|
45 | |||
21 | static const QString MIME_TYPE_GRAPH; |
|
46 | static const QString MIME_TYPE_GRAPH; | |
22 | static const QString MIME_TYPE_ZONE; |
|
47 | static const QString MIME_TYPE_ZONE; | |
23 |
|
48 | |||
24 | void setCurrentDragWidget(VisualizationDragWidget* dragWidget); |
|
49 | void setCurrentDragWidget(VisualizationDragWidget* dragWidget); | |
25 | VisualizationDragWidget* getCurrentDragWidget() const; |
|
50 | VisualizationDragWidget* getCurrentDragWidget() const; | |
26 |
|
51 | |||
27 | QWidget &placeHolder() const; |
|
52 | QWidget &placeHolder() const; | |
28 | void insertPlaceHolder(QVBoxLayout* layout, int index); |
|
53 | void insertPlaceHolder(QVBoxLayout* layout, int index); | |
29 | void removePlaceHolder(); |
|
54 | void removePlaceHolder(); | |
30 | bool isPlaceHolderSet() const; |
|
55 | bool isPlaceHolderSet() const; | |
31 |
|
56 | |||
32 | void addDragDropScrollArea(QScrollArea* scrollArea); |
|
57 | void addDragDropScrollArea(QScrollArea* scrollArea); | |
33 | void removeDragDropScrollArea(QScrollArea* scrollArea); |
|
58 | void removeDragDropScrollArea(QScrollArea* scrollArea); | |
34 |
|
59 | |||
35 | QUrl imageTemporaryUrl(const QImage& image) const; |
|
60 | QUrl imageTemporaryUrl(const QImage& image) const; | |
36 |
|
61 | |||
37 | private: |
|
62 | private: | |
38 | class DragDropHelperPrivate; |
|
63 | class DragDropHelperPrivate; | |
39 | spimpl::unique_impl_ptr<DragDropHelperPrivate> impl; |
|
64 | spimpl::unique_impl_ptr<DragDropHelperPrivate> impl; | |
40 | }; |
|
65 | }; | |
41 |
|
66 | |||
42 | #endif // DRAGDROPHELPER_H |
|
67 | #endif // DRAGDROPHELPER_H |
@@ -1,105 +1,248 | |||||
1 | #include "DragDropHelper.h" |
|
1 | #include "DragDropHelper.h" | |
2 | #include "Visualization/VisualizationDragWidget.h" |
|
2 | #include "Visualization/VisualizationDragWidget.h" | |
3 | #include "SqpApplication.h" |
|
3 | #include "SqpApplication.h" | |
4 |
|
4 | |||
5 | #include <QDragMoveEvent> |
|
5 | #include <QDragMoveEvent> | |
6 | #include <QDragEnterEvent> |
|
6 | #include <QDragEnterEvent> | |
7 | #include <QScrollBar> |
|
7 | #include <QScrollBar> | |
8 | #include <QScrollArea> |
|
8 | #include <QScrollArea> | |
9 | #include <QVBoxLayout> |
|
9 | #include <QVBoxLayout> | |
10 | #include <QTimer> |
|
10 | #include <QTimer> | |
11 | #include <QDir> |
|
11 | #include <QDir> | |
12 |
|
12 | |||
13 | const QString DragDropHelper::MIME_TYPE_GRAPH = "scqlop/graph"; |
|
13 | const QString DragDropHelper::MIME_TYPE_GRAPH = "scqlop/graph"; | |
14 | const QString DragDropHelper::MIME_TYPE_ZONE = "scqlop/zone"; |
|
14 | const QString DragDropHelper::MIME_TYPE_ZONE = "scqlop/zone"; | |
15 |
|
15 | |||
|
16 | const int SCROLL_SPEED = 5; | |||
|
17 | const int SCROLL_ZONE_SIZE = 50; | |||
|
18 | ||||
|
19 | struct DragDropScroller::DragDropScrollerPrivate { | |||
|
20 | ||||
|
21 | QList<QScrollArea*> m_scrollAreas; | |||
|
22 | QScrollArea* m_currentScrollArea = nullptr; | |||
|
23 | std::unique_ptr<QTimer> m_timer = nullptr; | |||
|
24 | ||||
|
25 | ||||
|
26 | enum class ScrollDirection {up, down, unknown}; | |||
|
27 | ScrollDirection m_direction = ScrollDirection::unknown; | |||
|
28 | ||||
|
29 | explicit DragDropScrollerPrivate() | |||
|
30 | : m_timer{std::make_unique<QTimer>()} | |||
|
31 | { | |||
|
32 | m_timer->setInterval(0); | |||
|
33 | } | |||
|
34 | }; | |||
|
35 | ||||
|
36 | DragDropScroller::DragDropScroller(QObject* parent) | |||
|
37 | : QObject{parent}, impl{spimpl::make_unique_impl<DragDropScrollerPrivate>()} | |||
|
38 | { | |||
|
39 | connect(impl->m_timer.get(), &QTimer::timeout, this, &DragDropScroller::onTimer); | |||
|
40 | } | |||
|
41 | ||||
|
42 | void DragDropScroller::addScrollArea(QScrollArea* scrollArea) | |||
|
43 | { | |||
|
44 | impl->m_scrollAreas << scrollArea; | |||
|
45 | scrollArea->viewport()->setAcceptDrops(true); | |||
|
46 | } | |||
|
47 | ||||
|
48 | void DragDropScroller::removeScrollArea(QScrollArea* scrollArea) | |||
|
49 | { | |||
|
50 | impl->m_scrollAreas.removeAll(scrollArea); | |||
|
51 | scrollArea->viewport()->setAcceptDrops(false); | |||
|
52 | } | |||
|
53 | ||||
|
54 | bool DragDropScroller::eventFilter(QObject *obj, QEvent *event) | |||
|
55 | { | |||
|
56 | if (event->type() == QEvent::DragMove) | |||
|
57 | { | |||
|
58 |
auto w = static_cast<QWidget*>(obj);
In case of a DragMove, Qt ensure the object will always be a QWidget. |
|||
|
59 | ||||
|
60 | if (impl->m_currentScrollArea && impl->m_currentScrollArea->isAncestorOf(w)) | |||
|
61 | { | |||
|
62 | auto moveEvent = static_cast<QDragMoveEvent*>(event); | |||
|
63 | ||||
|
64 | auto pos = moveEvent->pos(); | |||
|
65 | if (impl->m_currentScrollArea->viewport() != w) | |||
|
66 | { | |||
|
67 | auto globalPos = w->mapToGlobal(moveEvent->pos()); | |||
|
68 | pos = impl->m_currentScrollArea->viewport()->mapFromGlobal(globalPos); | |||
|
69 | } | |||
|
70 | ||||
|
71 | auto isInTopZone = pos.y() > impl->m_currentScrollArea->viewport()->size().height() - SCROLL_ZONE_SIZE; | |||
|
72 | auto isInBottomZone = pos.y() < SCROLL_ZONE_SIZE; | |||
|
73 | ||||
|
74 | if (!isInTopZone && !isInBottomZone) | |||
|
75 | { | |||
|
76 | impl->m_direction = DragDropScrollerPrivate::ScrollDirection::unknown; | |||
|
77 | impl->m_timer->stop(); | |||
|
78 | } | |||
|
79 | else if (!impl->m_timer->isActive()) | |||
|
80 | { | |||
|
81 | impl->m_direction = isInTopZone ? DragDropScrollerPrivate::ScrollDirection::up : DragDropScrollerPrivate::ScrollDirection::down; | |||
|
82 | impl->m_timer->start(); | |||
|
83 | } | |||
|
84 | } | |||
|
85 | } | |||
|
86 | else if (event->type() == QEvent::DragEnter) | |||
|
87 | { | |||
|
88 | auto w = static_cast<QWidget*>(obj); | |||
|
89 | ||||
|
90 | for (auto scrollArea : impl-> m_scrollAreas) | |||
|
91 | { | |||
|
92 | if (impl->m_currentScrollArea != scrollArea && scrollArea->isAncestorOf(w)) | |||
|
93 | { | |||
|
94 | auto enterEvent = static_cast<QDragEnterEvent*>(event); | |||
|
95 | enterEvent->acceptProposedAction(); | |||
|
96 | enterEvent->setDropAction(Qt::IgnoreAction); | |||
|
97 | impl->m_currentScrollArea = scrollArea; | |||
|
98 | break; | |||
|
99 | } | |||
|
100 | } | |||
|
101 | } | |||
|
102 | else if (event->type() == QEvent::DragLeave) | |||
|
103 | { | |||
|
104 | auto w = static_cast<QWidget*>(obj); | |||
|
105 | if (impl->m_currentScrollArea) | |||
|
106 | { | |||
|
107 | if (!QRect(QPoint(), impl->m_currentScrollArea->size()).contains(impl->m_currentScrollArea->mapFromGlobal(QCursor::pos()))) | |||
|
108 | { | |||
|
109 | impl->m_currentScrollArea = nullptr; | |||
|
110 | impl->m_direction = DragDropScrollerPrivate::ScrollDirection::unknown; | |||
|
111 | impl->m_timer->stop(); | |||
|
112 | } | |||
|
113 | } | |||
|
114 | } | |||
|
115 | else if (event->type() == QEvent::Drop) | |||
|
116 | { | |||
|
117 | auto w = static_cast<QWidget*>(obj); | |||
|
118 | if (impl->m_currentScrollArea) | |||
|
119 | { | |||
|
120 | impl->m_currentScrollArea = nullptr; | |||
|
121 | impl->m_direction = DragDropScrollerPrivate::ScrollDirection::unknown; | |||
|
122 | impl->m_timer->stop(); | |||
|
123 | } | |||
|
124 | } | |||
|
125 | ||||
|
126 | return false; | |||
|
127 | } | |||
|
128 | ||||
|
129 | void DragDropScroller::onTimer() | |||
|
130 | { | |||
|
131 | if (impl->m_currentScrollArea) | |||
|
132 | { | |||
|
133 | auto mvt = 0; | |||
|
134 | switch (impl->m_direction) | |||
|
135 | { | |||
|
136 | case DragDropScrollerPrivate::ScrollDirection::up: | |||
|
137 | mvt = SCROLL_SPEED; | |||
|
138 | break; | |||
|
139 | case DragDropScrollerPrivate::ScrollDirection::down: | |||
|
140 | mvt = -SCROLL_SPEED; | |||
|
141 | break; | |||
|
142 | default: | |||
|
143 | break; | |||
|
144 | } | |||
|
145 | ||||
|
146 | impl->m_currentScrollArea->verticalScrollBar()->setValue(impl->m_currentScrollArea->verticalScrollBar()->value() + mvt); | |||
|
147 | } | |||
|
148 | } | |||
16 |
|
149 | |||
17 | struct DragDropHelper::DragDropHelperPrivate { |
|
150 | struct DragDropHelper::DragDropHelperPrivate { | |
18 |
|
151 | |||
19 | VisualizationDragWidget* m_currentDragWidget = nullptr; |
|
152 | VisualizationDragWidget* m_currentDragWidget = nullptr; | |
20 | std::unique_ptr<QWidget> m_placeHolder = nullptr; |
|
153 | std::unique_ptr<QWidget> m_placeHolder = nullptr; | |
21 | std::unique_ptr<DragDropScroller> m_dragDropScroller = nullptr; |
|
154 | std::unique_ptr<DragDropScroller> m_dragDropScroller = nullptr; | |
22 | QString m_imageTempUrl; //Temporary file for image url generated by the drag & drop. Not using QTemporaryFile to have a name which is not generated. |
|
155 | QString m_imageTempUrl; //Temporary file for image url generated by the drag & drop. Not using QTemporaryFile to have a name which is not generated. | |
23 |
|
156 | |||
24 | explicit DragDropHelperPrivate() |
|
157 | explicit DragDropHelperPrivate() | |
25 | : m_placeHolder{std::make_unique<QWidget>()}, |
|
158 | : m_placeHolder{std::make_unique<QWidget>()}, | |
26 | m_dragDropScroller{std::make_unique<DragDropScroller>()} |
|
159 | m_dragDropScroller{std::make_unique<DragDropScroller>()} | |
27 | { |
|
160 | { | |
28 | m_placeHolder->setStyleSheet("background-color: #BBD5EE; border:2px solid #2A7FD4"); |
|
161 | m_placeHolder->setStyleSheet("background-color: #BBD5EE; border:2px solid #2A7FD4"); | |
29 | sqpApp->installEventFilter(m_dragDropScroller.get()); |
|
162 | sqpApp->installEventFilter(m_dragDropScroller.get()); | |
30 |
|
163 | |||
31 |
|
164 | |||
32 | m_imageTempUrl = QDir::temp().absoluteFilePath("Scqlop_graph.png"); |
|
165 | m_imageTempUrl = QDir::temp().absoluteFilePath("Scqlop_graph.png"); | |
33 | } |
|
166 | } | |
34 |
|
167 | |||
35 | void preparePlaceHolder() const |
|
168 | void preparePlaceHolder() const | |
36 | { |
|
169 | { | |
37 | if (m_currentDragWidget) |
|
170 | if (m_currentDragWidget) | |
38 | { |
|
171 | { | |
39 | m_placeHolder->setMinimumSize(m_currentDragWidget->size()); |
|
172 | m_placeHolder->setMinimumSize(m_currentDragWidget->size()); | |
40 | m_placeHolder->setSizePolicy(m_currentDragWidget->sizePolicy()); |
|
173 | m_placeHolder->setSizePolicy(m_currentDragWidget->sizePolicy()); | |
41 | } |
|
174 | } | |
42 | else |
|
175 | else | |
43 | { |
|
176 | { | |
44 | m_placeHolder->setMinimumSize(200, 200); |
|
177 | m_placeHolder->setMinimumSize(200, 200); | |
45 | } |
|
178 | } | |
46 | } |
|
179 | } | |
47 | }; |
|
180 | }; | |
48 |
|
181 | |||
49 |
|
182 | |||
50 | DragDropHelper::DragDropHelper() : |
|
183 | DragDropHelper::DragDropHelper() : | |
51 | impl{spimpl::make_unique_impl<DragDropHelperPrivate>()} |
|
184 | impl{spimpl::make_unique_impl<DragDropHelperPrivate>()} | |
52 | { |
|
185 | { | |
53 | } |
|
186 | } | |
54 |
|
187 | |||
55 | DragDropHelper::~DragDropHelper() |
|
188 | DragDropHelper::~DragDropHelper() | |
56 | { |
|
189 | { | |
57 | QFile::remove(impl->m_imageTempUrl); |
|
190 | QFile::remove(impl->m_imageTempUrl); | |
58 | } |
|
191 | } | |
59 |
|
192 | |||
60 | void DragDropHelper::setCurrentDragWidget(VisualizationDragWidget *dragWidget) |
|
193 | void DragDropHelper::setCurrentDragWidget(VisualizationDragWidget *dragWidget) | |
61 | { |
|
194 | { | |
62 | impl->m_currentDragWidget = dragWidget; |
|
195 | impl->m_currentDragWidget = dragWidget; | |
63 | } |
|
196 | } | |
64 |
|
197 | |||
65 | VisualizationDragWidget *DragDropHelper::getCurrentDragWidget() const |
|
198 | VisualizationDragWidget *DragDropHelper::getCurrentDragWidget() const | |
66 | { |
|
199 | { | |
67 | return impl->m_currentDragWidget; |
|
200 | return impl->m_currentDragWidget; | |
68 | } |
|
201 | } | |
69 |
|
202 | |||
70 |
|
203 | |||
71 | QWidget& DragDropHelper::placeHolder() const |
|
204 | QWidget& DragDropHelper::placeHolder() const | |
72 | { |
|
205 | { | |
73 | return *impl->m_placeHolder; |
|
206 | return *impl->m_placeHolder; | |
74 | } |
|
207 | } | |
75 |
|
208 | |||
76 | void DragDropHelper::insertPlaceHolder(QVBoxLayout *layout, int index) |
|
209 | void DragDropHelper::insertPlaceHolder(QVBoxLayout *layout, int index) | |
77 | { |
|
210 | { | |
78 | removePlaceHolder(); |
|
211 | removePlaceHolder(); | |
79 | impl->preparePlaceHolder(); |
|
212 | impl->preparePlaceHolder(); | |
80 | layout->insertWidget(index, impl->m_placeHolder.get()); |
|
213 | layout->insertWidget(index, impl->m_placeHolder.get()); | |
81 | impl->m_placeHolder->show(); |
|
214 | impl->m_placeHolder->show(); | |
82 | } |
|
215 | } | |
83 |
|
216 | |||
84 | void DragDropHelper::removePlaceHolder() |
|
217 | void DragDropHelper::removePlaceHolder() | |
85 | { |
|
218 | { | |
86 | auto parentWidget = impl->m_placeHolder->parentWidget(); |
|
219 | auto parentWidget = impl->m_placeHolder->parentWidget(); | |
87 | if (parentWidget) |
|
220 | if (parentWidget) | |
88 | { |
|
221 | { | |
89 | parentWidget->layout()->removeWidget(impl->m_placeHolder.get()); |
|
222 | parentWidget->layout()->removeWidget(impl->m_placeHolder.get()); | |
90 | impl->m_placeHolder->setParent(nullptr); |
|
223 | impl->m_placeHolder->setParent(nullptr); | |
91 | impl->m_placeHolder->hide(); |
|
224 | impl->m_placeHolder->hide(); | |
92 | } |
|
225 | } | |
93 | } |
|
226 | } | |
94 |
|
227 | |||
95 | bool DragDropHelper::isPlaceHolderSet() const |
|
228 | bool DragDropHelper::isPlaceHolderSet() const | |
96 | { |
|
229 | { | |
97 | return impl->m_placeHolder->parentWidget(); |
|
230 | return impl->m_placeHolder->parentWidget(); | |
98 | } |
|
231 | } | |
99 |
|
232 | |||
|
233 | void DragDropHelper::addDragDropScrollArea(QScrollArea *scrollArea) | |||
|
234 | { | |||
|
235 | impl->m_dragDropScroller->addScrollArea(scrollArea); | |||
|
236 | } | |||
|
237 | ||||
|
238 | void DragDropHelper::removeDragDropScrollArea(QScrollArea *scrollArea) | |||
|
239 | { | |||
|
240 | impl->m_dragDropScroller->removeScrollArea(scrollArea); | |||
|
241 | } | |||
|
242 | ||||
100 | QUrl DragDropHelper::imageTemporaryUrl(const QImage& image) const |
|
243 | QUrl DragDropHelper::imageTemporaryUrl(const QImage& image) const | |
101 | { |
|
244 | { | |
102 | image.save(impl->m_imageTempUrl); |
|
245 | image.save(impl->m_imageTempUrl); | |
103 | return QUrl::fromLocalFile(impl->m_imageTempUrl); |
|
246 | return QUrl::fromLocalFile(impl->m_imageTempUrl); | |
104 | } |
|
247 | } | |
105 |
|
248 |
@@ -1,181 +1,183 | |||||
1 | #include "Visualization/VisualizationTabWidget.h" |
|
1 | #include "Visualization/VisualizationTabWidget.h" | |
2 | #include "Visualization/IVisualizationWidgetVisitor.h" |
|
2 | #include "Visualization/IVisualizationWidgetVisitor.h" | |
3 | #include "ui_VisualizationTabWidget.h" |
|
3 | #include "ui_VisualizationTabWidget.h" | |
4 |
|
4 | |||
5 | #include "Visualization/VisualizationZoneWidget.h" |
|
5 | #include "Visualization/VisualizationZoneWidget.h" | |
6 | #include "Visualization/VisualizationGraphWidget.h" |
|
6 | #include "Visualization/VisualizationGraphWidget.h" | |
7 |
|
7 | |||
8 | #include "SqpApplication.h" |
|
8 | #include "SqpApplication.h" | |
9 | #include "DragDropHelper.h" |
|
9 | #include "DragDropHelper.h" | |
10 |
|
10 | |||
11 | Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget") |
|
11 | Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget") | |
12 |
|
12 | |||
13 | namespace { |
|
13 | namespace { | |
14 |
|
14 | |||
15 | /// Generates a default name for a new zone, according to the number of zones already displayed in |
|
15 | /// Generates a default name for a new zone, according to the number of zones already displayed in | |
16 | /// the tab |
|
16 | /// the tab | |
17 | QString defaultZoneName(const QLayout &layout) |
|
17 | QString defaultZoneName(const QLayout &layout) | |
18 | { |
|
18 | { | |
19 | auto count = 0; |
|
19 | auto count = 0; | |
20 | for (auto i = 0; i < layout.count(); ++i) { |
|
20 | for (auto i = 0; i < layout.count(); ++i) { | |
21 | if (dynamic_cast<VisualizationZoneWidget *>(layout.itemAt(i)->widget())) { |
|
21 | if (dynamic_cast<VisualizationZoneWidget *>(layout.itemAt(i)->widget())) { | |
22 | count++; |
|
22 | count++; | |
23 | } |
|
23 | } | |
24 | } |
|
24 | } | |
25 |
|
25 | |||
26 | return QObject::tr("Zone %1").arg(count + 1); |
|
26 | return QObject::tr("Zone %1").arg(count + 1); | |
27 | } |
|
27 | } | |
28 |
|
28 | |||
29 | /** |
|
29 | /** | |
30 | * Applies a function to all zones of the tab represented by its layout |
|
30 | * Applies a function to all zones of the tab represented by its layout | |
31 | * @param layout the layout that contains zones |
|
31 | * @param layout the layout that contains zones | |
32 | * @param fun the function to apply to each zone |
|
32 | * @param fun the function to apply to each zone | |
33 | */ |
|
33 | */ | |
34 | template <typename Fun> |
|
34 | template <typename Fun> | |
35 | void processZones(QLayout &layout, Fun fun) |
|
35 | void processZones(QLayout &layout, Fun fun) | |
36 | { |
|
36 | { | |
37 | for (auto i = 0; i < layout.count(); ++i) { |
|
37 | for (auto i = 0; i < layout.count(); ++i) { | |
38 | if (auto item = layout.itemAt(i)) { |
|
38 | if (auto item = layout.itemAt(i)) { | |
39 | if (auto visualizationZoneWidget |
|
39 | if (auto visualizationZoneWidget | |
40 | = dynamic_cast<VisualizationZoneWidget *>(item->widget())) { |
|
40 | = dynamic_cast<VisualizationZoneWidget *>(item->widget())) { | |
41 | fun(*visualizationZoneWidget); |
|
41 | fun(*visualizationZoneWidget); | |
42 | } |
|
42 | } | |
43 | } |
|
43 | } | |
44 | } |
|
44 | } | |
45 | } |
|
45 | } | |
46 |
|
46 | |||
47 | } // namespace |
|
47 | } // namespace | |
48 |
|
48 | |||
49 | struct VisualizationTabWidget::VisualizationTabWidgetPrivate { |
|
49 | struct VisualizationTabWidget::VisualizationTabWidgetPrivate { | |
50 | explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {} |
|
50 | explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {} | |
51 |
|
51 | |||
52 | QString m_Name; |
|
52 | QString m_Name; | |
53 | }; |
|
53 | }; | |
54 |
|
54 | |||
55 | VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent) |
|
55 | VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent) | |
56 | : QWidget{parent}, |
|
56 | : QWidget{parent}, | |
57 | ui{new Ui::VisualizationTabWidget}, |
|
57 | ui{new Ui::VisualizationTabWidget}, | |
58 | impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)} |
|
58 | impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)} | |
59 | { |
|
59 | { | |
60 | ui->setupUi(this); |
|
60 | ui->setupUi(this); | |
61 |
|
61 | |||
62 | ui->dragDropContainer->setAcceptedMimeTypes({DragDropHelper::MIME_TYPE_GRAPH, DragDropHelper::MIME_TYPE_ZONE}); |
|
62 | ui->dragDropContainer->setAcceptedMimeTypes({DragDropHelper::MIME_TYPE_GRAPH, DragDropHelper::MIME_TYPE_ZONE}); | |
63 | connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this, &VisualizationTabWidget::dropMimeData); |
|
63 | connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this, &VisualizationTabWidget::dropMimeData); | |
|
64 | sqpApp->dragDropHelper().addDragDropScrollArea(ui->scrollArea); | |||
64 |
|
65 | |||
65 | // Widget is deleted when closed |
|
66 | // Widget is deleted when closed | |
66 | setAttribute(Qt::WA_DeleteOnClose); |
|
67 | setAttribute(Qt::WA_DeleteOnClose); | |
67 | } |
|
68 | } | |
68 |
|
69 | |||
69 | VisualizationTabWidget::~VisualizationTabWidget() |
|
70 | VisualizationTabWidget::~VisualizationTabWidget() | |
70 | { |
|
71 | { | |
|
72 | sqpApp->dragDropHelper().removeDragDropScrollArea(ui->scrollArea); | |||
71 | delete ui; |
|
73 | delete ui; | |
72 | } |
|
74 | } | |
73 |
|
75 | |||
74 | void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget) |
|
76 | void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget) | |
75 | { |
|
77 | { | |
76 | ui->dragDropContainer->addDragWidget(zoneWidget); |
|
78 | ui->dragDropContainer->addDragWidget(zoneWidget); | |
77 | } |
|
79 | } | |
78 |
|
80 | |||
79 | void VisualizationTabWidget::insertZone(int index, VisualizationZoneWidget *zoneWidget) |
|
81 | void VisualizationTabWidget::insertZone(int index, VisualizationZoneWidget *zoneWidget) | |
80 | { |
|
82 | { | |
81 | ui->dragDropContainer->insertDragWidget(index, zoneWidget); |
|
83 | ui->dragDropContainer->insertDragWidget(index, zoneWidget); | |
82 | } |
|
84 | } | |
83 |
|
85 | |||
84 | VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable) |
|
86 | VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable) | |
85 | { |
|
87 | { | |
86 | return createZone({variable}, -1); |
|
88 | return createZone({variable}, -1); | |
87 | } |
|
89 | } | |
88 |
|
90 | |||
89 | VisualizationZoneWidget *VisualizationTabWidget::createZone(const QList<std::shared_ptr<Variable> > &variables, int index) |
|
91 | VisualizationZoneWidget *VisualizationTabWidget::createZone(const QList<std::shared_ptr<Variable> > &variables, int index) | |
90 | { |
|
92 | { | |
91 | auto zoneWidget = new VisualizationZoneWidget{defaultZoneName(*ui->dragDropContainer->layout()), this}; |
|
93 | auto zoneWidget = new VisualizationZoneWidget{defaultZoneName(*ui->dragDropContainer->layout()), this}; | |
92 | this->insertZone(index, zoneWidget); |
|
94 | this->insertZone(index, zoneWidget); | |
93 |
|
95 | |||
94 | // Creates a new graph into the zone |
|
96 | // Creates a new graph into the zone | |
95 | zoneWidget->createGraph(variables, index); |
|
97 | zoneWidget->createGraph(variables, index); | |
96 |
|
98 | |||
97 | return zoneWidget; |
|
99 | return zoneWidget; | |
98 | } |
|
100 | } | |
99 |
|
101 | |||
100 | void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor) |
|
102 | void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor) | |
101 | { |
|
103 | { | |
102 | if (visitor) { |
|
104 | if (visitor) { | |
103 | visitor->visitEnter(this); |
|
105 | visitor->visitEnter(this); | |
104 |
|
106 | |||
105 | // Apply visitor to zone children: widgets different from zones are not visited (no action) |
|
107 | // Apply visitor to zone children: widgets different from zones are not visited (no action) | |
106 | processZones(tabLayout(), [visitor](VisualizationZoneWidget &zoneWidget) { |
|
108 | processZones(tabLayout(), [visitor](VisualizationZoneWidget &zoneWidget) { | |
107 | zoneWidget.accept(visitor); |
|
109 | zoneWidget.accept(visitor); | |
108 | }); |
|
110 | }); | |
109 |
|
111 | |||
110 | visitor->visitLeave(this); |
|
112 | visitor->visitLeave(this); | |
111 | } |
|
113 | } | |
112 | else { |
|
114 | else { | |
113 | qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null"); |
|
115 | qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null"); | |
114 | } |
|
116 | } | |
115 | } |
|
117 | } | |
116 |
|
118 | |||
117 | bool VisualizationTabWidget::canDrop(const Variable &variable) const |
|
119 | bool VisualizationTabWidget::canDrop(const Variable &variable) const | |
118 | { |
|
120 | { | |
119 | // A tab can always accomodate a variable |
|
121 | // A tab can always accomodate a variable | |
120 | Q_UNUSED(variable); |
|
122 | Q_UNUSED(variable); | |
121 | return true; |
|
123 | return true; | |
122 | } |
|
124 | } | |
123 |
|
125 | |||
124 | bool VisualizationTabWidget::contains(const Variable &variable) const |
|
126 | bool VisualizationTabWidget::contains(const Variable &variable) const | |
125 | { |
|
127 | { | |
126 | Q_UNUSED(variable); |
|
128 | Q_UNUSED(variable); | |
127 | return false; |
|
129 | return false; | |
128 | } |
|
130 | } | |
129 |
|
131 | |||
130 | QString VisualizationTabWidget::name() const |
|
132 | QString VisualizationTabWidget::name() const | |
131 | { |
|
133 | { | |
132 | return impl->m_Name; |
|
134 | return impl->m_Name; | |
133 | } |
|
135 | } | |
134 |
|
136 | |||
135 | void VisualizationTabWidget::closeEvent(QCloseEvent *event) |
|
137 | void VisualizationTabWidget::closeEvent(QCloseEvent *event) | |
136 | { |
|
138 | { | |
137 | // Closes zones in the tab |
|
139 | // Closes zones in the tab | |
138 | processZones(tabLayout(), [](VisualizationZoneWidget &zoneWidget) { zoneWidget.close(); }); |
|
140 | processZones(tabLayout(), [](VisualizationZoneWidget &zoneWidget) { zoneWidget.close(); }); | |
139 |
|
141 | |||
140 | QWidget::closeEvent(event); |
|
142 | QWidget::closeEvent(event); | |
141 | } |
|
143 | } | |
142 |
|
144 | |||
143 | QLayout &VisualizationTabWidget::tabLayout() const noexcept |
|
145 | QLayout &VisualizationTabWidget::tabLayout() const noexcept | |
144 | { |
|
146 | { | |
145 | return *ui->dragDropContainer->layout(); |
|
147 | return *ui->dragDropContainer->layout(); | |
146 | } |
|
148 | } | |
147 |
|
149 | |||
148 | void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData) |
|
150 | void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData) | |
149 | { |
|
151 | { | |
150 | auto& helper = sqpApp->dragDropHelper(); |
|
152 | auto& helper = sqpApp->dragDropHelper(); | |
151 | if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_GRAPH)) |
|
153 | if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_GRAPH)) | |
152 | { |
|
154 | { | |
153 | auto graphWidget = static_cast<VisualizationGraphWidget*>(helper.getCurrentDragWidget()); |
|
155 | auto graphWidget = static_cast<VisualizationGraphWidget*>(helper.getCurrentDragWidget()); | |
154 | auto parentDragDropContainer = qobject_cast<VisualizationDragDropContainer*>(graphWidget->parentWidget()); |
|
156 | auto parentDragDropContainer = qobject_cast<VisualizationDragDropContainer*>(graphWidget->parentWidget()); | |
155 | Q_ASSERT(parentDragDropContainer); |
|
157 | Q_ASSERT(parentDragDropContainer); | |
156 |
|
158 | |||
157 | auto nbGraph = parentDragDropContainer->countDragWidget(); |
|
159 | auto nbGraph = parentDragDropContainer->countDragWidget(); | |
158 | if (nbGraph == 1) |
|
160 | if (nbGraph == 1) | |
159 | { |
|
161 | { | |
160 | //This is the only graph in the previous zone, close the zone |
|
162 | //This is the only graph in the previous zone, close the zone | |
161 | graphWidget->parentZoneWidget()->close(); |
|
163 | graphWidget->parentZoneWidget()->close(); | |
162 | } |
|
164 | } | |
163 | else |
|
165 | else | |
164 | { |
|
166 | { | |
165 | //Close the graph |
|
167 | //Close the graph | |
166 | graphWidget->close(); |
|
168 | graphWidget->close(); | |
167 | } |
|
169 | } | |
168 |
|
170 | |||
169 | const auto& variables = graphWidget->variables(); |
|
171 | const auto& variables = graphWidget->variables(); | |
170 | createZone(variables, index); |
|
172 | createZone(variables, index); | |
171 | } |
|
173 | } | |
172 | else if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_ZONE)) |
|
174 | else if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_ZONE)) | |
173 | { |
|
175 | { | |
174 | //Simple move of the zone, no variable operation associated |
|
176 | //Simple move of the zone, no variable operation associated | |
175 | auto zoneWidget = static_cast<VisualizationZoneWidget*>(helper.getCurrentDragWidget()); |
|
177 | auto zoneWidget = static_cast<VisualizationZoneWidget*>(helper.getCurrentDragWidget()); | |
176 | auto parentDragDropContainer = zoneWidget->parentWidget(); |
|
178 | auto parentDragDropContainer = zoneWidget->parentWidget(); | |
177 | parentDragDropContainer->layout()->removeWidget(zoneWidget); |
|
179 | parentDragDropContainer->layout()->removeWidget(zoneWidget); | |
178 |
|
180 | |||
179 | ui->dragDropContainer->insertDragWidget(index, zoneWidget); |
|
181 | ui->dragDropContainer->insertDragWidget(index, zoneWidget); | |
180 | } |
|
182 | } | |
181 | } |
|
183 | } |
General Comments 6
Pull request updated. Auto status change to "Under Review"
Changed commits: * 1 added * 0 removed Changed files: * M gui/include/Visualization/VisualizationDragDropContainer.h * M gui/include/Visualization/VisualizationDragWidget.h * M gui/src/Visualization/VisualizationDragDropContainer.cpp * M gui/src/Visualization/VisualizationGraphWidget.cpp * M gui/src/Visualization/VisualizationZoneWidget.cpp
Status change > Approved
You need to be logged in to leave comments.
Login now