1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2006 Alexander Olk
24 // Alexander Olk alex.olk@googlemail.com
28 // public static int GetIconIndexForFile( string full_filename )
29 // public static int GetIconIndexForMimeType( string mime_type )
30 // to get the image index in MimeIconEngine.SmallIcons and MimeIconEngine.LargeIcons
33 using System.Reflection;
35 using System.Collections;
38 using System.Runtime.InteropServices;
41 namespace System.Windows.Forms
43 internal enum MimeExtensionHandlerStatus
49 internal enum EPlatformHandler
55 internal class ResourceImageLoader
57 static Assembly assembly = typeof (ResourceImageLoader).Assembly;
59 static internal Bitmap Get (string name)
61 Stream stream = assembly.GetManifestResourceStream (name);
64 Console.WriteLine ("Failed to read {0}", name);
68 return new Bitmap (stream);
71 static internal Icon GetIcon (string name)
73 Stream stream = assembly.GetManifestResourceStream (name);
76 Console.WriteLine ("Failed to read {0}", name);
80 return new Icon (stream);
84 internal class MimeIconEngine
86 public static ImageList SmallIcons = new ImageList();
87 public static ImageList LargeIcons = new ImageList();
89 private static EPlatformHandler platform = EPlatformHandler.Default;
91 internal static Hashtable MimeIconIndex = new Hashtable ();
93 private static PlatformMimeIconHandler platformMimeHandler = null;
95 private static object lock_object = new Object();
97 static MimeIconEngine ()
99 SmallIcons.ColorDepth = ColorDepth.Depth32Bit;
100 SmallIcons.TransparentColor = Color.Transparent;
101 LargeIcons.ColorDepth = ColorDepth.Depth32Bit;
102 LargeIcons.TransparentColor = Color.Transparent;
104 string session = Environment.GetEnvironmentVariable ("DESKTOP_SESSION");
106 if (session != null) {
107 session = session.ToUpper ();
109 if (session == "DEFAULT") {
110 string helper = Environment.GetEnvironmentVariable ("GNOME_DESKTOP_SESSION_ID");
116 session = String.Empty;
118 if (Mime.MimeAvailable && session == "GNOME") {
119 SmallIcons.ImageSize = new Size (24, 24);
120 LargeIcons.ImageSize = new Size (48, 48);
122 platformMimeHandler = new GnomeHandler ();
123 if (platformMimeHandler.Start () == MimeExtensionHandlerStatus.OK) {
124 platform = EPlatformHandler.GNOME;
126 MimeIconEngine.LargeIcons.Images.Clear ();
127 MimeIconEngine.SmallIcons.Images.Clear ();
128 platformMimeHandler = new PlatformDefaultHandler ();
129 platformMimeHandler.Start ();
132 SmallIcons.ImageSize = new Size (16, 16);
133 LargeIcons.ImageSize = new Size (48, 48);
135 platformMimeHandler = new PlatformDefaultHandler ();
136 platformMimeHandler.Start ();
140 public static int GetIconIndexForFile (string full_filename)
143 if (platform == EPlatformHandler.Default) {
144 return (int)MimeIconIndex ["unknown/unknown"];
147 string mime_type = Mime.GetMimeTypeForFile (full_filename);
149 object oindex = GetIconIndex (mime_type);
152 if (oindex == null) {
153 int index = full_filename.IndexOf (':');
156 oindex = MimeIconIndex ["unknown/unknown"];
159 oindex = platformMimeHandler.AddAndGetIconIndex (full_filename, mime_type);
163 oindex = MimeIconIndex ["unknown/unknown"];
171 public static int GetIconIndexForMimeType (string mime_type)
174 if (platform == EPlatformHandler.Default) {
175 if (mime_type == "inode/directory") {
176 return (int)MimeIconIndex ["inode/directory"];
178 return (int)MimeIconIndex ["unknown/unknown"];
182 object oindex = GetIconIndex (mime_type);
185 if (oindex == null) {
186 oindex = platformMimeHandler.AddAndGetIconIndex (mime_type);
190 oindex = MimeIconIndex ["unknown/unknown"];
197 public static Image GetIconForMimeTypeAndSize (string mime_type, Size size)
200 object oindex = GetIconIndex (mime_type);
202 Bitmap bmp = new Bitmap (LargeIcons.Images [(int)oindex], size);
208 internal static void AddIconByImage (string mime_type, Image image)
210 int index = SmallIcons.Images.Add (image, Color.Transparent);
211 LargeIcons.Images.Add (image, Color.Transparent);
213 MimeIconIndex.Add (mime_type, index);
216 private static object GetIconIndex (string mime_type)
218 object oindex = null;
220 if (mime_type != null) {
221 // first check if mime_type is available in the mimetype/icon hashtable
222 oindex = MimeIconIndex [mime_type];
224 if (oindex == null) {
225 // it is not available, check if an alias exist for mime_type
226 string alias = Mime.GetMimeAlias (mime_type);
229 string[] split = alias.Split (new char [] { ',' });
231 for (int i = 0; i < split.Length; i++) {
232 oindex = MimeIconIndex [split [i]];
239 // if oindex is still null check if mime_type is a sub class of an other mime type
240 string sub_class = Mime.SubClasses [mime_type];
242 if (sub_class != null) {
243 oindex = MimeIconIndex [sub_class];
249 // last check, see if we find an entry for the main mime type class
250 string mime_class_main = mime_type.Substring (0, mime_type.IndexOf ('/'));
251 return MimeIconIndex [mime_class_main];
259 internal abstract class PlatformMimeIconHandler
261 protected MimeExtensionHandlerStatus mimeExtensionHandlerStatus = MimeExtensionHandlerStatus.OK;
263 public MimeExtensionHandlerStatus MimeExtensionHandlerStatus {
265 return mimeExtensionHandlerStatus;
269 public abstract MimeExtensionHandlerStatus Start ();
271 public virtual object AddAndGetIconIndex (string filename, string mime_type)
276 public virtual object AddAndGetIconIndex (string mime_type)
282 internal class PlatformDefaultHandler : PlatformMimeIconHandler
284 public override MimeExtensionHandlerStatus Start ()
286 MimeIconEngine.AddIconByImage ("inode/directory", ResourceImageLoader.Get ("folder.png"));
287 MimeIconEngine.AddIconByImage ("unknown/unknown", ResourceImageLoader.Get ("text-x-generic.png"));
288 MimeIconEngine.AddIconByImage ("desktop/desktop", ResourceImageLoader.Get ("user-desktop.png"));
289 MimeIconEngine.AddIconByImage ("directory/home", ResourceImageLoader.Get ("user-home.png"));
291 MimeIconEngine.AddIconByImage ("network/network", ResourceImageLoader.Get ("folder-remote.png"));
292 MimeIconEngine.AddIconByImage ("recently/recently", ResourceImageLoader.Get ("document-open.png"));
293 MimeIconEngine.AddIconByImage ("workplace/workplace", ResourceImageLoader.Get ("computer.png"));
295 return MimeExtensionHandlerStatus.OK; // return always ok
299 internal class GnomeHandler : PlatformMimeIconHandler
301 public override MimeExtensionHandlerStatus Start ()
305 return MimeExtensionHandlerStatus.OK;
308 private void CreateUIIcons ()
310 AddGnomeIcon ("unknown/unknown", "gnome-fs-regular");
311 AddGnomeIcon ("inode/directory", "gnome-fs-directory");
312 AddGnomeIcon ("directory/home", "gnome-fs-home");
313 AddGnomeIcon ("desktop/desktop", "gnome-fs-desktop");
314 AddGnomeIcon ("recently/recently", "gnome-fs-directory-accept");
315 AddGnomeIcon ("workplace/workplace", "gnome-fs-client");
317 AddGnomeIcon ("network/network", "gnome-fs-network");
318 AddGnomeIcon ("nfs/nfs", "gnome-fs-nfs");
319 AddGnomeIcon ("smb/smb", "gnome-fs-smb");
321 AddGnomeIcon ("harddisk/harddisk", "gnome-dev-harddisk");
322 AddGnomeIcon ("cdrom/cdrom", "gnome-dev-cdrom");
323 AddGnomeIcon ("removable/removable", "gnome-dev-removable");
326 private void AddGnomeIcon (string internal_mime_type, string name)
330 if (MimeIconEngine.MimeIconIndex.ContainsKey (internal_mime_type)) {
334 Image image = GnomeUtil.GetIcon (name, 48);
337 if (internal_mime_type == "unknown/unknown")
338 image = ResourceImageLoader.Get ("text-x-generic.png");
340 if (internal_mime_type == "inode/directory")
341 image = ResourceImageLoader.Get ("folder.png");
343 if (internal_mime_type == "directory/home")
344 image = ResourceImageLoader.Get ("user-home.png");
346 if (internal_mime_type == "desktop/desktop")
347 image = ResourceImageLoader.Get ("user-desktop.png");
349 if (internal_mime_type == "recently/recently")
350 image = ResourceImageLoader.Get ("document-open.png");
352 if (internal_mime_type == "workplace/workplace")
353 image = ResourceImageLoader.Get ("computer.png");
355 if (internal_mime_type == "network/network" || internal_mime_type == "nfs/nfs" || internal_mime_type == "smb/smb")
356 image = ResourceImageLoader.Get ("folder-remote.png");
358 if (internal_mime_type == "harddisk/harddisk" || internal_mime_type == "cdrom/cdrom" || internal_mime_type == "removable/removable")
359 image = ResourceImageLoader.Get ("text-x-generic.png");
363 index = MimeIconEngine.SmallIcons.Images.Add (image, Color.Transparent);
364 MimeIconEngine.LargeIcons.Images.Add (image, Color.Transparent);
365 MimeIconEngine.MimeIconIndex.Add (internal_mime_type, index);
369 public override object AddAndGetIconIndex (string filename, string mime_type)
373 Image image = GnomeUtil.GetIcon (filename, mime_type, 48);
375 index = MimeIconEngine.SmallIcons.Images.Add (image, Color.Transparent);
376 MimeIconEngine.LargeIcons.Images.Add (image, Color.Transparent);
377 MimeIconEngine.MimeIconIndex.Add (mime_type, index);
383 public override object AddAndGetIconIndex (string mime_type)
387 Image image = GnomeUtil.GetIcon (mime_type, 48);
389 index = MimeIconEngine.SmallIcons.Images.Add (image, Color.Transparent);
390 MimeIconEngine.LargeIcons.Images.Add (image, Color.Transparent);
391 MimeIconEngine.MimeIconIndex.Add (mime_type, index);
398 internal class GnomeUtil
400 const string libgdk = "libgdk-x11-2.0.so.0";
401 const string libgdk_pixbuf = "libgdk_pixbuf-2.0.so.0";
402 const string libgtk = "libgtk-x11-2.0.so.0";
403 const string libglib = "libglib-2.0.so.0";
404 const string libgobject = "libgobject-2.0.so.0";
405 const string libgnomeui = "libgnomeui-2.so.0";
406 const string librsvg = "librsvg-2.so.2";
409 static extern IntPtr rsvg_pixbuf_from_file_at_size (string file_name, int width, int height, out IntPtr error);
411 [DllImport(libgdk_pixbuf)]
412 static extern bool gdk_pixbuf_save_to_buffer (IntPtr pixbuf, out IntPtr buffer, out UIntPtr buffer_size, string type, out IntPtr error, IntPtr option_dummy);
415 static extern void g_free (IntPtr mem);
418 static extern bool gdk_init_check (IntPtr argc, IntPtr argv);
420 [DllImport(libgobject)]
421 static extern void g_object_unref (IntPtr nativeObject);
423 [DllImport(libgnomeui)]
424 static extern string gnome_icon_lookup (IntPtr icon_theme, IntPtr thumbnail_factory, string file_uri, string custom_icon, IntPtr file_info, string mime_type, GnomeIconLookupFlags flags, IntPtr result);
427 static extern IntPtr gtk_icon_theme_get_default ();
430 static extern IntPtr gtk_icon_theme_load_icon (IntPtr icon_theme, string icon_name, int size, GtkIconLookupFlags flags, out IntPtr error);
433 static extern bool gtk_icon_theme_has_icon (IntPtr icon_theme, string icon_name);
435 enum GnomeIconLookupFlags
437 GNOME_ICON_LOOKUP_FLAGS_NONE = 0,
438 GNOME_ICON_LOOKUP_FLAGS_EMBEDDING_TEXT = 1<<0,
439 GNOME_ICON_LOOKUP_FLAGS_SHOW_SMALL_IMAGES_AS_THEMSELVES = 1<<1,
440 GNOME_ICON_LOOKUP_FLAGS_ALLOW_SVG_AS_THEMSELVES = 1<<2
443 enum GtkIconLookupFlags
445 GTK_ICON_LOOKUP_NO_SVG = 1 << 0,
446 GTK_ICON_LOOKUP_FORCE_SVG = 1 << 1,
447 GTK_ICON_LOOKUP_USE_BUILTIN = 1 << 2
450 static bool inited = false;
452 static IntPtr default_icon_theme = IntPtr.Zero;
456 gdk_init_check (IntPtr.Zero, IntPtr.Zero);
460 default_icon_theme = gtk_icon_theme_get_default ();
463 public static Image GetIcon (string file_name, string mime_type, int size)
468 Uri uri = new Uri (file_name);
473 icon = gnome_icon_lookup (default_icon_theme, IntPtr.Zero, uri.AbsoluteUri,
474 null, IntPtr.Zero, mime_type,
475 GnomeIconLookupFlags.GNOME_ICON_LOOKUP_FLAGS_NONE, IntPtr.Zero);
477 // If libgnomeui is not installed, in preparation for Gnome 3
481 IntPtr error = IntPtr.Zero;
482 IntPtr pixbuf = gtk_icon_theme_load_icon (default_icon_theme, icon, size,
483 GtkIconLookupFlags.GTK_ICON_LOOKUP_USE_BUILTIN, out error);
485 if (error != IntPtr.Zero)
488 return GdkPixbufToImage (pixbuf);
491 public static Image GetIcon (string icon, int size)
496 IntPtr error = IntPtr.Zero;
497 IntPtr pixbuf = gtk_icon_theme_load_icon (default_icon_theme, icon, size,
498 GtkIconLookupFlags.GTK_ICON_LOOKUP_USE_BUILTIN, out error);
500 if (error != IntPtr.Zero)
503 return GdkPixbufToImage (pixbuf);
506 public static Image GdkPixbufToImage (IntPtr pixbuf)
508 IntPtr error = IntPtr.Zero;
510 UIntPtr buffer_size_as_ptr;
513 bool saved = gdk_pixbuf_save_to_buffer (pixbuf, out buffer, out buffer_size_as_ptr, type, out error, IntPtr.Zero);
518 int buffer_size = (int) (uint) buffer_size_as_ptr;
519 byte[] result = new byte [buffer_size];
520 Marshal.Copy (buffer, result, 0, (int) buffer_size);
522 g_object_unref (pixbuf);
525 MemoryStream s = new MemoryStream (result);
526 image = Image.FromStream (s);
531 public static Image GetSVGasImage (string filename, int width, int height)
536 if (!File.Exists (filename))
538 IntPtr error = IntPtr.Zero;
539 IntPtr pixbuf = rsvg_pixbuf_from_file_at_size (filename, width, height, out error);
541 if (error != IntPtr.Zero)
544 return GdkPixbufToImage (pixbuf);
547 public static bool HasImage (string name)
552 return gtk_icon_theme_has_icon (default_icon_theme, name);