diff options
-rw-r--r-- | src/gui/kernel/qplatformtheme.cpp | 19 | ||||
-rw-r--r-- | src/gui/kernel/qplatformtheme.h | 84 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoatheme.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoatheme.mm | 144 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qtwindows_additional.h | 15 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowscontext.cpp | 5 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowscontext.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowstheme.cpp | 230 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowstheme.h | 3 | ||||
-rw-r--r-- | src/widgets/itemviews/qfileiconprovider.cpp | 194 | ||||
-rw-r--r-- | src/widgets/styles/qcommonstyle.cpp | 123 | ||||
-rw-r--r-- | src/widgets/styles/qmacstyle_mac.mm | 1 | ||||
-rw-r--r-- | src/widgets/styles/qstyle.cpp | 1 | ||||
-rw-r--r-- | src/widgets/styles/qstyle.h | 1 | ||||
-rw-r--r-- | src/widgets/styles/qwindowsstyle.cpp | 260 |
15 files changed, 621 insertions, 464 deletions
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp index b91d3d0281..2e896eecf4 100644 --- a/src/gui/kernel/qplatformtheme.cpp +++ b/src/gui/kernel/qplatformtheme.cpp @@ -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(); } diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h index 398339255c..25453e792f 100644 --- a/src/gui/kernel/qplatformtheme.h +++ b/src/gui/kernel/qplatformtheme.h @@ -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); }; diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h index a747a82d09..0ff160957f 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.h +++ b/src/plugins/platforms/cocoa/qcocoatheme.h @@ -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; diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index ddb550dd5f..967d65faec 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -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; } diff --git a/src/plugins/platforms/windows/qtwindows_additional.h b/src/plugins/platforms/windows/qtwindows_additional.h index f5ea2cf6bf..3566367e41 100644 --- a/src/plugins/platforms/windows/qtwindows_additional.h +++ b/src/plugins/platforms/windows/qtwindows_additional.h @@ -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 diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 98c17deba9..3d4871d7a2 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -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; diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index 450d6c8f4b..78cd104fbe 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -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 diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index 7b3ffc633f..748ba09a90 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -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 diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h index 7e885b8f3e..89ef527e76 100644 --- a/src/plugins/platforms/windows/qwindowstheme.h +++ b/src/plugins/platforms/windows/qwindowstheme.h @@ -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; diff --git a/src/widgets/itemviews/qfileiconprovider.cpp b/src/widgets/itemviews/qfileiconprovider.cpp index 99a7c1c929..70750c6006 100644 --- a/src/widgets/itemviews/qfileiconprovider.cpp +++ b/src/widgets/itemviews/qfileiconprovider.cpp @@ -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,162 +224,50 @@ 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); - SHFILEINFO info; - unsigned long val = 0; + QList<int> sizes = theme->themeHint(QPlatformTheme::IconPixmapSizes).value<QList<int> >(); + if (sizes.isEmpty()) + return retIcon; - //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 + const QString fileExtension = fi.suffix().toUpper(); + const QString keyBase = QLatin1String("qt_.") + fi.suffix().toUpper(); - // 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); - } - else { - qWarning("QFileIconProviderPrivate::getWinIcon() no large icon found"); + if (cacheable) + QPixmapCache::insert(keyBase + QString::number(size), pixmap); } - 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 /*! @@ -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); diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 50fceab694..d4e4ea22d0 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -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; } - 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); + + 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; } - if (icon) { - qt_mac_constructQIconFromIconRef(icon, overlayIcon, &retIcon, standardIcon); - ReleaseIconRef(icon); - } - if (overlayIcon) - ReleaseIconRef(overlayIcon); - return retIcon; + + default: + break; } } // if (QApplication::desktopSettingsAware()) -#endif // Q_WS_MAC +#endif // Q_OS_MAC switch (standardIcon) { #ifndef QT_NO_IMAGEFORMAT_PNG diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 77656f9ed5..20791d6625 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -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 diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index 77c647e136..f0d1d2319c 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -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. diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h index 539424639b..48491b3e3e 100644 --- a/src/widgets/styles/qstyle.h +++ b/src/widgets/styles/qstyle.h @@ -731,6 +731,7 @@ public: SP_DirOpenIcon, SP_DirClosedIcon, SP_DirLinkIcon, + SP_DirLinkOpenIcon, SP_FileIcon, SP_FileLinkIcon, SP_ToolBarHorizontalExtensionButton, diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index ee13852813..714898e809 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -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_VistaShield: + 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: - { - 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()); } 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; } |