diff options
Diffstat (limited to 'src/gui/styles')
-rw-r--r-- | src/gui/styles/qmacstyle.qdoc | 10 | ||||
-rw-r--r-- | src/gui/styles/qmacstyle_mac.mm | 5 | ||||
-rw-r--r-- | src/gui/styles/qs60style.cpp | 123 | ||||
-rw-r--r-- | src/gui/styles/qs60style_feedbackinterface_p.h | 50 | ||||
-rw-r--r-- | src/gui/styles/qs60style_p.h | 11 | ||||
-rw-r--r-- | src/gui/styles/qs60style_s60.cpp | 99 | ||||
-rw-r--r-- | src/gui/styles/qstyle.cpp | 8 | ||||
-rw-r--r-- | src/gui/styles/qstylesheetstyle.cpp | 143 | ||||
-rw-r--r-- | src/gui/styles/qstylesheetstyle_p.h | 20 | ||||
-rw-r--r-- | src/gui/styles/qwindowsxpstyle.cpp | 2 | ||||
-rw-r--r-- | src/gui/styles/styles.pri | 2 |
11 files changed, 307 insertions, 166 deletions
diff --git a/src/gui/styles/qmacstyle.qdoc b/src/gui/styles/qmacstyle.qdoc index a86f2ed..3efabe1 100644 --- a/src/gui/styles/qmacstyle.qdoc +++ b/src/gui/styles/qmacstyle.qdoc @@ -7,11 +7,11 @@ ** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:FDL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in a -** written agreement between you and Nokia. +** 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 Technology Preview License Agreement accompanying +** this package. ** ** GNU Free Documentation License ** Alternatively, this file may be used under the terms of the GNU Free diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm index 3a05f40..a05ec6b 100644 --- a/src/gui/styles/qmacstyle_mac.mm +++ b/src/gui/styles/qmacstyle_mac.mm @@ -1948,10 +1948,9 @@ void QMacStyle::unpolish(QWidget* w) rubber->setAttribute(Qt::WA_NoSystemBackground, true); } - if (QFocusFrame *frame = qobject_cast<QFocusFrame *>(w)) { + if (QFocusFrame *frame = qobject_cast<QFocusFrame *>(w)) frame->setAttribute(Qt::WA_NoSystemBackground, true); - frame->setAutoFillBackground(true); - } + QWindowsStyle::unpolish(w); } diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 89f54bc..087907f 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -405,13 +405,14 @@ void QS60StylePrivate::clearCaches(CacheClearReason reason) QPixmapCache::clear(); break; case CC_ThemeChange: - m_colorCache.clear(); QPixmapCache::clear(); +#ifdef Q_WS_S60 + deleteStoredSettings(); +#endif deleteBackground(); break; case CC_UndefinedChange: default: - m_colorCache.clear(); m_mappedFontsCache.clear(); QPixmapCache::clear(); deleteBackground(); @@ -419,64 +420,53 @@ void QS60StylePrivate::clearCaches(CacheClearReason reason) } } -// 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 +QColor QS60StylePrivate::calculatedColor(SkinFrameElements frame) const { - const bool cachedColorExists = m_colorCache.contains(frame); - if (!cachedColorExists) { - const int frameCornerWidth = pixelMetric(PM_FrameCornerWidth); - const int frameCornerHeight = pixelMetric(PM_FrameCornerHeight); - Q_ASSERT(2 * frameCornerWidth < 32); - Q_ASSERT(2 * frameCornerHeight < 32); - - const QImage frameImage = QS60StylePrivate::frame(frame, QSize(32, 32)).toImage(); - Q_ASSERT(frameImage.bytesPerLine() > 0); - if (frameImage.isNull()) - return Qt::black; - - const QRgb *pixelRgb = (const QRgb*)frameImage.bits(); - const int pixels = frameImage.byteCount()/sizeof(QRgb); - - 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++; + const int frameCornerWidth = pixelMetric(PM_FrameCornerWidth); + const int frameCornerHeight = pixelMetric(PM_FrameCornerHeight); + Q_ASSERT(2 * frameCornerWidth < 32); + Q_ASSERT(2 * frameCornerHeight < 32); + + const QImage frameImage = QS60StylePrivate::frame(frame, QSize(32, 32)).toImage(); + Q_ASSERT(frameImage.bytesPerLine() > 0); + if (frameImage.isNull()) + return Qt::black; + + const QRgb *pixelRgb = (const QRgb*)frameImage.constBits(); + const int pixels = frameImage.byteCount() / sizeof(QRgb); + + 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() - topBorderLastPixel; + 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); } - } else { pixelRgb++; - skips++; + 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); } - + QColor frameColor(estimatedRed/estimations, estimatedGreen/estimations, estimatedBlue/estimations); + return !estimations ? Qt::black : frameColor; } void QS60StylePrivate::setThemePalette(QApplication *app) const @@ -731,11 +721,14 @@ void QS60StylePrivate::setThemePalette(QPalette *palette) const palette->setBrush(QPalette::Window, backgroundTexture()); // set as transparent so that styled full screen theme background is visible palette->setBrush(QPalette::Base, Qt::transparent); - // set button and tooltipbase based on pixel colors + // set button color based on pixel colors +#ifndef Q_WS_S60 + //For emulated style, just calculate the color every time + const QColor buttonColor = calculatedColor(SF_ButtonNormal); +#else const QColor buttonColor = colorFromFrameGraphics(SF_ButtonNormal); +#endif palette->setColor(QPalette::Button, buttonColor); - const QColor toolTipColor = 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)); @@ -837,11 +830,8 @@ void QS60StylePrivate::setThemePaletteHash(QPalette *palette) const s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0)); QApplication::setPalette(widgetPalette, "QLineEdit"); QApplication::setPalette(widgetPalette, "QTextEdit"); - widgetPalette = *palette; - - widgetPalette.setColor(QPalette::HighlightedText, - s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0)); QApplication::setPalette(widgetPalette, "QComboBox"); + QApplication::setPalette(widgetPalette, "QSpinBox"); widgetPalette = *palette; widgetPalette.setColor(QPalette::WindowText, s60Color(QS60StyleEnums::CL_QsnTextColors, 7, 0)); @@ -2524,9 +2514,9 @@ int QS60Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const metricValue = QS60StylePrivate::pixelMetric(PM_LayoutLeftMargin); } - if (widget && (metric == PM_LayoutTopMargin)) + if (widget && (metric == PM_LayoutTopMargin || metric == PM_LayoutLeftMargin || metric == PM_LayoutRightMargin)) if (widget->windowType() == Qt::Dialog) - //double the top layout margin for dialogs, it is very close to real value + //double the layout margins (except bottom) for dialogs, it is very close to real value //without having to define custom pixel metric metricValue *= 2; @@ -2620,6 +2610,8 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); break; } + if (!sz.isValid()) + sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget); return sz; } @@ -3425,8 +3417,11 @@ bool QS60Style::eventFilter(QObject *object, QEvent *event) qobject_cast<QCheckBox *>(w)) d->m_pressedWidget = w; - if ( d->m_pressedWidget) + if (d->m_pressedWidget) d->m_pressedWidget->update(); +#ifdef Q_WS_S60 + d->touchFeedback(event, w); +#endif } break; } diff --git a/src/gui/styles/qs60style_feedbackinterface_p.h b/src/gui/styles/qs60style_feedbackinterface_p.h new file mode 100644 index 0000000..81fcdc3 --- /dev/null +++ b/src/gui/styles/qs60style_feedbackinterface_p.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QObject> + +class TactileFeedbackInterface : public QObject +{ + public: + virtual void touchFeedback(QEvent *event, const QWidget *widget) = 0; +}; + +Q_DECLARE_INTERFACE(TactileFeedbackInterface, "com.trolltech.Qt.TactileFeedbackInterface/1.0") diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index b3f4160..db4285d 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -387,6 +387,7 @@ private: //data members class QFocusFrame; class QProgressBar; class QS60StyleAnimation; +class TactileFeedbackInterface; // Private class #ifdef Q_OS_SYMBIAN @@ -522,8 +523,12 @@ public: static bool isSingleClickUi(); static bool isWidgetPressed(const QWidget *widget); - // calculates average color based on button skin graphics (minus borders). +#ifdef Q_WS_S60 + static void deleteStoredSettings(); + // calculates average color based on theme graphics (minus borders). QColor colorFromFrameGraphics(SkinFrameElements frame) const; +#endif + QColor calculatedColor(SkinFrameElements frame) const; //set theme palette for application void setThemePalette(QApplication *application) const; @@ -541,7 +546,6 @@ public: 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 { @@ -572,6 +576,8 @@ public: void stopAnimation(QS60StyleEnums::SkinParts animation); static QS60StyleAnimation* animationDefinition(QS60StyleEnums::SkinParts part); static void removeAnimations(); + //No support for tactile feedback in emulated style + void touchFeedback(QEvent *event, const QWidget *widget); #endif @@ -626,6 +632,7 @@ private: #ifdef Q_WS_S60 //list of progress bars having animation running QList<QProgressBar *> m_bars; + TactileFeedbackInterface *m_feedbackPlugin; #endif }; diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index 5dda42e..7b75d40 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -48,6 +48,11 @@ #include "private/qpixmap_s60_p.h" #include "private/qcore_symbian_p.h" #include "qapplication.h" +#include "qsettings.h" + +#include "qpluginloader.h" +#include "qlibraryinfo.h" +#include "private/qs60style_feedbackinterface_p.h" #include <w32std.h> #include <AknsConstants.h> @@ -65,6 +70,8 @@ #include <gulicon.h> #include <AknBitmapAnimation.h> +#include <centralrepository.h> + #if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN) QT_BEGIN_NAMESPACE @@ -77,6 +84,8 @@ enum TDrawType { ENoDraw }; +const TUid personalisationUID = { 0x101F876F }; + enum TSupportRelease { ES60_None = 0x0000, //indicates that the commonstyle should draw the graphics ES60_3_1 = 0x0001, @@ -685,6 +694,76 @@ bool QS60StylePrivate::isSingleClickUi() return (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0); } +void QS60StylePrivate::deleteStoredSettings() +{ + QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); + settings.beginGroup(QLatin1String("QS60Style")); + settings.remove(""); + settings.endGroup(); +} + +// Since S60Style has 'button' as a graphic, we don't have any native color which to use +// for QPalette::Button. Therefore S60Style needs to guesstimate palette color by calculating +// average rgb values for button pixels. +// Returns Qt::black if there is an issue with the graphics (image is NULL, or no constBits() found). +QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const +{ +#ifndef QT_NO_SETTINGS + TInt themeID = 0; + //First we need to fetch active theme ID. We need to store the themeID at the same time + //as color, so that we can later check if the stored color is still from the same theme. + //Native side stores active theme UID/Timestamp into central repository. + int error = 0; + QT_TRAP_THROWING( + CRepository *themeRepository = CRepository::NewLC(personalisationUID); + if (themeRepository) { + static const TInt KThemePkgIDDesSize = 23; //size of the stored theme package ID + TBuf<32> value; //themeID is currently max of 8 + 1 + 8 characters, but lets have some extra space + const TUint32 key = 0x00000002; //active theme key in the repository + error = themeRepository->Get(key, value); + if (error == KErrNone) { + TLex lex(value); + TPtrC numberToken(lex.NextToken()); + if (numberToken.Length()) + error = TLex(numberToken).Val(themeID); + else + error = KErrArgument; + } + } + CleanupStack::PopAndDestroy(themeRepository); + ); + + QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); + settings.beginGroup(QLatin1String("QS60Style")); + if (themeID != 0) { + QVariant buttonColor = settings.value(QLatin1String("ButtonColor")); + if (!buttonColor.isNull()) { + //there is a stored color value, lets see if the theme ID matches + if (error == KErrNone) { + QVariant themeUID = settings.value(QLatin1String("ThemeUID")); + if (!themeUID.isNull() && themeUID.toInt() == themeID) { + QColor storedColor(buttonColor.value<QColor>()); + if (storedColor.isValid()) + return storedColor; + } + } + settings.remove(""); //if color was invalid, or theme has been changed, just delete all stored settings + } + } +#endif + + QColor color = calculatedColor(frame); + +#ifndef QT_NO_SETTINGS + settings.setValue(QLatin1String("ThemeUID"), QVariant(themeID)); + if (frame == SF_ButtonNormal) //other colors are not currently calculated from graphics + settings.setValue(QLatin1String("ButtonColor"), QVariant(color)); + settings.endGroup(); +#endif + + return color; +} + QPoint qt_s60_fill_background_offset(const QWidget *targetWidget) { CCoeControl *control = targetWidget->effectiveWinId(); @@ -1143,13 +1222,25 @@ void QS60StylePrivate::setActiveLayout() Q_GLOBAL_STATIC(QList<QS60StyleAnimation *>, m_animations) -QS60StylePrivate::QS60StylePrivate() +QS60StylePrivate::QS60StylePrivate() : m_feedbackPlugin(0) { //Animation defaults need to be created when style is instantiated QS60StyleAnimation* progressBarAnimation = new QS60StyleAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim, 7, 100); m_animations()->append(progressBarAnimation); // No need to set active layout, if dynamic metrics API is available setActiveLayout(); + + //Tactile feedback plugin is only available for touch devices. + if (isTouchSupported()) { + QString pluginsPath = QLibraryInfo::location(QLibraryInfo::PluginsPath); + pluginsPath += QLatin1String("/feedback/qtactilefeedback.dll"); + + // Create plugin loader + QPluginLoader pluginLoader(pluginsPath); + // Load plugin and store pointer to the plugin implementation + if (pluginLoader.load()) + m_feedbackPlugin = qobject_cast<TactileFeedbackInterface*>(pluginLoader.instance()); + } } void QS60StylePrivate::removeAnimations() @@ -1439,6 +1530,12 @@ void QS60StylePrivate::stopAnimation(QS60StyleEnums::SkinParts animationPart) } } +void QS60StylePrivate::touchFeedback(QEvent *event, const QWidget *widget) +{ + if (m_feedbackPlugin) + m_feedbackPlugin->touchFeedback(event, widget); +} + QVariant QS60StyleModeSpecifics::themeDefinition( QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part) { diff --git a/src/gui/styles/qstyle.cpp b/src/gui/styles/qstyle.cpp index 0a75492..3ebfab2 100644 --- a/src/gui/styles/qstyle.cpp +++ b/src/gui/styles/qstyle.cpp @@ -367,10 +367,10 @@ QStyle::~QStyle() Note that the default implementation does nothing. Reasonable actions in this function might be to call the QWidget::setBackgroundMode() function for the widget. Do not use - the function to set, for example, the geometry; reimplementing - this function do provide a back-door through which the appearance - of a widget can be changed, but with Qt 4.0's style engine there - is rarely necessary to implement this function; reimplement the + the function to set, for example, the geometry. Reimplementing + this function provides a back-door through which the appearance + of a widget can be changed, but with Qt's style engine it is + rarely necessary to implement this function; reimplement drawItemPixmap(), drawItemText(), drawPrimitive(), etc. instead. The QWidget::inherits() function may provide enough information to diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index 4be439d..fb6fc23 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -99,14 +99,7 @@ public: }; -static QHash<const QWidget *, QVector<StyleRule> > *styleRulesCache = 0; -static QHash<const QWidget *, QHash<int, bool> > *hasStyleRuleCache = 0; -typedef QHash<int, QHash<quint64, QRenderRule> > QRenderRules; -static QHash<const QWidget *, QRenderRules> *renderRulesCache = 0; -static QHash<const QWidget *, QPalette> *customPaletteWidgets = 0; // widgets whose palette we tampered -static QHash<const void *, StyleSheet> *styleSheetCache = 0; // parsed style sheets -static QSet<const QWidget *> *autoFillDisabledWidgets = 0; - +static QStyleSheetStyleCaches *styleSheetCaches = 0; /* RECURSION_GUARD: * the QStyleSheetStyle is a proxy. If used with others proxy style, we may end up with something like: @@ -1525,8 +1518,8 @@ private: QVector<QCss::StyleRule> QStyleSheetStyle::styleRules(const QWidget *w) const { - QHash<const QWidget *, QVector<StyleRule> >::const_iterator cacheIt = styleRulesCache->constFind(w); - if (cacheIt != styleRulesCache->constEnd()) + QHash<const QWidget *, QVector<StyleRule> >::const_iterator cacheIt = styleSheetCaches->styleRulesCache.constFind(w); + if (cacheIt != styleSheetCaches->styleRulesCache.constEnd()) return cacheIt.value(); if (!initWidget(w)) { @@ -1536,12 +1529,12 @@ QVector<QCss::StyleRule> QStyleSheetStyle::styleRules(const QWidget *w) const QStyleSheetStyleSelector styleSelector; StyleSheet defaultSs; - QHash<const void *, StyleSheet>::const_iterator defaultCacheIt = styleSheetCache->constFind(baseStyle()); - if (defaultCacheIt == styleSheetCache->constEnd()) { + QHash<const void *, StyleSheet>::const_iterator defaultCacheIt = styleSheetCaches->styleSheetCache.constFind(baseStyle()); + if (defaultCacheIt == styleSheetCaches->styleSheetCache.constEnd()) { defaultSs = getDefaultStyleSheet(); QStyle *bs = baseStyle(); - styleSheetCache->insert(bs, defaultSs); - QObject::connect(bs, SIGNAL(destroyed(QObject*)), this, SLOT(styleDestroyed(QObject*)), Qt::UniqueConnection); + styleSheetCaches->styleSheetCache.insert(bs, defaultSs); + QObject::connect(bs, SIGNAL(destroyed(QObject*)), styleSheetCaches, SLOT(styleDestroyed(QObject*)), Qt::UniqueConnection); } else { defaultSs = defaultCacheIt.value(); } @@ -1549,8 +1542,8 @@ QVector<QCss::StyleRule> QStyleSheetStyle::styleRules(const QWidget *w) const if (!qApp->styleSheet().isEmpty()) { StyleSheet appSs; - QHash<const void *, StyleSheet>::const_iterator appCacheIt = styleSheetCache->constFind(qApp); - if (appCacheIt == styleSheetCache->constEnd()) { + QHash<const void *, StyleSheet>::const_iterator appCacheIt = styleSheetCaches->styleSheetCache.constFind(qApp); + if (appCacheIt == styleSheetCaches->styleSheetCache.constEnd()) { QString ss = qApp->styleSheet(); if (ss.startsWith(QLatin1String("file:///"))) ss.remove(0, 8); @@ -1559,7 +1552,7 @@ QVector<QCss::StyleRule> QStyleSheetStyle::styleRules(const QWidget *w) const qWarning("Could not parse application stylesheet"); appSs.origin = StyleSheetOrigin_Inline; appSs.depth = 1; - styleSheetCache->insert(qApp, appSs); + styleSheetCaches->styleSheetCache.insert(qApp, appSs); } else { appSs = appCacheIt.value(); } @@ -1571,8 +1564,8 @@ QVector<QCss::StyleRule> QStyleSheetStyle::styleRules(const QWidget *w) const if (wid->styleSheet().isEmpty()) continue; StyleSheet ss; - QHash<const void *, StyleSheet>::const_iterator widCacheIt = styleSheetCache->constFind(wid); - if (widCacheIt == styleSheetCache->constEnd()) { + QHash<const void *, StyleSheet>::const_iterator widCacheIt = styleSheetCaches->styleSheetCache.constFind(wid); + if (widCacheIt == styleSheetCaches->styleSheetCache.constEnd()) { parser.init(wid->styleSheet()); if (!parser.parse(&ss)) { parser.init(QLatin1String("* {") + wid->styleSheet() + QLatin1Char('}')); @@ -1580,7 +1573,7 @@ QVector<QCss::StyleRule> QStyleSheetStyle::styleRules(const QWidget *w) const qWarning("Could not parse stylesheet of widget %p", wid); } ss.origin = StyleSheetOrigin_Inline; - styleSheetCache->insert(wid, ss); + styleSheetCaches->styleSheetCache.insert(wid, ss); } else { ss = widCacheIt.value(); } @@ -1595,7 +1588,7 @@ QVector<QCss::StyleRule> QStyleSheetStyle::styleRules(const QWidget *w) const StyleSelector::NodePtr n; n.ptr = (void *)w; QVector<QCss::StyleRule> rules = styleSelector.styleRulesForNode(n); - styleRulesCache->insert(w, rules); + styleSheetCaches->styleRulesCache.insert(w, rules); return rules; } @@ -1724,7 +1717,7 @@ static void qt_check_if_internal_widget(const QWidget **w, int *element) QRenderRule QStyleSheetStyle::renderRule(const QWidget *w, int element, quint64 state) const { qt_check_if_internal_widget(&w, &element); - QHash<quint64, QRenderRule> &cache = (*renderRulesCache)[w][element]; + QHash<quint64, QRenderRule> &cache = styleSheetCaches->renderRulesCache[w][element]; QHash<quint64, QRenderRule>::const_iterator cacheIt = cache.constFind(state); if (cacheIt != cache.constEnd()) return cacheIt.value(); @@ -2035,7 +2028,7 @@ QRenderRule QStyleSheetStyle::renderRule(const QWidget *w, const QStyleOption *o bool QStyleSheetStyle::hasStyleRule(const QWidget *w, int part) const { - QHash<int, bool> &cache = (*hasStyleRuleCache)[w]; + QHash<int, bool> &cache = styleSheetCaches->hasStyleRuleCache[w]; QHash<int, bool>::const_iterator cacheIt = cache.constFind(part); if (cacheIt != cache.constEnd()) return cacheIt.value(); @@ -2565,7 +2558,7 @@ void QStyleSheetStyle::setPalette(QWidget *w) rule.configurePalette(&p, map[i].group, ew, ew != w); } - customPaletteWidgets->insert(w, w->palette()); + styleSheetCaches->customPaletteWidgets.insert(w, w->palette()); w->setPalette(p); if (ew != w) ew->setPalette(p); @@ -2573,32 +2566,32 @@ void QStyleSheetStyle::setPalette(QWidget *w) void QStyleSheetStyle::unsetPalette(QWidget *w) { - if (customPaletteWidgets->contains(w)) { - QPalette p = customPaletteWidgets->value(w); + if (styleSheetCaches->customPaletteWidgets.contains(w)) { + QPalette p = styleSheetCaches->customPaletteWidgets.value(w); w->setPalette(p); QWidget *ew = embeddedWidget(w); if (ew != w) ew->setPalette(p); - customPaletteWidgets->remove(w); + styleSheetCaches->customPaletteWidgets.remove(w); } QVariant oldFont = w->property("_q_styleSheetWidgetFont"); if (oldFont.isValid()) { w->setFont(qvariant_cast<QFont>(oldFont)); } - if (autoFillDisabledWidgets->contains(w)) { + if (styleSheetCaches->autoFillDisabledWidgets.contains(w)) { embeddedWidget(w)->setAutoFillBackground(true); - autoFillDisabledWidgets->remove(w); + styleSheetCaches->autoFillDisabledWidgets.remove(w); } } static void updateWidgets(const QList<const QWidget *>& widgets) { - if (!styleRulesCache->isEmpty() || !hasStyleRuleCache->isEmpty() || !renderRulesCache->isEmpty()) { + if (!styleSheetCaches->styleRulesCache.isEmpty() || !styleSheetCaches->hasStyleRuleCache.isEmpty() || !styleSheetCaches->renderRulesCache.isEmpty()) { for (int i = 0; i < widgets.size(); ++i) { const QWidget *widget = widgets.at(i); - styleRulesCache->remove(widget); - hasStyleRuleCache->remove(widget); - renderRulesCache->remove(widget); + styleSheetCaches->styleRulesCache.remove(widget); + styleSheetCaches->hasStyleRuleCache.remove(widget); + styleSheetCaches->renderRulesCache.remove(widget); } } for (int i = 0; i < widgets.size(); ++i) { @@ -2622,12 +2615,7 @@ QStyleSheetStyle::QStyleSheetStyle(QStyle *base) { ++numinstances; if (numinstances == 1) { - styleRulesCache = new QHash<const QWidget *, QVector<StyleRule> >; - hasStyleRuleCache = new QHash<const QWidget *, QHash<int, bool> >; - renderRulesCache = new QHash<const QWidget *, QRenderRules>; - customPaletteWidgets = new QHash<const QWidget *, QPalette>; - styleSheetCache = new QHash<const void *, StyleSheet>; - autoFillDisabledWidgets = new QSet<const QWidget *>; + styleSheetCaches = new QStyleSheetStyleCaches; } } @@ -2635,18 +2623,7 @@ QStyleSheetStyle::~QStyleSheetStyle() { --numinstances; if (numinstances == 0) { - delete styleRulesCache; - styleRulesCache = 0; - delete hasStyleRuleCache; - hasStyleRuleCache = 0; - delete renderRulesCache; - renderRulesCache = 0; - delete customPaletteWidgets; - customPaletteWidgets = 0; - delete styleSheetCache; - styleSheetCache = 0; - delete autoFillDisabledWidgets; - autoFillDisabledWidgets = 0; + delete styleSheetCaches; } } QStyle *QStyleSheetStyle::baseStyle() const @@ -2658,19 +2635,19 @@ QStyle *QStyleSheetStyle::baseStyle() const return QApplication::style(); } -void QStyleSheetStyle::widgetDestroyed(QObject *o) +void QStyleSheetStyleCaches::widgetDestroyed(QObject *o) { - styleRulesCache->remove((const QWidget *)o); - hasStyleRuleCache->remove((const QWidget *)o); - renderRulesCache->remove((const QWidget *)o); - customPaletteWidgets->remove((const QWidget *)o); - styleSheetCache->remove((const QWidget *)o); - autoFillDisabledWidgets->remove((const QWidget *)o); + styleRulesCache.remove((const QWidget *)o); + hasStyleRuleCache.remove((const QWidget *)o); + renderRulesCache.remove((const QWidget *)o); + customPaletteWidgets.remove((const QWidget *)o); + styleSheetCache.remove((const QWidget *)o); + autoFillDisabledWidgets.remove((const QWidget *)o); } -void QStyleSheetStyle::styleDestroyed(QObject *o) +void QStyleSheetStyleCaches::styleDestroyed(QObject *o) { - styleSheetCache->remove(o); + styleSheetCache.remove(o); } /*! @@ -2688,7 +2665,7 @@ bool QStyleSheetStyle::initWidget(const QWidget *w) const return false; const_cast<QWidget *>(w)->setAttribute(Qt::WA_StyleSheet, true); - QObject::connect(w, SIGNAL(destroyed(QObject*)), this, SLOT(widgetDestroyed(QObject*))); + QObject::connect(w, SIGNAL(destroyed(QObject*)), styleSheetCaches, SLOT(widgetDestroyed(QObject*)), Qt::UniqueConnection); return true; } @@ -2700,12 +2677,12 @@ void QStyleSheetStyle::polish(QWidget *w) if (!initWidget(w)) return; - if (styleRulesCache->contains(w)) { + if (styleSheetCaches->styleRulesCache.contains(w)) { // the widget accessed its style pointer before polish (or repolish) // (exemple: the QAbstractSpinBox constructor ask for the stylehint) - styleRulesCache->remove(w); - hasStyleRuleCache->remove(w); - renderRulesCache->remove(w); + styleSheetCaches->styleRulesCache.remove(w); + styleSheetCaches->hasStyleRuleCache.remove(w); + styleSheetCaches->renderRulesCache.remove(w); } setGeometry(w); setProperties(w); @@ -2771,7 +2748,7 @@ void QStyleSheetStyle::polish(QWidget *w) QWidget *ew = embeddedWidget(w); if (ew->autoFillBackground()) { ew->setAutoFillBackground(false); - autoFillDisabledWidgets->insert(w); + styleSheetCaches->autoFillDisabledWidgets.insert(w); if (ew != w) { //eg. viewport of a scrollarea //(in order to draw the background anyway in case we don't.) ew->setAttribute(Qt::WA_StyledBackground, true); @@ -2797,18 +2774,18 @@ void QStyleSheetStyle::repolish(QWidget *w) { QList<const QWidget *> children = w->findChildren<const QWidget *>(QString()); children.append(w); - styleSheetCache->remove(w); + styleSheetCaches->styleSheetCache.remove(w); updateWidgets(children); } void QStyleSheetStyle::repolish(QApplication *app) { Q_UNUSED(app); - const QList<const QWidget*> allWidgets = styleRulesCache->keys(); - styleSheetCache->remove(qApp); - styleRulesCache->clear(); - hasStyleRuleCache->clear(); - renderRulesCache->clear(); + const QList<const QWidget*> allWidgets = styleSheetCaches->styleRulesCache.keys(); + styleSheetCaches->styleSheetCache.remove(qApp); + styleSheetCaches->styleRulesCache.clear(); + styleSheetCaches->hasStyleRuleCache.clear(); + styleSheetCaches->renderRulesCache.clear(); updateWidgets(allWidgets); } @@ -2819,10 +2796,10 @@ void QStyleSheetStyle::unpolish(QWidget *w) return; } - styleRulesCache->remove(w); - hasStyleRuleCache->remove(w); - renderRulesCache->remove(w); - styleSheetCache->remove(w); + styleSheetCaches->styleRulesCache.remove(w); + styleSheetCaches->hasStyleRuleCache.remove(w); + styleSheetCaches->renderRulesCache.remove(w); + styleSheetCaches->styleSheetCache.remove(w); unsetPalette(w); w->setProperty("_q_stylesheet_minw", QVariant()); w->setProperty("_q_stylesheet_minh", QVariant()); @@ -2849,10 +2826,10 @@ void QStyleSheetStyle::unpolish(QApplication *app) { baseStyle()->unpolish(app); RECURSION_GUARD(return) - styleRulesCache->clear(); - hasStyleRuleCache->clear(); - renderRulesCache->clear(); - styleSheetCache->remove(qApp); + styleSheetCaches->styleRulesCache.clear(); + styleSheetCaches->hasStyleRuleCache.clear(); + styleSheetCaches->renderRulesCache.clear(); + styleSheetCaches->styleSheetCache.remove(qApp); } #ifndef QT_NO_TABBAR @@ -4157,6 +4134,10 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op pseudoElement = PseudoElement_DownArrow; break; + case PE_IndicatorArrowUp: + pseudoElement = PseudoElement_UpArrow; + break; + case PE_IndicatorRadioButton: pseudoElement = PseudoElement_ExclusiveIndicator; break; @@ -4257,7 +4238,7 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op case PE_Widget: if (!rule.hasDrawable()) { QWidget *container = containerWidget(w); - if (autoFillDisabledWidgets->contains(container) + if (styleSheetCaches->autoFillDisabledWidgets.contains(container) && (container == w || !renderRule(container, opt).hasBackground())) { //we do not have a background, but we disabled the autofillbackground anyway. so fill the background now. // (this may happen if we have rules like :focus) diff --git a/src/gui/styles/qstylesheetstyle_p.h b/src/gui/styles/qstylesheetstyle_p.h index fd81437..4564950 100644 --- a/src/gui/styles/qstylesheetstyle_p.h +++ b/src/gui/styles/qstylesheetstyle_p.h @@ -145,10 +145,6 @@ protected Q_SLOTS: protected: bool event(QEvent *e); -private Q_SLOTS: - void widgetDestroyed(QObject *); - void styleDestroyed(QObject *); - private: int refcount; @@ -186,6 +182,22 @@ private: Q_DECLARE_PRIVATE(QStyleSheetStyle) }; +class QStyleSheetStyleCaches : public QObject +{ + Q_OBJECT +public Q_SLOTS: + void widgetDestroyed(QObject *); + void styleDestroyed(QObject *); +public: + QHash<const QWidget *, QVector<QCss::StyleRule> > styleRulesCache; + QHash<const QWidget *, QHash<int, bool> > hasStyleRuleCache; + typedef QHash<int, QHash<quint64, QRenderRule> > QRenderRules; + QHash<const QWidget *, QRenderRules> renderRulesCache; + QHash<const QWidget *, QPalette> customPaletteWidgets; // widgets whose palette we tampered + QHash<const void *, QCss::StyleSheet> styleSheetCache; // parsed style sheets + QSet<const QWidget *> autoFillDisabledWidgets; +}; + QT_END_NAMESPACE #endif // QT_NO_STYLE_STYLESHEET diff --git a/src/gui/styles/qwindowsxpstyle.cpp b/src/gui/styles/qwindowsxpstyle.cpp index f185c0d..6ded280 100644 --- a/src/gui/styles/qwindowsxpstyle.cpp +++ b/src/gui/styles/qwindowsxpstyle.cpp @@ -302,7 +302,7 @@ HWND QWindowsXPStylePrivate::winId(const QWidget *widget) limboWidget = new QWidget(0); limboWidget->createWinId(); limboWidget->setObjectName(QLatin1String("xp_limbo_widget")); - // We dont need this internal widget to appear in QApplication::topLevelWidgets() + // We don't need this internal widget to appear in QApplication::topLevelWidgets() if (QWidgetPrivate::allWidgets) QWidgetPrivate::allWidgets->remove(limboWidget); } diff --git a/src/gui/styles/styles.pri b/src/gui/styles/styles.pri index b22a908..b6eeec9 100644 --- a/src/gui/styles/styles.pri +++ b/src/gui/styles/styles.pri @@ -35,7 +35,7 @@ contains( styles, all ) { styles = mac windows windowsxp windowsvista } -x11|embedded|!macx-*:styles -= mac +x11|embedded|qpa|!macx-*:styles -= mac x11{ QMAKE_CXXFLAGS += $$QT_CFLAGS_QGTKSTYLE |