##// END OF EJS Templates
Variable update signal forwards variable ID...
jeandet -
r32:6b6270b07547
parent child
Show More
@@ -1,112 +1,113
1 #ifndef SCIQLOP_VARIABLE_H
1 #ifndef SCIQLOP_VARIABLE_H
2 #define SCIQLOP_VARIABLE_H
2 #define SCIQLOP_VARIABLE_H
3
3
4 #include <optional>
4 #include <optional>
5
5
6 #include <QLoggingCategory>
6 #include <QLoggingCategory>
7 #include <QObject>
7 #include <QObject>
8 #include <QUuid>
8 #include <QUuid>
9 #include <QReadWriteLock>
9 #include <QReadWriteLock>
10 #include <QDataStream>
10 #include <QDataStream>
11
11
12 #include "CoreGlobal.h"
12 #include "CoreGlobal.h"
13 #include <Data/DataSeriesIterator.h>
13 #include <Data/DataSeriesIterator.h>
14 #include <Data/DataSeriesType.h>
14 #include <Data/DataSeriesType.h>
15 #include <Data/DateTimeRange.h>
15 #include <Data/DateTimeRange.h>
16
16
17
17
18 #include <Common/deprecate.h>
18 #include <Common/deprecate.h>
19 #include <Common/MetaTypes.h>
19 #include <Common/MetaTypes.h>
20 #include <Common/spimpl.h>
20 #include <Common/spimpl.h>
21
21
22 Q_DECLARE_LOGGING_CATEGORY(LOG_Variable)
22 Q_DECLARE_LOGGING_CATEGORY(LOG_Variable)
23
23
24 class IDataSeries;
24 class IDataSeries;
25 class QString;
25 class QString;
26
26
27 /**
27 /**
28 * @brief The Variable class represents a variable in SciQlop.
28 * @brief The Variable class represents a variable in SciQlop.
29 */
29 */
30 class SCIQLOP_CORE_EXPORT Variable : public QObject {
30 class SCIQLOP_CORE_EXPORT Variable : public QObject {
31
31
32 Q_OBJECT
32 Q_OBJECT
33
33
34 public:
34 public:
35 explicit Variable(const QString &name, const QVariantHash &metadata = {});
35 explicit Variable(const QString &name, const QVariantHash &metadata = {});
36
36
37 /// Copy ctor
37 /// Copy ctor
38 explicit Variable(const Variable &other);
38 explicit Variable(const Variable &other);
39
39
40 std::shared_ptr<Variable> clone() const;
40 std::shared_ptr<Variable> clone() const;
41
41
42 QString name() const noexcept;
42 QString name() const noexcept;
43 void setName(const QString &name) noexcept;
43 void setName(const QString &name) noexcept;
44 DateTimeRange range() const noexcept;
44 DateTimeRange range() const noexcept;
45 void setRange(const DateTimeRange &range, bool notify=false) noexcept;
45 void setRange(const DateTimeRange &range, bool notify=false) noexcept;
46 DateTimeRange cacheRange() const noexcept;
46 DateTimeRange cacheRange() const noexcept;
47 void setCacheRange(const DateTimeRange &cacheRange) noexcept;
47 void setCacheRange(const DateTimeRange &cacheRange) noexcept;
48
48
49 /// @return the number of points hold by the variable. The number of points is updated each time
49 /// @return the number of points hold by the variable. The number of points is updated each time
50 /// the data series changes
50 /// the data series changes
51 unsigned int nbPoints() const noexcept;
51 unsigned int nbPoints() const noexcept;
52
52
53 /// Returns the real range of the variable, i.e. the min and max x-axis values of the data
53 /// Returns the real range of the variable, i.e. the min and max x-axis values of the data
54 /// series between the range of the variable. The real range is updated each time the variable
54 /// series between the range of the variable. The real range is updated each time the variable
55 /// range or the data series changed
55 /// range or the data series changed
56 /// @return the real range, invalid range if the data series is null or empty
56 /// @return the real range, invalid range if the data series is null or empty
57 /// @sa setDataSeries()
57 /// @sa setDataSeries()
58 /// @sa setRange()
58 /// @sa setRange()
59 std::optional<DateTimeRange> realRange() const noexcept;
59 std::optional<DateTimeRange> realRange() const noexcept;
60
60
61 /// @return the data of the variable, nullptr if there is no data
61 /// @return the data of the variable, nullptr if there is no data
62 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
62 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
63
63
64 /// @return the type of data that the variable holds
64 /// @return the type of data that the variable holds
65 DataSeriesType type() const noexcept;
65 DataSeriesType type() const noexcept;
66
66
67 QVariantHash metadata() const noexcept;
67 QVariantHash metadata() const noexcept;
68
68
69 void updateData(const std::vector<IDataSeries*>& dataSeries,
69 void updateData(const std::vector<IDataSeries*>& dataSeries,
70 const DateTimeRange& newRange, const DateTimeRange& newCacheRange,
70 const DateTimeRange& newRange, const DateTimeRange& newCacheRange,
71 bool notify=true);
71 bool notify=true);
72
72
73 static QByteArray mimeData(const std::vector<std::shared_ptr<Variable> > &variables)
73 static QByteArray mimeData(const std::vector<std::shared_ptr<Variable> > &variables)
74 {
74 {
75 auto encodedData = QByteArray{};
75 auto encodedData = QByteArray{};
76 QDataStream stream{&encodedData, QIODevice::WriteOnly};
76 QDataStream stream{&encodedData, QIODevice::WriteOnly};
77 for (auto &var : variables) {
77 for (auto &var : variables) {
78 stream << var->ID().toByteArray();
78 stream << var->ID().toByteArray();
79 }
79 }
80 return encodedData;
80 return encodedData;
81 }
81 }
82
82
83 static std::vector<QUuid> variablesIDs(QByteArray mimeData)
83 static std::vector<QUuid> variablesIDs(QByteArray mimeData)
84 {
84 {
85 std::vector<QUuid> variables;
85 std::vector<QUuid> variables;
86 QDataStream stream{mimeData};
86 QDataStream stream{mimeData};
87
87
88 QVariantList ids;
88 QVariantList ids;
89 stream >> ids;
89 stream >> ids;
90
90
91 for (const auto& id : ids) {
91 for (const auto& id : ids) {
92 variables.emplace_back (id.toByteArray());
92 variables.emplace_back (id.toByteArray());
93 }
93 }
94 return variables;
94 return variables;
95 }
95 }
96
96
97 operator QUuid() {return _uuid;}
97 operator QUuid() {return _uuid;}
98 QUuid ID(){return _uuid;}
98 QUuid ID(){return _uuid;}
99 signals:
99 signals:
100 void updated();
100 void updated(QUuid ID);
101
101 private:
102 private:
102 class VariablePrivate;
103 class VariablePrivate;
103 spimpl::unique_impl_ptr<VariablePrivate> impl;
104 spimpl::unique_impl_ptr<VariablePrivate> impl;
104 QUuid _uuid;
105 QUuid _uuid;
105 QReadWriteLock m_lock;
106 QReadWriteLock m_lock;
106 };
107 };
107
108
108 // Required for using shared_ptr in signals/slots
109 // Required for using shared_ptr in signals/slots
109 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
110 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
110 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY, QVector<std::shared_ptr<Variable> >)
111 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY, QVector<std::shared_ptr<Variable> >)
111
112
112 #endif // SCIQLOP_VARIABLE_H
113 #endif // SCIQLOP_VARIABLE_H
@@ -1,68 +1,68
1 #ifndef SCIQLOP_VARIABLEMODEL2_H
1 #ifndef SCIQLOP_VARIABLEMODEL2_H
2 #define SCIQLOP_VARIABLEMODEL2_H
2 #define SCIQLOP_VARIABLEMODEL2_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/DateTimeRange.h>
6 #include <Data/DateTimeRange.h>
7
7
8 #include <QAbstractTableModel>
8 #include <QAbstractTableModel>
9 #include <QLoggingCategory>
9 #include <QLoggingCategory>
10
10
11 #include <Common/MetaTypes.h>
11 #include <Common/MetaTypes.h>
12 #include <Common/spimpl.h>
12 #include <Common/spimpl.h>
13
13
14
14
15
15
16 class IDataSeries;
16 class IDataSeries;
17 class Variable;
17 class Variable;
18 class VariableController2;
18 class VariableController2;
19
19
20 enum VariableRoles { ProgressRole = Qt::UserRole };
20 enum VariableRoles { ProgressRole = Qt::UserRole };
21
21
22 /**
22 /**
23 * @brief The VariableModel class aims to hold the variables that have been created in SciQlop
23 * @brief The VariableModel class aims to hold the variables that have been created in SciQlop
24 */
24 */
25 class SCIQLOP_CORE_EXPORT VariableModel2 : public QAbstractTableModel {
25 class SCIQLOP_CORE_EXPORT VariableModel2 : public QAbstractTableModel {
26 Q_OBJECT
26 Q_OBJECT
27 // read only mirror of VariableController2 content
27 // read only mirror of VariableController2 content
28 std::vector<std::shared_ptr<Variable>> _variables;
28 std::vector<std::shared_ptr<Variable>> _variables;
29 public:
29 public:
30 explicit VariableModel2(QObject *parent = nullptr);
30 explicit VariableModel2(QObject *parent = nullptr);
31
31
32 // /////////////////////////// //
32 // /////////////////////////// //
33 // QAbstractTableModel methods //
33 // QAbstractTableModel methods //
34 // /////////////////////////// //
34 // /////////////////////////// //
35
35
36 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
36 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
37 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
37 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
38 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
38 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
39 virtual QVariant headerData(int section, Qt::Orientation orientation,
39 virtual QVariant headerData(int section, Qt::Orientation orientation,
40 int role = Qt::DisplayRole) const override;
40 int role = Qt::DisplayRole) const override;
41 virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
41 virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
42
42
43 // ///////////////// //
43 // ///////////////// //
44 // Drag&Drop methods //
44 // Drag&Drop methods //
45 // ///////////////// //
45 // ///////////////// //
46
46
47 virtual Qt::DropActions supportedDropActions() const override;
47 virtual Qt::DropActions supportedDropActions() const override;
48 virtual Qt::DropActions supportedDragActions() const override;
48 virtual Qt::DropActions supportedDragActions() const override;
49 virtual QStringList mimeTypes() const override;
49 virtual QStringList mimeTypes() const override;
50 virtual QMimeData *mimeData(const QModelIndexList &indexes) const override;
50 virtual QMimeData *mimeData(const QModelIndexList &indexes) const override;
51 virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
51 virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
52 const QModelIndex &parent) const override;
52 const QModelIndex &parent) const override;
53 virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
53 virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
54 const QModelIndex &parent) override;
54 const QModelIndex &parent) override;
55 const std::vector<std::shared_ptr<Variable>>& variables() const
55 const std::vector<std::shared_ptr<Variable>>& variables() const
56 {return _variables;}
56 {return _variables;}
57
57
58 signals:
58 signals:
59 void createVariable(const QVariantHash &productData);
59 void createVariable(const QVariantHash &productData);
60 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
60 void asyncChangeRange(const std::shared_ptr<Variable>& variable, const DateTimeRange& r);
61 public slots:
61 public slots:
62 /// Slot called when data of a variable has been updated
62 /// Slot called when data of a variable has been updated
63 void variableUpdated() noexcept;
63 void variableUpdated(QUuid id) noexcept;
64 void variableAdded(const std::shared_ptr<Variable>&);
64 void variableAdded(const std::shared_ptr<Variable>&);
65 void variableDeleted(const std::shared_ptr<Variable>&);
65 void variableDeleted(const std::shared_ptr<Variable>&);
66 };
66 };
67
67
68 #endif // SCIQLOP_VARIABLEMODEL2_H
68 #endif // SCIQLOP_VARIABLEMODEL2_H
@@ -1,214 +1,212
1 #include <optional>
1 #include <optional>
2 #include <QMutex>
2 #include <QMutex>
3 #include <QReadWriteLock>
3 #include <QReadWriteLock>
4 #include <QThread>
4 #include <QThread>
5
5
6 #include "Variable/Variable.h"
6 #include "Variable/Variable.h"
7
7
8 #include <Data/IDataSeries.h>
8 #include <Data/IDataSeries.h>
9 #include <Data/DateTimeRange.h>
9 #include <Data/DateTimeRange.h>
10
10
11 #include <Common/debug.h>
11 #include <Common/debug.h>
12
12
13 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
13 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
14
14
15
15
16 /**
16 /**
17 * Searches in metadata for a value that can be converted to DataSeriesType
17 * Searches in metadata for a value that can be converted to DataSeriesType
18 * @param metadata the metadata where to search
18 * @param metadata the metadata where to search
19 * @return the value converted to a DataSeriesType if it was found, UNKNOWN type otherwise
19 * @return the value converted to a DataSeriesType if it was found, UNKNOWN type otherwise
20 * @sa DataSeriesType
20 * @sa DataSeriesType
21 */
21 */
22 static DataSeriesType findDataSeriesType(const QVariantHash &metadata)
22 static DataSeriesType findDataSeriesType(const QVariantHash &metadata)
23 {
23 {
24 auto dataSeriesType = DataSeriesType::UNKNOWN;
24 auto dataSeriesType = DataSeriesType::UNKNOWN;
25
25
26 // Go through the metadata and stop at the first value that could be converted to DataSeriesType
26 // Go through the metadata and stop at the first value that could be converted to DataSeriesType
27 for (auto it = metadata.cbegin(), end = metadata.cend();
27 for (auto it = metadata.cbegin(), end = metadata.cend();
28 it != end && dataSeriesType == DataSeriesType::UNKNOWN; ++it) {
28 it != end && dataSeriesType == DataSeriesType::UNKNOWN; ++it) {
29 dataSeriesType = DataSeriesTypeUtils::fromString(it.value().toString());
29 dataSeriesType = DataSeriesTypeUtils::fromString(it.value().toString());
30 }
30 }
31
31
32 return dataSeriesType;
32 return dataSeriesType;
33 }
33 }
34
34
35
35
36 #define VP_PROPERTY(property,getter,setter,type) \
36 #define VP_PROPERTY(property,getter,setter,type) \
37 type getter() noexcept\
37 type getter() noexcept\
38 {\
38 {\
39 QReadLocker lock{&m_Lock};\
39 QReadLocker lock{&m_Lock};\
40 return property;\
40 return property;\
41 }\
41 }\
42 void setter(const type& getter) noexcept\
42 void setter(const type& getter) noexcept\
43 {\
43 {\
44 QWriteLocker lock{&m_Lock};\
44 QWriteLocker lock{&m_Lock};\
45 property = getter;\
45 property = getter;\
46 }\
46 }\
47 type property;\
47 type property;\
48
48
49 #define V_FW_GETTER_SETTER(getter,setter, type)\
49 #define V_FW_GETTER_SETTER(getter,setter, type)\
50 type Variable::getter() const noexcept \
50 type Variable::getter() const noexcept \
51 {\
51 {\
52 return impl->getter();\
52 return impl->getter();\
53 }\
53 }\
54 void Variable::setter(const type& getter) noexcept \
54 void Variable::setter(const type& getter) noexcept \
55 {\
55 {\
56 impl->setter(getter);\
56 impl->setter(getter);\
57 emit updated();\
57 emit updated(this->ID());\
58 }\
58 }\
59
59
60 struct Variable::VariablePrivate {
60 struct Variable::VariablePrivate {
61 explicit VariablePrivate(const QString &name, const QVariantHash &metadata)
61 explicit VariablePrivate(const QString &name, const QVariantHash &metadata)
62 : m_Name{name},
62 : m_Name{name},
63 m_Range{INVALID_RANGE},
63 m_Range{INVALID_RANGE},
64 m_CacheRange{INVALID_RANGE},
64 m_CacheRange{INVALID_RANGE},
65 m_Metadata{metadata},
65 m_Metadata{metadata},
66 m_DataSeries{nullptr},
66 m_DataSeries{nullptr},
67 m_RealRange{INVALID_RANGE},
67 m_RealRange{INVALID_RANGE},
68 m_NbPoints{0},
68 m_NbPoints{0},
69 m_Type{findDataSeriesType(m_Metadata)}
69 m_Type{findDataSeriesType(m_Metadata)}
70 {
70 {
71 }
71 }
72
72
73 VariablePrivate(const VariablePrivate &other)
73 VariablePrivate(const VariablePrivate &other)
74 : m_Name{other.m_Name},
74 : m_Name{other.m_Name},
75 m_Range{other.m_Range},
75 m_Range{other.m_Range},
76 m_CacheRange{other.m_CacheRange},
76 m_CacheRange{other.m_CacheRange},
77 m_Metadata{other.m_Metadata},
77 m_Metadata{other.m_Metadata},
78 m_DataSeries{other.m_DataSeries != nullptr ? other.m_DataSeries->clone() : nullptr},
78 m_DataSeries{other.m_DataSeries != nullptr ? other.m_DataSeries->clone() : nullptr},
79 m_RealRange{other.m_RealRange},
79 m_RealRange{other.m_RealRange},
80 m_NbPoints{other.m_NbPoints},
80 m_NbPoints{other.m_NbPoints},
81 m_Type{findDataSeriesType(m_Metadata)}
81 m_Type{findDataSeriesType(m_Metadata)}
82 {
82 {
83 }
83 }
84
84
85 void lockRead() { m_Lock.lockForRead(); }
85 void lockRead() { m_Lock.lockForRead(); }
86 void lockWrite() { m_Lock.lockForWrite(); }
86 void lockWrite() { m_Lock.lockForWrite(); }
87 void unlock() { m_Lock.unlock(); }
87 void unlock() { m_Lock.unlock(); }
88
88
89 void purgeDataSeries()
89 void purgeDataSeries()
90 {
90 {
91 if (m_DataSeries) {
91 if (m_DataSeries) {
92 m_DataSeries->purge(m_CacheRange.m_TStart, m_CacheRange.m_TEnd);
92 m_DataSeries->purge(m_CacheRange.m_TStart, m_CacheRange.m_TEnd);
93 }
93 }
94 updateRealRange();
94 updateRealRange();
95 updateNbPoints();
95 updateNbPoints();
96 }
96 }
97 void mergeDataSeries(const std::vector<IDataSeries*>& dataseries)
97 void mergeDataSeries(const std::vector<IDataSeries*>& dataseries)
98 {
98 {
99 QWriteLocker lock{&m_Lock};
99 QWriteLocker lock{&m_Lock};
100 for(auto ds:dataseries)
100 for(auto ds:dataseries)
101 {
101 {
102 if(m_DataSeries)
102 if(m_DataSeries)
103 m_DataSeries->merge(ds);
103 m_DataSeries->merge(ds);
104 else
104 else
105 m_DataSeries = ds->clone();
105 m_DataSeries = ds->clone();
106 }
106 }
107 }
107 }
108 void updateNbPoints() { m_NbPoints = m_DataSeries ? m_DataSeries->nbPoints() : 0; }
108 void updateNbPoints() { m_NbPoints = m_DataSeries ? m_DataSeries->nbPoints() : 0; }
109
109
110 /// Updates real range according to current variable range and data series
110 /// Updates real range according to current variable range and data series
111 void updateRealRange()
111 void updateRealRange()
112 {
112 {
113 if (m_DataSeries) {
113 if (m_DataSeries) {
114 auto lock = m_DataSeries->getReadLock();
114 auto lock = m_DataSeries->getReadLock();
115 auto end = m_DataSeries->cend();
115 auto end = m_DataSeries->cend();
116 auto minXAxisIt = m_DataSeries->minXAxisData(m_Range.m_TStart);
116 auto minXAxisIt = m_DataSeries->minXAxisData(m_Range.m_TStart);
117 auto maxXAxisIt = m_DataSeries->maxXAxisData(m_Range.m_TEnd);
117 auto maxXAxisIt = m_DataSeries->maxXAxisData(m_Range.m_TEnd);
118 if(minXAxisIt != end && maxXAxisIt != end && minXAxisIt->x() <= maxXAxisIt->x())
118 if(minXAxisIt != end && maxXAxisIt != end && minXAxisIt->x() <= maxXAxisIt->x())
119 m_RealRange = DateTimeRange{minXAxisIt->x(), maxXAxisIt->x()};
119 m_RealRange = DateTimeRange{minXAxisIt->x(), maxXAxisIt->x()};
120 else
120 else
121 m_RealRange = std::nullopt;
121 m_RealRange = std::nullopt;
122 }
122 }
123 else {
123 else {
124 m_RealRange = std::nullopt;
124 m_RealRange = std::nullopt;
125 }
125 }
126 }
126 }
127
127
128 VP_PROPERTY(m_Name, name, setName, QString)
128 VP_PROPERTY(m_Name, name, setName, QString)
129 VP_PROPERTY(m_Range, range, setRange, DateTimeRange)
129 VP_PROPERTY(m_Range, range, setRange, DateTimeRange)
130 VP_PROPERTY(m_CacheRange, cacheRange, setCacheRange, DateTimeRange)
130 VP_PROPERTY(m_CacheRange, cacheRange, setCacheRange, DateTimeRange)
131 VP_PROPERTY(m_Metadata, metadata, setMetadata, QVariantHash)
131 VP_PROPERTY(m_Metadata, metadata, setMetadata, QVariantHash)
132 VP_PROPERTY(m_DataSeries, dataSeries, setDataSeries, std::shared_ptr<IDataSeries>)
132 VP_PROPERTY(m_DataSeries, dataSeries, setDataSeries, std::shared_ptr<IDataSeries>)
133 VP_PROPERTY(m_RealRange, realRange, setRealRange, std::optional<DateTimeRange>)
133 VP_PROPERTY(m_RealRange, realRange, setRealRange, std::optional<DateTimeRange>)
134 unsigned int m_NbPoints;
134 unsigned int m_NbPoints;
135 VP_PROPERTY(m_Type, type, setType, DataSeriesType)
135 VP_PROPERTY(m_Type, type, setType, DataSeriesType)
136 QReadWriteLock m_Lock;
136 QReadWriteLock m_Lock;
137 };
137 };
138
138
139 Variable::Variable(const QString &name, const QVariantHash &metadata)
139 Variable::Variable(const QString &name, const QVariantHash &metadata)
140 : impl{spimpl::make_unique_impl<VariablePrivate>(name, metadata)},
140 : impl{spimpl::make_unique_impl<VariablePrivate>(name, metadata)},
141 _uuid{QUuid::createUuid()}
141 _uuid{QUuid::createUuid()}
142 {
142 {
143 }
143 }
144
144
145 Variable::Variable(const Variable &other)
145 Variable::Variable(const Variable &other)
146 : impl{spimpl::make_unique_impl<VariablePrivate>(*other.impl)},
146 : impl{spimpl::make_unique_impl<VariablePrivate>(*other.impl)},
147 _uuid{QUuid::createUuid()} //is a clone but must have a != uuid
147 _uuid{QUuid::createUuid()} //is a clone but must have a != uuid
148 {
148 {
149 }
149 }
150
150
151 std::shared_ptr<Variable> Variable::clone() const
151 std::shared_ptr<Variable> Variable::clone() const
152 {
152 {
153 return std::make_shared<Variable>(*this);
153 return std::make_shared<Variable>(*this);
154 }
154 }
155
155
156 V_FW_GETTER_SETTER(name,setName,QString)
156 V_FW_GETTER_SETTER(name,setName,QString)
157
157
158 DateTimeRange Variable::range() const noexcept
158 DateTimeRange Variable::range() const noexcept
159 {
159 {
160 return impl->range();
160 return impl->range();
161 }
161 }
162
162
163 void Variable::setRange(const DateTimeRange &range, bool notify) noexcept
163 void Variable::setRange(const DateTimeRange &range, bool notify) noexcept
164 {
164 {
165 impl->setRange(range);
165 impl->setRange(range);
166 impl->updateRealRange();
166 impl->updateRealRange();
167 if(notify)
167 if(notify)
168 emit this->updated();
168 emit this->updated(this->ID());
169 }
169 }
170
170
171 V_FW_GETTER_SETTER(cacheRange, setCacheRange, DateTimeRange)
171 V_FW_GETTER_SETTER(cacheRange, setCacheRange, DateTimeRange)
172
172
173 unsigned int Variable::nbPoints() const noexcept
173 unsigned int Variable::nbPoints() const noexcept
174 {
174 {
175 return impl->m_NbPoints;
175 return impl->m_NbPoints;
176 }
176 }
177
177
178 std::optional<DateTimeRange> Variable::realRange() const noexcept
178 std::optional<DateTimeRange> Variable::realRange() const noexcept
179 {
179 {
180 return impl->realRange();
180 return impl->realRange();
181 }
181 }
182
182
183 void Variable::updateData(const std::vector<IDataSeries *> &dataSeries, const DateTimeRange &newRange, const DateTimeRange &newCacheRange, bool notify)
183 void Variable::updateData(const std::vector<IDataSeries *> &dataSeries, const DateTimeRange &newRange, const DateTimeRange &newCacheRange, bool notify)
184 {
184 {
185 {
185 {
186 QWriteLocker lock{&m_lock};
186 QWriteLocker lock{&m_lock};
187 impl->mergeDataSeries(dataSeries);
187 impl->mergeDataSeries(dataSeries);
188 impl->setRange(newRange);
188 impl->setRange(newRange);
189 impl->setCacheRange(newCacheRange);
189 impl->setCacheRange(newCacheRange);
190 impl->purgeDataSeries();
190 impl->purgeDataSeries();
191 }
191 }
192 if(notify)
192 if(notify)
193 emit updated();
193 emit updated(this->ID());
194 }
194 }
195
195
196
197 std::shared_ptr<IDataSeries> Variable::dataSeries() const noexcept
196 std::shared_ptr<IDataSeries> Variable::dataSeries() const noexcept
198 {
197 {
199 return impl->dataSeries();
198 return impl->dataSeries();
200 }
199 }
201
200
202 DataSeriesType Variable::type() const noexcept
201 DataSeriesType Variable::type() const noexcept
203 {
202 {
204 return impl->type();
203 return impl->type();
205 }
204 }
206
205
207 QVariantHash Variable::metadata() const noexcept
206 QVariantHash Variable::metadata() const noexcept
208 {
207 {
209 impl->lockRead();
208 impl->lockRead();
210 auto metadata = impl->m_Metadata;
209 auto metadata = impl->m_Metadata;
211 impl->unlock();
210 impl->unlock();
212 return metadata;
211 return metadata;
213 }
212 }
214
@@ -1,270 +1,270
1 #include <QMimeData>
1 #include <QMimeData>
2 #include <QSize>
2 #include <QSize>
3 #include <QTimer>
3 #include <QTimer>
4 #include <unordered_map>
4 #include <unordered_map>
5
5
6 #include <Variable/Variable.h>
6 #include <Variable/Variable.h>
7 #include <Variable/VariableController2.h>
7 #include <Variable/VariableController2.h>
8 #include <Variable/VariableModel2.h>
8 #include <Variable/VariableModel2.h>
9
9
10 #include <Common/DateUtils.h>
10 #include <Common/DateUtils.h>
11 #include <Common/MimeTypesDef.h>
11 #include <Common/MimeTypesDef.h>
12 #include <Common/StringUtils.h>
12 #include <Common/StringUtils.h>
13 #include <Common/containers.h>
13 #include <Common/containers.h>
14
14
15 #include <Data/IDataSeries.h>
15 #include <Data/IDataSeries.h>
16
16
17 #include <DataSource/DataSourceController.h>
17 #include <DataSource/DataSourceController.h>
18 #include <Time/TimeController.h>
18 #include <Time/TimeController.h>
19
19
20 namespace {
20 namespace {
21
21
22 // Column indexes
22 // Column indexes
23 const auto NAME_COLUMN = 0;
23 const auto NAME_COLUMN = 0;
24 const auto TSTART_COLUMN = 1;
24 const auto TSTART_COLUMN = 1;
25 const auto TEND_COLUMN = 2;
25 const auto TEND_COLUMN = 2;
26 const auto NBPOINTS_COLUMN = 3;
26 const auto NBPOINTS_COLUMN = 3;
27 const auto UNIT_COLUMN = 4;
27 const auto UNIT_COLUMN = 4;
28 const auto MISSION_COLUMN = 5;
28 const auto MISSION_COLUMN = 5;
29 const auto PLUGIN_COLUMN = 6;
29 const auto PLUGIN_COLUMN = 6;
30 const auto NB_COLUMNS = 7;
30 const auto NB_COLUMNS = 7;
31
31
32 // Column properties
32 // Column properties
33 const auto DEFAULT_HEIGHT = 25;
33 const auto DEFAULT_HEIGHT = 25;
34 const auto DEFAULT_WIDTH = 100;
34 const auto DEFAULT_WIDTH = 100;
35
35
36 struct ColumnProperties {
36 struct ColumnProperties {
37 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
37 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
38 int height = DEFAULT_HEIGHT)
38 int height = DEFAULT_HEIGHT)
39 : m_Name{name}, m_Width{width}, m_Height{height}
39 : m_Name{name}, m_Width{width}, m_Height{height}
40 {
40 {
41 }
41 }
42
42
43 QString m_Name;
43 QString m_Name;
44 int m_Width;
44 int m_Width;
45 int m_Height;
45 int m_Height;
46 };
46 };
47
47
48 const auto COLUMN_PROPERTIES = QHash<int, ColumnProperties>{
48 const auto COLUMN_PROPERTIES = QHash<int, ColumnProperties>{
49 {NAME_COLUMN, {QObject::tr("Name")}}, {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
49 {NAME_COLUMN, {QObject::tr("Name")}}, {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
50 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}, {NBPOINTS_COLUMN, {QObject::tr("Nb points")}},
50 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}, {NBPOINTS_COLUMN, {QObject::tr("Nb points")}},
51 {UNIT_COLUMN, {QObject::tr("Unit")}}, {MISSION_COLUMN, {QObject::tr("Mission")}},
51 {UNIT_COLUMN, {QObject::tr("Unit")}}, {MISSION_COLUMN, {QObject::tr("Mission")}},
52 {PLUGIN_COLUMN, {QObject::tr("Plugin")}}};
52 {PLUGIN_COLUMN, {QObject::tr("Plugin")}}};
53
53
54 QString uniqueName(const QString &defaultName,
54 QString uniqueName(const QString &defaultName,
55 const std::vector<std::shared_ptr<Variable> > &variables)
55 const std::vector<std::shared_ptr<Variable> > &variables)
56 {
56 {
57 auto forbiddenNames = std::vector<QString>(variables.size());
57 auto forbiddenNames = std::vector<QString>(variables.size());
58 std::transform(variables.cbegin(), variables.cend(), forbiddenNames.begin(),
58 std::transform(variables.cbegin(), variables.cend(), forbiddenNames.begin(),
59 [](const auto &variable) { return variable->name(); });
59 [](const auto &variable) { return variable->name(); });
60 auto uniqueName = StringUtils::uniqueName(defaultName, forbiddenNames);
60 auto uniqueName = StringUtils::uniqueName(defaultName, forbiddenNames);
61 Q_ASSERT(!uniqueName.isEmpty());
61 Q_ASSERT(!uniqueName.isEmpty());
62
62
63 return uniqueName;
63 return uniqueName;
64 }
64 }
65
65
66 } // namespace
66 } // namespace
67
67
68
68
69
69
70 VariableModel2::VariableModel2(QObject *parent)
70 VariableModel2::VariableModel2(QObject *parent)
71 : QAbstractTableModel{parent}
71 : QAbstractTableModel{parent}
72 {
72 {
73 }
73 }
74
74
75
75
76 int VariableModel2::columnCount(const QModelIndex &parent) const
76 int VariableModel2::columnCount(const QModelIndex &parent) const
77 {
77 {
78 Q_UNUSED(parent);
78 Q_UNUSED(parent);
79
79
80 return NB_COLUMNS;
80 return NB_COLUMNS;
81 }
81 }
82
82
83 int VariableModel2::rowCount(const QModelIndex &parent) const
83 int VariableModel2::rowCount(const QModelIndex &parent) const
84 {
84 {
85 Q_UNUSED(parent);
85 Q_UNUSED(parent);
86 return _variables.size();
86 return _variables.size();
87 }
87 }
88
88
89 QVariant VariableModel2::data(const QModelIndex &index, int role) const
89 QVariant VariableModel2::data(const QModelIndex &index, int role) const
90 {
90 {
91 if (!index.isValid()) {
91 if (!index.isValid()) {
92 return QVariant{};
92 return QVariant{};
93 }
93 }
94
94
95 if (index.row() < 0 || index.row() >= rowCount()) {
95 if (index.row() < 0 || index.row() >= rowCount()) {
96 return QVariant{};
96 return QVariant{};
97 }
97 }
98
98
99 if (role == Qt::DisplayRole) {
99 if (role == Qt::DisplayRole) {
100 if (auto variable = _variables[index.row()]) {
100 if (auto variable = _variables[index.row()]) {
101 switch (index.column()) {
101 switch (index.column()) {
102 case NAME_COLUMN:
102 case NAME_COLUMN:
103 return variable->name();
103 return variable->name();
104 case TSTART_COLUMN: {
104 case TSTART_COLUMN: {
105 if(auto range = variable->realRange(); range.has_value())
105 if(auto range = variable->realRange(); range.has_value())
106 return DateUtils::dateTime(range.value().m_TStart).toString(DATETIME_FORMAT);
106 return DateUtils::dateTime(range.value().m_TStart).toString(DATETIME_FORMAT);
107 return QVariant{};
107 return QVariant{};
108 }
108 }
109 case TEND_COLUMN: {
109 case TEND_COLUMN: {
110 if(auto range = variable->realRange(); range.has_value())
110 if(auto range = variable->realRange(); range.has_value())
111 return DateUtils::dateTime(range.value().m_TEnd).toString(DATETIME_FORMAT);
111 return DateUtils::dateTime(range.value().m_TEnd).toString(DATETIME_FORMAT);
112 return QVariant{};
112 return QVariant{};
113 }
113 }
114 case NBPOINTS_COLUMN:
114 case NBPOINTS_COLUMN:
115 return variable->nbPoints();
115 return variable->nbPoints();
116 case UNIT_COLUMN:
116 case UNIT_COLUMN:
117 return variable->metadata().value(QStringLiteral("units"));
117 return variable->metadata().value(QStringLiteral("units"));
118 case MISSION_COLUMN:
118 case MISSION_COLUMN:
119 return variable->metadata().value(QStringLiteral("mission"));
119 return variable->metadata().value(QStringLiteral("mission"));
120 case PLUGIN_COLUMN:
120 case PLUGIN_COLUMN:
121 return variable->metadata().value(QStringLiteral("plugin"));
121 return variable->metadata().value(QStringLiteral("plugin"));
122 default:
122 default:
123 // No action
123 // No action
124 break;
124 break;
125 }
125 }
126 }
126 }
127 }
127 }
128 else if (role == VariableRoles::ProgressRole) {
128 else if (role == VariableRoles::ProgressRole) {
129 return QVariant{};
129 return QVariant{};
130 }
130 }
131
131
132 return QVariant{};
132 return QVariant{};
133 }
133 }
134
134
135 QVariant VariableModel2::headerData(int section, Qt::Orientation orientation, int role) const
135 QVariant VariableModel2::headerData(int section, Qt::Orientation orientation, int role) const
136 {
136 {
137 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
137 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
138 return QVariant{};
138 return QVariant{};
139 }
139 }
140
140
141 if (orientation == Qt::Horizontal) {
141 if (orientation == Qt::Horizontal) {
142 auto propertiesIt = COLUMN_PROPERTIES.find(section);
142 auto propertiesIt = COLUMN_PROPERTIES.find(section);
143 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
143 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
144 // Role is either DisplayRole or SizeHintRole
144 // Role is either DisplayRole or SizeHintRole
145 return (role == Qt::DisplayRole)
145 return (role == Qt::DisplayRole)
146 ? QVariant{propertiesIt->m_Name}
146 ? QVariant{propertiesIt->m_Name}
147 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
147 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
148 }
148 }
149 }
149 }
150
150
151 return QVariant{};
151 return QVariant{};
152 }
152 }
153
153
154 Qt::ItemFlags VariableModel2::flags(const QModelIndex &index) const
154 Qt::ItemFlags VariableModel2::flags(const QModelIndex &index) const
155 {
155 {
156 return QAbstractTableModel::flags(index) | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
156 return QAbstractTableModel::flags(index) | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
157 }
157 }
158
158
159 Qt::DropActions VariableModel2::supportedDropActions() const
159 Qt::DropActions VariableModel2::supportedDropActions() const
160 {
160 {
161 return Qt::CopyAction | Qt::MoveAction;
161 return Qt::CopyAction | Qt::MoveAction;
162 }
162 }
163
163
164 Qt::DropActions VariableModel2::supportedDragActions() const
164 Qt::DropActions VariableModel2::supportedDragActions() const
165 {
165 {
166 return Qt::CopyAction | Qt::MoveAction;
166 return Qt::CopyAction | Qt::MoveAction;
167 }
167 }
168
168
169 QStringList VariableModel2::mimeTypes() const
169 QStringList VariableModel2::mimeTypes() const
170 {
170 {
171 return {MIME_TYPE_VARIABLE_LIST, MIME_TYPE_TIME_RANGE};
171 return {MIME_TYPE_VARIABLE_LIST, MIME_TYPE_TIME_RANGE};
172 }
172 }
173
173
174 QMimeData *VariableModel2::mimeData(const QModelIndexList &indexes) const
174 QMimeData *VariableModel2::mimeData(const QModelIndexList &indexes) const
175 {
175 {
176 auto mimeData = new QMimeData;
176 auto mimeData = new QMimeData;
177 std::vector<std::shared_ptr<Variable> > variables;
177 std::vector<std::shared_ptr<Variable> > variables;
178
178
179 DateTimeRange firstTimeRange;
179 DateTimeRange firstTimeRange;
180 for (const auto &index : indexes) {
180 for (const auto &index : indexes) {
181 if (index.column() == 0) { // only the first column
181 if (index.column() == 0) { // only the first column
182 auto variable = _variables[index.row()];
182 auto variable = _variables[index.row()];
183 if (variable.get() && index.isValid()) {
183 if (variable.get() && index.isValid()) {
184
184
185 if (variables.size()==0) {
185 if (variables.size()==0) {
186 // Gets the range of the first variable
186 // Gets the range of the first variable
187 firstTimeRange = variable->range();
187 firstTimeRange = variable->range();
188 }
188 }
189 variables.push_back(variable);
189 variables.push_back(variable);
190 }
190 }
191 }
191 }
192 }
192 }
193
193
194 auto variablesEncodedData = Variable::mimeData(variables);
194 auto variablesEncodedData = Variable::mimeData(variables);
195 mimeData->setData(MIME_TYPE_VARIABLE_LIST, variablesEncodedData);
195 mimeData->setData(MIME_TYPE_VARIABLE_LIST, variablesEncodedData);
196
196
197 if (variables.size() == 1) {
197 if (variables.size() == 1) {
198 // No time range MIME data if multiple variables are dragged
198 // No time range MIME data if multiple variables are dragged
199 auto timeEncodedData = TimeController::mimeDataForTimeRange(firstTimeRange);
199 auto timeEncodedData = TimeController::mimeDataForTimeRange(firstTimeRange);
200 mimeData->setData(MIME_TYPE_TIME_RANGE, timeEncodedData);
200 mimeData->setData(MIME_TYPE_TIME_RANGE, timeEncodedData);
201 }
201 }
202
202
203 return mimeData;
203 return mimeData;
204 }
204 }
205
205
206 bool VariableModel2::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row,
206 bool VariableModel2::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row,
207 int column, const QModelIndex &parent) const
207 int column, const QModelIndex &parent) const
208 {
208 {
209 Q_UNUSED(column);
209 Q_UNUSED(column);
210 // drop of a product
210 // drop of a product
211 return data->hasFormat(MIME_TYPE_PRODUCT_LIST)
211 return data->hasFormat(MIME_TYPE_PRODUCT_LIST)
212 || (data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid()
212 || (data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid()
213 && !data->hasFormat(MIME_TYPE_VARIABLE_LIST));
213 && !data->hasFormat(MIME_TYPE_VARIABLE_LIST));
214 }
214 }
215
215
216 bool VariableModel2::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
216 bool VariableModel2::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
217 const QModelIndex &parent)
217 const QModelIndex &parent)
218 {
218 {
219 auto dropDone = false;
219 auto dropDone = false;
220
220
221 if (data->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
221 if (data->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
222 auto productList
222 auto productList
223 = DataSourceController::productsDataForMimeData(data->data(MIME_TYPE_PRODUCT_LIST));
223 = DataSourceController::productsDataForMimeData(data->data(MIME_TYPE_PRODUCT_LIST));
224
224
225 for (auto metaData : productList) {
225 for (auto metaData : productList) {
226 emit createVariable(metaData.toHash());
226 emit createVariable(metaData.toHash());
227 }
227 }
228
228
229 dropDone = true;
229 dropDone = true;
230 }
230 }
231 else if (data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid()) {
231 else if (data->hasFormat(MIME_TYPE_TIME_RANGE) && parent.isValid()) {
232 auto variable = _variables[parent.row()];
232 auto variable = _variables[parent.row()];
233 auto range = TimeController::timeRangeForMimeData(data->data(MIME_TYPE_TIME_RANGE));
233 auto range = TimeController::timeRangeForMimeData(data->data(MIME_TYPE_TIME_RANGE));
234
234
235 emit asyncChangeRange(variable, range);
235 emit asyncChangeRange(variable, range);
236
236
237 dropDone = true;
237 dropDone = true;
238 }
238 }
239
239
240 return dropDone;
240 return dropDone;
241 }
241 }
242
242
243 void VariableModel2::variableUpdated() noexcept
243 void VariableModel2::variableUpdated(QUuid id) noexcept
244 {
244 {
245 emit dataChanged(QModelIndex(),QModelIndex());
245 emit dataChanged(QModelIndex(),QModelIndex());
246 }
246 }
247
247
248 void VariableModel2::variableAdded(const std::shared_ptr<Variable> & variable)
248 void VariableModel2::variableAdded(const std::shared_ptr<Variable> & variable)
249 {
249 {
250 if(!SciQLop::containers::contains(_variables,variable))
250 if(!SciQLop::containers::contains(_variables,variable))
251 {
251 {
252 beginInsertRows(QModelIndex(), this->_variables.size(), this->_variables.size());
252 beginInsertRows(QModelIndex(), this->_variables.size(), this->_variables.size());
253 this->_variables.push_back(variable);
253 this->_variables.push_back(variable);
254 endInsertRows();
254 endInsertRows();
255 connect(variable.get(),&Variable::updated,this,&VariableModel2::variableUpdated);
255 connect(variable.get(),&Variable::updated,this,&VariableModel2::variableUpdated);
256 }
256 }
257 }
257 }
258
258
259 void VariableModel2::variableDeleted(const std::shared_ptr<Variable> &variable)
259 void VariableModel2::variableDeleted(const std::shared_ptr<Variable> &variable)
260 {
260 {
261 auto it = std::find(_variables.begin(), _variables.end(), variable);
261 auto it = std::find(_variables.begin(), _variables.end(), variable);
262 if (it != _variables.end())
262 if (it != _variables.end())
263 {
263 {
264 auto index = std::distance(_variables.begin(), it);
264 auto index = std::distance(_variables.begin(), it);
265 beginRemoveRows(QModelIndex(), index, index);
265 beginRemoveRows(QModelIndex(), index, index);
266 _variables.erase(it);
266 _variables.erase(it);
267 endRemoveRows();
267 endRemoveRows();
268 }
268 }
269 }
269 }
270
270
General Comments 0
You need to be logged in to leave comments. Login now