##// END OF EJS Templates
Merge pull request 196 from SCIQLOP-Initialisation develop...
perrinel -
r495:f81e8612a847 merge
parent child
Show More
@@ -0,0 +1,19
1 #ifndef SCIQLOP_DATEUTILS_H
2 #define SCIQLOP_DATEUTILS_H
3
4 #include "CoreGlobal.h"
5
6 #include <QDateTime>
7
8 /**
9 * Utility class with methods for dates
10 */
11 struct SCIQLOP_CORE_EXPORT DateUtils {
12 /// Converts seconds (since epoch) to datetime. By default, the datetime is in UTC
13 static QDateTime dateTime(double secs, Qt::TimeSpec timeSpec = Qt::UTC) noexcept;
14
15 /// Converts datetime to seconds since epoch
16 static double secondsSinceEpoch(const QDateTime &dateTime) noexcept;
17 };
18
19 #endif // SCIQLOP_DATEUTILS_H
@@ -0,0 +1,13
1 #include "Common/DateUtils.h"
2
3 QDateTime DateUtils::dateTime(double secs, Qt::TimeSpec timeSpec) noexcept
4 {
5 // Uses msecs to be Qt 4 compatible
6 return QDateTime::fromMSecsSinceEpoch(secs * 1000., timeSpec);
7 }
8
9 double DateUtils::secondsSinceEpoch(const QDateTime &dateTime) noexcept
10 {
11 // Uses msecs to be Qt 4 compatible
12 return dateTime.toMSecsSinceEpoch() / 1000.;
13 }
@@ -0,0 +1,20
1 #ifndef SCIQLOP_VISUALIZATIONGRAPHRENDERINGDELEGATE_H
2 #define SCIQLOP_VISUALIZATIONGRAPHRENDERINGDELEGATE_H
3
4 #include <Common/spimpl.h>
5
6 class QCustomPlot;
7 class QMouseEvent;
8
9 class VisualizationGraphRenderingDelegate {
10 public:
11 explicit VisualizationGraphRenderingDelegate(QCustomPlot &plot);
12
13 void onMouseMove(QMouseEvent *event) noexcept;
14
15 private:
16 class VisualizationGraphRenderingDelegatePrivate;
17 spimpl::unique_impl_ptr<VisualizationGraphRenderingDelegatePrivate> impl;
18 };
19
20 #endif // SCIQLOP_VISUALIZATIONGRAPHRENDERINGDELEGATE_H
@@ -0,0 +1,123
1 #include "Visualization/VisualizationGraphRenderingDelegate.h"
2 #include "Visualization/qcustomplot.h"
3
4 #include <Common/DateUtils.h>
5
6 namespace {
7
8 const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss:zzz");
9
10 const auto TEXT_TRACER_FORMAT = QStringLiteral("key: %1\nvalue: %2");
11
12 /// Timeout after which a tracer is displayed
13 const auto TRACER_TIMEOUT = 500;
14
15 /// Formats a data value according to the axis on which it is present
16 QString formatValue(double value, const QCPAxis &axis)
17 {
18 // If the axis is a time axis, formats the value as a date
19 if (auto axisTicker = qSharedPointerDynamicCast<QCPAxisTickerDateTime>(axis.ticker())) {
20 return DateUtils::dateTime(value, axisTicker->dateTimeSpec()).toString(DATETIME_FORMAT);
21 }
22 else {
23 return QString::number(value);
24 }
25 }
26
27 void initPointTracerStyle(QCPItemTracer &tracer) noexcept
28 {
29 tracer.setInterpolating(false);
30 tracer.setStyle(QCPItemTracer::tsPlus);
31 tracer.setPen(QPen(Qt::black));
32 tracer.setBrush(Qt::black);
33 tracer.setSize(10);
34 }
35
36 void initTextTracerStyle(QCPItemText &tracer) noexcept
37 {
38 tracer.setPen(QPen{Qt::gray});
39 tracer.setBrush(Qt::white);
40 tracer.setPadding(QMargins{6, 6, 6, 6});
41 tracer.setPositionAlignment(Qt::AlignTop | Qt::AlignLeft);
42 tracer.setTextAlignment(Qt::AlignLeft);
43 }
44
45 } // namespace
46
47 struct VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegatePrivate {
48 explicit VisualizationGraphRenderingDelegatePrivate(QCustomPlot &plot)
49 : m_Plot{plot},
50 m_PointTracer{new QCPItemTracer{&plot}},
51 m_TextTracer{new QCPItemText{&plot}},
52 m_TracerTimer{}
53 {
54 initPointTracerStyle(*m_PointTracer);
55 initTextTracerStyle(*m_TextTracer);
56
57 m_TracerTimer.setInterval(TRACER_TIMEOUT);
58 m_TracerTimer.setSingleShot(true);
59 }
60
61 QCustomPlot &m_Plot;
62 QCPItemTracer *m_PointTracer;
63 QCPItemText *m_TextTracer;
64 QTimer m_TracerTimer;
65 };
66
67 VisualizationGraphRenderingDelegate::VisualizationGraphRenderingDelegate(QCustomPlot &plot)
68 : impl{spimpl::make_unique_impl<VisualizationGraphRenderingDelegatePrivate>(plot)}
69 {
70 }
71
72 void VisualizationGraphRenderingDelegate::onMouseMove(QMouseEvent *event) noexcept
73 {
74 // Cancels pending refresh
75 impl->m_TracerTimer.disconnect();
76
77 auto showTracers = [ eventPos = event->pos(), this ]()
78 {
79 // Lambda function to display a tracer
80 auto displayTracer = [this](auto &tracer) {
81 // Tracer is set on top of the plot's main layer
82 tracer.setLayer(impl->m_Plot.layer("main"));
83 tracer.setVisible(true);
84 impl->m_Plot.replot();
85 };
86
87 // Reinits tracers
88 impl->m_PointTracer->setGraph(nullptr);
89 impl->m_PointTracer->setVisible(false);
90 impl->m_TextTracer->setVisible(false);
91 impl->m_Plot.replot();
92
93 // Gets the graph under the mouse position
94 if (auto graph = qobject_cast<QCPGraph *>(impl->m_Plot.plottableAt(eventPos))) {
95 auto mouseKey = graph->keyAxis()->pixelToCoord(eventPos.x());
96 auto graphData = graph->data();
97
98 // Gets the closest data point to the mouse
99 auto graphDataIt = graphData->findBegin(mouseKey);
100 if (graphDataIt != graphData->constEnd()) {
101 auto key = formatValue(graphDataIt->key, *graph->keyAxis());
102 auto value = formatValue(graphDataIt->value, *graph->valueAxis());
103 impl->m_TextTracer->setText(TEXT_TRACER_FORMAT.arg(key, value));
104
105 // Displays point tracer
106 impl->m_PointTracer->setGraph(graph);
107 impl->m_PointTracer->setGraphKey(graphDataIt->key);
108 displayTracer(*impl->m_PointTracer);
109
110 // Displays text tracer
111 auto tracerPosition = impl->m_TextTracer->position;
112 tracerPosition->setAxes(graph->keyAxis(), graph->valueAxis());
113 tracerPosition->setCoords(impl->m_PointTracer->position->key(),
114 impl->m_PointTracer->position->value());
115 displayTracer(*impl->m_TextTracer);
116 }
117 }
118 };
119
120 // Starts the timer to display tracers at timeout
121 QObject::connect(&impl->m_TracerTimer, &QTimer::timeout, showTracers);
122 impl->m_TracerTimer.start();
123 }
@@ -36,7 +36,6
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>
@@ -23,7 +23,7 struct Unit {
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 /**
@@ -3,18 +3,18
3
3
4 #include <QObject>
4 #include <QObject>
5
5
6 #include <QDateTime>
7 #include <QDebug>
6 #include <QDebug>
8
7
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
@@ -30,10 +30,9 struct SqpDateTime {
30
30
31 inline QDebug operator<<(QDebug d, SqpDateTime obj)
31 inline QDebug operator<<(QDebug d, SqpDateTime obj)
32 {
32 {
33 auto tendDateTimeStart = QDateTime::fromMSecsSinceEpoch(obj.m_TStart * 1000);
33 auto tendDateTimeStart = DateUtils::dateTime(obj.m_TStart);
34 auto tendDateTimeEnd = QDateTime::fromMSecsSinceEpoch(obj.m_TEnd * 1000);
34 auto tendDateTimeEnd = DateUtils::dateTime(obj.m_TEnd);
35
35
36 // QDebug << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
37 d << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
36 d << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
38 return d;
37 return d;
39 }
38 }
@@ -8,7 +8,6
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>
@@ -1,9 +1,10
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>
5
4 #include <Data/IDataSeries.h>
6 #include <Data/IDataSeries.h>
5
7
6 #include <QDateTime>
7 #include <QSize>
8 #include <QSize>
8 #include <unordered_map>
9 #include <unordered_map>
9
10
@@ -150,8 +151,8 QVariant VariableModel::data(const QModelIndex &index, int role) const
150 if (role == Qt::DisplayRole) {
151 if (role == Qt::DisplayRole) {
151 if (auto variable = impl->m_Variables.at(index.row()).get()) {
152 if (auto variable = impl->m_Variables.at(index.row()).get()) {
152 /// 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
153 auto dateTimeVariant = [](double time) {
154 auto dateTimeVariant = [](double secs) {
154 auto dateTime = QDateTime::fromMSecsSinceEpoch(time * 1000.);
155 auto dateTime = DateUtils::dateTime(secs);
155 return dateTime.toString(DATETIME_FORMAT);
156 return dateTime.toString(DATETIME_FORMAT);
156 };
157 };
157
158
@@ -69,6 +69,8 private slots:
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
73 void onMouseMove(QMouseEvent *event) noexcept;
72 /// 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
73 void onMouseWheel(QWheelEvent *event) noexcept;
75 void onMouseWheel(QWheelEvent *event) noexcept;
74 /// 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
@@ -1,6 +1,7
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 <SqpApplication.h>
5 #include <SqpApplication.h>
5 #include <Time/TimeController.h>
6 #include <Time/TimeController.h>
6
7
@@ -22,13 +23,15 TimeWidget::TimeWidget(QWidget *parent) : QWidget{parent}, ui{new Ui::TimeWidget
22 &TimeController::onTimeNotify);
23 &TimeController::onTimeNotify);
23
24
24 // Initialisation
25 // Initialisation
25 ui->startDateTimeEdit->setDateTime(
26 auto endDateTime = QDateTime::currentDateTimeUtc();
26 QDateTime::currentDateTime().addSecs(-3600)); // one hour berefore
27 auto startDateTime = endDateTime.addSecs(-3600); // one hour before
27 ui->endDateTimeEdit->setDateTime(QDateTime::currentDateTime());
28
29 ui->startDateTimeEdit->setDateTime(startDateTime);
30 ui->endDateTimeEdit->setDateTime(endDateTime);
31
32 auto dateTime = SqpDateTime{DateUtils::secondsSinceEpoch(startDateTime),
33 DateUtils::secondsSinceEpoch(endDateTime)};
28
34
29 auto dateTime
30 = SqpDateTime{QDateTime::currentDateTime().addSecs(-3600).toMSecsSinceEpoch() / 1000.0,
31 QDateTime::currentDateTime().toMSecsSinceEpoch() / 1000.0};
32 sqpApp->timeController().onTimeToUpdate(dateTime);
35 sqpApp->timeController().onTimeToUpdate(dateTime);
33 }
36 }
34
37
@@ -40,9 +43,8 TimeWidget::~TimeWidget()
40
43
41 void TimeWidget::onTimeUpdateRequested()
44 void TimeWidget::onTimeUpdateRequested()
42 {
45 {
43 auto dateTime = SqpDateTime{
46 auto dateTime = SqpDateTime{DateUtils::secondsSinceEpoch(ui->startDateTimeEdit->dateTime()),
44 static_cast<double>(ui->startDateTimeEdit->dateTime().toMSecsSinceEpoch() / 1000.),
47 DateUtils::secondsSinceEpoch(ui->endDateTimeEdit->dateTime())};
45 static_cast<double>(ui->endDateTimeEdit->dateTime().toMSecsSinceEpoch()) / 1000.};
46
48
47 emit timeUpdated(std::move(dateTime));
49 emit timeUpdated(std::move(dateTime));
48 }
50 }
@@ -25,6 +25,7 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis)
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
29
29 return dateTicker;
30 return dateTicker;
30 }
31 }
@@ -1,6 +1,7
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 "ui_VisualizationGraphWidget.h"
5 #include "ui_VisualizationGraphWidget.h"
5
6
6 #include <Data/ArrayData.h>
7 #include <Data/ArrayData.h>
@@ -33,17 +34,21 double toleranceValue(const QString &key, double defaultValue) noexcept
33
34
34 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
35 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
35
36
36 explicit VisualizationGraphWidgetPrivate() : m_DoSynchronize{true}, m_IsCalibration{false} {}
37 explicit VisualizationGraphWidgetPrivate()
37
38 : m_DoSynchronize{true}, m_IsCalibration{false}, m_RenderingDelegate{nullptr}
39 {
40 }
38
41
39 // Return the operation when range changed
42 // Return the operation when range changed
40 VisualizationGraphWidgetZoomType getZoomType(const QCPRange &t1, const QCPRange &t2);
43 VisualizationGraphWidgetZoomType getZoomType(const QCPRange &t1, const QCPRange &t2);
41
44
42 // 1 variable -> n qcpplot
45 // 1 variable -> n qcpplot
43 std::multimap<std::shared_ptr<Variable>, QCPAbstractPlottable *> m_VariableToPlotMultiMap;
46 std::multimap<std::shared_ptr<Variable>, QCPAbstractPlottable *> m_VariableToPlotMultiMap;
44
45 bool m_DoSynchronize;
47 bool m_DoSynchronize;
46 bool m_IsCalibration;
48 bool m_IsCalibration;
49 QCPItemTracer *m_TextTracer;
50 /// Delegate used to attach rendering features to the plot
51 std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
47 };
52 };
48
53
49 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
54 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
@@ -53,6 +58,9 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget
53 {
58 {
54 ui->setupUi(this);
59 ui->setupUi(this);
55
60
61 // The delegate must be initialized after the ui as it uses the plot
62 impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*ui->widget);
63
56 ui->graphNameLabel->setText(name);
64 ui->graphNameLabel->setText(name);
57
65
58 // 'Close' options : widget is deleted when closed
66 // 'Close' options : widget is deleted when closed
@@ -65,9 +73,11 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget
65 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
73 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
66 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
74 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
67 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
75 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
76
68 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
77 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
69 connect(ui->widget, &QCustomPlot::mouseRelease, this,
78 connect(ui->widget, &QCustomPlot::mouseRelease, this,
70 &VisualizationGraphWidget::onMouseRelease);
79 &VisualizationGraphWidget::onMouseRelease);
80 connect(ui->widget, &QCustomPlot::mouseMove, this, &VisualizationGraphWidget::onMouseMove);
71 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
81 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
72 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 &)>(
73 &QCPAxis::rangeChanged),
83 &QCPAxis::rangeChanged),
@@ -329,6 +339,12 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange
329 }
339 }
330 }
340 }
331
341
342 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
343 {
344 // Handles plot rendering when mouse is moving
345 impl->m_RenderingDelegate->onMouseMove(event);
346 }
347
332 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
348 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
333 {
349 {
334 auto zoomOrientations = QFlags<Qt::Orientation>{};
350 auto zoomOrientations = QFlags<Qt::Orientation>{};
@@ -47,6 +47,9
47 <property name="calendarPopup">
47 <property name="calendarPopup">
48 <bool>true</bool>
48 <bool>true</bool>
49 </property>
49 </property>
50 <property name="timeSpec">
51 <enum>Qt::UTC</enum>
52 </property>
50 </widget>
53 </widget>
51 </item>
54 </item>
52 <item>
55 <item>
@@ -76,6 +79,9
76 <property name="calendarPopup">
79 <property name="calendarPopup">
77 <bool>true</bool>
80 <bool>true</bool>
78 </property>
81 </property>
82 <property name="timeSpec">
83 <enum>Qt::UTC</enum>
84 </property>
79 </widget>
85 </widget>
80 </item>
86 </item>
81 <item>
87 <item>
@@ -2,6 +2,7
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 <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
6 #include <Network/NetworkController.h>
7 #include <Network/NetworkController.h>
7 #include <SqpApplication.h>
8 #include <SqpApplication.h>
@@ -31,7 +32,7 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
31 /// 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
32 QString dateFormat(double sqpDateTime) noexcept
33 QString dateFormat(double sqpDateTime) noexcept
33 {
34 {
34 auto dateTime = QDateTime::fromMSecsSinceEpoch(sqpDateTime * 1000.);
35 auto dateTime = DateUtils::dateTime(sqpDateTime);
35 return dateTime.toString(AMDA_TIME_FORMAT);
36 return dateTime.toString(AMDA_TIME_FORMAT);
36 }
37 }
37
38
@@ -1,5 +1,6
1 #include "AmdaResultParser.h"
1 #include "AmdaResultParser.h"
2
2
3 #include <Common/DateUtils.h>
3 #include <Data/ScalarSeries.h>
4 #include <Data/ScalarSeries.h>
4
5
5 #include <QDateTime>
6 #include <QDateTime>
@@ -33,10 +34,17 const auto UNIT_REGEX = QRegularExpression{QStringLiteral("-\\s*Units\\s*:\\s*(.
33 double doubleDate(const QString &stringDate) noexcept
34 double doubleDate(const QString &stringDate) noexcept
34 {
35 {
35 auto dateTime = QDateTime::fromString(stringDate, DATE_FORMAT);
36 auto dateTime = QDateTime::fromString(stringDate, DATE_FORMAT);
36 return dateTime.isValid() ? (dateTime.toMSecsSinceEpoch() / 1000.)
37 dateTime.setTimeSpec(Qt::UTC);
38 return dateTime.isValid() ? DateUtils::secondsSinceEpoch(dateTime)
37 : std::numeric_limits<double>::quiet_NaN();
39 : std::numeric_limits<double>::quiet_NaN();
38 }
40 }
39
41
42 /// Checks if a line is a comment line
43 bool isCommentLine(const QString &line)
44 {
45 return line.startsWith("#");
46 }
47
40 /**
48 /**
41 * Reads stream to retrieve x-axis unit
49 * Reads stream to retrieve x-axis unit
42 * @param stream the stream to read
50 * @param stream the stream to read
@@ -47,20 +55,16 Unit readXAxisUnit(QTextStream &stream)
47 {
55 {
48 QString line{};
56 QString line{};
49
57
50 if (stream.readLineInto(&line)) {
58 // Searches unit in the comment lines
59 while (stream.readLineInto(&line) && isCommentLine(line)) {
51 auto match = UNIT_REGEX.match(line);
60 auto match = UNIT_REGEX.match(line);
52 if (match.hasMatch()) {
61 if (match.hasMatch()) {
53 return Unit{match.captured(1), true};
62 return Unit{match.captured(1), true};
54 }
63 }
55 else {
56 qCWarning(LOG_AmdaResultParser())
57 << QObject::tr("Can't read unit: invalid line %1").arg(line);
58 }
59 }
60 else {
61 qCWarning(LOG_AmdaResultParser()) << QObject::tr("Can't read unit: end of file");
62 }
64 }
63
65
66 qCWarning(LOG_AmdaResultParser()) << QObject::tr("The unit could not be found in the file");
67
64 // Error cases
68 // Error cases
65 return Unit{{}, true};
69 return Unit{{}, true};
66 }
70 }
@@ -76,32 +80,36 QPair<QVector<double>, QVector<double> > readResults(QTextStream &stream)
76 auto valuesData = QVector<double>{};
80 auto valuesData = QVector<double>{};
77
81
78 QString line{};
82 QString line{};
83
79 while (stream.readLineInto(&line)) {
84 while (stream.readLineInto(&line)) {
80 auto lineData = line.split(RESULT_LINE_SEPARATOR, QString::SkipEmptyParts);
85 // Ignore comment lines
81 if (lineData.size() == 2) {
86 if (!isCommentLine(line)) {
82 // X : the data is converted from date to double (in secs)
87 auto lineData = line.split(RESULT_LINE_SEPARATOR, QString::SkipEmptyParts);
83 auto x = doubleDate(lineData.at(0));
88 if (lineData.size() == 2) {
84
89 // X : the data is converted from date to double (in secs)
85 // Value
90 auto x = doubleDate(lineData.at(0));
86 bool valueOk;
91
87 auto value = lineData.at(1).toDouble(&valueOk);
92 // Value
88
93 bool valueOk;
89 // Adds result only if x and value are valid
94 auto value = lineData.at(1).toDouble(&valueOk);
90 if (!std::isnan(x) && !std::isnan(value) && valueOk) {
95
91 xData.push_back(x);
96 // Adds result only if x and value are valid
92 valuesData.push_back(value);
97 if (!std::isnan(x) && !std::isnan(value) && valueOk) {
98 xData.push_back(x);
99 valuesData.push_back(value);
100 }
101 else {
102 qCWarning(LOG_AmdaResultParser())
103 << QObject::tr(
104 "Can't retrieve results from line %1: x and/or value are invalid")
105 .arg(line);
106 }
93 }
107 }
94 else {
108 else {
95 qCWarning(LOG_AmdaResultParser())
109 qCWarning(LOG_AmdaResultParser())
96 << QObject::tr(
110 << QObject::tr("Can't retrieve results from line %1: invalid line").arg(line);
97 "Can't retrieve results from line %1: x and/or value are invalid")
98 .arg(line);
99 }
111 }
100 }
112 }
101 else {
102 qCWarning(LOG_AmdaResultParser())
103 << QObject::tr("Can't retrieve results from line %1: invalid line").arg(line);
104 }
105 }
113 }
106
114
107 return qMakePair(std::move(xData), std::move(valuesData));
115 return qMakePair(std::move(xData), std::move(valuesData));
@@ -131,13 +139,12 std::shared_ptr<IDataSeries> AmdaResultParser::readTxt(const QString &filePath)
131 return nullptr;
139 return nullptr;
132 }
140 }
133
141
134 // Ignore comments lines
135 stream.readLine();
136
137 // Reads x-axis unit
142 // Reads x-axis unit
143 stream.seek(0); // returns to the beginning of the file
138 auto xAxisUnit = readXAxisUnit(stream);
144 auto xAxisUnit = readXAxisUnit(stream);
139
145
140 // Reads results
146 // Reads results
147 stream.seek(0); // returns to the beginning of the file
141 auto results = readResults(stream);
148 auto results = readResults(stream);
142
149
143 return std::make_shared<ScalarSeries>(std::move(results.first), std::move(results.second),
150 return std::make_shared<ScalarSeries>(std::move(results.first), std::move(results.second),
@@ -99,7 +99,7 void TestAmdaResultParser::testReadTxt_data()
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
@@ -5,7 +5,6
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>
General Comments 0
You need to be logged in to leave comments. Login now