diff options
author | Sergio Martins <sergio.martins@kdab.com> | 2013-05-29 11:04:55 (GMT) |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-09 13:29:47 (GMT) |
commit | 5bb495c9b8f64bc2cb435d62674f2b0fdfa5d764 (patch) | |
tree | 16a139b350ec7ded9e5ab8af5b0cbe8e06bab7c7 /src/gui | |
parent | 8d120435d7fce0e29b33900b7ddf81c4e9f0b50e (diff) | |
download | Qt-5bb495c9b8f64bc2cb435d62674f2b0fdfa5d764.zip Qt-5bb495c9b8f64bc2cb435d62674f2b0fdfa5d764.tar.gz Qt-5bb495c9b8f64bc2cb435d62674f2b0fdfa5d764.tar.bz2 |
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.
Unlike in Qt5, here we didn't add new methods to QFileIconProvider
do avoid introducing new symbols.
Change-Id: I0b98a180e53c9ee7d583f19b3917fcc9166cb3eb
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
(cherry picked from qtbase/46685f755b01288fd53c4483cb97a22c426a57f0)
(cherry picked from qtbase/149f3efc39bebbe8fceacf2553836f90d2e1c383)
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/dialogs/qfiledialog.cpp | 8 | ||||
-rw-r--r-- | src/gui/dialogs/qfiledialog.h | 15 | ||||
-rw-r--r-- | src/gui/itemviews/qfileiconprovider.cpp | 37 | ||||
-rw-r--r-- | src/gui/itemviews/qfileiconprovider.h | 1 | ||||
-rw-r--r-- | src/gui/itemviews/qfileiconprovider_p.h | 2 |
5 files changed, 52 insertions, 11 deletions
diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index 7df8197..3518780 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -58,6 +58,7 @@ #include <qdebug.h> #include <qapplication.h> #include <qstylepainter.h> +#include <itemviews/qfileiconprovider_p.h> #if !defined(Q_WS_WINCE) && !defined(Q_OS_SYMBIAN) #include "ui_qfiledialog.h" #else @@ -240,6 +241,10 @@ Q_GUI_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook static functions will always be an application modal dialog. If you want to use sheets, use QFileDialog::open() instead. + \value DontUseCustomDirectoryIcons Always use the default directory icon. + Some platforms allow the user to set a different icon. Custom icon lookup + cause a big performance impact over network or removable drives. Setting this + will affect the behavior of the icon provider. This enum value was added in Qt 4.8.6. */ /*! @@ -685,6 +690,9 @@ void QFileDialog::setOptions(Options options) if (changed & ShowDirsOnly) setFilter((options & ShowDirsOnly) ? filter() & ~QDir::Files : filter() | QDir::Files); + + if (changed & DontUseCustomDirectoryIcons) + iconProvider()->d_ptr->setUseCustomDirectoryIcons(!(options & DontUseCustomDirectoryIcons)); } QFileDialog::Options QFileDialog::options() const diff --git a/src/gui/dialogs/qfiledialog.h b/src/gui/dialogs/qfiledialog.h index 66c02c4..817ee8d 100644 --- a/src/gui/dialogs/qfiledialog.h +++ b/src/gui/dialogs/qfiledialog.h @@ -88,13 +88,14 @@ public: // ### Rename to FileDialogOption and FileDialogOptions for Qt 5.0 enum Option { - ShowDirsOnly = 0x00000001, - DontResolveSymlinks = 0x00000002, - DontConfirmOverwrite = 0x00000004, - DontUseSheet = 0x00000008, - DontUseNativeDialog = 0x00000010, - ReadOnly = 0x00000020, - HideNameFilterDetails = 0x00000040 + ShowDirsOnly = 0x00000001, + DontResolveSymlinks = 0x00000002, + DontConfirmOverwrite = 0x00000004, + DontUseSheet = 0x00000008, + DontUseNativeDialog = 0x00000010, + ReadOnly = 0x00000020, + HideNameFilterDetails = 0x00000040, + DontUseCustomDirectoryIcons = 0x00000080 }; Q_DECLARE_FLAGS(Options, Option) diff --git a/src/gui/itemviews/qfileiconprovider.cpp b/src/gui/itemviews/qfileiconprovider.cpp index f1ad7e0..9fd9e99 100644 --- a/src/gui/itemviews/qfileiconprovider.cpp +++ b/src/gui/itemviews/qfileiconprovider.cpp @@ -89,10 +89,15 @@ QT_BEGIN_NAMESPACE */ QFileIconProviderPrivate::QFileIconProviderPrivate() : - homePath(QDir::home().absolutePath()) + homePath(QDir::home().absolutePath()), useCustomDirectoryIcons(true) { } +void QFileIconProviderPrivate::setUseCustomDirectoryIcons(bool enable) +{ + useCustomDirectoryIcons = enable; +} + QIcon QFileIconProviderPrivate::getIcon(QStyle::StandardPixmap name) const { switch (name) { @@ -213,6 +218,8 @@ static bool isCacheable(const QFileInfo &fi) QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const { QIcon retIcon; + static int defaultFolderIIcon = -1; + QString key; QPixmap pixmap; // If it's a file, non-{exe,lnk,ico} then we might have it cached already @@ -228,6 +235,19 @@ QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const } } + const bool cacheableDirIcon = fileInfo.isDir() && !fileInfo.isRoot(); + if (!useCustomDirectoryIcons && defaultFolderIIcon >= 0 && cacheableDirIcon) { + // We already have the default folder icon, just return it + key = QString::fromLatin1("qt_dir_%1").arg(defaultFolderIIcon); + QPixmapCache::find(key, pixmap); + if (!pixmap.isNull()) { + retIcon.addPixmap(pixmap); + if (QPixmapCache::find(key + QLatin1Char('l'), pixmap)) + retIcon.addPixmap(pixmap); + 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); @@ -237,19 +257,28 @@ QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const unsigned long val = 0; //Get the small icon - const unsigned int flags = + unsigned int flags = #ifndef Q_OS_WINCE SHGFI_ICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS|SHGFI_OVERLAYINDEX; #else SHGFI_SYSICONINDEX; #endif - val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), - 0, &info, sizeof(SHFILEINFO), flags | SHGFI_SMALLICON); + if (cacheableDirIcon && !useCustomDirectoryIcons) { + flags |= SHGFI_USEFILEATTRIBUTES; + val = SHGetFileInfo(L"dummy", + FILE_ATTRIBUTE_DIRECTORY, &info, + sizeof(SHFILEINFO), flags | SHGFI_SMALLICON); + } else { + val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), + 0, &info, sizeof(SHFILEINFO), flags | SHGFI_SMALLICON); + } // Even if GetFileInfo returns a valid result, hIcon can be empty in some cases if (val && info.hIcon) { if (fileInfo.isDir() && !fileInfo.isRoot()) { + if (!useCustomDirectoryIcons && defaultFolderIIcon < 0) + defaultFolderIIcon = info.iIcon; //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); diff --git a/src/gui/itemviews/qfileiconprovider.h b/src/gui/itemviews/qfileiconprovider.h index 2ae4e81..3c98562 100644 --- a/src/gui/itemviews/qfileiconprovider.h +++ b/src/gui/itemviews/qfileiconprovider.h @@ -70,6 +70,7 @@ private: Q_DECLARE_PRIVATE(QFileIconProvider) QScopedPointer<QFileIconProviderPrivate> d_ptr; Q_DISABLE_COPY(QFileIconProvider) + friend class QFileDialog; }; #endif // QT_NO_FILEICONPROVIDER diff --git a/src/gui/itemviews/qfileiconprovider_p.h b/src/gui/itemviews/qfileiconprovider_p.h index 704418b..a44ae51 100644 --- a/src/gui/itemviews/qfileiconprovider_p.h +++ b/src/gui/itemviews/qfileiconprovider_p.h @@ -57,6 +57,7 @@ class QFileIconProviderPrivate public: QFileIconProviderPrivate(); + void setUseCustomDirectoryIcons(bool enable); QIcon getIcon(QStyle::StandardPixmap name) const; #ifdef Q_WS_WIN QIcon getWinIcon(const QFileInfo &fi) const; @@ -67,6 +68,7 @@ public: const QString homePath; private: + bool useCustomDirectoryIcons; mutable QIcon file; mutable QIcon fileLink; mutable QIcon directory; |