Read RTFData?

Bonjour,

I read a plist file, written by a macOS app, in which there is a RTF data.
I can load it and after decodebase64 it, i have something like this :

rtfd����������������TXT.rtf����._���+�������W���{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600�{\fonttbl\f0\fnil\fcharset0 Geneva;}�{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}�{\*\expandedcolortbl;;\csgenericrgb\c0\c0\c0;}�\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0��\f0\fs24 \cf2 Advanced Text}����#�����������TXT.rtf�������`������������

I tried to put it in the RFTData property of a StyledText but the text property of the StyledText stay empty…

In Objective-c, if I do that :

    NSData *mRTFData = [variant objectForKey:@"RTFData"];
    NSAttributedString *mAttrStr = [[NSAttributedString alloc] initWithData:mRTFData options:@{ } documentAttributes:nil error:nil];
    NSString *mStr = [mAttrStr string];

I have the text.
How can I do the same with Xojo?

The first part of that text is not RTF, it looks like it has something to do with the .rtfd file type – strip it off. The RTF begins wtih

{\rtf1\ansi\ansicpg1252…

You might want to have a look at MacOSLib - it has functions to deal with RTF that used to be MUCH faster than Xojo’s build-in ones (by a factor of 100) and didn’t mangle the RTF text. Not sure if Xojo has ever improved their own functions.

Thanks to all!
I have removed characters before the first { and after the last } and it is OK.
I will also take a look at MacOSLib.

If you use MBS Xojo Plugins, you may check NSAttributedStringMBS class, which should be able to read those files.

Still, Eric’s Objective-c code looks to take care of rtfd. It would be nice if Xojo handled them the same way.

Could you make the original file available after taking out any personal information? I’d like to try something …

The original data is :
cnRmZAAAAAADAAAAAgAAAAcAAABUWFQucnRmAQAAAC5fAQAAKwAAAAEAAABXAQAAe1xydGYxXGFuc2lcYW5zaWNwZzEyNTJcY29jb2FydGYxNjcxXGNvY29hc3VicnRmNjAwCntcZm9udHRibFxmMFxmbmlsXGZjaGFyc2V0MCBHZW5ldmE7fQp7XGNvbG9ydGJsO1xyZWQyNTVcZ3JlZW4yNTVcYmx1ZTI1NTtccmVkMFxncmVlbjBcYmx1ZTA7fQp7XCpcZXhwYW5kZWRjb2xvcnRibDs7XGNzZ2VuZXJpY3JnYlxjMFxjMFxjMDt9ClxwYXJkXHR4NTYwXHR4MTEyMFx0eDE2ODBcdHgyMjQwXHR4MjgwMFx0eDMzNjBcdHgzOTIwXHR4NDQ4MFx0eDUwNDBcdHg1NjAwXHR4NjE2MFx0eDY3MjBccGFyZGlybmF0dXJhbFxwYXJ0aWdodGVuZmFjdG9yMAoKXGYwXGZzMjQgXGNmMiBBZHZhbmNlZCBUZXh0fQEAAAAjAAAAAQAAAAcAAABUWFQucnRmEAAAALwa8mC2AQAAAAAAAAAAAAA=

Is that enough for what you want?

To open the RTFD add the MacOSlib and the Additional Modules to your project.

MacOSlib has a readRTFD method that is an extension of a TextArea and returns a boolean

So all you have to do is either use CALL (if you don’t want to use the return value)

  #if TargetCocoa    

    Var file As FolderItem = Folderitem.ShowOpenFileDialog("Special/Any")

    Call t.ReadRTFDFromFile(file.NativePath)

  #else
    
    #pragma unused t
    
  #endif

or use if … end if:

  #if TargetCocoa    

    Var file As FolderItem = Folderitem.ShowOpenFileDialog("Special/Any")

    If t.ReadRTFDFromFile(file.NativePath) Then
        // your own stuff, eg add window to window menu
    else
      MessageBox "Could not open file."
    End If

  #else
    
    #pragma unused t
    
  #endif

Best wrap it into an extension method that you can call from anywhere:

Public Sub OpenRTFD(extends t as TextArea)
  
  #if TargetCocoa
    
    Var file As FolderItem = Folderitem.ShowOpenFileDialog("Special/Any")
    
    If file Is Nil Then
      // user cancelled
      
    Else
      
      Try
        
        Call t.ReadRTFDFromFile(file.NativePath)
        
        // or
        ' If t.ReadRTFDFromFile(file.NativePath) Then
        ' 
        '  End If
        
      Catch e As IOException
        // unable to open file
      End Try
      
    End If
    
    
  #else
    
    #pragma unused t
    
  #endif
  
End Sub

MacOSlib also has a WriteRTFDToFile extension method …

In the TextArea Open event add:

Sub Open() Handles Open
  Me.UsesFindPanel = True
  me.UsesFindBar = True
  me.UsesInspectorBar = True
End Sub

Thank you Markus!

P.S. Don’t forget that in the menubar you need to set the Find menu to CocoaMenuItemFind if you want to use the find bar …