##// END OF EJS Templates
Time Zone Mode + prepare graph mode
trabillard -
r1138:f7fe3621eadc
parent child
Show More
@@ -1,37 +1,40
1 #ifndef SCIQLOP_CATALOGUEEVENTSWIDGET_H
1 #ifndef SCIQLOP_CATALOGUEEVENTSWIDGET_H
2 #define SCIQLOP_CATALOGUEEVENTSWIDGET_H
2 #define SCIQLOP_CATALOGUEEVENTSWIDGET_H
3
3
4 #include <Common/spimpl.h>
4 #include <Common/spimpl.h>
5 #include <QLoggingCategory>
5 #include <QWidget>
6 #include <QWidget>
6
7
7 class DBCatalogue;
8 class DBCatalogue;
8 class DBEvent;
9 class DBEvent;
9 class VisualizationWidget;
10 class VisualizationWidget;
10
11
11 namespace Ui {
12 namespace Ui {
12 class CatalogueEventsWidget;
13 class CatalogueEventsWidget;
13 }
14 }
14
15
16 Q_DECLARE_LOGGING_CATEGORY(LOG_CatalogueEventsWidget)
17
15 class CatalogueEventsWidget : public QWidget {
18 class CatalogueEventsWidget : public QWidget {
16 Q_OBJECT
19 Q_OBJECT
17
20
18 signals:
21 signals:
19 void eventsSelected(const QVector<DBEvent> &event);
22 void eventsSelected(const QVector<DBEvent> &event);
20
23
21 public:
24 public:
22 explicit CatalogueEventsWidget(QWidget *parent = 0);
25 explicit CatalogueEventsWidget(QWidget *parent = 0);
23 virtual ~CatalogueEventsWidget();
26 virtual ~CatalogueEventsWidget();
24
27
25 void setVisualizationWidget(VisualizationWidget *visualization);
28 void setVisualizationWidget(VisualizationWidget *visualization);
26
29
27 public slots:
30 public slots:
28 void populateWithCatalogues(const QVector<DBCatalogue> &catalogues);
31 void populateWithCatalogues(const QVector<DBCatalogue> &catalogues);
29
32
30 private:
33 private:
31 Ui::CatalogueEventsWidget *ui;
34 Ui::CatalogueEventsWidget *ui;
32
35
33 class CatalogueEventsWidgetPrivate;
36 class CatalogueEventsWidgetPrivate;
34 spimpl::unique_impl_ptr<CatalogueEventsWidgetPrivate> impl;
37 spimpl::unique_impl_ptr<CatalogueEventsWidgetPrivate> impl;
35 };
38 };
36
39
37 #endif // SCIQLOP_CATALOGUEEVENTSWIDGET_H
40 #endif // SCIQLOP_CATALOGUEEVENTSWIDGET_H
@@ -1,84 +1,88
1 #ifndef SCIQLOP_VISUALIZATIONTABWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONTABWIDGET_H
2 #define SCIQLOP_VISUALIZATIONTABWIDGET_H
2 #define SCIQLOP_VISUALIZATIONTABWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
4 #include "Visualization/IVisualizationWidget.h"
5
5
6 #include <Common/spimpl.h>
6 #include <Common/spimpl.h>
7
7
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9 #include <QMimeData>
9 #include <QMimeData>
10 #include <QWidget>
10 #include <QWidget>
11
11
12 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationTabWidget)
12 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationTabWidget)
13
13
14 class Variable;
14 class Variable;
15 class VisualizationZoneWidget;
15 class VisualizationZoneWidget;
16
16
17 namespace Ui {
17 namespace Ui {
18 class VisualizationTabWidget;
18 class VisualizationTabWidget;
19 } // namespace Ui
19 } // namespace Ui
20
20
21 class VisualizationTabWidget : public QWidget, public IVisualizationWidget {
21 class VisualizationTabWidget : public QWidget, public IVisualizationWidget {
22 Q_OBJECT
22 Q_OBJECT
23
23
24 public:
24 public:
25 explicit VisualizationTabWidget(const QString &name = {}, QWidget *parent = 0);
25 explicit VisualizationTabWidget(const QString &name = {}, QWidget *parent = 0);
26 virtual ~VisualizationTabWidget();
26 virtual ~VisualizationTabWidget();
27
27
28 /// Adds a zone widget
28 /// Adds a zone widget
29 void addZone(VisualizationZoneWidget *zoneWidget);
29 void addZone(VisualizationZoneWidget *zoneWidget);
30
30
31 /// Inserts a zone widget at the specified position
31 /// Inserts a zone widget at the specified position
32 void insertZone(int index, VisualizationZoneWidget *zoneWidget);
32 void insertZone(int index, VisualizationZoneWidget *zoneWidget);
33
33
34 /// Returns the list of zone widget names in the order they are displayed
34 /// Returns the list of zone widget names in the order they are displayed
35 QStringList availableZoneWidgets() const;
35 QStringList availableZoneWidgets() const;
36
36
37 /// Returns the zone with the specified name.
38 /// If multiple zone with the same name exist, the first one is returned.
39 VisualizationZoneWidget *getZoneWithName(const QString &zoneName);
40
37 /**
41 /**
38 * Creates a zone using a variable. The variable will be displayed in a new graph of the new
42 * Creates a zone using a variable. The variable will be displayed in a new graph of the new
39 * zone. The zone is added at the end.
43 * zone. The zone is added at the end.
40 * @param variable the variable for which to create the zone
44 * @param variable the variable for which to create the zone
41 * @return the pointer to the created zone
45 * @return the pointer to the created zone
42 */
46 */
43 VisualizationZoneWidget *createZone(std::shared_ptr<Variable> variable);
47 VisualizationZoneWidget *createZone(std::shared_ptr<Variable> variable);
44
48
45 /**
49 /**
46 * Creates a zone using a list of variables. The variables will be displayed in a new graph of
50 * Creates a zone using a list of variables. The variables will be displayed in a new graph of
47 * the new zone. The zone is inserted at the specified index.
51 * the new zone. The zone is inserted at the specified index.
48 * @param variables the variables for which to create the zone
52 * @param variables the variables for which to create the zone
49 * @param index The index where the zone should be inserted in the layout
53 * @param index The index where the zone should be inserted in the layout
50 * @return the pointer to the created zone
54 * @return the pointer to the created zone
51 */
55 */
52 VisualizationZoneWidget *createZone(const QList<std::shared_ptr<Variable> > &variables,
56 VisualizationZoneWidget *createZone(const QList<std::shared_ptr<Variable> > &variables,
53 int index);
57 int index);
54
58
55 /**
59 /**
56 * Creates a zone which is empty (no variables). The zone is inserted at the specified index.
60 * Creates a zone which is empty (no variables). The zone is inserted at the specified index.
57 * @param index The index where the zone should be inserted in the layout
61 * @param index The index where the zone should be inserted in the layout
58 * @return the pointer to the created zone
62 * @return the pointer to the created zone
59 */
63 */
60 VisualizationZoneWidget *createEmptyZone(int index);
64 VisualizationZoneWidget *createEmptyZone(int index);
61
65
62 // IVisualizationWidget interface
66 // IVisualizationWidget interface
63 void accept(IVisualizationWidgetVisitor *visitor) override;
67 void accept(IVisualizationWidgetVisitor *visitor) override;
64 bool canDrop(const Variable &variable) const override;
68 bool canDrop(const Variable &variable) const override;
65 bool contains(const Variable &variable) const override;
69 bool contains(const Variable &variable) const override;
66 QString name() const override;
70 QString name() const override;
67
71
68 protected:
72 protected:
69 void closeEvent(QCloseEvent *event) override;
73 void closeEvent(QCloseEvent *event) override;
70
74
71 private:
75 private:
72 /// @return the layout of tab in which zones are added
76 /// @return the layout of tab in which zones are added
73 QLayout &tabLayout() const noexcept;
77 QLayout &tabLayout() const noexcept;
74
78
75 Ui::VisualizationTabWidget *ui;
79 Ui::VisualizationTabWidget *ui;
76
80
77 class VisualizationTabWidgetPrivate;
81 class VisualizationTabWidgetPrivate;
78 spimpl::unique_impl_ptr<VisualizationTabWidgetPrivate> impl;
82 spimpl::unique_impl_ptr<VisualizationTabWidgetPrivate> impl;
79
83
80 private slots:
84 private slots:
81 void dropMimeData(int index, const QMimeData *mimeData);
85 void dropMimeData(int index, const QMimeData *mimeData);
82 };
86 };
83
87
84 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
88 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
@@ -1,98 +1,103
1 #ifndef SCIQLOP_VISUALIZATIONZONEWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONZONEWIDGET_H
2 #define SCIQLOP_VISUALIZATIONZONEWIDGET_H
2 #define SCIQLOP_VISUALIZATIONZONEWIDGET_H
3
3
4 #include "Data/SqpRange.h"
4 #include "Visualization/IVisualizationWidget.h"
5 #include "Visualization/IVisualizationWidget.h"
5 #include "Visualization/VisualizationDragWidget.h"
6 #include "Visualization/VisualizationDragWidget.h"
6
7
7 #include <QLoggingCategory>
8 #include <QLoggingCategory>
8 #include <QWidget>
9 #include <QWidget>
9
10
10 #include <memory>
11 #include <memory>
11
12
12 #include <Common/spimpl.h>
13 #include <Common/spimpl.h>
13
14
14 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationZoneWidget)
15 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationZoneWidget)
15
16
16 namespace Ui {
17 namespace Ui {
17 class VisualizationZoneWidget;
18 class VisualizationZoneWidget;
18 } // namespace Ui
19 } // namespace Ui
19
20
20 class Variable;
21 class Variable;
21 class VisualizationGraphWidget;
22 class VisualizationGraphWidget;
22
23
23 class VisualizationZoneWidget : public VisualizationDragWidget, public IVisualizationWidget {
24 class VisualizationZoneWidget : public VisualizationDragWidget, public IVisualizationWidget {
24 Q_OBJECT
25 Q_OBJECT
25
26
26 public:
27 public:
27 explicit VisualizationZoneWidget(const QString &name = {}, QWidget *parent = 0);
28 explicit VisualizationZoneWidget(const QString &name = {}, QWidget *parent = 0);
28 virtual ~VisualizationZoneWidget();
29 virtual ~VisualizationZoneWidget();
29
30
31 /// Sets the range of the zone, only works if there is at least one graph in the zone
32 /// Note: calibrations between graphs are lost.
33 void setZoneRange(const SqpRange &range);
34
30 /// Adds a graph widget
35 /// Adds a graph widget
31 void addGraph(VisualizationGraphWidget *graphWidget);
36 void addGraph(VisualizationGraphWidget *graphWidget);
32
37
33 /// Inserts a graph widget
38 /// Inserts a graph widget
34 void insertGraph(int index, VisualizationGraphWidget *graphWidget);
39 void insertGraph(int index, VisualizationGraphWidget *graphWidget);
35
40
36 /**
41 /**
37 * Creates a graph using a variable. The variable will be displayed in the new graph.
42 * Creates a graph using a variable. The variable will be displayed in the new graph.
38 * The graph is added at the end.
43 * The graph is added at the end.
39 * @param variable the variable for which to create the graph
44 * @param variable the variable for which to create the graph
40 * @return the pointer to the created graph
45 * @return the pointer to the created graph
41 */
46 */
42 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable);
47 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable);
43
48
44 /**
49 /**
45 * Creates a graph using a variable. The variable will be displayed in the new graph.
50 * Creates a graph using a variable. The variable will be displayed in the new graph.
46 * The graph is inserted at the specified index.
51 * The graph is inserted at the specified index.
47 * @param variable the variable for which to create the graph
52 * @param variable the variable for which to create the graph
48 * @param index The index where the graph should be inserted in the layout
53 * @param index The index where the graph should be inserted in the layout
49 * @return the pointer to the created graph
54 * @return the pointer to the created graph
50 */
55 */
51 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable, int index);
56 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable, int index);
52
57
53 /**
58 /**
54 * Creates a graph using a list of variables. The variables will be displayed in the new graph.
59 * Creates a graph using a list of variables. The variables will be displayed in the new graph.
55 * The graph is inserted at the specified index.
60 * The graph is inserted at the specified index.
56 * @param variables List of variables to be added to the graph
61 * @param variables List of variables to be added to the graph
57 * @param index The index where the graph should be inserted in the layout
62 * @param index The index where the graph should be inserted in the layout
58 * @return the pointer to the created graph
63 * @return the pointer to the created graph
59 */
64 */
60 VisualizationGraphWidget *createGraph(const QList<std::shared_ptr<Variable> > variables,
65 VisualizationGraphWidget *createGraph(const QList<std::shared_ptr<Variable> > variables,
61 int index);
66 int index);
62
67
63 /// Returns the first graph in the zone or nullptr if there is no graph inside
68 /// Returns the first graph in the zone or nullptr if there is no graph inside
64 VisualizationGraphWidget *firstGraph() const;
69 VisualizationGraphWidget *firstGraph() const;
65
70
66 // IVisualizationWidget interface
71 // IVisualizationWidget interface
67 void accept(IVisualizationWidgetVisitor *visitor) override;
72 void accept(IVisualizationWidgetVisitor *visitor) override;
68 bool canDrop(const Variable &variable) const override;
73 bool canDrop(const Variable &variable) const override;
69 bool contains(const Variable &variable) const override;
74 bool contains(const Variable &variable) const override;
70 QString name() const override;
75 QString name() const override;
71
76
72 // VisualisationDragWidget
77 // VisualisationDragWidget
73 QMimeData *mimeData(const QPoint &position) const override;
78 QMimeData *mimeData(const QPoint &position) const override;
74 bool isDragAllowed() const override;
79 bool isDragAllowed() const override;
75
80
76 void notifyMouseMoveInGraph(const QPointF &graphPosition, const QPointF &plotPosition,
81 void notifyMouseMoveInGraph(const QPointF &graphPosition, const QPointF &plotPosition,
77 VisualizationGraphWidget *graphWidget);
82 VisualizationGraphWidget *graphWidget);
78 void notifyMouseLeaveGraph(VisualizationGraphWidget *graphWidget);
83 void notifyMouseLeaveGraph(VisualizationGraphWidget *graphWidget);
79
84
80 protected:
85 protected:
81 void closeEvent(QCloseEvent *event) override;
86 void closeEvent(QCloseEvent *event) override;
82
87
83 private:
88 private:
84 Ui::VisualizationZoneWidget *ui;
89 Ui::VisualizationZoneWidget *ui;
85
90
86 class VisualizationZoneWidgetPrivate;
91 class VisualizationZoneWidgetPrivate;
87 spimpl::unique_impl_ptr<VisualizationZoneWidgetPrivate> impl;
92 spimpl::unique_impl_ptr<VisualizationZoneWidgetPrivate> impl;
88
93
89 private slots:
94 private slots:
90 void onVariableAdded(std::shared_ptr<Variable> variable);
95 void onVariableAdded(std::shared_ptr<Variable> variable);
91 /// Slot called when a variable is about to be removed from a graph contained in the zone
96 /// Slot called when a variable is about to be removed from a graph contained in the zone
92 void onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable);
97 void onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable);
93
98
94 void dropMimeData(int index, const QMimeData *mimeData);
99 void dropMimeData(int index, const QMimeData *mimeData);
95 void dropMimeDataOnGraph(VisualizationDragWidget *dragWidget, const QMimeData *mimeData);
100 void dropMimeDataOnGraph(VisualizationDragWidget *dragWidget, const QMimeData *mimeData);
96 };
101 };
97
102
98 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
103 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
@@ -1,218 +1,292
1 #include "Catalogue/CatalogueEventsWidget.h"
1 #include "Catalogue/CatalogueEventsWidget.h"
2 #include "ui_CatalogueEventsWidget.h"
2 #include "ui_CatalogueEventsWidget.h"
3
3
4 #include <Catalogue/CatalogueController.h>
4 #include <Catalogue/CatalogueController.h>
5 #include <Catalogue/CatalogueEventsTableModel.h>
5 #include <Catalogue/CatalogueEventsTableModel.h>
6 #include <CatalogueDao.h>
6 #include <CatalogueDao.h>
7 #include <DBCatalogue.h>
7 #include <DBCatalogue.h>
8 #include <SqpApplication.h>
8 #include <SqpApplication.h>
9 #include <Visualization/VisualizationTabWidget.h>
9 #include <Visualization/VisualizationTabWidget.h>
10 #include <Visualization/VisualizationWidget.h>
10 #include <Visualization/VisualizationWidget.h>
11 #include <Visualization/VisualizationZoneWidget.h>
11
12
12 #include <QDialog>
13 #include <QDialog>
13 #include <QDialogButtonBox>
14 #include <QDialogButtonBox>
14 #include <QListWidget>
15 #include <QListWidget>
15
16
17 Q_LOGGING_CATEGORY(LOG_CatalogueEventsWidget, "CatalogueEventsWidget")
16
18
17 /// Format of the dates appearing in the label of a cursor
19 /// Format of the dates appearing in the label of a cursor
18 const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss");
20 const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss");
19
21
20 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate {
22 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate {
21
23
22 CatalogueEventsTableModel *m_Model = nullptr;
24 CatalogueEventsTableModel *m_Model = nullptr;
23 QString m_ZoneForTimeMode;
25 QStringList m_ZonesForTimeMode;
24 QString m_ZoneForGraphMode;
26 QString m_ZoneForGraphMode;
25
27
26 VisualizationWidget *m_VisualizationWidget = nullptr;
28 VisualizationWidget *m_VisualizationWidget = nullptr;
27
29
28 void setEvents(const QVector<DBEvent> &events, QTableView *tableView)
30 void setEvents(const QVector<DBEvent> &events, QTableView *tableView)
29 {
31 {
30 tableView->setSortingEnabled(false);
32 tableView->setSortingEnabled(false);
31 m_Model->setEvents(events);
33 m_Model->setEvents(events);
32 tableView->setSortingEnabled(true);
34 tableView->setSortingEnabled(true);
33 }
35 }
34
36
35 void addEvent(const DBEvent &event, QTableView *tableView)
37 void addEvent(const DBEvent &event, QTableView *tableView)
36 {
38 {
37 tableView->setSortingEnabled(false);
39 tableView->setSortingEnabled(false);
38 m_Model->addEvent(event);
40 m_Model->addEvent(event);
39 tableView->setSortingEnabled(true);
41 tableView->setSortingEnabled(true);
40 }
42 }
41
43
42 void removeEvent(const DBEvent &event, QTableView *tableView)
44 void removeEvent(const DBEvent &event, QTableView *tableView)
43 {
45 {
44 tableView->setSortingEnabled(false);
46 tableView->setSortingEnabled(false);
45 m_Model->removeEvent(event);
47 m_Model->removeEvent(event);
46 tableView->setSortingEnabled(true);
48 tableView->setSortingEnabled(true);
47 }
49 }
48
50
49 QStringList getAvailableVisualizationZoneList() const
51 QStringList getAvailableVisualizationZoneList() const
50 {
52 {
51 if (m_VisualizationWidget) {
53 if (m_VisualizationWidget) {
52 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
54 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
53 return tab->availableZoneWidgets();
55 return tab->availableZoneWidgets();
54 }
56 }
55 }
57 }
56
58
57 return QStringList{};
59 return QStringList{};
58 }
60 }
59
61
60 QStringList selectZone(QWidget *parent, const QStringList &selectedZones,
62 QStringList selectZone(QWidget *parent, const QStringList &selectedZones,
61 bool allowMultiSelection, const QPoint &location)
63 bool allowMultiSelection, const QPoint &location)
62 {
64 {
63 auto availableZones = getAvailableVisualizationZoneList();
65 auto availableZones = getAvailableVisualizationZoneList();
64 if (availableZones.isEmpty()) {
66 if (availableZones.isEmpty()) {
65 return QStringList{};
67 return QStringList{};
66 }
68 }
67
69
68 QDialog d(parent, Qt::Tool);
70 QDialog d(parent, Qt::Tool);
69 d.setWindowTitle("Choose a zone");
71 d.setWindowTitle("Choose a zone");
70 auto layout = new QVBoxLayout{&d};
72 auto layout = new QVBoxLayout{&d};
71 layout->setContentsMargins(0, 0, 0, 0);
73 layout->setContentsMargins(0, 0, 0, 0);
72 auto listWidget = new QListWidget{&d};
74 auto listWidget = new QListWidget{&d};
73 layout->addWidget(listWidget);
75 layout->addWidget(listWidget);
74
76
75 QSet<QListWidgetItem *> checkedItems;
77 QSet<QListWidgetItem *> checkedItems;
76 for (auto zone : availableZones) {
78 for (auto zone : availableZones) {
77 auto item = new QListWidgetItem{zone};
79 auto item = new QListWidgetItem{zone};
78 item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
80 item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
79 if (selectedZones.contains(zone)) {
81 if (selectedZones.contains(zone)) {
80 item->setCheckState(Qt::Checked);
82 item->setCheckState(Qt::Checked);
81 checkedItems << item;
83 checkedItems << item;
82 }
84 }
83 else {
85 else {
84 item->setCheckState(Qt::Unchecked);
86 item->setCheckState(Qt::Unchecked);
85 }
87 }
86
88
87 listWidget->addItem(item);
89 listWidget->addItem(item);
88 }
90 }
89
91
90 auto buttonBox = new QDialogButtonBox{QDialogButtonBox::Ok, &d};
92 auto buttonBox = new QDialogButtonBox{QDialogButtonBox::Ok, &d};
91 layout->addWidget(buttonBox);
93 layout->addWidget(buttonBox);
92
94
93 QObject::connect(buttonBox, &QDialogButtonBox::accepted, &d, &QDialog::accept);
95 QObject::connect(buttonBox, &QDialogButtonBox::accepted, &d, &QDialog::accept);
94 QObject::connect(buttonBox, &QDialogButtonBox::rejected, &d, &QDialog::reject);
96 QObject::connect(buttonBox, &QDialogButtonBox::rejected, &d, &QDialog::reject);
95
97
96 QObject::connect(listWidget, &QListWidget::itemChanged,
98 QObject::connect(listWidget, &QListWidget::itemChanged,
97 [&checkedItems, allowMultiSelection, listWidget](auto item) {
99 [&checkedItems, allowMultiSelection, listWidget](auto item) {
98 if (item->checkState() == Qt::Checked) {
100 if (item->checkState() == Qt::Checked) {
99 if (!allowMultiSelection) {
101 if (!allowMultiSelection) {
100 for (auto checkedItem : checkedItems) {
102 for (auto checkedItem : checkedItems) {
101 listWidget->blockSignals(true);
103 listWidget->blockSignals(true);
102 checkedItem->setCheckState(Qt::Unchecked);
104 checkedItem->setCheckState(Qt::Unchecked);
103 listWidget->blockSignals(false);
105 listWidget->blockSignals(false);
104 }
106 }
105
107
106 checkedItems.clear();
108 checkedItems.clear();
107 }
109 }
108 checkedItems << item;
110 checkedItems << item;
109 }
111 }
110 else {
112 else {
111 checkedItems.remove(item);
113 checkedItems.remove(item);
112 }
114 }
113 });
115 });
114
116
115 QStringList result;
117 QStringList result;
116
118
117 d.setMinimumWidth(120);
119 d.setMinimumWidth(120);
118 d.resize(d.minimumSizeHint());
120 d.resize(d.minimumSizeHint());
119 d.move(location);
121 d.move(location);
120 if (d.exec() == QDialog::Accepted) {
122 if (d.exec() == QDialog::Accepted) {
121 for (auto item : checkedItems) {
123 for (auto item : checkedItems) {
122 result += item->text();
124 result += item->text();
123 }
125 }
124 }
126 }
125 else {
127 else {
126 result = selectedZones;
128 result = selectedZones;
127 }
129 }
128
130
129 return result;
131 return result;
130 }
132 }
133
134 void updateForTimeMode(QTableView *tableView)
135 {
136 auto selectedRows = tableView->selectionModel()->selectedRows();
137
138 if (selectedRows.count() == 1) {
139 auto event = m_Model->getEvent(selectedRows.first().row());
140 if (m_VisualizationWidget) {
141 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
142
143 for (auto zoneName : m_ZonesForTimeMode) {
144 if (auto zone = tab->getZoneWithName(zoneName)) {
145 SqpRange eventRange;
146 eventRange.m_TStart = event.getTStart();
147 eventRange.m_TEnd = event.getTEnd();
148 zone->setZoneRange(eventRange);
149 }
150 }
151 }
152 else {
153 qCWarning(LOG_CatalogueEventsWidget())
154 << "updateTimeZone: no tab found in the visualization";
155 }
156 }
157 else {
158 qCWarning(LOG_CatalogueEventsWidget())
159 << "updateTimeZone: visualization widget not found";
160 }
161 }
162 else {
163 qCWarning(LOG_CatalogueEventsWidget())
164 << "updateTimeZone: not compatible with multiple events selected";
165 }
166 }
167
168 void updateForGraphMode(QTableView *tableView)
169 {
170 auto selectedRows = tableView->selectionModel()->selectedRows();
171
172 if (selectedRows.count() == 1) {
173 auto event = m_Model->getEvent(selectedRows.first().row());
174 if (m_VisualizationWidget) {
175 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
176 if (auto zone = tab->getZoneWithName(m_ZoneForGraphMode)) {
177 // TODO
178 }
179 }
180 else {
181 qCWarning(LOG_CatalogueEventsWidget())
182 << "updateGraphMode: no tab found in the visualization";
183 }
184 }
185 else {
186 qCWarning(LOG_CatalogueEventsWidget())
187 << "updateGraphMode: visualization widget not found";
188 }
189 }
190 else {
191 qCWarning(LOG_CatalogueEventsWidget())
192 << "updateGraphMode: not compatible with multiple events selected";
193 }
194 }
131 };
195 };
132
196
133 CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent)
197 CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent)
134 : QWidget(parent),
198 : QWidget(parent),
135 ui(new Ui::CatalogueEventsWidget),
199 ui(new Ui::CatalogueEventsWidget),
136 impl{spimpl::make_unique_impl<CatalogueEventsWidgetPrivate>()}
200 impl{spimpl::make_unique_impl<CatalogueEventsWidgetPrivate>()}
137 {
201 {
138 ui->setupUi(this);
202 ui->setupUi(this);
139
203
140 impl->m_Model = new CatalogueEventsTableModel{this};
204 impl->m_Model = new CatalogueEventsTableModel{this};
141 ui->tableView->setModel(impl->m_Model);
205 ui->tableView->setModel(impl->m_Model);
142
206
143 ui->tableView->setSortingEnabled(true);
207 ui->tableView->setSortingEnabled(true);
144 ui->tableView->setDragDropMode(QAbstractItemView::DragDrop);
208 ui->tableView->setDragDropMode(QAbstractItemView::DragDrop);
145 ui->tableView->setDragEnabled(true);
209 ui->tableView->setDragEnabled(true);
146
210
147 connect(ui->btnTime, &QToolButton::clicked, [this](auto checked) {
211 connect(ui->btnTime, &QToolButton::clicked, [this](auto checked) {
148 if (checked) {
212 if (checked) {
149 ui->btnChart->setChecked(false);
213 ui->btnChart->setChecked(false);
150 impl->m_ZoneForTimeMode
214 impl->m_ZonesForTimeMode
151 = impl->selectZone(this, {impl->m_ZoneForTimeMode}, false,
215 = impl->selectZone(this, impl->m_ZonesForTimeMode, true,
152 this->mapToGlobal(ui->btnTime->frameGeometry().center()))
216 this->mapToGlobal(ui->btnTime->frameGeometry().center()));
153 .value(0);
217
218 impl->updateForTimeMode(ui->tableView);
154 }
219 }
155 });
220 });
156
221
157 connect(ui->btnChart, &QToolButton::clicked, [this](auto checked) {
222 connect(ui->btnChart, &QToolButton::clicked, [this](auto checked) {
158 if (checked) {
223 if (checked) {
159 ui->btnTime->setChecked(false);
224 ui->btnTime->setChecked(false);
160 impl->m_ZoneForGraphMode
225 impl->m_ZoneForGraphMode
161 = impl->selectZone(this, {impl->m_ZoneForGraphMode}, false,
226 = impl->selectZone(this, {impl->m_ZoneForGraphMode}, false,
162 this->mapToGlobal(ui->btnChart->frameGeometry().center()))
227 this->mapToGlobal(ui->btnChart->frameGeometry().center()))
163 .value(0);
228 .value(0);
229
230 impl->updateForGraphMode(ui->tableView);
164 }
231 }
165 });
232 });
166
233
167 auto emitSelection = [this]() {
234 auto emitSelection = [this]() {
168 QVector<DBEvent> events;
235 QVector<DBEvent> events;
169 for (auto rowIndex : ui->tableView->selectionModel()->selectedRows()) {
236 for (auto rowIndex : ui->tableView->selectionModel()->selectedRows()) {
170 events << impl->m_Model->getEvent(rowIndex.row());
237 events << impl->m_Model->getEvent(rowIndex.row());
171 }
238 }
172
239
173 emit this->eventsSelected(events);
240 emit this->eventsSelected(events);
174 };
241 };
175
242
176 connect(ui->tableView, &QTableView::clicked, emitSelection);
243 connect(ui->tableView, &QTableView::clicked, emitSelection);
177 connect(ui->tableView->selectionModel(), &QItemSelectionModel::selectionChanged, emitSelection);
244 connect(ui->tableView->selectionModel(), &QItemSelectionModel::selectionChanged, emitSelection);
178
245
179 connect(ui->tableView->selectionModel(), &QItemSelectionModel::selectionChanged, [this]() {
246 connect(ui->tableView->selectionModel(), &QItemSelectionModel::selectionChanged, [this]() {
180 auto isNotMultiSelection = ui->tableView->selectionModel()->selectedRows().count() <= 1;
247 auto isNotMultiSelection = ui->tableView->selectionModel()->selectedRows().count() <= 1;
181 ui->btnChart->setEnabled(isNotMultiSelection);
248 ui->btnChart->setEnabled(isNotMultiSelection);
182 ui->btnTime->setEnabled(isNotMultiSelection);
249 ui->btnTime->setEnabled(isNotMultiSelection);
250
251 if (isNotMultiSelection && ui->btnTime->isChecked()) {
252 impl->updateForTimeMode(ui->tableView);
253 }
254 else if (isNotMultiSelection && ui->btnChart->isChecked()) {
255 impl->updateForGraphMode(ui->tableView);
256 }
183 });
257 });
184
258
185 ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
259 ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
186 ui->tableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
260 ui->tableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
187 ui->tableView->horizontalHeader()->setSortIndicatorShown(true);
261 ui->tableView->horizontalHeader()->setSortIndicatorShown(true);
188 }
262 }
189
263
190 CatalogueEventsWidget::~CatalogueEventsWidget()
264 CatalogueEventsWidget::~CatalogueEventsWidget()
191 {
265 {
192 delete ui;
266 delete ui;
193 }
267 }
194
268
195 void CatalogueEventsWidget::setVisualizationWidget(VisualizationWidget *visualization)
269 void CatalogueEventsWidget::setVisualizationWidget(VisualizationWidget *visualization)
196 {
270 {
197 impl->m_VisualizationWidget = visualization;
271 impl->m_VisualizationWidget = visualization;
198 }
272 }
199
273
200 void CatalogueEventsWidget::populateWithCatalogues(const QVector<DBCatalogue> &catalogues)
274 void CatalogueEventsWidget::populateWithCatalogues(const QVector<DBCatalogue> &catalogues)
201 {
275 {
202 auto &dao = sqpApp->catalogueController().getDao();
276 auto &dao = sqpApp->catalogueController().getDao();
203
277
204 QSet<QUuid> eventIds;
278 QSet<QUuid> eventIds;
205 QVector<DBEvent> events;
279 QVector<DBEvent> events;
206
280
207 for (auto catalogue : catalogues) {
281 for (auto catalogue : catalogues) {
208 auto catalogueEvents = dao.getCatalogueEvents(catalogue);
282 auto catalogueEvents = dao.getCatalogueEvents(catalogue);
209 for (auto event : catalogueEvents) {
283 for (auto event : catalogueEvents) {
210 if (!eventIds.contains(event.getUniqId())) {
284 if (!eventIds.contains(event.getUniqId())) {
211 events << event;
285 events << event;
212 eventIds.insert(event.getUniqId());
286 eventIds.insert(event.getUniqId());
213 }
287 }
214 }
288 }
215 }
289 }
216
290
217 impl->setEvents(events, ui->tableView);
291 impl->setEvents(events, ui->tableView);
218 }
292 }
@@ -1,342 +1,354
1 #include "Visualization/VisualizationTabWidget.h"
1 #include "Visualization/VisualizationTabWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "ui_VisualizationTabWidget.h"
3 #include "ui_VisualizationTabWidget.h"
4
4
5 #include "Visualization/VisualizationGraphWidget.h"
5 #include "Visualization/VisualizationGraphWidget.h"
6 #include "Visualization/VisualizationZoneWidget.h"
6 #include "Visualization/VisualizationZoneWidget.h"
7
7
8 #include "Visualization/MacScrollBarStyle.h"
8 #include "Visualization/MacScrollBarStyle.h"
9
9
10 #include "Variable/VariableController.h"
10 #include "Variable/VariableController.h"
11
11
12 #include "Common/MimeTypesDef.h"
12 #include "Common/MimeTypesDef.h"
13
13
14 #include "DragAndDrop/DragDropGuiController.h"
14 #include "DragAndDrop/DragDropGuiController.h"
15 #include "SqpApplication.h"
15 #include "SqpApplication.h"
16
16
17 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
17 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
18
18
19 namespace {
19 namespace {
20
20
21 /**
21 /**
22 * Applies a function to all zones of the tab represented by its layout
22 * Applies a function to all zones of the tab represented by its layout
23 * @param layout the layout that contains zones
23 * @param layout the layout that contains zones
24 * @param fun the function to apply to each zone
24 * @param fun the function to apply to each zone
25 */
25 */
26 template <typename Fun>
26 template <typename Fun>
27 void processZones(QLayout &layout, Fun fun)
27 void processZones(QLayout &layout, Fun fun)
28 {
28 {
29 for (auto i = 0; i < layout.count(); ++i) {
29 for (auto i = 0; i < layout.count(); ++i) {
30 if (auto item = layout.itemAt(i)) {
30 if (auto item = layout.itemAt(i)) {
31 if (auto visualizationZoneWidget
31 if (auto visualizationZoneWidget
32 = qobject_cast<VisualizationZoneWidget *>(item->widget())) {
32 = qobject_cast<VisualizationZoneWidget *>(item->widget())) {
33 fun(*visualizationZoneWidget);
33 fun(*visualizationZoneWidget);
34 }
34 }
35 }
35 }
36 }
36 }
37 }
37 }
38
38
39 /// Generates a default name for a new zone, according to the number of zones already displayed in
39 /// Generates a default name for a new zone, according to the number of zones already displayed in
40 /// the tab
40 /// the tab
41 QString defaultZoneName(QLayout &layout)
41 QString defaultZoneName(QLayout &layout)
42 {
42 {
43 QSet<QString> existingNames;
43 QSet<QString> existingNames;
44 processZones(layout,
44 processZones(layout,
45 [&existingNames](auto &zoneWidget) { existingNames.insert(zoneWidget.name()); });
45 [&existingNames](auto &zoneWidget) { existingNames.insert(zoneWidget.name()); });
46
46
47 int zoneNum = 1;
47 int zoneNum = 1;
48 QString name;
48 QString name;
49 do {
49 do {
50 name = QObject::tr("Zone ").append(QString::number(zoneNum));
50 name = QObject::tr("Zone ").append(QString::number(zoneNum));
51 ++zoneNum;
51 ++zoneNum;
52 } while (existingNames.contains(name));
52 } while (existingNames.contains(name));
53
53
54 return name;
54 return name;
55 }
55 }
56
56
57 } // namespace
57 } // namespace
58
58
59 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
59 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
60 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
60 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
61
61
62 QString m_Name;
62 QString m_Name;
63
63
64 #ifdef Q_OS_MAC
64 #ifdef Q_OS_MAC
65 std::unique_ptr<MacScrollBarStyle> m_MacScrollBarStyle = std::make_unique<MacScrollBarStyle>();
65 std::unique_ptr<MacScrollBarStyle> m_MacScrollBarStyle = std::make_unique<MacScrollBarStyle>();
66 #endif
66 #endif
67
67
68 void dropGraph(int index, VisualizationTabWidget *tabWidget);
68 void dropGraph(int index, VisualizationTabWidget *tabWidget);
69 void dropZone(int index, VisualizationTabWidget *tabWidget);
69 void dropZone(int index, VisualizationTabWidget *tabWidget);
70 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
70 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
71 VisualizationTabWidget *tabWidget);
71 VisualizationTabWidget *tabWidget);
72 };
72 };
73
73
74 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
74 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
75 : QWidget{parent},
75 : QWidget{parent},
76 ui{new Ui::VisualizationTabWidget},
76 ui{new Ui::VisualizationTabWidget},
77 impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)}
77 impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)}
78 {
78 {
79 ui->setupUi(this);
79 ui->setupUi(this);
80
80
81 #ifdef Q_OS_MAC
81 #ifdef Q_OS_MAC
82 impl->m_MacScrollBarStyle->selfInstallOn(ui->scrollArea, true);
82 impl->m_MacScrollBarStyle->selfInstallOn(ui->scrollArea, true);
83 #endif
83 #endif
84
84
85 ui->dragDropContainer->setPlaceHolderType(DragDropGuiController::PlaceHolderType::Zone, "Zone");
85 ui->dragDropContainer->setPlaceHolderType(DragDropGuiController::PlaceHolderType::Zone, "Zone");
86 ui->dragDropContainer->layout()->setContentsMargins(0, 0, 0, 12);
86 ui->dragDropContainer->layout()->setContentsMargins(0, 0, 0, 12);
87 ui->dragDropContainer->layout()->setSpacing(0);
87 ui->dragDropContainer->layout()->setSpacing(0);
88 ui->dragDropContainer->setMimeType(MIME_TYPE_GRAPH,
88 ui->dragDropContainer->setMimeType(MIME_TYPE_GRAPH,
89 VisualizationDragDropContainer::DropBehavior::Inserted);
89 VisualizationDragDropContainer::DropBehavior::Inserted);
90 ui->dragDropContainer->setMimeType(MIME_TYPE_ZONE,
90 ui->dragDropContainer->setMimeType(MIME_TYPE_ZONE,
91 VisualizationDragDropContainer::DropBehavior::Inserted);
91 VisualizationDragDropContainer::DropBehavior::Inserted);
92 ui->dragDropContainer->setMimeType(MIME_TYPE_VARIABLE_LIST,
92 ui->dragDropContainer->setMimeType(MIME_TYPE_VARIABLE_LIST,
93 VisualizationDragDropContainer::DropBehavior::Inserted);
93 VisualizationDragDropContainer::DropBehavior::Inserted);
94
94
95 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
95 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
96 return sqpApp->dragDropGuiController().checkMimeDataForVisualization(mimeData,
96 return sqpApp->dragDropGuiController().checkMimeDataForVisualization(mimeData,
97 ui->dragDropContainer);
97 ui->dragDropContainer);
98 });
98 });
99
99
100 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this,
100 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this,
101 &VisualizationTabWidget::dropMimeData);
101 &VisualizationTabWidget::dropMimeData);
102
102
103 sqpApp->dragDropGuiController().addDragDropScrollArea(ui->scrollArea);
103 sqpApp->dragDropGuiController().addDragDropScrollArea(ui->scrollArea);
104
104
105 // Widget is deleted when closed
105 // Widget is deleted when closed
106 setAttribute(Qt::WA_DeleteOnClose);
106 setAttribute(Qt::WA_DeleteOnClose);
107 }
107 }
108
108
109 VisualizationTabWidget::~VisualizationTabWidget()
109 VisualizationTabWidget::~VisualizationTabWidget()
110 {
110 {
111 sqpApp->dragDropGuiController().removeDragDropScrollArea(ui->scrollArea);
111 sqpApp->dragDropGuiController().removeDragDropScrollArea(ui->scrollArea);
112 delete ui;
112 delete ui;
113 }
113 }
114
114
115 void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget)
115 void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget)
116 {
116 {
117 ui->dragDropContainer->addDragWidget(zoneWidget);
117 ui->dragDropContainer->addDragWidget(zoneWidget);
118 }
118 }
119
119
120 void VisualizationTabWidget::insertZone(int index, VisualizationZoneWidget *zoneWidget)
120 void VisualizationTabWidget::insertZone(int index, VisualizationZoneWidget *zoneWidget)
121 {
121 {
122 ui->dragDropContainer->insertDragWidget(index, zoneWidget);
122 ui->dragDropContainer->insertDragWidget(index, zoneWidget);
123 }
123 }
124
124
125 QStringList VisualizationTabWidget::availableZoneWidgets() const
125 QStringList VisualizationTabWidget::availableZoneWidgets() const
126 {
126 {
127 QStringList zones;
127 QStringList zones;
128 processZones(tabLayout(),
128 processZones(tabLayout(),
129 [&zones](VisualizationZoneWidget &zoneWidget) { zones << zoneWidget.name(); });
129 [&zones](VisualizationZoneWidget &zoneWidget) { zones << zoneWidget.name(); });
130
130
131 return zones;
131 return zones;
132 }
132 }
133
133
134 VisualizationZoneWidget *VisualizationTabWidget::getZoneWithName(const QString &zoneName)
135 {
136 VisualizationZoneWidget *result = nullptr;
137 processZones(tabLayout(), [&zoneName, &result](VisualizationZoneWidget &zoneWidget) {
138 if (!result && zoneWidget.name() == zoneName) {
139 result = &zoneWidget;
140 }
141 });
142
143 return result;
144 }
145
134 VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable)
146 VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable)
135 {
147 {
136 return createZone({variable}, -1);
148 return createZone({variable}, -1);
137 }
149 }
138
150
139 VisualizationZoneWidget *
151 VisualizationZoneWidget *
140 VisualizationTabWidget::createZone(const QList<std::shared_ptr<Variable> > &variables, int index)
152 VisualizationTabWidget::createZone(const QList<std::shared_ptr<Variable> > &variables, int index)
141 {
153 {
142 auto zoneWidget = createEmptyZone(index);
154 auto zoneWidget = createEmptyZone(index);
143
155
144 // Creates a new graph into the zone
156 // Creates a new graph into the zone
145 zoneWidget->createGraph(variables, index);
157 zoneWidget->createGraph(variables, index);
146
158
147 return zoneWidget;
159 return zoneWidget;
148 }
160 }
149
161
150 VisualizationZoneWidget *VisualizationTabWidget::createEmptyZone(int index)
162 VisualizationZoneWidget *VisualizationTabWidget::createEmptyZone(int index)
151 {
163 {
152 auto zoneWidget
164 auto zoneWidget
153 = new VisualizationZoneWidget{defaultZoneName(*ui->dragDropContainer->layout()), this};
165 = new VisualizationZoneWidget{defaultZoneName(*ui->dragDropContainer->layout()), this};
154 this->insertZone(index, zoneWidget);
166 this->insertZone(index, zoneWidget);
155
167
156 return zoneWidget;
168 return zoneWidget;
157 }
169 }
158
170
159 void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor)
171 void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor)
160 {
172 {
161 if (visitor) {
173 if (visitor) {
162 visitor->visitEnter(this);
174 visitor->visitEnter(this);
163
175
164 // Apply visitor to zone children: widgets different from zones are not visited (no action)
176 // Apply visitor to zone children: widgets different from zones are not visited (no action)
165 processZones(tabLayout(), [visitor](VisualizationZoneWidget &zoneWidget) {
177 processZones(tabLayout(), [visitor](VisualizationZoneWidget &zoneWidget) {
166 zoneWidget.accept(visitor);
178 zoneWidget.accept(visitor);
167 });
179 });
168
180
169 visitor->visitLeave(this);
181 visitor->visitLeave(this);
170 }
182 }
171 else {
183 else {
172 qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null");
184 qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null");
173 }
185 }
174 }
186 }
175
187
176 bool VisualizationTabWidget::canDrop(const Variable &variable) const
188 bool VisualizationTabWidget::canDrop(const Variable &variable) const
177 {
189 {
178 // A tab can always accomodate a variable
190 // A tab can always accomodate a variable
179 Q_UNUSED(variable);
191 Q_UNUSED(variable);
180 return true;
192 return true;
181 }
193 }
182
194
183 bool VisualizationTabWidget::contains(const Variable &variable) const
195 bool VisualizationTabWidget::contains(const Variable &variable) const
184 {
196 {
185 Q_UNUSED(variable);
197 Q_UNUSED(variable);
186 return false;
198 return false;
187 }
199 }
188
200
189 QString VisualizationTabWidget::name() const
201 QString VisualizationTabWidget::name() const
190 {
202 {
191 return impl->m_Name;
203 return impl->m_Name;
192 }
204 }
193
205
194 void VisualizationTabWidget::closeEvent(QCloseEvent *event)
206 void VisualizationTabWidget::closeEvent(QCloseEvent *event)
195 {
207 {
196 // Closes zones in the tab
208 // Closes zones in the tab
197 processZones(tabLayout(), [](VisualizationZoneWidget &zoneWidget) { zoneWidget.close(); });
209 processZones(tabLayout(), [](VisualizationZoneWidget &zoneWidget) { zoneWidget.close(); });
198
210
199 QWidget::closeEvent(event);
211 QWidget::closeEvent(event);
200 }
212 }
201
213
202 QLayout &VisualizationTabWidget::tabLayout() const noexcept
214 QLayout &VisualizationTabWidget::tabLayout() const noexcept
203 {
215 {
204 return *ui->dragDropContainer->layout();
216 return *ui->dragDropContainer->layout();
205 }
217 }
206
218
207 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData)
219 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData)
208 {
220 {
209 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
221 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
210 impl->dropGraph(index, this);
222 impl->dropGraph(index, this);
211 }
223 }
212 else if (mimeData->hasFormat(MIME_TYPE_ZONE)) {
224 else if (mimeData->hasFormat(MIME_TYPE_ZONE)) {
213 impl->dropZone(index, this);
225 impl->dropZone(index, this);
214 }
226 }
215 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
227 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
216 auto variables = sqpApp->variableController().variablesForMimeData(
228 auto variables = sqpApp->variableController().variablesForMimeData(
217 mimeData->data(MIME_TYPE_VARIABLE_LIST));
229 mimeData->data(MIME_TYPE_VARIABLE_LIST));
218 impl->dropVariables(variables, index, this);
230 impl->dropVariables(variables, index, this);
219 }
231 }
220 else {
232 else {
221 qCWarning(LOG_VisualizationZoneWidget())
233 qCWarning(LOG_VisualizationZoneWidget())
222 << tr("VisualizationTabWidget::dropMimeData, unknown MIME data received.");
234 << tr("VisualizationTabWidget::dropMimeData, unknown MIME data received.");
223 }
235 }
224 }
236 }
225
237
226 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph(
238 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph(
227 int index, VisualizationTabWidget *tabWidget)
239 int index, VisualizationTabWidget *tabWidget)
228 {
240 {
229 auto &helper = sqpApp->dragDropGuiController();
241 auto &helper = sqpApp->dragDropGuiController();
230
242
231 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
243 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
232 if (!graphWidget) {
244 if (!graphWidget) {
233 qCWarning(LOG_VisualizationZoneWidget())
245 qCWarning(LOG_VisualizationZoneWidget())
234 << tr("VisualizationTabWidget::dropGraph, drop aborted, the dropped graph is not "
246 << tr("VisualizationTabWidget::dropGraph, drop aborted, the dropped graph is not "
235 "found or invalid.");
247 "found or invalid.");
236 Q_ASSERT(false);
248 Q_ASSERT(false);
237 return;
249 return;
238 }
250 }
239
251
240 auto parentDragDropContainer
252 auto parentDragDropContainer
241 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
253 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
242 if (!parentDragDropContainer) {
254 if (!parentDragDropContainer) {
243 qCWarning(LOG_VisualizationZoneWidget())
255 qCWarning(LOG_VisualizationZoneWidget())
244 << tr("VisualizationTabWidget::dropGraph, drop aborted, the parent container of "
256 << tr("VisualizationTabWidget::dropGraph, drop aborted, the parent container of "
245 "the dropped graph is not found.");
257 "the dropped graph is not found.");
246 Q_ASSERT(false);
258 Q_ASSERT(false);
247 return;
259 return;
248 }
260 }
249
261
250 auto nbGraph = parentDragDropContainer->countDragWidget();
262 auto nbGraph = parentDragDropContainer->countDragWidget();
251
263
252 const auto &variables = graphWidget->variables();
264 const auto &variables = graphWidget->variables();
253
265
254 if (!variables.isEmpty()) {
266 if (!variables.isEmpty()) {
255 // Abort the requests for the variables (if any)
267 // Abort the requests for the variables (if any)
256 // Commented, because it's not sure if it's needed or not
268 // Commented, because it's not sure if it's needed or not
257 // for (const auto& var : variables)
269 // for (const auto& var : variables)
258 //{
270 //{
259 // sqpApp->variableController().onAbortProgressRequested(var);
271 // sqpApp->variableController().onAbortProgressRequested(var);
260 //}
272 //}
261
273
262 if (nbGraph == 1) {
274 if (nbGraph == 1) {
263 // This is the only graph in the previous zone, close the zone
275 // This is the only graph in the previous zone, close the zone
264 helper.delayedCloseWidget(graphWidget->parentZoneWidget());
276 helper.delayedCloseWidget(graphWidget->parentZoneWidget());
265 }
277 }
266 else {
278 else {
267 // Close the graph
279 // Close the graph
268 helper.delayedCloseWidget(graphWidget);
280 helper.delayedCloseWidget(graphWidget);
269 }
281 }
270
282
271 auto zoneWidget = tabWidget->createZone(variables, index);
283 auto zoneWidget = tabWidget->createZone(variables, index);
272 auto firstGraph = zoneWidget->firstGraph();
284 auto firstGraph = zoneWidget->firstGraph();
273 if (firstGraph) {
285 if (firstGraph) {
274 firstGraph->addSelectionZones(graphWidget->selectionZoneRanges());
286 firstGraph->addSelectionZones(graphWidget->selectionZoneRanges());
275 }
287 }
276 else {
288 else {
277 qCWarning(LOG_VisualizationZoneWidget())
289 qCWarning(LOG_VisualizationZoneWidget())
278 << tr("VisualizationTabWidget::dropGraph, no graph added in the widget.");
290 << tr("VisualizationTabWidget::dropGraph, no graph added in the widget.");
279 Q_ASSERT(false);
291 Q_ASSERT(false);
280 }
292 }
281 }
293 }
282 else {
294 else {
283 // The graph is empty, create an empty zone and move the graph inside
295 // The graph is empty, create an empty zone and move the graph inside
284
296
285 auto parentZoneWidget = graphWidget->parentZoneWidget();
297 auto parentZoneWidget = graphWidget->parentZoneWidget();
286
298
287 parentDragDropContainer->layout()->removeWidget(graphWidget);
299 parentDragDropContainer->layout()->removeWidget(graphWidget);
288
300
289 auto zoneWidget = tabWidget->createEmptyZone(index);
301 auto zoneWidget = tabWidget->createEmptyZone(index);
290 zoneWidget->addGraph(graphWidget);
302 zoneWidget->addGraph(graphWidget);
291
303
292 // Close the old zone if it was the only graph inside
304 // Close the old zone if it was the only graph inside
293 if (nbGraph == 1) {
305 if (nbGraph == 1) {
294 helper.delayedCloseWidget(parentZoneWidget);
306 helper.delayedCloseWidget(parentZoneWidget);
295 }
307 }
296 }
308 }
297 }
309 }
298
310
299 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropZone(
311 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropZone(
300 int index, VisualizationTabWidget *tabWidget)
312 int index, VisualizationTabWidget *tabWidget)
301 {
313 {
302 auto &helper = sqpApp->dragDropGuiController();
314 auto &helper = sqpApp->dragDropGuiController();
303
315
304 auto zoneWidget = qobject_cast<VisualizationZoneWidget *>(helper.getCurrentDragWidget());
316 auto zoneWidget = qobject_cast<VisualizationZoneWidget *>(helper.getCurrentDragWidget());
305 if (!zoneWidget) {
317 if (!zoneWidget) {
306 qCWarning(LOG_VisualizationZoneWidget())
318 qCWarning(LOG_VisualizationZoneWidget())
307 << tr("VisualizationTabWidget::dropZone, drop aborted, the dropped zone is not "
319 << tr("VisualizationTabWidget::dropZone, drop aborted, the dropped zone is not "
308 "found or invalid.");
320 "found or invalid.");
309 Q_ASSERT(false);
321 Q_ASSERT(false);
310 return;
322 return;
311 }
323 }
312
324
313 auto parentDragDropContainer
325 auto parentDragDropContainer
314 = qobject_cast<VisualizationDragDropContainer *>(zoneWidget->parentWidget());
326 = qobject_cast<VisualizationDragDropContainer *>(zoneWidget->parentWidget());
315 if (!parentDragDropContainer) {
327 if (!parentDragDropContainer) {
316 qCWarning(LOG_VisualizationZoneWidget())
328 qCWarning(LOG_VisualizationZoneWidget())
317 << tr("VisualizationTabWidget::dropZone, drop aborted, the parent container of "
329 << tr("VisualizationTabWidget::dropZone, drop aborted, the parent container of "
318 "the dropped zone is not found.");
330 "the dropped zone is not found.");
319 Q_ASSERT(false);
331 Q_ASSERT(false);
320 return;
332 return;
321 }
333 }
322
334
323 // Simple move of the zone, no variable operation associated
335 // Simple move of the zone, no variable operation associated
324 parentDragDropContainer->layout()->removeWidget(zoneWidget);
336 parentDragDropContainer->layout()->removeWidget(zoneWidget);
325 tabWidget->ui->dragDropContainer->insertDragWidget(index, zoneWidget);
337 tabWidget->ui->dragDropContainer->insertDragWidget(index, zoneWidget);
326 }
338 }
327
339
328 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropVariables(
340 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropVariables(
329 const QList<std::shared_ptr<Variable> > &variables, int index,
341 const QList<std::shared_ptr<Variable> > &variables, int index,
330 VisualizationTabWidget *tabWidget)
342 VisualizationTabWidget *tabWidget)
331 {
343 {
332 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
344 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
333 // compatible variable here
345 // compatible variable here
334 if (variables.count() > 1) {
346 if (variables.count() > 1) {
335 qCWarning(LOG_VisualizationZoneWidget())
347 qCWarning(LOG_VisualizationZoneWidget())
336 << tr("VisualizationTabWidget::dropVariables, dropping multiple variables, operation "
348 << tr("VisualizationTabWidget::dropVariables, dropping multiple variables, operation "
337 "aborted.");
349 "aborted.");
338 return;
350 return;
339 }
351 }
340
352
341 tabWidget->createZone(variables, index);
353 tabWidget->createZone(variables, index);
342 }
354 }
@@ -1,590 +1,601
1 #include "Visualization/VisualizationZoneWidget.h"
1 #include "Visualization/VisualizationZoneWidget.h"
2
2
3 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/IVisualizationWidgetVisitor.h"
4 #include "Visualization/QCustomPlotSynchronizer.h"
4 #include "Visualization/QCustomPlotSynchronizer.h"
5 #include "Visualization/VisualizationGraphWidget.h"
5 #include "Visualization/VisualizationGraphWidget.h"
6 #include "Visualization/VisualizationWidget.h"
6 #include "Visualization/VisualizationWidget.h"
7 #include "ui_VisualizationZoneWidget.h"
7 #include "ui_VisualizationZoneWidget.h"
8
8
9 #include "Common/MimeTypesDef.h"
9 #include "Common/MimeTypesDef.h"
10 #include "Common/VisualizationDef.h"
10 #include "Common/VisualizationDef.h"
11
11
12 #include <Data/SqpRange.h>
12 #include <Data/SqpRange.h>
13 #include <Time/TimeController.h>
13 #include <Time/TimeController.h>
14 #include <Variable/Variable.h>
14 #include <Variable/Variable.h>
15 #include <Variable/VariableController.h>
15 #include <Variable/VariableController.h>
16
16
17 #include <Visualization/operations/FindVariableOperation.h>
17 #include <Visualization/operations/FindVariableOperation.h>
18
18
19 #include <DragAndDrop/DragDropGuiController.h>
19 #include <DragAndDrop/DragDropGuiController.h>
20 #include <QUuid>
20 #include <QUuid>
21 #include <SqpApplication.h>
21 #include <SqpApplication.h>
22 #include <cmath>
22 #include <cmath>
23
23
24 #include <QLayout>
24 #include <QLayout>
25
25
26 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
26 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
27
27
28 namespace {
28 namespace {
29
29
30 /**
30 /**
31 * Applies a function to all graphs of the zone represented by its layout
31 * Applies a function to all graphs of the zone represented by its layout
32 * @param layout the layout that contains graphs
32 * @param layout the layout that contains graphs
33 * @param fun the function to apply to each graph
33 * @param fun the function to apply to each graph
34 */
34 */
35 template <typename Fun>
35 template <typename Fun>
36 void processGraphs(QLayout &layout, Fun fun)
36 void processGraphs(QLayout &layout, Fun fun)
37 {
37 {
38 for (auto i = 0; i < layout.count(); ++i) {
38 for (auto i = 0; i < layout.count(); ++i) {
39 if (auto item = layout.itemAt(i)) {
39 if (auto item = layout.itemAt(i)) {
40 if (auto visualizationGraphWidget
40 if (auto visualizationGraphWidget
41 = qobject_cast<VisualizationGraphWidget *>(item->widget())) {
41 = qobject_cast<VisualizationGraphWidget *>(item->widget())) {
42 fun(*visualizationGraphWidget);
42 fun(*visualizationGraphWidget);
43 }
43 }
44 }
44 }
45 }
45 }
46 }
46 }
47
47
48 /// Generates a default name for a new graph, according to the number of graphs already displayed in
48 /// Generates a default name for a new graph, according to the number of graphs already displayed in
49 /// the zone
49 /// the zone
50 QString defaultGraphName(QLayout &layout)
50 QString defaultGraphName(QLayout &layout)
51 {
51 {
52 QSet<QString> existingNames;
52 QSet<QString> existingNames;
53 processGraphs(
53 processGraphs(
54 layout, [&existingNames](auto &graphWidget) { existingNames.insert(graphWidget.name()); });
54 layout, [&existingNames](auto &graphWidget) { existingNames.insert(graphWidget.name()); });
55
55
56 int zoneNum = 1;
56 int zoneNum = 1;
57 QString name;
57 QString name;
58 do {
58 do {
59 name = QObject::tr("Graph ").append(QString::number(zoneNum));
59 name = QObject::tr("Graph ").append(QString::number(zoneNum));
60 ++zoneNum;
60 ++zoneNum;
61 } while (existingNames.contains(name));
61 } while (existingNames.contains(name));
62
62
63 return name;
63 return name;
64 }
64 }
65
65
66 } // namespace
66 } // namespace
67
67
68 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
68 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
69
69
70 explicit VisualizationZoneWidgetPrivate()
70 explicit VisualizationZoneWidgetPrivate()
71 : m_SynchronisationGroupId{QUuid::createUuid()},
71 : m_SynchronisationGroupId{QUuid::createUuid()},
72 m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
72 m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
73 {
73 {
74 }
74 }
75 QUuid m_SynchronisationGroupId;
75 QUuid m_SynchronisationGroupId;
76 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
76 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
77
77
78 void dropGraph(int index, VisualizationZoneWidget *zoneWidget);
78 void dropGraph(int index, VisualizationZoneWidget *zoneWidget);
79 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
79 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
80 VisualizationZoneWidget *zoneWidget);
80 VisualizationZoneWidget *zoneWidget);
81 };
81 };
82
82
83 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
83 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
84 : VisualizationDragWidget{parent},
84 : VisualizationDragWidget{parent},
85 ui{new Ui::VisualizationZoneWidget},
85 ui{new Ui::VisualizationZoneWidget},
86 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
86 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
87 {
87 {
88 ui->setupUi(this);
88 ui->setupUi(this);
89
89
90 ui->zoneNameLabel->setText(name);
90 ui->zoneNameLabel->setText(name);
91
91
92 ui->dragDropContainer->setPlaceHolderType(DragDropGuiController::PlaceHolderType::Graph);
92 ui->dragDropContainer->setPlaceHolderType(DragDropGuiController::PlaceHolderType::Graph);
93 ui->dragDropContainer->setMimeType(MIME_TYPE_GRAPH,
93 ui->dragDropContainer->setMimeType(MIME_TYPE_GRAPH,
94 VisualizationDragDropContainer::DropBehavior::Inserted);
94 VisualizationDragDropContainer::DropBehavior::Inserted);
95 ui->dragDropContainer->setMimeType(
95 ui->dragDropContainer->setMimeType(
96 MIME_TYPE_VARIABLE_LIST, VisualizationDragDropContainer::DropBehavior::InsertedAndMerged);
96 MIME_TYPE_VARIABLE_LIST, VisualizationDragDropContainer::DropBehavior::InsertedAndMerged);
97 ui->dragDropContainer->setMimeType(MIME_TYPE_TIME_RANGE,
97 ui->dragDropContainer->setMimeType(MIME_TYPE_TIME_RANGE,
98 VisualizationDragDropContainer::DropBehavior::Merged);
98 VisualizationDragDropContainer::DropBehavior::Merged);
99 ui->dragDropContainer->setMimeType(MIME_TYPE_ZONE,
99 ui->dragDropContainer->setMimeType(MIME_TYPE_ZONE,
100 VisualizationDragDropContainer::DropBehavior::Forbidden);
100 VisualizationDragDropContainer::DropBehavior::Forbidden);
101 ui->dragDropContainer->setMimeType(MIME_TYPE_SELECTION_ZONE,
101 ui->dragDropContainer->setMimeType(MIME_TYPE_SELECTION_ZONE,
102 VisualizationDragDropContainer::DropBehavior::Forbidden);
102 VisualizationDragDropContainer::DropBehavior::Forbidden);
103 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
103 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
104 return sqpApp->dragDropGuiController().checkMimeDataForVisualization(mimeData,
104 return sqpApp->dragDropGuiController().checkMimeDataForVisualization(mimeData,
105 ui->dragDropContainer);
105 ui->dragDropContainer);
106 });
106 });
107
107
108 auto acceptDragWidgetFun = [](auto dragWidget, auto mimeData) {
108 auto acceptDragWidgetFun = [](auto dragWidget, auto mimeData) {
109 if (!mimeData) {
109 if (!mimeData) {
110 return false;
110 return false;
111 }
111 }
112
112
113 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
113 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
114 auto variables = sqpApp->variableController().variablesForMimeData(
114 auto variables = sqpApp->variableController().variablesForMimeData(
115 mimeData->data(MIME_TYPE_VARIABLE_LIST));
115 mimeData->data(MIME_TYPE_VARIABLE_LIST));
116
116
117 if (variables.count() != 1) {
117 if (variables.count() != 1) {
118 return false;
118 return false;
119 }
119 }
120 auto variable = variables.first();
120 auto variable = variables.first();
121
121
122 if (auto graphWidget = dynamic_cast<const VisualizationGraphWidget *>(dragWidget)) {
122 if (auto graphWidget = dynamic_cast<const VisualizationGraphWidget *>(dragWidget)) {
123 return graphWidget->canDrop(*variable);
123 return graphWidget->canDrop(*variable);
124 }
124 }
125 }
125 }
126
126
127 return true;
127 return true;
128 };
128 };
129 ui->dragDropContainer->setAcceptDragWidgetFunction(acceptDragWidgetFun);
129 ui->dragDropContainer->setAcceptDragWidgetFunction(acceptDragWidgetFun);
130
130
131 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this,
131 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this,
132 &VisualizationZoneWidget::dropMimeData);
132 &VisualizationZoneWidget::dropMimeData);
133 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredOnWidget, this,
133 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredOnWidget, this,
134 &VisualizationZoneWidget::dropMimeDataOnGraph);
134 &VisualizationZoneWidget::dropMimeDataOnGraph);
135
135
136 // 'Close' options : widget is deleted when closed
136 // 'Close' options : widget is deleted when closed
137 setAttribute(Qt::WA_DeleteOnClose);
137 setAttribute(Qt::WA_DeleteOnClose);
138 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
138 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
139 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
139 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
140
140
141 // Synchronisation id
141 // Synchronisation id
142 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
142 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
143 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
143 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
144 }
144 }
145
145
146 VisualizationZoneWidget::~VisualizationZoneWidget()
146 VisualizationZoneWidget::~VisualizationZoneWidget()
147 {
147 {
148 delete ui;
148 delete ui;
149 }
149 }
150
150
151 void VisualizationZoneWidget::setZoneRange(const SqpRange &range)
152 {
153 if (auto graph = firstGraph()) {
154 graph->setGraphRange(range);
155 }
156 else {
157 qCWarning(LOG_VisualizationZoneWidget())
158 << tr("setZoneRange:Cannot set the range of an empty zone.");
159 }
160 }
161
151 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
162 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
152 {
163 {
153 // Synchronize new graph with others in the zone
164 // Synchronize new graph with others in the zone
154 impl->m_Synchronizer->addGraph(*graphWidget);
165 impl->m_Synchronizer->addGraph(*graphWidget);
155
166
156 ui->dragDropContainer->addDragWidget(graphWidget);
167 ui->dragDropContainer->addDragWidget(graphWidget);
157 }
168 }
158
169
159 void VisualizationZoneWidget::insertGraph(int index, VisualizationGraphWidget *graphWidget)
170 void VisualizationZoneWidget::insertGraph(int index, VisualizationGraphWidget *graphWidget)
160 {
171 {
161 // Synchronize new graph with others in the zone
172 // Synchronize new graph with others in the zone
162 impl->m_Synchronizer->addGraph(*graphWidget);
173 impl->m_Synchronizer->addGraph(*graphWidget);
163
174
164 ui->dragDropContainer->insertDragWidget(index, graphWidget);
175 ui->dragDropContainer->insertDragWidget(index, graphWidget);
165 }
176 }
166
177
167 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
178 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
168 {
179 {
169 return createGraph(variable, -1);
180 return createGraph(variable, -1);
170 }
181 }
171
182
172 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable,
183 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable,
173 int index)
184 int index)
174 {
185 {
175 auto graphWidget
186 auto graphWidget
176 = new VisualizationGraphWidget{defaultGraphName(*ui->dragDropContainer->layout()), this};
187 = new VisualizationGraphWidget{defaultGraphName(*ui->dragDropContainer->layout()), this};
177
188
178
189
179 // Set graph properties
190 // Set graph properties
180 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
191 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
181 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
192 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
182
193
183
194
184 // Lambda to synchronize zone widget
195 // Lambda to synchronize zone widget
185 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &graphRange,
196 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &graphRange,
186 const SqpRange &oldGraphRange) {
197 const SqpRange &oldGraphRange) {
187
198
188 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
199 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
189 auto frameLayout = ui->dragDropContainer->layout();
200 auto frameLayout = ui->dragDropContainer->layout();
190 for (auto i = 0; i < frameLayout->count(); ++i) {
201 for (auto i = 0; i < frameLayout->count(); ++i) {
191 auto graphChild
202 auto graphChild
192 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
203 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
193 if (graphChild && (graphChild != graphWidget)) {
204 if (graphChild && (graphChild != graphWidget)) {
194
205
195 auto graphChildRange = graphChild->graphRange();
206 auto graphChildRange = graphChild->graphRange();
196 switch (zoomType) {
207 switch (zoomType) {
197 case AcquisitionZoomType::ZoomIn: {
208 case AcquisitionZoomType::ZoomIn: {
198 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
209 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
199 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
210 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
200 graphChildRange.m_TStart += deltaLeft;
211 graphChildRange.m_TStart += deltaLeft;
201 graphChildRange.m_TEnd -= deltaRight;
212 graphChildRange.m_TEnd -= deltaRight;
202 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
213 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
203 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
214 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
204 << deltaLeft;
215 << deltaLeft;
205 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
216 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
206 << deltaRight;
217 << deltaRight;
207 qCDebug(LOG_VisualizationZoneWidget())
218 qCDebug(LOG_VisualizationZoneWidget())
208 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
219 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
209
220
210 break;
221 break;
211 }
222 }
212
223
213 case AcquisitionZoomType::ZoomOut: {
224 case AcquisitionZoomType::ZoomOut: {
214 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
225 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
215 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
226 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
216 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
227 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
217 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
228 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
218 << deltaLeft;
229 << deltaLeft;
219 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
230 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
220 << deltaRight;
231 << deltaRight;
221 qCDebug(LOG_VisualizationZoneWidget())
232 qCDebug(LOG_VisualizationZoneWidget())
222 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
233 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
223 graphChildRange.m_TStart -= deltaLeft;
234 graphChildRange.m_TStart -= deltaLeft;
224 graphChildRange.m_TEnd += deltaRight;
235 graphChildRange.m_TEnd += deltaRight;
225 break;
236 break;
226 }
237 }
227 case AcquisitionZoomType::PanRight: {
238 case AcquisitionZoomType::PanRight: {
228 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
239 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
229 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
240 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
230 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
241 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
231 graphChildRange.m_TStart += deltaLeft;
242 graphChildRange.m_TStart += deltaLeft;
232 graphChildRange.m_TEnd += deltaRight;
243 graphChildRange.m_TEnd += deltaRight;
233 qCDebug(LOG_VisualizationZoneWidget())
244 qCDebug(LOG_VisualizationZoneWidget())
234 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
245 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
235 break;
246 break;
236 }
247 }
237 case AcquisitionZoomType::PanLeft: {
248 case AcquisitionZoomType::PanLeft: {
238 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
249 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
239 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
250 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
240 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
251 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
241 graphChildRange.m_TStart -= deltaLeft;
252 graphChildRange.m_TStart -= deltaLeft;
242 graphChildRange.m_TEnd -= deltaRight;
253 graphChildRange.m_TEnd -= deltaRight;
243 break;
254 break;
244 }
255 }
245 case AcquisitionZoomType::Unknown: {
256 case AcquisitionZoomType::Unknown: {
246 qCDebug(LOG_VisualizationZoneWidget())
257 qCDebug(LOG_VisualizationZoneWidget())
247 << tr("Impossible to synchronize: zoom type unknown");
258 << tr("Impossible to synchronize: zoom type unknown");
248 break;
259 break;
249 }
260 }
250 default:
261 default:
251 qCCritical(LOG_VisualizationZoneWidget())
262 qCCritical(LOG_VisualizationZoneWidget())
252 << tr("Impossible to synchronize: zoom type not take into account");
263 << tr("Impossible to synchronize: zoom type not take into account");
253 // No action
264 // No action
254 break;
265 break;
255 }
266 }
256 graphChild->enableAcquisition(false);
267 graphChild->enableAcquisition(false);
257 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
268 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
258 << graphChild->graphRange();
269 << graphChild->graphRange();
259 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
270 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
260 << graphChildRange;
271 << graphChildRange;
261 qCDebug(LOG_VisualizationZoneWidget())
272 qCDebug(LOG_VisualizationZoneWidget())
262 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
273 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
263 graphChild->setGraphRange(graphChildRange);
274 graphChild->setGraphRange(graphChildRange);
264 graphChild->enableAcquisition(true);
275 graphChild->enableAcquisition(true);
265 }
276 }
266 }
277 }
267 };
278 };
268
279
269 // connection for synchronization
280 // connection for synchronization
270 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
281 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
271 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
282 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
272 &VisualizationZoneWidget::onVariableAdded);
283 &VisualizationZoneWidget::onVariableAdded);
273 connect(graphWidget, &VisualizationGraphWidget::variableAboutToBeRemoved, this,
284 connect(graphWidget, &VisualizationGraphWidget::variableAboutToBeRemoved, this,
274 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
285 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
275
286
276 auto range = SqpRange{};
287 auto range = SqpRange{};
277 if (auto firstGraph = this->firstGraph()) {
288 if (auto firstGraph = this->firstGraph()) {
278 // Case of a new graph in a existant zone
289 // Case of a new graph in a existant zone
279 range = firstGraph->graphRange();
290 range = firstGraph->graphRange();
280 }
291 }
281 else {
292 else {
282 // Case of a new graph as the first of the zone
293 // Case of a new graph as the first of the zone
283 range = variable->range();
294 range = variable->range();
284 }
295 }
285
296
286 this->insertGraph(index, graphWidget);
297 this->insertGraph(index, graphWidget);
287
298
288 graphWidget->addVariable(variable, range);
299 graphWidget->addVariable(variable, range);
289 graphWidget->setYRange(variable);
300 graphWidget->setYRange(variable);
290
301
291 return graphWidget;
302 return graphWidget;
292 }
303 }
293
304
294 VisualizationGraphWidget *
305 VisualizationGraphWidget *
295 VisualizationZoneWidget::createGraph(const QList<std::shared_ptr<Variable> > variables, int index)
306 VisualizationZoneWidget::createGraph(const QList<std::shared_ptr<Variable> > variables, int index)
296 {
307 {
297 if (variables.isEmpty()) {
308 if (variables.isEmpty()) {
298 return nullptr;
309 return nullptr;
299 }
310 }
300
311
301 auto graphWidget = createGraph(variables.first(), index);
312 auto graphWidget = createGraph(variables.first(), index);
302 for (auto variableIt = variables.cbegin() + 1; variableIt != variables.cend(); ++variableIt) {
313 for (auto variableIt = variables.cbegin() + 1; variableIt != variables.cend(); ++variableIt) {
303 graphWidget->addVariable(*variableIt, graphWidget->graphRange());
314 graphWidget->addVariable(*variableIt, graphWidget->graphRange());
304 }
315 }
305
316
306 return graphWidget;
317 return graphWidget;
307 }
318 }
308
319
309 VisualizationGraphWidget *VisualizationZoneWidget::firstGraph() const
320 VisualizationGraphWidget *VisualizationZoneWidget::firstGraph() const
310 {
321 {
311 VisualizationGraphWidget *firstGraph = nullptr;
322 VisualizationGraphWidget *firstGraph = nullptr;
312 auto layout = ui->dragDropContainer->layout();
323 auto layout = ui->dragDropContainer->layout();
313 if (layout->count() > 0) {
324 if (layout->count() > 0) {
314 if (auto visualizationGraphWidget
325 if (auto visualizationGraphWidget
315 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
326 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
316 firstGraph = visualizationGraphWidget;
327 firstGraph = visualizationGraphWidget;
317 }
328 }
318 }
329 }
319
330
320 return firstGraph;
331 return firstGraph;
321 }
332 }
322
333
323 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
334 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
324 {
335 {
325 if (visitor) {
336 if (visitor) {
326 visitor->visitEnter(this);
337 visitor->visitEnter(this);
327
338
328 // Apply visitor to graph children: widgets different from graphs are not visited (no
339 // Apply visitor to graph children: widgets different from graphs are not visited (no
329 // action)
340 // action)
330 processGraphs(
341 processGraphs(
331 *ui->dragDropContainer->layout(),
342 *ui->dragDropContainer->layout(),
332 [visitor](VisualizationGraphWidget &graphWidget) { graphWidget.accept(visitor); });
343 [visitor](VisualizationGraphWidget &graphWidget) { graphWidget.accept(visitor); });
333
344
334 visitor->visitLeave(this);
345 visitor->visitLeave(this);
335 }
346 }
336 else {
347 else {
337 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
348 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
338 }
349 }
339 }
350 }
340
351
341 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
352 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
342 {
353 {
343 // A tab can always accomodate a variable
354 // A tab can always accomodate a variable
344 Q_UNUSED(variable);
355 Q_UNUSED(variable);
345 return true;
356 return true;
346 }
357 }
347
358
348 bool VisualizationZoneWidget::contains(const Variable &variable) const
359 bool VisualizationZoneWidget::contains(const Variable &variable) const
349 {
360 {
350 Q_UNUSED(variable);
361 Q_UNUSED(variable);
351 return false;
362 return false;
352 }
363 }
353
364
354 QString VisualizationZoneWidget::name() const
365 QString VisualizationZoneWidget::name() const
355 {
366 {
356 return ui->zoneNameLabel->text();
367 return ui->zoneNameLabel->text();
357 }
368 }
358
369
359 QMimeData *VisualizationZoneWidget::mimeData(const QPoint &position) const
370 QMimeData *VisualizationZoneWidget::mimeData(const QPoint &position) const
360 {
371 {
361 Q_UNUSED(position);
372 Q_UNUSED(position);
362
373
363 auto mimeData = new QMimeData;
374 auto mimeData = new QMimeData;
364 mimeData->setData(MIME_TYPE_ZONE, QByteArray{});
375 mimeData->setData(MIME_TYPE_ZONE, QByteArray{});
365
376
366 if (auto firstGraph = this->firstGraph()) {
377 if (auto firstGraph = this->firstGraph()) {
367 auto timeRangeData = TimeController::mimeDataForTimeRange(firstGraph->graphRange());
378 auto timeRangeData = TimeController::mimeDataForTimeRange(firstGraph->graphRange());
368 mimeData->setData(MIME_TYPE_TIME_RANGE, timeRangeData);
379 mimeData->setData(MIME_TYPE_TIME_RANGE, timeRangeData);
369 }
380 }
370
381
371 return mimeData;
382 return mimeData;
372 }
383 }
373
384
374 bool VisualizationZoneWidget::isDragAllowed() const
385 bool VisualizationZoneWidget::isDragAllowed() const
375 {
386 {
376 return true;
387 return true;
377 }
388 }
378
389
379 void VisualizationZoneWidget::notifyMouseMoveInGraph(const QPointF &graphPosition,
390 void VisualizationZoneWidget::notifyMouseMoveInGraph(const QPointF &graphPosition,
380 const QPointF &plotPosition,
391 const QPointF &plotPosition,
381 VisualizationGraphWidget *graphWidget)
392 VisualizationGraphWidget *graphWidget)
382 {
393 {
383 processGraphs(*ui->dragDropContainer->layout(), [&graphPosition, &plotPosition, &graphWidget](
394 processGraphs(*ui->dragDropContainer->layout(), [&graphPosition, &plotPosition, &graphWidget](
384 VisualizationGraphWidget &processedGraph) {
395 VisualizationGraphWidget &processedGraph) {
385
396
386 switch (sqpApp->plotsCursorMode()) {
397 switch (sqpApp->plotsCursorMode()) {
387 case SqpApplication::PlotsCursorMode::Vertical:
398 case SqpApplication::PlotsCursorMode::Vertical:
388 processedGraph.removeHorizontalCursor();
399 processedGraph.removeHorizontalCursor();
389 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
400 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
390 break;
401 break;
391 case SqpApplication::PlotsCursorMode::Temporal:
402 case SqpApplication::PlotsCursorMode::Temporal:
392 processedGraph.addVerticalCursor(plotPosition.x());
403 processedGraph.addVerticalCursor(plotPosition.x());
393 processedGraph.removeHorizontalCursor();
404 processedGraph.removeHorizontalCursor();
394 break;
405 break;
395 case SqpApplication::PlotsCursorMode::Horizontal:
406 case SqpApplication::PlotsCursorMode::Horizontal:
396 processedGraph.removeVerticalCursor();
407 processedGraph.removeVerticalCursor();
397 if (&processedGraph == graphWidget) {
408 if (&processedGraph == graphWidget) {
398 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
409 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
399 }
410 }
400 else {
411 else {
401 processedGraph.removeHorizontalCursor();
412 processedGraph.removeHorizontalCursor();
402 }
413 }
403 break;
414 break;
404 case SqpApplication::PlotsCursorMode::Cross:
415 case SqpApplication::PlotsCursorMode::Cross:
405 if (&processedGraph == graphWidget) {
416 if (&processedGraph == graphWidget) {
406 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
417 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
407 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
418 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
408 }
419 }
409 else {
420 else {
410 processedGraph.removeHorizontalCursor();
421 processedGraph.removeHorizontalCursor();
411 processedGraph.removeVerticalCursor();
422 processedGraph.removeVerticalCursor();
412 }
423 }
413 break;
424 break;
414 case SqpApplication::PlotsCursorMode::NoCursor:
425 case SqpApplication::PlotsCursorMode::NoCursor:
415 processedGraph.removeHorizontalCursor();
426 processedGraph.removeHorizontalCursor();
416 processedGraph.removeVerticalCursor();
427 processedGraph.removeVerticalCursor();
417 break;
428 break;
418 }
429 }
419
430
420
431
421 });
432 });
422 }
433 }
423
434
424 void VisualizationZoneWidget::notifyMouseLeaveGraph(VisualizationGraphWidget *graphWidget)
435 void VisualizationZoneWidget::notifyMouseLeaveGraph(VisualizationGraphWidget *graphWidget)
425 {
436 {
426 processGraphs(*ui->dragDropContainer->layout(), [](VisualizationGraphWidget &processedGraph) {
437 processGraphs(*ui->dragDropContainer->layout(), [](VisualizationGraphWidget &processedGraph) {
427 processedGraph.removeHorizontalCursor();
438 processedGraph.removeHorizontalCursor();
428 processedGraph.removeVerticalCursor();
439 processedGraph.removeVerticalCursor();
429 });
440 });
430 }
441 }
431
442
432 void VisualizationZoneWidget::closeEvent(QCloseEvent *event)
443 void VisualizationZoneWidget::closeEvent(QCloseEvent *event)
433 {
444 {
434 // Closes graphs in the zone
445 // Closes graphs in the zone
435 processGraphs(*ui->dragDropContainer->layout(),
446 processGraphs(*ui->dragDropContainer->layout(),
436 [](VisualizationGraphWidget &graphWidget) { graphWidget.close(); });
447 [](VisualizationGraphWidget &graphWidget) { graphWidget.close(); });
437
448
438 // Delete synchronization group from variable controller
449 // Delete synchronization group from variable controller
439 QMetaObject::invokeMethod(&sqpApp->variableController(), "onRemoveSynchronizationGroupId",
450 QMetaObject::invokeMethod(&sqpApp->variableController(), "onRemoveSynchronizationGroupId",
440 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
451 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
441
452
442 QWidget::closeEvent(event);
453 QWidget::closeEvent(event);
443 }
454 }
444
455
445 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
456 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
446 {
457 {
447 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
458 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
448 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
459 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
449 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
460 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
450 }
461 }
451
462
452 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable)
463 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable)
453 {
464 {
454 QMetaObject::invokeMethod(&sqpApp->variableController(), "desynchronize", Qt::QueuedConnection,
465 QMetaObject::invokeMethod(&sqpApp->variableController(), "desynchronize", Qt::QueuedConnection,
455 Q_ARG(std::shared_ptr<Variable>, variable),
466 Q_ARG(std::shared_ptr<Variable>, variable),
456 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
467 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
457 }
468 }
458
469
459 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData)
470 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData)
460 {
471 {
461 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
472 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
462 impl->dropGraph(index, this);
473 impl->dropGraph(index, this);
463 }
474 }
464 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
475 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
465 auto variables = sqpApp->variableController().variablesForMimeData(
476 auto variables = sqpApp->variableController().variablesForMimeData(
466 mimeData->data(MIME_TYPE_VARIABLE_LIST));
477 mimeData->data(MIME_TYPE_VARIABLE_LIST));
467 impl->dropVariables(variables, index, this);
478 impl->dropVariables(variables, index, this);
468 }
479 }
469 else {
480 else {
470 qCWarning(LOG_VisualizationZoneWidget())
481 qCWarning(LOG_VisualizationZoneWidget())
471 << tr("VisualizationZoneWidget::dropMimeData, unknown MIME data received.");
482 << tr("VisualizationZoneWidget::dropMimeData, unknown MIME data received.");
472 }
483 }
473 }
484 }
474
485
475 void VisualizationZoneWidget::dropMimeDataOnGraph(VisualizationDragWidget *dragWidget,
486 void VisualizationZoneWidget::dropMimeDataOnGraph(VisualizationDragWidget *dragWidget,
476 const QMimeData *mimeData)
487 const QMimeData *mimeData)
477 {
488 {
478 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(dragWidget);
489 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(dragWidget);
479 if (!graphWidget) {
490 if (!graphWidget) {
480 qCWarning(LOG_VisualizationZoneWidget())
491 qCWarning(LOG_VisualizationZoneWidget())
481 << tr("VisualizationZoneWidget::dropMimeDataOnGraph, dropping in an unknown widget, "
492 << tr("VisualizationZoneWidget::dropMimeDataOnGraph, dropping in an unknown widget, "
482 "drop aborted");
493 "drop aborted");
483 Q_ASSERT(false);
494 Q_ASSERT(false);
484 return;
495 return;
485 }
496 }
486
497
487 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
498 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
488 auto variables = sqpApp->variableController().variablesForMimeData(
499 auto variables = sqpApp->variableController().variablesForMimeData(
489 mimeData->data(MIME_TYPE_VARIABLE_LIST));
500 mimeData->data(MIME_TYPE_VARIABLE_LIST));
490 for (const auto &var : variables) {
501 for (const auto &var : variables) {
491 graphWidget->addVariable(var, graphWidget->graphRange());
502 graphWidget->addVariable(var, graphWidget->graphRange());
492 }
503 }
493 }
504 }
494 else if (mimeData->hasFormat(MIME_TYPE_TIME_RANGE)) {
505 else if (mimeData->hasFormat(MIME_TYPE_TIME_RANGE)) {
495 auto range = TimeController::timeRangeForMimeData(mimeData->data(MIME_TYPE_TIME_RANGE));
506 auto range = TimeController::timeRangeForMimeData(mimeData->data(MIME_TYPE_TIME_RANGE));
496 graphWidget->setGraphRange(range);
507 graphWidget->setGraphRange(range);
497 }
508 }
498 else {
509 else {
499 qCWarning(LOG_VisualizationZoneWidget())
510 qCWarning(LOG_VisualizationZoneWidget())
500 << tr("VisualizationZoneWidget::dropMimeDataOnGraph, unknown MIME data received.");
511 << tr("VisualizationZoneWidget::dropMimeDataOnGraph, unknown MIME data received.");
501 }
512 }
502 }
513 }
503
514
504 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
515 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
505 int index, VisualizationZoneWidget *zoneWidget)
516 int index, VisualizationZoneWidget *zoneWidget)
506 {
517 {
507 auto &helper = sqpApp->dragDropGuiController();
518 auto &helper = sqpApp->dragDropGuiController();
508
519
509 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
520 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
510 if (!graphWidget) {
521 if (!graphWidget) {
511 qCWarning(LOG_VisualizationZoneWidget())
522 qCWarning(LOG_VisualizationZoneWidget())
512 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the dropped graph is not "
523 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the dropped graph is not "
513 "found or invalid.");
524 "found or invalid.");
514 Q_ASSERT(false);
525 Q_ASSERT(false);
515 return;
526 return;
516 }
527 }
517
528
518 auto parentDragDropContainer
529 auto parentDragDropContainer
519 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
530 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
520 if (!parentDragDropContainer) {
531 if (!parentDragDropContainer) {
521 qCWarning(LOG_VisualizationZoneWidget())
532 qCWarning(LOG_VisualizationZoneWidget())
522 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the parent container of "
533 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the parent container of "
523 "the dropped graph is not found.");
534 "the dropped graph is not found.");
524 Q_ASSERT(false);
535 Q_ASSERT(false);
525 return;
536 return;
526 }
537 }
527
538
528 const auto &variables = graphWidget->variables();
539 const auto &variables = graphWidget->variables();
529
540
530 if (parentDragDropContainer != zoneWidget->ui->dragDropContainer && !variables.isEmpty()) {
541 if (parentDragDropContainer != zoneWidget->ui->dragDropContainer && !variables.isEmpty()) {
531 // The drop didn't occur in the same zone
542 // The drop didn't occur in the same zone
532
543
533 // Abort the requests for the variables (if any)
544 // Abort the requests for the variables (if any)
534 // Commented, because it's not sure if it's needed or not
545 // Commented, because it's not sure if it's needed or not
535 // for (const auto& var : variables)
546 // for (const auto& var : variables)
536 //{
547 //{
537 // sqpApp->variableController().onAbortProgressRequested(var);
548 // sqpApp->variableController().onAbortProgressRequested(var);
538 //}
549 //}
539
550
540 auto previousParentZoneWidget = graphWidget->parentZoneWidget();
551 auto previousParentZoneWidget = graphWidget->parentZoneWidget();
541 auto nbGraph = parentDragDropContainer->countDragWidget();
552 auto nbGraph = parentDragDropContainer->countDragWidget();
542 if (nbGraph == 1) {
553 if (nbGraph == 1) {
543 // This is the only graph in the previous zone, close the zone
554 // This is the only graph in the previous zone, close the zone
544 helper.delayedCloseWidget(previousParentZoneWidget);
555 helper.delayedCloseWidget(previousParentZoneWidget);
545 }
556 }
546 else {
557 else {
547 // Close the graph
558 // Close the graph
548 helper.delayedCloseWidget(graphWidget);
559 helper.delayedCloseWidget(graphWidget);
549 }
560 }
550
561
551 // Creates the new graph in the zone
562 // Creates the new graph in the zone
552 auto newGraphWidget = zoneWidget->createGraph(variables, index);
563 auto newGraphWidget = zoneWidget->createGraph(variables, index);
553 newGraphWidget->addSelectionZones(graphWidget->selectionZoneRanges());
564 newGraphWidget->addSelectionZones(graphWidget->selectionZoneRanges());
554 }
565 }
555 else {
566 else {
556 // The drop occurred in the same zone or the graph is empty
567 // The drop occurred in the same zone or the graph is empty
557 // Simple move of the graph, no variable operation associated
568 // Simple move of the graph, no variable operation associated
558 parentDragDropContainer->layout()->removeWidget(graphWidget);
569 parentDragDropContainer->layout()->removeWidget(graphWidget);
559
570
560 if (variables.isEmpty() && parentDragDropContainer != zoneWidget->ui->dragDropContainer) {
571 if (variables.isEmpty() && parentDragDropContainer != zoneWidget->ui->dragDropContainer) {
561 // The graph is empty and dropped in a different zone.
572 // The graph is empty and dropped in a different zone.
562 // Take the range of the first graph in the zone (if existing).
573 // Take the range of the first graph in the zone (if existing).
563 auto layout = zoneWidget->ui->dragDropContainer->layout();
574 auto layout = zoneWidget->ui->dragDropContainer->layout();
564 if (layout->count() > 0) {
575 if (layout->count() > 0) {
565 if (auto visualizationGraphWidget
576 if (auto visualizationGraphWidget
566 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
577 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
567 graphWidget->setGraphRange(visualizationGraphWidget->graphRange());
578 graphWidget->setGraphRange(visualizationGraphWidget->graphRange());
568 }
579 }
569 }
580 }
570 }
581 }
571
582
572 zoneWidget->ui->dragDropContainer->insertDragWidget(index, graphWidget);
583 zoneWidget->ui->dragDropContainer->insertDragWidget(index, graphWidget);
573 }
584 }
574 }
585 }
575
586
576 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropVariables(
587 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropVariables(
577 const QList<std::shared_ptr<Variable> > &variables, int index,
588 const QList<std::shared_ptr<Variable> > &variables, int index,
578 VisualizationZoneWidget *zoneWidget)
589 VisualizationZoneWidget *zoneWidget)
579 {
590 {
580 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
591 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
581 // compatible variable here
592 // compatible variable here
582 if (variables.count() > 1) {
593 if (variables.count() > 1) {
583 qCWarning(LOG_VisualizationZoneWidget())
594 qCWarning(LOG_VisualizationZoneWidget())
584 << tr("VisualizationZoneWidget::dropVariables, dropping multiple variables, operation "
595 << tr("VisualizationZoneWidget::dropVariables, dropping multiple variables, operation "
585 "aborted.");
596 "aborted.");
586 return;
597 return;
587 }
598 }
588
599
589 zoneWidget->createGraph(variables, index);
600 zoneWidget->createGraph(variables, index);
590 }
601 }
General Comments 0
You need to be logged in to leave comments. Login now