##// END OF EJS Templates
Format changes
trabillard -
r844:90e991aec5fa
parent child
Show More
@@ -1,67 +1,65
1 #ifndef DRAGDROPHELPER_H
2 #define DRAGDROPHELPER_H
1 #ifndef SCIQLOP_DRAGDROPHELPER_H
2 #define SCIQLOP_DRAGDROPHELPER_H
3 3
4 4 #include <Common/spimpl.h>
5 5 #include <QWidget>
6 6
7 7 class QVBoxLayout;
8 8 class QScrollArea;
9 9 class VisualizationDragWidget;
10 10 class QMimeData;
11 11
12 12 /**
13 13 * @brief Event filter class which manage the scroll of QScrollArea during a drag&drop operation.
14 14 * @note A QScrollArea inside an other QScrollArea is not fully supported.
15 15 */
16 class DragDropScroller : public QObject
17 {
16 class DragDropScroller : public QObject {
18 17 Q_OBJECT
19 18
20 19 public:
21 DragDropScroller(QObject* parent = nullptr);
20 DragDropScroller(QObject *parent = nullptr);
22 21
23 void addScrollArea(QScrollArea* scrollArea);
24 void removeScrollArea(QScrollArea* scrollArea);
22 void addScrollArea(QScrollArea *scrollArea);
23 void removeScrollArea(QScrollArea *scrollArea);
25 24
26 25 protected:
27 26 bool eventFilter(QObject *obj, QEvent *event);
28 27
29 28 private:
30 29 class DragDropScrollerPrivate;
31 30 spimpl::unique_impl_ptr<DragDropScrollerPrivate> impl;
32 31
33 32 private slots:
34 33 void onTimer();
35 34 };
36 35
37 36 /**
38 37 * @brief Helper class for drag&drop operations.
39 38 */
40 class DragDropHelper
41 {
39 class DragDropHelper {
42 40 public:
43 DragDropHelper();
44 ~DragDropHelper();
45
46 41 static const QString MIME_TYPE_GRAPH;
47 42 static const QString MIME_TYPE_ZONE;
48 43
49 void setCurrentDragWidget(VisualizationDragWidget* dragWidget);
50 VisualizationDragWidget* getCurrentDragWidget() const;
44 DragDropHelper();
45 virtual ~DragDropHelper();
46
47 void setCurrentDragWidget(VisualizationDragWidget *dragWidget);
48 VisualizationDragWidget *getCurrentDragWidget() const;
51 49
52 50 QWidget &placeHolder() const;
53 void insertPlaceHolder(QVBoxLayout* layout, int index);
51 void insertPlaceHolder(QVBoxLayout *layout, int index);
54 52 void removePlaceHolder();
55 53 bool isPlaceHolderSet() const;
56 54
57 void addDragDropScrollArea(QScrollArea* scrollArea);
58 void removeDragDropScrollArea(QScrollArea* scrollArea);
55 void addDragDropScrollArea(QScrollArea *scrollArea);
56 void removeDragDropScrollArea(QScrollArea *scrollArea);
59 57
60 QUrl imageTemporaryUrl(const QImage& image) const;
58 QUrl imageTemporaryUrl(const QImage &image) const;
61 59
62 60 private:
63 61 class DragDropHelperPrivate;
64 62 spimpl::unique_impl_ptr<DragDropHelperPrivate> impl;
65 63 };
66 64
67 #endif // DRAGDROPHELPER_H
65 #endif // SCIQLOP_DRAGDROPHELPER_H
@@ -1,56 +1,56
1 1 #ifndef SCIQLOP_SQPAPPLICATION_H
2 2 #define SCIQLOP_SQPAPPLICATION_H
3 3
4 4 #include "SqpApplication.h"
5 5
6 6 #include <QApplication>
7 7 #include <QLoggingCategory>
8 8
9 9 #include <Common/spimpl.h>
10 10
11 11 Q_DECLARE_LOGGING_CATEGORY(LOG_SqpApplication)
12 12
13 13 #if defined(sqpApp)
14 14 #undef sqpApp
15 15 #endif
16 16 #define sqpApp (static_cast<SqpApplication *>(QCoreApplication::instance()))
17 17
18 18 class DataSourceController;
19 19 class NetworkController;
20 20 class TimeController;
21 21 class VariableController;
22 22 class VisualizationController;
23 23 class DragDropHelper;
24 24
25 25 /**
26 26 * @brief The SqpApplication class aims to make the link between SciQlop
27 27 * and its plugins. This is the intermediate class that SciQlop has to use
28 28 * in the way to connect a data source. Please first use load method to initialize
29 29 * a plugin specified by its metadata name (JSON plugin source) then others specifics
30 30 * method will be able to access it.
31 31 * You can load a data source driver plugin then create a data source.
32 32 */
33 33
34 34 class SqpApplication : public QApplication {
35 35 Q_OBJECT
36 36 public:
37 37 explicit SqpApplication(int &argc, char **argv);
38 38 virtual ~SqpApplication();
39 39 void initialize();
40 40
41 41 /// Accessors for the differents sciqlop controllers
42 42 DataSourceController &dataSourceController() noexcept;
43 43 NetworkController &networkController() noexcept;
44 44 TimeController &timeController() noexcept;
45 45 VariableController &variableController() noexcept;
46 46 VisualizationController &visualizationController() noexcept;
47 47
48 /// Accessors for the differents sciqlop helpers
48 /// Accessors for the differents sciqlop helpers
49 49 DragDropHelper &dragDropHelper() noexcept;
50 50
51 51 private:
52 52 class SqpApplicationPrivate;
53 53 spimpl::unique_impl_ptr<SqpApplicationPrivate> impl;
54 54 };
55 55
56 56 #endif // SCIQLOP_SQPAPPLICATION_H
@@ -1,45 +1,42
1 1 #ifndef VISUALIZATIONDRAGDROPCONTAINER_H
2 2 #define VISUALIZATIONDRAGDROPCONTAINER_H
3 3
4 #include <QWidget>
5 #include <QVBoxLayout>
6 #include <QMimeData>
7 4 #include <Common/spimpl.h>
5 #include <QMimeData>
6 #include <QVBoxLayout>
7 #include <QWidget>
8 8
9 9 class VisualizationDragWidget;
10 10
11 class VisualizationDragDropContainer : public QWidget
12 {
11 class VisualizationDragDropContainer : public QWidget {
13 12 Q_OBJECT
14 13
15 14 signals:
16 void dropOccured(int dropIndex, const QMimeData* mimeData);
15 void dropOccured(int dropIndex, const QMimeData *mimeData);
17 16
18 17 public:
19 VisualizationDragDropContainer(QWidget* parent = nullptr);
18 VisualizationDragDropContainer(QWidget *parent = nullptr);
20 19
21 void addDragWidget(VisualizationDragWidget* dragWidget);
22 void insertDragWidget(int index, VisualizationDragWidget* dragWidget);
20 void addDragWidget(VisualizationDragWidget *dragWidget);
21 void insertDragWidget(int index, VisualizationDragWidget *dragWidget);
23 22
24 void setAcceptedMimeTypes(const QStringList& mimeTypes);
25 void setMergeAllowedMimeTypes(const QStringList& mimeTypes);
23 void setAcceptedMimeTypes(const QStringList &mimeTypes);
24 void setMergeAllowedMimeTypes(const QStringList &mimeTypes);
26 25
27 26 int countDragWidget() const;
28 27
29 28 protected:
30 29 void dragEnterEvent(QDragEnterEvent *event);
31 30 void dragLeaveEvent(QDragLeaveEvent *event);
32 31 void dragMoveEvent(QDragMoveEvent *event);
33 32 void dropEvent(QDropEvent *event);
34 33
35 34 private:
36
37
38 35 class VisualizationDragDropContainerPrivate;
39 36 spimpl::unique_impl_ptr<VisualizationDragDropContainerPrivate> impl;
40 37
41 38 private slots:
42 void startDrag(VisualizationDragWidget* dragWidget, const QPoint& dragPosition);
39 void startDrag(VisualizationDragWidget *dragWidget, const QPoint &dragPosition);
43 40 };
44 41
45 42 #endif // VISUALIZATIONDRAGDROPCONTAINER_H
@@ -1,30 +1,29
1 1 #ifndef VISUALIZATIONDRAGWIDGET_H
2 2 #define VISUALIZATIONDRAGWIDGET_H
3 3
4 #include <QWidget>
5 #include <QMimeData>
6 4 #include <Common/spimpl.h>
5 #include <QMimeData>
6 #include <QWidget>
7 7
8 class VisualizationDragWidget : public QWidget
9 {
8 class VisualizationDragWidget : public QWidget {
10 9 Q_OBJECT
11 10
12 11 public:
13 VisualizationDragWidget(QWidget* parent = nullptr);
12 VisualizationDragWidget(QWidget *parent = nullptr);
14 13
15 virtual QMimeData* mimeData() const = 0;
14 virtual QMimeData *mimeData() const = 0;
16 15 virtual bool isDragAllowed() const = 0;
17 16
18 17 protected:
19 18 virtual void mousePressEvent(QMouseEvent *event) override;
20 19 virtual void mouseMoveEvent(QMouseEvent *event) override;
21 20
22 21 private:
23 22 class VisualizationDragWidgetPrivate;
24 23 spimpl::unique_impl_ptr<VisualizationDragWidgetPrivate> impl;
25 24
26 25 signals:
27 void dragDetected(VisualizationDragWidget* dragWidget, const QPoint& dragPosition);
26 void dragDetected(VisualizationDragWidget *dragWidget, const QPoint &dragPosition);
28 27 };
29 28
30 29 #endif // VISUALIZATIONDRAGWIDGET_H
@@ -1,107 +1,107
1 1 #ifndef SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
2 2 #define SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
3 3
4 4 #include "Visualization/IVisualizationWidget.h"
5 5 #include "Visualization/VisualizationDragWidget.h"
6 6
7 7 #include <QLoggingCategory>
8 8 #include <QWidget>
9 9
10 10 #include <memory>
11 11
12 12 #include <Common/spimpl.h>
13 13
14 14 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationGraphWidget)
15 15
16 16 class QCPRange;
17 17 class QCustomPlot;
18 18 class SqpRange;
19 19 class Variable;
20 20 class VisualizationZoneWidget;
21 21
22 22 namespace Ui {
23 23 class VisualizationGraphWidget;
24 24 } // namespace Ui
25 25
26 26 class VisualizationGraphWidget : public VisualizationDragWidget, public IVisualizationWidget {
27 27 Q_OBJECT
28 28
29 29 friend class QCustomPlotSynchronizer;
30 30 friend class VisualizationGraphRenderingDelegate;
31 31
32 32 public:
33 33 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
34 34 virtual ~VisualizationGraphWidget();
35 35
36 VisualizationZoneWidget* parentZoneWidget() const noexcept;
36 VisualizationZoneWidget *parentZoneWidget() const noexcept;
37 37
38 38 /// If acquisition isn't enable, requestDataLoading signal cannot be emit
39 39 void enableAcquisition(bool enable);
40 40
41 41 void addVariable(std::shared_ptr<Variable> variable, SqpRange range);
42 42
43 43 /// Removes a variable from the graph
44 44 void removeVariable(std::shared_ptr<Variable> variable) noexcept;
45 45
46 46 /// Returns the list of all variables used in the graph
47 QList<std::shared_ptr<Variable>> variables() const;
47 QList<std::shared_ptr<Variable> > variables() const;
48 48
49 49 void setYRange(const SqpRange &range);
50 50 SqpRange graphRange() const noexcept;
51 51 void setGraphRange(const SqpRange &range);
52 52
53 53 // IVisualizationWidget interface
54 54 void accept(IVisualizationWidgetVisitor *visitor) override;
55 55 bool canDrop(const Variable &variable) const override;
56 56 bool contains(const Variable &variable) const override;
57 57 QString name() const override;
58 58
59 59 // VisualisationDragWidget
60 QMimeData* mimeData() const override;
60 QMimeData *mimeData() const override;
61 61 bool isDragAllowed() const override;
62 62
63 63 signals:
64 64 void synchronize(const SqpRange &range, const SqpRange &oldRange);
65 65 void requestDataLoading(QVector<std::shared_ptr<Variable> > variable, const SqpRange &range,
66 66 bool synchronise);
67 67
68 68 /// Signal emitted when the variable is about to be removed from the graph
69 69 void variableAboutToBeRemoved(std::shared_ptr<Variable> var);
70 70 /// Signal emitted when the variable has been added to the graph
71 71 void variableAdded(std::shared_ptr<Variable> var);
72 72
73 73 protected:
74 74 void closeEvent(QCloseEvent *event) override;
75 75 void enterEvent(QEvent *event) override;
76 76 void leaveEvent(QEvent *event) override;
77 77
78 78 QCustomPlot &plot() noexcept;
79 79
80 80 private:
81 81 Ui::VisualizationGraphWidget *ui;
82 82
83 83 class VisualizationGraphWidgetPrivate;
84 84 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
85 85
86 86 private slots:
87 87 /// Slot called when right clicking on the graph (displays a menu)
88 88 void onGraphMenuRequested(const QPoint &pos) noexcept;
89 89
90 90 /// Rescale the X axe to range parameter
91 91 void onRangeChanged(const QCPRange &t1, const QCPRange &t2);
92 92
93 93 /// Slot called when a mouse move was made
94 94 void onMouseMove(QMouseEvent *event) noexcept;
95 95 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
96 96 void onMouseWheel(QWheelEvent *event) noexcept;
97 97 /// Slot called when a mouse press was made, to activate the calibration of a graph
98 98 void onMousePress(QMouseEvent *event) noexcept;
99 99 /// Slot called when a mouse release was made, to deactivate the calibration of a graph
100 100 void onMouseRelease(QMouseEvent *event) noexcept;
101 101
102 102 void onDataCacheVariableUpdated();
103 103
104 104 void onUpdateVarDisplaying(std::shared_ptr<Variable> variable, const SqpRange &range);
105 105 };
106 106
107 107 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
@@ -1,79 +1,80
1 1 #ifndef SCIQLOP_VISUALIZATIONTABWIDGET_H
2 2 #define SCIQLOP_VISUALIZATIONTABWIDGET_H
3 3
4 4 #include "Visualization/IVisualizationWidget.h"
5 5
6 6 #include <Common/spimpl.h>
7 7
8 8 #include <QLoggingCategory>
9 #include <QWidget>
10 9 #include <QMimeData>
10 #include <QWidget>
11 11
12 12 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationTabWidget)
13 13
14 14 class Variable;
15 15 class VisualizationZoneWidget;
16 16
17 17 namespace Ui {
18 18 class VisualizationTabWidget;
19 19 } // namespace Ui
20 20
21 21 class VisualizationTabWidget : public QWidget, public IVisualizationWidget {
22 22 Q_OBJECT
23 23
24 24 public:
25 25 explicit VisualizationTabWidget(const QString &name = {}, QWidget *parent = 0);
26 26 virtual ~VisualizationTabWidget();
27 27
28 28 /// Add a zone widget
29 29 void addZone(VisualizationZoneWidget *zoneWidget);
30 30
31 31 void insertZone(int index, VisualizationZoneWidget *zoneWidget);
32 32
33 33 /**
34 34 * Creates a zone using a variable. The variable will be displayed in a new graph of the new
35 35 * zone. The zone is added at the end.
36 36 * @param variable the variable for which to create the zone
37 37 * @return the pointer to the created zone
38 38 */
39 39 VisualizationZoneWidget *createZone(std::shared_ptr<Variable> variable);
40 40
41 41 /**
42 * Creates a zone using a list of variables. The variables will be displayed in a new graph of the new
43 * zone. The zone is inserted at the specified index.
42 * Creates a zone using a list of variables. The variables will be displayed in a new graph of
43 * the new zone. The zone is inserted at the specified index.
44 44 * @param variables the variables for which to create the zone
45 45 * @param index The index where the zone should be inserted in the layout
46 46 * @return the pointer to the created zone
47 47 */
48 VisualizationZoneWidget *createZone(const QList<std::shared_ptr<Variable>>& variables, int index);
48 VisualizationZoneWidget *createZone(const QList<std::shared_ptr<Variable> > &variables,
49 int index);
49 50
50 51 /**
51 52 * Creates a zone which is empty (no variables). The zone is inserted at the specified index.
52 53 * @param index The index where the zone should be inserted in the layout
53 54 * @return the pointer to the created zone
54 55 */
55 56 VisualizationZoneWidget *createEmptyZone(int index);
56 57
57 58 // IVisualizationWidget interface
58 59 void accept(IVisualizationWidgetVisitor *visitor) override;
59 60 bool canDrop(const Variable &variable) const override;
60 61 bool contains(const Variable &variable) const override;
61 62 QString name() const override;
62 63
63 64 protected:
64 65 void closeEvent(QCloseEvent *event) override;
65 66
66 67 private:
67 68 /// @return the layout of tab in which zones are added
68 69 QLayout &tabLayout() const noexcept;
69 70
70 71 Ui::VisualizationTabWidget *ui;
71 72
72 73 class VisualizationTabWidgetPrivate;
73 74 spimpl::unique_impl_ptr<VisualizationTabWidgetPrivate> impl;
74 75
75 76 private slots:
76 77 void dropMimeData(int index, const QMimeData *mimeData);
77 78 };
78 79
79 80 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
@@ -1,89 +1,90
1 1 #ifndef SCIQLOP_VISUALIZATIONZONEWIDGET_H
2 2 #define SCIQLOP_VISUALIZATIONZONEWIDGET_H
3 3
4 4 #include "Visualization/IVisualizationWidget.h"
5 5 #include "Visualization/VisualizationDragWidget.h"
6 6
7 7 #include <QLoggingCategory>
8 8 #include <QWidget>
9 9
10 10 #include <memory>
11 11
12 12 #include <Common/spimpl.h>
13 13
14 14 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationZoneWidget)
15 15
16 16 namespace Ui {
17 17 class VisualizationZoneWidget;
18 } // Ui
18 } // namespace Ui
19 19
20 20 class Variable;
21 21 class VisualizationGraphWidget;
22 22
23 23 class VisualizationZoneWidget : public VisualizationDragWidget, public IVisualizationWidget {
24 24 Q_OBJECT
25 25
26 26 public:
27 27 explicit VisualizationZoneWidget(const QString &name = {}, QWidget *parent = 0);
28 28 virtual ~VisualizationZoneWidget();
29 29
30 30 /// Adds a graph widget
31 31 void addGraph(VisualizationGraphWidget *graphWidget);
32 32
33 /// Inserts a graph widget
33 /// Inserts a graph widget
34 34 void insertGraph(int index, VisualizationGraphWidget *graphWidget);
35 35
36 36 /**
37 37 * Creates a graph using a variable. The variable will be displayed in the new graph.
38 38 * The graph is added at the end.
39 39 * @param variable the variable for which to create the graph
40 40 * @return the pointer to the created graph
41 41 */
42 42 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable);
43 43
44 44 /**
45 45 * Creates a graph using a variable. The variable will be displayed in the new graph.
46 46 * The graph is inserted at the specified index.
47 47 * @param variable the variable for which to create the graph
48 48 * @param index The index where the graph should be inserted in the layout
49 49 * @return the pointer to the created graph
50 50 */
51 51 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable, int index);
52 52
53 53 /**
54 54 * Creates a graph using a list of variables. The variables will be displayed in the new graph.
55 55 * The graph is inserted at the specified index.
56 56 * @param variables List of variables to be added to the graph
57 57 * @param index The index where the graph should be inserted in the layout
58 58 * @return the pointer to the created graph
59 59 */
60 VisualizationGraphWidget *createGraph(const QList<std::shared_ptr<Variable>> variables, int index);
60 VisualizationGraphWidget *createGraph(const QList<std::shared_ptr<Variable> > variables,
61 int index);
61 62
62 63 // IVisualizationWidget interface
63 64 void accept(IVisualizationWidgetVisitor *visitor) override;
64 65 bool canDrop(const Variable &variable) const override;
65 66 bool contains(const Variable &variable) const override;
66 67 QString name() const override;
67 68
68 69 // VisualisationDragWidget
69 QMimeData* mimeData() const override;
70 QMimeData *mimeData() const override;
70 71 bool isDragAllowed() const override;
71 72
72 73 protected:
73 74 void closeEvent(QCloseEvent *event) override;
74 75
75 76 private:
76 77 Ui::VisualizationZoneWidget *ui;
77 78
78 79 class VisualizationZoneWidgetPrivate;
79 80 spimpl::unique_impl_ptr<VisualizationZoneWidgetPrivate> impl;
80 81
81 82 private slots:
82 83 void onVariableAdded(std::shared_ptr<Variable> variable);
83 84 /// Slot called when a variable is about to be removed from a graph contained in the zone
84 85 void onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable);
85 86
86 void dropMimeData(int index, const QMimeData* mimeData);
87 void dropMimeData(int index, const QMimeData *mimeData);
87 88 };
88 89
89 90 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
@@ -1,248 +1,230
1 1 #include "DragDropHelper.h"
2 #include "Visualization/VisualizationDragWidget.h"
3 2 #include "SqpApplication.h"
3 #include "Visualization/VisualizationDragWidget.h"
4 4
5 #include <QDragMoveEvent>
5 #include <QDir>
6 6 #include <QDragEnterEvent>
7 #include <QScrollBar>
7 #include <QDragMoveEvent>
8 8 #include <QScrollArea>
9 #include <QVBoxLayout>
9 #include <QScrollBar>
10 10 #include <QTimer>
11 #include <QDir>
11 #include <QVBoxLayout>
12 12
13 13 const QString DragDropHelper::MIME_TYPE_GRAPH = "scqlop/graph";
14 14 const QString DragDropHelper::MIME_TYPE_ZONE = "scqlop/zone";
15 15
16 16 const int SCROLL_SPEED = 5;
17 17 const int SCROLL_ZONE_SIZE = 50;
18 18
19 19 struct DragDropScroller::DragDropScrollerPrivate {
20 20
21 QList<QScrollArea*> m_scrollAreas;
22 QScrollArea* m_currentScrollArea = nullptr;
23 std::unique_ptr<QTimer> m_timer = nullptr;
21 QList<QScrollArea *> m_ScrollAreas;
22 QScrollArea *m_CurrentScrollArea = nullptr;
23 std::unique_ptr<QTimer> m_Timer = nullptr;
24 24
25 25
26 enum class ScrollDirection {up, down, unknown};
27 ScrollDirection m_direction = ScrollDirection::unknown;
26 enum class ScrollDirection { up, down, unknown };
27 ScrollDirection m_Direction = ScrollDirection::unknown;
28 28
29 explicit DragDropScrollerPrivate()
30 : m_timer{std::make_unique<QTimer>()}
29 explicit DragDropScrollerPrivate() : m_Timer{std::make_unique<QTimer>()}
31 30 {
32 m_timer->setInterval(0);
31 m_Timer->setInterval(0);
33 32 }
34 33 };
35 34
36 DragDropScroller::DragDropScroller(QObject* parent)
37 : QObject{parent}, impl{spimpl::make_unique_impl<DragDropScrollerPrivate>()}
35 DragDropScroller::DragDropScroller(QObject *parent)
36 : QObject{parent}, impl{spimpl::make_unique_impl<DragDropScrollerPrivate>()}
38 37 {
39 connect(impl->m_timer.get(), &QTimer::timeout, this, &DragDropScroller::onTimer);
38 connect(impl->m_Timer.get(), &QTimer::timeout, this, &DragDropScroller::onTimer);
40 39 }
41 40
42 void DragDropScroller::addScrollArea(QScrollArea* scrollArea)
41 void DragDropScroller::addScrollArea(QScrollArea *scrollArea)
43 42 {
44 impl->m_scrollAreas << scrollArea;
43 impl->m_ScrollAreas << scrollArea;
45 44 scrollArea->viewport()->setAcceptDrops(true);
46 45 }
47 46
48 void DragDropScroller::removeScrollArea(QScrollArea* scrollArea)
47 void DragDropScroller::removeScrollArea(QScrollArea *scrollArea)
49 48 {
50 impl->m_scrollAreas.removeAll(scrollArea);
49 impl->m_ScrollAreas.removeAll(scrollArea);
51 50 scrollArea->viewport()->setAcceptDrops(false);
52 51 }
53 52
54 53 bool DragDropScroller::eventFilter(QObject *obj, QEvent *event)
55 54 {
56 if (event->type() == QEvent::DragMove)
57 {
58 auto w = static_cast<QWidget*>(obj);
55 if (event->type() == QEvent::DragMove) {
56 auto w = static_cast<QWidget *>(obj);
59 57
60 if (impl->m_currentScrollArea && impl->m_currentScrollArea->isAncestorOf(w))
61 {
62 auto moveEvent = static_cast<QDragMoveEvent*>(event);
58 if (impl->m_CurrentScrollArea && impl->m_CurrentScrollArea->isAncestorOf(w)) {
59 auto moveEvent = static_cast<QDragMoveEvent *>(event);
63 60
64 61 auto pos = moveEvent->pos();
65 if (impl->m_currentScrollArea->viewport() != w)
66 {
62 if (impl->m_CurrentScrollArea->viewport() != w) {
67 63 auto globalPos = w->mapToGlobal(moveEvent->pos());
68 pos = impl->m_currentScrollArea->viewport()->mapFromGlobal(globalPos);
64 pos = impl->m_CurrentScrollArea->viewport()->mapFromGlobal(globalPos);
69 65 }
70 66
71 auto isInTopZone = pos.y() > impl->m_currentScrollArea->viewport()->size().height() - SCROLL_ZONE_SIZE;
67 auto isInTopZone = pos.y() > impl->m_CurrentScrollArea->viewport()->size().height()
68 - SCROLL_ZONE_SIZE;
72 69 auto isInBottomZone = pos.y() < SCROLL_ZONE_SIZE;
73 70
74 if (!isInTopZone && !isInBottomZone)
75 {
76 impl->m_direction = DragDropScrollerPrivate::ScrollDirection::unknown;
77 impl->m_timer->stop();
71 if (!isInTopZone && !isInBottomZone) {
72 impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown;
73 impl->m_Timer->stop();
78 74 }
79 else if (!impl->m_timer->isActive())
80 {
81 impl->m_direction = isInTopZone ? DragDropScrollerPrivate::ScrollDirection::up : DragDropScrollerPrivate::ScrollDirection::down;
82 impl->m_timer->start();
75 else if (!impl->m_Timer->isActive()) {
76 impl->m_Direction = isInTopZone ? DragDropScrollerPrivate::ScrollDirection::up
77 : DragDropScrollerPrivate::ScrollDirection::down;
78 impl->m_Timer->start();
83 79 }
84 80 }
85 81 }
86 else if (event->type() == QEvent::DragEnter)
87 {
88 auto w = static_cast<QWidget*>(obj);
82 else if (event->type() == QEvent::DragEnter) {
83 auto w = static_cast<QWidget *>(obj);
89 84
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);
85 for (auto scrollArea : impl->m_ScrollAreas) {
86 if (impl->m_CurrentScrollArea != scrollArea && scrollArea->isAncestorOf(w)) {
87 auto enterEvent = static_cast<QDragEnterEvent *>(event);
95 88 enterEvent->acceptProposedAction();
96 89 enterEvent->setDropAction(Qt::IgnoreAction);
97 impl->m_currentScrollArea = scrollArea;
90 impl->m_CurrentScrollArea = scrollArea;
98 91 break;
99 92 }
100 93 }
101 94 }
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();
95 else if (event->type() == QEvent::DragLeave) {
96 auto w = static_cast<QWidget *>(obj);
97 if (impl->m_CurrentScrollArea) {
98 if (!QRect(QPoint(), impl->m_CurrentScrollArea->size())
99 .contains(impl->m_CurrentScrollArea->mapFromGlobal(QCursor::pos()))) {
100 impl->m_CurrentScrollArea = nullptr;
101 impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown;
102 impl->m_Timer->stop();
112 103 }
113 104 }
114 105 }
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();
106 else if (event->type() == QEvent::Drop) {
107 auto w = static_cast<QWidget *>(obj);
108 if (impl->m_CurrentScrollArea) {
109 impl->m_CurrentScrollArea = nullptr;
110 impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown;
111 impl->m_Timer->stop();
123 112 }
124 113 }
125 114
126 115 return false;
127 116 }
128 117
129 118 void DragDropScroller::onTimer()
130 119 {
131 if (impl->m_currentScrollArea)
132 {
120 if (impl->m_CurrentScrollArea) {
133 121 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;
122 switch (impl->m_Direction) {
123 case DragDropScrollerPrivate::ScrollDirection::up:
124 mvt = SCROLL_SPEED;
125 break;
126 case DragDropScrollerPrivate::ScrollDirection::down:
127 mvt = -SCROLL_SPEED;
128 break;
129 default:
130 break;
144 131 }
145 132
146 impl->m_currentScrollArea->verticalScrollBar()->setValue(impl->m_currentScrollArea->verticalScrollBar()->value() + mvt);
133 impl->m_CurrentScrollArea->verticalScrollBar()->setValue(
134 impl->m_CurrentScrollArea->verticalScrollBar()->value() + mvt);
147 135 }
148 136 }
149 137
150 138 struct DragDropHelper::DragDropHelperPrivate {
151 139
152 VisualizationDragWidget* m_currentDragWidget = nullptr;
153 std::unique_ptr<QWidget> m_placeHolder = nullptr;
154 std::unique_ptr<DragDropScroller> m_dragDropScroller = nullptr;
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.
140 VisualizationDragWidget *m_CurrentDragWidget = nullptr;
141 std::unique_ptr<QWidget> m_PlaceHolder = nullptr;
142 std::unique_ptr<DragDropScroller> m_DragDropScroller = nullptr;
143 QString m_ImageTempUrl; // Temporary file for image url generated by the drag & drop. Not using
144 // QTemporaryFile to have a name which is not generated.
156 145
157 146 explicit DragDropHelperPrivate()
158 : m_placeHolder{std::make_unique<QWidget>()},
159 m_dragDropScroller{std::make_unique<DragDropScroller>()}
147 : m_PlaceHolder{std::make_unique<QWidget>()},
148 m_DragDropScroller{std::make_unique<DragDropScroller>()}
160 149 {
161 m_placeHolder->setStyleSheet("background-color: #BBD5EE; border:2px solid #2A7FD4");
162 sqpApp->installEventFilter(m_dragDropScroller.get());
150 m_PlaceHolder->setStyleSheet("background-color: #BBD5EE; border:2px solid #2A7FD4");
151 sqpApp->installEventFilter(m_DragDropScroller.get());
163 152
164 153
165 m_imageTempUrl = QDir::temp().absoluteFilePath("Scqlop_graph.png");
154 m_ImageTempUrl = QDir::temp().absoluteFilePath("Scqlop_graph.png");
166 155 }
167 156
168 157 void preparePlaceHolder() const
169 158 {
170 if (m_currentDragWidget)
171 {
172 m_placeHolder->setMinimumSize(m_currentDragWidget->size());
173 m_placeHolder->setSizePolicy(m_currentDragWidget->sizePolicy());
159 if (m_CurrentDragWidget) {
160 m_PlaceHolder->setMinimumSize(m_CurrentDragWidget->size());
161 m_PlaceHolder->setSizePolicy(m_CurrentDragWidget->sizePolicy());
174 162 }
175 else
176 {
177 m_placeHolder->setMinimumSize(200, 200);
163 else {
164 m_PlaceHolder->setMinimumSize(200, 200);
178 165 }
179 166 }
180 167 };
181 168
182 169
183 DragDropHelper::DragDropHelper() :
184 impl{spimpl::make_unique_impl<DragDropHelperPrivate>()}
185 {
186 }
170 DragDropHelper::DragDropHelper() : impl{spimpl::make_unique_impl<DragDropHelperPrivate>()} {}
187 171
188 172 DragDropHelper::~DragDropHelper()
189 173 {
190 QFile::remove(impl->m_imageTempUrl);
174 QFile::remove(impl->m_ImageTempUrl);
191 175 }
192 176
193 177 void DragDropHelper::setCurrentDragWidget(VisualizationDragWidget *dragWidget)
194 178 {
195 impl->m_currentDragWidget = dragWidget;
179 impl->m_CurrentDragWidget = dragWidget;
196 180 }
197 181
198 182 VisualizationDragWidget *DragDropHelper::getCurrentDragWidget() const
199 183 {
200 return impl->m_currentDragWidget;
184 return impl->m_CurrentDragWidget;
201 185 }
202 186
203 187
204 QWidget& DragDropHelper::placeHolder() const
188 QWidget &DragDropHelper::placeHolder() const
205 189 {
206 return *impl->m_placeHolder;
190 return *impl->m_PlaceHolder;
207 191 }
208 192
209 193 void DragDropHelper::insertPlaceHolder(QVBoxLayout *layout, int index)
210 194 {
211 195 removePlaceHolder();
212 196 impl->preparePlaceHolder();
213 layout->insertWidget(index, impl->m_placeHolder.get());
214 impl->m_placeHolder->show();
197 layout->insertWidget(index, impl->m_PlaceHolder.get());
198 impl->m_PlaceHolder->show();
215 199 }
216 200
217 201 void DragDropHelper::removePlaceHolder()
218 202 {
219 auto parentWidget = impl->m_placeHolder->parentWidget();
220 if (parentWidget)
221 {
222 parentWidget->layout()->removeWidget(impl->m_placeHolder.get());
223 impl->m_placeHolder->setParent(nullptr);
224 impl->m_placeHolder->hide();
203 auto parentWidget = impl->m_PlaceHolder->parentWidget();
204 if (parentWidget) {
205 parentWidget->layout()->removeWidget(impl->m_PlaceHolder.get());
206 impl->m_PlaceHolder->setParent(nullptr);
207 impl->m_PlaceHolder->hide();
225 208 }
226 209 }
227 210
228 211 bool DragDropHelper::isPlaceHolderSet() const
229 212 {
230 return impl->m_placeHolder->parentWidget();
213 return impl->m_PlaceHolder->parentWidget();
231 214 }
232 215
233 216 void DragDropHelper::addDragDropScrollArea(QScrollArea *scrollArea)
234 217 {
235 impl->m_dragDropScroller->addScrollArea(scrollArea);
218 impl->m_DragDropScroller->addScrollArea(scrollArea);
236 219 }
237 220
238 221 void DragDropHelper::removeDragDropScrollArea(QScrollArea *scrollArea)
239 222 {
240 impl->m_dragDropScroller->removeScrollArea(scrollArea);
223 impl->m_DragDropScroller->removeScrollArea(scrollArea);
241 224 }
242 225
243 QUrl DragDropHelper::imageTemporaryUrl(const QImage& image) const
226 QUrl DragDropHelper::imageTemporaryUrl(const QImage &image) const
244 227 {
245 image.save(impl->m_imageTempUrl);
246 return QUrl::fromLocalFile(impl->m_imageTempUrl);
228 image.save(impl->m_ImageTempUrl);
229 return QUrl::fromLocalFile(impl->m_ImageTempUrl);
247 230 }
248
@@ -1,159 +1,155
1 1 #include "SqpApplication.h"
2 2
3 3 #include <Data/IDataProvider.h>
4 4 #include <DataSource/DataSourceController.h>
5 #include <DragDropHelper.h>
5 6 #include <Network/NetworkController.h>
6 7 #include <QThread>
7 8 #include <Time/TimeController.h>
8 9 #include <Variable/Variable.h>
9 10 #include <Variable/VariableController.h>
10 11 #include <Visualization/VisualizationController.h>
11 #include <DragDropHelper.h>
12 12
13 13 Q_LOGGING_CATEGORY(LOG_SqpApplication, "SqpApplication")
14 14
15 15 class SqpApplication::SqpApplicationPrivate {
16 16 public:
17 17 SqpApplicationPrivate()
18 18 : m_DataSourceController{std::make_unique<DataSourceController>()},
19 19 m_NetworkController{std::make_unique<NetworkController>()},
20 20 m_TimeController{std::make_unique<TimeController>()},
21 21 m_VariableController{std::make_unique<VariableController>()},
22 22 m_VisualizationController{std::make_unique<VisualizationController>()},
23 23 m_DragDropHelper{std::make_unique<DragDropHelper>()}
24 24 {
25 25 // /////////////////////////////// //
26 26 // Connections between controllers //
27 27 // /////////////////////////////// //
28 28
29 29 // VariableController <-> DataSourceController
30 30 connect(m_DataSourceController.get(),
31 31 SIGNAL(variableCreationRequested(const QString &, const QVariantHash &,
32 32 std::shared_ptr<IDataProvider>)),
33 33 m_VariableController.get(),
34 34 SLOT(createVariable(const QString &, const QVariantHash &,
35 35 std::shared_ptr<IDataProvider>)));
36 36
37 37 // VariableController <-> VisualizationController
38 38 connect(m_VariableController.get(),
39 39 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)),
40 40 m_VisualizationController.get(),
41 41 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), Qt::DirectConnection);
42 42
43 43 connect(m_VariableController.get(),
44 44 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpRange &)),
45 45 m_VisualizationController.get(),
46 46 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpRange &)));
47 47
48 48
49 49 m_DataSourceController->moveToThread(&m_DataSourceControllerThread);
50 50 m_DataSourceControllerThread.setObjectName("DataSourceControllerThread");
51 51 m_NetworkController->moveToThread(&m_NetworkControllerThread);
52 52 m_NetworkControllerThread.setObjectName("NetworkControllerThread");
53 53 m_VariableController->moveToThread(&m_VariableControllerThread);
54 54 m_VariableControllerThread.setObjectName("VariableControllerThread");
55 55 m_VisualizationController->moveToThread(&m_VisualizationControllerThread);
56 56 m_VisualizationControllerThread.setObjectName("VsualizationControllerThread");
57 57
58 58
59 59 // Additionnal init
60 60 m_VariableController->setTimeController(m_TimeController.get());
61 61 }
62 62
63 63 virtual ~SqpApplicationPrivate()
64 64 {
65 65 m_DataSourceControllerThread.quit();
66 66 m_DataSourceControllerThread.wait();
67 67
68 68 m_NetworkControllerThread.quit();
69 69 m_NetworkControllerThread.wait();
70 70
71 71 m_VariableControllerThread.quit();
72 72 m_VariableControllerThread.wait();
73 73
74 74 m_VisualizationControllerThread.quit();
75 75 m_VisualizationControllerThread.wait();
76 76 }
77 77
78 78 std::unique_ptr<DataSourceController> m_DataSourceController;
79 79 std::unique_ptr<VariableController> m_VariableController;
80 80 std::unique_ptr<TimeController> m_TimeController;
81 81 std::unique_ptr<NetworkController> m_NetworkController;
82 82 std::unique_ptr<VisualizationController> m_VisualizationController;
83 83 QThread m_DataSourceControllerThread;
84 84 QThread m_NetworkControllerThread;
85 85 QThread m_VariableControllerThread;
86 86 QThread m_VisualizationControllerThread;
87 87
88 88 std::unique_ptr<DragDropHelper> m_DragDropHelper;
89 89 };
90 90
91 91
92 92 SqpApplication::SqpApplication(int &argc, char **argv)
93 93 : QApplication{argc, argv}, impl{spimpl::make_unique_impl<SqpApplicationPrivate>()}
94 94 {
95 95 qCDebug(LOG_SqpApplication()) << tr("SqpApplication construction") << QThread::currentThread();
96 96
97 97 connect(&impl->m_DataSourceControllerThread, &QThread::started,
98 98 impl->m_DataSourceController.get(), &DataSourceController::initialize);
99 99 connect(&impl->m_DataSourceControllerThread, &QThread::finished,
100 100 impl->m_DataSourceController.get(), &DataSourceController::finalize);
101 101
102 102 connect(&impl->m_NetworkControllerThread, &QThread::started, impl->m_NetworkController.get(),
103 103 &NetworkController::initialize);
104 104 connect(&impl->m_NetworkControllerThread, &QThread::finished, impl->m_NetworkController.get(),
105 105 &NetworkController::finalize);
106 106
107 107 connect(&impl->m_VariableControllerThread, &QThread::started, impl->m_VariableController.get(),
108 108 &VariableController::initialize);
109 109 connect(&impl->m_VariableControllerThread, &QThread::finished, impl->m_VariableController.get(),
110 110 &VariableController::finalize);
111 111
112 112 connect(&impl->m_VisualizationControllerThread, &QThread::started,
113 113 impl->m_VisualizationController.get(), &VisualizationController::initialize);
114 114 connect(&impl->m_VisualizationControllerThread, &QThread::finished,
115 115 impl->m_VisualizationController.get(), &VisualizationController::finalize);
116 116
117 117 impl->m_DataSourceControllerThread.start();
118 118 impl->m_NetworkControllerThread.start();
119 119 impl->m_VariableControllerThread.start();
120 120 impl->m_VisualizationControllerThread.start();
121 121 }
122 122
123 SqpApplication::~SqpApplication()
124 {
125 }
123 SqpApplication::~SqpApplication() {}
126 124
127 void SqpApplication::initialize()
128 {
129 }
125 void SqpApplication::initialize() {}
130 126
131 127 DataSourceController &SqpApplication::dataSourceController() noexcept
132 128 {
133 129 return *impl->m_DataSourceController;
134 130 }
135 131
136 132 NetworkController &SqpApplication::networkController() noexcept
137 133 {
138 134 return *impl->m_NetworkController;
139 135 }
140 136
141 137 TimeController &SqpApplication::timeController() noexcept
142 138 {
143 139 return *impl->m_TimeController;
144 140 }
145 141
146 142 VariableController &SqpApplication::variableController() noexcept
147 143 {
148 144 return *impl->m_VariableController;
149 145 }
150 146
151 147 VisualizationController &SqpApplication::visualizationController() noexcept
152 148 {
153 149 return *impl->m_VisualizationController;
154 150 }
155 151
156 152 DragDropHelper &SqpApplication::dragDropHelper() noexcept
157 153 {
158 154 return *impl->m_DragDropHelper;
159 155 }
@@ -1,312 +1,301
1 1 #include "Visualization/VisualizationDragDropContainer.h"
2 #include "Visualization/VisualizationDragWidget.h"
3 #include "SqpApplication.h"
4 2 #include "DragDropHelper.h"
3 #include "SqpApplication.h"
4 #include "Visualization/VisualizationDragWidget.h"
5 5
6 6 #include <QDrag>
7 #include <QVBoxLayout>
8 7 #include <QDragEnterEvent>
8 #include <QVBoxLayout>
9 9
10 10 #include <memory>
11 11
12 12 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate {
13 13
14 QVBoxLayout* m_layout;
15 QStringList m_acceptedMimeTypes;
16 QStringList m_mergeAllowedMimeTypes;
14 QVBoxLayout *m_Layout;
15 QStringList m_AcceptedMimeTypes;
16 QStringList m_MergeAllowedMimeTypes;
17 17
18 explicit VisualizationDragDropContainerPrivate(QWidget* widget)
18 explicit VisualizationDragDropContainerPrivate(QWidget *widget)
19 19 {
20 m_layout = new QVBoxLayout(widget);
21 m_layout->setContentsMargins(0,0,0,0);
20 m_Layout = new QVBoxLayout(widget);
21 m_Layout->setContentsMargins(0, 0, 0, 0);
22 22 }
23 23
24 bool acceptMimeData(const QMimeData* data) const
24 bool acceptMimeData(const QMimeData *data) const
25 25 {
26 for (const auto& type : m_acceptedMimeTypes)
27 {
28 if (data->hasFormat(type))
26 for (const auto &type : m_AcceptedMimeTypes) {
27 if (data->hasFormat(type)) {
29 28 return true;
29 }
30 30 }
31 31
32 32 return false;
33 33 }
34 34
35 bool allowMergeMimeData(const QMimeData* data) const
35 bool allowMergeMimeData(const QMimeData *data) const
36 36 {
37 for (const auto& type : m_mergeAllowedMimeTypes)
38 {
39 if (data->hasFormat(type))
37 for (const auto &type : m_MergeAllowedMimeTypes) {
38 if (data->hasFormat(type)) {
40 39 return true;
40 }
41 41 }
42 42
43 43 return false;
44 44 }
45 45
46 46 bool hasPlaceHolder() const
47 47 {
48 return sqpApp->dragDropHelper().placeHolder().parentWidget() == m_layout->parentWidget();
48 return sqpApp->dragDropHelper().placeHolder().parentWidget() == m_Layout->parentWidget();
49 49 }
50 50
51 VisualizationDragWidget* getChildDragWidgetAt(QWidget* parent, const QPoint &pos) const
51 VisualizationDragWidget *getChildDragWidgetAt(QWidget *parent, const QPoint &pos) const
52 52 {
53 VisualizationDragWidget* dragWidget = nullptr;
54
55 for (auto child : parent->children())
56 {
57 auto widget = qobject_cast<VisualizationDragWidget*>(child);
58 if (widget && widget->isVisible())
59 {
60 if (widget->frameGeometry().contains(pos))
61 {
53 VisualizationDragWidget *dragWidget = nullptr;
54
55 for (auto child : parent->children()) {
56 auto widget = qobject_cast<VisualizationDragWidget *>(child);
57 if (widget && widget->isVisible()) {
58 if (widget->frameGeometry().contains(pos)) {
62 59 dragWidget = widget;
63 60 break;
64 61 }
65 62 }
66 63 }
67 64
68 65 return dragWidget;
69 66 }
70 67
71 bool cursorIsInContainer(QWidget* container) const
68 bool cursorIsInContainer(QWidget *container) const
72 69 {
73 auto adustNum = 18; //to be safe, in case of scrollbar on the side
74 auto containerRect = QRect(QPoint(), container->contentsRect().size()).adjusted(adustNum, adustNum, -adustNum, -adustNum);
70 auto adustNum = 18; // to be safe, in case of scrollbar on the side
71 auto containerRect = QRect(QPoint(), container->contentsRect().size())
72 .adjusted(adustNum, adustNum, -adustNum, -adustNum);
75 73 qDebug() << containerRect << container->mapFromGlobal(QCursor::pos());
76 74 return containerRect.contains(container->mapFromGlobal(QCursor::pos()));
77 75 }
78
79 76 };
80 77
81 78 VisualizationDragDropContainer::VisualizationDragDropContainer(QWidget *parent)
82 : QWidget{parent}, impl{spimpl::make_unique_impl<VisualizationDragDropContainerPrivate>(this)}
79 : QWidget{parent},
80 impl{spimpl::make_unique_impl<VisualizationDragDropContainerPrivate>(this)}
83 81 {
84 82 setAcceptDrops(true);
85 83 }
86 84
87 85 void VisualizationDragDropContainer::addDragWidget(VisualizationDragWidget *dragWidget)
88 86 {
89 impl->m_layout->addWidget(dragWidget);
87 impl->m_Layout->addWidget(dragWidget);
90 88 disconnect(dragWidget, &VisualizationDragWidget::dragDetected, nullptr, nullptr);
91 connect(dragWidget, &VisualizationDragWidget::dragDetected, this, &VisualizationDragDropContainer::startDrag);
89 connect(dragWidget, &VisualizationDragWidget::dragDetected, this,
90 &VisualizationDragDropContainer::startDrag);
92 91 }
93 92
94 void VisualizationDragDropContainer::insertDragWidget(int index, VisualizationDragWidget *dragWidget)
93 void VisualizationDragDropContainer::insertDragWidget(int index,
94 VisualizationDragWidget *dragWidget)
95 95 {
96 impl->m_layout->insertWidget(index, dragWidget);
96 impl->m_Layout->insertWidget(index, dragWidget);
97 97 disconnect(dragWidget, &VisualizationDragWidget::dragDetected, nullptr, nullptr);
98 connect(dragWidget, &VisualizationDragWidget::dragDetected, this, &VisualizationDragDropContainer::startDrag);
98 connect(dragWidget, &VisualizationDragWidget::dragDetected, this,
99 &VisualizationDragDropContainer::startDrag);
99 100 }
100 101
101 102 void VisualizationDragDropContainer::setAcceptedMimeTypes(const QStringList &mimeTypes)
102 103 {
103 impl->m_acceptedMimeTypes = mimeTypes;
104 impl->m_AcceptedMimeTypes = mimeTypes;
104 105 }
105 106
106 107 void VisualizationDragDropContainer::setMergeAllowedMimeTypes(const QStringList &mimeTypes)
107 108 {
108 impl->m_mergeAllowedMimeTypes = mimeTypes;
109 impl->m_MergeAllowedMimeTypes = mimeTypes;
109 110 }
110 111
111 112 int VisualizationDragDropContainer::countDragWidget() const
112 113 {
113 114 auto nbGraph = 0;
114 for (auto child : children())
115 {
116 auto widget = qobject_cast<VisualizationDragWidget*>(child);
117 if (widget)
118 {
115 for (auto child : children()) {
116 auto widget = qobject_cast<VisualizationDragWidget *>(child);
117 if (widget) {
119 118 nbGraph += 1;
120 119 }
121 120 }
122 121
123 122 return nbGraph;
124 123 }
125 124
126 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidget, const QPoint &dragPosition)
125 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidget,
126 const QPoint &dragPosition)
127 127 {
128 auto& helper = sqpApp->dragDropHelper();
128 auto &helper = sqpApp->dragDropHelper();
129 129
130 //Note: The management of the drag object is done by Qt
130 // Note: The management of the drag object is done by Qt
131 131 auto *drag = new QDrag{dragWidget};
132 132 drag->setHotSpot(dragPosition);
133 133
134 134 auto mimeData = dragWidget->mimeData();
135 135 drag->setMimeData(mimeData);
136 136
137 137 auto pixmap = QPixmap(dragWidget->size());
138 138 dragWidget->render(&pixmap);
139 139 drag->setPixmap(pixmap);
140 140
141 141 auto image = pixmap.toImage();
142 142 mimeData->setImageData(image);
143 143 mimeData->setUrls({helper.imageTemporaryUrl(image)});
144 144
145 if (impl->m_layout->indexOf(dragWidget) >= 0)
146 {
145 if (impl->m_Layout->indexOf(dragWidget) >= 0) {
147 146 helper.setCurrentDragWidget(dragWidget);
148 147
149 if (impl->cursorIsInContainer(this))
150 {
151 auto dragWidgetIndex = impl->m_layout->indexOf(dragWidget);
152 helper.insertPlaceHolder(impl->m_layout, dragWidgetIndex);
148 if (impl->cursorIsInContainer(this)) {
149 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
150 helper.insertPlaceHolder(impl->m_Layout, dragWidgetIndex);
153 151 dragWidget->setVisible(false);
154 152 }
155 153 }
156 154
157 //Note: The exec() is blocking on windows but not on linux and macOS
155 // Note: The exec() is blocking on windows but not on linux and macOS
158 156 drag->exec(Qt::MoveAction | Qt::CopyAction);
159 157 }
160 158
161 159 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event)
162 160 {
163 if (impl->acceptMimeData(event->mimeData()))
164 {
161 if (impl->acceptMimeData(event->mimeData())) {
165 162 event->acceptProposedAction();
166 163
167 auto& helper = sqpApp->dragDropHelper();
164 auto &helper = sqpApp->dragDropHelper();
168 165
169 if (!impl->hasPlaceHolder())
170 {
166 if (!impl->hasPlaceHolder()) {
171 167 auto dragWidget = helper.getCurrentDragWidget();
172 auto parentWidget = qobject_cast<VisualizationDragDropContainer*>(dragWidget->parentWidget());
173 if (parentWidget)
174 {
168 auto parentWidget
169 = qobject_cast<VisualizationDragDropContainer *>(dragWidget->parentWidget());
170 if (parentWidget) {
175 171 dragWidget->setVisible(false);
176 172 }
177 173
178 174 auto dragWidgetHovered = impl->getChildDragWidgetAt(this, event->pos());
179 175
180 if (dragWidgetHovered)
181 {
182 auto hoveredWidgetIndex = impl->m_layout->indexOf(dragWidgetHovered);
183 auto dragWidgetIndex = impl->m_layout->indexOf(helper.getCurrentDragWidget());
184 if (dragWidgetIndex >= 0 && dragWidgetIndex <= hoveredWidgetIndex)
185 hoveredWidgetIndex += 1; //Correction of the index if the drop occurs in the same container
176 if (dragWidgetHovered) {
177 auto hoveredWidgetIndex = impl->m_Layout->indexOf(dragWidgetHovered);
178 auto dragWidgetIndex = impl->m_Layout->indexOf(helper.getCurrentDragWidget());
179 if (dragWidgetIndex >= 0 && dragWidgetIndex <= hoveredWidgetIndex) {
180 hoveredWidgetIndex
181 += 1; // Correction of the index if the drop occurs in the same container
182 }
186 183
187 helper.insertPlaceHolder(impl->m_layout, hoveredWidgetIndex);
184 helper.insertPlaceHolder(impl->m_Layout, hoveredWidgetIndex);
188 185 }
189 else
190 {
191 helper.insertPlaceHolder(impl->m_layout, 0);
186 else {
187 helper.insertPlaceHolder(impl->m_Layout, 0);
192 188 }
193 189 }
194 190 }
195 191 else
196 192 event->ignore();
197 193
198 194 QWidget::dragEnterEvent(event);
199 195 }
200 196
201 197 void VisualizationDragDropContainer::dragLeaveEvent(QDragLeaveEvent *event)
202 198 {
203 199 Q_UNUSED(event);
204 200
205 auto& helper = sqpApp->dragDropHelper();
201 auto &helper = sqpApp->dragDropHelper();
206 202
207 if (!impl->cursorIsInContainer(this))
208 {
203 if (!impl->cursorIsInContainer(this)) {
209 204 helper.removePlaceHolder();
210 205
211 206 bool isInternal = true;
212 if (isInternal)
213 {
214 //Only if the drag is strated from the visualization
215 //Show the drag widget at its original place
216 //So the drag widget doesn't stay hidden if the drop occurs outside the visualization drop zone
217 //(It is not possible to catch a drop event outside of the application)
207 if (isInternal) {
208 // Only if the drag is strated from the visualization
209 // Show the drag widget at its original place
210 // So the drag widget doesn't stay hidden if the drop occurs outside the visualization
211 // drop zone (It is not possible to catch a drop event outside of the application)
218 212
219 213 auto dragWidget = sqpApp->dragDropHelper().getCurrentDragWidget();
220 if (dragWidget)
221 {
214 if (dragWidget) {
222 215 dragWidget->setVisible(true);
223 216 }
224 217 }
225 218 }
226 219
227 220 QWidget::dragLeaveEvent(event);
228 221 }
229 222
230 223 void VisualizationDragDropContainer::dragMoveEvent(QDragMoveEvent *event)
231 224 {
232 if (impl->acceptMimeData(event->mimeData()))
233 {
225 if (impl->acceptMimeData(event->mimeData())) {
234 226 auto dragWidgetHovered = impl->getChildDragWidgetAt(this, event->pos());
235 if (dragWidgetHovered)
236 {
227 if (dragWidgetHovered) {
237 228 auto canMerge = impl->allowMergeMimeData(event->mimeData());
238 229
239 230 auto nbDragWidget = countDragWidget();
240 if (nbDragWidget > 0)
241 {
231 if (nbDragWidget > 0) {
242 232 auto graphHeight = size().height() / nbDragWidget;
243 233 auto dropIndex = floor(event->pos().y() / graphHeight);
244 234 auto zoneSize = qMin(graphHeight / 3.0, 150.0);
245 235
246 236 auto isOnTop = event->pos().y() < dropIndex * graphHeight + zoneSize;
247 237 auto isOnBottom = event->pos().y() > (dropIndex + 1) * graphHeight - zoneSize;
248 238
249 auto& helper = sqpApp->dragDropHelper();
250 auto placeHolderIndex = impl->m_layout->indexOf(&(helper.placeHolder()));
239 auto &helper = sqpApp->dragDropHelper();
240 auto placeHolderIndex = impl->m_Layout->indexOf(&(helper.placeHolder()));
251 241
252 if (isOnTop || isOnBottom)
253 {
254 if (isOnBottom)
242 if (isOnTop || isOnBottom) {
243 if (isOnBottom) {
255 244 dropIndex += 1;
245 }
256 246
257 auto dragWidgetIndex = impl->m_layout->indexOf(helper.getCurrentDragWidget());
258 if (dragWidgetIndex >= 0 && dragWidgetIndex <= dropIndex)
259 dropIndex += 1; //Correction of the index if the drop occurs in the same container
247 auto dragWidgetIndex = impl->m_Layout->indexOf(helper.getCurrentDragWidget());
248 if (dragWidgetIndex >= 0 && dragWidgetIndex <= dropIndex) {
249 dropIndex += 1; // Correction of the index if the drop occurs in the same
250 // container
251 }
260 252
261 if (dropIndex != placeHolderIndex)
262 {
263 helper.insertPlaceHolder(impl->m_layout, dropIndex);
253 if (dropIndex != placeHolderIndex) {
254 helper.insertPlaceHolder(impl->m_Layout, dropIndex);
264 255 }
265 256 }
266 else if (canMerge)
267 {
268 //drop on the middle -> merge
269 if (impl->hasPlaceHolder())
270 {
257 else if (canMerge) {
258 // drop on the middle -> merge
259 if (impl->hasPlaceHolder()) {
271 260 helper.removePlaceHolder();
272 261 }
273 262 }
274 263 }
275 264 }
276 265 }
277 266 else
278 267 event->ignore();
279 268
280 269 QWidget::dragMoveEvent(event);
281 270 }
282 271
283 272 void VisualizationDragDropContainer::dropEvent(QDropEvent *event)
284 273 {
285 if (impl->acceptMimeData(event->mimeData()))
286 {
274 if (impl->acceptMimeData(event->mimeData())) {
287 275 auto dragWidget = sqpApp->dragDropHelper().getCurrentDragWidget();
288 if (impl->hasPlaceHolder() && dragWidget)
289 {
290 auto& helper = sqpApp->dragDropHelper();
276 if (impl->hasPlaceHolder() && dragWidget) {
277 auto &helper = sqpApp->dragDropHelper();
291 278
292 auto droppedIndex = impl->m_layout->indexOf(&helper.placeHolder());
279 auto droppedIndex = impl->m_Layout->indexOf(&helper.placeHolder());
293 280
294 auto dragWidgetIndex = impl->m_layout->indexOf(dragWidget);
295 if (dragWidgetIndex >= 0 && dragWidgetIndex < droppedIndex)
296 droppedIndex -= 1; //Correction of the index if the drop occurs in the same container
281 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
282 if (dragWidgetIndex >= 0 && dragWidgetIndex < droppedIndex) {
283 droppedIndex
284 -= 1; // Correction of the index if the drop occurs in the same container
285 }
297 286
298 287 dragWidget->setVisible(true);
299 288 dragWidget->setStyleSheet("");
300 289
301 290 event->acceptProposedAction();
302 291
303 292 helper.removePlaceHolder();
304 293
305 294 emit dropOccured(droppedIndex, event->mimeData());
306 295 }
307 296 }
308 297 else
309 298 event->ignore();
310 299
311 300 QWidget::dropEvent(event);
312 301 }
@@ -1,50 +1,53
1 1 #include "Visualization/VisualizationDragWidget.h"
2 2 #include "Visualization/VisualizationDragDropContainer.h"
3 3
4 #include <QMouseEvent>
5 4 #include <QApplication>
5 #include <QMouseEvent>
6 6
7 7 struct VisualizationDragWidget::VisualizationDragWidgetPrivate {
8 8
9 QPoint m_dragStartPosition;
10 bool m_dragStartPositionValid = false;
9 QPoint m_DragStartPosition;
10 bool m_DragStartPositionValid = false;
11 11
12 explicit VisualizationDragWidgetPrivate()
13 {
14 }
12 explicit VisualizationDragWidgetPrivate() {}
15 13 };
16 14
17 VisualizationDragWidget::VisualizationDragWidget(QWidget* parent)
18 : QWidget{parent}, impl{spimpl::make_unique_impl<VisualizationDragWidgetPrivate>()}
15 VisualizationDragWidget::VisualizationDragWidget(QWidget *parent)
16 : QWidget{parent}, impl{spimpl::make_unique_impl<VisualizationDragWidgetPrivate>()}
19 17 {
20
21 18 }
22 19
23 20 void VisualizationDragWidget::mousePressEvent(QMouseEvent *event)
24 21 {
25 if (event->button() == Qt::LeftButton)
26 impl->m_dragStartPosition = event->pos();
22 if (event->button() == Qt::LeftButton) {
23 impl->m_DragStartPosition = event->pos();
24 }
27 25
28 impl->m_dragStartPositionValid = isDragAllowed();
26 impl->m_DragStartPositionValid = isDragAllowed();
29 27
30 28 QWidget::mousePressEvent(event);
31 29 }
32 30
33 31 void VisualizationDragWidget::mouseMoveEvent(QMouseEvent *event)
34 32 {
35 if (!impl->m_dragStartPositionValid || !isDragAllowed())
33 if (!impl->m_DragStartPositionValid || !isDragAllowed()) {
36 34 return;
35 }
37 36
38 if (!(event->buttons() & Qt::LeftButton))
37 if (!(event->buttons() & Qt::LeftButton)) {
39 38 return;
39 }
40 40
41 if (!event->modifiers().testFlag(Qt::AltModifier))
41 if (!event->modifiers().testFlag(Qt::AltModifier)) {
42 42 return;
43 }
43 44
44 if ((event->pos() - impl->m_dragStartPosition).manhattanLength() < QApplication::startDragDistance())
45 if ((event->pos() - impl->m_DragStartPosition).manhattanLength()
46 < QApplication::startDragDistance()) {
45 47 return;
48 }
46 49
47 emit dragDetected(this, impl->m_dragStartPosition);
50 emit dragDetected(this, impl->m_DragStartPosition);
48 51
49 52 QWidget::mouseMoveEvent(event);
50 53 }
@@ -1,385 +1,385
1 1 #include "Visualization/VisualizationGraphWidget.h"
2 2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 3 #include "Visualization/VisualizationDefs.h"
4 4 #include "Visualization/VisualizationGraphHelper.h"
5 5 #include "Visualization/VisualizationGraphRenderingDelegate.h"
6 6 #include "Visualization/VisualizationZoneWidget.h"
7 7 #include "ui_VisualizationGraphWidget.h"
8 8
9 9 #include <Data/ArrayData.h>
10 10 #include <Data/IDataSeries.h>
11 #include <DragDropHelper.h>
11 12 #include <Settings/SqpSettingsDefs.h>
12 13 #include <SqpApplication.h>
13 #include <DragDropHelper.h>
14 14 #include <Variable/Variable.h>
15 15 #include <Variable/VariableController.h>
16 16
17 17 #include <unordered_map>
18 18
19 19 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
20 20
21 21 namespace {
22 22
23 23 /// Key pressed to enable zoom on horizontal axis
24 24 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
25 25
26 26 /// Key pressed to enable zoom on vertical axis
27 27 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
28 28
29 29 } // namespace
30 30
31 31 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
32 32
33 33 explicit VisualizationGraphWidgetPrivate(const QString &name)
34 34 : m_Name{name},
35 35 m_DoAcquisition{true},
36 36 m_IsCalibration{false},
37 37 m_RenderingDelegate{nullptr}
38 38 {
39 39 }
40 40
41 41 QString m_Name;
42 42 // 1 variable -> n qcpplot
43 43 std::map<std::shared_ptr<Variable>, PlottablesMap> m_VariableToPlotMultiMap;
44 44 bool m_DoAcquisition;
45 45 bool m_IsCalibration;
46 46 QCPItemTracer *m_TextTracer;
47 47 /// Delegate used to attach rendering features to the plot
48 48 std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
49 49 };
50 50
51 51 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
52 52 : VisualizationDragWidget{parent},
53 53 ui{new Ui::VisualizationGraphWidget},
54 54 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>(name)}
55 55 {
56 56 ui->setupUi(this);
57 57
58 58 // 'Close' options : widget is deleted when closed
59 59 setAttribute(Qt::WA_DeleteOnClose);
60 60
61 61 // Set qcpplot properties :
62 62 // - Drag (on x-axis) and zoom are enabled
63 63 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
64 64 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectItems);
65 65 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
66 66
67 67 // The delegate must be initialized after the ui as it uses the plot
68 68 impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*this);
69 69
70 70 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
71 71 connect(ui->widget, &QCustomPlot::mouseRelease, this,
72 72 &VisualizationGraphWidget::onMouseRelease);
73 73 connect(ui->widget, &QCustomPlot::mouseMove, this, &VisualizationGraphWidget::onMouseMove);
74 74 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
75 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
76 &QCPAxis::rangeChanged),
77 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
75 connect(
76 ui->widget->xAxis,
77 static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(&QCPAxis::rangeChanged),
78 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
78 79
79 80 // Activates menu when right clicking on the graph
80 81 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
81 82 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
82 83 &VisualizationGraphWidget::onGraphMenuRequested);
83 84
84 85 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
85 86 &VariableController::onRequestDataLoading);
86 87
87 88 connect(&sqpApp->variableController(), &VariableController::updateVarDisplaying, this,
88 89 &VisualizationGraphWidget::onUpdateVarDisplaying);
89 90 }
90 91
91 92
92 93 VisualizationGraphWidget::~VisualizationGraphWidget()
93 94 {
94 95 delete ui;
95 96 }
96 97
97 98 VisualizationZoneWidget *VisualizationGraphWidget::parentZoneWidget() const noexcept
98 99 {
99 100 auto parent = parentWidget();
100 do
101 {
101 do {
102 102 parent = parent->parentWidget();
103 } while (parent != nullptr && !qobject_cast<VisualizationZoneWidget*>(parent));
103 } while (parent != nullptr && !qobject_cast<VisualizationZoneWidget *>(parent));
104 104
105 return qobject_cast<VisualizationZoneWidget*>(parent);
105 return qobject_cast<VisualizationZoneWidget *>(parent);
106 106 }
107 107
108 108 void VisualizationGraphWidget::enableAcquisition(bool enable)
109 109 {
110 110 impl->m_DoAcquisition = enable;
111 111 }
112 112
113 113 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, SqpRange range)
114 114 {
115 115 // Uses delegate to create the qcpplot components according to the variable
116 116 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
117 117 impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)});
118 118
119 119 // Set axes properties according to the units of the data series
120 120 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
121 121 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
122 122 auto xAxisUnit = Unit{};
123 123 auto valuesUnit = Unit{};
124 124
125 125 if (auto dataSeries = variable->dataSeries()) {
126 126 dataSeries->lockRead();
127 127 xAxisUnit = dataSeries->xAxisUnit();
128 128 valuesUnit = dataSeries->valuesUnit();
129 129 dataSeries->unlock();
130 130 }
131 131 impl->m_RenderingDelegate->setAxesProperties(xAxisUnit, valuesUnit);
132 132
133 133 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
134 134
135 135 this->enableAcquisition(false);
136 136 this->setGraphRange(range);
137 137 this->enableAcquisition(true);
138 138
139 139 emit requestDataLoading(QVector<std::shared_ptr<Variable> >() << variable, range, false);
140 140
141 141 emit variableAdded(variable);
142 142 }
143 143
144 144 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
145 145 {
146 146 // Each component associated to the variable :
147 147 // - is removed from qcpplot (which deletes it)
148 148 // - is no longer referenced in the map
149 149 auto variableIt = impl->m_VariableToPlotMultiMap.find(variable);
150 150 if (variableIt != impl->m_VariableToPlotMultiMap.cend()) {
151 151 emit variableAboutToBeRemoved(variable);
152 152
153 153 auto &plottablesMap = variableIt->second;
154 154
155 155 for (auto plottableIt = plottablesMap.cbegin(), plottableEnd = plottablesMap.cend();
156 156 plottableIt != plottableEnd;) {
157 157 ui->widget->removePlottable(plottableIt->second);
158 158 plottableIt = plottablesMap.erase(plottableIt);
159 159 }
160 160
161 161 impl->m_VariableToPlotMultiMap.erase(variableIt);
162 162 }
163 163
164 164 // Updates graph
165 165 ui->widget->replot();
166 166 }
167 167
168 QList<std::shared_ptr<Variable>> VisualizationGraphWidget::variables() const
168 QList<std::shared_ptr<Variable> > VisualizationGraphWidget::variables() const
169 169 {
170 auto variables = QList<std::shared_ptr<Variable>>{};
171 for (auto it = std::cbegin(impl->m_VariableToPlotMultiMap); it != std::cend(impl->m_VariableToPlotMultiMap); ++it)
172 {
170 auto variables = QList<std::shared_ptr<Variable> >{};
171 for (auto it = std::cbegin(impl->m_VariableToPlotMultiMap);
172 it != std::cend(impl->m_VariableToPlotMultiMap); ++it) {
173 173 variables << it->first;
174 174 }
175 175
176 176 return variables;
177 177 }
178 178
179 179 void VisualizationGraphWidget::setYRange(const SqpRange &range)
180 180 {
181 181 ui->widget->yAxis->setRange(range.m_TStart, range.m_TEnd);
182 182 }
183 183
184 184 SqpRange VisualizationGraphWidget::graphRange() const noexcept
185 185 {
186 186 auto graphRange = ui->widget->xAxis->range();
187 187 return SqpRange{graphRange.lower, graphRange.upper};
188 188 }
189 189
190 190 void VisualizationGraphWidget::setGraphRange(const SqpRange &range)
191 191 {
192 192 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
193 193 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
194 194 ui->widget->replot();
195 195 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
196 196 }
197 197
198 198 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
199 199 {
200 200 if (visitor) {
201 201 visitor->visit(this);
202 202 }
203 203 else {
204 204 qCCritical(LOG_VisualizationGraphWidget())
205 205 << tr("Can't visit widget : the visitor is null");
206 206 }
207 207 }
208 208
209 209 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
210 210 {
211 211 /// @todo : for the moment, a graph can always accomodate a variable
212 212 Q_UNUSED(variable);
213 213 return true;
214 214 }
215 215
216 216 bool VisualizationGraphWidget::contains(const Variable &variable) const
217 217 {
218 218 // Finds the variable among the keys of the map
219 219 auto variablePtr = &variable;
220 220 auto findVariable
221 221 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
222 222
223 223 auto end = impl->m_VariableToPlotMultiMap.cend();
224 224 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
225 225 return it != end;
226 226 }
227 227
228 228 QString VisualizationGraphWidget::name() const
229 229 {
230 230 return impl->m_Name;
231 231 }
232 232
233 233 QMimeData *VisualizationGraphWidget::mimeData() const
234 234 {
235 auto *mimeData = new QMimeData;
236 mimeData->setData(DragDropHelper::MIME_TYPE_GRAPH, QByteArray());
235 auto *mimeData = new QMimeData;
236 mimeData->setData(DragDropHelper::MIME_TYPE_GRAPH, QByteArray());
237 237
238 return mimeData;
238 return mimeData;
239 239 }
240 240
241 241 bool VisualizationGraphWidget::isDragAllowed() const
242 242 {
243 243 return true;
244 244 }
245 245
246 246 void VisualizationGraphWidget::closeEvent(QCloseEvent *event)
247 247 {
248 248 Q_UNUSED(event);
249 249
250 250 // Prevents that all variables will be removed from graph when it will be closed
251 251 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
252 252 emit variableAboutToBeRemoved(variableEntry.first);
253 253 }
254 254 }
255 255
256 256 void VisualizationGraphWidget::enterEvent(QEvent *event)
257 257 {
258 258 Q_UNUSED(event);
259 259 impl->m_RenderingDelegate->showGraphOverlay(true);
260 260 }
261 261
262 262 void VisualizationGraphWidget::leaveEvent(QEvent *event)
263 263 {
264 264 Q_UNUSED(event);
265 265 impl->m_RenderingDelegate->showGraphOverlay(false);
266 266 }
267 267
268 268 QCustomPlot &VisualizationGraphWidget::plot() noexcept
269 269 {
270 270 return *ui->widget;
271 271 }
272 272
273 273 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
274 274 {
275 275 QMenu graphMenu{};
276 276
277 277 // Iterates on variables (unique keys)
278 278 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
279 279 end = impl->m_VariableToPlotMultiMap.cend();
280 280 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
281 281 // 'Remove variable' action
282 282 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
283 283 [ this, var = it->first ]() { removeVariable(var); });
284 284 }
285 285
286 286 if (!graphMenu.isEmpty()) {
287 287 graphMenu.exec(QCursor::pos());
288 288 }
289 289 }
290 290
291 291 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
292 292 {
293 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged")
294 << QThread::currentThread()->objectName() << "DoAcqui"
295 << impl->m_DoAcquisition;
293 qCDebug(LOG_VisualizationGraphWidget())
294 << tr("TORM: VisualizationGraphWidget::onRangeChanged")
295 << QThread::currentThread()->objectName() << "DoAcqui" << impl->m_DoAcquisition;
296 296
297 297 auto graphRange = SqpRange{t1.lower, t1.upper};
298 298 auto oldGraphRange = SqpRange{t2.lower, t2.upper};
299 299
300 300 if (impl->m_DoAcquisition) {
301 301 QVector<std::shared_ptr<Variable> > variableUnderGraphVector;
302 302
303 303 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
304 304 end = impl->m_VariableToPlotMultiMap.end();
305 305 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
306 306 variableUnderGraphVector.push_back(it->first);
307 307 }
308 308 emit requestDataLoading(std::move(variableUnderGraphVector), graphRange,
309 309 !impl->m_IsCalibration);
310 310
311 311 if (!impl->m_IsCalibration) {
312 312 qCDebug(LOG_VisualizationGraphWidget())
313 313 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
314 314 << QThread::currentThread()->objectName() << graphRange << oldGraphRange;
315 315 emit synchronize(graphRange, oldGraphRange);
316 316 }
317 317 }
318 318 }
319 319
320 320 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
321 321 {
322 322 // Handles plot rendering when mouse is moving
323 323 impl->m_RenderingDelegate->onMouseMove(event);
324 324
325 325 VisualizationDragWidget::mouseMoveEvent(event);
326 326 }
327 327
328 328 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
329 329 {
330 330 auto zoomOrientations = QFlags<Qt::Orientation>{};
331 331
332 332 // Lambda that enables a zoom orientation if the key modifier related to this orientation
333 333 // has
334 334 // been pressed
335 335 auto enableOrientation
336 336 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
337 337 auto orientationEnabled = event->modifiers().testFlag(modifier);
338 338 zoomOrientations.setFlag(orientation, orientationEnabled);
339 339 };
340 340 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
341 341 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
342 342
343 343 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
344 344 }
345 345
346 346 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
347 347 {
348 348 impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
349 349
350 350 plot().setInteraction(QCP::iRangeDrag, !event->modifiers().testFlag(Qt::AltModifier));
351 351
352 352 VisualizationDragWidget::mousePressEvent(event);
353 353 }
354 354
355 355 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
356 356 {
357 357 impl->m_IsCalibration = false;
358 358 }
359 359
360 360 void VisualizationGraphWidget::onDataCacheVariableUpdated()
361 361 {
362 362 auto graphRange = ui->widget->xAxis->range();
363 363 auto dateTime = SqpRange{graphRange.lower, graphRange.upper};
364 364
365 365 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
366 366 auto variable = variableEntry.first;
367 367 qCDebug(LOG_VisualizationGraphWidget())
368 368 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
369 369 qCDebug(LOG_VisualizationGraphWidget())
370 370 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
371 371 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
372 372 VisualizationGraphHelper::updateData(variableEntry.second, variable->dataSeries(),
373 373 variable->range());
374 374 }
375 375 }
376 376 }
377 377
378 378 void VisualizationGraphWidget::onUpdateVarDisplaying(std::shared_ptr<Variable> variable,
379 379 const SqpRange &range)
380 380 {
381 381 auto it = impl->m_VariableToPlotMultiMap.find(variable);
382 382 if (it != impl->m_VariableToPlotMultiMap.end()) {
383 383 VisualizationGraphHelper::updateData(it->second, variable->dataSeries(), range);
384 384 }
385 385 }
@@ -1,219 +1,219
1 1 #include "Visualization/VisualizationTabWidget.h"
2 2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 3 #include "ui_VisualizationTabWidget.h"
4 4
5 #include "Visualization/VisualizationZoneWidget.h"
6 5 #include "Visualization/VisualizationGraphWidget.h"
6 #include "Visualization/VisualizationZoneWidget.h"
7 7
8 8 #include "Variable/VariableController.h"
9 9
10 #include "SqpApplication.h"
11 10 #include "DragDropHelper.h"
11 #include "SqpApplication.h"
12 12
13 13 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
14 14
15 15 namespace {
16 16
17 17 /// Generates a default name for a new zone, according to the number of zones already displayed in
18 18 /// the tab
19 19 QString defaultZoneName(const QLayout &layout)
20 20 {
21 21 auto count = 0;
22 22 for (auto i = 0; i < layout.count(); ++i) {
23 23 if (dynamic_cast<VisualizationZoneWidget *>(layout.itemAt(i)->widget())) {
24 24 count++;
25 25 }
26 26 }
27 27
28 28 return QObject::tr("Zone %1").arg(count + 1);
29 29 }
30 30
31 31 /**
32 32 * Applies a function to all zones of the tab represented by its layout
33 33 * @param layout the layout that contains zones
34 34 * @param fun the function to apply to each zone
35 35 */
36 36 template <typename Fun>
37 37 void processZones(QLayout &layout, Fun fun)
38 38 {
39 39 for (auto i = 0; i < layout.count(); ++i) {
40 40 if (auto item = layout.itemAt(i)) {
41 41 if (auto visualizationZoneWidget
42 42 = dynamic_cast<VisualizationZoneWidget *>(item->widget())) {
43 43 fun(*visualizationZoneWidget);
44 44 }
45 45 }
46 46 }
47 47 }
48 48
49 49 } // namespace
50 50
51 51 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
52 52 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
53 53
54 54 QString m_Name;
55 55 };
56 56
57 57 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
58 58 : QWidget{parent},
59 59 ui{new Ui::VisualizationTabWidget},
60 60 impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)}
61 61 {
62 62 ui->setupUi(this);
63 63
64 ui->dragDropContainer->setAcceptedMimeTypes({DragDropHelper::MIME_TYPE_GRAPH, DragDropHelper::MIME_TYPE_ZONE});
65 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this, &VisualizationTabWidget::dropMimeData);
64 ui->dragDropContainer->setAcceptedMimeTypes(
65 {DragDropHelper::MIME_TYPE_GRAPH, DragDropHelper::MIME_TYPE_ZONE});
66 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this,
67 &VisualizationTabWidget::dropMimeData);
66 68 sqpApp->dragDropHelper().addDragDropScrollArea(ui->scrollArea);
67 69
68 70 // Widget is deleted when closed
69 71 setAttribute(Qt::WA_DeleteOnClose);
70 72 }
71 73
72 74 VisualizationTabWidget::~VisualizationTabWidget()
73 75 {
74 76 sqpApp->dragDropHelper().removeDragDropScrollArea(ui->scrollArea);
75 77 delete ui;
76 78 }
77 79
78 80 void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget)
79 81 {
80 82 ui->dragDropContainer->addDragWidget(zoneWidget);
81 83 }
82 84
83 85 void VisualizationTabWidget::insertZone(int index, VisualizationZoneWidget *zoneWidget)
84 86 {
85 ui->dragDropContainer->insertDragWidget(index, zoneWidget);
87 ui->dragDropContainer->insertDragWidget(index, zoneWidget);
86 88 }
87 89
88 90 VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable)
89 91 {
90 92 return createZone({variable}, -1);
91 93 }
92 94
93 VisualizationZoneWidget *VisualizationTabWidget::createZone(const QList<std::shared_ptr<Variable> > &variables, int index)
95 VisualizationZoneWidget *
96 VisualizationTabWidget::createZone(const QList<std::shared_ptr<Variable> > &variables, int index)
94 97 {
95 98 auto zoneWidget = createEmptyZone(index);
96 99
97 100 // Creates a new graph into the zone
98 101 zoneWidget->createGraph(variables, index);
99 102
100 103 return zoneWidget;
101 104 }
102 105
103 106 VisualizationZoneWidget *VisualizationTabWidget::createEmptyZone(int index)
104 107 {
105 auto zoneWidget = new VisualizationZoneWidget{defaultZoneName(*ui->dragDropContainer->layout()), this};
108 auto zoneWidget
109 = new VisualizationZoneWidget{defaultZoneName(*ui->dragDropContainer->layout()), this};
106 110 this->insertZone(index, zoneWidget);
107 111
108 112 return zoneWidget;
109 113 }
110 114
111 115 void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor)
112 116 {
113 117 if (visitor) {
114 118 visitor->visitEnter(this);
115 119
116 120 // Apply visitor to zone children: widgets different from zones are not visited (no action)
117 121 processZones(tabLayout(), [visitor](VisualizationZoneWidget &zoneWidget) {
118 122 zoneWidget.accept(visitor);
119 123 });
120 124
121 125 visitor->visitLeave(this);
122 126 }
123 127 else {
124 128 qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null");
125 129 }
126 130 }
127 131
128 132 bool VisualizationTabWidget::canDrop(const Variable &variable) const
129 133 {
130 134 // A tab can always accomodate a variable
131 135 Q_UNUSED(variable);
132 136 return true;
133 137 }
134 138
135 139 bool VisualizationTabWidget::contains(const Variable &variable) const
136 140 {
137 141 Q_UNUSED(variable);
138 142 return false;
139 143 }
140 144
141 145 QString VisualizationTabWidget::name() const
142 146 {
143 147 return impl->m_Name;
144 148 }
145 149
146 150 void VisualizationTabWidget::closeEvent(QCloseEvent *event)
147 151 {
148 152 // Closes zones in the tab
149 153 processZones(tabLayout(), [](VisualizationZoneWidget &zoneWidget) { zoneWidget.close(); });
150 154
151 155 QWidget::closeEvent(event);
152 156 }
153 157
154 158 QLayout &VisualizationTabWidget::tabLayout() const noexcept
155 159 {
156 160 return *ui->dragDropContainer->layout();
157 161 }
158 162
159 163 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData)
160 164 {
161 auto& helper = sqpApp->dragDropHelper();
162 if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_GRAPH))
163 {
164 auto graphWidget = static_cast<VisualizationGraphWidget*>(helper.getCurrentDragWidget());
165 auto parentDragDropContainer = qobject_cast<VisualizationDragDropContainer*>(graphWidget->parentWidget());
165 auto &helper = sqpApp->dragDropHelper();
166 if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_GRAPH)) {
167 auto graphWidget = static_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
168 auto parentDragDropContainer
169 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
166 170 Q_ASSERT(parentDragDropContainer);
167 171
168 172 auto nbGraph = parentDragDropContainer->countDragWidget();
169 173
170 const auto& variables = graphWidget->variables();
174 const auto &variables = graphWidget->variables();
171 175
172 if (!variables.isEmpty())
173 {
174 //Abort the requests for the variables (if any)
175 //Commented, because it's not sure if it's needed or not
176 //for (const auto& var : variables)
176 if (!variables.isEmpty()) {
177 // Abort the requests for the variables (if any)
178 // Commented, because it's not sure if it's needed or not
179 // for (const auto& var : variables)
177 180 //{
178 181 // sqpApp->variableController().onAbortProgressRequested(var);
179 182 //}
180 183
181 if (nbGraph == 1)
182 {
183 //This is the only graph in the previous zone, close the zone
184 if (nbGraph == 1) {
185 // This is the only graph in the previous zone, close the zone
184 186 graphWidget->parentZoneWidget()->close();
185 187 }
186 else
187 {
188 //Close the graph
188 else {
189 // Close the graph
189 190 graphWidget->close();
190 191 }
191 192
192 193 createZone(variables, index);
193 194 }
194 else
195 {
196 //The graph is empty, create an empty zone and move the graph inside
195 else {
196 // The graph is empty, create an empty zone and move the graph inside
197 197
198 198 auto parentZoneWidget = graphWidget->parentZoneWidget();
199 199
200 200 parentDragDropContainer->layout()->removeWidget(graphWidget);
201 201
202 202 auto zoneWidget = createEmptyZone(index);
203 203 zoneWidget->addGraph(graphWidget);
204 204
205 //Close the old zone if it was the only graph inside
206 if (nbGraph == 1)
205 // Close the old zone if it was the only graph inside
206 if (nbGraph == 1) {
207 207 parentZoneWidget->close();
208 }
208 209 }
209 210 }
210 else if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_ZONE))
211 {
212 //Simple move of the zone, no variable operation associated
213 auto zoneWidget = static_cast<VisualizationZoneWidget*>(helper.getCurrentDragWidget());
211 else if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_ZONE)) {
212 // Simple move of the zone, no variable operation associated
213 auto zoneWidget = static_cast<VisualizationZoneWidget *>(helper.getCurrentDragWidget());
214 214 auto parentDragDropContainer = zoneWidget->parentWidget();
215 215 parentDragDropContainer->layout()->removeWidget(zoneWidget);
216 216
217 217 ui->dragDropContainer->insertDragWidget(index, zoneWidget);
218 218 }
219 219 }
@@ -1,413 +1,410
1 1 #include "Visualization/VisualizationZoneWidget.h"
2 2
3 3 #include "Visualization/IVisualizationWidgetVisitor.h"
4 4 #include "Visualization/QCustomPlotSynchronizer.h"
5 5 #include "Visualization/VisualizationGraphWidget.h"
6 6 #include "ui_VisualizationZoneWidget.h"
7 7
8 8 #include <Data/SqpRange.h>
9 9 #include <Variable/Variable.h>
10 10 #include <Variable/VariableController.h>
11 11
12 #include <DragDropHelper.h>
12 13 #include <QUuid>
13 14 #include <SqpApplication.h>
14 #include <DragDropHelper.h>
15 15 #include <cmath>
16 16
17 17 #include <QLayout>
18 18
19 19 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
20 20
21 21 namespace {
22 22
23 23 /// Minimum height for graph added in zones (in pixels)
24 24 const auto GRAPH_MINIMUM_HEIGHT = 300;
25 25
26 26 /// Generates a default name for a new graph, according to the number of graphs already displayed in
27 27 /// the zone
28 28 QString defaultGraphName(const QLayout &layout)
29 29 {
30 30 auto count = 0;
31 31 for (auto i = 0; i < layout.count(); ++i) {
32 32 if (dynamic_cast<VisualizationGraphWidget *>(layout.itemAt(i)->widget())) {
33 33 count++;
34 34 }
35 35 }
36 36
37 37 return QObject::tr("Graph %1").arg(count + 1);
38 38 }
39 39
40 40 /**
41 41 * Applies a function to all graphs of the zone represented by its layout
42 42 * @param layout the layout that contains graphs
43 43 * @param fun the function to apply to each graph
44 44 */
45 45 template <typename Fun>
46 46 void processGraphs(QLayout &layout, Fun fun)
47 47 {
48 48 for (auto i = 0; i < layout.count(); ++i) {
49 49 if (auto item = layout.itemAt(i)) {
50 50 if (auto visualizationGraphWidget
51 51 = dynamic_cast<VisualizationGraphWidget *>(item->widget())) {
52 52 fun(*visualizationGraphWidget);
53 53 }
54 54 }
55 55 }
56 56 }
57 57
58 58 } // namespace
59 59
60 60 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
61 61
62 62 explicit VisualizationZoneWidgetPrivate()
63 63 : m_SynchronisationGroupId{QUuid::createUuid()},
64 64 m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
65 65 {
66 66 }
67 67 QUuid m_SynchronisationGroupId;
68 68 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
69 69 };
70 70
71 71 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
72 72 : VisualizationDragWidget{parent},
73 73 ui{new Ui::VisualizationZoneWidget},
74 74 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
75 75 {
76 76 ui->setupUi(this);
77 77
78 78 ui->zoneNameLabel->setText(name);
79 79
80 80 ui->dragDropContainer->setAcceptedMimeTypes({DragDropHelper::MIME_TYPE_GRAPH});
81 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this, &VisualizationZoneWidget::dropMimeData);
81 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this,
82 &VisualizationZoneWidget::dropMimeData);
82 83
83 84 // 'Close' options : widget is deleted when closed
84 85 setAttribute(Qt::WA_DeleteOnClose);
85 86 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
86 87 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
87 88
88 89 // Synchronisation id
89 90 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
90 91 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
91 92 }
92 93
93 94 VisualizationZoneWidget::~VisualizationZoneWidget()
94 95 {
95 96 delete ui;
96 97 }
97 98
98 99 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
99 100 {
100 101 // Synchronize new graph with others in the zone
101 102 impl->m_Synchronizer->addGraph(*graphWidget);
102 103
103 104 ui->dragDropContainer->addDragWidget(graphWidget);
104 105 }
105 106
106 107 void VisualizationZoneWidget::insertGraph(int index, VisualizationGraphWidget *graphWidget)
107 108 {
108 109 // Synchronize new graph with others in the zone
109 110 impl->m_Synchronizer->addGraph(*graphWidget);
110 111
111 112 ui->dragDropContainer->insertDragWidget(index, graphWidget);
112 113 }
113 114
114 115 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
115 116 {
116 117 return createGraph(variable, -1);
117 118 }
118 119
119 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable, int index)
120 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable,
121 int index)
120 122 {
121 auto graphWidget = new VisualizationGraphWidget{
122 defaultGraphName(*ui->dragDropContainer->layout()), this};
123 auto graphWidget
124 = new VisualizationGraphWidget{defaultGraphName(*ui->dragDropContainer->layout()), this};
123 125
124 126
125 127 // Set graph properties
126 128 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
127 129 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
128 130
129 131
130 132 // Lambda to synchronize zone widget
131 133 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &graphRange,
132 134 const SqpRange &oldGraphRange) {
133 135
134 136 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
135 137 auto frameLayout = ui->dragDropContainer->layout();
136 138 for (auto i = 0; i < frameLayout->count(); ++i) {
137 139 auto graphChild
138 140 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
139 141 if (graphChild && (graphChild != graphWidget)) {
140 142
141 143 auto graphChildRange = graphChild->graphRange();
142 144 switch (zoomType) {
143 145 case AcquisitionZoomType::ZoomIn: {
144 146 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
145 147 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
146 148 graphChildRange.m_TStart += deltaLeft;
147 149 graphChildRange.m_TEnd -= deltaRight;
148 150 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
149 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
150 << deltaLeft;
151 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
152 << deltaRight;
151 qCDebug(LOG_VisualizationZoneWidget())
152 << tr("TORM: deltaLeft") << deltaLeft;
153 qCDebug(LOG_VisualizationZoneWidget())
154 << tr("TORM: deltaRight") << deltaRight;
153 155 qCDebug(LOG_VisualizationZoneWidget())
154 156 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
155 157
156 158 break;
157 159 }
158 160
159 161 case AcquisitionZoomType::ZoomOut: {
160 162 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
161 163 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
162 164 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
163 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
164 << deltaLeft;
165 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
166 << deltaRight;
165 qCDebug(LOG_VisualizationZoneWidget())
166 << tr("TORM: deltaLeft") << deltaLeft;
167 qCDebug(LOG_VisualizationZoneWidget())
168 << tr("TORM: deltaRight") << deltaRight;
167 169 qCDebug(LOG_VisualizationZoneWidget())
168 170 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
169 171 graphChildRange.m_TStart -= deltaLeft;
170 172 graphChildRange.m_TEnd += deltaRight;
171 173 break;
172 174 }
173 175 case AcquisitionZoomType::PanRight: {
174 176 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
175 177 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
176 178 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
177 179 graphChildRange.m_TStart += deltaLeft;
178 180 graphChildRange.m_TEnd += deltaRight;
179 181 qCDebug(LOG_VisualizationZoneWidget())
180 182 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
181 183 break;
182 184 }
183 185 case AcquisitionZoomType::PanLeft: {
184 186 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
185 187 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
186 188 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
187 189 graphChildRange.m_TStart -= deltaLeft;
188 190 graphChildRange.m_TEnd -= deltaRight;
189 191 break;
190 192 }
191 193 case AcquisitionZoomType::Unknown: {
192 194 qCDebug(LOG_VisualizationZoneWidget())
193 195 << tr("Impossible to synchronize: zoom type unknown");
194 196 break;
195 197 }
196 198 default:
197 199 qCCritical(LOG_VisualizationZoneWidget())
198 200 << tr("Impossible to synchronize: zoom type not take into account");
199 201 // No action
200 202 break;
201 203 }
202 204 graphChild->enableAcquisition(false);
203 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
204 << graphChild->graphRange();
205 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
206 << graphChildRange;
205 qCDebug(LOG_VisualizationZoneWidget())
206 << tr("TORM: Range before: ") << graphChild->graphRange();
207 qCDebug(LOG_VisualizationZoneWidget())
208 << tr("TORM: Range after : ") << graphChildRange;
207 209 qCDebug(LOG_VisualizationZoneWidget())
208 210 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
209 211 graphChild->setGraphRange(graphChildRange);
210 212 graphChild->enableAcquisition(true);
211 213 }
212 214 }
213 215 };
214 216
215 217 // connection for synchronization
216 218 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
217 219 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
218 220 &VisualizationZoneWidget::onVariableAdded);
219 221 connect(graphWidget, &VisualizationGraphWidget::variableAboutToBeRemoved, this,
220 222 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
221 223
222 224 auto range = SqpRange{};
223 225
224 226 // Apply visitor to graph children
225 227 auto layout = ui->dragDropContainer->layout();
226 228 if (layout->count() > 0) {
227 229 // Case of a new graph in a existant zone
228 230 if (auto visualizationGraphWidget
229 = dynamic_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
231 = dynamic_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
230 232 range = visualizationGraphWidget->graphRange();
231 233 }
232 234 }
233 235 else {
234 236 // Case of a new graph as the first of the zone
235 237 range = variable->range();
236 238 }
237 239
238 240 this->insertGraph(index, graphWidget);
239 241
240 242 graphWidget->addVariable(variable, range);
241 243
242 244 // get y using variable range
243 245 if (auto dataSeries = variable->dataSeries()) {
244 246 dataSeries->lockRead();
245 247 auto valuesBounds
246 = dataSeries->valuesBounds(variable->range().m_TStart, variable->range().m_TEnd);
248 = dataSeries->valuesBounds(variable->range().m_TStart, variable->range().m_TEnd);
247 249 auto end = dataSeries->cend();
248 250 if (valuesBounds.first != end && valuesBounds.second != end) {
249 251 auto rangeValue = [](const auto &value) { return std::isnan(value) ? 0. : value; };
250 252
251 253 auto minValue = rangeValue(valuesBounds.first->minValue());
252 254 auto maxValue = rangeValue(valuesBounds.second->maxValue());
253 255
254 256 graphWidget->setYRange(SqpRange{minValue, maxValue});
255 257 }
256 258 dataSeries->unlock();
257 259 }
258 260
259 261 return graphWidget;
260 262 }
261 263
262 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(const QList<std::shared_ptr<Variable> > variables, int index)
264 VisualizationGraphWidget *
265 VisualizationZoneWidget::createGraph(const QList<std::shared_ptr<Variable> > variables, int index)
263 266 {
264 if (variables.isEmpty())
267 if (variables.isEmpty()) {
265 268 return nullptr;
269 }
266 270
267 271 auto graphWidget = createGraph(variables.first(), index);
268 for (auto variableIt = variables.cbegin() + 1; variableIt != variables.cend(); ++variableIt)
269 {
272 for (auto variableIt = variables.cbegin() + 1; variableIt != variables.cend(); ++variableIt) {
270 273 graphWidget->addVariable(*variableIt, graphWidget->graphRange());
271 274 }
272 275
273 276 return graphWidget;
274 277 }
275 278
276 279 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
277 280 {
278 281 if (visitor) {
279 282 visitor->visitEnter(this);
280 283
281 284 // Apply visitor to graph children: widgets different from graphs are not visited (no
282 285 // action)
283 286 processGraphs(
284 287 *ui->dragDropContainer->layout(),
285 288 [visitor](VisualizationGraphWidget &graphWidget) { graphWidget.accept(visitor); });
286 289
287 290 visitor->visitLeave(this);
288 291 }
289 292 else {
290 293 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
291 294 }
292 295 }
293 296
294 297 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
295 298 {
296 299 // A tab can always accomodate a variable
297 300 Q_UNUSED(variable);
298 301 return true;
299 302 }
300 303
301 304 bool VisualizationZoneWidget::contains(const Variable &variable) const
302 305 {
303 306 Q_UNUSED(variable);
304 307 return false;
305 308 }
306 309
307 310 QString VisualizationZoneWidget::name() const
308 311 {
309 312 return ui->zoneNameLabel->text();
310 313 }
311 314
312 315 QMimeData *VisualizationZoneWidget::mimeData() const
313 316 {
314 317 auto *mimeData = new QMimeData;
315 318 mimeData->setData(DragDropHelper::MIME_TYPE_ZONE, QByteArray());
316 319
317 320 return mimeData;
318 321 }
319 322
320 323 bool VisualizationZoneWidget::isDragAllowed() const
321 324 {
322 325 return true;
323 326 }
324 327
325 328 void VisualizationZoneWidget::closeEvent(QCloseEvent *event)
326 329 {
327 330 // Closes graphs in the zone
328 331 processGraphs(*ui->dragDropContainer->layout(),
329 332 [](VisualizationGraphWidget &graphWidget) { graphWidget.close(); });
330 333
331 334 // Delete synchronization group from variable controller
332 335 QMetaObject::invokeMethod(&sqpApp->variableController(), "onRemoveSynchronizationGroupId",
333 336 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
334 337
335 338 QWidget::closeEvent(event);
336 339 }
337 340
338 341 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
339 342 {
340 343 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
341 344 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
342 345 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
343 346 }
344 347
345 348 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable)
346 349 {
347 350 QMetaObject::invokeMethod(&sqpApp->variableController(), "desynchronize", Qt::QueuedConnection,
348 351 Q_ARG(std::shared_ptr<Variable>, variable),
349 352 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
350 353 }
351 354
352 355 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData)
353 356 {
354 auto& helper = sqpApp->dragDropHelper();
355 if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_GRAPH))
356 {
357 auto graphWidget = static_cast<VisualizationGraphWidget*>(helper.getCurrentDragWidget());
358 auto parentDragDropContainer = qobject_cast<VisualizationDragDropContainer*>(graphWidget->parentWidget());
357 auto &helper = sqpApp->dragDropHelper();
358 if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_GRAPH)) {
359 auto graphWidget = static_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
360 auto parentDragDropContainer
361 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
359 362 Q_ASSERT(parentDragDropContainer);
360 363
361 const auto& variables = graphWidget->variables();
364 const auto &variables = graphWidget->variables();
362 365
363 if (parentDragDropContainer != ui->dragDropContainer && !variables.isEmpty())
364 {
365 //The drop didn't occur in the same zone
366 if (parentDragDropContainer != ui->dragDropContainer && !variables.isEmpty()) {
367 // The drop didn't occur in the same zone
366 368
367 //Abort the requests for the variables (if any)
368 //Commented, because it's not sure if it's needed or not
369 //for (const auto& var : variables)
369 // Abort the requests for the variables (if any)
370 // Commented, because it's not sure if it's needed or not
371 // for (const auto& var : variables)
370 372 //{
371 373 // sqpApp->variableController().onAbortProgressRequested(var);
372 374 //}
373 375
374 376 auto previousParentZoneWidget = graphWidget->parentZoneWidget();
375 377 auto nbGraph = parentDragDropContainer->countDragWidget();
376 if (nbGraph == 1)
377 {
378 //This is the only graph in the previous zone, close the zone
378 if (nbGraph == 1) {
379 // This is the only graph in the previous zone, close the zone
379 380 previousParentZoneWidget->close();
380 381 }
381 else
382 {
383 //Close the graph
382 else {
383 // Close the graph
384 384 graphWidget->close();
385 385 }
386 386
387 //Creates the new graph in the zone
387 // Creates the new graph in the zone
388 388 createGraph(variables, index);
389 389 }
390 else
391 {
392 //The drop occurred in the same zone or the graph is empty
393 //Simple move of the graph, no variable operation associated
390 else {
391 // The drop occurred in the same zone or the graph is empty
392 // Simple move of the graph, no variable operation associated
394 393 parentDragDropContainer->layout()->removeWidget(graphWidget);
395 394
396 if (variables.isEmpty() && parentDragDropContainer != ui->dragDropContainer)
397 {
395 if (variables.isEmpty() && parentDragDropContainer != ui->dragDropContainer) {
398 396 // The graph is empty and dropped in a different zone.
399 397 // Take the range of the first graph in the zone (if existing).
400 398 auto layout = ui->dragDropContainer->layout();
401 if (layout->count() > 0)
402 {
403 if (auto visualizationGraphWidget = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget()))
404 {
399 if (layout->count() > 0) {
400 if (auto visualizationGraphWidget
401 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
405 402 graphWidget->setGraphRange(visualizationGraphWidget->graphRange());
406 403 }
407 404 }
408 405 }
409 406
410 407 ui->dragDropContainer->insertDragWidget(index, graphWidget);
411 408 }
412 409 }
413 410 }
General Comments 0
You need to be logged in to leave comments. Login now