2017-10-22

1: The Preface of the Series, 'Notes About Using UNO in Basic Macros'

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

Main Body START

This Series Is a Complement to the Main Series, 'To Develop UNO Extensions (LibreOffice Extensions or Apache OpenOffice Extensions)', for Applying Descriptions of the Main Series to Using UNO in Basic Macros

About: UNO (Universal Network Objects)

About: LibreOffice

About: Apache OpenOffice

About: LibreOffice Basic Programming Language

The Purpose of This Series

Here are -Hypothesizer and -Rebutter sitting in front of a computer screen in a room on a brook among some mountains on the Bias planet.

-Hypothesizer

There is already a series, 'To Develop UNO Extensions (LibreOffice Extensions or Apache OpenOffice Extensions)', which is about developing UNO extensions that consist of Java UNO components (see here to know what UNO components are), and most of the basic ideas described there also apply to using UNO in Basic macros because they are about using UNO, which is basically language-independent specifications.

-Rebutter

OK.

-Hypothesizer

However, as some special treatment is given to the Basic mapping of UNO, we have to know them.

-Rebutter

Why is such special treatment given to the Basic mapping of UNO?

-Hypothesizer

As LibreOffice Basic lacks some functionality that is essential in UNO, that is necessary. Most conspicuously, there is no concept of interfaces in Basic.

-Rebutter

Ah-ha.

What We Deals with in This Series

The same with the previous scene.

-Hypothesizer

As a note, as we aren't in the habit of implementing large-scale logic in Basic, we don't intend to make any exhaustive commentary on building logic using UNO in Basic.

-Rebutter

I don't understand well.

-Hypothesizer

For example, we have dealt with how to read from and write to spread sheet cells in the main series, but we won't deal with such specific logic in this series.

-Rebutter

Ah, logic described there should be applicable to Basic; it is only a matter of which programming language the logic is written in.

-Hypothesizer

So, we won't repeat the same argument just in order to show it in Basic codes.

-Rebutter

Fine.

-Hypothesizer

In fact, I don't have any incentive to write large-scale Basic codes.

-Rebutter

Why not?

-Hypothesizer

Because I can write much more extensive logic more efficiently and robustly in Java by developing UNO components: Java is more robust (doing more rigorous datum types checking), more suitable for large-scale programmings (being a full-fledged object oriented language), richer in functionality (having richer datum types such as BigDecimal, List, Set, and Map, being able to do multithreading, having richer networking functionality, being able to develop richer GUIs, and being able to access OS native features through JNI).

-Rebutter

In fact, we aren't so familiar with Basic.

-Hypothesizer

We aren't, and that's the biggest reason.

-Rebutter

Ah-ha.

-Hypothesizer

And we won't deal with details of individual UNO components, because they are or will be dealt with in the main series.

-Rebutter

Again, they are language-independent.

-Hypothesizer

In this series, we will deal with only how to invoke general UNO components in Basic.

Special Treatment of the Component Context

The same with the previous scene.

-Hypothesizer

A general rule about using UNO is, "Get the component context, and we can do whatever allowed us to do, using the component context."

-Rebutter

The component context is a handle to a UNO environment, and any UNO object (see here to know what UNO objects are) as a UNO service instance (see here to know what UNO services are) receives one as the constructor argument and any external UNO program gets one, connecting to the desired UNO environment. That's what we learned in the series, 'To Develop UNO Extensions (LibreOffice Extensions or Apache OpenOffice Extensions)', and the series, 'How to Use UNO (Handle LibreOffice or Apache OpenOffice Documents) in External Java Programs'.

-Hypothesizer

But . . .

-Rebutter

. . . But what?

-Hypothesizer

I wonder whether I should have said "But". . . . In fact, in Basic macros also, certainly, we can get the component context, and can handle the UNO environment using the component context.

-Rebutter

So, what's the matter?

-Hypothesizer

Nothing particularly. In fact, we can get the component context like this.

-Hypothesizer starts a LibreOffice instance, opens a Basic module, and writes a Sub in the module.

@LibreOffice Basic Source Code
Sub testToGetDefaultComponentContext
 Dim l_componentContext As Variant
 
 l_componentContext = GetProcessServiceManager ().getPropertyValue ("DefaultContext")
End Sub
-Rebutter

Um? Well, however we get the component context, we can use it basically the same way as we do in Java, right?

-Hypothesizer

Right. . . . But . . .

-Rebutter

. . . But what?

-Hypothesizer

Well, this is a typical way of creating a UNO service instance, in Basic.

-Hypothesizer writes another Sub in the module.

@LibreOffice Basic Source Code
Sub testToCreatServiceInstanceInTypicalWay
 Dim l_globalServicesManager As Variant
 Dim l_arguments (0)
 Dim l_heyUnoExtensionsUnoObject As Variant
 
 l_globalServicesManager = GetProcessServiceManager ()
 l_arguments (0) = "Good morning"
 l_heyUnoExtensionsUnoObject = l_globalServicesManager.createInstanceWithArguments ("thebiasplanet.uno.heyunoextensionsunoextension.HeyUnoExtensionsService", l_arguments ())
End Sub
-Rebutter

Well, the function, 'GetProcessServiceManager', which we previously used to get the component context, actually returns the global UNO services manager (see here to know what the global UNO services manager is). . . . What is the method, 'createInstanceWithArguments'? I mean, we have used the method, 'createInstanceWithArgumentsAndContext', passing the component context, in Java.

-Hypothesizer

We can use the former method also in Java, but haven't, because such a practice isn't optimal.

-Rebutter

Why?

-Hypothesizer

We have kept saying that the component context is a handle to a UNO environment, but in fact, the component context is also a container of some properties as the run time environment.

-Rebutter

Ah-ha . . .

-Hypothesizer

And the component context is something that is supposed to be passed along creation stacks of UNO objects, while the component context can be replaced with modified versions along the way.

-Rebutter

For example, when a UNO object is created, it receives a component context; it can create a modified version of the component context (some properties can be added, some properties can be removed, some property values can be changed, or some or all of them can be done) if necessary, and passes the newest version of the component context (the modified one if modified, the received one if not modified) to another, newly created UNO object . . .

-Hypothesizer

Yes. When we use 'createInstanceWithArguments', we don't pass the newest version of the component context to the newly created UNO object: a component context that the global UNO service manager recognizes as the default component context is passed to the newly created UNO object.

-Rebutter

And that's exactly what the typical code above is doing . . .

-Hypothesizer

Yes.

-Rebutter

Well, after all, as Basic modules aren't UNO components, they don't receive particular component contexts, or we would say, they receive the default component context, and whether they explicitly pass the default component context to newly created UNO objects or not, it practically doesn't matter, because the default component context is passed either way.

-Hypothesizer

That seems to be the case.

As the Basic runtime presupposes that the default component context will be always used, it doesn't directly disclose the default component context, but the global UNO service manager, and in most cases, we can do without explicitly specifying the component context to use. However, if we have to or want to explicitly specify a particular component context, we always can do so. In fact, this code works fine.

-Hypothesizer writes a Sub in the module.

@LibreOffice Basic Source Code
Sub testToCreatServiceInstanceExplicitlySpecifyingComponentContext
 Dim l_componentContext As Variant
 Dim l_globalServicesManager As Variant
 Dim l_arguments (0)
 Dim l_heyUnoExtensionsUnoObject As Variant
 
 l_componentContext = GetProcessServiceManager ().getPropertyValue ("DefaultContext")
 l_globalServicesManager = l_componentContext.getServiceManager ()
 l_arguments (0) = "Good morning"
 l_heyUnoExtensionsUnoObject = l_globalServicesManager.createInstanceWithArgumentsAndContext ("thebiasplanet.uno.heyunoextensionsunoextension.HeyUnoExtensionsService", l_arguments (), l_componentContext)
End Sub
-Rebutter

How about creating UNO service instances through 'UNO service'-specific UNO service instances factories (see here to know what we mean by ''UNO service'-specific UNO service instances factories')?

-Hypothesizer

The same. We can do without passing the component context although we can pass it if we want to.

-Rebutter

Do you mean we can just ignore the existence of the first argument that takes the component context, not pass null to the first argument?

-Hypothesizer

Yes.

-Rebutter

By the way, the component context we have talked about so far is that of the LibreOffice instance on which the Basic code runs, right?

-Hypothesizer

Yes. That is the UNO environment Basic macros are usually supposed to handle.

-Rebutter

How can we get the component context of another UNO environment, for example a UNO environment on a remote host?

-Hypothesizer

I don't know how to do that by Basic self; I would be able do that through my UNO component, if necessary.

-Rebutter

Ah, we can do that according to some descriptions of the series, 'How to Use UNO (Handle LibreOffice Documents) in External Java Programs'.

Special Treatment of UNO Interfaces

-Hypothesizer

In Basic, we don't need to explicitly get any UNO proxy (see here to know what UNO proxies are) that represents each UNO interface (see here to know what UNO interfaces are): we can just call any method on an UNO object.

-Rebutter

I remember that that is true only if the UNO component is made to support that feature (see here).

-Hypothesizer

Yes, that should be the case.

Just Use Variant as the Variable Type to Refer to any UNO Object

-Hypothesizer

We use Variant as the variable type to refer to any UNO object.

-Rebutter

Ah, in Java, we use a UNO interface as the variable type to refer to a UNO object (to be exact, a UNO proxy).

-Hypothesizer

As we can't use interfaces in Basic, we just do with using Variant.

This reference document says that we shouldn't use Object as the variable type, although Object is frequently used in examples of reference documents.

-Rebutter

So, we should do as the reference document says, not as reference documents do . . .

We Have to Know the Datum Types Mapping

-Rebutter

We will have to know the datum types mapping between UNO and Basic.

-Hypothesizer

We can look it up here.

Main Body END

References

  • Apache OpenOffice Wiki. (2009/05/13). OpenOffice.org Basic. Retrieved from https://wiki.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Basic/OpenOffice.org_Basic

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