How to throw CloseVetoException inside queryClosing using OLE Automation bridge

Hi,

I have managed to add a close listener on a document with addCloseListener. I get the queryClosing notification successfully, but in some scenarios I would like to prevent closing by throwing a CloseVetoException inside it (as per the documentation). However, I am using OLE Automation (Delphi) and I can’t figure out how to go about throwing a CloseVetoException. If I raise a Delphi exception (like EOLEError) it is ignored and the document is closed anyway. Does anyone know how to veto the closing of a frame from inside queryClosing using the OLE Automation bridge?

Thanks!

You can’t. LibreOffice Developer's Guide: Chapter 2 - Professional UNO - The Document Foundation Wiki explains that automation bridge doesn’t throw; there is a limited number of HRESULT return values that translate to exceptions, but CloseVetoException isn’t among the thrown exceptions there.

Thanks Mike, does this mean that there is no way for me to prevent a frame from closing?

The biggest problem I am trying to solve involves the QuickStarter: When the QuickStarter is not running then the LibreOffice desktop may be owned by an external instance started by a user. When the user closes this external instance then the frame inside my application dies with it, which is highly undesirable.

A second problem that I want to solve at the same time is to prevent the user from closing a document that has not yet been saved to the database.

We can listen to all document and application events:

  oBroadCaster = CreateUnoService("com.sun.star.frame.GlobalEventBroadcaster")
  oBroadCaster.addDocumentEventListener oListener

When the application closes, an event with property EventName value OnCloseApp will be sent

According to the documentation the OnCloseApp event occurs after all documents have already been closed. Since I want to prevent the document from closing, that would be too late.

As the CloseVetoException route is not available, is there another way in which I can coerce LIbreOffice into not closing my document under any circumstance?

As @mikekaganski pointed out, there is no direct way.
Theoretically, it is possible to run an agent program in the LO environment in a language that can work with named exceptions (Java, Python), which will subscribe to GlobalEventBroadcaster events and will receive from our program identifiers (RuntimeUID) of documents that should not be closed. But this is a long way…

I’m wondering if I should perhaps take a stab at adding mappings for CloseVetoException and TerminationVetoException myself and then open a pull request. Any negative HRESULT that is not currently in use should do right? Assuming I manage to pull it off, is this something the development team would be open to incorporating?

I would suggest to create a function to throw an exception from its name instead :slight_smile:

My C++ proficiency is at the copy-and-paste and see if it compiles level. I was planning to duplicate some lines in oleobjw.cxx under the “map error codes to exceptions” comment. Adding a function that throws an exception requires an understanding of C++ and LibreOffice that I do not possess.

I’m going to open a feature request and hopefully someone takes pity on me. :slight_smile:

1 Like