src/gui/styles/qs60style.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
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 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 "qs60style_p.h"
       
    43 
       
    44 #include "qapplication.h"
       
    45 #include "qpainter.h"
       
    46 #include "qstyleoption.h"
       
    47 #include "qevent.h"
       
    48 #include "qpixmapcache.h"
       
    49 
       
    50 #include "qcalendarwidget.h"
       
    51 #include "qdial.h"
       
    52 #include "qdialog.h"
       
    53 #include "qgroupbox.h"
       
    54 #include "qheaderview.h"
       
    55 #include "qlist.h"
       
    56 #include "qlistwidget.h"
       
    57 #include "qlistview.h"
       
    58 #include "qmenu.h"
       
    59 #include "qmenubar.h"
       
    60 #include "qpushbutton.h"
       
    61 #include "qscrollarea.h"
       
    62 #include "qscrollbar.h"
       
    63 #include "qtabbar.h"
       
    64 #include "qtablewidget.h"
       
    65 #include "qtableview.h"
       
    66 #include "qtextedit.h"
       
    67 #include "qtoolbar.h"
       
    68 #include "qtoolbutton.h"
       
    69 #include "qtreeview.h"
       
    70 #include "qfocusframe.h"
       
    71 
       
    72 #include "private/qtoolbarextension_p.h"
       
    73 #include "private/qcombobox_p.h"
       
    74 #include "private/qwidget_p.h"
       
    75 #include "private/qapplication_p.h"
       
    76 
       
    77 #if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN)
       
    78 
       
    79 QT_BEGIN_NAMESPACE
       
    80 
       
    81 // from text/qfont.cpp
       
    82 extern Q_GUI_EXPORT int qt_defaultDpiY();
       
    83 
       
    84 const QS60StylePrivate::SkinElementFlags QS60StylePrivate::KDefaultSkinElementFlags =
       
    85     SkinElementFlags(SF_PointNorth | SF_StateEnabled);
       
    86 
       
    87 static const QByteArray propertyKeyLayouts = "layouts";
       
    88 static const QByteArray propertyKeyCurrentlayout = "currentlayout";
       
    89 
       
    90 static const qreal goldenRatio = 1.618;
       
    91 
       
    92 const layoutHeader QS60StylePrivate::m_layoutHeaders[] = {
       
    93 // *** generated layout data ***
       
    94 {240,320,1,14,true,"QVGA Landscape Mirrored"},
       
    95 {240,320,1,14,false,"QVGA Landscape"},
       
    96 {320,240,1,14,true,"QVGA Portrait Mirrored"},
       
    97 {320,240,1,14,false,"QVGA Portrait"},
       
    98 {360,640,1,14,true,"NHD Landscape Mirrored"},
       
    99 {360,640,1,14,false,"NHD Landscape"},
       
   100 {640,360,1,14,true,"NHD Portrait Mirrored"},
       
   101 {640,360,1,14,false,"NHD Portrait"},
       
   102 {352,800,1,12,true,"E90 Landscape Mirrored"},
       
   103 {352,800,1,12,false,"E90 Landscape"}
       
   104 // *** End of generated data ***
       
   105 };
       
   106 const int QS60StylePrivate::m_numberOfLayouts =
       
   107     (int)sizeof(QS60StylePrivate::m_layoutHeaders)/sizeof(QS60StylePrivate::m_layoutHeaders[0]);
       
   108 
       
   109 const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = {
       
   110 // *** generated pixel metrics ***
       
   111 {5,0,-909,0,0,1,0,0,-1,8,15,22,15,15,7,198,-909,-909,-909,19,15,2,0,0,21,-909,21,-909,4,4,1,-909,-909,0,2,0,0,13,23,17,17,21,21,2,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,51,27,51,4,4,5,10,15,-909,5,58,12,5,0,7,4,4,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1},
       
   112 {5,0,-909,0,0,1,0,0,-1,8,15,22,15,15,7,198,-909,-909,-909,19,15,2,0,0,21,-909,21,-909,4,4,1,-909,-909,0,2,0,0,13,23,17,17,21,21,2,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,51,27,51,4,4,5,10,15,-909,5,58,12,5,0,4,4,7,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1},
       
   113 {5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,-909,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,7,4,4,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1},
       
   114 {5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,-909,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1},
       
   115 {7,0,-909,0,0,2,0,0,-1,20,53,28,19,19,9,258,-909,-909,-909,29,19,26,0,0,32,-909,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,8,5,5,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1},
       
   116 {7,0,-909,0,0,2,0,0,-1,20,53,28,19,19,9,258,-909,-909,-909,29,19,26,0,0,32,-909,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1},
       
   117 {7,0,-909,0,0,2,0,0,-1,20,52,28,19,19,9,258,-909,-909,-909,29,19,6,0,0,32,-909,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,98,35,98,5,5,6,8,19,-909,7,74,22,7,0,8,5,5,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1},
       
   118 {7,0,-909,0,0,2,0,0,-1,20,52,28,19,19,9,258,-909,-909,-909,29,19,6,0,0,32,-909,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,98,35,98,5,5,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1},
       
   119 {7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,-909,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,5,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,8,6,5,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1},
       
   120 {7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,-909,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1}
       
   121 // *** End of generated data ***
       
   122 };
       
   123 
       
   124 const short *QS60StylePrivate::m_pmPointer = QS60StylePrivate::data[0];
       
   125 
       
   126 // theme background texture
       
   127 QPixmap *QS60StylePrivate::m_background = 0;
       
   128 
       
   129 // theme palette
       
   130 QPalette *QS60StylePrivate::m_themePalette = 0;
       
   131 
       
   132 const struct QS60StylePrivate::frameElementCenter QS60StylePrivate::m_frameElementsData[] = {
       
   133     {SE_ButtonNormal,           QS60StyleEnums::SP_QsnFrButtonTbCenter},
       
   134     {SE_ButtonPressed,          QS60StyleEnums::SP_QsnFrButtonTbCenterPressed},
       
   135     {SE_FrameLineEdit,          QS60StyleEnums::SP_QsnFrInputCenter},
       
   136     {SE_ListHighlight,          QS60StyleEnums::SP_QsnFrListCenter},
       
   137     {SE_OptionsMenu,            QS60StyleEnums::SP_QsnFrPopupCenter},
       
   138     {SE_SettingsList,           QS60StyleEnums::SP_QsnFrSetOptCenter},
       
   139     {SE_TableItem,              QS60StyleEnums::SP_QsnFrCaleCenter},
       
   140     {SE_TableHeaderItem,        QS60StyleEnums::SP_QsnFrCaleHeadingCenter},
       
   141     {SE_ToolTip,                QS60StyleEnums::SP_QsnFrPopupPreviewCenter},
       
   142     {SE_ToolBar,                QS60StyleEnums::SP_QsnFrPopupSubCenter},
       
   143     {SE_ToolBarButton,          QS60StyleEnums::SP_QsnFrSctrlButtonCenter},
       
   144     {SE_ToolBarButtonPressed,   QS60StyleEnums::SP_QsnFrSctrlButtonCenterPressed},
       
   145     {SE_PanelBackground,        QS60StyleEnums::SP_QsnFrSetOptCenter},
       
   146     {SE_ButtonInactive,         QS60StyleEnums::SP_QsnFrButtonCenterInactive},
       
   147     {SE_Editor,                 QS60StyleEnums::SP_QsnFrNotepadCenter},
       
   148 };
       
   149 
       
   150 static const int frameElementsCount =
       
   151     int(sizeof(QS60StylePrivate::m_frameElementsData)/sizeof(QS60StylePrivate::m_frameElementsData[0]));
       
   152 
       
   153 const int KNotFound = -909;
       
   154 const double KTabFontMul = 0.72;
       
   155 
       
   156 QS60StylePrivate::~QS60StylePrivate()
       
   157 {
       
   158     clearCaches(); //deletes also background image
       
   159     deleteThemePalette();
       
   160 }
       
   161 
       
   162 void QS60StylePrivate::drawSkinElement(SkinElements element, QPainter *painter,
       
   163     const QRect &rect, SkinElementFlags flags)
       
   164 {
       
   165     switch (element) {
       
   166     case SE_ButtonNormal:
       
   167         drawFrame(SF_ButtonNormal, painter, rect, flags | SF_PointNorth);
       
   168         break;
       
   169     case SE_ButtonPressed:
       
   170         drawFrame(SF_ButtonPressed, painter, rect, flags | SF_PointNorth);
       
   171         break;
       
   172     case SE_FrameLineEdit:
       
   173         drawFrame(SF_FrameLineEdit, painter, rect, flags | SF_PointNorth);
       
   174         break;
       
   175     case SE_ProgressBarGrooveHorizontal:
       
   176         drawRow(QS60StyleEnums::SP_QgnGrafBarFrameSideL, QS60StyleEnums::SP_QgnGrafBarFrameCenter,
       
   177             QS60StyleEnums::SP_QgnGrafBarFrameSideR, Qt::Horizontal, painter, rect, flags | SF_PointNorth);
       
   178         break;
       
   179     case SE_ProgressBarGrooveVertical:
       
   180         drawRow(QS60StyleEnums::SP_QgnGrafBarFrameSideL, QS60StyleEnums::SP_QgnGrafBarFrameCenter,
       
   181             QS60StyleEnums::SP_QgnGrafBarFrameSideR, Qt::Vertical, painter, rect, flags | SF_PointEast);
       
   182         break;
       
   183     case SE_ProgressBarIndicatorHorizontal:
       
   184         drawPart(QS60StyleEnums::SP_QgnGrafBarProgress, painter, rect, flags | SF_PointNorth);
       
   185         break;
       
   186     case SE_ProgressBarIndicatorVertical:
       
   187         drawPart(QS60StyleEnums::SP_QgnGrafBarProgress, painter, rect, flags | SF_PointWest);
       
   188         break;
       
   189     case SE_ScrollBarGrooveHorizontal:
       
   190         drawRow(QS60StyleEnums::SP_QsnCpScrollBgBottom, QS60StyleEnums::SP_QsnCpScrollBgMiddle,
       
   191             QS60StyleEnums::SP_QsnCpScrollBgTop, Qt::Horizontal, painter, rect, flags | SF_PointEast);
       
   192         break;
       
   193     case SE_ScrollBarGrooveVertical:
       
   194         drawRow(QS60StyleEnums::SP_QsnCpScrollBgTop, QS60StyleEnums::SP_QsnCpScrollBgMiddle,
       
   195             QS60StyleEnums::SP_QsnCpScrollBgBottom, Qt::Vertical, painter, rect, flags | SF_PointNorth);
       
   196         break;
       
   197     case SE_ScrollBarHandleHorizontal:
       
   198         drawRow(QS60StyleEnums::SP_QsnCpScrollHandleBottom, QS60StyleEnums::SP_QsnCpScrollHandleMiddle,
       
   199             QS60StyleEnums::SP_QsnCpScrollHandleTop, Qt::Horizontal, painter, rect, flags | SF_PointEast);
       
   200         break;
       
   201     case SE_ScrollBarHandleVertical:
       
   202         drawRow(QS60StyleEnums::SP_QsnCpScrollHandleTop, QS60StyleEnums::SP_QsnCpScrollHandleMiddle,
       
   203             QS60StyleEnums::SP_QsnCpScrollHandleBottom, Qt::Vertical, painter, rect, flags | SF_PointNorth);
       
   204         break;
       
   205     case SE_SliderHandleHorizontal:
       
   206         drawPart(QS60StyleEnums::SP_QgnIndiSliderEdit, painter, rect, flags | SF_PointNorth);
       
   207         break;
       
   208     case SE_SliderHandleVertical:
       
   209         drawPart(QS60StyleEnums::SP_QgnIndiSliderEdit, painter, rect, flags | SF_PointEast);
       
   210         break;
       
   211     case SE_TabBarTabEastActive:
       
   212         drawRow(QS60StyleEnums::SP_QgnGrafTabActiveL, QS60StyleEnums::SP_QgnGrafTabActiveM,
       
   213             QS60StyleEnums::SP_QgnGrafTabActiveR, Qt::Vertical, painter, rect, flags | SF_PointEast);
       
   214         break;
       
   215     case SE_TabBarTabEastInactive:
       
   216         drawRow(QS60StyleEnums::SP_QgnGrafTabPassiveL, QS60StyleEnums::SP_QgnGrafTabPassiveM,
       
   217             QS60StyleEnums::SP_QgnGrafTabPassiveR, Qt::Vertical, painter, rect, flags | SF_PointEast);
       
   218         break;
       
   219     case SE_TabBarTabNorthActive:
       
   220         drawRow(QS60StyleEnums::SP_QgnGrafTabActiveL, QS60StyleEnums::SP_QgnGrafTabActiveM,
       
   221             QS60StyleEnums::SP_QgnGrafTabActiveR, Qt::Horizontal, painter, rect, flags | SF_PointNorth);
       
   222         break;
       
   223     case SE_TabBarTabNorthInactive:
       
   224         drawRow(QS60StyleEnums::SP_QgnGrafTabPassiveL, QS60StyleEnums::SP_QgnGrafTabPassiveM,
       
   225             QS60StyleEnums::SP_QgnGrafTabPassiveR, Qt::Horizontal, painter, rect, flags | SF_PointNorth);
       
   226         break;
       
   227     case SE_TabBarTabSouthActive:
       
   228         drawRow(QS60StyleEnums::SP_QgnGrafTabActiveR, QS60StyleEnums::SP_QgnGrafTabActiveM,
       
   229             QS60StyleEnums::SP_QgnGrafTabActiveL, Qt::Horizontal, painter, rect, flags | SF_PointSouth);
       
   230         break;
       
   231     case SE_TabBarTabSouthInactive:
       
   232         drawRow(QS60StyleEnums::SP_QgnGrafTabPassiveR, QS60StyleEnums::SP_QgnGrafTabPassiveM,
       
   233             QS60StyleEnums::SP_QgnGrafTabPassiveL, Qt::Horizontal, painter, rect, flags | SF_PointSouth);
       
   234         break;
       
   235     case SE_TabBarTabWestActive:
       
   236         drawRow(QS60StyleEnums::SP_QgnGrafTabActiveR, QS60StyleEnums::SP_QgnGrafTabActiveM,
       
   237             QS60StyleEnums::SP_QgnGrafTabActiveL, Qt::Vertical, painter, rect, flags | SF_PointWest);
       
   238         break;
       
   239     case SE_TabBarTabWestInactive:
       
   240         drawRow(QS60StyleEnums::SP_QgnGrafTabPassiveR, QS60StyleEnums::SP_QgnGrafTabPassiveM,
       
   241             QS60StyleEnums::SP_QgnGrafTabPassiveL, Qt::Vertical, painter, rect, flags | SF_PointWest);
       
   242         break;
       
   243     case SE_ListHighlight:
       
   244         drawFrame(SF_ListHighlight, painter, rect, flags | SF_PointNorth);
       
   245         break;
       
   246     case SE_OptionsMenu:
       
   247         drawFrame(SF_OptionsMenu, painter, rect, flags | SF_PointNorth);
       
   248         break;
       
   249     case SE_SettingsList:
       
   250         drawFrame(SF_SettingsList, painter, rect, flags | SF_PointNorth);
       
   251         break;
       
   252     case SE_TableItem:
       
   253         drawFrame(SF_TableItem, painter, rect, flags | SF_PointNorth);
       
   254         break;
       
   255     case SE_TableHeaderItem:
       
   256         drawFrame(SF_TableHeaderItem, painter, rect, flags | SF_PointNorth);
       
   257         break;
       
   258     case SE_ToolTip:
       
   259         drawFrame(SF_ToolTip, painter, rect, flags | SF_PointNorth);
       
   260         break;
       
   261     case SE_ToolBar:
       
   262         drawFrame(SF_ToolBar, painter, rect, flags | SF_PointNorth);
       
   263         break;
       
   264     case SE_ToolBarButton:
       
   265         drawFrame(SF_ToolBarButton, painter, rect, flags | SF_PointNorth);
       
   266         break;
       
   267     case SE_ToolBarButtonPressed:
       
   268         drawFrame(SF_ToolBarButtonPressed, painter, rect, flags | SF_PointNorth);
       
   269         break;
       
   270     case SE_PanelBackground:
       
   271         drawFrame(SF_PanelBackground, painter, rect, flags | SF_PointNorth);
       
   272         break;
       
   273     case SE_ScrollBarHandlePressedHorizontal:
       
   274         drawRow(QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed, QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed,
       
   275             QS60StyleEnums::SP_QsnCpScrollHandleTopPressed, Qt::Horizontal, painter, rect, flags | SF_PointEast);
       
   276         break;
       
   277     case SE_ScrollBarHandlePressedVertical:
       
   278         drawRow(QS60StyleEnums::SP_QsnCpScrollHandleTopPressed, QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed,
       
   279             QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed, Qt::Vertical, painter, rect, flags | SF_PointNorth);
       
   280         break;
       
   281     case SE_ButtonInactive:
       
   282         drawFrame(SF_ButtonInactive, painter, rect, flags | SF_PointNorth);
       
   283         break;
       
   284     case SE_Editor:
       
   285         drawFrame(SF_Editor, painter, rect, flags | SF_PointNorth);
       
   286         break;
       
   287     default:
       
   288         break;
       
   289     }
       
   290 }
       
   291 
       
   292 void QS60StylePrivate::drawSkinPart(QS60StyleEnums::SkinParts part,
       
   293     QPainter *painter, const QRect &rect, SkinElementFlags flags)
       
   294 {
       
   295     drawPart(part, painter, rect, flags);
       
   296 }
       
   297 
       
   298 short QS60StylePrivate::pixelMetric(int metric)
       
   299 {
       
   300     Q_ASSERT(metric < MAX_PIXELMETRICS);
       
   301     const short returnValue = m_pmPointer[metric];
       
   302     return returnValue;
       
   303 }
       
   304 
       
   305 void QS60StylePrivate::setStyleProperty(const char *name, const QVariant &value)
       
   306 {
       
   307     if (name == propertyKeyCurrentlayout) {
       
   308         static const QStringList layouts = styleProperty(propertyKeyLayouts).toStringList();
       
   309         const QString layout = value.toString();
       
   310         Q_ASSERT(layouts.contains(layout));
       
   311         const int layoutIndex = layouts.indexOf(layout);
       
   312         setCurrentLayout(layoutIndex);
       
   313         QApplication::setLayoutDirection(m_layoutHeaders[layoutIndex].mirroring ? Qt::RightToLeft : Qt::LeftToRight);
       
   314         clearCaches();
       
   315         refreshUI();
       
   316     }
       
   317 }
       
   318 
       
   319 QVariant QS60StylePrivate::styleProperty(const char *name) const
       
   320 {
       
   321     if (name == propertyKeyLayouts) {
       
   322         static QStringList layouts;
       
   323         if (layouts.isEmpty())
       
   324             for (int i = 0; i < m_numberOfLayouts; i++)
       
   325                 layouts.append(QLatin1String(m_layoutHeaders[i].layoutName));
       
   326         return layouts;
       
   327     }
       
   328     return QVariant();
       
   329 }
       
   330 
       
   331 QColor QS60StylePrivate::stateColor(const QColor &color, const QStyleOption *option)
       
   332 {
       
   333     QColor retColor (color);
       
   334     if (option && !(option->state & QStyle::State_Enabled)) {
       
   335         QColor hsvColor = retColor.toHsv();
       
   336         int colorSat = hsvColor.saturation();
       
   337         int colorVal = hsvColor.value();
       
   338         colorSat = (colorSat!=0) ? (colorSat>>1) : 128;
       
   339         colorVal = (colorVal!=0) ? (colorVal>>1) : 128;
       
   340         hsvColor.setHsv(hsvColor.hue(), colorSat, colorVal);
       
   341         retColor = hsvColor.toRgb();
       
   342     }
       
   343     return retColor;
       
   344 }
       
   345 
       
   346 QColor QS60StylePrivate::lighterColor(const QColor &baseColor)
       
   347 {
       
   348     QColor result(baseColor);
       
   349     bool modifyColor = false;
       
   350     if (result.saturation() == 0) {
       
   351         result.setHsv(result.hue(), 128, result.value());
       
   352         modifyColor = true;
       
   353     }
       
   354     if (result.value() == 0) {
       
   355         result.setHsv(result.hue(), result.saturation(), 128);
       
   356         modifyColor = true;
       
   357     }
       
   358     if (modifyColor)
       
   359         result = result.lighter(175);
       
   360     else
       
   361         result = result.lighter(225);
       
   362     return result;
       
   363 }
       
   364 
       
   365 bool QS60StylePrivate::drawsOwnThemeBackground(const QWidget *widget)
       
   366 {
       
   367     return qobject_cast<const QDialog *> (widget);
       
   368 }
       
   369 
       
   370 QFont QS60StylePrivate::s60Font(
       
   371     QS60StyleEnums::FontCategories fontCategory, int pointSize) const
       
   372 {
       
   373     QFont result;
       
   374     int actualPointSize = pointSize;
       
   375     if (actualPointSize <= 0) {
       
   376         const QFont appFont = QApplication::font();
       
   377         actualPointSize = appFont.pointSize();
       
   378         if (actualPointSize <= 0)
       
   379             actualPointSize = appFont.pixelSize() * 72 / qt_defaultDpiY();
       
   380     }
       
   381     Q_ASSERT(actualPointSize > 0);
       
   382     const QPair<QS60StyleEnums::FontCategories, int> key(fontCategory, actualPointSize);
       
   383     if (!m_mappedFontsCache.contains(key)) {
       
   384         result = s60Font_specific(fontCategory, actualPointSize);
       
   385         m_mappedFontsCache.insert(key, result);
       
   386     } else {
       
   387         result = m_mappedFontsCache.value(key);
       
   388         if (result.pointSize() != actualPointSize)
       
   389             result.setPointSize(actualPointSize);
       
   390     }
       
   391     return result;
       
   392 }
       
   393 
       
   394 void QS60StylePrivate::clearCaches(CacheClearReason reason)
       
   395 {
       
   396     switch(reason){
       
   397     case CC_LayoutChange:
       
   398         // when layout changes, the colors remain in cache, but graphics and fonts can change
       
   399         m_mappedFontsCache.clear();
       
   400         deleteBackground();
       
   401         QPixmapCache::clear();
       
   402         break;
       
   403     case CC_ThemeChange:
       
   404         m_colorCache.clear();
       
   405         QPixmapCache::clear();
       
   406         deleteBackground();
       
   407         break;
       
   408     case CC_UndefinedChange:
       
   409     default:
       
   410         m_colorCache.clear();
       
   411         m_mappedFontsCache.clear();
       
   412         QPixmapCache::clear();
       
   413         deleteBackground();
       
   414         break;
       
   415     }
       
   416 }
       
   417 
       
   418 // Since S60Style has 'button' and 'tooltip' as a graphic, we don't have any native color which to use
       
   419 // for QPalette::Button and QPalette::ToolTipBase. Therefore S60Style needs to guesstimate
       
   420 // palette colors by calculating average rgb values for button pixels.
       
   421 // Returns Qt::black if there is an issue with the graphics (image is NULL, or no bits() found).
       
   422 QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const
       
   423 {
       
   424     const bool cachedColorExists = m_colorCache.contains(frame);
       
   425     if (!cachedColorExists) {
       
   426         const int frameCornerWidth = pixelMetric(PM_Custom_FrameCornerWidth);
       
   427         const int frameCornerHeight = pixelMetric(PM_Custom_FrameCornerHeight);
       
   428         Q_ASSERT(2*frameCornerWidth<32);
       
   429         Q_ASSERT(2*frameCornerHeight<32);
       
   430 
       
   431         const QImage frameImage = QS60StylePrivate::frame(frame, QSize(32,32)).toImage();
       
   432         Q_ASSERT(frameImage.bytesPerLine() > 0);
       
   433         if (frameImage.isNull())
       
   434             return Qt::black;
       
   435 
       
   436         const QRgb *pixelRgb = (const QRgb*)frameImage.bits();
       
   437         const int pixels = frameImage.numBytes()/sizeof(QRgb);
       
   438 
       
   439         int estimatedRed = 0;
       
   440         int estimatedGreen = 0;
       
   441         int estimatedBlue = 0;
       
   442 
       
   443         int skips = 0;
       
   444         int estimations = 0;
       
   445 
       
   446         const int topBorderLastPixel = frameCornerHeight*frameImage.width()-1;
       
   447         const int bottomBorderFirstPixel = frameImage.width()*frameImage.height()-frameCornerHeight*frameImage.width()-1;
       
   448         const int rightBorderFirstPixel = frameImage.width()-frameCornerWidth;
       
   449         const int leftBorderLastPixel = frameCornerWidth;
       
   450 
       
   451         while ((skips + estimations) < pixels) {
       
   452             if ((skips+estimations) > topBorderLastPixel &&
       
   453                 (skips+estimations) < bottomBorderFirstPixel) {
       
   454                 for (int rowIndex = 0; rowIndex < frameImage.width(); rowIndex++) {
       
   455                     if (rowIndex > leftBorderLastPixel &&
       
   456                         rowIndex < rightBorderFirstPixel) {
       
   457                         estimatedRed += qRed(*pixelRgb);
       
   458                         estimatedGreen += qGreen(*pixelRgb);
       
   459                         estimatedBlue += qBlue(*pixelRgb);
       
   460                     }
       
   461                     pixelRgb++;
       
   462                     estimations++;
       
   463                 }
       
   464             } else {
       
   465                 pixelRgb++;
       
   466                 skips++;
       
   467             }
       
   468         }
       
   469         QColor frameColor(estimatedRed/estimations, estimatedGreen/estimations, estimatedBlue/estimations);
       
   470         m_colorCache.insert(frame, frameColor);
       
   471         return !estimations ? Qt::black : frameColor;
       
   472     } else {
       
   473         return m_colorCache.value(frame);
       
   474     }
       
   475 
       
   476 }
       
   477 
       
   478 void QS60StylePrivate::setThemePalette(QApplication *app) const
       
   479 {
       
   480     Q_UNUSED(app)
       
   481     QPalette widgetPalette = QPalette(Qt::white);
       
   482     setThemePalette(&widgetPalette);
       
   483     QApplication::setPalette(widgetPalette); //calling QApplication::setPalette clears palette hash
       
   484     setThemePaletteHash(&widgetPalette);
       
   485     storeThemePalette(&widgetPalette);
       
   486 }
       
   487 
       
   488 void QS60StylePrivate::setThemePalette(QStyleOption *option) const
       
   489 {
       
   490     setThemePalette(&option->palette);
       
   491 }
       
   492 
       
   493 QPalette* QS60StylePrivate::themePalette()
       
   494 {
       
   495     return m_themePalette;
       
   496 }
       
   497 
       
   498 void QS60StylePrivate::setBackgroundTexture(QApplication *app) const
       
   499 {
       
   500     Q_UNUSED(app)
       
   501     QPalette applicationPalette = QApplication::palette();
       
   502     applicationPalette.setBrush(QPalette::Window, backgroundTexture());
       
   503     QApplication::setPalette(applicationPalette);
       
   504 }
       
   505 
       
   506 void QS60StylePrivate::deleteBackground()
       
   507 {
       
   508     if (m_background) {
       
   509         delete m_background;
       
   510         m_background = 0;
       
   511     }
       
   512 }
       
   513 
       
   514 void QS60StylePrivate::setCurrentLayout(int index)
       
   515 {
       
   516     m_pmPointer = data[index];
       
   517 }
       
   518 
       
   519 void QS60StylePrivate::drawPart(QS60StyleEnums::SkinParts skinPart,
       
   520     QPainter *painter, const QRect &rect, SkinElementFlags flags)
       
   521 {
       
   522     static const bool doCache =
       
   523 #if defined(Q_WS_S60)
       
   524         // Freezes on 3.1. Anyways, caching is only really needed on touch UI
       
   525         !(QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2);
       
   526 #else
       
   527         true;
       
   528 #endif
       
   529     const QPixmap skinPartPixMap((doCache ? cachedPart : part)(skinPart, rect.size(), flags));
       
   530     if (!skinPartPixMap.isNull())
       
   531         painter->drawPixmap(rect.topLeft(), skinPartPixMap);
       
   532 }
       
   533 
       
   534 void QS60StylePrivate::drawFrame(SkinFrameElements frameElement, QPainter *painter, const QRect &rect, SkinElementFlags flags)
       
   535 {
       
   536     static const bool doCache =
       
   537 #if defined(Q_WS_S60)
       
   538         // Freezes on 3.1. Anyways, caching is only really needed on touch UI
       
   539         !(QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2);
       
   540 #else
       
   541         true;
       
   542 #endif
       
   543     const QPixmap frameElementPixMap((doCache ? cachedFrame : frame)(frameElement, rect.size(), flags));
       
   544     if (!frameElementPixMap.isNull())
       
   545         painter->drawPixmap(rect.topLeft(), frameElementPixMap);
       
   546 }
       
   547 
       
   548 void QS60StylePrivate::drawRow(QS60StyleEnums::SkinParts start,
       
   549     QS60StyleEnums::SkinParts middle, QS60StyleEnums::SkinParts end,
       
   550     Qt::Orientation orientation, QPainter *painter, const QRect &rect,
       
   551     SkinElementFlags flags)
       
   552 {
       
   553     QSize startEndSize(partSize(start, flags));
       
   554     startEndSize.scale(rect.size(), Qt::KeepAspectRatio);
       
   555 
       
   556     QRect startRect = QRect(rect.topLeft(), startEndSize);
       
   557     QRect middleRect = rect;
       
   558     QRect endRect;
       
   559 
       
   560     if (orientation == Qt::Horizontal) {
       
   561         startRect.setWidth(qMin((rect.width() >> 1) - 1, startRect.width()));
       
   562         endRect = startRect.translated(rect.width() - startRect.width(), 0);
       
   563         middleRect.adjust(startRect.width(), 0, -startRect.width(), 0);
       
   564         if (startRect.bottomRight().x() > endRect.topLeft().x()) {
       
   565             const int overlap = (startRect.bottomRight().x() -  endRect.topLeft().x())>>1;
       
   566             startRect.setWidth(startRect.width()-overlap);
       
   567             endRect.adjust(overlap,0,0,0);
       
   568         }
       
   569     } else {
       
   570         startRect.setHeight(qMin((rect.height() >> 1) - 1, startRect.height()));
       
   571         endRect = startRect.translated(0, rect.height() - startRect.height());
       
   572         middleRect.adjust(0, startRect.height(), 0, -startRect.height());
       
   573         if (startRect.topRight().y() > endRect.bottomLeft().y()) {
       
   574             const int overlap = (startRect.topRight().y() - endRect.bottomLeft().y())>>1;
       
   575             startRect.setHeight(startRect.height()-overlap);
       
   576             endRect.adjust(0,overlap,0,0);
       
   577         }
       
   578     }
       
   579 
       
   580 #if 0
       
   581     painter->save();
       
   582     painter->setOpacity(.3);
       
   583     painter->fillRect(startRect, Qt::red);
       
   584     painter->fillRect(middleRect, Qt::green);
       
   585     painter->fillRect(endRect, Qt::blue);
       
   586     painter->restore();
       
   587 #else
       
   588     drawPart(start, painter, startRect, flags);
       
   589     if (middleRect.isValid())
       
   590         drawPart(middle, painter, middleRect, flags);
       
   591     drawPart(end, painter, endRect, flags);
       
   592 #endif
       
   593 }
       
   594 
       
   595 QPixmap QS60StylePrivate::cachedPart(QS60StyleEnums::SkinParts part,
       
   596     const QSize &size, SkinElementFlags flags)
       
   597 {
       
   598     QPixmap result;
       
   599     const QString cacheKey =
       
   600         QString::fromLatin1("S60Style: SkinParts=%1 QSize=%2|%3 SkinPartFlags=%4")
       
   601             .arg((int)part).arg(size.width()).arg(size.height()).arg((int)flags);
       
   602     if (!QPixmapCache::find(cacheKey, result)) {
       
   603         result = QS60StylePrivate::part(part, size, flags);
       
   604         QPixmapCache::insert(cacheKey, result);
       
   605     }
       
   606     return result;
       
   607 }
       
   608 
       
   609 QPixmap QS60StylePrivate::cachedFrame(SkinFrameElements frame, const QSize &size, SkinElementFlags flags)
       
   610 {
       
   611     QPixmap result;
       
   612     const QString cacheKey =
       
   613         QString::fromLatin1("S60Style: SkinFrameElements=%1 QSize=%2|%3 SkinElementFlags=%4")
       
   614             .arg((int)frame).arg(size.width()).arg(size.height()).arg((int)flags);
       
   615     if (!QPixmapCache::find(cacheKey, result)) {
       
   616         result = QS60StylePrivate::frame(frame, size, flags);
       
   617         QPixmapCache::insert(cacheKey, result);
       
   618     }
       
   619     return result;
       
   620 }
       
   621 
       
   622 void QS60StylePrivate::refreshUI()
       
   623 {
       
   624     QList<QWidget *> widgets = QApplication::allWidgets();
       
   625 
       
   626     for (int i = 0; i < widgets.size(); ++i) {
       
   627         QWidget *widget = widgets.at(i);
       
   628         if (widget == 0)
       
   629             continue;
       
   630 
       
   631         if (widget->style()) {
       
   632             widget->style()->polish(widget);
       
   633             QEvent event(QEvent::StyleChange);
       
   634             qApp->sendEvent(widget, &event);
       
   635         }
       
   636         widget->update();
       
   637         widget->updateGeometry();
       
   638     }
       
   639 }
       
   640 
       
   641 void QS60StylePrivate::setFont(QWidget *widget) const
       
   642 {
       
   643     QS60StyleEnums::FontCategories fontCategory = QS60StyleEnums::FC_Undefined;
       
   644     if (!widget)
       
   645         return;
       
   646     if (qobject_cast<QPushButton *>(widget)){
       
   647         fontCategory = QS60StyleEnums::FC_Primary;
       
   648     } else if (qobject_cast<QToolButton *>(widget)){
       
   649         fontCategory = QS60StyleEnums::FC_Primary;
       
   650     } else if (qobject_cast<QHeaderView *>(widget)){
       
   651         fontCategory = QS60StyleEnums::FC_Secondary;
       
   652     } else if (qobject_cast<QGroupBox *>(widget)){
       
   653         fontCategory = QS60StyleEnums::FC_Title;
       
   654     }
       
   655     if (fontCategory != QS60StyleEnums::FC_Undefined) {
       
   656         const QFont suggestedFont =
       
   657             s60Font(fontCategory, widget->font().pointSizeF());
       
   658         widget->setFont(suggestedFont);
       
   659     }
       
   660 }
       
   661 
       
   662 void QS60StylePrivate::setThemePalette(QWidget *widget) const
       
   663 {
       
   664     if(!widget)
       
   665         return;
       
   666     QPalette widgetPalette = QApplication::palette(widget);
       
   667 
       
   668     //header view and its viewport need to be set 100% transparent button color, since drawing code will
       
   669     //draw transparent theme graphics to table column and row headers.
       
   670     if (qobject_cast<QHeaderView *>(widget)){
       
   671         widgetPalette.setColor(QPalette::Active, QPalette::ButtonText,
       
   672             s60Color(QS60StyleEnums::CL_QsnTextColors, 23, 0));
       
   673         QHeaderView* header = qobject_cast<QHeaderView *>(widget);
       
   674         widgetPalette.setColor(QPalette::Button, Qt::transparent );
       
   675         if ( header->viewport() )
       
   676             header->viewport()->setPalette(widgetPalette);
       
   677         QApplication::setPalette(widgetPalette, "QHeaderView");
       
   678     }
       
   679 }
       
   680 
       
   681 void QS60StylePrivate::setThemePalette(QPalette *palette) const
       
   682 {
       
   683     if (!palette)
       
   684         return;
       
   685 
       
   686     // basic colors
       
   687     palette->setColor(QPalette::WindowText,
       
   688         s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0));
       
   689     palette->setColor(QPalette::ButtonText,
       
   690         s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0));
       
   691     palette->setColor(QPalette::Text,
       
   692         s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0));
       
   693     palette->setColor(QPalette::ToolTipText,
       
   694         s60Color(QS60StyleEnums::CL_QsnTextColors, 55, 0));
       
   695     palette->setColor(QPalette::BrightText, palette->color(QPalette::WindowText).lighter());
       
   696     palette->setColor(QPalette::HighlightedText,
       
   697         s60Color(QS60StyleEnums::CL_QsnTextColors, 10, 0));
       
   698     palette->setColor(QPalette::Link,
       
   699         s60Color(QS60StyleEnums::CL_QsnHighlightColors, 3, 0));
       
   700     palette->setColor(QPalette::LinkVisited, palette->color(QPalette::Link).darker());
       
   701     palette->setColor(QPalette::Highlight,
       
   702         s60Color(QS60StyleEnums::CL_QsnHighlightColors, 2, 0));
       
   703     // set background image as a texture brush
       
   704     palette->setBrush(QPalette::Window, backgroundTexture());
       
   705     // set these as transparent so that styled full screen theme background is visible
       
   706     palette->setColor(QPalette::AlternateBase, Qt::transparent);
       
   707     palette->setBrush(QPalette::Base, Qt::transparent);
       
   708     // set button and tooltipbase based on pixel colors
       
   709     const QColor buttonColor = colorFromFrameGraphics(SF_ButtonNormal);
       
   710     palette->setColor(QPalette::Button, buttonColor);
       
   711     const QColor toolTipColor = colorFromFrameGraphics(SF_ToolTip);
       
   712     palette->setColor(QPalette::ToolTipBase, toolTipColor);
       
   713     palette->setColor(QPalette::Light, palette->color(QPalette::Button).lighter());
       
   714     palette->setColor(QPalette::Dark, palette->color(QPalette::Button).darker());
       
   715     palette->setColor(QPalette::Midlight, palette->color(QPalette::Button).lighter(125));
       
   716     palette->setColor(QPalette::Mid, palette->color(QPalette::Button).darker(150));
       
   717     palette->setColor(QPalette::Shadow, Qt::black);
       
   718 }
       
   719 
       
   720 void QS60StylePrivate::deleteThemePalette()
       
   721 {
       
   722     if (m_themePalette) {
       
   723         delete m_themePalette;
       
   724         m_themePalette = 0;
       
   725     }
       
   726 }
       
   727 
       
   728 void QS60StylePrivate::storeThemePalette(QPalette *palette)
       
   729 {
       
   730     deleteThemePalette();
       
   731     //store specified palette for latter use.
       
   732     m_themePalette = new QPalette(*palette);
       
   733 }
       
   734 
       
   735 // set widget specific palettes
       
   736 void QS60StylePrivate::setThemePaletteHash(QPalette *palette) const
       
   737 {
       
   738     if (!palette)
       
   739         return;
       
   740 
       
   741     //store the original palette
       
   742     QPalette widgetPalette = *palette;
       
   743     const QColor mainAreaTextColor =
       
   744         s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0);
       
   745 
       
   746     widgetPalette.setColor(QPalette::All, QPalette::WindowText,
       
   747         s60Color(QS60StyleEnums::CL_QsnLineColors, 8, 0));
       
   748     QApplication::setPalette(widgetPalette, "QSlider");
       
   749     // return to original palette after each widget
       
   750     widgetPalette = *palette;
       
   751 
       
   752     widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, mainAreaTextColor);
       
   753     widgetPalette.setColor(QPalette::Inactive, QPalette::ButtonText, mainAreaTextColor);
       
   754     const QStyleOption opt;
       
   755     widgetPalette.setColor(QPalette::Disabled, QPalette::ButtonText,
       
   756         s60Color(QS60StyleEnums::CL_QsnTextColors, 6, &opt));
       
   757     QApplication::setPalette(widgetPalette, "QPushButton");
       
   758     widgetPalette = *palette;
       
   759 
       
   760     widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, mainAreaTextColor);
       
   761     widgetPalette.setColor(QPalette::Inactive, QPalette::ButtonText, mainAreaTextColor);
       
   762     QApplication::setPalette(widgetPalette, "QToolButton");
       
   763     widgetPalette = *palette;
       
   764 
       
   765     widgetPalette.setColor(QPalette::Active, QPalette::ButtonText,
       
   766         s60Color(QS60StyleEnums::CL_QsnTextColors, 23, 0));
       
   767     QApplication::setPalette(widgetPalette, "QHeaderView");
       
   768     widgetPalette = *palette;
       
   769 
       
   770     widgetPalette.setColor(QPalette::All, QPalette::ButtonText,
       
   771         s60Color(QS60StyleEnums::CL_QsnTextColors, 8, 0));
       
   772     QApplication::setPalette(widgetPalette, "QMenuBar");
       
   773     widgetPalette = *palette;
       
   774 
       
   775     widgetPalette.setColor(QPalette::Active, QPalette::WindowText,
       
   776         s60Color(QS60StyleEnums::CL_QsnTextColors, 4, 0));
       
   777     QApplication::setPalette(widgetPalette, "QTabBar");
       
   778     widgetPalette = *palette;
       
   779 
       
   780     widgetPalette.setColor(QPalette::All, QPalette::Text,
       
   781         s60Color(QS60StyleEnums::CL_QsnTextColors, 22, 0));
       
   782     QApplication::setPalette(widgetPalette, "QTableView");
       
   783     widgetPalette = *palette;
       
   784 
       
   785     widgetPalette.setColor(QPalette::All, QPalette::HighlightedText,
       
   786         s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0));
       
   787     QApplication::setPalette(widgetPalette, "QLineEdit");
       
   788     widgetPalette = *palette;
       
   789 
       
   790     widgetPalette.setColor(QPalette::All, QPalette::Text,
       
   791         s60Color(QS60StyleEnums::CL_QsnTextColors, 34, 0));
       
   792     widgetPalette.setColor(QPalette::All, QPalette::HighlightedText,
       
   793         s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0));
       
   794     QApplication::setPalette(widgetPalette, "QTextEdit");
       
   795     widgetPalette = *palette;
       
   796 
       
   797     widgetPalette.setColor(QPalette::All, QPalette::HighlightedText,
       
   798         s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0));
       
   799     QApplication::setPalette(widgetPalette, "QComboBox");
       
   800     widgetPalette = *palette;
       
   801 
       
   802     widgetPalette.setColor(QPalette::WindowText, mainAreaTextColor);
       
   803     widgetPalette.setColor(QPalette::Button, QApplication::palette().color(QPalette::Button));
       
   804     widgetPalette.setColor(QPalette::Dark, mainAreaTextColor.darker());
       
   805     widgetPalette.setColor(QPalette::Light, mainAreaTextColor.lighter());
       
   806     QApplication::setPalette(widgetPalette, "QDial");
       
   807     widgetPalette = *palette;
       
   808 
       
   809     widgetPalette.setBrush(QPalette::Window, QBrush());
       
   810     QApplication::setPalette(widgetPalette, "QScrollArea");
       
   811     widgetPalette = *palette;
       
   812 }
       
   813 
       
   814 QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlags flags)
       
   815 {
       
   816     QSize result(20, 20);
       
   817     switch (part)
       
   818         {
       
   819         case QS60StyleEnums::SP_QgnGrafBarProgress:
       
   820             result.setWidth(pixelMetric(QStyle::PM_ProgressBarChunkWidth));
       
   821             break;
       
   822         case QS60StyleEnums::SP_QgnGrafTabActiveM:
       
   823         case QS60StyleEnums::SP_QgnGrafTabPassiveM:
       
   824         case QS60StyleEnums::SP_QgnGrafTabActiveR:
       
   825         case QS60StyleEnums::SP_QgnGrafTabPassiveR:
       
   826         case QS60StyleEnums::SP_QgnGrafTabPassiveL:
       
   827         case QS60StyleEnums::SP_QgnGrafTabActiveL:
       
   828             break;
       
   829         case QS60StyleEnums::SP_QgnIndiSliderEdit:
       
   830             result.scale(pixelMetric(QStyle::PM_SliderLength),
       
   831                 pixelMetric(QStyle::PM_SliderControlThickness), Qt::IgnoreAspectRatio);
       
   832             break;
       
   833 
       
   834         case QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed:
       
   835         case QS60StyleEnums::SP_QsnCpScrollHandleTopPressed:
       
   836         case QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed:
       
   837         case QS60StyleEnums::SP_QsnCpScrollBgBottom:
       
   838         case QS60StyleEnums::SP_QsnCpScrollBgMiddle:
       
   839         case QS60StyleEnums::SP_QsnCpScrollBgTop:
       
   840         case QS60StyleEnums::SP_QsnCpScrollHandleBottom:
       
   841         case QS60StyleEnums::SP_QsnCpScrollHandleMiddle:
       
   842         case QS60StyleEnums::SP_QsnCpScrollHandleTop:
       
   843             result.setHeight(pixelMetric(QStyle::PM_ScrollBarExtent));
       
   844             result.setWidth(pixelMetric(QStyle::PM_ScrollBarSliderMin));
       
   845             break;
       
   846         default:
       
   847             // Generic frame part size gathering.
       
   848             for (int i = 0; i < frameElementsCount; ++i)
       
   849             {
       
   850                 switch (m_frameElementsData[i].center - part) {
       
   851                     case 8: /* CornerTl */
       
   852                     case 7: /* CornerTr */
       
   853                     case 6: /* CornerBl */
       
   854                     case 5: /* CornerBr */
       
   855                         result.setWidth(pixelMetric(PM_Custom_FrameCornerWidth));
       
   856                         // Falltrough intended...
       
   857                     case 4: /* SideT */
       
   858                     case 3: /* SideB */
       
   859                         result.setHeight(pixelMetric(PM_Custom_FrameCornerHeight));
       
   860                         break;
       
   861                     case 2: /* SideL */
       
   862                     case 1: /* SideR */
       
   863                         result.setWidth(pixelMetric(PM_Custom_FrameCornerWidth));
       
   864                         break;
       
   865                     case 0: /* center */
       
   866                     default:
       
   867                         break;
       
   868                 }
       
   869             }
       
   870             break;
       
   871     }
       
   872     if (flags & (SF_PointEast | SF_PointWest)) {
       
   873         const int temp = result.width();
       
   874         result.setWidth(result.height());
       
   875         result.setHeight(temp);
       
   876     }
       
   877     return result;
       
   878 }
       
   879 
       
   880 /*!
       
   881   \class QS60Style
       
   882   \brief The QS60Style class provides a look and feel suitable for applications on S60.
       
   883   \since 4.6
       
   884   \ingroup appearance
       
   885 
       
   886   \sa QMacStyle, QWindowsStyle, QWindowsXPStyle, QWindowsVistaStyle, QPlastiqueStyle, QCleanlooksStyle, QMotifStyle
       
   887 */
       
   888 
       
   889 
       
   890 /*!
       
   891     Destroys the style.
       
   892 */
       
   893 QS60Style::~QS60Style()
       
   894 {
       
   895 }
       
   896 
       
   897 /*!
       
   898   \reimp
       
   899 */
       
   900 void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
       
   901 {
       
   902     const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ?  QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled;
       
   903     SubControls sub = option->subControls;
       
   904 
       
   905     switch (control) {
       
   906 #ifndef QT_NO_SCROLLBAR
       
   907     case CC_ScrollBar:
       
   908         if (const QStyleOptionSlider *optionSlider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
       
   909             const bool horizontal = optionSlider->orientation == Qt::Horizontal;
       
   910 
       
   911             const QRect scrollBarSlider = subControlRect(control, optionSlider, SC_ScrollBarSlider, widget);
       
   912             const QRect grooveRect = subControlRect(control, optionSlider, SC_ScrollBarGroove, widget);
       
   913 
       
   914             const QS60StylePrivate::SkinElements grooveElement =
       
   915                 horizontal ? QS60StylePrivate::SE_ScrollBarGrooveHorizontal : QS60StylePrivate::SE_ScrollBarGrooveVertical;
       
   916             QS60StylePrivate::drawSkinElement(grooveElement, painter, grooveRect, flags);
       
   917 
       
   918             const QStyle::SubControls subControls = optionSlider->subControls;
       
   919 
       
   920             // select correct slider (horizontal/vertical/pressed)
       
   921             const bool sliderPressed = ((optionSlider->state & QStyle::State_Sunken) && (subControls & SC_ScrollBarSlider));
       
   922             const QS60StylePrivate::SkinElements handleElement =
       
   923                 horizontal ?
       
   924                     ( sliderPressed ?
       
   925                         QS60StylePrivate::SE_ScrollBarHandlePressedHorizontal :
       
   926                         QS60StylePrivate::SE_ScrollBarHandleHorizontal ) :
       
   927                     ( sliderPressed ?
       
   928                         QS60StylePrivate::SE_ScrollBarHandlePressedVertical :
       
   929                         QS60StylePrivate::SE_ScrollBarHandleVertical);
       
   930             QS60StylePrivate::drawSkinElement(handleElement, painter, scrollBarSlider, flags);
       
   931         }
       
   932         break;
       
   933 #endif // QT_NO_SCROLLBAR
       
   934 #ifndef QT_NO_SLIDER
       
   935     case CC_Slider:
       
   936         if (const QStyleOptionSlider *optionSlider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
       
   937 
       
   938             // The groove is just a centered line. Maybe a qgn_graf_line_* at some point
       
   939             const QRect sliderGroove = subControlRect(control, optionSlider, SC_SliderGroove, widget);
       
   940             const QPoint sliderGrooveCenter = sliderGroove.center();
       
   941             const bool horizontal = optionSlider->orientation == Qt::Horizontal;
       
   942             painter->save();
       
   943             if (widget)
       
   944                 painter->setPen(widget->palette().windowText().color());
       
   945             if (horizontal)
       
   946                 painter->drawLine(0, sliderGrooveCenter.y(), sliderGroove.right(), sliderGrooveCenter.y());
       
   947             else
       
   948                 painter->drawLine(sliderGrooveCenter.x(), 0, sliderGrooveCenter.x(), sliderGroove.bottom());
       
   949             painter->restore();
       
   950 
       
   951             const QRect sliderHandle = subControlRect(control, optionSlider, SC_SliderHandle, widget);
       
   952             const QS60StylePrivate::SkinElements handleElement =
       
   953                 horizontal ? QS60StylePrivate::SE_SliderHandleHorizontal : QS60StylePrivate::SE_SliderHandleVertical;
       
   954             QS60StylePrivate::drawSkinElement(handleElement, painter, sliderHandle, flags);
       
   955         }
       
   956         break;
       
   957 #endif // QT_NO_SLIDER
       
   958 #ifndef QT_NO_COMBOBOX
       
   959     case CC_ComboBox:
       
   960         if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
       
   961             const QRect cmbxEditField = subControlRect(CC_ComboBox, option, SC_ComboBoxEditField, widget);
       
   962             const QRect cmbxFrame = subControlRect(CC_ComboBox, option, SC_ComboBoxFrame, widget);
       
   963             const bool direction = cmb->direction == Qt::LeftToRight;
       
   964 
       
   965             // Button frame
       
   966             QStyleOptionFrame  buttonOption;
       
   967             buttonOption.QStyleOption::operator=(*cmb);
       
   968             const int maxHeight = cmbxFrame.height();
       
   969             const int maxWidth = cmbxFrame.width() - cmbxEditField.width();
       
   970             const int topLeftPoint = direction ? cmbxEditField.right()+1 : cmbxEditField.left()+1-maxWidth;
       
   971             const QRect buttonRect(topLeftPoint, cmbxEditField.top(), maxWidth, maxHeight);
       
   972             buttonOption.rect = buttonRect;
       
   973             buttonOption.state = cmb->state & (State_Enabled | State_MouseOver);
       
   974             drawPrimitive(PE_PanelButtonCommand, &buttonOption, painter, widget);
       
   975 
       
   976             // draw label background - label itself is drawn separately
       
   977             const QS60StylePrivate::SkinElements skinElement = QS60StylePrivate::SE_FrameLineEdit;
       
   978             QS60StylePrivate::drawSkinElement(skinElement, painter, cmbxEditField, flags);
       
   979 
       
   980             // Draw the combobox arrow
       
   981             if (sub & SC_ComboBoxArrow) {
       
   982                 // Make rect slightly smaller
       
   983                 buttonOption.rect.adjust(1, 1, -1, -1);
       
   984                 painter->save();
       
   985                 painter->setPen(option->palette.buttonText().color());
       
   986                 drawPrimitive(PE_IndicatorSpinDown, &buttonOption, painter, widget);
       
   987                 painter->restore();
       
   988             }
       
   989         }
       
   990         break;
       
   991 #endif // QT_NO_COMBOBOX
       
   992 #ifndef QT_NO_TOOLBUTTON
       
   993     case CC_ToolButton:
       
   994         if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
       
   995             const State bflags = toolBtn->state;
       
   996             const QRect button(subControlRect(control, toolBtn, SC_ToolButton, widget));
       
   997             QStyleOptionToolButton toolButton = *toolBtn;
       
   998 
       
   999             if (sub&SC_ToolButton) {
       
  1000                 QStyleOption tool(0);
       
  1001                 tool.palette = toolBtn->palette;
       
  1002 
       
  1003                 // Check if toolbutton is in toolbar.
       
  1004                 QToolBar *toolBar = 0;
       
  1005                 if (widget)
       
  1006                     toolBar = qobject_cast<QToolBar *>(widget->parentWidget());
       
  1007 
       
  1008                 if (bflags & (State_Sunken | State_On | State_Raised)) {
       
  1009                     tool.rect = button;
       
  1010                     tool.state = bflags;
       
  1011 
       
  1012                     // todo: I'd like to move extension button next to where last button is
       
  1013                     // however, the painter seems to want to clip the button rect even if I turn of the clipping.
       
  1014                     if (toolBar && (qobject_cast<const QToolBarExtension *>(widget))){
       
  1015                         /*QList<QAction *> actionList = toolBar->actions();
       
  1016                         const int actionCount = actionList.count();
       
  1017                         const int toolbarWidth = toolBar->width();
       
  1018                         const int extButtonWidth = pixelMetric(PM_ToolBarExtensionExtent, option, widget);
       
  1019                         const int toolBarButtonWidth = pixelMetric(PM_ToolBarIconSize, option, widget);
       
  1020                         const int frame = pixelMetric(PM_ToolBarFrameWidth, option, widget);
       
  1021                         const int margin = pixelMetric(PM_ToolBarItemMargin, option, widget);
       
  1022                         const int border = frame + margin;
       
  1023                         const int spacing = pixelMetric(PM_ToolBarItemSpacing, option, widget);
       
  1024                         const int toolBarButtonArea = toolbarWidth - extButtonWidth - spacing - 2*border;
       
  1025                         const int numberOfVisibleButtons = toolBarButtonArea / toolBarButtonWidth;
       
  1026                         // new extension button place is after border and all the other visible buttons (with spacings)
       
  1027                         const int newXForExtensionButton = numberOfVisibleButtons * toolBarButtonWidth + (numberOfVisibleButtons-1)*spacing + border;
       
  1028                         painter->save();
       
  1029                         painter->setClipping(false);
       
  1030                         tool.rect.translate(-newXForExtensionButton,0);
       
  1031                         painter->restore();*/
       
  1032                     }
       
  1033 
       
  1034                     if (toolBar){
       
  1035                         /*if (toolBar->orientation() == Qt::Vertical){
       
  1036                             // todo: I'd like to make all vertical buttons the same size, but again the painter
       
  1037                             // prefers to use clipping for button rects, even though clipping has been set off.
       
  1038                             painter->save();
       
  1039                             painter->setClipping(false);
       
  1040 
       
  1041                             const int origWidth = tool.rect.width();
       
  1042                             const int newWidth = toolBar->width()-2*pixelMetric(PM_ToolBarFrameWidth, option, widget);
       
  1043                             painter->translate(origWidth-newWidth,0);
       
  1044                             tool.rect.translate(origWidth-tool.rect.width(),0);
       
  1045                             tool.rect.setWidth(newWidth);
       
  1046 
       
  1047                             if (option->state & QStyle::State_Sunken)
       
  1048                                 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButtonPressed, painter, tool.rect, flags);
       
  1049                             else
       
  1050                                 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButton, painter, tool.rect, flags);
       
  1051 
       
  1052                         }*/
       
  1053                         if (option->state & QStyle::State_Sunken)
       
  1054                             QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButtonPressed, painter, tool.rect, flags);
       
  1055                         else
       
  1056                             QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButton, painter, tool.rect, flags);
       
  1057                         /*
       
  1058                         if (toolBar->orientation() == Qt::Vertical)
       
  1059                             painter->restore();
       
  1060                             */
       
  1061                     } else {
       
  1062                         drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
       
  1063                     }
       
  1064                 }
       
  1065             }
       
  1066 
       
  1067             if (toolBtn->features & QStyleOptionToolButton::Arrow) {
       
  1068                 QStyle::PrimitiveElement pe;
       
  1069                 switch (toolBtn->arrowType) {
       
  1070                     case Qt::LeftArrow:
       
  1071                         pe = QStyle::PE_IndicatorArrowLeft;
       
  1072                         break;
       
  1073                     case Qt::RightArrow:
       
  1074                         pe = QStyle::PE_IndicatorArrowRight;
       
  1075                         break;
       
  1076                     case Qt::UpArrow:
       
  1077                         pe = QStyle::PE_IndicatorArrowUp;
       
  1078                         break;
       
  1079                     case Qt::DownArrow:
       
  1080                         pe = QStyle::PE_IndicatorArrowDown;
       
  1081                         break;
       
  1082                     default:
       
  1083                         break; }
       
  1084                 toolButton.rect = button;
       
  1085                 drawPrimitive(pe, &toolButton, painter, widget);
       
  1086             }
       
  1087 
       
  1088             if (toolBtn->text.length()>0 ||
       
  1089                 !toolBtn->icon.isNull()) {
       
  1090                 const int frameWidth = pixelMetric(PM_DefaultFrameWidth, option, widget);
       
  1091                 toolButton.rect = button.adjusted(frameWidth, frameWidth, -frameWidth, -frameWidth);
       
  1092                 drawControl(CE_ToolButtonLabel, &toolButton, painter, widget);
       
  1093                 }
       
  1094             }
       
  1095         break;
       
  1096 #endif //QT_NO_TOOLBUTTON
       
  1097 #ifndef QT_NO_SPINBOX
       
  1098     case CC_SpinBox:
       
  1099         if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
       
  1100             QStyleOptionSpinBox copy = *spinBox;
       
  1101             PrimitiveElement pe;
       
  1102 
       
  1103             if (spinBox->subControls & SC_SpinBoxUp) {
       
  1104                 copy.subControls = SC_SpinBoxUp;
       
  1105                 QPalette spinBoxPal = spinBox->palette;
       
  1106                 if (!(spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled)) {
       
  1107                     spinBoxPal.setCurrentColorGroup(QPalette::Disabled);
       
  1108                     copy.state &= ~State_Enabled;
       
  1109                     copy.palette = spinBoxPal;
       
  1110                 }
       
  1111 
       
  1112                 if (spinBox->activeSubControls == SC_SpinBoxUp && (spinBox->state & State_Sunken)) {
       
  1113                     copy.state |= State_On;
       
  1114                     copy.state |= State_Sunken;
       
  1115                 } else {
       
  1116                     copy.state |= State_Raised;
       
  1117                     copy.state &= ~State_Sunken;
       
  1118                 }
       
  1119                 pe = (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) ?
       
  1120                       PE_IndicatorSpinPlus :
       
  1121                       PE_IndicatorSpinUp;
       
  1122 
       
  1123                 copy.rect = subControlRect(CC_SpinBox, spinBox, SC_SpinBoxUp, widget);
       
  1124                 drawPrimitive(PE_PanelButtonBevel, &copy, painter, widget);
       
  1125                 copy.rect.adjust(1, 1, -1, -1);
       
  1126                 drawPrimitive(pe, &copy, painter, widget);
       
  1127             }
       
  1128 
       
  1129             if (spinBox->subControls & SC_SpinBoxDown) {
       
  1130                 copy.subControls = SC_SpinBoxDown;
       
  1131                 copy.state = spinBox->state;
       
  1132                 QPalette spinBoxPal = spinBox->palette;
       
  1133                 if (!(spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled)) {
       
  1134                     spinBoxPal.setCurrentColorGroup(QPalette::Disabled);
       
  1135                     copy.state &= ~State_Enabled;
       
  1136                     copy.palette = spinBoxPal;
       
  1137                 }
       
  1138 
       
  1139                 if (spinBox->activeSubControls == SC_SpinBoxDown && (spinBox->state & State_Sunken)) {
       
  1140                     copy.state |= State_On;
       
  1141                     copy.state |= State_Sunken;
       
  1142                 } else {
       
  1143                     copy.state |= State_Raised;
       
  1144                     copy.state &= ~State_Sunken;
       
  1145                 }
       
  1146                 pe = (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) ?
       
  1147                       PE_IndicatorSpinMinus :
       
  1148                       PE_IndicatorSpinDown;
       
  1149 
       
  1150                 copy.rect = subControlRect(CC_SpinBox, spinBox, SC_SpinBoxDown, widget);
       
  1151                 drawPrimitive(PE_PanelButtonBevel, &copy, painter, widget);
       
  1152                 copy.rect.adjust(1, 1, -1, -1);
       
  1153                 drawPrimitive(pe, &copy, painter, widget);
       
  1154             }
       
  1155         }
       
  1156         break;
       
  1157 #endif //QT_NO_SPINBOX
       
  1158 #ifndef QT_NO_GROUPBOX
       
  1159     case CC_GroupBox:
       
  1160         if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
       
  1161             // Draw frame
       
  1162             const QRect textRect = subControlRect(CC_GroupBox, option, SC_GroupBoxLabel, widget);
       
  1163             const QRect checkBoxRect = subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget);
       
  1164             if (groupBox->subControls & QStyle::SC_GroupBoxFrame) {
       
  1165                 QStyleOptionFrameV2 frame;
       
  1166                 frame.QStyleOption::operator=(*groupBox);
       
  1167                 frame.features = groupBox->features;
       
  1168                 frame.lineWidth = groupBox->lineWidth;
       
  1169                 frame.midLineWidth = groupBox->midLineWidth;
       
  1170                 frame.rect = subControlRect(CC_GroupBox, option, SC_GroupBoxFrame, widget);
       
  1171                 drawPrimitive(PE_FrameGroupBox, &frame, painter, widget);
       
  1172             }
       
  1173 
       
  1174             // Draw title
       
  1175             if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
       
  1176                 const QColor textColor = groupBox->textColor;
       
  1177                 painter->save();
       
  1178 
       
  1179                 if (textColor.isValid())
       
  1180                     painter->setPen(textColor);
       
  1181                 int alignment = int(groupBox->textAlignment);
       
  1182                 if (!styleHint(QStyle::SH_UnderlineShortcut, option, widget))
       
  1183                     alignment |= Qt::TextHideMnemonic;
       
  1184 
       
  1185                 drawItemText(painter, textRect,  Qt::TextShowMnemonic | Qt::AlignHCenter | Qt::AlignVCenter | alignment,
       
  1186                              groupBox->palette, groupBox->state & State_Enabled, groupBox->text,
       
  1187                              textColor.isValid() ? QPalette::NoRole : QPalette::WindowText);
       
  1188                 painter->restore();
       
  1189             }
       
  1190 
       
  1191             // Draw checkbox
       
  1192             if (groupBox->subControls & SC_GroupBoxCheckBox) {
       
  1193                 QStyleOptionButton box;
       
  1194                 box.QStyleOption::operator=(*groupBox);
       
  1195                 box.rect = checkBoxRect;
       
  1196                 drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget);
       
  1197             }
       
  1198         }
       
  1199         break;
       
  1200 #endif //QT_NO_GROUPBOX
       
  1201     default:
       
  1202         QCommonStyle::drawComplexControl(control, option, painter, widget);
       
  1203     }
       
  1204 }
       
  1205 
       
  1206 /*!
       
  1207   \reimp
       
  1208 */
       
  1209 void QS60Style::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
       
  1210 {
       
  1211     Q_D(const QS60Style);
       
  1212     const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ?  QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled;
       
  1213     switch (element) {
       
  1214     case CE_PushButton:
       
  1215         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
       
  1216 
       
  1217             drawControl(CE_PushButtonBevel, btn, painter, widget);
       
  1218             QStyleOptionButton subopt = *btn;
       
  1219             subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
       
  1220 
       
  1221             drawControl(CE_PushButtonLabel, &subopt, painter, widget);
       
  1222         }
       
  1223         break;
       
  1224     case CE_PushButtonBevel:
       
  1225         if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
       
  1226             const bool isDisabled = !(option->state & QStyle::State_Enabled);
       
  1227             const bool isFlat = button->features & QStyleOptionButton::Flat;
       
  1228             QS60StyleEnums::SkinParts skinPart;
       
  1229             QS60StylePrivate::SkinElements skinElement;
       
  1230             if (!isDisabled) {
       
  1231                 const bool isPressed = (option->state & QStyle::State_Sunken) ||
       
  1232                                        (option->state & QStyle::State_On);
       
  1233                 if (isFlat) {
       
  1234                     skinPart =
       
  1235                         isPressed ? QS60StyleEnums::SP_QsnFrButtonTbCenterPressed : QS60StyleEnums::SP_QsnFrButtonTbCenter;
       
  1236                 } else {
       
  1237                     skinElement =
       
  1238                         isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal;
       
  1239                 }
       
  1240             } else {
       
  1241                 if (isFlat)
       
  1242                     skinPart =QS60StyleEnums::SP_QsnFrButtonCenterInactive;
       
  1243                 else
       
  1244                     skinElement = QS60StylePrivate::SE_ButtonInactive;
       
  1245             }
       
  1246             if (isFlat)
       
  1247                 QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags);
       
  1248             else
       
  1249                 QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags);
       
  1250             }
       
  1251         break;
       
  1252 #ifndef QT_NO_TOOLBUTTON
       
  1253     case CE_ToolButtonLabel:
       
  1254         if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
       
  1255             QStyleOptionToolButton optionToolButton = *toolBtn;
       
  1256 
       
  1257             if (!optionToolButton.icon.isNull() && (optionToolButton.state & QStyle::State_Sunken)
       
  1258                     && (optionToolButton.state & State_Enabled)) {
       
  1259 
       
  1260                     const QIcon::State state = optionToolButton.state & State_On ? QIcon::On : QIcon::Off;
       
  1261                     const QPixmap pm(optionToolButton.icon.pixmap(optionToolButton.rect.size().boundedTo(optionToolButton.iconSize),
       
  1262                             QIcon::Normal, state));
       
  1263                     optionToolButton.icon = generatedIconPixmap(QIcon::Selected, pm, &optionToolButton);
       
  1264             }
       
  1265 
       
  1266             QCommonStyle::drawControl(element, &optionToolButton, painter, widget);
       
  1267         }
       
  1268         break;
       
  1269 #endif //QT_NO_TOOLBUTTON
       
  1270 #ifndef QT_NO_COMBOBOX
       
  1271     case CE_ComboBoxLabel:
       
  1272         if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
       
  1273             QStyleOption optionComboBox = *comboBox;
       
  1274             optionComboBox.palette.setColor(QPalette::Active, QPalette::WindowText,
       
  1275                 optionComboBox.palette.text().color() );
       
  1276             optionComboBox.palette.setColor(QPalette::Inactive, QPalette::WindowText,
       
  1277                 optionComboBox.palette.text().color() );
       
  1278             QRect editRect = subControlRect(CC_ComboBox, comboBox, SC_ComboBoxEditField, widget);
       
  1279             painter->save();
       
  1280             painter->setClipRect(editRect);
       
  1281 
       
  1282             if (!comboBox->currentIcon.isNull()) {
       
  1283                 QIcon::Mode mode = comboBox->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
       
  1284                 QPixmap pixmap = comboBox->currentIcon.pixmap(comboBox->iconSize, mode);
       
  1285                 QRect iconRect(editRect);
       
  1286                 iconRect.setWidth(comboBox->iconSize.width() + 4);
       
  1287                 iconRect = alignedRect(comboBox->direction,
       
  1288                                        Qt::AlignLeft | Qt::AlignVCenter,
       
  1289                                        iconRect.size(), editRect);
       
  1290                 if (comboBox->editable)
       
  1291                     painter->fillRect(iconRect, optionComboBox.palette.brush(QPalette::Base));
       
  1292                 drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap);
       
  1293 
       
  1294                 if (comboBox->direction == Qt::RightToLeft)
       
  1295                     editRect.translate(-4 - comboBox->iconSize.width(), 0);
       
  1296                 else
       
  1297                     editRect.translate(comboBox->iconSize.width() + 4, 0);
       
  1298             }
       
  1299             if (!comboBox->currentText.isEmpty() && !comboBox->editable) {
       
  1300                 QCommonStyle::drawItemText(painter,
       
  1301                             editRect.adjusted(QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth), 0, -1, 0),
       
  1302                             visualAlignment(comboBox->direction, Qt::AlignLeft | Qt::AlignVCenter),
       
  1303                             comboBox->palette, comboBox->state & State_Enabled, comboBox->currentText);
       
  1304             }
       
  1305             painter->restore();
       
  1306         }
       
  1307         break;
       
  1308 #endif //QT_NO_COMBOBOX
       
  1309 #ifndef QT_NO_ITEMVIEWS
       
  1310     case CE_ItemViewItem:
       
  1311         if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
       
  1312             QStyleOptionViewItemV4 voptAdj = *vopt;
       
  1313             painter->save();
       
  1314 
       
  1315             painter->setClipRect(voptAdj.rect);
       
  1316             const bool isSelected = (vopt->state & QStyle::State_Selected);
       
  1317 
       
  1318             bool isVisible = false;
       
  1319             int scrollBarWidth = 0;
       
  1320             QList<QScrollBar *> scrollBars = qFindChildren<QScrollBar *>(widget);
       
  1321             for (int i = 0; i < scrollBars.size(); ++i) {
       
  1322                 QScrollBar *scrollBar = scrollBars.at(i);
       
  1323                 if (scrollBar && scrollBar->orientation() == Qt::Vertical) {
       
  1324                     isVisible = scrollBar->isVisible();
       
  1325                     scrollBarWidth = scrollBar->size().width();
       
  1326                     break;
       
  1327                 }
       
  1328             }
       
  1329 
       
  1330             int rightValue = widget ? widget->contentsRect().right() : 0;
       
  1331 
       
  1332             if (isVisible)
       
  1333                 rightValue -= scrollBarWidth;
       
  1334 
       
  1335             if (voptAdj.rect.right() > rightValue)
       
  1336                 voptAdj.rect.setRight(rightValue);
       
  1337 
       
  1338             const QRect iconRect = subElementRect(SE_ItemViewItemDecoration, &voptAdj, widget);
       
  1339             QRect textRect = subElementRect(SE_ItemViewItemText, &voptAdj, widget);
       
  1340 
       
  1341             // draw themed background for table unless background brush has been defined.
       
  1342             if (vopt->backgroundBrush == Qt::NoBrush) {
       
  1343                 const QStyleOptionViewItemV4 *tableOption = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option);
       
  1344                 const QTableView *table = qobject_cast<const QTableView *>(widget);
       
  1345                 if (table && tableOption) {
       
  1346                     const QModelIndex index = tableOption->index;
       
  1347                     //todo: Draw cell background only once - for the first cell.
       
  1348                     QStyleOptionViewItemV4 voptAdj2 = voptAdj;
       
  1349                     const QModelIndex indexFirst = table->model()->index(0,0);
       
  1350                     const QModelIndex indexLast = table->model()->index(
       
  1351                         table->model()->rowCount()-1,table->model()->columnCount()-1);
       
  1352                     if (table->viewport())
       
  1353                         voptAdj2.rect = QRect( table->visualRect(indexFirst).topLeft(),
       
  1354                             table->visualRect(indexLast).bottomRight()).intersect(table->viewport()->rect());
       
  1355                     drawPrimitive(PE_PanelItemViewItem, &voptAdj2, painter, widget);
       
  1356                 }
       
  1357             } else { QCommonStyle::drawPrimitive(PE_PanelItemViewItem, option, painter, widget);}
       
  1358 
       
  1359             // draw the focus rect
       
  1360             if (isSelected) {
       
  1361                 QRect highlightRect = option->rect.adjusted(1,1,-1,-1);
       
  1362                 const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget);
       
  1363                 if (view && view->selectionBehavior() != QAbstractItemView::SelectItems) {
       
  1364                     // set highlight rect so that it is continuous from cell to cell, yet sligthly
       
  1365                     // smaller than cell rect
       
  1366                     int xBeginning = 0, yBeginning = 0, xEnd = 0, yEnd = 0;
       
  1367                     if (view->selectionBehavior() == QAbstractItemView::SelectRows) {
       
  1368                         yBeginning = 1; yEnd = -1;
       
  1369                         if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning)
       
  1370                             xBeginning = 1;
       
  1371                         else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End)
       
  1372                             xEnd = -1;
       
  1373                     } else if (view->selectionBehavior() == QAbstractItemView::SelectColumns) {
       
  1374                         xBeginning = 1; xEnd = -1;
       
  1375                         if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning)
       
  1376                             yBeginning = 1;
       
  1377                         else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End)
       
  1378                             yEnd = -1;
       
  1379                     }
       
  1380                     highlightRect = option->rect.adjusted(xBeginning, yBeginning, xEnd, xBeginning);
       
  1381                 }
       
  1382                 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, highlightRect, flags);
       
  1383             }
       
  1384 
       
  1385              // draw the icon
       
  1386              const QIcon::Mode mode = (voptAdj.state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled;
       
  1387              const QIcon::State state = voptAdj.state & QStyle::State_Open ? QIcon::On : QIcon::Off;
       
  1388              voptAdj.icon.paint(painter, iconRect, voptAdj.decorationAlignment, mode, state);
       
  1389 
       
  1390              // Draw selection check mark. Show check mark only in multi selection modes.
       
  1391              if (const QListView *listView = (qobject_cast<const QListView *>(widget))) {
       
  1392                  const bool singleSelection =
       
  1393                      listView &&
       
  1394                      (listView->selectionMode() == QAbstractItemView::SingleSelection ||
       
  1395                      listView->selectionMode() == QAbstractItemView::NoSelection);
       
  1396                  const QRect selectionRect = subElementRect(SE_ItemViewItemCheckIndicator, &voptAdj, widget);
       
  1397                  if (voptAdj.state & QStyle::State_Selected && !singleSelection) {
       
  1398                      QStyleOptionViewItemV4 option(voptAdj);
       
  1399                      option.rect = selectionRect;
       
  1400                      // Draw selection mark.
       
  1401                      drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option, painter, widget);
       
  1402                      if ( textRect.right() > selectionRect.left() )
       
  1403                          textRect.setRight(selectionRect.left());
       
  1404                  } else if (singleSelection &&
       
  1405                      voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator) {
       
  1406                      // draw the check mark
       
  1407                      if (selectionRect.isValid()) {
       
  1408                          QStyleOptionViewItemV4 option(*vopt);
       
  1409                          option.rect = selectionRect;
       
  1410                          option.state = option.state & ~QStyle::State_HasFocus;
       
  1411 
       
  1412                          switch (vopt->checkState) {
       
  1413                          case Qt::Unchecked:
       
  1414                              option.state |= QStyle::State_Off;
       
  1415                              break;
       
  1416                          case Qt::PartiallyChecked:
       
  1417                              option.state |= QStyle::State_NoChange;
       
  1418                              break;
       
  1419                          case Qt::Checked:
       
  1420                              option.state |= QStyle::State_On;
       
  1421                              break;
       
  1422                          }
       
  1423                          drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option, painter, widget);
       
  1424                      }
       
  1425                  }
       
  1426              }
       
  1427 
       
  1428              // draw the text
       
  1429             if (!voptAdj.text.isEmpty()) {
       
  1430                 const QStyleOptionViewItemV4 *tableOption = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option);
       
  1431                 if (isSelected) {
       
  1432                     if (qobject_cast<const QTableView *>(widget) && tableOption)
       
  1433                         voptAdj.palette.setColor(
       
  1434                             QPalette::Text, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 11, 0));
       
  1435                     else
       
  1436                         voptAdj.palette.setColor(
       
  1437                             QPalette::Text, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 10, 0));
       
  1438                 }
       
  1439                 painter->setPen(voptAdj.palette.text().color());
       
  1440                 d->viewItemDrawText(painter, &voptAdj, textRect);
       
  1441             }
       
  1442             painter->restore();
       
  1443         }
       
  1444         break;
       
  1445 #endif // QT_NO_ITEMVIEWS
       
  1446 #ifndef QT_NO_TABBAR
       
  1447     case CE_TabBarTabShape:
       
  1448         if (const QStyleOptionTabV3 *optionTab = qstyleoption_cast<const QStyleOptionTabV3 *>(option)) {
       
  1449             QStyleOptionTabV3 optionTabAdj = *optionTab;
       
  1450             const bool isSelected = optionTab->state & QStyle::State_Selected;
       
  1451             const bool directionMirrored = (optionTab->direction == Qt::RightToLeft);
       
  1452             QS60StylePrivate::SkinElements skinElement;
       
  1453             switch (optionTab->shape) {
       
  1454                 case QTabBar::TriangularEast:
       
  1455                 case QTabBar::RoundedEast:
       
  1456                     skinElement = isSelected ? QS60StylePrivate::SE_TabBarTabEastActive:
       
  1457                         QS60StylePrivate::SE_TabBarTabEastInactive;
       
  1458                     break;
       
  1459                 case QTabBar::TriangularSouth:
       
  1460                 case QTabBar::RoundedSouth:
       
  1461                     skinElement = isSelected ? QS60StylePrivate::SE_TabBarTabSouthActive:
       
  1462                         QS60StylePrivate::SE_TabBarTabSouthInactive;
       
  1463                     break;
       
  1464                 case QTabBar::TriangularWest:
       
  1465                 case QTabBar::RoundedWest:
       
  1466                     skinElement = isSelected ? QS60StylePrivate::SE_TabBarTabWestActive:
       
  1467                         QS60StylePrivate::SE_TabBarTabWestInactive;
       
  1468                     break;
       
  1469                 case QTabBar::TriangularNorth:
       
  1470                 case QTabBar::RoundedNorth:
       
  1471                 default:
       
  1472                     skinElement = isSelected ? QS60StylePrivate::SE_TabBarTabNorthActive:
       
  1473                         QS60StylePrivate::SE_TabBarTabNorthInactive;
       
  1474                     break;
       
  1475             }
       
  1476             if (skinElement==QS60StylePrivate::SE_TabBarTabEastInactive||
       
  1477                     skinElement==QS60StylePrivate::SE_TabBarTabNorthInactive||
       
  1478                     skinElement==QS60StylePrivate::SE_TabBarTabSouthInactive||
       
  1479                     skinElement==QS60StylePrivate::SE_TabBarTabWestInactive||
       
  1480                     skinElement==QS60StylePrivate::SE_TabBarTabEastActive||
       
  1481                     skinElement==QS60StylePrivate::SE_TabBarTabNorthActive||
       
  1482                     skinElement==QS60StylePrivate::SE_TabBarTabSouthActive||
       
  1483                     skinElement==QS60StylePrivate::SE_TabBarTabWestActive) {
       
  1484                 const int borderThickness =
       
  1485                     QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth);
       
  1486                 const int tabOverlap =
       
  1487                     QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap) - borderThickness;
       
  1488                 //todo: draw navi wipe behind tabbar - must be drawn with first draw
       
  1489 
       
  1490                 if (skinElement==QS60StylePrivate::SE_TabBarTabEastInactive||
       
  1491                         skinElement==QS60StylePrivate::SE_TabBarTabEastActive||
       
  1492                         skinElement==QS60StylePrivate::SE_TabBarTabWestInactive||
       
  1493                         skinElement==QS60StylePrivate::SE_TabBarTabWestActive){
       
  1494                     optionTabAdj.rect.adjust(0, 0, 0, tabOverlap);
       
  1495                 } else {
       
  1496                     if (directionMirrored)
       
  1497                         optionTabAdj.rect.adjust(-tabOverlap, 0, 0, 0);
       
  1498                     else
       
  1499                         optionTabAdj.rect.adjust(0, 0, tabOverlap, 0);
       
  1500                     }
       
  1501             }
       
  1502             QS60StylePrivate::drawSkinElement(skinElement, painter, optionTabAdj.rect, flags);
       
  1503         }
       
  1504         break;
       
  1505     case CE_TabBarTabLabel:
       
  1506         if (const QStyleOptionTabV3 *tab = qstyleoption_cast<const QStyleOptionTabV3 *>(option)) {
       
  1507             QStyleOptionTabV3 optionTab = *tab;
       
  1508             QRect tr = optionTab.rect;
       
  1509             const bool directionMirrored = (optionTab.direction == Qt::RightToLeft);
       
  1510             const int borderThickness = QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth);
       
  1511             const int tabOverlap =
       
  1512                 QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap) - borderThickness;
       
  1513             const QRect windowRect = painter->window();
       
  1514 
       
  1515             switch (tab->shape) {
       
  1516                 case QTabBar::TriangularWest:
       
  1517                 case QTabBar::RoundedWest:
       
  1518                 case QTabBar::TriangularEast:
       
  1519                 case QTabBar::RoundedEast:
       
  1520                     tr.adjust(0, 0, 0, tabOverlap);
       
  1521                     break;
       
  1522                 case QTabBar::TriangularSouth:
       
  1523                 case QTabBar::RoundedSouth:
       
  1524                 case QTabBar::TriangularNorth:
       
  1525                 case QTabBar::RoundedNorth:
       
  1526                 default:
       
  1527                     if (directionMirrored)
       
  1528                         tr.adjust(-tabOverlap, 0, 0, 0);
       
  1529                     else
       
  1530                         tr.adjust(0, 0, tabOverlap, 0);
       
  1531                     break;
       
  1532             }
       
  1533             painter->save();
       
  1534             QFont f = painter->font();
       
  1535             f.setPointSizeF(f.pointSizeF() * KTabFontMul);
       
  1536             painter->setFont(f);
       
  1537 
       
  1538             if (option->state & QStyle::State_Selected){
       
  1539                 optionTab.palette.setColor(QPalette::Active, QPalette::WindowText,
       
  1540                     QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 3, option));
       
  1541             }
       
  1542 
       
  1543             const bool verticalTabs = optionTab.shape == QTabBar::RoundedEast
       
  1544                                 || optionTab.shape == QTabBar::RoundedWest
       
  1545                                 || optionTab.shape == QTabBar::TriangularEast
       
  1546                                 || optionTab.shape == QTabBar::TriangularWest;
       
  1547             const bool selected = optionTab.state & State_Selected;
       
  1548             if (verticalTabs) {
       
  1549                 painter->save();
       
  1550                 int newX, newY, newRotation;
       
  1551                 if (optionTab.shape == QTabBar::RoundedEast || optionTab.shape == QTabBar::TriangularEast) {
       
  1552                     newX = tr.width();
       
  1553                     newY = tr.y();
       
  1554                     newRotation = 90;
       
  1555                 } else {
       
  1556                     newX = 0;
       
  1557                     newY = tr.y() + tr.height();
       
  1558                     newRotation = -90;
       
  1559                 }
       
  1560                 tr.setRect(0, 0, tr.height(), tr.width());
       
  1561                 QTransform m;
       
  1562                 m.translate(newX, newY);
       
  1563                 m.rotate(newRotation);
       
  1564                 painter->setTransform(m, true);
       
  1565             }
       
  1566             tr.adjust(0, 0, pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget),
       
  1567                             pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget));
       
  1568 
       
  1569             if (selected) {
       
  1570                 tr.setBottom(tr.bottom() - pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget));
       
  1571                 tr.setRight(tr.right() - pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget));
       
  1572             }
       
  1573 
       
  1574             int alignment = Qt::AlignCenter | Qt::TextShowMnemonic;
       
  1575             if (!styleHint(SH_UnderlineShortcut, &optionTab, widget))
       
  1576                 alignment |= Qt::TextHideMnemonic;
       
  1577             if (!optionTab.icon.isNull()) {
       
  1578                 QSize iconSize = optionTab.iconSize;
       
  1579                 int iconExtent = pixelMetric(PM_TabBarIconSize);
       
  1580                 if (iconSize.height() > iconExtent || iconSize.width() > iconExtent)
       
  1581                     iconSize = QSize(iconExtent, iconExtent);
       
  1582                 QPixmap tabIcon = optionTab.icon.pixmap(iconSize,
       
  1583                     (optionTab.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled);
       
  1584                 if (tab->text.isEmpty())
       
  1585                     painter->drawPixmap(tr.center().x() - (tabIcon.height() >>1),
       
  1586                                         tr.center().y() - (tabIcon.height() >>1),
       
  1587                                         tabIcon);
       
  1588                 else
       
  1589                     painter->drawPixmap(tr.left() + tabOverlap,
       
  1590                                         tr.center().y() - (tabIcon.height() >>1),
       
  1591                                         tabIcon);
       
  1592                 tr.setLeft(tr.left() + iconSize.width() + 4);
       
  1593             }
       
  1594 
       
  1595             QCommonStyle::drawItemText(painter, tr, alignment, optionTab.palette, tab->state & State_Enabled, tab->text, QPalette::WindowText);
       
  1596             if (verticalTabs)
       
  1597                 painter->restore();
       
  1598 
       
  1599             painter->restore();
       
  1600         }
       
  1601         break;
       
  1602 #endif // QT_NO_TABBAR
       
  1603 #ifndef QT_NO_PROGRESSBAR
       
  1604     case CE_ProgressBarContents:
       
  1605         if (const QStyleOptionProgressBarV2 *optionProgressBar = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
       
  1606             QRect progressRect = optionProgressBar->rect;
       
  1607 
       
  1608             if (optionProgressBar->minimum == optionProgressBar->maximum && optionProgressBar->minimum == 0) {
       
  1609                 // busy indicator
       
  1610                 const QS60StylePrivate::SkinElementFlag orientationFlag = optionProgressBar->orientation == Qt::Horizontal ?
       
  1611                     QS60StylePrivate::SF_PointNorth : QS60StylePrivate::SF_PointWest;
       
  1612                 QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafBarWait, painter, progressRect, flags | orientationFlag);
       
  1613             } else {
       
  1614                 const qreal progressFactor = (optionProgressBar->minimum == optionProgressBar->maximum) ? 1.0
       
  1615                     : (qreal)optionProgressBar->progress / optionProgressBar->maximum;
       
  1616                 if (optionProgressBar->orientation == Qt::Horizontal) {
       
  1617                     progressRect.setWidth(int(progressRect.width() * progressFactor));
       
  1618                     if(optionProgressBar->direction == Qt::RightToLeft)
       
  1619                         progressRect.translate(optionProgressBar->rect.width()-progressRect.width(),0);
       
  1620                     progressRect.adjust(1, 0, -1, 0);
       
  1621                 } else {
       
  1622                     progressRect.adjust(0, 1, 0, -1);
       
  1623                     progressRect.setTop(progressRect.bottom() - int(progressRect.height() * progressFactor));
       
  1624                 }
       
  1625 
       
  1626                 const QS60StylePrivate::SkinElements skinElement = optionProgressBar->orientation == Qt::Horizontal ?
       
  1627                     QS60StylePrivate::SE_ProgressBarIndicatorHorizontal : QS60StylePrivate::SE_ProgressBarIndicatorVertical;
       
  1628                 QS60StylePrivate::drawSkinElement(skinElement, painter, progressRect, flags);
       
  1629             }
       
  1630         }
       
  1631         break;
       
  1632     case CE_ProgressBarGroove:
       
  1633         if (const QStyleOptionProgressBarV2 *optionProgressBar = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
       
  1634             const QS60StylePrivate::SkinElements skinElement = optionProgressBar->orientation == Qt::Horizontal ?
       
  1635                 QS60StylePrivate::SE_ProgressBarGrooveHorizontal : QS60StylePrivate::SE_ProgressBarGrooveVertical;
       
  1636             QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags);
       
  1637         }
       
  1638         break;
       
  1639     case CE_ProgressBarLabel:
       
  1640         if (const QStyleOptionProgressBarV2 *progressbar = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
       
  1641             QStyleOptionProgressBarV2 optionProgressBar = *progressbar;
       
  1642             QCommonStyle::drawItemText(painter, progressbar->rect, flags | Qt::AlignCenter | Qt::TextSingleLine, optionProgressBar.palette,
       
  1643                 progressbar->state & State_Enabled, progressbar->text, QPalette::WindowText);
       
  1644         }
       
  1645         break;
       
  1646 #endif // QT_NO_PROGRESSBAR
       
  1647 #ifndef QT_NO_MENU
       
  1648     case CE_MenuItem:
       
  1649         if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
       
  1650             QStyleOptionMenuItem optionMenuItem = *menuItem;
       
  1651 
       
  1652             bool drawSubMenuIndicator = false;
       
  1653             switch(menuItem->menuItemType) {
       
  1654                 case QStyleOptionMenuItem::Scroller:
       
  1655                 case QStyleOptionMenuItem::Separator:
       
  1656                     return; // no separators or scrollers in S60 menus
       
  1657                 case QStyleOptionMenuItem::SubMenu:
       
  1658                     drawSubMenuIndicator = true;
       
  1659                     break;
       
  1660                 default:
       
  1661                     break;
       
  1662             }
       
  1663             const bool enabled = optionMenuItem.state & State_Enabled;
       
  1664             const bool checkable = optionMenuItem.checkType != QStyleOptionMenuItem::NotCheckable;
       
  1665 
       
  1666             uint text_flags = Qt::AlignLeading | Qt::TextShowMnemonic | Qt::TextDontClip
       
  1667                             | Qt::TextSingleLine | Qt::AlignVCenter;
       
  1668             if (!styleHint(SH_UnderlineShortcut, menuItem, widget))
       
  1669                 text_flags |= Qt::TextHideMnemonic;
       
  1670 
       
  1671             QRect iconRect =
       
  1672                 subElementRect(SE_ItemViewItemDecoration, &optionMenuItem, widget);
       
  1673             QRect textRect = subElementRect(SE_ItemViewItemText, &optionMenuItem, widget);
       
  1674 
       
  1675             if ((option->state & State_Selected) && (option->state & State_Enabled))
       
  1676                 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags);
       
  1677 
       
  1678             //todo: move the vertical spacing stuff into subElementRect
       
  1679             const int vSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing);
       
  1680             if (checkable){
       
  1681                 QStyleOptionMenuItem optionCheckBox;
       
  1682                 optionCheckBox.QStyleOption::operator=(*menuItem);
       
  1683                 optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth));
       
  1684                 optionCheckBox.rect.setHeight(pixelMetric(PM_IndicatorHeight));
       
  1685                 const int moveByX = optionCheckBox.rect.width()+vSpacing;
       
  1686                 if (optionMenuItem.direction == Qt::LeftToRight) {
       
  1687                     textRect.translate(moveByX,0);
       
  1688                     iconRect.translate(moveByX, 0);
       
  1689                     iconRect.setWidth(iconRect.width()+vSpacing);
       
  1690                     textRect.setWidth(textRect.width()-moveByX-vSpacing);
       
  1691                 } else {
       
  1692                     textRect.setWidth(textRect.width()-moveByX);
       
  1693                     iconRect.setWidth(iconRect.width()+vSpacing);
       
  1694                     iconRect.translate(-optionCheckBox.rect.width()-vSpacing, 0);
       
  1695                     optionCheckBox.rect.translate(textRect.width()+iconRect.width(),0);
       
  1696                 }
       
  1697                 drawPrimitive(PE_IndicatorMenuCheckMark, &optionCheckBox, painter, widget);
       
  1698             }
       
  1699             //draw icon and/or checkState
       
  1700             QPixmap pix = menuItem->icon.pixmap(pixelMetric(PM_SmallIconSize),
       
  1701                 enabled ? QIcon::Normal : QIcon::Disabled);
       
  1702             const bool itemWithIcon = !pix.isNull();
       
  1703             if (itemWithIcon) {
       
  1704                 drawItemPixmap(painter, iconRect, text_flags, pix);
       
  1705                 if (optionMenuItem.direction == Qt::LeftToRight)
       
  1706                     textRect.translate(vSpacing,0);
       
  1707                 else
       
  1708                     textRect.translate(-vSpacing,0);
       
  1709                 textRect.setWidth(textRect.width()-vSpacing);
       
  1710             }
       
  1711 
       
  1712             //draw indicators
       
  1713             if (drawSubMenuIndicator) {
       
  1714                 QStyleOptionMenuItem arrowOptions;
       
  1715                 arrowOptions.QStyleOption::operator=(*menuItem);
       
  1716                 const int indicatorWidth = (pixelMetric(PM_ListViewIconSize, option, widget)>>1) +
       
  1717                     pixelMetric(QStyle::PM_LayoutVerticalSpacing, option, widget);
       
  1718                 if (optionMenuItem.direction == Qt::LeftToRight)
       
  1719                     arrowOptions.rect.setLeft(textRect.right());
       
  1720                 arrowOptions.rect.setWidth(indicatorWidth);
       
  1721                 //by default sub menu indicator in S60 points to east,so here icon
       
  1722                 // direction is set to north (and south when in RightToLeft)
       
  1723                 const QS60StylePrivate::SkinElementFlag arrowDirection = (arrowOptions.direction == Qt::LeftToRight) ?
       
  1724                     QS60StylePrivate::SF_PointNorth : QS60StylePrivate::SF_PointSouth;
       
  1725                 QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnIndiSubMenu, painter, arrowOptions.rect,
       
  1726                     (flags | QS60StylePrivate::SF_ColorSkinned | arrowDirection));
       
  1727             }
       
  1728 
       
  1729             //draw text
       
  1730             if (!enabled){
       
  1731                 //In s60, if something becomes disabled, it is removed from menu, so no native look-alike available.
       
  1732                 optionMenuItem.palette.setColor(QPalette::Disabled, QPalette::Text, QS60StylePrivate::lighterColor(
       
  1733                         optionMenuItem.palette.color(QPalette::Disabled, QPalette::Text)));
       
  1734                 painter->save();
       
  1735                 painter->setOpacity(0.5);
       
  1736             }
       
  1737             QCommonStyle::drawItemText(painter, textRect, text_flags,
       
  1738                     optionMenuItem.palette, enabled,
       
  1739                     optionMenuItem.text, QPalette::Text);
       
  1740             if (!enabled)
       
  1741                 painter->restore();
       
  1742         }
       
  1743         break;
       
  1744     case CE_MenuEmptyArea:
       
  1745         break;
       
  1746 #endif //QT_NO_MENU
       
  1747 
       
  1748 #ifndef QT_NO_MENUBAR
       
  1749     case CE_MenuBarEmptyArea:
       
  1750         break;
       
  1751 #endif //QT_NO_MENUBAR
       
  1752 
       
  1753     case CE_HeaderSection:
       
  1754         if ( const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
       
  1755             painter->save();
       
  1756             QPen linePen = QPen(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 1, header));
       
  1757             const int penWidth = (header->orientation == Qt::Horizontal) ?
       
  1758                 linePen.width()+QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth)
       
  1759                 : linePen.width()+QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth);
       
  1760             linePen.setWidth(penWidth);
       
  1761             painter->setPen(linePen);
       
  1762             if (header->orientation == Qt::Horizontal){
       
  1763                 painter->drawLine(header->rect.bottomLeft(), header->rect.bottomRight());
       
  1764             } else {
       
  1765                 if ( header->direction == Qt::LeftToRight ) {
       
  1766                     painter->drawLine(header->rect.topRight(), header->rect.bottomRight());
       
  1767                 } else {
       
  1768                     painter->drawLine(header->rect.topLeft(), header->rect.bottomLeft());
       
  1769                 }
       
  1770             }
       
  1771             painter->restore();
       
  1772         }
       
  1773         break;
       
  1774     case CE_HeaderEmptyArea: // no need to draw this
       
  1775         break;
       
  1776     case CE_Header:
       
  1777         if ( const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
       
  1778             drawControl(CE_HeaderSection, header, painter, widget);
       
  1779             QStyleOptionHeader subopt = *header;
       
  1780             subopt.rect = subElementRect(SE_HeaderLabel, header, widget);
       
  1781             if (subopt.rect.isValid())
       
  1782                 drawControl(CE_HeaderLabel, &subopt, painter, widget);
       
  1783             if (header->sortIndicator != QStyleOptionHeader::None) {
       
  1784                 subopt.rect = subElementRect(SE_HeaderArrow, option, widget);
       
  1785                 drawPrimitive(PE_IndicatorHeaderArrow, &subopt, painter, widget);
       
  1786             }
       
  1787         }
       
  1788         break;
       
  1789 #ifndef QT_NO_TOOLBAR
       
  1790     case CE_ToolBar:
       
  1791         if (const QStyleOptionToolBar *toolBar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) {
       
  1792             const QToolBar *tbWidget = qobject_cast<const QToolBar *>(widget);
       
  1793 
       
  1794             //toolbar within a toolbar, skip
       
  1795             if (!tbWidget || (widget && qobject_cast<QToolBar *>(widget->parentWidget())))
       
  1796                 break;
       
  1797 
       
  1798             // Normally in S60 5.0+ there is no background for toolbar, but in some cases with versatile QToolBar,
       
  1799             // it looks a bit strange. So, lets fillRect with Button.
       
  1800             if (!QS60StylePrivate::isToolBarBackground()) {
       
  1801                 QList<QAction *> actions = tbWidget->actions();
       
  1802                 bool justToolButtonsInToolBar = true;
       
  1803                 for (int i = 0; i < actions.size(); ++i) {
       
  1804                     QWidget *childWidget = tbWidget->widgetForAction(actions.at(i));
       
  1805                     const QToolButton *button = qobject_cast<const QToolButton *>(childWidget);
       
  1806                     if (!button){
       
  1807                         justToolButtonsInToolBar = false;
       
  1808                     }
       
  1809                 }
       
  1810 
       
  1811                 // Draw frame background
       
  1812                 // for vertical toolbars with text only and
       
  1813                 // for toolbars with extension buttons and
       
  1814                 // for toolbars with widgets in them.
       
  1815                 if (!justToolButtonsInToolBar ||
       
  1816                         (tbWidget &&
       
  1817                          (tbWidget->orientation() == Qt::Vertical) &&
       
  1818                          (tbWidget->toolButtonStyle() == Qt::ToolButtonTextOnly))) {
       
  1819                         painter->save();
       
  1820                         if (widget)
       
  1821                             painter->setBrush(widget->palette().button());
       
  1822                         painter->setOpacity(0.3);
       
  1823                         painter->fillRect(toolBar->rect, painter->brush());
       
  1824                         painter->restore();
       
  1825                 }
       
  1826             } else {
       
  1827                 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBar, painter, toolBar->rect, flags);
       
  1828             }
       
  1829         }
       
  1830         break;
       
  1831 #endif //QT_NO_TOOLBAR
       
  1832     case CE_ShapedFrame:
       
  1833         if (qobject_cast<const QTextEdit *>(widget)) {
       
  1834             QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_Editor, painter, option->rect, flags);
       
  1835         } else if (qobject_cast<const QTableView *>(widget)) {
       
  1836             QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_TableItem, painter, option->rect, flags);
       
  1837         } else if (const QHeaderView *header = qobject_cast<const QHeaderView *>(widget)) {
       
  1838             if (header->orientation() == Qt::Horizontal) {
       
  1839                 QRect headerRect = option->rect;
       
  1840                 const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
       
  1841                 headerRect.adjust(0,frameWidth,-2*frameWidth,0);
       
  1842                 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_TableHeaderItem, painter, headerRect, flags);
       
  1843             } else {
       
  1844                 //todo: update to horizontal table graphic
       
  1845                 QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_TableHeaderItem, painter, option->rect, flags | QS60StylePrivate::SF_PointWest);
       
  1846             }
       
  1847         } else if (qobject_cast<const QFrame *>(widget)) {
       
  1848             QCommonStyle::drawControl(element, option, painter, widget);
       
  1849         }
       
  1850         break;
       
  1851     case CE_MenuScroller:
       
  1852         break;
       
  1853     case CE_FocusFrame:
       
  1854         {
       
  1855             // The pen width should nearly fill the layoutspacings around the widget
       
  1856             const int penWidth =
       
  1857                 qMin(pixelMetric(QS60Style::PM_LayoutVerticalSpacing), pixelMetric(QS60Style::PM_LayoutHorizontalSpacing))
       
  1858                 - 2; // But keep 1 pixel distance to the focus widget and 1 pixel to the adjacent widgets
       
  1859 
       
  1860 #ifdef QT_KEYPAD_NAVIGATION
       
  1861             bool editFocus = false;
       
  1862             if (const QFocusFrame *focusFrame = qobject_cast<const QFocusFrame*>(widget)) {
       
  1863                 if (focusFrame->widget() && focusFrame->widget()->hasEditFocus())
       
  1864                     editFocus = true;
       
  1865             }
       
  1866             const qreal opacity = editFocus ? 0.65 : 0.45; // Trial and error factors. Feel free to improve.
       
  1867 #else
       
  1868             const qreal opacity = 0.5;
       
  1869 #endif
       
  1870             // Because of Qts coordinate system, we need to tweak the rect by .5 pixels, otherwise it gets blurred.
       
  1871             const qreal rectAdjustment = (penWidth % 2) ? -.5 : 0;
       
  1872 
       
  1873             // Make sure that the pen stroke is inside the rect
       
  1874             const QRectF adjustedRect =
       
  1875                 QRectF(option->rect).adjusted(
       
  1876                     rectAdjustment + penWidth,
       
  1877                     rectAdjustment + penWidth,
       
  1878                     -rectAdjustment - penWidth,
       
  1879                     -rectAdjustment - penWidth
       
  1880                 );
       
  1881 
       
  1882             const qreal roundRectRadius = penWidth * goldenRatio;
       
  1883 
       
  1884             painter->save();
       
  1885             painter->setRenderHint(QPainter::Antialiasing);
       
  1886             painter->setOpacity(opacity);
       
  1887             painter->setPen(QPen(option->palette.color(QPalette::Text), penWidth));
       
  1888             painter->drawRoundedRect(adjustedRect, roundRectRadius, roundRectRadius);
       
  1889             painter->restore();
       
  1890         }
       
  1891         break;
       
  1892     default:
       
  1893         QCommonStyle::drawControl(element, option, painter, widget);
       
  1894     }
       
  1895 }
       
  1896 
       
  1897 /*!
       
  1898   \reimp
       
  1899 */
       
  1900 void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
       
  1901 {
       
  1902     const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ?  QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled;
       
  1903     switch (element) {
       
  1904 #ifndef QT_NO_LINEEDIT
       
  1905     case PE_PanelLineEdit:
       
  1906         if (const QStyleOptionFrame *lineEdit = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
       
  1907 #ifndef QT_NO_COMBOBOX
       
  1908             if (widget && qobject_cast<const QComboBox *>(widget->parentWidget()))
       
  1909                 break;
       
  1910 #endif
       
  1911             QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_FrameLineEdit,
       
  1912                 painter, option->rect, flags);
       
  1913         }
       
  1914     break;
       
  1915 #endif // QT_NO_LINEEDIT
       
  1916     case PE_IndicatorCheckBox:
       
  1917         {
       
  1918             const QRect indicatorRect = option->rect;
       
  1919             // Draw checkbox indicator as color skinned graphics.
       
  1920             const QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ?
       
  1921                 QS60StyleEnums::SP_QgnIndiCheckboxOn : QS60StyleEnums::SP_QgnIndiCheckboxOff;
       
  1922             QS60StylePrivate::drawSkinPart(skinPart, painter, indicatorRect,
       
  1923                 (flags | QS60StylePrivate::SF_ColorSkinned));
       
  1924         }
       
  1925         break;
       
  1926     case PE_IndicatorViewItemCheck:
       
  1927 #ifndef QT_NO_ITEMVIEWS
       
  1928         if (const QListView *listItem = (qobject_cast<const QListView *>(widget))) {
       
  1929             if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
       
  1930                 const bool checkBoxVisible = vopt->features & QStyleOptionViewItemV2::HasCheckIndicator;
       
  1931                 const bool singleSelection = listItem->selectionMode() ==
       
  1932                     QAbstractItemView::SingleSelection || listItem->selectionMode() == QAbstractItemView::NoSelection;
       
  1933                 // draw either checkbox at the beginning
       
  1934                 if (checkBoxVisible && singleSelection) {
       
  1935                     drawPrimitive(PE_IndicatorCheckBox, option, painter, widget);
       
  1936                 // ... or normal "tick" selection at the end.
       
  1937                 } else if (option->state & QStyle::State_Selected) {
       
  1938                     QRect tickRect = option->rect;
       
  1939                     const int frameBorderWidth = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth);
       
  1940                     // adjust tickmark rect to exclude frame border
       
  1941                     tickRect.adjust(0,-frameBorderWidth,0,-frameBorderWidth);
       
  1942                     QS60StyleEnums::SkinParts skinPart = QS60StyleEnums::SP_QgnIndiMarkedAdd;
       
  1943                     QS60StylePrivate::drawSkinPart(skinPart, painter, tickRect,
       
  1944                         (flags | QS60StylePrivate::SF_ColorSkinned));
       
  1945                 }
       
  1946             }
       
  1947         }
       
  1948 #endif //QT_NO_ITEMVIEWS
       
  1949         break;
       
  1950     case PE_IndicatorRadioButton: {
       
  1951             QRect buttonRect = option->rect;
       
  1952             //there is empty (a. 33%) space in svg graphics for radiobutton
       
  1953             const qreal reduceWidth = (qreal)buttonRect.width()/3.0;
       
  1954             const qreal rectWidth = (qreal)option->rect.width() != 0 ? option->rect.width() : 1.0;
       
  1955             // Try to occupy the full area
       
  1956             const qreal scaler = 1 + (reduceWidth/rectWidth);
       
  1957             buttonRect.setWidth((int)((buttonRect.width()-reduceWidth) * scaler));
       
  1958             buttonRect.setHeight((int)(buttonRect.height() * scaler));
       
  1959             // move the rect up for half of the new height-gain
       
  1960             const int newY = (buttonRect.bottomRight().y() - option->rect.bottomRight().y()) >> 1 ;
       
  1961             buttonRect.adjust(0,-newY,0,-newY);
       
  1962 
       
  1963             // Draw radiobutton indicator as color skinned graphics.
       
  1964             QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ?
       
  1965                 QS60StyleEnums::SP_QgnIndiRadiobuttOn : QS60StyleEnums::SP_QgnIndiRadiobuttOff;
       
  1966             QS60StylePrivate::drawSkinPart(skinPart, painter, buttonRect,
       
  1967                 (flags | QS60StylePrivate::SF_ColorSkinned));
       
  1968         }
       
  1969         break;
       
  1970     case PE_PanelButtonCommand:
       
  1971     case PE_PanelButtonTool:
       
  1972     case PE_PanelButtonBevel:
       
  1973     case PE_FrameButtonBevel: {
       
  1974         const bool isPressed = option->state & QStyle::State_Sunken;
       
  1975         const QS60StylePrivate::SkinElements skinElement =
       
  1976             isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal;
       
  1977         QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags);
       
  1978         }
       
  1979         break;
       
  1980 #ifndef QT_NO_TOOLBUTTON
       
  1981     case PE_IndicatorArrowDown:
       
  1982     case PE_IndicatorArrowLeft:
       
  1983     case PE_IndicatorArrowRight:
       
  1984     case PE_IndicatorArrowUp: {
       
  1985         QS60StyleEnums::SkinParts skinPart;
       
  1986         if (element==PE_IndicatorArrowDown)
       
  1987             skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowDown;
       
  1988         else if (element==PE_IndicatorArrowLeft)
       
  1989             skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowLeft;
       
  1990         else if (element==PE_IndicatorArrowRight)
       
  1991             skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowRight;
       
  1992         else if (element==PE_IndicatorArrowUp)
       
  1993             skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowUp;
       
  1994 
       
  1995         QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags);
       
  1996         }
       
  1997         break;
       
  1998 #endif //QT_NO_TOOLBUTTON
       
  1999 #ifndef QT_NO_SPINBOX
       
  2000     case PE_IndicatorSpinDown:
       
  2001     case PE_IndicatorSpinUp:
       
  2002         if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
       
  2003             QStyleOptionSpinBox optionSpinBox = *spinBox;
       
  2004             const QS60StyleEnums::SkinParts part = (element == PE_IndicatorSpinUp) ?
       
  2005                 QS60StyleEnums::SP_QgnGrafScrollArrowUp :
       
  2006                 QS60StyleEnums::SP_QgnGrafScrollArrowDown;
       
  2007             const int adjustment = qMin(optionSpinBox.rect.width(), optionSpinBox.rect.height())/6;
       
  2008             optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment );
       
  2009             QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect,flags);
       
  2010         }
       
  2011 #ifndef QT_NO_COMBOBOX
       
  2012         else if (const QStyleOptionFrame *cmb = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
       
  2013             // We want to draw down arrow here for comboboxes as well.
       
  2014             const QS60StyleEnums::SkinParts part = QS60StyleEnums::SP_QgnGrafScrollArrowDown;
       
  2015             QStyleOptionFrame comboBox = *cmb;
       
  2016             const int adjustment = qMin(comboBox.rect.width(), comboBox.rect.height())/6;
       
  2017             comboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment );
       
  2018             QS60StylePrivate::drawSkinPart(part, painter, comboBox.rect,flags);
       
  2019         }
       
  2020 #endif //QT_NO_COMBOBOX
       
  2021         break;
       
  2022     case PE_IndicatorSpinMinus:
       
  2023     case PE_IndicatorSpinPlus:
       
  2024         if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
       
  2025             QStyleOptionSpinBox optionSpinBox = *spinBox;
       
  2026             QCommonStyle::drawPrimitive(element, &optionSpinBox, painter, widget);
       
  2027         }
       
  2028 #ifndef QT_NO_COMBOBOX
       
  2029         else if (const QStyleOptionFrame *cmb = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
       
  2030             // We want to draw down arrow here for comboboxes as well.
       
  2031             QStyleOptionFrame comboBox = *cmb;
       
  2032             const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
       
  2033             comboBox.rect.adjust(0,frameWidth,0,-frameWidth);
       
  2034             QCommonStyle::drawPrimitive(element, &comboBox, painter, widget);
       
  2035         }
       
  2036 #endif //QT_NO_COMBOBOX
       
  2037         break;
       
  2038 #endif //QT_NO_SPINBOX
       
  2039     case PE_Widget:
       
  2040         if (QS60StylePrivate::drawsOwnThemeBackground(widget)
       
  2041 #ifndef QT_NO_COMBOBOX
       
  2042             || qobject_cast<const QComboBoxListView *>(widget)
       
  2043 #endif //QT_NO_COMBOBOX
       
  2044 #ifndef QT_NO_MENU
       
  2045             || qobject_cast<const QMenu *> (widget)
       
  2046 #endif //QT_NO_MENU
       
  2047             ) {
       
  2048             QS60StylePrivate::SkinElements skinElement = QS60StylePrivate::SE_OptionsMenu;
       
  2049             QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags);
       
  2050         }
       
  2051         break;
       
  2052     case PE_FrameWindow:
       
  2053     case PE_FrameTabWidget:
       
  2054         if (const QStyleOptionTabWidgetFrame *tabFrame = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
       
  2055             QStyleOptionTabWidgetFrame optionTabFrame = *tabFrame;
       
  2056             QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_PanelBackground, painter, optionTabFrame.rect, flags);
       
  2057         }
       
  2058         break;
       
  2059     case PE_IndicatorHeaderArrow:
       
  2060         if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
       
  2061             if (header->sortIndicator & QStyleOptionHeader::SortUp)
       
  2062                 drawPrimitive(PE_IndicatorArrowUp, header, painter, widget);
       
  2063             else if (header->sortIndicator & QStyleOptionHeader::SortDown)
       
  2064                 drawPrimitive(PE_IndicatorArrowDown, header, painter, widget);
       
  2065         } // QStyleOptionHeader::None is not drawn => not needed
       
  2066         break;
       
  2067 #ifndef QT_NO_GROUPBOX
       
  2068     case PE_FrameGroupBox:
       
  2069         if (const QStyleOptionFrameV2 *frame = qstyleoption_cast<const QStyleOptionFrameV2 *>(option))
       
  2070             QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_SettingsList, painter, frame->rect, flags);
       
  2071         break;
       
  2072 #endif //QT_NO_GROUPBOX
       
  2073 
       
  2074     // Qt3 primitives are not supported
       
  2075     case PE_Q3CheckListController:
       
  2076     case PE_Q3CheckListExclusiveIndicator:
       
  2077     case PE_Q3CheckListIndicator:
       
  2078     case PE_Q3DockWindowSeparator:
       
  2079     case PE_Q3Separator:
       
  2080         Q_ASSERT(false);
       
  2081         break;
       
  2082     case PE_Frame:
       
  2083         break;
       
  2084 #ifndef QT_NO_ITEMVIEWS
       
  2085     case PE_PanelItemViewItem:
       
  2086     case PE_PanelItemViewRow: // ### Qt 5: remove
       
  2087         break;
       
  2088 #endif //QT_NO_ITEMVIEWS
       
  2089 
       
  2090     case PE_IndicatorMenuCheckMark:
       
  2091         if (const QStyleOptionMenuItem *checkBox = qstyleoption_cast<const QStyleOptionMenuItem *>(option)){
       
  2092             QStyleOptionMenuItem optionCheckBox = *checkBox;
       
  2093             if (optionCheckBox.checked)
       
  2094                 optionCheckBox.state = (optionCheckBox.state | State_On);
       
  2095             drawPrimitive(PE_IndicatorCheckBox, &optionCheckBox, painter, widget);
       
  2096         }
       
  2097         break;
       
  2098 #ifndef QT_NO_TOOLBAR
       
  2099     case PE_IndicatorToolBarHandle:
       
  2100         // no toolbar handles in S60/AVKON UI
       
  2101     case PE_IndicatorToolBarSeparator:
       
  2102         // no separators in S60/AVKON UI
       
  2103         break;
       
  2104 #endif //QT_NO_TOOLBAR
       
  2105 
       
  2106     case PE_PanelMenuBar:
       
  2107     case PE_FrameMenu:
       
  2108         break; //disable frame in menu
       
  2109 
       
  2110     case PE_IndicatorBranch:
       
  2111 #if defined(Q_WS_S60)
       
  2112         // 3.1 AVKON UI does not have tree view component, use common style for drawing there
       
  2113         if (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1) {
       
  2114 #else
       
  2115         if (true) {
       
  2116 #endif
       
  2117             QCommonStyle::drawPrimitive(element, option, painter, widget);
       
  2118         } else {
       
  2119             const bool rightLine = option->state & State_Item;
       
  2120             const bool downLine = option->state & State_Sibling;
       
  2121             const bool upLine = option->state & (State_Open | State_Children | State_Item | State_Sibling);
       
  2122 
       
  2123             QS60StyleEnums::SkinParts skinPart;
       
  2124             bool drawSkinPart = false;
       
  2125             if (rightLine && downLine && upLine) {
       
  2126                 skinPart = QS60StyleEnums::SP_QgnIndiHlLineBranch;
       
  2127                 drawSkinPart = true;
       
  2128             } else if (rightLine && upLine) {
       
  2129                 skinPart = QS60StyleEnums::SP_QgnIndiHlLineEnd;
       
  2130                 drawSkinPart = true;
       
  2131             } else if (upLine && downLine) {
       
  2132                 skinPart = QS60StyleEnums::SP_QgnIndiHlLineStraight;
       
  2133                 drawSkinPart = true;
       
  2134             }
       
  2135 
       
  2136             if ( drawSkinPart )
       
  2137                 QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags);
       
  2138 
       
  2139             if (option->state & State_Children) {
       
  2140                 QS60StyleEnums::SkinParts skinPart =
       
  2141                         (option->state & State_Open) ? QS60StyleEnums::SP_QgnIndiHlColSuper : QS60StyleEnums::SP_QgnIndiHlExpSuper;
       
  2142                 int minDimension = qMin(option->rect.width(), option->rect.height());
       
  2143                 const int resizeValue = minDimension >> 1;
       
  2144                 minDimension += resizeValue; // Adjust the icon bigger because of empty space in svg icon.
       
  2145                 QRect iconRect(option->rect.topLeft(), QSize(minDimension, minDimension));
       
  2146                 int verticalMagic(0);
       
  2147                 // magic values for positioning svg icon.
       
  2148                 if (option->rect.width() <= option->rect.height())
       
  2149                     verticalMagic = 3;
       
  2150                 iconRect.translate(3, verticalMagic - resizeValue);
       
  2151                 QS60StylePrivate::drawSkinPart(skinPart, painter, iconRect, flags);
       
  2152             }
       
  2153         }
       
  2154         break;
       
  2155 
       
  2156         // todo: items are below with #ifdefs "just in case". in final version, remove all non-required cases
       
  2157     case PE_FrameLineEdit:
       
  2158     case PE_IndicatorButtonDropDown:
       
  2159     case PE_IndicatorDockWidgetResizeHandle:
       
  2160     case PE_PanelTipLabel:
       
  2161     case PE_PanelScrollAreaCorner:
       
  2162 
       
  2163 #ifndef QT_NO_TABBAR
       
  2164     case PE_IndicatorTabTear: // No tab tear in S60
       
  2165 #endif // QT_NO_TABBAR
       
  2166     case PE_FrameDefaultButton:
       
  2167 #ifndef QT_NO_DOCKWIDGET
       
  2168     case PE_FrameDockWidget:
       
  2169 #endif //QT_NO_DOCKWIDGET
       
  2170 #ifndef QT_NO_PROGRESSBAR
       
  2171     case PE_IndicatorProgressChunk:
       
  2172 #endif //QT_NO_PROGRESSBAR
       
  2173 #ifndef QT_NO_TOOLBAR
       
  2174     case PE_PanelToolBar:
       
  2175 #endif //QT_NO_TOOLBAR
       
  2176 #ifndef QT_NO_COLUMNVIEW
       
  2177     case PE_IndicatorColumnViewArrow:
       
  2178     case PE_IndicatorItemViewItemDrop:
       
  2179 #endif //QT_NO_COLUMNVIEW
       
  2180     case PE_FrameTabBarBase: // since tabs are in S60 always in navipane, let's use common style for tab base in Qt.
       
  2181     default:
       
  2182         QCommonStyle::drawPrimitive(element, option, painter, widget);
       
  2183     }
       
  2184 }
       
  2185 
       
  2186 /*! \reimp */
       
  2187 int QS60Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
       
  2188 {
       
  2189     int metricValue = QS60StylePrivate::pixelMetric(metric);
       
  2190     if (metricValue == KNotFound)
       
  2191         metricValue = QCommonStyle::pixelMetric(metric, option, widget);
       
  2192 
       
  2193     if (metric == PM_SubMenuOverlap && widget){
       
  2194         const QMenu *menu = qobject_cast<const QMenu *>(widget);
       
  2195         if (menu && menu->activeAction() && menu->activeAction()->menu()) {
       
  2196             const int menuWidth = menu->activeAction()->menu()->sizeHint().width();
       
  2197             metricValue = -menuWidth;
       
  2198         }
       
  2199     }
       
  2200     return metricValue;
       
  2201 }
       
  2202 
       
  2203 /*! \reimp */
       
  2204 QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
       
  2205                                   const QSize &csz, const QWidget *widget) const
       
  2206 {
       
  2207     QSize sz(csz);
       
  2208     switch (ct) {
       
  2209         case CT_PushButton:
       
  2210             sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
       
  2211             if (const QAbstractButton *buttonWidget = (qobject_cast<const QAbstractButton *>(widget)))
       
  2212                 if (buttonWidget->isCheckable())
       
  2213                     sz += QSize(pixelMetric(PM_IndicatorWidth) + pixelMetric(PM_CheckBoxLabelSpacing), 0);
       
  2214             break;
       
  2215         case CT_LineEdit:
       
  2216             if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt))
       
  2217                 sz += QSize(2*f->lineWidth, 4*f->lineWidth);
       
  2218             break;
       
  2219         case CT_TabBarTab:
       
  2220             QSize naviPaneSize = QS60StylePrivate::naviPaneSize();
       
  2221             sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
       
  2222             if (naviPaneSize.height() > sz.height())
       
  2223                 sz.setHeight(naviPaneSize.height());
       
  2224             break;
       
  2225         default:
       
  2226             sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
       
  2227             break;
       
  2228     }
       
  2229     return sz;
       
  2230 }
       
  2231 
       
  2232 /*! \reimp */
       
  2233 int QS60Style::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *widget,
       
  2234                             QStyleHintReturn *hret) const
       
  2235 {
       
  2236     int retValue = -1;
       
  2237     switch (sh) {
       
  2238         case SH_Table_GridLineColor:
       
  2239             retValue = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors,2,0).rgb();
       
  2240             break;
       
  2241         case SH_GroupBox_TextLabelColor:
       
  2242             retValue = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors,6,0).rgb();
       
  2243             break;
       
  2244         case SH_ScrollBar_ScrollWhenPointerLeavesControl:
       
  2245             retValue = true;
       
  2246             break;
       
  2247         case SH_Slider_SnapToValue:
       
  2248             retValue = true;
       
  2249             break;
       
  2250         case SH_Slider_StopMouseOverSlider:
       
  2251             retValue = true;
       
  2252             break;
       
  2253         case SH_LineEdit_PasswordCharacter:
       
  2254             retValue = '*';
       
  2255             break;
       
  2256         case SH_ComboBox_PopupFrameStyle:
       
  2257             retValue = QFrame::NoFrame | QFrame::Plain;
       
  2258             break;
       
  2259         case SH_Dial_BackgroundRole:
       
  2260             retValue = QPalette::Base;
       
  2261             break;
       
  2262         case SH_ItemView_ActivateItemOnSingleClick:
       
  2263             retValue = true;
       
  2264             break;
       
  2265         case SH_ProgressDialog_TextLabelAlignment:
       
  2266             retValue = (QApplication::layoutDirection() == Qt::LeftToRight) ?
       
  2267                 Qt::AlignLeft :
       
  2268                 Qt::AlignRight;
       
  2269             break;
       
  2270         case SH_Menu_SubMenuPopupDelay:
       
  2271             retValue = 300;
       
  2272             break;
       
  2273         case SH_Menu_Scrollable:
       
  2274             retValue = true;
       
  2275             break;
       
  2276         case SH_Menu_SelectionWrap:
       
  2277             retValue = true;
       
  2278             break;
       
  2279         case SH_ItemView_ShowDecorationSelected:
       
  2280             retValue = true;
       
  2281             break;
       
  2282         case SH_ToolBar_Movable:
       
  2283             retValue = false;
       
  2284             break;
       
  2285         case SH_BlinkCursorWhenTextSelected:
       
  2286             retValue = true;
       
  2287             break;
       
  2288         case SH_UnderlineShortcut:
       
  2289             retValue = 0;
       
  2290             break;
       
  2291         case SH_RequestSoftwareInputPanel:
       
  2292             retValue = RSIP_OnMouseClickAndAlreadyFocused;
       
  2293             break;
       
  2294         default:
       
  2295             break;
       
  2296     }
       
  2297     if (retValue == -1)
       
  2298         retValue = QCommonStyle::styleHint(sh, opt, widget, hret);
       
  2299     return retValue;
       
  2300 }
       
  2301 
       
  2302 /*! \reimp */
       
  2303 QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComplex *option, SubControl scontrol, const QWidget *widget) const
       
  2304 {
       
  2305     QRect ret;
       
  2306     switch (control) {
       
  2307 #ifndef QT_NO_SCROLLBAR
       
  2308     // This implementation of subControlRect(CC_ScrollBar..) basically just removes the SC_ScrollBarSubLine and SC_ScrollBarAddLine
       
  2309     case CC_ScrollBar:
       
  2310         if (const QStyleOptionSlider *scrollbarOption = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
       
  2311             const QRect scrollBarRect = scrollbarOption->rect;
       
  2312             const bool isHorizontal = scrollbarOption->orientation == Qt::Horizontal;
       
  2313             const int maxlen = isHorizontal ? scrollBarRect.width() : scrollBarRect.height();
       
  2314             int sliderlen;
       
  2315 
       
  2316             // calculate slider length
       
  2317             if (scrollbarOption->maximum != scrollbarOption->minimum) {
       
  2318                 const uint range = scrollbarOption->maximum - scrollbarOption->minimum;
       
  2319                 sliderlen = (qint64(scrollbarOption->pageStep) * maxlen) / (range + scrollbarOption->pageStep);
       
  2320 
       
  2321                 const int slidermin = pixelMetric(PM_ScrollBarSliderMin, scrollbarOption, widget);
       
  2322                 if (sliderlen < slidermin || range > (INT_MAX>>1))
       
  2323                     sliderlen = slidermin;
       
  2324                 if (sliderlen > maxlen)
       
  2325                     sliderlen = maxlen;
       
  2326             } else {
       
  2327                 sliderlen = maxlen;
       
  2328             }
       
  2329 
       
  2330             const int sliderstart = sliderPositionFromValue(scrollbarOption->minimum,
       
  2331                                                             scrollbarOption->maximum,
       
  2332                                                             scrollbarOption->sliderPosition,
       
  2333                                                             maxlen - sliderlen,
       
  2334                                                             scrollbarOption->upsideDown);
       
  2335 
       
  2336             switch (scontrol) {
       
  2337                 case SC_ScrollBarSubPage:            // between top/left button and slider
       
  2338                     if (isHorizontal)
       
  2339                         ret.setRect(0, 0, sliderstart, scrollBarRect.height());
       
  2340                     else
       
  2341                         ret.setRect(0, 0, scrollBarRect.width(), sliderstart);
       
  2342                     break;
       
  2343                 case SC_ScrollBarAddPage: {         // between bottom/right button and slider
       
  2344                     const int addPageLength = sliderstart + sliderlen;
       
  2345                     if (isHorizontal)
       
  2346                         ret = scrollBarRect.adjusted(addPageLength, 0, 0, 0);
       
  2347                     else
       
  2348                         ret = scrollBarRect.adjusted(0, addPageLength, 0, 0);
       
  2349                     }
       
  2350                     break;
       
  2351                 case SC_ScrollBarGroove:
       
  2352                     ret = scrollBarRect;
       
  2353                     break;
       
  2354                 case SC_ScrollBarSlider:
       
  2355                     if (scrollbarOption->orientation == Qt::Horizontal)
       
  2356                         ret.setRect(sliderstart, 0, sliderlen, scrollBarRect.height());
       
  2357                     else
       
  2358                         ret.setRect(0, sliderstart, scrollBarRect.width(), sliderlen);
       
  2359                     break;
       
  2360                 case SC_ScrollBarSubLine:            // top/left button
       
  2361                 case SC_ScrollBarAddLine:            // bottom/right button
       
  2362                 default:
       
  2363                     break;
       
  2364             }
       
  2365             ret = visualRect(scrollbarOption->direction, scrollBarRect, ret);
       
  2366         }
       
  2367         break;
       
  2368 #endif // QT_NO_SCROLLBAR
       
  2369     case CC_SpinBox:
       
  2370         if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
       
  2371             const int frameThickness = spinbox->frame ? pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0;
       
  2372             const int buttonMargin = spinbox->frame ? 2 : 0;
       
  2373             const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize) + 2*buttonMargin;
       
  2374             QSize buttonSize;
       
  2375             buttonSize.setHeight(qMax(8, spinbox->rect.height() - frameThickness));
       
  2376             buttonSize.setWidth(buttonWidth);
       
  2377             buttonSize = buttonSize.expandedTo(QApplication::globalStrut());
       
  2378 
       
  2379             const int y = frameThickness + spinbox->rect.y();
       
  2380             const int x = spinbox->rect.x() + spinbox->rect.width() - frameThickness - 2*buttonSize.width();
       
  2381 
       
  2382             switch (scontrol) {
       
  2383                 case SC_SpinBoxUp:
       
  2384                     if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
       
  2385                         return QRect();
       
  2386                     ret = QRect(x, y, buttonWidth, buttonSize.height());
       
  2387                     break;
       
  2388                 case SC_SpinBoxDown:
       
  2389                     if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
       
  2390                         return QRect();
       
  2391                     ret = QRect(x+buttonSize.width(), y, buttonWidth, buttonSize.height());
       
  2392                     break;
       
  2393                 case SC_SpinBoxEditField:
       
  2394                     if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
       
  2395                         ret = QRect(
       
  2396                                 frameThickness,
       
  2397                                 frameThickness,
       
  2398                                 spinbox->rect.width() - 2*frameThickness,
       
  2399                                 spinbox->rect.height() - 2*frameThickness);
       
  2400                     else
       
  2401                         ret = QRect(
       
  2402                                 frameThickness,
       
  2403                                 frameThickness,
       
  2404                                 x - frameThickness,
       
  2405                                 spinbox->rect.height() - 2*frameThickness);
       
  2406                     break;
       
  2407                 case SC_SpinBoxFrame:
       
  2408                     ret = spinbox->rect;
       
  2409                     break;
       
  2410                 default:
       
  2411                     break;
       
  2412             }
       
  2413         ret = visualRect(spinbox->direction, spinbox->rect, ret);
       
  2414         }
       
  2415         break;
       
  2416     case CC_ComboBox:
       
  2417         if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
       
  2418             ret = cmb->rect;
       
  2419             const int width = cmb->rect.width();
       
  2420             const int height = cmb->rect.height();
       
  2421             const int buttonMargin = cmb->frame ? 2 : 0;
       
  2422             // lets use spinbox frame here as well, as no combobox specific value available.
       
  2423             const int frameThickness = cmb->frame ? pixelMetric(PM_SpinBoxFrameWidth, cmb, widget) : 0;
       
  2424             const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize);
       
  2425 
       
  2426             QSize buttonSize;
       
  2427             buttonSize.setHeight(qMax(8, (cmb->rect.height()>>1) - frameThickness)); //minimum of 8 pixels
       
  2428             buttonSize.setWidth(buttonWidth+2*buttonMargin);
       
  2429             buttonSize = buttonSize.expandedTo(QApplication::globalStrut());
       
  2430             switch (scontrol) {
       
  2431                 case SC_ComboBoxArrow:
       
  2432                     ret.setRect(
       
  2433                         ret.x() + ret.width() - buttonMargin - buttonWidth,
       
  2434                         ret.y() + buttonMargin,
       
  2435                         buttonWidth,
       
  2436                         height - 2*buttonMargin);
       
  2437                     break;
       
  2438                 case SC_ComboBoxEditField: {
       
  2439                     ret.setRect(
       
  2440                         ret.x() + frameThickness,
       
  2441                         ret.y() + frameThickness,
       
  2442                         ret.width() - 2*frameThickness - buttonSize.width(),
       
  2443                         ret.height() - 2*frameThickness);
       
  2444                     }
       
  2445                 break;
       
  2446             default:
       
  2447                 break;
       
  2448             }
       
  2449         }
       
  2450         break;
       
  2451     case CC_GroupBox:
       
  2452         if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
       
  2453             ret = QCommonStyle::subControlRect(control, option, scontrol, widget);
       
  2454             switch (scontrol) {
       
  2455                 case SC_GroupBoxCheckBox: //fallthrough
       
  2456                 case SC_GroupBoxLabel: {
       
  2457                     //slightly indent text and boxes, so that dialog border does not mess with them.
       
  2458                     const int horizontalSpacing =
       
  2459                         QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
       
  2460                     ret.adjust(2,horizontalSpacing-3,0,0);
       
  2461                     }
       
  2462                     break;
       
  2463                 case SC_GroupBoxFrame: {
       
  2464                     const QRect textBox = subControlRect(control, option, SC_GroupBoxLabel, widget);
       
  2465                     const int tbHeight = textBox.height();
       
  2466                     ret.translate(0, -ret.y());
       
  2467                     // include title to within the groupBox frame
       
  2468                     ret.setHeight(ret.height()+tbHeight);
       
  2469                     if (widget && ret.bottom() > widget->rect().bottom())
       
  2470                         ret.setBottom(widget->rect().bottom());
       
  2471                     }
       
  2472                     break;
       
  2473                 default:
       
  2474                     break;
       
  2475             }
       
  2476         }
       
  2477         break;
       
  2478     default:
       
  2479         ret = QCommonStyle::subControlRect(control, option, scontrol, widget);
       
  2480     }
       
  2481     return ret;
       
  2482 }
       
  2483 
       
  2484 /*!
       
  2485   \reimp
       
  2486 */
       
  2487 QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, const QWidget *widget) const
       
  2488 {
       
  2489     QRect ret;
       
  2490     switch (element) {
       
  2491         case SE_LineEditContents: {
       
  2492             // in S60 the input text box doesn't start from line Edit's TL, but
       
  2493             // a bit indented.
       
  2494                 QRect lineEditRect = opt->rect;
       
  2495                 const int adjustment = opt->rect.height()>>2;
       
  2496                 lineEditRect.adjust(adjustment,0,0,0);
       
  2497                 ret = lineEditRect;
       
  2498             }
       
  2499             break;
       
  2500         case SE_TabBarTearIndicator:
       
  2501             ret = QRect(0,0,0,0);
       
  2502             break;
       
  2503         case SE_TabWidgetTabBar:
       
  2504             if (const QStyleOptionTabWidgetFrame *optionTab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
       
  2505                 ret = QCommonStyle::subElementRect(element, opt, widget);
       
  2506 
       
  2507                 if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
       
  2508                     const int tabOverlapNoBorder =
       
  2509                         QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap);
       
  2510                     const int tabOverlap =
       
  2511                         tabOverlapNoBorder-QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth);
       
  2512                     const QTabWidget *tab = qobject_cast<const QTabWidget *>(widget);
       
  2513                     int gain = (tab) ? tabOverlap * tab->count() : 0;
       
  2514                     switch (twf->shape) {
       
  2515                         case QTabBar::RoundedNorth:
       
  2516                         case QTabBar::TriangularNorth:
       
  2517                         case QTabBar::RoundedSouth:
       
  2518                         case QTabBar::TriangularSouth: {
       
  2519                             if (widget) {
       
  2520                                 // make sure that gain does not set the rect outside of widget boundaries
       
  2521                                 if (twf->direction == Qt::RightToLeft) {
       
  2522                                     if ((ret.left() - gain) < widget->rect().left())
       
  2523                                         gain = widget->rect().left()-ret.left();
       
  2524                                     ret.adjust(-gain,0,0,0);
       
  2525                                 } else {
       
  2526                                     if ((ret.right() + gain) > widget->rect().right())
       
  2527                                         gain = widget->rect().right()-ret.right();
       
  2528                                     ret.adjust(0,0,gain,0);
       
  2529                                     }
       
  2530                             }
       
  2531                             break;
       
  2532                         }
       
  2533                         default: {
       
  2534                             if (widget) {
       
  2535                                 if ((ret.bottom() + gain) > widget->rect().bottom())
       
  2536                                     gain = widget->rect().bottom()-ret.bottom();
       
  2537                                 ret.adjust(0,0,0,gain);
       
  2538                             }
       
  2539                             break;
       
  2540                         }
       
  2541                     }
       
  2542                 }
       
  2543             }
       
  2544             break;
       
  2545         case SE_ItemViewItemText:
       
  2546         case SE_ItemViewItemDecoration:
       
  2547             if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
       
  2548                 const QListWidget *listItem = qobject_cast<const QListWidget *>(widget);
       
  2549                 const bool multiSelection = !listItem ? false :
       
  2550                     listItem->selectionMode() == QAbstractItemView::MultiSelection ||
       
  2551                     listItem->selectionMode() == QAbstractItemView::ExtendedSelection ||
       
  2552                     listItem->selectionMode() == QAbstractItemView::ContiguousSelection;
       
  2553                 ret = QCommonStyle::subElementRect(element, opt, widget);
       
  2554                 // If both multiselect & check-state, then remove checkbox and move
       
  2555                 // text and decoration towards the beginning
       
  2556                 if (listItem &&
       
  2557                     multiSelection &&
       
  2558                     (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator)) {
       
  2559                     const int verticalSpacing =
       
  2560                         QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing);
       
  2561                     //const int horizontalSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
       
  2562                     const int checkBoxRectWidth = subElementRect(SE_ItemViewItemCheckIndicator, opt, widget).width();
       
  2563                     ret.adjust(-checkBoxRectWidth-verticalSpacing,0,-checkBoxRectWidth-verticalSpacing,0);
       
  2564                 }
       
  2565             } else if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
       
  2566                 const bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable;
       
  2567                 const int indicatorWidth = checkable ?
       
  2568                     pixelMetric(PM_ListViewIconSize, opt, widget) :
       
  2569                     pixelMetric(PM_SmallIconSize, opt, widget);
       
  2570                 ret = menuItem->rect;
       
  2571 
       
  2572                 if (element == SE_ItemViewItemDecoration) {
       
  2573                     if (menuItem->direction == Qt::RightToLeft)
       
  2574                         ret.translate(ret.width()-indicatorWidth, 0);
       
  2575                     ret.setWidth(indicatorWidth);
       
  2576                 } else {
       
  2577                     ret = menuItem->rect;
       
  2578                     if (!menuItem->icon.isNull())
       
  2579                         if (menuItem->direction == Qt::LeftToRight)
       
  2580                             ret.adjust(indicatorWidth, 0, 0, 0);
       
  2581                         else
       
  2582                             ret.adjust(0, 0, -indicatorWidth, 0);
       
  2583 
       
  2584                     // Make room for submenu indicator
       
  2585                     if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu){
       
  2586                         // submenu indicator is very small, so lets halve the rect
       
  2587                         if (menuItem->direction == Qt::LeftToRight)
       
  2588                             ret.adjust(0,0,-(indicatorWidth >> 1),0);
       
  2589                         else
       
  2590                             ret.adjust((indicatorWidth >> 1),0,0,0);
       
  2591                     }
       
  2592                 }
       
  2593             }
       
  2594             break;
       
  2595         case SE_ItemViewItemCheckIndicator:
       
  2596             if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
       
  2597                 const QListWidget *listItem = qobject_cast<const QListWidget *>(widget);
       
  2598 
       
  2599                 const bool singleSelection = listItem &&
       
  2600                     (listItem->selectionMode() == QAbstractItemView::SingleSelection ||
       
  2601                      listItem->selectionMode() == QAbstractItemView::NoSelection);
       
  2602                 const bool checkBoxOnly = (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator) &&
       
  2603                     listItem &&
       
  2604                     singleSelection;
       
  2605 
       
  2606                 // Selection check mark rect.
       
  2607                 const int indicatorWidth = QS60StylePrivate::pixelMetric(QStyle::PM_IndicatorWidth);
       
  2608                 const int indicatorHeight = QS60StylePrivate::pixelMetric(QStyle::PM_IndicatorHeight);
       
  2609                 const int spacing = QS60StylePrivate::pixelMetric(QStyle::PM_CheckBoxLabelSpacing);
       
  2610 
       
  2611                 const int itemHeight = opt->rect.height();
       
  2612                 int heightOffset = 0;
       
  2613                 if (indicatorHeight < itemHeight)
       
  2614                     heightOffset = ((itemHeight - indicatorHeight)>>1);
       
  2615                 if (checkBoxOnly) {
       
  2616                     // Move rect and make it slightly smaller, so that
       
  2617                     // a) highlight border does not cross the rect
       
  2618                     // b) in s60 list checkbox is smaller than normal checkbox
       
  2619                     //todo; magic three
       
  2620                     ret.setRect(opt->rect.left()+3, opt->rect.top() + heightOffset,
       
  2621                         indicatorWidth-3, indicatorHeight-3);
       
  2622                 } else {
       
  2623                     ret.setRect(opt->rect.right() - indicatorWidth - spacing, opt->rect.top() + heightOffset,
       
  2624                         indicatorWidth, indicatorHeight);
       
  2625                 }
       
  2626             } else  {
       
  2627                 ret = QCommonStyle::subElementRect(element, opt, widget);
       
  2628             }
       
  2629             break;
       
  2630         case SE_HeaderLabel:
       
  2631             ret = QCommonStyle::subElementRect(element, opt, widget);
       
  2632             if (qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
       
  2633                 // Subtract area needed for line
       
  2634                 if (opt->state & State_Horizontal)
       
  2635                     ret.setHeight(ret.height() - QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth));
       
  2636                 else
       
  2637                     ret.setWidth(ret.width() - QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth));
       
  2638                 }
       
  2639             ret = visualRect(opt->direction, opt->rect, ret);
       
  2640             break;
       
  2641         default:
       
  2642             ret = QCommonStyle::subElementRect(element, opt, widget);
       
  2643     }
       
  2644     return ret;
       
  2645 }
       
  2646 
       
  2647 /*!
       
  2648   \reimp
       
  2649  */
       
  2650 void QS60Style::polish(QWidget *widget)
       
  2651 {
       
  2652     Q_D(const QS60Style);
       
  2653     QCommonStyle::polish(widget);
       
  2654 
       
  2655     if (!widget)
       
  2656         return;
       
  2657 
       
  2658     if (false
       
  2659 #ifndef QT_NO_SCROLLBAR
       
  2660         || qobject_cast<QScrollBar *>(widget)
       
  2661 #endif
       
  2662         ) {
       
  2663         widget->setAttribute(Qt::WA_OpaquePaintEvent, false);
       
  2664     }
       
  2665 
       
  2666     if (QS60StylePrivate::drawsOwnThemeBackground(widget)) {
       
  2667         widget->setAttribute(Qt::WA_StyledBackground);
       
  2668     } else if (false
       
  2669 #ifndef QT_NO_MENU
       
  2670         || qobject_cast<const QMenu *> (widget)
       
  2671 #endif // QT_NO_MENU
       
  2672     ) {
       
  2673         widget->setAttribute(Qt::WA_StyledBackground);
       
  2674     } else if (false
       
  2675 #ifndef QT_NO_COMBOBOX
       
  2676         || qobject_cast<const QComboBoxListView *>(widget)
       
  2677 #endif //QT_NO_COMBOBOX
       
  2678         ) {
       
  2679         widget->setAttribute(Qt::WA_StyledBackground);
       
  2680     }
       
  2681     d->setThemePalette(widget);
       
  2682     d->setFont(widget);
       
  2683 }
       
  2684 
       
  2685 /*!
       
  2686   \reimp
       
  2687  */
       
  2688 void QS60Style::unpolish(QWidget *widget)
       
  2689 {
       
  2690     if (false
       
  2691     #ifndef QT_NO_SCROLLBAR
       
  2692         || qobject_cast<QScrollBar *>(widget)
       
  2693     #endif
       
  2694         )
       
  2695         widget->setAttribute(Qt::WA_OpaquePaintEvent);
       
  2696 
       
  2697     if (QS60StylePrivate::drawsOwnThemeBackground(widget)) {
       
  2698         widget->setAttribute(Qt::WA_StyledBackground, false);
       
  2699     } else if (false
       
  2700 #ifndef QT_NO_MENU
       
  2701         || qobject_cast<const QMenu *> (widget)
       
  2702 #endif // QT_NO_MENU
       
  2703         ) {
       
  2704         widget->setAttribute(Qt::WA_StyledBackground, false);
       
  2705     } else if (false
       
  2706 #ifndef QT_NO_COMBOBOX
       
  2707         || qobject_cast<const QComboBoxListView *>(widget)
       
  2708 #endif //QT_NO_COMBOBOX
       
  2709         ) {
       
  2710         widget->setAttribute(Qt::WA_StyledBackground, false);
       
  2711     }
       
  2712 
       
  2713     if (widget)
       
  2714         widget->setPalette(QPalette());
       
  2715 
       
  2716     QCommonStyle::unpolish(widget);
       
  2717 }
       
  2718 
       
  2719 /*!
       
  2720   \reimp
       
  2721  */
       
  2722 void QS60Style::polish(QApplication *application)
       
  2723 {
       
  2724     Q_D(QS60Style);
       
  2725     d->m_originalPalette = application->palette();
       
  2726     d->setThemePalette(application);
       
  2727 }
       
  2728 
       
  2729 /*!
       
  2730   \reimp
       
  2731  */
       
  2732 void QS60Style::unpolish(QApplication *application)
       
  2733 {
       
  2734     Q_UNUSED(application)
       
  2735     Q_D(QS60Style);
       
  2736     const QPalette newPalette = QApplication::style()->standardPalette();
       
  2737     QApplication::setPalette(newPalette);
       
  2738     QApplicationPrivate::setSystemPalette(d->m_originalPalette);
       
  2739 }
       
  2740 
       
  2741 /*!
       
  2742   Sets the style property \a name to the \a value.
       
  2743  */
       
  2744 void QS60Style::setStyleProperty(const char *name, const QVariant &value)
       
  2745 {
       
  2746     Q_D(QS60Style);
       
  2747     d->setStyleProperty_specific(name, value);
       
  2748 }
       
  2749 
       
  2750 /*!
       
  2751   Returns the value of style property \a name.
       
  2752  */
       
  2753 QVariant QS60Style::styleProperty(const char *name) const
       
  2754 {
       
  2755     Q_D(const QS60Style);
       
  2756     return d->styleProperty_specific(name);
       
  2757 }
       
  2758 
       
  2759 /*!
       
  2760   \reimp
       
  2761  */
       
  2762 bool QS60Style::event(QEvent *e)
       
  2763 {
       
  2764 #ifdef QT_KEYPAD_NAVIGATION
       
  2765     if (QS60StylePrivate::isTouchSupported())
       
  2766         return false;
       
  2767     Q_D(QS60Style);
       
  2768     switch (e->type()) {
       
  2769     case QEvent::FocusIn:
       
  2770         if (QWidget *focusWidget = QApplication::focusWidget()) {
       
  2771             if (!d->m_focusFrame)
       
  2772                 d->m_focusFrame = new QFocusFrame(focusWidget);
       
  2773             d->m_focusFrame->setWidget(focusWidget);
       
  2774         } else if (d->m_focusFrame) {
       
  2775             d->m_focusFrame->setWidget(0);
       
  2776         }
       
  2777         break;
       
  2778     case QEvent::FocusOut:
       
  2779         if (d->m_focusFrame)
       
  2780             d->m_focusFrame->setWidget(0);
       
  2781         break;
       
  2782     case QEvent::EnterEditFocus:
       
  2783     case QEvent::LeaveEditFocus:
       
  2784         if (d->m_focusFrame)
       
  2785             d->m_focusFrame->update();
       
  2786         break;
       
  2787     default:
       
  2788         break;
       
  2789     }
       
  2790 #else
       
  2791     Q_UNUSED(e)
       
  2792 #endif
       
  2793     return false;
       
  2794 }
       
  2795 
       
  2796 /*!
       
  2797     \internal
       
  2798  */
       
  2799 QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon,
       
  2800     const QStyleOption *option, const QWidget *widget) const
       
  2801 {
       
  2802     const int iconDimension = QS60StylePrivate::pixelMetric(QStyle::PM_ToolBarIconSize);
       
  2803     const QRect iconSize = (!option) ? QRect(0,0,iconDimension,iconDimension) : option->rect;
       
  2804     QS60StyleEnums::SkinParts part;
       
  2805     QS60StylePrivate::SkinElementFlags adjustedFlags;
       
  2806     if (option)
       
  2807         adjustedFlags = (option->state & State_Enabled || option->state == 0) ?
       
  2808             QS60StylePrivate::SF_StateEnabled :
       
  2809             QS60StylePrivate::SF_StateDisabled;
       
  2810 
       
  2811     switch(standardIcon) {
       
  2812         case QStyle::SP_MessageBoxWarning:
       
  2813             part = QS60StyleEnums::SP_QgnNoteWarning;
       
  2814             break;
       
  2815         case QStyle::SP_MessageBoxInformation:
       
  2816             part = QS60StyleEnums::SP_QgnNoteInfo;
       
  2817             break;
       
  2818         case QStyle::SP_MessageBoxCritical:
       
  2819             part = QS60StyleEnums::SP_QgnNoteError;
       
  2820             break;
       
  2821         case QStyle::SP_MessageBoxQuestion:
       
  2822             part = QS60StyleEnums::SP_QgnNoteQuery;
       
  2823             break;
       
  2824         case QStyle::SP_ArrowRight:
       
  2825             part = QS60StyleEnums::SP_QgnIndiNaviArrowRight;
       
  2826             break;
       
  2827         case QStyle::SP_ArrowLeft:
       
  2828             part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft;
       
  2829             break;
       
  2830         case QStyle::SP_ArrowUp:
       
  2831             part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft;
       
  2832             adjustedFlags |= QS60StylePrivate::SF_PointEast;
       
  2833             break;
       
  2834         case QStyle::SP_ArrowDown:
       
  2835             part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft;
       
  2836             adjustedFlags |= QS60StylePrivate::SF_PointWest;
       
  2837             break;
       
  2838         case QStyle::SP_ArrowBack:
       
  2839             if (QApplication::layoutDirection() == Qt::RightToLeft)
       
  2840                 return QS60Style::standardIcon(SP_ArrowRight, option, widget);
       
  2841             return QS60Style::standardIcon(SP_ArrowLeft, option, widget);
       
  2842         case QStyle::SP_ArrowForward:
       
  2843             if (QApplication::layoutDirection() == Qt::RightToLeft)
       
  2844                 return QS60Style::standardIcon(SP_ArrowLeft, option, widget);
       
  2845             return QS60Style::standardIcon(SP_ArrowRight, option, widget);
       
  2846         case QStyle::SP_ComputerIcon:
       
  2847             part = QS60StyleEnums::SP_QgnPropPhoneMemcLarge;
       
  2848             break;
       
  2849         case QStyle::SP_DirClosedIcon:
       
  2850             part = QS60StyleEnums::SP_QgnPropFolderSmall;
       
  2851             break;
       
  2852         case QStyle::SP_DirOpenIcon:
       
  2853             part = QS60StyleEnums::SP_QgnPropFolderCurrent;
       
  2854             break;
       
  2855         case QStyle::SP_DirIcon:
       
  2856             part = QS60StyleEnums::SP_QgnPropFolderSmall;
       
  2857             break;
       
  2858         case QStyle::SP_FileDialogNewFolder:
       
  2859             part = QS60StyleEnums::SP_QgnPropFolderSmallNew;
       
  2860             break;
       
  2861         case QStyle::SP_FileIcon:
       
  2862             part = QS60StyleEnums::SP_QgnPropFileSmall;
       
  2863             break;
       
  2864         case QStyle::SP_TrashIcon:
       
  2865             part = QS60StyleEnums::SP_QgnNoteErased;
       
  2866             break;
       
  2867         case QStyle::SP_ToolBarHorizontalExtensionButton:
       
  2868             part = QS60StyleEnums::SP_QgnIndiSubMenu;
       
  2869             if (QApplication::layoutDirection() == Qt::RightToLeft)
       
  2870                 adjustedFlags |= QS60StylePrivate::SF_PointSouth;
       
  2871             break;
       
  2872         case QStyle::SP_ToolBarVerticalExtensionButton:
       
  2873             adjustedFlags |= QS60StylePrivate::SF_PointEast;
       
  2874             part = QS60StyleEnums::SP_QgnIndiSubMenu;
       
  2875             break;
       
  2876 
       
  2877         default:
       
  2878             return QCommonStyle::standardIconImplementation(standardIcon, option, widget);
       
  2879     }
       
  2880     const QS60StylePrivate::SkinElementFlags flags = adjustedFlags;
       
  2881     const QPixmap cachedPixMap(QS60StylePrivate::cachedPart(part, iconSize.size(), flags));
       
  2882     return cachedPixMap.isNull() ?
       
  2883         QCommonStyle::standardIconImplementation(standardIcon, option, widget) : QIcon(cachedPixMap);
       
  2884 }
       
  2885 
       
  2886 extern QPoint qt_s60_fill_background_offset(const QWidget *targetWidget);
       
  2887 
       
  2888 bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush)
       
  2889 {
       
  2890     const QPixmap backgroundTexture(QS60StylePrivate::backgroundTexture());
       
  2891     if (backgroundTexture.cacheKey() != brush.texture().cacheKey())
       
  2892         return false;
       
  2893 
       
  2894     const QPaintDevice *target = painter->device();
       
  2895     if (target->devType() == QInternal::Widget) {
       
  2896         const QWidget *widget = static_cast<const QWidget *>(target);
       
  2897         const QVector<QRect> &rects = rgn.rects();
       
  2898         for (int i = 0; i < rects.size(); ++i) {
       
  2899             const QRect rect(rects.at(i));
       
  2900             painter->drawPixmap(rect.topLeft(), backgroundTexture,
       
  2901                                 rect.translated(qt_s60_fill_background_offset(widget)));
       
  2902         }
       
  2903     }
       
  2904     return true;
       
  2905 }
       
  2906 
       
  2907 QT_END_NAMESPACE
       
  2908 
       
  2909 #endif // QT_NO_STYLE_S60 || QT_PLUGIN