1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
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 http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <qstyle.h>
43 #include <private/qproxystyle_p.h>
44 #include <private/qapplication_p.h>
45 #include "qproxystyle.h"
46 #include "qstylefactory.h"
47 #include <private/qstyle_p.h>
48
49 #if !defined(QT_NO_STYLE_PROXY) || defined(QT_PLUGIN)
50
51 QT_BEGIN_NAMESPACE
52
53 /*!
54 \class QProxyStyle
55
56 \brief The QProxyStyle class is a convenience class that simplifies
57 dynamically overriding QStyle elements.
58
59 \since 4.6
60
61 A QProxyStyle wraps a QStyle (usually the default system style) for the
62 purpose of dynamically overriding painting or other specific style behavior.
63
64 The following example shows how to override the shortcut underline
65 behavior on any platform:
66
67 \snippet doc/src/snippets/code/src_gui_qproxystyle.cpp 1
68
69 Warning: The \l {QCommonStyle} {common styles} provided by Qt will
70 respect this hint, because they call QStyle::proxy(), but there is
71 no guarantee that QStyle::proxy() will be called for user defined
72 or system controlled styles. It would not work on a Mac, for
73 example, where menus are handled by the operating system.
74
75 \sa QStyle
76 */
77
ensureBaseStyle() const78 void QProxyStylePrivate::ensureBaseStyle() const
79 {
80 Q_Q(const QProxyStyle);
81
82 if (baseStyle)
83 return;
84
85 if (!baseStyle && !QApplicationPrivate::styleOverride.isEmpty()) {
86 baseStyle = QStyleFactory::create(QApplicationPrivate::styleOverride);
87 if (baseStyle) {
88 // If baseStyle is an instance of the same proxyStyle
89 // we destroy it and fall back to the desktop style
90 if (qstrcmp(baseStyle->metaObject()->className(),
91 q->metaObject()->className()) == 0) {
92 delete baseStyle;
93 baseStyle = 0;
94 }
95 }
96 }
97
98 if (!baseStyle) // Use application desktop style
99 baseStyle = QStyleFactory::create(QApplicationPrivate::desktopStyleKey());
100
101 if (!baseStyle) // Fallback to windows style
102 baseStyle = QStyleFactory::create(QLatin1String("windows"));
103
104 baseStyle->setProxy(const_cast<QProxyStyle*>(q));
105 baseStyle->setParent(const_cast<QProxyStyle*>(q)); // Take ownership
106 }
107
108 /*!
109 Constructs a QProxyStyle object for overriding behavior in \a style
110 or in the current application \l{QStyle}{style} if \a style is 0
111 (default). Normally \a style is 0, because you want to override
112 behavior in the system style.
113
114 Ownership of \a style is transferred to QProxyStyle.
115 */
QProxyStyle(QStyle * style)116 QProxyStyle::QProxyStyle(QStyle *style) :
117 QCommonStyle(*new QProxyStylePrivate())
118 {
119 Q_D(QProxyStyle);
120 if (style) {
121 style->setProxy(this);
122 style->setParent(this); // Take ownership
123 d->baseStyle = style;
124 }
125 }
126
127 /*!
128 Destroys the QProxyStyle object.
129 */
~QProxyStyle()130 QProxyStyle::~QProxyStyle()
131 {
132 }
133
134 /*!
135 Returns the proxy base style object. If no base style
136 is set on the proxy style, QProxyStyle will create
137 an instance of the application style instead.
138
139 \sa setBaseStyle(), QStyle
140 */
baseStyle() const141 QStyle *QProxyStyle::baseStyle() const
142 {
143 Q_D (const QProxyStyle);
144 d->ensureBaseStyle();
145 return d->baseStyle;
146 }
147
148 /*!
149 Sets the base style that should be proxied.
150
151 Ownership of \a style is transferred to QProxyStyle.
152
153 If style is zero, a desktop-dependant style will be
154 assigned automatically.
155 */
setBaseStyle(QStyle * style)156 void QProxyStyle::setBaseStyle(QStyle *style)
157 {
158 Q_D (QProxyStyle);
159
160 if (d->baseStyle && d->baseStyle->parent() == this)
161 d->baseStyle->deleteLater();
162
163 d->baseStyle = style;
164
165 if (d->baseStyle) {
166 d->baseStyle->setProxy(this);
167 d->baseStyle->setParent(this);
168 }
169 }
170
171 /*! \reimp
172 */
drawPrimitive(PrimitiveElement element,const QStyleOption * option,QPainter * painter,const QWidget * widget) const173 void QProxyStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
174 {
175 Q_D (const QProxyStyle);
176 d->ensureBaseStyle();
177 d->baseStyle->drawPrimitive(element, option, painter, widget);
178 }
179
180 /*!
181 \reimp
182 */
drawControl(ControlElement element,const QStyleOption * option,QPainter * painter,const QWidget * widget) const183 void QProxyStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
184 {
185 Q_D (const QProxyStyle);
186 d->ensureBaseStyle();
187 d->baseStyle->drawControl(element, option, painter, widget);
188 }
189
190 /*! \reimp
191 */
drawComplexControl(ComplexControl control,const QStyleOptionComplex * option,QPainter * painter,const QWidget * widget) const192 void QProxyStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
193 {
194 Q_D (const QProxyStyle);
195 d->ensureBaseStyle();
196 d->baseStyle->drawComplexControl(control, option, painter, widget);
197 }
198
199 /*! \reimp
200 */
drawItemText(QPainter * painter,const QRect & rect,int flags,const QPalette & pal,bool enabled,const QString & text,QPalette::ColorRole textRole) const201 void QProxyStyle::drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled,
202 const QString &text, QPalette::ColorRole textRole) const
203 {
204 Q_D (const QProxyStyle);
205 d->ensureBaseStyle();
206 d->baseStyle->drawItemText(painter, rect, flags, pal, enabled, text, textRole);
207 }
208
209 /*! \reimp
210 */
drawItemPixmap(QPainter * painter,const QRect & rect,int alignment,const QPixmap & pixmap) const211 void QProxyStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const
212 {
213 Q_D (const QProxyStyle);
214 d->ensureBaseStyle();
215 d->baseStyle->drawItemPixmap(painter, rect, alignment, pixmap);
216 }
217
218 /*! \reimp
219 */
sizeFromContents(ContentsType type,const QStyleOption * option,const QSize & size,const QWidget * widget) const220 QSize QProxyStyle::sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const
221 {
222 Q_D (const QProxyStyle);
223 d->ensureBaseStyle();
224 return d->baseStyle->sizeFromContents(type, option, size, widget);
225 }
226
227 /*! \reimp
228 */
subElementRect(SubElement element,const QStyleOption * option,const QWidget * widget) const229 QRect QProxyStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
230 {
231 Q_D (const QProxyStyle);
232 d->ensureBaseStyle();
233 return d->baseStyle->subElementRect(element, option, widget);
234 }
235
236 /*! \reimp
237 */
subControlRect(ComplexControl cc,const QStyleOptionComplex * option,SubControl sc,const QWidget * widget) const238 QRect QProxyStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *option, SubControl sc, const QWidget *widget) const
239 {
240 Q_D (const QProxyStyle);
241 d->ensureBaseStyle();
242 return d->baseStyle->subControlRect(cc, option, sc, widget);
243 }
244
245 /*! \reimp
246 */
itemTextRect(const QFontMetrics & fm,const QRect & r,int flags,bool enabled,const QString & text) const247 QRect QProxyStyle::itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, const QString &text) const
248 {
249 Q_D (const QProxyStyle);
250 d->ensureBaseStyle();
251 return d->baseStyle->itemTextRect(fm, r, flags, enabled, text);
252 }
253
254 /*! \reimp
255 */
itemPixmapRect(const QRect & r,int flags,const QPixmap & pixmap) const256 QRect QProxyStyle::itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const
257 {
258 Q_D (const QProxyStyle);
259 d->ensureBaseStyle();
260 return d->baseStyle->itemPixmapRect(r, flags, pixmap);
261 }
262
263 /*! \reimp
264 */
hitTestComplexControl(ComplexControl control,const QStyleOptionComplex * option,const QPoint & pos,const QWidget * widget) const265 QStyle::SubControl QProxyStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &pos, const QWidget *widget) const
266 {
267 Q_D (const QProxyStyle);
268 d->ensureBaseStyle();
269 return d->baseStyle->hitTestComplexControl(control, option, pos, widget);
270 }
271
272 /*! \reimp
273 */
styleHint(StyleHint hint,const QStyleOption * option,const QWidget * widget,QStyleHintReturn * returnData) const274 int QProxyStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const
275 {
276 Q_D (const QProxyStyle);
277 d->ensureBaseStyle();
278 return d->baseStyle->styleHint(hint, option, widget, returnData);
279 }
280
281 /*! \reimp
282 */
pixelMetric(PixelMetric metric,const QStyleOption * option,const QWidget * widget) const283 int QProxyStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
284 {
285 Q_D (const QProxyStyle);
286 d->ensureBaseStyle();
287 return d->baseStyle->pixelMetric(metric, option, widget);
288 }
289
290 /*! \reimp
291 */
standardPixmap(StandardPixmap standardPixmap,const QStyleOption * opt,const QWidget * widget) const292 QPixmap QProxyStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget) const
293 {
294 Q_D (const QProxyStyle);
295 d->ensureBaseStyle();
296 return d->baseStyle->standardPixmap(standardPixmap, opt, widget);
297 }
298
299 /*! \reimp
300 */
generatedIconPixmap(QIcon::Mode iconMode,const QPixmap & pixmap,const QStyleOption * opt) const301 QPixmap QProxyStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const
302 {
303 Q_D (const QProxyStyle);
304 d->ensureBaseStyle();
305 return d->baseStyle->generatedIconPixmap(iconMode, pixmap, opt);
306 }
307
308 /*! \reimp
309 */
standardPalette() const310 QPalette QProxyStyle::standardPalette() const
311 {
312 Q_D (const QProxyStyle);
313 d->ensureBaseStyle();
314 return d->baseStyle->standardPalette();
315 }
316
317 /*! \reimp
318 */
polish(QWidget * widget)319 void QProxyStyle::polish(QWidget *widget)
320 {
321 Q_D (QProxyStyle);
322 d->ensureBaseStyle();
323 d->baseStyle->polish(widget);
324 }
325
326 /*! \reimp
327 */
polish(QPalette & pal)328 void QProxyStyle::polish(QPalette &pal)
329 {
330 Q_D (QProxyStyle);
331 d->ensureBaseStyle();
332 d->baseStyle->polish(pal);
333 }
334
335 /*! \reimp
336 */
polish(QApplication * app)337 void QProxyStyle::polish(QApplication *app)
338 {
339 Q_D (QProxyStyle);
340 d->ensureBaseStyle();
341 d->baseStyle->polish(app);
342 }
343
344 /*! \reimp
345 */
unpolish(QWidget * widget)346 void QProxyStyle::unpolish(QWidget *widget)
347 {
348 Q_D (QProxyStyle);
349 d->ensureBaseStyle();
350 d->baseStyle->unpolish(widget);
351 }
352
353 /*! \reimp
354 */
unpolish(QApplication * app)355 void QProxyStyle::unpolish(QApplication *app)
356 {
357 Q_D (QProxyStyle);
358 d->ensureBaseStyle();
359 d->baseStyle->unpolish(app);
360 }
361
362 /*! \reimp
363 */
event(QEvent * e)364 bool QProxyStyle::event(QEvent *e)
365 {
366 Q_D (QProxyStyle);
367 d->ensureBaseStyle();
368 return d->baseStyle->event(e);
369 }
370
371 /*!
372 Returns an icon for the given \a standardIcon.
373
374 Reimplement this slot to provide your own icons in a QStyle
375 subclass. The \a option argument can be used to pass extra
376 information required to find the appropriate icon. The \a widget
377 argument is optional and can also be used to help find the icon.
378
379 \note Because of binary compatibility constraints, standardIcon()
380 introduced in Qt 4.1 is not virtual. Therefore it must dynamically
381 detect and call \e this slot. This default implementation simply
382 calls standardIcon() with the given parameters.
383
384 \sa standardIcon()
385 */
standardIconImplementation(StandardPixmap standardIcon,const QStyleOption * option,const QWidget * widget) const386 QIcon QProxyStyle::standardIconImplementation(StandardPixmap standardIcon,
387 const QStyleOption *option,
388 const QWidget *widget) const
389 {
390 Q_D (const QProxyStyle);
391 d->ensureBaseStyle();
392 return d->baseStyle->standardIcon(standardIcon, option, widget);
393 }
394
395 /*!
396 This slot is called by layoutSpacing() to determine the spacing that
397 should be used between \a control1 and \a control2 in a layout. \a
398 orientation specifies whether the controls are laid out side by side
399 or stacked vertically. The \a option parameter can be used to pass
400 extra information about the parent widget. The \a widget parameter
401 is optional and can also be used if \a option is 0.
402
403 The default implementation returns -1.
404
405 \sa layoutSpacing(), combinedLayoutSpacing()
406 */
layoutSpacingImplementation(QSizePolicy::ControlType control1,QSizePolicy::ControlType control2,Qt::Orientation orientation,const QStyleOption * option,const QWidget * widget) const407 int QProxyStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1,
408 QSizePolicy::ControlType control2,
409 Qt::Orientation orientation,
410 const QStyleOption *option,
411 const QWidget *widget) const
412 {
413 Q_D (const QProxyStyle);
414 d->ensureBaseStyle();
415 return d->baseStyle->layoutSpacing(control1, control2, orientation, option, widget);
416 }
417
418 QT_END_NAMESPACE
419
420 #endif // QT_NO_STYLE_PROXY
421