/Tools/IronStudio/IronStudio/VisualStudio/Project/HierarchyNode.cs
C# | 2008 lines | 1395 code | 229 blank | 384 comment | 265 complexity | e153a4817df2a5a660a7983afc61f827 MD5 | raw file
Possible License(s): CPL-1.0, BSD-3-Clause, ISC, GPL-2.0, MPL-2.0-no-copyleft-exception
Large files files are truncated, but you can click here to view the full file
- /* ****************************************************************************
- *
- * Copyright (c) Microsoft Corporation.
- *
- * This source code is subject to terms and conditions of the Apache License, Version 2.0. A
- * copy of the license can be found in the License.html file at the root of this distribution. If
- * you cannot locate the Apache License, Version 2.0, please send an email to
- * ironpy@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
- * by the terms of the Apache License, Version 2.0.
- *
- * You must not remove this notice, or any other, from this software.
- *
- * ***************************************************************************/
-
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Diagnostics.CodeAnalysis;
- using System.Globalization;
- using System.IO;
- using System.Runtime.InteropServices;
- using System.Text;
- using Microsoft.VisualStudio;
- using Microsoft.VisualStudio.OLE.Interop;
- using Microsoft.VisualStudio.Shell;
- //#define CCI_TRACING
- using Microsoft.VisualStudio.Shell.Interop;
- using OleConstants = Microsoft.VisualStudio.OLE.Interop.Constants;
- using ShellConstants = Microsoft.VisualStudio.Shell.Interop.Constants;
- using VsCommands = Microsoft.VisualStudio.VSConstants.VSStd97CmdID;
- using VsCommands2K = Microsoft.VisualStudio.VSConstants.VSStd2KCmdID;
-
- namespace Microsoft.VisualStudio.Project
- {
- /// <summary>
- /// An object that deals with user interaction via a GUI in the form a hierarchy: a parent node with zero or more child nodes, each of which
- /// can itself be a hierarchy.
- /// </summary>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling"), CLSCompliant(false), ComVisible(true)]
- public abstract class HierarchyNode :
- IVsUIHierarchy,
- IVsPersistHierarchyItem2,
- Microsoft.VisualStudio.OLE.Interop.IOleCommandTarget,
- IVsHierarchyDropDataSource2,
- IVsHierarchyDropDataSource,
- IVsHierarchyDropDataTarget,
- IVsHierarchyDeleteHandler,
- IDisposable
- //, IVsBuildStatusCallback
- {
- #region nested types
- /// <summary>
- /// DropEffect as defined in oleidl.h
- /// </summary>
- internal enum DropEffect
- {
- None,
- Copy = 1,
- Move = 2,
- Link = 4
- };
- #endregion
-
- #region Events
- internal event EventHandler<HierarchyNodeEventArgs> OnChildAdded
- {
- add { onChildAdded += value; }
- remove { onChildAdded -= value; }
- }
- internal event EventHandler<HierarchyNodeEventArgs> OnChildRemoved
- {
- add { onChildRemoved += value; }
- remove { onChildRemoved -= value; }
- }
- #endregion
-
- #region static/const fields
- public static readonly Guid SolutionExplorer = new Guid(EnvDTE.Constants.vsWindowKindSolutionExplorer);
- public const int NoImage = -1;
- #if DEBUG
- internal static int LastTracedProperty;
- #endif
- #endregion
-
- #region fields
- private EventSinkCollection hierarchyEventSinks = new EventSinkCollection();
- private ProjectNode projectMgr;
- private ProjectElement itemNode;
- private HierarchyNode parentNode;
- private HierarchyNode nextSibling;
- private HierarchyNode firstChild;
- private HierarchyNode lastChild;
- private bool isExpanded;
- private uint hierarchyId;
- private uint docCookie;
- private bool hasDesigner;
- private string virtualNodeName = String.Empty; // Only used by virtual nodes
- private IVsHierarchy parentHierarchy;
- private int parentHierarchyItemId;
- private NodeProperties nodeProperties;
- private OleServiceProvider oleServiceProvider = new OleServiceProvider();
- private bool excludeNodeFromScc;
- private EventHandler<HierarchyNodeEventArgs> onChildAdded;
- private EventHandler<HierarchyNodeEventArgs> onChildRemoved;
- private bool hasParentNodeNameRelation;
- private List<HierarchyNode> itemsDraggedOrCutOrCopied;
- private bool sourceDraggedOrCutOrCopied;
-
- /// <summary>
- /// Has the object been disposed.
- /// </summary>
- /// <devremark>We will not specify a property for isDisposed, rather it is expected that the a private flag is defined
- /// on all subclasses. We do not want get in a situation where the base class's dipose is not called because a child sets the flag through the property.</devremark>
- private bool isDisposed;
- #endregion
-
- #region abstract properties
- /// <summary>
- /// The URL of the node.
- /// </summary>
- /// <value></value>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings")]
- public abstract string Url
- {
- get;
- }
-
- /// <summary>
- /// The Caption of the node.
- /// </summary>
- /// <value></value>
- public abstract string Caption
- {
- get;
- }
-
- /// <summary>
- /// The item type guid associated to a node.
- /// </summary>
- /// <value></value>
- public abstract Guid ItemTypeGuid
- {
- get;
- }
- #endregion
-
- #region virtual properties
- /// <summary>
- /// Defines a string that is used to separate the name relation from the extension
- /// </summary>
- public virtual string NameRelationSeparator
- {
- get
- {
- return ".";
- }
- }
-
-
- public virtual int MenuCommandId
- {
- get { return VsMenus.IDM_VS_CTXT_NOCOMMANDS; }
- }
-
-
- /// <summary>
- /// Return an imageindex
- /// </summary>
- /// <returns></returns>
- public virtual int ImageIndex
- {
- get { return NoImage; }
- }
-
- /// <summary>
- /// Return an state icon index
- /// </summary>
- /// <returns></returns>
- /// <summary>
- /// Sets the state icon for a file.
- /// </summary>
- public virtual VsStateIcon StateIconIndex
- {
- get
- {
- if(!this.ExcludeNodeFromScc)
- {
- IVsSccManager2 sccManager = this.ProjectMgr.Site.GetService(typeof(SVsSccManager)) as IVsSccManager2;
-
- if(sccManager != null)
- {
- VsStateIcon[] statIcons = new VsStateIcon[1] { VsStateIcon.STATEICON_NOSTATEICON };
- uint[] sccStatus = new uint[1] { 0 };
- // Get the glyph from the scc manager. Note that it will fail in command line
- // scenarios.
- if(ErrorHandler.Succeeded(sccManager.GetSccGlyph(1, new string[] { this.GetMkDocument() }, statIcons, sccStatus)))
- {
- return statIcons[0];
- }
- }
- }
-
- return VsStateIcon.STATEICON_NOSTATEICON;
- }
- }
-
- /// <summary>
- /// Defines whether a node can execute a command if in selection.
- /// </summary>
- public virtual bool CanExecuteCommand
- {
- get
- {
- return true;
- }
- }
-
- /// <summary>
- /// Used to determine the sort order of different node types
- /// in the solution explorer window.
- /// Nodes with the same priorities are sorted based on their captions.
- /// </summary>
- public virtual int SortPriority
- {
- get { return DefaultSortOrderNode.HierarchyNode; }
- }
-
- /// <summary>
- /// Defines the properties attached to this node.
- /// </summary>
- public virtual NodeProperties NodeProperties
- {
- get
- {
- if(null == nodeProperties)
- {
- nodeProperties = CreatePropertiesObject();
- }
- return this.nodeProperties;
- }
-
- }
-
- /// <summary>
- /// Returns an object that is a special view over this object; this is the value
- /// returned by the Object property of the automation objects.
- /// </summary>
- internal virtual object Object
- {
- get { return this; }
- }
- #endregion
-
- #region properties
-
- public OleServiceProvider OleServiceProvider
- {
- get
- {
- return this.oleServiceProvider;
- }
- }
-
- [System.ComponentModel.BrowsableAttribute(false)]
- public ProjectNode ProjectMgr
- {
- get
- {
- return this.projectMgr;
- }
- set
- {
- this.projectMgr = value;
- }
- }
-
-
- [System.ComponentModel.BrowsableAttribute(false)]
- public HierarchyNode NextSibling
- {
- get
- {
- return this.nextSibling;
- }
- set
- {
- this.nextSibling = value;
- }
- }
-
-
- [System.ComponentModel.BrowsableAttribute(false)]
- public HierarchyNode FirstChild
- {
- get
- {
- return this.firstChild;
- }
- set
- {
- this.firstChild = value;
- }
- }
-
- [System.ComponentModel.BrowsableAttribute(false)]
- public HierarchyNode LastChild
- {
- get
- {
- return this.lastChild;
- }
- set
- {
- this.lastChild = value;
- }
- }
-
-
- [System.ComponentModel.BrowsableAttribute(false)]
- public HierarchyNode Parent
- {
- get
- {
- return this.parentNode;
- }
- set
- {
- this.parentNode = value;
- }
- }
-
-
- [System.ComponentModel.BrowsableAttribute(false)]
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID")]
- public uint ID
- {
- get
- {
- return this.hierarchyId;
- }
- internal set
- {
- this.hierarchyId = value;
- }
- }
-
-
- [System.ComponentModel.BrowsableAttribute(false)]
- public ProjectElement ItemNode
- {
- get
- {
- return itemNode;
- }
- set
- {
- itemNode = value;
- }
- }
-
-
- [System.ComponentModel.BrowsableAttribute(false)]
- public bool HasDesigner
- {
- get
- {
- return this.hasDesigner;
- }
- set { this.hasDesigner = value; }
- }
-
-
- [System.ComponentModel.BrowsableAttribute(false)]
- public bool IsExpanded
- {
- get
- {
- return this.isExpanded;
- }
- set { this.isExpanded = value; }
- }
-
- public string VirtualNodeName
- {
- get
- {
- return this.virtualNodeName;
- }
- set
- {
- this.virtualNodeName = value;
- }
- }
-
-
- [System.ComponentModel.BrowsableAttribute(false)]
- public HierarchyNode PreviousSibling
- {
- get
- {
- if(this.parentNode == null) return null;
- HierarchyNode prev = null;
- for(HierarchyNode child = this.parentNode.firstChild; child != null; child = child.nextSibling)
- {
- if(child == this)
- break;
- prev = child;
- }
- return prev;
- }
- }
-
- public uint DocCookie
- {
- get
- {
- return this.docCookie;
- }
- set
- {
- this.docCookie = value;
- }
- }
-
- /// <summary>
- /// Specifies if a Node is under source control.
- /// </summary>
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Scc")]
- public bool ExcludeNodeFromScc
- {
- get
- {
- return this.excludeNodeFromScc;
- }
- set
- {
- this.excludeNodeFromScc = value;
- }
- }
-
- /// <summary>
- /// Defines if a node a name relation to its parent node
- ///
- /// </summary>
- public bool HasParentNodeNameRelation
- {
- get
- {
- return this.hasParentNodeNameRelation;
- }
- set
- {
- this.hasParentNodeNameRelation = value;
- }
- }
-
- protected bool SourceDraggedOrCutOrCopied
- {
- get
- {
- return this.sourceDraggedOrCutOrCopied;
- }
- set
- {
- this.sourceDraggedOrCutOrCopied = value;
- }
- }
-
- protected IList<HierarchyNode> ItemsDraggedOrCutOrCopied
- {
- get
- {
- return this.itemsDraggedOrCutOrCopied;
- }
- }
- #endregion
-
- #region ctors
-
- protected HierarchyNode()
- {
- this.IsExpanded = true;
- }
-
- protected HierarchyNode(ProjectNode root, ProjectElement element)
- {
- if (root == null)
- {
- throw new ArgumentNullException("root");
- }
-
- this.projectMgr = root;
- this.itemNode = element;
- this.hierarchyId = this.projectMgr.ItemIdMap.Add(this);
- this.oleServiceProvider.AddService(typeof(IVsHierarchy), root, false);
- }
-
- /// <summary>
- /// Overloaded ctor.
- /// </summary>
- /// <param name="root"></param>
- protected HierarchyNode(ProjectNode root)
- {
- if (root == null)
- {
- throw new ArgumentNullException("root");
- }
-
- this.projectMgr = root;
- this.itemNode = new ProjectElement(this.projectMgr, null, true);
- this.hierarchyId = this.projectMgr.ItemIdMap.Add(this);
- this.oleServiceProvider.AddService(typeof(IVsHierarchy), root, false);
- }
- #endregion
-
- #region static methods
- /// <summary>
- /// Get the outer IVsHierarchy implementation.
- /// This is used for scenario where a flavor may be modifying the behavior
- /// </summary>
- internal static IVsHierarchy GetOuterHierarchy(HierarchyNode node)
- {
- IVsHierarchy hierarchy = null;
- // The hierarchy of a node is its project node hierarchy
- IntPtr projectUnknown = Marshal.GetIUnknownForObject(node.projectMgr);
- try
- {
- hierarchy = (IVsHierarchy)Marshal.GetTypedObjectForIUnknown(projectUnknown, typeof(IVsHierarchy));
- }
- finally
- {
- if(projectUnknown != IntPtr.Zero)
- {
- Marshal.Release(projectUnknown);
- }
- }
- return hierarchy;
- }
- #endregion
-
- #region virtual methods
- /// <summary>
- /// Creates an object derived from NodeProperties that will be used to expose properties
- /// spacific for this object to the property browser.
- /// </summary>
- /// <returns></returns>
- protected virtual NodeProperties CreatePropertiesObject()
- {
- return null;
- }
-
- /// <summary>
- /// Return an iconhandle
- /// </summary>
- /// <param name="open"></param>
- /// <returns></returns>
- public virtual object GetIconHandle(bool open)
- {
- return null;
- }
-
- /// <summary>
- /// AddChild - add a node, sorted in the right location.
- /// </summary>
- /// <param name="node">The node to add.</param>
- public virtual void AddChild(HierarchyNode node)
- {
- if(node == null)
- {
- throw new ArgumentNullException("node");
- }
-
- // make sure the node is in the map.
- Object nodeWithSameID = this.projectMgr.ItemIdMap[node.hierarchyId];
- if(!Object.ReferenceEquals(node, nodeWithSameID as HierarchyNode))
- {
- if(nodeWithSameID == null && node.ID <= this.ProjectMgr.ItemIdMap.Count)
- { // reuse our hierarchy id if possible.
- this.projectMgr.ItemIdMap.SetAt(node.hierarchyId, this);
- }
- else
- {
- throw new InvalidOperationException();
- }
- }
-
- HierarchyNode previous = null;
- for(HierarchyNode n = this.firstChild; n != null; n = n.nextSibling)
- {
- if(this.ProjectMgr.CompareNodes(node, n) > 0) break;
- previous = n;
- }
- // insert "node" after "previous".
- if(previous != null)
- {
- node.nextSibling = previous.nextSibling;
- previous.nextSibling = node;
- if(previous == this.lastChild)
- {
- this.lastChild = node;
- }
- }
- else
- {
- if(this.lastChild == null)
- {
- this.lastChild = node;
- }
- node.nextSibling = this.firstChild;
- this.firstChild = node;
- }
- node.parentNode = this;
- this.OnItemAdded(this, node);
- }
-
- /// <summary>
- /// Removes a node from the hierarchy.
- /// </summary>
- /// <param name="node">The node to remove.</param>
- public virtual void RemoveChild(HierarchyNode node)
- {
- if(node == null)
- {
- throw new ArgumentNullException("node");
- }
-
- this.projectMgr.ItemIdMap.Remove(node);
-
- HierarchyNode last = null;
- for(HierarchyNode n = this.firstChild; n != null; n = n.nextSibling)
- {
- if(n == node)
- {
- if(last != null)
- {
- last.nextSibling = n.nextSibling;
- }
- if(n == this.lastChild)
- {
- if(last == this.lastChild)
- {
- this.lastChild = null;
- }
- else
- {
- this.lastChild = last;
- }
- }
- if(n == this.firstChild)
- {
- this.firstChild = n.nextSibling;
- }
- return;
- }
- last = n;
- }
- throw new InvalidOperationException("Node not found");
- }
-
- /// <summary>
- /// Returns an automation object representing this node
- /// </summary>
- /// <returns>The automation object</returns>
- public virtual object GetAutomationObject()
- {
- return new Automation.OAProjectItem<HierarchyNode>(this.projectMgr.GetAutomationObject() as Automation.OAProject, this);
- }
-
- /// <summary>
- /// Returns a property object based on a property id
- /// </summary>
- /// <param name="propId">the property id of the property requested</param>
- /// <returns>the property object requested</returns>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
- public virtual object GetProperty(int propId)
- {
- object result = null;
- switch((__VSHPROPID)propId)
- {
- case __VSHPROPID.VSHPROPID_Expandable:
- result = (this.firstChild != null);
- break;
-
- case __VSHPROPID.VSHPROPID_Caption:
- result = this.Caption;
- break;
-
- case __VSHPROPID.VSHPROPID_Name:
- result = this.Caption;
- break;
-
- case __VSHPROPID.VSHPROPID_ExpandByDefault:
- result = false;
- break;
-
- case __VSHPROPID.VSHPROPID_IconImgList:
- result = this.ProjectMgr.ImageHandler.ImageList.Handle;
- break;
-
- case __VSHPROPID.VSHPROPID_OpenFolderIconIndex:
- case __VSHPROPID.VSHPROPID_IconIndex:
- int index = this.ImageIndex;
- if(index != NoImage)
- {
- result = index;
- }
- break;
-
- case __VSHPROPID.VSHPROPID_StateIconIndex:
- result = (int)this.StateIconIndex;
- break;
-
- case __VSHPROPID.VSHPROPID_IconHandle:
- result = GetIconHandle(false);
- break;
-
- case __VSHPROPID.VSHPROPID_OpenFolderIconHandle:
- result = GetIconHandle(true);
- break;
-
- case __VSHPROPID.VSHPROPID_NextVisibleSibling:
- goto case __VSHPROPID.VSHPROPID_NextSibling;
-
- case __VSHPROPID.VSHPROPID_NextSibling:
- result = (int)((this.nextSibling != null) ? this.nextSibling.hierarchyId : VSConstants.VSITEMID_NIL);
- break;
-
- case __VSHPROPID.VSHPROPID_FirstChild:
- goto case __VSHPROPID.VSHPROPID_FirstVisibleChild;
-
- case __VSHPROPID.VSHPROPID_FirstVisibleChild:
- result = (int)((this.firstChild != null) ? this.firstChild.hierarchyId : VSConstants.VSITEMID_NIL);
- break;
-
- case __VSHPROPID.VSHPROPID_Parent:
- if(null == this.parentNode)
- {
- unchecked { result = new IntPtr((int)VSConstants.VSITEMID_NIL); }
- }
- else
- {
- result = new IntPtr((int)this.parentNode.hierarchyId); // see bug 176470
- }
- break;
-
- case __VSHPROPID.VSHPROPID_ParentHierarchyItemid:
- if(parentHierarchy != null)
- {
- result = (IntPtr)parentHierarchyItemId; // VS requires VT_I4 | VT_INT_PTR
- }
- break;
-
- case __VSHPROPID.VSHPROPID_ParentHierarchy:
- result = parentHierarchy;
- break;
-
- case __VSHPROPID.VSHPROPID_Root:
- result = Marshal.GetIUnknownForObject(this.projectMgr);
- break;
-
- case __VSHPROPID.VSHPROPID_Expanded:
- result = this.isExpanded;
- break;
-
- case __VSHPROPID.VSHPROPID_BrowseObject:
- result = this.NodeProperties;
- if(result != null) result = new DispatchWrapper(result);
- break;
-
- case __VSHPROPID.VSHPROPID_EditLabel:
- if(this.ProjectMgr != null && !this.ProjectMgr.IsClosed && !this.ProjectMgr.IsCurrentStateASuppressCommandsMode())
- {
- result = GetEditLabel();
- }
- break;
-
- case __VSHPROPID.VSHPROPID_SaveName:
- //SaveName is the name shown in the Save and the Save Changes dialog boxes.
- result = this.Caption;
- break;
-
- case __VSHPROPID.VSHPROPID_ItemDocCookie:
- if(this.docCookie != 0) return (IntPtr)this.docCookie; //cast to IntPtr as some callers expect VT_INT
- break;
-
- case __VSHPROPID.VSHPROPID_ExtObject:
- result = GetAutomationObject();
- break;
- }
-
- __VSHPROPID2 id2 = (__VSHPROPID2)propId;
- switch(id2)
- {
- case __VSHPROPID2.VSHPROPID_NoDefaultNestedHierSorting:
- return true; // We are doing the sorting ourselves through VSHPROPID_FirstChild and VSHPROPID_NextSibling
- case __VSHPROPID2.VSHPROPID_BrowseObjectCATID:
- {
- // If there is a browse object and it is a NodeProperties, then get it's CATID
- object browseObject = this.GetProperty((int)__VSHPROPID.VSHPROPID_BrowseObject);
- if(browseObject != null)
- {
- if(browseObject is DispatchWrapper)
- browseObject = ((DispatchWrapper)browseObject).WrappedObject;
- result = this.ProjectMgr.GetCATIDForType(browseObject.GetType()).ToString("B");
- if(String.CompareOrdinal(result as string, Guid.Empty.ToString("B")) == 0)
- result = null;
- }
- break;
- }
- case __VSHPROPID2.VSHPROPID_ExtObjectCATID:
- {
- // If there is a extensibility object and it is a NodeProperties, then get it's CATID
- object extObject = this.GetProperty((int)__VSHPROPID.VSHPROPID_ExtObject);
- if(extObject != null)
- {
- if(extObject is DispatchWrapper)
- extObject = ((DispatchWrapper)extObject).WrappedObject;
- result = this.ProjectMgr.GetCATIDForType(extObject.GetType()).ToString("B");
- if(String.CompareOrdinal(result as string, Guid.Empty.ToString("B")) == 0)
- result = null;
- }
- break;
- }
- }
- #if DEBUG
- if(propId != LastTracedProperty)
- {
- string trailer = (result == null) ? "null" : result.ToString();
- CCITracing.TraceCall(this.hierarchyId + "," + propId.ToString() + " = " + trailer);
- LastTracedProperty = propId; // some basic filtering here...
- }
- #endif
- return result;
- }
-
- /// <summary>
- /// Sets the value of a property for a given property id
- /// </summary>
- /// <param name="propid">the property id of the property to be set</param>
- /// <param name="value">value of the property</param>
- /// <returns>S_OK if succeeded</returns>
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "propid")]
- public virtual int SetProperty(int propid, object value)
- {
- __VSHPROPID id = (__VSHPROPID)propid;
-
- CCITracing.TraceCall(this.hierarchyId + "," + id.ToString());
- switch(id)
- {
- case __VSHPROPID.VSHPROPID_Expanded:
- this.isExpanded = (bool)value;
- break;
-
- case __VSHPROPID.VSHPROPID_ParentHierarchy:
- parentHierarchy = (IVsHierarchy)value;
- break;
-
- case __VSHPROPID.VSHPROPID_ParentHierarchyItemid:
- parentHierarchyItemId = (int)value;
- break;
-
- case __VSHPROPID.VSHPROPID_EditLabel:
- return SetEditLabel((string)value);
-
- default:
- CCITracing.TraceCall(" unhandled");
- break;
- }
- return VSConstants.S_OK;
- }
-
- /// <summary>
- /// Get a guid property
- /// </summary>
- /// <param name="propid">property id for the guid property requested</param>
- /// <param name="guid">the requested guid</param>
- /// <returns>S_OK if succeded</returns>
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "propid")]
- public virtual int GetGuidProperty(int propid, out Guid guid)
- {
- guid = Guid.Empty;
- if(propid == (int)__VSHPROPID.VSHPROPID_TypeGuid)
- {
- guid = this.ItemTypeGuid;
- }
-
- if(guid.CompareTo(Guid.Empty) == 0)
- {
- return VSConstants.DISP_E_MEMBERNOTFOUND;
- }
-
- return VSConstants.S_OK;
- }
-
- /// <summary>
- /// Set a guid property.
- /// </summary>
- /// <param name="propid">property id of the guid property to be set</param>
- /// <param name="guid">the guid to be set</param>
- /// <returns>E_NOTIMPL</returns>
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "propid")]
- public virtual int SetGuidProperty(int propid, ref Guid guid)
- {
- return VSConstants.E_NOTIMPL;
- }
-
- /// <summary>
- /// Called by the shell when a node has been renamed from the GUI
- /// </summary>
- /// <param name="label"></param>
- /// <returns>E_NOTIMPL</returns>
- public virtual int SetEditLabel(string label)
- {
- return VSConstants.E_NOTIMPL;
- }
-
- /// <summary>
- /// Called by the shell to get the node caption when the user tries to rename from the GUI
- /// </summary>
- /// <returns>the node cation</returns>
- public virtual string GetEditLabel()
- {
- return this.Caption;
- }
-
- /// <summary>
- /// This method is called by the interface method GetMkDocument to specify the item moniker.
- /// </summary>
- /// <returns>The moniker for this item</returns>
- [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Mk")]
- public virtual string GetMkDocument()
- {
- return String.Empty;
- }
-
- /// <summary>
- /// Removes items from the hierarchy. Project overwrites this
- /// </summary>
- /// <param name="removeFromStorage"></param>
- public virtual void Remove(bool removeFromStorage)
- {
- string documentToRemove = this.GetMkDocument();
-
- // Ask Document tracker listeners if we can remove the item.
- string[] filesToBeDeleted = new string[1] { documentToRemove };
- VSQUERYREMOVEFILEFLAGS[] queryRemoveFlags = this.GetQueryRemoveFileFlags(filesToBeDeleted);
- if(!this.ProjectMgr.Tracker.CanRemoveItems(filesToBeDeleted, queryRemoveFlags))
- {
- return;
- }
-
- // Close the document if it has a manager.
- DocumentManager manager = this.GetDocumentManager();
- if(manager != null)
- {
- if(manager.Close(!removeFromStorage ? __FRAMECLOSE.FRAMECLOSE_PromptSave : __FRAMECLOSE.FRAMECLOSE_NoSave) == VSConstants.E_ABORT)
- {
- // User cancelled operation in message box.
- return;
- }
- }
-
- // Check out the project file.
- if(!this.ProjectMgr.QueryEditProjectFile(false))
- {
- throw Marshal.GetExceptionForHR(VSConstants.OLE_E_PROMPTSAVECANCELLED);
- }
-
- // Notify hierarchy event listeners that the file is going to be removed.
- OnItemDeleted();
-
- // Remove child if any before removing from the hierarchy
- for(HierarchyNode child = this.FirstChild; child != null; child = child.NextSibling)
- {
- child.Remove(removeFromStorage);
- }
-
- // the project node has no parentNode
- if(this.parentNode != null)
- {
- // Remove from the Hierarchy
- this.parentNode.RemoveChild(this);
- }
-
- // We save here the path to delete since this.Url might call the Include which will be deleted by the RemoveFromProjectFile call.
- string pathToDelete = this.GetMkDocument();
- this.itemNode.RemoveFromProjectFile();
-
- if(removeFromStorage)
- {
- this.DeleteFromStorage(pathToDelete);
- }
-
- // Close the document window if opened.
- CloseDocumentWindow(this);
-
- // Notify document tracker listeners that we have removed the item.
- VSREMOVEFILEFLAGS[] removeFlags = this.GetRemoveFileFlags(filesToBeDeleted);
- Debug.Assert(removeFlags != null, "At least an empty array should be returned for the GetRemoveFileFlags");
- this.ProjectMgr.Tracker.OnItemRemoved(documentToRemove, removeFlags[0]);
-
- // Notify hierarchy event listeners that we have removed the item
- if(null != this.parentNode.onChildRemoved)
- {
- HierarchyNodeEventArgs args = new HierarchyNodeEventArgs(this);
- parentNode.onChildRemoved(parentNode, args);
- }
-
- // Notify hierarchy event listeners that items have been invalidated
- OnInvalidateItems(this.parentNode);
-
- // Dispose the node now that is deleted.
- this.Dispose(true);
- }
-
- /// <summary>
- /// Returns the relational name which is defined as the first part of the caption until indexof NameRelationSeparator
- /// </summary>
- public virtual string GetRelationalName()
- {
- //Get the first part of the caption
- string[] partsOfParent = this.Caption.Split(new string[] { this.NameRelationSeparator }, StringSplitOptions.None);
- return partsOfParent[0];
- }
-
- /// <summary>
- /// Returns the 'extension' of the relational name
- /// e.g. form1.resx returns .resx, form1.designer.cs returns .designer.cs
- /// </summary>
- /// <returns>The extension</returns>
- public virtual string GetRelationNameExtension()
- {
- return this.Caption.Substring(this.Caption.IndexOf(this.NameRelationSeparator, StringComparison.Ordinal));
- }
-
- /// <summary>
- /// Close open document frame for a specific node.
- /// </summary>
- protected void CloseDocumentWindow(HierarchyNode node)
- {
- if (node == null)
- {
- throw new ArgumentNullException("node");
- }
-
- // We walk the RDT looking for all running documents attached to this hierarchy and itemid. There
- // are cases where there may be two different editors (not views) open on the same document.
- IEnumRunningDocuments pEnumRdt;
- IVsRunningDocumentTable pRdt = this.GetService(typeof(SVsRunningDocumentTable)) as IVsRunningDocumentTable;
- if(pRdt == null)
- {
- throw new InvalidOperationException();
- }
- if(ErrorHandler.Succeeded(pRdt.GetRunningDocumentsEnum(out pEnumRdt)))
- {
- uint[] cookie = new uint[1];
- uint fetched;
- uint saveOptions = (uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_NoSave;
- IVsHierarchy srpOurHier = node.projectMgr as IVsHierarchy;
-
- ErrorHandler.ThrowOnFailure(pEnumRdt.Reset());
- while(VSConstants.S_OK == pEnumRdt.Next(1, cookie, out fetched))
- {
- // Note we can pass NULL for all parameters we don't care about
- uint empty;
- string emptyStr;
- IntPtr ppunkDocData;
- IVsHierarchy srpHier;
- uint itemid = VSConstants.VSITEMID_NIL;
-
- ErrorHandler.ThrowOnFailure(pRdt.GetDocumentInfo(
- cookie[0],
- out empty,
- out empty,
- out empty,
- out emptyStr,
- out srpHier,
- out itemid,
- out ppunkDocData));
-
- // Is this one of our documents?
- if(Utilities.IsSameComObject(srpOurHier, srpHier) && itemid == node.ID)
- {
- IVsSolution soln = GetService(typeof(SVsSolution)) as IVsSolution;
- ErrorHandler.ThrowOnFailure(soln.CloseSolutionElement(saveOptions, srpOurHier, cookie[0]));
- }
- if(ppunkDocData != IntPtr.Zero)
- Marshal.Release(ppunkDocData);
-
- }
- }
- }
-
- /// <summary>
- /// Redraws the state icon if the node is not excluded from source control.
- /// </summary>
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Scc")]
- protected internal virtual void UpdateSccStateIcons()
- {
- if(!this.ExcludeNodeFromScc)
- {
- this.ReDraw(UIHierarchyElement.SccState);
- }
- }
-
- /// <summary>
- /// To be overwritten by descendants.
- /// </summary>
- protected internal virtual int SetEditLabel(string label, string relativePath)
- {
- throw new NotImplementedException();
- }
-
- /// <summary>
- /// Called by the drag and drop implementation to ask the node
- /// which is being dragged/droped over which nodes should
- /// process the operation.
- /// This allows for dragging to a node that cannot contain
- /// items to let its parent accept the drop
- /// </summary>
- /// <returns>HierarchyNode that accept the drop handling</returns>
- protected internal virtual HierarchyNode GetDragTargetHandlerNode()
- {
- return this;
- }
-
- /// <summary>
- /// Add a new Folder to the project hierarchy.
- /// </summary>
- /// <returns>S_OK if succeeded, otherwise an error</returns>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
- protected virtual int AddNewFolder()
- {
- // Check out the project file.
- if(!this.ProjectMgr.QueryEditProjectFile(false))
- {
- throw Marshal.GetExceptionForHR(VSConstants.OLE_E_PROMPTSAVECANCELLED);
- }
-
- try
- {
- // Generate a new folder name
- string newFolderName;
- ErrorHandler.ThrowOnFailure(this.projectMgr.GenerateUniqueItemName(this.hierarchyId, String.Empty, String.Empty, out newFolderName));
-
- // create the project part of it, the project file
- HierarchyNode child = this.ProjectMgr.CreateFolderNodes(Path.Combine(this.virtualNodeName, newFolderName));
-
- if(child is FolderNode)
- {
- ((FolderNode)child).CreateDirectory();
- }
-
- // If we are in automation mode then skip the ui part which is about renaming the folder
- if(!Utilities.IsInAutomationFunction(this.projectMgr.Site))
- {
- IVsUIHierarchyWindow uiWindow = UIHierarchyUtilities.GetUIHierarchyWindow(this.projectMgr.Site, SolutionExplorer);
- // we need to get into label edit mode now...
- // so first select the new guy...
- ErrorHandler.ThrowOnFailure(uiWindow.ExpandItem(this.projectMgr, child.hierarchyId, EXPANDFLAGS.EXPF_SelectItem));
- // them post the rename command to the shell. Folder verification and creation will
- // happen in the setlabel code...
- IVsUIShell shell = this.projectMgr.Site.GetService(typeof(SVsUIShell)) as IVsUIShell;
-
- Debug.Assert(shell != null, "Could not get the ui shell from the project");
- if(shell == null)
- {
- return VSConstants.E_FAIL;
- }
-
- object dummy = null;
- Guid cmdGroup = VsMenus.guidStandardCommandSet97;
- ErrorHandler.ThrowOnFailure(shell.PostExecCommand(ref cmdGroup, (uint)VsCommands.Rename, 0, ref dummy));
- }
- }
- catch(COMException e)
- {
- Trace.WriteLine("Exception : " + e.Message);
- return e.ErrorCode;
- }
-
- return VSConstants.S_OK;
- }
-
- protected virtual int AddItemToHierarchy(HierarchyAddType addType)
- {
- CCITracing.TraceCall();
- IVsAddProjectItemDlg addItemDialog;
-
- string strFilter = String.Empty;
- int iDontShowAgain;
- uint uiFlags;
- IVsProject3 project = (IVsProject3)this.projectMgr;
-
- string strBrowseLocations = Path.GetDirectoryName(this.projectMgr.BaseURI.Uri.LocalPath);
-
- System.Guid projectGuid = this.projectMgr.ProjectGuid;
-
- addItemDialog = this.GetService(typeof(IVsAddProjectItemDlg)) as IVsAddProjectItemDlg;
-
- if(addType == HierarchyAddType.AddNewItem)
- uiFlags = (uint)(__VSADDITEMFLAGS.VSADDITEM_AddNewItems | __VSADDITEMFLAGS.VSADDITEM_SuggestTemplateName | __VSADDITEMFLAGS.VSADDITEM_AllowHiddenTreeView);
- else
- uiFlags = (uint)(__VSADDITEMFLAGS.VSADDITEM_AddExistingItems | __VSADDITEMFLAGS.VSADDITEM_AllowMultiSelect | __VSADDITEMFLAGS.VSADDITEM_AllowStickyFilter);
-
- ErrorHandler.ThrowOnFailure(addItemDialog.AddProjectItemDlg(this.hierarchyId, ref projectGuid, project, uiFlags, null, null, ref strBrowseLocations, ref strFilter, out iDontShowAgain)); /*&fDontShowAgain*/
-
- return VSConstants.S_OK;
- }
-
- /// <summary>
- /// Overwritten in subclasses
- /// </summary>
- protected virtual void DoDefaultAction()
- {
- CCITracing.TraceCall();
- }
-
- /// <summary>
- /// Handles the exclude from project command.
- /// </summary>
- /// <returns></returns>
- protected virtual int ExcludeFromProject()
- {
- Debug.Assert(this.ProjectMgr != null, "The project item " + this.ToString() + " has not been initialised correctly. It has a null ProjectMgr");
- this.Remove(false);
- return VSConstants.S_OK;
- }
-
- /// <summary>
- /// Handles the Show in Designer command.
- /// </summary>
- /// <returns></returns>
- protected virtual int ShowInDesigner(IList<HierarchyNode> selectedNodes)
- {
- return (int)OleConstants.OLECMDERR_E_NOTSUPPORTED;
- }
-
- /// <summary>
- /// Prepares a selected node for clipboard.
- /// It takes the the project reference string of this item and adds it to a stringbuilder.
- /// </summary>
- /// <returns>A stringbuilder.</returns>
- /// <devremark>This method has to be public since seleceted nodes will call it.</devremark>
- [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "ClipBoard")]
- protected internal virtual StringBuilder PrepareSelectedNodesForClipBoard()
- {
- Debug.Assert(this.ProjectMgr != null, " No project mananager available for this node " + ToString());
- Debug.Assert(this.ProjectMgr.ItemsDraggedOrCutOrCopied != null, " The itemsdragged list should have been initialized prior calling this method");
- StringBuilder sb = new StringBuilder();
-
- if(this.hierarchyId == VSConstants.VSITEMID_ROOT)
- {
- if(this.ProjectMgr.ItemsDraggedOrCutOrCopied != null)
- {
- this.ProjectMgr.ItemsDraggedOrCutOrCopied.Clear();// abort
- }
- return sb;
- }
-
- if(this.ProjectMgr.ItemsDraggedOrCutOrCopied != null)
- {
- this.ProjectMgr.ItemsDraggedOrCutOrCopied.Add(this);
- }
-
- string projref = String.Empty;
- IVsSolution solution = this.GetService(typeof(IVsSolution)) as IVsSolution;
- if(solution != null)
- {
- ErrorHandler.ThrowOnFailure(solution.GetProjrefOfItem(this.ProjectMgr, this.hierarchyId, out projref));
- if(String.IsNullOrEmpty(projref))
- {
- if(this.ProjectMgr.ItemsDraggedOrCutOrCopied != null)
- {
- this.ProjectMgr.ItemsDraggedOrCutOrCopied.Clear();// abort
- }
- return sb;
- }
- }
-
- // Append the projectref and a null terminator to the string builder
- sb.Append(projref);
- sb.Append('\0');
-
- return sb;
- }
-
- /// <summary>
- /// Returns the Cannonical Name
- /// </summary>
- /// <returns>Cannonical Name</returns>
- protected virtual string GetCanonicalName()
- {
- return this.GetMkDocument();
- }
-
- /// <summary>
- /// Factory method for the Document Manager object
- /// </summary>
- /// <returns>null object, since a hierarchy node does not know its kind of document</returns>
- /// <remarks>Must be overriden by derived node classes if a document manager is needed</remarks>
- protected internal virtual DocumentManager GetDocumentManager()
- {
- return null;
- }
-
- /// <summary>
- /// Displays the context menu.
- /// </summary>
- /// <param name="selectedNodes">list of selected nodes.</param>
- /// <param name="pointerToVariant">contains the location (x,y) at which to show the menu.</param>
- [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "pointer")]
- protected virtual int DisplayContextMenu(IList<HierarchyNode> selectedNodes, IntPtr pointerToVariant)
- {
- if(selectedNodes == null || selectedNodes.Count == 0 || pointerToVariant == IntPtr.Zero)
- {
- return NativeMethods.OLECMDERR_E_NOTSUPPORTED;
- }
-
- int idmxStoredMenu = 0;
-
- foreach(HierarchyNode node in selectedNodes)
- {
- // We check here whether we have a multiple selection of
- // nodes of differing type.
- if(idmxStoredMenu == 0)
- {
- // First time through or single node case
- idmxStoredMenu = node.MenuCommandId;
- }
- else if(idmxStoredMenu != node.MenuCommandId)
- {
- // We have different node types. Check if any of the nodes is
- // the project node and set the menu accordingly.
- if(node.MenuCommandId == VsMenus.IDM_VS_CTXT_PROJNODE)
- {
- idmxStoredMenu = VsMenus.IDM_VS_CTXT_XPROJ_PROJITEM;
- }
- else
- {
- idmxStoredMenu = VsMenus.IDM_VS_CTXT_XPROJ_MULTIITEM;
- }
- }
- }
-
- object variant = Marshal.GetObjectForNativeVariant(pointerToVariant);
- UInt32 pointsAsUint = (UInt32)variant;
- short x = (short)(pointsAsUint & 0x0000ffff);
- short y = (short)((pointsAsUint & 0xffff0000) / 0x10000);
-
-
- POINTS points = new POINTS();
- points.x = x;
- points.y = y;
- return ShowContextMenu(idmxStoredMenu, VsMenus.guidSHLMainMenu, points);
- }
-
- /// <summary>
- /// Shows the specified context menu at a specified location.
- /// </summary>
- /// <param name="menuId">The context menu ID.</param>
- /// <param name="groupGuid">The GUID of the menu group.</param>
- /// <param name="points">The location at which to show the menu.</param>
- protected virtual int ShowContextMenu(int menuId, Guid menuGroup, POINTS points)
- {
- IVsUIShell shell = this.projectMgr.Site.GetService(typeof(SVsUIShell)) as IVsUIShell;
-
- Debug.Assert(shell != null, "Could not get the ui shell from the project");
- if(shell == null)
- {
- return VSConstants.E_FAIL;
- }
- POINTS[] pnts = new POINTS[1];
- pnts[0].x = points.x;
- pnts[0].y = points.y;
- return shell.ShowContextMenu(0, ref menuGroup, menuId, pnts, (Microsoft.VisualStudio.OLE.Interop.IOleCommandTarget)this);
- }
-
- #region initiation of command execution
- /// <summary>
- /// Handles command execution.
- /// </summary>
- /// <param name="cmdGroup">Unique identifier of the command group</param>
- /// <param name="cmd">The command to be executed.</param>
- /// <param name="nCmdexecopt">Values describe how the object should execute the command.</param>
- /// <param name="pvaIn">Pointer to a VARIANTARG structure containing input arguments. Can be NULL</param>
- /// <param name="pvaOut">VARIANTARG structure to receive command output. Can be NULL.</param>
- /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cmdexecopt")]
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "n")]
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "pva")]
- protected virtual int ExecCommandOnNode(Guid cmdGroup, uint cmd, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
- {
- if(this.projectMgr == null || this.projectMgr.IsClosed)
- {
- return (int)OleConstants.OLECMDERR_E_NOTSUPPORTED;
- }
-
- if(cmdGroup == Guid.Empty)
- {
- return (int)OleConstants.OLECMDERR_E_NOTSUPPORTED;
- }
- else if(cmdGroup == VsMenus.guidVsUIHierarchyWindowCmds)
- {
- switch(cmd)
- {
- case (uint)VSConstants.VsUIHierarchyWindowCmdIds.UIHWCMDID_DoubleClick:
- case (uint)VSConstants.VsUIHierarchyWindowCmdIds.UIHWCMDID_EnterKey:
- this.DoDefaultAction();
- return VSConstants.S_OK;
- }
- return (int)OleConstants.OLECMDERR_E_NOTSUPPORTED;
- }
- else if(cmdGroup == VsMenus.guidStandardCommandSet97)
- {
- HierarchyNode nodeToAddTo = this.GetDragTargetHandlerNode();
- switch((VsCommands)cmd)
- {
- case VsCommands.AddNewItem:
- return nodeToAddTo.AddItemToHierarchy(HierarchyAddType.AddNewItem);
-
- case VsCommands.AddExistingItem:
- return nodeToAddTo.AddItemToHierarchy(HierarchyAddType.AddExistingItem);
-
- case VsCommands.NewFolder:
- return nodeToAddTo.AddNewFolder();
-
- case VsCommands.Paste:
- return this.ProjectMgr.PasteFromClipboard(this);
- }
-
- }
- else if(cmdGroup == VsMenus.guidStandardCommandSet2K)
- {
- switch((VsCommands2K)cmd)
- {
- case VsCommands2K.EXCLUDEFROMPROJECT:
- return this.ExcludeFromProject();
- }
- }
-
- return (int)OleConstants.OLECMDERR_E_NOTSUPPORTED;
- }
-
- /// <summary>
- /// Executes a command that can only be executed once the whole selection is known.
- /// </summary>
- /// <param name="cmdGroup">Unique identifier of the command group</param>
- /// <param name="cmdId">The command to be executed.</param>
- /// <param name="cmdExecOpt">Values describe how the object should execute the command.</param>
- /// <param name="vaIn">Pointer to a VARIANTARG structure containing input arguments. Can be NULL</param>
- /// <param name="vaOut">VARIANTARG structure to receive command output. Can be NULL.</param>
- /// <param name="commandOrigin">The origin of the command. From IOleCommandTarget or hierarchy.</param>
- /// <param name="selectedNodes">The list of the selected nodes.</param>
- /// <param name="handled">An out parameter specifying that the command was handled.</param>
- /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
- [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "vaIn")]
- protected virtual int ExecCommandThatDependsOnSelectedNodes(Guid cmdGroup, uint cmdId, uint cmdExecOpt, IntPtr vaIn, IntPtr vaOut, CommandOrigin commandOrigin, IList<HierarchyNode> selectedNodes, out bool handled)
- {
- handled = false;
- if(cmdGroup == VsMenus.guidVsUIHierarchyWindowCmds)
- {
- switch(cmdId)
- {
- case (uint)VSConstants.VsUIHierarchyWindowCmdIds.UIHWCMDID_RightClick:
- // The UIHWCMDID_RightClick is what tells an IVsUIHierarchy in a UIHierarchyWindow
- // to put up the context menu. Since the mouse may have moved between the
- // mouse down and the mouse up, GetCursorPos won't tell you the right place
- // to put the context menu (especially if it came through the keyboard).
- // So we pack the proper menu position into pvaIn by
- // memcpy'ing a POINTS struct into the VT_UI4 part of the pvaIn variant. The
- // code to unpack it looks like this:
- // ULONG ulPts = V_UI4(pvaIn);
- // POINTS pts;
- // memcpy((void*)&pts, &ulPts, sizeof(POINTS));
- // You then pass that POINTS into DisplayContextMenu.
- handled = true;
- return this.DisplayContextMenu(selectedNodes, vaIn);
- default:
- break;
- }
- }
- else if(cmdGroup == VsMenus.guidStandardCommandSet2K)
- {
- switch((VsCommands2K)cmdId)
- {
- case VsCommands2K.ViewInClassDiagram:
- handled = true;
- return this.ShowInDesigner(selectedNodes);
- }
- }
-
- return (int)OleConstants.OLECMDERR_E_NOTSUPPORTED;
- }
-
- /// <summary>
- /// Executes command that are independent of a selection.
- /// </summary>
- /// <param name="cmdGroup">Unique identifier of the command group</param>
- /// <param name="cmdId">The command to be executed.</param>
- /// <param name="cmdExecOpt">Values describe how the object should execute the command.</param>
- /// <param name="vaIn">Pointer to a VARIANTARG structure containing input arguments. Can be NULL</param>
- /// <param name="vaOut">VARIANTARG structure to receive command output. Can be NULL.</param>
- /// <param name="commandOrigin">The origin of the command. From IOleCommandTarget or hierarchy.</param>
- /// <param name="handled">An out parameter specifying that the command was handled.</param>
- /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
- [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "vaIn")]
- protected virtual int ExecCommandIndependentOfSelection(Guid cmdGroup, uint cmdId, uint cmdExecOpt, IntPtr vaIn, IntPtr vaOut, CommandOrigin commandOrigin, out bool handled)
- {
- handled = false;
-
- if(this.projectMgr == null || this.projectMgr.IsClosed)
- {
- return VSConstants.E_FAIL;
- }
-
- if(cmdGroup == VsMenus.guidStandardCommandSet97)
- {
- if(commandOrigin == CommandOrigin.OleCommandTarget)
- {
- switch((VsCommands)cmdId)
- {
- case VsCommands.Cut:
- case VsCommands.Copy:
- case VsCommands.Paste:
- case VsCommands.Rename:
- handled = true;
- return (int)OleConstants.OLECMDERR_E_NOTSUPPORTED;
- }
- }
-
- switch((VsCommands)cmdId)
- {
- case VsCommands.Copy:
- handled = true;
- return this.ProjectMgr.CopyToClipboard();
-
- case VsCommands.Cut:
- handled = true;
- return this.ProjectMgr.CutToClipboard();
-
- case VsCommands.SolutionCfg:
- handled = true;
- return (int)OleConstants.OLECMDERR_E_NOTSUPPORTED;
-
- case VsCommands.SearchCombo:
- handled = true;
- return (int)OleConstants.OLECMDERR_E_NOTSUPPORTED;
-
- }
- }
- else if(cmdGroup == VsMenus.guidStandardCommandSet2K)
- {
- // There should only be the project node who handles these and should manifest in the same action regardles of selection.
- switch((VsCommands2K)cmdId)
- {
- case VsCommands2K.SHOWALLFILES:
- handled = true;
- return this.projectMgr.ShowAllFiles();
- case VsCommands2K.ADDREFERENCE:
- handled = true;
- return this.projectMgr.AddProjectReference();
- case VsCommands2K.ADDWEBREFERENCE:
- handled = true;
- return this.projectMgr.AddWebReference();
- }
- }
-
- return (int)OleConstants.OLECMDERR_E_NOTSUPPORTED;
- }
-
- /// <summary>
- /// The main entry point for command excection. Gets called from the IVsUIHierarchy and IOleCommandTarget methods.
- /// </summary>
- /// <param name="cmdGroup">Unique identifier of the command group</param>
- /// <param name="cmdId">The command to be executed.</param>
- /// <param name="cmdExecOpt">Values describe how the object should execute the command.</param>
- /// <param name="vaIn">Pointer to a VARIANTARG structure containing input arguments. Can be NULL</param>
- /// <param name="vaOut">VARIANTARG structure to receive command output. Can be NULL.</param>
- /// <param name="commandOrigin">The origin of the command. From IOleCommandTarget or hierarchy.</param>
- /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
- [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "vaIn")]
- protected virtual int InternalExecCommand(Guid cmdGroup, uint cmdId, uint cmdExecOpt, IntPtr vaIn, IntPtr vaOut, CommandOrigin commandOrigin)
- {
- CCITracing.TraceCall(cmdGroup.ToString() + "," + cmdId.ToString());
- if(this.projectMgr == null || this.projectMgr.IsClosed)
- {
- return (int)OleConstants.OLECMDERR_E_NOTSUPPORTED;
- }
-
- if(cmdGroup == Guid.Empty)
- {
- return (int)OleConstants.OLECMDERR_E_NOTSUPPORTED;
- }
-
- IList<HierarchyNode> selectedNodes = this.projectMgr.GetSelectedNodes();
-
- // Check if all nodes can execute a command. If there is at least one that cannot return not handled.
- foreach(HierarchyNode node in selectedNodes)
- {
- if(!node.CanExecuteCommand)
- {
- return (int)OleConstants.OLECMDERR_E_NOTSUPPORTED;
- }
- }
-
- // Handle commands that are …
Large files files are truncated, but you can click here to view the full file