📄 nantpadtreeview.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 + -