Paste Plain Text

6 posts, 1 answers
  1. Nick Anderson
    Nick Anderson avatar
    40 posts
    Member since:
    May 2009

    Posted 15 Mar 2012 Link to this post

    Does the RadRichTextBox support a 'paste plain text' mode?

    If a user wants to paste in text that is formatted as a table, I would like it to just paste the data in the tables, becuase our reporting technology cannot handle html tables.

    Any ideas if this can be done? I don't see anything in the Demos about special paste functions
  2. Martin Ivanov
    Admin
    Martin Ivanov avatar
    104 posts

    Posted 20 Mar 2012 Link to this post

    Hello Nick,

    RadRichTextBox does not have customization options regarding the text that is being pasted.

    However, you can attach to the CommandExecuting event of the rich text box and manipulate the data from the clipboard:

    this.radRichTextBox1.CommandExecuting += OnCommandExecuting;

    private void OnCommandExecuting(object sender, CommandExecutingEventArgs e)
    {
        if (e.Command is PasteCommand)
        {
            DocumentFragment fragment = ClipboardEx.GetDocument();
            if (fragment != null)
            {
                RadDocument document = fragment.ToDocument();
                foreach (Block block in document.EnumerateChildrenOfType<Block>().ToList<Block>())
                {
                    if (block is Table)
                    {
                        block.Parent.Children.Remove(block);
                    }
                    else if (block is Paragraph)
                    {
                        Paragraph para = (Paragraph)block;
                        foreach (Inline item in para.Inlines)
                        {
                            if (item is ImageInline || item is FloatingImageBlock || item is AnnotationMarkerBase)
                            {
                                para.Inlines.Remove(item);
                            }
                            else if (item is Span)
                            {
                                var span = item as Span;
                                span.ForeColor = Colors.Black;
                                span.FontFamily = FontFamily;
                                span.FontSize = FontSize;
                            }
                        }
                    }
                }
     
                DocumentSelection selection = new DocumentSelection(document);
                selection.SelectAll();
                this.radRichTextBox1.InsertFragment(new DocumentFragment(selection));
                e.Cancel = true;
            }
        }
    }

    In the example code images and annotation markers (hyperlinks, comments, etc.) are removed. Table cell data is inserted while the table itself is not.
    You can do some more customization depending on the logic in your case. If you need further assistance, contact us again.

    Kind regards,
    Martin
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  3. UI for WPF is Visual Studio 2017 Ready
  4. Nick Anderson
    Nick Anderson avatar
    40 posts
    Member since:
    May 2009

    Posted 02 Apr 2012 Link to this post

    I have tried to implement your solution, but it seems as if it just doesn't paste the table at all. I do not get the data from the table, as your comment indicated I would.

    I am starting with just a simple table that I created in excel and copied out.

    I translated the code to VB for our use, is there something I messed up?
    Private Sub richTextBox_CommandExecuting(sender As Object, e As Telerik.Windows.Documents.RichTextBoxCommands.CommandExecutingEventArgs) Handles richTextBox.CommandExecuting
           If e.Command.GetType Is GetType(Telerik.Windows.Documents.RichTextBoxCommands.PasteCommand) Then
               Dim fragment As DocumentFragment = ClipboardEx.GetDocument()
               If fragment IsNot Nothing Then
                   Dim document As RadDocument = fragment.ToDocument()
                   For Each chunk As Telerik.Windows.Documents.Model.Block In document.EnumerateChildrenOfType(Of Telerik.Windows.Documents.Model.Block)().ToList
                       If chunk.GetType Is GetType(Table) Then
                           chunk.Parent.Children.Remove(chunk)
                       ElseIf chunk.GetType Is GetType(Paragraph) Then
                           Dim para As Paragraph = chunk
                           For Each item As Inline In para.Inlines
                               If item.GetType Is GetType(ImageInline) Or item.GetType Is GetType(FloatingImageBlock) Or item.GetType Is GetType(AnnotationMarkerBase) Then
                                   para.Inlines.Remove(item)
                               ElseIf item.GetType Is GetType(Span) Then
                                   Dim span As Span = item
                                   span.ForeColor = Colors.Black
                                   span.FontFamily = FontFamily
                                   span.FontSize = FontSize
                               End If
                           Next
                       End If
                   Next
                   Dim selection As New DocumentSelection(document)
                   selection.SelectAll()
                   Me.richTextBox.InsertFragment(New DocumentFragment(selection))
                   e.Cancel = True
               End If
           End If
       End Sub
  5. Answer
    Martin Ivanov
    Admin
    Martin Ivanov avatar
    104 posts

    Posted 05 Apr 2012 Link to this post

    Hi Nick,

    You are right, the code from my previous snippet skips the tables altogether and the data in them is ignored.

    You can use the following code to remove the table while adding its contents to the document:
    private void editor_CommandExecuting(object sender, CommandExecutingEventArgs e)
    {
        if (e.Command is PasteCommand)
        {
            DocumentFragment fragment = ClipboardEx.GetDocument();
            if (fragment != null)
            {
                RadDocument document = fragment.ToDocument();
                RadDocument newDocument = new RadDocument();
                foreach (Section section in document.Sections)
                {
                    Section sectionCopy = section.CreateShallowCopy() as Section;
                    foreach (Block block in section.Children)
                    {
                        if (block is Paragraph)
                        {
                            Paragraph originalParagraph = (Paragraph)block;
                            Paragraph strippedParagraph = this.CreateFormattingStrippedCopy(originalParagraph);
                            if (originalParagraph.IsEmpty || !strippedParagraph.IsEmpty)
                            {
                                sectionCopy.Blocks.Add(strippedParagraph);
                            }
                        }
                        else if (block is Table)
                        {
                            foreach (Paragraph paragraph in this.GetParagraphsFromTable((Table)block))
                            {
                                Paragraph strippedParagraph = this.CreateFormattingStrippedCopy(paragraph);
                                if (!strippedParagraph.IsEmpty)
                                {
                                    sectionCopy.Blocks.Add(strippedParagraph);
                                }
                            }
                        }
                    }
                    newDocument.Sections.Add(sectionCopy);
                }
     
                newDocument.MeasureAndArrangeInDefaultSize();
                DocumentSelection selection = new DocumentSelection(newDocument);
                selection.SelectAll();
                this.editor.InsertFragment(new DocumentFragment(selection));
                e.Cancel = true;
            }
        }
    }
     
    private Paragraph CreateFormattingStrippedCopy(Paragraph paragraph)
    {
        Paragraph newParagraph = paragraph.CreateShallowCopy() as Paragraph;
        foreach (Inline item in paragraph.Inlines)
        {
            if (item is Span)
            {
                Span spanCopy = item.CreateDeepCopy() as Span;
                if (spanCopy.Text != string.Empty)
                {
                    //change ForeColor, FontSize and FontFamily if required
                    spanCopy.ForeColor = Colors.Black;
     
                    newParagraph.Inlines.Add(spanCopy);
                }
            }
        }
        return newParagraph;
    }
     
    private List<Paragraph> GetParagraphsFromTable(Table table)
    {
        List<Paragraph> paragraphs = new List<Paragraph>();
        foreach (Block child in table.Children)
        {
            foreach (Block block in child.EnumerateChildrenOfType<Block>().ToList<Block>())
            {
                if (block is Paragraph)
                {
                    paragraphs.Add((Paragraph)block);
                }
                else if (block is Table)
                {
                    paragraphs.Union(GetParagraphsFromTable((Table)block));
                }
            }
        }
        return paragraphs;
    }

    Here is the equivalent code in VB:
    Private Sub richTextBox_CommandExecuting(sender As System.Object, e As Telerik.Windows.Documents.RichTextBoxCommands.CommandExecutingEventArgs)
        If TypeOf e.Command Is PasteCommand Then
            Dim fragment As DocumentFragment = ClipboardEx.GetDocument()
            If fragment IsNot Nothing Then
                Dim document As RadDocument = fragment.ToDocument()
                Dim newDocument As New RadDocument()
                For Each section As Section In document.Sections
                    Dim sectionCopy As Section = TryCast(section.CreateShallowCopy(), Section)
                    For Each block As Block In section.Children
                        If TypeOf block Is Paragraph Then
                            Dim originalParagraph As Paragraph = DirectCast(block, Paragraph)
                            Dim strippedParagraph As Paragraph = Me.CreateFormattingStrippedCopy(originalParagraph)
                            If originalParagraph.IsEmpty OrElse Not strippedParagraph.IsEmpty Then
                                sectionCopy.Blocks.Add(strippedParagraph)
                            End If
                        ElseIf TypeOf block Is Table Then
                            For Each paragraph As Paragraph In Me.GetParagraphsFromTable(DirectCast(block, Table))
                                Dim strippedParagraph As Paragraph = Me.CreateFormattingStrippedCopy(paragraph)
                                If Not strippedParagraph.IsEmpty Then
                                    sectionCopy.Blocks.Add(strippedParagraph)
                                End If
                            Next
                        End If
                    Next
                    newDocument.Sections.Add(sectionCopy)
                Next
     
                newDocument.MeasureAndArrangeInDefaultSize()
                Dim selection As New DocumentSelection(newDocument)
                selection.SelectAll()
                Me.richTextBox.InsertFragment(New DocumentFragment(selection))
                e.Cancel = True
            End If
        End If
    End Sub
     
    Private Function CreateFormattingStrippedCopy(paragraph As Paragraph) As Paragraph
        Dim newParagraph As Paragraph = TryCast(paragraph.CreateShallowCopy(), Paragraph)
        For Each item As Inline In paragraph.Inlines
            If TypeOf item Is Span Then
                Dim spanCopy As Span = TryCast(item.CreateDeepCopy(), Span)
                If spanCopy.Text <> String.Empty Then
                    'change ForeColor, FontSize and FontFamily if required
                    spanCopy.ForeColor = Colors.Black
     
                    newParagraph.Inlines.Add(spanCopy)
                End If
            End If
        Next
        Return newParagraph
    End Function
     
    Private Function GetParagraphsFromTable(table As Table) As List(Of Paragraph)
        Dim paragraphs As New List(Of Paragraph)()
        For Each child As Block In table.Children
            For Each block As Block In child.EnumerateChildrenOfType(Of Block)().ToList()
                If TypeOf block Is Paragraph Then
                    paragraphs.Add(DirectCast(block, Paragraph))
                ElseIf TypeOf block Is Table Then
                    paragraphs.Union(GetParagraphsFromTable(DirectCast(block, Table)))
                End If
            Next
        Next
        Return paragraphs
    End Function

    If you have any other questions, do not hesitate to contact us again.

    Regards,
    Martin
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  6. Nick Anderson
    Nick Anderson avatar
    40 posts
    Member since:
    May 2009

    Posted 05 Apr 2012 Link to this post

    Thanks, I modified your code slightly to loop through the table rows, and just create one paragraph per row instead of including a paragraph for every line. This lets the data still somewhat look like a table when pasted, instead of the data for each cell being inserted as it's own line. The only way i could find to seperate the spans from each other was to add empty spaces at the end of the text, which is fine.

    Now my users can use spaces to format the table the rest of the way, but there is no table formatting included, so the report still works.

    Private Sub richTextBox_CommandExecuting(sender As Object, e As Telerik.Windows.Documents.RichTextBoxCommands.CommandExecutingEventArgs) Handles richTextBox.CommandExecuting
      
            If e.Command.GetType Is GetType(Telerik.Windows.Documents.RichTextBoxCommands.PasteCommand) Then
                Dim fragment As DocumentFragment = ClipboardEx.GetDocument()
                If fragment IsNot Nothing Then
                    Dim document As RadDocument = fragment.ToDocument()
                    Dim newDocument As New RadDocument()
                    For Each section As Section In document.Sections
                        Dim sectionCopy As Section = TryCast(section.CreateShallowCopy(), Section)
                        For Each block As Block In section.Children
                            If TypeOf block Is Paragraph Then
                                Dim originalParagraph As Paragraph = DirectCast(block, Paragraph)
                                Dim strippedParagraph As Paragraph = Me.CreateFormattingStrippedCopy(originalParagraph)
                                If originalParagraph.IsEmpty OrElse Not strippedParagraph.IsEmpty Then
                                    sectionCopy.Blocks.Add(strippedParagraph)
                                End If
                            ElseIf TypeOf block Is Table Then
                                For Each row As TableRow In Me.GetRowsFromTable(DirectCast(block, Table))
                                    Dim newPara As New Paragraph
                                    For Each item As Span In GetSpansFromRow(row)
                                        newPara.Inlines.Add(item)
                                    Next
      
                                    sectionCopy.Blocks.Add(newPara)
                                Next
      
                                'For Each paragraph As Paragraph In Me.GetParagraphsFromTable(DirectCast(block, Table))
                                '    Dim strippedParagraph As Paragraph = Me.CreateFormattingStrippedCopy(paragraph)
                                '    If Not strippedParagraph.IsEmpty Then
                                '        sectionCopy.Blocks.Add(strippedParagraph)
                                '    End If
                                'Next
                            End If
                        Next
                        newDocument.Sections.Add(sectionCopy)
                    Next
      
                    newDocument.MeasureAndArrangeInDefaultSize()
                    Dim selection As New DocumentSelection(newDocument)
                    selection.SelectAll()
                    Me.richTextBox.InsertFragment(New DocumentFragment(selection))
                    e.Cancel = True
                End If
            End If
      
        End Sub
      
        Private Function CreateFormattingStrippedCopy(paragraph As Paragraph) As Paragraph
            Dim newParagraph As Paragraph = TryCast(paragraph.CreateShallowCopy(), Paragraph)
            For Each item As Inline In paragraph.Inlines
                If TypeOf item Is Span Then
                    Dim spanCopy As Span = TryCast(item.CreateDeepCopy(), Span)
                    If spanCopy.Text <> String.Empty Then
                        'change ForeColor, FontSize and FontFamily if required
                        'spanCopy.ForeColor = Colors.Black
      
                        newParagraph.Inlines.Add(spanCopy)
                    End If
                End If
            Next
            Return newParagraph
        End Function
      
        Private Function GetSpansFromRow(table As TableRow) As List(Of Span)
            Dim spans As New List(Of Span)()
            For Each child As Block In table.Children
                For Each block As Paragraph In child.EnumerateChildrenOfType(Of Paragraph)().ToList()
                    If TypeOf block Is Paragraph Then
                        For Each item As Inline In block.Inlines
                            If TypeOf item Is Span Then
                                Dim spanCopy As Span = TryCast(item.CreateDeepCopy(), Span)
                                If spanCopy.Text <> String.Empty Then
                                    spanCopy.Text &= "     "
                                    spans.Add(spanCopy)
                                End If
                            End If
                        Next
                    End If
                Next
            Next
            Return spans
        End Function
      
        Private Function GetRowsFromTable(table As Table) As List(Of TableRow)
            Dim rows As New List(Of TableRow)()
            For Each child As Block In table.Children
                For Each block As Block In child.EnumerateChildrenOfType(Of Block)().ToList()
                    If TypeOf block Is TableRow Then
                        rows.Add(DirectCast(block, TableRow))
                    End If
                Next
            Next
            Return rows
        End Function
      
        Private Function GetParagraphsFromTable(table As Table) As List(Of Paragraph)
            Dim paragraphs As New List(Of Paragraph)()
            For Each child As Block In table.Children
                For Each block As Block In child.EnumerateChildrenOfType(Of Block)().ToList()
                    If TypeOf block Is Paragraph Then
                        paragraphs.Add(DirectCast(block, Paragraph))
                    ElseIf TypeOf block Is Table Then
                        paragraphs.Union(GetParagraphsFromTable(DirectCast(block, Table)))
                    End If
                Next
            Next
            Return paragraphs
        End Function
  7. Ivailo Karamanolev
    Admin
    Ivailo Karamanolev avatar
    276 posts

    Posted 09 Apr 2012 Link to this post

    Hi,

    We're glad to hear you found your way around and made it work better for your case.
    If you need anything additional, feel free to contact us again.

    Regards,
    Ivailo Karamanolev
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

Back to Top
UI for WPF is Visual Studio 2017 Ready