##// END OF EJS Templates
Merge branch 'feature/DataSourceItemUpdate' into develop
Alexandre Leroux -
r362:7becb422304c merge
parent child
Show More
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
@@ -11,7 +11,7 class DataSourceItemAction;
11 /**
11 /**
12 * Possible types of an item
12 * Possible types of an item
13 */
13 */
14 enum class DataSourceItemType { NODE, PRODUCT };
14 enum class DataSourceItemType { NODE, PRODUCT, COMPONENT };
15
15
16 /**
16 /**
17 * @brief The DataSourceItem class aims to represent a structure element of a data source.
17 * @brief The DataSourceItem class aims to represent a structure element of a data source.
@@ -21,7 +21,11 enum class DataSourceItemType { NODE, PRODUCT };
21 */
21 */
22 class DataSourceItem {
22 class DataSourceItem {
23 public:
23 public:
24 explicit DataSourceItem(DataSourceItemType type, QVector<QVariant> data = {});
24 /// Key associated with the name of the item
25 static const QString NAME_DATA_KEY;
26
27 explicit DataSourceItem(DataSourceItemType type, const QString &name);
28 explicit DataSourceItem(DataSourceItemType type, QHash<QString, QVariant> data = {});
25
29
26 /// @return the actions of the item as a vector
30 /// @return the actions of the item as a vector
27 QVector<DataSourceItemAction *> actions() const noexcept;
31 QVector<DataSourceItemAction *> actions() const noexcept;
@@ -49,11 +53,16 public:
49 int childCount() const noexcept;
53 int childCount() const noexcept;
50
54
51 /**
55 /**
52 * Get the data associated to an index
56 * Get the data associated to a key
53 * @param dataIndex the index to search
57 * @param key the key to search
54 * @return the data found if index is valid, default QVariant otherwise
58 * @return the data found if key is valid, default QVariant otherwise
55 */
59 */
56 QVariant data(int dataIndex) const noexcept;
60 QVariant data(const QString &key) const noexcept;
61
62 /// Gets all data
63 const QHash<QString, QVariant> &data() const noexcept;
64
65 bool isRoot() const noexcept;
57
66
58 QString name() const noexcept;
67 QString name() const noexcept;
59
68
@@ -63,8 +72,20 public:
63 */
72 */
64 DataSourceItem *parentItem() const noexcept;
73 DataSourceItem *parentItem() const noexcept;
65
74
75 /**
76 * Sets or appends a value to a key
77 * @param key the key
78 * @param value the value
79 * @param append if true, the value is added to the values already existing for the key,
80 * otherwise it replaces the existing values
81 */
82 void setData(const QString &key, const QVariant &value, bool append = false) noexcept;
83
66 DataSourceItemType type() const noexcept;
84 DataSourceItemType type() const noexcept;
67
85
86 bool operator==(const DataSourceItem &other);
87 bool operator!=(const DataSourceItem &other);
88
68 private:
89 private:
69 class DataSourceItemPrivate;
90 class DataSourceItemPrivate;
70 spimpl::unique_impl_ptr<DataSourceItemPrivate> impl;
91 spimpl::unique_impl_ptr<DataSourceItemPrivate> impl;
@@ -3,15 +3,10
3
3
4 #include <QVector>
4 #include <QVector>
5
5
6 namespace {
6 const QString DataSourceItem::NAME_DATA_KEY = QStringLiteral("name");
7
8 /// Index of the 'name' value in the item
9 const auto NAME_INDEX = 0;
10
11 } // namespace
12
7
13 struct DataSourceItem::DataSourceItemPrivate {
8 struct DataSourceItem::DataSourceItemPrivate {
14 explicit DataSourceItemPrivate(DataSourceItemType type, QVector<QVariant> data)
9 explicit DataSourceItemPrivate(DataSourceItemType type, QHash<QString, QVariant> data)
15 : m_Parent{nullptr}, m_Children{}, m_Type{type}, m_Data{std::move(data)}, m_Actions{}
10 : m_Parent{nullptr}, m_Children{}, m_Type{type}, m_Data{std::move(data)}, m_Actions{}
16 {
11 {
17 }
12 }
@@ -19,11 +14,16 struct DataSourceItem::DataSourceItemPrivate {
19 DataSourceItem *m_Parent;
14 DataSourceItem *m_Parent;
20 std::vector<std::unique_ptr<DataSourceItem> > m_Children;
15 std::vector<std::unique_ptr<DataSourceItem> > m_Children;
21 DataSourceItemType m_Type;
16 DataSourceItemType m_Type;
22 QVector<QVariant> m_Data;
17 QHash<QString, QVariant> m_Data;
23 std::vector<std::unique_ptr<DataSourceItemAction> > m_Actions;
18 std::vector<std::unique_ptr<DataSourceItemAction> > m_Actions;
24 };
19 };
25
20
26 DataSourceItem::DataSourceItem(DataSourceItemType type, QVector<QVariant> data)
21 DataSourceItem::DataSourceItem(DataSourceItemType type, const QString &name)
22 : DataSourceItem{type, QHash<QString, QVariant>{{NAME_DATA_KEY, name}}}
23 {
24 }
25
26 DataSourceItem::DataSourceItem(DataSourceItemType type, QHash<QString, QVariant> data)
27 : impl{spimpl::make_unique_impl<DataSourceItemPrivate>(type, std::move(data))}
27 : impl{spimpl::make_unique_impl<DataSourceItemPrivate>(type, std::move(data))}
28 {
28 {
29 }
29 }
@@ -65,14 +65,24 int DataSourceItem::childCount() const noexcept
65 return impl->m_Children.size();
65 return impl->m_Children.size();
66 }
66 }
67
67
68 QVariant DataSourceItem::data(int dataIndex) const noexcept
68 QVariant DataSourceItem::data(const QString &key) const noexcept
69 {
70 return impl->m_Data.value(key);
71 }
72
73 const QHash<QString, QVariant> &DataSourceItem::data() const noexcept
69 {
74 {
70 return impl->m_Data.value(dataIndex);
75 return impl->m_Data;
76 }
77
78 bool DataSourceItem::isRoot() const noexcept
79 {
80 return impl->m_Parent == nullptr;
71 }
81 }
72
82
73 QString DataSourceItem::name() const noexcept
83 QString DataSourceItem::name() const noexcept
74 {
84 {
75 return data(NAME_INDEX).toString();
85 return data(NAME_DATA_KEY).toString();
76 }
86 }
77
87
78 DataSourceItem *DataSourceItem::parentItem() const noexcept
88 DataSourceItem *DataSourceItem::parentItem() const noexcept
@@ -80,7 +90,51 DataSourceItem *DataSourceItem::parentItem() const noexcept
80 return impl->m_Parent;
90 return impl->m_Parent;
81 }
91 }
82
92
93 void DataSourceItem::setData(const QString &key, const QVariant &value, bool append) noexcept
94 {
95 auto it = impl->m_Data.constFind(key);
96 if (append && it != impl->m_Data.constEnd()) {
97 // Case of an existing value to which we want to add to the new value
98 if (it->canConvert<QVariantList>()) {
99 auto variantList = it->value<QVariantList>();
100 variantList.append(value);
101
102 impl->m_Data.insert(key, variantList);
103 }
104 else {
105 impl->m_Data.insert(key, QVariantList{*it, value});
106 }
107 }
108 else {
109 // Other cases :
110 // - new value in map OR
111 // - replacement of an existing value (not appending)
112 impl->m_Data.insert(key, value);
113 }
114 }
115
83 DataSourceItemType DataSourceItem::type() const noexcept
116 DataSourceItemType DataSourceItem::type() const noexcept
84 {
117 {
85 return impl->m_Type;
118 return impl->m_Type;
86 }
119 }
120
121 bool DataSourceItem::operator==(const DataSourceItem &other)
122 {
123 // Compares items' attributes
124 if (std::tie(impl->m_Type, impl->m_Data) == std::tie(other.impl->m_Type, other.impl->m_Data)) {
125 // Compares contents of items' children
126 return std::equal(std::cbegin(impl->m_Children), std::cend(impl->m_Children),
127 std::cbegin(other.impl->m_Children),
128 [](const auto &itemChild, const auto &otherChild) {
129 return *itemChild == *otherChild;
130 });
131 }
132 else {
133 return false;
134 }
135 }
136
137 bool DataSourceItem::operator!=(const DataSourceItem &other)
138 {
139 return !(*this == other);
140 }
@@ -30,9 +30,7 void TestDataSourceController::testSetDataSourceItem()
30
30
31 // Create a data source item
31 // Create a data source item
32 auto source1Name = QStringLiteral("Source1");
32 auto source1Name = QStringLiteral("Source1");
33 auto source1Values = QVector<QVariant>{source1Name};
33 auto source1Item = std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT, source1Name);
34 auto source1Item
35 = std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT, std::move(source1Values));
36
34
37 // Add data source item to the controller and check that a signal has been emitted after setting
35 // Add data source item to the controller and check that a signal has been emitted after setting
38 // data source item in the controller
36 // data source item in the controller
@@ -1,5 +1,9
1 <RCC>
1 <RCC>
2 <qresource prefix="/">
2 <qresource prefix="/">
3 <file>icones/dataSourceComponent.png</file>
4 <file>icones/dataSourceNode.png</file>
5 <file>icones/dataSourceProduct.png</file>
6 <file>icones/dataSourceRoot.png</file>
3 <file>icones/delete.png</file>
7 <file>icones/delete.png</file>
4 <file>icones/openInspector.png</file>
8 <file>icones/openInspector.png</file>
5 <file>icones/next.png</file>
9 <file>icones/next.png</file>
@@ -2,23 +2,28
2 #include <DataSource/DataSourceItemAction.h>
2 #include <DataSource/DataSourceItemAction.h>
3 #include <DataSource/DataSourceTreeWidgetItem.h>
3 #include <DataSource/DataSourceTreeWidgetItem.h>
4
4
5 #include <SqpApplication.h>
6
7 #include <QAction>
5 #include <QAction>
8
6
9 Q_LOGGING_CATEGORY(LOG_DataSourceTreeWidgetItem, "DataSourceTreeWidgetItem")
7 Q_LOGGING_CATEGORY(LOG_DataSourceTreeWidgetItem, "DataSourceTreeWidgetItem")
10
8
11 namespace {
9 namespace {
12
10
11 // Column indexes
12 const auto NAME_COLUMN = 0;
13
13 QIcon itemIcon(const DataSourceItem *dataSource)
14 QIcon itemIcon(const DataSourceItem *dataSource)
14 {
15 {
15 if (dataSource) {
16 if (dataSource) {
16 auto dataSourceType = dataSource->type();
17 auto dataSourceType = dataSource->type();
17 switch (dataSourceType) {
18 switch (dataSourceType) {
18 case DataSourceItemType::NODE:
19 case DataSourceItemType::NODE: {
19 return sqpApp->style()->standardIcon(QStyle::SP_DirIcon);
20 return dataSource->isRoot() ? QIcon{":/icones/dataSourceRoot.png"}
21 : QIcon{":/icones/dataSourceNode.png"};
22 }
20 case DataSourceItemType::PRODUCT:
23 case DataSourceItemType::PRODUCT:
21 return sqpApp->style()->standardIcon(QStyle::SP_FileIcon);
24 return QIcon{":/icones/dataSourceProduct.png"};
25 case DataSourceItemType::COMPONENT:
26 return QIcon{":/icones/dataSourceComponent.png"};
22 default:
27 default:
23 // No action
28 // No action
24 break;
29 break;
@@ -28,7 +33,7 QIcon itemIcon(const DataSourceItem *dataSource)
28 << QObject::tr("Can't set data source icon : unknown data source type");
33 << QObject::tr("Can't set data source icon : unknown data source type");
29 }
34 }
30 else {
35 else {
31 qCWarning(LOG_DataSourceTreeWidgetItem())
36 qCCritical(LOG_DataSourceTreeWidgetItem())
32 << QObject::tr("Can't set data source icon : the data source is null");
37 << QObject::tr("Can't set data source icon : the data source is null");
33 }
38 }
34
39
@@ -36,6 +41,54 QIcon itemIcon(const DataSourceItem *dataSource)
36 return QIcon{};
41 return QIcon{};
37 }
42 }
38
43
44 /// @return the tooltip text for a variant. The text depends on whether the data is a simple variant
45 /// or a list of variants
46 QString tooltipValue(const QVariant &variant) noexcept
47 {
48 // If the variant is a list of variants, the text of the tooltip is of the form: {val1, val2,
49 // ...}
50 if (variant.canConvert<QVariantList>()) {
51 auto valueString = QStringLiteral("{");
52
53 auto variantList = variant.value<QVariantList>();
54 for (auto it = variantList.cbegin(), end = variantList.cend(); it != end; ++it) {
55 valueString.append(it->toString());
56
57 if (std::distance(it, end) != 1) {
58 valueString.append(", ");
59 }
60 }
61
62 valueString.append(QStringLiteral("}"));
63
64 return valueString;
65 }
66 else {
67 return variant.toString();
68 }
69 }
70
71 QString itemTooltip(const DataSourceItem *dataSource) noexcept
72 {
73 // The tooltip displays all item's data
74 if (dataSource) {
75 auto result = QString{};
76
77 const auto &data = dataSource->data();
78 for (auto it = data.cbegin(), end = data.cend(); it != end; ++it) {
79 result.append(QString{"<b>%1:</b> %2<br/>"}.arg(it.key(), tooltipValue(it.value())));
80 }
81
82 return result;
83 }
84 else {
85 qCCritical(LOG_DataSourceTreeWidgetItem())
86 << QObject::tr("Can't set data source tooltip : the data source is null");
87
88 return QString{};
89 }
90 }
91
39 } // namespace
92 } // namespace
40
93
41 struct DataSourceTreeWidgetItem::DataSourceTreeWidgetItemPrivate {
94 struct DataSourceTreeWidgetItem::DataSourceTreeWidgetItemPrivate {
@@ -58,8 +111,9 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(QTreeWidget *parent, const Da
58 : QTreeWidgetItem{parent, type},
111 : QTreeWidgetItem{parent, type},
59 impl{spimpl::make_unique_impl<DataSourceTreeWidgetItemPrivate>(data)}
112 impl{spimpl::make_unique_impl<DataSourceTreeWidgetItemPrivate>(data)}
60 {
113 {
61 // Sets the icon depending on the data source
114 // Sets the icon and the tooltip depending on the data source
62 setIcon(0, itemIcon(impl->m_Data));
115 setIcon(0, itemIcon(impl->m_Data));
116 setToolTip(0, itemTooltip(impl->m_Data));
63
117
64 // Generates tree actions based on the item actions
118 // Generates tree actions based on the item actions
65 auto createTreeAction = [this, &parent](const auto &itemAction) {
119 auto createTreeAction = [this, &parent](const auto &itemAction) {
@@ -80,7 +134,23 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(QTreeWidget *parent, const Da
80 QVariant DataSourceTreeWidgetItem::data(int column, int role) const
134 QVariant DataSourceTreeWidgetItem::data(int column, int role) const
81 {
135 {
82 if (role == Qt::DisplayRole) {
136 if (role == Qt::DisplayRole) {
83 return (impl->m_Data) ? impl->m_Data->data(column) : QVariant{};
137 if (impl->m_Data) {
138 switch (column) {
139 case NAME_COLUMN:
140 return impl->m_Data->name();
141 default:
142 // No action
143 break;
144 }
145
146 qCWarning(LOG_DataSourceTreeWidgetItem())
147 << QObject::tr("Can't get data (unknown column %1)").arg(column);
148 }
149 else {
150 qCCritical(LOG_DataSourceTreeWidgetItem()) << QObject::tr("Can't get data (null item)");
151 }
152
153 return QVariant{};
84 }
154 }
85 else {
155 else {
86 return QTreeWidgetItem::data(column, role);
156 return QTreeWidgetItem::data(column, role);
@@ -23,8 +23,7 std::unique_ptr<IDataProvider> createDataProvider() noexcept
23 std::unique_ptr<DataSourceItem> createProductItem(const QString &productName,
23 std::unique_ptr<DataSourceItem> createProductItem(const QString &productName,
24 const QUuid &dataSourceUid)
24 const QUuid &dataSourceUid)
25 {
25 {
26 auto result = std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT,
26 auto result = std::make_unique<DataSourceItem>(DataSourceItemType::PRODUCT, productName);
27 QVector<QVariant>{productName});
28
27
29 // Add action to load product from DataSourceController
28 // Add action to load product from DataSourceController
30 result->addAction(std::make_unique<DataSourceItemAction>(
29 result->addAction(std::make_unique<DataSourceItemAction>(
@@ -42,18 +41,17 std::unique_ptr<DataSourceItem> createProductItem(const QString &productName,
42 std::unique_ptr<DataSourceItem> createDataSourceItem(const QUuid &dataSourceUid) noexcept
41 std::unique_ptr<DataSourceItem> createDataSourceItem(const QUuid &dataSourceUid) noexcept
43 {
42 {
44 // Magnetic field products
43 // Magnetic field products
45 auto magneticFieldFolder = std::make_unique<DataSourceItem>(
44 auto magneticFieldFolder = std::make_unique<DataSourceItem>(DataSourceItemType::NODE,
46 DataSourceItemType::NODE, QVector<QVariant>{QStringLiteral("Magnetic field")});
45 QStringLiteral("Magnetic field"));
47 magneticFieldFolder->appendChild(createProductItem(QStringLiteral("FGM"), dataSourceUid));
46 magneticFieldFolder->appendChild(createProductItem(QStringLiteral("FGM"), dataSourceUid));
48 magneticFieldFolder->appendChild(createProductItem(QStringLiteral("SC"), dataSourceUid));
47 magneticFieldFolder->appendChild(createProductItem(QStringLiteral("SC"), dataSourceUid));
49
48
50 // Electric field products
49 // Electric field products
51 auto electricFieldFolder = std::make_unique<DataSourceItem>(
50 auto electricFieldFolder = std::make_unique<DataSourceItem>(DataSourceItemType::NODE,
52 DataSourceItemType::NODE, QVector<QVariant>{QStringLiteral("Electric field")});
51 QStringLiteral("Electric field"));
53
52
54 // Root
53 // Root
55 auto root = std::make_unique<DataSourceItem>(DataSourceItemType::NODE,
54 auto root = std::make_unique<DataSourceItem>(DataSourceItemType::NODE, DATA_SOURCE_NAME);
56 QVector<QVariant>{DATA_SOURCE_NAME});
57 root->appendChild(std::move(magneticFieldFolder));
55 root->appendChild(std::move(magneticFieldFolder));
58 root->appendChild(std::move(electricFieldFolder));
56 root->appendChild(std::move(electricFieldFolder));
59
57
General Comments 0
You need to be logged in to leave comments. Login now