Add fonts to QPlatformTheme.

- 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>
bb10
Friedemann Kleint 2012-03-07 08:56:41 +01:00 committed by Qt by Nokia
parent 7439fb47cd
commit 83cabda862
24 changed files with 351 additions and 158 deletions

View 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());

View 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) {

View 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;
};

View File

@ -374,18 +374,6 @@ QFont QPlatformFontDatabase::defaultFont() const
return QFont(QLatin1String("Helvetica"));
}
/*!
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.

View 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

View 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>
@ -54,6 +55,20 @@
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

View 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;

View 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

View 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

View 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

View 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) {

View 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)

View 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)

View 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,

View 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)

View 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);

View 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

View 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)

View 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()
{

View 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)

View 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);
}

View 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())

View 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);

View 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)),