예제 #1
0
        private static bool IsNodeNonMemberItem(HierarchyNode node, object criteria)
        {
            bool isNonMemberItem = false;
            if (node != null)
            {
                object propObj = node.GetProperty((int) __VSHPROPID.VSHPROPID_IsNonMemberItem);
                if (propObj != null)
                {
                    Boolean.TryParse(propObj.ToString(), out isNonMemberItem);
                }
            }

            return isNonMemberItem;
        }
        /// <summary>
        /// Process dataobject from Drag/Drop/Cut/Copy/Paste operation
        /// </summary>
        /// <remarks>The targetNode is set if the method is called from a drop operation, otherwise it is null</remarks>
        internal DropDataType ProcessSelectionDataObject(IOleDataObject dataObject, HierarchyNode targetNode)
        {
            DropDataType dropDataType = DropDataType.None;
            bool isWindowsFormat = false;

            // Try to get it as a directory based project.
            List<string> filesDropped = DragDropHelper.GetDroppedFiles(DragDropHelper.CF_VSSTGPROJECTITEMS, dataObject, out dropDataType);
            if (filesDropped.Count == 0)
            {
                filesDropped = DragDropHelper.GetDroppedFiles(DragDropHelper.CF_VSREFPROJECTITEMS, dataObject, out dropDataType);
            }
            if (filesDropped.Count == 0)
            {
                filesDropped = DragDropHelper.GetDroppedFiles(NativeMethods.CF_HDROP, dataObject, out dropDataType);
                isWindowsFormat = (filesDropped.Count > 0);
            }

            if (dropDataType != DropDataType.None && filesDropped.Count > 0)
            {
                string[] filesDroppedAsArray = filesDropped.ToArray();

                HierarchyNode node = (targetNode == null) ? this : targetNode;

                // For directory based projects the content of the clipboard is a double-NULL terminated list of Projref strings.
                if (isWindowsFormat)
                {
                    // This is the code path when source is windows explorer
                    VSADDRESULT[] vsaddresults = new VSADDRESULT[1];
                    vsaddresults[0] = VSADDRESULT.ADDRESULT_Failure;
                    int addResult = AddItem(node.ID, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, null, (uint)filesDropped.Count, filesDroppedAsArray, IntPtr.Zero, vsaddresults);
                    if (addResult != VSConstants.S_OK && addResult != VSConstants.S_FALSE && addResult != (int)OleConstants.OLECMDERR_E_CANCELED
                        && vsaddresults[0] != VSADDRESULT.ADDRESULT_Success)
                    {
                        ErrorHandler.ThrowOnFailure(addResult);
                    }

                    return dropDataType;
                }
                else
                {
                    if (AddFilesFromProjectReferences(node, filesDroppedAsArray))
                    {
                        return dropDataType;
                    }
                }
            }

            // If we reached this point then the drop data must be set to None.
            // Otherwise the OnPaste will be called with a valid DropData and that would actually delete the item.
            return DropDataType.None;
        }
예제 #3
0
 public NodeProperties(HierarchyNode node)
 {
     if (node == null)
     {
         throw new ArgumentNullException("node");
     }
     this.node = node;
 }
예제 #4
0
 public FolderNodeProperties(HierarchyNode node)
     : base(node)
 {
 }
예제 #5
0
 public SingleFileGeneratorNodeProperties(HierarchyNode node)
     : base(node)
 {
 }
        /// <summary>
        /// Process dataobject from Drag/Drop/Cut/Copy/Paste operation
        /// </summary>
        /// <remarks>The targetNode is set if the method is called from a drop operation, otherwise it is null</remarks>
        internal DropDataType ProcessSelectionDataObject(IOleDataObject dataObject, HierarchyNode targetNode, uint grfKeyState)
        {
            DropDataType dropDataType = DropDataType.None;
            bool isWindowsFormat = false;

            // Try to get it as a directory based project.
            List<string> filesDropped = DragDropHelper.GetDroppedFiles(DragDropHelper.CF_VSSTGPROJECTITEMS, dataObject, out dropDataType);
            if (filesDropped.Count == 0)
            {
                filesDropped = DragDropHelper.GetDroppedFiles(DragDropHelper.CF_VSREFPROJECTITEMS, dataObject, out dropDataType);
            }
            if (filesDropped.Count == 0)
            {
                filesDropped = DragDropHelper.GetDroppedFiles(NativeMethods.CF_HDROP, dataObject, out dropDataType);
                isWindowsFormat = (filesDropped.Count > 0);
            }

            dropItems.Clear();

            if (dropDataType != DropDataType.None && filesDropped.Count > 0)
            {
                bool saveAllowDuplicateLinks = this.AllowDuplicateLinks;
                try
                {
                    DropEffect dropEffect = this.QueryDropEffect(dropDataType, grfKeyState);
                    this.dropAsCopy = dropEffect == DropEffect.Copy;
                    if (dropEffect == DropEffect.Move && this.SourceDraggedOrCutOrCopied)
                    {
                        // Temporarily allow duplicate links to enable cut-paste or drag-move of links within the project.
                        // This won't happen when the source is another project because this.SourceDraggedOrCutOrCopied won't get set.
                        this.AllowDuplicateLinks = true;
                    }

                    string[] filesDroppedAsArray = filesDropped.ToArray();

                    HierarchyNode node = (targetNode == null) ? this : targetNode;

                    // For directory based projects the content of the clipboard is a double-NULL terminated list of Projref strings.
                    if (isWindowsFormat)
                    {
                        // This is the code path when source is windows explorer
                        VSADDRESULT[] vsaddresults = new VSADDRESULT[1];
                        vsaddresults[0] = VSADDRESULT.ADDRESULT_Failure;
                        int addResult = AddItem(node.ID, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, null, (uint)filesDropped.Count, filesDroppedAsArray, IntPtr.Zero, vsaddresults);
                        if (addResult != VSConstants.S_OK && addResult != VSConstants.S_FALSE && addResult != (int)OleConstants.OLECMDERR_E_CANCELED
                            && vsaddresults[0] != VSADDRESULT.ADDRESULT_Success)
                        {
                            ErrorHandler.ThrowOnFailure(addResult);
                        }

                        return dropDataType;
                    }
                    else
                    {
                        if (AddFilesFromProjectReferences(node, filesDroppedAsArray, (uint)dropEffect))
                        {
                            return dropDataType;
                        }
                    }
                }
                finally
                {
                    this.AllowDuplicateLinks = saveAllowDuplicateLinks;
                }
            }

            this.dataWasCut = false;

            // If we reached this point then the drop data must be set to None.
            // Otherwise the OnPaste will be called with a valid DropData and that would actually delete the item.
            return DropDataType.None;
        }
 /// <summary>
 /// Handle the Paste operation to a targetNode
 /// </summary>
 protected internal override int PasteFromClipboard(HierarchyNode targetNode)
 {
     int returnValue;
     try
     {
         this.isInPasteOrDrop = true;
         this.dropAsCopy = !this.dataWasCut;
         returnValue = PasteFromClipboardCore(targetNode);
     }
     finally
     {
         this.isInPasteOrDrop = false;
         this.dropAsCopy = false;
         this.pasteAsNonMemberItem = false;
     }
     return returnValue;
 }
        /// <summary>
        /// Recursive method that walk a hierarchy and add items it find to our project.
        /// Note that this is meant as an helper to the Copy&Paste/Drag&Drop functionality.
        /// </summary>
        /// <param name="sourceHierarchy">Hierarchy to walk</param>
        /// <param name="itemId">Item ID where to start walking the hierarchy</param>
        /// <param name="targetNode">Node to start adding to</param>
        /// <param name="name">Folder name to use</param>
        /// <param name="addSiblings">Typically false on first call and true after that</param>
        /// <remarks>Use this method when the folder name to add items to is not
        /// the same as the source.</remarks>
        protected virtual void WalkSourceProjectAndAdd(IVsHierarchy sourceHierarchy, uint itemId, HierarchyNode targetNode, string name, bool addSiblings)
        {
            // Before we start the walk, add the current node
            object variant = null;
            HierarchyNode newNode = targetNode;
            if (itemId != VSConstants.VSITEMID_NIL)
            {
                // Calculate the corresponding path in our project
                string targetPath = Path.Combine(GetBaseDirectoryForAddingFiles(targetNode), name);

                // See if this is a linked item (file can be linked, not folders)
                VSADDITEMOPERATION addItemOp = VSADDITEMOPERATION.VSADDITEMOP_OPENFILE;
                ErrorHandler.ThrowOnFailure(sourceHierarchy.GetProperty(itemId, (int)__VSHPROPID.VSHPROPID_BrowseObject, out variant), VSConstants.E_NOTIMPL);
                VSLangProj.FileProperties fileProperties = variant as VSLangProj.FileProperties;
                if (fileProperties != null && fileProperties.IsLink)
                {
                    addItemOp = VSADDITEMOPERATION.VSADDITEMOP_LINKTOFILE;
                    targetPath = fileProperties.FullPath;
                }

                ErrorHandler.ThrowOnFailure(sourceHierarchy.GetProperty(itemId, (int)__VSHPROPID.VSHPROPID_IsNonMemberItem, out variant), VSConstants.E_NOTIMPL);
                bool oldPasteAsNonMemberItem = this.PasteAsNonMemberItem;
                try
                {
                    this.pasteAsNonMemberItem = variant != null && (bool)variant;
                    newNode = AddNodeIfTargetExistInStorage(targetNode, name, targetPath, addItemOp);
                }
                finally
                {
                    this.pasteAsNonMemberItem = oldPasteAsNonMemberItem;
                }

                // Start with child nodes (depth first)
                variant = null;
                ErrorHandler.ThrowOnFailure(sourceHierarchy.GetProperty(itemId, (int)__VSHPROPID.VSHPROPID_FirstVisibleChild, out variant));

                uint currentItemID;
                if (variant is int)
                {
                    currentItemID = (uint)System.BitConverter.ToUInt32(System.BitConverter.GetBytes((int)variant), 0);
                }
                else
                {
                    currentItemID = (uint)variant;
                }
                WalkSourceProjectAndAdd(sourceHierarchy, currentItemID, newNode, true);

                if (addSiblings)
                {
                    // Then look at siblings
                    currentItemID = itemId;
                    while (currentItemID != VSConstants.VSITEMID_NIL)
                    {
                        variant = null;
                        ErrorHandler.ThrowOnFailure(sourceHierarchy.GetProperty(currentItemID, (int)__VSHPROPID.VSHPROPID_NextVisibleSibling, out variant));
                        if (variant is int)
                        {
                            currentItemID = (uint)System.BitConverter.ToUInt32(System.BitConverter.GetBytes((int)variant), 0);
                        }
                        else
                        {
                            currentItemID = (uint)variant;
                        }
                        WalkSourceProjectAndAdd(sourceHierarchy, currentItemID, targetNode, false);
                    }
                }
            }
        }
예제 #9
0
 /// <include file='doc\Hierarchy.uex' path='docs/doc[@for="HierarchyNode.OnItemsAppended"]/*' />
 public void OnItemsAppended(HierarchyNode parent){
     HierarchyNode foo;
     foo = this.projectMgr == null ? this : this.projectMgr;
     try{
         foreach (IVsHierarchyEvents sink in foo.hierarchyEventSinks){
             sink.OnItemsAppended(parent.hierarchyId);
         }
     } catch{
     }
 }
예제 #10
0
 /// <include file='doc\Hierarchy.uex' path='docs/doc[@for="HierarchyNode.OnItemAdded"]/*' />
 public void OnItemAdded(HierarchyNode parent, HierarchyNode child){
     HierarchyNode foo;
     foo = this.projectMgr == null ? this : this.projectMgr;
     HierarchyNode prev = child.PreviousSibling;
     uint prevId = (prev != null) ? prev.hierarchyId : VsConstants.VSITEMID_NIL;
     try{
         foreach (IVsHierarchyEvents sink in foo.hierarchyEventSinks){
             sink.OnItemAdded(parent.hierarchyId, prevId, child.hierarchyId);
         }
     } catch{
     }
 }
예제 #11
0
        /// <include file='doc\Hierarchy.uex' path='docs/doc[@for="HierarchyNode.AddNewFolder"]/*' />
        /// <summary>
        /// Get's called to a add a new Folder to the project hierarchy. Opens the dialog to do so and
        /// creates the physical representation
        /// </summary>
        /// <returns></returns>
        public int AddNewFolder(){
            // first generate a new folder name...
            try{
                string relFolder;
                object dummy = null;
                IVsProject3 project = (IVsProject3)this.projectMgr;
                IVsUIHierarchyWindow uiWindow = this.projectMgr.GetIVsUIHierarchyWindow(VsConstants.Guid_SolutionExplorer);

                project.GenerateUniqueItemName(this.hierarchyId, "", "", out relFolder);

                if (this != this.projectMgr){
                    // add this guys relpath to it...
                    relFolder = this.xmlNode.GetAttribute("RelPath") + relFolder;
                }
                // create the project part of it, the xml in the xsproj file
                XmlElement e = this.projectMgr.AddFolderNodeToProject(relFolder);
                HierarchyNode child = new HierarchyNode(this.projectMgr, HierarchyNodeType.Folder, e);
                this.AddChild(child);

                child.CreateDirectory();
                // we need to get into label edit mode now...
                // so first select the new guy...
                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...
                this.projectMgr.UIShell.PostExecCommand(ref VsConstants.guidStandardCommandSet97, (uint)VsCommands.Rename, 0, ref dummy);
            } catch{
            }

            return 0;
        }
예제 #12
0
        /// <include file='doc\Hierarchy.uex' path='docs/doc[@for="HierarchyNode.RemoveChild"]/*' />
        public virtual void RemoveChild(HierarchyNode 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");
        }
예제 #13
0
 public void Set(HierarchyNode node) {
   selection.Clear();
   selection.Add(new NodeProperties(node));
 }
예제 #14
0
 public void Add(HierarchyNode node) {
   selection.Add(new NodeProperties(node));
 }
예제 #15
0
 public SelectionContainer(HierarchyNode node) {
   selection = new ArrayList();
   selection.Add(new NodeProperties(node));
 }
        /// <summary>
        /// This is used to recursively add a folder from an other project.
        /// Note that while we copy the folder content completely, we only
        /// add to the project items which are part of the source project.
        /// </summary>
        /// <param name="folderToAdd">Project reference (from data object) using the format: {Guid}|project|folderPath</param>
        /// <param name="targetNode">Node to add the new folder to</param>
        /// <param name="dropEffect">The drop effect</param>
        /// <param name="validateOnly">If true, no action is actually taken. Only checks for error cases.</param>
        protected internal virtual void AddFolderFromOtherProject(string folderToAdd, HierarchyNode targetNode, uint dropEffect, bool validateOnly)
        {
            if (String.IsNullOrEmpty(folderToAdd))
                throw new ArgumentNullException("folderToAdd");
            if (targetNode == null)
                throw new ArgumentNullException("targetNode");

            // get the source path
            Guid projectInstanceGuid;
            string folder = GetSourceFromFolderReference(folderToAdd, out projectInstanceGuid);
            string folderNoTrailingSlash = folder.Substring(0, folder.Length - 1);

            // Get the target path
            string folderName = Path.GetFileName(Path.GetDirectoryName(folder));
            string newFolderBaseDir = GetBaseDirectoryForAddingFiles(targetNode);
            string targetPath = Path.Combine(newFolderBaseDir, folderName);

            bool bPathsSame = NativeMethods.IsSamePath(folderNoTrailingSlash, targetPath);

            if (!bPathsSame && targetPath.StartsWith(folder, StringComparison.Ordinal))
            {
                throw new DestionPathSubfolderOfSourceException(folderName);
            }

            // If these paths are the same, allow it and prepend "Copy of" only
            // if it was copied to clipboard or dragged with copy effect
            if (bPathsSame && (!this.SourceDragged && !this.dataWasCut) || (this.SourceDragged && dropEffect == (uint)DropEffect.Copy))
            {
                // When validating, do not find a free directory
                // Validation is finished at this point.
                if (validateOnly)
                    return;

                int copyNumber = 0;
                string originalFolderName = folderName;
                while (Directory.Exists(targetPath))
                {
                    copyNumber++;
                    if (copyNumber == 1)
                    {
                        folderName = SR.GetString(SR.CopyOfFile, originalFolderName);
                    }
                    else
                    {
                        folderName = SR.GetString(SR.CopyNOfFile, copyNumber, originalFolderName);
                    }
                    targetPath = Path.Combine(newFolderBaseDir, folderName);
                }
            }

            // Do not perform copy if paths are still the same.
            if (NativeMethods.IsSamePath(folderNoTrailingSlash, targetPath))
            {
                throw new DestionPathSameAsSourceException(folderName);
            }

            if (Directory.Exists(targetPath))
            {
                throw new DestinationFolderAlreadyExists(folderName);
            }

            if (validateOnly)
                return;

            // Recursively copy the directory to the new location
            Utilities.RecursivelyCopyDirectory(folder, targetPath);

            // Retrieve the project from which the items are being copied
            IVsHierarchy sourceHierarchy;
            IVsSolution solution = (IVsSolution)GetService(typeof(SVsSolution));
            ErrorHandler.ThrowOnFailure(solution.GetProjectOfGuid(ref projectInstanceGuid, out sourceHierarchy));

            // Then retrieve the item ID of the item to copy
            uint itemID = VSConstants.VSITEMID_ROOT;
            ErrorHandler.ThrowOnFailure(sourceHierarchy.ParseCanonicalName(folder, out itemID));

            // Ensure we don't end up in an endless recursion
            if (Utilities.IsSameComObject(this, sourceHierarchy))
            {
                HierarchyNode cursorNode = targetNode;
                while (cursorNode != null)
                {
                    if (String.Compare(folder, cursorNode.GetMkDocument(), StringComparison.OrdinalIgnoreCase) == 0)
                        throw new ApplicationException();
                    cursorNode = cursorNode.Parent;
                }
            }

            // Now walk the source project hierarchy to see which node needs to be added.
            WalkSourceProjectAndAdd(sourceHierarchy, itemID, targetNode, folderName, false);
        }
        /// <summary>
        /// Recursive method that walk a hierarchy and add items it find to our project.
        /// Note that this is meant as an helper to the Copy&Paste/Drag&Drop functionality.
        /// </summary>
        /// <param name="sourceHierarchy">Hierarchy to walk</param>
        /// <param name="itemId">Item ID where to start walking the hierarchy</param>
        /// <param name="targetNode">Node to start adding to</param>
        /// <param name="addSiblings">Typically false on first call and true after that</param>
        protected virtual void WalkSourceProjectAndAdd(IVsHierarchy sourceHierarchy, uint itemId, HierarchyNode targetNode, bool addSiblings)
        {
            // Before we start the walk, add the current node
            if (itemId != VSConstants.VSITEMID_NIL)
            {
                string source;
                ErrorHandler.ThrowOnFailure(((IVsProject)sourceHierarchy).GetMkDocument(itemId, out source));
                string name = Path.GetFileName(source.TrimEnd(new char[] { '/', '\\' }));

                WalkSourceProjectAndAdd(sourceHierarchy, itemId, targetNode, name, addSiblings);
            }
        }
예제 #18
0
 /// <include file='doc\Hierarchy.uex' path='docs/doc[@for="HierarchyNode.OnPropertyChanged"]/*' />
 public void OnPropertyChanged(HierarchyNode node, int propid, uint flags){
     HierarchyNode foo;
     foo = this.projectMgr == null ? this : this.projectMgr;
     foreach (IVsHierarchyEvents sink in foo.hierarchyEventSinks){
         sink.OnPropertyChanged(node.hierarchyId, propid, flags);
     }
 }
 /// <summary>
 /// Add an existing item (file/folder) to the project if it already exist in our storage.
 /// </summary>
 /// <param name="parentNode">Node to that this item to</param>
 /// <param name="name">Name of the item being added</param>
 /// <param name="targetPath">Path of the item being added</param>
 /// <returns>Node that was added</returns>
 protected virtual HierarchyNode AddNodeIfTargetExistInStorage(HierarchyNode parentNode, string name, string targetPath, VSADDITEMOPERATION addItemOp)
 {
     HierarchyNode newNode = parentNode;
     // If the file/directory exist, add a node for it
     if (addItemOp == VSADDITEMOPERATION.VSADDITEMOP_LINKTOFILE || File.Exists(targetPath))
     {
         VSADDRESULT[] result = new VSADDRESULT[1];
         ErrorHandler.ThrowOnFailure(this.AddItem(parentNode.ID, addItemOp, name, 1, new string[] { targetPath }, IntPtr.Zero, result));
         if (result[0] != VSADDRESULT.ADDRESULT_Success)
             throw new ApplicationException();
         newNode = this.FindChild(targetPath);
         if (newNode == null)
             throw new ApplicationException();
     }
     else if (Directory.Exists(targetPath))
     {
         newNode = this.CreateFolderNodes(targetPath);
     }
     return newNode;
 }    
예제 #20
0
 /// <include file='doc\Hierarchy.uex' path='docs/doc[@for="HierarchyNode.OnInvalidateItems"]/*' />
 public void OnInvalidateItems(HierarchyNode parent){
     HierarchyNode foo;
     foo = this.projectMgr == null ? this : this.projectMgr;
     foreach (IVsHierarchyEvents sink in foo.hierarchyEventSinks){
         sink.OnInvalidateItems(parent.hierarchyId);
     }
 }
        /// <summary>
        /// Handle the Paste operation to a targetNode. Do not call directly
        /// outside of PasteFromClipboard.
        /// </summary>
        private int PasteFromClipboardCore(HierarchyNode targetNode)
        {
            int returnValue = (int)OleConstants.OLECMDERR_E_NOTSUPPORTED;

            //Get the clipboardhelper service and use it after processing dataobject
            IVsUIHierWinClipboardHelper clipboardHelper = (IVsUIHierWinClipboardHelper)GetService(typeof(SVsUIHierWinClipboardHelper));
            if (clipboardHelper == null)
            {
                return VSConstants.E_FAIL;
            }

            try
            {
                //Get dataobject from clipboard
                IOleDataObject dataObject = null;
                ErrorHandler.ThrowOnFailure(UnsafeNativeMethods.OleGetClipboard(out dataObject));
                if (dataObject == null)
                {
                    return VSConstants.E_UNEXPECTED;
                }

                DropEffect dropEffect = DropEffect.None;
                DropDataType dropDataType = DropDataType.None;
                try
                {
                    this.SourceDraggedOrCutOrCopied = this.dataWasCut;
                    dropDataType = this.ProcessSelectionDataObject(dataObject, targetNode.GetDragTargetHandlerNode(), 0);
                    dropEffect = this.QueryDropEffect(dropDataType, 0);
                }
                catch (ExternalException e)
                {
                    Trace.WriteLine("Exception : " + e.Message);

                    // If it is a drop from windows and we get any kind of error ignore it. This
                    // prevents bogus messages from the shell from being displayed
                    if (dropDataType != DropDataType.Shell)
                    {
                        throw e;
                    }
                }
                finally
                {
                    // Inform VS (UiHierarchyWindow) of the paste
                    returnValue = clipboardHelper.Paste(dataObject, (uint)dropEffect);
                }
            }
            catch (COMException e)
            {
                Trace.WriteLine("Exception : " + e.Message);

                returnValue = e.ErrorCode;
            }

            return returnValue;
        }
예제 #22
0
        //////////////////////////////////////////////////////////////////////////////////////////
        //  
        //  AddChild - add a node, sorted in the right location.
        //
        //////////////////////////////////////////////////////////////////////////////////////////
        /// <include file='doc\Hierarchy.uex' path='docs/doc[@for="HierarchyNode.AddChild"]/*' />
        public virtual void AddChild(HierarchyNode node){
            // make sure it's in the map.
            if (node.hierarchyId < this.projectMgr.ItemIdMap.Length && this.projectMgr.ItemIdMap[node.hierarchyId] == null){ // reuse our hierarchy id if possible.
                this.projectMgr.ItemIdMap.SetAt(node.hierarchyId, this);
            } else{
                node.hierarchyId = this.projectMgr.ItemIdMap.Add(node);
            }

            HierarchyNode previous = null;
            for (HierarchyNode n = this.firstChild; n != null; n = n.nextSibling){
                if (n.CompareTo(node) > 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);
        }
예제 #23
0
 public ReferenceNodeProperties(HierarchyNode node)
     : base(node)
 {
 }
예제 #24
0
 /// <include file='doc\PropertyPages.uex' path='docs/doc[@for="NodeProperties.NodeProperties"]/*' />
 public NodeProperties(HierarchyNode node)
 {
     this.Node = node;
     project = node.ProjectMgr;
 }
예제 #25
0
 public DependentFileNodeProperties(HierarchyNode node)
     : base(node)
 {
 }
예제 #26
0
 /// <include file='doc\PropertyPages.uex' path='docs/doc[@for="FileProperties.FileProperties"]/*' />
 public FileProperties(HierarchyNode node) : base(node)
 {
 }
예제 #27
0
 public LinkedFileNodeProperties(HierarchyNode node)
     : base(node)
 {
 }
        /// <summary>
        /// Moves files from one part of our project to another.
        /// </summary>
        /// <param name="targetNode">the targetHandler node</param>
        /// <param name="projectReferences">List of projectref string</param>
        /// <param name="dropEffect">The drop effect</param>
        /// <returns>true if succeeded</returns>
        internal bool AddFilesFromProjectReferences(HierarchyNode targetNode, string[] projectReferences, uint dropEffect)
        {
            // Validate input
            if (projectReferences == null)
            {
                throw new ArgumentException(SR.GetString(SR.InvalidParameter, CultureInfo.CurrentUICulture), "projectReferences");
            }
            if (targetNode == null)
            {
                throw new InvalidOperationException();
            }

            // Build a list
            bool bSourceProjectIsNotThisProject = false;
            foreach (string projectReference in projectReferences)
            {
                if (String.IsNullOrEmpty(projectReference))
                {
                    // bad projectref, bail out
                    return false;
                }

                IVsSolution solution = this.GetService(typeof(IVsSolution)) as IVsSolution;
                if (solution == null)
                {
                    throw new InvalidOperationException();
                }

                if (projectReference.EndsWith("/", StringComparison.Ordinal) || projectReference.EndsWith("\\", StringComparison.Ordinal))
                {
                    Guid projectInstanceGuid;
                    string folder = GetSourceFromFolderReference(projectReference, out projectInstanceGuid);
                    string folderNoTrailingSlash = folder.Substring(0, folder.Length - 1);

                    // Check if the source is not this project if it hasn't been
                    // determined yet.
                    if(!bSourceProjectIsNotThisProject)
                    {
                        if (projectInstanceGuid != this.ProjectIDGuid)
                        {
                            bSourceProjectIsNotThisProject = true;
                        }
                    }

                    string folderName = Path.GetFileName(Path.GetDirectoryName(folder));
                    string newFolderBaseDir = GetBaseDirectoryForAddingFiles(targetNode);
                    string targetPath = Path.Combine(newFolderBaseDir, folderName);

                    DragDropItem newItem = new DragDropItem();
                    newItem.reference = projectReference;
                    newItem.source = folderNoTrailingSlash;
                    newItem.destination = targetPath;
                    newItem.destinationExists = Directory.Exists(targetPath);
                    newItem.isFolder = true;
                    newItem.sourceDirMatchesDestDir = NativeMethods.IsSamePath(folderNoTrailingSlash, targetPath);

                    dropItems.Add(newItem);
                }
                else
                {
                    uint itemidLoc;
                    IVsHierarchy hierarchy;
                    string str;
                    VSUPDATEPROJREFREASON[] reason = new VSUPDATEPROJREFREASON[1];
                    ErrorHandler.ThrowOnFailure(solution.GetItemOfProjref(projectReference, out hierarchy, out itemidLoc, out str, reason));
                    if (hierarchy == null)
                    {
                        throw new InvalidOperationException();
                    }

                    // This will throw invalid cast exception if the hierrachy is not a project.
                    IVsProject project = (IVsProject)hierarchy;

                    string moniker;
                    ErrorHandler.ThrowOnFailure(project.GetMkDocument(itemidLoc, out moniker));

                    HierarchyNode n = targetNode;
                    while ((!(n is ProjectNode)) && (!(n is FolderNode)) && (!this.CanFileNodesHaveChilds || !(n is FileNode)))
                    {
                        n = n.Parent;
                    }

                    Guid projectInstanceGuid;
                    solution.GetGuidOfProject(hierarchy, out projectInstanceGuid);
                    // Check if the source is not this project if it hasn't been
                    // determined yet.
                    if (!bSourceProjectIsNotThisProject)
                    {
                        if (projectInstanceGuid != this.ProjectIDGuid)
                        {
                            bSourceProjectIsNotThisProject = true;
                        }
                    }

                    string filename = Path.GetFileName(moniker);
                    string destination = Path.Combine(this.GetBaseDirectoryForAddingFiles(n), filename);
                    string sourcedir = Path.GetDirectoryName(moniker);
                    string destdir = Path.GetDirectoryName(destination);

                    DragDropItem newItem = new DragDropItem();
                    newItem.reference = projectReference;
                    newItem.source = moniker;
                    newItem.destination = destination;
                    newItem.destinationExists = File.Exists(destination);
                    newItem.isFolder = false;
                    newItem.sourceDirMatchesDestDir = NativeMethods.IsSamePath(sourcedir, destdir);

                    dropItems.Add(newItem);
                }
            }

            // We don't want to copy files that are within any selected directories
            foreach (DragDropItem dropItem1 in dropItems)
            {
                if (dropItem1.isFolder)
                {
                    foreach (DragDropItem dropItem2 in dropItems)
                    {
                        // If this item is underneath a folder also being copied
                        // or moved, then remove it from the list of items to be
                        // copied or moved since the copy/move operation of the
                        // containing folder will handle it.
                        if (!dropItem2.source.Equals(dropItem1.source) && dropItem2.source.StartsWith(dropItem1.source, StringComparison.Ordinal))
                        {
                            // set userCancelled so that this item gets skipped
                            dropItem2.userCancelled = true;
                        }
                    }
                }
            }

            // Check for error cases
            foreach (DragDropItem dropItem in dropItems)
            {
                if (dropItem.userCancelled)
                    continue;

                if (dropItem.isFolder)
                {
                    try
                    {
                        AddFolderFromOtherProject(dropItem.reference, targetNode, dropEffect, true);
                    }
                    catch (CopyPasteException e)
                    {
                        string errorMessage = e.Message;
                        if (!Utilities.IsInAutomationFunction(this.ProjectMgr.Site))
                        {
                            string title = null;
                            OLEMSGICON icon = OLEMSGICON.OLEMSGICON_CRITICAL;
                            OLEMSGBUTTON buttons = OLEMSGBUTTON.OLEMSGBUTTON_OK;
                            OLEMSGDEFBUTTON defaultButton = OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST;
                            VsShellUtilities.ShowMessageBox(this.ProjectMgr.Site, title, errorMessage, icon, buttons, defaultButton);
                            return false;
                        }
                        else
                        {
                            throw new InvalidOperationException(errorMessage);
                        }
                    }
                }
                else
                {
                    try
                    {
                        if (dropItem.sourceDirMatchesDestDir && dropEffect == (uint)DropEffect.Move)
                        {
                            throw new DestionPathSameAsSourceException(filename);
                        }

                        bool bWillHaveCopyOfPrepended = dropItem.sourceDirMatchesDestDir && dropEffect == (uint)DropEffect.Copy;
                        // Check if overwriting is possible.
                        // If not, a dialog box will be shown by SystemCanOverwriteExistingItem
                        // and we should stop processing items.
                        if (!bWillHaveCopyOfPrepended && dropItem.destinationExists && this.SystemCanOverwriteExistingItem(dropItem.source, dropItem.destination) != VSConstants.S_OK)
                        {
                            return false;
                        }
                    }
                    catch (DestionPathSameAsSourceException e)
                    {
                        string errorMessage = e.Message;
                        if (!Utilities.IsInAutomationFunction(this.ProjectMgr.Site))
                        {
                            string title = null;
                            OLEMSGICON icon = OLEMSGICON.OLEMSGICON_CRITICAL;
                            OLEMSGBUTTON buttons = OLEMSGBUTTON.OLEMSGBUTTON_OK;
                            OLEMSGDEFBUTTON defaultButton = OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST;
                            VsShellUtilities.ShowMessageBox(this.ProjectMgr.Site, title, errorMessage, icon, buttons, defaultButton);
                            return false;
                        }
                        else
                        {
                            throw new InvalidOperationException(errorMessage);
                        }
                    }
                }
            }

            bool bAnyWereCancelled = false;
            bool bDoApplyAll = false;
            DialogResult applyAllResult = DialogResult.No;
            // Prompt for files to be overwritten
            for (int i = 0; i < dropItems.Count; i++)
            {
                DragDropItem dropItem = dropItems[i];

                if (dropItem.userCancelled)
                    continue;

                // If the source dir matches the dest dir and we are doing copy
                // then no overwriting will occur. Instead, "Copy of " will be
                // prepended.
                if (dropItem.destinationExists && !(dropItem.sourceDirMatchesDestDir && dropEffect == (uint)DropEffect.Copy))
                {
                    string message = SR.GetString(SR.FileAlreadyExists, Path.GetFileName(dropItem.destination));
                    string title = SR.GetString(SR.FileAlreadyExistsCaption);
                    DialogResult msgboxResult;
                    if (bDoApplyAll)
                    {
                        msgboxResult = applyAllResult;
                    }
                    else
                    {
                        bool bApplyAllChecked;
                        msgboxResult = FileOverwriteDialog.LaunchFileOverwriteDialog(this.Site, message, title, null, FileOverwriteDialog.DefaultButton.Yes, out bApplyAllChecked);
                        if(bApplyAllChecked)
                        {
                            bDoApplyAll = true;
                            applyAllResult = msgboxResult;
                        }
                    }

                    if (msgboxResult == DialogResult.No)
                    {
                        dropItem.userCancelled = true;
                        bAnyWereCancelled = true;
                    }
                    else if (msgboxResult != DialogResult.Yes)
                    {
                        // user cancelled the whole thing
                        return false;
                    }
                }
            }

            // Iteratively add files from projectref
            foreach (DragDropItem dropItem in dropItems)
            {
                if (dropItem.userCancelled)
                    continue;

                if (dropItem.isFolder)
                {
                    AddFolderFromOtherProject(dropItem.reference, targetNode, dropEffect);
                }
                else
                {
                    bool oldHandledOverwrite = this.alreadyHandledOverwritePrompts;
                    this.alreadyHandledOverwritePrompts = true;
                    try
                    {
                        if (!AddFileToNodeFromProjectReference(dropItem.reference, targetNode))
                        {
                            return false;
                        }
                    }
                    finally
                    {
                        this.alreadyHandledOverwritePrompts = oldHandledOverwrite;
                    }
                }
            }

            // If any items were cancelled and the source and target projects
            // differ, return false here so that none of the source items are
            // removed. It would be incorrect to remove all of the source
            // items at this point.
            if (bSourceProjectIsNotThisProject && bAnyWereCancelled)
                return false;

            return true;
        }
예제 #29
0
 public BaseFileNodeProperties(HierarchyNode node)
     : base(node)
 {
 }
 /// <summary>
 /// This is used to recursively add a folder from an other project.
 /// Note that while we copy the folder content completely, we only
 /// add to the project items which are part of the source project.
 /// </summary>
 /// <param name="folderToAdd">Project reference (from data object) using the format: {Guid}|project|folderPath</param>
 /// <param name="targetNode">Node to add the new folder to</param>
 /// <param name="dropEffect">The drop effect</param>
 protected internal virtual void AddFolderFromOtherProject(string folderToAdd, HierarchyNode targetNode, uint dropEffect)
 {
     AddFolderFromOtherProject(folderToAdd, targetNode, dropEffect, false);
 }