Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qproxystyle.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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// Qt-Security score:significant reason:default
4
5#include <qstyle.h>
6#include <private/qproxystyle_p.h>
7#include <private/qapplication_p.h>
8#include "qproxystyle.h"
10#include <private/qstyle_p.h>
11
12#if !defined(QT_NO_STYLE_PROXY) || defined(QT_PLUGIN)
13
15
16using namespace Qt::StringLiterals;
17
18/*!
19 \class QProxyStyle
20
21 \brief The QProxyStyle class is a convenience class that simplifies
22 dynamically overriding QStyle elements.
23
24 \since 4.6
25
26 \inmodule QtWidgets
27
28 A QProxyStyle wraps a QStyle (usually the default system style) for the
29 purpose of dynamically overriding painting or other specific style behavior.
30
31 The following example shows how to override the shortcut underline
32 behavior on any platform:
33
34 \snippet code/src_gui_qproxystyle.cpp 1
35
36 Warning: The \l {QCommonStyle} {common styles} provided by Qt will
37 respect this hint, because they call QStyle::proxy(), but there is
38 no guarantee that QStyle::proxy() will be called for user defined
39 or system controlled styles. It would not work on a Mac, for
40 example, where menus are handled by the operating system.
41
42 When a proxy style should be set on a specific widget only, you have
43 to make sure to not set the proxy on the global application style which
44 is returned by QWidget::style(). You have to create a separate custom style
45 for the widget similar to:
46
47 \snippet code/src_gui_qproxystyle.cpp 2
48
49 \sa QStyle
50*/
51
52void QProxyStylePrivate::ensureBaseStyle() const
53{
54 Q_Q(const QProxyStyle);
55
56 if (baseStyle)
57 return;
58
59 if (!baseStyle && !QApplicationPrivate::styleOverride.isEmpty()) {
60 baseStyle = QStyleFactory::create(QApplicationPrivate::styleOverride);
61 if (baseStyle) {
62 // If baseStyle is an instance of the same proxyStyle
63 // we destroy it and fall back to the desktop style
64 if (qstrcmp(baseStyle->metaObject()->className(),
65 q->metaObject()->className()) == 0) {
66 delete baseStyle;
67 baseStyle = nullptr;
68 }
69 }
70 }
71
72 if (!baseStyle) // Use application desktop style
73 baseStyle = QStyleFactory::create(QApplicationPrivate::desktopStyleKey());
74
75 if (!baseStyle) // Fallback to windows style
76 baseStyle = QStyleFactory::create("windows"_L1);
77
78 baseStyle->setProxy(const_cast<QProxyStyle*>(q));
79 baseStyle->setParent(const_cast<QProxyStyle*>(q)); // Take ownership
80}
81
82/*!
83 Constructs a QProxyStyle object for overriding behavior in the
84 specified \a style, or in the default native \l{QApplication::style()}
85 {style} if \a style is not specified.
86
87 Ownership of \a style is transferred to QProxyStyle.
88*/
89QProxyStyle::QProxyStyle(QStyle *style) :
90 QCommonStyle(*new QProxyStylePrivate())
91{
92 Q_D(QProxyStyle);
93 if (style) {
94 d->baseStyle = style;
95 style->setProxy(this);
96 style->setParent(this); // Take ownership
97 }
98}
99
100/*!
101 Constructs a QProxyStyle object for overriding behavior in
102 the base style specified by style \a key, or in the current
103 \l{QApplication::style()}{application style} if the specified
104 style \a key is unrecognized.
105
106 \sa QStyleFactory::create()
107*/
108QProxyStyle::QProxyStyle(const QString &key)
109 : QProxyStyle(QStyleFactory::create(key))
110{
111}
112
113/*!
114 Destroys the QProxyStyle object.
115*/
116QProxyStyle::~QProxyStyle()
117{
118}
119
120/*!
121 Returns the proxy base style object. If no base style
122 is set on the proxy style, QProxyStyle will create
123 an instance of the application style instead.
124
125 \sa setBaseStyle(), QStyle
126*/
127QStyle *QProxyStyle::baseStyle() const
128{
129 Q_D (const QProxyStyle);
130 d->ensureBaseStyle();
131 return d->baseStyle;
132}
133
134/*!
135 Sets the base style that should be proxied.
136
137 Ownership of \a style is transferred to QProxyStyle.
138
139 If style is \nullptr, a desktop-dependent style will be
140 assigned automatically.
141*/
142void QProxyStyle::setBaseStyle(QStyle *style)
143{
144 Q_D (QProxyStyle);
145
146 if (d->baseStyle && d->baseStyle->parent() == this)
147 d->baseStyle->deleteLater();
148
149 d->baseStyle = style;
150
151 if (d->baseStyle) {
152 d->baseStyle->setProxy(this);
153 d->baseStyle->setParent(this);
154 }
155}
156
157/*! \reimp
158 */
159void QProxyStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
160{
161 Q_D (const QProxyStyle);
162 d->ensureBaseStyle();
163 d->baseStyle->drawPrimitive(element, option, painter, widget);
164}
165
166/*!
167 \reimp
168 */
169void QProxyStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
170{
171 Q_D (const QProxyStyle);
172 d->ensureBaseStyle();
173 d->baseStyle->drawControl(element, option, painter, widget);
174}
175
176/*! \reimp
177 */
178void QProxyStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
179{
180 Q_D (const QProxyStyle);
181 d->ensureBaseStyle();
182 d->baseStyle->drawComplexControl(control, option, painter, widget);
183}
184
185/*! \reimp
186 */
187void QProxyStyle::drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled,
188 const QString &text, QPalette::ColorRole textRole) const
189{
190 Q_D (const QProxyStyle);
191 d->ensureBaseStyle();
192 d->baseStyle->drawItemText(painter, rect, flags, pal, enabled, text, textRole);
193}
194
195/*! \reimp
196 */
197void QProxyStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const
198{
199 Q_D (const QProxyStyle);
200 d->ensureBaseStyle();
201 d->baseStyle->drawItemPixmap(painter, rect, alignment, pixmap);
202}
203
204/*! \reimp
205 */
206QSize QProxyStyle::sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const
207{
208 Q_D (const QProxyStyle);
209 d->ensureBaseStyle();
210 return d->baseStyle->sizeFromContents(type, option, size, widget);
211}
212
213/*! \reimp
214 */
215QRect QProxyStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
216{
217 Q_D (const QProxyStyle);
218 d->ensureBaseStyle();
219 return d->baseStyle->subElementRect(element, option, widget);
220}
221
222/*! \reimp
223 */
224QRect QProxyStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *option, SubControl sc, const QWidget *widget) const
225{
226 Q_D (const QProxyStyle);
227 d->ensureBaseStyle();
228 return d->baseStyle->subControlRect(cc, option, sc, widget);
229}
230
231/*! \reimp
232 */
233QRect QProxyStyle::itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, const QString &text) const
234{
235 Q_D (const QProxyStyle);
236 d->ensureBaseStyle();
237 return d->baseStyle->itemTextRect(fm, r, flags, enabled, text);
238}
239
240/*! \reimp
241 */
242QRect QProxyStyle::itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const
243{
244 Q_D (const QProxyStyle);
245 d->ensureBaseStyle();
246 return d->baseStyle->itemPixmapRect(r, flags, pixmap);
247}
248
249/*! \reimp
250 */
251QStyle::SubControl QProxyStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &pos, const QWidget *widget) const
252{
253 Q_D (const QProxyStyle);
254 d->ensureBaseStyle();
255 return d->baseStyle->hitTestComplexControl(control, option, pos, widget);
256}
257
258/*! \reimp
259 */
260int QProxyStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const
261{
262 Q_D (const QProxyStyle);
263 d->ensureBaseStyle();
264 return d->baseStyle->styleHint(hint, option, widget, returnData);
265}
266
267/*! \reimp
268 */
269int QProxyStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
270{
271 Q_D (const QProxyStyle);
272 d->ensureBaseStyle();
273 return d->baseStyle->pixelMetric(metric, option, widget);
274}
275
276/*! \reimp
277 */
278QPixmap QProxyStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget) const
279{
280 Q_D (const QProxyStyle);
281 d->ensureBaseStyle();
282 return d->baseStyle->standardPixmap(standardPixmap, opt, widget);
283}
284
285/*! \reimp
286 */
287QPixmap QProxyStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const
288{
289 Q_D (const QProxyStyle);
290 d->ensureBaseStyle();
291 return d->baseStyle->generatedIconPixmap(iconMode, pixmap, opt);
292}
293
294/*! \reimp
295 */
296QPalette QProxyStyle::standardPalette() const
297{
298 Q_D (const QProxyStyle);
299 d->ensureBaseStyle();
300 return d->baseStyle->standardPalette();
301}
302
303/*! \reimp
304 */
305void QProxyStyle::polish(QWidget *widget)
306{
307 Q_D (QProxyStyle);
308 d->ensureBaseStyle();
309 d->baseStyle->polish(widget);
310}
311
312/*! \reimp
313 */
314void QProxyStyle::polish(QPalette &pal)
315{
316 Q_D (QProxyStyle);
317 d->ensureBaseStyle();
318 d->baseStyle->polish(pal);
319}
320
321/*! \reimp
322 */
323void QProxyStyle::polish(QApplication *app)
324{
325 Q_D (QProxyStyle);
326 d->ensureBaseStyle();
327 d->baseStyle->polish(app);
328}
329
330/*! \reimp
331 */
332void QProxyStyle::unpolish(QWidget *widget)
333{
334 Q_D (QProxyStyle);
335 d->ensureBaseStyle();
336 d->baseStyle->unpolish(widget);
337}
338
339/*! \reimp
340 */
341void QProxyStyle::unpolish(QApplication *app)
342{
343 Q_D (QProxyStyle);
344 d->ensureBaseStyle();
345 d->baseStyle->unpolish(app);
346}
347
348/*! \reimp
349 */
350bool QProxyStyle::event(QEvent *e)
351{
352 Q_D (QProxyStyle);
353
354 switch (e->type()) {
355 // The Mac style relies on these events in order to set the focus frame
356 case QEvent::FocusIn:
357 case QEvent::FocusOut:
358 d->ensureBaseStyle();
359 return QApplication::sendEvent(d->baseStyle, e);
360 default:
361 break;
362 }
363
364 return QCommonStyle::event(e);
365}
366
367/*!
368 Returns an icon for the given \a standardIcon.
369
370 Reimplement this slot to provide your own icons in a QStyle
371 subclass. The \a option argument can be used to pass extra
372 information required to find the appropriate icon. The \a widget
373 argument is optional and can also be used to help find the icon.
374 */
375QIcon QProxyStyle::standardIcon(StandardPixmap standardIcon,
376 const QStyleOption *option,
377 const QWidget *widget) const
378{
379 Q_D (const QProxyStyle);
380 d->ensureBaseStyle();
381 return d->baseStyle->standardIcon(standardIcon, option, widget);
382}
383
384/*!
385 This slot is called by layoutSpacing() to determine the spacing that
386 should be used between \a control1 and \a control2 in a layout. \a
387 orientation specifies whether the controls are laid out side by side
388 or stacked vertically. The \a option parameter can be used to pass
389 extra information about the parent widget. The \a widget parameter
390 is optional and can also be used if \a option is \nullptr.
391
392 The default implementation returns -1.
393
394 \sa combinedLayoutSpacing()
395 */
396int QProxyStyle::layoutSpacing(QSizePolicy::ControlType control1,
397 QSizePolicy::ControlType control2,
398 Qt::Orientation orientation,
399 const QStyleOption *option,
400 const QWidget *widget) const
401{
402 Q_D (const QProxyStyle);
403 d->ensureBaseStyle();
404 return d->baseStyle->layoutSpacing(control1, control2, orientation, option, widget);
405}
406
407QT_END_NAMESPACE
408
409#include "moc_qproxystyle.cpp"
410
411#endif // QT_NO_STYLE_PROXY