Is close listener already registered for this doc?
-
- Posts: 44
- Joined: Tue Apr 10, 2018 6:15 am
Is close listener already registered for this doc?
Is there a method to determine whether a close listener has already been registered for a given SwXTextDocument, appealing only to the object itself and not the value returned by the doc's addCloseListener method? My library (in ooBasic) handles many documents, which continually open and close. They need a close listener only if they reference (by activating a hyperlink) each other but, at that event, I don't know whether they already have a registered close listener. I have a solution based on an association list but it is excessive if all I need to do is ask the doc object.
W10 Libre 6.1.5.2 and Ubuntu-Mate 18.04 Libre 6.0.7.3
Re: Is close listener already registered for this doc?
I've had the same problem with other listeners - wanting to know if one's running or not - I think the answer's no.
In your case have you considered using Tools/Customise/Events/Document is going to be close/Document closed events. They look to be the same two events so you wouldn't need to worry about this.
Alternatively you could use a collection, indexed by the RuntimeUID perhaps.
In your case have you considered using Tools/Customise/Events/Document is going to be close/Document closed events. They look to be the same two events so you wouldn't need to worry about this.
Alternatively you could use a collection, indexed by the RuntimeUID perhaps.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
-
- Posts: 44
- Joined: Tue Apr 10, 2018 6:15 am
Re: Is close listener already registered for this doc?
Although keeping a list of the documents for which my library has registered a close listener generally works, program problems can cause the list and documents to get out-of-sync. I have encountered this only when one of my macros under development crashes, but an unrelated macro crash could theoretically also cause the problem. I have designed my close listener to not do anything bad if invoked more than once (on the same document) and to not do anything absolutely essential, but a tighter association would be better. Since it seems that there is nothing built into SwXTextDocument to tell its status vis a vis my listener, I decided to roll my own.
As far as I can tell, the only property clearly intended for non-native application communication is "InteropGrabBag". It is an array of beans properties. It seems to always be empty in my system but it is obviously a shared resource. Only a bad actor would assume sole ownership. I wrote a simple macro to add a unique (I hope) property to the bag and another to look for the property. The bag is not persistent. Closing and reopening the document shows it to again be empty, so there is no need for a macro to delete the property although this would also be simple. The globals all have prefix LXA, which is unique (I hope) to my library. I haven't changed it for this example because something unique should be there. For generality, these macros all take doc argument, which is usually ThisComponent.
As far as I can tell, the only property clearly intended for non-native application communication is "InteropGrabBag". It is an array of beans properties. It seems to always be empty in my system but it is obviously a shared resource. Only a bad actor would assume sole ownership. I wrote a simple macro to add a unique (I hope) property to the bag and another to look for the property. The bag is not persistent. Closing and reopening the document shows it to again be empty, so there is no need for a macro to delete the property although this would also be simple. The globals all have prefix LXA, which is unique (I hope) to my library. I haven't changed it for this example because something unique should be there. For generality, these macros all take doc argument, which is usually ThisComponent.
Code: Select all
sub LXAaddToIopBag(doc as object, item as object)
dim was, cnt as integer, idx as integer
was = doc.getPropertyValue("InteropGrabBag")
cnt = ubound(was)
dim repl(cnt + 1) as new com.sun.star.beans.PropertyValue
for idx = 0 to cnt step 1
repl(idx) = was(idx)
next idx
repl(cnt + 1) = item
doc.setPropertyValue("InteropGrabBag", repl)
end sub
function LXAgetIopBagItem(doc as object, iname as string) as object
dim idx as integer
With doc
for idx = 0 to ubound(.InteropGrabBag)
if .InteropGrabBag(idx).Name = iname then
LXAgetIopBagItem() = .InteropGrabBag(idx)
exit function
endif
next idx
end With
end function
sub LXAregWindowCloseListener(doc as object)
dim listener as object
dim item as new com.sun.star.beans.PropertyValue
if IsNull(LXAgetIopBagItem(doc, "LXAListen")) then
item.Name = "LXAListen"
item.Value = TRUE
LXAaddToIopBag(doc, item)
listener = CreateUnoListener("LXAonWindowClose_", _
"com.sun.star.util.XCloseListener")
doc.addCloseListener(listener)
endif
end sub
W10 Libre 6.1.5.2 and Ubuntu-Mate 18.04 Libre 6.0.7.3
-
- Posts: 44
- Joined: Tue Apr 10, 2018 6:15 am
Re: Is close listener already registered for this doc?
JeJe, thank you for pointing out RuntimeUID. Although I decided on a solution that doesn't involve lookup, another part of my program does. I had been using the document's URL, which is more expensive and not actually needed in this situation.
W10 Libre 6.1.5.2 and Ubuntu-Mate 18.04 Libre 6.0.7.3
Re: Is close listener already registered for this doc?
It won't help you as you're on Linux but for anyone who only uses Windows it has APIs for storing information against hwnds (the OS number allocated to a window). They are 32 bit functions though - so there may be problems on later versions of Windows. The Vb6 code here probably translates to OOBasic with little or no adaptation.
http://www.cpearson.com/excel/SetGetProp.htm
Edit: the hwnd is directly accessible in OO through the ContainerWindow.getWindowHandle
http://www.cpearson.com/excel/SetGetProp.htm
Edit: the hwnd is directly accessible in OO through the ContainerWindow.getWindowHandle
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)