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