##// END OF EJS Templates
Adds method to get all variables from model...
Alexandre Leroux -
r636:c7028b4894dd
parent child
Show More
@@ -1,80 +1,81
1 #ifndef SCIQLOP_VARIABLEMODEL_H
1 #ifndef SCIQLOP_VARIABLEMODEL_H
2 #define SCIQLOP_VARIABLEMODEL_H
2 #define SCIQLOP_VARIABLEMODEL_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/SqpRange.h>
6 #include <Data/SqpRange.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 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableModel)
14 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableModel)
15
15
16 enum VariableRoles { ProgressRole = Qt::UserRole };
16 enum VariableRoles { ProgressRole = Qt::UserRole };
17
17
18
18
19 class IDataSeries;
19 class IDataSeries;
20 class Variable;
20 class Variable;
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 VariableModel : public QAbstractTableModel {
25 class SCIQLOP_CORE_EXPORT VariableModel : public QAbstractTableModel {
26 Q_OBJECT
26 Q_OBJECT
27 public:
27 public:
28 explicit VariableModel(QObject *parent = nullptr);
28 explicit VariableModel(QObject *parent = nullptr);
29
29
30 /**
30 /**
31 * Creates a new variable in the model
31 * Creates a new variable in the model
32 * @param name the name of the new variable
32 * @param name the name of the new variable
33 * @param dateTime the dateTime of the new variable
33 * @param dateTime the dateTime of the new variable
34 * @param metadata the metadata associated to the new variable
34 * @param metadata the metadata associated to the new variable
35 * @return the pointer to the new variable
35 * @return the pointer to the new variable
36 */
36 */
37 std::shared_ptr<Variable> createVariable(const QString &name, const SqpRange &dateTime,
37 std::shared_ptr<Variable> createVariable(const QString &name, const SqpRange &dateTime,
38 const QVariantHash &metadata) noexcept;
38 const QVariantHash &metadata) noexcept;
39
39
40 /**
40 /**
41 * Deletes a variable from the model, if it exists
41 * Deletes a variable from the model, if it exists
42 * @param variable the variable to delete
42 * @param variable the variable to delete
43 */
43 */
44 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
44 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
45
45
46
46
47 std::shared_ptr<Variable> variable(int index) const;
47 std::shared_ptr<Variable> variable(int index) const;
48 std::vector<std::shared_ptr<Variable> > variables() const;
48
49
49 void setDataProgress(std::shared_ptr<Variable> variable, double progress);
50 void setDataProgress(std::shared_ptr<Variable> variable, double progress);
50
51
51
52
52 // /////////////////////////// //
53 // /////////////////////////// //
53 // QAbstractTableModel methods //
54 // QAbstractTableModel methods //
54 // /////////////////////////// //
55 // /////////////////////////// //
55
56
56 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
57 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
57 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
58 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
58 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
59 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
59 virtual QVariant headerData(int section, Qt::Orientation orientation,
60 virtual QVariant headerData(int section, Qt::Orientation orientation,
60 int role = Qt::DisplayRole) const override;
61 int role = Qt::DisplayRole) const override;
61
62
62
63
63 void abortProgress(const QModelIndex &index);
64 void abortProgress(const QModelIndex &index);
64
65
65 signals:
66 signals:
66 void abortProgessRequested(std::shared_ptr<Variable> variable);
67 void abortProgessRequested(std::shared_ptr<Variable> variable);
67
68
68 private:
69 private:
69 class VariableModelPrivate;
70 class VariableModelPrivate;
70 spimpl::unique_impl_ptr<VariableModelPrivate> impl;
71 spimpl::unique_impl_ptr<VariableModelPrivate> impl;
71
72
72 private slots:
73 private slots:
73 /// Slot called when data of a variable has been updated
74 /// Slot called when data of a variable has been updated
74 void onVariableUpdated() noexcept;
75 void onVariableUpdated() noexcept;
75 };
76 };
76
77
77 // Registers QVector<int> metatype so it can be used in VariableModel::dataChanged() signal
78 // Registers QVector<int> metatype so it can be used in VariableModel::dataChanged() signal
78 SCIQLOP_REGISTER_META_TYPE(QVECTOR_INT_REGISTRY, QVector<int>)
79 SCIQLOP_REGISTER_META_TYPE(QVECTOR_INT_REGISTRY, QVector<int>)
79
80
80 #endif // SCIQLOP_VARIABLEMODEL_H
81 #endif // SCIQLOP_VARIABLEMODEL_H
@@ -1,260 +1,265
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableModel.h>
2 #include <Variable/VariableModel.h>
3
3
4 #include <Common/DateUtils.h>
4 #include <Common/DateUtils.h>
5
5
6 #include <Data/IDataSeries.h>
6 #include <Data/IDataSeries.h>
7
7
8 #include <QSize>
8 #include <QSize>
9 #include <unordered_map>
9 #include <unordered_map>
10
10
11 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
11 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
12
12
13 namespace {
13 namespace {
14
14
15 // Column indexes
15 // Column indexes
16 const auto NAME_COLUMN = 0;
16 const auto NAME_COLUMN = 0;
17 const auto TSTART_COLUMN = 1;
17 const auto TSTART_COLUMN = 1;
18 const auto TEND_COLUMN = 2;
18 const auto TEND_COLUMN = 2;
19 const auto UNIT_COLUMN = 3;
19 const auto UNIT_COLUMN = 3;
20 const auto MISSION_COLUMN = 4;
20 const auto MISSION_COLUMN = 4;
21 const auto PLUGIN_COLUMN = 5;
21 const auto PLUGIN_COLUMN = 5;
22 const auto NB_COLUMNS = 6;
22 const auto NB_COLUMNS = 6;
23
23
24 // Column properties
24 // Column properties
25 const auto DEFAULT_HEIGHT = 25;
25 const auto DEFAULT_HEIGHT = 25;
26 const auto DEFAULT_WIDTH = 100;
26 const auto DEFAULT_WIDTH = 100;
27
27
28 struct ColumnProperties {
28 struct ColumnProperties {
29 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
29 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
30 int height = DEFAULT_HEIGHT)
30 int height = DEFAULT_HEIGHT)
31 : m_Name{name}, m_Width{width}, m_Height{height}
31 : m_Name{name}, m_Width{width}, m_Height{height}
32 {
32 {
33 }
33 }
34
34
35 QString m_Name;
35 QString m_Name;
36 int m_Width;
36 int m_Width;
37 int m_Height;
37 int m_Height;
38 };
38 };
39
39
40 const auto COLUMN_PROPERTIES = QHash<int, ColumnProperties>{
40 const auto COLUMN_PROPERTIES = QHash<int, ColumnProperties>{
41 {NAME_COLUMN, {QObject::tr("Name")}}, {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
41 {NAME_COLUMN, {QObject::tr("Name")}}, {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
42 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}, {UNIT_COLUMN, {QObject::tr("Unit")}},
42 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}, {UNIT_COLUMN, {QObject::tr("Unit")}},
43 {MISSION_COLUMN, {QObject::tr("Mission")}}, {PLUGIN_COLUMN, {QObject::tr("Plugin")}}};
43 {MISSION_COLUMN, {QObject::tr("Mission")}}, {PLUGIN_COLUMN, {QObject::tr("Plugin")}}};
44
44
45 /// Format for datetimes
45 /// Format for datetimes
46 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
46 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
47
47
48
48
49 } // namespace
49 } // namespace
50
50
51 struct VariableModel::VariableModelPrivate {
51 struct VariableModel::VariableModelPrivate {
52 /// Variables created in SciQlop
52 /// Variables created in SciQlop
53 std::vector<std::shared_ptr<Variable> > m_Variables;
53 std::vector<std::shared_ptr<Variable> > m_Variables;
54 std::unordered_map<std::shared_ptr<Variable>, double> m_VariableToProgress;
54 std::unordered_map<std::shared_ptr<Variable>, double> m_VariableToProgress;
55
55
56 /// Return the row index of the variable. -1 if it's not found
56 /// Return the row index of the variable. -1 if it's not found
57 int indexOfVariable(Variable *variable) const noexcept;
57 int indexOfVariable(Variable *variable) const noexcept;
58 };
58 };
59
59
60 VariableModel::VariableModel(QObject *parent)
60 VariableModel::VariableModel(QObject *parent)
61 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
61 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
62 {
62 {
63 }
63 }
64
64
65 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
65 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
66 const SqpRange &dateTime,
66 const SqpRange &dateTime,
67 const QVariantHash &metadata) noexcept
67 const QVariantHash &metadata) noexcept
68 {
68 {
69 auto insertIndex = rowCount();
69 auto insertIndex = rowCount();
70 beginInsertRows({}, insertIndex, insertIndex);
70 beginInsertRows({}, insertIndex, insertIndex);
71
71
72 auto variable = std::make_shared<Variable>(name, dateTime, metadata);
72 auto variable = std::make_shared<Variable>(name, dateTime, metadata);
73
73
74 impl->m_Variables.push_back(variable);
74 impl->m_Variables.push_back(variable);
75 connect(variable.get(), &Variable::updated, this, &VariableModel::onVariableUpdated);
75 connect(variable.get(), &Variable::updated, this, &VariableModel::onVariableUpdated);
76
76
77 endInsertRows();
77 endInsertRows();
78
78
79 return variable;
79 return variable;
80 }
80 }
81
81
82 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
82 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
83 {
83 {
84 if (!variable) {
84 if (!variable) {
85 qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
85 qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
86 return;
86 return;
87 }
87 }
88
88
89 // Finds variable in the model
89 // Finds variable in the model
90 auto begin = impl->m_Variables.cbegin();
90 auto begin = impl->m_Variables.cbegin();
91 auto end = impl->m_Variables.cend();
91 auto end = impl->m_Variables.cend();
92 auto it = std::find(begin, end, variable);
92 auto it = std::find(begin, end, variable);
93 if (it != end) {
93 if (it != end) {
94 auto removeIndex = std::distance(begin, it);
94 auto removeIndex = std::distance(begin, it);
95
95
96 // Deletes variable
96 // Deletes variable
97 beginRemoveRows({}, removeIndex, removeIndex);
97 beginRemoveRows({}, removeIndex, removeIndex);
98 impl->m_Variables.erase(it);
98 impl->m_Variables.erase(it);
99 endRemoveRows();
99 endRemoveRows();
100 }
100 }
101 else {
101 else {
102 qCritical(LOG_VariableModel())
102 qCritical(LOG_VariableModel())
103 << tr("Can't delete variable %1 from the model: the variable is not in the model")
103 << tr("Can't delete variable %1 from the model: the variable is not in the model")
104 .arg(variable->name());
104 .arg(variable->name());
105 }
105 }
106
106
107 // Removes variable from progress map
107 // Removes variable from progress map
108 impl->m_VariableToProgress.erase(variable);
108 impl->m_VariableToProgress.erase(variable);
109 }
109 }
110
110
111
111
112 std::shared_ptr<Variable> VariableModel::variable(int index) const
112 std::shared_ptr<Variable> VariableModel::variable(int index) const
113 {
113 {
114 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
114 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
115 }
115 }
116
116
117 std::vector<std::shared_ptr<Variable> > VariableModel::variables() const
118 {
119 return impl->m_Variables;
120 }
121
117 void VariableModel::setDataProgress(std::shared_ptr<Variable> variable, double progress)
122 void VariableModel::setDataProgress(std::shared_ptr<Variable> variable, double progress)
118 {
123 {
119 if (progress > 0.0) {
124 if (progress > 0.0) {
120 impl->m_VariableToProgress[variable] = progress;
125 impl->m_VariableToProgress[variable] = progress;
121 }
126 }
122 else {
127 else {
123 impl->m_VariableToProgress.erase(variable);
128 impl->m_VariableToProgress.erase(variable);
124 }
129 }
125 auto modelIndex = createIndex(impl->indexOfVariable(variable.get()), NAME_COLUMN);
130 auto modelIndex = createIndex(impl->indexOfVariable(variable.get()), NAME_COLUMN);
126
131
127 emit dataChanged(modelIndex, modelIndex);
132 emit dataChanged(modelIndex, modelIndex);
128 }
133 }
129
134
130 int VariableModel::columnCount(const QModelIndex &parent) const
135 int VariableModel::columnCount(const QModelIndex &parent) const
131 {
136 {
132 Q_UNUSED(parent);
137 Q_UNUSED(parent);
133
138
134 return NB_COLUMNS;
139 return NB_COLUMNS;
135 }
140 }
136
141
137 int VariableModel::rowCount(const QModelIndex &parent) const
142 int VariableModel::rowCount(const QModelIndex &parent) const
138 {
143 {
139 Q_UNUSED(parent);
144 Q_UNUSED(parent);
140
145
141 return impl->m_Variables.size();
146 return impl->m_Variables.size();
142 }
147 }
143
148
144 QVariant VariableModel::data(const QModelIndex &index, int role) const
149 QVariant VariableModel::data(const QModelIndex &index, int role) const
145 {
150 {
146 if (!index.isValid()) {
151 if (!index.isValid()) {
147 return QVariant{};
152 return QVariant{};
148 }
153 }
149
154
150 if (index.row() < 0 || index.row() >= rowCount()) {
155 if (index.row() < 0 || index.row() >= rowCount()) {
151 return QVariant{};
156 return QVariant{};
152 }
157 }
153
158
154 if (role == Qt::DisplayRole) {
159 if (role == Qt::DisplayRole) {
155 if (auto variable = impl->m_Variables.at(index.row()).get()) {
160 if (auto variable = impl->m_Variables.at(index.row()).get()) {
156 switch (index.column()) {
161 switch (index.column()) {
157 case NAME_COLUMN:
162 case NAME_COLUMN:
158 return variable->name();
163 return variable->name();
159 case TSTART_COLUMN: {
164 case TSTART_COLUMN: {
160 auto range = variable->realRange();
165 auto range = variable->realRange();
161 return range != INVALID_RANGE
166 return range != INVALID_RANGE
162 ? DateUtils::dateTime(range.m_TStart).toString(DATETIME_FORMAT)
167 ? DateUtils::dateTime(range.m_TStart).toString(DATETIME_FORMAT)
163 : QVariant{};
168 : QVariant{};
164 }
169 }
165 case TEND_COLUMN: {
170 case TEND_COLUMN: {
166 auto range = variable->realRange();
171 auto range = variable->realRange();
167 return range != INVALID_RANGE
172 return range != INVALID_RANGE
168 ? DateUtils::dateTime(range.m_TEnd).toString(DATETIME_FORMAT)
173 ? DateUtils::dateTime(range.m_TEnd).toString(DATETIME_FORMAT)
169 : QVariant{};
174 : QVariant{};
170 }
175 }
171 case UNIT_COLUMN:
176 case UNIT_COLUMN:
172 return variable->metadata().value(QStringLiteral("units"));
177 return variable->metadata().value(QStringLiteral("units"));
173 case MISSION_COLUMN:
178 case MISSION_COLUMN:
174 return variable->metadata().value(QStringLiteral("mission"));
179 return variable->metadata().value(QStringLiteral("mission"));
175 case PLUGIN_COLUMN:
180 case PLUGIN_COLUMN:
176 return variable->metadata().value(QStringLiteral("plugin"));
181 return variable->metadata().value(QStringLiteral("plugin"));
177 default:
182 default:
178 // No action
183 // No action
179 break;
184 break;
180 }
185 }
181
186
182 qWarning(LOG_VariableModel())
187 qWarning(LOG_VariableModel())
183 << tr("Can't get data (unknown column %1)").arg(index.column());
188 << tr("Can't get data (unknown column %1)").arg(index.column());
184 }
189 }
185 else {
190 else {
186 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
191 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
187 }
192 }
188 }
193 }
189 else if (role == VariableRoles::ProgressRole) {
194 else if (role == VariableRoles::ProgressRole) {
190 if (auto variable = impl->m_Variables.at(index.row())) {
195 if (auto variable = impl->m_Variables.at(index.row())) {
191
196
192 auto it = impl->m_VariableToProgress.find(variable);
197 auto it = impl->m_VariableToProgress.find(variable);
193 if (it != impl->m_VariableToProgress.cend()) {
198 if (it != impl->m_VariableToProgress.cend()) {
194 return it->second;
199 return it->second;
195 }
200 }
196 }
201 }
197 }
202 }
198
203
199 return QVariant{};
204 return QVariant{};
200 }
205 }
201
206
202 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
207 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
203 {
208 {
204 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
209 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
205 return QVariant{};
210 return QVariant{};
206 }
211 }
207
212
208 if (orientation == Qt::Horizontal) {
213 if (orientation == Qt::Horizontal) {
209 auto propertiesIt = COLUMN_PROPERTIES.find(section);
214 auto propertiesIt = COLUMN_PROPERTIES.find(section);
210 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
215 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
211 // Role is either DisplayRole or SizeHintRole
216 // Role is either DisplayRole or SizeHintRole
212 return (role == Qt::DisplayRole)
217 return (role == Qt::DisplayRole)
213 ? QVariant{propertiesIt->m_Name}
218 ? QVariant{propertiesIt->m_Name}
214 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
219 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
215 }
220 }
216 else {
221 else {
217 qWarning(LOG_VariableModel())
222 qWarning(LOG_VariableModel())
218 << tr("Can't get header data (unknown column %1)").arg(section);
223 << tr("Can't get header data (unknown column %1)").arg(section);
219 }
224 }
220 }
225 }
221
226
222 return QVariant{};
227 return QVariant{};
223 }
228 }
224
229
225 void VariableModel::abortProgress(const QModelIndex &index)
230 void VariableModel::abortProgress(const QModelIndex &index)
226 {
231 {
227 if (auto variable = impl->m_Variables.at(index.row())) {
232 if (auto variable = impl->m_Variables.at(index.row())) {
228 emit abortProgessRequested(variable);
233 emit abortProgessRequested(variable);
229 }
234 }
230 }
235 }
231
236
232 void VariableModel::onVariableUpdated() noexcept
237 void VariableModel::onVariableUpdated() noexcept
233 {
238 {
234 // Finds variable that has been updated in the model
239 // Finds variable that has been updated in the model
235 if (auto updatedVariable = dynamic_cast<Variable *>(sender())) {
240 if (auto updatedVariable = dynamic_cast<Variable *>(sender())) {
236 auto updatedVariableIndex = impl->indexOfVariable(updatedVariable);
241 auto updatedVariableIndex = impl->indexOfVariable(updatedVariable);
237
242
238 if (updatedVariableIndex > -1) {
243 if (updatedVariableIndex > -1) {
239 emit dataChanged(createIndex(updatedVariableIndex, 0),
244 emit dataChanged(createIndex(updatedVariableIndex, 0),
240 createIndex(updatedVariableIndex, columnCount() - 1));
245 createIndex(updatedVariableIndex, columnCount() - 1));
241 }
246 }
242 }
247 }
243 }
248 }
244
249
245 int VariableModel::VariableModelPrivate::indexOfVariable(Variable *variable) const noexcept
250 int VariableModel::VariableModelPrivate::indexOfVariable(Variable *variable) const noexcept
246 {
251 {
247 auto begin = std::cbegin(m_Variables);
252 auto begin = std::cbegin(m_Variables);
248 auto end = std::cend(m_Variables);
253 auto end = std::cend(m_Variables);
249 auto it
254 auto it
250 = std::find_if(begin, end, [variable](const auto &var) { return var.get() == variable; });
255 = std::find_if(begin, end, [variable](const auto &var) { return var.get() == variable; });
251
256
252 if (it != end) {
257 if (it != end) {
253 // Gets the index of the variable in the model: we assume here that views have the same
258 // Gets the index of the variable in the model: we assume here that views have the same
254 // order as the model
259 // order as the model
255 return std::distance(begin, it);
260 return std::distance(begin, it);
256 }
261 }
257 else {
262 else {
258 return -1;
263 return -1;
259 }
264 }
260 }
265 }
General Comments 0
You need to be logged in to leave comments. Login now