[Solved] Extension uninstall cleanup hook

Discussions about using 3rd party extension with OpenOffice.org
Post Reply
Berwyn
Posts: 6
Joined: Thu May 11, 2023 5:41 am

[Solved] Extension uninstall cleanup hook

Post by Berwyn »

Hello,

TLDR: Is there a way to run cleanup code when an extension is uninstalled?

I am the author of the WordCount Bookmarked Sections extension. It sets up a function to run OnSave event, using the code below. But it turns out that when someone uninstalls my extensions, that OnSave event is still set and when you save it causes an error. How can I make the extension manager run my cleanup code to remove the OnSave event during uninstallation?

I know how to write the cleanup function. I just can't get LibreOffice to call it during uninstallation.

My setup code is:

Code: Select all

Sub setup_on_save()
	' Call this subroutine to connect the LibreOffice "Save Document" event to the Basic macro `on_save()`.
	' It needs to be added to globalEventBroadcaster instead of to ThisComponent because
	' otherwise libreoffice produces a warnings that this document has macros.
	Dim aProps(1) As New com.sun.star.beans.PropertyValue
	aProps(0).Name		= "EventType"
	aProps(0).Value		= "Script"
	aProps(1).Name		= "Script"
	aProps(1).Value		= "vnd.sun.star.script:Wordcounter.wordcount_sections.on_save?language=Basic&location=application"
	oGlobalEventBroadcaster = GetDefaultContext().getByName( "/singletons/com.sun.star.frame.theGlobalEventBroadcaster" )
	oGlobalEventBroadcaster.Events.replaceByName("OnSave", aProps())
End Sub
Last edited by Hagar Delest on Tue Jun 13, 2023 8:33 am, edited 1 time in total.
Reason: tagged solved.
I'm using Libreoffice v7.5.2.2 on Linux Mint
JeJe
Volunteer
Posts: 2764
Joined: Wed Mar 09, 2016 2:40 pm

Re: Extension uninstall cleanup hook

Post by JeJe »

Could your extension add the onSave event sub in the the User Standard library after installation - eg on first running of the extension - then within that sub it tests for and reassigns the event if the extension has been uninstalled?

Edit:
Or/and provide an uninstall script the user has to use instead of the inbuilt extensions dialog.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
Berwyn
Posts: 6
Joined: Thu May 11, 2023 5:41 am

Re: Extension uninstall cleanup hook

Post by Berwyn »

Really? Can a macro add itself to another library? How?
I'm using Libreoffice v7.5.2.2 on Linux Mint
JeJe
Volunteer
Posts: 2764
Joined: Wed Mar 09, 2016 2:40 pm

Re: Extension uninstall cleanup hook

Post by JeJe »

Code: Select all

dim libs,libraryname,modulename,subst,modl

libraryname = "Standard"
modulename = "Module88B2"
subst = "Sub NewSub" & chr(13) & "End Sub"

libs = globalscope.basiclibraries
if libs.hasbyname(libraryname)=false then
libs.insertbyname(libraryname)
end if
libr = libs.getbyname(libraryname)
if libr.hasbyname(modulename) = false then
modl=libr.insertbyname(modulename,subst)
else
'modl = libr.getbyname(modulename)
libs.loadlibrary(libraryname)
newst= libr.getbyname(modulename)
newst = newst & chr(13) & chr(13) &  subst
libr.replacebyname(modulename,newst)
end if
libs.storelibraries

Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
Berwyn
Posts: 6
Joined: Thu May 11, 2023 5:41 am

Re: Extension uninstall cleanup hook

Post by Berwyn »

Woah. Dodgy as. But thanks.
Is 88B2 just a random number you made up or is it some kind of special magic number?
Do you know whether this is a standard technique for an uninstall hook?
I'm using Libreoffice v7.5.2.2 on Linux Mint
JeJe
Volunteer
Posts: 2764
Joined: Wed Mar 09, 2016 2:40 pm

Re: Extension uninstall cleanup hook

Post by JeJe »

Its a random name as you might already have a "Module1" or something else like that.

No, not a standard technique. I'm just brainstorming for a solution. Assuming the uninstallation routine doesn't do that bit of the cleanup properly, you need a workaround.

Another approach would be to leave the user to assign the event to the macro - then they'll know how to remove it after uninstallation.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
Berwyn
Posts: 6
Joined: Thu May 11, 2023 5:41 am

Re: Extension uninstall cleanup hook

Post by Berwyn »

I actually got this working using the following code:

Code: Select all

Sub setupOnSave()
	' Connects the LibreOffice "Save Document" event to our Basic subroutine `GlobalOnSave()`.
	' It adds OnSave to globalEventBroadcaster instead of ThisComponent (current doc) because
	' otherwise LibreOffice produces a warning that this document has macros.
	' Copies a stub subroutine GlobalOnSave() into the Standard library
	' so that OnSave doesn't produce errors even if the extension is uninstalled.
	copy_code("Wordcounter", "wordcount_sections", "Standard", "wordcount_sections", "copy_marker")

	Dim aProps(1) As New com.sun.star.beans.PropertyValue
	aProps(0).Name		= "EventType"
	aProps(0).Value		= "Script"
	aProps(1).Name		= "Script"
	aProps(1).Value		= "vnd.sun.star.script:Standard.wordcount_sections.GlobalOnSave?language=Basic&location=application"

	oGlobalEventBroadcaster = GetDefaultContext().getByName( "/singletons/com.sun.star.frame.theGlobalEventBroadcaster" )
	oGlobalEventBroadcaster.Events.replaceByName("OnSave", aProps())
End Sub

Sub copy_code(fromlib, frommod, tolib, tomod, marker)
	' Copy code after _marker_ from fromlib/frommod into module tolib/tomod
	libs = globalscope.basiclibraries
	libs.loadlibrary(fromlib)
	libr = libs.getbyname(fromlib)
	module = libr.getbyname(frommod)

	textSearch = CreateUnoService("com.sun.star.util.TextSearch")
	options = CreateUnoStruct("com.sun.star.util.SearchOptions")
	options.algorithmType = com.sun.star.util.SearchAlgorithms.REGEXP
	options.searchString = "_" & marker & "_"
	textSearch.setOptions(options)
	found = textSearch.searchForward(module, 0, Len(module))
	code = right(module, Len(module) - found.endOffset(0) - 1)

	libr = libs.getbyname(tolib)
	if not libs.hasbyname(tolib) then
		libs.insertbyname(tolib)
	end if
	if not libr.hasbyname(tomod) then
		libr.insertbyname(tomod,code)
	else
		libs.loadlibrary(tolib)
		'libr.removebyname(tomod)
		libr.replacebyname(tomod,code)
	end if
	libs.storelibraries()
End Sub


' The rest of this file gets copied to Standard library so OnSave doesn't create an error if extension is uninstalled
' _copy_marker_
Sub GlobalOnSave(oEvent As Object)
	' This subroutine gets connected to the "Save Document" event of LibreOffice, OnSaveAs.
	' It provides a stub so that the OnSave event doesn't create errors even if the Wordcounter extension is removed
	library = "Wordcounter"
	if globalscope.basiclibraries.hasbyname(library) then
		basiclibraries.loadLibrary(library)
		Wordcounter.wordcount_sections.OnSave(oEvent)
	end if
End Sub
I'm using Libreoffice v7.5.2.2 on Linux Mint
Post Reply