##// END OF EJS Templates
New event filter class to manage the tab switching of a tabBar during a drag&drop
trabillard -
r892:28af007d2663
parent child
Show More
@@ -0,0 +1,29
1 #ifndef SCIQLOP_DRAGDROPTABSWITCHER_H
2 #define SCIQLOP_DRAGDROPTABSWITCHER_H
3
4 #include <Common/spimpl.h>
5
6 #include <QLoggingCategory>
7 #include <QTabBar>
8
9 Q_DECLARE_LOGGING_CATEGORY(LOG_DragDropTabSwitcher)
10
11 class DragDropTabSwitcher : public QObject {
12 Q_OBJECT
13
14 public:
15 DragDropTabSwitcher(QObject *parent = nullptr);
16
17 void addTabBar(QTabBar *tabBar);
18 void removeTabBar(QTabBar *tabBar);
19
20 protected:
21 bool eventFilter(QObject *obj, QEvent *event);
22
23 private:
24 class DragDropTabSwitcherPrivate;
25 spimpl::unique_impl_ptr<DragDropTabSwitcherPrivate> impl;
26 };
27
28
29 #endif // SCIQLOP_DRAGDROPTABSWITCHER_H
@@ -0,0 +1,180
1 #include "DragAndDrop/DragDropTabSwitcher.h"
2
3 #include <QAbstractButton>
4 #include <QDragEnterEvent>
5 #include <QDragMoveEvent>
6 #include <QTimer>
7
8 #include "SqpApplication.h"
9
10 Q_LOGGING_CATEGORY(LOG_DragDropTabSwitcher, "DragDropTabSwitcher")
11
12 const int CHANGE_TAB_INTERVAL = 400; // time necessary over a tab to accept the switch
13 const int SCROLL_BUTTON_AUTO_CLICK_INTERVAL
14 = 500; // time between 2 auto clicks on a scroll button of the tab bar
15
16 struct DragDropTabSwitcher::DragDropTabSwitcherPrivate {
17
18 QList<QTabBar *> m_TabBarList;
19 QTabBar *m_CurrentTabBar = nullptr;
20
21 int m_HoveredTabIndex = -1;
22 std::unique_ptr<QTimer> m_TabSwitchTimer = nullptr;
23
24 QAbstractButton *m_HoveredScrollButton = nullptr;
25 std::unique_ptr<QTimer> m_ScrollButtonsTimer = nullptr;
26
27 explicit DragDropTabSwitcherPrivate()
28 : m_TabSwitchTimer{std::make_unique<QTimer>()},
29 m_ScrollButtonsTimer{std::make_unique<QTimer>()}
30 {
31 m_TabSwitchTimer->setSingleShot(true);
32 m_TabSwitchTimer->setInterval(CHANGE_TAB_INTERVAL);
33 QObject::connect(m_TabSwitchTimer.get(), &QTimer::timeout, [this]() {
34 if (m_CurrentTabBar) {
35 m_CurrentTabBar->setCurrentIndex(m_HoveredTabIndex);
36 }
37 else {
38 qCWarning(LOG_DragDropTabSwitcher()) << "DragDropTabSwitcherPrivate::timeout: "
39 "Cannot select a new tab: unknown current "
40 "tab bar.";
41 }
42 });
43
44 m_ScrollButtonsTimer->setInterval(SCROLL_BUTTON_AUTO_CLICK_INTERVAL);
45 QObject::connect(m_ScrollButtonsTimer.get(), &QTimer::timeout, [this]() {
46 if (m_HoveredScrollButton) {
47 m_HoveredScrollButton->animateClick();
48 }
49 else {
50 qCWarning(LOG_DragDropTabSwitcher())
51 << "DragDropTabSwitcherPrivate::timeoutScroll: "
52 "Unknown scroll button";
53 }
54 });
55 }
56
57 bool isScrollTabButton(QAbstractButton *button, QTabBar *tabBar)
58 {
59 auto isNextOrPreviousTabButton = true;
60
61 if (tabBar->isAncestorOf(button)) {
62 for (auto i = 0; i < tabBar->count(); ++i) {
63 if (tabBar->tabButton(i, QTabBar::RightSide) == button
64 || tabBar->tabButton(i, QTabBar::LeftSide) == button) {
65 isNextOrPreviousTabButton = false;
66 break;
67 }
68 }
69 }
70 else {
71 isNextOrPreviousTabButton = false;
72 }
73
74 return isNextOrPreviousTabButton;
75 }
76
77 QAbstractButton *tabScrollButtonAt(const QPoint &pos, QTabBar *tabBar)
78 {
79
80 auto globalPos = tabBar->mapToGlobal(pos);
81
82 auto widgetUnderMouse = sqpApp->widgetAt(globalPos);
83 if (auto btn = qobject_cast<QAbstractButton *>(widgetUnderMouse)) {
84
85 if (isScrollTabButton(btn, tabBar)) {
86 return btn;
87 }
88 }
89
90 return nullptr;
91 }
92 };
93
94 DragDropTabSwitcher::DragDropTabSwitcher(QObject *parent)
95 : QObject(parent), impl{spimpl::make_unique_impl<DragDropTabSwitcherPrivate>()}
96 {
97 }
98
99 void DragDropTabSwitcher::addTabBar(QTabBar *tabBar)
100 {
101 impl->m_TabBarList << tabBar;
102 tabBar->setAcceptDrops(true);
103 }
104
105 void DragDropTabSwitcher::removeTabBar(QTabBar *tabBar)
106 {
107 impl->m_TabBarList.removeAll(tabBar);
108 tabBar->setAcceptDrops(false);
109 }
110
111 bool DragDropTabSwitcher::eventFilter(QObject *obj, QEvent *event)
112 {
113 if (event->type() == QEvent::DragMove) {
114
115 if (impl->m_CurrentTabBar) {
116
117 QWidget *w = static_cast<QWidget *>(obj);
118 if (!impl->m_CurrentTabBar->isAncestorOf(w)) {
119 return false;
120 }
121
122 auto moveEvent = static_cast<QDragMoveEvent *>(event);
123
124 auto scrollButton = impl->tabScrollButtonAt(moveEvent->pos(), impl->m_CurrentTabBar);
125
126 if (!scrollButton) {
127
128 auto tabIndex = impl->m_CurrentTabBar->tabAt(moveEvent->pos());
129 if (tabIndex >= 0 && tabIndex != impl->m_CurrentTabBar->currentIndex()) {
130 // The mouse is over an unselected tab
131 if (!impl->m_TabSwitchTimer->isActive()
132 || tabIndex != impl->m_HoveredTabIndex) {
133 impl->m_HoveredTabIndex = tabIndex;
134 impl->m_TabSwitchTimer->start();
135 }
136 else {
137 // do nothing, timer already running
138 }
139 }
140 else {
141 impl->m_TabSwitchTimer->stop();
142 }
143
144 impl->m_ScrollButtonsTimer->stop();
145 }
146 else {
147 // The mouse is over a scroll button
148 // click it in a loop with a timer
149 if (!impl->m_ScrollButtonsTimer->isActive()
150 || impl->m_HoveredScrollButton != scrollButton) {
151 impl->m_HoveredScrollButton = scrollButton;
152 impl->m_ScrollButtonsTimer->start();
153 }
154 }
155 }
156 }
157 else if (event->type() == QEvent::DragEnter) {
158 QWidget *w = static_cast<QWidget *>(obj);
159
160 for (auto tabBar : impl->m_TabBarList) {
161 if (w == tabBar) {
162 auto enterEvent = static_cast<QDragEnterEvent *>(event);
163 enterEvent->acceptProposedAction();
164 enterEvent->setDropAction(Qt::IgnoreAction);
165 impl->m_CurrentTabBar = tabBar;
166 break;
167 }
168 }
169 }
170 else if (event->type() == QEvent::DragLeave || event->type() == QEvent::Drop) {
171 if (impl->m_CurrentTabBar) {
172 impl->m_HoveredTabIndex = -1;
173 impl->m_TabSwitchTimer->stop();
174 impl->m_CurrentTabBar = nullptr;
175 impl->m_ScrollButtonsTimer->stop();
176 }
177 }
178
179 return false;
180 }
@@ -1,67 +1,71
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 QTabBar;
10 class VisualizationDragWidget;
11 class VisualizationDragWidget;
11 class VisualizationDragDropContainer;
12 class VisualizationDragDropContainer;
12 class QMimeData;
13 class QMimeData;
13
14
14 Q_DECLARE_LOGGING_CATEGORY(LOG_DragDropHelper)
15 Q_DECLARE_LOGGING_CATEGORY(LOG_DragDropHelper)
15
16
16 /**
17 /**
17 * @brief Helper class for drag&drop operations.
18 * @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
19 * @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
20 * application (like a controller). But contrary to a controller, it doesn't live in a thread and
20 * can interect with the gui.
21 * can interect with the gui.
21 * @see SqpApplication
22 * @see SqpApplication
22 */
23 */
23 class DragDropHelper {
24 class DragDropHelper {
24 public:
25 public:
25 static const QString MIME_TYPE_GRAPH;
26 static const QString MIME_TYPE_GRAPH;
26 static const QString MIME_TYPE_ZONE;
27 static const QString MIME_TYPE_ZONE;
27
28
28 enum class PlaceHolderType { Default, Graph, Zone };
29 enum class PlaceHolderType { Default, Graph, Zone };
29
30
30 DragDropHelper();
31 DragDropHelper();
31 virtual ~DragDropHelper();
32 virtual ~DragDropHelper();
32
33
33 /// Resets some internal variables. Must be called before any new drag&drop operation.
34 /// Resets some internal variables. Must be called before any new drag&drop operation.
34 void resetDragAndDrop();
35 void resetDragAndDrop();
35
36
36 /// Sets the visualization widget currently being drag on the visualization.
37 /// Sets the visualization widget currently being drag on the visualization.
37 void setCurrentDragWidget(VisualizationDragWidget *dragWidget);
38 void setCurrentDragWidget(VisualizationDragWidget *dragWidget);
38
39
39 /// Returns the visualization widget currently being drag on the visualization.
40 /// 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
41 /// Can be null if a new visualization widget is intended to be created by the drag&drop
41 /// operation.
42 /// operation.
42 VisualizationDragWidget *getCurrentDragWidget() const;
43 VisualizationDragWidget *getCurrentDragWidget() const;
43
44
44 QWidget &placeHolder() const;
45 QWidget &placeHolder() const;
45 void insertPlaceHolder(QVBoxLayout *layout, int index, PlaceHolderType type,
46 void insertPlaceHolder(QVBoxLayout *layout, int index, PlaceHolderType type,
46 const QString &topLabelText);
47 const QString &topLabelText);
47 void removePlaceHolder();
48 void removePlaceHolder();
48 bool isPlaceHolderSet() const;
49 bool isPlaceHolderSet() const;
49
50
50 /// Checks if the specified mime data is valid for a drop in the visualization
51 /// Checks if the specified mime data is valid for a drop in the visualization
51 bool checkMimeDataForVisualization(const QMimeData *mimeData,
52 bool checkMimeDataForVisualization(const QMimeData *mimeData,
52 VisualizationDragDropContainer *dropContainer);
53 VisualizationDragDropContainer *dropContainer);
53
54
54 void addDragDropScrollArea(QScrollArea *scrollArea);
55 void addDragDropScrollArea(QScrollArea *scrollArea);
55 void removeDragDropScrollArea(QScrollArea *scrollArea);
56 void removeDragDropScrollArea(QScrollArea *scrollArea);
56
57
58 void addDragDropTabBar(QTabBar *tabBar);
59 void removeDragDropTabBar(QTabBar *tabBar);
60
57 QUrl imageTemporaryUrl(const QImage &image) const;
61 QUrl imageTemporaryUrl(const QImage &image) const;
58
62
59 void setHightlightedDragWidget(VisualizationDragWidget *dragWidget);
63 void setHightlightedDragWidget(VisualizationDragWidget *dragWidget);
60 VisualizationDragWidget *getHightlightedDragWidget() const;
64 VisualizationDragWidget *getHightlightedDragWidget() const;
61
65
62 private:
66 private:
63 class DragDropHelperPrivate;
67 class DragDropHelperPrivate;
64 spimpl::unique_impl_ptr<DragDropHelperPrivate> impl;
68 spimpl::unique_impl_ptr<DragDropHelperPrivate> impl;
65 };
69 };
66
70
67 #endif // SCIQLOP_DRAGDROPHELPER_H
71 #endif // SCIQLOP_DRAGDROPHELPER_H
@@ -1,93 +1,95
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/DragAndDrop/DragDropScroller.h',
11 'include/DragAndDrop/DragDropTabSwitcher.h',
11 'include/TimeWidget/TimeWidget.h',
12 'include/TimeWidget/TimeWidget.h',
12 'include/Variable/VariableInspectorWidget.h',
13 'include/Variable/VariableInspectorWidget.h',
13 'include/Variable/VariableInspectorTableView.h',
14 'include/Variable/VariableInspectorTableView.h',
14 'include/Variable/RenameVariableDialog.h',
15 'include/Variable/RenameVariableDialog.h',
15 'include/Visualization/qcustomplot.h',
16 'include/Visualization/qcustomplot.h',
16 'include/Visualization/VisualizationGraphWidget.h',
17 'include/Visualization/VisualizationGraphWidget.h',
17 'include/Visualization/VisualizationTabWidget.h',
18 'include/Visualization/VisualizationTabWidget.h',
18 'include/Visualization/VisualizationWidget.h',
19 'include/Visualization/VisualizationWidget.h',
19 'include/Visualization/VisualizationZoneWidget.h',
20 'include/Visualization/VisualizationZoneWidget.h',
20 'include/Visualization/VisualizationDragDropContainer.h',
21 'include/Visualization/VisualizationDragDropContainer.h',
21 'include/Visualization/VisualizationDragWidget.h'
22 'include/Visualization/VisualizationDragWidget.h'
22 ]
23 ]
23
24
24 gui_ui_files = [
25 gui_ui_files = [
25 'ui/DataSource/DataSourceWidget.ui',
26 'ui/DataSource/DataSourceWidget.ui',
26 'ui/Settings/SqpSettingsDialog.ui',
27 'ui/Settings/SqpSettingsDialog.ui',
27 'ui/Settings/SqpSettingsGeneralWidget.ui',
28 'ui/Settings/SqpSettingsGeneralWidget.ui',
28 'ui/SidePane/SqpSidePane.ui',
29 'ui/SidePane/SqpSidePane.ui',
29 'ui/TimeWidget/TimeWidget.ui',
30 'ui/TimeWidget/TimeWidget.ui',
30 'ui/Variable/VariableInspectorWidget.ui',
31 'ui/Variable/VariableInspectorWidget.ui',
31 'ui/Variable/RenameVariableDialog.ui',
32 'ui/Variable/RenameVariableDialog.ui',
32 'ui/Variable/VariableMenuHeaderWidget.ui',
33 'ui/Variable/VariableMenuHeaderWidget.ui',
33 'ui/Visualization/VisualizationGraphWidget.ui',
34 'ui/Visualization/VisualizationGraphWidget.ui',
34 'ui/Visualization/VisualizationTabWidget.ui',
35 'ui/Visualization/VisualizationTabWidget.ui',
35 'ui/Visualization/VisualizationWidget.ui',
36 'ui/Visualization/VisualizationWidget.ui',
36 'ui/Visualization/VisualizationZoneWidget.ui'
37 'ui/Visualization/VisualizationZoneWidget.ui'
37 ]
38 ]
38
39
39 gui_qresources = ['resources/sqpguiresources.qrc']
40 gui_qresources = ['resources/sqpguiresources.qrc']
40
41
41 gui_moc_files = qt5.preprocess(moc_headers : gui_moc_headers,
42 gui_moc_files = qt5.preprocess(moc_headers : gui_moc_headers,
42 ui_files : gui_ui_files,
43 ui_files : gui_ui_files,
43 qresources : gui_qresources)
44 qresources : gui_qresources)
44
45
45 gui_sources = [
46 gui_sources = [
46 'src/SqpApplication.cpp',
47 'src/SqpApplication.cpp',
47 'src/DragAndDrop/DragDropHelper.cpp',
48 'src/DragAndDrop/DragDropHelper.cpp',
48 'src/DragAndDrop/DragDropScroller.cpp',
49 'src/DragAndDrop/DragDropScroller.cpp',
50 'src/DragAndDrop/DragDropTabSwitcher.cpp',
49 'src/Common/ColorUtils.cpp',
51 'src/Common/ColorUtils.cpp',
50 'src/Common/VisualizationDef.cpp',
52 'src/Common/VisualizationDef.cpp',
51 'src/DataSource/DataSourceTreeWidgetItem.cpp',
53 'src/DataSource/DataSourceTreeWidgetItem.cpp',
52 'src/DataSource/DataSourceTreeWidgetHelper.cpp',
54 'src/DataSource/DataSourceTreeWidgetHelper.cpp',
53 'src/DataSource/DataSourceWidget.cpp',
55 'src/DataSource/DataSourceWidget.cpp',
54 'src/DataSource/DataSourceTreeWidget.cpp',
56 'src/DataSource/DataSourceTreeWidget.cpp',
55 'src/Settings/SqpSettingsDialog.cpp',
57 'src/Settings/SqpSettingsDialog.cpp',
56 'src/Settings/SqpSettingsGeneralWidget.cpp',
58 'src/Settings/SqpSettingsGeneralWidget.cpp',
57 'src/SidePane/SqpSidePane.cpp',
59 'src/SidePane/SqpSidePane.cpp',
58 'src/TimeWidget/TimeWidget.cpp',
60 'src/TimeWidget/TimeWidget.cpp',
59 'src/Variable/VariableInspectorWidget.cpp',
61 'src/Variable/VariableInspectorWidget.cpp',
60 'src/Variable/VariableInspectorTableView.cpp',
62 'src/Variable/VariableInspectorTableView.cpp',
61 'src/Variable/VariableMenuHeaderWidget.cpp',
63 'src/Variable/VariableMenuHeaderWidget.cpp',
62 'src/Variable/RenameVariableDialog.cpp',
64 'src/Variable/RenameVariableDialog.cpp',
63 'src/Visualization/VisualizationGraphHelper.cpp',
65 'src/Visualization/VisualizationGraphHelper.cpp',
64 'src/Visualization/VisualizationGraphRenderingDelegate.cpp',
66 'src/Visualization/VisualizationGraphRenderingDelegate.cpp',
65 'src/Visualization/VisualizationGraphWidget.cpp',
67 'src/Visualization/VisualizationGraphWidget.cpp',
66 'src/Visualization/VisualizationTabWidget.cpp',
68 'src/Visualization/VisualizationTabWidget.cpp',
67 'src/Visualization/VisualizationWidget.cpp',
69 'src/Visualization/VisualizationWidget.cpp',
68 'src/Visualization/VisualizationZoneWidget.cpp',
70 'src/Visualization/VisualizationZoneWidget.cpp',
69 'src/Visualization/qcustomplot.cpp',
71 'src/Visualization/qcustomplot.cpp',
70 'src/Visualization/QCustomPlotSynchronizer.cpp',
72 'src/Visualization/QCustomPlotSynchronizer.cpp',
71 'src/Visualization/operations/FindVariableOperation.cpp',
73 'src/Visualization/operations/FindVariableOperation.cpp',
72 'src/Visualization/operations/GenerateVariableMenuOperation.cpp',
74 'src/Visualization/operations/GenerateVariableMenuOperation.cpp',
73 'src/Visualization/operations/MenuBuilder.cpp',
75 'src/Visualization/operations/MenuBuilder.cpp',
74 'src/Visualization/operations/RemoveVariableOperation.cpp',
76 'src/Visualization/operations/RemoveVariableOperation.cpp',
75 'src/Visualization/operations/RescaleAxeOperation.cpp',
77 'src/Visualization/operations/RescaleAxeOperation.cpp',
76 'src/Visualization/VisualizationDragDropContainer.cpp',
78 'src/Visualization/VisualizationDragDropContainer.cpp',
77 'src/Visualization/VisualizationDragWidget.cpp'
79 'src/Visualization/VisualizationDragWidget.cpp'
78 ]
80 ]
79
81
80 gui_inc = include_directories(['include'])
82 gui_inc = include_directories(['include'])
81
83
82 sciqlop_gui_lib = library('sciqlopgui',
84 sciqlop_gui_lib = library('sciqlopgui',
83 gui_sources,
85 gui_sources,
84 gui_moc_files,
86 gui_moc_files,
85 include_directories : [gui_inc],
87 include_directories : [gui_inc],
86 dependencies : [ qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core],
88 dependencies : [ qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core],
87 install : true
89 install : true
88 )
90 )
89
91
90 sciqlop_gui = declare_dependency(link_with : sciqlop_gui_lib,
92 sciqlop_gui = declare_dependency(link_with : sciqlop_gui_lib,
91 include_directories : gui_inc,
93 include_directories : gui_inc,
92 dependencies : [qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core])
94 dependencies : [qt5printsupport, qt5gui, qt5widgets, qt5svg, sciqlop_core])
93
95
@@ -1,261 +1,275
1 #include "DragAndDrop/DragDropHelper.h"
1 #include "DragAndDrop/DragDropHelper.h"
2 #include "DragAndDrop/DragDropScroller.h"
2 #include "DragAndDrop/DragDropScroller.h"
3 #include "DragAndDrop/DragDropTabSwitcher.h"
3 #include "SqpApplication.h"
4 #include "SqpApplication.h"
4 #include "Visualization/VisualizationDragDropContainer.h"
5 #include "Visualization/VisualizationDragDropContainer.h"
5 #include "Visualization/VisualizationDragWidget.h"
6 #include "Visualization/VisualizationDragWidget.h"
6 #include "Visualization/VisualizationWidget.h"
7 #include "Visualization/VisualizationWidget.h"
7 #include "Visualization/operations/FindVariableOperation.h"
8 #include "Visualization/operations/FindVariableOperation.h"
8
9
9 #include "Variable/Variable.h"
10 #include "Variable/Variable.h"
10 #include "Variable/VariableController.h"
11 #include "Variable/VariableController.h"
11
12
12 #include "Common/MimeTypesDef.h"
13 #include "Common/MimeTypesDef.h"
13 #include "Common/VisualizationDef.h"
14 #include "Common/VisualizationDef.h"
14
15
15 #include <QDir>
16 #include <QDir>
16 #include <QLabel>
17 #include <QLabel>
17 #include <QUrl>
18 #include <QUrl>
18 #include <QVBoxLayout>
19 #include <QVBoxLayout>
19
20
20
21
21 Q_LOGGING_CATEGORY(LOG_DragDropHelper, "DragDrophelper")
22 Q_LOGGING_CATEGORY(LOG_DragDropHelper, "DragDropHelper")
22
23
23
24
24 struct DragDropHelper::DragDropHelperPrivate {
25 struct DragDropHelper::DragDropHelperPrivate {
25
26
26 VisualizationDragWidget *m_CurrentDragWidget = nullptr;
27 VisualizationDragWidget *m_CurrentDragWidget = nullptr;
27 std::unique_ptr<QWidget> m_PlaceHolder = nullptr;
28 std::unique_ptr<QWidget> m_PlaceHolder = nullptr;
28 QLabel *m_PlaceHolderLabel;
29 QLabel *m_PlaceHolderLabel;
29 QWidget *m_PlaceBackground;
30 QWidget *m_PlaceBackground;
30 std::unique_ptr<DragDropScroller> m_DragDropScroller = nullptr;
31 std::unique_ptr<DragDropScroller> m_DragDropScroller = nullptr;
32 std::unique_ptr<DragDropTabSwitcher> m_DragDropTabSwitcher = nullptr;
31 QString m_ImageTempUrl; // Temporary file for image url generated by the drag & drop. Not using
33 QString m_ImageTempUrl; // Temporary file for image url generated by the drag & drop. Not using
32 // QTemporaryFile to have a name which is not generated.
34 // QTemporaryFile to have a name which is not generated.
33
35
34 VisualizationDragWidget *m_HighlightedDragWidget = nullptr;
36 VisualizationDragWidget *m_HighlightedDragWidget = nullptr;
35
37
36 QMetaObject::Connection m_DragWidgetDestroyedConnection;
38 QMetaObject::Connection m_DragWidgetDestroyedConnection;
37 QMetaObject::Connection m_HighlightedWidgetDestroyedConnection;
39 QMetaObject::Connection m_HighlightedWidgetDestroyedConnection;
38
40
39 explicit DragDropHelperPrivate()
41 explicit DragDropHelperPrivate()
40 : m_PlaceHolder{std::make_unique<QWidget>()},
42 : m_PlaceHolder{std::make_unique<QWidget>()},
41 m_DragDropScroller{std::make_unique<DragDropScroller>()}
43 m_DragDropScroller{std::make_unique<DragDropScroller>()},
44 m_DragDropTabSwitcher{std::make_unique<DragDropTabSwitcher>()}
42 {
45 {
43
46
44 auto layout = new QVBoxLayout{m_PlaceHolder.get()};
47 auto layout = new QVBoxLayout{m_PlaceHolder.get()};
45 layout->setSpacing(0);
48 layout->setSpacing(0);
46 layout->setContentsMargins(0, 0, 0, 0);
49 layout->setContentsMargins(0, 0, 0, 0);
47
50
48 m_PlaceHolderLabel = new QLabel{"", m_PlaceHolder.get()};
51 m_PlaceHolderLabel = new QLabel{"", m_PlaceHolder.get()};
49 m_PlaceHolderLabel->setMinimumHeight(25);
52 m_PlaceHolderLabel->setMinimumHeight(25);
50 layout->addWidget(m_PlaceHolderLabel);
53 layout->addWidget(m_PlaceHolderLabel);
51
54
52 m_PlaceBackground = new QWidget{m_PlaceHolder.get()};
55 m_PlaceBackground = new QWidget{m_PlaceHolder.get()};
53 m_PlaceBackground->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
56 m_PlaceBackground->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
54 layout->addWidget(m_PlaceBackground);
57 layout->addWidget(m_PlaceBackground);
55
58
56 sqpApp->installEventFilter(m_DragDropScroller.get());
59 sqpApp->installEventFilter(m_DragDropScroller.get());
60 sqpApp->installEventFilter(m_DragDropTabSwitcher.get());
57
61
58 m_ImageTempUrl = QDir::temp().absoluteFilePath("Sciqlop_graph.png");
62 m_ImageTempUrl = QDir::temp().absoluteFilePath("Sciqlop_graph.png");
59 }
63 }
60
64
61 void preparePlaceHolder(DragDropHelper::PlaceHolderType type, const QString &topLabelText) const
65 void preparePlaceHolder(DragDropHelper::PlaceHolderType type, const QString &topLabelText) const
62 {
66 {
63 if (m_CurrentDragWidget) {
67 if (m_CurrentDragWidget) {
64 m_PlaceHolder->setMinimumSize(m_CurrentDragWidget->size());
68 m_PlaceHolder->setMinimumSize(m_CurrentDragWidget->size());
65 m_PlaceHolder->setSizePolicy(m_CurrentDragWidget->sizePolicy());
69 m_PlaceHolder->setSizePolicy(m_CurrentDragWidget->sizePolicy());
66 }
70 }
67 else {
71 else {
68 // Configuration of the placeHolder when there is no dragWidget
72 // Configuration of the placeHolder when there is no dragWidget
69 // (for instance with a drag from a variable)
73 // (for instance with a drag from a variable)
70
74
71 m_PlaceHolder->setMinimumSize(0, GRAPH_MINIMUM_HEIGHT);
75 m_PlaceHolder->setMinimumSize(0, GRAPH_MINIMUM_HEIGHT);
72 m_PlaceHolder->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
76 m_PlaceHolder->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
73 }
77 }
74
78
75 switch (type) {
79 switch (type) {
76 case DragDropHelper::PlaceHolderType::Graph:
80 case DragDropHelper::PlaceHolderType::Graph:
77 m_PlaceBackground->setStyleSheet(
81 m_PlaceBackground->setStyleSheet(
78 "background-color: #BBD5EE; border: 1px solid #2A7FD4");
82 "background-color: #BBD5EE; border: 1px solid #2A7FD4");
79 break;
83 break;
80 case DragDropHelper::PlaceHolderType::Zone:
84 case DragDropHelper::PlaceHolderType::Zone:
81 case DragDropHelper::PlaceHolderType::Default:
85 case DragDropHelper::PlaceHolderType::Default:
82 m_PlaceBackground->setStyleSheet(
86 m_PlaceBackground->setStyleSheet(
83 "background-color: #BBD5EE; border: 2px solid #2A7FD4");
87 "background-color: #BBD5EE; border: 2px solid #2A7FD4");
84 m_PlaceHolderLabel->setStyleSheet("color: #2A7FD4");
88 m_PlaceHolderLabel->setStyleSheet("color: #2A7FD4");
85 break;
89 break;
86 }
90 }
87
91
88 m_PlaceHolderLabel->setText(topLabelText);
92 m_PlaceHolderLabel->setText(topLabelText);
89 m_PlaceHolderLabel->setVisible(!topLabelText.isEmpty());
93 m_PlaceHolderLabel->setVisible(!topLabelText.isEmpty());
90 }
94 }
91 };
95 };
92
96
93
97
94 DragDropHelper::DragDropHelper() : impl{spimpl::make_unique_impl<DragDropHelperPrivate>()} {}
98 DragDropHelper::DragDropHelper() : impl{spimpl::make_unique_impl<DragDropHelperPrivate>()} {}
95
99
96 DragDropHelper::~DragDropHelper()
100 DragDropHelper::~DragDropHelper()
97 {
101 {
98 QFile::remove(impl->m_ImageTempUrl);
102 QFile::remove(impl->m_ImageTempUrl);
99 }
103 }
100
104
101 void DragDropHelper::resetDragAndDrop()
105 void DragDropHelper::resetDragAndDrop()
102 {
106 {
103 setCurrentDragWidget(nullptr);
107 setCurrentDragWidget(nullptr);
104 impl->m_HighlightedDragWidget = nullptr;
108 impl->m_HighlightedDragWidget = nullptr;
105 }
109 }
106
110
107 void DragDropHelper::setCurrentDragWidget(VisualizationDragWidget *dragWidget)
111 void DragDropHelper::setCurrentDragWidget(VisualizationDragWidget *dragWidget)
108 {
112 {
109 if (impl->m_CurrentDragWidget) {
113 if (impl->m_CurrentDragWidget) {
110
114
111 QObject::disconnect(impl->m_DragWidgetDestroyedConnection);
115 QObject::disconnect(impl->m_DragWidgetDestroyedConnection);
112 }
116 }
113
117
114 if (dragWidget) {
118 if (dragWidget) {
115 // ensures the impl->m_CurrentDragWidget is reset when the widget is destroyed
119 // ensures the impl->m_CurrentDragWidget is reset when the widget is destroyed
116 impl->m_DragWidgetDestroyedConnection
120 impl->m_DragWidgetDestroyedConnection
117 = QObject::connect(dragWidget, &VisualizationDragWidget::destroyed,
121 = QObject::connect(dragWidget, &VisualizationDragWidget::destroyed,
118 [this]() { impl->m_CurrentDragWidget = nullptr; });
122 [this]() { impl->m_CurrentDragWidget = nullptr; });
119 }
123 }
120
124
121 impl->m_CurrentDragWidget = dragWidget;
125 impl->m_CurrentDragWidget = dragWidget;
122 }
126 }
123
127
124 VisualizationDragWidget *DragDropHelper::getCurrentDragWidget() const
128 VisualizationDragWidget *DragDropHelper::getCurrentDragWidget() const
125 {
129 {
126 return impl->m_CurrentDragWidget;
130 return impl->m_CurrentDragWidget;
127 }
131 }
128
132
129 QWidget &DragDropHelper::placeHolder() const
133 QWidget &DragDropHelper::placeHolder() const
130 {
134 {
131 return *impl->m_PlaceHolder;
135 return *impl->m_PlaceHolder;
132 }
136 }
133
137
134 void DragDropHelper::insertPlaceHolder(QVBoxLayout *layout, int index, PlaceHolderType type,
138 void DragDropHelper::insertPlaceHolder(QVBoxLayout *layout, int index, PlaceHolderType type,
135 const QString &topLabelText)
139 const QString &topLabelText)
136 {
140 {
137 removePlaceHolder();
141 removePlaceHolder();
138 impl->preparePlaceHolder(type, topLabelText);
142 impl->preparePlaceHolder(type, topLabelText);
139 layout->insertWidget(index, impl->m_PlaceHolder.get());
143 layout->insertWidget(index, impl->m_PlaceHolder.get());
140 impl->m_PlaceHolder->show();
144 impl->m_PlaceHolder->show();
141 }
145 }
142
146
143 void DragDropHelper::removePlaceHolder()
147 void DragDropHelper::removePlaceHolder()
144 {
148 {
145 auto parentWidget = impl->m_PlaceHolder->parentWidget();
149 auto parentWidget = impl->m_PlaceHolder->parentWidget();
146 if (parentWidget) {
150 if (parentWidget) {
147 parentWidget->layout()->removeWidget(impl->m_PlaceHolder.get());
151 parentWidget->layout()->removeWidget(impl->m_PlaceHolder.get());
148 impl->m_PlaceHolder->setParent(nullptr);
152 impl->m_PlaceHolder->setParent(nullptr);
149 impl->m_PlaceHolder->hide();
153 impl->m_PlaceHolder->hide();
150 }
154 }
151 }
155 }
152
156
153 bool DragDropHelper::isPlaceHolderSet() const
157 bool DragDropHelper::isPlaceHolderSet() const
154 {
158 {
155 return impl->m_PlaceHolder->parentWidget();
159 return impl->m_PlaceHolder->parentWidget();
156 }
160 }
157
161
158 void DragDropHelper::addDragDropScrollArea(QScrollArea *scrollArea)
162 void DragDropHelper::addDragDropScrollArea(QScrollArea *scrollArea)
159 {
163 {
160 impl->m_DragDropScroller->addScrollArea(scrollArea);
164 impl->m_DragDropScroller->addScrollArea(scrollArea);
161 }
165 }
162
166
163 void DragDropHelper::removeDragDropScrollArea(QScrollArea *scrollArea)
167 void DragDropHelper::removeDragDropScrollArea(QScrollArea *scrollArea)
164 {
168 {
165 impl->m_DragDropScroller->removeScrollArea(scrollArea);
169 impl->m_DragDropScroller->removeScrollArea(scrollArea);
166 }
170 }
167
171
172 void DragDropHelper::addDragDropTabBar(QTabBar *tabBar)
173 {
174 impl->m_DragDropTabSwitcher->addTabBar(tabBar);
175 }
176
177 void DragDropHelper::removeDragDropTabBar(QTabBar *tabBar)
178 {
179 impl->m_DragDropTabSwitcher->removeTabBar(tabBar);
180 }
181
168 QUrl DragDropHelper::imageTemporaryUrl(const QImage &image) const
182 QUrl DragDropHelper::imageTemporaryUrl(const QImage &image) const
169 {
183 {
170 image.save(impl->m_ImageTempUrl);
184 image.save(impl->m_ImageTempUrl);
171 return QUrl::fromLocalFile(impl->m_ImageTempUrl);
185 return QUrl::fromLocalFile(impl->m_ImageTempUrl);
172 }
186 }
173
187
174 void DragDropHelper::setHightlightedDragWidget(VisualizationDragWidget *dragWidget)
188 void DragDropHelper::setHightlightedDragWidget(VisualizationDragWidget *dragWidget)
175 {
189 {
176 if (impl->m_HighlightedDragWidget) {
190 if (impl->m_HighlightedDragWidget) {
177 impl->m_HighlightedDragWidget->highlightForMerge(false);
191 impl->m_HighlightedDragWidget->highlightForMerge(false);
178 QObject::disconnect(impl->m_HighlightedWidgetDestroyedConnection);
192 QObject::disconnect(impl->m_HighlightedWidgetDestroyedConnection);
179 }
193 }
180
194
181 if (dragWidget) {
195 if (dragWidget) {
182 dragWidget->highlightForMerge(true);
196 dragWidget->highlightForMerge(true);
183
197
184 // ensures the impl->m_HighlightedDragWidget is reset when the widget is destroyed
198 // ensures the impl->m_HighlightedDragWidget is reset when the widget is destroyed
185 impl->m_DragWidgetDestroyedConnection
199 impl->m_DragWidgetDestroyedConnection
186 = QObject::connect(dragWidget, &VisualizationDragWidget::destroyed,
200 = QObject::connect(dragWidget, &VisualizationDragWidget::destroyed,
187 [this]() { impl->m_HighlightedDragWidget = nullptr; });
201 [this]() { impl->m_HighlightedDragWidget = nullptr; });
188 }
202 }
189
203
190 impl->m_HighlightedDragWidget = dragWidget;
204 impl->m_HighlightedDragWidget = dragWidget;
191 }
205 }
192
206
193 VisualizationDragWidget *DragDropHelper::getHightlightedDragWidget() const
207 VisualizationDragWidget *DragDropHelper::getHightlightedDragWidget() const
194 {
208 {
195 return impl->m_HighlightedDragWidget;
209 return impl->m_HighlightedDragWidget;
196 }
210 }
197
211
198 bool DragDropHelper::checkMimeDataForVisualization(const QMimeData *mimeData,
212 bool DragDropHelper::checkMimeDataForVisualization(const QMimeData *mimeData,
199 VisualizationDragDropContainer *dropContainer)
213 VisualizationDragDropContainer *dropContainer)
200 {
214 {
201 if (!mimeData || !dropContainer) {
215 if (!mimeData || !dropContainer) {
202 qCWarning(LOG_DragDropHelper()) << QObject::tr(
216 qCWarning(LOG_DragDropHelper()) << QObject::tr(
203 "DragDropHelper::checkMimeDataForVisualization, invalid input parameters.");
217 "DragDropHelper::checkMimeDataForVisualization, invalid input parameters.");
204 Q_ASSERT(false);
218 Q_ASSERT(false);
205 return false;
219 return false;
206 }
220 }
207
221
208 auto result = false;
222 auto result = false;
209
223
210 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
224 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
211 auto variables = sqpApp->variableController().variablesForMimeData(
225 auto variables = sqpApp->variableController().variablesForMimeData(
212 mimeData->data(MIME_TYPE_VARIABLE_LIST));
226 mimeData->data(MIME_TYPE_VARIABLE_LIST));
213
227
214 if (variables.count() == 1) {
228 if (variables.count() == 1) {
215
229
216 auto variable = variables.first();
230 auto variable = variables.first();
217 if (variable->dataSeries() != nullptr) {
231 if (variable->dataSeries() != nullptr) {
218
232
219 // Check that the variable is not already in a graph
233 // Check that the variable is not already in a graph
220
234
221 auto parent = dropContainer->parentWidget();
235 auto parent = dropContainer->parentWidget();
222 while (parent && qobject_cast<VisualizationWidget *>(parent) == nullptr) {
236 while (parent && qobject_cast<VisualizationWidget *>(parent) == nullptr) {
223 parent = parent->parentWidget(); // Search for the top level VisualizationWidget
237 parent = parent->parentWidget(); // Search for the top level VisualizationWidget
224 }
238 }
225
239
226 if (parent) {
240 if (parent) {
227 auto visualizationWidget = static_cast<VisualizationWidget *>(parent);
241 auto visualizationWidget = static_cast<VisualizationWidget *>(parent);
228
242
229 FindVariableOperation findVariableOperation{variable};
243 FindVariableOperation findVariableOperation{variable};
230 visualizationWidget->accept(&findVariableOperation);
244 visualizationWidget->accept(&findVariableOperation);
231 auto variableContainers = findVariableOperation.result();
245 auto variableContainers = findVariableOperation.result();
232 if (variableContainers.empty()) {
246 if (variableContainers.empty()) {
233 result = true;
247 result = true;
234 }
248 }
235 else {
249 else {
236 // result = false: the variable already exist in the visualisation
250 // result = false: the variable already exist in the visualisation
237 }
251 }
238 }
252 }
239 else {
253 else {
240 qCWarning(LOG_DragDropHelper()) << QObject::tr(
254 qCWarning(LOG_DragDropHelper()) << QObject::tr(
241 "DragDropHelper::checkMimeDataForVisualization, the parent "
255 "DragDropHelper::checkMimeDataForVisualization, the parent "
242 "VisualizationWidget cannot be found. Cannot check if the variable is "
256 "VisualizationWidget cannot be found. Cannot check if the variable is "
243 "already used or not.");
257 "already used or not.");
244 }
258 }
245 }
259 }
246 else {
260 else {
247 // result = false: the variable is not fully loaded
261 // result = false: the variable is not fully loaded
248 }
262 }
249 }
263 }
250 else {
264 else {
251 // result = false: cannot drop multiple variables in the visualisation
265 // result = false: cannot drop multiple variables in the visualisation
252 }
266 }
253 }
267 }
254 else {
268 else {
255 // Other MIME data
269 // Other MIME data
256 // no special rules, accepted by default
270 // no special rules, accepted by default
257 result = true;
271 result = true;
258 }
272 }
259
273
260 return result;
274 return result;
261 }
275 }
@@ -1,172 +1,178
1 #include "Visualization/VisualizationWidget.h"
1 #include "Visualization/VisualizationWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/VisualizationGraphWidget.h"
3 #include "Visualization/VisualizationGraphWidget.h"
4 #include "Visualization/VisualizationTabWidget.h"
4 #include "Visualization/VisualizationTabWidget.h"
5 #include "Visualization/VisualizationZoneWidget.h"
5 #include "Visualization/VisualizationZoneWidget.h"
6 #include "Visualization/operations/FindVariableOperation.h"
6 #include "Visualization/operations/FindVariableOperation.h"
7 #include "Visualization/operations/GenerateVariableMenuOperation.h"
7 #include "Visualization/operations/GenerateVariableMenuOperation.h"
8 #include "Visualization/operations/RemoveVariableOperation.h"
8 #include "Visualization/operations/RemoveVariableOperation.h"
9 #include "Visualization/operations/RescaleAxeOperation.h"
9 #include "Visualization/operations/RescaleAxeOperation.h"
10 #include "Visualization/qcustomplot.h"
10 #include "Visualization/qcustomplot.h"
11
11
12 #include "ui_VisualizationWidget.h"
12 #include "ui_VisualizationWidget.h"
13
13
14 #include "DragAndDrop/DragDropHelper.h"
15 #include "SqpApplication.h"
16
14 #include <QToolButton>
17 #include <QToolButton>
15
18
16 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
19 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
17
20
18 VisualizationWidget::VisualizationWidget(QWidget *parent)
21 VisualizationWidget::VisualizationWidget(QWidget *parent)
19 : QWidget{parent}, ui{new Ui::VisualizationWidget}
22 : QWidget{parent}, ui{new Ui::VisualizationWidget}
20 {
23 {
21 ui->setupUi(this);
24 ui->setupUi(this);
22
25
23 auto addTabViewButton = new QToolButton{ui->tabWidget};
26 auto addTabViewButton = new QToolButton{ui->tabWidget};
24 addTabViewButton->setText(tr("Add View"));
27 addTabViewButton->setText(tr("Add View"));
25 addTabViewButton->setCursor(Qt::ArrowCursor);
28 addTabViewButton->setCursor(Qt::ArrowCursor);
26 ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner);
29 ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner);
27
30
28 auto enableMinimumCornerWidgetSize = [this](bool enable) {
31 auto enableMinimumCornerWidgetSize = [this](bool enable) {
29
32
30 auto tabViewCornerWidget = ui->tabWidget->cornerWidget();
33 auto tabViewCornerWidget = ui->tabWidget->cornerWidget();
31 auto width = enable ? tabViewCornerWidget->width() : 0;
34 auto width = enable ? tabViewCornerWidget->width() : 0;
32 auto height = enable ? tabViewCornerWidget->height() : 0;
35 auto height = enable ? tabViewCornerWidget->height() : 0;
33 tabViewCornerWidget->setMinimumHeight(height);
36 tabViewCornerWidget->setMinimumHeight(height);
34 tabViewCornerWidget->setMinimumWidth(width);
37 tabViewCornerWidget->setMinimumWidth(width);
35 ui->tabWidget->setMinimumHeight(height);
38 ui->tabWidget->setMinimumHeight(height);
36 ui->tabWidget->setMinimumWidth(width);
39 ui->tabWidget->setMinimumWidth(width);
37 };
40 };
38
41
39 auto addTabView = [this, enableMinimumCornerWidgetSize]() {
42 auto addTabView = [this, enableMinimumCornerWidgetSize]() {
40 auto widget = new VisualizationTabWidget{QString{"View %1"}.arg(ui->tabWidget->count() + 1),
43 auto widget = new VisualizationTabWidget{QString{"View %1"}.arg(ui->tabWidget->count() + 1),
41 ui->tabWidget};
44 ui->tabWidget};
42 auto index = ui->tabWidget->addTab(widget, widget->name());
45 auto index = ui->tabWidget->addTab(widget, widget->name());
43 if (ui->tabWidget->count() > 0) {
46 if (ui->tabWidget->count() > 0) {
44 enableMinimumCornerWidgetSize(false);
47 enableMinimumCornerWidgetSize(false);
45 }
48 }
46 qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index);
49 qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index);
47 };
50 };
48
51
49 auto removeTabView = [this, enableMinimumCornerWidgetSize](int index) {
52 auto removeTabView = [this, enableMinimumCornerWidgetSize](int index) {
50 if (ui->tabWidget->count() == 1) {
53 if (ui->tabWidget->count() == 1) {
51 enableMinimumCornerWidgetSize(true);
54 enableMinimumCornerWidgetSize(true);
52 }
55 }
53
56
54 // Removes widget from tab and closes it
57 // Removes widget from tab and closes it
55 auto widget = ui->tabWidget->widget(index);
58 auto widget = ui->tabWidget->widget(index);
56 ui->tabWidget->removeTab(index);
59 ui->tabWidget->removeTab(index);
57 if (widget) {
60 if (widget) {
58 widget->close();
61 widget->close();
59 }
62 }
60
63
61 qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index);
64 qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index);
62
65
63 };
66 };
64
67
65 ui->tabWidget->setTabsClosable(true);
68 ui->tabWidget->setTabsClosable(true);
66
69
67 connect(addTabViewButton, &QToolButton::clicked, addTabView);
70 connect(addTabViewButton, &QToolButton::clicked, addTabView);
68 connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView);
71 connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView);
69
72
73 sqpApp->dragDropHelper().addDragDropTabBar(ui->tabWidget->tabBar());
74
70 // Adds default tab
75 // Adds default tab
71 addTabView();
76 addTabView();
72 }
77 }
73
78
74 VisualizationWidget::~VisualizationWidget()
79 VisualizationWidget::~VisualizationWidget()
75 {
80 {
81 sqpApp->dragDropHelper().removeDragDropTabBar(ui->tabWidget->tabBar());
76 delete ui;
82 delete ui;
77 }
83 }
78
84
79 void VisualizationWidget::accept(IVisualizationWidgetVisitor *visitor)
85 void VisualizationWidget::accept(IVisualizationWidgetVisitor *visitor)
80 {
86 {
81 if (visitor) {
87 if (visitor) {
82 visitor->visitEnter(this);
88 visitor->visitEnter(this);
83
89
84 // Apply visitor for tab children
90 // Apply visitor for tab children
85 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
91 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
86 // Widgets different from tabs are not visited (no action)
92 // Widgets different from tabs are not visited (no action)
87 if (auto visualizationTabWidget
93 if (auto visualizationTabWidget
88 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
94 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
89 visualizationTabWidget->accept(visitor);
95 visualizationTabWidget->accept(visitor);
90 }
96 }
91 }
97 }
92
98
93 visitor->visitLeave(this);
99 visitor->visitLeave(this);
94 }
100 }
95 else {
101 else {
96 qCCritical(LOG_VisualizationWidget()) << tr("Can't visit widget : the visitor is null");
102 qCCritical(LOG_VisualizationWidget()) << tr("Can't visit widget : the visitor is null");
97 }
103 }
98 }
104 }
99
105
100 bool VisualizationWidget::canDrop(const Variable &variable) const
106 bool VisualizationWidget::canDrop(const Variable &variable) const
101 {
107 {
102 // The main widget can never accomodate a variable
108 // The main widget can never accomodate a variable
103 Q_UNUSED(variable);
109 Q_UNUSED(variable);
104 return false;
110 return false;
105 }
111 }
106
112
107 bool VisualizationWidget::contains(const Variable &variable) const
113 bool VisualizationWidget::contains(const Variable &variable) const
108 {
114 {
109 Q_UNUSED(variable);
115 Q_UNUSED(variable);
110 return false;
116 return false;
111 }
117 }
112
118
113 QString VisualizationWidget::name() const
119 QString VisualizationWidget::name() const
114 {
120 {
115 return QStringLiteral("MainView");
121 return QStringLiteral("MainView");
116 }
122 }
117
123
118 void VisualizationWidget::attachVariableMenu(
124 void VisualizationWidget::attachVariableMenu(
119 QMenu *menu, const QVector<std::shared_ptr<Variable> > &variables) noexcept
125 QMenu *menu, const QVector<std::shared_ptr<Variable> > &variables) noexcept
120 {
126 {
121 // Menu is generated only if there is a single variable
127 // Menu is generated only if there is a single variable
122 if (variables.size() == 1) {
128 if (variables.size() == 1) {
123 if (auto variable = variables.first()) {
129 if (auto variable = variables.first()) {
124 // Gets the containers of the variable
130 // Gets the containers of the variable
125 FindVariableOperation findVariableOperation{variable};
131 FindVariableOperation findVariableOperation{variable};
126 accept(&findVariableOperation);
132 accept(&findVariableOperation);
127 auto variableContainers = findVariableOperation.result();
133 auto variableContainers = findVariableOperation.result();
128
134
129 // Generates the actions that make it possible to visualize the variable
135 // Generates the actions that make it possible to visualize the variable
130 GenerateVariableMenuOperation generateVariableMenuOperation{
136 GenerateVariableMenuOperation generateVariableMenuOperation{
131 menu, variable, std::move(variableContainers)};
137 menu, variable, std::move(variableContainers)};
132 accept(&generateVariableMenuOperation);
138 accept(&generateVariableMenuOperation);
133 }
139 }
134 else {
140 else {
135 qCCritical(LOG_VisualizationWidget()) << tr(
141 qCCritical(LOG_VisualizationWidget()) << tr(
136 "Can't generate the menu relative to the visualization: the variable is null");
142 "Can't generate the menu relative to the visualization: the variable is null");
137 }
143 }
138 }
144 }
139 else {
145 else {
140 qCDebug(LOG_VisualizationWidget())
146 qCDebug(LOG_VisualizationWidget())
141 << tr("No generation of the menu related to the visualization: several variables are "
147 << tr("No generation of the menu related to the visualization: several variables are "
142 "selected");
148 "selected");
143 }
149 }
144 }
150 }
145
151
146 void VisualizationWidget::onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept
152 void VisualizationWidget::onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept
147 {
153 {
148 // Calls the operation of removing all references to the variable in the visualization
154 // Calls the operation of removing all references to the variable in the visualization
149 auto removeVariableOperation = RemoveVariableOperation{variable};
155 auto removeVariableOperation = RemoveVariableOperation{variable};
150 accept(&removeVariableOperation);
156 accept(&removeVariableOperation);
151 }
157 }
152
158
153 void VisualizationWidget::onRangeChanged(std::shared_ptr<Variable> variable,
159 void VisualizationWidget::onRangeChanged(std::shared_ptr<Variable> variable,
154 const SqpRange &range) noexcept
160 const SqpRange &range) noexcept
155 {
161 {
156 // Calls the operation of rescaling all graph that contrains variable in the visualization
162 // Calls the operation of rescaling all graph that contrains variable in the visualization
157 auto rescaleVariableOperation = RescaleAxeOperation{variable, range};
163 auto rescaleVariableOperation = RescaleAxeOperation{variable, range};
158 accept(&rescaleVariableOperation);
164 accept(&rescaleVariableOperation);
159 }
165 }
160
166
161 void VisualizationWidget::closeEvent(QCloseEvent *event)
167 void VisualizationWidget::closeEvent(QCloseEvent *event)
162 {
168 {
163 // Closes tabs in the widget
169 // Closes tabs in the widget
164 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
170 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
165 if (auto visualizationTabWidget
171 if (auto visualizationTabWidget
166 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
172 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
167 visualizationTabWidget->close();
173 visualizationTabWidget->close();
168 }
174 }
169 }
175 }
170
176
171 QWidget::closeEvent(event);
177 QWidget::closeEvent(event);
172 }
178 }
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