| Index: obsolete/Microsoft.VisualStudio.Project/NestedProjectNode.cs
|
| diff --git a/obsolete/Microsoft.VisualStudio.Project/NestedProjectNode.cs b/obsolete/Microsoft.VisualStudio.Project/NestedProjectNode.cs
|
| deleted file mode 100644
|
| index 4e612206e87f1b8488892fb2bd344bb3bdcc00b4..0000000000000000000000000000000000000000
|
| --- a/obsolete/Microsoft.VisualStudio.Project/NestedProjectNode.cs
|
| +++ /dev/null
|
| @@ -1,1138 +0,0 @@
|
| -/// Copyright (c) Microsoft Corporation. All rights reserved.
|
| -
|
| -using System;
|
| -using System.Diagnostics;
|
| -using System.Diagnostics.CodeAnalysis;
|
| -using System.Globalization;
|
| -using System.IO;
|
| -using System.Runtime.InteropServices;
|
| -using Microsoft.VisualStudio;
|
| -using Microsoft.VisualStudio.OLE.Interop;
|
| -using Microsoft.VisualStudio.Shell;
|
| -using Microsoft.VisualStudio.Shell.Interop;
|
| -using ErrorHandler = Microsoft.VisualStudio.ErrorHandler;
|
| -using ShellConstants = Microsoft.VisualStudio.Shell.Interop.Constants;
|
| -
|
| -namespace Microsoft.VisualStudio.Project
|
| -{
|
| - [CLSCompliant(false), ComVisible(true)]
|
| - public class NestedProjectNode : HierarchyNode, IPropertyNotifySink
|
| - {
|
| - #region fields
|
| - private IVsHierarchy nestedHierarchy;
|
| -
|
| - Guid projectInstanceGuid = Guid.Empty;
|
| -
|
| - private string projectName = String.Empty;
|
| -
|
| - private string projectPath = String.Empty;
|
| -
|
| - private ImageHandler imageHandler;
|
| -
|
| - /// <summary>
|
| - /// Defines an object that will be a mutex for this object for synchronizing thread calls.
|
| - /// </summary>
|
| - private static volatile object Mutex = new object();
|
| -
|
| - /// <summary>
|
| - /// Sets the dispose flag on the object.
|
| - /// </summary>
|
| - private bool isDisposed;
|
| -
|
| - // A cooike retrieved when advising on property chnanged events.
|
| - private uint projectPropertyNotifySinkCookie;
|
| - #endregion
|
| -
|
| - #region properties
|
| - internal IVsHierarchy NestedHierarchy
|
| - {
|
| - get
|
| - {
|
| - return this.nestedHierarchy;
|
| - }
|
| - }
|
| - #endregion
|
| -
|
| - #region virtual properties
|
| - /// <summary>
|
| - /// Returns the __VSADDVPFLAGS that will be passed in when calling AddVirtualProjectEx
|
| - /// </summary>
|
| - protected virtual uint VirtualProjectFlags
|
| - {
|
| - get { return 0; }
|
| - }
|
| - #endregion
|
| -
|
| - #region overridden properties
|
| - /// <summary>
|
| - /// The path of the nested project.
|
| - /// </summary>
|
| - public override string Url
|
| - {
|
| - get
|
| - {
|
| - return this.projectPath;
|
| - }
|
| - }
|
| -
|
| - /// <summary>
|
| - /// The Caption of the nested project.
|
| - /// </summary>
|
| - public override string Caption
|
| - {
|
| - get
|
| - {
|
| - return Path.GetFileNameWithoutExtension(this.projectName);
|
| - }
|
| - }
|
| -
|
| - public override Guid ItemTypeGuid
|
| - {
|
| - get
|
| - {
|
| - return VSConstants.GUID_ItemType_SubProject;
|
| - }
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Defines whether a node can execute a command if in selection.
|
| - /// We do this in order to let the nested project to handle the execution of its own commands.
|
| - /// </summary>
|
| - public override bool CanExecuteCommand
|
| - {
|
| - get
|
| - {
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - public override int SortPriority
|
| - {
|
| - get { return DefaultSortOrderNode.NestedProjectNode; }
|
| - }
|
| -
|
| - protected bool IsDisposed
|
| - {
|
| - get { return this.isDisposed; }
|
| - set { this.isDisposed = value; }
|
| - }
|
| -
|
| -
|
| -
|
| - #endregion
|
| -
|
| - #region ctor
|
| -
|
| - protected NestedProjectNode()
|
| - {
|
| - }
|
| -
|
| - public NestedProjectNode(ProjectNode root, ProjectElement element)
|
| - : base(root, element)
|
| - {
|
| - this.IsExpanded = true;
|
| - }
|
| - #endregion
|
| -
|
| - #region IPropertyNotifySink Members
|
| - /// <summary>
|
| - /// Notifies a sink that the [bindable] property specified by dispID has changed.
|
| - /// If dispID is DISPID_UNKNOWN, then multiple properties have changed together.
|
| - /// The client (owner of the sink) should then retrieve the current value of each property of interest from the object that generated the notification.
|
| - /// In our case we will care about the VSLangProj80.VsProjPropId.VBPROJPROPID_FileName and update the changes in the parent project file.
|
| - /// </summary>
|
| - /// <param name="dispid">Dispatch identifier of the property that is about to change or DISPID_UNKNOWN if multiple properties are about to change.</param>
|
| - public virtual void OnChanged(int dispid)
|
| - {
|
| - if(dispid == (int)VSLangProj80.VsProjPropId.VBPROJPROPID_FileName)
|
| - {
|
| - // Get the filename of the nested project. Inetead of asking the label on the nested we ask the filename, since the label might not yet been set.
|
| - IVsProject3 nestedProject = this.nestedHierarchy as IVsProject3;
|
| -
|
| - if(nestedProject != null)
|
| - {
|
| - string document;
|
| - ErrorHandler.ThrowOnFailure(nestedProject.GetMkDocument(VSConstants.VSITEMID_ROOT, out document));
|
| - this.RenameNestedProjectInParentProject(Path.GetFileNameWithoutExtension(document));
|
| -
|
| - // We need to redraw the caption since for some reason, by intervining to the OnChanged event the Caption is not updated.
|
| - this.ReDraw(UIHierarchyElement.Caption);
|
| - }
|
| - }
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Notifies a sink that a [requestedit] property is about to change and that the object is asking the sink how to proceed.
|
| - /// </summary>
|
| - /// <param name="dispid">Dispatch identifier of the property that is about to change or DISPID_UNKNOWN if multiple properties are about to change.</param>
|
| - public virtual void OnRequestEdit(int dispid)
|
| - {
|
| -
|
| - }
|
| -
|
| - #endregion
|
| -
|
| - #region public methods
|
| - #endregion
|
| -
|
| - #region overridden methods
|
| -
|
| - /// <summary>
|
| - /// Get the automation object for the NestedProjectNode
|
| - /// </summary>
|
| - /// <returns>An instance of the Automation.OANestedProjectItem type if succeded</returns>
|
| - public override object GetAutomationObject()
|
| - {
|
| - //Validate that we are not disposed or the project is closing
|
| - if(this.isDisposed || this.ProjectMgr == null || this.ProjectMgr.IsClosed)
|
| - {
|
| - return null;
|
| - }
|
| -
|
| - return new Automation.OANestedProjectItem(this.ProjectMgr.GetAutomationObject() as Automation.OAProject, this);
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Gets properties of a given node or of the hierarchy.
|
| - /// </summary>
|
| - /// <param name="propId">Identifier of the hierarchy property</param>
|
| - /// <returns>It return an object which type is dependent on the propid.</returns>
|
| - public override object GetProperty(int propId)
|
| - {
|
| - __VSHPROPID vshPropId = (__VSHPROPID)propId;
|
| - switch(vshPropId)
|
| - {
|
| - default:
|
| - return base.GetProperty(propId);
|
| -
|
| - case __VSHPROPID.VSHPROPID_Expandable:
|
| - return true;
|
| -
|
| - case __VSHPROPID.VSHPROPID_BrowseObject:
|
| - case __VSHPROPID.VSHPROPID_HandlesOwnReload:
|
| - return this.DelegateGetPropertyToNested(propId);
|
| - }
|
| - }
|
| -
|
| -
|
| - /// <summary>
|
| - /// Gets properties whose values are GUIDs.
|
| - /// </summary>
|
| - /// <param name="propid">Identifier of the hierarchy property</param>
|
| - /// <param name="guid"> Pointer to a GUID property specified in propid</param>
|
| - /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
|
| - public override int GetGuidProperty(int propid, out Guid guid)
|
| - {
|
| - guid = Guid.Empty;
|
| - switch((__VSHPROPID)propid)
|
| - {
|
| - case __VSHPROPID.VSHPROPID_ProjectIDGuid:
|
| - guid = this.projectInstanceGuid;
|
| - break;
|
| -
|
| - default:
|
| - return base.GetGuidProperty(propid, out guid);
|
| - }
|
| -
|
| - CCITracing.TraceCall(String.Format(CultureInfo.CurrentCulture, "Guid for {0} property", propid));
|
| - if(guid.CompareTo(Guid.Empty) == 0)
|
| - {
|
| - return VSConstants.DISP_E_MEMBERNOTFOUND;
|
| - }
|
| -
|
| - return VSConstants.S_OK;
|
| - }
|
| -
|
| -
|
| - /// <summary>
|
| - /// Determines whether the hierarchy item changed.
|
| - /// </summary>
|
| - /// <param name="itemId">Item identifier of the hierarchy item contained in VSITEMID</param>
|
| - /// <param name="punkDocData">Pointer to the IUnknown interface of the hierarchy item. </param>
|
| - /// <param name="pfDirty">TRUE if the hierarchy item changed.</param>
|
| - /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
|
| - public override int IsItemDirty(uint itemId, IntPtr punkDocData, out int pfDirty)
|
| - {
|
| - Debug.Assert(this.nestedHierarchy != null, "The nested hierarchy object must be created before calling this method");
|
| - Debug.Assert(punkDocData != IntPtr.Zero, "docData intptr was zero");
|
| -
|
| - // Get an IPersistFileFormat object from docData object
|
| - IPersistFileFormat persistFileFormat = Marshal.GetTypedObjectForIUnknown(punkDocData, typeof(IPersistFileFormat)) as IPersistFileFormat;
|
| - Debug.Assert(persistFileFormat != null, "The docData object does not implement the IPersistFileFormat interface");
|
| -
|
| - // Call IsDirty on the IPersistFileFormat interface
|
| - ErrorHandler.ThrowOnFailure(persistFileFormat.IsDirty(out pfDirty));
|
| -
|
| - return VSConstants.S_OK;
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Saves the hierarchy item to disk.
|
| - /// </summary>
|
| - /// <param name="dwSave">Flags whose values are taken from the VSSAVEFLAGS enumeration.</param>
|
| - /// <param name="silentSaveAsName">File name to be applied when dwSave is set to VSSAVE_SilentSave. </param>
|
| - /// <param name="itemid">Item identifier of the hierarchy item saved from VSITEMID. </param>
|
| - /// <param name="punkDocData">Pointer to the IUnknown interface of the hierarchy item saved.</param>
|
| - /// <param name="pfCancelled">TRUE if the save action was canceled. </param>
|
| - /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
|
| - public override int SaveItem(VSSAVEFLAGS dwSave, string silentSaveAsName, uint itemid, IntPtr punkDocData, out int pfCancelled)
|
| - {
|
| - // Don't ignore/unignore file changes
|
| - // Use Advise/Unadvise to work around rename situations
|
| - try
|
| - {
|
| - this.StopObservingNestedProjectFile();
|
| - Debug.Assert(this.nestedHierarchy != null, "The nested hierarchy object must be created before calling this method");
|
| - Debug.Assert(punkDocData != IntPtr.Zero, "docData intptr was zero");
|
| -
|
| - // Get an IPersistFileFormat object from docData object (we don't call release on punkDocData since did not increment its ref count)
|
| - IPersistFileFormat persistFileFormat = Marshal.GetTypedObjectForIUnknown(punkDocData, typeof(IPersistFileFormat)) as IPersistFileFormat;
|
| - Debug.Assert(persistFileFormat != null, "The docData object does not implement the IPersistFileFormat interface");
|
| -
|
| - IVsUIShell uiShell = this.GetService(typeof(SVsUIShell)) as IVsUIShell;
|
| - string newName;
|
| - ErrorHandler.ThrowOnFailure(uiShell.SaveDocDataToFile(dwSave, persistFileFormat, silentSaveAsName, out newName, out pfCancelled));
|
| -
|
| - // When supported do a rename of the nested project here
|
| - }
|
| - finally
|
| - {
|
| - // Succeeded or not we must hook to the file change events
|
| - // Don't ignore/unignore file changes
|
| - // Use Advise/Unadvise to work around rename situations
|
| - this.ObserveNestedProjectFile();
|
| - }
|
| -
|
| - return VSConstants.S_OK;
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Gets the icon handle. It tries first the nested to get the icon handle. If that is not supported it will get it from
|
| - /// the image list of the nested if that is supported. If neither of these is supported a default image will be shown.
|
| - /// </summary>
|
| - /// <returns>An object representing the icon.</returns>
|
| - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "Microsoft.VisualStudio.Shell.Interop.IVsHierarchy.GetProperty(System.UInt32,System.Int32,System.Object@)")]
|
| - public override object GetIconHandle(bool open)
|
| - {
|
| - Debug.Assert(this.nestedHierarchy != null, "The nested hierarchy object must be created before calling this method");
|
| -
|
| - object iconHandle = null;
|
| - this.nestedHierarchy.GetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_IconHandle, out iconHandle);
|
| - if(iconHandle == null)
|
| - {
|
| - if(null == imageHandler)
|
| - {
|
| - InitImageHandler();
|
| - }
|
| - // Try to get an icon from the nested hierrachy image list.
|
| - if(imageHandler.ImageList != null)
|
| - {
|
| - object imageIndexAsObject = null;
|
| - if(this.nestedHierarchy.GetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_IconIndex, out imageIndexAsObject) == VSConstants.S_OK &&
|
| - imageIndexAsObject != null)
|
| - {
|
| - int imageIndex = (int)imageIndexAsObject;
|
| - if(imageIndex < imageHandler.ImageList.Images.Count)
|
| - {
|
| - iconHandle = imageHandler.GetIconHandle(imageIndex);
|
| - }
|
| - }
|
| - }
|
| -
|
| - if(null == iconHandle)
|
| - {
|
| - iconHandle = this.ProjectMgr.ImageHandler.GetIconHandle((int)ProjectNode.ImageName.Application);
|
| - }
|
| - }
|
| -
|
| - return iconHandle;
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Return S_OK. Implementation of Closing a nested project is done in CloseNestedProject which is called by CloseChildren.
|
| - /// </summary>
|
| - /// <returns>S_OK</returns>
|
| - public override int Close()
|
| - {
|
| - return VSConstants.S_OK;
|
| - }
|
| -
|
| -
|
| - /// <summary>
|
| - /// Returns the moniker of the nested project.
|
| - /// </summary>
|
| - /// <returns></returns>
|
| - public override string GetMkDocument()
|
| - {
|
| - Debug.Assert(this.nestedHierarchy != null, "The nested hierarchy object must be created before calling this method");
|
| - if(this.isDisposed || this.ProjectMgr == null || this.ProjectMgr.IsClosed)
|
| - {
|
| - return String.Empty;
|
| - }
|
| -
|
| - return this.projectPath;
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Called by the shell when a node has been renamed from the GUI
|
| - /// </summary>
|
| - /// <param name="label">The name of the new label.</param>
|
| - /// <returns>A success or failure value.</returns>
|
| - public override int SetEditLabel(string label)
|
| - {
|
| - int result = this.DelegateSetPropertyToNested((int)__VSHPROPID.VSHPROPID_EditLabel, label);
|
| - if(ErrorHandler.Succeeded(result))
|
| - {
|
| - this.RenameNestedProjectInParentProject(label);
|
| - }
|
| -
|
| - return result;
|
| - }
|
| -
|
| - /// <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 override string GetEditLabel()
|
| - {
|
| - return (string)this.DelegateGetPropertyToNested((int)__VSHPROPID.VSHPROPID_EditLabel);
|
| - }
|
| -
|
| - /// <summary>
|
| - /// This is temporary until we have support for re-adding a nested item
|
| - /// </summary>
|
| - protected override bool CanDeleteItem(__VSDELETEITEMOPERATION deleteOperation)
|
| - {
|
| - return false;
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Delegates the call to the inner hierarchy.
|
| - /// </summary>
|
| - /// <param name="reserved">Reserved parameter defined at the IVsPersistHierarchyItem2::ReloadItem parameter.</param>
|
| - protected internal override void ReloadItem(uint reserved)
|
| - {
|
| - #region precondition
|
| - if(this.isDisposed || this.ProjectMgr == null || this.ProjectMgr.IsClosed)
|
| - {
|
| - throw new InvalidOperationException();
|
| - }
|
| -
|
| - Debug.Assert(this.nestedHierarchy != null, "The nested hierarchy object must be created before calling this method");
|
| - #endregion
|
| -
|
| - IVsPersistHierarchyItem2 persistHierachyItem = this.nestedHierarchy as IVsPersistHierarchyItem2;
|
| -
|
| - // We are expecting that if we get called then the nestedhierarchy supports IVsPersistHierarchyItem2, since then hierrachy should support handling its own reload.
|
| - // There should be no errormessage to the user since this is an internal error, that it cannot be fixed at user level.
|
| - if(persistHierachyItem == null)
|
| - {
|
| - throw new InvalidOperationException();
|
| - }
|
| -
|
| - ErrorHandler.ThrowOnFailure(persistHierachyItem.ReloadItem(VSConstants.VSITEMID_ROOT, reserved));
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Flag indicating that changes to a file can be ignored when item is saved or reloaded.
|
| - /// </summary>
|
| - /// <param name="ignoreFlag">Flag indicating whether or not to ignore changes (1 to ignore, 0 to stop ignoring).</param>
|
| - protected internal override void IgnoreItemFileChanges(bool ignoreFlag)
|
| - {
|
| - #region precondition
|
| - if(this.isDisposed || this.ProjectMgr == null || this.ProjectMgr.IsClosed)
|
| - {
|
| - throw new InvalidOperationException();
|
| - }
|
| -
|
| - Debug.Assert(this.nestedHierarchy != null, "The nested hierarchy object must be created before calling this method");
|
| - #endregion
|
| -
|
| - this.IgnoreNestedProjectFile(ignoreFlag);
|
| -
|
| - IVsPersistHierarchyItem2 persistHierachyItem = this.nestedHierarchy as IVsPersistHierarchyItem2;
|
| -
|
| - // If the IVsPersistHierarchyItem2 is not implemented by the nested just return
|
| - if(persistHierachyItem == null)
|
| - {
|
| - return;
|
| - }
|
| -
|
| - ErrorHandler.ThrowOnFailure(persistHierachyItem.IgnoreItemFileChanges(VSConstants.VSITEMID_ROOT, ignoreFlag ? 1 : 0));
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Sets the VSADDFILEFLAGS that will be used to call the IVsTrackProjectDocumentsEvents2 OnAddFiles
|
| - /// </summary>
|
| - /// <param name="files">The files to which an array of VSADDFILEFLAGS has to be specified.</param>
|
| - /// <returns></returns>
|
| - protected internal override VSADDFILEFLAGS[] GetAddFileFlags(string[] files)
|
| - {
|
| - if(files == null || files.Length == 0)
|
| - {
|
| - return new VSADDFILEFLAGS[1] { VSADDFILEFLAGS.VSADDFILEFLAGS_NoFlags };
|
| - }
|
| -
|
| - VSADDFILEFLAGS[] addFileFlags = new VSADDFILEFLAGS[files.Length];
|
| -
|
| - for(int i = 0; i < files.Length; i++)
|
| - {
|
| - addFileFlags[i] = VSADDFILEFLAGS.VSADDFILEFLAGS_IsNestedProjectFile;
|
| - }
|
| -
|
| - return addFileFlags;
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Sets the VSQUERYADDFILEFLAGS that will be used to call the IVsTrackProjectDocumentsEvents2 OnQueryAddFiles
|
| - /// </summary>
|
| - /// <param name="files">The files to which an array of VSADDFILEFLAGS has to be specified.</param>
|
| - /// <returns></returns>
|
| - protected internal override VSQUERYADDFILEFLAGS[] GetQueryAddFileFlags(string[] files)
|
| - {
|
| - if(files == null || files.Length == 0)
|
| - {
|
| - return new VSQUERYADDFILEFLAGS[1] { VSQUERYADDFILEFLAGS.VSQUERYADDFILEFLAGS_NoFlags };
|
| - }
|
| -
|
| - VSQUERYADDFILEFLAGS[] queryAddFileFlags = new VSQUERYADDFILEFLAGS[files.Length];
|
| -
|
| - for(int i = 0; i < files.Length; i++)
|
| - {
|
| - queryAddFileFlags[i] = VSQUERYADDFILEFLAGS.VSQUERYADDFILEFLAGS_IsNestedProjectFile;
|
| - }
|
| -
|
| - return queryAddFileFlags;
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Sets the VSREMOVEFILEFLAGS that will be used to call the IVsTrackProjectDocumentsEvents2 OnRemoveFiles
|
| - /// </summary>
|
| - /// <param name="files">The files to which an array of VSREMOVEFILEFLAGS has to be specified.</param>
|
| - /// <returns></returns>
|
| - protected internal override VSREMOVEFILEFLAGS[] GetRemoveFileFlags(string[] files)
|
| - {
|
| - if(files == null || files.Length == 0)
|
| - {
|
| - return new VSREMOVEFILEFLAGS[1] { VSREMOVEFILEFLAGS.VSREMOVEFILEFLAGS_NoFlags };
|
| - }
|
| -
|
| - VSREMOVEFILEFLAGS[] removeFileFlags = new VSREMOVEFILEFLAGS[files.Length];
|
| -
|
| - for(int i = 0; i < files.Length; i++)
|
| - {
|
| - removeFileFlags[i] = VSREMOVEFILEFLAGS.VSREMOVEFILEFLAGS_IsNestedProjectFile;
|
| - }
|
| -
|
| - return removeFileFlags;
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Sets the VSQUERYREMOVEFILEFLAGS that will be used to call the IVsTrackProjectDocumentsEvents2 OnQueryRemoveFiles
|
| - /// </summary>
|
| - /// <param name="files">The files to which an array of VSQUERYREMOVEFILEFLAGS has to be specified.</param>
|
| - /// <returns></returns>
|
| - protected internal override VSQUERYREMOVEFILEFLAGS[] GetQueryRemoveFileFlags(string[] files)
|
| - {
|
| - if(files == null || files.Length == 0)
|
| - {
|
| - return new VSQUERYREMOVEFILEFLAGS[1] { VSQUERYREMOVEFILEFLAGS.VSQUERYREMOVEFILEFLAGS_NoFlags };
|
| - }
|
| -
|
| - VSQUERYREMOVEFILEFLAGS[] queryRemoveFileFlags = new VSQUERYREMOVEFILEFLAGS[files.Length];
|
| -
|
| - for(int i = 0; i < files.Length; i++)
|
| - {
|
| - queryRemoveFileFlags[i] = VSQUERYREMOVEFILEFLAGS.VSQUERYREMOVEFILEFLAGS_IsNestedProjectFile;
|
| - }
|
| -
|
| - return queryRemoveFileFlags;
|
| - }
|
| - #endregion
|
| -
|
| - #region virtual methods
|
| - /// <summary>
|
| - /// Initialize the nested hierarhy node.
|
| - /// </summary>
|
| - /// <param name="fileName">The file name of the nested project.</param>
|
| - /// <param name="destination">The location of the nested project.</param>
|
| - /// <param name="projectName">The name of the project.</param>
|
| - /// <param name="createFlags">The nested project creation flags </param>
|
| - /// <remarks>This methos should be called just after a NestedProjectNode object is created.</remarks>
|
| - public virtual void Init(string fileName, string destination, string projectName, __VSCREATEPROJFLAGS createFlags)
|
| - {
|
| - if(String.IsNullOrEmpty(fileName))
|
| - {
|
| - throw new ArgumentException(SR.GetString(SR.ParameterCannotBeNullOrEmpty, CultureInfo.CurrentUICulture), "fileName");
|
| - }
|
| -
|
| - if(String.IsNullOrEmpty(destination))
|
| - {
|
| - throw new ArgumentException(SR.GetString(SR.ParameterCannotBeNullOrEmpty, CultureInfo.CurrentUICulture), "destination");
|
| - }
|
| -
|
| - this.projectName = Path.GetFileName(fileName);
|
| - this.projectPath = Path.Combine(destination, this.projectName);
|
| -
|
| - // get the IVsSolution interface from the global service provider
|
| - IVsSolution solution = this.GetService(typeof(IVsSolution)) as IVsSolution;
|
| - Debug.Assert(solution != null, "Could not get the IVsSolution object from the services exposed by this project");
|
| - if(solution == null)
|
| - {
|
| - throw new InvalidOperationException();
|
| - }
|
| -
|
| - // Get the project type guid from project element
|
| - string typeGuidString = this.ItemNode.GetMetadataAndThrow(ProjectFileConstants.TypeGuid, new InvalidOperationException());
|
| - Guid projectFactoryGuid = Guid.Empty;
|
| - if(!String.IsNullOrEmpty(typeGuidString))
|
| - {
|
| - projectFactoryGuid = new Guid(typeGuidString);
|
| - }
|
| -
|
| - // Get the project factory.
|
| - IVsProjectFactory projectFactory;
|
| - ErrorHandler.ThrowOnFailure(solution.GetProjectFactory((uint)0, new Guid[] { projectFactoryGuid }, fileName, out projectFactory));
|
| -
|
| - this.CreateProjectDirectory();
|
| -
|
| - //Create new project using factory
|
| - int cancelled;
|
| - Guid refiid = NativeMethods.IID_IUnknown;
|
| - IntPtr projectPtr = IntPtr.Zero;
|
| -
|
| - // For a nested project the creation at unsafe location is governed by the parent project since the nested project will end up in the cone of the parent project.
|
| - bool dontShowAgain = DontShowAgainDialog.ReadDontShowAgainValue(ProjectFactory.DontShowProjectSecurityWarningAgain);
|
| -
|
| - try
|
| - {
|
| - DontShowAgainDialog.WriteDontShowAgainValue(ProjectFactory.DontShowProjectSecurityWarningAgain, 1);
|
| - ErrorHandler.ThrowOnFailure(projectFactory.CreateProject(fileName, destination, projectName, (uint)createFlags, ref refiid, out projectPtr, out cancelled));
|
| -
|
| - if(projectPtr != IntPtr.Zero)
|
| - {
|
| - this.nestedHierarchy = Marshal.GetTypedObjectForIUnknown(projectPtr, typeof(IVsHierarchy)) as IVsHierarchy;
|
| - Debug.Assert(this.nestedHierarchy != null, "Nested hierarchy could not be created");
|
| - Debug.Assert(cancelled == 0);
|
| - }
|
| - }
|
| - finally
|
| - {
|
| - if(projectPtr != IntPtr.Zero)
|
| - {
|
| - // We created a new instance of the project, we need to call release to decrement the ref count
|
| - // the RCW (this.nestedHierarchy) still has a reference to it which will keep it alive
|
| - Marshal.Release(projectPtr);
|
| - }
|
| -
|
| - // Revert back the old value that security questions about unsafe location are stil asked if that was the value.
|
| - if(!dontShowAgain)
|
| - {
|
| - DontShowAgainDialog.WriteDontShowAgainValue(ProjectFactory.DontShowProjectSecurityWarningAgain, 0);
|
| - }
|
| - }
|
| -
|
| - if(cancelled != 0 && this.nestedHierarchy == null)
|
| - {
|
| - ErrorHandler.ThrowOnFailure(VSConstants.OLE_E_PROMPTSAVECANCELLED);
|
| - }
|
| -
|
| - // Link into the nested VS hierarchy.
|
| - ErrorHandler.ThrowOnFailure(this.nestedHierarchy.SetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ParentHierarchy, this.ProjectMgr));
|
| - ErrorHandler.ThrowOnFailure(this.nestedHierarchy.SetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ParentHierarchyItemid, (object)(int)this.ID));
|
| -
|
| - this.LockRDTEntry();
|
| -
|
| - this.ConnectPropertyNotifySink();
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Links a nested project as a virtual project to the solution.
|
| - /// </summary>
|
| - protected internal virtual void AddVirtualProject()
|
| - {
|
| - // This is the second step in creating and adding a nested project. The inner hierarchy must have been
|
| - // already initialized at this point.
|
| - #region precondition
|
| - if(this.nestedHierarchy == null)
|
| - {
|
| - throw new InvalidOperationException();
|
| - }
|
| - #endregion
|
| - // get the IVsSolution interface from the global service provider
|
| - IVsSolution solution = this.GetService(typeof(IVsSolution)) as IVsSolution;
|
| - Debug.Assert(solution != null, "Could not get the IVsSolution object from the services exposed by this project");
|
| - if(solution == null)
|
| - {
|
| - throw new InvalidOperationException();
|
| - }
|
| -
|
| - this.InitializeInstanceGuid();
|
| -
|
| - // Add virtual project to solution.
|
| - ErrorHandler.ThrowOnFailure(solution.AddVirtualProjectEx(this.nestedHierarchy, this.VirtualProjectFlags, ref this.projectInstanceGuid));
|
| -
|
| - // Now set up to listen on file changes on the nested project node.
|
| - this.ObserveNestedProjectFile();
|
| - }
|
| -
|
| - /// <summary>
|
| - /// The method that does the cleanup.
|
| - /// </summary>
|
| - /// <param name="disposing"></param>
|
| - protected override void Dispose(bool disposing)
|
| - {
|
| - // Everybody can go here.
|
| - if(!this.isDisposed)
|
| - {
|
| - try
|
| - {
|
| - // Synchronize calls to the Dispose simulteniously.
|
| - lock(Mutex)
|
| - {
|
| - if(disposing)
|
| - {
|
| - this.DisconnectPropertyNotifySink();
|
| - this.StopObservingNestedProjectFile();
|
| - this.imageHandler.Close();
|
| - }
|
| - }
|
| - }
|
| - finally
|
| - {
|
| - base.Dispose(disposing);
|
| - this.isDisposed = true;
|
| - }
|
| - }
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Creates the project directory if it does not exist.
|
| - /// </summary>
|
| - /// <returns></returns>
|
| - protected virtual void CreateProjectDirectory()
|
| - {
|
| - string directoryName = Path.GetDirectoryName(this.projectPath);
|
| -
|
| - if(!Directory.Exists(directoryName))
|
| - {
|
| - Directory.CreateDirectory(directoryName);
|
| - }
|
| - }
|
| -
|
| -
|
| - /// <summary>
|
| - /// Lock the RDT Entry for the nested project.
|
| - /// By default this document is marked as "Dont Save as". That means the menu File->SaveAs is disabled for the
|
| - /// nested project node.
|
| - /// </summary>
|
| - [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "RDT")]
|
| - protected virtual void LockRDTEntry()
|
| - {
|
| - // Define flags for the nested project document
|
| - _VSRDTFLAGS flags = _VSRDTFLAGS.RDT_VirtualDocument | _VSRDTFLAGS.RDT_ProjSlnDocument; ;
|
| -
|
| - // Request the RDT service
|
| - IVsRunningDocumentTable rdt = this.GetService(typeof(SVsRunningDocumentTable)) as IVsRunningDocumentTable;
|
| - Debug.Assert(rdt != null, " Could not get running document table from the services exposed by this project");
|
| - if(rdt == null)
|
| - {
|
| - throw new InvalidOperationException();
|
| - }
|
| -
|
| - // First we see if someone else has opened the requested view of the file.
|
| - uint itemid;
|
| - IntPtr docData = IntPtr.Zero;
|
| - IVsHierarchy ivsHierarchy;
|
| - uint docCookie;
|
| - IntPtr projectPtr = IntPtr.Zero;
|
| -
|
| - try
|
| - {
|
| - ErrorHandler.ThrowOnFailure(rdt.FindAndLockDocument((uint)flags, this.projectPath, out ivsHierarchy, out itemid, out docData, out docCookie));
|
| - flags |= _VSRDTFLAGS.RDT_EditLock;
|
| -
|
| - if(ivsHierarchy != null && docCookie != (uint)ShellConstants.VSDOCCOOKIE_NIL)
|
| - {
|
| - if(docCookie != this.DocCookie)
|
| - {
|
| - this.DocCookie = docCookie;
|
| - }
|
| - }
|
| - else
|
| - {
|
| -
|
| - // get inptr for hierarchy
|
| - projectPtr = Marshal.GetIUnknownForObject(this.nestedHierarchy);
|
| - Debug.Assert(projectPtr != IntPtr.Zero, " Project pointer for the nested hierarchy has not been initialized");
|
| - ErrorHandler.ThrowOnFailure(rdt.RegisterAndLockDocument((uint)flags, this.projectPath, this.ProjectMgr, this.ID, projectPtr, out docCookie));
|
| -
|
| - this.DocCookie = docCookie;
|
| - Debug.Assert(this.DocCookie != (uint)ShellConstants.VSDOCCOOKIE_NIL, "Invalid cookie when registering document in the running document table.");
|
| -
|
| - //we must also set the doc cookie on the nested hier
|
| - this.SetDocCookieOnNestedHier(this.DocCookie);
|
| - }
|
| - }
|
| - finally
|
| - {
|
| - // Release all Inptr's that that were given as out pointers
|
| - if(docData != IntPtr.Zero)
|
| - {
|
| - Marshal.Release(docData);
|
| - }
|
| - if(projectPtr != IntPtr.Zero)
|
| - {
|
| - Marshal.Release(projectPtr);
|
| - }
|
| - }
|
| -
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Unlock the RDT entry for the nested project
|
| - /// </summary>
|
| - [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "RDT")]
|
| - protected virtual void UnlockRDTEntry()
|
| - {
|
| - if(this.isDisposed || this.ProjectMgr == null || this.ProjectMgr.IsClosed)
|
| - {
|
| - return;
|
| - }
|
| - // First we see if someone else has opened the requested view of the file.
|
| - IVsRunningDocumentTable rdt = this.GetService(typeof(SVsRunningDocumentTable)) as IVsRunningDocumentTable;
|
| - if(rdt != null && this.DocCookie != (int)ShellConstants.VSDOCCOOKIE_NIL)
|
| - {
|
| - _VSRDTFLAGS flags = _VSRDTFLAGS.RDT_EditLock;
|
| -
|
| - ErrorHandler.ThrowOnFailure(rdt.UnlockDocument((uint)flags, (uint)this.DocCookie));
|
| - }
|
| -
|
| - this.DocCookie = (int)ShellConstants.VSDOCCOOKIE_NIL;
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Renames the project file in the parent project structure.
|
| - /// </summary>
|
| - /// <param name="label">The new label.</param>
|
| - protected virtual void RenameNestedProjectInParentProject(string label)
|
| - {
|
| - string existingLabel = this.Caption;
|
| -
|
| - if(String.Compare(existingLabel, label, StringComparison.Ordinal) == 0)
|
| - {
|
| - return;
|
| - }
|
| -
|
| - string oldFileName = this.projectPath;
|
| - string oldPath = this.Url;
|
| -
|
| - try
|
| - {
|
| - this.StopObservingNestedProjectFile();
|
| - this.ProjectMgr.SuspendMSBuild();
|
| -
|
| - // Check out the project file if necessary.
|
| - if(!this.ProjectMgr.QueryEditProjectFile(false))
|
| - {
|
| - throw Marshal.GetExceptionForHR(VSConstants.OLE_E_PROMPTSAVECANCELLED);
|
| - }
|
| -
|
| -
|
| - string newFileName = label + Path.GetExtension(oldFileName);
|
| - this.SaveNestedProjectItemInProjectFile(newFileName);
|
| -
|
| - string projectDirectory = Path.GetDirectoryName(oldFileName);
|
| -
|
| - // update state.
|
| - this.projectName = newFileName;
|
| - this.projectPath = Path.Combine(projectDirectory, this.projectName);
|
| -
|
| - // Unload and lock the RDT entries
|
| - this.UnlockRDTEntry();
|
| - this.LockRDTEntry();
|
| -
|
| - // Since actually this is a rename in our hierarchy notify the tracker that a rename has happened.
|
| - this.ProjectMgr.Tracker.OnItemRenamed(oldPath, this.projectPath, VSRENAMEFILEFLAGS.VSRENAMEFILEFLAGS_IsNestedProjectFile);
|
| - }
|
| - finally
|
| - {
|
| - this.ObserveNestedProjectFile();
|
| - this.ProjectMgr.ResumeMSBuild(this.ProjectMgr.ReEvaluateProjectFileTargetName);
|
| - }
|
| - }
|
| - /// <summary>
|
| - /// Saves the nested project information in the project file.
|
| - /// </summary>
|
| - /// <param name="newFileName"></param>
|
| - protected virtual void SaveNestedProjectItemInProjectFile(string newFileName)
|
| - {
|
| - string existingInclude = this.ItemNode.Item.Include;
|
| - string existingRelativePath = Path.GetDirectoryName(existingInclude);
|
| - string newRelativePath = Path.Combine(existingRelativePath, newFileName);
|
| - this.ItemNode.Rename(newRelativePath);
|
| - }
|
| - #endregion
|
| -
|
| - #region helper methods
|
| - /// <summary>
|
| - /// Closes a nested project and releases the nested hierrachy pointer.
|
| - /// </summary>
|
| - internal void CloseNestedProjectNode()
|
| - {
|
| - if(this.isDisposed || this.ProjectMgr == null || this.ProjectMgr.IsClosed)
|
| - {
|
| - return;
|
| - }
|
| -
|
| - uint itemid = VSConstants.VSITEMID_NIL;
|
| - try
|
| - {
|
| - this.DisconnectPropertyNotifySink();
|
| -
|
| - IVsUIHierarchy hier;
|
| -
|
| - IVsWindowFrame windowFrame;
|
| - VsShellUtilities.IsDocumentOpen(this.ProjectMgr.Site, this.projectPath, Guid.Empty, out hier, out itemid, out windowFrame);
|
| -
|
| -
|
| - if(itemid == VSConstants.VSITEMID_NIL)
|
| - {
|
| - this.UnlockRDTEntry();
|
| - }
|
| -
|
| - IVsSolution solution = this.GetService(typeof(IVsSolution)) as IVsSolution;
|
| - if(solution == null)
|
| - {
|
| - throw new InvalidOperationException();
|
| - }
|
| -
|
| - ErrorHandler.ThrowOnFailure(solution.RemoveVirtualProject(this.nestedHierarchy, 0));
|
| -
|
| - }
|
| - finally
|
| - {
|
| - this.StopObservingNestedProjectFile();
|
| -
|
| - // if we haven't already release the RDT cookie, do so now.
|
| - if(itemid == VSConstants.VSITEMID_NIL)
|
| - {
|
| - this.UnlockRDTEntry();
|
| - }
|
| -
|
| - this.Dispose(true);
|
| - }
|
| - }
|
| -
|
| - private void InitializeInstanceGuid()
|
| - {
|
| - if(this.projectInstanceGuid != Guid.Empty)
|
| - {
|
| - return;
|
| - }
|
| -
|
| - Guid instanceGuid = Guid.Empty;
|
| -
|
| - Debug.Assert(this.nestedHierarchy != null, "The nested hierarchy object must be created before calling this method");
|
| -
|
| - // This method should be called from the open children method, then we can safely use the IsNewProject property
|
| - if(this.ProjectMgr.IsNewProject)
|
| - {
|
| - instanceGuid = Guid.NewGuid();
|
| - this.ItemNode.SetMetadata(ProjectFileConstants.InstanceGuid, instanceGuid.ToString("B"));
|
| - ErrorHandler.ThrowOnFailure(this.nestedHierarchy.SetGuidProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ProjectIDGuid, ref instanceGuid));
|
| - }
|
| - else
|
| - {
|
| - // Get a guid from the nested hiererachy.
|
| - Guid nestedHiererachyInstanceGuid;
|
| - ErrorHandler.ThrowOnFailure(this.nestedHierarchy.GetGuidProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ProjectIDGuid, out nestedHiererachyInstanceGuid));
|
| -
|
| - // Get instance guid from the project file. If it does not exist then we create one.
|
| - string instanceGuidAsString = this.ItemNode.GetMetadata(ProjectFileConstants.InstanceGuid);
|
| -
|
| - // 1. nestedHiererachyInstanceGuid is empty and instanceGuidAsString is empty then create a new one.
|
| - // 2. nestedHiererachyInstanceGuid is empty and instanceGuidAsString not empty use instanceGuidAsString and update the nested project object by calling SetGuidProperty.
|
| - // 3. nestedHiererachyInstanceGuid is not empty instanceGuidAsString is empty then use nestedHiererachyInstanceGuid and update the outer project element.
|
| - // 4. nestedHiererachyInstanceGuid is not empty instanceGuidAsString is empty then use nestedHiererachyInstanceGuid and update the outer project element.
|
| -
|
| - if(nestedHiererachyInstanceGuid == Guid.Empty && String.IsNullOrEmpty(instanceGuidAsString))
|
| - {
|
| - instanceGuid = Guid.NewGuid();
|
| - }
|
| - else if(nestedHiererachyInstanceGuid == Guid.Empty && !String.IsNullOrEmpty(instanceGuidAsString))
|
| - {
|
| - instanceGuid = new Guid(instanceGuidAsString);
|
| -
|
| - ErrorHandler.ThrowOnFailure(this.nestedHierarchy.SetGuidProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ProjectIDGuid, ref instanceGuid));
|
| - }
|
| - else if(nestedHiererachyInstanceGuid != Guid.Empty)
|
| - {
|
| - instanceGuid = nestedHiererachyInstanceGuid;
|
| -
|
| - // If the instanceGuidAsString is empty then creating a guid out of it would throw an exception.
|
| - if(String.IsNullOrEmpty(instanceGuidAsString) || nestedHiererachyInstanceGuid != new Guid(instanceGuidAsString))
|
| - {
|
| - this.ItemNode.SetMetadata(ProjectFileConstants.InstanceGuid, instanceGuid.ToString("B"));
|
| - }
|
| - }
|
| - }
|
| -
|
| - this.projectInstanceGuid = instanceGuid;
|
| - }
|
| -
|
| - private void SetDocCookieOnNestedHier(uint itemDocCookie)
|
| - {
|
| - object docCookie = (int)itemDocCookie;
|
| -
|
| - try
|
| - {
|
| - ErrorHandler.ThrowOnFailure(this.nestedHierarchy.SetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ItemDocCookie, docCookie));
|
| - }
|
| - catch(NotImplementedException)
|
| - {
|
| - //we swallow this exception on purpose
|
| - }
|
| - }
|
| -
|
| - private void InitImageHandler()
|
| - {
|
| - Debug.Assert(this.nestedHierarchy != null, "The nested hierarchy object must be created before calling this method");
|
| -
|
| - if(null == imageHandler)
|
| - {
|
| - imageHandler = new ImageHandler();
|
| - }
|
| - object imageListAsPointer = null;
|
| - ErrorHandler.ThrowOnFailure(this.nestedHierarchy.GetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_IconImgList, out imageListAsPointer));
|
| - if(imageListAsPointer != null)
|
| - {
|
| - this.imageHandler.ImageList = Utilities.GetImageList(imageListAsPointer);
|
| - }
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Delegates Getproperty calls to the inner nested.
|
| - /// </summary>
|
| - /// <param name="propID">The property to delegate.</param>
|
| - /// <returns>The return of the GetProperty from nested.</returns>
|
| - private object DelegateGetPropertyToNested(int propID)
|
| - {
|
| - object returnValue = null;
|
| - if(!this.ProjectMgr.IsClosed)
|
| - {
|
| - Debug.Assert(this.nestedHierarchy != null, "The nested hierarchy object must be created before calling this method");
|
| -
|
| - // Do not throw since some project types will return E_FAIL if they do not support a property.
|
| - ErrorHandler.ThrowOnFailure(this.nestedHierarchy.GetProperty(VSConstants.VSITEMID_ROOT, propID, out returnValue));
|
| - }
|
| - return returnValue;
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Delegates Setproperty calls to the inner nested.
|
| - /// </summary>
|
| - /// <param name="propID">The property to delegate.</param>
|
| - /// <param name="value">The property to set.</param>
|
| - /// <returns>The return of the SetProperty from nested.</returns>
|
| - private int DelegateSetPropertyToNested(int propID, object value)
|
| - {
|
| - if(this.ProjectMgr.IsClosed)
|
| - {
|
| - return VSConstants.E_FAIL;
|
| - }
|
| -
|
| - Debug.Assert(this.nestedHierarchy != null, "The nested hierarchy object must be created before calling this method");
|
| -
|
| - // Do not throw since some project types will return E_FAIL if they do not support a property.
|
| - return this.nestedHierarchy.SetProperty(VSConstants.VSITEMID_ROOT, propID, value);
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Starts observing changes on this file.
|
| - /// </summary>
|
| - private void ObserveNestedProjectFile()
|
| - {
|
| - ProjectContainerNode parent = this.ProjectMgr as ProjectContainerNode;
|
| - Debug.Assert(parent != null, "The parent project for nested projects should be subclassed from ProjectContainerNode");
|
| - parent.NestedProjectNodeReloader.ObserveItem(this.GetMkDocument(), this.ID);
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Stops observing changes on this file.
|
| - /// </summary>
|
| - private void StopObservingNestedProjectFile()
|
| - {
|
| - ProjectContainerNode parent = this.ProjectMgr as ProjectContainerNode;
|
| - Debug.Assert(parent != null, "The parent project for nested projects should be subclassed from ProjectContainerNode");
|
| - parent.NestedProjectNodeReloader.StopObservingItem(this.GetMkDocument());
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Ignores observing changes on this file depending on the boolean flag.
|
| - /// </summary>
|
| - /// <param name="ignoreFlag">Flag indicating whether or not to ignore changes (1 to ignore, 0 to stop ignoring).</param>
|
| - private void IgnoreNestedProjectFile(bool ignoreFlag)
|
| - {
|
| - ProjectContainerNode parent = this.ProjectMgr as ProjectContainerNode;
|
| - Debug.Assert(parent != null, "The parent project for nested projects should be subclassed from ProjectContainerNode");
|
| - parent.NestedProjectNodeReloader.IgnoreItemChanges(this.GetMkDocument(), ignoreFlag);
|
| - }
|
| -
|
| - /// <summary>
|
| - /// We need to advise property notify sink on project properties so that
|
| - /// we know when the project file is renamed through a property.
|
| - /// </summary>
|
| - private void ConnectPropertyNotifySink()
|
| - {
|
| - if(this.projectPropertyNotifySinkCookie != (uint)ShellConstants.VSCOOKIE_NIL)
|
| - {
|
| - return;
|
| - }
|
| -
|
| - IConnectionPoint connectionPoint = this.GetConnectionPointFromPropertySink();
|
| - if(connectionPoint != null)
|
| - {
|
| - connectionPoint.Advise(this, out this.projectPropertyNotifySinkCookie);
|
| - }
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Disconnects the propertynotify sink
|
| - /// </summary>
|
| - private void DisconnectPropertyNotifySink()
|
| - {
|
| - if(this.projectPropertyNotifySinkCookie == (uint)ShellConstants.VSCOOKIE_NIL)
|
| - {
|
| - return;
|
| - }
|
| -
|
| - IConnectionPoint connectionPoint = this.GetConnectionPointFromPropertySink();
|
| - if(connectionPoint != null)
|
| - {
|
| - connectionPoint.Unadvise(this.projectPropertyNotifySinkCookie);
|
| - this.projectPropertyNotifySinkCookie = (uint)ShellConstants.VSCOOKIE_NIL;
|
| - }
|
| - }
|
| -
|
| - /// <summary>
|
| - /// Gets a ConnectionPoint for the IPropertyNotifySink interface.
|
| - /// </summary>
|
| - /// <returns></returns>
|
| - private IConnectionPoint GetConnectionPointFromPropertySink()
|
| - {
|
| - IConnectionPoint connectionPoint = null;
|
| - object browseObject = this.GetProperty((int)__VSHPROPID.VSHPROPID_BrowseObject);
|
| - IConnectionPointContainer connectionPointContainer = browseObject as IConnectionPointContainer;
|
| -
|
| - if(connectionPointContainer != null)
|
| - {
|
| - Guid guid = typeof(IPropertyNotifySink).GUID;
|
| - connectionPointContainer.FindConnectionPoint(ref guid, out connectionPoint);
|
| - }
|
| -
|
| - return connectionPoint;
|
| - }
|
| - #endregion
|
| - }
|
| -}
|
|
|