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