@@ -0,0 +1,68 | |||||
|
1 | ||||
|
2 | /*------------------------------------------------------------------------------ | |||
|
3 | * -- This file is a part of SciQLop | |||
|
4 | * -- Copyright (C) 2019, Plasma Physics Laboratory - CNRS | |||
|
5 | * -- | |||
|
6 | * -- This program is free software; you can redistribute it and/or modify | |||
|
7 | * -- it under the terms of the GNU General Public License as published by | |||
|
8 | * -- the Free Software Foundation; either version 3 of the License, or | |||
|
9 | * -- (at your option) any later version. | |||
|
10 | * -- | |||
|
11 | * -- This program is distributed in the hope that it will be useful, | |||
|
12 | * -- but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
13 | * -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
14 | * -- GNU General Public License for more details. | |||
|
15 | * -- | |||
|
16 | * -- You should have received a copy of the GNU General Public License | |||
|
17 | * -- along with this program; if not, write to the Free Software | |||
|
18 | * -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
|
19 | * -------------------------------------------------------------------------------*/ | |||
|
20 | /* -- Author : Alexis Jeandet | |||
|
21 | * -- Mail : alexis.jeandet@lpp.polytechnique.fr | |||
|
22 | * -- alexis.jeandet@member.fsf.org | |||
|
23 | * ----------------------------------------------------------------------------*/ | |||
|
24 | ||||
|
25 | #ifndef DATASOURCES_H | |||
|
26 | #define DATASOURCES_H | |||
|
27 | ||||
|
28 | #include "Data/IDataProvider.h" | |||
|
29 | #include "DataSourceItem.h" | |||
|
30 | ||||
|
31 | #include <QAbstractItemModel> | |||
|
32 | ||||
|
33 | class DataSources : public QAbstractItemModel | |||
|
34 | { | |||
|
35 | Q_OBJECT | |||
|
36 | ||||
|
37 | public: | |||
|
38 | enum Roles | |||
|
39 | { | |||
|
40 | CustomRole = Qt::UserRole | |||
|
41 | }; | |||
|
42 | ||||
|
43 | public: | |||
|
44 | DataSources() : _root{} {} | |||
|
45 | ~DataSources() { delete _root; } | |||
|
46 | ||||
|
47 | virtual QVariant data(const QModelIndex& index, int role) const override; | |||
|
48 | ||||
|
49 | int columnCount(const QModelIndex& parent) const override; | |||
|
50 | ||||
|
51 | virtual int rowCount(const QModelIndex& parent) const override; | |||
|
52 | ||||
|
53 | QModelIndex parent(const QModelIndex& index) const override; | |||
|
54 | ||||
|
55 | virtual QModelIndex index(int row, int column, | |||
|
56 | const QModelIndex& parent) const override; | |||
|
57 | ||||
|
58 | void addDataSourceItem(const QUuid& providerUid, const QString& path, | |||
|
59 | const QMap<QString, QString>& metaData) noexcept; | |||
|
60 | ||||
|
61 | void addProvider(IDataProvider* provider) noexcept; | |||
|
62 | ||||
|
63 | private: | |||
|
64 | DataSourceItem* _root; | |||
|
65 | std::map<QUuid, std::shared_ptr<IDataProvider>> _DataProviders; | |||
|
66 | }; | |||
|
67 | ||||
|
68 | #endif // DATASOURCES_H |
@@ -0,0 +1,144 | |||||
|
1 | /*------------------------------------------------------------------------------ | |||
|
2 | * -- This file is a part of SciQLop | |||
|
3 | * -- Copyright (C) 2019, Plasma Physics Laboratory - CNRS | |||
|
4 | * -- | |||
|
5 | * -- This program is free software; you can redistribute it and/or modify | |||
|
6 | * -- it under the terms of the GNU General Public License as published by | |||
|
7 | * -- the Free Software Foundation; either version 3 of the License, or | |||
|
8 | * -- (at your option) any later version. | |||
|
9 | * -- | |||
|
10 | * -- This program is distributed in the hope that it will be useful, | |||
|
11 | * -- but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
12 | * -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
13 | * -- GNU General Public License for more details. | |||
|
14 | * -- | |||
|
15 | * -- You should have received a copy of the GNU General Public License | |||
|
16 | * -- along with this program; if not, write to the Free Software | |||
|
17 | * -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
|
18 | * -------------------------------------------------------------------------------*/ | |||
|
19 | /*-- Author : Alexis Jeandet | |||
|
20 | * -- Mail : alexis.jeandet@lpp.polytechnique.fr | |||
|
21 | * -- alexis.jeandet@member.fsf.org | |||
|
22 | * ----------------------------------------------------------------------------*/ | |||
|
23 | // https://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html | |||
|
24 | ||||
|
25 | #include "DataSource/datasources.h" | |||
|
26 | ||||
|
27 | inline std::unique_ptr<DataSourceItem> make_folder_item(const QString& name) | |||
|
28 | { | |||
|
29 | return std::make_unique<DataSourceItem>(DataSourceItemType::NODE, name); | |||
|
30 | } | |||
|
31 | ||||
|
32 | template<typename T> | |||
|
33 | DataSourceItem* make_path_items(const T& path_list_begin, | |||
|
34 | const T& path_list_end, DataSourceItem* root) | |||
|
35 | { | |||
|
36 | std::for_each(path_list_begin, path_list_end, | |||
|
37 | [&root](const auto& folder_name) mutable { | |||
|
38 | auto folder_ptr = root->findItem(folder_name); | |||
|
39 | if(folder_ptr == nullptr) | |||
|
40 | { | |||
|
41 | auto folder = make_folder_item(folder_name); | |||
|
42 | folder_ptr = folder.get(); | |||
|
43 | root->appendChild(std::move(folder)); | |||
|
44 | } | |||
|
45 | root = folder_ptr; | |||
|
46 | }); | |||
|
47 | return root; | |||
|
48 | } | |||
|
49 | ||||
|
50 | inline std::unique_ptr<DataSourceItem> | |||
|
51 | make_product_item(const QVariantHash& metaData, const QUuid& dataSourceUid, | |||
|
52 | const QString& DATA_SOURCE_NAME, DataSources* dc) | |||
|
53 | { | |||
|
54 | auto result = | |||
|
55 | std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT, metaData); | |||
|
56 | ||||
|
57 | // Adds plugin name to product metadata | |||
|
58 | result->setData(DataSourceItem::PLUGIN_DATA_KEY, DATA_SOURCE_NAME); | |||
|
59 | result->setData(DataSourceItem::ID_DATA_KEY, | |||
|
60 | metaData.value(DataSourceItem::NAME_DATA_KEY)); | |||
|
61 | ||||
|
62 | auto productName = metaData.value(DataSourceItem::NAME_DATA_KEY).toString(); | |||
|
63 | ||||
|
64 | // Add action to load product from DataSourceController | |||
|
65 | // result->addAction(std::make_unique<DataSourceItemAction>( | |||
|
66 | // QObject::tr("Load %1 product").arg(productName), | |||
|
67 | // [productName, dataSourceUid, dc](DataSourceItem& item) { | |||
|
68 | // if(dc) { dc->loadProductItem(dataSourceUid, item); } | |||
|
69 | // })); | |||
|
70 | ||||
|
71 | return result; | |||
|
72 | } | |||
|
73 | ||||
|
74 | QVariant DataSources::data(const QModelIndex& index, int role) const | |||
|
75 | { | |||
|
76 | if(!index.isValid()) return QVariant(); | |||
|
77 | if(role != Qt::DisplayRole) return QVariant(); | |||
|
78 | DataSourceItem* item = static_cast<DataSourceItem*>(index.internalPointer()); | |||
|
79 | return item->name(); | |||
|
80 | } | |||
|
81 | ||||
|
82 | int DataSources::columnCount(const QModelIndex& parent) const | |||
|
83 | { | |||
|
84 | (void)parent; | |||
|
85 | return 0; | |||
|
86 | } | |||
|
87 | ||||
|
88 | int DataSources::rowCount(const QModelIndex& parent) const | |||
|
89 | { | |||
|
90 | DataSourceItem* parentItem; | |||
|
91 | if(parent.column() > 0) return 0; | |||
|
92 | if(!parent.isValid()) | |||
|
93 | parentItem = _root; | |||
|
94 | else | |||
|
95 | parentItem = static_cast<DataSourceItem*>(parent.internalPointer()); | |||
|
96 | return parentItem->childCount(); | |||
|
97 | } | |||
|
98 | ||||
|
99 | QModelIndex DataSources::parent(const QModelIndex& index) const | |||
|
100 | { | |||
|
101 | if(!index.isValid()) return QModelIndex(); | |||
|
102 | DataSourceItem* childItem = | |||
|
103 | static_cast<DataSourceItem*>(index.internalPointer()); | |||
|
104 | DataSourceItem* parentItem = childItem->parentItem(); | |||
|
105 | if(parentItem == _root) return QModelIndex(); | |||
|
106 | return createIndex(parentItem->index(), 0, parentItem); | |||
|
107 | } | |||
|
108 | ||||
|
109 | QModelIndex DataSources::index(int row, int column, | |||
|
110 | const QModelIndex& parent) const | |||
|
111 | { | |||
|
112 | if(!hasIndex(row, column, parent)) return QModelIndex(); | |||
|
113 | DataSourceItem* parentItem; | |||
|
114 | if(!parent.isValid()) | |||
|
115 | parentItem = _root; | |||
|
116 | else | |||
|
117 | parentItem = static_cast<DataSourceItem*>(parent.internalPointer()); | |||
|
118 | DataSourceItem* childItem = parentItem->child(row); | |||
|
119 | if(childItem) return createIndex(row, column, childItem); | |||
|
120 | return QModelIndex(); | |||
|
121 | } | |||
|
122 | ||||
|
123 | void DataSources::addDataSourceItem( | |||
|
124 | const QUuid& providerUid, const QString& path, | |||
|
125 | const QMap<QString, QString>& metaData) noexcept | |||
|
126 | { | |||
|
127 | auto path_list = path.split('/', QString::SkipEmptyParts); | |||
|
128 | auto name = *(std::cend(path_list) - 1); | |||
|
129 | auto path_item = | |||
|
130 | make_path_items(std::cbegin(path_list), std::cend(path_list) - 1, _root); | |||
|
131 | QVariantHash meta_data{{DataSourceItem::NAME_DATA_KEY, name}}; | |||
|
132 | for(auto& key : metaData.keys()) | |||
|
133 | { | |||
|
134 | meta_data[key] = metaData[key]; | |||
|
135 | } | |||
|
136 | path_item->appendChild( | |||
|
137 | make_product_item(meta_data, providerUid, "test", this)); | |||
|
138 | } | |||
|
139 | ||||
|
140 | void DataSources::addProvider(IDataProvider* provider) noexcept | |||
|
141 | { | |||
|
142 | _DataProviders.insert( | |||
|
143 | {provider->id(), std::unique_ptr<IDataProvider>{provider}}); | |||
|
144 | } |
@@ -0,0 +1,19 | |||||
|
1 | #include <DataSource/datasources.h> | |||
|
2 | #include <DataSource/DataSourceItem.h> | |||
|
3 | ||||
|
4 | #include <QObject> | |||
|
5 | #include <QtTest> | |||
|
6 | ||||
|
7 | class TestDataSources : public QObject { | |||
|
8 | Q_OBJECT | |||
|
9 | private slots: | |||
|
10 | void addItems(); | |||
|
11 | }; | |||
|
12 | ||||
|
13 | void TestDataSources::addItems() | |||
|
14 | { | |||
|
15 | DataSources ds; | |||
|
16 | } | |||
|
17 | ||||
|
18 | QTEST_MAIN(TestDataSources) | |||
|
19 | #include "TestDataSources.moc" |
@@ -34,9 +34,7 class SCIQLOP_CORE_EXPORT IDataProvider : public QObject | |||||
34 |
|
34 | |||
35 | public: |
|
35 | public: | |
36 | virtual ~IDataProvider() noexcept = default; |
|
36 | virtual ~IDataProvider() noexcept = default; | |
37 | // virtual std::shared_ptr<IDataProvider> clone() const = 0; |
|
|||
38 |
|
37 | |||
39 | // Synchronous call -> asyncGetData may be written for asynchronous get |
|
|||
40 | virtual TimeSeries::ITimeSerie* |
|
38 | virtual TimeSeries::ITimeSerie* | |
41 | getData(const DataProviderParameters& parameters) = 0; |
|
39 | getData(const DataProviderParameters& parameters) = 0; | |
42 |
|
40 | |||
@@ -54,7 +52,5 signals: | |||||
54 | // Required for using shared_ptr in signals/slots |
|
52 | // Required for using shared_ptr in signals/slots | |
55 | SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_PTR_REGISTRY, |
|
53 | SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_PTR_REGISTRY, | |
56 | std::shared_ptr<IDataProvider>) |
|
54 | std::shared_ptr<IDataProvider>) | |
57 | SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_FUNCTION_REGISTRY, |
|
|||
58 | std::function<void(QNetworkReply*, QUuid)>) |
|
|||
59 |
|
55 | |||
60 | #endif // SCIQLOP_IDATAPROVIDER_H |
|
56 | #endif // SCIQLOP_IDATAPROVIDER_H |
@@ -4,11 +4,11 | |||||
4 | #include "CoreGlobal.h" |
|
4 | #include "CoreGlobal.h" | |
5 |
|
5 | |||
6 | #include <Common/spimpl.h> |
|
6 | #include <Common/spimpl.h> | |
7 | #include <trees/algorithms.hpp> |
|
|||
8 | #include <QVariant> |
|
7 | #include <QVariant> | |
9 | #include <QVector> |
|
8 | #include <QVector> | |
10 | #include <iostream> |
|
|||
11 | #include <iomanip> |
|
9 | #include <iomanip> | |
|
10 | #include <iostream> | |||
|
11 | #include <trees/algorithms.hpp> | |||
12 |
|
12 | |||
13 | class DataSourceItemAction; |
|
13 | class DataSourceItemAction; | |
14 |
|
14 | |||
@@ -22,8 +22,6 enum class DataSourceItemType | |||||
22 | COMPONENT |
|
22 | COMPONENT | |
23 | }; |
|
23 | }; | |
24 |
|
24 | |||
25 |
|
||||
26 |
|
||||
27 | /** |
|
25 | /** | |
28 | * @brief The DataSourceItem class aims to represent a structure element of a |
|
26 | * @brief The DataSourceItem class aims to represent a structure element of a | |
29 | * data source. A data source has a tree structure that is made up of a main |
|
27 | * data source. A data source has a tree structure that is made up of a main | |
@@ -33,10 +31,11 enum class DataSourceItemType | |||||
33 | */ |
|
31 | */ | |
34 | class SCIQLOP_CORE_EXPORT DataSourceItem |
|
32 | class SCIQLOP_CORE_EXPORT DataSourceItem | |
35 | { |
|
33 | { | |
36 |
|
||||
37 | public: |
|
34 | public: | |
38 | using iterator_type = decltype (std::begin(std::declval<std::vector<std::unique_ptr<DataSourceItem>>>())); |
|
35 | using iterator_type = decltype( | |
39 |
|
|
36 | std::begin(std::declval<std::vector<std::unique_ptr<DataSourceItem>>>())); | |
|
37 | using const_iterator_type = decltype(std::cbegin( | |||
|
38 | std::declval<std::vector<std::unique_ptr<DataSourceItem>>>())); | |||
40 | /// Key associated with the name of the item |
|
39 | /// Key associated with the name of the item | |
41 | static const QString NAME_DATA_KEY; |
|
40 | static const QString NAME_DATA_KEY; | |
42 | /// Key associated with the plugin of the item |
|
41 | /// Key associated with the plugin of the item | |
@@ -74,6 +73,8 public: | |||||
74 |
|
73 | |||
75 | int childCount() const noexcept; |
|
74 | int childCount() const noexcept; | |
76 |
|
75 | |||
|
76 | int index() const noexcept; | |||
|
77 | ||||
77 | /** |
|
78 | /** | |
78 | * Get the data associated to a key |
|
79 | * Get the data associated to a key | |
79 | * @param key the key to search |
|
80 | * @param key the key to search | |
@@ -177,10 +178,11 public: | |||||
177 |
|
178 | |||
178 | iterator_type begin() noexcept; |
|
179 | iterator_type begin() noexcept; | |
179 | iterator_type end() noexcept; |
|
180 | iterator_type end() noexcept; | |
180 | const_iterator_type begin()const noexcept; |
|
181 | const_iterator_type begin() const noexcept; | |
181 |
const_iterator_type end()const |
|
182 | const_iterator_type end() const noexcept; | |
182 | const_iterator_type cbegin()const noexcept; |
|
183 | const_iterator_type cbegin() const noexcept; | |
183 |
const_iterator_type cend()const |
|
184 | const_iterator_type cend() const noexcept; | |
|
185 | ||||
184 | private: |
|
186 | private: | |
185 | class DataSourceItemPrivate; |
|
187 | class DataSourceItemPrivate; | |
186 | spimpl::unique_impl_ptr<DataSourceItemPrivate> impl; |
|
188 | spimpl::unique_impl_ptr<DataSourceItemPrivate> impl; |
@@ -30,6 +30,7 core_moc_headers = [ | |||||
30 | './include/Settings/SqpSettingsDefs.h', |
|
30 | './include/Settings/SqpSettingsDefs.h', | |
31 | './include/Settings/ISqpSettingsBindable.h', |
|
31 | './include/Settings/ISqpSettingsBindable.h', | |
32 | './include/DataSource/DataSourceController.h', |
|
32 | './include/DataSource/DataSourceController.h', | |
|
33 | './include/DataSource/datasources.h', | |||
33 | './include/DataSource/DataSourceItem.h', |
|
34 | './include/DataSource/DataSourceItem.h', | |
34 | './include/DataSource/DataSourceItemAction.h', |
|
35 | './include/DataSource/DataSourceItemAction.h', | |
35 | './include/DataSource/DataSourceItemMergeHelper.h', |
|
36 | './include/DataSource/DataSourceItemMergeHelper.h', | |
@@ -61,6 +62,7 core_sources = ['./src/Common/MimeTypesDef.cpp', | |||||
61 | './src/DataSource/DataSourceItemMergeHelper.cpp', |
|
62 | './src/DataSource/DataSourceItemMergeHelper.cpp', | |
62 | './src/DataSource/DataSourceItem.cpp', |
|
63 | './src/DataSource/DataSourceItem.cpp', | |
63 | './src/DataSource/DataSourceController.cpp', |
|
64 | './src/DataSource/DataSourceController.cpp', | |
|
65 | './src/DataSource/datasources.cpp', | |||
64 | './src/Time/TimeController.cpp', |
|
66 | './src/Time/TimeController.cpp', | |
65 | './src/PluginManager/PluginManager.cpp', |
|
67 | './src/PluginManager/PluginManager.cpp', | |
66 | './src/Version.cpp', |
|
68 | './src/Version.cpp', |
@@ -2,6 +2,7 | |||||
2 | #include <DataSource/DataSourceItemAction.h> |
|
2 | #include <DataSource/DataSourceItemAction.h> | |
3 | #include <DataSource/DataSourceItemMergeHelper.h> |
|
3 | #include <DataSource/DataSourceItemMergeHelper.h> | |
4 | #include <QVector> |
|
4 | #include <QVector> | |
|
5 | #include <containers/algorithms.hpp> | |||
5 |
|
6 | |||
6 | const QString DataSourceItem::NAME_DATA_KEY = QStringLiteral("name"); |
|
7 | const QString DataSourceItem::NAME_DATA_KEY = QStringLiteral("name"); | |
7 | const QString DataSourceItem::PLUGIN_DATA_KEY = QStringLiteral("plugin"); |
|
8 | const QString DataSourceItem::PLUGIN_DATA_KEY = QStringLiteral("plugin"); | |
@@ -25,6 +26,12 struct DataSourceItem::DataSourceItemPrivate | |||||
25 | auto end()noexcept{return m_Children.end();} |
|
26 | auto end()noexcept{return m_Children.end();} | |
26 | auto cbegin()const noexcept{return m_Children.cbegin();} |
|
27 | auto cbegin()const noexcept{return m_Children.cbegin();} | |
27 | auto cend()const noexcept{return m_Children.cend();} |
|
28 | auto cend()const noexcept{return m_Children.cend();} | |
|
29 | ||||
|
30 | int index_of(const DataSourceItem* item) | |||
|
31 | { | |||
|
32 | return std::distance( | |||
|
33 | std::cbegin(m_Children), std::find_if(std::cbegin(m_Children), std::cend(m_Children), [item](const auto& other){return other.get()==item;})); | |||
|
34 | } | |||
28 | }; |
|
35 | }; | |
29 |
|
36 | |||
30 | DataSourceItem::DataSourceItem(DataSourceItemType type, const QString& name) |
|
37 | DataSourceItem::DataSourceItem(DataSourceItemType type, const QString& name) | |
@@ -120,6 +127,15 DataSourceItem* DataSourceItem::parentItem() const noexcept | |||||
120 | return impl->m_Parent; |
|
127 | return impl->m_Parent; | |
121 | } |
|
128 | } | |
122 |
|
129 | |||
|
130 | int DataSourceItem::index() const noexcept | |||
|
131 | { | |||
|
132 | if(auto parent = parentItem(); parent) | |||
|
133 | { | |||
|
134 | return parent->impl->index_of(this); | |||
|
135 | } | |||
|
136 | return 0; | |||
|
137 | } | |||
|
138 | ||||
123 | const DataSourceItem& DataSourceItem::rootItem() const noexcept |
|
139 | const DataSourceItem& DataSourceItem::rootItem() const noexcept | |
124 | { |
|
140 | { | |
125 | return isRoot() ? *this : parentItem()->rootItem(); |
|
141 | return isRoot() ? *this : parentItem()->rootItem(); |
@@ -29,6 +29,13 tests = [ | |||||
29 | 'deps': [sciqlop_core, qt5test] |
|
29 | 'deps': [sciqlop_core, qt5test] | |
30 | }, |
|
30 | }, | |
31 | { |
|
31 | { | |
|
32 | 'name':'TestDataSources', | |||
|
33 | 'sources': [ | |||
|
34 | 'DataSource/TestDataSources.cpp' | |||
|
35 | ], | |||
|
36 | 'deps': [sciqlop_core, qt5test, TestUtils_dep] | |||
|
37 | }, | |||
|
38 | { | |||
32 | 'name':'TestDataSourceItem', |
|
39 | 'name':'TestDataSourceItem', | |
33 | 'sources': [ |
|
40 | 'sources': [ | |
34 | 'DataSource/TestDataSourceItem.cpp', |
|
41 | 'DataSource/TestDataSourceItem.cpp', |
General Comments 0
You need to be logged in to leave comments.
Login now