QPA: Introducing QPlatformTheme standardPixmap(), fileIconPixmap()
The basic idea is that the platform theme is now responsible for providing the pixmaps for the given standard name, or any file or directory. Then, the QStyle implementation should query the platform theme for the pixmaps, and build the icons accordingly using ThemeHint::IconPixmapSizes. Same thing for QFileIconProvider. This also opens future support for getting platform dependent pixmaps in QtQuick components. Also includes the implementation for the Cocoa (QCocoaTheme) and Windows (QWindowsTheme) platform plugins. Task-number: QTBUG-27450 Change-Id: I4e8406585d970a9af481be10f6643cf0abbc38a3 Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com> Reviewed-by: Jens Bache-Wiig <jens.bache-wiig@digia.com> Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
This commit is contained in:
parent
c153f471d2
commit
c3b939818a
@ -43,6 +43,7 @@
|
||||
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/qfileinfo.h>
|
||||
#include <qpalette.h>
|
||||
#include <qtextformat.h>
|
||||
|
||||
@ -164,6 +165,22 @@ const QFont *QPlatformTheme::font(Font type) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
QPixmap QPlatformTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
|
||||
{
|
||||
Q_UNUSED(sp);
|
||||
Q_UNUSED(size);
|
||||
// TODO Should return QCommonStyle pixmaps?
|
||||
return QPixmap();
|
||||
}
|
||||
|
||||
QPixmap QPlatformTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const
|
||||
{
|
||||
Q_UNUSED(fileInfo);
|
||||
Q_UNUSED(size);
|
||||
// TODO Should return QCommonStyle pixmaps?
|
||||
return QPixmap();
|
||||
}
|
||||
|
||||
QVariant QPlatformTheme::themeHint(ThemeHint hint) const
|
||||
{
|
||||
return QPlatformTheme::defaultThemeHint(hint);
|
||||
@ -223,6 +240,8 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
|
||||
return QVariant(int(QTextCharFormat::SpellCheckUnderline));
|
||||
case TabAllWidgets:
|
||||
return QVariant(true);
|
||||
case IconPixmapSizes:
|
||||
return QVariant::fromValue(QList<int>());
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
@ -67,6 +67,9 @@ class QPlatformSystemTrayIcon;
|
||||
class QVariant;
|
||||
class QPalette;
|
||||
class QFont;
|
||||
class QPixmap;
|
||||
class QSizeF;
|
||||
class QFileInfo;
|
||||
|
||||
class Q_GUI_EXPORT QPlatformTheme
|
||||
{
|
||||
@ -97,7 +100,8 @@ public:
|
||||
KeyboardScheme,
|
||||
UiEffects,
|
||||
SpellCheckUnderlineStyle,
|
||||
TabAllWidgets
|
||||
TabAllWidgets,
|
||||
IconPixmapSizes
|
||||
};
|
||||
|
||||
enum DialogType {
|
||||
@ -150,6 +154,81 @@ public:
|
||||
NFonts
|
||||
};
|
||||
|
||||
enum StandardPixmap { // Keep in sync with QStyle::StandardPixmap
|
||||
TitleBarMenuButton,
|
||||
TitleBarMinButton,
|
||||
TitleBarMaxButton,
|
||||
TitleBarCloseButton,
|
||||
TitleBarNormalButton,
|
||||
TitleBarShadeButton,
|
||||
TitleBarUnshadeButton,
|
||||
TitleBarContextHelpButton,
|
||||
DockWidgetCloseButton,
|
||||
MessageBoxInformation,
|
||||
MessageBoxWarning,
|
||||
MessageBoxCritical,
|
||||
MessageBoxQuestion,
|
||||
DesktopIcon,
|
||||
TrashIcon,
|
||||
ComputerIcon,
|
||||
DriveFDIcon,
|
||||
DriveHDIcon,
|
||||
DriveCDIcon,
|
||||
DriveDVDIcon,
|
||||
DriveNetIcon,
|
||||
DirOpenIcon,
|
||||
DirClosedIcon,
|
||||
DirLinkIcon,
|
||||
DirLinkOpenIcon,
|
||||
FileIcon,
|
||||
FileLinkIcon,
|
||||
ToolBarHorizontalExtensionButton,
|
||||
ToolBarVerticalExtensionButton,
|
||||
FileDialogStart,
|
||||
FileDialogEnd,
|
||||
FileDialogToParent,
|
||||
FileDialogNewFolder,
|
||||
FileDialogDetailedView,
|
||||
FileDialogInfoView,
|
||||
FileDialogContentsView,
|
||||
FileDialogListView,
|
||||
FileDialogBack,
|
||||
DirIcon,
|
||||
DialogOkButton,
|
||||
DialogCancelButton,
|
||||
DialogHelpButton,
|
||||
DialogOpenButton,
|
||||
DialogSaveButton,
|
||||
DialogCloseButton,
|
||||
DialogApplyButton,
|
||||
DialogResetButton,
|
||||
DialogDiscardButton,
|
||||
DialogYesButton,
|
||||
DialogNoButton,
|
||||
ArrowUp,
|
||||
ArrowDown,
|
||||
ArrowLeft,
|
||||
ArrowRight,
|
||||
ArrowBack,
|
||||
ArrowForward,
|
||||
DirHomeIcon,
|
||||
CommandLink,
|
||||
VistaShield,
|
||||
BrowserReload,
|
||||
BrowserStop,
|
||||
MediaPlay,
|
||||
MediaStop,
|
||||
MediaPause,
|
||||
MediaSkipForward,
|
||||
MediaSkipBackward,
|
||||
MediaSeekForward,
|
||||
MediaSeekBackward,
|
||||
MediaVolume,
|
||||
MediaVolumeMuted,
|
||||
// do not add any values below/greater than this
|
||||
CustomBase = 0xf0000000
|
||||
};
|
||||
|
||||
enum KeyboardSchemes
|
||||
{
|
||||
WindowsKeyboardScheme,
|
||||
@ -190,6 +269,9 @@ public:
|
||||
|
||||
virtual QVariant themeHint(ThemeHint hint) const;
|
||||
|
||||
virtual QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const;
|
||||
virtual QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const;
|
||||
|
||||
static QVariant defaultThemeHint(ThemeHint hint);
|
||||
};
|
||||
|
||||
|
@ -67,6 +67,8 @@ public:
|
||||
|
||||
const QPalette *palette(Palette type = SystemPalette) const;
|
||||
const QFont *font(Font type = SystemFont) const;
|
||||
QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const;
|
||||
QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const;
|
||||
|
||||
QVariant themeHint(ThemeHint hint) const;
|
||||
|
||||
|
@ -54,7 +54,9 @@
|
||||
#include "qcocoamenu.h"
|
||||
#include "qcocoamenubar.h"
|
||||
|
||||
#include <QtCore/qfileinfo.h>
|
||||
#include <QtGui/private/qguiapplication_p.h>
|
||||
#include <QtGui/qpainter.h>
|
||||
#include <qpa/qplatformintegration.h>
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
|
||||
@ -135,6 +137,143 @@ const QFont *QCocoaTheme::font(Font type) const
|
||||
return m_fonts.value(type, 0);
|
||||
}
|
||||
|
||||
// Defined in qpaintengine_mac.mm
|
||||
extern CGContextRef qt_mac_cg_context(const QPaintDevice *pdev);
|
||||
|
||||
//! \internal
|
||||
QPixmap qt_mac_convert_iconref(const IconRef icon, int width, int height)
|
||||
{
|
||||
QPixmap ret(width, height);
|
||||
ret.fill(QColor(0, 0, 0, 0));
|
||||
|
||||
CGRect rect = CGRectMake(0, 0, width, height);
|
||||
|
||||
CGContextRef ctx = qt_mac_cg_context(&ret);
|
||||
CGAffineTransform old_xform = CGContextGetCTM(ctx);
|
||||
CGContextConcatCTM(ctx, CGAffineTransformInvert(old_xform));
|
||||
CGContextConcatCTM(ctx, CGAffineTransformIdentity);
|
||||
|
||||
::RGBColor b;
|
||||
b.blue = b.green = b.red = 255*255;
|
||||
PlotIconRefInContext(ctx, &rect, kAlignNone, kTransformNone, &b, kPlotIconRefNormalFlags, icon);
|
||||
CGContextRelease(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
QPixmap QCocoaTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
|
||||
{
|
||||
OSType iconType = 0;
|
||||
switch (sp) {
|
||||
case MessageBoxQuestion:
|
||||
iconType = kQuestionMarkIcon;
|
||||
break;
|
||||
case MessageBoxInformation:
|
||||
iconType = kAlertNoteIcon;
|
||||
break;
|
||||
case MessageBoxWarning:
|
||||
iconType = kAlertCautionIcon;
|
||||
break;
|
||||
case MessageBoxCritical:
|
||||
iconType = kAlertStopIcon;
|
||||
break;
|
||||
case DesktopIcon:
|
||||
iconType = kDesktopIcon;
|
||||
break;
|
||||
case TrashIcon:
|
||||
iconType = kTrashIcon;
|
||||
break;
|
||||
case ComputerIcon:
|
||||
iconType = kComputerIcon;
|
||||
break;
|
||||
case DriveFDIcon:
|
||||
iconType = kGenericFloppyIcon;
|
||||
break;
|
||||
case DriveHDIcon:
|
||||
iconType = kGenericHardDiskIcon;
|
||||
break;
|
||||
case DriveCDIcon:
|
||||
case DriveDVDIcon:
|
||||
iconType = kGenericCDROMIcon;
|
||||
break;
|
||||
case DriveNetIcon:
|
||||
iconType = kGenericNetworkIcon;
|
||||
break;
|
||||
case DirOpenIcon:
|
||||
iconType = kOpenFolderIcon;
|
||||
break;
|
||||
case DirClosedIcon:
|
||||
case DirLinkIcon:
|
||||
iconType = kGenericFolderIcon;
|
||||
break;
|
||||
case FileLinkIcon:
|
||||
case FileIcon:
|
||||
iconType = kGenericDocumentIcon;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (iconType != 0) {
|
||||
QPixmap pixmap;
|
||||
IconRef icon;
|
||||
IconRef overlayIcon = 0;
|
||||
if (iconType != kGenericApplicationIcon) {
|
||||
GetIconRef(kOnSystemDisk, kSystemIconsCreator, iconType, &icon);
|
||||
} else {
|
||||
FSRef fsRef;
|
||||
ProcessSerialNumber psn = { 0, kCurrentProcess };
|
||||
GetProcessBundleLocation(&psn, &fsRef);
|
||||
GetIconRefFromFileInfo(&fsRef, 0, 0, 0, 0, kIconServicesNormalUsageFlag, &icon, 0);
|
||||
if (sp == MessageBoxCritical) {
|
||||
overlayIcon = icon;
|
||||
GetIconRef(kOnSystemDisk, kSystemIconsCreator, kAlertCautionIcon, &icon);
|
||||
}
|
||||
}
|
||||
|
||||
if (icon) {
|
||||
pixmap = qt_mac_convert_iconref(icon, size.width(), size.height());
|
||||
ReleaseIconRef(icon);
|
||||
}
|
||||
|
||||
if (overlayIcon) {
|
||||
QSizeF littleSize = size / 2;
|
||||
QPixmap overlayPix = qt_mac_convert_iconref(overlayIcon, littleSize.width(), littleSize.height());
|
||||
QPainter painter(&pixmap);
|
||||
painter.drawPixmap(littleSize.width(), littleSize.height(), overlayPix);
|
||||
ReleaseIconRef(overlayIcon);
|
||||
}
|
||||
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
return QPlatformTheme::standardPixmap(sp, size);
|
||||
}
|
||||
|
||||
QPixmap QCocoaTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const
|
||||
{
|
||||
FSRef macRef;
|
||||
OSStatus status = FSPathMakeRef(reinterpret_cast<const UInt8*>(fileInfo.canonicalFilePath().toUtf8().constData()),
|
||||
&macRef, 0);
|
||||
if (status != noErr)
|
||||
return QPixmap();
|
||||
FSCatalogInfo info;
|
||||
HFSUniStr255 macName;
|
||||
status = FSGetCatalogInfo(&macRef, kIconServicesCatalogInfoMask, &info, &macName, 0, 0);
|
||||
if (status != noErr)
|
||||
return QPixmap();
|
||||
IconRef iconRef;
|
||||
SInt16 iconLabel;
|
||||
status = GetIconRefFromFileInfo(&macRef, macName.length, macName.unicode,
|
||||
kIconServicesCatalogInfoMask, &info, kIconServicesNormalUsageFlag,
|
||||
&iconRef, &iconLabel);
|
||||
if (status != noErr)
|
||||
return QPixmap();
|
||||
|
||||
QPixmap pixmap = qt_mac_convert_iconref(iconRef, size.width(), size.height());
|
||||
ReleaseIconRef(iconRef);
|
||||
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
QVariant QCocoaTheme::themeHint(ThemeHint hint) const
|
||||
{
|
||||
switch (hint) {
|
||||
@ -146,6 +285,11 @@ QVariant QCocoaTheme::themeHint(ThemeHint hint) const
|
||||
return QVariant(int(MacKeyboardScheme));
|
||||
case TabAllWidgets:
|
||||
return QVariant(bool([[NSApplication sharedApplication] isFullKeyboardAccessEnabled]));
|
||||
case IconPixmapSizes: {
|
||||
QList<int> sizes;
|
||||
sizes << 16 << 32 << 64 << 128;
|
||||
return QVariant::fromValue(sizes);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -83,6 +83,21 @@
|
||||
#define CHILDID_SELF 0
|
||||
#define WM_GETOBJECT 0x003D
|
||||
|
||||
#ifndef SIID_SHIELD // Shell structures for icons.
|
||||
typedef struct _SHSTOCKICONINFO
|
||||
{
|
||||
DWORD cbSize;
|
||||
HICON hIcon;
|
||||
int iSysImageIndex;
|
||||
int iIcon;
|
||||
WCHAR szPath[MAX_PATH];
|
||||
} SHSTOCKICONINFO;
|
||||
|
||||
# define SIID_SHIELD 77
|
||||
# define SHGFI_ADDOVERLAYS 0x20
|
||||
# define SHGFI_OVERLAYINDEX 0x40
|
||||
#endif // SIID_SHIELD
|
||||
|
||||
#if !defined(__MINGW64_VERSION_MAJOR)
|
||||
|
||||
#define STATE_SYSTEM_HASPOPUP 0x40000000
|
||||
|
@ -210,7 +210,9 @@ bool QWindowsUser32DLL::initTouch()
|
||||
\ingroup qt-lighthouse-win
|
||||
*/
|
||||
|
||||
QWindowsShell32DLL::QWindowsShell32DLL() : sHCreateItemFromParsingName(0)
|
||||
QWindowsShell32DLL::QWindowsShell32DLL()
|
||||
: sHCreateItemFromParsingName(0)
|
||||
, sHGetStockIconInfo(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -218,6 +220,7 @@ void QWindowsShell32DLL::init()
|
||||
{
|
||||
QSystemLibrary library(QStringLiteral("shell32"));
|
||||
sHCreateItemFromParsingName = (SHCreateItemFromParsingName)(library.resolve("SHCreateItemFromParsingName"));
|
||||
sHGetStockIconInfo = (SHGetStockIconInfo)library.resolve("SHGetStockIconInfo");
|
||||
}
|
||||
|
||||
QWindowsUser32DLL QWindowsContext::user32dll;
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include <QtCore/QSharedPointer>
|
||||
|
||||
struct IBindCtx;
|
||||
struct _SHSTOCKICONINFO;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -99,8 +100,10 @@ struct QWindowsShell32DLL
|
||||
inline void init();
|
||||
|
||||
typedef HRESULT (WINAPI *SHCreateItemFromParsingName)(PCWSTR, IBindCtx *, const GUID&, void **);
|
||||
typedef HRESULT (WINAPI *SHGetStockIconInfo)(int , int , _SHSTOCKICONINFO *);
|
||||
|
||||
SHCreateItemFromParsingName sHCreateItemFromParsingName;
|
||||
SHGetStockIconInfo sHGetStockIconInfo;
|
||||
};
|
||||
#endif // Q_OS_WINCE
|
||||
|
||||
|
@ -55,9 +55,13 @@
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtCore/QSysInfo>
|
||||
#include <QtCore/QCache>
|
||||
#include <QtGui/QPalette>
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QPixmapCache>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
#include <private/qsystemlibrary_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -348,6 +352,11 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const
|
||||
return QVariant(int(WindowsKeyboardScheme));
|
||||
case UiEffects:
|
||||
return QVariant(uiEffects());
|
||||
case IconPixmapSizes: {
|
||||
QList<int> sizes;
|
||||
sizes << 16 << 32;
|
||||
return QVariant::fromValue(sizes);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -433,4 +442,225 @@ void QWindowsTheme::windowsThemeChanged(QWindow * window)
|
||||
QWindowSystemInterface::handleThemeChange(window);
|
||||
}
|
||||
|
||||
// Defined in qpixmap_win.cpp
|
||||
Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon);
|
||||
|
||||
static QPixmap loadIconFromShell32(int resourceId, QSizeF size)
|
||||
{
|
||||
#ifdef Q_OS_WINCE
|
||||
HMODULE hmod = LoadLibrary(L"ceshell");
|
||||
#else
|
||||
HMODULE hmod = QSystemLibrary::load(L"shell32");
|
||||
#endif
|
||||
if (hmod) {
|
||||
HICON iconHandle = (HICON)LoadImage(hmod, MAKEINTRESOURCE(resourceId), IMAGE_ICON, size.width(), size.height(), 0);
|
||||
if (iconHandle) {
|
||||
QPixmap iconpixmap = qt_pixmapFromWinHICON(iconHandle);
|
||||
DestroyIcon(iconHandle);
|
||||
return iconpixmap;
|
||||
}
|
||||
}
|
||||
return QPixmap();
|
||||
}
|
||||
|
||||
QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
|
||||
{
|
||||
int resourceId = -1;
|
||||
LPCTSTR iconName = 0;
|
||||
switch (sp) {
|
||||
case DriveCDIcon:
|
||||
case DriveDVDIcon:
|
||||
resourceId = 12;
|
||||
break;
|
||||
case DriveNetIcon:
|
||||
resourceId = 10;
|
||||
break;
|
||||
case DriveHDIcon:
|
||||
resourceId = 9;
|
||||
break;
|
||||
case DriveFDIcon:
|
||||
resourceId = 7;
|
||||
break;
|
||||
case FileIcon:
|
||||
case FileLinkIcon:
|
||||
resourceId = 1;
|
||||
break;
|
||||
case DirIcon:
|
||||
case DirLinkIcon:
|
||||
case DirClosedIcon:
|
||||
resourceId = 4;
|
||||
break;
|
||||
case DesktopIcon:
|
||||
resourceId = 35;
|
||||
break;
|
||||
case ComputerIcon:
|
||||
resourceId = 16;
|
||||
break;
|
||||
case DirOpenIcon:
|
||||
case DirLinkOpenIcon:
|
||||
resourceId = 5;
|
||||
break;
|
||||
case FileDialogNewFolder:
|
||||
resourceId = 319;
|
||||
break;
|
||||
case DirHomeIcon:
|
||||
resourceId = 235;
|
||||
break;
|
||||
case TrashIcon:
|
||||
resourceId = 191;
|
||||
break;
|
||||
case MessageBoxInformation:
|
||||
iconName = IDI_INFORMATION;
|
||||
break;
|
||||
case MessageBoxWarning:
|
||||
iconName = IDI_WARNING;
|
||||
break;
|
||||
case MessageBoxCritical:
|
||||
iconName = IDI_ERROR;
|
||||
break;
|
||||
case MessageBoxQuestion:
|
||||
iconName = IDI_QUESTION;
|
||||
break;
|
||||
case VistaShield:
|
||||
if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
|
||||
&& (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)) {
|
||||
if (!QWindowsContext::shell32dll.sHGetStockIconInfo)
|
||||
return QPixmap();
|
||||
QPixmap pixmap;
|
||||
SHSTOCKICONINFO iconInfo;
|
||||
memset(&iconInfo, 0, sizeof(iconInfo));
|
||||
iconInfo.cbSize = sizeof(iconInfo);
|
||||
const int iconSize = size.width() > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON;
|
||||
if (QWindowsContext::shell32dll.sHGetStockIconInfo(SIID_SHIELD, SHGFI_ICON | iconSize, &iconInfo) == S_OK) {
|
||||
pixmap = qt_pixmapFromWinHICON(iconInfo.hIcon);
|
||||
DestroyIcon(iconInfo.hIcon);
|
||||
return pixmap;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (resourceId != -1) {
|
||||
QPixmap pixmap = loadIconFromShell32(resourceId, size);
|
||||
if (!pixmap.isNull()) {
|
||||
if (sp == FileLinkIcon || sp == DirLinkIcon || sp == DirLinkOpenIcon) {
|
||||
QPainter painter(&pixmap);
|
||||
QPixmap link = loadIconFromShell32(30, size);
|
||||
painter.drawPixmap(0, 0, size.width(), size.height(), link);
|
||||
}
|
||||
return pixmap;
|
||||
}
|
||||
}
|
||||
|
||||
if (iconName) {
|
||||
HICON iconHandle = LoadIcon(NULL, iconName);
|
||||
QPixmap pixmap = qt_pixmapFromWinHICON(iconHandle);
|
||||
DestroyIcon(iconHandle);
|
||||
if (!pixmap.isNull())
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
return QPlatformTheme::standardPixmap(sp, size);
|
||||
}
|
||||
|
||||
static QString dirIconPixmapCacheKey(int iIcon, int iconSize)
|
||||
{
|
||||
QString key = QLatin1String("qt_dir_") + QString::number(iIcon);
|
||||
if (iconSize == SHGFI_LARGEICON)
|
||||
key += QLatin1Char('l');
|
||||
return key;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class FakePointer
|
||||
{
|
||||
public:
|
||||
|
||||
Q_STATIC_ASSERT_X(sizeof(T) <= sizeof(void *), "FakePointers can only go that far.");
|
||||
|
||||
static FakePointer *create(T thing)
|
||||
{
|
||||
return reinterpret_cast<FakePointer *>(thing);
|
||||
}
|
||||
|
||||
T operator * () const
|
||||
{
|
||||
return reinterpret_cast<T>(this);
|
||||
}
|
||||
|
||||
void operator delete (void *) {}
|
||||
};
|
||||
|
||||
QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const
|
||||
{
|
||||
/* We don't use the variable, but by storing it statically, we
|
||||
* ensure CoInitialize is only called once. */
|
||||
static HRESULT comInit = CoInitialize(NULL);
|
||||
Q_UNUSED(comInit);
|
||||
|
||||
static QCache<QString, FakePointer<int> > dirIconEntryCache(1000);
|
||||
static QMutex mx;
|
||||
|
||||
QPixmap pixmap;
|
||||
const QString filePath = QDir::toNativeSeparators(fileInfo.filePath());
|
||||
int iconSize = size.width() > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON;
|
||||
|
||||
bool cacheableDirIcon = fileInfo.isDir() && !fileInfo.isRoot();
|
||||
if (cacheableDirIcon) {
|
||||
QMutexLocker locker(&mx);
|
||||
int iIcon = **dirIconEntryCache.object(filePath);
|
||||
if (iIcon) {
|
||||
QPixmapCache::find(dirIconPixmapCacheKey(iIcon, iconSize), pixmap);
|
||||
if (pixmap.isNull()) // Let's keep both caches in sync
|
||||
dirIconEntryCache.remove(filePath);
|
||||
else
|
||||
return pixmap;
|
||||
}
|
||||
}
|
||||
|
||||
SHFILEINFO info;
|
||||
unsigned int flags =
|
||||
#ifndef Q_OS_WINCE
|
||||
SHGFI_ICON|iconSize|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS|SHGFI_OVERLAYINDEX;
|
||||
#else
|
||||
iconSize|SHGFI_SYSICONINDEX;
|
||||
#endif // Q_OS_WINCE
|
||||
unsigned long val = SHGetFileInfo((const wchar_t *)filePath.utf16(), 0,
|
||||
&info, sizeof(SHFILEINFO), flags);
|
||||
|
||||
// Even if GetFileInfo returns a valid result, hIcon can be empty in some cases
|
||||
if (val && info.hIcon) {
|
||||
QString key;
|
||||
if (cacheableDirIcon) {
|
||||
//using the unique icon index provided by windows save us from duplicate keys
|
||||
key = dirIconPixmapCacheKey(info.iIcon, iconSize);
|
||||
QPixmapCache::find(key, pixmap);
|
||||
if (!pixmap.isNull()) {
|
||||
QMutexLocker locker(&mx);
|
||||
dirIconEntryCache.insert(filePath, FakePointer<int>::create(info.iIcon));
|
||||
}
|
||||
}
|
||||
|
||||
if (pixmap.isNull()) {
|
||||
pixmap = qt_pixmapFromWinHICON(info.hIcon);
|
||||
if (!pixmap.isNull()) {
|
||||
if (cacheableDirIcon) {
|
||||
QMutexLocker locker(&mx);
|
||||
QPixmapCache::insert(key, pixmap);
|
||||
dirIconEntryCache.insert(filePath, FakePointer<int>::create(info.iIcon));
|
||||
}
|
||||
} else {
|
||||
qWarning("QWindowsTheme::fileIconPixmap() no icon found");
|
||||
}
|
||||
}
|
||||
DestroyIcon(info.hIcon);
|
||||
}
|
||||
|
||||
if (!pixmap.isNull())
|
||||
return pixmap;
|
||||
return QPlatformTheme::fileIconPixmap(fileInfo, size);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -67,6 +67,9 @@ public:
|
||||
virtual const QFont *font(Font type = SystemFont) const
|
||||
{ return m_fonts[type]; }
|
||||
|
||||
virtual QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const;
|
||||
virtual QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const;
|
||||
|
||||
void windowsThemeChanged(QWindow *window);
|
||||
|
||||
static const char *name;
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include <private/qguiapplication_p.h>
|
||||
#include <qpa/qplatformintegration.h>
|
||||
#include <qpa/qplatformservices.h>
|
||||
#include <qpa/qplatformtheme.h>
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#if defined(_WIN32_IE)
|
||||
@ -59,26 +60,14 @@
|
||||
# include <qt_windows.h>
|
||||
# include <commctrl.h>
|
||||
# include <objbase.h>
|
||||
|
||||
#elif defined(Q_WS_MAC)
|
||||
# include <private/qt_cocoa_helpers_mac_p.h>
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_UNIX) && !defined(QT_NO_STYLE_GTK)
|
||||
# include <private/qgtkstyle_p.h>
|
||||
#endif
|
||||
|
||||
#ifndef SHGFI_ADDOVERLAYS
|
||||
# define SHGFI_ADDOVERLAYS 0x000000020
|
||||
# define SHGFI_OVERLAYINDEX 0x000000040
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#if defined (Q_OS_WIN)
|
||||
Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\class QFileIconProvider
|
||||
|
||||
@ -105,11 +94,8 @@ class QFileIconProviderPrivate
|
||||
public:
|
||||
QFileIconProviderPrivate();
|
||||
QIcon getIcon(QStyle::StandardPixmap name) const;
|
||||
#ifdef Q_OS_WIN
|
||||
QIcon getWinIcon(const QFileInfo &fi) const;
|
||||
#elif defined(Q_WS_MAC)
|
||||
QIcon getMacIcon(const QFileInfo &fi) const;
|
||||
#endif
|
||||
QIcon getIcon(const QFileInfo &fi) const;
|
||||
|
||||
QFileIconProvider *q_ptr;
|
||||
const QString homePath;
|
||||
|
||||
@ -238,163 +224,51 @@ QIcon QFileIconProvider::icon(IconType type) const
|
||||
return QIcon();
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const
|
||||
QIcon QFileIconProviderPrivate::getIcon(const QFileInfo &fi) const
|
||||
{
|
||||
QIcon retIcon;
|
||||
const QString fileExtension = QLatin1Char('.') + fileInfo.suffix().toUpper();
|
||||
|
||||
QString key;
|
||||
if (fileInfo.isFile() && !fileInfo.isExecutable() && !fileInfo.isSymLink() && fileExtension != QLatin1String(".ICO"))
|
||||
key = QLatin1String("qt_") + fileExtension;
|
||||
|
||||
QPixmap pixmap;
|
||||
if (!key.isEmpty()) {
|
||||
QPixmapCache::find(key, pixmap);
|
||||
}
|
||||
|
||||
if (!pixmap.isNull()) {
|
||||
retIcon.addPixmap(pixmap);
|
||||
if (QPixmapCache::find(key + QLatin1Char('l'), pixmap))
|
||||
retIcon.addPixmap(pixmap);
|
||||
const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
|
||||
if (!theme)
|
||||
return retIcon;
|
||||
}
|
||||
|
||||
/* We don't use the variable, but by storing it statically, we
|
||||
* ensure CoInitialize is only called once. */
|
||||
static HRESULT comInit = CoInitialize(NULL);
|
||||
Q_UNUSED(comInit);
|
||||
QList<int> sizes = theme->themeHint(QPlatformTheme::IconPixmapSizes).value<QList<int> >();
|
||||
if (sizes.isEmpty())
|
||||
return retIcon;
|
||||
|
||||
SHFILEINFO info;
|
||||
unsigned long val = 0;
|
||||
const QString fileExtension = fi.suffix().toUpper();
|
||||
const QString keyBase = QLatin1String("qt_.") + fi.suffix().toUpper();
|
||||
|
||||
//Get the small icon
|
||||
#ifndef Q_OS_WINCE
|
||||
val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
|
||||
sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_SMALLICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS|SHGFI_OVERLAYINDEX);
|
||||
#else
|
||||
val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
|
||||
sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_SYSICONINDEX);
|
||||
#endif
|
||||
|
||||
// Even if GetFileInfo returns a valid result, hIcon can be empty in some cases
|
||||
if (val && info.hIcon) {
|
||||
if (fileInfo.isDir() && !fileInfo.isRoot()) {
|
||||
//using the unique icon index provided by windows save us from duplicate keys
|
||||
key = QString::fromLatin1("qt_dir_%1").arg(info.iIcon);
|
||||
QPixmapCache::find(key, pixmap);
|
||||
if (!pixmap.isNull()) {
|
||||
retIcon.addPixmap(pixmap);
|
||||
if (QPixmapCache::find(key + QLatin1Char('l'), pixmap))
|
||||
bool cacheable = fi.isFile() && !fi.isExecutable() && !fi.isSymLink() && fileExtension != QLatin1String("ICO");
|
||||
if (cacheable) {
|
||||
QPixmap pixmap;
|
||||
QPixmapCache::find(keyBase + QString::number(sizes.at(0)), pixmap);
|
||||
if (!pixmap.isNull()) {
|
||||
bool iconIsComplete = true;
|
||||
retIcon.addPixmap(pixmap);
|
||||
for (int i = 1; i < sizes.count(); i++)
|
||||
if (QPixmapCache::find(keyBase + QString::number(sizes.at(i)), pixmap)) {
|
||||
retIcon.addPixmap(pixmap);
|
||||
DestroyIcon(info.hIcon);
|
||||
} else {
|
||||
iconIsComplete = false;
|
||||
break;
|
||||
}
|
||||
if (iconIsComplete)
|
||||
return retIcon;
|
||||
}
|
||||
}
|
||||
if (pixmap.isNull()) {
|
||||
pixmap = qt_pixmapFromWinHICON(info.hIcon);
|
||||
if (!pixmap.isNull()) {
|
||||
retIcon.addPixmap(pixmap);
|
||||
if (!key.isEmpty())
|
||||
QPixmapCache::insert(key, pixmap);
|
||||
}
|
||||
else {
|
||||
qWarning("QFileIconProviderPrivate::getWinIcon() no small icon found");
|
||||
}
|
||||
}
|
||||
DestroyIcon(info.hIcon);
|
||||
}
|
||||
|
||||
//Get the big icon
|
||||
#ifndef Q_OS_WINCE
|
||||
val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
|
||||
sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_LARGEICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS|SHGFI_OVERLAYINDEX);
|
||||
#else
|
||||
val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
|
||||
sizeof(SHFILEINFO), SHGFI_LARGEICON|SHGFI_SYSICONINDEX);
|
||||
#endif
|
||||
if (val && info.hIcon) {
|
||||
if (fileInfo.isDir() && !fileInfo.isRoot()) {
|
||||
//using the unique icon index provided by windows save us from duplicate keys
|
||||
key = QString::fromLatin1("qt_dir_%1").arg(info.iIcon);
|
||||
}
|
||||
pixmap = qt_pixmapFromWinHICON(info.hIcon);
|
||||
Q_FOREACH (int size, sizes) {
|
||||
QPixmap pixmap = theme->fileIconPixmap(fi, QSizeF(size, size));
|
||||
if (!pixmap.isNull()) {
|
||||
retIcon.addPixmap(pixmap);
|
||||
if (!key.isEmpty())
|
||||
QPixmapCache::insert(key + QLatin1Char('l'), pixmap);
|
||||
if (cacheable)
|
||||
QPixmapCache::insert(keyBase + QString::number(size), pixmap);
|
||||
}
|
||||
else {
|
||||
qWarning("QFileIconProviderPrivate::getWinIcon() no large icon found");
|
||||
}
|
||||
DestroyIcon(info.hIcon);
|
||||
}
|
||||
|
||||
return retIcon;
|
||||
}
|
||||
|
||||
#elif defined(Q_WS_MAC)
|
||||
QIcon QFileIconProviderPrivate::getMacIcon(const QFileInfo &fi) const
|
||||
{
|
||||
QIcon retIcon;
|
||||
QString fileExtension = fi.suffix().toUpper();
|
||||
fileExtension.prepend(QLatin1String("."));
|
||||
|
||||
const QString keyBase = QLatin1String("qt_") + fileExtension;
|
||||
|
||||
QPixmap pixmap;
|
||||
if (fi.isFile() && !fi.isExecutable() && !fi.isSymLink()) {
|
||||
QPixmapCache::find(keyBase + QLatin1String("16"), pixmap);
|
||||
}
|
||||
|
||||
if (!pixmap.isNull()) {
|
||||
retIcon.addPixmap(pixmap);
|
||||
if (QPixmapCache::find(keyBase + QLatin1String("32"), pixmap)) {
|
||||
retIcon.addPixmap(pixmap);
|
||||
if (QPixmapCache::find(keyBase + QLatin1String("64"), pixmap)) {
|
||||
retIcon.addPixmap(pixmap);
|
||||
if (QPixmapCache::find(keyBase + QLatin1String("128"), pixmap)) {
|
||||
retIcon.addPixmap(pixmap);
|
||||
return retIcon;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FSRef macRef;
|
||||
OSStatus status = FSPathMakeRef(reinterpret_cast<const UInt8*>(fi.canonicalFilePath().toUtf8().constData()),
|
||||
&macRef, 0);
|
||||
if (status != noErr)
|
||||
return retIcon;
|
||||
FSCatalogInfo info;
|
||||
HFSUniStr255 macName;
|
||||
status = FSGetCatalogInfo(&macRef, kIconServicesCatalogInfoMask, &info, &macName, 0, 0);
|
||||
if (status != noErr)
|
||||
return retIcon;
|
||||
IconRef iconRef;
|
||||
SInt16 iconLabel;
|
||||
status = GetIconRefFromFileInfo(&macRef, macName.length, macName.unicode,
|
||||
kIconServicesCatalogInfoMask, &info, kIconServicesNormalUsageFlag,
|
||||
&iconRef, &iconLabel);
|
||||
if (status != noErr)
|
||||
return retIcon;
|
||||
qt_mac_constructQIconFromIconRef(iconRef, 0, &retIcon);
|
||||
ReleaseIconRef(iconRef);
|
||||
|
||||
if (fi.isFile() && !fi.isExecutable() && !fi.isSymLink()) {
|
||||
pixmap = retIcon.pixmap(16);
|
||||
QPixmapCache::insert(keyBase + QLatin1String("16"), pixmap);
|
||||
pixmap = retIcon.pixmap(32);
|
||||
QPixmapCache::insert(keyBase + QLatin1String("32"), pixmap);
|
||||
pixmap = retIcon.pixmap(64);
|
||||
QPixmapCache::insert(keyBase + QLatin1String("64"), pixmap);
|
||||
pixmap = retIcon.pixmap(128);
|
||||
QPixmapCache::insert(keyBase + QLatin1String("128"), pixmap);
|
||||
}
|
||||
return retIcon;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
Returns an icon for the file described by \a info.
|
||||
@ -412,15 +286,10 @@ QIcon QFileIconProvider::icon(const QFileInfo &info) const
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
QIcon retIcon = d->getMacIcon(info);
|
||||
QIcon retIcon = d->getIcon(info);
|
||||
if (!retIcon.isNull())
|
||||
return retIcon;
|
||||
#elif defined Q_OS_WIN
|
||||
QIcon icon = d->getWinIcon(info);
|
||||
if (!icon.isNull())
|
||||
return icon;
|
||||
#endif
|
||||
|
||||
if (info.isRoot())
|
||||
#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE)
|
||||
{
|
||||
@ -445,6 +314,7 @@ QIcon QFileIconProvider::icon(const QFileInfo &info) const
|
||||
#else
|
||||
return d->getIcon(QStyle::SP_DriveHDIcon);
|
||||
#endif
|
||||
|
||||
if (info.isFile()) {
|
||||
if (info.isSymLink())
|
||||
return d->getIcon(QStyle::SP_FileLinkIcon);
|
||||
|
@ -5519,67 +5519,24 @@ QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption
|
||||
break;
|
||||
}
|
||||
} // if (QApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty())
|
||||
if (!icon.isNull())
|
||||
return icon;
|
||||
#if defined(Q_WS_MAC)
|
||||
|
||||
if (!icon.isNull())
|
||||
return icon;
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
if (QApplication::desktopSettingsAware()) {
|
||||
OSType iconType = 0;
|
||||
switch (standardIcon) {
|
||||
case QStyle::SP_MessageBoxQuestion:
|
||||
iconType = kQuestionMarkIcon;
|
||||
break;
|
||||
case QStyle::SP_MessageBoxInformation:
|
||||
iconType = kAlertNoteIcon;
|
||||
break;
|
||||
case QStyle::SP_MessageBoxWarning:
|
||||
iconType = kAlertCautionIcon;
|
||||
break;
|
||||
case QStyle::SP_MessageBoxCritical:
|
||||
iconType = kAlertStopIcon;
|
||||
break;
|
||||
case SP_DesktopIcon:
|
||||
iconType = kDesktopIcon;
|
||||
break;
|
||||
case SP_TrashIcon:
|
||||
iconType = kTrashIcon;
|
||||
break;
|
||||
case SP_ComputerIcon:
|
||||
iconType = kComputerIcon;
|
||||
break;
|
||||
case SP_DriveFDIcon:
|
||||
iconType = kGenericFloppyIcon;
|
||||
break;
|
||||
case SP_DriveHDIcon:
|
||||
iconType = kGenericHardDiskIcon;
|
||||
break;
|
||||
case SP_DriveCDIcon:
|
||||
case SP_DriveDVDIcon:
|
||||
iconType = kGenericCDROMIcon;
|
||||
break;
|
||||
case SP_DriveNetIcon:
|
||||
iconType = kGenericNetworkIcon;
|
||||
break;
|
||||
case SP_DirOpenIcon:
|
||||
iconType = kOpenFolderIcon;
|
||||
break;
|
||||
case SP_DirClosedIcon:
|
||||
case SP_DirLinkIcon:
|
||||
iconType = kGenericFolderIcon;
|
||||
break;
|
||||
case SP_FileLinkIcon:
|
||||
case SP_FileIcon:
|
||||
iconType = kGenericDocumentIcon;
|
||||
break;
|
||||
case SP_DirIcon: {
|
||||
// A rather special case
|
||||
QIcon closeIcon = QStyle::standardIcon(SP_DirClosedIcon, option, widget);
|
||||
QIcon openIcon = QStyle::standardIcon(SP_DirOpenIcon, option, widget);
|
||||
QIcon closeIcon = QCommonStyle::standardIcon(SP_DirClosedIcon, option, widget);
|
||||
QIcon openIcon = QCommonStyle::standardIcon(SP_DirOpenIcon, option, widget);
|
||||
closeIcon.addPixmap(openIcon.pixmap(16, 16), QIcon::Normal, QIcon::On);
|
||||
closeIcon.addPixmap(openIcon.pixmap(32, 32), QIcon::Normal, QIcon::On);
|
||||
closeIcon.addPixmap(openIcon.pixmap(64, 64), QIcon::Normal, QIcon::On);
|
||||
closeIcon.addPixmap(openIcon.pixmap(128, 128), QIcon::Normal, QIcon::On);
|
||||
return closeIcon;
|
||||
}
|
||||
|
||||
case SP_TitleBarNormalButton:
|
||||
case SP_TitleBarCloseButton: {
|
||||
QIcon titleBarIcon;
|
||||
@ -5592,35 +5549,49 @@ QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption
|
||||
}
|
||||
return titleBarIcon;
|
||||
}
|
||||
|
||||
case SP_MessageBoxQuestion:
|
||||
case SP_MessageBoxInformation:
|
||||
case SP_MessageBoxWarning:
|
||||
case SP_MessageBoxCritical:
|
||||
case SP_DesktopIcon:
|
||||
case SP_TrashIcon:
|
||||
case SP_ComputerIcon:
|
||||
case SP_DriveFDIcon:
|
||||
case SP_DriveHDIcon:
|
||||
case SP_DriveCDIcon:
|
||||
case SP_DriveDVDIcon:
|
||||
case SP_DriveNetIcon:
|
||||
case SP_DirOpenIcon:
|
||||
case SP_DirClosedIcon:
|
||||
case SP_DirLinkIcon:
|
||||
case SP_FileLinkIcon:
|
||||
case SP_FileIcon:
|
||||
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
|
||||
QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardIcon);
|
||||
QIcon retIcon;
|
||||
QList<int> sizes = theme->themeHint(QPlatformTheme::IconPixmapSizes).value<QList<int> >();
|
||||
Q_FOREACH (int size, sizes) {
|
||||
QPixmap mainIcon;
|
||||
const QString cacheKey = QLatin1String("qt_mac_constructQIconFromIconRef") + QString::number(standardIcon) + QString::number(size);
|
||||
if (standardIcon >= QStyle::SP_CustomBase) {
|
||||
mainIcon = theme->standardPixmap(sp, QSizeF(size, size));
|
||||
} else if (QPixmapCache::find(cacheKey, mainIcon) == false) {
|
||||
mainIcon = theme->standardPixmap(sp, QSizeF(size, size));
|
||||
QPixmapCache::insert(cacheKey, mainIcon);
|
||||
}
|
||||
|
||||
retIcon.addPixmap(mainIcon);
|
||||
}
|
||||
if (!retIcon.isNull())
|
||||
return retIcon;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (iconType != 0) {
|
||||
QIcon retIcon;
|
||||
IconRef icon;
|
||||
IconRef overlayIcon = 0;
|
||||
if (iconType != kGenericApplicationIcon) {
|
||||
GetIconRef(kOnSystemDisk, kSystemIconsCreator, iconType, &icon);
|
||||
} else {
|
||||
FSRef fsRef;
|
||||
ProcessSerialNumber psn = { 0, kCurrentProcess };
|
||||
GetProcessBundleLocation(&psn, &fsRef);
|
||||
GetIconRefFromFileInfo(&fsRef, 0, 0, 0, 0, kIconServicesNormalUsageFlag, &icon, 0);
|
||||
if (standardIcon == SP_MessageBoxCritical) {
|
||||
overlayIcon = icon;
|
||||
GetIconRef(kOnSystemDisk, kSystemIconsCreator, kAlertCautionIcon, &icon);
|
||||
}
|
||||
}
|
||||
if (icon) {
|
||||
qt_mac_constructQIconFromIconRef(icon, overlayIcon, &retIcon, standardIcon);
|
||||
ReleaseIconRef(icon);
|
||||
}
|
||||
if (overlayIcon)
|
||||
ReleaseIconRef(overlayIcon);
|
||||
return retIcon;
|
||||
}
|
||||
} // if (QApplication::desktopSettingsAware())
|
||||
#endif // Q_WS_MAC
|
||||
#endif // Q_OS_MAC
|
||||
|
||||
switch (standardIcon) {
|
||||
#ifndef QT_NO_IMAGEFORMAT_PNG
|
||||
|
@ -103,6 +103,7 @@
|
||||
#include <private/qstylehelper_p.h>
|
||||
#include <private/qstyleanimation_p.h>
|
||||
#include <qpa/qplatformfontdatabase.h>
|
||||
#include <qpa/qplatformtheme.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
|
@ -1934,6 +1934,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
|
||||
\value SP_DirClosedIcon The closed directory icon.
|
||||
\value SP_DirIcon The directory icon.
|
||||
\value SP_DirLinkIcon The link to directory icon.
|
||||
\value SP_DirLinkOpenIcon The link to open directory icon.
|
||||
\value SP_FileIcon The file icon.
|
||||
\value SP_FileLinkIcon The link to file icon.
|
||||
\value SP_FileDialogStart The "start" icon in a file dialog.
|
||||
|
@ -731,6 +731,7 @@ public:
|
||||
SP_DirOpenIcon,
|
||||
SP_DirClosedIcon,
|
||||
SP_DirLinkIcon,
|
||||
SP_DirLinkOpenIcon,
|
||||
SP_FileIcon,
|
||||
SP_FileLinkIcon,
|
||||
SP_ToolBarHorizontalExtensionButton,
|
||||
|
@ -68,6 +68,8 @@
|
||||
#include "qlistview.h"
|
||||
#include <private/qmath_p.h>
|
||||
#include <qmath.h>
|
||||
#include <qpa/qplatformtheme.h>
|
||||
#include <private/qguiapplication_p.h>
|
||||
|
||||
#include <private/qstylehelper_p.h>
|
||||
#include <private/qstyleanimation_p.h>
|
||||
@ -889,26 +891,6 @@ static const char *const question_xpm[] = {
|
||||
|
||||
#endif //QT_NO_IMAGEFORMAT_XPM
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
static QPixmap loadIconFromShell32( int resourceId, int size )
|
||||
{
|
||||
#ifdef Q_OS_WINCE
|
||||
HMODULE hmod = LoadLibrary(L"ceshell");
|
||||
#else
|
||||
HMODULE hmod = QSystemLibrary::load(L"shell32");
|
||||
#endif
|
||||
if( hmod ) {
|
||||
HICON iconHandle = (HICON)LoadImage(hmod, MAKEINTRESOURCE(resourceId), IMAGE_ICON, size, size, 0);
|
||||
if( iconHandle ) {
|
||||
QPixmap iconpixmap = qt_pixmapFromWinHICON(iconHandle);
|
||||
DestroyIcon(iconHandle);
|
||||
return iconpixmap;
|
||||
}
|
||||
}
|
||||
return QPixmap();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
@ -920,125 +902,32 @@ QPixmap QWindowsStyle::standardPixmap(StandardPixmap standardPixmap, const QStyl
|
||||
switch(standardPixmap) {
|
||||
case SP_DriveCDIcon:
|
||||
case SP_DriveDVDIcon:
|
||||
{
|
||||
desktopIcon = loadIconFromShell32(12, 16);
|
||||
break;
|
||||
}
|
||||
case SP_DriveNetIcon:
|
||||
{
|
||||
desktopIcon = loadIconFromShell32(10, 16);
|
||||
break;
|
||||
}
|
||||
case SP_DriveHDIcon:
|
||||
{
|
||||
desktopIcon = loadIconFromShell32(9, 16);
|
||||
break;
|
||||
}
|
||||
case SP_DriveFDIcon:
|
||||
{
|
||||
desktopIcon = loadIconFromShell32(7, 16);
|
||||
break;
|
||||
}
|
||||
case SP_FileIcon:
|
||||
{
|
||||
desktopIcon = loadIconFromShell32(1, 16);
|
||||
break;
|
||||
}
|
||||
case SP_FileLinkIcon:
|
||||
{
|
||||
desktopIcon = loadIconFromShell32(1, 16);
|
||||
QPainter painter(&desktopIcon);
|
||||
QPixmap link = loadIconFromShell32(30, 16);
|
||||
painter.drawPixmap(0, 0, 16, 16, link);
|
||||
break;
|
||||
}
|
||||
case SP_DirLinkIcon:
|
||||
{
|
||||
desktopIcon = loadIconFromShell32(4, 16);
|
||||
QPainter painter(&desktopIcon);
|
||||
QPixmap link = loadIconFromShell32(30, 16);
|
||||
painter.drawPixmap(0, 0, 16, 16, link);
|
||||
break;
|
||||
}
|
||||
case SP_DirClosedIcon:
|
||||
{
|
||||
desktopIcon = loadIconFromShell32(4, 16);
|
||||
break;
|
||||
}
|
||||
case SP_DesktopIcon:
|
||||
{
|
||||
desktopIcon = loadIconFromShell32(35, 16);
|
||||
break;
|
||||
}
|
||||
case SP_ComputerIcon:
|
||||
{
|
||||
desktopIcon = loadIconFromShell32(16, 16);
|
||||
break;
|
||||
}
|
||||
case SP_DirOpenIcon:
|
||||
{
|
||||
desktopIcon = loadIconFromShell32(5, 16);
|
||||
break;
|
||||
}
|
||||
case SP_FileDialogNewFolder:
|
||||
{
|
||||
desktopIcon = loadIconFromShell32(319, 16);
|
||||
break;
|
||||
}
|
||||
case SP_DirHomeIcon:
|
||||
{
|
||||
desktopIcon = loadIconFromShell32(235, 16);
|
||||
break;
|
||||
}
|
||||
case SP_TrashIcon:
|
||||
{
|
||||
desktopIcon = loadIconFromShell32(191, 16);
|
||||
break;
|
||||
}
|
||||
case SP_MessageBoxInformation:
|
||||
{
|
||||
HICON iconHandle = LoadIcon(NULL, IDI_INFORMATION);
|
||||
desktopIcon = qt_pixmapFromWinHICON(iconHandle);
|
||||
DestroyIcon(iconHandle);
|
||||
break;
|
||||
}
|
||||
case SP_MessageBoxWarning:
|
||||
{
|
||||
HICON iconHandle = LoadIcon(NULL, IDI_WARNING);
|
||||
desktopIcon = qt_pixmapFromWinHICON(iconHandle);
|
||||
DestroyIcon(iconHandle);
|
||||
break;
|
||||
}
|
||||
case SP_MessageBoxCritical:
|
||||
{
|
||||
HICON iconHandle = LoadIcon(NULL, IDI_ERROR);
|
||||
desktopIcon = qt_pixmapFromWinHICON(iconHandle);
|
||||
DestroyIcon(iconHandle);
|
||||
break;
|
||||
}
|
||||
case SP_MessageBoxQuestion:
|
||||
{
|
||||
HICON iconHandle = LoadIcon(NULL, IDI_QUESTION);
|
||||
desktopIcon = qt_pixmapFromWinHICON(iconHandle);
|
||||
DestroyIcon(iconHandle);
|
||||
break;
|
||||
}
|
||||
case SP_VistaShield:
|
||||
{
|
||||
if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
|
||||
&& (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)
|
||||
&& pSHGetStockIconInfo)
|
||||
{
|
||||
QPixmap pixmap;
|
||||
QSHSTOCKICONINFO iconInfo;
|
||||
memset(&iconInfo, 0, sizeof(iconInfo));
|
||||
iconInfo.cbSize = sizeof(iconInfo);
|
||||
if (pSHGetStockIconInfo(_SIID_SHIELD, _SHGFI_ICON | _SHGFI_SMALLICON, &iconInfo) == S_OK) {
|
||||
pixmap = qt_pixmapFromWinHICON(iconInfo.hIcon);
|
||||
DestroyIcon(iconInfo.hIcon);
|
||||
return pixmap;
|
||||
}
|
||||
}
|
||||
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
|
||||
QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardPixmap);
|
||||
desktopIcon = theme->standardPixmap(sp, QSizeF(16, 16));
|
||||
}
|
||||
break;
|
||||
case SP_MessageBoxInformation:
|
||||
case SP_MessageBoxWarning:
|
||||
case SP_MessageBoxCritical:
|
||||
case SP_MessageBoxQuestion:
|
||||
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
|
||||
QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardPixmap);
|
||||
desktopIcon = theme->standardPixmap(sp, QSizeF());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -3046,124 +2935,47 @@ QIcon QWindowsStyle::standardIcon(StandardPixmap standardIcon, const QStyleOptio
|
||||
const QWidget *widget) const
|
||||
{
|
||||
QIcon icon;
|
||||
QPixmap pixmap;
|
||||
#ifdef Q_OS_WIN
|
||||
QPixmap pixmap;
|
||||
switch (standardIcon) {
|
||||
case SP_FileDialogNewFolder:
|
||||
{
|
||||
for (int size = 16 ; size <= 32 ; size += 16) {
|
||||
pixmap = loadIconFromShell32(319, size);
|
||||
icon.addPixmap(pixmap, QIcon::Normal);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SP_DirHomeIcon:
|
||||
{
|
||||
for (int size = 16 ; size <= 32 ; size += 16) {
|
||||
pixmap = loadIconFromShell32(235, size);
|
||||
icon.addPixmap(pixmap, QIcon::Normal);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SP_DirIcon:
|
||||
for (int size = 16 ; size <= 32 ; size += 16) {
|
||||
pixmap = loadIconFromShell32(4, size);
|
||||
icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off);
|
||||
pixmap = loadIconFromShell32(5, size);
|
||||
icon.addPixmap(pixmap, QIcon::Normal, QIcon::On);
|
||||
}
|
||||
break;
|
||||
case SP_DirLinkIcon:
|
||||
for (int size = 16 ; size <= 32 ; size += 16) {
|
||||
QPixmap link = loadIconFromShell32(30, size);
|
||||
pixmap = loadIconFromShell32(4, size);
|
||||
if (!pixmap.isNull() && !link.isNull()) {
|
||||
QPainter painter(&pixmap);
|
||||
painter.drawPixmap(0, 0, size, size, link);
|
||||
icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off);
|
||||
}
|
||||
link = loadIconFromShell32(30, size);
|
||||
pixmap = loadIconFromShell32(5, size);
|
||||
if (!pixmap.isNull() && !link.isNull()) {
|
||||
QPainter painter(&pixmap);
|
||||
painter.drawPixmap(0, 0, size, size, link);
|
||||
icon.addPixmap(pixmap, QIcon::Normal, QIcon::On);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SP_FileIcon:
|
||||
for (int size = 16 ; size <= 32 ; size += 16) {
|
||||
pixmap = loadIconFromShell32(1, size);
|
||||
icon.addPixmap(pixmap, QIcon::Normal);
|
||||
}
|
||||
break;
|
||||
case SP_ComputerIcon:
|
||||
for (int size = 16 ; size <= 32 ; size += 16) {
|
||||
pixmap = loadIconFromShell32(16, size);
|
||||
icon.addPixmap(pixmap, QIcon::Normal);
|
||||
}
|
||||
break;
|
||||
|
||||
case SP_DesktopIcon:
|
||||
for (int size = 16 ; size <= 32 ; size += 16) {
|
||||
pixmap = loadIconFromShell32(35, size);
|
||||
icon.addPixmap(pixmap, QIcon::Normal);
|
||||
}
|
||||
break;
|
||||
case SP_DriveCDIcon:
|
||||
case SP_DriveDVDIcon:
|
||||
for (int size = 16 ; size <= 32 ; size += 16) {
|
||||
pixmap = loadIconFromShell32(12, size);
|
||||
icon.addPixmap(pixmap, QIcon::Normal);
|
||||
}
|
||||
break;
|
||||
case SP_DriveNetIcon:
|
||||
for (int size = 16 ; size <= 32 ; size += 16) {
|
||||
pixmap = loadIconFromShell32(10, size);
|
||||
icon.addPixmap(pixmap, QIcon::Normal);
|
||||
}
|
||||
break;
|
||||
case SP_DriveHDIcon:
|
||||
for (int size = 16 ; size <= 32 ; size += 16) {
|
||||
pixmap = loadIconFromShell32(9, size);
|
||||
icon.addPixmap(pixmap, QIcon::Normal);
|
||||
}
|
||||
break;
|
||||
case SP_DriveFDIcon:
|
||||
for (int size = 16 ; size <= 32 ; size += 16) {
|
||||
pixmap = loadIconFromShell32(7, size);
|
||||
icon.addPixmap(pixmap, QIcon::Normal);
|
||||
}
|
||||
break;
|
||||
case SP_FileIcon:
|
||||
case SP_FileLinkIcon:
|
||||
for (int size = 16 ; size <= 32 ; size += 16) {
|
||||
QPixmap link;
|
||||
link = loadIconFromShell32(30, size);
|
||||
pixmap = loadIconFromShell32(1, size);
|
||||
if (!pixmap.isNull() && !link.isNull()) {
|
||||
QPainter painter(&pixmap);
|
||||
painter.drawPixmap(0, 0, size, size, link);
|
||||
case SP_DesktopIcon:
|
||||
case SP_ComputerIcon:
|
||||
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
|
||||
QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardIcon);
|
||||
for (int size = 16 ; size <= 32 ; size += 16) {
|
||||
pixmap = theme->standardPixmap(sp, QSizeF(size, size));
|
||||
icon.addPixmap(pixmap, QIcon::Normal);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SP_VistaShield:
|
||||
{
|
||||
if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
|
||||
&& (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)
|
||||
&& pSHGetStockIconInfo)
|
||||
{
|
||||
icon.addPixmap(proxy()->standardPixmap(SP_VistaShield, option, widget)); //fetches small icon
|
||||
QSHSTOCKICONINFO iconInfo; //append large icon
|
||||
memset(&iconInfo, 0, sizeof(iconInfo));
|
||||
iconInfo.cbSize = sizeof(iconInfo);
|
||||
if (pSHGetStockIconInfo(_SIID_SHIELD, _SHGFI_ICON | _SHGFI_LARGEICON, &iconInfo) == S_OK) {
|
||||
icon.addPixmap(qt_pixmapFromWinHICON(iconInfo.hIcon));
|
||||
DestroyIcon(iconInfo.hIcon);
|
||||
}
|
||||
case SP_DirIcon:
|
||||
case SP_DirLinkIcon:
|
||||
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
|
||||
QPlatformTheme::StandardPixmap spOff = static_cast<QPlatformTheme::StandardPixmap>(standardIcon);
|
||||
QPlatformTheme::StandardPixmap spOn = standardIcon == SP_DirIcon ? QPlatformTheme::DirOpenIcon :
|
||||
QPlatformTheme::DirLinkOpenIcon;
|
||||
for (int size = 16 ; size <= 32 ; size += 16) {
|
||||
QSizeF pixSize(size, size);
|
||||
pixmap = theme->standardPixmap(spOff, pixSize);
|
||||
icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off);
|
||||
pixmap = theme->standardPixmap(spOn, pixSize);
|
||||
icon.addPixmap(pixmap, QIcon::Normal, QIcon::On);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SP_VistaShield:
|
||||
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
|
||||
QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardIcon);
|
||||
pixmap = theme->standardPixmap(sp, QSizeF(32, 32));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user