Changing RichTextItem fontstyle and size

I’ve been attempting to write some LotusScript code to parse a RichTextItem and change all the text content to DefaultSansSerif size 10 … yep, you guessed it, so it will display correctly on the web! Sigh!

I wrote a routine (cribbed heavily from the Notes help) - see below. However when I run this routine, and save the backend document and then reload the UIDoc, I get an NSD crash in the client.

I have see Andre Guirard’s post (Hi Andre - the kiwi’s back!) about how to change the value in an RTF field and refresh without saving the document. So I’ll try incorporating that approach next. However the client shouldn’t be able to be crashed should it!!??

Any help with the code below would be VERY VERY welcome! :wink:

Thanks all,

Regards

Mark

Here’s the call to the subroutine:

Sub Click(Source As Button)

Dim s As New NotesSession

Dim ws As New NotesUIWorkspace

Dim uidoc As NotesUIDocument

Dim rtitem As NotesRichTextItem



Set uidoc=ws.CurrentDocument

Dim doc As NotesDocument

Set doc=uidoc.Document



If uidoc.IsNewDoc Then

	Call uidoc.Save

	Call uidoc.Reload		

End If



Set rtitem=doc.GetFirstItem("RichText2")	

Call SetRTFont(doc,rtitem)

Call doc.Save(True,False)



'Call uidoc.Refresh

'Call uidoc.Reload

REM NOTE : commented above out to prevent NSD crash … now hangs instead!!!

End Sub

Here’s the Subroutine itself

Sub SetRTFont(doc As NotesDocument, rtitem As NotesRichTextItem)

Dim rtnav As NotesRichTextNavigator

Dim rtnav2 As NotesRichTextNavigator

Dim rtrange As NotesRichTextRange

Dim rtrange2 As NotesRichTextRange

Dim currstyle As NotesRichTextStyle



'Find paragraphs in rtitem

Set rtnav = rtitem.CreateNavigator



If rtnav.FindFirstElement(RTELEM_TYPE_TEXTPARAGRAPH) Then

	Set rtrange = rtitem.CreateRange

	Set rtnav2 = rtitem.CreateNavigator

	Set rtrange2 = rtitem.CreateRange

	count% = 0

	Do

		count% = count% + 1

  		' Set range for paragraph

		Call rtrange.SetBegin(rtnav)

		Call rtrange.SetEnd(rtnav)

		

		' Create navigator for paragraph

		Set rtnav2 = rtrange.Navigator

		

		' Find text runs in paragraph

		If rtnav2.FindFirstElement(RTELEM_TYPE_TEXTRUN) Then

			count2% = 0

			msg$ = ""

			Do

				count2% = count2% + 1

      			' Set range for text run

				Call rtrange2.SetBegin(rtnav2)

				' Now get the existing style of the run

				Set currstyle=rtrange2.Style

                                    ' Change font face and size to FONT_HELV and size 10

				currstyle.NotesFont=FONT_HELV

				currstyle.FontSize=10

                                    ' And replace it again

				Call rtrange2.SetStyle(currstyle)

			' Get next text run

			Loop While rtnav2.FindNextElement(RTELEM_TYPE_TEXTRUN)

		End If

		

	' Get next paragraph

	Loop While rtnav.FindNextElement(RTELEM_TYPE_TEXTPARAGRAPH)

Else

	Print "No text in Rich Text field: " & rtitem.Name ,, "No text"

End If

End Sub

Subject: Changing RichTextItem fontstyle and size - one for Andre Guirard?

Andre -

I know you’re the guru on this one … any suggestions?

Cheers from Down-Under!

Mark

Subject: RE: Changing RichTextItem fontstyle and size

You might try doing this from a view instead of in an open document. You might also try in version 6.5.5 or 7.0.1.

No, the client shouldn’t crash, but the client doesn’t always seem to know that. Please create a small demo database that demonstrates the problem and go thru Lotus support. If they create an SPR, please make sure they don’t categorize it under “Design”. This sounds like a “LotusScript - Front-end” issue.

Subject: RE: Changing RichTextItem fontstyle and size

Hi Andre

I actually did get it working in a little test app using your recommended method of refreshing the UI document.

However not content with that, I’ve made further progress! :wink:

I thought I’d abstract the processes into a couple of script libraries so I can reuse the functions - and also so I can reuse the function for changing font size/style/colour from backend as well as from the UI. So I created one script library for handling the back-end process of updating the RTF field, and one for managing the UI end of things.

The UI script library calls the back-end sub (from the backend library) to change the font style, size and colour of the text in the RTF field, then calls a sub from the UI library to refresh the document (as per your method).

And it now NSD’s the client application every time!! :wink:

Will see if I can figure out what’s triggering it, and if I can get it working, I’ll post the code here - might be useful to someone?

Cheers

Mark

Subject: NotesRichText classes seem VERY buggy!

Well the state of play is that after a full day of teeth gnashing and head slapping, I was forced to give up on getting the code working in the front-end UI. It continually crashed the client (6.5.4) with NSD errors.

So I concentrated on getting the code to work in the backend by running it from a PostSave event.

What I’m wanting to do, is to check the contents of a RichTextField, and ensure that all the fonts used are DefaultSansSerif, size 10, black. This is so when the field is displayed on the web, Domino doesn’t get excited and stick loads of tags in the content - that way we can control the display of the text properly using CSS.

So I run the code (see below) from the PostSave event, and (good news!) it works perfectly … well ALMOST perfectly. It does indeed change the font to DefaultSansSerif size 10. But if any of the text has a different font color set, it REFUSES (ARRRGH) to change the colour of the font to black.

If you want to try this out, create a simple form with a RichTextField in it, and add these routines below. The setRTStyle subroutine I put in a script library - you’ll need to add %Include “LSCONST.LSS” to the script library or form globals too.

What’s interesting, is that when you step through the code. When the code hits a textrun that is in a different fontcolor, the code correctly changes the fontcolor, but it simply DOES NOT get applied when you apply the style using SetStyle.

That’s GOT to be a bug!

Any help/suggestions/workarounds welcome. My forehead’s flat from banging it against the table!

Cheers

Mark

Here’s how I call the routine:

Sub Postsave(Source As Notesuidocument)

Dim currentDoc As NotesDocument

Dim ritem As NotesRichTextItem	



Set session  = New NotesSession

Set currentDoc = Source.Document

Set ritem=currentDoc.GetFirstItem("RichText2")

Call SetRTStyle(ritem)	

Call currentDoc.Save(True,False)

End Sub

And here’s the routine itself:

%REM

This subroutine will set the font style and size of a rich text field to Default Sans Serif size 10, colour black

%END REM

Sub SetRTStyle(rtitem As NotesRichTextItem)

Dim Status As String, Count As Integer, elementfound As Boolean

Dim rtnav As NotesRichTextNavigator

Dim rtrange As NotesRichTextRange

Dim currstyle As NotesRichTextStyle

Dim isitalic As Boolean, isbold As Boolean, isunderline As Boolean



On Error Goto Errorhandler



'Find paragraphs in rtitem

Count=0

Set rtnav = rtitem.CreateNavigator

elementfound=rtnav.FindFirstElement(RTELEM_TYPE_TEXTRUN) 

While elementfound

	Count=Count+1

	Set rtrange = rtitem.CreateRange	

		' Set range for paragraph

	Call rtrange.SetBegin(rtnav)

	Call rtrange.SetEnd(rtnav)

	Set currstyle=rtrange.Style

	isbold=currstyle.Bold

	isItalic=currstyle.Italic

	isUnderline=currstyle.Underline

	

	' Shouldn't really need this bit below, as leaving unchanged should work OK.

	If isbold Then

		currstyle.Bold=True

	Else

		currstyle.Bold=False

	End If

	If isitalic Then

		currstyle.Italic=True

	Else

		currstyle.Italic=False	

	End If

	If isUnderline Then

		currstyle.Underline=True

	Else

		currstyle.Underline=False	

	End If

	

	' Now the important bit - set the defaults we want

	' Set defaults for new style - set font to default sans-serif (FONT_HELV), Black, 10pt

	currstyle.NotesFont=FONT_HELV

	currstyle.FontSize=10

	currstyle.NotesColor=COLOR_BLACK

	

	Call rtrange.SetStyle(currstyle)

	Set currstyle=Nothing

	

	' Get next text run

	elementfound=rtnav.FindNextElement(RTELEM_TYPE_TEXTRUN)

Wend



Call rtitem.Update ' Just in case this might make a difference (it didn't!!)

Print "Processed " & count & " text runs"

Done:

Exit Sub

ErrorHandler:

status$ = Error() & " (Error number " & Err() & " at line " & Erl()  & ")"

Print "SetRTStyle: "  & status$ 	

Resume Done

End Sub

Subject: RE: NotesRichText classes seem VERY buggy!

I’m afraid that if you search these forums, you won’t have a hard time getting people to agree with that (buggy rich text classes). I know that I am biased, but perhaps it is time to try out our Midas Rich Text LSX, which allows much more flexibility and stability. Midas is also a lot less verbose. If I understand what you are doing, the Midas code to do it would be the following, which would have the additional advantage that the document wouldn’t have to be saved at all unless you wanted:

‘(Options)’

Uselsx “*lsxrtc”

Sub Click(Source As Button)

Dim s As New NotesSession

Dim ws As New NotesUIWorkspace

Dim uidoc As NotesUIDocument

Dim rtitem As New GeniiRTItem

Dim mode As Boolean



Set uidoc=ws.CurrentDocument

Dim doc As NotesDocument

Set doc=uidoc.Document

mode = uidoc.EditMode

If mode Then Call uidoc.Save

uidoc.Close



Call rtitem.ConnectBackend(doc.Handle, "RichText2", True)

rtitem.Everything.Font = "10pt Default Sans Serif"

Set uidoc = ws.EditDocument(mode, doc)

End Sub