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