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