Macro to get list of hyperlinks from Navigator

I have written a Writer macro that uses .createEnumeration() to give me the URLs in the current document. Unfortunately it sometimes returns multiple elements per link with the same URL. Its likely a bug and it happens randomly. For example, the last time it occurred, the link that spanned four words, enumeration returned two links with the second link being the last letter of the text.

When I look at the document navigator, the links are shown correctly. Pressing enter on the links with the above problem highlights the link correctly.

Is there a way to access the list of links that the navigator maintains so I don’t have to use the enumeration method?

Thanks,
C

Please, could you upload an example of such a document and the mentioned macro?

urlbug.odt (18.2 KB)

Here is sample doc and the code. I think I found the bug. It occurs when you edit the text of the link from the document itself rather than the link dialog. Simply delete and insert a letter and the link breaks up.

Also, if you close the doc and reopen it, the Navigator also show the link as broken up. :frowning:

function getNextHyperlink()

	Dim LF ' for a line feed
	LF = Chr(10) ' at top of macro where LF will be used

	Dim oParEnum, oParElem
	Dim oEnum, oElem
	
	Dim oTextCurs, oTC, oVC
	
	oVC = ThisComponent.CurrentController.getViewCursor()
	oTextCurs= ThisComponent.Text.createTextCursorByRange(oVC.getEnd())
	oTextCurs.gotoEnd(true)
	 
	oParEnum = thisComponent.getText().createEnumeration()
	do While oParEnum.hasMoreElements
		oParElem = oParEnum.NextElement
		
		oEnum = oParElem.createEnumeration()
		
		Do While oEnum.hasMoreElements()
			
			oElem = oEnum.nextElement()
			
			Dim t As string: t = oElem.getString() 
			Dim u as string: u = oElem.HyperLinkURL
						
			If oELem.HyperLinkURL <> "" Then
				oTC = ThisComponent.Text.createTextCursorByRange(oElem)
								
				msgbox "Text: " & t & LF & "URL: " &u

				'getNextHyperlink = oTC
				'Exit function
			End If			
		loop
	loop
	
end function
1 Like

If I open your example, I see 3 hyperlinks in Navigator, and your macro also returns 3 hyperlinks, so it seems correctly.

How did you create the hyperlink: Its likely a bug and its appens randomly.? Is it weirdly Pasted hyperlink via CtrlCV from other program?
Because if I wrote the Url address, it changes to the correct hyperlink. And the same when I used Insert/ Hyperlink.

LibreOffice 7.3.1.3 Win10x64

I created the link using the Hyperlink dialog on Windows. Then I inserted a character (in the text of the link from Writer not from the dialog) and the code now finds three duplicate links one after the other. Close and reopen the document and Navigator now also shows multiple links with the link text in pieces. I checked with the latest stable version 7.2.6.2 (x64) and it occurs there too. I checked with the earliest version of LO and couldn’t reproduce it there. So it appear a bug that was introduced after the split from OO. I’ll keep checking to locate the version it was introduced in and report it.

Probably macro will be unsafe, but I don’t know how to get Navigator as object by some better way :frowning:

Sub getHyperlinksFromNavigator
	dim navigatorName$, tk as object, n%, topwindow as object, o as object, i%, oLink as object, document as object, dispatcher as object
	
	document=ThisComponent.CurrentController.Frame
	dispatcher=createUnoService("com.sun.star.frame.DispatchHelper")
	dim args1(0) as new com.sun.star.beans.PropertyValue
		args1(0).Name="Navigator"
		args1(0).Value=true
	dispatcher.executeDispatch(document,  ".uno:Navigator",  "",  0,  args1() ) 'show Navigator	window (from macro recorder)
	
	rem source: https://forum.openoffice.org//en/forum/viewtopic.php?f=20&t=98738
    Globalscope.BasicLibraries.loadLibrary("Tools")
    navigatorName=GetRegistryKeyContent("org.openoffice.Office.UI.Sidebar/Content/PanelList/SwNavigatorPanel").Title
    tk=Stardesktop.CurrentFrame.ComponentWindow.Toolkit
    for n=0 to tk.TopWindowCount -1 'iterate all windows
        topwindow=tk.getTopWindow(n)
        if topwindow.AccessibleContext.AccessibleName=navigatorName then 'window is Navigator
            o=topwindow.AccessibleContext.getAccessibleChild(0).AccessibleContext.getAccessibleChild(0).AccessibleContext.getAccessibleChild(0).AccessibleContext.getAccessibleChild(0).AccessibleContext.getAccessibleChild(1).AccessibleContext.getAccessibleChild(0).getAccessibleChild(7) 'object with hyperlinks from Navigator - I know it is wacky :-(
            for i=0 to o.AccessibleChildCount-1
            	oLink=o.getAccessibleChild(i) 'hyperlink
            	msgbox oLink.Text
            next i
            exit sub
        end if
    next n
End Sub
1 Like

Neat. Unfortunately, I found that closing and opening the doc will update the links in Navigator and shows them in pieces like my original code. :frowning: