##// END OF EJS Templates
Corrects regression on variable destruction
Alexandre Leroux -
r386:4458a8f811e4
parent child
Show More
@@ -1,212 +1,215
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableCacheController.h>
2 #include <Variable/VariableCacheController.h>
3 #include <Variable/VariableController.h>
3 #include <Variable/VariableController.h>
4 #include <Variable/VariableModel.h>
4 #include <Variable/VariableModel.h>
5
5
6 #include <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
7 #include <Data/IDataProvider.h>
7 #include <Data/IDataProvider.h>
8 #include <Data/IDataSeries.h>
8 #include <Data/IDataSeries.h>
9 #include <Time/TimeController.h>
9 #include <Time/TimeController.h>
10
10
11 #include <QDateTime>
11 #include <QDateTime>
12 #include <QMutex>
12 #include <QMutex>
13 #include <QThread>
13 #include <QThread>
14 #include <QUuid>
14 #include <QUuid>
15 #include <QtCore/QItemSelectionModel>
15 #include <QtCore/QItemSelectionModel>
16
16
17 #include <unordered_map>
17 #include <unordered_map>
18
18
19 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
19 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
20
20
21 struct VariableController::VariableControllerPrivate {
21 struct VariableController::VariableControllerPrivate {
22 explicit VariableControllerPrivate(VariableController *parent)
22 explicit VariableControllerPrivate(VariableController *parent)
23 : m_WorkingMutex{},
23 : m_WorkingMutex{},
24 m_VariableModel{new VariableModel{parent}},
24 m_VariableModel{new VariableModel{parent}},
25 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
25 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
26 m_VariableCacheController{std::make_unique<VariableCacheController>()}
26 m_VariableCacheController{std::make_unique<VariableCacheController>()}
27 {
27 {
28 }
28 }
29
29
30 QMutex m_WorkingMutex;
30 QMutex m_WorkingMutex;
31 /// Variable model. The VariableController has the ownership
31 /// Variable model. The VariableController has the ownership
32 VariableModel *m_VariableModel;
32 VariableModel *m_VariableModel;
33 QItemSelectionModel *m_VariableSelectionModel;
33 QItemSelectionModel *m_VariableSelectionModel;
34
34
35
35
36 TimeController *m_TimeController{nullptr};
36 TimeController *m_TimeController{nullptr};
37 std::unique_ptr<VariableCacheController> m_VariableCacheController;
37 std::unique_ptr<VariableCacheController> m_VariableCacheController;
38
38
39 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
39 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
40 m_VariableToProviderMap;
40 m_VariableToProviderMap;
41 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifier;
41 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
42 };
42 };
43
43
44 VariableController::VariableController(QObject *parent)
44 VariableController::VariableController(QObject *parent)
45 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
45 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
46 {
46 {
47 qCDebug(LOG_VariableController()) << tr("VariableController construction")
47 qCDebug(LOG_VariableController()) << tr("VariableController construction")
48 << QThread::currentThread();
48 << QThread::currentThread();
49 }
49 }
50
50
51 VariableController::~VariableController()
51 VariableController::~VariableController()
52 {
52 {
53 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
53 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
54 << QThread::currentThread();
54 << QThread::currentThread();
55 this->waitForFinish();
55 this->waitForFinish();
56 }
56 }
57
57
58 VariableModel *VariableController::variableModel() noexcept
58 VariableModel *VariableController::variableModel() noexcept
59 {
59 {
60 return impl->m_VariableModel;
60 return impl->m_VariableModel;
61 }
61 }
62
62
63 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
63 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
64 {
64 {
65 return impl->m_VariableSelectionModel;
65 return impl->m_VariableSelectionModel;
66 }
66 }
67
67
68 void VariableController::setTimeController(TimeController *timeController) noexcept
68 void VariableController::setTimeController(TimeController *timeController) noexcept
69 {
69 {
70 impl->m_TimeController = timeController;
70 impl->m_TimeController = timeController;
71 }
71 }
72
72
73 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
73 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
74 {
74 {
75 if (!variable) {
75 if (!variable) {
76 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
76 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
77 return;
77 return;
78 }
78 }
79
79
80 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
80 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
81 // make some treatments before the deletion
81 // make some treatments before the deletion
82 emit variableAboutToBeDeleted(variable);
82 emit variableAboutToBeDeleted(variable);
83
83
84 // Deletes identifier
85 impl->m_VariableToIdentifierMap.erase(variable);
86
84 // Deletes provider
87 // Deletes provider
85 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
88 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
86 qCDebug(LOG_VariableController())
89 qCDebug(LOG_VariableController())
87 << tr("Number of providers deleted for variable %1: %2")
90 << tr("Number of providers deleted for variable %1: %2")
88 .arg(variable->name(), QString::number(nbProvidersDeleted));
91 .arg(variable->name(), QString::number(nbProvidersDeleted));
89
92
90 // Clears cache
93 // Clears cache
91 impl->m_VariableCacheController->clear(variable);
94 impl->m_VariableCacheController->clear(variable);
92
95
93 // Deletes from model
96 // Deletes from model
94 impl->m_VariableModel->deleteVariable(variable);
97 impl->m_VariableModel->deleteVariable(variable);
95 }
98 }
96
99
97 void VariableController::deleteVariables(
100 void VariableController::deleteVariables(
98 const QVector<std::shared_ptr<Variable> > &variables) noexcept
101 const QVector<std::shared_ptr<Variable> > &variables) noexcept
99 {
102 {
100 for (auto variable : qAsConst(variables)) {
103 for (auto variable : qAsConst(variables)) {
101 deleteVariable(variable);
104 deleteVariable(variable);
102 }
105 }
103 }
106 }
104
107
105 void VariableController::createVariable(const QString &name, const QVariantHash &metadata,
108 void VariableController::createVariable(const QString &name, const QVariantHash &metadata,
106 std::shared_ptr<IDataProvider> provider) noexcept
109 std::shared_ptr<IDataProvider> provider) noexcept
107 {
110 {
108
111
109 if (!impl->m_TimeController) {
112 if (!impl->m_TimeController) {
110 qCCritical(LOG_VariableController())
113 qCCritical(LOG_VariableController())
111 << tr("Impossible to create variable: The time controller is null");
114 << tr("Impossible to create variable: The time controller is null");
112 return;
115 return;
113 }
116 }
114
117
115 auto dateTime = impl->m_TimeController->dateTime();
118 auto dateTime = impl->m_TimeController->dateTime();
116
119
117 if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime, metadata)) {
120 if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime, metadata)) {
118 auto identifier = QUuid::createUuid();
121 auto identifier = QUuid::createUuid();
119
122
120 // store the provider
123 // store the provider
121 impl->m_VariableToProviderMap[newVariable] = provider;
124 impl->m_VariableToProviderMap[newVariable] = provider;
122 impl->m_VariableToIdentifier[newVariable] = identifier;
125 impl->m_VariableToIdentifierMap[newVariable] = identifier;
123
126
124 auto addDateTimeAcquired = [ this, varW = std::weak_ptr<Variable>{newVariable} ](
127 auto addDateTimeAcquired = [ this, varW = std::weak_ptr<Variable>{newVariable} ](
125 QUuid identifier, auto dataSeriesAcquired, auto dateTimeToPutInCache)
128 QUuid identifier, auto dataSeriesAcquired, auto dateTimeToPutInCache)
126 {
129 {
127 if (auto variable = varW.lock()) {
130 if (auto variable = varW.lock()) {
128 auto varIdentifier = impl->m_VariableToIdentifier.at(variable);
131 auto varIdentifier = impl->m_VariableToIdentifierMap.at(variable);
129 if (varIdentifier == identifier) {
132 if (varIdentifier == identifier) {
130 impl->m_VariableCacheController->addDateTime(variable, dateTimeToPutInCache);
133 impl->m_VariableCacheController->addDateTime(variable, dateTimeToPutInCache);
131 variable->setDataSeries(dataSeriesAcquired);
134 variable->setDataSeries(dataSeriesAcquired);
132 }
135 }
133 }
136 }
134 };
137 };
135
138
136 connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
139 connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
137 this->onRequestDataLoading(newVariable, dateTime);
140 this->onRequestDataLoading(newVariable, dateTime);
138 }
141 }
139 }
142 }
140
143
141 void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
144 void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
142 {
145 {
143 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
146 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
144 << QThread::currentThread()->objectName();
147 << QThread::currentThread()->objectName();
145 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
148 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
146
149
147 for (const auto &selectedRow : qAsConst(selectedRows)) {
150 for (const auto &selectedRow : qAsConst(selectedRows)) {
148 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
151 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
149 selectedVariable->setDateTime(dateTime);
152 selectedVariable->setDateTime(dateTime);
150 this->onRequestDataLoading(selectedVariable, dateTime);
153 this->onRequestDataLoading(selectedVariable, dateTime);
151 }
154 }
152 }
155 }
153 }
156 }
154
157
155 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
158 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
156 {
159 {
157 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
160 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
158
161
159 auto end = impl->m_VariableToIdentifier.cend();
162 auto end = impl->m_VariableToIdentifierMap.cend();
160 auto it = std::find_if(impl->m_VariableToIdentifier.cbegin(), end, findReply);
163 auto it = std::find_if(impl->m_VariableToIdentifierMap.cbegin(), end, findReply);
161 if (it != end) {
164 if (it != end) {
162 impl->m_VariableModel->setDataProgress(it->first, progress);
165 impl->m_VariableModel->setDataProgress(it->first, progress);
163 }
166 }
164 }
167 }
165
168
166
169
167 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
170 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
168 const SqpDateTime &dateTime)
171 const SqpDateTime &dateTime)
169 {
172 {
170 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
173 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
171 << QThread::currentThread()->objectName();
174 << QThread::currentThread()->objectName();
172 // we want to load data of the variable for the dateTime.
175 // we want to load data of the variable for the dateTime.
173 // First we check if the cache contains some of them.
176 // First we check if the cache contains some of them.
174 // For the other, we ask the provider to give them.
177 // For the other, we ask the provider to give them.
175 if (variable) {
178 if (variable) {
176
179
177 auto dateTimeListNotInCache
180 auto dateTimeListNotInCache
178 = impl->m_VariableCacheController->provideNotInCacheDateTimeList(variable, dateTime);
181 = impl->m_VariableCacheController->provideNotInCacheDateTimeList(variable, dateTime);
179
182
180 if (!dateTimeListNotInCache.empty()) {
183 if (!dateTimeListNotInCache.empty()) {
181 // Ask the provider for each data on the dateTimeListNotInCache
184 // Ask the provider for each data on the dateTimeListNotInCache
182 auto identifier = impl->m_VariableToIdentifier.at(variable);
185 auto identifier = impl->m_VariableToIdentifierMap.at(variable);
183 impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
186 impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
184 identifier,
187 identifier,
185 DataProviderParameters{std::move(dateTimeListNotInCache), variable->metadata()});
188 DataProviderParameters{std::move(dateTimeListNotInCache), variable->metadata()});
186 }
189 }
187 else {
190 else {
188 emit variable->updated();
191 emit variable->updated();
189 }
192 }
190 }
193 }
191 else {
194 else {
192 qCCritical(LOG_VariableController()) << tr("Impossible to load data of a variable null");
195 qCCritical(LOG_VariableController()) << tr("Impossible to load data of a variable null");
193 }
196 }
194 }
197 }
195
198
196
199
197 void VariableController::initialize()
200 void VariableController::initialize()
198 {
201 {
199 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
202 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
200 impl->m_WorkingMutex.lock();
203 impl->m_WorkingMutex.lock();
201 qCDebug(LOG_VariableController()) << tr("VariableController init END");
204 qCDebug(LOG_VariableController()) << tr("VariableController init END");
202 }
205 }
203
206
204 void VariableController::finalize()
207 void VariableController::finalize()
205 {
208 {
206 impl->m_WorkingMutex.unlock();
209 impl->m_WorkingMutex.unlock();
207 }
210 }
208
211
209 void VariableController::waitForFinish()
212 void VariableController::waitForFinish()
210 {
213 {
211 QMutexLocker locker{&impl->m_WorkingMutex};
214 QMutexLocker locker{&impl->m_WorkingMutex};
212 }
215 }
@@ -1,235 +1,233
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableModel.h>
2 #include <Variable/VariableModel.h>
3
3
4 #include <Data/IDataSeries.h>
4 #include <Data/IDataSeries.h>
5
5
6 #include <QDateTime>
6 #include <QDateTime>
7 #include <QSize>
7 #include <QSize>
8 #include <unordered_map>
8 #include <unordered_map>
9
9
10 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
10 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
11
11
12 namespace {
12 namespace {
13
13
14 // Column indexes
14 // Column indexes
15 const auto NAME_COLUMN = 0;
15 const auto NAME_COLUMN = 0;
16 const auto TSTART_COLUMN = 1;
16 const auto TSTART_COLUMN = 1;
17 const auto TEND_COLUMN = 2;
17 const auto TEND_COLUMN = 2;
18 const auto NB_COLUMNS = 3;
18 const auto NB_COLUMNS = 3;
19
19
20 // Column properties
20 // Column properties
21 const auto DEFAULT_HEIGHT = 25;
21 const auto DEFAULT_HEIGHT = 25;
22 const auto DEFAULT_WIDTH = 100;
22 const auto DEFAULT_WIDTH = 100;
23
23
24 struct ColumnProperties {
24 struct ColumnProperties {
25 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
25 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
26 int height = DEFAULT_HEIGHT)
26 int height = DEFAULT_HEIGHT)
27 : m_Name{name}, m_Width{width}, m_Height{height}
27 : m_Name{name}, m_Width{width}, m_Height{height}
28 {
28 {
29 }
29 }
30
30
31 QString m_Name;
31 QString m_Name;
32 int m_Width;
32 int m_Width;
33 int m_Height;
33 int m_Height;
34 };
34 };
35
35
36 const auto COLUMN_PROPERTIES
36 const auto COLUMN_PROPERTIES
37 = QHash<int, ColumnProperties>{{NAME_COLUMN, {QObject::tr("Name")}},
37 = QHash<int, ColumnProperties>{{NAME_COLUMN, {QObject::tr("Name")}},
38 {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
38 {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
39 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}};
39 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}};
40
40
41 /// Format for datetimes
41 /// Format for datetimes
42 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
42 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
43
43
44
44
45 } // namespace
45 } // namespace
46
46
47 struct VariableModel::VariableModelPrivate {
47 struct VariableModel::VariableModelPrivate {
48 /// Variables created in SciQlop
48 /// Variables created in SciQlop
49 std::vector<std::shared_ptr<Variable> > m_Variables;
49 std::vector<std::shared_ptr<Variable> > m_Variables;
50 std::unordered_map<std::shared_ptr<Variable>, double> m_VariableToProgress;
50 std::unordered_map<Variable *, double> m_VariableToProgress;
51
52
51
53 /// Return the row index of the variable. -1 if it's not found
52 /// Return the row index of the variable. -1 if it's not found
54 int indexOfVariable(Variable *variable) const noexcept;
53 int indexOfVariable(Variable *variable) const noexcept;
55 };
54 };
56
55
57 VariableModel::VariableModel(QObject *parent)
56 VariableModel::VariableModel(QObject *parent)
58 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
57 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
59 {
58 {
60 }
59 }
61
60
62 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
61 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
63 const SqpDateTime &dateTime,
62 const SqpDateTime &dateTime,
64 const QVariantHash &metadata) noexcept
63 const QVariantHash &metadata) noexcept
65 {
64 {
66 auto insertIndex = rowCount();
65 auto insertIndex = rowCount();
67 beginInsertRows({}, insertIndex, insertIndex);
66 beginInsertRows({}, insertIndex, insertIndex);
68
67
69 auto variable = std::make_shared<Variable>(name, dateTime, metadata);
68 auto variable = std::make_shared<Variable>(name, dateTime, metadata);
70
69
71 impl->m_Variables.push_back(variable);
70 impl->m_Variables.push_back(variable);
72 connect(variable.get(), &Variable::updated, this, &VariableModel::onVariableUpdated);
71 connect(variable.get(), &Variable::updated, this, &VariableModel::onVariableUpdated);
73
72
74 endInsertRows();
73 endInsertRows();
75
74
76 return variable;
75 return variable;
77 }
76 }
78
77
79 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
78 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
80 {
79 {
81 if (!variable) {
80 if (!variable) {
82 qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
81 qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
83 return;
82 return;
84 }
83 }
85
84
86 // Finds variable in the model
85 // Finds variable in the model
87 auto begin = impl->m_Variables.cbegin();
86 auto begin = impl->m_Variables.cbegin();
88 auto end = impl->m_Variables.cend();
87 auto end = impl->m_Variables.cend();
89 auto it = std::find(begin, end, variable);
88 auto it = std::find(begin, end, variable);
90 if (it != end) {
89 if (it != end) {
91 auto removeIndex = std::distance(begin, it);
90 auto removeIndex = std::distance(begin, it);
92
91
93 // Deletes variable
92 // Deletes variable
94 beginRemoveRows({}, removeIndex, removeIndex);
93 beginRemoveRows({}, removeIndex, removeIndex);
95 impl->m_Variables.erase(it);
94 impl->m_Variables.erase(it);
96 endRemoveRows();
95 endRemoveRows();
97 }
96 }
98 else {
97 else {
99 qCritical(LOG_VariableModel())
98 qCritical(LOG_VariableModel())
100 << tr("Can't delete variable %1 from the model: the variable is not in the model")
99 << tr("Can't delete variable %1 from the model: the variable is not in the model")
101 .arg(variable->name());
100 .arg(variable->name());
102 }
101 }
103 }
102 }
104
103
105
104
106 std::shared_ptr<Variable> VariableModel::variable(int index) const
105 std::shared_ptr<Variable> VariableModel::variable(int index) const
107 {
106 {
108 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
107 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
109 }
108 }
110
109
111 void VariableModel::setDataProgress(std::shared_ptr<Variable> variable, double progress)
110 void VariableModel::setDataProgress(std::shared_ptr<Variable> variable, double progress)
112 {
111 {
113
112 impl->m_VariableToProgress[variable.get()] = progress;
114 impl->m_VariableToProgress[variable] = progress;
115 auto modelIndex = createIndex(impl->indexOfVariable(variable.get()), NAME_COLUMN);
113 auto modelIndex = createIndex(impl->indexOfVariable(variable.get()), NAME_COLUMN);
116
114
117 emit dataChanged(modelIndex, modelIndex);
115 emit dataChanged(modelIndex, modelIndex);
118 }
116 }
119
117
120 int VariableModel::columnCount(const QModelIndex &parent) const
118 int VariableModel::columnCount(const QModelIndex &parent) const
121 {
119 {
122 Q_UNUSED(parent);
120 Q_UNUSED(parent);
123
121
124 return NB_COLUMNS;
122 return NB_COLUMNS;
125 }
123 }
126
124
127 int VariableModel::rowCount(const QModelIndex &parent) const
125 int VariableModel::rowCount(const QModelIndex &parent) const
128 {
126 {
129 Q_UNUSED(parent);
127 Q_UNUSED(parent);
130
128
131 return impl->m_Variables.size();
129 return impl->m_Variables.size();
132 }
130 }
133
131
134 QVariant VariableModel::data(const QModelIndex &index, int role) const
132 QVariant VariableModel::data(const QModelIndex &index, int role) const
135 {
133 {
136 if (!index.isValid()) {
134 if (!index.isValid()) {
137 return QVariant{};
135 return QVariant{};
138 }
136 }
139
137
140 if (index.row() < 0 || index.row() >= rowCount()) {
138 if (index.row() < 0 || index.row() >= rowCount()) {
141 return QVariant{};
139 return QVariant{};
142 }
140 }
143
141
144 if (role == Qt::DisplayRole) {
142 if (role == Qt::DisplayRole) {
145 if (auto variable = impl->m_Variables.at(index.row()).get()) {
143 if (auto variable = impl->m_Variables.at(index.row()).get()) {
146 /// Lambda function that builds the variant to return for a time value
144 /// Lambda function that builds the variant to return for a time value
147 auto dateTimeVariant = [](double time) {
145 auto dateTimeVariant = [](double time) {
148 auto dateTime = QDateTime::fromMSecsSinceEpoch(time * 1000.);
146 auto dateTime = QDateTime::fromMSecsSinceEpoch(time * 1000.);
149 return dateTime.toString(DATETIME_FORMAT);
147 return dateTime.toString(DATETIME_FORMAT);
150 };
148 };
151
149
152 switch (index.column()) {
150 switch (index.column()) {
153 case NAME_COLUMN:
151 case NAME_COLUMN:
154 return variable->name();
152 return variable->name();
155 case TSTART_COLUMN:
153 case TSTART_COLUMN:
156 return dateTimeVariant(variable->dateTime().m_TStart);
154 return dateTimeVariant(variable->dateTime().m_TStart);
157 case TEND_COLUMN:
155 case TEND_COLUMN:
158 return dateTimeVariant(variable->dateTime().m_TEnd);
156 return dateTimeVariant(variable->dateTime().m_TEnd);
159 default:
157 default:
160 // No action
158 // No action
161 break;
159 break;
162 }
160 }
163
161
164 qWarning(LOG_VariableModel())
162 qWarning(LOG_VariableModel())
165 << tr("Can't get data (unknown column %1)").arg(index.column());
163 << tr("Can't get data (unknown column %1)").arg(index.column());
166 }
164 }
167 else {
165 else {
168 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
166 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
169 }
167 }
170 }
168 }
171 else if (role == VariableRoles::ProgressRole) {
169 else if (role == VariableRoles::ProgressRole) {
172 if (auto variable = impl->m_Variables.at(index.row())) {
170 if (auto variable = impl->m_Variables.at(index.row())) {
173
171
174 auto it = impl->m_VariableToProgress.find(variable);
172 auto it = impl->m_VariableToProgress.find(variable.get());
175 if (it != impl->m_VariableToProgress.cend()) {
173 if (it != impl->m_VariableToProgress.cend()) {
176 return it->second;
174 return it->second;
177 }
175 }
178 }
176 }
179 }
177 }
180
178
181 return QVariant{};
179 return QVariant{};
182 }
180 }
183
181
184 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
182 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
185 {
183 {
186 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
184 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
187 return QVariant{};
185 return QVariant{};
188 }
186 }
189
187
190 if (orientation == Qt::Horizontal) {
188 if (orientation == Qt::Horizontal) {
191 auto propertiesIt = COLUMN_PROPERTIES.find(section);
189 auto propertiesIt = COLUMN_PROPERTIES.find(section);
192 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
190 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
193 // Role is either DisplayRole or SizeHintRole
191 // Role is either DisplayRole or SizeHintRole
194 return (role == Qt::DisplayRole)
192 return (role == Qt::DisplayRole)
195 ? QVariant{propertiesIt->m_Name}
193 ? QVariant{propertiesIt->m_Name}
196 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
194 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
197 }
195 }
198 else {
196 else {
199 qWarning(LOG_VariableModel())
197 qWarning(LOG_VariableModel())
200 << tr("Can't get header data (unknown column %1)").arg(section);
198 << tr("Can't get header data (unknown column %1)").arg(section);
201 }
199 }
202 }
200 }
203
201
204 return QVariant{};
202 return QVariant{};
205 }
203 }
206
204
207 void VariableModel::onVariableUpdated() noexcept
205 void VariableModel::onVariableUpdated() noexcept
208 {
206 {
209 // Finds variable that has been updated in the model
207 // Finds variable that has been updated in the model
210 if (auto updatedVariable = dynamic_cast<Variable *>(sender())) {
208 if (auto updatedVariable = dynamic_cast<Variable *>(sender())) {
211 auto updatedVariableIndex = impl->indexOfVariable(updatedVariable);
209 auto updatedVariableIndex = impl->indexOfVariable(updatedVariable);
212
210
213 if (updatedVariableIndex > -1) {
211 if (updatedVariableIndex > -1) {
214 emit dataChanged(createIndex(updatedVariableIndex, 0),
212 emit dataChanged(createIndex(updatedVariableIndex, 0),
215 createIndex(updatedVariableIndex, columnCount() - 1));
213 createIndex(updatedVariableIndex, columnCount() - 1));
216 }
214 }
217 }
215 }
218 }
216 }
219
217
220 int VariableModel::VariableModelPrivate::indexOfVariable(Variable *variable) const noexcept
218 int VariableModel::VariableModelPrivate::indexOfVariable(Variable *variable) const noexcept
221 {
219 {
222 auto begin = std::cbegin(m_Variables);
220 auto begin = std::cbegin(m_Variables);
223 auto end = std::cend(m_Variables);
221 auto end = std::cend(m_Variables);
224 auto it
222 auto it
225 = std::find_if(begin, end, [variable](const auto &var) { return var.get() == variable; });
223 = std::find_if(begin, end, [variable](const auto &var) { return var.get() == variable; });
226
224
227 if (it != end) {
225 if (it != end) {
228 // Gets the index of the variable in the model: we assume here that views have the same
226 // Gets the index of the variable in the model: we assume here that views have the same
229 // order as the model
227 // order as the model
230 return std::distance(begin, it);
228 return std::distance(begin, it);
231 }
229 }
232 else {
230 else {
233 return -1;
231 return -1;
234 }
232 }
235 }
233 }
General Comments 3
Under Review
author

Pull request updated. Auto status change to "Under Review"

Changed commits:
  * 3 added
  * 0 removed

Changed files:
  * A plugins/amda/tests-resources/TestAmdaResultParser/FileNotFound.txt
  * M gui/src/Visualization/operations/RescaleAxeOperation.cpp
  * M app/src/MainWindow.cpp
  * M core/include/Data/IDataProvider.h
  * M core/include/DataSource/DataSourceItemAction.h
  * M core/include/Variable/VariableController.h
  * M core/include/Variable/VariableModel.h
  * M core/include/Visualization/VisualizationController.h
  * M core/src/Network/NetworkController.cpp
  * M core/src/Variable/Variable.cpp
  * M core/src/Variable/VariableController.cpp
  * M core/src/Variable/VariableModel.cpp
  * M gui/include/Visualization/VisualizationGraphWidget.h
  * M gui/include/Visualization/VisualizationWidget.h
  * M gui/src/SqpApplication.cpp
  * M gui/src/Variable/VariableInspectorWidget.cpp
  * M gui/src/Visualization/VisualizationGraphHelper.cpp
  * M gui/src/Visualization/VisualizationGraphWidget.cpp
  * M gui/src/Visualization/VisualizationWidget.cpp
  * M gui/src/Visualization/VisualizationZoneWidget.cpp
  * M plugins/amda/include/AmdaProvider.h
  * M plugins/amda/src/AmdaProvider.cpp
  * M plugins/amda/src/AmdaResultParser.cpp
  * M plugins/amda/tests/TestAmdaResultParser.cpp
  * M plugins/mockplugin/include/CosinusProvider.h
  * M plugins/mockplugin/src/CosinusProvider.cpp
  * R COPYING
  * R app/ui/MainWindow.ui
  * R cmake/sciqlop_package_qt.cmake
  * R core/include/Common/MetaTypes.h
  * R core/include/Data/ArrayData.h
  * R core/include/Data/DataProviderParameters.h
  * R core/include/Data/DataSeries.h
  * R core/include/Data/IDataSeries.h
  * R core/include/Data/ScalarSeries.h
  * R core/include/Data/SqpDateTime.h
  * R core/include/Network/NetworkController.h
  * R core/include/Plugin/PluginManager.h
  * R core/include/Time/TimeController.h
  * R core/include/Variable/Variable.h
  * R core/include/Variable/VariableCacheController.h
  * R core/src/Data/ScalarSeries.cpp
  * R core/src/DataSource/DataSourceItemAction.cpp
  * R core/src/Plugin/PluginManager.cpp
  * R core/src/Time/TimeController.cpp
  * R core/src/Variable/VariableCacheController.cpp
  * R core/src/Visualization/VisualizationController.cpp
  * R core/tests/Variable/TestVariableCacheController.cpp
  * R gui/include/DataSource/DataSourceTreeWidgetItem.h
  * R gui/include/DataSource/DataSourceWidget.h
  * R gui/include/SidePane/SqpSidePane.h
  * R gui/include/TimeWidget/TimeWidget.h
  * R gui/include/Variable/VariableInspectorWidget.h
  * R gui/include/Variable/VariableMenuHeaderWidget.h
  * R gui/include/Visualization/IVariableContainer.h
  * R gui/include/Visualization/IVisualizationWidget.h
  * R gui/include/Visualization/IVisualizationWidgetVisitor.h
  * R gui/include/Visualization/VisualizationGraphHelper.h
  * R gui/include/Visualization/VisualizationTabWidget.h
  * R gui/include/Visualization/VisualizationZoneWidget.h
  * R gui/include/Visualization/operations/GenerateVariableMenuOperation.h
  * R gui/include/Visualization/operations/MenuBuilder.h
  * R gui/include/Visualization/operations/RemoveVariableOperation.h
  * R gui/include/Visualization/qcustomplot.h
  * R gui/resources/icones/dataSourceComponent.png
  * R gui/resources/icones/dataSourceNode.png
  * R gui/resources/icones/dataSourceProduct.png
  * R gui/resources/icones/dataSourceRoot.png
  * R gui/resources/icones/delete.png
  * R gui/resources/icones/next.png
  * R gui/resources/icones/openInspector.png
  * R gui/resources/icones/plot.png
  * R gui/resources/icones/previous.png
  * R gui/resources/icones/sciqlop2PNG_1024.png
  * R gui/resources/icones/unplot.png
  * R gui/resources/sqpguiresources.qrc
  * R gui/src/DataSource/DataSourceTreeWidgetItem.cpp
  * R gui/src/DataSource/DataSourceWidget.cpp
  * R gui/src/SidePane/SqpSidePane.cpp
  * R gui/src/TimeWidget/TimeWidget.cpp
  * R gui/src/Variable/VariableMenuHeaderWidget.cpp
  * R gui/src/Visualization/VisualizationTabWidget.cpp
  * R gui/src/Visualization/operations/GenerateVariableMenuOperation.cpp
  * R gui/src/Visualization/operations/MenuBuilder.cpp
  * R gui/src/Visualization/operations/RemoveVariableOperation.cpp
  * R gui/src/Visualization/qcustomplot.cpp
  * R gui/ui/DataSource/DataSourceWidget.ui
  * R gui/ui/SidePane/SqpSidePane.ui
  * R gui/ui/TimeWidget/TimeWidget.ui
  * R gui/ui/Variable/VariableInspectorWidget.ui
  * R gui/ui/Variable/VariableMenuHeaderWidget.ui
  * R gui/ui/Visualization/VisualizationGraphWidget.ui
  * R gui/ui/Visualization/VisualizationTabWidget.ui
  * R gui/ui/Visualization/VisualizationWidget.ui
  * R gui/ui/Visualization/VisualizationZoneWidget.ui
  * R gui/vera-exclusions/exclusions.txt
  * R plugin/CMakeLists.txt
  * R plugin/cmake/Findsciqlop-plugin.cmake
  * R plugin/include/Plugin/IPlugin.h
  * R plugins/amda/CMakeLists.txt
  * R plugins/amda/cmake/Findsciqlop-amda.cmake
  * R plugins/amda/include/AmdaDefs.h
  * R plugins/amda/include/AmdaGlobal.h
  * R plugins/amda/include/AmdaParser.h
  * R plugins/amda/include/AmdaPlugin.h
  * R plugins/amda/include/AmdaResultParser.h
  * R plugins/amda/resources/amda.json
  * R plugins/amda/resources/amdaresources.qrc
  * R plugins/amda/resources/samples/AmdaSample.json
  * R plugins/amda/src/AmdaDefs.cpp
  * R plugins/amda/src/AmdaParser.cpp
  * R plugins/amda/src/AmdaPlugin.cpp
  * R plugins/amda/tests-resources/TestAmdaParser/TwoRootsFile.json
  * R plugins/amda/tests-resources/TestAmdaParser/ValidFile1.json
  * R plugins/amda/tests-resources/TestAmdaParser/WrongRootKey.json
  * R plugins/amda/tests-resources/TestAmdaParser/WrongRootType.json
  * R plugins/amda/tests-resources/TestAmdaResultParser/NaNValue.txt
  * R plugins/amda/tests-resources/TestAmdaResultParser/NoUnit.txt
  * R plugins/amda/tests-resources/TestAmdaResultParser/TooManyValues.txt
  * R plugins/amda/tests-resources/TestAmdaResultParser/ValidScalar1.txt
  * R plugins/amda/tests-resources/TestAmdaResultParser/WrongDate.txt
  * R plugins/amda/tests-resources/TestAmdaResultParser/WrongUnit.txt
  * R plugins/amda/tests-resources/TestAmdaResultParser/WrongValue.txt
  * R plugins/amda/tests/TestAmdaParser.cpp
  * R plugins/mockplugin/CMakeLists.txt
  * R plugins/mockplugin/cmake/Findsciqlop-mockplugin.cmake
  * R plugins/mockplugin/include/MockPlugin.h
  * R plugins/mockplugin/include/MockPluginGlobal.h
  * R plugins/mockplugin/resources/mockplugin.json
  * R plugins/mockplugin/src/MockPlugin.cpp
  * R README.md
  * R app/CMakeLists.txt
  * R app/include/MainWindow.h
  * R app/src/Main.cpp
  * R app/vera-exclusions/exclusions.txt
  * R cmake/sciqlop.cmake
  * R cmake/sciqlop_applications.cmake
  * R cmake/sciqlop_package.cmake
  * R cmake/sciqlop_params.cmake
  * R core/CMakeLists.txt
  * R core/include/Common/spimpl.h
  * R core/include/DataSource/DataSourceController.h
  * R core/include/DataSource/DataSourceItem.h
  * R core/src/DataSource/DataSourceController.cpp
  * R core/src/DataSource/DataSourceItem.cpp
  * R core/tests/DataSource/TestDataSourceController.cpp
  * R core/vera-exclusions/exclusions.txt
  * R formatting/cmake/use_clangformat.cmake
  * R formatting/vera-exclusions/exclusions.txt
  * R gui/CMakeLists.txt
  * R gui/include/SqpApplication.h
  * R LICENSE
  * R app/src/mainwindow.cpp
  * R app/src/mainwindow.ui
Approved
author

Status change > Approved

You need to be logged in to leave comments. Login now