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