##// END OF EJS Templates
Moves the class DragDropScroller in its own file
trabillard -
r891:dd73a5040007
parent child
Show More
@@ -0,0 +1,32
1 #ifndef SCIQLOP_DRAGDROPSCROLLER_H
2 #define SCIQLOP_DRAGDROPSCROLLER_H
3
4 #include <Common/spimpl.h>
5 #include <QScrollArea>
6
7 /**
8 * @brief Event filter class which manage the scroll of QScrollArea during a drag&drop operation.
9 * @note A QScrollArea inside an other QScrollArea is not fully supported.
10 */
11 class DragDropScroller : public QObject {
12 Q_OBJECT
13
14 public:
15 DragDropScroller(QObject *parent = nullptr);
16
17 void addScrollArea(QScrollArea *scrollArea);
18 void removeScrollArea(QScrollArea *scrollArea);
19
20 protected:
21 bool eventFilter(QObject *obj, QEvent *event);
22
23 private:
24 class DragDropScrollerPrivate;
25 spimpl::unique_impl_ptr<DragDropScrollerPrivate> impl;
26
27 private slots:
28 void onTimer();
29 };
30
31
32 #endif // SCIQLOP_DRAGDROPSCROLLER_H
@@ -0,0 +1,125
1 #include "DragAndDrop/DragDropScroller.h"
2
3 #include <QDragEnterEvent>
4 #include <QDragMoveEvent>
5 #include <QScrollBar>
6 #include <QTimer>
7
8 const int SCROLL_SPEED = 5;
9 const int SCROLL_ZONE_SIZE = 50;
10
11 struct DragDropScroller::DragDropScrollerPrivate {
12
13 QList<QScrollArea *> m_ScrollAreas;
14 QScrollArea *m_CurrentScrollArea = nullptr;
15 std::unique_ptr<QTimer> m_Timer = nullptr;
16
17 enum class ScrollDirection { up, down, unknown };
18 ScrollDirection m_Direction = ScrollDirection::unknown;
19
20 explicit DragDropScrollerPrivate() : m_Timer{std::make_unique<QTimer>()}
21 {
22 m_Timer->setInterval(0);
23 }
24 };
25
26 DragDropScroller::DragDropScroller(QObject *parent)
27 : QObject{parent}, impl{spimpl::make_unique_impl<DragDropScrollerPrivate>()}
28 {
29 connect(impl->m_Timer.get(), &QTimer::timeout, this, &DragDropScroller::onTimer);
30 }
31
32 void DragDropScroller::addScrollArea(QScrollArea *scrollArea)
33 {
34 impl->m_ScrollAreas << scrollArea;
35 scrollArea->viewport()->setAcceptDrops(true);
36 }
37
38 void DragDropScroller::removeScrollArea(QScrollArea *scrollArea)
39 {
40 impl->m_ScrollAreas.removeAll(scrollArea);
41 scrollArea->viewport()->setAcceptDrops(false);
42 }
43
44 bool DragDropScroller::eventFilter(QObject *obj, QEvent *event)
45 {
46 if (event->type() == QEvent::DragMove) {
47 auto w = static_cast<QWidget *>(obj);
48
49 if (impl->m_CurrentScrollArea && impl->m_CurrentScrollArea->isAncestorOf(w)) {
50 auto moveEvent = static_cast<QDragMoveEvent *>(event);
51
52 auto pos = moveEvent->pos();
53 if (impl->m_CurrentScrollArea->viewport() != w) {
54 auto globalPos = w->mapToGlobal(moveEvent->pos());
55 pos = impl->m_CurrentScrollArea->viewport()->mapFromGlobal(globalPos);
56 }
57
58 auto isInTopZone = pos.y() > impl->m_CurrentScrollArea->viewport()->size().height()
59 - SCROLL_ZONE_SIZE;
60 auto isInBottomZone = pos.y() < SCROLL_ZONE_SIZE;
61
62 if (!isInTopZone && !isInBottomZone) {
63 impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown;
64 impl->m_Timer->stop();
65 }
66 else if (!impl->m_Timer->isActive()) {
67 impl->m_Direction = isInTopZone ? DragDropScrollerPrivate::ScrollDirection::up
68 : DragDropScrollerPrivate::ScrollDirection::down;
69 impl->m_Timer->start();
70 }
71 }
72 }
73 else if (event->type() == QEvent::DragEnter) {
74 auto w = static_cast<QWidget *>(obj);
75
76 for (auto scrollArea : impl->m_ScrollAreas) {
77 if (impl->m_CurrentScrollArea != scrollArea && scrollArea->isAncestorOf(w)) {
78 auto enterEvent = static_cast<QDragEnterEvent *>(event);
79 enterEvent->acceptProposedAction();
80 enterEvent->setDropAction(Qt::IgnoreAction);
81 impl->m_CurrentScrollArea = scrollArea;
82 break;
83 }
84 }
85 }
86 else if (event->type() == QEvent::DragLeave) {
87 if (impl->m_CurrentScrollArea) {
88 if (!QRect(QPoint(), impl->m_CurrentScrollArea->size())
89 .contains(impl->m_CurrentScrollArea->mapFromGlobal(QCursor::pos()))) {
90 impl->m_CurrentScrollArea = nullptr;
91 impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown;
92 impl->m_Timer->stop();
93 }
94 }
95 }
96 else if (event->type() == QEvent::Drop) {
97 if (impl->m_CurrentScrollArea) {
98 impl->m_CurrentScrollArea = nullptr;
99 impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown;
100 impl->m_Timer->stop();
101 }
102 }
103
104 return false;
105 }
106
107 void DragDropScroller::onTimer()
108 {
109 if (impl->m_CurrentScrollArea) {
110 auto mvt = 0;
111 switch (impl->m_Direction) {
112 case DragDropScrollerPrivate::ScrollDirection::up:
113 mvt = SCROLL_SPEED;
114 break;
115 case DragDropScrollerPrivate::ScrollDirection::down:
116 mvt = -SCROLL_SPEED;
117 break;
118 default:
119 break;
120 }
121
122 impl->m_CurrentScrollArea->verticalScrollBar()->setValue(
123 impl->m_CurrentScrollArea->verticalScrollBar()->value() + mvt);
124 }
125 }
@@ -1,91 +1,67
1 #ifndef SCIQLOP_DRAGDROPHELPER_H
1 #ifndef SCIQLOP_DRAGDROPHELPER_H
2 #define SCIQLOP_DRAGDROPHELPER_H
2 #define SCIQLOP_DRAGDROPHELPER_H
3
3
4 #include <Common/spimpl.h>
4 #include <Common/spimpl.h>
5 #include <QLoggingCategory>
5 #include <QLoggingCategory>
6 #include <QWidget>
6 #include <QWidget>
7
7
8 class QVBoxLayout;
8 class QVBoxLayout;
9 class QScrollArea;
9 class QScrollArea;
10 class VisualizationDragWidget;
10 class VisualizationDragWidget;
11 class VisualizationDragDropContainer;
11 class VisualizationDragDropContainer;
12 class QMimeData;
12 class QMimeData;
13
13
14 Q_DECLARE_LOGGING_CATEGORY(LOG_DragDropHelper)
14 Q_DECLARE_LOGGING_CATEGORY(LOG_DragDropHelper)
15
15
16 /**
16 /**
17 * @brief Helper class for drag&drop operations.
17 * @brief Helper class for drag&drop operations.
18 * @note The helper is accessible from the sqpApp singleton and has the same life as the whole
18 * @note The helper is accessible from the sqpApp singleton and has the same life as the whole
19 * application (like a controller). But contrary to a controller, it doesn't live in a thread and
19 * application (like a controller). But contrary to a controller, it doesn't live in a thread and
20 * can interect with the gui.
20 * can interect with the gui.
21 * @see SqpApplication
21 * @see SqpApplication
22 */
22 */
23 class DragDropHelper {
23 class DragDropHelper {
24 public:
24 public:
25 static const QString MIME_TYPE_GRAPH;
25 static const QString MIME_TYPE_GRAPH;
26 static const QString MIME_TYPE_ZONE;
26 static const QString MIME_TYPE_ZONE;
27
27
28 enum class PlaceHolderType { Default, Graph, Zone };
28 enum class PlaceHolderType { Default, Graph, Zone };
29
29
30 DragDropHelper();
30 DragDropHelper();
31 virtual ~DragDropHelper();
31 virtual ~DragDropHelper();
32
32
33 /// Resets some internal variables. Must be called before any new drag&drop operation.
33 /// Resets some internal variables. Must be called before any new drag&drop operation.
34 void resetDragAndDrop();
34 void resetDragAndDrop();
35
35
36 /// Sets the visualization widget currently being drag on the visualization.
36 /// Sets the visualization widget currently being drag on the visualization.
37 void setCurrentDragWidget(VisualizationDragWidget *dragWidget);
37 void setCurrentDragWidget(VisualizationDragWidget *dragWidget);
38
38
39 /// Returns the visualization widget currently being drag on the visualization.
39 /// Returns the visualization widget currently being drag on the visualization.
40 /// Can be null if a new visualization widget is intended to be created by the drag&drop
40 /// Can be null if a new visualization widget is intended to be created by the drag&drop
41 /// operation.
41 /// operation.
42 VisualizationDragWidget *getCurrentDragWidget() const;
42 VisualizationDragWidget *getCurrentDragWidget() const;
43
43
44 QWidget &placeHolder() const;
44 QWidget &placeHolder() const;
45 void insertPlaceHolder(QVBoxLayout *layout, int index, PlaceHolderType type,
45 void insertPlaceHolder(QVBoxLayout *layout, int index, PlaceHolderType type,
46 const QString &topLabelText);
46 const QString &topLabelText);
47 void removePlaceHolder();
47 void removePlaceHolder();
48 bool isPlaceHolderSet() const;
48 bool isPlaceHolderSet() const;
49
49
50 /// Checks if the specified mime data is valid for a drop in the visualization
50 /// Checks if the specified mime data is valid for a drop in the visualization
51 bool checkMimeDataForVisualization(const QMimeData *mimeData,
51 bool checkMimeDataForVisualization(const QMimeData *mimeData,
52 VisualizationDragDropContainer *dropContainer);
52 VisualizationDragDropContainer *dropContainer);
53
53
54 void addDragDropScrollArea(QScrollArea *scrollArea);
54 void addDragDropScrollArea(QScrollArea *scrollArea);
55 void removeDragDropScrollArea(QScrollArea *scrollArea);
55 void removeDragDropScrollArea(QScrollArea *scrollArea);
56
56
57 QUrl imageTemporaryUrl(const QImage &image) const;
57 QUrl imageTemporaryUrl(const QImage &image) const;
58
58
59 void setHightlightedDragWidget(VisualizationDragWidget *dragWidget);
59 void setHightlightedDragWidget(VisualizationDragWidget *dragWidget);
60 VisualizationDragWidget *getHightlightedDragWidget() const;
60 VisualizationDragWidget *getHightlightedDragWidget() const;
61
61
62 private:
62 private:
63 class DragDropHelperPrivate;
63 class DragDropHelperPrivate;
64 spimpl::unique_impl_ptr<DragDropHelperPrivate> impl;
64 spimpl::unique_impl_ptr<DragDropHelperPrivate> impl;
65 };
65 };
66
66
67 /**
68 * @brief Event filter class which manage the scroll of QScrollArea during a drag&drop operation.
69 * @note A QScrollArea inside an other QScrollArea is not fully supported.
70 */
71 class DragDropScroller : public QObject {
72 Q_OBJECT
73
74 public:
75 DragDropScroller(QObject *parent = nullptr);
76
77 void addScrollArea(QScrollArea *scrollArea);
78 void removeScrollArea(QScrollArea *scrollArea);
79
80 protected:
81 bool eventFilter(QObject *obj, QEvent *event);
82
83 private:
84 class DragDropScrollerPrivate;
85 spimpl::unique_impl_ptr<DragDropScrollerPrivate> impl;
86
87 private slots:
88 void onTimer();
89 };
90
91 #endif // SCIQLOP_DRAGDROPHELPER_H
67 #endif // SCIQLOP_DRAGDROPHELPER_H
@@ -1,91 +1,93
1
1
2 gui_moc_headers = [
2 gui_moc_headers = [
3 'include/DataSource/DataSourceWidget.h',
3 'include/DataSource/DataSourceWidget.h',
4 'include/DataSource/DataSourceTreeWidget.h',
4 'include/DataSource/DataSourceTreeWidget.h',
5 'include/Settings/SqpSettingsDialog.h',
5 'include/Settings/SqpSettingsDialog.h',
6 'include/Settings/SqpSettingsGeneralWidget.h',
6 'include/Settings/SqpSettingsGeneralWidget.h',
7 'include/SidePane/SqpSidePane.h',
7 'include/SidePane/SqpSidePane.h',
8 'include/SqpApplication.h',
8 'include/SqpApplication.h',
9 'include/DragAndDrop/DragDropHelper.h',
9 'include/DragAndDrop/DragDropHelper.h',
10 'include/DragAndDrop/DragDropScroller.h',
10 'include/TimeWidget/TimeWidget.h',
11 'include/TimeWidget/TimeWidget.h',
11 'include/Variable/VariableInspectorWidget.h',
12 'include/Variable/VariableInspectorWidget.h',
12 'include/Variable/VariableInspectorTableView.h',
13 'include/Variable/VariableInspectorTableView.h',
13 'include/Variable/RenameVariableDialog.h',
14 'include/Variable/RenameVariableDialog.h',
14 'include/Visualization/qcustomplot.h',
15 'include/Visualization/qcustomplot.h',
15 'include/Visualization/VisualizationGraphWidget.h',
16 'include/Visualization/VisualizationGraphWidget.h',
16 'include/Visualization/VisualizationTabWidget.h',
17 'include/Visualization/VisualizationTabWidget.h',
17 'include/Visualization/VisualizationWidget.h',
18 'include/Visualization/VisualizationWidget.h',
18 'include/Visualization/VisualizationZoneWidget.h',
19 'include/Visualization/VisualizationZoneWidget.h',
19 'include/Visualization/VisualizationDragDropContainer.h',
20 'include/Visualization/VisualizationDragDropContainer.h',
20 'include/Visualization/VisualizationDragWidget.h'
21 'include/Visualization/VisualizationDragWidget.h'
21 ]
22 ]
22
23
23 gui_ui_files = [
24 gui_ui_files = [
24 'ui/DataSource/DataSourceWidget.ui',
25 'ui/DataSource/DataSourceWidget.ui',
25 'ui/Settings/SqpSettingsDialog.ui',
26 'ui/Settings/SqpSettingsDialog.ui',
26 'ui/Settings/SqpSettingsGeneralWidget.ui',
27 'ui/Settings/SqpSettingsGeneralWidget.ui',
27 'ui/SidePane/SqpSidePane.ui',
28 'ui/SidePane/SqpSidePane.ui',
28 'ui/TimeWidget/TimeWidget.ui',
29 'ui/TimeWidget/TimeWidget.ui',
29 'ui/Variable/VariableInspectorWidget.ui',
30 'ui/Variable/VariableInspectorWidget.ui',
30 'ui/Variable/RenameVariableDialog.ui',
31 'ui/Variable/RenameVariableDialog.ui',
31 'ui/Variable/VariableMenuHeaderWidget.ui',
32 'ui/Variable/VariableMenuHeaderWidget.ui',
32 'ui/Visualization/VisualizationGraphWidget.ui',
33 'ui/Visualization/VisualizationGraphWidget.ui',
33 'ui/Visualization/VisualizationTabWidget.ui',
34 'ui/Visualization/VisualizationTabWidget.ui',
34 'ui/Visualization/VisualizationWidget.ui',
35 'ui/Visualization/VisualizationWidget.ui',
35 'ui/Visualization/VisualizationZoneWidget.ui'
36 'ui/Visualization/VisualizationZoneWidget.ui'
36 ]
37 ]
37
38
38 gui_qresources = ['resources/sqpguiresources.qrc']
39 gui_qresources = ['resources/sqpguiresources.qrc']
39
40
40 gui_moc_files = qt5.preprocess(moc_headers : gui_moc_headers,
41 gui_moc_files = qt5.preprocess(moc_headers : gui_moc_headers,
41 ui_files : gui_ui_files,
42 ui_files : gui_ui_files,
42 qresources : gui_qresources)
43 qresources : gui_qresources)
43
44
44 gui_sources = [
45 gui_sources = [
45 'src/SqpApplication.cpp',
46 'src/SqpApplication.cpp',
46 'src/DragAndDrop/DragDropHelper.cpp',
47 'src/DragAndDrop/DragDropHelper.cpp',
48 'src/DragAndDrop/DragDropScroller.cpp',
47 'src/Common/ColorUtils.cpp',
49 'src/Common/ColorUtils.cpp',
48 'src/Common/VisualizationDef.cpp',
50 'src/Common/VisualizationDef.cpp',
49 'src/DataSource/DataSourceTreeWidgetItem.cpp',
51 'src/DataSource/DataSourceTreeWidgetItem.cpp',
50 'src/DataSource/DataSourceTreeWidgetHelper.cpp',
52 'src/DataSource/DataSourceTreeWidgetHelper.cpp',
51 'src/DataSource/DataSourceWidget.cpp',
53 'src/DataSource/DataSourceWidget.cpp',
52 'src/DataSource/DataSourceTreeWidget.cpp',
54 'src/DataSource/DataSourceTreeWidget.cpp',
53 'src/Settings/SqpSettingsDialog.cpp',
55 'src/Settings/SqpSettingsDialog.cpp',
54 'src/Settings/SqpSettingsGeneralWidget.cpp',
56 'src/Settings/SqpSettingsGeneralWidget.cpp',
55 'src/SidePane/SqpSidePane.cpp',
57 'src/SidePane/SqpSidePane.cpp',
56 'src/TimeWidget/TimeWidget.cpp',
58 'src/TimeWidget/TimeWidget.cpp',
57 'src/Variable/VariableInspectorWidget.cpp',
59 'src/Variable/VariableInspectorWidget.cpp',
58 'src/Variable/VariableInspectorTableView.cpp',
60 'src/Variable/VariableInspectorTableView.cpp',
59 'src/Variable/VariableMenuHeaderWidget.cpp',
61 'src/Variable/VariableMenuHeaderWidget.cpp',
60 'src/Variable/RenameVariableDialog.cpp',
62 'src/Variable/RenameVariableDialog.cpp',
61 'src/Visualization/VisualizationGraphHelper.cpp',
63 'src/Visualization/VisualizationGraphHelper.cpp',
62 'src/Visualization/VisualizationGraphRenderingDelegate.cpp',
64 'src/Visualization/VisualizationGraphRenderingDelegate.cpp',
63 'src/Visualization/VisualizationGraphWidget.cpp',
65 'src/Visualization/VisualizationGraphWidget.cpp',
64 'src/Visualization/VisualizationTabWidget.cpp',
66 'src/Visualization/VisualizationTabWidget.cpp',
65 'src/Visualization/VisualizationWidget.cpp',
67 'src/Visualization/VisualizationWidget.cpp',
66 'src/Visualization/VisualizationZoneWidget.cpp',
68 'src/Visualization/VisualizationZoneWidget.cpp',
67 'src/Visualization/qcustomplot.cpp',
69 'src/Visualization/qcustomplot.cpp',
68 'src/Visualization/QCustomPlotSynchronizer.cpp',
70 'src/Visualization/QCustomPlotSynchronizer.cpp',
69 'src/Visualization/operations/FindVariableOperation.cpp',
71 'src/Visualization/operations/FindVariableOperation.cpp',
70 'src/Visualization/operations/GenerateVariableMenuOperation.cpp',
72 'src/Visualization/operations/GenerateVariableMenuOperation.cpp',
71 'src/Visualization/operations/MenuBuilder.cpp',
73 'src/Visualization/operations/MenuBuilder.cpp',
72 'src/Visualization/operations/RemoveVariableOperation.cpp',
74 'src/Visualization/operations/RemoveVariableOperation.cpp',
73 'src/Visualization/operations/RescaleAxeOperation.cpp',
75 'src/Visualization/operations/RescaleAxeOperation.cpp',
74 'src/Visualization/VisualizationDragDropContainer.cpp',
76 'src/Visualization/VisualizationDragDropContainer.cpp',
75 'src/Visualization/VisualizationDragWidget.cpp'
77 'src/Visualization/VisualizationDragWidget.cpp'
76 ]
78 ]
77
79
78 gui_inc = include_directories(['include'])
80 gui_inc = include_directories(['include'])
79
81
80 sciqlop_gui_lib = library('sciqlopgui',
82 sciqlop_gui_lib = library('sciqlopgui',
81 gui_sources,
83 gui_sources,
82 gui_moc_files,
84 gui_moc_files,
83 include_directories : [gui_inc],
85 include_directories : [gui_inc],
84 dependencies : [ qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core],
86 dependencies : [ qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core],
85 install : true
87 install : true
86 )
88 )
87
89
88 sciqlop_gui = declare_dependency(link_with : sciqlop_gui_lib,
90 sciqlop_gui = declare_dependency(link_with : sciqlop_gui_lib,
89 include_directories : gui_inc,
91 include_directories : gui_inc,
90 dependencies : [qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core])
92 dependencies : [qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core])
91
93
@@ -1,381 +1,261
1 #include "DragAndDrop/DragDropHelper.h"
1 #include "DragAndDrop/DragDropHelper.h"
2 #include "DragAndDrop/DragDropScroller.h"
2 #include "SqpApplication.h"
3 #include "SqpApplication.h"
3 #include "Visualization/VisualizationDragDropContainer.h"
4 #include "Visualization/VisualizationDragDropContainer.h"
4 #include "Visualization/VisualizationDragWidget.h"
5 #include "Visualization/VisualizationDragWidget.h"
5 #include "Visualization/VisualizationWidget.h"
6 #include "Visualization/VisualizationWidget.h"
6 #include "Visualization/operations/FindVariableOperation.h"
7 #include "Visualization/operations/FindVariableOperation.h"
7
8
8 #include "Variable/Variable.h"
9 #include "Variable/Variable.h"
9 #include "Variable/VariableController.h"
10 #include "Variable/VariableController.h"
10
11
11 #include "Common/MimeTypesDef.h"
12 #include "Common/MimeTypesDef.h"
12 #include "Common/VisualizationDef.h"
13 #include "Common/VisualizationDef.h"
13
14
14 #include <QDir>
15 #include <QDir>
15 #include <QDragEnterEvent>
16 #include <QDragMoveEvent>
17 #include <QLabel>
16 #include <QLabel>
18 #include <QScrollArea>
17 #include <QUrl>
19 #include <QScrollBar>
20 #include <QTimer>
21 #include <QVBoxLayout>
18 #include <QVBoxLayout>
22
19
23 const int SCROLL_SPEED = 5;
24 const int SCROLL_ZONE_SIZE = 50;
25
20
26 Q_LOGGING_CATEGORY(LOG_DragDropHelper, "DragDrophelper")
21 Q_LOGGING_CATEGORY(LOG_DragDropHelper, "DragDrophelper")
27
22
28 struct DragDropScroller::DragDropScrollerPrivate {
29
30 QList<QScrollArea *> m_ScrollAreas;
31 QScrollArea *m_CurrentScrollArea = nullptr;
32 std::unique_ptr<QTimer> m_Timer = nullptr;
33
34 enum class ScrollDirection { up, down, unknown };
35 ScrollDirection m_Direction = ScrollDirection::unknown;
36
37 explicit DragDropScrollerPrivate() : m_Timer{std::make_unique<QTimer>()}
38 {
39 m_Timer->setInterval(0);
40 }
41 };
42
43 DragDropScroller::DragDropScroller(QObject *parent)
44 : QObject{parent}, impl{spimpl::make_unique_impl<DragDropScrollerPrivate>()}
45 {
46 connect(impl->m_Timer.get(), &QTimer::timeout, this, &DragDropScroller::onTimer);
47 }
48
49 void DragDropScroller::addScrollArea(QScrollArea *scrollArea)
50 {
51 impl->m_ScrollAreas << scrollArea;
52 scrollArea->viewport()->setAcceptDrops(true);
53 }
54
55 void DragDropScroller::removeScrollArea(QScrollArea *scrollArea)
56 {
57 impl->m_ScrollAreas.removeAll(scrollArea);
58 scrollArea->viewport()->setAcceptDrops(false);
59 }
60
61 bool DragDropScroller::eventFilter(QObject *obj, QEvent *event)
62 {
63 if (event->type() == QEvent::DragMove) {
64 auto w = static_cast<QWidget *>(obj);
65
66 if (impl->m_CurrentScrollArea && impl->m_CurrentScrollArea->isAncestorOf(w)) {
67 auto moveEvent = static_cast<QDragMoveEvent *>(event);
68
69 auto pos = moveEvent->pos();
70 if (impl->m_CurrentScrollArea->viewport() != w) {
71 auto globalPos = w->mapToGlobal(moveEvent->pos());
72 pos = impl->m_CurrentScrollArea->viewport()->mapFromGlobal(globalPos);
73 }
74
75 auto isInTopZone = pos.y() > impl->m_CurrentScrollArea->viewport()->size().height()
76 - SCROLL_ZONE_SIZE;
77 auto isInBottomZone = pos.y() < SCROLL_ZONE_SIZE;
78
79 if (!isInTopZone && !isInBottomZone) {
80 impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown;
81 impl->m_Timer->stop();
82 }
83 else if (!impl->m_Timer->isActive()) {
84 impl->m_Direction = isInTopZone ? DragDropScrollerPrivate::ScrollDirection::up
85 : DragDropScrollerPrivate::ScrollDirection::down;
86 impl->m_Timer->start();
87 }
88 }
89 }
90 else if (event->type() == QEvent::DragEnter) {
91 auto w = static_cast<QWidget *>(obj);
92
93 for (auto scrollArea : impl->m_ScrollAreas) {
94 if (impl->m_CurrentScrollArea != scrollArea && scrollArea->isAncestorOf(w)) {
95 auto enterEvent = static_cast<QDragEnterEvent *>(event);
96 enterEvent->acceptProposedAction();
97 enterEvent->setDropAction(Qt::IgnoreAction);
98 impl->m_CurrentScrollArea = scrollArea;
99 break;
100 }
101 }
102 }
103 else if (event->type() == QEvent::DragLeave) {
104 if (impl->m_CurrentScrollArea) {
105 if (!QRect(QPoint(), impl->m_CurrentScrollArea->size())
106 .contains(impl->m_CurrentScrollArea->mapFromGlobal(QCursor::pos()))) {
107 impl->m_CurrentScrollArea = nullptr;
108 impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown;
109 impl->m_Timer->stop();
110 }
111 }
112 }
113 else if (event->type() == QEvent::Drop) {
114 if (impl->m_CurrentScrollArea) {
115 impl->m_CurrentScrollArea = nullptr;
116 impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown;
117 impl->m_Timer->stop();
118 }
119 }
120
121 return false;
122 }
123
124 void DragDropScroller::onTimer()
125 {
126 if (impl->m_CurrentScrollArea) {
127 auto mvt = 0;
128 switch (impl->m_Direction) {
129 case DragDropScrollerPrivate::ScrollDirection::up:
130 mvt = SCROLL_SPEED;
131 break;
132 case DragDropScrollerPrivate::ScrollDirection::down:
133 mvt = -SCROLL_SPEED;
134 break;
135 default:
136 break;
137 }
138
139 impl->m_CurrentScrollArea->verticalScrollBar()->setValue(
140 impl->m_CurrentScrollArea->verticalScrollBar()->value() + mvt);
141 }
142 }
143
23
144 struct DragDropHelper::DragDropHelperPrivate {
24 struct DragDropHelper::DragDropHelperPrivate {
145
25
146 VisualizationDragWidget *m_CurrentDragWidget = nullptr;
26 VisualizationDragWidget *m_CurrentDragWidget = nullptr;
147 std::unique_ptr<QWidget> m_PlaceHolder = nullptr;
27 std::unique_ptr<QWidget> m_PlaceHolder = nullptr;
148 QLabel *m_PlaceHolderLabel;
28 QLabel *m_PlaceHolderLabel;
149 QWidget *m_PlaceBackground;
29 QWidget *m_PlaceBackground;
150 std::unique_ptr<DragDropScroller> m_DragDropScroller = nullptr;
30 std::unique_ptr<DragDropScroller> m_DragDropScroller = nullptr;
151 QString m_ImageTempUrl; // Temporary file for image url generated by the drag & drop. Not using
31 QString m_ImageTempUrl; // Temporary file for image url generated by the drag & drop. Not using
152 // QTemporaryFile to have a name which is not generated.
32 // QTemporaryFile to have a name which is not generated.
153
33
154 VisualizationDragWidget *m_HighlightedDragWidget = nullptr;
34 VisualizationDragWidget *m_HighlightedDragWidget = nullptr;
155
35
156 QMetaObject::Connection m_DragWidgetDestroyedConnection;
36 QMetaObject::Connection m_DragWidgetDestroyedConnection;
157 QMetaObject::Connection m_HighlightedWidgetDestroyedConnection;
37 QMetaObject::Connection m_HighlightedWidgetDestroyedConnection;
158
38
159 explicit DragDropHelperPrivate()
39 explicit DragDropHelperPrivate()
160 : m_PlaceHolder{std::make_unique<QWidget>()},
40 : m_PlaceHolder{std::make_unique<QWidget>()},
161 m_DragDropScroller{std::make_unique<DragDropScroller>()}
41 m_DragDropScroller{std::make_unique<DragDropScroller>()}
162 {
42 {
163
43
164 auto layout = new QVBoxLayout{m_PlaceHolder.get()};
44 auto layout = new QVBoxLayout{m_PlaceHolder.get()};
165 layout->setSpacing(0);
45 layout->setSpacing(0);
166 layout->setContentsMargins(0, 0, 0, 0);
46 layout->setContentsMargins(0, 0, 0, 0);
167
47
168 m_PlaceHolderLabel = new QLabel{"", m_PlaceHolder.get()};
48 m_PlaceHolderLabel = new QLabel{"", m_PlaceHolder.get()};
169 m_PlaceHolderLabel->setMinimumHeight(25);
49 m_PlaceHolderLabel->setMinimumHeight(25);
170 layout->addWidget(m_PlaceHolderLabel);
50 layout->addWidget(m_PlaceHolderLabel);
171
51
172 m_PlaceBackground = new QWidget{m_PlaceHolder.get()};
52 m_PlaceBackground = new QWidget{m_PlaceHolder.get()};
173 m_PlaceBackground->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
53 m_PlaceBackground->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
174 layout->addWidget(m_PlaceBackground);
54 layout->addWidget(m_PlaceBackground);
175
55
176 sqpApp->installEventFilter(m_DragDropScroller.get());
56 sqpApp->installEventFilter(m_DragDropScroller.get());
177
57
178 m_ImageTempUrl = QDir::temp().absoluteFilePath("Sciqlop_graph.png");
58 m_ImageTempUrl = QDir::temp().absoluteFilePath("Sciqlop_graph.png");
179 }
59 }
180
60
181 void preparePlaceHolder(DragDropHelper::PlaceHolderType type, const QString &topLabelText) const
61 void preparePlaceHolder(DragDropHelper::PlaceHolderType type, const QString &topLabelText) const
182 {
62 {
183 if (m_CurrentDragWidget) {
63 if (m_CurrentDragWidget) {
184 m_PlaceHolder->setMinimumSize(m_CurrentDragWidget->size());
64 m_PlaceHolder->setMinimumSize(m_CurrentDragWidget->size());
185 m_PlaceHolder->setSizePolicy(m_CurrentDragWidget->sizePolicy());
65 m_PlaceHolder->setSizePolicy(m_CurrentDragWidget->sizePolicy());
186 }
66 }
187 else {
67 else {
188 // Configuration of the placeHolder when there is no dragWidget
68 // Configuration of the placeHolder when there is no dragWidget
189 // (for instance with a drag from a variable)
69 // (for instance with a drag from a variable)
190
70
191 m_PlaceHolder->setMinimumSize(0, GRAPH_MINIMUM_HEIGHT);
71 m_PlaceHolder->setMinimumSize(0, GRAPH_MINIMUM_HEIGHT);
192 m_PlaceHolder->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
72 m_PlaceHolder->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
193 }
73 }
194
74
195 switch (type) {
75 switch (type) {
196 case DragDropHelper::PlaceHolderType::Graph:
76 case DragDropHelper::PlaceHolderType::Graph:
197 m_PlaceBackground->setStyleSheet(
77 m_PlaceBackground->setStyleSheet(
198 "background-color: #BBD5EE; border: 1px solid #2A7FD4");
78 "background-color: #BBD5EE; border: 1px solid #2A7FD4");
199 break;
79 break;
200 case DragDropHelper::PlaceHolderType::Zone:
80 case DragDropHelper::PlaceHolderType::Zone:
201 case DragDropHelper::PlaceHolderType::Default:
81 case DragDropHelper::PlaceHolderType::Default:
202 m_PlaceBackground->setStyleSheet(
82 m_PlaceBackground->setStyleSheet(
203 "background-color: #BBD5EE; border: 2px solid #2A7FD4");
83 "background-color: #BBD5EE; border: 2px solid #2A7FD4");
204 m_PlaceHolderLabel->setStyleSheet("color: #2A7FD4");
84 m_PlaceHolderLabel->setStyleSheet("color: #2A7FD4");
205 break;
85 break;
206 }
86 }
207
87
208 m_PlaceHolderLabel->setText(topLabelText);
88 m_PlaceHolderLabel->setText(topLabelText);
209 m_PlaceHolderLabel->setVisible(!topLabelText.isEmpty());
89 m_PlaceHolderLabel->setVisible(!topLabelText.isEmpty());
210 }
90 }
211 };
91 };
212
92
213
93
214 DragDropHelper::DragDropHelper() : impl{spimpl::make_unique_impl<DragDropHelperPrivate>()} {}
94 DragDropHelper::DragDropHelper() : impl{spimpl::make_unique_impl<DragDropHelperPrivate>()} {}
215
95
216 DragDropHelper::~DragDropHelper()
96 DragDropHelper::~DragDropHelper()
217 {
97 {
218 QFile::remove(impl->m_ImageTempUrl);
98 QFile::remove(impl->m_ImageTempUrl);
219 }
99 }
220
100
221 void DragDropHelper::resetDragAndDrop()
101 void DragDropHelper::resetDragAndDrop()
222 {
102 {
223 setCurrentDragWidget(nullptr);
103 setCurrentDragWidget(nullptr);
224 impl->m_HighlightedDragWidget = nullptr;
104 impl->m_HighlightedDragWidget = nullptr;
225 }
105 }
226
106
227 void DragDropHelper::setCurrentDragWidget(VisualizationDragWidget *dragWidget)
107 void DragDropHelper::setCurrentDragWidget(VisualizationDragWidget *dragWidget)
228 {
108 {
229 if (impl->m_CurrentDragWidget) {
109 if (impl->m_CurrentDragWidget) {
230
110
231 QObject::disconnect(impl->m_DragWidgetDestroyedConnection);
111 QObject::disconnect(impl->m_DragWidgetDestroyedConnection);
232 }
112 }
233
113
234 if (dragWidget) {
114 if (dragWidget) {
235 // ensures the impl->m_CurrentDragWidget is reset when the widget is destroyed
115 // ensures the impl->m_CurrentDragWidget is reset when the widget is destroyed
236 impl->m_DragWidgetDestroyedConnection
116 impl->m_DragWidgetDestroyedConnection
237 = QObject::connect(dragWidget, &VisualizationDragWidget::destroyed,
117 = QObject::connect(dragWidget, &VisualizationDragWidget::destroyed,
238 [this]() { impl->m_CurrentDragWidget = nullptr; });
118 [this]() { impl->m_CurrentDragWidget = nullptr; });
239 }
119 }
240
120
241 impl->m_CurrentDragWidget = dragWidget;
121 impl->m_CurrentDragWidget = dragWidget;
242 }
122 }
243
123
244 VisualizationDragWidget *DragDropHelper::getCurrentDragWidget() const
124 VisualizationDragWidget *DragDropHelper::getCurrentDragWidget() const
245 {
125 {
246 return impl->m_CurrentDragWidget;
126 return impl->m_CurrentDragWidget;
247 }
127 }
248
128
249 QWidget &DragDropHelper::placeHolder() const
129 QWidget &DragDropHelper::placeHolder() const
250 {
130 {
251 return *impl->m_PlaceHolder;
131 return *impl->m_PlaceHolder;
252 }
132 }
253
133
254 void DragDropHelper::insertPlaceHolder(QVBoxLayout *layout, int index, PlaceHolderType type,
134 void DragDropHelper::insertPlaceHolder(QVBoxLayout *layout, int index, PlaceHolderType type,
255 const QString &topLabelText)
135 const QString &topLabelText)
256 {
136 {
257 removePlaceHolder();
137 removePlaceHolder();
258 impl->preparePlaceHolder(type, topLabelText);
138 impl->preparePlaceHolder(type, topLabelText);
259 layout->insertWidget(index, impl->m_PlaceHolder.get());
139 layout->insertWidget(index, impl->m_PlaceHolder.get());
260 impl->m_PlaceHolder->show();
140 impl->m_PlaceHolder->show();
261 }
141 }
262
142
263 void DragDropHelper::removePlaceHolder()
143 void DragDropHelper::removePlaceHolder()
264 {
144 {
265 auto parentWidget = impl->m_PlaceHolder->parentWidget();
145 auto parentWidget = impl->m_PlaceHolder->parentWidget();
266 if (parentWidget) {
146 if (parentWidget) {
267 parentWidget->layout()->removeWidget(impl->m_PlaceHolder.get());
147 parentWidget->layout()->removeWidget(impl->m_PlaceHolder.get());
268 impl->m_PlaceHolder->setParent(nullptr);
148 impl->m_PlaceHolder->setParent(nullptr);
269 impl->m_PlaceHolder->hide();
149 impl->m_PlaceHolder->hide();
270 }
150 }
271 }
151 }
272
152
273 bool DragDropHelper::isPlaceHolderSet() const
153 bool DragDropHelper::isPlaceHolderSet() const
274 {
154 {
275 return impl->m_PlaceHolder->parentWidget();
155 return impl->m_PlaceHolder->parentWidget();
276 }
156 }
277
157
278 void DragDropHelper::addDragDropScrollArea(QScrollArea *scrollArea)
158 void DragDropHelper::addDragDropScrollArea(QScrollArea *scrollArea)
279 {
159 {
280 impl->m_DragDropScroller->addScrollArea(scrollArea);
160 impl->m_DragDropScroller->addScrollArea(scrollArea);
281 }
161 }
282
162
283 void DragDropHelper::removeDragDropScrollArea(QScrollArea *scrollArea)
163 void DragDropHelper::removeDragDropScrollArea(QScrollArea *scrollArea)
284 {
164 {
285 impl->m_DragDropScroller->removeScrollArea(scrollArea);
165 impl->m_DragDropScroller->removeScrollArea(scrollArea);
286 }
166 }
287
167
288 QUrl DragDropHelper::imageTemporaryUrl(const QImage &image) const
168 QUrl DragDropHelper::imageTemporaryUrl(const QImage &image) const
289 {
169 {
290 image.save(impl->m_ImageTempUrl);
170 image.save(impl->m_ImageTempUrl);
291 return QUrl::fromLocalFile(impl->m_ImageTempUrl);
171 return QUrl::fromLocalFile(impl->m_ImageTempUrl);
292 }
172 }
293
173
294 void DragDropHelper::setHightlightedDragWidget(VisualizationDragWidget *dragWidget)
174 void DragDropHelper::setHightlightedDragWidget(VisualizationDragWidget *dragWidget)
295 {
175 {
296 if (impl->m_HighlightedDragWidget) {
176 if (impl->m_HighlightedDragWidget) {
297 impl->m_HighlightedDragWidget->highlightForMerge(false);
177 impl->m_HighlightedDragWidget->highlightForMerge(false);
298 QObject::disconnect(impl->m_HighlightedWidgetDestroyedConnection);
178 QObject::disconnect(impl->m_HighlightedWidgetDestroyedConnection);
299 }
179 }
300
180
301 if (dragWidget) {
181 if (dragWidget) {
302 dragWidget->highlightForMerge(true);
182 dragWidget->highlightForMerge(true);
303
183
304 // ensures the impl->m_HighlightedDragWidget is reset when the widget is destroyed
184 // ensures the impl->m_HighlightedDragWidget is reset when the widget is destroyed
305 impl->m_DragWidgetDestroyedConnection
185 impl->m_DragWidgetDestroyedConnection
306 = QObject::connect(dragWidget, &VisualizationDragWidget::destroyed,
186 = QObject::connect(dragWidget, &VisualizationDragWidget::destroyed,
307 [this]() { impl->m_HighlightedDragWidget = nullptr; });
187 [this]() { impl->m_HighlightedDragWidget = nullptr; });
308 }
188 }
309
189
310 impl->m_HighlightedDragWidget = dragWidget;
190 impl->m_HighlightedDragWidget = dragWidget;
311 }
191 }
312
192
313 VisualizationDragWidget *DragDropHelper::getHightlightedDragWidget() const
193 VisualizationDragWidget *DragDropHelper::getHightlightedDragWidget() const
314 {
194 {
315 return impl->m_HighlightedDragWidget;
195 return impl->m_HighlightedDragWidget;
316 }
196 }
317
197
318 bool DragDropHelper::checkMimeDataForVisualization(const QMimeData *mimeData,
198 bool DragDropHelper::checkMimeDataForVisualization(const QMimeData *mimeData,
319 VisualizationDragDropContainer *dropContainer)
199 VisualizationDragDropContainer *dropContainer)
320 {
200 {
321 if (!mimeData || !dropContainer) {
201 if (!mimeData || !dropContainer) {
322 qCWarning(LOG_DragDropHelper()) << QObject::tr(
202 qCWarning(LOG_DragDropHelper()) << QObject::tr(
323 "DragDropHelper::checkMimeDataForVisualization, invalid input parameters.");
203 "DragDropHelper::checkMimeDataForVisualization, invalid input parameters.");
324 Q_ASSERT(false);
204 Q_ASSERT(false);
325 return false;
205 return false;
326 }
206 }
327
207
328 auto result = false;
208 auto result = false;
329
209
330 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
210 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
331 auto variables = sqpApp->variableController().variablesForMimeData(
211 auto variables = sqpApp->variableController().variablesForMimeData(
332 mimeData->data(MIME_TYPE_VARIABLE_LIST));
212 mimeData->data(MIME_TYPE_VARIABLE_LIST));
333
213
334 if (variables.count() == 1) {
214 if (variables.count() == 1) {
335
215
336 auto variable = variables.first();
216 auto variable = variables.first();
337 if (variable->dataSeries() != nullptr) {
217 if (variable->dataSeries() != nullptr) {
338
218
339 // Check that the variable is not already in a graph
219 // Check that the variable is not already in a graph
340
220
341 auto parent = dropContainer->parentWidget();
221 auto parent = dropContainer->parentWidget();
342 while (parent && qobject_cast<VisualizationWidget *>(parent) == nullptr) {
222 while (parent && qobject_cast<VisualizationWidget *>(parent) == nullptr) {
343 parent = parent->parentWidget(); // Search for the top level VisualizationWidget
223 parent = parent->parentWidget(); // Search for the top level VisualizationWidget
344 }
224 }
345
225
346 if (parent) {
226 if (parent) {
347 auto visualizationWidget = static_cast<VisualizationWidget *>(parent);
227 auto visualizationWidget = static_cast<VisualizationWidget *>(parent);
348
228
349 FindVariableOperation findVariableOperation{variable};
229 FindVariableOperation findVariableOperation{variable};
350 visualizationWidget->accept(&findVariableOperation);
230 visualizationWidget->accept(&findVariableOperation);
351 auto variableContainers = findVariableOperation.result();
231 auto variableContainers = findVariableOperation.result();
352 if (variableContainers.empty()) {
232 if (variableContainers.empty()) {
353 result = true;
233 result = true;
354 }
234 }
355 else {
235 else {
356 // result = false: the variable already exist in the visualisation
236 // result = false: the variable already exist in the visualisation
357 }
237 }
358 }
238 }
359 else {
239 else {
360 qCWarning(LOG_DragDropHelper()) << QObject::tr(
240 qCWarning(LOG_DragDropHelper()) << QObject::tr(
361 "DragDropHelper::checkMimeDataForVisualization, the parent "
241 "DragDropHelper::checkMimeDataForVisualization, the parent "
362 "VisualizationWidget cannot be found. Cannot check if the variable is "
242 "VisualizationWidget cannot be found. Cannot check if the variable is "
363 "already used or not.");
243 "already used or not.");
364 }
244 }
365 }
245 }
366 else {
246 else {
367 // result = false: the variable is not fully loaded
247 // result = false: the variable is not fully loaded
368 }
248 }
369 }
249 }
370 else {
250 else {
371 // result = false: cannot drop multiple variables in the visualisation
251 // result = false: cannot drop multiple variables in the visualisation
372 }
252 }
373 }
253 }
374 else {
254 else {
375 // Other MIME data
255 // Other MIME data
376 // no special rules, accepted by default
256 // no special rules, accepted by default
377 result = true;
257 result = true;
378 }
258 }
379
259
380 return result;
260 return result;
381 }
261 }
General Comments 3
Under Review
author

Pull request updated. Auto status change to "Under Review"

Changed commits:
  * 1 added
  * 0 removed

Changed files:
  * A core/tests/meson.build
You need to be logged in to leave comments. Login now