Пример #1
0
        /// <summary>
        /// This is overridden to handle drop operations correctly in a help file builder project
        /// </summary>
        /// <inheritdoc />
        public override int Drop(IOleDataObject pDataObject, uint grfKeyState, uint itemid, ref uint pdwEffect)
        {
            DropDataType dropDataType = DropDataType.None;

            if (pDataObject == null)
            {
                return(VSConstants.E_INVALIDARG);
            }

            pdwEffect = (uint)DropEffect.None;

            // If the source is within the project, let the base class handle it
            if (this.SourceDraggedOrCutOrCopied)
            {
                return(base.Drop(pDataObject, grfKeyState, itemid, ref pdwEffect));
            }

            // Get the node that is being dragged over and ask it which node should handle this call
            HierarchyNode targetNode = NodeFromItemId(itemid);

            if (targetNode == null)
            {
                return(VSConstants.S_FALSE);
            }

            targetNode = targetNode.GetDragTargetHandlerNode();

            dropDataType = this.HandleSelectionDataObject(pDataObject, targetNode);

            // Since we can get a mix of files that may not necessarily be moved into the project (i.e.
            // documentation sources and references), we'll always act as if they were copied.
            pdwEffect = (uint)DropEffect.Copy;

            return((dropDataType != DropDataType.Shell) ? VSConstants.E_FAIL : VSConstants.S_OK);
        }
Пример #2
0
        /// <summary>
        /// Handle the Paste operation to a targetNode
        /// </summary>
        protected internal override int PasteFromClipboard(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
                {
                    dropDataType = this.ProcessSelectionDataObject(dataObject, targetNode.GetDragTargetHandlerNode());
                    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);
        }
Пример #3
0
        /// <summary>
        /// Called when one or more items are dropped into the target hierarchy or hierarchy window when the mouse button is released.
        /// </summary>
        /// <param name="pDataObject">Reference to the IDataObject interface on the item being dragged. This data object contains the data being transferred in the drag-and-drop operation.
        /// If the drop occurs, then this data object (item) is incorporated into the target hierarchy or hierarchy window.</param>
        /// <param name="grfKeyState">Current state of the keyboard and the mouse modifier keys. See <seealso cref="IVsHierarchyDropDataTarget"/></param>
        /// <param name="itemid">Item identifier of the drop data target over which the item is being dragged</param>
        /// <param name="pdwEffect">Visual effects associated with the drag-and drop-operation, such as a cursor, bitmap, and so on.
        /// The value of dwEffects passed to the source object via the OnDropNotify method is the value of pdwEffects returned by the Drop method</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code. </returns>
        public override int Drop(IOleDataObject pDataObject, uint grfKeyState, uint itemid, ref uint pdwEffect)
        {
            if (pDataObject == null)
            {
                return(VSConstants.E_INVALIDARG);
            }

            pdwEffect = (uint)DropEffect.None;

            // Get the node that is being dragged over and ask it which node should handle this call
            HierarchyNode targetNode = NodeFromItemId(itemid);

            if (targetNode != null)
            {
                targetNode = targetNode.GetDragTargetHandlerNode();
            }
            else
            {
                // There is no target node. The drop can not be completed.
                return(VSConstants.S_FALSE);
            }

            int returnValue;

            try
            {
                DropDataType dropDataType = DropDataType.None;
                dropDataType = ProcessSelectionDataObject(pDataObject, targetNode);
                pdwEffect    = (uint)this.QueryDropEffect(dropDataType, grfKeyState);

                // If it is a drop from windows and we get any kind of error we return S_FALSE and dropeffect none. This
                // prevents bogus messages from the shell from being displayed
                returnValue = (dropDataType != DropDataType.Shell) ? VSConstants.E_FAIL : VSConstants.S_OK;
            }
            catch (System.IO.FileNotFoundException e)
            {
                Trace.WriteLine("Exception : " + e.Message);

                if (!Utilities.IsInAutomationFunction(this.Site))
                {
                    string          message       = e.Message;
                    string          title         = string.Empty;
                    OLEMSGICON      icon          = OLEMSGICON.OLEMSGICON_CRITICAL;
                    OLEMSGBUTTON    buttons       = OLEMSGBUTTON.OLEMSGBUTTON_OK;
                    OLEMSGDEFBUTTON defaultButton = OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST;
                    VsShellUtilities.ShowMessageBox(this.Site, title, message, icon, buttons, defaultButton);
                }

                returnValue = VSConstants.E_FAIL;
            }

            return(returnValue);
        }
        /// <summary>
        /// Handle the Paste operation to a targetNode
        /// </summary>
        public override int PasteFromClipboard(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
                {
                    dropDataType = this.ProcessSelectionDataObject(dataObject, targetNode.GetDragTargetHandlerNode());
                    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;
                    }
                }
                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;
        }
        internal void DropFilesOrFolders(string[] filesDropped, HierarchyNode ontoNode) {
            var waitDialog = (IVsThreadedWaitDialog)Site.GetService(typeof(SVsThreadedWaitDialog));
            int waitResult = waitDialog.StartWaitDialog(
                "Adding files and folders...",
                "Adding files to your project, this may take several seconds...",
                null,
                0,
                null,
                null
            );
            try {
                ontoNode = ontoNode.GetDragTargetHandlerNode();
                string nodePath = ontoNode.FullPathToChildren;
                bool droppingExistingDirectory = true;
                foreach (var droppedFile in filesDropped) {
                    if (!Directory.Exists(droppedFile) ||
                        !String.Equals(Path.GetDirectoryName(droppedFile), nodePath, StringComparison.OrdinalIgnoreCase)) {
                        droppingExistingDirectory = false;
                        break;
                    }
                }

                if (droppingExistingDirectory) {
                    // we're dragging a directory/directories that already exist
                    // into the location where they exist, we can do this via a fast path,
                    // and pop up a nice progress bar.
                    AddExistingDirectories(ontoNode, filesDropped);
                } else {
                    foreach (var droppedFile in filesDropped) {
                        if (Directory.Exists(droppedFile) &&
                            CommonUtils.IsSubpathOf(droppedFile, nodePath)) {
                            int cancelled = 0;
                            waitDialog.EndWaitDialog(ref cancelled);
                            waitResult = VSConstants.E_FAIL; // don't end twice

                            Utilities.ShowMessageBox(
                                Site,
                                SR.GetString(SR.CannotAddFolderAsDescendantOfSelf, CommonUtils.GetFileOrDirectoryName(droppedFile)),
                                null,
                                OLEMSGICON.OLEMSGICON_CRITICAL,
                                OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);

                            return;
                        }
                    }

                    // This is the code path when source is windows explorer
                    VSADDRESULT[] vsaddresults = new VSADDRESULT[1];
                    vsaddresults[0] = VSADDRESULT.ADDRESULT_Failure;
                    int addResult = AddItem(ontoNode.ID, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, null, (uint)filesDropped.Length, filesDropped, 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);
                    }
                }
            } finally {
                if (ErrorHandler.Succeeded(waitResult)) {
                    int cancelled = 0;
                    waitDialog.EndWaitDialog(ref cancelled);
                }
            }
        }
Пример #6
0
        /// <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>
        protected internal virtual bool AddFolderFromOtherProject(string folderToAdd, HierarchyNode targetNode, bool drop)
        {
            Utilities.ArgumentNotNullOrEmpty(folderToAdd, "folderToAdd");
            Utilities.ArgumentNotNull("targetNode", targetNode);

            var targetFolderNode = targetNode.GetDragTargetHandlerNode();

            // Split the reference in its 3 parts
            int index1 = Guid.Empty.ToString("B").Length;
            if (index1 + 1 >= folderToAdd.Length)
                throw new ArgumentOutOfRangeException("folderToAdd");

            // Get the Guid
            string guidString = folderToAdd.Substring(1, index1 - 2);
            Guid projectInstanceGuid = new Guid(guidString);

            // Get the project path
            int index2 = folderToAdd.IndexOf('|', index1 + 1);
            if (index2 < 0 || index2 + 1 >= folderToAdd.Length)
                throw new ArgumentOutOfRangeException("folderToAdd");

            // Finally get the source path
            string folder = folderToAdd.Substring(index2 + 1);

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

            // 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));

            string name = folderName;
            // Ensure we don't end up in an endless recursion
            if (Utilities.IsSameComObject(this, sourceHierarchy))
            {
                // copy file onto its self, we should make a copy of the folder
                if (String.Equals(folder, targetNode.GetMkDocument(), StringComparison.OrdinalIgnoreCase))
                {
                    if (drop)
                    {
                        // cancelled drag and drop
                        return false;
                    }
                    string newDir;
                    string baseName = folder;
                    folder = CommonUtils.TrimEndSeparator(folder);
                    int copyCount = 0;
                    do
                    {
                        name = folderName + " - Copy";
                        if (copyCount != 0)
                        {
                            name += " (" + copyCount + ")";
                        }
                        copyCount++;
                        newDir = Path.Combine(Path.GetDirectoryName(folder), name);
                    } while (Directory.Exists(newDir));

                    targetPath = newDir;
                    targetFolderNode = targetNode.Parent;
                }
                else
                {
                    HierarchyNode cursorNode = targetFolderNode;
                    while (cursorNode != null)
                    {
                        if (String.Equals(folder, cursorNode.GetMkDocument(), StringComparison.OrdinalIgnoreCase))
                        {
                            throw new InvalidOperationException(String.Format("Cannot copy '{0}'. The destination folder is a subfolder of the source folder.", folderName));
                        }
                        cursorNode = cursorNode.Parent;
                    }
                }
            }

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

            // Now walk the source project hierarchy to see which node needs to be added.
            WalkSourceProjectAndAdd(sourceHierarchy, itemID, targetFolderNode, false, name);

            return true;
        }