##// END OF EJS Templates
Creates graph when dropping a product in the visu
trabillard -
r1288:5bae3c800f05
parent child
Show More
@@ -1,142 +1,144
1 #ifndef SCIQLOP_VARIABLECONTROLLER_H
1 #ifndef SCIQLOP_VARIABLECONTROLLER_H
2 #define SCIQLOP_VARIABLECONTROLLER_H
2 #define SCIQLOP_VARIABLECONTROLLER_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/AcquisitionDataPacket.h>
6 #include <Data/AcquisitionDataPacket.h>
7 #include <Data/SqpRange.h>
7 #include <Data/SqpRange.h>
8
8
9 #include <QLoggingCategory>
9 #include <QLoggingCategory>
10 #include <QObject>
10 #include <QObject>
11 #include <QUuid>
11 #include <QUuid>
12
12
13 #include <Common/spimpl.h>
13 #include <Common/spimpl.h>
14
14
15 class IDataProvider;
15 class IDataProvider;
16 class QItemSelectionModel;
16 class QItemSelectionModel;
17 class TimeController;
17 class TimeController;
18 class Variable;
18 class Variable;
19 class VariableModel;
19 class VariableModel;
20
20
21 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableController)
21 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableController)
22
22
23
23
24 /**
24 /**
25 * Possible types of zoom operation
25 * Possible types of zoom operation
26 */
26 */
27 enum class AcquisitionZoomType { ZoomOut, ZoomIn, PanRight, PanLeft, Unknown };
27 enum class AcquisitionZoomType { ZoomOut, ZoomIn, PanRight, PanLeft, Unknown };
28
28
29
29
30 /**
30 /**
31 * @brief The VariableController class aims to handle the variables in SciQlop.
31 * @brief The VariableController class aims to handle the variables in SciQlop.
32 */
32 */
33 class SCIQLOP_CORE_EXPORT VariableController : public QObject {
33 class SCIQLOP_CORE_EXPORT VariableController : public QObject {
34 Q_OBJECT
34 Q_OBJECT
35 public:
35 public:
36 explicit VariableController(QObject *parent = 0);
36 explicit VariableController(QObject *parent = 0);
37 virtual ~VariableController();
37 virtual ~VariableController();
38
38
39 VariableModel *variableModel() noexcept;
39 VariableModel *variableModel() noexcept;
40 QItemSelectionModel *variableSelectionModel() noexcept;
40 QItemSelectionModel *variableSelectionModel() noexcept;
41
41
42 void setTimeController(TimeController *timeController) noexcept;
42 void setTimeController(TimeController *timeController) noexcept;
43
43
44 /**
44 /**
45 * Clones the variable passed in parameter and adds the duplicate to the controller
45 * Clones the variable passed in parameter and adds the duplicate to the controller
46 * @param variable the variable to duplicate
46 * @param variable the variable to duplicate
47 * @return the duplicate created, nullptr if the variable couldn't be created
47 * @return the duplicate created, nullptr if the variable couldn't be created
48 */
48 */
49 std::shared_ptr<Variable> cloneVariable(std::shared_ptr<Variable> variable) noexcept;
49 std::shared_ptr<Variable> cloneVariable(std::shared_ptr<Variable> variable) noexcept;
50
50
51 /**
51 /**
52 * Deletes from the controller the variable passed in parameter.
52 * Deletes from the controller the variable passed in parameter.
53 *
53 *
54 * Delete a variable includes:
54 * Delete a variable includes:
55 * - the deletion of the various references to the variable in SciQlop
55 * - the deletion of the various references to the variable in SciQlop
56 * - the deletion of the model variable
56 * - the deletion of the model variable
57 * - the deletion of the provider associated with the variable
57 * - the deletion of the provider associated with the variable
58 * - removing the cache associated with the variable
58 * - removing the cache associated with the variable
59 *
59 *
60 * @param variable the variable to delete from the controller.
60 * @param variable the variable to delete from the controller.
61 */
61 */
62 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
62 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
63
63
64 /**
64 /**
65 * Deletes from the controller the variables passed in parameter.
65 * Deletes from the controller the variables passed in parameter.
66 * @param variables the variables to delete from the controller.
66 * @param variables the variables to delete from the controller.
67 * @sa deleteVariable()
67 * @sa deleteVariable()
68 */
68 */
69 void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept;
69 void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept;
70
70
71 /// Returns the MIME data associated to a list of variables
71 /// Returns the MIME data associated to a list of variables
72 QByteArray mimeDataForVariables(const QList<std::shared_ptr<Variable> > &variables) const;
72 QByteArray mimeDataForVariables(const QList<std::shared_ptr<Variable> > &variables) const;
73
73
74 /// Returns the list of variables contained in a MIME data
74 /// Returns the list of variables contained in a MIME data
75 QList<std::shared_ptr<Variable> > variablesForMimeData(const QByteArray &mimeData) const;
75 QList<std::shared_ptr<Variable> > variablesForMimeData(const QByteArray &mimeData) const;
76
76
77 static AcquisitionZoomType getZoomType(const SqpRange &range, const SqpRange &oldRange);
77 static AcquisitionZoomType getZoomType(const SqpRange &range, const SqpRange &oldRange);
78 signals:
78 signals:
79 /// Signal emitted when a variable is about to be deleted from the controller
79 /// Signal emitted when a variable is about to be deleted from the controller
80 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
80 void variableAboutToBeDeleted(std::shared_ptr<Variable> variable);
81
81
82 /// Signal emitted when a data acquisition is requested on a range for a variable
82 /// Signal emitted when a data acquisition is requested on a range for a variable
83 void rangeChanged(std::shared_ptr<Variable> variable, const SqpRange &range);
83 void rangeChanged(std::shared_ptr<Variable> variable, const SqpRange &range);
84
84
85 /// Signal emitted when a sub range of the cacheRange of the variable can be displayed
85 /// Signal emitted when a sub range of the cacheRange of the variable can be displayed
86 void updateVarDisplaying(std::shared_ptr<Variable> variable, const SqpRange &range);
86 void updateVarDisplaying(std::shared_ptr<Variable> variable, const SqpRange &range);
87
87
88 /// Signal emitted when all acquisitions related to the variables have been completed (whether
88 /// Signal emitted when all acquisitions related to the variables have been completed (whether
89 /// validated, canceled, or failed)
89 /// validated, canceled, or failed)
90 void acquisitionFinished();
90 void acquisitionFinished();
91
91
92 void variableAdded(const std::shared_ptr<Variable> &variable);
93
92 public slots:
94 public slots:
93 /// Request the data loading of the variable whithin range
95 /// Request the data loading of the variable whithin range
94 void onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables, const SqpRange &range,
96 void onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables, const SqpRange &range,
95 bool synchronise);
97 bool synchronise);
96 /**
98 /**
97 * Creates a new variable and adds it to the model
99 * Creates a new variable and adds it to the model
98 * @param name the name of the new variable
100 * @param name the name of the new variable
99 * @param metadata the metadata of the new variable
101 * @param metadata the metadata of the new variable
100 * @param provider the data provider for the new variable
102 * @param provider the data provider for the new variable
101 * @return the pointer to the new variable or nullptr if the creation failed
103 * @return the pointer to the new variable or nullptr if the creation failed
102 */
104 */
103 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata,
105 std::shared_ptr<Variable> createVariable(const QString &name, const QVariantHash &metadata,
104 std::shared_ptr<IDataProvider> provider) noexcept;
106 std::shared_ptr<IDataProvider> provider) noexcept;
105
107
106 /// Update the temporal parameters of every selected variable to dateTime
108 /// Update the temporal parameters of every selected variable to dateTime
107 void onDateTimeOnSelection(const SqpRange &dateTime);
109 void onDateTimeOnSelection(const SqpRange &dateTime);
108
110
109 /// Update the temporal parameters of the specified variable
111 /// Update the temporal parameters of the specified variable
110 void onUpdateDateTime(std::shared_ptr<Variable> variable, const SqpRange &dateTime);
112 void onUpdateDateTime(std::shared_ptr<Variable> variable, const SqpRange &dateTime);
111
113
112
114
113 void onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
115 void onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
114 const SqpRange &cacheRangeRequested,
116 const SqpRange &cacheRangeRequested,
115 QVector<AcquisitionDataPacket> dataAcquired);
117 QVector<AcquisitionDataPacket> dataAcquired);
116
118
117 void onVariableRetrieveDataInProgress(QUuid identifier, double progress);
119 void onVariableRetrieveDataInProgress(QUuid identifier, double progress);
118
120
119 /// Cancel the current request for the variable
121 /// Cancel the current request for the variable
120 void onAbortProgressRequested(std::shared_ptr<Variable> variable);
122 void onAbortProgressRequested(std::shared_ptr<Variable> variable);
121 void onAbortAcquisitionRequested(QUuid vIdentifier);
123 void onAbortAcquisitionRequested(QUuid vIdentifier);
122
124
123 // synchronization group methods
125 // synchronization group methods
124 void onAddSynchronizationGroupId(QUuid synchronizationGroupId);
126 void onAddSynchronizationGroupId(QUuid synchronizationGroupId);
125 void onRemoveSynchronizationGroupId(QUuid synchronizationGroupId);
127 void onRemoveSynchronizationGroupId(QUuid synchronizationGroupId);
126 void onAddSynchronized(std::shared_ptr<Variable> variable, QUuid synchronizationGroupId);
128 void onAddSynchronized(std::shared_ptr<Variable> variable, QUuid synchronizationGroupId);
127
129
128 /// Desynchronizes the variable of the group whose identifier is passed in parameter
130 /// Desynchronizes the variable of the group whose identifier is passed in parameter
129 /// @remarks the method does nothing if the variable is not part of the group
131 /// @remarks the method does nothing if the variable is not part of the group
130 void desynchronize(std::shared_ptr<Variable> variable, QUuid synchronizationGroupId);
132 void desynchronize(std::shared_ptr<Variable> variable, QUuid synchronizationGroupId);
131
133
132 void initialize();
134 void initialize();
133 void finalize();
135 void finalize();
134
136
135 private:
137 private:
136 void waitForFinish();
138 void waitForFinish();
137
139
138 class VariableControllerPrivate;
140 class VariableControllerPrivate;
139 spimpl::unique_impl_ptr<VariableControllerPrivate> impl;
141 spimpl::unique_impl_ptr<VariableControllerPrivate> impl;
140 };
142 };
141
143
142 #endif // SCIQLOP_VARIABLECONTROLLER_H
144 #endif // SCIQLOP_VARIABLECONTROLLER_H
@@ -1,1102 +1,1104
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableAcquisitionWorker.h>
2 #include <Variable/VariableAcquisitionWorker.h>
3 #include <Variable/VariableCacheStrategy.h>
3 #include <Variable/VariableCacheStrategy.h>
4 #include <Variable/VariableCacheStrategyFactory.h>
4 #include <Variable/VariableCacheStrategyFactory.h>
5 #include <Variable/VariableController.h>
5 #include <Variable/VariableController.h>
6 #include <Variable/VariableModel.h>
6 #include <Variable/VariableModel.h>
7 #include <Variable/VariableSynchronizationGroup.h>
7 #include <Variable/VariableSynchronizationGroup.h>
8
8
9 #include <Data/DataProviderParameters.h>
9 #include <Data/DataProviderParameters.h>
10 #include <Data/IDataProvider.h>
10 #include <Data/IDataProvider.h>
11 #include <Data/IDataSeries.h>
11 #include <Data/IDataSeries.h>
12 #include <Data/VariableRequest.h>
12 #include <Data/VariableRequest.h>
13 #include <Time/TimeController.h>
13 #include <Time/TimeController.h>
14
14
15 #include <QDataStream>
15 #include <QDataStream>
16 #include <QMutex>
16 #include <QMutex>
17 #include <QThread>
17 #include <QThread>
18 #include <QUuid>
18 #include <QUuid>
19 #include <QtCore/QItemSelectionModel>
19 #include <QtCore/QItemSelectionModel>
20
20
21 #include <deque>
21 #include <deque>
22 #include <set>
22 #include <set>
23 #include <unordered_map>
23 #include <unordered_map>
24
24
25 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
25 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
26
26
27 namespace {
27 namespace {
28
28
29 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
29 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
30 const SqpRange &oldGraphRange)
30 const SqpRange &oldGraphRange)
31 {
31 {
32 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
32 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
33
33
34 auto varRangeRequested = varRange;
34 auto varRangeRequested = varRange;
35 switch (zoomType) {
35 switch (zoomType) {
36 case AcquisitionZoomType::ZoomIn: {
36 case AcquisitionZoomType::ZoomIn: {
37 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
37 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
38 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
38 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
39 varRangeRequested.m_TStart += deltaLeft;
39 varRangeRequested.m_TStart += deltaLeft;
40 varRangeRequested.m_TEnd -= deltaRight;
40 varRangeRequested.m_TEnd -= deltaRight;
41 break;
41 break;
42 }
42 }
43
43
44 case AcquisitionZoomType::ZoomOut: {
44 case AcquisitionZoomType::ZoomOut: {
45 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
45 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
46 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
46 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
47 varRangeRequested.m_TStart -= deltaLeft;
47 varRangeRequested.m_TStart -= deltaLeft;
48 varRangeRequested.m_TEnd += deltaRight;
48 varRangeRequested.m_TEnd += deltaRight;
49 break;
49 break;
50 }
50 }
51 case AcquisitionZoomType::PanRight: {
51 case AcquisitionZoomType::PanRight: {
52 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
52 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
53 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
53 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
54 varRangeRequested.m_TStart += deltaLeft;
54 varRangeRequested.m_TStart += deltaLeft;
55 varRangeRequested.m_TEnd += deltaRight;
55 varRangeRequested.m_TEnd += deltaRight;
56 break;
56 break;
57 }
57 }
58 case AcquisitionZoomType::PanLeft: {
58 case AcquisitionZoomType::PanLeft: {
59 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
59 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
60 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
60 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
61 varRangeRequested.m_TStart -= deltaLeft;
61 varRangeRequested.m_TStart -= deltaLeft;
62 varRangeRequested.m_TEnd -= deltaRight;
62 varRangeRequested.m_TEnd -= deltaRight;
63 break;
63 break;
64 }
64 }
65 case AcquisitionZoomType::Unknown: {
65 case AcquisitionZoomType::Unknown: {
66 qCCritical(LOG_VariableController())
66 qCCritical(LOG_VariableController())
67 << VariableController::tr("Impossible to synchronize: zoom type unknown");
67 << VariableController::tr("Impossible to synchronize: zoom type unknown");
68 break;
68 break;
69 }
69 }
70 default:
70 default:
71 qCCritical(LOG_VariableController()) << VariableController::tr(
71 qCCritical(LOG_VariableController()) << VariableController::tr(
72 "Impossible to synchronize: zoom type not take into account");
72 "Impossible to synchronize: zoom type not take into account");
73 // No action
73 // No action
74 break;
74 break;
75 }
75 }
76
76
77 return varRangeRequested;
77 return varRangeRequested;
78 }
78 }
79 }
79 }
80
80
81 enum class VariableRequestHandlerState { OFF, RUNNING, PENDING };
81 enum class VariableRequestHandlerState { OFF, RUNNING, PENDING };
82
82
83 struct VariableRequestHandler {
83 struct VariableRequestHandler {
84
84
85 VariableRequestHandler()
85 VariableRequestHandler()
86 {
86 {
87 m_CanUpdate = false;
87 m_CanUpdate = false;
88 m_State = VariableRequestHandlerState::OFF;
88 m_State = VariableRequestHandlerState::OFF;
89 }
89 }
90
90
91 QUuid m_VarId;
91 QUuid m_VarId;
92 VariableRequest m_RunningVarRequest;
92 VariableRequest m_RunningVarRequest;
93 VariableRequest m_PendingVarRequest;
93 VariableRequest m_PendingVarRequest;
94 VariableRequestHandlerState m_State;
94 VariableRequestHandlerState m_State;
95 bool m_CanUpdate;
95 bool m_CanUpdate;
96 };
96 };
97
97
98 struct VariableController::VariableControllerPrivate {
98 struct VariableController::VariableControllerPrivate {
99 explicit VariableControllerPrivate(VariableController *parent)
99 explicit VariableControllerPrivate(VariableController *parent)
100 : m_WorkingMutex{},
100 : m_WorkingMutex{},
101 m_VariableModel{new VariableModel{parent}},
101 m_VariableModel{new VariableModel{parent}},
102 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
102 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
103 // m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
103 // m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
104 m_VariableCacheStrategy{VariableCacheStrategyFactory::createCacheStrategy(
104 m_VariableCacheStrategy{VariableCacheStrategyFactory::createCacheStrategy(
105 CacheStrategy::SingleThreshold)},
105 CacheStrategy::SingleThreshold)},
106 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
106 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
107 q{parent}
107 q{parent}
108 {
108 {
109
109
110 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
110 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
111 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
111 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
112 }
112 }
113
113
114
114
115 virtual ~VariableControllerPrivate()
115 virtual ~VariableControllerPrivate()
116 {
116 {
117 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
117 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
118 m_VariableAcquisitionWorkerThread.quit();
118 m_VariableAcquisitionWorkerThread.quit();
119 m_VariableAcquisitionWorkerThread.wait();
119 m_VariableAcquisitionWorkerThread.wait();
120 }
120 }
121
121
122
122
123 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
123 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
124 QUuid varRequestId);
124 QUuid varRequestId);
125
125
126 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
126 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
127 std::shared_ptr<IDataSeries>
127 std::shared_ptr<IDataSeries>
128 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
128 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
129
129
130 void registerProvider(std::shared_ptr<IDataProvider> provider);
130 void registerProvider(std::shared_ptr<IDataProvider> provider);
131
131
132 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
132 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
133 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
133 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
134 void updateVariables(QUuid varRequestId);
134 void updateVariables(QUuid varRequestId);
135 void updateVariableRequest(QUuid varRequestId);
135 void updateVariableRequest(QUuid varRequestId);
136 void cancelVariableRequest(QUuid varRequestId);
136 void cancelVariableRequest(QUuid varRequestId);
137 void executeVarRequest(std::shared_ptr<Variable> var, VariableRequest &varRequest);
137 void executeVarRequest(std::shared_ptr<Variable> var, VariableRequest &varRequest);
138
138
139 template <typename VariableIterator>
139 template <typename VariableIterator>
140 void desynchronize(VariableIterator variableIt, const QUuid &syncGroupId);
140 void desynchronize(VariableIterator variableIt, const QUuid &syncGroupId);
141
141
142 QMutex m_WorkingMutex;
142 QMutex m_WorkingMutex;
143 /// Variable model. The VariableController has the ownership
143 /// Variable model. The VariableController has the ownership
144 VariableModel *m_VariableModel;
144 VariableModel *m_VariableModel;
145 QItemSelectionModel *m_VariableSelectionModel;
145 QItemSelectionModel *m_VariableSelectionModel;
146
146
147
147
148 TimeController *m_TimeController{nullptr};
148 TimeController *m_TimeController{nullptr};
149 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
149 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
150 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
150 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
151 QThread m_VariableAcquisitionWorkerThread;
151 QThread m_VariableAcquisitionWorkerThread;
152
152
153 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
153 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
154 m_VariableToProviderMap;
154 m_VariableToProviderMap;
155 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
155 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
156 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
156 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
157 m_GroupIdToVariableSynchronizationGroupMap;
157 m_GroupIdToVariableSynchronizationGroupMap;
158 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
158 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
159 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
159 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
160
160
161 std::map<QUuid, std::list<QUuid> > m_VarGroupIdToVarIds;
161 std::map<QUuid, std::list<QUuid> > m_VarGroupIdToVarIds;
162 std::map<QUuid, std::unique_ptr<VariableRequestHandler> > m_VarIdToVarRequestHandler;
162 std::map<QUuid, std::unique_ptr<VariableRequestHandler> > m_VarIdToVarRequestHandler;
163
163
164 VariableController *q;
164 VariableController *q;
165 };
165 };
166
166
167
167
168 VariableController::VariableController(QObject *parent)
168 VariableController::VariableController(QObject *parent)
169 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
169 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
170 {
170 {
171 qCDebug(LOG_VariableController()) << tr("VariableController construction")
171 qCDebug(LOG_VariableController()) << tr("VariableController construction")
172 << QThread::currentThread();
172 << QThread::currentThread();
173
173
174 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
174 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
175 &VariableController::onAbortProgressRequested);
175 &VariableController::onAbortProgressRequested);
176
176
177 connect(impl->m_VariableAcquisitionWorker.get(),
177 connect(impl->m_VariableAcquisitionWorker.get(),
178 &VariableAcquisitionWorker::variableCanceledRequested, this,
178 &VariableAcquisitionWorker::variableCanceledRequested, this,
179 &VariableController::onAbortAcquisitionRequested);
179 &VariableController::onAbortAcquisitionRequested);
180
180
181 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
181 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
182 &VariableController::onDataProvided);
182 &VariableController::onDataProvided);
183 connect(impl->m_VariableAcquisitionWorker.get(),
183 connect(impl->m_VariableAcquisitionWorker.get(),
184 &VariableAcquisitionWorker::variableRequestInProgress, this,
184 &VariableAcquisitionWorker::variableRequestInProgress, this,
185 &VariableController::onVariableRetrieveDataInProgress);
185 &VariableController::onVariableRetrieveDataInProgress);
186
186
187
187
188 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
188 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
189 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
189 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
190 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
190 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
191 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
191 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
192
192
193 connect(impl->m_VariableModel, &VariableModel::requestVariableRangeUpdate, this,
193 connect(impl->m_VariableModel, &VariableModel::requestVariableRangeUpdate, this,
194 &VariableController::onUpdateDateTime);
194 &VariableController::onUpdateDateTime);
195
195
196 impl->m_VariableAcquisitionWorkerThread.start();
196 impl->m_VariableAcquisitionWorkerThread.start();
197 }
197 }
198
198
199 VariableController::~VariableController()
199 VariableController::~VariableController()
200 {
200 {
201 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
201 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
202 << QThread::currentThread();
202 << QThread::currentThread();
203 this->waitForFinish();
203 this->waitForFinish();
204 }
204 }
205
205
206 VariableModel *VariableController::variableModel() noexcept
206 VariableModel *VariableController::variableModel() noexcept
207 {
207 {
208 return impl->m_VariableModel;
208 return impl->m_VariableModel;
209 }
209 }
210
210
211 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
211 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
212 {
212 {
213 return impl->m_VariableSelectionModel;
213 return impl->m_VariableSelectionModel;
214 }
214 }
215
215
216 void VariableController::setTimeController(TimeController *timeController) noexcept
216 void VariableController::setTimeController(TimeController *timeController) noexcept
217 {
217 {
218 impl->m_TimeController = timeController;
218 impl->m_TimeController = timeController;
219 }
219 }
220
220
221 std::shared_ptr<Variable>
221 std::shared_ptr<Variable>
222 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
222 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
223 {
223 {
224 if (impl->m_VariableModel->containsVariable(variable)) {
224 if (impl->m_VariableModel->containsVariable(variable)) {
225 // Clones variable
225 // Clones variable
226 auto duplicate = variable->clone();
226 auto duplicate = variable->clone();
227
227
228 // Adds clone to model
228 // Adds clone to model
229 impl->m_VariableModel->addVariable(duplicate);
229 impl->m_VariableModel->addVariable(duplicate);
230
230
231 // Generates clone identifier
231 // Generates clone identifier
232 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
232 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
233
233
234 // Registers provider
234 // Registers provider
235 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
235 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
236 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
236 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
237
237
238 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
238 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
239 if (duplicateProvider) {
239 if (duplicateProvider) {
240 impl->registerProvider(duplicateProvider);
240 impl->registerProvider(duplicateProvider);
241 }
241 }
242
242
243 return duplicate;
243 return duplicate;
244 }
244 }
245 else {
245 else {
246 qCCritical(LOG_VariableController())
246 qCCritical(LOG_VariableController())
247 << tr("Can't create duplicate of variable %1: variable not registered in the model")
247 << tr("Can't create duplicate of variable %1: variable not registered in the model")
248 .arg(variable->name());
248 .arg(variable->name());
249 return nullptr;
249 return nullptr;
250 }
250 }
251 }
251 }
252
252
253 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
253 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
254 {
254 {
255 if (!variable) {
255 if (!variable) {
256 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
256 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
257 return;
257 return;
258 }
258 }
259
259
260 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
260 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
261 // make some treatments before the deletion
261 // make some treatments before the deletion
262 emit variableAboutToBeDeleted(variable);
262 emit variableAboutToBeDeleted(variable);
263
263
264 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
264 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
265 Q_ASSERT(variableIt != impl->m_VariableToIdentifierMap.cend());
265 Q_ASSERT(variableIt != impl->m_VariableToIdentifierMap.cend());
266
266
267 auto variableId = variableIt->second;
267 auto variableId = variableIt->second;
268
268
269 // Removes variable's handler
269 // Removes variable's handler
270 impl->m_VarIdToVarRequestHandler.erase(variableId);
270 impl->m_VarIdToVarRequestHandler.erase(variableId);
271
271
272 // Desynchronizes variable (if the variable is in a sync group)
272 // Desynchronizes variable (if the variable is in a sync group)
273 auto syncGroupIt = impl->m_VariableIdGroupIdMap.find(variableId);
273 auto syncGroupIt = impl->m_VariableIdGroupIdMap.find(variableId);
274 if (syncGroupIt != impl->m_VariableIdGroupIdMap.cend()) {
274 if (syncGroupIt != impl->m_VariableIdGroupIdMap.cend()) {
275 impl->desynchronize(variableIt, syncGroupIt->second);
275 impl->desynchronize(variableIt, syncGroupIt->second);
276 }
276 }
277
277
278 // Deletes identifier
278 // Deletes identifier
279 impl->m_VariableToIdentifierMap.erase(variableIt);
279 impl->m_VariableToIdentifierMap.erase(variableIt);
280
280
281 // Deletes provider
281 // Deletes provider
282 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
282 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
283 qCDebug(LOG_VariableController())
283 qCDebug(LOG_VariableController())
284 << tr("Number of providers deleted for variable %1: %2")
284 << tr("Number of providers deleted for variable %1: %2")
285 .arg(variable->name(), QString::number(nbProvidersDeleted));
285 .arg(variable->name(), QString::number(nbProvidersDeleted));
286
286
287
287
288 // Deletes from model
288 // Deletes from model
289 impl->m_VariableModel->deleteVariable(variable);
289 impl->m_VariableModel->deleteVariable(variable);
290 }
290 }
291
291
292 void VariableController::deleteVariables(
292 void VariableController::deleteVariables(
293 const QVector<std::shared_ptr<Variable> > &variables) noexcept
293 const QVector<std::shared_ptr<Variable> > &variables) noexcept
294 {
294 {
295 for (auto variable : qAsConst(variables)) {
295 for (auto variable : qAsConst(variables)) {
296 deleteVariable(variable);
296 deleteVariable(variable);
297 }
297 }
298 }
298 }
299
299
300 QByteArray
300 QByteArray
301 VariableController::mimeDataForVariables(const QList<std::shared_ptr<Variable> > &variables) const
301 VariableController::mimeDataForVariables(const QList<std::shared_ptr<Variable> > &variables) const
302 {
302 {
303 auto encodedData = QByteArray{};
303 auto encodedData = QByteArray{};
304
304
305 QVariantList ids;
305 QVariantList ids;
306 for (auto &var : variables) {
306 for (auto &var : variables) {
307 auto itVar = impl->m_VariableToIdentifierMap.find(var);
307 auto itVar = impl->m_VariableToIdentifierMap.find(var);
308 if (itVar == impl->m_VariableToIdentifierMap.cend()) {
308 if (itVar == impl->m_VariableToIdentifierMap.cend()) {
309 qCCritical(LOG_VariableController())
309 qCCritical(LOG_VariableController())
310 << tr("Impossible to find the data for an unknown variable.");
310 << tr("Impossible to find the data for an unknown variable.");
311 }
311 }
312
312
313 ids << itVar->second.toByteArray();
313 ids << itVar->second.toByteArray();
314 }
314 }
315
315
316 QDataStream stream{&encodedData, QIODevice::WriteOnly};
316 QDataStream stream{&encodedData, QIODevice::WriteOnly};
317 stream << ids;
317 stream << ids;
318
318
319 return encodedData;
319 return encodedData;
320 }
320 }
321
321
322 QList<std::shared_ptr<Variable> >
322 QList<std::shared_ptr<Variable> >
323 VariableController::variablesForMimeData(const QByteArray &mimeData) const
323 VariableController::variablesForMimeData(const QByteArray &mimeData) const
324 {
324 {
325 auto variables = QList<std::shared_ptr<Variable> >{};
325 auto variables = QList<std::shared_ptr<Variable> >{};
326 QDataStream stream{mimeData};
326 QDataStream stream{mimeData};
327
327
328 QVariantList ids;
328 QVariantList ids;
329 stream >> ids;
329 stream >> ids;
330
330
331 for (auto id : ids) {
331 for (auto id : ids) {
332 auto uuid = QUuid{id.toByteArray()};
332 auto uuid = QUuid{id.toByteArray()};
333 auto var = impl->findVariable(uuid);
333 auto var = impl->findVariable(uuid);
334 variables << var;
334 variables << var;
335 }
335 }
336
336
337 return variables;
337 return variables;
338 }
338 }
339
339
340 std::shared_ptr<Variable>
340 std::shared_ptr<Variable>
341 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
341 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
342 std::shared_ptr<IDataProvider> provider) noexcept
342 std::shared_ptr<IDataProvider> provider) noexcept
343 {
343 {
344 if (!impl->m_TimeController) {
344 if (!impl->m_TimeController) {
345 qCCritical(LOG_VariableController())
345 qCCritical(LOG_VariableController())
346 << tr("Impossible to create variable: The time controller is null");
346 << tr("Impossible to create variable: The time controller is null");
347 return nullptr;
347 return nullptr;
348 }
348 }
349
349
350 auto range = impl->m_TimeController->dateTime();
350 auto range = impl->m_TimeController->dateTime();
351
351
352 if (auto newVariable = impl->m_VariableModel->createVariable(name, metadata)) {
352 if (auto newVariable = impl->m_VariableModel->createVariable(name, metadata)) {
353 auto varId = QUuid::createUuid();
353 auto varId = QUuid::createUuid();
354
354
355 // Create the handler
355 // Create the handler
356 auto varRequestHandler = std::make_unique<VariableRequestHandler>();
356 auto varRequestHandler = std::make_unique<VariableRequestHandler>();
357 varRequestHandler->m_VarId = varId;
357 varRequestHandler->m_VarId = varId;
358
358
359 impl->m_VarIdToVarRequestHandler.insert(
359 impl->m_VarIdToVarRequestHandler.insert(
360 std::make_pair(varId, std::move(varRequestHandler)));
360 std::make_pair(varId, std::move(varRequestHandler)));
361
361
362 // store the provider
362 // store the provider
363 impl->registerProvider(provider);
363 impl->registerProvider(provider);
364
364
365 // Associate the provider
365 // Associate the provider
366 impl->m_VariableToProviderMap[newVariable] = provider;
366 impl->m_VariableToProviderMap[newVariable] = provider;
367 impl->m_VariableToIdentifierMap[newVariable] = varId;
367 impl->m_VariableToIdentifierMap[newVariable] = varId;
368
368
369 this->onRequestDataLoading(QVector<std::shared_ptr<Variable> >{newVariable}, range, false);
369 this->onRequestDataLoading(QVector<std::shared_ptr<Variable> >{newVariable}, range, false);
370
370
371 // auto varRequestId = QUuid::createUuid();
371 // auto varRequestId = QUuid::createUuid();
372 // qCInfo(LOG_VariableController()) << "createVariable: " << varId << varRequestId;
372 // qCInfo(LOG_VariableController()) << "createVariable: " << varId << varRequestId;
373 // impl->processRequest(newVariable, range, varRequestId);
373 // impl->processRequest(newVariable, range, varRequestId);
374 // impl->updateVariableRequest(varRequestId);
374 // impl->updateVariableRequest(varRequestId);
375
375
376 emit variableAdded(newVariable);
377
376 return newVariable;
378 return newVariable;
377 }
379 }
378
380
379 qCCritical(LOG_VariableController()) << tr("Impossible to create variable");
381 qCCritical(LOG_VariableController()) << tr("Impossible to create variable");
380 return nullptr;
382 return nullptr;
381 }
383 }
382
384
383 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
385 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
384 {
386 {
385 // NOTE: Even if acquisition request is aborting, the graphe range will be changed
387 // NOTE: Even if acquisition request is aborting, the graphe range will be changed
386 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
388 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
387 << QThread::currentThread()->objectName();
389 << QThread::currentThread()->objectName();
388 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
390 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
389
391
390 // NOTE we only permit the time modification for one variable
392 // NOTE we only permit the time modification for one variable
391 // DEPRECATED
393 // DEPRECATED
392 // auto variables = QVector<std::shared_ptr<Variable> >{};
394 // auto variables = QVector<std::shared_ptr<Variable> >{};
393 // for (const auto &selectedRow : qAsConst(selectedRows)) {
395 // for (const auto &selectedRow : qAsConst(selectedRows)) {
394 // if (auto selectedVariable =
396 // if (auto selectedVariable =
395 // impl->m_VariableModel->variable(selectedRow.row())) {
397 // impl->m_VariableModel->variable(selectedRow.row())) {
396 // variables << selectedVariable;
398 // variables << selectedVariable;
397
399
398 // // notify that rescale operation has to be done
400 // // notify that rescale operation has to be done
399 // emit rangeChanged(selectedVariable, dateTime);
401 // emit rangeChanged(selectedVariable, dateTime);
400 // }
402 // }
401 // }
403 // }
402 // if (!variables.isEmpty()) {
404 // if (!variables.isEmpty()) {
403 // this->onRequestDataLoading(variables, dateTime, synchro);
405 // this->onRequestDataLoading(variables, dateTime, synchro);
404 // }
406 // }
405 if (selectedRows.size() == 1) {
407 if (selectedRows.size() == 1) {
406
408
407 if (auto selectedVariable
409 if (auto selectedVariable
408 = impl->m_VariableModel->variable(qAsConst(selectedRows).first().row())) {
410 = impl->m_VariableModel->variable(qAsConst(selectedRows).first().row())) {
409
411
410 onUpdateDateTime(selectedVariable, dateTime);
412 onUpdateDateTime(selectedVariable, dateTime);
411 }
413 }
412 }
414 }
413 else if (selectedRows.size() > 1) {
415 else if (selectedRows.size() > 1) {
414 qCCritical(LOG_VariableController())
416 qCCritical(LOG_VariableController())
415 << tr("Impossible to set time for more than 1 variable in the same time");
417 << tr("Impossible to set time for more than 1 variable in the same time");
416 }
418 }
417 else {
419 else {
418 qCWarning(LOG_VariableController())
420 qCWarning(LOG_VariableController())
419 << tr("There is no variable selected to set the time one");
421 << tr("There is no variable selected to set the time one");
420 }
422 }
421 }
423 }
422
424
423 void VariableController::onUpdateDateTime(std::shared_ptr<Variable> variable,
425 void VariableController::onUpdateDateTime(std::shared_ptr<Variable> variable,
424 const SqpRange &dateTime)
426 const SqpRange &dateTime)
425 {
427 {
426 auto itVar = impl->m_VariableToIdentifierMap.find(variable);
428 auto itVar = impl->m_VariableToIdentifierMap.find(variable);
427 if (itVar == impl->m_VariableToIdentifierMap.cend()) {
429 if (itVar == impl->m_VariableToIdentifierMap.cend()) {
428 qCCritical(LOG_VariableController())
430 qCCritical(LOG_VariableController())
429 << tr("Impossible to onDateTimeOnSelection request for unknown variable");
431 << tr("Impossible to onDateTimeOnSelection request for unknown variable");
430 return;
432 return;
431 }
433 }
432
434
433 // notify that rescale operation has to be done
435 // notify that rescale operation has to be done
434 emit rangeChanged(variable, dateTime);
436 emit rangeChanged(variable, dateTime);
435
437
436 auto synchro
438 auto synchro
437 = impl->m_VariableIdGroupIdMap.find(itVar->second) != impl->m_VariableIdGroupIdMap.cend();
439 = impl->m_VariableIdGroupIdMap.find(itVar->second) != impl->m_VariableIdGroupIdMap.cend();
438
440
439 this->onRequestDataLoading(QVector<std::shared_ptr<Variable> >{variable}, dateTime, synchro);
441 this->onRequestDataLoading(QVector<std::shared_ptr<Variable> >{variable}, dateTime, synchro);
440 }
442 }
441
443
442 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
444 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
443 const SqpRange &cacheRangeRequested,
445 const SqpRange &cacheRangeRequested,
444 QVector<AcquisitionDataPacket> dataAcquired)
446 QVector<AcquisitionDataPacket> dataAcquired)
445 {
447 {
446 qCDebug(LOG_VariableController()) << tr("onDataProvided") << QThread::currentThread();
448 qCDebug(LOG_VariableController()) << tr("onDataProvided") << QThread::currentThread();
447 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
449 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
448 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
450 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
449 if (!varRequestId.isNull()) {
451 if (!varRequestId.isNull()) {
450 impl->updateVariables(varRequestId);
452 impl->updateVariables(varRequestId);
451 }
453 }
452 }
454 }
453
455
454 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
456 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
455 {
457 {
456 qCDebug(LOG_VariableController())
458 qCDebug(LOG_VariableController())
457 << "TORM: variableController::onVariableRetrieveDataInProgress"
459 << "TORM: variableController::onVariableRetrieveDataInProgress"
458 << QThread::currentThread()->objectName() << progress;
460 << QThread::currentThread()->objectName() << progress;
459 if (auto var = impl->findVariable(identifier)) {
461 if (auto var = impl->findVariable(identifier)) {
460 impl->m_VariableModel->setDataProgress(var, progress);
462 impl->m_VariableModel->setDataProgress(var, progress);
461 }
463 }
462 else {
464 else {
463 qCCritical(LOG_VariableController())
465 qCCritical(LOG_VariableController())
464 << tr("Impossible to notify progression of a null variable");
466 << tr("Impossible to notify progression of a null variable");
465 }
467 }
466 }
468 }
467
469
468 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
470 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
469 {
471 {
470 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortProgressRequested"
472 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortProgressRequested"
471 << QThread::currentThread()->objectName() << variable->name();
473 << QThread::currentThread()->objectName() << variable->name();
472
474
473 auto itVar = impl->m_VariableToIdentifierMap.find(variable);
475 auto itVar = impl->m_VariableToIdentifierMap.find(variable);
474 if (itVar == impl->m_VariableToIdentifierMap.cend()) {
476 if (itVar == impl->m_VariableToIdentifierMap.cend()) {
475 qCCritical(LOG_VariableController())
477 qCCritical(LOG_VariableController())
476 << tr("Impossible to onAbortProgressRequested request for unknown variable");
478 << tr("Impossible to onAbortProgressRequested request for unknown variable");
477 return;
479 return;
478 }
480 }
479
481
480 auto varId = itVar->second;
482 auto varId = itVar->second;
481
483
482 auto itVarHandler = impl->m_VarIdToVarRequestHandler.find(varId);
484 auto itVarHandler = impl->m_VarIdToVarRequestHandler.find(varId);
483 if (itVarHandler == impl->m_VarIdToVarRequestHandler.cend()) {
485 if (itVarHandler == impl->m_VarIdToVarRequestHandler.cend()) {
484 qCCritical(LOG_VariableController())
486 qCCritical(LOG_VariableController())
485 << tr("Impossible to onAbortProgressRequested for variable with unknown handler");
487 << tr("Impossible to onAbortProgressRequested for variable with unknown handler");
486 return;
488 return;
487 }
489 }
488
490
489 auto varHandler = itVarHandler->second.get();
491 auto varHandler = itVarHandler->second.get();
490
492
491 // case where a variable has a running request
493 // case where a variable has a running request
492 if (varHandler->m_State != VariableRequestHandlerState::OFF) {
494 if (varHandler->m_State != VariableRequestHandlerState::OFF) {
493 impl->cancelVariableRequest(varHandler->m_RunningVarRequest.m_VariableGroupId);
495 impl->cancelVariableRequest(varHandler->m_RunningVarRequest.m_VariableGroupId);
494 }
496 }
495 }
497 }
496
498
497 void VariableController::onAbortAcquisitionRequested(QUuid vIdentifier)
499 void VariableController::onAbortAcquisitionRequested(QUuid vIdentifier)
498 {
500 {
499 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortAcquisitionRequested"
501 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortAcquisitionRequested"
500 << QThread::currentThread()->objectName() << vIdentifier;
502 << QThread::currentThread()->objectName() << vIdentifier;
501
503
502 if (auto var = impl->findVariable(vIdentifier)) {
504 if (auto var = impl->findVariable(vIdentifier)) {
503 this->onAbortProgressRequested(var);
505 this->onAbortProgressRequested(var);
504 }
506 }
505 else {
507 else {
506 qCCritical(LOG_VariableController())
508 qCCritical(LOG_VariableController())
507 << tr("Impossible to abort Acquisition Requestof a null variable");
509 << tr("Impossible to abort Acquisition Requestof a null variable");
508 }
510 }
509 }
511 }
510
512
511 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
513 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
512 {
514 {
513 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
515 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
514 << QThread::currentThread()->objectName()
516 << QThread::currentThread()->objectName()
515 << synchronizationGroupId;
517 << synchronizationGroupId;
516 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
518 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
517 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
519 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
518 std::make_pair(synchronizationGroupId, vSynchroGroup));
520 std::make_pair(synchronizationGroupId, vSynchroGroup));
519 }
521 }
520
522
521 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
523 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
522 {
524 {
523 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
525 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
524 }
526 }
525
527
526 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
528 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
527 QUuid synchronizationGroupId)
529 QUuid synchronizationGroupId)
528
530
529 {
531 {
530 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
532 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
531 << synchronizationGroupId;
533 << synchronizationGroupId;
532 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
534 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
533 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
535 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
534 auto groupIdToVSGIt
536 auto groupIdToVSGIt
535 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
537 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
536 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
538 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
537 impl->m_VariableIdGroupIdMap.insert(
539 impl->m_VariableIdGroupIdMap.insert(
538 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
540 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
539 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
541 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
540 }
542 }
541 else {
543 else {
542 qCCritical(LOG_VariableController())
544 qCCritical(LOG_VariableController())
543 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
545 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
544 << variable->name();
546 << variable->name();
545 }
547 }
546 }
548 }
547 else {
549 else {
548 qCCritical(LOG_VariableController())
550 qCCritical(LOG_VariableController())
549 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
551 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
550 }
552 }
551 }
553 }
552
554
553 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
555 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
554 QUuid synchronizationGroupId)
556 QUuid synchronizationGroupId)
555 {
557 {
556 // Gets variable id
558 // Gets variable id
557 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
559 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
558 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
560 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
559 qCCritical(LOG_VariableController())
561 qCCritical(LOG_VariableController())
560 << tr("Can't desynchronize variable %1: variable identifier not found")
562 << tr("Can't desynchronize variable %1: variable identifier not found")
561 .arg(variable->name());
563 .arg(variable->name());
562 return;
564 return;
563 }
565 }
564
566
565 impl->desynchronize(variableIt, synchronizationGroupId);
567 impl->desynchronize(variableIt, synchronizationGroupId);
566 }
568 }
567
569
568 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
570 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
569 const SqpRange &range, bool synchronise)
571 const SqpRange &range, bool synchronise)
570 {
572 {
571 // variables is assumed synchronized
573 // variables is assumed synchronized
572 // TODO: Asser variables synchronization
574 // TODO: Asser variables synchronization
573 // we want to load data of the variable for the dateTime.
575 // we want to load data of the variable for the dateTime.
574 if (variables.isEmpty()) {
576 if (variables.isEmpty()) {
575 return;
577 return;
576 }
578 }
577
579
578 auto varRequestId = QUuid::createUuid();
580 auto varRequestId = QUuid::createUuid();
579 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
581 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
580 << QThread::currentThread()->objectName() << varRequestId
582 << QThread::currentThread()->objectName() << varRequestId
581 << range << synchronise;
583 << range << synchronise;
582
584
583 if (!synchronise) {
585 if (!synchronise) {
584 auto varIds = std::list<QUuid>{};
586 auto varIds = std::list<QUuid>{};
585 for (const auto &var : variables) {
587 for (const auto &var : variables) {
586 auto vId = impl->m_VariableToIdentifierMap.at(var);
588 auto vId = impl->m_VariableToIdentifierMap.at(var);
587 varIds.push_back(vId);
589 varIds.push_back(vId);
588 }
590 }
589 impl->m_VarGroupIdToVarIds.insert(std::make_pair(varRequestId, varIds));
591 impl->m_VarGroupIdToVarIds.insert(std::make_pair(varRequestId, varIds));
590 for (const auto &var : variables) {
592 for (const auto &var : variables) {
591 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId
593 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId
592 << varIds.size();
594 << varIds.size();
593 impl->processRequest(var, range, varRequestId);
595 impl->processRequest(var, range, varRequestId);
594 }
596 }
595 }
597 }
596 else {
598 else {
597 auto vId = impl->m_VariableToIdentifierMap.at(variables.first());
599 auto vId = impl->m_VariableToIdentifierMap.at(variables.first());
598 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
600 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
599 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
601 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
600 auto groupId = varIdToGroupIdIt->second;
602 auto groupId = varIdToGroupIdIt->second;
601
603
602 auto vSynchronizationGroup
604 auto vSynchronizationGroup
603 = impl->m_GroupIdToVariableSynchronizationGroupMap.at(groupId);
605 = impl->m_GroupIdToVariableSynchronizationGroupMap.at(groupId);
604 auto vSyncIds = vSynchronizationGroup->getIds();
606 auto vSyncIds = vSynchronizationGroup->getIds();
605
607
606 auto varIds = std::list<QUuid>{};
608 auto varIds = std::list<QUuid>{};
607 for (auto vId : vSyncIds) {
609 for (auto vId : vSyncIds) {
608 varIds.push_back(vId);
610 varIds.push_back(vId);
609 }
611 }
610 impl->m_VarGroupIdToVarIds.insert(std::make_pair(varRequestId, varIds));
612 impl->m_VarGroupIdToVarIds.insert(std::make_pair(varRequestId, varIds));
611
613
612 for (auto vId : vSyncIds) {
614 for (auto vId : vSyncIds) {
613 auto var = impl->findVariable(vId);
615 auto var = impl->findVariable(vId);
614
616
615 // Don't process already processed var
617 // Don't process already processed var
616 if (var != nullptr) {
618 if (var != nullptr) {
617 qCDebug(LOG_VariableController()) << "processRequest synchro for" << var->name()
619 qCDebug(LOG_VariableController()) << "processRequest synchro for" << var->name()
618 << varRequestId;
620 << varRequestId;
619 auto vSyncRangeRequested
621 auto vSyncRangeRequested
620 = variables.contains(var)
622 = variables.contains(var)
621 ? range
623 ? range
622 : computeSynchroRangeRequested(var->range(), range,
624 : computeSynchroRangeRequested(var->range(), range,
623 variables.first()->range());
625 variables.first()->range());
624 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
626 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
625 impl->processRequest(var, vSyncRangeRequested, varRequestId);
627 impl->processRequest(var, vSyncRangeRequested, varRequestId);
626 }
628 }
627 else {
629 else {
628 qCCritical(LOG_VariableController())
630 qCCritical(LOG_VariableController())
629
631
630 << tr("Impossible to synchronize a null variable");
632 << tr("Impossible to synchronize a null variable");
631 }
633 }
632 }
634 }
633 }
635 }
634 }
636 }
635
637
636 impl->updateVariables(varRequestId);
638 impl->updateVariables(varRequestId);
637 }
639 }
638
640
639
641
640 void VariableController::initialize()
642 void VariableController::initialize()
641 {
643 {
642 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
644 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
643 impl->m_WorkingMutex.lock();
645 impl->m_WorkingMutex.lock();
644 qCDebug(LOG_VariableController()) << tr("VariableController init END");
646 qCDebug(LOG_VariableController()) << tr("VariableController init END");
645 }
647 }
646
648
647 void VariableController::finalize()
649 void VariableController::finalize()
648 {
650 {
649 impl->m_WorkingMutex.unlock();
651 impl->m_WorkingMutex.unlock();
650 }
652 }
651
653
652 void VariableController::waitForFinish()
654 void VariableController::waitForFinish()
653 {
655 {
654 QMutexLocker locker{&impl->m_WorkingMutex};
656 QMutexLocker locker{&impl->m_WorkingMutex};
655 }
657 }
656
658
657 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
659 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
658 {
660 {
659 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
661 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
660 auto zoomType = AcquisitionZoomType::Unknown;
662 auto zoomType = AcquisitionZoomType::Unknown;
661 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
663 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
662 qCDebug(LOG_VariableController()) << "zoomtype: ZoomOut";
664 qCDebug(LOG_VariableController()) << "zoomtype: ZoomOut";
663 zoomType = AcquisitionZoomType::ZoomOut;
665 zoomType = AcquisitionZoomType::ZoomOut;
664 }
666 }
665 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
667 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
666 qCDebug(LOG_VariableController()) << "zoomtype: PanRight";
668 qCDebug(LOG_VariableController()) << "zoomtype: PanRight";
667 zoomType = AcquisitionZoomType::PanRight;
669 zoomType = AcquisitionZoomType::PanRight;
668 }
670 }
669 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
671 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
670 qCDebug(LOG_VariableController()) << "zoomtype: PanLeft";
672 qCDebug(LOG_VariableController()) << "zoomtype: PanLeft";
671 zoomType = AcquisitionZoomType::PanLeft;
673 zoomType = AcquisitionZoomType::PanLeft;
672 }
674 }
673 else if (range.m_TStart >= oldRange.m_TStart && oldRange.m_TEnd >= range.m_TEnd) {
675 else if (range.m_TStart >= oldRange.m_TStart && oldRange.m_TEnd >= range.m_TEnd) {
674 qCDebug(LOG_VariableController()) << "zoomtype: ZoomIn";
676 qCDebug(LOG_VariableController()) << "zoomtype: ZoomIn";
675 zoomType = AcquisitionZoomType::ZoomIn;
677 zoomType = AcquisitionZoomType::ZoomIn;
676 }
678 }
677 else {
679 else {
678 qCDebug(LOG_VariableController()) << "getZoomType: Unknown type detected";
680 qCDebug(LOG_VariableController()) << "getZoomType: Unknown type detected";
679 }
681 }
680 return zoomType;
682 return zoomType;
681 }
683 }
682
684
683 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
685 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
684 const SqpRange &rangeRequested,
686 const SqpRange &rangeRequested,
685 QUuid varRequestId)
687 QUuid varRequestId)
686 {
688 {
687 auto itVar = m_VariableToIdentifierMap.find(var);
689 auto itVar = m_VariableToIdentifierMap.find(var);
688 if (itVar == m_VariableToIdentifierMap.cend()) {
690 if (itVar == m_VariableToIdentifierMap.cend()) {
689 qCCritical(LOG_VariableController())
691 qCCritical(LOG_VariableController())
690 << tr("Impossible to process request for unknown variable");
692 << tr("Impossible to process request for unknown variable");
691 return;
693 return;
692 }
694 }
693
695
694 auto varId = itVar->second;
696 auto varId = itVar->second;
695
697
696 auto itVarHandler = m_VarIdToVarRequestHandler.find(varId);
698 auto itVarHandler = m_VarIdToVarRequestHandler.find(varId);
697 if (itVarHandler == m_VarIdToVarRequestHandler.cend()) {
699 if (itVarHandler == m_VarIdToVarRequestHandler.cend()) {
698 qCCritical(LOG_VariableController())
700 qCCritical(LOG_VariableController())
699 << tr("Impossible to process request for variable with unknown handler");
701 << tr("Impossible to process request for variable with unknown handler");
700 return;
702 return;
701 }
703 }
702
704
703 auto oldRange = var->range();
705 auto oldRange = var->range();
704
706
705 auto varHandler = itVarHandler->second.get();
707 auto varHandler = itVarHandler->second.get();
706
708
707 if (varHandler->m_State != VariableRequestHandlerState::OFF) {
709 if (varHandler->m_State != VariableRequestHandlerState::OFF) {
708 oldRange = varHandler->m_RunningVarRequest.m_RangeRequested;
710 oldRange = varHandler->m_RunningVarRequest.m_RangeRequested;
709 }
711 }
710
712
711 auto varRequest = VariableRequest{};
713 auto varRequest = VariableRequest{};
712 varRequest.m_VariableGroupId = varRequestId;
714 varRequest.m_VariableGroupId = varRequestId;
713 auto varStrategyRangesRequested
715 auto varStrategyRangesRequested
714 = m_VariableCacheStrategy->computeRange(oldRange, rangeRequested);
716 = m_VariableCacheStrategy->computeRange(oldRange, rangeRequested);
715 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
717 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
716 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
718 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
717
719
718 switch (varHandler->m_State) {
720 switch (varHandler->m_State) {
719 case VariableRequestHandlerState::OFF: {
721 case VariableRequestHandlerState::OFF: {
720 qCDebug(LOG_VariableController()) << tr("Process Request OFF")
722 qCDebug(LOG_VariableController()) << tr("Process Request OFF")
721 << varRequest.m_RangeRequested
723 << varRequest.m_RangeRequested
722 << varRequest.m_CacheRangeRequested;
724 << varRequest.m_CacheRangeRequested;
723 varHandler->m_RunningVarRequest = varRequest;
725 varHandler->m_RunningVarRequest = varRequest;
724 varHandler->m_State = VariableRequestHandlerState::RUNNING;
726 varHandler->m_State = VariableRequestHandlerState::RUNNING;
725 executeVarRequest(var, varRequest);
727 executeVarRequest(var, varRequest);
726 break;
728 break;
727 }
729 }
728 case VariableRequestHandlerState::RUNNING: {
730 case VariableRequestHandlerState::RUNNING: {
729 qCDebug(LOG_VariableController()) << tr("Process Request RUNNING")
731 qCDebug(LOG_VariableController()) << tr("Process Request RUNNING")
730 << varRequest.m_RangeRequested
732 << varRequest.m_RangeRequested
731 << varRequest.m_CacheRangeRequested;
733 << varRequest.m_CacheRangeRequested;
732 varHandler->m_State = VariableRequestHandlerState::PENDING;
734 varHandler->m_State = VariableRequestHandlerState::PENDING;
733 varHandler->m_PendingVarRequest = varRequest;
735 varHandler->m_PendingVarRequest = varRequest;
734 break;
736 break;
735 }
737 }
736 case VariableRequestHandlerState::PENDING: {
738 case VariableRequestHandlerState::PENDING: {
737 qCDebug(LOG_VariableController()) << tr("Process Request PENDING")
739 qCDebug(LOG_VariableController()) << tr("Process Request PENDING")
738 << varRequest.m_RangeRequested
740 << varRequest.m_RangeRequested
739 << varRequest.m_CacheRangeRequested;
741 << varRequest.m_CacheRangeRequested;
740 auto variableGroupIdToCancel = varHandler->m_PendingVarRequest.m_VariableGroupId;
742 auto variableGroupIdToCancel = varHandler->m_PendingVarRequest.m_VariableGroupId;
741 cancelVariableRequest(variableGroupIdToCancel);
743 cancelVariableRequest(variableGroupIdToCancel);
742 // Cancel variable can make state downgrade
744 // Cancel variable can make state downgrade
743 varHandler->m_State = VariableRequestHandlerState::PENDING;
745 varHandler->m_State = VariableRequestHandlerState::PENDING;
744 varHandler->m_PendingVarRequest = varRequest;
746 varHandler->m_PendingVarRequest = varRequest;
745
747
746 break;
748 break;
747 }
749 }
748 default:
750 default:
749 qCCritical(LOG_VariableController())
751 qCCritical(LOG_VariableController())
750 << QObject::tr("Unknown VariableRequestHandlerState");
752 << QObject::tr("Unknown VariableRequestHandlerState");
751 }
753 }
752 }
754 }
753
755
754 std::shared_ptr<Variable>
756 std::shared_ptr<Variable>
755 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
757 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
756 {
758 {
757 std::shared_ptr<Variable> var;
759 std::shared_ptr<Variable> var;
758 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
760 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
759
761
760 auto end = m_VariableToIdentifierMap.cend();
762 auto end = m_VariableToIdentifierMap.cend();
761 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
763 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
762 if (it != end) {
764 if (it != end) {
763 var = it->first;
765 var = it->first;
764 }
766 }
765 else {
767 else {
766 qCCritical(LOG_VariableController())
768 qCCritical(LOG_VariableController())
767 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
769 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
768 }
770 }
769
771
770 return var;
772 return var;
771 }
773 }
772
774
773 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
775 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
774 const QVector<AcquisitionDataPacket> acqDataPacketVector)
776 const QVector<AcquisitionDataPacket> acqDataPacketVector)
775 {
777 {
776 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
778 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
777 << acqDataPacketVector.size();
779 << acqDataPacketVector.size();
778 std::shared_ptr<IDataSeries> dataSeries;
780 std::shared_ptr<IDataSeries> dataSeries;
779 if (!acqDataPacketVector.isEmpty()) {
781 if (!acqDataPacketVector.isEmpty()) {
780 dataSeries = acqDataPacketVector[0].m_DateSeries;
782 dataSeries = acqDataPacketVector[0].m_DateSeries;
781 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
783 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
782 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
784 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
783 }
785 }
784 }
786 }
785 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
787 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
786 << acqDataPacketVector.size();
788 << acqDataPacketVector.size();
787 return dataSeries;
789 return dataSeries;
788 }
790 }
789
791
790 void VariableController::VariableControllerPrivate::registerProvider(
792 void VariableController::VariableControllerPrivate::registerProvider(
791 std::shared_ptr<IDataProvider> provider)
793 std::shared_ptr<IDataProvider> provider)
792 {
794 {
793 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
795 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
794 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
796 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
795 << provider->objectName();
797 << provider->objectName();
796 m_ProviderSet.insert(provider);
798 m_ProviderSet.insert(provider);
797 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
799 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
798 &VariableAcquisitionWorker::onVariableDataAcquired);
800 &VariableAcquisitionWorker::onVariableDataAcquired);
799 connect(provider.get(), &IDataProvider::dataProvidedProgress,
801 connect(provider.get(), &IDataProvider::dataProvidedProgress,
800 m_VariableAcquisitionWorker.get(),
802 m_VariableAcquisitionWorker.get(),
801 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
803 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
802 connect(provider.get(), &IDataProvider::dataProvidedFailed,
804 connect(provider.get(), &IDataProvider::dataProvidedFailed,
803 m_VariableAcquisitionWorker.get(),
805 m_VariableAcquisitionWorker.get(),
804 &VariableAcquisitionWorker::onVariableAcquisitionFailed);
806 &VariableAcquisitionWorker::onVariableAcquisitionFailed);
805 }
807 }
806 else {
808 else {
807 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
809 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
808 }
810 }
809 }
811 }
810
812
811 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
813 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
812 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
814 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
813 {
815 {
814 auto itVarHandler = m_VarIdToVarRequestHandler.find(varId);
816 auto itVarHandler = m_VarIdToVarRequestHandler.find(varId);
815 if (itVarHandler == m_VarIdToVarRequestHandler.cend()) {
817 if (itVarHandler == m_VarIdToVarRequestHandler.cend()) {
816 return QUuid();
818 return QUuid();
817 }
819 }
818
820
819 auto varHandler = itVarHandler->second.get();
821 auto varHandler = itVarHandler->second.get();
820 if (varHandler->m_State == VariableRequestHandlerState::OFF) {
822 if (varHandler->m_State == VariableRequestHandlerState::OFF) {
821 qCCritical(LOG_VariableController())
823 qCCritical(LOG_VariableController())
822 << tr("acceptVariableRequest impossible on a variable with OFF state");
824 << tr("acceptVariableRequest impossible on a variable with OFF state");
823 }
825 }
824
826
825 varHandler->m_RunningVarRequest.m_DataSeries = dataSeries;
827 varHandler->m_RunningVarRequest.m_DataSeries = dataSeries;
826 varHandler->m_CanUpdate = true;
828 varHandler->m_CanUpdate = true;
827
829
828 // Element traitΓ©, on a dΓ©jΓ  toutes les donnΓ©es necessaires
830 // Element traitΓ©, on a dΓ©jΓ  toutes les donnΓ©es necessaires
829 auto varGroupId = varHandler->m_RunningVarRequest.m_VariableGroupId;
831 auto varGroupId = varHandler->m_RunningVarRequest.m_VariableGroupId;
830 qCDebug(LOG_VariableController()) << "Variable::acceptVariableRequest" << varGroupId
832 qCDebug(LOG_VariableController()) << "Variable::acceptVariableRequest" << varGroupId
831 << m_VarGroupIdToVarIds.size();
833 << m_VarGroupIdToVarIds.size();
832
834
833 return varHandler->m_RunningVarRequest.m_VariableGroupId;
835 return varHandler->m_RunningVarRequest.m_VariableGroupId;
834 }
836 }
835
837
836 void VariableController::VariableControllerPrivate::updateVariables(QUuid varRequestId)
838 void VariableController::VariableControllerPrivate::updateVariables(QUuid varRequestId)
837 {
839 {
838 qCDebug(LOG_VariableController()) << "VariableControllerPrivate::updateVariables"
840 qCDebug(LOG_VariableController()) << "VariableControllerPrivate::updateVariables"
839 << QThread::currentThread()->objectName() << varRequestId;
841 << QThread::currentThread()->objectName() << varRequestId;
840
842
841 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
843 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
842 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
844 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
843 qCWarning(LOG_VariableController())
845 qCWarning(LOG_VariableController())
844 << tr("Impossible to updateVariables of unknown variables") << varRequestId;
846 << tr("Impossible to updateVariables of unknown variables") << varRequestId;
845 return;
847 return;
846 }
848 }
847
849
848 auto &varIds = varGroupIdToVarIdsIt->second;
850 auto &varIds = varGroupIdToVarIdsIt->second;
849 auto varIdsEnd = varIds.end();
851 auto varIdsEnd = varIds.end();
850 bool processVariableUpdate = true;
852 bool processVariableUpdate = true;
851 qCDebug(LOG_VariableController()) << "VariableControllerPrivate::updateVariables"
853 qCDebug(LOG_VariableController()) << "VariableControllerPrivate::updateVariables"
852 << varRequestId << varIds.size();
854 << varRequestId << varIds.size();
853 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd) && processVariableUpdate;
855 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd) && processVariableUpdate;
854 ++varIdsIt) {
856 ++varIdsIt) {
855 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
857 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
856 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
858 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
857 processVariableUpdate &= itVarHandler->second->m_CanUpdate;
859 processVariableUpdate &= itVarHandler->second->m_CanUpdate;
858 }
860 }
859 }
861 }
860
862
861 if (processVariableUpdate) {
863 if (processVariableUpdate) {
862 qCDebug(LOG_VariableController()) << "Final update OK for the var request" << varIds.size();
864 qCDebug(LOG_VariableController()) << "Final update OK for the var request" << varIds.size();
863 for (auto varIdsIt = varIds.begin(); varIdsIt != varIdsEnd; ++varIdsIt) {
865 for (auto varIdsIt = varIds.begin(); varIdsIt != varIdsEnd; ++varIdsIt) {
864 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
866 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
865 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
867 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
866 if (auto var = findVariable(*varIdsIt)) {
868 if (auto var = findVariable(*varIdsIt)) {
867 auto &varRequest = itVarHandler->second->m_RunningVarRequest;
869 auto &varRequest = itVarHandler->second->m_RunningVarRequest;
868 var->setRange(varRequest.m_RangeRequested);
870 var->setRange(varRequest.m_RangeRequested);
869 var->setCacheRange(varRequest.m_CacheRangeRequested);
871 var->setCacheRange(varRequest.m_CacheRangeRequested);
870 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
872 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
871 << varRequest.m_RangeRequested
873 << varRequest.m_RangeRequested
872 << varRequest.m_CacheRangeRequested;
874 << varRequest.m_CacheRangeRequested;
873 qCDebug(LOG_VariableController()) << tr("2: onDataProvided var points before")
875 qCDebug(LOG_VariableController()) << tr("2: onDataProvided var points before")
874 << var->nbPoints()
876 << var->nbPoints()
875 << varRequest.m_DataSeries->nbPoints();
877 << varRequest.m_DataSeries->nbPoints();
876 var->mergeDataSeries(varRequest.m_DataSeries);
878 var->mergeDataSeries(varRequest.m_DataSeries);
877 qCDebug(LOG_VariableController()) << tr("3: onDataProvided var points after")
879 qCDebug(LOG_VariableController()) << tr("3: onDataProvided var points after")
878 << var->nbPoints();
880 << var->nbPoints();
879
881
880 emit var->updated();
882 emit var->updated();
881 qCDebug(LOG_VariableController()) << tr("Update OK");
883 qCDebug(LOG_VariableController()) << tr("Update OK");
882 }
884 }
883 else {
885 else {
884 qCCritical(LOG_VariableController())
886 qCCritical(LOG_VariableController())
885 << tr("Impossible to update data to a null variable");
887 << tr("Impossible to update data to a null variable");
886 }
888 }
887 }
889 }
888 }
890 }
889 updateVariableRequest(varRequestId);
891 updateVariableRequest(varRequestId);
890
892
891 // cleaning varRequestId
893 // cleaning varRequestId
892 qCDebug(LOG_VariableController()) << tr("m_VarGroupIdToVarIds erase") << varRequestId;
894 qCDebug(LOG_VariableController()) << tr("m_VarGroupIdToVarIds erase") << varRequestId;
893 m_VarGroupIdToVarIds.erase(varRequestId);
895 m_VarGroupIdToVarIds.erase(varRequestId);
894 if (m_VarGroupIdToVarIds.empty()) {
896 if (m_VarGroupIdToVarIds.empty()) {
895 emit q->acquisitionFinished();
897 emit q->acquisitionFinished();
896 }
898 }
897 }
899 }
898 }
900 }
899
901
900
902
901 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
903 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
902 {
904 {
903 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
905 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
904 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
906 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
905 qCCritical(LOG_VariableController()) << QObject::tr(
907 qCCritical(LOG_VariableController()) << QObject::tr(
906 "Impossible to updateVariableRequest since varGroupdId isn't here anymore");
908 "Impossible to updateVariableRequest since varGroupdId isn't here anymore");
907
909
908 return;
910 return;
909 }
911 }
910
912
911 auto &varIds = varGroupIdToVarIdsIt->second;
913 auto &varIds = varGroupIdToVarIdsIt->second;
912 auto varIdsEnd = varIds.end();
914 auto varIdsEnd = varIds.end();
913 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd); ++varIdsIt) {
915 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd); ++varIdsIt) {
914 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
916 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
915 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
917 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
916
918
917 auto varHandler = itVarHandler->second.get();
919 auto varHandler = itVarHandler->second.get();
918 varHandler->m_CanUpdate = false;
920 varHandler->m_CanUpdate = false;
919
921
920
922
921 switch (varHandler->m_State) {
923 switch (varHandler->m_State) {
922 case VariableRequestHandlerState::OFF: {
924 case VariableRequestHandlerState::OFF: {
923 qCCritical(LOG_VariableController())
925 qCCritical(LOG_VariableController())
924 << QObject::tr("Impossible to update a variable with handler in OFF state");
926 << QObject::tr("Impossible to update a variable with handler in OFF state");
925 } break;
927 } break;
926 case VariableRequestHandlerState::RUNNING: {
928 case VariableRequestHandlerState::RUNNING: {
927 varHandler->m_State = VariableRequestHandlerState::OFF;
929 varHandler->m_State = VariableRequestHandlerState::OFF;
928 varHandler->m_RunningVarRequest = VariableRequest{};
930 varHandler->m_RunningVarRequest = VariableRequest{};
929 break;
931 break;
930 }
932 }
931 case VariableRequestHandlerState::PENDING: {
933 case VariableRequestHandlerState::PENDING: {
932 varHandler->m_State = VariableRequestHandlerState::RUNNING;
934 varHandler->m_State = VariableRequestHandlerState::RUNNING;
933 varHandler->m_RunningVarRequest = varHandler->m_PendingVarRequest;
935 varHandler->m_RunningVarRequest = varHandler->m_PendingVarRequest;
934 varHandler->m_PendingVarRequest = VariableRequest{};
936 varHandler->m_PendingVarRequest = VariableRequest{};
935 auto var = findVariable(itVarHandler->first);
937 auto var = findVariable(itVarHandler->first);
936 executeVarRequest(var, varHandler->m_RunningVarRequest);
938 executeVarRequest(var, varHandler->m_RunningVarRequest);
937 updateVariables(varHandler->m_RunningVarRequest.m_VariableGroupId);
939 updateVariables(varHandler->m_RunningVarRequest.m_VariableGroupId);
938 break;
940 break;
939 }
941 }
940 default:
942 default:
941 qCCritical(LOG_VariableController())
943 qCCritical(LOG_VariableController())
942 << QObject::tr("Unknown VariableRequestHandlerState");
944 << QObject::tr("Unknown VariableRequestHandlerState");
943 }
945 }
944 }
946 }
945 }
947 }
946 }
948 }
947
949
948
950
949 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
951 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
950 {
952 {
951 qCDebug(LOG_VariableController()) << tr("cancelVariableRequest") << varRequestId;
953 qCDebug(LOG_VariableController()) << tr("cancelVariableRequest") << varRequestId;
952
954
953 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
955 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
954 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
956 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
955 qCCritical(LOG_VariableController())
957 qCCritical(LOG_VariableController())
956 << tr("Impossible to cancelVariableRequest for unknown varGroupdId") << varRequestId;
958 << tr("Impossible to cancelVariableRequest for unknown varGroupdId") << varRequestId;
957 return;
959 return;
958 }
960 }
959
961
960 auto &varIds = varGroupIdToVarIdsIt->second;
962 auto &varIds = varGroupIdToVarIdsIt->second;
961 auto varIdsEnd = varIds.end();
963 auto varIdsEnd = varIds.end();
962 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd); ++varIdsIt) {
964 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd); ++varIdsIt) {
963 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
965 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
964 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
966 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
965
967
966 auto varHandler = itVarHandler->second.get();
968 auto varHandler = itVarHandler->second.get();
967 varHandler->m_VarId = QUuid{};
969 varHandler->m_VarId = QUuid{};
968 switch (varHandler->m_State) {
970 switch (varHandler->m_State) {
969 case VariableRequestHandlerState::OFF: {
971 case VariableRequestHandlerState::OFF: {
970 qCWarning(LOG_VariableController())
972 qCWarning(LOG_VariableController())
971 << QObject::tr("Impossible to cancel a variable with no running request");
973 << QObject::tr("Impossible to cancel a variable with no running request");
972 break;
974 break;
973 }
975 }
974 case VariableRequestHandlerState::RUNNING: {
976 case VariableRequestHandlerState::RUNNING: {
975
977
976 if (varHandler->m_RunningVarRequest.m_VariableGroupId == varRequestId) {
978 if (varHandler->m_RunningVarRequest.m_VariableGroupId == varRequestId) {
977 auto var = findVariable(itVarHandler->first);
979 auto var = findVariable(itVarHandler->first);
978 auto varProvider = m_VariableToProviderMap.at(var);
980 auto varProvider = m_VariableToProviderMap.at(var);
979 if (varProvider != nullptr) {
981 if (varProvider != nullptr) {
980 m_VariableAcquisitionWorker->abortProgressRequested(
982 m_VariableAcquisitionWorker->abortProgressRequested(
981 itVarHandler->first);
983 itVarHandler->first);
982 }
984 }
983 m_VariableModel->setDataProgress(var, 0.0);
985 m_VariableModel->setDataProgress(var, 0.0);
984 varHandler->m_CanUpdate = false;
986 varHandler->m_CanUpdate = false;
985 varHandler->m_State = VariableRequestHandlerState::OFF;
987 varHandler->m_State = VariableRequestHandlerState::OFF;
986 varHandler->m_RunningVarRequest = VariableRequest{};
988 varHandler->m_RunningVarRequest = VariableRequest{};
987 }
989 }
988 else {
990 else {
989 // TODO: log Impossible to cancel the running variable request beacause its
991 // TODO: log Impossible to cancel the running variable request beacause its
990 // varRequestId isn't not the canceled one
992 // varRequestId isn't not the canceled one
991 }
993 }
992 break;
994 break;
993 }
995 }
994 case VariableRequestHandlerState::PENDING: {
996 case VariableRequestHandlerState::PENDING: {
995 if (varHandler->m_RunningVarRequest.m_VariableGroupId == varRequestId) {
997 if (varHandler->m_RunningVarRequest.m_VariableGroupId == varRequestId) {
996 auto var = findVariable(itVarHandler->first);
998 auto var = findVariable(itVarHandler->first);
997 auto varProvider = m_VariableToProviderMap.at(var);
999 auto varProvider = m_VariableToProviderMap.at(var);
998 if (varProvider != nullptr) {
1000 if (varProvider != nullptr) {
999 m_VariableAcquisitionWorker->abortProgressRequested(
1001 m_VariableAcquisitionWorker->abortProgressRequested(
1000 itVarHandler->first);
1002 itVarHandler->first);
1001 }
1003 }
1002 m_VariableModel->setDataProgress(var, 0.0);
1004 m_VariableModel->setDataProgress(var, 0.0);
1003 varHandler->m_CanUpdate = false;
1005 varHandler->m_CanUpdate = false;
1004 varHandler->m_State = VariableRequestHandlerState::RUNNING;
1006 varHandler->m_State = VariableRequestHandlerState::RUNNING;
1005 varHandler->m_RunningVarRequest = varHandler->m_PendingVarRequest;
1007 varHandler->m_RunningVarRequest = varHandler->m_PendingVarRequest;
1006 varHandler->m_PendingVarRequest = VariableRequest{};
1008 varHandler->m_PendingVarRequest = VariableRequest{};
1007 executeVarRequest(var, varHandler->m_RunningVarRequest);
1009 executeVarRequest(var, varHandler->m_RunningVarRequest);
1008 }
1010 }
1009 else if (varHandler->m_PendingVarRequest.m_VariableGroupId == varRequestId) {
1011 else if (varHandler->m_PendingVarRequest.m_VariableGroupId == varRequestId) {
1010 varHandler->m_State = VariableRequestHandlerState::RUNNING;
1012 varHandler->m_State = VariableRequestHandlerState::RUNNING;
1011 varHandler->m_PendingVarRequest = VariableRequest{};
1013 varHandler->m_PendingVarRequest = VariableRequest{};
1012 }
1014 }
1013 else {
1015 else {
1014 // TODO: log Impossible to cancel the variable request beacause its
1016 // TODO: log Impossible to cancel the variable request beacause its
1015 // varRequestId isn't not the canceled one
1017 // varRequestId isn't not the canceled one
1016 }
1018 }
1017 break;
1019 break;
1018 }
1020 }
1019 default:
1021 default:
1020 qCCritical(LOG_VariableController())
1022 qCCritical(LOG_VariableController())
1021 << QObject::tr("Unknown VariableRequestHandlerState");
1023 << QObject::tr("Unknown VariableRequestHandlerState");
1022 }
1024 }
1023 }
1025 }
1024 }
1026 }
1025 qCDebug(LOG_VariableController()) << tr("cancelVariableRequest: erase") << varRequestId;
1027 qCDebug(LOG_VariableController()) << tr("cancelVariableRequest: erase") << varRequestId;
1026 m_VarGroupIdToVarIds.erase(varRequestId);
1028 m_VarGroupIdToVarIds.erase(varRequestId);
1027 if (m_VarGroupIdToVarIds.empty()) {
1029 if (m_VarGroupIdToVarIds.empty()) {
1028 emit q->acquisitionFinished();
1030 emit q->acquisitionFinished();
1029 }
1031 }
1030 }
1032 }
1031
1033
1032 void VariableController::VariableControllerPrivate::executeVarRequest(std::shared_ptr<Variable> var,
1034 void VariableController::VariableControllerPrivate::executeVarRequest(std::shared_ptr<Variable> var,
1033 VariableRequest &varRequest)
1035 VariableRequest &varRequest)
1034 {
1036 {
1035 qCDebug(LOG_VariableController()) << tr("TORM: executeVarRequest");
1037 qCDebug(LOG_VariableController()) << tr("TORM: executeVarRequest");
1036
1038
1037 auto varIdIt = m_VariableToIdentifierMap.find(var);
1039 auto varIdIt = m_VariableToIdentifierMap.find(var);
1038 if (varIdIt == m_VariableToIdentifierMap.cend()) {
1040 if (varIdIt == m_VariableToIdentifierMap.cend()) {
1039 qCWarning(LOG_VariableController()) << tr(
1041 qCWarning(LOG_VariableController()) << tr(
1040 "Can't execute request of a variable that is not registered (may has been deleted)");
1042 "Can't execute request of a variable that is not registered (may has been deleted)");
1041 return;
1043 return;
1042 }
1044 }
1043
1045
1044 auto varId = varIdIt->second;
1046 auto varId = varIdIt->second;
1045
1047
1046 auto varCacheRange = var->cacheRange();
1048 auto varCacheRange = var->cacheRange();
1047 auto varCacheRangeRequested = varRequest.m_CacheRangeRequested;
1049 auto varCacheRangeRequested = varRequest.m_CacheRangeRequested;
1048 auto notInCacheRangeList
1050 auto notInCacheRangeList
1049 = Variable::provideNotInCacheRangeList(varCacheRange, varCacheRangeRequested);
1051 = Variable::provideNotInCacheRangeList(varCacheRange, varCacheRangeRequested);
1050 auto inCacheRangeList
1052 auto inCacheRangeList
1051 = Variable::provideInCacheRangeList(varCacheRange, varCacheRangeRequested);
1053 = Variable::provideInCacheRangeList(varCacheRange, varCacheRangeRequested);
1052
1054
1053 if (!notInCacheRangeList.empty()) {
1055 if (!notInCacheRangeList.empty()) {
1054
1056
1055 auto varProvider = m_VariableToProviderMap.at(var);
1057 auto varProvider = m_VariableToProviderMap.at(var);
1056 if (varProvider != nullptr) {
1058 if (varProvider != nullptr) {
1057 qCDebug(LOG_VariableController()) << "executeVarRequest " << varRequest.m_RangeRequested
1059 qCDebug(LOG_VariableController()) << "executeVarRequest " << varRequest.m_RangeRequested
1058 << varRequest.m_CacheRangeRequested;
1060 << varRequest.m_CacheRangeRequested;
1059 m_VariableAcquisitionWorker->pushVariableRequest(
1061 m_VariableAcquisitionWorker->pushVariableRequest(
1060 varRequest.m_VariableGroupId, varId, varRequest.m_RangeRequested,
1062 varRequest.m_VariableGroupId, varId, varRequest.m_RangeRequested,
1061 varRequest.m_CacheRangeRequested,
1063 varRequest.m_CacheRangeRequested,
1062 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
1064 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
1063 varProvider);
1065 varProvider);
1064 }
1066 }
1065 else {
1067 else {
1066 qCCritical(LOG_VariableController())
1068 qCCritical(LOG_VariableController())
1067 << "Impossible to provide data with a null provider";
1069 << "Impossible to provide data with a null provider";
1068 }
1070 }
1069
1071
1070 if (!inCacheRangeList.empty()) {
1072 if (!inCacheRangeList.empty()) {
1071 emit q->updateVarDisplaying(var, inCacheRangeList.first());
1073 emit q->updateVarDisplaying(var, inCacheRangeList.first());
1072 }
1074 }
1073 }
1075 }
1074 else {
1076 else {
1075 acceptVariableRequest(varId,
1077 acceptVariableRequest(varId,
1076 var->dataSeries()->subDataSeries(varRequest.m_CacheRangeRequested));
1078 var->dataSeries()->subDataSeries(varRequest.m_CacheRangeRequested));
1077 }
1079 }
1078 }
1080 }
1079
1081
1080 template <typename VariableIterator>
1082 template <typename VariableIterator>
1081 void VariableController::VariableControllerPrivate::desynchronize(VariableIterator variableIt,
1083 void VariableController::VariableControllerPrivate::desynchronize(VariableIterator variableIt,
1082 const QUuid &syncGroupId)
1084 const QUuid &syncGroupId)
1083 {
1085 {
1084 const auto &variable = variableIt->first;
1086 const auto &variable = variableIt->first;
1085 const auto &variableId = variableIt->second;
1087 const auto &variableId = variableIt->second;
1086
1088
1087 // Gets synchronization group
1089 // Gets synchronization group
1088 auto groupIt = m_GroupIdToVariableSynchronizationGroupMap.find(syncGroupId);
1090 auto groupIt = m_GroupIdToVariableSynchronizationGroupMap.find(syncGroupId);
1089 if (groupIt == m_GroupIdToVariableSynchronizationGroupMap.cend()) {
1091 if (groupIt == m_GroupIdToVariableSynchronizationGroupMap.cend()) {
1090 qCCritical(LOG_VariableController())
1092 qCCritical(LOG_VariableController())
1091 << tr("Can't desynchronize variable %1: unknown synchronization group")
1093 << tr("Can't desynchronize variable %1: unknown synchronization group")
1092 .arg(variable->name());
1094 .arg(variable->name());
1093 return;
1095 return;
1094 }
1096 }
1095
1097
1096 // Removes variable from synchronization group
1098 // Removes variable from synchronization group
1097 auto synchronizationGroup = groupIt->second;
1099 auto synchronizationGroup = groupIt->second;
1098 synchronizationGroup->removeVariableId(variableId);
1100 synchronizationGroup->removeVariableId(variableId);
1099
1101
1100 // Removes link between variable and synchronization group
1102 // Removes link between variable and synchronization group
1101 m_VariableIdGroupIdMap.erase(variableId);
1103 m_VariableIdGroupIdMap.erase(variableId);
1102 }
1104 }
@@ -1,384 +1,389
1 #include "Visualization/VisualizationTabWidget.h"
1 #include "Visualization/VisualizationTabWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "ui_VisualizationTabWidget.h"
3 #include "ui_VisualizationTabWidget.h"
4
4
5 #include "Visualization/VisualizationGraphWidget.h"
5 #include "Visualization/VisualizationGraphWidget.h"
6 #include "Visualization/VisualizationZoneWidget.h"
6 #include "Visualization/VisualizationZoneWidget.h"
7
7
8 #include "Visualization/MacScrollBarStyle.h"
8 #include "Visualization/MacScrollBarStyle.h"
9
9
10 #include "DataSource/DataSourceController.h"
10 #include "DataSource/DataSourceController.h"
11 #include "Variable/VariableController.h"
11 #include "Variable/VariableController.h"
12
12
13 #include "Common/MimeTypesDef.h"
13 #include "Common/MimeTypesDef.h"
14
14
15 #include "DragAndDrop/DragDropGuiController.h"
15 #include "DragAndDrop/DragDropGuiController.h"
16 #include "SqpApplication.h"
16 #include "SqpApplication.h"
17
17
18 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
18 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
19
19
20 namespace {
20 namespace {
21
21
22 /**
22 /**
23 * Applies a function to all zones of the tab represented by its layout
23 * Applies a function to all zones of the tab represented by its layout
24 * @param layout the layout that contains zones
24 * @param layout the layout that contains zones
25 * @param fun the function to apply to each zone
25 * @param fun the function to apply to each zone
26 */
26 */
27 template <typename Fun>
27 template <typename Fun>
28 void processZones(QLayout &layout, Fun fun)
28 void processZones(QLayout &layout, Fun fun)
29 {
29 {
30 for (auto i = 0; i < layout.count(); ++i) {
30 for (auto i = 0; i < layout.count(); ++i) {
31 if (auto item = layout.itemAt(i)) {
31 if (auto item = layout.itemAt(i)) {
32 if (auto visualizationZoneWidget
32 if (auto visualizationZoneWidget
33 = qobject_cast<VisualizationZoneWidget *>(item->widget())) {
33 = qobject_cast<VisualizationZoneWidget *>(item->widget())) {
34 fun(*visualizationZoneWidget);
34 fun(*visualizationZoneWidget);
35 }
35 }
36 }
36 }
37 }
37 }
38 }
38 }
39
39
40 /// Generates a default name for a new zone, according to the number of zones already displayed in
40 /// Generates a default name for a new zone, according to the number of zones already displayed in
41 /// the tab
41 /// the tab
42 QString defaultZoneName(QLayout &layout)
42 QString defaultZoneName(QLayout &layout)
43 {
43 {
44 QSet<QString> existingNames;
44 QSet<QString> existingNames;
45 processZones(layout,
45 processZones(layout,
46 [&existingNames](auto &zoneWidget) { existingNames.insert(zoneWidget.name()); });
46 [&existingNames](auto &zoneWidget) { existingNames.insert(zoneWidget.name()); });
47
47
48 int zoneNum = 1;
48 int zoneNum = 1;
49 QString name;
49 QString name;
50 do {
50 do {
51 name = QObject::tr("Zone ").append(QString::number(zoneNum));
51 name = QObject::tr("Zone ").append(QString::number(zoneNum));
52 ++zoneNum;
52 ++zoneNum;
53 } while (existingNames.contains(name));
53 } while (existingNames.contains(name));
54
54
55 return name;
55 return name;
56 }
56 }
57
57
58 } // namespace
58 } // namespace
59
59
60 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
60 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
61 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
61 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
62
62
63 QString m_Name;
63 QString m_Name;
64
64
65 #ifdef Q_OS_MAC
65 #ifdef Q_OS_MAC
66 std::unique_ptr<MacScrollBarStyle> m_MacScrollBarStyle = std::make_unique<MacScrollBarStyle>();
66 std::unique_ptr<MacScrollBarStyle> m_MacScrollBarStyle = std::make_unique<MacScrollBarStyle>();
67 #endif
67 #endif
68
68
69 void dropGraph(int index, VisualizationTabWidget *tabWidget);
69 void dropGraph(int index, VisualizationTabWidget *tabWidget);
70 void dropZone(int index, VisualizationTabWidget *tabWidget);
70 void dropZone(int index, VisualizationTabWidget *tabWidget);
71 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
71 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
72 VisualizationTabWidget *tabWidget);
72 VisualizationTabWidget *tabWidget);
73 void dropProducts(const QVariantList &productsMetaData, int index,
73 void dropProducts(const QVariantList &productsMetaData, int index,
74 VisualizationTabWidget *tabWidget);
74 VisualizationTabWidget *tabWidget);
75 };
75 };
76
76
77 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
77 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
78 : QWidget{parent},
78 : QWidget{parent},
79 ui{new Ui::VisualizationTabWidget},
79 ui{new Ui::VisualizationTabWidget},
80 impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)}
80 impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)}
81 {
81 {
82 ui->setupUi(this);
82 ui->setupUi(this);
83
83
84 #ifdef Q_OS_MAC
84 #ifdef Q_OS_MAC
85 impl->m_MacScrollBarStyle->selfInstallOn(ui->scrollArea, true);
85 impl->m_MacScrollBarStyle->selfInstallOn(ui->scrollArea, true);
86 #endif
86 #endif
87
87
88 ui->dragDropContainer->setPlaceHolderType(DragDropGuiController::PlaceHolderType::Zone, "Zone");
88 ui->dragDropContainer->setPlaceHolderType(DragDropGuiController::PlaceHolderType::Zone, "Zone");
89 ui->dragDropContainer->layout()->setContentsMargins(0, 0, 0, 12);
89 ui->dragDropContainer->layout()->setContentsMargins(0, 0, 0, 12);
90 ui->dragDropContainer->layout()->setSpacing(0);
90 ui->dragDropContainer->layout()->setSpacing(0);
91 ui->dragDropContainer->setMimeType(MIME_TYPE_GRAPH,
91 ui->dragDropContainer->setMimeType(MIME_TYPE_GRAPH,
92 VisualizationDragDropContainer::DropBehavior::Inserted);
92 VisualizationDragDropContainer::DropBehavior::Inserted);
93 ui->dragDropContainer->setMimeType(MIME_TYPE_ZONE,
93 ui->dragDropContainer->setMimeType(MIME_TYPE_ZONE,
94 VisualizationDragDropContainer::DropBehavior::Inserted);
94 VisualizationDragDropContainer::DropBehavior::Inserted);
95 ui->dragDropContainer->setMimeType(MIME_TYPE_VARIABLE_LIST,
95 ui->dragDropContainer->setMimeType(MIME_TYPE_VARIABLE_LIST,
96 VisualizationDragDropContainer::DropBehavior::Inserted);
96 VisualizationDragDropContainer::DropBehavior::Inserted);
97 ui->dragDropContainer->setMimeType(MIME_TYPE_PRODUCT_LIST,
97 ui->dragDropContainer->setMimeType(MIME_TYPE_PRODUCT_LIST,
98 VisualizationDragDropContainer::DropBehavior::Inserted);
98 VisualizationDragDropContainer::DropBehavior::Inserted);
99
99
100 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
100 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
101 return sqpApp->dragDropGuiController().checkMimeDataForVisualization(mimeData,
101 return sqpApp->dragDropGuiController().checkMimeDataForVisualization(mimeData,
102 ui->dragDropContainer);
102 ui->dragDropContainer);
103 });
103 });
104
104
105 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this,
105 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this,
106 &VisualizationTabWidget::dropMimeData);
106 &VisualizationTabWidget::dropMimeData);
107
107
108 sqpApp->dragDropGuiController().addDragDropScrollArea(ui->scrollArea);
108 sqpApp->dragDropGuiController().addDragDropScrollArea(ui->scrollArea);
109
109
110 // Widget is deleted when closed
110 // Widget is deleted when closed
111 setAttribute(Qt::WA_DeleteOnClose);
111 setAttribute(Qt::WA_DeleteOnClose);
112 }
112 }
113
113
114 VisualizationTabWidget::~VisualizationTabWidget()
114 VisualizationTabWidget::~VisualizationTabWidget()
115 {
115 {
116 sqpApp->dragDropGuiController().removeDragDropScrollArea(ui->scrollArea);
116 sqpApp->dragDropGuiController().removeDragDropScrollArea(ui->scrollArea);
117 delete ui;
117 delete ui;
118 }
118 }
119
119
120 void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget)
120 void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget)
121 {
121 {
122 ui->dragDropContainer->addDragWidget(zoneWidget);
122 ui->dragDropContainer->addDragWidget(zoneWidget);
123 }
123 }
124
124
125 void VisualizationTabWidget::insertZone(int index, VisualizationZoneWidget *zoneWidget)
125 void VisualizationTabWidget::insertZone(int index, VisualizationZoneWidget *zoneWidget)
126 {
126 {
127 ui->dragDropContainer->insertDragWidget(index, zoneWidget);
127 ui->dragDropContainer->insertDragWidget(index, zoneWidget);
128 }
128 }
129
129
130 QStringList VisualizationTabWidget::availableZoneWidgets() const
130 QStringList VisualizationTabWidget::availableZoneWidgets() const
131 {
131 {
132 QStringList zones;
132 QStringList zones;
133 processZones(tabLayout(),
133 processZones(tabLayout(),
134 [&zones](VisualizationZoneWidget &zoneWidget) { zones << zoneWidget.name(); });
134 [&zones](VisualizationZoneWidget &zoneWidget) { zones << zoneWidget.name(); });
135
135
136 return zones;
136 return zones;
137 }
137 }
138
138
139 VisualizationZoneWidget *VisualizationTabWidget::getZoneWithName(const QString &zoneName)
139 VisualizationZoneWidget *VisualizationTabWidget::getZoneWithName(const QString &zoneName)
140 {
140 {
141 VisualizationZoneWidget *result = nullptr;
141 VisualizationZoneWidget *result = nullptr;
142 processZones(tabLayout(), [&zoneName, &result](VisualizationZoneWidget &zoneWidget) {
142 processZones(tabLayout(), [&zoneName, &result](VisualizationZoneWidget &zoneWidget) {
143 if (!result && zoneWidget.name() == zoneName) {
143 if (!result && zoneWidget.name() == zoneName) {
144 result = &zoneWidget;
144 result = &zoneWidget;
145 }
145 }
146 });
146 });
147
147
148 return result;
148 return result;
149 }
149 }
150
150
151 VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable)
151 VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable)
152 {
152 {
153 return createZone({variable}, -1);
153 return createZone({variable}, -1);
154 }
154 }
155
155
156 VisualizationZoneWidget *
156 VisualizationZoneWidget *
157 VisualizationTabWidget::createZone(const QList<std::shared_ptr<Variable> > &variables, int index)
157 VisualizationTabWidget::createZone(const QList<std::shared_ptr<Variable> > &variables, int index)
158 {
158 {
159 auto zoneWidget = createEmptyZone(index);
159 auto zoneWidget = createEmptyZone(index);
160
160
161 // Creates a new graph into the zone
161 // Creates a new graph into the zone
162 zoneWidget->createGraph(variables, index);
162 zoneWidget->createGraph(variables, index);
163
163
164 return zoneWidget;
164 return zoneWidget;
165 }
165 }
166
166
167 VisualizationZoneWidget *VisualizationTabWidget::createEmptyZone(int index)
167 VisualizationZoneWidget *VisualizationTabWidget::createEmptyZone(int index)
168 {
168 {
169 auto zoneWidget
169 auto zoneWidget
170 = new VisualizationZoneWidget{defaultZoneName(*ui->dragDropContainer->layout()), this};
170 = new VisualizationZoneWidget{defaultZoneName(*ui->dragDropContainer->layout()), this};
171 this->insertZone(index, zoneWidget);
171 this->insertZone(index, zoneWidget);
172
172
173 return zoneWidget;
173 return zoneWidget;
174 }
174 }
175
175
176 void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor)
176 void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor)
177 {
177 {
178 if (visitor) {
178 if (visitor) {
179 visitor->visitEnter(this);
179 visitor->visitEnter(this);
180
180
181 // Apply visitor to zone children: widgets different from zones are not visited (no action)
181 // Apply visitor to zone children: widgets different from zones are not visited (no action)
182 processZones(tabLayout(), [visitor](VisualizationZoneWidget &zoneWidget) {
182 processZones(tabLayout(), [visitor](VisualizationZoneWidget &zoneWidget) {
183 zoneWidget.accept(visitor);
183 zoneWidget.accept(visitor);
184 });
184 });
185
185
186 visitor->visitLeave(this);
186 visitor->visitLeave(this);
187 }
187 }
188 else {
188 else {
189 qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null");
189 qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null");
190 }
190 }
191 }
191 }
192
192
193 bool VisualizationTabWidget::canDrop(const Variable &variable) const
193 bool VisualizationTabWidget::canDrop(const Variable &variable) const
194 {
194 {
195 // A tab can always accomodate a variable
195 // A tab can always accomodate a variable
196 Q_UNUSED(variable);
196 Q_UNUSED(variable);
197 return true;
197 return true;
198 }
198 }
199
199
200 bool VisualizationTabWidget::contains(const Variable &variable) const
200 bool VisualizationTabWidget::contains(const Variable &variable) const
201 {
201 {
202 Q_UNUSED(variable);
202 Q_UNUSED(variable);
203 return false;
203 return false;
204 }
204 }
205
205
206 QString VisualizationTabWidget::name() const
206 QString VisualizationTabWidget::name() const
207 {
207 {
208 return impl->m_Name;
208 return impl->m_Name;
209 }
209 }
210
210
211 void VisualizationTabWidget::closeEvent(QCloseEvent *event)
211 void VisualizationTabWidget::closeEvent(QCloseEvent *event)
212 {
212 {
213 // Closes zones in the tab
213 // Closes zones in the tab
214 processZones(tabLayout(), [](VisualizationZoneWidget &zoneWidget) { zoneWidget.close(); });
214 processZones(tabLayout(), [](VisualizationZoneWidget &zoneWidget) { zoneWidget.close(); });
215
215
216 QWidget::closeEvent(event);
216 QWidget::closeEvent(event);
217 }
217 }
218
218
219 QLayout &VisualizationTabWidget::tabLayout() const noexcept
219 QLayout &VisualizationTabWidget::tabLayout() const noexcept
220 {
220 {
221 return *ui->dragDropContainer->layout();
221 return *ui->dragDropContainer->layout();
222 }
222 }
223
223
224 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData)
224 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData)
225 {
225 {
226 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
226 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
227 impl->dropGraph(index, this);
227 impl->dropGraph(index, this);
228 }
228 }
229 else if (mimeData->hasFormat(MIME_TYPE_ZONE)) {
229 else if (mimeData->hasFormat(MIME_TYPE_ZONE)) {
230 impl->dropZone(index, this);
230 impl->dropZone(index, this);
231 }
231 }
232 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
232 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
233 auto variables = sqpApp->variableController().variablesForMimeData(
233 auto variables = sqpApp->variableController().variablesForMimeData(
234 mimeData->data(MIME_TYPE_VARIABLE_LIST));
234 mimeData->data(MIME_TYPE_VARIABLE_LIST));
235 impl->dropVariables(variables, index, this);
235 impl->dropVariables(variables, index, this);
236 }
236 }
237 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
237 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
238 auto productsData = sqpApp->dataSourceController().productsDataForMimeData(
238 auto productsData = sqpApp->dataSourceController().productsDataForMimeData(
239 mimeData->data(MIME_TYPE_PRODUCT_LIST));
239 mimeData->data(MIME_TYPE_PRODUCT_LIST));
240 impl->dropProducts(productsData, index, this);
240 impl->dropProducts(productsData, index, this);
241 }
241 }
242 else {
242 else {
243 qCWarning(LOG_VisualizationZoneWidget())
243 qCWarning(LOG_VisualizationZoneWidget())
244 << tr("VisualizationTabWidget::dropMimeData, unknown MIME data received.");
244 << tr("VisualizationTabWidget::dropMimeData, unknown MIME data received.");
245 }
245 }
246 }
246 }
247
247
248 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph(
248 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph(
249 int index, VisualizationTabWidget *tabWidget)
249 int index, VisualizationTabWidget *tabWidget)
250 {
250 {
251 auto &helper = sqpApp->dragDropGuiController();
251 auto &helper = sqpApp->dragDropGuiController();
252
252
253 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
253 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
254 if (!graphWidget) {
254 if (!graphWidget) {
255 qCWarning(LOG_VisualizationZoneWidget())
255 qCWarning(LOG_VisualizationZoneWidget())
256 << tr("VisualizationTabWidget::dropGraph, drop aborted, the dropped graph is not "
256 << tr("VisualizationTabWidget::dropGraph, drop aborted, the dropped graph is not "
257 "found or invalid.");
257 "found or invalid.");
258 Q_ASSERT(false);
258 Q_ASSERT(false);
259 return;
259 return;
260 }
260 }
261
261
262 auto parentDragDropContainer
262 auto parentDragDropContainer
263 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
263 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
264 if (!parentDragDropContainer) {
264 if (!parentDragDropContainer) {
265 qCWarning(LOG_VisualizationZoneWidget())
265 qCWarning(LOG_VisualizationZoneWidget())
266 << tr("VisualizationTabWidget::dropGraph, drop aborted, the parent container of "
266 << tr("VisualizationTabWidget::dropGraph, drop aborted, the parent container of "
267 "the dropped graph is not found.");
267 "the dropped graph is not found.");
268 Q_ASSERT(false);
268 Q_ASSERT(false);
269 return;
269 return;
270 }
270 }
271
271
272 auto nbGraph = parentDragDropContainer->countDragWidget();
272 auto nbGraph = parentDragDropContainer->countDragWidget();
273
273
274 const auto &variables = graphWidget->variables();
274 const auto &variables = graphWidget->variables();
275
275
276 if (!variables.isEmpty()) {
276 if (!variables.isEmpty()) {
277 // Abort the requests for the variables (if any)
277 // Abort the requests for the variables (if any)
278 // Commented, because it's not sure if it's needed or not
278 // Commented, because it's not sure if it's needed or not
279 // for (const auto& var : variables)
279 // for (const auto& var : variables)
280 //{
280 //{
281 // sqpApp->variableController().onAbortProgressRequested(var);
281 // sqpApp->variableController().onAbortProgressRequested(var);
282 //}
282 //}
283
283
284 if (nbGraph == 1) {
284 if (nbGraph == 1) {
285 // This is the only graph in the previous zone, close the zone
285 // This is the only graph in the previous zone, close the zone
286 helper.delayedCloseWidget(graphWidget->parentZoneWidget());
286 helper.delayedCloseWidget(graphWidget->parentZoneWidget());
287 }
287 }
288 else {
288 else {
289 // Close the graph
289 // Close the graph
290 helper.delayedCloseWidget(graphWidget);
290 helper.delayedCloseWidget(graphWidget);
291 }
291 }
292
292
293 auto zoneWidget = tabWidget->createZone(variables, index);
293 auto zoneWidget = tabWidget->createZone(variables, index);
294 auto firstGraph = zoneWidget->firstGraph();
294 auto firstGraph = zoneWidget->firstGraph();
295 if (firstGraph) {
295 if (firstGraph) {
296 firstGraph->addSelectionZones(graphWidget->selectionZoneRanges());
296 firstGraph->addSelectionZones(graphWidget->selectionZoneRanges());
297 }
297 }
298 else {
298 else {
299 qCWarning(LOG_VisualizationZoneWidget())
299 qCWarning(LOG_VisualizationZoneWidget())
300 << tr("VisualizationTabWidget::dropGraph, no graph added in the widget.");
300 << tr("VisualizationTabWidget::dropGraph, no graph added in the widget.");
301 Q_ASSERT(false);
301 Q_ASSERT(false);
302 }
302 }
303 }
303 }
304 else {
304 else {
305 // The graph is empty, create an empty zone and move the graph inside
305 // The graph is empty, create an empty zone and move the graph inside
306
306
307 auto parentZoneWidget = graphWidget->parentZoneWidget();
307 auto parentZoneWidget = graphWidget->parentZoneWidget();
308
308
309 parentDragDropContainer->layout()->removeWidget(graphWidget);
309 parentDragDropContainer->layout()->removeWidget(graphWidget);
310
310
311 auto zoneWidget = tabWidget->createEmptyZone(index);
311 auto zoneWidget = tabWidget->createEmptyZone(index);
312 zoneWidget->addGraph(graphWidget);
312 zoneWidget->addGraph(graphWidget);
313
313
314 // Close the old zone if it was the only graph inside
314 // Close the old zone if it was the only graph inside
315 if (nbGraph == 1) {
315 if (nbGraph == 1) {
316 helper.delayedCloseWidget(parentZoneWidget);
316 helper.delayedCloseWidget(parentZoneWidget);
317 }
317 }
318 }
318 }
319 }
319 }
320
320
321 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropZone(
321 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropZone(
322 int index, VisualizationTabWidget *tabWidget)
322 int index, VisualizationTabWidget *tabWidget)
323 {
323 {
324 auto &helper = sqpApp->dragDropGuiController();
324 auto &helper = sqpApp->dragDropGuiController();
325
325
326 auto zoneWidget = qobject_cast<VisualizationZoneWidget *>(helper.getCurrentDragWidget());
326 auto zoneWidget = qobject_cast<VisualizationZoneWidget *>(helper.getCurrentDragWidget());
327 if (!zoneWidget) {
327 if (!zoneWidget) {
328 qCWarning(LOG_VisualizationZoneWidget())
328 qCWarning(LOG_VisualizationZoneWidget())
329 << tr("VisualizationTabWidget::dropZone, drop aborted, the dropped zone is not "
329 << tr("VisualizationTabWidget::dropZone, drop aborted, the dropped zone is not "
330 "found or invalid.");
330 "found or invalid.");
331 Q_ASSERT(false);
331 Q_ASSERT(false);
332 return;
332 return;
333 }
333 }
334
334
335 auto parentDragDropContainer
335 auto parentDragDropContainer
336 = qobject_cast<VisualizationDragDropContainer *>(zoneWidget->parentWidget());
336 = qobject_cast<VisualizationDragDropContainer *>(zoneWidget->parentWidget());
337 if (!parentDragDropContainer) {
337 if (!parentDragDropContainer) {
338 qCWarning(LOG_VisualizationZoneWidget())
338 qCWarning(LOG_VisualizationZoneWidget())
339 << tr("VisualizationTabWidget::dropZone, drop aborted, the parent container of "
339 << tr("VisualizationTabWidget::dropZone, drop aborted, the parent container of "
340 "the dropped zone is not found.");
340 "the dropped zone is not found.");
341 Q_ASSERT(false);
341 Q_ASSERT(false);
342 return;
342 return;
343 }
343 }
344
344
345 // Simple move of the zone, no variable operation associated
345 // Simple move of the zone, no variable operation associated
346 parentDragDropContainer->layout()->removeWidget(zoneWidget);
346 parentDragDropContainer->layout()->removeWidget(zoneWidget);
347 tabWidget->ui->dragDropContainer->insertDragWidget(index, zoneWidget);
347 tabWidget->ui->dragDropContainer->insertDragWidget(index, zoneWidget);
348 }
348 }
349
349
350 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropVariables(
350 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropVariables(
351 const QList<std::shared_ptr<Variable> > &variables, int index,
351 const QList<std::shared_ptr<Variable> > &variables, int index,
352 VisualizationTabWidget *tabWidget)
352 VisualizationTabWidget *tabWidget)
353 {
353 {
354 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
354 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
355 // compatible variable here
355 // compatible variable here
356 if (variables.count() > 1) {
356 if (variables.count() > 1) {
357 qCWarning(LOG_VisualizationZoneWidget())
357 qCWarning(LOG_VisualizationZoneWidget())
358 << tr("VisualizationTabWidget::dropVariables, dropping multiple variables, operation "
358 << tr("VisualizationTabWidget::dropVariables, dropping multiple variables, operation "
359 "aborted.");
359 "aborted.");
360 return;
360 return;
361 }
361 }
362
362
363 tabWidget->createZone(variables, index);
363 tabWidget->createZone(variables, index);
364 }
364 }
365
365
366 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropProducts(
366 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropProducts(
367 const QVariantList &productsMetaData, int index, VisualizationTabWidget *tabWidget)
367 const QVariantList &productsMetaData, int index, VisualizationTabWidget *tabWidget)
368 {
368 {
369 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
369 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
370 // compatible variable here
370 // compatible variable here
371 if (productsMetaData.count() != 1) {
371 if (productsMetaData.count() != 1) {
372 qCWarning(LOG_VisualizationZoneWidget())
372 qCWarning(LOG_VisualizationZoneWidget())
373 << tr("VisualizationTabWidget::dropProducts, dropping multiple products, operation "
373 << tr("VisualizationTabWidget::dropProducts, dropping multiple products, operation "
374 "aborted.");
374 "aborted.");
375 return;
375 return;
376 }
376 }
377
377
378 auto context = new QObject{tabWidget};
379 connect(&sqpApp->variableController(), &VariableController::variableAdded, context,
380 [this, index, tabWidget, context](auto variable) {
381 tabWidget->createZone({variable}, index);
382 delete context; // removes the connection
383 },
384 Qt::QueuedConnection);
385
378 auto productData = productsMetaData.first().toHash();
386 auto productData = productsMetaData.first().toHash();
379 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
387 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
380 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
388 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
381
382
383 // TODO: add graph
384 }
389 }
@@ -1,639 +1,652
1 #include "Visualization/VisualizationZoneWidget.h"
1 #include "Visualization/VisualizationZoneWidget.h"
2
2
3 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/IVisualizationWidgetVisitor.h"
4 #include "Visualization/QCustomPlotSynchronizer.h"
4 #include "Visualization/QCustomPlotSynchronizer.h"
5 #include "Visualization/VisualizationGraphWidget.h"
5 #include "Visualization/VisualizationGraphWidget.h"
6 #include "Visualization/VisualizationWidget.h"
6 #include "Visualization/VisualizationWidget.h"
7 #include "ui_VisualizationZoneWidget.h"
7 #include "ui_VisualizationZoneWidget.h"
8
8
9 #include "Common/MimeTypesDef.h"
9 #include "Common/MimeTypesDef.h"
10 #include "Common/VisualizationDef.h"
10 #include "Common/VisualizationDef.h"
11
11
12 #include <Data/SqpRange.h>
12 #include <Data/SqpRange.h>
13 #include <DataSource/DataSourceController.h>
13 #include <DataSource/DataSourceController.h>
14 #include <Time/TimeController.h>
14 #include <Time/TimeController.h>
15 #include <Variable/Variable.h>
15 #include <Variable/Variable.h>
16 #include <Variable/VariableController.h>
16 #include <Variable/VariableController.h>
17
17
18 #include <Visualization/operations/FindVariableOperation.h>
18 #include <Visualization/operations/FindVariableOperation.h>
19
19
20 #include <DragAndDrop/DragDropGuiController.h>
20 #include <DragAndDrop/DragDropGuiController.h>
21 #include <QUuid>
21 #include <QUuid>
22 #include <SqpApplication.h>
22 #include <SqpApplication.h>
23 #include <cmath>
23 #include <cmath>
24
24
25 #include <QLayout>
25 #include <QLayout>
26
26
27 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
27 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
28
28
29 namespace {
29 namespace {
30
30
31 /**
31 /**
32 * Applies a function to all graphs of the zone represented by its layout
32 * Applies a function to all graphs of the zone represented by its layout
33 * @param layout the layout that contains graphs
33 * @param layout the layout that contains graphs
34 * @param fun the function to apply to each graph
34 * @param fun the function to apply to each graph
35 */
35 */
36 template <typename Fun>
36 template <typename Fun>
37 void processGraphs(QLayout &layout, Fun fun)
37 void processGraphs(QLayout &layout, Fun fun)
38 {
38 {
39 for (auto i = 0; i < layout.count(); ++i) {
39 for (auto i = 0; i < layout.count(); ++i) {
40 if (auto item = layout.itemAt(i)) {
40 if (auto item = layout.itemAt(i)) {
41 if (auto visualizationGraphWidget
41 if (auto visualizationGraphWidget
42 = qobject_cast<VisualizationGraphWidget *>(item->widget())) {
42 = qobject_cast<VisualizationGraphWidget *>(item->widget())) {
43 fun(*visualizationGraphWidget);
43 fun(*visualizationGraphWidget);
44 }
44 }
45 }
45 }
46 }
46 }
47 }
47 }
48
48
49 /// Generates a default name for a new graph, according to the number of graphs already displayed in
49 /// Generates a default name for a new graph, according to the number of graphs already displayed in
50 /// the zone
50 /// the zone
51 QString defaultGraphName(QLayout &layout)
51 QString defaultGraphName(QLayout &layout)
52 {
52 {
53 QSet<QString> existingNames;
53 QSet<QString> existingNames;
54 processGraphs(
54 processGraphs(
55 layout, [&existingNames](auto &graphWidget) { existingNames.insert(graphWidget.name()); });
55 layout, [&existingNames](auto &graphWidget) { existingNames.insert(graphWidget.name()); });
56
56
57 int zoneNum = 1;
57 int zoneNum = 1;
58 QString name;
58 QString name;
59 do {
59 do {
60 name = QObject::tr("Graph ").append(QString::number(zoneNum));
60 name = QObject::tr("Graph ").append(QString::number(zoneNum));
61 ++zoneNum;
61 ++zoneNum;
62 } while (existingNames.contains(name));
62 } while (existingNames.contains(name));
63
63
64 return name;
64 return name;
65 }
65 }
66
66
67 } // namespace
67 } // namespace
68
68
69 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
69 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
70
70
71 explicit VisualizationZoneWidgetPrivate()
71 explicit VisualizationZoneWidgetPrivate()
72 : m_SynchronisationGroupId{QUuid::createUuid()},
72 : m_SynchronisationGroupId{QUuid::createUuid()},
73 m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
73 m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
74 {
74 {
75 }
75 }
76 QUuid m_SynchronisationGroupId;
76 QUuid m_SynchronisationGroupId;
77 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
77 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
78
78
79 void dropGraph(int index, VisualizationZoneWidget *zoneWidget);
79 void dropGraph(int index, VisualizationZoneWidget *zoneWidget);
80 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
80 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
81 VisualizationZoneWidget *zoneWidget);
81 VisualizationZoneWidget *zoneWidget);
82 void dropProducts(const QVariantList &productsData, int index,
82 void dropProducts(const QVariantList &productsData, int index,
83 VisualizationZoneWidget *zoneWidget);
83 VisualizationZoneWidget *zoneWidget);
84 };
84 };
85
85
86 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
86 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
87 : VisualizationDragWidget{parent},
87 : VisualizationDragWidget{parent},
88 ui{new Ui::VisualizationZoneWidget},
88 ui{new Ui::VisualizationZoneWidget},
89 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
89 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
90 {
90 {
91 ui->setupUi(this);
91 ui->setupUi(this);
92
92
93 ui->zoneNameLabel->setText(name);
93 ui->zoneNameLabel->setText(name);
94
94
95 ui->dragDropContainer->setPlaceHolderType(DragDropGuiController::PlaceHolderType::Graph);
95 ui->dragDropContainer->setPlaceHolderType(DragDropGuiController::PlaceHolderType::Graph);
96 ui->dragDropContainer->setMimeType(MIME_TYPE_GRAPH,
96 ui->dragDropContainer->setMimeType(MIME_TYPE_GRAPH,
97 VisualizationDragDropContainer::DropBehavior::Inserted);
97 VisualizationDragDropContainer::DropBehavior::Inserted);
98 ui->dragDropContainer->setMimeType(
98 ui->dragDropContainer->setMimeType(
99 MIME_TYPE_VARIABLE_LIST, VisualizationDragDropContainer::DropBehavior::InsertedAndMerged);
99 MIME_TYPE_VARIABLE_LIST, VisualizationDragDropContainer::DropBehavior::InsertedAndMerged);
100 ui->dragDropContainer->setMimeType(
100 ui->dragDropContainer->setMimeType(
101 MIME_TYPE_PRODUCT_LIST, VisualizationDragDropContainer::DropBehavior::InsertedAndMerged);
101 MIME_TYPE_PRODUCT_LIST, VisualizationDragDropContainer::DropBehavior::InsertedAndMerged);
102 ui->dragDropContainer->setMimeType(MIME_TYPE_TIME_RANGE,
102 ui->dragDropContainer->setMimeType(MIME_TYPE_TIME_RANGE,
103 VisualizationDragDropContainer::DropBehavior::Merged);
103 VisualizationDragDropContainer::DropBehavior::Merged);
104 ui->dragDropContainer->setMimeType(MIME_TYPE_ZONE,
104 ui->dragDropContainer->setMimeType(MIME_TYPE_ZONE,
105 VisualizationDragDropContainer::DropBehavior::Forbidden);
105 VisualizationDragDropContainer::DropBehavior::Forbidden);
106 ui->dragDropContainer->setMimeType(MIME_TYPE_SELECTION_ZONE,
106 ui->dragDropContainer->setMimeType(MIME_TYPE_SELECTION_ZONE,
107 VisualizationDragDropContainer::DropBehavior::Forbidden);
107 VisualizationDragDropContainer::DropBehavior::Forbidden);
108 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
108 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
109 return sqpApp->dragDropGuiController().checkMimeDataForVisualization(mimeData,
109 return sqpApp->dragDropGuiController().checkMimeDataForVisualization(mimeData,
110 ui->dragDropContainer);
110 ui->dragDropContainer);
111 });
111 });
112
112
113 auto acceptDragWidgetFun = [](auto dragWidget, auto mimeData) {
113 auto acceptDragWidgetFun = [](auto dragWidget, auto mimeData) {
114 if (!mimeData) {
114 if (!mimeData) {
115 return false;
115 return false;
116 }
116 }
117
117
118 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
118 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
119 auto variables = sqpApp->variableController().variablesForMimeData(
119 auto variables = sqpApp->variableController().variablesForMimeData(
120 mimeData->data(MIME_TYPE_VARIABLE_LIST));
120 mimeData->data(MIME_TYPE_VARIABLE_LIST));
121
121
122 if (variables.count() != 1) {
122 if (variables.count() != 1) {
123 return false;
123 return false;
124 }
124 }
125 auto variable = variables.first();
125 auto variable = variables.first();
126
126
127 if (auto graphWidget = dynamic_cast<const VisualizationGraphWidget *>(dragWidget)) {
127 if (auto graphWidget = dynamic_cast<const VisualizationGraphWidget *>(dragWidget)) {
128 return graphWidget->canDrop(*variable);
128 return graphWidget->canDrop(*variable);
129 }
129 }
130 }
130 }
131
131
132 return true;
132 return true;
133 };
133 };
134 ui->dragDropContainer->setAcceptDragWidgetFunction(acceptDragWidgetFun);
134 ui->dragDropContainer->setAcceptDragWidgetFunction(acceptDragWidgetFun);
135
135
136 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this,
136 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this,
137 &VisualizationZoneWidget::dropMimeData);
137 &VisualizationZoneWidget::dropMimeData);
138 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredOnWidget, this,
138 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredOnWidget, this,
139 &VisualizationZoneWidget::dropMimeDataOnGraph);
139 &VisualizationZoneWidget::dropMimeDataOnGraph);
140
140
141 // 'Close' options : widget is deleted when closed
141 // 'Close' options : widget is deleted when closed
142 setAttribute(Qt::WA_DeleteOnClose);
142 setAttribute(Qt::WA_DeleteOnClose);
143 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
143 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
144 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
144 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
145
145
146 // Synchronisation id
146 // Synchronisation id
147 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
147 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
148 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
148 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
149 }
149 }
150
150
151 VisualizationZoneWidget::~VisualizationZoneWidget()
151 VisualizationZoneWidget::~VisualizationZoneWidget()
152 {
152 {
153 delete ui;
153 delete ui;
154 }
154 }
155
155
156 void VisualizationZoneWidget::setZoneRange(const SqpRange &range)
156 void VisualizationZoneWidget::setZoneRange(const SqpRange &range)
157 {
157 {
158 if (auto graph = firstGraph()) {
158 if (auto graph = firstGraph()) {
159 graph->setGraphRange(range);
159 graph->setGraphRange(range);
160 }
160 }
161 else {
161 else {
162 qCWarning(LOG_VisualizationZoneWidget())
162 qCWarning(LOG_VisualizationZoneWidget())
163 << tr("setZoneRange:Cannot set the range of an empty zone.");
163 << tr("setZoneRange:Cannot set the range of an empty zone.");
164 }
164 }
165 }
165 }
166
166
167 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
167 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
168 {
168 {
169 // Synchronize new graph with others in the zone
169 // Synchronize new graph with others in the zone
170 impl->m_Synchronizer->addGraph(*graphWidget);
170 impl->m_Synchronizer->addGraph(*graphWidget);
171
171
172 ui->dragDropContainer->addDragWidget(graphWidget);
172 ui->dragDropContainer->addDragWidget(graphWidget);
173 }
173 }
174
174
175 void VisualizationZoneWidget::insertGraph(int index, VisualizationGraphWidget *graphWidget)
175 void VisualizationZoneWidget::insertGraph(int index, VisualizationGraphWidget *graphWidget)
176 {
176 {
177 // Synchronize new graph with others in the zone
177 // Synchronize new graph with others in the zone
178 impl->m_Synchronizer->addGraph(*graphWidget);
178 impl->m_Synchronizer->addGraph(*graphWidget);
179
179
180 ui->dragDropContainer->insertDragWidget(index, graphWidget);
180 ui->dragDropContainer->insertDragWidget(index, graphWidget);
181 }
181 }
182
182
183 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
183 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
184 {
184 {
185 return createGraph(variable, -1);
185 return createGraph(variable, -1);
186 }
186 }
187
187
188 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable,
188 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable,
189 int index)
189 int index)
190 {
190 {
191 auto graphWidget
191 auto graphWidget
192 = new VisualizationGraphWidget{defaultGraphName(*ui->dragDropContainer->layout()), this};
192 = new VisualizationGraphWidget{defaultGraphName(*ui->dragDropContainer->layout()), this};
193
193
194
194
195 // Set graph properties
195 // Set graph properties
196 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
196 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
197 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
197 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
198
198
199
199
200 // Lambda to synchronize zone widget
200 // Lambda to synchronize zone widget
201 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &graphRange,
201 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &graphRange,
202 const SqpRange &oldGraphRange) {
202 const SqpRange &oldGraphRange) {
203
203
204 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
204 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
205 auto frameLayout = ui->dragDropContainer->layout();
205 auto frameLayout = ui->dragDropContainer->layout();
206 for (auto i = 0; i < frameLayout->count(); ++i) {
206 for (auto i = 0; i < frameLayout->count(); ++i) {
207 auto graphChild
207 auto graphChild
208 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
208 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
209 if (graphChild && (graphChild != graphWidget)) {
209 if (graphChild && (graphChild != graphWidget)) {
210
210
211 auto graphChildRange = graphChild->graphRange();
211 auto graphChildRange = graphChild->graphRange();
212 switch (zoomType) {
212 switch (zoomType) {
213 case AcquisitionZoomType::ZoomIn: {
213 case AcquisitionZoomType::ZoomIn: {
214 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
214 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
215 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
215 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
216 graphChildRange.m_TStart += deltaLeft;
216 graphChildRange.m_TStart += deltaLeft;
217 graphChildRange.m_TEnd -= deltaRight;
217 graphChildRange.m_TEnd -= deltaRight;
218 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
218 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
219 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
219 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
220 << deltaLeft;
220 << deltaLeft;
221 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
221 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
222 << deltaRight;
222 << deltaRight;
223 qCDebug(LOG_VisualizationZoneWidget())
223 qCDebug(LOG_VisualizationZoneWidget())
224 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
224 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
225
225
226 break;
226 break;
227 }
227 }
228
228
229 case AcquisitionZoomType::ZoomOut: {
229 case AcquisitionZoomType::ZoomOut: {
230 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
230 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
231 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
231 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
232 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
232 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
233 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
233 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
234 << deltaLeft;
234 << deltaLeft;
235 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
235 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
236 << deltaRight;
236 << deltaRight;
237 qCDebug(LOG_VisualizationZoneWidget())
237 qCDebug(LOG_VisualizationZoneWidget())
238 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
238 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
239 graphChildRange.m_TStart -= deltaLeft;
239 graphChildRange.m_TStart -= deltaLeft;
240 graphChildRange.m_TEnd += deltaRight;
240 graphChildRange.m_TEnd += deltaRight;
241 break;
241 break;
242 }
242 }
243 case AcquisitionZoomType::PanRight: {
243 case AcquisitionZoomType::PanRight: {
244 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
244 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
245 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
245 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
246 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
246 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
247 graphChildRange.m_TStart += deltaLeft;
247 graphChildRange.m_TStart += deltaLeft;
248 graphChildRange.m_TEnd += deltaRight;
248 graphChildRange.m_TEnd += deltaRight;
249 qCDebug(LOG_VisualizationZoneWidget())
249 qCDebug(LOG_VisualizationZoneWidget())
250 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
250 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
251 break;
251 break;
252 }
252 }
253 case AcquisitionZoomType::PanLeft: {
253 case AcquisitionZoomType::PanLeft: {
254 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
254 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
255 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
255 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
256 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
256 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
257 graphChildRange.m_TStart -= deltaLeft;
257 graphChildRange.m_TStart -= deltaLeft;
258 graphChildRange.m_TEnd -= deltaRight;
258 graphChildRange.m_TEnd -= deltaRight;
259 break;
259 break;
260 }
260 }
261 case AcquisitionZoomType::Unknown: {
261 case AcquisitionZoomType::Unknown: {
262 qCDebug(LOG_VisualizationZoneWidget())
262 qCDebug(LOG_VisualizationZoneWidget())
263 << tr("Impossible to synchronize: zoom type unknown");
263 << tr("Impossible to synchronize: zoom type unknown");
264 break;
264 break;
265 }
265 }
266 default:
266 default:
267 qCCritical(LOG_VisualizationZoneWidget())
267 qCCritical(LOG_VisualizationZoneWidget())
268 << tr("Impossible to synchronize: zoom type not take into account");
268 << tr("Impossible to synchronize: zoom type not take into account");
269 // No action
269 // No action
270 break;
270 break;
271 }
271 }
272 graphChild->setFlags(GraphFlag::DisableAll);
272 graphChild->setFlags(GraphFlag::DisableAll);
273 qCDebug(LOG_VisualizationZoneWidget())
273 qCDebug(LOG_VisualizationZoneWidget())
274 << tr("TORM: Range before: ") << graphChild->graphRange();
274 << tr("TORM: Range before: ") << graphChild->graphRange();
275 qCDebug(LOG_VisualizationZoneWidget())
275 qCDebug(LOG_VisualizationZoneWidget())
276 << tr("TORM: Range after : ") << graphChildRange;
276 << tr("TORM: Range after : ") << graphChildRange;
277 qCDebug(LOG_VisualizationZoneWidget())
277 qCDebug(LOG_VisualizationZoneWidget())
278 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
278 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
279 graphChild->setGraphRange(graphChildRange);
279 graphChild->setGraphRange(graphChildRange);
280 graphChild->setFlags(GraphFlag::EnableAll);
280 graphChild->setFlags(GraphFlag::EnableAll);
281 }
281 }
282 }
282 }
283 };
283 };
284
284
285 // connection for synchronization
285 // connection for synchronization
286 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
286 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
287 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
287 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
288 &VisualizationZoneWidget::onVariableAdded);
288 &VisualizationZoneWidget::onVariableAdded);
289 connect(graphWidget, &VisualizationGraphWidget::variableAboutToBeRemoved, this,
289 connect(graphWidget, &VisualizationGraphWidget::variableAboutToBeRemoved, this,
290 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
290 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
291
291
292 auto range = SqpRange{};
292 auto range = SqpRange{};
293 if (auto firstGraph = this->firstGraph()) {
293 if (auto firstGraph = this->firstGraph()) {
294 // Case of a new graph in a existant zone
294 // Case of a new graph in a existant zone
295 range = firstGraph->graphRange();
295 range = firstGraph->graphRange();
296 }
296 }
297 else {
297 else {
298 // Case of a new graph as the first of the zone
298 // Case of a new graph as the first of the zone
299 range = variable->range();
299 range = variable->range();
300 }
300 }
301
301
302 this->insertGraph(index, graphWidget);
302 this->insertGraph(index, graphWidget);
303
303
304 graphWidget->addVariable(variable, range);
304 graphWidget->addVariable(variable, range);
305 graphWidget->setYRange(variable);
305 graphWidget->setYRange(variable);
306
306
307 return graphWidget;
307 return graphWidget;
308 }
308 }
309
309
310 VisualizationGraphWidget *
310 VisualizationGraphWidget *
311 VisualizationZoneWidget::createGraph(const QList<std::shared_ptr<Variable> > variables, int index)
311 VisualizationZoneWidget::createGraph(const QList<std::shared_ptr<Variable> > variables, int index)
312 {
312 {
313 if (variables.isEmpty()) {
313 if (variables.isEmpty()) {
314 return nullptr;
314 return nullptr;
315 }
315 }
316
316
317 auto graphWidget = createGraph(variables.first(), index);
317 auto graphWidget = createGraph(variables.first(), index);
318 for (auto variableIt = variables.cbegin() + 1; variableIt != variables.cend(); ++variableIt) {
318 for (auto variableIt = variables.cbegin() + 1; variableIt != variables.cend(); ++variableIt) {
319 graphWidget->addVariable(*variableIt, graphWidget->graphRange());
319 graphWidget->addVariable(*variableIt, graphWidget->graphRange());
320 }
320 }
321
321
322 return graphWidget;
322 return graphWidget;
323 }
323 }
324
324
325 VisualizationGraphWidget *VisualizationZoneWidget::firstGraph() const
325 VisualizationGraphWidget *VisualizationZoneWidget::firstGraph() const
326 {
326 {
327 VisualizationGraphWidget *firstGraph = nullptr;
327 VisualizationGraphWidget *firstGraph = nullptr;
328 auto layout = ui->dragDropContainer->layout();
328 auto layout = ui->dragDropContainer->layout();
329 if (layout->count() > 0) {
329 if (layout->count() > 0) {
330 if (auto visualizationGraphWidget
330 if (auto visualizationGraphWidget
331 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
331 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
332 firstGraph = visualizationGraphWidget;
332 firstGraph = visualizationGraphWidget;
333 }
333 }
334 }
334 }
335
335
336 return firstGraph;
336 return firstGraph;
337 }
337 }
338
338
339 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
339 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
340 {
340 {
341 if (visitor) {
341 if (visitor) {
342 visitor->visitEnter(this);
342 visitor->visitEnter(this);
343
343
344 // Apply visitor to graph children: widgets different from graphs are not visited (no
344 // Apply visitor to graph children: widgets different from graphs are not visited (no
345 // action)
345 // action)
346 processGraphs(
346 processGraphs(
347 *ui->dragDropContainer->layout(),
347 *ui->dragDropContainer->layout(),
348 [visitor](VisualizationGraphWidget &graphWidget) { graphWidget.accept(visitor); });
348 [visitor](VisualizationGraphWidget &graphWidget) { graphWidget.accept(visitor); });
349
349
350 visitor->visitLeave(this);
350 visitor->visitLeave(this);
351 }
351 }
352 else {
352 else {
353 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
353 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
354 }
354 }
355 }
355 }
356
356
357 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
357 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
358 {
358 {
359 // A tab can always accomodate a variable
359 // A tab can always accomodate a variable
360 Q_UNUSED(variable);
360 Q_UNUSED(variable);
361 return true;
361 return true;
362 }
362 }
363
363
364 bool VisualizationZoneWidget::contains(const Variable &variable) const
364 bool VisualizationZoneWidget::contains(const Variable &variable) const
365 {
365 {
366 Q_UNUSED(variable);
366 Q_UNUSED(variable);
367 return false;
367 return false;
368 }
368 }
369
369
370 QString VisualizationZoneWidget::name() const
370 QString VisualizationZoneWidget::name() const
371 {
371 {
372 return ui->zoneNameLabel->text();
372 return ui->zoneNameLabel->text();
373 }
373 }
374
374
375 QMimeData *VisualizationZoneWidget::mimeData(const QPoint &position) const
375 QMimeData *VisualizationZoneWidget::mimeData(const QPoint &position) const
376 {
376 {
377 Q_UNUSED(position);
377 Q_UNUSED(position);
378
378
379 auto mimeData = new QMimeData;
379 auto mimeData = new QMimeData;
380 mimeData->setData(MIME_TYPE_ZONE, QByteArray{});
380 mimeData->setData(MIME_TYPE_ZONE, QByteArray{});
381
381
382 if (auto firstGraph = this->firstGraph()) {
382 if (auto firstGraph = this->firstGraph()) {
383 auto timeRangeData = TimeController::mimeDataForTimeRange(firstGraph->graphRange());
383 auto timeRangeData = TimeController::mimeDataForTimeRange(firstGraph->graphRange());
384 mimeData->setData(MIME_TYPE_TIME_RANGE, timeRangeData);
384 mimeData->setData(MIME_TYPE_TIME_RANGE, timeRangeData);
385 }
385 }
386
386
387 return mimeData;
387 return mimeData;
388 }
388 }
389
389
390 bool VisualizationZoneWidget::isDragAllowed() const
390 bool VisualizationZoneWidget::isDragAllowed() const
391 {
391 {
392 return true;
392 return true;
393 }
393 }
394
394
395 void VisualizationZoneWidget::notifyMouseMoveInGraph(const QPointF &graphPosition,
395 void VisualizationZoneWidget::notifyMouseMoveInGraph(const QPointF &graphPosition,
396 const QPointF &plotPosition,
396 const QPointF &plotPosition,
397 VisualizationGraphWidget *graphWidget)
397 VisualizationGraphWidget *graphWidget)
398 {
398 {
399 processGraphs(*ui->dragDropContainer->layout(), [&graphPosition, &plotPosition, &graphWidget](
399 processGraphs(*ui->dragDropContainer->layout(), [&graphPosition, &plotPosition, &graphWidget](
400 VisualizationGraphWidget &processedGraph) {
400 VisualizationGraphWidget &processedGraph) {
401
401
402 switch (sqpApp->plotsCursorMode()) {
402 switch (sqpApp->plotsCursorMode()) {
403 case SqpApplication::PlotsCursorMode::Vertical:
403 case SqpApplication::PlotsCursorMode::Vertical:
404 processedGraph.removeHorizontalCursor();
404 processedGraph.removeHorizontalCursor();
405 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
405 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
406 break;
406 break;
407 case SqpApplication::PlotsCursorMode::Temporal:
407 case SqpApplication::PlotsCursorMode::Temporal:
408 processedGraph.addVerticalCursor(plotPosition.x());
408 processedGraph.addVerticalCursor(plotPosition.x());
409 processedGraph.removeHorizontalCursor();
409 processedGraph.removeHorizontalCursor();
410 break;
410 break;
411 case SqpApplication::PlotsCursorMode::Horizontal:
411 case SqpApplication::PlotsCursorMode::Horizontal:
412 processedGraph.removeVerticalCursor();
412 processedGraph.removeVerticalCursor();
413 if (&processedGraph == graphWidget) {
413 if (&processedGraph == graphWidget) {
414 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
414 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
415 }
415 }
416 else {
416 else {
417 processedGraph.removeHorizontalCursor();
417 processedGraph.removeHorizontalCursor();
418 }
418 }
419 break;
419 break;
420 case SqpApplication::PlotsCursorMode::Cross:
420 case SqpApplication::PlotsCursorMode::Cross:
421 if (&processedGraph == graphWidget) {
421 if (&processedGraph == graphWidget) {
422 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
422 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
423 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
423 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
424 }
424 }
425 else {
425 else {
426 processedGraph.removeHorizontalCursor();
426 processedGraph.removeHorizontalCursor();
427 processedGraph.removeVerticalCursor();
427 processedGraph.removeVerticalCursor();
428 }
428 }
429 break;
429 break;
430 case SqpApplication::PlotsCursorMode::NoCursor:
430 case SqpApplication::PlotsCursorMode::NoCursor:
431 processedGraph.removeHorizontalCursor();
431 processedGraph.removeHorizontalCursor();
432 processedGraph.removeVerticalCursor();
432 processedGraph.removeVerticalCursor();
433 break;
433 break;
434 }
434 }
435
435
436
436
437 });
437 });
438 }
438 }
439
439
440 void VisualizationZoneWidget::notifyMouseLeaveGraph(VisualizationGraphWidget *graphWidget)
440 void VisualizationZoneWidget::notifyMouseLeaveGraph(VisualizationGraphWidget *graphWidget)
441 {
441 {
442 processGraphs(*ui->dragDropContainer->layout(), [](VisualizationGraphWidget &processedGraph) {
442 processGraphs(*ui->dragDropContainer->layout(), [](VisualizationGraphWidget &processedGraph) {
443 processedGraph.removeHorizontalCursor();
443 processedGraph.removeHorizontalCursor();
444 processedGraph.removeVerticalCursor();
444 processedGraph.removeVerticalCursor();
445 });
445 });
446 }
446 }
447
447
448 void VisualizationZoneWidget::closeEvent(QCloseEvent *event)
448 void VisualizationZoneWidget::closeEvent(QCloseEvent *event)
449 {
449 {
450 // Closes graphs in the zone
450 // Closes graphs in the zone
451 processGraphs(*ui->dragDropContainer->layout(),
451 processGraphs(*ui->dragDropContainer->layout(),
452 [](VisualizationGraphWidget &graphWidget) { graphWidget.close(); });
452 [](VisualizationGraphWidget &graphWidget) { graphWidget.close(); });
453
453
454 // Delete synchronization group from variable controller
454 // Delete synchronization group from variable controller
455 QMetaObject::invokeMethod(&sqpApp->variableController(), "onRemoveSynchronizationGroupId",
455 QMetaObject::invokeMethod(&sqpApp->variableController(), "onRemoveSynchronizationGroupId",
456 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
456 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
457
457
458 QWidget::closeEvent(event);
458 QWidget::closeEvent(event);
459 }
459 }
460
460
461 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
461 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
462 {
462 {
463 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
463 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
464 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
464 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
465 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
465 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
466 }
466 }
467
467
468 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable)
468 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable)
469 {
469 {
470 QMetaObject::invokeMethod(&sqpApp->variableController(), "desynchronize", Qt::QueuedConnection,
470 QMetaObject::invokeMethod(&sqpApp->variableController(), "desynchronize", Qt::QueuedConnection,
471 Q_ARG(std::shared_ptr<Variable>, variable),
471 Q_ARG(std::shared_ptr<Variable>, variable),
472 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
472 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
473 }
473 }
474
474
475 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData)
475 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData)
476 {
476 {
477 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
477 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
478 impl->dropGraph(index, this);
478 impl->dropGraph(index, this);
479 }
479 }
480 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
480 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
481 auto variables = sqpApp->variableController().variablesForMimeData(
481 auto variables = sqpApp->variableController().variablesForMimeData(
482 mimeData->data(MIME_TYPE_VARIABLE_LIST));
482 mimeData->data(MIME_TYPE_VARIABLE_LIST));
483 impl->dropVariables(variables, index, this);
483 impl->dropVariables(variables, index, this);
484 }
484 }
485 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
485 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
486 auto products = sqpApp->dataSourceController().productsDataForMimeData(
486 auto products = sqpApp->dataSourceController().productsDataForMimeData(
487 mimeData->data(MIME_TYPE_PRODUCT_LIST));
487 mimeData->data(MIME_TYPE_PRODUCT_LIST));
488 impl->dropProducts(products, index, this);
488 impl->dropProducts(products, index, this);
489 }
489 }
490 else {
490 else {
491 qCWarning(LOG_VisualizationZoneWidget())
491 qCWarning(LOG_VisualizationZoneWidget())
492 << tr("VisualizationZoneWidget::dropMimeData, unknown MIME data received.");
492 << tr("VisualizationZoneWidget::dropMimeData, unknown MIME data received.");
493 }
493 }
494 }
494 }
495
495
496 void VisualizationZoneWidget::dropMimeDataOnGraph(VisualizationDragWidget *dragWidget,
496 void VisualizationZoneWidget::dropMimeDataOnGraph(VisualizationDragWidget *dragWidget,
497 const QMimeData *mimeData)
497 const QMimeData *mimeData)
498 {
498 {
499 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(dragWidget);
499 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(dragWidget);
500 if (!graphWidget) {
500 if (!graphWidget) {
501 qCWarning(LOG_VisualizationZoneWidget())
501 qCWarning(LOG_VisualizationZoneWidget())
502 << tr("VisualizationZoneWidget::dropMimeDataOnGraph, dropping in an unknown widget, "
502 << tr("VisualizationZoneWidget::dropMimeDataOnGraph, dropping in an unknown widget, "
503 "drop aborted");
503 "drop aborted");
504 Q_ASSERT(false);
504 Q_ASSERT(false);
505 return;
505 return;
506 }
506 }
507
507
508 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
508 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
509 auto variables = sqpApp->variableController().variablesForMimeData(
509 auto variables = sqpApp->variableController().variablesForMimeData(
510 mimeData->data(MIME_TYPE_VARIABLE_LIST));
510 mimeData->data(MIME_TYPE_VARIABLE_LIST));
511 for (const auto &var : variables) {
511 for (const auto &var : variables) {
512 graphWidget->addVariable(var, graphWidget->graphRange());
512 graphWidget->addVariable(var, graphWidget->graphRange());
513 }
513 }
514 }
514 }
515 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
515 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
516 auto products = sqpApp->dataSourceController().productsDataForMimeData(
516 auto products = sqpApp->dataSourceController().productsDataForMimeData(
517 mimeData->data(MIME_TYPE_PRODUCT_LIST));
517 mimeData->data(MIME_TYPE_PRODUCT_LIST));
518
518
519 auto context = new QObject{this};
520 connect(&sqpApp->variableController(), &VariableController::variableAdded, context,
521 [this, graphWidget, context](auto variable) {
522 graphWidget->addVariable(variable, graphWidget->graphRange());
523 delete context; // removes the connection
524 },
525 Qt::QueuedConnection);
526
519 auto productData = products.first().toHash();
527 auto productData = products.first().toHash();
520 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
528 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
521 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
529 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
522 }
530 }
523 else if (mimeData->hasFormat(MIME_TYPE_TIME_RANGE)) {
531 else if (mimeData->hasFormat(MIME_TYPE_TIME_RANGE)) {
524 auto range = TimeController::timeRangeForMimeData(mimeData->data(MIME_TYPE_TIME_RANGE));
532 auto range = TimeController::timeRangeForMimeData(mimeData->data(MIME_TYPE_TIME_RANGE));
525 graphWidget->setGraphRange(range);
533 graphWidget->setGraphRange(range);
526 }
534 }
527 else {
535 else {
528 qCWarning(LOG_VisualizationZoneWidget())
536 qCWarning(LOG_VisualizationZoneWidget())
529 << tr("VisualizationZoneWidget::dropMimeDataOnGraph, unknown MIME data received.");
537 << tr("VisualizationZoneWidget::dropMimeDataOnGraph, unknown MIME data received.");
530 }
538 }
531 }
539 }
532
540
533 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
541 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
534 int index, VisualizationZoneWidget *zoneWidget)
542 int index, VisualizationZoneWidget *zoneWidget)
535 {
543 {
536 auto &helper = sqpApp->dragDropGuiController();
544 auto &helper = sqpApp->dragDropGuiController();
537
545
538 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
546 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
539 if (!graphWidget) {
547 if (!graphWidget) {
540 qCWarning(LOG_VisualizationZoneWidget())
548 qCWarning(LOG_VisualizationZoneWidget())
541 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the dropped graph is not "
549 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the dropped graph is not "
542 "found or invalid.");
550 "found or invalid.");
543 Q_ASSERT(false);
551 Q_ASSERT(false);
544 return;
552 return;
545 }
553 }
546
554
547 auto parentDragDropContainer
555 auto parentDragDropContainer
548 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
556 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
549 if (!parentDragDropContainer) {
557 if (!parentDragDropContainer) {
550 qCWarning(LOG_VisualizationZoneWidget())
558 qCWarning(LOG_VisualizationZoneWidget())
551 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the parent container of "
559 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the parent container of "
552 "the dropped graph is not found.");
560 "the dropped graph is not found.");
553 Q_ASSERT(false);
561 Q_ASSERT(false);
554 return;
562 return;
555 }
563 }
556
564
557 const auto &variables = graphWidget->variables();
565 const auto &variables = graphWidget->variables();
558
566
559 if (parentDragDropContainer != zoneWidget->ui->dragDropContainer && !variables.isEmpty()) {
567 if (parentDragDropContainer != zoneWidget->ui->dragDropContainer && !variables.isEmpty()) {
560 // The drop didn't occur in the same zone
568 // The drop didn't occur in the same zone
561
569
562 // Abort the requests for the variables (if any)
570 // Abort the requests for the variables (if any)
563 // Commented, because it's not sure if it's needed or not
571 // Commented, because it's not sure if it's needed or not
564 // for (const auto& var : variables)
572 // for (const auto& var : variables)
565 //{
573 //{
566 // sqpApp->variableController().onAbortProgressRequested(var);
574 // sqpApp->variableController().onAbortProgressRequested(var);
567 //}
575 //}
568
576
569 auto previousParentZoneWidget = graphWidget->parentZoneWidget();
577 auto previousParentZoneWidget = graphWidget->parentZoneWidget();
570 auto nbGraph = parentDragDropContainer->countDragWidget();
578 auto nbGraph = parentDragDropContainer->countDragWidget();
571 if (nbGraph == 1) {
579 if (nbGraph == 1) {
572 // This is the only graph in the previous zone, close the zone
580 // This is the only graph in the previous zone, close the zone
573 helper.delayedCloseWidget(previousParentZoneWidget);
581 helper.delayedCloseWidget(previousParentZoneWidget);
574 }
582 }
575 else {
583 else {
576 // Close the graph
584 // Close the graph
577 helper.delayedCloseWidget(graphWidget);
585 helper.delayedCloseWidget(graphWidget);
578 }
586 }
579
587
580 // Creates the new graph in the zone
588 // Creates the new graph in the zone
581 auto newGraphWidget = zoneWidget->createGraph(variables, index);
589 auto newGraphWidget = zoneWidget->createGraph(variables, index);
582 newGraphWidget->addSelectionZones(graphWidget->selectionZoneRanges());
590 newGraphWidget->addSelectionZones(graphWidget->selectionZoneRanges());
583 }
591 }
584 else {
592 else {
585 // The drop occurred in the same zone or the graph is empty
593 // The drop occurred in the same zone or the graph is empty
586 // Simple move of the graph, no variable operation associated
594 // Simple move of the graph, no variable operation associated
587 parentDragDropContainer->layout()->removeWidget(graphWidget);
595 parentDragDropContainer->layout()->removeWidget(graphWidget);
588
596
589 if (variables.isEmpty() && parentDragDropContainer != zoneWidget->ui->dragDropContainer) {
597 if (variables.isEmpty() && parentDragDropContainer != zoneWidget->ui->dragDropContainer) {
590 // The graph is empty and dropped in a different zone.
598 // The graph is empty and dropped in a different zone.
591 // Take the range of the first graph in the zone (if existing).
599 // Take the range of the first graph in the zone (if existing).
592 auto layout = zoneWidget->ui->dragDropContainer->layout();
600 auto layout = zoneWidget->ui->dragDropContainer->layout();
593 if (layout->count() > 0) {
601 if (layout->count() > 0) {
594 if (auto visualizationGraphWidget
602 if (auto visualizationGraphWidget
595 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
603 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
596 graphWidget->setGraphRange(visualizationGraphWidget->graphRange());
604 graphWidget->setGraphRange(visualizationGraphWidget->graphRange());
597 }
605 }
598 }
606 }
599 }
607 }
600
608
601 zoneWidget->ui->dragDropContainer->insertDragWidget(index, graphWidget);
609 zoneWidget->ui->dragDropContainer->insertDragWidget(index, graphWidget);
602 }
610 }
603 }
611 }
604
612
605 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropVariables(
613 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropVariables(
606 const QList<std::shared_ptr<Variable> > &variables, int index,
614 const QList<std::shared_ptr<Variable> > &variables, int index,
607 VisualizationZoneWidget *zoneWidget)
615 VisualizationZoneWidget *zoneWidget)
608 {
616 {
609 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
617 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
610 // compatible variable here
618 // compatible variable here
611 if (variables.count() > 1) {
619 if (variables.count() > 1) {
612 qCWarning(LOG_VisualizationZoneWidget())
620 qCWarning(LOG_VisualizationZoneWidget())
613 << tr("VisualizationZoneWidget::dropVariables, dropping multiple variables, operation "
621 << tr("VisualizationZoneWidget::dropVariables, dropping multiple variables, operation "
614 "aborted.");
622 "aborted.");
615 return;
623 return;
616 }
624 }
617
625
618 zoneWidget->createGraph(variables, index);
626 zoneWidget->createGraph(variables, index);
619 }
627 }
620
628
621 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropProducts(
629 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropProducts(
622 const QVariantList &productsData, int index, VisualizationZoneWidget *zoneWidget)
630 const QVariantList &productsData, int index, VisualizationZoneWidget *zoneWidget)
623 {
631 {
624 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
632 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
625 // compatible variable here
633 // compatible variable here
626 if (productsData.count() != 1) {
634 if (productsData.count() != 1) {
627 qCWarning(LOG_VisualizationZoneWidget())
635 qCWarning(LOG_VisualizationZoneWidget())
628 << tr("VisualizationTabWidget::dropProducts, dropping multiple products, operation "
636 << tr("VisualizationTabWidget::dropProducts, dropping multiple products, operation "
629 "aborted.");
637 "aborted.");
630 return;
638 return;
631 }
639 }
632
640
641 auto context = new QObject{zoneWidget};
642 connect(&sqpApp->variableController(), &VariableController::variableAdded, context,
643 [this, index, zoneWidget, context](auto variable) {
644 zoneWidget->createGraph(variable, index);
645 delete context; // removes the connection
646 },
647 Qt::QueuedConnection);
648
633 auto productData = productsData.first().toHash();
649 auto productData = productsData.first().toHash();
634 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
650 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
635 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
651 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
636
637
638 // TODO: add graph
639 }
652 }
General Comments 0
You need to be logged in to leave comments. Login now