src/gui/styles/qproxystyle.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    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