<The previous article in this series | The table of contents of this series | The next article in this series>
To Know How to Call Some Functions That Are Otherwise Unavailable from the Outside of LibreOffice or Apache OpenOffice
So far, we have called some functions from our UNO extensions, but not all functions can be called from UNO extensions, or standalone UNO programs.
I know. We have to have a reference to an UNO object (to be exact, a reference to a UNO proxy of the UNO object) in order to call a function that belongs to the UNO object, but there is no guarantee that we can get the reference.
We can get a reference to an UNO object in this process.
We get the component context; we get UNO objects (the global UNO service manager is one of them) contained in the component context; we get UNO objects from the global UNO service manager; we get UNO objects as return values or output arguments of methods of UNO objects that we already have references to; we get UNO objects as properties or attributes of UNO objects that we already have references to.
UNO objects can also be gotten as members of return struct values or output struct arguments, etc, but that wouldn't be necessary to mention.
A UNO object that isn't exposed in the process can't be accessed from the outside of LibreOffice or Apache OpenOffice.
Of course. And a function may not be even implemented as a UNO component method.
Yes. LibreOffice is mostly implemented in C++, and not all C++ classes are UNO components.
So, there can be some functions we want to call, but can't.
However, there is another mechanism by which we can call some functions, which is the dispatch mechanism.
What is it like?
There are predetermined commands, which are identified by their URLs, and we can call one of them, specifying the URL and some arguments that are specific to the command.
Can we call all of those commands?
There is no guarantee for that. We may not be able to get a reference to a UNO object that is required as an argument to call a command, and there may be some special conditions that have to be fulfilled in order for it to be called successfully.
Special conditions?
For example, a dialog window may have to be opened when a command is called.
Hmm . . .
That's just an example I conceived. There might not be really such cases.
Ah-ha . . .
How can we know those URLs and specifications of their arguments?
That's the issue. . . . I couldn't find any document that comprehensively explains them.
Hmm.
So far, my best measure is to see the source codes of LibreOffice. Where and how we should see is the next issue, but we won't delve into it now.
OK.
By recording macros, we can see some instances of calling commands, but they aren't always perfect.
How can they be imperfect.
For example, when we export a document as a PDF file, we can sign the PDF file, but the recorded macro doesn't sign the PDF file.
So, some arguments are just missed?
Or values aren't set for some arguments.
I see. So, how can we call a command, exactly?
There is a global UNO service named, 'com.sun.star.frame.DispatchHelper', and we can create an instance of the UNO service from the global UNO services manager. The UNO component of the instance implements a UNO interface, 'com.sun.star.frame.XDispatchHelper', which has a method called, 'executeDispatch', which takes the dispatch provider, the command URL, and the command arguments.
What is the dispatch provider?
Commands aren't executed mystically, but are received and dealt with by an entity, which is the dispatch provider, according to my understanding.
How can we get the dispatch provider?
Of course, it depends on the command, but in most cases we are concerned now, the frame in which the document resides is the dispatch provider.
How can we get the frame?
We can get the frame from the controller of the document, using the 'com.sun.star.frame.XController' UNO interface implemented by the controller.
I see.
After all, I wrote this sample code , where 'componentContext' is the component context in 'com.sun.star.uno.XComponentContext' (see this previous article to know how we got it) and 'l_currentSpreadSheetsDocumentModel' is the spread sheet document UNO object in 'com.sun.star.frame.XModel' (see this previous article to know how we got it).
import com.sun.star.frame.XFrame;
import com.sun.star.frame.XController;
import com.sun.star.frame.XDispatchHelper;
import com.sun.star.frame.XDispatchProvider;
import com.sun.star.beans.PropertyValue;
XDispatchHelper l_dispatchHelperInXDispatchHelper = (XDispatchHelper) UnoRuntime.queryInterface (XDispatchHelper .class, componentContext.getServiceManager ().createInstanceWithContext ("com.sun.star.frame.DispatchHelper", componentContext));
XController l_controllerInXController = (XController) UnoRuntime.queryInterface (XController.class, l_currentSpreadSheetsDocumentModel.getCurrentController ());
l_frameInXDispatchProvider = (XDispatchProvider) UnoRuntime.queryInterface (XDispatchProvider.class, l_controllerInXController.getFrame ());
PropertyValue [] l_commandProperties = new PropertyValue [1];
l_commandProperties [0] = new PropertyValue ();
l_commandProperties [0].Name = "ToPoint";
l_commandProperties [0].Value = "$B$2";
l_dispatchHelperInXDispatchHelper.executeDispatch (l_frameInXDispatchProvider, ".uno:GoToCell", "", 0, l_commandProperties);
What is the command?
That's a command that moves the cell current position to the B2 cell.
Is that different from selecting the cell?
That's different, at least in appearance. When a cell is selected, the cell is shaded, while when the cell is just current, the cell isn't shaded.
Well, that is a subtle difference.
And when we export a spread sheet document as a PDF file, a selected cell is recognized as the selection while just a current cell isn't.
What do you mean by "recognized as the selection"?
When we export a spread sheet document as a PDF file, we can export only the selected part of the document.
I see.
<The previous article in this series | The table of contents of this series | The next article in this series>