Ticket #9401: 0001-Get-file-icons-on-linux.patch
File 0001-Get-file-icons-on-linux.patch, 8.5 KB (added by , 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 487 487 path = m_dir + data->name; 488 488 } 489 489 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); 491 497 } 492 498 return icon; 493 499 } -
src/interface/systemimagelist.cpp
diff --git a/src/interface/systemimagelist.cpp b/src/interface/systemimagelist.cpp index 2480ac3..a175397 100644
a b 17 17 #include "themeprovider.h" 18 18 #include <wx/rawbmp.h> 19 19 #endif 20 #ifdef __WXGTK__ 21 #include <gio/gio.h> 22 #include <gtk/gtk.h> 23 #include <wx/dynlib.h> 24 #endif 20 25 21 26 wxImageListEx::wxImageListEx() 22 27 : wxImageList() … … static void OverlaySymlink(wxBitmap& bmp) 63 68 { 64 69 // This is ugly, but apparently needed so that the data is _really_ in the right internal format 65 70 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(); 67 79 68 80 wxAlphaPixelData target(bmp); 69 81 wxAlphaPixelData source(symlink); … … bool CSystemImageList::CreateSystemImageList(int size) 119 131 #else 120 132 m_pImageList = new wxImageListEx(size, size); 121 133 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 125 149 m_pImageList->Add(file); 126 150 m_pImageList->Add(folderclosed); 127 151 m_pImageList->Add(folder); … … CSystemImageList::~CSystemImageList() 150 174 m_pImageList = 0; 151 175 } 152 176 153 #ifndef __WXMSW__ 177 #ifdef __WXGTK__ 178 179 typedef 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; 185 typedef enum { 186 GNOME_ICON_LOOKUP_RESULT_FLAGS_NONE = 0, 187 GNOME_ICON_LOOKUP_RESULT_FLAGS_THUMBNAIL = 1<<0 188 } GnomeIconLookupResultFlags; 189 struct 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 218 wxBitmap 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 154 251 // This function converts to the right size with the given background colour 155 252 wxBitmap PrepareIcon(wxIcon icon, wxSize size) 156 253 { … … wxBitmap PrepareIcon(wxIcon icon, wxSize size) 160 257 bmp.CopyFromIcon(icon); 161 258 return bmp.ConvertToImage().Rescale(size.GetWidth(), size.GetHeight()); 162 259 } 260 261 wxBitmap 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 } 163 281 #endif 164 282 165 283 int CSystemImageList::GetIconIndex(enum filetype type, const wxString& fileName /*=_T("")*/, bool physical /*=true*/, bool symlink /*=false*/) … … int CSystemImageList::GetIconIndex(enum filetype type, const wxString& fileName 216 334 return cacheIter->second; 217 335 } 218 336 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; 241 344 } 242 delete pType;243 345 244 346 if (symlink) 245 347 m_iconCache[ext] = icon;