1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** All rights reserved.
|
---|
5 | ** Contact: Nokia Corporation ([email protected])
|
---|
6 | **
|
---|
7 | ** This file is part of the QtGui module of the Qt Toolkit.
|
---|
8 | **
|
---|
9 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
10 | ** Commercial Usage
|
---|
11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
14 | ** a written agreement between you and Nokia.
|
---|
15 | **
|
---|
16 | ** GNU Lesser General Public License Usage
|
---|
17 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
---|
18 | ** General Public License version 2.1 as published by the Free Software
|
---|
19 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
---|
20 | ** packaging of this file. Please review the following information to
|
---|
21 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
---|
22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
---|
23 | **
|
---|
24 | ** In addition, as a special exception, Nokia gives you certain additional
|
---|
25 | ** rights. These rights are described in the Nokia Qt LGPL Exception
|
---|
26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
---|
27 | **
|
---|
28 | ** GNU General Public License Usage
|
---|
29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
30 | ** General Public License version 3.0 as published by the Free Software
|
---|
31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
32 | ** packaging of this file. Please review the following information to
|
---|
33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
35 | **
|
---|
36 | ** If you have questions regarding the use of this file, please contact
|
---|
37 | ** Nokia at [email protected].
|
---|
38 | ** $QT_END_LICENSE$
|
---|
39 | **
|
---|
40 | ****************************************************************************/
|
---|
41 |
|
---|
42 | #include <qstyle.h>
|
---|
43 | #include <private/qstyle_p.h>
|
---|
44 | #include <private/qproxystyle_p.h>
|
---|
45 | #include <private/qapplication_p.h>
|
---|
46 | #include "qproxystyle.h"
|
---|
47 | #include "qstylefactory.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 |
|
---|
78 | 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 | */
|
---|
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 | */
|
---|
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 | */
|
---|
141 | 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 | */
|
---|
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 | */
|
---|
173 | 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 | */
|
---|
183 | 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 | */
|
---|
192 | 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 | */
|
---|
201 | 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 | */
|
---|
211 | 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 | */
|
---|
220 | 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 | */
|
---|
229 | 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 | */
|
---|
238 | 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 | */
|
---|
247 | 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 | */
|
---|
256 | 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 | */
|
---|
265 | 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 | */
|
---|
274 | 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 | */
|
---|
283 | 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 | */
|
---|
292 | 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 | */
|
---|
301 | 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 | */
|
---|
310 | QPalette QProxyStyle::standardPalette() const
|
---|
311 | {
|
---|
312 | Q_D (const QProxyStyle);
|
---|
313 | d->ensureBaseStyle();
|
---|
314 | return d->baseStyle->standardPalette();
|
---|
315 | }
|
---|
316 |
|
---|
317 | /*! \reimp
|
---|
318 | */
|
---|
319 | void QProxyStyle::polish(QWidget *widget)
|
---|
320 | {
|
---|
321 | Q_D (QProxyStyle);
|
---|
322 | d->ensureBaseStyle();
|
---|
323 | d->baseStyle->polish(widget);
|
---|
324 | }
|
---|
325 |
|
---|
326 | /*! \reimp
|
---|
327 | */
|
---|
328 | void QProxyStyle::polish(QPalette &pal)
|
---|
329 | {
|
---|
330 | Q_D (QProxyStyle);
|
---|
331 | d->ensureBaseStyle();
|
---|
332 | d->baseStyle->polish(pal);
|
---|
333 | }
|
---|
334 |
|
---|
335 | /*! \reimp
|
---|
336 | */
|
---|
337 | void QProxyStyle::polish(QApplication *app)
|
---|
338 | {
|
---|
339 | Q_D (QProxyStyle);
|
---|
340 | d->ensureBaseStyle();
|
---|
341 | d->baseStyle->polish(app);
|
---|
342 | }
|
---|
343 |
|
---|
344 | /*! \reimp
|
---|
345 | */
|
---|
346 | void QProxyStyle::unpolish(QWidget *widget)
|
---|
347 | {
|
---|
348 | Q_D (QProxyStyle);
|
---|
349 | d->ensureBaseStyle();
|
---|
350 | d->baseStyle->unpolish(widget);
|
---|
351 | }
|
---|
352 |
|
---|
353 | /*! \reimp
|
---|
354 | */
|
---|
355 | void QProxyStyle::unpolish(QApplication *app)
|
---|
356 | {
|
---|
357 | Q_D (QProxyStyle);
|
---|
358 | d->ensureBaseStyle();
|
---|
359 | d->baseStyle->unpolish(app);
|
---|
360 | }
|
---|
361 |
|
---|
362 | /*! \reimp
|
---|
363 | */
|
---|
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 | */
|
---|
386 | 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 | */
|
---|
407 | 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
|
---|