@@ -0,0 +1,55 | |||||
|
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 | #ifndef DATASOURCESFILTER_H_INCLUDED | |||
|
24 | #define DATASOURCESFILTER_H_INCLUDED | |||
|
25 | ||||
|
26 | #include "DataSourceItem.h" | |||
|
27 | ||||
|
28 | #include <QObject> | |||
|
29 | #include <QSortFilterProxyModel> | |||
|
30 | ||||
|
31 | class DataSourceFilter : public QSortFilterProxyModel | |||
|
32 | { | |||
|
33 | Q_OBJECT | |||
|
34 | public: | |||
|
35 | explicit DataSourceFilter(QObject* parent = nullptr); | |||
|
36 | ||||
|
37 | bool filterAcceptsRow(int sourceRow, | |||
|
38 | const QModelIndex& sourceParent) const override | |||
|
39 | { | |||
|
40 | if(filterRegExp().isEmpty()) { return true; } | |||
|
41 | DataSourceItem* childItem = static_cast<DataSourceItem*>( | |||
|
42 | sourceModel()->index(sourceRow, 0, sourceParent).internalPointer()); | |||
|
43 | if(childItem) | |||
|
44 | { | |||
|
45 | auto data = childItem->data(); | |||
|
46 | return (std::find_if(std::cbegin(data), std::cend(data), | |||
|
47 | [regex = filterRegExp()](const auto& item) { | |||
|
48 | return item.toString().contains(regex); | |||
|
49 | }) != std::cend(data)); | |||
|
50 | } | |||
|
51 | return false; | |||
|
52 | } | |||
|
53 | }; | |||
|
54 | ||||
|
55 | #endif // DATASOURCESFILTER_H_INCLUDED |
@@ -0,0 +1,28 | |||||
|
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 | ||||
|
24 | #include "DataSource/DataSourcesFilter.h" | |||
|
25 | ||||
|
26 | DataSourceFilter::DataSourceFilter(QObject* parent) | |||
|
27 | : QSortFilterProxyModel(parent) | |||
|
28 | {} |
@@ -0,0 +1,78 | |||||
|
1 | #include "DataSource/DataSourcesFilter.h" | |||
|
2 | #include "DataSource/datasources.h" | |||
|
3 | #include "TestProviders.h" | |||
|
4 | ||||
|
5 | #include <QApplication> | |||
|
6 | #include <QFileIconProvider> | |||
|
7 | #include <QLineEdit> | |||
|
8 | #include <QObject> | |||
|
9 | #include <QTreeView> | |||
|
10 | #include <QVBoxLayout> | |||
|
11 | #include <QWidget> | |||
|
12 | #include <cpp_utils.hpp> | |||
|
13 | #include <iostream> | |||
|
14 | ||||
|
15 | void fillModel(DataSources* ds, SimpleRange<1>* provider) | |||
|
16 | { | |||
|
17 | ds->addIcon("folder", QFileIconProvider().icon(QFileIconProvider::Folder)); | |||
|
18 | ds->addIcon("computer", | |||
|
19 | QFileIconProvider().icon(QFileIconProvider::Computer)); | |||
|
20 | ds->addProvider(provider); | |||
|
21 | ds->addDataSourceItem(*provider, "/test/node1", {{"Key", "Value"}}); | |||
|
22 | ds->addDataSourceItem(*provider, "/test/node2", {}); | |||
|
23 | ds->addDataSourceItem(*provider, "/test/node3", {}); | |||
|
24 | ds->addDataSourceItem(*provider, "/test/node4", {}); | |||
|
25 | ds->setIcon("/test", "folder"); | |||
|
26 | ds->addDataSourceItem(*provider, "/test/folder/node1", {}); | |||
|
27 | ds->addDataSourceItem(*provider, "/test2/folder/node1", {}); | |||
|
28 | repeat_n( | |||
|
29 | [ds, provider](int i) { | |||
|
30 | repeat_n( | |||
|
31 | [ds, provider, i](int j) { | |||
|
32 | repeat_n( | |||
|
33 | [ds, provider, i, j](int k) { | |||
|
34 | ds->addDataSourceItem(*provider, | |||
|
35 | "/test2/folder" + QString::number(i) + | |||
|
36 | "/folder" + QString::number(j) + | |||
|
37 | "/node" + QString::number(k), | |||
|
38 | {}); | |||
|
39 | }, | |||
|
40 | 10); | |||
|
41 | }, | |||
|
42 | 10); | |||
|
43 | }, | |||
|
44 | 10); | |||
|
45 | ||||
|
46 | ds->updateNodeMetaData("/test2/folder", {{"KeyUp", "ValueUp"}}); | |||
|
47 | ds->setIcon("/test2", "computer"); | |||
|
48 | } | |||
|
49 | ||||
|
50 | int main(int argc, char** argv) | |||
|
51 | { | |||
|
52 | SimpleRange<1>* provider = new SimpleRange<1>{}; | |||
|
53 | QApplication app(argc, argv); | |||
|
54 | auto w = new QWidget(); | |||
|
55 | auto layout = new QVBoxLayout(w); | |||
|
56 | DataSources* ds = new DataSources(); | |||
|
57 | // DataSourceFilter* filter = new DataSourceFilter(); | |||
|
58 | QSortFilterProxyModel* filter = new QSortFilterProxyModel(); | |||
|
59 | filter->setSourceModel(ds); | |||
|
60 | QTreeView* view = new QTreeView(); | |||
|
61 | QLineEdit* filterBox = new QLineEdit(); | |||
|
62 | QObject::connect( | |||
|
63 | filterBox, | |||
|
64 | static_cast<void (QLineEdit::*)(const QString&)>(&QLineEdit::textChanged), | |||
|
65 | filter, | |||
|
66 | static_cast<void (QSortFilterProxyModel::*)(const QString&)>( | |||
|
67 | &QSortFilterProxyModel::setFilterRegExp)); | |||
|
68 | layout->addWidget(filterBox); | |||
|
69 | layout->addWidget(view); | |||
|
70 | view->setModel(filter); | |||
|
71 | w->show(); | |||
|
72 | view->setDragEnabled(true); | |||
|
73 | filter->setFilterRole(Qt::ToolTipRole); | |||
|
74 | filter->setRecursiveFilteringEnabled(true); | |||
|
75 | fillModel(ds, provider); | |||
|
76 | view->expandAll(); | |||
|
77 | return app.exec(); | |||
|
78 | } |
@@ -43,6 +43,8 public: | |||||
43 | { |
|
43 | { | |
44 | return QString("%1-%2").arg(this->metaObject()->className()).arg(id().toString()); |
|
44 | return QString("%1-%2").arg(this->metaObject()->className()).arg(id().toString()); | |
45 | } |
|
45 | } | |
|
46 | ||||
|
47 | operator QUuid(){return _id;} | |||
46 |
|
48 | |||
47 | signals: |
|
49 | signals: | |
48 |
|
50 |
@@ -4,10 +4,12 | |||||
4 | #include "CoreGlobal.h" |
|
4 | #include "CoreGlobal.h" | |
5 |
|
5 | |||
6 | #include <Common/spimpl.h> |
|
6 | #include <Common/spimpl.h> | |
|
7 | #include <QUuid> | |||
7 | #include <QVariant> |
|
8 | #include <QVariant> | |
8 | #include <QVector> |
|
9 | #include <QVector> | |
9 | #include <iomanip> |
|
10 | #include <iomanip> | |
10 | #include <iostream> |
|
11 | #include <iostream> | |
|
12 | #include <optional> | |||
11 | #include <trees/algorithms.hpp> |
|
13 | #include <trees/algorithms.hpp> | |
12 |
|
14 | |||
13 | class DataSourceItemAction; |
|
15 | class DataSourceItemAction; | |
@@ -43,8 +45,9 public: | |||||
43 | /// Key associated with a unique id of the plugin |
|
45 | /// Key associated with a unique id of the plugin | |
44 | static const QString ID_DATA_KEY; |
|
46 | static const QString ID_DATA_KEY; | |
45 |
|
47 | |||
46 | explicit DataSourceItem(DataSourceItemType type, const QString& name); |
|
48 | //explicit DataSourceItem(DataSourceItemType type, const QString& name); | |
47 |
explicit DataSourceItem(DataSourceItemType type, QVariantHash data = {} |
|
49 | explicit DataSourceItem(DataSourceItemType type, const QString& name, QVariantHash data = {}, | |
|
50 | std::optional<QUuid> sourceUUID = std::nullopt); | |||
48 |
|
51 | |||
49 | std::unique_ptr<DataSourceItem> clone() const; |
|
52 | std::unique_ptr<DataSourceItem> clone() const; | |
50 |
|
53 | |||
@@ -128,7 +131,15 public: | |||||
128 |
|
131 | |||
129 | bool isRoot() const noexcept; |
|
132 | bool isRoot() const noexcept; | |
130 |
|
133 | |||
|
134 | inline bool isProductOrComponent() const noexcept | |||
|
135 | { | |||
|
136 | return (this->type() == DataSourceItemType::PRODUCT) || | |||
|
137 | (this->type() == DataSourceItemType::COMPONENT); | |||
|
138 | } | |||
|
139 | ||||
131 | QString name() const noexcept; |
|
140 | QString name() const noexcept; | |
|
141 | QString icon() const noexcept; | |||
|
142 | void setIcon(const QString& iconName); | |||
132 |
|
143 | |||
133 | /** |
|
144 | /** | |
134 | * Get the item's parent |
|
145 | * Get the item's parent | |
@@ -183,8 +194,10 public: | |||||
183 | const_iterator_type cbegin() const noexcept; |
|
194 | const_iterator_type cbegin() const noexcept; | |
184 | const_iterator_type cend() const noexcept; |
|
195 | const_iterator_type cend() const noexcept; | |
185 |
|
196 | |||
|
197 | std::optional<QUuid> source_uuid() const noexcept; | |||
|
198 | ||||
186 | private: |
|
199 | private: | |
187 |
|
|
200 | struct DataSourceItemPrivate; | |
188 | spimpl::unique_impl_ptr<DataSourceItemPrivate> impl; |
|
201 | spimpl::unique_impl_ptr<DataSourceItemPrivate> impl; | |
189 | }; |
|
202 | }; | |
190 |
|
203 |
@@ -1,4 +1,3 | |||||
1 |
|
||||
2 |
|
|
1 | /*------------------------------------------------------------------------------ | |
3 | * -- This file is a part of SciQLop |
|
2 | * -- This file is a part of SciQLop | |
4 | * -- Copyright (C) 2019, Plasma Physics Laboratory - CNRS |
|
3 | * -- Copyright (C) 2019, Plasma Physics Laboratory - CNRS | |
@@ -29,6 +28,8 | |||||
29 | #include "DataSourceItem.h" |
|
28 | #include "DataSourceItem.h" | |
30 |
|
29 | |||
31 | #include <QAbstractItemModel> |
|
30 | #include <QAbstractItemModel> | |
|
31 | #include <QObject> | |||
|
32 | #include <QMimeData> | |||
32 |
|
33 | |||
33 | class DataSources : public QAbstractItemModel |
|
34 | class DataSources : public QAbstractItemModel | |
34 | { |
|
35 | { | |
@@ -41,28 +42,49 public: | |||||
41 | }; |
|
42 | }; | |
42 |
|
43 | |||
43 | public: |
|
44 | public: | |
44 | DataSources() : _root{} {} |
|
45 | DataSources() : _root(new DataSourceItem(DataSourceItemType::NODE, "root")) {} | |
45 | ~DataSources() { delete _root; } |
|
46 | ~DataSources() { delete _root; } | |
46 |
|
47 | |||
47 |
virtual QVariant data(const QModelIndex& index, int role) const |
|
48 | virtual QVariant data(const QModelIndex& index, int role) const final; | |
|
49 | virtual QMimeData* mimeData(const QModelIndexList& indexes) const final; | |||
48 |
|
50 | |||
49 |
int columnCount(const QModelIndex& parent) const |
|
51 | virtual int columnCount(const QModelIndex& parent) const final; | |
50 |
|
52 | |||
51 |
virtual int rowCount(const QModelIndex& parent) const |
|
53 | virtual int rowCount(const QModelIndex& parent) const final; | |
52 |
|
54 | |||
53 |
QModelIndex parent(const QModelIndex& index) const |
|
55 | QModelIndex parent(const QModelIndex& index) const final; | |
54 |
|
56 | |||
55 | virtual QModelIndex index(int row, int column, |
|
57 | virtual QModelIndex index(int row, int column, | |
56 |
const QModelIndex& parent) const |
|
58 | const QModelIndex& parent) const final; | |
|
59 | ||||
|
60 | Qt::ItemFlags flags(const QModelIndex& index) const final; | |||
57 |
|
61 | |||
58 | void addDataSourceItem(const QUuid& providerUid, const QString& path, |
|
62 | void addDataSourceItem(const QUuid& providerUid, const QString& path, | |
59 | const QMap<QString, QString>& metaData) noexcept; |
|
63 | const QMap<QString, QString>& metaData) noexcept; | |
60 |
|
64 | |||
61 | void addProvider(IDataProvider* provider) noexcept; |
|
65 | void addProvider(IDataProvider* provider) noexcept; | |
62 |
|
66 | |||
|
67 | void updateNodeMetaData(const QString& path, | |||
|
68 | const QMap<QString, QString>& metaData) noexcept; | |||
|
69 | ||||
|
70 | void createVariable(const DataSourceItem& item); | |||
|
71 | ||||
|
72 | void addIcon(const QString& name, QVariant icon) | |||
|
73 | { | |||
|
74 | _icons[name] = std::move(icon); | |||
|
75 | } | |||
|
76 | ||||
|
77 | void setIcon(const QString& path, const QString& iconName); | |||
|
78 | ||||
|
79 | Q_SIGNALS: | |||
|
80 | void createVariable(const QString& variableName, | |||
|
81 | const QVariantHash& variableMetadata, | |||
|
82 | std::shared_ptr<IDataProvider> variableProvider); | |||
|
83 | ||||
63 | private: |
|
84 | private: | |
64 | DataSourceItem* _root; |
|
85 | DataSourceItem* _root; | |
65 | std::map<QUuid, std::shared_ptr<IDataProvider>> _DataProviders; |
|
86 | std::map<QUuid, std::shared_ptr<IDataProvider>> _DataProviders; | |
|
87 | QHash<QString, QVariant> _icons; | |||
66 | }; |
|
88 | }; | |
67 |
|
89 | |||
68 | #endif // DATASOURCES_H |
|
90 | #endif // DATASOURCES_H |
@@ -31,6 +31,7 core_moc_headers = [ | |||||
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/datasources.h', | |
|
34 | './include/DataSource/DataSourcesFilter.h', | |||
34 | './include/DataSource/DataSourceItem.h', |
|
35 | './include/DataSource/DataSourceItem.h', | |
35 | './include/DataSource/DataSourceItemAction.h', |
|
36 | './include/DataSource/DataSourceItemAction.h', | |
36 | './include/DataSource/DataSourceItemMergeHelper.h', |
|
37 | './include/DataSource/DataSourceItemMergeHelper.h', | |
@@ -63,6 +64,7 core_sources = ['./src/Common/MimeTypesDef.cpp', | |||||
63 | './src/DataSource/DataSourceItem.cpp', |
|
64 | './src/DataSource/DataSourceItem.cpp', | |
64 | './src/DataSource/DataSourceController.cpp', |
|
65 | './src/DataSource/DataSourceController.cpp', | |
65 | './src/DataSource/datasources.cpp', |
|
66 | './src/DataSource/datasources.cpp', | |
|
67 | './src/DataSource/DataSourcesFilter.cpp', | |||
66 | './src/Time/TimeController.cpp', |
|
68 | './src/Time/TimeController.cpp', | |
67 | './src/PluginManager/PluginManager.cpp', |
|
69 | './src/PluginManager/PluginManager.cpp', | |
68 | './src/Version.cpp', |
|
70 | './src/Version.cpp', |
@@ -40,15 +40,16 std::unique_ptr<DataSourceItem> | |||||
40 | make_product_item(const QVariantHash& metaData, const QUuid& dataSourceUid, |
|
40 | make_product_item(const QVariantHash& metaData, const QUuid& dataSourceUid, | |
41 | const QString& DATA_SOURCE_NAME, DataSourceController* dc) |
|
41 | const QString& DATA_SOURCE_NAME, DataSourceController* dc) | |
42 | { |
|
42 | { | |
|
43 | auto productName = metaData.value(DataSourceItem::NAME_DATA_KEY).toString(); | |||
43 | auto result = |
|
44 | auto result = | |
44 |
|
|
45 | std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT,productName, metaData); | |
45 |
|
46 | |||
46 | // Adds plugin name to product metadata |
|
47 | // Adds plugin name to product metadata | |
47 | result->setData(DataSourceItem::PLUGIN_DATA_KEY, DATA_SOURCE_NAME); |
|
48 | result->setData(DataSourceItem::PLUGIN_DATA_KEY, DATA_SOURCE_NAME); | |
48 | result->setData(DataSourceItem::ID_DATA_KEY, |
|
49 | result->setData(DataSourceItem::ID_DATA_KEY, | |
49 | metaData.value(DataSourceItem::NAME_DATA_KEY)); |
|
50 | metaData.value(DataSourceItem::NAME_DATA_KEY)); | |
50 |
|
51 | |||
51 | auto productName = metaData.value(DataSourceItem::NAME_DATA_KEY).toString(); |
|
52 | ||
52 |
|
|
53 | ||
53 |
|
|
54 | // Add action to load product from DataSourceController | |
54 | result->addAction(std::make_unique<DataSourceItemAction>( |
|
55 | result->addAction(std::make_unique<DataSourceItemAction>( |
@@ -1,8 +1,10 | |||||
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 | #include <QUuid> | |||
4 | #include <QVector> |
|
5 | #include <QVector> | |
5 | #include <containers/algorithms.hpp> |
|
6 | #include <containers/algorithms.hpp> | |
|
7 | #include <optional> | |||
6 |
|
8 | |||
7 | const QString DataSourceItem::NAME_DATA_KEY = QStringLiteral("name"); |
|
9 | const QString DataSourceItem::NAME_DATA_KEY = QStringLiteral("name"); | |
8 | const QString DataSourceItem::PLUGIN_DATA_KEY = QStringLiteral("plugin"); |
|
10 | const QString DataSourceItem::PLUGIN_DATA_KEY = QStringLiteral("plugin"); | |
@@ -10,42 +12,63 const QString DataSourceItem::ID_DATA_KEY = QStringLiteral("uuid"); | |||||
10 |
|
12 | |||
11 | struct DataSourceItem::DataSourceItemPrivate |
|
13 | struct DataSourceItem::DataSourceItemPrivate | |
12 | { |
|
14 | { | |
13 |
explicit DataSourceItemPrivate(DataSourceItemType type, |
|
15 | explicit DataSourceItemPrivate(DataSourceItemType type, const QString& name, | |
14 | : m_Parent{nullptr}, |
|
16 | QVariantHash data, | |
15 | m_Children{}, m_Type{type}, m_Data{std::move(data)}, m_Actions{} |
|
17 | std::optional<QUuid> sourceUUID = std::nullopt) | |
16 | {} |
|
18 | : m_Parent{nullptr}, m_dataSourceUid{sourceUUID}, m_Children{}, | |
|
19 | m_name{name}, m_Type{type}, m_Data{std::move(data)}, m_Actions{} | |||
|
20 | { | |||
|
21 | m_Data[DataSourceItem::NAME_DATA_KEY] = name; | |||
|
22 | } | |||
17 |
|
23 | |||
18 | DataSourceItem* m_Parent; |
|
24 | DataSourceItem* m_Parent; | |
|
25 | std::optional<QUuid> m_dataSourceUid = std::nullopt; | |||
19 | std::vector<std::unique_ptr<DataSourceItem>> m_Children; |
|
26 | std::vector<std::unique_ptr<DataSourceItem>> m_Children; | |
|
27 | QString m_icon; | |||
|
28 | QString m_name; | |||
20 | DataSourceItemType m_Type; |
|
29 | DataSourceItemType m_Type; | |
21 | //TODO check if QVariant is really wise here, looks quite overkill |
|
30 | // TODO check if QVariant is really wise here, looks quite overkill | |
22 | // maybe a simple map<string,string> could be enough |
|
31 | // maybe a simple map<string,string> could be enough | |
23 | QVariantHash m_Data; |
|
32 | QVariantHash m_Data; | |
24 | std::vector<std::unique_ptr<DataSourceItemAction>> m_Actions; |
|
33 | std::vector<std::unique_ptr<DataSourceItemAction>> m_Actions; | |
25 | auto begin()noexcept{return m_Children.begin();} |
|
34 | auto begin() noexcept { return m_Children.begin(); } | |
26 | auto end()noexcept{return m_Children.end();} |
|
35 | auto end() noexcept { return m_Children.end(); } | |
27 | auto cbegin()const noexcept{return m_Children.cbegin();} |
|
36 | auto cbegin() const noexcept { return m_Children.cbegin(); } | |
28 | auto cend()const noexcept{return m_Children.cend();} |
|
37 | auto cend() const noexcept { return m_Children.cend(); } | |
29 |
|
38 | inline std::optional<QUuid> source_uuid() const noexcept | ||
|
39 | { | |||
|
40 | return m_dataSourceUid; | |||
|
41 | } | |||
30 | int index_of(const DataSourceItem* item) |
|
42 | int index_of(const DataSourceItem* item) | |
31 | { |
|
43 | { | |
32 |
|
|
44 | return std::distance(std::cbegin(m_Children), | |
33 | std::cbegin(m_Children), std::find_if(std::cbegin(m_Children), std::cend(m_Children), [item](const auto& other){return other.get()==item;})); |
|
45 | std::find_if(std::cbegin(m_Children), | |
|
46 | std::cend(m_Children), | |||
|
47 | [item](const auto& other) { | |||
|
48 | return other.get() == item; | |||
|
49 | })); | |||
34 | } |
|
50 | } | |
|
51 | inline QString name() const noexcept { return m_name; } | |||
|
52 | inline QString icon() const noexcept { return m_icon; } | |||
|
53 | inline void setIcon(const QString& iconName) { m_icon = iconName; } | |||
35 | }; |
|
54 | }; | |
36 |
|
55 | |||
37 | DataSourceItem::DataSourceItem(DataSourceItemType type, const QString& name) |
|
56 | // DataSourceItem::DataSourceItem(DataSourceItemType type, const QString& name) | |
38 | : DataSourceItem{type, QVariantHash{{NAME_DATA_KEY, name}}} |
|
57 | // : DataSourceItem{type,name, QVariantHash{{NAME_DATA_KEY, name}}} | |
39 | {} |
|
58 | //{} | |
40 |
|
59 | |||
41 |
DataSourceItem::DataSourceItem(DataSourceItemType type, |
|
60 | DataSourceItem::DataSourceItem(DataSourceItemType type, const QString& name, | |
42 | : impl{spimpl::make_unique_impl<DataSourceItemPrivate>(type, |
|
61 | QVariantHash data, | |
43 | std::move(data))} |
|
62 | std::optional<QUuid> sourceUUID) | |
|
63 | : impl{spimpl::make_unique_impl<DataSourceItemPrivate>( | |||
|
64 | type, name, std::move(data), sourceUUID)} | |||
44 | {} |
|
65 | {} | |
45 |
|
66 | |||
|
67 | // TODO remove this method ASAP | |||
46 | std::unique_ptr<DataSourceItem> DataSourceItem::clone() const |
|
68 | std::unique_ptr<DataSourceItem> DataSourceItem::clone() const | |
47 | { |
|
69 | { | |
48 |
auto result = std::make_unique<DataSourceItem>(impl->m_Type, impl->m_ |
|
70 | auto result = std::make_unique<DataSourceItem>(impl->m_Type, impl->m_name, | |
|
71 | impl->m_Data); | |||
49 |
|
72 | |||
50 | // Clones children |
|
73 | // Clones children | |
51 | for(const auto& child : impl->m_Children) |
|
74 | for(const auto& child : impl->m_Children) | |
@@ -117,9 +140,13 bool DataSourceItem::isRoot() const noexcept | |||||
117 | return impl->m_Parent == nullptr; |
|
140 | return impl->m_Parent == nullptr; | |
118 | } |
|
141 | } | |
119 |
|
142 | |||
120 | QString DataSourceItem::name() const noexcept |
|
143 | QString DataSourceItem::name() const noexcept { return impl->name(); } | |
|
144 | ||||
|
145 | QString DataSourceItem::icon() const noexcept { return impl->icon(); } | |||
|
146 | ||||
|
147 | void DataSourceItem::setIcon(const QString& iconName) | |||
121 | { |
|
148 | { | |
122 | return data(NAME_DATA_KEY).toString(); |
|
149 | impl->setIcon(iconName); | |
123 | } |
|
150 | } | |
124 |
|
151 | |||
125 | DataSourceItem* DataSourceItem::parentItem() const noexcept |
|
152 | DataSourceItem* DataSourceItem::parentItem() const noexcept | |
@@ -129,11 +156,9 DataSourceItem* DataSourceItem::parentItem() const noexcept | |||||
129 |
|
156 | |||
130 | int DataSourceItem::index() const noexcept |
|
157 | int DataSourceItem::index() const noexcept | |
131 | { |
|
158 | { | |
132 |
|
|
159 | if(auto parent = parentItem(); parent) | |
133 | { |
|
160 | { return parent->impl->index_of(this); } | |
134 | return parent->impl->index_of(this); |
|
161 | return 0; | |
135 | } |
|
|||
136 | return 0; |
|
|||
137 | } |
|
162 | } | |
138 |
|
163 | |||
139 | const DataSourceItem& DataSourceItem::rootItem() const noexcept |
|
164 | const DataSourceItem& DataSourceItem::rootItem() const noexcept | |
@@ -271,3 +296,8 DataSourceItem::const_iterator_type DataSourceItem::end() const noexcept | |||||
271 | { |
|
296 | { | |
272 | return impl->cend(); |
|
297 | return impl->cend(); | |
273 | } |
|
298 | } | |
|
299 | ||||
|
300 | std::optional<QUuid> DataSourceItem::source_uuid() const noexcept | |||
|
301 | { | |||
|
302 | return impl->source_uuid(); | |||
|
303 | } |
@@ -24,49 +24,109 | |||||
24 |
|
24 | |||
25 | #include "DataSource/datasources.h" |
|
25 | #include "DataSource/datasources.h" | |
26 |
|
26 | |||
|
27 | #include "Common/MimeTypesDef.h" | |||
|
28 | #include "DataSource/DataSourceItemAction.h" | |||
|
29 | #include "containers/algorithms.hpp" | |||
|
30 | ||||
|
31 | #include <QDataStream> | |||
|
32 | ||||
|
33 | QString QVariant2QString(const QVariant& variant) noexcept | |||
|
34 | { | |||
|
35 | if(variant.canConvert<QVariantList>()) | |||
|
36 | { | |||
|
37 | auto valueString = QStringLiteral("{"); | |||
|
38 | auto variantList = variant.value<QVariantList>(); | |||
|
39 | QStringList items; | |||
|
40 | std::transform(std::cbegin(variantList), std::cend(variantList), | |||
|
41 | std::back_inserter(items), | |||
|
42 | [](const auto& item) { return QVariant2QString(item); }); | |||
|
43 | valueString.append(cpp_utils::containers::join(items, ", ")); | |||
|
44 | valueString.append("}"); | |||
|
45 | return valueString; | |||
|
46 | } | |||
|
47 | else | |||
|
48 | { | |||
|
49 | return variant.toString(); | |||
|
50 | } | |||
|
51 | } | |||
|
52 | ||||
27 | inline std::unique_ptr<DataSourceItem> make_folder_item(const QString& name) |
|
53 | inline std::unique_ptr<DataSourceItem> make_folder_item(const QString& name) | |
28 | { |
|
54 | { | |
29 | return std::make_unique<DataSourceItem>(DataSourceItemType::NODE, name); |
|
55 | return std::make_unique<DataSourceItem>(DataSourceItemType::NODE, name); | |
30 | } |
|
56 | } | |
31 |
|
57 | |||
32 | template<typename T> |
|
58 | template<typename T> | |
33 | DataSourceItem* make_path_items(const T& path_list_begin, |
|
59 | DataSourceItem* walk_tree( | |
34 |
|
|
60 | const T& path_list_begin, const T& path_list_end, DataSourceItem* root, | |
|
61 | const std::function<DataSourceItem*(DataSourceItem*, DataSourceItem*, | |||
|
62 | const decltype(*std::declval<T>())&)>& | |||
|
63 | f = [](DataSourceItem* parent, DataSourceItem* node, | |||
|
64 | const auto& name) -> DataSourceItem* { | |||
|
65 | (void)parent; | |||
|
66 | (void)name; | |||
|
67 | return node; | |||
|
68 | }) | |||
35 | { |
|
69 | { | |
36 | std::for_each(path_list_begin, path_list_end, |
|
70 | std::for_each(path_list_begin, path_list_end, | |
37 | [&root](const auto& folder_name) mutable { |
|
71 | [&root, &f](const auto& folder_name) mutable { | |
38 | auto folder_ptr = root->findItem(folder_name); |
|
72 | auto folder_ptr = root->findItem(folder_name); | |
39 | if(folder_ptr == nullptr) |
|
73 | root = f(root, folder_ptr, folder_name); | |
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 | }); |
|
74 | }); | |
47 | return root; |
|
75 | return root; | |
48 | } |
|
76 | } | |
49 |
|
77 | |||
|
78 | DataSourceItem* walk_tree( | |||
|
79 | const QString& path, DataSourceItem* root, | |||
|
80 | const std::function<DataSourceItem*(DataSourceItem*, DataSourceItem*, | |||
|
81 | const QString&)>& f = | |||
|
82 | [](DataSourceItem* parent, DataSourceItem* node, | |||
|
83 | const auto& name) -> DataSourceItem* { | |||
|
84 | (void)parent; | |||
|
85 | (void)name; | |||
|
86 | return node; | |||
|
87 | }) | |||
|
88 | { | |||
|
89 | auto path_list = path.split('/', QString::SkipEmptyParts); | |||
|
90 | return walk_tree(std::cbegin(path_list), std::cend(path_list), root, f); | |||
|
91 | } | |||
|
92 | ||||
|
93 | template<typename T> | |||
|
94 | DataSourceItem* make_path_items(const T& path_list_begin, | |||
|
95 | const T& path_list_end, DataSourceItem* root) | |||
|
96 | { | |||
|
97 | auto node_ctor = [](DataSourceItem* parent, DataSourceItem* node, | |||
|
98 | const auto& name) -> DataSourceItem* { | |||
|
99 | if(node == nullptr) | |||
|
100 | { | |||
|
101 | auto folder = make_folder_item(name); | |||
|
102 | node = folder.get(); | |||
|
103 | parent->appendChild(std::move(folder)); | |||
|
104 | } | |||
|
105 | return node; | |||
|
106 | }; | |||
|
107 | return walk_tree(path_list_begin, path_list_end, root, node_ctor); | |||
|
108 | } | |||
|
109 | ||||
50 | inline std::unique_ptr<DataSourceItem> |
|
110 | inline std::unique_ptr<DataSourceItem> | |
51 |
make_product_item(const QVariantHash& metaData, |
|
111 | make_product_item(const QString& name, QVariantHash& metaData, | |
52 |
const QString& DATA_SOURCE_NAME, |
|
112 | const QUuid& dataSourceUid, const QString& DATA_SOURCE_NAME, | |
|
113 | DataSources* dataSources) | |||
53 | { |
|
114 | { | |
54 | auto result = |
|
115 | auto result = std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT, | |
55 | std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT, metaData); |
|
116 | name, metaData, dataSourceUid); | |
56 |
|
117 | |||
57 | // Adds plugin name to product metadata |
|
118 | // Adds plugin name to product metadata | |
|
119 | // TODO re-consider adding a name attribute to DataSourceItem class | |||
58 | result->setData(DataSourceItem::PLUGIN_DATA_KEY, DATA_SOURCE_NAME); |
|
120 | result->setData(DataSourceItem::PLUGIN_DATA_KEY, DATA_SOURCE_NAME); | |
59 | result->setData(DataSourceItem::ID_DATA_KEY, |
|
121 | // result->setData(DataSourceItem::ID_DATA_KEY, | |
60 | metaData.value(DataSourceItem::NAME_DATA_KEY)); |
|
122 | // metaData.value(DataSourceItem::NAME_DATA_KEY)); | |
61 |
|
||||
62 | auto productName = metaData.value(DataSourceItem::NAME_DATA_KEY).toString(); |
|
|||
63 |
|
123 | |||
64 |
// Add action to load product from DataSource |
|
124 | // Add action to load product from DataSources | |
65 |
|
|
125 | result->addAction(std::make_unique<DataSourceItemAction>( | |
66 |
|
|
126 | QObject::tr("Load %1 product").arg(name), | |
67 |
|
|
127 | [dataSources](DataSourceItem& item) { | |
68 | // if(dc) { dc->loadProductItem(dataSourceUid, item); } |
|
128 | if(dataSources) { dataSources->createVariable(item); } | |
69 |
|
|
129 | })); | |
70 |
|
130 | |||
71 | return result; |
|
131 | return result; | |
72 | } |
|
132 | } | |
@@ -74,15 +134,51 make_product_item(const QVariantHash& metaData, const QUuid& dataSourceUid, | |||||
74 | QVariant DataSources::data(const QModelIndex& index, int role) const |
|
134 | QVariant DataSources::data(const QModelIndex& index, int role) const | |
75 | { |
|
135 | { | |
76 | if(!index.isValid()) return QVariant(); |
|
136 | if(!index.isValid()) return QVariant(); | |
77 | if(role != Qt::DisplayRole) return QVariant(); |
|
|||
78 | DataSourceItem* item = static_cast<DataSourceItem*>(index.internalPointer()); |
|
137 | DataSourceItem* item = static_cast<DataSourceItem*>(index.internalPointer()); | |
79 | return item->name(); |
|
138 | if(role == Qt::DisplayRole) { return item->name(); } | |
|
139 | if(role == Qt::DecorationRole) | |||
|
140 | { return _icons.value(item->icon(), QVariant{}); } | |||
|
141 | if(role == Qt::ToolTipRole) | |||
|
142 | { | |||
|
143 | auto result = QString{}; | |||
|
144 | const auto& data = item->data(); | |||
|
145 | std::for_each(data.constKeyValueBegin(), data.constKeyValueEnd(), | |||
|
146 | [&result](const auto& item) { | |||
|
147 | result.append(QString{"<b>%1:</b> %2<br/>"}.arg( | |||
|
148 | item.first, QVariant2QString(item.second))); | |||
|
149 | }); | |||
|
150 | return result; | |||
|
151 | } | |||
|
152 | return QVariant(); | |||
|
153 | } | |||
|
154 | ||||
|
155 | QMimeData* DataSources::mimeData(const QModelIndexList& indexes) const | |||
|
156 | { | |||
|
157 | QVariantList productData; | |||
|
158 | std::for_each(std::cbegin(indexes), std::cend(indexes), | |||
|
159 | [&productData](const auto& index) { | |||
|
160 | if(index.isValid()) | |||
|
161 | { | |||
|
162 | DataSourceItem* item = | |||
|
163 | static_cast<DataSourceItem*>(index.internalPointer()); | |||
|
164 | if(item->isProductOrComponent()) | |||
|
165 | { productData.append(item->data()); } | |||
|
166 | } | |||
|
167 | }); | |||
|
168 | // TODO refactor this later | |||
|
169 | // maybe just an encode function | |||
|
170 | QByteArray encodedData; | |||
|
171 | QDataStream stream{&encodedData, QIODevice::WriteOnly}; | |||
|
172 | stream << productData; | |||
|
173 | auto mimeData = new QMimeData; | |||
|
174 | mimeData->setData(MIME_TYPE_PRODUCT_LIST, encodedData); | |||
|
175 | return mimeData; | |||
80 | } |
|
176 | } | |
81 |
|
177 | |||
82 | int DataSources::columnCount(const QModelIndex& parent) const |
|
178 | int DataSources::columnCount(const QModelIndex& parent) const | |
83 | { |
|
179 | { | |
84 | (void)parent; |
|
180 | (void)parent; | |
85 |
return |
|
181 | return 1; | |
86 | } |
|
182 | } | |
87 |
|
183 | |||
88 | int DataSources::rowCount(const QModelIndex& parent) const |
|
184 | int DataSources::rowCount(const QModelIndex& parent) const | |
@@ -120,10 +216,28 QModelIndex DataSources::index(int row, int column, | |||||
120 | return QModelIndex(); |
|
216 | return QModelIndex(); | |
121 | } |
|
217 | } | |
122 |
|
218 | |||
|
219 | Qt::ItemFlags DataSources::flags(const QModelIndex& index) const | |||
|
220 | { | |||
|
221 | Qt::ItemFlags flags = Qt::NoItemFlags; | |||
|
222 | if(index.isValid()) | |||
|
223 | { | |||
|
224 | flags |= Qt::ItemIsSelectable | Qt::ItemIsEnabled; | |||
|
225 | DataSourceItem* item = | |||
|
226 | static_cast<DataSourceItem*>(index.internalPointer()); | |||
|
227 | if(item && item->isProductOrComponent()) | |||
|
228 | { flags |= Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; } | |||
|
229 | } | |||
|
230 | return flags; | |||
|
231 | } | |||
|
232 | ||||
|
233 | // TODO This can be optimized to only use insert row and column | |||
|
234 | // this should be much faster than doing a ResetModel all the time | |||
|
235 | // but this is more difficult to implement | |||
123 | void DataSources::addDataSourceItem( |
|
236 | void DataSources::addDataSourceItem( | |
124 | const QUuid& providerUid, const QString& path, |
|
237 | const QUuid& providerUid, const QString& path, | |
125 | const QMap<QString, QString>& metaData) noexcept |
|
238 | const QMap<QString, QString>& metaData) noexcept | |
126 | { |
|
239 | { | |
|
240 | beginResetModel(); | |||
127 | auto path_list = path.split('/', QString::SkipEmptyParts); |
|
241 | auto path_list = path.split('/', QString::SkipEmptyParts); | |
128 | auto name = *(std::cend(path_list) - 1); |
|
242 | auto name = *(std::cend(path_list) - 1); | |
129 | auto path_item = |
|
243 | auto path_item = | |
@@ -134,7 +248,8 void DataSources::addDataSourceItem( | |||||
134 | meta_data[key] = metaData[key]; |
|
248 | meta_data[key] = metaData[key]; | |
135 | } |
|
249 | } | |
136 | path_item->appendChild( |
|
250 | path_item->appendChild( | |
137 | make_product_item(meta_data, providerUid, "test", this)); |
|
251 | make_product_item(name, meta_data, providerUid, "test", this)); | |
|
252 | endResetModel(); | |||
138 | } |
|
253 | } | |
139 |
|
254 | |||
140 | void DataSources::addProvider(IDataProvider* provider) noexcept |
|
255 | void DataSources::addProvider(IDataProvider* provider) noexcept | |
@@ -142,3 +257,32 void DataSources::addProvider(IDataProvider* provider) noexcept | |||||
142 | _DataProviders.insert( |
|
257 | _DataProviders.insert( | |
143 | {provider->id(), std::unique_ptr<IDataProvider>{provider}}); |
|
258 | {provider->id(), std::unique_ptr<IDataProvider>{provider}}); | |
144 | } |
|
259 | } | |
|
260 | ||||
|
261 | void DataSources::updateNodeMetaData( | |||
|
262 | const QString& path, const QMap<QString, QString>& metaData) noexcept | |||
|
263 | { | |||
|
264 | auto node = walk_tree(path, _root); | |||
|
265 | if(node != nullptr) | |||
|
266 | { | |||
|
267 | std::for_each( | |||
|
268 | metaData.constKeyValueBegin(), metaData.constKeyValueEnd(), | |||
|
269 | [node](const auto& it) { node->setData(it.first, it.second, true); }); | |||
|
270 | } | |||
|
271 | } | |||
|
272 | ||||
|
273 | void DataSources::createVariable(const DataSourceItem& item) | |||
|
274 | { | |||
|
275 | if(auto ds_uuid = item.source_uuid(); | |||
|
276 | ds_uuid.has_value() && item.isProductOrComponent()) | |||
|
277 | { | |||
|
278 | if(auto data_source_it = _DataProviders.find(ds_uuid.value()); | |||
|
279 | data_source_it != std::cend(_DataProviders)) | |||
|
280 | emit createVariable(item.name(), item.data(), data_source_it->second); | |||
|
281 | } | |||
|
282 | } | |||
|
283 | ||||
|
284 | void DataSources::setIcon(const QString& path, const QString& iconName) | |||
|
285 | { | |||
|
286 | auto node = walk_tree(path, _root); | |||
|
287 | if(node != nullptr) { node->setIcon(iconName); } | |||
|
288 | } |
@@ -30,7 +30,7 private slots: | |||||
30 | QTest::addColumn<QDateTime>("tend"); |
|
30 | QTest::addColumn<QDateTime>("tend"); | |
31 | QTest::addColumn<double>("expected"); |
|
31 | QTest::addColumn<double>("expected"); | |
32 | auto now = QDateTime::currentDateTime(); |
|
32 | auto now = QDateTime::currentDateTime(); | |
33 |
auto yesterday = |
|
33 | auto yesterday = now.addDays(-1); | |
34 | QTest::newRow("No delta") << now << now << 0.; |
|
34 | QTest::newRow("No delta") << now << now << 0.; | |
35 | QTest::newRow("One day delta") << yesterday << now << 60. * 60. * 24.; |
|
35 | QTest::newRow("One day delta") << yesterday << now << 60. * 60. * 24.; | |
36 | QTest::newRow("Minus one day delta") |
|
36 | QTest::newRow("Minus one day delta") | |
@@ -103,6 +103,7 private slots: | |||||
103 | QTest::newRow("Zoom OUT 0.001") |
|
103 | QTest::newRow("Zoom OUT 0.001") | |
104 | << range << 0.999 << computeZoom(yestd, now, 0.999); |
|
104 | << range << 0.999 << computeZoom(yestd, now, 0.999); | |
105 | } |
|
105 | } | |
|
106 | ||||
106 | void testRangeZoom() |
|
107 | void testRangeZoom() | |
107 | { |
|
108 | { | |
108 | QFETCH(DateTimeRange, initial); |
|
109 | QFETCH(DateTimeRange, initial); | |
@@ -196,6 +197,7 private slots: | |||||
196 | << range << range * 0.9 + Seconds<double>{-10.} |
|
197 | << range << range * 0.9 + Seconds<double>{-10.} | |
197 | << DateTimeRangeTransformation{0.9, Seconds<double>{-10.}}; |
|
198 | << DateTimeRangeTransformation{0.9, Seconds<double>{-10.}}; | |
198 | } |
|
199 | } | |
|
200 | ||||
199 | void testRangeTransformations() |
|
201 | void testRangeTransformations() | |
200 | { |
|
202 | { | |
201 | QFETCH(DateTimeRange, range1); |
|
203 | QFETCH(DateTimeRange, range1); |
@@ -9,7 +9,7 DataSourceItemBuilder &DataSourceItemBuilder::root(const QString &name) | |||||
9 |
|
9 | |||
10 | DataSourceItemBuilder &DataSourceItemBuilder::root(QVariantHash data) |
|
10 | DataSourceItemBuilder &DataSourceItemBuilder::root(QVariantHash data) | |
11 | { |
|
11 | { | |
12 | m_Root = std::make_shared<DataSourceItem>(DataSourceItemType::NODE, data); |
|
12 | m_Root = std::make_shared<DataSourceItem>(DataSourceItemType::NODE,data[DataSourceItem::NAME_DATA_KEY].toString(), data); | |
13 | m_Items.push(m_Root.get()); |
|
13 | m_Items.push(m_Root.get()); | |
14 | return *this; |
|
14 | return *this; | |
15 | } |
|
15 | } | |
@@ -21,7 +21,7 DataSourceItemBuilder &DataSourceItemBuilder::node(const QString &name) | |||||
21 |
|
21 | |||
22 | DataSourceItemBuilder &DataSourceItemBuilder::node(QVariantHash data) |
|
22 | DataSourceItemBuilder &DataSourceItemBuilder::node(QVariantHash data) | |
23 | { |
|
23 | { | |
24 | return append(DataSourceItemType::NODE, std::move(data)); |
|
24 | return append(DataSourceItemType::NODE,data[DataSourceItem::NAME_DATA_KEY].toString(), std::move(data)); | |
25 | } |
|
25 | } | |
26 |
|
26 | |||
27 | DataSourceItemBuilder &DataSourceItemBuilder::product(const QString &name) |
|
27 | DataSourceItemBuilder &DataSourceItemBuilder::product(const QString &name) | |
@@ -31,7 +31,7 DataSourceItemBuilder &DataSourceItemBuilder::product(const QString &name) | |||||
31 |
|
31 | |||
32 | DataSourceItemBuilder &DataSourceItemBuilder::product(QVariantHash data) |
|
32 | DataSourceItemBuilder &DataSourceItemBuilder::product(QVariantHash data) | |
33 | { |
|
33 | { | |
34 | return append(DataSourceItemType::PRODUCT, std::move(data)); |
|
34 | return append(DataSourceItemType::PRODUCT,data[DataSourceItem::NAME_DATA_KEY].toString(), std::move(data)); | |
35 | } |
|
35 | } | |
36 |
|
36 | |||
37 | DataSourceItemBuilder &DataSourceItemBuilder::component(const QString &name) |
|
37 | DataSourceItemBuilder &DataSourceItemBuilder::component(const QString &name) | |
@@ -41,7 +41,7 DataSourceItemBuilder &DataSourceItemBuilder::component(const QString &name) | |||||
41 |
|
41 | |||
42 | DataSourceItemBuilder &DataSourceItemBuilder::component(QVariantHash data) |
|
42 | DataSourceItemBuilder &DataSourceItemBuilder::component(QVariantHash data) | |
43 | { |
|
43 | { | |
44 | return append(DataSourceItemType::COMPONENT, std::move(data)); |
|
44 | return append(DataSourceItemType::COMPONENT,data[DataSourceItem::NAME_DATA_KEY].toString(), std::move(data)); | |
45 | } |
|
45 | } | |
46 |
|
46 | |||
47 | DataSourceItemBuilder &DataSourceItemBuilder::end() |
|
47 | DataSourceItemBuilder &DataSourceItemBuilder::end() | |
@@ -57,16 +57,16 std::shared_ptr<DataSourceItem> DataSourceItemBuilder::build() | |||||
57 |
|
57 | |||
58 | DataSourceItemBuilder &DataSourceItemBuilder::append(DataSourceItemType type, const QString &name) |
|
58 | DataSourceItemBuilder &DataSourceItemBuilder::append(DataSourceItemType type, const QString &name) | |
59 | { |
|
59 | { | |
60 | append(type, QVariantHash{{DataSourceItem::NAME_DATA_KEY, name}}); |
|
60 | append(type,name, QVariantHash{{DataSourceItem::NAME_DATA_KEY, name}}); | |
61 | return *this; |
|
61 | return *this; | |
62 | } |
|
62 | } | |
63 |
|
63 | |||
64 | DataSourceItemBuilder &DataSourceItemBuilder::append(DataSourceItemType type, QVariantHash data) |
|
64 | DataSourceItemBuilder &DataSourceItemBuilder::append(DataSourceItemType type, const QString &name, QVariantHash data) | |
65 | { |
|
65 | { | |
66 | auto parentItem = m_Items.top(); |
|
66 | auto parentItem = m_Items.top(); | |
67 |
|
67 | |||
68 | auto insertIndex = parentItem->childCount(); |
|
68 | auto insertIndex = parentItem->childCount(); | |
69 | parentItem->appendChild(std::make_unique<DataSourceItem>(type, std::move(data))); |
|
69 | parentItem->appendChild(std::make_unique<DataSourceItem>(type,name, std::move(data))); | |
70 |
|
70 | |||
71 | m_Items.push(parentItem->child(insertIndex)); |
|
71 | m_Items.push(parentItem->child(insertIndex)); | |
72 | return *this; |
|
72 | return *this; |
@@ -36,7 +36,7 public: | |||||
36 |
|
36 | |||
37 | private: |
|
37 | private: | |
38 | DataSourceItemBuilder& append(DataSourceItemType type, const QString &name); |
|
38 | DataSourceItemBuilder& append(DataSourceItemType type, const QString &name); | |
39 | DataSourceItemBuilder& append(DataSourceItemType type, QVariantHash data); |
|
39 | DataSourceItemBuilder& append(DataSourceItemType type,const QString &name, QVariantHash data); | |
40 |
|
40 | |||
41 | std::shared_ptr<DataSourceItem> m_Root{nullptr}; |
|
41 | std::shared_ptr<DataSourceItem> m_Root{nullptr}; | |
42 | std::stack<DataSourceItem*> m_Items; |
|
42 | std::stack<DataSourceItem*> m_Items; |
@@ -5,7 +5,7 | |||||
5 | #include <QtTest> |
|
5 | #include <QtTest> | |
6 |
|
6 | |||
7 | #include <memory> |
|
7 | #include <memory> | |
8 |
|
8 | //TODO remove this | ||
9 | class TestDataSourceController : public QObject { |
|
9 | class TestDataSourceController : public QObject { | |
10 | Q_OBJECT |
|
10 | Q_OBJECT | |
11 | private slots: |
|
11 | private slots: | |
@@ -39,10 +39,10 void TestDataSourceController::testSetDataSourceItem() | |||||
39 | QCOMPARE(signalSpy.count(), 1); |
|
39 | QCOMPARE(signalSpy.count(), 1); | |
40 |
|
40 | |||
41 | // Try to a data source item with an unregistered uid and check that no signal has been emitted |
|
41 | // Try to a data source item with an unregistered uid and check that no signal has been emitted | |
42 | auto unregisteredUid = QUuid::createUuid(); |
|
42 | //auto unregisteredUid = QUuid::createUuid(); | |
43 | dataSourceController.setDataSourceItem( |
|
43 | ///dataSourceController.setDataSourceItem( | |
44 | unregisteredUid, std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT)); |
|
44 | // unregisteredUid, std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT)); | |
45 | QCOMPARE(signalSpy.count(), 1); |
|
45 | //QCOMPARE(signalSpy.count(), 1); | |
46 | } |
|
46 | } | |
47 |
|
47 | |||
48 | QTEST_MAIN(TestDataSourceController) |
|
48 | QTEST_MAIN(TestDataSourceController) |
@@ -3,6 +3,7 | |||||
3 |
|
3 | |||
4 | #include <QObject> |
|
4 | #include <QObject> | |
5 | #include <QtTest> |
|
5 | #include <QtTest> | |
|
6 | #include "TestProviders.h" | |||
6 |
|
7 | |||
7 | class TestDataSources : public QObject { |
|
8 | class TestDataSources : public QObject { | |
8 | Q_OBJECT |
|
9 | Q_OBJECT | |
@@ -12,7 +13,15 private slots: | |||||
12 |
|
13 | |||
13 | void TestDataSources::addItems() |
|
14 | void TestDataSources::addItems() | |
14 | { |
|
15 | { | |
|
16 | SimpleRange<1>* provider = new SimpleRange<1>{}; | |||
15 | DataSources ds; |
|
17 | DataSources ds; | |
|
18 | ds.addProvider(provider); | |||
|
19 | ds.addDataSourceItem(provider->id(),"/test/node1",{}); | |||
|
20 | ds.addDataSourceItem(provider->id(),"/test/node2",{}); | |||
|
21 | ds.addDataSourceItem(provider->id(),"/test/node3",{}); | |||
|
22 | ds.addDataSourceItem(provider->id(),"/test/node4",{}); | |||
|
23 | auto rc = ds.rowCount(ds.index(0,0,QModelIndex())); | |||
|
24 | QVERIFY(rc==4); | |||
16 | } |
|
25 | } | |
17 |
|
26 | |||
18 | QTEST_MAIN(TestDataSources) |
|
27 | QTEST_MAIN(TestDataSources) |
@@ -7,8 +7,6 TestUtils_dep = declare_dependency(link_with : TestUtils, | |||||
7 | include_directories: include_directories('TestUtils'), |
|
7 | include_directories: include_directories('TestUtils'), | |
8 | dependencies : [sciqlop_core, qt5test]) |
|
8 | dependencies : [sciqlop_core, qt5test]) | |
9 |
|
9 | |||
10 |
|
||||
11 |
|
||||
12 | tests = [ |
|
10 | tests = [ | |
13 | { |
|
11 | { | |
14 | 'name':'TestSyncGroup', |
|
12 | 'name':'TestSyncGroup', | |
@@ -85,3 +83,5 foreach unit_test : tests | |||||
85 |
|
83 | |||
86 | endforeach |
|
84 | endforeach | |
87 |
|
85 | |||
|
86 | datasources_manual_test_exe = executable('datasources_manual_test', 'DataSource/DataSourcesManualTest.cpp', dependencies :[sciqlop_core, | |||
|
87 | TestUtils_dep, qt5gui, qt5widgets]) |
General Comments 0
You need to be logged in to leave comments.
Login now