Exemplo n.º 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);
        }
Exemplo n.º 2
0
        /// <summary>
        ///  After a drop or paste, will use the dwEffects
        ///  to determine whether we need to clean up the source nodes or not. If
        ///  justCleanup is set, it only does the cleanup work.
        /// </summary>
        internal void CleanupSelectionDataObject(bool dropped, bool cut, bool moved, bool justCleanup)
        {
            if (this.ItemsDraggedOrCutOrCopied == null || this.ItemsDraggedOrCutOrCopied.Count == 0)
            {
                return;
            }

            try
            {
                IVsUIHierarchyWindow w = UIHierarchyUtilities.GetUIHierarchyWindow(this.site, HierarchyNode.SolutionExplorer);
                foreach (HierarchyNode node in this.ItemsDraggedOrCutOrCopied)
                {
                    if ((moved && (cut || dropped) && !justCleanup))
                    {
                        // do not close it if the doc is dirty or we do not own it
                        bool isDirty, isOpen, isOpenedByUs;
                        uint docCookie;
                        IVsPersistDocData ppIVsPersistDocData;
                        DocumentManager   manager = node.GetDocumentManager();

                        if (manager != null)
                        {
                            manager.GetDocInfo(out isOpen, out isDirty, out isOpenedByUs, out docCookie, out ppIVsPersistDocData);
                            if (isDirty || (isOpen && !isOpenedByUs))
                            {
                                continue;
                            }

                            // close it if opened
                            if (isOpen)
                            {
                                manager.Close(__FRAMECLOSE.FRAMECLOSE_NoSave);
                            }
                        }

                        node.Remove(true);
                    }
                    else if (w != null)
                    {
                        ErrorHandler.ThrowOnFailure(w.ExpandItem((IVsUIHierarchy)this, node.ID, EXPANDFLAGS.EXPF_UnCutHighlightItem));
                    }
                }
            }
            finally
            {
                // Now delete the memory allocated by the packaging of datasources.
                // If we just did a cut, or we are told to cleanup, then we need to free the data object. Otherwise, we leave it
                // alone so that you can continue to paste the data in new locations.
                if (moved || cut || justCleanup)
                {
                    this.ItemsDraggedOrCutOrCopied.Clear();
                    this.CleanAndFlushClipboard();
                }

                this.dataObject   = null;
                this.dropDataType = DropDataType.None;
            }
        }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
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);
        }
Exemplo n.º 5
0
        /// <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();

                string sourceProjectPath = DragDropHelper.GetSourceProjectPath(dataObject);

                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, filesDropped.ToArray(), 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);
        }
        /// <summary>
        /// Called as soon as the mouse drags an item over a new hierarchy or hierarchy window
        /// </summary>
        /// <param name="pDataObject">reference to interface IDataObject of the item being dragged</param>
        /// <param name="grfKeyState">Current state of the keyboard and the mouse modifier keys. See docs for a list of possible values</param>
        /// <param name="itemid">Item identifier for the item currently being dragged</param>
        /// <param name="pdwEffect">On entry, a pointer to the current DropEffect. On return, must contain the new valid DropEffect</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        public override int DragEnter(IOleDataObject pDataObject, uint grfKeyState, uint itemid, ref uint pdwEffect)
        {
            pdwEffect = (uint)DropEffect.None;

            this.dropDataType = QueryDropDataType(pDataObject);
            if (this.dropDataType != DropDataType.None)
            {
                pdwEffect = (uint)this.QueryDropEffect(this.dropDataType, grfKeyState);
            }

            return VSConstants.S_OK;
        }
        /// <summary>
        /// Called as soon as the mouse drags an item over a new hierarchy or hierarchy window
        /// </summary>
        /// <param name="pDataObject">reference to interface IDataObject of the item being dragged</param>
        /// <param name="grfKeyState">Current state of the keyboard and the mouse modifier keys. See docs for a list of possible values</param>
        /// <param name="itemid">Item identifier for the item currently being dragged</param>
        /// <param name="pdwEffect">On entry, a pointer to the current DropEffect. On return, must contain the new valid DropEffect</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        public int DragEnter(IOleDataObject pDataObject, uint grfKeyState, uint itemid, ref uint pdwEffect) {
            pdwEffect = (uint)DropEffect.None;

            var item = NodeFromItemId(itemid);

            if (item.GetDragTargetHandlerNode().CanAddFiles) {
                _dropType = QueryDropDataType(pDataObject);
                if (_dropType != DropDataType.None) {
                    pdwEffect = (uint)QueryDropEffect(grfKeyState);
                }
            }

            return VSConstants.S_OK;
        }
Exemplo n.º 8
0
        /// <summary>
        /// Called as soon as the mouse drags an item over a new hierarchy or hierarchy window
        /// </summary>
        /// <param name="pDataObject">reference to interface IDataObject of the item being dragged</param>
        /// <param name="grfKeyState">Current state of the keyboard and the mouse modifier keys. See docs for a list of possible values</param>
        /// <param name="itemid">Item identifier for the item currently being dragged</param>
        /// <param name="pdwEffect">On entry, a pointer to the current DropEffect. On return, must contain the new valid DropEffect</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        public override int DragEnter(IOleDataObject pDataObject, uint grfKeyState, uint itemid, ref uint pdwEffect)
        {
            pdwEffect = (uint)DropEffect.None;

            if (this.SourceDraggedOrCutOrCopied)
            {
                return(VSConstants.S_OK);
            }

            this.dropDataType = QueryDropDataType(pDataObject);
            if (this.dropDataType != DropDataType.None)
            {
                pdwEffect = (uint)this.QueryDropEffect(this.dropDataType, grfKeyState);
            }

            return(VSConstants.S_OK);
        }
Exemplo n.º 9
0
        public override int DragOver(uint grfKeyState, uint itemid, ref uint pdwEffect)
        {
            if (this.dataObject == null)
            {
                this.dataObject = PackageSelectionDataObject(false);
            }
            this.dropDataType = QueryDropDataType(this.dataObject);
            if (this.dropDataType != DropDataType.None)
            {
                pdwEffect = (uint)QueryDropEffect(dropDataType, grfKeyState);
            }
            //We should also analyze if the node being dragged over can accept the drop
            if (!CanTargetNodeAcceptDrop(itemid))
            {
                pdwEffect = (uint)DropEffect.None;
            }

            return(VSConstants.S_OK);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Called as soon as the mouse drags an item over a new hierarchy or hierarchy window
        /// </summary>
        /// <param name="pDataObject">reference to interface IDataObject of the item being dragged</param>
        /// <param name="grfKeyState">Current state of the keyboard and the mouse modifier keys. See docs for a list of possible values</param>
        /// <param name="itemid">Item identifier for the item currently bbeing dragged</param>
        /// <param name="pdwEffect">On entry, a pointer to the current DropEffect. On return, must contain the
        /// new valid DropEffect</param>
        /// <returns>S_OK if the method succeeds</returns>
        public override int DragEnter(IOleDataObject pDataObject, uint grfKeyState, uint itemid, ref uint pdwEffect)
        {
            pdwEffect = (uint)DropEffect.None;
            if (this.SourceDraggedOrCutOrCopied)
            {
                return VSConstants.S_OK;
            }
            else
            {
                this.dataObject = (IOleDataObject)pDataObject;
            }

            this.dropDataType = QueryDropDataType(pDataObject);
            if (this.dropDataType != DropDataType.None)
            {
                pdwEffect = (uint)QueryDropEffect(this.dropDataType, grfKeyState);
            }
            return VSConstants.S_OK;
        }
Exemplo n.º 11
0
        /// <summary>
        /// Called as soon as the mouse drags an item over a new hierarchy or hierarchy window
        /// </summary>
        /// <param name="pDataObject">reference to interface IDataObject of the item being dragged</param>
        /// <param name="grfKeyState">Current state of the keyboard and the mouse modifier keys. See docs for a list of possible values</param>
        /// <param name="itemid">Item identifier for the item currently being dragged</param>
        /// <param name="pdwEffect">On entry, a pointer to the current DropEffect. On return, must contain the new valid DropEffect</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        public override int DragEnter(IOleDataObject pDataObject, uint grfKeyState, uint itemid, ref uint pdwEffect)
        {
            pdwEffect = (uint)DropEffect.None;

            // changed from MPFProj:
            // http://mpfproj10.codeplex.com/WorkItem/View.aspx?WorkItemId=8145
            /*
            if(this.SourceDraggedOrCutOrCopied)
            {
                return VSConstants.S_OK;
            }*/

            this.dropDataType = QueryDropDataType(pDataObject);
            if (this.dropDataType != DropDataType.None)
            {
                pdwEffect = (uint)this.QueryDropEffect(this.dropDataType, grfKeyState);
            }

            return VSConstants.S_OK;
        }
Exemplo n.º 12
0
        /// <summary>
        /// Returns the drop effect.
        /// </summary>
        /// <remarks>
        /// // A directory based project should perform as follow:
        ///		NO MODIFIER
        ///			- COPY if not from current hierarchy,
        ///			- MOVE if from current hierarchy
        ///		SHIFT DRAG - MOVE
        ///		CTRL DRAG - COPY
        ///		CTRL-SHIFT DRAG - NO DROP (used for reference based projects only)
        /// </remarks>
        internal DropEffect QueryDropEffect(DropDataType dropDataType, uint grfKeyState)
        {
            //Validate the dropdatatype
            if ((dropDataType != DropDataType.Shell) && (dropDataType != DropDataType.VsRef) && (dropDataType != DropDataType.VsStg))
            {
                return(DropEffect.None);
            }

            // CTRL-SHIFT
            if ((grfKeyState & NativeMethods.MK_CONTROL) != 0 && (grfKeyState & NativeMethods.MK_SHIFT) != 0)
            {
                // Because we are not referenced base, we don't support link
                return(DropEffect.None);
            }

            // CTRL
            if ((grfKeyState & NativeMethods.MK_CONTROL) != 0)
            {
                return(DropEffect.Copy);
            }

            // SHIFT
            if ((grfKeyState & NativeMethods.MK_SHIFT) != 0)
            {
                return(DropEffect.Move);
            }

            // no modifier
            if (this.SourceDraggedOrCutOrCopied)
            {
                return(DropEffect.Move);
            }
            else
            {
                return(DropEffect.Copy);
            }
        }
        /// <summary>
        /// Returns the drop effect.
        /// </summary>
        /// <remarks>
        /// // A directory based project should perform as follow:
        ///        NO MODIFIER 
        ///            - COPY if not from current hierarchy, 
        ///            - MOVE if from current hierarchy
        ///        SHIFT DRAG - MOVE
        ///        CTRL DRAG - COPY
        ///        CTRL-SHIFT DRAG - NO DROP (used for reference based projects only)
        /// </remarks>
        internal DropEffect QueryDropEffect(DropDataType dropDataType, uint grfKeyState)
        {
            //Validate the dropdatatype
            if ((dropDataType != DropDataType.Shell) && (dropDataType != DropDataType.VsRef) && (dropDataType != DropDataType.VsStg))
            {
                return DropEffect.None;
            }

            // CTRL-SHIFT
            if ((grfKeyState & NativeMethods.MK_CONTROL) != 0 && (grfKeyState & NativeMethods.MK_SHIFT) != 0)
            {
                // Because we are not referenced base, we don't support link
                return DropEffect.None;
            }

            // CTRL
            if ((grfKeyState & NativeMethods.MK_CONTROL) != 0)
                return DropEffect.Copy;

            // SHIFT
            if ((grfKeyState & NativeMethods.MK_SHIFT) != 0)
                return DropEffect.Move;

            // no modifier
            if (this.SourceDraggedOrCutOrCopied)
            {
                return DropEffect.Move;
            }
            else
            {
                return DropEffect.Copy;
            }
        }
Exemplo n.º 14
0
        public static bool AttemptVsFormat(HierarchyNode activeNode, ushort cfFormat, Microsoft.VisualStudio.OLE.Interop.IDataObject pDataObject, uint grfKeyState, out DropDataType pddt) {
            pddt = DropDataType.None;
            FORMATETC fmtetc = new FORMATETC();

            fmtetc.cfFormat = cfFormat;
            fmtetc.ptd = IntPtr.Zero;
            fmtetc.dwAspect = (uint)DVASPECT.DVASPECT_CONTENT;
            fmtetc.lindex = -1;
            fmtetc.tymed = (uint)TYMED.TYMED_HGLOBAL;

            bool hasData = false;
            try {
                QueryGetData(pDataObject, ref fmtetc);
                hasData = true;
            } catch (Exception) {
            }

            if (hasData) {
                try {
                    STGMEDIUM stgmedium = GetData(pDataObject, ref fmtetc);
                    if (stgmedium.tymed == (uint)TYMED.TYMED_HGLOBAL) {
                        IntPtr hDropInfo = stgmedium.unionmember;
                        if (hDropInfo != IntPtr.Zero) {
                            pddt = DropDataType.VsRef;
                            try {
                                activeNode.AddFiles(UtilGetFilesFromPROJITEMDrop(hDropInfo));
                                Marshal.FreeHGlobal(hDropInfo);
                            } catch (Exception e) {
                                Marshal.FreeHGlobal(hDropInfo);
                                throw e;
                            }
                            return true;
                        }
                    }
                } catch (Exception e) {
                    Console.WriteLine("Exception:" + e.Message);
                }
            }
            return false;
        }
Exemplo n.º 15
0
 /// <summary>
 /// Called when one or more items are dragged out of the hierarchy or hierarchy window, or when the drag-and-drop operation is cancelled or completed.
 /// </summary>
 /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
 public override int DragLeave()
 {
     this.dropDataType = DropDataType.None;
     return(VSConstants.S_OK);
 }
Exemplo n.º 16
0
        DropEffect QueryDropEffect(DropDataType ddt, uint grfKeyState){
            // We are reference-based project so we should perform as follow:
            // for shell and physical items:
            //  NO MODIFIER - LINK
            //  SHIFT DRAG - NO DROP
            //  CTRL DRAG - NO DROP
            //  CTRL-SHIFT DRAG - LINK
            // for reference/link items
            //  NO MODIFIER - MOVE
            //  SHIFT DRAG - MOVE
            //  CTRL DRAG - COPY
            //  CTRL-SHIFT DRAG - LINK
            if ((ddt != DropDataType.Shell) && (ddt != DropDataType.VsRef) && (ddt != DropDataType.VsStg))
                return DropEffect.None;

            switch (ddt){
                case DropDataType.Shell: goto case DropDataType.VsStg;

                case DropDataType.VsStg:
                    // CTRL-SHIFT
                    if ((grfKeyState & MK_CONTROL) != 0 && (grfKeyState & MK_SHIFT) != 0){
                        return DropEffect.Link;
                    }
                    // CTRL
                    if ((grfKeyState & MK_CONTROL) != 0)
                        return DropEffect.None;
                    // SHIFT
                    if ((grfKeyState & MK_SHIFT) != 0)
                        return DropEffect.None;
                    // no modifier
                    return DropEffect.Link;

                case DropDataType.VsRef:
                    // CTRL-SHIFT
                    if ((grfKeyState & MK_CONTROL) != 0 && (grfKeyState & MK_SHIFT) != 0){
                        return DropEffect.Link;
                    }
                    // CTRL
                    if ((grfKeyState & MK_CONTROL) != 0){
                        return DropEffect.Copy;
                    }
                    // SHIFT
                    if ((grfKeyState & MK_SHIFT) != 0){
                        return DropEffect.Move;
                    }
                    // no modifier
                    return DropEffect.Move;
            }

            return DropEffect.None;
        }
Exemplo n.º 17
0
 public virtual void DragLeave()  {
   CCITracing.TraceCall();
   _ddt = DropDataType.None;
 }
        /// <summary>
        ///  After a drop or paste, will use the dwEffects 
        ///  to determine whether we need to clean up the source nodes or not. If
        ///  justCleanup is set, it only does the cleanup work.
        /// </summary>
        internal void CleanupSelectionDataObject(bool dropped, bool cut, bool moved, bool justCleanup)
        {
            if (this.ItemsDraggedOrCutOrCopied == null || this.ItemsDraggedOrCutOrCopied.Count == 0)
            {
                return;
            }

            // If the source and destination are within the same project, the
            // number of items dropped and selected should be equal.
            Debug.Assert(!this.SourceDraggedOrCutOrCopied ||
                (dropItems == null || dropItems.Count == 0 || (dropItems.Count > 0 && dropItems.Count == this.ItemsDraggedOrCutOrCopied.Count)),
                "Number of drop items didn't match number of items selected.");

            try
            {
                int index = -1;
                IVsUIHierarchyWindow w = UIHierarchyUtilities.GetUIHierarchyWindow(this.site, HierarchyNode.SolutionExplorer);
                foreach (HierarchyNode node in this.ItemsDraggedOrCutOrCopied)
                {
                    index++;
                    bool shouldRemove = ((moved && dropped) || cut) && !justCleanup;

                    // get matching drop item
                    // there might not be any drop items if an error occured early on
                    if (dropItems != null && dropItems.Count > 0)
                    {
                        DragDropItem dropItem = dropItems[index];
                        if (dropItem.userCancelled)
                            shouldRemove = false;
                    }

                    if (shouldRemove)
                    {
                        // do not close it if the doc is dirty or we do not own it
                        bool isDirty, isOpen, isOpenedByUs;
                        uint docCookie;
                        IVsPersistDocData ppIVsPersistDocData;
                        DocumentManager manager = node.GetDocumentManager();
                        if (manager != null)
                        {
                            manager.GetDocInfo(out isOpen, out isDirty, out isOpenedByUs, out docCookie, out ppIVsPersistDocData);
                            if (isDirty || (isOpen && !isOpenedByUs))
                            {
                                continue;
                            }

                            // close it if opened
                            if (isOpen)
                            {
                                manager.Close(__FRAMECLOSE.FRAMECLOSE_NoSave);
                            }
                        }

                        node.Remove(true);
                    }
                    else if (w != null)
                    {
                        w.ExpandItem((IVsUIHierarchy)this, node.ID, EXPANDFLAGS.EXPF_UnCutHighlightItem);
                    }
                }
            }
            finally
            {
                try
                {
                    // Now delete the memory allocated by the packaging of datasources.
                    // If we just did a cut, or we are told to cleanup, then we need to free the data object. Otherwise, we leave it
                    // alone so that you can continue to paste the data in new locations.
                    if (moved || cut || justCleanup)
                    {
                        this.ItemsDraggedOrCutOrCopied.Clear();
                        this.CleanAndFlushClipboard();
                    }
                }
                finally
                {
                    this.dropItems.Clear();
                    this.dropDataType = DropDataType.None;
                }
            }
        }
Exemplo n.º 19
0
        /// <summary>
        /// Retrives data from a VS format.
        /// </summary>
        public static List <string> GetDroppedFiles(ushort format, Microsoft.VisualStudio.OLE.Interop.IDataObject dataObject, out DropDataType ddt)
        {
            ddt = DropDataType.None;
            List <string> droppedFiles = new List <string>();

            // try HDROP
            FORMATETC fmtetc = CreateFormatEtc(format);

            if (QueryGetData(dataObject, ref fmtetc) == VSConstants.S_OK)
            {
                STGMEDIUM stgmedium = DragDropHelper.GetData(dataObject, ref fmtetc);
                if (stgmedium.tymed == (uint)TYMED.TYMED_HGLOBAL)
                {
                    // We are releasing the cloned hglobal here.
                    IntPtr dropInfoHandle = stgmedium.unionmember;
                    if (dropInfoHandle != IntPtr.Zero)
                    {
                        ddt = DropDataType.Shell;
                        try
                        {
                            uint numFiles = UnsafeNativeMethods.DragQueryFile(dropInfoHandle, 0xFFFFFFFF, null, 0);

                            // We are a directory based project thus a projref string is placed on the clipboard.
                            // We assign the maximum length of a projref string.
                            // The format of a projref is : <Proj Guid>|<project rel path>|<file path>
                            uint   lenght  = (uint)Guid.Empty.ToString().Length + 2 * NativeMethods.MAX_PATH + 2;
                            char[] moniker = new char[lenght + 1];
                            for (uint fileIndex = 0; fileIndex < numFiles; fileIndex++)
                            {
                                uint   queryFileLength = UnsafeNativeMethods.DragQueryFile(dropInfoHandle, fileIndex, moniker, lenght);
                                string filename        = new String(moniker, 0, (int)queryFileLength);
                                droppedFiles.Add(filename);
                            }
                        }
                        finally
                        {
                            Marshal.FreeHGlobal(dropInfoHandle);
                        }
                    }
                }
            }

            return(droppedFiles);
        }
Exemplo n.º 20
0
        public override int DragOver(uint grfKeyState, uint itemid, ref uint pdwEffect)
        {
            if (this.dataObject == null)
            {
                this.dataObject = PackageSelectionDataObject(false);
            }
            this.dropDataType = QueryDropDataType(this.dataObject);
            if (this.dropDataType != DropDataType.None)
            {
                pdwEffect = (uint)QueryDropEffect(dropDataType, grfKeyState);
            }
            //We should also analyze if the node being dragged over can accept the drop
            if (!CanTargetNodeAcceptDrop(itemid))
                pdwEffect = (uint)DropEffect.None;

            return VSConstants.S_OK;
        }
        /// <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;
        }
 /// <summary>
 /// Called when one or more items are dragged out of the hierarchy or hierarchy window, or when the drag-and-drop operation is cancelled or completed.
 /// </summary>
 /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
 public int DragLeave() {
     _dropType = DropDataType.None;
     return VSConstants.S_OK;
 }
Exemplo n.º 23
0
 /// <include file='doc\Hierarchy.uex' path='docs/doc[@for="HierarchyNode.DragLeave"]/*' />
 public virtual int DragLeave(){
   _ddt = DropDataType.None;
   return 0;
 }
Exemplo n.º 24
0
 /// <include file='doc\Hierarchy.uex' path='docs/doc[@for="HierarchyNode.DragEnter"]/*' />
 public virtual int DragEnter(Microsoft.VisualStudio.OLE.Interop.IDataObject pDataObject, uint grfKeyState, uint itemid, ref uint pdwEffect){
   pdwEffect = (uint)DropEffect.None;
   if (dragSource)
     return 0;
   _ddt = QueryDropDataType(pDataObject);
   if (_ddt != DropDataType.None){
     pdwEffect = (uint)QueryDropEffect(_ddt, grfKeyState);
   }
   return 0;
 }
        /// <summary>
        ///  After a drop or paste, will use the dwEffects 
        ///  to determine whether we need to clean up the source nodes or not. If
        ///  justCleanup is set, it only does the cleanup work.
        /// </summary>
        public void CleanupSelectionDataObject(bool dropped, bool cut, bool moved, bool justCleanup)
        {
            if (this.ItemsDraggedOrCutOrCopied == null || this.ItemsDraggedOrCutOrCopied.Count == 0)
            {
                return;
            }

            try
            {
                IVsUIHierarchyWindow w = UIHierarchyUtilities.GetUIHierarchyWindow(this.site, HierarchyNode.SolutionExplorer);
                foreach (HierarchyNode node in this.ItemsDraggedOrCutOrCopied)
                {
                    if ((moved && (cut || dropped) && !justCleanup))
                    {
                        // do not close it if the doc is dirty or we do not own it
                        bool isDirty, isOpen, isOpenedByUs;
                        uint docCookie;
                        IVsPersistDocData ppIVsPersistDocData;
                        DocumentManager manager = node.GetDocumentManager();
                        if (manager != null)
                        {
                            manager.GetDocInfo(out isOpen, out isDirty, out isOpenedByUs, out docCookie, out ppIVsPersistDocData);
                            if (isDirty || (isOpen && !isOpenedByUs))
                            {
                                continue;
                            }

                            // close it if opened
                            if (isOpen)
                            {
                                manager.Close(__FRAMECLOSE.FRAMECLOSE_NoSave);
                            }
                        }

                        node.Remove(true);
                    }
                    else if (w != null)
                    {
                        ErrorHandler.ThrowOnFailure(w.ExpandItem((IVsUIHierarchy)this, node.ID, EXPANDFLAGS.EXPF_UnCutHighlightItem));
                    }
                }
            }
            finally
            {
                try
                {
                    // Now delete the memory allocated by the packaging of datasources.
                    // If we just did a cut, or we are told to cleanup, then we need to free the data object. Otherwise, we leave it
                    // alone so that you can continue to paste the data in new locations.
                    if (moved || cut || justCleanup)
                    {
                        this.ItemsDraggedOrCutOrCopied.Clear();
                        this.CleanAndFlushClipboard();
                    }
                }
                finally
                {
                    this.dropDataType = DropDataType.None;
                }
            }
        }
Exemplo n.º 26
0
        public static bool AttemptVsFormat(HierarchyNode activeNode, ushort cfFormat, Microsoft.VisualStudio.OLE.Interop.IDataObject pDataObject, uint grfKeyState, out DropDataType pddt)
        {
            pddt = DropDataType.None;
            FORMATETC fmtetc = new FORMATETC();

            fmtetc.cfFormat = cfFormat;
            fmtetc.ptd      = IntPtr.Zero;
            fmtetc.dwAspect = (uint)DVASPECT.DVASPECT_CONTENT;
            fmtetc.lindex   = -1;
            fmtetc.tymed    = (uint)TYMED.TYMED_HGLOBAL;

            bool hasData = false;

            try
            {
                QueryGetData(pDataObject, ref fmtetc);
                hasData = true;
            }
            catch
            {
            }

            if (hasData)
            {
                try
                {
                    STGMEDIUM stgmedium = GetData(pDataObject, ref fmtetc);
                    if (stgmedium.tymed == (uint)TYMED.TYMED_HGLOBAL)
                    {
                        IntPtr hDropInfo = stgmedium.unionmember;
                        if (hDropInfo != IntPtr.Zero)
                        {
                            pddt = DropDataType.VsRef;
                            try
                            {
                                activeNode.AddFiles(UtilGetFilesFromPROJITEMDrop(hDropInfo));
                            }
                            finally
                            {
                                Marshal.FreeHGlobal(hDropInfo);
                            }
                            return(true);
                        }
                    }
                }
                catch (Exception e)
                {
                    Trace.WriteLine("Exception:" + e.Message);
                }
                catch
                {
                    Trace.WriteLine("Exception");
                }
            }
            return(false);
        }
        /// <summary>
        /// Returns the drop effect.
        /// </summary>
        /// <remarks>
        /// // A directory based project should perform as follow:
        ///     NO MODIFIER 
        ///         - COPY if not from current hierarchy, 
        ///         - MOVE if from current hierarchy
        ///     SHIFT DRAG - MOVE
        ///     CTRL DRAG - COPY
        ///     CTRL-SHIFT DRAG - NO DROP (used for reference based projects only)
        /// </remarks>
        internal DropEffect QueryDropEffect(DropDataType dropDataType, uint grfKeyState)
        {
            //Validate the dropdatatype
            if ((dropDataType != DropDataType.Shell) && (dropDataType != DropDataType.VsRef) && (dropDataType != DropDataType.VsStg))
            {
                return DropEffect.None;
            }

            // CTRL-SHIFT
            if ((grfKeyState & NativeMethods.MK_CONTROL) != 0 && (grfKeyState & NativeMethods.MK_SHIFT) != 0)
            {
                // Because we are not referenced base, we don't support link
                return DropEffect.None;
            }

            // CTRL
            if ((grfKeyState & NativeMethods.MK_CONTROL) != 0)
                return DropEffect.Copy;

            // SHIFT
            if ((grfKeyState & NativeMethods.MK_SHIFT) != 0)
                return DropEffect.Move;

            // If the source project is this project, default to move items,
            // otherwise copy items.
            if (this.SourceDraggedOrCutOrCopied)
                return DropEffect.Move;
            else
                return DropEffect.Copy;
        }
        /// <summary>
        /// Called as soon as the mouse drags an item over a new hierarchy or hierarchy window
        /// </summary>
        /// <param name="dataObject">reference to interface IDataObject of the item being dragged</param>
        /// <param name="keyState">Current state of the keyboard and the mouse modifier keys. See docs for a list of possible values</param>
        /// <param name="itemId">Item identifier for the item currently being dragged</param>
        /// <param name="effect">On entry, a pointer to the current DropEffect. On return, must contain the new valid DropEffect</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        public override int DragEnter(IOleDataObject dataObject, uint keyState, uint itemId, ref DropEffects effect)
        {
            effect = DropEffects.None;

            if(this.SourceDraggedOrCutOrCopied)
            {
                return VSConstants.S_OK;
            }

            this._dropDataType = QueryDropDataType(dataObject);
            if(this._dropDataType != DropDataType.None)
            {
                effect = this.QueryDropEffect(this._dropDataType, keyState);
            }

            return VSConstants.S_OK;
        }
        /// <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
            {
                this.isInPasteOrDrop = true;
                DropDataType dropDataType = DropDataType.None;
                dropDataType = ProcessSelectionDataObject(pDataObject, targetNode, grfKeyState);
                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;
            }
            finally
            {
                this.isInPasteOrDrop = false;
                this.dropAsCopy = false;
            }

            return returnValue;
        }
Exemplo n.º 30
0
 /// <include file='doc\Hierarchy.uex' path='docs/doc[@for="HierarchyNode.DragLeave"]/*' />
 public virtual int DragLeave() {
     _ddt = DropDataType.None;
     return NativeMethods.S_OK;
 }
 /// <summary>
 /// Called when one or more items are dragged out of the hierarchy or hierarchy window, or when the drag-and-drop operation is cancelled or completed.
 /// </summary>
 /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
 public override int DragLeave()
 {
     this.dropDataType = DropDataType.None;
     return VSConstants.S_OK;
 }
Exemplo n.º 32
0
        // ================= Drag/Drop/Cut/Copy/Paste ========================
        // Ported from HeirUtil7\PrjHeir.cpp
        void ProcessSelectionDataObject(Microsoft.VisualStudio.OLE.Interop.IDataObject pDataObject, uint grfKeyState, out DropDataType pddt){
            pddt = DropDataType.None;
            // try HDROP
            FORMATETC fmtetc = DragDropHelper.CreateFormatEtc(CF_HDROP);

            bool hasData = false;
            try{
                DragDropHelper.QueryGetData(pDataObject, ref fmtetc);
                hasData = true;
            } catch (Exception){
            }

            if (hasData){
                try{
                    STGMEDIUM stgmedium = DragDropHelper.GetData(pDataObject, ref fmtetc);
                    if (stgmedium.tymed == (uint)TYMED.TYMED_HGLOBAL){
                        IntPtr hDropInfo = stgmedium.unionmember;
                        if (hDropInfo != IntPtr.Zero){
                            pddt = DropDataType.Shell;
                            try{
                                uint numFiles = DragQueryFile(hDropInfo, 0xFFFFFFFF, null, 0);
                                char[] szMoniker = new char[MAX_PATH + 1];
                                IVsProject vsProj = (IVsProject)this.projectMgr;
                                for (uint iFile = 0; iFile < numFiles; iFile++){
                                    uint len = DragQueryFile(hDropInfo, iFile, szMoniker, MAX_PATH);
                                    string filename = new String(szMoniker, 0, (int)len);
                                    // Is full path returned
                                    if (File.Exists(filename)){
                                        VSADDRESULT[] vsaddresult = new VSADDRESULT[1];
                                        vsaddresult[0] = VSADDRESULT.ADDRESULT_Failure;
                                        string[] files = new String[1]{ filename };
                                        // TODO: support dropping into subfolders...
                                        vsProj.AddItem(this.projectMgr.hierarchyId, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, null, 1, files, IntPtr.Zero, vsaddresult);
                                    }
                                }
                                Marshal.FreeHGlobal(hDropInfo);
                            } catch (Exception e){
                                Marshal.FreeHGlobal(hDropInfo);
                                throw e;
                            }
                        }
                    }
                    return;
                } catch (Exception){
                    hasData = false;
                }
            }

            if (DragDropHelper.AttemptVsFormat(this, DragDropHelper.CF_VSREFPROJECTITEMS, pDataObject, grfKeyState, out pddt))
                return;

            if (DragDropHelper.AttemptVsFormat(this, DragDropHelper.CF_VSSTGPROJECTITEMS, pDataObject, grfKeyState, out pddt))
                return;
        }
        /// <summary>
        /// Retrieves data from a VS format.
        /// </summary>
        public static List<string> GetDroppedFiles(ushort format, Microsoft.VisualStudio.OLE.Interop.IDataObject dataObject, out DropDataType ddt) {
            ddt = DropDataType.None;
            List<string> droppedFiles = new List<string>();

            // try HDROP
            FORMATETC fmtetc = CreateFormatEtc(format);

            if (QueryGetData(dataObject, ref fmtetc) == VSConstants.S_OK) {
                STGMEDIUM stgmedium = DragDropHelper.GetData(dataObject, ref fmtetc);
                if (stgmedium.tymed == (uint)TYMED.TYMED_HGLOBAL) {
                    // We are releasing the cloned hglobal here.
                    IntPtr dropInfoHandle = stgmedium.unionmember;
                    if (dropInfoHandle != IntPtr.Zero) {
                        ddt = DropDataType.Shell;
                        try {
                            uint numFiles = UnsafeNativeMethods.DragQueryFile(dropInfoHandle, 0xFFFFFFFF, null, 0);

                            // We are a directory based project thus a projref string is placed on the clipboard.
                            // We assign the maximum length of a projref string.
                            // The format of a projref is : <Proj Guid>|<project rel path>|<file path>
                            uint lenght = (uint)Guid.Empty.ToString().Length + 2 * NativeMethods.MAX_PATH + 2;
                            char[] moniker = new char[lenght + 1];
                            for (uint fileIndex = 0; fileIndex < numFiles; fileIndex++) {
                                uint queryFileLength = UnsafeNativeMethods.DragQueryFile(dropInfoHandle, fileIndex, moniker, lenght);
                                string filename = new String(moniker, 0, (int)queryFileLength);
                                droppedFiles.Add(filename);
                            }
                        } finally {
                            Marshal.FreeHGlobal(dropInfoHandle);
                        }
                    }
                }
            }

            return droppedFiles;
        }
Exemplo n.º 34
0
        /// <summary>
        /// Process data object 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>
        private DropDataType HandleSelectionDataObject(IOleDataObject dataObject, HierarchyNode targetNode)
        {
            DropDataType dropDataType    = DropDataType.None;
            bool         isWindowsFormat = false;

            if (targetNode == null)
            {
                targetNode = this;
            }

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

            // Handle documentation sources and references first.  These will be removed from the list before
            // passing on what's left to add as standard project files.
            if (isWindowsFormat && filesDropped.Count != 0)
            {
                List <string> docSources = filesDropped.Where(f =>
                {
                    string ext = Path.GetExtension(f);

                    return(ext.Equals(".sln", StringComparison.OrdinalIgnoreCase) ||
                           ext.EndsWith("proj", StringComparison.OrdinalIgnoreCase));
                }).ToList(),
                refSources = filesDropped.Where(f =>
                {
                    string ext = Path.GetExtension(f);

                    return(ext.Equals(".dll", StringComparison.OrdinalIgnoreCase) ||
                           ext.Equals(".exe", StringComparison.OrdinalIgnoreCase) ||
                           ext.Equals(".winmd", StringComparison.OrdinalIgnoreCase));
                }).ToList(),
                xmlDocSources = filesDropped.Where(f =>
                {
                    string file = Path.GetFileNameWithoutExtension(f), ext = Path.GetExtension(f);

                    // We only want XML files with a base name that matches an assembly in the list
                    return(ext.Equals(".xml", StringComparison.OrdinalIgnoreCase) &&
                           refSources.Any(r => Path.GetFileNameWithoutExtension(r).Equals(file,
                                                                                          StringComparison.OrdinalIgnoreCase)));
                }).ToList(),
                allDocSources = docSources.Concat(refSources).Concat(xmlDocSources).ToList();

                var docSourcesNode = targetNode as DocumentationSourcesContainerNode;

                // If dropped on the Documentation Sources node, add all documentation sources
                if (docSourcesNode != null)
                {
                    foreach (string f in allDocSources)
                    {
                        if (!f.EndsWith(".sln", StringComparison.OrdinalIgnoreCase))
                        {
                            docSourcesNode.AddDocumentationSource(f);
                        }
                        else
                        {
                            foreach (string project in SandcastleBuilder.Utils.MSBuild.SelectProjectsDlg.SelectSolutionOrProjects(f))
                            {
                                docSourcesNode.AddDocumentationSource(project);
                            }
                        }
                    }
                }
                else
                {
                    var refsNode = targetNode as SandcastleBuilderReferenceContainerNode;

                    // If dropped on the references node, add all reference files
                    if (refsNode != null)
                    {
                        foreach (string f in refSources)
                        {
                            var node = refsNode.AddReferenceFromSelectorData(new VSCOMPONENTSELECTORDATA
                            {
                                type     = VSCOMPONENTTYPE.VSCOMPONENTTYPE_File,
                                bstrFile = f
                            }, null);

                            // Clear the Name and AseemblyName metadata and set the HintPath metadata so that it
                            // treats it correctly when the project is reloaded
                            if (node != null)
                            {
                                string hintPath = f;

                                if (Path.IsPathRooted(hintPath))
                                {
                                    hintPath = PackageUtilities.GetPathDistance(this.ProjectMgr.BaseURI.Uri,
                                                                                new Uri(hintPath));
                                }

                                node.ItemNode.SetMetadata(ProjectFileConstants.Name, null);
                                node.ItemNode.SetMetadata(ProjectFileConstants.AssemblyName, null);
                                node.ItemNode.SetMetadata(ProjectFileConstants.HintPath, hintPath);
                            }
                        }
                    }
                }

                // Remove the documentation source and reference files from the list
                filesDropped = filesDropped.Except(allDocSources).ToList();
            }

            // Handle all other file types
            if (dropDataType != DropDataType.None && filesDropped.Count > 0)
            {
                string[] filesDroppedAsArray = filesDropped.ToArray();

                // 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 = this.AddItem(targetNode.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(targetNode, 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);
        }