##// END OF EJS Templates
Some refac for new PySide2 bindings...
jeandet -
r92:9ff5f48e3d71
parent child
Show More
@@ -0,0 +1,57
1 #pragma once
2 #include "cpp_utils.h"
3 #include "types_detectors.h"
4
5 #include <algorithm>
6 #include <iomanip>
7 #include <iostream>
8
9 HAS_METHOD(name)
10 HAS_METHOD(text)
11 HAS_METHOD(toStdString)
12
13 template<typename T> std::string _get_name(const T& item)
14 {
15 if constexpr(has_name<T>) { return _get_name(item.name()); }
16 else if constexpr(has_text<T>)
17 {
18 return _get_name(item.text(0));
19 }
20 else if constexpr(has_toStdString<T>)
21 {
22 return _get_name(item.toStdString());
23 }
24 else
25 {
26 return item;
27 }
28 }
29
30 template<typename T>
31 void _print_tree(const T& tree, int indent_increment, int indent_lvl)
32 {
33 auto print_lambda = [&indent_lvl, &indent_increment](const auto& node) {
34 indent_lvl * [indent_increment](){std::cout <<"│"<< std::string(indent_increment, ' ');};
35 std::cout << "├";
36 (indent_increment-1) * [](){std::cout <<"─";};
37 std::cout << " "<< _get_name(to_value(node)) << std::endl;
38 print_tree(to_value(node), indent_increment, indent_lvl+1);
39 };
40 if constexpr(is_qt_tree_item<T>::value)
41 {
42 for(int i = 0; i < tree.childCount(); i++)
43 {
44 print_lambda(tree.child(i));
45 }
46 }
47 else
48 {
49 std::for_each(std::cbegin(tree), std::cend(tree), print_lambda);
50 }
51 }
52
53 template<typename T>
54 void print_tree(const T& tree, int indent_increment = 3, int indent_lvl = 0)
55 {
56 _print_tree(to_value(tree), indent_increment, indent_lvl);
57 }
@@ -0,0 +1,40
1 #pragma once
2 #include <type_traits>
3
4 template<typename T, typename = void> struct is_smart_ptr : std::false_type
5 {};
6 template<typename T>
7 struct is_smart_ptr<T, decltype(std::declval<T>().get(),
8 std::declval<T>().reset())> : std::true_type
9 {};
10
11 template<typename T, typename = void> struct is_qt_tree_item : std::false_type
12 {};
13 template<typename T>
14 struct is_qt_tree_item<T, decltype(std::declval<T>().takeChildren(),
15 std::declval<T>().parent(),
16 std::declval<T>().addChild(nullptr))>
17 : std::true_type
18 {};
19
20 template<typename T, typename = void> struct has_name_method : std::false_type
21 {};
22 template<typename T>
23 struct has_name_method<T, decltype(std::declval<T>().name(),
24 std::declval<void>())> : std::true_type
25 {};
26
27 template<typename T, typename = void> struct has_text_method : std::false_type
28 {};
29 template<typename T>
30 struct has_text_method<T, decltype(std::declval<T>().text(),
31 std::declval<void>())> : std::true_type
32 {};
33
34
35 template<typename T, typename = void> struct has_tostdstring_method : std::false_type
36 {};
37 template<typename T>
38 struct has_tostdstring_method<T, decltype(std::declval<T>().toStdString(),
39 std::declval<void>())> : std::true_type
40 {};
@@ -1,6 +1,8
1 #ifndef CPP_UTILS_H
1 #ifndef CPP_UTILS_H
2 #define CPP_UTILS_H
2 #define CPP_UTILS_H
3
3
4 #include "types_detectors.h"
5
4 #include <functional>
6 #include <functional>
5 #include <tuple>
7 #include <tuple>
6 #include <type_traits>
8 #include <type_traits>
@@ -34,4 +36,31 template<typename T> constexpr T diff(const std::pair<T, T>& p)
34 return p.second - p.first;
36 return p.second - p.first;
35 }
37 }
36
38
39 template<typename T> constexpr auto const& to_value(const T& item)
40 {
41 if constexpr(std::is_pointer_v<std::remove_reference_t<std::remove_cv_t<T>>>)
42 { return *item; }
43 else
44 {
45 if constexpr(is_smart_ptr<T>::value) { return *item.get(); }
46 else
47 {
48 return item;
49 }
50 }
51 }
52
53 template<typename T> void repeat_n(T func, int number)
54 {
55 for(int i = 0; i < number; i++)
56 func();
57 }
58
59 inline int operator*(int number, const std::function<void(void)>& func)
60 {
61 for(int i = 0; i < number; i++)
62 func();
63 return number;
64 }
65
37 #endif // CPP_UTILS_H
66 #endif // CPP_UTILS_H
@@ -29,6 +29,9 DEPRECATE(class QNetworkReply; class QNetworkRequest;)
29 class SCIQLOP_CORE_EXPORT IDataProvider : public QObject
29 class SCIQLOP_CORE_EXPORT IDataProvider : public QObject
30 {
30 {
31 Q_OBJECT
31 Q_OBJECT
32
33 QUuid _id=QUuid::createUuid();
34
32 public:
35 public:
33 virtual ~IDataProvider() noexcept = default;
36 virtual ~IDataProvider() noexcept = default;
34 // virtual std::shared_ptr<IDataProvider> clone() const = 0;
37 // virtual std::shared_ptr<IDataProvider> clone() const = 0;
@@ -37,6 +40,12 public:
37 virtual TimeSeries::ITimeSerie*
40 virtual TimeSeries::ITimeSerie*
38 getData(const DataProviderParameters& parameters) = 0;
41 getData(const DataProviderParameters& parameters) = 0;
39
42
43 QUuid id() const { return _id; }
44 QString name()
45 {
46 return QString("%1-%2").arg(this->metaObject()->className()).arg(id().toString());
47 }
48
40 signals:
49 signals:
41
50
42 void progress(QUuid requestID, double progress);
51 void progress(QUuid requestID, double progress);
@@ -35,6 +35,9 public:
35 */
35 */
36 QUuid registerDataSource(const QString &dataSourceName) noexcept;
36 QUuid registerDataSource(const QString &dataSourceName) noexcept;
37
37
38 // should deprecate both registerDataSource and setDataProvider
39 void registerProvider(IDataProvider* provider) noexcept;
40
38 /**
41 /**
39 * Sets the structure of a data source. The controller takes ownership of the structure.
42 * Sets the structure of a data source. The controller takes ownership of the structure.
40 * @param dataSourceUid the unique id with which the data source has been registered into the
43 * @param dataSourceUid the unique id with which the data source has been registered into the
@@ -45,6 +48,9 public:
45 void setDataSourceItem(const QUuid &dataSourceUid,
48 void setDataSourceItem(const QUuid &dataSourceUid,
46 std::unique_ptr<DataSourceItem> dataSourceItem) noexcept;
49 std::unique_ptr<DataSourceItem> dataSourceItem) noexcept;
47
50
51 void setDataSourceItem(const QUuid &dataSourceUid,
52 const QString &path, const QMap<QString, QString>& metaData) noexcept;
53
48 /**
54 /**
49 * Sets the data provider used to retrieve data from of a data source. The controller takes
55 * Sets the data provider used to retrieve data from of a data source. The controller takes
50 * ownership of the provider.
56 * ownership of the provider.
@@ -4,8 +4,11
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Common/spimpl.h>
6 #include <Common/spimpl.h>
7 #include <Common/trees.h>
7 #include <QVariant>
8 #include <QVariant>
8 #include <QVector>
9 #include <QVector>
10 #include <iostream>
11 #include <iomanip>
9
12
10 class DataSourceItemAction;
13 class DataSourceItemAction;
11
14
@@ -19,6 +22,8 enum class DataSourceItemType
19 COMPONENT
22 COMPONENT
20 };
23 };
21
24
25
26
22 /**
27 /**
23 * @brief The DataSourceItem class aims to represent a structure element of a
28 * @brief The DataSourceItem class aims to represent a structure element of a
24 * data source. A data source has a tree structure that is made up of a main
29 * data source. A data source has a tree structure that is made up of a main
@@ -28,7 +33,10 enum class DataSourceItemType
28 */
33 */
29 class SCIQLOP_CORE_EXPORT DataSourceItem
34 class SCIQLOP_CORE_EXPORT DataSourceItem
30 {
35 {
36
31 public:
37 public:
38 using iterator_type = decltype (std::begin(std::declval<std::vector<std::unique_ptr<DataSourceItem>>>()));
39 using const_iterator_type = decltype (std::cbegin(std::declval<std::vector<std::unique_ptr<DataSourceItem>>>()));
32 /// Key associated with the name of the item
40 /// Key associated with the name of the item
33 static const QString NAME_DATA_KEY;
41 static const QString NAME_DATA_KEY;
34 /// Key associated with the plugin of the item
42 /// Key associated with the plugin of the item
@@ -167,6 +175,12 public:
167 bool operator==(const DataSourceItem& other);
175 bool operator==(const DataSourceItem& other);
168 bool operator!=(const DataSourceItem& other);
176 bool operator!=(const DataSourceItem& other);
169
177
178 iterator_type begin() noexcept;
179 iterator_type end() noexcept;
180 const_iterator_type begin()const noexcept;
181 const_iterator_type end()const noexcept;
182 const_iterator_type cbegin()const noexcept;
183 const_iterator_type cend()const noexcept;
170 private:
184 private:
171 class DataSourceItemPrivate;
185 class DataSourceItemPrivate;
172 spimpl::unique_impl_ptr<DataSourceItemPrivate> impl;
186 spimpl::unique_impl_ptr<DataSourceItemPrivate> impl;
@@ -1,3 +1,4
1 #pragma once
1 #include "Variable/VariableSynchronizationGroup2.h"
2 #include "Variable/VariableSynchronizationGroup2.h"
2
3
3 #include <Common/containers.h>
4 #include <Common/containers.h>
@@ -1,197 +1,298
1 #include "DataSource/DataSourceController.h"
1 #include "DataSource/DataSourceController.h"
2
2 #include "DataSource/DataSourceItem.h"
3 #include "DataSource/DataSourceItem.h"
4 #include "DataSource/DataSourceItemAction.h"
3
5
6 #include <Common/containers.h>
4 #include <Data/IDataProvider.h>
7 #include <Data/IDataProvider.h>
5
6 #include <QMutex>
7 #include <QThread>
8
9 #include <QDataStream>
8 #include <QDataStream>
10 #include <QDir>
9 #include <QDir>
10 #include <QMutex>
11 #include <QStandardPaths>
11 #include <QStandardPaths>
12 #include <QThread>
12
13
13 Q_LOGGING_CATEGORY(LOG_DataSourceController, "DataSourceController")
14 Q_LOGGING_CATEGORY(LOG_DataSourceController, "DataSourceController")
14
15
15 class DataSourceController::DataSourceControllerPrivate {
16 std::unique_ptr<DataSourceItem> make_folder_item(const QString& name)
17 {
18 return std::make_unique<DataSourceItem>(DataSourceItemType::NODE, name);
19 }
20
21 template<typename T>
22 DataSourceItem* make_path_items(const T& path_list_begin,
23 const T& path_list_end, DataSourceItem* root)
24 {
25 std::for_each(path_list_begin, path_list_end,
26 [&root](const auto& folder_name) mutable {
27 auto folder_ptr = root->findItem(folder_name);
28 if(folder_ptr == nullptr)
29 {
30 auto folder = make_folder_item(folder_name);
31 folder_ptr = folder.get();
32 root->appendChild(std::move(folder));
33 }
34 root = folder_ptr;
35 });
36 return root;
37 }
38
39 std::unique_ptr<DataSourceItem>
40 make_product_item(const QVariantHash& metaData, const QUuid& dataSourceUid,
41 const QString& DATA_SOURCE_NAME, DataSourceController* dc)
42 {
43 auto result =
44 std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT, metaData);
45
46 // Adds plugin name to product metadata
47 result->setData(DataSourceItem::PLUGIN_DATA_KEY, DATA_SOURCE_NAME);
48 result->setData(DataSourceItem::ID_DATA_KEY,
49 metaData.value(DataSourceItem::NAME_DATA_KEY));
50
51 auto productName = metaData.value(DataSourceItem::NAME_DATA_KEY).toString();
52
53 // Add action to load product from DataSourceController
54 result->addAction(std::make_unique<DataSourceItemAction>(
55 QObject::tr("Load %1 product").arg(productName),
56 [productName, dataSourceUid, dc](DataSourceItem& item) {
57 if(dc) { dc->loadProductItem(dataSourceUid, item); }
58 }));
59
60 return result;
61 }
62
63 class DataSourceController::DataSourceControllerPrivate
64 {
16 public:
65 public:
17 QMutex m_WorkingMutex;
66 QMutex m_WorkingMutex;
18 /// Data sources registered
67 /// Data sources registered
19 QHash<QUuid, QString> m_DataSources;
68 QHash<QUuid, QString> m_DataSources;
20 /// Data sources structures
69 /// Data sources structures
21 std::map<QUuid, std::unique_ptr<DataSourceItem> > m_DataSourceItems;
70 std::map<QUuid, std::unique_ptr<DataSourceItem>> m_DataSourceItems;
22 /// Data providers registered
71 /// Data providers registered
23 /// @remarks Data providers are stored as shared_ptr as they can be sent to a variable and
72 /// @remarks Data providers are stored as shared_ptr as they can be sent to a
24 /// continue to live without necessarily the data source controller
73 /// variable and continue to live without necessarily the data source
25 std::map<QUuid, std::shared_ptr<IDataProvider> > m_DataProviders;
74 /// controller
26
75 std::map<QUuid, std::shared_ptr<IDataProvider>> m_DataProviders;
27 // Search for the first datasource item matching the specified data
76
28 DataSourceItem *findDataSourceItem(const QVariantHash &data)
77 // Search for the first datasource item matching the specified data
78 DataSourceItem* findDataSourceItem(const QVariantHash& data)
79 {
80 DataSourceItem* sourceItem = nullptr;
81 for(const auto& item : m_DataSourceItems)
29 {
82 {
30 DataSourceItem *sourceItem = nullptr;
83 sourceItem = item.second->findItem(data, true);
31 for (const auto &item : m_DataSourceItems) {
84 if(sourceItem) { break; }
32 sourceItem = item.second->findItem(data, true);
33 if (sourceItem) {
34 break;
35 }
36 }
37
38 return sourceItem;
39 }
85 }
40
86
41 // Search for the first datasource item matching the specified ID_DATA_KEY
87 return sourceItem;
42 DataSourceItem *findDataSourceItem(const QString &datasourceIdKey)
88 }
89
90 // Search for the first datasource item matching the specified ID_DATA_KEY
91 DataSourceItem* findDataSourceItem(const QString& datasourceIdKey)
92 {
93 DataSourceItem* sourceItem = nullptr;
94 for(const auto& item : m_DataSourceItems)
43 {
95 {
44 DataSourceItem *sourceItem = nullptr;
96 sourceItem = item.second->findItem(datasourceIdKey, true);
45 for (const auto &item : m_DataSourceItems) {
97 if(sourceItem) { break; }
46 sourceItem = item.second->findItem(datasourceIdKey, true);
47 if (sourceItem) {
48 break;
49 }
50 }
51
52 return sourceItem;
53 }
98 }
99
100 return sourceItem;
101 }
54 };
102 };
55
103
56 DataSourceController::DataSourceController(QObject *parent)
104 DataSourceController::DataSourceController(QObject* parent)
57 : impl{spimpl::make_unique_impl<DataSourceControllerPrivate>()}
105 : impl{spimpl::make_unique_impl<DataSourceControllerPrivate>()}
58 {
106 {
59 qCDebug(LOG_DataSourceController()) << tr("DataSourceController construction")
107 qCDebug(LOG_DataSourceController())
60 << QThread::currentThread();
108 << tr("DataSourceController construction") << QThread::currentThread();
61 }
109 }
62
110
63 DataSourceController::~DataSourceController()
111 DataSourceController::~DataSourceController()
64 {
112 {
65 qCDebug(LOG_DataSourceController()) << tr("DataSourceController destruction")
113 qCDebug(LOG_DataSourceController())
66 << QThread::currentThread();
114 << tr("DataSourceController destruction") << QThread::currentThread();
67 this->waitForFinish();
115 this->waitForFinish();
68 }
116 }
69
117
70 QUuid DataSourceController::registerDataSource(const QString &dataSourceName) noexcept
118 QUuid DataSourceController::registerDataSource(
119 const QString& dataSourceName) noexcept
71 {
120 {
72 auto dataSourceUid = QUuid::createUuid();
121 auto dataSourceUid = QUuid::createUuid();
73 impl->m_DataSources.insert(dataSourceUid, dataSourceName);
122 impl->m_DataSources.insert(dataSourceUid, dataSourceName);
74
123
75 return dataSourceUid;
124 return dataSourceUid;
125 }
126
127 void DataSourceController::registerProvider(IDataProvider *provider) noexcept
128 {
129 impl->m_DataSources.insert(provider->id(), provider->name());
130 impl->m_DataProviders.insert({provider->id(), std::unique_ptr<IDataProvider>{provider}});
131 // TODO rethink this, I don't get why we have to do this crap
132 // why do we need a root node for each provider
133 setDataSourceItem(provider->id(),make_folder_item(provider->name()));
76 }
134 }
77
135
78 void DataSourceController::setDataSourceItem(
136 void DataSourceController::setDataSourceItem(
79 const QUuid &dataSourceUid, std::unique_ptr<DataSourceItem> dataSourceItem) noexcept
137 const QUuid& dataSourceUid,
138 std::unique_ptr<DataSourceItem> dataSourceItem) noexcept
80 {
139 {
81 if (!dataSourceItem) {
140 if(!dataSourceItem)
82 qCWarning(LOG_DataSourceController())
141 {
83 << tr("Data source item can't be registered (null item)");
142 qCWarning(LOG_DataSourceController())
84 return;
143 << tr("Data source item can't be registered (null item)");
85 }
144 return;
145 }
146
147 if(impl->m_DataSources.contains(dataSourceUid))
148 {
149 // The data provider is implicitly converted to a shared_ptr
150 impl->m_DataSourceItems.insert(
151 std::make_pair(dataSourceUid, std::move(dataSourceItem)));
152
153 // Retrieves the data source item to emit the signal with it
154 auto it = impl->m_DataSourceItems.find(dataSourceUid);
155 if(it != impl->m_DataSourceItems.end())
156 { emit dataSourceItemSet(it->second.get()); }
157 }
158 else
159 {
160 qCWarning(LOG_DataSourceController())
161 << tr("Can't set data source item for uid %1 : no "
162 "data source has been registered with the uid")
163 .arg(dataSourceUid.toString());
164 }
165 }
86
166
87 if (impl->m_DataSources.contains(dataSourceUid)) {
88 // The data provider is implicitly converted to a shared_ptr
89 impl->m_DataSourceItems.insert(std::make_pair(dataSourceUid, std::move(dataSourceItem)));
90
167
91 // Retrieves the data source item to emit the signal with it
92 auto it = impl->m_DataSourceItems.find(dataSourceUid);
93 if (it != impl->m_DataSourceItems.end()) {
94 emit dataSourceItemSet(it->second.get());
95 }
96 }
97 else {
98 qCWarning(LOG_DataSourceController()) << tr("Can't set data source item for uid %1 : no "
99 "data source has been registered with the uid")
100 .arg(dataSourceUid.toString());
101 }
102 }
103
168
104 void DataSourceController::setDataProvider(const QUuid &dataSourceUid,
169 void DataSourceController::setDataSourceItem(const QUuid& dataSourceUid, const QString& path,
105 std::unique_ptr<IDataProvider> dataProvider) noexcept
170 const QMap<QString, QString> &metaData) noexcept
106 {
171 {
107 if (impl->m_DataSources.contains(dataSourceUid)) {
172 if(auto it = impl->m_DataSourceItems.find(dataSourceUid);
108 impl->m_DataProviders.insert(std::make_pair(dataSourceUid, std::move(dataProvider)));
173 it != impl->m_DataSourceItems.end())
109 }
174 {
110 else {
175 auto path_list = path.split('/', QString::SkipEmptyParts);
111 qCWarning(LOG_DataSourceController()) << tr("Can't set data provider for uid %1 : no data "
176 auto name = *(std::cend(path_list) - 1);
112 "source has been registered with the uid")
177 auto path_item = make_path_items(
113 .arg(dataSourceUid.toString());
178 std::cbegin(path_list), std::cend(path_list) - 1, it->second.get());
179 QVariantHash meta_data{{DataSourceItem::NAME_DATA_KEY, name}};
180 for(auto& key : metaData.keys())
181 {
182 meta_data[key] = metaData[key];
114 }
183 }
184 path_item->appendChild(
185 make_product_item(meta_data, dataSourceUid, "test", this));
186 emit dataSourceItemSet(it->second.get());
187 }
115 }
188 }
116
189
117 void DataSourceController::loadProductItem(const QUuid &dataSourceUid,
190 void DataSourceController::setDataProvider(
118 const DataSourceItem &productItem) noexcept
191 const QUuid& dataSourceUid,
192 std::unique_ptr<IDataProvider> dataProvider) noexcept
119 {
193 {
120 if (productItem.type() == DataSourceItemType::PRODUCT
194 if(impl->m_DataSources.contains(dataSourceUid))
121 || productItem.type() == DataSourceItemType::COMPONENT) {
195 {
122 /// Retrieves the data provider of the data source (if any)
196 impl->m_DataProviders.insert(
123 auto it = impl->m_DataProviders.find(dataSourceUid);
197 std::make_pair(dataSourceUid, std::move(dataProvider)));
124 auto dataProvider = (it != impl->m_DataProviders.end()) ? it->second : nullptr;
198 }
199 else
200 {
201 qCWarning(LOG_DataSourceController())
202 << tr("Can't set data provider for uid %1 : no data "
203 "source has been registered with the uid")
204 .arg(dataSourceUid.toString());
205 }
206 }
125
207
126 emit createVariable(productItem.name(), productItem.data(), dataProvider);
208 void DataSourceController::loadProductItem(
127 }
209 const QUuid& dataSourceUid, const DataSourceItem& productItem) noexcept
128 else {
210 {
129 qCWarning(LOG_DataSourceController()) << tr("Can't load an item that is not a product");
211 if(productItem.type() == DataSourceItemType::PRODUCT ||
130 }
212 productItem.type() == DataSourceItemType::COMPONENT)
213 {
214 /// Retrieves the data provider of the data source (if any)
215 auto it = impl->m_DataProviders.find(dataSourceUid);
216 auto dataProvider =
217 (it != impl->m_DataProviders.end()) ? it->second : nullptr;
218
219 emit createVariable(productItem.name(), productItem.data(), dataProvider);
220 }
221 else
222 {
223 qCWarning(LOG_DataSourceController())
224 << tr("Can't load an item that is not a product");
225 }
131 }
226 }
132
227
133 QByteArray DataSourceController::mimeDataForProductsData(const QVariantList &productsData)
228 QByteArray
229 DataSourceController::mimeDataForProductsData(const QVariantList& productsData)
134 {
230 {
135 QByteArray encodedData;
231 QByteArray encodedData;
136 QDataStream stream{&encodedData, QIODevice::WriteOnly};
232 QDataStream stream{&encodedData, QIODevice::WriteOnly};
137
233
138 stream << productsData;
234 stream << productsData;
139
235
140 return encodedData;
236 return encodedData;
141 }
237 }
142
238
143 QVariantList DataSourceController::productsDataForMimeData(const QByteArray &mimeData)
239 QVariantList
240 DataSourceController::productsDataForMimeData(const QByteArray& mimeData)
144 {
241 {
145 QDataStream stream{mimeData};
242 QDataStream stream{mimeData};
146
243
147 QVariantList productList;
244 QVariantList productList;
148 stream >> productList;
245 stream >> productList;
149
246
150 return productList;
247 return productList;
151 }
248 }
152
249
153 void DataSourceController::initialize()
250 void DataSourceController::initialize()
154 {
251 {
155 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init")
252 qCDebug(LOG_DataSourceController())
156 << QThread::currentThread();
253 << tr("DataSourceController init") << QThread::currentThread();
157 impl->m_WorkingMutex.lock();
254 impl->m_WorkingMutex.lock();
158 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init END");
255 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init END");
159 }
256 }
160
257
161 void DataSourceController::finalize()
258 void DataSourceController::finalize() { impl->m_WorkingMutex.unlock(); }
162 {
163 impl->m_WorkingMutex.unlock();
164 }
165
259
166 void DataSourceController::requestVariableFromProductIdKey(const QString &datasourceIdKey)
260 void DataSourceController::requestVariableFromProductIdKey(
261 const QString& datasourceIdKey)
167 {
262 {
168 auto sourceItem = impl->findDataSourceItem(datasourceIdKey);
263 auto sourceItem = impl->findDataSourceItem(datasourceIdKey);
169
264
170 if (sourceItem) {
265 if(sourceItem)
171 auto sourceName = sourceItem->rootItem().name();
266 {
172 auto sourceId = impl->m_DataSources.key(sourceName);
267 auto sourceName = sourceItem->rootItem().name();
173 loadProductItem(sourceId, *sourceItem);
268 auto sourceId = impl->m_DataSources.key(sourceName);
174 }
269 loadProductItem(sourceId, *sourceItem);
175 else {
270 }
176 qCWarning(LOG_DataSourceController()) << tr("requestVariable, product data not found");
271 else
177 }
272 {
273 qCWarning(LOG_DataSourceController())
274 << tr("requestVariable, product data not found");
275 }
178 }
276 }
179
277
180 void DataSourceController::requestVariable(const QVariantHash &productData)
278 void DataSourceController::requestVariable(const QVariantHash& productData)
181 {
279 {
182 auto sourceItem = impl->findDataSourceItem(productData);
280 auto sourceItem = impl->findDataSourceItem(productData);
183
281
184 if (sourceItem) {
282 if(sourceItem)
185 auto sourceName = sourceItem->rootItem().name();
283 {
186 auto sourceId = impl->m_DataSources.key(sourceName);
284 auto sourceName = sourceItem->rootItem().name();
187 loadProductItem(sourceId, *sourceItem);
285 auto sourceId = impl->m_DataSources.key(sourceName);
188 }
286 loadProductItem(sourceId, *sourceItem);
189 else {
287 }
190 qCWarning(LOG_DataSourceController()) << tr("requestVariable, product data not found");
288 else
191 }
289 {
290 qCWarning(LOG_DataSourceController())
291 << tr("requestVariable, product data not found");
292 }
192 }
293 }
193
294
194 void DataSourceController::waitForFinish()
295 void DataSourceController::waitForFinish()
195 {
296 {
196 QMutexLocker locker{&impl->m_WorkingMutex};
297 QMutexLocker locker{&impl->m_WorkingMutex};
197 }
298 }
@@ -17,8 +17,14 struct DataSourceItem::DataSourceItemPrivate
17 DataSourceItem* m_Parent;
17 DataSourceItem* m_Parent;
18 std::vector<std::unique_ptr<DataSourceItem>> m_Children;
18 std::vector<std::unique_ptr<DataSourceItem>> m_Children;
19 DataSourceItemType m_Type;
19 DataSourceItemType m_Type;
20 //TODO check if QVariant is really wise here, looks quite overkill
21 // maybe a simple map<string,string> could be enough
20 QVariantHash m_Data;
22 QVariantHash m_Data;
21 std::vector<std::unique_ptr<DataSourceItemAction>> m_Actions;
23 std::vector<std::unique_ptr<DataSourceItemAction>> m_Actions;
24 auto begin()noexcept{return m_Children.begin();}
25 auto end()noexcept{return m_Children.end();}
26 auto cbegin()const noexcept{return m_Children.cbegin();}
27 auto cend()const noexcept{return m_Children.cend();}
22 };
28 };
23
29
24 DataSourceItem::DataSourceItem(DataSourceItemType type, const QString& name)
30 DataSourceItem::DataSourceItem(DataSourceItemType type, const QString& name)
@@ -219,3 +225,33 bool DataSourceItem::operator!=(const DataSourceItem& other)
219 {
225 {
220 return !(*this == other);
226 return !(*this == other);
221 }
227 }
228
229 DataSourceItem::iterator_type DataSourceItem::begin() noexcept
230 {
231 return impl->begin();
232 }
233
234 DataSourceItem::iterator_type DataSourceItem::end() noexcept
235 {
236 return impl->end();
237 }
238
239 DataSourceItem::const_iterator_type DataSourceItem::cbegin() const noexcept
240 {
241 return impl->cbegin();
242 }
243
244 DataSourceItem::const_iterator_type DataSourceItem::cend() const noexcept
245 {
246 return impl->cend();
247 }
248
249 DataSourceItem::const_iterator_type DataSourceItem::begin() const noexcept
250 {
251 return impl->cbegin();
252 }
253
254 DataSourceItem::const_iterator_type DataSourceItem::end() const noexcept
255 {
256 return impl->cend();
257 }
@@ -2,54 +2,54
2
2
3 #include <DataSource/DataSourceItem.h>
3 #include <DataSource/DataSourceItem.h>
4
4
5 namespace {
5 namespace
6
7 /**
8 * Finds in a tree an item similar to the item passed in parameter
9 * @param item the item for which to find a similar item
10 * @param root the root item of the tree
11 * @return the similar item if found, nullptr otherwise
12 */
13 DataSourceItem *findSimilarItem(const DataSourceItem &item, const DataSourceItem &root)
14 {
6 {
7 /**
8 * Finds in a tree an item similar to the item passed in parameter
9 * @param item the item for which to find a similar item
10 * @param root the root item of the tree
11 * @return the similar item if found, nullptr otherwise
12 */
13 DataSourceItem* findSimilarItem(const DataSourceItem& item,
14 const DataSourceItem& root)
15 {
15 // An item is considered similar to the another item if:
16 // An item is considered similar to the another item if:
16 // - the items are both nodes AND
17 // - the items are both nodes AND
17 // - the names of the items are identical
18 // - the names of the items are identical
18
19
19 if (item.type() != DataSourceItemType::NODE) {
20 if(item.type() != DataSourceItemType::NODE) { return nullptr; }
20 return nullptr;
21 }
22
23 DataSourceItem *result{nullptr};
24 bool found{false};
25 for (auto i = 0, count = root.childCount(); i < count && !found; ++i) {
26 auto child = root.child(i);
27
21
28 found = child->type() == DataSourceItemType::NODE
22 auto similar_item = std::find_if(
29 && QString::compare(child->name(), item.name(), Qt::CaseInsensitive) == 0;
23 std::cbegin(root), std::cend(root), [&item](const auto& child) {
30 if (found) {
24 return child->type() == DataSourceItemType::NODE &&
31 result = child;
25 QString::compare(child->name(), item.name(),
32 }
26 Qt::CaseInsensitive) == 0;
33 }
27 });
34
28 if(similar_item == std::cend(root)) return nullptr;
35 return result;
29 return similar_item->get();
36 }
30 }
37
31
38 } // namespace
32 } // namespace
39
33
40 void DataSourceItemMergeHelper::merge(const DataSourceItem &source, DataSourceItem &dest)
34 void DataSourceItemMergeHelper::merge(const DataSourceItem& source,
35 DataSourceItem& dest)
41 {
36 {
42 // Checks if the source item can be merged into the destination item (i.e. there is a child item
37 // Checks if the source item can be merged into the destination item (i.e.
43 // similar to the source item)
38 // there is a child item similar to the source item)
44 if (auto subItem = findSimilarItem(source, dest)) {
39 if(auto subItem = findSimilarItem(source, dest))
45 // If there is an item similar to the source item, applies the merge recursively
40 {
46 for (auto i = 0, count = source.childCount(); i < count; ++i) {
41 // If there is an item similar to the source item, applies the merge
47 merge(*source.child(i), *subItem);
42 // recursively
48 }
43 std::for_each(std::cbegin(source), std::cend(source),
49 }
44 [subItem](auto& child) { merge(*child.get(), *subItem); });
50 else {
45 }
51 // If no item is similar to the source item, the item is copied as the child of the
46 else
52 // destination item
47 {
53 dest.appendChild(source.clone());
48 // If no item is similar to the source item, the item is copied as the child
54 }
49 // of the destination item
50 if(std::cend(dest) == std::find_if(std::cbegin(dest), std::cend(dest),
51 [&source](const auto& child)
52 {return source.type() != DataSourceItemType::NODE && source.name()==child->name() && source.data()==child->data();}))
53 dest.appendChild(source.clone());
54 }
55 }
55 }
@@ -226,7 +226,7 class VariableController2::VariableController2Private
226 }
226 }
227 else // force new range to all variables -> may be weird if more than one
227 else // force new range to all variables -> may be weird if more than one
228 // var in the group
228 // var in the group
229 // @TODO ensure that there is no side effects
229 // TODO ensure that there is no side effects
230 {
230 {
231 for(auto varId : group->variables())
231 for(auto varId : group->variables())
232 {
232 {
General Comments 0
You need to be logged in to leave comments. Login now