##// END OF EJS Templates
Handles items with same names in the same node...
Alexandre Leroux -
r1037:c90049fe7bc2
parent child
Show More
@@ -1,185 +1,225
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 /**
15 * Generates the full name of an item.
16 *
17 * The full name of an item is its name possibly suffixed by the name of its plugin, in case there
18 * are items of the same name in its relatives
19 * @param item the item for which to generate the complete name
20 * @return the complete name of the item
21 */
22 QString completeName(const DataSourceItem &item)
23 {
24 auto name = item.name();
25
26 if (item.type() == DataSourceItemType::NODE) {
27 return name;
28 }
29
30 auto parentItem = item.parentItem();
31 if (!parentItem) {
32 return name;
33 }
34
35 // Finds in item's relatives items that have the same name
36 bool foundSameName = false;
37 for (auto i = 0, count = parentItem->childCount(); i < count && !foundSameName; ++i) {
38 auto child = parentItem->child(i);
39 foundSameName = child != &item
40 && QString::compare(child->name(), item.name(), Qt::CaseInsensitive) == 0;
41 }
42
43 // If the name of the item is not unique, it is completed by the plugin suffix
44 return foundSameName
45 ? QString{"%1 (%2)"}.arg(name, item.data(DataSourceItem::PLUGIN_DATA_KEY).toString())
46 : name;
47 }
48
14 QIcon itemIcon(const DataSourceItem *dataSource)
49 QIcon itemIcon(const DataSourceItem *dataSource)
15 {
50 {
16 if (dataSource) {
51 if (dataSource) {
17 auto dataSourceType = dataSource->type();
52 auto dataSourceType = dataSource->type();
18 switch (dataSourceType) {
53 switch (dataSourceType) {
19 case DataSourceItemType::NODE: {
54 case DataSourceItemType::NODE: {
20 return dataSource->isRoot() ? QIcon{":/icones/dataSourceRoot.png"}
55 return dataSource->isRoot() ? QIcon{":/icones/dataSourceRoot.png"}
21 : QIcon{":/icones/dataSourceNode.png"};
56 : QIcon{":/icones/dataSourceNode.png"};
22 }
57 }
23 case DataSourceItemType::PRODUCT:
58 case DataSourceItemType::PRODUCT:
24 return QIcon{":/icones/dataSourceProduct.png"};
59 return QIcon{":/icones/dataSourceProduct.png"};
25 case DataSourceItemType::COMPONENT:
60 case DataSourceItemType::COMPONENT:
26 return QIcon{":/icones/dataSourceComponent.png"};
61 return QIcon{":/icones/dataSourceComponent.png"};
27 default:
62 default:
28 // No action
63 // No action
29 break;
64 break;
30 }
65 }
31
66
32 qCWarning(LOG_DataSourceTreeWidgetItem())
67 qCWarning(LOG_DataSourceTreeWidgetItem())
33 << QObject::tr("Can't set data source icon : unknown data source type");
68 << QObject::tr("Can't set data source icon : unknown data source type");
34 }
69 }
35 else {
70 else {
36 qCCritical(LOG_DataSourceTreeWidgetItem())
71 qCCritical(LOG_DataSourceTreeWidgetItem())
37 << QObject::tr("Can't set data source icon : the data source is null");
72 << QObject::tr("Can't set data source icon : the data source is null");
38 }
73 }
39
74
40 // Default cases
75 // Default cases
41 return QIcon{};
76 return QIcon{};
42 }
77 }
43
78
44 /// @return the tooltip text for a variant. The text depends on whether the data is a simple variant
79 /// @return the tooltip text for a variant. The text depends on whether the data is a simple variant
45 /// or a list of variants
80 /// or a list of variants
46 QString tooltipValue(const QVariant &variant) noexcept
81 QString tooltipValue(const QVariant &variant) noexcept
47 {
82 {
48 // If the variant is a list of variants, the text of the tooltip is of the form: {val1, val2,
83 // If the variant is a list of variants, the text of the tooltip is of the form: {val1, val2,
49 // ...}
84 // ...}
50 if (variant.canConvert<QVariantList>()) {
85 if (variant.canConvert<QVariantList>()) {
51 auto valueString = QStringLiteral("{");
86 auto valueString = QStringLiteral("{");
52
87
53 auto variantList = variant.value<QVariantList>();
88 auto variantList = variant.value<QVariantList>();
54 for (auto it = variantList.cbegin(), end = variantList.cend(); it != end; ++it) {
89 for (auto it = variantList.cbegin(), end = variantList.cend(); it != end; ++it) {
55 valueString.append(it->toString());
90 valueString.append(it->toString());
56
91
57 if (std::distance(it, end) != 1) {
92 if (std::distance(it, end) != 1) {
58 valueString.append(", ");
93 valueString.append(", ");
59 }
94 }
60 }
95 }
61
96
62 valueString.append(QStringLiteral("}"));
97 valueString.append(QStringLiteral("}"));
63
98
64 return valueString;
99 return valueString;
65 }
100 }
66 else {
101 else {
67 return variant.toString();
102 return variant.toString();
68 }
103 }
69 }
104 }
70
105
71 QString itemTooltip(const DataSourceItem *dataSource) noexcept
106 QString itemTooltip(const DataSourceItem *dataSource) noexcept
72 {
107 {
73 // The tooltip displays all item's data
108 // The tooltip displays all item's data
74 if (dataSource) {
109 if (dataSource) {
75 auto result = QString{};
110 auto result = QString{};
76
111
77 const auto &data = dataSource->data();
112 const auto &data = dataSource->data();
78 for (auto it = data.cbegin(), end = data.cend(); it != end; ++it) {
113 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())));
114 result.append(QString{"<b>%1:</b> %2<br/>"}.arg(it.key(), tooltipValue(it.value())));
80 }
115 }
81
116
82 return result;
117 return result;
83 }
118 }
84 else {
119 else {
85 qCCritical(LOG_DataSourceTreeWidgetItem())
120 qCCritical(LOG_DataSourceTreeWidgetItem())
86 << QObject::tr("Can't set data source tooltip : the data source is null");
121 << QObject::tr("Can't set data source tooltip : the data source is null");
87
122
88 return QString{};
123 return QString{};
89 }
124 }
90 }
125 }
91
126
92 } // namespace
127 } // namespace
93
128
94 struct DataSourceTreeWidgetItem::DataSourceTreeWidgetItemPrivate {
129 struct DataSourceTreeWidgetItem::DataSourceTreeWidgetItemPrivate {
95 explicit DataSourceTreeWidgetItemPrivate(const DataSourceItem *data) : m_Data{data} {}
130 explicit DataSourceTreeWidgetItemPrivate(const DataSourceItem *data)
131 : m_Data{data}, m_Name{completeName(*m_Data)}
132 {
133 }
96
134
97 /// Model used to retrieve data source information
135 /// Model used to retrieve data source information
98 const DataSourceItem *m_Data;
136 const DataSourceItem *m_Data;
137 /// Name displayed
138 QString m_Name;
99 /// Actions associated to the item. The parent of the item (QTreeWidget) takes the ownership of
139 /// Actions associated to the item. The parent of the item (QTreeWidget) takes the ownership of
100 /// the actions
140 /// the actions
101 QList<QAction *> m_Actions;
141 QList<QAction *> m_Actions;
102 };
142 };
103
143
104 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(const DataSourceItem *data, int type)
144 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(const DataSourceItem *data, int type)
105 : DataSourceTreeWidgetItem{nullptr, data, type}
145 : DataSourceTreeWidgetItem{nullptr, data, type}
106 {
146 {
107 }
147 }
108
148
109 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(QTreeWidget *parent, const DataSourceItem *data,
149 DataSourceTreeWidgetItem::DataSourceTreeWidgetItem(QTreeWidget *parent, const DataSourceItem *data,
110 int type)
150 int type)
111 : QTreeWidgetItem{parent, type},
151 : QTreeWidgetItem{parent, type},
112 impl{spimpl::make_unique_impl<DataSourceTreeWidgetItemPrivate>(data)}
152 impl{spimpl::make_unique_impl<DataSourceTreeWidgetItemPrivate>(data)}
113 {
153 {
114 // Sets the icon and the tooltip depending on the data source
154 // Sets the icon and the tooltip depending on the data source
115 setIcon(0, itemIcon(impl->m_Data));
155 setIcon(0, itemIcon(impl->m_Data));
116 setToolTip(0, itemTooltip(impl->m_Data));
156 setToolTip(0, itemTooltip(impl->m_Data));
117
157
118 // Generates tree actions based on the item actions
158 // Generates tree actions based on the item actions
119 auto createTreeAction = [this, &parent](const auto &itemAction) {
159 auto createTreeAction = [this, &parent](const auto &itemAction) {
120 auto treeAction = new QAction{itemAction->name(), parent};
160 auto treeAction = new QAction{itemAction->name(), parent};
121
161
122 // Executes item action when tree action is triggered
162 // Executes item action when tree action is triggered
123 QObject::connect(treeAction, &QAction::triggered, itemAction,
163 QObject::connect(treeAction, &QAction::triggered, itemAction,
124 &DataSourceItemAction::execute);
164 &DataSourceItemAction::execute);
125
165
126 return treeAction;
166 return treeAction;
127 };
167 };
128
168
129 auto itemActions = impl->m_Data->actions();
169 auto itemActions = impl->m_Data->actions();
130 std::transform(std::cbegin(itemActions), std::cend(itemActions),
170 std::transform(std::cbegin(itemActions), std::cend(itemActions),
131 std::back_inserter(impl->m_Actions), createTreeAction);
171 std::back_inserter(impl->m_Actions), createTreeAction);
132
172
133 // Sets the flags of the items
173 // Sets the flags of the items
134 auto flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
174 auto flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
135 if (data->type() == DataSourceItemType::COMPONENT
175 if (data->type() == DataSourceItemType::COMPONENT
136 || data->type() == DataSourceItemType::PRODUCT) {
176 || data->type() == DataSourceItemType::PRODUCT) {
137 flags |= Qt::ItemIsDragEnabled;
177 flags |= Qt::ItemIsDragEnabled;
138 }
178 }
139
179
140 setFlags(flags);
180 setFlags(flags);
141 }
181 }
142
182
143 const DataSourceItem *DataSourceTreeWidgetItem::data() const
183 const DataSourceItem *DataSourceTreeWidgetItem::data() const
144 {
184 {
145 return impl->m_Data;
185 return impl->m_Data;
146 }
186 }
147
187
148 QVariant DataSourceTreeWidgetItem::data(int column, int role) const
188 QVariant DataSourceTreeWidgetItem::data(int column, int role) const
149 {
189 {
150 if (role == Qt::DisplayRole) {
190 if (role == Qt::DisplayRole) {
151 if (impl->m_Data) {
191 if (impl->m_Data) {
152 switch (column) {
192 switch (column) {
153 case NAME_COLUMN:
193 case NAME_COLUMN:
154 return impl->m_Data->name();
194 return impl->m_Name;
155 default:
195 default:
156 // No action
196 // No action
157 break;
197 break;
158 }
198 }
159
199
160 qCWarning(LOG_DataSourceTreeWidgetItem())
200 qCWarning(LOG_DataSourceTreeWidgetItem())
161 << QObject::tr("Can't get data (unknown column %1)").arg(column);
201 << QObject::tr("Can't get data (unknown column %1)").arg(column);
162 }
202 }
163 else {
203 else {
164 qCCritical(LOG_DataSourceTreeWidgetItem()) << QObject::tr("Can't get data (null item)");
204 qCCritical(LOG_DataSourceTreeWidgetItem()) << QObject::tr("Can't get data (null item)");
165 }
205 }
166
206
167 return QVariant{};
207 return QVariant{};
168 }
208 }
169 else {
209 else {
170 return QTreeWidgetItem::data(column, role);
210 return QTreeWidgetItem::data(column, role);
171 }
211 }
172 }
212 }
173
213
174 void DataSourceTreeWidgetItem::setData(int column, int role, const QVariant &value)
214 void DataSourceTreeWidgetItem::setData(int column, int role, const QVariant &value)
175 {
215 {
176 // Data can't be changed by edition
216 // Data can't be changed by edition
177 if (role != Qt::EditRole) {
217 if (role != Qt::EditRole) {
178 QTreeWidgetItem::setData(column, role, value);
218 QTreeWidgetItem::setData(column, role, value);
179 }
219 }
180 }
220 }
181
221
182 QList<QAction *> DataSourceTreeWidgetItem::actions() const noexcept
222 QList<QAction *> DataSourceTreeWidgetItem::actions() const noexcept
183 {
223 {
184 return impl->m_Actions;
224 return impl->m_Actions;
185 }
225 }
General Comments 0
You need to be logged in to leave comments. Login now