/// <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; } }
/// <summary> /// Allows the drag source to prompt to save unsaved items being dropped. /// Notifies the source hierarchy that information dragged from it is about to be dropped on a target. /// This method is called immediately after the mouse button is released on a drop. /// </summary> /// <param name="o">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 hierarchy window of the new hierarchy.</param> /// <param name="dwEffect">Current state of the keyboard and the mouse modifier keys.</param> /// <param name="fCancelDrop">If true, then the drop is cancelled by the source hierarchy. If false, then the drop can continue.</param> /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code. </returns> public override int OnBeforeDropNotify(IOleDataObject o, uint dwEffect, out int fCancelDrop) { // If there is nothing to be dropped just return that drop should be cancelled. if (this.ItemsDraggedOrCutOrCopied == null) { fCancelDrop = 1; return(VSConstants.S_OK); } fCancelDrop = 0; bool dirty = false; foreach (HierarchyNode node in this.ItemsDraggedOrCutOrCopied) { 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 && isOpenedByUs) { dirty = true; break; } } } // if there are no dirty docs we are ok to proceed if (!dirty) { return(VSConstants.S_OK); } // Prompt to save if there are dirty docs string message = SR.GetString(SR.SaveModifiedDocuments, CultureInfo.CurrentUICulture); string title = string.Empty; OLEMSGICON icon = OLEMSGICON.OLEMSGICON_WARNING; OLEMSGBUTTON buttons = OLEMSGBUTTON.OLEMSGBUTTON_YESNOCANCEL; OLEMSGDEFBUTTON defaultButton = OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST; int result = VsShellUtilities.ShowMessageBox(Site, title, message, icon, buttons, defaultButton); switch (result) { case NativeMethods.IDYES: break; case NativeMethods.IDNO: return(VSConstants.S_OK); case NativeMethods.IDCANCEL: goto default; default: fCancelDrop = 1; return(VSConstants.S_OK); } // Save all dirty documents foreach (HierarchyNode node in this.ItemsDraggedOrCutOrCopied) { DocumentManager manager = node.GetDocumentManager(); if (manager != null) { manager.Save(true); } } return(VSConstants.S_OK); }