📄 projectbrowserview.cs
字号:
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version value="$version"/>
// </file>
using System;
using System.IO;
using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing;
using System.Diagnostics;
using System.Collections;
using System.Collections.Specialized;
using System.Collections.Utility;
using System.Xml;
using System.Resources;
using Reflector.UserInterface;
using ICSharpCode.Core.Properties;
using ICSharpCode.Core.AddIns;
using ICSharpCode.Core.AddIns.Codons;
using ICSharpCode.Core.Services;
using ICSharpCode.SharpDevelop.Internal.Project;
using ICSharpCode.SharpDevelop.Gui.Dialogs;
using ICSharpCode.SharpDevelop.Services;
namespace ICSharpCode.SharpDevelop.Gui.Pads.ProjectBrowser
{
/// <summary>
/// This class implements a project browser.
/// </summary>
public class ProjectBrowserView : TreeView, IPadContent, IMementoCapable
{
static readonly string nodeBuilderPath = "/SharpDevelop/Views/ProjectBrowser/NodeBuilders";
AbstractBrowserNode highlightedNode = null;
public static Font PlainFont = null;
Font boldFont = null;
Panel contentPanel = new Panel();
static ResourceService resourceService = (ResourceService)ServiceManager.Services.GetService(typeof(IResourceService));
static FileUtilityService fileUtilityService = (FileUtilityService)ServiceManager.Services.GetService(typeof(FileUtilityService));
static PropertyService propertyService = (PropertyService)ServiceManager.Services.GetService(typeof(PropertyService));
public Control Control {
get {
return contentPanel;
}
}
public string Title {
get {
return resourceService.GetString("MainWindow.Windows.ProjectScoutLabel");
}
}
public string Icon {
get {
return "Icons.16x16.CombineIcon";
}
}
string category;
public string Category {
get {
return category;
}
set{
category = value;
}
}
string[] shortcut; // TODO: Inherit from AbstractPadContent
public string[] Shortcut {
get {
return shortcut;
}
set {
shortcut = value;
}
}
public void RedrawContent()
{
BeginUpdate();
AbstractBrowserNode.ShowExtensions = propertyService.GetProperty("ICSharpCode.SharpDevelop.Gui.ProjectBrowser.ShowExtensions", true);
foreach (AbstractBrowserNode node in Nodes) {
node.UpdateNaming();
}
EndUpdate();
}
static ProjectBrowserView()
{
projectBrowserImageList = new ImageList();
projectBrowserImageList.ColorDepth = ColorDepth.Depth32Bit;
}
public ProjectBrowserView()
{
LabelEdit = true;
AllowDrop = true;
HideSelection = false;
Dock = DockStyle.Fill;
ImageList = projectBrowserImageList;
LabelEdit = false;
WorkbenchSingleton.Workbench.ActiveWorkbenchWindowChanged += new EventHandler(ActiveWindowChanged);
IProjectService projectService = (IProjectService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(IProjectService));
projectService.CombineOpened += new CombineEventHandler(OpenCombine);
projectService.CombineClosed += new CombineEventHandler(CloseCombine);
PlainFont = new Font(Font, FontStyle.Regular);
boldFont = new Font(Font, FontStyle.Bold);
Font = boldFont;
contentPanel.Controls.Add(this);
}
public void RefreshTree(Combine combine)
{
DisposeProjectNodes();
Nodes.Clear();
TreeNode treeNode = BuildCombineTreeNode(combine);
SortUtility.SortedInsert(treeNode, Nodes, TreeNodeComparer.ProjectNode);
combine.StartupPropertyChanged += new EventHandler(StartupPropertyChanged);
StartupPropertyChanged(null, null);
// .NET bugfix : have to expand the node to ensure the refresh
// (Refresh won't work) tested 08/16/2002 Mike
treeNode.Expand();
}
void OpenCombine(object sender, CombineEventArgs e)
{
try {
RefreshTree(e.Combine);
} catch (InvalidOperationException) {
this.Invoke(new CombineEventHandler(OpenCombine), new object[] {sender, e});
}
}
void CloseCombine(object sender, CombineEventArgs e)
{
try {
DisposeProjectNodes();
Nodes.Clear();
ContextMenu = null;
} catch (InvalidOperationException) {
this.Invoke(new CombineEventHandler(CloseCombine), new object[] {sender, e});
}
}
void StartupPropertyChanged(object sender, EventArgs e)
{
Combine combine = ((AbstractBrowserNode)Nodes[0]).Combine;
if (highlightedNode != null) {
highlightedNode.NodeFont = PlainFont;
}
if (combine.SingleStartupProject) {
foreach (AbstractBrowserNode node in Nodes[0].Nodes) {
if (node is ProjectBrowserNode) {
if (combine.SingleStartProjectName == node.Project.Name) {
highlightedNode = node;
node.NodeFont = null;
}
} else if (node is CombineBrowserNode) {
if (combine.SingleStartProjectName == node.Combine.Name) {
highlightedNode = node;
node.NodeFont = null;
}
}
}
} else {
highlightedNode = (AbstractBrowserNode)Nodes[0];
highlightedNode.NodeFont = boldFont;
}
}
void DisposeProjectNodes()
{
if (Nodes.Count == 1) {
Stack stack = new Stack();
stack.Push(Nodes[0]);
while (stack.Count > 0) {
TreeNode node = (TreeNode)stack.Pop();
if (node is IDisposable) {
((IDisposable)node).Dispose();
}
foreach (TreeNode childNode in node.Nodes) {
stack.Push(childNode);
}
}
}
}
/// <summary>
/// Searches AbstractBrowserNodeCollection recursively for a given file name.
/// Note that the UserData properties for the files have to set to FileInformation
/// or to ReferenceInformation for this method to work.
/// </summary>
AbstractBrowserNode GetNodeFromCollectionTreeByFileName(TreeNodeCollection collection, string fileName)
{
foreach (AbstractBrowserNode node in collection) {
string nodePath = (node.UserData as ProjectFile) == null ? null : ((ProjectFile)node.UserData).Name;
if (node.UserData is ProjectFile && nodePath != null && fileName != null && Path.GetFullPath(nodePath).ToUpper() == Path.GetFullPath(fileName).ToUpper()) {
return node;
}
if (node.UserData is ProjectReference && ((ProjectReference)node.UserData).GetReferencedFileName(node.Project) == fileName) {
return node;
}
AbstractBrowserNode childnode = GetNodeFromCollectionTreeByFileName(node.Nodes, fileName);
if (childnode != null) {
return childnode;
}
}
return null;
}
/// <summary>
/// Selectes the current active workbench window in the Project Browser Tree and ensures
/// the visibility of this node.
/// </summary>
void ActiveWindowChanged(object sender, EventArgs e)
{
if (WorkbenchSingleton.Workbench.ActiveWorkbenchWindow != null) {
string fileName = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow.ViewContent.FileName;
if (fileName == null) {
fileName = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow.ViewContent.UntitledName;
}
FileUtilityService fileUtilityService = (FileUtilityService)ServiceManager.Services.GetService(typeof(FileUtilityService));
if (!fileUtilityService.IsValidFileName(fileName)) {
return;
}
try {
if (fileName.StartsWith("http:") || !Path.IsPathRooted(fileName)) {
return;
}
} catch (Exception) {
return;
}
AbstractBrowserNode node = GetNodeFromCollectionTreeByFileName(Nodes, fileName);
if (node != null) {
node.EnsureVisible();
SelectedNode = node;
}
}
}
/// <summary>
/// If you want to edit a node label. Select the node you want to edit and then
/// call this method, instead of using the LabelEdit Property and the BeginEdit
/// Method directly.
/// </summary>
public void StartLabelEdit()
{
AbstractBrowserNode selectedNode = (AbstractBrowserNode)SelectedNode;
if (selectedNode != null && selectedNode.CanLabelEdited) {
LabelEdit = true;
selectedNode.BeforeLabelEdit();
selectedNode.BeginEdit();
}
}
/// <summary>
/// Updates the combine tree, this method should be called, if the combine has
/// changed (added a project/combine)
/// </summary>
public void UpdateCombineTree()
{
XmlElement storedTree = new TreeViewMemento(this).ToXmlElement(new XmlDocument());
IProjectService projectService = (IProjectService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(IProjectService));
CloseCombine(this,new CombineEventArgs(projectService.CurrentOpenCombine));
OpenCombine(this, new CombineEventArgs(projectService.CurrentOpenCombine));
((TreeViewMemento)new TreeViewMemento().FromXmlElement(storedTree)).Restore(this);
ActiveWindowChanged(this, EventArgs.Empty);
}
/// <summary>
/// This method builds a ProjectBrowserNode Tree out of a given combine.
/// </summary>
public static AbstractBrowserNode BuildProjectTreeNode(IProject project)
{
IProjectNodeBuilder[] nodeBuilders = (IProjectNodeBuilder[])(AddInTreeSingleton.AddInTree.GetTreeNode(nodeBuilderPath).BuildChildItems(null)).ToArray(typeof(IProjectNodeBuilder));
IProjectNodeBuilder projectNodeBuilder = null;
foreach (IProjectNodeBuilder nodeBuilder in nodeBuilders) {
if (nodeBuilder.CanBuildProjectTree(project)) {
projectNodeBuilder = nodeBuilder;
break;
}
}
if (projectNodeBuilder != null) {
return projectNodeBuilder.BuildProjectTreeNode(project);
}
throw new NotImplementedException("can't create node builder for project type " + project.ProjectType);
}
/// <summary>
/// This method builds a ProjectBrowserNode Tree out of a given combine.
/// </summary>
public static AbstractBrowserNode BuildCombineTreeNode(Combine combine)
{
CombineBrowserNode combineNode = new CombineBrowserNode(combine);
// build subtree
foreach (CombineEntry entry in combine.Entries) {
TreeNode node = null;
if (entry.Entry is IProject) {
node = BuildProjectTreeNode((IProject)entry.Entry);
} else {
node = BuildCombineTreeNode((Combine)entry.Entry);
}
combineNode.Nodes.Add(node);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -