Merge remote-tracking branch 'origin/4.7' into qt-4.8-from-4.7
[qt:qt.git] / src / gui / styles / qs60style_s60.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qs60style.h"
43 #include "qs60style_p.h"
44 #include "qpainter.h"
45 #include "qstyleoption.h"
46 #include "qstyle.h"
47 #include "private/qapplication_p.h"
48 #include "private/qt_s60_p.h"
49 #include "private/qpixmap_raster_symbian_p.h"
50 #include "private/qcore_symbian_p.h"
51 #include "private/qvolatileimage_p.h"
52 #include "qapplication.h"
53 #include "qsettings.h"
54
55 #include <w32std.h>
56 #include <AknsConstants.h>
57 #include <aknconsts.h>
58 #include <AknsItemID.h>
59 #include <AknsUtils.h>
60 #include <AknsDrawUtils.h>
61 #include <AknsSkinInstance.h>
62 #include <AknsBasicBackgroundControlContext.h>
63 #include <avkon.mbg>
64 #include <AknFontAccess.h>
65 #include <AknLayoutFont.h>
66 #include <AknUtils.h>
67 #include <aknnavi.h>
68 #include <gulicon.h>
69 #include <AknBitmapAnimation.h>
70 #include <centralrepository.h>
71
72 #if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN)
73
74 QT_BEGIN_NAMESPACE
75
76 enum TDrawType {
77     EDrawIcon,
78     EDrawGulIcon,
79     EDrawBackground,
80     EDrawAnimation,
81     ENoDraw
82 };
83
84 const TUid personalisationUID = { 0x101F876F };
85
86 enum TSupportRelease {
87     ES60_None     = 0x0000, //indicates that the commonstyle should draw the graphics
88     ES60_3_1      = 0x0001,
89     ES60_3_2      = 0x0002,
90     ES60_5_0      = 0x0004,
91     ES60_5_1      = 0x0008,
92     ES60_5_2      = 0x0010,
93     ES60_5_3      = 0x0020,
94     ES60_3_X      = ES60_3_1 | ES60_3_2,
95     // Releases before Symbian Foundation
96     ES60_PreSF    = ES60_3_1 | ES60_3_2 | ES60_5_0,
97     // Releases before the S60 5.2
98     ES60_Pre52    = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1,
99     // Releases before S60 5.3
100     ES60_Pre53    = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1 | ES60_5_2,
101     // Add all new releases here
102     ES60_All = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1 | ES60_5_2 | ES60_5_3
103 };
104
105 typedef struct {
106     const TAknsItemID &skinID; // Determines default theme graphics ID.
107     TDrawType drawType; // Determines which native drawing routine is used to draw this item.
108     int supportInfo;    // Defines the S60 versions that use the default graphics.
109     // These two, define new graphics that are used in releases other than partMapEntry.supportInfo defined releases.
110     // In general, these are given in numeric form to allow style compilation in earlier 
111     // native releases that do not contain the new graphics.
112     int newMajorSkinId;
113     int newMinorSkinId;
114 } partMapEntry;
115
116 AnimationData::AnimationData(const QS60StyleEnums::SkinParts part, int frames, int interval) : m_id(part),
117     m_frames(frames), m_interval(interval), m_mode(QS60StyleEnums::AM_Looping)
118 {
119 }
120
121 AnimationDataV2::AnimationDataV2(const AnimationData &data) : AnimationData(data.m_id, data.m_frames, data.m_interval),
122     m_animation(0), m_currentFrame(0), m_resourceBased(false), m_timerId(0)
123 {
124 }
125 AnimationDataV2::~AnimationDataV2()
126 {
127     delete m_animation;
128 }
129
130 QS60StyleAnimation::QS60StyleAnimation(const QS60StyleEnums::SkinParts part, int frames, int interval)
131 {
132     QT_TRAP_THROWING(m_defaultData = new (ELeave) AnimationData(part, frames, interval));
133     QT_TRAP_THROWING(m_currentData = new (ELeave) AnimationDataV2(*m_defaultData));
134 }
135
136 QS60StyleAnimation::~QS60StyleAnimation()
137 {
138     delete m_currentData;
139     delete m_defaultData;
140 }
141
142 void QS60StyleAnimation::setAnimationObject(CAknBitmapAnimation* animation)
143 {
144     Q_ASSERT(animation);
145     if (m_currentData->m_animation)
146         delete m_currentData->m_animation;
147     m_currentData->m_animation = animation;
148 }
149
150 void QS60StyleAnimation::resetToDefaults()
151 {
152     delete m_currentData;
153     m_currentData = 0;
154     QT_TRAP_THROWING(m_currentData = new (ELeave) AnimationDataV2(*m_defaultData));
155 }
156
157 class QS60StyleModeSpecifics
158 {
159 public:
160     static QPixmap skinnedGraphics(QS60StyleEnums::SkinParts stylepart,
161         const QSize &size, QS60StylePrivate::SkinElementFlags flags);
162     static QPixmap skinnedGraphics(QS60StylePrivate::SkinFrameElements frameElement, const QSize &size, QS60StylePrivate::SkinElementFlags flags);
163     static QPixmap colorSkinnedGraphics(const QS60StyleEnums::SkinParts &stylepart,
164         const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags);
165     static QColor colorValue(const TAknsItemID &colorGroup, int colorIndex);
166     static QPixmap fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask, QS60StylePrivate::SkinElementFlags flags, const TSize& targetSize);
167     static bool disabledPartGraphic(QS60StyleEnums::SkinParts &part);
168     static bool disabledFrameGraphic(QS60StylePrivate::SkinFrameElements &frame);
169     static QPixmap generateMissingThemeGraphic(QS60StyleEnums::SkinParts &part, const QSize &size, QS60StylePrivate::SkinElementFlags flags);
170     static TAknsItemID partSpecificThemeId(int part);
171
172     static QVariant themeDefinition(QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part);
173
174 private:
175     static QPixmap createSkinnedGraphicsLX(QS60StyleEnums::SkinParts part,
176         const QSize &size, QS60StylePrivate::SkinElementFlags flags);
177     static QPixmap createSkinnedGraphicsLX(QS60StylePrivate::SkinFrameElements frameElement, const QSize &size, QS60StylePrivate::SkinElementFlags flags);
178     static QPixmap colorSkinnedGraphicsLX(const QS60StyleEnums::SkinParts &stylepart,
179         const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags);
180     static void frameIdAndCenterId(QS60StylePrivate::SkinFrameElements frameElement, TAknsItemID &frameId, TAknsItemID &centerId);
181     static TRect innerRectFromElement(QS60StylePrivate::SkinFrameElements frameElement, const TRect &outerRect);
182     static void fallbackInfo(const QS60StyleEnums::SkinParts &stylePart, TInt &fallbackIndex);
183     static bool checkSupport(const int supportedRelease);
184     // Array to match the skin ID, fallback graphics and Qt widget graphics.
185     static const partMapEntry m_partMap[];
186 };
187
188 const partMapEntry QS60StyleModeSpecifics::m_partMap[] = {
189     /* SP_QgnGrafBarWaitAnim */            {KAknsIIDQgnGrafBarWaitAnim,       EDrawAnimation,   ES60_All,    -1,-1},
190     /* SP_QgnGrafBarFrameCenter */         {KAknsIIDQgnGrafBarFrameCenter,         EDrawIcon,   ES60_All,    -1,-1},
191     /* SP_QgnGrafBarFrameSideL */          {KAknsIIDQgnGrafBarFrameSideL,          EDrawIcon,   ES60_All,    -1,-1},
192     /* SP_QgnGrafBarFrameSideR */          {KAknsIIDQgnGrafBarFrameSideR,          EDrawIcon,   ES60_All,    -1,-1},
193     /* SP_QgnGrafBarProgress */            {KAknsIIDQgnGrafBarProgress,            EDrawIcon,   ES60_All,    -1,-1},
194     // No drop area for 3.x non-touch devices
195     /* SP_QgnGrafOrgBgGrid */              {KAknsIIDNone,                          EDrawIcon,   ES60_3_X,    EAknsMajorGeneric ,0x1eba}, //KAknsIIDQgnGrafOrgBgGrid
196     /* SP_QgnGrafScrollArrowDown */        {KAknsIIDQgnGrafScrollArrowDown,     EDrawGulIcon,   ES60_All,    -1,-1},
197     /* SP_QgnGrafScrollArrowLeft */        {KAknsIIDQgnGrafScrollArrowLeft,     EDrawGulIcon,   ES60_All,    -1,-1},
198     /* SP_QgnGrafScrollArrowRight */       {KAknsIIDQgnGrafScrollArrowRight,    EDrawGulIcon,   ES60_All,    -1,-1},
199     /* SP_QgnGrafScrollArrowUp */          {KAknsIIDQgnGrafScrollArrowUp,       EDrawGulIcon,   ES60_All,    -1,-1},
200
201     // In S60 5.3 there is a new tab graphic
202     /* SP_QgnGrafTabActiveL */             {KAknsIIDQgnGrafTabActiveL,             EDrawIcon,   ES60_Pre53,    EAknsMajorSkin, 0x2219}, //KAknsIIDQtgFrTabActiveNormalL
203     /* SP_QgnGrafTabActiveM */             {KAknsIIDQgnGrafTabActiveM,             EDrawIcon,   ES60_Pre53,    EAknsMajorSkin, 0x221b}, //KAknsIIDQtgFrTabActiveNormalC
204     /* SP_QgnGrafTabActiveR */             {KAknsIIDQgnGrafTabActiveR,             EDrawIcon,   ES60_Pre53,    EAknsMajorSkin, 0x221a}, //KAknsIIDQtgFrTabActiveNormalR
205     /* SP_QgnGrafTabPassiveL */            {KAknsIIDQgnGrafTabPassiveL,            EDrawIcon,   ES60_Pre53,    EAknsMajorSkin, 0x2221}, //KAknsIIDQtgFrTabPassiveNormalL
206     /* SP_QgnGrafTabPassiveM */            {KAknsIIDQgnGrafTabPassiveM,            EDrawIcon,   ES60_Pre53,    EAknsMajorSkin, 0x2223}, //KAknsIIDQtgFrTabPassiveNormalC
207     /* SP_QgnGrafTabPassiveR */            {KAknsIIDQgnGrafTabPassiveR,            EDrawIcon,   ES60_Pre53,    EAknsMajorSkin, 0x2222}, //KAknsIIDQtgFrTabPassiveNormalR
208
209     // In 3.1 there is no slider groove.
210     /* SP_QgnGrafNsliderEndLeft */         {KAknsIIDNone,                          EDrawIcon,   ES60_3_1,    EAknsMajorGeneric, 0x19cf /* KAknsIIDQgnGrafNsliderEndLeft */},
211     /* SP_QgnGrafNsliderEndRight */        {KAknsIIDNone,                          EDrawIcon,   ES60_3_1,    EAknsMajorGeneric, 0x19d0 /* KAknsIIDQgnGrafNsliderEndRight */},
212     /* SP_QgnGrafNsliderMiddle */          {KAknsIIDNone,                          EDrawIcon,   ES60_3_1,    EAknsMajorGeneric, 0x19d2 /* KAknsIIDQgnGrafNsliderMiddle */},
213     /* SP_QgnIndiCheckboxOff */            {KAknsIIDQgnIndiCheckboxOff,            EDrawIcon,   ES60_All,    -1,-1},
214     /* SP_QgnIndiCheckboxOn */             {KAknsIIDQgnIndiCheckboxOn,             EDrawIcon,   ES60_All,    -1,-1},
215
216     // Following 5 items (SP_QgnIndiHlColSuper - SP_QgnIndiHlLineStraight) are available starting from S60 release 3.2.
217     // In 3.1 CommonStyle drawing is used for these QTreeView elements, since no similar icons in AVKON UI.
218     /* SP_QgnIndiHlColSuper */             {KAknsIIDNone,                          EDrawIcon,   ES60_3_1,    EAknsMajorGeneric, 0x17d5 /* KAknsIIDQgnIndiHlColSuper */},
219     /* SP_QgnIndiHlExpSuper */             {KAknsIIDNone,                          EDrawIcon,   ES60_3_1,    EAknsMajorGeneric, 0x17d6 /* KAknsIIDQgnIndiHlExpSuper */},
220     /* SP_QgnIndiHlLineBranch */           {KAknsIIDNone,                          EDrawIcon,   ES60_3_1,    EAknsMajorGeneric, 0x17d7 /* KAknsIIDQgnIndiHlLineBranch */},
221     /* SP_QgnIndiHlLineEnd */              {KAknsIIDNone,                          EDrawIcon,   ES60_3_1,    EAknsMajorGeneric, 0x17d8 /* KAknsIIDQgnIndiHlLineEnd */},
222     /* SP_QgnIndiHlLineStraight */         {KAknsIIDNone,                          EDrawIcon,   ES60_3_1,    EAknsMajorGeneric, 0x17d9 /* KAknsIIDQgnIndiHlLineStraight */},
223     /* SP_QgnIndiMarkedAdd */              {KAknsIIDQgnIndiMarkedAdd,              EDrawIcon,   ES60_All,    -1,-1},
224     /* SP_QgnIndiNaviArrowLeft */          {KAknsIIDQgnIndiNaviArrowLeft,          EDrawIcon,   ES60_All,    -1,-1},
225     /* SP_QgnIndiNaviArrowRight */         {KAknsIIDQgnIndiNaviArrowRight,         EDrawIcon,   ES60_All,    -1,-1},
226     /* SP_QgnIndiRadiobuttOff */           {KAknsIIDQgnIndiRadiobuttOff,           EDrawIcon,   ES60_All,    -1,-1},
227     /* SP_QgnIndiRadiobuttOn */            {KAknsIIDQgnIndiRadiobuttOn,            EDrawIcon,   ES60_All,    -1,-1},
228
229     // In 3.1 there different slider graphic and no pressed state.
230     /* SP_QgnGrafNsliderMarker */          {KAknsIIDQgnIndiSliderEdit,             EDrawIcon,   ES60_3_1,    EAknsMajorGeneric, 0x19d1 /* KAknsIIDQgnGrafNsliderMarker */},
231     /* SP_QgnGrafNsliderMarkerSelected */  {KAknsIIDQgnIndiSliderEdit,             EDrawIcon,   ES60_3_1,    EAknsMajorGeneric, 0x1a4a /* KAknsIIDQgnGrafNsliderMarkerSelected */},
232     /* SP_QgnIndiSubmenu */                {KAknsIIDQgnIndiSubmenu,                EDrawIcon,   ES60_All,    -1,-1},
233     /* SP_QgnNoteErased */                 {KAknsIIDQgnNoteErased,                 EDrawIcon,   ES60_All,    -1,-1},
234     /* SP_QgnNoteError */                  {KAknsIIDQgnNoteError,                  EDrawIcon,   ES60_All,    -1,-1},
235     /* SP_QgnNoteInfo */                   {KAknsIIDQgnNoteInfo,                   EDrawIcon,   ES60_All,    -1,-1},
236     /* SP_QgnNoteOk */                     {KAknsIIDQgnNoteOk,                     EDrawIcon,   ES60_All,    -1,-1},
237     /* SP_QgnNoteQuery */                  {KAknsIIDQgnNoteQuery,                  EDrawIcon,   ES60_All,    -1,-1},
238     /* SP_QgnNoteWarning */                {KAknsIIDQgnNoteWarning,                EDrawIcon,   ES60_All,    -1,-1},
239     /* SP_QgnPropFileSmall */              {KAknsIIDQgnPropFileSmall,              EDrawIcon,   ES60_All,    -1,-1},
240     /* SP_QgnPropFolderCurrent */          {KAknsIIDQgnPropFolderCurrent,          EDrawIcon,   ES60_All,    -1,-1},
241     /* SP_QgnPropFolderSmall */            {KAknsIIDQgnPropFolderSmall,            EDrawIcon,   ES60_All,    -1,-1},
242     /* SP_QgnPropFolderSmallNew */         {KAknsIIDQgnPropFolderSmallNew,         EDrawIcon,   ES60_All,    -1,-1},
243     /* SP_QgnPropPhoneMemcLarge */         {KAknsIIDQgnPropPhoneMemcLarge,         EDrawIcon,   ES60_All,    -1,-1},
244
245     // Toolbar graphics is different in 3.1/3.2 vs. 5.0
246     /* SP_QgnFrSctrlButtonCornerTl */   {KAknsIIDQsnFrButtonTbCornerTl,         ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2301}, /* KAknsIIDQgnFrSctrlButtonCornerTl*/
247     /* SP_QgnFrSctrlButtonCornerTr */   {KAknsIIDQsnFrButtonTbCornerTr,         ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2302},
248     /* SP_QgnFrSctrlButtonCornerBl */   {KAknsIIDQsnFrButtonTbCornerBl,         ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2303},
249     /* SP_QgnFrSctrlButtonCornerBr */   {KAknsIIDQsnFrButtonTbCornerBr,         ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2304},
250     /* SP_QgnFrSctrlButtonSideT */      {KAknsIIDQsnFrButtonTbSideT,            ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2305},
251     /* SP_QgnFrSctrlButtonSideB */      {KAknsIIDQsnFrButtonTbSideB,            ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2306},
252     /* SP_QgnFrSctrlButtonSideL */      {KAknsIIDQsnFrButtonTbSideL,            ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2307},
253     /* SP_QgnFrSctrlButtonSideR */      {KAknsIIDQsnFrButtonTbSideR,            ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2308},
254     /* SP_QgnFrSctrlButtonCenter */     {KAknsIIDQsnFrButtonTbCenter,           ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2309}, /*KAknsIIDQgnFrSctrlButtonCenter*/
255
256     // No pressed state for toolbar button in 3.1/3.2.
257     /* SP_QgnFrSctrlButtonCornerTlPressed */ {KAknsIIDQsnFrButtonTbCornerTl,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2621},  /*KAknsIIDQgnFrSctrlButtonCornerTlPressed*/
258     /* SP_QgnFrSctrlButtonCornerTrPressed */ {KAknsIIDQsnFrButtonTbCornerTr,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2622},
259     /* SP_QgnFrSctrlButtonCornerBlPressed */ {KAknsIIDQsnFrButtonTbCornerBl,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2623},
260     /* SP_QgnFrSctrlButtonCornerBrPressed */ {KAknsIIDQsnFrButtonTbCornerBr,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2624},
261     /* SP_QgnFrSctrlButtonSideTPressed */    {KAknsIIDQsnFrButtonTbSideT,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2625},
262     /* SP_QgnFrSctrlButtonSideBPressed */    {KAknsIIDQsnFrButtonTbSideB,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2626},
263     /* SP_QgnFrSctrlButtonSideLPressed */    {KAknsIIDQsnFrButtonTbSideL,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2627},
264     /* SP_QgnFrSctrlButtonSideRPressed */    {KAknsIIDQsnFrButtonTbSideR,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2628},
265     /* SP_QgnFrSctrlButtonCenterPressed */   {KAknsIIDQsnFrButtonTbCenter,      ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2629},
266
267     // 3.1 & 3.2 do not have pressed state for scrollbar, so use normal scrollbar graphics instead.
268     /* SP_QsnCpScrollHandleBottomPressed*/ {KAknsIIDQsnCpScrollHandleBottom,    EDrawIcon,   ES60_3_X,    EAknsMajorGeneric, 0x20f8}, /*KAknsIIDQsnCpScrollHandleBottomPressed*/
269     /* SP_QsnCpScrollHandleMiddlePressed*/ {KAknsIIDQsnCpScrollHandleMiddle,    EDrawIcon,   ES60_3_X,    EAknsMajorGeneric, 0x20f9}, /*KAknsIIDQsnCpScrollHandleMiddlePressed*/
270     /* SP_QsnCpScrollHandleTopPressed*/    {KAknsIIDQsnCpScrollHandleTop,       EDrawIcon,   ES60_3_X,    EAknsMajorGeneric, 0x20fa}, /*KAknsIIDQsnCpScrollHandleTopPressed*/
271
272     /* SP_QsnBgScreen */                {KAknsIIDQsnBgScreen,              EDrawBackground,  ES60_All,    -1,-1},
273
274     /* SP_QsnCpScrollBgBottom */        {KAknsIIDQsnCpScrollBgBottom,           EDrawIcon,   ES60_All,    -1,-1},
275     /* SP_QsnCpScrollBgMiddle */        {KAknsIIDQsnCpScrollBgMiddle,           EDrawIcon,   ES60_All,    -1,-1},
276     /* SP_QsnCpScrollBgTop */           {KAknsIIDQsnCpScrollBgTop,              EDrawIcon,   ES60_All,    -1,-1},
277
278     /* SP_QsnCpScrollHandleBottom */    {KAknsIIDQsnCpScrollHandleBottom,       EDrawIcon,   ES60_All,    -1,-1},
279     /* SP_QsnCpScrollHandleMiddle */    {KAknsIIDQsnCpScrollHandleMiddle,       EDrawIcon,   ES60_All,    -1,-1},
280     /* SP_QsnCpScrollHandleTop */       {KAknsIIDQsnCpScrollHandleTop,          EDrawIcon,   ES60_All,    -1,-1},
281
282     /* SP_QsnFrButtonTbCornerTl */      {KAknsIIDQsnFrButtonTbCornerTl,         ENoDraw,     ES60_All,    -1, -1},
283     /* SP_QsnFrButtonTbCornerTr */      {KAknsIIDQsnFrButtonTbCornerTr,         ENoDraw,     ES60_All,    -1, -1},
284     /* SP_QsnFrButtonTbCornerBl */      {KAknsIIDQsnFrButtonTbCornerBl,         ENoDraw,     ES60_All,    -1, -1},
285     /* SP_QsnFrButtonTbCornerBr */      {KAknsIIDQsnFrButtonTbCornerBr,         ENoDraw,     ES60_All,    -1, -1},
286     /* SP_QsnFrButtonTbSideT */         {KAknsIIDQsnFrButtonTbSideT,            ENoDraw,     ES60_All,    -1, -1},
287     /* SP_QsnFrButtonTbSideB */         {KAknsIIDQsnFrButtonTbSideB,            ENoDraw,     ES60_All,    -1, -1},
288     /* SP_QsnFrButtonTbSideL */         {KAknsIIDQsnFrButtonTbSideL,            ENoDraw,     ES60_All,    -1, -1},
289     /* SP_QsnFrButtonTbSideR */         {KAknsIIDQsnFrButtonTbSideR,            ENoDraw,     ES60_All,    -1, -1},
290     /* SP_QsnFrButtonTbCenter */        {KAknsIIDQsnFrButtonTbCenter,           EDrawIcon,   ES60_All,    -1, -1},
291
292     /* SP_QsnFrButtonTbCornerTlPressed */{KAknsIIDQsnFrButtonTbCornerTlPressed, ENoDraw,     ES60_All,    -1,-1},
293     /* SP_QsnFrButtonTbCornerTrPressed */{KAknsIIDQsnFrButtonTbCornerTrPressed, ENoDraw,     ES60_All,    -1,-1},
294     /* SP_QsnFrButtonTbCornerBlPressed */{KAknsIIDQsnFrButtonTbCornerBlPressed, ENoDraw,     ES60_All,    -1,-1},
295     /* SP_QsnFrButtonTbCornerBrPressed */{KAknsIIDQsnFrButtonTbCornerBrPressed, ENoDraw,     ES60_All,    -1,-1},
296     /* SP_QsnFrButtonTbSideTPressed */   {KAknsIIDQsnFrButtonTbSideTPressed,    ENoDraw,     ES60_All,    -1,-1},
297     /* SP_QsnFrButtonTbSideBPressed */   {KAknsIIDQsnFrButtonTbSideBPressed,    ENoDraw,     ES60_All,    -1,-1},
298     /* SP_QsnFrButtonTbSideLPressed */   {KAknsIIDQsnFrButtonTbSideLPressed,    ENoDraw,     ES60_All,    -1,-1},
299     /* SP_QsnFrButtonTbSideRPressed */   {KAknsIIDQsnFrButtonTbSideRPressed,    ENoDraw,     ES60_All,    -1,-1},
300     /* SP_QsnFrButtonTbCenterPressed */  {KAknsIIDQsnFrButtonTbCenterPressed,   EDrawIcon,   ES60_All,    -1,-1},
301
302     /* SP_QsnFrCaleCornerTl */          {KAknsIIDQsnFrCaleCornerTl,             ENoDraw,     ES60_All,    -1,-1},
303     /* SP_QsnFrCaleCornerTr */          {KAknsIIDQsnFrCaleCornerTr,             ENoDraw,     ES60_All,    -1,-1},
304     /* SP_QsnFrCaleCornerBl */          {KAknsIIDQsnFrCaleCornerBl,             ENoDraw,     ES60_All,    -1,-1},
305     /* SP_QsnFrCaleCornerBr */          {KAknsIIDQsnFrCaleCornerBr,             ENoDraw,     ES60_All,    -1,-1},
306     /* SP_QsnFrCaleSideT */             {KAknsIIDQsnFrCaleSideT,                ENoDraw,     ES60_All,    -1,-1},
307     /* SP_QsnFrCaleSideB */             {KAknsIIDQsnFrCaleSideB,                ENoDraw,     ES60_All,    -1,-1},
308     /* SP_QsnFrCaleSideL */             {KAknsIIDQsnFrCaleSideL,                ENoDraw,     ES60_All,    -1,-1},
309     /* SP_QsnFrCaleSideR */             {KAknsIIDQsnFrCaleSideR,                ENoDraw,     ES60_All,    -1,-1},
310     /* SP_QsnFrCaleCenter */            {KAknsIIDQsnFrCaleCenter,               ENoDraw,     ES60_All,    -1,-1},
311
312     /* SP_QsnFrCaleHeadingCornerTl */   {KAknsIIDQsnFrCaleHeadingCornerTl,      ENoDraw,     ES60_All,    -1,-1},
313     /* SP_QsnFrCaleHeadingCornerTr */   {KAknsIIDQsnFrCaleHeadingCornerTr,      ENoDraw,     ES60_All,    -1,-1},
314     /* SP_QsnFrCaleHeadingCornerBl */   {KAknsIIDQsnFrCaleHeadingCornerBl,      ENoDraw,     ES60_All,    -1,-1},
315     /* SP_QsnFrCaleHeadingCornerBr */   {KAknsIIDQsnFrCaleHeadingCornerBr,      ENoDraw,     ES60_All,    -1,-1},
316     /* SP_QsnFrCaleHeadingSideT */      {KAknsIIDQsnFrCaleHeadingSideT,         ENoDraw,     ES60_All,    -1,-1},
317     /* SP_QsnFrCaleHeadingSideB */      {KAknsIIDQsnFrCaleHeadingSideB,         ENoDraw,     ES60_All,    -1,-1},
318     /* SP_QsnFrCaleHeadingSideL */      {KAknsIIDQsnFrCaleHeadingSideL,         ENoDraw,     ES60_All,    -1,-1},
319     /* SP_QsnFrCaleHeadingSideR */      {KAknsIIDQsnFrCaleHeadingSideR,         ENoDraw,     ES60_All,    -1,-1},
320     /* SP_QsnFrCaleHeadingCenter */     {KAknsIIDQsnFrCaleHeadingCenter,        ENoDraw,     ES60_All,    -1,-1},
321
322     /* SP_QsnFrInputCornerTl */         {KAknsIIDQsnFrInputCornerTl,            ENoDraw,     ES60_All,    -1,-1},
323     /* SP_QsnFrInputCornerTr */         {KAknsIIDQsnFrInputCornerTr,            ENoDraw,     ES60_All,    -1,-1},
324     /* SP_QsnFrInputCornerBl */         {KAknsIIDQsnFrInputCornerBl,            ENoDraw,     ES60_All,    -1,-1},
325     /* SP_QsnFrInputCornerBr */         {KAknsIIDQsnFrInputCornerBr,            ENoDraw,     ES60_All,    -1,-1},
326     /* SP_QsnFrInputSideT */            {KAknsIIDQsnFrInputSideT,               ENoDraw,     ES60_All,    -1,-1},
327     /* SP_QsnFrInputSideB */            {KAknsIIDQsnFrInputSideB,               ENoDraw,     ES60_All,    -1,-1},
328     /* SP_QsnFrInputSideL */            {KAknsIIDQsnFrInputSideL,               ENoDraw,     ES60_All,    -1,-1},
329     /* SP_QsnFrInputSideR */            {KAknsIIDQsnFrInputSideR,               ENoDraw,     ES60_All,    -1,-1},
330     /* SP_QsnFrInputCenter */           {KAknsIIDQsnFrInputCenter,              ENoDraw,     ES60_All,    -1,-1},
331
332     /* SP_QsnFrListCornerTl */          {KAknsIIDQsnFrListCornerTl,             ENoDraw,     ES60_All,    -1,-1},
333     /* SP_QsnFrListCornerTr */          {KAknsIIDQsnFrListCornerTr,             ENoDraw,     ES60_All,    -1,-1},
334     /* SP_QsnFrListCornerBl */          {KAknsIIDQsnFrListCornerBl,             ENoDraw,     ES60_All,    -1,-1},
335     /* SP_QsnFrListCornerBr */          {KAknsIIDQsnFrListCornerBr,             ENoDraw,     ES60_All,    -1,-1},
336     /* SP_QsnFrListSideT */             {KAknsIIDQsnFrListSideT,                ENoDraw,     ES60_All,    -1,-1},
337     /* SP_QsnFrListSideB */             {KAknsIIDQsnFrListSideB,                ENoDraw,     ES60_All,    -1,-1},
338     /* SP_QsnFrListSideL */             {KAknsIIDQsnFrListSideL,                ENoDraw,     ES60_All,    -1,-1},
339     /* SP_QsnFrListSideR */             {KAknsIIDQsnFrListSideR,                ENoDraw,     ES60_All,    -1,-1},
340     /* SP_QsnFrListCenter */            {KAknsIIDQsnFrListCenter,               ENoDraw,     ES60_All,    -1,-1},
341
342     /* SP_QsnFrPopupCornerTl */         {KAknsIIDQsnFrPopupCornerTl,            ENoDraw,     ES60_All,    -1,-1},
343     /* SP_QsnFrPopupCornerTr */         {KAknsIIDQsnFrPopupCornerTr,            ENoDraw,     ES60_All,    -1,-1},
344     /* SP_QsnFrPopupCornerBl */         {KAknsIIDQsnFrPopupCornerBl,            ENoDraw,     ES60_All,    -1,-1},
345     /* SP_QsnFrPopupCornerBr */         {KAknsIIDQsnFrPopupCornerBr,            ENoDraw,     ES60_All,    -1,-1},
346     /* SP_QsnFrPopupSideT */            {KAknsIIDQsnFrPopupSideT,               ENoDraw,     ES60_All,    -1,-1},
347     /* SP_QsnFrPopupSideB */            {KAknsIIDQsnFrPopupSideB,               ENoDraw,     ES60_All,    -1,-1},
348     /* SP_QsnFrPopupSideL */            {KAknsIIDQsnFrPopupSideL,               ENoDraw,     ES60_All,    -1,-1},
349     /* SP_QsnFrPopupSideR */            {KAknsIIDQsnFrPopupSideR,               ENoDraw,     ES60_All,    -1,-1},
350     /* SP_QsnFrPopupCenter */           {KAknsIIDQsnFrPopupCenterSubmenu,       ENoDraw,     ES60_All,    -1,-1},
351
352     // ToolTip graphics different in 3.1 vs. 3.2+.
353     /* SP_QsnFrPopupPreviewCornerTl */  {KAknsIIDQsnFrPopupCornerTl,            ENoDraw,     ES60_3_1,    EAknsMajorSkin, 0x19c5}, /* KAknsIIDQsnFrPopupPreviewCornerTl */
354     /* SP_QsnFrPopupPreviewCornerTr */  {KAknsIIDQsnFrPopupCornerTr,            ENoDraw,     ES60_3_1,    EAknsMajorSkin, 0x19c6},
355     /* SP_QsnFrPopupPreviewCornerBl */  {KAknsIIDQsnFrPopupCornerBl,            ENoDraw,     ES60_3_1,    EAknsMajorSkin, 0x19c3},
356     /* SP_QsnFrPopupPreviewCornerBr */  {KAknsIIDQsnFrPopupCornerBr,            ENoDraw,     ES60_3_1,    EAknsMajorSkin, 0x19c4},
357     /* SP_QsnFrPopupPreviewSideT */     {KAknsIIDQsnFrPopupSideT,               ENoDraw,     ES60_3_1,    EAknsMajorSkin, 0x19ca},
358     /* SP_QsnFrPopupPreviewSideB */     {KAknsIIDQsnFrPopupSideB,               ENoDraw,     ES60_3_1,    EAknsMajorSkin, 0x19c7},
359     /* SP_QsnFrPopupPreviewSideL */     {KAknsIIDQsnFrPopupSideL,               ENoDraw,     ES60_3_1,    EAknsMajorSkin, 0x19c8},
360     /* SP_QsnFrPopupPreviewSideR */     {KAknsIIDQsnFrPopupSideR,               ENoDraw,     ES60_3_1,    EAknsMajorSkin, 0x19c9},
361     /* SP_QsnFrPopupPreviewCenter */    {KAknsIIDQsnFrPopupCenter,              ENoDraw,     ES60_3_1,    EAknsMajorSkin, 0x19c2},
362
363     /* SP_QsnFrSetOptCornerTl */        {KAknsIIDQsnFrSetOptCornerTl,           ENoDraw,     ES60_All,    -1,-1},
364     /* SP_QsnFrSetOptCornerTr */        {KAknsIIDQsnFrSetOptCornerTr,           ENoDraw,     ES60_All,    -1,-1},
365     /* SP_QsnFrSetOptCornerBl */        {KAknsIIDQsnFrSetOptCornerBl,           ENoDraw,     ES60_All,    -1,-1},
366     /* SP_QsnFrSetOptCornerBr */        {KAknsIIDQsnFrSetOptCornerBr,           ENoDraw,     ES60_All,    -1,-1},
367     /* SP_QsnFrSetOptSideT */           {KAknsIIDQsnFrSetOptSideT,              ENoDraw,     ES60_All,    -1,-1},
368     /* SP_QsnFrSetOptSideB */           {KAknsIIDQsnFrSetOptSideB,              ENoDraw,     ES60_All,    -1,-1},
369     /* SP_QsnFrSetOptSideL */           {KAknsIIDQsnFrSetOptSideL,              ENoDraw,     ES60_All,    -1,-1},
370     /* SP_QsnFrSetOptSideR */           {KAknsIIDQsnFrSetOptSideR,              ENoDraw,     ES60_All,    -1,-1},
371     /* SP_QsnFrSetOptCenter */          {KAknsIIDQsnFrSetOptCenter,             ENoDraw,     ES60_All,    -1,-1},
372
373     // No toolbar frame for 5.0+ releases.
374     /* SP_QsnFrPopupSubCornerTl */      {KAknsIIDQsnFrPopupSubCornerTl,         ENoDraw,     ES60_3_X,    -1,-1},
375     /* SP_QsnFrPopupSubCornerTr */      {KAknsIIDQsnFrPopupSubCornerTr,         ENoDraw,     ES60_3_X,    -1,-1},
376     /* SP_QsnFrPopupSubCornerBl */      {KAknsIIDQsnFrPopupSubCornerBl,         ENoDraw,     ES60_3_X,    -1,-1},
377     /* SP_QsnFrPopupSubCornerBr */      {KAknsIIDQsnFrPopupSubCornerBr,         ENoDraw,     ES60_3_X,    -1,-1},
378     /* SP_QsnFrPopupSubSideT */         {KAknsIIDQsnFrPopupSubSideT,            ENoDraw,     ES60_3_X,    -1,-1},
379     /* SP_QsnFrPopupSubSideB */         {KAknsIIDQsnFrPopupSubSideB,            ENoDraw,     ES60_3_X,    -1,-1},
380     /* SP_QsnFrPopupSubSideL */         {KAknsIIDQsnFrPopupSubSideL,            ENoDraw,     ES60_3_X,    -1,-1},
381     /* SP_QsnFrPopupSubSideR */         {KAknsIIDQsnFrPopupSubSideR,            ENoDraw,     ES60_3_X,    -1,-1},
382     /* SP_QsnFrPopupSubCenter */        {KAknsIIDQsnFrPopupCenterSubmenu,       ENoDraw,     ES60_3_X,    -1,-1},
383
384     // No inactive button graphics in 3.1/3.2
385     /* SP_QsnFrButtonCornerTlInactive */ {KAknsIIDQsnFrButtonTbCornerTl,        ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x21b1}, /*KAknsIIDQsnFrButtonCornerTlInactive*/
386     /* SP_QsnFrButtonCornerTrInactive */ {KAknsIIDQsnFrButtonTbCornerTr,        ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x21b2},
387     /* SP_QsnFrButtonCornerBlInactive */ {KAknsIIDQsnFrButtonTbCornerBl,        ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x21b3},
388     /* SP_QsnFrButtonCornerTrInactive */ {KAknsIIDQsnFrButtonTbCornerBr,        ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x21b4},
389     /* SP_QsnFrButtonSideTInactive */    {KAknsIIDQsnFrButtonTbSideT,           ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x21b5},
390     /* SP_QsnFrButtonSideBInactive */    {KAknsIIDQsnFrButtonTbSideB,           ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x21b6},
391     /* SP_QsnFrButtonSideLInactive */    {KAknsIIDQsnFrButtonTbSideL,           ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x21b7},
392     /* SP_QsnFrButtonSideRInactive */    {KAknsIIDQsnFrButtonTbSideR,           ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x21b8},
393     /* SP_QsnFrButtonCenterInactive */   {KAknsIIDQsnFrButtonTbCenter,          EDrawIcon,   ES60_3_X,    EAknsMajorSkin, 0x21b9},
394
395     // No pressed down grid in 3.1/3.2
396     /* SP_QsnFrGridCornerTlPressed */    {KAknsIIDQsnFrGridCornerTl,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2681}, /*KAknsIIDQsnFrGridCornerTlPressed*/
397     /* SP_QsnFrGridCornerTrPressed */    {KAknsIIDQsnFrGridCornerTr,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2682},
398     /* SP_QsnFrGridCornerBlPressed */    {KAknsIIDQsnFrGridCornerBl,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2683},
399     /* SP_QsnFrGridCornerBrPressed */    {KAknsIIDQsnFrGridCornerBr,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2684},
400     /* SP_QsnFrGridSideTPressed */       {KAknsIIDQsnFrGridSideT,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2685},
401     /* SP_QsnFrGridSideBPressed */       {KAknsIIDQsnFrGridSideB,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2686},
402     /* SP_QsnFrGridSideLPressed */       {KAknsIIDQsnFrGridSideL,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2687},
403     /* SP_QsnFrGridSideRPressed */       {KAknsIIDQsnFrGridSideR,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2688},
404     /* SP_QsnFrGridCenterPressed */      {KAknsIIDQsnFrGridCenter,      ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2689},
405
406     // No pressed down list in 3.1/3.2
407     /* SP_QsnFrListCornerTlPressed */    {KAknsIIDQsnFrListCornerTl,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x268b}, /*KAknsIIDQsnFrListCornerTlPressed*/
408     /* SP_QsnFrListCornerTrPressed */    {KAknsIIDQsnFrListCornerTr,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x268c},
409     /* SP_QsnFrListCornerBlPressed */    {KAknsIIDQsnFrListCornerBl,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x268d},
410     /* SP_QsnFrListCornerBrPressed */    {KAknsIIDQsnFrListCornerBr,    ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x268e},
411     /* SP_QsnFrListSideTPressed */       {KAknsIIDQsnFrListSideT,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x268f},
412     /* SP_QsnFrListSideBPressed */       {KAknsIIDQsnFrListSideB,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2690},
413     /* SP_QsnFrListSideLPressed */       {KAknsIIDQsnFrListSideL,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2691},
414     /* SP_QsnFrListSideRPressed */       {KAknsIIDQsnFrListSideR,       ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2692},
415     /* SP_QsnFrListCenterPressed */      {KAknsIIDQsnFrListCenter,      ENoDraw,     ES60_3_X,    EAknsMajorSkin, 0x2693},
416 };
417
418 QPixmap QS60StyleModeSpecifics::skinnedGraphics(
419     QS60StyleEnums::SkinParts stylepart, const QSize &size,
420     QS60StylePrivate::SkinElementFlags flags)
421 {
422     QPixmap themedImage;
423     TRAPD( error, QT_TRYCATCH_LEAVING({
424             const QPixmap skinnedImage = createSkinnedGraphicsLX(stylepart, size, flags);
425             themedImage = skinnedImage;
426     }));
427     if (error)
428         return themedImage = QPixmap();
429     return themedImage;
430 }
431
432 QPixmap QS60StyleModeSpecifics::skinnedGraphics(
433     QS60StylePrivate::SkinFrameElements frame, const QSize &size, QS60StylePrivate::SkinElementFlags flags)
434 {
435     QPixmap themedImage;
436     TRAPD( error, QT_TRYCATCH_LEAVING({
437             const QPixmap skinnedImage = createSkinnedGraphicsLX(frame, size, flags);
438             themedImage = skinnedImage;
439     }));
440     if (error)
441         return themedImage = QPixmap();
442     return themedImage;
443 }
444
445 QPixmap QS60StyleModeSpecifics::colorSkinnedGraphics(
446     const QS60StyleEnums::SkinParts &stylepart, const QSize &size, QPainter *painter,
447     QS60StylePrivate::SkinElementFlags flags)
448 {
449     QPixmap colorGraphics;
450     TRAPD(error, QT_TRYCATCH_LEAVING(colorGraphics = colorSkinnedGraphicsLX(stylepart, size, painter, flags)));
451     return error ? QPixmap() : colorGraphics;
452 }
453
454 void QS60StyleModeSpecifics::fallbackInfo(const QS60StyleEnums::SkinParts &stylePart, TInt &fallbackIndex)
455 {
456     switch(stylePart) {
457         case QS60StyleEnums::SP_QgnGrafBarWaitAnim:
458             fallbackIndex = EMbmAvkonQgn_graf_bar_wait_1;
459             break;
460         case QS60StyleEnums::SP_QgnGrafBarFrameCenter:
461             fallbackIndex = EMbmAvkonQgn_graf_bar_frame_center;
462             break;
463         case QS60StyleEnums::SP_QgnGrafBarFrameSideL:
464             fallbackIndex = EMbmAvkonQgn_graf_bar_frame_side_l;
465             break;
466         case QS60StyleEnums::SP_QgnGrafBarFrameSideR:
467             fallbackIndex = EMbmAvkonQgn_graf_bar_frame_side_r;
468             break;
469         case QS60StyleEnums::SP_QgnGrafBarProgress:
470             fallbackIndex = EMbmAvkonQgn_graf_bar_progress;
471             break;
472         case QS60StyleEnums::SP_QgnGrafTabActiveL:
473             fallbackIndex = EMbmAvkonQgn_graf_tab_active_l;
474             break;
475         case QS60StyleEnums::SP_QgnGrafTabActiveM:
476             fallbackIndex = EMbmAvkonQgn_graf_tab_active_m;
477             break;
478         case QS60StyleEnums::SP_QgnGrafTabActiveR:
479             fallbackIndex = EMbmAvkonQgn_graf_tab_active_r;
480             break;
481         case QS60StyleEnums::SP_QgnGrafTabPassiveL:
482             fallbackIndex = EMbmAvkonQgn_graf_tab_passive_l;
483             break;
484         case QS60StyleEnums::SP_QgnGrafTabPassiveM:
485             fallbackIndex = EMbmAvkonQgn_graf_tab_passive_m;
486             break;
487         case QS60StyleEnums::SP_QgnGrafTabPassiveR:
488             fallbackIndex = EMbmAvkonQgn_graf_tab_passive_r;
489             break;
490         case QS60StyleEnums::SP_QgnIndiCheckboxOff:
491             fallbackIndex = EMbmAvkonQgn_indi_checkbox_off;
492             break;
493         case QS60StyleEnums::SP_QgnIndiCheckboxOn:
494             fallbackIndex = EMbmAvkonQgn_indi_checkbox_on;
495             break;
496         case QS60StyleEnums::SP_QgnIndiHlColSuper:
497             fallbackIndex = 0x4456; /* EMbmAvkonQgn_indi_hl_col_super */
498             break;
499         case QS60StyleEnums::SP_QgnIndiHlExpSuper:
500             fallbackIndex = 0x4458; /* EMbmAvkonQgn_indi_hl_exp_super */
501             break;
502         case QS60StyleEnums::SP_QgnIndiHlLineBranch:
503             fallbackIndex = 0x445A; /* EMbmAvkonQgn_indi_hl_line_branch */
504             break;
505         case QS60StyleEnums::SP_QgnIndiHlLineEnd:
506             fallbackIndex = 0x445C; /* EMbmAvkonQgn_indi_hl_line_end */
507             break;
508         case QS60StyleEnums::SP_QgnIndiHlLineStraight:
509             fallbackIndex = 0x445E; /* EMbmAvkonQgn_indi_hl_line_straight */
510             break;
511         case QS60StyleEnums::SP_QgnIndiMarkedAdd:
512             fallbackIndex = EMbmAvkonQgn_indi_marked_add;
513             break;
514         case QS60StyleEnums::SP_QgnIndiNaviArrowLeft:
515             fallbackIndex = EMbmAvkonQgn_indi_navi_arrow_left;
516             break;
517         case QS60StyleEnums::SP_QgnIndiNaviArrowRight:
518             fallbackIndex = EMbmAvkonQgn_indi_navi_arrow_right;
519             break;
520         case QS60StyleEnums::SP_QgnIndiRadiobuttOff:
521             fallbackIndex = EMbmAvkonQgn_indi_radiobutt_off;
522             break;
523         case QS60StyleEnums::SP_QgnIndiRadiobuttOn:
524             fallbackIndex = EMbmAvkonQgn_indi_radiobutt_on;
525             break;
526         case QS60StyleEnums::SP_QgnGrafNsliderMarker:
527             fallbackIndex = 17572; /* EMbmAvkonQgn_graf_nslider_marker */
528             break;
529         case QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected:
530             fallbackIndex = 17574; /* EMbmAvkonQgn_graf_nslider_marker_selected */
531             break;
532         case QS60StyleEnums::SP_QgnIndiSubmenu:
533             fallbackIndex = EMbmAvkonQgn_indi_submenu;
534             break;
535         case QS60StyleEnums::SP_QgnNoteErased:
536             fallbackIndex = EMbmAvkonQgn_note_erased;
537             break;
538         case QS60StyleEnums::SP_QgnNoteError:
539             fallbackIndex = EMbmAvkonQgn_note_error;
540             break;
541         case QS60StyleEnums::SP_QgnNoteInfo:
542             fallbackIndex = EMbmAvkonQgn_note_info;
543             break;
544         case QS60StyleEnums::SP_QgnNoteOk:
545             fallbackIndex = EMbmAvkonQgn_note_ok;
546             break;
547         case QS60StyleEnums::SP_QgnNoteQuery:
548             fallbackIndex = EMbmAvkonQgn_note_query;
549             break;
550         case QS60StyleEnums::SP_QgnNoteWarning:
551             fallbackIndex = EMbmAvkonQgn_note_warning;
552             break;
553         case QS60StyleEnums::SP_QgnPropFileSmall:
554             fallbackIndex = EMbmAvkonQgn_prop_file_small;
555             break;
556         case QS60StyleEnums::SP_QgnPropFolderCurrent:
557             fallbackIndex = EMbmAvkonQgn_prop_folder_current;
558             break;
559         case QS60StyleEnums::SP_QgnPropFolderSmall:
560             fallbackIndex = EMbmAvkonQgn_prop_folder_small;
561             break;
562         case QS60StyleEnums::SP_QgnPropFolderSmallNew:
563             fallbackIndex = EMbmAvkonQgn_prop_folder_small_new;
564             break;
565         case QS60StyleEnums::SP_QgnPropPhoneMemcLarge:
566             fallbackIndex = EMbmAvkonQgn_prop_phone_memc_large;
567             break;
568         default:
569             fallbackIndex = -1;
570             break;
571     }
572 }
573
574 QPixmap QS60StyleModeSpecifics::colorSkinnedGraphicsLX(
575     const QS60StyleEnums::SkinParts &stylepart,
576     const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags)
577 {
578     // this function can throw both exceptions and leaves. There are no cleanup dependencies between Qt and Symbian parts.
579     const int stylepartIndex = (int)stylepart;
580     const TAknsItemID skinId = m_partMap[stylepartIndex].skinID;
581
582     TInt fallbackGraphicID = -1;
583     fallbackInfo(stylepart, fallbackGraphicID);
584
585     TAknsItemID colorGroup = KAknsIIDQsnIconColors;
586     TRgb defaultColor = KRgbBlack;
587     int colorIndex = -1; //set a bogus value to color index to ensure that painter color is used
588                          //to color the icon
589     if (painter) {
590         QRgb widgetColor = painter->pen().color().rgb();
591         defaultColor = TRgb(qRed(widgetColor), qGreen(widgetColor), qBlue(widgetColor));
592     }
593
594     const bool rotatedBy90or270 =
595         (flags & (QS60StylePrivate::SF_PointEast | QS60StylePrivate::SF_PointWest));
596     const TSize targetSize =
597         rotatedBy90or270?TSize(size.height(), size.width()):TSize(size.width(), size.height());
598     CFbsBitmap *icon = 0;
599     CFbsBitmap *iconMask = 0;
600     const TInt fallbackGraphicsMaskID =
601         fallbackGraphicID == KErrNotFound?KErrNotFound:fallbackGraphicID+1; //masks are auto-generated as next in mif files
602     MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
603     AknsUtils::CreateColorIconLC(
604         skinInstance,
605         skinId,
606         colorGroup,
607         colorIndex,
608         icon,
609         iconMask,
610         AknIconUtils::AvkonIconFileName(),
611         fallbackGraphicID,
612         fallbackGraphicsMaskID,
613         defaultColor);
614
615     QPixmap result = fromFbsBitmap(icon, iconMask, flags, targetSize);
616     CleanupStack::PopAndDestroy(2); //icon, iconMask
617     return result;
618 }
619
620 QColor QS60StyleModeSpecifics::colorValue(const TAknsItemID &colorGroup, int colorIndex)
621 {
622     TRgb skinnedColor;
623     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
624     AknsUtils::GetCachedColor(skin, skinnedColor, colorGroup, colorIndex);
625     return QColor(skinnedColor.Red(),skinnedColor.Green(),skinnedColor.Blue());
626 }
627
628 struct QAutoFbsBitmapHeapLock
629 {
630     QAutoFbsBitmapHeapLock(CFbsBitmap* aBmp) : mBmp(aBmp) { mBmp->LockHeap(); }
631     ~QAutoFbsBitmapHeapLock() { mBmp->UnlockHeap(); }
632     CFbsBitmap* mBmp;
633 };
634
635 QPixmap QS60StyleModeSpecifics::fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask, QS60StylePrivate::SkinElementFlags flags, const TSize &targetSize)
636 {
637     Q_ASSERT(icon);
638
639     AknIconUtils::DisableCompression(icon);
640     TInt error = AknIconUtils::SetSize(icon, targetSize, EAspectRatioNotPreserved);
641
642     if (mask && !error) {
643         AknIconUtils::DisableCompression(mask);
644         error = AknIconUtils::SetSize(mask, targetSize, EAspectRatioNotPreserved);
645     }
646     if (error)
647         return QPixmap();
648
649     QPixmap pixmap;
650     QScopedPointer<QPixmapData> pd(QPixmapData::create(0, 0, QPixmapData::PixmapType));
651     if (mask) {
652         // Try the efficient path with less copying and conversion.
653         QVolatileImage img(icon, mask);
654         pd->fromNativeType(&img, QPixmapData::VolatileImage);
655         if (!pd->isNull())
656             pixmap = QPixmap(pd.take());
657     }
658     if (pixmap.isNull()) {
659         // Potentially more expensive path.
660         pd->fromNativeType(icon, QPixmapData::FbsBitmap);
661         pixmap = QPixmap(pd.take());
662         if (mask) {
663             pixmap.setAlphaChannel(QPixmap::fromSymbianCFbsBitmap(mask));
664         }
665     }
666
667     if ((flags & QS60StylePrivate::SF_PointEast) ||
668         (flags & QS60StylePrivate::SF_PointSouth) ||
669         (flags & QS60StylePrivate::SF_PointWest)) {
670         QImage iconImage = pixmap.toImage();
671         QTransform imageTransform;
672         if (flags & QS60StylePrivate::SF_PointEast) {
673             imageTransform.rotate(90);
674         } else if (flags & QS60StylePrivate::SF_PointSouth) {
675             imageTransform.rotate(180);
676             iconImage = iconImage.transformed(imageTransform);
677         } else if (flags & QS60StylePrivate::SF_PointWest) {
678             imageTransform.rotate(270);
679         }
680         if (imageTransform.isRotating())
681             iconImage = iconImage.transformed(imageTransform);
682
683         pixmap = QPixmap::fromImage(iconImage);
684     }
685     if ((flags & QS60StylePrivate::SF_Mirrored_X_Axis) ||
686         (flags & QS60StylePrivate::SF_Mirrored_Y_Axis)) {
687         QImage iconImage = pixmap.toImage().mirrored(
688             flags & QS60StylePrivate::SF_Mirrored_X_Axis,
689             flags & QS60StylePrivate::SF_Mirrored_Y_Axis);
690         pixmap = QPixmap::fromImage(iconImage);
691     }
692
693     return pixmap;
694 }
695
696 bool QS60StylePrivate::isSingleClickUi()
697 {
698     return (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0);
699 }
700
701 void QS60StylePrivate::deleteStoredSettings()
702 {
703     QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
704     settings.beginGroup(QLatin1String("QS60Style"));
705     settings.remove(QString());
706     settings.endGroup();
707 }
708
709 // Since S60Style has 'button' as a graphic, we don't have any native color which to use
710 // for QPalette::Button. Therefore S60Style needs to guesstimate palette color by calculating
711 // average rgb values for button pixels.
712 // Returns Qt::black if there is an issue with the graphics (image is NULL, or no constBits() found).
713 QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const
714 {
715 #ifndef QT_NO_SETTINGS
716     TInt themeID = 0;
717     //First we need to fetch active theme ID. We need to store the themeID at the same time
718     //as color, so that we can later check if the stored color is still from the same theme.
719     //Native side stores active theme UID/Timestamp into central repository.
720     int error = 0;
721     QT_TRAP_THROWING(
722         CRepository *themeRepository = CRepository::NewLC(personalisationUID);
723         if (themeRepository) {
724             TBuf<32> value; //themeID is currently max of 8 + 1 + 8 characters, but lets have some extra space
725             const TUint32 key = 0x00000002; //active theme key in the repository
726             error = themeRepository->Get(key, value);
727             if (error == KErrNone) {
728                 TLex lex(value);
729                 TPtrC numberToken(lex.NextToken());
730                 if (numberToken.Length())
731                     error = TLex(numberToken).Val(themeID);
732                 else
733                     error = KErrArgument;
734             }
735         }
736         CleanupStack::PopAndDestroy(themeRepository);
737     );
738
739     QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
740     settings.beginGroup(QLatin1String("QS60Style"));
741     if (themeID != 0) {
742         QVariant buttonColor = settings.value(QLatin1String("ButtonColor"));
743         if (!buttonColor.isNull()) {
744             //there is a stored color value, lets see if the theme ID matches
745             if (error == KErrNone) {
746                 QVariant themeUID = settings.value(QLatin1String("ThemeUID"));
747                 if (!themeUID.isNull() && themeUID.toInt() == themeID) {
748                     QColor storedColor(buttonColor.value<QColor>());
749                     if (storedColor.isValid())
750                         return storedColor;
751                 }
752             }
753             settings.remove(QString()); //if color was invalid, or theme has been changed, just delete all stored settings
754         }
755     }
756 #endif
757
758     QColor color = calculatedColor(frame);
759
760 #ifndef QT_NO_SETTINGS
761     settings.setValue(QLatin1String("ThemeUID"), QVariant(themeID));
762     if (frame == SF_ButtonNormal) //other colors are not currently calculated from graphics
763         settings.setValue(QLatin1String("ButtonColor"), QVariant(color));
764     settings.endGroup();
765 #endif
766
767     return color;
768 }
769
770 QPoint qt_s60_fill_background_offset(const QWidget *targetWidget)
771 {
772     CCoeControl *control = targetWidget->effectiveWinId();
773     TPoint pos(0,0);
774     if (control)
775         pos = control->PositionRelativeToScreen();
776     return QPoint(pos.iX, pos.iY);
777 }
778
779 QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(
780     QS60StyleEnums::SkinParts part, const QSize &size,
781     QS60StylePrivate::SkinElementFlags flags)
782 {
783     // this function can throw both exceptions and leaves. There are no cleanup dependencies between Qt and Symbian parts.
784     if (!size.isValid())
785         return QPixmap();
786
787     // Check release support and change part, if necessary.
788     const TAknsItemID skinId = partSpecificThemeId((int)part);
789     const int stylepartIndex = (int)part;
790     const TDrawType drawType = m_partMap[stylepartIndex].drawType;
791     Q_ASSERT(drawType != ENoDraw);
792     const bool rotatedBy90or270 =
793         (flags & (QS60StylePrivate::SF_PointEast | QS60StylePrivate::SF_PointWest));
794     const TSize targetSize =
795         rotatedBy90or270 ? TSize(size.height(), size.width()) : qt_QSize2TSize(size);
796
797     MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
798     static const TDisplayMode displayMode = S60->supportsPremultipliedAlpha ? Q_SYMBIAN_ECOLOR16MAP : EColor16MA;
799     static const TInt drawParam = S60->supportsPremultipliedAlpha ? KAknsDrawParamDefault : KAknsDrawParamRGBOnly;
800
801     QPixmap result;
802
803     switch (drawType) {
804         case EDrawGulIcon: {
805             CGulIcon* icon = AknsUtils::CreateGulIconL( AknsUtils::SkinInstance(), skinId, EFalse );
806             if (icon)
807                 result = fromFbsBitmap(icon->Bitmap(), icon->Mask(), flags, targetSize);
808             delete icon;
809             break;
810         }
811         case EDrawIcon: {
812             TInt fallbackGraphicID = -1;
813             fallbackInfo(part, fallbackGraphicID);
814
815             CFbsBitmap *icon = 0;
816             CFbsBitmap *iconMask = 0;
817             const TInt fallbackGraphicsMaskID =
818                 fallbackGraphicID == KErrNotFound?KErrNotFound:fallbackGraphicID+1; //masks are auto-generated as next in mif files
819
820             AknsUtils::CreateIconL(
821                 skinInstance,
822                 skinId,
823                 icon,
824                 iconMask,
825                 AknIconUtils::AvkonIconFileName(),
826                 fallbackGraphicID ,
827                 fallbackGraphicsMaskID);
828
829             result = fromFbsBitmap(icon, iconMask, flags, targetSize);
830             delete icon;
831             delete iconMask;
832             break;
833         }
834         case EDrawBackground: {
835     //        QS60WindowSurface::unlockBitmapHeap();
836             CFbsBitmap *background = new (ELeave) CFbsBitmap(); //offscreen
837             CleanupStack::PushL(background);
838             User::LeaveIfError(background->Create(targetSize, displayMode));
839
840             CFbsBitmapDevice *dev = CFbsBitmapDevice::NewL(background);
841             CleanupStack::PushL(dev);
842             CFbsBitGc *gc = NULL;
843             User::LeaveIfError(dev->CreateContext(gc));
844             CleanupStack::PushL(gc);
845
846             CAknsBasicBackgroundControlContext *bgContext = CAknsBasicBackgroundControlContext::NewL(
847                 skinId,
848                 targetSize,
849                 EFalse);
850             CleanupStack::PushL(bgContext);
851
852             const TBool drawn = AknsDrawUtils::DrawBackground(
853                 skinInstance,
854                 bgContext,
855                 NULL,
856                 *gc,
857                 TPoint(),
858                 targetSize,
859                 drawParam);
860
861             if (drawn)
862                 result = fromFbsBitmap(background, NULL, flags, targetSize);
863             // if drawing fails in skin server, just ignore the background (probably OOM case)
864
865             CleanupStack::PopAndDestroy(4, background); //background, dev, gc, bgContext
866     //        QS60WindowSurface::lockBitmapHeap();
867             break;
868         }
869         case EDrawAnimation: {
870             CFbsBitmap* animationFrame;
871             CFbsBitmap* frameMask;
872             CAknBitmapAnimation* aknAnimation = 0;
873             TBool constructedFromTheme = ETrue;
874
875             QS60StyleAnimation* animation = QS60StylePrivate::animationDefinition(part); //ownership is not passed
876             if (animation) {
877                 if (!animation->animationObject() && !animation->isResourceBased()) {// no pre-made item exists, create new animation
878                     CAknBitmapAnimation* newAnimation = CAknBitmapAnimation::NewL();
879                     CleanupStack::PushL(newAnimation);
880                     if (newAnimation)
881                         constructedFromTheme = newAnimation->ConstructFromSkinL(skinId);
882                     if (constructedFromTheme && newAnimation->BitmapAnimData()->FrameArray().Count() > 0) {
883                         animation->setResourceBased(false);
884                         animation->setAnimationObject(newAnimation); //animation takes ownership
885                     }
886                     CleanupStack::Pop(newAnimation);
887                 }
888                 //fill-in stored information
889                 aknAnimation = animation->animationObject();
890                 constructedFromTheme = !animation->isResourceBased();
891             }
892
893             const int currentFrame = QS60StylePrivate::currentAnimationFrame(part);
894             if (constructedFromTheme && aknAnimation && aknAnimation->BitmapAnimData()->FrameArray().Count() > 0) {
895                 //Animation was created successfully and contains frames, just fetch current frame
896                 if(currentFrame >= aknAnimation->BitmapAnimData()->FrameArray().Count())
897                     User::Leave(KErrOverflow);
898                 const CBitmapFrameData* frameData = aknAnimation->BitmapAnimData()->FrameArray().At(currentFrame);
899                 if (frameData) {
900                     animationFrame = frameData->Bitmap();
901                     frameMask = frameData->Mask();
902                 }
903             } else {
904                 //Theme does not contain animation theming, create frames from resource file
905                 TInt fallbackGraphicID = -1;
906                 fallbackInfo(part, fallbackGraphicID);
907                 fallbackGraphicID = fallbackGraphicID + (currentFrame * 2); //skip masks
908                 TInt fallbackGraphicsMaskID =
909                     (fallbackGraphicID == KErrNotFound) ? KErrNotFound : fallbackGraphicID + 1; //masks are auto-generated as next in mif files
910                 if (fallbackGraphicsMaskID != KErrNotFound)
911                     fallbackGraphicsMaskID = fallbackGraphicsMaskID + (currentFrame * 2); //skip actual graphics
912
913                 //Then draw animation frame
914                 AknsUtils::CreateIconL(
915                     skinInstance,
916                     KAknsIIDDefault, //animation is not themed, lets force fallback graphics
917                     animationFrame,
918                     frameMask,
919                     AknIconUtils::AvkonIconFileName(),
920                     fallbackGraphicID ,
921                     fallbackGraphicsMaskID);
922             }
923             result = fromFbsBitmap(animationFrame, frameMask, flags, targetSize);
924             if (!constructedFromTheme) {
925                 delete animationFrame;
926                 animationFrame = 0;
927                 delete frameMask;
928                 frameMask = 0;
929             }
930             break;
931         }
932     }
933     if (!result)
934         result = QPixmap();
935
936     return result;
937 }
938
939 QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(QS60StylePrivate::SkinFrameElements frameElement,
940     const QSize &size, QS60StylePrivate::SkinElementFlags flags)
941 {
942     // this function can throw both exceptions and leaves. There are no cleanup dependencies between Qt and Symbian parts.
943     if (!size.isValid())
944         return QPixmap();
945
946     const bool rotatedBy90or270 =
947         (flags & (QS60StylePrivate::SF_PointEast | QS60StylePrivate::SF_PointWest));
948     const TSize targetSize =
949         rotatedBy90or270 ? TSize(size.height(), size.width()) : qt_QSize2TSize(size);
950
951     MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
952     QPixmap result;
953
954     static const TDisplayMode displayMode = S60->supportsPremultipliedAlpha ? Q_SYMBIAN_ECOLOR16MAP : EColor16MA;
955     static const TInt drawParam = S60->supportsPremultipliedAlpha ? KAknsDrawParamDefault : KAknsDrawParamNoClearUnderImage|KAknsDrawParamRGBOnly;
956
957     CFbsBitmap *frame = new (ELeave) CFbsBitmap(); //offscreen
958     CleanupStack::PushL(frame);
959     User::LeaveIfError(frame->Create(targetSize, displayMode));
960
961     CFbsBitmapDevice* bitmapDev = CFbsBitmapDevice::NewL(frame);
962     CleanupStack::PushL(bitmapDev);
963     CFbsBitGc* bitmapGc = NULL;
964     User::LeaveIfError(bitmapDev->CreateContext(bitmapGc));
965     CleanupStack::PushL(bitmapGc);
966
967     frame->LockHeap();
968     memset(frame->DataAddress(), 0, frame->SizeInPixels().iWidth * frame->SizeInPixels().iHeight * 4);  // 4: argb bytes
969     frame->UnlockHeap();
970
971     const TRect outerRect(TPoint(0, 0), targetSize);
972     const TRect innerRect = innerRectFromElement(frameElement, outerRect);
973
974     TAknsItemID frameSkinID, centerSkinID;
975     frameSkinID = centerSkinID = partSpecificThemeId(QS60StylePrivate::m_frameElementsData[frameElement].center);
976     frameIdAndCenterId(frameElement, frameSkinID, centerSkinID);
977
978     TBool drawn = AknsDrawUtils::DrawFrame(
979         skinInstance,
980         *bitmapGc,
981         outerRect,
982         innerRect,
983         frameSkinID,
984         centerSkinID,
985         drawParam );
986
987     if (S60->supportsPremultipliedAlpha) {
988         if (drawn) {
989             result = fromFbsBitmap(frame, NULL, flags, targetSize);
990         } else {
991             // Drawing might fail due to OOM (we can do nothing about that),
992             // or due to skin item not being available.
993             // If the latter occurs, lets try switch to non-release specific items (if available)
994             // and re-try the drawing.
995             frameSkinID = centerSkinID = m_partMap[(int)QS60StylePrivate::m_frameElementsData[frameElement].center].skinID;
996             frameIdAndCenterId(frameElement, frameSkinID, centerSkinID);
997             drawn = AknsDrawUtils::DrawFrame( skinInstance,
998                                    *bitmapGc, outerRect, innerRect,
999                                    frameSkinID, centerSkinID,
1000                                    drawParam );
1001             // in case drawing fails, even after using default graphics, ignore the error
1002             if (drawn)
1003                 result = fromFbsBitmap(frame, NULL, flags, targetSize);
1004         }
1005     } else {
1006         TDisplayMode maskDepth = EGray256;
1007         // Query the skin item for possible frame graphics mask details.
1008         if (skinInstance) {
1009             CAknsMaskedBitmapItemData* skinMaskedBmp = static_cast<CAknsMaskedBitmapItemData*>(
1010                     skinInstance->GetCachedItemData(frameSkinID,EAknsITMaskedBitmap));
1011             if (skinMaskedBmp && skinMaskedBmp->Mask())
1012                 maskDepth = skinMaskedBmp->Mask()->DisplayMode();
1013         }
1014         if (maskDepth != ENone) {
1015             CFbsBitmap *frameMask = new (ELeave) CFbsBitmap(); //offscreen
1016             CleanupStack::PushL(frameMask);
1017             User::LeaveIfError(frameMask->Create(targetSize, maskDepth));
1018
1019             CFbsBitmapDevice* maskBitmapDevice = CFbsBitmapDevice::NewL(frameMask);
1020             CleanupStack::PushL(maskBitmapDevice);
1021             CFbsBitGc* maskBitGc = NULL;
1022             User::LeaveIfError(maskBitmapDevice->CreateContext(maskBitGc));
1023             CleanupStack::PushL(maskBitGc);
1024
1025             if (drawn) {
1026                 //ensure that the mask is really transparent
1027                 maskBitGc->Activate( maskBitmapDevice );
1028                 maskBitGc->SetPenStyle(CGraphicsContext::ENullPen);
1029                 maskBitGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
1030                 maskBitGc->SetBrushColor(KRgbWhite);
1031                 maskBitGc->Clear();
1032                 maskBitGc->SetBrushStyle(CGraphicsContext::ENullBrush);
1033
1034                 drawn = AknsDrawUtils::DrawFrame(skinInstance,
1035                                            *maskBitGc, outerRect, innerRect,
1036                                            frameSkinID, centerSkinID,
1037                                            KAknsSDMAlphaOnly |KAknsDrawParamNoClearUnderImage);
1038                 if (drawn)
1039                     result = fromFbsBitmap(frame, frameMask, flags, targetSize);
1040             }
1041             CleanupStack::PopAndDestroy(3, frameMask);
1042         }
1043     }
1044     CleanupStack::PopAndDestroy(3, frame); //frame, bitmapDev, bitmapGc
1045     return result;
1046 }
1047
1048 void QS60StyleModeSpecifics::frameIdAndCenterId(QS60StylePrivate::SkinFrameElements frameElement, TAknsItemID &frameId, TAknsItemID &centerId)
1049 {
1050 // There are some major mix-ups in skin declarations for some frames.
1051 // First, the frames are not declared in sequence.
1052 // Second, the parts use different major than the frame-master.
1053
1054     switch(frameElement) {
1055         case QS60StylePrivate::SF_ToolTip:
1056             centerId.Set(EAknsMajorGeneric, 0x19c2);
1057             frameId.Set(EAknsMajorSkin, 0x5300);
1058             break;
1059         case QS60StylePrivate::SF_PopupBackground:
1060             centerId.Set(KAknsIIDQsnFrPopupCenterSubmenu);
1061             frameId.Set(KAknsIIDQsnFrPopupSub);
1062             break;
1063         case QS60StylePrivate::SF_SettingsList:
1064             // Starting from S60_5_3, the root theme has been changed so that KAknsIIDQsnFrSetOpt is empty.
1065             // Set the theme ID to None, to avoid theme server trying to draw the empty frame.
1066             if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_2) {
1067                 centerId.Set(KAknsIIDNone);
1068                 frameId.Set(KAknsIIDNone);
1069             }
1070             break;
1071         case QS60StylePrivate::SF_PanelBackground:
1072             // remove center piece for panel graphics, so that only border is drawn
1073             centerId.Set(KAknsIIDNone);
1074             frameId.Set(KAknsIIDQsnFrSetOpt);
1075             break;
1076         default:
1077             // center should be correct here
1078             frameId.iMinor = centerId.iMinor - 9;
1079             break;
1080     }
1081 }
1082
1083 TRect QS60StyleModeSpecifics::innerRectFromElement(QS60StylePrivate::SkinFrameElements frameElement, const TRect &outerRect)
1084 {
1085     TInt widthShrink = QS60StylePrivate::pixelMetric(PM_FrameCornerWidth);
1086     TInt heightShrink = QS60StylePrivate::pixelMetric(PM_FrameCornerHeight);
1087     switch(frameElement) {
1088         case QS60StylePrivate::SF_PanelBackground:
1089             // panel should have slightly slimmer border to enable thin line of background graphics between closest component
1090             widthShrink = widthShrink - 2;
1091             heightShrink = heightShrink - 2;
1092             break;
1093         case QS60StylePrivate::SF_ToolTip:
1094             widthShrink = widthShrink >> 1;
1095             heightShrink = heightShrink >> 1;
1096             break;
1097         case QS60StylePrivate::SF_ListHighlight:
1098             //In Sym^3 devices highlights are less blocky
1099             if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
1100                 widthShrink += 2;
1101                 heightShrink += 2;
1102             } else {
1103                 widthShrink -= 2;
1104                 heightShrink -= 2;
1105             }
1106             break;
1107         case QS60StylePrivate::SF_PopupBackground:
1108             widthShrink = widthShrink + 5;
1109             heightShrink = heightShrink + 5;
1110             break;
1111         default:
1112             break;
1113     }
1114     TRect innerRect(outerRect);
1115     innerRect.Shrink(widthShrink, heightShrink);
1116     return innerRect;
1117 }
1118
1119 bool QS60StyleModeSpecifics::checkSupport(const int supportedRelease)
1120 {
1121     const QSysInfo::S60Version currentRelease = QSysInfo::s60Version();
1122     return ( (currentRelease == QSysInfo::SV_S60_3_1 && supportedRelease & ES60_3_1) ||
1123              (currentRelease == QSysInfo::SV_S60_3_2 && supportedRelease & ES60_3_2) ||
1124              (currentRelease == QSysInfo::SV_S60_5_0 && supportedRelease & ES60_5_0) ||
1125              (currentRelease == QSysInfo::SV_S60_5_1 && supportedRelease & ES60_5_1) ||
1126              (currentRelease == QSysInfo::SV_S60_5_2 && supportedRelease & ES60_5_2) ||
1127              (currentRelease == QSysInfo::SV_S60_5_3 && supportedRelease & ES60_5_3) );
1128 }
1129
1130 TAknsItemID QS60StyleModeSpecifics::partSpecificThemeId(int part)
1131 {
1132     TAknsItemID newSkinId;
1133     if (!checkSupport(m_partMap[(int)part].supportInfo))
1134         newSkinId.Set(m_partMap[(int)part].newMajorSkinId, m_partMap[(int)part].newMinorSkinId);
1135     else
1136         newSkinId.Set(m_partMap[(int)part].skinID);
1137     return newSkinId;
1138 }
1139
1140 QFont QS60StylePrivate::s60Font_specific(
1141     QS60StyleEnums::FontCategories fontCategory,
1142     int pointSize, bool resolveFontSize)
1143 {
1144     Q_UNUSED(resolveFontSize);
1145
1146     TAknFontCategory aknFontCategory = EAknFontCategoryUndefined;
1147     switch (fontCategory) {
1148         case QS60StyleEnums::FC_Primary:
1149             aknFontCategory = EAknFontCategoryPrimary;
1150             break;
1151         case QS60StyleEnums::FC_Secondary:
1152             aknFontCategory = EAknFontCategorySecondary;
1153             break;
1154         case QS60StyleEnums::FC_Title:
1155             aknFontCategory = EAknFontCategoryTitle;
1156             break;
1157         case QS60StyleEnums::FC_PrimarySmall:
1158             aknFontCategory = EAknFontCategoryPrimarySmall;
1159             break;
1160         case QS60StyleEnums::FC_Digital:
1161             aknFontCategory = EAknFontCategoryDigital;
1162             break;
1163         case QS60StyleEnums::FC_Undefined:
1164         default:
1165             break;
1166     }
1167
1168     // Create AVKON font according the given parameters
1169     CWsScreenDevice* dev = CCoeEnv::Static()->ScreenDevice();
1170     TAknFontSpecification spec(aknFontCategory, TFontSpec(), NULL);
1171     if (pointSize > 0) {
1172         const TInt pixelSize = dev->VerticalTwipsToPixels(pointSize * KTwipsPerPoint);
1173         spec.SetTextPaneHeight(pixelSize + 4); // TODO: Is 4 a reasonable top+bottom margin?
1174     }
1175
1176     QFont result;
1177     TRAPD( error, QT_TRYCATCH_LEAVING({
1178         const CAknLayoutFont* aknFont =
1179             AknFontAccess::CreateLayoutFontFromSpecificationL(*dev, spec);
1180
1181         result = qt_TFontSpec2QFontL(aknFont->DoFontSpecInTwips());
1182         if (result.pointSize() != pointSize)
1183             result.setPointSize(pointSize); // Correct the font size returned by CreateLayoutFontFromSpecificationL()
1184
1185         delete aknFont;
1186     }));
1187     if (error) result = QFont();
1188     return result;
1189 }
1190
1191 void QS60StylePrivate::setActiveLayout()
1192 {
1193     const QSize activeScreenSize(screenSize());
1194     int activeLayoutIndex = -1;
1195     const short screenHeight = (short)activeScreenSize.height();
1196     const short screenWidth = (short)activeScreenSize.width();
1197     for (int i=0; i<m_numberOfLayouts; i++) {
1198         if (screenHeight==m_layoutHeaders[i].height &&
1199             screenWidth==m_layoutHeaders[i].width) {
1200             activeLayoutIndex = i;
1201             break;
1202         }
1203     }
1204
1205     //not found, lets try with either of dimensions
1206     if (activeLayoutIndex==-1){
1207         const bool landscape = screenHeight < screenWidth;
1208         activeLayoutIndex += (!landscape) ? 1 : 0;
1209     }
1210
1211     setCurrentLayout(activeLayoutIndex);
1212 }
1213
1214 Q_GLOBAL_STATIC(QList<QS60StyleAnimation *>, m_animations)
1215
1216 QS60StylePrivate::QS60StylePrivate()
1217 {
1218     //Animation defaults need to be created when style is instantiated
1219     QS60StyleAnimation* progressBarAnimation = new QS60StyleAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim, 7, 100);
1220     m_animations()->append(progressBarAnimation);
1221     // No need to set active layout, if dynamic metrics API is available
1222     setActiveLayout();
1223 }
1224
1225 void QS60StylePrivate::removeAnimations()
1226 {
1227     //currently only one animation in the list.
1228     m_animations()->removeFirst();
1229 }
1230
1231 QColor QS60StylePrivate::s60Color(QS60StyleEnums::ColorLists list,
1232     int index, const QStyleOption *option)
1233 {
1234     static const TAknsItemID *idMap[] = {
1235         &KAknsIIDQsnHighlightColors,
1236         &KAknsIIDQsnIconColors,
1237         &KAknsIIDQsnLineColors,
1238         &KAknsIIDQsnOtherColors,
1239         &KAknsIIDQsnParentColors,
1240         &KAknsIIDQsnTextColors
1241     };
1242     Q_ASSERT((int)list < (int)sizeof(idMap)/sizeof(idMap[0]));
1243     const QColor color = QS60StyleModeSpecifics::colorValue(*idMap[(int) list], index - 1);
1244     return option ? QS60StylePrivate::stateColor(color, option) : color;
1245 }
1246
1247 // In some cases, the AVKON UI themegraphic is already in 'disabled state'.
1248 // If so, return true for these parts.
1249 bool QS60StyleModeSpecifics::disabledPartGraphic(QS60StyleEnums::SkinParts &part)
1250 {
1251     bool disabledGraphic = false;
1252     switch(part){
1253         // inactive button graphics are available from 5.0 onwards
1254         case QS60StyleEnums::SP_QsnFrButtonCornerTlInactive:
1255         case QS60StyleEnums::SP_QsnFrButtonCornerTrInactive:
1256         case QS60StyleEnums::SP_QsnFrButtonCornerBlInactive:
1257         case QS60StyleEnums::SP_QsnFrButtonCornerBrInactive:
1258         case QS60StyleEnums::SP_QsnFrButtonSideTInactive:
1259         case QS60StyleEnums::SP_QsnFrButtonSideBInactive:
1260         case QS60StyleEnums::SP_QsnFrButtonSideLInactive:
1261         case QS60StyleEnums::SP_QsnFrButtonSideRInactive:
1262         case QS60StyleEnums::SP_QsnFrButtonCenterInactive:
1263             disabledGraphic = true;
1264             break;
1265         default:
1266             break;
1267     }
1268     return disabledGraphic;
1269 }
1270
1271 // In some cases, the AVKON UI themegraphic is already in 'disabled state'.
1272 // If so, return true for these frames.
1273 bool QS60StyleModeSpecifics::disabledFrameGraphic(QS60StylePrivate::SkinFrameElements &frame)
1274 {
1275     bool disabledGraphic = false;
1276     switch(frame){
1277         // inactive button graphics are available from 5.0 onwards
1278         case QS60StylePrivate::SF_ButtonInactive:
1279             disabledGraphic = true;
1280             break;
1281         default:
1282             break;
1283     }
1284     return disabledGraphic;
1285 }
1286
1287 QPixmap QS60StyleModeSpecifics::generateMissingThemeGraphic(QS60StyleEnums::SkinParts &part,
1288         const QSize &size, QS60StylePrivate::SkinElementFlags flags)
1289 {
1290     QS60StyleEnums::SkinParts updatedPart = part;
1291     switch(part){
1292     // AVKON UI has a abnormal handling for scrollbar graphics. It is possible that the root
1293     // skin does not contain mandatory graphics for scrollbar pressed states. Therefore, AVKON UI
1294     // creates dynamically these graphics by modifying the normal state scrollbar graphics slightly.
1295     // S60Style needs to work similarly. Therefore if skingraphics call provides to be a miss
1296     // (i.e. result is not valid), style needs to draw normal graphics instead and apply some
1297     // modifications (similar to generatedIconPixmap()) to the result.
1298     case QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed:
1299         updatedPart = QS60StyleEnums::SP_QsnCpScrollHandleBottom;
1300         break;
1301     case QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed:
1302         updatedPart = QS60StyleEnums::SP_QsnCpScrollHandleMiddle;
1303         break;
1304     case QS60StyleEnums::SP_QsnCpScrollHandleTopPressed:
1305         updatedPart = QS60StyleEnums::SP_QsnCpScrollHandleTop;
1306         break;
1307     default:
1308         break;
1309     }
1310     if (part==updatedPart) {
1311         return QPixmap();
1312     } else {
1313         QPixmap result = skinnedGraphics(updatedPart, size, flags);
1314         QStyleOption opt;
1315         QPalette *themePalette = QS60StylePrivate::themePalette();
1316         if (themePalette)
1317             opt.palette = *themePalette;
1318
1319         // For now, always generate new icon based on "selected". In the future possibly, expand
1320         // this to consist other possibilities as well.
1321         result = QApplication::style()->generatedIconPixmap(QIcon::Selected, result, &opt);
1322         return result;
1323     }
1324 }
1325
1326 QPixmap QS60StylePrivate::part(QS60StyleEnums::SkinParts part,
1327     const QSize &size, QPainter *painter, SkinElementFlags flags)
1328 {
1329     QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
1330
1331     QPixmap result = (flags & SF_ColorSkinned)?
1332           QS60StyleModeSpecifics::colorSkinnedGraphics(part, size, painter, flags)
1333         : QS60StyleModeSpecifics::skinnedGraphics(part, size, flags);
1334
1335     lock.relock();
1336
1337     if (flags & SF_StateDisabled && !QS60StyleModeSpecifics::disabledPartGraphic(part)) {
1338         QStyleOption opt;
1339         QPalette *themePalette = QS60StylePrivate::themePalette();
1340         if (themePalette)
1341             opt.palette = *themePalette;
1342         result = QApplication::style()->generatedIconPixmap(QIcon::Disabled, result, &opt);
1343     }
1344
1345     if (!result)
1346         result = QS60StyleModeSpecifics::generateMissingThemeGraphic(part, size, flags);
1347
1348     return result;
1349 }
1350
1351 QPixmap QS60StylePrivate::frame(SkinFrameElements frame, const QSize &size, SkinElementFlags flags)
1352 {
1353     QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
1354     QPixmap result = QS60StyleModeSpecifics::skinnedGraphics(frame, size, flags);
1355     lock.relock();
1356
1357     if (flags & SF_StateDisabled && !QS60StyleModeSpecifics::disabledFrameGraphic(frame)) {
1358         QStyleOption opt;
1359         QPalette *themePalette = QS60StylePrivate::themePalette();
1360         if (themePalette)
1361             opt.palette = *themePalette;
1362         result = QApplication::style()->generatedIconPixmap(QIcon::Disabled, result, &opt);
1363     }
1364     return result;
1365 }
1366
1367 QPixmap QS60StylePrivate::backgroundTexture(bool skipCreation)
1368 {
1369     bool createNewBackground = false;
1370     TRect applicationRect = (static_cast<CEikAppUi*>(S60->appUi())->ApplicationRect());
1371     if (!m_background) {
1372         createNewBackground = true;
1373     } else {
1374         //if background brush does not match screensize, re-create it
1375         if (m_background->width() != applicationRect.Width() ||
1376             m_background->height() != applicationRect.Height()) {
1377             delete m_background;
1378             m_background = 0;
1379             createNewBackground = true;
1380         }
1381     }
1382
1383     if (createNewBackground && !skipCreation) {
1384         QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen,
1385             QSize(applicationRect.Width(), applicationRect.Height()), 0, SkinElementFlags());
1386         m_background = new QPixmap(background);
1387
1388         // Notify all widgets that palette is updated with the actual background texture.
1389         QPalette pal = QApplication::palette();
1390         pal.setBrush(QPalette::Window, *m_background);
1391
1392         //Application palette hash is automatically cleared when QApplication::setPalette is called.
1393         //To avoid losing palette hash data, back it up before calling the setPalette() API and
1394         //restore it afterwards.
1395         typedef QHash<QByteArray, QPalette> PaletteHash;
1396         PaletteHash hash;
1397         if (qt_app_palettes_hash() || !qt_app_palettes_hash()->isEmpty())
1398             hash = *qt_app_palettes_hash();
1399         QApplication::setPalette(pal);
1400         if (hash.isEmpty()) {
1401             //set default theme palette hash
1402             setThemePaletteHash(&pal);
1403         } else {
1404             for (int i = 0; i < hash.count() - 1; i++) {
1405                 QByteArray widgetClassName = hash.keys().at(i);
1406                 QApplication::setPalette(hash.value(widgetClassName), widgetClassName);
1407             }
1408         }
1409         storeThemePalette(&pal);
1410         foreach (QWidget *widget, QApplication::allWidgets()) {
1411             setThemePalette(widget);
1412             widget->ensurePolished();
1413         }
1414     }
1415     if (!m_background)
1416         return QPixmap();
1417     return *m_background;
1418 }
1419
1420 QSize QS60StylePrivate::screenSize()
1421 {
1422     return QSize(S60->screenWidthInPixels, S60->screenHeightInPixels);
1423 }
1424
1425 QS60Style::QS60Style()
1426     : QCommonStyle(*new QS60StylePrivate)
1427 {
1428 }
1429
1430 #ifdef Q_WS_S60
1431 void QS60StylePrivate::handleDynamicLayoutVariantSwitch()
1432 {
1433     clearCaches(QS60StylePrivate::CC_LayoutChange);
1434     setBackgroundTexture(qApp);
1435     setActiveLayout();
1436     foreach (QWidget *widget, QApplication::allWidgets())
1437         widget->ensurePolished();
1438 }
1439
1440 void QS60StylePrivate::handleSkinChange()
1441 {
1442     clearCaches(QS60StylePrivate::CC_ThemeChange);
1443     setThemePalette(qApp);
1444     foreach (QWidget *topLevelWidget, QApplication::allWidgets()){
1445         QEvent e(QEvent::StyleChange);
1446         QApplication::sendEvent(topLevelWidget, &e);
1447         setThemePalette(topLevelWidget);
1448         topLevelWidget->ensurePolished();
1449     }
1450 #ifndef QT_NO_PROGRESSBAR
1451     //re-start animation timer
1452     stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); //todo: once we have more animations, we could say "stop all running ones"
1453     startAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); //and "re-start all previously running ones"
1454 #endif
1455 }
1456
1457 int QS60StylePrivate::currentAnimationFrame(QS60StyleEnums::SkinParts part)
1458 {
1459     QS60StyleAnimation *animation = animationDefinition(part);
1460     // todo: looping could be done in QS60Style::timerEvent
1461     if (animation->frameCount() == animation->currentFrame())
1462         animation->setCurrentFrame(0);
1463     return animation->currentFrame();
1464 }
1465
1466 QS60StyleAnimation* QS60StylePrivate::animationDefinition(QS60StyleEnums::SkinParts part)
1467 {
1468     int i = 0;
1469     const int animationsCount = m_animations()->isEmpty() ? 0 : m_animations()->count();
1470     for(; i < animationsCount; i++) {
1471         if (part == m_animations()->at(i)->animationId())
1472             break;
1473     }
1474     return m_animations()->at(i);
1475 }
1476
1477 void QS60StylePrivate::startAnimation(QS60StyleEnums::SkinParts animationPart)
1478 {
1479     Q_Q(QS60Style);
1480
1481     //Query animation data from theme and store values to local struct.
1482     QVariant themeAnimationDataVariant = QS60StyleModeSpecifics::themeDefinition(
1483         QS60StyleEnums::TD_AnimationData, animationPart);
1484     QList<QVariant> themeAnimationData = themeAnimationDataVariant.toList();
1485
1486     QS60StyleAnimation *animation = QS60StylePrivate::animationDefinition(animationPart);
1487     if (animation) {
1488         if (themeAnimationData.at(QS60StyleEnums::AD_Interval).toInt() != 0)
1489             animation->setInterval(themeAnimationData.at(QS60StyleEnums::AD_Interval).toInt());
1490
1491         if (themeAnimationData.at(QS60StyleEnums::AD_NumberOfFrames).toInt() != 0)
1492             animation->setFrameCount(themeAnimationData.at(QS60StyleEnums::AD_NumberOfFrames).toInt());
1493
1494         //todo: playmode is ignored for now, since it seems to return invalid data on some themes
1495         //lets use the table values for play mode
1496
1497         animation->setCurrentFrame(0); //always initialize
1498         const int timerId = q->startTimer(animation->interval());
1499         animation->setTimerId(timerId);
1500     }
1501 }
1502
1503 void QS60StylePrivate::stopAnimation(QS60StyleEnums::SkinParts animationPart)
1504 {
1505     Q_Q(QS60Style);
1506
1507     QS60StyleAnimation *animation = QS60StylePrivate::animationDefinition(animationPart);
1508     if (animation) {
1509         animation->setCurrentFrame(0);
1510         if (animation->timerId() != 0) {
1511             q->killTimer(animation->timerId());
1512             animation->setTimerId(0);
1513         }
1514         animation->resetToDefaults();
1515     }
1516 }
1517
1518 QVariant QS60StyleModeSpecifics::themeDefinition(
1519     QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part)
1520 {
1521     MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
1522
1523     Q_ASSERT(skinInstance);
1524
1525     switch(definition) {
1526     //Animation definitions
1527     case QS60StyleEnums::TD_AnimationData:
1528         {
1529             CAknsBmpAnimItemData *animationData = 0;
1530             TAknsItemID animationSkinId = partSpecificThemeId(part);
1531             QList<QVariant> list;
1532
1533             TRAPD( error, QT_TRYCATCH_LEAVING(
1534                     animationData = static_cast<CAknsBmpAnimItemData*>(skinInstance->CreateUncachedItemDataL(
1535                             animationSkinId, EAknsITBmpAnim))));
1536             if (error)
1537                 return list;
1538
1539             if (animationData) {
1540                 list.append((int)animationData->FrameInterval());
1541                 list.append((int)animationData->NumberOfImages());
1542
1543                 QS60StyleEnums::AnimationMode playMode;
1544                 switch(animationData->PlayMode()) {
1545                     case CBitmapAnimClientData::ECycle:
1546                         playMode = QS60StyleEnums::AM_Looping;
1547                         break;
1548                     case CBitmapAnimClientData::EBounce:
1549                         playMode = QS60StyleEnums::AM_Bounce;
1550                         break;
1551                     default:
1552                         playMode = QS60StyleEnums::AM_PlayOnce;
1553                         break;
1554                 }
1555                 list.append(QVariant((int)playMode));
1556                 delete animationData;
1557             } else {
1558                 list.append(0);
1559                 list.append(0);
1560             }
1561             return list;
1562         }
1563         break;
1564     default:
1565         break;
1566     }
1567     return QVariant();
1568 }
1569
1570 #endif // Q_WS_S60
1571
1572 QT_END_NAMESPACE
1573
1574 #endif // QT_NO_STYLE_S60 || QT_PLUGIN