##// END OF EJS Templates
Merge pull request 220 from SCIQLOP-Initialisation develop...
perrinel -
r523:c61dc4e21f67 merge
parent child
Show More
@@ -0,0 +1,199
1 #include "Data/ArrayData.h"
2 #include <QObject>
3 #include <QtTest>
4
5 class TestOneDimArrayData : public QObject {
6 Q_OBJECT
7 private slots:
8 /// Tests @sa ArrayData::data()
9 void testData_data();
10 void testData();
11
12 /// Tests @sa ArrayData::data(int componentIndex)
13 void testDataByComponentIndex_data();
14 void testDataByComponentIndex();
15
16 /// Tests @sa ArrayData::add()
17 void testAdd_data();
18 void testAdd();
19
20 /// Tests @sa ArrayData::at(int index)
21 void testAt_data();
22 void testAt();
23
24 /// Tests @sa ArrayData::clear()
25 void testClear_data();
26 void testClear();
27
28 /// Tests @sa ArrayData::size()
29 void testSize_data();
30 void testSize();
31
32 /// Tests @sa ArrayData::sort()
33 void testSort_data();
34 void testSort();
35 };
36
37 void TestOneDimArrayData::testData_data()
38 {
39 // Test structure
40 QTest::addColumn<QVector<double> >("inputData"); // array's data input
41 QTest::addColumn<QVector<double> >("expectedData"); // expected data
42
43 // Test cases
44 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.}
45 << QVector<double>{1., 2., 3., 4., 5.};
46 }
47
48 void TestOneDimArrayData::testData()
49 {
50 QFETCH(QVector<double>, inputData);
51 QFETCH(QVector<double>, expectedData);
52
53 ArrayData<1> arrayData{inputData};
54 QVERIFY(arrayData.data() == expectedData);
55 }
56
57 void TestOneDimArrayData::testDataByComponentIndex_data()
58 {
59 // Test structure
60 QTest::addColumn<QVector<double> >("inputData"); // array data's input
61 QTest::addColumn<int>("componentIndex"); // component index to test
62 QTest::addColumn<QVector<double> >("expectedData"); // expected data
63
64 // Test cases
65 QTest::newRow("validIndex") << QVector<double>{1., 2., 3., 4., 5.} << 0
66 << QVector<double>{1., 2., 3., 4., 5.};
67 QTest::newRow("invalidIndex1")
68 << QVector<double>{1., 2., 3., 4., 5.} << -1 << QVector<double>{};
69 QTest::newRow("invalidIndex2") << QVector<double>{1., 2., 3., 4., 5.} << 1 << QVector<double>{};
70 }
71
72 void TestOneDimArrayData::testDataByComponentIndex()
73 {
74 QFETCH(QVector<double>, inputData);
75 QFETCH(int, componentIndex);
76 QFETCH(QVector<double>, expectedData);
77
78 ArrayData<1> arrayData{inputData};
79 QVERIFY(arrayData.data(componentIndex) == expectedData);
80 }
81
82 void TestOneDimArrayData::testAdd_data()
83 {
84 // Test structure
85 QTest::addColumn<QVector<double> >("inputData"); // array's data input
86 QTest::addColumn<QVector<double> >("otherData"); // array data's input to merge with
87 QTest::addColumn<bool>("prepend"); // prepend or append merge
88 QTest::addColumn<QVector<double> >("expectedData"); // expected data after merge
89
90 // Test cases
91 QTest::newRow("appendMerge") << QVector<double>{1., 2., 3., 4., 5.}
92 << QVector<double>{6., 7., 8.} << false
93 << QVector<double>{1., 2., 3., 4., 5., 6., 7., 8.};
94 QTest::newRow("prependMerge") << QVector<double>{1., 2., 3., 4., 5.}
95 << QVector<double>{6., 7., 8.} << true
96 << QVector<double>{6., 7., 8., 1., 2., 3., 4., 5.};
97 }
98
99 void TestOneDimArrayData::testAdd()
100 {
101 QFETCH(QVector<double>, inputData);
102 QFETCH(QVector<double>, otherData);
103 QFETCH(bool, prepend);
104 QFETCH(QVector<double>, expectedData);
105
106 ArrayData<1> arrayData{inputData};
107 ArrayData<1> other{otherData};
108
109 arrayData.add(other, prepend);
110 QVERIFY(arrayData.data() == expectedData);
111 }
112
113 void TestOneDimArrayData::testAt_data()
114 {
115 // Test structure
116 QTest::addColumn<QVector<double> >("inputData"); // array data's input
117 QTest::addColumn<int>("index"); // index to retrieve data
118 QTest::addColumn<double>("expectedData"); // expected data at index
119
120 // Test cases
121 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.} << 0 << 1.;
122 QTest::newRow("data2") << QVector<double>{1., 2., 3., 4., 5.} << 3 << 4.;
123 }
124
125 void TestOneDimArrayData::testAt()
126 {
127 QFETCH(QVector<double>, inputData);
128 QFETCH(int, index);
129 QFETCH(double, expectedData);
130
131 ArrayData<1> arrayData{inputData};
132 QVERIFY(arrayData.at(index) == expectedData);
133 }
134
135 void TestOneDimArrayData::testClear_data()
136 {
137 // Test structure
138 QTest::addColumn<QVector<double> >("inputData"); // array data's input
139
140 // Test cases
141 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.};
142 }
143
144 void TestOneDimArrayData::testClear()
145 {
146 QFETCH(QVector<double>, inputData);
147
148 ArrayData<1> arrayData{inputData};
149 arrayData.clear();
150 QVERIFY(arrayData.data() == QVector<double>{});
151 }
152
153 void TestOneDimArrayData::testSize_data()
154 {
155 // Test structure
156 QTest::addColumn<QVector<double> >("inputData"); // array data's input
157 QTest::addColumn<int>("expectedSize"); // expected array data size
158
159 // Test cases
160 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.} << 5;
161 }
162
163 void TestOneDimArrayData::testSize()
164 {
165 QFETCH(QVector<double>, inputData);
166 QFETCH(int, expectedSize);
167
168 ArrayData<1> arrayData{inputData};
169 QVERIFY(arrayData.size() == expectedSize);
170 }
171
172 void TestOneDimArrayData::testSort_data()
173 {
174 // Test structure
175 QTest::addColumn<QVector<double> >("inputData"); // array data's input
176 QTest::addColumn<std::vector<int> >("sortPermutation"); // permutation used to sort data
177 QTest::addColumn<QVector<double> >("expectedData"); // expected data after sorting
178
179 // Test cases
180 QTest::newRow("data1") << QVector<double>{1., 2., 3., 4., 5.} << std::vector<int>{0, 2, 3, 1, 4}
181 << QVector<double>{1., 3., 4., 2., 5.};
182 QTest::newRow("data2") << QVector<double>{1., 2., 3., 4., 5.} << std::vector<int>{4, 1, 2, 3, 0}
183 << QVector<double>{5., 2., 3., 4., 1.};
184 }
185
186 void TestOneDimArrayData::testSort()
187 {
188 QFETCH(QVector<double>, inputData);
189 QFETCH(std::vector<int>, sortPermutation);
190 QFETCH(QVector<double>, expectedData);
191
192 ArrayData<1> arrayData{inputData};
193 auto sortedArrayData = arrayData.sort(sortPermutation);
194 QVERIFY(sortedArrayData);
195 QVERIFY(sortedArrayData->data() == expectedData);
196 }
197
198 QTEST_MAIN(TestOneDimArrayData)
199 #include "TestOneDimArrayData.moc"
@@ -0,0 +1,224
1 #include "Data/ArrayData.h"
2 #include <QObject>
3 #include <QtTest>
4
5 using DataContainer = QVector<QVector<double> >;
6
7 class TestTwoDimArrayData : public QObject {
8 Q_OBJECT
9 private slots:
10 /// Tests @sa ArrayData::data(int componentIndex)
11 void testDataByComponentIndex_data();
12 void testDataByComponentIndex();
13
14 /// Tests @sa ArrayData ctor
15 void testCtor_data();
16 void testCtor();
17
18 /// Tests @sa ArrayData::add()
19 void testAdd_data();
20 void testAdd();
21
22 /// Tests @sa ArrayData::clear()
23 void testClear_data();
24 void testClear();
25
26 /// Tests @sa ArrayData::size()
27 void testSize_data();
28 void testSize();
29
30 /// Tests @sa ArrayData::sort()
31 void testSort_data();
32 void testSort();
33 };
34
35 void TestTwoDimArrayData::testDataByComponentIndex_data()
36 {
37 // Test structure
38 QTest::addColumn<DataContainer>("inputData"); // array data's input
39 QTest::addColumn<int>("componentIndex"); // component index to test
40 QTest::addColumn<QVector<double> >("expectedData"); // expected data
41
42 // Test cases
43 auto inputData
44 = DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}};
45
46 QTest::newRow("validIndex1") << inputData << 0 << QVector<double>{1., 2., 3., 4., 5.};
47 QTest::newRow("validIndex2") << inputData << 1 << QVector<double>{6., 7., 8., 9., 10.};
48 QTest::newRow("validIndex3") << inputData << 2 << QVector<double>{11., 12., 13., 14., 15.};
49 QTest::newRow("invalidIndex1") << inputData << -1 << QVector<double>{};
50 QTest::newRow("invalidIndex2") << inputData << 3 << QVector<double>{};
51 }
52
53 void TestTwoDimArrayData::testDataByComponentIndex()
54 {
55 QFETCH(DataContainer, inputData);
56 QFETCH(int, componentIndex);
57 QFETCH(QVector<double>, expectedData);
58
59 ArrayData<2> arrayData{inputData};
60 QVERIFY(arrayData.data(componentIndex) == expectedData);
61 }
62
63 void TestTwoDimArrayData::testCtor_data()
64 {
65 // Test structure
66 QTest::addColumn<DataContainer>("inputData"); // array data's input
67 QTest::addColumn<bool>("success"); // array data has been successfully constructed
68 QTest::addColumn<DataContainer>("expectedData"); // expected array data (when success)
69
70 // Test cases
71 QTest::newRow("validInput")
72 << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}}
73 << true
74 << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}};
75 QTest::newRow("malformedInput (components of the array data haven't the same size")
76 << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8.}, {11., 12.}} << true
77 << DataContainer{{}, {}, {}};
78 QTest::newRow("invalidInput (less than tow components")
79 << DataContainer{{1., 2., 3., 4., 5.}} << false << DataContainer{{}, {}, {}};
80 }
81
82 void TestTwoDimArrayData::testCtor()
83 {
84 QFETCH(DataContainer, inputData);
85 QFETCH(bool, success);
86
87 if (success) {
88 QFETCH(DataContainer, expectedData);
89
90 ArrayData<2> arrayData{inputData};
91
92 for (auto i = 0; i < expectedData.size(); ++i) {
93 QVERIFY(arrayData.data(i) == expectedData.at(i));
94 }
95 }
96 else {
97 QVERIFY_EXCEPTION_THROWN(ArrayData<2> arrayData{inputData}, std::invalid_argument);
98 }
99 }
100
101 void TestTwoDimArrayData::testAdd_data()
102 {
103 // Test structure
104 QTest::addColumn<DataContainer>("inputData"); // array's data input
105 QTest::addColumn<DataContainer>("otherData"); // array data's input to merge with
106 QTest::addColumn<bool>("prepend"); // prepend or append merge
107 QTest::addColumn<DataContainer>("expectedData"); // expected data after merge
108
109 // Test cases
110 auto inputData
111 = DataContainer{{1., 2., 3., 4., 5.}, {11., 12., 13., 14., 15.}, {21., 22., 23., 24., 25.}};
112
113 auto vectorContainer = DataContainer{{6., 7., 8.}, {16., 17., 18.}, {26., 27., 28}};
114 auto tensorContainer = DataContainer{{6., 7., 8.}, {16., 17., 18.}, {26., 27., 28},
115 {36., 37., 38.}, {46., 47., 48.}, {56., 57., 58}};
116
117 QTest::newRow("appendMerge") << inputData << vectorContainer << false
118 << DataContainer{{1., 2., 3., 4., 5., 6., 7., 8.},
119 {11., 12., 13., 14., 15., 16., 17., 18.},
120 {21., 22., 23., 24., 25., 26., 27., 28}};
121 QTest::newRow("prependMerge") << inputData << vectorContainer << true
122 << DataContainer{{6., 7., 8., 1., 2., 3., 4., 5.},
123 {16., 17., 18., 11., 12., 13., 14., 15.},
124 {26., 27., 28, 21., 22., 23., 24., 25.}};
125 QTest::newRow("invalidMerge") << inputData << tensorContainer << false << inputData;
126 }
127
128 void TestTwoDimArrayData::testAdd()
129 {
130 QFETCH(DataContainer, inputData);
131 QFETCH(DataContainer, otherData);
132 QFETCH(bool, prepend);
133 QFETCH(DataContainer, expectedData);
134
135 ArrayData<2> arrayData{inputData};
136 ArrayData<2> other{otherData};
137
138 arrayData.add(other, prepend);
139
140 for (auto i = 0; i < expectedData.size(); ++i) {
141 QVERIFY(arrayData.data(i) == expectedData.at(i));
142 }
143 }
144
145 void TestTwoDimArrayData::testClear_data()
146 {
147 // Test structure
148 QTest::addColumn<DataContainer>("inputData"); // array data's input
149
150 // Test cases
151 QTest::newRow("data1") << DataContainer{
152 {1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}};
153 }
154
155 void TestTwoDimArrayData::testClear()
156 {
157 QFETCH(DataContainer, inputData);
158
159 ArrayData<2> arrayData{inputData};
160 arrayData.clear();
161
162 for (auto i = 0; i < inputData.size(); ++i) {
163 QVERIFY(arrayData.data(i) == QVector<double>{});
164 }
165 }
166
167 void TestTwoDimArrayData::testSize_data()
168 {
169 // Test structure
170 QTest::addColumn<QVector<QVector<double> > >("inputData"); // array data's input
171 QTest::addColumn<int>("expectedSize"); // expected array data size
172
173 // Test cases
174 QTest::newRow("data1") << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}} << 5;
175 QTest::newRow("data2") << DataContainer{{1., 2., 3., 4., 5.},
176 {6., 7., 8., 9., 10.},
177 {11., 12., 13., 14., 15.}}
178 << 5;
179 }
180
181 void TestTwoDimArrayData::testSize()
182 {
183 QFETCH(DataContainer, inputData);
184 QFETCH(int, expectedSize);
185
186 ArrayData<2> arrayData{inputData};
187 QVERIFY(arrayData.size() == expectedSize);
188 }
189
190 void TestTwoDimArrayData::testSort_data()
191 {
192 // Test structure
193 QTest::addColumn<DataContainer>("inputData"); // array data's input
194 QTest::addColumn<std::vector<int> >("sortPermutation"); // permutation used to sort data
195 QTest::addColumn<DataContainer>("expectedData"); // expected data after sorting
196
197 // Test cases
198 QTest::newRow("data1")
199 << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}}
200 << std::vector<int>{0, 2, 3, 1, 4}
201 << DataContainer{{1., 3., 4., 2., 5.}, {6., 8., 9., 7., 10.}, {11., 13., 14., 12., 15.}};
202 QTest::newRow("data2")
203 << DataContainer{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}}
204 << std::vector<int>{2, 4, 3, 0, 1}
205 << DataContainer{{3., 5., 4., 1., 2.}, {8., 10., 9., 6., 7.}, {13., 15., 14., 11., 12.}};
206 }
207
208 void TestTwoDimArrayData::testSort()
209 {
210 QFETCH(DataContainer, inputData);
211 QFETCH(std::vector<int>, sortPermutation);
212 QFETCH(DataContainer, expectedData);
213
214 ArrayData<2> arrayData{inputData};
215 auto sortedArrayData = arrayData.sort(sortPermutation);
216 QVERIFY(sortedArrayData);
217
218 for (auto i = 0; i < expectedData.size(); ++i) {
219 QVERIFY(sortedArrayData->data(i) == expectedData.at(i));
220 }
221 }
222
223 QTEST_MAIN(TestTwoDimArrayData)
224 #include "TestTwoDimArrayData.moc"
@@ -1,254 +1,254
1 /*------------------------------------------------------------------------------
1 /*------------------------------------------------------------------------------
2 -- This file is a part of the SciQLop Software
2 -- This file is a part of the SciQLop Software
3 -- Copyright (C) 2017, Plasma Physics Laboratory - CNRS
3 -- Copyright (C) 2017, Plasma Physics Laboratory - CNRS
4 --
4 --
5 -- This program is free software; you can redistribute it and/or modify
5 -- This program is free software; you can redistribute it and/or modify
6 -- it under the terms of the GNU General Public License as published by
6 -- it under the terms of the GNU General Public License as published by
7 -- the Free Software Foundation; either version 2 of the License, or
7 -- the Free Software Foundation; either version 2 of the License, or
8 -- (at your option) any later version.
8 -- (at your option) any later version.
9 --
9 --
10 -- This program is distributed in the hope that it will be useful,
10 -- This program is distributed in the hope that it will be useful,
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 -- GNU General Public License for more details.
13 -- GNU General Public License for more details.
14 --
14 --
15 -- You should have received a copy of the GNU General Public License
15 -- You should have received a copy of the GNU General Public License
16 -- along with this program; if not, write to the Free Software
16 -- along with this program; if not, write to the Free Software
17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 -------------------------------------------------------------------------------*/
18 -------------------------------------------------------------------------------*/
19 /*-- Author : Alexis Jeandet
19 /*-- Author : Alexis Jeandet
20 -- Mail : alexis.jeandet@member.fsf.org
20 -- Mail : alexis.jeandet@member.fsf.org
21 ----------------------------------------------------------------------------*/
21 ----------------------------------------------------------------------------*/
22 #include "MainWindow.h"
22 #include "MainWindow.h"
23 #include "ui_MainWindow.h"
23 #include "ui_MainWindow.h"
24
24
25 #include <DataSource/DataSourceController.h>
25 #include <DataSource/DataSourceController.h>
26 #include <DataSource/DataSourceWidget.h>
26 #include <DataSource/DataSourceWidget.h>
27 #include <Settings/SqpSettingsDialog.h>
27 #include <Settings/SqpSettingsDialog.h>
28 #include <Settings/SqpSettingsGeneralWidget.h>
28 #include <Settings/SqpSettingsGeneralWidget.h>
29 #include <SidePane/SqpSidePane.h>
29 #include <SidePane/SqpSidePane.h>
30 #include <SqpApplication.h>
30 #include <SqpApplication.h>
31 #include <Time/TimeController.h>
31 #include <Time/TimeController.h>
32 #include <TimeWidget/TimeWidget.h>
32 #include <TimeWidget/TimeWidget.h>
33 #include <Variable/Variable.h>
33 #include <Variable/Variable.h>
34 #include <Variable/VariableController.h>
34 #include <Variable/VariableController.h>
35 #include <Visualization/VisualizationController.h>
35 #include <Visualization/VisualizationController.h>
36
36
37 #include <QAction>
37 #include <QAction>
38 #include <QDate>
38 #include <QDate>
39 #include <QDir>
39 #include <QDir>
40 #include <QFileDialog>
40 #include <QFileDialog>
41 #include <QToolBar>
41 #include <QToolBar>
42 #include <QToolButton>
42 #include <QToolButton>
43 #include <memory.h>
43 #include <memory.h>
44
44
45 #include "iostream"
45 #include "iostream"
46
46
47 Q_LOGGING_CATEGORY(LOG_MainWindow, "MainWindow")
47 Q_LOGGING_CATEGORY(LOG_MainWindow, "MainWindow")
48
48
49 namespace {
49 namespace {
50 const auto LEFTMAININSPECTORWIDGETSPLITTERINDEX = 0;
50 const auto LEFTMAININSPECTORWIDGETSPLITTERINDEX = 0;
51 const auto LEFTINSPECTORSIDEPANESPLITTERINDEX = 1;
51 const auto LEFTINSPECTORSIDEPANESPLITTERINDEX = 1;
52 const auto VIEWPLITTERINDEX = 2;
52 const auto VIEWPLITTERINDEX = 2;
53 const auto RIGHTINSPECTORSIDEPANESPLITTERINDEX = 3;
53 const auto RIGHTINSPECTORSIDEPANESPLITTERINDEX = 3;
54 const auto RIGHTMAININSPECTORWIDGETSPLITTERINDEX = 4;
54 const auto RIGHTMAININSPECTORWIDGETSPLITTERINDEX = 4;
55 }
55 }
56
56
57 class MainWindow::MainWindowPrivate {
57 class MainWindow::MainWindowPrivate {
58 public:
58 public:
59 explicit MainWindowPrivate(MainWindow *mainWindow)
59 explicit MainWindowPrivate(MainWindow *mainWindow)
60 : m_LastOpenLeftInspectorSize{},
60 : m_LastOpenLeftInspectorSize{},
61 m_LastOpenRightInspectorSize{},
61 m_LastOpenRightInspectorSize{},
62 m_GeneralSettingsWidget{new SqpSettingsGeneralWidget{mainWindow}},
62 m_GeneralSettingsWidget{new SqpSettingsGeneralWidget{mainWindow}},
63 m_SettingsDialog{new SqpSettingsDialog{mainWindow}}
63 m_SettingsDialog{new SqpSettingsDialog{mainWindow}}
64 {
64 {
65 }
65 }
66
66
67 QSize m_LastOpenLeftInspectorSize;
67 QSize m_LastOpenLeftInspectorSize;
68 QSize m_LastOpenRightInspectorSize;
68 QSize m_LastOpenRightInspectorSize;
69 /// General settings widget. MainWindow has the ownership
69 /// General settings widget. MainWindow has the ownership
70 SqpSettingsGeneralWidget *m_GeneralSettingsWidget;
70 SqpSettingsGeneralWidget *m_GeneralSettingsWidget;
71 /// Settings dialog. MainWindow has the ownership
71 /// Settings dialog. MainWindow has the ownership
72 SqpSettingsDialog *m_SettingsDialog;
72 SqpSettingsDialog *m_SettingsDialog;
73 };
73 };
74
74
75 MainWindow::MainWindow(QWidget *parent)
75 MainWindow::MainWindow(QWidget *parent)
76 : QMainWindow{parent},
76 : QMainWindow{parent},
77 m_Ui{new Ui::MainWindow},
77 m_Ui{new Ui::MainWindow},
78 impl{spimpl::make_unique_impl<MainWindowPrivate>(this)}
78 impl{spimpl::make_unique_impl<MainWindowPrivate>(this)}
79 {
79 {
80 m_Ui->setupUi(this);
80 m_Ui->setupUi(this);
81
81
82 m_Ui->splitter->setCollapsible(LEFTINSPECTORSIDEPANESPLITTERINDEX, false);
82 m_Ui->splitter->setCollapsible(LEFTINSPECTORSIDEPANESPLITTERINDEX, false);
83 m_Ui->splitter->setCollapsible(RIGHTINSPECTORSIDEPANESPLITTERINDEX, false);
83 m_Ui->splitter->setCollapsible(RIGHTINSPECTORSIDEPANESPLITTERINDEX, false);
84
84
85
85
86 auto leftSidePane = m_Ui->leftInspectorSidePane->sidePane();
86 auto leftSidePane = m_Ui->leftInspectorSidePane->sidePane();
87 auto openLeftInspectorAction = new QAction{QIcon{
87 auto openLeftInspectorAction = new QAction{QIcon{
88 ":/icones/previous.png",
88 ":/icones/previous.png",
89 },
89 },
90 tr("Show/hide the left inspector"), this};
90 tr("Show/hide the left inspector"), this};
91
91
92
92
93 auto spacerLeftTop = new QWidget{};
93 auto spacerLeftTop = new QWidget{};
94 spacerLeftTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
94 spacerLeftTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
95
95
96 auto spacerLeftBottom = new QWidget{};
96 auto spacerLeftBottom = new QWidget{};
97 spacerLeftBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
97 spacerLeftBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
98
98
99 leftSidePane->addWidget(spacerLeftTop);
99 leftSidePane->addWidget(spacerLeftTop);
100 leftSidePane->addAction(openLeftInspectorAction);
100 leftSidePane->addAction(openLeftInspectorAction);
101 leftSidePane->addWidget(spacerLeftBottom);
101 leftSidePane->addWidget(spacerLeftBottom);
102
102
103
103
104 auto rightSidePane = m_Ui->rightInspectorSidePane->sidePane();
104 auto rightSidePane = m_Ui->rightInspectorSidePane->sidePane();
105 auto openRightInspectorAction = new QAction{QIcon{
105 auto openRightInspectorAction = new QAction{QIcon{
106 ":/icones/next.png",
106 ":/icones/next.png",
107 },
107 },
108 tr("Show/hide the right inspector"), this};
108 tr("Show/hide the right inspector"), this};
109
109
110 auto spacerRightTop = new QWidget{};
110 auto spacerRightTop = new QWidget{};
111 spacerRightTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
111 spacerRightTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
112
112
113 auto spacerRightBottom = new QWidget{};
113 auto spacerRightBottom = new QWidget{};
114 spacerRightBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
114 spacerRightBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
115
115
116 rightSidePane->addWidget(spacerRightTop);
116 rightSidePane->addWidget(spacerRightTop);
117 rightSidePane->addAction(openRightInspectorAction);
117 rightSidePane->addAction(openRightInspectorAction);
118 rightSidePane->addWidget(spacerRightBottom);
118 rightSidePane->addWidget(spacerRightBottom);
119
119
120 openLeftInspectorAction->setCheckable(true);
120 openLeftInspectorAction->setCheckable(true);
121 openRightInspectorAction->setCheckable(true);
121 openRightInspectorAction->setCheckable(true);
122
122
123 auto openInspector = [this](bool checked, bool right, auto action) {
123 auto openInspector = [this](bool checked, bool right, auto action) {
124
124
125 action->setIcon(QIcon{(checked xor right) ? ":/icones/next.png" : ":/icones/previous.png"});
125 action->setIcon(QIcon{(checked xor right) ? ":/icones/next.png" : ":/icones/previous.png"});
126
126
127 auto &lastInspectorSize
127 auto &lastInspectorSize
128 = right ? impl->m_LastOpenRightInspectorSize : impl->m_LastOpenLeftInspectorSize;
128 = right ? impl->m_LastOpenRightInspectorSize : impl->m_LastOpenLeftInspectorSize;
129
129
130 auto nextInspectorSize = right ? m_Ui->rightMainInspectorWidget->size()
130 auto nextInspectorSize = right ? m_Ui->rightMainInspectorWidget->size()
131 : m_Ui->leftMainInspectorWidget->size();
131 : m_Ui->leftMainInspectorWidget->size();
132
132
133 // Update of the last opened geometry
133 // Update of the last opened geometry
134 if (checked) {
134 if (checked) {
135 lastInspectorSize = nextInspectorSize;
135 lastInspectorSize = nextInspectorSize;
136 }
136 }
137
137
138 auto startSize = lastInspectorSize;
138 auto startSize = lastInspectorSize;
139 auto endSize = startSize;
139 auto endSize = startSize;
140 endSize.setWidth(0);
140 endSize.setWidth(0);
141
141
142 auto splitterInspectorIndex
142 auto splitterInspectorIndex
143 = right ? RIGHTMAININSPECTORWIDGETSPLITTERINDEX : LEFTMAININSPECTORWIDGETSPLITTERINDEX;
143 = right ? RIGHTMAININSPECTORWIDGETSPLITTERINDEX : LEFTMAININSPECTORWIDGETSPLITTERINDEX;
144
144
145 auto currentSizes = m_Ui->splitter->sizes();
145 auto currentSizes = m_Ui->splitter->sizes();
146 if (checked) {
146 if (checked) {
147 // adjust sizes individually here, e.g.
147 // adjust sizes individually here, e.g.
148 currentSizes[splitterInspectorIndex] -= lastInspectorSize.width();
148 currentSizes[splitterInspectorIndex] -= lastInspectorSize.width();
149 currentSizes[VIEWPLITTERINDEX] += lastInspectorSize.width();
149 currentSizes[VIEWPLITTERINDEX] += lastInspectorSize.width();
150 m_Ui->splitter->setSizes(currentSizes);
150 m_Ui->splitter->setSizes(currentSizes);
151 }
151 }
152 else {
152 else {
153 // adjust sizes individually here, e.g.
153 // adjust sizes individually here, e.g.
154 currentSizes[splitterInspectorIndex] += lastInspectorSize.width();
154 currentSizes[splitterInspectorIndex] += lastInspectorSize.width();
155 currentSizes[VIEWPLITTERINDEX] -= lastInspectorSize.width();
155 currentSizes[VIEWPLITTERINDEX] -= lastInspectorSize.width();
156 m_Ui->splitter->setSizes(currentSizes);
156 m_Ui->splitter->setSizes(currentSizes);
157 }
157 }
158
158
159 };
159 };
160
160
161
161
162 connect(openLeftInspectorAction, &QAction::triggered,
162 connect(openLeftInspectorAction, &QAction::triggered,
163 [openInspector, openLeftInspectorAction](bool checked) {
163 [openInspector, openLeftInspectorAction](bool checked) {
164 openInspector(checked, false, openLeftInspectorAction);
164 openInspector(checked, false, openLeftInspectorAction);
165 });
165 });
166 connect(openRightInspectorAction, &QAction::triggered,
166 connect(openRightInspectorAction, &QAction::triggered,
167 [openInspector, openRightInspectorAction](bool checked) {
167 [openInspector, openRightInspectorAction](bool checked) {
168 openInspector(checked, true, openRightInspectorAction);
168 openInspector(checked, true, openRightInspectorAction);
169 });
169 });
170
170
171 // //// //
171 // //// //
172 // Menu //
172 // Menu //
173 // //// //
173 // //// //
174 this->menuBar()->addAction(tr("File"));
174 this->menuBar()->addAction(tr("File"));
175 auto toolsMenu = this->menuBar()->addMenu(tr("Tools"));
175 auto toolsMenu = this->menuBar()->addMenu(tr("Tools"));
176 toolsMenu->addAction(tr("Settings..."), [this]() {
176 toolsMenu->addAction(tr("Settings..."), [this]() {
177 // Loads settings
177 // Loads settings
178 impl->m_SettingsDialog->loadSettings();
178 impl->m_SettingsDialog->loadSettings();
179
179
180 // Open settings dialog and save settings if the dialog is accepted
180 // Open settings dialog and save settings if the dialog is accepted
181 if (impl->m_SettingsDialog->exec() == QDialog::Accepted) {
181 if (impl->m_SettingsDialog->exec() == QDialog::Accepted) {
182 impl->m_SettingsDialog->saveSettings();
182 impl->m_SettingsDialog->saveSettings();
183 }
183 }
184
184
185 });
185 });
186
186
187 auto mainToolBar = this->addToolBar(QStringLiteral("MainToolBar"));
187 auto mainToolBar = this->addToolBar(QStringLiteral("MainToolBar"));
188
188
189 auto timeWidget = new TimeWidget{};
189 auto timeWidget = new TimeWidget{};
190 mainToolBar->addWidget(timeWidget);
190 mainToolBar->addWidget(timeWidget);
191
191
192 // //////// //
192 // //////// //
193 // Settings //
193 // Settings //
194 // //////// //
194 // //////// //
195
195
196 // Registers "general settings" widget to the settings dialog
196 // Registers "general settings" widget to the settings dialog
197 impl->m_SettingsDialog->registerWidget(QStringLiteral("General"),
197 impl->m_SettingsDialog->registerWidget(QStringLiteral("General"),
198 impl->m_GeneralSettingsWidget);
198 impl->m_GeneralSettingsWidget);
199
199
200 // /////////// //
200 // /////////// //
201 // Connections //
201 // Connections //
202 // /////////// //
202 // /////////// //
203
203
204 // Controllers / controllers connections
204 // Controllers / controllers connections
205 connect(&sqpApp->timeController(), SIGNAL(timeUpdated(SqpDateTime)),
205 connect(&sqpApp->timeController(), SIGNAL(timeUpdated(SqpRange)), &sqpApp->variableController(),
206 &sqpApp->variableController(), SLOT(onDateTimeOnSelection(SqpDateTime)));
206 SLOT(onDateTimeOnSelection(SqpRange)));
207
207
208 // Widgets / controllers connections
208 // Widgets / controllers connections
209
209
210 // DataSource
210 // DataSource
211 connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem *)),
211 connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem *)),
212 m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem *)));
212 m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem *)));
213
213
214 // Time
214 // Time
215 connect(timeWidget, SIGNAL(timeUpdated(SqpDateTime)), &sqpApp->timeController(),
215 connect(timeWidget, SIGNAL(timeUpdated(SqpRange)), &sqpApp->timeController(),
216 SLOT(onTimeToUpdate(SqpDateTime)));
216 SLOT(onTimeToUpdate(SqpRange)));
217
217
218 // Visualization
218 // Visualization
219 connect(&sqpApp->visualizationController(),
219 connect(&sqpApp->visualizationController(),
220 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), m_Ui->view,
220 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), m_Ui->view,
221 SLOT(onVariableAboutToBeDeleted(std::shared_ptr<Variable>)));
221 SLOT(onVariableAboutToBeDeleted(std::shared_ptr<Variable>)));
222
222
223 connect(&sqpApp->visualizationController(),
223 connect(&sqpApp->visualizationController(),
224 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpDateTime &)), m_Ui->view,
224 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpRange &)), m_Ui->view,
225 SLOT(onRangeChanged(std::shared_ptr<Variable>, const SqpDateTime &)));
225 SLOT(onRangeChanged(std::shared_ptr<Variable>, const SqpRange &)));
226
226
227 // Widgets / widgets connections
227 // Widgets / widgets connections
228
228
229 // For the following connections, we use DirectConnection to allow each widget that can
229 // For the following connections, we use DirectConnection to allow each widget that can
230 // potentially attach a menu to the variable's menu to do so before this menu is displayed.
230 // potentially attach a menu to the variable's menu to do so before this menu is displayed.
231 // The order of connections is also important, since it determines the order in which each
231 // The order of connections is also important, since it determines the order in which each
232 // widget will attach its menu
232 // widget will attach its menu
233 connect(
233 connect(
234 m_Ui->variableInspectorWidget,
234 m_Ui->variableInspectorWidget,
235 SIGNAL(tableMenuAboutToBeDisplayed(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
235 SIGNAL(tableMenuAboutToBeDisplayed(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
236 m_Ui->view, SLOT(attachVariableMenu(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
236 m_Ui->view, SLOT(attachVariableMenu(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
237 Qt::DirectConnection);
237 Qt::DirectConnection);
238 }
238 }
239
239
240 MainWindow::~MainWindow()
240 MainWindow::~MainWindow()
241 {
241 {
242 }
242 }
243
243
244 void MainWindow::changeEvent(QEvent *e)
244 void MainWindow::changeEvent(QEvent *e)
245 {
245 {
246 QMainWindow::changeEvent(e);
246 QMainWindow::changeEvent(e);
247 switch (e->type()) {
247 switch (e->type()) {
248 case QEvent::LanguageChange:
248 case QEvent::LanguageChange:
249 m_Ui->retranslateUi(this);
249 m_Ui->retranslateUi(this);
250 break;
250 break;
251 default:
251 default:
252 break;
252 break;
253 }
253 }
254 }
254 }
@@ -1,18 +1,18
1 #ifndef SCIQLOP_DATAPROVIDERPARAMETERS_H
1 #ifndef SCIQLOP_DATAPROVIDERPARAMETERS_H
2 #define SCIQLOP_DATAPROVIDERPARAMETERS_H
2 #define SCIQLOP_DATAPROVIDERPARAMETERS_H
3
3
4 #include "SqpDateTime.h"
4 #include "SqpRange.h"
5
5
6 /**
6 /**
7 * @brief The DataProviderParameters struct holds the information needed to retrieve data from a
7 * @brief The DataProviderParameters struct holds the information needed to retrieve data from a
8 * data provider
8 * data provider
9 * @sa IDataProvider
9 * @sa IDataProvider
10 */
10 */
11 struct DataProviderParameters {
11 struct DataProviderParameters {
12 /// Times for which retrieve data
12 /// Times for which retrieve data
13 QVector<SqpDateTime> m_Times;
13 QVector<SqpRange> m_Times;
14 /// Extra data that can be used by the provider to retrieve data
14 /// Extra data that can be used by the provider to retrieve data
15 QVariantHash m_Data;
15 QVariantHash m_Data;
16 };
16 };
17
17
18 #endif // SCIQLOP_DATAPROVIDERPARAMETERS_H
18 #endif // SCIQLOP_DATAPROVIDERPARAMETERS_H
@@ -1,74 +1,74
1 #ifndef SCIQLOP_IDATAPROVIDER_H
1 #ifndef SCIQLOP_IDATAPROVIDER_H
2 #define SCIQLOP_IDATAPROVIDER_H
2 #define SCIQLOP_IDATAPROVIDER_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <memory>
6 #include <memory>
7
7
8 #include <QObject>
8 #include <QObject>
9 #include <QUuid>
9 #include <QUuid>
10
10
11 #include <Common/MetaTypes.h>
11 #include <Common/MetaTypes.h>
12
12
13 #include <Data/SqpDateTime.h>
13 #include <Data/SqpRange.h>
14
14
15 #include <functional>
15 #include <functional>
16
16
17 class DataProviderParameters;
17 class DataProviderParameters;
18 class IDataSeries;
18 class IDataSeries;
19 class QNetworkReply;
19 class QNetworkReply;
20 class QNetworkRequest;
20 class QNetworkRequest;
21
21
22 /**
22 /**
23 * @brief The IDataProvider interface aims to declare a data provider.
23 * @brief The IDataProvider interface aims to declare a data provider.
24 *
24 *
25 * A data provider is an entity that generates data and returns it according to various parameters
25 * A data provider is an entity that generates data and returns it according to various parameters
26 * (time interval, product to retrieve the data, etc.)
26 * (time interval, product to retrieve the data, etc.)
27 *
27 *
28 * @sa IDataSeries
28 * @sa IDataSeries
29 */
29 */
30 class SCIQLOP_CORE_EXPORT IDataProvider : public QObject {
30 class SCIQLOP_CORE_EXPORT IDataProvider : public QObject {
31
31
32 Q_OBJECT
32 Q_OBJECT
33 public:
33 public:
34 virtual ~IDataProvider() noexcept = default;
34 virtual ~IDataProvider() noexcept = default;
35
35
36 /**
36 /**
37 * @brief requestDataLoading provide datas for the data identified by identifier and parameters
37 * @brief requestDataLoading provide datas for the data identified by identifier and parameters
38 */
38 */
39 virtual void requestDataLoading(QUuid identifier, const DataProviderParameters &parameters) = 0;
39 virtual void requestDataLoading(QUuid identifier, const DataProviderParameters &parameters) = 0;
40
40
41 /**
41 /**
42 * @brief requestDataAborting stop data loading of the data identified by identifier
42 * @brief requestDataAborting stop data loading of the data identified by identifier
43 */
43 */
44 virtual void requestDataAborting(QUuid identifier) = 0;
44 virtual void requestDataAborting(QUuid identifier) = 0;
45
45
46 signals:
46 signals:
47 /**
47 /**
48 * @brief dataProvided send dataSeries under dateTime and that corresponds of the data
48 * @brief dataProvided send dataSeries under dateTime and that corresponds of the data
49 * identified by identifier
49 * identified by identifier
50 */
50 */
51 void dataProvided(QUuid identifier, std::shared_ptr<IDataSeries> dateSerie,
51 void dataProvided(QUuid identifier, std::shared_ptr<IDataSeries> dateSerie,
52 const SqpDateTime &dateTime);
52 const SqpRange &dateTime);
53
53
54 /**
54 /**
55 * @brief dataProvided send dataSeries under dateTime and that corresponds of the data
55 * @brief dataProvided send dataSeries under dateTime and that corresponds of the data
56 * identified by identifier
56 * identified by identifier
57 */
57 */
58 void dataProvidedProgress(QUuid identifier, double progress);
58 void dataProvidedProgress(QUuid identifier, double progress);
59
59
60
60
61 /**
61 /**
62 * @brief requestConstructed send a request for the data identified by identifier
62 * @brief requestConstructed send a request for the data identified by identifier
63 * @callback is the methode call by the reply of the request when it is finished.
63 * @callback is the methode call by the reply of the request when it is finished.
64 */
64 */
65 void requestConstructed(const QNetworkRequest &request, QUuid identifier,
65 void requestConstructed(const QNetworkRequest &request, QUuid identifier,
66 std::function<void(QNetworkReply *, QUuid)> callback);
66 std::function<void(QNetworkReply *, QUuid)> callback);
67 };
67 };
68
68
69 // Required for using shared_ptr in signals/slots
69 // Required for using shared_ptr in signals/slots
70 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_PTR_REGISTRY, std::shared_ptr<IDataProvider>)
70 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_PTR_REGISTRY, std::shared_ptr<IDataProvider>)
71 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_FUNCTION_REGISTRY,
71 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_FUNCTION_REGISTRY,
72 std::function<void(QNetworkReply *, QUuid)>)
72 std::function<void(QNetworkReply *, QUuid)>)
73
73
74 #endif // SCIQLOP_IDATAPROVIDER_H
74 #endif // SCIQLOP_IDATAPROVIDER_H
@@ -1,43 +1,43
1 #ifndef SCIQLOP_SQPDATETIME_H
1 #ifndef SCIQLOP_SQPRANGE_H
2 #define SCIQLOP_SQPDATETIME_H
2 #define SCIQLOP_SQPRANGE_H
3
3
4 #include <QObject>
4 #include <QObject>
5
5
6 #include <QDebug>
6 #include <QDebug>
7
7
8 #include <Common/DateUtils.h>
8 #include <Common/DateUtils.h>
9 #include <Common/MetaTypes.h>
9 #include <Common/MetaTypes.h>
10
10
11 /**
11 /**
12 * @brief The SqpDateTime struct holds the information of time parameters
12 * @brief The SqpRange struct holds the information of time parameters
13 */
13 */
14 struct SqpDateTime {
14 struct SqpRange {
15 /// Start time (UTC)
15 /// Start time (UTC)
16 double m_TStart;
16 double m_TStart;
17 /// End time (UTC)
17 /// End time (UTC)
18 double m_TEnd;
18 double m_TEnd;
19
19
20 bool contains(const SqpDateTime &dateTime) const noexcept
20 bool contains(const SqpRange &dateTime) const noexcept
21 {
21 {
22 return (m_TStart <= dateTime.m_TStart && m_TEnd >= dateTime.m_TEnd);
22 return (m_TStart <= dateTime.m_TStart && m_TEnd >= dateTime.m_TEnd);
23 }
23 }
24
24
25 bool intersect(const SqpDateTime &dateTime) const noexcept
25 bool intersect(const SqpRange &dateTime) const noexcept
26 {
26 {
27 return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd);
27 return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd);
28 }
28 }
29 };
29 };
30
30
31 inline QDebug operator<<(QDebug d, SqpDateTime obj)
31 inline QDebug operator<<(QDebug d, SqpRange obj)
32 {
32 {
33 auto tendDateTimeStart = DateUtils::dateTime(obj.m_TStart);
33 auto tendDateTimeStart = DateUtils::dateTime(obj.m_TStart);
34 auto tendDateTimeEnd = DateUtils::dateTime(obj.m_TEnd);
34 auto tendDateTimeEnd = DateUtils::dateTime(obj.m_TEnd);
35
35
36 d << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
36 d << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
37 return d;
37 return d;
38 }
38 }
39
39
40 // Required for using shared_ptr in signals/slots
40 // Required for using shared_ptr in signals/slots
41 SCIQLOP_REGISTER_META_TYPE(SQPDATETIME_REGISTRY, SqpDateTime)
41 SCIQLOP_REGISTER_META_TYPE(SQPRANGE_REGISTRY, SqpRange)
42
42
43 #endif // SCIQLOP_SQPDATETIME_H
43 #endif // SCIQLOP_SQPRANGE_H
@@ -1,42 +1,42
1 #ifndef SCIQLOP_TIMECONTROLLER_H
1 #ifndef SCIQLOP_TIMECONTROLLER_H
2 #define SCIQLOP_TIMECONTROLLER_H
2 #define SCIQLOP_TIMECONTROLLER_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/SqpDateTime.h>
6 #include <Data/SqpRange.h>
7
7
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9 #include <QObject>
9 #include <QObject>
10
10
11 #include <Common/spimpl.h>
11 #include <Common/spimpl.h>
12
12
13
13
14 Q_DECLARE_LOGGING_CATEGORY(LOG_TimeController)
14 Q_DECLARE_LOGGING_CATEGORY(LOG_TimeController)
15
15
16 /**
16 /**
17 * @brief The TimeController class aims to handle the Time parameters notification in SciQlop.
17 * @brief The TimeController class aims to handle the Time parameters notification in SciQlop.
18 */
18 */
19 class SCIQLOP_CORE_EXPORT TimeController : public QObject {
19 class SCIQLOP_CORE_EXPORT TimeController : public QObject {
20 Q_OBJECT
20 Q_OBJECT
21 public:
21 public:
22 explicit TimeController(QObject *parent = 0);
22 explicit TimeController(QObject *parent = 0);
23
23
24 SqpDateTime dateTime() const noexcept;
24 SqpRange dateTime() const noexcept;
25
25
26 signals:
26 signals:
27 /// Signal emitted to notify that time parameters has beed updated
27 /// Signal emitted to notify that time parameters has beed updated
28 void timeUpdated(SqpDateTime time);
28 void timeUpdated(SqpRange time);
29
29
30 public slots:
30 public slots:
31 /// Slot called when a new dateTime has been defined.
31 /// Slot called when a new dateTime has been defined.
32 void onTimeToUpdate(SqpDateTime dateTime);
32 void onTimeToUpdate(SqpRange dateTime);
33
33
34 /// Slot called when the dateTime has to be notified. Call timeUpdated signal
34 /// Slot called when the dateTime has to be notified. Call timeUpdated signal
35 void onTimeNotify();
35 void onTimeNotify();
36
36
37 private:
37 private:
38 class TimeControllerPrivate;
38 class TimeControllerPrivate;
39 spimpl::unique_impl_ptr<TimeControllerPrivate> impl;
39 spimpl::unique_impl_ptr<TimeControllerPrivate> impl;
40 };
40 };
41
41
42 #endif // SCIQLOP_TIMECONTROLLER_H
42 #endif // SCIQLOP_TIMECONTROLLER_H
@@ -1,57 +1,57
1 #ifndef SCIQLOP_VARIABLE_H
1 #ifndef SCIQLOP_VARIABLE_H
2 #define SCIQLOP_VARIABLE_H
2 #define SCIQLOP_VARIABLE_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/SqpDateTime.h>
6 #include <Data/SqpRange.h>
7
7
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9 #include <QObject>
9 #include <QObject>
10
10
11 #include <Common/MetaTypes.h>
11 #include <Common/MetaTypes.h>
12 #include <Common/spimpl.h>
12 #include <Common/spimpl.h>
13
13
14 Q_DECLARE_LOGGING_CATEGORY(LOG_Variable)
14 Q_DECLARE_LOGGING_CATEGORY(LOG_Variable)
15
15
16 class IDataSeries;
16 class IDataSeries;
17 class QString;
17 class QString;
18
18
19 /**
19 /**
20 * @brief The Variable class represents a variable in SciQlop.
20 * @brief The Variable class represents a variable in SciQlop.
21 */
21 */
22 class SCIQLOP_CORE_EXPORT Variable : public QObject {
22 class SCIQLOP_CORE_EXPORT Variable : public QObject {
23
23
24 Q_OBJECT
24 Q_OBJECT
25
25
26 public:
26 public:
27 explicit Variable(const QString &name, const SqpDateTime &dateTime,
27 explicit Variable(const QString &name, const SqpRange &dateTime,
28 const QVariantHash &metadata = {});
28 const QVariantHash &metadata = {});
29
29
30 QString name() const noexcept;
30 QString name() const noexcept;
31 SqpDateTime dateTime() const noexcept;
31 SqpRange dateTime() const noexcept;
32 void setDateTime(const SqpDateTime &dateTime) noexcept;
32 void setDateTime(const SqpRange &dateTime) noexcept;
33
33
34 /// @return the data of the variable, nullptr if there is no data
34 /// @return the data of the variable, nullptr if there is no data
35 IDataSeries *dataSeries() const noexcept;
35 IDataSeries *dataSeries() const noexcept;
36
36
37 QVariantHash metadata() const noexcept;
37 QVariantHash metadata() const noexcept;
38
38
39 bool contains(const SqpDateTime &dateTime) const noexcept;
39 bool contains(const SqpRange &dateTime) const noexcept;
40 bool intersect(const SqpDateTime &dateTime) const noexcept;
40 bool intersect(const SqpRange &dateTime) const noexcept;
41 bool isInside(const SqpDateTime &dateTime) const noexcept;
41 bool isInside(const SqpRange &dateTime) const noexcept;
42
42
43 public slots:
43 public slots:
44 void setDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept;
44 void setDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept;
45
45
46 signals:
46 signals:
47 void updated();
47 void updated();
48
48
49 private:
49 private:
50 class VariablePrivate;
50 class VariablePrivate;
51 spimpl::unique_impl_ptr<VariablePrivate> impl;
51 spimpl::unique_impl_ptr<VariablePrivate> impl;
52 };
52 };
53
53
54 // Required for using shared_ptr in signals/slots
54 // Required for using shared_ptr in signals/slots
55 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
55 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
56
56
57 #endif // SCIQLOP_VARIABLE_H
57 #endif // SCIQLOP_VARIABLE_H
@@ -1,45 +1,45
1 #ifndef SCIQLOP_VARIABLECACHECONTROLLER_H
1 #ifndef SCIQLOP_VARIABLECACHECONTROLLER_H
2 #define SCIQLOP_VARIABLECACHECONTROLLER_H
2 #define SCIQLOP_VARIABLECACHECONTROLLER_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <QLoggingCategory>
6 #include <QLoggingCategory>
7 #include <QObject>
7 #include <QObject>
8
8
9 #include <Data/SqpDateTime.h>
9 #include <Data/SqpRange.h>
10
10
11 #include <QLoggingCategory>
11 #include <QLoggingCategory>
12
12
13 #include <Common/spimpl.h>
13 #include <Common/spimpl.h>
14
14
15 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableCacheController)
15 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableCacheController)
16
16
17 class Variable;
17 class Variable;
18
18
19 /// This class aims to store in the cache all of the dateTime already requested to the variable.
19 /// This class aims to store in the cache all of the dateTime already requested to the variable.
20 class SCIQLOP_CORE_EXPORT VariableCacheController : public QObject {
20 class SCIQLOP_CORE_EXPORT VariableCacheController : public QObject {
21 Q_OBJECT
21 Q_OBJECT
22 public:
22 public:
23 explicit VariableCacheController(QObject *parent = 0);
23 explicit VariableCacheController(QObject *parent = 0);
24
24
25
25
26 void addDateTime(std::shared_ptr<Variable> variable, const SqpDateTime &dateTime);
26 void addDateTime(std::shared_ptr<Variable> variable, const SqpRange &dateTime);
27
27
28 /// Clears cache concerning a variable
28 /// Clears cache concerning a variable
29 void clear(std::shared_ptr<Variable> variable) noexcept;
29 void clear(std::shared_ptr<Variable> variable) noexcept;
30
30
31 /// Return all of the SqpDataTime part of the dateTime whose are not in the cache
31 /// Return all of the SqpDataTime part of the dateTime whose are not in the cache
32 QVector<SqpDateTime> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
32 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
33 const SqpDateTime &dateTime);
33 const SqpRange &dateTime);
34
34
35
35
36 QVector<SqpDateTime> dateCacheList(std::shared_ptr<Variable> variable) const noexcept;
36 QVector<SqpRange> dateCacheList(std::shared_ptr<Variable> variable) const noexcept;
37
37
38 void displayCache(std::shared_ptr<Variable> variable) const;
38 void displayCache(std::shared_ptr<Variable> variable) const;
39
39
40 private:
40 private:
41 class VariableCacheControllerPrivate;
41 class VariableCacheControllerPrivate;
42 spimpl::unique_impl_ptr<VariableCacheControllerPrivate> impl;
42 spimpl::unique_impl_ptr<VariableCacheControllerPrivate> impl;
43 };
43 };
44
44
45 #endif // SCIQLOP_VARIABLECACHECONTROLLER_H
45 #endif // SCIQLOP_VARIABLECACHECONTROLLER_H
@@ -1,97 +1,97
1 #ifndef SCIQLOP_VARIABLECONTROLLER_H
1 #ifndef SCIQLOP_VARIABLECONTROLLER_H
2 #define SCIQLOP_VARIABLECONTROLLER_H
2 #define SCIQLOP_VARIABLECONTROLLER_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/SqpDateTime.h>
6 #include <Data/SqpRange.h>
7
7
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9 #include <QObject>
9 #include <QObject>
10
10
11 #include <Common/spimpl.h>
11 #include <Common/spimpl.h>
12
12
13 class IDataProvider;
13 class IDataProvider;
14 class QItemSelectionModel;
14 class QItemSelectionModel;
15 class TimeController;
15 class TimeController;
16 class Variable;
16 class Variable;
17 class VariableModel;
17 class VariableModel;
18
18
19 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableController)
19 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableController)
20
20
21 /**
21 /**
22 * @brief The VariableController class aims to handle the variables in SciQlop.
22 * @brief The VariableController class aims to handle the variables in SciQlop.
23 */
23 */
24 class SCIQLOP_CORE_EXPORT VariableController : public QObject {
24 class SCIQLOP_CORE_EXPORT VariableController : public QObject {
25 Q_OBJECT
25 Q_OBJECT
26 public:
26 public:
27 explicit VariableController(QObject *parent = 0);
27 explicit VariableController(QObject *parent = 0);
28 virtual ~VariableController();
28 virtual ~VariableController();
29
29
30 VariableModel *variableModel() noexcept;
30 VariableModel *variableModel() noexcept;
31 QItemSelectionModel *variableSelectionModel() noexcept;
31 QItemSelectionModel *variableSelectionModel() noexcept;
32
32
33 void setTimeController(TimeController *timeController) noexcept;
33 void setTimeController(TimeController *timeController) noexcept;
34
34
35 /**
35 /**
36 * Deletes from the controller the variable passed in parameter.
36 * Deletes from the controller the variable passed in parameter.
37 *
37 *
38 * Delete a variable includes:
38 * Delete a variable includes:
39 * - the deletion of the various references to the variable in SciQlop
39 * - the deletion of the various references to the variable in SciQlop
40 * - the deletion of the model variable
40 * - the deletion of the model variable
41 * - the deletion of the provider associated with the variable
41 * - the deletion of the provider associated with the variable
42 * - removing the cache associated with the variable
42 * - removing the cache associated with the variable
43 *
43 *
44 * @param variable the variable to delete from the controller.
44 * @param variable the variable to delete from the controller.
45 */
45 */
46 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
46 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
47
47
48 /**
48 /**
49 * Deletes from the controller the variables passed in parameter.
49 * Deletes from the controller the variables passed in parameter.
50 * @param variables the variables to delete from the controller.
50 * @param variables the variables to delete from the controller.
51 * @sa deleteVariable()
51 * @sa deleteVariable()
52 */
52 */
53 void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept;
53 void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept;
54
54
55 /**
55 /**
56 * @brief abort the variable retrieve data progression
56 * @brief abort the variable retrieve data progression
57 */
57 */
58 void abortProgress(std::shared_ptr<Variable> variable);
58 void abortProgress(std::shared_ptr<Variable> variable);
59
59
60 signals:
60 signals:
61 /// Signal emitted when a variable is about to be deleted from the controller
61 /// Signal emitted when a variable is about to be deleted from the controller
62 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
62 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
63
63
64 /// Signal emitted when a data acquisition is requested on a range for a variable
64 /// Signal emitted when a data acquisition is requested on a range for a variable
65 void rangeChanged(std::shared_ptr<Variable> variable, const SqpDateTime &range);
65 void rangeChanged(std::shared_ptr<Variable> variable, const SqpRange &range);
66
66
67 public slots:
67 public slots:
68 /// Request the data loading of the variable whithin dateTime
68 /// Request the data loading of the variable whithin dateTime
69 void onRequestDataLoading(std::shared_ptr<Variable> variable, const SqpDateTime &dateTime);
69 void onRequestDataLoading(std::shared_ptr<Variable> variable, const SqpRange &dateTime);
70 /**
70 /**
71 * Creates a new variable and adds it to the model
71 * Creates a new variable and adds it to the model
72 * @param name the name of the new variable
72 * @param name the name of the new variable
73 * @param metadata the metadata of the new variable
73 * @param metadata the metadata of the new variable
74 * @param provider the data provider for the new variable
74 * @param provider the data provider for the new variable
75 */
75 */
76 void createVariable(const QString &name, const QVariantHash &metadata,
76 void createVariable(const QString &name, const QVariantHash &metadata,
77 std::shared_ptr<IDataProvider> provider) noexcept;
77 std::shared_ptr<IDataProvider> provider) noexcept;
78
78
79 /// Update the temporal parameters of every selected variable to dateTime
79 /// Update the temporal parameters of every selected variable to dateTime
80 void onDateTimeOnSelection(const SqpDateTime &dateTime);
80 void onDateTimeOnSelection(const SqpRange &dateTime);
81
81
82
82
83 void onVariableRetrieveDataInProgress(QUuid identifier, double progress);
83 void onVariableRetrieveDataInProgress(QUuid identifier, double progress);
84
84
85 void onAbortProgressRequested(std::shared_ptr<Variable> variable);
85 void onAbortProgressRequested(std::shared_ptr<Variable> variable);
86
86
87 void initialize();
87 void initialize();
88 void finalize();
88 void finalize();
89
89
90 private:
90 private:
91 void waitForFinish();
91 void waitForFinish();
92
92
93 class VariableControllerPrivate;
93 class VariableControllerPrivate;
94 spimpl::unique_impl_ptr<VariableControllerPrivate> impl;
94 spimpl::unique_impl_ptr<VariableControllerPrivate> impl;
95 };
95 };
96
96
97 #endif // SCIQLOP_VARIABLECONTROLLER_H
97 #endif // SCIQLOP_VARIABLECONTROLLER_H
@@ -1,80 +1,80
1 #ifndef SCIQLOP_VARIABLEMODEL_H
1 #ifndef SCIQLOP_VARIABLEMODEL_H
2 #define SCIQLOP_VARIABLEMODEL_H
2 #define SCIQLOP_VARIABLEMODEL_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/SqpDateTime.h>
6 #include <Data/SqpRange.h>
7
7
8 #include <QAbstractTableModel>
8 #include <QAbstractTableModel>
9 #include <QLoggingCategory>
9 #include <QLoggingCategory>
10
10
11 #include <Common/MetaTypes.h>
11 #include <Common/MetaTypes.h>
12 #include <Common/spimpl.h>
12 #include <Common/spimpl.h>
13
13
14 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableModel)
14 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableModel)
15
15
16 enum VariableRoles { ProgressRole = Qt::UserRole };
16 enum VariableRoles { ProgressRole = Qt::UserRole };
17
17
18
18
19 class IDataSeries;
19 class IDataSeries;
20 class Variable;
20 class Variable;
21
21
22 /**
22 /**
23 * @brief The VariableModel class aims to hold the variables that have been created in SciQlop
23 * @brief The VariableModel class aims to hold the variables that have been created in SciQlop
24 */
24 */
25 class SCIQLOP_CORE_EXPORT VariableModel : public QAbstractTableModel {
25 class SCIQLOP_CORE_EXPORT VariableModel : public QAbstractTableModel {
26 Q_OBJECT
26 Q_OBJECT
27 public:
27 public:
28 explicit VariableModel(QObject *parent = nullptr);
28 explicit VariableModel(QObject *parent = nullptr);
29
29
30 /**
30 /**
31 * Creates a new variable in the model
31 * Creates a new variable in the model
32 * @param name the name of the new variable
32 * @param name the name of the new variable
33 * @param dateTime the dateTime of the new variable
33 * @param dateTime the dateTime of the new variable
34 * @param metadata the metadata associated to the new variable
34 * @param metadata the metadata associated to the new variable
35 * @return the pointer to the new variable
35 * @return the pointer to the new variable
36 */
36 */
37 std::shared_ptr<Variable> createVariable(const QString &name, const SqpDateTime &dateTime,
37 std::shared_ptr<Variable> createVariable(const QString &name, const SqpRange &dateTime,
38 const QVariantHash &metadata) noexcept;
38 const QVariantHash &metadata) noexcept;
39
39
40 /**
40 /**
41 * Deletes a variable from the model, if it exists
41 * Deletes a variable from the model, if it exists
42 * @param variable the variable to delete
42 * @param variable the variable to delete
43 */
43 */
44 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
44 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
45
45
46
46
47 std::shared_ptr<Variable> variable(int index) const;
47 std::shared_ptr<Variable> variable(int index) const;
48
48
49 void setDataProgress(std::shared_ptr<Variable> variable, double progress);
49 void setDataProgress(std::shared_ptr<Variable> variable, double progress);
50
50
51
51
52 // /////////////////////////// //
52 // /////////////////////////// //
53 // QAbstractTableModel methods //
53 // QAbstractTableModel methods //
54 // /////////////////////////// //
54 // /////////////////////////// //
55
55
56 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
56 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
57 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
57 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
58 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
58 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
59 virtual QVariant headerData(int section, Qt::Orientation orientation,
59 virtual QVariant headerData(int section, Qt::Orientation orientation,
60 int role = Qt::DisplayRole) const override;
60 int role = Qt::DisplayRole) const override;
61
61
62
62
63 void abortProgress(const QModelIndex &index);
63 void abortProgress(const QModelIndex &index);
64
64
65 signals:
65 signals:
66 void abortProgessRequested(std::shared_ptr<Variable> variable);
66 void abortProgessRequested(std::shared_ptr<Variable> variable);
67
67
68 private:
68 private:
69 class VariableModelPrivate;
69 class VariableModelPrivate;
70 spimpl::unique_impl_ptr<VariableModelPrivate> impl;
70 spimpl::unique_impl_ptr<VariableModelPrivate> impl;
71
71
72 private slots:
72 private slots:
73 /// Slot called when data of a variable has been updated
73 /// Slot called when data of a variable has been updated
74 void onVariableUpdated() noexcept;
74 void onVariableUpdated() noexcept;
75 };
75 };
76
76
77 // Registers QVector<int> metatype so it can be used in VariableModel::dataChanged() signal
77 // Registers QVector<int> metatype so it can be used in VariableModel::dataChanged() signal
78 SCIQLOP_REGISTER_META_TYPE(QVECTOR_INT_REGISTRY, QVector<int>)
78 SCIQLOP_REGISTER_META_TYPE(QVECTOR_INT_REGISTRY, QVector<int>)
79
79
80 #endif // SCIQLOP_VARIABLEMODEL_H
80 #endif // SCIQLOP_VARIABLEMODEL_H
@@ -1,51 +1,51
1 #ifndef SCIQLOP_VISUALIZATIONCONTROLLER_H
1 #ifndef SCIQLOP_VISUALIZATIONCONTROLLER_H
2 #define SCIQLOP_VISUALIZATIONCONTROLLER_H
2 #define SCIQLOP_VISUALIZATIONCONTROLLER_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/SqpDateTime.h>
6 #include <Data/SqpRange.h>
7
7
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9 #include <QObject>
9 #include <QObject>
10 #include <QUuid>
10 #include <QUuid>
11
11
12 #include <Common/spimpl.h>
12 #include <Common/spimpl.h>
13
13
14 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationController)
14 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationController)
15
15
16 class DataSourceItem;
16 class DataSourceItem;
17 class Variable;
17 class Variable;
18
18
19 /**
19 /**
20 * @brief The VisualizationController class aims to make the link between SciQlop and its plugins.
20 * @brief The VisualizationController class aims to make the link between SciQlop and its plugins.
21 * This is the intermediate class that SciQlop has to use in the way to connect a data source.
21 * This is the intermediate class that SciQlop has to use in the way to connect a data source.
22 * Please first use register method to initialize a plugin specified by its metadata name (JSON
22 * Please first use register method to initialize a plugin specified by its metadata name (JSON
23 * plugin source) then others specifics method will be able to access it. You can load a data source
23 * plugin source) then others specifics method will be able to access it. You can load a data source
24 * driver plugin then create a data source.
24 * driver plugin then create a data source.
25 */
25 */
26 class SCIQLOP_CORE_EXPORT VisualizationController : public QObject {
26 class SCIQLOP_CORE_EXPORT VisualizationController : public QObject {
27 Q_OBJECT
27 Q_OBJECT
28 public:
28 public:
29 explicit VisualizationController(QObject *parent = 0);
29 explicit VisualizationController(QObject *parent = 0);
30 virtual ~VisualizationController();
30 virtual ~VisualizationController();
31
31
32 signals:
32 signals:
33 /// Signal emitted when a variable is about to be deleted from SciQlop
33 /// Signal emitted when a variable is about to be deleted from SciQlop
34 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
34 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
35
35
36 /// Signal emitted when a data acquisition is requested on a range for a variable
36 /// Signal emitted when a data acquisition is requested on a range for a variable
37 void rangeChanged(std::shared_ptr<Variable> variable, const SqpDateTime &range);
37 void rangeChanged(std::shared_ptr<Variable> variable, const SqpRange &range);
38
38
39 public slots:
39 public slots:
40 /// Manage init/end of the controller
40 /// Manage init/end of the controller
41 void initialize();
41 void initialize();
42 void finalize();
42 void finalize();
43
43
44 private:
44 private:
45 void waitForFinish();
45 void waitForFinish();
46
46
47 class VisualizationControllerPrivate;
47 class VisualizationControllerPrivate;
48 spimpl::unique_impl_ptr<VisualizationControllerPrivate> impl;
48 spimpl::unique_impl_ptr<VisualizationControllerPrivate> impl;
49 };
49 };
50
50
51 #endif // SCIQLOP_VISUALIZATIONCONTROLLER_H
51 #endif // SCIQLOP_VISUALIZATIONCONTROLLER_H
@@ -1,29 +1,29
1 #include "Time/TimeController.h"
1 #include "Time/TimeController.h"
2
2
3 Q_LOGGING_CATEGORY(LOG_TimeController, "TimeController")
3 Q_LOGGING_CATEGORY(LOG_TimeController, "TimeController")
4
4
5 struct TimeController::TimeControllerPrivate {
5 struct TimeController::TimeControllerPrivate {
6
6
7 SqpDateTime m_DateTime;
7 SqpRange m_DateTime;
8 };
8 };
9
9
10 TimeController::TimeController(QObject *parent)
10 TimeController::TimeController(QObject *parent)
11 : QObject{parent}, impl{spimpl::make_unique_impl<TimeControllerPrivate>()}
11 : QObject{parent}, impl{spimpl::make_unique_impl<TimeControllerPrivate>()}
12 {
12 {
13 qCDebug(LOG_TimeController()) << tr("TimeController construction");
13 qCDebug(LOG_TimeController()) << tr("TimeController construction");
14 }
14 }
15
15
16 SqpDateTime TimeController::dateTime() const noexcept
16 SqpRange TimeController::dateTime() const noexcept
17 {
17 {
18 return impl->m_DateTime;
18 return impl->m_DateTime;
19 }
19 }
20
20
21 void TimeController::onTimeToUpdate(SqpDateTime dateTime)
21 void TimeController::onTimeToUpdate(SqpRange dateTime)
22 {
22 {
23 impl->m_DateTime = dateTime;
23 impl->m_DateTime = dateTime;
24 }
24 }
25
25
26 void TimeController::onTimeNotify()
26 void TimeController::onTimeNotify()
27 {
27 {
28 emit timeUpdated(impl->m_DateTime);
28 emit timeUpdated(impl->m_DateTime);
29 }
29 }
@@ -1,86 +1,86
1 #include "Variable/Variable.h"
1 #include "Variable/Variable.h"
2
2
3 #include <Data/IDataSeries.h>
3 #include <Data/IDataSeries.h>
4 #include <Data/SqpDateTime.h>
4 #include <Data/SqpRange.h>
5
5
6 #include <QReadWriteLock>
6 #include <QReadWriteLock>
7 #include <QThread>
7 #include <QThread>
8
8
9 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
9 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
10
10
11 struct Variable::VariablePrivate {
11 struct Variable::VariablePrivate {
12 explicit VariablePrivate(const QString &name, const SqpDateTime &dateTime,
12 explicit VariablePrivate(const QString &name, const SqpRange &dateTime,
13 const QVariantHash &metadata)
13 const QVariantHash &metadata)
14 : m_Name{name}, m_DateTime{dateTime}, m_Metadata{metadata}, m_DataSeries{nullptr}
14 : m_Name{name}, m_DateTime{dateTime}, m_Metadata{metadata}, m_DataSeries{nullptr}
15 {
15 {
16 }
16 }
17
17
18 QString m_Name;
18 QString m_Name;
19
19
20 SqpDateTime m_DateTime; // The dateTime available in the view and loaded. not the cache.
20 SqpRange m_DateTime; // The dateTime available in the view and loaded. not the cache.
21 QVariantHash m_Metadata;
21 QVariantHash m_Metadata;
22 std::unique_ptr<IDataSeries> m_DataSeries;
22 std::unique_ptr<IDataSeries> m_DataSeries;
23 };
23 };
24
24
25 Variable::Variable(const QString &name, const SqpDateTime &dateTime, const QVariantHash &metadata)
25 Variable::Variable(const QString &name, const SqpRange &dateTime, const QVariantHash &metadata)
26 : impl{spimpl::make_unique_impl<VariablePrivate>(name, dateTime, metadata)}
26 : impl{spimpl::make_unique_impl<VariablePrivate>(name, dateTime, metadata)}
27 {
27 {
28 }
28 }
29
29
30 QString Variable::name() const noexcept
30 QString Variable::name() const noexcept
31 {
31 {
32 return impl->m_Name;
32 return impl->m_Name;
33 }
33 }
34
34
35 SqpDateTime Variable::dateTime() const noexcept
35 SqpRange Variable::dateTime() const noexcept
36 {
36 {
37 return impl->m_DateTime;
37 return impl->m_DateTime;
38 }
38 }
39
39
40 void Variable::setDateTime(const SqpDateTime &dateTime) noexcept
40 void Variable::setDateTime(const SqpRange &dateTime) noexcept
41 {
41 {
42 impl->m_DateTime = dateTime;
42 impl->m_DateTime = dateTime;
43 }
43 }
44
44
45 void Variable::setDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
45 void Variable::setDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
46 {
46 {
47 qCDebug(LOG_Variable()) << "Variable::setDataSeries" << QThread::currentThread()->objectName();
47 qCDebug(LOG_Variable()) << "Variable::setDataSeries" << QThread::currentThread()->objectName();
48 if (!dataSeries) {
48 if (!dataSeries) {
49 /// @todo ALX : log
49 /// @todo ALX : log
50 return;
50 return;
51 }
51 }
52
52
53 // Inits the data series of the variable
53 // Inits the data series of the variable
54 if (!impl->m_DataSeries) {
54 if (!impl->m_DataSeries) {
55 impl->m_DataSeries = dataSeries->clone();
55 impl->m_DataSeries = dataSeries->clone();
56 }
56 }
57 else {
57 else {
58 impl->m_DataSeries->merge(dataSeries.get());
58 impl->m_DataSeries->merge(dataSeries.get());
59 // emit updated();
59 // emit updated();
60 }
60 }
61 }
61 }
62
62
63 IDataSeries *Variable::dataSeries() const noexcept
63 IDataSeries *Variable::dataSeries() const noexcept
64 {
64 {
65 return impl->m_DataSeries.get();
65 return impl->m_DataSeries.get();
66 }
66 }
67
67
68 QVariantHash Variable::metadata() const noexcept
68 QVariantHash Variable::metadata() const noexcept
69 {
69 {
70 return impl->m_Metadata;
70 return impl->m_Metadata;
71 }
71 }
72
72
73 bool Variable::contains(const SqpDateTime &dateTime) const noexcept
73 bool Variable::contains(const SqpRange &dateTime) const noexcept
74 {
74 {
75 return impl->m_DateTime.contains(dateTime);
75 return impl->m_DateTime.contains(dateTime);
76 }
76 }
77
77
78 bool Variable::intersect(const SqpDateTime &dateTime) const noexcept
78 bool Variable::intersect(const SqpRange &dateTime) const noexcept
79 {
79 {
80 return impl->m_DateTime.intersect(dateTime);
80 return impl->m_DateTime.intersect(dateTime);
81 }
81 }
82
82
83 bool Variable::isInside(const SqpDateTime &dateTime) const noexcept
83 bool Variable::isInside(const SqpRange &dateTime) const noexcept
84 {
84 {
85 return dateTime.contains(SqpDateTime{impl->m_DateTime.m_TStart, impl->m_DateTime.m_TEnd});
85 return dateTime.contains(SqpRange{impl->m_DateTime.m_TStart, impl->m_DateTime.m_TEnd});
86 }
86 }
@@ -1,228 +1,225
1 #include "Variable/VariableCacheController.h"
1 #include "Variable/VariableCacheController.h"
2
2
3 #include "Variable/Variable.h"
3 #include "Variable/Variable.h"
4 #include <unordered_map>
4 #include <unordered_map>
5
5
6 #include <QThread>
6 #include <QThread>
7 Q_LOGGING_CATEGORY(LOG_VariableCacheController, "VariableCacheController")
7 Q_LOGGING_CATEGORY(LOG_VariableCacheController, "VariableCacheController")
8
8
9 struct VariableCacheController::VariableCacheControllerPrivate {
9 struct VariableCacheController::VariableCacheControllerPrivate {
10
10
11 std::unordered_map<std::shared_ptr<Variable>, QVector<SqpDateTime> >
11 std::unordered_map<std::shared_ptr<Variable>, QVector<SqpRange> > m_VariableToSqpRangeListMap;
12 m_VariableToSqpDateTimeListMap;
13
12
14 void addInCacheDataByEnd(const SqpDateTime &dateTime, QVector<SqpDateTime> &dateTimeList,
13 void addInCacheDataByEnd(const SqpRange &dateTime, QVector<SqpRange> &dateTimeList,
15 QVector<SqpDateTime> &notInCache, int cacheIndex,
14 QVector<SqpRange> &notInCache, int cacheIndex, double currentTStart);
16 double currentTStart);
17
15
18 void addInCacheDataByStart(const SqpDateTime &dateTime, QVector<SqpDateTime> &dateTimeList,
16 void addInCacheDataByStart(const SqpRange &dateTime, QVector<SqpRange> &dateTimeList,
19 QVector<SqpDateTime> &notInCache, int cacheIndex,
17 QVector<SqpRange> &notInCache, int cacheIndex, double currentTStart);
20 double currentTStart);
21
18
22
19
23 void addDateTimeRecurse(const SqpDateTime &dateTime, QVector<SqpDateTime> &dateTimeList,
20 void addDateTimeRecurse(const SqpRange &dateTime, QVector<SqpRange> &dateTimeList,
24 int cacheIndex);
21 int cacheIndex);
25 };
22 };
26
23
27
24
28 VariableCacheController::VariableCacheController(QObject *parent)
25 VariableCacheController::VariableCacheController(QObject *parent)
29 : QObject{parent}, impl{spimpl::make_unique_impl<VariableCacheControllerPrivate>()}
26 : QObject{parent}, impl{spimpl::make_unique_impl<VariableCacheControllerPrivate>()}
30 {
27 {
31 }
28 }
32
29
33 void VariableCacheController::addDateTime(std::shared_ptr<Variable> variable,
30 void VariableCacheController::addDateTime(std::shared_ptr<Variable> variable,
34 const SqpDateTime &dateTime)
31 const SqpRange &dateTime)
35 {
32 {
36 qCDebug(LOG_VariableCacheController()) << "VariableCacheController::addDateTime"
33 qCDebug(LOG_VariableCacheController()) << "VariableCacheController::addDateTime"
37 << QThread::currentThread()->objectName();
34 << QThread::currentThread()->objectName();
38 if (variable) {
35 if (variable) {
39 auto findVariableIte = impl->m_VariableToSqpDateTimeListMap.find(variable);
36 auto findVariableIte = impl->m_VariableToSqpRangeListMap.find(variable);
40 if (findVariableIte == impl->m_VariableToSqpDateTimeListMap.end()) {
37 if (findVariableIte == impl->m_VariableToSqpRangeListMap.end()) {
41 impl->m_VariableToSqpDateTimeListMap[variable].push_back(dateTime);
38 impl->m_VariableToSqpRangeListMap[variable].push_back(dateTime);
42 }
39 }
43 else {
40 else {
44
41
45 // addDateTime modify the list<SqpDateTime> of the variable in a way to ensure
42 // addDateTime modify the list<SqpRange> of the variable in a way to ensure
46 // that the list is ordered : l(0) < l(1). We assume also a < b
43 // that the list is ordered : l(0) < l(1). We assume also a < b
47 // (with a & b of type SqpDateTime) means ts(b) > te(a)
44 // (with a & b of type SqpRange) means ts(b) > te(a)
48
45
49 // The algorithm will try the merge of two interval:
46 // The algorithm will try the merge of two interval:
50 // - dateTime will be compare with the first interval of the list:
47 // - dateTime will be compare with the first interval of the list:
51 // A: if it is inferior, it will be inserted and it's finished.
48 // A: if it is inferior, it will be inserted and it's finished.
52 // B: if it is in intersection, it will be merge then the merged one
49 // B: if it is in intersection, it will be merge then the merged one
53 // will be compared to the next interval. The old one is remove from the list
50 // will be compared to the next interval. The old one is remove from the list
54 // C: if it is superior, we do the same with the next interval of the list
51 // C: if it is superior, we do the same with the next interval of the list
55
52
56 try {
53 try {
57 impl->addDateTimeRecurse(dateTime,
54 impl->addDateTimeRecurse(dateTime, impl->m_VariableToSqpRangeListMap.at(variable),
58 impl->m_VariableToSqpDateTimeListMap.at(variable), 0);
55 0);
59 }
56 }
60 catch (const std::out_of_range &e) {
57 catch (const std::out_of_range &e) {
61 qCWarning(LOG_VariableCacheController()) << "addDateTime" << e.what();
58 qCWarning(LOG_VariableCacheController()) << "addDateTime" << e.what();
62 }
59 }
63 }
60 }
64 }
61 }
65 }
62 }
66
63
67 void VariableCacheController::clear(std::shared_ptr<Variable> variable) noexcept
64 void VariableCacheController::clear(std::shared_ptr<Variable> variable) noexcept
68 {
65 {
69 if (!variable) {
66 if (!variable) {
70 qCCritical(LOG_VariableCacheController()) << "Can't clear variable cache: variable is null";
67 qCCritical(LOG_VariableCacheController()) << "Can't clear variable cache: variable is null";
71 return;
68 return;
72 }
69 }
73
70
74 auto nbEntries = impl->m_VariableToSqpDateTimeListMap.erase(variable);
71 auto nbEntries = impl->m_VariableToSqpRangeListMap.erase(variable);
75
72
76 auto clearCacheMessage
73 auto clearCacheMessage
77 = (nbEntries != 0)
74 = (nbEntries != 0)
78 ? tr("Variable cache cleared for variable %1").arg(variable->name())
75 ? tr("Variable cache cleared for variable %1").arg(variable->name())
79 : tr("No deletion of variable cache: no cache was associated with the variable");
76 : tr("No deletion of variable cache: no cache was associated with the variable");
80 qCDebug(LOG_VariableCacheController()) << clearCacheMessage;
77 qCDebug(LOG_VariableCacheController()) << clearCacheMessage;
81 }
78 }
82
79
83 QVector<SqpDateTime>
80 QVector<SqpRange>
84 VariableCacheController::provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
81 VariableCacheController::provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
85 const SqpDateTime &dateTime)
82 const SqpRange &dateTime)
86 {
83 {
87 qCDebug(LOG_VariableCacheController())
84 qCDebug(LOG_VariableCacheController())
88 << "VariableCacheController::provideNotInCacheDateTimeList"
85 << "VariableCacheController::provideNotInCacheDateTimeList"
89 << QThread::currentThread()->objectName();
86 << QThread::currentThread()->objectName();
90 auto notInCache = QVector<SqpDateTime>{};
87 auto notInCache = QVector<SqpRange>{};
91
88
92 // This algorithm is recursif. The idea is to localise the start time then the end time in the
89 // This algorithm is recursif. The idea is to localise the start time then the end time in the
93 // list of date time request associated to the variable
90 // list of date time request associated to the variable
94 // We assume that the list is ordered in a way that l(0) < l(1). We assume also a < b
91 // We assume that the list is ordered in a way that l(0) < l(1). We assume also a < b
95 // (with a & b of type SqpDateTime) means ts(b) > te(a)
92 // (with a & b of type SqpRange) means ts(b) > te(a)
96 auto it = impl->m_VariableToSqpDateTimeListMap.find(variable);
93 auto it = impl->m_VariableToSqpRangeListMap.find(variable);
97 if (it != impl->m_VariableToSqpDateTimeListMap.end()) {
94 if (it != impl->m_VariableToSqpRangeListMap.end()) {
98 impl->addInCacheDataByStart(dateTime, it->second, notInCache, 0, dateTime.m_TStart);
95 impl->addInCacheDataByStart(dateTime, it->second, notInCache, 0, dateTime.m_TStart);
99 }
96 }
100 else {
97 else {
101 notInCache << dateTime;
98 notInCache << dateTime;
102 }
99 }
103
100
104 return notInCache;
101 return notInCache;
105 }
102 }
106
103
107 QVector<SqpDateTime>
104 QVector<SqpRange>
108 VariableCacheController::dateCacheList(std::shared_ptr<Variable> variable) const noexcept
105 VariableCacheController::dateCacheList(std::shared_ptr<Variable> variable) const noexcept
109 {
106 {
110 qCDebug(LOG_VariableCacheController()) << "VariableCacheController::dateCacheList"
107 qCDebug(LOG_VariableCacheController()) << "VariableCacheController::dateCacheList"
111 << QThread::currentThread()->objectName();
108 << QThread::currentThread()->objectName();
112 try {
109 try {
113 return impl->m_VariableToSqpDateTimeListMap.at(variable);
110 return impl->m_VariableToSqpRangeListMap.at(variable);
114 }
111 }
115 catch (const std::out_of_range &e) {
112 catch (const std::out_of_range &e) {
116 qCWarning(LOG_VariableCacheController()) << e.what();
113 qCWarning(LOG_VariableCacheController()) << e.what();
117 return QVector<SqpDateTime>{};
114 return QVector<SqpRange>{};
118 }
115 }
119 }
116 }
120
117
121 void VariableCacheController::VariableCacheControllerPrivate::addDateTimeRecurse(
118 void VariableCacheController::VariableCacheControllerPrivate::addDateTimeRecurse(
122 const SqpDateTime &dateTime, QVector<SqpDateTime> &dateTimeList, int cacheIndex)
119 const SqpRange &dateTime, QVector<SqpRange> &dateTimeList, int cacheIndex)
123 {
120 {
124 const auto dateTimeListSize = dateTimeList.count();
121 const auto dateTimeListSize = dateTimeList.count();
125 if (cacheIndex >= dateTimeListSize) {
122 if (cacheIndex >= dateTimeListSize) {
126 dateTimeList.push_back(dateTime);
123 dateTimeList.push_back(dateTime);
127 // there is no anymore interval to compore, we can just push_back it
124 // there is no anymore interval to compore, we can just push_back it
128 return;
125 return;
129 }
126 }
130
127
131 auto currentDateTime = dateTimeList[cacheIndex];
128 auto currentDateTime = dateTimeList[cacheIndex];
132
129
133 if (dateTime.m_TEnd < currentDateTime.m_TStart) {
130 if (dateTime.m_TEnd < currentDateTime.m_TStart) {
134 // The compared one is < to current one compared, we can insert it
131 // The compared one is < to current one compared, we can insert it
135 dateTimeList.insert(cacheIndex, dateTime);
132 dateTimeList.insert(cacheIndex, dateTime);
136 }
133 }
137 else if (dateTime.m_TStart > currentDateTime.m_TEnd) {
134 else if (dateTime.m_TStart > currentDateTime.m_TEnd) {
138 // The compared one is > to current one compared we can comparet if to the next one
135 // The compared one is > to current one compared we can comparet if to the next one
139 addDateTimeRecurse(dateTime, dateTimeList, ++cacheIndex);
136 addDateTimeRecurse(dateTime, dateTimeList, ++cacheIndex);
140 }
137 }
141 else {
138 else {
142 // Merge cases: we need to merge the two interval, remove the old one from the list then
139 // Merge cases: we need to merge the two interval, remove the old one from the list then
143 // rerun the algo from this index with the merged interval
140 // rerun the algo from this index with the merged interval
144 auto mTStart = std::min(dateTime.m_TStart, currentDateTime.m_TStart);
141 auto mTStart = std::min(dateTime.m_TStart, currentDateTime.m_TStart);
145 auto mTEnd = std::max(dateTime.m_TEnd, currentDateTime.m_TEnd);
142 auto mTEnd = std::max(dateTime.m_TEnd, currentDateTime.m_TEnd);
146 auto mergeDateTime = SqpDateTime{mTStart, mTEnd};
143 auto mergeDateTime = SqpRange{mTStart, mTEnd};
147
144
148 dateTimeList.remove(cacheIndex);
145 dateTimeList.remove(cacheIndex);
149 addDateTimeRecurse(mergeDateTime, dateTimeList, cacheIndex);
146 addDateTimeRecurse(mergeDateTime, dateTimeList, cacheIndex);
150 }
147 }
151 }
148 }
152
149
153
150
154 void VariableCacheController::VariableCacheControllerPrivate::addInCacheDataByEnd(
151 void VariableCacheController::VariableCacheControllerPrivate::addInCacheDataByEnd(
155 const SqpDateTime &dateTime, QVector<SqpDateTime> &dateTimeList,
152 const SqpRange &dateTime, QVector<SqpRange> &dateTimeList, QVector<SqpRange> &notInCache,
156 QVector<SqpDateTime> &notInCache, int cacheIndex, double currentTStart)
153 int cacheIndex, double currentTStart)
157 {
154 {
158 const auto dateTimeListSize = dateTimeList.count();
155 const auto dateTimeListSize = dateTimeList.count();
159 if (cacheIndex >= dateTimeListSize) {
156 if (cacheIndex >= dateTimeListSize) {
160 if (currentTStart < dateTime.m_TEnd) {
157 if (currentTStart < dateTime.m_TEnd) {
161
158
162 // te localised after all other interval: The last interval is [currentTsart, te]
159 // te localised after all other interval: The last interval is [currentTsart, te]
163 notInCache.push_back(SqpDateTime{currentTStart, dateTime.m_TEnd});
160 notInCache.push_back(SqpRange{currentTStart, dateTime.m_TEnd});
164 }
161 }
165 return;
162 return;
166 }
163 }
167
164
168 auto currentDateTimeJ = dateTimeList[cacheIndex];
165 auto currentDateTimeJ = dateTimeList[cacheIndex];
169 if (dateTime.m_TEnd <= currentDateTimeJ.m_TStart) {
166 if (dateTime.m_TEnd <= currentDateTimeJ.m_TStart) {
170 // te localised between to interval: The last interval is [currentTsart, te]
167 // te localised between to interval: The last interval is [currentTsart, te]
171 notInCache.push_back(SqpDateTime{currentTStart, dateTime.m_TEnd});
168 notInCache.push_back(SqpRange{currentTStart, dateTime.m_TEnd});
172 }
169 }
173 else {
170 else {
174 notInCache.push_back(SqpDateTime{currentTStart, currentDateTimeJ.m_TStart});
171 notInCache.push_back(SqpRange{currentTStart, currentDateTimeJ.m_TStart});
175 if (dateTime.m_TEnd > currentDateTimeJ.m_TEnd) {
172 if (dateTime.m_TEnd > currentDateTimeJ.m_TEnd) {
176 // te not localised before the current interval: we need to look at the next interval
173 // te not localised before the current interval: we need to look at the next interval
177 addInCacheDataByEnd(dateTime, dateTimeList, notInCache, ++cacheIndex,
174 addInCacheDataByEnd(dateTime, dateTimeList, notInCache, ++cacheIndex,
178 currentDateTimeJ.m_TEnd);
175 currentDateTimeJ.m_TEnd);
179 }
176 }
180 }
177 }
181 }
178 }
182
179
183 void VariableCacheController::VariableCacheControllerPrivate::addInCacheDataByStart(
180 void VariableCacheController::VariableCacheControllerPrivate::addInCacheDataByStart(
184 const SqpDateTime &dateTime, QVector<SqpDateTime> &dateTimeList,
181 const SqpRange &dateTime, QVector<SqpRange> &dateTimeList, QVector<SqpRange> &notInCache,
185 QVector<SqpDateTime> &notInCache, int cacheIndex, double currentTStart)
182 int cacheIndex, double currentTStart)
186 {
183 {
187 const auto dateTimeListSize = dateTimeList.count();
184 const auto dateTimeListSize = dateTimeList.count();
188 if (cacheIndex >= dateTimeListSize) {
185 if (cacheIndex >= dateTimeListSize) {
189 // ts localised after all other interval: The last interval is [ts, te]
186 // ts localised after all other interval: The last interval is [ts, te]
190 notInCache.push_back(SqpDateTime{currentTStart, dateTime.m_TEnd});
187 notInCache.push_back(SqpRange{currentTStart, dateTime.m_TEnd});
191 return;
188 return;
192 }
189 }
193
190
194 auto currentDateTimeI = dateTimeList[cacheIndex];
191 auto currentDateTimeI = dateTimeList[cacheIndex];
195 if (currentTStart < currentDateTimeI.m_TStart) {
192 if (currentTStart < currentDateTimeI.m_TStart) {
196
193
197 // ts localised between to interval: let's localized te
194 // ts localised between to interval: let's localized te
198 addInCacheDataByEnd(dateTime, dateTimeList, notInCache, cacheIndex, currentTStart);
195 addInCacheDataByEnd(dateTime, dateTimeList, notInCache, cacheIndex, currentTStart);
199 }
196 }
200 else if (currentTStart < currentDateTimeI.m_TEnd) {
197 else if (currentTStart < currentDateTimeI.m_TEnd) {
201 if (dateTime.m_TEnd > currentDateTimeI.m_TEnd) {
198 if (dateTime.m_TEnd > currentDateTimeI.m_TEnd) {
202 // ts not localised before the current interval: we need to look at the next interval
199 // ts not localised before the current interval: we need to look at the next interval
203 // We can assume now current tstart is the last interval tend, because data between them
200 // We can assume now current tstart is the last interval tend, because data between them
204 // are
201 // are
205 // in the cache
202 // in the cache
206 addInCacheDataByStart(dateTime, dateTimeList, notInCache, ++cacheIndex,
203 addInCacheDataByStart(dateTime, dateTimeList, notInCache, ++cacheIndex,
207 currentDateTimeI.m_TEnd);
204 currentDateTimeI.m_TEnd);
208 }
205 }
209 }
206 }
210 else {
207 else {
211 // ts not localised before the current interval: we need to look at the next interval
208 // ts not localised before the current interval: we need to look at the next interval
212 addInCacheDataByStart(dateTime, dateTimeList, notInCache, ++cacheIndex, currentTStart);
209 addInCacheDataByStart(dateTime, dateTimeList, notInCache, ++cacheIndex, currentTStart);
213 }
210 }
214 }
211 }
215
212
216
213
217 void VariableCacheController::displayCache(std::shared_ptr<Variable> variable) const
214 void VariableCacheController::displayCache(std::shared_ptr<Variable> variable) const
218 {
215 {
219 auto variableDateTimeList = impl->m_VariableToSqpDateTimeListMap.find(variable);
216 auto variableDateTimeList = impl->m_VariableToSqpRangeListMap.find(variable);
220 if (variableDateTimeList != impl->m_VariableToSqpDateTimeListMap.end()) {
217 if (variableDateTimeList != impl->m_VariableToSqpRangeListMap.end()) {
221 qCInfo(LOG_VariableCacheController()) << tr("VariableCacheController::displayCache")
218 qCInfo(LOG_VariableCacheController()) << tr("VariableCacheController::displayCache")
222 << variableDateTimeList->second;
219 << variableDateTimeList->second;
223 }
220 }
224 else {
221 else {
225 qCWarning(LOG_VariableCacheController())
222 qCWarning(LOG_VariableCacheController())
226 << tr("Cannot display a variable that is not in the cache");
223 << tr("Cannot display a variable that is not in the cache");
227 }
224 }
228 }
225 }
@@ -1,243 +1,243
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableCacheController.h>
2 #include <Variable/VariableCacheController.h>
3 #include <Variable/VariableController.h>
3 #include <Variable/VariableController.h>
4 #include <Variable/VariableModel.h>
4 #include <Variable/VariableModel.h>
5
5
6 #include <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
7 #include <Data/IDataProvider.h>
7 #include <Data/IDataProvider.h>
8 #include <Data/IDataSeries.h>
8 #include <Data/IDataSeries.h>
9 #include <Time/TimeController.h>
9 #include <Time/TimeController.h>
10
10
11 #include <QMutex>
11 #include <QMutex>
12 #include <QThread>
12 #include <QThread>
13 #include <QUuid>
13 #include <QUuid>
14 #include <QtCore/QItemSelectionModel>
14 #include <QtCore/QItemSelectionModel>
15
15
16 #include <unordered_map>
16 #include <unordered_map>
17
17
18 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
18 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
19
19
20 struct VariableController::VariableControllerPrivate {
20 struct VariableController::VariableControllerPrivate {
21 explicit VariableControllerPrivate(VariableController *parent)
21 explicit VariableControllerPrivate(VariableController *parent)
22 : m_WorkingMutex{},
22 : m_WorkingMutex{},
23 m_VariableModel{new VariableModel{parent}},
23 m_VariableModel{new VariableModel{parent}},
24 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
24 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
25 m_VariableCacheController{std::make_unique<VariableCacheController>()}
25 m_VariableCacheController{std::make_unique<VariableCacheController>()}
26 {
26 {
27 }
27 }
28
28
29 QMutex m_WorkingMutex;
29 QMutex m_WorkingMutex;
30 /// Variable model. The VariableController has the ownership
30 /// Variable model. The VariableController has the ownership
31 VariableModel *m_VariableModel;
31 VariableModel *m_VariableModel;
32 QItemSelectionModel *m_VariableSelectionModel;
32 QItemSelectionModel *m_VariableSelectionModel;
33
33
34
34
35 TimeController *m_TimeController{nullptr};
35 TimeController *m_TimeController{nullptr};
36 std::unique_ptr<VariableCacheController> m_VariableCacheController;
36 std::unique_ptr<VariableCacheController> m_VariableCacheController;
37
37
38 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
38 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
39 m_VariableToProviderMap;
39 m_VariableToProviderMap;
40 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
40 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
41 };
41 };
42
42
43 VariableController::VariableController(QObject *parent)
43 VariableController::VariableController(QObject *parent)
44 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
44 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
45 {
45 {
46 qCDebug(LOG_VariableController()) << tr("VariableController construction")
46 qCDebug(LOG_VariableController()) << tr("VariableController construction")
47 << QThread::currentThread();
47 << QThread::currentThread();
48
48
49 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
49 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
50 &VariableController::onAbortProgressRequested);
50 &VariableController::onAbortProgressRequested);
51 }
51 }
52
52
53 VariableController::~VariableController()
53 VariableController::~VariableController()
54 {
54 {
55 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
55 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
56 << QThread::currentThread();
56 << QThread::currentThread();
57 this->waitForFinish();
57 this->waitForFinish();
58 }
58 }
59
59
60 VariableModel *VariableController::variableModel() noexcept
60 VariableModel *VariableController::variableModel() noexcept
61 {
61 {
62 return impl->m_VariableModel;
62 return impl->m_VariableModel;
63 }
63 }
64
64
65 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
65 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
66 {
66 {
67 return impl->m_VariableSelectionModel;
67 return impl->m_VariableSelectionModel;
68 }
68 }
69
69
70 void VariableController::setTimeController(TimeController *timeController) noexcept
70 void VariableController::setTimeController(TimeController *timeController) noexcept
71 {
71 {
72 impl->m_TimeController = timeController;
72 impl->m_TimeController = timeController;
73 }
73 }
74
74
75 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
75 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
76 {
76 {
77 if (!variable) {
77 if (!variable) {
78 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
78 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
79 return;
79 return;
80 }
80 }
81
81
82 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
82 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
83 // make some treatments before the deletion
83 // make some treatments before the deletion
84 emit variableAboutToBeDeleted(variable);
84 emit variableAboutToBeDeleted(variable);
85
85
86 // Deletes identifier
86 // Deletes identifier
87 impl->m_VariableToIdentifierMap.erase(variable);
87 impl->m_VariableToIdentifierMap.erase(variable);
88
88
89 // Deletes provider
89 // Deletes provider
90 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
90 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
91 qCDebug(LOG_VariableController())
91 qCDebug(LOG_VariableController())
92 << tr("Number of providers deleted for variable %1: %2")
92 << tr("Number of providers deleted for variable %1: %2")
93 .arg(variable->name(), QString::number(nbProvidersDeleted));
93 .arg(variable->name(), QString::number(nbProvidersDeleted));
94
94
95 // Clears cache
95 // Clears cache
96 impl->m_VariableCacheController->clear(variable);
96 impl->m_VariableCacheController->clear(variable);
97
97
98 // Deletes from model
98 // Deletes from model
99 impl->m_VariableModel->deleteVariable(variable);
99 impl->m_VariableModel->deleteVariable(variable);
100 }
100 }
101
101
102 void VariableController::deleteVariables(
102 void VariableController::deleteVariables(
103 const QVector<std::shared_ptr<Variable> > &variables) noexcept
103 const QVector<std::shared_ptr<Variable> > &variables) noexcept
104 {
104 {
105 for (auto variable : qAsConst(variables)) {
105 for (auto variable : qAsConst(variables)) {
106 deleteVariable(variable);
106 deleteVariable(variable);
107 }
107 }
108 }
108 }
109
109
110 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
110 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
111 {
111 {
112 }
112 }
113
113
114 void VariableController::createVariable(const QString &name, const QVariantHash &metadata,
114 void VariableController::createVariable(const QString &name, const QVariantHash &metadata,
115 std::shared_ptr<IDataProvider> provider) noexcept
115 std::shared_ptr<IDataProvider> provider) noexcept
116 {
116 {
117
117
118 if (!impl->m_TimeController) {
118 if (!impl->m_TimeController) {
119 qCCritical(LOG_VariableController())
119 qCCritical(LOG_VariableController())
120 << tr("Impossible to create variable: The time controller is null");
120 << tr("Impossible to create variable: The time controller is null");
121 return;
121 return;
122 }
122 }
123
123
124 auto dateTime = impl->m_TimeController->dateTime();
124 auto dateTime = impl->m_TimeController->dateTime();
125
125
126 if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime, metadata)) {
126 if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime, metadata)) {
127 auto identifier = QUuid::createUuid();
127 auto identifier = QUuid::createUuid();
128
128
129 // store the provider
129 // store the provider
130 impl->m_VariableToProviderMap[newVariable] = provider;
130 impl->m_VariableToProviderMap[newVariable] = provider;
131 impl->m_VariableToIdentifierMap[newVariable] = identifier;
131 impl->m_VariableToIdentifierMap[newVariable] = identifier;
132
132
133 auto addDateTimeAcquired = [ this, varW = std::weak_ptr<Variable>{newVariable} ](
133 auto addDateTimeAcquired = [ this, varW = std::weak_ptr<Variable>{newVariable} ](
134 QUuid identifier, auto dataSeriesAcquired, auto dateTimeToPutInCache)
134 QUuid identifier, auto dataSeriesAcquired, auto dateTimeToPutInCache)
135 {
135 {
136 if (auto variable = varW.lock()) {
136 if (auto variable = varW.lock()) {
137 auto varIdentifier = impl->m_VariableToIdentifierMap.at(variable);
137 auto varIdentifier = impl->m_VariableToIdentifierMap.at(variable);
138 if (varIdentifier == identifier) {
138 if (varIdentifier == identifier) {
139 impl->m_VariableCacheController->addDateTime(variable, dateTimeToPutInCache);
139 impl->m_VariableCacheController->addDateTime(variable, dateTimeToPutInCache);
140 variable->setDataSeries(dataSeriesAcquired);
140 variable->setDataSeries(dataSeriesAcquired);
141 emit variable->updated();
141 emit variable->updated();
142 }
142 }
143 }
143 }
144 };
144 };
145
145
146 connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
146 connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
147 connect(provider.get(), &IDataProvider::dataProvidedProgress, this,
147 connect(provider.get(), &IDataProvider::dataProvidedProgress, this,
148 &VariableController::onVariableRetrieveDataInProgress);
148 &VariableController::onVariableRetrieveDataInProgress);
149 this->onRequestDataLoading(newVariable, dateTime);
149 this->onRequestDataLoading(newVariable, dateTime);
150 }
150 }
151 }
151 }
152
152
153 void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
153 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
154 {
154 {
155 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
155 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
156 << QThread::currentThread()->objectName();
156 << QThread::currentThread()->objectName();
157 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
157 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
158
158
159 for (const auto &selectedRow : qAsConst(selectedRows)) {
159 for (const auto &selectedRow : qAsConst(selectedRows)) {
160 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
160 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
161 selectedVariable->setDateTime(dateTime);
161 selectedVariable->setDateTime(dateTime);
162 this->onRequestDataLoading(selectedVariable, dateTime);
162 this->onRequestDataLoading(selectedVariable, dateTime);
163
163
164 // notify that rescale operation has to be done
164 // notify that rescale operation has to be done
165 emit rangeChanged(selectedVariable, dateTime);
165 emit rangeChanged(selectedVariable, dateTime);
166 }
166 }
167 }
167 }
168 }
168 }
169
169
170 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
170 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
171 {
171 {
172 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
172 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
173
173
174 auto end = impl->m_VariableToIdentifierMap.cend();
174 auto end = impl->m_VariableToIdentifierMap.cend();
175 auto it = std::find_if(impl->m_VariableToIdentifierMap.cbegin(), end, findReply);
175 auto it = std::find_if(impl->m_VariableToIdentifierMap.cbegin(), end, findReply);
176 if (it != end) {
176 if (it != end) {
177 impl->m_VariableModel->setDataProgress(it->first, progress);
177 impl->m_VariableModel->setDataProgress(it->first, progress);
178 }
178 }
179 }
179 }
180
180
181 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
181 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
182 {
182 {
183 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
183 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
184 << QThread::currentThread()->objectName();
184 << QThread::currentThread()->objectName();
185
185
186 auto it = impl->m_VariableToIdentifierMap.find(variable);
186 auto it = impl->m_VariableToIdentifierMap.find(variable);
187 if (it != impl->m_VariableToIdentifierMap.cend()) {
187 if (it != impl->m_VariableToIdentifierMap.cend()) {
188 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
188 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
189 }
189 }
190 else {
190 else {
191 qCWarning(LOG_VariableController())
191 qCWarning(LOG_VariableController())
192 << tr("Aborting progression of inexistant variable detected !!!")
192 << tr("Aborting progression of inexistant variable detected !!!")
193 << QThread::currentThread()->objectName();
193 << QThread::currentThread()->objectName();
194 }
194 }
195 }
195 }
196
196
197
197
198 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
198 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
199 const SqpDateTime &dateTime)
199 const SqpRange &dateTime)
200 {
200 {
201 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
201 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
202 << QThread::currentThread()->objectName();
202 << QThread::currentThread()->objectName();
203 // we want to load data of the variable for the dateTime.
203 // we want to load data of the variable for the dateTime.
204 // First we check if the cache contains some of them.
204 // First we check if the cache contains some of them.
205 // For the other, we ask the provider to give them.
205 // For the other, we ask the provider to give them.
206 if (variable) {
206 if (variable) {
207
207
208 auto dateTimeListNotInCache
208 auto dateTimeListNotInCache
209 = impl->m_VariableCacheController->provideNotInCacheDateTimeList(variable, dateTime);
209 = impl->m_VariableCacheController->provideNotInCacheDateTimeList(variable, dateTime);
210
210
211 if (!dateTimeListNotInCache.empty()) {
211 if (!dateTimeListNotInCache.empty()) {
212 // Ask the provider for each data on the dateTimeListNotInCache
212 // Ask the provider for each data on the dateTimeListNotInCache
213 auto identifier = impl->m_VariableToIdentifierMap.at(variable);
213 auto identifier = impl->m_VariableToIdentifierMap.at(variable);
214 impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
214 impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
215 identifier,
215 identifier,
216 DataProviderParameters{std::move(dateTimeListNotInCache), variable->metadata()});
216 DataProviderParameters{std::move(dateTimeListNotInCache), variable->metadata()});
217 }
217 }
218 else {
218 else {
219 emit variable->updated();
219 emit variable->updated();
220 }
220 }
221 }
221 }
222 else {
222 else {
223 qCCritical(LOG_VariableController()) << tr("Impossible to load data of a variable null");
223 qCCritical(LOG_VariableController()) << tr("Impossible to load data of a variable null");
224 }
224 }
225 }
225 }
226
226
227
227
228 void VariableController::initialize()
228 void VariableController::initialize()
229 {
229 {
230 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
230 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
231 impl->m_WorkingMutex.lock();
231 impl->m_WorkingMutex.lock();
232 qCDebug(LOG_VariableController()) << tr("VariableController init END");
232 qCDebug(LOG_VariableController()) << tr("VariableController init END");
233 }
233 }
234
234
235 void VariableController::finalize()
235 void VariableController::finalize()
236 {
236 {
237 impl->m_WorkingMutex.unlock();
237 impl->m_WorkingMutex.unlock();
238 }
238 }
239
239
240 void VariableController::waitForFinish()
240 void VariableController::waitForFinish()
241 {
241 {
242 QMutexLocker locker{&impl->m_WorkingMutex};
242 QMutexLocker locker{&impl->m_WorkingMutex};
243 }
243 }
@@ -1,249 +1,249
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableModel.h>
2 #include <Variable/VariableModel.h>
3
3
4 #include <Common/DateUtils.h>
4 #include <Common/DateUtils.h>
5
5
6 #include <Data/IDataSeries.h>
6 #include <Data/IDataSeries.h>
7
7
8 #include <QSize>
8 #include <QSize>
9 #include <unordered_map>
9 #include <unordered_map>
10
10
11 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
11 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
12
12
13 namespace {
13 namespace {
14
14
15 // Column indexes
15 // Column indexes
16 const auto NAME_COLUMN = 0;
16 const auto NAME_COLUMN = 0;
17 const auto TSTART_COLUMN = 1;
17 const auto TSTART_COLUMN = 1;
18 const auto TEND_COLUMN = 2;
18 const auto TEND_COLUMN = 2;
19 const auto NB_COLUMNS = 3;
19 const auto NB_COLUMNS = 3;
20
20
21 // Column properties
21 // Column properties
22 const auto DEFAULT_HEIGHT = 25;
22 const auto DEFAULT_HEIGHT = 25;
23 const auto DEFAULT_WIDTH = 100;
23 const auto DEFAULT_WIDTH = 100;
24
24
25 struct ColumnProperties {
25 struct ColumnProperties {
26 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
26 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
27 int height = DEFAULT_HEIGHT)
27 int height = DEFAULT_HEIGHT)
28 : m_Name{name}, m_Width{width}, m_Height{height}
28 : m_Name{name}, m_Width{width}, m_Height{height}
29 {
29 {
30 }
30 }
31
31
32 QString m_Name;
32 QString m_Name;
33 int m_Width;
33 int m_Width;
34 int m_Height;
34 int m_Height;
35 };
35 };
36
36
37 const auto COLUMN_PROPERTIES
37 const auto COLUMN_PROPERTIES
38 = QHash<int, ColumnProperties>{{NAME_COLUMN, {QObject::tr("Name")}},
38 = QHash<int, ColumnProperties>{{NAME_COLUMN, {QObject::tr("Name")}},
39 {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
39 {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
40 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}};
40 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}};
41
41
42 /// Format for datetimes
42 /// Format for datetimes
43 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
43 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
44
44
45
45
46 } // namespace
46 } // namespace
47
47
48 struct VariableModel::VariableModelPrivate {
48 struct VariableModel::VariableModelPrivate {
49 /// Variables created in SciQlop
49 /// Variables created in SciQlop
50 std::vector<std::shared_ptr<Variable> > m_Variables;
50 std::vector<std::shared_ptr<Variable> > m_Variables;
51 std::unordered_map<std::shared_ptr<Variable>, double> m_VariableToProgress;
51 std::unordered_map<std::shared_ptr<Variable>, double> m_VariableToProgress;
52
52
53 /// Return the row index of the variable. -1 if it's not found
53 /// Return the row index of the variable. -1 if it's not found
54 int indexOfVariable(Variable *variable) const noexcept;
54 int indexOfVariable(Variable *variable) const noexcept;
55 };
55 };
56
56
57 VariableModel::VariableModel(QObject *parent)
57 VariableModel::VariableModel(QObject *parent)
58 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
58 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
59 {
59 {
60 }
60 }
61
61
62 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
62 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
63 const SqpDateTime &dateTime,
63 const SqpRange &dateTime,
64 const QVariantHash &metadata) noexcept
64 const QVariantHash &metadata) noexcept
65 {
65 {
66 auto insertIndex = rowCount();
66 auto insertIndex = rowCount();
67 beginInsertRows({}, insertIndex, insertIndex);
67 beginInsertRows({}, insertIndex, insertIndex);
68
68
69 auto variable = std::make_shared<Variable>(name, dateTime, metadata);
69 auto variable = std::make_shared<Variable>(name, dateTime, metadata);
70
70
71 impl->m_Variables.push_back(variable);
71 impl->m_Variables.push_back(variable);
72 connect(variable.get(), &Variable::updated, this, &VariableModel::onVariableUpdated);
72 connect(variable.get(), &Variable::updated, this, &VariableModel::onVariableUpdated);
73
73
74 endInsertRows();
74 endInsertRows();
75
75
76 return variable;
76 return variable;
77 }
77 }
78
78
79 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
79 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
80 {
80 {
81 if (!variable) {
81 if (!variable) {
82 qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
82 qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
83 return;
83 return;
84 }
84 }
85
85
86 // Finds variable in the model
86 // Finds variable in the model
87 auto begin = impl->m_Variables.cbegin();
87 auto begin = impl->m_Variables.cbegin();
88 auto end = impl->m_Variables.cend();
88 auto end = impl->m_Variables.cend();
89 auto it = std::find(begin, end, variable);
89 auto it = std::find(begin, end, variable);
90 if (it != end) {
90 if (it != end) {
91 auto removeIndex = std::distance(begin, it);
91 auto removeIndex = std::distance(begin, it);
92
92
93 // Deletes variable
93 // Deletes variable
94 beginRemoveRows({}, removeIndex, removeIndex);
94 beginRemoveRows({}, removeIndex, removeIndex);
95 impl->m_Variables.erase(it);
95 impl->m_Variables.erase(it);
96 endRemoveRows();
96 endRemoveRows();
97 }
97 }
98 else {
98 else {
99 qCritical(LOG_VariableModel())
99 qCritical(LOG_VariableModel())
100 << tr("Can't delete variable %1 from the model: the variable is not in the model")
100 << tr("Can't delete variable %1 from the model: the variable is not in the model")
101 .arg(variable->name());
101 .arg(variable->name());
102 }
102 }
103
103
104 // Removes variable from progress map
104 // Removes variable from progress map
105 impl->m_VariableToProgress.erase(variable);
105 impl->m_VariableToProgress.erase(variable);
106 }
106 }
107
107
108
108
109 std::shared_ptr<Variable> VariableModel::variable(int index) const
109 std::shared_ptr<Variable> VariableModel::variable(int index) const
110 {
110 {
111 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
111 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
112 }
112 }
113
113
114 void VariableModel::setDataProgress(std::shared_ptr<Variable> variable, double progress)
114 void VariableModel::setDataProgress(std::shared_ptr<Variable> variable, double progress)
115 {
115 {
116 if (progress > 0.0) {
116 if (progress > 0.0) {
117 impl->m_VariableToProgress[variable] = progress;
117 impl->m_VariableToProgress[variable] = progress;
118 }
118 }
119 else {
119 else {
120 impl->m_VariableToProgress.erase(variable);
120 impl->m_VariableToProgress.erase(variable);
121 }
121 }
122 auto modelIndex = createIndex(impl->indexOfVariable(variable.get()), NAME_COLUMN);
122 auto modelIndex = createIndex(impl->indexOfVariable(variable.get()), NAME_COLUMN);
123
123
124 emit dataChanged(modelIndex, modelIndex);
124 emit dataChanged(modelIndex, modelIndex);
125 }
125 }
126
126
127 int VariableModel::columnCount(const QModelIndex &parent) const
127 int VariableModel::columnCount(const QModelIndex &parent) const
128 {
128 {
129 Q_UNUSED(parent);
129 Q_UNUSED(parent);
130
130
131 return NB_COLUMNS;
131 return NB_COLUMNS;
132 }
132 }
133
133
134 int VariableModel::rowCount(const QModelIndex &parent) const
134 int VariableModel::rowCount(const QModelIndex &parent) const
135 {
135 {
136 Q_UNUSED(parent);
136 Q_UNUSED(parent);
137
137
138 return impl->m_Variables.size();
138 return impl->m_Variables.size();
139 }
139 }
140
140
141 QVariant VariableModel::data(const QModelIndex &index, int role) const
141 QVariant VariableModel::data(const QModelIndex &index, int role) const
142 {
142 {
143 if (!index.isValid()) {
143 if (!index.isValid()) {
144 return QVariant{};
144 return QVariant{};
145 }
145 }
146
146
147 if (index.row() < 0 || index.row() >= rowCount()) {
147 if (index.row() < 0 || index.row() >= rowCount()) {
148 return QVariant{};
148 return QVariant{};
149 }
149 }
150
150
151 if (role == Qt::DisplayRole) {
151 if (role == Qt::DisplayRole) {
152 if (auto variable = impl->m_Variables.at(index.row()).get()) {
152 if (auto variable = impl->m_Variables.at(index.row()).get()) {
153 /// Lambda function that builds the variant to return for a time value
153 /// Lambda function that builds the variant to return for a time value
154 auto dateTimeVariant = [](double secs) {
154 auto dateTimeVariant = [](double secs) {
155 auto dateTime = DateUtils::dateTime(secs);
155 auto dateTime = DateUtils::dateTime(secs);
156 return dateTime.toString(DATETIME_FORMAT);
156 return dateTime.toString(DATETIME_FORMAT);
157 };
157 };
158
158
159 switch (index.column()) {
159 switch (index.column()) {
160 case NAME_COLUMN:
160 case NAME_COLUMN:
161 return variable->name();
161 return variable->name();
162 case TSTART_COLUMN:
162 case TSTART_COLUMN:
163 return dateTimeVariant(variable->dateTime().m_TStart);
163 return dateTimeVariant(variable->dateTime().m_TStart);
164 case TEND_COLUMN:
164 case TEND_COLUMN:
165 return dateTimeVariant(variable->dateTime().m_TEnd);
165 return dateTimeVariant(variable->dateTime().m_TEnd);
166 default:
166 default:
167 // No action
167 // No action
168 break;
168 break;
169 }
169 }
170
170
171 qWarning(LOG_VariableModel())
171 qWarning(LOG_VariableModel())
172 << tr("Can't get data (unknown column %1)").arg(index.column());
172 << tr("Can't get data (unknown column %1)").arg(index.column());
173 }
173 }
174 else {
174 else {
175 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
175 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
176 }
176 }
177 }
177 }
178 else if (role == VariableRoles::ProgressRole) {
178 else if (role == VariableRoles::ProgressRole) {
179 if (auto variable = impl->m_Variables.at(index.row())) {
179 if (auto variable = impl->m_Variables.at(index.row())) {
180
180
181 auto it = impl->m_VariableToProgress.find(variable);
181 auto it = impl->m_VariableToProgress.find(variable);
182 if (it != impl->m_VariableToProgress.cend()) {
182 if (it != impl->m_VariableToProgress.cend()) {
183 return it->second;
183 return it->second;
184 }
184 }
185 }
185 }
186 }
186 }
187
187
188 return QVariant{};
188 return QVariant{};
189 }
189 }
190
190
191 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
191 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
192 {
192 {
193 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
193 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
194 return QVariant{};
194 return QVariant{};
195 }
195 }
196
196
197 if (orientation == Qt::Horizontal) {
197 if (orientation == Qt::Horizontal) {
198 auto propertiesIt = COLUMN_PROPERTIES.find(section);
198 auto propertiesIt = COLUMN_PROPERTIES.find(section);
199 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
199 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
200 // Role is either DisplayRole or SizeHintRole
200 // Role is either DisplayRole or SizeHintRole
201 return (role == Qt::DisplayRole)
201 return (role == Qt::DisplayRole)
202 ? QVariant{propertiesIt->m_Name}
202 ? QVariant{propertiesIt->m_Name}
203 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
203 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
204 }
204 }
205 else {
205 else {
206 qWarning(LOG_VariableModel())
206 qWarning(LOG_VariableModel())
207 << tr("Can't get header data (unknown column %1)").arg(section);
207 << tr("Can't get header data (unknown column %1)").arg(section);
208 }
208 }
209 }
209 }
210
210
211 return QVariant{};
211 return QVariant{};
212 }
212 }
213
213
214 void VariableModel::abortProgress(const QModelIndex &index)
214 void VariableModel::abortProgress(const QModelIndex &index)
215 {
215 {
216 if (auto variable = impl->m_Variables.at(index.row())) {
216 if (auto variable = impl->m_Variables.at(index.row())) {
217 emit abortProgessRequested(variable);
217 emit abortProgessRequested(variable);
218 }
218 }
219 }
219 }
220
220
221 void VariableModel::onVariableUpdated() noexcept
221 void VariableModel::onVariableUpdated() noexcept
222 {
222 {
223 // Finds variable that has been updated in the model
223 // Finds variable that has been updated in the model
224 if (auto updatedVariable = dynamic_cast<Variable *>(sender())) {
224 if (auto updatedVariable = dynamic_cast<Variable *>(sender())) {
225 auto updatedVariableIndex = impl->indexOfVariable(updatedVariable);
225 auto updatedVariableIndex = impl->indexOfVariable(updatedVariable);
226
226
227 if (updatedVariableIndex > -1) {
227 if (updatedVariableIndex > -1) {
228 emit dataChanged(createIndex(updatedVariableIndex, 0),
228 emit dataChanged(createIndex(updatedVariableIndex, 0),
229 createIndex(updatedVariableIndex, columnCount() - 1));
229 createIndex(updatedVariableIndex, columnCount() - 1));
230 }
230 }
231 }
231 }
232 }
232 }
233
233
234 int VariableModel::VariableModelPrivate::indexOfVariable(Variable *variable) const noexcept
234 int VariableModel::VariableModelPrivate::indexOfVariable(Variable *variable) const noexcept
235 {
235 {
236 auto begin = std::cbegin(m_Variables);
236 auto begin = std::cbegin(m_Variables);
237 auto end = std::cend(m_Variables);
237 auto end = std::cend(m_Variables);
238 auto it
238 auto it
239 = std::find_if(begin, end, [variable](const auto &var) { return var.get() == variable; });
239 = std::find_if(begin, end, [variable](const auto &var) { return var.get() == variable; });
240
240
241 if (it != end) {
241 if (it != end) {
242 // Gets the index of the variable in the model: we assume here that views have the same
242 // Gets the index of the variable in the model: we assume here that views have the same
243 // order as the model
243 // order as the model
244 return std::distance(begin, it);
244 return std::distance(begin, it);
245 }
245 }
246 else {
246 else {
247 return -1;
247 return -1;
248 }
248 }
249 }
249 }
@@ -1,353 +1,353
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableCacheController.h>
2 #include <Variable/VariableCacheController.h>
3
3
4 #include <QObject>
4 #include <QObject>
5 #include <QtTest>
5 #include <QtTest>
6
6
7 #include <memory>
7 #include <memory>
8
8
9 class TestVariableCacheController : public QObject {
9 class TestVariableCacheController : public QObject {
10 Q_OBJECT
10 Q_OBJECT
11
11
12 private slots:
12 private slots:
13 void testProvideNotInCacheDateTimeList();
13 void testProvideNotInCacheDateTimeList();
14
14
15 void testAddDateTime();
15 void testAddDateTime();
16 };
16 };
17
17
18
18
19 void TestVariableCacheController::testProvideNotInCacheDateTimeList()
19 void TestVariableCacheController::testProvideNotInCacheDateTimeList()
20 {
20 {
21 VariableCacheController variableCacheController{};
21 VariableCacheController variableCacheController{};
22
22
23 auto ts0 = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}};
23 auto ts0 = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}};
24 auto te0 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
24 auto te0 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
25 auto sqp0 = SqpDateTime{static_cast<double>(ts0.toMSecsSinceEpoch()),
25 auto sqp0 = SqpRange{static_cast<double>(ts0.toMSecsSinceEpoch()),
26 static_cast<double>(te0.toMSecsSinceEpoch())};
26 static_cast<double>(te0.toMSecsSinceEpoch())};
27
27
28 auto ts1 = QDateTime{QDate{2017, 01, 01}, QTime{2, 6, 0, 0}};
28 auto ts1 = QDateTime{QDate{2017, 01, 01}, QTime{2, 6, 0, 0}};
29 auto te1 = QDateTime{QDate{2017, 01, 01}, QTime{2, 8, 0, 0}};
29 auto te1 = QDateTime{QDate{2017, 01, 01}, QTime{2, 8, 0, 0}};
30 auto sqp1 = SqpDateTime{static_cast<double>(ts1.toMSecsSinceEpoch()),
30 auto sqp1 = SqpRange{static_cast<double>(ts1.toMSecsSinceEpoch()),
31 static_cast<double>(te1.toMSecsSinceEpoch())};
31 static_cast<double>(te1.toMSecsSinceEpoch())};
32
32
33 auto ts2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 18, 0, 0}};
33 auto ts2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 18, 0, 0}};
34 auto te2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 20, 0, 0}};
34 auto te2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 20, 0, 0}};
35 auto sqp2 = SqpDateTime{static_cast<double>(ts2.toMSecsSinceEpoch()),
35 auto sqp2 = SqpRange{static_cast<double>(ts2.toMSecsSinceEpoch()),
36 static_cast<double>(te2.toMSecsSinceEpoch())};
36 static_cast<double>(te2.toMSecsSinceEpoch())};
37
37
38 auto var0 = std::make_shared<Variable>("", sqp0);
38 auto var0 = std::make_shared<Variable>("", sqp0);
39
39
40 variableCacheController.addDateTime(var0, sqp0);
40 variableCacheController.addDateTime(var0, sqp0);
41 variableCacheController.addDateTime(var0, sqp1);
41 variableCacheController.addDateTime(var0, sqp1);
42 variableCacheController.addDateTime(var0, sqp2);
42 variableCacheController.addDateTime(var0, sqp2);
43
43
44 // first case [ts,te] < ts0
44 // first case [ts,te] < ts0
45 auto ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
45 auto ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
46 auto te = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}};
46 auto te = QDateTime{QDate{2017, 01, 01}, QTime{2, 1, 0, 0}};
47 auto sqp = SqpDateTime{static_cast<double>(ts.toMSecsSinceEpoch()),
47 auto sqp = SqpRange{static_cast<double>(ts.toMSecsSinceEpoch()),
48 static_cast<double>(te.toMSecsSinceEpoch())};
48 static_cast<double>(te.toMSecsSinceEpoch())};
49
49
50
50
51 auto notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
51 auto notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
52
52
53 QCOMPARE(notInCach.size(), 1);
53 QCOMPARE(notInCach.size(), 1);
54 auto notInCacheSqp = notInCach.first();
54 auto notInCacheSqp = notInCach.first();
55 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(ts.toMSecsSinceEpoch()));
55 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(ts.toMSecsSinceEpoch()));
56 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(te.toMSecsSinceEpoch()));
56 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(te.toMSecsSinceEpoch()));
57
57
58
58
59 // second case ts < ts0 && ts0 < te <= te0
59 // second case ts < ts0 && ts0 < te <= te0
60 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
60 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
61 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
61 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
62 sqp = SqpDateTime{static_cast<double>(ts.toMSecsSinceEpoch()),
62 sqp = SqpRange{static_cast<double>(ts.toMSecsSinceEpoch()),
63 static_cast<double>(te.toMSecsSinceEpoch())};
63 static_cast<double>(te.toMSecsSinceEpoch())};
64
64
65
65
66 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
66 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
67
67
68 QCOMPARE(notInCach.size(), 1);
68 QCOMPARE(notInCach.size(), 1);
69 notInCacheSqp = notInCach.first();
69 notInCacheSqp = notInCach.first();
70 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(ts.toMSecsSinceEpoch()));
70 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(ts.toMSecsSinceEpoch()));
71 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts0.toMSecsSinceEpoch()));
71 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts0.toMSecsSinceEpoch()));
72
72
73 // 3th case ts < ts0 && te0 < te <= ts1
73 // 3th case ts < ts0 && te0 < te <= ts1
74 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
74 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
75 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
75 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
76 sqp = SqpDateTime{static_cast<double>(ts.toMSecsSinceEpoch()),
76 sqp = SqpRange{static_cast<double>(ts.toMSecsSinceEpoch()),
77 static_cast<double>(te.toMSecsSinceEpoch())};
77 static_cast<double>(te.toMSecsSinceEpoch())};
78
78
79
79
80 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
80 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
81
81
82 QCOMPARE(notInCach.size(), 2);
82 QCOMPARE(notInCach.size(), 2);
83 notInCacheSqp = notInCach.first();
83 notInCacheSqp = notInCach.first();
84 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(ts.toMSecsSinceEpoch()));
84 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(ts.toMSecsSinceEpoch()));
85 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts0.toMSecsSinceEpoch()));
85 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts0.toMSecsSinceEpoch()));
86
86
87 notInCacheSqp = notInCach.at(1);
87 notInCacheSqp = notInCach.at(1);
88 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te0.toMSecsSinceEpoch()));
88 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te0.toMSecsSinceEpoch()));
89 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(te.toMSecsSinceEpoch()));
89 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(te.toMSecsSinceEpoch()));
90
90
91 // 4th case ts < ts0 && ts1 < te <= te1
91 // 4th case ts < ts0 && ts1 < te <= te1
92 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
92 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
93 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 7, 0, 0}};
93 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 7, 0, 0}};
94 sqp = SqpDateTime{static_cast<double>(ts.toMSecsSinceEpoch()),
94 sqp = SqpRange{static_cast<double>(ts.toMSecsSinceEpoch()),
95 static_cast<double>(te.toMSecsSinceEpoch())};
95 static_cast<double>(te.toMSecsSinceEpoch())};
96
96
97
97
98 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
98 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
99
99
100 QCOMPARE(notInCach.size(), 2);
100 QCOMPARE(notInCach.size(), 2);
101 notInCacheSqp = notInCach.first();
101 notInCacheSqp = notInCach.first();
102 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(ts.toMSecsSinceEpoch()));
102 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(ts.toMSecsSinceEpoch()));
103 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts0.toMSecsSinceEpoch()));
103 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts0.toMSecsSinceEpoch()));
104
104
105 notInCacheSqp = notInCach.at(1);
105 notInCacheSqp = notInCach.at(1);
106 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te0.toMSecsSinceEpoch()));
106 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te0.toMSecsSinceEpoch()));
107 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts1.toMSecsSinceEpoch()));
107 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts1.toMSecsSinceEpoch()));
108
108
109 // 5th case ts < ts0 && te3 < te
109 // 5th case ts < ts0 && te3 < te
110 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
110 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 0, 0, 0}};
111 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 22, 0, 0}};
111 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 22, 0, 0}};
112 sqp = SqpDateTime{static_cast<double>(ts.toMSecsSinceEpoch()),
112 sqp = SqpRange{static_cast<double>(ts.toMSecsSinceEpoch()),
113 static_cast<double>(te.toMSecsSinceEpoch())};
113 static_cast<double>(te.toMSecsSinceEpoch())};
114
114
115
115
116 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
116 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
117
117
118 QCOMPARE(notInCach.size(), 4);
118 QCOMPARE(notInCach.size(), 4);
119 notInCacheSqp = notInCach.first();
119 notInCacheSqp = notInCach.first();
120 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(ts.toMSecsSinceEpoch()));
120 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(ts.toMSecsSinceEpoch()));
121 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts0.toMSecsSinceEpoch()));
121 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts0.toMSecsSinceEpoch()));
122
122
123 notInCacheSqp = notInCach.at(1);
123 notInCacheSqp = notInCach.at(1);
124 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te0.toMSecsSinceEpoch()));
124 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te0.toMSecsSinceEpoch()));
125 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts1.toMSecsSinceEpoch()));
125 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts1.toMSecsSinceEpoch()));
126
126
127 notInCacheSqp = notInCach.at(2);
127 notInCacheSqp = notInCach.at(2);
128 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te1.toMSecsSinceEpoch()));
128 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te1.toMSecsSinceEpoch()));
129 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts2.toMSecsSinceEpoch()));
129 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts2.toMSecsSinceEpoch()));
130
130
131 notInCacheSqp = notInCach.at(3);
131 notInCacheSqp = notInCach.at(3);
132 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te2.toMSecsSinceEpoch()));
132 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te2.toMSecsSinceEpoch()));
133 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(te.toMSecsSinceEpoch()));
133 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(te.toMSecsSinceEpoch()));
134
134
135
135
136 // 6th case ts2 < ts
136 // 6th case ts2 < ts
137 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 45, 0, 0}};
137 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 45, 0, 0}};
138 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 47, 0, 0}};
138 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 47, 0, 0}};
139 sqp = SqpDateTime{static_cast<double>(ts.toMSecsSinceEpoch()),
139 sqp = SqpRange{static_cast<double>(ts.toMSecsSinceEpoch()),
140 static_cast<double>(te.toMSecsSinceEpoch())};
140 static_cast<double>(te.toMSecsSinceEpoch())};
141
141
142
142
143 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
143 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
144
144
145 QCOMPARE(notInCach.size(), 1);
145 QCOMPARE(notInCach.size(), 1);
146 notInCacheSqp = notInCach.first();
146 notInCacheSqp = notInCach.first();
147 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(ts.toMSecsSinceEpoch()));
147 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(ts.toMSecsSinceEpoch()));
148 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(te.toMSecsSinceEpoch()));
148 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(te.toMSecsSinceEpoch()));
149
149
150 // 7th case ts = te0 && te < ts1
150 // 7th case ts = te0 && te < ts1
151 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
151 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
152 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
152 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
153 sqp = SqpDateTime{static_cast<double>(ts.toMSecsSinceEpoch()),
153 sqp = SqpRange{static_cast<double>(ts.toMSecsSinceEpoch()),
154 static_cast<double>(te.toMSecsSinceEpoch())};
154 static_cast<double>(te.toMSecsSinceEpoch())};
155
155
156
156
157 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
157 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
158
158
159 QCOMPARE(notInCach.size(), 1);
159 QCOMPARE(notInCach.size(), 1);
160 notInCacheSqp = notInCach.first();
160 notInCacheSqp = notInCach.first();
161 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te0.toMSecsSinceEpoch()));
161 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te0.toMSecsSinceEpoch()));
162 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(te.toMSecsSinceEpoch()));
162 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(te.toMSecsSinceEpoch()));
163
163
164 // 8th case ts0 < ts < te0 && te < ts1
164 // 8th case ts0 < ts < te0 && te < ts1
165 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
165 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
166 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
166 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
167 sqp = SqpDateTime{static_cast<double>(ts.toMSecsSinceEpoch()),
167 sqp = SqpRange{static_cast<double>(ts.toMSecsSinceEpoch()),
168 static_cast<double>(te.toMSecsSinceEpoch())};
168 static_cast<double>(te.toMSecsSinceEpoch())};
169
169
170
170
171 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
171 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
172
172
173 QCOMPARE(notInCach.size(), 1);
173 QCOMPARE(notInCach.size(), 1);
174 notInCacheSqp = notInCach.first();
174 notInCacheSqp = notInCach.first();
175 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te0.toMSecsSinceEpoch()));
175 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te0.toMSecsSinceEpoch()));
176 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(te.toMSecsSinceEpoch()));
176 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(te.toMSecsSinceEpoch()));
177
177
178 // 9th case ts0 < ts < te0 && ts1 < te < te1
178 // 9th case ts0 < ts < te0 && ts1 < te < te1
179 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
179 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 30, 0}};
180 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 7, 0, 0}};
180 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 7, 0, 0}};
181 sqp = SqpDateTime{static_cast<double>(ts.toMSecsSinceEpoch()),
181 sqp = SqpRange{static_cast<double>(ts.toMSecsSinceEpoch()),
182 static_cast<double>(te.toMSecsSinceEpoch())};
182 static_cast<double>(te.toMSecsSinceEpoch())};
183
183
184
184
185 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
185 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
186
186
187 QCOMPARE(notInCach.size(), 1);
187 QCOMPARE(notInCach.size(), 1);
188 notInCacheSqp = notInCach.first();
188 notInCacheSqp = notInCach.first();
189 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te0.toMSecsSinceEpoch()));
189 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te0.toMSecsSinceEpoch()));
190 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts1.toMSecsSinceEpoch()));
190 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts1.toMSecsSinceEpoch()));
191
191
192 // 10th case te1 < ts < te < ts2
192 // 10th case te1 < ts < te < ts2
193 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 9, 0, 0}};
193 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 9, 0, 0}};
194 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 10, 0, 0}};
194 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 10, 0, 0}};
195 sqp = SqpDateTime{static_cast<double>(ts.toMSecsSinceEpoch()),
195 sqp = SqpRange{static_cast<double>(ts.toMSecsSinceEpoch()),
196 static_cast<double>(te.toMSecsSinceEpoch())};
196 static_cast<double>(te.toMSecsSinceEpoch())};
197
197
198
198
199 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
199 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
200
200
201 QCOMPARE(notInCach.size(), 1);
201 QCOMPARE(notInCach.size(), 1);
202 notInCacheSqp = notInCach.first();
202 notInCacheSqp = notInCach.first();
203 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(ts.toMSecsSinceEpoch()));
203 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(ts.toMSecsSinceEpoch()));
204 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(te.toMSecsSinceEpoch()));
204 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(te.toMSecsSinceEpoch()));
205
205
206 // 11th case te0 < ts < ts1 && te3 < te
206 // 11th case te0 < ts < ts1 && te3 < te
207 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
207 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
208 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 47, 0, 0}};
208 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 47, 0, 0}};
209 sqp = SqpDateTime{static_cast<double>(ts.toMSecsSinceEpoch()),
209 sqp = SqpRange{static_cast<double>(ts.toMSecsSinceEpoch()),
210 static_cast<double>(te.toMSecsSinceEpoch())};
210 static_cast<double>(te.toMSecsSinceEpoch())};
211
211
212
212
213 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
213 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
214
214
215 QCOMPARE(notInCach.size(), 3);
215 QCOMPARE(notInCach.size(), 3);
216 notInCacheSqp = notInCach.first();
216 notInCacheSqp = notInCach.first();
217 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(ts.toMSecsSinceEpoch()));
217 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(ts.toMSecsSinceEpoch()));
218 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts1.toMSecsSinceEpoch()));
218 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts1.toMSecsSinceEpoch()));
219
219
220 notInCacheSqp = notInCach.at(1);
220 notInCacheSqp = notInCach.at(1);
221 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te1.toMSecsSinceEpoch()));
221 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te1.toMSecsSinceEpoch()));
222 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts2.toMSecsSinceEpoch()));
222 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts2.toMSecsSinceEpoch()));
223
223
224 notInCacheSqp = notInCach.at(2);
224 notInCacheSqp = notInCach.at(2);
225 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te2.toMSecsSinceEpoch()));
225 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te2.toMSecsSinceEpoch()));
226 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(te.toMSecsSinceEpoch()));
226 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(te.toMSecsSinceEpoch()));
227
227
228 // 12th case te0 < ts < ts1 && te3 < te
228 // 12th case te0 < ts < ts1 && te3 < te
229 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
229 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 5, 0, 0}};
230 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 10, 0, 0}};
230 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 10, 0, 0}};
231 sqp = SqpDateTime{static_cast<double>(ts.toMSecsSinceEpoch()),
231 sqp = SqpRange{static_cast<double>(ts.toMSecsSinceEpoch()),
232 static_cast<double>(te.toMSecsSinceEpoch())};
232 static_cast<double>(te.toMSecsSinceEpoch())};
233
233
234 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
234 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
235
235
236 QCOMPARE(notInCach.size(), 2);
236 QCOMPARE(notInCach.size(), 2);
237 notInCacheSqp = notInCach.first();
237 notInCacheSqp = notInCach.first();
238 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(ts.toMSecsSinceEpoch()));
238 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(ts.toMSecsSinceEpoch()));
239 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts1.toMSecsSinceEpoch()));
239 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(ts1.toMSecsSinceEpoch()));
240
240
241 notInCacheSqp = notInCach.at(1);
241 notInCacheSqp = notInCach.at(1);
242 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te1.toMSecsSinceEpoch()));
242 QCOMPARE(notInCacheSqp.m_TStart, static_cast<double>(te1.toMSecsSinceEpoch()));
243 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(te.toMSecsSinceEpoch()));
243 QCOMPARE(notInCacheSqp.m_TEnd, static_cast<double>(te.toMSecsSinceEpoch()));
244
244
245
245
246 // 12th case ts0 < ts < te0
246 // 12th case ts0 < ts < te0
247 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 10, 0}};
247 ts = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 10, 0}};
248 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 50, 0}};
248 te = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 50, 0}};
249 sqp = SqpDateTime{static_cast<double>(ts.toMSecsSinceEpoch()),
249 sqp = SqpRange{static_cast<double>(ts.toMSecsSinceEpoch()),
250 static_cast<double>(te.toMSecsSinceEpoch())};
250 static_cast<double>(te.toMSecsSinceEpoch())};
251
251
252 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
252 notInCach = variableCacheController.provideNotInCacheDateTimeList(var0, sqp);
253 QCOMPARE(notInCach.size(), 0);
253 QCOMPARE(notInCach.size(), 0);
254 }
254 }
255
255
256
256
257 void TestVariableCacheController::testAddDateTime()
257 void TestVariableCacheController::testAddDateTime()
258 {
258 {
259 VariableCacheController variableCacheController{};
259 VariableCacheController variableCacheController{};
260
260
261 auto ts0 = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}};
261 auto ts0 = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}};
262 auto te0 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
262 auto te0 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
263 auto sqp0 = SqpDateTime{static_cast<double>(ts0.toMSecsSinceEpoch()),
263 auto sqp0 = SqpRange{static_cast<double>(ts0.toMSecsSinceEpoch()),
264 static_cast<double>(te0.toMSecsSinceEpoch())};
264 static_cast<double>(te0.toMSecsSinceEpoch())};
265
265
266 auto ts1 = QDateTime{QDate{2017, 01, 01}, QTime{2, 6, 0, 0}};
266 auto ts1 = QDateTime{QDate{2017, 01, 01}, QTime{2, 6, 0, 0}};
267 auto te1 = QDateTime{QDate{2017, 01, 01}, QTime{2, 8, 0, 0}};
267 auto te1 = QDateTime{QDate{2017, 01, 01}, QTime{2, 8, 0, 0}};
268 auto sqp1 = SqpDateTime{static_cast<double>(ts1.toMSecsSinceEpoch()),
268 auto sqp1 = SqpRange{static_cast<double>(ts1.toMSecsSinceEpoch()),
269 static_cast<double>(te1.toMSecsSinceEpoch())};
269 static_cast<double>(te1.toMSecsSinceEpoch())};
270
270
271 auto ts2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 18, 0, 0}};
271 auto ts2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 18, 0, 0}};
272 auto te2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 20, 0, 0}};
272 auto te2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 20, 0, 0}};
273 auto sqp2 = SqpDateTime{static_cast<double>(ts2.toMSecsSinceEpoch()),
273 auto sqp2 = SqpRange{static_cast<double>(ts2.toMSecsSinceEpoch()),
274 static_cast<double>(te2.toMSecsSinceEpoch())};
274 static_cast<double>(te2.toMSecsSinceEpoch())};
275
275
276 auto ts01 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
276 auto ts01 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
277 auto te01 = QDateTime{QDate{2017, 01, 01}, QTime{2, 6, 0, 0}};
277 auto te01 = QDateTime{QDate{2017, 01, 01}, QTime{2, 6, 0, 0}};
278 auto sqp01 = SqpDateTime{static_cast<double>(ts01.toMSecsSinceEpoch()),
278 auto sqp01 = SqpRange{static_cast<double>(ts01.toMSecsSinceEpoch()),
279 static_cast<double>(te01.toMSecsSinceEpoch())};
279 static_cast<double>(te01.toMSecsSinceEpoch())};
280
280
281 auto ts3 = QDateTime{QDate{2017, 01, 01}, QTime{2, 14, 0, 0}};
281 auto ts3 = QDateTime{QDate{2017, 01, 01}, QTime{2, 14, 0, 0}};
282 auto te3 = QDateTime{QDate{2017, 01, 01}, QTime{2, 16, 0, 0}};
282 auto te3 = QDateTime{QDate{2017, 01, 01}, QTime{2, 16, 0, 0}};
283 auto sqp3 = SqpDateTime{static_cast<double>(ts3.toMSecsSinceEpoch()),
283 auto sqp3 = SqpRange{static_cast<double>(ts3.toMSecsSinceEpoch()),
284 static_cast<double>(te3.toMSecsSinceEpoch())};
284 static_cast<double>(te3.toMSecsSinceEpoch())};
285
285
286 auto ts03 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
286 auto ts03 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}};
287 auto te03 = QDateTime{QDate{2017, 01, 01}, QTime{2, 22, 0, 0}};
287 auto te03 = QDateTime{QDate{2017, 01, 01}, QTime{2, 22, 0, 0}};
288 auto sqp03 = SqpDateTime{static_cast<double>(ts03.toMSecsSinceEpoch()),
288 auto sqp03 = SqpRange{static_cast<double>(ts03.toMSecsSinceEpoch()),
289 static_cast<double>(te03.toMSecsSinceEpoch())};
289 static_cast<double>(te03.toMSecsSinceEpoch())};
290
290
291
291
292 auto var0 = std::make_shared<Variable>("", sqp0);
292 auto var0 = std::make_shared<Variable>("", sqp0);
293
293
294
294
295 // First case: add the first interval to the variable :sqp0
295 // First case: add the first interval to the variable :sqp0
296 variableCacheController.addDateTime(var0, sqp0);
296 variableCacheController.addDateTime(var0, sqp0);
297 auto dateCacheList = variableCacheController.dateCacheList(var0);
297 auto dateCacheList = variableCacheController.dateCacheList(var0);
298 QCOMPARE(dateCacheList.count(), 1);
298 QCOMPARE(dateCacheList.count(), 1);
299 auto dateCache = dateCacheList.at(0);
299 auto dateCache = dateCacheList.at(0);
300 QCOMPARE(dateCache.m_TStart, static_cast<double>(ts0.toMSecsSinceEpoch()));
300 QCOMPARE(dateCache.m_TStart, static_cast<double>(ts0.toMSecsSinceEpoch()));
301 QCOMPARE(dateCache.m_TEnd, static_cast<double>(te0.toMSecsSinceEpoch()));
301 QCOMPARE(dateCache.m_TEnd, static_cast<double>(te0.toMSecsSinceEpoch()));
302
302
303 // 2nd case: add a second interval : sqp1 > sqp0
303 // 2nd case: add a second interval : sqp1 > sqp0
304 variableCacheController.addDateTime(var0, sqp1);
304 variableCacheController.addDateTime(var0, sqp1);
305 dateCacheList = variableCacheController.dateCacheList(var0);
305 dateCacheList = variableCacheController.dateCacheList(var0);
306 QCOMPARE(dateCacheList.count(), 2);
306 QCOMPARE(dateCacheList.count(), 2);
307 dateCache = dateCacheList.at(0);
307 dateCache = dateCacheList.at(0);
308 QCOMPARE(dateCache.m_TStart, static_cast<double>(ts0.toMSecsSinceEpoch()));
308 QCOMPARE(dateCache.m_TStart, static_cast<double>(ts0.toMSecsSinceEpoch()));
309 QCOMPARE(dateCache.m_TEnd, static_cast<double>(te0.toMSecsSinceEpoch()));
309 QCOMPARE(dateCache.m_TEnd, static_cast<double>(te0.toMSecsSinceEpoch()));
310
310
311 dateCache = dateCacheList.at(1);
311 dateCache = dateCacheList.at(1);
312 QCOMPARE(dateCache.m_TStart, static_cast<double>(ts1.toMSecsSinceEpoch()));
312 QCOMPARE(dateCache.m_TStart, static_cast<double>(ts1.toMSecsSinceEpoch()));
313 QCOMPARE(dateCache.m_TEnd, static_cast<double>(te1.toMSecsSinceEpoch()));
313 QCOMPARE(dateCache.m_TEnd, static_cast<double>(te1.toMSecsSinceEpoch()));
314
314
315 // 3th case: merge sqp0 & sqp1 with sqp01
315 // 3th case: merge sqp0 & sqp1 with sqp01
316 variableCacheController.addDateTime(var0, sqp01);
316 variableCacheController.addDateTime(var0, sqp01);
317 dateCacheList = variableCacheController.dateCacheList(var0);
317 dateCacheList = variableCacheController.dateCacheList(var0);
318 QCOMPARE(dateCacheList.count(), 1);
318 QCOMPARE(dateCacheList.count(), 1);
319 dateCache = dateCacheList.at(0);
319 dateCache = dateCacheList.at(0);
320 QCOMPARE(dateCache.m_TStart, static_cast<double>(ts0.toMSecsSinceEpoch()));
320 QCOMPARE(dateCache.m_TStart, static_cast<double>(ts0.toMSecsSinceEpoch()));
321 QCOMPARE(dateCache.m_TEnd, static_cast<double>(te1.toMSecsSinceEpoch()));
321 QCOMPARE(dateCache.m_TEnd, static_cast<double>(te1.toMSecsSinceEpoch()));
322
322
323
323
324 // 4th case: add a second interval : sqp1 > sqp0
324 // 4th case: add a second interval : sqp1 > sqp0
325 variableCacheController.addDateTime(var0, sqp2);
325 variableCacheController.addDateTime(var0, sqp2);
326 variableCacheController.addDateTime(var0, sqp3);
326 variableCacheController.addDateTime(var0, sqp3);
327 dateCacheList = variableCacheController.dateCacheList(var0);
327 dateCacheList = variableCacheController.dateCacheList(var0);
328 QCOMPARE(dateCacheList.count(), 3);
328 QCOMPARE(dateCacheList.count(), 3);
329 dateCache = dateCacheList.at(0);
329 dateCache = dateCacheList.at(0);
330 QCOMPARE(dateCache.m_TStart, static_cast<double>(ts0.toMSecsSinceEpoch()));
330 QCOMPARE(dateCache.m_TStart, static_cast<double>(ts0.toMSecsSinceEpoch()));
331 QCOMPARE(dateCache.m_TEnd, static_cast<double>(te1.toMSecsSinceEpoch()));
331 QCOMPARE(dateCache.m_TEnd, static_cast<double>(te1.toMSecsSinceEpoch()));
332
332
333 dateCache = dateCacheList.at(1);
333 dateCache = dateCacheList.at(1);
334 QCOMPARE(dateCache.m_TStart, static_cast<double>(ts3.toMSecsSinceEpoch()));
334 QCOMPARE(dateCache.m_TStart, static_cast<double>(ts3.toMSecsSinceEpoch()));
335 QCOMPARE(dateCache.m_TEnd, static_cast<double>(te3.toMSecsSinceEpoch()));
335 QCOMPARE(dateCache.m_TEnd, static_cast<double>(te3.toMSecsSinceEpoch()));
336
336
337 dateCache = dateCacheList.at(2);
337 dateCache = dateCacheList.at(2);
338 QCOMPARE(dateCache.m_TStart, static_cast<double>(ts2.toMSecsSinceEpoch()));
338 QCOMPARE(dateCache.m_TStart, static_cast<double>(ts2.toMSecsSinceEpoch()));
339 QCOMPARE(dateCache.m_TEnd, static_cast<double>(te2.toMSecsSinceEpoch()));
339 QCOMPARE(dateCache.m_TEnd, static_cast<double>(te2.toMSecsSinceEpoch()));
340
340
341
341
342 // 5th case: merge all interval
342 // 5th case: merge all interval
343 variableCacheController.addDateTime(var0, sqp03);
343 variableCacheController.addDateTime(var0, sqp03);
344 dateCacheList = variableCacheController.dateCacheList(var0);
344 dateCacheList = variableCacheController.dateCacheList(var0);
345 QCOMPARE(dateCacheList.count(), 1);
345 QCOMPARE(dateCacheList.count(), 1);
346 dateCache = dateCacheList.at(0);
346 dateCache = dateCacheList.at(0);
347 QCOMPARE(dateCache.m_TStart, static_cast<double>(ts0.toMSecsSinceEpoch()));
347 QCOMPARE(dateCache.m_TStart, static_cast<double>(ts0.toMSecsSinceEpoch()));
348 QCOMPARE(dateCache.m_TEnd, static_cast<double>(te03.toMSecsSinceEpoch()));
348 QCOMPARE(dateCache.m_TEnd, static_cast<double>(te03.toMSecsSinceEpoch()));
349 }
349 }
350
350
351
351
352 QTEST_MAIN(TestVariableCacheController)
352 QTEST_MAIN(TestVariableCacheController)
353 #include "TestVariableCacheController.moc"
353 #include "TestVariableCacheController.moc"
@@ -1,32 +1,32
1 #ifndef SCIQLOP_TIMEWIDGET_H
1 #ifndef SCIQLOP_TIMEWIDGET_H
2 #define SCIQLOP_TIMEWIDGET_H
2 #define SCIQLOP_TIMEWIDGET_H
3
3
4 #include <QWidget>
4 #include <QWidget>
5
5
6 #include <Data/SqpDateTime.h>
6 #include <Data/SqpRange.h>
7
7
8 namespace Ui {
8 namespace Ui {
9 class TimeWidget;
9 class TimeWidget;
10 } // Ui
10 } // Ui
11
11
12 class TimeWidget : public QWidget {
12 class TimeWidget : public QWidget {
13 Q_OBJECT
13 Q_OBJECT
14
14
15 public:
15 public:
16 explicit TimeWidget(QWidget *parent = 0);
16 explicit TimeWidget(QWidget *parent = 0);
17 virtual ~TimeWidget();
17 virtual ~TimeWidget();
18
18
19 signals:
19 signals:
20 /// Signal emitted when the time parameters has beed updated
20 /// Signal emitted when the time parameters has beed updated
21 void timeUpdated(SqpDateTime time);
21 void timeUpdated(SqpRange time);
22
22
23 public slots:
23 public slots:
24 /// slot called when time parameters update has ben requested
24 /// slot called when time parameters update has ben requested
25 void onTimeUpdateRequested();
25 void onTimeUpdateRequested();
26
26
27
27
28 private:
28 private:
29 Ui::TimeWidget *ui;
29 Ui::TimeWidget *ui;
30 };
30 };
31
31
32 #endif // SCIQLOP_ SQPSIDEPANE_H
32 #endif // SCIQLOP_ SQPSIDEPANE_H
@@ -1,38 +1,38
1 #ifndef SCIQLOP_VISUALIZATIONGRAPHHELPER_H
1 #ifndef SCIQLOP_VISUALIZATIONGRAPHHELPER_H
2 #define SCIQLOP_VISUALIZATIONGRAPHHELPER_H
2 #define SCIQLOP_VISUALIZATIONGRAPHHELPER_H
3
3
4 #include <Data/SqpDateTime.h>
4 #include <Data/SqpRange.h>
5
5
6 #include <QLoggingCategory>
6 #include <QLoggingCategory>
7 #include <QVector>
7 #include <QVector>
8
8
9 #include <memory>
9 #include <memory>
10
10
11 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationGraphHelper)
11 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationGraphHelper)
12
12
13 class IDataSeries;
13 class IDataSeries;
14 class QCPAbstractPlottable;
14 class QCPAbstractPlottable;
15 class QCustomPlot;
15 class QCustomPlot;
16 class Variable;
16 class Variable;
17
17
18 /**
18 /**
19 * @brief The VisualizationGraphHelper class aims to create the QCustomPlot components relative to a
19 * @brief The VisualizationGraphHelper class aims to create the QCustomPlot components relative to a
20 * variable, depending on the data series of this variable
20 * variable, depending on the data series of this variable
21 */
21 */
22 struct VisualizationGraphHelper {
22 struct VisualizationGraphHelper {
23 /**
23 /**
24 * Creates (if possible) the QCustomPlot components relative to the variable passed in
24 * Creates (if possible) the QCustomPlot components relative to the variable passed in
25 * parameter, and adds these to the plot passed in parameter.
25 * parameter, and adds these to the plot passed in parameter.
26 * @param variable the variable for which to create the components
26 * @param variable the variable for which to create the components
27 * @param plot the plot in which to add the created components. It takes ownership of these
27 * @param plot the plot in which to add the created components. It takes ownership of these
28 * components.
28 * components.
29 * @return the list of the components created
29 * @return the list of the components created
30 */
30 */
31 static QVector<QCPAbstractPlottable *> create(std::shared_ptr<Variable> variable,
31 static QVector<QCPAbstractPlottable *> create(std::shared_ptr<Variable> variable,
32 QCustomPlot &plot) noexcept;
32 QCustomPlot &plot) noexcept;
33
33
34 static void updateData(QVector<QCPAbstractPlottable *> plotableVect, IDataSeries *dataSeries,
34 static void updateData(QVector<QCPAbstractPlottable *> plotableVect, IDataSeries *dataSeries,
35 const SqpDateTime &dateTime);
35 const SqpRange &dateTime);
36 };
36 };
37
37
38 #endif // SCIQLOP_VISUALIZATIONGRAPHHELPER_H
38 #endif // SCIQLOP_VISUALIZATIONGRAPHHELPER_H
@@ -1,84 +1,84
1 #ifndef SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
2 #define SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
2 #define SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
4 #include "Visualization/IVisualizationWidget.h"
5
5
6 #include <QLoggingCategory>
6 #include <QLoggingCategory>
7 #include <QWidget>
7 #include <QWidget>
8
8
9 #include <memory>
9 #include <memory>
10
10
11 #include <Common/spimpl.h>
11 #include <Common/spimpl.h>
12
12
13 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationGraphWidget)
13 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationGraphWidget)
14
14
15 class QCPRange;
15 class QCPRange;
16 class SqpDateTime;
16 class SqpRange;
17 class Variable;
17 class Variable;
18
18
19 /**
19 /**
20 * Possible types of zoom operation
20 * Possible types of zoom operation
21 */
21 */
22 enum class VisualizationGraphWidgetZoomType { ZoomOut, ZoomIn, PanRight, PanLeft, Unknown };
22 enum class VisualizationGraphWidgetZoomType { ZoomOut, ZoomIn, PanRight, PanLeft, Unknown };
23
23
24 namespace Ui {
24 namespace Ui {
25 class VisualizationGraphWidget;
25 class VisualizationGraphWidget;
26 } // namespace Ui
26 } // namespace Ui
27
27
28 class VisualizationGraphWidget : public QWidget, public IVisualizationWidget {
28 class VisualizationGraphWidget : public QWidget, public IVisualizationWidget {
29 Q_OBJECT
29 Q_OBJECT
30
30
31 public:
31 public:
32 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
32 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
33 virtual ~VisualizationGraphWidget();
33 virtual ~VisualizationGraphWidget();
34
34
35 void enableSynchronize(bool enable);
35 void enableSynchronize(bool enable);
36
36
37 void addVariable(std::shared_ptr<Variable> variable);
37 void addVariable(std::shared_ptr<Variable> variable);
38 void addVariableUsingGraph(std::shared_ptr<Variable> variable);
38 void addVariableUsingGraph(std::shared_ptr<Variable> variable);
39 /// Removes a variable from the graph
39 /// Removes a variable from the graph
40 void removeVariable(std::shared_ptr<Variable> variable) noexcept;
40 void removeVariable(std::shared_ptr<Variable> variable) noexcept;
41
41
42 void setRange(std::shared_ptr<Variable> variable, const SqpDateTime &range);
42 void setRange(std::shared_ptr<Variable> variable, const SqpRange &range);
43 SqpDateTime graphRange() const noexcept;
43 SqpRange graphRange() const noexcept;
44 void setGraphRange(const SqpDateTime &range);
44 void setGraphRange(const SqpRange &range);
45
45
46 // IVisualizationWidget interface
46 // IVisualizationWidget interface
47 void accept(IVisualizationWidgetVisitor *visitor) override;
47 void accept(IVisualizationWidgetVisitor *visitor) override;
48 bool canDrop(const Variable &variable) const override;
48 bool canDrop(const Variable &variable) const override;
49 bool contains(const Variable &variable) const override;
49 bool contains(const Variable &variable) const override;
50 QString name() const override;
50 QString name() const override;
51
51
52
52
53 signals:
53 signals:
54 void requestDataLoading(std::shared_ptr<Variable> variable, const SqpDateTime &dateTime);
54 void requestDataLoading(std::shared_ptr<Variable> variable, const SqpRange &dateTime);
55 void synchronize(const SqpDateTime &dateTime, const SqpDateTime &oldDateTime,
55 void synchronize(const SqpRange &dateTime, const SqpRange &oldDateTime,
56 VisualizationGraphWidgetZoomType zoomType);
56 VisualizationGraphWidgetZoomType zoomType);
57
57
58
58
59 private:
59 private:
60 Ui::VisualizationGraphWidget *ui;
60 Ui::VisualizationGraphWidget *ui;
61
61
62 class VisualizationGraphWidgetPrivate;
62 class VisualizationGraphWidgetPrivate;
63 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
63 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
64
64
65 private slots:
65 private slots:
66 /// Slot called when right clicking on the graph (displays a menu)
66 /// Slot called when right clicking on the graph (displays a menu)
67 void onGraphMenuRequested(const QPoint &pos) noexcept;
67 void onGraphMenuRequested(const QPoint &pos) noexcept;
68
68
69 /// Rescale the X axe to range parameter
69 /// Rescale the X axe to range parameter
70 void onRangeChanged(const QCPRange &t1, const QCPRange &t2);
70 void onRangeChanged(const QCPRange &t1, const QCPRange &t2);
71
71
72 /// Slot called when a mouse move was made
72 /// Slot called when a mouse move was made
73 void onMouseMove(QMouseEvent *event) noexcept;
73 void onMouseMove(QMouseEvent *event) noexcept;
74 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
74 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
75 void onMouseWheel(QWheelEvent *event) noexcept;
75 void onMouseWheel(QWheelEvent *event) noexcept;
76 /// Slot called when a mouse press was made, to activate the calibration of a graph
76 /// Slot called when a mouse press was made, to activate the calibration of a graph
77 void onMousePress(QMouseEvent *event) noexcept;
77 void onMousePress(QMouseEvent *event) noexcept;
78 /// Slot called when a mouse release was made, to deactivate the calibration of a graph
78 /// Slot called when a mouse release was made, to deactivate the calibration of a graph
79 void onMouseRelease(QMouseEvent *event) noexcept;
79 void onMouseRelease(QMouseEvent *event) noexcept;
80
80
81 void onDataCacheVariableUpdated();
81 void onDataCacheVariableUpdated();
82 };
82 };
83
83
84 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
84 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
@@ -1,51 +1,51
1 #ifndef SCIQLOP_VISUALIZATIONWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONWIDGET_H
2 #define SCIQLOP_VISUALIZATIONWIDGET_H
2 #define SCIQLOP_VISUALIZATIONWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
4 #include "Visualization/IVisualizationWidget.h"
5 #include <Data/SqpDateTime.h>
5 #include <Data/SqpRange.h>
6
6
7 #include <QLoggingCategory>
7 #include <QLoggingCategory>
8 #include <QWidget>
8 #include <QWidget>
9
9
10 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationWidget)
10 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationWidget)
11
11
12 class QMenu;
12 class QMenu;
13 class Variable;
13 class Variable;
14 class VisualizationTabWidget;
14 class VisualizationTabWidget;
15
15
16 namespace Ui {
16 namespace Ui {
17 class VisualizationWidget;
17 class VisualizationWidget;
18 } // namespace Ui
18 } // namespace Ui
19
19
20 class VisualizationWidget : public QWidget, public IVisualizationWidget {
20 class VisualizationWidget : public QWidget, public IVisualizationWidget {
21 Q_OBJECT
21 Q_OBJECT
22
22
23 public:
23 public:
24 explicit VisualizationWidget(QWidget *parent = 0);
24 explicit VisualizationWidget(QWidget *parent = 0);
25 virtual ~VisualizationWidget();
25 virtual ~VisualizationWidget();
26
26
27 // IVisualizationWidget interface
27 // IVisualizationWidget interface
28 void accept(IVisualizationWidgetVisitor *visitor) override;
28 void accept(IVisualizationWidgetVisitor *visitor) override;
29 bool canDrop(const Variable &variable) const override;
29 bool canDrop(const Variable &variable) const override;
30 bool contains(const Variable &variable) const override;
30 bool contains(const Variable &variable) const override;
31 QString name() const override;
31 QString name() const override;
32
32
33 public slots:
33 public slots:
34 /**
34 /**
35 * Attaches to a menu the menu relative to the visualization of variables
35 * Attaches to a menu the menu relative to the visualization of variables
36 * @param menu the parent menu of the generated menu
36 * @param menu the parent menu of the generated menu
37 * @param variables the variables for which to generate the menu
37 * @param variables the variables for which to generate the menu
38 */
38 */
39 void attachVariableMenu(QMenu *menu,
39 void attachVariableMenu(QMenu *menu,
40 const QVector<std::shared_ptr<Variable> > &variables) noexcept;
40 const QVector<std::shared_ptr<Variable> > &variables) noexcept;
41
41
42 /// Slot called when a variable is about to be deleted from SciQlop
42 /// Slot called when a variable is about to be deleted from SciQlop
43 void onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept;
43 void onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept;
44
44
45 void onRangeChanged(std::shared_ptr<Variable> variable, const SqpDateTime &range) noexcept;
45 void onRangeChanged(std::shared_ptr<Variable> variable, const SqpRange &range) noexcept;
46
46
47 private:
47 private:
48 Ui::VisualizationWidget *ui;
48 Ui::VisualizationWidget *ui;
49 };
49 };
50
50
51 #endif // VISUALIZATIONWIDGET_H
51 #endif // VISUALIZATIONWIDGET_H
@@ -1,42 +1,42
1 #ifndef SCIQLOP_RESCALEAXEOPERATION_H
1 #ifndef SCIQLOP_RESCALEAXEOPERATION_H
2 #define SCIQLOP_RESCALEAXEOPERATION_H
2 #define SCIQLOP_RESCALEAXEOPERATION_H
3
3
4 #include "Visualization/IVisualizationWidgetVisitor.h"
4 #include "Visualization/IVisualizationWidgetVisitor.h"
5 #include <Data/SqpDateTime.h>
5 #include <Data/SqpRange.h>
6
6
7 #include <Common/spimpl.h>
7 #include <Common/spimpl.h>
8
8
9 #include <QLoggingCategory>
9 #include <QLoggingCategory>
10
10
11 #include <memory>
11 #include <memory>
12
12
13 class Variable;
13 class Variable;
14
14
15 Q_DECLARE_LOGGING_CATEGORY(LOG_RescaleAxeOperation)
15 Q_DECLARE_LOGGING_CATEGORY(LOG_RescaleAxeOperation)
16
16
17 /**
17 /**
18 * @brief The RescaleAxeOperation class defines an operation that traverses all of visualization
18 * @brief The RescaleAxeOperation class defines an operation that traverses all of visualization
19 * widgets to remove a variable if they contain it
19 * widgets to remove a variable if they contain it
20 */
20 */
21 class RescaleAxeOperation : public IVisualizationWidgetVisitor {
21 class RescaleAxeOperation : public IVisualizationWidgetVisitor {
22 public:
22 public:
23 /**
23 /**
24 * Ctor
24 * Ctor
25 * @param variable the variable to remove from widgets
25 * @param variable the variable to remove from widgets
26 */
26 */
27 explicit RescaleAxeOperation(std::shared_ptr<Variable> variable, const SqpDateTime &range);
27 explicit RescaleAxeOperation(std::shared_ptr<Variable> variable, const SqpRange &range);
28
28
29 void visitEnter(VisualizationWidget *widget) override final;
29 void visitEnter(VisualizationWidget *widget) override final;
30 void visitLeave(VisualizationWidget *widget) override final;
30 void visitLeave(VisualizationWidget *widget) override final;
31 void visitEnter(VisualizationTabWidget *tabWidget) override final;
31 void visitEnter(VisualizationTabWidget *tabWidget) override final;
32 void visitLeave(VisualizationTabWidget *tabWidget) override final;
32 void visitLeave(VisualizationTabWidget *tabWidget) override final;
33 void visitEnter(VisualizationZoneWidget *zoneWidget) override final;
33 void visitEnter(VisualizationZoneWidget *zoneWidget) override final;
34 void visitLeave(VisualizationZoneWidget *zoneWidget) override final;
34 void visitLeave(VisualizationZoneWidget *zoneWidget) override final;
35 void visit(VisualizationGraphWidget *graphWidget) override final;
35 void visit(VisualizationGraphWidget *graphWidget) override final;
36
36
37 private:
37 private:
38 class RescaleAxeOperationPrivate;
38 class RescaleAxeOperationPrivate;
39 spimpl::unique_impl_ptr<RescaleAxeOperationPrivate> impl;
39 spimpl::unique_impl_ptr<RescaleAxeOperationPrivate> impl;
40 };
40 };
41
41
42 #endif // SCIQLOP_RESCALEAXEOPERATION_H
42 #endif // SCIQLOP_RESCALEAXEOPERATION_H
@@ -1,151 +1,151
1 #include "SqpApplication.h"
1 #include "SqpApplication.h"
2
2
3 #include <Data/IDataProvider.h>
3 #include <Data/IDataProvider.h>
4 #include <DataSource/DataSourceController.h>
4 #include <DataSource/DataSourceController.h>
5 #include <Network/NetworkController.h>
5 #include <Network/NetworkController.h>
6 #include <QThread>
6 #include <QThread>
7 #include <Time/TimeController.h>
7 #include <Time/TimeController.h>
8 #include <Variable/Variable.h>
8 #include <Variable/Variable.h>
9 #include <Variable/VariableController.h>
9 #include <Variable/VariableController.h>
10 #include <Visualization/VisualizationController.h>
10 #include <Visualization/VisualizationController.h>
11
11
12 Q_LOGGING_CATEGORY(LOG_SqpApplication, "SqpApplication")
12 Q_LOGGING_CATEGORY(LOG_SqpApplication, "SqpApplication")
13
13
14 class SqpApplication::SqpApplicationPrivate {
14 class SqpApplication::SqpApplicationPrivate {
15 public:
15 public:
16 SqpApplicationPrivate()
16 SqpApplicationPrivate()
17 : m_DataSourceController{std::make_unique<DataSourceController>()},
17 : m_DataSourceController{std::make_unique<DataSourceController>()},
18 m_NetworkController{std::make_unique<NetworkController>()},
18 m_NetworkController{std::make_unique<NetworkController>()},
19 m_TimeController{std::make_unique<TimeController>()},
19 m_TimeController{std::make_unique<TimeController>()},
20 m_VariableController{std::make_unique<VariableController>()},
20 m_VariableController{std::make_unique<VariableController>()},
21 m_VisualizationController{std::make_unique<VisualizationController>()}
21 m_VisualizationController{std::make_unique<VisualizationController>()}
22 {
22 {
23 // /////////////////////////////// //
23 // /////////////////////////////// //
24 // Connections between controllers //
24 // Connections between controllers //
25 // /////////////////////////////// //
25 // /////////////////////////////// //
26
26
27 // VariableController <-> DataSourceController
27 // VariableController <-> DataSourceController
28 connect(m_DataSourceController.get(),
28 connect(m_DataSourceController.get(),
29 SIGNAL(variableCreationRequested(const QString &, const QVariantHash &,
29 SIGNAL(variableCreationRequested(const QString &, const QVariantHash &,
30 std::shared_ptr<IDataProvider>)),
30 std::shared_ptr<IDataProvider>)),
31 m_VariableController.get(),
31 m_VariableController.get(),
32 SLOT(createVariable(const QString &, const QVariantHash &,
32 SLOT(createVariable(const QString &, const QVariantHash &,
33 std::shared_ptr<IDataProvider>)));
33 std::shared_ptr<IDataProvider>)));
34
34
35 // VariableController <-> VisualizationController
35 // VariableController <-> VisualizationController
36 connect(m_VariableController.get(),
36 connect(m_VariableController.get(),
37 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)),
37 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)),
38 m_VisualizationController.get(),
38 m_VisualizationController.get(),
39 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), Qt::DirectConnection);
39 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), Qt::DirectConnection);
40
40
41 connect(m_VariableController.get(),
41 connect(m_VariableController.get(),
42 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpDateTime &)),
42 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpRange &)),
43 m_VisualizationController.get(),
43 m_VisualizationController.get(),
44 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpDateTime &)));
44 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpRange &)));
45
45
46
46
47 m_DataSourceController->moveToThread(&m_DataSourceControllerThread);
47 m_DataSourceController->moveToThread(&m_DataSourceControllerThread);
48 m_DataSourceControllerThread.setObjectName("DataSourceControllerThread");
48 m_DataSourceControllerThread.setObjectName("DataSourceControllerThread");
49 m_NetworkController->moveToThread(&m_NetworkControllerThread);
49 m_NetworkController->moveToThread(&m_NetworkControllerThread);
50 m_NetworkControllerThread.setObjectName("NetworkControllerThread");
50 m_NetworkControllerThread.setObjectName("NetworkControllerThread");
51 m_VariableController->moveToThread(&m_VariableControllerThread);
51 m_VariableController->moveToThread(&m_VariableControllerThread);
52 m_VariableControllerThread.setObjectName("VariableControllerThread");
52 m_VariableControllerThread.setObjectName("VariableControllerThread");
53 m_VisualizationController->moveToThread(&m_VisualizationControllerThread);
53 m_VisualizationController->moveToThread(&m_VisualizationControllerThread);
54 m_VisualizationControllerThread.setObjectName("VsualizationControllerThread");
54 m_VisualizationControllerThread.setObjectName("VsualizationControllerThread");
55
55
56
56
57 // Additionnal init
57 // Additionnal init
58 m_VariableController->setTimeController(m_TimeController.get());
58 m_VariableController->setTimeController(m_TimeController.get());
59 }
59 }
60
60
61 virtual ~SqpApplicationPrivate()
61 virtual ~SqpApplicationPrivate()
62 {
62 {
63 qCInfo(LOG_SqpApplication()) << tr("SqpApplicationPrivate destruction");
63 qCInfo(LOG_SqpApplication()) << tr("SqpApplicationPrivate destruction");
64 m_DataSourceControllerThread.quit();
64 m_DataSourceControllerThread.quit();
65 m_DataSourceControllerThread.wait();
65 m_DataSourceControllerThread.wait();
66
66
67 m_NetworkControllerThread.quit();
67 m_NetworkControllerThread.quit();
68 m_NetworkControllerThread.wait();
68 m_NetworkControllerThread.wait();
69
69
70 m_VariableControllerThread.quit();
70 m_VariableControllerThread.quit();
71 m_VariableControllerThread.wait();
71 m_VariableControllerThread.wait();
72
72
73 m_VisualizationControllerThread.quit();
73 m_VisualizationControllerThread.quit();
74 m_VisualizationControllerThread.wait();
74 m_VisualizationControllerThread.wait();
75 }
75 }
76
76
77 std::unique_ptr<DataSourceController> m_DataSourceController;
77 std::unique_ptr<DataSourceController> m_DataSourceController;
78 std::unique_ptr<VariableController> m_VariableController;
78 std::unique_ptr<VariableController> m_VariableController;
79 std::unique_ptr<TimeController> m_TimeController;
79 std::unique_ptr<TimeController> m_TimeController;
80 std::unique_ptr<NetworkController> m_NetworkController;
80 std::unique_ptr<NetworkController> m_NetworkController;
81 std::unique_ptr<VisualizationController> m_VisualizationController;
81 std::unique_ptr<VisualizationController> m_VisualizationController;
82 QThread m_DataSourceControllerThread;
82 QThread m_DataSourceControllerThread;
83 QThread m_NetworkControllerThread;
83 QThread m_NetworkControllerThread;
84 QThread m_VariableControllerThread;
84 QThread m_VariableControllerThread;
85 QThread m_VisualizationControllerThread;
85 QThread m_VisualizationControllerThread;
86 };
86 };
87
87
88
88
89 SqpApplication::SqpApplication(int &argc, char **argv)
89 SqpApplication::SqpApplication(int &argc, char **argv)
90 : QApplication{argc, argv}, impl{spimpl::make_unique_impl<SqpApplicationPrivate>()}
90 : QApplication{argc, argv}, impl{spimpl::make_unique_impl<SqpApplicationPrivate>()}
91 {
91 {
92 qCDebug(LOG_SqpApplication()) << tr("SqpApplication construction") << QThread::currentThread();
92 qCDebug(LOG_SqpApplication()) << tr("SqpApplication construction") << QThread::currentThread();
93
93
94 connect(&impl->m_DataSourceControllerThread, &QThread::started,
94 connect(&impl->m_DataSourceControllerThread, &QThread::started,
95 impl->m_DataSourceController.get(), &DataSourceController::initialize);
95 impl->m_DataSourceController.get(), &DataSourceController::initialize);
96 connect(&impl->m_DataSourceControllerThread, &QThread::finished,
96 connect(&impl->m_DataSourceControllerThread, &QThread::finished,
97 impl->m_DataSourceController.get(), &DataSourceController::finalize);
97 impl->m_DataSourceController.get(), &DataSourceController::finalize);
98
98
99 connect(&impl->m_NetworkControllerThread, &QThread::started, impl->m_NetworkController.get(),
99 connect(&impl->m_NetworkControllerThread, &QThread::started, impl->m_NetworkController.get(),
100 &NetworkController::initialize);
100 &NetworkController::initialize);
101 connect(&impl->m_NetworkControllerThread, &QThread::finished, impl->m_NetworkController.get(),
101 connect(&impl->m_NetworkControllerThread, &QThread::finished, impl->m_NetworkController.get(),
102 &NetworkController::finalize);
102 &NetworkController::finalize);
103
103
104 connect(&impl->m_VariableControllerThread, &QThread::started, impl->m_VariableController.get(),
104 connect(&impl->m_VariableControllerThread, &QThread::started, impl->m_VariableController.get(),
105 &VariableController::initialize);
105 &VariableController::initialize);
106 connect(&impl->m_VariableControllerThread, &QThread::finished, impl->m_VariableController.get(),
106 connect(&impl->m_VariableControllerThread, &QThread::finished, impl->m_VariableController.get(),
107 &VariableController::finalize);
107 &VariableController::finalize);
108
108
109 connect(&impl->m_VisualizationControllerThread, &QThread::started,
109 connect(&impl->m_VisualizationControllerThread, &QThread::started,
110 impl->m_VisualizationController.get(), &VisualizationController::initialize);
110 impl->m_VisualizationController.get(), &VisualizationController::initialize);
111 connect(&impl->m_VisualizationControllerThread, &QThread::finished,
111 connect(&impl->m_VisualizationControllerThread, &QThread::finished,
112 impl->m_VisualizationController.get(), &VisualizationController::finalize);
112 impl->m_VisualizationController.get(), &VisualizationController::finalize);
113
113
114 impl->m_DataSourceControllerThread.start();
114 impl->m_DataSourceControllerThread.start();
115 impl->m_NetworkControllerThread.start();
115 impl->m_NetworkControllerThread.start();
116 impl->m_VariableControllerThread.start();
116 impl->m_VariableControllerThread.start();
117 impl->m_VisualizationControllerThread.start();
117 impl->m_VisualizationControllerThread.start();
118 }
118 }
119
119
120 SqpApplication::~SqpApplication()
120 SqpApplication::~SqpApplication()
121 {
121 {
122 }
122 }
123
123
124 void SqpApplication::initialize()
124 void SqpApplication::initialize()
125 {
125 {
126 }
126 }
127
127
128 DataSourceController &SqpApplication::dataSourceController() noexcept
128 DataSourceController &SqpApplication::dataSourceController() noexcept
129 {
129 {
130 return *impl->m_DataSourceController;
130 return *impl->m_DataSourceController;
131 }
131 }
132
132
133 NetworkController &SqpApplication::networkController() noexcept
133 NetworkController &SqpApplication::networkController() noexcept
134 {
134 {
135 return *impl->m_NetworkController;
135 return *impl->m_NetworkController;
136 }
136 }
137
137
138 TimeController &SqpApplication::timeController() noexcept
138 TimeController &SqpApplication::timeController() noexcept
139 {
139 {
140 return *impl->m_TimeController;
140 return *impl->m_TimeController;
141 }
141 }
142
142
143 VariableController &SqpApplication::variableController() noexcept
143 VariableController &SqpApplication::variableController() noexcept
144 {
144 {
145 return *impl->m_VariableController;
145 return *impl->m_VariableController;
146 }
146 }
147
147
148 VisualizationController &SqpApplication::visualizationController() noexcept
148 VisualizationController &SqpApplication::visualizationController() noexcept
149 {
149 {
150 return *impl->m_VisualizationController;
150 return *impl->m_VisualizationController;
151 }
151 }
@@ -1,50 +1,50
1 #include "TimeWidget/TimeWidget.h"
1 #include "TimeWidget/TimeWidget.h"
2 #include "ui_TimeWidget.h"
2 #include "ui_TimeWidget.h"
3
3
4 #include <Common/DateUtils.h>
4 #include <Common/DateUtils.h>
5 #include <SqpApplication.h>
5 #include <SqpApplication.h>
6 #include <Time/TimeController.h>
6 #include <Time/TimeController.h>
7
7
8 TimeWidget::TimeWidget(QWidget *parent) : QWidget{parent}, ui{new Ui::TimeWidget}
8 TimeWidget::TimeWidget(QWidget *parent) : QWidget{parent}, ui{new Ui::TimeWidget}
9 {
9 {
10 ui->setupUi(this);
10 ui->setupUi(this);
11
11
12 ui->applyToolButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_DialogApplyButton));
12 ui->applyToolButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_DialogApplyButton));
13
13
14 // Connection
14 // Connection
15 connect(ui->startDateTimeEdit, &QDateTimeEdit::dateTimeChanged, this,
15 connect(ui->startDateTimeEdit, &QDateTimeEdit::dateTimeChanged, this,
16 &TimeWidget::onTimeUpdateRequested);
16 &TimeWidget::onTimeUpdateRequested);
17
17
18 connect(ui->endDateTimeEdit, &QDateTimeEdit::dateTimeChanged, this,
18 connect(ui->endDateTimeEdit, &QDateTimeEdit::dateTimeChanged, this,
19 &TimeWidget::onTimeUpdateRequested);
19 &TimeWidget::onTimeUpdateRequested);
20
20
21
21
22 connect(ui->applyToolButton, &QToolButton::clicked, &sqpApp->timeController(),
22 connect(ui->applyToolButton, &QToolButton::clicked, &sqpApp->timeController(),
23 &TimeController::onTimeNotify);
23 &TimeController::onTimeNotify);
24
24
25 // Initialisation
25 // Initialisation
26 auto endDateTime = QDateTime::currentDateTimeUtc();
26 auto endDateTime = QDateTime::currentDateTimeUtc();
27 auto startDateTime = endDateTime.addSecs(-3600); // one hour before
27 auto startDateTime = endDateTime.addSecs(-3600); // one hour before
28
28
29 ui->startDateTimeEdit->setDateTime(startDateTime);
29 ui->startDateTimeEdit->setDateTime(startDateTime);
30 ui->endDateTimeEdit->setDateTime(endDateTime);
30 ui->endDateTimeEdit->setDateTime(endDateTime);
31
31
32 auto dateTime = SqpDateTime{DateUtils::secondsSinceEpoch(startDateTime),
32 auto dateTime = SqpRange{DateUtils::secondsSinceEpoch(startDateTime),
33 DateUtils::secondsSinceEpoch(endDateTime)};
33 DateUtils::secondsSinceEpoch(endDateTime)};
34
34
35 sqpApp->timeController().onTimeToUpdate(dateTime);
35 sqpApp->timeController().onTimeToUpdate(dateTime);
36 }
36 }
37
37
38
38
39 TimeWidget::~TimeWidget()
39 TimeWidget::~TimeWidget()
40 {
40 {
41 delete ui;
41 delete ui;
42 }
42 }
43
43
44 void TimeWidget::onTimeUpdateRequested()
44 void TimeWidget::onTimeUpdateRequested()
45 {
45 {
46 auto dateTime = SqpDateTime{DateUtils::secondsSinceEpoch(ui->startDateTimeEdit->dateTime()),
46 auto dateTime = SqpRange{DateUtils::secondsSinceEpoch(ui->startDateTimeEdit->dateTime()),
47 DateUtils::secondsSinceEpoch(ui->endDateTimeEdit->dateTime())};
47 DateUtils::secondsSinceEpoch(ui->endDateTimeEdit->dateTime())};
48
48
49 emit timeUpdated(std::move(dateTime));
49 emit timeUpdated(std::move(dateTime));
50 }
50 }
@@ -1,162 +1,162
1 #include "Visualization/VisualizationGraphHelper.h"
1 #include "Visualization/VisualizationGraphHelper.h"
2 #include "Visualization/qcustomplot.h"
2 #include "Visualization/qcustomplot.h"
3
3
4 #include <Data/ScalarSeries.h>
4 #include <Data/ScalarSeries.h>
5
5
6 #include <Variable/Variable.h>
6 #include <Variable/Variable.h>
7
7
8 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
8 Q_LOGGING_CATEGORY(LOG_VisualizationGraphHelper, "VisualizationGraphHelper")
9
9
10 namespace {
10 namespace {
11
11
12 class SqpDataContainer : public QCPGraphDataContainer {
12 class SqpDataContainer : public QCPGraphDataContainer {
13 public:
13 public:
14 void appendGraphData(const QCPGraphData &data) { mData.append(data); }
14 void appendGraphData(const QCPGraphData &data) { mData.append(data); }
15 };
15 };
16
16
17
17
18 /// Format for datetimes on a axis
18 /// Format for datetimes on a axis
19 const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss");
19 const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss");
20
20
21 /// Generates the appropriate ticker for an axis, depending on whether the axis displays time or
21 /// Generates the appropriate ticker for an axis, depending on whether the axis displays time or
22 /// non-time data
22 /// non-time data
23 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis)
23 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis)
24 {
24 {
25 if (isTimeAxis) {
25 if (isTimeAxis) {
26 auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create();
26 auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create();
27 dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT);
27 dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT);
28 dateTicker->setDateTimeSpec(Qt::UTC);
28 dateTicker->setDateTimeSpec(Qt::UTC);
29
29
30 return dateTicker;
30 return dateTicker;
31 }
31 }
32 else {
32 else {
33 // default ticker
33 // default ticker
34 return QSharedPointer<QCPAxisTicker>::create();
34 return QSharedPointer<QCPAxisTicker>::create();
35 }
35 }
36 }
36 }
37
37
38 void updateScalarData(QCPAbstractPlottable *component, ScalarSeries &scalarSeries,
38 void updateScalarData(QCPAbstractPlottable *component, ScalarSeries &scalarSeries,
39 const SqpDateTime &dateTime)
39 const SqpRange &dateTime)
40 {
40 {
41 qCDebug(LOG_VisualizationGraphHelper()) << "TORM: updateScalarData"
41 qCDebug(LOG_VisualizationGraphHelper()) << "TORM: updateScalarData"
42 << QThread::currentThread()->objectName();
42 << QThread::currentThread()->objectName();
43 if (auto qcpGraph = dynamic_cast<QCPGraph *>(component)) {
43 if (auto qcpGraph = dynamic_cast<QCPGraph *>(component)) {
44 scalarSeries.lockRead();
44 scalarSeries.lockRead();
45 {
45 {
46 const auto &xData = scalarSeries.xAxisData()->cdata();
46 const auto &xData = scalarSeries.xAxisData()->cdata();
47 const auto &valuesData = scalarSeries.valuesData()->cdata();
47 const auto &valuesData = scalarSeries.valuesData()->cdata();
48
48
49 auto xDataBegin = xData.cbegin();
49 auto xDataBegin = xData.cbegin();
50 auto xDataEnd = xData.cend();
50 auto xDataEnd = xData.cend();
51
51
52 qCInfo(LOG_VisualizationGraphHelper()) << "TORM: Current points in cache"
52 qCInfo(LOG_VisualizationGraphHelper()) << "TORM: Current points in cache"
53 << xData.count();
53 << xData.count();
54
54
55 auto sqpDataContainer = QSharedPointer<SqpDataContainer>::create();
55 auto sqpDataContainer = QSharedPointer<SqpDataContainer>::create();
56 qcpGraph->setData(sqpDataContainer);
56 qcpGraph->setData(sqpDataContainer);
57
57
58 auto lowerIt = std::lower_bound(xDataBegin, xDataEnd, dateTime.m_TStart);
58 auto lowerIt = std::lower_bound(xDataBegin, xDataEnd, dateTime.m_TStart);
59 auto upperIt = std::upper_bound(xDataBegin, xDataEnd, dateTime.m_TEnd);
59 auto upperIt = std::upper_bound(xDataBegin, xDataEnd, dateTime.m_TEnd);
60 auto distance = std::distance(xDataBegin, lowerIt);
60 auto distance = std::distance(xDataBegin, lowerIt);
61
61
62 auto valuesDataIt = valuesData.cbegin() + distance;
62 auto valuesDataIt = valuesData.cbegin() + distance;
63 for (auto xAxisDataIt = lowerIt; xAxisDataIt != upperIt;
63 for (auto xAxisDataIt = lowerIt; xAxisDataIt != upperIt;
64 ++xAxisDataIt, ++valuesDataIt) {
64 ++xAxisDataIt, ++valuesDataIt) {
65 sqpDataContainer->appendGraphData(QCPGraphData(*xAxisDataIt, *valuesDataIt));
65 sqpDataContainer->appendGraphData(QCPGraphData(*xAxisDataIt, *valuesDataIt));
66 }
66 }
67
67
68 qCInfo(LOG_VisualizationGraphHelper()) << "TORM: Current points displayed"
68 qCInfo(LOG_VisualizationGraphHelper()) << "TORM: Current points displayed"
69 << sqpDataContainer->size();
69 << sqpDataContainer->size();
70 }
70 }
71 scalarSeries.unlock();
71 scalarSeries.unlock();
72
72
73
73
74 // Display all data
74 // Display all data
75 component->parentPlot()->replot();
75 component->parentPlot()->replot();
76 }
76 }
77 else {
77 else {
78 /// @todo DEBUG
78 /// @todo DEBUG
79 }
79 }
80 }
80 }
81
81
82 QCPAbstractPlottable *createScalarSeriesComponent(ScalarSeries &scalarSeries, QCustomPlot &plot,
82 QCPAbstractPlottable *createScalarSeriesComponent(ScalarSeries &scalarSeries, QCustomPlot &plot,
83 const SqpDateTime &dateTime)
83 const SqpRange &dateTime)
84 {
84 {
85 auto component = plot.addGraph();
85 auto component = plot.addGraph();
86
86
87 if (component) {
87 if (component) {
88 // // Graph data
88 // // Graph data
89 component->setData(scalarSeries.xAxisData()->data(), scalarSeries.valuesData()->data(),
89 component->setData(scalarSeries.xAxisData()->data(), scalarSeries.valuesData()->data(),
90 true);
90 true);
91
91
92 updateScalarData(component, scalarSeries, dateTime);
92 updateScalarData(component, scalarSeries, dateTime);
93
93
94 // Axes properties
94 // Axes properties
95 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
95 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
96 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
96 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
97
97
98 auto setAxisProperties = [](auto axis, const auto &unit) {
98 auto setAxisProperties = [](auto axis, const auto &unit) {
99 // label (unit name)
99 // label (unit name)
100 axis->setLabel(unit.m_Name);
100 axis->setLabel(unit.m_Name);
101
101
102 // ticker (depending on the type of unit)
102 // ticker (depending on the type of unit)
103 axis->setTicker(axisTicker(unit.m_TimeUnit));
103 axis->setTicker(axisTicker(unit.m_TimeUnit));
104 };
104 };
105 setAxisProperties(plot.xAxis, scalarSeries.xAxisUnit());
105 setAxisProperties(plot.xAxis, scalarSeries.xAxisUnit());
106 setAxisProperties(plot.yAxis, scalarSeries.valuesUnit());
106 setAxisProperties(plot.yAxis, scalarSeries.valuesUnit());
107
107
108 // Display all data
108 // Display all data
109 component->rescaleAxes();
109 component->rescaleAxes();
110 plot.replot();
110 plot.replot();
111 }
111 }
112 else {
112 else {
113 qCDebug(LOG_VisualizationGraphHelper())
113 qCDebug(LOG_VisualizationGraphHelper())
114 << QObject::tr("Can't create graph for the scalar series");
114 << QObject::tr("Can't create graph for the scalar series");
115 }
115 }
116
116
117 return component;
117 return component;
118 }
118 }
119
119
120 } // namespace
120 } // namespace
121
121
122 QVector<QCPAbstractPlottable *> VisualizationGraphHelper::create(std::shared_ptr<Variable> variable,
122 QVector<QCPAbstractPlottable *> VisualizationGraphHelper::create(std::shared_ptr<Variable> variable,
123 QCustomPlot &plot) noexcept
123 QCustomPlot &plot) noexcept
124 {
124 {
125 auto result = QVector<QCPAbstractPlottable *>{};
125 auto result = QVector<QCPAbstractPlottable *>{};
126
126
127 if (variable) {
127 if (variable) {
128 // Gets the data series of the variable to call the creation of the right components
128 // Gets the data series of the variable to call the creation of the right components
129 // according to its type
129 // according to its type
130 if (auto scalarSeries = dynamic_cast<ScalarSeries *>(variable->dataSeries())) {
130 if (auto scalarSeries = dynamic_cast<ScalarSeries *>(variable->dataSeries())) {
131 result.append(createScalarSeriesComponent(*scalarSeries, plot, variable->dateTime()));
131 result.append(createScalarSeriesComponent(*scalarSeries, plot, variable->dateTime()));
132 }
132 }
133 else {
133 else {
134 qCDebug(LOG_VisualizationGraphHelper())
134 qCDebug(LOG_VisualizationGraphHelper())
135 << QObject::tr("Can't create graph plottables : unmanaged data series type");
135 << QObject::tr("Can't create graph plottables : unmanaged data series type");
136 }
136 }
137 }
137 }
138 else {
138 else {
139 qCDebug(LOG_VisualizationGraphHelper())
139 qCDebug(LOG_VisualizationGraphHelper())
140 << QObject::tr("Can't create graph plottables : the variable is null");
140 << QObject::tr("Can't create graph plottables : the variable is null");
141 }
141 }
142
142
143 return result;
143 return result;
144 }
144 }
145
145
146 void VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *> plotableVect,
146 void VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *> plotableVect,
147 IDataSeries *dataSeries, const SqpDateTime &dateTime)
147 IDataSeries *dataSeries, const SqpRange &dateTime)
148 {
148 {
149 if (auto scalarSeries = dynamic_cast<ScalarSeries *>(dataSeries)) {
149 if (auto scalarSeries = dynamic_cast<ScalarSeries *>(dataSeries)) {
150 if (plotableVect.size() == 1) {
150 if (plotableVect.size() == 1) {
151 updateScalarData(plotableVect.at(0), *scalarSeries, dateTime);
151 updateScalarData(plotableVect.at(0), *scalarSeries, dateTime);
152 }
152 }
153 else {
153 else {
154 qCCritical(LOG_VisualizationGraphHelper()) << QObject::tr(
154 qCCritical(LOG_VisualizationGraphHelper()) << QObject::tr(
155 "Can't update Data of a scalarSeries because there is not only one component "
155 "Can't update Data of a scalarSeries because there is not only one component "
156 "associated");
156 "associated");
157 }
157 }
158 }
158 }
159 else {
159 else {
160 /// @todo DEBUG
160 /// @todo DEBUG
161 }
161 }
162 }
162 }
@@ -1,428 +1,427
1 #include "Visualization/VisualizationGraphWidget.h"
1 #include "Visualization/VisualizationGraphWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/VisualizationGraphHelper.h"
3 #include "Visualization/VisualizationGraphHelper.h"
4 #include "Visualization/VisualizationGraphRenderingDelegate.h"
4 #include "Visualization/VisualizationGraphRenderingDelegate.h"
5 #include "ui_VisualizationGraphWidget.h"
5 #include "ui_VisualizationGraphWidget.h"
6
6
7 #include <Data/ArrayData.h>
7 #include <Data/ArrayData.h>
8 #include <Data/IDataSeries.h>
8 #include <Data/IDataSeries.h>
9 #include <Settings/SqpSettingsDefs.h>
9 #include <Settings/SqpSettingsDefs.h>
10 #include <SqpApplication.h>
10 #include <SqpApplication.h>
11 #include <Variable/Variable.h>
11 #include <Variable/Variable.h>
12 #include <Variable/VariableController.h>
12 #include <Variable/VariableController.h>
13
13
14 #include <unordered_map>
14 #include <unordered_map>
15
15
16 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
16 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
17
17
18 namespace {
18 namespace {
19
19
20 /// Key pressed to enable zoom on horizontal axis
20 /// Key pressed to enable zoom on horizontal axis
21 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
21 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
22
22
23 /// Key pressed to enable zoom on vertical axis
23 /// Key pressed to enable zoom on vertical axis
24 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
24 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
25
25
26 /// Gets a tolerance value from application settings. If the setting can't be found, the default
26 /// Gets a tolerance value from application settings. If the setting can't be found, the default
27 /// value passed in parameter is returned
27 /// value passed in parameter is returned
28 double toleranceValue(const QString &key, double defaultValue) noexcept
28 double toleranceValue(const QString &key, double defaultValue) noexcept
29 {
29 {
30 return QSettings{}.value(key, defaultValue).toDouble();
30 return QSettings{}.value(key, defaultValue).toDouble();
31 }
31 }
32
32
33 } // namespace
33 } // namespace
34
34
35 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
35 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
36
36
37 explicit VisualizationGraphWidgetPrivate()
37 explicit VisualizationGraphWidgetPrivate()
38 : m_DoSynchronize{true}, m_IsCalibration{false}, m_RenderingDelegate{nullptr}
38 : m_DoSynchronize{true}, m_IsCalibration{false}, m_RenderingDelegate{nullptr}
39 {
39 {
40 }
40 }
41
41
42 // Return the operation when range changed
42 // Return the operation when range changed
43 VisualizationGraphWidgetZoomType getZoomType(const QCPRange &t1, const QCPRange &t2);
43 VisualizationGraphWidgetZoomType getZoomType(const QCPRange &t1, const QCPRange &t2);
44
44
45 // 1 variable -> n qcpplot
45 // 1 variable -> n qcpplot
46 std::multimap<std::shared_ptr<Variable>, QCPAbstractPlottable *> m_VariableToPlotMultiMap;
46 std::multimap<std::shared_ptr<Variable>, QCPAbstractPlottable *> m_VariableToPlotMultiMap;
47 bool m_DoSynchronize;
47 bool m_DoSynchronize;
48 bool m_IsCalibration;
48 bool m_IsCalibration;
49 QCPItemTracer *m_TextTracer;
49 QCPItemTracer *m_TextTracer;
50 /// Delegate used to attach rendering features to the plot
50 /// Delegate used to attach rendering features to the plot
51 std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
51 std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
52 };
52 };
53
53
54 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
54 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
55 : QWidget{parent},
55 : QWidget{parent},
56 ui{new Ui::VisualizationGraphWidget},
56 ui{new Ui::VisualizationGraphWidget},
57 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>()}
57 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>()}
58 {
58 {
59 ui->setupUi(this);
59 ui->setupUi(this);
60
60
61 // The delegate must be initialized after the ui as it uses the plot
61 // The delegate must be initialized after the ui as it uses the plot
62 impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*ui->widget);
62 impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*ui->widget);
63
63
64 ui->graphNameLabel->setText(name);
64 ui->graphNameLabel->setText(name);
65
65
66 // 'Close' options : widget is deleted when closed
66 // 'Close' options : widget is deleted when closed
67 setAttribute(Qt::WA_DeleteOnClose);
67 setAttribute(Qt::WA_DeleteOnClose);
68 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationGraphWidget::close);
68 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationGraphWidget::close);
69 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
69 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
70
70
71 // Set qcpplot properties :
71 // Set qcpplot properties :
72 // - Drag (on x-axis) and zoom are enabled
72 // - Drag (on x-axis) and zoom are enabled
73 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
73 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
74 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
74 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
75 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
75 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
76
76
77 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
77 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
78 connect(ui->widget, &QCustomPlot::mouseRelease, this,
78 connect(ui->widget, &QCustomPlot::mouseRelease, this,
79 &VisualizationGraphWidget::onMouseRelease);
79 &VisualizationGraphWidget::onMouseRelease);
80 connect(ui->widget, &QCustomPlot::mouseMove, this, &VisualizationGraphWidget::onMouseMove);
80 connect(ui->widget, &QCustomPlot::mouseMove, this, &VisualizationGraphWidget::onMouseMove);
81 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
81 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
82 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
82 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
83 &QCPAxis::rangeChanged),
83 &QCPAxis::rangeChanged),
84 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
84 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
85
85
86 // Activates menu when right clicking on the graph
86 // Activates menu when right clicking on the graph
87 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
87 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
88 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
88 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
89 &VisualizationGraphWidget::onGraphMenuRequested);
89 &VisualizationGraphWidget::onGraphMenuRequested);
90
90
91 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
91 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
92 &VariableController::onRequestDataLoading);
92 &VariableController::onRequestDataLoading);
93 }
93 }
94
94
95
95
96 VisualizationGraphWidget::~VisualizationGraphWidget()
96 VisualizationGraphWidget::~VisualizationGraphWidget()
97 {
97 {
98 delete ui;
98 delete ui;
99 }
99 }
100
100
101 void VisualizationGraphWidget::enableSynchronize(bool enable)
101 void VisualizationGraphWidget::enableSynchronize(bool enable)
102 {
102 {
103 impl->m_DoSynchronize = enable;
103 impl->m_DoSynchronize = enable;
104 }
104 }
105
105
106 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable)
106 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable)
107 {
107 {
108 // Uses delegate to create the qcpplot components according to the variable
108 // Uses delegate to create the qcpplot components according to the variable
109 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
109 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
110
110
111 for (auto createdPlottable : qAsConst(createdPlottables)) {
111 for (auto createdPlottable : qAsConst(createdPlottables)) {
112 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
112 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
113 }
113 }
114
114
115 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
115 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
116 }
116 }
117 void VisualizationGraphWidget::addVariableUsingGraph(std::shared_ptr<Variable> variable)
117 void VisualizationGraphWidget::addVariableUsingGraph(std::shared_ptr<Variable> variable)
118 {
118 {
119
119
120 // when adding a variable, we need to set its time range to the current graph range
120 // when adding a variable, we need to set its time range to the current graph range
121 auto grapheRange = ui->widget->xAxis->range();
121 auto grapheRange = ui->widget->xAxis->range();
122 auto dateTime = SqpDateTime{grapheRange.lower, grapheRange.upper};
122 auto dateTime = SqpRange{grapheRange.lower, grapheRange.upper};
123 variable->setDateTime(dateTime);
123 variable->setDateTime(dateTime);
124
124
125 auto variableDateTimeWithTolerance = dateTime;
125 auto variableDateTimeWithTolerance = dateTime;
126
126
127 // add tolerance for each side
127 // add tolerance for each side
128 auto toleranceFactor
128 auto toleranceFactor
129 = toleranceValue(GENERAL_TOLERANCE_AT_INIT_KEY, GENERAL_TOLERANCE_AT_INIT_DEFAULT_VALUE);
129 = toleranceValue(GENERAL_TOLERANCE_AT_INIT_KEY, GENERAL_TOLERANCE_AT_INIT_DEFAULT_VALUE);
130 auto tolerance = toleranceFactor * (dateTime.m_TEnd - dateTime.m_TStart);
130 auto tolerance = toleranceFactor * (dateTime.m_TEnd - dateTime.m_TStart);
131 variableDateTimeWithTolerance.m_TStart -= tolerance;
131 variableDateTimeWithTolerance.m_TStart -= tolerance;
132 variableDateTimeWithTolerance.m_TEnd += tolerance;
132 variableDateTimeWithTolerance.m_TEnd += tolerance;
133
133
134 // Uses delegate to create the qcpplot components according to the variable
134 // Uses delegate to create the qcpplot components according to the variable
135 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
135 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
136
136
137 for (auto createdPlottable : qAsConst(createdPlottables)) {
137 for (auto createdPlottable : qAsConst(createdPlottables)) {
138 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
138 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
139 }
139 }
140
140
141 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
141 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
142
142
143 // CHangement detected, we need to ask controller to request data loading
143 // CHangement detected, we need to ask controller to request data loading
144 emit requestDataLoading(variable, variableDateTimeWithTolerance);
144 emit requestDataLoading(variable, variableDateTimeWithTolerance);
145 }
145 }
146
146
147 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
147 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
148 {
148 {
149 // Each component associated to the variable :
149 // Each component associated to the variable :
150 // - is removed from qcpplot (which deletes it)
150 // - is removed from qcpplot (which deletes it)
151 // - is no longer referenced in the map
151 // - is no longer referenced in the map
152 auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
152 auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
153 for (auto it = componentsIt.first; it != componentsIt.second;) {
153 for (auto it = componentsIt.first; it != componentsIt.second;) {
154 ui->widget->removePlottable(it->second);
154 ui->widget->removePlottable(it->second);
155 it = impl->m_VariableToPlotMultiMap.erase(it);
155 it = impl->m_VariableToPlotMultiMap.erase(it);
156 }
156 }
157
157
158 // Updates graph
158 // Updates graph
159 ui->widget->replot();
159 ui->widget->replot();
160 }
160 }
161
161
162 void VisualizationGraphWidget::setRange(std::shared_ptr<Variable> variable,
162 void VisualizationGraphWidget::setRange(std::shared_ptr<Variable> variable, const SqpRange &range)
163 const SqpDateTime &range)
164 {
163 {
165 // Note: in case of different axes that depends on variable, we could start with a code like
164 // Note: in case of different axes that depends on variable, we could start with a code like
166 // that:
165 // that:
167 // auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
166 // auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
168 // for (auto it = componentsIt.first; it != componentsIt.second;) {
167 // for (auto it = componentsIt.first; it != componentsIt.second;) {
169 // }
168 // }
170 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
169 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
171 ui->widget->replot();
170 ui->widget->replot();
172 }
171 }
173
172
174 SqpDateTime VisualizationGraphWidget::graphRange() const noexcept
173 SqpRange VisualizationGraphWidget::graphRange() const noexcept
175 {
174 {
176 auto grapheRange = ui->widget->xAxis->range();
175 auto grapheRange = ui->widget->xAxis->range();
177 return SqpDateTime{grapheRange.lower, grapheRange.upper};
176 return SqpRange{grapheRange.lower, grapheRange.upper};
178 }
177 }
179
178
180 void VisualizationGraphWidget::setGraphRange(const SqpDateTime &range)
179 void VisualizationGraphWidget::setGraphRange(const SqpRange &range)
181 {
180 {
182 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
181 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
183 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
182 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
184 ui->widget->replot();
183 ui->widget->replot();
185 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
184 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
186 }
185 }
187
186
188 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
187 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
189 {
188 {
190 if (visitor) {
189 if (visitor) {
191 visitor->visit(this);
190 visitor->visit(this);
192 }
191 }
193 else {
192 else {
194 qCCritical(LOG_VisualizationGraphWidget())
193 qCCritical(LOG_VisualizationGraphWidget())
195 << tr("Can't visit widget : the visitor is null");
194 << tr("Can't visit widget : the visitor is null");
196 }
195 }
197 }
196 }
198
197
199 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
198 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
200 {
199 {
201 /// @todo : for the moment, a graph can always accomodate a variable
200 /// @todo : for the moment, a graph can always accomodate a variable
202 Q_UNUSED(variable);
201 Q_UNUSED(variable);
203 return true;
202 return true;
204 }
203 }
205
204
206 bool VisualizationGraphWidget::contains(const Variable &variable) const
205 bool VisualizationGraphWidget::contains(const Variable &variable) const
207 {
206 {
208 // Finds the variable among the keys of the map
207 // Finds the variable among the keys of the map
209 auto variablePtr = &variable;
208 auto variablePtr = &variable;
210 auto findVariable
209 auto findVariable
211 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
210 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
212
211
213 auto end = impl->m_VariableToPlotMultiMap.cend();
212 auto end = impl->m_VariableToPlotMultiMap.cend();
214 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
213 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
215 return it != end;
214 return it != end;
216 }
215 }
217
216
218 QString VisualizationGraphWidget::name() const
217 QString VisualizationGraphWidget::name() const
219 {
218 {
220 return ui->graphNameLabel->text();
219 return ui->graphNameLabel->text();
221 }
220 }
222
221
223 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
222 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
224 {
223 {
225 QMenu graphMenu{};
224 QMenu graphMenu{};
226
225
227 // Iterates on variables (unique keys)
226 // Iterates on variables (unique keys)
228 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
227 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
229 end = impl->m_VariableToPlotMultiMap.cend();
228 end = impl->m_VariableToPlotMultiMap.cend();
230 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
229 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
231 // 'Remove variable' action
230 // 'Remove variable' action
232 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
231 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
233 [ this, var = it->first ]() { removeVariable(var); });
232 [ this, var = it->first ]() { removeVariable(var); });
234 }
233 }
235
234
236 if (!graphMenu.isEmpty()) {
235 if (!graphMenu.isEmpty()) {
237 graphMenu.exec(mapToGlobal(pos));
236 graphMenu.exec(mapToGlobal(pos));
238 }
237 }
239 }
238 }
240
239
241 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
240 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
242 {
241 {
243 qCInfo(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::onRangeChanged")
242 qCInfo(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::onRangeChanged")
244 << QThread::currentThread()->objectName();
243 << QThread::currentThread()->objectName();
245
244
246 auto dateTimeRange = SqpDateTime{t1.lower, t1.upper};
245 auto dateTimeRange = SqpRange{t1.lower, t1.upper};
247
246
248 auto zoomType = impl->getZoomType(t1, t2);
247 auto zoomType = impl->getZoomType(t1, t2);
249 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
248 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
250 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
249 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
251
250
252 auto variable = it->first;
251 auto variable = it->first;
253 auto currentDateTime = dateTimeRange;
252 auto currentDateTime = dateTimeRange;
254
253
255 auto toleranceFactor = toleranceValue(GENERAL_TOLERANCE_AT_UPDATE_KEY,
254 auto toleranceFactor = toleranceValue(GENERAL_TOLERANCE_AT_UPDATE_KEY,
256 GENERAL_TOLERANCE_AT_UPDATE_DEFAULT_VALUE);
255 GENERAL_TOLERANCE_AT_UPDATE_DEFAULT_VALUE);
257 auto tolerance = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
256 auto tolerance = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
258 auto variableDateTimeWithTolerance = currentDateTime;
257 auto variableDateTimeWithTolerance = currentDateTime;
259 variableDateTimeWithTolerance.m_TStart -= tolerance;
258 variableDateTimeWithTolerance.m_TStart -= tolerance;
260 variableDateTimeWithTolerance.m_TEnd += tolerance;
259 variableDateTimeWithTolerance.m_TEnd += tolerance;
261
260
262 qCDebug(LOG_VisualizationGraphWidget()) << "r" << currentDateTime;
261 qCDebug(LOG_VisualizationGraphWidget()) << "r" << currentDateTime;
263 qCDebug(LOG_VisualizationGraphWidget()) << "t" << variableDateTimeWithTolerance;
262 qCDebug(LOG_VisualizationGraphWidget()) << "t" << variableDateTimeWithTolerance;
264 qCDebug(LOG_VisualizationGraphWidget()) << "v" << variable->dateTime();
263 qCDebug(LOG_VisualizationGraphWidget()) << "v" << variable->dateTime();
265 // If new range with tol is upper than variable datetime parameters. we need to request new
264 // If new range with tol is upper than variable datetime parameters. we need to request new
266 // data
265 // data
267 if (!variable->contains(variableDateTimeWithTolerance)) {
266 if (!variable->contains(variableDateTimeWithTolerance)) {
268
267
269 auto variableDateTimeWithTolerance = currentDateTime;
268 auto variableDateTimeWithTolerance = currentDateTime;
270 if (!variable->isInside(currentDateTime)) {
269 if (!variable->isInside(currentDateTime)) {
271 auto variableDateTime = variable->dateTime();
270 auto variableDateTime = variable->dateTime();
272 if (variable->contains(variableDateTimeWithTolerance)) {
271 if (variable->contains(variableDateTimeWithTolerance)) {
273 qCDebug(LOG_VisualizationGraphWidget())
272 qCDebug(LOG_VisualizationGraphWidget())
274 << tr("TORM: Detection zoom in that need request:");
273 << tr("TORM: Detection zoom in that need request:");
275 // add tolerance for each side
274 // add tolerance for each side
276 tolerance
275 tolerance
277 = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
276 = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
278 variableDateTimeWithTolerance.m_TStart -= tolerance;
277 variableDateTimeWithTolerance.m_TStart -= tolerance;
279 variableDateTimeWithTolerance.m_TEnd += tolerance;
278 variableDateTimeWithTolerance.m_TEnd += tolerance;
280 }
279 }
281 else if (variableDateTime.m_TStart < currentDateTime.m_TStart) {
280 else if (variableDateTime.m_TStart < currentDateTime.m_TStart) {
282 qCInfo(LOG_VisualizationGraphWidget()) << tr("TORM: Detection pan to right:");
281 qCInfo(LOG_VisualizationGraphWidget()) << tr("TORM: Detection pan to right:");
283
282
284 auto diffEndToKeepDelta = currentDateTime.m_TEnd - variableDateTime.m_TEnd;
283 auto diffEndToKeepDelta = currentDateTime.m_TEnd - variableDateTime.m_TEnd;
285 currentDateTime.m_TStart = variableDateTime.m_TStart + diffEndToKeepDelta;
284 currentDateTime.m_TStart = variableDateTime.m_TStart + diffEndToKeepDelta;
286 // Tolerance have to be added to the right
285 // Tolerance have to be added to the right
287 // add tolerance for right (end) side
286 // add tolerance for right (end) side
288 tolerance
287 tolerance
289 = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
288 = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
290 variableDateTimeWithTolerance.m_TEnd += tolerance;
289 variableDateTimeWithTolerance.m_TEnd += tolerance;
291 }
290 }
292 else if (variableDateTime.m_TEnd > currentDateTime.m_TEnd) {
291 else if (variableDateTime.m_TEnd > currentDateTime.m_TEnd) {
293 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: Detection pan to left: ");
292 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: Detection pan to left: ");
294 auto diffStartToKeepDelta
293 auto diffStartToKeepDelta
295 = variableDateTime.m_TStart - currentDateTime.m_TStart;
294 = variableDateTime.m_TStart - currentDateTime.m_TStart;
296 currentDateTime.m_TEnd = variableDateTime.m_TEnd - diffStartToKeepDelta;
295 currentDateTime.m_TEnd = variableDateTime.m_TEnd - diffStartToKeepDelta;
297 // Tolerance have to be added to the left
296 // Tolerance have to be added to the left
298 // add tolerance for left (start) side
297 // add tolerance for left (start) side
299 tolerance
298 tolerance
300 = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
299 = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
301 variableDateTimeWithTolerance.m_TStart -= tolerance;
300 variableDateTimeWithTolerance.m_TStart -= tolerance;
302 }
301 }
303 else {
302 else {
304 qCCritical(LOG_VisualizationGraphWidget())
303 qCCritical(LOG_VisualizationGraphWidget())
305 << tr("Detection anormal zoom detection: ");
304 << tr("Detection anormal zoom detection: ");
306 }
305 }
307 }
306 }
308 else {
307 else {
309 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: Detection zoom out: ");
308 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: Detection zoom out: ");
310 // add tolerance for each side
309 // add tolerance for each side
311 tolerance = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
310 tolerance = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
312 variableDateTimeWithTolerance.m_TStart -= tolerance;
311 variableDateTimeWithTolerance.m_TStart -= tolerance;
313 variableDateTimeWithTolerance.m_TEnd += tolerance;
312 variableDateTimeWithTolerance.m_TEnd += tolerance;
314 zoomType = VisualizationGraphWidgetZoomType::ZoomOut;
313 zoomType = VisualizationGraphWidgetZoomType::ZoomOut;
315 }
314 }
316 if (!variable->contains(dateTimeRange)) {
315 if (!variable->contains(dateTimeRange)) {
317 qCDebug(LOG_VisualizationGraphWidget())
316 qCDebug(LOG_VisualizationGraphWidget())
318 << "TORM: Modif on variable datetime detected" << currentDateTime;
317 << "TORM: Modif on variable datetime detected" << currentDateTime;
319 variable->setDateTime(currentDateTime);
318 variable->setDateTime(currentDateTime);
320 }
319 }
321
320
322 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: Request data detection: ");
321 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: Request data detection: ");
323 // CHangement detected, we need to ask controller to request data loading
322 // CHangement detected, we need to ask controller to request data loading
324 emit requestDataLoading(variable, variableDateTimeWithTolerance);
323 emit requestDataLoading(variable, variableDateTimeWithTolerance);
325 }
324 }
326 else {
325 else {
327 qCInfo(LOG_VisualizationGraphWidget())
326 qCInfo(LOG_VisualizationGraphWidget())
328 << tr("TORM: Detection zoom in that doesn't need request: ");
327 << tr("TORM: Detection zoom in that doesn't need request: ");
329 zoomType = VisualizationGraphWidgetZoomType::ZoomIn;
328 zoomType = VisualizationGraphWidgetZoomType::ZoomIn;
330 }
329 }
331 }
330 }
332
331
333 if (impl->m_DoSynchronize && !impl->m_IsCalibration) {
332 if (impl->m_DoSynchronize && !impl->m_IsCalibration) {
334 auto oldDateTime = SqpDateTime{t2.lower, t2.upper};
333 auto oldDateTime = SqpRange{t2.lower, t2.upper};
335 qCDebug(LOG_VisualizationGraphWidget())
334 qCDebug(LOG_VisualizationGraphWidget())
336 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
335 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
337 << QThread::currentThread()->objectName();
336 << QThread::currentThread()->objectName();
338 emit synchronize(dateTimeRange, oldDateTime, zoomType);
337 emit synchronize(dateTimeRange, oldDateTime, zoomType);
339 }
338 }
340 }
339 }
341
340
342 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
341 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
343 {
342 {
344 // Handles plot rendering when mouse is moving
343 // Handles plot rendering when mouse is moving
345 impl->m_RenderingDelegate->onMouseMove(event);
344 impl->m_RenderingDelegate->onMouseMove(event);
346 }
345 }
347
346
348 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
347 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
349 {
348 {
350 auto zoomOrientations = QFlags<Qt::Orientation>{};
349 auto zoomOrientations = QFlags<Qt::Orientation>{};
351
350
352 // Lambda that enables a zoom orientation if the key modifier related to this orientation
351 // Lambda that enables a zoom orientation if the key modifier related to this orientation
353 // has
352 // has
354 // been pressed
353 // been pressed
355 auto enableOrientation
354 auto enableOrientation
356 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
355 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
357 auto orientationEnabled = event->modifiers().testFlag(modifier);
356 auto orientationEnabled = event->modifiers().testFlag(modifier);
358 zoomOrientations.setFlag(orientation, orientationEnabled);
357 zoomOrientations.setFlag(orientation, orientationEnabled);
359 };
358 };
360 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
359 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
361 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
360 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
362
361
363 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
362 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
364 }
363 }
365
364
366 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
365 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
367 {
366 {
368 impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
367 impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
369 }
368 }
370
369
371 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
370 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
372 {
371 {
373 impl->m_IsCalibration = false;
372 impl->m_IsCalibration = false;
374 }
373 }
375
374
376 void VisualizationGraphWidget::onDataCacheVariableUpdated()
375 void VisualizationGraphWidget::onDataCacheVariableUpdated()
377 {
376 {
378 // NOTE:
377 // NOTE:
379 // We don't want to call the method for each component of a variable unitarily, but for
378 // We don't want to call the method for each component of a variable unitarily, but for
380 // all
379 // all
381 // its components at once (eg its three components in the case of a vector).
380 // its components at once (eg its three components in the case of a vector).
382
381
383 // The unordered_multimap does not do this easily, so the question is whether to:
382 // The unordered_multimap does not do this easily, so the question is whether to:
384 // - use an ordered_multimap and the algos of std to group the values by key
383 // - use an ordered_multimap and the algos of std to group the values by key
385 // - use a map (unique keys) and store as values directly the list of components
384 // - use a map (unique keys) and store as values directly the list of components
386
385
387 auto grapheRange = ui->widget->xAxis->range();
386 auto grapheRange = ui->widget->xAxis->range();
388 auto dateTime = SqpDateTime{grapheRange.lower, grapheRange.upper};
387 auto dateTime = SqpRange{grapheRange.lower, grapheRange.upper};
389
388
390 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
389 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
391 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
390 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
392 auto variable = it->first;
391 auto variable = it->first;
393 qCDebug(LOG_VisualizationGraphWidget())
392 qCDebug(LOG_VisualizationGraphWidget())
394 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S"
393 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S"
395 << variable->dateTime();
394 << variable->dateTime();
396 qCDebug(LOG_VisualizationGraphWidget())
395 qCDebug(LOG_VisualizationGraphWidget())
397 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
396 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
398 if (dateTime.contains(variable->dateTime()) || dateTime.intersect(variable->dateTime())) {
397 if (dateTime.contains(variable->dateTime()) || dateTime.intersect(variable->dateTime())) {
399
398
400 VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
399 VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
401 variable->dataSeries(), variable->dateTime());
400 variable->dataSeries(), variable->dateTime());
402 }
401 }
403 }
402 }
404 }
403 }
405
404
406 VisualizationGraphWidgetZoomType
405 VisualizationGraphWidgetZoomType
407 VisualizationGraphWidget::VisualizationGraphWidgetPrivate::getZoomType(const QCPRange &t1,
406 VisualizationGraphWidget::VisualizationGraphWidgetPrivate::getZoomType(const QCPRange &t1,
408 const QCPRange &t2)
407 const QCPRange &t2)
409 {
408 {
410 // t1.lower <= t2.lower && t2.upper <= t1.upper
409 // t1.lower <= t2.lower && t2.upper <= t1.upper
411 auto zoomType = VisualizationGraphWidgetZoomType::Unknown;
410 auto zoomType = VisualizationGraphWidgetZoomType::Unknown;
412 if (t1.lower <= t2.lower && t2.upper <= t1.upper) {
411 if (t1.lower <= t2.lower && t2.upper <= t1.upper) {
413 zoomType = VisualizationGraphWidgetZoomType::ZoomOut;
412 zoomType = VisualizationGraphWidgetZoomType::ZoomOut;
414 }
413 }
415 else if (t1.lower > t2.lower && t1.upper > t2.upper) {
414 else if (t1.lower > t2.lower && t1.upper > t2.upper) {
416 zoomType = VisualizationGraphWidgetZoomType::PanRight;
415 zoomType = VisualizationGraphWidgetZoomType::PanRight;
417 }
416 }
418 else if (t1.lower < t2.lower && t1.upper < t2.upper) {
417 else if (t1.lower < t2.lower && t1.upper < t2.upper) {
419 zoomType = VisualizationGraphWidgetZoomType::PanLeft;
418 zoomType = VisualizationGraphWidgetZoomType::PanLeft;
420 }
419 }
421 else if (t1.lower > t2.lower && t2.upper > t1.upper) {
420 else if (t1.lower > t2.lower && t2.upper > t1.upper) {
422 zoomType = VisualizationGraphWidgetZoomType::ZoomIn;
421 zoomType = VisualizationGraphWidgetZoomType::ZoomIn;
423 }
422 }
424 else {
423 else {
425 qCCritical(LOG_VisualizationGraphWidget()) << "getZoomType: Unknown type detected";
424 qCCritical(LOG_VisualizationGraphWidget()) << "getZoomType: Unknown type detected";
426 }
425 }
427 return zoomType;
426 return zoomType;
428 }
427 }
@@ -1,152 +1,152
1 #include "Visualization/VisualizationWidget.h"
1 #include "Visualization/VisualizationWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/VisualizationGraphWidget.h"
3 #include "Visualization/VisualizationGraphWidget.h"
4 #include "Visualization/VisualizationTabWidget.h"
4 #include "Visualization/VisualizationTabWidget.h"
5 #include "Visualization/VisualizationZoneWidget.h"
5 #include "Visualization/VisualizationZoneWidget.h"
6 #include "Visualization/operations/GenerateVariableMenuOperation.h"
6 #include "Visualization/operations/GenerateVariableMenuOperation.h"
7 #include "Visualization/operations/RemoveVariableOperation.h"
7 #include "Visualization/operations/RemoveVariableOperation.h"
8 #include "Visualization/operations/RescaleAxeOperation.h"
8 #include "Visualization/operations/RescaleAxeOperation.h"
9 #include "Visualization/qcustomplot.h"
9 #include "Visualization/qcustomplot.h"
10
10
11 #include "ui_VisualizationWidget.h"
11 #include "ui_VisualizationWidget.h"
12
12
13 #include <QToolButton>
13 #include <QToolButton>
14
14
15 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
15 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
16
16
17 VisualizationWidget::VisualizationWidget(QWidget *parent)
17 VisualizationWidget::VisualizationWidget(QWidget *parent)
18 : QWidget{parent}, ui{new Ui::VisualizationWidget}
18 : QWidget{parent}, ui{new Ui::VisualizationWidget}
19 {
19 {
20 ui->setupUi(this);
20 ui->setupUi(this);
21
21
22 auto addTabViewButton = new QToolButton{ui->tabWidget};
22 auto addTabViewButton = new QToolButton{ui->tabWidget};
23 addTabViewButton->setText(tr("Add View"));
23 addTabViewButton->setText(tr("Add View"));
24 addTabViewButton->setCursor(Qt::ArrowCursor);
24 addTabViewButton->setCursor(Qt::ArrowCursor);
25 ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner);
25 ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner);
26
26
27 auto enableMinimumCornerWidgetSize = [this](bool enable) {
27 auto enableMinimumCornerWidgetSize = [this](bool enable) {
28
28
29 auto tabViewCornerWidget = ui->tabWidget->cornerWidget();
29 auto tabViewCornerWidget = ui->tabWidget->cornerWidget();
30 auto width = enable ? tabViewCornerWidget->width() : 0;
30 auto width = enable ? tabViewCornerWidget->width() : 0;
31 auto height = enable ? tabViewCornerWidget->height() : 0;
31 auto height = enable ? tabViewCornerWidget->height() : 0;
32 tabViewCornerWidget->setMinimumHeight(height);
32 tabViewCornerWidget->setMinimumHeight(height);
33 tabViewCornerWidget->setMinimumWidth(width);
33 tabViewCornerWidget->setMinimumWidth(width);
34 ui->tabWidget->setMinimumHeight(height);
34 ui->tabWidget->setMinimumHeight(height);
35 ui->tabWidget->setMinimumWidth(width);
35 ui->tabWidget->setMinimumWidth(width);
36 };
36 };
37
37
38 auto addTabView = [this, enableMinimumCornerWidgetSize]() {
38 auto addTabView = [this, enableMinimumCornerWidgetSize]() {
39 auto widget = new VisualizationTabWidget{QString{"View %1"}.arg(ui->tabWidget->count() + 1),
39 auto widget = new VisualizationTabWidget{QString{"View %1"}.arg(ui->tabWidget->count() + 1),
40 ui->tabWidget};
40 ui->tabWidget};
41 auto index = ui->tabWidget->addTab(widget, widget->name());
41 auto index = ui->tabWidget->addTab(widget, widget->name());
42 if (ui->tabWidget->count() > 0) {
42 if (ui->tabWidget->count() > 0) {
43 enableMinimumCornerWidgetSize(false);
43 enableMinimumCornerWidgetSize(false);
44 }
44 }
45 qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index);
45 qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index);
46 };
46 };
47
47
48 auto removeTabView = [this, enableMinimumCornerWidgetSize](int index) {
48 auto removeTabView = [this, enableMinimumCornerWidgetSize](int index) {
49 if (ui->tabWidget->count() == 1) {
49 if (ui->tabWidget->count() == 1) {
50 enableMinimumCornerWidgetSize(true);
50 enableMinimumCornerWidgetSize(true);
51 }
51 }
52
52
53 // Removes widget from tab and closes it
53 // Removes widget from tab and closes it
54 auto widget = ui->tabWidget->widget(index);
54 auto widget = ui->tabWidget->widget(index);
55 ui->tabWidget->removeTab(index);
55 ui->tabWidget->removeTab(index);
56 if (widget) {
56 if (widget) {
57 widget->close();
57 widget->close();
58 }
58 }
59
59
60 qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index);
60 qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index);
61
61
62 };
62 };
63
63
64 ui->tabWidget->setTabsClosable(true);
64 ui->tabWidget->setTabsClosable(true);
65
65
66 connect(addTabViewButton, &QToolButton::clicked, addTabView);
66 connect(addTabViewButton, &QToolButton::clicked, addTabView);
67 connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView);
67 connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView);
68
68
69 // Adds default tab
69 // Adds default tab
70 addTabView();
70 addTabView();
71 }
71 }
72
72
73 VisualizationWidget::~VisualizationWidget()
73 VisualizationWidget::~VisualizationWidget()
74 {
74 {
75 delete ui;
75 delete ui;
76 }
76 }
77
77
78 void VisualizationWidget::accept(IVisualizationWidgetVisitor *visitor)
78 void VisualizationWidget::accept(IVisualizationWidgetVisitor *visitor)
79 {
79 {
80 if (visitor) {
80 if (visitor) {
81 visitor->visitEnter(this);
81 visitor->visitEnter(this);
82
82
83 // Apply visitor for tab children
83 // Apply visitor for tab children
84 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
84 for (auto i = 0; i < ui->tabWidget->count(); ++i) {
85 // Widgets different from tabs are not visited (no action)
85 // Widgets different from tabs are not visited (no action)
86 if (auto visualizationTabWidget
86 if (auto visualizationTabWidget
87 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
87 = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->widget(i))) {
88 visualizationTabWidget->accept(visitor);
88 visualizationTabWidget->accept(visitor);
89 }
89 }
90 }
90 }
91
91
92 visitor->visitLeave(this);
92 visitor->visitLeave(this);
93 }
93 }
94 else {
94 else {
95 qCCritical(LOG_VisualizationWidget()) << tr("Can't visit widget : the visitor is null");
95 qCCritical(LOG_VisualizationWidget()) << tr("Can't visit widget : the visitor is null");
96 }
96 }
97 }
97 }
98
98
99 bool VisualizationWidget::canDrop(const Variable &variable) const
99 bool VisualizationWidget::canDrop(const Variable &variable) const
100 {
100 {
101 // The main widget can never accomodate a variable
101 // The main widget can never accomodate a variable
102 Q_UNUSED(variable);
102 Q_UNUSED(variable);
103 return false;
103 return false;
104 }
104 }
105
105
106 bool VisualizationWidget::contains(const Variable &variable) const
106 bool VisualizationWidget::contains(const Variable &variable) const
107 {
107 {
108 Q_UNUSED(variable);
108 Q_UNUSED(variable);
109 return false;
109 return false;
110 }
110 }
111
111
112 QString VisualizationWidget::name() const
112 QString VisualizationWidget::name() const
113 {
113 {
114 return QStringLiteral("MainView");
114 return QStringLiteral("MainView");
115 }
115 }
116
116
117 void VisualizationWidget::attachVariableMenu(
117 void VisualizationWidget::attachVariableMenu(
118 QMenu *menu, const QVector<std::shared_ptr<Variable> > &variables) noexcept
118 QMenu *menu, const QVector<std::shared_ptr<Variable> > &variables) noexcept
119 {
119 {
120 // Menu is generated only if there is a single variable
120 // Menu is generated only if there is a single variable
121 if (variables.size() == 1) {
121 if (variables.size() == 1) {
122 if (auto variable = variables.first()) {
122 if (auto variable = variables.first()) {
123 // Generates the actions that make it possible to visualize the variable
123 // Generates the actions that make it possible to visualize the variable
124 auto generateVariableMenuOperation = GenerateVariableMenuOperation{menu, variable};
124 auto generateVariableMenuOperation = GenerateVariableMenuOperation{menu, variable};
125 accept(&generateVariableMenuOperation);
125 accept(&generateVariableMenuOperation);
126 }
126 }
127 else {
127 else {
128 qCCritical(LOG_VisualizationWidget()) << tr(
128 qCCritical(LOG_VisualizationWidget()) << tr(
129 "Can't generate the menu relative to the visualization: the variable is null");
129 "Can't generate the menu relative to the visualization: the variable is null");
130 }
130 }
131 }
131 }
132 else {
132 else {
133 qCDebug(LOG_VisualizationWidget())
133 qCDebug(LOG_VisualizationWidget())
134 << tr("No generation of the menu related to the visualization: several variables are "
134 << tr("No generation of the menu related to the visualization: several variables are "
135 "selected");
135 "selected");
136 }
136 }
137 }
137 }
138
138
139 void VisualizationWidget::onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept
139 void VisualizationWidget::onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept
140 {
140 {
141 // Calls the operation of removing all references to the variable in the visualization
141 // Calls the operation of removing all references to the variable in the visualization
142 auto removeVariableOperation = RemoveVariableOperation{variable};
142 auto removeVariableOperation = RemoveVariableOperation{variable};
143 accept(&removeVariableOperation);
143 accept(&removeVariableOperation);
144 }
144 }
145
145
146 void VisualizationWidget::onRangeChanged(std::shared_ptr<Variable> variable,
146 void VisualizationWidget::onRangeChanged(std::shared_ptr<Variable> variable,
147 const SqpDateTime &range) noexcept
147 const SqpRange &range) noexcept
148 {
148 {
149 // Calls the operation of rescaling all graph that contrains variable in the visualization
149 // Calls the operation of rescaling all graph that contrains variable in the visualization
150 auto rescaleVariableOperation = RescaleAxeOperation{variable, range};
150 auto rescaleVariableOperation = RescaleAxeOperation{variable, range};
151 accept(&rescaleVariableOperation);
151 accept(&rescaleVariableOperation);
152 }
152 }
@@ -1,200 +1,200
1 #include "Visualization/VisualizationZoneWidget.h"
1 #include "Visualization/VisualizationZoneWidget.h"
2
2
3 #include "Data/SqpDateTime.h"
3 #include "Data/SqpRange.h"
4
4
5 #include "Visualization/IVisualizationWidgetVisitor.h"
5 #include "Visualization/IVisualizationWidgetVisitor.h"
6 #include "Visualization/VisualizationGraphWidget.h"
6 #include "Visualization/VisualizationGraphWidget.h"
7 #include "ui_VisualizationZoneWidget.h"
7 #include "ui_VisualizationZoneWidget.h"
8
8
9
9
10 #include <SqpApplication.h>
10 #include <SqpApplication.h>
11
11
12 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
12 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
13
13
14 namespace {
14 namespace {
15
15
16 /// Minimum height for graph added in zones (in pixels)
16 /// Minimum height for graph added in zones (in pixels)
17 const auto GRAPH_MINIMUM_HEIGHT = 300;
17 const auto GRAPH_MINIMUM_HEIGHT = 300;
18
18
19 /// Generates a default name for a new graph, according to the number of graphs already displayed in
19 /// Generates a default name for a new graph, according to the number of graphs already displayed in
20 /// the zone
20 /// the zone
21 QString defaultGraphName(const QLayout &layout)
21 QString defaultGraphName(const QLayout &layout)
22 {
22 {
23 auto count = 0;
23 auto count = 0;
24 for (auto i = 0; i < layout.count(); ++i) {
24 for (auto i = 0; i < layout.count(); ++i) {
25 if (dynamic_cast<VisualizationGraphWidget *>(layout.itemAt(i)->widget())) {
25 if (dynamic_cast<VisualizationGraphWidget *>(layout.itemAt(i)->widget())) {
26 count++;
26 count++;
27 }
27 }
28 }
28 }
29
29
30 return QObject::tr("Graph %1").arg(count + 1);
30 return QObject::tr("Graph %1").arg(count + 1);
31 }
31 }
32
32
33 } // namespace
33 } // namespace
34
34
35 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
35 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
36 : QWidget{parent}, ui{new Ui::VisualizationZoneWidget}
36 : QWidget{parent}, ui{new Ui::VisualizationZoneWidget}
37 {
37 {
38 ui->setupUi(this);
38 ui->setupUi(this);
39
39
40 ui->zoneNameLabel->setText(name);
40 ui->zoneNameLabel->setText(name);
41
41
42 // 'Close' options : widget is deleted when closed
42 // 'Close' options : widget is deleted when closed
43 setAttribute(Qt::WA_DeleteOnClose);
43 setAttribute(Qt::WA_DeleteOnClose);
44 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
44 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
45 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
45 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
46 }
46 }
47
47
48 VisualizationZoneWidget::~VisualizationZoneWidget()
48 VisualizationZoneWidget::~VisualizationZoneWidget()
49 {
49 {
50 delete ui;
50 delete ui;
51 }
51 }
52
52
53 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
53 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
54 {
54 {
55 ui->visualizationZoneFrame->layout()->addWidget(graphWidget);
55 ui->visualizationZoneFrame->layout()->addWidget(graphWidget);
56 }
56 }
57
57
58 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
58 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
59 {
59 {
60 auto graphWidget = new VisualizationGraphWidget{
60 auto graphWidget = new VisualizationGraphWidget{
61 defaultGraphName(*ui->visualizationZoneFrame->layout()), this};
61 defaultGraphName(*ui->visualizationZoneFrame->layout()), this};
62
62
63
63
64 // Set graph properties
64 // Set graph properties
65 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
65 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
66 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
66 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
67
67
68 this->addGraph(graphWidget);
68 this->addGraph(graphWidget);
69
69
70 graphWidget->addVariable(variable);
70 graphWidget->addVariable(variable);
71
71
72 // Lambda to synchronize zone widget
72 // Lambda to synchronize zone widget
73 auto synchronizeZoneWidget = [this, graphWidget](const SqpDateTime &dateTime,
73 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &dateTime,
74 const SqpDateTime &oldDateTime,
74 const SqpRange &oldDateTime,
75 VisualizationGraphWidgetZoomType zoomType) {
75 VisualizationGraphWidgetZoomType zoomType) {
76 auto frameLayout = ui->visualizationZoneFrame->layout();
76 auto frameLayout = ui->visualizationZoneFrame->layout();
77 for (auto i = 0; i < frameLayout->count(); ++i) {
77 for (auto i = 0; i < frameLayout->count(); ++i) {
78 auto graphChild
78 auto graphChild
79 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
79 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
80 if (graphChild && (graphChild != graphWidget)) {
80 if (graphChild && (graphChild != graphWidget)) {
81
81
82 auto graphChildRange = graphChild->graphRange();
82 auto graphChildRange = graphChild->graphRange();
83 switch (zoomType) {
83 switch (zoomType) {
84 case VisualizationGraphWidgetZoomType::ZoomIn: {
84 case VisualizationGraphWidgetZoomType::ZoomIn: {
85 auto deltaLeft = dateTime.m_TStart - oldDateTime.m_TStart;
85 auto deltaLeft = dateTime.m_TStart - oldDateTime.m_TStart;
86 auto deltaRight = oldDateTime.m_TEnd - dateTime.m_TEnd;
86 auto deltaRight = oldDateTime.m_TEnd - dateTime.m_TEnd;
87 graphChildRange.m_TStart += deltaLeft;
87 graphChildRange.m_TStart += deltaLeft;
88 graphChildRange.m_TEnd -= deltaRight;
88 graphChildRange.m_TEnd -= deltaRight;
89 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
89 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
90 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
90 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
91 << deltaLeft;
91 << deltaLeft;
92 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
92 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
93 << deltaRight;
93 << deltaRight;
94 qCCritical(LOG_VisualizationZoneWidget())
94 qCCritical(LOG_VisualizationZoneWidget())
95 << tr("TORM: dt") << dateTime.m_TEnd - dateTime.m_TStart;
95 << tr("TORM: dt") << dateTime.m_TEnd - dateTime.m_TStart;
96
96
97 break;
97 break;
98 }
98 }
99
99
100 case VisualizationGraphWidgetZoomType::ZoomOut: {
100 case VisualizationGraphWidgetZoomType::ZoomOut: {
101 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
101 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
102 auto deltaLeft = oldDateTime.m_TStart - dateTime.m_TStart;
102 auto deltaLeft = oldDateTime.m_TStart - dateTime.m_TStart;
103 auto deltaRight = dateTime.m_TEnd - oldDateTime.m_TEnd;
103 auto deltaRight = dateTime.m_TEnd - oldDateTime.m_TEnd;
104 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
104 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
105 << deltaLeft;
105 << deltaLeft;
106 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
106 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
107 << deltaRight;
107 << deltaRight;
108 qCCritical(LOG_VisualizationZoneWidget())
108 qCCritical(LOG_VisualizationZoneWidget())
109 << tr("TORM: dt") << dateTime.m_TEnd - dateTime.m_TStart;
109 << tr("TORM: dt") << dateTime.m_TEnd - dateTime.m_TStart;
110 graphChildRange.m_TStart -= deltaLeft;
110 graphChildRange.m_TStart -= deltaLeft;
111 graphChildRange.m_TEnd += deltaRight;
111 graphChildRange.m_TEnd += deltaRight;
112 break;
112 break;
113 }
113 }
114 case VisualizationGraphWidgetZoomType::PanRight: {
114 case VisualizationGraphWidgetZoomType::PanRight: {
115 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
115 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
116 auto deltaRight = dateTime.m_TEnd - oldDateTime.m_TEnd;
116 auto deltaRight = dateTime.m_TEnd - oldDateTime.m_TEnd;
117 graphChildRange.m_TStart += deltaRight;
117 graphChildRange.m_TStart += deltaRight;
118 graphChildRange.m_TEnd += deltaRight;
118 graphChildRange.m_TEnd += deltaRight;
119 qCCritical(LOG_VisualizationZoneWidget())
119 qCCritical(LOG_VisualizationZoneWidget())
120 << tr("TORM: dt") << dateTime.m_TEnd - dateTime.m_TStart;
120 << tr("TORM: dt") << dateTime.m_TEnd - dateTime.m_TStart;
121 break;
121 break;
122 }
122 }
123 case VisualizationGraphWidgetZoomType::PanLeft: {
123 case VisualizationGraphWidgetZoomType::PanLeft: {
124 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
124 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
125 auto deltaLeft = oldDateTime.m_TStart - dateTime.m_TStart;
125 auto deltaLeft = oldDateTime.m_TStart - dateTime.m_TStart;
126 graphChildRange.m_TStart -= deltaLeft;
126 graphChildRange.m_TStart -= deltaLeft;
127 graphChildRange.m_TEnd -= deltaLeft;
127 graphChildRange.m_TEnd -= deltaLeft;
128 break;
128 break;
129 }
129 }
130 case VisualizationGraphWidgetZoomType::Unknown: {
130 case VisualizationGraphWidgetZoomType::Unknown: {
131 qCCritical(LOG_VisualizationZoneWidget())
131 qCCritical(LOG_VisualizationZoneWidget())
132 << tr("Impossible to synchronize: zoom type unknown");
132 << tr("Impossible to synchronize: zoom type unknown");
133 break;
133 break;
134 }
134 }
135 default:
135 default:
136 qCCritical(LOG_VisualizationZoneWidget())
136 qCCritical(LOG_VisualizationZoneWidget())
137 << tr("Impossible to synchronize: zoom type not take into account");
137 << tr("Impossible to synchronize: zoom type not take into account");
138 // No action
138 // No action
139 break;
139 break;
140 }
140 }
141 graphChild->enableSynchronize(false);
141 graphChild->enableSynchronize(false);
142 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
142 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
143 << graphChild->graphRange();
143 << graphChild->graphRange();
144 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
144 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
145 << graphChildRange;
145 << graphChildRange;
146 qCCritical(LOG_VisualizationZoneWidget())
146 qCCritical(LOG_VisualizationZoneWidget())
147 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
147 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
148 graphChild->setGraphRange(graphChildRange);
148 graphChild->setGraphRange(graphChildRange);
149 graphChild->enableSynchronize(true);
149 graphChild->enableSynchronize(true);
150 }
150 }
151 }
151 }
152 };
152 };
153
153
154 // connection for synchronization
154 // connection for synchronization
155 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
155 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
156
156
157 return graphWidget;
157 return graphWidget;
158 }
158 }
159
159
160 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
160 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
161 {
161 {
162 if (visitor) {
162 if (visitor) {
163 visitor->visitEnter(this);
163 visitor->visitEnter(this);
164
164
165 // Apply visitor to graph children
165 // Apply visitor to graph children
166 auto layout = ui->visualizationZoneFrame->layout();
166 auto layout = ui->visualizationZoneFrame->layout();
167 for (auto i = 0; i < layout->count(); ++i) {
167 for (auto i = 0; i < layout->count(); ++i) {
168 if (auto item = layout->itemAt(i)) {
168 if (auto item = layout->itemAt(i)) {
169 // Widgets different from graphs are not visited (no action)
169 // Widgets different from graphs are not visited (no action)
170 if (auto visualizationGraphWidget
170 if (auto visualizationGraphWidget
171 = dynamic_cast<VisualizationGraphWidget *>(item->widget())) {
171 = dynamic_cast<VisualizationGraphWidget *>(item->widget())) {
172 visualizationGraphWidget->accept(visitor);
172 visualizationGraphWidget->accept(visitor);
173 }
173 }
174 }
174 }
175 }
175 }
176
176
177 visitor->visitLeave(this);
177 visitor->visitLeave(this);
178 }
178 }
179 else {
179 else {
180 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
180 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
181 }
181 }
182 }
182 }
183
183
184 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
184 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
185 {
185 {
186 // A tab can always accomodate a variable
186 // A tab can always accomodate a variable
187 Q_UNUSED(variable);
187 Q_UNUSED(variable);
188 return true;
188 return true;
189 }
189 }
190
190
191 bool VisualizationZoneWidget::contains(const Variable &variable) const
191 bool VisualizationZoneWidget::contains(const Variable &variable) const
192 {
192 {
193 Q_UNUSED(variable);
193 Q_UNUSED(variable);
194 return false;
194 return false;
195 }
195 }
196
196
197 QString VisualizationZoneWidget::name() const
197 QString VisualizationZoneWidget::name() const
198 {
198 {
199 return ui->zoneNameLabel->text();
199 return ui->zoneNameLabel->text();
200 }
200 }
@@ -1,71 +1,69
1 #include "Visualization/operations/RescaleAxeOperation.h"
1 #include "Visualization/operations/RescaleAxeOperation.h"
2 #include "Visualization/VisualizationGraphWidget.h"
2 #include "Visualization/VisualizationGraphWidget.h"
3
3
4 Q_LOGGING_CATEGORY(LOG_RescaleAxeOperation, "RescaleAxeOperation")
4 Q_LOGGING_CATEGORY(LOG_RescaleAxeOperation, "RescaleAxeOperation")
5
5
6 struct RescaleAxeOperation::RescaleAxeOperationPrivate {
6 struct RescaleAxeOperation::RescaleAxeOperationPrivate {
7 explicit RescaleAxeOperationPrivate(std::shared_ptr<Variable> variable,
7 explicit RescaleAxeOperationPrivate(std::shared_ptr<Variable> variable, const SqpRange &range)
8 const SqpDateTime &range)
9 : m_Variable{variable}, m_Range{range}
8 : m_Variable{variable}, m_Range{range}
10 {
9 {
11 }
10 }
12
11
13 std::shared_ptr<Variable> m_Variable;
12 std::shared_ptr<Variable> m_Variable;
14 SqpDateTime m_Range;
13 SqpRange m_Range;
15 };
14 };
16
15
17 RescaleAxeOperation::RescaleAxeOperation(std::shared_ptr<Variable> variable,
16 RescaleAxeOperation::RescaleAxeOperation(std::shared_ptr<Variable> variable, const SqpRange &range)
18 const SqpDateTime &range)
19 : impl{spimpl::make_unique_impl<RescaleAxeOperationPrivate>(variable, range)}
17 : impl{spimpl::make_unique_impl<RescaleAxeOperationPrivate>(variable, range)}
20 {
18 {
21 }
19 }
22
20
23 void RescaleAxeOperation::visitEnter(VisualizationWidget *widget)
21 void RescaleAxeOperation::visitEnter(VisualizationWidget *widget)
24 {
22 {
25 // VisualizationWidget is not intended to contain a variable
23 // VisualizationWidget is not intended to contain a variable
26 Q_UNUSED(widget)
24 Q_UNUSED(widget)
27 }
25 }
28
26
29 void RescaleAxeOperation::visitLeave(VisualizationWidget *widget)
27 void RescaleAxeOperation::visitLeave(VisualizationWidget *widget)
30 {
28 {
31 // VisualizationWidget is not intended to contain a variable
29 // VisualizationWidget is not intended to contain a variable
32 Q_UNUSED(widget)
30 Q_UNUSED(widget)
33 }
31 }
34
32
35 void RescaleAxeOperation::visitEnter(VisualizationTabWidget *tabWidget)
33 void RescaleAxeOperation::visitEnter(VisualizationTabWidget *tabWidget)
36 {
34 {
37 // VisualizationTabWidget is not intended to contain a variable
35 // VisualizationTabWidget is not intended to contain a variable
38 Q_UNUSED(tabWidget)
36 Q_UNUSED(tabWidget)
39 }
37 }
40
38
41 void RescaleAxeOperation::visitLeave(VisualizationTabWidget *tabWidget)
39 void RescaleAxeOperation::visitLeave(VisualizationTabWidget *tabWidget)
42 {
40 {
43 // VisualizationTabWidget is not intended to contain a variable
41 // VisualizationTabWidget is not intended to contain a variable
44 Q_UNUSED(tabWidget)
42 Q_UNUSED(tabWidget)
45 }
43 }
46
44
47 void RescaleAxeOperation::visitEnter(VisualizationZoneWidget *zoneWidget)
45 void RescaleAxeOperation::visitEnter(VisualizationZoneWidget *zoneWidget)
48 {
46 {
49 // VisualizationZoneWidget is not intended to contain a variable
47 // VisualizationZoneWidget is not intended to contain a variable
50 Q_UNUSED(zoneWidget)
48 Q_UNUSED(zoneWidget)
51 }
49 }
52
50
53 void RescaleAxeOperation::visitLeave(VisualizationZoneWidget *zoneWidget)
51 void RescaleAxeOperation::visitLeave(VisualizationZoneWidget *zoneWidget)
54 {
52 {
55 // VisualizationZoneWidget is not intended to contain a variable
53 // VisualizationZoneWidget is not intended to contain a variable
56 Q_UNUSED(zoneWidget)
54 Q_UNUSED(zoneWidget)
57 }
55 }
58
56
59 void RescaleAxeOperation::visit(VisualizationGraphWidget *graphWidget)
57 void RescaleAxeOperation::visit(VisualizationGraphWidget *graphWidget)
60 {
58 {
61 if (graphWidget) {
59 if (graphWidget) {
62 // If the widget contains the variable, rescale it
60 // If the widget contains the variable, rescale it
63 if (impl->m_Variable && graphWidget->contains(*impl->m_Variable)) {
61 if (impl->m_Variable && graphWidget->contains(*impl->m_Variable)) {
64 graphWidget->setRange(impl->m_Variable, impl->m_Range);
62 graphWidget->setRange(impl->m_Variable, impl->m_Range);
65 }
63 }
66 }
64 }
67 else {
65 else {
68 qCCritical(LOG_RescaleAxeOperation(),
66 qCCritical(LOG_RescaleAxeOperation(),
69 "Can't visit VisualizationGraphWidget : the widget is null");
67 "Can't visit VisualizationGraphWidget : the widget is null");
70 }
68 }
71 }
69 }
@@ -1,30 +1,30
1 #ifndef SCIQLOP_AMDAPROVIDER_H
1 #ifndef SCIQLOP_AMDAPROVIDER_H
2 #define SCIQLOP_AMDAPROVIDER_H
2 #define SCIQLOP_AMDAPROVIDER_H
3
3
4 #include "AmdaGlobal.h"
4 #include "AmdaGlobal.h"
5
5
6 #include <Data/IDataProvider.h>
6 #include <Data/IDataProvider.h>
7
7
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9
9
10
10
11 Q_DECLARE_LOGGING_CATEGORY(LOG_AmdaProvider)
11 Q_DECLARE_LOGGING_CATEGORY(LOG_AmdaProvider)
12
12
13 class QNetworkReply;
13 class QNetworkReply;
14
14
15 /**
15 /**
16 * @brief The AmdaProvider class is an example of how a data provider can generate data
16 * @brief The AmdaProvider class is an example of how a data provider can generate data
17 */
17 */
18 class SCIQLOP_AMDA_EXPORT AmdaProvider : public IDataProvider {
18 class SCIQLOP_AMDA_EXPORT AmdaProvider : public IDataProvider {
19 public:
19 public:
20 explicit AmdaProvider();
20 explicit AmdaProvider();
21
21
22 void requestDataLoading(QUuid token, const DataProviderParameters &parameters) override;
22 void requestDataLoading(QUuid token, const DataProviderParameters &parameters) override;
23
23
24 void requestDataAborting(QUuid identifier) override;
24 void requestDataAborting(QUuid identifier) override;
25
25
26 private:
26 private:
27 void retrieveData(QUuid token, const SqpDateTime &dateTime, const QVariantHash &data);
27 void retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data);
28 };
28 };
29
29
30 #endif // SCIQLOP_AMDAPROVIDER_H
30 #endif // SCIQLOP_AMDAPROVIDER_H
@@ -1,148 +1,148
1 #include "AmdaProvider.h"
1 #include "AmdaProvider.h"
2 #include "AmdaDefs.h"
2 #include "AmdaDefs.h"
3 #include "AmdaResultParser.h"
3 #include "AmdaResultParser.h"
4
4
5 #include <Common/DateUtils.h>
5 #include <Common/DateUtils.h>
6 #include <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
7 #include <Network/NetworkController.h>
7 #include <Network/NetworkController.h>
8 #include <SqpApplication.h>
8 #include <SqpApplication.h>
9 #include <Variable/Variable.h>
9 #include <Variable/Variable.h>
10
10
11 #include <QNetworkAccessManager>
11 #include <QNetworkAccessManager>
12 #include <QNetworkReply>
12 #include <QNetworkReply>
13 #include <QTemporaryFile>
13 #include <QTemporaryFile>
14 #include <QThread>
14 #include <QThread>
15
15
16 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
16 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
17
17
18 namespace {
18 namespace {
19
19
20 /// URL format for a request on AMDA server. The parameters are as follows:
20 /// URL format for a request on AMDA server. The parameters are as follows:
21 /// - %1: start date
21 /// - %1: start date
22 /// - %2: end date
22 /// - %2: end date
23 /// - %3: parameter id
23 /// - %3: parameter id
24 const auto AMDA_URL_FORMAT = QStringLiteral(
24 const auto AMDA_URL_FORMAT = QStringLiteral(
25 "http://amda.irap.omp.eu/php/rest/"
25 "http://amda.irap.omp.eu/php/rest/"
26 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&outputFormat=ASCII&"
26 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&outputFormat=ASCII&"
27 "timeFormat=ISO8601&gzip=0");
27 "timeFormat=ISO8601&gzip=0");
28
28
29 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
29 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
30 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
30 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
31
31
32 /// Formats a time to a date that can be passed in URL
32 /// Formats a time to a date that can be passed in URL
33 QString dateFormat(double sqpDateTime) noexcept
33 QString dateFormat(double sqpRange) noexcept
34 {
34 {
35 auto dateTime = DateUtils::dateTime(sqpDateTime);
35 auto dateTime = DateUtils::dateTime(sqpRange);
36 return dateTime.toString(AMDA_TIME_FORMAT);
36 return dateTime.toString(AMDA_TIME_FORMAT);
37 }
37 }
38
38
39 } // namespace
39 } // namespace
40
40
41 AmdaProvider::AmdaProvider()
41 AmdaProvider::AmdaProvider()
42 {
42 {
43 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
43 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
44 if (auto app = sqpApp) {
44 if (auto app = sqpApp) {
45 auto &networkController = app->networkController();
45 auto &networkController = app->networkController();
46 connect(this, SIGNAL(requestConstructed(QNetworkRequest, QUuid,
46 connect(this, SIGNAL(requestConstructed(QNetworkRequest, QUuid,
47 std::function<void(QNetworkReply *, QUuid)>)),
47 std::function<void(QNetworkReply *, QUuid)>)),
48 &networkController,
48 &networkController,
49 SLOT(onProcessRequested(QNetworkRequest, QUuid,
49 SLOT(onProcessRequested(QNetworkRequest, QUuid,
50 std::function<void(QNetworkReply *, QUuid)>)));
50 std::function<void(QNetworkReply *, QUuid)>)));
51
51
52
52
53 connect(&sqpApp->networkController(), SIGNAL(replyDownloadProgress(QUuid, double)), this,
53 connect(&sqpApp->networkController(), SIGNAL(replyDownloadProgress(QUuid, double)), this,
54 SIGNAL(dataProvidedProgress(QUuid, double)));
54 SIGNAL(dataProvidedProgress(QUuid, double)));
55 }
55 }
56 }
56 }
57
57
58 void AmdaProvider::requestDataLoading(QUuid token, const DataProviderParameters &parameters)
58 void AmdaProvider::requestDataLoading(QUuid token, const DataProviderParameters &parameters)
59 {
59 {
60 // NOTE: Try to use multithread if possible
60 // NOTE: Try to use multithread if possible
61 const auto times = parameters.m_Times;
61 const auto times = parameters.m_Times;
62 const auto data = parameters.m_Data;
62 const auto data = parameters.m_Data;
63 for (const auto &dateTime : qAsConst(times)) {
63 for (const auto &dateTime : qAsConst(times)) {
64 retrieveData(token, dateTime, data);
64 retrieveData(token, dateTime, data);
65 }
65 }
66 }
66 }
67
67
68 void AmdaProvider::requestDataAborting(QUuid identifier)
68 void AmdaProvider::requestDataAborting(QUuid identifier)
69 {
69 {
70 if (auto app = sqpApp) {
70 if (auto app = sqpApp) {
71 auto &networkController = app->networkController();
71 auto &networkController = app->networkController();
72 networkController.onReplyCanceled(identifier);
72 networkController.onReplyCanceled(identifier);
73 }
73 }
74 }
74 }
75
75
76 void AmdaProvider::retrieveData(QUuid token, const SqpDateTime &dateTime, const QVariantHash &data)
76 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
77 {
77 {
78 // Retrieves product ID from data: if the value is invalid, no request is made
78 // Retrieves product ID from data: if the value is invalid, no request is made
79 auto productId = data.value(AMDA_XML_ID_KEY).toString();
79 auto productId = data.value(AMDA_XML_ID_KEY).toString();
80 if (productId.isNull()) {
80 if (productId.isNull()) {
81 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
81 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
82 return;
82 return;
83 }
83 }
84 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData") << dateTime;
84 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData") << dateTime;
85
85
86 // /////////// //
86 // /////////// //
87 // Creates URL //
87 // Creates URL //
88 // /////////// //
88 // /////////// //
89
89
90 auto startDate = dateFormat(dateTime.m_TStart);
90 auto startDate = dateFormat(dateTime.m_TStart);
91 auto endDate = dateFormat(dateTime.m_TEnd);
91 auto endDate = dateFormat(dateTime.m_TEnd);
92
92
93 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
93 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
94 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData url:") << url;
94 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData url:") << url;
95 auto tempFile = std::make_shared<QTemporaryFile>();
95 auto tempFile = std::make_shared<QTemporaryFile>();
96
96
97 // LAMBDA
97 // LAMBDA
98 auto httpDownloadFinished
98 auto httpDownloadFinished
99 = [this, dateTime, tempFile, token](QNetworkReply *reply, QUuid dataId) noexcept {
99 = [this, dateTime, tempFile, token](QNetworkReply *reply, QUuid dataId) noexcept {
100 Q_UNUSED(dataId);
100 Q_UNUSED(dataId);
101
101
102 // Don't do anything if the reply was abort
102 // Don't do anything if the reply was abort
103 if (reply->error() != QNetworkReply::OperationCanceledError) {
103 if (reply->error() != QNetworkReply::OperationCanceledError) {
104
104
105 if (tempFile) {
105 if (tempFile) {
106 auto replyReadAll = reply->readAll();
106 auto replyReadAll = reply->readAll();
107 if (!replyReadAll.isEmpty()) {
107 if (!replyReadAll.isEmpty()) {
108 tempFile->write(replyReadAll);
108 tempFile->write(replyReadAll);
109 }
109 }
110 tempFile->close();
110 tempFile->close();
111
111
112 // Parse results file
112 // Parse results file
113 if (auto dataSeries = AmdaResultParser::readTxt(tempFile->fileName())) {
113 if (auto dataSeries = AmdaResultParser::readTxt(tempFile->fileName())) {
114 emit dataProvided(token, dataSeries, dateTime);
114 emit dataProvided(token, dataSeries, dateTime);
115 }
115 }
116 else {
116 else {
117 /// @todo ALX : debug
117 /// @todo ALX : debug
118 }
118 }
119 }
119 }
120 }
120 }
121
121
122 };
122 };
123 auto httpFinishedLambda
123 auto httpFinishedLambda
124 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
124 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
125
125
126 // Don't do anything if the reply was abort
126 // Don't do anything if the reply was abort
127 if (reply->error() != QNetworkReply::OperationCanceledError) {
127 if (reply->error() != QNetworkReply::OperationCanceledError) {
128 auto downloadFileUrl = QUrl{QString{reply->readAll()}};
128 auto downloadFileUrl = QUrl{QString{reply->readAll()}};
129
129
130
130
131 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData downloadFileUrl:")
131 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData downloadFileUrl:")
132 << downloadFileUrl;
132 << downloadFileUrl;
133 // Executes request for downloading file //
133 // Executes request for downloading file //
134
134
135 // Creates destination file
135 // Creates destination file
136 if (tempFile->open()) {
136 if (tempFile->open()) {
137 // Executes request
137 // Executes request
138 emit requestConstructed(QNetworkRequest{downloadFileUrl}, dataId,
138 emit requestConstructed(QNetworkRequest{downloadFileUrl}, dataId,
139 httpDownloadFinished);
139 httpDownloadFinished);
140 }
140 }
141 }
141 }
142 };
142 };
143
143
144 // //////////////// //
144 // //////////////// //
145 // Executes request //
145 // Executes request //
146 // //////////////// //
146 // //////////////// //
147 emit requestConstructed(QNetworkRequest{url}, token, httpFinishedLambda);
147 emit requestConstructed(QNetworkRequest{url}, token, httpFinishedLambda);
148 }
148 }
@@ -1,33 +1,33
1 #ifndef SCIQLOP_COSINUSPROVIDER_H
1 #ifndef SCIQLOP_COSINUSPROVIDER_H
2 #define SCIQLOP_COSINUSPROVIDER_H
2 #define SCIQLOP_COSINUSPROVIDER_H
3
3
4 #include "MockPluginGlobal.h"
4 #include "MockPluginGlobal.h"
5
5
6 #include <Data/IDataProvider.h>
6 #include <Data/IDataProvider.h>
7
7
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9 #include <QUuid>
9 #include <QUuid>
10
10
11 #include <QHash>
11 #include <QHash>
12 Q_DECLARE_LOGGING_CATEGORY(LOG_CosinusProvider)
12 Q_DECLARE_LOGGING_CATEGORY(LOG_CosinusProvider)
13
13
14 /**
14 /**
15 * @brief The CosinusProvider class is an example of how a data provider can generate data
15 * @brief The CosinusProvider class is an example of how a data provider can generate data
16 */
16 */
17 class SCIQLOP_MOCKPLUGIN_EXPORT CosinusProvider : public IDataProvider {
17 class SCIQLOP_MOCKPLUGIN_EXPORT CosinusProvider : public IDataProvider {
18 public:
18 public:
19 /// @sa IDataProvider::requestDataLoading(). The current impl isn't thread safe.
19 /// @sa IDataProvider::requestDataLoading(). The current impl isn't thread safe.
20 void requestDataLoading(QUuid token, const DataProviderParameters &parameters) override;
20 void requestDataLoading(QUuid token, const DataProviderParameters &parameters) override;
21
21
22
22
23 /// @sa IDataProvider::requestDataAborting(). The current impl isn't thread safe.
23 /// @sa IDataProvider::requestDataAborting(). The current impl isn't thread safe.
24 void requestDataAborting(QUuid identifier) override;
24 void requestDataAborting(QUuid identifier) override;
25
25
26
26
27 private:
27 private:
28 std::shared_ptr<IDataSeries> retrieveData(QUuid token, const SqpDateTime &dateTime);
28 std::shared_ptr<IDataSeries> retrieveData(QUuid token, const SqpRange &dateTime);
29
29
30 QHash<QUuid, bool> m_VariableToEnableProvider;
30 QHash<QUuid, bool> m_VariableToEnableProvider;
31 };
31 };
32
32
33 #endif // SCIQLOP_COSINUSPROVIDER_H
33 #endif // SCIQLOP_COSINUSPROVIDER_H
@@ -1,100 +1,100
1 #include "CosinusProvider.h"
1 #include "CosinusProvider.h"
2
2
3 #include <Data/DataProviderParameters.h>
3 #include <Data/DataProviderParameters.h>
4 #include <Data/ScalarSeries.h>
4 #include <Data/ScalarSeries.h>
5
5
6 #include <cmath>
6 #include <cmath>
7
7
8 #include <QFuture>
8 #include <QFuture>
9 #include <QThread>
9 #include <QThread>
10 #include <QtConcurrent/QtConcurrent>
10 #include <QtConcurrent/QtConcurrent>
11
11
12 Q_LOGGING_CATEGORY(LOG_CosinusProvider, "CosinusProvider")
12 Q_LOGGING_CATEGORY(LOG_CosinusProvider, "CosinusProvider")
13
13
14 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid token, const SqpDateTime &dateTime)
14 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid token, const SqpRange &dateTime)
15 {
15 {
16 // TODO: Add Mutex
16 // TODO: Add Mutex
17 auto dataIndex = 0;
17 auto dataIndex = 0;
18
18
19 // Gets the timerange from the parameters
19 // Gets the timerange from the parameters
20 double freq = 100.0;
20 double freq = 100.0;
21 double start = std::ceil(dateTime.m_TStart * freq); // 100 htz
21 double start = std::ceil(dateTime.m_TStart * freq); // 100 htz
22 double end = std::floor(dateTime.m_TEnd * freq); // 100 htz
22 double end = std::floor(dateTime.m_TEnd * freq); // 100 htz
23
23
24 // We assure that timerange is valid
24 // We assure that timerange is valid
25 if (end < start) {
25 if (end < start) {
26 std::swap(start, end);
26 std::swap(start, end);
27 }
27 }
28
28
29 // Generates scalar series containing cosinus values (one value per second)
29 // Generates scalar series containing cosinus values (one value per second)
30 auto dataCount = end - start;
30 auto dataCount = end - start;
31
31
32 auto xAxisData = QVector<double>{};
32 auto xAxisData = QVector<double>{};
33 xAxisData.resize(dataCount);
33 xAxisData.resize(dataCount);
34
34
35 auto valuesData = QVector<double>{};
35 auto valuesData = QVector<double>{};
36 valuesData.resize(dataCount);
36 valuesData.resize(dataCount);
37
37
38 int progress = 0;
38 int progress = 0;
39 auto progressEnd = dataCount;
39 auto progressEnd = dataCount;
40 for (auto time = start; time < end; ++time, ++dataIndex) {
40 for (auto time = start; time < end; ++time, ++dataIndex) {
41 auto it = m_VariableToEnableProvider.find(token);
41 auto it = m_VariableToEnableProvider.find(token);
42 if (it != m_VariableToEnableProvider.end() && it.value()) {
42 if (it != m_VariableToEnableProvider.end() && it.value()) {
43 const auto timeOnFreq = time / freq;
43 const auto timeOnFreq = time / freq;
44
44
45 xAxisData.replace(dataIndex, timeOnFreq);
45 xAxisData.replace(dataIndex, timeOnFreq);
46 valuesData.replace(dataIndex, std::cos(timeOnFreq));
46 valuesData.replace(dataIndex, std::cos(timeOnFreq));
47
47
48 // progression
48 // progression
49 int currentProgress = (time - start) * 100.0 / progressEnd;
49 int currentProgress = (time - start) * 100.0 / progressEnd;
50 if (currentProgress != progress) {
50 if (currentProgress != progress) {
51 progress = currentProgress;
51 progress = currentProgress;
52
52
53 emit dataProvidedProgress(token, progress);
53 emit dataProvidedProgress(token, progress);
54 }
54 }
55 }
55 }
56 else {
56 else {
57 if (!it.value()) {
57 if (!it.value()) {
58 qCDebug(LOG_CosinusProvider())
58 qCDebug(LOG_CosinusProvider())
59 << "CosinusProvider::retrieveData: ARRET De l'acquisition detecté"
59 << "CosinusProvider::retrieveData: ARRET De l'acquisition detecté"
60 << end - time;
60 << end - time;
61 }
61 }
62 }
62 }
63 }
63 }
64 emit dataProvidedProgress(token, 0.0);
64 emit dataProvidedProgress(token, 0.0);
65
65
66 return std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData),
66 return std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData),
67 Unit{QStringLiteral("t"), true}, Unit{});
67 Unit{QStringLiteral("t"), true}, Unit{});
68 }
68 }
69
69
70 void CosinusProvider::requestDataLoading(QUuid token, const DataProviderParameters &parameters)
70 void CosinusProvider::requestDataLoading(QUuid token, const DataProviderParameters &parameters)
71 {
71 {
72 // TODO: Add Mutex
72 // TODO: Add Mutex
73 m_VariableToEnableProvider[token] = true;
73 m_VariableToEnableProvider[token] = true;
74 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataLoading"
74 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataLoading"
75 << QThread::currentThread()->objectName();
75 << QThread::currentThread()->objectName();
76 // NOTE: Try to use multithread if possible
76 // NOTE: Try to use multithread if possible
77 const auto times = parameters.m_Times;
77 const auto times = parameters.m_Times;
78
78
79 for (const auto &dateTime : qAsConst(times)) {
79 for (const auto &dateTime : qAsConst(times)) {
80 if (m_VariableToEnableProvider[token]) {
80 if (m_VariableToEnableProvider[token]) {
81 auto scalarSeries = this->retrieveData(token, dateTime);
81 auto scalarSeries = this->retrieveData(token, dateTime);
82 emit dataProvided(token, scalarSeries, dateTime);
82 emit dataProvided(token, scalarSeries, dateTime);
83 }
83 }
84 }
84 }
85 }
85 }
86
86
87 void CosinusProvider::requestDataAborting(QUuid identifier)
87 void CosinusProvider::requestDataAborting(QUuid identifier)
88 {
88 {
89 // TODO: Add Mutex
89 // TODO: Add Mutex
90 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataAborting" << identifier
90 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataAborting" << identifier
91 << QThread::currentThread()->objectName();
91 << QThread::currentThread()->objectName();
92 auto it = m_VariableToEnableProvider.find(identifier);
92 auto it = m_VariableToEnableProvider.find(identifier);
93 if (it != m_VariableToEnableProvider.end()) {
93 if (it != m_VariableToEnableProvider.end()) {
94 it.value() = false;
94 it.value() = false;
95 }
95 }
96 else {
96 else {
97 qCWarning(LOG_CosinusProvider())
97 qCWarning(LOG_CosinusProvider())
98 << tr("Aborting progression of inexistant identifier detected !!!");
98 << tr("Aborting progression of inexistant identifier detected !!!");
99 }
99 }
100 }
100 }
General Comments 0
You need to be logged in to leave comments. Login now