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