##// END OF EJS Templates
Variable deletion (3)...
Alexandre Leroux -
r332:ec40cfe998fe
parent child
Show More
@@ -1,78 +1,79
1 1 #ifndef SCIQLOP_VARIABLECONTROLLER_H
2 2 #define SCIQLOP_VARIABLECONTROLLER_H
3 3
4 4 #include <Data/SqpDateTime.h>
5 5
6 6 #include <QLoggingCategory>
7 7 #include <QObject>
8 8
9 9 #include <Common/spimpl.h>
10 10
11 11 class IDataProvider;
12 12 class QItemSelectionModel;
13 13 class TimeController;
14 14 class Variable;
15 15 class VariableModel;
16 16
17 17 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableController)
18 18
19 19 /**
20 20 * @brief The VariableController class aims to handle the variables in SciQlop.
21 21 */
22 22 class VariableController : public QObject {
23 23 Q_OBJECT
24 24 public:
25 25 explicit VariableController(QObject *parent = 0);
26 26 virtual ~VariableController();
27 27
28 28 VariableModel *variableModel() noexcept;
29 29 QItemSelectionModel *variableSelectionModel() noexcept;
30 30
31 31 void setTimeController(TimeController *timeController) noexcept;
32 32
33 33 /**
34 34 * Deletes from the controller the variable passed in parameter.
35 35 *
36 36 * Delete a variable includes:
37 * - the deletion of the model variable
37 38 * - the deletion of the provider associated with the variable
38 39 * - removing the cache associated with the variable
39 40 *
40 41 * @param variable the variable to delete from the controller.
41 42 */
42 43 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
43 44
44 45 /**
45 46 * Deletes from the controller the variables passed in parameter.
46 47 * @param variables the variables to delete from the controller.
47 48 * @sa deleteVariable()
48 49 */
49 50 void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept;
50 51
51 52 signals:
52 53 /// Signal emitted when a variable has been created
53 54 void variableCreated(std::shared_ptr<Variable> variable);
54 55
55 56 public slots:
56 57 /// Request the data loading of the variable whithin dateTime
57 58 void onRequestDataLoading(std::shared_ptr<Variable> variable, const SqpDateTime &dateTime);
58 59 /**
59 60 * Creates a new variable and adds it to the model
60 61 * @param name the name of the new variable
61 62 * @param provider the data provider for the new variable
62 63 */
63 64 void createVariable(const QString &name, std::shared_ptr<IDataProvider> provider) noexcept;
64 65
65 66 /// Update the temporal parameters of every selected variable to dateTime
66 67 void onDateTimeOnSelection(const SqpDateTime &dateTime);
67 68
68 69 void initialize();
69 70 void finalize();
70 71
71 72 private:
72 73 void waitForFinish();
73 74
74 75 class VariableControllerPrivate;
75 76 spimpl::unique_impl_ptr<VariableControllerPrivate> impl;
76 77 };
77 78
78 79 #endif // SCIQLOP_VARIABLECONTROLLER_H
@@ -1,49 +1,55
1 1 #ifndef SCIQLOP_VARIABLEMODEL_H
2 2 #define SCIQLOP_VARIABLEMODEL_H
3 3
4 4
5 5 #include <Data/SqpDateTime.h>
6 6
7 7 #include <QAbstractTableModel>
8 8 #include <QLoggingCategory>
9 9
10 10 #include <Common/spimpl.h>
11 11
12 12 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableModel)
13 13
14 14 class IDataSeries;
15 15 class Variable;
16 16
17 17 /**
18 18 * @brief The VariableModel class aims to hold the variables that have been created in SciQlop
19 19 */
20 20 class VariableModel : public QAbstractTableModel {
21 21 public:
22 22 explicit VariableModel(QObject *parent = nullptr);
23 23
24 24 /**
25 25 * Creates a new variable in the model
26 26 * @param name the name of the new variable
27 27 * @param dateTime the dateTime of the new variable
28 28 * @return the pointer to the new variable
29 29 */
30 30 std::shared_ptr<Variable> createVariable(const QString &name,
31 31 const SqpDateTime &dateTime) noexcept;
32 32
33 /**
34 * Deletes a variable from the model, if it exists
35 * @param variable the variable to delete
36 */
37 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
38
33 39 std::shared_ptr<Variable> variable(int index) const;
34 40
35 41 // /////////////////////////// //
36 42 // QAbstractTableModel methods //
37 43 // /////////////////////////// //
38 44 virtual int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
39 45 virtual int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
40 46 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
41 47 virtual QVariant headerData(int section, Qt::Orientation orientation,
42 48 int role = Qt::DisplayRole) const override;
43 49
44 50 private:
45 51 class VariableModelPrivate;
46 52 spimpl::unique_impl_ptr<VariableModelPrivate> impl;
47 53 };
48 54
49 55 #endif // SCIQLOP_VARIABLEMODEL_H
@@ -1,203 +1,206
1 1 #include <Variable/Variable.h>
2 2 #include <Variable/VariableCacheController.h>
3 3 #include <Variable/VariableController.h>
4 4 #include <Variable/VariableModel.h>
5 5
6 6 #include <Data/DataProviderParameters.h>
7 7 #include <Data/IDataProvider.h>
8 8 #include <Data/IDataSeries.h>
9 9 #include <Time/TimeController.h>
10 10
11 11 #include <QDateTime>
12 12 #include <QMutex>
13 13 #include <QThread>
14 14 #include <QtCore/QItemSelectionModel>
15 15
16 16 #include <unordered_map>
17 17
18 18 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
19 19
20 20 namespace {
21 21
22 22 /// @todo Generates default dataseries, according to the provider passed in parameter. This method
23 23 /// will be deleted when the timerange is recovered from SciQlop
24 24 std::shared_ptr<IDataSeries> generateDefaultDataSeries(const IDataProvider &provider,
25 25 const SqpDateTime &dateTime) noexcept
26 26 {
27 27 auto parameters = DataProviderParameters{dateTime};
28 28
29 29 return provider.retrieveData(parameters);
30 30 }
31 31
32 32 } // namespace
33 33
34 34 struct VariableController::VariableControllerPrivate {
35 35 explicit VariableControllerPrivate(VariableController *parent)
36 36 : m_WorkingMutex{},
37 37 m_VariableModel{new VariableModel{parent}},
38 38 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
39 39 m_VariableCacheController{std::make_unique<VariableCacheController>()}
40 40 {
41 41 }
42 42
43 43 QMutex m_WorkingMutex;
44 44 /// Variable model. The VariableController has the ownership
45 45 VariableModel *m_VariableModel;
46 46 QItemSelectionModel *m_VariableSelectionModel;
47 47
48 48
49 49 TimeController *m_TimeController{nullptr};
50 50 std::unique_ptr<VariableCacheController> m_VariableCacheController;
51 51
52 52 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
53 53 m_VariableToProviderMap;
54 54 };
55 55
56 56 VariableController::VariableController(QObject *parent)
57 57 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
58 58 {
59 59 qCDebug(LOG_VariableController()) << tr("VariableController construction")
60 60 << QThread::currentThread();
61 61 }
62 62
63 63 VariableController::~VariableController()
64 64 {
65 65 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
66 66 << QThread::currentThread();
67 67 this->waitForFinish();
68 68 }
69 69
70 70 VariableModel *VariableController::variableModel() noexcept
71 71 {
72 72 return impl->m_VariableModel;
73 73 }
74 74
75 75 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
76 76 {
77 77 return impl->m_VariableSelectionModel;
78 78 }
79 79
80 80 void VariableController::setTimeController(TimeController *timeController) noexcept
81 81 {
82 82 impl->m_TimeController = timeController;
83 83 }
84 84
85 85 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
86 86 {
87 87 if (!variable) {
88 88 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
89 89 return;
90 90 }
91 91
92 92
93 93 // Deletes provider
94 94 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
95 95 qCDebug(LOG_VariableController())
96 96 << tr("Number of providers deleted for variable %1: %2")
97 97 .arg(variable->name(), QString::number(nbProvidersDeleted));
98 98
99 99 // Clears cache
100 100 impl->m_VariableCacheController->clear(variable);
101 101
102 // Deletes from model
103 impl->m_VariableModel->deleteVariable(variable);
104 }
102 105
103 106 void VariableController::deleteVariables(
104 107 const QVector<std::shared_ptr<Variable> > &variables) noexcept
105 108 {
106 109 for (auto variable : qAsConst(variables)) {
107 110 deleteVariable(variable);
108 111 }
109 112 }
110 113
111 114 void VariableController::createVariable(const QString &name,
112 115 std::shared_ptr<IDataProvider> provider) noexcept
113 116 {
114 117
115 118 if (!impl->m_TimeController) {
116 119 qCCritical(LOG_VariableController())
117 120 << tr("Impossible to create variable: The time controller is null");
118 121 return;
119 122 }
120 123
121 124
122 125 /// @todo : for the moment :
123 126 /// - the provider is only used to retrieve data from the variable for its initialization, but
124 127 /// it will be retained later
125 128 /// - default data are generated for the variable, without taking into account the timerange set
126 129 /// in sciqlop
127 130 auto dateTime = impl->m_TimeController->dateTime();
128 131 if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime)) {
129 132
130 133 // store the provider
131 134 impl->m_VariableToProviderMap[newVariable] = provider;
132 135
133 136 auto addDateTimeAcquired
134 137 = [this, newVariable](auto dataSeriesAcquired, auto dateTimeToPutInCache) {
135 138
136 139 impl->m_VariableCacheController->addDateTime(newVariable, dateTimeToPutInCache);
137 140 newVariable->setDataSeries(dataSeriesAcquired);
138 141
139 142 };
140 143
141 144 connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
142 145 this->onRequestDataLoading(newVariable, dateTime);
143 146
144 147 // notify the creation
145 148 emit variableCreated(newVariable);
146 149 }
147 150 }
148 151
149 152 void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
150 153 {
151 154 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
152 155
153 156 for (const auto &selectedRow : qAsConst(selectedRows)) {
154 157 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
155 158 selectedVariable->setDateTime(dateTime);
156 159 this->onRequestDataLoading(selectedVariable, dateTime);
157 160 }
158 161 }
159 162 }
160 163
161 164
162 165 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
163 166 const SqpDateTime &dateTime)
164 167 {
165 168 // we want to load data of the variable for the dateTime.
166 169 // First we check if the cache contains some of them.
167 170 // For the other, we ask the provider to give them.
168 171 if (variable) {
169 172
170 173 auto dateTimeListNotInCache
171 174 = impl->m_VariableCacheController->provideNotInCacheDateTimeList(variable, dateTime);
172 175
173 176 if (!dateTimeListNotInCache.empty()) {
174 177 // Ask the provider for each data on the dateTimeListNotInCache
175 178 impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
176 179 std::move(dateTimeListNotInCache));
177 180 }
178 181 else {
179 182 emit variable->updated();
180 183 }
181 184 }
182 185 else {
183 186 qCCritical(LOG_VariableController()) << tr("Impossible to load data of a variable null");
184 187 }
185 188 }
186 189
187 190
188 191 void VariableController::initialize()
189 192 {
190 193 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
191 194 impl->m_WorkingMutex.lock();
192 195 qCDebug(LOG_VariableController()) << tr("VariableController init END");
193 196 }
194 197
195 198 void VariableController::finalize()
196 199 {
197 200 impl->m_WorkingMutex.unlock();
198 201 }
199 202
200 203 void VariableController::waitForFinish()
201 204 {
202 205 QMutexLocker locker{&impl->m_WorkingMutex};
203 206 }
@@ -1,153 +1,179
1 1 #include <Variable/Variable.h>
2 2 #include <Variable/VariableModel.h>
3 3
4 4 #include <Data/IDataSeries.h>
5 5
6 6 #include <QDateTime>
7 7 #include <QSize>
8 8
9 9 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
10 10
11 11 namespace {
12 12
13 13 // Column indexes
14 14 const auto NAME_COLUMN = 0;
15 15 const auto TSTART_COLUMN = 1;
16 16 const auto TEND_COLUMN = 2;
17 17 const auto NB_COLUMNS = 3;
18 18
19 19 // Column properties
20 20 const auto DEFAULT_HEIGHT = 25;
21 21 const auto DEFAULT_WIDTH = 100;
22 22
23 23 struct ColumnProperties {
24 24 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
25 25 int height = DEFAULT_HEIGHT)
26 26 : m_Name{name}, m_Width{width}, m_Height{height}
27 27 {
28 28 }
29 29
30 30 QString m_Name;
31 31 int m_Width;
32 32 int m_Height;
33 33 };
34 34
35 35 const auto COLUMN_PROPERTIES
36 36 = QHash<int, ColumnProperties>{{NAME_COLUMN, {QObject::tr("Name")}},
37 37 {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
38 38 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}};
39 39
40 40 /// Format for datetimes
41 41 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
42 42
43 43 } // namespace
44 44
45 45 struct VariableModel::VariableModelPrivate {
46 46 /// Variables created in SciQlop
47 47 std::vector<std::shared_ptr<Variable> > m_Variables;
48 48 };
49 49
50 50 VariableModel::VariableModel(QObject *parent)
51 51 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
52 52 {
53 53 }
54 54
55 55 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
56 56 const SqpDateTime &dateTime) noexcept
57 57 {
58 58 auto insertIndex = rowCount();
59 59 beginInsertRows({}, insertIndex, insertIndex);
60 60
61 61 /// @todo For the moment, the other data of the variable is initialized with default values
62 62 auto variable = std::make_shared<Variable>(name, QStringLiteral("unit"),
63 63 QStringLiteral("mission"), dateTime);
64 64
65 65 impl->m_Variables.push_back(variable);
66 66
67 67 endInsertRows();
68 68
69 69 return variable;
70 70 }
71 71
72 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
73 {
74 if (!variable) {
75 qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
76 return;
77 }
78
79 // Finds variable in the model
80 auto begin = impl->m_Variables.cbegin();
81 auto end = impl->m_Variables.cend();
82 auto it = std::find(begin, end, variable);
83 if (it != end) {
84 auto removeIndex = std::distance(begin, it);
85
86 // Deletes variable
87 beginRemoveRows({}, removeIndex, removeIndex);
88 impl->m_Variables.erase(it);
89 endRemoveRows();
90 }
91 else {
92 qCritical(LOG_VariableModel())
93 << tr("Can't delete variable %1 from the model: the variable is not in the model")
94 .arg(variable->name());
95 }
96 }
97
72 98 std::shared_ptr<Variable> VariableModel::variable(int index) const
73 99 {
74 100 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
75 101 }
76 102
77 103 int VariableModel::columnCount(const QModelIndex &parent) const
78 104 {
79 105 Q_UNUSED(parent);
80 106
81 107 return NB_COLUMNS;
82 108 }
83 109
84 110 int VariableModel::rowCount(const QModelIndex &parent) const
85 111 {
86 112 Q_UNUSED(parent);
87 113
88 114 return impl->m_Variables.size();
89 115 }
90 116
91 117 QVariant VariableModel::data(const QModelIndex &index, int role) const
92 118 {
93 119 if (!index.isValid()) {
94 120 return QVariant{};
95 121 }
96 122
97 123 if (index.row() < 0 || index.row() >= rowCount()) {
98 124 return QVariant{};
99 125 }
100 126
101 127 if (role == Qt::DisplayRole) {
102 128 if (auto variable = impl->m_Variables.at(index.row()).get()) {
103 129 /// Lambda function that builds the variant to return for a time value
104 130 auto dateTimeVariant = [](double time) {
105 131 auto dateTime = QDateTime::fromMSecsSinceEpoch(time * 1000.);
106 132 return dateTime.toString(DATETIME_FORMAT);
107 133 };
108 134
109 135 switch (index.column()) {
110 136 case NAME_COLUMN:
111 137 return variable->name();
112 138 case TSTART_COLUMN:
113 139 return dateTimeVariant(variable->dateTime().m_TStart);
114 140 case TEND_COLUMN:
115 141 return dateTimeVariant(variable->dateTime().m_TEnd);
116 142 default:
117 143 // No action
118 144 break;
119 145 }
120 146
121 147 qWarning(LOG_VariableModel())
122 148 << tr("Can't get data (unknown column %1)").arg(index.column());
123 149 }
124 150 else {
125 151 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
126 152 }
127 153 }
128 154
129 155 return QVariant{};
130 156 }
131 157
132 158 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
133 159 {
134 160 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
135 161 return QVariant{};
136 162 }
137 163
138 164 if (orientation == Qt::Horizontal) {
139 165 auto propertiesIt = COLUMN_PROPERTIES.find(section);
140 166 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
141 167 // Role is either DisplayRole or SizeHintRole
142 168 return (role == Qt::DisplayRole)
143 169 ? QVariant{propertiesIt->m_Name}
144 170 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
145 171 }
146 172 else {
147 173 qWarning(LOG_VariableModel())
148 174 << tr("Can't get header data (unknown column %1)").arg(section);
149 175 }
150 176 }
151 177
152 178 return QVariant{};
153 179 }
General Comments 0
You need to be logged in to leave comments. Login now