[MonoDevelop] Monodevelop brother

Mike Krueger mike@icsharpcode.net
Mon, 28 Jun 2004 10:48:04 +0200


This is a multi-part message in MIME format.
--------------050903040900060809020804
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit

Hi

Small sourcecode issues:

FileUtilityService.cs (sand):

    /// <summary>
        /// This method checks the file fileName if it is valid.
        /// </summary>
        public bool IsValidFileName(string fileName)
        {
            // Fixme: 260 is the hardcoded maximal length for a path on 
my Windows XP system
            //        I can't find a .NET property or method for 
determining this variable.
            if (fileName == null || fileName.Length == 0 || 
fileName.Length >= 260) {
                return false;
            }
           
            // platform independend : check for invalid path chars
            foreach (char invalidChar in Path.InvalidPathChars) {
                if (fileName.IndexOf(invalidChar) >= 0) {
                    return false;
                }
            }
           
            // platform dependend : Check for invalid file names (DOS)
            // this routine checks for follwing bad file names :
            // CON, PRN, AUX, NUL, COM1-9 and LPT1-9
           
            string nameWithoutExtension = 
Path.GetFileNameWithoutExtension(fileName);
            if (nameWithoutExtension != null) {
                nameWithoutExtension = nameWithoutExtension.ToUpper();
            }
           
            if (nameWithoutExtension == "CON" ||
                nameWithoutExtension == "PRN" ||
                nameWithoutExtension == "AUX" ||
                nameWithoutExtension == "NUL") {
               
                return false;
            }
               
            char ch = nameWithoutExtension.Length == 4 ? 
nameWithoutExtension[3] : '\0';
           
            return !((nameWithoutExtension.StartsWith("COM") ||
                      nameWithoutExtension.StartsWith("LPT")) &&
                      Char.IsDigit(ch));
        }

SharpDevelop version:
        const string fileNameRegEx = @"^(([a-zA-Z]:)|.)[^:]*$";
        /// <summary>
        /// This method checks the file fileName if it is valid.
        /// </summary>
        public bool IsValidFileName(string fileName)
        {
            // Fixme: 260 is the hardcoded maximal length for a path on 
my Windows XP system
            //        I can't find a .NET property or method for 
determining this variable.
            if (fileName == null || fileName.Length == 0 || 
fileName.Length >= 260) {
                return false;
            }
           
            // platform independend : check for invalid path chars
            foreach (char invalidChar in Path.InvalidPathChars) {
                if (fileName.IndexOf(invalidChar) >= 0) {
                    return false;
                }
            }
            if (fileName.IndexOf('?') >= 0 || fileName.IndexOf('*') >= 0) {
                return false;
            }
           
            if (!Regex.IsMatch(fileName, fileNameRegEx)) {
                return false;
            }
           
            // platform dependend : Check for invalid file names (DOS)
            // this routine checks for follwing bad file names :
            // CON, PRN, AUX, NUL, COM1-9 and LPT1-9
           
            string nameWithoutExtension = 
Path.GetFileNameWithoutExtension(fileName);
            if (nameWithoutExtension != null) {
                nameWithoutExtension = nameWithoutExtension.ToUpper();
            }
           
            if (nameWithoutExtension == "CON" ||
                nameWithoutExtension == "PRN" ||
                nameWithoutExtension == "AUX" ||
                nameWithoutExtension == "NUL") {
                return false;
            }
               
            char ch = nameWithoutExtension.Length == 4 ? 
nameWithoutExtension[3] : '\0';
           
            return !((nameWithoutExtension.StartsWith("COM") ||
                      nameWithoutExtension.StartsWith("LPT")) &&
                      Char.IsDigit(ch));
        }
       

... ok we have some more bugfixes in our version (did some bugfixes 
lately, our subversion log prooves that) ... but the sand version is 
clearly a 'derived' version.

PropertyService.cs (sand):

    /// <summary>
        /// Expands ${xyz} style property values.
        /// </summary>
        public string Parse(string input, string[,] customTags)
        {
            string output = input;
            if (input != null) {
                const string pattern = @"\$\{([^\}]*)\}";
                foreach (Match m in Regex.Matches(input, pattern)) {
                    if (m.Length > 0) {
                        string token         = m.ToString();
                        string propertyName  = 
m.Groups[1].Captures[0].Value;
                        string propertyValue = null;
                        switch (propertyName.ToUpper()) {
                            case "DATE": // current date
                                propertyValue = 
DateTime.Today.ToShortDateString();
                                break;
                            case "TIME": // current time
                                propertyValue = 
DateTime.Now.ToShortTimeString();
                                break;
                            default:
                                propertyValue = null;
                                if (customTags != null) {
                                    for (int j = 0; j < 
customTags.GetLength(0); ++j) {
                                        if (propertyName.ToUpper() == 
customTags[j, 0].ToUpper()) {
                                            propertyValue = 
customTags[j, 1];
                                            break;
                                        }
                                    }
                                }
                               
                                if (propertyValue == null) {
                                    propertyValue = 
properties[propertyName.ToUpper()];
                                }
                           
                                break;
                        }
                        if (propertyValue != null) {
                            output = output.Replace(token, propertyValue);
                        }
                    }
                }
            }
            return output;
        }

StringParserService.cs (#D rev 1000, one of our contributors did some 
more corrections therefore I've taken an older version):

/// <summary>
        /// Expands ${xyz} style property values.
        /// </summary>
        public string Parse(string input, string[,] customTags)
        {
            string output = input;
            if (input != null) {
                const string pattern = @"\$\{([^\}]*)\}";
                foreach (Match m in Regex.Matches(input, pattern)) {
                    if (m.Length > 0) {
                        string token         = m.ToString();
                        string propertyName  = 
m.Groups[1].Captures[0].Value;
                        string propertyValue = null;
                        switch (propertyName.ToUpper()) {
                            case "USER": // current user
                                propertyValue = Environment.UserName;
                                break;
                            case "DATE": // current date
                                propertyValue = 
DateTime.Today.ToShortDateString();
                                break;
                            case "TIME": // current time
                                propertyValue = 
DateTime.Now.ToShortTimeString();
                                break;
                            default:
                                propertyValue = null;
                                if (customTags != null) {
                                    for (int j = 0; j < 
customTags.GetLength(0); ++j) {
                                        if (propertyName.ToUpper() == 
customTags[j, 0].ToUpper()) {
                                            propertyValue = 
customTags[j, 1];
                                            break;
                                        }
                                    }
                                }
                               
                                if (propertyValue == null) {
                                    propertyValue = 
properties[propertyName.ToUpper()];
                                }
                               
                                if (propertyValue == null) {
                                    IStringTagProvider stringTagProvider 
= stringTagProviders[propertyName.ToUpper()] as IStringTagProvider;
                                    if (stringTagProvider != null) {
                                        propertyValue = 
stringTagProvider.Convert(propertyName.ToUpper());
                                    }
                                }
                               
                                if (propertyValue == null) {
                                    int k = propertyName.IndexOf(':');
                                    if (k > 0) {
                                        switch 
(propertyName.Substring(0, k).ToUpper()) {
                                            case "RES":
                                                IResourceService 
resourceService = 
(IResourceService)ServiceManager.Services.GetService(typeof(IResourceService));
                                                if (resourceService != 
null) {
                                                    try {
                                                        propertyValue = 
Parse(resourceService.GetString(propertyName.Substring(k + 1)), customTags);
                                                    } catch (Exception) {
                                                        propertyValue = 
null;
                                                    }
                                                }
                                                break;
                                            case "PROPERTY":
                                                PropertyService 
propertyService = 
(PropertyService)ServiceManager.Services.GetService(typeof(PropertyService));
                                                propertyValue = 
propertyService.GetProperty(propertyName.Substring(k + 1)).ToString();
                                                break;
                                        }
                                    }
                                }
                                break;
                        }
                        if (propertyValue != null) {
                            output = output.Replace(token, propertyValue);
                        }
                    }
                }
            }
            return output;
        }
    }
... our's is again more complicated ... but you can see much coincidence 
here.

Or in the Project Browser are MANY occasions where #D code shines through:

using System;
using System.IO;
using System.Windows.Forms;
using System.Diagnostics;
using System.Drawing;
using System.Collections.Specialized;

using Sand.Interface.Editor.Core.Project;
using Sand.Interface.Editor.Core;

namespace Sand.Interface.Editor.Enviromins.Common.Controls
{
    /// <summary>
    /// This class represents the default directory in the project browser.
    /// </summary>
    public class DirectoryNode : FolderNode
    {
//        readonly static string defaultContextMenuPath = 
"/SharpDevelop/Views/ProjectBrowser/ContextMenu/DefaultDirectoryNode";
               
        string folderName;
        string folderPath;
       
        /// <summary>
        /// This property gets the name of a directory for a
        /// 'directory' folder.
        /// </summary>
        public string FolderName {
            get {
                return folderName;
            }
            set {
                folderName = value;
                canLabelEdited = true;
            }
        }
       
        public DirectoryNode(string folderName , string folderPath) : 
base(Path.GetFileName(folderName))
        {
            this.folderName = folderName;
            this.folderPath = folderPath;

            canLabelEdited  = true;

            OpenedImage = 
Sand.Interface.Editor.Core.FileSystemImages.FolderOpen;
            ClosedImage = 
Sand.Interface.Editor.Core.FileSystemImages.FolderClose;

            /*
            ResourceService resourceService = 
(ResourceService)ServiceManager.Services.GetService(typeof(IResourceService));
            OpenedImage = 
resourceService.GetBitmap("Icons.16x16.OpenFolderBitmap");
            ClosedImage = 
resourceService.GetBitmap("Icons.16x16.ClosedFolderBitmap");
            */
            /*
            FileIcon fIcon = new FileIcon (@"\");

            fIcon.Flags = fIcon.Flags
                | FileIcon.SHGetFileInfoConstants.SHGFI_SMALLICON &
                ~(FileIcon.SHGetFileInfoConstants.SHGFI_DISPLAYNAME | 
FileIcon.SHGetFileInfoConstants.SHGFI_TYPENAME |
                FileIcon.SHGetFileInfoConstants.SHGFI_ATTRIBUTES | 
FileIcon.SHGetFileInfoConstants.SHGFI_EXETYPE );
            fIcon.GetInfo();

            if(fIcon.ShellIcon != null)
                ClosedImage = (Image)fIcon.ShellIcon.ToBitmap();

            fIcon.Flags = fIcon.Flags
                | FileIcon.SHGetFileInfoConstants.SHGFI_SMALLICON &
                ~(FileIcon.SHGetFileInfoConstants.SHGFI_DISPLAYNAME | 
FileIcon.SHGetFileInfoConstants.SHGFI_TYPENAME |
                FileIcon.SHGetFileInfoConstants.SHGFI_ATTRIBUTES | 
FileIcon.SHGetFileInfoConstants.SHGFI_EXETYPE | 
FileIcon.SHGetFileInfoConstants.SHGFI_OPENICON );
            fIcon.GetInfo();

            if(fIcon.ShellIcon != null)
                OpenedImage = (Image)fIcon.ShellIcon.ToBitmap();

            OpenedImage = 
Sand.Interface.Editor.Core.FileSystemImages.FolderOpen;
            ClosedImage = 
Sand.Interface.Editor.Core.FileSystemImages.FolderClose;
*/           
           
        }
       
        public override DragDropEffects GetDragDropEffect(IDataObject 
dataObject, DragDropEffects proposedEffect)
        {
            if (dataObject.GetDataPresent(typeof(FileNode)) && 
DragDropUtil.CanDrag((FileNode)dataObject.GetData(typeof(FileNode)), 
this)) {               
                return proposedEffect;
            }
            if (dataObject.GetDataPresent(DataFormats.FileDrop)) {
                return proposedEffect;
            }
            return DragDropEffects.None;
        }
       
        public override void DoDragDrop(IDataObject dataObject, 
DragDropEffects effect)
        {
            if (dataObject.GetDataPresent(typeof(FileNode))) {
                FileNode fileNode = 
DragDropUtil.DoDrag((FileNode)dataObject.GetData(typeof(FileNode)), 
this, effect);
                DragDropUtil.DoDrop(fileNode, folderName, effect);
            } else if (dataObject.GetDataPresent(DataFormats.FileDrop)) {
                string[] files = 
(string[])dataObject.GetData(DataFormats.FileDrop);
                foreach (string file in files) {
                    try {
            //            ProjectBrowserView.MoveCopyFile(file, this, 
effect == DragDropEffects.Move, false);
                    } catch (Exception ex) {
                        Console.WriteLine(ex.ToString());
                    }
                }
            } else {
                throw new System.NotImplementedException();
            }
        }
       
        /*
        public override void AfterLabelEdit(string newName)
        {
            if (newName != null && newName.Trim().Length > 0) {
               
                string oldFoldername = folderName;
                string newFoldername = 
Path.GetDirectoryName(oldFoldername) + Path.DirectorySeparatorChar + 
newName;
                ResourceService resourceService = 
(ResourceService)ServiceManager.Services.GetService(typeof(IResourceService));
               
                if (oldFoldername != newFoldername) {
                    try {
                       
                        IFileService fileService = 
(IFileService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(IFileService));
                        FileUtilityService fileUtilityService = 
(FileUtilityService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(FileUtilityService));
                        if 
(fileUtilityService.IsValidFileName(newFoldername)) {
                            fileService.RenameFile(oldFoldername, 
newFoldername);
                            Text       = newName;
                            folderName = newFoldername;
                        }
                    } catch (System.IO.IOException) {   // assume 
duplicate file
                        IMessageService messageService 
=(IMessageService)ServiceManager.Services.GetService(typeof(IMessageService));
                        
messageService.ShowError("${res:Gui.ProjectBrowser.FileInUseError}");
                    } catch (System.ArgumentException) { // new file 
name with wildcard (*, ?) characters in it
                        IMessageService messageService 
=(IMessageService)ServiceManager.Services.GetService(typeof(IMessageService));
                        
messageService.ShowError("${res:Gui.ProjectBrowser.IllegalCharactersInFileNameError}");
                    }
                }
            }
        }
        */
       
        /*
        /// <summary>
        /// Removes a folder from a project.
        /// Note : The FolderName property must be set for this method 
to work.
        /// </summary>
        public override bool RemoveNode()
        {
            if (FolderName != null && FolderName.Length == 0) {
                return false;
            }
            ResourceService resourceService = 
(ResourceService)ServiceManager.Services.GetService(typeof(IResourceService));
            StringParserService stringParserService = 
(StringParserService)ServiceManager.Services.GetService(typeof(StringParserService));
           
            int ret = new 
SharpMessageBox(resourceService.GetString("ProjectComponent.RemoveFolder.Title"),
                                          
stringParserService.Parse(resourceService.GetString("ProjectComponent.RemoveFolder.Question"), 
new string[,] { {"FOLDER", Text}, {"PROJECT", Project.Name}}),
                                          
resourceService.GetString("Global.RemoveButtonText"),
                                          
resourceService.GetString("Global.DeleteButtonText"),
                                          
resourceService.GetString("Global.CancelButtonText")).ShowMessageBox();
            IFileService fileService = 
(IFileService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(IFileService));
            IProjectService projectService = 
(IProjectService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(IProjectService));
            switch (ret) {
                case -1:
                case 2:
                    return false;
                case 0:
                    projectService.RemoveFileFromProject(FolderName);
                    break;
                case 1:
                    fileService.RemoveFile(FolderName);
                    break;
            }
            return true;
        }
        */
    }
}

Same class from #D:

    /// <summary>
    /// This class represents the default directory in the project browser.
    /// </summary>
    public class DirectoryNode : FolderNode
    {
        readonly static string defaultContextMenuPath = 
"/SharpDevelop/Views/ProjectBrowser/ContextMenu/DefaultDirectoryNode";
               
        string folderName;
       
        /// <summary>
        /// This property gets the name of a directory for a
        /// 'directory' folder.
        /// </summary>
        public string FolderName {
            get {
                return folderName;
            }
            set {
                folderName = value;
                canLabelEdited = true;
            }
        }
       
        public DirectoryNode(string folderName) : 
base(Path.GetFileName(folderName))
        {
            this.folderName = folderName;
            canLabelEdited  = true;
            contextmenuAddinTreePath = defaultContextMenuPath;
            ResourceService resourceService = 
(ResourceService)ServiceManager.Services.GetService(typeof(IResourceService));
            OpenedImage = 
resourceService.GetBitmap("Icons.16x16.OpenFolderBitmap");
            ClosedImage = 
resourceService.GetBitmap("Icons.16x16.ClosedFolderBitmap");
        }
       
        public override DragDropEffects GetDragDropEffect(IDataObject 
dataObject, DragDropEffects proposedEffect)
        {
            if (dataObject.GetDataPresent(typeof(FileNode)) && 
DragDropUtil.CanDrag((FileNode)dataObject.GetData(typeof(FileNode)), 
this)) {               
                return proposedEffect;
            }
            if (dataObject.GetDataPresent(DataFormats.FileDrop)) {
                return proposedEffect;
            }
            return DragDropEffects.None;
        }
       
        public override void DoDragDrop(IDataObject dataObject, 
DragDropEffects effect)
        {
            if (dataObject.GetDataPresent(typeof(FileNode))) {
                FileNode fileNode = 
DragDropUtil.DoDrag((FileNode)dataObject.GetData(typeof(FileNode)), 
this, effect);
                DragDropUtil.DoDrop(fileNode, folderName, effect);
            } else if (dataObject.GetDataPresent(DataFormats.FileDrop)) {
                string[] files = 
(string[])dataObject.GetData(DataFormats.FileDrop);
                foreach (string file in files) {
                    try {
                        ProjectBrowserView.MoveCopyFile(file, this, 
effect == DragDropEffects.Move, false);
                    } catch (Exception ex) {
                        Console.WriteLine(ex.ToString());
                    }
                }
            } else {
                throw new System.NotImplementedException();
            }
        }
       
       
        public override void AfterLabelEdit(string newName)
        {
            if (newName != null && newName.Trim().Length > 0) {
               
                string oldFoldername = folderName;
                string newFoldername = 
Path.GetDirectoryName(oldFoldername) + Path.DirectorySeparatorChar + 
newName;
                ResourceService resourceService = 
(ResourceService)ServiceManager.Services.GetService(typeof(IResourceService));
               
                if (oldFoldername != newFoldername) {
                    try {
                       
                        IFileService fileService = 
(IFileService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(IFileService));
                        FileUtilityService fileUtilityService = 
(FileUtilityService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(FileUtilityService));
                        if 
(fileUtilityService.IsValidFileName(newFoldername) && 
!Directory.Exists(newFoldername) && !File.Exists(newFoldername)) {
                            fileService.RenameFile(oldFoldername, 
newFoldername);
                            Text       = newName;
                            folderName = newFoldername;
                        }
                    } catch (System.IO.IOException) {   // assume 
duplicate file
                        IMessageService messageService 
=(IMessageService)ServiceManager.Services.GetService(typeof(IMessageService));
                        
messageService.ShowError("${res:Gui.ProjectBrowser.FileInUseError}");
                    } catch (System.ArgumentException) { // new file 
name with wildcard (*, ?) characters in it
                        IMessageService messageService 
=(IMessageService)ServiceManager.Services.GetService(typeof(IMessageService));
                        
messageService.ShowError("${res:Gui.ProjectBrowser.IllegalCharactersInFileNameError}");
                    }
                }
            }
        }
       
        /// <summary>
        /// Removes a folder from a project.
        /// Note : The FolderName property must be set for this method 
to work.
        /// </summary>
        public override bool RemoveNode()
        {
            if (FolderName != null && FolderName.Length == 0) {
                return false;
            }
            ResourceService resourceService = 
(ResourceService)ServiceManager.Services.GetService(typeof(IResourceService));
            StringParserService stringParserService = 
(StringParserService)ServiceManager.Services.GetService(typeof(StringParserService));
           
            int ret = new 
SharpMessageBox(resourceService.GetString("ProjectComponent.RemoveFolder.Title"),
                                          
stringParserService.Parse(resourceService.GetString("ProjectComponent.RemoveFolder.Question"), 
new string[,] { {"FOLDER", Text}, {"PROJECT", Project.Name}}),
                                          
resourceService.GetString("Global.RemoveButtonText"),
                                          
resourceService.GetString("Global.DeleteButtonText"),
                                          
resourceService.GetString("Global.CancelButtonText")).ShowMessageBox();
            IFileService fileService = 
(IFileService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(IFileService));
            IProjectService projectService = 
(IProjectService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(IProjectService));
            switch (ret) {
                case -1:
                case 2:
                    return false;
                case 0:
                    projectService.RemoveFileFromProject(FolderName);
                    break;
                case 1:
                    fileService.RemoveFile(FolderName);
                    break;
            }
            return true;
        }
    }
... ok a lot code is commented out ... but anybody sees the coincidence.

btw. you forgot to take out :

#region Copyright © 2003 Fatih BOY [fatih@smartcoding.org]
// Software Studio GUI - Graphical User Interface components for 
Software Studio project
// Copyright (C) 2003-2004 Fatih Boy
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// Fatih BOY(fatih@smartcoding.org)
#endregion

taken from the 
Framework\Sand.Framework.SDE.Core\GUI\CommonControls\TreeView.cs file. 
I've chatted with Fatih and he DID NOT give you PERMISSION to use his 
GPL'ed code in a non GPL'ed program.

I've attached the resource services from both projects ... see yourself. 
Again is the #D one more advanced (lately we had contributors) but you 
can clearly see that's almost the same.
There are many more examples like this ... but I think that's enough to 
prove that. It's great that people think that #D code is good enough to 
use, but please follow the GPL (and nobody can take and dual license GPL 
code)..

Regards
Mike

--------------050903040900060809020804
Content-Type: text/plain;
 name="ResourceService(sand).cs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="ResourceService(sand).cs"

using System;
using System.IO;
using System.Windows.Forms;
using System.Collections;
using System.Threading;
using System.Resources;
using System.Drawing;
using System.Diagnostics;
using System.Reflection;
using System.Xml;

namespace Sand.Interface.Editor.Core.Services
{
	/// <summary>
	/// This Class contains two ResourceManagers, which handle string and image resources
	/// for the application. It do handle localization strings on this level.
	/// </summary>
	public class ResourceService : Service//: AbstractService, IResourceService
	{
		private readonly string stringResources  = "StringResources";
		private readonly string imageResources   = "BitmapResources";
		
		private readonly string resourceDirctory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) +
			Path.DirectorySeparatorChar + "resources";
		
		ResourceManager strings = null;
		ResourceManager icon    = null;
		
		Hashtable localStrings = null;
		Hashtable localIcons   = null;

		private Color _transparentColor = Color.Fuchsia;

		public override string ServiceName { get { return "Resource Service"; }}

		public string Language
		{
			get { return  Thread.CurrentThread.CurrentUICulture.Name;}
		}

		public Color TransparentColor
		{
			get { return _transparentColor;}
			set { _transparentColor = value;}
		}
		
//		void ChangeProperty(object sender, PropertyEventArgs e)
//		{
//			if (e.Key == uiLanguageProperty && e.OldValue != e.NewValue) 
//			{
//				LoadLanguageResources();
//			} 
//		}

		void LoadLanguageResources()
		{
//			PropertyService propertyService = (PropertyService)ServiceManager.Services.GetService(typeof(PropertyService));
//			string language = propertyService.GetProperty(uiLanguageProperty, Thread.CurrentThread.CurrentUICulture.Name);

			//string language = Thread.CurrentThread.CurrentUICulture.Name;
			
			localStrings = Load(stringResources, Language);
			if (localStrings == null && Language.IndexOf('-') > 0) 
			{
				localStrings = Load(stringResources, Language.Split(new char[] {'-'})[0]);
			}
			
//			localIcons = Load(imageResources, Language);
//			if (localIcons == null && Language.IndexOf('-') > 0) 
//			{
//				localIcons = Load(imageResources, Language.Split(new char[] {'-'})[0]);
//			}
			localIcons = CurrentAssemblyImages();
		}
		
		protected override void InitializeService()
		{
			//base.InitializeService();
			//PropertyService propertyService = (PropertyService)ServiceManager.Services.GetService(typeof(PropertyService));
			//propertyService.PropertyChanged += new PropertyEventHandler(ChangeProperty);
			
			LoadLanguageResources();
		}
		
		// core service : Can't use Initialize, because all other stuff needs this service before initialize is called.
		public ResourceService()
		{
			strings = new ResourceManager(stringResources, Assembly.GetCallingAssembly());
			icon    = new ResourceManager(imageResources,  Assembly.GetCallingAssembly());

			LoadLanguageResources();
		}
		
		/// <summary>
		/// The LoadFont routines provide a safe way to load fonts.
		/// </summary>
		/// <param name="fontName">The name of the font to load.</param>
		/// <param name="size">The size of the font to load.</param>
		/// <returns>
		/// The font to load or the menu font, if the requested font couldn't be loaded.
		/// </returns>
		public Font LoadFont(string fontName, int size)
		{
			return LoadFont(fontName, size, FontStyle.Regular);
		}
		
		/// <summary>
		/// The LoadFont routines provide a safe way to load fonts.
		/// </summary>
		/// <param name="fontName">The name of the font to load.</param>
		/// <param name="size">The size of the font to load.</param>
		/// <param name="style">The <see cref="System.Drawing.FontStyle"/> of the font</param>
		/// <returns>
		/// The font to load or the menu font, if the requested font couldn't be loaded.
		/// </returns>
		public Font LoadFont(string fontName, int size, FontStyle style)
		{
			try 
			{
				return new Font(fontName, size, style);
			} 
			catch (Exception) 
			{
				return SystemInformation.MenuFont;
			}
		}
		
		/// <summary>
		/// The LoadFont routines provide a safe way to load fonts.
		/// </summary>
		/// <param name="fontName">The name of the font to load.</param>
		/// <param name="size">The size of the font to load.</param>
		/// <param name="unit">The <see cref="System.Drawing.GraphicsUnit"/> of the font</param>
		/// <returns>
		/// The font to load or the menu font, if the requested font couldn't be loaded.
		/// </returns>
		public Font LoadFont(string fontName, int size, GraphicsUnit unit)
		{
			return LoadFont(fontName, size, FontStyle.Regular, unit);
		}
		
		/// <summary>
		/// The LoadFont routines provide a safe way to load fonts.
		/// </summary>
		/// <param name="fontName">The name of the font to load.</param>
		/// <param name="size">The size of the font to load.</param>
		/// <param name="style">The <see cref="System.Drawing.FontStyle"/> of the font</param>
		/// <param name="unit">The <see cref="System.Drawing.GraphicsUnit"/> of the font</param>
		/// <returns>
		/// The font to load or the menu font, if the requested font couldn't be loaded.
		/// </returns>
		public Font LoadFont(string fontName, int size, FontStyle style, GraphicsUnit unit)
		{
			try 
			{
				return new Font(fontName, size, style, unit);
			} 
			catch (Exception) 
			{
				return SystemInformation.MenuFont;
			}
		}
		
		Hashtable Load(string name, string language)
		{
			string fname = resourceDirctory + Path.DirectorySeparatorChar + name + "." + language + ".resources";
			
			if (File.Exists(fname)) 
			{
				Hashtable resources = new Hashtable();
				ResourceReader rr = new ResourceReader(fname);
				foreach (DictionaryEntry entry in rr) 
				{
					resources.Add(entry.Key, entry.Value);
				}
				rr.Close();
				return resources;
			}
			return null;
		}

		Hashtable CurrentAssemblyImages()
		{
			Hashtable resources = new Hashtable();
			//ResourceReader rr = new ResourceReader(Assembly.GetAssembly(GetType()).Location.ToString());
			foreach(string resourcename in GetType().Assembly.GetManifestResourceNames())
			{
				if(resourcename.EndsWith(".bmp"))
				{
					string ResourceFileName = resourcename.Replace("Sand.Interface.Editor.Core.Resources.",string.Empty);
					resources.Add(ResourceFileName, new Bitmap(GetType().Assembly.GetManifestResourceStream(resourcename)));
				}
			}
			//rr.Close();
			return resources;
		}
		
		/// <summary>
		/// Returns a string from the resource database, it handles localization
		/// transparent for the user.
		/// </summary>
		/// <returns>
		/// The string in the (localized) resource database.
		/// </returns>
		/// <param name="name">
		/// The name of the requested resource.
		/// </param>
		/// <exception cref="ResourceNotFoundException">
		/// Is thrown when the GlobalResource manager can't find a requested resource.
		/// </exception>
		public string GetString(string name)
		{
			if (localStrings != null && localStrings[name] != null) 
			{
				return localStrings[name].ToString();
			}
			
			string s = strings.GetString(name);
			
			if (s == null) 
			{
				throw new Exception("string >" + name + "<");
			}
			
			return s;
		}
		
		/// <summary>
		/// Returns a icon from the resource database, it handles localization
		/// transparent for the user. In the resource database can be a bitmap
		/// instead of an icon in the dabase. It is converted automatically.
		/// </summary>
		/// <returns>
		/// The icon in the (localized) resource database.
		/// </returns>
		/// <param name="name">
		/// The name of the requested icon.
		/// </param>
		/// <exception cref="ResourceNotFoundException">
		/// Is thrown when the GlobalResource manager can't find a requested resource.
		/// </exception>
		public Icon GetIcon(string name)
		{
			object iconobj = null;
			
			if (localIcons != null && localIcons[name] != null) 
			{
				iconobj = localIcons[name];
			} 
			else 
			{
				iconobj = icon.GetObject(name);
			}
			
			if (iconobj == null) 
			{
				return null;
			}
			
			if (iconobj is Icon) 
			{
				return (Icon)iconobj;
			} 
			else 
			{
				return Icon.FromHandle(((Bitmap)iconobj).GetHicon());
			}
		}
		
		/// <summary>
		/// Returns a bitmap from the resource database, it handles localization
		/// transparent for the user. 
		/// </summary>
		/// <returns>
		/// The bitmap in the (localized) resource database.
		/// </returns>
		/// <param name="name">
		/// The name of the requested bitmap.
		/// </param>
		/// <exception cref="ResourceNotFoundException">
		/// Is thrown when the GlobalResource manager can't find a requested resource.
		/// </exception>
		/// 
		public Bitmap GetBitmap(string name)
		{
			return GetBitmap (name , true);
		}
		
		public Icon GetIconFromImageArray (string name , int ImageNum)
		{
			return Icon.FromHandle(GetImageFromImageArray(name , ImageNum).GetHicon());
		}

		public Bitmap GetImageFromImageArray (string name , int ImageNum)
		{
			ImageList images = new ImageList();

			images.ImageSize = new Size(16, 16);
			images.Images.AddStrip ( GetBitmap(name) );

			return (Bitmap)images.Images[ImageNum];
		}

		public Bitmap GetBitmap(string name , bool transparent)
		{
			if (localIcons != null && localIcons[name] != null) 
			{
				Bitmap bitmap = (Bitmap)localIcons[name];

				if(transparent)
					bitmap.MakeTransparent();

				return bitmap;
			}
			Bitmap b = (Bitmap)icon.GetObject(name);
			
			Debug.Assert(b != null, "Resource " + name);
			
			return b;
		}
	}
}
--------------050903040900060809020804
Content-Type: text/plain;
 name="ResourceService(SD).cs"
Content-Transfer-Encoding: 8bit
Content-Disposition: inline;
 filename="ResourceService(SD).cs"

// <file>
//     <copyright see="prj:///doc/copyright.txt"/>
//     <license see="prj:///doc/license.txt"/>
//     <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
//     <version value="$version"/>
// </file>

using System;
using System.IO;
using System.Windows.Forms;
using System.Collections;
using System.Threading;
using System.Resources;
using System.Drawing;
using System.Diagnostics;
using System.Reflection;
using System.Xml;

using ICSharpCode.Core.Properties;

namespace ICSharpCode.Core.Services
{
	/// <summary>
	/// This Class contains two ResourceManagers, which handle string and image resources
	/// for the application. It do handle localization strings on this level.
	/// </summary>
	public class ResourceService : AbstractService, IResourceService
	{
		readonly static string uiLanguageProperty = "CoreProperties.UILanguage";
		
		readonly static string stringResources  = "StringResources";
		readonly static string imageResources   = "BitmapResources";
		
		static string resourceDirctory;
		
		static ResourceService()
		{
			PropertyService propertyService = (PropertyService)ServiceManager.Services.GetService(typeof(PropertyService));
			resourceDirctory = propertyService.DataDirectory + Path.DirectorySeparatorChar + "resources";
		}
		
		Hashtable userStrings = null;
		Hashtable userIcons   = null;
		Hashtable localUserStrings = null;
		Hashtable localUserIcons   = null;
		
		ArrayList strings = new ArrayList();
		ArrayList icon    = new ArrayList();
		
		Hashtable localStrings = null;
		Hashtable localIcons   = null;

		ArrayList localStringsResMgrs = new ArrayList();
		ArrayList localIconsResMgrs   = new ArrayList();

		ArrayList assemblies = new ArrayList();
		
		void ChangeProperty(object sender, PropertyEventArgs e)
		{
			if (e.Key == uiLanguageProperty && e.OldValue != e.NewValue) {
			    LoadLanguageResources();
			} 
		}
		void LoadLanguageResources()
		{
			
			PropertyService propertyService = (PropertyService)ServiceManager.Services.GetService(typeof(PropertyService));
			string language = propertyService.GetProperty(uiLanguageProperty, Thread.CurrentThread.CurrentUICulture.Name);
			
			try {
				Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);
			} catch (Exception) {
				try {
					Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language.Split('-')[0]);
				} catch (Exception) {}
			}

			if (System.Configuration.ConfigurationSettings.AppSettings["UserStrings"] != null) {
				string resourceName = System.Configuration.ConfigurationSettings.AppSettings["UserStrings"];
				resourceName = resourceName.Insert(resourceName.LastIndexOf(".resources"), "." + language);
				localUserStrings = Load(resourceDirctory +  Path.DirectorySeparatorChar + resourceName);
			}
			if (System.Configuration.ConfigurationSettings.AppSettings["UserIcons"] != null) {
				string resourceName = System.Configuration.ConfigurationSettings.AppSettings["UserIcons"];
				resourceName = resourceName.Insert(resourceName.LastIndexOf(".resources"), "." + language);
				localUserIcons   = Load(resourceDirctory +  Path.DirectorySeparatorChar + resourceName);
			}

			
			localStrings = Load(stringResources, language);
			if (localStrings == null && language.IndexOf('-') > 0) {
				localStrings = Load(stringResources, language.Split('-')[0]);
			}
			
			localIcons = Load(imageResources, language);
			if (localIcons == null && language.IndexOf('-') > 0) {
				localIcons = Load(imageResources, language.Split('-')[0]);
			}

			localStringsResMgrs.Clear();
			localIconsResMgrs.Clear();

			foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) {
				if (assemblies.Contains(assembly.FullName)) {
					if (assembly.GetManifestResourceInfo(stringResources+".resources") != null) {
						localStringsResMgrs.Add(new ResourceManager(stringResources, assembly));
					}
			
					if (assembly.GetManifestResourceInfo(imageResources+".resources") != null) {
						localIconsResMgrs.Add(new ResourceManager(imageResources, assembly));
					}
				}
			}
		}
		
		public override void InitializeService()
		{
			RegisterAssembly(Assembly.GetEntryAssembly());
			
			base.InitializeService();
			PropertyService propertyService = (PropertyService)ServiceManager.Services.GetService(typeof(PropertyService));
			propertyService.PropertyChanged += new PropertyEventHandler(ChangeProperty);
			
			LoadLanguageResources();
		}
		
		// core service : Can't use Initialize, because all other stuff needs this service before initialize is called.
		public ResourceService()
		{
			if (System.Configuration.ConfigurationSettings.AppSettings["UserStrings"] != null) {
				userStrings = Load(resourceDirctory +  Path.DirectorySeparatorChar + System.Configuration.ConfigurationSettings.AppSettings["UserStrings"]);
			}
			if (System.Configuration.ConfigurationSettings.AppSettings["UserIcons"] != null) {
				userIcons   = Load(resourceDirctory +  Path.DirectorySeparatorChar + System.Configuration.ConfigurationSettings.AppSettings["UserIcons"]);
			}
		}
		
		/// <summary>
		/// The LoadFont routines provide a safe way to load fonts.
		/// </summary>
		/// <param name="fontName">The name of the font to load.</param>
		/// <param name="size">The size of the font to load.</param>
		/// <returns>
		/// The font to load or the menu font, if the requested font couldn't be loaded.
		/// </returns>
		public Font LoadFont(string fontName, int size)
		{
			return LoadFont(fontName, size, FontStyle.Regular);
		}
		
		/// <summary>
		/// The LoadFont routines provide a safe way to load fonts.
		/// </summary>
		/// <param name="fontName">The name of the font to load.</param>
		/// <param name="size">The size of the font to load.</param>
		/// <param name="style">The <see cref="System.Drawing.FontStyle"/> of the font</param>
		/// <returns>
		/// The font to load or the menu font, if the requested font couldn't be loaded.
		/// </returns>
		public Font LoadFont(string fontName, int size, FontStyle style)
		{
			try {
				return new Font(fontName, size, style);
			} catch (Exception) {
				return SystemInformation.MenuFont;
			}
		}
		
		/// <summary>
		/// The LoadFont routines provide a safe way to load fonts.
		/// </summary>
		/// <param name="fontName">The name of the font to load.</param>
		/// <param name="size">The size of the font to load.</param>
		/// <param name="unit">The <see cref="System.Drawing.GraphicsUnit"/> of the font</param>
		/// <returns>
		/// The font to load or the menu font, if the requested font couldn't be loaded.
		/// </returns>
		public Font LoadFont(string fontName, int size, GraphicsUnit unit)
		{
			return LoadFont(fontName, size, FontStyle.Regular, unit);
		}
		
		/// <summary>
		/// The LoadFont routines provide a safe way to load fonts.
		/// </summary>
		/// <param name="fontName">The name of the font to load.</param>
		/// <param name="size">The size of the font to load.</param>
		/// <param name="style">The <see cref="System.Drawing.FontStyle"/> of the font</param>
		/// <param name="unit">The <see cref="System.Drawing.GraphicsUnit"/> of the font</param>
		/// <returns>
		/// The font to load or the menu font, if the requested font couldn't be loaded.
		/// </returns>
		public Font LoadFont(string fontName, int size, FontStyle style, GraphicsUnit unit)
		{
			try {
				return new Font(fontName, size, style, unit);
			} catch (Exception) {
				return SystemInformation.MenuFont;
			}
		}
		
		Hashtable Load(string fileName)
		{
			if (File.Exists(fileName)) {
				Hashtable resources = new Hashtable();
				ResourceReader rr = new ResourceReader(fileName);
				foreach (DictionaryEntry entry in rr) {
					resources.Add(entry.Key, entry.Value);
				}
				rr.Close();
				return resources;
			}
			return null;
		}
		Hashtable Load(string name, string language)
		{
			return Load(resourceDirctory + Path.DirectorySeparatorChar + name + "." + language + ".resources");
			
		}
		
		/// <summary>
		/// Returns a string from the resource database, it handles localization
		/// transparent for the user.
		/// </summary>
		/// <returns>
		/// The string in the (localized) resource database.
		/// </returns>
		/// <param name="name">
		/// The name of the requested resource.
		/// </param>
		/// <exception cref="ResourceNotFoundException">
		/// Is thrown when the GlobalResource manager can't find a requested resource.
		/// </exception>
		public string GetString(string name)
		{
			if (this.localUserStrings != null && this.localUserStrings[name] != null) {
				return localUserStrings[name].ToString();
			}
			if (this.userStrings != null && this.userStrings[name] != null) {
				return userStrings[name].ToString();
			}
			if (localStrings != null && localStrings[name] != null) {
				return localStrings[name].ToString();
			}
	
			string s = null;
			foreach (ResourceManager resourceManger in localStringsResMgrs) {
				s = resourceManger.GetString(name);
				if (s != null) {
					break;
				}
			}

			if (s == null) {
				foreach (ResourceManager resourceManger in strings) {
					s = resourceManger.GetString(name);
					if (s != null) {
						break;
					}
				}
			}
			if (s == null) {
				throw new ResourceNotFoundException("string >" + name + "<");
			}
			
			return s;
		}
		
		/// <summary>
		/// Take string/bitmap resources from an assembly and merge them in the resource service
		/// </summary>
		public void RegisterAssembly(Assembly assembly)
		{
			assemblies.Add(assembly.FullName);

			if (assembly.GetManifestResourceInfo(stringResources+".resources") != null) {
				strings.Add(new ResourceManager(stringResources, assembly));
			}
			
			if (assembly.GetManifestResourceInfo(imageResources+".resources") != null) {
				icon.Add(new ResourceManager(imageResources, assembly));
			}
		}
		
		object GetImageResource(string name)
		{
			object iconobj = null;
			if (this.localUserIcons != null && this.localUserIcons[name] != null) {
				iconobj = localUserIcons[name];
			} else  if (this.userIcons != null && this.userIcons[name] != null) {
				iconobj = userIcons[name];
			} else  if (localIcons != null && localIcons[name] != null) {
				iconobj = localIcons[name];
			} else {
				foreach (ResourceManager resourceManger in localIconsResMgrs) {
					iconobj = resourceManger.GetObject(name);
					if (iconobj != null) {
						break;
					}
				}

				if (iconobj == null) {
					foreach (ResourceManager resourceManger in icon) {
						iconobj = resourceManger.GetObject(name);
						if (iconobj != null) {
							break;
						}
					}
				}
			}
			return iconobj;
		}
		
		/// <summary>
		/// Returns a icon from the resource database, it handles localization
		/// transparent for the user. In the resource database can be a bitmap
		/// instead of an icon in the dabase. It is converted automatically.
		/// </summary>
		/// <returns>
		/// The icon in the (localized) resource database.
		/// </returns>
		/// <param name="name">
		/// The name of the requested icon.
		/// </param>
		/// <exception cref="ResourceNotFoundException">
		/// Is thrown when the GlobalResource manager can't find a requested resource.
		/// </exception>
		public Icon GetIcon(string name)
		{
			object iconobj = GetImageResource(name);
			
			if (iconobj == null) {
				return null;
			}
			if (iconobj is Icon) {
				return (Icon)iconobj;
			} else {
				return Icon.FromHandle(((Bitmap)iconobj).GetHicon());
			}
		}
		
		/// <summary>
		/// Returns a bitmap from the resource database, it handles localization
		/// transparent for the user. 
		/// </summary>
		/// <returns>
		/// The bitmap in the (localized) resource database.
		/// </returns>
		/// <param name="name">
		/// The name of the requested bitmap.
		/// </param>
		/// <exception cref="ResourceNotFoundException">
		/// Is thrown when the GlobalResource manager can't find a requested resource.
		/// </exception>
		public Bitmap GetBitmap(string name)
		{
			Bitmap b = (Bitmap)GetImageResource(name);
			Debug.Assert(b != null, "Resource " + name);
			return b;
		}
	}
}

--------------050903040900060809020804--