This is a migrated thread and some comments may be shown as answers.

Paste Plain Text

5 Answers 254 Views
RichTextBox
This is a migrated thread and some comments may be shown as answers.
Nick Anderson
Top achievements
Rank 1
Nick Anderson asked on 15 Mar 2012, 08:35 PM
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

5 Answers, 1 is accepted

Sort by
0
Martin Ivanov
Telerik team
answered on 20 Mar 2012, 04:38 PM
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 >>
0
Nick Anderson
Top achievements
Rank 1
answered on 02 Apr 2012, 05:20 PM
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
0
Accepted
Martin Ivanov
Telerik team
answered on 05 Apr 2012, 04:23 PM
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 >>

0
Nick Anderson
Top achievements
Rank 1
answered on 05 Apr 2012, 08:29 PM

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
0
Ivailo Karamanolev
Telerik team
answered on 09 Apr 2012, 12:57 PM
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 >>

Tags
RichTextBox
Asked by
Nick Anderson
Top achievements
Rank 1
Answers by
Martin Ivanov
Telerik team
Nick Anderson
Top achievements
Rank 1
Ivailo Karamanolev
Telerik team
Share this question
or