Difference between revisions of "UNO automation with a binary (executable)"

From Apache OpenOffice Wiki
Jump to: navigation, search
m (ServiceManager and Desktop objects)
m (To find and to save the Document)
 
(42 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{Documentation/Banner}}
+
{{DocBanner}}
 +
{{NeedsRework|EN}}
  
We want now discuss a fully UNO/OpenOffice.org program : we mean a program which automates some tasks on OpenOffice.org documents, file loading, file modifying, file saving... all in all “Create a binary program to replace a OOoBasic program”. The border between the examples of previous chapter and of this chapter is vague. I can only say  : if you imagine to automate any problem and create a program for, this paragraph and the next chapters are for you. Please read also [[Documentation/BASIC_Guide/API_Intro|Introduction to the OpenOffice.org API]].
+
We want now discuss a fully UNO/OpenOffice program : we mean a program which automates some tasks on {{AOo}} documents, file loading, file modifying, file saving... all in all “Create a binary program to replace a OOBasic program”. The border between the examples of previous chapter and of this chapter is vague. I can only say  : if you imagine to automate any problem and create a program for it, this paragraph and the next chapters are for you. Please read also [[Documentation/BASIC_Guide/API_Intro|Introduction to the {{AOo}} API]] and documentation [[Documentation/DevGuide/WritingUNO/Required_Files|on necessary tools for UNO development]] in Developer's Guide.
  
 
= Introduction : starting from a SDK example=
 
= Introduction : starting from a SDK example=
 
== Introduction to services and interfaces==
 
== Introduction to services and interfaces==
Before  going further, I have to explain the minimal organization of UNO API, particularly of the distinction between services and interfaces. A service is a set of interfaces. Both have a name starting with "com.sun.star" followed by a module's name ".lang" for instance and terminate with the effective service or interface name. An interface name begins always with a 'X' character. For instance , <idl>com.sun.star.lang.ServiceManager</idl> is a service and clicking on the link shows you it contains many interfaces, and <idl>com.sun.star.lang.XServiceInfo</idl> is one of them (name starting with a X).
+
Before  going further, I have to explain the minimal organization of UNO API, particularly of the distinction between services and interfaces. A service is a set of interfaces. Both have a name starting with "com.sun.star" followed by a module's name ".lang" for instance and terminate with the effective service or interface name. An interface name begins always with a 'X' character. For instance, <idl>com.sun.star.lang.ServiceManager</idl> is a service and clicking on the link shows you it contains many interfaces, and <idl>com.sun.star.lang.XServiceInfo</idl> is one of them (name starting with a X).
  
See also [[Documentation/BASIC_Guide/API_Intro|UNO API]] in OOoBasic document and [[Documentation/DevGuide/FirstSteps/Objects%2C_Interfaces%2C_and_Services|Developer's Guide]].
+
See also [[Documentation/BASIC_Guide/API_Intro|UNO API]] in {{AOo}} Basic document and [[Documentation/DevGuide/FirstSteps/Objects%2C_Interfaces%2C_and_Services|Developer's Guide]].
  
 
==ServiceManager and Desktop objects ==
 
==ServiceManager and Desktop objects ==
Danny Brewer wrote in the [http://www.oooforum.org/forum/viewtopic.php?t=5252 oooforum.org] :  
+
Danny Brewer wrote in the [https://web.archive.org/web/20070119064730/http://www.oooforum.org/forum/viewtopic.phtml?t=5252 oooforum.org] :  
“To do almost anything useful with OOo via. the API, in almost all cases, you must either create a new document, or open an existing document. Then you would manipulate the contents of the document, extract information from it, print it, convert it to a different format, work with data forms on the document, or perform various other tasks with office documents.
+
{{Citation|To do almost anything useful with {{AOo}} via the API, in almost all cases, you must either create a new document, or open an existing document. Then you would manipulate the contents of the document, extract information from it, print it, convert it to a different format, work with data forms on the document, or perform various other tasks with office documents.
  
 
Therefore, one of the first things to learn is how to open or create documents.
 
Therefore, one of the first things to learn is how to open or create documents.
  
In order to work with OOo via. the API, you must first acquire two essential objects.  
+
In order to work with {{AOo}} through the API, you must first acquire two essential objects.  
 
# the <idl>com.sun.star.lang.ServiceManager</idl>  
 
# the <idl>com.sun.star.lang.ServiceManager</idl>  
 
# the <idl>com.sun.star.frame.Desktop</idl>  
 
# the <idl>com.sun.star.frame.Desktop</idl>  
  
 
Once you have the <code>ServiceManager</code>, you call its createInstance() method to get the <code>Desktop</code> object.  
 
Once you have the <code>ServiceManager</code>, you call its createInstance() method to get the <code>Desktop</code> object.  
Once you have the <code>Desktop</code> object, you can use it to create or open new documents.  
+
Once you have the <code>Desktop</code> object, you can use it to create or open new documents.}}
  
 
More on <idl>com.sun.star.frame.Desktop</idl> service [[Documentation/BASIC_Guide/StarDesktop|here in OOoBasic Guide]].
 
More on <idl>com.sun.star.frame.Desktop</idl> service [[Documentation/BASIC_Guide/StarDesktop|here in OOoBasic Guide]].
Line 27: Line 28:
  
 
In every different programming language, there are different mechanisms for acquiring the Service Manager. One way of getting the service manager is given in one SDK example :
 
In every different programming language, there are different mechanisms for acquiring the Service Manager. One way of getting the service manager is given in one SDK example :
<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding
+
<OpenOffice_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding
 
We first check the example (under Linux) :
 
We first check the example (under Linux) :
{{Documentation/Linux|
+
{{Lin|
 
<pre>
 
<pre>
cd <OpenOffice.org1.1_SDK>
+
cd <OpenOffice_SDK>
 
./setsdkenv_unix
 
./setsdkenv_unix
 
cd examples/DevelopersGuide/ProfUNO/CppBinding
 
cd examples/DevelopersGuide/ProfUNO/CppBinding
Line 39: Line 40:
 
}}
 
}}
 
which only writes out "Connected successfully to the office". Under Windows it would be :
 
which only writes out "Connected successfully to the office". Under Windows it would be :
{{Documentation/Windows|
+
{{Win|
 
<pre>
 
<pre>
cd <OpenOffice.org1.1_SDK>
+
cd <OpenOffice_SDK>
 
setsdkenv_windows
 
setsdkenv_windows
 
cd examples/DevelopersGuide/ProfUNO/CppBinding
 
cd examples/DevelopersGuide/ProfUNO/CppBinding
Line 48: Line 49:
 
</pre>
 
</pre>
 
}}
 
}}
We start first our discussion from this example. Later on, we will provide an other starting code. All listings we will give below are to be added at  this example. Where ? It's shown here (in red) :  
+
We first start our discussion from this example. Later on, we will provide another starting code. All listings we will give below are to be added to this example. Where ? It's shown here :  
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
// Listing 1 Our first Connection
 
// Listing 1 Our first Connection
 
//C++  *** extract from office_connect.cxx
 
//C++  *** extract from office_connect.cxx
Line 103: Line 104:
 
return 0;
 
return 0;
 
}
 
}
</source>
+
</syntaxhighlight>
I cannot explain all the lines of this source file, but if you want to have an idea of what you have to learn when using UNO SDK, have a look at all the interfaces of this snippet : <idl>com.sun.star.uno.XComponentContext</idl>, <idl>com.sun.star.lang.XMultiComponentFactory</idl>, <idl>com.sun.star.uno.XInterface</idl> and <idl>com.sun.star.bridge.XUnoUrlResolver</idl>.  
+
I cannot explain all the lines of this source file, but if you want to have an idea of what you have to learn when using UNO SDK, have a look at all the interfaces encountered in this snippet. They are : <idl>com.sun.star.uno.XComponentContext</idl>, <idl>com.sun.star.lang.XMultiComponentFactory</idl>, <idl>com.sun.star.uno.XInterface</idl> and <idl>com.sun.star.bridge.XUnoUrlResolver</idl>.  
  
I can just say : here is one way among others to get the Service Manager. A second way is given in <OpenOffice.org1.1_SDK>/examples/cpp/DocumentLoader's example.
+
I can just say : here is one way among others to get the ServiceManager. The way to obtain the ServiceManager is named bootstraping process in {{AOo}} : see the next section or [[UNO_registery_and_Bootstrapping#The_Bootstrap|the complete explanation]]. A second way is given in <OpenOffice_SDK>/examples/cpp/DocumentLoader's example.
  
Before to go further I want to give explanations. The code above shows, even if you don't understend it, how we programm with UNO and C++. You should write C++ code with many strange variables like :
+
Before to go further I want to give explanations. The code above shows, even if you don't understend it, how we program with UNO and C++. You should write C++ code with many strange variables like :
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
Reference< XSomething > rSomething = aWayToObtainSomething;
+
Reference< XSomething > rSomething = aWayToObtainSomething();
</source>
+
</syntaxhighlight>
In this code XSometing is an interface because its name has a 'X' as first character. You have in the above code two ways to obtain interfaces :
+
In this code XSomething is an interface because its name has a 'X' as first character. In the above code you have two ways to obtain interfaces:
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
// obtain an interface first way : buildin function
 
// obtain an interface first way : buildin function
 
Reference< XComponentContext > rComponentContext = defaultBootstrap_InitialComponentContext();
 
Reference< XComponentContext > rComponentContext = defaultBootstrap_InitialComponentContext();
</source>
+
</syntaxhighlight>
et aussi
+
and also
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
// obtain an interface second way : UNO_QUERY starting from a service
 
// obtain an interface second way : UNO_QUERY starting from a service
 
Reference< XUnoUrlResolver > rResolver( rInstance, UNO_QUERY );
 
Reference< XUnoUrlResolver > rResolver( rInstance, UNO_QUERY );
</source>
+
</syntaxhighlight>
How do I know I start from a service ? If the first character of the name is not a 'X', it is a service and if you want to obtain it you have to cast it with a <idl>com.sun.star.uno.XInterface</idl>. You can see it's the case for rResolver  variable in the listing 1 (com.sun.star.bridge.UnoUrlResolver service).
+
How do I know I start from a service ? If the first character of the name is not a 'X', it is a service and if you want to obtain it, you have to cast it with a <idl>com.sun.star.uno.XInterface</idl>. You can see it's the case for rResolver  variable in the listing 1 (com.sun.star.bridge.UnoUrlResolver service).
  
{{Documentation/Note|
+
{{Note|
The C++ language doesn't allow you to use directly services, but rather interfaces. Every service has to be casted in a variable of type <idl>com.sun.star.uno.XInterface</idl>. It's not the same with OOoBasic programming which in the contrary allow you to use directly services.  
+
The C++ language doesn't allow you to use services directly, but rather interfaces. Every service has to be casted in a variable of type <idl>com.sun.star.uno.XInterface</idl>. It's not the same with {{AOo}} Basic programming which in the contrary allow you to use directly services.  
 
}}
 
}}
  
That piece of code is in general called bootstrapping and examining int he next section.
+
That piece of code is in general called bootstrapping and will be examined in the next section.
  
 
== Introduction to Bootstrapping ==
 
== Introduction to Bootstrapping ==
Line 137: Line 138:
 
[[Image:ch4Fig1bootstrap.png|none|thumb|600px|Bootstrapping Diagram]]
 
[[Image:ch4Fig1bootstrap.png|none|thumb|600px|Bootstrapping Diagram]]
  
If you are interested in, have a look simultaneously to the code and to the drawing to see the schematic conventions I have used to carry out the Figure above. For instance both XInterface are connected because we use the same variable in fact. The gray filled rectangles are for parameters... and so on.
+
If you are interested, have a simultaneous look at the code and the drawing, to see the schematic conventions I have used to carry out the Figure above. For instance, both XInterface are connected because we use the same variable in fact. The gray filled rectangles are for parameters... and so on.
  
We want now the desktop and load a OooCalc component.  
+
We want now the desktop and load a {{AOo}} Calc component.  
  
 
The '''first step''' is to obtain desktop. You then add this code :
 
The '''first step''' is to obtain desktop. You then add this code :
  
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
// Listing 2 Obtaining a desktop interface
 
// Listing 2 Obtaining a desktop interface
 
// C++
 
// C++
 
Reference< XInterface  > xDesktop = rOfficeServiceManager->createInstance(
 
Reference< XInterface  > xDesktop = rOfficeServiceManager->createInstance(
 
   OUString::createFromAscii( "com.sun.star.frame.Desktop" ));
 
   OUString::createFromAscii( "com.sun.star.frame.Desktop" ));
</source>
+
</syntaxhighlight>
 
Your desktop object is in xDesktop variable. More on Desktop service [[Documentation/BASIC_Guide/StarDesktop|here]].
 
Your desktop object is in xDesktop variable. More on Desktop service [[Documentation/BASIC_Guide/StarDesktop|here]].
  
 
'''Second step''' : query for the XComponentLoader interface
 
'''Second step''' : query for the XComponentLoader interface
  
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
// Listing 3  Query a XcomponentLoader Interface
 
// Listing 3  Query a XcomponentLoader Interface
 
// C++
 
// C++
Line 162: Line 163:
 
         printf( "XComonentloader succesfully instanciated\n" );
 
         printf( "XComonentloader succesfully instanciated\n" );
 
     }
 
     }
</source>
+
</syntaxhighlight>
 
Before to see the problems with this code, we give again a schematic representation :
 
Before to see the problems with this code, we give again a schematic representation :
  
Line 171: Line 172:
 
error 'XcomponentLoader' undeclared (First use this function) ....
 
error 'XcomponentLoader' undeclared (First use this function) ....
 
</pre>
 
</pre>
It shows us there is a problem with XComponentLoader : this indicates we have probably to add a hpp header file in the program's include statements. The file's name is probably XComponentLoader.hpp but we have to find where it lies. One way is to go in the [http://api.openoffice.org/docs/common/ref/index-files/index-1.html general index] and to look for XComponentLoader. We find : <idl>com.sun.star.frame.XComponentLoader</idl> which indicates  
+
It shows us there is a problem with XComponentLoader : this indicates we have probably to add a hpp header file in the program's include statements. The file's name is probably XComponentLoader.hpp but we have to find where it lies. One way is to go in the [https://www.openoffice.org/api/docs/common/ref/index-files/index-1.html general index] and to look for XComponentLoader. We find : <idl>com.sun.star.frame.XComponentLoader</idl> which indicates  
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
#include <com/sun/star/frame/XComponentLoader.hpp>
 
#include <com/sun/star/frame/XComponentLoader.hpp>
</source>
+
</syntaxhighlight>
 
is required. We can try and see it is not enough, we obtain always the same error message and one new before :
 
is required. We can try and see it is not enough, we obtain always the same error message and one new before :
 
com/sun/star/frame/XComponentLoader.hpp: No such file or directory  
 
com/sun/star/frame/XComponentLoader.hpp: No such file or directory  
I have already discussed this fact : the SDK doesn't provide any hpp file, they have to be constructed from IDL files. An other task is then : open and change the makefile. Only add the correspondant line :
+
I have already discussed this fact : the SDK doesn't provide any hpp file, they have to be constructed from IDL files. An other task is then: open and change the makefile. Only add the correspondant line:
 
<pre>
 
<pre>
 
#added com.sun.star.frame.XComponentLoader
 
#added com.sun.star.frame.XComponentLoader
Line 199: Line 200:
 
Making the project gives again the same error message. What is still lacking now ?  
 
Making the project gives again the same error message. What is still lacking now ?  
 
Only a namespace statement in the source file :
 
Only a namespace statement in the source file :
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
// C++
 
// C++
 
using namespace com::sun::star::frame;
 
using namespace com::sun::star::frame;
</source>
+
</syntaxhighlight>
 
(To go further with the two steps above see [[IDL_Files_and_Cpp#Getting_an_interface_in_C.2B.2B|Getting an Interface in C++]])
 
(To go further with the two steps above see [[IDL_Files_and_Cpp#Getting_an_interface_in_C.2B.2B|Getting an Interface in C++]])
  
 
'''Step 3''' : get an instance of the spreadsheet
 
'''Step 3''' : get an instance of the spreadsheet
 
    
 
    
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
// Listing 4 Loading a new OOoCalc document
 
// Listing 4 Loading a new OOoCalc document
 
// C++
 
// C++
Line 215: Line 216:
 
         0,
 
         0,
 
         Sequence < ::com::sun::star::beans::PropertyValue >());
 
         Sequence < ::com::sun::star::beans::PropertyValue >());
</source>
+
</syntaxhighlight>
and it works : you have a new OOoCalc document.
+
and it works : you have a new {{AOo}} Calc document.
  
This [[IDL_Files_and_Cpp#Getting_an_interface_in_C.2B.2B|hyperlink]] will takkle again the header file construction problem.
+
This [[IDL_Files_and_Cpp#Getting_an_interface_in_C.2B.2B|hyperlink]] will tackle again the header file construction problem.
  
 
An other thing to note is : when constructing variables with Reference template like :  
 
An other thing to note is : when constructing variables with Reference template like :  
Line 232: Line 233:
 
= The Compilation Chain =
 
= The Compilation Chain =
  
Perhaps we need to recall we use the phrase "compilation chain" to refer to a schematic representation of the makefile. This give information on what kind of files and tools are involved when constructing a UNO binary. Skills on the compilation chain are important only if you want to modify a makefile.
+
Perhaps we need to recall we use the phrase "compilation chain" to refer to a schematic representation of the makefile. This give information on what kind of files and tools are involved when constructing a UNO binary. Skills on the compilation chain are important only if you want to modify a makefile. At this point, it is important for you to have skills on necessary tools for [[Documentation/DevGuide/WritingUNO/Required_Files|UNO development]].  
  
You can find a compilation chain [[Constructing_Components#Make_dependency_of_a_Component|here in this Wiki]] and also [[Counter_Example|here]]. I will probably tackle in the futur the makefile problem in a [[Make|Make Chapter]].
+
[[Image:CompilationChain2.png|center|UNO binary build chain]]
  
We can also find a comilation chain figure in Java Eclipse Tutorial [[JavaEclipseTuto|here]] shown below :
+
Please have a look [[UNO_registery_and_Bootstrapping#office_connect.rdb_File_creation|here]] if you want to see how <code>regmerge</code> and <code>regcomp</code> are used for office_connect.rdb file creation.
  
[[Image:CompilationChain.png|center|UNO component build chain]]
+
{{Note|'''Important Note''' : The more important point in this compilation chain is in fact that <code>cppumaker</code> will construct every hpp and hdl files you need in your application. The SDK is not provinding all hpp files but you have to construct them starting from IDL files provided by SDK.}}
 +
{{Note|It is possible to construct all the hpp files when installing the SDK as [[SDKInstallation#Other_Windows_Installations_descriptions|mentioned in a Windows]] installation. It's also possible with other OS. In doing so, you don't need modifying your MakeFile.}}
  
 +
You can find a compilation chain [[Constructing_Components#Make_dependency_of_a_Component|here in this Wiki]] and also [[Counter_Example|here]]. I will probably in the future tackle the makefile problem in a [[MakeFile|Make Chapter]].
  
{{Documentation/Tip|We don't use the same Files and Tools schematic representation in our compilation chain diagrams. I find this one more compact than mine but at the moment I don't plan to change : perhaps in the futur.}}
+
We can also find a compilation chain figure in Java Eclipse Tutorial [[JavaEclipseTuto|here]] shown below :  
  
= Preparing a new Code as a starting Point =
+
[[Image:CompilationChain.png|center|UNO component build chain]]
The programming style presented in [[UNO_automation_with_a_binary_%28executable%29#Introduction_:_starting_from_a_SDK_example |introduction]] doesn't completely satisfy me. I give it because it's more easy to start explanations from an example provided with the SDK than to start with a new code. I find the functions with [[CppSDKAuthors|Niall Dorgan's]] code style better in [http://www.oooforum.org/forum/viewtopic.php?t=8664 oooforum.org]. Then I will adopt it slightly modified : a function is responsible of the connection : ooConnect()
+
  
<source lang="cpp">
 
// Listing 5
 
// C++
 
#include <stdio.h>
 
#include <cppuhelper/bootstrap.hxx>
 
#include <com/sun/star/bridge/XUnoUrlResolver.hpp>
 
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
 
// added
 
#include <com/sun/star/frame/XComponentLoader.hpp>
 
  
using namespace com::sun::star::uno;
+
{{Tip|We don't use the same Files and Tools schematic representation in our compilation chain diagrams. I find this one more compact than mine but at the moment I don't plan to change : perhaps in the future.}}
using namespace com::sun::star::lang;
+
using namespace com::sun::star::bridge;
+
// added
+
using namespace com::sun::star::frame;
+
  
using namespace rtl;
+
= Preparing a new Code as a starting Point =
using namespace cppu;
+
The programming style presented in [[UNO_automation_with_a_binary_%28executable%29#Introduction_:_starting_from_a_SDK_example |introduction]] doesn't completely satisfy me. I give it because it's more easy to start explanations from an example provided with the SDK than to start with a new code. I find the functions with [[CppSDKAuthors|Niall Dorgan's]] code style better in [https://web.archive.org/web/20071123103036/http://www.oooforum.org/forum/viewtopic.phtml?t=8664 oooforum.org]. Then I will adopt it slightly modified : a function is responsible of the connection : ooConnect()
 
+
{{:OOConnect}}
// a procedure for what the so called boostrap
+
Reference< XMultiServiceFactory > ooConnect(){
+
  // create the initial component context
+
  Reference< XComponentContext > rComponentContext =  
+
defaultBootstrap_InitialComponentContext();
+
 
+
  // retrieve the servicemanager from the context
+
  Reference< XMultiComponentFactory > rServiceManager =
+
rComponentContext->getServiceManager();
+
 
+
  // instantiate a sample service with the servicemanager.
+
  Reference< XInterface > rInstance =  rServiceManager->createInstanceWithContext(
+
        OUString::createFromAscii("com.sun.star.bridge.UnoUrlResolver" ),rComponentContext );
+
 
+
  // Query for the XUnoUrlResolver interface
+
  Reference< XUnoUrlResolver > rResolver( rInstance, UNO_QUERY );
+
  if( ! rResolver.is() ){
+
      printf( "Error: Couldn't instantiate com.sun.star.bridge.UnoUrlResolver service\n" );
+
      return NULL;
+
  }
+
  try {
+
      // resolve the uno-url
+
      rInstance = rResolver->resolve( OUString::createFromAscii(
+
        "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" ) );
+
 
+
      if( ! rInstance.is() ){
+
        printf( "StarOffice.ServiceManager is not exported from remote counterpart\n" );
+
        return NULL;
+
      }
+
 
+
      // query for the simpler XMultiServiceFactory interface, sufficient for scripting
+
      Reference< XMultiServiceFactory > rOfficeServiceManager (rInstance, UNO_QUERY);
+
 
+
      if( ! rOfficeServiceManager.is() ){
+
            printf( "XMultiServiceFactory interface is not exported for StarOffice.ServiceManager\n" );
+
            return NULL;
+
        }     
+
        return rOfficeServiceManager;
+
  }
+
  catch( Exception &e ){
+
      OString o = OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US );
+
      printf( "Error: %s\n", o.pData->buffer );
+
      return NULL;
+
  }
+
  return NULL;
+
}
+
 
+
int main( ) {
+
//retrieve an instance of the remote service manager
+
    Reference< XMultiServiceFactory > rOfficeServiceManager;
+
    rOfficeServiceManager = ooConnect();
+
    if( rOfficeServiceManager.is() ){
+
        printf( "Connected sucessfully to the office\n" );
+
    }
+
 
+
//get the desktop service using createInstance returns an XInterface type
+
    Reference< XInterface  > Desktop = rOfficeServiceManager->createInstance(
+
    OUString::createFromAscii( "com.sun.star.frame.Desktop" ));
+
 
+
//query for the XComponentLoader interface
+
    Reference< XComponentLoader > rComponentLoader (Desktop, UNO_QUERY);
+
    if( rComponentLoader.is() ){
+
        printf( "XComponentloader successfully instanciated\n" );
+
    }
+
 
+
//get an instance of the spreadsheet
+
    Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
+
OUString::createFromAscii("private:factory/scalc"),
+
        OUString::createFromAscii("_blank"),
+
        0,
+
        Sequence < ::com::sun::star::beans::PropertyValue >());
+
// add code here
+
    return 0;
+
}
+
</source>
+
Have look also at <idl>com.sun.star.lang.XMultiServiceFactory</idl>, <idl>com.sun.star.uno.XComponentContext</idl>, <idl>com.sun.star.lang.XMultiComponentFactory</idl>, <idl>com.sun.star.uno.XInterface</idl>, <idl>com.sun.star.bridge.XUnoUrlResolver</idl>, <idl>com.sun.star.frame.XComponentLoader</idl> and <idl>com.sun.star.lang.XComponent</idl> interfaces, and at <idl>com.sun.star.beans.PropertyValue</idl> structure, and at <idl>com.sun.star.frame.Desktop</idl> service.
+
  
 +
This function can be used with :
 +
{{:MainOOConnect}}
  
Put the above code in office_connect.cxx file in the <OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding directory (renaming and storing the old office_connect.cxx) and you can use the slightly modified makefile of previous [[UNO_automation_with_a_binary_%28executable%29#Introduction_:_starting_from_a_SDK_example |introduction]] to  compile the project. From now on, we will use this code as starting point. It means I will give only part of this code in the examples : the main() or part of the main. If you want to understand the ooConnect() code, have a look at [[Documentation/BASIC_Guide/StarDesktop|The StarDestop]] describing the Desktop service.
+
{{Note|Put the above code in office_connect.cxx file in the <OpenOffice_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding directory (renaming and storing the old office_connect.cxx) and you can use the slightly modified makefile of previous [[UNO_automation_with_a_binary_%28executable%29#Introduction_:_starting_from_a_SDK_example |introduction]] to  compile the project. From now on, we will use this code as starting point. It means I will give only part of this code in the examples : the main() or part of the main. If you want to understand the ooConnect() code, have a look at [[Documentation/BASIC_Guide/StarDesktop|The StarDestop]] describing the Desktop service.}}
  
To go further with explanations have a look [[IDL_Files_and_Cpp#IDL__and_C.2B.2B|here]]. This hyperlink is not for beginner
+
* an other way to bootstrap is [[Constructing_Helpers#The_GAP.27s_Helper|described here]] with a C++ class.
  
 
= To find  and to save the Document  =
 
= To find  and to save the Document  =
  
Read [[Documentation/BASIC_Guide/StarDesktop|The StarDestop]] if you want to understand more on Desktop service.
+
Read [[Documentation/BASIC_Guide/StarDesktop|The StarDesktop]] if you want to understand more on Desktop service.
  
All this section is based on the change of the below C++ Listing 6 in the previous Listing 5 :
+
This whole section is based on the change of the below C++ Listing 6 in the previous Listing 5 :
  
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
//Listing 6 Creating a new Component
 
//Listing 6 Creating a new Component
 
//C++
 
//C++
Line 362: Line 277:
 
         0,
 
         0,
 
         Sequence < ::com::sun::star::beans::PropertyValue >());
 
         Sequence < ::com::sun::star::beans::PropertyValue >());
</source>
+
</syntaxhighlight>
 
The two parameters "private:factory/scalc" and “_blank” strings can be changed. Let's see what happens with these changes.
 
The two parameters "private:factory/scalc" and “_blank” strings can be changed. Let's see what happens with these changes.
 
Loading an existing File  
 
Loading an existing File  
 
To load an existing file, change the previous code of Listing 6 as
 
To load an existing file, change the previous code of Listing 6 as
{{Documentation/Linux|
+
{{Lin|
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
//Listing 7 Loading a known File
 
//Listing 7 Loading a known File
 
//C++
 
//C++
Line 376: Line 291:
 
         0,
 
         0,
 
         Sequence < ::com::sun::star::beans::PropertyValue >());
 
         Sequence < ::com::sun::star::beans::PropertyValue >());
</source>
+
</syntaxhighlight>
 
}}
 
}}
 
You want to load, or to take an existing opened document with the same name, change the “_blank” parameter :
 
You want to load, or to take an existing opened document with the same name, change the “_blank” parameter :
{{Documentation/Linux|
+
{{Lin|
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
//Listing 8 Changing the _blank Parameter
 
//Listing 8 Changing the _blank Parameter
 
// C++
 
// C++
Line 389: Line 304:
 
         0,
 
         0,
 
         Sequence < ::com::sun::star::beans::PropertyValue >());
 
         Sequence < ::com::sun::star::beans::PropertyValue >());
</source>
+
</syntaxhighlight>
 
}}
 
}}
 
The presented file's name is a UNIX-like  name. Under Windows we can use the equivalence
 
The presented file's name is a UNIX-like  name. Under Windows we can use the equivalence
{{Documentation/Windows|
+
{{Win|
 
<pre>
 
<pre>
 
C:\My Documents\tata.sxc file:///C|/My%20Documents/tata.sxc  
 
C:\My Documents\tata.sxc file:///C|/My%20Documents/tata.sxc  
Line 398: Line 313:
 
}}
 
}}
 
On the left the system depending file's name, what is named the system path, and on the right the URL's file. It is possible to automatically construct the URL's file :
 
On the left the system depending file's name, what is named the system path, and on the right the URL's file. It is possible to automatically construct the URL's file :
{{Documentation/Linux|
+
{{Lin|
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
//Listing 9 Constructing an URL
 
//Listing 9 Constructing an URL
 
// LINUX C++
 
// LINUX C++
Line 413: Line 328:
 
         0,
 
         0,
 
         Sequence < ::com::sun::star::beans::PropertyValue >());
 
         Sequence < ::com::sun::star::beans::PropertyValue >());
</source>
+
</syntaxhighlight>
 
}}
 
}}
 
and the corresponding Windows code :
 
and the corresponding Windows code :
{{Documentation/Windows|
+
{{Win|
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
//Listing 9b Constructing an URL
 
//Listing 9b Constructing an URL
 
// Windows C++ to check
 
// Windows C++ to check
Line 424: Line 339:
 
OUString sDocUrl;
 
OUString sDocUrl;
 
osl::FileBase::getFileURLFromSystemPath(
 
osl::FileBase::getFileURLFromSystemPath(
  OUString::createFromAscii("C:\My Documents\tata.sxc"),sDocUrl);
+
  OUString::createFromAscii("C:\\My Documents\\tata.sxc"),sDocUrl);
 
//get an instance of the spreadsheet
 
//get an instance of the spreadsheet
 
     Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
 
     Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
Line 431: Line 346:
 
         0,
 
         0,
 
         Sequence < ::com::sun::star::beans::PropertyValue >());
 
         Sequence < ::com::sun::star::beans::PropertyValue >());
</source>
+
</syntaxhighlight>
 
}}
 
}}
 
An other way is to construct the URL form a file name and a directory name
 
An other way is to construct the URL form a file name and a directory name
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
//Listing 10 Constructing an URL : an other Way
 
//Listing 10 Constructing an URL : an other Way
 
// C++  LINUX and Windows
 
// C++  LINUX and Windows
Line 450: Line 365:
 
         0,
 
         0,
 
         Sequence < ::com::sun::star::beans::PropertyValue >());
 
         Sequence < ::com::sun::star::beans::PropertyValue >());
</source>
+
</syntaxhighlight>
 
where the file URL is constructed from the executing directory and the file name.
 
where the file URL is constructed from the executing directory and the file name.
Other transformations are possible : see osl::FileBase documentation in http://api.openoffice.org/docs/cpp/ref/names/osl/c-FileBase.html
+
Other transformations are possible : see osl::FileBase documentation in https://www.openoffice.org/api/docs/cpp/ref/names/osl/c-FileBase.html
  
 
== Create a new Document ==
 
== Create a new Document ==
Line 474: Line 389:
 
==The default opened Document==
 
==The default opened Document==
 
The way to obtain the default document is slightly different from the previous two chapters. We then first give the  program lines to change and after the effective changes.
 
The way to obtain the default document is slightly different from the previous two chapters. We then first give the  program lines to change and after the effective changes.
To find the default document, change the previous code given again below in Listing 11 with those given in Listing 12. See also <idl>com.sun.star.uno.XInterface</idl>, <idl>com.sun.star.frame.XComponentLoader</idl> and <idl>com.sun.star.lang.XComponent</idl> interfaces.
+
To find the default document, change the previous code given again below in Listing 11 with those given in Listing 12. See also <idl>com.sun.star.uno.XInterface</idl>, <idl>com.sun.star.frame.XComponentLoader</idl> and <idl>com.sun.star.lang.XComponent</idl> interfaces.
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
//Listing 11 Finding the default Document : code to remove
 
//Listing 11 Finding the default Document : code to remove
 
//C++
 
//C++
Line 495: Line 410:
 
// add code here
 
// add code here
 
     return 0;
 
     return 0;
</source>
+
</syntaxhighlight>
 
here is our new code :
 
here is our new code :
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
//Listing 12 Finding the default Document : Code to insert
 
//Listing 12 Finding the default Document : Code to insert
 
// C++
 
// C++
Line 512: Line 427:
 
Reference< XComponent > xcomponent = xDesktop->getCurrentComponent();  
 
Reference< XComponent > xcomponent = xDesktop->getCurrentComponent();  
 
return 0;
 
return 0;
</source>
+
</syntaxhighlight>
 
As you can see we have to query the XDesktop interface. It is important to note that every time you will query for an interface, you have to add one or two lines in the listing and an other in the makefile. To go further with explanations have a look [[IDL_Files_and_Cpp#IDL__and_C.2B.2B|here]] if you are not a beginner
 
As you can see we have to query the XDesktop interface. It is important to note that every time you will query for an interface, you have to add one or two lines in the listing and an other in the makefile. To go further with explanations have a look [[IDL_Files_and_Cpp#IDL__and_C.2B.2B|here]] if you are not a beginner
  
Line 518: Line 433:
 
In the examples of this section you will query for an interface : the <idl>com.sun.star.frame.XStorable</idl> interface.  
 
In the examples of this section you will query for an interface : the <idl>com.sun.star.frame.XStorable</idl> interface.  
 
Now you can save with adding the code
 
Now you can save with adding the code
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
//Listing 13 How to store a Document  
 
//Listing 13 How to store a Document  
 
// C++  
 
// C++  
Line 529: Line 444:
 
     }else
 
     }else
 
     rcomponentStore->store();
 
     rcomponentStore->store();
</source>
+
</syntaxhighlight>
 
It is also possible to give a name when saving :
 
It is also possible to give a name when saving :
{{Documentation/Windows|
+
{{Win|
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
//Listing 14 How to store a Document (Windows version)
 
//Listing 14 How to store a Document (Windows version)
 
// C++ Windows to check
 
// C++ Windows to check
Line 546: Line 461:
 
"file:///C|/My%20Documents/tata.sxd"),
 
"file:///C|/My%20Documents/tata.sxd"),
 
Sequence < ::com::sun::star::beans::PropertyValue >());
 
Sequence < ::com::sun::star::beans::PropertyValue >());
</source>
+
</syntaxhighlight>
 
}}
 
}}
 
or
 
or
{{Documentation/Linux|
+
{{Lin|
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
//Listing 15 How to store a Document (Linux Version)
 
//Listing 15 How to store a Document (Linux Version)
 
// C++ LINUX
 
// C++ LINUX
Line 563: Line 478:
 
     rcomponentStore->storeAsURL(OUString::createFromAscii("file:///home/smoutou/tata.sxd"),
 
     rcomponentStore->storeAsURL(OUString::createFromAscii("file:///home/smoutou/tata.sxd"),
 
Sequence < ::com::sun::star::beans::PropertyValue >());
 
Sequence < ::com::sun::star::beans::PropertyValue >());
</source>
+
</syntaxhighlight>
 
}}
 
}}
We are now ready to describe all the different Openoffice.org applications. We will begin with OpenOffice.orgCalc but before starting we have a look at Desktop.
+
We are now ready to describe all the different {{AOo}} applications. We will begin with {{AOo}} Calc but before starting we have a look at Desktop.
  
 
=My first Container enumeration with Desktop=
 
=My first Container enumeration with Desktop=
The container is an important OOo programming concept because you find it everywhere. In a worksheet all the sheets are in a container, in a Draw document, all the slides are in a container, in a slide all the shapes are in a container and so on.  
+
The container is an important {{AOo}} programming concept because you find it everywhere. In a worksheet all the sheets are in a container, in a Draw document, all the slides are in a container, in a slide all the shapes are in a container and so on.  
 
==XEnumerationAccess Interface==
 
==XEnumerationAccess Interface==
 
Using <idl>com.sun.star.frame.XDesktop</idl>, <idl>com.sun.star.container.XEnumerationAccess</idl>, <idl>com.sun.star.lang.XServiceInfo</idl> and <idl>com.sun.star.frame.XStorable </idl> interfaces follow us in this example of code :
 
Using <idl>com.sun.star.frame.XDesktop</idl>, <idl>com.sun.star.container.XEnumerationAccess</idl>, <idl>com.sun.star.lang.XServiceInfo</idl> and <idl>com.sun.star.frame.XStorable </idl> interfaces follow us in this example of code :
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
//Listing 16 XEnumeration Interface
 
//Listing 16 XEnumeration Interface
 
// C++
 
// C++
Line 608: Line 523:
 
       }
 
       }
 
     }
 
     }
</source>
+
</syntaxhighlight>
 
This program prints out :
 
This program prints out :
{{Documentation/Linux|
+
{{Lin|
 
<pre>
 
<pre>
-- file:///home/smoutou/OpenOffice.org1.1_SDK/UNOCpp_AP01.sxw
+
-- file:///home/smoutou/OpenOffice_SDK/UNOCpp_AP01.sxw
 
-- file:///home/smoutou/Inetrecup/Openoffice/01prog_menu-context_officebean2.sxw
 
-- file:///home/smoutou/Inetrecup/Openoffice/01prog_menu-context_officebean2.sxw
 
</pre>
 
</pre>
 
}}
 
}}
depending what files are loaded in OOo and what OS do you use.
+
depending what files are loaded in {{AOo}} and what OS you do use.
In general, there are  two ways to access a container : with an index or with a name. The corresponding interface are XIndexAccess and XNameAccess. If you want to know what you can do with an Interface, have a look in the corresponding IDL file. IDL files are explained later in the document ([[IDL_Files_and_Cpp|see chapter 10]]). For instance we give here the <idl>com.sun.star.container.XIndexAcess</idl> IDL file (removing all the comments) :
+
In general, there are  two ways to access a container : with an index or with a name. The corresponding interfaces are XIndexAccess and XNameAccess. If you want to know what you can do with an Interface, have a look in the corresponding IDL file. IDL files are explained later in the document ([[IDL_Files_and_Cpp|see chapter 10]]). For instance we give here the <idl>com.sun.star.container.XIndexAcess</idl> IDL file (removing all the comments) :
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
//Listing 17 XIndexAccess IDL File (without Comments)
 
//Listing 17 XIndexAccess IDL File (without Comments)
 
// IDL
 
// IDL
Line 631: Line 546:
 
};
 
};
 
}; }; }; };   
 
}; }; }; };   
</source>
+
</syntaxhighlight>
The IDL path can be retrieved with this file's content :<OpenOffice.org1.1_SDK>/idl/com/sun/star/container
+
The IDL path can be retrieved with this file's content :<OpenOffice_SDK>/idl/com/sun/star/container
 
and the file's name is only the interface's name followed by “.idl”.
 
and the file's name is only the interface's name followed by “.idl”.
Two methods can be used : getCount() and getByIndex() as it is easy to see in the above listing.
+
Two methods can be used : <tt>getCount()</tt> and <tt>getByIndex()</tt> as it is easy to see in the above listing.
  
 
See also <idl>com.sun.star.container.XElementAccess</idl>.
 
See also <idl>com.sun.star.container.XElementAccess</idl>.
Line 640: Line 555:
 
== XNameAccess Interface ==
 
== XNameAccess Interface ==
 
The second access interface is described with <idl>com.sun.star.container.XNameAccess</idl> :
 
The second access interface is described with <idl>com.sun.star.container.XNameAccess</idl> :
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
//Listing 18 XNameAccess IDL file (without Comments)
 
//Listing 18 XNameAccess IDL file (without Comments)
 
// IDL
 
// IDL
Line 653: Line 568:
 
};
 
};
 
}; }; }; };  
 
}; }; }; };  
</source>
+
</syntaxhighlight>
 
and then three methods. Our goal is to see the desktop as a container. It can effectively contains windows.
 
and then three methods. Our goal is to see the desktop as a container. It can effectively contains windows.
 
See also <idl>com.sun.star.container.XElementAccess</idl>.
 
See also <idl>com.sun.star.container.XElementAccess</idl>.
  
 
==What is not clear for me (and then need Help)==
 
==What is not clear for me (and then need Help)==
{{Documentation/HelpNeeded|Please add text on difference between services and interfaces}}
+
{{HelpNeeded|EN|Please add text on difference between services and interfaces}}
 
Later on, I will describe a [[Constructing_Helpers#Reflection_Helper|reflection helper]]. It allows us to know methods and properties of an object...
 
Later on, I will describe a [[Constructing_Helpers#Reflection_Helper|reflection helper]]. It allows us to know methods and properties of an object...
  
When I use this helper to see methods of “Desktop” object I clearly see getComponents() method. But I cannot call it. I have to construct a desktop variable named “desk” in the listing above before to call it. The desktop variable is a service while desk is an interface. In C++ you have to use interface while in OOoBasic you use service.
+
When I use this helper to see methods of “Desktop” object I clearly see getComponents() method. But I cannot call it. I have to construct a desktop variable named “desk” in the listing above before to call it. The desktop variable is a service while desk is an interface. In C++ you have to use interface while in {{AOo}} Basic you use service.
  
 
We don't need an “#include <com/sun/star/lang/XComponent.hpp>” and I don't see why !
 
We don't need an “#include <com/sun/star/lang/XComponent.hpp>” and I don't see why !
Line 668: Line 583:
  
 
=Chapter Summary=
 
=Chapter Summary=
I am always more interested in diagram than in long explanation : probably because of my little knowledge in English. Schematic drawings are easy to grasp only if we know every conventions. If not the case please read again the beginning of this chapter (particularly [[UNO_automation_with_a_binary_%28executable%29#Introduction_:_starting_from_a_SDK_example |introduction]]). We give now in a schematic form, all what we have learnt in this chapter.  
+
I am always more interested in diagram than in long explanation : probably because of my little knowledge in English. Schematic drawings are easy to grasp only if we know every conventions. If not the case please read again the beginning of this chapter (particularly [[UNO_automation_with_a_binary_%28executable%29#Introduction_:_starting_from_a_SDK_example |introduction]]). We now give, in a schematic form, all what we have learnt in this chapter.  
  
 
[[Image:ch4fig3Summary.png]]
 
[[Image:ch4fig3Summary.png]]
{{Documentation/Note|'''Note''' : The arrows in this drawing are what I call in a forthcoming chapter, finding a path in an IDL-Tree. The lecture of the corresponding [[Programming_OooWriter#Going_further_with_Inspector|section]] would be useful, even if at the moment, you are unable to understand completely the problem. Viewing the problem from different angles is always a good exercise.}}
+
{{Note|'''Note''' : The arrows in this drawing are what I call in a forthcoming chapter, finding a path in an IDL-Tree. The lecture of the corresponding [[Programming_OooWriter#Going_further_with_Inspector|section]] would be useful, even if at the moment, you are unable to understand completely the problem. Viewing the problem from different angles is always a good exercise.}}
  
  
Line 677: Line 592:
  
 
= See also =
 
= See also =
* [[Documentation/BASIC_Guide/API_Intro|Introduction to the OpenOffice.org API]]
+
* [[FR/Documentation/L%27automation_d%27OpenOffice.org_avec_un_binaire_ex%C3%A9cutable|French version of this chapter]].
 +
* [[Documentation/BASIC_Guide/API_Intro|Introduction to the {{AOo}} API]]
 
* [[Documentation/BASIC_Guide/StarDesktop|The StarDestop]]
 
* [[Documentation/BASIC_Guide/StarDesktop|The StarDestop]]
 
* [[Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno|C++ and UNO tutorial]]
 
* [[Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno|C++ and UNO tutorial]]
Line 684: Line 600:
 
* Writing a Program to Control OpenOffice.org, by Franco Pingiori — [http://www.linuxjournal.com/article/8550 Part 1] and [http://www.linuxjournal.com/article/8608 Part 2], Linux Journal
 
* Writing a Program to Control OpenOffice.org, by Franco Pingiori — [http://www.linuxjournal.com/article/8550 Part 1] and [http://www.linuxjournal.com/article/8608 Part 2], Linux Journal
  
[[Category:Development]]
 
 
[[Category:Uno]]
 
[[Category:Uno]]
 
[[Category:Cpp]]
 
[[Category:Cpp]]
 
[[Category:Tutorial]]
 
[[Category:Tutorial]]
 +
[[Category:Samples]]

Latest revision as of 12:06, 16 May 2022

doc OOo


Edit-find-replace.png This article should be checked for accuracy and conformity to style.

We want now discuss a fully UNO/OpenOffice program : we mean a program which automates some tasks on Apache OpenOffice documents, file loading, file modifying, file saving... all in all “Create a binary program to replace a OOBasic program”. The border between the examples of previous chapter and of this chapter is vague. I can only say  : if you imagine to automate any problem and create a program for it, this paragraph and the next chapters are for you. Please read also Introduction to the Apache OpenOffice API and documentation on necessary tools for UNO development in Developer's Guide.

Introduction : starting from a SDK example

Introduction to services and interfaces

Before going further, I have to explain the minimal organization of UNO API, particularly of the distinction between services and interfaces. A service is a set of interfaces. Both have a name starting with "com.sun.star" followed by a module's name ".lang" for instance and terminate with the effective service or interface name. An interface name begins always with a 'X' character. For instance, com.sun.star.lang.ServiceManager is a service and clicking on the link shows you it contains many interfaces, and com.sun.star.lang.XServiceInfo is one of them (name starting with a X).

See also UNO API in Apache OpenOffice Basic document and Developer's Guide.

ServiceManager and Desktop objects

Danny Brewer wrote in the oooforum.org : « To do almost anything useful with Apache OpenOffice via the API, in almost all cases, you must either create a new document, or open an existing document. Then you would manipulate the contents of the document, extract information from it, print it, convert it to a different format, work with data forms on the document, or perform various other tasks with office documents.

Therefore, one of the first things to learn is how to open or create documents.

In order to work with Apache OpenOffice through the API, you must first acquire two essential objects.

  1. the com.sun.star.lang.ServiceManager
  2. the com.sun.star.frame.Desktop

Once you have the ServiceManager, you call its createInstance() method to get the Desktop object. Once you have the Desktop object, you can use it to create or open new documents. »

More on com.sun.star.frame.Desktop service here in OOoBasic Guide.

Getting the Service Manager

In every different programming language, there are different mechanisms for acquiring the Service Manager. One way of getting the service manager is given in one SDK example : <OpenOffice_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding We first check the example (under Linux) :

Documentation linux.png
cd <OpenOffice_SDK>
./setsdkenv_unix
cd examples/DevelopersGuide/ProfUNO/CppBinding
make
make Office_connect.run

which only writes out "Connected successfully to the office". Under Windows it would be :

Documentation windows.png
cd <OpenOffice_SDK>
setsdkenv_windows
cd examples/DevelopersGuide/ProfUNO/CppBinding
make
make Office_connect.run

We first start our discussion from this example. Later on, we will provide another starting code. All listings we will give below are to be added to this example. Where ? It's shown here  :

// Listing 1 Our first Connection
//C++  *** extract from office_connect.cxx
int main( )
{
	// create the initial component context
	Reference< XComponentContext > rComponentContext =
		defaultBootstrap_InitialComponentContext();
	// retrieve the servicemanager from the context
	Reference< XMultiComponentFactory > rServiceManager =
		rComponentContext->getServiceManager();
	// instantiate a sample service with the servicemanager.
	Reference< XInterface > rInstance =
		rServiceManager->createInstanceWithContext(
			OUString::createFromAscii("com.sun.star.bridge.UnoUrlResolver" ),
			rComponentContext );
	// Query for the XUnoUrlResolver interface
	Reference< XUnoUrlResolver > rResolver( rInstance, UNO_QUERY );
	if( ! rResolver.is() )
	{
		printf( "Error: Couldn't instantiate com.sun.star.bridge.UnoUrlResolver service\n" );
		return 1;
	}
	try
	{
		// resolve the uno-url
		rInstance = rResolver->resolve( OUString::createFromAscii( 
			"uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" ) );
		if( ! rInstance.is() )
		{
			printf( "StarOffice.ServiceManager is not exported from remote counterpart\n" );
			return 1;
		}
		// query for the simpler XMultiServiceFactory interface, sufficient for scripting
		Reference< XMultiServiceFactory > rOfficeServiceManager (rInstance, UNO_QUERY);
		if( ! rInstance.is() )
        {
            printf( "XMultiServiceFactory interface is not exported for StarOffice.ServiceManager\n" );
            return 1;
        }
 
        printf( "Connected sucessfully to the office\n" );
 
//  ***** add your code here **************
 
	}
	catch( Exception &e )
	{
		OString o = OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US );
		printf( "Error: %s\n", o.pData->buffer );
		return 1;
	}
	return 0;
}

I cannot explain all the lines of this source file, but if you want to have an idea of what you have to learn when using UNO SDK, have a look at all the interfaces encountered in this snippet. They are : com.sun.star.uno.XComponentContext, com.sun.star.lang.XMultiComponentFactory, com.sun.star.uno.XInterface and com.sun.star.bridge.XUnoUrlResolver.

I can just say : here is one way among others to get the ServiceManager. The way to obtain the ServiceManager is named bootstraping process in Apache OpenOffice : see the next section or the complete explanation. A second way is given in <OpenOffice_SDK>/examples/cpp/DocumentLoader's example.

Before to go further I want to give explanations. The code above shows, even if you don't understend it, how we program with UNO and C++. You should write C++ code with many strange variables like :

Reference< XSomething > rSomething = aWayToObtainSomething();

In this code XSomething is an interface because its name has a 'X' as first character. In the above code you have two ways to obtain interfaces:

// obtain an interface first way : buildin function
Reference< XComponentContext > rComponentContext = defaultBootstrap_InitialComponentContext();

and also

// obtain an interface second way : UNO_QUERY starting from a service
Reference< XUnoUrlResolver > rResolver( rInstance, UNO_QUERY );

How do I know I start from a service ? If the first character of the name is not a 'X', it is a service and if you want to obtain it, you have to cast it with a com.sun.star.uno.XInterface. You can see it's the case for rResolver variable in the listing 1 (com.sun.star.bridge.UnoUrlResolver service).

Documentation note.png

The C++ language doesn't allow you to use services directly, but rather interfaces. Every service has to be casted in a variable of type com.sun.star.uno.XInterface. It's not the same with Apache OpenOffice Basic programming which in the contrary allow you to use directly services.

That piece of code is in general called bootstrapping and will be examined in the next section.

Introduction to Bootstrapping

Bootstrap processes are more deeply discussed later. We give only an introduction here.

To memorize this previous piece of code is not easy and probably useless. However, we give a drawing representation of this piece of code to show the main step of the bootstrap process.

Bootstrapping Diagram

If you are interested, have a simultaneous look at the code and the drawing, to see the schematic conventions I have used to carry out the Figure above. For instance, both XInterface are connected because we use the same variable in fact. The gray filled rectangles are for parameters... and so on.

We want now the desktop and load a Apache OpenOffice Calc component.

The first step is to obtain desktop. You then add this code :

// Listing 2 Obtaining a desktop interface
// C++
Reference< XInterface  > xDesktop = rOfficeServiceManager->createInstance(
   	OUString::createFromAscii( "com.sun.star.frame.Desktop" ));

Your desktop object is in xDesktop variable. More on Desktop service here.

Second step : query for the XComponentLoader interface

// Listing 3  Query a XcomponentLoader Interface
// C++
// query a XcomponentLoader Interface 
Reference< XComponentLoader > rComponentLoader (xDesktop, UNO_QUERY);
if( rComponentLoader.is() )
    	{
        	printf( "XComonentloader succesfully instanciated\n" );
    	}

Before to see the problems with this code, we give again a schematic representation :

Component Loader

The code above gives error messages :

error 'XcomponentLoader' undeclared (First use this function) ....

It shows us there is a problem with XComponentLoader : this indicates we have probably to add a hpp header file in the program's include statements. The file's name is probably XComponentLoader.hpp but we have to find where it lies. One way is to go in the general index and to look for XComponentLoader. We find : com.sun.star.frame.XComponentLoader which indicates

#include <com/sun/star/frame/XComponentLoader.hpp>

is required. We can try and see it is not enough, we obtain always the same error message and one new before : com/sun/star/frame/XComponentLoader.hpp: No such file or directory I have already discussed this fact : the SDK doesn't provide any hpp file, they have to be constructed from IDL files. An other task is then: open and change the makefile. Only add the correspondant line:

#added com.sun.star.frame.XComponentLoader
TYPES := \
	com.sun.star.uno.XNamingService \
	com.sun.star.uno.XComponentContext \
	com.sun.star.uno.XWeak \
	com.sun.star.uno.XAggregation \
	com.sun.star.frame.XComponentLoader \
	com.sun.star.lang.XMain \ 
        com.sun.star.lang.XMultiServiceFactory \
	com.sun.star.lang.XSingleComponentFactory \
	com.sun.star.lang.XTypeProvider \
	com.sun.star.lang.XComponent \
	com.sun.star.registry.XSimpleRegistry \
	com.sun.star.registry.XImplementationRegistration \
	com.sun.star.bridge.XBridgeFactory \
	com.sun.star.bridge.XUnoUrlResolver \
    com.sun.star.container.XHierarchicalNameAccess

Making the project gives again the same error message. What is still lacking now ? Only a namespace statement in the source file :

// C++
using namespace com::sun::star::frame;

(To go further with the two steps above see Getting an Interface in C++)

Step 3 : get an instance of the spreadsheet

// Listing 4 Loading a new OOoCalc document
// C++
Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
	OUString::createFromAscii("private:factory/scalc"),
        OUString::createFromAscii("_blank"),
        0,
        Sequence < ::com::sun::star::beans::PropertyValue >());

and it works : you have a new Apache OpenOffice Calc document.

This hyperlink will tackle again the header file construction problem.

An other thing to note is : when constructing variables with Reference template like :

	Reference<...>varName 

you can check with

	varName.is() 

function. The problem of what to do if this variable is not created (varName.is() is false) is complex and not deeply tackled in this document. It refers to exceptions.

The Compilation Chain

Perhaps we need to recall we use the phrase "compilation chain" to refer to a schematic representation of the makefile. This give information on what kind of files and tools are involved when constructing a UNO binary. Skills on the compilation chain are important only if you want to modify a makefile. At this point, it is important for you to have skills on necessary tools for UNO development.

UNO binary build chain

Please have a look here if you want to see how regmerge and regcomp are used for office_connect.rdb file creation.

Documentation note.png Important Note : The more important point in this compilation chain is in fact that cppumaker will construct every hpp and hdl files you need in your application. The SDK is not provinding all hpp files but you have to construct them starting from IDL files provided by SDK.
Documentation note.png It is possible to construct all the hpp files when installing the SDK as mentioned in a Windows installation. It's also possible with other OS. In doing so, you don't need modifying your MakeFile.

You can find a compilation chain here in this Wiki and also here. I will probably in the future tackle the makefile problem in a Make Chapter.

We can also find a compilation chain figure in Java Eclipse Tutorial here shown below :

UNO component build chain


Tip.png We don't use the same Files and Tools schematic representation in our compilation chain diagrams. I find this one more compact than mine but at the moment I don't plan to change : perhaps in the future.


Preparing a new Code as a starting Point

The programming style presented in introduction doesn't completely satisfy me. I give it because it's more easy to start explanations from an example provided with the SDK than to start with a new code. I find the functions with Niall Dorgan's code style better in oooforum.org. Then I will adopt it slightly modified : a function is responsible of the connection : ooConnect()

// Listing 0
// C++
#include <stdio.h>
#include <cppuhelper/bootstrap.hxx>
#include <com/sun/star/bridge/XUnoUrlResolver.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
// added
#include <com/sun/star/frame/XComponentLoader.hpp>
 
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::bridge;
// added
using namespace com::sun::star::frame;
 
using namespace rtl;
using namespace cppu;
 
// a procedure for what the so called boostrap
Reference< XMultiServiceFactory > ooConnect(){
   // create the initial component context
   Reference< XComponentContext > rComponentContext = 
				defaultBootstrap_InitialComponentContext();
 
   // retrieve the servicemanager from the context
   Reference< XMultiComponentFactory > rServiceManager = 
				rComponentContext->getServiceManager();
 
   // instantiate a sample service with the servicemanager.
   Reference< XInterface > rInstance =  rServiceManager->createInstanceWithContext(
         OUString::createFromAscii("com.sun.star.bridge.UnoUrlResolver" ),rComponentContext );
 
   // Query for the XUnoUrlResolver interface
   Reference< XUnoUrlResolver > rResolver( rInstance, UNO_QUERY );
   if( ! rResolver.is() ){
      printf( "Error: Couldn't instantiate com.sun.star.bridge.UnoUrlResolver service\n" );
      return NULL;
   }
   try {
      // resolve the uno-url
      rInstance = rResolver->resolve( OUString::createFromAscii(
         "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" ) );
 
      if( ! rInstance.is() ){
         printf( "StarOffice.ServiceManager is not exported from remote counterpart\n" );
         return NULL;
      }
 
      // query for the simpler XMultiServiceFactory interface, sufficient for scripting
      Reference< XMultiServiceFactory > rOfficeServiceManager (rInstance, UNO_QUERY);
 
      if( ! rOfficeServiceManager.is() ){
            printf( "XMultiServiceFactory interface is not exported for StarOffice.ServiceManager\n" );
            return NULL;
        }       
        return rOfficeServiceManager;
   }
   catch( Exception &e ){
      OString o = OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US );
      printf( "Error: %s\n", o.pData->buffer );
      return NULL;
   }
   return NULL;
}

Note : You have eventually to change "port=8100" into "port=2083" for recent SDK (after 2.X).

You can have a look at :

  1. com.sun.star.uno.XComponentContext, com.sun.star.lang.XMultiComponentFactory, com.sun.star.uno.XInterface, com.sun.star.bridge.XUnoUrlResolver and com.sun.star.lang.XMultiServiceFactory interfaces,
  2. com.sun.star.bridge.UnoUrlResolver service

This function can be used with :

//Listing 0b Again our starting main Code
int main( ) {
//retrieve an instance of the remote service manager
    Reference< XMultiServiceFactory > rOfficeServiceManager;
    rOfficeServiceManager = ooConnect();
    if( rOfficeServiceManager.is() ){
        printf( "Connected sucessfully to the office\n" );
    }
 
//get the desktop service using createInstance returns an XInterface type
    Reference< XInterface  > Desktop = rOfficeServiceManager->createInstance(
    OUString::createFromAscii( "com.sun.star.frame.Desktop" ));
 
//query for the XComponentLoader interface
    Reference< XComponentLoader > rComponentLoader (Desktop, UNO_QUERY);
    if( rComponentLoader.is() ){
        	printf( "XComponentloader successfully instanciated\n" );
    	}
 
//get an instance of the spreadsheet
    Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
	OUString::createFromAscii("private:factory/scalc"),
        OUString::createFromAscii("_blank"),
        0,
        Sequence < ::com::sun::star::beans::PropertyValue >());
// add code here
    return 0;
}

This code is called a bootstrap and uses :

  1. com.sun.star.lang.XMultiServiceFactory, com.sun.star.uno.XInterface, com.sun.star.frame.XComponentLoader and com.sun.star.lang.XComponent interfaces
  2. com.sun.star.frame.Desktop service
  3. com.sun.star.beans.PropertyValue structure.

Remember each time you query for an interface you have to add code lines (if they don't exist) in the source code and a line in the makefile. I will generally add comments to prevent omissions. You can find more explanations here (if you are not a beginner).

Documentation note.png Important Note : The more important point in the compilation chain of the examples above is that cppumaker will construct every hpp and hdl files you need in your application. The SDK doesn't provide every hpp files, but you have to construt them starting from IDL files provided by SDK.
Documentation note.png It is possible to construct all the hpp files when installing the SDK as mentioned in a Windows installation. It's also possible with other OS. In doing so, you don't need modifying your MakeFile.
Documentation note.png Put the above code in office_connect.cxx file in the <OpenOffice_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding directory (renaming and storing the old office_connect.cxx) and you can use the slightly modified makefile of previous introduction to compile the project. From now on, we will use this code as starting point. It means I will give only part of this code in the examples : the main() or part of the main. If you want to understand the ooConnect() code, have a look at The StarDestop describing the Desktop service.

To find and to save the Document

Read The StarDesktop if you want to understand more on Desktop service.

This whole section is based on the change of the below C++ Listing 6 in the previous Listing 5 :

//Listing 6 Creating a new Component
//C++
//get an instance of the spreadsheet
    Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
	OUString::createFromAscii("private:factory/scalc"),
        OUString::createFromAscii("_blank"),
        0,
        Sequence < ::com::sun::star::beans::PropertyValue >());

The two parameters "private:factory/scalc" and “_blank” strings can be changed. Let's see what happens with these changes. Loading an existing File To load an existing file, change the previous code of Listing 6 as

Documentation linux.png
//Listing 7 Loading a known File
//C++
//get an instance of the spreadsheet
    Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
	OUString::createFromAscii("file:///home/smoutou/work/undocument.sxc"),
        OUString::createFromAscii("_blank"),
        0,
        Sequence < ::com::sun::star::beans::PropertyValue >());

You want to load, or to take an existing opened document with the same name, change the “_blank” parameter :

Documentation linux.png
//Listing 8 Changing the _blank Parameter
// C++
//get an instance of the spreadsheet
    Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
	OUString::createFromAscii("file:///home/smoutou/OneDocument.sxc"),
        OUString::createFromAscii("_default"),
        0,
        Sequence < ::com::sun::star::beans::PropertyValue >());

The presented file's name is a UNIX-like name. Under Windows we can use the equivalence

Documentation windows.png
C:\My Documents\tata.sxc	file:///C|/My%20Documents/tata.sxc 

On the left the system depending file's name, what is named the system path, and on the right the URL's file. It is possible to automatically construct the URL's file :

Documentation linux.png
//Listing 9 Constructing an URL
// LINUX C++
// Don't forget #include <osl/file.hxx>
 
	OUString sDocUrl;
    osl::FileBase::getFileURLFromSystemPath(
                 OUString::createFromAscii("/home/smoutou/edt.sxd"),sDocUrl);
//get an instance of the spreadsheet
    Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
	    sDocUrl,
        OUString::createFromAscii("_blank"),
        0,
        Sequence < ::com::sun::star::beans::PropertyValue >());

and the corresponding Windows code :

Documentation windows.png
//Listing 9b Constructing an URL
// Windows C++ to check
// Don't forget #include <osl/file.hxx>
 
	OUString sDocUrl;
	osl::FileBase::getFileURLFromSystemPath(
			  OUString::createFromAscii("C:\\My Documents\\tata.sxc"),sDocUrl);
//get an instance of the spreadsheet
    Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
	    sDocUrl,
        OUString::createFromAscii("_blank"),
        0,
        Sequence < ::com::sun::star::beans::PropertyValue >());

An other way is to construct the URL form a file name and a directory name

//Listing 10 Constructing an URL : an other Way
// C++  LINUX and Windows
// Don't forget #include <osl/file.hxx>
// Don't forget #include <osl/process.hxx>
	OUString sDocUrl, sWorkingDir;
    osl_getProcessWorkingDir(&sWorkingDir.pData);
    osl::FileBase::getAbsoluteFileURL( sWorkingDir, OUString::createFromAscii("edt.sxd"),
												 sDocUrl);
 
//get an instance of the spreadsheet
    Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
	    sDocUrl,
        OUString::createFromAscii("_blank"),
        0,
        Sequence < ::com::sun::star::beans::PropertyValue >());

where the file URL is constructed from the executing directory and the file name. Other transformations are possible : see osl::FileBase documentation in https://www.openoffice.org/api/docs/cpp/ref/names/osl/c-FileBase.html

Create a new Document

You choose your document type and then replace "private:factory/scalc" by the corresponding magical text :

magical text
new Document's Type Magical Text
Writer text private:factory/swriter
Calc spreadsheet private:factory/scalc
Draw private:factory/sdraw
Impress presentation private:factory/simpress
Math formula private:factory/smath

The default opened Document

The way to obtain the default document is slightly different from the previous two chapters. We then first give the program lines to change and after the effective changes. To find the default document, change the previous code given again below in Listing 11 with those given in Listing 12. See also com.sun.star.uno.XInterface, com.sun.star.frame.XComponentLoader and com.sun.star.lang.XComponent interfaces.

//Listing 11 Finding the default Document : code to remove
//C++
//get the desktop service using createInstance returns an XInterface type
    Reference< XInterface  > Desktop = rOfficeServiceManager->createInstance(
    OUString::createFromAscii( "com.sun.star.frame.Desktop" ));
 
//query for the XComponentLoader interface
    Reference< XComponentLoader > rComponentLoader (Desktop, UNO_QUERY);
    if( rComponentLoader.is() ){
        	printf( "XComponentloader successfully instanciated\n" );
    	}
//get an instance of the spreadsheet
    Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
	OUString::createFromAscii("private:factory/scalc"),
        OUString::createFromAscii("_blank"),
        0,
        Sequence < ::com::sun::star::beans::PropertyValue >());
// add code here
    return 0;

here is our new code :

//Listing 12 Finding the default Document : Code to insert
// C++
// Don't forget the #include <com/sun/star/frame/XDesktop.hpp>
// Don't forget to add com.sun.star.frame.XDesktop \ in the makefile
 
//get the desktop service using createInstance returns an XInterface type
    Reference< XInterface  > Desktop = rOfficeServiceManager->createInstance(
    OUString::createFromAscii( "com.sun.star.frame.Desktop" ));
 
//query the XDesktop Interface
	Reference< XDesktop > xDesktop (Desktop, UNO_QUERY);
 
	Reference< XComponent > xcomponent = xDesktop->getCurrentComponent(); 
	return 0;

As you can see we have to query the XDesktop interface. It is important to note that every time you will query for an interface, you have to add one or two lines in the listing and an other in the makefile. To go further with explanations have a look here if you are not a beginner

Save the Document

In the examples of this section you will query for an interface : the com.sun.star.frame.XStorable interface. Now you can save with adding the code

//Listing 13 How to store a Document 
// C++ 
// Don't forget the #include <com/sun/star/frame/XStorable.hpp>
// Don't forget to add com.sun.star.frame.XStorable \ in the makefile
// Query for Xstorable interface
    Reference< XStorable > rcomponentStore (xcomponent, UNO_QUERY);
	if( !rcomponentStore.is() ){
        	printf( "XStorable Not successfully instanciated\n" );
    	}else
    rcomponentStore->store();

It is also possible to give a name when saving :

Documentation windows.png
//Listing 14 How to store a Document (Windows version)
// C++ Windows to check
//document save as 
// Don't forget the #include <com/sun/star/frame/XStorable.hpp>
// Don't forget to add com.sun.star.frame.XStorable \ in the makefile
// query for the ::com::sun::star::frame::XStorable interface
    Reference< XStorable > rcomponentStore (xcomponent, UNO_QUERY);
	if( !rcomponentStore.is() ){
        	printf( "XStorable Not successfully instanciated\n" );
    	}else
    rcomponentStore->storeAsURL(OUString::createFromAscii(
				"file:///C|/My%20Documents/tata.sxd"),
				Sequence < ::com::sun::star::beans::PropertyValue >());

or

Documentation linux.png
//Listing 15 How to store a Document (Linux Version)
// C++ LINUX
//document save as 
// Don't forget the #include <com/sun/star/frame/XStorable.hpp>
// Don't forget to add "com.sun.star.frame.XStorable \" in the makefile
// query for the ::com::sun::star::frame::XStorable interface
    Reference< XStorable > rcomponentStore (xcomponent, UNO_QUERY);
	if( !rcomponentStore.is() ){
        	printf( "XStorable Not successfully instanciated\n" );
    	}else
    rcomponentStore->storeAsURL(OUString::createFromAscii("file:///home/smoutou/tata.sxd"),
				Sequence < ::com::sun::star::beans::PropertyValue >());

We are now ready to describe all the different Apache OpenOffice applications. We will begin with Apache OpenOffice Calc but before starting we have a look at Desktop.

My first Container enumeration with Desktop

The container is an important Apache OpenOffice programming concept because you find it everywhere. In a worksheet all the sheets are in a container, in a Draw document, all the slides are in a container, in a slide all the shapes are in a container and so on.

XEnumerationAccess Interface

Using com.sun.star.frame.XDesktop, com.sun.star.container.XEnumerationAccess, com.sun.star.lang.XServiceInfo and com.sun.star.frame.XStorable interfaces follow us in this example of code :

//Listing 16 XEnumeration Interface
// C++
// container
// Don't forget to add : using namespace com::sun::star::frame;
// Don't forget to add : #include <com/sun/star/frame/XDesktop.hpp>
// Don't forget to add "com.sun.star.frame.XDesktop \" in the makefile
	Reference<XDesktop> desk(xServiceManager->createInstance(
			OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY);
 
// Don't forget to add : using namespace com::sun::star::container;
// Don't forget to add : #include <com/sun/star/container/XEnumerationAccess.hpp>
// Don't forget to add "com.sun.star.container.XEnumerationAccess \" in the makefile
    Reference<XEnumerationAccess> comps = desk->getComponents();
    if (comps->hasElements()) {
      Reference<XEnumeration> compenum(comps->createEnumeration(), UNO_QUERY);
      while (compenum->hasMoreElements()) {
        Reference<XComponent> comp(compenum->nextElement(), UNO_QUERY);
 
// Don't forget to add : using namespace com::sun::star::lang;
// Don't forget to add : #include <com/sun/star/lang/XServiceInfo.hpp>
// Don't forget to add "com.sun.star.lang.XServiceInfo \" in the makefile
        Reference<XServiceInfo> serviceinfo(comp, UNO_QUERY);
        if (serviceinfo->supportsService(
               OUString::createFromAscii("com.sun.star.document.OfficeDocument"))) {
 
// Don't forget to add : #include <com/sun/star/frame/XStorable.hpp>
// Don't forget to add "com.sun.star.frame.XStorable \" in the makefile
          Reference<XStorable> storeable(comp, UNO_QUERY);
          if (storeable->hasLocation()) {
            OString loc = OUStringToOString(storeable->getLocation(),
                                                 RTL_TEXTENCODING_ASCII_US);
	         printf("-- %s\n",loc.pData->buffer);
          }
        }
      }
    }

This program prints out :

Documentation linux.png
-- file:///home/smoutou/OpenOffice_SDK/UNOCpp_AP01.sxw
-- file:///home/smoutou/Inetrecup/Openoffice/01prog_menu-context_officebean2.sxw

depending what files are loaded in Apache OpenOffice and what OS you do use. In general, there are two ways to access a container : with an index or with a name. The corresponding interfaces are XIndexAccess and XNameAccess. If you want to know what you can do with an Interface, have a look in the corresponding IDL file. IDL files are explained later in the document (see chapter 10). For instance we give here the com.sun.star.container.XIndexAcess IDL file (removing all the comments) :

//Listing 17 XIndexAccess IDL File (without Comments)
// IDL
module com {  module sun {  module star {  module container {
interface XIndexAccess: com::sun::star::container::XElementAccess
{
	long getCount(); 
	any getByIndex( [in] long Index )
			raises( com::sun::star::lang::IndexOutOfBoundsException,
					com::sun::star::lang::WrappedTargetException );
 
};
}; }; }; };

The IDL path can be retrieved with this file's content :<OpenOffice_SDK>/idl/com/sun/star/container and the file's name is only the interface's name followed by “.idl”. Two methods can be used : getCount() and getByIndex() as it is easy to see in the above listing.

See also com.sun.star.container.XElementAccess.

XNameAccess Interface

The second access interface is described with com.sun.star.container.XNameAccess :

//Listing 18 XNameAccess IDL file (without Comments)
// IDL
module com {  module sun {  module star {  module container {
interface XNameAccess: com::sun::star::container::XElementAccess
{
	any getByName( [in] string aName ) 
			raises( com::sun::star::container::NoSuchElementException, 
					com::sun::star::lang::WrappedTargetException ); 
	sequence<string> getElementNames(); 
	boolean hasByName( [in] string aName );
};
}; }; }; };

and then three methods. Our goal is to see the desktop as a container. It can effectively contains windows. See also com.sun.star.container.XElementAccess.

What is not clear for me (and then need Help)

Documentation needshelp.png This article needs help


Please add text on difference between services and interfaces

Later on, I will describe a reflection helper. It allows us to know methods and properties of an object...

When I use this helper to see methods of “Desktop” object I clearly see getComponents() method. But I cannot call it. I have to construct a desktop variable named “desk” in the listing above before to call it. The desktop variable is a service while desk is an interface. In C++ you have to use interface while in Apache OpenOffice Basic you use service.

We don't need an “#include <com/sun/star/lang/XComponent.hpp>” and I don't see why !

You can find any explanations here written after the lines above (if you are not a beginner).

Chapter Summary

I am always more interested in diagram than in long explanation : probably because of my little knowledge in English. Schematic drawings are easy to grasp only if we know every conventions. If not the case please read again the beginning of this chapter (particularly introduction). We now give, in a schematic form, all what we have learnt in this chapter.

Ch4fig3Summary.png

Documentation note.png Note : The arrows in this drawing are what I call in a forthcoming chapter, finding a path in an IDL-Tree. The lecture of the corresponding section would be useful, even if at the moment, you are unable to understand completely the problem. Viewing the problem from different angles is always a good exercise.


See also

Personal tools