Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'mcs/class/Managed.Windows.Forms/System.Windows.Forms/MimeIcon.cs')
-rw-r--r--mcs/class/Managed.Windows.Forms/System.Windows.Forms/MimeIcon.cs1114
1 files changed, 1114 insertions, 0 deletions
diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/MimeIcon.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/MimeIcon.cs
new file mode 100644
index 00000000000..9f6f54a3687
--- /dev/null
+++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/MimeIcon.cs
@@ -0,0 +1,1114 @@
+// 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.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 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...
+ 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" );
+
+ 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[] { ',' } );
+
+ foreach ( string s in split )
+ {
+ if ( MimeTypeIconIndexHash.ContainsKey( s ) )
+ continue;
+
+ MimeTypeIconIndexHash.Add( s, 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[] { ',' } );
+
+ foreach ( string s in split )
+ {
+ oindex = MimeTypeIconIndexHash[ s ];
+
+ 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 = MimeGenerated.SubClasses[ mime_type ];
+
+ if ( sub_class != null )
+ return MimeTypeIconIndexHash[ sub_class ];
+
+ // 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", (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( "last_open", (Image)Locale.GetResource( "last_open" ) );
+ MimeIconEngine.AddIconByImage( "monitor-computer", (Image)Locale.GetResource( "monitor-computer" ) );
+
+ 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 );
+
+ foreach( string path in dirs )
+ {
+ if ( path.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 );
+
+ foreach ( string d in directories )
+ {
+ DirectoryInfo di = new DirectoryInfo( d );
+
+ FileInfo[] fileinfo = di.GetFiles( );
+
+ foreach ( FileInfo fi in fileinfo )
+ {
+ string name = Path.GetFileNameWithoutExtension( fi.Name );
+
+ MimeIconEngine.AddIcon( name, fi.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 );
+
+ foreach ( string d in directories )
+ {
+ string[] files = Directory.GetFiles( d );
+
+ foreach ( string f in files )
+ {
+ try {
+ ReadDotDesktop( f );
+ } 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 e ) {
+ 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 e) {
+
+ }
+
+ 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);
+
+ // use default gnome icon theme if there isn't a "/48x48" or "/scalable" dir
+ // for the current theme
+ if (resolv_path == String.Empty)
+ foreach (string path in icon_paths)
+ if (Directory.Exists (path + "/gnome")) {
+ resolv_path = path + "/gnome/48x48/";
+ break;
+ }
+
+ string[] dirs = Directory.GetDirectories (resolv_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";
+
+ if (!CheckAndAddUIIcons (dirs, name_mime_hash)) {
+ //could be a kde icon theme, so we check kde icon names also
+ 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 bool CheckAndAddUIIcons (string[] dirs, Hashtable name_mime_hash)
+ {
+ string extension = is_svg_icon_theme ? "svg" : "png";
+ int counter = 0;
+
+ foreach (string place in dirs) {
+ foreach (DictionaryEntry entry in name_mime_hash) {
+ string key = (string)entry.Key;
+ if (File.Exists (place + "/" + key + "." + extension)) {
+ string value = (string)entry.Value;
+ MimeIconEngine.AddMimeTypeAndIconName (value, key);
+ if (!is_svg_icon_theme)
+ MimeIconEngine.AddIcon (key, place + "/" + key + "." + extension);
+ else
+ MimeIconEngine.AddSVGIcon (key, place + "/" + key + "." + extension);
+ counter++;
+ if (counter == name_mime_hash.Count)
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ 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");
+
+ foreach (string file in files) {
+ string extension = Path.GetExtension (file);
+
+ if (!is_svg_icon_theme) {
+ if (extension != ".png")
+ continue;
+ } else
+ if (extension != ".svg")
+ continue;
+
+ string file_name = Path.GetFileNameWithoutExtension (file);
+
+ 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, file);
+ else
+ MimeIconEngine.AddSVGIcon (file_name, file);
+ }
+ }
+ }
+
+ 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;
+ }
+ }
+}
+