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) 2005 Novell, Inc. (http://www.novell.com)
24 // Alexander Olk xenomorph2@onlinehome.de
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;
36 //using System.Collections.Specialized;
39 using System.Runtime.InteropServices;
42 namespace System.Windows.Forms
44 internal enum MimeExtensionHandlerStatus
50 internal enum EPlatformHandler
56 internal class ResourceImageLoader
58 static Assembly assembly = typeof (ResourceImageLoader).Assembly;
60 static internal Bitmap Get (string name)
62 using (Stream stream = assembly.GetManifestResourceStream (name)) {
64 Console.WriteLine ("Failed to read {0}", name);
68 return new Bitmap (stream);
73 internal class MimeIconEngine
75 public static ImageList SmallIcons = new ImageList();
76 public static ImageList LargeIcons = new ImageList();
78 private static EPlatformHandler platform = EPlatformHandler.Default;
80 internal static Hashtable MimeIconIndex = new Hashtable ();
82 private static PlatformMimeIconHandler platformMimeHandler = null;
84 private static object lock_object = new Object();
86 static MimeIconEngine ()
88 SmallIcons.ColorDepth = ColorDepth.Depth32Bit;
89 SmallIcons.TransparentColor = Color.Transparent;
90 LargeIcons.ColorDepth = ColorDepth.Depth32Bit;
91 LargeIcons.TransparentColor = Color.Transparent;
93 string session = Environment.GetEnvironmentVariable ("DESKTOP_SESSION");
95 if (session != null) {
96 session = session.ToUpper ();
98 if (session == "DEFAULT") {
99 string helper = Environment.GetEnvironmentVariable ("GNOME_DESKTOP_SESSION_ID");
107 if (session == "GNOME") {
108 SmallIcons.ImageSize = new Size (24, 24);
109 LargeIcons.ImageSize = new Size (48, 48);
111 platformMimeHandler = new GnomeHandler ();
112 if (platformMimeHandler.Start () == MimeExtensionHandlerStatus.OK) {
113 platform = EPlatformHandler.GNOME;
115 MimeIconEngine.LargeIcons.Images.Clear ();
116 MimeIconEngine.SmallIcons.Images.Clear ();
117 platformMimeHandler = new PlatformDefaultHandler ();
118 platformMimeHandler.Start ();
121 SmallIcons.ImageSize = new Size (16, 16);
122 LargeIcons.ImageSize = new Size (48, 48);
124 platformMimeHandler = new PlatformDefaultHandler ();
125 platformMimeHandler.Start ();
129 public static int GetIconIndexForFile (string full_filename)
132 string mime_type = Mime.GetMimeTypeForFile (full_filename);
134 if (platform == EPlatformHandler.Default) {
135 if (mime_type == "inode/directory") {
136 return (int)MimeIconIndex ["inode/directory"];
138 return (int)MimeIconIndex ["unknown/unknown"];
142 object oindex = GetIconIndex (mime_type);
145 if (oindex == null) {
146 int index = full_filename.IndexOf (':');
149 oindex = MimeIconIndex ["unknown/unknown"];
152 oindex = platformMimeHandler.AddAndGetIconIndex (full_filename, mime_type);
156 oindex = MimeIconIndex ["unknown/unknown"];
164 public static int GetIconIndexForMimeType (string mime_type)
167 if (platform == EPlatformHandler.Default) {
168 if (mime_type == "inode/directory") {
169 return (int)MimeIconIndex ["inode/directory"];
171 return (int)MimeIconIndex ["unknown/unknown"];
175 object oindex = GetIconIndex (mime_type);
178 if (oindex == null) {
179 oindex = platformMimeHandler.AddAndGetIconIndex (mime_type);
183 oindex = MimeIconIndex ["unknown/unknown"];
190 public static Image GetIconForMimeTypeAndSize (string mime_type, Size size)
193 object oindex = GetIconIndex (mime_type);
195 Bitmap bmp = new Bitmap (LargeIcons.Images [(int)oindex], size);
201 internal static void AddIconByImage (string mime_type, Image image)
203 int index = SmallIcons.Images.Add (image, Color.Transparent);
204 LargeIcons.Images.Add (image, Color.Transparent);
206 MimeIconIndex.Add (mime_type, index);
209 private static object GetIconIndex (string mime_type)
211 object oindex = null;
213 if (mime_type != null) {
214 // first check if mime_type is available in the mimetype/icon hashtable
215 oindex = MimeIconIndex [mime_type];
217 if (oindex == null) {
218 // it is not available, check if an alias exist for mime_type
219 string alias = Mime.GetMimeAlias (mime_type);
222 string[] split = alias.Split (new char [] { ',' });
224 for (int i = 0; i < split.Length; i++) {
225 oindex = MimeIconIndex [split [i]];
232 // if oindex is still null check if mime_type is a sub class of an other mime type
233 string sub_class = Mime.SubClasses [mime_type];
235 if (sub_class != null) {
236 oindex = MimeIconIndex [sub_class];
242 // last check, see if we find an entry for the main mime type class
243 string mime_class_main = mime_type.Substring (0, mime_type.IndexOf ('/'));
244 return MimeIconIndex [mime_class_main];
252 internal abstract class PlatformMimeIconHandler
254 protected MimeExtensionHandlerStatus mimeExtensionHandlerStatus = MimeExtensionHandlerStatus.OK;
256 public MimeExtensionHandlerStatus MimeExtensionHandlerStatus {
258 return mimeExtensionHandlerStatus;
262 public abstract MimeExtensionHandlerStatus Start ();
264 public virtual object AddAndGetIconIndex (string filename, string mime_type)
269 public virtual object AddAndGetIconIndex (string mime_type)
275 internal class PlatformDefaultHandler : PlatformMimeIconHandler
277 public override MimeExtensionHandlerStatus Start ()
279 MimeIconEngine.AddIconByImage ("inode/directory", ResourceImageLoader.Get ("folder.png"));
280 MimeIconEngine.AddIconByImage ("unknown/unknown", ResourceImageLoader.Get ("text-x-generic.png"));
281 MimeIconEngine.AddIconByImage ("desktop/desktop", ResourceImageLoader.Get ("user-desktop.png"));
282 MimeIconEngine.AddIconByImage ("directory/home", ResourceImageLoader.Get ("user-home.png"));
285 MimeIconEngine.AddIconByImage ("network/network", ResourceImageLoader.Get ("document-open.png"));
286 MimeIconEngine.AddIconByImage ("recently/recently", ResourceImageLoader.Get ("document-open.png"));
287 MimeIconEngine.AddIconByImage ("workplace/workplace", ResourceImageLoader.Get ("document-open.png"));
289 return MimeExtensionHandlerStatus.OK; // return always ok
293 internal class GnomeHandler : PlatformMimeIconHandler
295 public override MimeExtensionHandlerStatus Start ()
299 return MimeExtensionHandlerStatus.OK;
302 private void CreateUIIcons ()
304 AddGnomeIcon ("unknown/unknown", "gnome-fs-regular");
305 AddGnomeIcon ("inode/directory", "gnome-fs-directory");
306 AddGnomeIcon ("directory/home", "gnome-fs-home");
307 AddGnomeIcon ("desktop/desktop", "gnome-fs-desktop");
308 AddGnomeIcon ("recently/recently", "gnome-fs-directory-accept");
309 AddGnomeIcon ("workplace/workplace", "gnome-fs-client");
311 AddGnomeIcon ("network/network", "gnome-fs-network");
312 AddGnomeIcon ("nfs/nfs", "gnome-fs-nfs");
313 AddGnomeIcon ("smb/smb", "gnome-fs-smb");
315 AddGnomeIcon ("harddisk/harddisk", "gnome-dev-harddisk");
316 AddGnomeIcon ("cdrom/cdrom", "gnome-dev-cdrom");
317 AddGnomeIcon ("removable/removable", "gnome-dev-removable");
320 private void AddGnomeIcon (string internal_mime_type, string name)
324 if (MimeIconEngine.MimeIconIndex.ContainsKey (internal_mime_type)) {
328 Image image = GnomeUtil.GetIcon (name, 48);
330 index = MimeIconEngine.SmallIcons.Images.Add (image, Color.Transparent);
331 MimeIconEngine.LargeIcons.Images.Add (image, Color.Transparent);
333 MimeIconEngine.MimeIconIndex.Add (internal_mime_type, index);
336 public override object AddAndGetIconIndex (string filename, string mime_type)
340 Image image = GnomeUtil.GetIcon (filename, mime_type, 48);
342 index = MimeIconEngine.SmallIcons.Images.Add (image, Color.Transparent);
343 MimeIconEngine.LargeIcons.Images.Add (image, Color.Transparent);
345 MimeIconEngine.MimeIconIndex.Add (mime_type, index);
350 public override object AddAndGetIconIndex (string mime_type)
354 Image image = GnomeUtil.GetIcon (mime_type, 48);
356 index = MimeIconEngine.SmallIcons.Images.Add (image, Color.Transparent);
357 MimeIconEngine.LargeIcons.Images.Add (image, Color.Transparent);
359 MimeIconEngine.MimeIconIndex.Add (mime_type, index);
365 internal class GnomeUtil
367 [DllImport("librsvg-2.so")]
368 static extern IntPtr rsvg_pixbuf_from_file_at_size (string file_name, int width, int height, out IntPtr error);
370 [DllImport("libgdk-x11-2.0.so.0")]
371 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);
373 [DllImport("libglib-2.0.so")]
374 static extern void g_free (IntPtr mem);
376 [DllImport("libgdk-x11-2.0.so.0")]
377 static extern bool gdk_init_check (IntPtr argc, IntPtr argv);
379 [DllImport("libgobject-2.0.so")]
380 static extern void g_object_unref (IntPtr nativeObject);
382 [DllImport("libgnomeui-2.so.0")]
383 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);
385 [DllImport("libgtk-x11-2.0.so")]
386 static extern IntPtr gtk_icon_theme_get_default ();
388 [DllImport("libgtk-x11-2.0.so")]
389 static extern IntPtr gtk_icon_theme_load_icon (IntPtr icon_theme, string icon_name, int size, GtkIconLookupFlags flags, out IntPtr error);
391 [DllImport("libgtk-x11-2.0.so")]
392 static extern bool gtk_icon_theme_has_icon (IntPtr icon_theme, string icon_name);
394 enum GnomeIconLookupFlags
396 GNOME_ICON_LOOKUP_FLAGS_NONE = 0,
397 GNOME_ICON_LOOKUP_FLAGS_EMBEDDING_TEXT = 1<<0,
398 GNOME_ICON_LOOKUP_FLAGS_SHOW_SMALL_IMAGES_AS_THEMSELVES = 1<<1,
399 GNOME_ICON_LOOKUP_FLAGS_ALLOW_SVG_AS_THEMSELVES = 1<<2
402 enum GtkIconLookupFlags
404 GTK_ICON_LOOKUP_NO_SVG = 1 << 0,
405 GTK_ICON_LOOKUP_FORCE_SVG = 1 << 1,
406 GTK_ICON_LOOKUP_USE_BUILTIN = 1 << 2
409 static bool inited = false;
411 static IntPtr default_icon_theme = IntPtr.Zero;
415 gdk_init_check (IntPtr.Zero, IntPtr.Zero);
419 default_icon_theme = gtk_icon_theme_get_default ();
422 public static Image GetIcon (string file_name, string mime_type, int size)
427 Uri uri = new Uri (file_name);
429 string icon = gnome_icon_lookup (default_icon_theme, IntPtr.Zero, uri.AbsoluteUri,
430 null, IntPtr.Zero, mime_type,
431 GnomeIconLookupFlags.GNOME_ICON_LOOKUP_FLAGS_NONE, IntPtr.Zero);
433 IntPtr error = IntPtr.Zero;
434 IntPtr pixbuf = gtk_icon_theme_load_icon (default_icon_theme, icon, size,
435 GtkIconLookupFlags.GTK_ICON_LOOKUP_USE_BUILTIN, out error);
437 if (error != IntPtr.Zero)
440 return GdkPixbufToImage (pixbuf);
443 public static Image GetIcon (string icon, int size)
448 IntPtr error = IntPtr.Zero;
449 IntPtr pixbuf = gtk_icon_theme_load_icon (default_icon_theme, icon, size,
450 GtkIconLookupFlags.GTK_ICON_LOOKUP_USE_BUILTIN, out error);
452 if (error != IntPtr.Zero)
455 return GdkPixbufToImage (pixbuf);
458 public static Image GdkPixbufToImage (IntPtr pixbuf)
460 IntPtr error = IntPtr.Zero;
462 UIntPtr buffer_size_as_ptr;
465 bool saved = gdk_pixbuf_save_to_buffer (pixbuf, out buffer, out buffer_size_as_ptr, type, out error, IntPtr.Zero);
470 int buffer_size = (int) (uint) buffer_size_as_ptr;
471 byte[] result = new byte [buffer_size];
472 Marshal.Copy (buffer, result, 0, (int) buffer_size);
474 g_object_unref (pixbuf);
477 using (MemoryStream s = new MemoryStream (result))
478 image = Image.FromStream (s);
483 public static Image GetSVGasImage (string filename, int width, int height)
488 if (!File.Exists (filename))
490 IntPtr error = IntPtr.Zero;
491 IntPtr pixbuf = rsvg_pixbuf_from_file_at_size (filename, width, height, out error);
493 if (error != IntPtr.Zero)
496 return GdkPixbufToImage (pixbuf);
499 public static bool HasImage (string name)
504 return gtk_icon_theme_has_icon (default_icon_theme, name);