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