##// END OF EJS Templates
New DataSources model class ready for integration...
jeandet -
r98:b081849458c2
parent child
Show More
@@ -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 class DataSourceItemPrivate;
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 override;
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 override;
51 virtual int columnCount(const QModelIndex& parent) const final;
50
52
51 virtual int rowCount(const QModelIndex& parent) const override;
53 virtual int rowCount(const QModelIndex& parent) const final;
52
54
53 QModelIndex parent(const QModelIndex& index) const override;
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 override;
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 std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT, metaData);
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 // Add action to load product from DataSourceController
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, QVariantHash data)
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 return std::distance(
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, QVariantHash data)
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_Data);
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 if(auto parent = parentItem(); parent)
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 const T& path_list_end, DataSourceItem* root)
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, const QUuid& dataSourceUid,
111 make_product_item(const QString& name, QVariantHash& metaData,
52 const QString& DATA_SOURCE_NAME, DataSources* dc)
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 DataSourceController
124 // Add action to load product from DataSources
65 // result->addAction(std::make_unique<DataSourceItemAction>(
125 result->addAction(std::make_unique<DataSourceItemAction>(
66 // QObject::tr("Load %1 product").arg(productName),
126 QObject::tr("Load %1 product").arg(name),
67 // [productName, dataSourceUid, dc](DataSourceItem& item) {
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 0;
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 = QDateTime::currentDateTime().addDays(-1);
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