Difference between revisions of "IDL Files and Cpp"
m (→Gathering UNO information with IDL files) |
m (→Mapping for Modules and Interfaces) |
||
(23 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
− | {{ | + | {{NeedsRework|EN}} |
[[IDL_Files_and_Cpp zh|中]] | [[IDL_Files_and_Cpp zh|中]] | ||
Line 39: | Line 39: | ||
'''Rule 1''' : C++ language allows us to go through interfaces, I mean starting from an interface and to get an other interface. We will focus us on the problem of [[IDL_Files_and_Cpp#Getting_an_interface_in_C.2B.2B|getting such interfaces later]]. | '''Rule 1''' : C++ language allows us to go through interfaces, I mean starting from an interface and to get an other interface. We will focus us on the problem of [[IDL_Files_and_Cpp#Getting_an_interface_in_C.2B.2B|getting such interfaces later]]. | ||
− | {{ | + | {{Note|'''Note''' : This rule is true for C++ language and in my knowledge for Java language. But OOoBasic language allows, for instance, using variables for services. It's more easy to use and gives shorter programs.}} |
'''Rule 2''' : if we are constrained to use a service, we have to use a <idl>com.sun.star.uno.XInterface</idl> variable as container. This type is an interface because begining with a letter X and this operation is then called a cast. We tackle [[IDL_Files_and_Cpp#Getting_an_Interface_through_XMultiServiceFactory|this problem further with C++]]. | '''Rule 2''' : if we are constrained to use a service, we have to use a <idl>com.sun.star.uno.XInterface</idl> variable as container. This type is an interface because begining with a letter X and this operation is then called a cast. We tackle [[IDL_Files_and_Cpp#Getting_an_Interface_through_XMultiServiceFactory|this problem further with C++]]. | ||
Line 61: | Line 61: | ||
And now the corresponding IDL file : | And now the corresponding IDL file : | ||
− | < | + | <syntaxhighlight lang="idl"> |
// IDL | // IDL | ||
interface XdrivingDirection | interface XdrivingDirection | ||
Line 68: | Line 68: | ||
void turnRight(); | void turnRight(); | ||
}; | }; | ||
− | </ | + | </syntaxhighlight> |
==Specifying a service== | ==Specifying a service== | ||
Example above is still used, here is the corresponding IDL specification : | Example above is still used, here is the corresponding IDL specification : | ||
− | < | + | <syntaxhighlight lang="idl"> |
// IDL | // IDL | ||
interface XdrivingDirection | interface XdrivingDirection | ||
Line 92: | Line 92: | ||
[attribute] float angle; | [attribute] float angle; | ||
}; | }; | ||
− | </ | + | </syntaxhighlight> |
We see a float type and we would use other IDL types later. | We see a float type and we would use other IDL types later. | ||
== Specifying a module == | == Specifying a module == | ||
Now, the same example would give this IDL specification : | Now, the same example would give this IDL specification : | ||
− | < | + | <syntaxhighlight lang="idl"> |
// IDL | // IDL | ||
module my_module | module my_module | ||
Line 121: | Line 121: | ||
}; | }; | ||
}; | }; | ||
− | </ | + | </syntaxhighlight> |
== Further with IDL == | == Further with IDL == | ||
Line 251: | Line 251: | ||
An interface can be derived from a base interface. A derived interface can declare its own attributes and methods. Attributes and methods cannot be redefined in the derived interface. | An interface can be derived from a base interface. A derived interface can declare its own attributes and methods. Attributes and methods cannot be redefined in the derived interface. | ||
An example of interface inheritance : | An example of interface inheritance : | ||
− | < | + | <syntaxhighlight lang="idl"> |
//IDL | //IDL | ||
interface animal { | interface animal { | ||
Line 259: | Line 259: | ||
attribute short leg; | attribute short leg; | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
Multiple inheritance is also possible : | Multiple inheritance is also possible : | ||
− | < | + | <syntaxhighlight lang="idl"> |
// IDL | // IDL | ||
interface dog{ | interface dog{ | ||
Line 267: | Line 267: | ||
interface friend; | interface friend; | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
Inheritance in service is presented in the next chapter. | Inheritance in service is presented in the next chapter. | ||
− | In the OOo object terminology there is a difference between attribute and property. The only difference is how to access them. Properties are accessed with setPropertyValue(PropertyName,Any) whereas attributes are accessed with set/get(AttributeName) methods. We have already | + | In the OOo object terminology there is a difference between attribute and property. The only difference is how to access them. Properties are accessed with setPropertyValue(PropertyName,Any) whereas attributes are accessed with set/get(AttributeName) methods. We have already encountered properties manipulation when examining [[Working_with_Shapes|shapes]]. |
= Gathering UNO information with IDL files = | = Gathering UNO information with IDL files = | ||
There are several ways to find information on UNO. | There are several ways to find information on UNO. | ||
− | One way is to use OooBasic and Bernard Marcelly's Xray tool (see [[Extensions_development_basic# | + | One way is to use OooBasic and Bernard Marcelly's Xray tool (see [[Extensions_development_basic#Xray_tool|XRay tool description]] in this wiki). '''Problem''' : OooBasic doesn't show exact methods and properties. |
− | An other way is to use | + | An other way is to use webservice at : [https://www.openoffice.org/api/docs/common/ref/index-files/index-1.html General OOoWEB Index] |
We have provided examples in previous chapters (particularly [[Programming_OooWriter|programming OOoWriter in C++]]) and then normally reader has skills on the subject. We recall however the points (from Danny Brewer's post in OOoForum). | We have provided examples in previous chapters (particularly [[Programming_OooWriter|programming OOoWriter in C++]]) and then normally reader has skills on the subject. We recall however the points (from Danny Brewer's post in OOoForum). | ||
Line 290: | Line 290: | ||
<idl>com.sun.star.sheet.SpreadsheetDocument</idl> is a service. | <idl>com.sun.star.sheet.SpreadsheetDocument</idl> is a service. | ||
<code>SpreadsheetDocument</code> includes the <idl>com.sun.star.document.OfficeDocument</idl> service and the <idl>com.sun.star.sheet.XSpreadsheetDocument</idl> interface. The correponding IDL file shows us this point : | <code>SpreadsheetDocument</code> includes the <idl>com.sun.star.document.OfficeDocument</idl> service and the <idl>com.sun.star.sheet.XSpreadsheetDocument</idl> interface. The correponding IDL file shows us this point : | ||
− | < | + | <syntaxhighlight lang="idl"> |
//Listing 7 Interface Specification | //Listing 7 Interface Specification | ||
//IDL | //IDL | ||
Line 310: | Line 310: | ||
//------------------------------------------------------------------------- | //------------------------------------------------------------------------- | ||
− | </ | + | </syntaxhighlight> |
Therefore, the combined set of interfaces from both <idl>com.sun.star.sheet.SpreadsheetDocument</idl> and <idl>com.sun.star.document.OfficeDocument</idl> are available at a Spreadsheet document. | Therefore, the combined set of interfaces from both <idl>com.sun.star.sheet.SpreadsheetDocument</idl> and <idl>com.sun.star.document.OfficeDocument</idl> are available at a Spreadsheet document. | ||
So, even though loadComponentFromURL returns some interface, that interface represents an underlying service which is a <idl>com.sun.star.sheet.SpreadsheetDocument</idl>. By looking at the API docs, you can tell what valid interfaces you may query. | So, even though loadComponentFromURL returns some interface, that interface represents an underlying service which is a <idl>com.sun.star.sheet.SpreadsheetDocument</idl>. By looking at the API docs, you can tell what valid interfaces you may query. | ||
Line 324: | Line 324: | ||
Similarly, if I create an object by its service name..... | Similarly, if I create an object by its service name..... | ||
− | < | + | <syntaxhighlight lang=oobas> |
oShape = oDoc.createUnoService( "com.sun.star.drawing.EllipseShape" ) | oShape = oDoc.createUnoService( "com.sun.star.drawing.EllipseShape" ) | ||
− | </ | + | </syntaxhighlight> |
then I know what service it is, because I gave the service name. | then I know what service it is, because I gave the service name. | ||
Line 344: | Line 344: | ||
We want now to show an example : we start from a <idl>com.sun.star.document.OfficeDocument</idl> and then examine <OpenOffice.org1.1_SDK>/idl/com/sun/star/document/OfficeDocument.idl presented below, (with removing all comments) : | We want now to show an example : we start from a <idl>com.sun.star.document.OfficeDocument</idl> and then examine <OpenOffice.org1.1_SDK>/idl/com/sun/star/document/OfficeDocument.idl presented below, (with removing all comments) : | ||
− | < | + | <syntaxhighlight lang="idl"> |
//Listing 8 Interface Specification | //Listing 8 Interface Specification | ||
//IDL | //IDL | ||
Line 361: | Line 361: | ||
[property, optional] boolean ApplyFormDesignMode; | [property, optional] boolean ApplyFormDesignMode; | ||
}; | }; | ||
− | </ | + | </syntaxhighlight> |
If we have a look at <idl>com.sun.star.text.TextDocument</idl> service, we find in the corresponding IDL file at <OpenOffice.org1.1_SDK>/idl/com/sun/star/text/TextDocument.idl : | If we have a look at <idl>com.sun.star.text.TextDocument</idl> service, we find in the corresponding IDL file at <OpenOffice.org1.1_SDK>/idl/com/sun/star/text/TextDocument.idl : | ||
− | < | + | <syntaxhighlight lang="idl"> |
//Listing 8 | //Listing 8 | ||
service TextDocument | service TextDocument | ||
Line 373: | Line 373: | ||
.... | .... | ||
}; | }; | ||
− | </ | + | </syntaxhighlight> |
As can be seen, the service <idl>com.sun.star.document.OfficeDocument</idl> belongs to <idl>com.sun.star.text.TextDocument</idl> service. This dépendance is inheritance as can be shwon in the figure below : | As can be seen, the service <idl>com.sun.star.document.OfficeDocument</idl> belongs to <idl>com.sun.star.text.TextDocument</idl> service. This dépendance is inheritance as can be shwon in the figure below : | ||
Line 379: | Line 379: | ||
[[Image:TextDocumentWithMethods.png|none|thumb|450px| From Developer's Guide.]] | [[Image:TextDocumentWithMethods.png|none|thumb|450px| From Developer's Guide.]] | ||
− | Remember we have already tackled Interfaces in [[IDL_Files_and_Cpp#IDL_specification|this section]]. | + | Remember, we have already tackled Interfaces in [[IDL_Files_and_Cpp#IDL_specification|this section]]. |
What is described so far is simple because we don't walk deep in the IDL-tree. In the following section we will go on to study complication with services. | What is described so far is simple because we don't walk deep in the IDL-tree. In the following section we will go on to study complication with services. | ||
==C++ and services : it's not so easy== | ==C++ and services : it's not so easy== | ||
− | {{ | + | {{Tip| |
If you really want to understand this section, at every variable ask yourself what services are available.}} | If you really want to understand this section, at every variable ask yourself what services are available.}} | ||
It's time to go deeper in our example and provide code with comments. For this purpose, we shall take code already tackled (see [[Programming_OooWriter#The_XTextCursor_Interface|the Corresponding Writer Code]]). | It's time to go deeper in our example and provide code with comments. For this purpose, we shall take code already tackled (see [[Programming_OooWriter#The_XTextCursor_Interface|the Corresponding Writer Code]]). | ||
− | < | + | <syntaxhighlight lang="cpp"> |
//Listing 9 Writer Example | //Listing 9 Writer Example | ||
//C++ | //C++ | ||
Line 403: | Line 403: | ||
Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY); | Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY); | ||
− | </ | + | </syntaxhighlight> |
The code above shows us the xWriterComponent variable is a type <idl>com.sun.star.lang.XComponent</idl>, which gives us <idl>com.sun.star.text.TextDocument</idl> service and then <idl>com.sun.star.document.OfficeDocument</idl> service as already explained. | The code above shows us the xWriterComponent variable is a type <idl>com.sun.star.lang.XComponent</idl>, which gives us <idl>com.sun.star.text.TextDocument</idl> service and then <idl>com.sun.star.document.OfficeDocument</idl> service as already explained. | ||
Line 409: | Line 409: | ||
<idl>com.sun.star.text.XTextDocument</idl> is an Interface of <code>TextDocument</code> service, easy to remember because only the X letter is added. But let's go on. | <idl>com.sun.star.text.XTextDocument</idl> is an Interface of <code>TextDocument</code> service, easy to remember because only the X letter is added. But let's go on. | ||
− | XTextDocument.idl shows us the getText method but we don't know what new services are returned by this method. Only two ways to learn that : Internet [ | + | XTextDocument.idl shows us the getText method, but we don't know what new services are returned by this method. Only two ways to learn that : Internet [https://www.openoffice.org/api/docs/common/ref/com/sun/star/text/XText.html XText interface] gives the answer : the service is <idl>com.sun.star.text.Text</idl>. The other way is to use Reflection as described later in [[IDL_Files_and_Cpp#Core_reflection_service__and_its_Interfaces|this section]]. |
− | < | + | <syntaxhighlight lang="cpp"> |
//Listing 10 Writer Example (continuation) | //Listing 10 Writer Example (continuation) | ||
//C++ | //C++ | ||
Reference< XText > xText = xTextDocument->getText(); | Reference< XText > xText = xTextDocument->getText(); | ||
− | </ | + | </syntaxhighlight> |
We try to get a XTextCursor Interface | We try to get a XTextCursor Interface | ||
− | < | + | <syntaxhighlight lang="cpp"> |
//Listing 11 Writer Example (continuation) | //Listing 11 Writer Example (continuation) | ||
//C++ | //C++ | ||
Reference< XTextCursor> xTextCursor = xText->createTextCursor(); | Reference< XTextCursor> xTextCursor = xText->createTextCursor(); | ||
− | </ | + | </syntaxhighlight> |
But how to explain this code ? Looking for in XText.idl files only shows two methods : | But how to explain this code ? Looking for in XText.idl files only shows two methods : | ||
− | < | + | <syntaxhighlight lang="idl"> |
//Listing 12 XText Interface IDL file | //Listing 12 XText Interface IDL file | ||
// IDL | // IDL | ||
Line 437: | Line 437: | ||
}; | }; | ||
}; }; }; }; | }; }; }; }; | ||
− | </ | + | </syntaxhighlight> |
But if you have a closer look at the IDL file, you will see the inheritance from XSimpleText. Is the createTextCursor method here ? Yes, as you can see. | But if you have a closer look at the IDL file, you will see the inheritance from XSimpleText. Is the createTextCursor method here ? Yes, as you can see. | ||
− | < | + | <syntaxhighlight lang="idl"> |
//Listing 13 XSimpleText Interface IDL file | //Listing 13 XSimpleText Interface IDL file | ||
// IDL | // IDL | ||
Line 457: | Line 457: | ||
}; | }; | ||
}; }; }; }; | }; }; }; }; | ||
− | </ | + | </syntaxhighlight> |
What are the services available here ? I have found them with a reflection tool : | What are the services available here ? I have found them with a reflection tool : | ||
<pre> | <pre> | ||
Line 470: | Line 470: | ||
com.sun.star.text.TextCursor | com.sun.star.text.TextCursor | ||
</pre> | </pre> | ||
− | You can probably find all of them with internet but I think it will be a long task : a good reason for explaining reflection services [[IDL_Files_and_Cpp#Core_reflection_service__and_its_Interfaces|later in this chapter]]. | + | You can probably find all of them with internet, but I think it will be a long task : a good reason for explaining reflection services [[IDL_Files_and_Cpp#Core_reflection_service__and_its_Interfaces|later in this chapter]]. |
− | {{ | + | {{Note|It's using a method returning an Interface Type, which make things difficult. To find then services is very difficult and personally, I use an introspection tool to find them (see [[UNO_registery_and_Bootstrapping#Interfaces_and_Services_with_defaultBootstrap_InitialComponentContext.28.29|an example here]]). Good news, two methods gives us explicitly the returned type : <code>createInstance</code> and <code>createInstanceWithContext</code> where the service is given as a parameter.}} |
− | Yes you have to walk through such ways to find what you can do when programming. Fortunately there is a shorter way : the SDK examples. Most of them are in Java but I have found many ideas with them. | + | Yes, you have to walk through such ways to find what you can do when programming. Fortunately, there is a shorter way : the SDK examples. Most of them are in Java, but I have found many ideas with them. |
= IDL and C++ = | = IDL and C++ = | ||
Line 491: | Line 491: | ||
===Obtaining an Interface with UNO_QUERY macro=== | ===Obtaining an Interface with UNO_QUERY macro=== | ||
As an example, we suppose we have obtained a <idl>com.sun.star.text.XTextDocument</idl> interface. This is done in general by something like: | As an example, we suppose we have obtained a <idl>com.sun.star.text.XTextDocument</idl> interface. This is done in general by something like: | ||
− | < | + | <syntaxhighlight lang="cpp"> |
//Listing 2 C++ code to get a service | //Listing 2 C++ code to get a service | ||
//C++ | //C++ | ||
Reference<com::sun::star::text::XTextDocument> OfDoc = something_to_get_this_interface(); | Reference<com::sun::star::text::XTextDocument> OfDoc = something_to_get_this_interface(); | ||
− | </ | + | </syntaxhighlight> |
or | or | ||
− | < | + | <syntaxhighlight lang="cpp"> |
Listing 3 using namespace to simplify the code | Listing 3 using namespace to simplify the code | ||
//C++ | //C++ | ||
Line 503: | Line 503: | ||
.... | .... | ||
Reference<XTextDocument> OfDoc = something_to_get_this_interface(); | Reference<XTextDocument> OfDoc = something_to_get_this_interface(); | ||
− | </ | + | </syntaxhighlight> |
and we want to query the <idl>com.sun.star.frame.XStorable</idl> interface to save our document. The figure below shows us all the interfaces we can query starting from <idl>com.sun.star.text.XTextDocument</idl> interface. | and we want to query the <idl>com.sun.star.frame.XStorable</idl> interface to save our document. The figure below shows us all the interfaces we can query starting from <idl>com.sun.star.text.XTextDocument</idl> interface. | ||
Line 515: | Line 515: | ||
'''Step 1''' Add your code's line as UNO's query | '''Step 1''' Add your code's line as UNO's query | ||
− | < | + | <syntaxhighlight lang="cpp"> |
//Listing 4 The UNO query in C++ code | //Listing 4 The UNO query in C++ code | ||
// C++ | // C++ | ||
// query from com::sun::star::frame::XStorable interface | // query from com::sun::star::frame::XStorable interface | ||
Reference< XStorable > oToStore (OfDoc, UNO_QUERY); | Reference< XStorable > oToStore (OfDoc, UNO_QUERY); | ||
− | </ | + | </syntaxhighlight> |
If the variable is already declared, please use : | If the variable is already declared, please use : | ||
− | < | + | <syntaxhighlight lang="cpp"> |
//Listing 4b The UNO query in C++ code | //Listing 4b The UNO query in C++ code | ||
// C++ | // C++ | ||
// query from com::sun::star::frame::XStorable interface | // query from com::sun::star::frame::XStorable interface | ||
oToStore = Reference< XStorable > (OfDoc, UNO_QUERY); | oToStore = Reference< XStorable > (OfDoc, UNO_QUERY); | ||
− | </ | + | </syntaxhighlight> |
'''Step 2''' Add the hpp file in an include statement. Add the corresponding namespace in an using namespace statement. Including is done with : | '''Step 2''' Add the hpp file in an include statement. Add the corresponding namespace in an using namespace statement. Including is done with : | ||
− | < | + | <syntaxhighlight lang="cpp"> |
//Listing 5 The corresponding include statement | //Listing 5 The corresponding include statement | ||
//C++ | //C++ | ||
#include <com/sun/star/frame/XStorable.hpp> | #include <com/sun/star/frame/XStorable.hpp> | ||
− | </ | + | </syntaxhighlight> |
and the corresponding namespace statement is : | and the corresponding namespace statement is : | ||
− | < | + | <syntaxhighlight lang="cpp"> |
//Listing 6 The corresponding namespace statement | //Listing 6 The corresponding namespace statement | ||
//C++ | //C++ | ||
using namespace com::sun::star::frame; | using namespace com::sun::star::frame; | ||
− | </ | + | </syntaxhighlight> |
'''Step 3''' Add the corresponding type in the makefile as shown below (XStorable line) : | '''Step 3''' Add the corresponding type in the makefile as shown below (XStorable line) : | ||
Line 555: | Line 555: | ||
com.sun.star.container.XHierarchicalNameAccess | com.sun.star.container.XHierarchicalNameAccess | ||
</pre> | </pre> | ||
− | {{ | + | {{Note| |
Learn to realize these three steps : you can not program in C++ without encountering an interface query. This problem of asking an interface is already tackled in [[UNO_automation_with_a_binary_%28executable%29|Office UNO automation]] and [[Calc/API/Programming|Calc API Programming]], in fact in all chapters tackled so far.}} | Learn to realize these three steps : you can not program in C++ without encountering an interface query. This problem of asking an interface is already tackled in [[UNO_automation_with_a_binary_%28executable%29|Office UNO automation]] and [[Calc/API/Programming|Calc API Programming]], in fact in all chapters tackled so far.}} | ||
Line 561: | Line 561: | ||
To help us understand the task above, let's us show a concrete example. All can be shown as a way through an IDL-tree : | To help us understand the task above, let's us show a concrete example. All can be shown as a way through an IDL-tree : | ||
− | [[Image:SimpleUNOQUERY2.png|center|thumb|600px|Querying an Interface starting from | + | [[Image:SimpleUNOQUERY2.png|center|thumb|600px|Querying an Interface starting from another]] |
− | And here is the | + | And here is the corresponding code. |
− | < | + | <syntaxhighlight lang="cpp"> |
//Listing 19 Simple UNO_QUERY call | //Listing 19 Simple UNO_QUERY call | ||
// C++ | // C++ | ||
Line 580: | Line 580: | ||
Reference < XStorable > xStorable (xTextDocument,UNO_QUERY); | Reference < XStorable > xStorable (xTextDocument,UNO_QUERY); | ||
xStorable->store(); | xStorable->store(); | ||
− | </ | + | </syntaxhighlight> |
which use <idl>com.sun.star.text.XTextDocument</idl> and <idl>com.sun.star.frame.XStorable</idl> interfaces. | which use <idl>com.sun.star.text.XTextDocument</idl> and <idl>com.sun.star.frame.XStorable</idl> interfaces. | ||
− | You have to learn to get interface in | + | You have to learn to get interface in another way, with first asking a service. |
===Getting an Interface through XMultiServiceFactory=== | ===Getting an Interface through XMultiServiceFactory=== | ||
Line 607: | Line 607: | ||
'''Second case :''' no interface's method can help you. You have to query a service before getting the interface. This can be done with two or three instructions style. I have already used both styles. Have a look into this listing : | '''Second case :''' no interface's method can help you. You have to query a service before getting the interface. This can be done with two or three instructions style. I have already used both styles. Have a look into this listing : | ||
− | < | + | <syntaxhighlight lang="cpp"> |
//Listing 20 Getting an Interface with XMultiServiceFacory | //Listing 20 Getting an Interface with XMultiServiceFacory | ||
// C++ | // C++ | ||
Line 616: | Line 616: | ||
Reference <XTextTable> xTable (oDocMSF->createInstance( | Reference <XTextTable> xTable (oDocMSF->createInstance( | ||
OUString::createFromAscii("com.sun.star.text.TextTable")),UNO_QUERY); | OUString::createFromAscii("com.sun.star.text.TextTable")),UNO_QUERY); | ||
− | </ | + | </syntaxhighlight> |
which uses two instruction style with <idl>com.sun.star.text.XTextDocument</idl> and <idl>com.sun.star.text.XTextTable</idl> interfaces. | which uses two instruction style with <idl>com.sun.star.text.XTextDocument</idl> and <idl>com.sun.star.text.XTextTable</idl> interfaces. | ||
Line 622: | Line 622: | ||
With three instructions style, the same code is shown in the listing above : | With three instructions style, the same code is shown in the listing above : | ||
− | < | + | <syntaxhighlight lang="cpp"> |
//Listing 21 Inserting a Table in a OOoWriter Document | //Listing 21 Inserting a Table in a OOoWriter Document | ||
// C++ | // C++ | ||
Line 631: | Line 631: | ||
// Don't forget to add #include <com/sun/star/text/XTextTable.hpp> | // Don't forget to add #include <com/sun/star/text/XTextTable.hpp> | ||
Reference< XTextTable > xTable(textTable, UNO_QUERY); | Reference< XTextTable > xTable(textTable, UNO_QUERY); | ||
− | </ | + | </syntaxhighlight> |
Note that both method require to include (and then construct) the corresponding hpp file (here XtextTable.hpp, as usual with [[IDL_Files_and_Cpp#Three_steps_to_have_an_interface|the three steps method]]), but not for the service because you get it with a method (named « createInstance » in this case) and cast it in a variable <idl>com.sun.star.uno.XInterface</idl> (see rule 3). We give a schematic to summarize what we talked about. | Note that both method require to include (and then construct) the corresponding hpp file (here XtextTable.hpp, as usual with [[IDL_Files_and_Cpp#Three_steps_to_have_an_interface|the three steps method]]), but not for the service because you get it with a method (named « createInstance » in this case) and cast it in a variable <idl>com.sun.star.uno.XInterface</idl> (see rule 3). We give a schematic to summarize what we talked about. | ||
Line 639: | Line 639: | ||
'''Last question :''' is it possible to start from any XMultiServiceFactory interface ? The answer to this question is no. Have a look to the code below where I take rOfficeServiceManager instead of oDocMSF because it's a XmultiServiceFactory Interface too. | '''Last question :''' is it possible to start from any XMultiServiceFactory interface ? The answer to this question is no. Have a look to the code below where I take rOfficeServiceManager instead of oDocMSF because it's a XmultiServiceFactory Interface too. | ||
− | < | + | <syntaxhighlight lang="cpp"> |
//Listing 22 Wrong code | //Listing 22 Wrong code | ||
// C++ | // C++ | ||
Line 651: | Line 651: | ||
return 1; | return 1; | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
This code compiles but gives a runtime error. This only means you cannot use every <idl>com.sun.star.lang.XMultiServiceFactory</idl> interface to get every Interface. | This code compiles but gives a runtime error. This only means you cannot use every <idl>com.sun.star.lang.XMultiServiceFactory</idl> interface to get every Interface. | ||
− | {{ | + | {{Warn| |
− | If you are working with a document ask the corresponding XMultiServiceFactory interface. At this point only experience can help you.}} | + | If you are working with a document, ask the corresponding XMultiServiceFactory interface. At this point, only experience can help you.}} |
− | ==== | + | ====Another example already tackled==== |
Note before going further, that a code used many times so far, can find an explanation. Even if in this case, the XMultiServiceFactory interface is not obtained in a standard way (for a document) because we still not have a document at this point in the code, the principles are the same : | Note before going further, that a code used many times so far, can find an explanation. Even if in this case, the XMultiServiceFactory interface is not obtained in a standard way (for a document) because we still not have a document at this point in the code, the principles are the same : | ||
− | < | + | <syntaxhighlight lang="cpp"> |
//Listing 23 Classic code | //Listing 23 Classic code | ||
// C++ | // C++ | ||
Line 675: | Line 675: | ||
//query for the XComponentLoader interface | //query for the XComponentLoader interface | ||
Reference< XComponentLoader > rComponentLoader (Desktop, UNO_QUERY); | Reference< XComponentLoader > rComponentLoader (Desktop, UNO_QUERY); | ||
− | </ | + | </syntaxhighlight> |
− | Easy to | + | Easy to retrieve the three instructions style to get the <idl>com.sun.star.frame.XComponentLoader</idl> interface with using <idl>com.sun.star.frame.Desktop</idl> service, isn't it ? |
Here is the corresponding IDL-tree. | Here is the corresponding IDL-tree. | ||
Line 683: | Line 683: | ||
[[Image:ch4fig2Componentloader.png|center|thumb|600px|Obtaining XComponentLoader Interface]] | [[Image:ch4fig2Componentloader.png|center|thumb|600px|Obtaining XComponentLoader Interface]] | ||
− | {{ | + | {{Note|When sketching IDL-tree in this document, I will always show the <idl>com.sun.star.uno.XInterface</idl> interface when getting a service. There is no other reason to see such an interface in an IDL-tree.}} |
− | + | Another more technical problem is the mapping : you have an IDL file, how is it compiled in C++ ? The next section tackle the subject : you can skip it in a first reading and go on into this [[IDL_Files_and_Cpp#Core_reflection_service__and_its_Interfaces|section]]. | |
== Mapping for Modules and Interfaces == | == Mapping for Modules and Interfaces == | ||
Line 696: | Line 696: | ||
Other examples are provided now. For instance: | Other examples are provided now. For instance: | ||
− | < | + | <syntaxhighlight lang="idl"> |
// IDL | // IDL | ||
module M | module M | ||
Line 702: | Line 702: | ||
}; | }; | ||
}; | }; | ||
− | </ | + | </syntaxhighlight> |
is mapped into: | is mapped into: | ||
− | < | + | <syntaxhighlight lang="cpp"> |
// C++ | // C++ | ||
namespace M | namespace M | ||
Line 710: | Line 710: | ||
{ Long L; }; | { Long L; }; | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
and E can be referred outside of M as M::E. Alternatively, a C++ using statement for namespace M can be used so that E can be referred to simply as E: | and E can be referred outside of M as M::E. Alternatively, a C++ using statement for namespace M can be used so that E can be referred to simply as E: | ||
− | < | + | <syntaxhighlight lang="cpp"> |
// C++ | // C++ | ||
using namespace M; | using namespace M; | ||
E e; | E e; | ||
e.L = 3; | e.L = 3; | ||
− | </ | + | </syntaxhighlight> |
= Core reflection service and its Interfaces = | = Core reflection service and its Interfaces = | ||
Line 726: | Line 726: | ||
== Reflection in OOoBasic== | == Reflection in OOoBasic== | ||
− | {{ | + | {{Warn|The aim of this section is not to replace the beautiful Bernard Marcelly's tool : XRay. See a short description [[Extensions_development_basic#Xray_tool|in this wiki]].}} |
OooBasic allow many things and in particular to explore core by reflection. [http://www.oooforum.org/forum/viewtopic.php?t=8737 Danny Brewer's code] shows us how to work around ? We have a look at his code : | OooBasic allow many things and in particular to explore core by reflection. [http://www.oooforum.org/forum/viewtopic.php?t=8737 Danny Brewer's code] shows us how to work around ? We have a look at his code : | ||
− | < | + | <syntaxhighlight lang="oobas"> |
REM ***** BASIC ***** | REM ***** BASIC ***** | ||
Sub Main | Sub Main | ||
Line 740: | Line 740: | ||
Next | Next | ||
End Sub | End Sub | ||
− | </ | + | </syntaxhighlight> |
We then create an idl file : | We then create an idl file : | ||
− | < | + | <syntaxhighlight lang="idl"> |
// IDL | // IDL | ||
#include <com/sun/star/uno/XInterface.idl> | #include <com/sun/star/uno/XInterface.idl> | ||
Line 763: | Line 763: | ||
}; | }; | ||
}; | }; | ||
− | </ | + | </syntaxhighlight> |
− | With this IDL file, we create a rdb file and register this rdb file. Now | + | With this IDL file, we create a rdb file and register this rdb file. Now {{AOo}} works as if we have an add-on even if we have not written its code. We cannot launch this add-on (without its code !) but we can see it. |
We then modify the above Danny's program : | We then modify the above Danny's program : | ||
− | < | + | <syntaxhighlight lang="oobas"> |
REM Listing 11 | REM Listing 11 | ||
REM ***** BASIC ***** | REM ***** BASIC ***** | ||
Line 775: | Line 775: | ||
oInfo = oReflection.forName( "my_module.XSomething" ) | oInfo = oReflection.forName( "my_module.XSomething" ) | ||
aMethods = oInfo.getMethods() | aMethods = oInfo.getMethods() | ||
− | ' | + | 'XRay oInfo |
print UBound( aMethods )+1 & " methods : ****" | print UBound( aMethods )+1 & " methods : ****" | ||
For i = 0 To UBound( aMethods ) | For i = 0 To UBound( aMethods ) | ||
Line 796: | Line 796: | ||
Next | Next | ||
End Sub | End Sub | ||
− | </ | + | </syntaxhighlight> |
launching this modified program produces : | launching this modified program produces : | ||
<pre> | <pre> | ||
Line 810: | Line 810: | ||
It is possible to retrieve more information on the methods for instance. If you want all the information given in the IDL file you can use OOoBasic code like that : | It is possible to retrieve more information on the methods for instance. If you want all the information given in the IDL file you can use OOoBasic code like that : | ||
− | < | + | <syntaxhighlight lang="oobas"> |
For i = LBound( oMethods ) To UBound( oMethods ) | For i = LBound( oMethods ) To UBound( oMethods ) | ||
oMethod = oMethods( i ) | oMethod = oMethods( i ) | ||
Line 833: | Line 833: | ||
' something to do with sString here | ' something to do with sString here | ||
Next | Next | ||
− | </ | + | </syntaxhighlight> |
To go further in C++, we examine XdlRefection Interface in next section. | To go further in C++, we examine XdlRefection Interface in next section. | ||
Line 846: | Line 846: | ||
= Using Java Inspector = | = Using Java Inspector = | ||
− | For an introduction of using Java with | + | For an introduction of using Java with {{AOo}}, see [[JavaEclipseTuto|Java and Eclipse tutorial]]. This point is not tackled here : we are only interested by using a Java component with C++. |
It is possible in principle, to use the Java inspector tools from every programming languages because it's a component. The way to do that is very simple : | It is possible in principle, to use the Java inspector tools from every programming languages because it's a component. The way to do that is very simple : | ||
Line 853: | Line 853: | ||
2°) Create a OOoBasic example, for instance (OOo1.1.X) : | 2°) Create a OOoBasic example, for instance (OOo1.1.X) : | ||
− | < | + | <syntaxhighlight lang="oobas"> |
'Listing 17 Simple OOoBasic example to call the Java Inspector | 'Listing 17 Simple OOoBasic example to call the Java Inspector | ||
Line 863: | Line 863: | ||
o.inspect(oReflection) | o.inspect(oReflection) | ||
End Sub | End Sub | ||
− | </ | + | </syntaxhighlight> |
− | {{ | + | |
+ | {{Note| | ||
For newer version of Java Inspector see [[Object_Inspector#Calling_from_a_Basic_Macro|Calling from a Basic Macro]].}} | For newer version of Java Inspector see [[Object_Inspector#Calling_from_a_Basic_Macro|Calling from a Basic Macro]].}} | ||
− | If java is not properly installed when running this program a dialog box will print out. Follow the instructions to install it (you have to know where your virtual machine (JRE) is installed. | + | If java is not properly installed when running this program, a dialog box will print out. Follow the instructions to install it (you have to know where your virtual machine (JRE) is installed. |
− | + | In the figure below, we see the result of this program. | |
[[Image:Inspector3.png|Old Java Object Inspector]] | [[Image:Inspector3.png|Old Java Object Inspector]] | ||
Line 880: | Line 881: | ||
# add the #include <org/OpenOffice/XInstanceInspector.hpp> and using namespace org::OpenOffice; | # add the #include <org/OpenOffice/XInstanceInspector.hpp> and using namespace org::OpenOffice; | ||
# add this code | # add this code | ||
− | < | + | <syntaxhighlight lang="cpp"> |
// C++ | // C++ | ||
Any toInspect; | Any toInspect; | ||
Line 887: | Line 888: | ||
OUString::createFromAscii( "org.OpenOffice.InstanceInspector" )),UNO_QUERY); | OUString::createFromAscii( "org.OpenOffice.InstanceInspector" )),UNO_QUERY); | ||
xinspect->inspect(toInspect); | xinspect->inspect(toInspect); | ||
− | </ | + | </syntaxhighlight> |
And it works like in OOoBasic. | And it works like in OOoBasic. | ||
Line 983: | Line 984: | ||
</pre> | </pre> | ||
− | {{ | + | {{Note|'''Note 1''' : [[Object Inspector|The New Object Inspector]] appears in SDK after 2.0 version. It is more complex and able to generate Java, C++ or OOoBasic code. I have not checked the above code with the [[Object Inspector|the new object inspector]] but don't see why it could not work properly.}} |
− | {{ | + | {{Note|'''Note 2''' : [[Programming_OooWriter#Going_further_with_Inspector|A little example]] with [[Object Inspector|the new object inspector]] can be found in this document.}} |
− | There is a simpler way to use Java Inspector. It's a component as all others and probably doesn't need starting from the IDL file, but constructing hpp files directly | + | There is a simpler way to use Java Inspector. It's a component as all others and probably doesn't need starting from the IDL file, but constructing hpp files directly from a RDB file, because the corresponding service is already registered. Then you only have to add "org.OpenOffice.XInstanceInspector" in the TYPE section of the makefile. See [[Writing_Professional_Components#Java_Inspector|Java Inspector in component]] : you can use Java Inspector in the same way with binary executable. |
= Translating OOoBasic programs into C++ = | = Translating OOoBasic programs into C++ = | ||
Line 993: | Line 994: | ||
When I tackled Writer [[Programming_OooWriter|in OOoWriter chapter]], I let the reader resolve some problems (particularly cursors problems). We chose these problems here as an example. We give first the OOoBasic program. | When I tackled Writer [[Programming_OooWriter|in OOoWriter chapter]], I let the reader resolve some problems (particularly cursors problems). We chose these problems here as an example. We give first the OOoBasic program. | ||
− | < | + | <syntaxhighlight lang="oobas"> |
'Listing 36 Simple OOoBasic program to translate | 'Listing 36 Simple OOoBasic program to translate | ||
REM **** OOoBasic | REM **** OOoBasic | ||
Line 1,003: | Line 1,004: | ||
MyCurseur.goRight(1, false) ' move right one character | MyCurseur.goRight(1, false) ' move right one character | ||
MyCurseur.goLeft(2, true) ' select the two previous characters | MyCurseur.goLeft(2, true) ' select the two previous characters | ||
− | </ | + | </syntaxhighlight> |
I summarize OOoBasic instructions to move the cursor in the above table : | I summarize OOoBasic instructions to move the cursor in the above table : | ||
Line 1,047: | Line 1,048: | ||
|} | |} | ||
− | But if you want to translate the use of all these OOoBasic functions in C++, you have to query Interfaces starting from a XtextCursor interface(see below Listing 41). This make the translation difficult. For instance three | + | But if you want to translate the use of all these OOoBasic functions in C++, you have to query Interfaces starting from a XtextCursor interface(see below Listing 41). This make the translation difficult. For instance three different cursor interfaces are involved when using the methods of OOoBasic starting program. It's time to show all the corresponding IDL files. |
First of all the XWordCursor interface is shown : | First of all the XWordCursor interface is shown : | ||
− | < | + | <syntaxhighlight lang="idl"> |
//Listing 37 XWordCursor interface (IDL file) | //Listing 37 XWordCursor interface (IDL file) | ||
// IDL | // IDL | ||
Line 1,063: | Line 1,064: | ||
}; | }; | ||
}; }; }; }; | }; }; }; }; | ||
− | </ | + | </syntaxhighlight> |
Now the XParagraphCursor interface is shown | Now the XParagraphCursor interface is shown | ||
− | < | + | <syntaxhighlight lang="idl"> |
//Listing 38 XParagraphCursor interface (IDL file) | //Listing 38 XParagraphCursor interface (IDL file) | ||
// IDL | // IDL | ||
Line 1,085: | Line 1,086: | ||
}; | }; | ||
}; }; }; }; | }; }; }; }; | ||
− | </ | + | </syntaxhighlight> |
and to finish XSentenceCursor interface : | and to finish XSentenceCursor interface : | ||
− | < | + | <syntaxhighlight lang="idl"> |
// Listing 39 XSentenceCursor interface (IDL file) | // Listing 39 XSentenceCursor interface (IDL file) | ||
// IDL | // IDL | ||
Line 1,105: | Line 1,106: | ||
}; }; }; }; | }; }; }; }; | ||
− | </ | + | </syntaxhighlight> |
If you want to know what interface you can ask you are obliged to retrieve the service. For our example it's TextCursor service. Here is the corresponding IDL file where you see all the interfaces you can query. | If you want to know what interface you can ask you are obliged to retrieve the service. For our example it's TextCursor service. Here is the corresponding IDL file where you see all the interfaces you can query. | ||
− | < | + | <syntaxhighlight lang="idl"> |
//Listing 40 TextCursor service (IDL file) | //Listing 40 TextCursor service (IDL file) | ||
// IDL | // IDL | ||
Line 1,127: | Line 1,128: | ||
}; | }; | ||
}; }; }; }; | }; }; }; }; | ||
− | </ | + | </syntaxhighlight> |
If you start for instance from Listing 11 you will need a UNO_QUERY to get a XWordCursor interface. | If you start for instance from Listing 11 you will need a UNO_QUERY to get a XWordCursor interface. | ||
− | < | + | <syntaxhighlight lang="cpp"> |
//Listing 41 Using XwordCursor Interface | //Listing 41 Using XwordCursor Interface | ||
// C++ | // C++ | ||
Line 1,139: | Line 1,140: | ||
xWordCursor->gotoNextWord(false); | xWordCursor->gotoNextWord(false); | ||
xWordCursor->gotoNextWord(true); | xWordCursor->gotoNextWord(true); | ||
− | </ | + | </syntaxhighlight> |
The translation could be achieve automatically, but such a compiler has to have knowledge on IDL files. | The translation could be achieve automatically, but such a compiler has to have knowledge on IDL files. | ||
− | By the way here we have again all these eight services | + | By the way here we have again all these eight services available : |
<pre> | <pre> | ||
******** Services : 8 | ******** Services : 8 | ||
Line 1,156: | Line 1,157: | ||
==Further reading== | ==Further reading== | ||
− | I will use OOoBasic and translate it in C++ when writing [[Component_and_Dialog|Managing a Dialog in a Component]] and [[Going_further_with_Dialog_and_Component|Going further with Dialog and Components]]. Even with my own C++ experience it was impossible for me to program directly in C++ in these chapters. | + | I will use OOoBasic and translate it in C++ when writing [[Component_and_Dialog|Managing a Dialog in a Component]] and [[Going_further_with_Dialog_and_Component|Going further with Dialog and Components]]. Even with my own C++ experience, it was impossible for me to program directly in C++ in these chapters. |
=Home Page= | =Home Page= |
Latest revision as of 12:15, 11 September 2022
For an introduction, you can read the component tutorial.
Contents
- 1 Services and Interfaces
- 2 IDL specification
- 3 Gathering UNO information with IDL files
- 4 IDL and C++
- 5 Core reflection service and its Interfaces
- 6 Using Java Inspector
- 7 Translating OOoBasic programs into C++
- 8 Home Page
- 9 See Also
Services and Interfaces
Introduction
See Introduction the OpenOffice.org API or Introducing the OpenOffice.org API. In OpenOffice API, a "service" is an abstract concept providing certain interfaces and properties/attributes. As Developer's Guide states : “Properties are data in an object that are provided by name over a generic interface for property access, that contains getPropertyValue() and setPropertyValue() access methods.”. It would be better to distinguish between attribute and property. A service has a collection of properties and an interface is a collection of methods that provide a means to change properties.
Danny Brewer's rules
Services are similar to objects in java.
1. A service can inherit from zero or one other service. (which each service can recursively follow these rules.)
2. A service can include zero or more services. (which each service can recursively follow these rules.)
3. A service can export (implement) interfaces.
4. A service can have properties.
5. An interface can inherit from zero or one other interface. (which each interface can recursively follow these rules.)
6. An interface can include from zero or more interfaces. (which each interface can recursively apply these rules.)
7. An interface can implement methods.
8. An interface is always named with an X.
From these rules you can deduce that methods are ALWAYS found in interfaces, and properties are ALWAYS found in services.
See also Introducing the OpenOffice.org_API and OOoBasic Introspection and Developer's Guide.
UNO programming and IDL-tree
I have already tackled the IDL-tree notion in a previous chapter (see Going further with Java Inspector This section seems to be place to go further in the explanations.
We have enough experience in UNO programming until now and then we can deduce few rules for C++ language.
Rule 1 : C++ language allows us to go through interfaces, I mean starting from an interface and to get an other interface. We will focus us on the problem of getting such interfaces later.
Rule 2 : if we are constrained to use a service, we have to use a com.sun.star.uno.XInterface variable as container. This type is an interface because begining with a letter X and this operation is then called a cast. We tackle this problem further with C++.
Both rules allow us to deduce that a C++ programmer have to find a path between interfaces. Starting from XThing interface, for instance, you can use every methods of XThing, or look for other interfaces with other methods. Every possibilities starting from XThing interface could be sketched with a tree : it's my IDL-tree. As programmer I have to find a path in this big tree and it's not always very easy because of the size of the tree. I have already presented this kind of IDL-tree (or more exactly paths in this IDL-tree) in this document with different representations :
- Path of IDL-tree with a textual Descrition.
- Path of IDL-tree with an Introspection Tool or with the cpp Inspector.
- Diagram and Path of IDL-tree for the boostrapping problem.
Before tackling how to realize path through IDL-tree in C++, we come back to IDL files as specifier for modules, interfaces and services.
IDL specification
Interfaces are specified using an Interface definition language (IDL). UNO uses UNO-IDL as the interface definition language. The Interface Definition Language (IDL) is a descriptive language (not a programming language) to describe the interfaces being implemented by the objects. Within IDL, you define the name of the interface, the names of each of the attributes and methods, and so forth. Once you've created the IDL file, you can use an IDL compiler to generate the header files in the C++ programming language. The way to specify simple modules with IDL is so straightforward that we choose to give only examples at first.
Specifying an interface
We choose as an example, the interface XdrivingDirection. The Figure below shows you the corresponding interface :
And now the corresponding IDL file :
// IDL interface XdrivingDirection { void turnLeft(); void turnRight(); };
Specifying a service
Example above is still used, here is the corresponding IDL specification :
// IDL interface XdrivingDirection { void turnLeft(); void turnRight(); }; interface XaccelerationControl { void speedUp(); void slowDown(); }; service car { // exported interfaces: interface XdrivingDirection; interface XaccelerationControl; [attribute] float speed; [attribute] float angle; };
We see a float type and we would use other IDL types later.
Specifying a module
Now, the same example would give this IDL specification :
// IDL module my_module { interface Xsomething { void methodone(); }; service my_service1 { // exported interfaces: interface Xsomething; }; interface XsomethingElse { void methodTwo(); void methodThree(); }; service my_service2 { // exported interfaces: interface XsomethingElse; }; };
Further with IDL
The IDL's types are :
char |
16-bit unicode character type |
boolean |
boolean type; true and false |
byte |
8-bit ordinal integer type |
short |
signed 16-bit ordinal integer type |
unsigned short |
unsigned 16-bit ordinal integer type |
long |
signed 32-bit ordinal integer type |
unsigned long |
unsigned 32-bit integer type |
hyper |
signed 64-bit ordinal integer type |
unsigned hyper |
unsigned 64-bit ordinal integer type |
float |
processor dependent float |
double |
processor dependent double |
string |
string of 16-bit unicode characters |
any |
universal type, takes every fundamental or compound UNO type, similar to Variant in other environments or Object in Java |
void |
Indicates that a method does not provide a return value |
Methods can have arguments. Each argument in the argument list must begin with one of the direction flags [ in ] , [ out ] or [ inout ] before a known type and identifier for the argument is given. We give an example that we will often encounter in this document : the counter example.
An interface can be derived from a base interface. A derived interface can declare its own attributes and methods. Attributes and methods cannot be redefined in the derived interface. An example of interface inheritance :
//IDL interface animal { attribute long age; }; interface dog : animal { attribute short leg; }
Multiple inheritance is also possible :
// IDL interface dog{ interface animal; interface friend; }
Inheritance in service is presented in the next chapter.
In the OOo object terminology there is a difference between attribute and property. The only difference is how to access them. Properties are accessed with setPropertyValue(PropertyName,Any) whereas attributes are accessed with set/get(AttributeName) methods. We have already encountered properties manipulation when examining shapes.
Gathering UNO information with IDL files
There are several ways to find information on UNO.
One way is to use OooBasic and Bernard Marcelly's Xray tool (see XRay tool description in this wiki). Problem : OooBasic doesn't show exact methods and properties.
An other way is to use webservice at : General OOoWEB Index
We have provided examples in previous chapters (particularly programming OOoWriter in C++) and then normally reader has skills on the subject. We recall however the points (from Danny Brewer's post in OOoForum).
Danny Brewer 's Point of View
Nonetheless, it is important to understand the concept of a "service" in the API docs. A service is just a way to group....
- more services
- interfaces
The (1) more services part, of course, means that there are even more interfaces available at the original service.
Let me give a different example.
com.sun.star.sheet.SpreadsheetDocument is a service.
SpreadsheetDocument
includes the com.sun.star.document.OfficeDocument service and the com.sun.star.sheet.XSpreadsheetDocument interface. The correponding IDL file shows us this point :
//Listing 7 Interface Specification //IDL service SpreadsheetDocument { //------------------------------------------------------------------------- /** common service for all types of documents. */ service com::sun::star::document::OfficeDocument; .......... //------------------------------------------------------------------------- /** provides access to the collection of spreadsheets. */ interface com::sun::star::sheet::XSpreadsheetDocument; //-------------------------------------------------------------------------
Therefore, the combined set of interfaces from both com.sun.star.sheet.SpreadsheetDocument and com.sun.star.document.OfficeDocument are available at a Spreadsheet document. So, even though loadComponentFromURL returns some interface, that interface represents an underlying service which is a com.sun.star.sheet.SpreadsheetDocument. By looking at the API docs, you can tell what valid interfaces you may query.
SpreadsheetDocument
service has com.sun.star.sheet.XSpreadsheetDocument interface.
OfficeDocument
has interfaces com.sun.star.view.XPrintable and com.sun.star.frame.XStorable.
Since SpreadsheetDocument
includes OfficeDocument
, it is therefore valid to queryInterface for either com.sun.star.view.XPrintable or com.sun.star.frame.XStorable from a SpreadsheetDocument
.
Now in the above discussion, substitute TextDocument for SpreadsheetDocument. How to tell what is the underlying service?
There is no magic formula for that. Generally it is obvious. If you load a Spreadsheet, then you have the com.sun.star.sheet.SpreadsheetDocument service.
Similarly, if I create an object by its service name.....
oShape = oDoc.createUnoService( "com.sun.star.drawing.EllipseShape" )
then I know what service it is, because I gave the service name.
You can always tell what interfaces are available if you know the name of the service -- just by looking at the API docs. No guesswork. No need for Xray. It is an absolute science. The collection of valid interfaces are the interfaces of the service itself, and of all of the services which the service includes, recursively.
In some cases, it is fairly clear what service you have.
If you call getCellRangeByName(), then you have a SheetCellRange. If you call getCellByPosition(), then you only have a SheetCell. Many of the same things are available on both a SheetCell and a SheetCellRange, but they are different animals. A SheetCellRange
does represent a rectangular group of cells, while a SheetCell
represents only a single cell. There are things you can do to a single cell that you cannot do to a group of cells together.
There are other issues as well. If you get a com.sun.star.table.CellRange from a table, it is just that. But if you get one from a spreadsheet, it is not only that, but it is really a com.sun.star.sheet.SheetCellRange. The SheetCellRange is merely an extended version of the CellRange. Which of the two services you have depends on whether you called getCellRangeByName() on a table, or on a spreadsheet.
Sometimes, especially in Writer, only the Developer's Guide helps clear up exactly what underlying service you get back from some other API method call. Writer is especially bad about that. But it is always the case that when you know what service you have, you can directly deduce, only from the API docs, exactly all of the interfaces that are valid to query. No guesswork. It is an exact science.
An other concrete Example
The IDL files are available with SDK in <OpenOffice.org1.1_SDK>/idl/ directory. Of course, the problem with this way is we only see the SDK's UNO IDL documentation, which can be slightly different from the Openoffice.org binary : remember the SDK comes months after a new version of Openoffice.org (it's not the case now). However, we will explain this way after just mentioning an other way : registry exploring. In fact, at the moment, I have no idea what kind of information can be derived from registery (see UNO registery and Bootstrapping)
We want now to show an example : we start from a com.sun.star.document.OfficeDocument and then examine <OpenOffice.org1.1_SDK>/idl/com/sun/star/document/OfficeDocument.idl presented below, (with removing all comments) :
//Listing 8 Interface Specification //IDL service OfficeDocument { interface com::sun::star::frame::XModel; interface com::sun::star::util::XModifiable; interface com::sun::star::frame::XStorable; interface com::sun::star::view::XPrintable; [optional] interface XEventBroadcaster; [optional] interface XEventsSupplier; [optional] interface XDocumentInfoSupplier; [optional] interface XViewDataSupplier; [optional] interface com::sun::star::view::XPrintJobBroadcaster; [property, optional] boolean AutomaticControlFocus; [property, optional] boolean ApplyFormDesignMode; };
If we have a look at com.sun.star.text.TextDocument service, we find in the corresponding IDL file at <OpenOffice.org1.1_SDK>/idl/com/sun/star/text/TextDocument.idl :
//Listing 8 service TextDocument { service com::sun::star::document::OfficeDocument; interface com::sun::star::text::XTextDocument; interface com::sun::star::util::XSearchable; interface com::sun::star::util::XRefreshable; .... };
As can be seen, the service com.sun.star.document.OfficeDocument belongs to com.sun.star.text.TextDocument service. This dépendance is inheritance as can be shwon in the figure below :
Remember, we have already tackled Interfaces in this section.
What is described so far is simple because we don't walk deep in the IDL-tree. In the following section we will go on to study complication with services.
C++ and services : it's not so easy
If you really want to understand this section, at every variable ask yourself what services are available. |
It's time to go deeper in our example and provide code with comments. For this purpose, we shall take code already tackled (see the Corresponding Writer Code).
//Listing 9 Writer Example //C++ OUString sDocUrl; osl::FileBase::getFileURLFromSystemPath( OUString::createFromAscii("/home/smoutou/Documents/demo.sxw"),sDocUrl); Reference< XComponent > xWriterComponent = rComponentLoader->loadComponentFromURL( sDocUrl, OUString::createFromAscii("_blank"), 0, Sequence < ::com::sun::star::beans::PropertyValue >()); Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);
The code above shows us the xWriterComponent variable is a type com.sun.star.lang.XComponent, which gives us com.sun.star.text.TextDocument service and then com.sun.star.document.OfficeDocument service as already explained.
com.sun.star.text.XTextDocument is an Interface of TextDocument
service, easy to remember because only the X letter is added. But let's go on.
XTextDocument.idl shows us the getText method, but we don't know what new services are returned by this method. Only two ways to learn that : Internet XText interface gives the answer : the service is com.sun.star.text.Text. The other way is to use Reflection as described later in this section.
//Listing 10 Writer Example (continuation) //C++ Reference< XText > xText = xTextDocument->getText();
We try to get a XTextCursor Interface
//Listing 11 Writer Example (continuation) //C++ Reference< XTextCursor> xTextCursor = xText->createTextCursor();
But how to explain this code ? Looking for in XText.idl files only shows two methods :
//Listing 12 XText Interface IDL file // IDL module com { module sun { module star { module text { interface XText: com::sun::star::text::XSimpleText { void insertTextContent( [in] com::sun::star::text::XTextRange xRange, [in] com::sun::star::text::XTextContent xContent, [in] boolean bAbsorb ) raises( com::sun::star::lang::IllegalArgumentException ); void removeTextContent( [in] com::sun::star::text::XTextContent xContent ) raises( com::sun::star::container::NoSuchElementException ); }; }; }; }; };
But if you have a closer look at the IDL file, you will see the inheritance from XSimpleText. Is the createTextCursor method here ? Yes, as you can see.
//Listing 13 XSimpleText Interface IDL file // IDL module com { module sun { module star { module text { interface XSimpleText: com::sun::star::text::XTextRange { com::sun::star::text::XTextCursor createTextCursor(); com::sun::star::text::XTextCursor createTextCursorByRange( [in] com::sun::star::text::XTextRange aTextPosition ); [oneway] void insertString( [in] com::sun::star::text::XTextRange xRange, [in] string aString, [in] boolean bAbsorb ); void insertControlCharacter( [in] com::sun::star::text::XTextRange xRange, [in] short nControlCharacter, [in] boolean bAbsorb ) raises( com::sun::star::lang::IllegalArgumentException ); }; }; }; }; };
What are the services available here ? I have found them with a reflection tool :
******** Services : 8 com.sun.star.text.TextSortable com.sun.star.style.ParagraphPropertiesComplex com.sun.star.style.ParagraphPropertiesAsian com.sun.star.style.ParagraphProperties com.sun.star.style.CharacterPropertiesComplex com.sun.star.style.CharacterPropertiesAsian com.sun.star.style.CharacterProperties com.sun.star.text.TextCursor
You can probably find all of them with internet, but I think it will be a long task : a good reason for explaining reflection services later in this chapter.
It's using a method returning an Interface Type, which make things difficult. To find then services is very difficult and personally, I use an introspection tool to find them (see an example here). Good news, two methods gives us explicitly the returned type : createInstance and createInstanceWithContext where the service is given as a parameter.
|
Yes, you have to walk through such ways to find what you can do when programming. Fortunately, there is a shorter way : the SDK examples. Most of them are in Java, but I have found many ideas with them.
IDL and C++
This problem is tackled in Developer's guide.
Getting an interface in C++
In C++, you only have variables of an Interface type. One of the most often encountered problem in C++ programming is then querying an interface. This problem occurs very rarely in OooBasic but very often in C++/Java. We can find an example in "SDK C++ language" and many other in Office UNO automation.
Obtaining an Interface with a buit-in function
We have already encountered such an use when studying bootstrapping code. Here is a schematic representation.
We start from nothing but use the defaultBootstrap_IntitialComponentContext()
built-in function and get an com.sun.star.uno.XComponentContext interface.
Obtaining an Interface with UNO_QUERY macro
As an example, we suppose we have obtained a com.sun.star.text.XTextDocument interface. This is done in general by something like:
//Listing 2 C++ code to get a service //C++ Reference<com::sun::star::text::XTextDocument> OfDoc = something_to_get_this_interface();
or
Listing 3 using namespace to simplify the code //C++ using namespace com::sun::star::text; .... Reference<XTextDocument> OfDoc = something_to_get_this_interface();
and we want to query the com.sun.star.frame.XStorable interface to save our document. The figure below shows us all the interfaces we can query starting from com.sun.star.text.XTextDocument interface.
Note that we can query all the interfaces shown from com.sun.star.util.XTextDocument, even though the diagram omits some of the red arrows.
Three steps to have an interface
Three steps are involved in this query :
Step 1 Add your code's line as UNO's query
//Listing 4 The UNO query in C++ code // C++ // query from com::sun::star::frame::XStorable interface Reference< XStorable > oToStore (OfDoc, UNO_QUERY);
If the variable is already declared, please use :
//Listing 4b The UNO query in C++ code // C++ // query from com::sun::star::frame::XStorable interface oToStore = Reference< XStorable > (OfDoc, UNO_QUERY);
Step 2 Add the hpp file in an include statement. Add the corresponding namespace in an using namespace statement. Including is done with :
//Listing 5 The corresponding include statement //C++ #include <com/sun/star/frame/XStorable.hpp>
and the corresponding namespace statement is :
//Listing 6 The corresponding namespace statement //C++ using namespace com::sun::star::frame;
Step 3 Add the corresponding type in the makefile as shown below (XStorable line) :
# makefile # added com.sun.star.frame.XStorable TYPES := \ com.sun.star.uno.XNamingService \ .... com.sun.star.uno.XAggregation \ com.sun.star.frame.XStorable \ com.sun.star.lang.XMain \ ... com.sun.star.container.XHierarchicalNameAccess
Learn to realize these three steps : you can not program in C++ without encountering an interface query. This problem of asking an interface is already tackled in Office UNO automation and Calc API Programming, in fact in all chapters tackled so far. |
Concrete Example
To help us understand the task above, let's us show a concrete example. All can be shown as a way through an IDL-tree :
And here is the corresponding code.
//Listing 19 Simple UNO_QUERY call // C++ OUString sDocUrl; osl::FileBase::getFileURLFromSystemPath( OUString::createFromAscii("/home/smoutou/Documents/demo.sxw"),sDocUrl); Reference< XComponent > xWriterComponent = rComponentLoader->loadComponentFromURL( sDocUrl, OUString::createFromAscii("_blank"), 0, Sequence < ::com::sun::star::beans::PropertyValue >()); Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY); // Don't forget to include #include <com/sun/star/frame/XStorable.hpp> Reference < XStorable > xStorable (xTextDocument,UNO_QUERY); xStorable->store();
which use com.sun.star.text.XTextDocument and com.sun.star.frame.XStorable interfaces.
You have to learn to get interface in another way, with first asking a service.
Getting an Interface through XMultiServiceFactory
See also Instantiate a Service snippet.
We have already encountered such a thing, so it should be quite familiar to us by now. But, because we have not discussed every step in detail, I want to illustrate how it works.
The Problem
How can you get an interface if the corresponding service is not directly available ? This is shwon in the figure below :
where both services com.sun.star.text.TextDocument and com.sun.star.text.TextTable haven't a direct dependance.
The Solutions
First case : a method of your interface allows to get the new interface. It was the case of the code of Listing 11. In this case the corresponding hdl file is not necessary and I have not found a way to retrieve the new services available witout a reflection tool !
Rule 3 : when getting an Interface with a method you never need to construct hdl files starting from IDL file as it is necessary in the three steps operation.
Second case : no interface's method can help you. You have to query a service before getting the interface. This can be done with two or three instructions style. I have already used both styles. Have a look into this listing :
//Listing 20 Getting an Interface with XMultiServiceFacory // C++ Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY); Reference<XMultiServiceFactory> oDocMSF (xTextDocument,UNO_QUERY); // Don't forget to add #include <com/sun/star/text/XTextTable.hpp> Reference <XTextTable> xTable (oDocMSF->createInstance( OUString::createFromAscii("com.sun.star.text.TextTable")),UNO_QUERY);
which uses two instruction style with com.sun.star.text.XTextDocument and com.sun.star.text.XTextTable interfaces.
With three instructions style, the same code is shown in the listing above :
//Listing 21 Inserting a Table in a OOoWriter Document // C++ Reference<XMultiServiceFactory> oDocMSF (xTextDocument,UNO_QUERY); Reference< XInterface > textTable = oDocMSF->createInstance( OUString::createFromAscii("com.sun.star.text.TextTable") ); // Don't forget to add #include <com/sun/star/text/XTextTable.hpp> Reference< XTextTable > xTable(textTable, UNO_QUERY);
Note that both method require to include (and then construct) the corresponding hpp file (here XtextTable.hpp, as usual with the three steps method), but not for the service because you get it with a method (named « createInstance » in this case) and cast it in a variable com.sun.star.uno.XInterface (see rule 3). We give a schematic to summarize what we talked about.
Last question : is it possible to start from any XMultiServiceFactory interface ? The answer to this question is no. Have a look to the code below where I take rOfficeServiceManager instead of oDocMSF because it's a XmultiServiceFactory Interface too.
//Listing 22 Wrong code // C++ // Reference<XMultiServiceFactory> oDocMSF (xTextDocument,UNO_QUERY); // using rOfficeServiceManager instead oDocMSF Reference< XInterface > textTable = rOfficeServiceManager->createInstance( OUString::createFromAscii("com.sun.star.text.TextTable") ); Reference< XTextTable > xTable(textTable, UNO_QUERY); if (!xTable.is()) { printf("Erreur creation XTextTable interface !\n"); return 1; }
This code compiles but gives a runtime error. This only means you cannot use every com.sun.star.lang.XMultiServiceFactory interface to get every Interface.
If you are working with a document, ask the corresponding XMultiServiceFactory interface. At this point, only experience can help you. |
Another example already tackled
Note before going further, that a code used many times so far, can find an explanation. Even if in this case, the XMultiServiceFactory interface is not obtained in a standard way (for a document) because we still not have a document at this point in the code, the principles are the same :
//Listing 23 Classic code // C++ int main( ) { //retrieve an instance of the remote service manager Reference< XMultiServiceFactory > rOfficeServiceManager; rOfficeServiceManager = ooConnect(); //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);
Easy to retrieve the three instructions style to get the com.sun.star.frame.XComponentLoader interface with using com.sun.star.frame.Desktop service, isn't it ?
Here is the corresponding IDL-tree.
When sketching IDL-tree in this document, I will always show the com.sun.star.uno.XInterface interface when getting a service. There is no other reason to see such an interface in an IDL-tree. |
Another more technical problem is the mapping : you have an IDL file, how is it compiled in C++ ? The next section tackle the subject : you can skip it in a first reading and go on into this section.
Mapping for Modules and Interfaces
We tackle in this section the correspondance between IDL files and the C++ automatically generated code. This problem has already been tackled with particular simple but very useful types :
See Developer's Guide for a more complete explanation.
Other examples are provided now. For instance:
// IDL module M { struct E { long L; }; };
is mapped into:
// C++ namespace M { struct E { Long L; }; }
and E can be referred outside of M as M::E. Alternatively, a C++ using statement for namespace M can be used so that E can be referred to simply as E:
// C++ using namespace M; E e; e.L = 3;
Core reflection service and its Interfaces
Many entry points for reflection are descibed in the Developer's Guide. We give again any of them here and show a way to use them with C++.
Before going further with technical problems, it's important to recall why introspection tools are useful. In this chapter, we have already shown and say why the great difficulty in UNO programming is to know, at every step, what are the services and interfaces available. This information resides in IDL files, but in my opinion, only partially. To recover this information is more easy with an introspection tool.
Reflection in OOoBasic
The aim of this section is not to replace the beautiful Bernard Marcelly's tool : XRay. See a short description in this wiki. |
OooBasic allow many things and in particular to explore core by reflection. Danny Brewer's code shows us how to work around ? We have a look at his code :
REM ***** BASIC ***** Sub Main oReflection = createUnoService( "com.sun.star.reflection.CoreReflection" ) oInfo = oReflection.forName( "nom.dannybrewer.test.XDannysCalcFunctions1" ) aMethods = oInfo.getMethods() For i = 0 To UBound( aMethods ) oMethod = aMethods( i ) Print oMethod.getName() Next End Sub
We then create an idl file :
// IDL #include <com/sun/star/uno/XInterface.idl> #include <com/sun/star/lang/XInitialization.idl> module my_module { interface XSomething : com::sun::star::uno::XInterface { long getCount(); void setCount( [in] long nCount ); long increment(); long decrement(); }; service MyService { interface XSomething; }; };
With this IDL file, we create a rdb file and register this rdb file. Now Apache OpenOffice works as if we have an add-on even if we have not written its code. We cannot launch this add-on (without its code !) but we can see it. We then modify the above Danny's program :
REM Listing 11 REM ***** BASIC ***** 'From Danny : http://www.oooforum.org/forum/viewtopic.php?t=8737 Sub Main oReflection = createUnoService( "com.sun.star.reflection.CoreReflection" ) oInfo = oReflection.forName( "my_module.XSomething" ) aMethods = oInfo.getMethods() 'XRay oInfo print UBound( aMethods )+1 & " methods : ****" For i = 0 To UBound( aMethods ) oMethod = aMethods( i ) Print oMethod.getName() Next aTypes = oInfo.getTypes() print UBound( aTypes )+1 & " types : ****" For i = 0 To UBound( aTypes ) oType = aTypes( i ) Print "Types : " + oType.getName() Next aInterfaces = oInfo.getInterfaces() print UBound( aInterfaces )+1 & " interfaces : ****" For i = 0 To UBound( aInterfaces ) oInterface = aInterfaces( i ) Print "Interfaces : " + oInterface.getName() Next End Sub
launching this modified program produces :
7 methods : **** queryInterface acquire release getCount setCount increment decrement 3 types : **** Types : com.sun.star.reflection.XIdlClass Types : com.sun.star.lang.XTypeProvider Types : com.sun.star.uno.XWeak 0 Interfaces : ****
We can see among others the four methods given in the IDL file.
It is possible to retrieve more information on the methods for instance. If you want all the information given in the IDL file you can use OOoBasic code like that :
For i = LBound( oMethods ) To UBound( oMethods ) oMethod = oMethods( i ) ' Check the method's interface to see if ' these aren't the droids you're looking for. sString = oMethod.getReturnType().getName() & " " & oMethod.getName() & "(" parametersInfo = oMethod.getParameterInfos() if UBound(parametersInfo) > 0 then for ii=0 to UBound(parametersInfo) if parametersInfo(ii).aMode = com.sun.star.reflection.ParamMode.IN Then stringType = "IN " elseif parametersInfo(ii).aMode = com.sun.star.reflection.ParamMode.OUT Then stringType = "OUT " else stringType = "INOUT " end if sString = sString & stringType & ParametersInfo(ii).aType.getName() & " " & parametersInfo(ii).aName if ii < UBound(parametersInfo) Then sString = sString & ", " Next end if sString = sString & ")" ' something to do with sString here Next
To go further in C++, we examine XdlRefection Interface in next section.
XIdlReflection interface
The com.sun.star.reflection.XIdlReflection Interface is described in the section CoreReflection Service in Developer's Guide. This interface is also described here with C++ code example.
The XIntrospection Interface
This interface com.sun.star.beans.XIntrospection is described here with C++ code examples. Other code is given in Constructing Helpers section. See also Introducing the OpenOffice.org_API and OOoBasic Introspection and Developer's Guide.
Using Java Inspector
For an introduction of using Java with Apache OpenOffice, see Java and Eclipse tutorial. This point is not tackled here : we are only interested by using a Java component with C++.
It is possible in principle, to use the Java inspector tools from every programming languages because it's a component. The way to do that is very simple :
1°) Compile the java example in <OpenOffice.org_SDK>/examples/java/Inspector after adding SDK_AUTO_DEPLOYMENT = YES in the beginning of makefile.
2°) Create a OOoBasic example, for instance (OOo1.1.X) :
'Listing 17 Simple OOoBasic example to call the Java Inspector REM ***** BASIC ***** Sub JavaInspector o = createUnoService("org.OpenOffice.InstanceInspector") 'XRay o oReflection = createUnoService( "com.sun.star.reflection.CoreReflection" ) o.inspect(oReflection) End Sub
For newer version of Java Inspector see Calling from a Basic Macro. |
If java is not properly installed when running this program, a dialog box will print out. Follow the instructions to install it (you have to know where your virtual machine (JRE) is installed. In the figure below, we see the result of this program.
Our problem is now to use the Java Inspector from C++. But I encounter a problem when I try to do that. Here is the way I choose :
- construct a urd file starting from IDL (in makefile)
- don't forget the registry of urd file in makefile
- add org.OpenOffice.XInstanceInspector in the TYPES macro in the makefile
- copy IDL file from <OpenOffice.org1.1_SDK>/examples/java/Inspector/XInstanceInspector.idl into <OpenOffice.org1.1_SDK>/idl/org/OpenOffice/ XInstanceInspector.idl
- add the #include <org/OpenOffice/XInstanceInspector.hpp> and using namespace org::OpenOffice;
- add this code
// C++ Any toInspect; toInspect <<= rDesktop; Reference< XInstanceInspector > xinspect (rOfficeServiceManager->createInstance( OUString::createFromAscii( "org.OpenOffice.InstanceInspector" )),UNO_QUERY); xinspect->inspect(toInspect);
And it works like in OOoBasic.
The corresponding Linux makefile is :
#Listing 18 Simple Makefile to compile a Java Inspector C++ call # very simple makefile HELPER = ReflectionHelper CXXFILE = office_connect.cxx OBJFILE = office_connect.o OUTBIN = office_connect OUT_COMP_INC = ../../../../LINUXexample.out/inc OUT_COMP_OBJ = ../../../../LINUXexample.out/obj OUT_COMP_BIN = ../../../../LINUXexample.out/bin # added for Inspector OUT_COMP_URD = $(OUT_COMP_BIN) # end added COMPONENT_RDB = $(OUT_COMP_BIN)/office_connect.rdb CC_FLAGS = -c -O -fpic -fno-rtti CC_DEFINES = -DUNX -DGCC -DLINUX -DCPPU_ENV=gcc3 PS = / TYPES := \ com.sun.star.uno.XNamingService \ .... com.sun.star.container.XHierarchicalNameAccess \ org.OpenOffice.XInstanceInspector # last line added TYPESLIST = $(foreach t,$(TYPES),-T$(t)) GENHPPFILES = $(foreach t,$(TYPES),$(OUT_COMP_INC)/$(subst .,/,$(t)).hpp) ALL : \ ProUNOCppBindingExample # added for Inspector #building urd file $(OUT_COMP_URD)/XInstanceInspector.urd : ../../../../idl/org/OpenOffice/XInstanceInspector.idl -mkdir -p $(OUT_COMP_URD) idlc -I. -I../../../../idl -O$(OUT_COMP_URD) ../../../../idl/org/OpenOffice/XInstanceInspector.idl # end added #office_connectrc is provided with SDK $(OUT_COMP_BIN)/office_connectrc : office_connectrc -mkdir -p $(OUT_COMP_BIN) cp office_connectrc $(OUT_COMP_BIN)/office_connectrc $(COMPONENT_RDB) : $(OUT_COMP_URD)/XInstanceInspector.urd -mkdir -p $(OUT_COMP_BIN) # added for Inspector regmerge $(COMPONENT_RDB) /UCR $(OUT_COMP_URD)/XInstanceInspector.urd # end added regmerge $(COMPONENT_RDB) / "/usr/lib/openoffice/program/types.rdb" @echo -------------------------------------------------------------------------------- @echo Register necessary runtime components in $(COMPONENT_RDB) @echo -------------------------------------------------------------------------------- regcomp -register -r $(COMPONENT_RDB) -c connector.uno.so regcomp -register -r $(COMPONENT_RDB) -c remotebridge.uno.so regcomp -register -r $(COMPONENT_RDB) -c bridgefac.uno.so regcomp -register -r $(COMPONENT_RDB) -c uuresolver.uno.so # @echo bla > $@ $(GENHPPFILES) : $(subst /,$(PS),$(@D)) mkdir -p $(subst /,$(PS),$(@D)) # modified for Inspector cppumaker -Gc -BUCR -O$(OUT_COMP_INC) $(TYPESLIST) "/usr/lib/openoffice/program/types.rdb" cppumaker -Gc -BUCR -O$(OUT_COMP_INC) $(TYPESLIST) $(COMPONENT_RDB) $(OUT_COMP_OBJ)/$(OBJFILE) : $(CXXFILE) $(GENHPPFILES) $(HELPER).hpp -mkdir -p $(subst /,$(PS),$(@D)) gcc $(CC_FLAGS) $(CC_INCLUDES) -I. -I/usr/include -I$(OUT_COMP_INC)/examples \ -I../../../../include -I$(OUT_COMP_INC) $(CC_DEFINES) -o$(OUT_COMP_OBJ)/$(OBJFILE) $(CXXFILE) $(OUT_COMP_OBJ)/$(HELPER).o : $(HELPER).cxx $(HELPER).hpp -mkdir -p $(OUT_COMP_OBJ)/ gcc $(CC_FLAGS) $(CC_INCLUDES) -I. -I/usr/include -I$(OUT_COMP_INC)/examples \ -I../../../../include -I$(OUT_COMP_INC) $(CC_DEFINES) -o$(OUT_COMP_OBJ)/$(HELPER).o $(HELPER).cxx $(OUT_COMP_BIN)/$(OUTBIN) : $(OUT_COMP_OBJ)/$(OBJFILE) $(OUT_COMP_OBJ)/$(HELPER).o -mkdir -p $(OUT_COMP_BIN) gcc -Wl -export-dynamic -L../../../../LINUXexample.out/lib -L../../../../linux/lib -L/usr/lib/openoffice/program \ $(OUT_COMP_OBJ)/$(HELPER).o \ -o$(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_OBJ)/$(OBJFILE) -lcppuhelpergcc3 -lcppu -lsalhelpergcc3 -lsal -lstlport_gcc ProUNOCppBindingExample : $(COMPONENT_RDB) $(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_BIN)/office_connectrc @echo -------------------------------------------------------------------------------- @echo Please use one of the following commands to execute the examples! @echo @echo make office_connect.run @echo -------------------------------------------------------------------------------- office_connect.run : $(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_BIN)/office_connectrc cd $(OUT_COMP_BIN) && $(OUTBIN)
Note 1 : The New Object Inspector appears in SDK after 2.0 version. It is more complex and able to generate Java, C++ or OOoBasic code. I have not checked the above code with the the new object inspector but don't see why it could not work properly. |
Note 2 : A little example with the new object inspector can be found in this document. |
There is a simpler way to use Java Inspector. It's a component as all others and probably doesn't need starting from the IDL file, but constructing hpp files directly from a RDB file, because the corresponding service is already registered. Then you only have to add "org.OpenOffice.XInstanceInspector" in the TYPE section of the makefile. See Java Inspector in component : you can use Java Inspector in the same way with binary executable.
Translating OOoBasic programs into C++
The translation of OOoBasic programs is not straightforward. The Interfaces, attributes seen with OOoBasic are constructed probably with a bridge for programming facility. Then what you see in OOoBasic will not be seen with C++. Consequently, it is impossible to imagine to achieve this task without reading IDL files.
When I tackled Writer in OOoWriter chapter, I let the reader resolve some problems (particularly cursors problems). We chose these problems here as an example. We give first the OOoBasic program.
'Listing 36 Simple OOoBasic program to translate REM **** OOoBasic Dim MyDocument As Object, MyText As Object Dim MyCursor As Object MyDocument = ThisComponent MyText = MyDocument.Text MyCurseur= MyTexte.createTextCursor MyCurseur.goRight(1, false) ' move right one character MyCurseur.goLeft(2, true) ' select the two previous characters
I summarize OOoBasic instructions to move the cursor in the above table :
- OOoBasic instructions
Method | Signification |
goRight(n, false) | moves the cursor the specified number of characters to the right |
goLeft(n, false) | moves the cursor the specified number of characters to the left |
gotoStart(false) | moves the cursor to the start of the text |
gotoEnd(false) | moves the cursor to the end of the text |
gotoStartOfParagraph(false) | moves the cursor to the start of the current paragraph |
gotoStartOfParagraph(false) | moves the cursor to the start of the current paragraph |
gotoEndOfParagraph(false) | moves the cursor to the end of the current paragraph |
gotoNextParagraph(false) | moves the cursor to the next paragraph |
gotoPreviousParagraph(false) | moves the cursor to the previous paragraph |
gotoNextWord(false) | moves the cursor to the next word |
gotoPreviousWord(false) | moves the cursor to the previous word |
gotoStartOfWord(false) | mmoves the cursor to the start of the current word |
gotoEndOfWord(false) | moves the cursor to the end of the current word |
gotoNextSentence(false) | moves the cursor to the start of the next sentence |
gotoPreviousSentence(false) | moves the cursor to the start of the previous sentence |
gotoStartOfSentence(false) | moves the cursor to the start of the current sentence |
gotoEndOfSentence(false) | moves the cursor to the end of the current sentence |
But if you want to translate the use of all these OOoBasic functions in C++, you have to query Interfaces starting from a XtextCursor interface(see below Listing 41). This make the translation difficult. For instance three different cursor interfaces are involved when using the methods of OOoBasic starting program. It's time to show all the corresponding IDL files. First of all the XWordCursor interface is shown :
//Listing 37 XWordCursor interface (IDL file) // IDL module com { module sun { module star { module text { interface XWordCursor: com::sun::star::text::XTextCursor { boolean isStartOfWord(); boolean isEndOfWord(); boolean gotoNextWord( [in] boolean bExpand ); boolean gotoPreviousWord( [in] boolean bExpand ); boolean gotoEndOfWord( [in] boolean bExpand ); boolean gotoStartOfWord( [in] boolean bExpand ); }; }; }; }; };
Now the XParagraphCursor interface is shown
//Listing 38 XParagraphCursor interface (IDL file) // IDL module com { module sun { module star { module text { interface XParagraphCursor: com::sun::star::text::XTextCursor { com::sun::star::text::XParagraphCursor::isStartOfParagraph boolean isStartOfParagraph(); boolean isEndOfParagraph(); com::sun::star::text::XParagraphCursor::gotoStartOfParagraph boolean gotoStartOfParagraph( [in] boolean bExpand ); com::sun::star::text::XParagraphCursor::gotoEndOfParagraph boolean gotoEndOfParagraph( [in] boolean bExpand ); boolean gotoNextParagraph( [in] boolean bExpand ); com::sun::star::text::XParagraphCursor::gotoPreviousParagraph boolean gotoPreviousParagraph( [in] boolean bExpand ); }; }; }; }; };
and to finish XSentenceCursor interface :
// Listing 39 XSentenceCursor interface (IDL file) // IDL module com { module sun { module star { module text { interface XSentenceCursor: com::sun::star::text::XTextCursor { boolean isStartOfSentence(); boolean isEndOfSentence(); boolean gotoNextSentence( [in] boolean Expand ); boolean gotoPreviousSentence( [in] boolean Expand ); boolean gotoStartOfSentence( [in] boolean Expand ); boolean gotoEndOfSentence( [in] boolean Expand ); }; //============================================================================= }; }; }; };
If you want to know what interface you can ask you are obliged to retrieve the service. For our example it's TextCursor service. Here is the corresponding IDL file where you see all the interfaces you can query.
//Listing 40 TextCursor service (IDL file) // IDL module com { module sun { module star { module text { service TextCursor { service com::sun::star::text::TextRange; interface com::sun::star::text::XTextCursor; [optional] interface com::sun::star::text::XWordCursor; [optional] interface com::sun::star::text::XSentenceCursor; [optional] interface com::sun::star::text::XParagraphCursor; interface com::sun::star::beans::XPropertySet; interface com::sun::star::beans::XPropertyState; interface com::sun::star::beans::XMultiPropertyStates; [optional] interface com::sun::star::document::XDocumentInsertable; [optional] interface com::sun::star::util::XSortable; }; }; }; }; };
If you start for instance from Listing 11 you will need a UNO_QUERY to get a XWordCursor interface.
//Listing 41 Using XwordCursor Interface // C++ // Don't forget to add : #include <com/sun/star/text/XWordCursor.hpp> // Don't forget to add "com.sun.star.text.XWordCursor \" in the makefile Reference < XWordCursor > xWordCursor (xTextCursor,UNO_QUERY); xWordCursor->gotoNextWord(false); xWordCursor->gotoNextWord(false); xWordCursor->gotoNextWord(true);
The translation could be achieve automatically, but such a compiler has to have knowledge on IDL files.
By the way here we have again all these eight services available :
******** Services : 8 com.sun.star.text.TextSortable com.sun.star.style.ParagraphPropertiesComplex com.sun.star.style.ParagraphPropertiesAsian com.sun.star.style.ParagraphProperties com.sun.star.style.CharacterPropertiesComplex com.sun.star.style.CharacterPropertiesAsian com.sun.star.style.CharacterProperties com.sun.star.text.TextCursor
Further reading
I will use OOoBasic and translate it in C++ when writing Managing a Dialog in a Component and Going further with Dialog and Components. Even with my own C++ experience, it was impossible for me to program directly in C++ in these chapters.
Home Page
See Also
- French version of this chapter.
- UNO Reflection API in Developer's Guide
- C++ and UNO tutorial
- UNO tutorial
- UNO IDL
- Uno/Article/Types&Reflection
- Introduction to the OpenOffice.org API
- Writing a Program to Control OpenOffice.org, by Franco Pingiori — Part 1 and Part 2, Linux Journal
- See also The New Object Inspector
- Extensions Introspection
- BASIC UNO Object Browser