2017-08-27

30: How to Issue UNO Commands to the Dispatch Mechanism

<The previous article in this series | The table of contents of this series | The next article in this series>

Main body START

To Know How to Call Some Functions That Are Otherwise Unavailable from the Outside of LibreOffice or Apache OpenOffice

Not All Functions Can Be Called from the Outside of LibreOffice or Apache OpenOffice

-Hypothesizer

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.

-Rebutter

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.

-Hypothesizer

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.

-Rebutter

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.

-Hypothesizer

A UNO object that isn't exposed in the process can't be accessed from the outside of LibreOffice or Apache OpenOffice.

-Rebutter

Of course. And a function may not be even implemented as a UNO component method.

-Hypothesizer

Yes. LibreOffice is mostly implemented in C++, and not all C++ classes are UNO components.

-Rebutter

So, there can be some functions we want to call, but can't.

There Is a Mechanism Called 'Dispatch'

-Hypothesizer

However, there is another mechanism by which we can call some functions, which is the dispatch mechanism.

-Rebutter

What is it like?

-Hypothesizer

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.

-Rebutter

Can we call all of those commands?

-Hypothesizer

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.

-Rebutter

Special conditions?

-Hypothesizer

For example, a dialog window may have to be opened when a command is called.

-Rebutter

Hmm . . .

-Hypothesizer

That's just an example I conceived. There might not be really such cases.

-Rebutter

Ah-ha . . .

How can we know those URLs and specifications of their arguments?

-Hypothesizer

That's the issue. . . . I couldn't find any document that comprehensively explains them.

-Rebutter

Hmm.

-Hypothesizer

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.

-Rebutter

OK.

-Hypothesizer

By recording macros, we can see some instances of calling commands, but they aren't always perfect.

-Rebutter

How can they be imperfect.

-Hypothesizer

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.

-Rebutter

So, some arguments are just missed?

-Hypothesizer

Or values aren't set for some arguments.

-Rebutter

I see. So, how can we call a command, exactly?

-Hypothesizer

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.

-Rebutter

What is the dispatch provider?

-Hypothesizer

Commands aren't executed mystically, but are received and dealt with by an entity, which is the dispatch provider, according to my understanding.

-Rebutter

How can we get the dispatch provider?

-Hypothesizer

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.

-Rebutter

How can we get the frame?

-Hypothesizer

We can get the frame from the controller of the document, using the 'com.sun.star.frame.XController' UNO interface implemented by the controller.

-Rebutter

I see.

-Hypothesizer

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);
-Rebutter

What is the command?

-Hypothesizer

That's a command that moves the cell current position to the B2 cell.

-Rebutter

Is that different from selecting the cell?

-Hypothesizer

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.

-Rebutter

Well, that is a subtle difference.

-Hypothesizer

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.

-Rebutter

What do you mean by "recognized as the selection"?

-Hypothesizer

When we export a spread sheet document as a PDF file, we can export only the selected part of the document.

-Rebutter

I see.

Main body END

<The previous article in this series | The table of contents of this series | The next article in this series>