##// END OF EJS Templates
Merge pull request 189 from SCIQLOP-Initialisation develop...
leroux -
r448:f7cb609ac07f merge
parent child
Show More
@@ -0,0 +1,42
1 #ifndef SCIQLOP_RESCALEAXEOPERATION_H
2 #define SCIQLOP_RESCALEAXEOPERATION_H
3
4 #include "Visualization/IVisualizationWidgetVisitor.h"
5 #include <Data/SqpDateTime.h>
6
7 #include <Common/spimpl.h>
8
9 #include <QLoggingCategory>
10
11 #include <memory>
12
13 class Variable;
14
15 Q_DECLARE_LOGGING_CATEGORY(LOG_RescaleAxeOperation)
16
17 /**
18 * @brief The RescaleAxeOperation class defines an operation that traverses all of visualization
19 * widgets to remove a variable if they contain it
20 */
21 class RescaleAxeOperation : public IVisualizationWidgetVisitor {
22 public:
23 /**
24 * Ctor
25 * @param variable the variable to remove from widgets
26 */
27 explicit RescaleAxeOperation(std::shared_ptr<Variable> variable, const SqpDateTime &range);
28
29 void visitEnter(VisualizationWidget *widget) override final;
30 void visitLeave(VisualizationWidget *widget) override final;
31 void visitEnter(VisualizationTabWidget *tabWidget) override final;
32 void visitLeave(VisualizationTabWidget *tabWidget) override final;
33 void visitEnter(VisualizationZoneWidget *zoneWidget) override final;
34 void visitLeave(VisualizationZoneWidget *zoneWidget) override final;
35 void visit(VisualizationGraphWidget *graphWidget) override final;
36
37 private:
38 class RescaleAxeOperationPrivate;
39 spimpl::unique_impl_ptr<RescaleAxeOperationPrivate> impl;
40 };
41
42 #endif // SCIQLOP_RESCALEAXEOPERATION_H
@@ -0,0 +1,71
1 #include "Visualization/operations/RescaleAxeOperation.h"
2 #include "Visualization/VisualizationGraphWidget.h"
3
4 Q_LOGGING_CATEGORY(LOG_RescaleAxeOperation, "RescaleAxeOperation")
5
6 struct RescaleAxeOperation::RescaleAxeOperationPrivate {
7 explicit RescaleAxeOperationPrivate(std::shared_ptr<Variable> variable,
8 const SqpDateTime &range)
9 : m_Variable{variable}, m_Range{range}
10 {
11 }
12
13 std::shared_ptr<Variable> m_Variable;
14 SqpDateTime m_Range;
15 };
16
17 RescaleAxeOperation::RescaleAxeOperation(std::shared_ptr<Variable> variable,
18 const SqpDateTime &range)
19 : impl{spimpl::make_unique_impl<RescaleAxeOperationPrivate>(variable, range)}
20 {
21 }
22
23 void RescaleAxeOperation::visitEnter(VisualizationWidget *widget)
24 {
25 // VisualizationWidget is not intended to contain a variable
26 Q_UNUSED(widget)
27 }
28
29 void RescaleAxeOperation::visitLeave(VisualizationWidget *widget)
30 {
31 // VisualizationWidget is not intended to contain a variable
32 Q_UNUSED(widget)
33 }
34
35 void RescaleAxeOperation::visitEnter(VisualizationTabWidget *tabWidget)
36 {
37 // VisualizationTabWidget is not intended to contain a variable
38 Q_UNUSED(tabWidget)
39 }
40
41 void RescaleAxeOperation::visitLeave(VisualizationTabWidget *tabWidget)
42 {
43 // VisualizationTabWidget is not intended to contain a variable
44 Q_UNUSED(tabWidget)
45 }
46
47 void RescaleAxeOperation::visitEnter(VisualizationZoneWidget *zoneWidget)
48 {
49 // VisualizationZoneWidget is not intended to contain a variable
50 Q_UNUSED(zoneWidget)
51 }
52
53 void RescaleAxeOperation::visitLeave(VisualizationZoneWidget *zoneWidget)
54 {
55 // VisualizationZoneWidget is not intended to contain a variable
56 Q_UNUSED(zoneWidget)
57 }
58
59 void RescaleAxeOperation::visit(VisualizationGraphWidget *graphWidget)
60 {
61 if (graphWidget) {
62 // If the widget contains the variable, rescale it
63 if (impl->m_Variable && graphWidget->contains(*impl->m_Variable)) {
64 graphWidget->setRange(impl->m_Variable, impl->m_Range);
65 }
66 }
67 else {
68 qCCritical(LOG_RescaleAxeOperation(),
69 "Can't visit VisualizationGraphWidget : the widget is null");
70 }
71 }
@@ -0,0 +1,3
1 Not Found
2
3 The requested URL /AMDA/data/WSRESULT/imf(0)-1343153090-1343153092-60.txt was not found on this server. No newline at end of file
@@ -192,6 +192,10 MainWindow::MainWindow(QWidget *parent)
192 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), m_Ui->view,
192 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), m_Ui->view,
193 SLOT(onVariableAboutToBeDeleted(std::shared_ptr<Variable>)));
193 SLOT(onVariableAboutToBeDeleted(std::shared_ptr<Variable>)));
194
194
195 connect(&sqpApp->visualizationController(),
196 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpDateTime &)), m_Ui->view,
197 SLOT(onRangeChanged(std::shared_ptr<Variable>, const SqpDateTime &)));
198
195 // Widgets / widgets connections
199 // Widgets / widgets connections
196
200
197 // For the following connections, we use DirectConnection to allow each widget that can
201 // For the following connections, we use DirectConnection to allow each widget that can
@@ -10,6 +10,8
10
10
11 #include <Data/SqpDateTime.h>
11 #include <Data/SqpDateTime.h>
12
12
13 #include <functional>
14
13 class DataProviderParameters;
15 class DataProviderParameters;
14 class IDataSeries;
16 class IDataSeries;
15 class QNetworkReply;
17 class QNetworkReply;
@@ -34,6 +36,11 public:
34 */
36 */
35 virtual void requestDataLoading(QUuid identifier, const DataProviderParameters &parameters) = 0;
37 virtual void requestDataLoading(QUuid identifier, const DataProviderParameters &parameters) = 0;
36
38
39 /**
40 * @brief requestDataAborting stop data loading of the data identified by identifier
41 */
42 virtual void requestDataAborting(QUuid identifier) = 0;
43
37 signals:
44 signals:
38 /**
45 /**
39 * @brief dataProvided send dataSeries under dateTime and that corresponds of the data
46 * @brief dataProvided send dataSeries under dateTime and that corresponds of the data
@@ -42,6 +49,12 signals:
42 void dataProvided(QUuid identifier, std::shared_ptr<IDataSeries> dateSerie,
49 void dataProvided(QUuid identifier, std::shared_ptr<IDataSeries> dateSerie,
43 const SqpDateTime &dateTime);
50 const SqpDateTime &dateTime);
44
51
52 /**
53 * @brief dataProvided send dataSeries under dateTime and that corresponds of the data
54 * identified by identifier
55 */
56 void dataProvidedProgress(QUuid identifier, double progress);
57
45
58
46 /**
59 /**
47 * @brief requestConstructed send a request for the data identified by identifier
60 * @brief requestConstructed send a request for the data identified by identifier
@@ -6,6 +6,8
6 #include <QLoggingCategory>
6 #include <QLoggingCategory>
7 #include <QObject>
7 #include <QObject>
8
8
9 #include <functional>
10
9 Q_DECLARE_LOGGING_CATEGORY(LOG_DataSourceItemAction)
11 Q_DECLARE_LOGGING_CATEGORY(LOG_DataSourceItemAction)
10
12
11 class DataSourceItem;
13 class DataSourceItem;
@@ -50,10 +50,18 public:
50 */
50 */
51 void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept;
51 void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept;
52
52
53 /**
54 * @brief abort the variable retrieve data progression
55 */
56 void abortProgress(std::shared_ptr<Variable> variable);
57
53 signals:
58 signals:
54 /// Signal emitted when a variable is about to be deleted from the controller
59 /// Signal emitted when a variable is about to be deleted from the controller
55 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
60 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
56
61
62 /// Signal emitted when a data acquisition is requested on a range for a variable
63 void rangeChanged(std::shared_ptr<Variable> variable, const SqpDateTime &range);
64
57 public slots:
65 public slots:
58 /// Request the data loading of the variable whithin dateTime
66 /// Request the data loading of the variable whithin dateTime
59 void onRequestDataLoading(std::shared_ptr<Variable> variable, const SqpDateTime &dateTime);
67 void onRequestDataLoading(std::shared_ptr<Variable> variable, const SqpDateTime &dateTime);
@@ -72,6 +80,8 public slots:
72
80
73 void onVariableRetrieveDataInProgress(QUuid identifier, double progress);
81 void onVariableRetrieveDataInProgress(QUuid identifier, double progress);
74
82
83 void onAbortProgressRequested(std::shared_ptr<Variable> variable);
84
75 void initialize();
85 void initialize();
76 void finalize();
86 void finalize();
77
87
@@ -22,6 +22,7 class Variable;
22 * @brief The VariableModel class aims to hold the variables that have been created in SciQlop
22 * @brief The VariableModel class aims to hold the variables that have been created in SciQlop
23 */
23 */
24 class VariableModel : public QAbstractTableModel {
24 class VariableModel : public QAbstractTableModel {
25 Q_OBJECT
25 public:
26 public:
26 explicit VariableModel(QObject *parent = nullptr);
27 explicit VariableModel(QObject *parent = nullptr);
27
28
@@ -46,6 +47,7 public:
46
47
47 void setDataProgress(std::shared_ptr<Variable> variable, double progress);
48 void setDataProgress(std::shared_ptr<Variable> variable, double progress);
48
49
50
49 // /////////////////////////// //
51 // /////////////////////////// //
50 // QAbstractTableModel methods //
52 // QAbstractTableModel methods //
51 // /////////////////////////// //
53 // /////////////////////////// //
@@ -56,6 +58,12 public:
56 virtual QVariant headerData(int section, Qt::Orientation orientation,
58 virtual QVariant headerData(int section, Qt::Orientation orientation,
57 int role = Qt::DisplayRole) const override;
59 int role = Qt::DisplayRole) const override;
58
60
61
62 void abortProgress(const QModelIndex &index);
63
64 signals:
65 void abortProgessRequested(std::shared_ptr<Variable> variable);
66
59 private:
67 private:
60 class VariableModelPrivate;
68 class VariableModelPrivate;
61 spimpl::unique_impl_ptr<VariableModelPrivate> impl;
69 spimpl::unique_impl_ptr<VariableModelPrivate> impl;
@@ -1,6 +1,8
1 #ifndef SCIQLOP_VISUALIZATIONCONTROLLER_H
1 #ifndef SCIQLOP_VISUALIZATIONCONTROLLER_H
2 #define SCIQLOP_VISUALIZATIONCONTROLLER_H
2 #define SCIQLOP_VISUALIZATIONCONTROLLER_H
3
3
4 #include <Data/SqpDateTime.h>
5
4 #include <QLoggingCategory>
6 #include <QLoggingCategory>
5 #include <QObject>
7 #include <QObject>
6 #include <QUuid>
8 #include <QUuid>
@@ -29,6 +31,9 signals:
29 /// Signal emitted when a variable is about to be deleted from SciQlop
31 /// Signal emitted when a variable is about to be deleted from SciQlop
30 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
32 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
31
33
34 /// Signal emitted when a data acquisition is requested on a range for a variable
35 void rangeChanged(std::shared_ptr<Variable> variable, const SqpDateTime &range);
36
32 public slots:
37 public slots:
33 /// Manage init/end of the controller
38 /// Manage init/end of the controller
34 void initialize();
39 void initialize();
@@ -4,6 +4,7
4 #include <QNetworkAccessManager>
4 #include <QNetworkAccessManager>
5 #include <QNetworkReply>
5 #include <QNetworkReply>
6 #include <QNetworkRequest>
6 #include <QNetworkRequest>
7 #include <QReadWriteLock>
7 #include <QThread>
8 #include <QThread>
8
9
9 #include <unordered_map>
10 #include <unordered_map>
@@ -14,8 +15,13 struct NetworkController::NetworkControllerPrivate {
14 explicit NetworkControllerPrivate(NetworkController *parent) : m_WorkingMutex{} {}
15 explicit NetworkControllerPrivate(NetworkController *parent) : m_WorkingMutex{} {}
15 QMutex m_WorkingMutex;
16 QMutex m_WorkingMutex;
16
17
18 QReadWriteLock m_Lock;
17 std::unordered_map<QNetworkReply *, QUuid> m_NetworkReplyToVariableId;
19 std::unordered_map<QNetworkReply *, QUuid> m_NetworkReplyToVariableId;
18 std::unique_ptr<QNetworkAccessManager> m_AccessManager{nullptr};
20 std::unique_ptr<QNetworkAccessManager> m_AccessManager{nullptr};
21
22 void lockRead() { m_Lock.lockForRead(); }
23 void lockWrite() { m_Lock.lockForWrite(); }
24 void unlock() { m_Lock.unlock(); }
19 };
25 };
20
26
21 NetworkController::NetworkController(QObject *parent)
27 NetworkController::NetworkController(QObject *parent)
@@ -26,35 +32,57 NetworkController::NetworkController(QObject *parent)
26 void NetworkController::onProcessRequested(const QNetworkRequest &request, QUuid identifier,
32 void NetworkController::onProcessRequested(const QNetworkRequest &request, QUuid identifier,
27 std::function<void(QNetworkReply *, QUuid)> callback)
33 std::function<void(QNetworkReply *, QUuid)> callback)
28 {
34 {
29 qCInfo(LOG_NetworkController()) << tr("NetworkController registered")
35 qCDebug(LOG_NetworkController()) << tr("NetworkController registered")
30 << QThread::currentThread();
36 << QThread::currentThread()->objectName();
31 auto reply = impl->m_AccessManager->get(request);
37 auto reply = impl->m_AccessManager->get(request);
32
38
33 // Store the couple reply id
39 // Store the couple reply id
40 impl->lockWrite();
34 impl->m_NetworkReplyToVariableId[reply] = identifier;
41 impl->m_NetworkReplyToVariableId[reply] = identifier;
42 impl->unlock();
35
43
36 auto onReplyFinished = [reply, this, identifier, callback]() {
44 auto onReplyFinished = [reply, this, identifier, callback]() {
37
45
38 qCInfo(LOG_NetworkController()) << tr("NetworkController onReplyFinished")
46 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyFinished")
39 << QThread::currentThread();
47 << QThread::currentThread() << reply;
48 impl->lockRead();
40 auto it = impl->m_NetworkReplyToVariableId.find(reply);
49 auto it = impl->m_NetworkReplyToVariableId.find(reply);
50 impl->unlock();
41 if (it != impl->m_NetworkReplyToVariableId.cend()) {
51 if (it != impl->m_NetworkReplyToVariableId.cend()) {
52 impl->lockWrite();
53 impl->m_NetworkReplyToVariableId.erase(reply);
54 impl->unlock();
55 // Deletes reply
42 callback(reply, identifier);
56 callback(reply, identifier);
57 reply->deleteLater();
58
59 emit this->replyDownloadProgress(identifier, 0);
43 }
60 }
61
62 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyFinished END")
63 << QThread::currentThread() << reply;
44 };
64 };
45
65
46 auto onReplyProgress = [reply, this](qint64 bytesRead, qint64 totalBytes) {
66 auto onReplyProgress = [reply, this](qint64 bytesRead, qint64 totalBytes) {
47
67
48 double progress = (bytesRead * 100.0) / totalBytes;
68 double progress = (bytesRead * 100.0) / totalBytes;
69 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress") << progress
70 << QThread::currentThread() << reply;
71 impl->lockRead();
49 auto it = impl->m_NetworkReplyToVariableId.find(reply);
72 auto it = impl->m_NetworkReplyToVariableId.find(reply);
73 impl->unlock();
50 if (it != impl->m_NetworkReplyToVariableId.cend()) {
74 if (it != impl->m_NetworkReplyToVariableId.cend()) {
51 emit this->replyDownloadProgress(it->second, progress);
75 emit this->replyDownloadProgress(it->second, progress);
52 }
76 }
77 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress END")
78 << QThread::currentThread() << reply;
53 };
79 };
54
80
55
81
56 connect(reply, &QNetworkReply::finished, this, onReplyFinished);
82 connect(reply, &QNetworkReply::finished, this, onReplyFinished);
57 connect(reply, &QNetworkReply::downloadProgress, this, onReplyProgress);
83 connect(reply, &QNetworkReply::downloadProgress, this, onReplyProgress);
84 qCDebug(LOG_NetworkController()) << tr("NetworkController registered END")
85 << QThread::currentThread()->objectName() << reply;
58 }
86 }
59
87
60 void NetworkController::initialize()
88 void NetworkController::initialize()
@@ -62,6 +90,17 void NetworkController::initialize()
62 qCDebug(LOG_NetworkController()) << tr("NetworkController init") << QThread::currentThread();
90 qCDebug(LOG_NetworkController()) << tr("NetworkController init") << QThread::currentThread();
63 impl->m_WorkingMutex.lock();
91 impl->m_WorkingMutex.lock();
64 impl->m_AccessManager = std::make_unique<QNetworkAccessManager>();
92 impl->m_AccessManager = std::make_unique<QNetworkAccessManager>();
93
94
95 auto onReplyErrors = [this](QNetworkReply *reply, const QList<QSslError> &errors) {
96
97 qCCritical(LOG_NetworkController()) << tr("NetworkAcessManager errors: ") << errors;
98
99 };
100
101
102 connect(impl->m_AccessManager.get(), &QNetworkAccessManager::sslErrors, this, onReplyErrors);
103
65 qCDebug(LOG_NetworkController()) << tr("NetworkController init END");
104 qCDebug(LOG_NetworkController()) << tr("NetworkController init END");
66 }
105 }
67
106
@@ -73,12 +112,19 void NetworkController::finalize()
73 void NetworkController::onReplyCanceled(QUuid identifier)
112 void NetworkController::onReplyCanceled(QUuid identifier)
74 {
113 {
75 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
114 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
115 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled")
116 << QThread::currentThread();
117
76
118
119 impl->lockRead();
77 auto end = impl->m_NetworkReplyToVariableId.cend();
120 auto end = impl->m_NetworkReplyToVariableId.cend();
78 auto it = std::find_if(impl->m_NetworkReplyToVariableId.cbegin(), end, findReply);
121 auto it = std::find_if(impl->m_NetworkReplyToVariableId.cbegin(), end, findReply);
122 impl->unlock();
79 if (it != end) {
123 if (it != end) {
80 it->first->abort();
124 it->first->abort();
81 }
125 }
126 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled END")
127 << QThread::currentThread();
82 }
128 }
83
129
84 void NetworkController::waitForFinish()
130 void NetworkController::waitForFinish()
@@ -60,7 +60,7 void Variable::setDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
60 impl->m_DataSeries->merge(dataSeries.get());
60 impl->m_DataSeries->merge(dataSeries.get());
61 impl->m_DataSeries->unlock();
61 impl->m_DataSeries->unlock();
62 dataSeries->unlock();
62 dataSeries->unlock();
63 emit updated();
63 // emit updated();
64 }
64 }
65 }
65 }
66
66
@@ -38,7 +38,7 struct VariableController::VariableControllerPrivate {
38
38
39 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
39 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
40 m_VariableToProviderMap;
40 m_VariableToProviderMap;
41 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifier;
41 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
42 };
42 };
43
43
44 VariableController::VariableController(QObject *parent)
44 VariableController::VariableController(QObject *parent)
@@ -46,6 +46,9 VariableController::VariableController(QObject *parent)
46 {
46 {
47 qCDebug(LOG_VariableController()) << tr("VariableController construction")
47 qCDebug(LOG_VariableController()) << tr("VariableController construction")
48 << QThread::currentThread();
48 << QThread::currentThread();
49
50 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
51 &VariableController::onAbortProgressRequested);
49 }
52 }
50
53
51 VariableController::~VariableController()
54 VariableController::~VariableController()
@@ -81,6 +84,9 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noex
81 // make some treatments before the deletion
84 // make some treatments before the deletion
82 emit variableAboutToBeDeleted(variable);
85 emit variableAboutToBeDeleted(variable);
83
86
87 // Deletes identifier
88 impl->m_VariableToIdentifierMap.erase(variable);
89
84 // Deletes provider
90 // Deletes provider
85 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
91 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
86 qCDebug(LOG_VariableController())
92 qCDebug(LOG_VariableController())
@@ -102,6 +108,10 void VariableController::deleteVariables(
102 }
108 }
103 }
109 }
104
110
111 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
112 {
113 }
114
105 void VariableController::createVariable(const QString &name, const QVariantHash &metadata,
115 void VariableController::createVariable(const QString &name, const QVariantHash &metadata,
106 std::shared_ptr<IDataProvider> provider) noexcept
116 std::shared_ptr<IDataProvider> provider) noexcept
107 {
117 {
@@ -119,21 +129,24 void VariableController::createVariable(const QString &name, const QVariantHash
119
129
120 // store the provider
130 // store the provider
121 impl->m_VariableToProviderMap[newVariable] = provider;
131 impl->m_VariableToProviderMap[newVariable] = provider;
122 impl->m_VariableToIdentifier[newVariable] = identifier;
132 impl->m_VariableToIdentifierMap[newVariable] = identifier;
123
133
124 auto addDateTimeAcquired = [ this, varW = std::weak_ptr<Variable>{newVariable} ](
134 auto addDateTimeAcquired = [ this, varW = std::weak_ptr<Variable>{newVariable} ](
125 QUuid identifier, auto dataSeriesAcquired, auto dateTimeToPutInCache)
135 QUuid identifier, auto dataSeriesAcquired, auto dateTimeToPutInCache)
126 {
136 {
127 if (auto variable = varW.lock()) {
137 if (auto variable = varW.lock()) {
128 auto varIdentifier = impl->m_VariableToIdentifier.at(variable);
138 auto varIdentifier = impl->m_VariableToIdentifierMap.at(variable);
129 if (varIdentifier == identifier) {
139 if (varIdentifier == identifier) {
130 impl->m_VariableCacheController->addDateTime(variable, dateTimeToPutInCache);
140 impl->m_VariableCacheController->addDateTime(variable, dateTimeToPutInCache);
131 variable->setDataSeries(dataSeriesAcquired);
141 variable->setDataSeries(dataSeriesAcquired);
142 emit variable->updated();
132 }
143 }
133 }
144 }
134 };
145 };
135
146
136 connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
147 connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
148 connect(provider.get(), &IDataProvider::dataProvidedProgress, this,
149 &VariableController::onVariableRetrieveDataInProgress);
137 this->onRequestDataLoading(newVariable, dateTime);
150 this->onRequestDataLoading(newVariable, dateTime);
138 }
151 }
139 }
152 }
@@ -148,6 +161,9 void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
148 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
161 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
149 selectedVariable->setDateTime(dateTime);
162 selectedVariable->setDateTime(dateTime);
150 this->onRequestDataLoading(selectedVariable, dateTime);
163 this->onRequestDataLoading(selectedVariable, dateTime);
164
165 // notify that rescale operation has to be done
166 emit rangeChanged(selectedVariable, dateTime);
151 }
167 }
152 }
168 }
153 }
169 }
@@ -156,13 +172,29 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, doub
156 {
172 {
157 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
173 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
158
174
159 auto end = impl->m_VariableToIdentifier.cend();
175 auto end = impl->m_VariableToIdentifierMap.cend();
160 auto it = std::find_if(impl->m_VariableToIdentifier.cbegin(), end, findReply);
176 auto it = std::find_if(impl->m_VariableToIdentifierMap.cbegin(), end, findReply);
161 if (it != end) {
177 if (it != end) {
162 impl->m_VariableModel->setDataProgress(it->first, progress);
178 impl->m_VariableModel->setDataProgress(it->first, progress);
163 }
179 }
164 }
180 }
165
181
182 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
183 {
184 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
185 << QThread::currentThread()->objectName();
186
187 auto it = impl->m_VariableToIdentifierMap.find(variable);
188 if (it != impl->m_VariableToIdentifierMap.cend()) {
189 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
190 }
191 else {
192 qCWarning(LOG_VariableController())
193 << tr("Aborting progression of inexistant variable detected !!!")
194 << QThread::currentThread()->objectName();
195 }
196 }
197
166
198
167 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
199 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
168 const SqpDateTime &dateTime)
200 const SqpDateTime &dateTime)
@@ -179,7 +211,7 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable
179
211
180 if (!dateTimeListNotInCache.empty()) {
212 if (!dateTimeListNotInCache.empty()) {
181 // Ask the provider for each data on the dateTimeListNotInCache
213 // Ask the provider for each data on the dateTimeListNotInCache
182 auto identifier = impl->m_VariableToIdentifier.at(variable);
214 auto identifier = impl->m_VariableToIdentifierMap.at(variable);
183 impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
215 impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
184 identifier,
216 identifier,
185 DataProviderParameters{std::move(dateTimeListNotInCache), variable->metadata()});
217 DataProviderParameters{std::move(dateTimeListNotInCache), variable->metadata()});
@@ -49,7 +49,6 struct VariableModel::VariableModelPrivate {
49 std::vector<std::shared_ptr<Variable> > m_Variables;
49 std::vector<std::shared_ptr<Variable> > m_Variables;
50 std::unordered_map<std::shared_ptr<Variable>, double> m_VariableToProgress;
50 std::unordered_map<std::shared_ptr<Variable>, double> m_VariableToProgress;
51
51
52
53 /// Return the row index of the variable. -1 if it's not found
52 /// Return the row index of the variable. -1 if it's not found
54 int indexOfVariable(Variable *variable) const noexcept;
53 int indexOfVariable(Variable *variable) const noexcept;
55 };
54 };
@@ -100,6 +99,9 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
100 << tr("Can't delete variable %1 from the model: the variable is not in the model")
99 << tr("Can't delete variable %1 from the model: the variable is not in the model")
101 .arg(variable->name());
100 .arg(variable->name());
102 }
101 }
102
103 // Removes variable from progress map
104 impl->m_VariableToProgress.erase(variable);
103 }
105 }
104
106
105
107
@@ -110,8 +112,12 std::shared_ptr<Variable> VariableModel::variable(int index) const
110
112
111 void VariableModel::setDataProgress(std::shared_ptr<Variable> variable, double progress)
113 void VariableModel::setDataProgress(std::shared_ptr<Variable> variable, double progress)
112 {
114 {
113
115 if (progress > 0.0) {
114 impl->m_VariableToProgress[variable] = progress;
116 impl->m_VariableToProgress[variable] = progress;
117 }
118 else {
119 impl->m_VariableToProgress.erase(variable);
120 }
115 auto modelIndex = createIndex(impl->indexOfVariable(variable.get()), NAME_COLUMN);
121 auto modelIndex = createIndex(impl->indexOfVariable(variable.get()), NAME_COLUMN);
116
122
117 emit dataChanged(modelIndex, modelIndex);
123 emit dataChanged(modelIndex, modelIndex);
@@ -204,6 +210,13 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int
204 return QVariant{};
210 return QVariant{};
205 }
211 }
206
212
213 void VariableModel::abortProgress(const QModelIndex &index)
214 {
215 if (auto variable = impl->m_Variables.at(index.row())) {
216 emit abortProgessRequested(variable);
217 }
218 }
219
207 void VariableModel::onVariableUpdated() noexcept
220 void VariableModel::onVariableUpdated() noexcept
208 {
221 {
209 // Finds variable that has been updated in the model
222 // Finds variable that has been updated in the model
@@ -16,6 +16,11 class QCPRange;
16 class SqpDateTime;
16 class SqpDateTime;
17 class Variable;
17 class Variable;
18
18
19 /**
20 * Possible types of zoom operation
21 */
22 enum class VisualizationGraphWidgetZoomType { ZoomOut, ZoomIn, PanRight, PanLeft, Unknown };
23
19 namespace Ui {
24 namespace Ui {
20 class VisualizationGraphWidget;
25 class VisualizationGraphWidget;
21 } // namespace Ui
26 } // namespace Ui
@@ -27,21 +32,28 public:
27 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
32 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
28 virtual ~VisualizationGraphWidget();
33 virtual ~VisualizationGraphWidget();
29
34
35 void enableSynchronize(bool enable);
36
30 void addVariable(std::shared_ptr<Variable> variable);
37 void addVariable(std::shared_ptr<Variable> variable);
31 void addVariableUsingGraph(std::shared_ptr<Variable> variable);
38 void addVariableUsingGraph(std::shared_ptr<Variable> variable);
32 /// Removes a variable from the graph
39 /// Removes a variable from the graph
33 void removeVariable(std::shared_ptr<Variable> variable) noexcept;
40 void removeVariable(std::shared_ptr<Variable> variable) noexcept;
34
41
42 void setRange(std::shared_ptr<Variable> variable, const SqpDateTime &range);
43 SqpDateTime graphRange() const noexcept;
44 void setGraphRange(const SqpDateTime &range);
45
35 // IVisualizationWidget interface
46 // IVisualizationWidget interface
36 void accept(IVisualizationWidgetVisitor *visitor) override;
47 void accept(IVisualizationWidgetVisitor *visitor) override;
37 bool canDrop(const Variable &variable) const override;
48 bool canDrop(const Variable &variable) const override;
38 bool contains(const Variable &variable) const override;
49 bool contains(const Variable &variable) const override;
39 QString name() const override;
50 QString name() const override;
40
51
41 void updateDisplay(std::shared_ptr<Variable> variable);
42
52
43 signals:
53 signals:
44 void requestDataLoading(std::shared_ptr<Variable> variable, const SqpDateTime &dateTime);
54 void requestDataLoading(std::shared_ptr<Variable> variable, const SqpDateTime &dateTime);
55 void synchronize(const SqpDateTime &dateTime, const SqpDateTime &oldDateTime,
56 VisualizationGraphWidgetZoomType zoomType);
45
57
46
58
47 private:
59 private:
@@ -54,10 +66,15 private slots:
54 /// Slot called when right clicking on the graph (displays a menu)
66 /// Slot called when right clicking on the graph (displays a menu)
55 void onGraphMenuRequested(const QPoint &pos) noexcept;
67 void onGraphMenuRequested(const QPoint &pos) noexcept;
56
68
57 void onRangeChanged(const QCPRange &t1);
69 /// Rescale the X axe to range parameter
70 void onRangeChanged(const QCPRange &t1, const QCPRange &t2);
58
71
59 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
72 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
60 void onMouseWheel(QWheelEvent *event) noexcept;
73 void onMouseWheel(QWheelEvent *event) noexcept;
74 /// Slot called when a mouse press was made, to activate the calibration of a graph
75 void onMousePress(QMouseEvent *event) noexcept;
76 /// Slot called when a mouse release was made, to deactivate the calibration of a graph
77 void onMouseRelease(QMouseEvent *event) noexcept;
61
78
62 void onDataCacheVariableUpdated();
79 void onDataCacheVariableUpdated();
63 };
80 };
@@ -2,6 +2,7
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
6
6 #include <QLoggingCategory>
7 #include <QLoggingCategory>
7 #include <QWidget>
8 #include <QWidget>
@@ -41,6 +42,8 public slots:
41 /// 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
42 void onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept;
43 void onVariableAboutToBeDeleted(std::shared_ptr<Variable> variable) noexcept;
43
44
45 void onRangeChanged(std::shared_ptr<Variable> variable, const SqpDateTime &range) noexcept;
46
44 private:
47 private:
45 Ui::VisualizationWidget *ui;
48 Ui::VisualizationWidget *ui;
46 };
49 };
@@ -38,11 +38,20 public:
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(),
42 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpDateTime &)),
43 m_VisualizationController.get(),
44 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const SqpDateTime &)));
45
41
46
42 m_DataSourceController->moveToThread(&m_DataSourceControllerThread);
47 m_DataSourceController->moveToThread(&m_DataSourceControllerThread);
48 m_DataSourceControllerThread.setObjectName("DataSourceControllerThread");
43 m_NetworkController->moveToThread(&m_NetworkControllerThread);
49 m_NetworkController->moveToThread(&m_NetworkControllerThread);
50 m_NetworkControllerThread.setObjectName("NetworkControllerThread");
44 m_VariableController->moveToThread(&m_VariableControllerThread);
51 m_VariableController->moveToThread(&m_VariableControllerThread);
52 m_VariableControllerThread.setObjectName("VariableControllerThread");
45 m_VisualizationController->moveToThread(&m_VisualizationControllerThread);
53 m_VisualizationController->moveToThread(&m_VisualizationControllerThread);
54 m_VisualizationControllerThread.setObjectName("VsualizationControllerThread");
46
55
47
56
48 // Additionnal init
57 // Additionnal init
@@ -106,11 +115,6 SqpApplication::SqpApplication(int &argc, char **argv)
106 impl->m_NetworkControllerThread.start();
115 impl->m_NetworkControllerThread.start();
107 impl->m_VariableControllerThread.start();
116 impl->m_VariableControllerThread.start();
108 impl->m_VisualizationControllerThread.start();
117 impl->m_VisualizationControllerThread.start();
109
110 // Core connections:
111 // NetworkController <-> VariableController
112 connect(&sqpApp->networkController(), &NetworkController::replyDownloadProgress,
113 &sqpApp->variableController(), &VariableController::onVariableRetrieveDataInProgress);
114 }
118 }
115
119
116 SqpApplication::~SqpApplication()
120 SqpApplication::~SqpApplication()
@@ -5,6 +5,7
5
5
6 #include <ui_VariableInspectorWidget.h>
6 #include <ui_VariableInspectorWidget.h>
7
7
8 #include <QMouseEvent>
8 #include <QSortFilterProxyModel>
9 #include <QSortFilterProxyModel>
9 #include <QStyledItemDelegate>
10 #include <QStyledItemDelegate>
10 #include <QWidgetAction>
11 #include <QWidgetAction>
@@ -27,9 +28,12 public:
27 if (data.isValid() && progressData.isValid()) {
28 if (data.isValid() && progressData.isValid()) {
28 auto name = data.value<QString>();
29 auto name = data.value<QString>();
29 auto progress = progressData.value<double>();
30 auto progress = progressData.value<double>();
30 if (progress >= 0) {
31 if (progress > 0) {
32 auto cancelButtonWidth = 20;
31 auto progressBarOption = QStyleOptionProgressBar{};
33 auto progressBarOption = QStyleOptionProgressBar{};
32 progressBarOption.rect = option.rect;
34 auto progressRect = option.rect;
35 progressRect.setWidth(progressRect.width() - cancelButtonWidth);
36 progressBarOption.rect = progressRect;
33 progressBarOption.minimum = 0;
37 progressBarOption.minimum = 0;
34 progressBarOption.maximum = 100;
38 progressBarOption.maximum = 100;
35 progressBarOption.progress = progress;
39 progressBarOption.progress = progress;
@@ -38,14 +42,69 public:
38 progressBarOption.textVisible = true;
42 progressBarOption.textVisible = true;
39 progressBarOption.textAlignment = Qt::AlignCenter;
43 progressBarOption.textAlignment = Qt::AlignCenter;
40
44
45
41 QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption,
46 QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption,
42 painter);
47 painter);
48
49 // Cancel button
50 auto buttonRect = QRect(progressRect.right(), option.rect.top(), cancelButtonWidth,
51 option.rect.height());
52 auto buttonOption = QStyleOptionButton{};
53 buttonOption.rect = buttonRect;
54 buttonOption.text = "X";
55
56 QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter);
57 }
58 else {
59 QStyledItemDelegate::paint(painter, option, index);
43 }
60 }
44 }
61 }
45 else {
62 else {
46 QStyledItemDelegate::paint(painter, option, index);
63 QStyledItemDelegate::paint(painter, option, index);
47 }
64 }
48 }
65 }
66
67 bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
68 const QModelIndex &index)
69 {
70 if (event->type() == QEvent::MouseButtonRelease) {
71 auto data = index.data(Qt::DisplayRole);
72 auto progressData = index.data(VariableRoles::ProgressRole);
73 if (data.isValid() && progressData.isValid()) {
74 auto cancelButtonWidth = 20;
75 auto progressRect = option.rect;
76 progressRect.setWidth(progressRect.width() - cancelButtonWidth);
77 // Cancel button
78 auto buttonRect = QRect(progressRect.right(), option.rect.top(), cancelButtonWidth,
79 option.rect.height());
80
81 auto e = (QMouseEvent *)event;
82 auto clickX = e->x();
83 auto clickY = e->y();
84
85 auto x = buttonRect.left(); // the X coordinate
86 auto y = buttonRect.top(); // the Y coordinate
87 auto w = buttonRect.width(); // button width
88 auto h = buttonRect.height(); // button height
89
90 if (clickX > x && clickX < x + w) {
91 if (clickY > y && clickY < y + h) {
92 auto variableModel = sqpApp->variableController().variableModel();
93 variableModel->abortProgress(index);
94 }
95 }
96 else {
97 QStyledItemDelegate::editorEvent(event, model, option, index);
98 }
99 }
100 else {
101 QStyledItemDelegate::editorEvent(event, model, option, index);
102 }
103 }
104 else {
105 QStyledItemDelegate::editorEvent(event, model, option, index);
106 }
107 }
49 };
108 };
50
109
51 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent)
110 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent)
@@ -69,7 +69,6 void updateScalarData(QCPAbstractPlottable *component, ScalarSeries &scalarSerie
69
69
70
70
71 // Display all data
71 // Display all data
72 component->rescaleAxes();
73 component->parentPlot()->replot();
72 component->parentPlot()->replot();
74 }
73 }
75 else {
74 else {
@@ -25,8 +25,17 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
25
25
26 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
26 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
27
27
28 explicit VisualizationGraphWidgetPrivate() : m_DoSynchronize{true}, m_IsCalibration{false} {}
29
30
31 // Return the operation when range changed
32 VisualizationGraphWidgetZoomType getZoomType(const QCPRange &t1, const QCPRange &t2);
33
28 // 1 variable -> n qcpplot
34 // 1 variable -> n qcpplot
29 std::multimap<std::shared_ptr<Variable>, QCPAbstractPlottable *> m_VariableToPlotMultiMap;
35 std::multimap<std::shared_ptr<Variable>, QCPAbstractPlottable *> m_VariableToPlotMultiMap;
36
37 bool m_DoSynchronize;
38 bool m_IsCalibration;
30 };
39 };
31
40
32 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
41 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
@@ -48,10 +57,13 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget
48 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
57 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
49 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
58 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
50 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
59 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
60 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
61 connect(ui->widget, &QCustomPlot::mouseRelease, this,
62 &VisualizationGraphWidget::onMouseRelease);
51 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
63 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
52 connect(ui->widget->xAxis,
64 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
53 static_cast<void (QCPAxis::*)(const QCPRange &)>(&QCPAxis::rangeChanged), this,
65 &QCPAxis::rangeChanged),
54 &VisualizationGraphWidget::onRangeChanged);
66 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
55
67
56 // Activates menu when right clicking on the graph
68 // Activates menu when right clicking on the graph
57 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
69 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
@@ -68,6 +80,11 VisualizationGraphWidget::~VisualizationGraphWidget()
68 delete ui;
80 delete ui;
69 }
81 }
70
82
83 void VisualizationGraphWidget::enableSynchronize(bool enable)
84 {
85 impl->m_DoSynchronize = enable;
86 }
87
71 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable)
88 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable)
72 {
89 {
73 // Uses delegate to create the qcpplot components according to the variable
90 // Uses delegate to create the qcpplot components according to the variable
@@ -89,8 +106,8 void VisualizationGraphWidget::addVariableUsingGraph(std::shared_ptr<Variable> v
89
106
90 auto variableDateTimeWithTolerance = dateTime;
107 auto variableDateTimeWithTolerance = dateTime;
91
108
92 // add 10% tolerance for each side
109 // add 20% tolerance for each side
93 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
110 auto tolerance = 0.2 * (dateTime.m_TEnd - dateTime.m_TStart);
94 variableDateTimeWithTolerance.m_TStart -= tolerance;
111 variableDateTimeWithTolerance.m_TStart -= tolerance;
95 variableDateTimeWithTolerance.m_TEnd += tolerance;
112 variableDateTimeWithTolerance.m_TEnd += tolerance;
96
113
@@ -122,6 +139,32 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable
122 ui->widget->replot();
139 ui->widget->replot();
123 }
140 }
124
141
142 void VisualizationGraphWidget::setRange(std::shared_ptr<Variable> variable,
143 const SqpDateTime &range)
144 {
145 // Note: in case of different axes that depends on variable, we could start with a code like
146 // that:
147 // auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
148 // for (auto it = componentsIt.first; it != componentsIt.second;) {
149 // }
150 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
151 ui->widget->replot();
152 }
153
154 SqpDateTime VisualizationGraphWidget::graphRange() const noexcept
155 {
156 auto grapheRange = ui->widget->xAxis->range();
157 return SqpDateTime{grapheRange.lower, grapheRange.upper};
158 }
159
160 void VisualizationGraphWidget::setGraphRange(const SqpDateTime &range)
161 {
162 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
163 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
164 ui->widget->replot();
165 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
166 }
167
125 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
168 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
126 {
169 {
127 if (visitor) {
170 if (visitor) {
@@ -175,62 +218,104 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
175 }
218 }
176 }
219 }
177
220
178 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1)
221 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
179 {
222 {
180 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::onRangeChanged")
223 qCInfo(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::onRangeChanged")
181 << QThread::currentThread()->objectName();
224 << QThread::currentThread()->objectName();
225
226 auto dateTimeRange = SqpDateTime{t1.lower, t1.upper};
182
227
228 auto zoomType = impl->getZoomType(t1, t2);
183 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
229 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
184 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
230 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
185
231
186 auto variable = it->first;
232 auto variable = it->first;
187 auto dateTime = SqpDateTime{t1.lower, t1.upper};
233 auto currentDateTime = dateTimeRange;
188
234
189 if (!variable->contains(dateTime)) {
235 auto toleranceFactor = 0.2;
190
236 auto tolerance = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
191 auto variableDateTimeWithTolerance = dateTime;
237 auto variableDateTimeWithTolerance = currentDateTime;
192 if (!variable->isInside(dateTime)) {
238 variableDateTimeWithTolerance.m_TStart -= tolerance;
239 variableDateTimeWithTolerance.m_TEnd += tolerance;
240
241 qCDebug(LOG_VisualizationGraphWidget()) << "r" << currentDateTime;
242 qCDebug(LOG_VisualizationGraphWidget()) << "t" << variableDateTimeWithTolerance;
243 qCDebug(LOG_VisualizationGraphWidget()) << "v" << variable->dateTime();
244 // If new range with tol is upper than variable datetime parameters. we need to request new
245 // data
246 if (!variable->contains(variableDateTimeWithTolerance)) {
247
248 auto variableDateTimeWithTolerance = currentDateTime;
249 if (!variable->isInside(currentDateTime)) {
193 auto variableDateTime = variable->dateTime();
250 auto variableDateTime = variable->dateTime();
194 if (variableDateTime.m_TStart < dateTime.m_TStart) {
251 if (variable->contains(variableDateTimeWithTolerance)) {
195 qCDebug(LOG_VisualizationGraphWidget()) << tr("TDetection pan to right:");
252 qCDebug(LOG_VisualizationGraphWidget())
253 << tr("TORM: Detection zoom in that need request:");
254 // add 10% tolerance for each side
255 tolerance
256 = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
257 variableDateTimeWithTolerance.m_TStart -= tolerance;
258 variableDateTimeWithTolerance.m_TEnd += tolerance;
259 }
260 else if (variableDateTime.m_TStart < currentDateTime.m_TStart) {
261 qCInfo(LOG_VisualizationGraphWidget()) << tr("TORM: Detection pan to right:");
196
262
197 auto diffEndToKeepDelta = dateTime.m_TEnd - variableDateTime.m_TEnd;
263 auto diffEndToKeepDelta = currentDateTime.m_TEnd - variableDateTime.m_TEnd;
198 dateTime.m_TStart = variableDateTime.m_TStart + diffEndToKeepDelta;
264 currentDateTime.m_TStart = variableDateTime.m_TStart + diffEndToKeepDelta;
199 // Tolerance have to be added to the right
265 // Tolerance have to be added to the right
200 // add 10% tolerance for right (end) side
266 // add tolerance for right (end) side
201 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
267 tolerance
268 = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
202 variableDateTimeWithTolerance.m_TEnd += tolerance;
269 variableDateTimeWithTolerance.m_TEnd += tolerance;
203 }
270 }
204 else if (variableDateTime.m_TEnd > dateTime.m_TEnd) {
271 else if (variableDateTime.m_TEnd > currentDateTime.m_TEnd) {
205 qCDebug(LOG_VisualizationGraphWidget()) << tr("Detection pan to left: ");
272 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: Detection pan to left: ");
206 auto diffStartToKeepDelta = variableDateTime.m_TStart - dateTime.m_TStart;
273 auto diffStartToKeepDelta
207 dateTime.m_TEnd = variableDateTime.m_TEnd - diffStartToKeepDelta;
274 = variableDateTime.m_TStart - currentDateTime.m_TStart;
275 currentDateTime.m_TEnd = variableDateTime.m_TEnd - diffStartToKeepDelta;
208 // Tolerance have to be added to the left
276 // Tolerance have to be added to the left
209 // add 10% tolerance for left (start) side
277 // add tolerance for left (start) side
210 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
278 tolerance
279 = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
211 variableDateTimeWithTolerance.m_TStart -= tolerance;
280 variableDateTimeWithTolerance.m_TStart -= tolerance;
212 }
281 }
213 else {
282 else {
214 qCWarning(LOG_VisualizationGraphWidget())
283 qCCritical(LOG_VisualizationGraphWidget())
215 << tr("Detection anormal zoom detection: ");
284 << tr("Detection anormal zoom detection: ");
216 }
285 }
217 }
286 }
218 else {
287 else {
219 qCDebug(LOG_VisualizationGraphWidget()) << tr("Detection zoom out: ");
288 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: Detection zoom out: ");
220 // add 10% tolerance for each side
289 // add 10% tolerance for each side
221 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
290 tolerance = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
222 variableDateTimeWithTolerance.m_TStart -= tolerance;
291 variableDateTimeWithTolerance.m_TStart -= tolerance;
223 variableDateTimeWithTolerance.m_TEnd += tolerance;
292 variableDateTimeWithTolerance.m_TEnd += tolerance;
293 zoomType = VisualizationGraphWidgetZoomType::ZoomOut;
294 }
295 if (!variable->contains(dateTimeRange)) {
296 qCDebug(LOG_VisualizationGraphWidget())
297 << "TORM: Modif on variable datetime detected" << currentDateTime;
298 variable->setDateTime(currentDateTime);
224 }
299 }
225 variable->setDateTime(dateTime);
226
300
301 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: Request data detection: ");
227 // CHangement detected, we need to ask controller to request data loading
302 // CHangement detected, we need to ask controller to request data loading
228 emit requestDataLoading(variable, variableDateTimeWithTolerance);
303 emit requestDataLoading(variable, variableDateTimeWithTolerance);
229 }
304 }
230 else {
305 else {
231 qCDebug(LOG_VisualizationGraphWidget()) << tr("Detection zoom in: ");
306 qCInfo(LOG_VisualizationGraphWidget())
307 << tr("TORM: Detection zoom in that doesn't need request: ");
308 zoomType = VisualizationGraphWidgetZoomType::ZoomIn;
232 }
309 }
233 }
310 }
311
312 if (impl->m_DoSynchronize && !impl->m_IsCalibration) {
313 auto oldDateTime = SqpDateTime{t2.lower, t2.upper};
314 qCDebug(LOG_VisualizationGraphWidget())
315 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
316 << QThread::currentThread()->objectName();
317 emit synchronize(dateTimeRange, oldDateTime, zoomType);
318 }
234 }
319 }
235
320
236 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
321 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
@@ -251,6 +336,16 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
251 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
336 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
252 }
337 }
253
338
339 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
340 {
341 impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
342 }
343
344 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
345 {
346 impl->m_IsCalibration = false;
347 }
348
254 void VisualizationGraphWidget::onDataCacheVariableUpdated()
349 void VisualizationGraphWidget::onDataCacheVariableUpdated()
255 {
350 {
256 // NOTE:
351 // NOTE:
@@ -262,24 +357,45 void VisualizationGraphWidget::onDataCacheVariableUpdated()
262 // - use an ordered_multimap and the algos of std to group the values by key
357 // - use an ordered_multimap and the algos of std to group the values by key
263 // - use a map (unique keys) and store as values directly the list of components
358 // - use a map (unique keys) and store as values directly the list of components
264
359
360 auto grapheRange = ui->widget->xAxis->range();
361 auto dateTime = SqpDateTime{grapheRange.lower, grapheRange.upper};
362
265 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
363 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
266 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
364 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
267 auto variable = it->first;
365 auto variable = it->first;
268 VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
366 qCDebug(LOG_VisualizationGraphWidget())
269 variable->dataSeries(), variable->dateTime());
367 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S"
368 << variable->dateTime();
369 qCDebug(LOG_VisualizationGraphWidget())
370 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
371 if (dateTime.contains(variable->dateTime()) || dateTime.intersect(variable->dateTime())) {
372
373 VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
374 variable->dataSeries(), variable->dateTime());
375 }
270 }
376 }
271 }
377 }
272
378
273 void VisualizationGraphWidget::updateDisplay(std::shared_ptr<Variable> variable)
379 VisualizationGraphWidgetZoomType
380 VisualizationGraphWidget::VisualizationGraphWidgetPrivate::getZoomType(const QCPRange &t1,
381 const QCPRange &t2)
274 {
382 {
275 auto abstractPlotableItPair = impl->m_VariableToPlotMultiMap.equal_range(variable);
383 // t1.lower <= t2.lower && t2.upper <= t1.upper
276
384 auto zoomType = VisualizationGraphWidgetZoomType::Unknown;
277 auto abstractPlotableVect = QVector<QCPAbstractPlottable *>{};
385 if (t1.lower <= t2.lower && t2.upper <= t1.upper) {
278
386 zoomType = VisualizationGraphWidgetZoomType::ZoomOut;
279 for (auto it = abstractPlotableItPair.first; it != abstractPlotableItPair.second; ++it) {
280 abstractPlotableVect.push_back(it->second);
281 }
387 }
282
388 else if (t1.lower > t2.lower && t1.upper > t2.upper) {
283 VisualizationGraphHelper::updateData(abstractPlotableVect, variable->dataSeries(),
389 zoomType = VisualizationGraphWidgetZoomType::PanRight;
284 variable->dateTime());
390 }
391 else if (t1.lower < t2.lower && t1.upper < t2.upper) {
392 zoomType = VisualizationGraphWidgetZoomType::PanLeft;
393 }
394 else if (t1.lower > t2.lower && t2.upper > t1.upper) {
395 zoomType = VisualizationGraphWidgetZoomType::ZoomIn;
396 }
397 else {
398 qCCritical(LOG_VisualizationGraphWidget()) << "getZoomType: Unknown type detected";
399 }
400 return zoomType;
285 }
401 }
@@ -5,6 +5,7
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/qcustomplot.h"
9 #include "Visualization/qcustomplot.h"
9
10
10 #include "ui_VisualizationWidget.h"
11 #include "ui_VisualizationWidget.h"
@@ -141,3 +142,11 void VisualizationWidget::onVariableAboutToBeDeleted(std::shared_ptr<Variable> v
141 auto removeVariableOperation = RemoveVariableOperation{variable};
142 auto removeVariableOperation = RemoveVariableOperation{variable};
142 accept(&removeVariableOperation);
143 accept(&removeVariableOperation);
143 }
144 }
145
146 void VisualizationWidget::onRangeChanged(std::shared_ptr<Variable> variable,
147 const SqpDateTime &range) noexcept
148 {
149 // Calls the operation of rescaling all graph that contrains variable in the visualization
150 auto rescaleVariableOperation = RescaleAxeOperation{variable, range};
151 accept(&rescaleVariableOperation);
152 }
@@ -1,8 +1,11
1 #include "Visualization/VisualizationZoneWidget.h"
1 #include "Visualization/VisualizationZoneWidget.h"
2
3 #include "Data/SqpDateTime.h"
4
2 #include "Visualization/IVisualizationWidgetVisitor.h"
5 #include "Visualization/IVisualizationWidgetVisitor.h"
6 #include "Visualization/VisualizationGraphWidget.h"
3 #include "ui_VisualizationZoneWidget.h"
7 #include "ui_VisualizationZoneWidget.h"
4
8
5 #include "Visualization/VisualizationGraphWidget.h"
6
9
7 #include <SqpApplication.h>
10 #include <SqpApplication.h>
8
11
@@ -57,6 +60,7 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<V
57 auto graphWidget = new VisualizationGraphWidget{
60 auto graphWidget = new VisualizationGraphWidget{
58 defaultGraphName(*ui->visualizationZoneFrame->layout()), this};
61 defaultGraphName(*ui->visualizationZoneFrame->layout()), this};
59
62
63
60 // Set graph properties
64 // Set graph properties
61 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
65 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
62 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
66 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
@@ -65,6 +69,91 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<V
65
69
66 graphWidget->addVariable(variable);
70 graphWidget->addVariable(variable);
67
71
72 // Lambda to synchronize zone widget
73 auto synchronizeZoneWidget = [this, graphWidget](const SqpDateTime &dateTime,
74 const SqpDateTime &oldDateTime,
75 VisualizationGraphWidgetZoomType zoomType) {
76 auto frameLayout = ui->visualizationZoneFrame->layout();
77 for (auto i = 0; i < frameLayout->count(); ++i) {
78 auto graphChild
79 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
80 if (graphChild && (graphChild != graphWidget)) {
81
82 auto graphChildRange = graphChild->graphRange();
83 switch (zoomType) {
84 case VisualizationGraphWidgetZoomType::ZoomIn: {
85 auto deltaLeft = dateTime.m_TStart - oldDateTime.m_TStart;
86 auto deltaRight = oldDateTime.m_TEnd - dateTime.m_TEnd;
87 graphChildRange.m_TStart += deltaLeft;
88 graphChildRange.m_TEnd -= deltaRight;
89 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
90 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
91 << deltaLeft;
92 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
93 << deltaRight;
94 qCCritical(LOG_VisualizationZoneWidget())
95 << tr("TORM: dt") << dateTime.m_TEnd - dateTime.m_TStart;
96
97 break;
98 }
99
100 case VisualizationGraphWidgetZoomType::ZoomOut: {
101 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
102 auto deltaLeft = oldDateTime.m_TStart - dateTime.m_TStart;
103 auto deltaRight = dateTime.m_TEnd - oldDateTime.m_TEnd;
104 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
105 << deltaLeft;
106 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
107 << deltaRight;
108 qCCritical(LOG_VisualizationZoneWidget())
109 << tr("TORM: dt") << dateTime.m_TEnd - dateTime.m_TStart;
110 graphChildRange.m_TStart -= deltaLeft;
111 graphChildRange.m_TEnd += deltaRight;
112 break;
113 }
114 case VisualizationGraphWidgetZoomType::PanRight: {
115 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
116 auto deltaRight = dateTime.m_TEnd - oldDateTime.m_TEnd;
117 graphChildRange.m_TStart += deltaRight;
118 graphChildRange.m_TEnd += deltaRight;
119 qCCritical(LOG_VisualizationZoneWidget())
120 << tr("TORM: dt") << dateTime.m_TEnd - dateTime.m_TStart;
121 break;
122 }
123 case VisualizationGraphWidgetZoomType::PanLeft: {
124 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
125 auto deltaLeft = oldDateTime.m_TStart - dateTime.m_TStart;
126 graphChildRange.m_TStart -= deltaLeft;
127 graphChildRange.m_TEnd -= deltaLeft;
128 break;
129 }
130 case VisualizationGraphWidgetZoomType::Unknown: {
131 qCCritical(LOG_VisualizationZoneWidget())
132 << tr("Impossible to synchronize: zoom type unknown");
133 break;
134 }
135 default:
136 qCCritical(LOG_VisualizationZoneWidget())
137 << tr("Impossible to synchronize: zoom type not take into account");
138 // No action
139 break;
140 }
141 graphChild->enableSynchronize(false);
142 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
143 << graphChild->graphRange();
144 qCCritical(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
145 << graphChildRange;
146 qCCritical(LOG_VisualizationZoneWidget())
147 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
148 graphChild->setGraphRange(graphChildRange);
149 graphChild->enableSynchronize(true);
150 }
151 }
152 };
153
154 // connection for synchronization
155 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
156
68 return graphWidget;
157 return graphWidget;
69 }
158 }
70
159
@@ -21,6 +21,8 public:
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;
25
24 private:
26 private:
25 void retrieveData(QUuid token, const SqpDateTime &dateTime, const QVariantHash &data);
27 void retrieveData(QUuid token, const SqpDateTime &dateTime, const QVariantHash &data);
26 };
28 };
@@ -26,7 +26,7 const auto AMDA_URL_FORMAT = QStringLiteral(
26 "timeFormat=ISO8601&gzip=0");
26 "timeFormat=ISO8601&gzip=0");
27
27
28 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
28 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
29 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:ss");
29 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
30
30
31 /// Formats a time to a date that can be passed in URL
31 /// Formats a time to a date that can be passed in URL
32 QString dateFormat(double sqpDateTime) noexcept
32 QString dateFormat(double sqpDateTime) noexcept
@@ -48,6 +48,10 AmdaProvider::AmdaProvider()
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
52
53 connect(&sqpApp->networkController(), SIGNAL(replyDownloadProgress(QUuid, double)), this,
54 SIGNAL(dataProvidedProgress(QUuid, double)));
51 }
55 }
52 }
56 }
53
57
@@ -61,6 +65,14 void AmdaProvider::requestDataLoading(QUuid token, const DataProviderParameters
61 }
65 }
62 }
66 }
63
67
68 void AmdaProvider::requestDataAborting(QUuid identifier)
69 {
70 if (auto app = sqpApp) {
71 auto &networkController = app->networkController();
72 networkController.onReplyCanceled(identifier);
73 }
74 }
75
64 void AmdaProvider::retrieveData(QUuid token, const SqpDateTime &dateTime, const QVariantHash &data)
76 void AmdaProvider::retrieveData(QUuid token, const SqpDateTime &dateTime, const QVariantHash &data)
65 {
77 {
66 // 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
@@ -69,6 +81,7 void AmdaProvider::retrieveData(QUuid token, const SqpDateTime &dateTime, const
69 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
81 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
70 return;
82 return;
71 }
83 }
84 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData") << dateTime;
72
85
73 // /////////// //
86 // /////////// //
74 // Creates URL //
87 // Creates URL //
@@ -78,7 +91,7 void AmdaProvider::retrieveData(QUuid token, const SqpDateTime &dateTime, const
78 auto endDate = dateFormat(dateTime.m_TEnd);
91 auto endDate = dateFormat(dateTime.m_TEnd);
79
92
80 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
93 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
81
94 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData url:") << url;
82 auto tempFile = std::make_shared<QTemporaryFile>();
95 auto tempFile = std::make_shared<QTemporaryFile>();
83
96
84 // LAMBDA
97 // LAMBDA
@@ -86,41 +99,47 void AmdaProvider::retrieveData(QUuid token, const SqpDateTime &dateTime, const
86 = [this, dateTime, tempFile, token](QNetworkReply *reply, QUuid dataId) noexcept {
99 = [this, dateTime, tempFile, token](QNetworkReply *reply, QUuid dataId) noexcept {
87 Q_UNUSED(dataId);
100 Q_UNUSED(dataId);
88
101
89 if (tempFile) {
102 // Don't do anything if the reply was abort
90 auto replyReadAll = reply->readAll();
103 if (reply->error() != QNetworkReply::OperationCanceledError) {
91 if (!replyReadAll.isEmpty()) {
104
92 tempFile->write(replyReadAll);
105 if (tempFile) {
93 }
106 auto replyReadAll = reply->readAll();
94 tempFile->close();
107 if (!replyReadAll.isEmpty()) {
95
108 tempFile->write(replyReadAll);
96 // Parse results file
109 }
97 if (auto dataSeries = AmdaResultParser::readTxt(tempFile->fileName())) {
110 tempFile->close();
98 emit dataProvided(token, dataSeries, dateTime);
111
99 }
112 // Parse results file
100 else {
113 if (auto dataSeries = AmdaResultParser::readTxt(tempFile->fileName())) {
101 /// @todo ALX : debug
114 emit dataProvided(token, dataSeries, dateTime);
115 }
116 else {
117 /// @todo ALX : debug
118 }
102 }
119 }
103 }
120 }
104
121
105 // Deletes reply
106 reply->deleteLater();
107 reply = nullptr;
108 };
122 };
109 auto httpFinishedLambda = [this, httpDownloadFinished, tempFile](QNetworkReply *reply,
123 auto httpFinishedLambda
110 QUuid dataId) noexcept {
124 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
111
125
112 auto downloadFileUrl = QUrl{QString{reply->readAll()}};
126 // Don't do anything if the reply was abort
113 // Deletes old reply
127 if (reply->error() != QNetworkReply::OperationCanceledError) {
114 reply->deleteLater();
128 auto downloadFileUrl = QUrl{QString{reply->readAll()}};
115
129
116 // Executes request for downloading file //
117
130
118 // Creates destination file
131 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData downloadFileUrl:")
119 if (tempFile->open()) {
132 << downloadFileUrl;
120 // Executes request
133 // Executes request for downloading file //
121 emit requestConstructed(QNetworkRequest{downloadFileUrl}, dataId, httpDownloadFinished);
134
122 }
135 // Creates destination file
123 };
136 if (tempFile->open()) {
137 // Executes request
138 emit requestConstructed(QNetworkRequest{downloadFileUrl}, dataId,
139 httpDownloadFinished);
140 }
141 }
142 };
124
143
125 // //////////////// //
144 // //////////////// //
126 // Executes request //
145 // Executes request //
@@ -12,6 +12,9 Q_LOGGING_CATEGORY(LOG_AmdaResultParser, "AmdaResultParser")
12
12
13 namespace {
13 namespace {
14
14
15 /// Message in result file when the file was not found on server
16 const auto FILE_NOT_FOUND_MESSAGE = QStringLiteral("Not Found");
17
15 /// Format for dates in result files
18 /// Format for dates in result files
16 const auto DATE_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss.zzz");
19 const auto DATE_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss.zzz");
17
20
@@ -119,8 +122,16 std::shared_ptr<IDataSeries> AmdaResultParser::readTxt(const QString &filePath)
119
122
120 QTextStream stream{&file};
123 QTextStream stream{&file};
121
124
122 // Ignore first two lines (comments lines)
125 // Checks if the file was found on the server
123 stream.readLine();
126 auto firstLine = stream.readLine();
127 if (firstLine.compare(FILE_NOT_FOUND_MESSAGE) == 0) {
128 qCCritical(LOG_AmdaResultParser())
129 << QObject::tr("Can't retrieve AMDA data from file %1: file was not found on server")
130 .arg(filePath);
131 return nullptr;
132 }
133
134 // Ignore comments lines
124 stream.readLine();
135 stream.readLine();
125
136
126 // Reads x-axis unit
137 // Reads x-axis unit
@@ -155,9 +155,12 void TestAmdaResultParser::testReadTxt_data()
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 file
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
162 QTest::newRow("Invalid file (file not found on server)") << QStringLiteral("FileNotFound.txt")
163 << ExpectedResults{};
161 }
164 }
162
165
163 void TestAmdaResultParser::testReadTxt()
166 void TestAmdaResultParser::testReadTxt()
@@ -6,7 +6,9
6 #include <Data/IDataProvider.h>
6 #include <Data/IDataProvider.h>
7
7
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9 #include <QUuid>
9
10
11 #include <QHash>
10 Q_DECLARE_LOGGING_CATEGORY(LOG_CosinusProvider)
12 Q_DECLARE_LOGGING_CATEGORY(LOG_CosinusProvider)
11
13
12 /**
14 /**
@@ -14,12 +16,18 Q_DECLARE_LOGGING_CATEGORY(LOG_CosinusProvider)
14 */
16 */
15 class SCIQLOP_MOCKPLUGIN_EXPORT CosinusProvider : public IDataProvider {
17 class SCIQLOP_MOCKPLUGIN_EXPORT CosinusProvider : public IDataProvider {
16 public:
18 public:
19 /// @sa IDataProvider::requestDataLoading(). The current impl isn't thread safe.
17 void requestDataLoading(QUuid token, const DataProviderParameters &parameters) override;
20 void requestDataLoading(QUuid token, const DataProviderParameters &parameters) override;
18
21
19
22
23 /// @sa IDataProvider::requestDataAborting(). The current impl isn't thread safe.
24 void requestDataAborting(QUuid identifier) override;
25
26
20 private:
27 private:
21 /// @sa IDataProvider::retrieveData()
28 std::shared_ptr<IDataSeries> retrieveData(QUuid token, const SqpDateTime &dateTime);
22 std::shared_ptr<IDataSeries> retrieveData(const SqpDateTime &dateTime) const;
29
30 QHash<QUuid, bool> m_VariableToEnableProvider;
23 };
31 };
24
32
25 #endif // SCIQLOP_COSINUSPROVIDER_H
33 #endif // SCIQLOP_COSINUSPROVIDER_H
@@ -6,12 +6,15
6 #include <cmath>
6 #include <cmath>
7
7
8 #include <QDateTime>
8 #include <QDateTime>
9 #include <QFuture>
9 #include <QThread>
10 #include <QThread>
11 #include <QtConcurrent/QtConcurrent>
10
12
11 Q_LOGGING_CATEGORY(LOG_CosinusProvider, "CosinusProvider")
13 Q_LOGGING_CATEGORY(LOG_CosinusProvider, "CosinusProvider")
12
14
13 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(const SqpDateTime &dateTime) const
15 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(QUuid token, const SqpDateTime &dateTime)
14 {
16 {
17 // TODO: Add Mutex
15 auto dataIndex = 0;
18 auto dataIndex = 0;
16
19
17 // Gets the timerange from the parameters
20 // Gets the timerange from the parameters
@@ -28,21 +31,65 std::shared_ptr<IDataSeries> CosinusProvider::retrieveData(const SqpDateTime &da
28 auto scalarSeries
31 auto scalarSeries
29 = std::make_shared<ScalarSeries>(end - start, Unit{QStringLiteral("t"), true}, Unit{});
32 = std::make_shared<ScalarSeries>(end - start, Unit{QStringLiteral("t"), true}, Unit{});
30
33
34
35 int progress = 0;
36 auto progressEnd = end - start;
31 for (auto time = start; time < end; ++time, ++dataIndex) {
37 for (auto time = start; time < end; ++time, ++dataIndex) {
32 const auto timeOnFreq = time / freq;
38 auto it = m_VariableToEnableProvider.find(token);
33 scalarSeries->setData(dataIndex, timeOnFreq, std::cos(timeOnFreq));
39 if (it != m_VariableToEnableProvider.end() && it.value()) {
40 const auto timeOnFreq = time / freq;
41 scalarSeries->setData(dataIndex, timeOnFreq, std::cos(timeOnFreq));
42
43 // progression
44 int currentProgress = (time - start) * 100.0 / progressEnd;
45 if (currentProgress != progress) {
46 progress = currentProgress;
47
48 emit dataProvidedProgress(token, progress);
49 }
50 }
51 else {
52 if (!it.value()) {
53 qCDebug(LOG_CosinusProvider())
54 << "CosinusProvider::retrieveData: ARRET De l'acquisition detectΓ©"
55 << end - time;
56 }
57 }
34 }
58 }
59 emit dataProvidedProgress(token, 0.0);
60
61
35 return scalarSeries;
62 return scalarSeries;
36 }
63 }
37
64
38 void CosinusProvider::requestDataLoading(QUuid token, const DataProviderParameters &parameters)
65 void CosinusProvider::requestDataLoading(QUuid token, const DataProviderParameters &parameters)
39 {
66 {
67 // TODO: Add Mutex
68 m_VariableToEnableProvider[token] = true;
40 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataLoading"
69 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataLoading"
41 << QThread::currentThread()->objectName();
70 << QThread::currentThread()->objectName();
42 // NOTE: Try to use multithread if possible
71 // NOTE: Try to use multithread if possible
43 const auto times = parameters.m_Times;
72 const auto times = parameters.m_Times;
73
44 for (const auto &dateTime : qAsConst(times)) {
74 for (const auto &dateTime : qAsConst(times)) {
45 auto scalarSeries = this->retrieveData(dateTime);
75 if (m_VariableToEnableProvider[token]) {
46 emit dataProvided(token, scalarSeries, dateTime);
76 auto scalarSeries = this->retrieveData(token, dateTime);
77 emit dataProvided(token, scalarSeries, dateTime);
78 }
79 }
80 }
81
82 void CosinusProvider::requestDataAborting(QUuid identifier)
83 {
84 // TODO: Add Mutex
85 qCDebug(LOG_CosinusProvider()) << "CosinusProvider::requestDataAborting" << identifier
86 << QThread::currentThread()->objectName();
87 auto it = m_VariableToEnableProvider.find(identifier);
88 if (it != m_VariableToEnableProvider.end()) {
89 it.value() = false;
90 }
91 else {
92 qCWarning(LOG_CosinusProvider())
93 << tr("Aborting progression of inexistant identifier detected !!!");
47 }
94 }
48 }
95 }
General Comments 0
You need to be logged in to leave comments. Login now