##// END OF EJS Templates
Some fixes...
Alexandre Leroux -
r491:0877c365bd5c
parent child
Show More
@@ -1,255 +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 <QDateTime>
40 #include <QDir>
39 #include <QDir>
41 #include <QFileDialog>
40 #include <QFileDialog>
42 #include <QToolBar>
41 #include <QToolBar>
43 #include <QToolButton>
42 #include <QToolButton>
44 #include <memory.h>
43 #include <memory.h>
45
44
46 #include "iostream"
45 #include "iostream"
47
46
48 Q_LOGGING_CATEGORY(LOG_MainWindow, "MainWindow")
47 Q_LOGGING_CATEGORY(LOG_MainWindow, "MainWindow")
49
48
50 namespace {
49 namespace {
51 const auto LEFTMAININSPECTORWIDGETSPLITTERINDEX = 0;
50 const auto LEFTMAININSPECTORWIDGETSPLITTERINDEX = 0;
52 const auto LEFTINSPECTORSIDEPANESPLITTERINDEX = 1;
51 const auto LEFTINSPECTORSIDEPANESPLITTERINDEX = 1;
53 const auto VIEWPLITTERINDEX = 2;
52 const auto VIEWPLITTERINDEX = 2;
54 const auto RIGHTINSPECTORSIDEPANESPLITTERINDEX = 3;
53 const auto RIGHTINSPECTORSIDEPANESPLITTERINDEX = 3;
55 const auto RIGHTMAININSPECTORWIDGETSPLITTERINDEX = 4;
54 const auto RIGHTMAININSPECTORWIDGETSPLITTERINDEX = 4;
56 }
55 }
57
56
58 class MainWindow::MainWindowPrivate {
57 class MainWindow::MainWindowPrivate {
59 public:
58 public:
60 explicit MainWindowPrivate(MainWindow *mainWindow)
59 explicit MainWindowPrivate(MainWindow *mainWindow)
61 : m_LastOpenLeftInspectorSize{},
60 : m_LastOpenLeftInspectorSize{},
62 m_LastOpenRightInspectorSize{},
61 m_LastOpenRightInspectorSize{},
63 m_GeneralSettingsWidget{new SqpSettingsGeneralWidget{mainWindow}},
62 m_GeneralSettingsWidget{new SqpSettingsGeneralWidget{mainWindow}},
64 m_SettingsDialog{new SqpSettingsDialog{mainWindow}}
63 m_SettingsDialog{new SqpSettingsDialog{mainWindow}}
65 {
64 {
66 }
65 }
67
66
68 QSize m_LastOpenLeftInspectorSize;
67 QSize m_LastOpenLeftInspectorSize;
69 QSize m_LastOpenRightInspectorSize;
68 QSize m_LastOpenRightInspectorSize;
70 /// General settings widget. MainWindow has the ownership
69 /// General settings widget. MainWindow has the ownership
71 SqpSettingsGeneralWidget *m_GeneralSettingsWidget;
70 SqpSettingsGeneralWidget *m_GeneralSettingsWidget;
72 /// Settings dialog. MainWindow has the ownership
71 /// Settings dialog. MainWindow has the ownership
73 SqpSettingsDialog *m_SettingsDialog;
72 SqpSettingsDialog *m_SettingsDialog;
74 };
73 };
75
74
76 MainWindow::MainWindow(QWidget *parent)
75 MainWindow::MainWindow(QWidget *parent)
77 : QMainWindow{parent},
76 : QMainWindow{parent},
78 m_Ui{new Ui::MainWindow},
77 m_Ui{new Ui::MainWindow},
79 impl{spimpl::make_unique_impl<MainWindowPrivate>(this)}
78 impl{spimpl::make_unique_impl<MainWindowPrivate>(this)}
80 {
79 {
81 m_Ui->setupUi(this);
80 m_Ui->setupUi(this);
82
81
83 m_Ui->splitter->setCollapsible(LEFTINSPECTORSIDEPANESPLITTERINDEX, false);
82 m_Ui->splitter->setCollapsible(LEFTINSPECTORSIDEPANESPLITTERINDEX, false);
84 m_Ui->splitter->setCollapsible(RIGHTINSPECTORSIDEPANESPLITTERINDEX, false);
83 m_Ui->splitter->setCollapsible(RIGHTINSPECTORSIDEPANESPLITTERINDEX, false);
85
84
86
85
87 auto leftSidePane = m_Ui->leftInspectorSidePane->sidePane();
86 auto leftSidePane = m_Ui->leftInspectorSidePane->sidePane();
88 auto openLeftInspectorAction = new QAction{QIcon{
87 auto openLeftInspectorAction = new QAction{QIcon{
89 ":/icones/previous.png",
88 ":/icones/previous.png",
90 },
89 },
91 tr("Show/hide the left inspector"), this};
90 tr("Show/hide the left inspector"), this};
92
91
93
92
94 auto spacerLeftTop = new QWidget{};
93 auto spacerLeftTop = new QWidget{};
95 spacerLeftTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
94 spacerLeftTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
96
95
97 auto spacerLeftBottom = new QWidget{};
96 auto spacerLeftBottom = new QWidget{};
98 spacerLeftBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
97 spacerLeftBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
99
98
100 leftSidePane->addWidget(spacerLeftTop);
99 leftSidePane->addWidget(spacerLeftTop);
101 leftSidePane->addAction(openLeftInspectorAction);
100 leftSidePane->addAction(openLeftInspectorAction);
102 leftSidePane->addWidget(spacerLeftBottom);
101 leftSidePane->addWidget(spacerLeftBottom);
103
102
104
103
105 auto rightSidePane = m_Ui->rightInspectorSidePane->sidePane();
104 auto rightSidePane = m_Ui->rightInspectorSidePane->sidePane();
106 auto openRightInspectorAction = new QAction{QIcon{
105 auto openRightInspectorAction = new QAction{QIcon{
107 ":/icones/next.png",
106 ":/icones/next.png",
108 },
107 },
109 tr("Show/hide the right inspector"), this};
108 tr("Show/hide the right inspector"), this};
110
109
111 auto spacerRightTop = new QWidget{};
110 auto spacerRightTop = new QWidget{};
112 spacerRightTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
111 spacerRightTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
113
112
114 auto spacerRightBottom = new QWidget{};
113 auto spacerRightBottom = new QWidget{};
115 spacerRightBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
114 spacerRightBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
116
115
117 rightSidePane->addWidget(spacerRightTop);
116 rightSidePane->addWidget(spacerRightTop);
118 rightSidePane->addAction(openRightInspectorAction);
117 rightSidePane->addAction(openRightInspectorAction);
119 rightSidePane->addWidget(spacerRightBottom);
118 rightSidePane->addWidget(spacerRightBottom);
120
119
121 openLeftInspectorAction->setCheckable(true);
120 openLeftInspectorAction->setCheckable(true);
122 openRightInspectorAction->setCheckable(true);
121 openRightInspectorAction->setCheckable(true);
123
122
124 auto openInspector = [this](bool checked, bool right, auto action) {
123 auto openInspector = [this](bool checked, bool right, auto action) {
125
124
126 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"});
127
126
128 auto &lastInspectorSize
127 auto &lastInspectorSize
129 = right ? impl->m_LastOpenRightInspectorSize : impl->m_LastOpenLeftInspectorSize;
128 = right ? impl->m_LastOpenRightInspectorSize : impl->m_LastOpenLeftInspectorSize;
130
129
131 auto nextInspectorSize = right ? m_Ui->rightMainInspectorWidget->size()
130 auto nextInspectorSize = right ? m_Ui->rightMainInspectorWidget->size()
132 : m_Ui->leftMainInspectorWidget->size();
131 : m_Ui->leftMainInspectorWidget->size();
133
132
134 // Update of the last opened geometry
133 // Update of the last opened geometry
135 if (checked) {
134 if (checked) {
136 lastInspectorSize = nextInspectorSize;
135 lastInspectorSize = nextInspectorSize;
137 }
136 }
138
137
139 auto startSize = lastInspectorSize;
138 auto startSize = lastInspectorSize;
140 auto endSize = startSize;
139 auto endSize = startSize;
141 endSize.setWidth(0);
140 endSize.setWidth(0);
142
141
143 auto splitterInspectorIndex
142 auto splitterInspectorIndex
144 = right ? RIGHTMAININSPECTORWIDGETSPLITTERINDEX : LEFTMAININSPECTORWIDGETSPLITTERINDEX;
143 = right ? RIGHTMAININSPECTORWIDGETSPLITTERINDEX : LEFTMAININSPECTORWIDGETSPLITTERINDEX;
145
144
146 auto currentSizes = m_Ui->splitter->sizes();
145 auto currentSizes = m_Ui->splitter->sizes();
147 if (checked) {
146 if (checked) {
148 // adjust sizes individually here, e.g.
147 // adjust sizes individually here, e.g.
149 currentSizes[splitterInspectorIndex] -= lastInspectorSize.width();
148 currentSizes[splitterInspectorIndex] -= lastInspectorSize.width();
150 currentSizes[VIEWPLITTERINDEX] += lastInspectorSize.width();
149 currentSizes[VIEWPLITTERINDEX] += lastInspectorSize.width();
151 m_Ui->splitter->setSizes(currentSizes);
150 m_Ui->splitter->setSizes(currentSizes);
152 }
151 }
153 else {
152 else {
154 // adjust sizes individually here, e.g.
153 // adjust sizes individually here, e.g.
155 currentSizes[splitterInspectorIndex] += lastInspectorSize.width();
154 currentSizes[splitterInspectorIndex] += lastInspectorSize.width();
156 currentSizes[VIEWPLITTERINDEX] -= lastInspectorSize.width();
155 currentSizes[VIEWPLITTERINDEX] -= lastInspectorSize.width();
157 m_Ui->splitter->setSizes(currentSizes);
156 m_Ui->splitter->setSizes(currentSizes);
158 }
157 }
159
158
160 };
159 };
161
160
162
161
163 connect(openLeftInspectorAction, &QAction::triggered,
162 connect(openLeftInspectorAction, &QAction::triggered,
164 [openInspector, openLeftInspectorAction](bool checked) {
163 [openInspector, openLeftInspectorAction](bool checked) {
165 openInspector(checked, false, openLeftInspectorAction);
164 openInspector(checked, false, openLeftInspectorAction);
166 });
165 });
167 connect(openRightInspectorAction, &QAction::triggered,
166 connect(openRightInspectorAction, &QAction::triggered,
168 [openInspector, openRightInspectorAction](bool checked) {
167 [openInspector, openRightInspectorAction](bool checked) {
169 openInspector(checked, true, openRightInspectorAction);
168 openInspector(checked, true, openRightInspectorAction);
170 });
169 });
171
170
172 // //// //
171 // //// //
173 // Menu //
172 // Menu //
174 // //// //
173 // //// //
175 this->menuBar()->addAction(tr("File"));
174 this->menuBar()->addAction(tr("File"));
176 auto toolsMenu = this->menuBar()->addMenu(tr("Tools"));
175 auto toolsMenu = this->menuBar()->addMenu(tr("Tools"));
177 toolsMenu->addAction(tr("Settings..."), [this]() {
176 toolsMenu->addAction(tr("Settings..."), [this]() {
178 // Loads settings
177 // Loads settings
179 impl->m_SettingsDialog->loadSettings();
178 impl->m_SettingsDialog->loadSettings();
180
179
181 // Open settings dialog and save settings if the dialog is accepted
180 // Open settings dialog and save settings if the dialog is accepted
182 if (impl->m_SettingsDialog->exec() == QDialog::Accepted) {
181 if (impl->m_SettingsDialog->exec() == QDialog::Accepted) {
183 impl->m_SettingsDialog->saveSettings();
182 impl->m_SettingsDialog->saveSettings();
184 }
183 }
185
184
186 });
185 });
187
186
188 auto mainToolBar = this->addToolBar(QStringLiteral("MainToolBar"));
187 auto mainToolBar = this->addToolBar(QStringLiteral("MainToolBar"));
189
188
190 auto timeWidget = new TimeWidget{};
189 auto timeWidget = new TimeWidget{};
191 mainToolBar->addWidget(timeWidget);
190 mainToolBar->addWidget(timeWidget);
192
191
193 // //////// //
192 // //////// //
194 // Settings //
193 // Settings //
195 // //////// //
194 // //////// //
196
195
197 // Registers "general settings" widget to the settings dialog
196 // Registers "general settings" widget to the settings dialog
198 impl->m_SettingsDialog->registerWidget(QStringLiteral("General"),
197 impl->m_SettingsDialog->registerWidget(QStringLiteral("General"),
199 impl->m_GeneralSettingsWidget);
198 impl->m_GeneralSettingsWidget);
200
199
201 // /////////// //
200 // /////////// //
202 // Connections //
201 // Connections //
203 // /////////// //
202 // /////////// //
204
203
205 // Controllers / controllers connections
204 // Controllers / controllers connections
206 connect(&sqpApp->timeController(), SIGNAL(timeUpdated(SqpDateTime)),
205 connect(&sqpApp->timeController(), SIGNAL(timeUpdated(SqpDateTime)),
207 &sqpApp->variableController(), SLOT(onDateTimeOnSelection(SqpDateTime)));
206 &sqpApp->variableController(), SLOT(onDateTimeOnSelection(SqpDateTime)));
208
207
209 // Widgets / controllers connections
208 // Widgets / controllers connections
210
209
211 // DataSource
210 // DataSource
212 connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem *)),
211 connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem *)),
213 m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem *)));
212 m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem *)));
214
213
215 // Time
214 // Time
216 connect(timeWidget, SIGNAL(timeUpdated(SqpDateTime)), &sqpApp->timeController(),
215 connect(timeWidget, SIGNAL(timeUpdated(SqpDateTime)), &sqpApp->timeController(),
217 SLOT(onTimeToUpdate(SqpDateTime)));
216 SLOT(onTimeToUpdate(SqpDateTime)));
218
217
219 // Visualization
218 // Visualization
220 connect(&sqpApp->visualizationController(),
219 connect(&sqpApp->visualizationController(),
221 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), m_Ui->view,
220 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), m_Ui->view,
222 SLOT(onVariableAboutToBeDeleted(std::shared_ptr<Variable>)));
221 SLOT(onVariableAboutToBeDeleted(std::shared_ptr<Variable>)));
223
222
224 connect(&sqpApp->visualizationController(),
223 connect(&sqpApp->visualizationController(),
225 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpDateTime &)), m_Ui->view,
224 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpDateTime &)), m_Ui->view,
226 SLOT(onRangeChanged(std::shared_ptr<Variable>, const SqpDateTime &)));
225 SLOT(onRangeChanged(std::shared_ptr<Variable>, const SqpDateTime &)));
227
226
228 // Widgets / widgets connections
227 // Widgets / widgets connections
229
228
230 // 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
231 // 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.
232 // 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
233 // widget will attach its menu
232 // widget will attach its menu
234 connect(
233 connect(
235 m_Ui->variableInspectorWidget,
234 m_Ui->variableInspectorWidget,
236 SIGNAL(tableMenuAboutToBeDisplayed(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
235 SIGNAL(tableMenuAboutToBeDisplayed(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
237 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> > &)),
238 Qt::DirectConnection);
237 Qt::DirectConnection);
239 }
238 }
240
239
241 MainWindow::~MainWindow()
240 MainWindow::~MainWindow()
242 {
241 {
243 }
242 }
244
243
245 void MainWindow::changeEvent(QEvent *e)
244 void MainWindow::changeEvent(QEvent *e)
246 {
245 {
247 QMainWindow::changeEvent(e);
246 QMainWindow::changeEvent(e);
248 switch (e->type()) {
247 switch (e->type()) {
249 case QEvent::LanguageChange:
248 case QEvent::LanguageChange:
250 m_Ui->retranslateUi(this);
249 m_Ui->retranslateUi(this);
251 break;
250 break;
252 default:
251 default:
253 break;
252 break;
254 }
253 }
255 }
254 }
@@ -1,69 +1,69
1 #ifndef SCIQLOP_IDATASERIES_H
1 #ifndef SCIQLOP_IDATASERIES_H
2 #define SCIQLOP_IDATASERIES_H
2 #define SCIQLOP_IDATASERIES_H
3
3
4 #include <Common/MetaTypes.h>
4 #include <Common/MetaTypes.h>
5
5
6 #include <memory>
6 #include <memory>
7
7
8 #include <QString>
8 #include <QString>
9
9
10 template <int Dim>
10 template <int Dim>
11 class ArrayData;
11 class ArrayData;
12
12
13 struct Unit {
13 struct Unit {
14 explicit Unit(const QString &name = {}, bool timeUnit = false)
14 explicit Unit(const QString &name = {}, bool timeUnit = false)
15 : m_Name{name}, m_TimeUnit{timeUnit}
15 : m_Name{name}, m_TimeUnit{timeUnit}
16 {
16 {
17 }
17 }
18
18
19 inline bool operator==(const Unit &other) const
19 inline bool operator==(const Unit &other) const
20 {
20 {
21 return std::tie(m_Name, m_TimeUnit) == std::tie(other.m_Name, other.m_TimeUnit);
21 return std::tie(m_Name, m_TimeUnit) == std::tie(other.m_Name, other.m_TimeUnit);
22 }
22 }
23 inline bool operator!=(const Unit &other) const { return !(*this == other); }
23 inline bool operator!=(const Unit &other) const { return !(*this == other); }
24
24
25 QString m_Name; ///< Unit name
25 QString m_Name; ///< Unit name
26 bool m_TimeUnit; ///< The unit is a unit of time
26 bool m_TimeUnit; ///< The unit is a unit of time (UTC)
27 };
27 };
28
28
29 /**
29 /**
30 * @brief The IDataSeries aims to declare a data series.
30 * @brief The IDataSeries aims to declare a data series.
31 *
31 *
32 * A data series is an entity that contains at least :
32 * A data series is an entity that contains at least :
33 * - one dataset representing the x-axis
33 * - one dataset representing the x-axis
34 * - one dataset representing the values
34 * - one dataset representing the values
35 *
35 *
36 * Each dataset is represented by an ArrayData, and is associated with a unit.
36 * Each dataset is represented by an ArrayData, and is associated with a unit.
37 *
37 *
38 * An ArrayData can be unidimensional or two-dimensional, depending on the implementation of the
38 * An ArrayData can be unidimensional or two-dimensional, depending on the implementation of the
39 * IDataSeries. The x-axis dataset is always unidimensional.
39 * IDataSeries. The x-axis dataset is always unidimensional.
40 *
40 *
41 * @sa ArrayData
41 * @sa ArrayData
42 */
42 */
43 class IDataSeries {
43 class IDataSeries {
44 public:
44 public:
45 virtual ~IDataSeries() noexcept = default;
45 virtual ~IDataSeries() noexcept = default;
46
46
47 /// Returns the x-axis dataset
47 /// Returns the x-axis dataset
48 virtual std::shared_ptr<ArrayData<1> > xAxisData() = 0;
48 virtual std::shared_ptr<ArrayData<1> > xAxisData() = 0;
49
49
50 /// Returns the x-axis dataset (as const)
50 /// Returns the x-axis dataset (as const)
51 virtual const std::shared_ptr<ArrayData<1> > xAxisData() const = 0;
51 virtual const std::shared_ptr<ArrayData<1> > xAxisData() const = 0;
52
52
53 virtual Unit xAxisUnit() const = 0;
53 virtual Unit xAxisUnit() const = 0;
54
54
55 virtual Unit valuesUnit() const = 0;
55 virtual Unit valuesUnit() const = 0;
56
56
57 virtual void merge(IDataSeries *dataSeries) = 0;
57 virtual void merge(IDataSeries *dataSeries) = 0;
58
58
59 virtual std::unique_ptr<IDataSeries> clone() const = 0;
59 virtual std::unique_ptr<IDataSeries> clone() const = 0;
60
60
61 virtual void lockRead() = 0;
61 virtual void lockRead() = 0;
62 virtual void lockWrite() = 0;
62 virtual void lockWrite() = 0;
63 virtual void unlock() = 0;
63 virtual void unlock() = 0;
64 };
64 };
65
65
66 // Required for using shared_ptr in signals/slots
66 // Required for using shared_ptr in signals/slots
67 SCIQLOP_REGISTER_META_TYPE(IDATASERIES_PTR_REGISTRY, std::shared_ptr<IDataSeries>)
67 SCIQLOP_REGISTER_META_TYPE(IDATASERIES_PTR_REGISTRY, std::shared_ptr<IDataSeries>)
68
68
69 #endif // SCIQLOP_IDATASERIES_H
69 #endif // SCIQLOP_IDATASERIES_H
@@ -1,43 +1,43
1 #ifndef SCIQLOP_SQPDATETIME_H
1 #ifndef SCIQLOP_SQPDATETIME_H
2 #define SCIQLOP_SQPDATETIME_H
2 #define SCIQLOP_SQPDATETIME_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 SqpDateTime struct holds the information of time parameters
13 */
13 */
14 struct SqpDateTime {
14 struct SqpDateTime {
15 /// Start time
15 /// Start time (UTC)
16 double m_TStart;
16 double m_TStart;
17 /// End time
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 SqpDateTime &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 SqpDateTime &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, SqpDateTime 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(SQPDATETIME_REGISTRY, SqpDateTime)
42
42
43 #endif // SCIQLOP_SQPDATETIME_H
43 #endif // SCIQLOP_SQPDATETIME_H
@@ -1,244 +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 <QDateTime>
12 #include <QMutex>
11 #include <QMutex>
13 #include <QThread>
12 #include <QThread>
14 #include <QUuid>
13 #include <QUuid>
15 #include <QtCore/QItemSelectionModel>
14 #include <QtCore/QItemSelectionModel>
16
15
17 #include <unordered_map>
16 #include <unordered_map>
18
17
19 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
18 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
20
19
21 struct VariableController::VariableControllerPrivate {
20 struct VariableController::VariableControllerPrivate {
22 explicit VariableControllerPrivate(VariableController *parent)
21 explicit VariableControllerPrivate(VariableController *parent)
23 : m_WorkingMutex{},
22 : m_WorkingMutex{},
24 m_VariableModel{new VariableModel{parent}},
23 m_VariableModel{new VariableModel{parent}},
25 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
24 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
26 m_VariableCacheController{std::make_unique<VariableCacheController>()}
25 m_VariableCacheController{std::make_unique<VariableCacheController>()}
27 {
26 {
28 }
27 }
29
28
30 QMutex m_WorkingMutex;
29 QMutex m_WorkingMutex;
31 /// Variable model. The VariableController has the ownership
30 /// Variable model. The VariableController has the ownership
32 VariableModel *m_VariableModel;
31 VariableModel *m_VariableModel;
33 QItemSelectionModel *m_VariableSelectionModel;
32 QItemSelectionModel *m_VariableSelectionModel;
34
33
35
34
36 TimeController *m_TimeController{nullptr};
35 TimeController *m_TimeController{nullptr};
37 std::unique_ptr<VariableCacheController> m_VariableCacheController;
36 std::unique_ptr<VariableCacheController> m_VariableCacheController;
38
37
39 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
38 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
40 m_VariableToProviderMap;
39 m_VariableToProviderMap;
41 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
40 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
42 };
41 };
43
42
44 VariableController::VariableController(QObject *parent)
43 VariableController::VariableController(QObject *parent)
45 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
44 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
46 {
45 {
47 qCDebug(LOG_VariableController()) << tr("VariableController construction")
46 qCDebug(LOG_VariableController()) << tr("VariableController construction")
48 << QThread::currentThread();
47 << QThread::currentThread();
49
48
50 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
49 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
51 &VariableController::onAbortProgressRequested);
50 &VariableController::onAbortProgressRequested);
52 }
51 }
53
52
54 VariableController::~VariableController()
53 VariableController::~VariableController()
55 {
54 {
56 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
55 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
57 << QThread::currentThread();
56 << QThread::currentThread();
58 this->waitForFinish();
57 this->waitForFinish();
59 }
58 }
60
59
61 VariableModel *VariableController::variableModel() noexcept
60 VariableModel *VariableController::variableModel() noexcept
62 {
61 {
63 return impl->m_VariableModel;
62 return impl->m_VariableModel;
64 }
63 }
65
64
66 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
65 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
67 {
66 {
68 return impl->m_VariableSelectionModel;
67 return impl->m_VariableSelectionModel;
69 }
68 }
70
69
71 void VariableController::setTimeController(TimeController *timeController) noexcept
70 void VariableController::setTimeController(TimeController *timeController) noexcept
72 {
71 {
73 impl->m_TimeController = timeController;
72 impl->m_TimeController = timeController;
74 }
73 }
75
74
76 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
75 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
77 {
76 {
78 if (!variable) {
77 if (!variable) {
79 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
78 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
80 return;
79 return;
81 }
80 }
82
81
83 // 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
84 // make some treatments before the deletion
83 // make some treatments before the deletion
85 emit variableAboutToBeDeleted(variable);
84 emit variableAboutToBeDeleted(variable);
86
85
87 // Deletes identifier
86 // Deletes identifier
88 impl->m_VariableToIdentifierMap.erase(variable);
87 impl->m_VariableToIdentifierMap.erase(variable);
89
88
90 // Deletes provider
89 // Deletes provider
91 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
90 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
92 qCDebug(LOG_VariableController())
91 qCDebug(LOG_VariableController())
93 << tr("Number of providers deleted for variable %1: %2")
92 << tr("Number of providers deleted for variable %1: %2")
94 .arg(variable->name(), QString::number(nbProvidersDeleted));
93 .arg(variable->name(), QString::number(nbProvidersDeleted));
95
94
96 // Clears cache
95 // Clears cache
97 impl->m_VariableCacheController->clear(variable);
96 impl->m_VariableCacheController->clear(variable);
98
97
99 // Deletes from model
98 // Deletes from model
100 impl->m_VariableModel->deleteVariable(variable);
99 impl->m_VariableModel->deleteVariable(variable);
101 }
100 }
102
101
103 void VariableController::deleteVariables(
102 void VariableController::deleteVariables(
104 const QVector<std::shared_ptr<Variable> > &variables) noexcept
103 const QVector<std::shared_ptr<Variable> > &variables) noexcept
105 {
104 {
106 for (auto variable : qAsConst(variables)) {
105 for (auto variable : qAsConst(variables)) {
107 deleteVariable(variable);
106 deleteVariable(variable);
108 }
107 }
109 }
108 }
110
109
111 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
110 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
112 {
111 {
113 }
112 }
114
113
115 void VariableController::createVariable(const QString &name, const QVariantHash &metadata,
114 void VariableController::createVariable(const QString &name, const QVariantHash &metadata,
116 std::shared_ptr<IDataProvider> provider) noexcept
115 std::shared_ptr<IDataProvider> provider) noexcept
117 {
116 {
118
117
119 if (!impl->m_TimeController) {
118 if (!impl->m_TimeController) {
120 qCCritical(LOG_VariableController())
119 qCCritical(LOG_VariableController())
121 << tr("Impossible to create variable: The time controller is null");
120 << tr("Impossible to create variable: The time controller is null");
122 return;
121 return;
123 }
122 }
124
123
125 auto dateTime = impl->m_TimeController->dateTime();
124 auto dateTime = impl->m_TimeController->dateTime();
126
125
127 if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime, metadata)) {
126 if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime, metadata)) {
128 auto identifier = QUuid::createUuid();
127 auto identifier = QUuid::createUuid();
129
128
130 // store the provider
129 // store the provider
131 impl->m_VariableToProviderMap[newVariable] = provider;
130 impl->m_VariableToProviderMap[newVariable] = provider;
132 impl->m_VariableToIdentifierMap[newVariable] = identifier;
131 impl->m_VariableToIdentifierMap[newVariable] = identifier;
133
132
134 auto addDateTimeAcquired = [ this, varW = std::weak_ptr<Variable>{newVariable} ](
133 auto addDateTimeAcquired = [ this, varW = std::weak_ptr<Variable>{newVariable} ](
135 QUuid identifier, auto dataSeriesAcquired, auto dateTimeToPutInCache)
134 QUuid identifier, auto dataSeriesAcquired, auto dateTimeToPutInCache)
136 {
135 {
137 if (auto variable = varW.lock()) {
136 if (auto variable = varW.lock()) {
138 auto varIdentifier = impl->m_VariableToIdentifierMap.at(variable);
137 auto varIdentifier = impl->m_VariableToIdentifierMap.at(variable);
139 if (varIdentifier == identifier) {
138 if (varIdentifier == identifier) {
140 impl->m_VariableCacheController->addDateTime(variable, dateTimeToPutInCache);
139 impl->m_VariableCacheController->addDateTime(variable, dateTimeToPutInCache);
141 variable->setDataSeries(dataSeriesAcquired);
140 variable->setDataSeries(dataSeriesAcquired);
142 emit variable->updated();
141 emit variable->updated();
143 }
142 }
144 }
143 }
145 };
144 };
146
145
147 connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
146 connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
148 connect(provider.get(), &IDataProvider::dataProvidedProgress, this,
147 connect(provider.get(), &IDataProvider::dataProvidedProgress, this,
149 &VariableController::onVariableRetrieveDataInProgress);
148 &VariableController::onVariableRetrieveDataInProgress);
150 this->onRequestDataLoading(newVariable, dateTime);
149 this->onRequestDataLoading(newVariable, dateTime);
151 }
150 }
152 }
151 }
153
152
154 void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
153 void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
155 {
154 {
156 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
155 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
157 << QThread::currentThread()->objectName();
156 << QThread::currentThread()->objectName();
158 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
157 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
159
158
160 for (const auto &selectedRow : qAsConst(selectedRows)) {
159 for (const auto &selectedRow : qAsConst(selectedRows)) {
161 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
160 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
162 selectedVariable->setDateTime(dateTime);
161 selectedVariable->setDateTime(dateTime);
163 this->onRequestDataLoading(selectedVariable, dateTime);
162 this->onRequestDataLoading(selectedVariable, dateTime);
164
163
165 // notify that rescale operation has to be done
164 // notify that rescale operation has to be done
166 emit rangeChanged(selectedVariable, dateTime);
165 emit rangeChanged(selectedVariable, dateTime);
167 }
166 }
168 }
167 }
169 }
168 }
170
169
171 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
170 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
172 {
171 {
173 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
172 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
174
173
175 auto end = impl->m_VariableToIdentifierMap.cend();
174 auto end = impl->m_VariableToIdentifierMap.cend();
176 auto it = std::find_if(impl->m_VariableToIdentifierMap.cbegin(), end, findReply);
175 auto it = std::find_if(impl->m_VariableToIdentifierMap.cbegin(), end, findReply);
177 if (it != end) {
176 if (it != end) {
178 impl->m_VariableModel->setDataProgress(it->first, progress);
177 impl->m_VariableModel->setDataProgress(it->first, progress);
179 }
178 }
180 }
179 }
181
180
182 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
181 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
183 {
182 {
184 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
183 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
185 << QThread::currentThread()->objectName();
184 << QThread::currentThread()->objectName();
186
185
187 auto it = impl->m_VariableToIdentifierMap.find(variable);
186 auto it = impl->m_VariableToIdentifierMap.find(variable);
188 if (it != impl->m_VariableToIdentifierMap.cend()) {
187 if (it != impl->m_VariableToIdentifierMap.cend()) {
189 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
188 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
190 }
189 }
191 else {
190 else {
192 qCWarning(LOG_VariableController())
191 qCWarning(LOG_VariableController())
193 << tr("Aborting progression of inexistant variable detected !!!")
192 << tr("Aborting progression of inexistant variable detected !!!")
194 << QThread::currentThread()->objectName();
193 << QThread::currentThread()->objectName();
195 }
194 }
196 }
195 }
197
196
198
197
199 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
198 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
200 const SqpDateTime &dateTime)
199 const SqpDateTime &dateTime)
201 {
200 {
202 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
201 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
203 << QThread::currentThread()->objectName();
202 << QThread::currentThread()->objectName();
204 // we want to load data of the variable for the dateTime.
203 // we want to load data of the variable for the dateTime.
205 // First we check if the cache contains some of them.
204 // First we check if the cache contains some of them.
206 // For the other, we ask the provider to give them.
205 // For the other, we ask the provider to give them.
207 if (variable) {
206 if (variable) {
208
207
209 auto dateTimeListNotInCache
208 auto dateTimeListNotInCache
210 = impl->m_VariableCacheController->provideNotInCacheDateTimeList(variable, dateTime);
209 = impl->m_VariableCacheController->provideNotInCacheDateTimeList(variable, dateTime);
211
210
212 if (!dateTimeListNotInCache.empty()) {
211 if (!dateTimeListNotInCache.empty()) {
213 // Ask the provider for each data on the dateTimeListNotInCache
212 // Ask the provider for each data on the dateTimeListNotInCache
214 auto identifier = impl->m_VariableToIdentifierMap.at(variable);
213 auto identifier = impl->m_VariableToIdentifierMap.at(variable);
215 impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
214 impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
216 identifier,
215 identifier,
217 DataProviderParameters{std::move(dateTimeListNotInCache), variable->metadata()});
216 DataProviderParameters{std::move(dateTimeListNotInCache), variable->metadata()});
218 }
217 }
219 else {
218 else {
220 emit variable->updated();
219 emit variable->updated();
221 }
220 }
222 }
221 }
223 else {
222 else {
224 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");
225 }
224 }
226 }
225 }
227
226
228
227
229 void VariableController::initialize()
228 void VariableController::initialize()
230 {
229 {
231 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
230 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
232 impl->m_WorkingMutex.lock();
231 impl->m_WorkingMutex.lock();
233 qCDebug(LOG_VariableController()) << tr("VariableController init END");
232 qCDebug(LOG_VariableController()) << tr("VariableController init END");
234 }
233 }
235
234
236 void VariableController::finalize()
235 void VariableController::finalize()
237 {
236 {
238 impl->m_WorkingMutex.unlock();
237 impl->m_WorkingMutex.unlock();
239 }
238 }
240
239
241 void VariableController::waitForFinish()
240 void VariableController::waitForFinish()
242 {
241 {
243 QMutexLocker locker{&impl->m_WorkingMutex};
242 QMutexLocker locker{&impl->m_WorkingMutex};
244 }
243 }
@@ -1,182 +1,182
1 #include "AmdaResultParser.h"
1 #include "AmdaResultParser.h"
2
2
3 #include <Data/ScalarSeries.h>
3 #include <Data/ScalarSeries.h>
4
4
5 #include <QObject>
5 #include <QObject>
6 #include <QtTest>
6 #include <QtTest>
7
7
8 namespace {
8 namespace {
9
9
10 /// Path for the tests
10 /// Path for the tests
11 const auto TESTS_RESOURCES_PATH
11 const auto TESTS_RESOURCES_PATH
12 = QFileInfo{QString{AMDA_TESTS_RESOURCES_DIR}, "TestAmdaResultParser"}.absoluteFilePath();
12 = QFileInfo{QString{AMDA_TESTS_RESOURCES_DIR}, "TestAmdaResultParser"}.absoluteFilePath();
13
13
14 QString inputFilePath(const QString &inputFileName)
14 QString inputFilePath(const QString &inputFileName)
15 {
15 {
16 return QFileInfo{TESTS_RESOURCES_PATH, inputFileName}.absoluteFilePath();
16 return QFileInfo{TESTS_RESOURCES_PATH, inputFileName}.absoluteFilePath();
17 }
17 }
18
18
19 struct ExpectedResults {
19 struct ExpectedResults {
20 explicit ExpectedResults() = default;
20 explicit ExpectedResults() = default;
21
21
22 /// Ctor with QVector<QDateTime> as x-axis data. Datetimes are converted to doubles
22 /// Ctor with QVector<QDateTime> as x-axis data. Datetimes are converted to doubles
23 explicit ExpectedResults(Unit xAxisUnit, Unit valuesUnit, const QVector<QDateTime> &xAxisData,
23 explicit ExpectedResults(Unit xAxisUnit, Unit valuesUnit, const QVector<QDateTime> &xAxisData,
24 QVector<double> valuesData)
24 QVector<double> valuesData)
25 : m_ParsingOK{true},
25 : m_ParsingOK{true},
26 m_XAxisUnit{xAxisUnit},
26 m_XAxisUnit{xAxisUnit},
27 m_ValuesUnit{valuesUnit},
27 m_ValuesUnit{valuesUnit},
28 m_XAxisData{},
28 m_XAxisData{},
29 m_ValuesData{std::move(valuesData)}
29 m_ValuesData{std::move(valuesData)}
30 {
30 {
31 // Converts QVector<QDateTime> to QVector<double>
31 // Converts QVector<QDateTime> to QVector<double>
32 std::transform(xAxisData.cbegin(), xAxisData.cend(), std::back_inserter(m_XAxisData),
32 std::transform(xAxisData.cbegin(), xAxisData.cend(), std::back_inserter(m_XAxisData),
33 [](const auto &dateTime) { return dateTime.toMSecsSinceEpoch() / 1000.; });
33 [](const auto &dateTime) { return dateTime.toMSecsSinceEpoch() / 1000.; });
34 }
34 }
35
35
36 /**
36 /**
37 * Validates a DataSeries compared to the expected results
37 * Validates a DataSeries compared to the expected results
38 * @param results the DataSeries to validate
38 * @param results the DataSeries to validate
39 */
39 */
40 void validate(std::shared_ptr<IDataSeries> results)
40 void validate(std::shared_ptr<IDataSeries> results)
41 {
41 {
42 if (m_ParsingOK) {
42 if (m_ParsingOK) {
43 auto scalarSeries = dynamic_cast<ScalarSeries *>(results.get());
43 auto scalarSeries = dynamic_cast<ScalarSeries *>(results.get());
44 QVERIFY(scalarSeries != nullptr);
44 QVERIFY(scalarSeries != nullptr);
45
45
46 // Checks units
46 // Checks units
47 QVERIFY(scalarSeries->xAxisUnit() == m_XAxisUnit);
47 QVERIFY(scalarSeries->xAxisUnit() == m_XAxisUnit);
48 QVERIFY(scalarSeries->valuesUnit() == m_ValuesUnit);
48 QVERIFY(scalarSeries->valuesUnit() == m_ValuesUnit);
49
49
50 // Checks values
50 // Checks values
51 QVERIFY(scalarSeries->xAxisData()->data() == m_XAxisData);
51 QVERIFY(scalarSeries->xAxisData()->data() == m_XAxisData);
52 QVERIFY(scalarSeries->valuesData()->data() == m_ValuesData);
52 QVERIFY(scalarSeries->valuesData()->data() == m_ValuesData);
53 }
53 }
54 else {
54 else {
55 QVERIFY(results == nullptr);
55 QVERIFY(results == nullptr);
56 }
56 }
57 }
57 }
58
58
59 // Parsing was successfully completed
59 // Parsing was successfully completed
60 bool m_ParsingOK{false};
60 bool m_ParsingOK{false};
61 // Expected x-axis unit
61 // Expected x-axis unit
62 Unit m_XAxisUnit{};
62 Unit m_XAxisUnit{};
63 // Expected values unit
63 // Expected values unit
64 Unit m_ValuesUnit{};
64 Unit m_ValuesUnit{};
65 // Expected x-axis data
65 // Expected x-axis data
66 QVector<double> m_XAxisData{};
66 QVector<double> m_XAxisData{};
67 // Expected values data
67 // Expected values data
68 QVector<double> m_ValuesData{};
68 QVector<double> m_ValuesData{};
69 };
69 };
70
70
71 } // namespace
71 } // namespace
72
72
73 Q_DECLARE_METATYPE(ExpectedResults)
73 Q_DECLARE_METATYPE(ExpectedResults)
74
74
75 class TestAmdaResultParser : public QObject {
75 class TestAmdaResultParser : public QObject {
76 Q_OBJECT
76 Q_OBJECT
77 private slots:
77 private slots:
78 /// Input test data
78 /// Input test data
79 /// @sa testTxtJson()
79 /// @sa testTxtJson()
80 void testReadTxt_data();
80 void testReadTxt_data();
81
81
82 /// Tests parsing of a TXT file
82 /// Tests parsing of a TXT file
83 void testReadTxt();
83 void testReadTxt();
84 };
84 };
85
85
86 void TestAmdaResultParser::testReadTxt_data()
86 void TestAmdaResultParser::testReadTxt_data()
87 {
87 {
88 // ////////////// //
88 // ////////////// //
89 // Test structure //
89 // Test structure //
90 // ////////////// //
90 // ////////////// //
91
91
92 // Name of TXT file to read
92 // Name of TXT file to read
93 QTest::addColumn<QString>("inputFileName");
93 QTest::addColumn<QString>("inputFileName");
94 // Expected results
94 // Expected results
95 QTest::addColumn<ExpectedResults>("expectedResults");
95 QTest::addColumn<ExpectedResults>("expectedResults");
96
96
97 // ////////// //
97 // ////////// //
98 // Test cases //
98 // Test cases //
99 // ////////// //
99 // ////////// //
100
100
101 auto dateTime = [](int year, int month, int day, int hours, int minutes, int seconds) {
101 auto dateTime = [](int year, int month, int day, int hours, int minutes, int seconds) {
102 return QDateTime{{year, month, day}, {hours, minutes, seconds}};
102 return QDateTime{{year, month, day}, {hours, minutes, seconds}, Qt::UTC};
103 };
103 };
104
104
105 // Valid file
105 // Valid file
106 QTest::newRow("Valid file")
106 QTest::newRow("Valid file")
107 << QStringLiteral("ValidScalar1.txt")
107 << QStringLiteral("ValidScalar1.txt")
108 << ExpectedResults{
108 << ExpectedResults{
109 Unit{QStringLiteral("nT"), true}, Unit{},
109 Unit{QStringLiteral("nT"), true}, Unit{},
110 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
110 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
111 dateTime(2013, 9, 23, 9, 2, 30), dateTime(2013, 9, 23, 9, 3, 30),
111 dateTime(2013, 9, 23, 9, 2, 30), dateTime(2013, 9, 23, 9, 3, 30),
112 dateTime(2013, 9, 23, 9, 4, 30), dateTime(2013, 9, 23, 9, 5, 30),
112 dateTime(2013, 9, 23, 9, 4, 30), dateTime(2013, 9, 23, 9, 5, 30),
113 dateTime(2013, 9, 23, 9, 6, 30), dateTime(2013, 9, 23, 9, 7, 30),
113 dateTime(2013, 9, 23, 9, 6, 30), dateTime(2013, 9, 23, 9, 7, 30),
114 dateTime(2013, 9, 23, 9, 8, 30), dateTime(2013, 9, 23, 9, 9, 30)},
114 dateTime(2013, 9, 23, 9, 8, 30), dateTime(2013, 9, 23, 9, 9, 30)},
115 QVector<double>{-2.83950, -2.71850, -2.52150, -2.57633, -2.58050, -2.48325, -2.63025,
115 QVector<double>{-2.83950, -2.71850, -2.52150, -2.57633, -2.58050, -2.48325, -2.63025,
116 -2.55800, -2.43250, -2.42200}};
116 -2.55800, -2.43250, -2.42200}};
117
117
118 // Valid files but with some invalid lines (wrong unit, wrong values, etc.)
118 // Valid files but with some invalid lines (wrong unit, wrong values, etc.)
119 QTest::newRow("No unit file") << QStringLiteral("NoUnit.txt")
119 QTest::newRow("No unit file") << QStringLiteral("NoUnit.txt")
120 << ExpectedResults{Unit{QStringLiteral(""), true}, Unit{},
120 << ExpectedResults{Unit{QStringLiteral(""), true}, Unit{},
121 QVector<QDateTime>{}, QVector<double>{}};
121 QVector<QDateTime>{}, QVector<double>{}};
122 QTest::newRow("Wrong unit file")
122 QTest::newRow("Wrong unit file")
123 << QStringLiteral("WrongUnit.txt")
123 << QStringLiteral("WrongUnit.txt")
124 << ExpectedResults{Unit{QStringLiteral(""), true}, Unit{},
124 << ExpectedResults{Unit{QStringLiteral(""), true}, Unit{},
125 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30),
125 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30),
126 dateTime(2013, 9, 23, 9, 1, 30),
126 dateTime(2013, 9, 23, 9, 1, 30),
127 dateTime(2013, 9, 23, 9, 2, 30)},
127 dateTime(2013, 9, 23, 9, 2, 30)},
128 QVector<double>{-2.83950, -2.71850, -2.52150}};
128 QVector<double>{-2.83950, -2.71850, -2.52150}};
129
129
130 QTest::newRow("Wrong results file (date of first line is invalid")
130 QTest::newRow("Wrong results file (date of first line is invalid")
131 << QStringLiteral("WrongDate.txt")
131 << QStringLiteral("WrongDate.txt")
132 << ExpectedResults{
132 << ExpectedResults{
133 Unit{QStringLiteral("nT"), true}, Unit{},
133 Unit{QStringLiteral("nT"), true}, Unit{},
134 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
134 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
135 QVector<double>{-2.71850, -2.52150}};
135 QVector<double>{-2.71850, -2.52150}};
136
136
137 QTest::newRow("Wrong results file (too many values for first line")
137 QTest::newRow("Wrong results file (too many values for first line")
138 << QStringLiteral("TooManyValues.txt")
138 << QStringLiteral("TooManyValues.txt")
139 << ExpectedResults{
139 << ExpectedResults{
140 Unit{QStringLiteral("nT"), true}, Unit{},
140 Unit{QStringLiteral("nT"), true}, Unit{},
141 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
141 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
142 QVector<double>{-2.71850, -2.52150}};
142 QVector<double>{-2.71850, -2.52150}};
143
143
144 QTest::newRow("Wrong results file (value of first line is invalid")
144 QTest::newRow("Wrong results file (value of first line is invalid")
145 << QStringLiteral("WrongValue.txt")
145 << QStringLiteral("WrongValue.txt")
146 << ExpectedResults{
146 << ExpectedResults{
147 Unit{QStringLiteral("nT"), true}, Unit{},
147 Unit{QStringLiteral("nT"), true}, Unit{},
148 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
148 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
149 QVector<double>{-2.71850, -2.52150}};
149 QVector<double>{-2.71850, -2.52150}};
150
150
151 QTest::newRow("Wrong results file (value of first line is NaN")
151 QTest::newRow("Wrong results file (value of first line is NaN")
152 << QStringLiteral("NaNValue.txt")
152 << QStringLiteral("NaNValue.txt")
153 << ExpectedResults{
153 << ExpectedResults{
154 Unit{QStringLiteral("nT"), true}, Unit{},
154 Unit{QStringLiteral("nT"), true}, Unit{},
155 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
155 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
156 QVector<double>{-2.71850, -2.52150}};
156 QVector<double>{-2.71850, -2.52150}};
157
157
158 // Invalid files
158 // Invalid files
159 QTest::newRow("Invalid file (unexisting file)") << QStringLiteral("UnexistingFile.txt")
159 QTest::newRow("Invalid file (unexisting file)") << QStringLiteral("UnexistingFile.txt")
160 << ExpectedResults{};
160 << ExpectedResults{};
161
161
162 QTest::newRow("Invalid file (file not found on server)") << QStringLiteral("FileNotFound.txt")
162 QTest::newRow("Invalid file (file not found on server)") << QStringLiteral("FileNotFound.txt")
163 << ExpectedResults{};
163 << ExpectedResults{};
164 }
164 }
165
165
166 void TestAmdaResultParser::testReadTxt()
166 void TestAmdaResultParser::testReadTxt()
167 {
167 {
168 QFETCH(QString, inputFileName);
168 QFETCH(QString, inputFileName);
169 QFETCH(ExpectedResults, expectedResults);
169 QFETCH(ExpectedResults, expectedResults);
170
170
171 // Parses file
171 // Parses file
172 auto filePath = inputFilePath(inputFileName);
172 auto filePath = inputFilePath(inputFileName);
173 auto results = AmdaResultParser::readTxt(filePath);
173 auto results = AmdaResultParser::readTxt(filePath);
174
174
175 // ///////////////// //
175 // ///////////////// //
176 // Validates results //
176 // Validates results //
177 // ///////////////// //
177 // ///////////////// //
178 expectedResults.validate(results);
178 expectedResults.validate(results);
179 }
179 }
180
180
181 QTEST_MAIN(TestAmdaResultParser)
181 QTEST_MAIN(TestAmdaResultParser)
182 #include "TestAmdaResultParser.moc"
182 #include "TestAmdaResultParser.moc"
@@ -1,101 +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 <QDateTime>
9 #include <QFuture>
8 #include <QFuture>
10 #include <QThread>
9 #include <QThread>
11 #include <QtConcurrent/QtConcurrent>
10 #include <QtConcurrent/QtConcurrent>
12
11
13 Q_LOGGING_CATEGORY(LOG_CosinusProvider, "CosinusProvider")
12 Q_LOGGING_CATEGORY(LOG_CosinusProvider, "CosinusProvider")
14
13
15 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid token, const SqpDateTime &dateTime)
14 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid token, const SqpDateTime &dateTime)
16 {
15 {
17 // TODO: Add Mutex
16 // TODO: Add Mutex
18 auto dataIndex = 0;
17 auto dataIndex = 0;
19
18
20 // Gets the timerange from the parameters
19 // Gets the timerange from the parameters
21 double freq = 100.0;
20 double freq = 100.0;
22 double start = std::ceil(dateTime.m_TStart * freq); // 100 htz
21 double start = std::ceil(dateTime.m_TStart * freq); // 100 htz
23 double end = std::floor(dateTime.m_TEnd * freq); // 100 htz
22 double end = std::floor(dateTime.m_TEnd * freq); // 100 htz
24
23
25 // We assure that timerange is valid
24 // We assure that timerange is valid
26 if (end < start) {
25 if (end < start) {
27 std::swap(start, end);
26 std::swap(start, end);
28 }
27 }
29
28
30 // Generates scalar series containing cosinus values (one value per second)
29 // Generates scalar series containing cosinus values (one value per second)
31 auto dataCount = end - start;
30 auto dataCount = end - start;
32
31
33 auto xAxisData = QVector<double>{};
32 auto xAxisData = QVector<double>{};
34 xAxisData.resize(dataCount);
33 xAxisData.resize(dataCount);
35
34
36 auto valuesData = QVector<double>{};
35 auto valuesData = QVector<double>{};
37 valuesData.resize(dataCount);
36 valuesData.resize(dataCount);
38
37
39 int progress = 0;
38 int progress = 0;
40 auto progressEnd = dataCount;
39 auto progressEnd = dataCount;
41 for (auto time = start; time < end; ++time, ++dataIndex) {
40 for (auto time = start; time < end; ++time, ++dataIndex) {
42 auto it = m_VariableToEnableProvider.find(token);
41 auto it = m_VariableToEnableProvider.find(token);
43 if (it != m_VariableToEnableProvider.end() && it.value()) {
42 if (it != m_VariableToEnableProvider.end() && it.value()) {
44 const auto timeOnFreq = time / freq;
43 const auto timeOnFreq = time / freq;
45
44
46 xAxisData.replace(dataIndex, timeOnFreq);
45 xAxisData.replace(dataIndex, timeOnFreq);
47 valuesData.replace(dataIndex, std::cos(timeOnFreq));
46 valuesData.replace(dataIndex, std::cos(timeOnFreq));
48
47
49 // progression
48 // progression
50 int currentProgress = (time - start) * 100.0 / progressEnd;
49 int currentProgress = (time - start) * 100.0 / progressEnd;
51 if (currentProgress != progress) {
50 if (currentProgress != progress) {
52 progress = currentProgress;
51 progress = currentProgress;
53
52
54 emit dataProvidedProgress(token, progress);
53 emit dataProvidedProgress(token, progress);
55 }
54 }
56 }
55 }
57 else {
56 else {
58 if (!it.value()) {
57 if (!it.value()) {
59 qCDebug(LOG_CosinusProvider())
58 qCDebug(LOG_CosinusProvider())
60 << "CosinusProvider::retrieveData: ARRET De l'acquisition detectΓ©"
59 << "CosinusProvider::retrieveData: ARRET De l'acquisition detectΓ©"
61 << end - time;
60 << end - time;
62 }
61 }
63 }
62 }
64 }
63 }
65 emit dataProvidedProgress(token, 0.0);
64 emit dataProvidedProgress(token, 0.0);
66
65
67 return std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData),
66 return std::make_shared<ScalarSeries>(std::move(xAxisData), std::move(valuesData),
68 Unit{QStringLiteral("t"), true}, Unit{});
67 Unit{QStringLiteral("t"), true}, Unit{});
69 }
68 }
70
69
71 void CosinusProvider::requestDataLoading(QUuid token, const DataProviderParameters &parameters)
70 void CosinusProvider::requestDataLoading(QUuid token, const DataProviderParameters &parameters)
72 {
71 {
73 // TODO: Add Mutex
72 // TODO: Add Mutex
74 m_VariableToEnableProvider[token] = true;
73 m_VariableToEnableProvider[token] = true;
75 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataLoading"
74 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataLoading"
76 << QThread::currentThread()->objectName();
75 << QThread::currentThread()->objectName();
77 // NOTE: Try to use multithread if possible
76 // NOTE: Try to use multithread if possible
78 const auto times = parameters.m_Times;
77 const auto times = parameters.m_Times;
79
78
80 for (const auto &dateTime : qAsConst(times)) {
79 for (const auto &dateTime : qAsConst(times)) {
81 if (m_VariableToEnableProvider[token]) {
80 if (m_VariableToEnableProvider[token]) {
82 auto scalarSeries = this->retrieveData(token, dateTime);
81 auto scalarSeries = this->retrieveData(token, dateTime);
83 emit dataProvided(token, scalarSeries, dateTime);
82 emit dataProvided(token, scalarSeries, dateTime);
84 }
83 }
85 }
84 }
86 }
85 }
87
86
88 void CosinusProvider::requestDataAborting(QUuid identifier)
87 void CosinusProvider::requestDataAborting(QUuid identifier)
89 {
88 {
90 // TODO: Add Mutex
89 // TODO: Add Mutex
91 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataAborting" << identifier
90 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataAborting" << identifier
92 << QThread::currentThread()->objectName();
91 << QThread::currentThread()->objectName();
93 auto it = m_VariableToEnableProvider.find(identifier);
92 auto it = m_VariableToEnableProvider.find(identifier);
94 if (it != m_VariableToEnableProvider.end()) {
93 if (it != m_VariableToEnableProvider.end()) {
95 it.value() = false;
94 it.value() = false;
96 }
95 }
97 else {
96 else {
98 qCWarning(LOG_CosinusProvider())
97 qCWarning(LOG_CosinusProvider())
99 << tr("Aborting progression of inexistant identifier detected !!!");
98 << tr("Aborting progression of inexistant identifier detected !!!");
100 }
99 }
101 }
100 }
General Comments 0
You need to be logged in to leave comments. Login now