##// END OF EJS Templates
Review fixes
Alexandre Leroux -
r344:c0501a972eb4
parent child
Show More
@@ -1,108 +1,105
1 #ifndef SCIQLOP_ARRAYDATA_H
1 #ifndef SCIQLOP_ARRAYDATA_H
2 #define SCIQLOP_ARRAYDATA_H
2 #define SCIQLOP_ARRAYDATA_H
3
3
4 #include <QReadLocker>
4 #include <QReadLocker>
5 #include <QReadWriteLock>
5 #include <QReadWriteLock>
6 #include <QVector>
6 #include <QVector>
7 /**
7 /**
8 * @brief The ArrayData class represents a dataset for a data series.
8 * @brief The ArrayData class represents a dataset for a data series.
9 *
9 *
10 * A dataset can be unidimensional or two-dimensional. This property is determined by the Dim
10 * A dataset can be unidimensional or two-dimensional. This property is determined by the Dim
11 * template-parameter.
11 * template-parameter.
12 *
12 *
13 * @tparam Dim the dimension of the ArrayData (one or two)
13 * @tparam Dim the dimension of the ArrayData (one or two)
14 * @sa IDataSeries
14 * @sa IDataSeries
15 */
15 */
16 template <int Dim>
16 template <int Dim>
17 class ArrayData {
17 class ArrayData {
18 public:
18 public:
19 /**
19 /**
20 * Ctor for a unidimensional ArrayData
20 * Ctor for a unidimensional ArrayData
21 * @param nbColumns the number of values the ArrayData will hold
21 * @param nbColumns the number of values the ArrayData will hold
22 */
22 */
23 template <int D = Dim, typename = std::enable_if_t<D == 1> >
23 template <int D = Dim, typename = std::enable_if_t<D == 1> >
24 explicit ArrayData(int nbColumns) : m_Data{1, QVector<double>{}}
24 explicit ArrayData(int nbColumns) : m_Data{1, QVector<double>{}}
25 {
25 {
26 QWriteLocker locker(&m_Lock);
26 QWriteLocker locker{&m_Lock};
27 m_Data[0].resize(nbColumns);
27 m_Data[0].resize(nbColumns);
28 }
28 }
29
29
30 /**
30 /// Copy ctor
31 * Ctor for a unidimensional ArrayData
32 * @param nbColumns the number of values the ArrayData will hold
33 */
34 explicit ArrayData(const ArrayData &other)
31 explicit ArrayData(const ArrayData &other)
35 {
32 {
36 QReadLocker otherLocker(&other.m_Lock);
33 QReadLocker otherLocker{&other.m_Lock};
37 QWriteLocker locker(&m_Lock);
34 QWriteLocker locker{&m_Lock};
38 m_Data = other.m_Data;
35 m_Data = other.m_Data;
39 }
36 }
40
37
41 /**
38 /**
42 * Sets a data at a specified index. The index has to be valid to be effective
39 * Sets a data at a specified index. The index has to be valid to be effective
43 * @param index the index to which the data will be set
40 * @param index the index to which the data will be set
44 * @param data the data to set
41 * @param data the data to set
45 * @remarks this method is only available for a unidimensional ArrayData
42 * @remarks this method is only available for a unidimensional ArrayData
46 */
43 */
47 template <int D = Dim, typename = std::enable_if_t<D == 1> >
44 template <int D = Dim, typename = std::enable_if_t<D == 1> >
48 void setData(int index, double data) noexcept
45 void setData(int index, double data) noexcept
49 {
46 {
50 QWriteLocker locker(&m_Lock);
47 QWriteLocker locker{&m_Lock};
51 if (index >= 0 && index < m_Data.at(0).size()) {
48 if (index >= 0 && index < m_Data.at(0).size()) {
52 m_Data[0].replace(index, data);
49 m_Data[0].replace(index, data);
53 }
50 }
54 }
51 }
55
52
56 /**
53 /**
57 * @return the data as a vector
54 * @return the data as a vector
58 * @remarks this method is only available for a unidimensional ArrayData
55 * @remarks this method is only available for a unidimensional ArrayData
59 */
56 */
60 template <int D = Dim, typename = std::enable_if_t<D == 1> >
57 template <int D = Dim, typename = std::enable_if_t<D == 1> >
61 QVector<double> data() const noexcept
58 QVector<double> data() const noexcept
62 {
59 {
63 QReadLocker locker(&m_Lock);
60 QReadLocker locker{&m_Lock};
64 return m_Data[0];
61 return m_Data[0];
65 }
62 }
66
63
67 /**
64 /**
68 * @return the data as a vector
65 * @return the data as a vector
69 * @remarks this method is only available for a unidimensional ArrayData
66 * @remarks this method is only available for a unidimensional ArrayData
70 */
67 */
71 template <int D = Dim, typename = std::enable_if_t<D == 1> >
68 template <int D = Dim, typename = std::enable_if_t<D == 1> >
72 QVector<double> data(double tStart, double tEnd) const noexcept
69 QVector<double> data(double tStart, double tEnd) const noexcept
73 {
70 {
74 QReadLocker locker(&m_Lock);
71 QReadLocker locker{&m_Lock};
75 return m_Data.at(tStart);
72 return m_Data.at(tStart);
76 }
73 }
77
74
78 // TODO Comment
75 // TODO Comment
79 template <int D = Dim, typename = std::enable_if_t<D == 1> >
76 template <int D = Dim, typename = std::enable_if_t<D == 1> >
80 void merge(const ArrayData<1> &arrayData)
77 void merge(const ArrayData<1> &arrayData)
81 {
78 {
82 QWriteLocker locker(&m_Lock);
79 QWriteLocker locker{&m_Lock};
83 if (!m_Data.empty()) {
80 if (!m_Data.empty()) {
84 QReadLocker otherLocker(&arrayData.m_Lock);
81 QReadLocker otherLocker{&arrayData.m_Lock};
85 m_Data[0] += arrayData.data();
82 m_Data[0] += arrayData.data();
86 }
83 }
87 }
84 }
88
85
89 template <int D = Dim, typename = std::enable_if_t<D == 1> >
86 template <int D = Dim, typename = std::enable_if_t<D == 1> >
90 int size() const
87 int size() const
91 {
88 {
92 QReadLocker locker(&m_Lock);
89 QReadLocker locker{&m_Lock};
93 return m_Data[0].size();
90 return m_Data[0].size();
94 }
91 }
95
92
96 void clear()
93 void clear()
97 {
94 {
98 QWriteLocker locker(&m_Lock);
95 QWriteLocker locker{&m_Lock};
99 m_Data.clear();
96 m_Data.clear();
100 }
97 }
101
98
102
99
103 private:
100 private:
104 QVector<QVector<double> > m_Data;
101 QVector<QVector<double> > m_Data;
105 mutable QReadWriteLock m_Lock;
102 mutable QReadWriteLock m_Lock;
106 };
103 };
107
104
108 #endif // SCIQLOP_ARRAYDATA_H
105 #endif // SCIQLOP_ARRAYDATA_H
@@ -1,198 +1,200
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableModel.h>
2 #include <Variable/VariableModel.h>
3
3
4 #include <Data/IDataSeries.h>
4 #include <Data/IDataSeries.h>
5
5
6 #include <QDateTime>
6 #include <QDateTime>
7 #include <QSize>
7 #include <QSize>
8
8
9 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
9 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
10
10
11 namespace {
11 namespace {
12
12
13 // Column indexes
13 // Column indexes
14 const auto NAME_COLUMN = 0;
14 const auto NAME_COLUMN = 0;
15 const auto TSTART_COLUMN = 1;
15 const auto TSTART_COLUMN = 1;
16 const auto TEND_COLUMN = 2;
16 const auto TEND_COLUMN = 2;
17 const auto NB_COLUMNS = 3;
17 const auto NB_COLUMNS = 3;
18
18
19 // Column properties
19 // Column properties
20 const auto DEFAULT_HEIGHT = 25;
20 const auto DEFAULT_HEIGHT = 25;
21 const auto DEFAULT_WIDTH = 100;
21 const auto DEFAULT_WIDTH = 100;
22
22
23 struct ColumnProperties {
23 struct ColumnProperties {
24 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
24 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
25 int height = DEFAULT_HEIGHT)
25 int height = DEFAULT_HEIGHT)
26 : m_Name{name}, m_Width{width}, m_Height{height}
26 : m_Name{name}, m_Width{width}, m_Height{height}
27 {
27 {
28 }
28 }
29
29
30 QString m_Name;
30 QString m_Name;
31 int m_Width;
31 int m_Width;
32 int m_Height;
32 int m_Height;
33 };
33 };
34
34
35 const auto COLUMN_PROPERTIES
35 const auto COLUMN_PROPERTIES
36 = QHash<int, ColumnProperties>{{NAME_COLUMN, {QObject::tr("Name")}},
36 = QHash<int, ColumnProperties>{{NAME_COLUMN, {QObject::tr("Name")}},
37 {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
37 {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
38 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}};
38 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}};
39
39
40 /// Format for datetimes
40 /// Format for datetimes
41 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
41 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
42
42
43 } // namespace
43 } // namespace
44
44
45 struct VariableModel::VariableModelPrivate {
45 struct VariableModel::VariableModelPrivate {
46 /// Variables created in SciQlop
46 /// Variables created in SciQlop
47 std::vector<std::shared_ptr<Variable> > m_Variables;
47 std::vector<std::shared_ptr<Variable> > m_Variables;
48 };
48 };
49
49
50 VariableModel::VariableModel(QObject *parent)
50 VariableModel::VariableModel(QObject *parent)
51 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
51 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
52 {
52 {
53 }
53 }
54
54
55 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
55 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
56 const SqpDateTime &dateTime) noexcept
56 const SqpDateTime &dateTime) noexcept
57 {
57 {
58 auto insertIndex = rowCount();
58 auto insertIndex = rowCount();
59 beginInsertRows({}, insertIndex, insertIndex);
59 beginInsertRows({}, insertIndex, insertIndex);
60
60
61 /// @todo For the moment, the other data of the variable is initialized with default values
61 /// @todo For the moment, the other data of the variable is initialized with default values
62 auto variable = std::make_shared<Variable>(name, QStringLiteral("unit"),
62 auto variable = std::make_shared<Variable>(name, QStringLiteral("unit"),
63 QStringLiteral("mission"), dateTime);
63 QStringLiteral("mission"), dateTime);
64
64
65 impl->m_Variables.push_back(variable);
65 impl->m_Variables.push_back(variable);
66 connect(variable.get(), &Variable::updated, this, &VariableModel::onVariableUpdated);
66 connect(variable.get(), &Variable::updated, this, &VariableModel::onVariableUpdated);
67
67
68 endInsertRows();
68 endInsertRows();
69
69
70 return variable;
70 return variable;
71 }
71 }
72
72
73 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
73 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
74 {
74 {
75 if (!variable) {
75 if (!variable) {
76 qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
76 qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
77 return;
77 return;
78 }
78 }
79
79
80 // Finds variable in the model
80 // Finds variable in the model
81 auto begin = impl->m_Variables.cbegin();
81 auto begin = impl->m_Variables.cbegin();
82 auto end = impl->m_Variables.cend();
82 auto end = impl->m_Variables.cend();
83 auto it = std::find(begin, end, variable);
83 auto it = std::find(begin, end, variable);
84 if (it != end) {
84 if (it != end) {
85 auto removeIndex = std::distance(begin, it);
85 auto removeIndex = std::distance(begin, it);
86
86
87 // Deletes variable
87 // Deletes variable
88 beginRemoveRows({}, removeIndex, removeIndex);
88 beginRemoveRows({}, removeIndex, removeIndex);
89 impl->m_Variables.erase(it);
89 impl->m_Variables.erase(it);
90 endRemoveRows();
90 endRemoveRows();
91 }
91 }
92 else {
92 else {
93 qCritical(LOG_VariableModel())
93 qCritical(LOG_VariableModel())
94 << tr("Can't delete variable %1 from the model: the variable is not in the model")
94 << tr("Can't delete variable %1 from the model: the variable is not in the model")
95 .arg(variable->name());
95 .arg(variable->name());
96 }
96 }
97 }
97 }
98
98
99 std::shared_ptr<Variable> VariableModel::variable(int index) const
99 std::shared_ptr<Variable> VariableModel::variable(int index) const
100 {
100 {
101 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
101 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
102 }
102 }
103
103
104 int VariableModel::columnCount(const QModelIndex &parent) const
104 int VariableModel::columnCount(const QModelIndex &parent) const
105 {
105 {
106 Q_UNUSED(parent);
106 Q_UNUSED(parent);
107
107
108 return NB_COLUMNS;
108 return NB_COLUMNS;
109 }
109 }
110
110
111 int VariableModel::rowCount(const QModelIndex &parent) const
111 int VariableModel::rowCount(const QModelIndex &parent) const
112 {
112 {
113 Q_UNUSED(parent);
113 Q_UNUSED(parent);
114
114
115 return impl->m_Variables.size();
115 return impl->m_Variables.size();
116 }
116 }
117
117
118 QVariant VariableModel::data(const QModelIndex &index, int role) const
118 QVariant VariableModel::data(const QModelIndex &index, int role) const
119 {
119 {
120 if (!index.isValid()) {
120 if (!index.isValid()) {
121 return QVariant{};
121 return QVariant{};
122 }
122 }
123
123
124 if (index.row() < 0 || index.row() >= rowCount()) {
124 if (index.row() < 0 || index.row() >= rowCount()) {
125 return QVariant{};
125 return QVariant{};
126 }
126 }
127
127
128 if (role == Qt::DisplayRole) {
128 if (role == Qt::DisplayRole) {
129 if (auto variable = impl->m_Variables.at(index.row()).get()) {
129 if (auto variable = impl->m_Variables.at(index.row()).get()) {
130 /// Lambda function that builds the variant to return for a time value
130 /// Lambda function that builds the variant to return for a time value
131 auto dateTimeVariant = [](double time) {
131 auto dateTimeVariant = [](double time) {
132 auto dateTime = QDateTime::fromMSecsSinceEpoch(time * 1000.);
132 auto dateTime = QDateTime::fromMSecsSinceEpoch(time * 1000.);
133 return dateTime.toString(DATETIME_FORMAT);
133 return dateTime.toString(DATETIME_FORMAT);
134 };
134 };
135
135
136 switch (index.column()) {
136 switch (index.column()) {
137 case NAME_COLUMN:
137 case NAME_COLUMN:
138 return variable->name();
138 return variable->name();
139 case TSTART_COLUMN:
139 case TSTART_COLUMN:
140 return dateTimeVariant(variable->dateTime().m_TStart);
140 return dateTimeVariant(variable->dateTime().m_TStart);
141 case TEND_COLUMN:
141 case TEND_COLUMN:
142 return dateTimeVariant(variable->dateTime().m_TEnd);
142 return dateTimeVariant(variable->dateTime().m_TEnd);
143 default:
143 default:
144 // No action
144 // No action
145 break;
145 break;
146 }
146 }
147
147
148 qWarning(LOG_VariableModel())
148 qWarning(LOG_VariableModel())
149 << tr("Can't get data (unknown column %1)").arg(index.column());
149 << tr("Can't get data (unknown column %1)").arg(index.column());
150 }
150 }
151 else {
151 else {
152 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
152 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
153 }
153 }
154 }
154 }
155
155
156 return QVariant{};
156 return QVariant{};
157 }
157 }
158
158
159 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
159 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
160 {
160 {
161 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
161 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
162 return QVariant{};
162 return QVariant{};
163 }
163 }
164
164
165 if (orientation == Qt::Horizontal) {
165 if (orientation == Qt::Horizontal) {
166 auto propertiesIt = COLUMN_PROPERTIES.find(section);
166 auto propertiesIt = COLUMN_PROPERTIES.find(section);
167 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
167 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
168 // Role is either DisplayRole or SizeHintRole
168 // Role is either DisplayRole or SizeHintRole
169 return (role == Qt::DisplayRole)
169 return (role == Qt::DisplayRole)
170 ? QVariant{propertiesIt->m_Name}
170 ? QVariant{propertiesIt->m_Name}
171 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
171 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
172 }
172 }
173 else {
173 else {
174 qWarning(LOG_VariableModel())
174 qWarning(LOG_VariableModel())
175 << tr("Can't get header data (unknown column %1)").arg(section);
175 << tr("Can't get header data (unknown column %1)").arg(section);
176 }
176 }
177 }
177 }
178
178
179 return QVariant{};
179 return QVariant{};
180 }
180 }
181
181
182 void VariableModel::onVariableUpdated() noexcept
182 void VariableModel::onVariableUpdated() noexcept
183 {
183 {
184 // Finds variable that has been updated in the model
184 // Finds variable that has been updated in the model
185 if (auto updatedVariable = dynamic_cast<Variable *>(sender())) {
185 if (auto updatedVariable = dynamic_cast<Variable *>(sender())) {
186 auto begin = std::cbegin(impl->m_Variables);
186 auto begin = std::cbegin(impl->m_Variables);
187 auto end = std::cend(impl->m_Variables);
187 auto end = std::cend(impl->m_Variables);
188 auto it = std::find_if(begin, end, [updatedVariable](const auto &variable) {
188 auto it = std::find_if(begin, end, [updatedVariable](const auto &variable) {
189 return variable.get() == updatedVariable;
189 return variable.get() == updatedVariable;
190 });
190 });
191
191
192 if (it != end) {
192 if (it != end) {
193 // Gets the index of the variable in the model: we assume here that views have the same
194 // order as the model
193 auto updateVariableIndex = std::distance(begin, it);
195 auto updateVariableIndex = std::distance(begin, it);
194 emit dataChanged(createIndex(updateVariableIndex, 0),
196 emit dataChanged(createIndex(updateVariableIndex, 0),
195 createIndex(updateVariableIndex, columnCount() - 1));
197 createIndex(updateVariableIndex, columnCount() - 1));
196 }
198 }
197 }
199 }
198 }
200 }
General Comments 0
You need to be logged in to leave comments. Login now