From 46685f755b01288fd53c4483cb97a22c426a57f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Mon, 29 Apr 2013 12:58:23 +0100 Subject: Windows: Introduce QFileDialog::DontUseCustomDirectoryIcons Folders can have a custom icon, set by the user. Some system folders also have one, for example c:\windows\fonts. This option allows you to disable this behavior, you'll get the folder directory icon. As a side-effect, you'll get a very big performance improvement on removable/network media: 2 seconds vs 60 seconds on a SDCard with 10000 folders. Change-Id: Id55ea628186e0a6523585ec7a4ff622d6f5da505 Reviewed-by: Giuseppe D'Angelo --- src/plugins/platforms/cocoa/qcocoatheme.h | 4 +++- src/plugins/platforms/cocoa/qcocoatheme.mm | 4 +++- src/plugins/platforms/windows/qwindowstheme.cpp | 23 +++++++++++++++++++---- src/plugins/platforms/windows/qwindowstheme.h | 3 ++- 4 files changed, 27 insertions(+), 7 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h index cac059763d..e4237c9b3e 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.h +++ b/src/plugins/platforms/cocoa/qcocoatheme.h @@ -68,7 +68,9 @@ 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; + QPixmap fileIconPixmap(const QFileInfo &fileInfo, + const QSizeF &size, + QPlatformTheme::IconOptions options = 0) const; QVariant themeHint(ThemeHint hint) const; diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index 36d7a49746..31bbd63e36 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -249,8 +249,10 @@ QPixmap QCocoaTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const return QPlatformTheme::standardPixmap(sp, size); } -QPixmap QCocoaTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const +QPixmap QCocoaTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size, + QPlatformTheme::IconOptions iconOptions) const { + Q_UNUSED(iconOptions); QCocoaAutoReleasePool pool; NSImage *iconImage = [[NSWorkspace sharedWorkspace] iconForFile:QCFString::toNSString(fileInfo.canonicalFilePath())]; diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index 844e46eec5..2531dc681a 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -595,7 +595,8 @@ public: void operator delete (void *) {} }; -QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const +QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size, + QPlatformTheme::IconOptions iconOptions) const { /* We don't use the variable, but by storing it statically, we * ensure CoInitialize is only called once. */ @@ -604,6 +605,8 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s static QCache > dirIconEntryCache(1000); static QMutex mx; + static int defaultFolderIIcon = 0; + const bool useDefaultFolderIcon = iconOptions & QPlatformTheme::DontUseCustomDirectoryIcons; QPixmap pixmap; const QString filePath = QDir::toNativeSeparators(fileInfo.filePath()); @@ -612,7 +615,8 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s bool cacheableDirIcon = fileInfo.isDir() && !fileInfo.isRoot(); if (cacheableDirIcon) { QMutexLocker locker(&mx); - int iIcon = **dirIconEntryCache.object(filePath); + int iIcon = (useDefaultFolderIcon && defaultFolderIIcon) ? defaultFolderIIcon + : **dirIconEntryCache.object(filePath); if (iIcon) { QPixmapCache::find(dirIconPixmapCacheKey(iIcon, iconSize), pixmap); if (pixmap.isNull()) // Let's keep both caches in sync @@ -629,13 +633,24 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s #else iconSize|SHGFI_SYSICONINDEX; #endif // Q_OS_WINCE - unsigned long val = SHGetFileInfo((const wchar_t *)filePath.utf16(), 0, - &info, sizeof(SHFILEINFO), flags); + unsigned long val = 0; + if (cacheableDirIcon && useDefaultFolderIcon) { + flags |= SHGFI_USEFILEATTRIBUTES; + val = SHGetFileInfo(L"dummy", + FILE_ATTRIBUTE_DIRECTORY, + &info, sizeof(SHFILEINFO), flags); + } else { + val = SHGetFileInfo(reinterpret_cast(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) { + if (useDefaultFolderIcon && !defaultFolderIIcon) + defaultFolderIIcon = info.iIcon; + //using the unique icon index provided by windows save us from duplicate keys key = dirIconPixmapCacheKey(info.iIcon, iconSize); QPixmapCache::find(key, pixmap); diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h index bbd7f4623f..9346621d59 100644 --- a/src/plugins/platforms/windows/qwindowstheme.h +++ b/src/plugins/platforms/windows/qwindowstheme.h @@ -68,7 +68,8 @@ public: { return m_fonts[type]; } virtual QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const; - virtual QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size) const; + virtual QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size, + QPlatformTheme::IconOptions iconOptions = 0) const; void windowsThemeChanged(QWindow *window); -- cgit v1.2.3