⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nantpadtreeview.cs

📁 c#源代码
💻 CS
字号:
//
// SharpDevelop NAnt add-in.
//
// Copyright (C) 2004 Matthew Ward
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// Matthew Ward (mrward@users.sourceforge.net)

using ICSharpCode.Core.AddIns;
using ICSharpCode.NAntAddIn;
using ICSharpCode.SharpDevelop.Internal.Project;
using ICSharpCode.SharpDevelop.Services;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

namespace ICSharpCode.NAntAddIn.Gui
{
	/// <summary>
	/// NAnt pad's tree view.  Shows a high level view of build file in
	/// a set of projects.
	/// </summary>
	public class NAntPadTreeView : System.Windows.Forms.UserControl, IOwnerState
	{
		private System.Windows.Forms.TreeView treeView;
		const string ContextMenuAddInTreePath = "/AddIns/NAntAddIn/NAntPadTreeView/ContextMenu";
		
		/// <summary>
		/// The possible states of the tree view.
		/// </summary>
		public enum NAntPadTreeViewState {
			Nothing = 0,
			BuildFileSelected = 1,
			TargetSelected = 2,
			ErrorSelected = 4
		}
		
		/// <summary>
		/// The current state of the tree view.
		/// </summary>
		NAntPadTreeViewState state = NAntPadTreeViewState.Nothing;
		
		delegate void AddCombineInvoker(Combine combine);
			
		public NAntPadTreeView()
		{
			//
			// The InitializeComponent() call is required for Windows Forms designer support.
			//
			InitializeComponent();
			
			treeView.Sorted = true;
			treeView.HideSelection = false;
			treeView.ImageList = NAntPadTreeViewImageList.GetImageList();
			
			MenuService menuService = (MenuService)ICSharpCode.Core.Services.ServiceManager.Services.GetService(typeof(MenuService));
			treeView.ContextMenu = menuService.CreateContextMenu(this, ContextMenuAddInTreePath);
		
			treeView.DoubleClick += new EventHandler(TreeViewDoubleClick);
		}
		
		/// <summary>
		/// Gets the "ownerstate" condition.
		/// </summary>
		public Enum InternalState {
			get {
				return state;
			}
		}
		
		/// <summary>
		/// Clears all items from the tree view.
		/// </summary>
		public void Clear()
		{
			if (InvokeRequired) {
				MethodInvoker invoker = new MethodInvoker(Clear);
				Invoke(invoker);
			} else {
				treeView.Nodes.Clear();			
			}
		}
		
		/// <summary>
		/// Adds items to the tree view for each build file that exists
		/// in all the combine's subprojects.
		/// </summary>
		/// <param name="combine">A combine containing projects.</param>
		public void AddCombine(Combine combine)
		{
			if (InvokeRequired) {
				AddCombineInvoker invoker = new AddCombineInvoker(AddCombine);
				Invoke(invoker);
			} else {
				foreach (CombineEntry entry in combine.Entries) {
					
					if (entry.Entry is IProject) {
						AddProject((IProject)entry.Entry);
					} else {
						AddCombine((Combine)entry.Entry);
					}
				}
			}
		}
		
		/// <summary>
		/// Adds items to the tree view for each build file that exist
		/// in a project.
		/// </summary>
		/// <param name="project">A SharpDevelop project.</param>
		public void AddProject(IProject project)
		{
			Debug.Assert(!InvokeRequired, "AddProject InvokeRequired");
			
			foreach (ProjectFile projectFile in project.ProjectFiles) {
				if (NAntBuildFile.IsBuildFile(projectFile.Name)) {
					
					AddBuildFile(project.Name, projectFile.Name);
				}
			}
		}
		
		/// <summary>
		/// Removes the specified build file from the
		/// tree view.</summary>
		public void RemoveBuildFile(string fileName)
		{
			Debug.Assert(!InvokeRequired, "RemoveBuildFile InvokeRequired");
			
			NAntBuildFileTreeNode node = FindMatchingNode(fileName);
			
			if (node != null) {
				node.Remove();
			}
		}
		
		/// <summary>
		/// Renames the build file.
		/// </summary>
		/// <param name="oldFileName">The filename to update.</param>
		/// <param name="newFileName">The updated filename.</param>
		public void RenameBuildFile(string oldFileName, string newFileName)
		{
			Debug.Assert(!InvokeRequired, "RenameBuildFile InvokeRequired");

			NAntBuildFileTreeNode node = FindMatchingNode(oldFileName);
			
			if (node != null) {
				node.FileName = Path.GetFileName(newFileName);
			}
		}
		
		/// <summary>
		/// Updates the build file in the tree view.
		/// </summary>
		/// <param name="fileName">The build file name.</param>
		public void UpdateBuildFile(string fileName)
		{
			Debug.Assert(!InvokeRequired, "UpdateBuildFile InvokeRequired");
			
			NAntBuildFileTreeNode node = FindMatchingNode(fileName);
			
			if (node != null) {
				NAntBuildFile buildFile = new NAntBuildFile(fileName);
				node.BuildFile = buildFile;
			}
		}		
		
		/// <summary>
		/// Adds a build file to the tree.
		/// </summary>
		/// <param name="projectName">The name of the project.</param>
		/// <param name="fileName">The build file name.</param>
		/// <param name="debug"><see langword="true"/> if the project's 
		/// active configuration is debug; <see langword="false"/> 
		/// otherwise.</param>
		public void AddBuildFile(string projectName, string fileName)
		{
			Debug.Assert(!InvokeRequired, "AddBuildFile InvokeRequired");

			NAntBuildFile buildFile = new NAntBuildFile(fileName);
			
			NAntBuildFileTreeNode node = new NAntBuildFileTreeNode(projectName, buildFile);
			
			treeView.Nodes.Add(node);
		}		
		
		/// <summary>
		/// Gets the currently selected <see cref="NAntBuildFile"/>.
		/// </summary>
		/// <remarks>This will return a NAntBuildFile if
		/// a target node is selected.</remarks>
		public NAntBuildFile SelectedBuildFile {
			get {
				NAntBuildFile buildFile = null;
				
				TreeNode selectedNode = treeView.SelectedNode;
				if (selectedNode is NAntBuildFileTreeNode) {
					NAntBuildFileTreeNode buildNode = (NAntBuildFileTreeNode)selectedNode;
					buildFile = buildNode.BuildFile;
				} else if(selectedNode is NAntBuildTargetTreeNode) {
					NAntBuildTargetTreeNode targetNode = (NAntBuildTargetTreeNode)selectedNode;
					NAntBuildFileTreeNode buildNode = (NAntBuildFileTreeNode)targetNode.Parent;
					buildFile = buildNode.BuildFile;
				} else if(selectedNode is NAntBuildFileErrorTreeNode) {
					NAntBuildFileErrorTreeNode errorNode = (NAntBuildFileErrorTreeNode)selectedNode;
					NAntBuildFileTreeNode buildNode = (NAntBuildFileTreeNode)errorNode.Parent;
					buildFile = buildNode.BuildFile;					
				}
				
				return buildFile;
			}
		}
		
		/// <summary>
		/// Gets the current selected <see cref="NAntBuildTarget"/>
		/// </summary>
		public NAntBuildTarget SelectedTarget {
			get {
				NAntBuildTarget target = null;
				
				NAntBuildTargetTreeNode targetNode = treeView.SelectedNode as NAntBuildTargetTreeNode;
				
				if (targetNode != null) {
					target = targetNode.Target;
				}
				
				return target;
			}
		}	
		
		/// <summary>
		/// Gets the current selected <see cref="NAntBuildFileError"/>
		/// </summary>
		public NAntBuildFileError SelectedError {
			get {
				NAntBuildFileError error = null;
				
				NAntBuildFileErrorTreeNode errorNode = treeView.SelectedNode as NAntBuildFileErrorTreeNode;
				
				if (errorNode != null) {
					error = errorNode.Error;
				}
				
				return error;				
			}
		}
		
		/// <summary>
		/// Gets whether a target is selected.
		/// </summary>
		public bool IsTargetSelected {
			get {
				bool isSelected = false;
				
				if (SelectedTarget != null) {
					isSelected = true;
				}
				
				return isSelected;
			}
		}
		
		#region Windows Forms Designer generated code
		/// <summary>
		/// This method is required for Windows Forms designer support.
		/// Do not change the method contents inside the source code editor. The Forms designer might
		/// not be able to load this method if it was changed manually.
		/// </summary>
		private void InitializeComponent() {
			this.treeView = new System.Windows.Forms.TreeView();
			this.SuspendLayout();
			// 
			// treeView
			// 
			this.treeView.Dock = System.Windows.Forms.DockStyle.Fill;
			this.treeView.ImageIndex = -1;
			this.treeView.Location = new System.Drawing.Point(0, 0);
			this.treeView.Name = "treeView";
			this.treeView.SelectedImageIndex = -1;
			this.treeView.Size = new System.Drawing.Size(292, 266);
			this.treeView.TabIndex = 0;
			this.treeView.MouseDown += new System.Windows.Forms.MouseEventHandler(this.TreeViewMouseDown);
			// 
			// NAntPadTreeView
			// 
			this.Controls.Add(this.treeView);
			this.Name = "NAntPadTreeView";
			this.Size = new System.Drawing.Size(292, 266);
			this.ResumeLayout(false);
		}
		#endregion
		
		/// <summary>
		/// User clicked the tree view.
		/// </summary>
		/// <param name="sender">The event source.</param>
		/// <param name="e">The event arguments.</param>
		void TreeViewMouseDown(object sender, MouseEventArgs e)
		{
			TreeNode node = treeView.GetNodeAt(e.X, e.Y);

			treeView.SelectedNode = node;
			
			state = NAntPadTreeViewState.Nothing;
			if (IsBuildFileNodeSelected) {
				state = NAntPadTreeViewState.BuildFileSelected;
			} 
			
			if (IsBuildTargetNodeSelected) {
				state = NAntPadTreeViewState.TargetSelected;
			}			
			
			if (IsBuildFileErrorNodeSelected) {
				state = NAntPadTreeViewState.ErrorSelected;
			}
		}
		
		/// <summary>
		/// Gets whether a build file is selected.
		/// </summary>
		bool IsBuildFileNodeSelected {
			get {
				return treeView.SelectedNode is NAntBuildFileTreeNode;
			}
		}
		
		/// <summary>
		/// Gets whether a target is selected.
		/// </summary>
		bool IsBuildTargetNodeSelected {
			get {
				return treeView.SelectedNode is NAntBuildTargetTreeNode;
			}
		}	
		
		/// <summary>
		/// Gets whether a build file error is selected.
		/// </summary>
		bool IsBuildFileErrorNodeSelected {
			get {
				return treeView.SelectedNode is NAntBuildFileErrorTreeNode;
			}
		}		
		
		/// <summary>
		/// Double clicking a node on the tree view opens the corresponding
		/// file.
		/// </summary>
		/// <param name="sender">The event source.</param>
		/// <param name="e">The event arguments.</param>
		void TreeViewDoubleClick(object sender, EventArgs e)
		{
			NAntBuildFile buildFile = SelectedBuildFile;
			if (buildFile != null) {
				
				string fileName = Path.Combine(buildFile.Directory, buildFile.FileName);
				
				if (IsBuildTargetNodeSelected) {
					SharpDevelopApplication.FileService.JumpToFilePosition(fileName, SelectedTarget.Line, SelectedTarget.Column);
				} else if (IsBuildFileErrorNodeSelected) {
					SharpDevelopApplication.FileService.JumpToFilePosition(fileName, SelectedError.Line, SelectedError.Column);					
				} else {					
					SharpDevelopApplication.FileService.OpenFile(fileName);
				}
			}
		}
		
		/// <summary>
		/// Looks for the tree node that is displaying the specified
		/// build file.
		/// </summary>
		/// <param name="fileName">The build file to look for.</param>
		/// <returns>The matching tree node if the build file exists
		/// in the tree; otherwise <see langword="null"/>.</returns>
		NAntBuildFileTreeNode FindMatchingNode(string fileName)
		{
			NAntBuildFileTreeNode matchedNode = null;
			
			foreach (NAntBuildFileTreeNode node in treeView.Nodes) {
				
				string nodeFileName = Path.Combine(node.BuildFile.Directory, node.BuildFile.FileName);
				if (String.Compare(Path.GetFullPath(fileName), Path.GetFullPath(nodeFileName), true) == 0) {
					
					matchedNode = node;
					break;
				}
			}
			
			return matchedNode;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -