/// <summary> /// Performs a rectangular paste operation. /// </summary> public static bool PerformRectangularPaste(TextArea textArea, TextViewPosition startPosition, string text, bool selectInsertedText) { if (textArea == null) { throw new ArgumentNullException("textArea"); } if (text == null) { throw new ArgumentNullException("text"); } int newLineCount = text.Count(c => c == '\n'); // TODO might not work in all cases, but single \r line endings are really rare today. TextLocation endLocation = new TextLocation(startPosition.Line + newLineCount, startPosition.Column); if (endLocation.Line <= textArea.Document.LineCount) { int endOffset = textArea.Document.GetOffset(endLocation); if (textArea.Selection.EnableVirtualSpace || textArea.Document.GetLocation(endOffset) == endLocation) { RectangleSelection rsel = new RectangleSelection(textArea, startPosition, endLocation.Line, GetXPos(textArea, startPosition)); rsel.ReplaceSelectionWithText(text); if (selectInsertedText && textArea.Selection is RectangleSelection) { RectangleSelection sel = (RectangleSelection)textArea.Selection; textArea.Selection = new RectangleSelection(textArea, startPosition, sel.endLine, sel.endXPos); } return(true); } } return(false); }
/// <summary> /// Performs a rectangular paste operation. /// </summary> public static bool PerformRectangularPaste(TextArea textArea, int startOffset, string text, bool selectInsertedText) { if (textArea == null) { throw new ArgumentNullException("textArea"); } if (text == null) { throw new ArgumentNullException("text"); } int newLineCount = text.Count(c => c == '\n'); TextLocation startLocation = textArea.Document.GetLocation(startOffset); TextLocation endLocation = new TextLocation(startLocation.Line + newLineCount, startLocation.Column); if (endLocation.Line <= textArea.Document.LineCount) { int endOffset = textArea.Document.GetOffset(endLocation); if (textArea.Document.GetLocation(endOffset) == endLocation) { RectangleSelection rsel = new RectangleSelection(textArea.Document, startOffset, endOffset); rsel.ReplaceSelectionWithText(textArea, text); if (selectInsertedText && textArea.Selection is RectangleSelection) { RectangleSelection sel = (RectangleSelection)textArea.Selection; textArea.Selection = new RectangleSelection(textArea.Document, startOffset, sel.EndOffset); } return(true); } } return(false); }
private void textArea_Drop(object sender, DragEventArgs e) { try { DragDropEffects effect = GetEffect(e); e.Effects = effect; if (effect != DragDropEffects.None) { int start = textArea.Caret.Offset; if (mode == SelectionMode.Drag && textArea.Selection.Contains(start)) { Debug.WriteLine("Drop: did not drop: drop target is inside selection"); e.Effects = DragDropEffects.None; } else { Debug.WriteLine("Drop: insert at " + start); var pastingEventArgs = new DataObjectPastingEventArgs(e.Data, true, DataFormats.UnicodeText); textArea.RaiseEvent(pastingEventArgs); if (pastingEventArgs.CommandCancelled) { return; } string text = EditingCommandHandler.GetTextToPaste(pastingEventArgs, textArea); if (text == null) { return; } bool rectangular = pastingEventArgs.DataObject.GetDataPresent(RectangleSelection.RectangularSelectionDataType); // Mark the undo group with the currentDragDescriptor, if the drag // is originating from the same control. This allows combining // the undo groups when text is moved. textArea.Document.UndoStack.StartUndoGroup(this.currentDragDescriptor); try { if (rectangular && RectangleSelection.PerformRectangularPaste(textArea, textArea.Caret.Position, text, true)) { } else { textArea.Document.Insert(start, text); textArea.Selection = Selection.Create(textArea, start, start + text.Length); } } finally { textArea.Document.UndoStack.EndUndoGroup(); } } e.Handled = true; } } catch (Exception ex) { OnDragException(ex); } }
private static void OnPaste(object target, ExecutedRoutedEventArgs args) { TextArea textArea = GetTextArea(target); if (textArea != null && textArea.Document != null) { IDataObject dataObject; try { dataObject = Clipboard.GetDataObject(); } catch (ExternalException) { return; } if (dataObject == null) { return; } var pastingEventArgs = new DataObjectPastingEventArgs(dataObject, false, DataFormats.UnicodeText); textArea.RaiseEvent(pastingEventArgs); if (pastingEventArgs.CommandCancelled) { return; } string text = GetTextToPaste(pastingEventArgs, textArea); if (!string.IsNullOrEmpty(text)) { dataObject = pastingEventArgs.DataObject; bool fullLine = textArea.Options.CutCopyWholeLine && dataObject.GetDataPresent(LineSelectedType); bool rectangular = dataObject.GetDataPresent(RectangleSelection.RectangularSelectionDataType); if (fullLine) { DocumentLine currentLine = textArea.Document.GetLineByNumber(textArea.Caret.Line); if (textArea.ReadOnlySectionProvider.CanInsert(currentLine.Offset)) { textArea.Document.Insert(currentLine.Offset, text); } } else if (rectangular && textArea.Selection.IsEmpty && !(textArea.Selection is RectangleSelection)) { if (!RectangleSelection.PerformRectangularPaste(textArea, textArea.Caret.Position, text, false)) { textArea.ReplaceSelectionWithText(text); } } else { textArea.ReplaceSelectionWithText(text); } } textArea.Caret.BringCaretToView(); args.Handled = true; } }
/// <inheritdoc/> public override bool Equals(object obj) { RectangleSelection r = obj as RectangleSelection; return(r != null && r.textArea == this.textArea && r.topLeftOffset == this.topLeftOffset && r.bottomRightOffset == this.bottomRightOffset && r.startLine == this.startLine && r.endLine == this.endLine && r.startXPos == this.startXPos && r.endXPos == this.endXPos); }
static void OnPaste(object target, ExecutedRoutedEventArgs args) { TextArea textArea = GetTextArea(target); if (textArea != null && textArea.Document != null) { IDataObject dataObject; try { dataObject = Clipboard.GetDataObject(); } catch (ExternalException) { return; } if (dataObject == null) { return; } Debug.WriteLine(dataObject.GetData(DataFormats.Html) as string); // convert text back to correct newlines for this document string newLine = TextUtilities.GetNewLineFromDocument(textArea.Document, textArea.Caret.Line); string text; try { text = (string)dataObject.GetData(DataFormats.UnicodeText); text = TextUtilities.NormalizeNewLines(text, newLine); } catch (OutOfMemoryException) { return; } if (!string.IsNullOrEmpty(text)) { bool fullLine = textArea.Options.CutCopyWholeLine && dataObject.GetDataPresent(LineSelectedType); bool rectangular = dataObject.GetDataPresent(RectangleSelection.RectangularSelectionDataType); if (fullLine) { DocumentLine currentLine = textArea.Document.GetLineByNumber(textArea.Caret.Line); if (textArea.ReadOnlySectionProvider.CanInsert(currentLine.Offset)) { textArea.Document.Insert(currentLine.Offset, text); } } else if (rectangular && textArea.Selection.IsEmpty && !(textArea.Selection is RectangleSelection)) { if (!RectangleSelection.PerformRectangularPaste(textArea, textArea.Caret.Position, text, false)) { textArea.ReplaceSelectionWithText(text); } } else { textArea.ReplaceSelectionWithText(text); } } textArea.Caret.BringCaretToView(); args.Handled = true; } }
void textArea_Drop(object sender, DragEventArgs e) { try { DragDropEffects effect = GetEffect(e); e.Effects = effect; if (effect != DragDropEffects.None) { string text = e.Data.GetData(DataFormats.UnicodeText, true) as string; if (text != null) { int start = textArea.Caret.Offset; if (mode == SelectionMode.Drag && textArea.Selection.Contains(start)) { Debug.WriteLine("Drop: did not drop: drop target is inside selection"); e.Effects = DragDropEffects.None; } else { Debug.WriteLine("Drop: insert at " + start); bool rectangular = e.Data.GetDataPresent(RectangleSelection.RectangularSelectionDataType); string newLine = TextUtilities.GetNewLineFromDocument(textArea.Document, textArea.Caret.Line); text = TextUtilities.NormalizeNewLines(text, newLine); // Mark the undo group with the currentDragDescriptor, if the drag // is originating from the same control. This allows combining // the undo groups when text is moved. textArea.Document.UndoStack.StartUndoGroup(currentDragDescriptor); try { if (rectangular && RectangleSelection.PerformRectangularPaste(textArea, textArea.Caret.Position, text, true)) { } else { textArea.Document.Insert(start, text); textArea.Selection = Selection.Create(textArea, start, start + text.Length); } } finally { textArea.Document.UndoStack.EndUndoGroup(); } } e.Handled = true; } } } catch (Exception ex) { OnDragException(ex); } }
static void OnPaste(object target, ExecutedRoutedEventArgs args) { TextArea textArea = GetTextArea(target); if (textArea != null && textArea.Document != null) { Debug.WriteLine(Clipboard.GetText(TextDataFormat.Html)); // convert text back to correct newlines for this document string newLine = TextUtilities.GetNewLineFromDocument(textArea.Document, textArea.Caret.Line); string text = TextUtilities.NormalizeNewLines(Clipboard.GetText(), newLine); if (!string.IsNullOrEmpty(text)) { bool fullLine = textArea.Options.CutCopyWholeLine && Clipboard.ContainsData(LineSelectedType); bool rectangular = Clipboard.ContainsData(RectangleSelection.RectangularSelectionDataType); if (fullLine) { DocumentLine currentLine = textArea.Document.GetLineByNumber(textArea.Caret.Line); if (textArea.ReadOnlySectionProvider.CanInsert(currentLine.Offset)) { textArea.Document.Insert(currentLine.Offset, text); } } else if (rectangular && textArea.Selection.IsEmpty) { if (!RectangleSelection.PerformRectangularPaste(textArea, textArea.Caret.Offset, text, false)) { textArea.ReplaceSelectionWithText(text); } } else { textArea.ReplaceSelectionWithText(text); } } textArea.Caret.BringCaretToView(); args.Handled = true; } }
/// <summary> /// Performs a rectangular paste operation. /// </summary> public static bool PerformRectangularPaste(TextArea textArea, TextViewPosition startPosition, string text, bool selectInsertedText) { if (textArea == null) throw new ArgumentNullException("textArea"); if (text == null) throw new ArgumentNullException("text"); int newLineCount = text.Count(c => c == '\n'); // TODO might not work in all cases, but single \r line endings are really rare today. TextLocation endLocation = new TextLocation(startPosition.Line + newLineCount, startPosition.Column); if (endLocation.Line <= textArea.Document.LineCount) { int endOffset = textArea.Document.GetOffset(endLocation); if (textArea.Selection.EnableVirtualSpace || textArea.Document.GetLocation(endOffset) == endLocation) { RectangleSelection rsel = new RectangleSelection(textArea, startPosition, endLocation.Line, GetXPos(textArea, startPosition)); rsel.ReplaceSelectionWithText(text); if (selectInsertedText && textArea.Selection is RectangleSelection) { RectangleSelection sel = (RectangleSelection)textArea.Selection; textArea.Selection = new RectangleSelection(textArea, startPosition, sel.endLine, sel.endXPos); } return true; } } return false; }
void textArea_Drop(object sender, DragEventArgs e) { try { DragDropEffects effect = GetEffect(e); e.Effects = effect; if (effect != DragDropEffects.None) { string text = e.Data.GetData(DataFormats.UnicodeText, true) as string; if (text != null) { int start = textArea.Caret.Offset; if (mode == SelectionMode.Drag && textArea.Selection.Contains(start)) { Debug.WriteLine("Drop: did not drop: drop target is inside selection"); e.Effects = DragDropEffects.None; } else { Debug.WriteLine("Drop: insert at " + start); bool rectangular = e.Data.GetDataPresent(RectangleSelection.RectangularSelectionDataType); string newLine = TextUtilities.GetNewLineFromDocument(textArea.Document, textArea.Caret.Line); text = TextUtilities.NormalizeNewLines(text, newLine); string pasteFormat; // fill the suggested DataFormat used for the paste action: if (rectangular) { pasteFormat = RectangleSelection.RectangularSelectionDataType; } else { pasteFormat = DataFormats.UnicodeText; } var pastingEventArgs = new DataObjectPastingEventArgs(e.Data, true, pasteFormat); textArea.RaiseEvent(pastingEventArgs); if (pastingEventArgs.CommandCancelled) { return; } // DataObject.PastingEvent handlers might have changed the format to apply. rectangular = pastingEventArgs.FormatToApply == RectangleSelection.RectangularSelectionDataType; // Mark the undo group with the currentDragDescriptor, if the drag // is originating from the same control. This allows combining // the undo groups when text is moved. textArea.Document.UndoStack.StartUndoGroup(this.currentDragDescriptor); try { if (rectangular && RectangleSelection.PerformRectangularPaste(textArea, textArea.Caret.Position, text, true)) { } else { textArea.Document.Insert(start, text); textArea.Selection = Selection.Create(textArea, start, start + text.Length); } } finally { textArea.Document.UndoStack.EndUndoGroup(); } } e.Handled = true; } } } catch (Exception ex) { OnDragException(ex); } }
private static void SurroundRectangleSelectionWithBlockComment(EdiTextEditor editor, BlockDefinition block, RectangleSelection sel) { if (sel == null) return; // Backup current view position of rectangular selection int selectionStart = editor.SelectionStart; int selectionLength = editor.SelectionLength; int caretOffset = editor.CaretOffset; TextViewPosition startPos = new TextViewPosition(sel.StartPosition); TextViewPosition endPos = new TextViewPosition(sel.EndPosition); TextReplaceBlockRegion[] region = new TextReplaceBlockRegion[sel.Segments.Count()]; bool bFoundNoMatch = true; for (int i = sel.Segments.Count() - 1; i >= 0; i--) { var item = sel.Segments.ElementAt(i); // Attempt to find the currently set comment before and after the current selection switch (block.TypeOfBlock) { case BlockDefinition.BlockAt.Start: region[i] = FindSelectedStartCommentRegion(block.StartBlock, editor.Document, editor.Document.GetText(item), item.StartOffset, item.Length); break; case BlockDefinition.BlockAt.End: region[i] = FindSelectedEndCommentRegion(block.EndBlock, editor.Document, editor.Document.GetText(item), item.StartOffset); break; case BlockDefinition.BlockAt.StartAndEnd: region[i] = FindSelectedCommentRegion(block.StartBlock, block.EndBlock, editor.Document, editor.Document.GetText(item), item.StartOffset, item.Length); break; default: throw new NotImplementedException(block.TypeOfBlock.ToString()); } if (region[i] == null) bFoundNoMatch = false; } if (bFoundNoMatch == true) { for (int i = sel.Segments.Count() - 1; i >= 0; i--) { var item = sel.Segments.ElementAt(i); // Remove the block surround (comment) if there is a match available switch (block.TypeOfBlock) { case BlockDefinition.BlockAt.Start: editor.Document.Remove(region[i].StartOffset, region[i].CommentStart.Length); break; case BlockDefinition.BlockAt.End: editor.Document.Remove(region[i].EndOffset, region[i].CommentEnd.Length); break; case BlockDefinition.BlockAt.StartAndEnd: editor.Document.Remove(region[i].EndOffset, region[i].CommentEnd.Length); editor.Document.Remove(region[i].StartOffset, region[i].CommentStart.Length); break; default: throw new NotImplementedException(block.TypeOfBlock.ToString()); } } } else { for (int i = sel.Segments.Count() - 1; i >= 0; i--) { var item = sel.Segments.ElementAt(i); switch (block.TypeOfBlock) { case BlockDefinition.BlockAt.Start: editor.Document.Insert(item.StartOffset, block.StartBlock); break; case BlockDefinition.BlockAt.End: editor.Document.Insert(item.EndOffset, block.EndBlock); break; case BlockDefinition.BlockAt.StartAndEnd: // Insert a new comment since we could not find one ... editor.Document.Insert(item.EndOffset, block.EndBlock); editor.Document.Insert(item.StartOffset, block.StartBlock); break; default: throw new NotImplementedException(block.TypeOfBlock.ToString()); } } // Move original selection to the rigth and apply rectangular selection editor.CaretOffset = caretOffset; editor.SelectionStart = selectionStart; editor.SelectionLength = selectionLength; //startPos.Column += block.StartBlock.Length; //endPos.Column += block.StartBlock.Length; // Reset selection to keep the text that was originally selected editor.TextArea.Selection = new RectangleSelection(editor.TextArea, startPos, endPos); } }
/// <inheritdoc/> public override bool Equals(object obj) { RectangleSelection r = obj as RectangleSelection; return(r != null && r.document == this.document && r.StartOffset == this.StartOffset && r.EndOffset == this.EndOffset); }
static void OnPaste(object target, ExecutedRoutedEventArgs args) { TextArea textArea = GetTextArea(target); if (textArea != null && textArea.Document != null) { IDataObject dataObject; try { dataObject = Clipboard.GetDataObject(); } catch (ExternalException) { return; } if (dataObject == null) { return; } var pastingEventArgs = new DataObjectPastingEventArgs(dataObject, false, DataFormats.UnicodeText); textArea.RaiseEvent(pastingEventArgs); if (pastingEventArgs.CommandCancelled) { return; } dataObject = pastingEventArgs.DataObject; if (dataObject == null) { return; } // convert text back to correct newlines for this document string newLine = TextUtilities.GetNewLineFromDocument(textArea.Document, textArea.Caret.Line); string text; try { // Try retrieving the text as one of: // - the FormatToApply // - UnicodeText // - Text // (but don't try the same format twice) if (pastingEventArgs.FormatToApply != null && dataObject.GetDataPresent(pastingEventArgs.FormatToApply)) { text = (string)dataObject.GetData(pastingEventArgs.FormatToApply); } else if (pastingEventArgs.FormatToApply != DataFormats.UnicodeText && dataObject.GetDataPresent(DataFormats.UnicodeText)) { text = (string)dataObject.GetData(DataFormats.UnicodeText); } else if (pastingEventArgs.FormatToApply != DataFormats.Text && dataObject.GetDataPresent(DataFormats.Text)) { text = (string)dataObject.GetData(DataFormats.Text); } else { return; // no text data format } text = TextUtilities.NormalizeNewLines(text, newLine); } catch (OutOfMemoryException) { // may happen when trying to paste a huge string return; } if (!string.IsNullOrEmpty(text)) { bool fullLine = textArea.Options.CutCopyWholeLine && dataObject.GetDataPresent(LineSelectedType); bool rectangular = dataObject.GetDataPresent(RectangleSelection.RectangularSelectionDataType); if (fullLine) { DocumentLine currentLine = textArea.Document.GetLineByNumber(textArea.Caret.Line); if (textArea.ReadOnlySectionProvider.CanInsert(currentLine.Offset)) { textArea.Document.Insert(currentLine.Offset, text); } } else if (rectangular && textArea.Selection.IsEmpty && !(textArea.Selection is RectangleSelection)) { if (!RectangleSelection.PerformRectangularPaste(textArea, textArea.Caret.Position, text, false)) { textArea.ReplaceSelectionWithText(text); } } else { textArea.ReplaceSelectionWithText(text); } } textArea.Caret.BringCaretToView(); args.Handled = true; } }
/// <summary> /// Performs a rectangular paste operation. /// </summary> public static bool PerformRectangularPaste(TextArea textArea, int startOffset, string text, bool selectInsertedText) { if (textArea == null) throw new ArgumentNullException("textArea"); if (text == null) throw new ArgumentNullException("text"); int newLineCount = text.Count(c => c == '\n'); TextLocation startLocation = textArea.Document.GetLocation(startOffset); TextLocation endLocation = new TextLocation(startLocation.Line + newLineCount, startLocation.Column); if (endLocation.Line <= textArea.Document.LineCount) { int endOffset = textArea.Document.GetOffset(endLocation); if (textArea.Document.GetLocation(endOffset) == endLocation) { RectangleSelection rsel = new RectangleSelection(textArea.Document, startOffset, endOffset); rsel.ReplaceSelectionWithText(textArea, text); if (selectInsertedText && textArea.Selection is RectangleSelection) { RectangleSelection sel = (RectangleSelection)textArea.Selection; textArea.Selection = new RectangleSelection(textArea.Document, startOffset, sel.EndOffset); } return true; } } return false; }