diff --git a/src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserTreeView.cs b/src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserTreeView.cs index bd62b335e1..0a02246a14 100644 --- a/src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserTreeView.cs +++ b/src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserTreeView.cs @@ -2,33 +2,38 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; -using System.Diagnostics; -using System.Windows; +using System.Collections.Generic; using System.Windows.Controls; -using System.Windows.Input; -using ICSharpCode.Core.Presentation; using ICSharpCode.TreeView; -using ICSharpCode.SharpDevelop.Workbench; namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser { public class ClassBrowserTreeView : SharpTreeView, IClassBrowserTreeView { - ClassBrowserWorkspace currentWorkspace; + #region IClassBrowser implementation + + public ICollection SpecialNodes { + get { return ((WorkspaceTreeNode)Root).SpecialNodes; } + } + + public AssemblyList AssemblyList { + get { return ((WorkspaceTreeNode)Root).AssemblyList; } + set { ((WorkspaceTreeNode)Root).AssemblyList = value; } + } + + #endregion - public ClassBrowserWorkspace Workspace { - get { return currentWorkspace; } - set { - if (currentWorkspace == value) - return; - currentWorkspace = value; - if (currentWorkspace != null) { - this.Root = new WorkspaceTreeNode(currentWorkspace); - this.ShowRoot = currentWorkspace.LoadedAssemblies.Count > 0 || !currentWorkspace.IsAssigned; - } else { - this.Root = null; - } - } + public ClassBrowserTreeView() + { + WorkspaceTreeNode root = new WorkspaceTreeNode(); + ClassBrowserTreeView instance = this; + root.SpecialNodes.CollectionChanged += delegate { + instance.ShowRoot = root.Children.Count > 1; + }; + root.PropertyChanged += delegate { + instance.ShowRoot = root.Children.Count > 1; + }; + this.Root = root; } protected override void OnContextMenuOpening(ContextMenuEventArgs e) @@ -40,7 +45,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser } } - public interface IClassBrowserTreeView + public interface IClassBrowserTreeView : IClassBrowser { } diff --git a/src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserWorkspace.cs b/src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserWorkspace.cs deleted file mode 100644 index e5d1d683d6..0000000000 --- a/src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserWorkspace.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) - -using System; -using System.Collections.Generic; -using System.Linq; -using ICSharpCode.Core; -using ICSharpCode.NRefactory; -using ICSharpCode.NRefactory.TypeSystem; -using ICSharpCode.NRefactory.TypeSystem.Implementation; -using ICSharpCode.SharpDevelop.Project; - -namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser -{ - /// - /// Description of ClassBrowserWorkspace. - /// - public class ClassBrowserWorkspace - { - ISolution assignedSolution; - IModelCollection loadedAssemblies; - string workspaceName; - - public ClassBrowserWorkspace(ISolution assignedSolution, IEnumerable assemblies = null) - : this(assignedSolution.FileName, assemblies) - { - this.assignedSolution = assignedSolution; - } - - public ClassBrowserWorkspace(string workspaceName, IEnumerable assemblies = null) - { - this.workspaceName = workspaceName; - this.loadedAssemblies = new SimpleModelCollection(assemblies ?? EmptyList.Instance); - } - - public bool IsAssigned { - get { return assignedSolution != null; } - } - - public ISolution AssignedSolution { - get { return assignedSolution; } - } - - public string Name { - get { return workspaceName; } - } - - public IModelCollection LoadedAssemblies { - get { return loadedAssemblies; } - } - } - - public class ClassBrowserSettings - { - IAssemblyReference[] ResolveReferences(IUnresolvedAssembly asm) - { - return new IAssemblyReference[0]; - } - - IAssemblyModel[] LoadAssemblyList(string name) - { - var assemblyNames = Container.GetList("AssemblyList." + name); - CecilLoader loader = new CecilLoader(); - var factory = SD.GetRequiredService(); - return assemblyNames - .Select(loader.LoadAssemblyFile) - .Select(asm => new AssemblyEntityModelContext(asm, ResolveReferences(asm))) - .Select(factory.CreateAssemblyModel) - .ToArray(); - } - - readonly Properties Container = SD.PropertyService.NestedProperties(typeof(ClassBrowserSettings).FullName); - - public ClassBrowserWorkspace LoadDefaultWorkspace() - { - return LoadWorkspace(""); - } - - public ClassBrowserWorkspace LoadWorkspace(string name) - { - return new ClassBrowserWorkspace(name, LoadAssemblyList(name)); - } - - public ClassBrowserWorkspace LoadForSolution(ISolution solution) - { - // maybe use solution.Preferences? - return new ClassBrowserWorkspace(solution, LoadAssemblyList(solution.FileName)); - } - - public void SaveWorkspace(ClassBrowserWorkspace workspace) - { - - } - } -} diff --git a/src/Main/Base/Project/Dom/ClassBrowser/IClassBrowser.cs b/src/Main/Base/Project/Dom/ClassBrowser/IClassBrowser.cs new file mode 100644 index 0000000000..26a9d84436 --- /dev/null +++ b/src/Main/Base/Project/Dom/ClassBrowser/IClassBrowser.cs @@ -0,0 +1,27 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using ICSharpCode.TreeView; + +namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser +{ + public interface IClassBrowser + { + ICollection SpecialNodes { get; } + AssemblyList AssemblyList { get; set; } + } + + public class AssemblyList + { + public string Name { get; set; } + public IMutableModelCollection Assemblies { get; set; } + + public AssemblyList() + { + Name = ""; + Assemblies = new SimpleModelCollection(); + } + } +} diff --git a/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceModel.cs b/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceModel.cs new file mode 100644 index 0000000000..9e3e1da6e6 --- /dev/null +++ b/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceModel.cs @@ -0,0 +1,48 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using ICSharpCode.TreeView; + +namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser +{ + /// + /// Description of WorkspaceModel. + /// + public class WorkspaceModel : System.ComponentModel.INotifyPropertyChanged + { + IMutableModelCollection specialNodes; + public IMutableModelCollection SpecialNodes { + get { return specialNodes; } + } + + AssemblyList assemblyList; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void OnPropertyChanged(string propertyName) + { + if (PropertyChanged != null) { + PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public AssemblyList AssemblyList { + get { + return assemblyList; + } + set { + if (assemblyList != value) { + assemblyList = value; + OnPropertyChanged("AssemblyList"); + } + } + } + public WorkspaceModel() + { + this.specialNodes = new SimpleModelCollection(); + this.AssemblyList = new AssemblyList(); + } + } +} diff --git a/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceTreeNode.cs b/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceTreeNode.cs index b17ebc07ba..9eb0abb97a 100644 --- a/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceTreeNode.cs +++ b/src/Main/Base/Project/Dom/ClassBrowser/WorkspaceTreeNode.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using ICSharpCode.TreeView; namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser @@ -12,13 +13,21 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser /// public class WorkspaceTreeNode : ModelCollectionTreeNode { - ClassBrowserWorkspace workspace; + WorkspaceModel workspace; - public WorkspaceTreeNode(ClassBrowserWorkspace workspace) + public IMutableModelCollection SpecialNodes { + get { return workspace.SpecialNodes; } + } + + public AssemblyList AssemblyList { + get { return workspace.AssemblyList; } + set { workspace.AssemblyList = value; } + } + + public WorkspaceTreeNode() { - if (workspace == null) - throw new ArgumentNullException("workspace"); - this.workspace = workspace; + this.workspace = new WorkspaceModel(); + this.workspace.SpecialNodes.CollectionChanged += SpecialNodesModelCollectionChanged; } protected override object GetModel() @@ -27,7 +36,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser } protected override IModelCollection ModelChildren { - get { return workspace.LoadedAssemblies; } + get { return workspace.AssemblyList.Assemblies; } } protected override IComparer NodeComparer { @@ -36,7 +45,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser public override object Text { get { - return "Workspace " + workspace.Name; + return "Workspace " + AssemblyList.Name; } } @@ -53,9 +62,12 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser protected override void InsertSpecialNodes() { - if (workspace.IsAssigned) { - InsertChildren(new[] { workspace.AssignedSolution }); - } + Children.AddRange(workspace.SpecialNodes); + } + + void SpecialNodesModelCollectionChanged(IReadOnlyCollection removedItems, IReadOnlyCollection addedItems) + { + SynchronizeModelChildren(); } } } diff --git a/src/Main/Base/Project/Dom/IModelCollection.cs b/src/Main/Base/Project/Dom/IModelCollection.cs index 608c686572..efde573e4b 100644 --- a/src/Main/Base/Project/Dom/IModelCollection.cs +++ b/src/Main/Base/Project/Dom/IModelCollection.cs @@ -19,23 +19,11 @@ namespace ICSharpCode.SharpDevelop.Dom { List> _handlers = new List>(); -// public static ModelCollectionChangedEvent operator+(ModelCollectionChangedEvent eventObject, ModelCollectionChangedEventHandler handler) -// { -// eventObject._handlers.Add(handler); -// return eventObject; -// } - public void AddHandler(ModelCollectionChangedEventHandler handler) { _handlers.Add(handler); } -// public static ModelCollectionChangedEvent operator-(ModelCollectionChangedEvent eventObject, ModelCollectionChangedEventHandler handler) -// { -// eventObject._handlers.Remove(handler); -// return eventObject; -// } - public void RemoveHandler(ModelCollectionChangedEventHandler handler) { _handlers.Remove(handler); diff --git a/src/Main/Base/Project/Dom/ModelCollectionTreeNode.cs b/src/Main/Base/Project/Dom/ModelCollectionTreeNode.cs index 57767df6ae..3bbe23f81c 100644 --- a/src/Main/Base/Project/Dom/ModelCollectionTreeNode.cs +++ b/src/Main/Base/Project/Dom/ModelCollectionTreeNode.cs @@ -78,12 +78,14 @@ namespace ICSharpCode.SharpDevelop.Dom } } - void SynchronizeModelChildren() + protected void SynchronizeModelChildren() { HashSet set = new HashSet(ModelChildren); Children.RemoveAll(n => !set.Contains(n.Model)); set.ExceptWith(Children.Select(n => n.Model)); InsertChildren(set); + if (IsSpecialNode()) + InsertSpecialNodes(); } void ModelChildrenCollectionChanged(IReadOnlyCollection removedItems, IReadOnlyCollection addedItems) diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin b/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin index 7bbc1dc26f..984f5175ad 100755 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin @@ -134,6 +134,7 @@ title = "${res:MainWindow.Windows.ClassScoutLabel}" icon = "PadIcons.ClassBrowser" class = "ICSharpCode.SharpDevelop.Dom.ClassBrowser.ClassBrowserPad" + serviceInterface = "ICSharpCode.SharpDevelop.Dom.ClassBrowser.IClassBrowser" defaultPosition = "Right" /> - + + diff --git a/src/Main/Base/Project/Src/Internal/Doozers/PadDescriptor.cs b/src/Main/Base/Project/Src/Internal/Doozers/PadDescriptor.cs index 1f39848389..0aaa29a0ac 100644 --- a/src/Main/Base/Project/Src/Internal/Doozers/PadDescriptor.cs +++ b/src/Main/Base/Project/Src/Internal/Doozers/PadDescriptor.cs @@ -37,6 +37,9 @@ namespace ICSharpCode.SharpDevelop AddIn addIn; Type padType; + string serviceInterfaceName; + Type serviceInterface; + IPadContent padContent; bool padContentCreated; @@ -53,6 +56,7 @@ namespace ICSharpCode.SharpDevelop icon = codon.Properties["icon"]; title = codon.Properties["title"]; @class = codon.Properties["class"]; + serviceInterfaceName = codon.Properties["serviceInterface"]; if (!string.IsNullOrEmpty(codon.Properties["defaultPosition"])) { DefaultPosition = (DefaultPadPositions)Enum.Parse(typeof(DefaultPadPositions), codon.Properties["defaultPosition"]); } @@ -75,6 +79,7 @@ namespace ICSharpCode.SharpDevelop this.icon = icon; this.category = "none"; this.shortcut = ""; + this.serviceInterface = null; } /// @@ -134,6 +139,18 @@ namespace ICSharpCode.SharpDevelop } } + /// + /// Gets the type of the service interface. + /// + public Type ServiceInterface { + get { + if (serviceInterface == null && addIn != null && !string.IsNullOrEmpty(serviceInterfaceName)) { + serviceInterface = addIn.FindType(serviceInterfaceName); + } + return serviceInterface; + } + } + /// /// Gets/sets the default position of the pad. /// diff --git a/src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserPad.cs b/src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserPad.cs index 3369d695c7..871bc7a139 100644 --- a/src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserPad.cs +++ b/src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserPad.cs @@ -2,6 +2,8 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.Linq; +using System.Collections.Generic; using System.Diagnostics; using System.Windows.Controls; using ICSharpCode.Core.Presentation; @@ -11,11 +13,23 @@ using ICSharpCode.SharpDevelop.Workbench; namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser { - class ClassBrowserPad : AbstractPadContent + class ClassBrowserPad : AbstractPadContent, IClassBrowser { + #region IClassBrowser implementation + + public ICollection SpecialNodes { + get { return treeView.SpecialNodes; } + } + + public AssemblyList AssemblyList { + get { return treeView.AssemblyList; } + set { treeView.AssemblyList = value; } + } + + #endregion + IProjectService projectService; ClassBrowserTreeView treeView; - ClassBrowserSettings settings; DockPanel panel; ToolBar toolBar; @@ -27,8 +41,6 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser public ClassBrowserPad(IProjectService projectService) { this.projectService = projectService; - this.settings = new ClassBrowserSettings(); - panel = new DockPanel(); treeView = new ClassBrowserTreeView(); // treeView must be created first because it's used by CreateToolBar @@ -39,7 +51,6 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser panel.Children.Add(treeView); //treeView.ContextMenu = CreateContextMenu("/SharpDevelop/Pads/UnitTestsPad/ContextMenu"); - projectService.CurrentSolutionChanged += ProjectServiceCurrentSolutionChanged; ProjectServiceCurrentSolutionChanged(null, null); } @@ -60,11 +71,10 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser void ProjectServiceCurrentSolutionChanged(object sender, EventArgs e) { - if (projectService.CurrentSolution == null) { - treeView.Workspace = settings.LoadDefaultWorkspace(); - } else { - treeView.Workspace = settings.LoadForSolution(projectService.CurrentSolution); - } + foreach (var node in treeView.SpecialNodes.OfType().ToArray()) + treeView.SpecialNodes.Remove(node); + if (projectService.CurrentSolution != null) + treeView.SpecialNodes.Add(new SolutionTreeNode(projectService.CurrentSolution)); } /// diff --git a/src/Main/SharpDevelop/Workbench/WpfWorkbench.cs b/src/Main/SharpDevelop/Workbench/WpfWorkbench.cs index 7b04b7b828..4aa30f9c29 100644 --- a/src/Main/SharpDevelop/Workbench/WpfWorkbench.cs +++ b/src/Main/SharpDevelop/Workbench/WpfWorkbench.cs @@ -432,6 +432,9 @@ namespace ICSharpCode.SharpDevelop.Workbench throw new ArgumentException("Pad is already loaded"); padDescriptorCollection.Add(content); + if (content.ServiceInterface != null) { + SD.Services.AddService(content.ServiceInterface, delegate { return content.PadContent; }); + } if (WorkbenchLayout != null) { WorkbenchLayout.ShowPad(content);