// Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Copyright (c) 2005 Novell, Inc. (http://www.novell.com) // // Authors: // // Alexander Olk xenomorph2@onlinehome.de // // short "how to" if you want to add an other platform handler, etc: // - first add mime type names and icon names (best is without extension) to MimeIconEngine, for example: // MimeIconEngine.AddMimeTypeAndIconName( "inode/directory", "gnome-fs-directory" ); // - next add the icon name (the same as used in AddMimeTypeAndIconName) and the full filename, for example: // MimeIconEngine.AddIcon( "gnome-fs-directory", "/opt/gnome/share/icons/gnome/48x48/filesystems/gnome-fs-directory.png" ); // AddIcon adds the icon to the image lists SmallIconList and LargeIconList // - provide always a "unknown/unknown" 'mime type' with a default icon for unkown mime types, // "desktop/desktop" 'mime type' for the desktop icon, "directory/home" 'mime type for the home dir of the user and so on // (look at the default platform handler) // // use // public static int GetIconIndexForFile( string full_filename ) // public static int GetIconIndexForMimeType( string mime_type ) // to get the image index in MimeIconEngine.SmallIcons and MimeIconEngine.LargeIcons // use // public static Image GetIconForMimeTypeAndSize( string mime_type, Size size ) // 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 { internal enum MimeExtensionHandlerStatus { OK, NO_KDEGLOBALS, NO_GNOMECONFIG, NO_ICONS, NO_MIMELNK } internal enum EPlatformHandler { Default, KDE, 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 EPlatformHandler platform = EPlatformHandler.Default; 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(); private static object lock_object = new Object(); static MimeIconEngine( ) { // add some more aliases, kde for example uses other mime type names for some mime types... 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; LargeIcons.ColorDepth = ColorDepth.Depth32Bit; LargeIcons.TransparentColor = Color.Transparent; string session = Environment.GetEnvironmentVariable( "DESKTOP_SESSION" ); if ( session != null ) { session = session.ToUpper( ); if ( session == "DEFAULT" ) { string helper = Environment.GetEnvironmentVariable( "KDE_FULL_SESSION" ); if ( helper != null ) session = "KDE"; else { helper = Environment.GetEnvironmentVariable( "GNOME_DESKTOP_SESSION_ID" ); if ( helper != null ) session = "GNOME"; } } } else session = ""; //Console.WriteLine( "Desktop session is: " + session ); PlatformMimeIconHandler platformMimeHandler = null; if ( session == "KDE" ) { SmallIcons.ImageSize = new Size( 24, 24 ); LargeIcons.ImageSize = new Size( 48, 48 ); platformMimeHandler = new KdeHandler( ); if ( platformMimeHandler.Start( ) == MimeExtensionHandlerStatus.OK ) { platform = EPlatformHandler.KDE; } else // fallback to default { MimeIconEngine.LargeIcons.Images.Clear( ); MimeIconEngine.SmallIcons.Images.Clear( ); platformMimeHandler = new PlatformDefaultHandler( ); platformMimeHandler.Start( ); } } else if ( session == "GNOME" ) { SmallIcons.ImageSize = new Size( 24, 24 ); LargeIcons.ImageSize = new Size( 48, 48 ); platformMimeHandler = new GnomeHandler( ); if ( platformMimeHandler.Start( ) == MimeExtensionHandlerStatus.OK ) { platform = EPlatformHandler.GNOME; } else // fallback to default { MimeIconEngine.LargeIcons.Images.Clear( ); MimeIconEngine.SmallIcons.Images.Clear( ); platformMimeHandler = new PlatformDefaultHandler( ); platformMimeHandler.Start( ); } } else { SmallIcons.ImageSize = new Size( 16, 16 ); LargeIcons.ImageSize = new Size( 48, 48 ); platformMimeHandler = new PlatformDefaultHandler( ); platformMimeHandler.Start( ); } IconNameMimeTypeNameValueCollection = null; added_icons = null; } public static int GetIconIndexForFile( string full_filename ) { lock ( lock_object ) { string mime_type = Mime.GetMimeTypeForFile( full_filename ); if ( platform == EPlatformHandler.Default ) { if ( mime_type == "inode/directory" ) { return (int)MimeTypeIconIndexHash[ "inode/directory" ]; } else { return (int)MimeTypeIconIndexHash[ "unknown/unknown" ]; } } object oindex = GetIconIndex( mime_type ); if ( oindex == null ) oindex = MimeTypeIconIndexHash[ "unknown/unknown" ]; return (int)oindex; } } public static int GetIconIndexForMimeType( string mime_type ) { lock ( lock_object ) { if ( platform == EPlatformHandler.Default ) { if (mime_type =="inode/directory") { return (int)MimeTypeIconIndexHash[ "inode/directory" ]; } else { return (int)MimeTypeIconIndexHash[ "unknown/unknown" ]; } } object oindex = GetIconIndex( mime_type ); if ( oindex == null ) oindex = MimeTypeIconIndexHash[ "unknown/unknown" ]; return (int)oindex; } } public static Image GetIconForMimeTypeAndSize( string mime_type, Size size ) { lock ( lock_object ) { object oindex = GetIconIndex( mime_type ); if ( oindex == null ) oindex = MimeTypeIconIndexHash[ "unknown/unknown" ]; Bitmap bmp = new Bitmap( LargeIcons.Images[ (int)oindex ], size ); return bmp; } } internal static void AddIcon( string name, string fullname ) { if ( !CheckIfIconIsNeeded( name ) ) return; if ( added_icons.Contains( name ) ) return; added_icons.Add( name ); AddMimeTypeIconIndexHash( name, new IconPath (fullname) ); } internal static void AddSVGIcon( string name, string fullname ) { if ( !CheckIfIconIsNeeded( name ) ) return; if ( added_icons.Contains( name ) ) return; added_icons.Add( name ); AddMimeTypeIconIndexHash( name, new SvgIconPath (fullname) ); } private static bool CheckIfIconIsNeeded( string name ) { string mime_types = IconNameMimeTypeNameValueCollection[ name ]; if ( mime_types != null ) return true; return false; } internal static void AddMimeTypeIconIndexHash( string name, object path_or_index ) { string mime_type = IconNameMimeTypeNameValueCollection[ name ]; if ( mime_type == null ) return; string[] split = mime_type.Split( new char[] { ',' } ); for (int i = 0; i < split.Length; i++) { if ( MimeTypeIconIndexHash.ContainsKey( split[i] ) ) continue; MimeTypeIconIndexHash.Add( split[i], path_or_index ); } } internal static void AddIconByImage( string name, Image image ) { int index = SmallIcons.Images.Add( image, Color.Transparent ); LargeIcons.Images.Add( image, Color.Transparent ); AddMimeTypeIconIndexHash( name, index ); } internal static void AddMimeTypeAndIconName( string mimetype, string iconname ) { if ( iconname.Equals( String.Empty ) ) return; IconNameMimeTypeNameValueCollection.Add( iconname, mimetype ); } private static object GetIconIndex( string mime_type ) { object oindex = null; if ( mime_type != null ) { // first check if mime_type is available in the mimetype/icon hashtable oindex = MimeTypeIconIndexHash[ mime_type ]; if ( oindex == null ) { // it is not available, check if an alias exist for mime_type string alias = Mime.GetMimeAlias( mime_type ); if ( alias != null ) { string[] split = alias.Split( new char[] { ',' } ); for (int i = 0; i < split.Length; i++) { oindex = MimeTypeIconIndexHash[ split[i] ]; if ( oindex != null ) return oindex; } } // if oindex is still null check if mime_type is a sub class of an other mime type string sub_class = Mime.SubClasses[ mime_type ]; 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 ]; } } return oindex; } } internal abstract class PlatformMimeIconHandler { protected StringCollection mime_paths = new StringCollection(); protected StringCollection icon_paths = new StringCollection(); protected string icon_theme = ""; protected MimeExtensionHandlerStatus mimeExtensionHandlerStatus = MimeExtensionHandlerStatus.OK; public MimeExtensionHandlerStatus MimeExtensionHandlerStatus { get { return mimeExtensionHandlerStatus; } } public abstract MimeExtensionHandlerStatus Start( ); // check, if icon, mime, etc., directories exist protected virtual bool CheckPlatformDirectories( ) { return true; } } internal class PlatformDefaultHandler : PlatformMimeIconHandler { public override MimeExtensionHandlerStatus Start( ) { MimeIconEngine.AddMimeTypeAndIconName( "unknown/unknown", "paper" ); MimeIconEngine.AddMimeTypeAndIconName( "inode/directory", "folder" ); 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", ResourceImageLoader.Get ("folder") ); MimeIconEngine.AddIconByImage( "paper", ResourceImageLoader.Get("text-x-generic") ); MimeIconEngine.AddIconByImage( "desktop", ResourceImageLoader.Get( "user-desktop" ) ); MimeIconEngine.AddIconByImage( "folder_with_paper", ResourceImageLoader.Get( "document-open" ) ); // fix MimeIconEngine.AddIconByImage( "monitor-planet", ResourceImageLoader.Get( "document-open" ) ); MimeIconEngine.AddIconByImage( "last_open", ResourceImageLoader.Get( "document-open" ) ); MimeIconEngine.AddIconByImage( "monitor-computer", ResourceImageLoader.Get( "document-open" ) ); return MimeExtensionHandlerStatus.OK; // return always ok } } internal class KdeHandler : PlatformMimeIconHandler { string full_kdegloabals_filename = Environment.GetFolderPath( Environment.SpecialFolder.Personal ) + "/" + ".kde/share/config/kdeglobals"; public override MimeExtensionHandlerStatus Start( ) { if ( !ReadKdeglobals( ) ) return mimeExtensionHandlerStatus; if ( !CheckPlatformDirectories( ) ) return mimeExtensionHandlerStatus; // check if the theme is svg only // if true, use theme "default.kde" // don't know if that is available in every linux distribution if ( SVGOnly( ) ) icon_theme = "default.kde"; else // check if there is a /48x48 directory if( No48x48( ) ) icon_theme = "default.kde"; ReadMimetypes( ); ReadIcons( ); return mimeExtensionHandlerStatus; } private bool SVGOnly( ) { // 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 ); if ( dirs.Length == 1 && dirs[ 0 ] == "scalable" ) return true; } 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; // default icon dirs if ( Directory.Exists( "/opt/kde3/share/icons/default.kde" ) ) { icon_paths.Add( "/opt/kde3/share/icons" + "/" ); icons_found = true; } else if ( Directory.Exists( "/usr/share/icons/default.kde" ) ) { icon_paths.Add( "/usr/share/icons" + "/" ); icons_found = true; } else if ( Directory.Exists( "/usr/local/share/icons/default.kde" ) ) { icon_paths.Add( "/usr/local/share/icons" + "/" ); icons_found = true; } else if ( !icons_found ) { mimeExtensionHandlerStatus = MimeExtensionHandlerStatus.NO_ICONS; return false; } bool mimelnk_found = false; if ( Directory.Exists( "/usr/share/mimelnk" ) ) { mime_paths.Add( "/usr/share/mimelnk" + "/" ); mimelnk_found = true; } if ( Directory.Exists( "/usr/local/share/mimelnk" ) ) { mime_paths.Add( "/usr/local/share/mimelnk" + "/" ); mimelnk_found = true; } if ( Directory.Exists( "/opt/kde3/share/mimelnk" ) ) { mime_paths.Add( "/opt/kde3/share/mimelnk" + "/" ); mimelnk_found = true; } if ( !mimelnk_found ) { mimeExtensionHandlerStatus = MimeExtensionHandlerStatus.NO_MIMELNK; return false; } return true; } private void ReadIcons( ) { foreach ( string icon_path_in in icon_paths ) { string icon_path = icon_path_in + icon_theme + "/48x48"; string[] directories = Directory.GetDirectories( icon_path ); for (int i = 0; i < directories.Length; i++) { DirectoryInfo di = new DirectoryInfo( directories [i] ); FileInfo[] fileinfo = di.GetFiles( ); for (int z = 0; z < fileinfo.Length; z++) { string name = Path.GetFileNameWithoutExtension( fileinfo [z].Name ); MimeIconEngine.AddIcon( name, fileinfo [z].FullName ); } } } } private void ReadMimetypes( ) { MimeIconEngine.AddMimeTypeAndIconName( "unknown/unknown", "unknown" ); 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 ); for (int i = 0; i < directories.Length; i++) { string[] files = Directory.GetFiles( directories [i] ); for (int z = 0; z < files.Length; z++) { try { ReadDotDesktop( files [z] ); } catch { // Ignore errors if the file can not be read. } } } } } private void ReadDotDesktop( string filename ) { StreamReader sr = new StreamReader( filename ); string line = sr.ReadLine( ); string icon_name = ""; string mime_type = ""; bool have_icon = false; bool have_mimetype = false; while ( line != null ) { line = line.Trim( ); if ( line.StartsWith( "Icon" ) ) { icon_name = line.Substring( line.IndexOf( '=' ) + 1 ); icon_name = icon_name.Trim( ); if ( have_mimetype ) break; have_icon = true; } else if ( line.StartsWith( "MimeType" ) ) { mime_type = line.Substring( line.IndexOf( '=' ) + 1 ); mime_type = mime_type.Trim( ); if ( have_icon ) break; have_mimetype = true; } line = sr.ReadLine( ); } sr.Close( ); MimeIconEngine.AddMimeTypeAndIconName( mime_type, icon_name ); } private bool ReadKdeglobals( ) { if ( !File.Exists( full_kdegloabals_filename ) ) { mimeExtensionHandlerStatus = MimeExtensionHandlerStatus.NO_KDEGLOBALS; return false; } StreamReader sr = new StreamReader( full_kdegloabals_filename ); string line = sr.ReadLine( ); while ( line != null ) { if ( line.IndexOf( "[Icons]" ) != -1 ) { line = sr.ReadLine( ); if ( line != null && line.IndexOf( "Theme" ) != -1 ) { line = line.Trim( ); icon_theme = line.Substring( line.IndexOf( '=' ) + 1 ); icon_theme = icon_theme.Trim( ); break; } } line = sr.ReadLine( ); } sr.Close( ); return true; } } 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( ) { icon_theme = String.Empty; if (!File.Exists (full_gnome_gconf_tree)) full_gnome_gconf_tree = Environment.GetFolderPath( Environment.SpecialFolder.Personal ) + "/" + ".gconf/desktop/gnome/interface/%gconf.xml"; 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; } private bool GetIconThemeFromGConf () { 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/share/icons")) global_icon_path = "/usr/share/icons"; else 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 bool GetMainIconThemePath () { foreach (string path in icon_paths) { if (Directory.Exists (path + "/" + icon_theme)) { main_icon_theme_path = path + "/" + icon_theme; return true; } } 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); 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 (!is_svg_icon_theme) { if (extension != ".png") continue; } else if (extension != ".svg") continue; string file_name = Path.GetFileNameWithoutExtension (files [z]); if (!file_name.StartsWith ("gnome-mime-")) continue; 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] = '/'; break; } 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 string ResolvePath (string path) { 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; } } }