Add fonts to QPlatformTheme.
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>
Wed, 7 Mar 2012 07:56:41 +0000 (08:56 +0100)
committerQt by Nokia <qt-info@nokia.com>
Wed, 7 Mar 2012 11:43:32 +0000 (12:43 +0100)
- Remove QPlatformFontDatabase::defaultFonts() returning
  a hash containing widget name ->font and the Windows
  implementation.
- Add enumeration and font accessor to QPlatformTheme. The value
  returned for the enumeration value overwrites the default font
  of the font database.
- Implement for Windows, Mac and KDE.
- Add more Windows palettes.

Task-number: QTBUG-23686

Change-Id: I8a2abdfd216df23daa7c9630c54264cdf61295db
Reviewed-by: Morten Johan Sørvig <morten.sorvig@nokia.com>
24 files changed:
src/gui/kernel/qguiapplication.cpp
src/gui/kernel/qplatformtheme_qpa.cpp
src/gui/kernel/qplatformtheme_qpa.h
src/gui/text/qplatformfontdatabase_qpa.cpp
src/gui/text/qplatformfontdatabase_qpa.h
src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
src/platformsupport/themes/genericunix/qgenericunixthemes_p.h
src/plugins/platforms/cocoa/qcocoasystemsettings.h
src/plugins/platforms/cocoa/qcocoasystemsettings.mm
src/plugins/platforms/cocoa/qcocoatheme.h
src/plugins/platforms/cocoa/qcocoatheme.mm
src/plugins/platforms/windows/qtwindows_additional.h
src/plugins/platforms/windows/qwindowsfontdatabase.cpp
src/plugins/platforms/windows/qwindowsfontdatabase.h
src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
src/plugins/platforms/windows/qwindowsfontdatabase_ft.h
src/plugins/platforms/windows/qwindowstheme.cpp
src/plugins/platforms/windows/qwindowstheme.h
src/widgets/kernel/qapplication.cpp
src/widgets/kernel/qapplication_p.h
src/widgets/kernel/qapplication_qpa.cpp
src/widgets/widgets/qmdisubwindow.cpp
tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp

index 095336a..f5aea65 100644 (file)
@@ -172,6 +172,11 @@ static inline void clearPalette()
 
 static void initFontUnlocked()
 {
+    if (!QGuiApplicationPrivate::app_font) {
+        if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
+            if (const QFont *font = theme->font(QPlatformTheme::SystemFont))
+                QGuiApplicationPrivate::app_font = new QFont(*font);
+    }
     if (!QGuiApplicationPrivate::app_font)
         QGuiApplicationPrivate::app_font =
             new QFont(QGuiApplicationPrivate::platformIntegration()->fontDatabase()->defaultFont());
index 3fdece7..c631482 100644 (file)
@@ -137,6 +137,12 @@ const QPalette *QPlatformTheme::palette(Palette type) const
     return 0;
 }
 
+const QFont *QPlatformTheme::font(Font type) const
+{
+    Q_UNUSED(type)
+    return 0;
+}
+
 QVariant QPlatformTheme::themeHint(ThemeHint hint) const
 {
     switch (hint) {
index be18e4f..6ac6a0f 100644 (file)
@@ -55,6 +55,7 @@ class QPlatformMenuBar;
 class QPlatformDialogHelper;
 class QVariant;
 class QPalette;
+class QFont;
 
 class Q_GUI_EXPORT QPlatformTheme
 {
@@ -102,6 +103,31 @@ public:
         NPalettes
     };
 
+    enum Font {
+        SystemFont,
+        MenuFont,
+        MenuBarFont,
+        MenuItemFont,
+        MessageBoxFont,
+        LabelFont,
+        TipLabelFont,
+        StatusBarFont,
+        TitleBarFont,
+        MdiSubWindowTitleFont,
+        DockWidgetTitleFont,
+        PushButtonFont,
+        ToolButtonFont,
+        ItemViewFont,
+        ListViewFont,
+        HeaderViewFont,
+        ListBoxFont,
+        ComboMenuItemFont,
+        ComboLineEditFont,
+        SmallFont,
+        MiniFont,
+        NFonts
+    };
+
     enum KeyboardSchemes
     {
         WindowsKeyboardScheme,
@@ -122,6 +148,8 @@ public:
 
     virtual const QPalette *palette(Palette type = SystemPalette) const;
 
+    virtual const QFont *font(Font type = SystemFont) const;
+
     virtual QVariant themeHint(ThemeHint hint) const;
 };
 
index 8fcf421..47a9fe5 100644 (file)
@@ -375,18 +375,6 @@ QFont QPlatformFontDatabase::defaultFont() const
 }
 
 /*!
-    Returns fonts for class names.
-
-    \sa QGuiApplication::font()
-    \since 5.0
-*/
-
-QHash<QByteArray, QFont> QPlatformFontDatabase::defaultFonts() const
-{
-    return QHash<QByteArray, QFont>();
-}
-
-/*!
     Resolve alias to actual font family names.
 
     \since 5.0
index 6a58a31..5a5a8f3 100644 (file)
@@ -100,7 +100,7 @@ public:
     virtual QString fontDir() const;
 
     virtual QFont defaultFont() const;
-    virtual QHash<QByteArray, QFont> defaultFonts() const;
+
     virtual QString resolveFontFamilyAlias(const QString &family) const;
 
     //callback
index 257fe91..602dd62 100644 (file)
@@ -43,6 +43,7 @@
 #include "../../services/genericunix/qgenericunixservices_p.h"
 
 #include <QtGui/QPalette>
+#include <QtGui/QFont>
 #include <QtGui/QGuiApplication>
 #include <QtCore/QDir>
 #include <QtCore/QFileInfo>
 
 QT_BEGIN_NAMESPACE
 
+ResourceHelper::ResourceHelper()
+{
+    qFill(palettes, palettes + QPlatformTheme::NPalettes, static_cast<QPalette *>(0));
+    qFill(fonts, fonts + QPlatformTheme::NFonts, static_cast<QFont *>(0));
+}
+
+void ResourceHelper::clear()
+{
+    qDeleteAll(palettes, palettes + QPlatformTheme::NPalettes);
+    qDeleteAll(fonts, fonts + QPlatformTheme::NFonts);
+    qFill(palettes, palettes + QPlatformTheme::NPalettes, static_cast<QPalette *>(0));
+    qFill(fonts, fonts + QPlatformTheme::NFonts, static_cast<QFont *>(0));
+}
+
 /*!
     \class QGenericX11ThemeQKdeTheme
     \brief QGenericX11Theme is a generic theme implementation for X11.
@@ -148,19 +163,40 @@ QKdeTheme::QKdeTheme(const QString &kdeHome, int kdeVersion) :
     m_kdeHome(kdeHome), m_kdeVersion(kdeVersion),
     m_toolButtonStyle(Qt::ToolButtonTextBesideIcon), m_toolBarIconSize(0)
 {
-    qFill(m_palettes, m_palettes + NPalettes, static_cast<QPalette *>(0));
     refresh();
 }
 
-void QKdeTheme::clearPalettes()
+static inline QFont *readKdeFontSetting(const QSettings &settings, const QString &key)
 {
-     qDeleteAll(m_palettes, m_palettes + NPalettes);
-     qFill(m_palettes, m_palettes + NPalettes, static_cast<QPalette *>(0));
+    const QVariant fontValue = settings.value(key);
+    if (fontValue.isValid()) {
+        // Read font value: Might be a QStringList as KDE stores fonts without quotes.
+        // Also retrieve the family for the constructor since we cannot use the
+        // default constructor of QFont, which accesses QGuiApplication::systemFont()
+        // causing recursion.
+        QString fontDescription;
+        QString fontFamily;
+        if (fontValue.type() == QVariant::StringList) {
+            const QStringList list = fontValue.toStringList();
+            if (!list.isEmpty()) {
+                fontFamily = list.first();
+                fontDescription = list.join(QStringLiteral(","));
+            }
+        } else {
+            fontDescription = fontFamily = fontValue.toString();
+        }
+        if (!fontDescription.isEmpty()) {
+            QFont font(fontFamily);
+            if (font.fromString(fontDescription))
+                return new QFont(font);
+        }
+    }
+    return 0;
 }
 
 void QKdeTheme::refresh()
 {
-    clearPalettes();
+    m_resources.clear();
 
     m_toolButtonStyle = Qt::ToolButtonTextBesideIcon;
     m_toolBarIconSize = 0;
@@ -177,7 +213,7 @@ void QKdeTheme::refresh()
 
     QPalette systemPalette;
     if (readKdeSystemPalette(kdeSettings, &systemPalette))
-        m_palettes[SystemPalette] = new QPalette(systemPalette);
+        m_resources.palettes[SystemPalette] = new QPalette(systemPalette);
     //## TODO tooltip color
 
     const QVariant styleValue = kdeSettings.value(QStringLiteral("widgetStyle"));
@@ -205,6 +241,9 @@ void QKdeTheme::refresh()
         else if (toolBarStyle == QStringLiteral("TextUnderIcon"))
             m_toolButtonStyle = Qt::ToolButtonTextUnderIcon;
     }
+
+    // Read system font, ignore 'fixed' 'smallestReadableFont'
+    m_resources.fonts[SystemFont] = readKdeFontSetting(kdeSettings, QStringLiteral("font"));
 }
 
 QString QKdeTheme::globalSettingsFile() const
index 12937a2..a9db29e 100644 (file)
@@ -50,6 +50,18 @@ QT_BEGIN_HEADER
 
 QT_BEGIN_NAMESPACE
 
+class ResourceHelper
+{
+public:
+    ResourceHelper();
+    ~ResourceHelper() { clear(); }
+
+    void clear();
+
+    QPalette *palettes[QPlatformTheme::NPalettes];
+    QFont *fonts[QPlatformTheme::NFonts];
+};
+
 class QGenericUnixTheme : public QPlatformTheme
 {
 public:
@@ -66,21 +78,24 @@ class QKdeTheme : public QPlatformTheme
 {
     QKdeTheme(const QString &kdeHome, int kdeVersion);
 public:
-    ~QKdeTheme() { clearPalettes(); }
 
     static QPlatformTheme *createKdeTheme();
     virtual QVariant themeHint(ThemeHint hint) const;
+
     virtual const QPalette *palette(Palette type = SystemPalette) const
-        { return m_palettes[type]; }
+        { return m_resources.palettes[type]; }
+
+    virtual const QFont *font(Font type) const
+        { return m_resources.fonts[type]; }
 
 private:
     QString globalSettingsFile() const;
-    void clearPalettes();
     void refresh();
 
     const QString m_kdeHome;
     const int m_kdeVersion;
-    QPalette *m_palettes[NPalettes];
+
+    ResourceHelper m_resources;
     QString m_iconThemeName;
     QString m_iconFallbackThemeName;
     QStringList m_styleNames;
index 2ed6f76..10cac27 100644 (file)
@@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE
 
 QPalette * qt_mac_createSystemPalette();
 QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes();
+QHash<QPlatformTheme::Font, QFont *>  qt_mac_createRoleFonts();
 
 QT_END_NAMESPACE
 
index d5b2fce..c2f5df4 100644 (file)
@@ -42,6 +42,7 @@
 #include "qcocoasystemsettings.h"
 
 #include <QtCore/private/qcore_mac_p.h>
+#include <QtGui/qfont.h>
 
 #include <Carbon/Carbon.h>
 
@@ -229,4 +230,43 @@ QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes()
     return palettes;
 }
 
+QFont *qt_mac_qfontForThemeFont(ThemeFontID themeID)
+{
+    CTFontUIFontType ctID = HIThemeGetUIFontType(themeID);
+    QCFType<CTFontRef> ctfont = CTFontCreateUIFontForLanguage(ctID, 0, 0);
+    QString familyName = QCFString(CTFontCopyFamilyName(ctfont));
+    QCFType<CFDictionaryRef> dict = CTFontCopyTraits(ctfont);
+    CFNumberRef num = static_cast<CFNumberRef>(CFDictionaryGetValue(dict, kCTFontWeightTrait));
+    float fW;
+    CFNumberGetValue(num, kCFNumberFloat32Type, &fW);
+    QFont::Weight wght = fW > 0. ? QFont::Bold : QFont::Normal;
+    num = static_cast<CFNumberRef>(CFDictionaryGetValue(dict, kCTFontSlantTrait));
+    CFNumberGetValue(num, kCFNumberFloatType, &fW);
+    bool italic = (fW != 0.0);
+    return new QFont(familyName, CTFontGetSize(ctfont), wght, italic);
+}
+
+QHash<QPlatformTheme::Font, QFont *> qt_mac_createRoleFonts()
+{
+    QHash<QPlatformTheme::Font, QFont *> fonts;
+
+    fonts.insert(QPlatformTheme::SystemFont, qt_mac_qfontForThemeFont(kThemeApplicationFont));
+    fonts.insert(QPlatformTheme::PushButtonFont, qt_mac_qfontForThemeFont(kThemePushButtonFont));
+    fonts.insert(QPlatformTheme::ListViewFont, qt_mac_qfontForThemeFont(kThemeViewsFont));
+    fonts.insert(QPlatformTheme::ListBoxFont, qt_mac_qfontForThemeFont(kThemeViewsFont));
+    fonts.insert(QPlatformTheme::TitleBarFont, qt_mac_qfontForThemeFont(kThemeWindowTitleFont));
+    fonts.insert(QPlatformTheme::MenuFont, qt_mac_qfontForThemeFont(kThemeMenuItemFont));
+    fonts.insert(QPlatformTheme::ComboMenuItemFont, qt_mac_qfontForThemeFont(kThemeSystemFont));
+    fonts.insert(QPlatformTheme::HeaderViewFont, qt_mac_qfontForThemeFont(kThemeSmallSystemFont));
+    fonts.insert(QPlatformTheme::TipLabelFont, qt_mac_qfontForThemeFont(kThemeSmallSystemFont));
+    fonts.insert(QPlatformTheme::LabelFont, qt_mac_qfontForThemeFont(kThemeSystemFont));
+    fonts.insert(QPlatformTheme::ToolButtonFont, qt_mac_qfontForThemeFont(kThemeSmallSystemFont));
+    fonts.insert(QPlatformTheme::MenuItemFont, qt_mac_qfontForThemeFont(kThemeMenuItemFont));
+    fonts.insert(QPlatformTheme::ComboLineEditFont, qt_mac_qfontForThemeFont(kThemeViewsFont));
+    fonts.insert(QPlatformTheme::SmallFont, qt_mac_qfontForThemeFont(kThemeSmallSystemFont));
+    fonts.insert(QPlatformTheme::MiniFont, qt_mac_qfontForThemeFont(kThemeMiniSystemFont));
+
+    return fonts;
+}
+
 QT_END_NAMESPACE
index dccda2c..030db18 100644 (file)
@@ -61,11 +61,13 @@ public:
     QPlatformDialogHelper *createPlatformDialogHelper(DialogType dialogType) const;
 
     const QPalette *palette(Palette type = SystemPalette) const;
+    const QFont *font(Font type = SystemFont) const;
 
     QVariant themeHint(ThemeHint hint) const;
 private:
     mutable QPalette *m_systemPalette;
     mutable QHash<QPlatformTheme::Palette, QPalette*> m_palettes;
+    mutable QHash<QPlatformTheme::Font, QFont*> m_fonts;
 };
 
 QT_END_NAMESPACE
index 71d7c9e..8ec6e38 100644 (file)
@@ -118,6 +118,14 @@ const QPalette *QCocoaTheme::palette(Palette type) const
     return 0;
 }
 
+const QFont *QCocoaTheme::font(Font type) const
+{
+    if (m_fonts.isEmpty()) {
+        m_fonts = qt_mac_createRoleFonts();
+    }
+    return m_fonts.value(type, 0);
+}
+
 QVariant QCocoaTheme::themeHint(ThemeHint hint) const
 {
     switch (hint) {
index d822402..ac768e2 100644 (file)
@@ -61,7 +61,8 @@
 #    define FE_FONTSMOOTHINGCLEARTYPE 0x0002
 #    define CLEARTYPE_QUALITY       5
 #    define SPI_GETDROPSHADOW 0x1024
-
+#    define COLOR_MENUHILIGHT 29
+#    define COLOR_MENUBAR     30
 #    define CF_DIBV5 17
 
 #define CO_E_NOT_SUPPORTED               _HRESULT_TYPEDEF_(0x80004021L)
index fba7794..5094ad9 100644 (file)
@@ -40,6 +40,7 @@
 ****************************************************************************/
 
 #include "qwindowsfontdatabase.h"
+#include "qwindowsfontdatabase_ft.h" // for default font
 #include "qwindowscontext.h"
 #include "qwindowsfontengine.h"
 #include "qwindowsfontenginedirectwrite.h"
@@ -1066,53 +1067,7 @@ static inline int verticalDPI()
 
 QFont QWindowsFontDatabase::defaultFont() const
 {
-    LOGFONT lf;
-    GetObject(GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf);
-    QFont systemFont =  QWindowsFontDatabase::LOGFONT_to_QFont(lf);
-    // "MS Shell Dlg 2" is the correct system font >= Win2k
-    if (systemFont.family() == QStringLiteral("MS Shell Dlg"))
-        systemFont.setFamily(QStringLiteral("MS Shell Dlg 2"));
-    if (QWindowsContext::verboseFonts)
-        qDebug() << __FUNCTION__ << systemFont;
-    return systemFont;
-}
-
-QHash<QByteArray, QFont> QWindowsFontDatabase::defaultFonts() const
-{
-    QHash<QByteArray, QFont> result;
-    NONCLIENTMETRICS ncm;
-    ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT);
-    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0);
-
-    const int verticalRes = verticalDPI();
-
-    const QFont menuFont = LOGFONT_to_QFont(ncm.lfMenuFont, verticalRes);
-    const QFont messageFont = LOGFONT_to_QFont(ncm.lfMessageFont, verticalRes);
-    const QFont statusFont = LOGFONT_to_QFont(ncm.lfStatusFont, verticalRes);
-    const QFont titleFont = LOGFONT_to_QFont(ncm.lfCaptionFont, verticalRes);
-
-    LOGFONT lfIconTitleFont;
-    SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0);
-    const QFont iconTitleFont = LOGFONT_to_QFont(lfIconTitleFont, verticalRes);
-
-    result.insert(QByteArray("QMenu"), menuFont);
-    result.insert(QByteArray("QMenuBar"), menuFont);
-    result.insert(QByteArray("QMessageBox"), messageFont);
-    result.insert(QByteArray("QTipLabel"), statusFont);
-    result.insert(QByteArray("QStatusBar"), statusFont);
-    result.insert(QByteArray("Q3TitleBar"), titleFont);
-    result.insert(QByteArray("QWorkspaceTitleBar"), titleFont);
-    result.insert(QByteArray("QAbstractItemView"), iconTitleFont);
-    result.insert(QByteArray("QDockWidgetTitle"), iconTitleFont);
-    if (QWindowsContext::verboseFonts) {
-        typedef QHash<QByteArray, QFont>::const_iterator CIT;
-        QDebug nsp = qDebug().nospace();
-        nsp << __FUNCTION__ << " DPI=" << verticalRes << "\n";
-        const CIT cend = result.constEnd();
-        for (CIT it = result.constBegin(); it != cend; ++it)
-            nsp << it.key() << ' ' << it.value() << '\n';
-    }
-    return result;
+    return QWindowsFontDatabaseFT::systemDefaultFont();
 }
 
 QFont QWindowsFontDatabase::LOGFONT_to_QFont(const LOGFONT& logFont, int verticalDPI_In)
index b08b682..04d6ccd 100644 (file)
@@ -86,7 +86,6 @@ public:
     virtual QString fontDir() const;
 
     virtual QFont defaultFont() const;
-    virtual QHash<QByteArray, QFont> defaultFonts() const;
 
     static QFontEngine *createEngine(int script, const QFontDef &request,
                                      HDC fontHdc, int dpi, bool rawMode,
index e972ae2..fcce87d 100644 (file)
@@ -460,7 +460,7 @@ static inline int verticalDPI()
     return GetDeviceCaps(QWindowsContext::instance()->displayContext(), LOGPIXELSY);
 }
 
-QFont QWindowsFontDatabaseFT::defaultFont() const
+QFont QWindowsFontDatabaseFT::systemDefaultFont()
 {
     LOGFONT lf;
     GetObject(GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf);
@@ -473,44 +473,6 @@ QFont QWindowsFontDatabaseFT::defaultFont() const
     return systemFont;
 }
 
-QHash<QByteArray, QFont> QWindowsFontDatabaseFT::defaultFonts() const
-{
-    QHash<QByteArray, QFont> result;
-    NONCLIENTMETRICS ncm;
-    ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT);
-    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0);
-
-    const int verticalRes = verticalDPI();
-
-    const QFont menuFont = LOGFONT_to_QFont(ncm.lfMenuFont, verticalRes);
-    const QFont messageFont = LOGFONT_to_QFont(ncm.lfMessageFont, verticalRes);
-    const QFont statusFont = LOGFONT_to_QFont(ncm.lfStatusFont, verticalRes);
-    const QFont titleFont = LOGFONT_to_QFont(ncm.lfCaptionFont, verticalRes);
-
-    LOGFONT lfIconTitleFont;
-    SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0);
-    const QFont iconTitleFont = LOGFONT_to_QFont(lfIconTitleFont, verticalRes);
-
-    result.insert(QByteArray("QMenu"), menuFont);
-    result.insert(QByteArray("QMenuBar"), menuFont);
-    result.insert(QByteArray("QMessageBox"), messageFont);
-    result.insert(QByteArray("QTipLabel"), statusFont);
-    result.insert(QByteArray("QStatusBar"), statusFont);
-    result.insert(QByteArray("Q3TitleBar"), titleFont);
-    result.insert(QByteArray("QWorkspaceTitleBar"), titleFont);
-    result.insert(QByteArray("QAbstractItemView"), iconTitleFont);
-    result.insert(QByteArray("QDockWidgetTitle"), iconTitleFont);
-    if (QWindowsContext::verboseFonts) {
-        typedef QHash<QByteArray, QFont>::const_iterator CIT;
-        QDebug nsp = qDebug().nospace();
-        nsp << __FUNCTION__ << " DPI=" << verticalRes << "\n";
-        const CIT cend = result.constEnd();
-        for (CIT it = result.constBegin(); it != cend; ++it)
-            nsp << it.key() << ' ' << it.value() << '\n';
-    }
-    return result;
-}
-
 QFont QWindowsFontDatabaseFT::LOGFONT_to_QFont(const LOGFONT& logFont, int verticalDPI_In)
 {
     if (verticalDPI_In <= 0)
index 5a0c4c6..4136b75 100644 (file)
@@ -59,8 +59,9 @@ public:
     QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
 
     virtual QString fontDir() const;
-    virtual QFont defaultFont() const;
-    virtual QHash<QByteArray, QFont> defaultFonts() const;
+    virtual QFont defaultFont() const { return systemDefaultFont(); }
+    static QFont systemDefaultFont();
+
     static HFONT systemFont();
     static QFont LOGFONT_to_QFont(const LOGFONT& lf, int verticalDPI = 0);
 
index 5350b3c..10b4682 100644 (file)
@@ -44,6 +44,7 @@
 #include "qwindowscontext.h"
 #include "qwindowsintegration.h"
 #include "qt_windows.h"
+#include "qwindowsfontdatabase_ft.h"
 
 #include <QtCore/QVariant>
 #include <QtCore/QCoreApplication>
@@ -76,6 +77,22 @@ static inline QString paletteToString(const QPalette &palette)
     return result;
 }
 
+static inline bool booleanSystemParametersInfo(UINT what, bool defaultValue)
+{
+    BOOL result;
+    if (SystemParametersInfo(what, 0, &result, 0))
+        return result ? true : false;
+    return defaultValue;
+}
+
+static inline bool dWordSystemParametersInfo(UINT what, DWORD defaultValue)
+{
+    DWORD result;
+    if (SystemParametersInfo(what, 0, &result, 0))
+        return result;
+    return defaultValue;
+}
+
 static inline QColor mixColors(const QColor &c1, const QColor &c2)
 {
     return QColor ((c1.red() + c2.red()) / 2,
@@ -138,7 +155,7 @@ static inline QPalette systemPalette()
     return result;
 }
 
-QPalette toolTipPalette(const QPalette &systemPalette)
+static inline QPalette toolTipPalette(const QPalette &systemPalette)
 {
     QPalette result(systemPalette);
     const QColor tipBgColor(getSysColor(COLOR_INFOBK));
@@ -163,24 +180,58 @@ QPalette toolTipPalette(const QPalette &systemPalette)
     return result;
 }
 
-static inline bool booleanSystemParametersInfo(UINT what, bool defaultValue)
+static inline QPalette menuPalette(const QPalette &systemPalette)
 {
-    BOOL result;
-    if (SystemParametersInfo(what, 0, &result, 0))
-        return result ? true : false;
-    return defaultValue;
+    QPalette result(systemPalette);
+    const QColor menuColor(getSysColor(COLOR_INFOBK));
+    const QColor menuTextColor(getSysColor(COLOR_MENUTEXT));
+    const QColor disabled(getSysColor(COLOR_GRAYTEXT));
+    const bool isFlat = booleanSystemParametersInfo(SPI_GETFLATMENU, false);
+    // we might need a special color group for the result.
+    result.setColor(QPalette::Active, QPalette::Button, menuColor);
+    result.setColor(QPalette::Active, QPalette::Text, menuTextColor);
+    result.setColor(QPalette::Active, QPalette::WindowText, menuTextColor);
+    result.setColor(QPalette::Active, QPalette::ButtonText, menuTextColor);
+    result.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
+    result.setColor(QPalette::Disabled, QPalette::Text, disabled);
+    result.setColor(QPalette::Disabled, QPalette::Highlight,
+                    getSysColor(isFlat ? COLOR_MENUHILIGHT : COLOR_HIGHLIGHT));
+    result.setColor(QPalette::Disabled, QPalette::HighlightedText, disabled);
+    result.setColor(QPalette::Disabled, QPalette::Button,
+                    result.color(QPalette::Active, QPalette::Button));
+    result.setColor(QPalette::Inactive, QPalette::Button,
+                    result.color(QPalette::Active, QPalette::Button));
+    result.setColor(QPalette::Inactive, QPalette::Text,
+                    result.color(QPalette::Active, QPalette::Text));
+    result.setColor(QPalette::Inactive, QPalette::WindowText,
+                    result.color(QPalette::Active, QPalette::WindowText));
+    result.setColor(QPalette::Inactive, QPalette::ButtonText,
+                    result.color(QPalette::Active, QPalette::ButtonText));
+    result.setColor(QPalette::Inactive, QPalette::Highlight,
+                    result.color(QPalette::Active, QPalette::Highlight));
+    result.setColor(QPalette::Inactive, QPalette::HighlightedText,
+                    result.color(QPalette::Active, QPalette::HighlightedText));
+    result.setColor(QPalette::Inactive, QPalette::ButtonText,
+                    systemPalette.color(QPalette::Inactive, QPalette::Dark));
+    return result;
 }
 
-static inline bool dWordSystemParametersInfo(UINT what, DWORD defaultValue)
+static inline QPalette *menuBarPalette(const QPalette &menuPalette)
 {
-    DWORD result;
-    if (SystemParametersInfo(what, 0, &result, 0))
-        return result;
-    return defaultValue;
+    QPalette *result = 0;
+    if (booleanSystemParametersInfo(SPI_GETFLATMENU, false)) {
+        result = new QPalette(menuPalette);
+        const QColor menubar(getSysColor(COLOR_MENUBAR));
+        result->setColor(QPalette::Active, QPalette::Button, menubar);
+        result->setColor(QPalette::Disabled, QPalette::Button, menubar);
+        result->setColor(QPalette::Inactive, QPalette::Button, menubar);
+    }
+    return result;
 }
 
 QWindowsTheme::QWindowsTheme()
 {
+    qFill(m_fonts, m_fonts + NFonts, static_cast<QFont *>(0));
     qFill(m_palettes, m_palettes + NPalettes, static_cast<QPalette *>(0));
     refresh();
 }
@@ -188,12 +239,7 @@ QWindowsTheme::QWindowsTheme()
 QWindowsTheme::~QWindowsTheme()
 {
     clearPalettes();
-}
-
-void QWindowsTheme::clearPalettes()
-{
-    qDeleteAll(m_palettes, m_palettes + NPalettes);
-    qFill(m_palettes, m_palettes + NPalettes, static_cast<QPalette *>(0));
+    clearFonts();
 }
 
 QWindowsTheme *QWindowsTheme::instance()
@@ -243,17 +289,65 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const
     return QPlatformTheme::themeHint(hint);
 }
 
-void QWindowsTheme::refresh()
+void QWindowsTheme::clearPalettes()
 {
-    clearPalettes();
-    if (QGuiApplication::desktopSettingsAware()) {
-        m_palettes[SystemPalette] = new QPalette(systemPalette());
-        m_palettes[ToolTipPalette] = new QPalette(toolTipPalette(*m_palettes[SystemPalette]));
-        if (QWindowsContext::verboseTheming)
-            qDebug() << __FUNCTION__ << '\n'
-                     << "  system=" << paletteToString(*m_palettes[SystemPalette])
-                     << "  tooltip=" << paletteToString(*m_palettes[ToolTipPalette]);
-    }
+    qDeleteAll(m_palettes, m_palettes + NPalettes);
+    qFill(m_palettes, m_palettes + NPalettes, static_cast<QPalette *>(0));
+}
+
+void QWindowsTheme::refreshPalettes()
+{
+
+    if (!QGuiApplication::desktopSettingsAware())
+        return;
+    m_palettes[SystemPalette] = new QPalette(systemPalette());
+    m_palettes[ToolTipPalette] = new QPalette(toolTipPalette(*m_palettes[SystemPalette]));
+    m_palettes[MenuPalette] = new QPalette(menuPalette(*m_palettes[SystemPalette]));
+    m_palettes[MenuBarPalette] = menuBarPalette(*m_palettes[MenuPalette]);
+    if (QWindowsContext::verboseTheming)
+        qDebug() << __FUNCTION__ << '\n'
+                 << "  system=" << paletteToString(*m_palettes[SystemPalette])
+                 << "  tooltip=" << paletteToString(*m_palettes[ToolTipPalette]);
+}
+
+void QWindowsTheme::clearFonts()
+{
+    qDeleteAll(m_fonts, m_fonts + NFonts);
+    qFill(m_fonts, m_fonts + NFonts, static_cast<QFont *>(0));
+}
+
+void QWindowsTheme::refreshFonts()
+{
+    clearFonts();
+    if (!QGuiApplication::desktopSettingsAware())
+        return;
+    NONCLIENTMETRICS ncm;
+    ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT);
+    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0);
+
+    const QFont menuFont = QWindowsFontDatabaseFT::LOGFONT_to_QFont(ncm.lfMenuFont);
+    const QFont messageBoxFont = QWindowsFontDatabaseFT::LOGFONT_to_QFont(ncm.lfMessageFont);
+    const QFont statusFont = QWindowsFontDatabaseFT::LOGFONT_to_QFont(ncm.lfStatusFont);
+    const QFont titleFont = QWindowsFontDatabaseFT::LOGFONT_to_QFont(ncm.lfCaptionFont);
+
+    LOGFONT lfIconTitleFont;
+    SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0);
+    const QFont iconTitleFont = QWindowsFontDatabaseFT::LOGFONT_to_QFont(lfIconTitleFont);
+
+    m_fonts[SystemFont] = new QFont(QWindowsFontDatabaseFT::systemDefaultFont());
+    m_fonts[MenuFont] = new QFont(menuFont);
+    m_fonts[MenuBarFont] = new QFont(menuFont);
+    m_fonts[MessageBoxFont] = new QFont(messageBoxFont);
+    m_fonts[TipLabelFont] = new QFont(statusFont);
+    m_fonts[StatusBarFont] = new QFont(statusFont);
+    m_fonts[MdiSubWindowTitleFont] = new QFont(titleFont);
+    m_fonts[DockWidgetTitleFont] = new QFont(titleFont);
+    m_fonts[ItemViewFont] = new QFont(iconTitleFont);
+
+    if (QWindowsContext::verboseTheming)
+        qDebug() << __FUNCTION__ << '\n'
+                 << "  menuFont=" << menuFont
+                 << "  messageBox=" << MessageBoxFont;
 }
 
 bool QWindowsTheme::usePlatformNativeDialog(DialogType type) const
index 950c380..37346ee 100644 (file)
@@ -64,14 +64,20 @@ public:
     virtual QVariant themeHint(ThemeHint) const;
     virtual const QPalette *palette(Palette type = SystemPalette) const
         { return m_palettes[type]; }
+    virtual const QFont *font(Font type = SystemFont) const
+        { return m_fonts[type]; }
 
     void windowsThemeChanged(QWindow *window);
 
 private:
-    void refresh();
+    void refresh() { refreshPalettes(); refreshFonts(); }
     void clearPalettes();
+    void refreshPalettes();
+    void clearFonts();
+    void refreshFonts();
 
     QPalette *m_palettes[NPalettes];
+    QFont *m_fonts[NFonts];
 };
 
 static inline COLORREF qColorToCOLORREF(const QColor &color)
index bf2729a..90b64db 100644 (file)
@@ -431,11 +431,6 @@ PaletteHash *qt_app_palettes_hash()
     return app_palettes();
 }
 
-FontHash::FontHash()
-{
-    QHash<QByteArray, QFont>::operator=(QGuiApplicationPrivate::platformIntegration()->fontDatabase()->defaultFonts());
-}
-
 Q_GLOBAL_STATIC(FontHash, app_fonts)
 FontHash *qt_app_fonts_hash()
 {
index ae4f0c2..2d63917 100644 (file)
@@ -157,10 +157,7 @@ QMacTabletHash *qt_mac_tablet_hash();
 # endif
 #endif
 
-struct FontHash : public QHash<QByteArray, QFont>
-{
-    FontHash();
-};
+typedef QHash<QByteArray, QFont> FontHash;
 FontHash *qt_app_fonts_hash();
 
 typedef QHash<QByteArray, QPalette> PaletteHash;
@@ -292,6 +289,7 @@ public:
     static void setSystemPalette(const QPalette &pal);
     static void setPalette_helper(const QPalette &palette, const char* className, bool clearWidgetPaletteHash);
     static void initializeWidgetPaletteHash();
+    static void initializeWidgetFontHash();
     static void setSystemFont(const QFont &font);
 
 #if defined(Q_WS_X11)
index 6c91b89..97fc794 100644 (file)
@@ -318,6 +318,58 @@ void QApplicationPrivate::initializeWidgetPaletteHash()
     setPossiblePalette(platformTheme->palette(QPlatformTheme::TextLineEditPalette), "QLineEdit");
 }
 
+void QApplicationPrivate::initializeWidgetFontHash()
+{
+    const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
+    if (!theme)
+        return;
+    FontHash *fontHash = qt_app_fonts_hash();
+    if (const QFont *font = theme->font(QPlatformTheme::MenuFont))
+        fontHash->insert(QByteArrayLiteral("QMenu"), *font);
+    if (const QFont *font = theme->font(QPlatformTheme::MenuBarFont))
+        fontHash->insert(QByteArrayLiteral("QMenuBar"), *font);
+    if (const QFont *font = theme->font(QPlatformTheme::MenuItemFont))
+        fontHash->insert(QByteArrayLiteral("QMenuItem"), *font);
+    if (const QFont *font = theme->font(QPlatformTheme::MessageBoxFont))
+        fontHash->insert(QByteArrayLiteral("QMessageBox"), *font);
+    if (const QFont *font = theme->font(QPlatformTheme::LabelFont))
+        fontHash->insert(QByteArrayLiteral("QLabel"), *font);
+    if (const QFont *font = theme->font(QPlatformTheme::TipLabelFont))
+        fontHash->insert(QByteArrayLiteral("QTipLabel"), *font);
+    if (const QFont *font = theme->font(QPlatformTheme::TitleBarFont))
+        fontHash->insert(QByteArrayLiteral("QTitleBar"), *font);
+    if (const QFont *font = theme->font(QPlatformTheme::StatusBarFont))
+        fontHash->insert(QByteArrayLiteral("QStatusBar"), *font);
+    if (const QFont *font = theme->font(QPlatformTheme::MdiSubWindowTitleFont)) {
+        fontHash->insert(QByteArrayLiteral("QWorkspaceTitleBar"), *font);
+        fontHash->insert(QByteArrayLiteral("QMdiSubWindowTitleBar"), *font);
+    }
+    if (const QFont *font = theme->font(QPlatformTheme::DockWidgetTitleFont))
+        fontHash->insert(QByteArrayLiteral("QDockWidgetTitle"), *font);
+    if (const QFont *font = theme->font(QPlatformTheme::PushButtonFont))
+        fontHash->insert(QByteArrayLiteral("QPushButton"), *font);
+    if (const QFont *font = theme->font(QPlatformTheme::ToolButtonFont))
+        fontHash->insert(QByteArrayLiteral("QToolButton"), *font);
+    if (const QFont *font = theme->font(QPlatformTheme::ItemViewFont))
+        fontHash->insert(QByteArrayLiteral("QAbstractItemView"), *font);
+    if (const QFont *font = theme->font(QPlatformTheme::ListViewFont))
+        fontHash->insert(QByteArrayLiteral("QListViewFont"), *font);
+    if (const QFont *font = theme->font(QPlatformTheme::HeaderViewFont)) {
+        fontHash->insert(QByteArrayLiteral("QHeaderViewFont"), *font);
+        fontHash->insert(QByteArrayLiteral("Q3Header"), *font);
+    }
+    if (const QFont *font = theme->font(QPlatformTheme::ListBoxFont))
+        fontHash->insert(QByteArrayLiteral("QListBox"), *font);
+    if (const QFont *font = theme->font(QPlatformTheme::ComboMenuItemFont))
+        fontHash->insert(QByteArrayLiteral("QComboMenuItemFont"), *font);
+    if (const QFont *font = theme->font(QPlatformTheme::ComboLineEditFont))
+        fontHash->insert(QByteArrayLiteral("QComboLineEditFont"), *font);
+    if (const QFont *font = theme->font(QPlatformTheme::SmallFont))
+        fontHash->insert(QByteArrayLiteral("QSmallFont"), *font);
+    if (const QFont *font = theme->font(QPlatformTheme::MiniFont))
+        fontHash->insert(QByteArrayLiteral("QMiniFont"), *font);
+}
+
 #ifndef QT_NO_WHEELEVENT
 void QApplication::setWheelScrollLines(int lines)
 {
@@ -416,6 +468,7 @@ QPlatformNativeInterface *QApplication::platformNativeInterface()
 
 void qt_init(QApplicationPrivate *priv, int type)
 {
+    Q_UNUSED(priv);
     Q_UNUSED(type);
 
     qApp->setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
@@ -423,6 +476,7 @@ void qt_init(QApplicationPrivate *priv, int type)
 
     if (const QPalette *toolTipPalette = QGuiApplicationPrivate::platformTheme()->palette(QPlatformTheme::ToolTipPalette))
         QToolTip::setPalette(*toolTipPalette);
+    QApplicationPrivate::initializeWidgetFontHash();
     qApp->setObjectName(appName);
 }
 
index b42fedf..af75d6b 100644 (file)
@@ -2260,7 +2260,7 @@ QMdiSubWindow::QMdiSubWindow(QWidget *parent, Qt::WindowFlags flags)
     d->updateGeometryConstraints();
     setAttribute(Qt::WA_Resized, false);
     d->titleBarPalette = d->desktopPalette();
-    d->font = QApplication::font("QWorkspaceTitleBar");
+    d->font = QApplication::font("QMdiSubWindowTitleBar");
     // We don't want the menu icon by default on mac.
 #ifndef Q_WS_MAC
     if (windowIcon().isNull())
index f139eac..9bb08ed 100644 (file)
@@ -1830,10 +1830,11 @@ void tst_QListView::taskQTBUG_2233_scrollHiddenItems()
     QStringListModel model(&view);
     QStringList list;
     for (int i = 0; i < rowCount; ++i)
-        list << QString::fromAscii("Item %1").arg(i);
+        list << QString::number(i);
 
     model.setStringList(list);
     view.setModel(&model);
+    view.setUniformItemSizes(true);
     view.setViewMode(QListView::ListMode);
     for (int i = 0; i < rowCount / 2; ++i)
         view.setRowHidden(2 * i, true);
index 8f18719..544923a 100644 (file)
@@ -781,10 +781,6 @@ void tst_QStyleSheetStyle::focusColors()
                 + " did not contain background color #e8ff66, using style "
                 + QString::fromLatin1(qApp->style()->metaObject()->className()))
                 .toLocal8Bit().constData());
-#ifdef Q_OS_MAC
-        if (widget == widgets.first())
-            QEXPECT_FAIL("", "Failure only for first widget, the QPushButton, see QTBUG-23686", Continue);
-#endif
         QVERIFY2(testForColors(image, QColor(0xff, 0x00, 0x84)),
                 (QString::fromLatin1(widget->metaObject()->className())
                 + " did not contain text color #ff0084, using style "
@@ -882,8 +878,7 @@ void tst_QStyleSheetStyle::hoverColors()
                  (QString::fromLatin1(widget->metaObject()->className())
                  + " did not contain background color #e8ff66").toLocal8Bit().constData());
 #ifdef Q_OS_MAC
-        if (qobject_cast<QPushButton *>(widget)
-            || qobject_cast<QComboBox *>(widget))
+        if (qobject_cast<QComboBox *>(widget))
             QEXPECT_FAIL("", "Failure only for QPushButton and QComboBox, see QTBUG-23686", Continue);
 #endif
         QVERIFY2(testForColors(image, QColor(0xff, 0x00, 0x84)),