1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Qt Designer of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | #include "itemview_propertysheet.h" |
30 | |
31 | #include <QtDesigner/abstractformeditor.h> |
32 | |
33 | #include <QtWidgets/qabstractitemview.h> |
34 | #include <QtWidgets/qheaderview.h> |
35 | #include <QtCore/qdebug.h> |
36 | |
37 | QT_BEGIN_NAMESPACE |
38 | |
39 | namespace qdesigner_internal { |
40 | |
41 | struct Property { |
42 | Property() = default; |
43 | Property(QDesignerPropertySheetExtension *sheet, int id) |
44 | : m_sheet(sheet), m_id(id) {} |
45 | |
46 | QDesignerPropertySheetExtension *m_sheet{nullptr}; |
47 | int m_id{-1}; |
48 | }; |
49 | |
50 | typedef QMap<int, Property> FakePropertyMap; |
51 | |
52 | struct ItemViewPropertySheetPrivate { |
53 | ItemViewPropertySheetPrivate(QDesignerFormEditorInterface *core, |
54 | QHeaderView *, |
55 | QHeaderView *); |
56 | |
57 | inline QStringList realPropertyNames(); |
58 | inline QString fakePropertyName(const QString &prefix, const QString &realName); |
59 | |
60 | // Maps index of fake property to index of real property in respective sheet |
61 | FakePropertyMap m_propertyIdMap; |
62 | |
63 | // Maps name of fake property to name of real property |
64 | QHash<QString, QString> m_propertyNameMap; |
65 | |
66 | QHash<QHeaderView *, QDesignerPropertySheetExtension *> m_propertySheet; |
67 | QStringList m_realPropertyNames; |
68 | }; |
69 | |
70 | // Name of the fake group |
71 | static const char * = "Header" ; |
72 | |
73 | // Name of the real properties |
74 | static const char *visibleProperty = "visible" ; |
75 | static const char *cascadingSectionResizesProperty = "cascadingSectionResizes" ; |
76 | static const char *defaultSectionSizeProperty = "defaultSectionSize" ; |
77 | static const char *highlightSectionsProperty = "highlightSections" ; |
78 | static const char *minimumSectionSizeProperty = "minimumSectionSize" ; |
79 | static const char *showSortIndicatorProperty = "showSortIndicator" ; |
80 | static const char *stretchLastSectionProperty = "stretchLastSection" ; |
81 | } // namespace qdesigner_internal |
82 | |
83 | using namespace qdesigner_internal; |
84 | |
85 | |
86 | /***************** ItemViewPropertySheetPrivate *********************/ |
87 | |
88 | ItemViewPropertySheetPrivate::(QDesignerFormEditorInterface *core, |
89 | QHeaderView *, |
90 | QHeaderView *) |
91 | { |
92 | if (horizontalHeader) |
93 | m_propertySheet.insert(akey: horizontalHeader, |
94 | avalue: qt_extension<QDesignerPropertySheetExtension*> |
95 | (manager: core->extensionManager(), object: horizontalHeader)); |
96 | if (verticalHeader) |
97 | m_propertySheet.insert(akey: verticalHeader, |
98 | avalue: qt_extension<QDesignerPropertySheetExtension*> |
99 | (manager: core->extensionManager(), object: verticalHeader)); |
100 | } |
101 | |
102 | QStringList ItemViewPropertySheetPrivate::realPropertyNames() |
103 | { |
104 | if (m_realPropertyNames.isEmpty()) |
105 | m_realPropertyNames |
106 | << QLatin1String(visibleProperty) |
107 | << QLatin1String(cascadingSectionResizesProperty) |
108 | << QLatin1String(defaultSectionSizeProperty) |
109 | << QLatin1String(highlightSectionsProperty) |
110 | << QLatin1String(minimumSectionSizeProperty) |
111 | << QLatin1String(showSortIndicatorProperty) |
112 | << QLatin1String(stretchLastSectionProperty); |
113 | return m_realPropertyNames; |
114 | } |
115 | |
116 | QString ItemViewPropertySheetPrivate::fakePropertyName(const QString &prefix, |
117 | const QString &realName) |
118 | { |
119 | // prefix = "header", realPropertyName = "isVisible" returns "headerIsVisible" |
120 | QString fakeName = prefix + realName.at(i: 0).toUpper() + realName.mid(position: 1); |
121 | m_propertyNameMap.insert(akey: fakeName, avalue: realName); |
122 | return fakeName; |
123 | } |
124 | |
125 | /***************** ItemViewPropertySheet *********************/ |
126 | |
127 | /*! |
128 | \class qdesigner_internal::ItemViewPropertySheet |
129 | |
130 | \brief |
131 | Adds header fake properties to QTreeView and QTableView objects |
132 | |
133 | QHeaderView objects are currently not shown in the object inspector. |
134 | This class adds some fake properties to the property sheet |
135 | of QTreeView and QTableView objects that nevertheless allow the manipulation |
136 | of the headers attached to the item view object. |
137 | |
138 | Currently the defaultAlignment property is not shown because the property sheet |
139 | would only show integers, instead of the Qt::Alignment enumeration. |
140 | |
141 | The fake properties here need special handling in QDesignerResource, uiloader and uic. |
142 | */ |
143 | |
144 | ItemViewPropertySheet::ItemViewPropertySheet(QTreeView *treeViewObject, QObject *parent) |
145 | : QDesignerPropertySheet(treeViewObject, parent), |
146 | d(new ItemViewPropertySheetPrivate(core(), treeViewObject->header(), nullptr)) |
147 | { |
148 | initHeaderProperties(hv: treeViewObject->header(), QStringLiteral("header" )); |
149 | } |
150 | |
151 | ItemViewPropertySheet::ItemViewPropertySheet(QTableView *tableViewObject, QObject *parent) |
152 | : QDesignerPropertySheet(tableViewObject, parent), |
153 | d(new ItemViewPropertySheetPrivate(core(), |
154 | tableViewObject->horizontalHeader(), |
155 | tableViewObject->verticalHeader())) |
156 | { |
157 | initHeaderProperties(hv: tableViewObject->horizontalHeader(), QStringLiteral("horizontalHeader" )); |
158 | initHeaderProperties(hv: tableViewObject->verticalHeader(), QStringLiteral("verticalHeader" )); |
159 | } |
160 | |
161 | ItemViewPropertySheet::~ItemViewPropertySheet() |
162 | { |
163 | delete d; |
164 | } |
165 | |
166 | void ItemViewPropertySheet::(QHeaderView *hv, const QString &prefix) |
167 | { |
168 | QDesignerPropertySheetExtension * = d->m_propertySheet.value(akey: hv); |
169 | Q_ASSERT(headerSheet); |
170 | const QString = QLatin1String(headerGroup); |
171 | const QStringList &realPropertyNames = d->realPropertyNames(); |
172 | for (const QString &realPropertyName : realPropertyNames) { |
173 | const int = headerSheet->indexOf(name: realPropertyName); |
174 | Q_ASSERT(headerIndex != -1); |
175 | const QVariant defaultValue = realPropertyName == QLatin1String(visibleProperty) ? |
176 | QVariant(true) : headerSheet->property(index: headerIndex); |
177 | const QString fakePropertyName = d->fakePropertyName(prefix, realName: realPropertyName); |
178 | const int fakeIndex = createFakeProperty(propertyName: fakePropertyName, value: defaultValue); |
179 | d->m_propertyIdMap.insert(akey: fakeIndex, avalue: Property(headerSheet, headerIndex)); |
180 | setAttribute(index: fakeIndex, b: true); |
181 | setPropertyGroup(index: fakeIndex, group: headerGroupS); |
182 | } |
183 | } |
184 | |
185 | /*! |
186 | Returns the mapping of fake property names to real property names |
187 | */ |
188 | QHash<QString,QString> ItemViewPropertySheet::propertyNameMap() const |
189 | { |
190 | return d->m_propertyNameMap; |
191 | } |
192 | |
193 | QVariant ItemViewPropertySheet::property(int index) const |
194 | { |
195 | const FakePropertyMap::const_iterator it = d->m_propertyIdMap.constFind(akey: index); |
196 | if (it != d->m_propertyIdMap.constEnd()) |
197 | return it.value().m_sheet->property(index: it.value().m_id); |
198 | return QDesignerPropertySheet::property(index); |
199 | } |
200 | |
201 | void ItemViewPropertySheet::setProperty(int index, const QVariant &value) |
202 | { |
203 | const FakePropertyMap::iterator it = d->m_propertyIdMap.find(akey: index); |
204 | if (it != d->m_propertyIdMap.end()) { |
205 | it.value().m_sheet->setProperty(index: it.value().m_id, value); |
206 | } else { |
207 | QDesignerPropertySheet::setProperty(index, value); |
208 | } |
209 | } |
210 | |
211 | void ItemViewPropertySheet::setChanged(int index, bool changed) |
212 | { |
213 | const FakePropertyMap::iterator it = d->m_propertyIdMap.find(akey: index); |
214 | if (it != d->m_propertyIdMap.end()) { |
215 | it.value().m_sheet->setChanged(index: it.value().m_id, changed); |
216 | } else { |
217 | QDesignerPropertySheet::setChanged(index, changed); |
218 | } |
219 | } |
220 | |
221 | bool ItemViewPropertySheet::isChanged(int index) const |
222 | { |
223 | const FakePropertyMap::const_iterator it = d->m_propertyIdMap.constFind(akey: index); |
224 | if (it != d->m_propertyIdMap.constEnd()) |
225 | return it.value().m_sheet->isChanged(index: it.value().m_id); |
226 | return QDesignerPropertySheet::isChanged(index); |
227 | } |
228 | |
229 | bool ItemViewPropertySheet::hasReset(int index) const |
230 | { |
231 | const FakePropertyMap::const_iterator it = d->m_propertyIdMap.constFind(akey: index); |
232 | if (it != d->m_propertyIdMap.constEnd()) |
233 | return it.value().m_sheet->hasReset(index: it.value().m_id); |
234 | return QDesignerPropertySheet::hasReset(index); |
235 | } |
236 | |
237 | bool ItemViewPropertySheet::reset(int index) |
238 | { |
239 | const FakePropertyMap::iterator it = d->m_propertyIdMap.find(akey: index); |
240 | if (it != d->m_propertyIdMap.end()) { |
241 | QDesignerPropertySheetExtension * = it.value().m_sheet; |
242 | const int = it.value().m_id; |
243 | const bool resetRC = headerSheet->reset(index: headerIndex); |
244 | // Resetting for "visible" might fail and the stored default |
245 | // of the Widget database is "false" due to the widget not being |
246 | // visible at the time it was determined. Reset to "true" manually. |
247 | if (!resetRC && headerSheet->propertyName(index: headerIndex) == QLatin1String(visibleProperty)) { |
248 | headerSheet->setProperty(index: headerIndex, value: QVariant(true)); |
249 | headerSheet->setChanged(index: headerIndex, changed: false); |
250 | return true; |
251 | } |
252 | return resetRC; |
253 | } |
254 | return QDesignerPropertySheet::reset(index); |
255 | } |
256 | |
257 | QT_END_NAMESPACE |
258 | |