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

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtdeclarative/src/quicktemplates/qquickpopupitem.cpp