diff --git a/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserPad.cs b/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserPad.cs
index 77f448a523..44bc2b8a86 100644
--- a/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserPad.cs
+++ b/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserPad.cs
@@ -54,10 +54,11 @@ namespace ICSharpCode.SharpDevelop.Project
instance = this;
ProjectService.SolutionLoaded += ProjectServiceSolutionLoaded;
ProjectService.SolutionClosed += ProjectServiceSolutionClosed;
+ ProjectService.SolutionPreferencesSaving += ProjectServiceSolutionPreferencesSaving;
WorkbenchSingleton.Workbench.ActiveWorkbenchWindowChanged += ActiveWindowChanged;
if (ProjectService.OpenSolution != null) {
- projectBrowserPanel.ViewSolution(ProjectService.OpenSolution);
+ ProjectServiceSolutionLoaded(null, new SolutionEventArgs(ProjectService.OpenSolution));
}
}
@@ -66,9 +67,15 @@ namespace ICSharpCode.SharpDevelop.Project
ProjectBrowserControl.TreeView.StartLabelEdit(node);
}
+ void ProjectServiceSolutionPreferencesSaving(object sender, SolutionEventArgs e)
+ {
+ projectBrowserPanel.StoreViewState(e.Solution.Preferences.Properties);
+ }
+
void ProjectServiceSolutionLoaded(object sender, SolutionEventArgs e)
{
projectBrowserPanel.ViewSolution(e.Solution);
+ projectBrowserPanel.ReadViewState(e.Solution.Preferences.Properties);
}
void ProjectServiceSolutionClosed(object sender, EventArgs e)
@@ -180,6 +187,5 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
#endregion
-
}
}
diff --git a/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserPanel.cs b/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserPanel.cs
index d398c18a97..7b911c1a3f 100644
--- a/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserPanel.cs
+++ b/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserPanel.cs
@@ -8,6 +8,7 @@
using System;
using System.ComponentModel;
using System.Drawing;
+using System.Text;
using System.Windows.Forms;
using ICSharpCode.Core;
@@ -51,7 +52,7 @@ namespace ICSharpCode.SharpDevelop.Project
projectBrowserControl.TreeView.BeforeSelect += TreeViewBeforeSelect;
}
- void TreeViewBeforeSelect(object sender, TreeViewCancelEventArgs e)
+ void TreeViewBeforeSelect(object sender, TreeViewCancelEventArgs e)
{
AbstractProjectBrowserTreeNode node = e.Node as AbstractProjectBrowserTreeNode;
if (node == null) {
@@ -71,6 +72,86 @@ namespace ICSharpCode.SharpDevelop.Project
projectBrowserControl.ViewSolution(solution);
}
+ ///
+ /// Writes the current view state into the memento.
+ ///
+ public void StoreViewState(Properties memento)
+ {
+ memento.Set("ProjectBrowserState", GetViewStateString(projectBrowserControl.TreeView));
+ }
+
+ ///
+ /// Reads the view state from the memento.
+ ///
+ public void ReadViewState(Properties memento)
+ {
+ ApplyViewStateString(memento.Get("ProjectBrowserState", ""), projectBrowserControl.TreeView);
+ }
+
+ // example ViewStateString:
+ // [Main[ICSharpCode.SharpDevelop[Src[Gui[Pads[ProjectBrowser[]]]]Services[]]]]
+ // -> every node name is terminated by opening bracket
+ // -> only expanded nodes are included in the view state string
+ // -> after an opening bracket, an identifier or closing bracket must follow
+ // -> after a closing bracket, an identifier or closing bracket must follow
+ // -> nodes whose text contains '[' can not be saved
+ public static string GetViewStateString(TreeView treeView)
+ {
+ StringBuilder b = new StringBuilder();
+ WriteViewStateString(b, treeView.Nodes[0]);
+ return b.ToString();
+ }
+ static void WriteViewStateString(StringBuilder b, TreeNode node)
+ {
+ b.Append('[');
+ foreach (TreeNode subNode in node.Nodes) {
+ if (subNode.IsExpanded && subNode.Text.IndexOf('[') < 0) {
+ b.Append(subNode.Text);
+ WriteViewStateString(b, subNode);
+ }
+ }
+ b.Append(']');
+ }
+ public static void ApplyViewStateString(string viewState, TreeView treeView)
+ {
+ if (viewState.Length == 0)
+ return;
+ int i = 0;
+ ApplyViewStateString(treeView.Nodes[0], viewState, ref i);
+ System.Diagnostics.Debug.Assert(i == viewState.Length - 1);
+ }
+ static void ApplyViewStateString(TreeNode node, string viewState, ref int pos)
+ {
+ if (viewState[pos++] != '[')
+ throw new ArgumentException("pos must point to '['");
+ // expect an identifier or an closing bracket
+ while (viewState[pos] != ']') {
+ StringBuilder nameBuilder = new StringBuilder();
+ char ch;
+ while ((ch = viewState[pos++]) != '[') {
+ nameBuilder.Append(ch);
+ }
+ pos -= 1; // go back to '[' character
+ string nodeText = nameBuilder.ToString();
+ // find the node in question
+ TreeNode subNode = null;
+ if (node != null) {
+ foreach (TreeNode n in node.Nodes) {
+ if (n.Text == nodeText) {
+ subNode = n;
+ break;
+ }
+ }
+ }
+ if (subNode != null) {
+ subNode.Expand();
+ }
+ ApplyViewStateString(subNode, viewState, ref pos);
+ // pos now points to the closing bracket of the inner view state
+ pos += 1; // move to next character
+ }
+ }
+
public void Clear()
{
projectBrowserControl.Clear();
diff --git a/src/Main/Base/Project/Src/Project/Solution/SolutionPreferences.cs b/src/Main/Base/Project/Src/Project/Solution/SolutionPreferences.cs
index bc868d572f..bf66e907e9 100644
--- a/src/Main/Base/Project/Src/Project/Solution/SolutionPreferences.cs
+++ b/src/Main/Base/Project/Src/Project/Solution/SolutionPreferences.cs
@@ -14,6 +14,7 @@ namespace ICSharpCode.SharpDevelop.Project
public class SolutionPreferences : IMementoCapable
{
Solution solution;
+ Properties properties = new Properties();
string startupProject = "";
string activeConfiguration = "Debug";
string activePlatform = "Any CPU";
@@ -23,6 +24,12 @@ namespace ICSharpCode.SharpDevelop.Project
this.solution = solution;
}
+ public Properties Properties {
+ get {
+ return properties;
+ }
+ }
+
public IProject StartupProject {
get {
if (startupProject.Length == 0)
@@ -61,9 +68,9 @@ namespace ICSharpCode.SharpDevelop.Project
///
/// Creates a new memento from the state.
///
- public Properties CreateMemento()
+ Properties IMementoCapable.CreateMemento()
{
- Properties p = new Properties();
+ Properties p = properties;
p.Set("StartupProject", startupProject);
p.Set("ActiveConfiguration", activeConfiguration);
p.Set("ActivePlatform", activePlatform);
@@ -73,7 +80,7 @@ namespace ICSharpCode.SharpDevelop.Project
///
/// Sets the state to the given memento.
///
- public void SetMemento(Properties memento)
+ void IMementoCapable.SetMemento(Properties memento)
{
startupProject = memento.Get("StartupProject", "");
string configuration = memento.Get("ActiveConfiguration", activeConfiguration);
@@ -89,6 +96,8 @@ namespace ICSharpCode.SharpDevelop.Project
this.ActiveConfiguration = configuration;
this.ActivePlatform = platform;
+
+ this.properties = memento;
}
}
}
diff --git a/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs b/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs
index 538e862033..b54af80894 100644
--- a/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs
+++ b/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs
@@ -18,6 +18,7 @@ namespace ICSharpCode.SharpDevelop.Project
static IProject currentProject;
public static Solution OpenSolution {
+ [System.Diagnostics.DebuggerStepThrough]
get {
return openSolution;
}
@@ -218,16 +219,18 @@ namespace ICSharpCode.SharpDevelop.Project
openSolution = Solution.Load(fileName);
if (openSolution == null)
return;
- OnSolutionLoaded(new SolutionEventArgs(openSolution));
try {
string file = GetPreferenceFileName(openSolution.FileName);
if (FileUtility.IsValidFileName(file) && File.Exists(file)) {
- openSolution.Preferences.SetMemento(Properties.Load(file));
+ (openSolution.Preferences as IMementoCapable).SetMemento(Properties.Load(file));
}
ApplyConfigurationAndReadPreferences();
} catch (Exception ex) {
MessageService.ShowError(ex);
}
+ // preferences must be read before OnSolutionLoad is called to enable
+ // the event listeners to read e.Solution.Preferences.Properties
+ OnSolutionLoaded(new SolutionEventArgs(openSolution));
}
static void ApplyConfigurationAndReadPreferences()
@@ -275,8 +278,10 @@ namespace ICSharpCode.SharpDevelop.Project
solution.Save(solutionFile);
openSolution = solution;
- OnSolutionLoaded(new SolutionEventArgs(openSolution));
ApplyConfigurationAndReadPreferences();
+ // preferences must be read before OnSolutionLoad is called to enable
+ // the event listeners to read e.Solution.Preferences.Properties
+ OnSolutionLoaded(new SolutionEventArgs(openSolution));
}
public static void SaveSolution()
@@ -307,14 +312,13 @@ namespace ICSharpCode.SharpDevelop.Project
Directory.CreateDirectory(directory);
}
- string fullFileName;
- Properties memento = openSolution.Preferences.CreateMemento();
- if (memento != null) {
- fullFileName = GetPreferenceFileName(openSolution.FileName);
-
- if (FileUtility.IsValidFileName(fullFileName)) {
- FileUtility.ObservedSave(new NamedFileOperationDelegate(memento.Save), fullFileName, FileErrorPolicy.Inform);
- }
+ if (SolutionPreferencesSaving != null)
+ SolutionPreferencesSaving(null, new SolutionEventArgs(openSolution));
+ Properties memento = (openSolution.Preferences as IMementoCapable).CreateMemento();
+
+ string fullFileName = GetPreferenceFileName(openSolution.FileName);
+ if (FileUtility.IsValidFileName(fullFileName)) {
+ FileUtility.ObservedSave(new NamedFileOperationDelegate(memento.Save), fullFileName, FileErrorPolicy.Inform);
}
foreach (IProject project in OpenSolution.Projects) {
@@ -474,6 +478,12 @@ namespace ICSharpCode.SharpDevelop.Project
public static event EventHandler SolutionClosing;
public static event EventHandler SolutionClosed;
+ ///
+ /// Raised before the solution preferences are being saved. Allows you to save
+ /// your additional properties in the solution preferences.
+ ///
+ public static event EventHandler SolutionPreferencesSaving;
+
public static event ProjectEventHandler CurrentProjectChanged;
public static event EventHandler ProjectItemAdded;