##// END OF EJS Templates
Handles tooltip for a data source item
Alexandre Leroux -
r346:4b46cbe03729
parent child
Show More
@@ -1,79 +1,82
1 #ifndef SCIQLOP_DATASOURCEITEM_H
1 #ifndef SCIQLOP_DATASOURCEITEM_H
2 #define SCIQLOP_DATASOURCEITEM_H
2 #define SCIQLOP_DATASOURCEITEM_H
3
3
4 #include <Common/spimpl.h>
4 #include <Common/spimpl.h>
5
5
6 #include <QVariant>
6 #include <QVariant>
7 #include <QVector>
7 #include <QVector>
8
8
9 class DataSourceItemAction;
9 class DataSourceItemAction;
10
10
11 /**
11 /**
12 * Possible types of an item
12 * Possible types of an item
13 */
13 */
14 enum class DataSourceItemType { NODE, PRODUCT, COMPONENT };
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.
18 * A data source has a tree structure that is made up of a main DataSourceItem object (root)
18 * A data source has a tree structure that is made up of a main DataSourceItem object (root)
19 * containing other DataSourceItem objects (children).
19 * containing other DataSourceItem objects (children).
20 * For each DataSourceItem can be associated a set of data representing it.
20 * For each DataSourceItem can be associated a set of data representing it.
21 */
21 */
22 class DataSourceItem {
22 class DataSourceItem {
23 public:
23 public:
24 /// Key associated with the name of the item
24 /// Key associated with the name of the item
25 static const QString NAME_DATA_KEY;
25 static const QString NAME_DATA_KEY;
26
26
27 explicit DataSourceItem(DataSourceItemType type, const QString &name);
27 explicit DataSourceItem(DataSourceItemType type, const QString &name);
28 explicit DataSourceItem(DataSourceItemType type, QHash<QString, QVariant> data = {});
28 explicit DataSourceItem(DataSourceItemType type, QHash<QString, QVariant> data = {});
29
29
30 /// @return the actions of the item as a vector
30 /// @return the actions of the item as a vector
31 QVector<DataSourceItemAction *> actions() const noexcept;
31 QVector<DataSourceItemAction *> actions() const noexcept;
32
32
33 /**
33 /**
34 * Adds an action to the item. The item takes ownership of the action, and the action is
34 * Adds an action to the item. The item takes ownership of the action, and the action is
35 * automatically associated to the item
35 * automatically associated to the item
36 * @param action the action to add
36 * @param action the action to add
37 */
37 */
38 void addAction(std::unique_ptr<DataSourceItemAction> action) noexcept;
38 void addAction(std::unique_ptr<DataSourceItemAction> action) noexcept;
39
39
40 /**
40 /**
41 * Adds a child to the item. The item takes ownership of the child.
41 * Adds a child to the item. The item takes ownership of the child.
42 * @param child the child to add
42 * @param child the child to add
43 */
43 */
44 void appendChild(std::unique_ptr<DataSourceItem> child) noexcept;
44 void appendChild(std::unique_ptr<DataSourceItem> child) noexcept;
45
45
46 /**
46 /**
47 * Returns the item's child associated to an index
47 * Returns the item's child associated to an index
48 * @param childIndex the index to search
48 * @param childIndex the index to search
49 * @return a pointer to the child if index is valid, nullptr otherwise
49 * @return a pointer to the child if index is valid, nullptr otherwise
50 */
50 */
51 DataSourceItem *child(int childIndex) const noexcept;
51 DataSourceItem *child(int childIndex) const noexcept;
52
52
53 int childCount() const noexcept;
53 int childCount() const noexcept;
54
54
55 /**
55 /**
56 * Get the data associated to a key
56 * Get the data associated to a key
57 * @param key the key to search
57 * @param key the key to search
58 * @return the data found if key is valid, default QVariant otherwise
58 * @return the data found if key is valid, default QVariant otherwise
59 */
59 */
60 QVariant data(const QString &key) const noexcept;
60 QVariant data(const QString &key) const noexcept;
61
61
62 /// Gets all data
63 const QHash<QString, QVariant> &data() const noexcept;
64
62 bool isRoot() const noexcept;
65 bool isRoot() const noexcept;
63
66
64 QString name() const noexcept;
67 QString name() const noexcept;
65
68
66 /**
69 /**
67 * Get the item's parent
70 * Get the item's parent
68 * @return a pointer to the parent if it exists, nullptr if the item is a root
71 * @return a pointer to the parent if it exists, nullptr if the item is a root
69 */
72 */
70 DataSourceItem *parentItem() const noexcept;
73 DataSourceItem *parentItem() const noexcept;
71
74
72 DataSourceItemType type() const noexcept;
75 DataSourceItemType type() const noexcept;
73
76
74 private:
77 private:
75 class DataSourceItemPrivate;
78 class DataSourceItemPrivate;
76 spimpl::unique_impl_ptr<DataSourceItemPrivate> impl;
79 spimpl::unique_impl_ptr<DataSourceItemPrivate> impl;
77 };
80 };
78
81
79 #endif // SCIQLOP_DATASOURCEITEMMODEL_H
82 #endif // SCIQLOP_DATASOURCEITEMMODEL_H
@@ -1,91 +1,96
1 #include <DataSource/DataSourceItem.h>
1 #include <DataSource/DataSourceItem.h>
2 #include <DataSource/DataSourceItemAction.h>
2 #include <DataSource/DataSourceItemAction.h>
3
3
4 #include <QVector>
4 #include <QVector>
5
5
6 const QString DataSourceItem::NAME_DATA_KEY = QStringLiteral("name");
6 const QString DataSourceItem::NAME_DATA_KEY = QStringLiteral("name");
7
7
8 struct DataSourceItem::DataSourceItemPrivate {
8 struct DataSourceItem::DataSourceItemPrivate {
9 explicit DataSourceItemPrivate(DataSourceItemType type, QHash<QString, QVariant> data)
9 explicit DataSourceItemPrivate(DataSourceItemType type, QHash<QString, QVariant> data)
10 : 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{}
11 {
11 {
12 }
12 }
13
13
14 DataSourceItem *m_Parent;
14 DataSourceItem *m_Parent;
15 std::vector<std::unique_ptr<DataSourceItem> > m_Children;
15 std::vector<std::unique_ptr<DataSourceItem> > m_Children;
16 DataSourceItemType m_Type;
16 DataSourceItemType m_Type;
17 QHash<QString, QVariant> m_Data;
17 QHash<QString, QVariant> m_Data;
18 std::vector<std::unique_ptr<DataSourceItemAction> > m_Actions;
18 std::vector<std::unique_ptr<DataSourceItemAction> > m_Actions;
19 };
19 };
20
20
21 DataSourceItem::DataSourceItem(DataSourceItemType type, const QString &name)
21 DataSourceItem::DataSourceItem(DataSourceItemType type, const QString &name)
22 : DataSourceItem{type, QHash<QString, QVariant>{{NAME_DATA_KEY, name}}}
22 : DataSourceItem{type, QHash<QString, QVariant>{{NAME_DATA_KEY, name}}}
23 {
23 {
24 }
24 }
25
25
26 DataSourceItem::DataSourceItem(DataSourceItemType type, QHash<QString, QVariant> data)
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 }
30
30
31 QVector<DataSourceItemAction *> DataSourceItem::actions() const noexcept
31 QVector<DataSourceItemAction *> DataSourceItem::actions() const noexcept
32 {
32 {
33 auto result = QVector<DataSourceItemAction *>{};
33 auto result = QVector<DataSourceItemAction *>{};
34
34
35 std::transform(std::cbegin(impl->m_Actions), std::cend(impl->m_Actions),
35 std::transform(std::cbegin(impl->m_Actions), std::cend(impl->m_Actions),
36 std::back_inserter(result), [](const auto &action) { return action.get(); });
36 std::back_inserter(result), [](const auto &action) { return action.get(); });
37
37
38 return result;
38 return result;
39 }
39 }
40
40
41 void DataSourceItem::addAction(std::unique_ptr<DataSourceItemAction> action) noexcept
41 void DataSourceItem::addAction(std::unique_ptr<DataSourceItemAction> action) noexcept
42 {
42 {
43 action->setDataSourceItem(this);
43 action->setDataSourceItem(this);
44 impl->m_Actions.push_back(std::move(action));
44 impl->m_Actions.push_back(std::move(action));
45 }
45 }
46
46
47 void DataSourceItem::appendChild(std::unique_ptr<DataSourceItem> child) noexcept
47 void DataSourceItem::appendChild(std::unique_ptr<DataSourceItem> child) noexcept
48 {
48 {
49 child->impl->m_Parent = this;
49 child->impl->m_Parent = this;
50 impl->m_Children.push_back(std::move(child));
50 impl->m_Children.push_back(std::move(child));
51 }
51 }
52
52
53 DataSourceItem *DataSourceItem::child(int childIndex) const noexcept
53 DataSourceItem *DataSourceItem::child(int childIndex) const noexcept
54 {
54 {
55 if (childIndex < 0 || childIndex >= childCount()) {
55 if (childIndex < 0 || childIndex >= childCount()) {
56 return nullptr;
56 return nullptr;
57 }
57 }
58 else {
58 else {
59 return impl->m_Children.at(childIndex).get();
59 return impl->m_Children.at(childIndex).get();
60 }
60 }
61 }
61 }
62
62
63 int DataSourceItem::childCount() const noexcept
63 int DataSourceItem::childCount() const noexcept
64 {
64 {
65 return impl->m_Children.size();
65 return impl->m_Children.size();
66 }
66 }
67
67
68 QVariant DataSourceItem::data(const QString &key) const noexcept
68 QVariant DataSourceItem::data(const QString &key) const noexcept
69 {
69 {
70 return impl->m_Data.value(key);
70 return impl->m_Data.value(key);
71 }
71 }
72
72
73 const QHash<QString, QVariant> &DataSourceItem::data() const noexcept
74 {
75 return impl->m_Data;
76 }
77
73 bool DataSourceItem::isRoot() const noexcept
78 bool DataSourceItem::isRoot() const noexcept
74 {
79 {
75 return impl->m_Parent == nullptr;
80 return impl->m_Parent == nullptr;
76 }
81 }
77
82
78 QString DataSourceItem::name() const noexcept
83 QString DataSourceItem::name() const noexcept
79 {
84 {
80 return data(NAME_DATA_KEY).toString();
85 return data(NAME_DATA_KEY).toString();
81 }
86 }
82
87
83 DataSourceItem *DataSourceItem::parentItem() const noexcept
88 DataSourceItem *DataSourceItem::parentItem() const noexcept
84 {
89 {
85 return impl->m_Parent;
90 return impl->m_Parent;
86 }
91 }
87
92
88 DataSourceItemType DataSourceItem::type() const noexcept
93 DataSourceItemType DataSourceItem::type() const noexcept
89 {
94 {
90 return impl->m_Type;
95 return impl->m_Type;
91 }
96 }
@@ -1,122 +1,171
1 #include <DataSource/DataSourceItem.h>
1 #include <DataSource/DataSourceItem.h>
2 #include <DataSource/DataSourceItemAction.h>
2 #include <DataSource/DataSourceItemAction.h>
3 #include <DataSource/DataSourceTreeWidgetItem.h>
3 #include <DataSource/DataSourceTreeWidgetItem.h>
4
4
5 #include <QAction>
5 #include <QAction>
6
6
7 Q_LOGGING_CATEGORY(LOG_DataSourceTreeWidgetItem, "DataSourceTreeWidgetItem")
7 Q_LOGGING_CATEGORY(LOG_DataSourceTreeWidgetItem, "DataSourceTreeWidgetItem")
8
8
9 namespace {
9 namespace {
10
10
11 // Column indexes
11 // Column indexes
12 const auto NAME_COLUMN = 0;
12 const auto NAME_COLUMN = 0;
13
13
14 QIcon itemIcon(const DataSourceItem *dataSource)
14 QIcon itemIcon(const DataSourceItem *dataSource)
15 {
15 {
16 if (dataSource) {
16 if (dataSource) {
17 auto dataSourceType = dataSource->type();
17 auto dataSourceType = dataSource->type();
18 switch (dataSourceType) {
18 switch (dataSourceType) {
19 case DataSourceItemType::NODE: {
19 case DataSourceItemType::NODE: {
20 return dataSource->isRoot() ? QIcon{":/icones/dataSourceRoot.png"}
20 return dataSource->isRoot() ? QIcon{":/icones/dataSourceRoot.png"}
21 : QIcon{":/icones/dataSourceNode.png"};
21 : QIcon{":/icones/dataSourceNode.png"};
22 }
22 }
23 case DataSourceItemType::PRODUCT:
23 case DataSourceItemType::PRODUCT:
24 return QIcon{":/icones/dataSourceProduct.png"};
24 return QIcon{":/icones/dataSourceProduct.png"};
25 case DataSourceItemType::COMPONENT:
25 case DataSourceItemType::COMPONENT:
26 return QIcon{":/icones/dataSourceComponent.png"};
26 return QIcon{":/icones/dataSourceComponent.png"};
27 default:
27 default:
28 // No action
28 // No action
29 break;
29 break;
30 }
30 }
31
31
32 qCWarning(LOG_DataSourceTreeWidgetItem())
32 qCWarning(LOG_DataSourceTreeWidgetItem())
33 << 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");
34 }
34 }
35 else {
35 else {
36 qCCritical(LOG_DataSourceTreeWidgetItem())
36 qCCritical(LOG_DataSourceTreeWidgetItem())
37 << 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");
38 }
38 }
39
39
40 // Default cases
40 // Default cases
41 return QIcon{};
41 return QIcon{};
42 }
42 }
43
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
44 } // namespace
92 } // namespace
45
93
46 struct DataSourceTreeWidgetItem::DataSourceTreeWidgetItemPrivate {
94 struct DataSourceTreeWidgetItem::DataSourceTreeWidgetItemPrivate {
47 explicit DataSourceTreeWidgetItemPrivate(const DataSourceItem *data) : m_Data{data} {}
95 explicit DataSourceTreeWidgetItemPrivate(const DataSourceItem *data) : m_Data{data} {}
48
96
49 /// Model used to retrieve data source information
97 /// Model used to retrieve data source information
50 const DataSourceItem *m_Data;
98 const DataSourceItem *m_Data;
51 /// Actions associated to the item. The parent of the item (QTreeWidget) takes the ownership of
99 /// Actions associated to the item. The parent of the item (QTreeWidget) takes the ownership of
52 /// the actions
100 /// the actions
53 QList<QAction *> m_Actions;
101 QList<QAction *> m_Actions;
54 };
102 };
55
103
56 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(const DataSourceItem *data, int type)
104 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(const DataSourceItem *data, int type)
57 : DataSourceTreeWidgetItem{nullptr, data, type}
105 : DataSourceTreeWidgetItem{nullptr, data, type}
58 {
106 {
59 }
107 }
60
108
61 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(QTreeWidget *parent, const DataSourceItem *data,
109 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(QTreeWidget *parent, const DataSourceItem *data,
62 int type)
110 int type)
63 : QTreeWidgetItem{parent, type},
111 : QTreeWidgetItem{parent, type},
64 impl{spimpl::make_unique_impl<DataSourceTreeWidgetItemPrivate>(data)}
112 impl{spimpl::make_unique_impl<DataSourceTreeWidgetItemPrivate>(data)}
65 {
113 {
66 // Sets the icon depending on the data source
114 // Sets the icon and the tooltip depending on the data source
67 setIcon(0, itemIcon(impl->m_Data));
115 setIcon(0, itemIcon(impl->m_Data));
116 setToolTip(0, itemTooltip(impl->m_Data));
68
117
69 // Generates tree actions based on the item actions
118 // Generates tree actions based on the item actions
70 auto createTreeAction = [this, &parent](const auto &itemAction) {
119 auto createTreeAction = [this, &parent](const auto &itemAction) {
71 auto treeAction = new QAction{itemAction->name(), parent};
120 auto treeAction = new QAction{itemAction->name(), parent};
72
121
73 // Executes item action when tree action is triggered
122 // Executes item action when tree action is triggered
74 QObject::connect(treeAction, &QAction::triggered, itemAction,
123 QObject::connect(treeAction, &QAction::triggered, itemAction,
75 &DataSourceItemAction::execute);
124 &DataSourceItemAction::execute);
76
125
77 return treeAction;
126 return treeAction;
78 };
127 };
79
128
80 auto itemActions = impl->m_Data->actions();
129 auto itemActions = impl->m_Data->actions();
81 std::transform(std::cbegin(itemActions), std::cend(itemActions),
130 std::transform(std::cbegin(itemActions), std::cend(itemActions),
82 std::back_inserter(impl->m_Actions), createTreeAction);
131 std::back_inserter(impl->m_Actions), createTreeAction);
83 }
132 }
84
133
85 QVariant DataSourceTreeWidgetItem::data(int column, int role) const
134 QVariant DataSourceTreeWidgetItem::data(int column, int role) const
86 {
135 {
87 if (role == Qt::DisplayRole) {
136 if (role == Qt::DisplayRole) {
88 if (impl->m_Data) {
137 if (impl->m_Data) {
89 switch (column) {
138 switch (column) {
90 case NAME_COLUMN:
139 case NAME_COLUMN:
91 return impl->m_Data->name();
140 return impl->m_Data->name();
92 default:
141 default:
93 // No action
142 // No action
94 break;
143 break;
95 }
144 }
96
145
97 qCWarning(LOG_DataSourceTreeWidgetItem())
146 qCWarning(LOG_DataSourceTreeWidgetItem())
98 << QObject::tr("Can't get data (unknown column %1)").arg(column);
147 << QObject::tr("Can't get data (unknown column %1)").arg(column);
99 }
148 }
100 else {
149 else {
101 qCCritical(LOG_DataSourceTreeWidgetItem()) << QObject::tr("Can't get data (null item)");
150 qCCritical(LOG_DataSourceTreeWidgetItem()) << QObject::tr("Can't get data (null item)");
102 }
151 }
103
152
104 return QVariant{};
153 return QVariant{};
105 }
154 }
106 else {
155 else {
107 return QTreeWidgetItem::data(column, role);
156 return QTreeWidgetItem::data(column, role);
108 }
157 }
109 }
158 }
110
159
111 void DataSourceTreeWidgetItem::setData(int column, int role, const QVariant &value)
160 void DataSourceTreeWidgetItem::setData(int column, int role, const QVariant &value)
112 {
161 {
113 // Data can't be changed by edition
162 // Data can't be changed by edition
114 if (role != Qt::EditRole) {
163 if (role != Qt::EditRole) {
115 QTreeWidgetItem::setData(column, role, value);
164 QTreeWidgetItem::setData(column, role, value);
116 }
165 }
117 }
166 }
118
167
119 QList<QAction *> DataSourceTreeWidgetItem::actions() const noexcept
168 QList<QAction *> DataSourceTreeWidgetItem::actions() const noexcept
120 {
169 {
121 return impl->m_Actions;
170 return impl->m_Actions;
122 }
171 }
General Comments 0
You need to be logged in to leave comments. Login now