]> granicus.if.org Git - transmission/commitdiff
(trunk, qt) #5483: use native windows icons, more win portability goodness from mikedld
authorJordan Lee <jordan@transmissionbt.com>
Sun, 8 Sep 2013 18:53:11 +0000 (18:53 +0000)
committerJordan Lee <jordan@transmissionbt.com>
Sun, 8 Sep 2013 18:53:11 +0000 (18:53 +0000)
qt/utils.cc
qt/utils.h

index 9cbc81f852315867be6dc1ef35cf4fc33fad6266..56352bd787a711150b91c6455f0152540eec4972 100644 (file)
 
 #include <iostream>
 
+#ifdef WIN32
+ #include <windows.h>
+ #include <shellapi.h>
+#endif
+
 #include <QApplication>
 #include <QDataStream>
 #include <QFile>
@@ -19,6 +24,7 @@
 #include <QFileInfo>
 #include <QInputDialog>
 #include <QObject>
+#include <QPixmapCache>
 #include <QSet>
 #include <QStyle>
 
 ****
 ***/
 
+#if defined(WIN32) && QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+// Should be in QtWinExtras soon, but for now let's import it manually
+extern QPixmap qt_pixmapFromWinHICON(HICON icon);
+#endif
+
 QString
 Utils :: remoteFileChooser( QWidget * parent, const QString& title, const QString& myPath, bool dir, bool local )
 {
@@ -55,9 +66,64 @@ Utils :: toStderr( const QString& str )
     std::cerr << qPrintable(str) << std::endl;
 }
 
-const QIcon&
+#ifdef WIN32
+namespace
+{
+  void
+  addAssociatedFileIcon (const QFileInfo& fileInfo, UINT iconSize, QIcon& icon)
+  {
+    QString const pixmapCacheKey = QLatin1String ("tr_file_ext_") +
+      QString::number (iconSize) + "_" + fileInfo.suffix ();
+    QPixmap pixmap;
+    if (!QPixmapCache::find (pixmapCacheKey, &pixmap))
+      {
+        const QString filename = fileInfo.fileName ();
+
+        SHFILEINFO shellFileInfo;
+        if (::SHGetFileInfoW ((const wchar_t*) filename.utf16 (), FILE_ATTRIBUTE_NORMAL,
+                              &shellFileInfo, sizeof(shellFileInfo),
+                              SHGFI_ICON | iconSize | SHGFI_USEFILEATTRIBUTES) != 0)
+          {
+            if (shellFileInfo.hIcon != NULL)
+              {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+                pixmap = qt_pixmapFromWinHICON (shellFileInfo.hIcon);
+#else
+                pixmap = QPixmap::fromWinHICON (shellFileInfo.hIcon);
+#endif
+                ::DestroyIcon (shellFileInfo.hIcon);
+              }
+          }
+
+        QPixmapCache::insert (pixmapCacheKey, pixmap);
+      }
+
+    if (!pixmap.isNull ())
+      icon.addPixmap (pixmap);
+  }
+} // namespace
+#endif
+
+QIcon
 Utils :: guessMimeIcon( const QString& filename )
 {
+#ifdef WIN32
+  QIcon icon;
+
+  if (!filename.isEmpty ())
+    {
+      const QFileInfo fileInfo (filename);
+
+      addAssociatedFileIcon (fileInfo, SHGFI_SMALLICON, icon);
+      addAssociatedFileIcon (fileInfo, 0, icon);
+      addAssociatedFileIcon (fileInfo, SHGFI_LARGEICON, icon);
+    }
+
+  if (icon.isNull ())
+    icon = QApplication::style ()->standardIcon (QStyle::SP_FileIcon);
+
+  return icon;
+#else
     enum { DISK, DOCUMENT, PICTURE, VIDEO, ARCHIVE, AUDIO, APP, TYPE_COUNT };
     static QIcon fallback;
     static QIcon fileIcons[TYPE_COUNT];
@@ -116,6 +182,7 @@ Utils :: guessMimeIcon( const QString& filename )
             return fileIcons[i];
 
     return fallback;
+#endif
 }
 
 bool
index 6bf739aa2800bcb89d3756d35ceee94833830f12..83d8d9d3b1b1a80d0e89576bb08c99ffb1dd591f 100644 (file)
@@ -31,7 +31,7 @@ class Utils: public QObject
 
     public:
         static QString remoteFileChooser( QWidget * parent, const QString& title, const QString& myPath, bool dir, bool local );
-        static const QIcon& guessMimeIcon( const QString& filename );
+        static QIcon guessMimeIcon( const QString& filename );
         // Test if string is UTF-8 or not
         static bool isValidUtf8 ( const char *s );