summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows/qwindowstheme.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/windows/qwindowstheme.cpp')
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp168
1 files changed, 81 insertions, 87 deletions
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index ff4cfe63cb..841464391d 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -49,17 +49,12 @@
#include "qwindowsintegration.h"
#include "qt_windows.h"
#include "qwindowsfontdatabase.h"
-#ifdef Q_OS_WINCE
-# include "qplatformfunctions_wince.h"
-# include "winuser.h"
-#else
-# include <commctrl.h>
-# include <objbase.h>
-# ifndef Q_CC_MINGW
-# include <commoncontrols.h>
-# endif
-# include <shellapi.h>
+#include <commctrl.h>
+#include <objbase.h>
+#ifndef Q_CC_MINGW
+# include <commoncontrols.h>
#endif
+#include <shellapi.h>
#include <QtCore/QVariant>
#include <QtCore/QCoreApplication>
@@ -73,6 +68,7 @@
#include <QtGui/QPainter>
#include <QtGui/QPixmapCache>
#include <qpa/qwindowsysteminterface.h>
+#include <QtPlatformSupport/private/qabstractfileiconengine_p.h>
#include <private/qhighdpiscaling_p.h>
#include <private/qsystemlibrary_p.h>
@@ -128,7 +124,6 @@ static inline QColor getSysColor(int index)
return COLORREFToQColor(GetSysColor(index));
}
-#ifndef QT_NO_WINCE_SHELLSDK
// QTBUG-48823/Windows 10: SHGetFileInfo() (as called by item views on file system
// models has been observed to trigger a WM_PAINT on the mainwindow. Suppress the
// behavior by running it in a thread.
@@ -170,7 +165,6 @@ static bool shGetFileInfoBackground(QWindowsThreadPoolRunner &r,
}
return result;
}
-#endif // !QT_NO_WINCE_SHELLSDK
// from QStyle::standardPalette
static inline QPalette standardPalette()
@@ -281,14 +275,9 @@ static inline QPalette menuPalette(const QPalette &systemPalette)
result.setColor(QPalette::Active, QPalette::ButtonText, menuTextColor);
result.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
result.setColor(QPalette::Disabled, QPalette::Text, disabled);
-#ifndef Q_OS_WINCE
const bool isFlat = booleanSystemParametersInfo(SPI_GETFLATMENU, false);
result.setColor(QPalette::Disabled, QPalette::Highlight,
getSysColor(isFlat ? COLOR_MENUHILIGHT : COLOR_HIGHLIGHT));
-#else
- result.setColor(QPalette::Disabled, QPalette::Highlight,
- getSysColor(COLOR_HIGHLIGHT));
-#endif
result.setColor(QPalette::Disabled, QPalette::HighlightedText, disabled);
result.setColor(QPalette::Disabled, QPalette::Button,
result.color(QPalette::Active, QPalette::Button));
@@ -314,11 +303,7 @@ static inline QPalette *menuBarPalette(const QPalette &menuPalette)
QPalette *result = 0;
if (booleanSystemParametersInfo(SPI_GETFLATMENU, false)) {
result = new QPalette(menuPalette);
-#ifndef Q_OS_WINCE
const QColor menubar(getSysColor(COLOR_MENUBAR));
-#else
- const QColor menubar(getSysColor(COLOR_MENU));
-#endif
result->setColor(QPalette::Active, QPalette::Button, menubar);
result->setColor(QPalette::Disabled, QPalette::Button, menubar);
result->setColor(QPalette::Inactive, QPalette::Button, menubar);
@@ -330,6 +315,7 @@ const char *QWindowsTheme::name = "windows";
QWindowsTheme *QWindowsTheme::m_instance = 0;
QWindowsTheme::QWindowsTheme()
+ : m_threadPoolRunner(new QWindowsThreadPoolRunner)
{
m_instance = this;
std::fill(m_fonts, m_fonts + NFonts, static_cast<QFont *>(0));
@@ -364,7 +350,7 @@ static inline QStringList styleNames()
static inline int uiEffects()
{
- int result = 0;
+ int result = QPlatformTheme::HoverEffect;
if (booleanSystemParametersInfo(SPI_GETUIEFFECTS, false))
result |= QPlatformTheme::GeneralUiEffect;
if (booleanSystemParametersInfo(SPI_GETMENUANIMATION, false))
@@ -389,12 +375,10 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const
return QVariant(iconThemeSearchPaths());
case StyleNames:
return QVariant(styleNames());
-#ifndef Q_OS_WINCE
case TextCursorWidth:
return QVariant(int(dWordSystemParametersInfo(SPI_GETCARETWIDTH, 1u)));
case DropShadow:
return QVariant(booleanSystemParametersInfo(SPI_GETDROPSHADOW, false));
-#endif // !Q_OS_WINCE
case MaximumScrollBarDragDistance:
return QVariant(qRound(qreal(QWindowsContext::instance()->defaultDPI()) * 1.375));
case KeyboardScheme:
@@ -402,7 +386,7 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const
case UiEffects:
return QVariant(uiEffects());
case IconPixmapSizes:
- return m_fileIconSizes;
+ return QVariant::fromValue(m_fileIconSizes);
case DialogSnapToDefaultButton:
return QVariant(booleanSystemParametersInfo(SPI_GETSNAPTODEFBUTTON, false));
case ContextMenuOnMouseRelease:
@@ -445,7 +429,6 @@ void QWindowsTheme::clearFonts()
void QWindowsTheme::refreshFonts()
{
-#ifndef Q_OS_WINCE // ALL THIS FUNCTIONALITY IS MISSING ON WINCE
clearFonts();
if (!QGuiApplication::desktopSettingsAware())
return;
@@ -474,7 +457,6 @@ void QWindowsTheme::refreshFonts()
m_fonts[DockWidgetTitleFont] = new QFont(titleFont);
m_fonts[ItemViewFont] = new QFont(iconTitleFont);
m_fonts[FixedFont] = new QFont(fixedFont);
-#endif // !Q_OS_WINCE
}
enum FileIconSize {
@@ -512,15 +494,14 @@ void QWindowsTheme::refreshIconPixmapSizes()
fileIconSizes[ExtraLargeFileIcon] =
fileIconSizes[LargeFileIcon] + fileIconSizes[LargeFileIcon] / 2;
fileIconSizes[JumboFileIcon] = 8 * fileIconSizes[LargeFileIcon]; // empirical, has not been observed to work
- QList<int> sizes;
- sizes << fileIconSizes[SmallFileIcon] << fileIconSizes[LargeFileIcon];
+
#ifdef USE_IIMAGELIST
- sizes << fileIconSizes[ExtraLargeFileIcon]; // sHIL_EXTRALARGE
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA)
- sizes << fileIconSizes[JumboFileIcon]; // SHIL_JUMBO
+ int *availEnd = fileIconSizes + JumboFileIcon + 1;
+#else
+ int *availEnd = fileIconSizes + LargeFileIcon + 1;
#endif // USE_IIMAGELIST
- qCDebug(lcQpaWindows) << __FUNCTION__ << sizes;
- m_fileIconSizes = QVariant::fromValue(sizes);
+ m_fileIconSizes = QAbstractFileIconEngine::toSizeList(fileIconSizes, availEnd);
+ qCDebug(lcQpaWindows) << __FUNCTION__ << m_fileIconSizes;
}
// Defined in qpixmap_win.cpp
@@ -528,12 +509,7 @@ 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) {
+ if (const HMODULE hmod = QSystemLibrary::load(L"shell32")) {
HICON iconHandle =
static_cast<HICON>(LoadImage(hmod, MAKEINTRESOURCE(resourceId),
IMAGE_ICON, int(size.width()), int(size.height()), 0));
@@ -549,7 +525,7 @@ static QPixmap loadIconFromShell32(int resourceId, QSizeF size)
QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSize) const
{
int resourceId = -1;
- int stockId = SIID_INVALID;
+ SHSTOCKICONID stockId = SIID_INVALID;
UINT stockFlags = 0;
LPCTSTR iconName = 0;
switch (sp) {
@@ -575,14 +551,14 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz
break;
case FileLinkIcon:
stockFlags = SHGSI_LINKOVERLAY;
- // Fall through
+ Q_FALLTHROUGH();
case FileIcon:
stockId = SIID_DOCNOASSOC;
resourceId = 1;
break;
case DirLinkIcon:
stockFlags = SHGSI_LINKOVERLAY;
- // Fall through
+ Q_FALLTHROUGH();
case DirClosedIcon:
case DirIcon:
stockId = SIID_FOLDER;
@@ -596,7 +572,7 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz
break;
case DirLinkOpenIcon:
stockFlags = SHGSI_LINKOVERLAY;
- // Fall through
+ Q_FALLTHROUGH();
case DirOpenIcon:
stockId = SIID_FOLDEROPEN;
resourceId = 5;
@@ -612,7 +588,6 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz
stockId = SIID_RECYCLER;
resourceId = 191;
break;
-#ifndef Q_OS_WINCE
case MessageBoxInformation:
stockId = SIID_INFO;
iconName = IDI_INFORMATION;
@@ -632,29 +607,22 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz
case VistaShield:
stockId = SIID_SHIELD;
break;
-#endif
default:
break;
}
-#ifndef Q_OS_WINCE
if (stockId != SIID_INVALID) {
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
- && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)
- && QWindowsContext::shell32dll.sHGetStockIconInfo) {
- QPixmap pixmap;
- SHSTOCKICONINFO iconInfo;
- memset(&iconInfo, 0, sizeof(iconInfo));
- iconInfo.cbSize = sizeof(iconInfo);
- stockFlags |= (pixmapSize.width() > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON);
- if (QWindowsContext::shell32dll.sHGetStockIconInfo(stockId, SHGFI_ICON | stockFlags, &iconInfo) == S_OK) {
- pixmap = qt_pixmapFromWinHICON(iconInfo.hIcon);
- DestroyIcon(iconInfo.hIcon);
- return pixmap;
- }
+ QPixmap pixmap;
+ SHSTOCKICONINFO iconInfo;
+ memset(&iconInfo, 0, sizeof(iconInfo));
+ iconInfo.cbSize = sizeof(iconInfo);
+ stockFlags |= (pixmapSize.width() > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON);
+ if (SHGetStockIconInfo(stockId, SHGFI_ICON | stockFlags, &iconInfo) == S_OK) {
+ pixmap = qt_pixmapFromWinHICON(iconInfo.hIcon);
+ DestroyIcon(iconInfo.hIcon);
+ return pixmap;
}
}
-#endif
if (resourceId != -1) {
QPixmap pixmap = loadIconFromShell32(resourceId, pixmapSize);
@@ -729,14 +697,8 @@ static QPixmap pixmapFromShellImageList(int iImageList, const SHFILEINFO &info)
// For MinGW:
static const IID iID_IImageList = {0x46eb5926, 0x582e, 0x4017, {0x9f, 0xdf, 0xe8, 0x99, 0x8d, 0xaa, 0x9, 0x50}};
- if (!QWindowsContext::shell32dll.sHGetImageList)
- return result;
- if (iImageList == sHIL_JUMBO && QSysInfo::WindowsVersion < QSysInfo::WV_VISTA)
- return result;
-
IImageList *imageList = 0;
- HRESULT hr = QWindowsContext::shell32dll.sHGetImageList(iImageList, iID_IImageList,
- reinterpret_cast<void **>(&imageList));
+ HRESULT hr = SHGetImageList(iImageList, iID_IImageList, reinterpret_cast<void **>(&imageList));
if (hr != S_OK)
return result;
HICON hIcon;
@@ -753,8 +715,46 @@ static QPixmap pixmapFromShellImageList(int iImageList, const SHFILEINFO &info)
return result;
}
-QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size,
- QPlatformTheme::IconOptions iconOptions) const
+class QWindowsFileIconEngine : public QAbstractFileIconEngine
+{
+public:
+ explicit QWindowsFileIconEngine(const QFileInfo &info,
+ QPlatformTheme::IconOptions opts,
+ const QSharedPointer<QWindowsThreadPoolRunner> &runner) :
+ QAbstractFileIconEngine(info, opts), m_threadPoolRunner(runner) {}
+
+ QList<QSize> availableSizes(QIcon::Mode = QIcon::Normal, QIcon::State = QIcon::Off) const override
+ { return QWindowsTheme::instance()->availableFileIconSizes(); }
+
+protected:
+ QString cacheKey() const override;
+ QPixmap filePixmap(const QSize &size, QIcon::Mode mode, QIcon::State) override;
+
+private:
+ const QSharedPointer<QWindowsThreadPoolRunner> m_threadPoolRunner;
+};
+
+QString QWindowsFileIconEngine::cacheKey() const
+{
+ // Cache directories unless custom or drives, which have custom icons depending on type
+ if ((options() & QPlatformTheme::DontUseCustomDirectoryIcons) && fileInfo().isDir() && !fileInfo().isRoot())
+ return QStringLiteral("qt_/directory/");
+ if (!fileInfo().isFile())
+ return QString();
+ // Return "" for .exe, .lnk and .ico extensions.
+ // It is faster to just look at the file extensions;
+ // avoiding slow QFileInfo::isExecutable() (QTBUG-13182)
+ const QString &suffix = fileInfo().suffix();
+ if (!suffix.compare(QLatin1String("exe"), Qt::CaseInsensitive)
+ || !suffix.compare(QLatin1String("lnk"), Qt::CaseInsensitive)
+ || !suffix.compare(QLatin1String("ico"), Qt::CaseInsensitive)) {
+ return QString();
+ }
+ return QLatin1String("qt_.")
+ + (suffix.isEmpty() ? fileInfo().fileName() : suffix.toUpper()); // handle "Makefile" ;)
+}
+
+QPixmap QWindowsFileIconEngine::filePixmap(const QSize &size, QIcon::Mode, QIcon::State)
{
/* We don't use the variable, but by storing it statically, we
* ensure CoInitialize is only called once. */
@@ -764,10 +764,10 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
static QCache<QString, FakePointer<int> > dirIconEntryCache(1000);
static QMutex mx;
static int defaultFolderIIcon = -1;
- const bool useDefaultFolderIcon = iconOptions & QPlatformTheme::DontUseCustomDirectoryIcons;
+ const bool useDefaultFolderIcon = options() & QPlatformTheme::DontUseCustomDirectoryIcons;
QPixmap pixmap;
- const QString filePath = QDir::toNativeSeparators(fileInfo.filePath());
+ const QString filePath = QDir::toNativeSeparators(fileInfo().filePath());
const int width = int(size.width());
const int iconSize = width > fileIconSizes[SmallFileIcon] ? SHGFI_LARGEICON : SHGFI_SMALLICON;
const int requestedImageListSize =
@@ -778,7 +778,7 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
#else
0;
#endif // !USE_IIMAGELIST
- bool cacheableDirIcon = fileInfo.isDir() && !fileInfo.isRoot();
+ bool cacheableDirIcon = fileInfo().isDir() && !fileInfo().isRoot();
if (cacheableDirIcon) {
QMutexLocker locker(&mx);
int iIcon = (useDefaultFolderIcon && defaultFolderIIcon >= 0) ? defaultFolderIIcon
@@ -794,22 +794,13 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
SHFILEINFO info;
const unsigned int flags =
-#ifndef Q_OS_WINCE
SHGFI_ICON|iconSize|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS|SHGFI_OVERLAYINDEX;
-#else
- iconSize|SHGFI_SYSICONINDEX;
-#endif // Q_OS_WINCE
-
-#if !defined(QT_NO_WINCE_SHELLSDK)
const bool val = cacheableDirIcon && useDefaultFolderIcon
- ? shGetFileInfoBackground(m_threadPoolRunner, L"dummy", FILE_ATTRIBUTE_DIRECTORY,
+ ? shGetFileInfoBackground(*m_threadPoolRunner.data(), L"dummy", FILE_ATTRIBUTE_DIRECTORY,
&info, flags | SHGFI_USEFILEATTRIBUTES)
- : shGetFileInfoBackground(m_threadPoolRunner, reinterpret_cast<const wchar_t *>(filePath.utf16()), 0,
+ : shGetFileInfoBackground(*m_threadPoolRunner.data(), reinterpret_cast<const wchar_t *>(filePath.utf16()), 0,
&info, flags);
-#else
- const bool val = false;
-#endif // !QT_NO_WINCE_SHELLSDK
// Even if GetFileInfo returns a valid result, hIcon can be empty in some cases
if (val && info.hIcon) {
@@ -848,9 +839,12 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
DestroyIcon(info.hIcon);
}
- if (!pixmap.isNull())
- return pixmap;
- return QPlatformTheme::fileIconPixmap(fileInfo, size);
+ return pixmap;
+}
+
+QIcon QWindowsTheme::fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions) const
+{
+ return QIcon(new QWindowsFileIconEngine(fileInfo, iconOptions, m_threadPoolRunner));
}
QT_END_NAMESPACE