|
|
@ -7,12 +7,26 @@ using System.Collections.Generic; |
|
|
|
using System.Diagnostics; |
|
|
|
using System.Diagnostics; |
|
|
|
using System.Windows.Controls; |
|
|
|
using System.Windows.Controls; |
|
|
|
using ICSharpCode.Core.Presentation; |
|
|
|
using ICSharpCode.Core.Presentation; |
|
|
|
|
|
|
|
using ICSharpCode.NRefactory; |
|
|
|
|
|
|
|
using ICSharpCode.NRefactory.TypeSystem; |
|
|
|
using ICSharpCode.TreeView; |
|
|
|
using ICSharpCode.TreeView; |
|
|
|
using ICSharpCode.SharpDevelop.Project; |
|
|
|
using ICSharpCode.SharpDevelop.Project; |
|
|
|
using ICSharpCode.SharpDevelop.Workbench; |
|
|
|
using ICSharpCode.SharpDevelop.Workbench; |
|
|
|
|
|
|
|
|
|
|
|
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser |
|
|
|
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
public class PersistedWorkspace |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
public PersistedWorkspace() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
AssemblyFiles = new List<string>(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public string Name { get; set; } |
|
|
|
|
|
|
|
public List<String> AssemblyFiles { get; set; } |
|
|
|
|
|
|
|
public bool IsActive { get; set; } |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
class ClassBrowserPad : AbstractPadContent, IClassBrowser |
|
|
|
class ClassBrowserPad : AbstractPadContent, IClassBrowser |
|
|
|
{ |
|
|
|
{ |
|
|
|
#region IClassBrowser implementation
|
|
|
|
#region IClassBrowser implementation
|
|
|
@ -25,13 +39,19 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser |
|
|
|
get { return treeView.AssemblyList; } |
|
|
|
get { return treeView.AssemblyList; } |
|
|
|
set { treeView.AssemblyList = value; } |
|
|
|
set { treeView.AssemblyList = value; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const string PersistedWorkspaceSetting = "ClassBrowser.Workspaces"; |
|
|
|
|
|
|
|
const string DefaultWorkspaceName = "<default>"; |
|
|
|
|
|
|
|
|
|
|
|
IProjectService projectService; |
|
|
|
IProjectService projectService; |
|
|
|
ClassBrowserTreeView treeView; |
|
|
|
ClassBrowserTreeView treeView; |
|
|
|
DockPanel panel; |
|
|
|
DockPanel panel; |
|
|
|
ToolBar toolBar; |
|
|
|
ToolBar toolBar; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
List<PersistedWorkspace> persistedWorkspaces; |
|
|
|
|
|
|
|
PersistedWorkspace activeWorkspace; |
|
|
|
|
|
|
|
|
|
|
|
public ClassBrowserPad() |
|
|
|
public ClassBrowserPad() |
|
|
|
: this(SD.GetRequiredService<IProjectService>()) |
|
|
|
: this(SD.GetRequiredService<IProjectService>()) |
|
|
@ -53,6 +73,9 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser |
|
|
|
//treeView.ContextMenu = CreateContextMenu("/SharpDevelop/Pads/UnitTestsPad/ContextMenu");
|
|
|
|
//treeView.ContextMenu = CreateContextMenu("/SharpDevelop/Pads/UnitTestsPad/ContextMenu");
|
|
|
|
projectService.CurrentSolutionChanged += ProjectServiceCurrentSolutionChanged; |
|
|
|
projectService.CurrentSolutionChanged += ProjectServiceCurrentSolutionChanged; |
|
|
|
ProjectServiceCurrentSolutionChanged(null, null); |
|
|
|
ProjectServiceCurrentSolutionChanged(null, null); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Load workspaces from configuration
|
|
|
|
|
|
|
|
LoadWorkspaces(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override void Dispose() |
|
|
|
public override void Dispose() |
|
|
@ -77,6 +100,26 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser |
|
|
|
treeView.SpecialNodes.Add(new SolutionTreeNode(projectService.CurrentSolution)); |
|
|
|
treeView.SpecialNodes.Add(new SolutionTreeNode(projectService.CurrentSolution)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void AssemblyListCollectionChanged(IReadOnlyCollection<IAssemblyModel> removedItems, IReadOnlyCollection<IAssemblyModel> addedItems) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
foreach (var assembly in addedItems) { |
|
|
|
|
|
|
|
// Add this assembly to current workspace
|
|
|
|
|
|
|
|
if (activeWorkspace != null) { |
|
|
|
|
|
|
|
activeWorkspace.AssemblyFiles.Add(assembly.Context.Location); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var assembly in removedItems) { |
|
|
|
|
|
|
|
// Add this assembly to current workspace
|
|
|
|
|
|
|
|
if (activeWorkspace != null) { |
|
|
|
|
|
|
|
activeWorkspace.AssemblyFiles.Remove(assembly.Context.Location); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Update workspace list in configuration
|
|
|
|
|
|
|
|
SaveWorkspaces(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
/// Virtual method so we can override this method and return
|
|
|
|
/// Virtual method so we can override this method and return
|
|
|
|
/// a dummy ToolBar when testing.
|
|
|
|
/// a dummy ToolBar when testing.
|
|
|
@ -96,5 +139,108 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser |
|
|
|
Debug.Assert(treeView != null); |
|
|
|
Debug.Assert(treeView != null); |
|
|
|
return MenuService.CreateContextMenu(treeView, name); |
|
|
|
return MenuService.CreateContextMenu(treeView, name); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// Loads persisted workspaces from configuration.
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
void LoadWorkspaces() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
persistedWorkspaces = SD.PropertyService.GetList<PersistedWorkspace>(PersistedWorkspaceSetting).ToList(); |
|
|
|
|
|
|
|
if (!persistedWorkspaces.Any()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// Add at least default workspace
|
|
|
|
|
|
|
|
persistedWorkspaces = new List<PersistedWorkspace>(); |
|
|
|
|
|
|
|
persistedWorkspaces.Add(new PersistedWorkspace() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Name = DefaultWorkspaceName |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Load all assemblies (for now always from default workspace)
|
|
|
|
|
|
|
|
PersistedWorkspace defaultWorkspace = persistedWorkspaces.FirstOrDefault(w => w.Name == DefaultWorkspaceName); |
|
|
|
|
|
|
|
ActivateWorkspace(defaultWorkspace); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// Stores currently saved workspaces in configuration.
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
void SaveWorkspaces() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
SD.PropertyService.SetList<PersistedWorkspace>(PersistedWorkspaceSetting, persistedWorkspaces); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static IAssemblyModel CreateAssemblyModelFromFile(string fileName) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// TODO References?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var loader = new CecilLoader(); |
|
|
|
|
|
|
|
loader.IncludeInternalMembers = true; |
|
|
|
|
|
|
|
loader.LazyLoad = true; |
|
|
|
|
|
|
|
var assembly = loader.LoadAssemblyFile(fileName); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IEntityModelContext context = new AssemblyEntityModelContext(assembly); |
|
|
|
|
|
|
|
IAssemblyModel model = SD.GetRequiredService<IModelFactory>().CreateAssemblyModel(context); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (model is IUpdateableAssemblyModel) { |
|
|
|
|
|
|
|
((IUpdateableAssemblyModel)model).Update(EmptyList<IUnresolvedTypeDefinition>.Instance, assembly.TopLevelTypeDefinitions.ToList()); |
|
|
|
|
|
|
|
((IUpdateableAssemblyModel) model).AssemblyName = assembly.AssemblyName; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return model; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void AppendAssemblyFileToList(string assemblyFile) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
IAssemblyModel assemblyModel = CreateAssemblyModelFromFile(assemblyFile); |
|
|
|
|
|
|
|
if (assemblyModel != null) { |
|
|
|
|
|
|
|
AssemblyList.Assemblies.Add(assemblyModel); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
// TODO Throw exception?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// Activates the specified workspace.
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
void ActivateWorkspace(PersistedWorkspace workspace) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// Update the activation flags in workspace list
|
|
|
|
|
|
|
|
foreach (var workspaceElement in persistedWorkspaces) { |
|
|
|
|
|
|
|
workspaceElement.IsActive = (workspaceElement == workspace); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
UpdateActiveWorkspace(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// Updates active workspace and AssemblyList according to <see cref="PersistedWorkspace.IsActive"/> flags.
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
void UpdateActiveWorkspace() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if ((AssemblyList != null) && (activeWorkspace != null)) { |
|
|
|
|
|
|
|
// Temporarily detach from event handler
|
|
|
|
|
|
|
|
AssemblyList.Assemblies.CollectionChanged -= AssemblyListCollectionChanged; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
activeWorkspace = persistedWorkspaces.FirstOrDefault(w => w.IsActive); |
|
|
|
|
|
|
|
if (activeWorkspace == null) { |
|
|
|
|
|
|
|
// If no workspace is active, activate default
|
|
|
|
|
|
|
|
var defaultWorkspace = persistedWorkspaces.FirstOrDefault(w => w.Name == DefaultWorkspaceName); |
|
|
|
|
|
|
|
activeWorkspace = defaultWorkspace; |
|
|
|
|
|
|
|
defaultWorkspace.IsActive = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AssemblyList.Assemblies.Clear(); |
|
|
|
|
|
|
|
if (activeWorkspace != null) { |
|
|
|
|
|
|
|
foreach (string assemblyFile in activeWorkspace.AssemblyFiles) { |
|
|
|
|
|
|
|
AppendAssemblyFileToList(assemblyFile); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Attach to event handler, again.
|
|
|
|
|
|
|
|
if (AssemblyList != null) { |
|
|
|
|
|
|
|
AssemblyList.Assemblies.CollectionChanged += AssemblyListCollectionChanged; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|