// SharpDevelop samples // Copyright (c) 2007, AlphaSierraPapa // All rights reserved. // // Redistribution and use in source and binary forms, with or without modification, are // permitted provided that the following conditions are met: // // - Redistributions of source code must retain the above copyright notice, this list // of conditions and the following disclaimer. // // - Redistributions in binary form must reproduce the above copyright notice, this list // of conditions and the following disclaimer in the documentation and/or other materials // provided with the distribution. // // - Neither the name of the SharpDevelop team nor the names of its contributors may be used to // endorse or promote products derived from this software without specific prior written // permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &AS IS& AND ANY EXPRESS // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using System; using System.Diagnostics; using System.IO; using System.Windows.Forms; using ICSharpCode.Core; using ICSharpCode.Core.WinForms; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Project; namespace ICSharpCode.NAnt.Gui { /// /// NAnt pad's tree view. Shows a high level view of build file in /// a set of projects. /// public class NAntPadTreeView : System.Windows.Forms.UserControl, IOwnerState { private System.Windows.Forms.TreeView treeView; const string ContextMenuAddInTreePath = "/SharpDevelop/Pads/NAntPad/ContextMenu"; /// /// The possible states of the tree view. /// public enum NAntPadTreeViewState { Nothing = 0, BuildFileSelected = 1, TargetSelected = 2, ErrorSelected = 4 } /// /// The current state of the tree view. /// NAntPadTreeViewState state = NAntPadTreeViewState.Nothing; delegate void AddSolutionInvoker(Solution solution); public NAntPadTreeView() { // // The InitializeComponent() call is required for Windows Forms designer support. // InitializeComponent(); treeView.Sorted = true; treeView.HideSelection = false; treeView.ImageList = NAntPadTreeViewImageList.GetImageList(); treeView.ContextMenuStrip = MenuService.CreateContextMenu(this, ContextMenuAddInTreePath); treeView.DoubleClick += new EventHandler(TreeViewDoubleClick); } /// /// Gets the "ownerstate" condition. /// public Enum InternalState { get { return state; } } /// /// Clears all items from the tree view. /// public void Clear() { if (InvokeRequired) { MethodInvoker invoker = new MethodInvoker(Clear); Invoke(invoker); } else { treeView.Nodes.Clear(); } } /// /// Adds items to the tree view for each build file that exists /// in all the solution's subprojects. /// /// A solution containing projects. public void AddSolution(Solution solution) { if (InvokeRequired) { AddSolutionInvoker invoker = new AddSolutionInvoker(AddSolution); Invoke(invoker); } else { foreach (IProject project in solution.Projects) { AddProject(project); } } } /// /// Adds items to the tree view for each build file that exist /// in a project. /// /// A SharpDevelop project. public void AddProject(IProject project) { Debug.Assert(!InvokeRequired, "AddProject InvokeRequired"); foreach (ProjectItem projectItem in project.Items) { if (NAntBuildFile.IsBuildFile(projectItem.FileName)) { AddBuildFile(project.Name, projectItem.FileName); } } } /// /// Removes the specified build file from the /// tree view. public void RemoveBuildFile(string fileName) { Debug.Assert(!InvokeRequired, "RemoveBuildFile InvokeRequired"); NAntBuildFileTreeNode node = FindMatchingNode(fileName); if (node != null) { node.Remove(); } } /// /// Renames the build file. /// /// The filename to update. /// The updated filename. public void RenameBuildFile(string oldFileName, string newFileName) { Debug.Assert(!InvokeRequired, "RenameBuildFile InvokeRequired"); NAntBuildFileTreeNode node = FindMatchingNode(oldFileName); if (node != null) { node.FileName = Path.GetFileName(newFileName); } } /// /// Updates the build file in the tree view. /// /// The build file name. 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; } else { AddBuildFile(String.Empty, fileName); } } /// /// Adds a build file to the tree. /// /// The name of the project. /// The build file name. /// if the project's /// active configuration is debug; /// otherwise. public void AddBuildFile(string projectName, string fileName) { Debug.Assert(!InvokeRequired, "AddBuildFile InvokeRequired"); if (File.Exists(fileName)) { NAntBuildFile buildFile = new NAntBuildFile(fileName); NAntBuildFileTreeNode node = new NAntBuildFileTreeNode(projectName, buildFile); treeView.Nodes.Add(node); } } /// /// Gets the currently selected . /// /// This will return a NAntBuildFile if /// a target node is selected. 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; } } /// /// Gets the current selected /// public NAntBuildTarget SelectedTarget { get { NAntBuildTarget target = null; NAntBuildTargetTreeNode targetNode = treeView.SelectedNode as NAntBuildTargetTreeNode; if (targetNode != null) { target = targetNode.Target; } return target; } } /// /// Gets the current selected /// public NAntBuildFileError SelectedError { get { NAntBuildFileError error = null; NAntBuildFileErrorTreeNode errorNode = treeView.SelectedNode as NAntBuildFileErrorTreeNode; if (errorNode != null) { error = errorNode.Error; } return error; } } /// /// Gets whether a target is selected. /// public bool IsTargetSelected { get { bool isSelected = false; if (SelectedTarget != null) { isSelected = true; } return isSelected; } } #region Windows Forms Designer generated code /// /// 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. /// 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 /// /// User clicked the tree view. /// /// The event source. /// The event arguments. 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; } } /// /// Gets whether a build file is selected. /// bool IsBuildFileNodeSelected { get { return treeView.SelectedNode is NAntBuildFileTreeNode; } } /// /// Gets whether a target is selected. /// bool IsBuildTargetNodeSelected { get { return treeView.SelectedNode is NAntBuildTargetTreeNode; } } /// /// Gets whether a build file error is selected. /// bool IsBuildFileErrorNodeSelected { get { return treeView.SelectedNode is NAntBuildFileErrorTreeNode; } } /// /// Double clicking a node on the tree view opens the corresponding /// file. /// /// The event source. /// The event arguments. void TreeViewDoubleClick(object sender, EventArgs e) { NAntBuildFile buildFile = SelectedBuildFile; if (buildFile != null) { string fileName = Path.Combine(buildFile.Directory, buildFile.FileName); if (IsBuildTargetNodeSelected) { FileService.JumpToFilePosition(fileName, SelectedTarget.Line, SelectedTarget.Column); } else if (IsBuildFileErrorNodeSelected) { FileService.JumpToFilePosition(fileName, SelectedError.Line, SelectedError.Column); } else { FileService.OpenFile(fileName); } } } /// /// Looks for the tree node that is displaying the specified /// build file. /// /// The build file to look for. /// The matching tree node if the build file exists /// in the tree; otherwise . NAntBuildFileTreeNode FindMatchingNode(string fileName) { 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) { return node; } } return null; } } }