source: trunk/src/gui/styles/qs60style.cpp@ 570

Last change on this file since 570 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

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