1 | // Copyright (C) 2017 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qquickpopupitem_p_p.h" |
5 | #include "qquickapplicationwindow_p.h" |
6 | #include "qquickpage_p_p.h" |
7 | #include "qquickcontentitem_p.h" |
8 | #include "qquickpopup_p_p.h" |
9 | #include "qquickdeferredexecute_p_p.h" |
10 | |
11 | #if QT_CONFIG(accessibility) |
12 | #include <QtQuick/private/qquickaccessibleattached_p.h> |
13 | #endif |
14 | |
15 | QT_BEGIN_NAMESPACE |
16 | |
17 | Q_LOGGING_CATEGORY(, "qt.quick.controls.popupitem" ) |
18 | |
19 | QQuickPopupItemPrivate::(QQuickPopup *) |
20 | : popup(popup) |
21 | { |
22 | isTabFence = true; |
23 | } |
24 | |
25 | QQuickPopupItemPrivate *QQuickPopupItemPrivate::(QQuickPopupItem *) |
26 | { |
27 | return popupItem->d_func(); |
28 | } |
29 | |
30 | void QQuickPopupItemPrivate::() |
31 | { |
32 | qCDebug(lcPopupItem).nospace() << "implicitWidthChanged called on " << q_func() << "; new implicitWidth is " << implicitWidth; |
33 | QQuickPagePrivate::implicitWidthChanged(); |
34 | emit popup->implicitWidthChanged(); |
35 | } |
36 | |
37 | void QQuickPopupItemPrivate::() |
38 | { |
39 | qCDebug(lcPopupItem).nospace() << "implicitHeightChanged called on " << q_func() << "; new implicitHeight is " << implicitHeight; |
40 | QQuickPagePrivate::implicitHeightChanged(); |
41 | emit popup->implicitHeightChanged(); |
42 | } |
43 | |
44 | void QQuickPopupItemPrivate::() |
45 | { |
46 | if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(object: popup->window())) |
47 | inheritFont(font: window->font()); |
48 | else |
49 | inheritFont(font: QQuickTheme::font(scope: QQuickTheme::System)); |
50 | } |
51 | |
52 | QQuickItem *QQuickPopupItemPrivate::() |
53 | { |
54 | Q_Q(QQuickPopupItem); |
55 | if (QQuickItem *item = QQuickPagePrivate::getContentItem()) |
56 | return item; |
57 | |
58 | return new QQuickContentItem(popup, q); |
59 | } |
60 | |
61 | static inline QString contentItemName() { return QStringLiteral("contentItem" ); } |
62 | |
63 | void QQuickPopupItemPrivate::() |
64 | { |
65 | quickCancelDeferred(object: popup, property: contentItemName()); |
66 | } |
67 | |
68 | void QQuickPopupItemPrivate::(bool complete) |
69 | { |
70 | if (contentItem.wasExecuted()) |
71 | return; |
72 | |
73 | if (!contentItem || complete) |
74 | quickBeginDeferred(object: popup, property: contentItemName(), delegate&: contentItem); |
75 | if (complete) |
76 | quickCompleteDeferred(object: popup, property: contentItemName(), delegate&: contentItem); |
77 | } |
78 | |
79 | void QQuickPopupItemPrivate::() |
80 | { |
81 | quickCancelDeferred(object: popup, property: backgroundName()); |
82 | } |
83 | |
84 | void QQuickPopupItemPrivate::(bool complete) |
85 | { |
86 | if (background.wasExecuted()) |
87 | return; |
88 | |
89 | if (!background || complete) |
90 | quickBeginDeferred(object: popup, property: backgroundName(), delegate&: background); |
91 | if (complete) |
92 | quickCompleteDeferred(object: popup, property: backgroundName(), delegate&: background); |
93 | } |
94 | |
95 | QQuickPopupItem::(QQuickPopup *) |
96 | : QQuickPage(*(new QQuickPopupItemPrivate(popup)), nullptr) |
97 | { |
98 | setParent(popup); |
99 | setFlag(flag: ItemIsFocusScope); |
100 | setAcceptedMouseButtons(Qt::AllButtons); |
101 | #if QT_CONFIG(quicktemplates2_multitouch) |
102 | setAcceptTouchEvents(true); |
103 | #endif |
104 | #if QT_CONFIG(cursor) |
105 | setCursor(Qt::ArrowCursor); |
106 | #endif |
107 | |
108 | connect(sender: popup, signal: &QQuickPopup::paletteChanged, context: this, slot: &QQuickItem::paletteChanged); |
109 | connect(sender: popup, signal: &QQuickPopup::paletteCreated, context: this, slot: &QQuickItem::paletteCreated); |
110 | |
111 | #if QT_CONFIG(quicktemplates2_hover) |
112 | // TODO: switch to QStyleHints::useHoverEffects in Qt 5.8 |
113 | setHoverEnabled(true); |
114 | // setAcceptHoverEvents(QGuiApplication::styleHints()->useHoverEffects()); |
115 | // connect(QGuiApplication::styleHints(), &QStyleHints::useHoverEffectsChanged, this, &QQuickItem::setAcceptHoverEvents); |
116 | #endif |
117 | } |
118 | |
119 | QQuickPalette *QQuickPopupItemPrivate::() const |
120 | { |
121 | return QQuickPopupPrivate::get(popup)->palette(); |
122 | } |
123 | |
124 | void QQuickPopupItemPrivate::(QQuickPalette *p) |
125 | { |
126 | QQuickPopupPrivate::get(popup)->setPalette(p); |
127 | } |
128 | |
129 | void QQuickPopupItemPrivate::() |
130 | { |
131 | QQuickPopupPrivate::get(popup)->resetPalette(); |
132 | } |
133 | |
134 | QPalette QQuickPopupItemPrivate::() const |
135 | { |
136 | return QQuickPopupPrivate::get(popup)->defaultPalette(); |
137 | } |
138 | |
139 | bool QQuickPopupItemPrivate::() const |
140 | { |
141 | return QQuickPopupPrivate::get(popup)->providesPalette(); |
142 | } |
143 | |
144 | QPalette QQuickPopupItemPrivate::(const QPalette &fallbackPalette) const |
145 | { |
146 | return QQuickPopupPrivate::get(popup)->parentPalette(fallbackPalette); |
147 | } |
148 | |
149 | void QQuickPopupItem::() |
150 | { |
151 | Q_D(QQuickPopupItem); |
152 | return QQuickPopupPrivate::get(popup: d->popup)->reposition(); |
153 | } |
154 | |
155 | bool QQuickPopupItem::(QQuickItem *child, QEvent *event) |
156 | { |
157 | Q_D(QQuickPopupItem); |
158 | return d->popup->childMouseEventFilter(child, event); |
159 | } |
160 | |
161 | void QQuickPopupItem::(QFocusEvent *event) |
162 | { |
163 | Q_D(QQuickPopupItem); |
164 | d->popup->focusInEvent(event); |
165 | } |
166 | |
167 | void QQuickPopupItem::(QFocusEvent *event) |
168 | { |
169 | Q_D(QQuickPopupItem); |
170 | d->popup->focusOutEvent(event); |
171 | } |
172 | |
173 | void QQuickPopupItem::(QKeyEvent *event) |
174 | { |
175 | Q_D(QQuickPopupItem); |
176 | d->popup->keyPressEvent(event); |
177 | } |
178 | |
179 | void QQuickPopupItem::(QKeyEvent *event) |
180 | { |
181 | Q_D(QQuickPopupItem); |
182 | d->popup->keyReleaseEvent(event); |
183 | } |
184 | |
185 | void QQuickPopupItem::(QMouseEvent *event) |
186 | { |
187 | Q_D(QQuickPopupItem); |
188 | d->popup->mousePressEvent(event); |
189 | } |
190 | |
191 | void QQuickPopupItem::(QMouseEvent *event) |
192 | { |
193 | Q_D(QQuickPopupItem); |
194 | d->popup->mouseMoveEvent(event); |
195 | } |
196 | |
197 | void QQuickPopupItem::(QMouseEvent *event) |
198 | { |
199 | Q_D(QQuickPopupItem); |
200 | d->popup->mouseReleaseEvent(event); |
201 | } |
202 | |
203 | void QQuickPopupItem::(QMouseEvent *event) |
204 | { |
205 | Q_D(QQuickPopupItem); |
206 | d->popup->mouseDoubleClickEvent(event); |
207 | } |
208 | |
209 | void QQuickPopupItem::() |
210 | { |
211 | Q_D(QQuickPopupItem); |
212 | d->popup->mouseUngrabEvent(); |
213 | } |
214 | |
215 | #if QT_CONFIG(quicktemplates2_multitouch) |
216 | void QQuickPopupItem::(QTouchEvent *event) |
217 | { |
218 | Q_D(QQuickPopupItem); |
219 | d->popup->touchEvent(event); |
220 | } |
221 | |
222 | void QQuickPopupItem::() |
223 | { |
224 | Q_D(QQuickPopupItem); |
225 | d->popup->touchUngrabEvent(); |
226 | } |
227 | #endif |
228 | |
229 | #if QT_CONFIG(wheelevent) |
230 | void QQuickPopupItem::(QWheelEvent *event) |
231 | { |
232 | Q_D(QQuickPopupItem); |
233 | d->popup->wheelEvent(event); |
234 | } |
235 | #endif |
236 | |
237 | void QQuickPopupItem::(QQuickItem *newItem, QQuickItem *oldItem) |
238 | { |
239 | Q_D(QQuickPopupItem); |
240 | QQuickPage::contentItemChange(newItem, oldItem); |
241 | d->popup->contentItemChange(newItem, oldItem); |
242 | } |
243 | |
244 | void QQuickPopupItem::(const QSizeF &newSize, const QSizeF &oldSize) |
245 | { |
246 | Q_D(QQuickPopupItem); |
247 | qCDebug(lcPopupItem) << "contentSizeChange called on" << this << "newSize" << newSize << "oldSize" << oldSize; |
248 | QQuickPage::contentSizeChange(newSize, oldSize); |
249 | d->popup->contentSizeChange(newSize, oldSize); |
250 | } |
251 | |
252 | void QQuickPopupItem::(const QFont &newFont, const QFont &oldFont) |
253 | { |
254 | Q_D(QQuickPopupItem); |
255 | QQuickPage::fontChange(newFont, oldFont); |
256 | d->popup->fontChange(newFont, oldFont); |
257 | } |
258 | |
259 | void QQuickPopupItem::(const QRectF &newGeometry, const QRectF &oldGeometry) |
260 | { |
261 | Q_D(QQuickPopupItem); |
262 | qCDebug(lcPopupItem) << "geometryChange called on" << this << "newGeometry" << newGeometry << "oldGeometry" << oldGeometry; |
263 | QQuickPage::geometryChange(newGeometry, oldGeometry); |
264 | d->popup->geometryChange(newGeometry, oldGeometry); |
265 | } |
266 | |
267 | void QQuickPopupItem::(const QLocale &newLocale, const QLocale &oldLocale) |
268 | { |
269 | Q_D(QQuickPopupItem); |
270 | QQuickPage::localeChange(newLocale, oldLocale); |
271 | d->popup->localeChange(newLocale, oldLocale); |
272 | } |
273 | |
274 | void QQuickPopupItem::() |
275 | { |
276 | Q_D(QQuickPopupItem); |
277 | emit d->popup->mirroredChanged(); |
278 | } |
279 | |
280 | void QQuickPopupItem::(ItemChange change, const ItemChangeData &data) |
281 | { |
282 | Q_D(QQuickPopupItem); |
283 | QQuickPage::itemChange(change, value: data); |
284 | d->popup->itemChange(change, data); |
285 | } |
286 | |
287 | void QQuickPopupItem::(const QMarginsF &newPadding, const QMarginsF &oldPadding) |
288 | { |
289 | Q_D(QQuickPopupItem); |
290 | QQuickPage::paddingChange(newPadding, oldPadding); |
291 | d->popup->paddingChange(newPadding, oldPadding); |
292 | } |
293 | |
294 | void QQuickPopupItem::() |
295 | { |
296 | Q_D(QQuickPopupItem); |
297 | // Just having QQuickPopup connect our QQuickItem::enabledChanged() signal |
298 | // to its enabledChanged() signal is enough for the enabled property to work, |
299 | // but we must also ensure that its paletteChanged() signal is emitted |
300 | // so that bindings to palette are re-evaluated, because QQuickControl::palette() |
301 | // returns a different palette depending on whether or not the control is enabled. |
302 | // To save a connection, we also emit enabledChanged here. |
303 | emit d->popup->enabledChanged(); |
304 | } |
305 | |
306 | QFont QQuickPopupItem::() const |
307 | { |
308 | Q_D(const QQuickPopupItem); |
309 | return d->popup->defaultFont(); |
310 | } |
311 | |
312 | #if QT_CONFIG(accessibility) |
313 | QAccessible::Role QQuickPopupItem::() const |
314 | { |
315 | Q_D(const QQuickPopupItem); |
316 | return d->popup->effectiveAccessibleRole(); |
317 | } |
318 | |
319 | void QQuickPopupItem::(bool active) |
320 | { |
321 | Q_D(const QQuickPopupItem); |
322 | // Can't just use d->popup->accessibleName() here, because that refers to the accessible |
323 | // name of us, the popup item, which is not what we want. |
324 | const QQuickAccessibleAttached * = QQuickControlPrivate::accessibleAttached(object: d->popup); |
325 | const QString = popupAccessibleAttached ? popupAccessibleAttached->name() : QString(); |
326 | const bool = popupAccessibleAttached && popupAccessibleAttached->wasNameExplicitlySet(); |
327 | |
328 | QQuickPage::accessibilityActiveChanged(active); |
329 | |
330 | QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(object: this); |
331 | const QString ourName = accessibleAttached ? accessibleAttached->name() : QString(); |
332 | if (wasNameExplicitlySetOnPopup && accessibleAttached && ourName != oldPopupName) { |
333 | // The user set Accessible.name on the Popup. Since the Popup and its popup item |
334 | // have different accessible attached properties, the popup item doesn't know that |
335 | // a name was set on the Popup by the user, and that it should use that, rather than |
336 | // whatever QQuickPage sets. That's why we need to do it here. |
337 | // To avoid it being overridden by the call to accessibilityActiveChanged() below, |
338 | // we set it explicitly. It's safe to do this as the popup item is an internal implementation detail. |
339 | accessibleAttached->setName(oldPopupName); |
340 | } |
341 | |
342 | // This allows the different popup types to set a name on their popup item accordingly. |
343 | // For example: Dialog uses its title and ToolTip uses its text. |
344 | d->popup->accessibilityActiveChanged(active); |
345 | } |
346 | #endif |
347 | |
348 | QT_END_NAMESPACE |
349 | |
350 | #include "moc_qquickpopupitem_p_p.cpp" |
351 | |