diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/BookmarkManager/Bookmark.cs b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/BookmarkManager/Bookmark.cs
index 933987fb65..bf32032539 100644
--- a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/BookmarkManager/Bookmark.cs
+++ b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/BookmarkManager/Bookmark.cs
@@ -25,7 +25,19 @@ namespace ICSharpCode.TextEditor.Document
return document;
}
set {
- document = value;
+ if (document != value) {
+ document = value;
+ OnDocumentChanged(EventArgs.Empty);
+ }
+ }
+ }
+
+ public event EventHandler DocumentChanged;
+
+ protected virtual void OnDocumentChanged(EventArgs e)
+ {
+ if (DocumentChanged != null) {
+ DocumentChanged(this, e);
}
}
@@ -35,8 +47,10 @@ namespace ICSharpCode.TextEditor.Document
}
set {
isEnabled = value;
- document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, lineNumber));
- document.CommitUpdate();
+ if (document != null) {
+ document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, lineNumber));
+ document.CommitUpdate();
+ }
}
}
@@ -80,7 +94,7 @@ namespace ICSharpCode.TextEditor.Document
this.lineNumber = lineNumber;
this.isEnabled = isEnabled;
}
-
+
public virtual void Click(SWF.MouseButtons mouseButtons)
{
if (mouseButtons == SWF.MouseButtons.Left) {
diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
index 6b33b6e207..077327133f 100644
--- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
+++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
@@ -132,7 +132,6 @@
-
@@ -662,6 +661,7 @@
Component
+
diff --git a/src/Main/Base/Project/Src/Commands/FileCommands.cs b/src/Main/Base/Project/Src/Commands/FileCommands.cs
index 323a08e38a..91941a81dc 100644
--- a/src/Main/Base/Project/Src/Commands/FileCommands.cs
+++ b/src/Main/Base/Project/Src/Commands/FileCommands.cs
@@ -67,7 +67,7 @@ namespace ICSharpCode.SharpDevelop.Commands
ProjectService.MarkFileDirty(window.ViewContent.FileName);
- FileUtility.ObservedSave(new FileOperationDelegate(window.ViewContent.Save), window.ViewContent.FileName);
+ FileUtility.ObservedSave(new FileOperationDelegate(window.ViewContent.Save), window.ViewContent.FileName, FileErrorPolicy.ProvideAlternative);
}
}
}
diff --git a/src/Main/Base/Project/Src/Gui/IMementoCapable.cs b/src/Main/Base/Project/Src/Gui/IMementoCapable.cs
deleted file mode 100644
index 02328c0034..0000000000
--- a/src/Main/Base/Project/Src/Gui/IMementoCapable.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-//
-//
-//
-//
-//
-
-using ICSharpCode.Core;
-
-namespace ICSharpCode.SharpDevelop.Gui
-{
- ///
- /// This interface flags an object beeing "mementocapable". This means that the
- /// state of the object could be saved to an object
- /// and set from a object from the same class.
- /// This is used to save and restore the state of GUI objects.
- ///
- public interface IMementoCapable
- {
- ///
- /// Creates a new memento from the state.
- ///
- Properties CreateMemento();
-
- ///
- /// Sets the state to the given memento.
- ///
- void SetMemento(Properties memento);
- }
-}
diff --git a/src/Main/Base/Project/Src/Gui/Workbench/DefaultWorkbench.cs b/src/Main/Base/Project/Src/Gui/Workbench/DefaultWorkbench.cs
index abb89823ef..73aba64c08 100644
--- a/src/Main/Base/Project/Src/Gui/Workbench/DefaultWorkbench.cs
+++ b/src/Main/Base/Project/Src/Gui/Workbench/DefaultWorkbench.cs
@@ -276,7 +276,7 @@ namespace ICSharpCode.SharpDevelop.Gui
string fullFileName = Path.Combine(directory, fileName);
if (FileUtility.IsValidFileName(fullFileName)) {
- FileUtility.ObservedSave(new NamedFileOperationDelegate(memento.Save), fullFileName, FileErrorPolicy.ProvideAlternative);
+ FileUtility.ObservedSave(new NamedFileOperationDelegate(memento.Save), fullFileName, FileErrorPolicy.Inform);
}
}
@@ -371,8 +371,6 @@ namespace ICSharpCode.SharpDevelop.Gui
{
base.OnClosing(e);
-
- ProjectService.SaveSolutionPreferences();
while (WorkbenchSingleton.Workbench.ViewContentCollection.Count > 0) {
IViewContent content = WorkbenchSingleton.Workbench.ViewContentCollection[0];
content.WorkbenchWindow.CloseWindow(false);
@@ -382,15 +380,6 @@ namespace ICSharpCode.SharpDevelop.Gui
}
}
ProjectService.CloseSolution();
-
- // TODO : Dirty Files Dialog
- // foreach (IViewContent content in ViewContentCollection) {
- // if (content.IsDirty) {
- // ICSharpCode.SharpDevelop.Gui.DirtyFilesDialog dfd = new ICSharpCode.SharpDevelop.Gui.DirtyFilesDialog();
- // e.Cancel = dfd.ShowDialog(ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.MainForm) == DialogResult.Cancel;
- // return;
- // }
- // }
}
protected override void OnClosed(EventArgs e)
diff --git a/src/Main/Base/Project/Src/Project/AbstractProject.cs b/src/Main/Base/Project/Src/Project/AbstractProject.cs
index 969c322431..e4f7af11b1 100644
--- a/src/Main/Base/Project/Src/Project/AbstractProject.cs
+++ b/src/Main/Base/Project/Src/Project/AbstractProject.cs
@@ -362,5 +362,28 @@ namespace ICSharpCode.SharpDevelop.Project
{
return null;
}
+
+
+
+ ///
+ /// Saves project preferences (currently opened files, bookmarks etc.) to the
+ /// a property container.
+ ///
+ public virtual Properties CreateMemento()
+ {
+ Properties properties = new Properties();
+ properties.Set("bookmarks", ICSharpCode.SharpDevelop.Bookmarks.BookmarkManager.GetProjectBookmarks(this).ToArray());
+ return properties;
+ }
+
+ ///
+ /// Loads project preferences (currently opened files, bookmarks etc.).
+ ///
+ public virtual void SetMemento(Properties properties)
+ {
+ foreach (ICSharpCode.SharpDevelop.Bookmarks.SDBookmark mark in properties.Get("bookmarks", new ICSharpCode.SharpDevelop.Bookmarks.SDBookmark[0])) {
+ ICSharpCode.SharpDevelop.Bookmarks.BookmarkManager.AddMark(mark);
+ }
+ }
}
}
diff --git a/src/Main/Base/Project/Src/Project/IProject.cs b/src/Main/Base/Project/Src/Project/IProject.cs
index 1485c5f140..5c4556b1c6 100644
--- a/src/Main/Base/Project/Src/Project/IProject.cs
+++ b/src/Main/Base/Project/Src/Project/IProject.cs
@@ -1,6 +1,7 @@
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
+using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Project
{
@@ -11,7 +12,7 @@ namespace ICSharpCode.SharpDevelop.Project
Module
};
- public interface IProject : ISolutionFolder, IDisposable
+ public interface IProject : ISolutionFolder, IDisposable, IMementoCapable
{
PropertyGroup BaseConfiguration {
get;
diff --git a/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs b/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs
index cf6d5ac935..2431d5ad49 100644
--- a/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs
+++ b/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs
@@ -137,6 +137,16 @@ namespace ICSharpCode.SharpDevelop.Project
{
openSolution = Solution.Load(fileName);
OnSolutionLoaded(new SolutionEventArgs(openSolution));
+ try {
+ foreach (IProject project in openSolution.Projects) {
+ string file = GetPreferenceFileName(project);
+ if (FileUtility.IsValidFileName(file) && File.Exists(file)) {
+ project.SetMemento(Properties.Load(file));
+ }
+ }
+ } catch (Exception ex) {
+ MessageService.ShowError(ex);
+ }
}
public static void SaveSolution()
@@ -150,9 +160,30 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
+ static string GetPreferenceFileName(IProject project)
+ {
+ string directory = PropertyService.ConfigDirectory + "preferences";
+ string fileName = project.FileName.Substring(3).Replace('/', '.').Replace('\\', '.').Replace(Path.DirectorySeparatorChar, '.');
+ string fullFileName = Path.Combine(directory, fileName + ".xml");
+ return fullFileName;
+ }
+
public static void SaveSolutionPreferences()
{
- // TODO:
+ string directory = PropertyService.ConfigDirectory + "preferences";
+ if (!Directory.Exists(directory)) {
+ Directory.CreateDirectory(directory);
+ }
+
+ foreach (IProject project in OpenSolution.Projects) {
+ Properties memento = project.CreateMemento();
+ if (memento == null) continue;
+
+ string fullFileName = GetPreferenceFileName(project);
+ if (FileUtility.IsValidFileName(fullFileName)) {
+ FileUtility.ObservedSave(new NamedFileOperationDelegate(memento.Save), fullFileName, FileErrorPolicy.Inform);
+ }
+ }
}
public static void CloseSolution()
@@ -160,6 +191,7 @@ namespace ICSharpCode.SharpDevelop.Project
if (openSolution != null) {
OnSolutionClosing(new SolutionEventArgs(openSolution));
+ SaveSolutionPreferences();
openSolution.Dispose();
openSolution = null;
@@ -182,7 +214,7 @@ namespace ICSharpCode.SharpDevelop.Project
{
project.IsDirty = true;
}
-
+
static void OnCurrentProjectChanged(ProjectEventArgs e)
{
if (CurrentProjectChanged != null) {
@@ -218,14 +250,14 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
- static void OnProjectConfigurationChanged(ProjectConfigurationEventArgs e)
+ static void OnProjectConfigurationChanged(ProjectConfigurationEventArgs e)
{
if (ProjectConfigurationChanged != null) {
ProjectConfigurationChanged(null, e);
}
}
- static void OnSolutionConfigurationChanged(SolutionConfigurationEventArgs e)
+ static void OnSolutionConfigurationChanged(SolutionConfigurationEventArgs e)
{
if (SolutionConfigurationChanged != null) {
SolutionConfigurationChanged(null, e);
@@ -246,7 +278,7 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
- static void OnEndBuild(EventArgs e)
+ static void OnEndBuild(EventArgs e)
{
if (EndBuild != null) {
EndBuild(null, e);
@@ -267,7 +299,7 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
- static void OnSolutionFolderRemoved(SolutionFolderEventArgs e)
+ static void OnSolutionFolderRemoved(SolutionFolderEventArgs e)
{
if (SolutionFolderRemoved != null) {
SolutionFolderRemoved(null, e);
diff --git a/src/Main/Base/Project/Src/TextEditor/Bookmarks/Bookmark.cs b/src/Main/Base/Project/Src/TextEditor/Bookmarks/Bookmark.cs
index 47ba7afba2..62a169713f 100644
--- a/src/Main/Base/Project/Src/TextEditor/Bookmarks/Bookmark.cs
+++ b/src/Main/Base/Project/Src/TextEditor/Bookmarks/Bookmark.cs
@@ -6,6 +6,7 @@
//
using System;
+using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
@@ -19,6 +20,7 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
///
/// Description of Bookmark.
///
+ [TypeConverter(typeof(BookmarkConverter))]
public class SDBookmark : Bookmark
{
string fileName;
diff --git a/src/Main/Base/Project/Src/TextEditor/Bookmarks/BookmarkConverter.cs b/src/Main/Base/Project/Src/TextEditor/Bookmarks/BookmarkConverter.cs
new file mode 100644
index 0000000000..5baecb2b15
--- /dev/null
+++ b/src/Main/Base/Project/Src/TextEditor/Bookmarks/BookmarkConverter.cs
@@ -0,0 +1,73 @@
+//
+//
+//
+//
+//
+//
+
+
+using System;
+using System.ComponentModel;
+using System.Text;
+using System.Globalization;
+using ICSharpCode.Core;
+using ICSharpCode.TextEditor.Document;
+
+namespace ICSharpCode.SharpDevelop.Bookmarks
+{
+ public sealed class BookmarkConverter : TypeConverter
+ {
+ public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
+ {
+ if (sourceType == typeof(string)) {
+ return true;
+ } else {
+ return base.CanConvertFrom(context, sourceType);
+ }
+ }
+
+ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
+ {
+ if (value is string) {
+ string[] v = ((string)value).Split('|');
+ string fileName = v[1];
+ int lineNumber = int.Parse(v[2], culture);
+ SDBookmark bookmark;
+ switch (v[0]) {
+ case "Breakpoint":
+ bookmark = new Breakpoint(null, fileName, lineNumber).Bookmark;
+ break;
+ default:
+ bookmark = new SDBookmark(fileName, null, lineNumber);
+ break;
+ }
+ bookmark.IsEnabled = bool.Parse(v[3]);
+ return bookmark;
+ } else {
+ return base.ConvertFrom(context, culture, value);
+ }
+ }
+
+ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
+ {
+ SDBookmark bookmark = value as SDBookmark;
+ if (destinationType == typeof(string) && bookmark != null) {
+ StringBuilder b = new StringBuilder();
+ if (bookmark is BreakpointBookmark) {
+ b.Append("Breakpoint");
+ } else {
+ b.Append("Bookmark");
+ }
+ b.Append('|');
+ b.Append(bookmark.FileName);
+ b.Append('|');
+ b.Append(bookmark.LineNumber);
+ b.Append('|');
+ b.Append(bookmark.IsEnabled.ToString());
+ return b.ToString();
+ } else {
+ return base.ConvertTo(context, culture, value, destinationType);
+ }
+ }
+ }
+}
diff --git a/src/Main/Base/Project/Src/TextEditor/Bookmarks/BookmarkManager.cs b/src/Main/Base/Project/Src/TextEditor/Bookmarks/BookmarkManager.cs
index a138e04d41..112fd4f03d 100644
--- a/src/Main/Base/Project/Src/TextEditor/Bookmarks/BookmarkManager.cs
+++ b/src/Main/Base/Project/Src/TextEditor/Bookmarks/BookmarkManager.cs
@@ -60,6 +60,17 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
}
}
+ public static List GetProjectBookmarks(ICSharpCode.SharpDevelop.Project.IProject project)
+ {
+ List projectBookmarks = new List();
+ foreach (SDBookmark mark in bookmarks) {
+ if (mark.FileName != null && project.IsFileInProject(mark.FileName)) {
+ projectBookmarks.Add(mark);
+ }
+ }
+ return projectBookmarks;
+ }
+
public static event BookmarkEventHandler Removed;
public static event BookmarkEventHandler Added;
}
diff --git a/src/Main/Base/Project/Src/TextEditor/Bookmarks/Pad/Nodes/BookmarkFolderNode.cs b/src/Main/Base/Project/Src/TextEditor/Bookmarks/Pad/Nodes/BookmarkFolderNode.cs
index 6e19471136..03c8e5beba 100644
--- a/src/Main/Base/Project/Src/TextEditor/Bookmarks/Pad/Nodes/BookmarkFolderNode.cs
+++ b/src/Main/Base/Project/Src/TextEditor/Bookmarks/Pad/Nodes/BookmarkFolderNode.cs
@@ -1,4 +1,5 @@
using System;
+using System.IO;
using System.Drawing;
using System.Collections.Generic;
using System.Windows.Forms;
@@ -15,10 +16,11 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
{
List marks = new List();
string fileName;
+ string fileNameText;
string occurences;
Image icon;
- public List Marks {
+ public List Marks {
get {
return marks;
}
@@ -28,6 +30,7 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
{
drawDefault = false;
this.fileName = fileName;
+ fileNameText = Path.GetFileName(fileName) + " in " + Path.GetDirectoryName(fileName);
icon = IconService.GetBitmap(IconService.GetImageForFile(fileName));
Nodes.Add(new TreeNode());
}
@@ -39,13 +42,13 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
} else {
occurences = " (" + marks.Count + " bookmarks)";
}
- this.Text = fileName + occurences;
+ this.Text = fileNameText + occurences;
}
protected override int MeasureItemWidth(DrawTreeNodeEventArgs e)
{
Graphics g = e.Graphics;
- int x = MeasureTextWidth(g, fileName, Font);
+ int x = MeasureTextWidth(g, fileNameText, Font);
x += MeasureTextWidth(g, occurences, ItalicFont);
if (icon != null) {
x += icon.Width;
@@ -60,17 +63,30 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
g.DrawImage(icon, x, e.Bounds.Y, icon.Width, icon.Height);
x += icon.Width;
}
- DrawText(g, fileName, Brushes.Black, Font, ref x, e.Bounds.Y);
+ DrawText(g, fileNameText, Brushes.Black, Font, ref x, e.Bounds.Y);
DrawText(g, occurences, Brushes.Gray, ItalicFont, ref x, e.Bounds.Y);
}
public void AddMark(SDBookmark mark)
{
- marks.Add(mark);
+ int index = -1;
+ for (int i = 0; i < marks.Count; ++i) {
+ if (mark.LineNumber < marks[i].LineNumber) {
+ index = i;
+ break;
+ }
+ }
+ if (index < 0)
+ marks.Add(mark);
+ else
+ marks.Insert(index, mark);
if (isInitialized) {
BookmarkNode newNode = new BookmarkNode(mark);
- Nodes.Add(newNode);
+ if (index < 0)
+ Nodes.Add(newNode);
+ else
+ Nodes.Insert(index, newNode);
newNode.EnsureVisible();
}
SetText();
@@ -95,7 +111,7 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
Nodes.Clear();
if (marks.Count > 0) {
IDocument document = marks[0].Document;
- if (document.HighlightingStrategy == null) {
+ if (document != null && document.HighlightingStrategy == null) {
document.HighlightingStrategy = HighlightingStrategyFactory.CreateHighlightingStrategyForFile(fileName);
}
foreach (SDBookmark mark in marks) {
diff --git a/src/Main/Base/Project/Src/TextEditor/Bookmarks/Pad/Nodes/BookmarkNode.cs b/src/Main/Base/Project/Src/TextEditor/Bookmarks/Pad/Nodes/BookmarkNode.cs
index 4b2e7293ea..c257e35206 100644
--- a/src/Main/Base/Project/Src/TextEditor/Bookmarks/Pad/Nodes/BookmarkNode.cs
+++ b/src/Main/Base/Project/Src/TextEditor/Bookmarks/Pad/Nodes/BookmarkNode.cs
@@ -37,15 +37,37 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
Checked = bookmark.IsEnabled;
positionText = "(" + (bookmark.LineNumber + 1) + ") ";
- line = bookmark.Document.GetLineSegment(bookmark.LineNumber);
- Text = positionText + bookmark.Document.GetText(line);
+ bookmark.DocumentChanged += BookmarkDocumentChanged;
+ bookmark.LineNumberChanged += BookmarkLineNumberChanged;
+ if (bookmark.Document != null) {
+ line = bookmark.Document.GetLineSegment(bookmark.LineNumber);
+ Text = positionText + bookmark.Document.GetText(line);
+ } else {
+ Text = positionText;
+ }
+ }
+
+ void BookmarkDocumentChanged(object sender, EventArgs e)
+ {
+ if (bookmark.Document != null) {
+ line = bookmark.Document.GetLineSegment(bookmark.LineNumber);
+ Text = positionText + bookmark.Document.GetText(line);
+ }
+ }
+
+ void BookmarkLineNumberChanged(object sender, EventArgs e)
+ {
+ positionText = "(" + (bookmark.LineNumber + 1) + ") ";
+ BookmarkDocumentChanged(sender, e);
}
protected override int MeasureItemWidth(DrawTreeNodeEventArgs e)
{
Graphics g = e.Graphics;
int x = MeasureTextWidth(g, positionText, BoldMonospacedFont);
- x += MeasureTextWidth(g, bookmark.Document.GetText(line).Replace("\t", " "), BoldMonospacedFont);
+ if (line != null) {
+ x += MeasureTextWidth(g, bookmark.Document.GetText(line).Replace("\t", " "), BoldMonospacedFont);
+ }
return x;
}
@@ -57,7 +79,9 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
spaceSize = g.MeasureString("-", Font, new PointF(0, 0), StringFormat.GenericTypographic);
- DrawLine(g, line, e.Bounds.Y, x);
+ if (line != null) {
+ DrawLine(g, line, e.Bounds.Y, x);
+ }
}
public override void ActivateItem()
diff --git a/src/Main/Core/Project/Src/AddInTree/AddIn/AddIn.cs b/src/Main/Core/Project/Src/AddInTree/AddIn/AddIn.cs
index a106a14180..092ba332f4 100644
--- a/src/Main/Core/Project/Src/AddInTree/AddIn/AddIn.cs
+++ b/src/Main/Core/Project/Src/AddInTree/AddIn/AddIn.cs
@@ -23,7 +23,7 @@ namespace ICSharpCode.Core
return o;
}
}
- return null;
+ throw new ArgumentException("Cannot create object: " + className);
}
public List Runtimes {
diff --git a/src/Main/Core/Project/Src/Services/PropertyService/Properties.cs b/src/Main/Core/Project/Src/Services/PropertyService/Properties.cs
index cb2ff9212a..b369c74775 100644
--- a/src/Main/Core/Project/Src/Services/PropertyService/Properties.cs
+++ b/src/Main/Core/Project/Src/Services/PropertyService/Properties.cs
@@ -2,11 +2,31 @@ using System;
using System.IO;
using System.ComponentModel;
using System.Text;
+using System.Collections;
using System.Collections.Generic;
using System.Xml;
namespace ICSharpCode.Core
{
+ ///
+ /// This interface flags an object beeing "mementocapable". This means that the
+ /// state of the object could be saved to an object
+ /// and set from a object from the same class.
+ /// This is used to save and restore the state of GUI objects.
+ ///
+ public interface IMementoCapable
+ {
+ ///
+ /// Creates a new memento from the state.
+ ///
+ Properties CreateMemento();
+
+ ///
+ /// Sets the state to the given memento.
+ ///
+ void SetMemento(Properties memento);
+ }
+
///
/// Description of PropertyGroup.
///
@@ -23,21 +43,6 @@ namespace ICSharpCode.Core
}
}
- public T Get(string property, T defaultValue)
- {
- if (!properties.ContainsKey(property)) {
- properties.Add(property, defaultValue);
- return defaultValue;
- }
- object o = properties[property];
-
- if (o is System.String && typeof(T) != typeof(System.String)) {
- TypeConverter c = TypeDescriptor.GetConverter(typeof(T));
- return (T)c.ConvertFromInvariantString(o.ToString());
- }
- return (T)o;
- }
-
public object Get(string property)
{
if (!properties.ContainsKey(property)) {
@@ -61,7 +66,7 @@ namespace ICSharpCode.Core
public bool Contains(string property)
{
return properties.ContainsKey(property);
- }
+ }
public bool Remove(string property)
{
@@ -71,7 +76,7 @@ namespace ICSharpCode.Core
public Properties()
{
}
-
+
public override string ToString()
{
StringBuilder sb = new StringBuilder();
@@ -86,7 +91,7 @@ namespace ICSharpCode.Core
return sb.ToString();
}
- public static Properties ReadFromAttributes(XmlReader reader)
+ public static Properties ReadFromAttributes(XmlReader reader)
{
Properties properties = new Properties();
if (reader.HasAttributes) {
@@ -118,6 +123,9 @@ namespace ICSharpCode.Core
Properties p = new Properties();
p.ReadProperties(reader, "Properties");
properties[propertyName] = p;
+ } else if (propertyName == "Array") {
+ propertyName = reader.GetAttribute(0);
+ properties[propertyName] = ReadArray(reader);
} else {
properties[propertyName] = reader.HasAttributes ? reader.GetAttribute(0) : null;
}
@@ -126,23 +134,59 @@ namespace ICSharpCode.Core
}
}
+ ArrayList ReadArray(XmlTextReader reader)
+ {
+ ArrayList l = new ArrayList();
+ while (reader.Read()) {
+ switch (reader.NodeType) {
+ case XmlNodeType.EndElement:
+ if (reader.LocalName == "Array") {
+ return l;
+ }
+ break;
+ case XmlNodeType.Element:
+ l.Add(reader.HasAttributes ? reader.GetAttribute(0) : null);
+ break;
+ }
+ }
+ return l;
+ }
+
public void WriteProperties(XmlTextWriter writer)
{
foreach (KeyValuePair entry in properties) {
-
- if (entry.Value is Properties) {
+ object val = entry.Value;
+ if (val is Properties) {
writer.WriteStartElement("Properties");
writer.WriteAttributeString("name", entry.Key);
- ((Properties)entry.Value).WriteProperties(writer);
+ ((Properties)val).WriteProperties(writer);
+ writer.WriteEndElement();
+ } else if (val is Array) {
+ writer.WriteStartElement("Array");
+ writer.WriteAttributeString("name", entry.Key);
+ foreach (object o in (Array)val) {
+ writer.WriteStartElement("Element");
+ WriteValue(writer, o);
+ writer.WriteEndElement();
+ }
+ writer.WriteEndElement();
+ } else {
+ writer.WriteStartElement(entry.Key);
+ WriteValue(writer, val);
writer.WriteEndElement();
- continue;
}
-
- writer.WriteStartElement(entry.Key);
- if (entry.Value != null) {
- writer.WriteAttributeString("value", entry.Value.ToString());
+ }
+ }
+
+ void WriteValue(XmlTextWriter writer, object val)
+ {
+ if (val != null) {
+ if (val is string) {
+ writer.WriteAttributeString("value", val.ToString());
+ } else {
+ TypeConverter c = TypeDescriptor.GetConverter(val.GetType());
+ writer.WriteAttributeString("value", c.ConvertToInvariantString(val));
}
- writer.WriteEndElement();
}
}
@@ -184,6 +228,35 @@ namespace ICSharpCode.Core
}
return null;
}
+
+ public T Get(string property, T defaultValue)
+ {
+ if (!properties.ContainsKey(property)) {
+ properties.Add(property, defaultValue);
+ return defaultValue;
+ }
+ object o = properties[property];
+
+ if (o is string && typeof(T) != typeof(string)) {
+ TypeConverter c = TypeDescriptor.GetConverter(typeof(T));
+ o = c.ConvertFromInvariantString(o.ToString());
+ properties[property] = o; // store for future look up
+ } else if (o is ArrayList && typeof(T).IsArray) {
+ ArrayList list = (ArrayList)o;
+ Type elementType = typeof(T).GetElementType();
+ Array arr = System.Array.CreateInstance(elementType, list.Count);
+ TypeConverter c = TypeDescriptor.GetConverter(elementType);
+ for (int i = 0; i < arr.Length; ++i) {
+ if (list[i] != null) {
+ arr.SetValue(c.ConvertFromInvariantString(list[i].ToString()), i);
+ }
+ }
+ o = arr;
+ properties[property] = o; // store for future look up
+ }
+ return (T)o;
+ }
+
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null) {