##// END OF EJS Templates
New methods to find a datasource item from its product ID_KEY
trabillard -
r1286:29270c1078f4
parent child
Show More
@@ -1,102 +1,106
1 #ifndef SCIQLOP_DATASOURCECONTROLLER_H
1 #ifndef SCIQLOP_DATASOURCECONTROLLER_H
2 #define SCIQLOP_DATASOURCECONTROLLER_H
2 #define SCIQLOP_DATASOURCECONTROLLER_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <QLoggingCategory>
6 #include <QLoggingCategory>
7 #include <QObject>
7 #include <QObject>
8 #include <QUuid>
8 #include <QUuid>
9
9
10 #include <Common/spimpl.h>
10 #include <Common/spimpl.h>
11
11
12 Q_DECLARE_LOGGING_CATEGORY(LOG_DataSourceController)
12 Q_DECLARE_LOGGING_CATEGORY(LOG_DataSourceController)
13
13
14 class DataSourceItem;
14 class DataSourceItem;
15 class IDataProvider;
15 class IDataProvider;
16
16
17 /**
17 /**
18 * @brief The DataSourceController class aims to make the link between SciQlop and its plugins. This
18 * @brief The DataSourceController class aims to make the link between SciQlop and its plugins. This
19 * is the intermediate class that SciQlop has to use in the way to connect a data source. Please
19 * is the intermediate class that SciQlop has to use in the way to connect a data source. Please
20 * first use register method to initialize a plugin specified by its metadata name (JSON plugin
20 * first use register method to initialize a plugin specified by its metadata name (JSON plugin
21 * source) then others specifics method will be able to access it. You can load a data source driver
21 * source) then others specifics method will be able to access it. You can load a data source driver
22 * plugin then create a data source.
22 * plugin then create a data source.
23 */
23 */
24 class SCIQLOP_CORE_EXPORT DataSourceController : public QObject {
24 class SCIQLOP_CORE_EXPORT DataSourceController : public QObject {
25 Q_OBJECT
25 Q_OBJECT
26 public:
26 public:
27 explicit DataSourceController(QObject *parent = 0);
27 explicit DataSourceController(QObject *parent = 0);
28 virtual ~DataSourceController();
28 virtual ~DataSourceController();
29
29
30 /**
30 /**
31 * Registers a data source. The method delivers a unique id that can be used afterwards to
31 * Registers a data source. The method delivers a unique id that can be used afterwards to
32 * access to the data source properties (structure, connection parameters, data provider, etc.)
32 * access to the data source properties (structure, connection parameters, data provider, etc.)
33 * @param dataSourceName the name of the data source
33 * @param dataSourceName the name of the data source
34 * @return the unique id with which the data source has been registered
34 * @return the unique id with which the data source has been registered
35 */
35 */
36 QUuid registerDataSource(const QString &dataSourceName) noexcept;
36 QUuid registerDataSource(const QString &dataSourceName) noexcept;
37
37
38 /**
38 /**
39 * Sets the structure of a data source. The controller takes ownership of the structure.
39 * 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
40 * @param dataSourceUid the unique id with which the data source has been registered into the
41 * controller. If it is invalid, the method has no effect.
41 * controller. If it is invalid, the method has no effect.
42 * @param dataSourceItem the structure of the data source. It must be not null to be registered
42 * @param dataSourceItem the structure of the data source. It must be not null to be registered
43 * @sa registerDataSource()
43 * @sa registerDataSource()
44 */
44 */
45 void setDataSourceItem(const QUuid &dataSourceUid,
45 void setDataSourceItem(const QUuid &dataSourceUid,
46 std::unique_ptr<DataSourceItem> dataSourceItem) noexcept;
46 std::unique_ptr<DataSourceItem> dataSourceItem) noexcept;
47
47
48 /**
48 /**
49 * Sets the data provider used to retrieve data from of a data source. The controller takes
49 * Sets the data provider used to retrieve data from of a data source. The controller takes
50 * ownership of the provider.
50 * ownership of the provider.
51 * @param dataSourceUid the unique id with which the data source has been registered into the
51 * @param dataSourceUid the unique id with which the data source has been registered into the
52 * controller. If it is invalid, the method has no effect.
52 * controller. If it is invalid, the method has no effect.
53 * @param dataProvider the provider of the data source
53 * @param dataProvider the provider of the data source
54 * @sa registerDataSource()
54 * @sa registerDataSource()
55 */
55 */
56 void setDataProvider(const QUuid &dataSourceUid,
56 void setDataProvider(const QUuid &dataSourceUid,
57 std::unique_ptr<IDataProvider> dataProvider) noexcept;
57 std::unique_ptr<IDataProvider> dataProvider) noexcept;
58
58
59 /**
59 /**
60 * Loads an item (product) as a variable in SciQlop
60 * Loads an item (product) as a variable in SciQlop
61 * @param dataSourceUid the unique id of the data source containing the item. It is used to get
61 * @param dataSourceUid the unique id of the data source containing the item. It is used to get
62 * the data provider associated to the data source, and pass it to for the variable creation
62 * the data provider associated to the data source, and pass it to for the variable creation
63 * @param productItem the item to load
63 * @param productItem the item to load
64 */
64 */
65 void loadProductItem(const QUuid &dataSourceUid, const DataSourceItem &productItem) noexcept;
65 void loadProductItem(const QUuid &dataSourceUid, const DataSourceItem &productItem) noexcept;
66
66
67 /// Returns the MIME data associated to a list of product meta data
67 /// Returns the MIME data associated to a list of product meta data
68 static QByteArray mimeDataForProductsData(const QVariantList &productsData);
68 static QByteArray mimeDataForProductsData(const QVariantList &productsData);
69
69
70 /// Returns the list of meta data contained in a MIME data
70 /// Returns the list of meta data contained in a MIME data
71 static QVariantList productsDataForMimeData(const QByteArray &mimeData);
71 static QVariantList productsDataForMimeData(const QByteArray &mimeData);
72
72
73 public slots:
73 public slots:
74 /// Manage init/end of the controller
74 /// Manage init/end of the controller
75 void initialize();
75 void initialize();
76 void finalize();
76 void finalize();
77
77
78 /// Request the creation of a variable from the ID_DATA_KEY of a product
79 void requestVariable(const QString &datasourceIdKey);
80
81 /// Request the creation of a variable from metadata of a product
78 void requestVariable(const QVariantHash &productData);
82 void requestVariable(const QVariantHash &productData);
79
83
80 signals:
84 signals:
81 /// Signal emitted when a structure has been set for a data source
85 /// Signal emitted when a structure has been set for a data source
82 void dataSourceItemSet(DataSourceItem *dataSourceItem);
86 void dataSourceItemSet(DataSourceItem *dataSourceItem);
83
87
84 /**
88 /**
85 * Signal emitted when a variable creation is asked for a product
89 * Signal emitted when a variable creation is asked for a product
86 * @param variableName the name of the variable
90 * @param variableName the name of the variable
87 * @param variableMetadata the metadata of the variable
91 * @param variableMetadata the metadata of the variable
88 * @param variableProvider the provider that will be used to retrieve the data of the variable
92 * @param variableProvider the provider that will be used to retrieve the data of the variable
89 * (can be null)
93 * (can be null)
90 */
94 */
91 void variableCreationRequested(const QString &variableName,
95 void variableCreationRequested(const QString &variableName,
92 const QVariantHash &variableMetadata,
96 const QVariantHash &variableMetadata,
93 std::shared_ptr<IDataProvider> variableProvider);
97 std::shared_ptr<IDataProvider> variableProvider);
94
98
95 private:
99 private:
96 void waitForFinish();
100 void waitForFinish();
97
101
98 class DataSourceControllerPrivate;
102 class DataSourceControllerPrivate;
99 spimpl::unique_impl_ptr<DataSourceControllerPrivate> impl;
103 spimpl::unique_impl_ptr<DataSourceControllerPrivate> impl;
100 };
104 };
101
105
102 #endif // SCIQLOP_DATASOURCECONTROLLER_H
106 #endif // SCIQLOP_DATASOURCECONTROLLER_H
@@ -1,156 +1,164
1 #ifndef SCIQLOP_DATASOURCEITEM_H
1 #ifndef SCIQLOP_DATASOURCEITEM_H
2 #define SCIQLOP_DATASOURCEITEM_H
2 #define SCIQLOP_DATASOURCEITEM_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Common/spimpl.h>
6 #include <Common/spimpl.h>
7
7
8 #include <QVariant>
8 #include <QVariant>
9 #include <QVector>
9 #include <QVector>
10
10
11 class DataSourceItemAction;
11 class DataSourceItemAction;
12
12
13 /**
13 /**
14 * Possible types of an item
14 * Possible types of an item
15 */
15 */
16 enum class DataSourceItemType { NODE, PRODUCT, COMPONENT };
16 enum class DataSourceItemType { NODE, PRODUCT, COMPONENT };
17
17
18 /**
18 /**
19 * @brief The DataSourceItem class aims to represent a structure element of a data source.
19 * @brief The DataSourceItem class aims to represent a structure element of a data source.
20 * A data source has a tree structure that is made up of a main DataSourceItem object (root)
20 * A data source has a tree structure that is made up of a main DataSourceItem object (root)
21 * containing other DataSourceItem objects (children).
21 * containing other DataSourceItem objects (children).
22 * For each DataSourceItem can be associated a set of data representing it.
22 * For each DataSourceItem can be associated a set of data representing it.
23 */
23 */
24 class SCIQLOP_CORE_EXPORT DataSourceItem {
24 class SCIQLOP_CORE_EXPORT DataSourceItem {
25 public:
25 public:
26 /// Key associated with the name of the item
26 /// Key associated with the name of the item
27 static const QString NAME_DATA_KEY;
27 static const QString NAME_DATA_KEY;
28 /// Key associated with the plugin of the item
28 /// Key associated with the plugin of the item
29 static const QString PLUGIN_DATA_KEY;
29 static const QString PLUGIN_DATA_KEY;
30 /// Key associated with a unique id of the plugin
30 /// Key associated with a unique id of the plugin
31 static const QString ID_DATA_KEY;
31 static const QString ID_DATA_KEY;
32
32
33 explicit DataSourceItem(DataSourceItemType type, const QString &name);
33 explicit DataSourceItem(DataSourceItemType type, const QString &name);
34 explicit DataSourceItem(DataSourceItemType type, QVariantHash data = {});
34 explicit DataSourceItem(DataSourceItemType type, QVariantHash data = {});
35
35
36 std::unique_ptr<DataSourceItem> clone() const;
36 std::unique_ptr<DataSourceItem> clone() const;
37
37
38 /// @return the actions of the item as a vector
38 /// @return the actions of the item as a vector
39 QVector<DataSourceItemAction *> actions() const noexcept;
39 QVector<DataSourceItemAction *> actions() const noexcept;
40
40
41 /**
41 /**
42 * Adds an action to the item. The item takes ownership of the action, and the action is
42 * Adds an action to the item. The item takes ownership of the action, and the action is
43 * automatically associated to the item
43 * automatically associated to the item
44 * @param action the action to add
44 * @param action the action to add
45 */
45 */
46 void addAction(std::unique_ptr<DataSourceItemAction> action) noexcept;
46 void addAction(std::unique_ptr<DataSourceItemAction> action) noexcept;
47
47
48 /**
48 /**
49 * Adds a child to the item. The item takes ownership of the child.
49 * Adds a child to the item. The item takes ownership of the child.
50 * @param child the child to add
50 * @param child the child to add
51 */
51 */
52 void appendChild(std::unique_ptr<DataSourceItem> child) noexcept;
52 void appendChild(std::unique_ptr<DataSourceItem> child) noexcept;
53
53
54 /**
54 /**
55 * Returns the item's child associated to an index
55 * Returns the item's child associated to an index
56 * @param childIndex the index to search
56 * @param childIndex the index to search
57 * @return a pointer to the child if index is valid, nullptr otherwise
57 * @return a pointer to the child if index is valid, nullptr otherwise
58 */
58 */
59 DataSourceItem *child(int childIndex) const noexcept;
59 DataSourceItem *child(int childIndex) const noexcept;
60
60
61 int childCount() const noexcept;
61 int childCount() const noexcept;
62
62
63 /**
63 /**
64 * Get the data associated to a key
64 * Get the data associated to a key
65 * @param key the key to search
65 * @param key the key to search
66 * @return the data found if key is valid, default QVariant otherwise
66 * @return the data found if key is valid, default QVariant otherwise
67 */
67 */
68 QVariant data(const QString &key) const noexcept;
68 QVariant data(const QString &key) const noexcept;
69
69
70 /// Gets all data
70 /// Gets all data
71 QVariantHash data() const noexcept;
71 QVariantHash data() const noexcept;
72
72
73 /**
73 /**
74 * Merge in the item the source item passed as parameter.
74 * Merge in the item the source item passed as parameter.
75 *
75 *
76 * The merge is done by adding as child of the item the complete tree represented by the source
76 * The merge is done by adding as child of the item the complete tree represented by the source
77 * item. If a part of the tree already exists in the item (based on the name of the nodes), it
77 * item. If a part of the tree already exists in the item (based on the name of the nodes), it
78 * is merged by completing the existing tree by items "leaves" (products, components or nodes
78 * is merged by completing the existing tree by items "leaves" (products, components or nodes
79 * with no child).
79 * with no child).
80 *
80 *
81 * For example, with item representing the tree:
81 * For example, with item representing the tree:
82 * R (root node)
82 * R (root node)
83 * - N1 (node)
83 * - N1 (node)
84 * -- N11 (node)
84 * -- N11 (node)
85 * --- P1 (product)
85 * --- P1 (product)
86 * --- P2 (product)
86 * --- P2 (product)
87 * - N2 (node)
87 * - N2 (node)
88 *
88 *
89 * and the source item representing the tree:
89 * and the source item representing the tree:
90 * N1 (root node)
90 * N1 (root node)
91 * - N11 (node)
91 * - N11 (node)
92 * -- P3 (product)
92 * -- P3 (product)
93 * - N12 (node)
93 * - N12 (node)
94 *
94 *
95 * The leaves of the source item to merge into the item are N1/N11/P3 and N1/N12 => we therefore
95 * The leaves of the source item to merge into the item are N1/N11/P3 and N1/N12 => we therefore
96 * have the following merge result:
96 * have the following merge result:
97 * R
97 * R
98 * - N1
98 * - N1
99 * -- N11
99 * -- N11
100 * --- P1
100 * --- P1
101 * --- P2
101 * --- P2
102 * --- P3 (added leaf)
102 * --- P3 (added leaf)
103 * -- N12 (added leaf)
103 * -- N12 (added leaf)
104 *
104 *
105 * @param item the source item
105 * @param item the source item
106 * @remarks No control is performed on products or components that are merged into the same tree
106 * @remarks No control is performed on products or components that are merged into the same tree
107 * part (two products or components may have the same name)
107 * part (two products or components may have the same name)
108 * @remarks the merge is made by copy (source item is not changed and still exists after the
108 * @remarks the merge is made by copy (source item is not changed and still exists after the
109 * operation)
109 * operation)
110 */
110 */
111 void merge(const DataSourceItem &item);
111 void merge(const DataSourceItem &item);
112
112
113 bool isRoot() const noexcept;
113 bool isRoot() const noexcept;
114
114
115 QString name() const noexcept;
115 QString name() const noexcept;
116
116
117 /**
117 /**
118 * Get the item's parent
118 * Get the item's parent
119 * @return a pointer to the parent if it exists, nullptr if the item is a root
119 * @return a pointer to the parent if it exists, nullptr if the item is a root
120 */
120 */
121 DataSourceItem *parentItem() const noexcept;
121 DataSourceItem *parentItem() const noexcept;
122
122
123 /**
123 /**
124 * Gets the item's root
124 * Gets the item's root
125 * @return the top parent, the item itself if it's the root item
125 * @return the top parent, the item itself if it's the root item
126 */
126 */
127 const DataSourceItem &rootItem() const noexcept;
127 const DataSourceItem &rootItem() const noexcept;
128
128
129 /**
129 /**
130 * Sets or appends a value to a key
130 * Sets or appends a value to a key
131 * @param key the key
131 * @param key the key
132 * @param value the value
132 * @param value the value
133 * @param append if true, the value is added to the values already existing for the key,
133 * @param append if true, the value is added to the values already existing for the key,
134 * otherwise it replaces the existing values
134 * otherwise it replaces the existing values
135 */
135 */
136 void setData(const QString &key, const QVariant &value, bool append = false) noexcept;
136 void setData(const QString &key, const QVariant &value, bool append = false) noexcept;
137
137
138 DataSourceItemType type() const noexcept;
138 DataSourceItemType type() const noexcept;
139
139
140 /**
140 /**
141 * @brief Searches the first child matching the specified data.
141 * @brief Searches the first child matching the specified data.
142 * @param data The data to search.
142 * @param data The data to search.
143 * @param recursive So the search recursively.
143 * @param recursive So the search recursively.
144 * @return the item matching the data or nullptr if it was not found.
144 * @return the item matching the data or nullptr if it was not found.
145 */
145 */
146 DataSourceItem *findItem(const QVariantHash &data, bool recursive);
146 DataSourceItem *findItem(const QVariantHash &data, bool recursive);
147
147
148 /**
149 * @brief Searches the first child matching the specified \p ID_DATA_KEY in its metadata.
150 * @param id The id to search.
151 * @param recursive So the search recursively.
152 * @return the item matching the data or nullptr if it was not found.
153 */
154 DataSourceItem *findItem(const QString &datasourceIdKey, bool recursive);
155
148 bool operator==(const DataSourceItem &other);
156 bool operator==(const DataSourceItem &other);
149 bool operator!=(const DataSourceItem &other);
157 bool operator!=(const DataSourceItem &other);
150
158
151 private:
159 private:
152 class DataSourceItemPrivate;
160 class DataSourceItemPrivate;
153 spimpl::unique_impl_ptr<DataSourceItemPrivate> impl;
161 spimpl::unique_impl_ptr<DataSourceItemPrivate> impl;
154 };
162 };
155
163
156 #endif // SCIQLOP_DATASOURCEITEMMODEL_H
164 #endif // SCIQLOP_DATASOURCEITEMMODEL_H
@@ -1,169 +1,197
1 #include "DataSource/DataSourceController.h"
1 #include "DataSource/DataSourceController.h"
2 #include "DataSource/DataSourceItem.h"
2 #include "DataSource/DataSourceItem.h"
3
3
4 #include <Data/IDataProvider.h>
4 #include <Data/IDataProvider.h>
5
5
6 #include <QMutex>
6 #include <QMutex>
7 #include <QThread>
7 #include <QThread>
8
8
9 #include <QDataStream>
9 #include <QDataStream>
10 #include <QDir>
10 #include <QDir>
11 #include <QStandardPaths>
11 #include <QStandardPaths>
12
12
13 Q_LOGGING_CATEGORY(LOG_DataSourceController, "DataSourceController")
13 Q_LOGGING_CATEGORY(LOG_DataSourceController, "DataSourceController")
14
14
15 class DataSourceController::DataSourceControllerPrivate {
15 class DataSourceController::DataSourceControllerPrivate {
16 public:
16 public:
17 QMutex m_WorkingMutex;
17 QMutex m_WorkingMutex;
18 /// Data sources registered
18 /// Data sources registered
19 QHash<QUuid, QString> m_DataSources;
19 QHash<QUuid, QString> m_DataSources;
20 /// Data sources structures
20 /// Data sources structures
21 std::map<QUuid, std::unique_ptr<DataSourceItem> > m_DataSourceItems;
21 std::map<QUuid, std::unique_ptr<DataSourceItem> > m_DataSourceItems;
22 /// Data providers registered
22 /// Data providers registered
23 /// @remarks Data providers are stored as shared_ptr as they can be sent to a variable and
23 /// @remarks Data providers are stored as shared_ptr as they can be sent to a variable and
24 /// continue to live without necessarily the data source controller
24 /// continue to live without necessarily the data source controller
25 std::map<QUuid, std::shared_ptr<IDataProvider> > m_DataProviders;
25 std::map<QUuid, std::shared_ptr<IDataProvider> > m_DataProviders;
26
26
27 // Search for the first datasource item matching the specified data
27 // Search for the first datasource item matching the specified data
28 DataSourceItem *findDataSourceItem(const QVariantHash &data)
28 DataSourceItem *findDataSourceItem(const QVariantHash &data)
29 {
29 {
30 DataSourceItem *sourceItem = nullptr;
30 DataSourceItem *sourceItem = nullptr;
31 for (const auto &item : m_DataSourceItems) {
31 for (const auto &item : m_DataSourceItems) {
32 sourceItem = item.second->findItem(data, true);
32 sourceItem = item.second->findItem(data, true);
33 if (sourceItem) {
33 if (sourceItem) {
34 break;
34 break;
35 }
35 }
36 }
36 }
37
37
38 return sourceItem;
38 return sourceItem;
39 }
39 }
40
41 // Search for the first datasource item matching the specified ID_DATA_KEY
42 DataSourceItem *findDataSourceItem(const QString &datasourceIdKey)
43 {
44 DataSourceItem *sourceItem = nullptr;
45 for (const auto &item : m_DataSourceItems) {
46 sourceItem = item.second->findItem(datasourceIdKey, true);
47 if (sourceItem) {
48 break;
49 }
50 }
51
52 return sourceItem;
53 }
40 };
54 };
41
55
42 DataSourceController::DataSourceController(QObject *parent)
56 DataSourceController::DataSourceController(QObject *parent)
43 : impl{spimpl::make_unique_impl<DataSourceControllerPrivate>()}
57 : impl{spimpl::make_unique_impl<DataSourceControllerPrivate>()}
44 {
58 {
45 qCDebug(LOG_DataSourceController()) << tr("DataSourceController construction")
59 qCDebug(LOG_DataSourceController()) << tr("DataSourceController construction")
46 << QThread::currentThread();
60 << QThread::currentThread();
47 }
61 }
48
62
49 DataSourceController::~DataSourceController()
63 DataSourceController::~DataSourceController()
50 {
64 {
51 qCDebug(LOG_DataSourceController()) << tr("DataSourceController destruction")
65 qCDebug(LOG_DataSourceController()) << tr("DataSourceController destruction")
52 << QThread::currentThread();
66 << QThread::currentThread();
53 this->waitForFinish();
67 this->waitForFinish();
54 }
68 }
55
69
56 QUuid DataSourceController::registerDataSource(const QString &dataSourceName) noexcept
70 QUuid DataSourceController::registerDataSource(const QString &dataSourceName) noexcept
57 {
71 {
58 auto dataSourceUid = QUuid::createUuid();
72 auto dataSourceUid = QUuid::createUuid();
59 impl->m_DataSources.insert(dataSourceUid, dataSourceName);
73 impl->m_DataSources.insert(dataSourceUid, dataSourceName);
60
74
61 return dataSourceUid;
75 return dataSourceUid;
62 }
76 }
63
77
64 void DataSourceController::setDataSourceItem(
78 void DataSourceController::setDataSourceItem(
65 const QUuid &dataSourceUid, std::unique_ptr<DataSourceItem> dataSourceItem) noexcept
79 const QUuid &dataSourceUid, std::unique_ptr<DataSourceItem> dataSourceItem) noexcept
66 {
80 {
67 if (!dataSourceItem) {
81 if (!dataSourceItem) {
68 qCWarning(LOG_DataSourceController())
82 qCWarning(LOG_DataSourceController())
69 << tr("Data source item can't be registered (null item)");
83 << tr("Data source item can't be registered (null item)");
70 return;
84 return;
71 }
85 }
72
86
73 if (impl->m_DataSources.contains(dataSourceUid)) {
87 if (impl->m_DataSources.contains(dataSourceUid)) {
74 // The data provider is implicitly converted to a shared_ptr
88 // The data provider is implicitly converted to a shared_ptr
75 impl->m_DataSourceItems.insert(std::make_pair(dataSourceUid, std::move(dataSourceItem)));
89 impl->m_DataSourceItems.insert(std::make_pair(dataSourceUid, std::move(dataSourceItem)));
76
90
77 // Retrieves the data source item to emit the signal with it
91 // Retrieves the data source item to emit the signal with it
78 auto it = impl->m_DataSourceItems.find(dataSourceUid);
92 auto it = impl->m_DataSourceItems.find(dataSourceUid);
79 if (it != impl->m_DataSourceItems.end()) {
93 if (it != impl->m_DataSourceItems.end()) {
80 emit dataSourceItemSet(it->second.get());
94 emit dataSourceItemSet(it->second.get());
81 }
95 }
82 }
96 }
83 else {
97 else {
84 qCWarning(LOG_DataSourceController()) << tr("Can't set data source item for uid %1 : no "
98 qCWarning(LOG_DataSourceController()) << tr("Can't set data source item for uid %1 : no "
85 "data source has been registered with the uid")
99 "data source has been registered with the uid")
86 .arg(dataSourceUid.toString());
100 .arg(dataSourceUid.toString());
87 }
101 }
88 }
102 }
89
103
90 void DataSourceController::setDataProvider(const QUuid &dataSourceUid,
104 void DataSourceController::setDataProvider(const QUuid &dataSourceUid,
91 std::unique_ptr<IDataProvider> dataProvider) noexcept
105 std::unique_ptr<IDataProvider> dataProvider) noexcept
92 {
106 {
93 if (impl->m_DataSources.contains(dataSourceUid)) {
107 if (impl->m_DataSources.contains(dataSourceUid)) {
94 impl->m_DataProviders.insert(std::make_pair(dataSourceUid, std::move(dataProvider)));
108 impl->m_DataProviders.insert(std::make_pair(dataSourceUid, std::move(dataProvider)));
95 }
109 }
96 else {
110 else {
97 qCWarning(LOG_DataSourceController()) << tr("Can't set data provider for uid %1 : no data "
111 qCWarning(LOG_DataSourceController()) << tr("Can't set data provider for uid %1 : no data "
98 "source has been registered with the uid")
112 "source has been registered with the uid")
99 .arg(dataSourceUid.toString());
113 .arg(dataSourceUid.toString());
100 }
114 }
101 }
115 }
102
116
103 void DataSourceController::loadProductItem(const QUuid &dataSourceUid,
117 void DataSourceController::loadProductItem(const QUuid &dataSourceUid,
104 const DataSourceItem &productItem) noexcept
118 const DataSourceItem &productItem) noexcept
105 {
119 {
106 if (productItem.type() == DataSourceItemType::PRODUCT
120 if (productItem.type() == DataSourceItemType::PRODUCT
107 || productItem.type() == DataSourceItemType::COMPONENT) {
121 || productItem.type() == DataSourceItemType::COMPONENT) {
108 /// Retrieves the data provider of the data source (if any)
122 /// Retrieves the data provider of the data source (if any)
109 auto it = impl->m_DataProviders.find(dataSourceUid);
123 auto it = impl->m_DataProviders.find(dataSourceUid);
110 auto dataProvider = (it != impl->m_DataProviders.end()) ? it->second : nullptr;
124 auto dataProvider = (it != impl->m_DataProviders.end()) ? it->second : nullptr;
111
125
112 emit variableCreationRequested(productItem.name(), productItem.data(), dataProvider);
126 emit variableCreationRequested(productItem.name(), productItem.data(), dataProvider);
113 }
127 }
114 else {
128 else {
115 qCWarning(LOG_DataSourceController()) << tr("Can't load an item that is not a product");
129 qCWarning(LOG_DataSourceController()) << tr("Can't load an item that is not a product");
116 }
130 }
117 }
131 }
118
132
119 QByteArray DataSourceController::mimeDataForProductsData(const QVariantList &productsData)
133 QByteArray DataSourceController::mimeDataForProductsData(const QVariantList &productsData)
120 {
134 {
121 QByteArray encodedData;
135 QByteArray encodedData;
122 QDataStream stream{&encodedData, QIODevice::WriteOnly};
136 QDataStream stream{&encodedData, QIODevice::WriteOnly};
123
137
124 stream << productsData;
138 stream << productsData;
125
139
126 return encodedData;
140 return encodedData;
127 }
141 }
128
142
129 QVariantList DataSourceController::productsDataForMimeData(const QByteArray &mimeData)
143 QVariantList DataSourceController::productsDataForMimeData(const QByteArray &mimeData)
130 {
144 {
131 QDataStream stream{mimeData};
145 QDataStream stream{mimeData};
132
146
133 QVariantList productList;
147 QVariantList productList;
134 stream >> productList;
148 stream >> productList;
135
149
136 return productList;
150 return productList;
137 }
151 }
138
152
139 void DataSourceController::initialize()
153 void DataSourceController::initialize()
140 {
154 {
141 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init")
155 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init")
142 << QThread::currentThread();
156 << QThread::currentThread();
143 impl->m_WorkingMutex.lock();
157 impl->m_WorkingMutex.lock();
144 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init END");
158 qCDebug(LOG_DataSourceController()) << tr("DataSourceController init END");
145 }
159 }
146
160
147 void DataSourceController::finalize()
161 void DataSourceController::finalize()
148 {
162 {
149 impl->m_WorkingMutex.unlock();
163 impl->m_WorkingMutex.unlock();
150 }
164 }
151
165
166 void DataSourceController::requestVariable(const QString &datasourceIdKey)
167 {
168 auto sourceItem = impl->findDataSourceItem(datasourceIdKey);
169
170 if (sourceItem) {
171 auto sourceName = sourceItem->rootItem().name();
172 auto sourceId = impl->m_DataSources.key(sourceName);
173 loadProductItem(sourceId, *sourceItem);
174 }
175 else {
176 qCWarning(LOG_DataSourceController()) << tr("requestVariable, product data not found");
177 }
178 }
179
152 void DataSourceController::requestVariable(const QVariantHash &productData)
180 void DataSourceController::requestVariable(const QVariantHash &productData)
153 {
181 {
154 auto sourceItem = impl->findDataSourceItem(productData);
182 auto sourceItem = impl->findDataSourceItem(productData);
155
183
156 if (sourceItem) {
184 if (sourceItem) {
157 auto sourceName = sourceItem->rootItem().name();
185 auto sourceName = sourceItem->rootItem().name();
158 auto sourceId = impl->m_DataSources.key(sourceName);
186 auto sourceId = impl->m_DataSources.key(sourceName);
159 loadProductItem(sourceId, *sourceItem);
187 loadProductItem(sourceId, *sourceItem);
160 }
188 }
161 else {
189 else {
162 qCWarning(LOG_DataSourceController()) << tr("requestVariable, product data not found");
190 qCWarning(LOG_DataSourceController()) << tr("requestVariable, product data not found");
163 }
191 }
164 }
192 }
165
193
166 void DataSourceController::waitForFinish()
194 void DataSourceController::waitForFinish()
167 {
195 {
168 QMutexLocker locker{&impl->m_WorkingMutex};
196 QMutexLocker locker{&impl->m_WorkingMutex};
169 }
197 }
@@ -1,187 +1,205
1 #include <DataSource/DataSourceItem.h>
1 #include <DataSource/DataSourceItem.h>
2 #include <DataSource/DataSourceItemAction.h>
2 #include <DataSource/DataSourceItemAction.h>
3 #include <DataSource/DataSourceItemMergeHelper.h>
3 #include <DataSource/DataSourceItemMergeHelper.h>
4
4
5 #include <QVector>
5 #include <QVector>
6
6
7 const QString DataSourceItem::NAME_DATA_KEY = QStringLiteral("name");
7 const QString DataSourceItem::NAME_DATA_KEY = QStringLiteral("name");
8 const QString DataSourceItem::PLUGIN_DATA_KEY = QStringLiteral("plugin");
8 const QString DataSourceItem::PLUGIN_DATA_KEY = QStringLiteral("plugin");
9 const QString DataSourceItem::ID_DATA_KEY = QStringLiteral("uuid");
9 const QString DataSourceItem::ID_DATA_KEY = QStringLiteral("uuid");
10
10
11 struct DataSourceItem::DataSourceItemPrivate {
11 struct DataSourceItem::DataSourceItemPrivate {
12 explicit DataSourceItemPrivate(DataSourceItemType type, QVariantHash data)
12 explicit DataSourceItemPrivate(DataSourceItemType type, QVariantHash data)
13 : m_Parent{nullptr}, m_Children{}, m_Type{type}, m_Data{std::move(data)}, m_Actions{}
13 : m_Parent{nullptr}, m_Children{}, m_Type{type}, m_Data{std::move(data)}, m_Actions{}
14 {
14 {
15 }
15 }
16
16
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 QVariantHash m_Data;
20 QVariantHash m_Data;
21 std::vector<std::unique_ptr<DataSourceItemAction> > m_Actions;
21 std::vector<std::unique_ptr<DataSourceItemAction> > m_Actions;
22 };
22 };
23
23
24 DataSourceItem::DataSourceItem(DataSourceItemType type, const QString &name)
24 DataSourceItem::DataSourceItem(DataSourceItemType type, const QString &name)
25 : DataSourceItem{type, QVariantHash{{NAME_DATA_KEY, name}}}
25 : DataSourceItem{type, QVariantHash{{NAME_DATA_KEY, name}}}
26 {
26 {
27 }
27 }
28
28
29 DataSourceItem::DataSourceItem(DataSourceItemType type, QVariantHash data)
29 DataSourceItem::DataSourceItem(DataSourceItemType type, QVariantHash data)
30 : impl{spimpl::make_unique_impl<DataSourceItemPrivate>(type, std::move(data))}
30 : impl{spimpl::make_unique_impl<DataSourceItemPrivate>(type, std::move(data))}
31 {
31 {
32 }
32 }
33
33
34 std::unique_ptr<DataSourceItem> DataSourceItem::clone() const
34 std::unique_ptr<DataSourceItem> DataSourceItem::clone() const
35 {
35 {
36 auto result = std::make_unique<DataSourceItem>(impl->m_Type, impl->m_Data);
36 auto result = std::make_unique<DataSourceItem>(impl->m_Type, impl->m_Data);
37
37
38 // Clones children
38 // Clones children
39 for (const auto &child : impl->m_Children) {
39 for (const auto &child : impl->m_Children) {
40 result->appendChild(std::move(child->clone()));
40 result->appendChild(std::move(child->clone()));
41 }
41 }
42
42
43 // Clones actions
43 // Clones actions
44 for (const auto &action : impl->m_Actions) {
44 for (const auto &action : impl->m_Actions) {
45 result->addAction(std::move(action->clone()));
45 result->addAction(std::move(action->clone()));
46 }
46 }
47
47
48 return result;
48 return result;
49 }
49 }
50
50
51 QVector<DataSourceItemAction *> DataSourceItem::actions() const noexcept
51 QVector<DataSourceItemAction *> DataSourceItem::actions() const noexcept
52 {
52 {
53 auto result = QVector<DataSourceItemAction *>{};
53 auto result = QVector<DataSourceItemAction *>{};
54
54
55 std::transform(std::cbegin(impl->m_Actions), std::cend(impl->m_Actions),
55 std::transform(std::cbegin(impl->m_Actions), std::cend(impl->m_Actions),
56 std::back_inserter(result), [](const auto &action) { return action.get(); });
56 std::back_inserter(result), [](const auto &action) { return action.get(); });
57
57
58 return result;
58 return result;
59 }
59 }
60
60
61 void DataSourceItem::addAction(std::unique_ptr<DataSourceItemAction> action) noexcept
61 void DataSourceItem::addAction(std::unique_ptr<DataSourceItemAction> action) noexcept
62 {
62 {
63 action->setDataSourceItem(this);
63 action->setDataSourceItem(this);
64 impl->m_Actions.push_back(std::move(action));
64 impl->m_Actions.push_back(std::move(action));
65 }
65 }
66
66
67 void DataSourceItem::appendChild(std::unique_ptr<DataSourceItem> child) noexcept
67 void DataSourceItem::appendChild(std::unique_ptr<DataSourceItem> child) noexcept
68 {
68 {
69 child->impl->m_Parent = this;
69 child->impl->m_Parent = this;
70 impl->m_Children.push_back(std::move(child));
70 impl->m_Children.push_back(std::move(child));
71 }
71 }
72
72
73 DataSourceItem *DataSourceItem::child(int childIndex) const noexcept
73 DataSourceItem *DataSourceItem::child(int childIndex) const noexcept
74 {
74 {
75 if (childIndex < 0 || childIndex >= childCount()) {
75 if (childIndex < 0 || childIndex >= childCount()) {
76 return nullptr;
76 return nullptr;
77 }
77 }
78 else {
78 else {
79 return impl->m_Children.at(childIndex).get();
79 return impl->m_Children.at(childIndex).get();
80 }
80 }
81 }
81 }
82
82
83 int DataSourceItem::childCount() const noexcept
83 int DataSourceItem::childCount() const noexcept
84 {
84 {
85 return impl->m_Children.size();
85 return impl->m_Children.size();
86 }
86 }
87
87
88 QVariant DataSourceItem::data(const QString &key) const noexcept
88 QVariant DataSourceItem::data(const QString &key) const noexcept
89 {
89 {
90 return impl->m_Data.value(key);
90 return impl->m_Data.value(key);
91 }
91 }
92
92
93 QVariantHash DataSourceItem::data() const noexcept
93 QVariantHash DataSourceItem::data() const noexcept
94 {
94 {
95 return impl->m_Data;
95 return impl->m_Data;
96 }
96 }
97
97
98 void DataSourceItem::merge(const DataSourceItem &item)
98 void DataSourceItem::merge(const DataSourceItem &item)
99 {
99 {
100 DataSourceItemMergeHelper::merge(item, *this);
100 DataSourceItemMergeHelper::merge(item, *this);
101 }
101 }
102
102
103 bool DataSourceItem::isRoot() const noexcept
103 bool DataSourceItem::isRoot() const noexcept
104 {
104 {
105 return impl->m_Parent == nullptr;
105 return impl->m_Parent == nullptr;
106 }
106 }
107
107
108 QString DataSourceItem::name() const noexcept
108 QString DataSourceItem::name() const noexcept
109 {
109 {
110 return data(NAME_DATA_KEY).toString();
110 return data(NAME_DATA_KEY).toString();
111 }
111 }
112
112
113 DataSourceItem *DataSourceItem::parentItem() const noexcept
113 DataSourceItem *DataSourceItem::parentItem() const noexcept
114 {
114 {
115 return impl->m_Parent;
115 return impl->m_Parent;
116 }
116 }
117
117
118 const DataSourceItem &DataSourceItem::rootItem() const noexcept
118 const DataSourceItem &DataSourceItem::rootItem() const noexcept
119 {
119 {
120 return isRoot() ? *this : parentItem()->rootItem();
120 return isRoot() ? *this : parentItem()->rootItem();
121 }
121 }
122
122
123 void DataSourceItem::setData(const QString &key, const QVariant &value, bool append) noexcept
123 void DataSourceItem::setData(const QString &key, const QVariant &value, bool append) noexcept
124 {
124 {
125 auto it = impl->m_Data.constFind(key);
125 auto it = impl->m_Data.constFind(key);
126 if (append && it != impl->m_Data.constEnd()) {
126 if (append && it != impl->m_Data.constEnd()) {
127 // Case of an existing value to which we want to add to the new value
127 // Case of an existing value to which we want to add to the new value
128 if (it->canConvert<QVariantList>()) {
128 if (it->canConvert<QVariantList>()) {
129 auto variantList = it->value<QVariantList>();
129 auto variantList = it->value<QVariantList>();
130 variantList.append(value);
130 variantList.append(value);
131
131
132 impl->m_Data.insert(key, variantList);
132 impl->m_Data.insert(key, variantList);
133 }
133 }
134 else {
134 else {
135 impl->m_Data.insert(key, QVariantList{*it, value});
135 impl->m_Data.insert(key, QVariantList{*it, value});
136 }
136 }
137 }
137 }
138 else {
138 else {
139 // Other cases :
139 // Other cases :
140 // - new value in map OR
140 // - new value in map OR
141 // - replacement of an existing value (not appending)
141 // - replacement of an existing value (not appending)
142 impl->m_Data.insert(key, value);
142 impl->m_Data.insert(key, value);
143 }
143 }
144 }
144 }
145
145
146 DataSourceItemType DataSourceItem::type() const noexcept
146 DataSourceItemType DataSourceItem::type() const noexcept
147 {
147 {
148 return impl->m_Type;
148 return impl->m_Type;
149 }
149 }
150
150
151 DataSourceItem *DataSourceItem::findItem(const QVariantHash &data, bool recursive)
151 DataSourceItem *DataSourceItem::findItem(const QVariantHash &data, bool recursive)
152 {
152 {
153 for (const auto &child : impl->m_Children) {
153 for (const auto &child : impl->m_Children) {
154 if (child->impl->m_Data == data) {
154 if (child->impl->m_Data == data) {
155 return child.get();
155 return child.get();
156 }
156 }
157
157
158 if (recursive) {
158 if (recursive) {
159 if (auto foundItem = child->findItem(data, true)) {
159 if (auto foundItem = child->findItem(data, true)) {
160 return foundItem;
160 return foundItem;
161 }
161 }
162 }
162 }
163 }
163 }
164
164
165 return nullptr;
165 return nullptr;
166 }
166 }
167
167
168 DataSourceItem *DataSourceItem::findItem(const QString &datasourceIdKey, bool recursive)
169 {
170 for (const auto &child : impl->m_Children) {
171 auto childId = child->impl->m_Data.value(ID_DATA_KEY);
172 if (childId == datasourceIdKey) {
173 return child.get();
174 }
175
176 if (recursive) {
177 if (auto foundItem = child->findItem(datasourceIdKey, true)) {
178 return foundItem;
179 }
180 }
181 }
182
183 return nullptr;
184 }
185
168 bool DataSourceItem::operator==(const DataSourceItem &other)
186 bool DataSourceItem::operator==(const DataSourceItem &other)
169 {
187 {
170 // Compares items' attributes
188 // Compares items' attributes
171 if (std::tie(impl->m_Type, impl->m_Data) == std::tie(other.impl->m_Type, other.impl->m_Data)) {
189 if (std::tie(impl->m_Type, impl->m_Data) == std::tie(other.impl->m_Type, other.impl->m_Data)) {
172 // Compares contents of items' children
190 // Compares contents of items' children
173 return std::equal(std::cbegin(impl->m_Children), std::cend(impl->m_Children),
191 return std::equal(std::cbegin(impl->m_Children), std::cend(impl->m_Children),
174 std::cbegin(other.impl->m_Children), std::cend(other.impl->m_Children),
192 std::cbegin(other.impl->m_Children), std::cend(other.impl->m_Children),
175 [](const auto &itemChild, const auto &otherChild) {
193 [](const auto &itemChild, const auto &otherChild) {
176 return *itemChild == *otherChild;
194 return *itemChild == *otherChild;
177 });
195 });
178 }
196 }
179 else {
197 else {
180 return false;
198 return false;
181 }
199 }
182 }
200 }
183
201
184 bool DataSourceItem::operator!=(const DataSourceItem &other)
202 bool DataSourceItem::operator!=(const DataSourceItem &other)
185 {
203 {
186 return !(*this == other);
204 return !(*this == other);
187 }
205 }
General Comments 0
You need to be logged in to leave comments. Login now