diff options
Diffstat (limited to 'src/gui/styles')
24 files changed, 5384 insertions, 20 deletions
diff --git a/src/gui/styles/qcleanlooksstyle.h b/src/gui/styles/qcleanlooksstyle.h index ebfb707f7f..834f238aa8 100644 --- a/src/gui/styles/qcleanlooksstyle.h +++ b/src/gui/styles/qcleanlooksstyle.h @@ -56,7 +56,7 @@ class QCleanlooksStylePrivate; class Q_GUI_EXPORT QCleanlooksStyle : public QWindowsStyle { Q_OBJECT - Q_DECLARE_PRIVATE(QCleanlooksStyle) + Q_DECLARE_SCOPED_PRIVATE(QCleanlooksStyle) public: QCleanlooksStyle(); diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index ba28e753dd..bfcb7c9815 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -3216,8 +3216,10 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt, if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) { if (!d->isViewItemCached(*vopt)) { d->viewItemLayout(vopt, &d->checkRect, &d->decorationRect, &d->displayRect, false); - if (d->cachedOption) + if (d->cachedOption) { delete d->cachedOption; + d->cachedOption = 0; + } d->cachedOption = new QStyleOptionViewItemV4(*vopt); } if (sr == SE_ViewItemCheckIndicator) diff --git a/src/gui/styles/qcommonstyle.h b/src/gui/styles/qcommonstyle.h index ce54a9644f..1f64fb34d0 100644 --- a/src/gui/styles/qcommonstyle.h +++ b/src/gui/styles/qcommonstyle.h @@ -98,7 +98,7 @@ protected: QCommonStyle(QCommonStylePrivate &dd); private: - Q_DECLARE_PRIVATE(QCommonStyle) + Q_DECLARE_SCOPED_PRIVATE(QCommonStyle) Q_DISABLE_COPY(QCommonStyle) }; diff --git a/src/gui/styles/qgtkstyle.h b/src/gui/styles/qgtkstyle.h index e12f175f10..3feeafa836 100644 --- a/src/gui/styles/qgtkstyle.h +++ b/src/gui/styles/qgtkstyle.h @@ -60,7 +60,7 @@ class QGtkStylePrivate; class Q_GUI_EXPORT QGtkStyle : public QCleanlooksStyle { Q_OBJECT - Q_DECLARE_PRIVATE(QGtkStyle) + Q_DECLARE_SCOPED_PRIVATE(QGtkStyle) public: QGtkStyle(); diff --git a/src/gui/styles/qmotifstyle.h b/src/gui/styles/qmotifstyle.h index e848eb4b71..356f420845 100644 --- a/src/gui/styles/qmotifstyle.h +++ b/src/gui/styles/qmotifstyle.h @@ -113,7 +113,7 @@ protected: bool eventFilter(QObject *o, QEvent *e); private: - Q_DECLARE_PRIVATE(QMotifStyle) + Q_DECLARE_SCOPED_PRIVATE(QMotifStyle) Q_DISABLE_COPY(QMotifStyle) bool highlightCols; diff --git a/src/gui/styles/qplastiquestyle.h b/src/gui/styles/qplastiquestyle.h index ac3da4154e..74560fc92c 100644 --- a/src/gui/styles/qplastiquestyle.h +++ b/src/gui/styles/qplastiquestyle.h @@ -56,7 +56,7 @@ class QPlastiqueStylePrivate; class Q_GUI_EXPORT QPlastiqueStyle : public QWindowsStyle { Q_OBJECT - Q_DECLARE_PRIVATE(QPlastiqueStyle) + Q_DECLARE_SCOPED_PRIVATE(QPlastiqueStyle) public: QPlastiqueStyle(); ~QPlastiqueStyle(); diff --git a/src/gui/styles/qproxystyle.h b/src/gui/styles/qproxystyle.h index c9edaff449..33f252a20a 100644 --- a/src/gui/styles/qproxystyle.h +++ b/src/gui/styles/qproxystyle.h @@ -102,7 +102,7 @@ protected Q_SLOTS: Qt::Orientation orientation, const QStyleOption *option = 0, const QWidget *widget = 0) const; private: Q_DISABLE_COPY(QProxyStyle) - Q_DECLARE_PRIVATE(QProxyStyle) + Q_DECLARE_SCOPED_PRIVATE(QProxyStyle) }; #endif // QT_NO_STYLE_PROXY diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp new file mode 100644 index 0000000000..01a469c4f1 --- /dev/null +++ b/src/gui/styles/qs60style.cpp @@ -0,0 +1,2878 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qs60style_p.h" + +#include "qapplication.h" +#include "qpainter.h" +#include "qstyleoption.h" +#include "qevent.h" +#include "qpixmapcache.h" + +#include "qcalendarwidget.h" +#include "qdial.h" +#include "qdialog.h" +#include "qgroupbox.h" +#include "qheaderview.h" +#include "qlist.h" +#include "qlistwidget.h" +#include "qlistview.h" +#include "qmenu.h" +#include "qmenubar.h" +#include "qpushbutton.h" +#include "qscrollarea.h" +#include "qscrollbar.h" +#include "qtabbar.h" +#include "qtablewidget.h" +#include "qtableview.h" +#include "qtextedit.h" +#include "qtoolbar.h" +#include "qtoolbutton.h" +#include "qtreeview.h" + +#include "private/qtoolbarextension_p.h" +#include "private/qcombobox_p.h" +#include "private/qwidget_p.h" +#include "private/qapplication_p.h" + +#if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN) + +QT_BEGIN_NAMESPACE + +// from text/qfont.cpp +extern Q_GUI_EXPORT int qt_defaultDpiY(); + +const QS60StylePrivate::SkinElementFlags QS60StylePrivate::KDefaultSkinElementFlags = + SkinElementFlags(SF_PointNorth | SF_StateEnabled); + +static const QByteArray propertyKeyLayouts = "layouts"; +static const QByteArray propertyKeyCurrentlayout = "currentlayout"; + +const layoutHeader QS60StylePrivate::m_layoutHeaders[] = { +// *** generated layout data *** +{240,320,1,14,true,"QVGA Landscape Mirrored"}, +{240,320,1,14,false,"QVGA Landscape"}, +{320,240,1,14,true,"QVGA Portrait Mirrored"}, +{320,240,1,14,false,"QVGA Portrait"}, +{360,640,1,14,true,"NHD Landscape Mirrored"}, +{360,640,1,14,false,"NHD Landscape"}, +{640,360,1,14,true,"NHD Portrait Mirrored"}, +{640,360,1,14,false,"NHD Portrait"}, +{352,800,1,12,true,"E90 Landscape Mirrored"}, +{352,800,1,12,false,"E90 Landscape"} +// *** End of generated data *** +}; +const int QS60StylePrivate::m_numberOfLayouts = + (int)sizeof(QS60StylePrivate::m_layoutHeaders)/sizeof(QS60StylePrivate::m_layoutHeaders[0]); + +const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = { +// *** generated pixel metrics *** +{5,0,-909,0,0,1,0,0,-1,8,15,22,15,15,7,198,-909,-909,-909,19,15,2,0,0,21,-909,21,-909,4,4,1,-909,-909,0,2,0,0,13,23,17,17,21,21,2,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,51,27,51,4,4,5,10,15,-909,5,58,12,5,0,7,4,4,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1}, +{5,0,-909,0,0,1,0,0,-1,8,15,22,15,15,7,198,-909,-909,-909,19,15,2,0,0,21,-909,21,-909,4,4,1,-909,-909,0,2,0,0,13,23,17,17,21,21,2,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,51,27,51,4,4,5,10,15,-909,5,58,12,5,0,4,4,7,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1}, +{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,-909,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,7,4,4,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1}, +{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,-909,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,1,-909,-909,-909,-909,4,4,3,1}, +{7,0,-909,0,0,2,0,0,-1,20,53,28,19,19,9,258,-909,-909,-909,29,19,26,0,0,32,-909,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,8,5,5,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1}, +{7,0,-909,0,0,2,0,0,-1,20,53,28,19,19,9,258,-909,-909,-909,29,19,26,0,0,32,-909,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1}, +{7,0,-909,0,0,2,0,0,-1,20,52,28,19,19,9,258,-909,-909,-909,29,19,6,0,0,32,-909,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,98,35,98,5,5,6,8,19,-909,7,74,22,7,0,8,5,5,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1}, +{7,0,-909,0,0,2,0,0,-1,20,52,28,19,19,9,258,-909,-909,-909,29,19,6,0,0,32,-909,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,98,35,98,5,5,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,2,-909,-909,-909,-909,7,7,3,1}, +{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,-909,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,5,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,8,6,5,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1}, +{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,-909,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1} +// *** End of generated data *** +}; + +const short *QS60StylePrivate::m_pmPointer = QS60StylePrivate::data[0]; + +// theme background texture +QPixmap *QS60StylePrivate::m_background = 0; + +// theme palette +QPalette *QS60StylePrivate::m_themePalette = 0; + +const struct QS60StylePrivate::frameElementCenter QS60StylePrivate::m_frameElementsData[] = { + {SE_ButtonNormal, QS60StyleEnums::SP_QsnFrButtonTbCenter}, + {SE_ButtonPressed, QS60StyleEnums::SP_QsnFrButtonTbCenterPressed}, + {SE_FrameLineEdit, QS60StyleEnums::SP_QsnFrInputCenter}, + {SE_ListHighlight, QS60StyleEnums::SP_QsnFrListCenter}, + {SE_OptionsMenu, QS60StyleEnums::SP_QsnFrPopupCenter}, + {SE_SettingsList, QS60StyleEnums::SP_QsnFrSetOptCenter}, + {SE_TableItem, QS60StyleEnums::SP_QsnFrCaleCenter}, + {SE_TableHeaderItem, QS60StyleEnums::SP_QsnFrCaleHeadingCenter}, + {SE_ToolTip, QS60StyleEnums::SP_QsnFrPopupPreviewCenter}, + {SE_ToolBar, QS60StyleEnums::SP_QsnFrPopupSubCenter}, + {SE_ToolBarButton, QS60StyleEnums::SP_QsnFrSctrlButtonCenter}, + {SE_ToolBarButtonPressed, QS60StyleEnums::SP_QsnFrSctrlButtonCenterPressed}, + {SE_PanelBackground, QS60StyleEnums::SP_QsnFrSetOptCenter}, + {SE_ButtonInactive, QS60StyleEnums::SP_QsnFrButtonCenterInactive}, + {SE_Editor, QS60StyleEnums::SP_QsnFrNotepadCenter}, +}; + +static const int frameElementsCount = + int(sizeof(QS60StylePrivate::m_frameElementsData)/sizeof(QS60StylePrivate::m_frameElementsData[0])); + +const int KNotFound = -909; +const double KTabFontMul = 0.72; + +QS60StylePrivate::~QS60StylePrivate() +{ + clearCaches(); //deletes also background image + deleteThemePalette(); +} + +void QS60StylePrivate::drawSkinElement(SkinElements element, QPainter *painter, + const QRect &rect, SkinElementFlags flags) +{ + switch (element) { + case SE_ButtonNormal: + drawFrame(SF_ButtonNormal, painter, rect, flags | SF_PointNorth); + break; + case SE_ButtonPressed: + drawFrame(SF_ButtonPressed, painter, rect, flags | SF_PointNorth); + break; + case SE_FrameLineEdit: + drawFrame(SF_FrameLineEdit, painter, rect, flags | SF_PointNorth); + break; + case SE_ProgressBarGrooveHorizontal: + drawRow(QS60StyleEnums::SP_QgnGrafBarFrameSideL, QS60StyleEnums::SP_QgnGrafBarFrameCenter, + QS60StyleEnums::SP_QgnGrafBarFrameSideR, Qt::Horizontal, painter, rect, flags | SF_PointNorth); + break; + case SE_ProgressBarGrooveVertical: + drawRow(QS60StyleEnums::SP_QgnGrafBarFrameSideL, QS60StyleEnums::SP_QgnGrafBarFrameCenter, + QS60StyleEnums::SP_QgnGrafBarFrameSideR, Qt::Vertical, painter, rect, flags | SF_PointEast); + break; + case SE_ProgressBarIndicatorHorizontal: + drawPart(QS60StyleEnums::SP_QgnGrafBarProgress, painter, rect, flags | SF_PointNorth); + break; + case SE_ProgressBarIndicatorVertical: + drawPart(QS60StyleEnums::SP_QgnGrafBarProgress, painter, rect, flags | SF_PointWest); + break; + case SE_ScrollBarGrooveHorizontal: + drawRow(QS60StyleEnums::SP_QsnCpScrollBgBottom, QS60StyleEnums::SP_QsnCpScrollBgMiddle, + QS60StyleEnums::SP_QsnCpScrollBgTop, Qt::Horizontal, painter, rect, flags | SF_PointEast); + break; + case SE_ScrollBarGrooveVertical: + drawRow(QS60StyleEnums::SP_QsnCpScrollBgTop, QS60StyleEnums::SP_QsnCpScrollBgMiddle, + QS60StyleEnums::SP_QsnCpScrollBgBottom, Qt::Vertical, painter, rect, flags | SF_PointNorth); + break; + case SE_ScrollBarHandleHorizontal: + drawRow(QS60StyleEnums::SP_QsnCpScrollHandleBottom, QS60StyleEnums::SP_QsnCpScrollHandleMiddle, + QS60StyleEnums::SP_QsnCpScrollHandleTop, Qt::Horizontal, painter, rect, flags | SF_PointEast); + break; + case SE_ScrollBarHandleVertical: + drawRow(QS60StyleEnums::SP_QsnCpScrollHandleTop, QS60StyleEnums::SP_QsnCpScrollHandleMiddle, + QS60StyleEnums::SP_QsnCpScrollHandleBottom, Qt::Vertical, painter, rect, flags | SF_PointNorth); + break; + case SE_SliderHandleHorizontal: + drawPart(QS60StyleEnums::SP_QgnIndiSliderEdit, painter, rect, flags | SF_PointNorth); + break; + case SE_SliderHandleVertical: + drawPart(QS60StyleEnums::SP_QgnIndiSliderEdit, painter, rect, flags | SF_PointEast); + break; + case SE_TabBarTabEastActive: + drawRow(QS60StyleEnums::SP_QgnGrafTabActiveL, QS60StyleEnums::SP_QgnGrafTabActiveM, + QS60StyleEnums::SP_QgnGrafTabActiveR, Qt::Vertical, painter, rect, flags | SF_PointEast); + break; + case SE_TabBarTabEastInactive: + drawRow(QS60StyleEnums::SP_QgnGrafTabPassiveL, QS60StyleEnums::SP_QgnGrafTabPassiveM, + QS60StyleEnums::SP_QgnGrafTabPassiveR, Qt::Vertical, painter, rect, flags | SF_PointEast); + break; + case SE_TabBarTabNorthActive: + drawRow(QS60StyleEnums::SP_QgnGrafTabActiveL, QS60StyleEnums::SP_QgnGrafTabActiveM, + QS60StyleEnums::SP_QgnGrafTabActiveR, Qt::Horizontal, painter, rect, flags | SF_PointNorth); + break; + case SE_TabBarTabNorthInactive: + drawRow(QS60StyleEnums::SP_QgnGrafTabPassiveL, QS60StyleEnums::SP_QgnGrafTabPassiveM, + QS60StyleEnums::SP_QgnGrafTabPassiveR, Qt::Horizontal, painter, rect, flags | SF_PointNorth); + break; + case SE_TabBarTabSouthActive: + drawRow(QS60StyleEnums::SP_QgnGrafTabActiveR, QS60StyleEnums::SP_QgnGrafTabActiveM, + QS60StyleEnums::SP_QgnGrafTabActiveL, Qt::Horizontal, painter, rect, flags | SF_PointSouth); + break; + case SE_TabBarTabSouthInactive: + drawRow(QS60StyleEnums::SP_QgnGrafTabPassiveR, QS60StyleEnums::SP_QgnGrafTabPassiveM, + QS60StyleEnums::SP_QgnGrafTabPassiveL, Qt::Horizontal, painter, rect, flags | SF_PointSouth); + break; + case SE_TabBarTabWestActive: + drawRow(QS60StyleEnums::SP_QgnGrafTabActiveR, QS60StyleEnums::SP_QgnGrafTabActiveM, + QS60StyleEnums::SP_QgnGrafTabActiveL, Qt::Vertical, painter, rect, flags | SF_PointWest); + break; + case SE_TabBarTabWestInactive: + drawRow(QS60StyleEnums::SP_QgnGrafTabPassiveR, QS60StyleEnums::SP_QgnGrafTabPassiveM, + QS60StyleEnums::SP_QgnGrafTabPassiveL, Qt::Vertical, painter, rect, flags | SF_PointWest); + break; + case SE_ListHighlight: + drawFrame(SF_ListHighlight, painter, rect, flags | SF_PointNorth); + break; + case SE_OptionsMenu: + drawFrame(SF_OptionsMenu, painter, rect, flags | SF_PointNorth); + break; + case SE_SettingsList: + drawFrame(SF_SettingsList, painter, rect, flags | SF_PointNorth); + break; + case SE_TableItem: + drawFrame(SF_TableItem, painter, rect, flags | SF_PointNorth); + break; + case SE_TableHeaderItem: + drawFrame(SF_TableHeaderItem, painter, rect, flags | SF_PointNorth); + break; + case SE_ToolTip: + drawFrame(SF_ToolTip, painter, rect, flags | SF_PointNorth); + break; + case SE_ToolBar: + drawFrame(SF_ToolBar, painter, rect, flags | SF_PointNorth); + break; + case SE_ToolBarButton: + drawFrame(SF_ToolBarButton, painter, rect, flags | SF_PointNorth); + break; + case SE_ToolBarButtonPressed: + drawFrame(SF_ToolBarButtonPressed, painter, rect, flags | SF_PointNorth); + break; + case SE_PanelBackground: + drawFrame(SF_PanelBackground, painter, rect, flags | SF_PointNorth); + break; + case SE_ScrollBarHandlePressedHorizontal: + drawRow(QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed, QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed, + QS60StyleEnums::SP_QsnCpScrollHandleTopPressed, Qt::Horizontal, painter, rect, flags | SF_PointEast); + break; + case SE_ScrollBarHandlePressedVertical: + drawRow(QS60StyleEnums::SP_QsnCpScrollHandleTopPressed, QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed, + QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed, Qt::Vertical, painter, rect, flags | SF_PointNorth); + break; + case SE_ButtonInactive: + drawFrame(SF_ButtonInactive, painter, rect, flags | SF_PointNorth); + break; + case SE_Editor: + drawFrame(SF_Editor, painter, rect, flags | SF_PointNorth); + break; + default: + break; + } +} + +void QS60StylePrivate::drawSkinPart(QS60StyleEnums::SkinParts part, + QPainter *painter, const QRect &rect, SkinElementFlags flags) +{ + drawPart(part, painter, rect, flags); +} + +short QS60StylePrivate::pixelMetric(int metric) +{ + Q_ASSERT(metric < MAX_PIXELMETRICS); + const short returnValue = m_pmPointer[metric]; + return returnValue; +} + +void QS60StylePrivate::setStyleProperty(const char *name, const QVariant &value) +{ + if (name == propertyKeyCurrentlayout) { + static const QStringList layouts = styleProperty(propertyKeyLayouts).toStringList(); + const QString layout = value.toString(); + Q_ASSERT(layouts.contains(layout)); + const int layoutIndex = layouts.indexOf(layout); + setCurrentLayout(layoutIndex); + QApplication::setLayoutDirection(m_layoutHeaders[layoutIndex].mirroring ? Qt::RightToLeft : Qt::LeftToRight); + clearCaches(); + refreshUI(); + } +} + +QVariant QS60StylePrivate::styleProperty(const char *name) const +{ + if (name == propertyKeyLayouts) { + static QStringList layouts; + if (layouts.isEmpty()) + for (int i = 0; i < m_numberOfLayouts; i++) + layouts.append(QLatin1String(m_layoutHeaders[i].layoutName)); + return layouts; + } + return QVariant(); +} + +QColor QS60StylePrivate::stateColor(const QColor &color, const QStyleOption *option) +{ + QColor retColor (color); + if (option && !(option->state & QStyle::State_Enabled)) { + QColor hsvColor = retColor.toHsv(); + int colorSat = hsvColor.saturation(); + int colorVal = hsvColor.value(); + colorSat = (colorSat!=0) ? (colorSat>>1) : 128; + colorVal = (colorVal!=0) ? (colorVal>>1) : 128; + hsvColor.setHsv(hsvColor.hue(), colorSat, colorVal); + retColor = hsvColor.toRgb(); + } + return retColor; +} + +QColor QS60StylePrivate::lighterColor(const QColor &baseColor) +{ + QColor result(baseColor); + bool modifyColor = false; + if (result.saturation() == 0) { + result.setHsv(result.hue(), 128, result.value()); + modifyColor = true; + } + if (result.value() == 0) { + result.setHsv(result.hue(), result.saturation(), 128); + modifyColor = true; + } + if (modifyColor) + result = result.lighter(175); + else + result = result.lighter(225); + return result; +} + +bool QS60StylePrivate::drawsOwnThemeBackground(const QWidget *widget) +{ + return qobject_cast<const QDialog *> (widget); +} + +QFont QS60StylePrivate::s60Font( + QS60StyleEnums::FontCategories fontCategory, int pointSize) const +{ + QFont result; + int actualPointSize = pointSize; + if (actualPointSize <= 0) { + const QFont appFont = QApplication::font(); + actualPointSize = appFont.pointSize(); + if (actualPointSize <= 0) + actualPointSize = appFont.pixelSize() * 72 / qt_defaultDpiY(); + } + Q_ASSERT(actualPointSize > 0); + const QPair<QS60StyleEnums::FontCategories, int> key(fontCategory, actualPointSize); + if (!m_mappedFontsCache.contains(key)) { + result = s60Font_specific(fontCategory, actualPointSize); + m_mappedFontsCache.insert(key, result); + } else { + result = m_mappedFontsCache.value(key); + if (result.pointSize() != actualPointSize) + result.setPointSize(actualPointSize); + } + return result; +} + +void QS60StylePrivate::clearCaches(CacheClearReason reason) +{ + switch(reason){ + case CC_LayoutChange: + // when layout changes, the colors remain in cache, but graphics and fonts can change + m_mappedFontsCache.clear(); + deleteBackground(); + QPixmapCache::clear(); + break; + case CC_ThemeChange: + m_colorCache.clear(); + QPixmapCache::clear(); + deleteBackground(); + break; + case CC_UndefinedChange: + default: + m_colorCache.clear(); + m_mappedFontsCache.clear(); + QPixmapCache::clear(); + deleteBackground(); + break; + } +} + +// Since S60Style has 'button' and 'tooltip' as a graphic, we don't have any native color which to use +// for QPalette::Button and QPalette::ToolTipBase. Therefore S60Style needs to guesstimate +// palette colors by calculating average rgb values for button pixels. +// Returns Qt::black if there is an issue with the graphics (image is NULL, or no bits() found). +QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const +{ + const bool cachedColorExists = m_colorCache.contains(frame); + if (!cachedColorExists) { + const int frameCornerWidth = pixelMetric(PM_Custom_FrameCornerWidth); + const int frameCornerHeight = pixelMetric(PM_Custom_FrameCornerHeight); + Q_ASSERT(2*frameCornerWidth<32); + Q_ASSERT(2*frameCornerHeight<32); + + const QImage frameImage = QS60StylePrivate::frame(frame, QSize(32,32)).toImage(); + if (frameImage.isNull()) + return Qt::black; + + const QRgb *pixelRgb = (const QRgb*)frameImage.bits(); + const int pixels = frameImage.numBytes()/sizeof(QRgb); + const int bytesPerLine = frameImage.bytesPerLine(); + Q_ASSERT(bytesPerLine); + + int estimatedRed = 0; + int estimatedGreen = 0; + int estimatedBlue = 0; + + int skips = 0; + int estimations = 0; + + const int topBorderLastPixel = frameCornerHeight*frameImage.width()-1; + const int bottomBorderFirstPixel = frameImage.width()*frameImage.height()-frameCornerHeight*frameImage.width()-1; + const int rightBorderFirstPixel = frameImage.width()-frameCornerWidth; + const int leftBorderLastPixel = frameCornerWidth; + + while ((skips + estimations) < pixels) { + if ((skips+estimations) > topBorderLastPixel && + (skips+estimations) < bottomBorderFirstPixel) { + for (int rowIndex = 0; rowIndex < frameImage.width(); rowIndex++) { + if (rowIndex > leftBorderLastPixel && + rowIndex < rightBorderFirstPixel) { + estimatedRed += qRed(*pixelRgb); + estimatedGreen += qGreen(*pixelRgb); + estimatedBlue += qBlue(*pixelRgb); + } + pixelRgb++; + estimations++; + } + } else { + pixelRgb++; + skips++; + } + } + QColor frameColor(estimatedRed/estimations, estimatedGreen/estimations, estimatedBlue/estimations); + m_colorCache.insert(frame, frameColor); + return !estimations ? Qt::black : frameColor; + } else { + return m_colorCache.value(frame); + } + +} + +void QS60StylePrivate::setThemePalette(QApplication *app) const +{ + Q_UNUSED(app) + QPalette widgetPalette = QPalette(Qt::white); + setThemePalette(&widgetPalette); + QApplication::setPalette(widgetPalette); //calling QApplication::setPalette clears palette hash + setThemePaletteHash(&widgetPalette); + storeThemePalette(&widgetPalette); +} + +void QS60StylePrivate::setThemePalette(QStyleOption *option) const +{ + setThemePalette(&option->palette); +} + +QPalette* QS60StylePrivate::themePalette() +{ + return m_themePalette; +} + +void QS60StylePrivate::setBackgroundTexture(QApplication *app) const +{ + Q_UNUSED(app) + QPalette applicationPalette = QApplication::palette(); + applicationPalette.setBrush(QPalette::Window, backgroundTexture()); + QApplication::setPalette(applicationPalette); +} + +void QS60StylePrivate::deleteBackground() +{ + if (m_background) { + delete m_background; + m_background = 0; + } +} + +int QS60StylePrivate::focusRectPenWidth() +{ + return pixelMetric(QS60Style::PM_DefaultFrameWidth); +} + +void QS60StylePrivate::setCurrentLayout(int index) +{ + m_pmPointer = data[index]; +} + +void QS60StylePrivate::drawPart(QS60StyleEnums::SkinParts skinPart, + QPainter *painter, const QRect &rect, SkinElementFlags flags) +{ + static const bool doCache = +#if defined(Q_WS_S60) + // Freezes on 3.1. Anyways, caching is only really needed on touch UI + !(QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2); +#else + true; +#endif + const QPixmap skinPartPixMap((doCache ? cachedPart : part)(skinPart, rect.size(), flags)); + if (!skinPartPixMap.isNull()) + painter->drawPixmap(rect.topLeft(), skinPartPixMap); +} + +void QS60StylePrivate::drawFrame(SkinFrameElements frameElement, QPainter *painter, const QRect &rect, SkinElementFlags flags) +{ + static const bool doCache = +#if defined(Q_WS_S60) + // Freezes on 3.1. Anyways, caching is only really needed on touch UI + !(QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2); +#else + true; +#endif + const QPixmap frameElementPixMap((doCache ? cachedFrame : frame)(frameElement, rect.size(), flags)); + if (!frameElementPixMap.isNull()) + painter->drawPixmap(rect.topLeft(), frameElementPixMap); +} + +void QS60StylePrivate::drawRow(QS60StyleEnums::SkinParts start, + QS60StyleEnums::SkinParts middle, QS60StyleEnums::SkinParts end, + Qt::Orientation orientation, QPainter *painter, const QRect &rect, + SkinElementFlags flags) +{ + QSize startEndSize(partSize(start, flags)); + startEndSize.scale(rect.size(), Qt::KeepAspectRatio); + + QRect startRect = QRect(rect.topLeft(), startEndSize); + QRect middleRect = rect; + QRect endRect; + + if (orientation == Qt::Horizontal) { + startRect.setWidth(qMin((rect.width() >> 1) - 1, startRect.width())); + endRect = startRect.translated(rect.width() - startRect.width(), 0); + middleRect.adjust(startRect.width(), 0, -startRect.width(), 0); + if (startRect.bottomRight().x() > endRect.topLeft().x()) { + const int overlap = (startRect.bottomRight().x() - endRect.topLeft().x())>>1; + startRect.setWidth(startRect.width()-overlap); + endRect.adjust(overlap,0,0,0); + } + } else { + startRect.setHeight(qMin((rect.height() >> 1) - 1, startRect.height())); + endRect = startRect.translated(0, rect.height() - startRect.height()); + middleRect.adjust(0, startRect.height(), 0, -startRect.height()); + if (startRect.topRight().y() > endRect.bottomLeft().y()) { + const int overlap = (startRect.topRight().y() - endRect.bottomLeft().y())>>1; + startRect.setHeight(startRect.height()-overlap); + endRect.adjust(0,overlap,0,0); + } + } + +#if 0 + painter->save(); + painter->setOpacity(.3); + painter->fillRect(startRect, Qt::red); + painter->fillRect(middleRect, Qt::green); + painter->fillRect(endRect, Qt::blue); + painter->restore(); +#else + drawPart(start, painter, startRect, flags); + if (middleRect.isValid()) + drawPart(middle, painter, middleRect, flags); + drawPart(end, painter, endRect, flags); +#endif +} + +QPixmap QS60StylePrivate::cachedPart(QS60StyleEnums::SkinParts part, + const QSize &size, SkinElementFlags flags) +{ + QPixmap result; + const QString cacheKey = + QString::fromLatin1("S60Style: SkinParts=%1 QSize=%2|%3 SkinPartFlags=%4") + .arg((int)part).arg(size.width()).arg(size.height()).arg((int)flags); + if (!QPixmapCache::find(cacheKey, result)) { + result = QS60StylePrivate::part(part, size, flags); + QPixmapCache::insert(cacheKey, result); + } + return result; +} + +QPixmap QS60StylePrivate::cachedFrame(SkinFrameElements frame, const QSize &size, SkinElementFlags flags) +{ + QPixmap result; + const QString cacheKey = + QString::fromLatin1("S60Style: SkinFrameElements=%1 QSize=%2|%3 SkinElementFlags=%4") + .arg((int)frame).arg(size.width()).arg(size.height()).arg((int)flags); + if (!QPixmapCache::find(cacheKey, result)) { + result = QS60StylePrivate::frame(frame, size, flags); + QPixmapCache::insert(cacheKey, result); + } + return result; +} + +void QS60StylePrivate::refreshUI() +{ + QList<QWidget *> widgets = QApplication::allWidgets(); + + for (int i = 0; i < widgets.size(); ++i) { + QWidget *widget = widgets.at(i); + if (widget == 0) + continue; + + if (widget->style()) { + widget->style()->polish(widget); + QEvent event(QEvent::StyleChange); + qApp->sendEvent(widget, &event); + } + widget->update(); + widget->updateGeometry(); + } +} + +void QS60StylePrivate::setFont(QWidget *widget) const +{ + QS60StyleEnums::FontCategories fontCategory = QS60StyleEnums::FC_Undefined; + if (!widget) + return; + if (qobject_cast<QPushButton *>(widget)){ + fontCategory = QS60StyleEnums::FC_Primary; + } else if (qobject_cast<QToolButton *>(widget)){ + fontCategory = QS60StyleEnums::FC_Primary; + } else if (qobject_cast<QHeaderView *>(widget)){ + fontCategory = QS60StyleEnums::FC_Secondary; + } else if (qobject_cast<QGroupBox *>(widget)){ + fontCategory = QS60StyleEnums::FC_Title; + } + if (fontCategory != QS60StyleEnums::FC_Undefined) { + const QFont suggestedFont = + s60Font(fontCategory, widget->font().pointSizeF()); + widget->setFont(suggestedFont); + } +} + +void QS60StylePrivate::setThemePalette(QWidget *widget) const +{ + if(!widget) + return; + QPalette widgetPalette = QApplication::palette(widget); + + //header view and its viewport need to be set 100% transparent button color, since drawing code will + //draw transparent theme graphics to table column and row headers. + if (qobject_cast<QHeaderView *>(widget)){ + widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, + s60Color(QS60StyleEnums::CL_QsnTextColors, 23, 0)); + QHeaderView* header = qobject_cast<QHeaderView *>(widget); + widgetPalette.setColor(QPalette::Button, Qt::transparent ); + if ( header->viewport() ) + header->viewport()->setPalette(widgetPalette); + QApplication::setPalette(widgetPalette, "QHeaderView"); + } +} + +void QS60StylePrivate::setThemePalette(QPalette *palette) const +{ + if (!palette) + return; + + // basic colors + palette->setColor(QPalette::WindowText, + s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0)); + palette->setColor(QPalette::ButtonText, + s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0)); + palette->setColor(QPalette::Text, + s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0)); + palette->setColor(QPalette::ToolTipText, + s60Color(QS60StyleEnums::CL_QsnTextColors, 55, 0)); + palette->setColor(QPalette::BrightText, palette->color(QPalette::WindowText).lighter()); + palette->setColor(QPalette::HighlightedText, + s60Color(QS60StyleEnums::CL_QsnTextColors, 10, 0)); + palette->setColor(QPalette::Link, + s60Color(QS60StyleEnums::CL_QsnHighlightColors, 3, 0)); + palette->setColor(QPalette::LinkVisited, palette->color(QPalette::Link).darker()); + palette->setColor(QPalette::Highlight, + s60Color(QS60StyleEnums::CL_QsnHighlightColors, 2, 0)); + // set background image as a texture brush + palette->setBrush(QPalette::Window, backgroundTexture()); + // set these as transparent so that styled full screen theme background is visible + palette->setColor(QPalette::AlternateBase, Qt::transparent); + palette->setBrush(QPalette::Base, Qt::transparent); + // set button and tooltipbase based on pixel colors + const QColor buttonColor = this->colorFromFrameGraphics(SF_ButtonNormal); + palette->setColor(QPalette::Button, buttonColor ); + const QColor toolTipColor = this->colorFromFrameGraphics(SF_ToolTip); + palette->setColor(QPalette::ToolTipBase, toolTipColor ); + palette->setColor(QPalette::Light, palette->color(QPalette::Button).lighter()); + palette->setColor(QPalette::Dark, palette->color(QPalette::Button).darker()); + palette->setColor(QPalette::Midlight, palette->color(QPalette::Button).lighter(125)); + palette->setColor(QPalette::Mid, palette->color(QPalette::Button).darker(150)); + palette->setColor(QPalette::Shadow, Qt::black); +} + +void QS60StylePrivate::deleteThemePalette() +{ + if (m_themePalette) { + delete m_themePalette; + m_themePalette = 0; + } +} + +void QS60StylePrivate::storeThemePalette(QPalette *palette) +{ + deleteThemePalette(); + //store specified palette for latter use. + m_themePalette = new QPalette(*palette); +} + +// set widget specific palettes +void QS60StylePrivate::setThemePaletteHash(QPalette *palette) const +{ + if (!palette) + return; + + //store the original palette + QPalette widgetPalette = *palette; + const QColor mainAreaTextColor = + s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0); + + widgetPalette.setColor(QPalette::All, QPalette::WindowText, + s60Color(QS60StyleEnums::CL_QsnLineColors, 8, 0)); + QApplication::setPalette(widgetPalette, "QSlider"); + // return to original palette after each widget + widgetPalette = *palette; + + widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, mainAreaTextColor); + widgetPalette.setColor(QPalette::Inactive, QPalette::ButtonText, mainAreaTextColor); + const QStyleOption opt; + widgetPalette.setColor(QPalette::Disabled, QPalette::ButtonText, + s60Color(QS60StyleEnums::CL_QsnTextColors, 6, &opt)); + QApplication::setPalette(widgetPalette, "QPushButton"); + widgetPalette = *palette; + + widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, mainAreaTextColor); + widgetPalette.setColor(QPalette::Inactive, QPalette::ButtonText, mainAreaTextColor); + QApplication::setPalette(widgetPalette, "QToolButton"); + widgetPalette = *palette; + + widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, + s60Color(QS60StyleEnums::CL_QsnTextColors, 23, 0)); + QApplication::setPalette(widgetPalette, "QHeaderView"); + widgetPalette = *palette; + + widgetPalette.setColor(QPalette::All, QPalette::ButtonText, + s60Color(QS60StyleEnums::CL_QsnTextColors, 8, 0)); + QApplication::setPalette(widgetPalette, "QMenuBar"); + widgetPalette = *palette; + + widgetPalette.setColor(QPalette::Active, QPalette::WindowText, + s60Color(QS60StyleEnums::CL_QsnTextColors, 4, 0)); + QApplication::setPalette(widgetPalette, "QTabBar"); + widgetPalette = *palette; + + widgetPalette.setColor(QPalette::All, QPalette::Text, + s60Color(QS60StyleEnums::CL_QsnTextColors, 22, 0)); + QApplication::setPalette(widgetPalette, "QTableView"); + widgetPalette = *palette; + + widgetPalette.setColor(QPalette::All, QPalette::HighlightedText, + s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0)); + QApplication::setPalette(widgetPalette, "QLineEdit"); + widgetPalette = *palette; + + widgetPalette.setColor(QPalette::All, QPalette::Text, + s60Color(QS60StyleEnums::CL_QsnTextColors, 34, 0)); + widgetPalette.setColor(QPalette::All, QPalette::HighlightedText, + s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0)); + QApplication::setPalette(widgetPalette, "QTextEdit"); + widgetPalette = *palette; + + widgetPalette.setColor(QPalette::All, QPalette::HighlightedText, + s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0)); + QApplication::setPalette(widgetPalette, "QComboBox"); + widgetPalette = *palette; + + widgetPalette.setColor(QPalette::WindowText, mainAreaTextColor); + widgetPalette.setColor(QPalette::Button, QApplication::palette().color(QPalette::Button)); + widgetPalette.setColor(QPalette::Dark, mainAreaTextColor.darker()); + widgetPalette.setColor(QPalette::Light, mainAreaTextColor.lighter()); + QApplication::setPalette(widgetPalette, "QDial"); + widgetPalette = *palette; + + widgetPalette.setBrush(QPalette::Window, QBrush()); + QApplication::setPalette(widgetPalette, "QScrollArea"); + widgetPalette = *palette; +} + +QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlags flags) +{ + QSize result(20, 20); + switch (part) + { + case QS60StyleEnums::SP_QgnGrafBarProgress: + result.setWidth(pixelMetric(QStyle::PM_ProgressBarChunkWidth)); + break; + case QS60StyleEnums::SP_QgnGrafTabActiveM: + case QS60StyleEnums::SP_QgnGrafTabPassiveM: + case QS60StyleEnums::SP_QgnGrafTabActiveR: + case QS60StyleEnums::SP_QgnGrafTabPassiveR: + case QS60StyleEnums::SP_QgnGrafTabPassiveL: + case QS60StyleEnums::SP_QgnGrafTabActiveL: + break; + case QS60StyleEnums::SP_QgnIndiSliderEdit: + result.scale(pixelMetric(QStyle::PM_SliderLength), + pixelMetric(QStyle::PM_SliderControlThickness), Qt::IgnoreAspectRatio); + break; + + case QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed: + case QS60StyleEnums::SP_QsnCpScrollHandleTopPressed: + case QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed: + case QS60StyleEnums::SP_QsnCpScrollBgBottom: + case QS60StyleEnums::SP_QsnCpScrollBgMiddle: + case QS60StyleEnums::SP_QsnCpScrollBgTop: + case QS60StyleEnums::SP_QsnCpScrollHandleBottom: + case QS60StyleEnums::SP_QsnCpScrollHandleMiddle: + case QS60StyleEnums::SP_QsnCpScrollHandleTop: + result.setHeight(pixelMetric(QStyle::PM_ScrollBarExtent)); + result.setWidth(pixelMetric(QStyle::PM_ScrollBarSliderMin)); + break; + default: + // Generic frame part size gathering. + for (int i = 0; i < frameElementsCount; ++i) + { + switch (m_frameElementsData[i].center - part) { + case 8: /* CornerTl */ + case 7: /* CornerTr */ + case 6: /* CornerBl */ + case 5: /* CornerBr */ + result.setWidth(pixelMetric(PM_Custom_FrameCornerWidth)); + // Falltrough intended... + case 4: /* SideT */ + case 3: /* SideB */ + result.setHeight(pixelMetric(PM_Custom_FrameCornerHeight)); + break; + case 2: /* SideL */ + case 1: /* SideR */ + result.setWidth(pixelMetric(PM_Custom_FrameCornerWidth)); + break; + case 0: /* center */ + default: + break; + } + } + break; + } + if (flags & (SF_PointEast | SF_PointWest)) { + const int temp = result.width(); + result.setWidth(result.height()); + result.setHeight(temp); + } + return result; +} + +/*! + \class QS60Style + \brief The QS60Style class provides a look and feel suitable for applications on S60. + \since 4.6 + \ingroup appearance + + \sa QMacStyle, QWindowsStyle, QWindowsXPStyle, QWindowsVistaStyle, QPlastiqueStyle, QCleanlooksStyle, QMotifStyle +*/ + +QS60Style::~QS60Style() +{ +} + +/*! + \reimp +*/ +void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const +{ + const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled; + SubControls sub = option->subControls; + + switch (control) { +#ifndef QT_NO_SCROLLBAR + case CC_ScrollBar: + if (const QStyleOptionSlider *optionSlider = qstyleoption_cast<const QStyleOptionSlider *>(option)) { + const bool horizontal = optionSlider->orientation == Qt::Horizontal; + + const QRect scrollBarSlider = subControlRect(control, optionSlider, SC_ScrollBarSlider, widget); + const QRect grooveRect = subControlRect(control, optionSlider, SC_ScrollBarGroove, widget); + + const QS60StylePrivate::SkinElements grooveElement = + horizontal ? QS60StylePrivate::SE_ScrollBarGrooveHorizontal : QS60StylePrivate::SE_ScrollBarGrooveVertical; + QS60StylePrivate::drawSkinElement(grooveElement, painter, grooveRect, flags); + + const QStyle::SubControls subControls = optionSlider->subControls; + + // select correct slider (horizontal/vertical/pressed) + const bool sliderPressed = ((optionSlider->state & QStyle::State_Sunken) && (subControls & SC_ScrollBarSlider)); + const QS60StylePrivate::SkinElements handleElement = + horizontal ? + ( sliderPressed ? + QS60StylePrivate::SE_ScrollBarHandlePressedHorizontal : + QS60StylePrivate::SE_ScrollBarHandleHorizontal ) : + ( sliderPressed ? + QS60StylePrivate::SE_ScrollBarHandlePressedVertical : + QS60StylePrivate::SE_ScrollBarHandleVertical); + QS60StylePrivate::drawSkinElement(handleElement, painter, scrollBarSlider, flags); + } + break; +#endif // QT_NO_SCROLLBAR +#ifndef QT_NO_SLIDER + case CC_Slider: + if (const QStyleOptionSlider *optionSlider = qstyleoption_cast<const QStyleOptionSlider *>(option)) { + + // The groove is just a centered line. Maybe a qgn_graf_line_* at some point + const QRect sliderGroove = subControlRect(control, optionSlider, SC_SliderGroove, widget); + const QPoint sliderGrooveCenter = sliderGroove.center(); + const bool horizontal = optionSlider->orientation == Qt::Horizontal; + painter->save(); + if (widget) + painter->setPen(widget->palette().windowText().color()); + if (horizontal) + painter->drawLine(0, sliderGrooveCenter.y(), sliderGroove.right(), sliderGrooveCenter.y()); + else + painter->drawLine(sliderGrooveCenter.x(), 0, sliderGrooveCenter.x(), sliderGroove.bottom()); + painter->restore(); + + const QRect sliderHandle = subControlRect(control, optionSlider, SC_SliderHandle, widget); + const QS60StylePrivate::SkinElements handleElement = + horizontal ? QS60StylePrivate::SE_SliderHandleHorizontal : QS60StylePrivate::SE_SliderHandleVertical; + QS60StylePrivate::drawSkinElement(handleElement, painter, sliderHandle, flags); + + if (optionSlider->state & State_HasFocus) { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*optionSlider); + fropt.rect = subElementRect(SE_SliderFocusRect, optionSlider, widget); + drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); + } + } + break; +#endif // QT_NO_SLIDER +#ifndef QT_NO_COMBOBOX + case CC_ComboBox: + if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { + const QRect cmbxEditField = subControlRect(CC_ComboBox, option, SC_ComboBoxEditField, widget); + const QRect cmbxFrame = subControlRect(CC_ComboBox, option, SC_ComboBoxFrame, widget); + const bool direction = cmb->direction == Qt::LeftToRight; + + // Button frame + QStyleOptionFrame buttonOption; + buttonOption.QStyleOption::operator=(*cmb); + const int maxHeight = cmbxFrame.height(); + const int maxWidth = cmbxFrame.width() - cmbxEditField.width(); + const int topLeftPoint = direction ? cmbxEditField.right()+1 : cmbxEditField.left()+1-maxWidth; + const QRect buttonRect(topLeftPoint, cmbxEditField.top(), maxWidth, maxHeight); + buttonOption.rect = buttonRect; + buttonOption.state = cmb->state & (State_Enabled | State_MouseOver); + drawPrimitive(PE_PanelButtonCommand, &buttonOption, painter, widget); + + // draw label background - label itself is drawn separately + const QS60StylePrivate::SkinElements skinElement = QS60StylePrivate::SE_FrameLineEdit; + QS60StylePrivate::drawSkinElement(skinElement, painter, cmbxEditField, flags); + + // Draw the combobox arrow + if (sub & SC_ComboBoxArrow) { + // Make rect slightly smaller + buttonOption.rect.adjust(1, 1, -1, -1); + painter->save(); + painter->setPen(option->palette.buttonText().color()); + drawPrimitive(PE_IndicatorSpinDown, &buttonOption, painter, widget); + painter->restore(); + } + + if (cmb->subControls & SC_ComboBoxEditField) { + if (cmb->state & State_HasFocus && !cmb->editable) { + QStyleOptionFocusRect focus; + focus.QStyleOption::operator=(*cmb); + focus.rect = cmbxEditField; + focus.state |= State_FocusAtBorder; + focus.backgroundColor = cmb->palette.highlight().color(); + drawPrimitive(PE_FrameFocusRect, &focus, painter, widget); + } + } + } + break; +#endif // QT_NO_COMBOBOX +#ifndef QT_NO_TOOLBUTTON + case CC_ToolButton: + if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(option)) { + const State bflags = toolBtn->state; + const QRect button(subControlRect(control, toolBtn, SC_ToolButton, widget)); + QStyleOptionToolButton toolButton = *toolBtn; + + if (sub&SC_ToolButton) { + QStyleOption tool(0); + tool.palette = toolBtn->palette; + + // Check if toolbutton is in toolbar. + QToolBar *toolBar = 0; + if (widget) + toolBar = qobject_cast<QToolBar *>(widget->parentWidget()); + + if (bflags & (State_Sunken | State_On | State_Raised)) { + tool.rect = button; + tool.state = bflags; + + // todo: I'd like to move extension button next to where last button is + // however, the painter seems to want to clip the button rect even if I turn of the clipping. + if (toolBar && (qobject_cast<const QToolBarExtension *>(widget))){ + /*QList<QAction *> actionList = toolBar->actions(); + const int actionCount = actionList.count(); + const int toolbarWidth = toolBar->width(); + const int extButtonWidth = pixelMetric(PM_ToolBarExtensionExtent, option, widget); + const int toolBarButtonWidth = pixelMetric(PM_ToolBarIconSize, option, widget); + const int frame = pixelMetric(PM_ToolBarFrameWidth, option, widget); + const int margin = pixelMetric(PM_ToolBarItemMargin, option, widget); + const int border = frame + margin; + const int spacing = pixelMetric(PM_ToolBarItemSpacing, option, widget); + const int toolBarButtonArea = toolbarWidth - extButtonWidth - spacing - 2*border; + const int numberOfVisibleButtons = toolBarButtonArea / toolBarButtonWidth; + // new extension button place is after border and all the other visible buttons (with spacings) + const int newXForExtensionButton = numberOfVisibleButtons * toolBarButtonWidth + (numberOfVisibleButtons-1)*spacing + border; + painter->save(); + painter->setClipping(false); + tool.rect.translate(-newXForExtensionButton,0); + painter->restore();*/ + } + + if (toolBar){ + /*if (toolBar->orientation() == Qt::Vertical){ + // todo: I'd like to make all vertical buttons the same size, but again the painter + // prefers to use clipping for button rects, even though clipping has been set off. + painter->save(); + painter->setClipping(false); + + const int origWidth = tool.rect.width(); + const int newWidth = toolBar->width()-2*pixelMetric(PM_ToolBarFrameWidth, option, widget); + painter->translate(origWidth-newWidth,0); + tool.rect.translate(origWidth-tool.rect.width(),0); + tool.rect.setWidth(newWidth); + + if (option->state & QStyle::State_Sunken) + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButtonPressed, painter, tool.rect, flags); + else + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButton, painter, tool.rect, flags); + + }*/ + if (option->state & QStyle::State_Sunken) + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButtonPressed, painter, tool.rect, flags); + else + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBarButton, painter, tool.rect, flags); + /* + if (toolBar->orientation() == Qt::Vertical) + painter->restore(); + */ + } else { + drawPrimitive(PE_PanelButtonTool, &tool, painter, widget); + } + } + } + if (toolBtn->state & State_HasFocus) { + QStyleOptionFocusRect fr; + fr.QStyleOption::operator=(*toolBtn); + const int frameWidth = pixelMetric(PM_DefaultFrameWidth, option, widget); + fr.rect.adjust(frameWidth, frameWidth, -frameWidth, -frameWidth); + drawPrimitive(PE_FrameFocusRect, &fr, painter, widget); + } + + if (toolBtn->features & QStyleOptionToolButton::Arrow) { + QStyle::PrimitiveElement pe; + switch (toolBtn->arrowType) { + case Qt::LeftArrow: + pe = QStyle::PE_IndicatorArrowLeft; + break; + case Qt::RightArrow: + pe = QStyle::PE_IndicatorArrowRight; + break; + case Qt::UpArrow: + pe = QStyle::PE_IndicatorArrowUp; + break; + case Qt::DownArrow: + pe = QStyle::PE_IndicatorArrowDown; + break; + default: + break; } + toolButton.rect = button; + drawPrimitive(pe, &toolButton, painter, widget); + } + + if (toolBtn->text.length()>0 || + !toolBtn->icon.isNull()) { + const int frameWidth = pixelMetric(PM_DefaultFrameWidth, option, widget); + toolButton.rect = button.adjusted(frameWidth, frameWidth, -frameWidth, -frameWidth); + drawControl(CE_ToolButtonLabel, &toolButton, painter, widget); + } + } + break; +#endif //QT_NO_TOOLBUTTON +#ifndef QT_NO_SPINBOX + case CC_SpinBox: + if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { + QStyleOptionSpinBox copy = *spinBox; + PrimitiveElement pe; + + if (spinBox->subControls & SC_SpinBoxUp) { + copy.subControls = SC_SpinBoxUp; + QPalette spinBoxPal = spinBox->palette; + if (!(spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled)) { + spinBoxPal.setCurrentColorGroup(QPalette::Disabled); + copy.state &= ~State_Enabled; + copy.palette = spinBoxPal; + } + + if (spinBox->activeSubControls == SC_SpinBoxUp && (spinBox->state & State_Sunken)) { + copy.state |= State_On; + copy.state |= State_Sunken; + } else { + copy.state |= State_Raised; + copy.state &= ~State_Sunken; + } + pe = (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) ? + PE_IndicatorSpinPlus : + PE_IndicatorSpinUp; + + copy.rect = subControlRect(CC_SpinBox, spinBox, SC_SpinBoxUp, widget); + drawPrimitive(PE_PanelButtonBevel, ©, painter, widget); + copy.rect.adjust(1, 1, -1, -1); + drawPrimitive(pe, ©, painter, widget); + } + + if (spinBox->subControls & SC_SpinBoxDown) { + copy.subControls = SC_SpinBoxDown; + copy.state = spinBox->state; + QPalette spinBoxPal = spinBox->palette; + if (!(spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled)) { + spinBoxPal.setCurrentColorGroup(QPalette::Disabled); + copy.state &= ~State_Enabled; + copy.palette = spinBoxPal; + } + + if (spinBox->activeSubControls == SC_SpinBoxDown && (spinBox->state & State_Sunken)) { + copy.state |= State_On; + copy.state |= State_Sunken; + } else { + copy.state |= State_Raised; + copy.state &= ~State_Sunken; + } + pe = (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) ? + PE_IndicatorSpinMinus : + PE_IndicatorSpinDown; + + copy.rect = subControlRect(CC_SpinBox, spinBox, SC_SpinBoxDown, widget); + drawPrimitive(PE_PanelButtonBevel, ©, painter, widget); + copy.rect.adjust(1, 1, -1, -1); + drawPrimitive(pe, ©, painter, widget); + } + } + break; +#endif //QT_NO_SPINBOX +#ifndef QT_NO_GROUPBOX + case CC_GroupBox: + if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) { + // Draw frame + const QRect textRect = subControlRect(CC_GroupBox, option, SC_GroupBoxLabel, widget); + const QRect checkBoxRect = subControlRect(CC_GroupBox, option, SC_GroupBoxCheckBox, widget); + if (groupBox->subControls & QStyle::SC_GroupBoxFrame) { + QStyleOptionFrameV2 frame; + frame.QStyleOption::operator=(*groupBox); + frame.features = groupBox->features; + frame.lineWidth = groupBox->lineWidth; + frame.midLineWidth = groupBox->midLineWidth; + frame.rect = subControlRect(CC_GroupBox, option, SC_GroupBoxFrame, widget); + drawPrimitive(PE_FrameGroupBox, &frame, painter, widget); + } + + // Draw title + if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) { + const QColor textColor = groupBox->textColor; + painter->save(); + + if (textColor.isValid()) + painter->setPen(textColor); + int alignment = int(groupBox->textAlignment); + if (!styleHint(QStyle::SH_UnderlineShortcut, option, widget)) + alignment |= Qt::TextHideMnemonic; + + drawItemText(painter, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | Qt::AlignVCenter | alignment, + groupBox->palette, groupBox->state & State_Enabled, groupBox->text, + textColor.isValid() ? QPalette::NoRole : QPalette::WindowText); + painter->restore(); + + if (groupBox->state & State_HasFocus) { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*groupBox); + fropt.rect = textRect; + drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); + } + } + + // Draw checkbox + if (groupBox->subControls & SC_GroupBoxCheckBox) { + QStyleOptionButton box; + box.QStyleOption::operator=(*groupBox); + box.rect = checkBoxRect; + drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget); + } + } + break; +#endif //QT_NO_GROUPBOX + default: + QCommonStyle::drawComplexControl(control, option, painter, widget); + } +} + +/*! + \reimp +*/ +void QS60Style::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const +{ + Q_D(const QS60Style); + const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled; + switch (element) { + case CE_PushButton: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { + + drawControl(CE_PushButtonBevel, btn, painter, widget); + QStyleOptionButton subopt = *btn; + subopt.rect = subElementRect(SE_PushButtonContents, btn, widget); + + drawControl(CE_PushButtonLabel, &subopt, painter, widget); + if (btn->state & State_HasFocus) { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*btn); + fropt.rect = subElementRect(SE_PushButtonFocusRect, btn, widget); + drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); + } + } + break; + case CE_PushButtonBevel: + if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) { + const bool isDisabled = !(option->state & QStyle::State_Enabled); + const bool isFlat = button->features & QStyleOptionButton::Flat; + QS60StyleEnums::SkinParts skinPart; + QS60StylePrivate::SkinElements skinElement; + if (!isDisabled) { + const bool isPressed = (option->state & QStyle::State_Sunken) || + (option->state & QStyle::State_On); + if (isFlat) { + skinPart = + isPressed ? QS60StyleEnums::SP_QsnFrButtonTbCenterPressed : QS60StyleEnums::SP_QsnFrButtonTbCenter; + } else { + skinElement = + isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal; + } + } else { + if (isFlat) + skinPart =QS60StyleEnums::SP_QsnFrButtonCenterInactive; + else + skinElement = QS60StylePrivate::SE_ButtonInactive; + } + if (isFlat) + QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags); + else + QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags); + } + break; +#ifndef QT_NO_TOOLBUTTON + case CE_ToolButtonLabel: + if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(option)) { + QStyleOptionToolButton optionToolButton = *toolBtn; + + if (!optionToolButton.icon.isNull() && (optionToolButton.state & QStyle::State_Sunken) + && (optionToolButton.state & State_Enabled)) { + + const QIcon::State state = optionToolButton.state & State_On ? QIcon::On : QIcon::Off; + const QPixmap pm(optionToolButton.icon.pixmap(optionToolButton.rect.size().boundedTo(optionToolButton.iconSize), + QIcon::Normal, state)); + optionToolButton.icon = generatedIconPixmap(QIcon::Selected, pm, &optionToolButton); + } + + QCommonStyle::drawControl(element, &optionToolButton, painter, widget); + } + break; +#endif //QT_NO_TOOLBUTTON +#ifndef QT_NO_COMBOBOX + case CE_ComboBoxLabel: + if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { + QStyleOption optionComboBox = *comboBox; + optionComboBox.palette.setColor(QPalette::Active, QPalette::WindowText, + optionComboBox.palette.text().color() ); + optionComboBox.palette.setColor(QPalette::Inactive, QPalette::WindowText, + optionComboBox.palette.text().color() ); + QRect editRect = subControlRect(CC_ComboBox, comboBox, SC_ComboBoxEditField, widget); + painter->save(); + painter->setClipRect(editRect); + + if (!comboBox->currentIcon.isNull()) { + QIcon::Mode mode = comboBox->state & State_Enabled ? QIcon::Normal : QIcon::Disabled; + QPixmap pixmap = comboBox->currentIcon.pixmap(comboBox->iconSize, mode); + QRect iconRect(editRect); + iconRect.setWidth(comboBox->iconSize.width() + 4); + iconRect = alignedRect(comboBox->direction, + Qt::AlignLeft | Qt::AlignVCenter, + iconRect.size(), editRect); + if (comboBox->editable) + painter->fillRect(iconRect, optionComboBox.palette.brush(QPalette::Base)); + drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap); + + if (comboBox->direction == Qt::RightToLeft) + editRect.translate(-4 - comboBox->iconSize.width(), 0); + else + editRect.translate(comboBox->iconSize.width() + 4, 0); + } + if (!comboBox->currentText.isEmpty() && !comboBox->editable) { + QCommonStyle::drawItemText(painter, + editRect.adjusted(QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth), 0, -1, 0), + visualAlignment(comboBox->direction, Qt::AlignLeft | Qt::AlignVCenter), + comboBox->palette, comboBox->state & State_Enabled, comboBox->currentText); + } + painter->restore(); + } + break; +#endif //QT_NO_COMBOBOX +#ifndef QT_NO_ITEMVIEWS + case CE_ItemViewItem: + if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) { + QStyleOptionViewItemV4 voptAdj = *vopt; + painter->save(); + + painter->setClipRect(voptAdj.rect); + const bool isSelected = (voptAdj.state & QStyle::State_HasFocus); + + bool isVisible = false; + int scrollBarWidth = 0; + QList<QScrollBar *> scrollBars = qFindChildren<QScrollBar *>(widget); + for (int i = 0; i < scrollBars.size(); ++i) { + QScrollBar *scrollBar = scrollBars.at(i); + if (scrollBar && scrollBar->orientation() == Qt::Vertical) { + isVisible = scrollBar->isVisible(); + scrollBarWidth = scrollBar->size().width(); + break; + } + } + + int rightValue = widget ? widget->contentsRect().right() : 0; + + if (isVisible) + rightValue -= scrollBarWidth; + + if (voptAdj.rect.right() > rightValue) + voptAdj.rect.setRight(rightValue); + + const QRect iconRect = subElementRect(SE_ItemViewItemDecoration, &voptAdj, widget); + QRect textRect = subElementRect(SE_ItemViewItemText, &voptAdj, widget); + + // draw themed background for table unless background brush has been defined. + if (vopt->backgroundBrush == Qt::NoBrush) { + const QStyleOptionViewItemV4 *tableOption = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option); + const QTableView *table = qobject_cast<const QTableView *>(widget); + if (table && tableOption) { + const QModelIndex index = tableOption->index; + //todo: Draw cell background only once - for the first cell. + QStyleOptionViewItemV4 voptAdj2 = voptAdj; + const QModelIndex indexFirst = table->model()->index(0,0); + const QModelIndex indexLast = table->model()->index( + table->model()->rowCount()-1,table->model()->columnCount()-1); + if (table->viewport()) + voptAdj2.rect = QRect( table->visualRect(indexFirst).topLeft(), + table->visualRect(indexLast).bottomRight()).intersect(table->viewport()->rect()); + drawPrimitive(PE_PanelItemViewItem, &voptAdj2, painter, widget); + } + } else { QCommonStyle::drawPrimitive(PE_PanelItemViewItem, option, painter, widget);} + + // draw the focus rect + if (isSelected) { + const QRect highlightRect = option->rect.adjusted(1,1,-1,-1); + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, highlightRect, flags); + } + + // draw the icon + const QIcon::Mode mode = (voptAdj.state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled; + const QIcon::State state = voptAdj.state & QStyle::State_Open ? QIcon::On : QIcon::Off; + voptAdj.icon.paint(painter, iconRect, voptAdj.decorationAlignment, mode, state); + + // Draw selection check mark. Show check mark only in multi selection modes. + if (const QListView *listView = (qobject_cast<const QListView *>(widget))) { + const bool singleSelection = + listView && + (listView->selectionMode() == QAbstractItemView::SingleSelection || + listView->selectionMode() == QAbstractItemView::NoSelection); + const QRect selectionRect = subElementRect(SE_ItemViewItemCheckIndicator, &voptAdj, widget); + if (voptAdj.state & QStyle::State_Selected && !singleSelection) { + QStyleOptionViewItemV4 option(voptAdj); + option.rect = selectionRect; + // Draw selection mark. + drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option, painter, widget); + if ( textRect.right() > selectionRect.left() ) + textRect.setRight(selectionRect.left()); + } else if (singleSelection && + voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator) { + // draw the check mark + if (selectionRect.isValid()) { + QStyleOptionViewItemV4 option(*vopt); + option.rect = selectionRect; + option.state = option.state & ~QStyle::State_HasFocus; + + switch (vopt->checkState) { + case Qt::Unchecked: + option.state |= QStyle::State_Off; + break; + case Qt::PartiallyChecked: + option.state |= QStyle::State_NoChange; + break; + case Qt::Checked: + option.state |= QStyle::State_On; + break; + } + drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option, painter, widget); + } + } + } + + // draw the text + if (!voptAdj.text.isEmpty()) { + const QStyleOptionViewItemV4 *tableOption = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option); + if (isSelected) { + if (qobject_cast<const QTableView *>(widget) && tableOption) + voptAdj.palette.setColor( + QPalette::Text, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 11, 0)); + else + voptAdj.palette.setColor( + QPalette::Text, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 10, 0)); + } + painter->setPen(voptAdj.palette.text().color()); + d->viewItemDrawText(painter, &voptAdj, textRect); + } + painter->restore(); + } + break; +#endif // QT_NO_ITEMVIEWS +#ifndef QT_NO_TABBAR + case CE_TabBarTabShape: + if (const QStyleOptionTabV3 *optionTab = qstyleoption_cast<const QStyleOptionTabV3 *>(option)) { + QStyleOptionTabV3 optionTabAdj = *optionTab; + const bool isSelected = optionTab->state & QStyle::State_Selected; + const bool directionMirrored = (optionTab->direction == Qt::RightToLeft); + QS60StylePrivate::SkinElements skinElement; + switch (optionTab->shape) { + case QTabBar::TriangularEast: + case QTabBar::RoundedEast: + skinElement = isSelected ? QS60StylePrivate::SE_TabBarTabEastActive: + QS60StylePrivate::SE_TabBarTabEastInactive; + break; + case QTabBar::TriangularSouth: + case QTabBar::RoundedSouth: + skinElement = isSelected ? QS60StylePrivate::SE_TabBarTabSouthActive: + QS60StylePrivate::SE_TabBarTabSouthInactive; + break; + case QTabBar::TriangularWest: + case QTabBar::RoundedWest: + skinElement = isSelected ? QS60StylePrivate::SE_TabBarTabWestActive: + QS60StylePrivate::SE_TabBarTabWestInactive; + break; + case QTabBar::TriangularNorth: + case QTabBar::RoundedNorth: + default: + skinElement = isSelected ? QS60StylePrivate::SE_TabBarTabNorthActive: + QS60StylePrivate::SE_TabBarTabNorthInactive; + break; + } + if (skinElement==QS60StylePrivate::SE_TabBarTabEastInactive|| + skinElement==QS60StylePrivate::SE_TabBarTabNorthInactive|| + skinElement==QS60StylePrivate::SE_TabBarTabSouthInactive|| + skinElement==QS60StylePrivate::SE_TabBarTabWestInactive|| + skinElement==QS60StylePrivate::SE_TabBarTabEastActive|| + skinElement==QS60StylePrivate::SE_TabBarTabNorthActive|| + skinElement==QS60StylePrivate::SE_TabBarTabSouthActive|| + skinElement==QS60StylePrivate::SE_TabBarTabWestActive) { + const int borderThickness = + QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth); + const int tabOverlap = + QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap) - borderThickness; + //todo: draw navi wipe behind tabbar - must be drawn with first draw + + if (skinElement==QS60StylePrivate::SE_TabBarTabEastInactive|| + skinElement==QS60StylePrivate::SE_TabBarTabEastActive|| + skinElement==QS60StylePrivate::SE_TabBarTabWestInactive|| + skinElement==QS60StylePrivate::SE_TabBarTabWestActive){ + optionTabAdj.rect.adjust(0, 0, 0, tabOverlap); + } else { + if (directionMirrored) + optionTabAdj.rect.adjust(-tabOverlap, 0, 0, 0); + else + optionTabAdj.rect.adjust(0, 0, tabOverlap, 0); + } + } + QS60StylePrivate::drawSkinElement(skinElement, painter, optionTabAdj.rect, flags); + } + break; + case CE_TabBarTabLabel: + if (const QStyleOptionTabV3 *tab = qstyleoption_cast<const QStyleOptionTabV3 *>(option)) { + QStyleOptionTabV3 optionTab = *tab; + QRect tr = optionTab.rect; + const bool directionMirrored = (optionTab.direction == Qt::RightToLeft); + const int borderThickness = QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth); + const int tabOverlap = + QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap) - borderThickness; + const QRect windowRect = painter->window(); + + switch (tab->shape) { + case QTabBar::TriangularWest: + case QTabBar::RoundedWest: + case QTabBar::TriangularEast: + case QTabBar::RoundedEast: + tr.adjust(0, 0, 0, tabOverlap); + break; + case QTabBar::TriangularSouth: + case QTabBar::RoundedSouth: + case QTabBar::TriangularNorth: + case QTabBar::RoundedNorth: + default: + if (directionMirrored) + tr.adjust(-tabOverlap, 0, 0, 0); + else + tr.adjust(0, 0, tabOverlap, 0); + break; + } + painter->save(); + QFont f = painter->font(); + f.setPointSizeF(f.pointSizeF() * KTabFontMul); + painter->setFont(f); + + if (option->state & QStyle::State_Selected){ + optionTab.palette.setColor(QPalette::Active, QPalette::WindowText, + QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 3, option)); + } + + const bool verticalTabs = optionTab.shape == QTabBar::RoundedEast + || optionTab.shape == QTabBar::RoundedWest + || optionTab.shape == QTabBar::TriangularEast + || optionTab.shape == QTabBar::TriangularWest; + const bool selected = optionTab.state & State_Selected; + if (verticalTabs) { + painter->save(); + int newX, newY, newRotation; + if (optionTab.shape == QTabBar::RoundedEast || optionTab.shape == QTabBar::TriangularEast) { + newX = tr.width(); + newY = tr.y(); + newRotation = 90; + } else { + newX = 0; + newY = tr.y() + tr.height(); + newRotation = -90; + } + tr.setRect(0, 0, tr.height(), tr.width()); + QTransform m; + m.translate(newX, newY); + m.rotate(newRotation); + painter->setTransform(m, true); + } + tr.adjust(0, 0, pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget), + pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget)); + + if (selected) { + tr.setBottom(tr.bottom() - pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget)); + tr.setRight(tr.right() - pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget)); + } + + int alignment = Qt::AlignCenter | Qt::TextShowMnemonic; + if (!styleHint(SH_UnderlineShortcut, &optionTab, widget)) + alignment |= Qt::TextHideMnemonic; + if (!optionTab.icon.isNull()) { + QSize iconSize = optionTab.iconSize; + int iconExtent = pixelMetric(PM_TabBarIconSize); + if (iconSize.height() > iconExtent || iconSize.width() > iconExtent) + iconSize = QSize(iconExtent, iconExtent); + QPixmap tabIcon = optionTab.icon.pixmap(iconSize, + (optionTab.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled); + if (tab->text.isEmpty()) + painter->drawPixmap(tr.center().x() - (tabIcon.height() >>1), + tr.center().y() - (tabIcon.height() >>1), + tabIcon); + else + painter->drawPixmap(tr.left() + tabOverlap, + tr.center().y() - (tabIcon.height() >>1), + tabIcon); + tr.setLeft(tr.left() + iconSize.width() + 4); + } + + QCommonStyle::drawItemText(painter, tr, alignment, optionTab.palette, tab->state & State_Enabled, tab->text, QPalette::WindowText); + if (verticalTabs) + painter->restore(); + + if (optionTab.state & State_HasFocus) { + const int OFFSET = 1 + pixelMetric(PM_DefaultFrameWidth); + const int leftBorder = optionTab.rect.left(); + const int rightBorder = optionTab.rect.right() - 1; + + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*tab); + fropt.rect.setRect(leftBorder + 1 + OFFSET, optionTab.rect.y() + OFFSET, + rightBorder - leftBorder - 2*OFFSET, optionTab.rect.height() - 2*OFFSET); + drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); + } + + painter->restore(); + } + break; +#endif // QT_NO_TABBAR +#ifndef QT_NO_PROGRESSBAR + case CE_ProgressBarContents: + if (const QStyleOptionProgressBarV2 *optionProgressBar = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) { + QRect progressRect = optionProgressBar->rect; + + if (optionProgressBar->minimum == optionProgressBar->maximum && optionProgressBar->minimum == 0) { + // busy indicator + QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafBarWait, painter, progressRect,flags); + } else { + const qreal progressFactor = (optionProgressBar->minimum == optionProgressBar->maximum) ? 1.0 + : (qreal)optionProgressBar->progress / optionProgressBar->maximum; + if (optionProgressBar->orientation == Qt::Horizontal) { + progressRect.setWidth(int(progressRect.width() * progressFactor)); + if(optionProgressBar->direction == Qt::RightToLeft) + progressRect.translate(optionProgressBar->rect.width()-progressRect.width(),0); + progressRect.adjust(1, 0, -1, 0); + } else { + progressRect.adjust(0, 1, 0, -1); + progressRect.setTop(progressRect.bottom() - int(progressRect.height() * progressFactor)); + } + + const QS60StylePrivate::SkinElements skinElement = optionProgressBar->orientation == Qt::Horizontal ? + QS60StylePrivate::SE_ProgressBarIndicatorHorizontal : QS60StylePrivate::SE_ProgressBarIndicatorVertical; + QS60StylePrivate::drawSkinElement(skinElement, painter, progressRect, flags); + } + } + break; + case CE_ProgressBarGroove: + if (const QStyleOptionProgressBarV2 *optionProgressBar = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) { + const QS60StylePrivate::SkinElements skinElement = optionProgressBar->orientation == Qt::Horizontal ? + QS60StylePrivate::SE_ProgressBarGrooveHorizontal : QS60StylePrivate::SE_ProgressBarGrooveVertical; + QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags); + } + break; + case CE_ProgressBarLabel: + if (const QStyleOptionProgressBarV2 *progressbar = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) { + QStyleOptionProgressBarV2 optionProgressBar = *progressbar; + QCommonStyle::drawItemText(painter, progressbar->rect, flags | Qt::AlignCenter | Qt::TextSingleLine, optionProgressBar.palette, + progressbar->state & State_Enabled, progressbar->text, QPalette::WindowText); + } + break; +#endif // QT_NO_PROGRESSBAR +#ifndef QT_NO_MENU + case CE_MenuItem: + if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) { + QStyleOptionMenuItem optionMenuItem = *menuItem; + + bool drawSubMenuIndicator = false; + switch(menuItem->menuItemType) { + case QStyleOptionMenuItem::Scroller: + case QStyleOptionMenuItem::Separator: + return; // no separators or scrollers in S60 menus + case QStyleOptionMenuItem::SubMenu: + drawSubMenuIndicator = true; + break; + default: + break; + } + const bool enabled = optionMenuItem.state & State_Enabled; + const bool checkable = optionMenuItem.checkType != QStyleOptionMenuItem::NotCheckable; + + uint text_flags = Qt::AlignLeading | Qt::TextShowMnemonic | Qt::TextDontClip + | Qt::TextSingleLine | Qt::AlignVCenter; + if (!styleHint(SH_UnderlineShortcut, menuItem, widget)) + text_flags |= Qt::TextHideMnemonic; + + QRect iconRect = + subElementRect(SE_ItemViewItemDecoration, &optionMenuItem, widget); + QRect textRect = subElementRect(SE_ItemViewItemText, &optionMenuItem, widget); + + if ((option->state & State_Selected) && (option->state & State_Enabled)) + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags); + + //todo: move the vertical spacing stuff into subElementRect + const int vSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing); + if (checkable){ + QStyleOptionMenuItem optionCheckBox; + optionCheckBox.QStyleOption::operator=(*menuItem); + optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth)); + optionCheckBox.rect.setHeight(pixelMetric(PM_IndicatorHeight)); + const int moveByX = optionCheckBox.rect.width()+vSpacing; + if (optionMenuItem.direction == Qt::LeftToRight) { + textRect.translate(moveByX,0); + iconRect.translate(moveByX, 0); + iconRect.setWidth(iconRect.width()+vSpacing); + textRect.setWidth(textRect.width()-moveByX-vSpacing); + } else { + textRect.setWidth(textRect.width()-moveByX); + iconRect.setWidth(iconRect.width()+vSpacing); + iconRect.translate(-optionCheckBox.rect.width()-vSpacing, 0); + optionCheckBox.rect.translate(textRect.width()+iconRect.width(),0); + } + drawPrimitive(PE_IndicatorMenuCheckMark, &optionCheckBox, painter, widget); + } + //draw icon and/or checkState + QPixmap pix = menuItem->icon.pixmap(pixelMetric(PM_SmallIconSize), + enabled ? QIcon::Normal : QIcon::Disabled); + const bool itemWithIcon = !pix.isNull(); + if (itemWithIcon) { + drawItemPixmap(painter, iconRect, text_flags, pix); + if (optionMenuItem.direction == Qt::LeftToRight) + textRect.translate(vSpacing,0); + else + textRect.translate(-vSpacing,0); + textRect.setWidth(textRect.width()-vSpacing); + } + + //draw indicators + if (drawSubMenuIndicator) { + QStyleOptionMenuItem arrowOptions; + arrowOptions.QStyleOption::operator=(*menuItem); + const int indicatorWidth = (pixelMetric(PM_ListViewIconSize, option, widget)>>1) + + pixelMetric(QStyle::PM_LayoutVerticalSpacing, option, widget); + if (optionMenuItem.direction == Qt::LeftToRight) + arrowOptions.rect.setLeft(textRect.right()); + arrowOptions.rect.setWidth(indicatorWidth); + //by default sub menu indicator in S60 points to east,so here icon + // direction is set to north (and south when in RightToLeft) + const QS60StylePrivate::SkinElementFlag arrowDirection = (arrowOptions.direction == Qt::LeftToRight) ? + QS60StylePrivate::SF_PointNorth : QS60StylePrivate::SF_PointSouth; + QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnIndiSubMenu, painter, arrowOptions.rect, + (flags | QS60StylePrivate::SF_ColorSkinned | arrowDirection)); + } + + //draw text + if (!enabled){ + //In s60, if something becomes disabled, it is removed from menu, so no native look-alike available. + optionMenuItem.palette.setColor(QPalette::Disabled, QPalette::Text, QS60StylePrivate::lighterColor( + optionMenuItem.palette.color(QPalette::Disabled, QPalette::Text))); + painter->save(); + painter->setOpacity(0.5); + } + QCommonStyle::drawItemText(painter, textRect, text_flags, + optionMenuItem.palette, enabled, + optionMenuItem.text, QPalette::Text); + if (!enabled) + painter->restore(); + } + break; + case CE_MenuEmptyArea: + break; +#endif //QT_NO_MENU + +#ifndef QT_NO_MENUBAR + case CE_MenuBarEmptyArea: + break; +#endif //QT_NO_MENUBAR + + case CE_HeaderSection: + if ( const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { + painter->save(); + QPen linePen = QPen(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 1, header)); + const int penWidth = (header->orientation == Qt::Horizontal) ? + linePen.width()+QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth) + : linePen.width()+QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth); + linePen.setWidth(penWidth); + painter->setPen(linePen); + if (header->orientation == Qt::Horizontal){ + painter->drawLine(header->rect.bottomLeft(), header->rect.bottomRight()); + } else { + if ( header->direction == Qt::LeftToRight ) { + painter->drawLine(header->rect.topRight(), header->rect.bottomRight()); + } else { + painter->drawLine(header->rect.topLeft(), header->rect.bottomLeft()); + } + } + painter->restore(); + } + break; + case CE_HeaderEmptyArea: // no need to draw this + break; + case CE_Header: + if ( const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { + drawControl(CE_HeaderSection, header, painter, widget); + QStyleOptionHeader subopt = *header; + subopt.rect = subElementRect(SE_HeaderLabel, header, widget); + if (subopt.rect.isValid()) + drawControl(CE_HeaderLabel, &subopt, painter, widget); + if (header->sortIndicator != QStyleOptionHeader::None) { + subopt.rect = subElementRect(SE_HeaderArrow, option, widget); + drawPrimitive(PE_IndicatorHeaderArrow, &subopt, painter, widget); + } + } + break; +#ifndef QT_NO_TOOLBAR + case CE_ToolBar: + if (const QStyleOptionToolBar *toolBar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) { + const QToolBar *tbWidget = qobject_cast<const QToolBar *>(widget); + + //toolbar within a toolbar, skip + if (!tbWidget || (widget && qobject_cast<QToolBar *>(widget->parentWidget()))) + break; + + // Normally in S60 5.0+ there is no background for toolbar, but in some cases with versatile QToolBar, + // it looks a bit strange. So, lets fillRect with Button. + if (!QS60StylePrivate::isToolBarBackground()) { + QList<QAction *> actions = tbWidget->actions(); + bool justToolButtonsInToolBar = true; + for (int i = 0; i < actions.size(); ++i) { + QWidget *childWidget = tbWidget->widgetForAction(actions.at(i)); + const QToolButton *button = qobject_cast<const QToolButton *>(childWidget); + if (!button){ + justToolButtonsInToolBar = false; + } + } + + // Draw frame background + // for vertical toolbars with text only and + // for toolbars with extension buttons and + // for toolbars with widgets in them. + if (!justToolButtonsInToolBar || + (tbWidget && + (tbWidget->orientation() == Qt::Vertical) && + (tbWidget->toolButtonStyle() == Qt::ToolButtonTextOnly))) { + painter->save(); + if (widget) + painter->setBrush(widget->palette().button()); + painter->setOpacity(0.3); + painter->fillRect(toolBar->rect, painter->brush()); + painter->restore(); + } + } else { + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBar, painter, toolBar->rect, flags); + } + } + break; +#endif //QT_NO_TOOLBAR + case CE_ShapedFrame: + if (qobject_cast<const QTextEdit *>(widget)) { + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_Editor, painter, option->rect, flags); + } else if (qobject_cast<const QTableView *>(widget)) { + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_TableItem, painter, option->rect, flags); + } else if (const QHeaderView *header = qobject_cast<const QHeaderView *>(widget)) { + if (header->orientation() == Qt::Horizontal) { + QRect headerRect = option->rect; + const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); + headerRect.adjust(0,frameWidth,-2*frameWidth,0); + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_TableHeaderItem, painter, headerRect, flags); + } else { + //todo: update to horizontal table graphic + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_TableHeaderItem, painter, option->rect, flags | QS60StylePrivate::SF_PointWest); + } + } + if (option->state & State_HasFocus) + drawPrimitive(PE_FrameFocusRect, option, painter, widget); + break; + case CE_MenuScroller: + break; + default: + QCommonStyle::drawControl(element, option, painter, widget); + } +} + +/*! + \reimp +*/ +void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const +{ + const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled; + switch (element) { +#ifndef QT_NO_LINEEDIT + case PE_PanelLineEdit: + if (const QStyleOptionFrame *lineEdit = qstyleoption_cast<const QStyleOptionFrame *>(option)) { +#ifndef QT_NO_COMBOBOX + if (widget && qobject_cast<const QComboBox *>(widget->parentWidget())) + break; +#endif + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_FrameLineEdit, + painter, option->rect, flags); + + if (lineEdit->state & State_HasFocus) + drawPrimitive(PE_FrameFocusRect, lineEdit, painter, widget); + } + break; +#endif // QT_NO_LINEEDIT + case PE_IndicatorCheckBox: + { + const QRect indicatorRect = option->rect; + // Draw checkbox indicator as color skinned graphics. + const QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ? + QS60StyleEnums::SP_QgnIndiCheckboxOn : QS60StyleEnums::SP_QgnIndiCheckboxOff; + QS60StylePrivate::drawSkinPart(skinPart, painter, indicatorRect, + (flags | QS60StylePrivate::SF_ColorSkinned)); + } + break; + case PE_IndicatorViewItemCheck: +#ifndef QT_NO_ITEMVIEWS + if (const QListView *listItem = (qobject_cast<const QListView *>(widget))) { + if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) { + const bool checkBoxVisible = vopt->features & QStyleOptionViewItemV2::HasCheckIndicator; + const bool singleSelection = listItem->selectionMode() == + QAbstractItemView::SingleSelection || listItem->selectionMode() == QAbstractItemView::NoSelection; + // draw either checkbox at the beginning + if (checkBoxVisible && singleSelection) { + drawPrimitive(PE_IndicatorCheckBox, option, painter, widget); + // ... or normal "tick" selection at the end. + } else if (option->state & QStyle::State_Selected) { + QRect tickRect = option->rect; + const int frameBorderWidth = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth); + // adjust tickmark rect to exclude frame border + tickRect.adjust(0,-frameBorderWidth,0,-frameBorderWidth); + QS60StyleEnums::SkinParts skinPart = QS60StyleEnums::SP_QgnIndiMarkedAdd; + QS60StylePrivate::drawSkinPart(skinPart, painter, tickRect, + (flags | QS60StylePrivate::SF_ColorSkinned)); + } + } + } +#endif //QT_NO_ITEMVIEWS + break; + case PE_IndicatorRadioButton: { + QRect buttonRect = option->rect; + //there is empty (a. 33%) space in svg graphics for radiobutton + const qreal reduceWidth = (qreal)buttonRect.width()/3.0; + const qreal rectWidth = (qreal)option->rect.width() != 0 ? option->rect.width() : 1.0; + // Try to occupy the full area + const qreal scaler = 1 + (reduceWidth/rectWidth); + buttonRect.setWidth((int)((buttonRect.width()-reduceWidth) * scaler)); + buttonRect.setHeight((int)(buttonRect.height() * scaler)); + // move the rect up for half of the new height-gain + const int newY = (buttonRect.bottomRight().y() - option->rect.bottomRight().y()) >> 1 ; + buttonRect.adjust(0,-newY,0,-newY); + + // Draw radiobutton indicator as color skinned graphics. + QS60StyleEnums::SkinParts skinPart = (option->state & QStyle::State_On) ? + QS60StyleEnums::SP_QgnIndiRadiobuttOn : QS60StyleEnums::SP_QgnIndiRadiobuttOff; + QS60StylePrivate::drawSkinPart(skinPart, painter, buttonRect, + (flags | QS60StylePrivate::SF_ColorSkinned)); + } + break; + case PE_PanelButtonCommand: + case PE_PanelButtonTool: + case PE_PanelButtonBevel: + case PE_FrameButtonBevel: { + const bool isPressed = option->state & QStyle::State_Sunken; + const QS60StylePrivate::SkinElements skinElement = + isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal; + QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags); + } + break; +#ifndef QT_NO_TOOLBUTTON + case PE_IndicatorArrowDown: + case PE_IndicatorArrowLeft: + case PE_IndicatorArrowRight: + case PE_IndicatorArrowUp: { + QS60StyleEnums::SkinParts skinPart; + if (element==PE_IndicatorArrowDown) + skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowDown; + else if (element==PE_IndicatorArrowLeft) + skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowLeft; + else if (element==PE_IndicatorArrowRight) + skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowRight; + else if (element==PE_IndicatorArrowUp) + skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowUp; + + QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags); + } + break; +#endif //QT_NO_TOOLBUTTON +#ifndef QT_NO_SPINBOX + case PE_IndicatorSpinDown: + case PE_IndicatorSpinUp: + if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { + QStyleOptionSpinBox optionSpinBox = *spinBox; + const QS60StyleEnums::SkinParts part = (element == PE_IndicatorSpinUp) ? + QS60StyleEnums::SP_QgnGrafScrollArrowUp : + QS60StyleEnums::SP_QgnGrafScrollArrowDown; + const int adjustment = qMin(optionSpinBox.rect.width(), optionSpinBox.rect.height())/6; + optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment ); + QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect,flags); + } +#ifndef QT_NO_COMBOBOX + else if (const QStyleOptionFrame *cmb = qstyleoption_cast<const QStyleOptionFrame *>(option)) { + // We want to draw down arrow here for comboboxes as well. + const QS60StyleEnums::SkinParts part = QS60StyleEnums::SP_QgnGrafScrollArrowDown; + QStyleOptionFrame comboBox = *cmb; + const int adjustment = qMin(comboBox.rect.width(), comboBox.rect.height())/6; + comboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment ); + QS60StylePrivate::drawSkinPart(part, painter, comboBox.rect,flags); + } +#endif //QT_NO_COMBOBOX + break; + case PE_IndicatorSpinMinus: + case PE_IndicatorSpinPlus: + if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { + QStyleOptionSpinBox optionSpinBox = *spinBox; + QCommonStyle::drawPrimitive(element, &optionSpinBox, painter, widget); + } +#ifndef QT_NO_COMBOBOX + else if (const QStyleOptionFrame *cmb = qstyleoption_cast<const QStyleOptionFrame *>(option)) { + // We want to draw down arrow here for comboboxes as well. + QStyleOptionFrame comboBox = *cmb; + const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); + comboBox.rect.adjust(0,frameWidth,0,-frameWidth); + QCommonStyle::drawPrimitive(element, &comboBox, painter, widget); + } +#endif //QT_NO_COMBOBOX + break; +#endif //QT_NO_SPINBOX + case PE_FrameFocusRect: +// Calendar widget and combox both do not use styled itemDelegate + if (widget && !(false +#ifndef QT_NO_CALENDARWIDGET + || qobject_cast<const QCalendarWidget *>(widget->parent()) +#endif //QT_NO_CALENDARWIDGET +#ifndef QT_NO_COMBOBOX + || qobject_cast<const QComboBoxListView *>(widget) +#endif //QT_NO_COMBOBOX + )) { + // no focus selection for touch + if (option->state & State_HasFocus && !QS60StylePrivate::isTouchSupported()) { + painter->save(); + const int penWidth = QS60StylePrivate::focusRectPenWidth(); +#ifdef QT_KEYPAD_NAVIGATION + const Qt::PenStyle penStyle = widget->hasEditFocus() ? Qt::SolidLine :Qt::DotLine; + const qreal opacity = widget->hasEditFocus() ? 0.6 : 0.4; +#else + const Qt::PenStyle penStyle = Qt::SolidLine; + const qreal opacity = 0.5; +#endif + painter->setPen(QPen(option->palette.color(QPalette::Text), penWidth, penStyle)); + painter->setRenderHint(QPainter::Antialiasing); + painter->setOpacity(opacity); + // Because of Qts coordinate system, we need to tweak the rect by .5 pixels, otherwise it gets blurred. + const qreal rectAdjustment = penWidth % 2?.5:0; + // Also we try to stay inside the option->rect, with penWidth > 1. Therefore these +1/-1 + const QRectF adjustedRect = QRectF(option->rect).adjusted( + rectAdjustment + penWidth - 1, + rectAdjustment + penWidth - 1, + -rectAdjustment - penWidth + 1, + -rectAdjustment - penWidth + 1); + painter->drawRoundedRect(adjustedRect, penWidth * 1.5, penWidth * 1.5); + painter->restore(); + } + } + break; + case PE_Widget: + if (QS60StylePrivate::drawsOwnThemeBackground(widget) +#ifndef QT_NO_COMBOBOX + || qobject_cast<const QComboBoxListView *>(widget) +#endif //QT_NO_COMBOBOX +#ifndef QT_NO_MENU + || qobject_cast<const QMenu *> (widget) +#endif //QT_NO_MENU + ) { + QS60StylePrivate::SkinElements skinElement = QS60StylePrivate::SE_OptionsMenu; + QS60StylePrivate::drawSkinElement(skinElement, painter, option->rect, flags); + } + break; + case PE_FrameWindow: + case PE_FrameTabWidget: + if (const QStyleOptionTabWidgetFrame *tabFrame = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) { + QStyleOptionTabWidgetFrame optionTabFrame = *tabFrame; + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_PanelBackground, painter, optionTabFrame.rect, flags); + } + break; + case PE_IndicatorHeaderArrow: + if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { + if (header->sortIndicator & QStyleOptionHeader::SortUp) + drawPrimitive(PE_IndicatorArrowUp, header, painter, widget); + else if (header->sortIndicator & QStyleOptionHeader::SortDown) + drawPrimitive(PE_IndicatorArrowDown, header, painter, widget); + } // QStyleOptionHeader::None is not drawn => not needed + break; +#ifndef QT_NO_GROUPBOX + case PE_FrameGroupBox: + if (const QStyleOptionFrameV2 *frame = qstyleoption_cast<const QStyleOptionFrameV2 *>(option)) + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_SettingsList, painter, frame->rect, flags); + break; +#endif //QT_NO_GROUPBOX + + // Qt3 primitives are not supported + case PE_Q3CheckListController: + case PE_Q3CheckListExclusiveIndicator: + case PE_Q3CheckListIndicator: + case PE_Q3DockWindowSeparator: + case PE_Q3Separator: + Q_ASSERT(false); + break; + case PE_Frame: + if (const QStyleOptionFrameV3 *frame = qstyleoption_cast<const QStyleOptionFrameV3 *>(option)) + drawPrimitive(PE_FrameFocusRect, frame, painter, widget); + break; +#ifndef QT_NO_ITEMVIEWS + case PE_PanelItemViewItem: + case PE_PanelItemViewRow: // ### Qt 5: remove + break; +#endif //QT_NO_ITEMVIEWS + + case PE_IndicatorMenuCheckMark: + if (const QStyleOptionMenuItem *checkBox = qstyleoption_cast<const QStyleOptionMenuItem *>(option)){ + QStyleOptionMenuItem optionCheckBox = *checkBox; + if (optionCheckBox.checked) + optionCheckBox.state = (optionCheckBox.state | State_On); + drawPrimitive(PE_IndicatorCheckBox, &optionCheckBox, painter, widget); + } + break; +#ifndef QT_NO_TOOLBAR + case PE_IndicatorToolBarHandle: + // no toolbar handles in S60/AVKON UI + case PE_IndicatorToolBarSeparator: + // no separators in S60/AVKON UI + break; +#endif //QT_NO_TOOLBAR + + case PE_PanelMenuBar: + case PE_FrameMenu: + break; //disable frame in menu + + case PE_IndicatorBranch: +#if defined(Q_WS_S60) + // 3.1 AVKON UI does not have tree view component, use common style for drawing there + if (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1) { +#else + if (true) { +#endif + QCommonStyle::drawPrimitive(element, option, painter, widget); + } else { + const bool rightLine = option->state & State_Item; + const bool downLine = option->state & State_Sibling; + const bool upLine = option->state & (State_Open | State_Children | State_Item | State_Sibling); + + QS60StyleEnums::SkinParts skinPart; + bool drawSkinPart = false; + if (rightLine && downLine && upLine) { + skinPart = QS60StyleEnums::SP_QgnIndiHlLineBranch; + drawSkinPart = true; + } else if (rightLine && upLine) { + skinPart = QS60StyleEnums::SP_QgnIndiHlLineEnd; + drawSkinPart = true; + } else if (upLine && downLine) { + skinPart = QS60StyleEnums::SP_QgnIndiHlLineStraight; + drawSkinPart = true; + } + + if ( drawSkinPart ) + QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags); + + if (option->state & State_Children) { + QS60StyleEnums::SkinParts skinPart = + (option->state & State_Open) ? QS60StyleEnums::SP_QgnIndiHlColSuper : QS60StyleEnums::SP_QgnIndiHlExpSuper; + int minDimension = qMin(option->rect.width(), option->rect.height()); + const int resizeValue = minDimension >> 1; + minDimension += resizeValue; // Adjust the icon bigger because of empty space in svg icon. + QRect iconRect(option->rect.topLeft(), QSize(minDimension, minDimension)); + int verticalMagic(0); + // magic values for positioning svg icon. + if (option->rect.width() <= option->rect.height()) + verticalMagic = 3; + iconRect.translate(3, verticalMagic - resizeValue); + QS60StylePrivate::drawSkinPart(skinPart, painter, iconRect, flags); + } + } + break; + + // todo: items are below with #ifdefs "just in case". in final version, remove all non-required cases + case PE_FrameLineEdit: + case PE_IndicatorButtonDropDown: + case PE_IndicatorDockWidgetResizeHandle: + case PE_PanelTipLabel: + case PE_PanelScrollAreaCorner: + +#ifndef QT_NO_TABBAR + case PE_IndicatorTabTear: // No tab tear in S60 +#endif // QT_NO_TABBAR + case PE_FrameDefaultButton: +#ifndef QT_NO_DOCKWIDGET + case PE_FrameDockWidget: +#endif //QT_NO_DOCKWIDGET +#ifndef QT_NO_PROGRESSBAR + case PE_IndicatorProgressChunk: +#endif //QT_NO_PROGRESSBAR +#ifndef QT_NO_TOOLBAR + case PE_PanelToolBar: +#endif //QT_NO_TOOLBAR +#ifndef QT_NO_COLUMNVIEW + case PE_IndicatorColumnViewArrow: + case PE_IndicatorItemViewItemDrop: +#endif //QT_NO_COLUMNVIEW + case PE_FrameTabBarBase: // since tabs are in S60 always in navipane, let's use common style for tab base in Qt. + default: + QCommonStyle::drawPrimitive(element, option, painter, widget); + } +} + +/*! \reimp */ +int QS60Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const +{ + int metricValue = QS60StylePrivate::pixelMetric(metric); + if (metricValue == KNotFound) + metricValue = QCommonStyle::pixelMetric(metric, option, widget); + + if (metric == PM_SubMenuOverlap && widget){ + const QMenu *menu = qobject_cast<const QMenu *>(widget); + if (menu && menu->activeAction() && menu->activeAction()->menu()) { + const int menuWidth = menu->activeAction()->menu()->sizeHint().width(); + metricValue = -menuWidth; + } + } + return metricValue; +} + +/*! \reimp */ +QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, + const QSize &csz, const QWidget *widget) const +{ + QSize sz(csz); + switch (ct) { + case CT_PushButton: + sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); + if (const QAbstractButton *buttonWidget = (qobject_cast<const QAbstractButton *>(widget))) + if (buttonWidget->isCheckable()) + sz += QSize(pixelMetric(PM_IndicatorWidth) + pixelMetric(PM_CheckBoxLabelSpacing), 0); + break; + case CT_LineEdit: + if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) + sz += QSize(2*f->lineWidth, 4*f->lineWidth); + break; + default: + sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); + break; + } + return sz; +} + +/*! \reimp */ +int QS60Style::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *widget, + QStyleHintReturn *hret) const +{ + int retValue = -1; + switch (sh) { + case SH_Table_GridLineColor: + retValue = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors,2,0).rgb(); + break; + case SH_GroupBox_TextLabelColor: + retValue = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors,6,0).rgb(); + break; + case SH_ScrollBar_ScrollWhenPointerLeavesControl: + retValue = true; + break; + case SH_Slider_SnapToValue: + retValue = true; + break; + case SH_Slider_StopMouseOverSlider: + retValue = true; + break; + case SH_LineEdit_PasswordCharacter: + retValue = '*'; + break; + case SH_ComboBox_PopupFrameStyle: + retValue = QFrame::NoFrame | QFrame::Plain; + break; + case SH_Dial_BackgroundRole: + retValue = QPalette::Base; + break; + case SH_ItemView_ActivateItemOnSingleClick: + retValue = true; + break; + case SH_ProgressDialog_TextLabelAlignment: + retValue = (QApplication::layoutDirection() == Qt::LeftToRight) ? + Qt::AlignLeft : + Qt::AlignRight; + break; + case SH_Menu_SubMenuPopupDelay: + retValue = 300; + break; + case SH_Menu_Scrollable: + retValue = true; + break; + case SH_Menu_SelectionWrap: + retValue = true; + break; + case SH_ItemView_ShowDecorationSelected: + retValue = true; + break; + case SH_ToolBar_Movable: + retValue = false; + break; + case SH_BlinkCursorWhenTextSelected: + retValue = true; + break; + case SH_UnderlineShortcut: + retValue = 0; + break; + default: + break; + } + if (retValue == -1) + retValue = QCommonStyle::styleHint(sh, opt, widget, hret); + return retValue; +} + +/*! \reimp */ +QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComplex *option, SubControl scontrol, const QWidget *widget) const +{ + QRect ret; + switch (control) { +#ifndef QT_NO_SCROLLBAR + // This implementation of subControlRect(CC_ScrollBar..) basically just removes the SC_ScrollBarSubLine and SC_ScrollBarAddLine + case CC_ScrollBar: + if (const QStyleOptionSlider *scrollbarOption = qstyleoption_cast<const QStyleOptionSlider *>(option)) { + const QRect scrollBarRect = scrollbarOption->rect; + const bool isHorizontal = scrollbarOption->orientation == Qt::Horizontal; + const int maxlen = isHorizontal ? scrollBarRect.width() : scrollBarRect.height(); + int sliderlen; + + // calculate slider length + if (scrollbarOption->maximum != scrollbarOption->minimum) { + const uint range = scrollbarOption->maximum - scrollbarOption->minimum; + sliderlen = (qint64(scrollbarOption->pageStep) * maxlen) / (range + scrollbarOption->pageStep); + + const int slidermin = pixelMetric(PM_ScrollBarSliderMin, scrollbarOption, widget); + if (sliderlen < slidermin || range > (INT_MAX>>1)) + sliderlen = slidermin; + if (sliderlen > maxlen) + sliderlen = maxlen; + } else { + sliderlen = maxlen; + } + + const int sliderstart = sliderPositionFromValue(scrollbarOption->minimum, + scrollbarOption->maximum, + scrollbarOption->sliderPosition, + maxlen - sliderlen, + scrollbarOption->upsideDown); + + switch (scontrol) { + case SC_ScrollBarSubPage: // between top/left button and slider + if (isHorizontal) + ret.setRect(0, 0, sliderstart, scrollBarRect.height()); + else + ret.setRect(0, 0, scrollBarRect.width(), sliderstart); + break; + case SC_ScrollBarAddPage: { // between bottom/right button and slider + const int addPageLength = sliderstart + sliderlen; + if (isHorizontal) + ret = scrollBarRect.adjusted(addPageLength, 0, 0, 0); + else + ret = scrollBarRect.adjusted(0, addPageLength, 0, 0); + } + break; + case SC_ScrollBarGroove: + ret = scrollBarRect; + break; + case SC_ScrollBarSlider: + if (scrollbarOption->orientation == Qt::Horizontal) + ret.setRect(sliderstart, 0, sliderlen, scrollBarRect.height()); + else + ret.setRect(0, sliderstart, scrollBarRect.width(), sliderlen); + break; + case SC_ScrollBarSubLine: // top/left button + case SC_ScrollBarAddLine: // bottom/right button + default: + break; + } + ret = visualRect(scrollbarOption->direction, scrollBarRect, ret); + } + break; +#endif // QT_NO_SCROLLBAR + case CC_SpinBox: + if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { + const int frameThickness = spinbox->frame ? pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0; + const int buttonMargin = spinbox->frame ? 2 : 0; + const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize) + 2*buttonMargin; + QSize buttonSize; + buttonSize.setHeight(qMax(8, spinbox->rect.height() - frameThickness)); + buttonSize.setWidth(buttonWidth); + buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); + + const int y = frameThickness + spinbox->rect.y(); + const int x = spinbox->rect.x() + spinbox->rect.width() - frameThickness - 2*buttonSize.width(); + + switch (scontrol) { + case SC_SpinBoxUp: + if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) + return QRect(); + ret = QRect(x, y, buttonWidth, buttonSize.height()); + break; + case SC_SpinBoxDown: + if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) + return QRect(); + ret = QRect(x+buttonSize.width(), y, buttonWidth, buttonSize.height()); + break; + case SC_SpinBoxEditField: + if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) + ret = QRect( + frameThickness, + frameThickness, + spinbox->rect.width() - 2*frameThickness, + spinbox->rect.height() - 2*frameThickness); + else + ret = QRect( + frameThickness, + frameThickness, + x - frameThickness, + spinbox->rect.height() - 2*frameThickness); + break; + case SC_SpinBoxFrame: + ret = spinbox->rect; + break; + default: + break; + } + ret = visualRect(spinbox->direction, spinbox->rect, ret); + } + break; + case CC_ComboBox: + if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { + ret = cmb->rect; + const int width = cmb->rect.width(); + const int height = cmb->rect.height(); + const int buttonMargin = cmb->frame ? 2 : 0; + // lets use spinbox frame here as well, as no combobox specific value available. + const int frameThickness = cmb->frame ? pixelMetric(PM_SpinBoxFrameWidth, cmb, widget) : 0; + const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize); + const int xposMod = (cmb->rect.x()) + width - buttonMargin - buttonWidth; + const int ypos = cmb->rect.y(); + + QSize buttonSize; + buttonSize.setHeight(qMax(8, (cmb->rect.height()>>1) - frameThickness)); //minimum of 8 pixels + buttonSize.setWidth(buttonWidth+2*buttonMargin); + buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); + switch (scontrol) { + case SC_ComboBoxArrow: + ret.setRect(xposMod, ypos + buttonMargin, buttonWidth, height - 2*buttonMargin); + break; + case SC_ComboBoxEditField: { + const int withFrameX = cmb->rect.x() + cmb->rect.width() - frameThickness - buttonSize.width(); + ret = QRect( + frameThickness, + frameThickness, + withFrameX - frameThickness, + cmb->rect.height() - 2*frameThickness); + } + break; + default: + break; + } + } + break; + case CC_GroupBox: + if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) { + ret = QCommonStyle::subControlRect(control, option, scontrol, widget); + switch (scontrol) { + case SC_GroupBoxCheckBox: //fallthrough + case SC_GroupBoxLabel: { + //slightly indent text and boxes, so that dialog border does not mess with them. + const int horizontalSpacing = + QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing); + ret.adjust(2,horizontalSpacing-3,0,0); + } + break; + case SC_GroupBoxFrame: { + const QRect textBox = subControlRect(control, option, SC_GroupBoxLabel, widget); + const int tbHeight = textBox.height(); + ret.translate(0, -ret.y()); + // include title to within the groupBox frame + ret.setHeight(ret.height()+tbHeight); + if (widget && ret.bottom() > widget->rect().bottom()) + ret.setBottom(widget->rect().bottom()); + } + break; + default: + break; + } + } + break; + default: + ret = QCommonStyle::subControlRect(control, option, scontrol, widget); + } + return ret; +} + +QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, const QWidget *widget) const +{ + QRect ret; + switch (element) { + case SE_LineEditContents: { + // in S60 the input text box doesn't start from line Edit's TL, but + // a bit indented. + QRect lineEditRect = opt->rect; + const int adjustment = opt->rect.height()>>2; + lineEditRect.adjust(adjustment,0,0,0); + ret = lineEditRect; + } + break; + case SE_TabBarTearIndicator: + ret = QRect(0,0,0,0); + break; + case SE_TabWidgetTabBar: + if (const QStyleOptionTabWidgetFrame *optionTab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) { + ret = QCommonStyle::subElementRect(element, opt, widget); + + if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) { + const int tabOverlapNoBorder = + QS60StylePrivate::pixelMetric(QStyle::PM_TabBarTabOverlap); + const int tabOverlap = + tabOverlapNoBorder-QS60StylePrivate::pixelMetric(QStyle::PM_DefaultFrameWidth); + const QTabWidget *tab = qobject_cast<const QTabWidget *>(widget); + int gain = (tab) ? tabOverlap * tab->count() : 0; + switch (twf->shape) { + case QTabBar::RoundedNorth: + case QTabBar::TriangularNorth: + case QTabBar::RoundedSouth: + case QTabBar::TriangularSouth: { + if (widget) { + // make sure that gain does not set the rect outside of widget boundaries + if (twf->direction == Qt::RightToLeft) { + if ((ret.left() - gain) < widget->rect().left()) + gain = widget->rect().left()-ret.left(); + ret.adjust(-gain,0,0,0); + } else { + if ((ret.right() + gain) > widget->rect().right()) + gain = widget->rect().right()-ret.right(); + ret.adjust(0,0,gain,0); + } + } + break; + } + default: { + if (widget) { + if ((ret.bottom() + gain) > widget->rect().bottom()) + gain = widget->rect().bottom()-ret.bottom(); + ret.adjust(0,0,0,gain); + } + break; + } + } + } + } + break; + case SE_ItemViewItemText: + case SE_ItemViewItemDecoration: + if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) { + const QListWidget *listItem = qobject_cast<const QListWidget *>(widget); + const bool multiSelection = !listItem ? false : + listItem->selectionMode() == QAbstractItemView::MultiSelection || + listItem->selectionMode() == QAbstractItemView::ExtendedSelection || + listItem->selectionMode() == QAbstractItemView::ContiguousSelection; + ret = QCommonStyle::subElementRect(element, opt, widget); + // If both multiselect & check-state, then remove checkbox and move + // text and decoration towards the beginning + if (listItem && + multiSelection && + (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator)) { + const int verticalSpacing = + QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing); + //const int horizontalSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing); + const int checkBoxRectWidth = subElementRect(SE_ItemViewItemCheckIndicator, opt, widget).width(); + ret.adjust(-checkBoxRectWidth-verticalSpacing,0,-checkBoxRectWidth-verticalSpacing,0); + } + } else if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) { + const bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable; + const int indicatorWidth = checkable ? + pixelMetric(PM_ListViewIconSize, opt, widget) : + pixelMetric(PM_SmallIconSize, opt, widget); + ret = menuItem->rect; + + if (element == SE_ItemViewItemDecoration) { + if (menuItem->direction == Qt::RightToLeft) + ret.translate(ret.width()-indicatorWidth, 0); + ret.setWidth(indicatorWidth); + } else { + ret = menuItem->rect; + if (!menuItem->icon.isNull()) + if (menuItem->direction == Qt::LeftToRight) + ret.adjust(indicatorWidth, 0, 0, 0); + else + ret.adjust(0, 0, -indicatorWidth, 0); + + // Make room for submenu indicator + if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu){ + // submenu indicator is very small, so lets halve the rect + if (menuItem->direction == Qt::LeftToRight) + ret.adjust(0,0,-(indicatorWidth >> 1),0); + else + ret.adjust((indicatorWidth >> 1),0,0,0); + } + } + } + break; + case SE_ItemViewItemCheckIndicator: + if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) { + const QListWidget *listItem = qobject_cast<const QListWidget *>(widget); + + const bool singleSelection = listItem && + (listItem->selectionMode() == QAbstractItemView::SingleSelection || + listItem->selectionMode() == QAbstractItemView::NoSelection); + const bool checkBoxOnly = (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator) && + listItem && + singleSelection; + + // Selection check mark rect. + const int indicatorWidth = QS60StylePrivate::pixelMetric(QStyle::PM_IndicatorWidth); + const int indicatorHeight = QS60StylePrivate::pixelMetric(QStyle::PM_IndicatorHeight); + const int spacing = QS60StylePrivate::pixelMetric(QStyle::PM_CheckBoxLabelSpacing); + + const int itemHeight = opt->rect.height(); + int heightOffset = 0; + if (indicatorHeight < itemHeight) + heightOffset = ((itemHeight - indicatorHeight)>>1); + if (checkBoxOnly) { + // Move rect and make it slightly smaller, so that + // a) highlight border does not cross the rect + // b) in s60 list checkbox is smaller than normal checkbox + //todo; magic three + ret.setRect(opt->rect.left()+3, opt->rect.top() + heightOffset, + indicatorWidth-3, indicatorHeight-3); + } else { + ret.setRect(opt->rect.right() - indicatorWidth - spacing, opt->rect.top() + heightOffset, + indicatorWidth, indicatorHeight); + } + } else { + ret = QCommonStyle::subElementRect(element, opt, widget); + } + break; + case SE_HeaderLabel: + ret = QCommonStyle::subElementRect(element, opt, widget); + if (qstyleoption_cast<const QStyleOptionHeader *>(opt)) { + // Subtract area needed for line + if (opt->state & State_Horizontal) + ret.setHeight(ret.height() - QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth)); + else + ret.setWidth(ret.width() - QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth)); + } + ret = visualRect(opt->direction, opt->rect, ret); + break; + case SE_FrameContents: + if (QS60StylePrivate::isTouchSupported()) { + return QCommonStyle::subElementRect(element, opt, widget); + } else if (const QStyleOptionFrameV2 *f = qstyleoption_cast<const QStyleOptionFrameV2 *>(opt)) { + // We shrink the frame contents by focusFrameWidth, so that we can draw the frame around it in keypad navigation mode. + const int frameWidth = QS60StylePrivate::focusRectPenWidth(); + ret = opt->rect.adjusted(frameWidth, frameWidth, -frameWidth, -frameWidth); + ret = visualRect(opt->direction, opt->rect, ret); + } + break; + default: + ret = QCommonStyle::subElementRect(element, opt, widget); + } + return ret; +} + +void QS60Style::polish(QWidget *widget) +{ + Q_D(const QS60Style); + QCommonStyle::polish(widget); + + if (!widget) + return; + + if (false +#ifndef QT_NO_SCROLLBAR + || qobject_cast<QScrollBar *>(widget) +#endif + ) { + widget->setAttribute(Qt::WA_OpaquePaintEvent, false); + } + + if (QS60StylePrivate::drawsOwnThemeBackground(widget)) { + widget->setAttribute(Qt::WA_StyledBackground); + } else if (false +#ifndef QT_NO_MENU + || qobject_cast<const QMenu *> (widget) +#endif // QT_NO_MENU + ) { + widget->setAttribute(Qt::WA_StyledBackground); + } else if (false +#ifndef QT_NO_COMBOBOX + || qobject_cast<const QComboBoxListView *>(widget) +#endif //QT_NO_COMBOBOX + ) { + widget->setAttribute(Qt::WA_StyledBackground); + } + d->setThemePalette(widget); + d->setFont(widget); +} + +void QS60Style::unpolish(QWidget *widget) +{ + if (false + #ifndef QT_NO_SCROLLBAR + || qobject_cast<QScrollBar *>(widget) + #endif + ) + widget->setAttribute(Qt::WA_OpaquePaintEvent); + + if (QS60StylePrivate::drawsOwnThemeBackground(widget)) { + widget->setAttribute(Qt::WA_StyledBackground, false); + } else if (false +#ifndef QT_NO_MENU + || qobject_cast<const QMenu *> (widget) +#endif // QT_NO_MENU + ) { + widget->setAttribute(Qt::WA_StyledBackground, false); + } else if (false +#ifndef QT_NO_COMBOBOX + || qobject_cast<const QComboBoxListView *>(widget) +#endif //QT_NO_COMBOBOX + ) { + widget->setAttribute(Qt::WA_StyledBackground, false); + } + + if (widget) + widget->setPalette(QPalette()); + + QCommonStyle::unpolish(widget); +} + +void QS60Style::polish(QApplication *application) +{ + Q_D(QS60Style); + d->m_originalPalette = application->palette(); + d->setThemePalette(application); +} + +void QS60Style::unpolish(QApplication *application) +{ + Q_UNUSED(application) + Q_D(QS60Style); + const QPalette newPalette = QApplication::style()->standardPalette(); + QApplication::setPalette(newPalette); + QApplicationPrivate::setSystemPalette(d->m_originalPalette); +} + +void QS60Style::setStyleProperty(const char *name, const QVariant &value) +{ + Q_D(QS60Style); + d->setStyleProperty_specific(name, value); +} + +QVariant QS60Style::styleProperty(const char *name) const +{ + Q_D(const QS60Style); + return d->styleProperty_specific(name); +} + +QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon, + const QStyleOption *option, const QWidget *widget) const +{ + const int iconDimension = QS60StylePrivate::pixelMetric(QStyle::PM_ToolBarIconSize); + const QRect iconSize = (!option) ? QRect(0,0,iconDimension,iconDimension) : option->rect; + QS60StyleEnums::SkinParts part; + QS60StylePrivate::SkinElementFlags adjustedFlags; + if (option) + adjustedFlags = (option->state & State_Enabled) ? + QS60StylePrivate::SF_StateEnabled : + QS60StylePrivate::SF_StateDisabled; + + switch(standardIcon) { + case QStyle::SP_MessageBoxWarning: + part = QS60StyleEnums::SP_QgnNoteWarning; + break; + case QStyle::SP_MessageBoxInformation: + part = QS60StyleEnums::SP_QgnNoteInfo; + break; + case QStyle::SP_MessageBoxCritical: + part = QS60StyleEnums::SP_QgnNoteError; + break; + case QStyle::SP_MessageBoxQuestion: + part = QS60StyleEnums::SP_QgnNoteQuery; + break; + case QStyle::SP_ArrowRight: + part = QS60StyleEnums::SP_QgnIndiNaviArrowRight; + break; + case QStyle::SP_ArrowLeft: + part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft; + break; + case QStyle::SP_ArrowUp: + part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft; + adjustedFlags |= QS60StylePrivate::SF_PointEast; + break; + case QStyle::SP_ArrowDown: + part = QS60StyleEnums::SP_QgnIndiNaviArrowLeft; + adjustedFlags |= QS60StylePrivate::SF_PointWest; + break; + case QStyle::SP_ArrowBack: + if (QApplication::layoutDirection() == Qt::RightToLeft) + return QS60Style::standardIcon(SP_ArrowRight, option, widget); + return QS60Style::standardIcon(SP_ArrowLeft, option, widget); + case QStyle::SP_ArrowForward: + if (QApplication::layoutDirection() == Qt::RightToLeft) + return QS60Style::standardIcon(SP_ArrowLeft, option, widget); + return QS60Style::standardIcon(SP_ArrowRight, option, widget); + case QStyle::SP_ComputerIcon: + part = QS60StyleEnums::SP_QgnPropPhoneMemcLarge; + break; + case QStyle::SP_DirClosedIcon: + part = QS60StyleEnums::SP_QgnPropFolderSmall; + break; + case QStyle::SP_DirOpenIcon: + part = QS60StyleEnums::SP_QgnPropFolderCurrent; + break; + case QStyle::SP_DirIcon: + part = QS60StyleEnums::SP_QgnPropFolderSmall; + break; + case QStyle::SP_FileDialogNewFolder: + part = QS60StyleEnums::SP_QgnPropFolderSmallNew; + break; + case QStyle::SP_FileIcon: + part = QS60StyleEnums::SP_QgnPropFileSmall; + break; + case QStyle::SP_TrashIcon: + part = QS60StyleEnums::SP_QgnNoteErased; + break; + case QStyle::SP_ToolBarHorizontalExtensionButton: + part = QS60StyleEnums::SP_QgnIndiSubMenu; + if (QApplication::layoutDirection() == Qt::RightToLeft) + adjustedFlags |= QS60StylePrivate::SF_PointSouth; + break; + case QStyle::SP_ToolBarVerticalExtensionButton: + adjustedFlags |= QS60StylePrivate::SF_PointEast; + part = QS60StyleEnums::SP_QgnIndiSubMenu; + break; + + default: + return QCommonStyle::standardIconImplementation(standardIcon, option, widget); + } + const QS60StylePrivate::SkinElementFlags flags = adjustedFlags; + const QPixmap cachedPixMap(QS60StylePrivate::cachedPart(part, iconSize.size(), flags)); + return cachedPixMap.isNull() ? + QCommonStyle::standardIconImplementation(standardIcon, option, widget) : QIcon(cachedPixMap); +} + +extern QPoint qt_s60_fill_background_offset(const QWidget *targetWidget); + +bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush) +{ + const QPixmap backgroundTexture(QS60StylePrivate::backgroundTexture()); + if (backgroundTexture.cacheKey() != brush.texture().cacheKey()) + return false; + + const QPaintDevice *target = painter->device(); + if (target->devType() == QInternal::Widget) { + const QWidget *widget = static_cast<const QWidget *>(target); + const QVector<QRect> &rects = rgn.rects(); + for (int i = 0; i < rects.size(); ++i) { + const QRect rect(rects.at(i)); + painter->drawPixmap(rect.topLeft(), backgroundTexture, + rect.translated(qt_s60_fill_background_offset(widget))); + } + } + return true; +} + +QT_END_NAMESPACE + +#endif // QT_NO_STYLE_S60 || QT_PLUGIN diff --git a/src/gui/styles/qs60style.h b/src/gui/styles/qs60style.h new file mode 100644 index 0000000000..38d8e48f1a --- /dev/null +++ b/src/gui/styles/qs60style.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QS60STYLE_H +#define QS60STYLE_H + +#include <QtGui/qcommonstyle.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +#if !defined(QT_NO_STYLE_S60) + +class QS60StylePrivate; + +class Q_GUI_EXPORT QS60Style : public QCommonStyle +{ + Q_OBJECT + Q_DECLARE_SCOPED_PRIVATE(QS60Style) + +public: + QS60Style(); + ~QS60Style(); + + void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = 0) const; + void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const; + void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const; + int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const; + QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w = 0) const; + int styleHint(StyleHint sh, const QStyleOption *opt = 0, const QWidget *w = 0, + QStyleHintReturn *shret = 0) const; + QRect subControlRect(ComplexControl control, const QStyleOptionComplex *option, SubControl scontrol, const QWidget *widget = 0) const; + QRect subElementRect(SubElement element, const QStyleOption *opt, const QWidget *widget = 0) const; + void polish(QWidget *widget); + void unpolish(QWidget *widget); + void polish(QApplication *application); + void unpolish(QApplication *application); + + void setStyleProperty(const char *name, const QVariant &value); + QVariant styleProperty(const char *name) const; + +#ifndef Q_WS_S60 + static QStringList partKeys(); + static QStringList colorListKeys(); + void setS60Theme(const QHash<QString, QPicture> &parts, + const QHash<QPair<QString , int>, QColor> &colors); + bool loadS60ThemeFromBlob(const QString &blobFile); + bool saveS60ThemeToBlob(const QString &blobFile) const; +#endif // !Q_WS_S60 + +#ifdef Q_WS_S60 +public Q_SLOTS: + void handleDynamicLayoutVariantSwitch(); + void handleSkinChange(); +#endif // Q_WS_S60 + +protected Q_SLOTS: + QIcon standardIconImplementation( + StandardPixmap standardIcon, const QStyleOption * option = 0, const QWidget * widget = 0 ) const; + +private: + Q_DISABLE_COPY(QS60Style) + friend class QStyleFactory; +}; + +#endif // QT_NO_STYLE_S60 + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QS60STYLE_H diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h new file mode 100644 index 0000000000..4bf8143d41 --- /dev/null +++ b/src/gui/styles/qs60style_p.h @@ -0,0 +1,501 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QS60STYLE_P_H +#define QS60STYLE_P_H + +#include "qs60style.h" +#include "qcommonstyle_p.h" +#include <QtCore/qhash.h> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +const int MAX_NON_CUSTOM_PIXELMETRICS = 92; +const int CUSTOMVALUESCOUNT = 4; +enum { + PM_Custom_FrameCornerWidth = MAX_NON_CUSTOM_PIXELMETRICS, + PM_Custom_FrameCornerHeight, + PM_Custom_BoldLineWidth, + PM_Custom_ThinLineWidth + }; +const int MAX_PIXELMETRICS = MAX_NON_CUSTOM_PIXELMETRICS + CUSTOMVALUESCOUNT; + +typedef struct { + unsigned short height; + unsigned short width; + int major_version; + int minor_version; + bool mirroring; // TODO: (nice to have) Use Qt::LayoutDirection + const char* layoutName; +} layoutHeader; + +#ifdef Q_OS_SYMBIAN +NONSHARABLE_CLASS (QS60StyleEnums) +#else +class QS60StyleEnums +#endif +: public QObject +{ +#ifndef Q_WS_S60 + Q_OBJECT + Q_ENUMS(FontCategories) + Q_ENUMS(SkinParts) + Q_ENUMS(ColorLists) +#endif // !Q_WS_S60 + +public: + // S60 look-and-feel font categories + enum FontCategories { + FC_Undefined, + FC_Primary, + FC_Secondary, + FC_Title, + FC_PrimarySmall, + FC_Digital + }; + + enum SkinParts { + SP_QgnGrafBarWait, + SP_QgnGrafBarFrameCenter, + SP_QgnGrafBarFrameSideL, + SP_QgnGrafBarFrameSideR, + SP_QgnGrafBarProgress, + SP_QgnGrafScrollArrowDown, + SP_QgnGrafScrollArrowLeft, + SP_QgnGrafScrollArrowRight, + SP_QgnGrafScrollArrowUp, + SP_QgnGrafTabActiveL, + SP_QgnGrafTabActiveM, + SP_QgnGrafTabActiveR, + SP_QgnGrafTabPassiveL, + SP_QgnGrafTabPassiveM, + SP_QgnGrafTabPassiveR, + SP_QgnIndiCheckboxOff, + SP_QgnIndiCheckboxOn, + SP_QgnIndiHlColSuper, // Available in S60 release 3.2 and later. + SP_QgnIndiHlExpSuper, // Available in S60 release 3.2 and later. + SP_QgnIndiHlLineBranch, // Available in S60 release 3.2 and later. + SP_QgnIndiHlLineEnd, // Available in S60 release 3.2 and later. + SP_QgnIndiHlLineStraight, // Available in S60 release 3.2 and later. + SP_QgnIndiMarkedAdd, + SP_QgnIndiNaviArrowLeft, + SP_QgnIndiNaviArrowRight, + SP_QgnIndiRadiobuttOff, + SP_QgnIndiRadiobuttOn, + SP_QgnIndiSliderEdit, + SP_QgnIndiSubMenu, + SP_QgnNoteErased, + SP_QgnNoteError, + SP_QgnNoteInfo, + SP_QgnNoteOk, + SP_QgnNoteQuery, + SP_QgnNoteWarning, + SP_QgnPropFileSmall, + SP_QgnPropFolderCurrent, + SP_QgnPropFolderSmall, + SP_QgnPropFolderSmallNew, + SP_QgnPropPhoneMemcLarge, + SP_QsnCpScrollHandleBottomPressed, //ScrollBar handle, pressed state + SP_QsnCpScrollHandleMiddlePressed, + SP_QsnCpScrollHandleTopPressed, + SP_QsnBgScreen, + SP_QsnCpScrollBgBottom, + SP_QsnCpScrollBgMiddle, + SP_QsnCpScrollBgTop, + SP_QsnCpScrollHandleBottom, + SP_QsnCpScrollHandleMiddle, + SP_QsnCpScrollHandleTop, + SP_QsnFrButtonTbCornerTl, // Button, normal state + SP_QsnFrButtonTbCornerTr, + SP_QsnFrButtonTbCornerBl, + SP_QsnFrButtonTbCornerBr, + SP_QsnFrButtonTbSideT, + SP_QsnFrButtonTbSideB, + SP_QsnFrButtonTbSideL, + SP_QsnFrButtonTbSideR, + SP_QsnFrButtonTbCenter, + SP_QsnFrButtonTbCornerTlPressed, // Button, pressed state + SP_QsnFrButtonTbCornerTrPressed, + SP_QsnFrButtonTbCornerBlPressed, + SP_QsnFrButtonTbCornerBrPressed, + SP_QsnFrButtonTbSideTPressed, + SP_QsnFrButtonTbSideBPressed, + SP_QsnFrButtonTbSideLPressed, + SP_QsnFrButtonTbSideRPressed, + SP_QsnFrButtonTbCenterPressed, + SP_QsnFrCaleCornerTl, // calendar grid item + SP_QsnFrCaleCornerTr, + SP_QsnFrCaleCornerBl, + SP_QsnFrCaleCornerBr, + SP_QsnFrCaleGSideT, + SP_QsnFrCaleGSideB, + SP_QsnFrCaleGSideL, + SP_QsnFrCaleGSideR, + SP_QsnFrCaleCenter, + SP_QsnFrCaleHeadingCornerTl, // calendar grid header + SP_QsnFrCaleHeadingCornerTr, + SP_QsnFrCaleHeadingCornerBl, + SP_QsnFrCaleHeadingCornerBr, + SP_QsnFrCaleHeadingSideT, + SP_QsnFrCaleHeadingSideB, + SP_QsnFrCaleHeadingSideL, + SP_QsnFrCaleHeadingSideR, + SP_QsnFrCaleHeadingCenter, + SP_QsnFrInputCornerTl, // Text input field + SP_QsnFrInputCornerTr, + SP_QsnFrInputCornerBl, + SP_QsnFrInputCornerBr, + SP_QsnFrInputSideT, + SP_QsnFrInputSideB, + SP_QsnFrInputSideL, + SP_QsnFrInputSideR, + SP_QsnFrInputCenter, + SP_QsnFrListCornerTl, // List background + SP_QsnFrListCornerTr, + SP_QsnFrListCornerBl, + SP_QsnFrListCornerBr, + SP_QsnFrListSideT, + SP_QsnFrListSideB, + SP_QsnFrListSideL, + SP_QsnFrListSideR, + SP_QsnFrListCenter, + SP_QsnFrPopupCornerTl, // Option menu background + SP_QsnFrPopupCornerTr, + SP_QsnFrPopupCornerBl, + SP_QsnFrPopupCornerBr, + SP_QsnFrPopupSideT, + SP_QsnFrPopupSideB, + SP_QsnFrPopupSideL, + SP_QsnFrPopupSideR, + SP_QsnFrPopupCenter, + SP_QsnFrPopupPreviewCornerTl, // tool tip background + SP_QsnFrPopupPreviewCornerTr, + SP_QsnFrPopupPreviewCornerBl, + SP_QsnFrPopupPreviewCornerBr, + SP_QsnFrPopupPreviewSideT, + SP_QsnFrPopupPreviewSideB, + SP_QsnFrPopupPreviewSideL, + SP_QsnFrPopupPreviewSideR, + SP_QsnFrPopupPreviewCenter, + SP_QsnFrSetOptCornerTl, // Settings list + SP_QsnFrSetOptCornerTr, + SP_QsnFrSetOptCornerBl, + SP_QsnFrSetOptCornerBr, + SP_QsnFrSetOptSideT, + SP_QsnFrSetOptSideB, + SP_QsnFrSetOptSideL, + SP_QsnFrSetOptSideR, + SP_QsnFrSetOptCenter, + SP_QsnFrPopupSubCornerTl, // Toolbar background + SP_QsnFrPopupSubCornerTr, + SP_QsnFrPopupSubCornerBl, + SP_QsnFrPopupSubCornerBr, + SP_QsnFrPopupSubSideT, + SP_QsnFrPopupSubSideB, + SP_QsnFrPopupSubSideL, + SP_QsnFrPopupSubSideR, + SP_QsnFrPopupSubCenter, + SP_QsnFrSctrlButtonCornerTl, // Toolbar button + SP_QsnFrSctrlButtonCornerTr, + SP_QsnFrSctrlButtonCornerBl, + SP_QsnFrSctrlButtonCornerBr, + SP_QsnFrSctrlButtonSideT, + SP_QsnFrSctrlButtonSideB, + SP_QsnFrSctrlButtonSideL, + SP_QsnFrSctrlButtonSideR, + SP_QsnFrSctrlButtonCenter, + SP_QsnFrSctrlButtonCornerTlPressed, // Toolbar button, pressed + SP_QsnFrSctrlButtonCornerTrPressed, + SP_QsnFrSctrlButtonCornerBlPressed, + SP_QsnFrSctrlButtonCornerBrPressed, + SP_QsnFrSctrlButtonSideTPressed, + SP_QsnFrSctrlButtonSideBPressed, + SP_QsnFrSctrlButtonSideLPressed, + SP_QsnFrSctrlButtonSideRPressed, + SP_QsnFrSctrlButtonCenterPressed, + SP_QsnFrButtonCornerTlInactive, // Inactive button + SP_QsnFrButtonCornerTrInactive, + SP_QsnFrButtonCornerBlInactive, + SP_QsnFrButtonCornerBrInactive, + SP_QsnFrButtonSideTInactive, + SP_QsnFrButtonSideBInactive, + SP_QsnFrButtonSideLInactive, + SP_QsnFrButtonSideRInactive, + SP_QsnFrButtonCenterInactive, + SP_QsnFrNotepadCornerTl, + SP_QsnFrNotepadCornerTr, + SP_QsnFrNotepadCornerBl, + SP_QsnFrNotepadCornerBr, + SP_QsnFrNotepadSideT, + SP_QsnFrNotepadSideB, + SP_QsnFrNotepadSideL, + SP_QsnFrNotepadSideR, + SP_QsnFrNotepadCenter + }; + + enum ColorLists { + CL_QsnHighlightColors, + CL_QsnIconColors, + CL_QsnLineColors, + CL_QsnOtherColors, + CL_QsnParentColors, + CL_QsnTextColors + }; +}; + +// Private class +#ifdef Q_OS_SYMBIAN +NONSHARABLE_CLASS (QS60StylePrivate) +#else +class QS60StylePrivate +#endif +: public QCommonStylePrivate +{ + Q_DECLARE_PUBLIC(QS60Style) + +public: + QS60StylePrivate(); + ~QS60StylePrivate(); + + enum SkinElements { + SE_ButtonNormal, + SE_ButtonPressed, + SE_FrameLineEdit, + SE_ProgressBarGrooveHorizontal, + SE_ProgressBarIndicatorHorizontal, + SE_ProgressBarGrooveVertical, + SE_ProgressBarIndicatorVertical, + SE_ScrollBarGrooveHorizontal, + SE_ScrollBarGrooveVertical, + SE_ScrollBarHandleHorizontal, + SE_ScrollBarHandleVertical, + SE_SliderHandleHorizontal, + SE_SliderHandleVertical, + SE_TabBarTabEastActive, + SE_TabBarTabEastInactive, + SE_TabBarTabNorthActive, + SE_TabBarTabNorthInactive, + SE_TabBarTabSouthActive, + SE_TabBarTabSouthInactive, + SE_TabBarTabWestActive, + SE_TabBarTabWestInactive, + SE_ListHighlight, + SE_OptionsMenu, + SE_SettingsList, + SE_TableItem, + SE_TableHeaderItem, + SE_ToolTip, //own graphic available on 3.2+ releases, + SE_ToolBar, + SE_ToolBarButton, + SE_ToolBarButtonPressed, + SE_PanelBackground, + SE_ScrollBarHandlePressedHorizontal, //only for 5.0+ + SE_ScrollBarHandlePressedVertical, + SE_ButtonInactive, + SE_Editor, + }; + + enum SkinFrameElements { + SF_ButtonNormal, + SF_ButtonPressed, + SF_FrameLineEdit, + SF_ListHighlight, + SF_OptionsMenu, + SF_SettingsList, + SF_TableItem, + SF_TableHeaderItem, + SF_ToolTip, + SF_ToolBar, + SF_ToolBarButton, + SF_ToolBarButtonPressed, + SF_PanelBackground, + SF_ButtonInactive, + SF_Editor, + }; + + enum SkinElementFlag { + SF_PointNorth = 0x0001, // North = the default + SF_PointEast = 0x0002, + SF_PointSouth = 0x0004, + SF_PointWest = 0x0008, + + SF_StateEnabled = 0x0010, // Enabled = the default + SF_StateDisabled = 0x0020, + SF_ColorSkinned = 0x0040, + }; + + enum CacheClearReason { + CC_UndefinedChange = 0, + CC_LayoutChange, + CC_ThemeChange + }; + + Q_DECLARE_FLAGS(SkinElementFlags, SkinElementFlag) + + // draws skin element + static void drawSkinElement(SkinElements element, QPainter *painter, + const QRect &rect, SkinElementFlags flags = KDefaultSkinElementFlags); + // draws a specific skin part + static void drawSkinPart(QS60StyleEnums::SkinParts part, QPainter *painter, + const QRect &rect, SkinElementFlags flags = KDefaultSkinElementFlags); + // sets style property + void setStyleProperty(const char *name, const QVariant &value); + // sets specific style property + void setStyleProperty_specific(const char *name, const QVariant &value); + // gets style property + QVariant styleProperty(const char *name) const; + // gets specific style property + QVariant styleProperty_specific(const char *name) const; + // gets pixel metrics value + static short pixelMetric(int metric); + // gets color. 'index' is NOT 0-based. + // It corresponds to the enum key 1-based numbers of TAknsQsnXYZColorsIndex, not the values. + static QColor s60Color(QS60StyleEnums::ColorLists list, + int index, const QStyleOption *option); + // gets state specific color + static QColor stateColor(const QColor &color, const QStyleOption *option); + // gets lighter color than base color + static QColor lighterColor(const QColor &baseColor); + //deduces if the given widget should have separately themeable background + static bool drawsOwnThemeBackground(const QWidget *widget); + + QFont s60Font(QS60StyleEnums::FontCategories fontCategory, + int pointSize = -1) const; + // clears all style caches (fonts, colors, pixmaps) + void clearCaches(CacheClearReason reason = CC_UndefinedChange); + + // themed main background oprations + void setBackgroundTexture(QApplication *application) const; + static void deleteBackground(); + + static bool isTouchSupported(); + static bool isToolBarBackground(); + + // calculates average color based on button skin graphics (minus borders). + QColor colorFromFrameGraphics(SkinFrameElements frame) const; + + //set theme palette for application + void setThemePalette(QApplication *application) const; + //set theme palette for style option + void setThemePalette(QStyleOption *option) const; + //access to theme palette + static QPalette* themePalette(); + + static int focusRectPenWidth(); + + static const layoutHeader m_layoutHeaders[]; + static const short data[][MAX_PIXELMETRICS]; + + void setCurrentLayout(int layoutIndex); + void setActiveLayout(); + // Pointer + static short const *m_pmPointer; + // number of layouts supported by the style + static const int m_numberOfLayouts; + + mutable QHash<QPair<QS60StyleEnums::FontCategories , int>, QFont> m_mappedFontsCache; + mutable QHash<SkinFrameElements, QColor> m_colorCache; + + // Has one entry per SkinFrameElements + static const struct frameElementCenter { + SkinElements element; + QS60StyleEnums::SkinParts center; + } m_frameElementsData[]; + + static QPixmap frame(SkinFrameElements frame, const QSize &size, + SkinElementFlags flags = KDefaultSkinElementFlags); + static QPixmap backgroundTexture(); + +private: + static void drawPart(QS60StyleEnums::SkinParts part, QPainter *painter, + const QRect &rect, SkinElementFlags flags = KDefaultSkinElementFlags); + static void drawRow(QS60StyleEnums::SkinParts start, QS60StyleEnums::SkinParts middle, + QS60StyleEnums::SkinParts end, Qt::Orientation orientation, QPainter *painter, + const QRect &rect, SkinElementFlags flags = KDefaultSkinElementFlags); + static void drawFrame(SkinFrameElements frame, QPainter *painter, + const QRect &rect, SkinElementFlags flags = KDefaultSkinElementFlags); + + static QPixmap cachedPart(QS60StyleEnums::SkinParts part, const QSize &size, + SkinElementFlags flags = KDefaultSkinElementFlags); + static QPixmap cachedFrame(SkinFrameElements frame, const QSize &size, + SkinElementFlags flags = KDefaultSkinElementFlags); + + static void refreshUI(); + + // set S60 font for widget + void setFont(QWidget *widget) const; + void setThemePalette(QWidget *widget) const; + void setThemePalette(QPalette *palette) const; + void setThemePaletteHash(QPalette *palette) const; + static void storeThemePalette(QPalette *palette); + static void deleteThemePalette(); + + static QSize partSize(QS60StyleEnums::SkinParts part, + SkinElementFlags flags = KDefaultSkinElementFlags); + static QPixmap part(QS60StyleEnums::SkinParts part, const QSize &size, + SkinElementFlags flags = KDefaultSkinElementFlags); + + static QFont s60Font_specific(QS60StyleEnums::FontCategories fontCategory, int pointSize); + + static QSize screenSize(); + + // Contains background texture. + static QPixmap *m_background; + const static SkinElementFlags KDefaultSkinElementFlags; + // defined theme palette + static QPalette *m_themePalette; + QPalette m_originalPalette; +}; + +QT_END_NAMESPACE + +#endif // QS60STYLE_P_H diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp new file mode 100644 index 0000000000..f304d14877 --- /dev/null +++ b/src/gui/styles/qs60style_s60.cpp @@ -0,0 +1,1387 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qs60style.h" +#include "qs60style_p.h" +#include "qpainter.h" +#include "qstyleoption.h" +#include "qstyle.h" +#include "private/qwindowsurface_s60_p.h" +#include "private/qt_s60_p.h" +#include "private/qcore_symbian_p.h" +#include "qapplication.h" + +#include <w32std.h> +#include <aknsconstants.h> +#include <aknconsts.h> +#include <aknsitemid.h> +#include <aknsutils.h> +#include <aknsdrawutils.h> +#include <aknsskininstance.h> +#include <aknsbasicbackgroundcontrolcontext.h> +#include <avkon.mbg> +#include <AknFontAccess.h> +#include <AknLayoutFont.h> +#include <aknutils.h> + +#if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN) + +QT_BEGIN_NAMESPACE + +enum TDrawType { + EDrawIcon, + EDrawBackground, + ENoDraw +}; + +enum TSupportRelease { + ES60_None = 0x0000, //indicates that the commonstyle should draw the graphics + ES60_3_1 = 0x0001, + ES60_3_2 = 0x0002, + ES60_5_0 = 0x0004, + ES60_5_1 = 0x0008, + ES60_5_2 = 0x0010, + // Add all new releases here + ES60_AllReleases = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1 | ES60_5_2 +}; + +typedef struct { + const TAknsItemID &skinID; + TDrawType drawType; + int supportInfo; + int newMajorSkinId; + int newMinorSkinId; +} partMapEntry; + +class QS60StyleModeSpecifics +{ +public: + static QPixmap skinnedGraphics(QS60StyleEnums::SkinParts stylepart, + const QSize &size, QS60StylePrivate::SkinElementFlags flags); + static QPixmap skinnedGraphics(QS60StylePrivate::SkinFrameElements frameElement, const QSize &size, QS60StylePrivate::SkinElementFlags flags); + static QPixmap colorSkinnedGraphics(const QS60StyleEnums::SkinParts &stylepart, + const QSize &size, QS60StylePrivate::SkinElementFlags flags); + static QColor colorValue(const TAknsItemID &colorGroup, int colorIndex); + static QPixmap fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask, QS60StylePrivate::SkinElementFlags flags, QImage::Format format); + static bool disabledPartGraphic(QS60StyleEnums::SkinParts &part); + static bool disabledFrameGraphic(QS60StylePrivate::SkinFrameElements &frame); + static QPixmap generateMissingThemeGraphic(QS60StyleEnums::SkinParts &part, const QSize &size, QS60StylePrivate::SkinElementFlags flags); + +private: + static QPixmap createSkinnedGraphicsLX(QS60StyleEnums::SkinParts part, + const QSize &size, QS60StylePrivate::SkinElementFlags flags); + static QPixmap createSkinnedGraphicsLX(QS60StylePrivate::SkinFrameElements frameElement, const QSize &size, QS60StylePrivate::SkinElementFlags flags); + static QPixmap colorSkinnedGraphicsLX(const QS60StyleEnums::SkinParts &stylepart, + const QSize &size, QS60StylePrivate::SkinElementFlags flags); + static void frameIdAndCenterId(QS60StylePrivate::SkinFrameElements frameElement, TAknsItemID &frameId, TAknsItemID ¢erId); + static TRect innerRectFromElement(QS60StylePrivate::SkinFrameElements frameElement, const TRect &outerRect); + static void checkAndUnCompressBitmapL(CFbsBitmap*& aOriginalBitmap); + static void checkAndUnCompressBitmap(CFbsBitmap*& aOriginalBitmap); + static void unCompressBitmapL(const TRect& aTrgRect, CFbsBitmap* aTrgBitmap, CFbsBitmap* aSrcBitmap); + static void colorGroupAndIndex(QS60StyleEnums::SkinParts skinID, + TAknsItemID &colorGroup, int colorIndex); + static void fallbackInfo(const QS60StyleEnums::SkinParts &stylepart, TDes& fallbackFileName, TInt& fallbackIndex); + static bool checkSupport(const int supportedRelease); + static TAknsItemID checkAndUpdateReleaseSpecificGraphics(int part); + // Array to match the skin ID, fallback graphics and Qt widget graphics. + static const partMapEntry m_partMap[]; +}; + +const partMapEntry QS60StyleModeSpecifics::m_partMap[] = { + /* SP_QgnGrafBarWait */ {KAknsIIDQgnGrafBarWaitAnim, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnGrafBarFrameCenter */ {KAknsIIDQgnGrafBarFrameCenter, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnGrafBarFrameSideL */ {KAknsIIDQgnGrafBarFrameSideL, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnGrafBarFrameSideR */ {KAknsIIDQgnGrafBarFrameSideR, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnGrafBarProgress */ {KAknsIIDQgnGrafBarProgress, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnGrafScrollArrowDown */ {KAknsIIDQgnGrafScrollArrowDown, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnGrafScrollArrowLeft */ {KAknsIIDQgnGrafScrollArrowLeft, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnGrafScrollArrowRight */ {KAknsIIDQgnGrafScrollArrowRight, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnGrafScrollArrowUp */ {KAknsIIDQgnGrafScrollArrowUp, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnGrafTabActiveL */ {KAknsIIDQgnGrafTabActiveL, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnGrafTabActiveM */ {KAknsIIDQgnGrafTabActiveM, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnGrafTabActiveR */ {KAknsIIDQgnGrafTabActiveR, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnGrafTabPassiveL */ {KAknsIIDQgnGrafTabPassiveL, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnGrafTabPassiveM */ {KAknsIIDQgnGrafTabPassiveM, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnGrafTabPassiveR */ {KAknsIIDQgnGrafTabPassiveR, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnIndiCheckboxOff */ {KAknsIIDQgnIndiCheckboxOff, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnIndiCheckboxOn */ {KAknsIIDQgnIndiCheckboxOn, EDrawIcon, ES60_AllReleases, -1,-1}, + // Following 5 items (SP_QgnIndiHlColSuper - SP_QgnIndiHlLineStraight) are available starting from S60 release 3.2. + // In 3.1 CommonStyle drawing is used for these QTreeView elements, since no similar icons in AVKON UI. + /* SP_QgnIndiHlColSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d5 /* KAknsIIDQgnIndiHlColSuper */}, + /* SP_QgnIndiHlExpSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d6 /* KAknsIIDQgnIndiHlExpSuper */}, + /* SP_QgnIndiHlLineBranch */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d7 /* KAknsIIDQgnIndiHlLineBranch */}, + /* SP_QgnIndiHlLineEnd */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d8 /* KAknsIIDQgnIndiHlLineEnd */}, + /* SP_QgnIndiHlLineStraight */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d9 /* KAknsIIDQgnIndiHlLineStraight */}, + /* SP_QgnIndiMarkedAdd */ {KAknsIIDQgnIndiMarkedAdd, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnIndiNaviArrowLeft */ {KAknsIIDQgnGrafScrollArrowLeft, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnIndiNaviArrowRight */ {KAknsIIDQgnGrafScrollArrowRight, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnIndiRadiobuttOff */ {KAknsIIDQgnIndiRadiobuttOff, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnIndiRadiobuttOn */ {KAknsIIDQgnIndiRadiobuttOn, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnIndiSliderEdit */ {KAknsIIDQgnIndiSliderEdit, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnIndiSubMenu */ {KAknsIIDQgnIndiSubmenu, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnNoteErased */ {KAknsIIDQgnNoteErased, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnNoteError */ {KAknsIIDQgnNoteError, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnNoteInfo */ {KAknsIIDQgnNoteInfo, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnNoteOk */ {KAknsIIDQgnNoteOk, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnNoteQuery */ {KAknsIIDQgnNoteQuery, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnNoteWarning */ {KAknsIIDQgnNoteWarning, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnPropFileSmall */ {KAknsIIDQgnPropFileSmall, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnPropFolderCurrent */ {KAknsIIDQgnPropFolderCurrent, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnPropFolderSmall */ {KAknsIIDQgnPropFolderSmall, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnPropFolderSmallNew */ {KAknsIIDQgnPropFolderSmallNew, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QgnPropPhoneMemcLarge */ {KAknsIIDQgnPropPhoneMemcLarge, EDrawIcon, ES60_AllReleases, -1,-1}, + + // 3.1 & 3.2 do not have pressed state for scrollbar, so use normal scrollbar graphics instead. + /* SP_QsnCpScrollHandleBottomPressed*/ {KAknsIIDQsnCpScrollHandleBottom, EDrawIcon, ES60_3_1 | ES60_3_2, EAknsMajorGeneric, 0x20f8}, /*KAknsIIDQsnCpScrollHandleBottomPressed*/ + /* SP_QsnCpScrollHandleMiddlePressed*/ {KAknsIIDQsnCpScrollHandleMiddle, EDrawIcon, ES60_3_1 | ES60_3_2, EAknsMajorGeneric, 0x20f9}, /*KAknsIIDQsnCpScrollHandleMiddlePressed*/ + /* SP_QsnCpScrollHandleTopPressed*/ {KAknsIIDQsnCpScrollHandleTop, EDrawIcon, ES60_3_1 | ES60_3_2, EAknsMajorGeneric, 0x20fa}, /*KAknsIIDQsnCpScrollHandleTopPressed*/ + + /* SP_QsnBgScreen */ {KAknsIIDQsnBgScreen, EDrawBackground, ES60_AllReleases, -1,-1}, + + /* SP_QsnCpScrollBgBottom */ {KAknsIIDQsnCpScrollBgBottom, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QsnCpScrollBgMiddle */ {KAknsIIDQsnCpScrollBgMiddle, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QsnCpScrollBgTop */ {KAknsIIDQsnCpScrollBgTop, EDrawIcon, ES60_AllReleases, -1,-1}, + + /* SP_QsnCpScrollHandleBottom */ {KAknsIIDQsnCpScrollHandleBottom, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QsnCpScrollHandleMiddle */ {KAknsIIDQsnCpScrollHandleMiddle, EDrawIcon, ES60_AllReleases, -1,-1}, + /* SP_QsnCpScrollHandleTop */ {KAknsIIDQsnCpScrollHandleTop, EDrawIcon, ES60_AllReleases, -1,-1}, + + /* SP_QsnFrButtonTbCornerTl */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_AllReleases, -1,-1}, //todo: use "normal button" from 5.0 onwards + /* SP_QsnFrButtonTbCornerTr */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrButtonTbCornerBl */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrButtonTbCornerBr */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrButtonTbSideT */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrButtonTbSideB */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrButtonTbSideL */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrButtonTbSideR */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrButtonTbCenter */ {KAknsIIDQsnFrButtonTbCenter, EDrawIcon, ES60_AllReleases, -1,-1}, + + /* SP_QsnFrButtonTbCornerTlPressed */{KAknsIIDQsnFrButtonTbCornerTlPressed, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrButtonTbCornerTrPressed */{KAknsIIDQsnFrButtonTbCornerTrPressed, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrButtonTbCornerBlPressed */{KAknsIIDQsnFrButtonTbCornerBlPressed, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrButtonTbCornerBrPressed */{KAknsIIDQsnFrButtonTbCornerBrPressed, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrButtonTbSideTPressed */ {KAknsIIDQsnFrButtonTbSideTPressed, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrButtonTbSideBPressed */ {KAknsIIDQsnFrButtonTbSideBPressed, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrButtonTbSideLPressed */ {KAknsIIDQsnFrButtonTbSideLPressed, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrButtonTbSideRPressed */ {KAknsIIDQsnFrButtonTbSideRPressed, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrButtonTbCenterPressed */ {KAknsIIDQsnFrButtonTbCenterPressed, EDrawIcon, ES60_AllReleases, -1,-1}, + + /* SP_QsnFrCaleCornerTl */ {KAknsIIDQsnFrCaleCornerTl, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrCaleCornerTr */ {KAknsIIDQsnFrCaleCornerTr, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrCaleCornerBl */ {KAknsIIDQsnFrCaleCornerBl, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrCaleCornerBr */ {KAknsIIDQsnFrCaleCornerBr, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrCaleGSideT */ {KAknsIIDQsnFrCaleSideT, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrCaleGSideB */ {KAknsIIDQsnFrCaleSideB, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrCaleGSideL */ {KAknsIIDQsnFrCaleSideL, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrCaleGSideR */ {KAknsIIDQsnFrCaleSideR, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrCaleCenter */ {KAknsIIDQsnFrCaleCenter, ENoDraw, ES60_AllReleases, -1,-1}, + + /* SP_QsnFrCaleHeadingCornerTl */ {KAknsIIDQsnFrCaleHeadingCornerTl, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrCaleHeadingCornerTr */ {KAknsIIDQsnFrCaleHeadingCornerTr, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrCaleHeadingCornerBl */ {KAknsIIDQsnFrCaleHeadingCornerBl, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrCaleHeadingCornerBr */ {KAknsIIDQsnFrCaleHeadingCornerBr, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrCaleHeadingSideT */ {KAknsIIDQsnFrCaleHeadingSideT, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrCaleHeadingSideB */ {KAknsIIDQsnFrCaleHeadingSideB, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrCaleHeadingSideL */ {KAknsIIDQsnFrCaleHeadingSideL, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrCaleHeadingSideR */ {KAknsIIDQsnFrCaleHeadingSideR, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrCaleHeadingCenter */ {KAknsIIDQsnFrCaleHeadingCenter, ENoDraw, ES60_AllReleases, -1,-1}, + + /* SP_QsnFrInputCornerTl */ {KAknsIIDQsnFrInputCornerTl, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrInputCornerTr */ {KAknsIIDQsnFrInputCornerTr, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrInputCornerBl */ {KAknsIIDQsnFrInputCornerBl, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrInputCornerBr */ {KAknsIIDQsnFrInputCornerBr, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrInputSideT */ {KAknsIIDQsnFrInputSideT, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrInputSideB */ {KAknsIIDQsnFrInputSideB, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrInputSideL */ {KAknsIIDQsnFrInputSideL, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrInputSideR */ {KAknsIIDQsnFrInputSideR, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrInputCenter */ {KAknsIIDQsnFrInputCenter, ENoDraw, ES60_AllReleases, -1,-1}, + + /* SP_QsnFrListCornerTl */ {KAknsIIDQsnFrListCornerTl, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrListCornerTr */ {KAknsIIDQsnFrListCornerTr, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrListCornerBl */ {KAknsIIDQsnFrListCornerBl, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrListCornerBr */ {KAknsIIDQsnFrListCornerBr, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrListSideT */ {KAknsIIDQsnFrListSideT, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrListSideB */ {KAknsIIDQsnFrListSideB, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrListSideL */ {KAknsIIDQsnFrListSideL, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrListSideR */ {KAknsIIDQsnFrListSideR, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrListCenter */ {KAknsIIDQsnFrListCenter, ENoDraw, ES60_AllReleases, -1,-1}, + + /* SP_QsnFrPopupCornerTl */ {KAknsIIDQsnFrPopupCornerTl, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrPopupCornerTr */ {KAknsIIDQsnFrPopupCornerTr, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrPopupCornerBl */ {KAknsIIDQsnFrPopupCornerBl, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrPopupCornerBr */ {KAknsIIDQsnFrPopupCornerBr, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrPopupSideT */ {KAknsIIDQsnFrPopupSideT, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrPopupSideB */ {KAknsIIDQsnFrPopupSideB, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrPopupSideL */ {KAknsIIDQsnFrPopupSideL, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrPopupSideR */ {KAknsIIDQsnFrPopupSideR, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrPopupCenter */ {KAknsIIDQsnFrPopupCenter, ENoDraw, ES60_AllReleases, -1,-1}, + + // ToolTip graphics different in 3.1 vs. 3.2+. + /* SP_QsnFrPopupPreviewCornerTl */ {KAknsIIDQsnFrPopupCornerTl, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c5}, /* KAknsIIDQsnFrPopupPreviewCornerTl */ + /* SP_QsnFrPopupPreviewCornerTr */ {KAknsIIDQsnFrPopupCornerTr, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c6}, + /* SP_QsnFrPopupPreviewCornerBl */ {KAknsIIDQsnFrPopupCornerBl, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c3}, + /* SP_QsnFrPopupPreviewCornerBr */ {KAknsIIDQsnFrPopupCornerBr, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c4}, + /* SP_QsnFrPopupPreviewSideT */ {KAknsIIDQsnFrPopupSideT, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19ca}, + /* SP_QsnFrPopupPreviewSideB */ {KAknsIIDQsnFrPopupSideB, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c7}, + /* SP_QsnFrPopupPreviewSideL */ {KAknsIIDQsnFrPopupSideL, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c8}, + /* SP_QsnFrPopupPreviewSideR */ {KAknsIIDQsnFrPopupSideR, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c9}, + /* SP_QsnFrPopupPreviewCenter */ {KAknsIIDQsnFrPopupCenter, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c2}, + + /* SP_QsnFrSetOptCornerTl */ {KAknsIIDQsnFrSetOptCornerTl, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrSetOptCornerTr */ {KAknsIIDQsnFrSetOptCornerTr, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrSetOptCornerBl */ {KAknsIIDQsnFrSetOptCornerBl, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrSetOptCornerBr */ {KAknsIIDQsnFrSetOptCornerBr, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrSetOptSideT */ {KAknsIIDQsnFrSetOptSideT, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrSetOptSideB */ {KAknsIIDQsnFrSetOptSideB, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrSetOptSideL */ {KAknsIIDQsnFrSetOptSideL, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrSetOptSideR */ {KAknsIIDQsnFrSetOptSideR, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrSetOptCenter */ {KAknsIIDQsnFrSetOptCenter, ENoDraw, ES60_AllReleases, -1,-1}, + + // No toolbar frame for 5.0+ releases. + /* SP_QsnFrPopupSubCornerTl */ {KAknsIIDQsnFrPopupSubCornerTl, ENoDraw, ES60_3_1 | ES60_3_2, -1,-1}, + /* SP_QsnFrPopupSubCornerTr */ {KAknsIIDQsnFrPopupSubCornerTr, ENoDraw, ES60_3_1 | ES60_3_2, -1,-1}, + /* SP_QsnFrPopupSubCornerBl */ {KAknsIIDQsnFrPopupSubCornerBl, ENoDraw, ES60_3_1 | ES60_3_2, -1,-1}, + /* SP_QsnFrPopupSubCornerBr */ {KAknsIIDQsnFrPopupSubCornerBr, ENoDraw, ES60_3_1 | ES60_3_2, -1,-1}, + /* SP_QsnFrPopupSubSideT */ {KAknsIIDQsnFrPopupSubSideT, ENoDraw, ES60_3_1 | ES60_3_2, -1,-1}, + /* SP_QsnFrPopupSubSideB */ {KAknsIIDQsnFrPopupSubSideB, ENoDraw, ES60_3_1 | ES60_3_2, -1,-1}, + /* SP_QsnFrPopupSubSideL */ {KAknsIIDQsnFrPopupSubSideL, ENoDraw, ES60_3_1 | ES60_3_2, -1,-1}, + /* SP_QsnFrPopupSubSideR */ {KAknsIIDQsnFrPopupSubSideR, ENoDraw, ES60_3_1 | ES60_3_2, -1,-1}, + /* SP_QsnFrPopupSubCenter */ {KAknsIIDQsnFrPopupCenterSubmenu, ENoDraw, ES60_3_1 | ES60_3_2, -1,-1}, + + // Toolbar graphics is different in 3.1/3.2 vs. 5.0 + /* SP_QsnFrSctrlButtonCornerTl */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2301}, /* KAknsIIDQgnFrSctrlButtonCornerTl*/ + /* SP_QsnFrSctrlButtonCornerTr */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2302}, + /* SP_QsnFrSctrlButtonCornerBl */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2303}, + /* SP_QsnFrSctrlButtonCornerBr */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2304}, + /* SP_QsnFrSctrlButtonSideT */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2305}, + /* SP_QsnFrSctrlButtonSideB */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2306}, + /* SP_QsnFrSctrlButtonSideL */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2307}, + /* SP_QsnFrSctrlButtonSideR */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2308}, + /* SP_QsnFrSctrlButtonCenter */ {KAknsIIDQsnFrButtonTbCenter, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2309}, /*KAknsIIDQgnFrSctrlButtonCenter*/ + + // No pressed state for toolbar button in 3.1/3.2. + /* SP_QsnFrSctrlButtonCornerTlPressed */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2621}, /*KAknsIIDQsnFrSctrlButtonCornerTlPressed*/ + /* SP_QsnFrSctrlButtonCornerTrPressed */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2622}, + /* SP_QsnFrSctrlButtonCornerBlPressed */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2623}, + /* SP_QsnFrSctrlButtonCornerBrPressed */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2624}, + /* SP_QsnFrSctrlButtonSideTPressed */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2625}, + /* SP_QsnFrSctrlButtonSideBPressed */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2626}, + /* SP_QsnFrSctrlButtonSideLPressed */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2627}, + /* SP_QsnFrSctrlButtonSideRPressed */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2628}, + /* SP_QsnFrSctrlButtonCenterPressed */ {KAknsIIDQsnFrButtonTbCenter, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x2629}, + + // No inactive button graphics in 3.1/3.2 + /* SP_QsnFrButtonCornerTlInactive */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b1}, /*KAknsIIDQsnFrButtonCornerTlInactive*/ + /* SP_QsnFrButtonCornerTrInactive */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b2}, + /* SP_QsnFrButtonCornerBlInactive */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b3}, + /* SP_QsnFrButtonCornerTrInactive */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b4}, + /* SP_QsnFrButtonSideTInactive */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b5}, + /* SP_QsnFrButtonSideBInactive */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b6}, + /* SP_QsnFrButtonSideLInactive */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b7}, + /* SP_QsnFrButtonSideRInactive */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b8}, + /* SP_QsnFrButtonCenterInactive */ {KAknsIIDQsnFrButtonTbCenter, EDrawIcon, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b9}, + + /* SP_QsnFrNotepadCornerTl */ {KAknsIIDQsnFrNotepadContCornerTl, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrNotepadCornerTr */ {KAknsIIDQsnFrNotepadContCornerTr, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrNotepadCornerBl */ {KAknsIIDQsnFrNotepadCornerBl, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrNotepadCornerBr */ {KAknsIIDQsnFrNotepadCornerBr, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrNotepadSideT */ {KAknsIIDQsnFrNotepadContSideT, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrNotepadSideB */ {KAknsIIDQsnFrNotepadSideB, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrNotepadSideL */ {KAknsIIDQsnFrNotepadSideL, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrNotepadSideR */ {KAknsIIDQsnFrNotepadSideR, ENoDraw, ES60_AllReleases, -1,-1}, + /* SP_QsnFrNotepadCenter */ {KAknsIIDQsnFrNotepadCenter, EDrawIcon, ES60_AllReleases, -1,-1}, + +}; + +QPixmap QS60StyleModeSpecifics::skinnedGraphics( + QS60StyleEnums::SkinParts stylepart, const QSize &size, + QS60StylePrivate::SkinElementFlags flags) +{ + QPixmap themedImage; + TRAPD( error, QT_TRYCATCH_LEAVING({ + const QPixmap skinnedImage = createSkinnedGraphicsLX(stylepart, size, flags); + themedImage = skinnedImage; + })); + if (error) + return themedImage = QPixmap(); + return themedImage; +} + +QPixmap QS60StyleModeSpecifics::skinnedGraphics( + QS60StylePrivate::SkinFrameElements frame, const QSize &size, QS60StylePrivate::SkinElementFlags flags) +{ + QPixmap themedImage; + TRAPD( error, QT_TRYCATCH_LEAVING({ + const QPixmap skinnedImage = createSkinnedGraphicsLX(frame, size, flags); + themedImage = skinnedImage; + })); + if (error) + return themedImage = QPixmap(); + return themedImage; +} + +QPixmap QS60StyleModeSpecifics::colorSkinnedGraphics( + const QS60StyleEnums::SkinParts &stylepart, + const QSize &size, QS60StylePrivate::SkinElementFlags flags) +{ + QPixmap colorGraphics; + TRAPD(error, QT_TRYCATCH_LEAVING(colorGraphics = colorSkinnedGraphicsLX(stylepart, size, flags))); + return error ? QPixmap() : colorGraphics; +} + +void QS60StyleModeSpecifics::fallbackInfo(const QS60StyleEnums::SkinParts &stylepart, TDes& fallbackFileName, TInt& fallbackIndex) +{ + switch(stylepart) { + case QS60StyleEnums::SP_QgnGrafBarWait: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_graf_bar_wait_1; + break; + case QS60StyleEnums::SP_QgnGrafBarFrameCenter: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_graf_bar_frame_center; + break; + case QS60StyleEnums::SP_QgnGrafBarFrameSideL: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_graf_bar_frame_side_l; + break; + case QS60StyleEnums::SP_QgnGrafBarFrameSideR: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_graf_bar_frame_side_r; + break; + case QS60StyleEnums::SP_QgnGrafBarProgress: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_graf_bar_progress; + break; + case QS60StyleEnums::SP_QgnGrafTabActiveL: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_graf_tab_active_l; + break; + case QS60StyleEnums::SP_QgnGrafTabActiveM: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_graf_tab_active_m; + break; + case QS60StyleEnums::SP_QgnGrafTabActiveR: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_graf_tab_active_r; + break; + case QS60StyleEnums::SP_QgnGrafTabPassiveL: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_graf_tab_passive_l; + break; + case QS60StyleEnums::SP_QgnGrafTabPassiveM: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_graf_tab_passive_m; + break; + case QS60StyleEnums::SP_QgnGrafTabPassiveR: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_graf_tab_passive_r; + break; + case QS60StyleEnums::SP_QgnIndiCheckboxOff: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_indi_checkbox_off; + break; + case QS60StyleEnums::SP_QgnIndiCheckboxOn: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_indi_checkbox_on; + break; + case QS60StyleEnums::SP_QgnIndiHlColSuper: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = 0x4456; /* EMbmAvkonQgn_indi_hl_col_super */ + break; + case QS60StyleEnums::SP_QgnIndiHlExpSuper: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = 0x4458; /* EMbmAvkonQgn_indi_hl_exp_super */ + break; + case QS60StyleEnums::SP_QgnIndiHlLineBranch: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = 0x445A; /* EMbmAvkonQgn_indi_hl_line_branch */ + break; + case QS60StyleEnums::SP_QgnIndiHlLineEnd: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = 0x445C; /* EMbmAvkonQgn_indi_hl_line_end */ + break; + case QS60StyleEnums::SP_QgnIndiHlLineStraight: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = 0x445E; /* EMbmAvkonQgn_indi_hl_line_straight */ + break; + case QS60StyleEnums::SP_QgnIndiMarkedAdd: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_indi_marked_add; + break; + case QS60StyleEnums::SP_QgnIndiNaviArrowLeft: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_indi_navi_arrow_left; + break; + case QS60StyleEnums::SP_QgnIndiNaviArrowRight: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_indi_navi_arrow_right; + break; + case QS60StyleEnums::SP_QgnIndiRadiobuttOff: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_indi_radiobutt_off; + break; + case QS60StyleEnums::SP_QgnIndiRadiobuttOn: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_indi_radiobutt_on; + break; + case QS60StyleEnums::SP_QgnIndiSliderEdit: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_indi_slider_edit; + break; + case QS60StyleEnums::SP_QgnIndiSubMenu: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_indi_submenu; + break; + case QS60StyleEnums::SP_QgnNoteErased: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_note_erased; + break; + case QS60StyleEnums::SP_QgnNoteError: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_note_error; + break; + case QS60StyleEnums::SP_QgnNoteInfo: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_note_info; + break; + case QS60StyleEnums::SP_QgnNoteOk: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_note_ok; + break; + case QS60StyleEnums::SP_QgnNoteQuery: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_note_query; + break; + case QS60StyleEnums::SP_QgnNoteWarning: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_note_warning; + break; + case QS60StyleEnums::SP_QgnPropFileSmall: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_prop_file_small; + break; + case QS60StyleEnums::SP_QgnPropFolderCurrent: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_prop_folder_current; + break; + case QS60StyleEnums::SP_QgnPropFolderSmall: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_prop_folder_small; + break; + case QS60StyleEnums::SP_QgnPropFolderSmallNew: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_prop_folder_small_new; + break; + case QS60StyleEnums::SP_QgnPropPhoneMemcLarge: + fallbackFileName = KAvkonBitmapFile(); + fallbackIndex = EMbmAvkonQgn_prop_phone_memc_large; + break; + default: + fallbackFileName = KNullDesC(); + fallbackIndex = -1; + break; + } +} + +QPixmap QS60StyleModeSpecifics::colorSkinnedGraphicsLX( + const QS60StyleEnums::SkinParts &stylepart, + const QSize &size, QS60StylePrivate::SkinElementFlags flags) +{ + // this function can throw both exceptions and leaves. There are no cleanup dependencies between Qt and Symbian parts. + const int stylepartIndex = (int)stylepart; + const TAknsItemID skinId = m_partMap[stylepartIndex].skinID; + + TInt fallbackGraphicID = -1; + HBufC* iconFile = HBufC::NewLC( KMaxFileName ); + TPtr fileNamePtr = iconFile->Des(); + fallbackInfo(stylepart, fileNamePtr, fallbackGraphicID); + + TAknsItemID colorGroup = KAknsIIDQsnIconColors; + int colorIndex = 0; + colorGroupAndIndex(stylepart, colorGroup, colorIndex); + + const bool rotatedBy90or270 = + (flags & (QS60StylePrivate::SF_PointEast | QS60StylePrivate::SF_PointWest)); + const TSize targetSize = + rotatedBy90or270?TSize(size.height(), size.width()):TSize(size.width(), size.height()); + CFbsBitmap *icon = 0; + CFbsBitmap *iconMask = 0; + const TInt fallbackGraphicsMaskID = + fallbackGraphicID == KErrNotFound?KErrNotFound:fallbackGraphicID+1; //masks are auto-generated as next in mif files + MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); + AknsUtils::CreateColorIconLC( + skinInstance, skinId, colorGroup, colorIndex, icon, iconMask, fileNamePtr, fallbackGraphicID , fallbackGraphicsMaskID, KRgbBlack); + User::LeaveIfError(AknIconUtils::SetSize(icon, targetSize, EAspectRatioNotPreserved)); + User::LeaveIfError(AknIconUtils::SetSize(iconMask, targetSize, EAspectRatioNotPreserved)); + QPixmap result = fromFbsBitmap(icon, iconMask, flags, qt_TDisplayMode2Format(icon->DisplayMode())); + CleanupStack::PopAndDestroy(3); //icon, iconMask, iconFile + return result; +} + +QColor QS60StyleModeSpecifics::colorValue(const TAknsItemID &colorGroup, int colorIndex) +{ + TRgb skinnedColor; + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + AknsUtils::GetCachedColor(skin, skinnedColor, colorGroup, colorIndex); + return QColor(skinnedColor.Red(),skinnedColor.Green(),skinnedColor.Blue()); +} + +struct QAutoFbsBitmapHeapLock +{ + QAutoFbsBitmapHeapLock(CFbsBitmap* aBmp) : mBmp(aBmp) { mBmp->LockHeap(); } + ~QAutoFbsBitmapHeapLock() { mBmp->UnlockHeap(); } + CFbsBitmap* mBmp; +}; + +QPixmap QS60StyleModeSpecifics::fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask, QS60StylePrivate::SkinElementFlags flags, QImage::Format format) +{ + Q_ASSERT(icon); + const TSize iconSize = icon->SizeInPixels(); + const int iconBytesPerLine = CFbsBitmap::ScanLineLength(iconSize.iWidth, icon->DisplayMode()); + const int iconBytesCount = iconBytesPerLine * iconSize.iHeight; + + QImage iconImage(qt_TSize2QSize(iconSize), format); + if (iconImage.isNull()) + return QPixmap(); + + checkAndUnCompressBitmap(icon); + if (!icon) //checkAndUnCompressBitmap might set icon to NULL + return QPixmap(); + + icon->LockHeap(); + const uchar *const iconBytes = (uchar*)icon->DataAddress(); + // The icon data needs to be copied, since the color format will be + // automatically converted to Format_ARGB32 when setAlphaChannel is called. + memcpy(iconImage.bits(), iconBytes, iconBytesCount); + icon->UnlockHeap(); + if (mask) { + checkAndUnCompressBitmap(mask); + if (mask) { //checkAndUnCompressBitmap might set mask to NULL + const TSize maskSize = icon->SizeInPixels(); + const int maskBytesPerLine = CFbsBitmap::ScanLineLength(maskSize.iWidth, mask->DisplayMode()); + // heap lock object required because QImage ctor might throw + QAutoFbsBitmapHeapLock maskHeapLock(mask); + const uchar *const maskBytes = (uchar *)mask->DataAddress(); + // Since no other bitmap should be locked, we can just "borrow" the mask data for setAlphaChannel + const QImage maskImage(maskBytes, maskSize.iWidth, maskSize.iHeight, maskBytesPerLine, QImage::Format_Indexed8); + if (!maskImage.isNull()) + iconImage.setAlphaChannel(maskImage); + } + } + + QTransform imageTransform; + if (flags & QS60StylePrivate::SF_PointEast) { + imageTransform.rotate(90); + } else if (flags & QS60StylePrivate::SF_PointSouth) { + imageTransform.rotate(180); + iconImage = iconImage.transformed(imageTransform); + } else if (flags & QS60StylePrivate::SF_PointWest) { + imageTransform.rotate(270); + } + if (imageTransform.isRotating()) + iconImage = iconImage.transformed(imageTransform); + + return QPixmap::fromImage(iconImage); +} + +bool QS60StylePrivate::isTouchSupported() +{ + return bool(AknLayoutUtils::PenEnabled()); +} + +bool QS60StylePrivate::isToolBarBackground() +{ + return (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2); +} + +QPoint qt_s60_fill_background_offset(const QWidget *targetWidget) +{ + CCoeControl *control = targetWidget->effectiveWinId(); + TPoint globalPos = control ? control->PositionRelativeToScreen() : TPoint(0,0); + return QPoint(globalPos.iX, globalPos.iY); +} + +QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX( + QS60StyleEnums::SkinParts part, + const QSize &size, QS60StylePrivate::SkinElementFlags flags) +{ + // this function can throw both exceptions and leaves. There are no cleanup dependencies between Qt and Symbian parts. + if (!size.isValid()) + return QPixmap(); + + // Check release support and change part, if necessary. + const TAknsItemID skinId = checkAndUpdateReleaseSpecificGraphics((int)part); + const int stylepartIndex = (int)part; + const TDrawType drawType = m_partMap[stylepartIndex].drawType; + Q_ASSERT(drawType != ENoDraw); + const bool rotatedBy90or270 = + (flags & (QS60StylePrivate::SF_PointEast | QS60StylePrivate::SF_PointWest)); + const TSize targetSize = + rotatedBy90or270 ? TSize(size.height(), size.width()) : qt_QSize2TSize(size); + + MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); + + QPixmap result; + + switch (drawType) { + case EDrawIcon: { + TInt fallbackGraphicID = -1; + HBufC* iconFile = HBufC::NewLC( KMaxFileName ); + TPtr fileNamePtr = iconFile->Des(); + fallbackInfo(part, fileNamePtr, fallbackGraphicID); + // todo: could we instead use AknIconUtils::AvkonIconFileName(); to avoid allocating each time? + + CFbsBitmap *icon = 0; + CFbsBitmap *iconMask = 0; + const TInt fallbackGraphicsMaskID = + fallbackGraphicID == KErrNotFound?KErrNotFound:fallbackGraphicID+1; //masks are auto-generated as next in mif files + // QS60WindowSurface::unlockBitmapHeap(); + AknsUtils::CreateIconLC(skinInstance, skinId, icon, iconMask, fileNamePtr, fallbackGraphicID , fallbackGraphicsMaskID); + User::LeaveIfError(AknIconUtils::SetSize(icon, targetSize, EAspectRatioNotPreserved)); + User::LeaveIfError(AknIconUtils::SetSize(iconMask, targetSize, EAspectRatioNotPreserved)); + result = fromFbsBitmap(icon, iconMask, flags, qt_TDisplayMode2Format(icon->DisplayMode())); + CleanupStack::PopAndDestroy(3); // iconMask, icon, iconFile + // QS60WindowSurface::lockBitmapHeap(); + break; + } + case EDrawBackground: { + // QS60WindowSurface::unlockBitmapHeap(); + CFbsBitmap *background = new (ELeave) CFbsBitmap(); //offscreen + CleanupStack::PushL(background); + User::LeaveIfError(background->Create(targetSize, EColor16MA)); + + CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL(background); + CleanupStack::PushL(dev); + CFbsBitGc* gc = NULL; + User::LeaveIfError(dev->CreateContext(gc)); + CleanupStack::PushL(gc); + + CAknsBasicBackgroundControlContext* bgContext = CAknsBasicBackgroundControlContext::NewL( + skinId, + targetSize, + EFalse); + CleanupStack::PushL(bgContext); + + const TBool drawn = AknsDrawUtils::DrawBackground( + skinInstance, + bgContext, + NULL, + *gc, + TPoint(), + targetSize, + KAknsDrawParamDefault | KAknsDrawParamRGBOnly); + + if (drawn) + result = fromFbsBitmap(background, NULL, flags, QImage::Format_RGB32); + + CleanupStack::PopAndDestroy(4, background); //background, dev, gc, bgContext + // QS60WindowSurface::lockBitmapHeap(); + break; + } + } + + return result; +} + +QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(QS60StylePrivate::SkinFrameElements frameElement, + const QSize &size, QS60StylePrivate::SkinElementFlags flags) +{ + // this function can throw both exceptions and leaves. There are no cleanup dependencies between Qt and Symbian parts. + if (!size.isValid()) + return QPixmap(); + + const bool rotatedBy90or270 = + (flags & (QS60StylePrivate::SF_PointEast | QS60StylePrivate::SF_PointWest)); + const TSize targetSize = + rotatedBy90or270 ? TSize(size.height(), size.width()) : qt_QSize2TSize(size); + + MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance(); + QPixmap result; + +// QS60WindowSurface::unlockBitmapHeap(); + static const bool canDoEColor16MAP = !(QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2); + static const TDisplayMode displayMode = canDoEColor16MAP ? TDisplayMode(13) : EColor16MA; // 13 = EColor16MAP + static const TInt drawParam = canDoEColor16MAP ? KAknsDrawParamDefault : KAknsDrawParamNoClearUnderImage|KAknsDrawParamRGBOnly; + + CFbsBitmap *frame = new (ELeave) CFbsBitmap(); //offscreen + CleanupStack::PushL(frame); + User::LeaveIfError(frame->Create(targetSize, displayMode)); + + CFbsBitmapDevice* bitmapDev = CFbsBitmapDevice::NewL(frame); + CleanupStack::PushL(bitmapDev); + CFbsBitGc* bitmapGc = NULL; + User::LeaveIfError(bitmapDev->CreateContext(bitmapGc)); + CleanupStack::PushL(bitmapGc); + + frame->LockHeap(); + memset(frame->DataAddress(), 0, frame->SizeInPixels().iWidth * frame->SizeInPixels().iHeight * 4); // 4: argb bytes + frame->UnlockHeap(); + + const TRect outerRect(TPoint(0, 0), targetSize); + const TRect innerRect = innerRectFromElement(frameElement, outerRect); + + TAknsItemID frameSkinID, centerSkinID; + frameSkinID = centerSkinID = checkAndUpdateReleaseSpecificGraphics(QS60StylePrivate::m_frameElementsData[frameElement].center); + frameIdAndCenterId(frameElement, frameSkinID, centerSkinID); + const TBool drawn = AknsDrawUtils::DrawFrame( skinInstance, + *bitmapGc, outerRect, innerRect, + frameSkinID, centerSkinID, + drawParam ); + + if (canDoEColor16MAP) { + if (drawn) + result = fromFbsBitmap(frame, NULL, flags, QImage::Format_ARGB32_Premultiplied); + } else { + TDisplayMode maskDepth = EGray2; + // Query the skin item for possible frame graphics mask details. + if (skinInstance) { + CAknsMaskedBitmapItemData* skinMaskedBmp = static_cast<CAknsMaskedBitmapItemData*>( + skinInstance->GetCachedItemData(frameSkinID,EAknsITMaskedBitmap)); + if (skinMaskedBmp && skinMaskedBmp->Mask()) + maskDepth = skinMaskedBmp->Mask()->DisplayMode(); + } + if (maskDepth != ENone) { + CFbsBitmap *frameMask = new (ELeave) CFbsBitmap(); //offscreen + CleanupStack::PushL(frameMask); + User::LeaveIfError(frameMask->Create(targetSize, maskDepth)); + + CFbsBitmapDevice* maskBitmapDevice = CFbsBitmapDevice::NewL(frameMask); + CleanupStack::PushL(maskBitmapDevice); + CFbsBitGc* maskBitGc = NULL; + User::LeaveIfError(maskBitmapDevice->CreateContext(maskBitGc)); + CleanupStack::PushL(maskBitGc); + + if (drawn) { + //ensure that the mask is really transparent + maskBitGc->Activate( maskBitmapDevice ); + maskBitGc->SetPenStyle(CGraphicsContext::ENullPen); + maskBitGc->SetBrushStyle(CGraphicsContext::ESolidBrush); + maskBitGc->SetBrushColor(KRgbWhite); + maskBitGc->Clear(); + maskBitGc->SetBrushStyle(CGraphicsContext::ENullBrush); + + AknsDrawUtils::DrawFrame(skinInstance, + *maskBitGc, outerRect, innerRect, + frameSkinID, centerSkinID, + KAknsSDMAlphaOnly |KAknsDrawParamNoClearUnderImage); + result = fromFbsBitmap(frame, frameMask, flags, QImage::Format_ARGB32); + } + CleanupStack::PopAndDestroy(3, frameMask); + } + } + CleanupStack::PopAndDestroy(3, frame); //frame, bitmapDev, bitmapGc + return result; +} + +void QS60StyleModeSpecifics::frameIdAndCenterId(QS60StylePrivate::SkinFrameElements frameElement, TAknsItemID &frameId, TAknsItemID ¢erId) +{ +// There are some major mix-ups in skin declarations for some frames. +// First, the frames are not declared in sequence. +// Second, the parts use different major than the frame-master. + + switch(frameElement) { + case QS60StylePrivate::SF_ToolTip: + if (QSysInfo::s60Version()!=QSysInfo::SV_S60_3_1) { + centerId.Set(EAknsMajorGeneric, 0x19c2); + frameId.Set(EAknsMajorSkin, 0x5300); + } else { + centerId.Set(KAknsIIDQsnFrPopupCenter); + frameId.iMinor = centerId.iMinor - 9; + } + break; + case QS60StylePrivate::SF_ToolBar: + if (QSysInfo::s60Version()==QSysInfo::SV_S60_3_1 || QSysInfo::s60Version()==QSysInfo::SV_S60_3_2) { + centerId.Set(KAknsIIDQsnFrPopupCenterSubmenu); + frameId.Set(KAknsIIDQsnFrPopupSub); + } + break; + case QS60StylePrivate::SF_PanelBackground: + // remove center piece for panel graphics, so that only border is drawn + centerId.Set(KAknsIIDNone); + frameId.Set(KAknsIIDQsnFrSetOpt); + break; + case QS60StylePrivate::SF_Editor: + centerId.Set(KAknsIIDQsnFrNotepadCenter); + frameId.Set(KAknsIIDQsnFrNotepadCont); + break; + default: + // center should be correct here + frameId.iMinor = centerId.iMinor - 9; + break; + } +} + +TRect QS60StyleModeSpecifics::innerRectFromElement(QS60StylePrivate::SkinFrameElements frameElement, const TRect &outerRect) +{ + TInt widthShrink = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth); + TInt heightShrink = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerHeight); + switch(frameElement) { + case QS60StylePrivate::SF_PanelBackground: + // panel should have slightly slimmer border to enable thin line of background graphics between closest component + widthShrink = widthShrink-2; + heightShrink = heightShrink-2; + break; + case QS60StylePrivate::SF_ToolTip: + widthShrink = widthShrink>>1; + heightShrink = heightShrink>>1; + break; + case QS60StylePrivate::SF_ListHighlight: + widthShrink = widthShrink-2; + heightShrink = heightShrink-2; + break; + default: + break; + } + TRect innerRect(outerRect); + innerRect.Shrink(widthShrink, heightShrink); + return innerRect; +} + +bool QS60StyleModeSpecifics::checkSupport(const int supportedRelease) +{ + const QSysInfo::S60Version currentRelease = QSysInfo::s60Version(); + return ( (currentRelease == QSysInfo::SV_S60_3_1 && supportedRelease & ES60_3_1) || + (currentRelease == QSysInfo::SV_S60_3_2 && supportedRelease & ES60_3_2) || + (currentRelease == QSysInfo::SV_S60_5_0 && supportedRelease & ES60_5_0)); +} + +TAknsItemID QS60StyleModeSpecifics::checkAndUpdateReleaseSpecificGraphics(int part) +{ + TAknsItemID newSkinId; + if (!checkSupport(m_partMap[(int)part].supportInfo)) + newSkinId.Set(m_partMap[(int)part].newMajorSkinId, m_partMap[(int)part].newMinorSkinId); + else + newSkinId.Set(m_partMap[(int)part].skinID); + return newSkinId; +} + +void QS60StyleModeSpecifics::checkAndUnCompressBitmap(CFbsBitmap*& aOriginalBitmap) +{ + TRAPD(error, checkAndUnCompressBitmapL(aOriginalBitmap)); + if (error) + aOriginalBitmap = NULL; +} + +void QS60StyleModeSpecifics::checkAndUnCompressBitmapL(CFbsBitmap*& aOriginalBitmap) +{ + const TSize iconSize = aOriginalBitmap->SizeInPixels(); + const int iconBytesPerLine = CFbsBitmap::ScanLineLength(iconSize.iWidth, aOriginalBitmap->DisplayMode()); + const int iconBytesCount = iconBytesPerLine * iconSize.iHeight; + if (aOriginalBitmap->IsCompressedInRAM() || aOriginalBitmap->Header().iBitmapSize < iconBytesCount) { + const TSize iconSize(aOriginalBitmap->SizeInPixels().iWidth, + aOriginalBitmap->SizeInPixels().iHeight); + CFbsBitmap* uncompressedBitmap = new (ELeave) CFbsBitmap(); + CleanupStack::PushL(uncompressedBitmap); + User::LeaveIfError(uncompressedBitmap->Create(iconSize, + aOriginalBitmap->DisplayMode())); + unCompressBitmapL(iconSize, uncompressedBitmap, aOriginalBitmap); + CleanupStack::Pop(uncompressedBitmap); + User::LeaveIfError(aOriginalBitmap->Duplicate( + uncompressedBitmap->Handle())); + delete uncompressedBitmap; + } +} + +QFont QS60StylePrivate::s60Font_specific( + QS60StyleEnums::FontCategories fontCategory, int pointSize) +{ + TAknFontCategory aknFontCategory = EAknFontCategoryUndefined; + switch (fontCategory) { + case QS60StyleEnums::FC_Primary: + aknFontCategory = EAknFontCategoryPrimary; + break; + case QS60StyleEnums::FC_Secondary: + aknFontCategory = EAknFontCategorySecondary; + break; + case QS60StyleEnums::FC_Title: + aknFontCategory = EAknFontCategoryTitle; + break; + case QS60StyleEnums::FC_PrimarySmall: + aknFontCategory = EAknFontCategoryPrimarySmall; + break; + case QS60StyleEnums::FC_Digital: + aknFontCategory = EAknFontCategoryDigital; + break; + case QS60StyleEnums::FC_Undefined: + default: + break; + } + + // Create AVKON font according the given parameters + CWsScreenDevice* dev = CCoeEnv::Static()->ScreenDevice(); + TAknFontSpecification spec(aknFontCategory, TFontSpec(), NULL); + if (pointSize > 0) { + const TInt pixelSize = dev->VerticalTwipsToPixels(pointSize * KTwipsPerPoint); + spec.SetTextPaneHeight(pixelSize + 4); // TODO: Is 4 a reasonable top+bottom margin? + } + + QFont result; + TRAPD( error, QT_TRYCATCH_LEAVING({ + const CAknLayoutFont* aknFont = + AknFontAccess::CreateLayoutFontFromSpecificationL(*dev, spec); + + result = qt_TFontSpec2QFontL(aknFont->DoFontSpecInTwips()); + if (result.pointSize() != pointSize) + result.setPointSize(pointSize); // Correct the font size returned by CreateLayoutFontFromSpecificationL() + + delete aknFont; + })); + if (error) result = QFont(); + return result; +} + +void QS60StylePrivate::setActiveLayout() +{ + const QSize activeScreenSize(screenSize()); + int activeLayoutIndex = -1; + const bool mirrored = !QApplication::isLeftToRight(); + const short screenHeight = (short)activeScreenSize.height(); + const short screenWidth = (short)activeScreenSize.width(); + for (int i=0; i<m_numberOfLayouts; i++) { + if (screenHeight==m_layoutHeaders[i].height && + screenWidth==m_layoutHeaders[i].width && + mirrored==m_layoutHeaders[i].mirroring) { + activeLayoutIndex = i; + break; + } + } + + //not found, lets try without mirroring info + if (activeLayoutIndex==-1){ + for (int i=0; i<m_numberOfLayouts; i++) { + if (screenHeight==m_layoutHeaders[i].height && + screenWidth==m_layoutHeaders[i].width) { + activeLayoutIndex = i; + break; + } + } + } + + //not found, lets try with either of dimensions + if (activeLayoutIndex==-1){ + const QSysInfo::S60Version currentRelease = QSysInfo::s60Version(); + const bool landscape = screenHeight < screenWidth; + + activeLayoutIndex = (currentRelease == QSysInfo::SV_S60_3_1 || currentRelease == QSysInfo::SV_S60_3_2) ? 0 : 4; + activeLayoutIndex += (!landscape) ? 2 : 0; + activeLayoutIndex += (!mirrored) ? 1 : 0; + } + + m_pmPointer = data[activeLayoutIndex]; +} + +QS60StylePrivate::QS60StylePrivate() +{ + // No need to set active layout, if dynamic metrics API is available + setActiveLayout(); +} + +void QS60StylePrivate::setStyleProperty_specific(const char *name, const QVariant &value) +{ + if (name == QLatin1String("foo")) { + // BaR + } else { + setStyleProperty(name, value); + } +} + +QVariant QS60StylePrivate::styleProperty_specific(const char *name) const +{ + if (name == QLatin1String("foo")) + return QLatin1String("Bar"); + else + return styleProperty(name); +} + +QColor QS60StylePrivate::s60Color(QS60StyleEnums::ColorLists list, + int index, const QStyleOption *option) +{ + static const TAknsItemID *idMap[] = { + &KAknsIIDQsnHighlightColors, + &KAknsIIDQsnIconColors, + &KAknsIIDQsnLineColors, + &KAknsIIDQsnOtherColors, + &KAknsIIDQsnParentColors, + &KAknsIIDQsnTextColors + }; + Q_ASSERT((int)list <= (int)sizeof(idMap)/sizeof(idMap[0])); + const QColor color = QS60StyleModeSpecifics::colorValue(*idMap[(int) list], index - 1); + return option ? QS60StylePrivate::stateColor(color, option) : color; +} + +// In some cases, the AVKON UI themegraphic is already in 'disabled state'. +// If so, return true for these parts. +bool QS60StyleModeSpecifics::disabledPartGraphic(QS60StyleEnums::SkinParts &part) +{ + bool disabledGraphic = false; + switch(part){ + // inactive button graphics are available from 5.0 onwards + case QS60StyleEnums::SP_QsnFrButtonCornerTlInactive: + case QS60StyleEnums::SP_QsnFrButtonCornerTrInactive: + case QS60StyleEnums::SP_QsnFrButtonCornerBlInactive: + case QS60StyleEnums::SP_QsnFrButtonCornerBrInactive: + case QS60StyleEnums::SP_QsnFrButtonSideTInactive: + case QS60StyleEnums::SP_QsnFrButtonSideBInactive: + case QS60StyleEnums::SP_QsnFrButtonSideLInactive: + case QS60StyleEnums::SP_QsnFrButtonSideRInactive: + case QS60StyleEnums::SP_QsnFrButtonCenterInactive: + if (!(QSysInfo::s60Version()==QSysInfo::SV_S60_3_1 || + QSysInfo::s60Version()==QSysInfo::SV_S60_3_2)) + disabledGraphic = true; + break; + default: + break; + } + return disabledGraphic; +} + +// In some cases, the AVKON UI themegraphic is already in 'disabled state'. +// If so, return true for these frames. +bool QS60StyleModeSpecifics::disabledFrameGraphic(QS60StylePrivate::SkinFrameElements &frame) +{ + bool disabledGraphic = false; + switch(frame){ + // inactive button graphics are available from 5.0 onwards + case QS60StylePrivate::SF_ButtonInactive: + if (!(QSysInfo::s60Version()==QSysInfo::SV_S60_3_1 || + QSysInfo::s60Version()==QSysInfo::SV_S60_3_2)) + disabledGraphic = true; + break; + default: + break; + } + return disabledGraphic; +} + +QPixmap QS60StyleModeSpecifics::generateMissingThemeGraphic(QS60StyleEnums::SkinParts &part, + const QSize &size, QS60StylePrivate::SkinElementFlags flags) +{ + if (!QS60StylePrivate::isTouchSupported()) + return QPixmap(); + + QS60StyleEnums::SkinParts updatedPart = part; + switch(part){ + // AVKON UI has a abnormal handling for scrollbar graphics. It is possible that the root + // skin does not contain mandatory graphics for scrollbar pressed states. Therefore, AVKON UI + // creates dynamically these graphics by modifying the normal state scrollbar graphics slightly. + // S60Style needs to work similarly. Therefore if skingraphics call provides to be a miss + // (i.e. result is not valid), style needs to draw normal graphics instead and apply some + // modifications (similar to generatedIconPixmap()) to the result. + case QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed: + updatedPart = QS60StyleEnums::SP_QsnCpScrollHandleBottom; + break; + case QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed: + updatedPart = QS60StyleEnums::SP_QsnCpScrollHandleMiddle; + break; + case QS60StyleEnums::SP_QsnCpScrollHandleTopPressed: + updatedPart = QS60StyleEnums::SP_QsnCpScrollHandleTop; + break; + default: + break; + } + if (part==updatedPart) { + return QPixmap(); + } else { + QPixmap result = skinnedGraphics(updatedPart, size, flags); + QStyleOption opt; + QPalette *themePalette = QS60StylePrivate::themePalette(); + if (themePalette) + opt.palette = *themePalette; + + // For now, always generate new icon based on "selected". In the future possibly, expand + // this to consist other possibilities as well. + result = QApplication::style()->generatedIconPixmap(QIcon::Selected, result, &opt); + return result; + } +} + +QPixmap QS60StylePrivate::part(QS60StyleEnums::SkinParts part, + const QSize &size, SkinElementFlags flags) +{ + QS60WindowSurface::unlockBitmapHeap(); + QPixmap result = (flags & SF_ColorSkinned)? + QS60StyleModeSpecifics::colorSkinnedGraphics(part, size, flags) + : QS60StyleModeSpecifics::skinnedGraphics(part, size, flags); + QS60WindowSurface::lockBitmapHeap(); + + if (flags & SF_StateDisabled && !QS60StyleModeSpecifics::disabledPartGraphic(part)) { + QStyleOption opt; + QPalette *themePalette = QS60StylePrivate::themePalette(); + if (themePalette) + opt.palette = *themePalette; + result = QApplication::style()->generatedIconPixmap(QIcon::Disabled, result, &opt); + } + + if (!result) + result = QS60StyleModeSpecifics::generateMissingThemeGraphic(part, size, flags); + + return result; +} + +QPixmap QS60StylePrivate::frame(SkinFrameElements frame, const QSize &size, SkinElementFlags flags) +{ + QS60WindowSurface::unlockBitmapHeap(); + QPixmap result = QS60StyleModeSpecifics::skinnedGraphics(frame, size, flags); + QS60WindowSurface::lockBitmapHeap(); + + if (flags & SF_StateDisabled && !QS60StyleModeSpecifics::disabledFrameGraphic(frame)) { + QStyleOption opt; + QPalette *themePalette = QS60StylePrivate::themePalette(); + if (themePalette) + opt.palette = *themePalette; + result = QApplication::style()->generatedIconPixmap(QIcon::Disabled, result, &opt); + } + return result; +} + +QPixmap QS60StylePrivate::backgroundTexture() +{ + if (!m_background) { + QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen, + QSize(S60->screenWidthInPixels, S60->screenHeightInPixels), SkinElementFlags()); + m_background = new QPixmap(background); + } + return *m_background; +} + +// If the public SDK returns compressed images, please let us also uncompress those! +void QS60StyleModeSpecifics::unCompressBitmapL(const TRect& aTrgRect, CFbsBitmap* aTrgBitmap, CFbsBitmap* aSrcBitmap) +{ + if (!aSrcBitmap) + User::Leave(KErrArgument); + if (!aTrgBitmap) + User::Leave(KErrArgument); + + // Note! aSrcBitmap->IsCompressedInRAM() is always ETrue, since this method is called only if that applies! + // Extra note! this function is also being used when bitmaps appear to be compressed (because DataSize is too small) + // even when they pretend they are not. Assert removed. +// ASSERT(aSrcBitmap->IsCompressedInRAM()); + + TDisplayMode displayMode = aSrcBitmap->DisplayMode(); + + if (displayMode != aTrgBitmap->DisplayMode()) + User::Leave(KErrArgument); + + const TSize trgSize = aTrgBitmap->SizeInPixels(); + const TSize srcSize = aSrcBitmap->SizeInPixels(); + + // calculate the valid drawing area + TRect drawRect = aTrgRect; + drawRect.Intersection(TRect(TPoint(0, 0), trgSize)); + + if (drawRect.IsEmpty()) + return; + + CFbsBitmap* realSource = new (ELeave) CFbsBitmap(); + CleanupStack::PushL(realSource); + User::LeaveIfError(realSource->Create(srcSize, displayMode)); + CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL(realSource); + CleanupStack::PushL(dev); + CFbsBitGc* gc = NULL; + User::LeaveIfError(dev->CreateContext(gc)); + CleanupStack::PushL(gc); + gc->BitBlt(TPoint(0, 0), aSrcBitmap); + CleanupStack::PopAndDestroy(2); // dev, gc + + // Heap lock for FBServ large chunk is only needed with large bitmaps. + if (realSource->IsLargeBitmap() || aTrgBitmap->IsLargeBitmap()) { + aTrgBitmap->LockHeapLC(ETrue); // fbsheaplock + } else { + CleanupStack::PushL((TAny*) NULL); + } + + TUint32* srcAddress = realSource->DataAddress(); + TUint32* trgAddress = aTrgBitmap->DataAddress(); + + const TInt xSkip = (srcSize.iWidth << 8) / aTrgRect.Width(); + const TInt ySkip = (srcSize.iHeight << 8) / aTrgRect.Height(); + + const TInt drawWidth = drawRect.Width(); + const TInt drawHeight = drawRect.Height(); + + const TRect offsetRect(aTrgRect.iTl, drawRect.iTl); + const TInt yPosOffset = ySkip * offsetRect.Height(); + const TInt xPosOffset = xSkip * offsetRect.Width(); + + if ((displayMode == EGray256) || (displayMode == EColor256)) { + const TInt srcScanLen8 = CFbsBitmap::ScanLineLength(srcSize.iWidth, + displayMode); + const TInt trgScanLen8 = CFbsBitmap::ScanLineLength(trgSize.iWidth, + displayMode); + + TUint8* trgAddress8 = reinterpret_cast<TUint8*> (trgAddress); + + TInt yPos = yPosOffset; + // skip left and top margins in the beginning + trgAddress8 += trgScanLen8 * drawRect.iTl.iY + drawRect.iTl.iX; + + for (TInt y = 0; y < drawHeight; y++) { + const TUint8* srcAddress8 = reinterpret_cast<const TUint8*> (srcAddress) + + (srcScanLen8 * (yPos >> 8)); + + TInt xPos = xPosOffset; + for (TInt x = 0; x < drawWidth; x++) { + *(trgAddress8++) = srcAddress8[xPos >> 8]; + xPos += xSkip; + } + + yPos += ySkip; + + trgAddress8 += trgScanLen8 - drawWidth; + } + } else if (displayMode == EColor4K || displayMode == EColor64K) { + const TInt srcScanLen16 = CFbsBitmap::ScanLineLength(srcSize.iWidth, + displayMode) >>1; + const TInt trgScanLen16 = CFbsBitmap::ScanLineLength(trgSize.iWidth, + displayMode) >>1; + + TUint16* trgAddress16 = reinterpret_cast<TUint16*> (trgAddress); + + TInt yPos = yPosOffset; + // skip left and top margins in the beginning + trgAddress16 += trgScanLen16 * drawRect.iTl.iY + drawRect.iTl.iX; + + for (TInt y = 0; y < drawHeight; y++) { + const TUint16* srcAddress16 = reinterpret_cast<const TUint16*> (srcAddress) + + (srcScanLen16 * (yPos >> 8)); + + TInt xPos = xPosOffset; + for (TInt x = 0; x < drawWidth; x++) { + *(trgAddress16++) = srcAddress16[xPos >> 8]; + xPos += xSkip; + } + + yPos += ySkip; + + trgAddress16 += trgScanLen16 - drawWidth; + } + } else if (displayMode == EColor16MU || displayMode == EColor16MA) { + const TInt srcScanLen32 = CFbsBitmap::ScanLineLength(srcSize.iWidth, + displayMode) >>2; + const TInt trgScanLen32 = CFbsBitmap::ScanLineLength(trgSize.iWidth, + displayMode) >>2; + + TUint32* trgAddress32 = reinterpret_cast<TUint32*> (trgAddress); + + TInt yPos = yPosOffset; + // skip left and top margins in the beginning + trgAddress32 += trgScanLen32 * drawRect.iTl.iY + drawRect.iTl.iX; + + for (TInt y = 0; y < drawHeight; y++) { + const TUint32* srcAddress32 = reinterpret_cast<const TUint32*> (srcAddress) + + (srcScanLen32 * (yPos >> 8)); + + TInt xPos = xPosOffset; + for (TInt x = 0; x < drawWidth; x++) { + *(trgAddress32++) = srcAddress32[xPos >> 8]; + xPos += xSkip; + } + + yPos += ySkip; + + trgAddress32 += trgScanLen32 - drawWidth; + } + } else { User::Leave(KErrUnknown);} + + CleanupStack::PopAndDestroy(2); // fbsheaplock, realSource +} + +QSize QS60StylePrivate::screenSize() +{ + const TSize screenSize = QS60Data::screenDevice()->SizeInPixels(); + return QSize(screenSize.iWidth, screenSize.iHeight); +} + +void QS60StyleModeSpecifics::colorGroupAndIndex( + QS60StyleEnums::SkinParts skinID, TAknsItemID &colorGroup, int colorIndex) +{ + switch(skinID) { + case QS60StyleEnums::SP_QgnIndiSubMenu: + colorGroup = KAknsIIDQsnIconColors; + colorIndex = EAknsCIQsnIconColorsCG1; + break; + case QS60StyleEnums::SP_QgnIndiRadiobuttOff: + case QS60StyleEnums::SP_QgnIndiRadiobuttOn: + case QS60StyleEnums::SP_QgnIndiCheckboxOff: + case QS60StyleEnums::SP_QgnIndiCheckboxOn: + colorGroup = KAknsIIDQsnIconColors; + colorIndex = EAknsCIQsnIconColorsCG14; + break; + default: + break; + } +} + +/*! + Constructs a QS60Style object. +*/ +QS60Style::QS60Style() + : QCommonStyle(*new QS60StylePrivate) +{ +} + +void QS60Style::handleDynamicLayoutVariantSwitch() +{ + Q_D(QS60Style); + d->clearCaches(QS60StylePrivate::CC_LayoutChange); + d->setActiveLayout(); + d->refreshUI(); + d->setBackgroundTexture(qApp); + foreach (QWidget *widget, QApplication::allWidgets()) + widget->ensurePolished(); +} + +void QS60Style::handleSkinChange() +{ + Q_D(QS60Style); + d->clearCaches(QS60StylePrivate::CC_ThemeChange); + d->setThemePalette(qApp); + foreach (QWidget *topLevelWidget, QApplication::allWidgets()){ + QEvent e(QEvent::StyleChange); + QApplication::sendEvent(topLevelWidget, &e); + d->setThemePalette(topLevelWidget); + topLevelWidget->ensurePolished(); + } +} + +QT_END_NAMESPACE + +#endif // QT_NO_STYLE_S60 || QT_PLUGIN diff --git a/src/gui/styles/qs60style_simulated.cpp b/src/gui/styles/qs60style_simulated.cpp new file mode 100644 index 0000000000..684f23213f --- /dev/null +++ b/src/gui/styles/qs60style_simulated.cpp @@ -0,0 +1,449 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qs60style.h" +#include "qs60style_p.h" +#include "qfile.h" +#include "qhash.h" +#include "qapplication.h" +#include "qpainter.h" +#include "qpicture.h" +#include "qstyleoption.h" +#include "qtransform.h" +#include "qlayout.h" +#include "qpixmapcache.h" +#include "qmetaobject.h" +#include "qdebug.h" +#include "qbuffer.h" +#include "qdesktopwidget.h" + +#if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN) + +QT_BEGIN_NAMESPACE + +static const quint32 blobVersion = 1; +static const int pictureSize = 256; + +#if defined(Q_CC_GNU) +#if __GNUC__ >= 2 +#define __FUNCTION__ __func__ +#endif +#endif + + +bool saveThemeToBlob(const QString &themeBlob, + const QHash<QString, QPicture> &partPictures, + const QHash<QPair<QString, int>, QColor> &colors) +{ + QFile blob(themeBlob); + if (!blob.open(QIODevice::WriteOnly)) { + qWarning() << __FUNCTION__ << ": Could not create blob: " << themeBlob; + return false; + } + + QByteArray data; + QBuffer dataBuffer(&data); + dataBuffer.open(QIODevice::WriteOnly); + QDataStream dataOut(&dataBuffer); + + const int colorsCount = colors.count(); + dataOut << colorsCount; + const QList<QPair<QString, int> > colorKeys = colors.keys(); + for (int i = 0; i < colorsCount; ++i) { + const QPair<QString, int> &key = colorKeys.at(i); + dataOut << key; + const QColor color = colors.value(key); + dataOut << color; + } + + const int picturesCount = partPictures.count(); + dataOut << picturesCount; + foreach (const QString &key, partPictures.keys()) { + const QPicture picture = partPictures.value(key); + dataOut << key; + dataOut << picture; + } + + QDataStream blobOut(&blob); + blobOut << blobVersion; + blobOut << qCompress(data); + return blobOut.status() == QDataStream::Ok; +} + +bool loadThemeFromBlob(const QString &themeBlob, + QHash<QString, QPicture> &partPictures, + QHash<QPair<QString, int>, QColor> &colors) +{ + QFile blob(themeBlob); + if (!blob.open(QIODevice::ReadOnly)) { + qWarning() << __FUNCTION__ << ": Could not read blob: " << themeBlob; + return false; + } + QDataStream blobIn(&blob); + + quint32 version; + blobIn >> version; + + if (version != blobVersion) { + qWarning() << __FUNCTION__ << ": Invalid blob version: " << version << " ...expected: " << blobVersion; + return false; + } + + QByteArray data; + blobIn >> data; + data = qUncompress(data); + QBuffer dataBuffer(&data); + dataBuffer.open(QIODevice::ReadOnly); + QDataStream dataIn(&dataBuffer); + + int colorsCount; + dataIn >> colorsCount; + for (int i = 0; i < colorsCount; ++i) { + QPair<QString, int> key; + dataIn >> key; + QColor value; + dataIn >> value; + colors.insert(key, value); + } + + int picturesCount; + dataIn >> picturesCount; + for (int i = 0; i < picturesCount; ++i) { + QString key; + dataIn >> key; + QPicture value; + dataIn >> value; + value.setBoundingRect(QRect(0, 0, pictureSize, pictureSize)); // Bug? The forced bounding rect was not deserialized. + partPictures.insert(key, value); + } + + if (dataIn.status() != QDataStream::Ok) { + qWarning() << __FUNCTION__ << ": Invalid data blob: " << themeBlob; + return false; + } + return true; +} + +class QS60StyleModeSpecifics +{ +public: + static QPixmap skinnedGraphics(QS60StyleEnums::SkinParts stylepart, + const QSize &size, QS60StylePrivate::SkinElementFlags flags); + static QHash<QString, QPicture> m_partPictures; + static QHash<QPair<QString , int>, QColor> m_colors; +}; +QHash<QString, QPicture> QS60StyleModeSpecifics::m_partPictures; +QHash<QPair<QString , int>, QColor> QS60StyleModeSpecifics::m_colors; + +QS60StylePrivate::QS60StylePrivate() +{ + setCurrentLayout(0); +} + +QColor QS60StylePrivate::s60Color(QS60StyleEnums::ColorLists list, + int index, const QStyleOption *option) +{ + const QString listKey = QS60Style::colorListKeys().at(list); + return QS60StylePrivate::stateColor( + QS60StyleModeSpecifics::m_colors.value(QPair<QString, int>(listKey, index)), + option + ); +} + +QPixmap QS60StylePrivate::part(QS60StyleEnums::SkinParts part, const QSize &size, + QS60StylePrivate::SkinElementFlags flags) +{ + const QString partKey = QS60Style::partKeys().at(part); + const QPicture partPicture = QS60StyleModeSpecifics::m_partPictures.value(partKey); + QSize partSize(partPicture.boundingRect().size()); + if (flags & (SF_PointEast | SF_PointWest)) { + const int temp = partSize.width(); + partSize.setWidth(partSize.height()); + partSize.setHeight(temp); + } + const qreal scaleX = size.width() / (qreal)partSize.width(); + const qreal scaleY = size.height() / (qreal)partSize.height(); + + QImage partImage(size, QImage::Format_ARGB32); + partImage.fill(Qt::transparent); + QPainter resultPainter(&partImage); + QTransform t; + + if (flags & SF_PointEast) + t.translate(size.width(), 0); + else if (flags & SF_PointSouth) + t.translate(size.width(), size.height()); + else if (flags & SF_PointWest) + t.translate(0, size.height()); + + t.scale(scaleX, scaleY); + + if (flags & SF_PointEast) + t.rotate(90); + else if (flags & SF_PointSouth) + t.rotate(180); + else if (flags & SF_PointWest) + t.rotate(270); + + resultPainter.setTransform(t, true); + const_cast<QPicture *>(&partPicture)->play(&resultPainter); + resultPainter.end(); + + QPixmap result = QPixmap::fromImage(partImage); + if (flags & SF_StateDisabled) { + QStyleOption opt; + QPalette *themePalette = QS60StylePrivate::themePalette(); + if (themePalette) + opt.palette = *themePalette; + result = QApplication::style()->generatedIconPixmap(QIcon::Disabled, result, &opt); + } + + return result; +} + +QPixmap QS60StylePrivate::frame(SkinFrameElements frame, const QSize &size, + SkinElementFlags flags) +{ + const QS60StyleEnums::SkinParts center = m_frameElementsData[frame].center; + const QS60StyleEnums::SkinParts topLeft = QS60StyleEnums::SkinParts(center - 8); + const QS60StyleEnums::SkinParts topRight = QS60StyleEnums::SkinParts(center - 7); + const QS60StyleEnums::SkinParts bottomLeft = QS60StyleEnums::SkinParts(center - 6); + const QS60StyleEnums::SkinParts bottomRight = QS60StyleEnums::SkinParts(center - 5); + const QS60StyleEnums::SkinParts top = QS60StyleEnums::SkinParts(center - 4); + const QS60StyleEnums::SkinParts bottom = QS60StyleEnums::SkinParts(center - 3); + const QS60StyleEnums::SkinParts left = QS60StyleEnums::SkinParts(center - 2); + const QS60StyleEnums::SkinParts right = QS60StyleEnums::SkinParts(center - 1); + + // The size of topLeft defines all other sizes + const QSize cornerSize(partSize(topLeft)); + // if frame is so small that corners would cover it completely, draw only center piece + const bool drawOnlyCenter = + 2 * cornerSize.width() + 1 >= size.width() || 2 * cornerSize.height() + 1 >= size.height(); + + const int cornerWidth = cornerSize.width(); + const int cornerHeight = cornerSize.height(); + const int rectWidth = size.width(); + const int rectHeight = size.height(); + const QRect rect(QPoint(), size); + + const QRect topLeftRect = QRect(rect.topLeft(), cornerSize); + const QRect topRect = rect.adjusted(cornerWidth, 0, -cornerWidth, -(rectHeight - cornerHeight)); + const QRect topRightRect = topLeftRect.translated(rectWidth - cornerWidth, 0); + const QRect rightRect = rect.adjusted(rectWidth - cornerWidth, cornerHeight, 0, -cornerHeight); + const QRect bottomRightRect = topRightRect.translated(0, rectHeight - cornerHeight); + const QRect bottomRect = topRect.translated(0, rectHeight - cornerHeight); + const QRect bottomLeftRect = topLeftRect.translated(0, rectHeight - cornerHeight); + const QRect leftRect = rightRect.translated(cornerWidth - rectWidth, 0); + const QRect centerRect = drawOnlyCenter ? rect : rect.adjusted(cornerWidth, cornerWidth, -cornerWidth, -cornerWidth); + + QPixmap result(size); + result.fill(Qt::transparent); + QPainter painter(&result); + +#if 0 + painter.save(); + painter.setOpacity(.3); + painter.fillRect(topLeftRect, Qt::red); + painter.fillRect(topRect, Qt::green); + painter.fillRect(topRightRect, Qt::blue); + painter.fillRect(rightRect, Qt::green); + painter.fillRect(bottomRightRect, Qt::red); + painter.fillRect(bottomRect, Qt::blue); + painter.fillRect(bottomLeftRect, Qt::green); + painter.fillRect(leftRect, Qt::blue); + painter.fillRect(centerRect, Qt::red); + painter.restore(); +#else + drawPart(topLeft, &painter, topLeftRect, flags); + drawPart(top, &painter, topRect, flags); + drawPart(topRight, &painter, topRightRect, flags); + drawPart(right, &painter, rightRect, flags); + drawPart(bottomRight, &painter, bottomRightRect, flags); + drawPart(bottom, &painter, bottomRect, flags); + drawPart(bottomLeft, &painter, bottomLeftRect, flags); + drawPart(left, &painter, leftRect, flags); + drawPart(center, &painter, centerRect, flags); +#endif + + return result; +} + +void QS60StylePrivate::setStyleProperty_specific(const char *name, const QVariant &value) +{ + setStyleProperty(name, value); +} + +QVariant QS60StylePrivate::styleProperty_specific(const char *name) const +{ + return styleProperty(name); +} + +QPixmap QS60StylePrivate::backgroundTexture() +{ + if (!m_background) { + const QSize size = QApplication::desktop()->screen()->size(); + QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen, size); + m_background = new QPixmap(background); + } + return *m_background; +} + + +bool QS60StylePrivate::isTouchSupported() +{ +#ifdef QT_KEYPAD_NAVIGATION + return !QApplication::keypadNavigationEnabled(); +#else + return true; +#endif +} + +bool QS60StylePrivate::isToolBarBackground() +{ + return true; +} + +QFont QS60StylePrivate::s60Font_specific(QS60StyleEnums::FontCategories fontCategory, int pointSize) +{ + QFont result; + result.setPointSize(pointSize); + switch (fontCategory) { + case QS60StyleEnums::FC_Primary: + result.setBold(true); + break; + case QS60StyleEnums::FC_Secondary: + case QS60StyleEnums::FC_Title: + case QS60StyleEnums::FC_PrimarySmall: + case QS60StyleEnums::FC_Digital: + case QS60StyleEnums::FC_Undefined: + default: + break; + } + return result; +} + +/*! + Constructs a QS60Style object. +*/ +QS60Style::QS60Style() + : QCommonStyle(*new QS60StylePrivate) +{ + // Assume, that the resource system has a ':/s60Stylethemes/Default.blob' + const QString defaultBlob = QString::fromLatin1(":/s60Stylethemes/Default.blob"); + if (QFile::exists(defaultBlob)) + loadS60ThemeFromBlob(defaultBlob); +} + +Q_GLOBAL_STATIC_WITH_INITIALIZER(QStringList, enumPartKeys, { + const int enumIndex = QS60StyleEnums::staticMetaObject.indexOfEnumerator("SkinParts"); + Q_ASSERT(enumIndex >= 0); + const QMetaEnum metaEnum = QS60StyleEnums::staticMetaObject.enumerator(enumIndex); + for (int i = 0; i < metaEnum.keyCount(); ++i) { + const QString enumKey = QString::fromLatin1(metaEnum.key(i)); + QString partKey; + // Following loop does following conversions: "SP_QgnNoteInfo" to "qgn_note_info"... + for (int charPosition = 3; charPosition < enumKey.length(); charPosition++) { + if (charPosition > 3 && enumKey[charPosition].isUpper()) + partKey.append(QChar::fromLatin1('_')); + partKey.append(enumKey[charPosition].toLower()); + } + x->append(partKey); + } +}) + +QStringList QS60Style::partKeys() +{ + return *enumPartKeys(); +} + +Q_GLOBAL_STATIC_WITH_INITIALIZER(QStringList, enumColorListKeys, { + const int enumIndex = QS60StyleEnums::staticMetaObject.indexOfEnumerator("ColorLists"); + Q_ASSERT(enumIndex >= 0); + const QMetaEnum metaEnum = QS60StyleEnums::staticMetaObject.enumerator(enumIndex); + for (int i = 0; i < metaEnum.keyCount(); i++) { + const QString enumKey = QString::fromLatin1(metaEnum.key(i)); + // Following line does following conversions: CL_QsnTextColors to "text"... + x->append(enumKey.mid(6, enumKey.length() - 12).toLower()); + } +}) + +QStringList QS60Style::colorListKeys() +{ + return *enumColorListKeys(); +} + +void QS60Style::setS60Theme(const QHash<QString, QPicture> &parts, + const QHash<QPair<QString , int>, QColor> &colors) +{ + Q_D(QS60Style); + QS60StyleModeSpecifics::m_partPictures = parts; + QS60StyleModeSpecifics::m_colors = colors; + d->clearCaches(QS60StylePrivate::CC_ThemeChange); + d->setBackgroundTexture(qApp); + d->setThemePalette(qApp); +} + +bool QS60Style::loadS60ThemeFromBlob(const QString &blobFile) +{ + QHash<QString, QPicture> partPictures; + QHash<QPair<QString, int>, QColor> colors; + + if (!loadThemeFromBlob(blobFile, partPictures, colors)) + return false; + setS60Theme(partPictures, colors); + return true; +} + +bool QS60Style::saveS60ThemeToBlob(const QString &blobFile) const +{ + return saveThemeToBlob(blobFile, + QS60StyleModeSpecifics::m_partPictures, QS60StyleModeSpecifics::m_colors); +} + +QPoint qt_s60_fill_background_offset(const QWidget *targetWidget) +{ + Q_UNUSED(targetWidget) + return QPoint(); +} + +QT_END_NAMESPACE + +#endif // QT_NO_STYLE_S60 || QT_PLUGIN diff --git a/src/gui/styles/qstyle.h b/src/gui/styles/qstyle.h index f22bf55a63..68d4734c3a 100644 --- a/src/gui/styles/qstyle.h +++ b/src/gui/styles/qstyle.h @@ -68,7 +68,7 @@ class QStylePrivate; class Q_GUI_EXPORT QStyle : public QObject { Q_OBJECT - Q_DECLARE_PRIVATE(QStyle) + Q_DECLARE_SCOPED_PRIVATE(QStyle) protected: QStyle(QStylePrivate &dd); diff --git a/src/gui/styles/qstyle_p.h b/src/gui/styles/qstyle_p.h index 2d6ef22214..11be2f86af 100644 --- a/src/gui/styles/qstyle_p.h +++ b/src/gui/styles/qstyle_p.h @@ -65,7 +65,7 @@ class QStyle; class QStylePrivate: public QObjectPrivate { - Q_DECLARE_PUBLIC(QStyle); + Q_DECLARE_PUBLIC(QStyle) public: inline QStylePrivate() : layoutSpacingIndex(-1), proxyStyle(0) {} diff --git a/src/gui/styles/qstyle_s60_simulated.qrc b/src/gui/styles/qstyle_s60_simulated.qrc new file mode 100644 index 0000000000..72aab9e624 --- /dev/null +++ b/src/gui/styles/qstyle_s60_simulated.qrc @@ -0,0 +1,6 @@ +<!DOCTYPE RCC> +<RCC version="1.0"> + <qresource prefix="/trolltech/styles/s60style"> + <file>images/s60themes.dat</file> + </qresource> +</RCC> diff --git a/src/gui/styles/qstylefactory.cpp b/src/gui/styles/qstylefactory.cpp index 36f405caff..a1d585ddac 100644 --- a/src/gui/styles/qstylefactory.cpp +++ b/src/gui/styles/qstylefactory.cpp @@ -69,6 +69,9 @@ #ifndef QT_NO_STYLE_WINDOWSMOBILE #include "qwindowsmobilestyle.h" #endif +#ifndef QT_NO_STYLE_S60 +#include "qs60style.h" +#endif QT_BEGIN_NAMESPACE @@ -154,6 +157,11 @@ QStyle *QStyleFactory::create(const QString& key) ret = new QCDEStyle; else #endif +#ifndef QT_NO_STYLE_S60 + if (style == QLatin1String("s60")) + ret = new QS60Style; + else +#endif #ifndef QT_NO_STYLE_PLASTIQUE if (style == QLatin1String("plastique")) ret = new QPlastiqueStyle; @@ -233,6 +241,10 @@ QStringList QStyleFactory::keys() if (!list.contains(QLatin1String("CDE"))) list << QLatin1String("CDE"); #endif +#ifndef QT_NO_STYLE_S60 + if (!list.contains(QLatin1String("S60"))) + list << QLatin1String("S60"); +#endif #ifndef QT_NO_STYLE_PLASTIQUE if (!list.contains(QLatin1String("Plastique"))) list << QLatin1String("Plastique"); diff --git a/src/gui/styles/qstylesheetstyle_default.cpp b/src/gui/styles/qstylesheetstyle_default.cpp index b008c12227..91464f7a94 100644 --- a/src/gui/styles/qstylesheetstyle_default.cpp +++ b/src/gui/styles/qstylesheetstyle_default.cpp @@ -154,11 +154,12 @@ StyleSheet QStyleSheetStyle::getDefaultStyleSheet() const Value value; Pseudo pseudo; AttributeSelector attr; - + // pixmap based style doesn't support any features bool styleIsPixmapBased = baseStyle()->inherits("QMacStyle") || baseStyle()->inherits("QWindowsXPStyle") - || baseStyle()->inherits("QGtkStyle"); + || baseStyle()->inherits("QGtkStyle") + || baseStyle()->inherits("QS60Style"); /*QLineEdit { @@ -212,7 +213,7 @@ StyleSheet QStyleSheetStyle::getDefaultStyleSheet() const ADD_BASIC_SELECTOR; ADD_SELECTOR; - + SET_PROPERTY(QLatin1String("padding-top"), PaddingTop); ADD_VALUE(Value::Identifier, QString::fromLatin1("2px")); ADD_DECLARATION; diff --git a/src/gui/styles/qstylesheetstyle_p.h b/src/gui/styles/qstylesheetstyle_p.h index 9b7b79d0f7..399e449da5 100644 --- a/src/gui/styles/qstylesheetstyle_p.h +++ b/src/gui/styles/qstylesheetstyle_p.h @@ -182,7 +182,7 @@ public: private: Q_DISABLE_COPY(QStyleSheetStyle) - Q_DECLARE_PRIVATE(QStyleSheetStyle) + Q_DECLARE_SCOPED_PRIVATE(QStyleSheetStyle) }; diff --git a/src/gui/styles/qwindowsmobilestyle.h b/src/gui/styles/qwindowsmobilestyle.h index ab32e8e8c3..9892decd70 100644 --- a/src/gui/styles/qwindowsmobilestyle.h +++ b/src/gui/styles/qwindowsmobilestyle.h @@ -104,7 +104,7 @@ protected: QWindowsMobileStyle(QWindowsMobileStylePrivate &dd); private: - Q_DECLARE_PRIVATE(QWindowsMobileStyle) + Q_DECLARE_SCOPED_PRIVATE(QWindowsMobileStyle) }; #endif // QT_NO_STYLE_WINDOWSMOBILE diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp index 4c66bbb79a..bc1df9d546 100644 --- a/src/gui/styles/qwindowsstyle.cpp +++ b/src/gui/styles/qwindowsstyle.cpp @@ -122,7 +122,8 @@ static const int windowsItemHMargin = 3; // menu item hor text margin static const int windowsItemVMargin = 2; // menu item ver text margin static const int windowsArrowHMargin = 6; // arrow horizontal margin static const int windowsTabSpacing = 12; // space between text and tab -static const int windowsCheckMarkHMargin = 2; // horiz. margins of check mark +// Save some space and avoid warning. +//static const int windowsCheckMarkHMargin = 2; // horiz. margins of check mark static const int windowsRightBorder = 15; // right border on windows static const int windowsCheckMarkWidth = 12; // checkmarks width on windows @@ -2485,7 +2486,6 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai bool floating = false; bool active = dwOpt->state & State_Active; - int menuOffset = 0; //used to center text when floated QColor inactiveCaptionTextColor = d->inactiveCaptionText; if (dwOpt->movable) { QColor left, right; @@ -2500,7 +2500,6 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai left = d->inactiveCaptionColor; right = d->inactiveGradientCaptionColor; } - menuOffset = 2; QBrush fillBrush(left); if (left != right) { QPoint p1(r.x(), r.top() + r.height()/2); diff --git a/src/gui/styles/qwindowsstyle.h b/src/gui/styles/qwindowsstyle.h index c169a84a43..45260e8a85 100644 --- a/src/gui/styles/qwindowsstyle.h +++ b/src/gui/styles/qwindowsstyle.h @@ -98,7 +98,7 @@ protected: private: Q_DISABLE_COPY(QWindowsStyle) - Q_DECLARE_PRIVATE(QWindowsStyle) + Q_DECLARE_SCOPED_PRIVATE(QWindowsStyle) void *reserved; }; diff --git a/src/gui/styles/qwindowsvistastyle.h b/src/gui/styles/qwindowsvistastyle.h index 97b1e74038..60cd7a527a 100644 --- a/src/gui/styles/qwindowsvistastyle.h +++ b/src/gui/styles/qwindowsvistastyle.h @@ -96,7 +96,7 @@ protected Q_SLOTS: private: Q_DISABLE_COPY(QWindowsVistaStyle) - Q_DECLARE_PRIVATE(QWindowsVistaStyle) + Q_DECLARE_SCOPED_PRIVATE(QWindowsVistaStyle) friend class QStyleFactory; }; #endif //QT_NO_STYLE_WINDOWSVISTA diff --git a/src/gui/styles/qwindowsxpstyle.h b/src/gui/styles/qwindowsxpstyle.h index ab26f566d3..21e24ff452 100644 --- a/src/gui/styles/qwindowsxpstyle.h +++ b/src/gui/styles/qwindowsxpstyle.h @@ -93,7 +93,7 @@ protected Q_SLOTS: private: Q_DISABLE_COPY(QWindowsXPStyle) - Q_DECLARE_PRIVATE(QWindowsXPStyle) + Q_DECLARE_SCOPED_PRIVATE(QWindowsXPStyle) friend class QStyleFactory; void *reserved; }; diff --git a/src/gui/styles/styles.pri b/src/gui/styles/styles.pri index d255f80c27..277be765d6 100644 --- a/src/gui/styles/styles.pri +++ b/src/gui/styles/styles.pri @@ -161,3 +161,19 @@ contains( styles, windowsmobile ) { DEFINES += QT_NO_STYLE_WINDOWSMOBILE } +contains( styles, s60 ):contains(QT_CONFIG, s60) { + HEADERS += \ + styles/qs60style.h \ + styles/qs60style_p.h + SOURCES += styles/qs60style.cpp + symbian { + SOURCES += styles/qs60style_s60.cpp + # TODO: fix the following LIBS hack. Line 1 is for armv5, 2 for winscw + LIBS += aknicon aknskins aknskinsrv fontutils + LIBS += -laknicon -laknskins -laknskinsrv -lfontutils + } else { + SOURCES += styles/qs60style_simulated.cpp + } +} else { + DEFINES += QT_NO_STYLE_S60 +} |