Macro to insert hyperlinks not working as it used to

I have a macro in calc that used to work in 7.3.2, but gives different results since I installed 24.2.3.

The macro clears the selected cell, inserts a hyperlink, then goes back to that cell, inserts a Paragraph_Break (hard return) and insets a second hyperlink. All used to work great.

This is the first I’ve run the macro since updating to 24.2.3. Now it clears the cell, inserts the first hyperlink, but when it goes back to the cell to add the second, the Paragraph_Break gets added, but the second hyperlink overwrites the first hyperlink and the break is after the only hyperlink remaining.

If I put a break point anywhere in the debug window, say the very first line of code that defines the sub, then continue the macro and let it finish, it works fine. But if I don’t pause it in the debug, it doesn’t work right. Seems like it’s a focus thing, but like I said, it used to work fine. Here’s the piece of code that actually inserts the hyperlinks and the break:

Sub InsertHyperlink(LinkURL as String, LabelText as String, IsFirst as Boolean)

dim oFrame				as Object
dim dispatcher		as Object
dim txt						as Object
dim tc						as Object

oFrame		= ThisComponent.CurrentController.Frame
dispatcher	= createUnoService("com.sun.star.frame.DispatchHelper")

if IsFirst Then		' Before inserting the first hyperlink, clear the selected cell
	dispatcher.executeDispatch(oFrame, ".uno:ClearContents", "", 0, Array())
Else
	' Edit the selected cell to insert a paragraph break before inserting the next hyperlink
	txt	= ThisComponent.CurrentController.Selection.text
	tc		= txt.CreateTextCursorByRange(txt.end)		' Create a text cursor at the end of the text in the cell
	'tc.collapsetoend								' Move text cursor to the end of the text

	' Insert the hard return at text cursor position
	txt.insertControlCharacter(tc, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, True)
end if

dim HypData(4) as new com.sun.star.beans.PropertyValue
' Data for hyperlink
HypData(0).Name	= "Hyperlink.Text"
HypData(0).Value	= LabelText
HypData(1).Name	= "Hyperlink.URL"
HypData(1).Value	= ConvertToURL(LinkURL)				' Link needs to be in URL format
HypData(2).Name	= "Hyperlink.Target"
HypData(2).Value	= ""
HypData(3).Name	= "Hyperlink.Name"
HypData(3).Value	= ""
HypData(4).Name	= "Hyperlink.Type"
HypData(4).Value	= 1

dispatcher.executeDispatch(oFrame, ".uno:SetHyperlink", "", 0, HypData())

End Sub

Can anyone show me the error of my ways? I’d like to blame something that’s changed, but my track record isn’t good, so if I’ve done something stupid, let me know.

And what is the (simplified) code that actually uses that function, so that the result can be put into a library and run, to reproduce the problem?

E.g., running this code in an empty spreadsheet in Version: 24.2.4.2 (X86_64) / LibreOffice Community
Build ID: 51a6219feb6075d9a4c46691dcfe0cd9c4fff3c2
CPU threads: 24; OS: Windows 10.0 Build 22631; UI render: default; VCL: win
Locale: ru-RU (ru_RU); UI: en-US
Calc: CL threaded

sub tstInsH
  InsertHyperlink("www.foo.bar", "first", true)
  InsertHyperlink("www.bar.baz", "second", false)
end sub

gives me the expected

image

image

Try to put a WAIT instead of a breakpoint. Slowing the code is a work-around, but Calc may need some time to check references etc. So Mikes test may not trigger this, but you sheet and hardware can do…

From https://wiki.documentfoundation.org/Documentation/BASIC_Guide#Error_Handling

There are three examples over on Live LibreOffice Python UNO Examples that may be helpful.


Calc Convert link text to Hyperlink, Intercept Context Menu and Cell Texts all work with hyperlinks in Calc.

OK, I don’t get an error, so I don’t think the error handler is the way to go.

As for the Wait statements, I sprinkled some Wait 1000 statements around the section of the Else and the insertion of the hyperlink. Actually, I put one between each line of code. Same result.

As for the code that calls this code, here it is:

' Now insert the 2 hyperlinks into the invoice cell
' Make pointers to the invoice cell and the one to the left of it
oCellInv		= oSheet.getCellByPosition(InvoiceCol - 1,         SelRow - 1)
oCellOther	= oSheet.getCellByPosition((InvoiceCol - 1) - 1, SelRow - 1)

' Select the invoice column of the new row
ThisComponent.CurrentController.Select(oCellInv)

' Insert the first hyperlink for the agency's copy of the invoice
InsertHyperlink(FNameComm, BookNum, True)


' Select another cell to stop editing of the invoice cell,
' then reselect the invoice cell to put the second link in.
ThisComponent.CurrentController.Select(oCellOther)
ThisComponent.CurrentController.Select(oCellInv)
' Insert the second hyperlink for the client's copy of the invoice
InsertHyperlink(FNameNoComm, "Client", False)

' Select another cell to stop the editing
ThisComponent.CurrentController.Select(oCellOther)

I even put a Wait 1000 in the above code between the two lines that select a different cell then go back to the cell for the second hyperlink. It’s slow enough that I can watch it actually go to the other cell, then go back to the insertion cell. It’s hard to tell, but it looks like it inserts the hard return after the first hyperlink, but then replaces the first link with the second link, leaving the hard return at the end of the cell contents.

I went one step further. After the hard return insertion, I added

	txt.String = txt.String & "here"

The ‘here’ is where it should be, on the next line after the first link, but the second link still replaces the first link. I end up with:

Client (this being a hyperlink pointing to the correct document for the second link)
here

I’m baffled, but if there are any suggestions or questions, please let me know.

So I did a little more testing. I do most of my work on my desktop and it turns out that I went from 7.3.2.2 to

Version: 24.2.3.2 (X86_64) / LibreOffice Community
Build ID: 433d9c2ded56988e8a90e6b2e771ee4e6a5ab2ba
CPU threads: 8; OS: Windows 10.0 Build 22631; UI render: Skia/Raster; VCL: win
Locale: en-US (en_US); UI: en-US
Calc: CL threaded

I went to my laptop which also has 24.2.3.2 but inslallers for both 7.6.6.3 and 7.3.2.2. So I uninstalled 24, install 7.6 and it worked the same, in that the second link overwrites the first. Then I went back to 7.3.2.2 and it worked how I remember it. I got 2 hyperlinks in the same cell and both worked. The second did NOT overwrite the first.

So it looks like something changed between 7.3.2.2 and 7.6.6.3. I haven’t a clue what to do with this information, but hopefully someone in the know can look into it.

QA/Bibisect - The Document Foundation Wiki is you friend.
(may look a bit intimidating at first, but all in all, it’s workable :wink: )

Just updated LO to:

Version: 24.2.4.2 (X86_64) / LibreOffice Community
Build ID: 51a6219feb6075d9a4c46691dcfe0cd9c4fff3c2
CPU threads: 8; OS: Windows 10.0 Build 22631; UI render: Skia/Raster; VCL: win
Locale: en-US (en_US); UI: en-US
Calc: CL threaded

Still does the same thing as 24.2.3.2. Second hyperlink overwrites the first.

fpy, you must be a sadist. That was painful just figuring out how to get that all to run.

Anyway, I finally did get it to run and here’s what I got:

C:\Utils\Git\LO74\win64-7.4>git bisect good
03c7263ddb8b1548ff4b1fde53df380a214164c6 is the first bad commit
commit 03c7263ddb8b1548ff4b1fde53df380a214164c6
Author: Norbert Thiebaud <nthiebaud@gmail.com>
Date:   Thu Apr 7 02:53:28 2022 -0700

    source sha:803c9a6f8d8681e1862e4132dbbc8cdb2f61b7b6

    source sha:803c9a6f8d8681e1862e4132dbbc8cdb2f61b7b6

 instdir/program/sclo.dll    | Bin 17074688 -> 17075200 bytes
 instdir/program/setup.ini   |   2 +-
 instdir/program/version.ini |   2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)

This all means nothing to me.

So what now??

:congratulations:

that’s a free ticket to your bugzilla journey :
from 803c9a6f8d8681e1862e4132dbbc8cdb2f61b7b6 - core - Gitiles
to 80043 – EDITING: Insert hyperlink dialog wont use text in highlighted cell as hyperlink text

so, you can proudly open a NEW bug with a brief summary of yours posts …
and wait if it rings a bell to the guilty commiter :wink:

Thanks fpy. I think it was a short journey but I never would have gotten there without you pointing me in the right direction.

After looking at the information on the code changes for inserting a hyperlink in a cell that already has text, it seemed that what they wanted and what I wanted were in conflict with each other. But in looking at what they did and their description, it stated that the cell was selected with a single click. So since I’m not selecting the cell manually, why wasn’t it being seen as edit mode instead of a single click? I thought that the cell would have been in edit mode since I’d inserted the hard return, but apparently not. So I found this:

dispatcher.executeDispatch(StarDesktop.ActiveFrame, ".uno:FocusInputLine", "", 0, Array())

in another discussion thread. I added that to my code after inserting the hard return and now the cell is seen as being in edit mode and the second hyperlink is inserted after the hard return and doesn’t replace the cell contents.

My sub now looks like this:

'***********************************************************************
' Sub InsertHyperlink
' Inserts a hyperlink in the selected cell.
' Leaves the cell "open" for editing so the caller must move to another
' cell to close the editing of the selected cell.
'***********************************************************************
Sub InsertHyperlink(LinkURL as String, LabelText as String, IsFirst as Boolean)

dim oFrame				as Object
dim dispatcher		as Object
dim txt						as Object
dim tc						as Object

oFrame		= ThisComponent.CurrentController.Frame
dispatcher	= createUnoService("com.sun.star.frame.DispatchHelper")

	' Data for hyperlink
dim HypData(4) as new com.sun.star.beans.PropertyValue
HypData(0).Name	= "Hyperlink.Text"
HypData(0).Value	= LabelText
HypData(1).Name	= "Hyperlink.URL"
HypData(1).Value	= ConvertToURL(LinkURL)				' Link needs to be in URL format
HypData(2).Name	= "Hyperlink.Target"
HypData(2).Value	= ""
HypData(3).Name	= "Hyperlink.Name"
HypData(3).Value	= ""
HypData(4).Name	= "Hyperlink.Type"
HypData(4).Value	= 1

if IsFirst Then		' Before inserting the first hyperlink, clear the selected cell
	dispatcher.executeDispatch(oFrame, ".uno:ClearContents", "", 0, Array())
Else
	' Edit the selected cell to insert a paragraph break before inserting the next hyperlink
	txt	= ThisComponent.CurrentController.Selection.text
	tc		= txt.CreateTextCursorByRange(txt.end)		' Create a text cursor at the end of the text in the cell

	' Insert the hard return at text cursor position
	txt.insertControlCharacter(tc, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, True)
	
	' Now put the cell in "edit" mode so the hyperlink is inserted instead of replacing cell content
	dispatcher.executeDispatch(StarDesktop.ActiveFrame, ".uno:FocusInputLine", "", 0, Array())
end if

	' Now insert the hyperlink (first or second)
	dispatcher.executeDispatch(oFrame, ".uno:SetHyperlink", "", 0, HypData())

End Sub

I guess this was a long-winded way of saying that my macro works again and no bug report is needed (IMHO).

Thanks again for your help fpy.

3 Likes