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
27 // short "how to" if you want to add an other platform handler, etc:
28 // - first add mime type names and icon names (best is without extension) to MimeIconEngine, for example:
29 // MimeIconEngine.AddMimeTypeAndIconName( "inode/directory", "gnome-fs-directory" );
30 // - next add the icon name (the same as used in AddMimeTypeAndIconName) and the full filename, for example:
31 // MimeIconEngine.AddIcon( "gnome-fs-directory", "/opt/gnome/share/icons/gnome/48x48/filesystems/gnome-fs-directory.png" );
32 // AddIcon adds the icon to the image lists SmallIconList and LargeIconList
33 // - provide always a "unknown/unknown" 'mime type' with a default icon for unkown mime types,
34 // "desktop/desktop" 'mime type' for the desktop icon, "directory/home" 'mime type for the home dir of the user and so on
35 // (look at the default platform handler)
38 // public static int GetIconIndexForFile( string full_filename )
39 // public static int GetIconIndexForMimeType( string mime_type )
40 // to get the image index in MimeIconEngine.SmallIcons and MimeIconEngine.LargeIcons
42 // public static Image GetIconForMimeTypeAndSize( string mime_type, Size size )
43 // to get the image itself for a mime type with a specific size
46 using System.Reflection;
48 using System.Collections;
49 using System.Collections.Specialized;
52 using System.Runtime.InteropServices;
55 namespace System.Windows.Forms
57 internal enum MimeExtensionHandlerStatus
66 internal enum EPlatformHandler
74 internal class ResourceImageLoader {
75 static Assembly assembly = typeof (ResourceImageLoader).Assembly;
77 static internal Bitmap Get (string name)
79 using (Stream stream = assembly.GetManifestResourceStream (name)){
81 Console.WriteLine ("Failed to read {0}", name);
85 return new Bitmap (stream);
90 internal class MimeIconEngine
92 public static ImageList SmallIcons = new ImageList();
93 public static ImageList LargeIcons = new ImageList();
95 private static EPlatformHandler platform = EPlatformHandler.Default;
97 private static IconIndexHash MimeTypeIconIndexHash = new IconIndexHash();
100 public string Fullname;
101 public IconPath (string path)
108 public string Fullname;
109 public SvgIconPath (string path)
115 private class IconIndexHash {
117 Hashtable hash = new Hashtable ();
119 private int LoadIcon (IconPath path)
121 Bitmap bmp = new Bitmap (path.Fullname);
123 int index = SmallIcons.Images.Add (bmp, Color.Transparent);
124 LargeIcons.Images.Add (bmp, Color.Transparent);
128 private int LoadSvgIcon (SvgIconPath path)
130 Image image = SVGUtil.GetSVGasImage (path.Fullname, 48, 48);
132 int index = SmallIcons.Images.Add (image, Color.Transparent);
133 LargeIcons.Images.Add (image, Color.Transparent);
137 private int LoadIcon (object path)
139 if (path is SvgIconPath)
140 return LoadSvgIcon ((SvgIconPath) path);
142 return LoadIcon ((IconPath) path);
145 public object this [object key] {
147 if (hash [key] == null)
149 else if (hash [key] is int)
152 hash [key] = LoadIcon (hash [key]);
157 public void Add (string name, object path)
162 public bool ContainsKey (string s)
164 return hash.ContainsKey (s);
168 private static NameValueCollection IconNameMimeTypeNameValueCollection = new NameValueCollection();
170 private static StringCollection added_icons = new StringCollection();
172 private static object lock_object = new Object();
174 static MimeIconEngine( )
176 // add some more aliases, kde for example uses other mime type names for some mime types...
177 Mime.Aliases.Add( "application/x-compressed-tar", "application/x-tgz" );
178 Mime.Aliases.Add( "application/x-bzip-compressed-tar", "application/x-tbz" );
179 Mime.Aliases.Add( "application/zip", "application/x-zip" );
180 Mime.Aliases.Add( "text/x-patch", "text/x-diff" );
182 SmallIcons.ColorDepth = ColorDepth.Depth32Bit;
183 SmallIcons.TransparentColor = Color.Transparent;
184 LargeIcons.ColorDepth = ColorDepth.Depth32Bit;
185 LargeIcons.TransparentColor = Color.Transparent;
187 string session = Environment.GetEnvironmentVariable( "DESKTOP_SESSION" );
189 if ( session != null )
191 session = session.ToUpper( );
193 if ( session == "DEFAULT" )
195 string helper = Environment.GetEnvironmentVariable( "KDE_FULL_SESSION" );
197 if ( helper != null )
201 helper = Environment.GetEnvironmentVariable( "GNOME_DESKTOP_SESSION_ID" );
203 if ( helper != null )
211 //Console.WriteLine( "Desktop session is: " + session );
213 PlatformMimeIconHandler platformMimeHandler = null;
215 if ( session == "KDE" )
217 SmallIcons.ImageSize = new Size( 24, 24 );
218 LargeIcons.ImageSize = new Size( 48, 48 );
220 platformMimeHandler = new KdeHandler( );
221 if ( platformMimeHandler.Start( ) == MimeExtensionHandlerStatus.OK )
223 platform = EPlatformHandler.KDE;
225 else // fallback to default
227 MimeIconEngine.LargeIcons.Images.Clear( );
228 MimeIconEngine.SmallIcons.Images.Clear( );
229 platformMimeHandler = new PlatformDefaultHandler( );
230 platformMimeHandler.Start( );
234 if ( session == "GNOME" )
236 SmallIcons.ImageSize = new Size( 24, 24 );
237 LargeIcons.ImageSize = new Size( 48, 48 );
239 platformMimeHandler = new GnomeHandler( );
240 if ( platformMimeHandler.Start( ) == MimeExtensionHandlerStatus.OK )
242 platform = EPlatformHandler.GNOME;
244 else // fallback to default
246 MimeIconEngine.LargeIcons.Images.Clear( );
247 MimeIconEngine.SmallIcons.Images.Clear( );
248 platformMimeHandler = new PlatformDefaultHandler( );
249 platformMimeHandler.Start( );
254 SmallIcons.ImageSize = new Size( 16, 16 );
255 LargeIcons.ImageSize = new Size( 48, 48 );
257 platformMimeHandler = new PlatformDefaultHandler( );
258 platformMimeHandler.Start( );
261 IconNameMimeTypeNameValueCollection = null;
265 public static int GetIconIndexForFile( string full_filename )
269 string mime_type = Mime.GetMimeTypeForFile( full_filename );
271 if ( platform == EPlatformHandler.Default )
273 if ( mime_type == "inode/directory" )
275 return (int)MimeTypeIconIndexHash[ "inode/directory" ];
279 return (int)MimeTypeIconIndexHash[ "unknown/unknown" ];
283 object oindex = GetIconIndex( mime_type );
285 if ( oindex == null )
286 oindex = MimeTypeIconIndexHash[ "unknown/unknown" ];
292 public static int GetIconIndexForMimeType( string mime_type )
296 if ( platform == EPlatformHandler.Default )
298 if (mime_type =="inode/directory")
300 return (int)MimeTypeIconIndexHash[ "inode/directory" ];
304 return (int)MimeTypeIconIndexHash[ "unknown/unknown" ];
308 object oindex = GetIconIndex( mime_type );
310 if ( oindex == null )
311 oindex = MimeTypeIconIndexHash[ "unknown/unknown" ];
317 public static Image GetIconForMimeTypeAndSize( string mime_type, Size size )
321 object oindex = GetIconIndex( mime_type );
323 if ( oindex == null )
324 oindex = MimeTypeIconIndexHash[ "unknown/unknown" ];
326 Bitmap bmp = new Bitmap( LargeIcons.Images[ (int)oindex ], size );
332 internal static void AddIcon( string name, string fullname )
334 if ( !CheckIfIconIsNeeded( name ) )
337 if ( added_icons.Contains( name ) )
340 added_icons.Add( name );
342 AddMimeTypeIconIndexHash( name, new IconPath (fullname) );
345 internal static void AddSVGIcon( string name, string fullname )
347 if ( !CheckIfIconIsNeeded( name ) )
350 if ( added_icons.Contains( name ) )
353 added_icons.Add( name );
355 AddMimeTypeIconIndexHash( name, new SvgIconPath (fullname) );
358 private static bool CheckIfIconIsNeeded( string name )
360 string mime_types = IconNameMimeTypeNameValueCollection[ name ];
362 if ( mime_types != null )
368 internal static void AddMimeTypeIconIndexHash( string name, object path_or_index )
370 string mime_type = IconNameMimeTypeNameValueCollection[ name ];
372 if ( mime_type == null )
375 string[] split = mime_type.Split( new char[] { ',' } );
377 for (int i = 0; i < split.Length; i++)
379 if ( MimeTypeIconIndexHash.ContainsKey( split[i] ) )
382 MimeTypeIconIndexHash.Add( split[i], path_or_index );
386 internal static void AddIconByImage( string name, Image image )
388 int index = SmallIcons.Images.Add( image, Color.Transparent );
389 LargeIcons.Images.Add( image, Color.Transparent );
391 AddMimeTypeIconIndexHash( name, index );
394 internal static void AddMimeTypeAndIconName( string mimetype, string iconname )
396 if ( iconname.Equals( String.Empty ) )
399 IconNameMimeTypeNameValueCollection.Add( iconname, mimetype );
402 private static object GetIconIndex( string mime_type )
404 object oindex = null;
406 if ( mime_type != null )
408 // first check if mime_type is available in the mimetype/icon hashtable
409 oindex = MimeTypeIconIndexHash[ mime_type ];
411 if ( oindex == null )
413 // it is not available, check if an alias exist for mime_type
414 string alias = Mime.GetMimeAlias( mime_type );
418 string[] split = alias.Split( new char[] { ',' } );
420 for (int i = 0; i < split.Length; i++)
422 oindex = MimeTypeIconIndexHash[ split[i] ];
424 if ( oindex != null )
429 // if oindex is still null check if mime_type is a sub class of an other mime type
430 string sub_class = Mime.SubClasses[ mime_type ];
432 if ( sub_class != null ) {
433 oindex = MimeTypeIconIndexHash[ sub_class ];
435 if ( oindex != null )
439 // last check, see if we find an entry for the main mime type class
440 string mime_class_main = mime_type.Substring( 0, mime_type.IndexOf( '/' ) );
441 return MimeTypeIconIndexHash[ mime_class_main ];
449 internal abstract class PlatformMimeIconHandler
451 protected StringCollection mime_paths = new StringCollection();
453 protected StringCollection icon_paths = new StringCollection();
455 protected string icon_theme = "";
457 protected MimeExtensionHandlerStatus mimeExtensionHandlerStatus = MimeExtensionHandlerStatus.OK;
459 public MimeExtensionHandlerStatus MimeExtensionHandlerStatus
462 return mimeExtensionHandlerStatus;
466 public abstract MimeExtensionHandlerStatus Start( );
468 // check, if icon, mime, etc., directories exist
469 protected virtual bool CheckPlatformDirectories( )
475 internal class PlatformDefaultHandler : PlatformMimeIconHandler
478 public override MimeExtensionHandlerStatus Start( )
480 MimeIconEngine.AddMimeTypeAndIconName( "unknown/unknown", "paper" );
481 MimeIconEngine.AddMimeTypeAndIconName( "inode/directory", "folder" );
482 MimeIconEngine.AddMimeTypeAndIconName( "desktop/desktop", "desktop" );
483 MimeIconEngine.AddMimeTypeAndIconName( "directory/home", "folder_with_paper" );
484 MimeIconEngine.AddMimeTypeAndIconName( "network/network", "monitor-planet" );
485 MimeIconEngine.AddMimeTypeAndIconName( "recently/recently", "last_open" );
486 MimeIconEngine.AddMimeTypeAndIconName( "workplace/workplace", "monitor-computer" );
488 MimeIconEngine.AddIconByImage( "folder", ResourceImageLoader.Get ("folder.png") );
489 MimeIconEngine.AddIconByImage( "paper", ResourceImageLoader.Get("text-x-generic.png") );
490 MimeIconEngine.AddIconByImage( "desktop", ResourceImageLoader.Get( "user-desktop.png" ) );
491 MimeIconEngine.AddIconByImage( "folder_with_paper", ResourceImageLoader.Get( "document-open.png" ) );
494 MimeIconEngine.AddIconByImage( "monitor-planet", ResourceImageLoader.Get( "document-open.png" ) );
495 MimeIconEngine.AddIconByImage( "last_open", ResourceImageLoader.Get( "document-open.png" ) );
496 MimeIconEngine.AddIconByImage( "monitor-computer", ResourceImageLoader.Get( "document-open.png" ) );
498 return MimeExtensionHandlerStatus.OK; // return always ok
502 internal class KdeHandler : PlatformMimeIconHandler
504 string full_kdegloabals_filename = Environment.GetFolderPath( Environment.SpecialFolder.Personal )
506 + ".kde/share/config/kdeglobals";
508 public override MimeExtensionHandlerStatus Start( )
510 if ( !ReadKdeglobals( ) )
511 return mimeExtensionHandlerStatus;
513 if ( !CheckPlatformDirectories( ) )
514 return mimeExtensionHandlerStatus;
516 // check if the theme is svg only
517 // if true, use theme "default.kde"
518 // don't know if that is available in every linux distribution
520 icon_theme = "default.kde";
522 // check if there is a /48x48 directory
524 icon_theme = "default.kde";
530 return mimeExtensionHandlerStatus;
533 private bool SVGOnly( )
535 // check only the first path in icon_paths
536 if ( icon_paths.Count > 0 )
538 string icon_path = icon_paths[ 0 ] + icon_theme;
539 string[] dirs = Directory.GetDirectories( icon_path );
541 if ( dirs.Length == 1 && dirs[ 0 ] == "scalable" )
548 private bool No48x48( )
550 // check only the first path in icon_paths
551 if ( icon_paths.Count > 0 )
553 string icon_path = icon_paths[ 0 ] + icon_theme;
554 string[] dirs = Directory.GetDirectories( icon_path );
556 for (int i = 0; i < dirs.Length; i++)
558 if ( dirs[i].EndsWith( "48x48" ) )
566 protected override bool CheckPlatformDirectories( )
568 bool icons_found = false;
571 if ( Directory.Exists( "/opt/kde3/share/icons/default.kde" ) )
573 icon_paths.Add( "/opt/kde3/share/icons" + "/" );
577 if ( Directory.Exists( "/usr/share/icons/default.kde" ) )
579 icon_paths.Add( "/usr/share/icons" + "/" );
583 if ( Directory.Exists( "/usr/local/share/icons/default.kde" ) )
585 icon_paths.Add( "/usr/local/share/icons" + "/" );
591 mimeExtensionHandlerStatus = MimeExtensionHandlerStatus.NO_ICONS;
595 bool mimelnk_found = false;
597 if ( Directory.Exists( "/usr/share/mimelnk" ) )
599 mime_paths.Add( "/usr/share/mimelnk" + "/" );
600 mimelnk_found = true;
603 if ( Directory.Exists( "/usr/local/share/mimelnk" ) )
605 mime_paths.Add( "/usr/local/share/mimelnk" + "/" );
606 mimelnk_found = true;
609 if ( Directory.Exists( "/opt/kde3/share/mimelnk" ) )
611 mime_paths.Add( "/opt/kde3/share/mimelnk" + "/" );
612 mimelnk_found = true;
615 if ( !mimelnk_found )
617 mimeExtensionHandlerStatus = MimeExtensionHandlerStatus.NO_MIMELNK;
624 private void ReadIcons( )
626 foreach ( string icon_path_in in icon_paths )
628 string icon_path = icon_path_in + icon_theme + "/48x48";
630 string[] directories = Directory.GetDirectories( icon_path );
632 for (int i = 0; i < directories.Length; i++)
634 DirectoryInfo di = new DirectoryInfo( directories [i] );
636 FileInfo[] fileinfo = di.GetFiles( );
638 for (int z = 0; z < fileinfo.Length; z++)
640 string name = Path.GetFileNameWithoutExtension( fileinfo [z].Name );
642 MimeIconEngine.AddIcon( name, fileinfo [z].FullName );
648 private void ReadMimetypes( )
650 MimeIconEngine.AddMimeTypeAndIconName( "unknown/unknown", "unknown" );
651 MimeIconEngine.AddMimeTypeAndIconName( "desktop/desktop", "desktop" );
652 MimeIconEngine.AddMimeTypeAndIconName( "directory/home", "folder_home" );
653 MimeIconEngine.AddMimeTypeAndIconName( "network/network", "network" );
654 MimeIconEngine.AddMimeTypeAndIconName( "recently/recently", "folder_man" );
655 MimeIconEngine.AddMimeTypeAndIconName( "workplace/workplace", "system" );
657 MimeIconEngine.AddMimeTypeAndIconName( "nfs/nfs", "nfs_mount" );
658 MimeIconEngine.AddMimeTypeAndIconName( "smb/smb", "server" );
660 MimeIconEngine.AddMimeTypeAndIconName( "harddisk/harddisk", "hdd_mount" );
661 MimeIconEngine.AddMimeTypeAndIconName( "cdrom/cdrom", "cdrom_mount" );
662 MimeIconEngine.AddMimeTypeAndIconName( "removable/removable", "usbpendrive_mount" );
664 foreach ( string mime_path in mime_paths )
666 string[] directories = Directory.GetDirectories( mime_path );
668 for (int i = 0; i < directories.Length; i++)
670 string[] files = Directory.GetFiles( directories [i] );
672 for (int z = 0; z < files.Length; z++)
675 ReadDotDesktop( files [z] );
677 // Ignore errors if the file can not be read.
684 private void ReadDotDesktop( string filename )
686 StreamReader sr = new StreamReader( filename );
688 string line = sr.ReadLine( );
690 string icon_name = "";
692 string mime_type = "";
694 bool have_icon = false;
695 bool have_mimetype = false;
697 while ( line != null )
701 if ( line.StartsWith( "Icon" ) )
703 icon_name = line.Substring( line.IndexOf( '=' ) + 1 );
704 icon_name = icon_name.Trim( );
710 if ( line.StartsWith( "MimeType" ) )
712 mime_type = line.Substring( line.IndexOf( '=' ) + 1 );
713 mime_type = mime_type.Trim( );
716 have_mimetype = true;
719 line = sr.ReadLine( );
724 MimeIconEngine.AddMimeTypeAndIconName( mime_type, icon_name );
727 private bool ReadKdeglobals( )
729 if ( !File.Exists( full_kdegloabals_filename ) )
731 mimeExtensionHandlerStatus = MimeExtensionHandlerStatus.NO_KDEGLOBALS;
736 StreamReader sr = new StreamReader( full_kdegloabals_filename );
738 string line = sr.ReadLine( );
740 while ( line != null )
742 if ( line.IndexOf( "[Icons]" ) != -1 )
744 line = sr.ReadLine( );
746 if ( line != null && line.IndexOf( "Theme" ) != -1 )
750 icon_theme = line.Substring( line.IndexOf( '=' ) + 1 );
752 icon_theme = icon_theme.Trim( );
758 line = sr.ReadLine( );
767 internal class GnomeHandler : PlatformMimeIconHandler
769 string full_gnome_gconf_tree = Environment.GetFolderPath( Environment.SpecialFolder.Personal )
771 + ".gconf/%gconf-tree.xml";
773 bool is_svg_icon_theme = false;
775 string main_icon_theme_path;
777 StringCollection inherits_path_collection = new StringCollection ();
779 public override MimeExtensionHandlerStatus Start( )
781 icon_theme = String.Empty;
783 if (!File.Exists (full_gnome_gconf_tree))
784 full_gnome_gconf_tree = Environment.GetFolderPath( Environment.SpecialFolder.Personal )
786 + ".gconf/desktop/gnome/interface/%gconf.xml";
788 GetIconThemeFromGConf ();
790 if (!GetIconPaths ())
791 return MimeExtensionHandlerStatus.NO_ICONS;
793 if (!GetMainIconThemePath ())
794 return MimeExtensionHandlerStatus.NO_ICONS;
797 GetIconThemeInherits ();
801 CreateMimeTypeIcons( );
802 } catch (Exception e) {
803 Console.Error.WriteLine ("Unable to start GNOME mime engine:");
804 Console.Error.WriteLine (e);
805 return MimeExtensionHandlerStatus.NO_GNOMECONFIG;
808 inherits_path_collection = null;
811 return MimeExtensionHandlerStatus.OK;
814 private bool GetIconThemeFromGConf ()
816 if (!File.Exists (full_gnome_gconf_tree))
820 bool found_icon_theme_in_xml = false;
822 XmlTextReader xtr = new XmlTextReader (full_gnome_gconf_tree);
824 while (xtr.Read ()) {
825 if (xtr.NodeType == XmlNodeType.Element && xtr.Name.ToUpper () == "ENTRY" && xtr.GetAttribute ("name") == "icon_theme") {
826 found_icon_theme_in_xml = true;
828 if (xtr.NodeType == XmlNodeType.Element && xtr.Name.ToUpper () == "STRINGVALUE" && found_icon_theme_in_xml) {
830 icon_theme = xtr.Value;
836 if (icon_theme != String.Empty)
839 icon_theme = "gnome";
842 } catch (Exception) {
847 private bool GetIconPaths ()
849 string global_icon_path = "";
851 if (Directory.Exists ("/opt/gnome/share/icons"))
852 global_icon_path = "/opt/gnome/share/icons";
854 if (Directory.Exists ("/usr/share/icons"))
855 global_icon_path = "/usr/share/icons";
857 if (Directory.Exists ("/usr/local/share/icons"))
858 global_icon_path = "/usr/local/share/icons";
860 if (global_icon_path.Length > 0)
861 icon_paths.Add (global_icon_path);
863 if (Directory.Exists (Environment.GetFolderPath (Environment.SpecialFolder.Personal) + "/.icons"))
864 icon_paths.Add (Environment.GetFolderPath (Environment.SpecialFolder.Personal) + "/.icons");
866 if (icon_paths.Count == 0)
872 private bool GetMainIconThemePath ()
874 foreach (string path in icon_paths) {
875 if (Directory.Exists (path + "/" + icon_theme)) {
876 main_icon_theme_path = path + "/" + icon_theme;
884 private void GetIconThemeInherits ()
886 inherits_path_collection.Add (main_icon_theme_path);
887 GetIndexThemeInherits (main_icon_theme_path + "/" + "index.theme");
890 private void GetIndexThemeInherits (string filename)
892 StringCollection tmp_inherits = new StringCollection ();
895 StreamReader sr = new StreamReader (filename);
897 string line = sr.ReadLine ();
899 while (line != null) {
900 if (line.IndexOf ("Inherits=") != -1) {
902 line = line.Replace ("Inherits=", "");
906 string[] split = line.Split (new char [] { ',' });
908 tmp_inherits.AddRange (split);
911 line = sr.ReadLine ();
915 } catch (Exception) {
919 if (tmp_inherits.Count > 0) {
920 foreach (string icon_theme in tmp_inherits) {
921 foreach (string path in icon_paths) {
922 if (Directory.Exists (path + "/" + icon_theme)) {
923 if (!inherits_path_collection.Contains (path + "/" + icon_theme)) {
924 inherits_path_collection.Add (path + "/" + icon_theme);
926 if (File.Exists (path + "/" + icon_theme + "/" + "index.theme"))
927 GetIndexThemeInherits (path + "/" + icon_theme + "/" + "index.theme");
936 private void CreateUIIcons ()
938 string resolv_path = ResolvePath (main_icon_theme_path);
939 string default_gnome_path = "";
941 // get the default gnome icon theme path
942 foreach (string path in icon_paths)
943 if (Directory.Exists (path + "/gnome")) {
944 default_gnome_path = path + "/gnome/48x48/";
948 // use default gnome icon theme if there isn't a "/48x48" or "/scalable" dir
949 // for the current theme
950 if (resolv_path == String.Empty)
951 resolv_path = default_gnome_path;
953 Hashtable name_mime_hash = new Hashtable ();
955 name_mime_hash ["gnome-fs-directory"] = "inode/directory";
956 name_mime_hash ["gnome-fs-regular"] = "unknown/unknown";
957 name_mime_hash ["gnome-fs-desktop"] = "desktop/desktop";
958 name_mime_hash ["gnome-fs-home"] = "directory/home";
959 name_mime_hash ["gnome-fs-network"] = "network/network";
960 name_mime_hash ["gnome-fs-directory-accept"] = "recently/recently";
961 name_mime_hash ["gnome-fs-client"] = "workplace/workplace";
963 name_mime_hash ["gnome-fs-nfs"] = "nfs/nfs";
964 name_mime_hash ["gnome-fs-smb"] = "smb/smb";
966 name_mime_hash ["gnome-dev-cdrom"] = "cdrom/cdrom";
967 name_mime_hash ["gnome-dev-harddisk"] = "harddisk/harddisk";
968 name_mime_hash ["gnome-dev-removable"] = "removable/removable";
970 int initial_name_mime_hash_count = name_mime_hash.Count;
972 // first check the current icon theme path
973 string[] dirs = Directory.GetDirectories (resolv_path);
974 ArrayList objects = CheckAndAddUIIcons (dirs, name_mime_hash);
976 if (objects.Count != name_mime_hash.Count) {
977 // remove found icons
978 foreach (object o in objects) {
979 name_mime_hash.Remove (o);
982 // check the default gnome path
983 dirs = Directory.GetDirectories (default_gnome_path);
984 objects = CheckAndAddUIIcons (dirs, name_mime_hash);
986 //could be a kde icon theme, so we check kde icon names too
987 if (objects.Count == initial_name_mime_hash_count) {
988 dirs = Directory.GetDirectories (resolv_path);
990 name_mime_hash.Clear ();
991 name_mime_hash ["folder"] = "inode/directory";
992 name_mime_hash ["unknown"] = "unknown/unknown";
993 name_mime_hash ["desktop"] = "desktop/desktop";
994 name_mime_hash ["folder_home"] = "directory/home";
995 name_mime_hash ["network"] = "network/network";
996 name_mime_hash ["folder_man"] = "recently/recently";
997 name_mime_hash ["system"] = "workplace/workplace";
999 name_mime_hash ["nfs_mount"] = "nfs/nfs";
1000 name_mime_hash ["server"] = "smb/smb";
1002 name_mime_hash ["cdrom_mount"] = "cdrom/cdrom";
1003 name_mime_hash ["hdd_mount"] = "harddisk/harddisk";
1004 name_mime_hash ["usbpendrive_mount"] = "removable/removable";
1006 CheckAndAddUIIcons (dirs, name_mime_hash);
1011 private ArrayList CheckAndAddUIIcons (string[] dirs, Hashtable name_mime_hash)
1013 ArrayList al = new ArrayList (name_mime_hash.Count);
1015 string extension = is_svg_icon_theme ? "svg" : "png";
1017 for (int i = 0; i < dirs.Length; i++) {
1018 foreach (DictionaryEntry entry in name_mime_hash) {
1019 string key = (string)entry.Key;
1020 if (File.Exists (dirs [i] + "/" + key + "." + extension)) {
1021 string value = (string)entry.Value;
1023 MimeIconEngine.AddMimeTypeAndIconName (value, key);
1025 if (!is_svg_icon_theme)
1026 MimeIconEngine.AddIcon (key, dirs [i] + "/" + key + "." + extension);
1028 MimeIconEngine.AddSVGIcon (key, dirs [i] + "/" + key + "." + extension);
1038 private void CreateMimeTypeIcons ()
1040 foreach (string ip in inherits_path_collection) {
1041 string path_to_use = ResolvePath (ip);
1043 if (path_to_use == String.Empty)
1046 if (!Directory.Exists (path_to_use + "mimetypes"))
1049 string[] files = Directory.GetFiles (path_to_use + "mimetypes");
1051 for (int z = 0; z < files.Length; z++) {
1052 string extension = Path.GetExtension (files [z]);
1054 if (!is_svg_icon_theme) {
1055 if (extension != ".png")
1058 if (extension != ".svg")
1061 string file_name = Path.GetFileNameWithoutExtension (files [z]);
1063 if (!file_name.StartsWith ("gnome-mime-"))
1066 StringBuilder mime_type = new StringBuilder (file_name.Replace ("gnome-mime-", ""));
1068 for (int i = 0; i < mime_type.Length; i++)
1069 if (mime_type [i] == '-') {
1070 mime_type [i] = '/';
1074 MimeIconEngine.AddMimeTypeAndIconName (mime_type.ToString (), file_name);
1076 if (!is_svg_icon_theme)
1077 MimeIconEngine.AddIcon (file_name, files [z]);
1079 MimeIconEngine.AddSVGIcon (file_name, files [z]);
1084 private string ResolvePath (string path)
1086 if (Directory.Exists (path + "/48x48")) {
1087 is_svg_icon_theme = false;
1088 return path + "/48x48/";
1091 if (Directory.Exists (path + "/scalable")) {
1092 is_svg_icon_theme = true;
1093 return path + "/scalable/";
1096 return String.Empty;
1100 internal class SVGUtil {
1101 [DllImport("librsvg-2.so")]
1102 static extern IntPtr rsvg_pixbuf_from_file_at_size (string file_name, int width, int height, out IntPtr error);
1104 [DllImport("libgdk-x11-2.0.so")]
1105 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);
1107 [DllImport("libglib-2.0.so")]
1108 static extern void g_free (IntPtr mem);
1110 [DllImport("libgdk-x11-2.0.so")]
1111 static extern bool gdk_init_check(out int argc, string argv);
1113 [DllImport("libgobject-2.0.so")]
1114 static extern void g_object_unref (IntPtr nativeObject);
1116 static bool inited = false;
1118 static void Init () {
1122 gdk_init_check (out argc, argv);
1127 public static Image GetSVGasImage (string filename, int width, int height) {
1131 if (!File.Exists (filename))
1133 IntPtr error = IntPtr.Zero;
1134 IntPtr pixbuf = rsvg_pixbuf_from_file_at_size (filename, width, height, out error);
1136 if (error != IntPtr.Zero)
1139 error = IntPtr.Zero;
1141 UIntPtr buffer_size_as_ptr;
1142 string type = "png";
1144 bool saved = gdk_pixbuf_save_to_buffer (pixbuf, out buffer, out buffer_size_as_ptr, type, out error, IntPtr.Zero);
1149 int buffer_size = (int) (uint) buffer_size_as_ptr;
1150 byte[] result = new byte [buffer_size];
1151 Marshal.Copy (buffer, result, 0, (int) buffer_size);
1153 g_object_unref (pixbuf);
1156 using (MemoryStream s = new MemoryStream (result))
1157 image = Image.FromStream (s);