merge -r 61110:61111
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / MimeIcon.cs
index 5d8863d01cef9ac07284f20d3b1d63284ef62804..d1a1b2298a840cf45edc03f21ba4c79f775bf8ba 100644 (file)
 // to get the image itself for a mime type with a specific size
 
 using System;
+using System.Reflection;
 using System.Drawing;
 using System.Collections;
 using System.Collections.Specialized;
 using System.IO;
 using System.Text;
+using System.Runtime.InteropServices;
+using System.Xml;
 
 namespace System.Windows.Forms
 {
@@ -67,18 +70,101 @@ namespace System.Windows.Forms
                GNOME
                // Win, Mac OSX...
        }
+
+       internal class ResourceImageLoader {
+               static Assembly assembly = typeof (ResourceImageLoader).Assembly;
+               
+               static internal Bitmap Get (string name)
+               {
+                       using (Stream stream = assembly.GetManifestResourceStream (name)){
+                               if (stream == null){
+                                       Console.WriteLine ("Failed to read {0}", name);
+                                       return null;
+                               }
+                               
+                               return new Bitmap (stream);
+                       }
+               }
+       }
        
        internal class MimeIconEngine
        {
                public static ImageList SmallIcons = new ImageList();
                public static ImageList LargeIcons = new ImageList();
                
-               private static PlatformMimeIconHandler platformMimeHandler = null;
-               
                private static EPlatformHandler platform = EPlatformHandler.Default;
                
-               private static Hashtable MimeTypeIconIndexHash = new Hashtable();
+               private static IconIndexHash MimeTypeIconIndexHash = new IconIndexHash();
                
+               struct IconPath { 
+                       public string Fullname; 
+                       public IconPath (string path)
+                       {
+                               Fullname = path;
+                       }
+               }
+
+               struct SvgIconPath { 
+                       public string Fullname; 
+                       public SvgIconPath (string path)
+                       {
+                               Fullname = path;
+                       }
+               }
+
+               private class IconIndexHash {
+
+                       Hashtable hash = new Hashtable ();
+
+                       private int LoadIcon (IconPath path)
+                       {
+                               Bitmap bmp = new Bitmap (path.Fullname);
+                       
+                               int index = SmallIcons.Images.Add (bmp, Color.Transparent);
+                               LargeIcons.Images.Add (bmp, Color.Transparent);
+                               return index;
+                       }
+
+                       private int LoadSvgIcon (SvgIconPath path)
+                       {
+                               Image image = SVGUtil.GetSVGasImage (path.Fullname, 48, 48);
+                       
+                               int index = SmallIcons.Images.Add (image, Color.Transparent);
+                               LargeIcons.Images.Add (image, Color.Transparent);
+                               return index;
+                       }
+
+                       private int LoadIcon (object path)
+                       {
+                               if (path is SvgIconPath)
+                                       return LoadSvgIcon ((SvgIconPath) path);
+                               else
+                                       return LoadIcon ((IconPath) path);
+                       }
+
+                       public object this [object key] {
+                               get {
+                                       if (hash [key] == null)
+                                               return null;
+                                       else if (hash [key] is int)
+                                               return hash [key];
+
+                                       hash [key] = LoadIcon (hash [key]);
+                                       return hash [key];
+                               }
+                       }
+
+                       public void Add (string name, object path)
+                       {
+                               hash [name] = path;
+                       }
+
+                       public bool ContainsKey (string s)
+                       {
+                               return hash.ContainsKey (s);
+                       }
+               }
+
                private static NameValueCollection IconNameMimeTypeNameValueCollection = new NameValueCollection();
                
                private static StringCollection added_icons = new StringCollection();
@@ -88,10 +174,10 @@ namespace System.Windows.Forms
                static MimeIconEngine( )
                {
                        // add some more aliases, kde for example uses other mime type names for some mime types...
-                       MimeGenerated.Aliases.Add( "application/x-compressed-tar", "application/x-tgz" );
-                       MimeGenerated.Aliases.Add( "application/x-bzip-compressed-tar", "application/x-tbz" );
-                       MimeGenerated.Aliases.Add( "application/zip", "application/x-zip" );
-                       MimeGenerated.Aliases.Add( "text/x-patch", "text/x-diff" );
+                       Mime.Aliases.Add( "application/x-compressed-tar", "application/x-tgz" );
+                       Mime.Aliases.Add( "application/x-bzip-compressed-tar", "application/x-tbz" );
+                       Mime.Aliases.Add( "application/zip", "application/x-zip" );
+                       Mime.Aliases.Add( "text/x-patch", "text/x-diff" );
                        
                        SmallIcons.ColorDepth = ColorDepth.Depth32Bit;
                        SmallIcons.TransparentColor = Color.Transparent;
@@ -122,7 +208,9 @@ namespace System.Windows.Forms
                        else
                                session = "";
                        
-                       Console.WriteLine( "Desktop session is: " + session );
+                       //Console.WriteLine( "Desktop session is: " + session ); 
+                       
+                       PlatformMimeIconHandler platformMimeHandler = null;
                        
                        if ( session == "KDE" )
                        {
@@ -132,7 +220,6 @@ namespace System.Windows.Forms
                                platformMimeHandler = new KdeHandler( );
                                if ( platformMimeHandler.Start( ) == MimeExtensionHandlerStatus.OK )
                                {
-                                       Console.WriteLine( "Kde icons ready..." );
                                        platform = EPlatformHandler.KDE;
                                }
                                else // fallback to default
@@ -152,7 +239,6 @@ namespace System.Windows.Forms
                                platformMimeHandler = new GnomeHandler( );
                                if ( platformMimeHandler.Start( ) == MimeExtensionHandlerStatus.OK )
                                {
-                                       Console.WriteLine( "Gnome icons ready..." );
                                        platform = EPlatformHandler.GNOME;
                                }
                                else // fallback to default
@@ -209,7 +295,7 @@ namespace System.Windows.Forms
                        {
                                if ( platform == EPlatformHandler.Default )
                                {
-                                       if ( mime_type == "inode/directory" )
+                                       if (mime_type =="inode/directory")
                                        {
                                                return (int)MimeTypeIconIndexHash[ "inode/directory" ];
                                        }
@@ -253,12 +339,20 @@ namespace System.Windows.Forms
                        
                        added_icons.Add( name );
                        
-                       Bitmap bmp = new Bitmap( fullname );
+                       AddMimeTypeIconIndexHash( name, new IconPath (fullname) );
+               }
+               
+               internal static void AddSVGIcon( string name, string fullname )
+               {
+                       if ( !CheckIfIconIsNeeded( name ) )
+                               return;
                        
-                       int index = SmallIcons.Images.Add( bmp, Color.Transparent );
-                       LargeIcons.Images.Add( bmp, Color.Transparent );
+                       if ( added_icons.Contains( name ) )
+                               return;
                        
-                       AddMimeTypeIconIndexHash( name, index );
+                       added_icons.Add( name );
+                       
+                       AddMimeTypeIconIndexHash( name, new SvgIconPath (fullname) );
                }
                
                private static bool CheckIfIconIsNeeded( string name )
@@ -271,7 +365,7 @@ namespace System.Windows.Forms
                        return false;
                }
                
-               internal static void AddMimeTypeIconIndexHash( string name, int index )
+               internal static void AddMimeTypeIconIndexHash( string name, object path_or_index )
                {
                        string mime_type = IconNameMimeTypeNameValueCollection[ name ];
                        
@@ -280,12 +374,12 @@ namespace System.Windows.Forms
                        
                        string[] split = mime_type.Split( new char[] { ',' } );
                        
-                       foreach ( string s in split )
+                       for (int i = 0; i < split.Length; i++)
                        {
-                               if ( MimeTypeIconIndexHash.ContainsKey( s ) )
+                               if ( MimeTypeIconIndexHash.ContainsKey( split[i] ) )
                                        continue;
                                
-                               MimeTypeIconIndexHash.Add( sindex );
+                               MimeTypeIconIndexHash.Add( split[i], path_or_index );
                        }
                }
                
@@ -323,23 +417,28 @@ namespace System.Windows.Forms
                                        {
                                                string[] split = alias.Split( new char[] { ',' } );
                                                
-                                               foreach ( string s in split )
+                                               for (int i = 0; i < split.Length; i++)
                                                {
-                                                       oindex = MimeTypeIconIndexHash[ s ];
+                                                       oindex = MimeTypeIconIndexHash[ split[i] ];
                                                        
                                                        if ( oindex != null )
-                                                               break;
+                                                               return oindex;
                                                }
                                        }
                                        
                                        // if oindex is still null check if mime_type is a sub class of an other mime type
-                                       if ( oindex == null )
-                                       {
-                                               string sub_class = MimeGenerated.SubClasses[ mime_type ];
+                                       string sub_class = Mime.SubClasses[ mime_type ];
+                                       
+                                       if ( sub_class != null ) {
+                                               oindex = MimeTypeIconIndexHash[ sub_class ];
                                                
-                                               if ( sub_class != null )
-                                                       oindex = MimeTypeIconIndexHash[ sub_class ];
+                                               if ( oindex != null )
+                                                       return oindex;
                                        }
+                                       
+                                       // last check, see if we find an entry for the main mime type class
+                                       string mime_class_main = mime_type.Substring( 0, mime_type.IndexOf( '/' ) );
+                                       return MimeTypeIconIndexHash[ mime_class_main ];
                                }
                        }
                        
@@ -375,6 +474,7 @@ namespace System.Windows.Forms
        
        internal class PlatformDefaultHandler : PlatformMimeIconHandler
        {
+               
                public override MimeExtensionHandlerStatus Start( )
                {
                        MimeIconEngine.AddMimeTypeAndIconName( "unknown/unknown", "paper" );
@@ -382,12 +482,18 @@ namespace System.Windows.Forms
                        MimeIconEngine.AddMimeTypeAndIconName( "desktop/desktop", "desktop" );
                        MimeIconEngine.AddMimeTypeAndIconName( "directory/home", "folder_with_paper" );
                        MimeIconEngine.AddMimeTypeAndIconName( "network/network", "monitor-planet" );
+                       MimeIconEngine.AddMimeTypeAndIconName( "recently/recently", "last_open" );
+                       MimeIconEngine.AddMimeTypeAndIconName( "workplace/workplace", "monitor-computer" );
                        
-                       MimeIconEngine.AddIconByImage( "folder",  (Image)Locale.GetResource( "folder" ) );
-                       MimeIconEngine.AddIconByImage( "paper",  (Image)Locale.GetResource( "paper" ) );
-                       MimeIconEngine.AddIconByImage( "desktop",  (Image)Locale.GetResource( "desktop" ) );
-                       MimeIconEngine.AddIconByImage( "folder_with_paper",  (Image)Locale.GetResource( "folder_with_paper" ) );
-                       MimeIconEngine.AddIconByImage( "monitor-planet",  (Image)Locale.GetResource( "monitor-planet" ) );
+                       MimeIconEngine.AddIconByImage( "folder",  ResourceImageLoader.Get ("folder.png") );
+                       MimeIconEngine.AddIconByImage( "paper",  ResourceImageLoader.Get("text-x-generic.png") );
+                       MimeIconEngine.AddIconByImage( "desktop",  ResourceImageLoader.Get( "user-desktop.png" ) );
+                       MimeIconEngine.AddIconByImage( "folder_with_paper",  ResourceImageLoader.Get( "document-open.png" ) );
+
+                       // fix
+                       MimeIconEngine.AddIconByImage( "monitor-planet",  ResourceImageLoader.Get( "document-open.png" ) );
+                       MimeIconEngine.AddIconByImage( "last_open",  ResourceImageLoader.Get( "document-open.png" ) );
+                       MimeIconEngine.AddIconByImage( "monitor-computer",  ResourceImageLoader.Get( "document-open.png" ) );
                        
                        return MimeExtensionHandlerStatus.OK; // return always ok
                }
@@ -410,9 +516,12 @@ namespace System.Windows.Forms
                        // check if the theme is svg only
                        // if true, use theme "default.kde"
                        // don't know if that is available in every linux distribution
-                       // MWF has no svg support yet (cairo's libsvg!?!)
                        if ( SVGOnly( ) )
                                icon_theme = "default.kde";
+                       else
+                       // check if there is a /48x48 directory
+                       if( No48x48( ) )
+                               icon_theme = "default.kde";
                        
                        ReadMimetypes( );
                        
@@ -436,6 +545,24 @@ namespace System.Windows.Forms
                        return false;
                }
                
+               private bool No48x48( )
+               {
+                       // check only the first path in icon_paths
+                       if ( icon_paths.Count > 0 )
+                       {
+                               string icon_path = icon_paths[ 0 ] + icon_theme;
+                               string[] dirs = Directory.GetDirectories( icon_path );
+                               
+                               for (int i = 0; i < dirs.Length; i++)
+                               {
+                                       if ( dirs[i].EndsWith( "48x48" ) )
+                                               return false;
+                               }
+                       }
+                       
+                       return true;
+               }
+               
                protected override bool CheckPlatformDirectories( )
                {
                        bool icons_found = false;
@@ -502,17 +629,17 @@ namespace System.Windows.Forms
                                
                                string[] directories = Directory.GetDirectories( icon_path );
                                
-                               foreach ( string d in directories )
+                               for (int i = 0; i < directories.Length; i++)
                                {
-                                       DirectoryInfo di = new DirectoryInfo( d );
+                                       DirectoryInfo di = new DirectoryInfo( directories [i] );
                                        
                                        FileInfo[] fileinfo = di.GetFiles( );
                                        
-                                       foreach ( FileInfo fi in fileinfo )
+                                       for (int z = 0; z < fileinfo.Length; z++)
                                        {
-                                               string name = Path.GetFileNameWithoutExtension( fi.Name );
+                                               string name = Path.GetFileNameWithoutExtension( fileinfo [z].Name );
                                                
-                                               MimeIconEngine.AddIcon( name, fi.FullName );
+                                               MimeIconEngine.AddIcon( name, fileinfo [z].FullName );
                                        }
                                }
                        }
@@ -524,18 +651,31 @@ namespace System.Windows.Forms
                        MimeIconEngine.AddMimeTypeAndIconName( "desktop/desktop", "desktop" );
                        MimeIconEngine.AddMimeTypeAndIconName( "directory/home", "folder_home" );
                        MimeIconEngine.AddMimeTypeAndIconName( "network/network", "network" );
+                       MimeIconEngine.AddMimeTypeAndIconName( "recently/recently", "folder_man" );
+                       MimeIconEngine.AddMimeTypeAndIconName( "workplace/workplace", "system" );
+                       
+                       MimeIconEngine.AddMimeTypeAndIconName( "nfs/nfs", "nfs_mount" );
+                       MimeIconEngine.AddMimeTypeAndIconName( "smb/smb", "server" );
+                       
+                       MimeIconEngine.AddMimeTypeAndIconName( "harddisk/harddisk", "hdd_mount" );
+                       MimeIconEngine.AddMimeTypeAndIconName( "cdrom/cdrom", "cdrom_mount" );
+                       MimeIconEngine.AddMimeTypeAndIconName( "removable/removable", "usbpendrive_mount" );
                        
                        foreach ( string mime_path in mime_paths )
                        {
                                string[] directories = Directory.GetDirectories( mime_path );
                                
-                               foreach ( string d in directories )
+                               for (int i = 0; i < directories.Length; i++)
                                {
-                                       string[] files = Directory.GetFiles( d );
+                                       string[] files = Directory.GetFiles( directories [i] );
                                        
-                                       foreach ( string f in files )
+                                       for (int z = 0; z < files.Length; z++)
                                        {
-                                               ReadDotDesktop( f );
+                                           try {
+                                                       ReadDotDesktop( files [z] );
+                                               } catch {
+                                               // Ignore errors if the file can not be read.
+                                           }
                                        }
                                }
                        }
@@ -624,108 +764,399 @@ namespace System.Windows.Forms
                }
        }
        
-       // GnomeHandler uses the default gnome icon theme (many others are svg only)
        internal class GnomeHandler : PlatformMimeIconHandler
        {
+               string full_gnome_gconf_tree = Environment.GetFolderPath( Environment.SpecialFolder.Personal )
+               + "/"
+               + ".gconf/%gconf-tree.xml";
+               
+               bool is_svg_icon_theme = false;
+               
+               string main_icon_theme_path;
+               
+               StringCollection inherits_path_collection = new StringCollection ();
+               
                public override MimeExtensionHandlerStatus Start( )
                {
-                       if ( !CheckPlatformDirectories( ) )
-                               return mimeExtensionHandlerStatus;
+                       icon_theme = String.Empty;
                        
-                       CreateMimeTypeFromIconName( );
+                       if (!File.Exists (full_gnome_gconf_tree))
+                               full_gnome_gconf_tree = Environment.GetFolderPath( Environment.SpecialFolder.Personal )
+                                       + "/"
+                                       + ".gconf/desktop/gnome/interface/%gconf.xml";
                        
-                       ReadIcons( );
+                       GetIconThemeFromGConf ();
+                       
+                       if (!GetIconPaths ())
+                               return MimeExtensionHandlerStatus.NO_ICONS;
+                       
+                       if (!GetMainIconThemePath ())
+                               return MimeExtensionHandlerStatus.NO_ICONS;
+
+                       try {
+                               GetIconThemeInherits ();
+                       
+                               CreateUIIcons ();
+                       
+                               CreateMimeTypeIcons( );
+                       } catch (Exception e) {
+                               Console.Error.WriteLine ("Unable to start GNOME mime engine:");
+                               Console.Error.WriteLine (e);
+                               return MimeExtensionHandlerStatus.NO_GNOMECONFIG;
+                       }
+                       
+                       inherits_path_collection = null;
+                       icon_paths = null;
                        
                        return MimeExtensionHandlerStatus.OK;
                }
                
-               protected override bool CheckPlatformDirectories( )
+               private bool GetIconThemeFromGConf ()
                {
-                       // add more directories ???
-                       if ( Directory.Exists( "/opt/gnome/share/icons/gnome/48x48" ) )
-                       {
-                               icon_paths.Add( "/opt/gnome/share/icons/gnome/48x48/" );
-                       }
-                       else
-                       if ( Directory.Exists( "/usr/share/icons/gnome/48x48" ) )
-                       {
-                               icon_paths.Add( "/usr/share/icons/gnome/48x48/" );
+                       if (!File.Exists (full_gnome_gconf_tree))
+                               return false;
+                       
+                       try {
+                               bool found_icon_theme_in_xml = false;
+                               
+                               XmlTextReader xtr = new XmlTextReader (full_gnome_gconf_tree);
+                               
+                               while (xtr.Read ()) {
+                                       if (xtr.NodeType == XmlNodeType.Element && xtr.Name.ToUpper () == "ENTRY" && xtr.GetAttribute ("name") == "icon_theme") {
+                                               found_icon_theme_in_xml = true;
+                                       } else
+                                       if (xtr.NodeType == XmlNodeType.Element && xtr.Name.ToUpper () == "STRINGVALUE" && found_icon_theme_in_xml) {
+                                               xtr.Read ();
+                                               icon_theme = xtr.Value;
+                                               break;
+                                       }
+                               }
+                               xtr.Close ();
+                               
+                               if (icon_theme != String.Empty)
+                                       return true;
+                               else {
+                                       icon_theme = "gnome";
+                                       return false;
+                               }
+                       } catch (Exception) {
+                               return false;
                        }
+               }
+               
+               private bool GetIconPaths () 
+               {
+                       string global_icon_path = "";
+                       
+                       if (Directory.Exists ("/opt/gnome/share/icons"))
+                               global_icon_path = "/opt/gnome/share/icons";
                        else
-                       if ( Directory.Exists( "/usr/local/share/icons/gnome/48x48" ) )
-                       {
-                               icon_paths.Add( "/usr/local/share/icons/gnome/48x48/" );
-                       }
+                       if (Directory.Exists ("/usr/share/icons"))
+                               global_icon_path = "/usr/share/icons";
                        else
-                       {
-                               mimeExtensionHandlerStatus = MimeExtensionHandlerStatus.NO_ICONS;
+                       if (Directory.Exists ("/usr/local/share/icons"))
+                               global_icon_path = "/usr/local/share/icons";
+                       
+                       if (global_icon_path.Length > 0)
+                               icon_paths.Add (global_icon_path);
+                       
+                       if (Directory.Exists (Environment.GetFolderPath (Environment.SpecialFolder.Personal) + "/.icons"))
+                               icon_paths.Add (Environment.GetFolderPath (Environment.SpecialFolder.Personal) + "/.icons");
+                       
+                       if (icon_paths.Count == 0)
                                return false;
-                       }
                        
                        return true;
                }
                
-               private void CreateMimeTypeFromIconName( )
+               private bool GetMainIconThemePath ()
                {
-                       MimeIconEngine.AddMimeTypeAndIconName( "inode/directory", "gnome-fs-directory" );
-                       MimeIconEngine.AddMimeTypeAndIconName( "unknown/unknown", "gnome-fs-regular" );
-                       MimeIconEngine.AddMimeTypeAndIconName( "desktop/desktop", "gnome-fs-desktop" );
-                       MimeIconEngine.AddMimeTypeAndIconName( "directory/home", "gnome-fs-home" );
-                       MimeIconEngine.AddMimeTypeAndIconName( "network/network", "gnome-fs-network" );
+                       foreach (string path in icon_paths) {
+                               if (Directory.Exists (path + "/" + icon_theme)) {
+                                       main_icon_theme_path = path + "/" + icon_theme;
+                                       return true;
+                               }
+                       }
                        
-                       foreach ( string ip in icon_paths )
-                       {
-                               string[] files = Directory.GetFiles( ip + "mimetypes" );
+                       return false;
+               }
+               
+               private void GetIconThemeInherits ()
+               {
+                       inherits_path_collection.Add (main_icon_theme_path);
+                       GetIndexThemeInherits (main_icon_theme_path + "/" + "index.theme");
+               }
+               
+               private void GetIndexThemeInherits (string filename)
+               {
+                       StringCollection tmp_inherits = new StringCollection ();
+                       
+                       try {
+                               StreamReader sr = new StreamReader (filename);
                                
-                               foreach ( string file in files )
-                               {
-                                       string extension = Path.GetExtension( file );
+                               string line = sr.ReadLine ();
+                               
+                               while (line != null) {
+                                       if (line.IndexOf ("Inherits=") != -1) {
+                                               line = line.Trim ();
+                                               line = line.Replace ("Inherits=", "");
+                                               
+                                               line = line.Trim ();
+                                               
+                                               string[] split = line.Split (new char [] { ',' });
+                                               
+                                               tmp_inherits.AddRange (split);
+                                               break;
+                                       }
+                                       line = sr.ReadLine ();
+                               }
+                               
+                               sr.Close ();
+                       } catch (Exception) {
+                               
+                       }
+                       
+                       if (tmp_inherits.Count > 0) {
+                               foreach (string icon_theme in tmp_inherits) {
+                                       foreach (string path in icon_paths) {
+                                               if (Directory.Exists (path + "/" + icon_theme)) {
+                                                       if (!inherits_path_collection.Contains (path + "/" + icon_theme)) {
+                                                               inherits_path_collection.Add (path + "/" + icon_theme);
+                                                               
+                                                               if (File.Exists (path + "/" + icon_theme + "/" + "index.theme"))
+                                                                       GetIndexThemeInherits (path + "/" + icon_theme + "/" + "index.theme");
+                                                       }
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               
+               private void CreateUIIcons ()
+               {
+                       string resolv_path = ResolvePath (main_icon_theme_path);
+                       string default_gnome_path = "";
+                       
+                       // get the default gnome icon theme path
+                       foreach (string path in icon_paths)
+                               if (Directory.Exists (path + "/gnome")) {
+                                       default_gnome_path = path + "/gnome/48x48/";
+                                       break;
+                               }
+
+                       // use default gnome icon theme if there isn't a "/48x48" or "/scalable" dir
+                       // for the current theme                        
+                       if (resolv_path == String.Empty)
+                               resolv_path = default_gnome_path;
+                       
+                       Hashtable name_mime_hash = new Hashtable ();
+                       
+                       name_mime_hash ["gnome-fs-directory"] = "inode/directory";
+                       name_mime_hash ["gnome-fs-regular"] = "unknown/unknown";
+                       name_mime_hash ["gnome-fs-desktop"] = "desktop/desktop";
+                       name_mime_hash ["gnome-fs-home"] = "directory/home";
+                       name_mime_hash ["gnome-fs-network"] = "network/network";
+                       name_mime_hash ["gnome-fs-directory-accept"] = "recently/recently";
+                       name_mime_hash ["gnome-fs-client"] = "workplace/workplace";
+                       
+                       name_mime_hash ["gnome-fs-nfs"] = "nfs/nfs";
+                       name_mime_hash ["gnome-fs-smb"] = "smb/smb";
+                       
+                       name_mime_hash ["gnome-dev-cdrom"] = "cdrom/cdrom";
+                       name_mime_hash ["gnome-dev-harddisk"] = "harddisk/harddisk";
+                       name_mime_hash ["gnome-dev-removable"] = "removable/removable";
+                       
+                       int initial_name_mime_hash_count = name_mime_hash.Count;
+                       
+                       // first check the current icon theme path
+                       string[] dirs = Directory.GetDirectories (resolv_path);
+                       ArrayList objects = CheckAndAddUIIcons (dirs, name_mime_hash);
+                       
+                       if (objects.Count != name_mime_hash.Count) {
+                               // remove found icons
+                               foreach (object o in objects) {
+                                       name_mime_hash.Remove (o);
+                               }
+                               
+                               // check the default gnome path
+                               dirs = Directory.GetDirectories (default_gnome_path);
+                               objects = CheckAndAddUIIcons (dirs, name_mime_hash);
+                               
+                               //could be a kde icon theme, so we check kde icon names too
+                               if (objects.Count == initial_name_mime_hash_count) {
+                                       dirs = Directory.GetDirectories (resolv_path);
+                                       
+                                       name_mime_hash.Clear ();
+                                       name_mime_hash ["folder"] = "inode/directory";
+                                       name_mime_hash ["unknown"] = "unknown/unknown";
+                                       name_mime_hash ["desktop"] = "desktop/desktop";
+                                       name_mime_hash ["folder_home"] = "directory/home";
+                                       name_mime_hash ["network"] = "network/network";
+                                       name_mime_hash ["folder_man"] = "recently/recently";
+                                       name_mime_hash ["system"] = "workplace/workplace";
+                                       
+                                       name_mime_hash ["nfs_mount"] = "nfs/nfs";
+                                       name_mime_hash ["server"] = "smb/smb";
+                                       
+                                       name_mime_hash ["cdrom_mount"] = "cdrom/cdrom";
+                                       name_mime_hash ["hdd_mount"] = "harddisk/harddisk";
+                                       name_mime_hash ["usbpendrive_mount"] = "removable/removable";
+                                       
+                                       CheckAndAddUIIcons (dirs, name_mime_hash);
+                               }
+                       }
+               }
+               
+               private ArrayList CheckAndAddUIIcons (string[] dirs, Hashtable name_mime_hash)
+               {
+                       ArrayList al = new ArrayList (name_mime_hash.Count);
+                       
+                       string extension = is_svg_icon_theme ? "svg" : "png";
+                       
+                       for (int i = 0; i < dirs.Length; i++) {
+                               foreach (DictionaryEntry entry in name_mime_hash) {
+                                       string key = (string)entry.Key;
+                                       if (File.Exists (dirs [i] + "/" + key + "." + extension)) {
+                                               string value = (string)entry.Value;
+                                               
+                                               MimeIconEngine.AddMimeTypeAndIconName (value, key);
+                                               
+                                               if (!is_svg_icon_theme)
+                                                       MimeIconEngine.AddIcon (key, dirs [i] + "/" + key + "." + extension);
+                                               else
+                                                       MimeIconEngine.AddSVGIcon (key, dirs [i] + "/" + key + "." + extension);
+                                               
+                                               al.Add (entry.Key);
+                                       }
+                               }
+                       }
+                       
+                       return al;
+               }
+               
+               private void CreateMimeTypeIcons ()
+               {
+                       foreach (string ip in inherits_path_collection) {
+                               string path_to_use = ResolvePath (ip);
+                               
+                               if (path_to_use == String.Empty)
+                                       continue;
+                               
+                               if (!Directory.Exists (path_to_use + "mimetypes"))
+                                   continue;
+                               
+                               string[] files = Directory.GetFiles (path_to_use + "mimetypes");
+                               
+                               for (int z = 0; z < files.Length; z++) {
+                                       string extension = Path.GetExtension (files [z]);
                                        
-                                       if ( extension != ".png" )
+                                       if (!is_svg_icon_theme) {
+                                               if (extension != ".png")
+                                                       continue;
+                                       } else
+                                       if (extension != ".svg")
                                                continue;
                                        
-                                       string file_name = Path.GetFileNameWithoutExtension( file );
+                                       string file_name = Path.GetFileNameWithoutExtension (files [z]);
                                        
-                                       if ( !file_name.StartsWith( "gnome-mime-" ) )
+                                       if (!file_name.StartsWith ("gnome-mime-"))
                                                continue;
                                        
-                                       StringBuilder mime_type = new StringBuilder( file_name.Replace( "gnome-mime-", "" ) );
+                                       StringBuilder mime_type = new StringBuilder (file_name.Replace ("gnome-mime-", ""));
                                        
-                                       for ( int i = 0; i < mime_type.Length; i++ )
-                                               if ( mime_type[ i ] == '-' )
-                                               {
-                                                       mime_type[ i ] = '/';
+                                       for (int i = 0; i < mime_type.Length; i++)
+                                               if (mime_type [i] == '-') {
+                                                       mime_type [i] = '/';
                                                        break;
                                                }
                                        
-                                       MimeIconEngine.AddMimeTypeAndIconName( mime_type.ToString( ), file_name );
+                                       MimeIconEngine.AddMimeTypeAndIconName (mime_type.ToString (), file_name);
+                                       
+                                       if (!is_svg_icon_theme)
+                                               MimeIconEngine.AddIcon (file_name, files [z]);
+                                       else
+                                               MimeIconEngine.AddSVGIcon (file_name, files [z]);
                                }
                        }
                }
                
-               private void ReadIcons( )
+               private string ResolvePath (string path)
                {
-                       foreach ( string icon_path in icon_paths )
-                       {
-                               string[] directories = Directory.GetDirectories( icon_path );
-                               
-                               foreach ( string directory in directories )
-                               {
-                                       DirectoryInfo di = new DirectoryInfo( directory );
-                                       
-                                       FileInfo[] fileinfo = di.GetFiles( );
-                                       
-                                       foreach ( FileInfo fi in fileinfo )
-                                       {
-                                               if ( fi.Extension != ".png" )
-                                                       continue;
-                                               
-                                               string name = Path.GetFileNameWithoutExtension( fi.Name );
-                                               
-                                               MimeIconEngine.AddIcon( name, fi.FullName );
-                                       }
-                               }
+                       if (Directory.Exists (path + "/48x48")) {
+                               is_svg_icon_theme = false;
+                               return path + "/48x48/";
+                       }
+                       
+                       if (Directory.Exists (path + "/scalable")) {
+                               is_svg_icon_theme = true;
+                               return path + "/scalable/";
                        }
+                       
+                       return String.Empty;
+               }
+       }
+       
+       internal class SVGUtil {
+               [DllImport("librsvg-2.so")]
+               static extern IntPtr rsvg_pixbuf_from_file_at_size (string file_name, int  width, int  height, out IntPtr error);
+               
+               [DllImport("libgdk-x11-2.0.so")]
+               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);
+               
+               [DllImport("libglib-2.0.so")]
+               static extern void g_free (IntPtr mem);
+               
+               [DllImport("libgdk-x11-2.0.so")]
+               static extern bool gdk_init_check(out int argc, string argv);
+               
+               [DllImport("libgobject-2.0.so")]
+               static extern void g_object_unref (IntPtr nativeObject);
+               
+               static bool inited = false;
+               
+               static void Init () {
+                       int argc = 0;
+                       string argv = "";
+                       
+                       gdk_init_check (out argc, argv);
+                       
+                       inited = true;
+               }
+               
+               public static Image GetSVGasImage (string filename, int width, int height) {
+                       if (!inited)
+                               Init ();
+                       
+                       if (!File.Exists (filename))
+                               return null;
+                       IntPtr error = IntPtr.Zero;
+                       IntPtr pixbuf = rsvg_pixbuf_from_file_at_size (filename, width, height, out error);
+                       
+                       if (error != IntPtr.Zero)
+                               return null;
+                       
+                       error = IntPtr.Zero;
+                       IntPtr buffer;
+                       UIntPtr buffer_size_as_ptr;
+                       string type = "png";
+                       
+                       bool saved = gdk_pixbuf_save_to_buffer (pixbuf, out buffer, out buffer_size_as_ptr, type, out error, IntPtr.Zero);
+                       
+                       if (!saved)
+                               return null;
+                       
+                       int buffer_size = (int) (uint) buffer_size_as_ptr;
+                       byte[] result = new byte [buffer_size];
+                       Marshal.Copy (buffer, result, 0, (int) buffer_size);
+                       g_free (buffer);
+                       g_object_unref (pixbuf);
+                       
+                       Image image = null;
+                       using (MemoryStream s = new MemoryStream (result))
+                               image = Image.FromStream (s);
+                       
+                       return image;
                }
        }
 }