Ticket #9401: 0001-Get-file-icons-on-linux.patch

File 0001-Get-file-icons-on-linux.patch, 8.5 KB (added by Francois Ferrand, 11 years ago)
  • src/interface/LocalListView.cpp

    From 919cbbf0123e129dcbde24afd09e6da40637f28f Mon Sep 17 00:00:00 2001
    From: Francois Ferrand <thetypz@gmail.com>
    Date: Mon, 3 Mar 2014 18:04:33 +0100
    Subject: [PATCH] Get file icons on linux.
    
    * Try to use Gnome VFS/mime database if available, otherwise fall back to
    g_file_query_info (which does not work for remote files).
    * Properly display local symlinks.
    ---
     src/interface/LocalListView.cpp   |   8 +-
     src/interface/systemimagelist.cpp | 158 +++++++++++++++++++++++++++++++-------
     2 files changed, 137 insertions(+), 29 deletions(-)
    
    diff --git a/src/interface/LocalListView.cpp b/src/interface/LocalListView.cpp
    index 2f4796f..4265e1f 100644
    a b int CLocalListView::OnGetItemImage(long item) const  
    487487                path = m_dir + data->name;
    488488        }
    489489
    490         icon = pThis->GetIconIndex(data->dir ? dir : file, path);
     490#if wxCHECK_VERSION(3,0,0)
     491        bool isSymLink = wxFileName::Exists(path, wxFILE_EXISTS_SYMLINK);
     492#else
     493        wxStructStat statbuf;
     494        bool isSymLink = wxLstat(path, &statbuf) == 0 && S_ISLNK(statbuf.st_mode);
     495#endif
     496        icon = pThis->GetIconIndex(data->dir ? dir : file, path, true, isSymLink);
    491497    }
    492498    return icon;
    493499}
  • src/interface/systemimagelist.cpp

    diff --git a/src/interface/systemimagelist.cpp b/src/interface/systemimagelist.cpp
    index 2480ac3..a175397 100644
    a b  
    1717#include "themeprovider.h"
    1818#include <wx/rawbmp.h>
    1919#endif
     20#ifdef __WXGTK__
     21#include <gio/gio.h>
     22#include <gtk/gtk.h>
     23#include <wx/dynlib.h>
     24#endif
    2025
    2126wxImageListEx::wxImageListEx()
    2227    : wxImageList()
    static void OverlaySymlink(wxBitmap& bmp)  
    6368{
    6469    // This is ugly, but apparently needed so that the data is _really_ in the right internal format
    6570    bmp = bmp.ConvertToImage();
    66     wxBitmap symlink = wxArtProvider::GetBitmap(_T("ART_SYMLINK"),  wxART_OTHER, wxSize(bmp.GetWidth(), bmp.GetHeight())).ConvertToImage();
     71
     72    wxBitmap symlink;
     73#ifdef __WXGTK__
     74    symlink = wxArtProvider::GetBitmap(_T("emblem-symbolic-link"), wxART_OTHER, wxSize(bmp.GetWidth(), bmp.GetHeight()));
     75#endif
     76    if (!symlink.IsOk())
     77        symlink = wxArtProvider::GetBitmap(_T("ART_SYMLINK"), wxART_OTHER, wxSize(bmp.GetWidth(), bmp.GetHeight()));
     78    symlink = symlink.ConvertToImage();
    6779
    6880    wxAlphaPixelData target(bmp);
    6981    wxAlphaPixelData source(symlink);
    bool CSystemImageList::CreateSystemImageList(int size)  
    119131#else
    120132    m_pImageList = new wxImageListEx(size, size);
    121133
    122     wxBitmap file = wxArtProvider::GetBitmap(_T("ART_FILE"),  wxART_OTHER, wxSize(size, size));
    123     wxBitmap folderclosed = wxArtProvider::GetBitmap(_T("ART_FOLDERCLOSED"),  wxART_OTHER, wxSize(size, size));
    124     wxBitmap folder = wxArtProvider::GetBitmap(_T("ART_FOLDER"),  wxART_OTHER, wxSize(size, size));
     134    wxBitmap file;
     135    wxBitmap folderclosed;
     136    wxBitmap folder;
     137#ifdef __WXGTK__
     138    file = wxArtProvider::GetBitmap(_T("unknown"),  wxART_OTHER, wxSize(size, size));
     139    folderclosed = wxArtProvider::GetBitmap(_T("folder"),  wxART_OTHER, wxSize(size, size));
     140    folder = wxArtProvider::GetBitmap(_T("folder-open"),  wxART_OTHER, wxSize(size, size));
     141#endif
     142    if (!file.IsOk())
     143        file = wxArtProvider::GetBitmap(_T("ART_FILE"),  wxART_OTHER, wxSize(size, size));
     144    if (!folderclosed.IsOk())
     145        folderclosed = wxArtProvider::GetBitmap(_T("ART_FOLDERCLOSED"),  wxART_OTHER, wxSize(size, size));
     146    if (!folder.IsOk())
     147        folder = wxArtProvider::GetBitmap(_T("ART_FOLDER"),  wxART_OTHER, wxSize(size, size));
     148
    125149    m_pImageList->Add(file);
    126150    m_pImageList->Add(folderclosed);
    127151    m_pImageList->Add(folder);
    CSystemImageList::~CSystemImageList()  
    150174    m_pImageList = 0;
    151175}
    152176
    153 #ifndef __WXMSW__
     177#ifdef __WXGTK__
     178
     179typedef enum {
     180    GNOME_ICON_LOOKUP_FLAGS_NONE = 0,
     181    GNOME_ICON_LOOKUP_FLAGS_EMBEDDING_TEXT = 1<<0,
     182    GNOME_ICON_LOOKUP_FLAGS_SHOW_SMALL_IMAGES_AS_THEMSELVES = 1<<1,
     183    GNOME_ICON_LOOKUP_FLAGS_ALLOW_SVG_AS_THEMSELVES = 1<<2
     184} GnomeIconLookupFlags;
     185typedef enum {
     186    GNOME_ICON_LOOKUP_RESULT_FLAGS_NONE = 0,
     187    GNOME_ICON_LOOKUP_RESULT_FLAGS_THUMBNAIL = 1<<0
     188} GnomeIconLookupResultFlags;
     189struct Gnome {
     190    Gnome():
     191        libGnomeVfs(_T("libgnomevfs-2.so")),
     192        libGnomeUi(_T("libgnomeui-2.so")),
     193        gnome_vfs_init((Gnome_Vfs_Init)libGnomeVfs.GetSymbol(_T("gnome_vfs_init"))),
     194        vfs_get_mime_type_for_name((Gnome_Vfs_Get_Mime_Type_For_Name)libGnomeVfs.GetSymbol(_T("gnome_vfs_get_mime_type_for_name"))),
     195        icon_lookup((Gnome_Icon_Lookup)libGnomeUi.GetSymbol(_T("gnome_icon_lookup")))
     196    {
     197        if (!gnome_vfs_init || !gnome_vfs_init())
     198            icon_lookup = NULL;
     199    }
     200
     201    typedef int (*Gnome_Vfs_Init)(void);
     202    typedef const char * (*Gnome_Vfs_Get_Mime_Type_For_Name)(const char *filename);
     203    typedef char * (*Gnome_Icon_Lookup)(GtkIconTheme *icon_theme,
     204                                        const char *file_uri,
     205                                        void/*GnomeThumbnailFactory*/ *thumbnail_factory,
     206                                        const char *custom_icon,
     207                                        void/*GnomeVFSFileInfo*/ *file_info,
     208                                        const char *mime_type,
     209                                        GnomeIconLookupFlags flags,
     210                                        GnomeIconLookupResultFlags *result);
     211    wxDynamicLibrary libGnomeVfs;
     212    wxDynamicLibrary libGnomeUi;
     213    Gnome_Vfs_Init gnome_vfs_init;
     214    Gnome_Vfs_Get_Mime_Type_For_Name vfs_get_mime_type_for_name;
     215    Gnome_Icon_Lookup icon_lookup;
     216} static gnome;
     217
     218wxBitmap GetFileIcon(const wxString & fileName, const wxString & ext)
     219{
     220    wxString iconName;
     221    if (gnome.icon_lookup)
     222    {
     223        GtkIconTheme *theme = gtk_icon_theme_get_default();
     224        const wxCharBuffer name = fileName.ToUTF8();
     225        const char * mimetype = gnome.vfs_get_mime_type_for_name(name.data());
     226        char * res = gnome.icon_lookup(theme, name.data(), NULL, NULL, NULL, mimetype, GNOME_ICON_LOOKUP_FLAGS_NONE, NULL);
     227        if (res)
     228            iconName = wxString::FromUTF8(res);
     229        g_free(res);
     230    }
     231    else
     232    {
     233        GFile * file = g_file_new_for_path(fileName.ToUTF8().data());
     234        GFileInfo * fileInfo = g_file_query_info(file, G_FILE_ATTRIBUTE_STANDARD_ICON, G_FILE_QUERY_INFO_NONE, NULL, NULL);
     235        GIcon * fileIcon = g_file_info_get_icon(fileInfo);
     236        const gchar * const * iconNames = g_themed_icon_get_names(G_THEMED_ICON(fileIcon));
     237        if (iconNames)
     238            iconName = wxString::FromUTF8(iconNames[0]);
     239        g_object_unref(fileIcon);
     240        g_object_unref(fileInfo);
     241        g_object_unref(file);
     242    }
     243
     244    wxSize iconSize = CThemeProvider::GetIconSize(iconSizeSmall);
     245    if (!iconName.IsNull() && iconName.GetChar(0) == '/')
     246        return wxImage(iconName).Rescale(iconSize.GetWidth(), iconSize.GetHeight());
     247    else
     248        return wxArtProvider::GetBitmap(iconName, wxART_OTHER, CThemeProvider::GetIconSize(iconSizeSmall));
     249}
     250#else
    154251// This function converts to the right size with the given background colour
    155252wxBitmap PrepareIcon(wxIcon icon, wxSize size)
    156253{
    wxBitmap PrepareIcon(wxIcon icon, wxSize size)  
    160257    bmp.CopyFromIcon(icon);
    161258    return bmp.ConvertToImage().Rescale(size.GetWidth(), size.GetHeight());
    162259}
     260
     261wxBitmap GetFileIcon(const wxString & /*fileName*/, const wxString & ext)
     262{
     263    wxFileType *pType = wxTheMimeTypesManager->GetFileTypeFromExtension(ext);
     264    if (!pType)
     265        return wxBitmap();
     266
     267    wxBitmap bmp;
     268    wxIconLocation loc;
     269    if (pType->GetIcon(&loc) && loc.IsOk())
     270    {
     271        wxLogNull nul;
     272        wxIcon newIcon(loc);
     273
     274        if (newIcon.Ok())
     275            bmp = PrepareIcon(newIcon, CThemeProvider::GetIconSize(iconSizeSmall));
     276    }
     277    delete pType;
     278
     279    return bmp;
     280}
    163281#endif
    164282
    165283int CSystemImageList::GetIconIndex(enum filetype type, const wxString& fileName /*=_T("")*/, bool physical /*=true*/, bool symlink /*=false*/)
    int CSystemImageList::GetIconIndex(enum filetype type, const wxString& fileName  
    216334            return cacheIter->second;
    217335    }
    218336
    219     wxFileType *pType = wxTheMimeTypesManager->GetFileTypeFromExtension(ext);
    220     if (!pType)
    221     {
    222         m_iconCache[ext] = icon;
    223         return icon;
    224     }
    225 
    226     wxIconLocation loc;
    227     if (pType->GetIcon(&loc) && loc.IsOk())
    228     {
    229         wxLogNull nul;
    230         wxIcon newIcon(loc);
    231 
    232         if (newIcon.Ok())
    233         {
    234             wxBitmap bmp = PrepareIcon(newIcon, CThemeProvider::GetIconSize(iconSizeSmall));
    235             if (symlink)
    236                 OverlaySymlink(bmp);
    237             int index = m_pImageList->Add(bmp);
    238             if (index > 0)
    239                 icon = index;
    240         }
     337    wxBitmap bmp = GetFileIcon(fileName, ext);
     338    if (bmp.IsOk()) {
     339        if (symlink)
     340            OverlaySymlink(bmp);
     341        int index = m_pImageList->Add(bmp);
     342        if (index > 0)
     343            icon = index;
    241344    }
    242     delete pType;
    243345
    244346    if (symlink)
    245347        m_iconCache[ext] = icon;