Browse Source

reimplement Workspace architecture with a single WorkspaceModel

pull/48/head
Siegfried Pammer 12 years ago
parent
commit
7679f1cc49
  1. 45
      src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserTreeView.cs
  2. 95
      src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserWorkspace.cs
  3. 27
      src/Main/Base/Project/Dom/ClassBrowser/IClassBrowser.cs
  4. 48
      src/Main/Base/Project/Dom/ClassBrowser/WorkspaceModel.cs
  5. 32
      src/Main/Base/Project/Dom/ClassBrowser/WorkspaceTreeNode.cs
  6. 12
      src/Main/Base/Project/Dom/IModelCollection.cs
  7. 4
      src/Main/Base/Project/Dom/ModelCollectionTreeNode.cs
  8. 1
      src/Main/Base/Project/ICSharpCode.SharpDevelop.addin
  9. 3
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  10. 17
      src/Main/Base/Project/Src/Internal/Doozers/PadDescriptor.cs
  11. 30
      src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserPad.cs
  12. 3
      src/Main/SharpDevelop/Workbench/WpfWorkbench.cs

45
src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserTreeView.cs

@ -2,33 +2,38 @@ @@ -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<SharpTreeNode> 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 @@ -40,7 +45,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
}
}
public interface IClassBrowserTreeView
public interface IClassBrowserTreeView : IClassBrowser
{
}

95
src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserWorkspace.cs

@ -1,95 +0,0 @@ @@ -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
{
/// <summary>
/// Description of ClassBrowserWorkspace.
/// </summary>
public class ClassBrowserWorkspace
{
ISolution assignedSolution;
IModelCollection<IAssemblyModel> loadedAssemblies;
string workspaceName;
public ClassBrowserWorkspace(ISolution assignedSolution, IEnumerable<IAssemblyModel> assemblies = null)
: this(assignedSolution.FileName, assemblies)
{
this.assignedSolution = assignedSolution;
}
public ClassBrowserWorkspace(string workspaceName, IEnumerable<IAssemblyModel> assemblies = null)
{
this.workspaceName = workspaceName;
this.loadedAssemblies = new SimpleModelCollection<IAssemblyModel>(assemblies ?? EmptyList<IAssemblyModel>.Instance);
}
public bool IsAssigned {
get { return assignedSolution != null; }
}
public ISolution AssignedSolution {
get { return assignedSolution; }
}
public string Name {
get { return workspaceName; }
}
public IModelCollection<IAssemblyModel> LoadedAssemblies {
get { return loadedAssemblies; }
}
}
public class ClassBrowserSettings
{
IAssemblyReference[] ResolveReferences(IUnresolvedAssembly asm)
{
return new IAssemblyReference[0];
}
IAssemblyModel[] LoadAssemblyList(string name)
{
var assemblyNames = Container.GetList<string>("AssemblyList." + name);
CecilLoader loader = new CecilLoader();
var factory = SD.GetRequiredService<IModelFactory>();
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("<default>");
}
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)
{
}
}
}

27
src/Main/Base/Project/Dom/ClassBrowser/IClassBrowser.cs

@ -0,0 +1,27 @@ @@ -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<SharpTreeNode> SpecialNodes { get; }
AssemblyList AssemblyList { get; set; }
}
public class AssemblyList
{
public string Name { get; set; }
public IMutableModelCollection<IAssemblyModel> Assemblies { get; set; }
public AssemblyList()
{
Name = "<default>";
Assemblies = new SimpleModelCollection<IAssemblyModel>();
}
}
}

48
src/Main/Base/Project/Dom/ClassBrowser/WorkspaceModel.cs

@ -0,0 +1,48 @@ @@ -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
{
/// <summary>
/// Description of WorkspaceModel.
/// </summary>
public class WorkspaceModel : System.ComponentModel.INotifyPropertyChanged
{
IMutableModelCollection<SharpTreeNode> specialNodes;
public IMutableModelCollection<SharpTreeNode> 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<SharpTreeNode>();
this.AssemblyList = new AssemblyList();
}
}
}

32
src/Main/Base/Project/Dom/ClassBrowser/WorkspaceTreeNode.cs

@ -3,6 +3,7 @@ @@ -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 @@ -12,13 +13,21 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
/// </summary>
public class WorkspaceTreeNode : ModelCollectionTreeNode
{
ClassBrowserWorkspace workspace;
WorkspaceModel workspace;
public WorkspaceTreeNode(ClassBrowserWorkspace workspace)
public IMutableModelCollection<SharpTreeNode> 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 @@ -27,7 +36,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
}
protected override IModelCollection<object> ModelChildren {
get { return workspace.LoadedAssemblies; }
get { return workspace.AssemblyList.Assemblies; }
}
protected override IComparer<SharpTreeNode> NodeComparer {
@ -36,7 +45,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser @@ -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 @@ -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<SharpTreeNode> removedItems, IReadOnlyCollection<SharpTreeNode> addedItems)
{
SynchronizeModelChildren();
}
}
}

12
src/Main/Base/Project/Dom/IModelCollection.cs

@ -19,23 +19,11 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -19,23 +19,11 @@ namespace ICSharpCode.SharpDevelop.Dom
{
List<ModelCollectionChangedEventHandler<T>> _handlers = new List<ModelCollectionChangedEventHandler<T>>();
// public static ModelCollectionChangedEvent<T> operator+(ModelCollectionChangedEvent<T> eventObject, ModelCollectionChangedEventHandler<T> handler)
// {
// eventObject._handlers.Add(handler);
// return eventObject;
// }
public void AddHandler(ModelCollectionChangedEventHandler<T> handler)
{
_handlers.Add(handler);
}
// public static ModelCollectionChangedEvent<T> operator-(ModelCollectionChangedEvent<T> eventObject, ModelCollectionChangedEventHandler<T> handler)
// {
// eventObject._handlers.Remove(handler);
// return eventObject;
// }
public void RemoveHandler(ModelCollectionChangedEventHandler<T> handler)
{
_handlers.Remove(handler);

4
src/Main/Base/Project/Dom/ModelCollectionTreeNode.cs

@ -78,12 +78,14 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -78,12 +78,14 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
void SynchronizeModelChildren()
protected void SynchronizeModelChildren()
{
HashSet<object> set = new HashSet<object>(ModelChildren);
Children.RemoveAll(n => !set.Contains(n.Model));
set.ExceptWith(Children.Select(n => n.Model));
InsertChildren(set);
if (IsSpecialNode())
InsertSpecialNodes();
}
void ModelChildrenCollectionChanged(IReadOnlyCollection<object> removedItems, IReadOnlyCollection<object> addedItems)

1
src/Main/Base/Project/ICSharpCode.SharpDevelop.addin

@ -134,6 +134,7 @@ @@ -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" />
<Pad id = "SideBar"

3
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -86,12 +86,13 @@ @@ -86,12 +86,13 @@
<Compile Include="Designer\TypeResolutionService.cs" />
<Compile Include="Dom\ClassBrowser\AssemblyTreeNode.cs" />
<Compile Include="Dom\ClassBrowser\ClassBrowserTreeView.cs" />
<Compile Include="Dom\ClassBrowser\ClassBrowserWorkspace.cs" />
<Compile Include="Dom\ClassBrowser\IClassBrowser.cs" />
<Compile Include="Dom\ClassBrowser\MemberTreeNode.cs" />
<Compile Include="Dom\ClassBrowser\NamespaceTreeNode.cs" />
<Compile Include="Dom\ClassBrowser\ProjectTreeNode.cs" />
<Compile Include="Dom\ClassBrowser\SolutionTreeNode.cs" />
<Compile Include="Dom\ClassBrowser\TypeDefinitionTreeNode.cs" />
<Compile Include="Dom\ClassBrowser\WorkspaceModel.cs" />
<Compile Include="Dom\ClassBrowser\WorkspaceTreeNode.cs" />
<Compile Include="Dom\IAssemblyModel.cs" />
<Compile Include="Dom\IEntityModelContext.cs" />

17
src/Main/Base/Project/Src/Internal/Doozers/PadDescriptor.cs

@ -37,6 +37,9 @@ namespace ICSharpCode.SharpDevelop @@ -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 @@ -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 @@ -75,6 +79,7 @@ namespace ICSharpCode.SharpDevelop
this.icon = icon;
this.category = "none";
this.shortcut = "";
this.serviceInterface = null;
}
/// <summary>
@ -134,6 +139,18 @@ namespace ICSharpCode.SharpDevelop @@ -134,6 +139,18 @@ namespace ICSharpCode.SharpDevelop
}
}
/// <summary>
/// Gets the type of the service interface.
/// </summary>
public Type ServiceInterface {
get {
if (serviceInterface == null && addIn != null && !string.IsNullOrEmpty(serviceInterfaceName)) {
serviceInterface = addIn.FindType(serviceInterfaceName);
}
return serviceInterface;
}
}
/// <summary>
/// Gets/sets the default position of the pad.
/// </summary>

30
src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserPad.cs

@ -2,6 +2,8 @@ @@ -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; @@ -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<SharpTreeNode> 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 @@ -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 @@ -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 @@ -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<SolutionTreeNode>().ToArray())
treeView.SpecialNodes.Remove(node);
if (projectService.CurrentSolution != null)
treeView.SpecialNodes.Add(new SolutionTreeNode(projectService.CurrentSolution));
}
/// <summary>

3
src/Main/SharpDevelop/Workbench/WpfWorkbench.cs

@ -432,6 +432,9 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -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);

Loading…
Cancel
Save