Ticket #9401: 0001-Get-file-icons-on-linux.2.patch
File 0001-Get-file-icons-on-linux.2.patch, 9.0 KB (added by , 10 years ago) |
---|
-
src/interface/LocalListView.cpp
From 81b4a0bdbf6a80b0b58a8814ec03db7f37e0e9f4 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). * Fallback to wxTheMimeTypesManager if no icon could be found through. * Properly display local symlinks. Gnome/Gtk. --- src/interface/LocalListView.cpp | 4 +- src/interface/systemimagelist.cpp | 176 +++++++++++++++++++++++++++++++------- 2 files changed, 149 insertions(+), 31 deletions(-) diff --git a/src/interface/LocalListView.cpp b/src/interface/LocalListView.cpp index 2f4796f..d4b971e 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 bool isSymLink = false; 491 CLocalFileSystem::GetFileInfo(path, isSymLink, NULL, NULL, NULL); 492 icon = pThis->GetIconIndex(data->dir ? dir : file, path, true, isSymLink); 491 493 } 492 494 return icon; 493 495 } -
src/interface/systemimagelist.cpp
diff --git a/src/interface/systemimagelist.cpp b/src/interface/systemimagelist.cpp index 2480ac3..af94585 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 186 typedef enum { 187 GNOME_ICON_LOOKUP_RESULT_FLAGS_NONE = 0, 188 GNOME_ICON_LOOKUP_RESULT_FLAGS_THUMBNAIL = 1<<0 189 } GnomeIconLookupResultFlags; 190 191 struct Gnome { 192 Gnome(): 193 libGnomeVfs(_T("libgnomevfs-2.so.0"), wxDL_QUIET), 194 libGnomeUi(_T("libgnomeui-2.so.0"), wxDL_QUIET), 195 gnome_vfs_init((Gnome_Vfs_Init)libGnomeVfs.GetSymbol(_T("gnome_vfs_init"))), 196 vfs_get_mime_type_for_name((Gnome_Vfs_Get_Mime_Type_For_Name)libGnomeVfs.GetSymbol(_T("gnome_vfs_get_mime_type_for_name"))), 197 icon_lookup((Gnome_Icon_Lookup)libGnomeUi.GetSymbol(_T("gnome_icon_lookup"))) 198 { 199 if (!gnome_vfs_init || !gnome_vfs_init()) 200 icon_lookup = NULL; 201 } 202 203 typedef int (*Gnome_Vfs_Init)(void); 204 typedef const char * (*Gnome_Vfs_Get_Mime_Type_For_Name)(const char *filename); 205 typedef char * (*Gnome_Icon_Lookup)(GtkIconTheme *icon_theme, 206 const char *file_uri, 207 void/*GnomeThumbnailFactory*/ *thumbnail_factory, 208 const char *custom_icon, 209 void/*GnomeVFSFileInfo*/ *file_info, 210 const char *mime_type, 211 GnomeIconLookupFlags flags, 212 GnomeIconLookupResultFlags *result); 213 wxDynamicLibrary libGnomeVfs; 214 wxDynamicLibrary libGnomeUi; 215 Gnome_Vfs_Init gnome_vfs_init; 216 Gnome_Vfs_Get_Mime_Type_For_Name vfs_get_mime_type_for_name; 217 Gnome_Icon_Lookup icon_lookup; 218 } static gnome; 219 220 static wxBitmap GetNativeFileIcon(const wxString & fileName, const wxString & ext) 221 { 222 wxString iconName; 223 if (gnome.icon_lookup) 224 { 225 GtkIconTheme *theme = gtk_icon_theme_get_default(); 226 const wxCharBuffer name = fileName.ToUTF8(); 227 const char * mimetype = gnome.vfs_get_mime_type_for_name(name.data()); 228 char * res = gnome.icon_lookup(theme, name.data(), NULL, NULL, NULL, mimetype, GNOME_ICON_LOOKUP_FLAGS_NONE, NULL); 229 if (res) 230 iconName = wxString::FromUTF8(res); 231 g_free(res); 232 } 233 else 234 { 235 GFile * file = g_file_new_for_path(fileName.ToUTF8().data()); 236 GFileInfo * fileInfo = file ? g_file_query_info(file, G_FILE_ATTRIBUTE_STANDARD_ICON, G_FILE_QUERY_INFO_NONE, NULL, NULL) : NULL; 237 GIcon * fileIcon = fileInfo ? g_file_info_get_icon(fileInfo) : NULL; 238 const gchar * const * iconNames = fileIcon ? g_themed_icon_get_names(G_THEMED_ICON(fileIcon)) : NULL; 239 if (iconNames) 240 iconName = wxString::FromUTF8(iconNames[0]); 241 if (fileInfo) 242 g_object_unref(fileInfo); 243 if (file) 244 g_object_unref(file); 245 } 246 247 wxSize iconSize = CThemeProvider::GetIconSize(iconSizeSmall); 248 if (iconName.IsEmpty()) 249 return wxBitmap(); 250 if (iconName.GetChar(0) == '/') 251 return wxImage(iconName).Rescale(iconSize.GetWidth(), iconSize.GetHeight()); 252 return wxArtProvider::GetBitmap(iconName, wxART_OTHER, CThemeProvider::GetIconSize(iconSizeSmall)); 253 } 254 255 #else 256 257 static wxBitmap GetNativeFileIcon(const wxString & /*fileName*/, const wxString & /*ext*/) 258 { 259 return wxBitmap(); 260 } 261 262 #endif 263 154 264 // This function converts to the right size with the given background colour 155 wxBitmap PrepareIcon(wxIcon icon, wxSize size)265 static wxBitmap PrepareIcon(wxIcon icon, wxSize size) 156 266 { 157 267 if (icon.GetWidth() == size.GetWidth() && icon.GetHeight() == size.GetHeight()) 158 268 return icon; … … wxBitmap PrepareIcon(wxIcon icon, wxSize size) 160 270 bmp.CopyFromIcon(icon); 161 271 return bmp.ConvertToImage().Rescale(size.GetWidth(), size.GetHeight()); 162 272 } 163 #endif 273 274 static wxBitmap GetFileIcon(const wxString & /*fileName*/, const wxString & ext) 275 { 276 wxFileType *pType = wxTheMimeTypesManager->GetFileTypeFromExtension(ext); 277 if (!pType) 278 return wxBitmap(); 279 280 wxBitmap bmp; 281 wxIconLocation loc; 282 if (pType->GetIcon(&loc) && loc.IsOk()) 283 { 284 wxLogNull nul; 285 wxIcon newIcon(loc); 286 287 if (newIcon.Ok()) 288 bmp = PrepareIcon(newIcon, CThemeProvider::GetIconSize(iconSizeSmall)); 289 } 290 delete pType; 291 292 return bmp; 293 } 164 294 165 295 int CSystemImageList::GetIconIndex(enum filetype type, const wxString& fileName /*=_T("")*/, bool physical /*=true*/, bool symlink /*=false*/) 166 296 { … … int CSystemImageList::GetIconIndex(enum filetype type, const wxString& fileName 216 346 return cacheIter->second; 217 347 } 218 348 219 wxFileType *pType = wxTheMimeTypesManager->GetFileTypeFromExtension(ext); 220 if (!pType) 221 { 222 m_iconCache[ext] = icon; 223 return icon; 349 wxBitmap bmp = GetNativeFileIcon(fileName, ext); 350 if (!bmp.IsOk()) 351 bmp = GetFileIcon(fileName, ext); 352 if (bmp.IsOk()) { 353 if (symlink) 354 OverlaySymlink(bmp); 355 int index = m_pImageList->Add(bmp); 356 if (index > 0) 357 icon = index; 224 358 } 225 359 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 }241 }242 delete pType;243 244 360 if (symlink) 245 361 m_iconCache[ext] = icon; 246 362 else