// 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.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
}
}
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;
}
}
}