TextArea Paste Question

I’m writing a Markdown editor based on MarkdownKit and a subclass of Xojo’s built-in TextArea. Things work fine except if I paste text into the TextArea. Is there a way when pasting into a TextArea using the default macOS cmd-V keystroke to paste in only plain text? I have a feeling that the styles are being pulled in with the paste and that’s messing things up.

For some context, my app is re-parsing the contents of the TextArea every second (if the text has changed), converting it into a Markdown abstract syntax tree and then walking that tree, pulling the start and end positions of each element and styling them using TextArea.StyledText.SomeProperty(start, length). Before each parse, I clear the styles in the TextArea in a method within the TextArea subclass like this:

// Cache the length of the text.
Var length As Integer = StyledText.Text.Length

Me.StyledText.Bold(0, length) = False
Me.StyledText.Italic(0, length) = False
Me.StyledText.Underline(0, length) = False
Me.StyledText.Size(0, length) = StyleTextSize
Me.StyledText.TextColor(0, length) = StyleTextColor

Any help greatly appreciated.

Have you tested your theory with shift command v (Mac) or edit>>paste special ?

Would prove your theory right if you did only paste plain text and it worked.

If you subclass text area and implement the edit menu handlers in your subclass you can do just about anything you want with the text

OK I’ve done that and put this in the EditPaste menu handler for my TextArea subclass:

Var c As New Clipboard
Var s As String = c.Text
Me.Text = s
Return True

Sometimes it works and is pasted in with the same font family and size as the preceding text but sometimes (and I’m struggling to track down where) the pasted text is in a different font. I’m guessing this might have something to do with StyleRuns?

On the subject of StyleRuns, what is the best way to remove all styles from the text within a TextArea without affecting the actual text in the TextArea? I’ve tried looping through and calling StyledText.RemoveStyleRunAt() but that ends up removing the text in the TextArea. If I cache the text in the TextArea before removing the style runs and then assign the cached text back to StyledText.Text then the TextArea will scroll to the top as if I’ve just pasted new text into it.

not tested… but I think

ta.styledText=ta.text

or something like that… off the top of my head

Depending on where the text is coming from you may have several options
Many apps put more than one “flavour” on the clipboard
And you can pick and choose which one you want to use

  1. see if there is a plain text variant on the clipboard
     dim c as new ClipBoard
     if c.RawDataAvailable("public-utf8-plain-text") then
          // use this text
          me.text = c.RawData("public-utf8-plain-text")
     end if
  1. convert any other text to plain text
     dim c as new ClipBoard
     dim s as new styledText
     dim r as new StyleRun
     r.text = c.Text
     s.appendStyleRun r
     dim rawText as string = s.text

You can combine the two

The downside is that Edit > Paste is handled one way and a right click + paste goes somewhere else so you may have to also override that contextual menu

FWIW I find ClipBoardViewer a very handy tool for looking at all the macOS clipboards (there are several)
You can see drag items, font and all the different flavours of data on the clip board that are there

EDIT : I even have a Zip of it anyone wants it
There is another on the market from Langui.Net or something but its not the same one
This old one is from Apple
Its a fat binary

1 Like

Norman hit the right direction (IMHO):

you have to know what you have in the Clipboard (at developement time) and implement the correct code.

I copied from Safari some characters from the above text. Then
In Script Editor, type:

Return Clipboard Info

Execute and you will get something like:

{{« class weba», 869}, {« class RTF », 376}, {« class HTML», 574}, {« class utf8», 102}, {« class ut16», 204}, {uniform styles, 144}, { string , 101}, { scrap styles , 22}, { Unicode text , 204}, {uniform styles, 144}, { scrap styles , 22}}

You have all of these in the Clipboard and you do not know what is pasted, so…

I forgot how to get the class I want from what is available (in AppleScript).
In Xojo, you must use RawData and pass the 4 letters code (Class name like weba, html, utf8, and so on).

1 Like

You can use the UTI as well like “pulic.utf8-plain-text”

What I cant tell you is which on Xojo WILL select when there are several and you ask for “Text”

1 Like

I do not used UTI here, yet.

Usually, people do not know how Clipboard works and what is really stored in the Clipboard (since the last 40 years…).

I recall Adobe Photoshop 1.5 who had in the Clipboard Text and Image and I was happy with that at save image time (paste the file name and modify it a bit) when I was dealing with images so may years ago (35 years ago ?)

After selecting your reply and then checking clip board viewer look at all the different types that are on there :stuck_out_tongue:
Some are still the old 4 char code types
A lot are not

1 Like

OK - All of these tips are super helpful and have taught me a lot about the clipboard!

The problem is my issue persists. I think the problem is actually with emojis and the Xojo TextArea. There is definitely a bug somewhere in the Xojo control. It seems to incorrectly report the length of emojis.

Does @bkeeney’s FTC handle emojis well?

No idea
I’d ask @bkeeney

What sort of issues are you seeing with emoji’s ?

Emoji’s are ‘special’. Martin T did some work for us on FTC 4 (now suspended for all intents and purposes) and I’m not entirely sure what the end result was. I know that there’s a new String.Characters iterator in 2020 R1 that Martin was happy with that actually fixed the issue with iterating emoji’s. The Xojo Text character iterator did it properly too and he put in a request to get that transferred over to String and Xojo actually did it.

Ah I have vague recollection of that
So a person could go through Xojo.Text in current versions and eliminate emoji’s before putting the pasted data into the text area

Thanks for pointer towards String.Characters @bkeeney - that actually fixes another bug I was seeing :smile:.

Take a look at the video below. Is this a bug or am I misunderstanding how to use a TextArea's StyledText object? Whenever the button is clicked, I am toggling the colour of the TextArea's StyledText between start position 0 for a length of 4 characters using TextArea1.StyledText.TextColor(0, 4) = someColor.

As you can see in the video, if the text in the TextArea is "ABCD" then it works however if I delete the "A" and replace it with the :grinning: emoji (using the Touch Bar on my Mac) then only letters "BC" are toggled to red. I would expect "BCD" to go red. It looks like the StyledText object is treating the emoji as two characters.

I’ve uploaded the demo app as a binary Xojo project here (saved with Xojo 2019 r3.1). The bug is present in 2020r1 too.

ABCD is 4 characters

:grinning:BCD is 5 characters (bytes)

Looks like Styledtext is using LENB not LEN

I’d tend to agree with daves assessment that styled text seems to be counting BYTES not “characters” (or grapheme clusters)

Ah. Could be. That smells like a bug or at least a leftover from the “pre-Text” era. I may be able to work around that if that’s the case…

almost seems like you need to properly count the “characters” - which might require Text until they ship a version that does that right in String
and then once you have that count convert it to BYTES IF Styled text is indeed counting bytes

Some tests to prove / disprove the theory that styled text is indeed counting bytes might be in order