Skip to content

Commit e57d86d

Browse files
committed
Fix #35: OnDrop: Retrieve text from DataObject after raising the DataObject.Pasting event.
1 parent a59f8ae commit e57d86d

2 files changed

Lines changed: 63 additions & 70 deletions

File tree

ICSharpCode.AvalonEdit/Editing/EditingCommandHandler.cs

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -428,35 +428,10 @@ static void OnPaste(object target, ExecutedRoutedEventArgs args)
428428
if (pastingEventArgs.CommandCancelled)
429429
return;
430430

431-
dataObject = pastingEventArgs.DataObject;
432-
if (dataObject == null)
433-
return;
434-
435-
// convert text back to correct newlines for this document
436-
string newLine = TextUtilities.GetNewLineFromDocument(textArea.Document, textArea.Caret.Line);
437-
string text;
438-
try {
439-
// Try retrieving the text as one of:
440-
// - the FormatToApply
441-
// - UnicodeText
442-
// - Text
443-
// (but don't try the same format twice)
444-
if (pastingEventArgs.FormatToApply != null && dataObject.GetDataPresent(pastingEventArgs.FormatToApply))
445-
text = (string)dataObject.GetData(pastingEventArgs.FormatToApply);
446-
else if (pastingEventArgs.FormatToApply != DataFormats.UnicodeText && dataObject.GetDataPresent(DataFormats.UnicodeText))
447-
text = (string)dataObject.GetData(DataFormats.UnicodeText);
448-
else if (pastingEventArgs.FormatToApply != DataFormats.Text && dataObject.GetDataPresent(DataFormats.Text))
449-
text = (string)dataObject.GetData(DataFormats.Text);
450-
else
451-
return; // no text data format
452-
text = TextUtilities.NormalizeNewLines(text, newLine);
453-
text = textArea.Options.ConvertTabsToSpaces ? text.Replace("\t", new String(' ', textArea.Options.IndentationSize)) : text;
454-
} catch (OutOfMemoryException) {
455-
// may happen when trying to paste a huge string
456-
return;
457-
}
431+
string text = GetTextToPaste(pastingEventArgs, textArea);
458432

459433
if (!string.IsNullOrEmpty(text)) {
434+
dataObject = pastingEventArgs.DataObject;
460435
bool fullLine = textArea.Options.CutCopyWholeLine && dataObject.GetDataPresent(LineSelectedType);
461436
bool rectangular = dataObject.GetDataPresent(RectangleSelection.RectangularSelectionDataType);
462437

@@ -476,6 +451,37 @@ static void OnPaste(object target, ExecutedRoutedEventArgs args)
476451
args.Handled = true;
477452
}
478453
}
454+
455+
internal static string GetTextToPaste(DataObjectPastingEventArgs pastingEventArgs, TextArea textArea)
456+
{
457+
var dataObject = pastingEventArgs.DataObject;
458+
if (dataObject == null)
459+
return null;
460+
try {
461+
string text;
462+
// Try retrieving the text as one of:
463+
// - the FormatToApply
464+
// - UnicodeText
465+
// - Text
466+
// (but don't try the same format twice)
467+
if (pastingEventArgs.FormatToApply != null && dataObject.GetDataPresent(pastingEventArgs.FormatToApply))
468+
text = (string)dataObject.GetData(pastingEventArgs.FormatToApply);
469+
else if (pastingEventArgs.FormatToApply != DataFormats.UnicodeText && dataObject.GetDataPresent(DataFormats.UnicodeText))
470+
text = (string)dataObject.GetData(DataFormats.UnicodeText);
471+
else if (pastingEventArgs.FormatToApply != DataFormats.Text && dataObject.GetDataPresent(DataFormats.Text))
472+
text = (string)dataObject.GetData(DataFormats.Text);
473+
else
474+
return null; // no text data format
475+
// convert text back to correct newlines for this document
476+
string newLine = TextUtilities.GetNewLineFromDocument(textArea.Document, textArea.Caret.Line);
477+
text = TextUtilities.NormalizeNewLines(text, newLine);
478+
text = textArea.Options.ConvertTabsToSpaces ? text.Replace("\t", new String(' ', textArea.Options.IndentationSize)) : text;
479+
return text;
480+
} catch (OutOfMemoryException) {
481+
// may happen when trying to paste a huge string
482+
return null;
483+
}
484+
}
479485
#endregion
480486

481487
#region DeleteLine

ICSharpCode.AvalonEdit/Editing/SelectionMouseHandler.cs

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -222,52 +222,39 @@ void textArea_Drop(object sender, DragEventArgs e)
222222
DragDropEffects effect = GetEffect(e);
223223
e.Effects = effect;
224224
if (effect != DragDropEffects.None) {
225-
string text = e.Data.GetData(DataFormats.UnicodeText, true) as string;
226-
if (text != null) {
227-
int start = textArea.Caret.Offset;
228-
if (mode == SelectionMode.Drag && textArea.Selection.Contains(start)) {
229-
Debug.WriteLine("Drop: did not drop: drop target is inside selection");
230-
e.Effects = DragDropEffects.None;
231-
} else {
232-
Debug.WriteLine("Drop: insert at " + start);
233-
234-
bool rectangular = e.Data.GetDataPresent(RectangleSelection.RectangularSelectionDataType);
235-
236-
string newLine = TextUtilities.GetNewLineFromDocument(textArea.Document, textArea.Caret.Line);
237-
text = TextUtilities.NormalizeNewLines(text, newLine);
238-
239-
string pasteFormat;
240-
// fill the suggested DataFormat used for the paste action:
241-
if (rectangular)
242-
pasteFormat = RectangleSelection.RectangularSelectionDataType;
243-
else
244-
pasteFormat = DataFormats.UnicodeText;
245-
246-
var pastingEventArgs = new DataObjectPastingEventArgs(e.Data, true, pasteFormat);
247-
textArea.RaiseEvent(pastingEventArgs);
248-
if (pastingEventArgs.CommandCancelled)
249-
return;
250-
251-
// DataObject.PastingEvent handlers might have changed the format to apply.
252-
rectangular = pastingEventArgs.FormatToApply == RectangleSelection.RectangularSelectionDataType;
253-
254-
// Mark the undo group with the currentDragDescriptor, if the drag
255-
// is originating from the same control. This allows combining
256-
// the undo groups when text is moved.
257-
textArea.Document.UndoStack.StartUndoGroup(this.currentDragDescriptor);
258-
try {
259-
if (rectangular && RectangleSelection.PerformRectangularPaste(textArea, textArea.Caret.Position, text, true)) {
260-
261-
} else {
262-
textArea.Document.Insert(start, text);
263-
textArea.Selection = Selection.Create(textArea, start, start + text.Length);
264-
}
265-
} finally {
266-
textArea.Document.UndoStack.EndUndoGroup();
225+
int start = textArea.Caret.Offset;
226+
if (mode == SelectionMode.Drag && textArea.Selection.Contains(start)) {
227+
Debug.WriteLine("Drop: did not drop: drop target is inside selection");
228+
e.Effects = DragDropEffects.None;
229+
} else {
230+
Debug.WriteLine("Drop: insert at " + start);
231+
232+
var pastingEventArgs = new DataObjectPastingEventArgs(e.Data, true, DataFormats.UnicodeText);
233+
textArea.RaiseEvent(pastingEventArgs);
234+
if (pastingEventArgs.CommandCancelled)
235+
return;
236+
237+
string text = EditingCommandHandler.GetTextToPaste(pastingEventArgs, textArea);
238+
if (text == null)
239+
return;
240+
bool rectangular = pastingEventArgs.DataObject.GetDataPresent(RectangleSelection.RectangularSelectionDataType);
241+
242+
// Mark the undo group with the currentDragDescriptor, if the drag
243+
// is originating from the same control. This allows combining
244+
// the undo groups when text is moved.
245+
textArea.Document.UndoStack.StartUndoGroup(this.currentDragDescriptor);
246+
try {
247+
if (rectangular && RectangleSelection.PerformRectangularPaste(textArea, textArea.Caret.Position, text, true)) {
248+
249+
} else {
250+
textArea.Document.Insert(start, text);
251+
textArea.Selection = Selection.Create(textArea, start, start + text.Length);
267252
}
253+
} finally {
254+
textArea.Document.UndoStack.EndUndoGroup();
268255
}
269-
e.Handled = true;
270256
}
257+
e.Handled = true;
271258
}
272259
} catch (Exception ex) {
273260
OnDragException(ex);

0 commit comments

Comments
 (0)