https://wiki.openoffice.org/w/api.php?action=feedcontributions&user=BMarcelly&feedformat=atomApache OpenOffice Wiki - User contributions [en]2024-03-28T13:45:50ZUser contributionsMediaWiki 1.23.13https://wiki.openoffice.org/wiki/NL/Documentation/BASIC_Guide/UNO_ToolsNL/Documentation/BASIC Guide/UNO Tools2016-05-01T06:48:12Z<p>BMarcelly: /* Gereedschap om te debuggen */</p>
<hr />
<div>{{DISPLAYTITLE:Gereedschap om te werken met UNO}}<br />
{{NL/Documentation/BASICGuideTOC/v2<br />
|ShowPrevNext=block<br />
|ShowPrevPage=block<br />
|PrevPage=NL/Documentation/BASIC Guide/Modules, Services and Interfaces<br />
|NextPage=NL/Documentation/BASIC Guide/Interface Overview<br />
|api=block<br />
}}<br />
<br />
De vraag blijft bestaan, welke objecten – of services als we blijven in de terminologie van UNO – ondersteunen welke eigenschappen, methoden en interfaces en hoe kunnen deze worden bepaald. In aanvulling op deze gids, kunt u meer informatie over objecten vinden in de volgende bronnen: de methode <tt>supportsService</tt>, de methoden voor debuggen en ook in de Developer's Guide en de verwijzingen naar de API.<br />
<br />
== De methode <tt>supportsService</tt> ==<br />
<br />
Een aantal objecten in UNO ondersteunt de methode <tt>supportsService</tt>, waarmee u vast kunt stellen of een object een bepaalde service ondersteunt. De volgende aanroep bijvoorbeeld bepaalt of het object <tt>TekstElement</tt> de service <idl>com.sun.star.text.Paragraph</idl> ondersteunt.<br />
<br />
<source lang="oobas"><br />
OK = TekstElement.supportsService("com.sun.star.text.Paragraph")<br />
</source><br />
<br />
== Eigenschappen debuggen ==<br />
<br />
Elk object in UNO weet welke eigenschappen, methoden en interfaces het al bevat. {{OOo}} BASIC verschaft eigenschappen die deze kunnen weergeven in de vorm van een tekenreeks die een lijst bevat. De overeenkomende eigenschappen zijn:<br />
<br />
;<tt>DBG_properties</tt>: geeft een tekenreeks terug die alle eigenschappen van een object bevat<br />
;<tt>DBG_methods</tt>: geeft een tekenreeks weer die alle methoden van een object bevat <br />
;<tt>DBG_supportedInterfaces</tt>: geeft een tekenreeks weer die alle interfaces bevat die een object ondersteunen.<br />
<br />
De volgende programmacode toont hoe <tt>DBG_properties</tt> en <tt>DBG_methods</tt> kunnen worden gebruikt in echte toepassingen. Het creëert eerst de service <idl>com.sun.star.frame.Desktop</idl> en geeft dan de ondersteunde eigenschappen en methoden weer in berichtenvensters.<br />
<br />
<source lang="oobas"><br />
Dim Obj As Object<br />
Obj = createUnoService("com.sun.star.frame.Desktop")<br />
<br />
MsgBox Obj.DBG_Properties<br />
MsgBox Obj.DBG_methods<br />
</source><br />
<br />
Wees er attent op dat bij het gebruik van <tt>DBG_properties</tt> de functie alle eigenschappen die een bepaalde service theoretisch kan ondersteunen weergeeft. Er is echter geen garantie dat deze ook kunnen worden gebruikt door het gevraagde object. In hele zeldzame gevallen moet u dus, vóór het opvragen van een eigenschap, eerst de functie <tt>IsEmpty</tt> gebruiken om te controleren of de eigenschap wel echt beschikbaar is.<br />
<br />
== Gereedschap om te debuggen ==<br />
<br />
het gebruiken van de eigenschappen '''<tt>DBG_</tt>''' is een hele ruwe methode om de inhoud van een object van de API te ontdekken.<br />
<br />
Het venster Controle van de BASIC IDE kan de eigenschappen van een object van UNO weergeven (maar niet de methoden en niet de interfaces).<br />
<br />
Gebruik in plaats daarvan <b>[[Extensions_development_basic#Xray_tool|programma Xray]] of [http://extensions.services.openoffice.org/project/MRI programma MRI]</b> om alle beschikbare informatie van een object weer te geven en te koppelen aan de overeenkomende documentatie van de API.<br />
<br />
{{Documentation/VBAnote|{{OOo}} BASIC heeft '''geen''' aanvulling van code. Alleen tijdens runtime kunt u vaststellen welke eigenschappen of methoden beschikbaar zijn voor een object. Alle bovengenoemde programma's voor debuggen werken bij een programma dat wordt uitgevoerd. }}<br />
<br />
== Verwijzingen naar de API ==<br />
<br />
Meer informatie over de beschikbare services en hun interfaces, methodenen eigenschappen kan worden gevonden in de [http://api.openoffice.org/docs/common/ref/com/sun/star/module-ix.html verwijzingen voor de {{OOo}} API].<br />
<br />
<br />
{{InterWiki Languages BasicGuide|articletitle=Documentation/BASIC Guide/UNO Tools}}<br />
{{PDL1}}</div>BMarcellyhttps://wiki.openoffice.org/wiki/FR/Documentation/XIntrospection_InterfaceFR/Documentation/XIntrospection Interface2016-05-01T06:45:17Z<p>BMarcelly: /* See also */</p>
<hr />
<div>Nous préférons utiliser la technique de l'Inspector Java : inspecter un objet réel. Vous pouvez trouver les valeurs des propriétés par exemple (<OpenOffice.org1.1_SDK>/examples/java/Inspector). De nouveau nous décrivons sommairement les interfaces que nous allons rencontrer. Commençons d'abord par l'interface <idl>com.sun.star.beans.XIntrospection</idl> :<br />
<source lang="idl"><br />
// IDL<br />
module com { module sun { module star { module beans {<br />
<br />
interface XIntrospection: com::sun::star::uno::XInterface<br />
{ <br />
com::sun::star::beans::XIntrospectionAccess inspect( [in] any aObject );<br />
};<br />
}; }; }; };<br />
</source> <br />
où nous voyons que nous devons nous concentrer sur l'autre interface <idl>com.sun.star.beans.XIntrospectionAccess</idl> :<br />
<source lang="idl"><br />
// IDL<br />
module com { module sun { module star { module beans {<br />
interface XIntrospectionAccess: com::sun::star::uno::XInterface<br />
{ <br />
long getSuppliedMethodConcepts(); <br />
long getSuppliedPropertyConcepts();<br />
com::sun::star::beans::Property getProperty( [in] string aName,<br />
[in] long nPropertyConcepts ) <br />
raises( com::sun::star::container::NoSuchElementException );<br />
boolean hasProperty( [in] string aName,<br />
[in] long nPropertyConcepts ); <br />
sequence<com::sun::star::beans::Property> getProperties( <br />
[in] long nPropertyConcepts );<br />
com::sun::star::reflection::XIdlMethod getMethod( [in] string aName, <br />
[in] long nMethodConcepts )<br />
raises( com::sun::star::lang::NoSuchMethodException ); <br />
boolean hasMethod( [in] string aName, <br />
[in] long nMethodConcepts );<br />
sequence<com::sun::star::reflection::XIdlMethod> getMethods(<br />
[in] long nMethodConcepts ); <br />
sequence<type> getSupportedListeners(); <br />
com::sun::star::uno::XInterface queryAdapter( [in] type aInterfaceType ) <br />
raises( com::sun::star::beans::IllegalTypeException ); <br />
};<br />
}; }; }; };<br />
</source><br />
S'il vous plait, prenez seul votre envol et regardez attentivement les autres fichiers IDL invoqués : <idl>com.sun.star.beans.Property</idl> et <idl>com.sun.star.uno.XInterface</idl>.<br />
<br />
== Obtenir des informations sur les méthodes ==<br />
Nous présentons maintenant comment construire l'information d'introspection à l'aide d'un schéma.<br />
<br />
[[Image:XIntrospectionMethodInfo.png]]<br />
<br />
La figure ci-dessus explique comment obtenir l'information sur les méthodes comme, le type retourné, le nom même de la méthode, et tout ce que vous voulez savoir sans oser le demander sur les paramètres. S'il vous plaît notez que <code>getParamMode</code> n'est pas fourni par le SDK, mais est mon propre code (inspiré très fortement de l'Inspector Java). Voir aussi l'énumération <idl>com.sun.star.reflection.ParamMode</idl>. <br />
{{Documentation/Caution|Comme vous le verrez dans le code C++, il y a une faute dans la figure ci-dessus pour le type retourné. La méthode est <code>getReturnType</code> au lieu de <code>getReturnedType</code>. Je corrigerai cela plus tard dans la figure.}}<br />
Commençons par donner le code correspondant à la fonction <code>getParamMode</code> :<br />
<source lang="cpp"><br />
//Listing 12 getParamMode function<br />
// C++<br />
// Ne pas oublier d'ajouter : #include <com/sun/star/reflection/ParamMode.hpp><br />
// Ne pas oublier d'ajouter : "com.sun.star.reflection.ParamMode \" in the makefile<br />
OUString getParamMode(ParamMode paramMode) {<br />
// comes from <OpenOffice1.1_SDK>/examples/java/Inspector<br />
OUString toReturn;<br />
toReturn = OUString::createFromAscii("");<br />
if (paramMode == ParamMode_IN) toReturn = OUString::createFromAscii("IN"); else<br />
if (paramMode == ParamMode_OUT) toReturn = OUString::createFromAscii("OUT"); else<br />
if (paramMode == ParamMode_INOUT) toReturn = OUString::createFromAscii("INOUT");<br />
return toReturn;<br />
}<br />
</source><br />
Et maintenant l'implémentation complète est donnée : partant de la figure ci-dessus, c'est facile de voir que nous avons besoin de deux paramètres, une interface <idl>com.sun.star.lang.XMultiServiceFactory</idl> (qui est la racine de notre arbre IDL) et un type Any (dans lequel nous mettons l'objet à introspecter) :<br />
<source lang="cpp"><br />
//Listing 13 getMethods function<br />
//C++<br />
// translated in C++ from <OpenOffice1.1_SDK>/examples/java/Inspector<br />
<br />
// Don't forget to add : using namespace com::sun::star::beans;<br />
// Don't forget to add : #include <com/sun/star/beans/XIntrospection.hpp><br />
// Don't forget to add "com.sun.star.beans.XIntrospection \" in the makefile<br />
<br />
Sequence <OUString> getMethods(Any any,Reference< XMultiServiceFactory > rSVM)<br />
Reference< XIntrospection >xIntrospection = Reference< XIntrospection ><br />
( rSVM->createInstance(<br />
OUString( RTL_CONSTASCII_USTRINGPARAM(<br />
"com.sun.star.beans.Introspection" ))), UNO_QUERY );<br />
<br />
// ********* get all methods for the given object *********************<br />
<br />
Reference< XIntrospectionAccess > xIntrospec = xIntrospection->inspect(any);<br />
<br />
// Don't forget to add : #include <com/sun/star/beans/MethodConcept.hpp><br />
// Don't forget to add "com.sun.star.beans.MethodConcept \" in the makefile<br />
Sequence< Reference < XIdlMethod > > mMethods = xIntrospec -> getMethods(MethodConcept::ALL);<br />
Sequence<OUString> OUStrs(mMethods.getLength());<br />
for (int i=0;i<mMethods.getLength();i++){<br />
OUString params;<br />
params=OUString::createFromAscii("(");<br />
Sequence< ParamInfo > ParamInfos = mMethods[i]->getParameterInfos();<br />
if (ParamInfos.getLength() > 0) {<br />
for (int j=0;j<ParamInfos.getLength();j++){<br />
Reference< XIdlClass > xIdlClass = ParamInfos[j].aType;<br />
if (j == 0)<br />
// first parameter has no leading comma<br />
params += OUString::createFromAscii("[") + getParamMode(ParamInfos[j].aMode)+<br />
OUString::createFromAscii("]") +<br />
xIdlClass->getName()+ OUString::createFromAscii(" ") + ParamInfos[j].aName;<br />
else<br />
params += OUString::createFromAscii(",[") + getParamMode(ParamInfos[j].aMode)+<br />
OUString::createFromAscii("]")+<br />
xIdlClass->getName()+ OUString::createFromAscii(" ") + ParamInfos[j].aName;<br />
}<br />
}<br />
params += OUString::createFromAscii(")");<br />
OUStrs[i]= mMethods[i]->getName()+params;<br />
}<br />
return OUStrs;<br />
}<br />
</source><br />
Voir aussi les constantes UNO <idl>com.sun.star.beans.MethodConcept</idl>, et l'interface <idl>com.sun.star.beans.XIntrospection</idl>.<br />
<br />
== Obtenir toutes les interfaces ==<br />
<br />
Obtenir tous les types (ou interfaces) est un travail assez simple comme montré dans la figure ci-dessous :<br />
<br />
[[Image:XIntrospectionInterfInfo.png|center]]<br />
<br />
Jeter un oeil sur l'interface <idl>com.sun.star.lang.XTypeProvider</idl> semble aussi très utile.<br />
<br />
Le Listing 14 ci-dessous montre, parmi d'autres choses, le code C++ correspondant.<br />
<br />
== Obtenir tous les services == <br />
<br />
Obtenir tous les services est encore une tâche plus aisée avec l'interface <idl>com.sun.star.lang.XServiceInfo</idl> :<br />
<br />
[[Image:XIntrospectionServicesInfo.png|center]]<br />
<br />
Et de nouveau le Listing 14 ci-après nous montre encore une fois le code C++ correspondant.<br />
<br />
== Obtenir toutes les propriétés ==<br />
<br />
Si vous avez une bonne connaissance de Java regardez dans le SDK dans le répertoire :<br />
<OpenOffice.org1.1_SDK>/examples/java/Inspector/InstanceInspector.java<br />
et voyez le code Java correspondant.<br />
{{Documentation/Caution|Quand j'ai écrit ce chapitre j'utilisais le SDK 1.1 pour lequel l'inspecteur java avait une taille raisonnable. Maintenant [[Object Inspector|l'inspecteur]] a beaucoup évolué puisqu'il est capable de générer du code et il est donc certainement plus difficile (mais pas impossible) d'y trouver des informations utiles comme au bon vieux temps.}}<br />
<br />
Le problème de l'obtention des valeurs des propriétés est donné dans le code C++ sous forme d'une classe dans la section suivante.<br />
<br />
== Une classe complete pour l'introspection ==<br />
<br />
Avant de lire la suite, prenez le temps de consulter [[Constructing_Helpers#Presentation| Constructing Helpers section (non encore traduite)]]. Voici en attendant un exemple de code avec les interfaces <idl>com.sun.star.reflection.XIdlClass</idl>, <idl>com.sun.star.beans.XIntrospection</idl>, <idl>com.sun.star.lang.XTypeProvider</idl>, <idl>com.sun.star.lang.XServiceInfo</idl> et <idl>com.sun.star.beans.XPropertySet</idl>, avec les contantes UNO <idl>com.sun.star.beans.PropertyConcept</idl> et les énumérations UNO <idl>com.sun.star.reflection.ParamMode</idl>.<br />
<br />
<br />
<source lang="cpp"><br />
//Listing 14 Implementation of the reflection helper<br />
// C++<br />
// with help of <OpenOffice1.1_SDK>/examples/java/Inspector<br />
// and Bernard Marcelly XRay tool<br />
// version 0.1 (22 Dec 2004)<br />
// To do : Exception Handling, to go further with properties values<br />
#include "/home/smoutou/OpenOffice.org1.1_SDK/examples/DevelopersGuide/ProfUNO/CppBinding/ReflectionHelper.hpp"<br />
#include <com/sun/star/reflection/XIdlClass.hpp><br />
#include <com/sun/star/beans/PropertyConcept.hpp><br />
#include <com/sun/star/beans/XPropertySet.hpp><br />
//#include <com/sun/star/reflection/ParamMode.hpp> done in ReflectionHelper.hpp<br />
<br />
// constructor<br />
ReflectionHelper::ReflectionHelper(Any any,Reference< XMultiServiceFactory > oSVM)<br />
: toInspect(any), xServiceManager(oSVM){<br />
xIntrospection = Reference< XIntrospection >( xServiceManager->createInstance(<br />
OUString( RTL_CONSTASCII_USTRINGPARAM(<br />
"com.sun.star.beans.Introspection" ))), UNO_QUERY );<br />
xIntrospec = xIntrospection->inspect(toInspect);<br />
mMethods = xIntrospec -> getMethods(MethodConcept::ALL);<br />
xTypeProvider = Reference< XTypeProvider> (toInspect,UNO_QUERY);<br />
types = xTypeProvider->getTypes();<br />
xServiceInfo = Reference< XServiceInfo>(toInspect,UNO_QUERY);<br />
Properties = xIntrospec -> getProperties(PropertyConcept::ALL);<br />
}<br />
<br />
Sequence < OUString > ReflectionHelper::getServices() {<br />
return xServiceInfo->getSupportedServiceNames();<br />
}<br />
<br />
Sequence < OUString > ReflectionHelper::getMethods(){<br />
Sequence< OUString > methods(mMethods.getLength());<br />
for (int i=0;i<mMethods.getLength();i++){<br />
OUString params;<br />
params=OUString::createFromAscii("(");<br />
Sequence< ParamInfo > ParamInfos = mMethods[i]->getParameterInfos();<br />
if (ParamInfos.getLength() > 0) {<br />
for (int j=0;j<ParamInfos.getLength();j++){<br />
Reference< XIdlClass > xIdlClass = ParamInfos[j].aType;<br />
if (j == 0)<br />
// first parameter has no leading comma<br />
params += OUString::createFromAscii("[") + getParamMode(ParamInfos[j].aMode)+<br />
OUString::createFromAscii("]") +<br />
xIdlClass->getName()+ OUString::createFromAscii(" ") + ParamInfos[j].aName;<br />
else<br />
params += OUString::createFromAscii(",[") + getParamMode(ParamInfos[j].aMode)+<br />
OUString::createFromAscii("]")+<br />
xIdlClass->getName()+ OUString::createFromAscii(" ") + ParamInfos[j].aName;<br />
}<br />
}<br />
params += OUString::createFromAscii(")");<br />
methods[i] = mMethods[i]->getReturnType()->getName()+OUString::createFromAscii(" ")+<br />
mMethods[i]->getName()+params;<br />
}<br />
return methods;<br />
}<br />
<br />
Sequence < OUString > ReflectionHelper::getTypes(){<br />
Sequence< OUString > interfaces(types.getLength());<br />
for (int i=0;i<types.getLength();i++){<br />
interfaces[i] = types[i].getTypeName();<br />
}<br />
return interfaces;<br />
}<br />
<br />
// to improve : change all the tests with getCppuType : probably quicker than a string test<br />
OUString ReflectionHelper::getValueName(Any object){<br />
OUString OUStr;<br />
OUStr = OUString::createFromAscii("!! No computed value !!");<br />
if (object.hasValue()) {<br />
if (object.isExtractableTo(getCppuBooleanType())){<br />
sal_Bool MyBool;<br />
object >>= MyBool;<br />
return OUStr.valueOf((sal_Bool) MyBool);<br />
} else<br />
if (object.getValueTypeName() == OUString::createFromAscii("string")) {<br />
OUString *MyOUStr;<br />
MyOUStr = (OUString *) object.getValue();<br />
OUStr = OUString::createFromAscii("\"");<br />
return OUStr + *MyOUStr + OUString::createFromAscii("\"");<br />
} else<br />
if (object.getValueTypeName() == OUString::createFromAscii("long")) {<br />
sal_Int32 *MyLong;<br />
MyLong = (sal_Int32*) object.getValue();<br />
return OUStr.valueOf((sal_Int32) *MyLong);<br />
} else<br />
if (object.getValueTypeName() == OUString::createFromAscii("short")) {<br />
sal_Int16 *MyShort;<br />
MyShort = (sal_Int16*) object.getValue();<br />
return OUStr.valueOf((sal_Int32) *MyShort);<br />
} else<br />
if (object.getValueTypeName() == OUString::createFromAscii("[]byte")) {<br />
Sequence< sal_Int8 > SeqByte;<br />
object >>= SeqByte;<br />
OUStr = OUString::createFromAscii("Length:");<br />
OUStr=OUStr.concat(OUStr.valueOf((sal_Int32) SeqByte.getLength()));<br />
for (sal_Int32 i=0; i<SeqByte.getLength(); i++){<br />
OUStr=OUStr.concat(OUStr.valueOf((sal_Int32) SeqByte[i]));<br />
OUStr=OUStr.concat(OUString::createFromAscii(" "));<br />
}<br />
return OUStr;<br />
} else<br />
if (object.getValueTypeName() == OUString::createFromAscii("[]string")) {<br />
Sequence< OUString > SeqOUStr;<br />
object >>= SeqOUStr;<br />
OUStr = OUString::createFromAscii("Length:");<br />
OUStr=OUStr.concat(OUStr.valueOf((sal_Int32) SeqOUStr.getLength())+<br />
OUString::createFromAscii(" : "));<br />
for (sal_Int32 i=0; i<SeqOUStr.getLength(); i++){<br />
OUStr=OUStr.concat(OUString::createFromAscii("\"")<br />
+SeqOUStr[i]<br />
+ OUString::createFromAscii("\""));<br />
}<br />
return OUStr;<br />
} else return OUStr;<br />
} else return OUStr;<br />
}<br />
<br />
// Get properties with values : only those computed in getValueName<br />
Sequence < OUString > ReflectionHelper::getPropertiesWithValues(){<br />
Sequence< OUString > propWithVal(Properties.getLength());<br />
for (int i=0;i<Properties.getLength();i++){<br />
Type typ = getCppuType( (const Reference< XPropertySet > *)0);<br />
Reference< XPropertySet > rPropertySet(xIntrospec->queryAdapter(typ),UNO_QUERY);<br />
Reference< XPropertySetInfo > rPropertySetInfo=rPropertySet->getPropertySetInfo();<br />
Any object; if (rPropertySetInfo->hasPropertyByName(Properties[i].Name)){<br />
object <<= rPropertySet->getPropertyValue(Properties[i].Name);<br />
//if (object.hasValue()) printf("Valeur trouvee : \n");<br />
propWithVal[i] = Properties[i].Name + OUString::createFromAscii(" = (")+<br />
Properties[i].Type.getTypeName() + OUString::createFromAscii(") ")<br />
+ getValueName(object);<br />
}<br />
}<br />
return propWithVal;<br />
}<br />
<br />
// Get properties without values but types<br />
Sequence < OUString > ReflectionHelper::getPropertiesWithoutValues(){<br />
Sequence< OUString > propWithVal(Properties.getLength());<br />
for (int i=0;i<Properties.getLength();i++){<br />
Type typ = getCppuType( (const Reference< XPropertySet > *)0);<br />
Reference< XPropertySet > xPropertySet(xIntrospec->queryAdapter(typ),UNO_QUERY);<br />
Reference< XPropertySetInfo > xPropertySetInfo=xPropertySet->getPropertySetInfo();<br />
if (xPropertySetInfo->hasPropertyByName(Properties[i].Name)){<br />
propWithVal[i] = Properties[i].Name + OUString::createFromAscii(" = (")+<br />
Properties[i].Type.getTypeName() + OUString::createFromAscii(")");<br />
}<br />
}<br />
return propWithVal;<br />
}<br />
<br />
// Don't forget to add : #include <com/sun/star/reflection/ParamMode.hpp><br />
// Don't forget to add "com.sun.star.reflection.ParamMode \" in the makefile<br />
OUString ReflectionHelper::getParamMode(ParamMode paramMode) {<br />
OUString toReturn;<br />
toReturn = OUString::createFromAscii("");<br />
if (paramMode == ParamMode_IN) toReturn = OUString::createFromAscii("IN"); else<br />
if (paramMode == ParamMode_OUT) toReturn = OUString::createFromAscii("OUT"); else<br />
if (paramMode == ParamMode_INOUT) toReturn = OUString::createFromAscii("INOUT");<br />
return toReturn;<br />
}<br />
</source><br />
{{Documentation/Caution|<br />
Parcequ'il est difficile de maintenir du code plusieurs fois répété, j'ai ajouté le code complet de la [[Development/Cpp/Helper/ReflectionHelper|Classe C++ ici]]. Je ne metterai à jour désormais que cette classe et elle correspondra donc à la version la plus récente de ce code.}}<br />
Cela représente beaucoup de code. Donnons-en donc une représentation schématique pour les parties manquantes, à savoir, l'obtention des propriétés.<br />
<br />
== Représentation schématique des propriétés ==<br />
<br />
Obtenir les propriétés avec les valeurs n'est pas chose aisée. J'espère que la figure ci-dessous vous sera d'un grand secours pour comprendre le code.<br />
<br />
[[Image:PropertiesIntrospection.png]]<br />
<br />
{{Documentation/Caution|Après vérification les points d'interrogation après XInterface peuvent être retirés. Je remettrai l'image à jour un de ces jours.}}<br />
<br />
Voir aussi les interfaces <idl>com.sun.star.lang.XMultiServiceFactory</idl>, <idl>com.sun.star.beans.XIntrospection</idl>, <idl>com.sun.star.beans.XIntrospectionAccess</idl>, <idl>com.sun.star.beans.XPropertySet</idl> et <idl>com.sun.star.beans.XPropertySetInfo</idl>.<br />
<br />
{{Documentation/Caution|<br />
Ce code utilise la méthode <code>getValueName</code> pour le moment à cause des difficultés que j'ai rencontrées pour résoudre le problème d'affichage des valeurs des propriétés. Je ne pense malheureusement pas utiliser le chemin le plus simple pour résoudre cela : ce problème devrait probablement être mieux résolu en utilisant d'avantage <code>getCppuType</code> ou en cherchant une autre manière pour les types Any.}}<br />
<br />
Retour à [[Documentation/FR/Fichiers_IDL_et_C%2B%2B|Fichiers IDL et C++]]<br />
<br />
=See also=<br />
* Utiliser C++ avec le SDK OOo : [[Documentation/FR/Cpp_Guide|Page d'accueil]]<br />
* Utiliser l'[[Documentation/FR/Fichiers_IDL_et_C%2B%2B#Utilisation_de_l.27Inspecteur_Java|Inspector Java]]<br />
* 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<br />
* Bernard Marcelly's [[Extensions_development_basic#Xray_tool|XRay tool description]] in this wiki<br />
* See also [[Object Inspector|The New Object Inspector]]<br />
<br />
[[Category:FR]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/FR/Documentation/Construire_des_composantsFR/Documentation/Construire des composants2016-05-01T06:44:25Z<p>BMarcelly: /* Voir aussi */</p>
<hr />
<div>Notre propos est d'étendre OpenOffice.org d'une manière quelconque. Toutes les possibilités d'extensions ne viennent pas à l'esprit la première fois que l'on se demande si cela est possible. Mais si je vous dis qu'il suffit de réaliser une librairie partagée puis de signifier à Openoffice.org qu'il doit l'utiliser, cela ne choquera personne. Ainsi il nous faut produire une librairie avec un suffixe uno.so sous Linux ou uno.dll sous Windows. Pour indiquer à OpenOffice.org d'utiliser cette nouvelle librairie et où la trouver, un fichier rdb est nécessaire et cette opération est appelée enregistrement dans une base de registre. La base de registre a déjà été présentée [[FR/Documentation/Base_de_registres|dans un chapitre précédent]]. Vous pouvez aussi lire [[Non-code_extensions_FR#Extensions_comportant_des_services_UNO_.28code.29|cette section]] avant de commencer.<br />
=La terminologie de Danny Brewer=<br />
([http://www.oooforum.org/forum/viewtopic.php?t=13335&postdays=0&postorder=asc&start=0 voir le oooforume])<br />
<br />
Clarifions (et peut-être inventons) un peu de terminologie.<br />
<br />
# '''Add On''' : ajoute un item supplémentaire sur la barre de menu ou un icône sur la barre d'outils. En modifiant le sous-noeud de configuration pour un AddOn, vous pouvez ajouter des items nouveaux et des items sous forme d'icone. Les programmes OOoBasic peuvent modifier la configuration pour ajouter des items au menu. Il n'est pas nécessaire d'utiliser pkgchk (devenu unopkg maintenant). Les composants (voir plus loin) peuvent aussi ajouter des items sur le menu quand ils sont installés en utilisant l'outil unopkg. <br />
# '''Add In''' : Un composant (décrit plus loin dans [[Documentation/FR/Construire_des_Addins|un autre chapitre]]) qui fournit des nouvelles fonctions au tableur OOoCalc. Ces fonctions sont alors visibles dans la boîte de dialogue de l'autopilote des fonctions. Cette boîte de dialogue peut complètement décrire vos fonctions, leurs paramètres, des informations supplémentaires etc...<br />
# '''Composant''' : Un composant UNO, écrit avec n'importe lequel des langages supportés, doit être installé avec la commande pkgchk. (Ce sera "pkgchk.exe" pour les utilisateurs de Windows.) Un composant fournit un ou plusieurs services qui sont enregistrés dans la base de registres. Ces services peuvent être instanciés comme n'importe quel autre service original d'OpenOffice. Par exemple en OooBasic, vous pouvez simplement appeler createUnoService( "name.DannyBrewer.magic.SomeService" ) pour avoir une instance du service et ainsi appeler directement l'ensemble de ses méthodes. De manière similaire, Python, Java ou Visual Basic, ou n'importe quel autre langage peut utiliser le nouveau service installé.<br />
<br />
Un composant fournit un ou plusieurs services. <br />
<br />
==Service ==<br />
C'est une abstraction UNO pour un objet. Un service peut actuellement ne pas représenter un objet associé unique. Un service peut avoir différentes interfaces qu'il implémente.. Un service possède des propriétés. Quelles méthodes sont utilsables à partir d'un service sont déterminées par les interfaces qu'il implémente.<br />
<br />
Comme un Add-in de OooCalc est seulement un composant qui implante certaines interfaces et services particuliers, le add-in de Ooocalc est installé comme un autre composant. Cela signifie qu'un add-in est installé et desinstallé en utilisant unopkg.<br />
<br />
Faire un add-in pour OooCalc est comme faire un autre service. Mais il faudra lui ajouter le service particulier : com.sun.star.sheet.AddIn, et devra implanter correctement toutes ses interfaces, sachant qu'il y en a plusieurs. Mais une fois cela réalisé votre service procure de nouvelles fonctions au tableur. Les add-In de OooCalc sont abordés dans le prochain chapitre.<br />
<br />
=Chaîne de compilation d'un composant=<br />
La création d'un composant nécessite un fichier IDL décrivant ses services et interfaces et un fichier cpp contenant le code correspondant. La construction complète à partir de ces deux fichiers (et quelques autres) est complètement décrite en Figure ci-dessous. Le but final est de créer un fichier d'extension uno.so ainsi qu'un fichier rdb. Pour plus d'information sur les outils binaires utilisés dans la chaîne de compilation, lisez le chapitre correspondant du [[Documentation/DevGuide/WritingUNO/Required_Files|Developer's Guide]].<br />
<br />
[[Image:ComponentTools.png|center|thumb|800px|Chaîne de compilation d'un composant]]<br />
<br />
Les flèches noires de cette Figure indiquent comment créer un fichier à partir d'un autre et l'outil employé pour cela. Par exemple, on se sert de idlc pour créer un fichier some.urd à partir d'un fichier some.idl. Les flèches rouges indiquent que regcomp est utilisé pour placer le nom de la librairie réalisée dans le fichier rdb. Finalement les flèches bleues indiquent une dépendance.<br />
Le processus complet de construction peut être décrit comme suit :<br />
# Créer les fichiers idl et cpp. La Figure ci-dessus montre ces fichiers avec comme nom some.idl et some.cpp.<br />
# Uitiser idlc pour compiler les fichiers idl en un fichier urd.<br />
# Transformer le fichier urd en un fichier rdb en utilisant regmerge. Le fichier rdb n'est pas encore complet car il doit contenir le nom et le chemin du fichier uno.so, opération réalisée à la fin en utilisant l'outil regcomp.<br />
# Utiliser cppumaker pour créer les fichiers d'entête hpp et hdl.<br />
# Utiliser gcc pour compiler le fichier cpp.<br />
# L'enregistrement final dans la base de registre a déjà été discuté précédemment et n'est pas montré en Figure ci-dessus.<br />
<br />
Pour créer un composant vous devez d'abord créer le fichier idl correspondant. Ce fichier IDL décrit l'interface.<br />
<br />
Le but des exemples suivants est de créer un composant visible d'OpenOffice.org ou plus précisément, visible du langage de programmation OOoBasic. Le SDK contient un exemple dans le répertoire : “<OpenOffice.org_SDK>/examples/DevelopersGuide/Components/CppComponent” et décrit aussi dans le [[Documentation/DevGuide/WritingUNO/C%2B%2B/C%2B%2B_Component|Developer's Guide]].<br />
<br />
=Premier exemple : accéder à un compteur à partir du OOoBasic=<br />
Notre premier objectif est de transformer un compteur en un composant. Un compteur n'est probablement pas grandiose mais c'est idéal pour débuter. L'inspiration pour cet exemple m'est venue à partir des deux exemples du SDK :<br />
*<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/Components/CppComponent (vaguement évoqué dans la section précédente) et décrit aussi dans le [[Documentation/DevGuide/WritingUNO/C%2B%2B/C%2B%2B_Component|Developer'sGuide]].<br />
*<OpenOffice.org1.1_SDK>/examples/cpp/counter<br />
Le problème à résoudre pour le deuxième exemple, celui du compteur, est que celui-ci est inaccessible à partir du OOoBasic. Nous aimerions le rendre accessible : un composant accessible à partir de OOoBasic est appelé "scriptable" dans la terminologie des composants.<br />
<br />
Nous allons commencer par décrire l'exemple du compteur.<br />
==Un compteur tout simple==<br />
Nous désirons réaliser dans cette section deux fichiers counter.cxx et countermain.cxx travaillant ensembles. Notez au passage que cet exemple serait bien plus simple s'il n'était pas destiné à travailler avec OpenOffice.org. Il nous intéresse parce qu'il est simple et nous servira de point de départ. A partir de là, nous nous poserons un tas de questions et leurs réponses nous montreront, je l'espère, comment les composants fonctionnent. J'utiliserai de temps à autre les notations UML dans ce chapitre.<br />
===Implantation en un seul fichier=== <br />
Nous commençons par le code de notre fameux compteur implantée en un seul fichier (sans compter le fichier d'inclusion) et par la même occasion complètement indépendant d'OpenOffice.org :<br />
<source lang="cpp"><br />
//Listing 1 Le compteur<br />
//c++<br />
//la classe et son utilisation dans un seul fichier<br />
#include <stdio.h><br />
#include "counter.hxx"<br />
<br />
MyCounterImpl::MyCounterImpl()<br />
: m_nCount( 0 )<br />
{ printf( "< MyCounterImpl ctor called >\n" ); }<br />
MyCounterImpl::~MyCounterImpl()<br />
{ printf( "< MyCounterImpl dtor called >\n" ); }<br />
int MyCounterImpl::getCount() <br />
{ return m_nCount; }<br />
void MyCounterImpl::setCount( int nCount ) <br />
{ m_nCount = nCount; }<br />
int MyCounterImpl::increment() <br />
{ return (++m_nCount); }<br />
int MyCounterImpl::decrement() <br />
{ return (--m_nCount); }<br />
<br />
int main(int argc, char **argv)<br />
{<br />
MyCounterImpl Cnt;<br />
Cnt.setCount(50);<br />
printf("-- %d\n",Cnt.getCount());<br />
Cnt.increment();<br />
printf("-- %d\n",Cnt.getCount());<br />
Cnt.decrement();<br />
printf("-- %d\n",Cnt.getCount());<br />
return 0;<br />
}<br />
</source><br />
et son fichier d'entête associé<br />
<source lang="cpp"><br />
//Listing 2 Fichier d'entête du compteur<br />
// C++<br />
// counter.hxx<br />
class MyCounterImpl {<br />
int m_nCount;<br />
public:<br />
MyCounterImpl();<br />
~MyCounterImpl();<br />
int getCount();<br />
void setCount( int nCount ); <br />
int increment(); <br />
int decrement() ;<br />
};<br />
</source><br />
Ce que nous voulons réaliser est la séparation du code en deux parties une pour la classe compteur ( counter.cxx) et la seconde pour l'utilisation de la classe ( countermain.cxx). Le fichier counter.cxx sera compilé en une librairie dynamique (fichier counter.so) et countermain utilisera cette librairie dynamique.<br />
===Implantation en deux fichiers===<br />
La façon classique de faire cela en C++ est illustrée à présent. Commençons par la librairie dynamique :<br />
<source lang="cpp"><br />
//Listing 3 Code C++ de la librairie dynamique<br />
//c++<br />
//counter.cxx<br />
#include <stdio.h><br />
#include "counter.hxx"<br />
<br />
MyCounterImpl::MyCounterImpl()<br />
: m_nCount( 0 )<br />
{ printf( "< MyCounterImpl ctor called >\n" ); }<br />
MyCounterImpl::~MyCounterImpl()<br />
{ printf( "< MyCounterImpl dtor called >\n" ); }<br />
int MyCounterImpl::getCount() <br />
{ return m_nCount; }<br />
void MyCounterImpl::setCount( int nCount ) <br />
{ m_nCount = nCount; }<br />
int MyCounterImpl::increment() <br />
{ return (++m_nCount); }<br />
int MyCounterImpl::decrement() <br />
{ return (--m_nCount); }<br />
</source><br />
Ce fichier est compilé à l'aide de la ligne de commande :<br />
<pre><br />
gcc -shared -fPIC -o counter.so counter.cxx<br />
</pre><br />
pour donner la librairie dynamique "counter.so".<br />
<br />
Pour utiliser ce cette librairie il nous faut un programme principal :<br />
<source lang="cpp"><br />
//Listing 4 Programme principal<br />
//c++<br />
//countermain.cxx<br />
#include "counter.hxx"<br />
#include <stdio.h><br />
int main(int argc, char **argv)<br />
{<br />
MyCounterImpl Cnt;<br />
Cnt.setCount(50);<br />
printf("-- %d\n",Cnt.getCount());<br />
Cnt.increment();<br />
printf("-- %d\n",Cnt.getCount());<br />
Cnt.decrement();<br />
printf("-- %d\n",Cnt.getCount());<br />
return 0;<br />
}<br />
</source><br />
La compilation est réalisée avec la ligne de commande :<br />
<pre><br />
gcc -o test1 countermain.cxx -L ./ counter.so -lstdc++<br />
</pre><br />
L'exécution de cet exemple nous donne à l'écran :<br />
<pre><br />
[smoutou@p3 component]$ ./test1<br />
< MyCounterImpl ctor called ><br />
-- 50<br />
-- 51<br />
-- 50<br />
< MyCounterImpl dtor called ><br />
</pre><br />
Une commande ldd nous montre clairement que ce code a besoin de counter.so :<br />
<pre> <br />
[smoutou@p3 component]$ ldd test1<br />
counter.so => ./counter.so (0x40015000)<br />
libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40024000)<br />
libc.so.6 => /lib/i686/libc.so.6 (0x400dd000)<br />
libm.so.6 => /lib/i686/libm.so.6 (0x4020e000)<br />
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x40231000)<br />
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)<br />
</pre><br />
Cet exemple est réalisé de manière classique, c'est à dire qu'il n'utilise aucune librairie de OpenOffice.org. Au contraire, l'exemple donné avec le SDK fait exactement la même chose mais nécessite OpenOffice.org ou en tout cas sa [[Documentation/FR/Base_de_registres|base de registre]].<br />
<br />
==Transformer le compteur pour qu'il puisse être enregistré ==<br />
Toute les librairies dynamiques ne peuvent pas forcément être enregistrées dans la base de registre d'OpenOffice. Si nous prenons celle que nous avons construit dans la section précédente et essayons de l'enregistrer, regardons ce qui se passe :<br />
<pre><br />
[smoutou@p3 bin]$ regcomp -register -r counter.uno.rdb -c counter.so<br />
Aborted<br />
</pre><br />
Regcomp est complètement incapable de faire son travail correctement Pourquoi ?<br />
<br />
Si l'on veut qu'une librairie dynamique puisse être enregistrée, il nous faut suivre des règles très strictes.<br />
<br />
'''Règle 1''' :Il vous faut construire un [[Documentation/DevGuide/WritingUNO/Using_UNOIDL_to_Specify_New_Components|fichier IDL]]. Ce fichier IDL vous permet de construire un fichier urd que l'on pourra ajouter dans un fichier rdb. Cela a déjà été discuté [[Documentation/FR/Construire_des_composants#Cha.C3.AEne_de_compilation_d.27un_composant|rapidement ici]]. Cette démarche a été réalisée en fait lors de notre premier essai d'enregistrement à l'aide de regcomp mais l'erreur qui en a resulté nous montre que cette règle ne suffit pas à elle seule.<br />
<br />
Regardez la figure ci-dessous qui est une illustration de cette règle 1.<br />
<br />
[[Image:Registery.png]]<br />
<br />
En l'examinant de plus près vous voyez qu'un fichier some.idl est requis (et naturellement le fichier uno.so correspondant).<br />
<br />
'''Règle 2''' : Votre librairie dynamique doit contenir obligatoirement trois sous programmes (au format du langage C). Leur noms et prototypes sont :<br />
<source lang="cpp"><br />
extern "C" void SAL_CALL component_getImplementationEnvironment(<br />
sal_Char const ** ppEnvTypeName, uno_Environment ** ppEnv );<br />
<br />
extern "C" sal_Bool SAL_CALL component_writeInfo(<br />
lang::XMultiServiceFactory * xMgr, registry::XRegistryKey * xRegistry );<br />
<br />
extern "C" void * SAL_CALL component_getFactory(<br />
sal_Char const * implName, lang::XMultiServiceFactory * xMgr, void * );<br />
</source><br />
Les deux premiers sous-programmes sont nécessaires pour l'enregistrement et le troisième pour permettre les appels UNO_QUERY.<br />
<br />
'''Règle 3 (règle provisoire)''' : Votre composant doit contenir d'autres interfaces que celles décrite dans votre fichier IDL : XInterface, XServiceInfo. L'exemple original du compteur les implémente effectivement comme cela est montré dans le listing suivant :<br />
<source lang="cpp"><br />
//Listing 6 Les interfaces du compteur<br />
// C++<br />
class MyCounterImpl<br />
: public XCountable<br />
, public XServiceInfo<br />
{<br />
....<br />
</source><br />
Je suppose que XCountable hérite de l'interface <idl>com.sun.star.uno.XInterface</idl>. (à vérifier tout cela) Il vous faut aussi regarder l'interface <idl>com.sun.star.lang.XServiceInfo</idl>.<br />
La figure ci-dessous nous montre un composant à l'aide d'une vue schématique.<br />
<br />
[[Image:ComponentInterface.png]]<br />
<br />
Le rectangle externe du bas de la Figure ci-dessus represente le composant. Dans ce composant, nous voyons notre classe Myclass héritant des interfaces XInterface, XServiceInfo et XCountable, ainsi que les trois procédures C pouvant être appelée de l'extérieur. Ce schéma indique que toutes les méthodes virtuelles des classes héritées sont à écrire (dix en tout pour cet exemple).<br />
<br />
La règle 3 définitive [[Documentation/FR/Construire_des_composants#Utilisation_d.27une_aide_.28helper.29_pour_construire_le_composant_scriptable|est présentée plus loin]], mais vous n'avez aucune raison de vous impatienter. Sinon, vous pouvez aussi lire le [[Documentation/DevGuide/WritingUNO/Core_Interfaces_to_Implement|Developer's Guide]] à ce sujet.<br />
<br />
==L'exemple du compteur du SDK==<br />
Cet exemple du SDK est partiellement [[Counter_Example|décrit ici en anglais]]. Il contient deux fichiers : counter.cxx et countermain.cxx. Ces fichiers montrent quelques différences par rapport aux Listing 3 et Listing 4 donnés précédemment parce qu'ils sont liés à OpenOffice.org maintenant, donc plus complexes : countermain.cxx sera responsable de l'enregistrement de "counter.uno.so" et counter.cxx devra implanter toutes les interfaces de la règle 3 provisoire. Ce petit exemple utilise donc une librairie externe enregistrée (counter.uno.so construit à partir counter.cxx) et un programme principal (countermain.cxx) qui l'utilise. <br />
<br />
Le compteur généré (comme l'exemple ProfUnoLifeTime du SDK) est capable de s'exécuter même si OpenOffice ne tourne pas. Cela nous indique que ce compteur est un composant minimal (qui n'a rien à faire avec le service manager).<br />
MainCounter est le programme binaire à lancer pour le test de l'exemple. Il n'y a pas de flèche directe entre MainCounter et Counter.uno.so (dans la chaîne de compilation de la Figure ci-dessous), cela indique qu'ils sont indépendants l'un de l'autre : si MainCounter veut quelque chose de Counter.uno.so, il doit le demander au cppuhelper (en d'autre mots à Openoffice). Cet exemple a été déjà réalisé sans le cppuhelper [[Documentation/FR/Construire_des_composants#Implantation_en_deux_fichiers|ci-dessus]], mais notre intention est justement de montrer l'utilisation du cppuhelper dans cette situation spécifique.<br />
<br />
[[Image:MakefileCounterEx.png|center|thumb|600px|Chaîne de compilation du compteur]]<br />
<br />
La chaîne de compilation pour cet exemple (voir Figure ci-dessus) est un peu plus compliquée que précédemment à cause des deux fichiers sources : counter.cxx et countermain.cxx. A noter comme cela a déjà été dit que nous avons à créer un troisième fichier pour cet exemple : Counter.idl. Le contenu de ce fichier IDL est maintenant compréhensible par un lecteur qui a étudié scrupuleusement le [[Documentation/FR/Fichiers_IDL_et_C%2B%2B|chapitre sur les fichiers IDL]] :<br />
<source lang="cpp"><br />
//Listing 6 The IDL Counter File : Counter.idl<br />
// IDL<br />
#include <com/sun/star/uno/XInterface.idl><br />
<br />
module foo<br />
{<br />
/**<br />
* Interface to count things. <br />
*/<br />
interface XCountable : com::sun::star::uno::XInterface<br />
{<br />
long getCount();<br />
void setCount( [in] long nCount );<br />
long increment();<br />
long decrement();<br />
};<br />
<br />
service Counter<br />
{<br />
// exported interface:<br />
interface XCountable;<br />
};<br />
};<br />
</source><br />
Ce fichier IDL décrit l'interface de counter.cxx qui deviendra counter.uno.so (counter.uno.dll sous Windows), un fichier librairie dynamique après compilation. Mais de nouveau vous appelez une des quatre méthodes non pas directement mais à travers cppuhelper.<br />
Ce fichier IDL est représenté en Figure ci-dessous.<br />
<br />
[[Image:ServiceCounter.png|center|thumb|600px|Service et Interface du compteur]]<br />
<br />
==Modification du Compteur simple pour examiner l'enregistrement==<br />
Encore une fois nous partons de l'exemple du compteur inclus dans le SDK et dans le répertoire <OpenOffice.org1.1_SDK>/examples/cpp/counter.<br />
Nous le modifions pour voir dans la console un certain nombre d'informations sur la manière dont l'enregistrement travaille et particulièrement la nécessité de la règle 2 décrite dans la [[FR/Documentation/Construire_des_composants#Transformer_le_compteur_pour_qu.27il_puisse_.C3.AAtre_enregistr.C3.A9|section ci-avant]]. Les modifications consistent seulement à ajouter des printf comme montré dans le listing ci-dessous :<br />
<source lang="cpp"><br />
//Listing 7 Modified Counter Component (extract)<br />
// C++<br />
.....<br />
<br />
//*************************************************************************<br />
OUString SAL_CALL MyCounterImpl::getImplementationName( )<br />
throw(RuntimeException)<br />
{<br />
printf("MyCounterImpl::getImplementationName( ) called \n");<br />
return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) );<br />
}<br />
//*************************************************************************<br />
sal_Bool SAL_CALL MyCounterImpl::supportsService( const OUString& ServiceName )<br />
throw(RuntimeException)<br />
{<br />
printf("MyCounterImpl::supportsService called\n");<br />
Sequence< OUString > aSNL = getSupportedServiceNames();<br />
const OUString * pArray = aSNL.getArray();<br />
for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )<br />
if( pArray[i] == ServiceName )<br />
return sal_True;<br />
return sal_False;<br />
} <br />
<br />
//*************************************************************************<br />
Sequence<OUString> SAL_CALL MyCounterImpl::getSupportedServiceNames( )<br />
throw(RuntimeException)<br />
{<br />
printf("MyCounterImpl::getSupportedServiceNames( ) called \n");<br />
return getSupportedServiceNames_Static();<br />
}<br />
<br />
//*************************************************************************<br />
Sequence<OUString> SAL_CALL MyCounterImpl::getSupportedServiceNames_Static( )<br />
{<br />
OUString aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) );<br />
printf("MyCounterImpl::getSupportedServiceNames_Static( ) called with %s\n",RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));<br />
return Sequence< OUString >( &aName, 1 );<br />
}<br />
<br />
/**<br />
* Function to create a new component instance; is needed by factory helper implementation.<br />
* @param xMgr service manager to if the components needs other component instances<br />
*/<br />
Reference< XInterface > SAL_CALL MyCounterImpl_create(<br />
const Reference< XMultiServiceFactory > & xMgr )<br />
{ printf("MyCounterImpl_create called\n");<br />
return Reference< XCountable >( new MyCounterImpl( xMgr ) );<br />
}<br />
<br />
//#####################################################################################<br />
//#### EXPORTED ####################################################################################<br />
//######################################################################################<br />
/**<br />
* Gives the environment this component belongs to.<br />
*/<br />
extern "C" void SAL_CALL component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv)<br />
{<br />
printf("getImplementationEnvironnement return %s\n",CPPU_CURRENT_LANGUAGE_BINDING_NAME);<br />
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;<br />
}<br />
<br />
/**<br />
* This function creates an implementation section in the registry and another subkey<br />
*<br />
* for each supported service.<br />
* @param pServiceManager the service manager<br />
* @param pRegistryKey the registry key<br />
*/<br />
extern "C" sal_Bool SAL_CALL component_writeInfo(void * pServiceManager, void * pRegistryKey)<br />
{<br />
sal_Bool result = sal_False;<br />
printf("component_writeInfo called\n");<br />
if (pRegistryKey)<br />
{<br />
try<br />
{<br />
Reference< XRegistryKey > xNewKey(<br />
reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey(<br />
OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME "/UNO/SERVICES") ) ) );<br />
printf("New key : %s\n",RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME "/UNO/SERVICES"));<br />
printf("--component_writeInfo calls MyCounterImpl::getSupportedServiceNames_Static()\n");<br />
const Sequence< OUString > & rSNL =<br />
MyCounterImpl::getSupportedServiceNames_Static();<br />
const OUString * pArray = rSNL.getConstArray();<br />
for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) {<br />
xNewKey->createKey( pArray[nPos] );<br />
printf("----Sous-Key : %s build\n",OUStringToOString(pArray[nPos],<br />
RTL_TEXTENCODING_ASCII_US)<br />
.pData->buffer);<br />
}<br />
return sal_True;<br />
}<br />
catch (InvalidRegistryException &)<br />
{<br />
// we should not ignore exceptions<br />
}<br />
}<br />
return result;<br />
}<br />
<br />
/**<br />
* This function is called to get service factories for an implementation.<br />
*<br />
* @param pImplName name of implementation<br />
* @param pServiceManager a service manager, need for component creation<br />
* @param pRegistryKey the registry key for this component, need for persistent data<br />
* @return a component factory<br />
*/<br />
/**/<br />
extern "C" void * SAL_CALL component_getFactory(const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey)<br />
{<br />
void * pRet = 0;<br />
printf("component_getFactory called\n");<br />
if (rtl_str_compare( pImplName, IMPLNAME ) == 0)<br />
{<br />
Reference< XSingleServiceFactory > xFactory( createSingleFactory(<br />
reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),<br />
OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ),<br />
MyCounterImpl_create,<br />
MyCounterImpl::getSupportedServiceNames_Static() ) );<br />
<br />
if (xFactory.is())<br />
{<br />
xFactory->acquire();<br />
pRet = xFactory.get();<br />
}<br />
}<br />
return pRet;<br />
}<br />
</source><br />
Avec countermain légèrement modifié pour savoir à partir de quand l'écriture dans la base de registre commence, cette pièce de code produit la sortie suivante :<br />
<pre><br />
[smoutou@p3 counter]$ make countermain.run<br />
cd ../../../LINUXexample.out/bin && countermain<br />
Here begin registry<br />
getImplementationEnvironnement return gcc3<br />
component_writeInfo called<br />
New key : /com.sun.star.comp.example.cpp.Counter/UNO/SERVICES<br />
--component_writeInfo calls MyCounterImpl::getSupportedServiceNames_Static()<br />
MyCounterImpl::getSupportedServiceNames_Static( ) called with foo.Counter<br />
----Sous-Key : foo.Counter build<br />
Here ends registry and begin instanciation<br />
getImplementationEnvironnement return gcc3<br />
component_getFactory called<br />
MyCounterImpl::getSupportedServiceNames_Static( ) called with foo.Counter<br />
MyCounterImpl_create called<br />
< MyCounterImpl2 ctor called ><br />
42,43,42<br />
Another registry use : getImplementations<br />
-- com.sun.star.comp.bridge.UnoUrlResolver<br />
< MyCounterImpl2 dtor called ><br />
[smoutou@p3 counter]$<br />
</pre><br />
tandis qu'une utilisation directe de regcomp produit la sortie suivante :<br />
<pre><br />
[smoutou@p3 bin]$ regcomp -register -r counter.uno.rdb -c counter.uno.so<br />
getImplementationEnvironnement return gcc3<br />
component_writeInfo called<br />
New key : /com.sun.star.comp.example.cpp.Counter/UNO/SERVICES<br />
--component_writeInfo calls MyCounterImpl::getSupportedServiceNames_Static()<br />
MyCounterImpl::getSupportedServiceNames_Static( ) called with foo.Counter<br />
----Sous-Key : foo.Counter build<br />
register component 'counter.uno.so' in registry 'counter.uno.rdb' succesful!<br />
[smoutou@p3 bin]$<br />
</pre><br />
Nous pouvons tirer des deux sorties consoles que l'enregistrement travaille de la façon attendue. Le premier appel demande des renseignements sur l'environnement qui retourne ici “gcc3”, et ensuite componentwriteinfo qui est responsable de l'enregistrement lui-même.<br />
<br />
===Résultats===<br />
Une question : comment est perçu notre compteur par OOoBasic à cette étape ? Parce que notre compteur est enregistré nous le voyons partiellement, mais nous ne pouvons en aucun cas l'utiliser.<br />
<br />
<source lang="oobas"><br />
'Listing 8 Petit OOoBasic programme pour voir notre compteur<br />
REM ***** BASIC *****<br />
Sub Main<br />
ocmpt = createUnoService("foo.Counter")<br />
XRay oCmpt<br />
End Sub<br />
</source><br />
En utilisant l'outil [[Extensions_development_basic#X-Ray_tool|XRay]] sur cet objet comme montré dans le listing ci-dessus, cela nous donne les informations suivantes :<br />
<br />
'''properties<br />
<pre><br />
--- Object internal name : ( no name )<br />
Dbg_Methods <br />
string <...> basic prop, read-only<br />
Dbg_Properties <br />
string <...> basic prop, read-only<br />
Dbg_SupportedInterfaces<br />
string <...> basic prop, read-only<br />
</pre><br />
'''methods<br />
<pre><br />
--- Object internal name : ( no name )<br />
queryInterface ( aType as type ) AS variant<br />
acquire ( )<br />
release ( )<br />
</pre><br />
'''supported interfaces<br />
<pre><br />
--- List of supported interfaces ---<br />
com.sun.star.uno.XInterface<br />
</pre><br />
<br />
Comme on peut le voir ci-dessus, seule l'interface <idl>com.sun.star.uno.XInterface</idl> peut être vue : pas grandiose ! On peut ainsi l'instancier mais on ne pourra pas appeler une de ses méthodes. L'étape suivante est de pouvoir utiliser le compteur avec OOoBasic : en d'autre mots de le rendre scriptable.<br />
<br />
==Utilisation d'une aide (helper) pour construire le composant scriptable==<br />
Nous pouvons trouver un document [[Uno/Cpp/Tutorials/component_tutorial|décrivant cet exemple]] (de Daniel Bölzle) mais que je n'ai pas réussi à faire fonctionner. Je vais donc construire ce composant moi-même.<br />
<br />
Les règles 1 et 2 sont [[FR/Documentation/Construire_des_composants#Transformer_le_compteur_pour_qu.27il_puisse_.C3.AAtre_enregistr.C3.A9|expliquées ici]].<br />
<br />
Si vous voulez rendre votre composant scriptable il vous faut modifier la règle 3 provisoire précédente comme suit :<br />
<br />
'''Règle 3 (définitive)''' : Votre composant doit fournir les interfaces : <idl>com.sun.star.uno.XInterface</idl>, <idl>com.sun.star.lang.XServiceInfo</idl>, <idl>com.sun.star.uno.XWeak</idl>, et <idl>com.sun.star.lang.XTypeProvider</idl>. La dernière est absolument caractéristique d'un composant scriptable. Voir aussi le [[Documentation/DevGuide/WritingUNO/Core_Interfaces_to_Implement|Developer's Guide]] à ce sujet. <br />
<br />
La Figure ci-après nous montre la version définitive d'un composant "scriptable". <br />
<br />
[[Image:ScripComponent.png|center|thumb|600px|Un composant scriptable]]<br />
<br />
Vous voyez que la classe que vous avez à implanter hérite de certaines interfaces : toutes les méthodes de ces interfaces se trouvent dans votre composant et il vous faut donc les implanter. Comme il sera montré plus loin, nous utilisons une aide (helper en anglais que je ne sais pas traduire) et cela signifie que nous n'aurons pas à implémenter nous-même toutes ces méthodes : seules celles de l'interface <idl>com.sun.star.lang.XServiceInfo</idl> est nécessaire : les trois autres sont implémentées automatiquement avec l'aide (helper) comme c'est indiqué dans [[Documentation/DevGuide/WritingUNO/Core_Interfaces_to_Implement|cette page du Developer's Guide]].<br />
<br />
Donnons pour conclure, notre schéma définitif de l'implantation avec Helper :<br />
<br />
[[Image:ScripComponentWithHelper.png|center|thumb|600px|Un composant scriptable avec Helper]]<br />
<br />
'''Règle 4''' : Vous voyez deux interfaces sur le figure ci-dessus, alors vous aurez à utiliser "::cppu::WeakImplHelper2" quand vous allez définir votre classe.<br />
<br />
Que dire de notre makefile ? Nous ne sommes plus vraiment intéressé par appeler notre compteur par countermain.cxx mais plutôt par l'utilisation de celui-ci dans OooBasic, ce qui signifie que nous devons enregistrer notre librairie dynamique à l'aide de notre Makefile et non plus à l'aide de "countermain.cxx". Deux solutions s'offrent à nous : <br />
#nous laissons encore countermain réaliser l'enregistrement et nous stoppons ce programme juste après cet enregistrement ce qui nous laisse le temps d'utiliser un programme OOoBasic, <br />
#nous cherchons un exemple du SDK qui réalise correctement l'enregistrement. On peut en trouver un dans le SDK comme mentionné plus haut :<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/Components/CppComponent<br />
et ainsi nous pouvons utiliser le makefile de ce composant. <br />
<br />
{{Documentation/Caution|Pour mon premier essai j'ai tenté d'utiliser la première solution mais elle ne fonctionne pas correctement : il y a probablement un problème avec la base de registre. Si un second programme gère l'enregistrement, cela ne fonctionne pas. Il doit y avoir un autre problème mais je n'ai pas poussé mais investigations plus loin. Cela fonctionne en utilisant le makefile de CppComponent en renommant le fichier IDL et le fichier cxx du MakeFile.<br />
A faire : résoudre le problème précédent sur l'enregistrement !!! En fait je pense que l'enregistrement réalisé par countermain n'est pas correct pour retrouver le service manager. Enquête à suivre.}}<br />
Pour le moment je vais donc expliquer la méthode à suivre à partir de l'exemple CppComponent du SDK.<br />
<br />
==Comment faire fonctionner nos exemples==<br />
Si vous voulez faire fonctionner l'exemple du compteur et tous les autres du chapitre suivant, le mieux est de partir du répertoire<br />
<br />
<OOo_SDK>/examples/DevelopersGuide/Component/CppComponent<br />
<br />
et de le copier entièrement en<br />
<br />
<OOo_SDK>/examples/DevelopersGuide/Component/MyComponent<br />
<br />
par exemple. Le point important étant qu'il ait la même profondeur sans quoi il y aurait un peu plus de changement à réaliser dans le Makefile, changements indiqués plus loin.<br />
<br />
===Fichier CppComponent.uno.xml===<br />
Dans votre répertoire <OOo_SDK>/examples/DevelopersGuide/Component/MyComponent nouvellement créé, vous pouvez voir un fichier CppComponent.uno.xml Ouvrez-le et remplacer<br />
<type>my_module.XSomething</type><br />
<type>my_module.MyService1</type><br />
<type>my_module.MyService2</type><br />
par<br />
<type>foo.XCountable</type><br />
<type>foo.Counter</type><br />
<br />
===Fichier Makefile===<br />
<br />
Dans le Makefile original<br />
remplacer<br />
<pre> <br />
IDLFILES = some.idl<br />
</pre><br />
par<br />
<pre><br />
IDLFILES = Counter.idl<br />
</pre><br />
et remplacer aussi<br />
<pre><br />
CXXFILES = service1_impl.cxx \<br />
service2_impl.cxx<br />
</pre><br />
par<br />
<pre><br />
CXXFILES = service_impl.Last.OK.cxx <br />
# service2_impl.cxx<br />
</pre><br />
où vous adapterez le nom de votre fichier source.<br />
<br />
===Fichier source IDL===<br />
Pour accéder au compteur en Basic, vous devez utiliser le même fichier IDL que dans le [[FR/Documentation/Construire_des_composants#L.27exemple_du_compteur|Listing 2]].<br />
<br />
===Fichier source compteur===<br />
Nous donnons maintenant le programme complet du compteur.<br />
<br />
<source lang="cpp"><br />
//Listing 9 Programme complet du compteur<br />
// C++<br />
// service_impl.Last.OK.cxx<br />
#ifndef _RTL_USTRING_HXX_<br />
#include <rtl/ustring.hxx><br />
#endif<br />
<br />
#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_<br />
#include <cppuhelper/queryinterface.hxx> // helper for queryInterface() impl<br />
#endif<br />
#ifndef _CPPUHELPER_FACTORY_HXX_<br />
#include <cppuhelper/factory.hxx> // helper for component factory<br />
#endif<br />
// New<br />
#include <cppuhelper/implbase2.hxx> // "2" implementing two interfaces<br />
#include <cppuhelper/implementationentry.hxx><br />
<br />
// generated c++ interfaces<br />
#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_<br />
#include <com/sun/star/lang/XSingleServiceFactory.hpp><br />
#endif<br />
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_<br />
#include <com/sun/star/lang/XMultiServiceFactory.hpp><br />
#endif<br />
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_<br />
#include <com/sun/star/lang/XServiceInfo.hpp><br />
#endif<br />
#ifndef _COM_SUN_STAR_REGISTRY_XREGISTRYKEY_HPP_<br />
#include <com/sun/star/registry/XRegistryKey.hpp><br />
#endif<br />
#ifndef _FOO_XCOUNTABLE_HPP_<br />
#include <foo/XCountable.hpp><br />
#endif<br />
<br />
#define SERVICENAME "foo.Counter"<br />
#define IMPLNAME "com.sun.star.comp.example.cpp.Counter"<br />
<br />
namespace my_sc_impl<br />
{<br />
static Sequence< OUString > getSupportedServiceNames_MyCounterImpl()<br />
{<br />
static Sequence < OUString > *pNames = 0;<br />
if( ! pNames )<br />
{<br />
// MutexGuard guard( Mutex::getGlobalMutex() );<br />
if( !pNames )<br />
{<br />
static Sequence< OUString > seqNames(1);<br />
seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));<br />
pNames = &seqNames;<br />
}<br />
}<br />
return *pNames;<br />
}<br />
<br />
static OUString getImplementationName_MyCounterImpl()<br />
{<br />
static OUString *pImplName = 0;<br />
if( ! pImplName )<br />
{<br />
// MutexGuard guard( Mutex::getGlobalMutex() );<br />
if( ! pImplName )<br />
{<br />
static OUString implName( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) );<br />
pImplName = &implName;<br />
}<br />
}<br />
return *pImplName;<br />
}<br />
<br />
// New<br />
class MyCounterImpl : public ::cppu::WeakImplHelper2<<br />
XCountable, XServiceInfo ><br />
{<br />
// to obtain other services if needed<br />
Reference< XMultiServiceFactory > m_xServiceManager;<br />
sal_Int32 m_nCount;<br />
<br />
public:<br />
// XServiceInfo implementation<br />
virtual OUString SAL_CALL getImplementationName( ) throw(RuntimeException);<br />
virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException);<br />
virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(RuntimeException);<br />
static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static( );<br />
<br />
// XCountable implementation<br />
virtual sal_Int32 SAL_CALL getCount() throw (RuntimeException)<br />
{ return m_nCount; }<br />
virtual void SAL_CALL setCount( sal_Int32 nCount ) throw (RuntimeException)<br />
{ m_nCount = nCount; }<br />
virtual sal_Int32 SAL_CALL increment() throw (RuntimeException)<br />
{ return (++m_nCount); }<br />
virtual sal_Int32 SAL_CALL decrement() throw (RuntimeException)<br />
{ return (--m_nCount); }<br />
};<br />
<br />
//*************************************************************************<br />
OUString SAL_CALL MyCounterImpl::getImplementationName( )<br />
throw(RuntimeException)<br />
{<br />
return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) );<br />
}<br />
<br />
//*************************************************************************<br />
sal_Bool SAL_CALL MyCounterImpl::supportsService( const OUString& ServiceName )<br />
throw(RuntimeException)<br />
{<br />
Sequence< OUString > aSNL = getSupportedServiceNames();<br />
const OUString * pArray = aSNL.getArray();<br />
for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )<br />
if( pArray[i] == ServiceName )<br />
return sal_True;<br />
return sal_False;<br />
} <br />
<br />
//*************************************************************************<br />
Sequence<OUString> SAL_CALL MyCounterImpl::getSupportedServiceNames( )<br />
throw(RuntimeException)<br />
{<br />
return getSupportedServiceNames_Static();<br />
}<br />
<br />
//*************************************************************************<br />
Sequence<OUString> SAL_CALL MyCounterImpl::getSupportedServiceNames_Static( )<br />
{<br />
OUString aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) );<br />
return Sequence< OUString >( &aName, 1 );<br />
}<br />
<br />
//***********NEW<br />
Reference< XInterface > SAL_CALL MyCounterImpl_create(<br />
Reference< XComponentContext > const & xContext )<br />
SAL_THROW( () )<br />
{<br />
return static_cast< XTypeProvider * >( new MyCounterImpl() );<br />
}<br />
<br />
}<br />
//##################################################################################################<br />
//#### EXPORTED ####################################################################################<br />
<br />
/* shared lib exports implemented without helpers in service_impl1.cxx */<br />
namespace my_sc_impl<br />
{<br />
static struct ::cppu::ImplementationEntry s_component_entries [] =<br />
{<br />
{<br />
MyCounterImpl_create, getImplementationName_MyCounterImpl,<br />
getSupportedServiceNames_MyCounterImpl, ::cppu::createSingleComponentFactory,<br />
0, 0<br />
},<br />
{ 0, 0, 0, 0, 0, 0 }<br />
};<br />
}<br />
<br />
extern "C"<br />
{<br />
void SAL_CALL component_getImplementationEnvironment(<br />
sal_Char const ** ppEnvTypeName, uno_Environment ** ppEnv )<br />
{<br />
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;<br />
}<br />
sal_Bool SAL_CALL component_writeInfo(<br />
XMultiServiceFactory * xMgr, XRegistryKey * xRegistry )<br />
{<br />
return ::cppu::component_writeInfoHelper(<br />
xMgr, xRegistry, ::my_sc_impl::s_component_entries );<br />
}<br />
void * SAL_CALL component_getFactory(<br />
sal_Char const * implName, XMultiServiceFactory * xMgr,<br />
XRegistryKey * xRegistry )<br />
{<br />
return ::cppu::component_getFactoryHelper(<br />
implName, xMgr, xRegistry, ::my_sc_impl::s_component_entries );<br />
}<br />
}<br />
</source><br />
Voila, nous sommes prêts pour les tests maintenant.<br />
<br />
===Fichier TestCppComponent.cxx===<br />
Dans votre répertoire vous aves un fichier appelé '''TestCppComponent.cxx''' qu'il vous faut modifier car celui-ci est compilé pour un autre exemple que le votre. Le meilleur moyen est de mettre en commentaire tout le contenu du main. A ce moment là votre test du compteur ne pourra pas se faire avec la commande :<br />
<pre><br />
make TestCppComponent.run<br />
</pre><br />
mais seulement par<br />
<pre><br />
make SimpleComponent.odt.load<br />
</pre><br />
et vous modifiez le programme OOoBasic du document SimpleComponent.odt comme indiqué ci-après. Nous apprendrons à appeler notre compteur à partir du langage C++ un peu plus tard.<br />
<br />
===Fichier OOoBasic de test===<br />
Le programme OOoBasic pour tester cet exemple est maintenant :<br />
<br />
<source lang='oobas'><br />
'Listing 10 Programme OOoBasic de test<br />
REM ***** BASIC *****<br />
<br />
Sub Main<br />
Dim oSimpleComponent<br />
oSimpleComponent = CreateUnoService( "foo.Counter" )<br />
oSimpleComponent.setCount(5)<br />
print oSimpleComponent.getCount()<br />
oSimpleComponent.increment()<br />
print oSimpleComponent.getCount()<br />
'XRay oSimpleComponent<br />
End Sub<br />
</source><br />
Ce programme de test peut être écrit dans SimpleComponent.odt and lancé avec le bouton fait pour cela. Tout cela se fait avec un <pre>make SimpleComponent.oxt.load</pre><br />
Une introspection avec [[Extensions_development_basic#X-Ray_tool|XRay]] du nouveau service créé nous montre maintenant :<br />
<br />
'''properties<br />
<pre><br />
--- Object internal name : com.sun.star.comp.example.cpp.Counter<br />
Count long <br />
ImplementationName string <br />
SupportedServiceNames ] string <br />
Types []type <br />
ImplementationId []byte <br />
Dbg_Methods string <br />
Dbg_Properties string <br />
Dbg_SupportedInterfaces string<br />
</pre><br />
'''methods<br />
<br />
<pre> <br />
--- Object internal name : com.sun.star.comp.example.cpp.Counter<br />
queryInterface ( aType as type ) <br />
acquire ( ) <br />
release ( ) <br />
getCount ( ) <br />
setCount ( nCount as long ) <br />
increment ( ) <br />
decrement ( ) <br />
getImplementationName ( ) <br />
supportsService ( ServiceName as string ) <br />
getSupportedServiceNames ( ) <br />
getTypes ( ) <br />
getImplementationId ( ) <br />
queryAdapter ( ) <br />
</pre><br />
{{Documentation/Note|A noter pour conclure que l'outil [[Extensions_development_basic#X-Ray_tool|XRay]] peut vous permettre de faire fonctionner le compteur en "XRayant" la méthode increment par exemple. [[Object_Inspector|L'inspecteur Java]] permet en plus d'utiliser la méthode setCount qui demande un paramètre (ce que XRay ne sait pas encore faire).}}<br />
L'utilisation de [[Object_Inspector|l'inspecteur Java]] se fait avec un programme OOoBasic :<br />
<source lang='oobas'><br />
'Listing 10b Programme OOoBasic de test<br />
REM ***** BASIC *****<br />
Dim oSimpleComponent<br />
oSimpleComponent = CreateUnoService( "foo.Counter" )<br />
oInspector = createUnoService("org.openoffice.InstanceInspector")<br />
oInspector.inspect(oSimpleComponent, "MyCounter")<br />
End Sub<br />
</source><br />
<br />
==Un compteur avec attribut==<br />
Une petite variation sur le composant compteur va nous accaparer maintenant : l'utilisation d'un [[Documentation/DevGuide/WritingUNO/Defining_an_Interface|attribut]]. Gardez à l'esprit que dans ce cas on accède automatiquement à l'attribut par deux méthodes set/get suivie du nom de l'attribut. Ces méthodes, j'insiste un peu, sont créées automatiquement il faut donc les retirer (ou ne pas les ajouter) dans le fichier IDL. Mon nouveau fichier IDL devient ainsi :<br />
<source lang="idl"><br />
//Listing 11 Notre nouveau fichier IDL pour le compteur<br />
//IDL<br />
#include <com/sun/star/uno/XInterface.idl><br />
//#include <com/sun/star/lang/XInitialization.idl><br />
<br />
module foo<br />
{<br />
<br />
interface XCountable : com::sun::star::uno::XInterface<br />
{<br />
// long getCount(); ************* generee automatiquement<br />
// void setCount( [in] long nCount ); ********** generee automatiquement<br />
[attribute] long Count;<br />
long increment();<br />
long decrement();<br />
};<br />
<br />
service Counter<br />
{<br />
interface XCountable;<br />
};<br />
};<br />
</source><br />
Comment ce nouveau compteur est-il vu du OooBasic ? On ne voit plus du tout getCount and setCount ! Cela ne signifie pas qu'elles ne sont pas disponibles. Pour prouver qu'elles sont bien disponibles, utilisons le programme OooBasic suivant. Il fonctionne correctement.<br />
<br />
<source lang="oobas"><br />
'Listing 12 <br />
REM ***** BASIC *****<br />
<br />
Sub Main<br />
Dim oSimpleComponent<br />
oSimpleComponent = CreateUnoService( "my_module.MyService" )<br />
oSimpleComponent.Count = 5<br />
print oSimpleComponent.Count<br />
oSimpleComponent.increment()<br />
print oSimpleComponent.Count<br />
XRay oSimpleComponent<br />
End Sub<br />
</source><br />
Une nouvelle introspection avec Xray du nouveau service créé nous montre maintenant :<br />
<br />
'''properties<br />
<pre><br />
--- Object internal name : com.sun.star.comp.example.cpp.Counter<br />
Count long <br />
ImplementationName string <...> pseudo-prop, read-only <br />
SupportedServiceNames []string pseudo-prop, read-only <br />
Types []type pseudo-prop, read-only <br />
ImplementationId []byte pseudo-prop, read-only <br />
Dbg_Methods string <...> basic prop, read-only<br />
Dbg_Properties string <...> basic prop, read-only<br />
Dbg_SupportedInterfaces string <...> basic prop, read-only <br />
</pre><br />
'''methods<br />
<pre><br />
--- Object internal name : com.sun.star.comp.example.cpp.Counter<br />
queryInterface ( aType as type ) AS variant <br />
acquire ( ) <br />
release ( ) <br />
increment ( ) AS long <br />
decrement ( ) AS long <br />
getImplementationName ( ) AS string <br />
supportsService ( ServiceName as string ) AS boolean <br />
getSupportedServiceNames ( ) AS []string <br />
getTypes ( ) AS []type <br />
getImplementationId ( ) AS []byte <br />
queryAdapter ( ) AS object <br />
</pre><br />
{{Documentation/Note|Vous gardez le même code source que l'exemple précédent pour faire fonctionner cet exemple, c'est à dire qu'il y aura du code pour getCount() et setCount() même si ces fonctions n'apparaissent pas dans le fichier IDL. Si vous faites un XRay sur la propriété Count, cela vous donne la bonne valeur (pourtant le champ correspondant n'existe pas, il est implanté dans un champ qui se nomme m_nCount de type sal_Int32).}}<br />
<br />
==Construire le compteur sans aide (helper)==<br />
Nous avons vu comment utiliser une aide pour éviter de coder certaines interfaces. Il est naturellement possible au programmeur de tout coder lui-même. C'est ce que nous voulons faire pour l'exemple du compteur.<br />
<br />
A faire...<br />
<br />
=Composants évolués=<br />
Les composants peuvent proposer des interfaces très évoluées, capables de travailler sur des documents. Il vous faudra pour cela obtenir un [[FR/Documentation/Composants_et_boite_de_dialogue#Obtention_du_contexte|contexte]] et/ou un [[FR/Documentation/Composants_et_boite_de_dialogue#Obtention_du_Service_Manager|Service Manager]].<br />
<br />
=Notre deuxième composant=<br />
{{Documentation/Caution|Je ne laisse cette section que parce qu'elle reprend un exemple du [[Documentation/DevGuide/WritingUNO/C%2B%2B/C%2B%2B_Component|Developer's Guide]] en le francisant. J'ai retiré cet exemple de la version anglaise du document car il est bien mieux traité dans le [[Documentation/DevGuide/WritingUNO/C%2B%2B/C%2B%2B_Component|Developer's Guide]].}}<br />
Notre première tâche consiste à trouver un morceau de code comme point de départ. L'idée générale est de partir de : “<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/Components/CppComponent” et de modifier légèrement le code. Commençons par décrire l'exemple : un seul module comportant deux services (MyService1 et MyService2). Ce que réalise cet exemple n'est pas extraordinaire mais fournit un bon point de départ.<br />
Voici le fichier IDL décrivant tout cela :<br />
<source lang="idl"><br />
//Listing 13 Fichier IDL de départ<br />
// IDL<br />
#include <com/sun/star/uno/XInterface.idl><br />
#include <com/sun/star/lang/XInitialization.idl><br />
<br />
module my_module<br />
{<br />
<br />
interface XSomething : com::sun::star::uno::XInterface<br />
{<br />
string methodOne( [in] string val );<br />
};<br />
<br />
service MyService1<br />
{<br />
interface XSomething;<br />
};<br />
service MyService2<br />
{<br />
interface XSomething;<br />
interface com::sun::star::lang::XInitialization;<br />
};<br />
};<br />
</source><br />
<br />
Le programme Basic suivant nous montre comment accéder à ce composant (ses services et interfaces).<br />
<source lang="oobas"><br />
'Listing 14 Accéder à un service et son interface en OOoBasic<br />
REM ***** BASIC *****<br />
Sub demonstrateSimpleComponent<br />
Dim oSimpleComponent<br />
oSimpleComponent = CreateUnoService( "my_module.MyService1" )<br />
msgbox oSimpleComponent.methodOne("Component succesfully instantiated!")<br />
'XRay oSimpleComponent<br />
End Sub<br />
</source><br />
Nous avons décidé en fait de simplifier cet exemple de départ, car il n'y a aucun exemple plus simple fourni avec le SDK. Le listing suivant nous fournit notre nouveau fichier IDL qui définit un seul service « MyService » une seule interface « XSomething » et deux méthodes.<br />
<source lang="idl"><br />
Listing 15 Notre fichier IDL de départ<br />
// IDL<br />
#include <com/sun/star/uno/XInterface.idl><br />
#include <com/sun/star/lang/XInitialization.idl><br />
<br />
module my_module<br />
{<br />
<br />
interface XSomething : com::sun::star::uno::XInterface<br />
{<br />
string methodOne( [in] string val );<br />
string methodTwo( [in] string val );<br />
};<br />
<br />
service MyService<br />
{<br />
interface XSomething;<br />
};<br />
};<br />
</source><br />
Il suffit ensuite de renommer le fichier “service2_impl.cxx” trouvé dans l'exemple “<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/Components/CppComponent” comme “service_impl.cxx” et ensuite réaliser les changements marqués en rouge dans le listing suivant : <br />
<source lang="cpp"><br />
Listing 16 <br />
// service_impl.cxx<br />
#include <cppuhelper/implbase3.hxx> // "3" implementing three interfaces<br />
#include <cppuhelper/factory.hxx><br />
#include <cppuhelper/implementationentry.hxx><br />
<br />
#include <com/sun/star/lang/XServiceInfo.hpp><br />
#include <com/sun/star/lang/XInitialization.hpp><br />
#include <com/sun/star/lang/IllegalArgumentException.hpp><br />
#include <my_module/XSomething.hpp><br />
<br />
<br />
using namespace ::rtl; // for OUString<br />
using namespace ::com::sun::star; // for odk interfaces<br />
using namespace ::com::sun::star::uno; // for basic types<br />
<br />
<br />
namespace my_sc_impl<br />
{<br />
<br />
static Sequence< OUString > getSupportedServiceNames_MyServiceImpl()<br />
{<br />
static Sequence < OUString > *pNames = 0;<br />
if( ! pNames )<br />
{<br />
// MutexGuard guard( Mutex::getGlobalMutex() );<br />
if( !pNames )<br />
{<br />
static Sequence< OUString > seqNames(1);<br />
seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("my_module.MyService"));<br />
pNames = &seqNames;<br />
}<br />
}<br />
return *pNames;<br />
}<br />
<br />
static OUString getImplementationName_MyServiceImpl()<br />
{<br />
static OUString *pImplName = 0;<br />
if( ! pImplName )<br />
{<br />
// MutexGuard guard( Mutex::getGlobalMutex() );<br />
if( ! pImplName )<br />
{<br />
static OUString implName( RTL_CONSTASCII_USTRINGPARAM("my_module.my_sc_implementation.MyService") );<br />
pImplName = &implName;<br />
}<br />
}<br />
return *pImplName;<br />
}<br />
<br />
class MyServiceImpl : public ::cppu::WeakImplHelper3<<br />
::my_module::XSomething, lang::XServiceInfo, lang::XInitialization ><br />
{<br />
OUString m_arg;<br />
public:<br />
// focus on three given interfaces,<br />
// no need to implement XInterface, XTypeProvider, XWeak<br />
<br />
// XInitialization will be called upon createInstanceWithArguments[AndContext]()<br />
virtual void SAL_CALL initialize( Sequence< Any > const & args )<br />
throw (Exception);<br />
// XSomething<br />
virtual OUString SAL_CALL methodOne( OUString const & str )<br />
throw (RuntimeException);<br />
// **********************ADDED<br />
virtual OUString SAL_CALL methodTwo( OUString const & str )<br />
throw (RuntimeException);<br />
// ********************** END ADDED<br />
// XServiceInfo<br />
virtual OUString SAL_CALL getImplementationName()<br />
throw (RuntimeException);<br />
virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName )<br />
throw (RuntimeException);<br />
virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()<br />
throw (RuntimeException);<br />
};<br />
// XInitialization implemention<br />
void MyServiceImpl::initialize( Sequence< Any > const & args )<br />
throw (Exception)<br />
{<br />
if (1 != args.getLength())<br />
{<br />
throw lang::IllegalArgumentException(<br />
OUString( RTL_CONSTASCII_USTRINGPARAM("give a string instanciating this component!") ),<br />
(::cppu::OWeakObject *)this, // resolve to XInterface reference<br />
0 ); // argument pos<br />
}<br />
if (! (args[ 0 ] >>= m_arg))<br />
{<br />
throw lang::IllegalArgumentException(<br />
OUString( RTL_CONSTASCII_USTRINGPARAM("no string given as argument!") ),<br />
(::cppu::OWeakObject *)this, // resolve to XInterface reference<br />
0 ); // argument pos<br />
}<br />
}<br />
// XSomething implementation<br />
OUString MyServiceImpl::methodOne( OUString const & str )<br />
throw (RuntimeException)<br />
{<br />
return OUString( RTL_CONSTASCII_USTRINGPARAM(<br />
"called methodOne() of MyService implementation: ") ) + m_arg + str;<br />
}<br />
// **********************ADDED<br />
OUString MyServiceImpl::methodTwo( OUString const & str )<br />
throw (RuntimeException)<br />
{<br />
return OUString( RTL_CONSTASCII_USTRINGPARAM(<br />
"called methodTwo() of MyService2 implementation: ") ) + m_arg + str;<br />
}<br />
// ********************** END ADDED<br />
// XServiceInfo implementation<br />
OUString MyServiceImpl::getImplementationName()<br />
throw (RuntimeException)<br />
{<br />
// unique implementation name<br />
return OUString( RTL_CONSTASCII_USTRINGPARAM("my_module.my_sc_impl.MyService") );<br />
}<br />
sal_Bool MyServiceImpl::supportsService( OUString const & serviceName )<br />
throw (RuntimeException)<br />
{<br />
// this object only supports one service, so the test is simple<br />
return serviceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("my_module.MyService") );<br />
}<br />
Sequence< OUString > MyServiceImpl::getSupportedServiceNames()<br />
throw (RuntimeException)<br />
{<br />
return getSupportedServiceNames_MyServiceImpl();<br />
}<br />
<br />
Reference< XInterface > SAL_CALL create_MyServiceImpl(<br />
Reference< XComponentContext > const & xContext )<br />
SAL_THROW( () )<br />
{<br />
return static_cast< lang::XTypeProvider * >( new MyServiceImpl() );<br />
}<br />
<br />
}<br />
<br />
/* shared lib exports implemented without helpers in service_impl1.cxx */<br />
namespace my_sc_impl<br />
{<br />
static struct ::cppu::ImplementationEntry s_component_entries [] =<br />
{<br />
{<br />
create_MyServiceImpl, getImplementationName_MyServiceImpl,<br />
getSupportedServiceNames_MyServiceImpl,::cppu::createSingleComponentFactory,<br />
0, 0<br />
},<br />
{ 0, 0, 0, 0, 0, 0 }<br />
};<br />
}<br />
<br />
extern "C"<br />
{<br />
void SAL_CALL component_getImplementationEnvironment(<br />
sal_Char const ** ppEnvTypeName, uno_Environment ** ppEnv )<br />
{<br />
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;<br />
}<br />
sal_Bool SAL_CALL component_writeInfo(<br />
lang::XMultiServiceFactory * xMgr, registry::XRegistryKey * xRegistry )<br />
{<br />
return ::cppu::component_writeInfoHelper(<br />
xMgr, xRegistry, ::my_sc_impl::s_component_entries );<br />
}<br />
void * SAL_CALL component_getFactory(<br />
sal_Char const * implName, lang::XMultiServiceFactory * xMgr,<br />
registry::XRegistryKey * xRegistry )<br />
{<br />
return ::cppu::component_getFactoryHelper(<br />
implName, xMgr, xRegistry, ::my_sc_impl::s_component_entries );<br />
}<br />
}<br />
</source><br />
Le fichier makefile est seulement changé pour prendre en compte des noms modifiés. Ensuite le module est complété et testé avec le programme OOoBasic :<br />
<source lang="oobas"><br />
'Listing 17 Programme OooBasic de test<br />
REM ***** BASIC *****<br />
<br />
Sub Main<br />
Dim oSimpleComponent<br />
oSimpleComponent = CreateUnoService( "my_module.MyService" )<br />
msgbox oSimpleComponent.methodOne( "Component succesfully instantiated!" )<br />
msgbox oSimpleComponent.methodTwo( "Component succesfully instantiated!" )<br />
'XRay oSimpleComponent<br />
End Sub<br />
</source><br />
<br />
D'où viennent les extern “C” présents dans le code source ? Ce problème a déjà été [[Documentation/FR/Construire_des_composants#Utilisation_d.27une_aide_.28helper.29_pour_construire_le_composant_scriptable|évoqué ici]].<br />
<br />
Nous avons en fait à implanter l'interface <idl>com.sun.star.lang.XServiceInfo</idl> quand on crée un composant. Cette interface est décrite comme d'habitude à l'aide du fichier IDL correspondant :<br />
<source lang="idl"><br />
//Listing 18 Fichier IDL correspondant au service XServiceInfo<br />
// IDL<br />
module com { module sun { module star { module lang {<br />
interface XServiceInfo: com::sun::star::uno::XInterface<br />
{<br />
string getImplementationName();<br />
boolean supportsService( [in] string ServiceName );<br />
sequence<string> getSupportedServiceNames();<br />
};<br />
}; }; }; };<br />
</source> <br />
Nous retrouvons des méthodes que l'on a pu reconnaître dans le code complet du composant. Ce service fournit de l'information concernant l'implémentation, c'est à dire quels services sont implantés et le nom de l'implantation.<br />
La première méthode fournit le nom de l'implantation du service<br />
La seconde méthode teste si le service passé en argument est disponible, c'est à dire implanté dans le composant.<br />
La troisième méthode fournit des noms ded service de l'implantation, incluant aussi indirectement les noms des services.<br />
Nous en déduisons une règle : quand les services sont écrits les trois méthodes de l'interface XserviceInfo doivent être écrites comme des fonctions C externes avec un préfixe “component_”.<br />
<br />
=Les problèmes spécifiques à Microsoft Windows=<br />
{{Documentation/Windows|Cette section aborde des problèmes que vous pouvez être amenés à rencontrer lorsque vous faites une édition de lien entre un composant et une librairie de style Unix. Gardez à l'esprit que les composants sont toujours construits avec Visual C++. Mais il y a un tas de librairies libres externes qui sont plutôt de style Unix et qui ne peuvent ainsi être construite qu'avec cygwin ou quelque chose d'approchant (MinGw). Les porter sous VC++ demanderait un travail trop important. Je veux donner ici un exemple montrant une voie que j'ai mis plusieurs jours à découvrir. Je ne vais pas construire un composant dans l'exemple qui suit, mais seulement un binaire exécutable construit avec VC++ qui utilise une dll construite avec cygwin.}}<br />
<br />
== Notre exemple ==<br />
Notre exemple est encore basé sur le compteur. Je commence par donner le code source complet car il est un peu modifié par rapport à l'exemple déjà traité. Commençons par le fichier d'inclusion :<br />
<source lang="cpp"><br />
//Listing 20 counter.hxx<br />
// C++<br />
class MyCounterImpl {<br />
int m_nCount;<br />
public:<br />
MyCounterImpl();<br />
~MyCounterImpl();<br />
int getCount();<br />
void setCount( int nCount );<br />
int increment();<br />
int decrement() ;<br />
};<br />
</source><br />
et par son code source C++ correspondant :<br />
<source lang="cpp"><br />
// counter.cxx Listing 21<br />
#include <stdio.h><br />
#include "counter.hxx"<br />
MyCounterImpl::MyCounterImpl()<br />
: m_nCount( 0 )<br />
{ printf( "< MyCounterImpl ctor called >\n" ); }<br />
MyCounterImpl::~MyCounterImpl()<br />
{ printf( "< MyCounterImpl dtor called >\n" ); }<br />
int MyCounterImpl::getCount()<br />
{ return m_nCount; }<br />
void MyCounterImpl::setCount( int nCount )<br />
{ m_nCount = nCount; }<br />
int MyCounterImpl::increment()<br />
{ return (++m_nCount); }<br />
int MyCounterImpl::decrement()<br />
{ return (--m_nCount); }<br />
<br />
extern "C" void essai1(int *a){<br />
MyCounterImpl count;<br />
count.setCount( *a);<br />
count.increment();<br />
*a=count.getCount();<br />
}<br />
</source><br />
Notez que j'ai ajouté une fonction externe C nommée "essai1". Le point important est que je ne peux pas utiliser directement les classes car les différents compilateurs leur donne des noms différents dans les fichiers objets ou librairies générés.<br />
<br />
{{Documentation/Note|VC++ ajoute un "_" comme prefix du nom de la fonction et un "@n" comme suffix avec n comme taille en octets des paramètres. Dans notre exemple "_essai1@4" serait exporté.}}<br />
<br />
<br />
Et maintenant le listing du programme principal :<br />
<br />
<source lang="cpp"><br />
//Listing 22 Main Program<br />
//c++<br />
//countermain.cxx<br />
#include <stdio.h><br />
<br />
extern "C" void essai1(int *a);<br />
// le __declspec(dllimport) ne marche pas<br />
//__declspec(dllimport) void essai1(void);<br />
<br />
int main(int argc, char **argv)<br />
{ int b=12;<br />
essai1(&b);<br />
printf("resultat attendu : 13, resultat calcule : %d\n",b);<br />
return 0;<br />
}<br />
</source><br />
Passons maintenant à la description de la phase de compilation.<br />
<br />
==Compilation==<br />
Le Listing 21 est compilé sous cygwin avec les outils du GNU et transformé en vraie dll.<br />
<pre><br />
gcc -c counter.cxx -o counter.o<br />
dlltool --export-all --output-def counter.def counter.o<br />
dllwrap counter.o --dllname counter.dll --def counter.def<br />
</pre><br />
L'option "-fPIC" ne semble pas nécessaire sous cygwin. Arrivé ici vous avez un fichier counter.dll. Copiez-le ainsi que counter.def dans un répertoire que vous allez utiliser avec VC++.<br />
{{Documentation/Windows|Si vous pouvez directement donner à gcc une librairie dynamique pour la phase d'édition de liens, ce n'est pas le cas sous Windows. Utiliser une dll se fait avec une librairie statique créée pour vous avec l'outil lib qui utilise le fichier de définition pour cela.}}<br />
La compilation sous VC++ se fait comme suit<br />
<pre><br />
lib /machine:i386 /def:counter.def<br />
cl countermain.cxx counter.lib<br />
</pre><br />
Voila c'est fait. La première ligne construit le fichier counter.lib qui est utilisé en deuxième ligne. Si votre cygwin1.dll est accessible, vous lancez simplement <code>countermain</code> et regardez ce qui se passe.<br />
<br />
==MakeFile==<br />
{{Documentation/Caution|<br />
Le chapitre sur les [[MakeFile|MakeFile]] est en construction et même pas traduit en français pour le moment, mais nous espérons ajouter un exemple de makeFile qui gère ce genre de situations dans le futur (aussi proche que possible).}}<br />
Nous allons maintenant examiner comment transformer un composant en addin.<br />
<br />
=Composant comme add-in simplifié=<br />
Il est possible d'utiliser un composant comme add-in OooCalc, c'est à dire une fonction OooCalc qui utilise le code du composant. L'idée est d'écrire une fonction OOoBasic qui appelle le composant et d'utiliser la fonction OOoBasic dans le tableur et cela parcequ'OpenOffice autorise l'utilisation de fonctions OOoBasic dans son tableur. Il nous est donc possible d'utiliser du code C++ dans le tableur de la manière suivante : Calc appelle le Basic qui appelle le C++. Cette manière de procéder a des limites, car les variables OOoBasic meurent quand les macros finissent et qu'ainsi il est difficile de stocker des résultats intermédiaire. Cela dit, c'est peut être pas si simple à faire non plus en C++. Il est difficile aussi de partager des objets entre deux sous-programmes Basic ! <br />
Nous pouvons donner un exemple. Le fichier IDL correspondant est :<br />
<source lang="idl"><br />
module my_module {<br />
<br />
interface XSomething : com::sun::star::uno::XInterface<br />
{<br />
long addFive(<br />
[in] long intDummy<br />
);<br />
long addSix(<br />
[in] long intDummy<br />
);<br />
};<br />
<br />
service MyService<br />
{<br />
interface XSomething;<br />
};<br />
};<br />
</source><br />
Si nous construisons complètement ce composant on peut écrire le programme Basic pour tester le fonctionnement :<br />
<source lang="oobas"><br />
REM ***** BASIC *****<br />
<br />
function demo(val as long) as long<br />
Dim oSimpleComponent As object<br />
oSimpleComponent = CreateUnoService( "my_module.MyService" )<br />
demo = oSimpleComponent.addFive(val)<br />
end Function <br />
</source><br />
De retour dans notre feuille de calcul, nous pouvons écrire dans une cellule “=demo(6)” ou “= demo(B2)” si B2 contient une valeur numérique.<br />
<br />
Nous examinerons plus loin dans ce document la vraie manière de [[Documentation/FR/Construire_des_Addins|construire un add-in]].<br />
<br />
=Réaliser des composants avec boîtes de dialogue=<br />
<br />
Ce problème est tellement vaste que nous lui réservons [[FR/Documentation/Composants_et_boite_de_dialogue|une page entière ici]] où nous aborderons le problème du compteur et de sa relation avec sa boîte de dialogue de plusieurs façons différentes.<br />
<br />
= Retour à la page d'accueil=<br />
<br />
[[Documentation/FR/Cpp_Guide|Page d'accueil du développement C++ à l'aide du SDK]]<br />
<br />
= Voir aussi =<br />
* [[Constructing_Components|Version anglaise de cette page]]<br />
* Daniel Bölzle's tutorial : [[Uno/Cpp/Tutorials/component_tutorial|Writing a simple UNO component]]<br />
* [[Documentation/DevGuide/WritingUNO/Writing_UNO_Components|Writing UNO Components]] in Developer's Guide<br />
* [[Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno|C++ and UNO tutorial]]<br />
* [http://cedric.bosdonnat.free.fr/wordpress/?p=19 Creating an URE application in C++]<br />
* [[Development/Cpp/Helper/ServiceDecl|Service Declaration]]<br />
* [[Development/Cpp/Helper/OPropertyContainerHelper|Registering properties]]<br />
*[[Tutorial_UNO_Library|UNO tutorial]]<br />
*[[Tutorial_UNO_IDL|UNO IDL]]<br />
* [[Extensions_Packager|Extensions Packager]] (BasicAddonBuilder from [mailto:paolomantovani@openoffice.org Paolo Mantovani])<br />
* [[BASIC/UNO_Object_Browser|BASIC UNO Object Browser]] : You can see the corresponding code as a complex component.<br />
* [[API/Samples/Java/Office/MinimalComponent|Minimal Java Component]]<br />
* [[General_UNO_Component_Project_Type|General UNO Component project Type in Java]]<br />
* [[OpenOffice_Add-On_Project_Type|Office Add-on Projet Type in Java]]<br />
* [[Uno/Article/Types%26Reflection]]<br />
* [[UNO_component_packaging|Component with Python]]<br />
* [[Non-code_extensions_FR|Extensions et packages UNO]]<br />
* 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<br />
* Bernard Marcelly's [[Extensions_development_basic#Xray_tool|XRay tool description]] in this wiki<br />
* See also [[Extension Deployement|Extension Deployement]]<br />
* [[UNO component packaging|(Python) UNO component packaging]]<br />
<br />
[[Category:FR/Cpp_Guide]]<br />
[[Category:FR/Extensions]]<br />
[[Category:Extensions]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/FR/Documentation/Fichiers_IDL_et_C%2B%2BFR/Documentation/Fichiers IDL et C++2016-05-01T06:43:08Z<p>BMarcelly: /* L'introspection et OOoBasic */</p>
<hr />
<div>(Cette introduction est faite avec l'aide de :http://udk.openoffice.org/cpp/man/component_tutorial.html )<br />
Vous devez commencer à être habitué si vous êtes parvenus jusqu'ici en lisant tous les chapitres précédents à la terminologie service/interface qui prévaut pour la programmation UNO. Cette terminologie n'étant pas universelle, je me permet d'en rappeler quelques éléments. <br />
<br />
<br />
=Services et Interfaces=<br />
==Introduction==<br />
Voir [[FR/Documentation/BASIC_Guide/API_Intro| Introduction à l'API StarOffice]] pour une introduction à UNO (ou [[Extensions_development_basic#Introducing_the_OpenOffice.org_API|Introducing the OpenOffice.org API]]).<br />
Dans l'API OpenOffice, un "service" est un concept abstrait qui fournit certaines interfaces et propriétés/attributs. Comme le souligne le Guide du développeur : “les propriétés sont des données dans un objet qui sont triées par nom sur une interface générique pour un accès de la propriété”. Il serait mieux de distinguer attribut et propriété. Mais nous ne le faisons pas pour le moment.<br />
<br />
Un service possède plusieurs propriétés et une interface correspond à plusieurs méthodes qui trouvent un moyen de changer les propriétés. <br />
Prenons une voiture pour illustrer ces concepts. La voiture fournit deux interfaces concrètes : XAccelerationControl et XDrivingDirection. Deux méthodes d'exportation d'interface, la première pour accélérer et ralentir, la seconde pour faire tourner la voiture à droite ou à gauche (voir Figure 9). Pourquoi deux (ou plusieurs) interfaces ? C'est seulement pour réunir des fonctionnalités caractéristiques. Pensez à une vraie voiture où ces interfaces sont séparées (le volant d'un côté et les pédales de l'autre) et ce qui se passerait si seulement les pieds dirigeaient ces deux interfaces ?<br />
<br />
Dans l'API OpenOffice, les modules groupent des services, des interfaces, des types, des énumérations et autres structures données (voir Figure 10). C'est impossible de comprendre un tel dessin sans se poser un certain nombre de questions et, en particulier, comment est-ce que nous voyons ce module quand il est utilisé dans un programme ?<br />
<br />
<br />
Pour répondre à cette question, nous choisissons le langage OOoBasic : <br />
<source lang="oobas"><br />
'Listing 1<br />
REM ***** BASIC *****<br />
'en premier, créez le service<br />
oSimpleComponent = CreateUnoService( "my_module.MyService1" )<br />
'call the unique method<br />
oSimpleComponent.methodOne()<br />
....<br />
'first create the service<br />
oSimpleComponent2 = CreateUnoService( "my_module.MyService2" )<br />
'call one of both method<br />
oSimpleComponent.methodTwo()<br />
...<br />
</source><br />
<br />
Les règles de Danny Brewer<br />
<br />
Les services sont similaires aux objets en java. <br />
<br />
# Un service peut hériter de rien ou d'un autre service. (auquel on peut appliquer récursivement cette règle) <br />
# Un service peut inclure zéro ou plusieurs services. (auxquels on peut appliquer récursivement ces règles) <br />
# Un service peut exporter des interfaces. <br />
# Un service peut avoir des propriétés. <br />
# Une interface peut hériter d'aucune ou d'une autre interface (à laquelle on peut appliquer récursivement cette règle). <br />
#Une interface peut inclure zéro ou plusieurs interfaces (auxquelles on peut appliquer récursivement ces règles). <br />
# Une interface peut exécuter des méthodes. <br />
# Une interface est toujours nommées par un nom commençant par un X. <br />
<br />
De ces règles vous pouvez déduire que les méthodes sont TOUJOURS trouvées dans des interfaces, et les propriétés sont TOUJOURS trouvées dans des services.<br />
<br />
==Arbres IDL et programmation UNO==<br />
J'ai déjà eu l'occasion d'aborder la notion d'arbre IDL dans un chapitre précédent (voir [[Documentation/FR/OpenOffice_Writer#Aller_plus_loin_avec_l.27Inspector_Java| Aller plus loin avec l'inspector Java]]). Ce chapitre me semble toutefois l'endroit tout indiqué pour aller plus loin dans les explications.<br />
<br />
Nous avons suffisamment programmé l'API UNO pour en déduire un certain nombre de règles pour le langage C++.<br />
<br />
'''Règle 1''' : le langace C++ nous permet de "naviguer" d'une interface à une autre. Nous aborderons le problème de l'obtention de ces interfaces [[Documentation/FR/Fichiers_IDL_et_C%2B%2B#Obtention_d.27une_interface_avec_la_macro_UNO_QUERY| plus loin]].<br />
{{Documentation/Note|'''Note''' : cette règle n'est vrai que pour le langage C++ et à ma connaissance pour le langage Java. Mais le langage OOoBasic permet quant à lui d'utiliser des variables pour stocker des services. C'est beaucoup plus pratique et donne des programmes beaucoup plus lisibles.}}<br />
<br />
'''Règle 2''' : si pour une raison ou une autre on est obligé de manipuler un service, il faudra le faire dans une variable de type <idl>com.sun.star.uno.XInterface</idl>. Ce type est une interface puisque son nom commence par un X, et mettre une variable d'un type dans une variable d'un autre type s'appelle transtyper. Nous aborderons [[Documentation/FR/Fichiers_IDL_et_C%2B%2B#Quand_pour_obtenir_une_interface_il_faut_passer_par_un_service_et_par_XMultiServiceFactory|plus loin]] le problème de l'obtention de ces services en C++.<br />
<br />
Nous pouvons déduire de ces deux règles que le programmeur C++ devra, d'une manière ou d'une autre, retrouver des chemins pour aller d'une interface vers une autre. Si je pars d'une interface XTruc, vous pouvez appeler toutes ses méthodes ou chercher d'autres interfaces me conduisant à utiliser d'autres méthodes. Toutes les possibilités à partir de l'interface XTruc peuvent être représentées par un arbre : c'est cela que j'appelle arbre-IDL. Mon travail de programmeur va consister à trouver un chemin dans cet arbre et ce n'est pas toujours facile. J'ai déjà présenté les arbres-IDL (ou plus exactement les chemins dans cet arbre) dans ce document sous plusieurs formes :<br />
#[[FR/Documentation/OpenOffice_Writer#Repr.C3.A9sentation_textuelle_d.27un_arbre_IDL|Représentation textuelle d'un arbre IDL]].<br />
#[[FR/Documentation/OpenOffice_Writer#Repr.C3.A9sentation_de_type_Introspection_d.27un_arbre_IDL|Représentation avec un outil d'introspection]] d'un arbre IDL.<br />
#[[Documentation/FR/L%27automation_d%27OpenOffice.org_avec_un_binaire_ex%C3%A9cutable#Introduction_au_Bootstrapping|Représentation schématique d'un arbre IDL]].<br />
<br />
Avant d'aborder la manière dont on réalise les chemins au travers des arbres en C++ on va déjà revenir sur les fichiers IDL permettant de spécifier des modules, des interfaces et des services.<br />
<br />
=Specification IDL=<br />
Les interfaces sont spécifiées à l'aide d'un langage spécial, le langage IDL. UNO utilise UNO-IDL comme le langage de définition de l'interface. Le Langage de définition de l'Interface (IDL) est un langage descriptif (et non un langage de programmation) décrivant l'existence des interfaces qui seront rendues effectives par les objets. Avec IDL, vous définissez le nom de l'interface, les noms de chacun des attributs et méthodes. Une fois que vous avez créé les fichiers IDL, vous pouvez utiliser un compilateur IDL pour générer les fichiers d'en-tête dans le langage de programmation C++. <br />
La façon de spécifier des modules simples avec IDL est si claire que nous choisissons de commencer en premier seulement par des exemples.<br />
==Specifier une interface==<br />
Nous prenons comme exemple, l'interface XdrivingDirection de la Figure ci-dessous.<br />
<br />
[[Image:Service&Interface.png]]<br />
<br />
<source lang="idl"><br />
//Listing 2 Interface imaginaire XDrivingDirection<br />
// IDL<br />
interface XDrivingDirection<br />
{<br />
void turnLeft();<br />
void turnRight();<br />
};<br />
</source><br />
<br />
==Spécifier un service==<br />
L'exemple de la Figure ci-dessus est toujours utilisé, voici la spécification IDL correspondante :<br />
<source lang="idl"><br />
//Listing 3 Spécification d'un service « car »<br />
// IDL<br />
interface XDrivingDirection<br />
{<br />
void turnLeft();<br />
void turnRight();<br />
};<br />
interface XaccelerationControl<br />
{<br />
void speedUp();<br />
void slowDown();<br />
};<br />
service car<br />
{<br />
// exported interfaces:<br />
interface XdrivingDirection;<br />
interface XaccelerationControl;<br />
[attribute] float speed; <br />
[attribute] float angle;<br />
};<br />
</source><br />
Nous voyons apparaître un type float et nous donnons d'autres types IDL plus loin.<br />
<br />
==Spécifier un module==<br />
Les modules sont un moyen de regrouper des services. Cette notion correspond plutôt à une bibliothèque et n'a que peu d'importance pour le programmeur C++ (sauf s'il désire réaliser des extensions composants ou addin par exemple). Nous donnons quand même ici la spécification IDL correspondant à un module :<br />
<source lang="idl"><br />
//Listing 4 Spécification IDL du module my_module<br />
// IDL<br />
module my_module<br />
{<br />
interface Xsomething<br />
{<br />
void methodone();<br />
};<br />
service my_service1<br />
{<br />
// exported interfaces:<br />
interface Xsomething;<br />
};<br />
interface XsomethingElse<br />
{<br />
void methodTwo();<br />
void methodThree();<br />
};<br />
service my_service2<br />
{<br />
// exported interfaces:<br />
interface XsomethingElse;<br />
};<br />
};<br />
</source><br />
<br />
==Plus loin avec IDL==<br />
Les types IDL sont décrits dans le tableau ci-dessous :<br />
<TABLE WIDTH=100% BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0><br />
<TR VALIGN=TOP><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale"><FONT COLOR="#000000">char</FONT> </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">16-bit unicode character type </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">boolean </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">boolean type; true and false</FONT></P><br />
</TD><br />
</TR><br />
<TR VALIGN=TOP><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">byte </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">8-bit ordinal integer type </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">short </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">signed 16-bit ordinal integer type </FONT><br />
</P><br />
</TD><br />
</TR><br />
<TR VALIGN=TOP><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">unsigned short </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">unsigned 16-bit ordinal integer type </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">long </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">signed 32-bit ordinal integer type</FONT></P><br />
</TD><br />
</TR><br />
<TR VALIGN=TOP><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">unsigned long</FONT></P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">unsigned 32-bit integer type </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">hyper </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">signed 64-bit ordinal integer type</FONT></P><br />
</TD><br />
</TR><br />
<TR VALIGN=TOP><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">unsigned hyper</FONT></P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">unsigned 64-bit ordinal integer type </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">float </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">processor dependent float</FONT></P><br />
</TD><br />
</TR><br />
<TR VALIGN=TOP><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">double</FONT></P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">processor dependent double </FONT><br />
</P><br />
<br />
</TD><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">string</FONT></P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">string of 16-bit unicode characters</FONT></P><br />
</TD><br />
</TR><br />
<TR VALIGN=TOP><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">any</FONT></P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">universal type, takes every fundamental<br />
or compound UNO type, similar to Variant in other environments or<br />
Object in Java</FONT></P><br />
</TD><br />
<TD WIDTH=12%><br />
<br />
<P><FONT FACE="Thorndale">void </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">Indicates that a method does not<br />
provide a return value</FONT></P><br />
</TD><br />
</TR><br />
</TABLE><br />
Les méthodes peuvent avoir des arguments. Chaque argument dans la liste des arguments doit commencer avec un des drapeaux de direction [in], [out] ou [inout] avant qu'un type connu et identificateur pour l'argument soit donné. Nous donnons un exemple que nous rencontrerons souvent dans ce document , un compteur :<br />
<source lang="idl"><br />
//Listing 5 Module IDL décrivant un compteur<br />
// IDL<br />
module my_module<br />
{<br />
interface XSomething <br />
{<br />
long getCount();<br />
void setCount( [in] long nCount );<br />
long increment();<br />
long decrement();<br />
};<br />
service MyService<br />
{<br />
interface XSomething;<br />
};<br />
};<br />
</source><br />
Une interface peut être dérivée à partir d'une interface de base. Une interface dérivée peut déclarer ses propres attributs et ses méthodes. Les attributs et méthodes hérités ne peuvent pas être redéfinies dans l'interface dérivée. <br />
Un exemple d'héritage de l'interface :<br />
<source lang="idl"><br />
//Listing 6 Héritage dog de annimal<br />
//IDL<br />
interface animal {<br />
attribute long age;<br />
};<br />
interface dog : animal {<br />
attribute short leg;<br />
}<br />
</source><br />
L'héritage multiple est aussi possible<br />
<source lang="idl"><br />
interface dog : animal, friend {<br />
</source><br />
L'héritage dans le service est présenté dans le prochain chapitre. <br />
Dans la terminologie objet OOo, il y a une différence entre attribut et propriété, différence qui se manifeste par leurs façons respectives d'y accéder. On accède aux propriétés avec setPropertyValue(PropertyName,Any) alors qu'on accède aux attributs avec la méthode set/get(AttributeName). Nous avons déjà rencontré la manipulation des propriétés lors de l'examen des formes.<br />
<br />
=Collecter de l'information UNO avec les fichiers IDL=<br />
Il y a plusieurs possibilités pour trouver de l'information sur UNO. <br />
La première est d'utiliser OOoBasic et l'outil XRay de Bernard Marcelly, [http://www.openoffice.org/fr/Documentation/Basic/ voir les Tutoriels Basic]. Point négatif : OOoBasic ne montre pas les propriétés et les méthodes exactes, quelques unes sont rajoutées parce qu'elles sont disponibles en OooBasic.<br />
L'autre possibilité est d'aller à l'adresse internet suivante : http://api.openoffice.org/docs/common/ref/index-files/index-1.html<br />
qui fournit la même information mais probablement de manière plus lisible. Nous avons fourni des exemples dans les chapitres antérieurs (en particulier [[FR/Documentation/OpenOffice Writer|chapitre 7...]]) et normalement le lecteur a des compétences sur le sujet.<br />
==Le point de vue de Danny Brewer ==<br />
Néanmoins, il est important de comprendre le concept d'un "service" dans les documents sur l'API. Un service est juste une façon de grouper...<br />
<br />
# d'autres services encore <br />
# des interfaces <br />
<br />
La partie (1) “d'autres services encore”, signifie bien sûr, qu'il y a même plus d'interfaces disponibles au service original. <br />
Laissez moi vous montrer différents exemples. <br />
<br />
<idl>com.sun.star.sheet.SpreadsheetDocument</idl> est un service. <br />
<code>SpreadsheetDocument</code> contient le service <idl>com.sun.star.document.OfficeDocument</idl> et l'interface <idl>com.sun.star.sheet.XSpreadsheetDocument</idl><br />
comme le montre le fichier IDL ci-dessous :<br />
<source lang="idl"><br />
//Listing 7 Interface Specification<br />
//IDL<br />
service SpreadsheetDocument<br />
{<br />
//-------------------------------------------------------------------------<br />
<br />
/** common service for all types of documents.<br />
*/<br />
service com::sun::star::document::OfficeDocument;<br />
<br />
..........<br />
<br />
//-------------------------------------------------------------------------<br />
<br />
/** provides access to the collection of spreadsheets.<br />
*/<br />
interface com::sun::star::sheet::XSpreadsheetDocument;<br />
<br />
//------------------------------------------------------------------------- <br />
</source> <br />
<br />
Par conséquent, l'ensemble combiné d'interfaces de <idl>com.sun.star.sheet.SpreadsheetDocument</idl> et <idl>com.sun.star.document.OfficeDocument</idl> est accessible à un document de la Feuille de calcul (qui est bien sûr un <idl>com.sun.star.sheet.SpreadsheetDocument</idl>).<br />
<br />
Donc, bien que le composant chargé depuis l'URL retourne une interface, cette interface représente un service sous-jacent qui est un <code>SpreadsheetDocument</code>. En regardant les documents de l'API, vous pouvez dire quelles interfaces valides vous pouvez mettre en oeuvre.<br />
<br />
<code>SpreadsheetDocument</code> possède une interface <idl>com.sun.star.sheet.XSpreadsheetDocument</idl>.<br />
<br />
Le service <idl>com.sun.star.document.OfficeDocument</idl> possède les interfaces <idl>com.sun.star.view.XPrintable</idl> et <idl>com.sun.star.frame.XStorable</idl>.<br />
<br />
Comme <code>SpreadsheetDocument</code> hérite de <code>OfficeDocument</code>, il est aussi valide de demander soit l'interface <idl>com.sun.star.view.XPrintable</idl> soit l'interface <idl>com.sun.star.frame.XStorable</idl> à partir de ce service <idl>com.sun.star.sheet.SpreadsheetDocument</idl>. <br />
<br />
Maintenant, remplaçons dans le paragraphe précédent, les documents tableurs par les documents textes et tout le discours précédent est encore valide.<br />
Comment expliquer ce qu'est un service sous-jacent ? <br />
<br />
Il n'y a pas de formules magique pour cela. En principe, c'est évident. Si vous démarrez un tableur, par exemple, alors vous avez le service <idl>com.sun.star.sheet.SpreadsheetDocument</idl>. <br />
<br />
De la même façon, si je crée un objet par son nom de service..... <br />
<source lang="oobas"><br />
' obtention d'un service en OOoBasic<br />
oShape = oDoc.createUnoService( "com.sun.star.drawing.EllipseShape" )<br />
</source> <br />
alors je sais quel service c'est, parce que j'ai donné le nom du service dans l'instruction. <br />
<br />
Oui, vous pouvez toujours dire quelles interfaces sont disponibles si vous savez le nom du service, et ce, seulement en regardant la documentation de l'API. Aucune hypothèse. Aucun besoin de XRay. C'est une science absolue. Les multiples interfaces valides sont les interfaces du service lui-même, et de tous les services qui seront hérités de ce service. <br />
<br />
Dans certains cas, il est évident de savoir quels services vous avez. <br />
<br />
Si vous appelez getCellRangeByName(), alors vous obtenez un service <idl>com.sun.star.sheet.SheetCellRange</idl>. Si vous appelez getCellByPosition(), alors vous avez un service <idl>com.sun.star.sheet.SheetCell</idl>. Beaucoup de choses identiques sont disponibles dans ces deux services <idl>com.sun.star.sheet.SheetCell</idl> et <idl>com.sun.star.sheet.SheetCellRange</idl>, mais ils sont de nature différents. Le service <idl>com.sun.star.sheet.SheetCellRange</idl> représente un groupe rectangulaire de cellules tandis que le service <idl>com.sun.star.sheet.SheetCell</idl> concerne une cellule unique. Il y a évidemment des choses que l'on peut faire avec une cellule unique mais pas avec un groupe de cellule.<br />
<br />
Il y a aussi d'autres possibilités. Si vous obtenez un service <idl>com.sun.star.table.CellRange</idl> à partir d'une table sous OOoWriter ce sera différent que si vous l'obtenez depuis une feuille de calcul, puisque ce sera un <idl>com.sun.star.sheet.SheetCellRange</idl>. Le service <code>SheetCellRange</code> est une version étendue du service <code>CellRange</code>. Lequel des deux services est obtenu dépend donc si votre demande getCellRangeByName() est réalisée à partir d'une table ou à partir d'une feuille de calcul.<br />
<br />
Parfois, spécialement pour l'application OooWriter, seul le guide du développeur est une aide précieuse, donnant des informations sur les services obtenus à partir d'autres services et des appels API. Mais il est toujours vrai que lorsque l'on connaît le service que l'on a, on peut en déduire directement, seulement à partir de la documentation de l'API toutes les interfaces qu'il est possible de demander. Pas d'essais inutiles, c'est une science exacte.<br />
<br />
==Un autre exemple concret==<br />
Les fichiers IDL sont disponibles dans le dossier <OpenOffice.org1.1_SDK>/idl/. Évidemment, le problème avec cette solution est que nous voyons uniquement l'API UNO du SDK installé, lequel peut être légèrement différent de notre Openoffice.org. Cependant, nous expliquerons cette possibilité après avoir mentionné juste une autre solution : [[Documentation/FR/Base_de_registres|l'exploration de la base de registres]].<br />
<br />
On veut maintenant montrer un exemple. On commence à partir d'un <br />
::com::sun::star::document::OfficeDocument et du nom du service, on en déduit sa position dans l'arborescence <OpenOffice.org1.1_SDK>/idl/com/sun/star/document/OfficeDocument.idl <br />
Ce fichier est présenté ci-dessous, en ayant pris soin de retirer les commentaires (voir <idl>com.sun.star.document.OfficeDocument</idl>) :<br />
<source lang="idl"><br />
//Listing 7<br />
//IDL<br />
service OfficeDocument<br />
{<br />
interface com::sun::star::frame::XModel;<br />
interface com::sun::star::util::XModifiable;<br />
interface com::sun::star::frame::XStorable;<br />
interface com::sun::star::view::XPrintable;<br />
[optional] interface XEventBroadcaster;<br />
[optional] interface XEventsSupplier;<br />
[optional] interface XDocumentInfoSupplier;<br />
[optional] interface XViewDataSupplier;<br />
[optional] interface com::sun::star::view::XPrintJobBroadcaster;<br />
[property, optional] boolean AutomaticControlFocus;<br />
[property, optional] boolean ApplyFormDesignMode;<br />
};<br />
</source><br />
Si on examine maintenant le service "<idl>com.sun.star.text.TextDocument</idl>" on trouve dans <OpenOffice.org1.1_SDK>/idl/com/sun/star/text/TextDocument.idl<br />
<source lang="idl"><br />
//Listing 8<br />
service TextDocument<br />
{<br />
service com::sun::star::document::OfficeDocument;<br />
interface com::sun::star::text::XTextDocument;<br />
interface com::sun::star::util::XSearchable;<br />
interface com::sun::star::util::XRefreshable;<br />
....<br />
};<br />
</source><br />
Comme on peut voir, ce service <idl>com.sun.star.text.TextDocument</idl> contient le service <idl>com.sun.star.document.OfficeDocument</idl>. Cette dépendance est en fait un héritage. La représentation complète UML de cet exemple peut être trouvée dans le guide de développeur : <br />
<br />
[[Image:TextDocumentWithMethods.png|none|thumb|450px| Figure tirée du Developer's Guide.]]<br />
<br />
Tout paraît simple jusqu'ici parce qu'on est resté très vague et que l'on ne s'est pas déplacé très profondément dans l'arbre IDL. Voyons ces complications d'un peu plus près.<br />
<br />
==Services et C++, c'est pas simple==<br />
{{Documentation/Tip|<br />
Si vous voulez bien comprendre le titre de cette section, lisez-là en vous posant systématiquement la question de savoir à tout moment quels sont les services disponibles.}}<br />
<br />
Il est grand temps maintenant d'aller plus loin dans notre exemple et de fournir du code avec commentaires. Pour cela nous allons prendre du code déjà abordé (voir [[Documentation/FR/OpenOffice_Writer#L.27interface_XTextCursor|le code correspondant pour OOoWriter]]).<br />
<source lang="cpp"> <br />
//Listing 9 Writer Example<br />
//C++<br />
OUString sDocUrl;<br />
osl::FileBase::getFileURLFromSystemPath(<br />
OUString::createFromAscii("/home/smoutou/Documents/demo.sxw"),sDocUrl);<br />
<br />
Reference< XComponent > xWriterComponent = <br />
rComponentLoader->loadComponentFromURL(<br />
sDocUrl,<br />
OUString::createFromAscii("_blank"),<br />
0,<br />
Sequence < ::com::sun::star::beans::PropertyValue >());<br />
<br />
Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);<br />
</source><br />
<br />
Le code nous montre que la variable xWriterComponent est de type <idl>com.sun.star.lang.XComponent</idl>, c'est une interface qui nous donne le service <idl>com.sun.star.text.TextDocument</idl> et ainsi aussi le service <idl>com.sun.star.document.OfficeDocument</idl> comme déjà expliqué. <br />
<br />
<idl>com.sun.star.text.XTextDocument</idl> est une Interface du service <code>TextDocument</code>, cela est une chose facile à retenir parce que les deux noms ne diffèrent que par la lettre X. Mais allons encore plus loin.<br />
<br />
Le fichier IDL <idl>com.sun.star.text.XTextDocument</idl> nous montre la méthode getText mais nous ne savons pas quels sont les nouveaux services disponibles dans la variable retournée par getText. Si l'on veut le savoir, il y a deux moyens : <br />
*Internet [http://api.openoffice.org/docs/common/ref/com/sun/star/text/XText.html XText interface] nous donne la réponse : le service est <idl>com.sun.star.text.Text</idl>. <br />
*L'autre manière est d'utiliser un outil d'introspection comme décrit plus tard dans [[Documentation/FR/Fichiers_IDL_et_C%2B%2B#Le_service_de_Core_reflection_et_son_interface_XIdlReflection|cette section]].<br />
<br />
A partir de<br />
<source lang="cpp"><br />
//Listing 10 Writer Example (continuation)<br />
//C++<br />
Reference< XText > xText = xTextDocument->getText();<br />
</source><br />
on essaie d'obtenir l'interface <idl>com.sun.star.text.XTextCursor</idl><br />
<source lang="cpp"><br />
//Listing 11 Writer Example (continuation)<br />
//C++<br />
Reference< XTextCursor> xTextCursor = xText->createTextCursor();<br />
</source><br />
Mais comment expliquer ce code ? Cherchant dans le fichier <idl>com.sun.star.text.XText</idl> nous trouvons seulement deux méthodes :<br />
<source lang="idl"><br />
//Listing 12 XText Interface IDL file<br />
// IDL<br />
module com { module sun { module star { module text { <br />
interface XText: com::sun::star::text::XSimpleText<br />
{ <br />
void insertTextContent( [in] com::sun::star::text::XTextRange xRange, <br />
[in] com::sun::star::text::XTextContent xContent, <br />
[in] boolean bAbsorb ) <br />
raises( com::sun::star::lang::IllegalArgumentException ); <br />
void removeTextContent( [in] com::sun::star::text::XTextContent xContent ) <br />
raises( com::sun::star::container::NoSuchElementException ); <br />
<br />
}; <br />
}; }; }; };<br />
</source><br />
Mais si vous regardez plus en détail dans ce fichier IDL, vous verrez que <idl>com.sun.star.text.XText</idl> hérite de <idl>com.sun.star.text.XSimpleText</idl>. Est-ce que la méthode createTextCursor est ici ? Oui, comme vous pouvez le voir.<br />
<source lang="idl"> <br />
//Listing 13 XSimpleText Interface IDL file<br />
// IDL<br />
module com { module sun { module star { module text { <br />
interface XSimpleText: com::sun::star::text::XTextRange<br />
{ <br />
com::sun::star::text::XTextCursor createTextCursor(); <br />
com::sun::star::text::XTextCursor createTextCursorByRange( [in] com::sun::star::text::XTextRange aTextPosition ); <br />
[oneway] void insertString( [in] com::sun::star::text::XTextRange xRange, <br />
[in] string aString, <br />
[in] boolean bAbsorb ); <br />
void insertControlCharacter( [in] com::sun::star::text::XTextRange xRange, <br />
[in] short nControlCharacter, <br />
[in] boolean bAbsorb ) <br />
raises( com::sun::star::lang::IllegalArgumentException ); <br />
<br />
};<br />
}; }; }; };<br />
</source><br />
{{Documentation/Tip|Si avant de lire la suite vous savez répondre à la question : quels sont les services disponibles dans la variable xTextCursor du listing 11, alors Bravo.}}<br />
<br />
Quels sont les services disponibles ici ? J'ai utilisé un outil d'introspection pour la réponse, qui me donne :<br />
<pre><br />
******** Services : 8<br />
com.sun.star.text.TextSortable<br />
com.sun.star.style.ParagraphPropertiesComplex<br />
com.sun.star.style.ParagraphPropertiesAsian<br />
com.sun.star.style.ParagraphProperties<br />
com.sun.star.style.CharacterPropertiesComplex<br />
com.sun.star.style.CharacterPropertiesAsian<br />
com.sun.star.style.CharacterProperties<br />
com.sun.star.text.TextCursor<br />
</pre><br />
Vous pouvez probablement trouver chacun d'entre eux via internet mais ce sera une tâche longue et fastidieuse : de bonnes raisons d'expliquer les services d'introspection [[Documentation/FR/Fichiers_IDL_et_C%2B%2B#Le_service_de_Core_reflection_et_son_interface_XIdlReflection|plus loin dans ce chapitre]].<br />
<br />
{{Documentation/Note|A noter que c'est l'utilisation des méthodes retournant un type donné qui sont absolument difficiles à déchiffrer. Trouver les services accessibles est alors très difficile et, personnellement, je ne m'y aventure pas sans outil d'instrospection (voir [[FR/Documentation/Base_de_registres#Interfaces_et_services_du_defaultBootstrap_InitialComponentContext.28.29|un exemple ici]]). Bonne nouvelle quand même, il y a quand même une exception avec les méthodes <code>createInstance</code> et <code>createInstanceWithContext</code> pour lesquelles le service retourné est complètement déterminé.}}<br />
<br />
Oui, voila décrit très superficiellement le travail du programmeur. Vous devez parcourir de tels chemins dans l'arbre IDL, pour trouver quoi faire en programmant. Heureusement il y a plus court en utilisant les exemples du SDK. Mais la plupart d'entre eux sont en Java, mais je dois avouer avoir trouvé beaucoup d'inspiration dans ces exemples même si je ne suis pas un programmeur Java.<br />
<br />
=IDL et C++ =<br />
Ce problème est développé dans le [[Documentation/DevGuide/ProUNO/C%2B%2B/C%2B%2B_Language_Binding|guide du développeur ici.]] <br />
==Obtention d'une interface en C++==<br />
En C++, vous avez seulement des variables de type interface. <br />
Un des problèmes les plus souvent rencontrés met en oeuvre une interface. Ce problème se produit très rarement dans OooBasic mais très souvent dans C++/Java. On peut trouver des exemples divers à partir du [[Documentation/FR/L%27automation_d%27OpenOffice.org_avec_un_binaire_ex%C3%A9cutable|chapitre 3]] régulièrement jusqu'à ce chapitre. <br />
===Obtention d'une interface avec une fonction de la librairie===<br />
<br />
L'obtention d'une interface par une fonction de la librairie a déjà été rencontrée dans [[FR/Documentation/L%27automation_d%27OpenOffice.org_avec_un_binaire_ex%C3%A9cutable#Introduction_au_Bootstrapping|le code de démarrage]]. Nous le présentons ici sous forme schématique.<br />
<br />
[[Image:BuiltInInterface.png|none|thumb|600px|Obtention de l'interface XComponentContext]]<br />
<br />
On part de nulle part mais utilisons une fonction toute prête, ici c'est <code>defaultBootstrap_IntitialComponentContext()</code> qui nous permet d'obtenir une interface de type <idl>com.sun.star.uno.XComponentContext</idl>.<br />
<br />
===Obtention d'une interface avec la macro UNO_QUERY===<br />
Comme exemple, on suppose qu'on a obtenu une interface <idl>com.sun.star.text.XTextDocument</idl>. En général, c'est fait par quelque chose comme :<br />
<source lang="cpp"><br />
//Listing 14<br />
//C++<br />
// Impossible à faire en C++ comme cela : il faut transtyper OfDoc en Interface<br />
Reference<com::sun::star::text::XTextDocument> OfDoc = something_to_get_this_interface();<br />
</source><br />
ou<br />
<source lang="cpp"><br />
//Listing 15<br />
//C++<br />
using namespace com::sun::star::text;<br />
....<br />
Reference<XTextDocument> OfDoc = something_to_get_this_interface();<br />
</source><br />
et nous voulons mettre en oeuvre l'interface <idl>com.sun.star.frame.XStorable</idl> pour sauver notre document. La figure ci-dessous nous montre toutes les interfaces que l'on peut obtenir à partir de <idl>com.sun.star.text.XTextDocument</idl>.<br />
<br />
[[Image:SimpleUNOQUERY.png|center]]<br />
<br />
Il s'agit des interfaces <idl>com.sun.star.util.XRefreshable</idl>, <idl>com.sun.star.util.XSearchable</idl>, <idl>com.sun.star.frame.XModel</idl>, <idl>com.sun.star.util.XModifiable</idl>, <idl>com.sun.star.frame.XStorable</idl> et <idl>com.sun.star.view.XPrintable</idl> même si l'on n'a pas représenté les flèches rouges correspondantes sur le dessin.<br />
<br />
====Les trois étapes pour l'obtention d'une interface====<br />
Trois étapes sont impliquées pour l'obtention d'une de ses interfaces :<br />
<br />
1) Ajoutez la ligne de votre code pour la demande de l'interface<br />
<source lang="cpp"><br />
// C++<br />
// query from com::sun::star::frame::XStorable interface<br />
Reference< XStorable > oToStore (OfDoc, UNO_QUERY); <br />
</source><br />
Il s'agit d'une déclaration de variable avec initialisation. Si la variable est déjà déclarée, utilisez alors une version un peu différente :<br />
<source lang="cpp"><br />
// C++<br />
// query from com::sun::star::frame::XStorable interface<br />
oToStore = Reference< XStorable > (OfDoc, UNO_QUERY);<br />
</source> <br />
2) Ajouter à l'aide d'une directive d'inclusion les fichiers hpp correspondants. Il faut ajouter aussi les espaces de nommage correspondants. L'inclusion est faite par :<br />
<source lang="cpp"><br />
//C++<br />
#include <com/sun/star/frame/XStorable.hpp><br />
</source><br />
et la gestion des espaces de nommage par : <br />
<source lang="cpp"><br />
//C++<br />
using namespace com::sun::star::frame;<br />
</source><br />
3) Ajouter les types correspondants dans le makefile comme montré ci-dessous dans la ligne com.sun.star.frame.XStorable \ qui est ajoutée<br />
<pre><br />
# Listing 16 Makefile <br />
# makefile<br />
# added com.sun.star.frame.XStorable<br />
TYPES := \<br />
com.sun.star.uno.XNamingService \<br />
....<br />
com.sun.star.uno.XAggregation \<br />
com.sun.star.frame.XStorable \<br />
com.sun.star.lang.XMain \ <br />
...<br />
com.sun.star.container.XHierarchicalNameAccess<br />
</pre><br />
{{Documentation/Note|<br />
Apprendre à réaliser ces trois étapes est essentiel pour une programmation en C++ : il vous sera impossible de réaliser un programme sans demander à un moment donné une interface (ou un service, comme traité plus loin).}}<br />
<br />
====Exemple concret====<br />
Appliquons les trois étapes sur un exemple concret. On peut schématiser tout cela simplement comme un chemin simple dans un arbre IDL :<br />
<br />
[[Image:SimpleUNOQUERY2.png|center|thumb|600px|Obtention d'une interface à partir d'une autre]]<br />
<br />
Et voici un exemple de code correspondant.<br />
<source lang="cpp"><br />
//Listing 19 Simple UNO_QUERY call<br />
// C++<br />
OUString sDocUrl;<br />
osl::FileBase::getFileURLFromSystemPath(<br />
OUString::createFromAscii("/home/smoutou/Documents/demo.sxw"),sDocUrl);<br />
Reference< XComponent > xWriterComponent = rComponentLoader->loadComponentFromURL(<br />
sDocUrl,<br />
OUString::createFromAscii("_blank"),<br />
0,<br />
Sequence < ::com::sun::star::beans::PropertyValue >());<br />
<br />
Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);<br />
// Ne pas oublier la direcive : #include <com/sun/star/frame/XStorable.hpp><br />
// ligne suivante correspond au schéma ci-dessus<br />
Reference < XStorable > xStorable (xTextDocument,UNO_QUERY);<br />
xStorable->store();<br />
</source><br />
qui utilise les interfaces <idl>com.sun.star.text.XTextDocument</idl> et <idl>com.sun.star.frame.XStorable</idl>.<br />
<br />
===Quand pour obtenir une interface il faut passer par un service et par XMultiServiceFactory===<br />
<br />
On a déjà rencontré cela plusieurs fois, ainsi cela doit vous être familier. Mais, puisque nous n'avons pas discuté toutes les étapes en détail, je vais maintenant m'y consacrer et montrer comment cela fonctionne.<br />
<br />
====Le problème====<br />
Comment pouvez-vous obtenir une interface si le service correspondant n'est pas directement disponible ? Schématiquement le problème peut se représenter par :<br />
<br />
[[Image:ComplexUNOQUERY.png|none|thumb|800px|Deux services indépendants]]<br />
<br />
où les deux services <idl>com.sun.star.text.TextDocument</idl> et <idl>com.sun.star.text.TextTable</idl> n'ont pas de dépendance soit par héritage, soit par inclusion (un des deux services contient l'autre).<br />
<br />
====Les solutions====<br />
<br />
'''Premier cas :''' une méthode de votre interface vous permet d'obtenir directement la nouvelle interface. C'était le cas du Listing 11 de ce chapitre. Dans ce cas le fichier hdl correpondant n'est pas requis et je n'ai pas trouvé de moyen simple pour trouver les nouveaux services disponibles sans outil d'introspection ! Voici comment ceci sera noté schématiquement dans les chemins des arbres IDL :<br />
<br />
[[Image:InterfaceParMethode.png|center|thumb|600px|Méthode pour l'obtention d'une interface]]<br />
<br />
'''Règle 3''' : lorsque vous obtenez une interface à partir d'une fonction membre vous ne devez pas construire les fichiers hdl en partant des fichiers IDL comme on doit le faire dans la méthode [[FR/Documentation/Fichiers_IDL_et_C%2B%2B#Les_trois_.C3.A9tapes_pour_l.27obtention_d.27une_interface|en trois étapes]].<br />
<br />
'''Second cas :''' aucune méthode de votre interface ne peut vous aider. Il vous faut demander un service avant d'obtenir l'interface. Cela peut être fait en deux ou trois instructions. J'ai déjà utilisé ces deux styles. Regardez dans le listing :<br />
<br />
<source lang="cpp"><br />
//Listing 20 Getting an Interface with XMultiServiceFacory<br />
// C++<br />
Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);<br />
// deux instructions à partir d'ici<br />
Reference<XMultiServiceFactory> oDocMSF (xTextDocument,UNO_QUERY);<br />
// Ne pas oublier la directive d'inclusion : #include <com/sun/star/text/XTextTable.hpp><br />
Reference <XTextTable> xTable (oDocMSF->createInstance(<br />
OUString::createFromAscii("com.sun.star.text.TextTable")),UNO_QUERY);<br />
</source><br />
<br />
qui utilise le style "deux instructions" et les interfaces <idl>com.sun.star.text.XTextDocument</idl> et <idl>com.sun.star.text.XTextTable</idl>. Avec le style "trois instructions", on obtient l'interface comme présenté ci-dessous :<br />
<br />
<source lang="cpp"><br />
//Listing 21 Inserting a Table in a OOoWriter Document<br />
// C++<br />
Reference<XMultiServiceFactory> oDocMSF (xTextDocument,UNO_QUERY);<br />
<br />
Reference< XInterface > textTable = oDocMSF->createInstance(<br />
OUString::createFromAscii("com.sun.star.text.TextTable") );<br />
// Ne pas oublier la directive d'inclusion : #include <com/sun/star/text/XTextTable.hpp><br />
Reference< XTextTable > xTable(textTable, UNO_QUERY);<br />
</source><br />
<br />
Notez que ces deux méthodes nécessitent une directive d'inclusion (et donc la construction) du fichier hpp correspondant (ici XtextTable.hpp) en travaillant comme pour [[Documentation/FR/Fichiers_IDL_et_C%2B%2B#Les_trois_.C3.A9tapes_pour_l.27obtention_d.27une_interface|l'obtention d'une interface en trois étapes]]. Mais le service ne nécessite pas de fichier d'inclusion car il est obtenu par une méthode (nommée «createInstance» dans ce cas) et de toute façon il est transtypé dans une <idl>com.sun.star.uno.XInterface</idl> (voir la règle 3 ci-dessus). <br />
<br />
Nous donnons un schéma du chemin dans l'arbre IDL pour résumer ce dont nous venons de parler. Remarquez que dans ce chemin on repère très vite la situation par la présence de l'interface <idl>com.sun.star.uno.XInterface</idl> qui n'aurait aucune autre raison d'être présente.<br />
<br />
[[Image:ComplexUNOQUERY2.png|center|thumb|600px|Obtention d'un service]]<br />
<br />
'''Dernière question :''' est-il possible de partir de l'interface XMultiServiceFactory pour obtenir n'importe quelle interface ? La réponse est non. Regardez le code ci-dessous où j'ai pris rOfficeServiceManager au lieu de oDocMSF parceque c'est une interface XmultiServiceFactory aussi.<br />
<br />
<source lang="cpp"><br />
//Listing 22 Wrong code<br />
// C++<br />
// Reference<XMultiServiceFactory> oDocMSF (xTextDocument,UNO_QUERY);<br />
// using rOfficeServiceManager instead oDocMSF<br />
Reference< XInterface > textTable = rOfficeServiceManager->createInstance(<br />
OUString::createFromAscii("com.sun.star.text.TextTable") );<br />
Reference< XTextTable > xTable(textTable, UNO_QUERY);<br />
if (!xTable.is()) {<br />
printf("Erreur creation XTextTable interface !\n");<br />
return 1;<br />
}<br />
</source><br />
<br />
Ce code se compile mais donne une erreur d'exécution. Cela signifie que l'on ne peut pas utiliser n'importe quelle interface <idl>com.sun.star.lang.XMultiServiceFactory</idl> pour obtenir n'importe quelle autre Interface. <br />
<br />
{{Documentation/Caution|Si vous travaillez avec un document demandez son interface <code>XMultiServiceFactory</code> correspondante avant d'envisager l'obtention d'un service particulier pour ce document.}}<br />
<br />
====Un autre exemple déjà présenté====<br />
Avant d'aller plus en avant, notez qu'un code [[FR/Documentation/L%27automation_d%27OpenOffice.org_avec_un_binaire_ex%C3%A9cutable#Introduction_au_Bootstrapping|utilisé plusieurs fois jusqu'ici]], peut trouver des explications même si l'interface XMultiServiceFactory n'est pas encore associée à un document à ce stade du code :<br />
<br />
<source lang="cpp"><br />
//Listing 23 code de démarrage (bootstrap)<br />
// C++<br />
int main( ) {<br />
//retrieve an instance of the remote service manager<br />
Reference< XMultiServiceFactory > rOfficeServiceManager;<br />
rOfficeServiceManager = ooConnect();<br />
<br />
//get the desktop service using createInstance returns an XInterface type<br />
Reference< XInterface > Desktop = rOfficeServiceManager->createInstance(<br />
OUString::createFromAscii( "com.sun.star.frame.Desktop" ));<br />
<br />
//query for the XComponentLoader interface<br />
Reference< XComponentLoader > rComponentLoader (Desktop, UNO_QUERY);<br />
</source><br />
<br />
Facile de retrouver le style "trois instructions" pou obtenir l'interface <idl>com.sun.star.frame.XComponentLoader</idl> en passant par le service <idl>com.sun.star.frame.Desktop</idl> n'est-ce pas ?<br />
<br />
Voici en résumé de manière schématique, le chemin dans l'arbre IDL correspondant au code ci-dessus :<br />
[[Image:ch4fig2Componentloader.png|center|thumb|600px|Obtention de l'interface XComponentLoader]]<br />
{{Documentation/Note|<br />
Je ferai l'effort, dans la suite du document, de systématiquement montrer le changement de type du service en interface <idl>com.sun.star.uno.XInterface</idl> dans mes schémas. Il n'y a aucune autre raison de trouver cette interface dans un arbre IDL, et cela rendra plus facile le repérage de cette opération.}}<br />
<br />
==Correspondances pour les modules et interfaces==<br />
On aborde très simplement, sans entrer dans les détails, la correspondance entre fichier IDL et le code C++ généré. Ce problème a été partiellement traité dans des cas très particuliers :<br />
*[[Documentation/FR/LanguageCpp#Aller_plus_loin_avec_le_probl.C3.A8me_des_types_.C3.A9num.C3.A9r.C3.A9s|Les types énuérés]]<br />
*[[Documentation/FR/LanguageCpp#Aller_plus_loin_:_les_constantes_UNO|Les constantes]]<br />
*[[Documentation/FR/OpenOffice_Calc#Rechercher_les_positions_absolues_X_et_Y_d.27une_cellule|Les structures]]<br />
<br />
Voir le [[Documentation/DevGuide/ProUNO/C%2B%2B/Type_Mappings|Developer's Guide]] pour un traitement plus complet.<br />
<br />
Continuons donc par d'autres exemples :<br />
<source lang="idl"><br />
//Listing 153<br />
// IDL <br />
module M <br />
{ struct E { long L; <br />
}; <br />
}; <br />
</source><br />
est compilé en C++ comme<br />
<source lang="cpp"> <br />
//Listing 154<br />
// C++ <br />
namespace M <br />
{ struct E <br />
{ Long L; }; <br />
}<br />
</source><br />
et on peut faire référence à E en dehors de M par M::E. D'autre part une instruction de nommage peut être utilisée pour référer cette structure simplement comme E : <br />
<source lang="cpp"><br />
//Listing 155<br />
// C++ <br />
using namespace M; <br />
E e;<br />
e.L = 3; <br />
</source><br />
Une autre alternative est d'employer la directive de nommage seulement pour M::E : <br />
<source lang="cpp"><br />
//Listing 156<br />
// C++ <br />
using M::E;<br />
E e;<br />
e.L = 3;<br />
</source><br />
Une interface est réalisée à l'aide d'une classe C++ qui contient les définitions des types, constantes et exceptions définies dans l'interface. L'exemple ci-dessous montre le comportement de cette correspondance pour une interface :<br />
<source lang="idl"><br />
//Listing 157<br />
// IDL<br />
interface A{<br />
struct S {<br />
short field;<br />
};<br />
};<br />
</source><br />
est compilée en :<br />
<source lang="cpp"> <br />
//Listing 158<br />
// C++<br />
class SAL_NO_VTABLE A {<br />
struct S {<br />
short fiel;<br />
};<br />
}; //A <br />
</source><br />
On peut utiliser aussi :<br />
<source lang="cpp"><br />
//Listing 159<br />
// Conformant uses<br />
A::S s; // declare a struct variable <br />
s.field = 3; // field access<br />
// Non-conformant uses: <br />
// one cannot declare an instance of an interface class... <br />
A a; // ...nor declare a pointer to an interface class... <br />
A *p; // ...nor declare a reference to an interface class. <br />
void f(A &r);<br />
</source><br />
<br />
=Le service de Core reflection et son interface XIdlReflection =<br />
<br />
Beaucoup de points d'entrée pour l'introspection sont décrits dans le [[Documentation/DevGuide/AdvUNO/UNO_Reflection_API|Developer's Guide]]. On en donne quelques uns et montrons le moyen d'en utiliser en C++.<br />
<br />
Avant d'aborder le problème technique, rappelons l'intérêt des outils d'introspection. Nous avons sans cesse répété dans ce chapitre que la grande difficulté de la programmation UNO est de savoir à tout moment, quels sont les services et interfaces disponibles. Cette information est contenue dans les fichiers IDL, mais, de mon point de vue, partiellement seulement. C'est pour cela qu'un outil d'introspection est intéressant : il peut à tout moment vous fournir l'information tant convoitée. <br />
<br />
==L'introspection et OOoBasic==<br />
{{Documentation/Caution|Cette section n'a pas pour vocation de remplacer l'inestimable outil de Bernard Marcelly, a savoir, XRay. Voir pour cela une description [[Extensions_development_basic#Xray_tool|dans ce wiki]].}}<br />
<br />
OooBasic permet beaucoup de choses et en particulier l'introspection. Le code de Danny Brewer présenté ici : http://www.oooforum.org/forum/viewtopic.php?t=8737 nous montre comment ? Examinons un peu plus en détail ce code :<br />
<source lang="oobas"><br />
'Listing 160 Code d'exploration de la base de registre en OOoBasic<br />
REM ***** BASIC *****<br />
Sub Main <br />
oReflection = createUnoService( "com.sun.star.reflection.CoreReflection" ) <br />
oInfo = oReflection.forName( "nom.dannybrewer.test.XDannysCalcFunctions1" ) <br />
aMethods = oInfo.getMethods() <br />
For i = 0 To UBound( aMethods ) <br />
oMethod = aMethods( i ) <br />
Print oMethod.getName() <br />
Next <br />
End Sub<br />
</source><br />
puis nous créons un fichier IDL : <br />
<source lang="idl"><br />
//Listing 161 Fichier IDL d'exemple<br />
// IDL<br />
#include <com/sun/star/uno/XInterface.idl><br />
#include <com/sun/star/lang/XInitialization.idl><br />
<br />
module my_module<br />
{<br />
<br />
interface XSomething : com::sun::star::uno::XInterface<br />
{<br />
long getCount();<br />
void setCount( [in] long nCount );<br />
long increment();<br />
long decrement();<br />
};<br />
<br />
service MyService<br />
{<br />
interface XSomething;<br />
};<br />
};<br />
</source><br />
Avec ce fichier IDL il nous est possible de créer un fichier rdb et de l'enregistrer dans la base de registre. Maintenant OpenOffice.org fonctionne comme si nous avions une interface supplémentaire même si l'on n'a pas encore écrit le code correspondant. Evidemment, il nous est impossible d'utiliser ce service puis qu'il n'y a pas de code correspondant, mais on peut le voir. <br />
Pour cela on modifie légèrement le code de Danny : <br />
<source lang="oobas"><br />
'Listing 162<br />
REM ***** BASIC *****<br />
'From Danny : http://www.oooforum.org/forum/viewtopic.php?t=8737 <br />
Sub Main<br />
oReflection = createUnoService( "com.sun.star.reflection.CoreReflection" )<br />
oInfo = oReflection.forName( "my_module.XSomething" )<br />
aMethods = oInfo.getMethods()<br />
'XRay.XRay oInfo<br />
print UBound( aMethods )+1 & " methods : ****"<br />
For i = 0 To UBound( aMethods )<br />
oMethod = aMethods( i )<br />
Print oMethod.getName()<br />
Next<br />
<br />
aTypes = oInfo.getTypes()<br />
print UBound( aTypes )+1 & " types : ****"<br />
For i = 0 To UBound( aTypes )<br />
oType = aTypes( i )<br />
Print "Types : " + oType.getName()<br />
Next<br />
<br />
aInterfaces = oInfo.getInterfaces()<br />
print UBound( aInterfaces )+1 & " interfaces : ****"<br />
For i = 0 To UBound( aInterfaces )<br />
oInterface = aInterfaces( i )<br />
Print "Interfaces : " + oInterface.getName()<br />
Next<br />
End Sub <br />
</source><br />
qui lancé, produit l'affichage suivant :<br />
<pre><br />
7 methods : ****<br />
queryInterface acquire release getCount setCount increment decrement<br />
3 types : ****<br />
Types : com.sun.star.reflection.XIdlClass<br />
Types : com.sun.star.lang.XTypeProvider<br />
Types : com.sun.star.uno.XWeak<br />
0 Interfaces : ****<br />
</pre><br />
où l'on peut voir parmi d'autres choses les quatre méthodes données dans le fichier IDL.<br />
<br />
Il est possible de retrouver un peu plus d'information sur les méthodes par exemple. Si vous voulez retrouver tout ce que vous avez dans les fichiers IDL, y compris le nom et type des paramètres, l'extrait de code OOoBasic suivant fait l'affaire :<br />
<source lang="oobas"><br />
For i = LBound( oMethods ) To UBound( oMethods )<br />
oMethod = oMethods( i )<br />
' Check the method's interface to see if<br />
' these aren't the droids you're looking for.<br />
sString = oMethod.getReturnType().getName() & " " & oMethod.getName() & "("<br />
parametersInfo = oMethod.getParameterInfos()<br />
if UBound(parametersInfo) > 0 then<br />
for ii=0 to UBound(parametersInfo)<br />
if parametersInfo(ii).aMode = com.sun.star.reflection.ParamMode.IN Then<br />
stringType = "IN "<br />
elseif parametersInfo(ii).aMode = com.sun.star.reflection.ParamMode.OUT Then<br />
stringType = "OUT "<br />
else<br />
stringType = "INOUT "<br />
end if <br />
sString = sString & stringType & ParametersInfo(ii).aType.getName() & " " & parametersInfo(ii).aName<br />
if ii < UBound(parametersInfo) Then sString = sString & ", "<br />
Next<br />
end if<br />
sString = sString & ")"<br />
' Faire quelquechose avec sString ici, par exemple l'afficher<br />
Next<br />
</source><br />
Pour aller plus loin en C++ voyez la section suivante sur l'interface XdlRefection.<br />
<br />
{{Documentation/Note|<br />
Vous pouvez modifier la base de registre d'Openoffice sans écrire aucun code. Pour cela vous avez besoin d'un fichier IDL et son fichier rdb correspondant. Ajouter le fichier rdb dans le répertoire Unix “<Ooo>/program/unorc” ou le répertoire windows “<Ooo>/program/uno.ini”.}}<br />
<br />
== L'interface XIdlReflection ==<br />
<br />
L'interface <idl>com.sun.star.reflection.XIdlReflection</idl> est décrite dans la section [[Documentation/DevGuide/AdvUNO/UNO_Reflection_API | CoreReflection Service in Developer's Guide]]. Cette interface est aussi décrite [[Documentation/FR/Interface_XIDLReflection |ici et en français]] et avec en prime du code C++.<br />
<br />
== The XIntrospection Interface ==<br />
<br />
Cette interface <idl>com.sun.star.beans.XIntrospection</idl> est décrite [[FR/Documentation/XIntrospection_Interface |ici avec des exemples de code]]. Un autre exemple de code est donné dans la section [[Documentation/FR/Utilitaires_C%2B%2B|Utilitaires C++]].<br />
Voir aussi [[Extensions_development_basic#Introducing_the_OpenOffice.org_API|Introducing the OpenOffice.org_API]] et [[Extensions_development_basic#Introspection|OOoBasic Introspection]] et [[Documentation/DevGuide/AdvUNO/UNO_Reflection_API | Developer's Guide]].<br />
<br />
= Utilisation de l'Inspecteur Java =<br />
Pour une introduction de la programmation en Java pour OOo, voir [[JavaEclipseTuto|Java and Eclipse tutorial]]. Ce point n'est pas abordé dans ce tutorial : nous sommes seulement intéressé ici dans l'utilisation d'un composant Java à partir d'un programme C++.<br />
<br />
Il est possible, en principe, d'utiliser l'Inspector Java à partir de n'importe quel langaga parcequ'il s'agit justement d'un composant. La méthode d'utilisation est très simple :<br />
<br />
1°) Compiler l'exemple Java dans <OpenOffice.org_SDK>/examples/java/Inspector après ajout de SDK_AUTO_DEPLOYMENT = YES au début du makefile.<br />
<br />
2°) Créer un exemple OOoBasic, par exemple (OOo1.1.X) :<br />
<source lang="oobas"><br />
'Listing 17 Simple OOoBasic example to call the Java Inspector<br />
<br />
REM ***** BASIC *****<br />
Sub JavaInspector <br />
o = createUnoService("org.OpenOffice.InstanceInspector")<br />
'XRay o<br />
oReflection = createUnoService( "com.sun.star.reflection.CoreReflection" )<br />
o.inspect(oReflection) <br />
End Sub<br />
</source><br />
{{Documentation/Note|<br />
Pour une utilisation du Java Inspector plus récent, voir [[Object_Inspector#Calling_from_a_Basic_Macro|Calling from a Basic Macro]]}}.<br />
Si Java n'est pas correctement intallé l'exécution de ce programme déclenchera l'ouverture d'une boîte de dialogue qui vous permettra de définir votre machine virtuelle JRE à condition de savoir où elle se trouve.<br />
<br />
Nous voyons ci-dessous le résultat de l'exécution de ce programme.<br />
<br />
[[Image:Inspector3.png|Old Java Object Inspector]]<br />
<br />
Notre problème est d'utiliser l'Inspecteur java à partir du C++. J'ai rencontré plusieurs problème pour faire cela et je présente la voie que j'ai choisie :<br />
<br />
# construction d'un fichier urd à partir du fichier IDL (dans le makefile)<br />
# Ne pas oublier d'enregistrer le fichier urd dans la base de registres (avec le makefile)<br />
# ajouter org.OpenOffice.XInstanceInspector dans les TYPES du makefile<br />
# copie du fichier IDL de <OpenOffice.org1.1_SDK>/examples/java/Inspector/XInstanceInspector.idl vers <OpenOffice.org1.1_SDK>/idl/org/OpenOffice/ XInstanceInspector.idl<br />
# ajout de l'inclusion #include <org/OpenOffice/XInstanceInspector.hpp> et de l'espace de nommage namespace org::OpenOffice;<br />
# ajout de ce code<br />
<source lang="cpp"><br />
// C++<br />
Any toInspect;<br />
toInspect <<= rDesktop;<br />
Reference< XInstanceInspector > xinspect (rOfficeServiceManager->createInstance(<br />
OUString::createFromAscii( "org.OpenOffice.InstanceInspector" )),UNO_QUERY);<br />
xinspect->inspect(toInspect);<br />
</source><br />
Et cela fonctionne comme en OOoBasic. Le makefile correspondant pour Linix est :<br />
<pre><br />
#Listing 18 Simple Makefile to compile a Java Inspector C++ call<br />
# very simple makefile<br />
HELPER = ReflectionHelper<br />
CXXFILE = office_connect.cxx<br />
OBJFILE = office_connect.o<br />
OUTBIN = office_connect<br />
OUT_COMP_INC = ../../../../LINUXexample.out/inc<br />
OUT_COMP_OBJ = ../../../../LINUXexample.out/obj<br />
OUT_COMP_BIN = ../../../../LINUXexample.out/bin<br />
# added for Inspector<br />
OUT_COMP_URD = $(OUT_COMP_BIN)<br />
# end added<br />
COMPONENT_RDB = $(OUT_COMP_BIN)/office_connect.rdb<br />
CC_FLAGS = -c -O -fpic -fno-rtti<br />
CC_DEFINES = -DUNX -DGCC -DLINUX -DCPPU_ENV=gcc3<br />
PS = /<br />
TYPES := \<br />
com.sun.star.uno.XNamingService \<br />
....<br />
com.sun.star.container.XHierarchicalNameAccess \<br />
org.OpenOffice.XInstanceInspector<br />
# last line added<br />
<br />
TYPESLIST = $(foreach t,$(TYPES),-T$(t))<br />
GENHPPFILES = $(foreach t,$(TYPES),$(OUT_COMP_INC)/$(subst .,/,$(t)).hpp)<br />
<br />
ALL : \<br />
ProUNOCppBindingExample<br />
<br />
# added for Inspector<br />
#building urd file<br />
$(OUT_COMP_URD)/XInstanceInspector.urd : ../../../../idl/org/OpenOffice/XInstanceInspector.idl<br />
-mkdir -p $(OUT_COMP_URD)<br />
idlc -I. -I../../../../idl -O$(OUT_COMP_URD) ../../../../idl/org/OpenOffice/XInstanceInspector.idl<br />
<br />
# end added<br />
<br />
#office_connectrc is provided with SDK<br />
$(OUT_COMP_BIN)/office_connectrc : office_connectrc<br />
-mkdir -p $(OUT_COMP_BIN)<br />
cp office_connectrc $(OUT_COMP_BIN)/office_connectrc<br />
<br />
$(COMPONENT_RDB) : $(OUT_COMP_URD)/XInstanceInspector.urd<br />
-mkdir -p $(OUT_COMP_BIN)<br />
# added for Inspector<br />
regmerge $(COMPONENT_RDB) /UCR $(OUT_COMP_URD)/XInstanceInspector.urd<br />
# end added<br />
regmerge $(COMPONENT_RDB) / "/usr/lib/openoffice/program/types.rdb"<br />
@echo --------------------------------------------------------------------------------<br />
@echo Register necessary runtime components in $(COMPONENT_RDB)<br />
@echo --------------------------------------------------------------------------------<br />
regcomp -register -r $(COMPONENT_RDB) -c connector.uno.so<br />
regcomp -register -r $(COMPONENT_RDB) -c remotebridge.uno.so<br />
regcomp -register -r $(COMPONENT_RDB) -c bridgefac.uno.so<br />
regcomp -register -r $(COMPONENT_RDB) -c uuresolver.uno.so<br />
# @echo bla > $@<br />
<br />
$(GENHPPFILES) : $(subst /,$(PS),$(@D))<br />
mkdir -p $(subst /,$(PS),$(@D))<br />
# modified for Inspector cppumaker -Gc -BUCR -O$(OUT_COMP_INC) $(TYPESLIST) "/usr/lib/openoffice/program/types.rdb"<br />
cppumaker -Gc -BUCR -O$(OUT_COMP_INC) $(TYPESLIST) $(COMPONENT_RDB)<br />
<br />
$(OUT_COMP_OBJ)/$(OBJFILE) : $(CXXFILE) $(GENHPPFILES) $(HELPER).hpp<br />
-mkdir -p $(subst /,$(PS),$(@D))<br />
gcc $(CC_FLAGS) $(CC_INCLUDES) -I. -I/usr/include -I$(OUT_COMP_INC)/examples \<br />
-I../../../../include -I$(OUT_COMP_INC) $(CC_DEFINES) -o$(OUT_COMP_OBJ)/$(OBJFILE) $(CXXFILE)<br />
<br />
$(OUT_COMP_OBJ)/$(HELPER).o : $(HELPER).cxx $(HELPER).hpp<br />
-mkdir -p $(OUT_COMP_OBJ)/<br />
gcc $(CC_FLAGS) $(CC_INCLUDES) -I. -I/usr/include -I$(OUT_COMP_INC)/examples \<br />
-I../../../../include -I$(OUT_COMP_INC) $(CC_DEFINES) -o$(OUT_COMP_OBJ)/$(HELPER).o $(HELPER).cxx<br />
<br />
<br />
$(OUT_COMP_BIN)/$(OUTBIN) : $(OUT_COMP_OBJ)/$(OBJFILE) $(OUT_COMP_OBJ)/$(HELPER).o<br />
-mkdir -p $(OUT_COMP_BIN)<br />
gcc -Wl -export-dynamic -L../../../../LINUXexample.out/lib -L../../../../linux/lib -L/usr/lib/openoffice/program \<br />
$(OUT_COMP_OBJ)/$(HELPER).o \<br />
-o$(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_OBJ)/$(OBJFILE) -lcppuhelpergcc3 -lcppu -lsalhelpergcc3 -lsal -lstlport_gcc<br />
<br />
<br />
ProUNOCppBindingExample : $(COMPONENT_RDB) $(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_BIN)/office_connectrc<br />
@echo --------------------------------------------------------------------------------<br />
@echo Please use one of the following commands to execute the examples!<br />
@echo<br />
@echo make office_connect.run<br />
@echo --------------------------------------------------------------------------------<br />
<br />
office_connect.run : $(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_BIN)/office_connectrc<br />
cd $(OUT_COMP_BIN) && $(OUTBIN)<br />
</pre><br />
<br />
{{Documentation/Note|'''Note 1''' : [[Object Inspector|The New Object Inspector]] apparaît dans le SDK après la version 2.0. Il est plus complexe et capable de générer du code Java, C++ ou OOoBasic. Je n'ai pas testé le code ci-dessus avec [[Object Inspector|the new object inspector]] mais ne vois pas pourquoi cela ne fonctionnerait pas correctement.}}<br />
<br />
{{Documentation/Note|'''Note 2''' : [[Documentation/FR/OpenOffice_Writer#Aller_plus_loin_avec_l.27Inspector_Java|Un petit exemple]] avec [[Object Inspector|the new object inspector]] peut être trouvé dans ce document.}}<br />
<br />
{{Documentation/Caution|Je pense qu'il y a bien plus simple pour utiliser l'inspecteur Java, en particulier qu'il n'y a pas lieu de modifier le makefile (sauf pour l'interface org.OpenOffice.XInstanceInspector). Il doit en effet pouvoir s'utiliser comme n'importe quel autre service et ne nécessite donc pas la céation d'un fichier URD à partir d'un fichier IDL. Je pense avoir manqué de recul sur ce coup là et qu'il me faudra un jour ou l'autre reprendre ce problème à zéro.}}<br />
<br />
=Traduire des programmes OooBasic en C++=<br />
<br />
La traduction des programmes OooBasic en C++ n'est pas si immédiate que cela. Les interfaces et attributs vus par les programmes OooBasic sont construits à travers un pont (bridge) pour des questions de facilité. Alors ce qui est vu en OooBasic ne sera pas forcément vu en C++. Une des conséquences de tout cela est qu'il est impossible de réaliser cette traduction sans passer un peu de temps avec les fichiers IDL.<br />
<br />
Quand j'ai abordé [[Documentation/FR/OpenOffice_Writer|Writer]], j'ai laissé le lecteur résoudre un certain nombre de problèmes (particulièrement les problèmes de curseurs). Nous choisissons ces problèmes ici comme exemple. Nous commençons par donner le programme OOoBasic de départ.<br />
<br />
<source lang="oobas"><br />
'Listing 36 Simple OOoBasic program to translate<br />
REM **** OOoBasic<br />
Dim MyDocument As Object, MyText As Object<br />
Dim MyCursor As Object<br />
MyDocument = ThisComponent<br />
MyText = MyDocument.Text<br />
MyCurseur= MyTexte.createTextCursor<br />
MyCurseur.goRight(1, false) ' move right one character<br />
MyCurseur.goLeft(2, true) ' select the two previous characters<br />
</source><br />
<br />
Toutes les instructions OOoBasic pour bouger le curseur sont résumées dans le tableau ci-dessous :<br />
<br />
; OOoBasic instructions<br />
{| border cellspacing="0" width="650"<br />
|- style = "background:#b3e2d1;text-align:center"<br />
| |Méthode||Signification<br />
|- style="text-align:left"<br />
| goRight(n, false)||bouge le curseur d'un nombre spécifié de caractères vers la droite<br />
|- style="text-align:left"<br />
|goLeft(n, false) ||bouge le curseur d'un nombre spécifié de caractères vers la gauche<br />
|- style="text-align:left"<br />
|gotoStart(false) ||bouge le curseur au début du texte<br />
|- style="text-align:left"<br />
|gotoEnd(false)||bouge le curseur à la fin du texte<br />
|- style="text-align:left"<br />
|gotoStartOfParagraph(false)||bouge le curseur au début du paragraphe courant<br />
|- style="text-align:left"<br />
|gotoEndOfParagraph(false) ||bouge le curseur à la fin du paragraphe courant<br />
|- style="text-align:left"<br />
|gotoNextParagraph(false)||bouge le curseur au prochain paragraphe<br />
|- style="text-align:left"<br />
|gotoPreviousParagraph(false) ||bouge le curseur au précédent paragraphe<br />
|- style="text-align:left"<br />
|gotoNextWord(false) ||bouge le curseur au prochain mot<br />
|- style="text-align:left"<br />
|gotoPreviousWord(false) ||bouge le curseur au précédent mot<br />
|- style="text-align:left"<br />
|gotoStartOfWord(false) ||bouge le curseur au début du mot courant<br />
|- style="text-align:left"<br />
|gotoEndOfWord(false) ||bouge le curseur à la fin du mot courant<br />
|- style="text-align:left"<br />
|gotoNextSentence(false) ||bouge le curseur au début de la prochaine phrase<br />
|- style="text-align:left"<br />
|gotoPreviousSentence(false) ||bouge le curseur au début de la précédente phrase<br />
|- style="text-align:left"<br />
|gotoStartOfSentence(false) ||bouge le curseur au début de la phrase courante<br />
|- style="text-align:left"<br />
|gotoEndOfSentence(false) ||bouge le curseur à la fin de la phrase courante<br />
|}<br />
<br />
Mais si vous voulez traduire l'utilisation de ces fonctions en C++, il vous faut obtenir les interfaces en partant de l'interface XtextCursor interface (voir plus bas en Listing 41). Cela rend la traduction difficile. Par exemple trois interfaces curseur différentes en utilisant les méthodes OOoBasic du programme de départ. Il est grand temps de montrer les fichiers IDL correspondants.<br />
<br />
Commençons par la première de toutes, l'interface <idl>com.sun.star.text.XWordCursor</idl> est montrée maintenant :<br />
<source lang="idl"><br />
//Listing 37 XWordCursor interface (IDL file)<br />
// IDL<br />
module com { module sun { module star { module text { <br />
interface XWordCursor: com::sun::star::text::XTextCursor<br />
{ <br />
boolean isStartOfWord(); <br />
boolean isEndOfWord(); <br />
boolean gotoNextWord( [in] boolean bExpand ); <br />
boolean gotoPreviousWord( [in] boolean bExpand ); <br />
boolean gotoEndOfWord( [in] boolean bExpand ); <br />
boolean gotoStartOfWord( [in] boolean bExpand ); <br />
}; <br />
}; }; }; }; <br />
</source><br />
<br />
L'interface <idl>com.sun.star.text.XParagraphCursor</idl> est montrée maintenant :<br />
<source lang="idl"><br />
//Listing 38 XParagraphCursor interface (IDL file)<br />
// IDL<br />
module com { module sun { module star { module text { <br />
interface XParagraphCursor: com::sun::star::text::XTextCursor<br />
{ <br />
com::sun::star::text::XParagraphCursor::isStartOfParagraph<br />
boolean isStartOfParagraph(); <br />
boolean isEndOfParagraph(); <br />
com::sun::star::text::XParagraphCursor::gotoStartOfParagraph<br />
boolean gotoStartOfParagraph( [in] boolean bExpand ); <br />
com::sun::star::text::XParagraphCursor::gotoEndOfParagraph<br />
boolean gotoEndOfParagraph( [in] boolean bExpand ); <br />
boolean gotoNextParagraph( [in] boolean bExpand ); <br />
com::sun::star::text::XParagraphCursor::gotoPreviousParagraph<br />
boolean gotoPreviousParagraph( [in] boolean bExpand ); <br />
<br />
}; <br />
}; }; }; }; <br />
</source><br />
<br />
et pour finir l'interface <idl>com.sun.star.text.XSentenceCursor</idl> : <br />
<source lang="idl"><br />
// Listing 39 XSentenceCursor interface (IDL file)<br />
// IDL<br />
module com { module sun { module star { module text { <br />
interface XSentenceCursor: com::sun::star::text::XTextCursor<br />
{ <br />
boolean isStartOfSentence(); <br />
boolean isEndOfSentence(); <br />
boolean gotoNextSentence( [in] boolean Expand ); <br />
boolean gotoPreviousSentence( [in] boolean Expand ); <br />
boolean gotoStartOfSentence( [in] boolean Expand ); <br />
boolean gotoEndOfSentence( [in] boolean Expand ); <br />
}; <br />
<br />
//============================================================================= <br />
<br />
}; }; }; };<br />
</source><br />
<br />
Si vous voulez savoir quelles interfaces vous pouvez demander il vous faut retrouver le service. Pour notre exemple c'est le service <idl>com.sun.star.text.TextCursor</idl>. Voici son fichier IDL où vous voyez les interfaces que vous pouvez demander.<br />
<br />
<source lang="idl"><br />
//Listing 40 TextCursor service (IDL file)<br />
// IDL<br />
module com { module sun { module star { module text {<br />
service TextCursor<br />
{<br />
service com::sun::star::text::TextRange;<br />
interface com::sun::star::text::XTextCursor;<br />
[optional] interface com::sun::star::text::XWordCursor;<br />
[optional] interface com::sun::star::text::XSentenceCursor;<br />
[optional] interface com::sun::star::text::XParagraphCursor;<br />
interface com::sun::star::beans::XPropertySet;<br />
interface com::sun::star::beans::XPropertyState;<br />
interface com::sun::star::beans::XMultiPropertyStates;<br />
[optional] interface com::sun::star::document::XDocumentInsertable;<br />
[optional] interface com::sun::star::util::XSortable;<br />
};<br />
}; }; }; }; <br />
</source><br />
<br />
Si vous partez de nouveau du Listing 11 il vous faudra un UNO_QUERY pour obtenir l'interface <idl>com.sun.star.text.XWordCursor</idl>.<br />
<source lang="cpp"><br />
//Listing 41 Using XwordCursor Interface<br />
// C++<br />
// Don't forget to add : #include <com/sun/star/text/XWordCursor.hpp><br />
// Don't forget to add "com.sun.star.text.XWordCursor \" in the makefile <br />
Reference < XWordCursor > xWordCursor (xTextCursor,UNO_QUERY);<br />
xWordCursor->gotoNextWord(false); <br />
xWordCursor->gotoNextWord(false); <br />
xWordCursor->gotoNextWord(true);<br />
</source><br />
La traduction peut probablement se faire automatiquement, mais un tel traducteur aurait besoin de connaissances sur les fichiers IDL.<br />
<br />
En passant nous avons encore les huit services disponibles :<br />
<pre><br />
******** Services : 8<br />
com.sun.star.text.TextSortable<br />
com.sun.star.style.ParagraphPropertiesComplex<br />
com.sun.star.style.ParagraphPropertiesAsian<br />
com.sun.star.style.ParagraphProperties<br />
com.sun.star.style.CharacterPropertiesComplex<br />
com.sun.star.style.CharacterPropertiesAsian<br />
com.sun.star.style.CharacterProperties<br />
com.sun.star.text.TextCursor<br />
</pre><br />
<br />
La traduction de OOoBasic en C++ nécessite donc une bonne connaissance des services. Par exemple, le code<br />
<source lang="oobas"><br />
Dim Obj As Object Obj = createUnoService("com.sun.star.frame.Desktop")<br />
</source><br />
est différent de<br />
<source lang="oobas"><br />
Dim RectangleShape As Object<br />
RectangleShape = _ <br />
Spreadsheet.createInstance("com.sun.star.drawing.RectangleShape")<br />
</source><br />
Le deuxième dénote un objet contextuel.<br />
<br />
Les objets contextuels sont généralement créés par une méthode d'objet dont dépend l'objet. La méthode createInstance, définie dans l'interface XMultiServiceFactory, est notamment utilisée dans les objets Document.<br />
<br />
Voir [[FR/Documentation/BASIC_Guide/API_Intro| Introduction à l'API StarOffice]] pour plus d'informations.<br />
<br />
J'ai eu aussi l'occasion de traduire des programmes OOoBasic dans les chapitres [[FR/Documentation/Composants_et_boite_de_dialogue|Composants et boîte de dialogue]]<br />
et [[FR/Documentation/Plus_loin_avec_Composants_et_boites_de_dialogue|Plus loin avec les composants et les boîtes de dialogue]].<br />
<br />
= Retour à la page d'accueil=<br />
<br />
[[Documentation/FR/Cpp_Guide|Page d'accueil du développement C++ à l'aide du SDK]]<br />
<br />
= Voir aussi =<br />
* [[FR/Documentation/BASIC_Guide/API_Intro|Introduction à l'API StarOffice]]<br />
* [[Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno|C++ and UNO tutorial]]<br />
* [[Tutorial_UNO_Library|UNO tutorial]]<br />
* [[Tutorial_UNO_IDL|UNO IDL]]<br />
* [[Uno/Article/Types%26Reflection]] <br />
* [[Documentation/BASIC_Guide/API_Intro|Introduction to the OpenOffice.org API]]<br />
* 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<br />
* Voir aussi [[Object Inspector|The New Object Inspector]]<br />
* [[Extensions_introspection|Extensions Introspection]]<br />
* [[BASIC/UNO_Object_Browser|BASIC UNO Object Browser]]<br />
<br />
[[Category:FR/Cpp_Guide]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Basic/Mapping_of_StructsDocumentation/DevGuide/ProUNO/Basic/Mapping of Structs2016-05-01T06:40:45Z<p>BMarcelly: </p>
<hr />
<div>{{Documentation/DevGuide/ProUNOTOC<br />
|ProUNO2c=block<br />
|Basic=block<br />
|UNOTypes=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/ProUNO/Basic/Mapping of Sequences and Arrays<br />
|NextPage=Documentation/DevGuide/ProUNO/Basic/Mapping of Enums and Constant Groups<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/ProUNO/Basic/{{SUBPAGENAME}}}}<br />
{{DISPLAYTITLE:Mapping of Structs}}<br />
UNO struct types can be instantiated with the <code>Dim As New</code> command as a single instance and array. <br />
<source lang="oobas"><br />
' Instantiate a Property struct<br />
Dim aProperty As New com.sun.star.beans.Property<br />
<br />
' Instantiate an array of Locale structs<br />
Dim Locales(10) As New com.sun.star.lang.Locale<br />
</source><br />
For instantiated polymorphic struct types, there is a special syntax of the <code>Dim As New</code> command, giving the type as a string literal instead of as a name:<br />
<source lang="oobas"><br />
Dim o As New "com.sun.star.beans.Optional<long>"<br />
</source><br />
The string literal representing a UNO name is built according to the following rules:<br />
<br />
* The strings representing the relevant simple UNO types are "<code>boolean</code>", "<code>byte</code>", "<code>short</code>", "<code>long</code>", "<code>hyper</code>", "<code>float</code>", "<code>double</code>", "<code>char</code>", "<code>string</code>", "<code>type</code>", and "<code>any</code>", respectively.<br />
* The string representing a UNO sequence type is "<code>[]</code>" followed by the string representing the component type.<br />
* The string representing a UNO enum, plain struct, or interface type is the name of that type.<br />
* The string representing an instantiated polymorphic struct type is the name of the polymorphic struct type template, followed by "<", followed by the representations of the type arguments (separated from one another by ","), followed by ">".<br />
<br />
No spurious spaces or other characters may be introduced into these string representations.<br />
<br />
UNO struct instances are handled like UNO objects. Struct members are accessed using the . operator. The <code>Dbg_Properties</code> property is supported. The properties <code>Dbg_SupportedInterfaces</code> and <code>Dbg_Methods</code> are not supported because they do not apply to structs. Inspectors <b>[[Extensions_development_basic#Xray_tool|Xray tool]] or [http://extensions.services.openoffice.org/project/MRI MRI tool]</b> can display UNO struct instances.<br />
<source lang="oobas"><br />
' Instantiate a Locale struct<br />
Dim aLocale As New com.sun.star.lang.Locale<br />
<br />
' Display properties<br />
MsgBox aLocale.Dbg_Properties<br />
<br />
' Access “Language” property<br />
aLocale.Language = "en"<br />
</source><br />
Objects and structs are different. Objects are handled as references and structs as values. When structs are assigned to variables, the structs are copied. This is important when modifying an object property that is a struct, because a struct property has to be reassigned to the object after reading and modifying it.<br />
<br />
In the following example, <code>oExample</code> is an object that has the properties <code>MyObject</code> and <code>MyStruct</code>. <br />
<br />
* The object provided by <code>MyObject</code> supports a string property <code>ObjectName</code>.<br />
* The struct provided by <code>MyStruct</code> supports a string property <code>StructName</code>. <br />
Both <code>oExample.MyObject.ObjectName</code> and <code>oExample.MyStruct.StructName</code> should be modified. The following code shows how this is done for an object:<br />
<source lang="oobas"><br />
' Accessing the object<br />
Dim oObject<br />
oObject = oExample.MyObject<br />
oObject.ObjectName = “Tim” ' Ok!<br />
<br />
' or shorter<br />
<br />
oExample.MyObject.ObjectName = “Tim” ' Ok!<br />
</source><br />
The following code shows how it is done correctly for the struct (and possible mistakes):<br />
<source lang="oobas"><br />
' Accessing the struct<br />
Dim aStruct<br />
aStruct = oExample.MyStruct ' aStruct is a copy of oExample.MyStruct!<br />
aStruct.StructName = “Tim” ' Affects only the property of the copy!<br />
<br />
' If the code ended here, oExample.MyStruct wouldn't be modified!<br />
<br />
oExample.MyStruct = aStruct ' Copy back the complete struct! Now it's ok!<br />
<br />
' Here the other variant does NOT work at all, because <br />
' only a temporary copy of the struct is modified!<br />
oExample.MyStruct.StructName = “Tim” ' WRONG! oExample.MyStruct is not modified!<br />
</source><br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Professional UNO]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Basic/Getting_Information_about_UNO_ObjectsDocumentation/DevGuide/ProUNO/Basic/Getting Information about UNO Objects2016-05-01T06:39:25Z<p>BMarcelly: /* Inspector tools */</p>
<hr />
<div>{{Documentation/DevGuide/ProUNOTOC<br />
|ProUNO2c=block<br />
|Basic=block<br />
|UNOObjects=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/ProUNO/Basic/Instantiating UNO Services<br />
|NextPage=Documentation/DevGuide/ProUNO/Basic/Mapping of UNO and Basic Types<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/ProUNO/Basic/{{SUBPAGENAME}}}}<br />
{{DISPLAYTITLE:Getting Information about UNO Objects}}<br />
__NOTOC__<br />
The Basic RTL retrieves information about UNO objects. There are functions to evaluate objects during runtime and object properties used to inspect objects during debugging.<br />
<br />
=== Checking for interfaces during runtime ===<br />
<br />
Although Basic does not support the queryInterface concept like C++ and Java, it can be useful to know if a certain interface is supported by a UNO Basic object or not. The function <code>HasUnoInterfaces()</code> detects this.<br />
<br />
The first parameter <code>HasUnoInterfaces()</code> expects is the object that should be tested. Parameter(s) of one or more fully qualified interface names can be passed to the function next. The function returns <code>True</code> if all these interfaces are supported by the object, otherwise <code>False</code>.<br />
<source lang="oobas"><br />
Sub Main<br />
Dim oSimpleFileAccess<br />
oSimpleFileAccess = CreateUnoService( "com.sun.star.ucb.SimpleFileAccess" )<br />
<br />
Dim bSuccess<br />
Dim IfaceName1$, IfaceName2$, IfaceName3$<br />
IfaceName1$ = "com.sun.star.uno.XInterface"<br />
IfaceName2$ = "com.sun.star.ucb.XSimpleFileAccess2"<br />
IfaceName3$ = "com.sun.star.container.XPropertySet"<br />
<br />
bSuccess = HasUnoInterfaces( oSimpleFileAccess, IfaceName1$ )<br />
MsgBox bSuccess ' Displays True because XInterface is supported<br />
<br />
bSuccess = HasUnoInterfaces( oSimpleFileAccess, IfaceName1$, IfaceName2$ )<br />
MsgBox bSuccess ' Displays True because XInterface<br />
' and XSimpleFileAccess2 are supported<br />
<br />
bSuccess = HasUnoInterfaces( oSimpleFileAccess, IfaceName3$ )<br />
MsgBox bSuccess ' Displays False because XPropertySet is NOT supported<br />
<br />
bSuccess = HasUnoInterfaces( oSimpleFileAccess, IfaceName1$, IfaceName2$, IfaceName3$ )<br />
MsgBox bSuccess ' Displays False because XPropertySet is NOT supported<br />
End Sub<br />
</source><br />
=== Testing if an object is a struct during runtime ===<br />
<br />
As described in the section [[Documentation/DevGuide/ProUNO/Basic/Mapping of Structs|Mapping of Structs]] above, structs are handled differently from objects, because they are treated as values. Use the <code>IsUnoStruct()</code> function to check it the UNO Basic object represents an object or a struct. This function expects one parameter and returns <code>True</code> if this parameter is a UNO struct, otherwise <code>False</code>. Example:<br />
<source lang="oobas"><br />
Sub Main<br />
Dim bIsStruct<br />
' Instantiate a service<br />
Dim oSimpleFileAccess<br />
oSimpleFileAccess = CreateUnoService( "com.sun.star.ucb.SimpleFileAccess" )<br />
bIsStruct = IsUnoStruct( oSimpleFileAccess )<br />
MsgBox bIsStruct ' Displays False because oSimpleFileAccess is NO struct<br />
' Instantiate a Property struct<br />
Dim aProperty As New com.sun.star.beans.Property<br />
bIsStruct = IsUnoStruct( aProperty )<br />
MsgBox bIsStruct ' Displays True because aProperty is a struct<br />
bIsStruct = IsUnoStruct( 42 )<br />
MsgBox bIsStruct ' Displays False because 42 is NO struct<br />
End Sub<br />
</source><br />
=== Testing objects for identity during runtime ===<br />
<br />
To find out if two UNO {{PRODUCTNAME}} Basic objects refer to the same UNO object instance, use the function <code>EqualUnoObjects()</code>. Basic is not able to apply the comparison operator = to arguments of type <tt>object</tt>, for example, <code>If Obj1 = Obj2 Then</code> will produce a runtime error.<br />
<source lang="oobas"><br />
Sub Main<br />
Dim bIdentical<br />
Dim oSimpleFileAccess, oSimpleFileAccess2, oSimpleFileAccess3<br />
' Instantiate a service<br />
oSimpleFileAccess = CreateUnoService( "com.sun.star.ucb.SimpleFileAccess" )<br />
oSimpleFileAccess2 = oSimpleFileAccess ' Copy the object reference<br />
bIdentical = EqualUnoObjects( oSimpleFileAccess, oSimpleFileAccess2 )<br />
MsgBox bIdentical ' Displays True because the objects are identical<br />
' Instantiate the service a second time<br />
oSimpleFileAccess3 = CreateUnoService( "com.sun.star.ucb.SimpleFileAccess" )<br />
bIdentical = EqualUnoObjects( oSimpleFileAccess, oSimpleFileAccess3 )<br />
MsgBox bIdentical ' Displays False, oSimpleFileAccess3 is another instance<br />
<br />
bIdentical = EqualUnoObjects( oSimpleFileAccess, 42 )<br />
MsgBox bIdentical ' Displays False, 42 is not even an object<br />
' Instantiate a Property struct<br />
Dim aProperty As New com.sun.star.beans.Property<br />
Dim aProperty2<br />
aProperty2 = aProperty ' Copy the struct<br />
bIdentical = EqualUnoObjects( aProperty, aProperty2 )<br />
MsgBox bIdentical ' Displays False because structs are values<br />
' and so aProperty2 is a copy of aProperty<br />
End Sub<br />
</source><br />
Basic hides interfaces behind {{PRODUCTNAME}} Basic objects that could lead to problems when developers are using API structures. It can be difficult to understand the API reference and find the correct method of accessing an object to reach a certain goal.<br />
<br />
To assist during development and debugging, every UNO object in {{PRODUCTNAME}} Basic has special properties that provide information about the object structure. These properties are all prefixed with <code>Dbg_</code> to emphasize their use for development and debugging purposes. The type of these properties is <code>String</code>. To display the properties use the <code>MsgBox</code> function.<br />
<br />
=== Inspecting interfaces during debugging ===<br />
<br />
The <code>Dbg_SupportedInterfaces</code> lists all interfaces supported by the object. In the following example, the object returned by the function <code>GetProcessServiceManager()</code> described in the previous section is taken as an example object.<br />
<source lang="oobas"><br />
oServiceManager = GetProcessServiceManager()<br />
MsgBox oServiceManager.Dbg_SupportedInterfaces<br />
</source><br />
This call displays a message box:<br />
<br />
[[Image:starbasic_dbg_supportedinterfaces.png|none|277px|thumb|Dbg_SupportedInterfaces Property]]<br />
<br />
The list contains all interfaces supported by the object. For interfaces that are derived from other interfaces, the super interfaces are indented as shown above for <idl>com.sun.star.container.XSet</idl>, which is derived from <idl>com.sun.star.container.XEnumerationAccess</idl> based upon <idl>com.sun.star.container.XElementAccess</idl>.<br />
<br />
{{Documentation/Note|If the text "(ERROR: Not really supported!)" is printed behind an interface name, the implementation of the object usually has a bug, because the object pretends to support this interface (per <idl>com.sun.star.lang.XTypeProvider</idl>, but a query for it fails. For details, see [[Documentation/DevGuide/AdvUNO/UNO Reflection API|UNO Reflection API]]).}}<br />
<br />
=== Inspecting properties during debugging ===<br />
<br />
The <code>Dbg_Properties</code> lists all properties supported by the object through <idl>com.sun.star.beans.XPropertySet</idl> and through get and set methods that could be mapped to Basic object properties:<br />
<source lang="oobas"><br />
oServiceManager = GetProcessServiceManager()<br />
MsgBox oServiceManager.Dbg_Properties<br />
</source><br />
This code produces a message box like the following example:<br />
<br />
[[Image:starbasic_dbg_properties.png|none|thumb|207px|Dbg_Properties]]<br />
<br />
=== Inspecting Methods During Debugging ===<br />
<br />
The <code>Dbg_Methods</code> lists all methods supported by an object. Example:<br />
<source lang="oobas"><br />
oServiceManager = GetProcessServiceManager()<br />
MsgBox oServiceManager.Dbg_Methods<br />
</source><br />
This code displays:<br />
<br />
[[Image:starbasic_dbg_methods.png|none|thumb|465px|Dbg_Methods]]<br />
<br />
The notations used in <code>Dbg_Properties</code> and <code>Dbg_Methods</code> refer to internal implementation type names in Basic. The <code>Sbx</code> prefix can be ignored. The remaining names correspond with the normal Basic type notation. The <code>SbxEMPTY</code> is the same type as <code>Variant</code>. Additional information about Basic types is available in the next chapter.<br />
<br />
{{Documentation/Note|Basic uses the <idl>com.sun.star.lang.XTypeProvider</idl> interface to detect which interfaces an object supports. Therefore, it is important to support this interface when implementing a component that should be accessible from Basic. For details, see [[Documentation/DevGuide/WritingUNO/Writing UNO Components|Writing UNO Components]].}}<br />
<br />
=== Inspector tools ===<br />
Using these <tt>Dbg_</tt> properties is a very crude method to discover the contents of an API objects. Use instead <b>[[Extensions_development_basic#Xray_tool|Xray tool]]</b> or <b>[http://extensions.services.openoffice.org/project/MRI MRI tool]</b>.<br />
<br />
The list of elements may be inconveniently long for MsgBox display. Code is available to write all <tt>Dbg_</tt> elements to a new Writer document. See OpenOffice.org Macros > Tools > Debug > WritedbgInfo. The <tt>Tools</tt> library must be loaded to use this routine:<br />
<source lang="oobas"><br />
GlobalScope.BasicLibraries.LoadLibrary( "Tools" )<br />
Call Tools.WritedbgInfo(MyObject)<br />
</source><br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Professional UNO]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/FirstSteps/How_do_I_know_Which_Type_I_Have%3FDocumentation/DevGuide/FirstSteps/How do I know Which Type I Have?2016-05-01T06:38:15Z<p>BMarcelly: </p>
<hr />
<div>{{Documentation/DevGuide/FirstStepsTOC<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/FirstSteps/Element Access<br />
|NextPage=Documentation/DevGuide/FirstSteps/Example: Hello Text, Hello Table, Hello Shape<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/FirstSteps/{{SUBPAGENAME}}}}<br />
{{DISPLAYTITLE:How Do I Know Which Type I Have?}}<br />
A common problem is deciding what capabilities an object really has, after you receive it from a method.<br />
By observing the code completion in Java IDE, you can discover the base interface of an object returned from a method. You will notice that <tt>loadComponentFromURL()</tt> returns a <idl>com.sun.star.lang.XComponent</idl>. <br />
<br />
By pressing Alt + F1 in the NetBeans IDE you can read specifications about the interfaces and services you are using.<br />
<br />
However, methods can only be specified to return one interface type. The interface you get from a method very often supports more interfaces than the one that is returned by the method (especially when the design of those interfaces predates the availability of multiple-inheritance interface types in UNO). Furthermore, the interface does not tell anything about the properties the object contains. <br />
<br />
Therefore you should use this manual to get an idea how things work. Then start writing code, using the code completion and the API reference.<br />
<br />
In addition, you can try the InstanceInspector, a Java tool which is part of the {{PRODUCTNAME}} SDK examples. It is a Java component that can be registered with the office and shows interfaces and properties of the object you are currently working with.<br />
<br />
In {{PRODUCTNAME}} Basic, you can inspect objects using the following Basic properties.<br />
<br />
<source lang="oobas"><br />
sub main<br />
oDocument = thiscomponent<br />
msgBox(oDocument.dbg_methods)<br />
msgBox(oDocument.dbg_properties)<br />
msgBox(oDocument.dbg_supportedInterfaces)<br />
end sub<br />
</source><br />
<br /><br />
For a complex object, these <tt>msgBox</tt> calls will run right off the screen. Try the following, instead:<br />
<br />
<source lang="oobas"><br />
sub main<br />
oDocument = thiscomponent<br />
GlobalScope.BasicLibraries.LoadLibrary( "Tools" )<br />
Call Tools.WritedbgInfo(oDocument)<br />
end sub<br />
</source><br />
<br />
This produces a new Writer document, containing the retrieved information.<br />
<br />
<br />
<br />
Using these DBG properties is a very crude method to discover the contents of an API objects. Use instead <b>[[Extensions_development_basic#Xray_tool|Xray tool]] or [http://extensions.services.openoffice.org/project/MRI MRI tool]</b>.<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/First Steps]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/BASIC_Guide/UNO_ToolsDocumentation/BASIC Guide/UNO Tools2016-05-01T06:36:33Z<p>BMarcelly: /* Debugging tools */</p>
<hr />
<div>{{DISPLAYTITLE:Tools for Working With UNO}}<br />
{{Documentation/BASICGuideTOC/v2<br />
|ShowPrevNext=block<br />
|ShowPrevPage=block<br />
|PrevPage=Documentation/BASIC Guide/Modules, Services and Interfaces<br />
|NextPage=Documentation/BASIC Guide/Interface Overview<br />
|api=block<br />
}}<br />
<br />
The question remains as to which objects — or services if we are going to remain with UNO terminology — support which properties, methods and interfaces and how these can be determined. In addition to this guide, you can get more information about objects from the following sources: the <tt>supportsService</tt> method, the debug methods as well as the Developer's Guide, and the API reference. <br />
<br />
== The <tt>supportsService</tt> Method ==<br />
<br />
A number of UNO objects support the <tt>supportsService</tt> method, with which you can establish whether an object supports a particular service. The following call, for example, determines whether the <tt>TextElement</tt> object supports the <idl>com.sun.star.text.Paragraph</idl> service.<br />
<br />
<source lang="oobas"><br />
Ok = TextElement.supportsService("com.sun.star.text.Paragraph")<br />
</source><br />
<br />
== Debug Properties ==<br />
<br />
Every UNO object knows what properties, methods and interfaces it already contains. {{OOo}} Basic provides properties that return these in the form of a string containing a list. The corresponding properties are: <br />
<br />
;<tt>DBG_properties</tt>:returns a string containing all properties of an object<br />
;<tt>DBG_methods</tt>:returns a string containing all methods of an object <br />
;<tt>DBG_supportedInterfaces</tt>:returns a string containing all interfaces which support an object.<br />
<br />
The following program code shows how <tt>DBG_properties</tt> and <tt>DBG_methods</tt> can be used in real-life applications. It first creates the <idl>com.sun.star.frame.Desktop</idl> service and then displays the supported properties and methods in message boxes.<br />
<br />
<source lang="oobas"><br />
Dim Obj As Object<br />
Obj = createUnoService("com.sun.star.frame.Desktop")<br />
<br />
MsgBox Obj.DBG_Properties<br />
MsgBox Obj.DBG_methods<br />
</source><br />
<br />
When using <tt>DBG_properties</tt>, note that the function returns all properties that the services offered by the object can theoretically support. No assurances are, however, provided for whether these can also be used by the object in question. In very rare cases, before calling up some property, use the <tt>IsEmpty</tt> function to check whether it is actually available.<br />
<br />
== Debugging tools ==<br />
Using the '''<tt>DBG_</tt>''' properties is a very crude method to discover the contents of an API objects.<br />
<br />
The watch window of the Basic IDE can display the properties of a Uno object (but not the methods, not the interfaces).<br />
<br />
To display all information available from an object and link to the corresponding API documentation, use instead <b>[[Extensions_development_basic#Xray_tool|Xray tool]] or [http://extensions.services.openoffice.org/project/MRI MRI tool]</b>.<br />
<br />
{{Documentation/VBAnote|{{OOo}} Basic does '''not''' provide code completion. Only at run-time can you find out which properties or methods are available for an object. All the above debug tools work on a running program. }}<br />
<br />
== API Reference ==<br />
<br />
More information about the available services, and their interfaces, methods and properties can be found in the [http://api.openoffice.org/docs/common/ref/com/sun/star/module-ix.html reference for the {{OOo}} API].<br />
<br />
<br />
{{InterWiki Languages BasicGuide|articletitle=Documentation/BASIC Guide/UNO Tools}}<br />
{{PDL1}}</div>BMarcellyhttps://wiki.openoffice.org/wiki/Extensions_development_basic_frExtensions development basic fr2016-05-01T06:34:36Z<p>BMarcelly: /* L'Outil Xray */</p>
<hr />
<div>'''Comment démarrer''' <br />
<br />
Cette page est un guide de démarrage qui vous permettra d'écrire des macros en OpenOffice.org Basic. Une connaissance préalable de la programmation est indispensable. Merci d'éditer cette page pour la rendre plus lisible. J'espère que vous la trouverez utile.<br />
<br />
Si vous maîtrisez les bases, alors vous pouvez consulter le [[CookBook]] qui donne des exemples et fournit des guides complémentaires.<br />
<br />
<br />
=Où le code est-il enregistré ?=<br />
Le code OpenOffice.org Basic est enregistré dans des modules eux-mêmes placés dans les bibliothèques. Une bibliothèque peut être : <br />
<br />
*Partagée (pour une installation en réseau - OOo Macros & Dialogues) <br />
*Uniquement pour l'utilisateur courant (Mes Macros & Dialogues) <br />
*Incorporée à un document ou à un modèle de manière que son code ne soit disponible que lorsque ce document est ouvert.<br />
<br />
Lorsque des bibliothèques ne sont stockées ni dans un document ni dans un modèle, c'est-à-dire lorsque les bibliothèques sont partagées ou pour l'utilisateur courant, on les appelle '''Bibliothèques OpenOffice.org'''. <br />
<br />
Pour connaître les dossiers qui contiennent les bibliothèques OpenOffice.org voir :<br> '''Outils > Options… > OpenOffice.org > Chemins > BASIC'''. <br />
<br />
[NdT : depuis la version 2.0.3, ces chemins ne sont plus affichés dans l'interface de OOo]<br />
<br />
{| border="1"<br />
|'''Note'''<br />
|Ne copiez pas ni ne déplacez les bibliothèques en utilisant les commandes du système d'exploitation. Préférez le gestionnaire de macros ou le gestionnaire de packages.<br />
|-<br />
|}<br />
<br />
<br />
La taille autorisée pour les modules placés à l'intérieur des bibliothèques est limitée à 64 Ko. Une bilbiothèque peut contenir jusqu'à 16.000 modules. <br />
<br />
Pour plus d'information, reportez-vous à l'aide en ligne, rubriques : "Bibliothèques;organisation" et "Modules;sous-routines et fonctions".<br />
<br />
=Accéder à l'IDE=<br />
Pour accéder à l'IDE (environnement de développement intégré) pour la première fois : <br />
<br />
OpenOffice.org 1.1.x: '''Outils > Macros > Macro… >''' <br />
<br />
OpenOffice.org 1.9.x et ultérieur : '''Outils > Macros > Gérer les macros > OpenOffice.org Basic… >''' <br />
<br />
Pour commencer, nous allons utiliser le Module1 de la bibliothèque Standard, présente pour l'utilisateur courant uniquement. <br />
<br />
Saisissons un nom pour notre nouvelle macro : '''HelloWorld''' <br />
<br />
Dans la macro, sélectionnons '''Standard''' dans la zone de liste.<br />
<br />
Cliquons sur '''Nouveau''' <br />
<br />
Nous devons maintenant trouver quelque chose comme ça : <br />
<br />
<source lang="oobas"><br />
REM ***** BASIC *****<br />
<br />
Sub Main<br />
<br />
End Sub<br />
<br />
Sub HelloWorld<br />
<br />
End Sub<br />
</source><br />
Le curseur est positionné au début de la ligne <tt>Sub HelloWorld</tt>. <br />
<br />
{| border="1"<br />
|'''Note'''<br />
|Maintenant que l'IDE est actif, il peut être accédé depuis le menu Fenêtre d'OpenOffice.org ou par la barre des tâches du système d'exploitation.<br />
|-<br />
|}<br />
<br />
=Saisie de code=<br />
Sélectionnons et effaçons : <br />
<br />
<source lang="oobas"><br />
REM ***** BASIC *****<br />
<br />
Sub Main<br />
<br />
End Sub<br />
</source><br />
Au-dessous de la ligne "Sub HelloWorld" entrons <tt>msgbox "Hello World!"</tt>, de manière à ce que l'éditeur ressemble à ceci : <br />
<br />
<source lang="oobas"><br />
Sub HelloWorld<br />
msgbox "Hello World!"<br />
End Sub<br />
</source><br />
{| border="1"<br />
|'''Notes:'''<br />
|L'IDE ne fournit aucune fonctionnalité de complétion du code, ni d'aide sur la syntaxe des commandes lors de la frappe. Pour obtenir de l'aide sur une commande Basic, plaçons le curseur dans la commande et tapons F1.<br> Les commandes OpenOffice.org Basic ne sont pas sensibles à la casse. C'est pourquoi msgbox, MSGBOX et Msgbox sont équivalents.<br> Les chaînes sont entourées de guillemets doubles.<br />
|-<br />
|}<br />
<br />
=Exécution du code=<br />
Le code Basic peut être exécuté de plusieurs façons : <br />
<br />
*Directement dans l'IDE. La barre des macro comprte un bouton Exécuter (par défaut, le troisième de la seconde barre d'outils). Ce bouton lance la première macro du module en cours. <br />
<br />
*Depuis le menu Outils :<br />
<br />
(Version 1.1.x) '''Outils > Macros > Macro…''';<br />
<br />
(Version 1.9.x et supérieures) '''Outils > Macros > Exécuter la macro…''' <br />
<br />
*Par assignation de la macro à une [[ touche]]. <br />
<br />
*Par assignation de la macro à une [[ option de menu]]. <br />
<br />
*Par assignation de la macro à un bouton de barre d'outil. <br />
<br />
*En créant un [[ contrôle dans un document]]. <br />
<br />
*Par assignation de la macro à un évènement. <br />
<br />
Pour l'instant essayons de lancer la procédure "HelloWorld" en cliquant sur le bouton '''Exécuter'''. Un dialogue intitulé "soffice" et comportant le texte "Hello World!" ainsi qu'un bouton OK doit s'afficher.<br />
<br />
=Enregistrement du code=<br />
Le code est enregistré automatiquement chaque fois que son conteneur est lui-même enregistré. Par conséquent, si le code se trouve dans une bibliothèque OpenOffice.org (partagée ou de l'utilisateur), il est automatiquement enregistré lorsque OpenOffice.org est refermé. Si le code se trouve dans une bilbiothèque qui fait partie d'un document, alors il est enregistré lorsque le document l'est. <br />
<br />
Un bouton Enregistrer figure dans la barre d'outils Standard (celle du haut par défaut). Si le code se trouve à l'intérieur d'un document ou modèle, alors la totalité du document est enregistrée. Si le code se trouve à l'intérieur d'une bibliothèque OpenOffice.org alors seule la bilbiothèque courante est enregistrée.<br />
<br />
=Les variables=<br />
Nous pouvons forcer la déclaration des variables en insérant <tt>Option Explicit</tt> au début du module. Pour consulter une discussion consacrée à la déclaration ou non des variables, voir : [[http://www.oooforum.org/forum/viewtopic.phtml?t=5845 cette discussion]]. <br />
<br />
Dans cette discussion, on voit que l'auteur de cette page défendait initialement la déclaration systématique des variables. Depuis lors il a changé d'avis et ne les déclare plus du tout. Bref, c'est une question de préférence personnelle. Dans un cas comme dans l'autre, les préférences de l'auteur vont au nommage des variables selon la convention suivante, qui sera utilisée tout au long des exemples de ce wiki :<br />
<br />
La première lettre du nom de la variable indique le type de valeur contenue, telle que présentée à la table ci-dessous (basée sur un tableau dans Tutorial.pdf de Sun) <br />
<br />
{| border="1"<br />
|'''''Lettre'''''<br />
|'''''Signification'''''<br />
|-<br />
|a<br />
|Structure<br />
|-<br />
|b<br />
|Boolean (TRUE ou FALSE)<br />
|-<br />
|e<br />
|Enumeration. Cette variable ne peut prendre qu'une valeur parmi un ensemble limité de valeurs.<br />
|-<br />
|f<br />
|Float (de 3.402823 x 1038 à 1.401298 x 10-45. Une variable de type float [NdT : single] peut occuper jusqu'à quatre octets)<br> Double (de 1.79769313486232 x 10308 à 4.94065645841247 x 10-324. Une variable de ce type peut occuper jusqu'à huit octets)<br> Currency (de -922337203685477.5808 à +922337203685477.5807 et occupe jusqu'à huit octets en mémoire)<br />
|-<br />
|m<br />
|Array (aka sequence aka matrice)<br />
|-<br />
|n<br />
|Integer (de -32768 à 32767) ou<br> Long (de -2147483648 à 2147483647).<br />
|-<br />
|o<br />
|Object, service ou interface<br />
|-<br />
|s<br />
|String (Une variable string peut mémoriser jusqu'à 65535 caractères Unicode).<br />
|-<br />
|x<br />
|Interface, montre que seules les opérations portant sur une interface particulière d'un objet sont utilisées<br />
|-<br />
|v<br />
|Variant, n'importe quelle valeur<br />
|-<br />
|}<br />
<br />
<br />
Utilisons des noms descriptifs suffisamment longs et employons le style "Camel case" [NdT : usage conjoint des majuscules et des minuscules pour faire ressortir les éléments du nom]<br />
<br />
{| border="1"<br />
|'''Note :'''<br />
|Les variables définies par l'utilisateur en OpenOffice.org Basic ne sont pas sensibles à la casse. Les constantes UNO-API le sont.<br />
|}<br />
<br />
<br />
Les variables indexant les boucles constituent une exception conventionnelle aux longs noms descriptifs. Des symboles tels que i, j et k sont en effet d'usage fréquent. De même, lorsqu'une chaîne est construite, on utilise fréquemment s comme variable temporaire. <br />
<br />
Editons la routine sub HelloWorld de manière qu'elle ressemble à ceci et exécutons-la : <br />
<br />
<source lang="oobas"><br />
sub HelloWorld<br />
dim i as integer 'ligne optionnelle<br />
for i = 0 to 2<br />
'Ces lignes sont indentées par souci de lisiblité uniquement<br />
'Notre code devrait toujours être structuré ainsi pour lui donner des chances de survie<br />
msgbox "Hello World " & i<br />
next i<br />
end sub<br />
</source><br />
Pour plus d'informations sur les variables, reportons-nous à l'aide en ligne, rubrique "variables;utilisation".<br />
<br />
=L'API OpenOffice.org=<br />
Cette section commence par un exemple. La suite donne des informations complémentaires qui nous permettront de comprendre l'exemple et de l'étendre.<br />
<br />
Essayons d'exécuter le code ci-dessous lorsque différents types de documents sont ouverts.<br />
<br />
<source lang="oobas"><br />
sub main<br />
'BasicLibraries.loadLibrary("XrayTool")<br />
'xray thisComponent<br />
msgbox fnWhichComponent(thisComponent)<br />
end sub<br />
<br />
<br />
function fnWhichComponent(oDoc) as string<br />
if HasUnoInterfaces(oDoc, "com.sun.star.lang.XServiceInfo") then <br />
if thisComponent.supportsService ("com.sun.star.text.GenericTextDocument") then<br />
fnWhichComponent = "Texte"<br />
elseif thisComponent.supportsService("com.sun.star.sheet.SpreadsheetDocument") then<br />
fnWhichComponent = "Feuille de calcul"<br />
elseif thisComponent.supportsService("com.sun.star.presentation.PresentationDocument") then<br />
fnWhichComponent = "Presentation"<br />
elseif thisComponent.supportsService("com.sun.star.drawing.GenericDrawingDocument") then<br />
fnWhichComponent = "Dessin"<br />
else<br />
fnWhichComponent = "Oops le document ouvert est autre chose"<br />
end if<br />
else<br />
fnWhichComponent = "Ce n'est pas un document"<br />
end if<br />
End function<br />
</source><br />
<br />
==Convention de nommage des routines==<br />
Dans l'exemple ci-dessus, le nom de la fonction utilisateur commence par "fn". Il s'agit de la convention adoptée par l'auteur initial [NdT : version anglaise] qui permet au lecteur de savoir qu'il s'agit d'une fonction définie par l'utilisateur. Dans le même esprit, l'auteur initial utilise la convention de débuter les noms des procédures par "sub". Lorsque l'on apprend un nouveau langage et de nouvelles API, il peut s'avérer difficile de reconnaître ce qui ressortit du langage lui-même de ce qui a été défini ailleurs dans notre code. Ce document/wiki emploie ces conventions pour le nommage des fonctions et des procédures.<br />
<br />
==Présentation de l'API OpenOffice.org==<br />
Cette section introduit les termes : <br />
<br />
* Interface <br />
* Module <br />
* Service <br />
* Méthode <br />
* Propriété <br />
<br />
S'il n'est pas essentiel de comprendre la différence entre une interface et un service ou ce qu'est un module pour pouvoir écrire des extensions à OpenOffice.org, la compréhension de ces termes aide à correctement interpréter la documentation ainsi qu'à l'introspection des éléments manipulés. Peut-être nous faudra-t-il relire cette section plusieurs fois. <br />
<br />
Une '''interface''' est la ''définition'' d'un ensemble de méthodes (avec leurs arguments) qu'un service implémentant cette interface doit comporter. <br />
<br />
Les interfaces sont regroupées en '''modules''' pour des besoins de nommage. Toutes les interfaces (et les services) commencent par le nom "com.sun.star" puis vient le nom du module puis celui de l'interface (ou du service). <br />
<br />
Par exemple, la plupart des services fournissent l'interface <tt>com.sun.star.beans.XPropertySet</tt>. Cette interface est enregistrée dans le module "beans" et fournit l'accès aux propriétés d'un service. Une '''propriété''' est une valeur tandis qu'une '''méthode''' définit une action. <br />
<br />
Un objet OpenOffice.org peut supporter de nombreux services. <br />
<br />
Un objet OpenOffice.org peut supporter un service qui implémente une interface dans laquell une description de méthode déclare qu'un autre objet OpenOffice.org est retourné.<br />
<br />
==Introspection==<br />
HasUnoInterfaces est une fonction OpenOffice.org Basic utilisée pour l'introspection. Ce document [[http://www.oooforum.org/forum/viewtopic.phtml?t=7068 link]] permettra d'apprendre ce que l'on entend par introspection dans d'autres langages de programmation. <br />
<br />
HasUnoInterfaces renvoie une valeur "vrai" si toutes les interfaces spécifiées sont disponibles pour l'objet appelant. <br />
<br />
La plupart des objets OpenOffice.org fournissent la méthode supportsService parce qu'ils disposent également de l'interface com.sun.star.lang.XServiceInfo. <br />
<br />
Dans l'exemple ci-dessus, la commande OpenOffice.org Basic, '''HasUnoInterfaces''' vérifie si le document actif dispose de l'interface com.sun.star.lang.XServiceInfo, car si cette interface n'est pas présente, alors le document n'aura pas non plus la méthode supportsService, et une erreur d'exécution se produirait si un objet tentait d'accéder à une méthode inexistante. <br />
<br />
'''SupportsService''' est une méthode qui renvoie la valeur "vrai" si le service spécifié est disponible. Dans l'exemple ci-dessus, on vérifie la présence d'un service afin de déterminer le type de document en cours d'activation.<br />
<br />
==L'Outil Xray==<br />
L'utilisation de "HasUnoInterfaces" et de "supportsService" permet d'obtenir des informations sur un objet donné lors de son exécution, mais procéder ainsi pour apprendre le langage Basic deviendrait vite fastidieux. Heureusement, et grâce à Bernard Marcelly, nous disposons de l'outil Xray. Cet outil est disponible ici en [[http://berma.pagesperso-orange.fr/Files_fr/XrayTool60_fr.odt version française]] et ici en [[http://berma.pagesperso-orange.fr/Files_en/XrayTool60_en.odt version anglaise]]. Téléchargez le fichier odt, ouvrez le document dans OpenOffice.org, et suivez les instructions pour son installation et configuration. <br />
<br />
Une partie de la configuration de l'outil Xray concerne la définition de l'endroit où est stockée une copie locale (sur le disque dur) du Kit de Développement OpenOffice.org (appélé SDK). Téléchargez le Kit de Développement OpenOffice.org depuis [[http://www.openoffice.org/dev_docs/source/sdk/ le site du SDK]] et installez le sur votre disque dur. <br />
<br />
Dans l'exemple ci-dessus, au début du code, il y a deux lignes mises en commentaires (les lignes de commentaires commencent avec des apostrophes ou le mot réservé rem): <br />
<br />
<source lang="oobas"><br />
'BasicLibraries.loadLibrary("XrayTool")<br />
'xray thisComponent<br />
</source><br />
Une fois l'outil Xray installé, supprimez les apostrophes dans les lignes indiquées ci-dessus et relancez la macro.<br />
<br />
'''BasicLibraries''' est une commande OpenOffice.org Basic qui renvoie un objet permettant d'accéder aux bibliothèques OpenOffice.org. La méthode <tt>loadLibrary</tt> rend disponible aux utilisateurs les routines présentes dans cette bibliothèque. <br />
<br />
<tt>xray</tt> indique la routine xray contenue dans la bibliothèque XrayTool, l'objet thisComponent étant l'objet transmis à xray pour l'introspection. <br />
<br />
Afin de trouver l'objet que vous cherchez, il est souvent nécessaire de le découvrir ou de le créer depuis StarDesktop ou thisComponent.<br />
<br />
==Desktop, documents, et current selection==<br />
StarDesktop et ThisComponent sont des commandes OpenOffice.org Basic qui ont trait à l'application et le document actif (c'est-à-dire, celui qui a le focus actuellement sur le bureau) respectivement. <br />
<br />
Contrairement à Microsoft Office, l'application OpenOffice.org est monolithique et comporte différents composants. Lorsqu'on exécute du code, il peut être utile de vérifier quel composant est actuellement en cours d'activation. Le code ci-dessus donne un exemple de la manière de procéder à cette vérification. <br />
<br />
Quand il est fait référence au Desktop dans StarDesktop, celui-ci se réfère à une existence virtuelle (puisqu'auparavant il existait réellement dans OpenOffice.org et dans StarOffice). On peut ainsi le considérer comme étant l'application OpenOffice.org elle-même.<br />
<br />
==Création de Nouveaux Documents==<br />
Pour créer un nouveau document Writer, on écrit le code suivant: <br />
<br />
<source lang="oobas"><br />
oDoc = StarDesktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, Array())<br />
</source><br />
<br />
De la même manière, pour un nouveau document Calc: <br />
<br />
<source lang="oobas"><br />
oDoc = StarDesktop.loadComponentFromURL("private:factory/scalc", "_blank", 0, Array())<br />
</source><br />
<br />
Il serait sans doute plus facile d'écrire une fonction simple: <br />
<br />
<source lang="oobas"><br />
function fnNewDoc(sDocType as string)<br />
fnNewDoc = StarDesktop.loadComponentFromURL("private:factory/" & sDocType , "_blank", 0, Array())<br />
end function<br />
</source><br />
<br />
Ensuite, on pourra créer de nouveaux documents ainsi: <br />
<br />
<source lang="oobas"><br />
oDoc = fnNewDoc("swriter")<br />
oDoc = fnNewDoc("scalc")<br />
oDoc = fnNewDoc("simpress")<br />
oDoc = fnNewDoc("sdraw")<br />
oDoc = fnNewDoc("smath")<br />
</source><br />
<br />
Voir également http://api.openoffice.org/docs/common/ref/com/sun/star/frame/XComponentLoader.html .<br />
<br />
==Ouverture d'un document==<br />
Le code suivant donne un exemple permettant d'ouvrir un fichier. Pour plus d'informations sur l'utilisation d'URL au sein de OpenOffice.org, voir [[ URL Basics]]. <br />
<br />
<source lang="oobas"><br />
sFile = "C:\Documents and Settings\danny\Desktop\MyCalc.sxc" ' Windows<br />
sFile = "/home/danny/Desktop/MyCalc.sxc" ' Linux<br />
sURL = ConvertToURL(sFile)<br />
oDoc = StarDesktop.loadComponentFromURL(sURL, "_blank", 0, Array())<br />
</source><br />
<br />
Ici encore, il peut être plus rationnel de simplifier le code en écrivant une fonction: <br />
<br />
<source lang="oobas"><br />
function fnOpenDoc(sFile)<br />
sURL = ConvertToURL(sFile)<br />
fnOpenDoc = StarDesktop.loadComponentFromURL(sURL, "_blank", 0, Array())<br />
end function<br />
</source><br />
<br />
Exemples d'utilisation de la fonction: <br />
<br />
<source lang="oobas"><br />
oDoc = fnOpenDoc("C:\Documents and Settings\danny\Desktop\MyCalc.sxc") ' Windows<br />
oDoc = fnOpenDoc("/home/danny/Desktop/MyCalc.sxc") ' Linux<br />
</source><br />
<br />
==La sélection en cours==<br />
Nous avons souvent besoin d'exécuter du code qui affecte la sélection courante. <tt>ThisComponent</tt> possède une méthode <tt>getCurrentSelection</tt>. Comme de nombreux types d'objets sont sélectionnables, il est habituel de vérifier que l'objet sélectionné possède le service qui contient la méthode que nous voulons appliquer à l'objet. <br />
<br />
Editons la routine principale du code ci-dessous et re-exécutons-la successivement sur un document texte comportant plusieurs sélections différentes (pour sélectionner plus d'un bloc de texte, nous maintenons la touche Control enfoncée). <br />
<br />
<source lang="oobas"><br />
sub main<br />
BasicLibraries.loadLibrary("XrayTool")<br />
if fnWhichComponent(thisComponent) = "Text" then<br />
oCurSelection = thisComponent.getCurrentSelection()<br />
'xray oCurSelection<br />
if oCurSelection.supportsService("com.sun.star.text.TextRanges") then<br />
msgbox "Il y a " & oCurSelection.getCount() & _<br />
" sélections dans le document texte en cours."<br />
end if<br />
end if<br />
end sub<br />
</source><br />
Lorsqu'il n'y a aucune sélection, le nombre affiché est un - le point d'insertion -, avec un bloc de text sélectionné, il renvoie également un, mais avec deux blocs de texte, ce nombre devient égal à trois - le point d'insertion et les deux blocs de texte sélectionnés. <br />
<br />
Exercice 1 : Modifier le code ci-dessus afin qu'il fonctionne sur des plages de cellules sélectionnées dans une feuille de calcul. <br />
<br />
Question 1 : Lorsque deux blocs de cellules sont sélectionnés, quelle est la valeur du nombre de sélections ?<br />
<br />
==Les propriétés==<br />
Retirons le commentaire de <tt>'xray oCurSelection</tt> de manière à lancer xray, ce qui permet de constater que l'objet pointé par <tt>oCurSelection</tt> possède une "propriété" nommée <tt>Count</tt> dont la description est "pseudo-prop, read only". Nous pourrions écrire <tt>oCurSelection.count</tt> en OpenOffice.org Basic, mais comme ce n'est pas possible dans tous les autres langages qui accèdent à l'API OpenOffice.org, ce wiki essaiera de toujours utiliser l'approche par méthode (je signale çà car je n'ai pas pris l'habitude de le faire et il m'arrive d'oublier). <br />
<br />
L'exemple suivant montre comment changer une valeur de propriété pour les sélections courantes. <br />
<br />
<source lang="oobas"><br />
sub main<br />
BasicLibraries.loadLibrary("XrayTool")<br />
if fnWhichComponent(thisComponent) = "Text" then<br />
oCurSelection = thisComponent.getCurrentSelection()<br />
if oCurSelection.supportsService("com.sun.star.text.TextRanges") then<br />
nCount = oCurSelection.Count<br />
'xray oCurSelection.getByIndex(0)<br />
'Attention : le point d'insertion va voir la même action appliquée deux fois<br />
'ici çà n'a pas d'importance mais il est des cas ou cela pourrait en avoir.<br />
for i = 0 to nCount - 1<br />
oCurSelection.getByIndex(i).setPropertyValue("CharStyleName", "Strong Emphasis")<br />
next<br />
end if<br />
end if<br />
end sub<br />
</source><br />
En Basic OpenOffice.org nous pouvons raccourcir la ligne d'affectation ainsi : <br />
<br />
<source lang="oobas"><br />
oCurSelection(i).CharStyleName = "Strong Emphasis"<br />
</source><br />
Ce wiki essaiera toujours d'utiliser les noms complets des méthodes pour l'indexation et l'assignation des propriétés. La raison en est que non seulement cela aide les nouveaux venus à comprendre ce qui se passe mais également nous rendons ainsi la conversion du code vers d'autres langages plus aisée (encore une fois, je n'ai pas l'habitude de pratiquer systématiquement ainsi, c'est pourquoi des contre-exemples pourraient m'échapper). <br />
<br />
Exercice 2 : Réécrire le code ci-dessus de manière que l'avertissement disparaisse. <br />
<br />
Voir [[ Current selection]].<br />
<br />
=Accès répété à des objets subordonnés (accès aux énumérations)=<br />
Il arrive qu'une énumération soit nécessaire pour accéder à l'objet désiré. C'est le cas, par exemple, des paragraphes à l'intérieur d'un document ou dans une sélection.<br />
<br />
Lorsqu'un document Writer est actif et que du texte y est sélectionné, <tt>thisDocument.getText()</tt> et <tt>thisComponent.getCurrentSelection().getByIndex(i)</tt> possèdent toutes deux le service <tt>com.sun.star.text.TextRange</tt> qui lui-même possède l'interface <tt>com.sun.star.container.XContentEnumerationAccess</tt>. Il est possible de créer une énumération des paragraphes du document en cours ou d'un sélection donnée. <br />
<br />
<source lang="oobas"><br />
' Creation de l'objet énumeration<br />
oTextElementEnum = thisComponent.getText().createEnumeration()<br />
'ou bien : thisComponent.getCurrentSelection().getByIndex(i).createEnumeration()<br />
<br />
' boucler sur tous les élément texte<br />
while oTextElementEnum.hasMoreElements()<br />
oTextElement = oTextElementEnum.nextElement<br />
if oTextElement.supportsService("com.sun.star.text.TextTable") then<br />
MsgBox "Le bloc en cours contient un tableau."<br />
end if<br />
if oTextElement.supportsService("com.sun.star.text.Paragraph") then<br />
MsgBox "Le bloc en cours contient un paragraphe."<br />
end if<br />
wend<br />
</source><br />
Exercise 3 : Etendre l'exemple ci-dessus pour lui faire afficher la liste de toutes les portions de textes mises en gras.<br />
<br />
=Accès nommés=<br />
Certains objets fournissent l'accès nommé à un type particulier d'objet subordonné, d'autres fournissent l'accès indexé et certains fournissent les deux à la fois, accès nommé et indexé. <br />
<br />
Par exemple, si le document en cours dans OpenOffice.org est une classeur, alors l'accès à une feuille spécifique peut s'effectuer par accès indexé : <br />
<br />
<source lang="oobas"><br />
oSheet = thisComponent.getSheets.getByIndex(0)<br />
</source><br />
ou bien par accès nommé : <br />
<br />
<source lang="oobas"><br />
oSheet = thisComponent.getSheets.getByName("Feuille1")<br />
</source><br />
Pour vérifier qu'un objet doté d'un nom particulier existe déjà, utilisons <tt>hasByName</tt>. Par exemple : <br />
<br />
<source lang="oobas"><br />
if thisComponent.getSheets.hasByName("Feuille1") then<br />
</source><br />
Parcourir tous les noms d'objets disponibles peut se faire comme ceci :<br />
<br />
<source lang="oobas"><br />
mNames = thisComponent.getSheets.getElementnames<br />
for i = lbound(mNames) to ubound(mNames)<br />
msgbox mNames(i)<br />
next<br />
</source><br />
<br />
<br />
Quelques objets subordonnés nommés fournissent également l'interface : <tt>com.sun.star.container.XNameContainer</tt>. Cette interface définit que de tels objets doivent comporter les méthodes : <tt>insertByName</tt>, <tt>replaceByname</tt> and <tt>removeByName</tt>. <br />
<br />
Ex : <br />
<br />
<source lang="oobas"><br />
thisComponent.getSheets.insertByName("NouvelleFeuille")<br />
</source><br />
<br />
=Créer de nouveaux objets=<br />
Certains objets proposent des services qui implémentent des interfaces fournissant des méthodes spécifiques pour créer un type particulier d'objet.<br />
<br />
Par exemple, si le document en cours est un document Writer, alors <tt>thisComponent.getText</tt> est un objet qui fournit le service <tt>com.sun.star.text.Text</tt> qui implémente l'interface <tt>com.sun.star.text.XSimpleText</tt> laquelle définit les méthodes <tt>createTextCursor</tt> et <tt>createTextCursorByRange</tt>. Ces deux méthodes permettent de créer un curseur texte afin d'accéder au corps du document. Ces curseurs sont indépendants du curseur de visualisation. Ce dernier est visible à l'écran et est manipulé par l'utilisateur (et également par programme), tandis qu'un curseur texte n'apparaît pas à l'écran et n'est employé que par des programmes. Le morceau de code qui suit montre la création d'un curseur texte qui démarre à l'emplacement du curseur de visualisation pour être ensuite déplacé indépendamment de ce dernier. <br />
<br />
<source lang="oobas"><br />
oVC = thisComponent.getCurrentController.getViewCursor<br />
oCursor = oVC.getText.createTextCursorByRange(oVC)<br />
oCursor.gotoStartOfSentence(false)<br />
oCursor.gotoEndOfSentence(true)<br />
msgbox oCursor.getString<br />
</source><br />
<br />
Certains objets sont dépendants du contexte et peuvent être créés par appel de la méthode <tt>createInstance</tt> définie dans l'interface <tt>com.sun.star.lang.XMultiServiceFactory</tt>. Par exemple, pour ajouter un rectangle sur la première page d'un document Draw : <br />
<br />
<source lang="oobas"><br />
dim aPoint as new com.sun.star.awt.Point<br />
dim aSize as new com.sun.star.awt.Size<br />
<br />
aPoint.x = 1000<br />
aPoint.y = 1000<br />
<br />
aSize.Width = 10000<br />
aSize.Height = 10000<br />
<br />
oRectangleShape = thisComponent.createInstance("com.sun.star.drawing.RectangleShape")<br />
oRectangleShape.Size = aSize<br />
oRectangleShape.Position = aPoint<br />
<br />
thisComponent.getDrawPages.getByIndex(0).add(oRectangleShape)<br />
</source><br />
<br />
Cet exemple utilise également des structures UNO. Voir plus bas pour plus d'informations sur ce sujet.<br />
<br />
Certains objets sont indépendants du contexte. Pour les créer, nous utilisons la commande Basic OpenOffice.org <tt>createUnoService</tt>. Par exemple, pour créer l'équivalent de StarDesktop : <br />
<br />
<source lang="oobas"><br />
oDesktop = createUnoService("com.sun.star.frame.Desktop")<br />
</source><br />
<br />
Le procédé que j'emploie pour savoir comment accéder ou créer un objet est le suivant :<br />
<br />
Est-ce que l'objet existe déjà ? Si oui, alors je dois pouvoir y accéder à partir de quelque chose comme <tt>thisComponent</tt>. <br />
<br />
L'objet doit-il appartenir à un autre objet ? Si oui, alors le propriétaire comporte-t-il une méthode spécifique pour créer l'objet ? Si oui, j'appelle cette méthode.<br />
<br />
Le nouvel objet doit-il appartenir à un autre objet qui ne fournit par de méthode de création mais fournit <tt>createInstance</tt> ? Si l'objet ne fournit pas <tt>createInstance</tt> suis-je certain que j'utilise le bon objet ou est-il dépendant du contexte ?<br />
<br />
Il me semble que la création d'objets est mal documentée actuellement c'est pourquoi j'espère que ce document/wiki rendra les choses plus claires.<br />
<br />
<br />
==Structures UNO==<br />
Les structures UNO se déclarent au moyen de la commande Basic OpenOffice.org <tt>dim</tt> : <br />
<br />
<source lang="oobas"><br />
dim aPoint as new com.sun.star.awt.Point<br />
</source><br />
Ou encore en employant la commande Basic OpenOffice.org <tt>createUnoStruct</tt>: <br />
<br />
<source lang="oobas"><br />
aPoint = createUnoStruct("com.sun.star.awt.Point")<br />
</source><br />
<br />
{| border="1"<br />
|'''Note :'''<br />
|La casse est importante lors de la déclaration de structures UNO. Tout ce qui précède le nom de la structure est en minuscules, le nom lui-même marriant minuscules et majuscules.<br />
|}<br />
<br />
==Création de Listeners et de Handlers==<br />
L'interface utilisateur permet d'assigner des macros à certains événements : <br />
<br />
OpenOffice.org versions 1.1.x: '''Outils > Adaptation > Evénements'''. <br />
<br />
OpenOffice.org versions 1.9.x and above: '''Outils > Personnaliser > Evénements'''. <br />
<br />
Nous pouvons également assigner des macros à une gamme plus large d'événements en utilisant la commande Basic OpenOffice.org <tt>CreateUnoListener</tt>. La même commande sert à créer à la fois des listeners aet des handlers. Un listener attend un événement et permet toujours à d'autres listeners de répondre à ce même événement. Un handler attend un événement et peut éventuellement le consommer afin que d'autres listeners ne puissent pas agir dessus.<br />
<br />
L'exemple ci-dessous crée un gestionnaire de clavier : <br />
<br />
<source lang="oobas"><br />
global IannzExampleKeyHandler<br />
<br />
sub SetupKeyHandler<br />
oController = thisComponent.currentController<br />
IannzExampleKeyHandler = CreateUnoListener("KeyHandler_","com.sun.star.awt.XKeyHandler")<br />
oController.addKeyHandler(IannzExampleKeyHandler) ' Enregistre le listener<br />
end sub<br />
<br />
<br />
sub RemoveKeyHandler<br />
thisComponent.currentController.removeKeyHandler(IannzExampleKeyHandler)<br />
end sub<br />
<br />
<br />
sub KeyHandler_disposing<br />
end sub<br />
<br />
<br />
function KeyHandler_keyReleased(oKeyEvent as new com.sun.star.awt.KeyHandler) as boolean<br />
KeyHandler_keyReleased = False <br />
end function<br />
<br />
<br />
function KeyHandler_keyPressed(oKeyEvent as new com.sun.star.awt.KeyHandler) as boolean<br />
KeyHandler_keyPressed = false 'Laisser d'autres listeners gérer l'événement<br />
if oKeyEvent.modifiers = com.sun.star.awt.KeyModifier.MOD2 then 'Control key was pressed<br />
if oKeyEvent.keyCode = com.sun.star.awt.Key.Q then<br />
msgbox "Alt + Q a été appuyé"<br />
KeyHandler_keyPressed = true 'Ne pas laisser d'autres listeners gérer l'événement<br />
end if<br />
end if<br />
end function<br />
</source><br />
Une variable globale conserve sa valeur après la sortie de la macro. Dans ce cas, nous voulons pouvoir utiliser cette variable plus tard pour supprimer le handler. Je fais débuter tous mes noms de variables globales du radical Iannz qui est le nom que j'ai enregistré pour le site web OpenOffice.org. Ceci permet d'éviter des conflits éventuels entre mes variables globales et d'autres bibliothèques qui pourraient utiliser les mêmes noms. <br />
<br />
<tt>sub SetupKeyHandler</tt> initialise le handler. Le premier paramètre de CreateUnoListener est le nom générique des méthodes qui sont appelées quand ce type d'événement se produit. Dans cet exemple .<tt>"KeyHandler_"</tt>. <br />
<br />
Le second parameter est le nom de l'interface du listener ou du handler, "com.sun.star.awt.XKeyHandler". Le nom est sensible à la casse, tout jusque et y compris le nom du module est toujours en minuscules, le nom de l'interface commence par un "X" et le reste est en TitleCase. <br />
<br />
Utilsions le SDK pour trouver quelles méthodes l'interface doit fournir. Nous devrons fournir des routines pour toutes ces méthodes, même si nous n'avons pas l'intention de les utiliser. Nous devrons également fournir une méthode de nettoyage. Les noms de ces routines débutent par la chaîne passée comme premier paramètre à CreateUnoListener. Dans l'exemple c'est <tt>"KeyHandler_"</tt>. <br />
<br />
Il y a donc dans l'exemple <tt>KeyHandler_disposing</tt> et <tt>KeyHandler_keyReleased</tt> qui, en fait, ne font rien mais sont nécessaires, et <tt>KeyHandler_keyPressed</tt> qui accomplit la fonctionnalité effective. <br />
<br />
<tt>sub RemoveKeyHandler</tt> montre comment supprimer le handler.<br />
<br />
=Les constantes OpenOffice.org=<br />
L'exemple ci-dessus utilise des constantes OpenOffice.org. <br />
<br />
Par ex : com.sun.star.awt.KeyModifier.MOD2<br />
<br />
Les constantes OpenOffice.org sont sensibles à la casse. Tout jusque et y compris le nom du module est toujours en minuscules. Le nom du groupe de constantes est en TitleCase. Le nom effectif de la constante est toujours en MAJUSCULES. <br />
<br />
Les programmeurs qui n'utilisent pas le Basic OpenOffice.org peuvent ne pas avoir accès à ces constantes.<br />
<br />
=Utilisation de l'enregistreur=<br />
Voir la section [[ L'enregistreur de macro OpenOffice.org et les appels UNO (dispatch)]]<br />
où sont comparés l'enregistrement des commandes UNO Dispatch et les appels API.<br />
<br />
Traduit de l'anglais : [[ The OpenOffice.org recorder and UNO dispatch calls]]<br />
<br />
= Voir aussi=<br />
* [[Programming_OooWriter |Programming OOoWriter in C++]] où des record OOBasic sont utilisés en C++<br />
* Une brève description de l'[[XIntrospection_Interface|interface XIntrospection]].<br />
* Télécharger [http://www.openoffice.org/fr/Documentation/Basic/ L'outil XRay OOoBasic] de Bernard Marcelly. <br />
* A voir aussi en anglais : [[Object Inspector|The New Object Inspector]] et [[BASIC/UNO_Object_Browser|The BASIC UNO Object Browser]]<br />
<br />
[[Category:Basic:Tutorials]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Extensions_introspectionExtensions introspection2016-05-01T06:27:09Z<p>BMarcelly: </p>
<hr />
<div>many introspection tools are available as the OOo API provides some usefull methods<br />
<br />
* XRAY<br />
The introspection tool for macros !!! ( see [[Extensions_development_basic#Xray_tool|XRay tool description]] in this wiki)<br />
<br />
a must have<br />
<br />
* [http://www.indesko.com/telechargements/pyxray___un_outil_po/downloadFile/attachedFile/pyXray.zip pyXRAY]<br />
the same as XRay for pyUNO<br />
<br />
* [[Object_Inspector|Object Inspector]]<br />
The Object Inspector is an OpenOffice.org extension that is to help the developer to inspect arbitrary Uno-Objects. As Uno provides a service-oriented API with abstract service descriptions exporting defined interfaces the capabilities of a Uno Object does not open up to the developer at design time. The Object Inspector also offers Sourcecode generation in several programming languages and links of interface and service descriptions either locally installed or from OpenOffice.org The Object Inspector is still under development.<br />
<br />
== See also ==<br />
* [[Constructing_Helpers#Reflection_Helper|Reflection Helper in C++]]<br />
* [[IDL_Files_and_Cpp#Core_reflection_service__and_its_Interfaces|Core Reflection in C++]]<br />
* [[IDL_Files_and_Cpp#Using_Java_Inspector|Using Java Inspector]]<br />
<br />
[[Category:Extensions]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/XIntrospection_InterfaceXIntrospection Interface2016-05-01T06:23:57Z<p>BMarcelly: /* See also */</p>
<hr />
<div>We prefer to use the Java Inspector method : inspect a real object. You can then find values of the properties for example. (<OpenOffice.org1.1_SDK>/examples/java/Inspector) Again we first give some of used interfaces. We begin first with <idl>com.sun.star.beans.XIntrospection</idl><br />
<source lang="idl"><br />
// IDL<br />
module com { module sun { module star { module beans {<br />
<br />
interface XIntrospection: com::sun::star::uno::XInterface<br />
{ <br />
com::sun::star::beans::XIntrospectionAccess inspect( [in] any aObject );<br />
};<br />
}; }; }; };<br />
</source> <br />
where we see we have to focus our attention to <idl>com.sun.star.beans.XIntrospectionAccess</idl> interface :<br />
<source lang="idl"><br />
// IDL<br />
module com { module sun { module star { module beans {<br />
interface XIntrospectionAccess: com::sun::star::uno::XInterface<br />
{ <br />
long getSuppliedMethodConcepts(); <br />
long getSuppliedPropertyConcepts();<br />
com::sun::star::beans::Property getProperty( [in] string aName,<br />
[in] long nPropertyConcepts ) <br />
raises( com::sun::star::container::NoSuchElementException );<br />
boolean hasProperty( [in] string aName,<br />
[in] long nPropertyConcepts ); <br />
sequence<com::sun::star::beans::Property> getProperties( <br />
[in] long nPropertyConcepts );<br />
com::sun::star::reflection::XIdlMethod getMethod( [in] string aName, <br />
[in] long nMethodConcepts )<br />
raises( com::sun::star::lang::NoSuchMethodException ); <br />
boolean hasMethod( [in] string aName, <br />
[in] long nMethodConcepts );<br />
sequence<com::sun::star::reflection::XIdlMethod> getMethods(<br />
[in] long nMethodConcepts ); <br />
sequence<type> getSupportedListeners(); <br />
com::sun::star::uno::XInterface queryAdapter( [in] type aInterfaceType ) <br />
raises( com::sun::star::beans::IllegalTypeException ); <br />
};<br />
}; }; }; };<br />
</source><br />
Please go on alone and have a look in the other involved IDL files : <idl>com.sun.star.beans.Property</idl> and <idl>com.sun.star.uno.XInterface</idl>.<br />
<br />
== Obtaining methods information ==<br />
We present now how to construct the Reflection information with a schematic representation.<br />
<br />
[[Image:XIntrospectionMethodInfo.png]]<br />
<br />
The figure above explains how to get the methods information with returned type, name of method and parameters information. Please note that <code>getParamMode</code> is not provided by SDK but my own code (inspired by Inspector Java code). See also the <idl>com.sun.star.reflection.ParamMode</idl> enumeration. <br />
{{Documentation/Caution|As you will see later in C++ snippet, there is a fault in the figure above for the returned type. The method is <code>getReturnType</code> instead of <code>getReturnedType</code>. This will be corrected later in the figure.}}<br />
<br />
We fist give the <code>getParamMode</code> function snippet :<br />
<source lang="cpp"><br />
//Listing 12 getParamMode function<br />
// C++<br />
// Don't forget to add : #include <com/sun/star/reflection/ParamMode.hpp><br />
// Don't forget to add "com.sun.star.reflection.ParamMode \" in the makefile<br />
OUString getParamMode(ParamMode paramMode) {<br />
// comes from <OpenOffice1.1_SDK>/examples/java/Inspector<br />
OUString toReturn;<br />
toReturn = OUString::createFromAscii("");<br />
if (paramMode == ParamMode_IN) toReturn = OUString::createFromAscii("IN"); else<br />
if (paramMode == ParamMode_OUT) toReturn = OUString::createFromAscii("OUT"); else<br />
if (paramMode == ParamMode_INOUT) toReturn = OUString::createFromAscii("INOUT");<br />
return toReturn;<br />
}<br />
</source><br />
Now the complete implementation is given : starting from the figure above, it's easy this code needs two parameters, a <idl>com.sun.star.lang.XMultiServiceFactory</idl> interface (where our IDL-tree is starting), and an Any type (where we put what we want to inspect) :<br />
<source lang="cpp"><br />
//Listing 13 getMethods function<br />
//C++<br />
// translated in C++ from <OpenOffice1.1_SDK>/examples/java/Inspector<br />
<br />
// Don't forget to add : using namespace com::sun::star::beans;<br />
// Don't forget to add : #include <com/sun/star/beans/XIntrospection.hpp><br />
// Don't forget to add "com.sun.star.beans.XIntrospection \" in the makefile<br />
<br />
Sequence <OUString> getMethods(Any any,Reference< XMultiServiceFactory > rSVM)<br />
Reference< XIntrospection >xIntrospection = Reference< XIntrospection ><br />
( rSVM->createInstance(<br />
OUString( RTL_CONSTASCII_USTRINGPARAM(<br />
"com.sun.star.beans.Introspection" ))), UNO_QUERY );<br />
<br />
// ********* get all methods for the given object *********************<br />
<br />
Reference< XIntrospectionAccess > xIntrospec = xIntrospection->inspect(any);<br />
<br />
// Don't forget to add : #include <com/sun/star/beans/MethodConcept.hpp><br />
// Don't forget to add "com.sun.star.beans.MethodConcept \" in the makefile<br />
Sequence< Reference < XIdlMethod > > mMethods = xIntrospec -> getMethods(MethodConcept::ALL);<br />
Sequence<OUString> OUStrs(mMethods.getLength());<br />
for (int i=0;i<mMethods.getLength();i++){<br />
OUString params;<br />
params=OUString::createFromAscii("(");<br />
Sequence< ParamInfo > ParamInfos = mMethods[i]->getParameterInfos();<br />
if (ParamInfos.getLength() > 0) {<br />
for (int j=0;j<ParamInfos.getLength();j++){<br />
Reference< XIdlClass > xIdlClass = ParamInfos[j].aType;<br />
if (j == 0)<br />
// first parameter has no leading comma<br />
params += OUString::createFromAscii("[") + getParamMode(ParamInfos[j].aMode)+<br />
OUString::createFromAscii("]") +<br />
xIdlClass->getName()+ OUString::createFromAscii(" ") + ParamInfos[j].aName;<br />
else<br />
params += OUString::createFromAscii(",[") + getParamMode(ParamInfos[j].aMode)+<br />
OUString::createFromAscii("]")+<br />
xIdlClass->getName()+ OUString::createFromAscii(" ") + ParamInfos[j].aName;<br />
}<br />
}<br />
params += OUString::createFromAscii(")");<br />
OUStrs[i]= mMethods[i]->getName()+params;<br />
}<br />
return OUStrs;<br />
}<br />
</source><br />
See also <idl>com.sun.star.beans.MethodConcept</idl> contants, and <idl>com.sun.star.beans.XIntrospection</idl> interface.<br />
<br />
== Obtaining all the interfaces ==<br />
<br />
Obtaining all the types (or interfaces) is a straight forwarder work as shown in the figure below :<br />
<br />
[[Image:XIntrospectionInterfInfo.png|center]]<br />
<br />
See also <idl>com.sun.star.lang.XTypeProvider</idl> interface.<br />
<br />
The Listing 14 below shows among others the corresponding C++ code.<br />
<br />
== Obtaining all the services == <br />
<br />
Obtaining all the services is more easier with <idl>com.sun.star.lang.XServiceInfo</idl> interface :<br />
<br />
[[Image:XIntrospectionServicesInfo.png|center]]<br />
<br />
Again the Listing 14 below shows the corresponding C++ code.<br />
<br />
== Obtaining all the properties ==<br />
<br />
If you know Java language have a look at SDK :<br />
<OpenOffice.org1.1_SDK>/examples/java/Inspector/InstanceInspector.java<br />
and see the corresponding Java code. <br />
<br />
{{Documentation/Caution|When writing this chapter, I used SDK 1.1 where the Java Inspector was of little size. For the time being [[Object Inspector|the New Inspector]] is biger because able to generate code, and it is certainly more difficult to find useful informations.}}<br />
<br />
The problem of properties values is given here with a C++ class below. Look for the corresponding code.<br />
<br />
== Complete Introspection Class ==<br />
<br />
Before going further have a look to [[Constructing_Helpers#Presentation| Constructing Helpers section]]. Here is the implementation code with <idl>com.sun.star.reflection.XIdlClass</idl>, <idl>com.sun.star.beans.XIntrospection</idl>, <idl>com.sun.star.lang.XTypeProvider</idl>, <idl>com.sun.star.lang.XServiceInfo</idl> and <idl>com.sun.star.beans.XPropertySet</idl> interfaces, with <idl>com.sun.star.beans.PropertyConcept</idl> constants and with <idl>com.sun.star.reflection.ParamMode</idl> enumeration.<br />
<br />
<source lang="cpp"><br />
//Listing 14 Implementation of the reflection helper<br />
// C++<br />
// with help of <OpenOffice1.1_SDK>/examples/java/Inspector<br />
// and Bernard Marcelly XRay tool<br />
// version 0.1 (22 Dec 2004)<br />
// To do : Exception Handling, to go further with properties values<br />
#include "/home/smoutou/OpenOffice.org1.1_SDK/examples/DevelopersGuide/ProfUNO/CppBinding/ReflectionHelper.hpp"<br />
#include <com/sun/star/reflection/XIdlClass.hpp><br />
#include <com/sun/star/beans/PropertyConcept.hpp><br />
#include <com/sun/star/beans/XPropertySet.hpp><br />
//#include <com/sun/star/reflection/ParamMode.hpp> done in ReflectionHelper.hpp<br />
<br />
// constructor<br />
ReflectionHelper::ReflectionHelper(Any any,Reference< XMultiServiceFactory > oSVM)<br />
: toInspect(any), xServiceManager(oSVM){<br />
xIntrospection = Reference< XIntrospection >( xServiceManager->createInstance(<br />
OUString( RTL_CONSTASCII_USTRINGPARAM(<br />
"com.sun.star.beans.Introspection" ))), UNO_QUERY );<br />
xIntrospec = xIntrospection->inspect(toInspect);<br />
mMethods = xIntrospec -> getMethods(MethodConcept::ALL);<br />
xTypeProvider = Reference< XTypeProvider> (toInspect,UNO_QUERY);<br />
types = xTypeProvider->getTypes();<br />
xServiceInfo = Reference< XServiceInfo>(toInspect,UNO_QUERY);<br />
Properties = xIntrospec -> getProperties(PropertyConcept::ALL);<br />
}<br />
<br />
Sequence < OUString > ReflectionHelper::getServices() {<br />
return xServiceInfo->getSupportedServiceNames();<br />
}<br />
<br />
Sequence < OUString > ReflectionHelper::getMethods(){<br />
Sequence< OUString > methods(mMethods.getLength());<br />
for (int i=0;i<mMethods.getLength();i++){<br />
OUString params;<br />
params=OUString::createFromAscii("(");<br />
Sequence< ParamInfo > ParamInfos = mMethods[i]->getParameterInfos();<br />
if (ParamInfos.getLength() > 0) {<br />
for (int j=0;j<ParamInfos.getLength();j++){<br />
Reference< XIdlClass > xIdlClass = ParamInfos[j].aType;<br />
if (j == 0)<br />
// first parameter has no leading comma<br />
params += OUString::createFromAscii("[") + getParamMode(ParamInfos[j].aMode)+<br />
OUString::createFromAscii("]") +<br />
xIdlClass->getName()+ OUString::createFromAscii(" ") + ParamInfos[j].aName;<br />
else<br />
params += OUString::createFromAscii(",[") + getParamMode(ParamInfos[j].aMode)+<br />
OUString::createFromAscii("]")+<br />
xIdlClass->getName()+ OUString::createFromAscii(" ") + ParamInfos[j].aName;<br />
}<br />
}<br />
params += OUString::createFromAscii(")");<br />
methods[i] = mMethods[i]->getReturnType()->getName()+OUString::createFromAscii(" ")+<br />
mMethods[i]->getName()+params;<br />
}<br />
return methods;<br />
}<br />
<br />
Sequence < OUString > ReflectionHelper::getTypes(){<br />
Sequence< OUString > interfaces(types.getLength());<br />
for (int i=0;i<types.getLength();i++){<br />
interfaces[i] = types[i].getTypeName();<br />
}<br />
return interfaces;<br />
}<br />
<br />
// to improve : change all the tests with getCppuType : probably quicker than a string test<br />
OUString ReflectionHelper::getValueName(Any object){<br />
OUString OUStr;<br />
OUStr = OUString::createFromAscii("!! No computed value !!");<br />
if (object.hasValue()) {<br />
if (object.isExtractableTo(getCppuBooleanType())){<br />
sal_Bool MyBool;<br />
object >>= MyBool;<br />
return OUStr.valueOf((sal_Bool) MyBool);<br />
} else<br />
if (object.getValueTypeName() == OUString::createFromAscii("string")) {<br />
OUString *MyOUStr;<br />
MyOUStr = (OUString *) object.getValue();<br />
OUStr = OUString::createFromAscii("\"");<br />
return OUStr + *MyOUStr + OUString::createFromAscii("\"");<br />
} else<br />
if (object.getValueTypeName() == OUString::createFromAscii("long")) {<br />
sal_Int32 *MyLong;<br />
MyLong = (sal_Int32*) object.getValue();<br />
return OUStr.valueOf((sal_Int32) *MyLong);<br />
} else<br />
if (object.getValueTypeName() == OUString::createFromAscii("short")) {<br />
sal_Int16 *MyShort;<br />
MyShort = (sal_Int16*) object.getValue();<br />
return OUStr.valueOf((sal_Int32) *MyShort);<br />
} else<br />
if (object.getValueTypeName() == OUString::createFromAscii("[]byte")) {<br />
Sequence< sal_Int8 > SeqByte;<br />
object >>= SeqByte;<br />
OUStr = OUString::createFromAscii("Length:");<br />
OUStr=OUStr.concat(OUStr.valueOf((sal_Int32) SeqByte.getLength()));<br />
for (sal_Int32 i=0; i<SeqByte.getLength(); i++){<br />
OUStr=OUStr.concat(OUStr.valueOf((sal_Int32) SeqByte[i]));<br />
OUStr=OUStr.concat(OUString::createFromAscii(" "));<br />
}<br />
return OUStr;<br />
} else<br />
if (object.getValueTypeName() == OUString::createFromAscii("[]string")) {<br />
Sequence< OUString > SeqOUStr;<br />
object >>= SeqOUStr;<br />
OUStr = OUString::createFromAscii("Length:");<br />
OUStr=OUStr.concat(OUStr.valueOf((sal_Int32) SeqOUStr.getLength())+<br />
OUString::createFromAscii(" : "));<br />
for (sal_Int32 i=0; i<SeqOUStr.getLength(); i++){<br />
OUStr=OUStr.concat(OUString::createFromAscii("\"")<br />
+SeqOUStr[i]<br />
+ OUString::createFromAscii("\""));<br />
}<br />
return OUStr;<br />
} else return OUStr;<br />
} else return OUStr;<br />
}<br />
<br />
// Get properties with values : only those computed in getValueName<br />
Sequence < OUString > ReflectionHelper::getPropertiesWithValues(){<br />
Sequence< OUString > propWithVal(Properties.getLength());<br />
for (int i=0;i<Properties.getLength();i++){<br />
Type typ = getCppuType( (const Reference< XPropertySet > *)0);<br />
Reference< XPropertySet > rPropertySet(xIntrospec->queryAdapter(typ),UNO_QUERY);<br />
Reference< XPropertySetInfo > rPropertySetInfo=rPropertySet->getPropertySetInfo();<br />
Any object; if (rPropertySetInfo->hasPropertyByName(Properties[i].Name)){<br />
object <<= rPropertySet->getPropertyValue(Properties[i].Name);<br />
//if (object.hasValue()) printf("Valeur trouvee : \n");<br />
propWithVal[i] = Properties[i].Name + OUString::createFromAscii(" = (")+<br />
Properties[i].Type.getTypeName() + OUString::createFromAscii(") ")<br />
+ getValueName(object);<br />
}<br />
}<br />
return propWithVal;<br />
}<br />
<br />
// Get properties without values but types<br />
Sequence < OUString > ReflectionHelper::getPropertiesWithoutValues(){<br />
Sequence< OUString > propWithVal(Properties.getLength());<br />
for (int i=0;i<Properties.getLength();i++){<br />
Type typ = getCppuType( (const Reference< XPropertySet > *)0);<br />
Reference< XPropertySet > xPropertySet(xIntrospec->queryAdapter(typ),UNO_QUERY);<br />
Reference< XPropertySetInfo > xPropertySetInfo=xPropertySet->getPropertySetInfo();<br />
if (xPropertySetInfo->hasPropertyByName(Properties[i].Name)){<br />
propWithVal[i] = Properties[i].Name + OUString::createFromAscii(" = (")+<br />
Properties[i].Type.getTypeName() + OUString::createFromAscii(")");<br />
}<br />
}<br />
return propWithVal;<br />
}<br />
<br />
// Don't forget to add : #include <com/sun/star/reflection/ParamMode.hpp><br />
// Don't forget to add "com.sun.star.reflection.ParamMode \" in the makefile<br />
OUString ReflectionHelper::getParamMode(ParamMode paramMode) {<br />
OUString toReturn;<br />
toReturn = OUString::createFromAscii("");<br />
if (paramMode == ParamMode_IN) toReturn = OUString::createFromAscii("IN"); else<br />
if (paramMode == ParamMode_OUT) toReturn = OUString::createFromAscii("OUT"); else<br />
if (paramMode == ParamMode_INOUT) toReturn = OUString::createFromAscii("INOUT");<br />
return toReturn;<br />
}<br />
</source><br />
{{Documentation/Caution|<br />
Because it's hard to maintain the same code in many places, I have added a [[Development/Cpp/Helper/ReflectionHelper|Snippet here]]. I will only update this snippet and then, it will be the more recent complete class code.}}<br />
This is quite a lot of code. Let's give a schematic representation (added with other in this article).<br />
<br />
== Shematic Representation of properties ==<br />
<br />
Obtaining properties with values is a difficult task. I hope the Figure below will help you to understand the code.<br />
<br />
[[Image:PropertiesIntrospection.png]]<br />
<br />
{{Documentation/Caution|After a verification, the question marks after XInterface can be removed.}}<br />
<br />
See also <idl>com.sun.star.lang.XMultiServiceFactory</idl>, <idl>com.sun.star.beans.XIntrospection</idl>, <idl>com.sun.star.beans.XIntrospectionAccess</idl>, <idl>com.sun.star.beans.XPropertySet</idl> and <idl>com.sun.star.beans.XPropertySetInfo</idl> interfaces.<br />
<br />
{{Documentation/Caution|<br />
This code use getValueName for the moment because of the difficulties I encounter to resolve the problem of printing out the values of properties. I think I don't use the better way to solve it : that problem should be better resolved with improving the use of getCppuType or seeing an other way with Any type.}}<br />
<br />
Go back to [[IDL_Files_and_Cpp|IDL Files and C++]]<br />
<br />
=See also=<br />
* Using C++ with OOo SDK : [[Using_Cpp_with_the_OOo_SDK | Main Page]]<br />
* Using [[IDL_Files_and_Cpp#Using_Java_Inspector|Java Inspector]]<br />
* 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<br />
* Bernard Marcelly's [[Extensions_development_basic#Xray_tool|XRay tool description]] in this wiki<br />
* See also [[Object Inspector|The New Object Inspector]]<br />
<br />
<br />
{{Template:Home_Page}}</div>BMarcellyhttps://wiki.openoffice.org/wiki/IDL_Files_and_CppIDL Files and Cpp2016-05-01T06:22:38Z<p>BMarcelly: /* Reflection in OOoBasic */</p>
<hr />
<div>{{Documentation/NeedsRework}}<br />
[[IDL_Files_and_Cpp zh|中]]<br />
<br />
For an introduction, you can read the [http://udk.openoffice.org/cpp/man/component_tutorial.html component tutorial].<br />
<br />
= Services and Interfaces =<br />
== Introduction ==<br />
See [[Documentation/BASIC_Guide/API_Intro|Introduction the OpenOffice.org API]] or [[Extensions_development_basic#Introducing_the_OpenOffice.org_API|Introducing the OpenOffice.org API]].<br />
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. <br />
<br />
'''[[CppSDKAuthors|Danny Brewer's]] rules'''<br />
<br />
Services are similar to objects in java. <br />
<br />
1. A service can inherit from zero or one other service. (which each service can recursively follow these rules.)<br />
<br />
2. A service can include zero or more services. (which each service can recursively follow these rules.)<br />
<br />
3. A service can export (implement) interfaces.<br />
<br />
4. A service can have properties. <br />
<br />
5. An interface can inherit from zero or one other interface. (which each interface can recursively follow these rules.)<br />
<br />
6. An interface can include from zero or more interfaces. (which each interface can recursively apply these rules.)<br />
<br />
7. An interface can implement methods.<br />
<br />
8. An interface is always named with an X. <br />
<br />
From these rules you can deduce that methods are ALWAYS found in interfaces, and properties are ALWAYS found in services.<br />
<br />
See also [[Extensions_development_basic#Introducing_the_OpenOffice.org_API|Introducing the OpenOffice.org_API]] and [[Extensions_development_basic#Introspection|OOoBasic Introspection]] and [[Documentation/DevGuide/FirstSteps/Objects%2C_Interfaces%2C_and_Services|Developer's Guide]].<br />
<br />
==UNO programming and IDL-tree==<br />
I have already tackled the IDL-tree notion in a previous chapter (see [[Programming_OooWriter#Going_further_with_Inspector|Going further with Java Inspector]] This section seems to be place to go further in the explanations.<br />
<br />
We have enough experience in UNO programming until now and then we can deduce few rules for C++ language.<br />
<br />
'''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]].<br />
{{Documentation/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.}}<br />
<br />
'''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++]].<br />
<br />
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 :<br />
#[[Programming_OooWriter#Path_of_IDL-tree_with_a_textual_Description|Path of IDL-tree with a textual Descrition]].<br />
#[[Programming_OooWriter#Path_of_IDL-tree_with_a_Introspection_Tool|Path of IDL-tree with an Introspection Tool]] or with [[Writing_Professional_Components#My_own_Inspector|the cpp Inspector]].<br />
#[[UNO_automation_with_a_binary_%28executable%29#Introduction_to_Bootstrapping|Diagram and Path of IDL-tree]] for the boostrapping problem.<br />
<br />
Before tackling how to realize path through IDL-tree in C++, we come back to IDL files as specifier for modules, interfaces and services.<br />
<br />
= IDL specification =<br />
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. <br />
The way to specify simple modules with IDL is so straightforward that we choose to give only examples at first.<br />
<br />
==Specifying an interface==<br />
We choose as an example, the interface XdrivingDirection. The Figure below shows you the corresponding interface :<br />
<br />
[[Image:Service&Interface.png]]<br />
<br />
And now the corresponding IDL file :<br />
<br />
<source lang="idl"><br />
// IDL<br />
interface XdrivingDirection<br />
{<br />
void turnLeft();<br />
void turnRight();<br />
};<br />
</source><br />
<br />
==Specifying a service==<br />
Example above is still used, here is the corresponding IDL specification :<br />
<source lang="idl"><br />
// IDL<br />
interface XdrivingDirection<br />
{<br />
void turnLeft();<br />
void turnRight();<br />
};<br />
interface XaccelerationControl<br />
{<br />
void speedUp();<br />
void slowDown();<br />
};<br />
service car<br />
{<br />
// exported interfaces:<br />
interface XdrivingDirection;<br />
interface XaccelerationControl;<br />
[attribute] float speed; <br />
[attribute] float angle;<br />
};<br />
</source><br />
We see a float type and we would use other IDL types later.<br />
<br />
== Specifying a module ==<br />
Now, the same example would give this IDL specification :<br />
<source lang="idl"><br />
// IDL<br />
module my_module<br />
{<br />
interface Xsomething<br />
{<br />
void methodone();<br />
};<br />
service my_service1<br />
{<br />
// exported interfaces:<br />
interface Xsomething;<br />
};<br />
interface XsomethingElse<br />
{<br />
void methodTwo();<br />
void methodThree();<br />
};<br />
service my_service2<br />
{<br />
// exported interfaces:<br />
interface XsomethingElse;<br />
};<br />
};<br />
</source><br />
<br />
== Further with IDL ==<br />
The IDL's types are :<br />
<TABLE WIDTH=100% BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0><br />
<TR VALIGN=TOP><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale"><FONT COLOR="#000000">char</FONT> </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">16-bit unicode character type </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">boolean </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">boolean type; true and false</FONT></P><br />
</TD><br />
</TR><br />
<TR VALIGN=TOP><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">byte </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">8-bit ordinal integer type </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">short </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">signed 16-bit ordinal integer type </FONT><br />
</P><br />
</TD><br />
</TR><br />
<TR VALIGN=TOP><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">unsigned short </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">unsigned 16-bit ordinal integer type </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">long </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">signed 32-bit ordinal integer type</FONT></P><br />
</TD><br />
</TR><br />
<TR VALIGN=TOP><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">unsigned long</FONT></P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">unsigned 32-bit integer type </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">hyper </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">signed 64-bit ordinal integer type</FONT></P><br />
</TD><br />
</TR><br />
<TR VALIGN=TOP><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">unsigned hyper</FONT></P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">unsigned 64-bit ordinal integer type </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">float </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">processor dependent float</FONT></P><br />
</TD><br />
</TR><br />
<TR VALIGN=TOP><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">double</FONT></P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">processor dependent double </FONT><br />
</P><br />
<br />
</TD><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">string</FONT></P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">string of 16-bit unicode characters</FONT></P><br />
</TD><br />
</TR><br />
<TR VALIGN=TOP><br />
<TD WIDTH=12%><br />
<P><FONT FACE="Thorndale">any</FONT></P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">universal type, takes every fundamental<br />
or compound UNO type, similar to Variant in other environments or<br />
Object in Java</FONT></P><br />
</TD><br />
<TD WIDTH=12%><br />
<br />
<P><FONT FACE="Thorndale">void </FONT><br />
</P><br />
</TD><br />
<TD WIDTH=38%><br />
<P><FONT FACE="Thorndale">Indicates that a method does not<br />
provide a return value</FONT></P><br />
</TD><br />
</TR><br />
</TABLE><br />
<br />
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 : [[Counter_Example#IDL_File|the counter example]].<br />
<br />
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.<br />
An example of interface inheritance :<br />
<source lang="idl"><br />
//IDL<br />
interface animal {<br />
attribute long age;<br />
};<br />
interface dog : animal {<br />
attribute short leg;<br />
}<br />
</source><br />
Multiple inheritance is also possible :<br />
<source lang="idl"><br />
// IDL<br />
interface dog{<br />
interface animal;<br />
interface friend;<br />
}<br />
</source><br />
Inheritance in service is presented in the next chapter.<br />
<br />
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 encounter properties manipulation when examining [[Working_with_Shapes|shapes]].<br />
<br />
= Gathering UNO information with IDL files =<br />
There are several ways to find information on UNO.<br />
<br />
One way is to use OooBasic and Bernard Marcelly's Xray tool (see [[Extensions_development_basic#X-Ray_tool|XRay tool description]] in this wiki). '''Problem''' : OooBasic doesn't show exact methods and properties.<br />
<br />
An other way is to use web service at : [http://api.openoffice.org/docs/common/ref/index-files/index-1.html General OOoWEB Index]<br />
<br />
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).<br />
<br />
== [[CppSDKAuthors|Danny Brewer 's]] Point of View ==<br />
<br />
Nonetheless, it is important to understand the concept of a "service" in the API docs. A service is just a way to group.... <br />
# more services <br />
# interfaces <br />
The (1) more services part, of course, means that there are even more interfaces available at the original service. <br />
Let me give a different example. <br />
<idl>com.sun.star.sheet.SpreadsheetDocument</idl> is a service. <br />
<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 :<br />
<source lang="idl"><br />
//Listing 7 Interface Specification<br />
//IDL<br />
service SpreadsheetDocument<br />
{<br />
//-------------------------------------------------------------------------<br />
<br />
/** common service for all types of documents.<br />
*/<br />
service com::sun::star::document::OfficeDocument;<br />
<br />
..........<br />
<br />
//-------------------------------------------------------------------------<br />
<br />
/** provides access to the collection of spreadsheets.<br />
*/<br />
interface com::sun::star::sheet::XSpreadsheetDocument;<br />
<br />
//------------------------------------------------------------------------- <br />
</source><br />
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. <br />
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.<br />
<br />
<code>SpreadsheetDocument</code> service has <idl>com.sun.star.sheet.XSpreadsheetDocument</idl> interface. <br />
<code>OfficeDocument</code> has interfaces <idl>com.sun.star.view.XPrintable</idl> and <idl>com.sun.star.frame.XStorable</idl>. <br />
Since <code>SpreadsheetDocument</code> includes <code>OfficeDocument</code>, it is therefore valid to queryInterface for either <idl>com.sun.star.view.XPrintable</idl> or <idl>com.sun.star.frame.XStorable</idl> from a <code>SpreadsheetDocument</code>. <br />
<br />
Now in the above discussion, substitute TextDocument for SpreadsheetDocument.<br />
How to tell what is the underlying service? <br />
<br />
There is no magic formula for that. Generally it is obvious. If you load a Spreadsheet, then you have the <idl>com.sun.star.sheet.SpreadsheetDocument</idl> service. <br />
<br />
Similarly, if I create an object by its service name.....<br />
<source lang=oobas> <br />
oShape = oDoc.createUnoService( "com.sun.star.drawing.EllipseShape" )<br />
</source> <br />
then I know what service it is, because I gave the service name. <br />
<br />
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. <br />
<br />
In some cases, it is fairly clear what service you have. <br />
<br />
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 <code>SheetCellRange</code> does represent a rectangular group of cells, while a <code>SheetCell</code> 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. <br />
<br />
There are other issues as well. If you get a <idl>com.sun.star.table.CellRange</idl> 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 <idl>com.sun.star.sheet.SheetCellRange</idl>. 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. <br />
<br />
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.<br />
<br />
== An other concrete Example ==<br />
<br />
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|UNO registery and Bootstrapping]])<br />
<br />
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) :<br />
<source lang="idl"><br />
//Listing 8 Interface Specification<br />
//IDL<br />
service OfficeDocument<br />
{<br />
interface com::sun::star::frame::XModel;<br />
interface com::sun::star::util::XModifiable;<br />
interface com::sun::star::frame::XStorable;<br />
interface com::sun::star::view::XPrintable;<br />
[optional] interface XEventBroadcaster;<br />
[optional] interface XEventsSupplier;<br />
[optional] interface XDocumentInfoSupplier;<br />
[optional] interface XViewDataSupplier;<br />
[optional] interface com::sun::star::view::XPrintJobBroadcaster;<br />
[property, optional] boolean AutomaticControlFocus;<br />
[property, optional] boolean ApplyFormDesignMode;<br />
};<br />
</source><br />
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 :<br />
<source lang="idl"><br />
//Listing 8<br />
service TextDocument<br />
{<br />
service com::sun::star::document::OfficeDocument;<br />
interface com::sun::star::text::XTextDocument;<br />
interface com::sun::star::util::XSearchable;<br />
interface com::sun::star::util::XRefreshable;<br />
....<br />
};<br />
</source><br />
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 : <br />
<br />
<br />
[[Image:TextDocumentWithMethods.png|none|thumb|450px| From Developer's Guide.]]<br />
<br />
Remember we have already tackled Interfaces in [[IDL_Files_and_Cpp#IDL_specification|this section]]. <br />
<br />
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.<br />
<br />
==C++ and services : it's not so easy==<br />
{{Documentation/Tip|<br />
If you really want to understand this section, at every variable ask yourself what services are available.}}<br />
<br />
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]]).<br />
<source lang="cpp"> <br />
//Listing 9 Writer Example<br />
//C++<br />
OUString sDocUrl;<br />
osl::FileBase::getFileURLFromSystemPath(<br />
OUString::createFromAscii("/home/smoutou/Documents/demo.sxw"),sDocUrl);<br />
<br />
Reference< XComponent > xWriterComponent = <br />
rComponentLoader->loadComponentFromURL(<br />
sDocUrl,<br />
OUString::createFromAscii("_blank"),<br />
0,<br />
Sequence < ::com::sun::star::beans::PropertyValue >());<br />
<br />
Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);<br />
</source><br />
<br />
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. <br />
<br />
<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. <br />
<br />
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 [http://api.openoffice.org/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]].<br />
<source lang="cpp"><br />
//Listing 10 Writer Example (continuation)<br />
//C++<br />
Reference< XText > xText = xTextDocument->getText();<br />
</source><br />
We try to get a XTextCursor Interface<br />
<source lang="cpp"><br />
//Listing 11 Writer Example (continuation)<br />
//C++<br />
Reference< XTextCursor> xTextCursor = xText->createTextCursor();<br />
</source><br />
But how to explain this code ? Looking for in XText.idl files only shows two methods :<br />
<source lang="idl"><br />
//Listing 12 XText Interface IDL file<br />
// IDL<br />
module com { module sun { module star { module text { <br />
interface XText: com::sun::star::text::XSimpleText<br />
{ <br />
void insertTextContent( [in] com::sun::star::text::XTextRange xRange, <br />
[in] com::sun::star::text::XTextContent xContent, <br />
[in] boolean bAbsorb ) <br />
raises( com::sun::star::lang::IllegalArgumentException ); <br />
void removeTextContent( [in] com::sun::star::text::XTextContent xContent ) <br />
raises( com::sun::star::container::NoSuchElementException ); <br />
<br />
}; <br />
}; }; }; };<br />
</source><br />
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.<br />
<source lang="idl"> <br />
//Listing 13 XSimpleText Interface IDL file<br />
// IDL<br />
module com { module sun { module star { module text { <br />
interface XSimpleText: com::sun::star::text::XTextRange<br />
{ <br />
com::sun::star::text::XTextCursor createTextCursor(); <br />
com::sun::star::text::XTextCursor createTextCursorByRange( [in] com::sun::star::text::XTextRange aTextPosition ); <br />
[oneway] void insertString( [in] com::sun::star::text::XTextRange xRange, <br />
[in] string aString, <br />
[in] boolean bAbsorb ); <br />
void insertControlCharacter( [in] com::sun::star::text::XTextRange xRange, <br />
[in] short nControlCharacter, <br />
[in] boolean bAbsorb ) <br />
raises( com::sun::star::lang::IllegalArgumentException ); <br />
<br />
};<br />
}; }; }; };<br />
</source><br />
What are the services available here ? I have found them with a reflection tool :<br />
<pre><br />
******** Services : 8<br />
com.sun.star.text.TextSortable<br />
com.sun.star.style.ParagraphPropertiesComplex<br />
com.sun.star.style.ParagraphPropertiesAsian<br />
com.sun.star.style.ParagraphProperties<br />
com.sun.star.style.CharacterPropertiesComplex<br />
com.sun.star.style.CharacterPropertiesAsian<br />
com.sun.star.style.CharacterProperties<br />
com.sun.star.text.TextCursor<br />
</pre><br />
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]].<br />
<br />
{{Documentation/Note|It's using a method returning an Interface Type which make things difficult. To find then services is very difficult and personnally, 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 new, two methods gives us explicitly the returned type : <code>createInstance</code> and <code>createInstanceWithContext</code> where the service is given as a paramter.}}<br />
<br />
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.<br />
<br />
= IDL and C++ =<br />
This problem is tackled in [[Documentation/DevGuide/ProUNO/C%2B%2B/C%2B%2B_Language_Binding| Developer's guide]].<br />
<br />
== Getting an interface in C++ ==<br />
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 "[[SDKCppLanguage|SDK C++ language]]" and many other in [[UNO_automation_with_a_binary_%28executable%29|Office UNO automation]]. <br />
<br />
===Obtaining an Interface with a buit-in function===<br />
We have already encountered such an use when [[UNO_automation_with_a_binary_%28executable%29#Introduction_to_Bootstrapping| studying bootstrapping code]]. Here is a schematic representation.<br />
<br />
[[Image:BuiltInInterface.png|none|thumb|600px|Obtaining XComponentContext Interface ]]<br />
<br />
We start from nothing but use the <code>defaultBootstrap_IntitialComponentContext()</code> built-in function and get an <idl>com.sun.star.uno.XComponentContext</idl> interface.<br />
<br />
===Obtaining an Interface with UNO_QUERY macro===<br />
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:<br />
<source lang="cpp"><br />
//Listing 2 C++ code to get a service<br />
//C++<br />
Reference<com::sun::star::text::XTextDocument> OfDoc = something_to_get_this_interface();<br />
</source><br />
or<br />
<source lang="cpp"><br />
Listing 3 using namespace to simplify the code<br />
//C++<br />
using namespace com::sun::star::text;<br />
....<br />
Reference<XTextDocument> OfDoc = something_to_get_this_interface();<br />
</source><br />
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. <br />
<br />
[[Image:SimpleUNOQUERY.png|center]]<br />
<br />
Note that we can query all the interfaces shown from <idl>com.sun.star.util.XTextDocument</idl>, even though the diagram omits some of the red arrows.<br />
<br />
====Three steps to have an interface====<br />
<br />
Three steps are involved in this query :<br />
<br />
'''Step 1''' Add your code's line as UNO's query<br />
<source lang="cpp"><br />
//Listing 4 The UNO query in C++ code<br />
// C++<br />
// query from com::sun::star::frame::XStorable interface<br />
Reference< XStorable > oToStore (OfDoc, UNO_QUERY);<br />
</source> <br />
If the variable is already declared, please use :<br />
<source lang="cpp"><br />
//Listing 4b The UNO query in C++ code<br />
// C++<br />
// query from com::sun::star::frame::XStorable interface<br />
oToStore = Reference< XStorable > (OfDoc, UNO_QUERY);<br />
</source> <br />
<br />
'''Step 2''' Add the hpp file in an include statement. Add the corresponding namespace in an using namespace statement. Including is done with :<br />
<source lang="cpp"><br />
//Listing 5 The corresponding include statement<br />
//C++<br />
#include <com/sun/star/frame/XStorable.hpp><br />
</source><br />
and the corresponding namespace statement is :<br />
<source lang="cpp"><br />
//Listing 6 The corresponding namespace statement<br />
//C++<br />
using namespace com::sun::star::frame;<br />
</source><br />
<br />
'''Step 3''' Add the corresponding type in the makefile as shown below (XStorable line) :<br />
<pre><br />
# makefile<br />
# added com.sun.star.frame.XStorable<br />
TYPES := \<br />
com.sun.star.uno.XNamingService \<br />
....<br />
com.sun.star.uno.XAggregation \<br />
com.sun.star.frame.XStorable \<br />
com.sun.star.lang.XMain \ <br />
...<br />
com.sun.star.container.XHierarchicalNameAccess<br />
</pre><br />
{{Documentation/Note|<br />
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.}}<br />
<br />
====Concrete Example====<br />
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 :<br />
<br />
[[Image:SimpleUNOQUERY2.png|center|thumb|600px|Querying an Interface starting from an other]]<br />
<br />
And here is the correponding code.<br />
<source lang="cpp"><br />
//Listing 19 Simple UNO_QUERY call<br />
// C++<br />
OUString sDocUrl;<br />
osl::FileBase::getFileURLFromSystemPath(<br />
OUString::createFromAscii("/home/smoutou/Documents/demo.sxw"),sDocUrl);<br />
Reference< XComponent > xWriterComponent = rComponentLoader->loadComponentFromURL(<br />
sDocUrl,<br />
OUString::createFromAscii("_blank"),<br />
0,<br />
Sequence < ::com::sun::star::beans::PropertyValue >());<br />
<br />
Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);<br />
// Don't forget to include #include <com/sun/star/frame/XStorable.hpp><br />
Reference < XStorable > xStorable (xTextDocument,UNO_QUERY);<br />
xStorable->store();<br />
</source><br />
which use <idl>com.sun.star.text.XTextDocument</idl> and <idl>com.sun.star.frame.XStorable</idl> interfaces.<br />
<br />
You have to learn to get interface in an other way, with first asking a service.<br />
<br />
===Getting an Interface through XMultiServiceFactory===<br />
See also [[Uno/Cpp/Snippet/Instantiate_a_Service|Instantiate a Service snippet]].<br />
<br />
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.<br />
<br />
====The Problem====<br />
How can you get an interface if the corresponding service is not directly available ? This is shwon in the figure below :<br />
<br />
[[Image:ComplexUNOQUERY.png]]<br />
<br />
where both services <idl>com.sun.star.text.TextDocument</idl> and <idl>com.sun.star.text.TextTable</idl> haven't a direct dependance.<br />
<br />
====The Solutions====<br />
<br />
'''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 !<br />
<br />
[[Image:InterfaceParMethode.png|center|thumb|600px|Direct Method to query an Interface]]<br />
<br />
'''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 [[IDL_Files_and_Cpp#Three_steps_to_have_an_interface|three steps operation]].<br />
<br />
'''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 :<br />
<br />
<source lang="cpp"><br />
//Listing 20 Getting an Interface with XMultiServiceFacory<br />
// C++<br />
Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);<br />
<br />
Reference<XMultiServiceFactory> oDocMSF (xTextDocument,UNO_QUERY);<br />
// Don't forget to add #include <com/sun/star/text/XTextTable.hpp><br />
Reference <XTextTable> xTable (oDocMSF->createInstance(<br />
OUString::createFromAscii("com.sun.star.text.TextTable")),UNO_QUERY);<br />
</source><br />
<br />
which uses two instruction style with <idl>com.sun.star.text.XTextDocument</idl> and <idl>com.sun.star.text.XTextTable</idl> interfaces. <br />
<br />
With three instructions style, the same code is shown in the listing above :<br />
<br />
<source lang="cpp"><br />
//Listing 21 Inserting a Table in a OOoWriter Document<br />
// C++<br />
Reference<XMultiServiceFactory> oDocMSF (xTextDocument,UNO_QUERY);<br />
<br />
Reference< XInterface > textTable = oDocMSF->createInstance(<br />
OUString::createFromAscii("com.sun.star.text.TextTable") );<br />
// Don't forget to add #include <com/sun/star/text/XTextTable.hpp><br />
Reference< XTextTable > xTable(textTable, UNO_QUERY);<br />
</source><br />
<br />
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.<br />
<br />
[[Image:ComplexUNOQUERY2.png|center|thumb|600px|Obtaining a service]]<br />
<br />
'''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.<br />
<br />
<source lang="cpp"><br />
//Listing 22 Wrong code<br />
// C++<br />
// Reference<XMultiServiceFactory> oDocMSF (xTextDocument,UNO_QUERY);<br />
// using rOfficeServiceManager instead oDocMSF<br />
Reference< XInterface > textTable = rOfficeServiceManager->createInstance(<br />
OUString::createFromAscii("com.sun.star.text.TextTable") );<br />
Reference< XTextTable > xTable(textTable, UNO_QUERY);<br />
if (!xTable.is()) {<br />
printf("Erreur creation XTextTable interface !\n");<br />
return 1;<br />
}<br />
</source><br />
<br />
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. <br />
<br />
{{Documentation/Caution|<br />
If you are working with a document ask the corresponding XMultiServiceFactory interface. At this point only experience can help you.}}<br />
<br />
====An other example already tackled====<br />
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 :<br />
<br />
<source lang="cpp"><br />
//Listing 23 Classic code<br />
// C++<br />
int main( ) {<br />
//retrieve an instance of the remote service manager<br />
Reference< XMultiServiceFactory > rOfficeServiceManager;<br />
rOfficeServiceManager = ooConnect();<br />
<br />
//get the desktop service using createInstance returns an XInterface type<br />
Reference< XInterface > Desktop = rOfficeServiceManager->createInstance(<br />
OUString::createFromAscii( "com.sun.star.frame.Desktop" ));<br />
<br />
//query for the XComponentLoader interface<br />
Reference< XComponentLoader > rComponentLoader (Desktop, UNO_QUERY);<br />
</source><br />
<br />
Easy to retreive 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 ?<br />
<br />
Here is the corresponding IDL-tree.<br />
<br />
[[Image:ch4fig2Componentloader.png|center|thumb|600px|Obtaining XComponentLoader Interface]]<br />
<br />
{{Documentation/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.}}<br />
<br />
An other 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]].<br />
<br />
== Mapping for Modules and Interfaces ==<br />
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 :<br />
*[[SDKCppLanguage#To_go_further_:_the_Enumeration_Type_Problem|The UNO enumeration types]]<br />
*[[SDKCppLanguage#To_go_further_:_the_Constant_Type_Problem|The UNO Constants types]]<br />
*[[Calc/API/Programming#Retrieve_the_absolute_X_and_Y_Positions_of_a_Cell|The UNO Structures]]<br />
<br />
See [[Documentation/DevGuide/ProUNO/C%2B%2B/Type_Mappings|Developer's Guide]] for a more complete explanation.<br />
<br />
Other examples are provided now. For instance: <br />
<pre><br />
// IDL <br />
module M <br />
{ struct E { long L; <br />
}; <br />
}; <br />
</pre><br />
is mapped into: <br />
<source lang="cpp"><br />
// C++ <br />
namespace M <br />
{ struct E <br />
{ Long L; }; <br />
}<br />
</source><br />
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:<br />
<source lang="cpp"> <br />
// C++ <br />
using namespace M; <br />
E e;<br />
e.L = 3;<br />
</source><br />
<br />
= Core reflection service and its Interfaces =<br />
<br />
Many entry points for reflection are descibed in the [[Documentation/DevGuide/AdvUNO/UNO_Reflection_API|Developer's Guide]]. We give again any of them here and show a way to use them with C++.<br />
<br />
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.<br />
<br />
== Reflection in OOoBasic==<br />
{{Documentation/Caution|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]].}}<br />
<br />
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 :<br />
<source lang="oobas"><br />
REM ***** BASIC *****<br />
Sub Main <br />
oReflection = createUnoService( "com.sun.star.reflection.CoreReflection" ) <br />
oInfo = oReflection.forName( "nom.dannybrewer.test.XDannysCalcFunctions1" ) <br />
aMethods = oInfo.getMethods() <br />
For i = 0 To UBound( aMethods ) <br />
oMethod = aMethods( i ) <br />
Print oMethod.getName() <br />
Next <br />
End Sub<br />
</source><br />
We then create an idl file : <br />
<source lang="idl"><br />
// IDL<br />
#include <com/sun/star/uno/XInterface.idl><br />
#include <com/sun/star/lang/XInitialization.idl><br />
<br />
module my_module<br />
{<br />
<br />
interface XSomething : com::sun::star::uno::XInterface<br />
{<br />
long getCount();<br />
void setCount( [in] long nCount );<br />
long increment();<br />
long decrement();<br />
};<br />
<br />
service MyService<br />
{<br />
interface XSomething;<br />
};<br />
};<br />
</source><br />
<br />
With this IDL file, we create a rdb file and register this rdb file. Now OpenOffice.org 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. <br />
We then modify the above Danny's program : <br />
<source lang="oobas"><br />
REM Listing 11 <br />
REM ***** BASIC *****<br />
'From Danny : http://www.oooforum.org/forum/viewtopic.php?t=8737 <br />
Sub Main<br />
oReflection = createUnoService( "com.sun.star.reflection.CoreReflection" )<br />
oInfo = oReflection.forName( "my_module.XSomething" )<br />
aMethods = oInfo.getMethods()<br />
'XRay oInfo<br />
print UBound( aMethods )+1 & " methods : ****"<br />
For i = 0 To UBound( aMethods )<br />
oMethod = aMethods( i )<br />
Print oMethod.getName()<br />
Next<br />
<br />
aTypes = oInfo.getTypes()<br />
print UBound( aTypes )+1 & " types : ****"<br />
For i = 0 To UBound( aTypes )<br />
oType = aTypes( i )<br />
Print "Types : " + oType.getName()<br />
Next<br />
<br />
aInterfaces = oInfo.getInterfaces()<br />
print UBound( aInterfaces )+1 & " interfaces : ****"<br />
For i = 0 To UBound( aInterfaces )<br />
oInterface = aInterfaces( i )<br />
Print "Interfaces : " + oInterface.getName()<br />
Next<br />
End Sub <br />
</source><br />
launching this modified program produces :<br />
<pre><br />
7 methods : ****<br />
queryInterface acquire release getCount setCount increment decrement<br />
3 types : ****<br />
Types : com.sun.star.reflection.XIdlClass<br />
Types : com.sun.star.lang.XTypeProvider<br />
Types : com.sun.star.uno.XWeak<br />
0 Interfaces : ****<br />
</pre><br />
We can see among others the four methods given in the IDL file.<br />
<br />
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 :<br />
<source lang="oobas"><br />
For i = LBound( oMethods ) To UBound( oMethods )<br />
oMethod = oMethods( i )<br />
' Check the method's interface to see if<br />
' these aren't the droids you're looking for.<br />
sString = oMethod.getReturnType().getName() & " " & oMethod.getName() & "("<br />
parametersInfo = oMethod.getParameterInfos()<br />
if UBound(parametersInfo) > 0 then<br />
for ii=0 to UBound(parametersInfo)<br />
if parametersInfo(ii).aMode = com.sun.star.reflection.ParamMode.IN Then<br />
stringType = "IN "<br />
elseif parametersInfo(ii).aMode = com.sun.star.reflection.ParamMode.OUT Then<br />
stringType = "OUT "<br />
else<br />
stringType = "INOUT "<br />
end if <br />
sString = sString & stringType & ParametersInfo(ii).aType.getName() & " " & parametersInfo(ii).aName<br />
if ii < UBound(parametersInfo) Then sString = sString & ", "<br />
Next<br />
end if<br />
sString = sString & ")"<br />
' something to do with sString here<br />
Next<br />
</source><br />
To go further in C++, we examine XdlRefection Interface in next section.<br />
<br />
== XIdlReflection interface ==<br />
<br />
The <idl>com.sun.star.reflection.XIdlReflection</idl> Interface is described in the section [[Documentation/DevGuide/AdvUNO/UNO_Reflection_API | CoreReflection Service in Developer's Guide]]. This interface is also described [[XIDLReflection_Interface |here]] with C++ code example.<br />
<br />
== The XIntrospection Interface ==<br />
<br />
This interface <idl>com.sun.star.beans.XIntrospection</idl> is described [[XIntrospection_Interface |here]] with C++ code examples. Other code is given in [[Constructing_Helpers#Reflection_Helper|Constructing Helpers]] section.<br />
See also [[Extensions_development_basic#Introducing_the_OpenOffice.org_API|Introducing the OpenOffice.org_API]] and [[Extensions_development_basic#Introspection|OOoBasic Introspection]] and [[Documentation/DevGuide/AdvUNO/UNO_Reflection_API | Developer's Guide]].<br />
<br />
= Using Java Inspector =<br />
For an introduction of using Java with OOo, see [[JavaEclipseTuto|Java and Eclipse tutorial]]. This point is not tackled here : we are only interested by using a Java component with C++.<br />
<br />
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 :<br />
<br />
1°) Compile the java example in <OpenOffice.org_SDK>/examples/java/Inspector after adding SDK_AUTO_DEPLOYMENT = YES in the beginning of makefile.<br />
<br />
2°) Create a OOoBasic example, for instance (OOo1.1.X) :<br />
<source lang="oobas"><br />
'Listing 17 Simple OOoBasic example to call the Java Inspector<br />
<br />
REM ***** BASIC *****<br />
Sub JavaInspector <br />
o = createUnoService("org.OpenOffice.InstanceInspector")<br />
'XRay o<br />
oReflection = createUnoService( "com.sun.star.reflection.CoreReflection" )<br />
o.inspect(oReflection) <br />
End Sub<br />
</source><br />
{{Documentation/Note|<br />
For newer version of Java Inspector see [[Object_Inspector#Calling_from_a_Basic_Macro|Calling from a Basic Macro]].}}<br />
<br />
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.<br />
We see below in Figure what is the result of this program.<br />
<br />
[[Image:Inspector3.png|Old Java Object Inspector]]<br />
<br />
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 :<br />
<br />
# construct a urd file starting from IDL (in makefile)<br />
# don't forget the registry of urd file in makefile<br />
# add org.OpenOffice.XInstanceInspector in the TYPES macro in the makefile<br />
# copy IDL file from <OpenOffice.org1.1_SDK>/examples/java/Inspector/XInstanceInspector.idl into <OpenOffice.org1.1_SDK>/idl/org/OpenOffice/ XInstanceInspector.idl<br />
# add the #include <org/OpenOffice/XInstanceInspector.hpp> and using namespace org::OpenOffice;<br />
# add this code<br />
<source lang="cpp"><br />
// C++<br />
Any toInspect;<br />
toInspect <<= rDesktop;<br />
Reference< XInstanceInspector > xinspect (rOfficeServiceManager->createInstance(<br />
OUString::createFromAscii( "org.OpenOffice.InstanceInspector" )),UNO_QUERY);<br />
xinspect->inspect(toInspect);<br />
</source><br />
And it works like in OOoBasic.<br />
<br />
The corresponding Linux makefile is :<br />
<pre><br />
#Listing 18 Simple Makefile to compile a Java Inspector C++ call<br />
# very simple makefile<br />
HELPER = ReflectionHelper<br />
CXXFILE = office_connect.cxx<br />
OBJFILE = office_connect.o<br />
OUTBIN = office_connect<br />
OUT_COMP_INC = ../../../../LINUXexample.out/inc<br />
OUT_COMP_OBJ = ../../../../LINUXexample.out/obj<br />
OUT_COMP_BIN = ../../../../LINUXexample.out/bin<br />
# added for Inspector<br />
OUT_COMP_URD = $(OUT_COMP_BIN)<br />
# end added<br />
COMPONENT_RDB = $(OUT_COMP_BIN)/office_connect.rdb<br />
CC_FLAGS = -c -O -fpic -fno-rtti<br />
CC_DEFINES = -DUNX -DGCC -DLINUX -DCPPU_ENV=gcc3<br />
PS = /<br />
TYPES := \<br />
com.sun.star.uno.XNamingService \<br />
....<br />
com.sun.star.container.XHierarchicalNameAccess \<br />
org.OpenOffice.XInstanceInspector<br />
# last line added<br />
<br />
TYPESLIST = $(foreach t,$(TYPES),-T$(t))<br />
GENHPPFILES = $(foreach t,$(TYPES),$(OUT_COMP_INC)/$(subst .,/,$(t)).hpp)<br />
<br />
ALL : \<br />
ProUNOCppBindingExample<br />
<br />
# added for Inspector<br />
#building urd file<br />
$(OUT_COMP_URD)/XInstanceInspector.urd : ../../../../idl/org/OpenOffice/XInstanceInspector.idl<br />
-mkdir -p $(OUT_COMP_URD)<br />
idlc -I. -I../../../../idl -O$(OUT_COMP_URD) ../../../../idl/org/OpenOffice/XInstanceInspector.idl<br />
<br />
# end added<br />
<br />
#office_connectrc is provided with SDK<br />
$(OUT_COMP_BIN)/office_connectrc : office_connectrc<br />
-mkdir -p $(OUT_COMP_BIN)<br />
cp office_connectrc $(OUT_COMP_BIN)/office_connectrc<br />
<br />
$(COMPONENT_RDB) : $(OUT_COMP_URD)/XInstanceInspector.urd<br />
-mkdir -p $(OUT_COMP_BIN)<br />
# added for Inspector<br />
regmerge $(COMPONENT_RDB) /UCR $(OUT_COMP_URD)/XInstanceInspector.urd<br />
# end added<br />
regmerge $(COMPONENT_RDB) / "/usr/lib/openoffice/program/types.rdb"<br />
@echo --------------------------------------------------------------------------------<br />
@echo Register necessary runtime components in $(COMPONENT_RDB)<br />
@echo --------------------------------------------------------------------------------<br />
regcomp -register -r $(COMPONENT_RDB) -c connector.uno.so<br />
regcomp -register -r $(COMPONENT_RDB) -c remotebridge.uno.so<br />
regcomp -register -r $(COMPONENT_RDB) -c bridgefac.uno.so<br />
regcomp -register -r $(COMPONENT_RDB) -c uuresolver.uno.so<br />
# @echo bla > $@<br />
<br />
$(GENHPPFILES) : $(subst /,$(PS),$(@D))<br />
mkdir -p $(subst /,$(PS),$(@D))<br />
# modified for Inspector cppumaker -Gc -BUCR -O$(OUT_COMP_INC) $(TYPESLIST) "/usr/lib/openoffice/program/types.rdb"<br />
cppumaker -Gc -BUCR -O$(OUT_COMP_INC) $(TYPESLIST) $(COMPONENT_RDB)<br />
<br />
$(OUT_COMP_OBJ)/$(OBJFILE) : $(CXXFILE) $(GENHPPFILES) $(HELPER).hpp<br />
-mkdir -p $(subst /,$(PS),$(@D))<br />
gcc $(CC_FLAGS) $(CC_INCLUDES) -I. -I/usr/include -I$(OUT_COMP_INC)/examples \<br />
-I../../../../include -I$(OUT_COMP_INC) $(CC_DEFINES) -o$(OUT_COMP_OBJ)/$(OBJFILE) $(CXXFILE)<br />
<br />
$(OUT_COMP_OBJ)/$(HELPER).o : $(HELPER).cxx $(HELPER).hpp<br />
-mkdir -p $(OUT_COMP_OBJ)/<br />
gcc $(CC_FLAGS) $(CC_INCLUDES) -I. -I/usr/include -I$(OUT_COMP_INC)/examples \<br />
-I../../../../include -I$(OUT_COMP_INC) $(CC_DEFINES) -o$(OUT_COMP_OBJ)/$(HELPER).o $(HELPER).cxx<br />
<br />
<br />
$(OUT_COMP_BIN)/$(OUTBIN) : $(OUT_COMP_OBJ)/$(OBJFILE) $(OUT_COMP_OBJ)/$(HELPER).o<br />
-mkdir -p $(OUT_COMP_BIN)<br />
gcc -Wl -export-dynamic -L../../../../LINUXexample.out/lib -L../../../../linux/lib -L/usr/lib/openoffice/program \<br />
$(OUT_COMP_OBJ)/$(HELPER).o \<br />
-o$(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_OBJ)/$(OBJFILE) -lcppuhelpergcc3 -lcppu -lsalhelpergcc3 -lsal -lstlport_gcc<br />
<br />
<br />
ProUNOCppBindingExample : $(COMPONENT_RDB) $(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_BIN)/office_connectrc<br />
@echo --------------------------------------------------------------------------------<br />
@echo Please use one of the following commands to execute the examples!<br />
@echo<br />
@echo make office_connect.run<br />
@echo --------------------------------------------------------------------------------<br />
<br />
office_connect.run : $(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_BIN)/office_connectrc<br />
cd $(OUT_COMP_BIN) && $(OUTBIN)<br />
</pre><br />
<br />
{{Documentation/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 check the above code with the [[Object Inspector|the new object inspector]] but don't see why it could not work properly.}}<br />
<br />
{{Documentation/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.}}<br />
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 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.<br />
<br />
= Translating OOoBasic programs into C++ =<br />
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.<br />
<br />
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.<br />
<br />
<source lang="oobas"><br />
'Listing 36 Simple OOoBasic program to translate<br />
REM **** OOoBasic<br />
Dim MyDocument As Object, MyText As Object<br />
Dim MyCursor As Object<br />
MyDocument = ThisComponent<br />
MyText = MyDocument.Text<br />
MyCurseur= MyTexte.createTextCursor<br />
MyCurseur.goRight(1, false) ' move right one character<br />
MyCurseur.goLeft(2, true) ' select the two previous characters<br />
</source><br />
<br />
I summarize OOoBasic instructions to move the cursor in the above table :<br />
<br />
; OOoBasic instructions<br />
{| border cellspacing="0" width="650"<br />
|- style = "background:#b3e2d1;text-align:center"<br />
| |Method||Signification<br />
|- style="text-align:left"<br />
| goRight(n, false)||moves the cursor the specified number of characters to the right<br />
|- style="text-align:left"<br />
|goLeft(n, false) ||moves the cursor the specified number of characters to the left<br />
|- style="text-align:left"<br />
|gotoStart(false) ||moves the cursor to the start of the text<br />
|- style="text-align:left"<br />
|gotoEnd(false)||moves the cursor to the end of the text<br />
|- style="text-align:left"<br />
|gotoStartOfParagraph(false)||moves the cursor to the start of the current paragraph<br />
|- style="text-align:left"<br />
|gotoStartOfParagraph(false) ||moves the cursor to the start of the current paragraph<br />
|- style="text-align:left"<br />
|gotoEndOfParagraph(false) ||moves the cursor to the end of the current paragraph<br />
|- style="text-align:left"<br />
|gotoNextParagraph(false)||moves the cursor to the next paragraph<br />
|- style="text-align:left"<br />
|gotoPreviousParagraph(false) ||moves the cursor to the previous paragraph<br />
|- style="text-align:left"<br />
|gotoNextWord(false) ||moves the cursor to the next word<br />
|- style="text-align:left"<br />
|gotoPreviousWord(false) ||moves the cursor to the previous word<br />
|- style="text-align:left"<br />
|gotoStartOfWord(false) ||mmoves the cursor to the start of the current word<br />
|- style="text-align:left"<br />
|gotoEndOfWord(false) ||moves the cursor to the end of the current word<br />
|- style="text-align:left"<br />
|gotoNextSentence(false) ||moves the cursor to the start of the next sentence<br />
|- style="text-align:left"<br />
|gotoPreviousSentence(false) ||moves the cursor to the start of the previous sentence<br />
|- style="text-align:left"<br />
|gotoStartOfSentence(false) ||moves the cursor to the start of the current sentence<br />
|- style="text-align:left"<br />
|gotoEndOfSentence(false) ||moves the cursor to the end of the current sentence<br />
|}<br />
<br />
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 differents cursors interfaces are involved when using the methods of OOoBasic starting program. It's time to show all the corresponding IDL files.<br />
First of all the XWordCursor interface is shown :<br />
<source lang="idl"><br />
//Listing 37 XWordCursor interface (IDL file)<br />
// IDL<br />
module com { module sun { module star { module text { <br />
interface XWordCursor: com::sun::star::text::XTextCursor<br />
{ <br />
boolean isStartOfWord(); <br />
boolean isEndOfWord(); <br />
boolean gotoNextWord( [in] boolean bExpand ); <br />
boolean gotoPreviousWord( [in] boolean bExpand ); <br />
boolean gotoEndOfWord( [in] boolean bExpand ); <br />
boolean gotoStartOfWord( [in] boolean bExpand ); <br />
}; <br />
}; }; }; }; <br />
</source><br />
<br />
Now the XParagraphCursor interface is shown<br />
<source lang="idl"><br />
//Listing 38 XParagraphCursor interface (IDL file)<br />
// IDL<br />
module com { module sun { module star { module text { <br />
interface XParagraphCursor: com::sun::star::text::XTextCursor<br />
{ <br />
com::sun::star::text::XParagraphCursor::isStartOfParagraph<br />
boolean isStartOfParagraph(); <br />
boolean isEndOfParagraph(); <br />
com::sun::star::text::XParagraphCursor::gotoStartOfParagraph<br />
boolean gotoStartOfParagraph( [in] boolean bExpand ); <br />
com::sun::star::text::XParagraphCursor::gotoEndOfParagraph<br />
boolean gotoEndOfParagraph( [in] boolean bExpand ); <br />
boolean gotoNextParagraph( [in] boolean bExpand ); <br />
com::sun::star::text::XParagraphCursor::gotoPreviousParagraph<br />
boolean gotoPreviousParagraph( [in] boolean bExpand ); <br />
<br />
}; <br />
}; }; }; }; <br />
</source><br />
<br />
and to finish XSentenceCursor interface : <br />
<source lang="idl"><br />
// Listing 39 XSentenceCursor interface (IDL file)<br />
// IDL<br />
module com { module sun { module star { module text { <br />
interface XSentenceCursor: com::sun::star::text::XTextCursor<br />
{ <br />
boolean isStartOfSentence(); <br />
boolean isEndOfSentence(); <br />
boolean gotoNextSentence( [in] boolean Expand ); <br />
boolean gotoPreviousSentence( [in] boolean Expand ); <br />
boolean gotoStartOfSentence( [in] boolean Expand ); <br />
boolean gotoEndOfSentence( [in] boolean Expand ); <br />
}; <br />
<br />
//============================================================================= <br />
<br />
}; }; }; };<br />
</source><br />
<br />
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.<br />
<br />
<source lang="idl"><br />
//Listing 40 TextCursor service (IDL file)<br />
// IDL<br />
module com { module sun { module star { module text {<br />
service TextCursor<br />
{<br />
service com::sun::star::text::TextRange;<br />
interface com::sun::star::text::XTextCursor;<br />
[optional] interface com::sun::star::text::XWordCursor;<br />
[optional] interface com::sun::star::text::XSentenceCursor;<br />
[optional] interface com::sun::star::text::XParagraphCursor;<br />
interface com::sun::star::beans::XPropertySet;<br />
interface com::sun::star::beans::XPropertyState;<br />
interface com::sun::star::beans::XMultiPropertyStates;<br />
[optional] interface com::sun::star::document::XDocumentInsertable;<br />
[optional] interface com::sun::star::util::XSortable;<br />
};<br />
}; }; }; }; <br />
</source><br />
<br />
If you start for instance from Listing 11 you will need a UNO_QUERY to get a XWordCursor interface.<br />
<source lang="cpp"><br />
//Listing 41 Using XwordCursor Interface<br />
// C++<br />
// Don't forget to add : #include <com/sun/star/text/XWordCursor.hpp><br />
// Don't forget to add "com.sun.star.text.XWordCursor \" in the makefile <br />
Reference < XWordCursor > xWordCursor (xTextCursor,UNO_QUERY);<br />
xWordCursor->gotoNextWord(false); <br />
xWordCursor->gotoNextWord(false); <br />
xWordCursor->gotoNextWord(true);<br />
</source><br />
The translation could be achieve automatically, but such a compiler has to have knowledge on IDL files.<br />
<br />
By the way here we have again all these eight services availables :<br />
<pre><br />
******** Services : 8<br />
com.sun.star.text.TextSortable<br />
com.sun.star.style.ParagraphPropertiesComplex<br />
com.sun.star.style.ParagraphPropertiesAsian<br />
com.sun.star.style.ParagraphProperties<br />
com.sun.star.style.CharacterPropertiesComplex<br />
com.sun.star.style.CharacterPropertiesAsian<br />
com.sun.star.style.CharacterProperties<br />
com.sun.star.text.TextCursor<br />
</pre><br />
<br />
==Further reading==<br />
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.<br />
<br />
=Home Page=<br />
{{Template:Home_Page}}<br />
<br />
= See Also =<br />
* [[FR/Documentation/Fichiers_IDL_et_C%2B%2B|French version of this chapter]].<br />
* [[Documentation/DevGuide/AdvUNO/UNO_Reflection_API|UNO Reflection API]] in Developer's Guide<br />
* [[Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno|C++ and UNO tutorial]]<br />
* [[Tutorial_UNO_Library|UNO tutorial]]<br />
* [[Tutorial_UNO_IDL|UNO IDL]]<br />
* [[Uno/Article/Types%26Reflection]] <br />
* [[Documentation/BASIC_Guide/API_Intro|Introduction to the OpenOffice.org API]]<br />
* 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<br />
* See also [[Object Inspector|The New Object Inspector]]<br />
* [[Extensions_introspection|Extensions Introspection]]<br />
* [[BASIC/UNO_Object_Browser|BASIC UNO Object Browser]]<br />
<br />
<br />
<br />
[[Category:Cpp]]<br />
[[Category:Uno]]<br />
[[Category:Tutorial]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Constructing_ComponentsConstructing Components2016-05-01T06:18:11Z<p>BMarcelly: /* See also */</p>
<hr />
<div>{{Documentation/Candidate}}<br />
{{Documentation/NeedsRework}}<br />
You want to extend OpenOffice.org in a way. The first step is to define what your goals are; what do you want achieve ? You then produce a shared library with suffix uno.so under Linux or uno.dll under Windows. You load your library into OpenOffice.org by using a rdb file and an operation called registry. Registry basics have already been detailed in [[UNO_registery_and_Bootstrapping|UNO registry and Bootstrapping]].<br />
<br />
=Danny Brewer's Terminology=<br />
<br />
You can read first in this wiki [[Extensions|the extensions terminology]].<br />
You can also read [http://www.oooforum.org/forum/viewtopic.php?t=13335&postdays=0&postorder=asc&start=0 here] :<br />
<br />
Let's clarify some terminology. <br />
<br />
* '''Add On''' <br />
A menu item on the Tools menu, and an icon on the toolbar. <br />
By modifying the Configuration sub node for AddOn, you can add new menu items and toolbar icon items to the AddOn menu or toolbar icon. <br />
Basic programs can modify the Configuration to add some Add On items to the menu. It is not necessary to use pkgchk. <br />
Components (see below) can also add things to the AddOn menu or toolbar when the component is installed using pkgchk. <br />
<br />
* '''Add In''' <br />
A component (see below) which provides new Calc spreadsheet functions. <br />
These functions show up on the Function List and Insert --> Function... dialog box. The dialog box can then fully describe your functions, their parameters, provide tooltips, etc. <br />
<br />
* '''[[Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno#C.2B.2B_components|Component]]''' <br />
An UNO [[Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno#C.2B.2B_components|Component]], written in any supported programming language, which must be installed using the pkgchk command. (This would be "pkgchk.exe" for Windows users.) <br />
A component provides one or more new Services which are registered in the OOo registry. These services can be instantiated just like the factory installed services in OOo. For instance, in Basic, you can just call createUnoService( "name.DannyBrewer.magic.SomeService" ) to get an instance of the service, and then immediately call its methods or properties. Similarly, Python or Java, or Visual Basic, or any other language can use the newly installed service. <br />
<br />
A component provides one or more services. See for instance [[IDL_Files_and_Cpp#Using_Java_Inspector|Using Java Inspector]] component.<br />
<br />
* '''Service''' <br />
An UNO abstraction for an Object. A service may not actually represent a single underlying object. A service may have many different interfaces which it implements. A service has properties. What methods are callable on the service are determined purely by what interfaces the service implements. <br />
<br />
Since a Calc Add-In is just a component, which implements certain particular interfaces and services, the Calc AddIn is installed and registered in the same way as any other component. That is, a Calc AddIn is installed or removed by using pkgchk. <br />
Making a Calc Add-In is just like making any other service. You must be a particular com.sun.star.sheet.AddIn service, and must properly implement all of its interfaces, of which there are several. But once you do this, your service magically provides new functions to the spreadsheet. Calc Add-In are tackled the next [[CompleteAddIn|chapter]]. You can find an introduction on addIn also [[SimpleCalcAddIn|here]].<br />
<br />
= Compilation Chain of a Component=<br />
To create a UNO component, you require an IDL file and a cpp file. The entire process is illustrated in the figure below. The final goal is to create a uno.so and a rdb file. If you want more information on binary tools in the compilation chain, have a look at the corresponding chapter in [[Documentation/DevGuide/WritingUNO/Required_Files|Developer's Guide]].<br />
<br />
<br />
[[Image:ComponentTools.png]]<br />
<br />
The black arrows in the figure above indicate how to create one file type from another. For example, use idlc to create some.urd starting from some.idl. The red arrow indicates that regcomp is used to place the name of the library done into the rdb file rather than create the rdb file. Finally, the blue arrows indicate a dependency.<br />
The entire process is as follows :<br />
# Create the idl and cpp files. Figure above shows these files as some.idl and some.cpp.<br />
# Use idlc to compile the idl file to a urd file.<br />
# Transform the urd file to the rdb file using regmerge. The rdb file is not yet complete because it must contain the name of the uno.so file, which is added at the end using regcomp.<br />
# Use cppumaker to create the hpp and hdl header files.<br />
# Use gcc to compile the cpp file.<br />
# The final registry step has been discussed previously and is not shown in Figure above.<br />
<br />
{{Documentation/Note|'''Service Managers''' UNO uses a factory concept to instantiate components in a target environment. This factory is called the service manager. The service manager maintains a database of registered components. Your application can instantiate and communicate with any component known by the service manager, no matter what language it was implemented in. Communication takes place through interface calls specified by the UNO IDL. See ''' Creating a ServiceManager from a Given Registry File''' in [[Documentation/DevGuide/WritingUNO/Special_Service_Manager_Configurations|Developer's Guide]].}}<br />
<br />
To create a component, you must first create an idl file. The IDL file describes the interface. The goal of the following examples, is to create a component, visible to OpenOffice.org more specifically, visible from OOoBasic. The SDK contains an example in: “<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/Components/CppComponent” and also described in [[Documentation/DevGuide/WritingUNO/C%2B%2B/C%2B%2B_Component|Developer's Guide]]. <br />
The view described above is only important when you wonder how a component is constructed. If you want to know what you have to do when writing a component an other view is needed ; it is described later with the corresponding three rules.<br />
<br />
=First Example : accessing a Counter from OOoBasic=<br />
<br />
Our first goal is to transform a counter into a component. A counter is perhaps not great but a good start. The inspiration comes to me with the following two SDK's examples :<br />
*<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/Components/CppComponent (used in previous section) and also descibed in [[Documentation/DevGuide/WritingUNO/C%2B%2B/C%2B%2B_Component|Developer'sGuide]].<br />
*<OpenOffice.org1.1_SDK>/examples/cpp/counter<br />
The problem with the counter example given above with the SDK is its inaccessibility from OOoBasic. A component callable from OOoBasic and then from all other programming language is called scriptable. We begin describing the counter.<br />
<br />
== A very simple Counter==<br />
We give in this section our start : a counter.cxx file and a countermain.cxx file working all together. Please note that this example would be simpler if not constructed for OpenOffice.org. It's only given here to present our start. From this start we will wonder a lot of questions showing I hope how components work. I will use sometimes UML notations in this chapter.<br />
===Single File Implementation===<br />
We plan to realize our counter with one file (except the header file) in this section :<br />
<source lang="cpp"><br />
//Listing 1 The Counter<br />
//c++<br />
#include <stdio.h><br />
#include "counter.hxx"<br />
<br />
MyCounterImpl::MyCounterImpl()<br />
: m_nCount( 0 )<br />
{ printf( "< MyCounterImpl ctor called >\n" ); }<br />
MyCounterImpl::~MyCounterImpl()<br />
{ printf( "< MyCounterImpl dtor called >\n" ); }<br />
int MyCounterImpl::getCount() <br />
{ return m_nCount; }<br />
void MyCounterImpl::setCount( int nCount ) <br />
{ m_nCount = nCount; }<br />
int MyCounterImpl::increment() <br />
{ return (++m_nCount); }<br />
int MyCounterImpl::decrement() <br />
{ return (--m_nCount); }<br />
<br />
int main(int argc, char **argv)<br />
{<br />
MyCounterImpl Cnt;<br />
Cnt.setCount(50);<br />
printf("-- %d\n",Cnt.getCount());<br />
Cnt.increment();<br />
printf("-- %d\n",Cnt.getCount());<br />
Cnt.decrement();<br />
printf("-- %d\n",Cnt.getCount());<br />
return 0;<br />
}<br />
</source><br />
<br />
with the header file<br />
<br />
<source lang="cpp"><br />
//Listing 2 The header File of the Counter<br />
// C++<br />
// counter.hxx<br />
class MyCounterImpl {<br />
int m_nCount;<br />
public:<br />
MyCounterImpl();<br />
~MyCounterImpl();<br />
int getCount();<br />
void setCount( int nCount ); <br />
int increment(); <br />
int decrement() ;<br />
};<br />
</source><br />
<br />
What we want is to separate the code in two files : one for the class : counter.cxx and a second for the utilisation of the class countermain.cxx. The counter.cxx will be compiled in counter.so file and countermain will use this dynamic library.<br />
<br />
===Two Files Implementation===<br />
The corresponding way in C++ is again illustrated. First the dynamic library :<br />
<br />
<source lang="cpp"><br />
//Listing 3 Dynamic library<br />
//c++<br />
//counter.cxx<br />
#include <stdio.h><br />
#include "counter.hxx"<br />
<br />
MyCounterImpl::MyCounterImpl()<br />
: m_nCount( 0 )<br />
{ printf( "< MyCounterImpl ctor called >\n" ); }<br />
MyCounterImpl::~MyCounterImpl()<br />
{ printf( "< MyCounterImpl dtor called >\n" ); }<br />
int MyCounterImpl::getCount() <br />
{ return m_nCount; }<br />
void MyCounterImpl::setCount( int nCount ) <br />
{ m_nCount = nCount; }<br />
int MyCounterImpl::increment() <br />
{ return (++m_nCount); }<br />
int MyCounterImpl::decrement() <br />
{ return (--m_nCount); }<br />
</source><br />
<br />
This file is compiled with :<br />
<br />
<pre><br />
gcc -shared -fPIC -o counter.uno.so counter.cxx<br />
</pre><br />
<br />
To use it I write this code :<br />
<br />
<source lang="cpp"><br />
//Listing 4 Main executable<br />
//c++<br />
//countermain.cxx<br />
#include "counter.hxx"<br />
#include <stdio.h><br />
int main(int argc, char **argv)<br />
{<br />
MyCounterImpl Cnt;<br />
Cnt.setCount(50);<br />
printf("-- %d\n",Cnt.getCount());<br />
Cnt.increment();<br />
printf("-- %d\n",Cnt.getCount());<br />
Cnt.decrement();<br />
printf("-- %d\n",Cnt.getCount());<br />
return 0;<br />
}<br />
</source><br />
<br />
The compilation is then done with<br />
<br />
<pre><br />
gcc -o test1 countermain.cxx -L ./ counter.uno.so -lstdc++<br />
</pre><br />
<br />
Running this example gives :<br />
<br />
<pre><br />
[smoutou@p3 component]$ ./test1<br />
< MyCounterImpl ctor called ><br />
-- 50<br />
-- 51<br />
-- 50<br />
< MyCounterImpl dtor called ><br />
</pre><br />
<br />
This example is done without Openoffice.org. In the contrary the example given in the SDK make exacly the same but needs OpenOffice.org. Problems with shared library and C++ are examined [[Uno/Cpp/Tutorials/Global_References|here]].<br />
<br />
==Making the Counter registrable==<br />
All dynamic libraries are not registrable. Taking the one constructed in previous section and give it to register, what's happening ?<br />
<pre><br />
[smoutou@p3 bin]$ regcomp -register -r counter.uno.rdb -c counter.uno.so<br />
Aborted<br />
</pre><br />
Regcomp is completely unable to do correctly its job. Why ? <br />
If you want to be able to registry something you have to follow strict rules.<br />
* '''Rule 1'''<br />
You have to construct first an [[Documentation/DevGuide/WritingUNO/Using_UNOIDL_to_Specify_New_Components|IDL file]]. This IDL file allows you to construct an urd file and to add it in a rdb file. This has already been discussed above.<br />
See the figure below.<br />
<br />
[[Image:Registery.png]]<br />
<br />
When examining this figure you see that a some.idl file is required (and naturally a uno.so file).<br />
<br />
* '''Rule 2'''<br />
Your dynamic library have to contain extern C subprograms. Their names are :<br />
<source lang="cpp"><br />
// C++<br />
extern "C" void SAL_CALL component_getImplementationEnvironment(<br />
sal_Char const ** ppEnvTypeName, uno_Environment ** ppEnv );<br />
<br />
extern "C" sal_Bool SAL_CALL component_writeInfo(<br />
lang::XMultiServiceFactory * xMgr, registry::XRegistryKey * xRegistry );<br />
<br />
extern "C" void * SAL_CALL component_getFactory(<br />
sal_Char const * implName, lang::XMultiServiceFactory * xMgr, void * );<br />
</source><br />
First and second subroutines are for registry and third is for allowing UNO_QUERY calls. More information [[Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno#Exported_symbols|here]] where a fourth optional extern C subprogram is presented : getDescription.<br />
<br />
* '''Rule 3 (provisional rule)'''<br />
Your component has to provide some other interfaces that those described in your IDL file : <idl>com.sun.star.uno.XInterface</idl>, <idl>com.sun.star.lang.XServiceInfo</idl>. The counter example provide these interfaces as shown in the listing below :<br />
<source lang="cpp"><br />
//Listing 5 The counter interfaces<br />
// C++<br />
class MyCounterImpl<br />
: public XCountable<br />
, public XServiceInfo<br />
{<br />
....<br />
</source><br />
I suppose XCountable is an inheritance from XInterface. <br />
The figure above shows us a component in a schematic view.<br />
<br />
[[Image:ComponentInterface.png]]<br />
<br />
The external rectangle in Figure above represents the component. In this component, we see a XCountable interface inheriting from XInterface and XServiceInfo and the three extern C callable functions.<br />
<br />
The definitive rule 3 is presented <br />
[[Constructing_Components#Using_an_Helper_to_construct_the_scriptable_Counter|later]]: please be patient or read the [[Documentation/DevGuide/WritingUNO/Core_Interfaces_to_Implement|Developer's Guide]] on the subject.<br />
<br />
== The Counter Example (from SDK) ==<br />
<br />
The Counter is provided with SDK here : <OpenOffice.org_SDK>/examples/cpp/counter. See a description of the [[Counter_Example|SDK counter example]].<br />
<br />
=== Modifying the simple Counter to see registry at Work===<br />
Again, we start with the counter example included in the SDK at <OpenOffice.org1.1_SDK>/examples/cpp/counter.<br />
We modify it to see in the console how registry works and particularly the necessity of the rule 2 described in [[Constructing_Components#Making_the_Counter_registerable|a previous section]]. The modification only consists of adding printf as shown in the listing below. The goal is to help us to see how it works.<br />
<source lang="cpp"><br />
//Listing 7 Modified Counter Component (extract)<br />
// C++<br />
.....<br />
<br />
//*************************************************************************<br />
OUString SAL_CALL MyCounterImpl::getImplementationName( )<br />
throw(RuntimeException)<br />
{<br />
printf("MyCounterImpl::getImplementationName( ) called \n");<br />
return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) );<br />
}<br />
//*************************************************************************<br />
sal_Bool SAL_CALL MyCounterImpl::supportsService( const OUString& ServiceName )<br />
throw(RuntimeException)<br />
{<br />
printf("MyCounterImpl::supportsService called\n");<br />
Sequence< OUString > aSNL = getSupportedServiceNames();<br />
const OUString * pArray = aSNL.getArray();<br />
for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )<br />
if( pArray[i] == ServiceName )<br />
return sal_True;<br />
return sal_False;<br />
} <br />
<br />
//*************************************************************************<br />
Sequence<OUString> SAL_CALL MyCounterImpl::getSupportedServiceNames( )<br />
throw(RuntimeException)<br />
{<br />
printf("MyCounterImpl::getSupportedServiceNames( ) called \n");<br />
return getSupportedServiceNames_Static();<br />
}<br />
<br />
//*************************************************************************<br />
Sequence<OUString> SAL_CALL MyCounterImpl::getSupportedServiceNames_Static( )<br />
{<br />
OUString aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) );<br />
printf("MyCounterImpl::getSupportedServiceNames_Static( ) called with <br />
%s\n",RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));<br />
return Sequence< OUString >( &aName, 1 );<br />
}<br />
<br />
/**<br />
* Function to create a new component instance; is needed by factory helper implementation.<br />
* @param xMgr service manager to if the components needs other component instances<br />
*/<br />
Reference< XInterface > SAL_CALL MyCounterImpl_create(<br />
const Reference< XMultiServiceFactory > & xMgr )<br />
{ printf("MyCounterImpl_create called\n");<br />
return Reference< XCountable >( new MyCounterImpl( xMgr ) );<br />
}<br />
<br />
//#####################################################################################<br />
//#### EXPORTED ####################################################################################<br />
//######################################################################################<br />
/**<br />
* Gives the environment this component belongs to.<br />
*/<br />
extern "C" void SAL_CALL component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName, <br />
uno_Environment ** ppEnv) {<br />
printf("getImplementationEnvironnement return %s\n",CPPU_CURRENT_LANGUAGE_BINDING_NAME);<br />
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;<br />
}<br />
<br />
/**<br />
* This function creates an implementation section in the registry and another subkey<br />
*<br />
* for each supported service.<br />
* @param pServiceManager the service manager<br />
* @param pRegistryKey the registry key<br />
*/<br />
extern "C" sal_Bool SAL_CALL component_writeInfo(void * pServiceManager, void * pRegistryKey)<br />
{<br />
sal_Bool result = sal_False;<br />
printf("component_writeInfo called\n");<br />
if (pRegistryKey)<br />
{<br />
try<br />
{<br />
Reference< XRegistryKey > xNewKey(<br />
reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey(<br />
OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME "/UNO/SERVICES") ) ) );<br />
printf("New key : %s\n",RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME "/UNO/SERVICES"));<br />
printf("--component_writeInfo calls MyCounterImpl::getSupportedServiceNames_Static()\n");<br />
const Sequence< OUString > & rSNL =<br />
MyCounterImpl::getSupportedServiceNames_Static();<br />
const OUString * pArray = rSNL.getConstArray();<br />
for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) {<br />
xNewKey->createKey( pArray[nPos] );<br />
printf("----Sub-Key : %s build\n",OUStringToOString(pArray[nPos],<br />
RTL_TEXTENCODING_ASCII_US)<br />
.pData->buffer);<br />
}<br />
return sal_True;<br />
}<br />
catch (InvalidRegistryException &)<br />
{<br />
// we should not ignore exceptions<br />
}<br />
}<br />
return result;<br />
}<br />
<br />
/**<br />
* This function is called to get service factories for an implementation.<br />
*<br />
* @param pImplName name of implementation<br />
* @param pServiceManager a service manager, need for component creation<br />
* @param pRegistryKey the registry key for this component, need for persistent data<br />
* @return a component factory<br />
*/<br />
/**/<br />
extern "C" void * SAL_CALL component_getFactory(const sal_Char * pImplName, <br />
void * pServiceManager, void * pRegistryKey){<br />
void * pRet = 0;<br />
printf("component_getFactory called\n");<br />
if (rtl_str_compare( pImplName, IMPLNAME ) == 0)<br />
{<br />
Reference< XSingleServiceFactory > xFactory( createSingleFactory(<br />
reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),<br />
OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ),<br />
MyCounterImpl_create,<br />
MyCounterImpl::getSupportedServiceNames_Static() ) );<br />
<br />
if (xFactory.is())<br />
{<br />
xFactory->acquire();<br />
pRet = xFactory.get();<br />
}<br />
}<br />
return pRet;<br />
}<br />
</source><br />
<br />
With countermain slightly modified to know where the registry begins, this piece of code produces the following output :<br />
<pre><br />
[smoutou@p3 counter]$ make countermain.run<br />
cd ../../../LINUXexample.out/bin && countermain<br />
Here begin registry<br />
getImplementationEnvironnement return gcc3<br />
component_writeInfo called<br />
New key : /com.sun.star.comp.example.cpp.Counter/UNO/SERVICES<br />
--component_writeInfo calls MyCounterImpl::getSupportedServiceNames_Static()<br />
MyCounterImpl::getSupportedServiceNames_Static( ) called with foo.Counter<br />
----Sub-Key : foo.Counter build<br />
Here ends registry and begin instanciation<br />
getImplementationEnvironnement return gcc3<br />
component_getFactory called<br />
MyCounterImpl::getSupportedServiceNames_Static( ) called with foo.Counter<br />
MyCounterImpl_create called<br />
< MyCounterImpl2 ctor called ><br />
42,43,42<br />
Another registry use : getImplementations<br />
-- com.sun.star.comp.bridge.UnoUrlResolver<br />
< MyCounterImpl2 dtor called ><br />
[smoutou@p3 counter]$<br />
</pre><br />
while a direct regcomp call produces this following output :<br />
<pre><br />
[smoutou@p3 bin]$ regcomp -register -r counter.uno.rdb -c counter.uno.so<br />
getImplementationEnvironnement return gcc3<br />
component_writeInfo called<br />
New key : /com.sun.star.comp.example.cpp.Counter/UNO/SERVICES<br />
--component_writeInfo calls MyCounterImpl::getSupportedServiceNames_Static()<br />
MyCounterImpl::getSupportedServiceNames_Static( ) called with foo.Counter<br />
----Sub-Key : foo.Counter build<br />
register component 'counter.uno.so' in registry 'counter.uno.rdb' succesful!<br />
[smoutou@p3 bin]$<br />
</pre><br />
We can draw from both shell ouputs that registry works the same way, in the both case as expected. The first call is asking for Environment which return “gcc3” here, and after componentwriteinfo which is responsible of registry itself.<br />
A question : how do we see our counter with OOoBasic at this step ? Because our counter is registered we see it (partially) but we cannot use it. (Note you have to stop countermain with a getchar to have time launch a OOoBasic program.)<br />
<source lang="oobas"><br />
'Listing 8 Little OOoBasic Program to see our Counter.<br />
<br />
REM ***** BASIC *****<br />
<br />
Sub Main<br />
ocmpt = createUnoService("foo.Counter")<br />
XRay oCmpt<br />
End Sub<br />
</source><br />
<br />
====Remark about OpenOffice build framework====<br />
When working in the OpenOffice build framework, make sure to add these functions to the util/NAME.map file, eg<br />
when adding the first UNO service to calc's scfilt library, do <br />
<source lang=bash><br />
--- sc/util/scfilt.map<br />
+++ sc/util/scfilt.map<br />
@@ -1,6 +1,9 @@<br />
SCFILT_1_0 {<br />
global:<br />
ScFilterCreate;<br />
+ component_getImplementationEnvironment;<br />
+ component_writeInfo;<br />
+ component_getFactory;<br />
local:<br />
*;<br />
};<br />
</source><br />
<br />
and that you tell scp2 the library is a UNO library, in the case of scfilt, do<br />
<source lang=bash><br />
--- scp2/source/calc/file_calc.scp<br />
+++ scp2/source/calc/file_calc.scp<br />
@@ -49,7 +49,7 @@ STD_UNO_LIB_FILE_PATCH( gid_File_Lib_Sc, sc)<br />
<br />
STD_LIB_FILE_PATCH( gid_File_Lib_Scui, scui)<br />
<br />
-STD_LIB_FILE( gid_File_Lib_Scfilt, scfilt)<br />
+STD_UNO_LIB_FILE( gid_File_Lib_Scfilt, scfilt)<br />
<br />
STD_UNO_LIB_FILE( gid_File_Lib_Scd, scd)<br />
</source><br />
<br />
=== Results ===<br />
'''XRay''' is a OOoBasic tool very easy to use for introspection. Bernard Marcelly's [[Extensions_development_basic#X-Ray_tool|XRay tool description]] can be found in this Wiki. <br />
<br />
XRaying this object as shown in the above listing, gives us :<br />
<br />
'''properties<br />
<pre><br />
--- Object internal name : ( no name )<br />
Dbg_Methods <br />
string <...> basic prop, read-only<br />
Dbg_Properties <br />
string <...> basic prop, read-only<br />
Dbg_SupportedInterfaces<br />
string <...> basic prop, read-only<br />
</pre><br />
'''methods<br />
<pre><br />
--- Object internal name : ( no name )<br />
queryInterface ( aType as type ) AS variant<br />
acquire ( )<br />
release ( )<br />
</pre><br />
'''supported interfaces<br />
<pre><br />
--- List of supported interfaces ---<br />
com.sun.star.uno.XInterface<br />
</pre><br />
<br />
As shown above, only the XInterface can bee seen : not great ! We can therefore instantiate it but not call one of its own method. The next step is to use the counter with OOoBasic : in other words, to make it scriptable.<br />
<br />
== Using an Helper to construct the scriptable Counter ==<br />
<br />
Starting from the [[Counter_Example| Counter example]] we hope to modify the [[Counter_Example#The_Counter_Class|counter class]] and make it scriptable.<br />
<br />
If you want to make your component scriptable you have to modify the previous rule 3 as this new one :<br />
* '''Rule 3'''<br />
Your component has to provide some interfaces : <idl>com.sun.star.uno.XInterface</idl>, <idl>com.sun.star.lang.XServiceInfo</idl>, <idl>com.sun.star.uno.XWeak</idl>, and <idl>com.sun.star.lang.XTypeProvider</idl>. The last one is then a characteristic of scriptable component. See also the [[Documentation/DevGuide/WritingUNO/Core_Interfaces_to_Implement|Developer's Guide]]. <br />
<br />
[[Image:ScripComponent.png|center|thumb|600px|A Scriptable Component]]<br />
<br />
The Figure above shows us a '''scriptable component''' with a schematic view. Implementing the class Myclass means then implement all the virtual methods because of inheritance (and also external C functions). As we will show later in fact we are using an helper and this means we haven't to implement all Interfaces : only <idl>com.sun.star.lang.XServiceInfo</idl> is needed : others are implemented automatically with the helper as mentionned in the [[Documentation/DevGuide/WritingUNO/Core_Interfaces_to_Implement|Developer's Guide]].<br />
<br />
Again we subsume the situation with a figure : how to construct a component with an helper. As shown in the figure below we have to implement seven methods for our counter.<br />
<br />
[[Image:ScripComponentWithHelper.png|center|thumb|600px|A Scriptable Component with an Helper]]<br />
<br />
* '''Rule 4'''<br />
Your component has to provide two interfaces as can be shown in the above figure, you will then use a "::cppu::WeakImplHelper2" when defining your class.<br />
<br />
What about our makefile ? We are no more interested in calling this counter with countermain.cxx but using it in OOoBasic that means we have to register our dynamic library. Two solutions : <br />
#we let again countermain to register the counter and we stop it after registered and then try to launch OOoBasic program, <br />
#we look for an example which correctly registers. One is provided with the SDK as mentioned above :<OOo_SDK>/examples/DevelopersGuide/Components/CppComponent<br />
and we can use the makefile of this component. <br />
<br />
{{Documentation/Caution|For a try I use the first solution but never make it working. There was probably a problem with registry. If a second program manage registry as in the counter example, I am unable to see the component correctly.<br />
<br />
It works when using the makefile of CppComponent renaming the IDL file and cxx file in Makefile as mentioned below. <br />
<br />
To do : to go further with the registry problem !!!}}<br />
<br />
==Starting with the CppComponent example==<br />
<br />
To explain how to construct our component I will start from the SDK example in <OOo_SDK>/examples/DevelopersGuide/Components/CppComponent directory. First copy this folder in <br />
<OOo_SDK>/examples/DevelopersGuide/Components/MyComponent for instance. The point is to keep a subdirectory of <OOo_SDK>/examples/DevelopersGuide/Components to minimize the change in makefile but every name can be used.<br />
<br />
===CppComponent.uno.xml File===<br />
In your new <OOo_SDK>/examples/DevelopersGuide/Component/MyComponent folder, you will find a file CppComponent.uno.xml. Open it and replace<br />
<type>my_module.XSomething</type><br />
<type>my_module.MyService1</type><br />
<type>my_module.MyService2</type><br />
by<br />
<type>foo.XCountable</type><br />
<type>foo.Counter</type><br />
This is the corresponding counter service and interface I want to add to OpenOffice.org.<br />
<br />
===Makefile File===<br />
<br />
In the original Makefile, replace <br />
<pre> <br />
IDLFILES = some.idl<br />
</pre><br />
by<br />
<pre><br />
IDLFILES = Counter.idl<br />
</pre><br />
and replace also<br />
<pre><br />
CXXFILES = service1_impl.cxx \<br />
service2_impl.cxx<br />
</pre><br />
by<br />
<pre><br />
CXXFILES = service_impl.Last.OK.cxx <br />
# service2_impl.cxx<br />
</pre><br />
where you adapt your own source file name.<br />
===IDL file ===<br />
You have no change to do in the IDL file for[[Counter_Example| Counter example]].<br />
<br />
===Counter C++ Source File===<br />
To access the counter interface in Basic, you require the same IDL names as in [[Counter_Example#IDL_File|Listing 6]] ; we give now the complete C++ counter program.<br />
<source lang="cpp"><br />
//Listing 9 The complete Counter Program<br />
// C++<br />
// counter.cxx<br />
/***************************************************************************************************<br />
***************************************************************************************************<br />
*<br />
* service implementation: foo.Counter<br />
* exported interfaces: foo.XCounter<br />
*<br />
* simple example component implementing a counter<br />
*<br />
***************************************************************************************************<br />
**************************************************************************************************/<br />
#ifndef _RTL_USTRING_HXX_<br />
#include <rtl/ustring.hxx><br />
#endif<br />
<br />
#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_<br />
#include <cppuhelper/queryinterface.hxx> // helper for queryInterface() impl<br />
#endif<br />
#ifndef _CPPUHELPER_FACTORY_HXX_<br />
#include <cppuhelper/factory.hxx> // helper for component factory<br />
#endif<br />
// New<br />
#include <cppuhelper/implbase2.hxx> // "2" implementing three interfaces<br />
#include <cppuhelper/implementationentry.hxx><br />
<br />
// generated c++ interfaces<br />
#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_<br />
#include <com/sun/star/lang/XSingleServiceFactory.hpp><br />
#endif<br />
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_<br />
#include <com/sun/star/lang/XMultiServiceFactory.hpp><br />
#endif<br />
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_<br />
#include <com/sun/star/lang/XServiceInfo.hpp><br />
#endif<br />
#ifndef _COM_SUN_STAR_REGISTRY_XREGISTRYKEY_HPP_<br />
#include <com/sun/star/registry/XRegistryKey.hpp><br />
#endif<br />
#ifndef _FOO_XCOUNTABLE_HPP_<br />
#include <foo/XCountable.hpp><br />
#endif<br />
<br />
#define SERVICENAME "foo.Counter"<br />
#define IMPLNAME "com.sun.star.comp.example.cpp.Counter"<br />
<br />
using namespace ::rtl;<br />
using namespace ::osl;<br />
using namespace ::cppu;<br />
using namespace ::com::sun::star::uno;<br />
using namespace ::com::sun::star::lang;<br />
using namespace ::com::sun::star::registry;<br />
using namespace ::foo;<br />
//==================================================================================================<br />
<br />
namespace my_sc_impl<br />
{<br />
static Sequence< OUString > getSupportedServiceNames_MyCounterImpl()<br />
{<br />
static Sequence < OUString > *pNames = 0;<br />
if( ! pNames )<br />
{<br />
// MutexGuard guard( Mutex::getGlobalMutex() );<br />
if( !pNames )<br />
{<br />
static Sequence< OUString > seqNames(1);<br />
seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));<br />
pNames = &seqNames;<br />
}<br />
}<br />
return *pNames;<br />
}<br />
<br />
static OUString getImplementationName_MyCounterImpl()<br />
{<br />
static OUString *pImplName = 0;<br />
if( ! pImplName )<br />
{<br />
// MutexGuard guard( Mutex::getGlobalMutex() );<br />
if( ! pImplName )<br />
{<br />
static OUString implName( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) );<br />
pImplName = &implName;<br />
}<br />
}<br />
return *pImplName;<br />
}<br />
<br />
// New<br />
class MyCounterImpl : public ::cppu::WeakImplHelper2<<br />
XCountable, XServiceInfo ><br />
{<br />
// to obtain other services if needed<br />
Reference< XMultiServiceFactory > m_xServiceManager;<br />
sal_Int32 m_nCount; <br />
public:<br />
// XServiceInfo implementation<br />
virtual OUString SAL_CALL getImplementationName( ) throw(RuntimeException);<br />
virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException);<br />
virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(RuntimeException);<br />
static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static( );<br />
<br />
// XCountable implementation<br />
virtual sal_Int32 SAL_CALL getCount() throw (RuntimeException)<br />
{ return m_nCount; }<br />
virtual void SAL_CALL setCount( sal_Int32 nCount ) throw (RuntimeException)<br />
{ m_nCount = nCount; }<br />
virtual sal_Int32 SAL_CALL increment() throw (RuntimeException)<br />
{ return (++m_nCount); }<br />
virtual sal_Int32 SAL_CALL decrement() throw (RuntimeException)<br />
{ return (--m_nCount); }<br />
};<br />
<br />
//*************************************************************************<br />
OUString SAL_CALL MyCounterImpl::getImplementationName( )<br />
throw(RuntimeException)<br />
{<br />
return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) );<br />
}<br />
<br />
//*************************************************************************<br />
sal_Bool SAL_CALL MyCounterImpl::supportsService( const OUString& ServiceName )<br />
throw(RuntimeException)<br />
{<br />
Sequence< OUString > aSNL = getSupportedServiceNames();<br />
const OUString * pArray = aSNL.getArray();<br />
for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )<br />
if( pArray[i] == ServiceName )<br />
return sal_True;<br />
return sal_False;<br />
} <br />
<br />
//*************************************************************************<br />
Sequence<OUString> SAL_CALL MyCounterImpl::getSupportedServiceNames( )<br />
throw(RuntimeException)<br />
{<br />
return getSupportedServiceNames_Static();<br />
}<br />
<br />
//*************************************************************************<br />
Sequence<OUString> SAL_CALL MyCounterImpl::getSupportedServiceNames_Static( )<br />
{<br />
OUString aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) );<br />
return Sequence< OUString >( &aName, 1 );<br />
}<br />
<br />
/**<br />
* Function to create a new component instance; is needed by factory helper implementation.<br />
* @param xMgr service manager to if the components needs other component instances<br />
*/<br />
//***********NEW<br />
Reference< XInterface > SAL_CALL MyCounterImpl_create(<br />
Reference< XComponentContext > const & xContext )<br />
SAL_THROW( () )<br />
{<br />
return static_cast< XTypeProvider * >( new MyCounterImpl() );<br />
}<br />
<br />
}<br />
//##################################################################################################<br />
//#### EXPORTED ####################################################################################<br />
//##################################################################################################<br />
<br />
/* New ****/<br />
namespace my_sc_impl<br />
{<br />
static struct ::cppu::ImplementationEntry s_component_entries [] =<br />
{<br />
{<br />
MyCounterImpl_create, getImplementationName_MyCounterImpl,<br />
getSupportedServiceNames_MyCounterImpl, ::cppu::createSingleComponentFactory,<br />
0, 0<br />
},<br />
{ 0, 0, 0, 0, 0, 0 }<br />
};<br />
}<br />
<br />
extern "C"<br />
{<br />
void SAL_CALL component_getImplementationEnvironment(<br />
sal_Char const ** ppEnvTypeName, uno_Environment ** ppEnv )<br />
{<br />
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;<br />
}<br />
sal_Bool SAL_CALL component_writeInfo(<br />
XMultiServiceFactory * xMgr, XRegistryKey * xRegistry )<br />
{<br />
return ::cppu::component_writeInfoHelper(<br />
xMgr, xRegistry, ::my_sc_impl::s_component_entries );<br />
}<br />
void * SAL_CALL component_getFactory(<br />
sal_Char const * implName, XMultiServiceFactory * xMgr,<br />
XRegistryKey * xRegistry )<br />
{<br />
return ::cppu::component_getFactoryHelper(<br />
implName, xMgr, xRegistry, ::my_sc_impl::s_component_entries );<br />
}<br />
}<br />
</source><br />
<br />
{{Documentation/Note|The use of helper (::cppu::WeakImplHelper2) provide a default class constructor. If you need a constructor managing a service manager or better a context, you have rewrite a corresponding constructor. See also [[Component_and_Dialog#Obtaining_a_context|obtaining a context]], [[helperNotHelper|difference between helper and not helper]] and also [[Uno/Cpp/Tutorials/component_tutorial| Daniel Bölzle's tutorial]] where helper is used with explicit constructor.}}<br />
<br />
===TestCppComponent.cxx File===<br />
In your directory you have a file named '''TestCppComponent.cxx''' which doesn't work anymore because written for an other service. You can set all the "main()" content in comment. Then your counter check could not be done with a command :<br />
<pre><br />
make TestCppComponent.run<br />
</pre><br />
but only with command<br />
<pre><br />
make SimpleComponent.odt.load<br />
</pre><br />
and you have to modify the OOoBasic program of SimpleComponent.odt document as shown below. We will learn how to modify '''TestCppComponent.cxx''' later.<br />
<br />
=== OOoBasic program for a test===<br />
The OOoBasic program to test this example is as follows:<br />
<source lang="oobas"><br />
'Listing 10 OOoBasic test Program<br />
REM ***** BASIC *****<br />
Sub Main<br />
Dim oSimpleComponent<br />
oSimpleComponent = CreateUnoService( "foo.Counter" )<br />
oSimpleComponent.setCount(5)<br />
print oSimpleComponent.getCount()<br />
oSimpleComponent.increment()<br />
print oSimpleComponent.getCount()<br />
XRay oSimpleComponent<br />
End Sub<br />
</source><br />
Inspecting the new created service with [[Extensions_development_basic#X-Ray_tool|XRay]] shows :<br />
<br />
'''properties<br />
<pre><br />
---- Object internal name : com.sun.star.comp.example.cpp.Counter<br />
Count long <br />
ImplementationName string <br />
SupportedServiceNames ] string <br />
Types []type <br />
ImplementationId []byte <br />
Dbg_Methods string <br />
Dbg_Properties string <br />
Dbg_SupportedInterfaces string <br />
</pre><br />
'''methods<br />
<pre><br />
--- Object internal name : com.sun.star.comp.example.cpp.Counter<br />
queryInterface ( aType as type ) <br />
acquire ( ) <br />
release ( ) <br />
getCount ( ) <br />
setCount ( nCount as long ) <br />
increment ( ) <br />
decrement ( ) <br />
getImplementationName ( ) <br />
supportsService ( ServiceName as string ) <br />
getSupportedServiceNames ( ) <br />
getTypes ( ) <br />
getImplementationId ( ) <br />
queryAdapter ( )<br />
</pre><br />
<br />
You see now the counter methods in OOoBasic ([[Extensions_development_basic#X-Ray_tool|XRay]] is a OOoBasic tool)<br />
<br />
{{Documentation/Note|To conlude I can mention that [[Extensions_development_basic#X-Ray_tool|XRay]] tool allow you to make the counter working with XRaying the "increment" method for instance. [[Object_Inspector|Java inspector Java]] allows also the call of "setCount" method which ask a parameter.}}<br />
The use of [[Object_Inspector|Java inspector]] could be done with the OOoBasic program :<br />
<source lang='oobas'><br />
'Listing 10b Programme OOoBasic de test<br />
REM ***** BASIC *****<br />
Dim oSimpleComponent<br />
oSimpleComponent = CreateUnoService( "foo.Counter" )<br />
oInspector = createUnoService("org.openoffice.InstanceInspector")<br />
oInspector.inspect(oSimpleComponent, "MyCounter")<br />
End Sub<br />
</source><br />
<br />
{{Documentation/Note|Please note that the tutorial (from Daniel Bölzle) [[Uno/Cpp/Tutorials/component_tutorial| here]] presents a scriptable counter too but using less interfaces (cppu::WeakImplHelper1< XCountable > instead of cppu::WeakImplHelper2< XCountable, XServiceInfo >) :}}<br />
<br />
<source lang="cpp"><br />
// C++ Daniel Bölzle<br />
....<br />
class MyCounterImpl : public cppu::WeakImplHelper1< XCountable ><br />
{<br />
// to obtain other services if needed<br />
Reference< XMultiServiceFactory > _xServiceManager;<br />
<br />
sal_Int32 _nCount;<br />
<br />
Reference< XText > _xText;<br />
void dump( sal_Int32 nValue ) const;<br />
<br />
public:<br />
MyCounterImpl( const Reference< XMultiServiceFactory > & xServiceManager );<br />
virtual ~MyCounterImpl();<br />
<br />
// XCountable implementation<br />
virtual sal_Int32 SAL_CALL getCount() throw (RuntimeException);<br />
virtual void SAL_CALL setCount( sal_Int32 nCount ) throw (RuntimeException);<br />
virtual sal_Int32 SAL_CALL increment() throw (RuntimeException);<br />
virtual sal_Int32 SAL_CALL decrement() throw (RuntimeException);<br />
};<br />
...<br />
</source><br />
<br />
= First Variation : a Counter with Attribute=<br />
A little variation on the counter component. I decide to use the attribute possibility in an IDL file. Bear in mind an attribute is automatically accessed with set/get methods. These methods are automatically created. We have then to remove the corresponding methods from the IDL file. My Counter IDL file becomes then :<br />
<source lang="idl"><br />
//Listing 11 Our new IDL File<br />
//IDL<br />
#include <com/sun/star/uno/XInterface.idl><br />
//#include <com/sun/star/lang/XInitialization.idl><br />
<br />
module foo<br />
{<br />
<br />
interface XCountable : com::sun::star::uno::XInterface<br />
{<br />
// long getCount(); ************* generee automatiquement<br />
// void setCount( [in] long nCount ); ********** generee automatiquement<br />
[attribute] long Count;<br />
long increment();<br />
long decrement();<br />
};<br />
<br />
service Counter<br />
{<br />
interface XCountable;<br />
};<br />
};<br />
</source><br />
How is this new counter seen with OooBasic ? We don't see getCount and setCount anymore ! That doesn't mean they don't exist anymore. To prove their existence we program this OooBasic program and run it successfully.<br />
<source lang="oobas"><br />
'Listing 12 <br />
REM ***** BASIC *****<br />
<br />
Sub Main<br />
Dim oSimpleComponent<br />
oSimpleComponent = CreateUnoService( "foo.counter" )<br />
oSimpleComponent.Count = 5<br />
print oSimpleComponent.Count<br />
oSimpleComponent.increment()<br />
print oSimpleComponent.Count<br />
XRay.XRay oSimpleComponent<br />
End Sub<br />
</source><br />
XRaying this object gives us :<br />
'''properties<br />
<pre><br />
--- Object internal name : com.sun.star.comp.example.cpp.Counter<br />
Count long <br />
ImplementationName string <...> pseudo-prop, read-only <br />
SupportedServiceNames []string pseudo-prop, read-only <br />
Types []type pseudo-prop, read-only <br />
ImplementationId []byte pseudo-prop, read-only <br />
Dbg_Methods string <...> basic prop, read-only<br />
Dbg_Properties string <...> basic prop, read-only<br />
Dbg_SupportedInterfaces string <...> basic prop, read-only <br />
</pre><br />
'''methods<br />
<pre><br />
--- Object internal name : com.sun.star.comp.example.cpp.Counter<br />
queryInterface ( aType as type ) AS variant <br />
acquire ( ) <br />
release ( ) <br />
increment ( ) AS long <br />
decrement ( ) AS long <br />
getImplementationName ( ) AS string <br />
supportsService ( ServiceName as string ) AS boolean <br />
getSupportedServiceNames ( ) AS []string <br />
getTypes ( ) AS []type <br />
getImplementationId ( ) AS []byte <br />
queryAdapter ( ) AS object <br />
</pre><br />
{{Documentation/Note|Don't change the C++ source code source of preceding example to make this counter with attribute working. I mean you have a "getCount()" and "setCount()" even if these functions are not in IDL file. If you XRay the Count property, you see the counter value, even if the Count field doesn't exist (in fact the implementation uses an other field m_nCount which is of type sal_Int32).}}<br />
<br />
= Second Variation : using the Service Manager in the Counter =<br />
<br />
You can find a tutorial describing a scriptable counter example (from Daniel Bölzle) [[Uno/Cpp/Tutorials/component_tutorial| here]] where the counter is opening a OOoCalc document, that means it uses OOo services and interfaces.<br />
<br />
The Service Manager management in counter component has been postponed [[Component_and_Dialog#Obtaining_a_context|later here]].<br />
<br />
=Constructing the scriptable Counter without Helper=<br />
We have seen how using helper avoid any interfaces coding. We want construct the counter but without helper, that means we will write everything we need. At the moment see the Developper's Guide.<br />
{{TODO|todonote=<br />
make this example working<br />
}}<br />
<br />
<br />
<br />
=Windows specific problems=<br />
{{Documentation/Windows|This section relates problems you can encounter when linking a component to a Unix-like library. Bear in mind that components are always constructed with Visual C++. But there is a lot of external free libraries which are Unix-like and then can only be constructed under cygwin or something similar (MinGw). Porting them under VC++ is a too heavy task. I want to give an example to show a way I spent few days to discover. I will not construct a component in the example below but only show how to construct a binary executable with VC++ using a dll constructed under cygwin.}}<br />
<br />
== Our example ==<br />
Our example is again based on the counter. I give the complete source code of the example. The include file is as follow :<br />
<source lang="cpp"><br />
//Listing 20 counter.hxx<br />
// C++<br />
class MyCounterImpl {<br />
int m_nCount;<br />
public:<br />
MyCounterImpl();<br />
~MyCounterImpl();<br />
int getCount();<br />
void setCount( int nCount );<br />
int increment();<br />
int decrement() ;<br />
};<br />
</source><br />
and the corresponding C++ source code :<br />
<source lang="cpp"><br />
// counter.cxx Listing 21<br />
#include <stdio.h><br />
#include "counter.hxx"<br />
MyCounterImpl::MyCounterImpl()<br />
: m_nCount( 0 )<br />
{ printf( "< MyCounterImpl ctor called >\n" ); }<br />
MyCounterImpl::~MyCounterImpl()<br />
{ printf( "< MyCounterImpl dtor called >\n" ); }<br />
int MyCounterImpl::getCount()<br />
{ return m_nCount; }<br />
void MyCounterImpl::setCount( int nCount )<br />
{ m_nCount = nCount; }<br />
int MyCounterImpl::increment()<br />
{ return (++m_nCount); }<br />
int MyCounterImpl::decrement()<br />
{ return (--m_nCount); }<br />
<br />
extern "C" void essai1(int *a){<br />
MyCounterImpl count;<br />
count.setCount( *a);<br />
count.increment();<br />
*a=count.getCount();<br />
}<br />
</source><br />
Note I have added an external C function named "essai1". The point is I cannot use directly the class because C++ compilers give different names to the member functions when compiling.<br />
{{Documentation/Note|VC++ adds a "_" as a prefix of the function name and a "@n" as suffix with n the size in octets of the parameter(s). In our example "_essai1@4" is exported.}}<br />
<br />
And now the listing of the main part :<br />
<br />
<source lang="cpp"><br />
//Listing 22 Main Program<br />
//c++<br />
//countermain.cxx<br />
#include <stdio.h><br />
<br />
extern "C" void essai1(int *a);<br />
// the __declspec(dllimport) doesn't work<br />
//__declspec(dllimport) void essai1(void);<br />
<br />
int main(int argc, char **argv)<br />
{ int b=12;<br />
essai1(&b);<br />
printf("expected result : 13, computed result : %d\n",b);<br />
return 0;<br />
}<br />
</source><br />
We want now describe the compilation phases.<br />
<br />
==Compilation==<br />
Lsiting 21 is compiled under cygwin and transformed as a true dll.<br />
<pre><br />
gcc -c counter.cxx -o counter.o<br />
dlltool --export-all --output-def counter.def counter.o<br />
dllwrap counter.o --dllname counter.dll --def counter.def<br />
</pre><br />
At this point you have a counter.dll file. Copy this file and counter.def in the directory you use with VC++.<br />
{{Documentation/Windows|If you can directly give a dynamic library in a Linux compiling process it's not the case under Windows. Using a dll is done with a static library file created with lib tool.}}<br />
The compilation under VC++ is as follow<br />
<pre><br />
lib /machine:i386 /def:counter.def<br />
cl countermain.cxx counter.lib<br />
</pre><br />
It's done : if your cygwin1.dll is available you only launch <code>countermain</code> and see what happens.<br />
<br />
==MakeFile==<br />
{{Documentation/Caution|<br />
The chapter on [[MakeFile|MakeFile]] is under construction but we hope to add an example of makefile for this kind of situation in the future.}}<br />
<br />
= Going further with components and dialog =<br />
[[Documentation/DevGuide/WritingUNO/Accessing_Dialogs | Developer's Guide]] states it is possible to construct a component with a dialog that has been created with the Dialog Editor integrated in the OpenOffice.org Basic IDE. <br />
<br />
[[Component_and_Dialog|In the following chapters]] we will go on to study dialog and components.<br />
{{Documentation/Tip|Dialogs at run time are probably possible to be created in a component. Installing Event listener for buttons is probably possible with [[Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno#The_Component_helper | the Component helper]], but what a hard task !}} <br />
<br />
See also [[Framework/Article/Generic_UNO_Interfaces_for_complex_toolbar_controls|Generic UNO Interfaces for complex toolbar controls]].<br />
<br />
=Home Page=<br />
<br />
[[Image:HomePageCpp.png]] [[Using_Cpp_with_the_OOo_SDK|Return to Document Home page]]<br />
<br />
=See also=<br />
<br />
* Daniel Bölzle's tutorial : [[Uno/Cpp/Tutorials/component_tutorial|Writing a simple UNO component]]<br />
* Old Service Manager and new Context passing when instanciating a component [[Documentation/DevGuide/ProUNO/Service_Manager_and_Component_Context|(see Developer's Guide)]]<br />
* [[Documentation/DevGuide/WritingUNO/Writing_UNO_Components|Writing UNO Components]] in Developer's Guide<br />
* [[Extensions_best_practices|Extensions best Practices]]<br />
* [[Framework/Article/Generic_UNO_Interfaces_for_complex_toolbar_controls|Generic UNO Interfaces for complex toolbar controls]]<br />
* [[HelperNotHelper|Helper Not Helper]]<br />
* [[Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno|C++ and UNO tutorial]]<br />
* [[Component_and_Dialog|Components and dialogs]]<br />
* [http://cedric.bosdonnat.free.fr/wordpress/?p=19 Creating an URE application in C++]<br />
* [[Development/Cpp/Helper/ServiceDecl|Service Declaration]]<br />
* [[Development/Cpp/Helper/OPropertyContainerHelper|Registering properties]]<br />
*[[Tutorial_UNO_Library|UNO tutorial]]<br />
*[[Tutorial_UNO_IDL|UNO IDL]]<br />
* [[Extensions_Packager|Extensions Packager]] (BasicAddonBuilder from [mailto:paolomantovani@openoffice.org Paolo Mantovani])<br />
* [[BASIC/UNO_Object_Browser|BASIC UNO Object Browser]] : You can see the corresponding code as a complex component.<br />
* [[API/Samples/Java/Office/MinimalComponent|Minimal Java Component]]<br />
* [[General_UNO_Component_Project_Type|General UNO Component project Type in Java]]<br />
* [[OpenOffice_Add-On_Project_Type|Office Add-on Projet Type in Java]]<br />
* [[Uno/Article/Types%26Reflection]]<br />
* [[UNO_component_packaging|Component with Python]]<br />
* 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<br />
* Bernard Marcelly's [[Extensions_development_basic#Xray_tool|XRay tool description]] in this wiki<br />
* See also [[Extension Deployement|Extension Deployement]]<br />
* [[UNO component packaging|(Python) UNO component packaging]]<br />
<br />
<br />
[[Category:Cpp]]<br />
[[Category:Uno]]<br />
[[Category:Tutorial]]<br />
[[Category:Add-In]]<br />
[[Category:Add-On]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/DE/Makro_Basic_TutorialDE/Makro Basic Tutorial2016-05-01T06:16:02Z<p>BMarcelly: /* X-Ray tool */Updated Link to Xray</p>
<hr />
<div>[[Category:DE/Dokumentation/OOoBASIC|Makro Basic Tutorial]]<br />
[[Category:Basic:Tutorials]]<br />
<br />
<br />
{| cellspacing=0 cellpadding=5 style="border: 1px solid black;"<br />
| bgcolor=orange colspan=2 |'''Achtung, work in progress'''<br />
Dieses Dokument wird gerade übersetzt, wer mag, darf auch gerne helfen. <br />
|-<br />
|'''Arbeitstitel:''' || "Einführung: Basic für OOo-Erweiterungen"<br />
|-<br />
|'''Originaldokument:''' || [[Extensions_development_basic]]<br><br />
|-<br />
|'''Ursprünglicher Autor:''' || Ian Laurenson<br />
|-<br />
| offene Fragen: || sind mit ??? gekennzeichnet<br />
|}<br />
<br />
Diese Seite soll Ihnen eine Einführung in das Schreiben von Makros mit OpenOffice.org Basic geben. Grundkenntnisse im Programmieren werden vorausgesetzt. Bitte fühlen Sie sich frei, diese Seite zu editieren, um sie lesbarer zu machen. Ich hoffe, dass sie Ihnen von Nutzen sein wird.<br />
<br />
Wenn Sie bereits mit den Grundlagen vertraut sind, können Sie sich auch direkt im KochBuch ([[CookBook]]) Wrapper (-> dt. Entwurfsmuster aus objektorientierter Programmierung; Schnittstelle zwischen aufrufendem und eingeschlossenen Programm, z.B. wenn unterschiedliche Programmiersprachen zum Einsatz kommen) und Beispiele anschauen.<br />
<br />
<br />
= Wohin schreibe ich den Code? =<br />
<br />
Der Basic-Code wird bei OpenOffice.org in '''Modulen''' gespeichert, die in '''Bibliotheken''' zusammengefasst sind. <br />
<br />
Eine Bibliothek kann<br />
* '''allgemein''', also für die gesamte (Netzwerk-) Installation verfügbar sein ("OOo Makros und Dialoge")<br />
* nur für den aktuellen '''Benutzer''' verfügbar sein ("Meine Makros und Dialoge")<br />
* in einem '''Dokument''' oder in einer Vorlage abgelegt sein, so dass ihr Code nur zur Verfügung steht, wenn das Dokument geöffnet ist. <br />
<br />
Bibliotheken, die in einem Dokument abgelegt sind, können mit dem Dokument auf einfache Weise kopiert, transportiert und verteilt werden.<br />
<br />
Bibliotheken, die nicht in einem Dokument abgelegt sind (also allgemein oder für den aktuellen Benutzer verfügbare Bibliotheken) werden im Folgenden als ''OpenOffice.org Bibliotheken'' zusammengefasst.<br />
<br />
Der physische Speicherort für diese OpenOffice.org Bibliotheken wird unter<br>'''Extras > Optionen… > OpenOffice.org > Pfade > BASIC''' festgelegt.<br />
<br />
{| border="1"<br />
|'''Anmerkung:'''<br />
|Hüten Sie sich, Bibliotheken auf Dateisystem-Ebene zu verschieben oder zu kopieren. Benutzen Sie stattdessen den Dialog "Makros verwalten" oder den Paket-Manager<br />
|}<br />
<br />
Module in Bibliotheken können maximal 64kb groß sein. Eine Bibliothek kann bis zu 16 000 Module enthalten. Weitere Infos finden Sie in der Online-Hilfe unter "Module und Bibliotheken" (???).<br />
<br />
= Die Entwicklungsumgebung (IDE) =<br />
<br />
Öffnen Sie die Entwicklungsumgebung:<br />
* in OOo 1.1.x unter '''Extras > Makros > Makro ...'''<br />
* in OOo 1.9.x und höher unter ''' Extras > Makros > Makros verwalten > OpenOffice.org Basic...'''<br />
<br />
Zum Einstieg benutzen wir das "Modul1" aus der Bibliothek "Standard" des aktuellen Benutzers:<br />
<br />
Geben Sie einen Namen für das neue Makro ein: "HelloWorld"<br />
<br />
Wählen Sie die Option '''Standard''' im Auswahlfeld "Makro aus:"<br />
<br />
Klicken Sie auf '''Neu'''<br />
<br />
Jetzt sollten Sie etwa folgendes sehen:<br />
<br />
<source lang="oobas"><br />
REM ***** BASIC *****<br />
<br />
Sub Main<br />
<br />
End Sub<br />
<br />
Sub HelloWorld<br />
<br />
End Sub<br />
</source><br />
<br />
Der Cursor sollte am Anfang der Zeile <tt>Sub HelloWorld</tt> stehen.<br />
<br />
<br />
{| border="1"<br />
|'''Achtung:'''<br />
|Das geöffnete IDE-Fenster ist sowohl über das Menü im OpenOffice.org-Fenster als auch über die Programmleiste des Betriebssystems erreichbar.<br />
|}<br />
<br />
<br />
= Eingeben von Programm-Code =<br />
<br />
Löschen Sie folgende Zeilen:<br />
<br />
<source lang="oobas"><br />
REM ***** BASIC *****<br />
<br />
Sub Main<br />
<br />
End Sub<br />
</source><br />
<br />
Schreiben Sie unterhalb der Zeile "Sub HelloWorld": <tt>msgbox "Hello World!"</tt>, so dass es in etwa so aussieht:<br />
<br />
<source lang="oobas"><br />
Sub HelloWorld<br />
msgbox "Hello World!"<br />
End Sub<br />
</source><br />
<br />
{| border="1"<br />
|'''Achtung:'''<br />
|Die IDE beherrscht zwar keine "code completion"(->dt.Auto-Vervollständigung), also die Fähigkeit eines Editors, den Text automatisch zu vervollständigen, um den Schreibprozess während der Eingabe zu beschleunigen, verfügt aber über eine kontext-sensitive Hilfe, wenn Sie während der Eingabe F1 oder "Hilfe" drücken oder der Cursor in einem Befehl steht.<br>Bei OpenOffice.org Basic-Befehlen wird die Groß- und Kleinschreibung nicht unterschieden. So sind die Eingaben msgbox, MSGBOX oder Msgbox äquivalent.<br> Strings (Textvariablen) werden in doppelte Anführungszeichen eingeschlossen.<br />
|-<br />
|}<br />
<br />
= Den Code ausführen =<br />
<br />
Hierfür gibt es mehrere Möglichkeiten:<br />
<br />
* direkt aus der IDE: das Symbol '''Ausführen''' (das 3. Symbol in der 2. Leiste) ruft das ERSTE Makro des aktuellen Moduls auf.<br />
* aus dem Menü "Extras":<br />
** (Version 1.1.x) '''Extras > Makros > Makro…'''<br />
** (Version 1.9.x und höher) '''Extras > Makro > Makro auführen…'''<br />
* Dem Makro ein Tastaturkürzel zuweisen.<br />
** (Version 1.1.x) ???<br />
** (Version 1.9.x und höher) '''Ansicht > Symbolleisten > Anpassen...''' Tab '''Tastatur'''<br />
* Dem Makro einen Menüeintrag zuweisen.<br />
** (Version 1.1.x) ???<br />
** (Version 1.9.x und höher) '''Ansicht > Symbolleisten > Anpassen...''' Tab '''Menüs'''<br />
* Dem Makro ein Symbolleisten-Symbol zuweisen.<br />
** (Version 1.1.x) ???<br />
** (Version 1.9.x und höher) '''Ansicht > Symbolleisten > Anpassen...''' Tab '''Symbolleisten'''<br />
* Ein Kontroll-Element in einem Dokument erstellen.<br />
** (Version 1.1.x) ???<br />
** (Version 1.9.x und höher) '''Ansicht > Symbolleisten > Anpassen...''' Tab '''Symbolleisten''' (bei '''Speichern in''' das aktuelle Dokument wählen)<br />
* Das Makro einem Ereignis zuweisen.<br />
** (Version 1.1.x) ???<br />
** (Version 1.9.x und höher) '''Ansicht > Symbolleisten > Anpassen...''' Tab '''Ereignisse'''<br />
<br />
Führen Sie für den Anfang die "HelloWorld"-Subroutine aus, indem Sie auf das '''Ausführen'''-Symbol klicken. Ein kleiner Dialog mit dem Titel "soffice" und dem Text "Hello World" sollte aufpoppen.<br />
<br />
= Speichern des Codes =<br />
<br />
Der Code wird immer automatisch gespeichert, wenn sein Container gespeichert wird. Wenn das Modul also in einer (allgemeinen oder benutzerspezifischen) OpenOffice.org-Bibliothek enthalten ist, wird es beim Schließen der Anwendung OpenOffice.org gespeichert. Entsprechend werden Dokument-interne Bibliotheken beim Speichern des Dokuments mitgesichert.<br />
<br />
Auf der Standard-Symbolleiste der IDE (normalerweise die oberste Symbolleiste) finden Sie ein Symbol "Speichern". Befindet sich der Code in einem Dokument oder einer Vorlage, dann speichert der Klick auf dieses Symbol das gesamte Dokument. Handelt es sich dagegen um eine OpenOffice.org-Bibliothek, wird nur die aktuelle Bibliothek gespeichert.<br />
<br />
= Variablen =<br />
<br />
Bei Variablen kann durch <tt>Option Explicit</tt> zu Beginn des Moduls die explizite Deklaration erzwungen werden. Zu Sinn und Unsinn des Deklarierens von Variablen lesen Sie [http://www.oooforum.org/forum/viewtopic.phtml?t=5845 diese Diskussion].<br />
<br />
In dieser Diskussion vertritt der ursprüngliche Autor dieses Wiki-Beitrags die Position, dass Variablen immer deklariert werden sollten. Mittlerweile hat er seine Meinung geändert. Kurz: es ist eine Frage des persönlichen Geschmacks. Unabhängig davon sollten nach Auffassung des ursprünglichen Autors Variablen nach folgender Konvention benannt werden, die auch bei den Beispielen aus diesem Wiki verwendet wurde:<br />
<br />
Der erste Buchstabe der Variable steht für den Typ des in der Variable gespeicherten Wertes. Dabei bezeichnen folgende Buchstaben die entsprechenden Datentypen (in Anlehung an das Tutorial.pdf von Sun):<br />
<br />
{| border="1"<br />
|'''''Buchstabe'''''<br />
|'''''Bedeutung'''''<br />
|-<br />
|a<br />
|Struktur (Structure)<br />
|-<br />
|b<br />
|Bool'sch (WAHR oder FALSCH)<br />
|-<br />
|e<br />
|Aufzählung (Enumeration). Diese Variable kann nur einen begrenzten Satz von Werten enthalten.<br />
|-<br />
|f<br />
|Fließkomma-Zahl (3.402823 x 1038 bis 1.401298 x 10-45. Eine einzelne Variable kann bis zu 4 Bytes umfassen)<br>"Double" (doppelte Genauigkeit, 1.79769313486232 x 10308 bis 4.94065645841247 x 10-324. Eine Double-Variable kann bis zu 8 Bytes umfassen)<br>Währung (-922337203685477.5808 bis +922337203685477.5807 ebenfalls 8 Byte umfassend)<br />
|-<br />
|m<br />
|Feld (Array) (aka Sequenz aka Matrix)<br />
|-<br />
|n<br />
|Integer (-32768 to 32767.) oder<br>Long (-2147483648 and 2147483647).<br />
|-<br />
|o<br />
|Objekt, Service oder Interface<br />
|-<br />
|s<br />
|Text (String) (Eine String-Variable kann bis zu 65535 Unicode-Zeichen enthalten).<br />
|-<br />
|x<br />
|Schnittstelle (Interface), um anzuzeigen, dass nur Methoden einer bstimmten Schnittstelle eines Objekts verwendet werden.<br />
|-<br />
|v<br />
|Variant, irgend ein Typ<br />
|-<br />
|}<br />
<br />
Benutzen Sie lange, beschreibende Variablennamen unter Verwendung von CamelCase (Groß-Klein-Schreibung).<br />
<br />
{| border="1"<br />
|'''Achtung:'''<br />
|Bei benutzerdefinierten OpenOffice.org Basic-Variablen spielt die Groß-/Kleinschreibunge keine Rolle. Bei UNO-API-Konstanten aber sehr wohl!<br />
|}<br />
<br />
Ausnahmen von der Regel, lange Namen zu verwenden, sind Index-Variablen (meist i, j oder k), sowie Strings (meist als s bezeichnet).<br />
<br />
Bearbeiten Sie nun die sub HelloWorld, so dass der Code ungefähr wie im folgenden aussieht und führen Sie sie aus:<br />
<br />
<source lang="oobas"><br />
sub HelloWorld<br />
dim i as integer 'This line is optional<br />
for i = 0 to 2<br />
'These lines are indented for ease of reading only<br />
'all your code should be like this for long time survival<br />
msgbox "Hello World " & i<br />
next i<br />
end sub<br />
</source><br />
<br />
Mehr Infos zur Verwendung von Variablen erhalten Sie in der Online-Hilfe unter "Variablen benutzen" (???)<br />
<br />
= Die OpenOffice.org API =<br />
<br />
Dieser Abschnitt beginnt mit einem Beispiel. Anschließend wird das Beispiel erläutert.<br />
<br />
Versuchen Sie den folgenden Code in Dokumenten unterschiedlichen Typs auszuführen:<br />
<br />
<source lang="oobas"><br />
sub main<br />
'basicLibraries.loadLibrary("XrayTool")<br />
'xray thisComponent<br />
msgbox fnWhichComponent(thisComponent)<br />
end sub<br />
<br />
<br />
function fnWhichComponent(oDoc) as string<br />
if HasUnoInterfaces(oDoc, "com.sun.star.lang.XServiceInfo") then <br />
if thisComponent.supportsService ("com.sun.star.text.GenericTextDocument") then<br />
fnWhichComponent = "Text"<br />
elseif thisComponent.supportsService("com.sun.star.sheet.SpreadsheetDocument") then<br />
fnWhichComponent = "Spreadsheet"<br />
elseif thisComponent.supportsService("com.sun.star.presentation.PresentationDocument") then<br />
fnWhichComponent = "Presentation"<br />
elseif thisComponent.supportsService("com.sun.star.drawing.GenericDrawingDocument") then<br />
fnWhichComponent = "Drawing"<br />
else<br />
fnWhichComponent = "Oops current document something else"<br />
end if<br />
else<br />
fnWhichComponent = "Not a document"<br />
end if<br />
End function<br />
</source><br />
<br />
<br />
== Namenskonventionen für Subroutinen ==<br />
Im obigen Beispiel beginnt die benutzerdefinierte Funktion mit den Buchstaben "fn". Diese Konvention (an die sich der ursprüngliche Autor hält) kennzeichnet eine Funktion als benutzerdefiniert. Entsprechend beginnt eine benutzerdefinierte Subroutine mit "sub". Diese im Folgenden benutzten Konventionen sollen Ihnen als Anfängern helfen, benutzerdefinierte von eingebauten Routinen/Funktionen zu unterscheiden.<br />
<br />
== Einführung in die OpenOffice.org API ==<br />
<br />
In diesem Abschnitt werden folgende Begriffe erläutert:<br />
<br />
* Interface (Schnittstelle)<br />
* Modul<br />
* Service (Dienst)<br />
* Methode<br />
* Property (Eigenschaft)<br />
<br />
Den Unterschied zwischen einer Schnittstelle und einem Service zu kennen, ist zwar nicht unbedingt Voraussetzung zum Programmieren unter OpenOffice.org, aber es hilft, die Dokumentation zu verstehen, und auch bei der Introspektion. Möglicherweise werden Sie den folgenden Abschnitt mindestens zwei mal lesen müssen!<br />
<br />
Eine Schnittstelle ist eine ''Definition'' eines Satzes von Methoden (und ihren Argumenten), die ein Dienst, der diese Schnittstelle implementiert, enthalten muss.<br />
<br />
Schnittstellen werden aus Gründen der Namensgebung zu '''Modulen''' gruppiert. Alle Schnittstellen (und Dienste) beginnen mit <tt>com.sun.star</tt>, gefolgt vom Modul-Namen, dann kommt der Name der Schnittstelle (oder des Dienstes).<br />
<br />
Beispielsweise bieten die meisten Dienste die Schnittstelle <tt>com.sun.star.beans.XPropertySet</tt>. Diese Schnittstelle ist im Modul <tt>beans</tt> gespeichert und ermöglicht Zugriff auf die Eigenschaften (Properties) eines Dienstes. Eine '''Eigenschaft''' ist ein Wert, eine '''Methode''' ist dagegen eine Aktion.<br />
<br />
Ein OpenOffice.org-Objekt kann viele Dienste enthalten.<br />
<br />
Ein OpenOffice.org-Objekt kann einen Dienst enthalten, der eine Schnittstelle implementiert, in welcher eine Methode beschreibt, dass ein anderes OpenOffice.org-Objekt zurückgegeben wird.<br />
<br />
== Introspektion ==<br />
<br />
'''HasUnoInterfaces''' ist eine OpenOffice.org-Basic-Funktion zur Introspektion. Informieren Sie sich über [http://www.oooforum.org/forum/viewtopic.phtml?t=7068 Introspektion in anderen Sprachen].<br />
<br />
<tt>HasUnoInterfaces</tt> gibt <tt>true</tt> zurück, wenn beim spezifizierten Objekt alle spezifizierten Schnittstellen verfügbar sind.<br />
<br />
Die meisten OpenOffice.org-Objekte enthalten die Methode '''supportsService''', weil sie die Schnittstelle <code>com.sun.star.lang.XServiceInfo</code> enthalten.<br />
<br />
Im obigen Beispiel prüft <tt>HasUnoInterfaces</tt>, ob das aktuelle Dokument die Schnittstelle <tt>com.sun.star.lang.XServiceInfo</tt> implementiert, da andernfalls die Methode <tt>supportsService</tt> fehlen würde. Der Aufruf dieser Methode würde in diesem Fall einen Laufzeitfehler verursachen.<br />
<br />
<tt>supportsService</tt> ist eine Methode, die den Wert <code>true</code> zurückgibt, wenn der spezifizierte Service verfügbar ist. Das obige Beispiel prüft das Vorhandensein eines Service, um so den Typ des aktuell aktiven Dokuments zu bestimmen.<br />
<br />
== X-Ray tool ==<br />
Die Benutzung von <tt>HasUnoInterfaces</tt> und <tt>supportsService</tt> reicht aus, um sich zur Laufzeit über ein Objekt zu informieren, aber zum Lernen eignet sich das [http://berma.pagesperso-orange.fr/Files_en/XrayTool60_de.odt X-Ray tool von Bernard Marcelly] viel besser. Laden Sie das ZIP-File herunter, entpacken Sie es und öffnen Sie das enthaltene Dokument mit OpenOffice.org. Befolgen Sie anschließend die Installationsanweisungen.<br />
<br />
Das '''X-Ray tool''' verlangt bei der Konfiguration eine lokale Kopie des OpenOffice.org SDK. Debian-Anwender brauchen nur das Paket "openoffice.org-dev" zu installieren. Sonst laden Sie es ggf. von [http://download.openoffice.org/sdk/index.html hier] herunter und entpacken Sie es. <br />
Unter dem Button "Configuration" auf dem Xray-Hauptdialog ist der Pfad zum lokal installierten OOo-SDK (z.B. /usr/lib/openoffice/basis3.1/sdk/ ) sowie zum gewünschten Browser (z.B. /usr/bin/konqueror ) anzugeben.<br />
<br />
Nun können Sie die beiden auskommentierten Zeilen des obigen Beispiels entkommentieren (den Apostroph entfernen):<br />
<br />
<source lang="oobas"><br />
'basicLibraries.loadLibrary("XrayTool")<br />
'xray thisComponent<br />
</source><br />
<br />
Führen Sie das Makro dann erneut aus.<br />
<br />
Ab Xray Version 5 heißt das Kommando einfach '''xray'''.<br />
<br />
'''BasicLibraries''' ist ein OpenOffice.org-Basic-Befehl, der ein Objekt zurückgibt, mit dem man auf die OpenOffice.org Bibliotheken zugreifen kann. Die Methode <tt>loadLibrary</tt> macht die Routinen aus dieser Bibliothek verfügbar. <br />
<br />
<tt>xray.xray</tt> spezifiziert die Subroutine <tt>xray</tt> im Modul <tt>xray</tt> in dieser Bibliothek, <tt>thisComponent</tt> ist das Objekt, das an xray zur Introspektion übergeben wird. <br />
<br />
Um mit einem bestimmten Objekt zu arbeiten erfordert häufig, dieses Objekt zu finden oder zu erzeugen, indem man mit <tt>StarDesktop</tt> oder <tt>thisComponent</tt> beginnt.<br />
<br />
== Desktop, Dokumente, Selektionen ==<br />
<tt>StarDesktop</tt> und <tt>ThisComponent</tt> sind OpenOffice.org-Basic-Befehle, die sich auf die Applikation bzw. das aktuell aktive Dokument beziehen. <br />
<br />
Im Unterschied zu Microsoft Office ist OpenOffice.org eine Anwendung mit unterschiedlichen Komponenten. Beim Ausführen von Code möchte man häufig wissen, welche Komponente aktuell aktiv ist. Der obige Code zeigt eine Möglichkeit, dies zu überprüfen. <br />
<br />
StarDesktop bezieht sich auf einen konzeptuellen Desktop (der historisch tatsächlich mal existiert hat) und meint de facto die Anwendung OpenOffice.org.<br />
<br />
== Neue Dokumente erzeugen ==<br />
Um ein neues Text-Dokument zu erzeugen: <br />
<br />
<source lang="oobas"><br />
oDoc = StarDesktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, Array())<br />
</source><br />
Um ein neues Tabellen-Dokument zu erzeugen:<br />
<br />
<source lang="oobas"><br />
oDoc = StarDesktop.loadComponentFromURL("private:factory/scalc", "_blank", 0, Array())<br />
</source><br />
Ein sinnvoller Ansatz wäre, eine einfache Funktion zu schreiben:<br />
<br />
<source lang="oobas"><br />
function fnNewDoc(sDocType as string)<br />
fnNewDoc = StarDesktop.loadComponentFromURL("private:factory/" & sDocType , "_blank", 0, Array())<br />
end function<br />
</source><br />
Dann könnte man neue Dokumente ganz einfach erzeugen (in Sub vor der Funktion):<br />
<br />
<source lang="oobas"><br />
oDoc = fnNewDoc("swriter")<br />
oDoc = fnNewDoc("scalc")<br />
oDoc = fnNewDoc("simpress")<br />
oDoc = fnNewDoc("sdraw")<br />
oDoc = fnNewDoc("smath")<br />
</source><br />
Siehe http://api.openoffice.org/docs/common/ref/com/sun/star/frame/XComponentLoader.html .<br />
<br />
== Ein bestehendes Dokument öffnen ==<br />
Im folgenden Beispiel sehen Sie, wie Sie eine Datei öffnen können. OpenOffice.org URLs sind in [[DE/URL Grundlagen]] erläutert. <br />
<br />
<source lang="oobas"><br />
sFile = "C:\Documents and Settings\danny\Desktop\MyCalc.sxc" ' Windows<br />
sFile = "/home/danny/Desktop/MyCalc.sxc" ' Linux<br />
sURL = ConvertToURL(sFile)<br />
oDoc = StarDesktop.loadComponentFromURL(sURL, "_blank", 0, Array())<br />
</source><br />
Auch hier könnte eine einfache Funktion das Schreiben verkürzen:<br />
<br />
<source lang="oobas"><br />
function fnOpenDoc(sFile)<br />
sURL = ConvertToURL(sFile)<br />
fnOpenDoc = StarDesktop.loadComponentFromURL(sURL, "_blank", 0, Array())<br />
end function<br />
</source><br />
Beispiele für Aufrufe:<br />
<br />
<source lang="oobas"><br />
oDoc = fnOpenDoc("C:\Documents and Settings\danny\Desktop\MyCalc.sxc") ' Windows<br />
oDoc = fnOpenDoc("/home/danny/Desktop/MyCalc.sxc") ' Linux<br />
</source><br />
<br />
== Die aktuelle Selektion ==<br />
Häufig werden Sie eine Funktion schreiben wollen, die etwas mit dem aktuell selektierten Bereich anstellt. <tt>ThisComponent</tt> enthält die Methode <tt>getCurrentSelection</tt>. Da viele unterschiedliche Objekte selektiert sein könnten, werden Sie zuerst prüfen wollen, ob das selektierte Objekt über den Dienst verfügt, der die Methode enthält, mit der Sie das Objekt bearbeiten wollen.<br />
<br />
Editieren Sie die Subroutine main im nachfolgenden Code und führen Sie sie mehrfach in einem Textdokument aus, wobei Sie unterschiedliche Objekte selektieren. (Um mehr als einen Textblock zu selektieren, betätigen Sie die '''Strg'''-Taste).<br />
<br />
<source lang="oobas"><br />
sub main<br />
basicLibraries.loadLibrary("XrayTool")<br />
if fnWhichComponent(thisComponent) = "Text" then<br />
oCurSelection = thisComponent.getCurrentSelection()<br />
'xray.xray oCurSelection<br />
if oCurSelection.supportsService("com.sun.star.text.TextRanges") then<br />
msgbox "There are " & oCurSelection.getCount() & _<br />
" selections in the current text document."<br />
end if<br />
end if<br />
end sub<br />
</source><br />
Wenn nichts selektiert ist, beträgt die Anzahl der Selektionen eins (nämlich der Einfügepunkt), wenn ein Textblock selektiert ist, beträgt die Anzahl ebenfalls eins, wenn zwei Textblöcke selektiert sind, beträgt sie drei: der Einfügepunkt sowie die beiden selektierten Textblöcke.<br />
<br />
Übung 1: Modifizieren Sie den obigen Code so, dass er mit selektierten Zellbereichen in einem Tabellendokument funktioniert.<br />
<br />
Frage 1: Wie hoch ist die Anzahl der Selektionen, wenn zwei Zellblöcke selektiert sind?<br />
<br />
==Properties==<br />
Wenn Sie die Zeile <tt>'xray.xray oCurSelection</tt> entkommentieren, so dass xray läuft, sehen Sie, dass das Objekt, worauf <tt>oCurSelection</tt> zeigt, eine "Property" namens <tt>Count</tt> besitzt, mit einer Beschreibung "pseudo-prop, read only". In OpenOffice.org Basic könnten Sie <tt>oCurSelection.count</tt> schreiben, da dies aber in keiner anderen Sprache, mit der Sie auf die OpenOffice.org API zugreifen können, möglich ist, werde ich versuchen, in diesem Wiki nur über Methoden zuzugreifen. (Möglicherweise vergesse ich das auch das eine oder andere Mal). <br />
<br />
Das nächste Beispiel zeigt, wie man einen Property-Wert für die aktuellen Selektionen ändert.<br />
<br />
<source lang="oobas"><br />
sub main<br />
basicLibraries.loadLibrary("XrayTool")<br />
if fnWhichComponent(thisComponent) = "Text" then<br />
oCurSelection = thisComponent.getCurrentSelection()<br />
if oCurSelection.supportsService("com.sun.star.text.TextRanges") then<br />
nCount = oCurSelection.Count<br />
'xray.xray oCurSelection.getByIndex(0)<br />
'Warnung: Am Einfügepunkt wird die selbe Aktion zwei mal angewandt -<br />
'das macht in diesem Fall nichts, kann aber durchaus problematisch werden.<br />
for i = 0 to nCount - 1<br />
oCurSelection.getByIndex(i).setPropertyValue("CharStyleName", "Strong Emphasis")<br />
next<br />
end if<br />
end if<br />
end sub<br />
</source><br />
<br />
In OpenOffice.org Basic kann man die Zuweisung auch abkürzen:<br />
<br />
<source lang="oobas"><br />
oCurSelection(i).CharStyleName = "Strong Emphasis"<br />
</source><br />
Hier in diesem Wiki versuche ich, sowohl zur Indexierung als auch zur Zuweisung von Properties die vollständigen Methoden zu verwenden. Dadurch kann der Code leichter in andere Sprachen portiert werden und es hilft Ihnen auch, zu verstehen, was vor sich geht (nochmal: Bitte um Entschuldigung, wenn ich mal von dieser Regel abweiche, weil ich es eigentlich nicht gewohnt bin)<br />
<br />
Übung 2: Schreiben Sie den obigen Code so um, dass die Warnung entfernt werden kann.<br />
<br />
Siehe [[DE/Aktuelle Selektion]] ([[ Current selection]]).<br />
<br />
=Iterativer Zugriff auf untergeordnete Objekte <br>( berechtigungsgesteuerte Auflistung )=<br />
Manchmal ist zum Zugriff auf ein gewünschtes Objekt eine Enumeration (Auflistung) nötig. Beispielsweise ein Absatz innerhalb eines Dokumentes oder innerhalb einer Auswahl.<br />
<br />
Wenn ein OpenOffice-Writer Dokument aktiviert ist und Text ausgewählt wird, können beide Methoden <tt>thisDocument.getText()</tt> und <tt>thisComponent.getCurrentSelection().getByIndex(i)</tt> verwand werden. <br />
com.sun.star.text.TextRange ist die Schnittstelle (Interface): com.sun.star.container.XContentEnumerationAccess, wodurch es möglich ist, eine Auflistung aller Absätze des aktuellen Dokuments oder für eine einzelne Auswahl zu erhalten. <br />
<br />
<source lang="oobas"><br />
' Create enumeration object<br />
oTextElementEnum = thisComponent.getText().createEnumeration()<br />
'or thisComponent.getCurrentSelection().getByIndex(i).createEnumeration()<br />
<br />
' loop over all text elements<br />
while oTextElementEnum.hasMoreElements()<br />
oTextElement = oTextElementEnum.nextElement<br />
if oTextElement.supportsService("com.sun.star.text.TextTable") then<br />
MsgBox "The current block contains a table."<br />
end if<br />
if oTextElement.supportsService("com.sun.star.text.Paragraph") then<br />
MsgBox "The current block contains a paragraph."<br />
end if<br />
wend<br />
</source><br />
Aufgabe 3: Erweitere das obige Beispiel so, das eine MessageBox aller Worte des Schrifttyps "bold" zeigt .<br />
<br />
=Benannte Zugriffe=<br />
Einige Objekte bieten benannte Zugriffe auf einzelne Typen von untergeordneten Objekten an, einige andere indizierten Zugriff, und manche benannten und indizierten Zugriff. <br />
<br />
Wenn zum Beispiel das aktuelle Dokument in OpenOffice.org ein Arbeitsblatt ist, dann kann der Zugriff auf ein einzelnes Blatt durch einen indizierten Zugriff erfolgen: <br />
<br />
<source lang="oobas"><br />
oSheet = thisComponent.getSheets.getByIndex(0)<br />
</source><br />
oder mit benanntem Zugriff: <br />
<br />
<source lang="oobas"><br />
oSheet = thisComponent.getSheets.getByName("Sheet1")<br />
</source><br />
Um zu überprüfen, ob ein Objekt mit einem einzelnen Namen schon existiert, benutzt man <tt>hasByName</tt>, zum Beispiel: <br />
<br />
<source lang="oobas"><br />
if thisComponent.getSheets.hasByName("Sheet1") then<br />
</source><br />
Eine Schleife durch alle verfügbaren Objektnamen kann in der Art erfolgen: <br />
<br />
<source lang="oobas"><br />
mNames = thisComponent.getSheets.getElementnames<br />
for i = lbound(mNames) to ubound(mNames)<br />
msgbox mNames(i)<br />
next<br />
</source><br />
<br />
<br />
Einige untergeordnete Objekte bieten ebenfalls eine Schnittstelle an: com.sun.star.container.XNameContainer. Diese Schnittstelle definiert, dass auf solche Objekte die folgenden Methoden angewendet werden können: <tt>insertByName</tt>, <tt>replaceByname</tt> and <tt>removeByName</tt>. <br />
<br />
Z.B. <br />
<br />
<source lang="oobas"><br />
thisComponent.getSheets.insertByName("NewSheet")<br />
</source><br />
<br />
=Neue Objekte erstellen=<br />
Einige Objekte bieten Dienste, die Schnittstellen beinhalten, die spezielle Methoden für die Erstellung von einzelnen Objekt-Typen anbieten. <br />
<br />
Wenn z.B. das aktuelle Dokument ein Writer Dokument ist, dann ist <tt>thisComponent.getText</tt> ein Objekt, das den Service com.sun.star.text.Text zur Verfügung stellt, der das Interface com.sun.star.text.XSimpleText implementiert, das wiederum die Methoden <tt>createTextCursor</tt> und <tt>createTextCursorByRange</tt> definiert. Diese beiden Methoden erstellen einen Text-Cursor um auf den Text des Dokumentes zu zu greifen. Diese Cursor sind ziemlich unabhängig vom View-Cursor. Der View-Cursor ist auf dem Bildschirm sichtbar und wird vom Benutzer gesteuert (er kann auch vom Programm gesteuert werden), wohingegen der Text-Cursor auf dem Bildschirm nicht sichtbar ist und ausschließlich vom Programm kontrolliert wird. Der folgende Code Schnippsel zeigt das Erstellen eines neuen Text-Cursors, derart dass er an der Position des View-Cursors beginnt und dann unabhängig von diesem bewegt wird.<br />
<br />
<source lang="oobas"><br />
oVC = thisComponent.getCurrentController.getViewCursor<br />
oCursor = oVC.getText.createTextCursorByRange(oVC)<br />
oCursor.gotoStartOfSentence(false)<br />
oCursor.gotoEndOfSentence(true)<br />
msgbox oCursor.getString<br />
</source><br />
<br />
Einige Objekte sind kontextabhängig und werden mit der Methode <tt>createInstance</tt> erstellt, die im Interface com.sun.star.lang.XMultiServiceFactory definiert wird. Z.B. um ein Rechteck zur ersten Seite eines Zeichnungs-Dokumentes hinzu zu fügen:<br />
<br />
<source lang="oobas"><br />
dim aPoint as new com.sun.star.awt.Point<br />
dim aSize as new com.sun.star.awt.Size<br />
<br />
aPoint.x = 1000<br />
aPoint.y = 1000<br />
<br />
aSize.Width = 10000<br />
aSize.Height = 10000<br />
<br />
oRectangleShape = thisComponent.createInstance("com.sun.star.drawing.RectangleShape")<br />
oRectangleShape.Size = aSize<br />
oRectangleShape.Position = aPoint<br />
<br />
thisComponent.getDrawPages.getByIndex(0).add(oRectangleShape)<br />
</source><br />
<br />
Dieses Beispiel benutzt auch UNO Structs. Weitere Erläuterungen zu UNO Structs siehe unten.<br />
<br />
Einige Objekte sind kontextunabhängig. Benutzen Sie zu Ihrer Erstellung den OpenOffice.org Basic Befehl createUnoService. Z.B. um die Entsprechung zum StarDesktop zu erzeugen: <br />
<br />
<source lang="oobas"><br />
oDesktop = createUnoService("com.sun.star.frame.Desktop")<br />
</source><br />
<br />
Ich nutze die folgende Vorgehensweise, um zu bestimmen, wie ich ein Objekt erstellen oder darauf zu greifen kann:<br />
<br />
Existiert das Objekt bereits? Wenn ja, so sollte ich von etwas in der Art wie <tt>thisComponent</tt> darauf zu greifen können.<br />
<br />
Wird das neue Objekt zu einem anderen Objekt gehören? Wenn ja: Hat der Besitzer eine spezifische Methode, um das Objekt zu erstellen? Wenn ja, so benutze ich diese.<br />
<br />
Das neue Objekt wird zu einem anderen Objekt gehören, welches keine spezifische Methode zu seiner Erstellung bereit stellt, aber es bietet <tt>createInstance</tt> an. Wenn das Objekt <tt>createInstance</tt> nicht zur Verfügung stellt, sind Sie sicher, dass Sie das richtige Objekt verwenden, oder ist es kontextunabhängig?<br />
<br />
Nach meiner Erfahrung ist es anhand der vorhandenen Dokumentation ziemlich schwierig, heraus zu finden, wie man ein Objekt erstellt, und ich hoffe, dass dieses Dokument/Wiki dies eventuell verdeutlicht.<br />
<br />
<br />
==UNO Structs==<br />
UNO Structures können mit dem OpenOffice.org Basic Befehl <tt>dim</tt> deklariert werden:<br />
<br />
<source lang="oobas"><br />
dim aPoint as new com.sun.star.awt.Point<br />
</source><br />
Oder unter Verwendung des OpenOffice.org Basic Befehls <tt>createUnoStruct</tt>:<br />
<br />
<source lang="oobas"><br />
aPoint = createUnoStruct("com.sun.star.awt.Point")<br />
</source><br />
<br />
{| border="1"<br />
|'''Anmerkung:'''<br />
|Beim Deklarieren von UNO Structs ist die Groß-/Kleinschreibung wichtig. Beachten Sie, dass alles bis zum Namen des Structs in Kleinbuchstaben steht, der Name des Structs dagegen in TitleCase.<br />
|}<br />
<br />
<br />
<br />
<br />
==Das Erzeugen von Listenern und Handlern==<br />
Mit Hilfe der Benutzeroberfläche ist es möglich, einigen Ereignissen Makros zu zu weisen:<br />
<br />
*in OOo 1.1.x ??? <br />
<br />
*in OOo 1.9.x und höher unter '''Extras > Anpassen… > Ereignisse'''. <br />
<br />
Mit Hilfe des OpenOffice.org Basic Befehls CreateUnoListener ist es möglich, einer breiteren Auswahl von Makros Ereignisse zu zu ordnen. Dieser Befehl wird zum Erzeugen sowohl von Listenern als auch von Handlern genutzt. <br />
Ein Listener überwacht das Auftreten eines Ereignisses und erlaubt dabei anderen Listenern immer, ebenfalls auf das Ereignis zu antworten. Ein Handler überwacht das Auftreten eines Ereignisses und kann wahlweise das Ereignis verbrauchen, so dass andere Listener nicht mehr dazu kommen, darauf zu reagieren.<br />
<br />
Das folgende Beispiel erzeugt einen keyHandler:<br />
<br />
<source lang="oobas"><br />
global IannzExampleKeyHandler<br />
<br />
sub SetupKeyHandler<br />
oController = thisComponent.currentController<br />
IannzExampleKeyHandler = CreateUnoListener("KeyHandler_","com.sun.star.awt.XKeyHandler")<br />
oController.addKeyHandler(IannzExampleKeyHandler) ' Register the listener<br />
end sub<br />
<br />
<br />
sub RemoveKeyHandler<br />
thisComponent.currentController.removeKeyHandler(IannzExampleKeyHandler)<br />
end sub<br />
<br />
<br />
sub KeyHandler_disposing<br />
end sub<br />
<br />
<br />
function KeyHandler_keyReleased(oKeyEvent as new com.sun.star.awt.KeyHandler) as boolean<br />
KeyHandler_keyReleased = False <br />
end function<br />
<br />
<br />
function KeyHandler_keyPressed(oKeyEvent as new com.sun.star.awt.KeyHandler) as boolean<br />
KeyHandler_keyPressed = false 'Let other listeners handle the event<br />
if oKeyEvent.modifiers = com.sun.star.awt.KeyModifier.MOD2 then 'Control key was pressed<br />
if oKeyEvent.keyCode = com.sun.star.awt.Key.Q then<br />
msgbox "Alt + Q was pressed"<br />
KeyHandler_keyPressed = true 'Don't let other listeners process this event<br />
end if<br />
end if<br />
end function<br />
</source><br />
Eine als global definierte Variable behält ihren Wert auch nachdem das Makro die Subroutine verlässt. In diesem Fall wollen wir die Variable später benutzen können, um den Handler zu entfernen. Da global definierte Variablen auch in anderen Bibliotheken benutzt werden könnten, lasse ich, um Konflikte möglichst zu vermeiden, alle meine globalen Variablen mit Iannz - meinem registrierten Namen für die OpenOffice.org Webseite - anfangen.<br />
<br />
<tt>sub SetupKeyHandler</tt> erstellt den Handler. Der erste Parameter für CreateUnoListener ist der Anfang des Namens für die Methoden, die beim Auftreten dieses Ereignisses aufgerufen werden; in diesem Beispiel <tt>"KeyHandler_"</tt>.<br />
<br />
Der zweite Parameter ist der Name des Interface für den Listener oder Handler, "com.sun.star.awt.XKeyHandler". Der Name ist case sensitive: alles bis einschließlich des Modulnamnes steht immer in Kleinbuchstaben, der Name des Interface beginnt immer mit "X" und der Rest steht in TitleCase. <br />
<br />
Nutzen Sie das SDK, um heraus zu finden, welche Methoden das Interface bereit stellen muss. Sie müssen für alle diese Methoden Routinen zur Verfügung stellen, selbst wenn Sie nicht beabsichtigen, sie zu verwenden. Sie müssen auch eine Methode bereitstellen, die den Listener/Handler entfernt. Die Namen dieser Routinen beginnen mit dem im ersten mit CreateUnoListener übergebenen Parameter enthaltenen String, im Beispiel <tt>"KeyHandler_"</tt>.<br />
<br />
So gibt es im Beipiel die Routinen <tt>KeyHandler_disposing</tt> und <tt>KeyHandler_keyReleased</tt>, die nichts tun, aber benötigt werden. <tt>KeyHandler_keyPressed</tt> erledigt die eigentliche Aufgabe.<br />
<br />
<tt>sub RemoveKeyHandler</tt> zeigt, wie man den Handler entfernt.<br />
<br />
=OpenOffice.org Konstanten=<br />
Das obige Beispiel benutzt OpenOffice.org Konstanten<br />
<br />
Z.B. com.sun.star.awt.KeyModifier.MOD2<br />
<br />
OpenOffice.org Konstanten sind case sensitive. Alles bis einschließlich des Modulnamens steht immer in Kleinbuchstaben. Die Gruppe der Konstanten steht in TitleCase. Der eigentliche Name der Konstanten steht immer in GROßBUCHSTABEN:<br />
<br />
Programmierer, die nicht OpenOffice.org Basic benutzen, haben eventuell keinen Zugriff auf diese Konstanten.<br />
<br />
<br />
=Die Benutzung des Rekorders=<br />
Im Beitrag [[ The OpenOffice.org recorder and UNO dispatch calls]] finden sie eine Diskussion über das Aufnehmen von UNO Dispatch Befehlen im Gegensatz zum Schreiben von API Aufrufen.</div>BMarcellyhttps://wiki.openoffice.org/wiki/Constructing_HelpersConstructing Helpers2016-05-01T06:06:27Z<p>BMarcelly: /* See also */</p>
<hr />
<div>{{Documentation/Candidate}}<br />
Up to then I have only used C-like style. This C-like style was only to focus on what seems the most important for a beginner : how to handle interfaces, services... But in this chapter we want to show a different way : constructing classes which help the programmer : it's why we name them “helper”. We can encounter such examples in Java code examples which comes with SDK. We begin with the fisrt one which comes in spirit : a connection helper.<br />
<br />
= Desktop Helper =<br />
<br />
== The GAP's Helper ==<br />
[[CppSDKAuthors|GAP]] from India helps me when trying to construct a Run Time Dialog Box. He provided this helper. We first give the SimpleOOConnection.hpp file :<br />
<source lang="cpp"><br />
//Listing 1 Gap helper<br />
// C++<br />
// SimpleOOConection.hpp<br />
#ifndef SIMPLEOOCONNECTION_HPP_<br />
#define SIMPLEOOCONNECTION_HPP_<br />
#endif<br />
<br />
#include<iostream><br />
<br />
#include <cppuhelper/bootstrap.hxx><br />
#include <com/sun/star/bridge/XUnoUrlResolver.hpp><br />
#include <com/sun/star/lang/XMultiServiceFactory.hpp><br />
<br />
using namespace std;<br />
using namespace com::sun::star::uno;<br />
using namespace com::sun::star::lang;<br />
using namespace com::sun::star::bridge;<br />
using namespace rtl;<br />
using namespace cppu;<br />
<br />
class SimpleOOConnection {<br />
public :<br />
SimpleOOConnection();<br />
Reference< XMultiServiceFactory > connect_ooffice(const char *url);<br />
<br />
private :<br />
int iNoOfConnection_;<br />
<br />
};<br />
</source><br />
This code use <idl>com.sun.star.bridge.XUnoUrlResolver</idl> and <idl>com.sun.star.lang.XMultiServiceFactory</idl> interfaces.<br />
<br />
And now the implementation file :<br />
<br />
<source lang="cpp"><br />
//Listing 2 <br />
// C++<br />
#include "SimpleOOConnection.hpp"<br />
<br />
// int SimpleOOConnection::iNoOfConnection_=0;<br />
SimpleOOConnection::SimpleOOConnection()<br />
{<br />
iNoOfConnection_++;<br />
}<br />
<br />
Reference< XMultiServiceFactory > SimpleOOConnection::connect_ooffice(const char *url)<br />
{<br />
// create the initial component context<br />
cout<<endl;<br />
cout<<url<<"HI"<<endl;<br />
<br />
//Initiating Local Component Context<br />
Reference< XComponentContext > rComponentContext =<br />
defaultBootstrap_InitialComponentContext();<br />
<br />
<br />
/**<br />
* This local Context contents small Service Manager tha konws how to create services that are neccessary to talk to other<br />
* component context.One such service is com.sun.star.bridge.UnoUrlResolver So it ask local Service Manager to create this<br />
* service.<br />
*/<br />
// retrieve the Local Service Manager from the Local context i.e We get Just servicemanager here<br />
Reference< XMultiComponentFactory > rServiceManager =<br />
rComponentContext->getServiceManager();<br />
<br />
// here we instantiate a sample service with the service com.sun.star.bridge.UnoUrlResolver . Created by local service manager.<br />
Reference< XInterface > rInstance =<br />
rServiceManager->createInstanceWithContext(<br />
OUString::createFromAscii("com.sun.star.bridge.UnoUrlResolver" ),rComponentContext );<br />
<br />
// Query for the XUnoUrlResolver interface fro sample service<br />
Reference< XUnoUrlResolver > rResolver( rInstance, UNO_QUERY );<br />
<br />
//Now it uses UnoUrlResolver to get component context together with service manager from server side<br />
try<br />
{<br />
// resolve the uno-url<br />
rInstance = rResolver->resolve( OUString::createFromAscii(url ) );<br />
<br />
// query for the simpler XMultiServiceFactory interface, sufficient for scripting<br />
Reference< XMultiServiceFactory > rOfficeServiceManager (rInstance, UNO_QUERY);<br />
<br />
return(rOfficeServiceManager);<br />
}<br />
catch( Exception &e )<br />
{<br />
OString o = OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US );<br />
printf( "Error: %s\n", o.pData->buffer );<br />
return('\0');<br />
}<br />
<br />
}<br />
</source><br />
For a better understanding, you can have a look at :<br />
* [[UNO_automation_with_a_binary_%28executable%29#Preparing_a_new_Code_as_a_starting_Point|Our previous starting code]],<br />
* <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> and <idl>com.sun.star.lang.XMultiServiceFactory</idl> interfaces,<br />
* <idl>com.sun.star.bridge.UnoUrlResolver</idl> service<br />
<br />
== Simple Desktop Helper ==<br />
The snippet below uses <idl>com.sun.star.uno.XInterface</idl>, <idl>com.sun.star.frame.XComponentLoader</idl>, <idl>com.sun.star.lang.XMultiServiceFactory</idl> and <idl>com/sun/star/frame/XDesktop</idl> interfaces and also <idl>com.sun.star.frame.Desktop</idl> and <idl>com.sun.star.bridge.UnoUrlResolver</idl> services.<br />
<br />
We first give the header file :<br />
<source lang="cpp"><br />
//Listing 3 Header file of the desktop helper<br />
// C++<br />
//********* DesktopHelper class : header DesktopHelper.hpp<br />
#include <com/sun/star/uno/XInterface.hpp><br />
#include <com/sun/star/frame/XComponentLoader.hpp><br />
#include <com/sun/star/lang/XMultiServiceFactory.hpp><br />
#include <com/sun/star/frame/XDesktop.hpp><br />
<br />
using namespace com::sun::star::uno;<br />
using namespace com::sun::star::frame;<br />
using namespace com::sun::star::lang;<br />
<br />
class DesktopHelper {<br />
public :<br />
DesktopHelper();<br />
Reference< XInterface > Desktop;<br />
Reference< XComponentLoader > xComponentLoader;<br />
Reference< XMultiServiceFactory > xSVMG;<br />
Reference< XDesktop > xDesktop;<br />
private :<br />
Reference< XMultiServiceFactory > ooConnect();<br />
};<br />
</source><br />
and the corresponding implementation :<br />
<source lang="cpp"><br />
//Listing 4 Desktop helper implementation<br />
// C++<br />
//****** DesktopHelper class : implementation DesktopHelper.cxx<br />
#include <stdio.h><br />
#include <com/sun/star/bridge/XUnoUrlResolver.hpp><br />
#include <cppuhelper/bootstrap.hxx><br />
<br />
using namespace com::sun::star::bridge;<br />
using rtl::OUString;<br />
using rtl::OString;<br />
using namespace cppu;<br />
<br />
DesktopHelper::DesktopHelper(){<br />
xSVMG = ooConnect();<br />
if( xSVMG.is() ){<br />
printf( "Connected sucessfully to the office\n" );<br />
}<br />
//get the desktop service using createInstance returns an XInterface type<br />
Reference< XInterface > Desktop = xSVMG->createInstance(<br />
OUString::createFromAscii( "com.sun.star.frame.Desktop" ));<br />
<br />
//query for the XComponentLoader interface<br />
xComponentLoader = Reference< XComponentLoader > (Desktop, UNO_QUERY);<br />
if( xComponentLoader.is() ){<br />
printf( "XComponentloader successfully instanciated\n" );<br />
<br />
}<br />
xDesktop = Reference< XDesktop > (Desktop,UNO_QUERY);<br />
}<br />
<br />
Reference< XMultiServiceFactory > DesktopHelper::ooConnect(){<br />
// create the initial component context<br />
Reference< XComponentContext > rComponentContext = <br />
defaultBootstrap_InitialComponentContext();<br />
<br />
// retrieve the servicemanager from the context<br />
Reference< XMultiComponentFactory > rServiceManager = <br />
rComponentContext->getServiceManager();<br />
<br />
// instantiate a sample service with the servicemanager.<br />
Reference< XInterface > rInstance = rServiceManager->createInstanceWithContext(<br />
OUString::createFromAscii("com.sun.star.bridge.UnoUrlResolver" ),rComponentContext );<br />
// Query for the XUnoUrlResolver interface<br />
Reference< XUnoUrlResolver > rResolver( rInstance, UNO_QUERY );<br />
<br />
if( ! rResolver.is() ){<br />
printf( "Error: Couldn't instantiate com.sun.star.bridge.UnoUrlResolver service\n" );<br />
return NULL;<br />
}<br />
try {<br />
// resolve the uno-url<br />
rInstance = rResolver->resolve( OUString::createFromAscii(<br />
"uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" ) );<br />
<br />
if( ! rInstance.is() ){<br />
printf( "StarOffice.ServiceManager is not exported from remote counterpart\n" );<br />
return NULL;<br />
}<br />
<br />
// query for the simpler XMultiServiceFactory interface, sufficient for scripting<br />
Reference< XMultiServiceFactory > rOfficeServiceManager (rInstance, UNO_QUERY);<br />
<br />
if( ! rOfficeServiceManager.is() ){<br />
printf( "XMultiServiceFactory interface is not exported for StarOffice.ServiceManager\n" );<br />
return NULL;<br />
}<br />
return rOfficeServiceManager;<br />
}<br />
catch( Exception &e ){<br />
OString o = OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US );<br />
printf( "Error: %s\n", o.pData->buffer );<br />
return NULL;<br />
}<br />
return NULL;<br />
}<br />
</source><br />
This code uses again the [[OOConnect|ooConnect() function]] instead of "connect_ooffice" of the [[Constructing_Helpers#The_GAP.27s_Helper|GAP's helper]].<br />
<br />
== Desktop Helper with message box ==<br />
What we want here is to have an helper which can avoid us using printf and use a message box instead. '''But remember the message box interface is deprecated.''' <br />
Have a look in the corresponding interfaces : <idl>com.sun.star.uno.XInterface</idl>, <idl>com.sun.star.frame.XComponentLoader</idl>, <idl>com.sun.star.lang.XMultiServiceFactory</idl>, <idl>com.sun.star.frame.XDesktop</idl>, <idl>com.sun.star.awt.XToolkit</idl> before starting to read the code. It is also important to have look [[Playing_with_Window_Toolkit_AWT#The_MessageBox_Windows|here where the mesage box]] is described with its <idl>com.sun.star.awt.XWindowPeer</idl>, <idl>com.sun.star.awt.XMessageBox</idl> and <idl>com.sun.star.frame.XFrame</idl> interfaces.<br />
<br />
The new class definition is :<br />
<source lang="cpp"><br />
//Listing 5 A second desktop helper (header file)<br />
// C++<br />
//********* DesktopHelper class : header DesktopHelper.hpp<br />
#include <com/sun/star/uno/XInterface.hpp><br />
#include <com/sun/star/frame/XComponentLoader.hpp><br />
#include <com/sun/star/lang/XMultiServiceFactory.hpp><br />
#include <com/sun/star/frame/XDesktop.hpp><br />
#include <com/sun/star/awt/XToolkit.hpp><br />
using namespace com::sun::star::uno;<br />
using namespace com::sun::star::frame;<br />
using namespace com::sun::star::lang;<br />
using namespace com::sun::star::awt;<br />
class DesktopHelper {<br />
public :<br />
DesktopHelper();<br />
void ShowMessageBox( const OUString& aTitle, const OUString& aMsgText );<br />
Reference< XInterface > Desktop;<br />
Reference< XComponentLoader > xComponentLoader;<br />
Reference< XMultiServiceFactory > xSVMG;<br />
Reference< XDesktop > xDesktop;<br />
sal_Int16 endMsgbox;<br />
private :<br />
Reference< XMultiServiceFactory > ooConnect();<br />
sal_Bool useMsgbox;<br />
Reference< XToolkit > xToolkit;<br />
Reference< XFrame > xFrame;<br />
};<br />
</source><br />
and the new constructor :<br />
<source lang="cpp"><br />
//Listing 6 A second desktop helper (implementation file)<br />
// C++<br />
DesktopHelper::DesktopHelper(){<br />
useMsgbox = false;<br />
endMsgbox = 0;<br />
xSVMG = ooConnect();<br />
if( xSVMG.is() ){<br />
printf( "Connected sucessfully to the office\n" );<br />
}<br />
//get the desktop service using createInstance returns an XInterface type<br />
Reference< XInterface > Desktop = xSVMG->createInstance(<br />
OUString::createFromAscii( "com.sun.star.frame.Desktop" ));<br />
<br />
//query for the XComponentLoader interface<br />
xComponentLoader = Reference< XComponentLoader > (Desktop, UNO_QUERY);<br />
if( xComponentLoader.is() ){<br />
printf( "XComponentloader successfully instanciated\n" );<br />
<br />
}<br />
xDesktop = Reference< XDesktop > (Desktop,UNO_QUERY);<br />
xToolkit = Reference< XToolkit >( xSVMG->createInstance(<br />
OUString( RTL_CONSTASCII_USTRINGPARAM(<br />
"com.sun.star.awt.Toolkit" ))), UNO_QUERY );<br />
xFrame = xDesktop->getCurrentFrame();<br />
if (xFrame.is() && xToolkit.is()) useMsgbox = true;<br />
}<br />
</source><br />
The method to print out a message is :<br />
<source lang="cpp"><br />
//Listing 7 ShowMessageBox function (XMessageBox interface is deprecated)<br />
// C++<br />
void DesktopHelper::ShowMessageBox( const OUString& aTitle, const OUString& aMsgText )<br />
{<br />
if ( useMsgbox )<br />
{<br />
// describe window properties.<br />
WindowDescriptor aDescriptor;<br />
aDescriptor.Type = WindowClass_MODALTOP;<br />
aDescriptor.WindowServiceName = OUString( RTL_CONSTASCII_USTRINGPARAM( "infobox" ));<br />
aDescriptor.ParentIndex = -1;<br />
aDescriptor.Parent = Reference< XWindowPeer > (xFrame->getContainerWindow(), UNO_QUERY );<br />
aDescriptor.Bounds = Rectangle(300,200,300,200);<br />
aDescriptor.WindowAttributes = WindowAttribute::BORDER | WindowAttribute::MOVEABLE | WindowAttribute::CLOSEABLE;<br />
<br />
Reference< XWindowPeer > xPeer = xToolkit->createWindow( aDescriptor );<br />
if ( xPeer.is() )<br />
{<br />
Reference< XMessageBox > xMsgBox( xPeer, UNO_QUERY );<br />
if ( xMsgBox.is() )<br />
{<br />
xMsgBox->setCaptionText( aTitle );<br />
xMsgBox->setMessageText( aMsgText );<br />
endMsgbox = xMsgBox->execute();<br />
}<br />
}<br />
} // else would be good to use cout<br />
}<br />
</source><br />
The way to use this new feature is shown in the above listing :<br />
<source lang="cpp"><br />
//Listing 8 Using the Desktop Helper<br />
// C++<br />
DesktopHelper *aDesktop = new (DesktopHelper);<br />
aDesktop->ShowMessageBox( OUString::createFromAscii("try"),<br />
OUString::createFromAscii("Hello"));<br />
while (! aDesktop->endMsgbox);<br />
printf("That's all folks !\n");<br />
</source><br />
where you see how to wait the MessageBox ending. This is why I have added this “endMsgbox” component in the class. Effectively, the problem with xMsgBox->execute() is this is a no-blocking instruction, I mean this instruction doesn't wait the MessageBox 's close. If you have no mean to wait, you will have a runtime error if your program finished befor this MessageBox is closed.<br />
<br />
This code use again the [[OOConnect|ooConnect() function]] instead of "connect_ooffice" of the [[Constructing_Helpers#The_GAP.27s_Helper|GAP's helper]].<br />
<br />
= Reflection Helper =<br />
<br />
{{Documentation/Tip|This helper is not a component at the moment. It is compiled as a separate code and you can call it from a binary executable as [[Constructing_Helpers#Using_The_Helper|shown below]].}}<br />
<br />
Because there is no such example in the SDK you have to change slightly the MakeFile. You can see such an example [[MakeFile#Office_connect_with_a_helper|of MakeFile here]].<br />
<br />
== Presentation ==<br />
<br />
The reflection helper goal is to provide Object informations on methods, interfaces, services and properties. Have a look :<br />
* in [[SDKCppLanguage#Sequences|Sequences]], [[SDKCppLanguage#Any|Any]] in this document<br />
* in the following interfaces <idl>com.sun.star.lang.XMultiServiceFactory</idl>, <idl>com.sun.star.beans.XIntrospection</idl>, <idl>com.sun.star.beans.XIntrospectionAccess</idl>, <idl>com.sun.star.lang.XTypeProvider</idl>, <idl>com.sun.star.reflection.XIdlMethod</idl>, <idl>com.sun.star.lang.XServiceInfo</idl><br />
* in the following UNO constants <idl>com.sun.star.beans.MethodConcept</idl>, <idl>com.sun.star.beans.PropertyConcept</idl> and [[SDKCppLanguage#To_go_further_:_the_Constant_Type_Problem|UNO constants in C++]] <br />
* in the following UNO struct <idl>com.sun.star.beans.Property</idl> and a [[Calc/API/Programming#Retrieve_the_absolute_X_and_Y_Positions_of_a_Cell|UNO structure example in C++]]<br />
* in the following UNO Enumeration <idl>com.sun.star.reflection.ParamMode</idl> and [[SDKCppLanguage#To_go_further_:_the_Enumeration_Type_Problem|UNO enumeration in C++]].<br />
<br />
We begin to give the ReflectionHelper.hpp file :<br />
<source lang="cpp"><br />
//Listing 11 Header file for reflection helper<br />
// C++<br />
// ReflectionHelper.hpp<br />
#include <rtl/ustring.hxx><br />
#include <com/sun/star/uno/Sequence.hxx><br />
#include <com/sun/star/uno/Any.hxx><br />
#include <com/sun/star/lang/XMultiServiceFactory.hpp><br />
#include <com/sun/star/beans/XIntrospection.hpp><br />
#include <com/sun/star/beans/XIntrospectionAccess.hpp><br />
#include <com/sun/star/lang/XTypeProvider.hpp><br />
#include <com/sun/star/beans/MethodConcept.hpp><br />
#include <com/sun/star/reflection/XIdlMethod.hpp><br />
#include <com/sun/star/uno/Type.hxx><br />
#include <com/sun/star/beans/Property.hpp><br />
#include <com/sun/star/lang/XServiceInfo.hpp><br />
#include <com/sun/star/reflection/ParamMode.hpp><br />
<br />
using rtl::OUString;<br />
using namespace com::sun::star::reflection;<br />
using namespace com::sun::star::beans;<br />
using namespace com::sun::star::lang;<br />
using namespace com::sun::star::uno;<br />
<br />
class ReflectionHelper {<br />
public:<br />
ReflectionHelper(Any any,Reference< XMultiServiceFactory > oSVM);<br />
<br />
Sequence < OUString > getMethods(),<br />
getTypes(),<br />
getServices(),<br />
getPropertiesWithoutValues(),<br />
getPropertiesWithValues();<br />
<br />
<br />
private:<br />
Any toInspect;<br />
Reference< XMultiServiceFactory > xServiceManager;<br />
Reference< XIntrospection >xIntrospection;<br />
Reference< XIntrospectionAccess > xIntrospec;<br />
Reference< XTypeProvider > xTypeProvider;<br />
OUString getValueName(Any object);<br />
OUString getParamMode(ParamMode paramMode);<br />
// methods<br />
Sequence< Reference< XIdlMethod > > mMethods;<br />
// Interfaces<br />
Sequence< Type > types;<br />
// Services<br />
Reference< XServiceInfo > xServiceInfo;<br />
// Sequence< OUString > services;<br />
// Properties<br />
Sequence< Property > Properties;<br />
};<br />
</source><br />
You can find the complete class implementation [[XIntrospection_Interface#Obtaining_all_the_properties|here in lising 14]]<br />
<br />
== Application ==<br />
<br />
A simple utilisation could be :<br />
<br />
<source lang="cpp"><br />
//Listing 13 <br />
// C++<br />
Any toInspect;<br />
// I want to inspect rDesktop object :<br />
toInspect <<= rDesktop;<br />
// need a service manager<br />
ReflectionHelper *Reflect = new (ReflectionHelper)(toInspect,rServiceManager);<br />
// get all the methods<br />
Sequence< OUString > mMethods = Reflect -> getMethods();<br />
printf("******** methods : (%d)\n",mMethods.getLength());<br />
for (int i=0;i<mMethods.getLength();i++){<br />
<br />
// do what you want with mMethods[i] : for instance<br />
OString OStr = OUStringToOString( mMethods[i], RTL_TEXTENCODING_ASCII_US );<br />
printf("%s\n",OStr.pData->buffer );<br />
<br />
}<br />
</source><br />
<br />
It's the great values of helpers : they make code simpler and more easy to read.<br />
<br />
== Printing out Reflection's Results in a Dialog ==<br />
<br />
A fast way of printing out results would be a Dialog and the goal of this chapter is to speak from this topic.<br />
<br />
=== hpp File of the Complete Class ===<br />
We present again the complete class :<br />
<br />
<source lang="cpp"><br />
//Listing 15 <br />
// C++<br />
// ReflectionHelper.hpp<br />
class ReflectionHelper {<br />
public:<br />
ReflectionHelper(Any any,Reference< XMultiServiceFactory > oSVM);<br />
<br />
Sequence < OUString > getMethods(),<br />
getTypes(),<br />
getServices(),<br />
getPropertiesWithoutValues(),<br />
getPropertiesWithValues();<br />
// Print out<br />
void printOut();<br />
<br />
private:<br />
Any toInspect;<br />
Reference< XMultiServiceFactory > xServiceManager;<br />
Reference< XIntrospection >xIntrospection;<br />
Reference< XIntrospectionAccess > xIntrospec;<br />
Reference< XTypeProvider > xTypeProvider;<br />
OUString getValueName(Any object);<br />
OUString getParamMode(ParamMode paramMode);<br />
// methods<br />
Sequence< Reference< XIdlMethod > > mMethods;<br />
// Interfaces<br />
Sequence< Type > types;<br />
// Services<br />
Reference< XServiceInfo > xServiceInfo;<br />
// Sequence< OUString > services;<br />
// Properties<br />
Sequence< Property > Properties;<br />
};<br />
</source><br />
A new method is added : printOut which know how to print results in a run time dialog box.<br />
<br />
=== New Implementation Code ===<br />
The corresponding implementation's code is now given. Notice the reference of '''listing 14''' in the code. Here is a direct link into the [[XIntrospection_Interface#Complete_Introspection_Class|corresponding listing 14]] or better in [[Development/Cpp/Helper/ReflectionHelper|the corresponding Snippet]].<br />
<source lang="cpp"><br />
//Listing 16 <br />
// C++<br />
// constructor<br />
ReflectionHelper::ReflectionHelper(Any any,Reference< XMultiServiceFactory > oSVM)<br />
: toInspect(any), xServiceManager(oSVM){<br />
xIntrospection = Reference< XIntrospection >( xServiceManager->createInstance(<br />
OUString( RTL_CONSTASCII_USTRINGPARAM(<br />
"com.sun.star.beans.Introspection" ))), UNO_QUERY );<br />
xIntrospec = xIntrospection->inspect(toInspect);<br />
mMethods = xIntrospec -> getMethods(MethodConcept::ALL);<br />
xTypeProvider = Reference< XTypeProvider> (toInspect,UNO_QUERY);<br />
types = xTypeProvider->getTypes();<br />
xServiceInfo = Reference< XServiceInfo>(toInspect,UNO_QUERY);<br />
Properties = xIntrospec -> getProperties(PropertyConcept::ALL);<br />
}<br />
<br />
Sequence < OUString > ReflectionHelper::getServices() {<br />
return xServiceInfo->getSupportedServiceNames();<br />
}<br />
<br />
Sequence < OUString > ReflectionHelper::getMethods(){<br />
// See Listing 14 to find the corresponding code.<br />
}<br />
<br />
Sequence < OUString > ReflectionHelper::getTypes(){<br />
// See Listing 14 to find the corresponding code.<br />
}<br />
<br />
// to improve : change all the tests with getCppuType : probably quicker than a string test<br />
OUString ReflectionHelper::getValueName(Any object){<br />
// See Listing 14 to find the corresponding code.<br />
}<br />
<br />
// Get properties with values : only those computed in getValueName<br />
Sequence < OUString > ReflectionHelper::getPropertiesWithValues(){<br />
// See Listing 14 to find the corresponding code.<br />
}<br />
<br />
// Get properties without values but types<br />
Sequence < OUString > ReflectionHelper::getPropertiesWithoutValues(){<br />
// See Listing 14 to find the corresponding code.<br />
}<br />
<br />
// Don't forget to add : #include <com/sun/star/reflection/ParamMode.hpp><br />
// Don't forget to add "com.sun.star.reflection.ParamMode \" in the makefile<br />
OUString ReflectionHelper::getParamMode(ParamMode paramMode) {<br />
// See Listing 14 to find the corresponding code.<br />
}<br />
<br />
void ReflectionHelper::printOut(){<br />
Reference< XInterface > xdialogModel =<br />
xServiceManager->createInstance(<br />
OUString::createFromAscii("com.sun.star.awt.UnoControlDialogModel"));<br />
#ifdef DEBUG<br />
if (xdialogModel.is()) printf("OK XDialogModel\n"); else printf("Error ... XDialodModel\n");<br />
#endif<br />
Any val;<br />
Reference< XPropertySet > xPSetDialog(xdialogModel,UNO_QUERY);<br />
#ifdef DEBUG<br />
if (xPSetDialog.is()) printf("OK XPropertySet\n"); else printf("Error ... XPropertySet\n");<br />
#endif<br />
sal_Int32 value=100;<br />
val<<=value;<br />
xPSetDialog->setPropertyValue(OUString::createFromAscii("PositionX"),val);<br />
xPSetDialog->setPropertyValue(OUString::createFromAscii("PositionY"),val);<br />
value=300;val<<=value;<br />
xPSetDialog->setPropertyValue(OUString::createFromAscii("Width"),val);<br />
value=200;val<<=value;<br />
xPSetDialog->setPropertyValue(OUString::createFromAscii("Height"),val);<br />
<br />
val <<=OUString::createFromAscii("Runtime Dialog Demo");<br />
xPSetDialog->setPropertyValue(OUString::createFromAscii("Title"),val);<br />
<br />
Reference< XMultiServiceFactory > xMultiServiceFactory( xdialogModel,UNO_QUERY);<br />
<br />
///*****************<br />
//******** in the above line xMultiServiceFactory instead xServiceManager !!!!!!<br />
//Reference< XInterface > xbuttonModel = xServiceManager>createInstance( ....<br />
Reference< XInterface > xbuttonModel = xMultiServiceFactory->createInstance(<br />
OUString::createFromAscii("com.sun.star.awt.UnoControlButtonModel"));<br />
#ifdef DEBUG<br />
if (xbuttonModel.is()) printf("OK UnoControlButtonModel\n"); else printf("Error ... UnoControlButtonModel\n");<br />
#endif<br />
Reference< XPropertySet > xPSetButton(xbuttonModel,UNO_QUERY);<br />
#ifdef DEBUG<br />
if (xPSetButton.is()) printf("OK XPropertySet\n"); else printf("Error ... XPropertySet\n");<br />
#endif<br />
value=20; val <<= value;<br />
xPSetButton->setPropertyValue(OUString::createFromAscii("PositionX"),val);<br />
value=170; val <<= value;<br />
xPSetButton->setPropertyValue(OUString::createFromAscii("PositionY"),val);<br />
value=50; val <<= value;<br />
xPSetButton->setPropertyValue(OUString::createFromAscii("Width"),val);<br />
value=14; val <<= value;<br />
xPSetButton->setPropertyValue(OUString::createFromAscii("Height"),val);<br />
val <<=OUString::createFromAscii("Button1");<br />
xPSetButton->setPropertyValue(OUString::createFromAscii("Name"),val);<br />
xPSetButton->setPropertyValue(OUString::createFromAscii("TabIndex"),makeAny((short)0));<br />
val <<=OUString::createFromAscii(">>");<br />
xPSetButton->setPropertyValue(OUString::createFromAscii("Label"),val);<br />
<br />
// second button : OK button<br />
// we need a second button modedl<br />
Reference< XInterface > xbuttonModel2 = xMultiServiceFactory->createInstance(<br />
OUString::createFromAscii("com.sun.star.awt.UnoControlButtonModel"));<br />
#ifdef DEBUG<br />
if (xbuttonModel.is()) printf("OK UnoControlButtonModel\n"); else printf("Error ... UnoControlButtonModel\n");<br />
#endif<br />
Reference< XPropertySet > xPSetButton2(xbuttonModel2,UNO_QUERY);<br />
#ifdef DEBUG<br />
if (xPSetButton2.is()) printf("OK XPropertySet\n"); else printf("Error ... XPropertySet\n");<br />
#endif<br />
// *** The following property is not position-independant !!!!!<br />
// Don't forget to add : #include <com/sun/star/awt/PushButtonType.hpp><br />
// Don't forget to add "com.sun.star.awt.PushButtonType \" in the makefile<br />
// short is found with Inspector<br />
val <<= (short)PushButtonType_OK;<br />
xPSetButton2->setPropertyValue(OUString::createFromAscii("PushButtonType"),val);<br />
<br />
value=220; val <<= value;<br />
xPSetButton2->setPropertyValue(OUString::createFromAscii("PositionX"),val);<br />
value=170; val <<= value;<br />
xPSetButton2->setPropertyValue(OUString::createFromAscii("PositionY"),val);<br />
value=50; val <<= value;<br />
xPSetButton2->setPropertyValue(OUString::createFromAscii("Width"),val);<br />
value=14; val <<= value;<br />
xPSetButton2->setPropertyValue(OUString::createFromAscii("Height"),val);<br />
val <<=OUString::createFromAscii("Button2");<br />
xPSetButton2->setPropertyValue(OUString::createFromAscii("Name"),val);<br />
xPSetButton2->setPropertyValue(OUString::createFromAscii("TabIndex"),makeAny((short)1));<br />
val <<=OUString::createFromAscii("OK");<br />
xPSetButton2->setPropertyValue(OUString::createFromAscii("Label"),val);<br />
<br />
Reference< XInterface > xlabelModel = xMultiServiceFactory->createInstance(<br />
OUString::createFromAscii("com.sun.star.awt.UnoControlEditModel"));<br />
#ifdef DEBUG<br />
if (xlabelModel.is()) printf("OK EditModel\n"); else printf("Error ... EditModel\n");<br />
#endif<br />
Reference< XPropertySet > xPSetLabel(xlabelModel,UNO_QUERY);<br />
#ifdef DEBUG<br />
if (xPSetLabel.is()) printf("OK XPropertySet2\n"); else printf("Error ... XPropertySet2\n");<br />
#endif<br />
value=10; val <<= value;<br />
xPSetLabel->setPropertyValue(OUString::createFromAscii("PositionX"),val);<br />
value=10; val <<= value;<br />
xPSetLabel->setPropertyValue(OUString::createFromAscii("PositionY"),val);<br />
value=280; val <<= value;<br />
xPSetLabel->setPropertyValue(OUString::createFromAscii("Width"),val);<br />
value=150; val <<= value;<br />
xPSetLabel->setPropertyValue(OUString::createFromAscii("Height"),val);<br />
xPSetLabel->setPropertyValue(OUString::createFromAscii("HScroll"),makeAny((sal_Bool)true));<br />
xPSetLabel->setPropertyValue(OUString::createFromAscii("VScroll"),makeAny((sal_Bool)true));<br />
xPSetLabel->setPropertyValue(OUString::createFromAscii("MultiLine"),makeAny((sal_Bool)true));<br />
xPSetLabel->setPropertyValue(OUString::createFromAscii("HardLineBreaks"),makeAny((sal_Bool)true));<br />
val <<=OUString::createFromAscii("Label1");<br />
xPSetLabel->setPropertyValue(OUString::createFromAscii("Name"),val);<br />
xPSetLabel->setPropertyValue(OUString::createFromAscii("TabIndex"),makeAny((short)2));<br />
<br />
// insert all the control in container<br />
Reference< XNameContainer > xNameCont(xdialogModel,UNO_QUERY);<br />
#ifdef DEBUG<br />
if (xNameCont.is()) printf("OK XNameContainer\n"); else printf("Error ... XNameContainer\n");<br />
#endif<br />
val <<= xbuttonModel;<br />
// We insert first the button<br />
xNameCont->insertByName(OUString::createFromAscii("Button1") ,val);<br />
#ifdef DEBUG<br />
printf("First\n");<br />
#endif<br />
val <<= xbuttonModel2;<br />
xNameCont->insertByName(OUString::createFromAscii("Button2") ,val); //printf("First\n");<br />
// We insert now the text control<br />
val <<= xlabelModel;<br />
xNameCont->insertByName(OUString::createFromAscii("Label1") , val);<br />
// create the dialog control and set the model<br />
Reference< XInterface >dialog = xServiceManager->createInstance(<br />
OUString::createFromAscii("com.sun.star.awt.UnoControlDialog"));<br />
#ifdef DEBUG<br />
if (dialog.is()) printf("OK dialog\n"); else printf("Error ... dialog\n");<br />
#endif<br />
Reference< XControl > xControl(dialog,UNO_QUERY);<br />
#ifdef DEBUG<br />
if (xControl.is()) printf("OK XControl\n"); else printf("Error ... XControl\n");<br />
#endif<br />
Reference< XControlModel > xControlModel(xdialogModel,UNO_QUERY);<br />
#ifdef DEBUG<br />
if (xControlModel.is()) printf("OK xControlModel\n"); else printf("Error ... xControlModel\n");<br />
#endif<br />
xControl->setModel(xControlModel);<br />
<br />
// add an action listener to the button control<br />
Reference< XControlContainer > xControlCont(dialog,UNO_QUERY);<br />
#ifdef DEBUG<br />
if (xControlCont.is()) printf("OK xControlContainer\n"); else printf("Error ... xControlContainer\n");<br />
#endif<br />
Reference< XInterface > objectButton=xControlCont->getControl(OUString::createFromAscii("Button1"));<br />
#ifdef DEBUG<br />
if (objectButton.is()) printf("OK objectButton\n"); else printf("Error ... objectButton\n");<br />
#endif<br />
Reference< XButton > xButton(objectButton,UNO_QUERY);<br />
ActionListenerImpl *xListener = new ActionListenerImpl( xControlCont,this );<br />
Reference< XActionListener > xActionListener = static_cast< XActionListener* > ( xListener );<br />
xButton->addActionListener( xActionListener );<br />
<br />
// create a peer<br />
Reference< XToolkit >xToolkit = Reference< XToolkit >( xServiceManager->createInstance(<br />
OUString( RTL_CONSTASCII_USTRINGPARAM(<br />
"com.sun.star.awt.Toolkit" ))), UNO_QUERY );<br />
#ifdef DEBUG<br />
if (xToolkit.is()) printf ("XToolkit OK...\n"); else printf("XToolkit Error\n");<br />
#endif<br />
Reference< XWindow > xWindow(xControl,UNO_QUERY);<br />
xWindow->setVisible(true);<br />
xControl->createPeer(xToolkit,NULL);<br />
<br />
Reference< XDialog > xDialog(dialog,UNO_QUERY);<br />
xDialog->execute();<br />
Reference< XComponent > xComponent(dialog,UNO_QUERY);<br />
xComponent->dispose();<br />
<br />
}<br />
</source><br />
We need also an event listener (see [[OpenOffice_Calc#Event_Listener|Calc Event Listener]] and [[First_Dialog|First Dialog]]). The corresponding code is :<br />
<source lang="cpp"><br />
//Listing 17 action performed event listener<br />
// C++<br />
// Don't forget the #include <cppuhelper/implbase1.hxx><br />
typedef ::cppu::WeakImplHelper1< ::com::sun::star::awt::XActionListener > ActionListenerHelper;<br />
/** action listener<br />
*/<br />
class ActionListenerImpl : public ActionListenerHelper<br />
{<br />
private :<br />
sal_Int32 _nCounts;<br />
Reference< XControlContainer > _xControlCont;<br />
//XControlContainer _xControlCont;<br />
ReflectionHelper *refHelp;<br />
Sequence <OUString> methods,properties,services,types;<br />
<br />
public :<br />
<br />
ActionListenerImpl(const Reference< XControlContainer >& xControlCont,ReflectionHelper *rHelper) {<br />
_xControlCont = xControlCont;<br />
_nCounts = 0;<br />
refHelp = rHelper;<br />
methods = refHelp->getMethods();<br />
properties = refHelp->getPropertiesWithValues();<br />
services = refHelp->getServices();<br />
types = refHelp->getTypes();<br />
}<br />
<br />
// XEventListener<br />
virtual void SAL_CALL disposing (const com::sun::star::lang::EventObject& aEventObj ) throw(::com::sun::star::uno::RuntimeException) {<br />
// _xControlCont = NULL;<br />
#ifdef DEBUG<br />
printf("object listened to will be disposed\n");<br />
#endif<br />
}<br />
<br />
// XActionListener<br />
virtual void SAL_CALL actionPerformed (const ::com::sun::star::awt::ActionEvent& rEvent ) throw ( RuntimeException) {<br />
OUString OUStr;<br />
// set label text<br />
Reference< XControl > label = _xControlCont->getControl(OUString::createFromAscii("Label1"));<br />
<br />
// Don't forget to add : #include <com/sun/star/awt/XTextComponent.hpp><br />
// Don't forget to add "com.sun.star.awt.XTextComponent \" in the makefile<br />
Reference< XTextComponent > xLabel(label,UNO_QUERY);<br />
switch (_nCounts%4){<br />
case 0 :<br />
for (int i=0;i<methods.getLength();i++){<br />
if(i==0) xLabel->setText(methods[i] + OUString::createFromAscii("\n"));else<br />
xLabel->insertText (xLabel->getSelection(),<br />
methods[i] + OUString::createFromAscii("\n"));<br />
}<br />
xLabel->insertText (xLabel->getSelection(),<br />
OUString::createFromAscii("******** Methods : ") +<br />
OUStr.valueOf((sal_Int32)methods.getLength())+ OUString::createFromAscii("\n"));<br />
break;<br />
case 1 :for (int i=0;i<properties.getLength();i++){<br />
if(i==0) xLabel->setText(properties[i] + OUString::createFromAscii("\n"));else<br />
xLabel->insertText (xLabel->getSelection(),<br />
properties[i] + OUString::createFromAscii("\n"));<br />
}<br />
xLabel->insertText (xLabel->getSelection(),<br />
OUString::createFromAscii("******** Properties : ") +<br />
OUStr.valueOf((sal_Int32)properties.getLength())+ OUString::createFromAscii("\n"));<br />
break;<br />
case 2 :for (int i=0;i<services.getLength();i++){<br />
if(i==0) xLabel->setText(services[i] + OUString::createFromAscii("\n"));else<br />
xLabel->insertText (xLabel->getSelection(),<br />
services[i] + OUString::createFromAscii("\n"));<br />
}<br />
xLabel->insertText (xLabel->getSelection(),<br />
OUString::createFromAscii("******** Services : ") +<br />
OUStr.valueOf((sal_Int32)services.getLength())+ OUString::createFromAscii("\n"));<br />
break;<br />
case 3 :for (int i=0;i<types.getLength();i++){<br />
if(i==0) xLabel->setText(types[i] + OUString::createFromAscii("\n"));else<br />
xLabel->insertText (xLabel->getSelection(),<br />
types[i] + OUString::createFromAscii("\n"));<br />
}<br />
xLabel->insertText (xLabel->getSelection(),<br />
OUString::createFromAscii("******** Types - Interfaces : ") +<br />
OUStr.valueOf((sal_Int32)types.getLength())+ OUString::createFromAscii("\n"));<br />
break;<br />
}<br />
<br />
// increase click counter<br />
_nCounts++;<br />
}<br />
};<br />
</source><br />
{{Documentation/Caution|<br />
Because it's hard to maintain code cut in many parts as above, I have added a [[Development/Cpp/Helper/ReflectionHelper|Snippet here]]. This snippet will be the more recent complete class code.}}<br />
<br />
===Using The Helper===<br />
<br />
Using this helper is easy : here is an example using <idl>com.sun.star.frame.XComponentLoader</idl>, <idl>com.sun.star.lang.XMultiServiceFactory</idl> Interfaces and <idl>com.sun.star.frame.Desktop</idl> service and also [[UNO_automation_with_a_binary_%28executable%29#Preparing_a_new_Code_as_a_starting_Point|ooConnect()]]. In a separate C++ file you can put :<br />
<source lang="cpp"><br />
//Listing 18 Using this helper<br />
// C++<br />
main( ) {<br />
//retrieve an instance of the remote service manager<br />
Reference< XMultiServiceFactory > xServiceManager;<br />
xServiceManager = ooConnect();<br />
if( xServiceManager.is() ){<br />
printf( "Connected sucessfully to the office\n" );<br />
}<br />
<br />
//get the desktop service using createInstance returns an XInterface type<br />
Reference< XInterface > Desktop = xServiceManager->createInstance(<br />
OUString::createFromAscii( "com.sun.star.frame.Desktop" ));<br />
<br />
//query for the XComponentLoader interface<br />
Reference< XComponentLoader > rComponentLoader (Desktop, UNO_QUERY);<br />
if( rComponentLoader.is() ){<br />
printf( "XComponentloader successfully instanciated\n" );<br />
}<br />
<br />
Any toInspect;<br />
// I want to inspect rComponentLoader object :<br />
toInspect <<= rComponentLoader;<br />
// need a service manager<br />
ReflectionHelper *Reflect = new (ReflectionHelper)(toInspect,xServiceManager);<br />
<br />
Reflect->printOut();<br />
<br />
return 0;<br />
}<br />
</source><br />
The corresponding result is given in the Figure below :<br />
<br />
[[Image:MyInspector.png]]<br />
<br />
After launching this dialog, please click on ">>" button to see the other informations on services, interfaces and properties.<br />
<br />
{{Documentation/Note|If you want to use this helper you have to modify [[MakeFile#Office_connect_with_a_helper|the makefile]] because your class is compiled as object file and then linked together with the office_connect program.}}<br />
<br />
{{Template:Home_Page}}<br />
<br />
=See also=<br />
<br />
* [[Documentation/DevGuide/Basic/Creating_Dialogs_at_Runtime|Creating Dialogs at Runtime]] in Developer's Guide<br />
* [[Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno|C++ and UNO tutorial]]<br />
* [[XIntrospection_Interface|XIntrospection Interface]]<br />
* [[XIDLReflection_Interface|XIdlReflection Interface]]<br />
* 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<br />
* Bernard Marcelly's [[Extensions_development_basic#Xray_tool|XRay tool description]] in this wiki.<br />
* See [[Object Inspector|The New Object Inspector]]<br />
* [[Extensions_introspection|Extensions Introspection]]<br />
<br />
[[Category:Cpp]]<br />
[[Category:Uno]]<br />
[[Category:Tutorial]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Extensions_development_basicExtensions development basic2016-05-01T05:56:10Z<p>BMarcelly: /* See also */ Xray link updated to the relocated site</p>
<hr />
<div>'''Getting started tutorial''' <br />
<br />
This page provides a getting started guide for writing macros in OpenOffice.org Basic. It assumes some prior programming knowledge. Please edit this page to make it more readable. I hope you will find it useful.<br />
<br />
If you already know the basics then you may want the [[CookBook]] for wrappers and examples.<br />
<br />
<br />
==Where do I write the code?==<br />
OpenOffice.org Basic code is stored in modules within libraries. A library can be: <br />
<br />
*Shared (for a network install - OOo Macros & Dialogs) <br />
*Just for the current user (My Macros & Dialogs) <br />
*Within a document or template, so that its code is only available when that document is open.<br />
<br />
Libraries stored in a document can easily be copied, transported and distributed with the document.<br />
<br />
Libraries not stored in a document or template (that is libraries that are shared or for the current user) are referred to as '''OpenOffice.org libraries'''. <br />
<br />
To determine the actual folders that contain the OpenOffice.org libraries see:<br> '''Tools > Options… > OpenOffice.org > Paths > BASIC'''. <br />
<br />
{| border="1"<br />
|'''Note'''<br />
|Do not copy or move libraries using operating system commands. Use the macro organizer or package manager instead.<br />
|-<br />
|}<br />
<br />
<br />
Modules within libraries have a maximum size of 64kb. A library can contain up to 16,000 modules. <br />
<br />
For more information see online help for: Modules and Libraries.<br />
<br />
==Accessing the IDE==<br />
To access the IDE for the first time: <br />
<br />
OpenOffice.org 1.1.x: '''Tools > Macros > Macro… >''' <br />
<br />
OpenOffice.org 1.9.x and above: '''Tools > Macros > Organize macros > OpenOffice.org Basic… >''' <br />
<br />
To get started we will use Module1 in the Standard library which is stored for the current user only: <br />
<br />
Type a name for the new macro: '''HelloWorld''' <br />
<br />
In the macro from listbox select '''Standard''' <br />
<br />
Click '''New''' <br />
<br />
You should now see something like: <br />
<br />
<source lang="oobas"><br />
REM ***** BASIC *****<br />
<br />
Sub Main<br />
<br />
End Sub<br />
<br />
Sub HelloWorld<br />
<br />
End Sub<br />
</source><br />
The cursor will be positioned at the start of the <tt>Sub HelloWorld</tt> line. <br />
<br />
{| border="1"<br />
|'''Note'''<br />
|Now that while the IDE is running it can be accessed from the OpenOffice.org Window menu, or the task panel provided by the operating system.<br />
|-<br />
|}<br />
<br />
==Entering the code==<br />
Select and delete: <br />
<br />
<source lang="oobas"><br />
REM ***** BASIC *****<br />
<br />
Sub Main<br />
<br />
End Sub<br />
</source><br />
Below the line "Sub HelloWorld" type <tt>msgbox "Hello World!"</tt>, so that the editor looks like: <br />
<br />
<source lang="oobas"><br />
Sub HelloWorld<br />
msgbox "Hello World!"<br />
End Sub<br />
</source><br />
{| border="1"<br />
|'''Notes:'''<br />
|The IDE does not provide code completion or help with command syntax as you type, but to get help on a Basic command position the cursor in the command and press F1.<br> OpenOffice.org Basic commands are not case sensitive. Thus msgbox, MSGBOX and Msgbox will all work.<br> Strings are enclosed in double quotes.<br />
|-<br />
|}<br />
<br />
==Running the code==<br />
There are several ways of running the Basic code, these include: <br />
<br />
*Directly from the IDE. There is a run button on the macro bar (by default the third control on the second toolbar). This will run the first macro in the current module. <br />
<br />
*From the tools menu:<br />
<br />
**(Version 1.1.x) '''Tools > Macros > Macro…''';<br />
<br />
**(Version 1.9.x and above) '''Tools > Macro > Run Macro…''' <br />
<br />
*Assigning the macro to a [[ key press]]. <br />
<br />
*Assigning the macro to a [[ menu entry]]. <br />
<br />
*Assigning the macro to a toolbar button. <br />
<br />
*Creating a [[ control in a document]]. <br />
<br />
*Assigning the macro to an event. <br />
<br />
For now try running the "HelloWorld" subroutine by clicking the '''Run''' button. A small dialog titled "soffice" with the text "Hello World!" and an OK button should be displayed.<br />
<br />
==Saving the code==<br />
The code gets automatically saved whenever the container for the code gets saved. Thus, if the code is in an OpenOffice.org library (shared or users) then it gets automatically saved when OpenOffice.org exits. If the code is in a library which is part of a document it gets saved whenever the document is saved. <br />
<br />
On the Standard toolbar (by default the top toolbar) in the IDE there is a save button. If the code is in a document or template then clicking this button saves the entire document or template. If the code is in an OpenOffice.org library then just the current library gets saved. <br />
<br />
<br />
==Variables==<br />
It is possible to force variable declaration with <tt>Option Explicit</tt> at the top of the module. For a discussion on whether to declare variables or not, see: [[http://www.oooforum.org/forum/viewtopic.phtml?t=5845 this discussion]]. <br />
<br />
In that discussion the initial author of this wiki thought that variables should always be declared. Since then he has changed to not declaring them. In short it is generally a personal preference. In either case, it is the initial authors preference that variables be named according to the following convention, which is used in the examples in this Wiki: <br />
<br />
The first letter of the variable name indicates the type of value that the variable is going to hold, as per the following table (based on a table in Tutorial.pdf by Sun) <br />
<br />
{| border="1"<br />
|'''''Letter'''''<br />
|'''''Meaning'''''<br />
|-<br />
|a<br />
|Structure<br />
|-<br />
|b<br />
|Boolean (TRUE or FALSE)<br />
|-<br />
|e<br />
|Enumeration. This variable can only have one of a limited set of values.<br />
|-<br />
|f<br />
|Float (3.402823 x 1038 to 1.401298 x 10-45. A single variable can take up to four bytes)<br> Double (1.79769313486232 x 10308 to 4.94065645841247 x 10-324. A double variable can take up to eight bytes)<br> Currency (-922337203685477.5808 to +922337203685477.5807 and takes up to eight bytes of memory)<br />
|-<br />
|m<br />
|Array (aka sequence aka matrix)<br />
|-<br />
|n<br />
|Integer (-32768 to 32767.) or<br> Long (-2147483648 and 2147483647).<br />
|-<br />
|o<br />
|Object, service, or interface<br />
|-<br />
|s<br />
|String (A string variable can store up to 65535 Unicode characters).<br />
|-<br />
|x<br />
|Interface, to indicate that only operations of a particular interface of an object are used<br />
|-<br />
|v<br />
|Variant, Any<br />
|-<br />
|}<br />
<br />
<br />
Use long descriptive variable names making use of camel case: <tt>nMsgBoxReturn</tt><br />
<br />
{| border="1"<br />
|'''Note:'''<br />
|User-defined OpenOffice.org Basic variables are not case sensitive. But UNO-API constants ''are'' case sensitive.<br />
|}<br />
<br />
<br />
Convention exceptions to long descriptive names are for index variables where <tt>i, j,</tt> and <tt>k</tt> are commonly used, and for when a string is being built-up, where <tt>s</tt> is commonly used. <br />
<br />
Edit sub HelloWorld so that it looks like the following and run it: <br />
<br />
<source lang="oobas"><br />
sub HelloWorld<br />
dim i as integer 'This line is optional<br />
for i = 0 to 2<br />
'These lines are indented for ease of reading only.<br />
'All your code should be like this for long-term survival.<br />
msgbox "Hello World " & i<br />
next i<br />
end sub<br />
</source><br />
For more information on variables see the online help for "using variables".<br />
<br />
==Understanding the OpenOffice.org API==<br />
This section will start with an example. The remainder of this section aims to give information so that the example can be understood and expanded upon. <br />
<br />
Try running the following code with different types of documents being active. <br />
<br />
<source lang="oobas"><br />
sub main<br />
'BasicLibraries.loadLibrary("XrayTool")<br />
'xray thisComponent<br />
msgbox fnWhichComponent(thisComponent)<br />
end sub<br />
<br />
<br />
function fnWhichComponent(oDoc) as string<br />
if HasUnoInterfaces(oDoc, "com.sun.star.lang.XServiceInfo") then <br />
if oDoc.supportsService ("com.sun.star.text.GenericTextDocument") then<br />
fnWhichComponent = "Text"<br />
elseif oDoc.supportsService("com.sun.star.sheet.SpreadsheetDocument") then<br />
fnWhichComponent = "Spreadsheet"<br />
elseif oDoc.supportsService("com.sun.star.presentation.PresentationDocument") then<br />
fnWhichComponent = "Presentation"<br />
elseif oDoc.supportsService("com.sun.star.drawing.GenericDrawingDocument") then<br />
fnWhichComponent = "Drawing"<br />
else<br />
fnWhichComponent = "Oops current document something else"<br />
end if<br />
else<br />
fnWhichComponent = "Not a document"<br />
end if<br />
End function<br />
</source><br />
<br />
===Subroutine naming convention===<br />
In the above example the user defined function has a name that starts with the letters "fn". This is the initial author's convention so that people know that this is a user defined function. Similarly, the initial author uses the convention that user defined subroutines start with the letters "sub". When learning a language and an API it can be difficult to know what is built-in and what has been defined elsewhere. This document/wiki will use this convention for naming functions and subroutines.<br />
<br />
===Introducing the OpenOffice.org API===<br />
This section introduces the following terms: <br />
<br />
* Interface <br />
* Module <br />
* Service <br />
* Method <br />
* Property <br />
<br />
Understanding the difference between an interface and a service and what a module is, is not essential to being able to write extensions for OpenOffice.org, but it does help interpreting the documentation, and for introspection purposes. You may need to read this section at least twice. <br />
<br />
An '''interface''' is a ''definition'' of a set of methods (and their arguments) that a service which implements that interface must have. <br />
<br />
Interfaces are grouped together in '''modules''' for naming purposes. All interfaces (and services) start with the name "com.sun.star" then the name of the module then the name of the interface (or service). <br />
<br />
For example most services provide the com.sun.star.beans.XPropertySet interface. This interface is stored in the module "beans" and provides access to the properties of a service. A '''property''' is a value whereas a '''method''' is an action. <br />
<br />
An OpenOffice.org object can have many services. <br />
<br />
An OpenOffice.org object may have a service, which implements an interface, in which a method description says that another OpenOffice.org object is returned.<br />
<br />
===Introspection===<br />
<tt>HasUnoInterfaces</tt> is an OpenOffice.org Basic function for introspection. See this [[http://www.oooforum.org/forum/viewtopic.phtml?t=7068 link]] for information on introspection in other languages. <br />
<br />
<tt>HasUnoInterfaces</tt> returns true if all of the specified interfaces are available for the specified object. <br />
<br />
Most OpenOffice.org objects provide the method <tt>supportsService</tt> because they have the interface <idl>com.sun.star.lang.XServiceInfo</idl>. <br />
<br />
In the above example, the OpenOffice.org Basic command <tt>HasUnoInterfaces</tt> checks that the current document has the interface <idl>com.sun.star.lang.XServiceInfo</idl>, because if it doesn't have that interface then it doesn't have the method <tt>supportsService</tt>, and a run time error would occur if such an object tried to access its nonexistent method. <br />
<br />
<tt>SupportsService</tt> is a method which returns true if the specified service is available. The above examples checks for a service to determine the type of document that is currently active.<br />
<br />
<br />
===Xray tool===<br />
Using <tt>HasUnoInterfaces</tt> and <tt>supportsService</tt> gives information about an object at run time, but checking an object like this would be a nightmare for learning? Thankfully, Bernard Marcelly has come to our rescue with the Xray tool. The Xray tool is available from: [[http://berma.pagesperso-orange.fr/Files_en/XrayTool60_en.odt odt installer(en)]]. Download the odt file, open the document in OpenOffice.org, follow the instructions for installation and set-up. <br />
<br />
Part of the Xray tool set-up is to specify a local copy of the OpenOffice.org SDK. Download the [http://www.openoffice.org/download/other.html#tested-sdk Apache OpenOffice 3.4 SDK] and extract it. <br />
<br />
In the above example, at the start of the code, there are two commented lines (comments start with an apostrophe): <br />
<br />
<source lang="oobas"><br />
'BasicLibraries.loadLibrary("XrayTool")<br />
'xray thisComponent<br />
</source><br />
Now that you have the Xray tool installed, uncomment these lines (remove the apostrophes) and rerun the macro.<br />
<br />
[[image:Xray60en.png]]<br />
<br />
'''BasicLibraries''' is an OpenOffice.org Basic command that returns an object for accessing the OpenOffice.org libraries. The <tt>loadLibrary</tt> method ensures that the routines in that library are available for use. <br />
<br />
<tt>xray</tt> specifies the <tt>xray</tt> subroutine within the library <tt>XrayTool</tt>. <tt>thisComponent</tt> is the object that is being passed to <tt>xray</tt> for introspection. <br />
<br />
To find the object that you want to work with often requires finding or creating it starting from either <tt>StarDesktop</tt> or <tt>thisComponent</tt>.<br />
<br />
===Desktop, documents, and current selection===<br />
<tt>StarDesktop</tt> and <tt>thisComponent</tt> are OpenOffice.org Basic commands that refer to the application and currently active document respectively. <br />
<br />
Unlike Microsoft Office, OpenOffice.org is one application with different components. When running some code it maybe useful to check which component is currently active. The above code demonstrates how that checking process can be done. <br />
<br />
The Desktop that <tt>StarDesktop</tt> refers to is conceptual (historically it actually existed) and can be thought of as the OpenOffice.org application.<br />
<br />
==Creating new documents==<br />
To create a new text document: <br />
<br />
<source lang="oobas"><br />
oDoc = StarDesktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, Array())<br />
</source><br />
To create a new spreadsheet document: <br />
<br />
<source lang="oobas"><br />
oDoc = StarDesktop.loadComponentFromURL("private:factory/scalc", "_blank", 0, Array())<br />
</source><br />
An easier approach would be to write a simple function: <br />
<source lang="oobas"><br />
function fnNewDoc(sDocType as string)<br />
fnNewDoc = StarDesktop.loadComponentFromURL("private:factory/" & sDocType , "_blank", 0, Array())<br />
end function<br />
</source><br />
Then creating new documents can be achieved with: <br />
<br />
<source lang="oobas"><br />
oDoc = fnNewDoc("swriter")<br />
oDoc = fnNewDoc("scalc")<br />
oDoc = fnNewDoc("simpress")<br />
oDoc = fnNewDoc("sdraw")<br />
oDoc = fnNewDoc("smath")<br />
</source><br />
See http://api.openoffice.org/docs/common/ref/com/sun/star/frame/XComponentLoader.html .<br />
<br />
==To open a document==<br />
The following example shows how to open a file. For information on URLs in OpenOffice.org see [[ URL Basics]]. <br />
<br />
<source lang="oobas"><br />
sFile = "C:\Documents and Settings\danny\Desktop\MyCalc.sxc" ' Windows<br />
sFile = "/home/danny/Desktop/MyCalc.sxc" ' Linux<br />
sURL = ConvertToURL(sFile)<br />
oDoc = StarDesktop.loadComponentFromURL(sURL, "_blank", 0, Array())<br />
</source><br />
Again it may make sense to make this easier by writing a simple function: <br />
<br />
<source lang="oobas"><br />
function fnOpenDoc(sFile)<br />
sURL = ConvertToURL(sFile)<br />
fnOpenDoc = StarDesktop.loadComponentFromURL(sURL, "_blank", 0, Array())<br />
end function<br />
</source><br />
Examples of calling the function: <br />
<br />
<source lang="oobas"><br />
oDoc = fnOpenDoc("C:\Documents and Settings\danny\Desktop\MyCalc.sxc") ' Windows<br />
oDoc = fnOpenDoc("/home/danny/Desktop/MyCalc.sxc") ' Linux<br />
</source><br />
<br />
==Opening a new file from a template==<br />
If you want to open a file using an existing template, use the template name instead of the file name. An untitled document will be opened from the template. <br />
<br />
Alternatively, set the "AsTemplate" property in the MediaDescriptor for the opened template to TRUE, and a new file will be opened based on the template, even if the template was stored by OO as an ordinary file, rather than a template. [[Opening a document]] has some examples.<br />
<br />
If the template location is known, simply use it. However, OpenOffice keeps at least two sets of templates: global templates available to all users and "My Templates" available to the current user, and the locations of the directories are not obviously available. They can be found by means of the [http://www.openoffice.org/api/docs/common/ref/com/sun/star/util/PathSettings.html PathSettings service] which allows the user to examine the various directory paths known to OpenOffice. The Template property of this service returns a string which is a semi-colon separated list of URLS, each of which represents a possible location for the desired template. It is necessary to search this string and the resulting directories to find the template. The following code finds a user template and opens a document based on it:<br />
<br />
<source lang="oobas"><br />
Dim PathService as Object<br />
Dim TemplatePath as String ' The path list<br />
Dim SCPos as Integer ' The position of the next semi-colon <br />
Dim MyTemplatePath as String ' The URL for the user template<br />
<br />
' substitute your template name here<br />
const TemplateName = "MyTemplate.ott"<br />
<br />
' This seems to be the place in which OO stores user templates<br />
const UserTemplateDirectory="/user/template"<br />
<br />
<br />
PathService=CreateUNOService("com.sun.star.util.PathSettings")<br />
TemplatePath=PathService.Template<br />
MyTemplatePath=""<br />
<br />
do while len(TemplatePath) >0<br />
SCPos=InStr (TemplatePath,";")<br />
if SCPos>0 then<br />
MyTemplatePath=Left(TemplatePath, SCPos-1)<br />
else<br />
MyTemplatePath=TemplatePath<br />
end if<br />
<br />
' NOTE: as well as file URLs there are some others which should be ignored<br />
if InStr(myTemplatePath,"file:///")=1 And _<br />
Right(myTemplatePath,14) = UserTemplateDirectory then<br />
exit do <br />
end if<br />
TemplatePath=mid(TemplatePath, SCPos+1, len(TemplatePath)-SCPos)<br />
MyTemplatePath="" <br />
loop<br />
<br />
if MyTemplatePath<>"" then<br />
TemplatePath=ConverttoURL(TemplateName)<br />
MyTemplatePath=MyTemplatePath & "/" & TemplateName<br />
InvoiceDoc=StarDesktop.LoadComponentfromURL(MytemplatePath, "_blank", 0, Array())<br />
else<br />
MsgBox "Cannot find the template directory"<br />
end if<br />
</source><br />
<br />
This code does not check that the desired template actually exists; if it doesn't, the LoadComponentfromURL call will fail.<br />
<br />
==Current Selection==<br />
It is common to want to run some code that affects the current selection. <tt>ThisComponent</tt> has the method <tt>getCurrentSelection</tt>. Since many different types of objects could possibly be selected it is common to check that the currently selected object has the service that contains the method that we want to apply to the object. <br />
<br />
Edit the main subroutine to the following and rerun it on a text document with different selections. (To select more than one block of text hold down the control key). <br />
<br />
<source lang="oobas"><br />
sub main<br />
BasicLibraries.loadLibrary("XrayTool")<br />
if fnWhichComponent(thisComponent) = "Text" then<br />
oCurSelection = thisComponent.getCurrentSelection()<br />
'xray oCurSelection<br />
if oCurSelection.supportsService("com.sun.star.text.TextRanges") then<br />
msgbox "There are " & oCurSelection.getCount() & _<br />
" selections in the current text document."<br />
end if<br />
end if<br />
end sub<br />
</source><br />
With nothing selected the number of selections is one - the insertion point, with one block of text selected the count is still one, but with two blocks of text the count is three - the insertion point and the two blocks of selected text. <br />
<br />
Exercise 1: Modify the above code so that it works on selected cell ranges in a spreadsheet. <br />
<br />
Question1: For two blocks of cells selected, what would be the count for the number of selections?<br />
<br />
==Properties==<br />
Uncomment <tt>'xray oCurSelection</tt> so that xray runs, to see that the object that <tt>oCurSelection</tt> points to has a "property" called <tt>Count</tt> with a description of "pseudo-prop, read only". It is possible in OpenOffice.org Basic to write <tt>oCurSelection.count</tt>, but as this is not possible in all other languages accessing the OpenOffice.org API, this Wiki will try to always use the method approach. (I say try because I have not been in the habit of doing this and sometimes I may forget). <br />
<br />
This next example demonstrates changing a property value for the current selections. <br />
<br />
<source lang="oobas"><br />
sub main<br />
BasicLibraries.loadLibrary("XrayTool")<br />
if fnWhichComponent(thisComponent) = "Text" then<br />
oCurSelection = thisComponent.getCurrentSelection()<br />
if oCurSelection.supportsService("com.sun.star.text.TextRanges") then<br />
nCount = oCurSelection.Count<br />
'xray oCurSelection.getByIndex(0)<br />
'Warning: The insertion point will have the same action applied twice<br />
'in this case it doesn't matter, but in others it might.<br />
for i = 0 to nCount - 1<br />
oCurSelection.getByIndex(i).setPropertyValue("CharStyleName", "Strong Emphasis")<br />
next<br />
end if<br />
end if<br />
end sub<br />
</source><br />
In OpenOffice.org Basic it is possible to shorten the assignment line to: <br />
<br />
<source lang="oobas"><br />
oCurSelection(i).CharStyleName = "Strong Emphasis"<br />
</source><br />
This wiki will try to use the full methods for both indexing and assigning properties. The rationale is that this makes converting the code to other languages easier and also helps the learner to understand what is happening (again I have not been in the habit of doing this so some examples may slip past me). <br />
<br />
Exercise 2: Rewrite the above code so that the warning can be removed. <br />
<br />
See [[ Current selection]].<br />
<br />
==Iterative Access to Subordinate Objects (Enumeration access)==<br />
Sometimes to access the desired object an enumeration is required. For example paragraphs, within a document or within a selection. <br />
<br />
When a Writer document is active and some text is selected, both <tt>thisDocument.getText()</tt> and <tt>thisComponent.getCurrentSelection().getByIndex(i)</tt> have the service: <idl>com.sun.star.text.TextRange</idl>, which has the interface: <idl>com.sun.star.container.XContentEnumerationAccess</idl>. It is possible to create an enumeration of the paragraphs for the current document or for a particular selection. <br />
<br />
<source lang="oobas"><br />
' Create enumeration object<br />
oTextElementEnum = thisComponent.getText().createEnumeration()<br />
'or thisComponent.getCurrentSelection().getByIndex(i).createEnumeration()<br />
<br />
' loop over all text elements<br />
while oTextElementEnum.hasMoreElements()<br />
oTextElement = oTextElementEnum.nextElement<br />
if oTextElement.supportsService("com.sun.star.text.TextTable") then<br />
MsgBox "The current block contains a table."<br />
end if<br />
if oTextElement.supportsService("com.sun.star.text.Paragraph") then<br />
MsgBox "The current block contains a paragraph."<br />
end if<br />
wend<br />
</source><br />
Exercise 3: Extend the above example to display in a message box all text portions that are bold.<br />
<br />
==Named access==<br />
Some objects provide named access to a particular type of subordinate object, some others indexed access, and some both named and indexed access. <br />
<br />
For example if the current document in OpenOffice.org is a spreadsheet then to access a particular sheet can be done by index access: <br />
<br />
<source lang="oobas"><br />
oSheet = thisComponent.getSheets.getByIndex(0)<br />
</source><br />
or named access: <br />
<br />
<source lang="oobas"><br />
oSheet = thisComponent.getSheets.getByName("Sheet1")<br />
</source><br />
To check if an object with a particular name already exists use <tt>hasByName</tt>, for example: <br />
<br />
<source lang="oobas"><br />
if thisComponent.getSheets.hasByName("Sheet1") then<br />
</source><br />
To loop through all the available object names can be done like: <br />
<br />
<source lang="oobas"><br />
mNames = thisComponent.getSheets.getElementnames<br />
for i = lbound(mNames) to ubound(mNames)<br />
msgbox mNames(i)<br />
next<br />
</source><br />
<br />
<br />
Some named subordinate objects also provide the interface: <idl>com.sun.star.container.XNameContainer</idl>. This interface defines that such objects should have the following methods: <tt>insertByName</tt>, <tt>insertNewByName</tt>, <tt>replaceByname</tt> and <tt>removeByName</tt>. <br />
<br />
E.g. <br />
<br />
<source lang="oobas"><br />
thisComponent.getSheets.insertNewByName("NewSheet", 0)<br />
</source><br />
<br />
==Create new objects==<br />
Some objects have services which implement interfaces to provide specific methods for creating a particular type of object. <br />
<br />
For example if the current document is a Writer document then <tt>thisComponent.getText</tt> is an object that provides the service <idl>com.sun.star.text.Text</idl>, which implements the interface <idl>com.sun.star.text.XSimpleText</idl>, which defines the methods <tt>createTextCursor</tt> and <tt>createTextCursorByRange</tt>. Both of these methods create a text cursor for accessing the text of the document. These cursors are quite independent of the view cursor. The view cursor is visible on the screen and is manipulated by the user (and can be manipulated by program control), whereas a text cursor is not visible on the screen and is solely used by program control. The following code snippet demonstrates creating a new text cursor, such that it starts at the same location as the view cursor and is then moved independent of the view cursor. <br />
<br />
<source lang="oobas"><br />
oVC = thisComponent.getCurrentController.getViewCursor<br />
oCursor = oVC.getText.createTextCursorByRange(oVC)<br />
oCursor.gotoStartOfSentence(false)<br />
oCursor.gotoEndOfSentence(true)<br />
msgbox oCursor.getString<br />
</source><br />
The string returned by the <tt>oCursor.getString</tt> method is the text of the sentence in which the view cursor currently resides.<br />
<br />
Some objects are context dependent and get created using the method <tt>createInstance</tt> which is defined in the interface <idl>com.sun.star.lang.XMultiServiceFactory</idl>. For example to add a rectangle to the first page of a drawing document: <br />
<br />
<source lang="oobas"><br />
dim aPoint as new com.sun.star.awt.Point<br />
dim aSize as new com.sun.star.awt.Size<br />
<br />
aPoint.x = 1000<br />
aPoint.y = 1000<br />
<br />
aSize.Width = 10000<br />
aSize.Height = 10000<br />
<br />
oRectangleShape = thisComponent.createInstance("com.sun.star.drawing.RectangleShape")<br />
oRectangleShape.Size = aSize<br />
oRectangleShape.Position = aPoint<br />
<br />
thisComponent.getDrawPages.getByIndex(0).add(oRectangleShape)<br />
</source><br />
<br />
This example also uses ''UNO structs''. See below for more information on UNO structs. <br />
<br />
Some objects are context independent; to create these objects, use the OpenOffice.org Basic command <tt>createUnoService</tt>. For example, to create the equivalent to <tt>StarDesktop</tt>: <br />
<br />
<source lang="oobas"><br />
oDesktop = createUnoService("com.sun.star.frame.Desktop")<br />
</source><br />
<br />
The process that I use to determine how to access or create an object is as follows: <br />
<br />
Does the object already exist, if so I should be able to access it from something like <tt>thisComponent</tt>. <br />
<br />
Will the new object belong to another object, if so does the owner have a specific method for creating the object, if so use it. <br />
<br />
The new object will belong to another object, but that object doesn't provide a specific method for creating it, but does provide <tt>createInstance</tt>. If the object doesn't provide <tt>createInstance</tt> are you sure you are using the correct object, or is it context independent. <br />
<br />
I have found working out how to create an object to be quite difficult with existing documentation so I hope that this document/wiki will eventually make this clear. <br />
<br />
<br />
===UNO structs===<br />
UNO structures can be declared using the OpenOffice.org Basic command <tt>dim as new</tt>: <br />
<br />
<source lang="oobas"><br />
dim aPoint as new com.sun.star.awt.Point<br />
</source><br />
Or by using the OpenOffice.org Basic command <tt>createUnoStruct</tt>: <br />
<br />
<source lang="oobas"><br />
aPoint = createUnoStruct("com.sun.star.awt.Point")<br />
</source><br />
<br />
{| border="1"<br />
|'''Note:'''<br />
|When declaring UNO structs, case is important. Note that everything up to the name of the struct is lowercase, and that the name of the struct is in TitleCase.<br />
|}<br />
<br />
<br />
<br />
<br />
===Creating Listeners and Handlers===<br />
Through the user interface it is possible to assign macros to some events: <br />
<br />
OpenOffice.org versions 1.1.x: '''Tools > Configure… > Events'''. <br />
<br />
OpenOffice.org versions 1.9.x and above: '''Tools > Customize… > Events'''. <br />
<br />
It is also possible to assign macros to a wider range of events using the OpenOffice.org Basic command <tt>CreateUnoListener</tt>. This same command is used for creating both listeners and handlers. A listener checks for an event and always allows other listeners to respond to the event as well. A handler listens for an event, and can optionally consume the event so that other listeners don't get to act on it. <br />
<br />
The following example creates a keyHandler: <br />
<br />
<source lang="oobas"><br />
global IannzExampleKeyHandler<br />
<br />
sub SetupKeyHandler<br />
oController = thisComponent.currentController<br />
IannzExampleKeyHandler = CreateUnoListener("KeyHandler_","com.sun.star.awt.XKeyHandler")<br />
oController.addKeyHandler(IannzExampleKeyHandler) ' Register the listener<br />
end sub<br />
<br />
sub RemoveKeyHandler<br />
thisComponent.currentController.removeKeyHandler(IannzExampleKeyHandler)<br />
end sub<br />
<br />
sub KeyHandler_disposing<br />
end sub<br />
<br />
function KeyHandler_keyReleased(oKeyEvent as new com.sun.star.awt.KeyHandler) as boolean<br />
KeyHandler_keyReleased = False <br />
end function<br />
<br />
function KeyHandler_keyPressed(oKeyEvent as new com.sun.star.awt.KeyHandler) as boolean<br />
KeyHandler_keyPressed = false 'Let other listeners handle the event<br />
if oKeyEvent.modifiers = com.sun.star.awt.KeyModifier.MOD2 then 'Control key was pressed<br />
if oKeyEvent.keyCode = com.sun.star.awt.Key.Q then<br />
msgbox "Alt + Q was pressed"<br />
KeyHandler_keyPressed = true 'Don't let other listeners process this event<br />
end if<br />
end if<br />
end function<br />
</source><br />
A variable declared as global keeps its value even after the macro exits. In this case we want to be able to use this variable later to remove the handler. As variables declared globally could be used in other libraries, to try and avoid conflict I start all my global variables with Iannz my registered name for the OpenOffice.org web site. <br />
<br />
<tt>sub SetupKeyHandler</tt> sets up the handler. The first parameter to <tt>CreateUnoListener</tt> is the starting name for the methods that will be called when that type of event occurs: in this example, <tt>"KeyHandler_"</tt>. <br />
<br />
The second parameter is the name of the interface for the listener or handler, "<idl>com.sun.star.awt.XKeyHandler</idl>". The name is case sensitive, everything up to and including the module name is always lowercase, the name of the interface always starts with "X" and the remainder is in TitleCase. <br />
<br />
Use the SDK to find out what methods the interface must supply. You must supply routines for all of these methods even if you don't intend to use them. You also need to supply a disposing method. The names of these routines start with the string given in the first parameter to <tt>CreateUnoListener</tt>, in this example <tt>"KeyHandler_"</tt>. <br />
<br />
Thus in the example there is <tt>KeyHandler_disposing</tt> and <tt>KeyHandler_keyReleased</tt> which don't actually do anything but are required, and <tt>KeyHandler_keyPressed</tt> which actually does the job. <br />
<br />
<tt>sub RemoveKeyHandler</tt> demonstrates how to remove the handler.<br />
<br />
==OpenOffice.org constants==<br />
The above example uses OpenOffice.org constants. <br />
<br />
E.g. <tt>com.sun.star.awt.KeyModifier.MOD2</tt><br />
<br />
OpenOffice.org constants are case sensitive. Everything up to and including the module name is always lowercase. The constant group is in TitleCase. The actual constant name is always UPPERCASE. <br />
<br />
Programmers not using OpenOffice.org Basic may not have access to these constants. <br />
<br />
<br />
==Using the recorder==<br />
See [[ The OpenOffice.org recorder and UNO dispatch calls]] section for a discussion on recording UNO Dispatch commands versus writing API calls.<br />
<br />
== See also==<br />
* [[CookBook|CookBook]]<br />
* [[Text_cursor|Text Cursor in OOoBasic]]<br />
* [[Framework/Article/Easy_To_Use_Message_Boxes|Easy To Use Message Boxes]]<br />
* [[Programming_OooWriter |Programming OOoWriter in C++]] where OOoBasic records are used in C++<br />
* A [[XIntrospection_Interface|XIntrospection Interface]] short description. XRay uses this interface.<br />
* Download Bernard Marcelly's [http://berma.pagesperso-orange.fr/Files_en/XrayTool60_en.odt XRay OOoBasic tool] <br />
* See [[Object Inspector|The New Object Inspector]] and [[BASIC/UNO_Object_Browser|The BASIC UNO Object Browser]]<br />
<br />
[[Category:Extensions]]<br />
[[Category:StarBasic]]<br />
[[Category:Documentation/Candidate]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Extensions_development_basicExtensions development basic2016-05-01T05:54:06Z<p>BMarcelly: /* Xray tool */ Xray link updated to the relocated site</p>
<hr />
<div>'''Getting started tutorial''' <br />
<br />
This page provides a getting started guide for writing macros in OpenOffice.org Basic. It assumes some prior programming knowledge. Please edit this page to make it more readable. I hope you will find it useful.<br />
<br />
If you already know the basics then you may want the [[CookBook]] for wrappers and examples.<br />
<br />
<br />
==Where do I write the code?==<br />
OpenOffice.org Basic code is stored in modules within libraries. A library can be: <br />
<br />
*Shared (for a network install - OOo Macros & Dialogs) <br />
*Just for the current user (My Macros & Dialogs) <br />
*Within a document or template, so that its code is only available when that document is open.<br />
<br />
Libraries stored in a document can easily be copied, transported and distributed with the document.<br />
<br />
Libraries not stored in a document or template (that is libraries that are shared or for the current user) are referred to as '''OpenOffice.org libraries'''. <br />
<br />
To determine the actual folders that contain the OpenOffice.org libraries see:<br> '''Tools > Options… > OpenOffice.org > Paths > BASIC'''. <br />
<br />
{| border="1"<br />
|'''Note'''<br />
|Do not copy or move libraries using operating system commands. Use the macro organizer or package manager instead.<br />
|-<br />
|}<br />
<br />
<br />
Modules within libraries have a maximum size of 64kb. A library can contain up to 16,000 modules. <br />
<br />
For more information see online help for: Modules and Libraries.<br />
<br />
==Accessing the IDE==<br />
To access the IDE for the first time: <br />
<br />
OpenOffice.org 1.1.x: '''Tools > Macros > Macro… >''' <br />
<br />
OpenOffice.org 1.9.x and above: '''Tools > Macros > Organize macros > OpenOffice.org Basic… >''' <br />
<br />
To get started we will use Module1 in the Standard library which is stored for the current user only: <br />
<br />
Type a name for the new macro: '''HelloWorld''' <br />
<br />
In the macro from listbox select '''Standard''' <br />
<br />
Click '''New''' <br />
<br />
You should now see something like: <br />
<br />
<source lang="oobas"><br />
REM ***** BASIC *****<br />
<br />
Sub Main<br />
<br />
End Sub<br />
<br />
Sub HelloWorld<br />
<br />
End Sub<br />
</source><br />
The cursor will be positioned at the start of the <tt>Sub HelloWorld</tt> line. <br />
<br />
{| border="1"<br />
|'''Note'''<br />
|Now that while the IDE is running it can be accessed from the OpenOffice.org Window menu, or the task panel provided by the operating system.<br />
|-<br />
|}<br />
<br />
==Entering the code==<br />
Select and delete: <br />
<br />
<source lang="oobas"><br />
REM ***** BASIC *****<br />
<br />
Sub Main<br />
<br />
End Sub<br />
</source><br />
Below the line "Sub HelloWorld" type <tt>msgbox "Hello World!"</tt>, so that the editor looks like: <br />
<br />
<source lang="oobas"><br />
Sub HelloWorld<br />
msgbox "Hello World!"<br />
End Sub<br />
</source><br />
{| border="1"<br />
|'''Notes:'''<br />
|The IDE does not provide code completion or help with command syntax as you type, but to get help on a Basic command position the cursor in the command and press F1.<br> OpenOffice.org Basic commands are not case sensitive. Thus msgbox, MSGBOX and Msgbox will all work.<br> Strings are enclosed in double quotes.<br />
|-<br />
|}<br />
<br />
==Running the code==<br />
There are several ways of running the Basic code, these include: <br />
<br />
*Directly from the IDE. There is a run button on the macro bar (by default the third control on the second toolbar). This will run the first macro in the current module. <br />
<br />
*From the tools menu:<br />
<br />
**(Version 1.1.x) '''Tools > Macros > Macro…''';<br />
<br />
**(Version 1.9.x and above) '''Tools > Macro > Run Macro…''' <br />
<br />
*Assigning the macro to a [[ key press]]. <br />
<br />
*Assigning the macro to a [[ menu entry]]. <br />
<br />
*Assigning the macro to a toolbar button. <br />
<br />
*Creating a [[ control in a document]]. <br />
<br />
*Assigning the macro to an event. <br />
<br />
For now try running the "HelloWorld" subroutine by clicking the '''Run''' button. A small dialog titled "soffice" with the text "Hello World!" and an OK button should be displayed.<br />
<br />
==Saving the code==<br />
The code gets automatically saved whenever the container for the code gets saved. Thus, if the code is in an OpenOffice.org library (shared or users) then it gets automatically saved when OpenOffice.org exits. If the code is in a library which is part of a document it gets saved whenever the document is saved. <br />
<br />
On the Standard toolbar (by default the top toolbar) in the IDE there is a save button. If the code is in a document or template then clicking this button saves the entire document or template. If the code is in an OpenOffice.org library then just the current library gets saved. <br />
<br />
<br />
==Variables==<br />
It is possible to force variable declaration with <tt>Option Explicit</tt> at the top of the module. For a discussion on whether to declare variables or not, see: [[http://www.oooforum.org/forum/viewtopic.phtml?t=5845 this discussion]]. <br />
<br />
In that discussion the initial author of this wiki thought that variables should always be declared. Since then he has changed to not declaring them. In short it is generally a personal preference. In either case, it is the initial authors preference that variables be named according to the following convention, which is used in the examples in this Wiki: <br />
<br />
The first letter of the variable name indicates the type of value that the variable is going to hold, as per the following table (based on a table in Tutorial.pdf by Sun) <br />
<br />
{| border="1"<br />
|'''''Letter'''''<br />
|'''''Meaning'''''<br />
|-<br />
|a<br />
|Structure<br />
|-<br />
|b<br />
|Boolean (TRUE or FALSE)<br />
|-<br />
|e<br />
|Enumeration. This variable can only have one of a limited set of values.<br />
|-<br />
|f<br />
|Float (3.402823 x 1038 to 1.401298 x 10-45. A single variable can take up to four bytes)<br> Double (1.79769313486232 x 10308 to 4.94065645841247 x 10-324. A double variable can take up to eight bytes)<br> Currency (-922337203685477.5808 to +922337203685477.5807 and takes up to eight bytes of memory)<br />
|-<br />
|m<br />
|Array (aka sequence aka matrix)<br />
|-<br />
|n<br />
|Integer (-32768 to 32767.) or<br> Long (-2147483648 and 2147483647).<br />
|-<br />
|o<br />
|Object, service, or interface<br />
|-<br />
|s<br />
|String (A string variable can store up to 65535 Unicode characters).<br />
|-<br />
|x<br />
|Interface, to indicate that only operations of a particular interface of an object are used<br />
|-<br />
|v<br />
|Variant, Any<br />
|-<br />
|}<br />
<br />
<br />
Use long descriptive variable names making use of camel case: <tt>nMsgBoxReturn</tt><br />
<br />
{| border="1"<br />
|'''Note:'''<br />
|User-defined OpenOffice.org Basic variables are not case sensitive. But UNO-API constants ''are'' case sensitive.<br />
|}<br />
<br />
<br />
Convention exceptions to long descriptive names are for index variables where <tt>i, j,</tt> and <tt>k</tt> are commonly used, and for when a string is being built-up, where <tt>s</tt> is commonly used. <br />
<br />
Edit sub HelloWorld so that it looks like the following and run it: <br />
<br />
<source lang="oobas"><br />
sub HelloWorld<br />
dim i as integer 'This line is optional<br />
for i = 0 to 2<br />
'These lines are indented for ease of reading only.<br />
'All your code should be like this for long-term survival.<br />
msgbox "Hello World " & i<br />
next i<br />
end sub<br />
</source><br />
For more information on variables see the online help for "using variables".<br />
<br />
==Understanding the OpenOffice.org API==<br />
This section will start with an example. The remainder of this section aims to give information so that the example can be understood and expanded upon. <br />
<br />
Try running the following code with different types of documents being active. <br />
<br />
<source lang="oobas"><br />
sub main<br />
'BasicLibraries.loadLibrary("XrayTool")<br />
'xray thisComponent<br />
msgbox fnWhichComponent(thisComponent)<br />
end sub<br />
<br />
<br />
function fnWhichComponent(oDoc) as string<br />
if HasUnoInterfaces(oDoc, "com.sun.star.lang.XServiceInfo") then <br />
if oDoc.supportsService ("com.sun.star.text.GenericTextDocument") then<br />
fnWhichComponent = "Text"<br />
elseif oDoc.supportsService("com.sun.star.sheet.SpreadsheetDocument") then<br />
fnWhichComponent = "Spreadsheet"<br />
elseif oDoc.supportsService("com.sun.star.presentation.PresentationDocument") then<br />
fnWhichComponent = "Presentation"<br />
elseif oDoc.supportsService("com.sun.star.drawing.GenericDrawingDocument") then<br />
fnWhichComponent = "Drawing"<br />
else<br />
fnWhichComponent = "Oops current document something else"<br />
end if<br />
else<br />
fnWhichComponent = "Not a document"<br />
end if<br />
End function<br />
</source><br />
<br />
===Subroutine naming convention===<br />
In the above example the user defined function has a name that starts with the letters "fn". This is the initial author's convention so that people know that this is a user defined function. Similarly, the initial author uses the convention that user defined subroutines start with the letters "sub". When learning a language and an API it can be difficult to know what is built-in and what has been defined elsewhere. This document/wiki will use this convention for naming functions and subroutines.<br />
<br />
===Introducing the OpenOffice.org API===<br />
This section introduces the following terms: <br />
<br />
* Interface <br />
* Module <br />
* Service <br />
* Method <br />
* Property <br />
<br />
Understanding the difference between an interface and a service and what a module is, is not essential to being able to write extensions for OpenOffice.org, but it does help interpreting the documentation, and for introspection purposes. You may need to read this section at least twice. <br />
<br />
An '''interface''' is a ''definition'' of a set of methods (and their arguments) that a service which implements that interface must have. <br />
<br />
Interfaces are grouped together in '''modules''' for naming purposes. All interfaces (and services) start with the name "com.sun.star" then the name of the module then the name of the interface (or service). <br />
<br />
For example most services provide the com.sun.star.beans.XPropertySet interface. This interface is stored in the module "beans" and provides access to the properties of a service. A '''property''' is a value whereas a '''method''' is an action. <br />
<br />
An OpenOffice.org object can have many services. <br />
<br />
An OpenOffice.org object may have a service, which implements an interface, in which a method description says that another OpenOffice.org object is returned.<br />
<br />
===Introspection===<br />
<tt>HasUnoInterfaces</tt> is an OpenOffice.org Basic function for introspection. See this [[http://www.oooforum.org/forum/viewtopic.phtml?t=7068 link]] for information on introspection in other languages. <br />
<br />
<tt>HasUnoInterfaces</tt> returns true if all of the specified interfaces are available for the specified object. <br />
<br />
Most OpenOffice.org objects provide the method <tt>supportsService</tt> because they have the interface <idl>com.sun.star.lang.XServiceInfo</idl>. <br />
<br />
In the above example, the OpenOffice.org Basic command <tt>HasUnoInterfaces</tt> checks that the current document has the interface <idl>com.sun.star.lang.XServiceInfo</idl>, because if it doesn't have that interface then it doesn't have the method <tt>supportsService</tt>, and a run time error would occur if such an object tried to access its nonexistent method. <br />
<br />
<tt>SupportsService</tt> is a method which returns true if the specified service is available. The above examples checks for a service to determine the type of document that is currently active.<br />
<br />
<br />
===Xray tool===<br />
Using <tt>HasUnoInterfaces</tt> and <tt>supportsService</tt> gives information about an object at run time, but checking an object like this would be a nightmare for learning? Thankfully, Bernard Marcelly has come to our rescue with the Xray tool. The Xray tool is available from: [[http://berma.pagesperso-orange.fr/Files_en/XrayTool60_en.odt odt installer(en)]]. Download the odt file, open the document in OpenOffice.org, follow the instructions for installation and set-up. <br />
<br />
Part of the Xray tool set-up is to specify a local copy of the OpenOffice.org SDK. Download the [http://www.openoffice.org/download/other.html#tested-sdk Apache OpenOffice 3.4 SDK] and extract it. <br />
<br />
In the above example, at the start of the code, there are two commented lines (comments start with an apostrophe): <br />
<br />
<source lang="oobas"><br />
'BasicLibraries.loadLibrary("XrayTool")<br />
'xray thisComponent<br />
</source><br />
Now that you have the Xray tool installed, uncomment these lines (remove the apostrophes) and rerun the macro.<br />
<br />
[[image:Xray60en.png]]<br />
<br />
'''BasicLibraries''' is an OpenOffice.org Basic command that returns an object for accessing the OpenOffice.org libraries. The <tt>loadLibrary</tt> method ensures that the routines in that library are available for use. <br />
<br />
<tt>xray</tt> specifies the <tt>xray</tt> subroutine within the library <tt>XrayTool</tt>. <tt>thisComponent</tt> is the object that is being passed to <tt>xray</tt> for introspection. <br />
<br />
To find the object that you want to work with often requires finding or creating it starting from either <tt>StarDesktop</tt> or <tt>thisComponent</tt>.<br />
<br />
===Desktop, documents, and current selection===<br />
<tt>StarDesktop</tt> and <tt>thisComponent</tt> are OpenOffice.org Basic commands that refer to the application and currently active document respectively. <br />
<br />
Unlike Microsoft Office, OpenOffice.org is one application with different components. When running some code it maybe useful to check which component is currently active. The above code demonstrates how that checking process can be done. <br />
<br />
The Desktop that <tt>StarDesktop</tt> refers to is conceptual (historically it actually existed) and can be thought of as the OpenOffice.org application.<br />
<br />
==Creating new documents==<br />
To create a new text document: <br />
<br />
<source lang="oobas"><br />
oDoc = StarDesktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, Array())<br />
</source><br />
To create a new spreadsheet document: <br />
<br />
<source lang="oobas"><br />
oDoc = StarDesktop.loadComponentFromURL("private:factory/scalc", "_blank", 0, Array())<br />
</source><br />
An easier approach would be to write a simple function: <br />
<source lang="oobas"><br />
function fnNewDoc(sDocType as string)<br />
fnNewDoc = StarDesktop.loadComponentFromURL("private:factory/" & sDocType , "_blank", 0, Array())<br />
end function<br />
</source><br />
Then creating new documents can be achieved with: <br />
<br />
<source lang="oobas"><br />
oDoc = fnNewDoc("swriter")<br />
oDoc = fnNewDoc("scalc")<br />
oDoc = fnNewDoc("simpress")<br />
oDoc = fnNewDoc("sdraw")<br />
oDoc = fnNewDoc("smath")<br />
</source><br />
See http://api.openoffice.org/docs/common/ref/com/sun/star/frame/XComponentLoader.html .<br />
<br />
==To open a document==<br />
The following example shows how to open a file. For information on URLs in OpenOffice.org see [[ URL Basics]]. <br />
<br />
<source lang="oobas"><br />
sFile = "C:\Documents and Settings\danny\Desktop\MyCalc.sxc" ' Windows<br />
sFile = "/home/danny/Desktop/MyCalc.sxc" ' Linux<br />
sURL = ConvertToURL(sFile)<br />
oDoc = StarDesktop.loadComponentFromURL(sURL, "_blank", 0, Array())<br />
</source><br />
Again it may make sense to make this easier by writing a simple function: <br />
<br />
<source lang="oobas"><br />
function fnOpenDoc(sFile)<br />
sURL = ConvertToURL(sFile)<br />
fnOpenDoc = StarDesktop.loadComponentFromURL(sURL, "_blank", 0, Array())<br />
end function<br />
</source><br />
Examples of calling the function: <br />
<br />
<source lang="oobas"><br />
oDoc = fnOpenDoc("C:\Documents and Settings\danny\Desktop\MyCalc.sxc") ' Windows<br />
oDoc = fnOpenDoc("/home/danny/Desktop/MyCalc.sxc") ' Linux<br />
</source><br />
<br />
==Opening a new file from a template==<br />
If you want to open a file using an existing template, use the template name instead of the file name. An untitled document will be opened from the template. <br />
<br />
Alternatively, set the "AsTemplate" property in the MediaDescriptor for the opened template to TRUE, and a new file will be opened based on the template, even if the template was stored by OO as an ordinary file, rather than a template. [[Opening a document]] has some examples.<br />
<br />
If the template location is known, simply use it. However, OpenOffice keeps at least two sets of templates: global templates available to all users and "My Templates" available to the current user, and the locations of the directories are not obviously available. They can be found by means of the [http://www.openoffice.org/api/docs/common/ref/com/sun/star/util/PathSettings.html PathSettings service] which allows the user to examine the various directory paths known to OpenOffice. The Template property of this service returns a string which is a semi-colon separated list of URLS, each of which represents a possible location for the desired template. It is necessary to search this string and the resulting directories to find the template. The following code finds a user template and opens a document based on it:<br />
<br />
<source lang="oobas"><br />
Dim PathService as Object<br />
Dim TemplatePath as String ' The path list<br />
Dim SCPos as Integer ' The position of the next semi-colon <br />
Dim MyTemplatePath as String ' The URL for the user template<br />
<br />
' substitute your template name here<br />
const TemplateName = "MyTemplate.ott"<br />
<br />
' This seems to be the place in which OO stores user templates<br />
const UserTemplateDirectory="/user/template"<br />
<br />
<br />
PathService=CreateUNOService("com.sun.star.util.PathSettings")<br />
TemplatePath=PathService.Template<br />
MyTemplatePath=""<br />
<br />
do while len(TemplatePath) >0<br />
SCPos=InStr (TemplatePath,";")<br />
if SCPos>0 then<br />
MyTemplatePath=Left(TemplatePath, SCPos-1)<br />
else<br />
MyTemplatePath=TemplatePath<br />
end if<br />
<br />
' NOTE: as well as file URLs there are some others which should be ignored<br />
if InStr(myTemplatePath,"file:///")=1 And _<br />
Right(myTemplatePath,14) = UserTemplateDirectory then<br />
exit do <br />
end if<br />
TemplatePath=mid(TemplatePath, SCPos+1, len(TemplatePath)-SCPos)<br />
MyTemplatePath="" <br />
loop<br />
<br />
if MyTemplatePath<>"" then<br />
TemplatePath=ConverttoURL(TemplateName)<br />
MyTemplatePath=MyTemplatePath & "/" & TemplateName<br />
InvoiceDoc=StarDesktop.LoadComponentfromURL(MytemplatePath, "_blank", 0, Array())<br />
else<br />
MsgBox "Cannot find the template directory"<br />
end if<br />
</source><br />
<br />
This code does not check that the desired template actually exists; if it doesn't, the LoadComponentfromURL call will fail.<br />
<br />
==Current Selection==<br />
It is common to want to run some code that affects the current selection. <tt>ThisComponent</tt> has the method <tt>getCurrentSelection</tt>. Since many different types of objects could possibly be selected it is common to check that the currently selected object has the service that contains the method that we want to apply to the object. <br />
<br />
Edit the main subroutine to the following and rerun it on a text document with different selections. (To select more than one block of text hold down the control key). <br />
<br />
<source lang="oobas"><br />
sub main<br />
BasicLibraries.loadLibrary("XrayTool")<br />
if fnWhichComponent(thisComponent) = "Text" then<br />
oCurSelection = thisComponent.getCurrentSelection()<br />
'xray oCurSelection<br />
if oCurSelection.supportsService("com.sun.star.text.TextRanges") then<br />
msgbox "There are " & oCurSelection.getCount() & _<br />
" selections in the current text document."<br />
end if<br />
end if<br />
end sub<br />
</source><br />
With nothing selected the number of selections is one - the insertion point, with one block of text selected the count is still one, but with two blocks of text the count is three - the insertion point and the two blocks of selected text. <br />
<br />
Exercise 1: Modify the above code so that it works on selected cell ranges in a spreadsheet. <br />
<br />
Question1: For two blocks of cells selected, what would be the count for the number of selections?<br />
<br />
==Properties==<br />
Uncomment <tt>'xray oCurSelection</tt> so that xray runs, to see that the object that <tt>oCurSelection</tt> points to has a "property" called <tt>Count</tt> with a description of "pseudo-prop, read only". It is possible in OpenOffice.org Basic to write <tt>oCurSelection.count</tt>, but as this is not possible in all other languages accessing the OpenOffice.org API, this Wiki will try to always use the method approach. (I say try because I have not been in the habit of doing this and sometimes I may forget). <br />
<br />
This next example demonstrates changing a property value for the current selections. <br />
<br />
<source lang="oobas"><br />
sub main<br />
BasicLibraries.loadLibrary("XrayTool")<br />
if fnWhichComponent(thisComponent) = "Text" then<br />
oCurSelection = thisComponent.getCurrentSelection()<br />
if oCurSelection.supportsService("com.sun.star.text.TextRanges") then<br />
nCount = oCurSelection.Count<br />
'xray oCurSelection.getByIndex(0)<br />
'Warning: The insertion point will have the same action applied twice<br />
'in this case it doesn't matter, but in others it might.<br />
for i = 0 to nCount - 1<br />
oCurSelection.getByIndex(i).setPropertyValue("CharStyleName", "Strong Emphasis")<br />
next<br />
end if<br />
end if<br />
end sub<br />
</source><br />
In OpenOffice.org Basic it is possible to shorten the assignment line to: <br />
<br />
<source lang="oobas"><br />
oCurSelection(i).CharStyleName = "Strong Emphasis"<br />
</source><br />
This wiki will try to use the full methods for both indexing and assigning properties. The rationale is that this makes converting the code to other languages easier and also helps the learner to understand what is happening (again I have not been in the habit of doing this so some examples may slip past me). <br />
<br />
Exercise 2: Rewrite the above code so that the warning can be removed. <br />
<br />
See [[ Current selection]].<br />
<br />
==Iterative Access to Subordinate Objects (Enumeration access)==<br />
Sometimes to access the desired object an enumeration is required. For example paragraphs, within a document or within a selection. <br />
<br />
When a Writer document is active and some text is selected, both <tt>thisDocument.getText()</tt> and <tt>thisComponent.getCurrentSelection().getByIndex(i)</tt> have the service: <idl>com.sun.star.text.TextRange</idl>, which has the interface: <idl>com.sun.star.container.XContentEnumerationAccess</idl>. It is possible to create an enumeration of the paragraphs for the current document or for a particular selection. <br />
<br />
<source lang="oobas"><br />
' Create enumeration object<br />
oTextElementEnum = thisComponent.getText().createEnumeration()<br />
'or thisComponent.getCurrentSelection().getByIndex(i).createEnumeration()<br />
<br />
' loop over all text elements<br />
while oTextElementEnum.hasMoreElements()<br />
oTextElement = oTextElementEnum.nextElement<br />
if oTextElement.supportsService("com.sun.star.text.TextTable") then<br />
MsgBox "The current block contains a table."<br />
end if<br />
if oTextElement.supportsService("com.sun.star.text.Paragraph") then<br />
MsgBox "The current block contains a paragraph."<br />
end if<br />
wend<br />
</source><br />
Exercise 3: Extend the above example to display in a message box all text portions that are bold.<br />
<br />
==Named access==<br />
Some objects provide named access to a particular type of subordinate object, some others indexed access, and some both named and indexed access. <br />
<br />
For example if the current document in OpenOffice.org is a spreadsheet then to access a particular sheet can be done by index access: <br />
<br />
<source lang="oobas"><br />
oSheet = thisComponent.getSheets.getByIndex(0)<br />
</source><br />
or named access: <br />
<br />
<source lang="oobas"><br />
oSheet = thisComponent.getSheets.getByName("Sheet1")<br />
</source><br />
To check if an object with a particular name already exists use <tt>hasByName</tt>, for example: <br />
<br />
<source lang="oobas"><br />
if thisComponent.getSheets.hasByName("Sheet1") then<br />
</source><br />
To loop through all the available object names can be done like: <br />
<br />
<source lang="oobas"><br />
mNames = thisComponent.getSheets.getElementnames<br />
for i = lbound(mNames) to ubound(mNames)<br />
msgbox mNames(i)<br />
next<br />
</source><br />
<br />
<br />
Some named subordinate objects also provide the interface: <idl>com.sun.star.container.XNameContainer</idl>. This interface defines that such objects should have the following methods: <tt>insertByName</tt>, <tt>insertNewByName</tt>, <tt>replaceByname</tt> and <tt>removeByName</tt>. <br />
<br />
E.g. <br />
<br />
<source lang="oobas"><br />
thisComponent.getSheets.insertNewByName("NewSheet", 0)<br />
</source><br />
<br />
==Create new objects==<br />
Some objects have services which implement interfaces to provide specific methods for creating a particular type of object. <br />
<br />
For example if the current document is a Writer document then <tt>thisComponent.getText</tt> is an object that provides the service <idl>com.sun.star.text.Text</idl>, which implements the interface <idl>com.sun.star.text.XSimpleText</idl>, which defines the methods <tt>createTextCursor</tt> and <tt>createTextCursorByRange</tt>. Both of these methods create a text cursor for accessing the text of the document. These cursors are quite independent of the view cursor. The view cursor is visible on the screen and is manipulated by the user (and can be manipulated by program control), whereas a text cursor is not visible on the screen and is solely used by program control. The following code snippet demonstrates creating a new text cursor, such that it starts at the same location as the view cursor and is then moved independent of the view cursor. <br />
<br />
<source lang="oobas"><br />
oVC = thisComponent.getCurrentController.getViewCursor<br />
oCursor = oVC.getText.createTextCursorByRange(oVC)<br />
oCursor.gotoStartOfSentence(false)<br />
oCursor.gotoEndOfSentence(true)<br />
msgbox oCursor.getString<br />
</source><br />
The string returned by the <tt>oCursor.getString</tt> method is the text of the sentence in which the view cursor currently resides.<br />
<br />
Some objects are context dependent and get created using the method <tt>createInstance</tt> which is defined in the interface <idl>com.sun.star.lang.XMultiServiceFactory</idl>. For example to add a rectangle to the first page of a drawing document: <br />
<br />
<source lang="oobas"><br />
dim aPoint as new com.sun.star.awt.Point<br />
dim aSize as new com.sun.star.awt.Size<br />
<br />
aPoint.x = 1000<br />
aPoint.y = 1000<br />
<br />
aSize.Width = 10000<br />
aSize.Height = 10000<br />
<br />
oRectangleShape = thisComponent.createInstance("com.sun.star.drawing.RectangleShape")<br />
oRectangleShape.Size = aSize<br />
oRectangleShape.Position = aPoint<br />
<br />
thisComponent.getDrawPages.getByIndex(0).add(oRectangleShape)<br />
</source><br />
<br />
This example also uses ''UNO structs''. See below for more information on UNO structs. <br />
<br />
Some objects are context independent; to create these objects, use the OpenOffice.org Basic command <tt>createUnoService</tt>. For example, to create the equivalent to <tt>StarDesktop</tt>: <br />
<br />
<source lang="oobas"><br />
oDesktop = createUnoService("com.sun.star.frame.Desktop")<br />
</source><br />
<br />
The process that I use to determine how to access or create an object is as follows: <br />
<br />
Does the object already exist, if so I should be able to access it from something like <tt>thisComponent</tt>. <br />
<br />
Will the new object belong to another object, if so does the owner have a specific method for creating the object, if so use it. <br />
<br />
The new object will belong to another object, but that object doesn't provide a specific method for creating it, but does provide <tt>createInstance</tt>. If the object doesn't provide <tt>createInstance</tt> are you sure you are using the correct object, or is it context independent. <br />
<br />
I have found working out how to create an object to be quite difficult with existing documentation so I hope that this document/wiki will eventually make this clear. <br />
<br />
<br />
===UNO structs===<br />
UNO structures can be declared using the OpenOffice.org Basic command <tt>dim as new</tt>: <br />
<br />
<source lang="oobas"><br />
dim aPoint as new com.sun.star.awt.Point<br />
</source><br />
Or by using the OpenOffice.org Basic command <tt>createUnoStruct</tt>: <br />
<br />
<source lang="oobas"><br />
aPoint = createUnoStruct("com.sun.star.awt.Point")<br />
</source><br />
<br />
{| border="1"<br />
|'''Note:'''<br />
|When declaring UNO structs, case is important. Note that everything up to the name of the struct is lowercase, and that the name of the struct is in TitleCase.<br />
|}<br />
<br />
<br />
<br />
<br />
===Creating Listeners and Handlers===<br />
Through the user interface it is possible to assign macros to some events: <br />
<br />
OpenOffice.org versions 1.1.x: '''Tools > Configure… > Events'''. <br />
<br />
OpenOffice.org versions 1.9.x and above: '''Tools > Customize… > Events'''. <br />
<br />
It is also possible to assign macros to a wider range of events using the OpenOffice.org Basic command <tt>CreateUnoListener</tt>. This same command is used for creating both listeners and handlers. A listener checks for an event and always allows other listeners to respond to the event as well. A handler listens for an event, and can optionally consume the event so that other listeners don't get to act on it. <br />
<br />
The following example creates a keyHandler: <br />
<br />
<source lang="oobas"><br />
global IannzExampleKeyHandler<br />
<br />
sub SetupKeyHandler<br />
oController = thisComponent.currentController<br />
IannzExampleKeyHandler = CreateUnoListener("KeyHandler_","com.sun.star.awt.XKeyHandler")<br />
oController.addKeyHandler(IannzExampleKeyHandler) ' Register the listener<br />
end sub<br />
<br />
sub RemoveKeyHandler<br />
thisComponent.currentController.removeKeyHandler(IannzExampleKeyHandler)<br />
end sub<br />
<br />
sub KeyHandler_disposing<br />
end sub<br />
<br />
function KeyHandler_keyReleased(oKeyEvent as new com.sun.star.awt.KeyHandler) as boolean<br />
KeyHandler_keyReleased = False <br />
end function<br />
<br />
function KeyHandler_keyPressed(oKeyEvent as new com.sun.star.awt.KeyHandler) as boolean<br />
KeyHandler_keyPressed = false 'Let other listeners handle the event<br />
if oKeyEvent.modifiers = com.sun.star.awt.KeyModifier.MOD2 then 'Control key was pressed<br />
if oKeyEvent.keyCode = com.sun.star.awt.Key.Q then<br />
msgbox "Alt + Q was pressed"<br />
KeyHandler_keyPressed = true 'Don't let other listeners process this event<br />
end if<br />
end if<br />
end function<br />
</source><br />
A variable declared as global keeps its value even after the macro exits. In this case we want to be able to use this variable later to remove the handler. As variables declared globally could be used in other libraries, to try and avoid conflict I start all my global variables with Iannz my registered name for the OpenOffice.org web site. <br />
<br />
<tt>sub SetupKeyHandler</tt> sets up the handler. The first parameter to <tt>CreateUnoListener</tt> is the starting name for the methods that will be called when that type of event occurs: in this example, <tt>"KeyHandler_"</tt>. <br />
<br />
The second parameter is the name of the interface for the listener or handler, "<idl>com.sun.star.awt.XKeyHandler</idl>". The name is case sensitive, everything up to and including the module name is always lowercase, the name of the interface always starts with "X" and the remainder is in TitleCase. <br />
<br />
Use the SDK to find out what methods the interface must supply. You must supply routines for all of these methods even if you don't intend to use them. You also need to supply a disposing method. The names of these routines start with the string given in the first parameter to <tt>CreateUnoListener</tt>, in this example <tt>"KeyHandler_"</tt>. <br />
<br />
Thus in the example there is <tt>KeyHandler_disposing</tt> and <tt>KeyHandler_keyReleased</tt> which don't actually do anything but are required, and <tt>KeyHandler_keyPressed</tt> which actually does the job. <br />
<br />
<tt>sub RemoveKeyHandler</tt> demonstrates how to remove the handler.<br />
<br />
==OpenOffice.org constants==<br />
The above example uses OpenOffice.org constants. <br />
<br />
E.g. <tt>com.sun.star.awt.KeyModifier.MOD2</tt><br />
<br />
OpenOffice.org constants are case sensitive. Everything up to and including the module name is always lowercase. The constant group is in TitleCase. The actual constant name is always UPPERCASE. <br />
<br />
Programmers not using OpenOffice.org Basic may not have access to these constants. <br />
<br />
<br />
==Using the recorder==<br />
See [[ The OpenOffice.org recorder and UNO dispatch calls]] section for a discussion on recording UNO Dispatch commands versus writing API calls.<br />
<br />
== See also==<br />
* [[CookBook|CookBook]]<br />
* [[Text_cursor|Text Cursor in OOoBasic]]<br />
* [[Framework/Article/Easy_To_Use_Message_Boxes|Easy To Use Message Boxes]]<br />
* [[Programming_OooWriter |Programming OOoWriter in C++]] where OOoBasic records are used in C++<br />
* A [[XIntrospection_Interface|XIntrospection Interface]] short description. XRay uses this interface.<br />
* Download Bernard Marcelly's [http://bernard.marcelly.perso.sfr.fr/Files_en/XrayTool60_en.odt XRay OOoBasic tool] <br />
* See [[Object Inspector|The New Object Inspector]] and [[BASIC/UNO_Object_Browser|The BASIC UNO Object Browser]]<br />
<br />
[[Category:Extensions]]<br />
[[Category:StarBasic]]<br />
[[Category:Documentation/Candidate]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Extensions_PackagerExtensions Packager2016-05-01T05:47:21Z<p>BMarcelly: /* Download */ Changed link addresses to my relocated personal site</p>
<hr />
<div>{{DISPLAYTITLE:Extensions Packagers}}<br />
<br />
= BasicAddonBuilder =<br />
<br />
BasicAddonBuilder is an OpenOffice.org extension that allow you to<br />
export a StarBasic library in the OpenOffice.org extension format, <br />
ready for deployment.<br />
BasicAddonBuilder does not require special skills or a deep knowledge <br />
of extensions specifications.<br />
A wizard-style dialog will guide you through the process, allowing<br />
you to define in a graphical way all menu and toolbars that will be <br />
added to the OpenOffice.org user interface in order to launch macros <br />
from your StarBasic library.<br />
<br />
[[image:BasicAddonBuilder.png|BasicAddonBuilder|frame|right|200px]]<br />
<br />
The exported extension (AKA UNO package) will be ready to install in<br />
any PC running OpenOffice.org 2.0 or above, using the Package manager.<br />
(Menu Tools->Package manager...)<br />
<br />
== Requirements ==<br />
In order to use BasicAddonBuilder, you must have OpenOffice.org 2.2 or above<br />
installed. <br />
BasicAddonBuilder will not work with OpenOffice.org 1.x <br />
<br />
== Install ==<br />
BasicAddonBuilder is [http://www.paolo-mantovani.org/downloads/BasicAddonBuilder/ downloadable at this location] and can be installed with the Extension manager.<br />
* Menu Tools->Extension manager...<br />
Further information in the OpenOffice.org Help<br />
<br />
== Known issues ==<br />
* Missing documentation<br />
The following features are not yet supported:<br />
* Dependances management of the generated extension<br />
* Import/export of BasicAddonBuilder projects<br />
<br />
== Homepage ==<br />
Current versions of BasicAddonBuilder for OpenOffice.org are always available [http://www.paolo-mantovani.org/downloads/BasicAddonBuilder/ here:]<br />
<br />
== Contacting author ==<br />
Please send your suggestions and bug reports to: [mailto:paolomantovani@openoffice.org Paolo Mantovani]<br />
Any feedback is welcome!<br />
<br />
= BasicAddonBuilder and AOO 4.x =<br />
<br />
From AOO 4.0 has the configuration file addons.xcu a modified structure for toolbars, see:<br />
http://wiki.openoffice.org/wiki/Extensions/Extensions_and_Apache_OpenOffice_4.0#addons.xcu_changes<br />
<br />
Therefore an update for BasicAddonBuilder is necessary because:<br />
* own toolbar of the BasicAddonBuilder 0.5.0 (and earlier releases) is not displayed in AOO 4.0 (and later versions)<br />
* BasicAddonBuilder 0.5.0 (and earlier releases) can not create extensions, which include toolbars that can be displayed in AOO 4.0 (and later versions)<br />
<br />
I wrote Paolo Mantovani, and Paolo replied me that he currently does not have time to create a new version of BasicAddonBuilder. Therefore, I ([mailto:joesch@calc-info.de Jörg Schmidt]) have now created a new Version (0.5.1).<br />
<br />
== BasicAddonBuilder 0.5.1 (Beta) ==<br />
At the moment there are (initially for testing purposes) two different versions of BasicAddonBuilder 0.5.1<br />
<br />
http://calc-info.de/files/BasicAddonBuilder-0.5.1.oxt (compatible with AOO 4.x)<br/><br />
http://calc-info.de/files/BasicAddonBuilder-oo3x-0.5.1.oxt (compatible up to AOO 3.4.1 and LibreOffice<sup>'''(*)'''</sup>)<br />
<br />
Both versions can produce compatible extensions for all versions of OOo, AOO and LO<sup>'''(*)'''</sup>.<br />
<br />
<sup>'''(*)'''</sup> ''not specifically tested''<br />
<br /><br /><br />
<br />
'''Requirements / Install'''<br /><br />
In order to use BasicAddonBuilder 0.5.1, you must have OpenOffice.org (2.2 or above) or LibreOffice installed.<br />
Please note that for AOO up to version 3.4.1 and LO another installation file must be used, as for AOO 4.x.<br /><br />
BasicAddonBuilder can be installed with the Extension manager (Menu Tools->Extension manager...). <br /><br /><br />
<br />
'''Questions and bug reports'''<br /><br />
<br />
Please send an email to [mailto:joesch@calc-info.de Jörg Schmidt]<br />
<br />
<br /><br /><br />
<br />
The following figures show the additional functions of BasicAddonBuilder 0.5.1<br />
* adjustable compatibility for toolbars in the created extension<br />
* embed the publisher in the created extension (in the file description.xml)<br /><br />
<br />
[[image:bab051go.png|General Options]]<br /><br /><br />
<br />
[[image:Bab051lav.png|Licence and Version]]<br />
<br />
<br /><br />
<br />
== BasicAddonBuilder 0.5.2 ==<br />
<br />
I got by Derby Russell, a new corrected version. Thank you.<br />
<br />
[mailto:joesch@calc-info.de Jörg Schmidt]<br />
<br />
<br /><br /><br />
<br />
The new version Basic Addon Builder 0.5.2 is available for download here: <br />
<br />
http://calc-info.de/files/BasicAddonBuilder-0.5.2.oxt<br />
<br />
(Note: this version is for Apache OpenOffice version 4.0 and higher)<br />
<br />
<br /><br /><br />
<br />
'''Additional Information (09/01/2016):'''<br />
<br />
I got the message that the foregoing version ("Basic Addon Builder 0.5.2.oxt") does not install any toolbar in the use under LibreOffice, therefore additionally here a 0.5.2-version for use with LibreOffice:<br />
<br />
http://calc-info.de/files/BasicAddonBuilder_LibreOffice_0.5.2.oxt<br />
<br />
<br />
The corrections are as follows:<br />
(Changes made by Derby Russell for 0.5.2)<br />
In the PkgExporter module:<br />
<br />
* the line 74 was changed from: sTempDirUrl = GetTempFile() & "/" to sTempDirUrl = GetTempFile()<br />
* line 75 was added: sTempDirUrl = EnsureFolderNameIsLongType(sTempDirUrl)<br />
* line 76 was added: sTempDirUrl = sTempDirUrl & "/"<br />
* at line 597 a new function: pmxInStrRev was added<br />
* at line 639 a new function: SplitFolderPath was added<br />
* at line 652 a new function: SplitFolderName was added<br />
* at line 664 a new function: SplitFolderNamePath was added<br />
* at line 690 a new function: EnsureFolderNameIsLongType was added<br />
<br />
= Extension Compiler =<br />
<br />
There are many kinds of extensions: they may use languages other than Basic, or even set a configuration without any executable code. Usually an extension provides menus and toolbars for one or more applications (Writer, Calc...).<br />
<br />
For a professional look you will have to add copyright statements, create your own help pages, provide automatic update. All displayable texts will probably have to be translated in several languages. This means editing lots of files, testing and editing each time you have found a bug, or added a feature, or added a new language.<br />
<br />
The Extension Compiler can handle all kinds of extensions and reduce your work load. Its documentation guides you through most of the process.<br />
You don't need to know all the implementation details, you don't need a complex environment. You will edit a Writer document to write the extension description, the license text, the help pages for your extension, in various languages if needed.<br />
<br />
The help pages for your extension may be specific to each application (Calc, Writer, Draw...). They are called by a help button in your dialogs, or by contextual help in the dialogs or menus, or from the help window. These help pages will be seamlessly integrated into the OpenOffice help system.<br />
<br />
You will then write a linear succession of simple Basic instructions to describe your extension.<br />
At a click on a button in the document, the Extension Compiler will create the files description.xml, addon.xml, manifest.xml, xxxWindowState.xml, and the license, extension description, display name, help pages for different languages. All files will be encoded in UTF-8 to support national characters, and stored in sub-folders. After a few seconds your oxt package is ready to be installed!<br />
<br />
If you made an error, or if you are not satisfied with your extension, change some instructions and run again. For complex extensions (e.g. many menus or buttons), incremental design is easy: start simple, test, add a feature, test it, add another feature, etc.<br />
<br />
== Requirements ==<br />
The extensions are installable on OpenOffice.org 2.4 or more recent (Apache OpenOffice, LibreOffice).<br />
<br />
== Install ==<br />
<br />
Extension Compiler is a Writer template document. Store it in a folder where macros are allowed. <br />
<br />
From this template, create a new Writer document by double-click or key Enter. You will be prompted to save it under the name of your extension in a dedicated folder where macro execution is allowed.<br />
<br />
You will store in this dedicated folder all the libraries, files, images, needed for your extension. You may use sub-folders.<br />
<br />
== Latest changes ==<br />
<br />
=== Version 2.1.2 ===<br />
Localized help : resolved inactive hyperlink due to API incompatibility introduced by Apache OpenOffice 4.1 (and LibreOffice 4.0).<br />
<br />
=== Version 2.1.1 ===<br />
Minor corrections, no impact for existing extensions.<br />
<br />
=== Version 2.1 ===<br />
Extension Compiler can now compile extensions having more than one toolbar in an application context, for example an extension that adds 2 toolbars in Calc.<br />
<br />
=== Version 2.0 ===<br />
Extension Compiler can now compile the same extension to different variants, if needed : OpenOffice.org or compatible, Apache OpenOffice 4.0 or more recent, LibreOffice 3.5 or more recent.<br />
<br />
== Related Issues ==<br />
<br />
There are currently some limitations or bugs in the extension mechanism itself, [http://qa.openoffice.org/issues/buglist.cgi?quicksearch=86437%2C86528%2C86534%2C87230%2C87412%2C91752%2C95086 see these Issues].<br />
<br />
== Download ==<br />
<br />
The latest version of Extension Compiler is [http://berma.pagesperso-orange.fr/Files_en/ExtensionCompiler.ott downloadable at this location].<br />
<br />
A French translation of the manual is [http://berma.pagesperso-orange.fr/Files_fr/ExtensionCompiler-Fr.odt downloadable at this location].<br />
<br />
To help understand how it works, here are two examples of extension projects:<br />
<br />
==== A simple extension ====<br />
<br />
The archive [http://berma.pagesperso-orange.fr/Files_en/SimpleDemo.zip SimpleDemo.zip] contains the files necessary to compile the extension [http://extensions.openoffice.org/fr/project/images-embedder Images Embedder] version 1.0.0. This extension installs a Basic program, without dialogs, and a menu item in Tools → Add-Ons. This menu item displays in several languages.<br />
<br />
The archive unzips into a directory named ImagesEmbedder/.<br />
<br />
Open the document ImagesEmbedder.odt, then at chapter 2.3.1 click the button ''Compile to OpenOffice.org or compatible''. The oxt file will be created in the same folder.<br />
<br />
==== A sophisticated extension ====<br />
<br />
The file [http://berma.pagesperso-orange.fr/Files_en/ExtensionDemo.zip ExtensionDemo.zip] shows more interesting features. The extension will require at least OpenOffice.org version 3.3.0.<br />
<br />
This archive unzips into a directory named Demo/. <br />
It contains all the data to create the extension ExtExample. The compiled extension package is also in the folder.<br />
<br />
ExtExample adds a toolbar and some commands in the menu Tools > Add-Ons of Writer and Calc.<br />
In Writer, Tools → Add-Ons sub-menu can start sample scripts in Basic, Python BeanShell, JavaScript, Java macro.<br />
<br />
Since there is a Toolbar, this extension is compiled to:<br />
* OpenOffice.org compatible (including LibreOffice)<br />
* Apache OpenOffice 4.0 <br />
<br />
Since it uses non-Basic scripts, this extension is also compiled for the current user only and for all users.<br />
<br />
The Extension Compiler creates the four variants from a unique extension.<br />
<br />
== Contacting author ==<br />
<br />
Extension Compiler is written by Bernard Marcelly.<br />
Please send your suggestions and bug reports at the address indicated in the document.<br />
Feedback are welcome.<br />
<br />
<br />
[[Category:Extensions]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/OfficeDev/Properties_of_a_FilterDocumentation/DevGuide/OfficeDev/Properties of a Filter2016-02-11T10:35:13Z<p>BMarcelly: </p>
<hr />
<div>{{Documentation/DevGuide/OfficeDevTOC<br />
|OfficeDev2b=block<br />
|OfficeDevInteg=block<br />
|OfficeDevDocFilter=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/OfficeDev/Properties of a Type<br />
|NextPage=Documentation/DevGuide/OfficeDev/Filter Options<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/OfficeDev/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:Properties of a Filter}}<br />
<br />
Every filter inside {{PRODUCTNAME}} is specified by the properties shown in the table below. These values are accessible at the previously mentioned service <idl>com.sun.star.document.FilterFactory</idl> using the interface <idl>com.sun.star.container.XNameAccess</idl>. Write access is not available here. All types are addressed by their internal names. The property names are identical to the configuration property names.<br />
<br />
{{Documentation/Caution|The documentation of the FilterFactory service currently is outdated. In case of conflicting information about the properties this page is right. An update will follow soon. }}<br />
<br />
A filter always is registered for only one type. A single filter implementation can handle several types but then must be registered multiple times. One type may handled by more than one filter. <br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Property Name <br />
!Description <br />
|-<br />
|<code>Name</code><br />
|string. The internal name of the filter. This is only an API property, not a configuration property. In the configuration this is the name of the configuration node containing all the other properties. To avoid name clashes with other node names it should follow the rules outlined for [[Documentation/DevGuide/Extensions/Extension_Identifiers | extension identifiers]].<br />
|-<br />
|<code>UIName</code> <br />
|string. User friendly name of the type. It may be localized using the localization support of the configuration. All Unicode characters are permitted here. The UI names of filters are used in the various file dialog.<br />
|-<br />
|<code>Type</code> <br />
|string. A filter is registered for the type it can handle. Multiple assignments are not allowed. Use multiple configuration entries to support more than one type with a single filter implementation.<br />
|-<br />
|<code>DocumentService</code> <br />
|string. UNO service name describing the component on which the filter can operate. As an example, "<code>com.sun.star.text.TextDocument</code>" specifies the filter as working with text documents. An object of this type will be passed to the filter in its <code>setTargetDocument()</code> or <code>setSourceDocument()</code> methods.<br />
|-<br />
|<code>FilterService</code> <br />
|string. This is the UNO service or implementation name of the filter. Of course a service name can be used only if it is not the generic <idl>com.sun.star.document.ImportFilter</idl> or <idl>com.sun.star.document.ExportFilter</idl>. In case of XML based filters the service name always must be <code>com.sun.star.comp.Writer.XMLFilterAdaptor</code>. This filter will use the "UserData" property to find the XMLImporter or XMLExporter service it shall instantiate. <br />
|-<br />
|<code>UIComponent</code> <br />
|string. UNO service or implementation name of a UI component (usually a dialog) where users can parameterize the filtering process. As an example, the "<code>Text - txt - csv (StarCalc)</code>" filter needs information about the used column separators to load data. More about that in the chapter about [[Documentation/DevGuide/OfficeDev/Filter_Options|filter options]].<br />
|-<br />
|<code>Flags</code> <br />
| <br />
<br />
* XML : string list. Some boolean attributes of a filter. <br />
<br />
* FilterFactory service, see <idl>com.sun.star.document.FilterFactory:XNameAccess</idl> : <code>int</code>. Contains a set of boolean values.<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!colspan="2"|Filter flags <br />
|-<br />
| ''3RDPARTYFILTER'' <br />
<code>0x00080000 h</code><br />
<br />
| The filter is a UNO component filter, as opposed to the internal C++ filters. This is an artefact that will vanish over time.<br />
|-<br />
| ''ALIEN'' <br />
<code>0x00000040 h</code><br />
| The filter may lose some information upon saving.<br />
|-<br />
| ''DEFAULT'' <br />
<code>0x00000100 h</code><br />
| This is the "best" filter for the document type it works on that is guaranteed not so lose any data on export. By default this filter will be used or suggested for every storing process unless the user has chosen a different default filter in the options dialog.<br />
|-<br />
| ''EXPORT''<br />
<code>0x00000002 h</code> <br />
| The filter supports the service com.sun.star.document.ExportFilter. It will be shown in the dialog "File-Export". If the filter also has the "IMPORT" flag set, it will be shown in the dialog "File-Save". This makes sure that a format that a user chooses in the save dialog can be loaded again. The same is not guaranteed for a format chosen in "File-Export".<br />
|-<br />
| ''IMPORT'' <br />
<code>0x00000001 h</code><br />
| The filter supports service com.sun.star.document.ImportFilter. The filter will be shown in the dialog "File-Open".<br />
|-<br />
| ''INTERNAL'' <br />
<code>0x00000008 h</code><br />
| This filter is used only for internal purposes and so can be used only in API calls. Users won't see it ever.<br />
|-<br />
| ''NOTINCHOOSER'' <br />
<code>0x00002000 h</code><br />
| This filter will not be shown in the dialog box for chosing a filter in case OOo was not able to detect one<br />
|-<br />
| ''NOTINFILEDIALOG''<br />
<code>0x00001000 h</code> <br />
| This filter will not be shown in the file dialog's filter list<br />
|-<br />
| ''OWN'' <br />
<code>0x00000020 h</code><br />
| The filter is a native OO.o format (ODF or otherwise).<br />
|-<br />
| ''PREFERRED'' <br />
<code>0x10000000 h</code><br />
| The filter is preferred in case of multiple filters for the same file type exist in the configuration<br />
|-<br />
| ''READONLY''<br />
<code>0x00010000 h</code> <br />
| All documents imported by this filter will automatically be in read-only state<br />
|-<br />
| ''SUPPORTSSELECTION''<br />
<code>0x00000400 h</code> <br />
| Filter can export only the selected part of a document. This information enables {{PRODUCTNAME}} to enable a corresponding check box in the "File-Export" dialog.<br />
|-<br />
| ''TEMPLATE'' <br />
<code>0x00000004 h</code><br />
| Filter denotes a template filter (means, by default all documents opened by it become an "untitled" one)<br />
|-<br />
| ''TEMPLATEPATH'' <br />
<code>0x00000010 h</code><br />
| Must always be set together with "TEMPLATE" to make this feature flag work; soon becoming deprecated<br />
|}<br />
|-<br />
|<code>UserData</code> <br />
|sequence<string>. Some filters need to store more configuration to work properly. The format of the string list is not restricted. An important example is the filter that implements the XMLFilterAdaptor service. It will get the service name of the XML based filter it must instantiate from the user data. In case this XML based filter is one of the XML adaptors for xslt files, the user data also must contain at least an absolute or relative file path point to the xslt file carrying out the transformation.<br />
|-<br />
|<code>FileFormatVersion</code> <br />
|int. Indicates that a filter handles only a particular format version of the content type. If a filter implementation can handle several versions of a filter, several configuration entries have to be created. This is not necessary if the filter handles all possible versions and the different versions don't need to appear in the user interface.<br />
|-<br />
|<code>TemplateName</code> <br />
|string. The name of a template file for styles the target document of an import filter shall use. If this property is set, the document merges the styles of this template with its default styles before the import starts.<br />
|}<br />
<br />
{{Documentation/Caution|Besides these filter flags there are other flags existing that are used currently, but are not documented here. Use documented flags only. <br />
}}<br />
<br />
===Sample configuration for an API based filter===<br />
<br />
<source lang="xml"><br />
<!-- Filter section --><br />
<node oor:name="Text (encoded)" oor:op="replace"><br />
<prop oor:name="UIName"><br />
<value>Text (encoded)</value><br />
</prop><br />
<prop oor:name="Flags"><value>IMPORT EXPORT ALIEN</value></prop><br />
<prop oor:name="UIComponent"><value>com.sun.star.comp.Writer.FilterOptionsDialog</value></prop><br />
<prop oor:name="FilterService"/><br />
<prop oor:name="UserData"><value>TEXT_DLG</value></prop><br />
<prop oor:name="FileFormatVersion"><value>0</value></prop><br />
<prop oor:name="Type"><value>writer_Text_encoded</value></prop><br />
<prop oor:name="TemplateName"/><br />
<prop oor:name="DocumentService"><value>com.sun.star.text.TextDocument</value></prop><br />
</node><br />
</source><br />
<br />
{{Documentation/Note|This filter has a UIComponent that shows that this filter needs additional information to load a file properly (the encoding of it in case it can't be detected). It does not have a "FilterService" property because it is an internal, C++ based filter.}}<br />
<br />
===Sample configuration for an XML based filter===<br />
<br />
<source lang="xml"><br />
<!-- Filter section --><br />
<node oor:name="PocketWord File" oor:op="replace"><br />
<prop oor:name="UIName"><br />
<value>Pocket Word</value><br />
</prop><br />
<prop oor:name="Type"><value>writer_PocketWord_File</value></prop><br />
<prop oor:name="FileFormatVersion"><value>0</value></prop><br />
<prop oor:name="DocumentService"><value>com.sun.star.text.TextDocument</value></prop><br />
<prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop><br />
<prop oor:name="UIComponent"/><br />
<prop oor:name="UserData"><value>com.sun.star.documentconversion.XMergeBridge classes/pocketword.jar com.sun.star.comp.Writer.XMLImporter com.sun.star.comp.Writer.XMLExporter staroffice/sxw application/x-pocket-word</value></prop><br />
<prop oor:name="TemplateName"/><br />
<prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER</value></prop><br />
</node><br />
</source><br />
<br />
{{Documentation/Note|This filter uses the XMLFilterAdaptor service. The "UserData" property is a space-separated list where the first list element denotes the XMLImportFilter to be instantiated and the third one and fourth one are service names of DocumentHandlers for import and export. Further parameters depend on the XMLImportFilter used.}}<br />
<br />
===Sample configuration for an xslt based filter===<br />
<br />
<source lang="xml"><br />
<!-- Filter section --><br />
<node oor:name="MediaWiki" oor:op="replace"><br />
<prop oor:name="FileFormatVersion"><value>0</value></prop><br />
<prop oor:name="Type"><value>MediaWiki</value></prop><br />
<prop oor:name="DocumentService"><value>com.sun.star.text.TextDocument</value></prop><br />
<prop oor:name="UIComponent"/><br />
<prop oor:name="UserData"><value oor:separator=",">com.sun.star.documentconversion.XSLTFilter,,,com.sun.star.comp.Writer.XMLOasisExporter,,../share/xslt/wiki/odt2mediawiki.xsl</value></prop><br />
<prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop><br />
<prop oor:name="UIName"><br />
<value xml:lang="x-default">MediaWiki</value><br />
</prop><br />
<prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop><br />
</node><br />
</source><br />
<br />
{{Documentation/Note|This filter uses the XMLFilterAdaptor service. The "UserData" property is a space-separated list where the first list element denotes the XMLImportFilter to be instantiated and the third one and fourth one are service names of DocumentHandlers for import and export. Further parameters depend on the XMLImportFilter used. }}<br />
<br />
Here the XMLFilter used is the <idl>com.sun.star.documentconversion.XSLTFilter</idl> that bridges to xslt files and basically can import and export if a suitable xslt is provided. It expects the following parameters in the user data ($(APP) stands for Writer,Calc,Draw,Impress,Chart,Math):<br />
<br />
(1) service name of the XSLTFilter<br />
(3) implementation/service name of an importer class (com.sun.star.comp.$(APP).XMLOasisImporter)<br />
(4) implementation/service name of an exporter class (com.sun.star.comp.$(APP).XMLOasisExporter)<br />
(5) relative or absolute path name to an importing style sheet<br />
(6) relative or absolute path name to an importing style sheet<br />
<br />
{{Documentation/Note|Older xslt based filters might have used the pre-ODF file format of {{PRODUCTNAME}}. They used importer and exporter class without "Oasis" in their names.}}<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Office Development]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Talk:Documentation/DevGuide/OfficeDev/Properties_of_a_FilterTalk:Documentation/DevGuide/OfficeDev/Properties of a Filter2016-02-10T16:42:57Z<p>BMarcelly: </p>
<hr />
<div>It should read (6) relative or absolute path name to an '''exporting''' style sheet?<br />
<br />
The link to [http://api.openoffice.org/docs/common/ref/com/sun/star/documentconversion/XSLTFilter.html]com.sun.star.documentconversion.XSLTFilter is dead.<br />
<br />
<br />
Comment from [[User:BMarcelly|BMarcelly]]<br />
<br />
In rev 2008-10-01T10:49:29, [[User:Mba|Mba]] replaced the Flags content type: <code>Int</code> by: <code>string list</code><br />
<br />
[[User:Mba|Mba]] was describing the XML syntax for Flags. But when you access the filters data from the API, property Flags contains a set of boolean flags. This must also be documented here.<br />
<br />
In rev 2008-10-01T11:05:57, [[User:Mba|Mba]] replaced the description of flag values by a string, and changed the order of description.<br />
<br />
Since the API does not offer constants for these values, the real values are still needed when accessing by API.<br />
<br />
I have kept the existing description for XML and added for the API the type <code>Int</code> for Flags, and added the values of these flags, found in /aoo-trunk/main/filter/source/config/cache/constant.hxx.</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/OfficeDev/Properties_of_a_FilterDocumentation/DevGuide/OfficeDev/Properties of a Filter2016-02-10T16:35:42Z<p>BMarcelly: </p>
<hr />
<div>{{Documentation/DevGuide/OfficeDevTOC<br />
|OfficeDev2b=block<br />
|OfficeDevInteg=block<br />
|OfficeDevDocFilter=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/OfficeDev/Properties of a Type<br />
|NextPage=Documentation/DevGuide/OfficeDev/Filter Options<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/OfficeDev/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:Properties of a Filter}}<br />
<br />
Every filter inside {{PRODUCTNAME}} is specified by the properties shown in the table below. These values are accessible at the previously mentioned service <idl>com.sun.star.document.FilterFactory</idl> using the interface <idl>com.sun.star.container.XNameAccess</idl>. Write access is not available here. All types are addressed by their internal names. The property names are identical to the configuration property names.<br />
<br />
{{Documentation/Caution|The documentation of the FilterFactory service currently is outdated. In case of conflicting information about the properties this page is right. An update will follow soon. }}<br />
<br />
A filter always is registered for only one type. A single filter implementation can handle several types but then must be registered multiple times. One type may handled by more than one filter. <br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Property Name <br />
!Description <br />
|-<br />
|<code>Name</code><br />
|string. The internal name of the filter. This is only an API property, not a configuration property. In the configuration this is the name of the configuration node containing all the other properties. To avoid name clashes with other node names it should follow the rules outlined for [[Documentation/DevGuide/Extensions/Extension_Identifiers | extension identifiers]].<br />
|-<br />
|<code>UIName</code> <br />
|string. User friendly name of the type. It may be localized using the localization support of the configuration. All Unicode characters are permitted here. The UI names of filters are used in the various file dialog.<br />
|-<br />
|<code>Type</code> <br />
|string. A filter is registered for the type it can handle. Multiple assignments are not allowed. Use multiple configuration entries to support more than one type with a single filter implementation.<br />
|-<br />
|<code>DocumentService</code> <br />
|string. UNO service name describing the component on which the filter can operate. As an example, "<code>com.sun.star.text.TextDocument</code>" specifies the filter as working with text documents. An object of this type will be passed to the filter in its <code>setTargetDocument()</code> or <code>setSourceDocument()</code> methods.<br />
|-<br />
|<code>FilterService</code> <br />
|string. This is the UNO service or implementation name of the filter. Of course a service name can be used only if it is not the generic <idl>com.sun.star.document.ImportFilter</idl> or <idl>com.sun.star.document.ExportFilter</idl>. In case of XML based filters the service name always must be <code>com.sun.star.comp.Writer.XMLFilterAdaptor</code>. This filter will use the "UserData" property to find the XMLImporter or XMLExporter service it shall instantiate. <br />
|-<br />
|<code>UIComponent</code> <br />
|string. UNO service or implementation name of a UI component (usually a dialog) where users can parameterize the filtering process. As an example, the "<code>Text - txt - csv (StarCalc)</code>" filter needs information about the used column separators to load data. More about that in the chapter about [[Documentation/DevGuide/OfficeDev/Filter_Options|filter options]].<br />
|-<br />
|<code>Flags</code> <br />
|XML : string list. Some boolean attributes of a filter. <br />
<br />
API : int. Contains a set of boolean values.<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!colspan="2"|Filter flags <br />
|-<br />
| ''3RDPARTYFILTER'' <br />
<code>0x00080000 h</code><br />
<br />
| The filter is a UNO component filter, as opposed to the internal C++ filters. This is an artefact that will vanish over time.<br />
|-<br />
| ''ALIEN'' <br />
<code>0x00000040 h</code><br />
| The filter may lose some information upon saving.<br />
|-<br />
| ''DEFAULT'' <br />
<code>0x00000100 h</code><br />
| This is the "best" filter for the document type it works on that is guaranteed not so lose any data on export. By default this filter will be used or suggested for every storing process unless the user has chosen a different default filter in the options dialog.<br />
|-<br />
| ''EXPORT''<br />
<code>0x00000002 h</code> <br />
| The filter supports the service com.sun.star.document.ExportFilter. It will be shown in the dialog "File-Export". If the filter also has the "IMPORT" flag set, it will be shown in the dialog "File-Save". This makes sure that a format that a user chooses in the save dialog can be loaded again. The same is not guaranteed for a format chosen in "File-Export".<br />
|-<br />
| ''IMPORT'' <br />
<code>0x00000001 h</code><br />
| The filter supports service com.sun.star.document.ImportFilter. The filter will be shown in the dialog "File-Open".<br />
|-<br />
| ''INTERNAL'' <br />
<code>0x00000008 h</code><br />
| This filter is used only for internal purposes and so can be used only in API calls. Users won't see it ever.<br />
|-<br />
| ''NOTINCHOOSER'' <br />
<code>0x00002000 h</code><br />
| This filter will not be shown in the dialog box for chosing a filter in case OOo was not able to detect one<br />
|-<br />
| ''NOTINFILEDIALOG''<br />
<code>0x00001000 h</code> <br />
| This filter will not be shown in the file dialog's filter list<br />
|-<br />
| ''OWN'' <br />
<code>0x00000020 h</code><br />
| The filter is a native OO.o format (ODF or otherwise).<br />
|-<br />
| ''PREFERRED'' <br />
<code>0x10000000 h</code><br />
| The filter is preferred in case of multiple filters for the same file type exist in the configuration<br />
|-<br />
| ''READONLY''<br />
<code>0x00010000 h</code> <br />
| All documents imported by this filter will automatically be in read-only state<br />
|-<br />
| ''SUPPORTSSELECTION''<br />
<code>0x00000400 h</code> <br />
| Filter can export only the selected part of a document. This information enables {{PRODUCTNAME}} to enable a corresponding check box in the "File-Export" dialog.<br />
|-<br />
| ''TEMPLATE'' <br />
<code>0x00000004 h</code><br />
| Filter denotes a template filter (means, by default all documents opened by it become an "untitled" one)<br />
|-<br />
| ''TEMPLATEPATH'' <br />
<code>0x00000010 h</code><br />
| Must always be set together with "TEMPLATE" to make this feature flag work; soon becoming deprecated<br />
|}<br />
|-<br />
|<code>UserData</code> <br />
|sequence<string>. Some filters need to store more configuration to work properly. The format of the string list is not restricted. An important example is the filter that implements the XMLFilterAdaptor service. It will get the service name of the XML based filter it must instantiate from the user data. In case this XML based filter is one of the XML adaptors for xslt files, the user data also must contain at least an absolute or relative file path point to the xslt file carrying out the transformation.<br />
|-<br />
|<code>FileFormatVersion</code> <br />
|int. Indicates that a filter handles only a particular format version of the content type. If a filter implementation can handle several versions of a filter, several configuration entries have to be created. This is not necessary if the filter handles all possible versions and the different versions don't need to appear in the user interface.<br />
|-<br />
|<code>TemplateName</code> <br />
|string. The name of a template file for styles the target document of an import filter shall use. If this property is set, the document merges the styles of this template with its default styles before the import starts.<br />
|}<br />
<br />
{{Documentation/Caution|Besides these filter flags there are other flags existing that are used currently, but are not documented here. Use documented flags only. <br />
}}<br />
<br />
===Sample configuration for an API based filter===<br />
<br />
<source lang="xml"><br />
<!-- Filter section --><br />
<node oor:name="Text (encoded)" oor:op="replace"><br />
<prop oor:name="UIName"><br />
<value>Text (encoded)</value><br />
</prop><br />
<prop oor:name="Flags"><value>IMPORT EXPORT ALIEN</value></prop><br />
<prop oor:name="UIComponent"><value>com.sun.star.comp.Writer.FilterOptionsDialog</value></prop><br />
<prop oor:name="FilterService"/><br />
<prop oor:name="UserData"><value>TEXT_DLG</value></prop><br />
<prop oor:name="FileFormatVersion"><value>0</value></prop><br />
<prop oor:name="Type"><value>writer_Text_encoded</value></prop><br />
<prop oor:name="TemplateName"/><br />
<prop oor:name="DocumentService"><value>com.sun.star.text.TextDocument</value></prop><br />
</node><br />
</source><br />
<br />
{{Documentation/Note|This filter has a UIComponent that shows that this filter needs additional information to load a file properly (the encoding of it in case it can't be detected). It does not have a "FilterService" property because it is an internal, C++ based filter.}}<br />
<br />
===Sample configuration for an XML based filter===<br />
<br />
<source lang="xml"><br />
<!-- Filter section --><br />
<node oor:name="PocketWord File" oor:op="replace"><br />
<prop oor:name="UIName"><br />
<value>Pocket Word</value><br />
</prop><br />
<prop oor:name="Type"><value>writer_PocketWord_File</value></prop><br />
<prop oor:name="FileFormatVersion"><value>0</value></prop><br />
<prop oor:name="DocumentService"><value>com.sun.star.text.TextDocument</value></prop><br />
<prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop><br />
<prop oor:name="UIComponent"/><br />
<prop oor:name="UserData"><value>com.sun.star.documentconversion.XMergeBridge classes/pocketword.jar com.sun.star.comp.Writer.XMLImporter com.sun.star.comp.Writer.XMLExporter staroffice/sxw application/x-pocket-word</value></prop><br />
<prop oor:name="TemplateName"/><br />
<prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER</value></prop><br />
</node><br />
</source><br />
<br />
{{Documentation/Note|This filter uses the XMLFilterAdaptor service. The "UserData" property is a space-separated list where the first list element denotes the XMLImportFilter to be instantiated and the third one and fourth one are service names of DocumentHandlers for import and export. Further parameters depend on the XMLImportFilter used.}}<br />
<br />
===Sample configuration for an xslt based filter===<br />
<br />
<source lang="xml"><br />
<!-- Filter section --><br />
<node oor:name="MediaWiki" oor:op="replace"><br />
<prop oor:name="FileFormatVersion"><value>0</value></prop><br />
<prop oor:name="Type"><value>MediaWiki</value></prop><br />
<prop oor:name="DocumentService"><value>com.sun.star.text.TextDocument</value></prop><br />
<prop oor:name="UIComponent"/><br />
<prop oor:name="UserData"><value oor:separator=",">com.sun.star.documentconversion.XSLTFilter,,,com.sun.star.comp.Writer.XMLOasisExporter,,../share/xslt/wiki/odt2mediawiki.xsl</value></prop><br />
<prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop><br />
<prop oor:name="UIName"><br />
<value xml:lang="x-default">MediaWiki</value><br />
</prop><br />
<prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop><br />
</node><br />
</source><br />
<br />
{{Documentation/Note|This filter uses the XMLFilterAdaptor service. The "UserData" property is a space-separated list where the first list element denotes the XMLImportFilter to be instantiated and the third one and fourth one are service names of DocumentHandlers for import and export. Further parameters depend on the XMLImportFilter used. }}<br />
<br />
Here the XMLFilter used is the <idl>com.sun.star.documentconversion.XSLTFilter</idl> that bridges to xslt files and basically can import and export if a suitable xslt is provided. It expects the following parameters in the user data ($(APP) stands for Writer,Calc,Draw,Impress,Chart,Math):<br />
<br />
(1) service name of the XSLTFilter<br />
(3) implementation/service name of an importer class (com.sun.star.comp.$(APP).XMLOasisImporter)<br />
(4) implementation/service name of an exporter class (com.sun.star.comp.$(APP).XMLOasisExporter)<br />
(5) relative or absolute path name to an importing style sheet<br />
(6) relative or absolute path name to an importing style sheet<br />
<br />
{{Documentation/Note|Older xslt based filters might have used the pre-ODF file format of {{PRODUCTNAME}}. They used importer and exporter class without "Oasis" in their names.}}<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Office Development]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/OfficeDev/Properties_of_a_FilterDocumentation/DevGuide/OfficeDev/Properties of a Filter2016-02-10T16:27:12Z<p>BMarcelly: See explanation of changes in discussion</p>
<hr />
<div>{{Documentation/DevGuide/OfficeDevTOC<br />
|OfficeDev2b=block<br />
|OfficeDevInteg=block<br />
|OfficeDevDocFilter=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/OfficeDev/Properties of a Type<br />
|NextPage=Documentation/DevGuide/OfficeDev/Filter Options<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/OfficeDev/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:Properties of a Filter}}<br />
<br />
Every filter inside {{PRODUCTNAME}} is specified by the properties shown in the table below. These values are accessible at the previously mentioned service <idl>com.sun.star.document.FilterFactory</idl> using the interface <idl>com.sun.star.container.XNameAccess</idl>. Write access is not available here. All types are addressed by their internal names. The property names are identical to the configuration property names.<br />
<br />
{{Documentation/Caution|The documentation of the FilterFactory service currently is outdated. In case of conflicting information about the properties this page is right. An update will follow soon. }}<br />
<br />
A filter always is registered for only one type. A single filter implementation can handle several types but then must be registered multiple times. One type may handled by more than one filter. <br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Property Name <br />
!Description <br />
|-<br />
|<code>Name</code><br />
|string. The internal name of the filter. This is only an API property, not a configuration property. In the configuration this is the name of the configuration node containing all the other properties. To avoid name clashes with other node names it should follow the rules outlined for [[Documentation/DevGuide/Extensions/Extension_Identifiers | extension identifiers]].<br />
|-<br />
|<code>UIName</code> <br />
|string. User friendly name of the type. It may be localized using the localization support of the configuration. All Unicode characters are permitted here. The UI names of filters are used in the various file dialog.<br />
|-<br />
|<code>Type</code> <br />
|string. A filter is registered for the type it can handle. Multiple assignments are not allowed. Use multiple configuration entries to support more than one type with a single filter implementation.<br />
|-<br />
|<code>DocumentService</code> <br />
|string. UNO service name describing the component on which the filter can operate. As an example, "<code>com.sun.star.text.TextDocument</code>" specifies the filter as working with text documents. An object of this type will be passed to the filter in its <code>setTargetDocument()</code> or <code>setSourceDocument()</code> methods.<br />
|-<br />
|<code>FilterService</code> <br />
|string. This is the UNO service or implementation name of the filter. Of course a service name can be used only if it is not the generic <idl>com.sun.star.document.ImportFilter</idl> or <idl>com.sun.star.document.ExportFilter</idl>. In case of XML based filters the service name always must be <code>com.sun.star.comp.Writer.XMLFilterAdaptor</code>. This filter will use the "UserData" property to find the XMLImporter or XMLExporter service it shall instantiate. <br />
|-<br />
|<code>UIComponent</code> <br />
|string. UNO service or implementation name of a UI component (usually a dialog) where users can parameterize the filtering process. As an example, the "<code>Text - txt - csv (StarCalc)</code>" filter needs information about the used column separators to load data. More about that in the chapter about [[Documentation/DevGuide/OfficeDev/Filter_Options|filter options]].<br />
|-<br />
|<code>Flags</code> <br />
|int. Set of boolean attributes of a filter.<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!colspan="2"|Filter flags <br />
|-<br />
| ''3RDPARTYFILTER'' <br />
<code>0x00080000 h</code><br />
<br />
| The filter is a UNO component filter, as opposed to the internal C++ filters. This is an artefact that will vanish over time.<br />
|-<br />
| ''ALIEN'' <br />
<code>0x00000040 h</code><br />
| The filter may lose some information upon saving.<br />
|-<br />
| ''DEFAULT'' <br />
<code>0x00000100 h</code><br />
| This is the "best" filter for the document type it works on that is guaranteed not so lose any data on export. By default this filter will be used or suggested for every storing process unless the user has chosen a different default filter in the options dialog.<br />
|-<br />
| ''EXPORT''<br />
<code>0x00000002 h</code> <br />
| The filter supports the service com.sun.star.document.ExportFilter. It will be shown in the dialog "File-Export". If the filter also has the "IMPORT" flag set, it will be shown in the dialog "File-Save". This makes sure that a format that a user chooses in the save dialog can be loaded again. The same is not guaranteed for a format chosen in "File-Export".<br />
|-<br />
| ''IMPORT'' <br />
<code>0x00000001 h</code><br />
| The filter supports service com.sun.star.document.ImportFilter. The filter will be shown in the dialog "File-Open".<br />
|-<br />
| ''INTERNAL'' <br />
<code>0x00000008 h</code><br />
| This filter is used only for internal purposes and so can be used only in API calls. Users won't see it ever.<br />
|-<br />
| ''NOTINCHOOSER'' <br />
<code>0x00002000 h</code><br />
| This filter will not be shown in the dialog box for chosing a filter in case OOo was not able to detect one<br />
|-<br />
| ''NOTINFILEDIALOG''<br />
<code>0x00001000 h</code> <br />
| This filter will not be shown in the file dialog's filter list<br />
|-<br />
| ''OWN'' <br />
<code>0x00000020 h</code><br />
| The filter is a native OO.o format (ODF or otherwise).<br />
|-<br />
| ''PREFERRED'' <br />
<code>0x10000000 h</code><br />
| The filter is preferred in case of multiple filters for the same file type exist in the configuration<br />
|-<br />
| ''READONLY''<br />
<code>0x00010000 h</code> <br />
| All documents imported by this filter will automatically be in read-only state<br />
|-<br />
| ''SUPPORTSSELECTION''<br />
<code>0x00000400 h</code> <br />
| Filter can export only the selected part of a document. This information enables {{PRODUCTNAME}} to enable a corresponding check box in the "File-Export" dialog.<br />
|-<br />
| ''TEMPLATE'' <br />
<code>0x00000004 h</code><br />
| Filter denotes a template filter (means, by default all documents opened by it become an "untitled" one)<br />
|-<br />
| ''TEMPLATEPATH'' <br />
<code>0x00000010 h</code><br />
| Must always be set together with "TEMPLATE" to make this feature flag work; soon becoming deprecated<br />
|}<br />
|-<br />
|<code>UserData</code> <br />
|sequence<string>. Some filters need to store more configuration to work properly. The format of the string list is not restricted. An important example is the filter that implements the XMLFilterAdaptor service. It will get the service name of the XML based filter it must instantiate from the user data. In case this XML based filter is one of the XML adaptors for xslt files, the user data also must contain at least an absolute or relative file path point to the xslt file carrying out the transformation.<br />
|-<br />
|<code>FileFormatVersion</code> <br />
|int. Indicates that a filter handles only a particular format version of the content type. If a filter implementation can handle several versions of a filter, several configuration entries have to be created. This is not necessary if the filter handles all possible versions and the different versions don't need to appear in the user interface.<br />
|-<br />
|<code>TemplateName</code> <br />
|string. The name of a template file for styles the target document of an import filter shall use. If this property is set, the document merges the styles of this template with its default styles before the import starts.<br />
|}<br />
<br />
{{Documentation/Caution|Besides these filter flags there are other flags existing that are used currently, but are not documented here. Use documented flags only. <br />
}}<br />
<br />
===Sample configuration for an API based filter===<br />
<br />
<source lang="xml"><br />
<!-- Filter section --><br />
<node oor:name="Text (encoded)" oor:op="replace"><br />
<prop oor:name="UIName"><br />
<value>Text (encoded)</value><br />
</prop><br />
<prop oor:name="Flags"><value>IMPORT EXPORT ALIEN</value></prop><br />
<prop oor:name="UIComponent"><value>com.sun.star.comp.Writer.FilterOptionsDialog</value></prop><br />
<prop oor:name="FilterService"/><br />
<prop oor:name="UserData"><value>TEXT_DLG</value></prop><br />
<prop oor:name="FileFormatVersion"><value>0</value></prop><br />
<prop oor:name="Type"><value>writer_Text_encoded</value></prop><br />
<prop oor:name="TemplateName"/><br />
<prop oor:name="DocumentService"><value>com.sun.star.text.TextDocument</value></prop><br />
</node><br />
</source><br />
<br />
{{Documentation/Note|This filter has a UIComponent that shows that this filter needs additional information to load a file properly (the encoding of it in case it can't be detected). It does not have a "FilterService" property because it is an internal, C++ based filter.}}<br />
<br />
===Sample configuration for an XML based filter===<br />
<br />
<source lang="xml"><br />
<!-- Filter section --><br />
<node oor:name="PocketWord File" oor:op="replace"><br />
<prop oor:name="UIName"><br />
<value>Pocket Word</value><br />
</prop><br />
<prop oor:name="Type"><value>writer_PocketWord_File</value></prop><br />
<prop oor:name="FileFormatVersion"><value>0</value></prop><br />
<prop oor:name="DocumentService"><value>com.sun.star.text.TextDocument</value></prop><br />
<prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop><br />
<prop oor:name="UIComponent"/><br />
<prop oor:name="UserData"><value>com.sun.star.documentconversion.XMergeBridge classes/pocketword.jar com.sun.star.comp.Writer.XMLImporter com.sun.star.comp.Writer.XMLExporter staroffice/sxw application/x-pocket-word</value></prop><br />
<prop oor:name="TemplateName"/><br />
<prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER</value></prop><br />
</node><br />
</source><br />
<br />
{{Documentation/Note|This filter uses the XMLFilterAdaptor service. The "UserData" property is a space-separated list where the first list element denotes the XMLImportFilter to be instantiated and the third one and fourth one are service names of DocumentHandlers for import and export. Further parameters depend on the XMLImportFilter used.}}<br />
<br />
===Sample configuration for an xslt based filter===<br />
<br />
<source lang="xml"><br />
<!-- Filter section --><br />
<node oor:name="MediaWiki" oor:op="replace"><br />
<prop oor:name="FileFormatVersion"><value>0</value></prop><br />
<prop oor:name="Type"><value>MediaWiki</value></prop><br />
<prop oor:name="DocumentService"><value>com.sun.star.text.TextDocument</value></prop><br />
<prop oor:name="UIComponent"/><br />
<prop oor:name="UserData"><value oor:separator=",">com.sun.star.documentconversion.XSLTFilter,,,com.sun.star.comp.Writer.XMLOasisExporter,,../share/xslt/wiki/odt2mediawiki.xsl</value></prop><br />
<prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop><br />
<prop oor:name="UIName"><br />
<value xml:lang="x-default">MediaWiki</value><br />
</prop><br />
<prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER</value></prop><br />
</node><br />
</source><br />
<br />
{{Documentation/Note|This filter uses the XMLFilterAdaptor service. The "UserData" property is a space-separated list where the first list element denotes the XMLImportFilter to be instantiated and the third one and fourth one are service names of DocumentHandlers for import and export. Further parameters depend on the XMLImportFilter used. }}<br />
<br />
Here the XMLFilter used is the <idl>com.sun.star.documentconversion.XSLTFilter</idl> that bridges to xslt files and basically can import and export if a suitable xslt is provided. It expects the following parameters in the user data ($(APP) stands for Writer,Calc,Draw,Impress,Chart,Math):<br />
<br />
(1) service name of the XSLTFilter<br />
(3) implementation/service name of an importer class (com.sun.star.comp.$(APP).XMLOasisImporter)<br />
(4) implementation/service name of an exporter class (com.sun.star.comp.$(APP).XMLOasisExporter)<br />
(5) relative or absolute path name to an importing style sheet<br />
(6) relative or absolute path name to an importing style sheet<br />
<br />
{{Documentation/Note|Older xslt based filters might have used the pre-ODF file format of {{PRODUCTNAME}}. They used importer and exporter class without "Oasis" in their names.}}<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Office Development]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Talk:Documentation/DevGuide/OfficeDev/Properties_of_a_FilterTalk:Documentation/DevGuide/OfficeDev/Properties of a Filter2016-02-10T16:10:13Z<p>BMarcelly: Explaining my changes</p>
<hr />
<div>It should read (6) relative or absolute path name to an '''exporting''' style sheet?<br />
<br />
The link to [http://api.openoffice.org/docs/common/ref/com/sun/star/documentconversion/XSLTFilter.html]com.sun.star.documentconversion.XSLTFilter is dead.<br />
<br />
<br />
Comment from [[User:BMarcelly|BMarcelly]]<br />
<br />
In rev 2008-10-01T10:49:29, [[User:Mba|Mba]] replaced the Flags content type: <code>Int</code> by: <code>string list</code><br />
<br />
Perhaps Mba wanted to change the API, but this was not done : in year 2016, the type of Flags is still <code>Int</code> and the value is a set of boolean flags. <br />
<br />
In rev 2008-10-01T11:05:57, [[User:Mba|Mba]] replaced the description of flag values by a string, and changed the order of description.<br />
<br />
Since the API does not offer constants for these values, the real values are still needed.<br />
<br />
I have put again the type <code>Int</code> for Flags, and added the values of the flags, found in /aoo-trunk/main/filter/source/config/cache/constant.hxx.</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/FR/Calc/Import_ou_export_via_filtre_XML_ou_XSLTDocumentation/FR/Calc/Import ou export via filtre XML ou XSLT2016-01-15T13:50:56Z<p>BMarcelly: /* Fichier source de l'exemple */</p>
<hr />
<div>[[Image:Editing.png|50px]] Cette page est en PROJET et a besoin de votre [https://forum.openoffice.org/fr/forum/viewtopic.php?f=37&t=41053 participation pour sa rédaction].<br />
<br />
== Introduction ==<br />
(Cette page est la traduction du fil [https://forum.openoffice.org/en/forum/viewtopic.php?t=3490 Create XSLT filters for import and export] dans le forum anglais Apache OpenOffice)<br />
<br />
<br />
Depuis la version 2.x d'OpenOffice, les documents sont enregistrés au format OASIS OpenDocument sous la forme de fichiers XML compressés. En outre OpenOffice supporte également un grand nombre d'autres formats de fichier plus courants comme ceux de la suite Microsoft. Et si tous les formats de fichiers disponibles ne suffisent pas, il y a aussi la possibilité d'ajouter de nouveaux filtres d'importation et d'exportation.<br />
<br />
Dans cet exemple, on vous montre comment créer vos propres filtres d'importation et d'exportation sous Calc.<br />
<br />
== Ressources additionnelles ==<br />
Pour obtenir la liste complète des noms des balises utilisées dans les documents OpenOffice, se référer à la spécification du format XML à la page suivante : http://xml.openoffice.org/.<br />
{{Documentation/Note|Validation du fichier<br />
* Il est conseillé de vérifier les fichiers XSLT avec un outil de validation XSLT avant l'import sous Calc. En effet en cas de problème sur le fichier, OpenOffice affiche un message d'erreur ne comportant aucune information quant à l'origine de l'erreur.}}<br />
<br />
== Les fichiers ==<br />
=== Fichier source de l'exemple === <br />
Pour notre exemple, nous allons utiliser un fichier XML simple avec 4 types de données :<br />
# '''purpose''': un texte simple,<br />
# '''amount''': un nombre avec 2 chiffres après la virgule,<br />
# '''tax''': un nombre avec 4 chiffres après la virgule ( bien que des taxes avec autant de précision soient un peu irréalistes ),<br />
# '''maturity''': une date.<br />
<br />
<br />
Le fichier XML de l'exemple est constitué de plusieurs paiements contenant ces champs. Voici le contenu du fichier :<br />
<br />
<source lang="xml"><br />
<?xml version="1.0"?><br />
<payments><br />
<payment><br />
<purpose>CD</purpose><br />
<amount>12.95</amount><br />
<tax>19.1234</tax><br />
<maturity>2008-03-01</maturity><br />
</payment><br />
<payment><br />
<purpose>DVD</purpose><br />
<amount>19.95</amount><br />
<tax>19.4321</tax><br />
<maturity>2008-03-02</maturity><br />
</payment><br />
<payment><br />
<purpose>Clothes</purpose><br />
<amount>99.95</amount><br />
<tax>18.5678</tax><br />
<maturity>2008-03-03</maturity><br />
</payment><br />
<payment><br />
<purpose>Book</purpose><br />
<amount>9.49</amount><br />
<tax>18.9876</tax><br />
<maturity>2008-03-04</maturity><br />
</payment><br />
</payments><br />
<br />
</source><br />
<br />
Enregistrez le fichier en tant que payments.xml, par exemple dans le dossier C:\Temp<br />
<br />
=== Fichier XML généré à l'aide des filtres ===<br />
Ce fichier est un peu différent. En effet, nous avons ajouté à des fins de démonstration deux éléments '''attribute''' à l'élément racine "payments".<br />
En utilisant <xsl:attribute name="my-attribute-name"><xsl:value-of select="$someValue"/></xsl:attribute> dans le filtre d'export XSLT, il est possible d'ajouter des attributs à tous les éléments.<br />
<br />
<br />
<source lang="xml"><br />
<br />
<?xml version="1.0" encoding="UTF-8"?><br />
<payments export-date="2008-01-01" export-user="hol.sten"><br />
<payment><br />
<purpose>CD</purpose><br />
<amount>12.95</amount><br />
<tax>19.1234</tax><br />
<maturity>2008-03-01</maturity><br />
</payment><br />
<payment><br />
<purpose>DVD</purpose><br />
<amount>19.95</amount><br />
<tax>19.4321</tax><br />
<maturity>2008-03-02</maturity><br />
</payment><br />
<payment><br />
<purpose>Clothes</purpose><br />
<amount>99.95</amount><br />
<tax>18.5678</tax><br />
<maturity>2008-03-03</maturity><br />
</payment><br />
<payment><br />
<purpose>Book</purpose><br />
<amount>9.49</amount><br />
<tax>18.9876</tax><br />
<maturity>2008-03-04</maturity><br />
</payment><br />
</payments><br />
</source><br />
<br />
<br />
== Les filtres ==<br />
=== Filtre d'import XSLT ===<br />
Pour importer le fichier XML d'exemple dans OOo Calc, nous avons besoin d'une feuille de style XSLT. Cette feuille de style créé un fichier XML utilisable par Calc. En voici le code source :<br />
<br />
<source lang="xml"><br />
<br />
<?xml version="1.0" encoding="UTF-8"?><br />
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><br />
<xsl:template match="/"><br />
<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" office:version="1.0"><br />
<br />
<office:automatic-styles><br />
<br />
<!-- Style des colonnes (co1 : 6 cm de largeur, co2: 3 cm de largeur) --><br />
<style:style style:name="co1" style:family="table-column"><br />
<style:table-column-properties fo:break-before="auto" style:column-width="6.000cm"/><br />
</style:style><br />
<style:style style:name="co2" style:family="table-column"><br />
<style:table-column-properties fo:break-before="auto" style:column-width="3.000cm"/><br />
</style:style><br />
<br />
<!-- Format des nombres (N36: date au format JJ.MM.AAAA, N107: nombre à virgule à 4 décimales) --><br />
<number:date-style style:name="N36" number:automatic-order="true"><br />
<number:day number:style="long"/><br />
<number:text>.</number:text><br />
<number:month number:style="long"/><br />
<number:text>.</number:text><br />
<number:year number:style="long"/><br />
</number:date-style><br />
<number:number-style style:name="N107"><br />
<number:number number:decimal-places="4" number:min-integer-digits="1"/><br />
</number:number-style><br />
<br />
<!-- Style des cellules (ce1: alignement à droite, ce2: nombre à 4 décimales, ce3: date) --><br />
<style:style style:name="ce1" style:family="table-cell" style:parent-style-name="Default"><br />
<style:table-cell-properties style:text-align-source="fix" style:repeat-content="false"/><br />
<style:paragraph-properties fo:text-align="end"/><br />
</style:style><br />
<style:style style:name="ce2" style:family="table-cell" style:parent-style-name="Default" style:data-style-name="N107"/><br />
<style:style style:name="ce3" style:family="table-cell" style:parent-style-name="Default" style:data-style-name="N36"/><br />
<br />
</office:automatic-styles><br />
<br />
<office:body><br />
<office:spreadsheet><br />
<table:table><br />
<br />
<!-- Application des formats aux 4 premières colonnes du tableau --><br />
<table:table-column table:style-name="co1" table:default-cell-style-name="Default"/><br />
<table:table-column table:style-name="co2" table:default-cell-style-name="Default"/><br />
<table:table-column table:style-name="co2" table:default-cell-style-name="ce2"/><br />
<table:table-column table:style-name="co2" table:default-cell-style-name="ce3"/><br />
<br />
<!-- Ajouter les en-têtes. Premier en-tête style par défaut, les 3 autres sont alignés à droite --><br />
<table:table-row><br />
<table:table-cell><text:p>Purpose</text:p></table:table-cell><br />
<table:table-cell table:style-name="ce1" office:value-type="string"><text:p>Amount</text:p></table:table-cell><br />
<table:table-cell table:style-name="ce1" office:value-type="string"><text:p>Tax</text:p></table:table-cell><br />
<table:table-cell table:style-name="ce1" office:value-type="string"><text:p>Maturity</text:p></table:table-cell><br />
</table:table-row><br />
<br />
<!-- Traitement de la source XML. Insertion d'une ligne pour chaque paiement --><br />
<xsl:for-each select="payments/payment"><br />
<table:table-row><br />
<br />
<!-- Insertion du champ "purpose" --><br />
<table:table-cell><br />
<text:p><xsl:value-of select="purpose"/></text:p><br />
</table:table-cell><br />
<br />
<!-- Insertion du champ "amount" --><br />
<table:table-cell office:value-type="float"><br />
<xsl:attribute name="office:value"><xsl:value-of select="amount"/></xsl:attribute><br />
<text:p><xsl:value-of select="amount"/></text:p><br />
</table:table-cell><br />
<br />
<!-- Insertion du champ "float" --><br />
<table:table-cell office:value-type="float"><br />
<xsl:attribute name="office:value"><xsl:value-of select="tax"/></xsl:attribute><br />
<text:p><xsl:value-of select="tax"/></text:p><br />
</table:table-cell><br />
<br />
<!-- Insertion du champ "maturity" --><br />
<table:table-cell office:value-type="date"><br />
<xsl:attribute name="office:date-value"><xsl:value-of select="maturity"/></xsl:attribute><br />
<text:p><xsl:value-of select="maturity"/></text:p><br />
</table:table-cell><br />
<br />
</table:table-row><br />
</xsl:for-each><br />
</table:table><br />
</office:spreadsheet><br />
</office:body><br />
</office:document-content><br />
</xsl:template><br />
</xsl:stylesheet><br />
<br />
</source><br />
<br />
=== Filtre d'export XSLT ===<br />
Pour exporter ce fichier d'exemple, nous avons besoin d'une feuille de style XML qui traduise le format Calc.<br />
Voici le code source :<br />
<br />
<source lang="xml"><br />
<br />
<?xmlversion="1.0" encoding="UTF-8"?><br />
<!--Nous devons définir plusieurs espaces de noms car nous utilisons --><br />
<!--le modèle de document du fichier OpenOffice.org en mémoire --><br />
<!--Si nous souhaitons accéder à plus de propriétés du document, --><br />
<!--nous devons ajouter les espaces de noms ici --><br />
<xsl:stylesheetversion="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"<br />
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"<br />
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"<br />
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"<br />
exclude-result-prefixes="officetable text"><br />
<br />
<xsl:outputmethod = "xml" indent = "yes" encoding = "UTF-8"omit-xml-declaration = "no"/><br />
<br />
<!--En spécifiant la PropertyValue 'URL' dans les propriétés destoreToURL(), --><br />
<!--nous pouvons passer un unique paramètre à cette feuille de style. --><br />
<!--Inconvénient : si nous utilisons la propriété 'URL' dans la feuille de style --><br />
<!--et que nous l'appelons depuis OOo par le menu« Fichiers » > « Exporter ... », --><br />
<!--OOodéfini une URL de destination. Ce n'est pas forcément ce que nous souhaitons. --><br />
<xsl:paramname="targetURL"/><br />
<br />
<xsl:variablename="exportDate"><br />
<xsl:choose><br />
<xsl:whentest="string-length(substring-before($targetURL,';'))=10"><br />
<xsl:value-ofselect="substring-before($targetURL,';')"/><br />
</xsl:when><br />
<xsl:whentest="string-length($targetURL)=10"><br />
<xsl:value-ofselect="$targetURL"/><br />
</xsl:when><br />
</xsl:choose><br />
</xsl:variable><br />
<br />
<xsl:variablename="exportUser"><br />
<xsl:iftest="string-length(substring-after($targetURL,';'))>0"><br />
<xsl:value-ofselect="substring-after($targetURL,';')"/><br />
</xsl:if><br />
</xsl:variable><br />
<br />
<!--Traitement du document OOo --><br />
<xsl:templatematch="/"> <payments> <xsl:attributename="export-date"><xsl:value-ofselect="$exportDate"/></xsl:attribute> <xsl:attributename="export-user"><xsl:value-ofselect="$exportUser"/></xsl:attribute> <!--Traitementde tout le tableau--> <xsl:apply-templatesselect="//table:table"/> </payments></xsl:template><br />
<payments><br />
<xsl:attributename="export-date"><xsl:value-ofselect="$exportDate"/></xsl:attribute><br />
<xsl:attributename="export-user"><xsl:value-ofselect="$exportUser"/></xsl:attribute><br />
<!--Process all tables --><br />
<xsl:apply-templatesselect="//table:table"/><br />
</payments><br />
</xsl:template></xsl:stylesheet><br />
<br />
</source><br />
<br />
== Utilisation des filtres ==<br />
=== Installation des filtres XSLT ===<br />
Pour installer les filtres, voici la marche à suivre :<br />
# Allez dans "Outils" > "Paramétrage des filtres XML..."<br />
# Cliquez "Nouveau..."<br />
# Dans l'onglet "Général", renseignez le champ "Nom du filtre" avec "Calc_payments", choississez "Calc" pour le champ "Application", entrez "Payments" dans le champ "Nom du type de fichier", ne modifiez pas le champ "Extension de fichier"<br />
# Dans l'onglet "Transformation", sélectionnez les filtres XSLT créés précédemment en tant que filtres "XSLT pour export" et "XSLT pour import".<br />
# C'est fini, vous n'avez plus qu'à cliquer sur "OK".<br />
<br />
=== Utiliser les filtres XSLT depuis le menu OOo ===<br />
Pour importer le fichier source XML de l'exemple, faites ceci :<br />
# Allez dans "Fichiers" > "Ouvrir..."<br />
# Allez dans le dossier où est enregistré le fichier '''payments.xml'''<br />
# Choississez le type de fichier "Payments (*.xml)" ou "Tous les fichiers"<br />
# Sélectionnez le fichier '''payments.xml'''<br />
# Cliquez sur "Ouvrir".<br />
<br />
Si tout s'est bien passé, vous devriez voir 4 colonnes avec en-têtes et 4 enregistrement.<br />
<br />
Maintenant, ajoutez un cinquième enregistrement à la suite. <br />
<br />
Vous pouvez exporter les enregistrements à l'aide de la boite de dialogue "Fichiers" > "Enregistrer sous...". Il suffit de choisir "Payments (*.xml)" comme type de fichier au moment de l'enregistrement.<br />
<br />
=== Utiliser les filtres XSLT depuis OOo Basic ===<br />
<br />
Voici une simple macro en OOo Basic pour importer l'exemple de fichier XML payments:<br />
<source lang="oobas"><br />
REM ***** BASIC *****<br />
<br />
Sub Main<br />
<br />
rem -------------------------------------------------------<br />
rem - Init import URL<br />
dim xmlurl as string<br />
xmlurl = "file:///C:/Temp/payments.xml"<br />
<br />
rem -------------------------------------------------------<br />
rem - Import payments<br />
dim properties(0) as new com.sun.star.beans.PropertyValue<br />
properties(0).Name = "FilterName"<br />
properties(0).Value = "Calc_Payments"<br />
<br />
dim doc As Object<br />
doc = StarDesktop.loadComponentFromURL(xmlurl, "_blank", 0, properties())<br />
<br />
End Sub<br />
</source><br />
<br />
On peut aussi exporter le fichier XML payments avec un script OOo. Une macro OOo Basic simple pour exporter se présente ainsi:<br />
<source lang="oobas"><br />
REM ***** BASIC *****<br />
<br />
Sub Main<br />
<br />
rem -------------------------------------------------------<br />
rem - Get access to the document<br />
dim document as object<br />
document = ThisComponent<br />
<br />
rem -------------------------------------------------------<br />
rem - Init export URL<br />
dim xmlurl as string<br />
xmlurl = "file:///C:/Temp/payments-export.xml"<br />
<br />
rem -------------------------------------------------------<br />
rem - Export payments<br />
dim properties(5) as new com.sun.star.beans.PropertyValue<br />
properties(0).Name = "FilterName"<br />
properties(0).Value = "Calc_Payments"<br />
properties(1).Name = "URL"<br />
properties(1).Value = xmlurl<br />
document.storeToURL(xmlurl, properties())<br />
<br />
End Sub<br />
</source><br />
<br />
== Références ==<br />
# [https://www.openoffice.org/xml/filter/ OpenOffice.org filters using the XML based file format]<br />
# [https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=office#technical OASIS OpenDocument file format]<br />
# [https://wiki.openoffice.org/wiki/Xml#Filters_and_Conversions_based_on_OpenDocument.2FOpenOffice.org_XML Filters and Conversions based on OpenDocument/OpenOffice.org XML]<br />
<br />
<br />
[[Category:FR]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/FR/Calc/Import_ou_export_via_filtre_XML_ou_XSLTDocumentation/FR/Calc/Import ou export via filtre XML ou XSLT2016-01-15T13:45:20Z<p>BMarcelly: /* Côté programmation Basic */ added Basic examples and References</p>
<hr />
<div>[[Image:Editing.png|50px]] Cette page est en PROJET et a besoin de votre [https://forum.openoffice.org/fr/forum/viewtopic.php?f=37&t=41053 participation pour sa rédaction].<br />
<br />
== Introduction ==<br />
(Cette page est la traduction du fil [https://forum.openoffice.org/en/forum/viewtopic.php?t=3490 Create XSLT filters for import and export] dans le forum anglais Apache OpenOffice)<br />
<br />
<br />
Depuis la version 2.x d'OpenOffice, les documents sont enregistrés au format OASIS OpenDocument sous la forme de fichiers XML compressés. En outre OpenOffice supporte également un grand nombre d'autres formats de fichier plus courants comme ceux de la suite Microsoft. Et si tous les formats de fichiers disponibles ne suffisent pas, il y a aussi la possibilité d'ajouter de nouveaux filtres d'importation et d'exportation.<br />
<br />
Dans cet exemple, on vous montre comment créer vos propres filtres d'importation et d'exportation sous Calc.<br />
<br />
== Ressources additionnelles ==<br />
Pour obtenir la liste complète des noms des balises utilisées dans les documents OpenOffice, se référer à la spécification du format XML à la page suivante : http://xml.openoffice.org/.<br />
{{Documentation/Note|Validation du fichier<br />
* Il est conseillé de vérifier les fichiers XSLT avec un outil de validation XSLT avant l'import sous Calc. En effet en cas de problème sur le fichier, OpenOffice affiche un message d'erreur ne comportant aucune information quant à l'origine de l'erreur.}}<br />
<br />
== Les fichiers ==<br />
=== Fichier source de l'exemple === <br />
Pour notre exemple, nous allons utiliser un fichier XML simple avec 4 types de données :<br />
- purpose, du texte simple,<br />
- amount, un nombre avec 2 chiffres après la virgule,<br />
- tax, un nombre avec 4 chiffres après la virgule ( bien que des taxes avec autant de précision soient un peu irréalistes ),<br />
- maturity, une date.<br />
<br />
<br />
Le fichier XML de l'exemple est constitué de plusieurs paiements contenant ces champs. Voici le contenu du fichier :<br />
<br />
<source lang="xml"><br />
<?xml version="1.0"?><br />
<payments><br />
<payment><br />
<purpose>CD</purpose><br />
<amount>12.95</amount><br />
<tax>19.1234</tax><br />
<maturity>2008-03-01</maturity><br />
</payment><br />
<payment><br />
<purpose>DVD</purpose><br />
<amount>19.95</amount><br />
<tax>19.4321</tax><br />
<maturity>2008-03-02</maturity><br />
</payment><br />
<payment><br />
<purpose>Clothes</purpose><br />
<amount>99.95</amount><br />
<tax>18.5678</tax><br />
<maturity>2008-03-03</maturity><br />
</payment><br />
<payment><br />
<purpose>Book</purpose><br />
<amount>9.49</amount><br />
<tax>18.9876</tax><br />
<maturity>2008-03-04</maturity><br />
</payment><br />
</payments><br />
<br />
</source><br />
<br />
Enregistrez le fichier en tant que payments.xml, par exemple dans le dossier C:\Temp<br />
<br />
=== Fichier XML généré à l'aide des filtres ===<br />
Ce fichier est un peu différent. En effet, nous avons ajouté à des fins de démonstration deux éléments '''attribute''' à l'élément racine "payments".<br />
En utilisant <xsl:attribute name="my-attribute-name"><xsl:value-of select="$someValue"/></xsl:attribute> dans le filtre d'export XSLT, il est possible d'ajouter des attributs à tous les éléments.<br />
<br />
<br />
<source lang="xml"><br />
<br />
<?xml version="1.0" encoding="UTF-8"?><br />
<payments export-date="2008-01-01" export-user="hol.sten"><br />
<payment><br />
<purpose>CD</purpose><br />
<amount>12.95</amount><br />
<tax>19.1234</tax><br />
<maturity>2008-03-01</maturity><br />
</payment><br />
<payment><br />
<purpose>DVD</purpose><br />
<amount>19.95</amount><br />
<tax>19.4321</tax><br />
<maturity>2008-03-02</maturity><br />
</payment><br />
<payment><br />
<purpose>Clothes</purpose><br />
<amount>99.95</amount><br />
<tax>18.5678</tax><br />
<maturity>2008-03-03</maturity><br />
</payment><br />
<payment><br />
<purpose>Book</purpose><br />
<amount>9.49</amount><br />
<tax>18.9876</tax><br />
<maturity>2008-03-04</maturity><br />
</payment><br />
</payments><br />
</source><br />
<br />
<br />
== Les filtres ==<br />
=== Filtre d'import XSLT ===<br />
Pour importer le fichier XML d'exemple dans OOo Calc, nous avons besoin d'une feuille de style XSLT. Cette feuille de style créé un fichier XML utilisable par Calc. En voici le code source :<br />
<br />
<source lang="xml"><br />
<br />
<?xml version="1.0" encoding="UTF-8"?><br />
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><br />
<xsl:template match="/"><br />
<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" office:version="1.0"><br />
<br />
<office:automatic-styles><br />
<br />
<!-- Style des colonnes (co1 : 6 cm de largeur, co2: 3 cm de largeur) --><br />
<style:style style:name="co1" style:family="table-column"><br />
<style:table-column-properties fo:break-before="auto" style:column-width="6.000cm"/><br />
</style:style><br />
<style:style style:name="co2" style:family="table-column"><br />
<style:table-column-properties fo:break-before="auto" style:column-width="3.000cm"/><br />
</style:style><br />
<br />
<!-- Format des nombres (N36: date au format JJ.MM.AAAA, N107: nombre à virgule à 4 décimales) --><br />
<number:date-style style:name="N36" number:automatic-order="true"><br />
<number:day number:style="long"/><br />
<number:text>.</number:text><br />
<number:month number:style="long"/><br />
<number:text>.</number:text><br />
<number:year number:style="long"/><br />
</number:date-style><br />
<number:number-style style:name="N107"><br />
<number:number number:decimal-places="4" number:min-integer-digits="1"/><br />
</number:number-style><br />
<br />
<!-- Style des cellules (ce1: alignement à droite, ce2: nombre à 4 décimales, ce3: date) --><br />
<style:style style:name="ce1" style:family="table-cell" style:parent-style-name="Default"><br />
<style:table-cell-properties style:text-align-source="fix" style:repeat-content="false"/><br />
<style:paragraph-properties fo:text-align="end"/><br />
</style:style><br />
<style:style style:name="ce2" style:family="table-cell" style:parent-style-name="Default" style:data-style-name="N107"/><br />
<style:style style:name="ce3" style:family="table-cell" style:parent-style-name="Default" style:data-style-name="N36"/><br />
<br />
</office:automatic-styles><br />
<br />
<office:body><br />
<office:spreadsheet><br />
<table:table><br />
<br />
<!-- Application des formats aux 4 premières colonnes du tableau --><br />
<table:table-column table:style-name="co1" table:default-cell-style-name="Default"/><br />
<table:table-column table:style-name="co2" table:default-cell-style-name="Default"/><br />
<table:table-column table:style-name="co2" table:default-cell-style-name="ce2"/><br />
<table:table-column table:style-name="co2" table:default-cell-style-name="ce3"/><br />
<br />
<!-- Ajouter les en-têtes. Premier en-tête style par défaut, les 3 autres sont alignés à droite --><br />
<table:table-row><br />
<table:table-cell><text:p>Purpose</text:p></table:table-cell><br />
<table:table-cell table:style-name="ce1" office:value-type="string"><text:p>Amount</text:p></table:table-cell><br />
<table:table-cell table:style-name="ce1" office:value-type="string"><text:p>Tax</text:p></table:table-cell><br />
<table:table-cell table:style-name="ce1" office:value-type="string"><text:p>Maturity</text:p></table:table-cell><br />
</table:table-row><br />
<br />
<!-- Traitement de la source XML. Insertion d'une ligne pour chaque paiement --><br />
<xsl:for-each select="payments/payment"><br />
<table:table-row><br />
<br />
<!-- Insertion du champ "purpose" --><br />
<table:table-cell><br />
<text:p><xsl:value-of select="purpose"/></text:p><br />
</table:table-cell><br />
<br />
<!-- Insertion du champ "amount" --><br />
<table:table-cell office:value-type="float"><br />
<xsl:attribute name="office:value"><xsl:value-of select="amount"/></xsl:attribute><br />
<text:p><xsl:value-of select="amount"/></text:p><br />
</table:table-cell><br />
<br />
<!-- Insertion du champ "float" --><br />
<table:table-cell office:value-type="float"><br />
<xsl:attribute name="office:value"><xsl:value-of select="tax"/></xsl:attribute><br />
<text:p><xsl:value-of select="tax"/></text:p><br />
</table:table-cell><br />
<br />
<!-- Insertion du champ "maturity" --><br />
<table:table-cell office:value-type="date"><br />
<xsl:attribute name="office:date-value"><xsl:value-of select="maturity"/></xsl:attribute><br />
<text:p><xsl:value-of select="maturity"/></text:p><br />
</table:table-cell><br />
<br />
</table:table-row><br />
</xsl:for-each><br />
</table:table><br />
</office:spreadsheet><br />
</office:body><br />
</office:document-content><br />
</xsl:template><br />
</xsl:stylesheet><br />
<br />
</source><br />
<br />
=== Filtre d'export XSLT ===<br />
Pour exporter ce fichier d'exemple, nous avons besoin d'une feuille de style XML qui traduise le format Calc.<br />
Voici le code source :<br />
<br />
<source lang="xml"><br />
<br />
<?xmlversion="1.0" encoding="UTF-8"?><br />
<!--Nous devons définir plusieurs espaces de noms car nous utilisons --><br />
<!--le modèle de document du fichier OpenOffice.org en mémoire --><br />
<!--Si nous souhaitons accéder à plus de propriétés du document, --><br />
<!--nous devons ajouter les espaces de noms ici --><br />
<xsl:stylesheetversion="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"<br />
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"<br />
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"<br />
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"<br />
exclude-result-prefixes="officetable text"><br />
<br />
<xsl:outputmethod = "xml" indent = "yes" encoding = "UTF-8"omit-xml-declaration = "no"/><br />
<br />
<!--En spécifiant la PropertyValue 'URL' dans les propriétés destoreToURL(), --><br />
<!--nous pouvons passer un unique paramètre à cette feuille de style. --><br />
<!--Inconvénient : si nous utilisons la propriété 'URL' dans la feuille de style --><br />
<!--et que nous l'appelons depuis OOo par le menu« Fichiers » > « Exporter ... », --><br />
<!--OOodéfini une URL de destination. Ce n'est pas forcément ce que nous souhaitons. --><br />
<xsl:paramname="targetURL"/><br />
<br />
<xsl:variablename="exportDate"><br />
<xsl:choose><br />
<xsl:whentest="string-length(substring-before($targetURL,';'))=10"><br />
<xsl:value-ofselect="substring-before($targetURL,';')"/><br />
</xsl:when><br />
<xsl:whentest="string-length($targetURL)=10"><br />
<xsl:value-ofselect="$targetURL"/><br />
</xsl:when><br />
</xsl:choose><br />
</xsl:variable><br />
<br />
<xsl:variablename="exportUser"><br />
<xsl:iftest="string-length(substring-after($targetURL,';'))>0"><br />
<xsl:value-ofselect="substring-after($targetURL,';')"/><br />
</xsl:if><br />
</xsl:variable><br />
<br />
<!--Traitement du document OOo --><br />
<xsl:templatematch="/"> <payments> <xsl:attributename="export-date"><xsl:value-ofselect="$exportDate"/></xsl:attribute> <xsl:attributename="export-user"><xsl:value-ofselect="$exportUser"/></xsl:attribute> <!--Traitementde tout le tableau--> <xsl:apply-templatesselect="//table:table"/> </payments></xsl:template><br />
<payments><br />
<xsl:attributename="export-date"><xsl:value-ofselect="$exportDate"/></xsl:attribute><br />
<xsl:attributename="export-user"><xsl:value-ofselect="$exportUser"/></xsl:attribute><br />
<!--Process all tables --><br />
<xsl:apply-templatesselect="//table:table"/><br />
</payments><br />
</xsl:template></xsl:stylesheet><br />
<br />
</source><br />
<br />
== Utilisation des filtres ==<br />
=== Installation des filtres XSLT ===<br />
Pour installer les filtres, voici la marche à suivre :<br />
# Allez dans "Outils" > "Paramétrage des filtres XML..."<br />
# Cliquez "Nouveau..."<br />
# Dans l'onglet "Général", renseignez le champ "Nom du filtre" avec "Calc_payments", choississez "Calc" pour le champ "Application", entrez "Payments" dans le champ "Nom du type de fichier", ne modifiez pas le champ "Extension de fichier"<br />
# Dans l'onglet "Transformation", sélectionnez les filtres XSLT créés précédemment en tant que filtres "XSLT pour export" et "XSLT pour import".<br />
# C'est fini, vous n'avez plus qu'à cliquer sur "OK".<br />
<br />
=== Utiliser les filtres XSLT depuis le menu OOo ===<br />
Pour importer le fichier source XML de l'exemple, faites ceci :<br />
# Allez dans "Fichiers" > "Ouvrir..."<br />
# Allez dans le dossier où est enregistré le fichier '''payments.xml'''<br />
# Choississez le type de fichier "Payments (*.xml)" ou "Tous les fichiers"<br />
# Sélectionnez le fichier '''payments.xml'''<br />
# Cliquez sur "Ouvrir".<br />
<br />
Si tout s'est bien passé, vous devriez voir 4 colonnes avec en-têtes et 4 enregistrement.<br />
<br />
Maintenant, ajoutez un cinquième enregistrement à la suite. <br />
<br />
Vous pouvez exporter les enregistrements à l'aide de la boite de dialogue "Fichiers" > "Enregistrer sous...". Il suffit de choisir "Payments (*.xml)" comme type de fichier au moment de l'enregistrement.<br />
<br />
=== Utiliser les filtres XSLT depuis OOo Basic ===<br />
<br />
Voici une simple macro en OOo Basic pour importer l'exemple de fichier XML payments:<br />
<source lang="oobas"><br />
REM ***** BASIC *****<br />
<br />
Sub Main<br />
<br />
rem -------------------------------------------------------<br />
rem - Init import URL<br />
dim xmlurl as string<br />
xmlurl = "file:///C:/Temp/payments.xml"<br />
<br />
rem -------------------------------------------------------<br />
rem - Import payments<br />
dim properties(0) as new com.sun.star.beans.PropertyValue<br />
properties(0).Name = "FilterName"<br />
properties(0).Value = "Calc_Payments"<br />
<br />
dim doc As Object<br />
doc = StarDesktop.loadComponentFromURL(xmlurl, "_blank", 0, properties())<br />
<br />
End Sub<br />
</source><br />
<br />
On peut aussi exporter le fichier XML payments avec un script OOo. Une macro OOo Basic simple pour exporter se présente ainsi:<br />
<source lang="oobas"><br />
REM ***** BASIC *****<br />
<br />
Sub Main<br />
<br />
rem -------------------------------------------------------<br />
rem - Get access to the document<br />
dim document as object<br />
document = ThisComponent<br />
<br />
rem -------------------------------------------------------<br />
rem - Init export URL<br />
dim xmlurl as string<br />
xmlurl = "file:///C:/Temp/payments-export.xml"<br />
<br />
rem -------------------------------------------------------<br />
rem - Export payments<br />
dim properties(5) as new com.sun.star.beans.PropertyValue<br />
properties(0).Name = "FilterName"<br />
properties(0).Value = "Calc_Payments"<br />
properties(1).Name = "URL"<br />
properties(1).Value = xmlurl<br />
document.storeToURL(xmlurl, properties())<br />
<br />
End Sub<br />
</source><br />
<br />
== Références ==<br />
# [https://www.openoffice.org/xml/filter/ OpenOffice.org filters using the XML based file format]<br />
# [https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=office#technical OASIS OpenDocument file format]<br />
# [https://wiki.openoffice.org/wiki/Xml#Filters_and_Conversions_based_on_OpenDocument.2FOpenOffice.org_XML Filters and Conversions based on OpenDocument/OpenOffice.org XML]<br />
<br />
<br />
[[Category:FR]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/FR/Calc/Import_ou_export_via_filtre_XML_ou_XSLTDocumentation/FR/Calc/Import ou export via filtre XML ou XSLT2016-01-15T13:29:18Z<p>BMarcelly: /* Appel des filtres avec les menus OOo */</p>
<hr />
<div>[[Image:Editing.png|50px]] Cette page est en PROJET et a besoin de votre [https://forum.openoffice.org/fr/forum/viewtopic.php?f=37&t=41053 participation pour sa rédaction].<br />
<br />
== Introduction ==<br />
(Cette page est la traduction du fil [https://forum.openoffice.org/en/forum/viewtopic.php?t=3490 Create XSLT filters for import and export] dans le forum anglais Apache OpenOffice)<br />
<br />
<br />
Depuis la version 2.x d'OpenOffice, les documents sont enregistrés au format OASIS OpenDocument sous la forme de fichiers XML compressés. En outre OpenOffice supporte également un grand nombre d'autres formats de fichier plus courants comme ceux de la suite Microsoft. Et si tous les formats de fichiers disponibles ne suffisent pas, il y a aussi la possibilité d'ajouter de nouveaux filtres d'importation et d'exportation.<br />
<br />
Dans cet exemple, on vous montre comment créer vos propres filtres d'importation et d'exportation sous Calc.<br />
<br />
== Ressources additionnelles ==<br />
Pour obtenir la liste complète des noms des balises utilisées dans les documents OpenOffice, se référer à la spécification du format XML à la page suivante : http://xml.openoffice.org/.<br />
{{Documentation/Note|Validation du fichier<br />
* Il est conseillé de vérifier les fichiers XSLT avec un outil de validation XSLT avant l'import sous Calc. En effet en cas de problème sur le fichier, OpenOffice affiche un message d'erreur ne comportant aucune information quant à l'origine de l'erreur.}}<br />
<br />
== Les fichiers ==<br />
=== Fichier source de l'exemple === <br />
Pour notre exemple, nous allons utiliser un fichier XML simple avec 4 types de données :<br />
- purpose, du texte simple,<br />
- amount, un nombre avec 2 chiffres après la virgule,<br />
- tax, un nombre avec 4 chiffres après la virgule ( bien que des taxes avec autant de précision soient un peu irréalistes ),<br />
- maturity, une date.<br />
<br />
<br />
Le fichier XML de l'exemple est constitué de plusieurs paiements contenant ces champs. Voici le contenu du fichier :<br />
<br />
<source lang="xml"><br />
<?xml version="1.0"?><br />
<payments><br />
<payment><br />
<purpose>CD</purpose><br />
<amount>12.95</amount><br />
<tax>19.1234</tax><br />
<maturity>2008-03-01</maturity><br />
</payment><br />
<payment><br />
<purpose>DVD</purpose><br />
<amount>19.95</amount><br />
<tax>19.4321</tax><br />
<maturity>2008-03-02</maturity><br />
</payment><br />
<payment><br />
<purpose>Clothes</purpose><br />
<amount>99.95</amount><br />
<tax>18.5678</tax><br />
<maturity>2008-03-03</maturity><br />
</payment><br />
<payment><br />
<purpose>Book</purpose><br />
<amount>9.49</amount><br />
<tax>18.9876</tax><br />
<maturity>2008-03-04</maturity><br />
</payment><br />
</payments><br />
<br />
</source><br />
<br />
Enregistrez le fichier en tant que payments.xml, par exemple dans le dossier C:\Temp<br />
<br />
=== Fichier XML généré à l'aide des filtres ===<br />
Ce fichier est un peu différent. En effet, nous avons ajouté à des fins de démonstration deux éléments '''attribute''' à l'élément racine "payments".<br />
En utilisant <xsl:attribute name="my-attribute-name"><xsl:value-of select="$someValue"/></xsl:attribute> dans le filtre d'export XSLT, il est possible d'ajouter des attributs à tous les éléments.<br />
<br />
<br />
<source lang="xml"><br />
<br />
<?xml version="1.0" encoding="UTF-8"?><br />
<payments export-date="2008-01-01" export-user="hol.sten"><br />
<payment><br />
<purpose>CD</purpose><br />
<amount>12.95</amount><br />
<tax>19.1234</tax><br />
<maturity>2008-03-01</maturity><br />
</payment><br />
<payment><br />
<purpose>DVD</purpose><br />
<amount>19.95</amount><br />
<tax>19.4321</tax><br />
<maturity>2008-03-02</maturity><br />
</payment><br />
<payment><br />
<purpose>Clothes</purpose><br />
<amount>99.95</amount><br />
<tax>18.5678</tax><br />
<maturity>2008-03-03</maturity><br />
</payment><br />
<payment><br />
<purpose>Book</purpose><br />
<amount>9.49</amount><br />
<tax>18.9876</tax><br />
<maturity>2008-03-04</maturity><br />
</payment><br />
</payments><br />
</source><br />
<br />
<br />
== Les filtres ==<br />
=== Filtre d'import XSLT ===<br />
Pour importer le fichier XML d'exemple dans OOo Calc, nous avons besoin d'une feuille de style XSLT. Cette feuille de style créé un fichier XML utilisable par Calc. En voici le code source :<br />
<br />
<source lang="xml"><br />
<br />
<?xml version="1.0" encoding="UTF-8"?><br />
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><br />
<xsl:template match="/"><br />
<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" office:version="1.0"><br />
<br />
<office:automatic-styles><br />
<br />
<!-- Style des colonnes (co1 : 6 cm de largeur, co2: 3 cm de largeur) --><br />
<style:style style:name="co1" style:family="table-column"><br />
<style:table-column-properties fo:break-before="auto" style:column-width="6.000cm"/><br />
</style:style><br />
<style:style style:name="co2" style:family="table-column"><br />
<style:table-column-properties fo:break-before="auto" style:column-width="3.000cm"/><br />
</style:style><br />
<br />
<!-- Format des nombres (N36: date au format JJ.MM.AAAA, N107: nombre à virgule à 4 décimales) --><br />
<number:date-style style:name="N36" number:automatic-order="true"><br />
<number:day number:style="long"/><br />
<number:text>.</number:text><br />
<number:month number:style="long"/><br />
<number:text>.</number:text><br />
<number:year number:style="long"/><br />
</number:date-style><br />
<number:number-style style:name="N107"><br />
<number:number number:decimal-places="4" number:min-integer-digits="1"/><br />
</number:number-style><br />
<br />
<!-- Style des cellules (ce1: alignement à droite, ce2: nombre à 4 décimales, ce3: date) --><br />
<style:style style:name="ce1" style:family="table-cell" style:parent-style-name="Default"><br />
<style:table-cell-properties style:text-align-source="fix" style:repeat-content="false"/><br />
<style:paragraph-properties fo:text-align="end"/><br />
</style:style><br />
<style:style style:name="ce2" style:family="table-cell" style:parent-style-name="Default" style:data-style-name="N107"/><br />
<style:style style:name="ce3" style:family="table-cell" style:parent-style-name="Default" style:data-style-name="N36"/><br />
<br />
</office:automatic-styles><br />
<br />
<office:body><br />
<office:spreadsheet><br />
<table:table><br />
<br />
<!-- Application des formats aux 4 premières colonnes du tableau --><br />
<table:table-column table:style-name="co1" table:default-cell-style-name="Default"/><br />
<table:table-column table:style-name="co2" table:default-cell-style-name="Default"/><br />
<table:table-column table:style-name="co2" table:default-cell-style-name="ce2"/><br />
<table:table-column table:style-name="co2" table:default-cell-style-name="ce3"/><br />
<br />
<!-- Ajouter les en-têtes. Premier en-tête style par défaut, les 3 autres sont alignés à droite --><br />
<table:table-row><br />
<table:table-cell><text:p>Purpose</text:p></table:table-cell><br />
<table:table-cell table:style-name="ce1" office:value-type="string"><text:p>Amount</text:p></table:table-cell><br />
<table:table-cell table:style-name="ce1" office:value-type="string"><text:p>Tax</text:p></table:table-cell><br />
<table:table-cell table:style-name="ce1" office:value-type="string"><text:p>Maturity</text:p></table:table-cell><br />
</table:table-row><br />
<br />
<!-- Traitement de la source XML. Insertion d'une ligne pour chaque paiement --><br />
<xsl:for-each select="payments/payment"><br />
<table:table-row><br />
<br />
<!-- Insertion du champ "purpose" --><br />
<table:table-cell><br />
<text:p><xsl:value-of select="purpose"/></text:p><br />
</table:table-cell><br />
<br />
<!-- Insertion du champ "amount" --><br />
<table:table-cell office:value-type="float"><br />
<xsl:attribute name="office:value"><xsl:value-of select="amount"/></xsl:attribute><br />
<text:p><xsl:value-of select="amount"/></text:p><br />
</table:table-cell><br />
<br />
<!-- Insertion du champ "float" --><br />
<table:table-cell office:value-type="float"><br />
<xsl:attribute name="office:value"><xsl:value-of select="tax"/></xsl:attribute><br />
<text:p><xsl:value-of select="tax"/></text:p><br />
</table:table-cell><br />
<br />
<!-- Insertion du champ "maturity" --><br />
<table:table-cell office:value-type="date"><br />
<xsl:attribute name="office:date-value"><xsl:value-of select="maturity"/></xsl:attribute><br />
<text:p><xsl:value-of select="maturity"/></text:p><br />
</table:table-cell><br />
<br />
</table:table-row><br />
</xsl:for-each><br />
</table:table><br />
</office:spreadsheet><br />
</office:body><br />
</office:document-content><br />
</xsl:template><br />
</xsl:stylesheet><br />
<br />
</source><br />
<br />
=== Filtre d'export XSLT ===<br />
Pour exporter ce fichier d'exemple, nous avons besoin d'une feuille de style XML qui traduise le format Calc.<br />
Voici le code source :<br />
<br />
<source lang="xml"><br />
<br />
<?xmlversion="1.0" encoding="UTF-8"?><br />
<!--Nous devons définir plusieurs espaces de noms car nous utilisons --><br />
<!--le modèle de document du fichier OpenOffice.org en mémoire --><br />
<!--Si nous souhaitons accéder à plus de propriétés du document, --><br />
<!--nous devons ajouter les espaces de noms ici --><br />
<xsl:stylesheetversion="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"<br />
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"<br />
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"<br />
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"<br />
exclude-result-prefixes="officetable text"><br />
<br />
<xsl:outputmethod = "xml" indent = "yes" encoding = "UTF-8"omit-xml-declaration = "no"/><br />
<br />
<!--En spécifiant la PropertyValue 'URL' dans les propriétés destoreToURL(), --><br />
<!--nous pouvons passer un unique paramètre à cette feuille de style. --><br />
<!--Inconvénient : si nous utilisons la propriété 'URL' dans la feuille de style --><br />
<!--et que nous l'appelons depuis OOo par le menu« Fichiers » > « Exporter ... », --><br />
<!--OOodéfini une URL de destination. Ce n'est pas forcément ce que nous souhaitons. --><br />
<xsl:paramname="targetURL"/><br />
<br />
<xsl:variablename="exportDate"><br />
<xsl:choose><br />
<xsl:whentest="string-length(substring-before($targetURL,';'))=10"><br />
<xsl:value-ofselect="substring-before($targetURL,';')"/><br />
</xsl:when><br />
<xsl:whentest="string-length($targetURL)=10"><br />
<xsl:value-ofselect="$targetURL"/><br />
</xsl:when><br />
</xsl:choose><br />
</xsl:variable><br />
<br />
<xsl:variablename="exportUser"><br />
<xsl:iftest="string-length(substring-after($targetURL,';'))>0"><br />
<xsl:value-ofselect="substring-after($targetURL,';')"/><br />
</xsl:if><br />
</xsl:variable><br />
<br />
<!--Traitement du document OOo --><br />
<xsl:templatematch="/"> <payments> <xsl:attributename="export-date"><xsl:value-ofselect="$exportDate"/></xsl:attribute> <xsl:attributename="export-user"><xsl:value-ofselect="$exportUser"/></xsl:attribute> <!--Traitementde tout le tableau--> <xsl:apply-templatesselect="//table:table"/> </payments></xsl:template><br />
<payments><br />
<xsl:attributename="export-date"><xsl:value-ofselect="$exportDate"/></xsl:attribute><br />
<xsl:attributename="export-user"><xsl:value-ofselect="$exportUser"/></xsl:attribute><br />
<!--Process all tables --><br />
<xsl:apply-templatesselect="//table:table"/><br />
</payments><br />
</xsl:template></xsl:stylesheet><br />
<br />
</source><br />
<br />
== Utilisation des filtres ==<br />
=== Installation des filtres XSLT ===<br />
Pour installer les filtres, voici la marche à suivre :<br />
# Allez dans "Outils" > "Paramétrage des filtres XML..."<br />
# Cliquez "Nouveau..."<br />
# Dans l'onglet "Général", renseignez le champ "Nom du filtre" avec "Calc_payments", choississez "Calc" pour le champ "Application", entrez "Payments" dans le champ "Nom du type de fichier", ne modifiez pas le champ "Extension de fichier"<br />
# Dans l'onglet "Transformation", sélectionnez les filtres XSLT créés précédemment en tant que filtres "XSLT pour export" et "XSLT pour import".<br />
# C'est fini, vous n'avez plus qu'à cliquer sur "OK".<br />
<br />
=== Utiliser les filtres XSLT depuis le menu OOo ===<br />
Pour importer le fichier source XML de l'exemple, faites ceci :<br />
# Allez dans "Fichiers" > "Ouvrir..."<br />
# Allez dans le dossier où est enregistré le fichier '''payments.xml'''<br />
# Choississez le type de fichier "Payments (*.xml)" ou "Tous les fichiers"<br />
# Sélectionnez le fichier '''payments.xml'''<br />
# Cliquez sur "Ouvrir".<br />
<br />
Si tout s'est bien passé, vous devriez voir 4 colonnes avec en-têtes et 4 enregistrement.<br />
<br />
Maintenant, ajoutez un cinquième enregistrement à la suite. <br />
<br />
Vous pouvez exporter les enregistrements à l'aide de la boite de dialogue "Fichiers" > "Enregistrer sous...". Il suffit de choisir "Payments (*.xml)" comme type de fichier au moment de l'enregistrement.<br />
<br />
== Côté programmation Basic ==<br />
(en attente)<br />
<br />
[[Category:FR]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/FR/Calc/Import_ou_export_via_filtre_XML_ou_XSLTDocumentation/FR/Calc/Import ou export via filtre XML ou XSLT2016-01-15T13:11:26Z<p>BMarcelly: /* Introduction */ added reference to original webpage</p>
<hr />
<div>[[Image:Editing.png|50px]] Cette page est en PROJET et a besoin de votre [https://forum.openoffice.org/fr/forum/viewtopic.php?f=37&t=41053 participation pour sa rédaction].<br />
<br />
== Introduction ==<br />
(Cette page est la traduction du fil [https://forum.openoffice.org/en/forum/viewtopic.php?t=3490 Create XSLT filters for import and export] dans le forum anglais Apache OpenOffice)<br />
<br />
<br />
Depuis la version 2.x d'OpenOffice, les documents sont enregistrés au format OASIS OpenDocument sous la forme de fichiers XML compressés. En outre OpenOffice supporte également un grand nombre d'autres formats de fichier plus courants comme ceux de la suite Microsoft. Et si tous les formats de fichiers disponibles ne suffisent pas, il y a aussi la possibilité d'ajouter de nouveaux filtres d'importation et d'exportation.<br />
<br />
Dans cet exemple, on vous montre comment créer vos propres filtres d'importation et d'exportation sous Calc.<br />
<br />
== Ressources additionnelles ==<br />
Pour obtenir la liste complète des noms des balises utilisées dans les documents OpenOffice, se référer à la spécification du format XML à la page suivante : http://xml.openoffice.org/.<br />
{{Documentation/Note|Validation du fichier<br />
* Il est conseillé de vérifier les fichiers XSLT avec un outil de validation XSLT avant l'import sous Calc. En effet en cas de problème sur le fichier, OpenOffice affiche un message d'erreur ne comportant aucune information quant à l'origine de l'erreur.}}<br />
<br />
== Les fichiers ==<br />
=== Fichier source de l'exemple === <br />
Pour notre exemple, nous allons utiliser un fichier XML simple avec 4 types de données :<br />
- purpose, du texte simple,<br />
- amount, un nombre avec 2 chiffres après la virgule,<br />
- tax, un nombre avec 4 chiffres après la virgule ( bien que des taxes avec autant de précision soient un peu irréalistes ),<br />
- maturity, une date.<br />
<br />
<br />
Le fichier XML de l'exemple est constitué de plusieurs paiements contenant ces champs. Voici le contenu du fichier :<br />
<br />
<source lang="xml"><br />
<?xml version="1.0"?><br />
<payments><br />
<payment><br />
<purpose>CD</purpose><br />
<amount>12.95</amount><br />
<tax>19.1234</tax><br />
<maturity>2008-03-01</maturity><br />
</payment><br />
<payment><br />
<purpose>DVD</purpose><br />
<amount>19.95</amount><br />
<tax>19.4321</tax><br />
<maturity>2008-03-02</maturity><br />
</payment><br />
<payment><br />
<purpose>Clothes</purpose><br />
<amount>99.95</amount><br />
<tax>18.5678</tax><br />
<maturity>2008-03-03</maturity><br />
</payment><br />
<payment><br />
<purpose>Book</purpose><br />
<amount>9.49</amount><br />
<tax>18.9876</tax><br />
<maturity>2008-03-04</maturity><br />
</payment><br />
</payments><br />
<br />
</source><br />
<br />
Enregistrez le fichier en tant que payments.xml, par exemple dans le dossier C:\Temp<br />
<br />
=== Fichier XML généré à l'aide des filtres ===<br />
Ce fichier est un peu différent. En effet, nous avons ajouté à des fins de démonstration deux éléments '''attribute''' à l'élément racine "payments".<br />
En utilisant <xsl:attribute name="my-attribute-name"><xsl:value-of select="$someValue"/></xsl:attribute> dans le filtre d'export XSLT, il est possible d'ajouter des attributs à tous les éléments.<br />
<br />
<br />
<source lang="xml"><br />
<br />
<?xml version="1.0" encoding="UTF-8"?><br />
<payments export-date="2008-01-01" export-user="hol.sten"><br />
<payment><br />
<purpose>CD</purpose><br />
<amount>12.95</amount><br />
<tax>19.1234</tax><br />
<maturity>2008-03-01</maturity><br />
</payment><br />
<payment><br />
<purpose>DVD</purpose><br />
<amount>19.95</amount><br />
<tax>19.4321</tax><br />
<maturity>2008-03-02</maturity><br />
</payment><br />
<payment><br />
<purpose>Clothes</purpose><br />
<amount>99.95</amount><br />
<tax>18.5678</tax><br />
<maturity>2008-03-03</maturity><br />
</payment><br />
<payment><br />
<purpose>Book</purpose><br />
<amount>9.49</amount><br />
<tax>18.9876</tax><br />
<maturity>2008-03-04</maturity><br />
</payment><br />
</payments><br />
</source><br />
<br />
<br />
== Les filtres ==<br />
=== Filtre d'import XSLT ===<br />
Pour importer le fichier XML d'exemple dans OOo Calc, nous avons besoin d'une feuille de style XSLT. Cette feuille de style créé un fichier XML utilisable par Calc. En voici le code source :<br />
<br />
<source lang="xml"><br />
<br />
<?xml version="1.0" encoding="UTF-8"?><br />
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><br />
<xsl:template match="/"><br />
<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" office:version="1.0"><br />
<br />
<office:automatic-styles><br />
<br />
<!-- Style des colonnes (co1 : 6 cm de largeur, co2: 3 cm de largeur) --><br />
<style:style style:name="co1" style:family="table-column"><br />
<style:table-column-properties fo:break-before="auto" style:column-width="6.000cm"/><br />
</style:style><br />
<style:style style:name="co2" style:family="table-column"><br />
<style:table-column-properties fo:break-before="auto" style:column-width="3.000cm"/><br />
</style:style><br />
<br />
<!-- Format des nombres (N36: date au format JJ.MM.AAAA, N107: nombre à virgule à 4 décimales) --><br />
<number:date-style style:name="N36" number:automatic-order="true"><br />
<number:day number:style="long"/><br />
<number:text>.</number:text><br />
<number:month number:style="long"/><br />
<number:text>.</number:text><br />
<number:year number:style="long"/><br />
</number:date-style><br />
<number:number-style style:name="N107"><br />
<number:number number:decimal-places="4" number:min-integer-digits="1"/><br />
</number:number-style><br />
<br />
<!-- Style des cellules (ce1: alignement à droite, ce2: nombre à 4 décimales, ce3: date) --><br />
<style:style style:name="ce1" style:family="table-cell" style:parent-style-name="Default"><br />
<style:table-cell-properties style:text-align-source="fix" style:repeat-content="false"/><br />
<style:paragraph-properties fo:text-align="end"/><br />
</style:style><br />
<style:style style:name="ce2" style:family="table-cell" style:parent-style-name="Default" style:data-style-name="N107"/><br />
<style:style style:name="ce3" style:family="table-cell" style:parent-style-name="Default" style:data-style-name="N36"/><br />
<br />
</office:automatic-styles><br />
<br />
<office:body><br />
<office:spreadsheet><br />
<table:table><br />
<br />
<!-- Application des formats aux 4 premières colonnes du tableau --><br />
<table:table-column table:style-name="co1" table:default-cell-style-name="Default"/><br />
<table:table-column table:style-name="co2" table:default-cell-style-name="Default"/><br />
<table:table-column table:style-name="co2" table:default-cell-style-name="ce2"/><br />
<table:table-column table:style-name="co2" table:default-cell-style-name="ce3"/><br />
<br />
<!-- Ajouter les en-têtes. Premier en-tête style par défaut, les 3 autres sont alignés à droite --><br />
<table:table-row><br />
<table:table-cell><text:p>Purpose</text:p></table:table-cell><br />
<table:table-cell table:style-name="ce1" office:value-type="string"><text:p>Amount</text:p></table:table-cell><br />
<table:table-cell table:style-name="ce1" office:value-type="string"><text:p>Tax</text:p></table:table-cell><br />
<table:table-cell table:style-name="ce1" office:value-type="string"><text:p>Maturity</text:p></table:table-cell><br />
</table:table-row><br />
<br />
<!-- Traitement de la source XML. Insertion d'une ligne pour chaque paiement --><br />
<xsl:for-each select="payments/payment"><br />
<table:table-row><br />
<br />
<!-- Insertion du champ "purpose" --><br />
<table:table-cell><br />
<text:p><xsl:value-of select="purpose"/></text:p><br />
</table:table-cell><br />
<br />
<!-- Insertion du champ "amount" --><br />
<table:table-cell office:value-type="float"><br />
<xsl:attribute name="office:value"><xsl:value-of select="amount"/></xsl:attribute><br />
<text:p><xsl:value-of select="amount"/></text:p><br />
</table:table-cell><br />
<br />
<!-- Insertion du champ "float" --><br />
<table:table-cell office:value-type="float"><br />
<xsl:attribute name="office:value"><xsl:value-of select="tax"/></xsl:attribute><br />
<text:p><xsl:value-of select="tax"/></text:p><br />
</table:table-cell><br />
<br />
<!-- Insertion du champ "maturity" --><br />
<table:table-cell office:value-type="date"><br />
<xsl:attribute name="office:date-value"><xsl:value-of select="maturity"/></xsl:attribute><br />
<text:p><xsl:value-of select="maturity"/></text:p><br />
</table:table-cell><br />
<br />
</table:table-row><br />
</xsl:for-each><br />
</table:table><br />
</office:spreadsheet><br />
</office:body><br />
</office:document-content><br />
</xsl:template><br />
</xsl:stylesheet><br />
<br />
</source><br />
<br />
=== Filtre d'export XSLT ===<br />
Pour exporter ce fichier d'exemple, nous avons besoin d'une feuille de style XML qui traduise le format Calc.<br />
Voici le code source :<br />
<br />
<source lang="xml"><br />
<br />
<?xmlversion="1.0" encoding="UTF-8"?><br />
<!--Nous devons définir plusieurs espaces de noms car nous utilisons --><br />
<!--le modèle de document du fichier OpenOffice.org en mémoire --><br />
<!--Si nous souhaitons accéder à plus de propriétés du document, --><br />
<!--nous devons ajouter les espaces de noms ici --><br />
<xsl:stylesheetversion="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"<br />
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"<br />
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"<br />
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"<br />
exclude-result-prefixes="officetable text"><br />
<br />
<xsl:outputmethod = "xml" indent = "yes" encoding = "UTF-8"omit-xml-declaration = "no"/><br />
<br />
<!--En spécifiant la PropertyValue 'URL' dans les propriétés destoreToURL(), --><br />
<!--nous pouvons passer un unique paramètre à cette feuille de style. --><br />
<!--Inconvénient : si nous utilisons la propriété 'URL' dans la feuille de style --><br />
<!--et que nous l'appelons depuis OOo par le menu« Fichiers » > « Exporter ... », --><br />
<!--OOodéfini une URL de destination. Ce n'est pas forcément ce que nous souhaitons. --><br />
<xsl:paramname="targetURL"/><br />
<br />
<xsl:variablename="exportDate"><br />
<xsl:choose><br />
<xsl:whentest="string-length(substring-before($targetURL,';'))=10"><br />
<xsl:value-ofselect="substring-before($targetURL,';')"/><br />
</xsl:when><br />
<xsl:whentest="string-length($targetURL)=10"><br />
<xsl:value-ofselect="$targetURL"/><br />
</xsl:when><br />
</xsl:choose><br />
</xsl:variable><br />
<br />
<xsl:variablename="exportUser"><br />
<xsl:iftest="string-length(substring-after($targetURL,';'))>0"><br />
<xsl:value-ofselect="substring-after($targetURL,';')"/><br />
</xsl:if><br />
</xsl:variable><br />
<br />
<!--Traitement du document OOo --><br />
<xsl:templatematch="/"> <payments> <xsl:attributename="export-date"><xsl:value-ofselect="$exportDate"/></xsl:attribute> <xsl:attributename="export-user"><xsl:value-ofselect="$exportUser"/></xsl:attribute> <!--Traitementde tout le tableau--> <xsl:apply-templatesselect="//table:table"/> </payments></xsl:template><br />
<payments><br />
<xsl:attributename="export-date"><xsl:value-ofselect="$exportDate"/></xsl:attribute><br />
<xsl:attributename="export-user"><xsl:value-ofselect="$exportUser"/></xsl:attribute><br />
<!--Process all tables --><br />
<xsl:apply-templatesselect="//table:table"/><br />
</payments><br />
</xsl:template></xsl:stylesheet><br />
<br />
</source><br />
<br />
== Utilisation des filtres ==<br />
=== Installation des filtres XSLT ===<br />
Pour installer les filtres, voici la marche à suivre :<br />
# Allez dans "Outils" > "Paramétrage des filtres XML..."<br />
# Cliquez "Nouveau..."<br />
# Dans l'onglet "Général", renseignez le champ "Nom du filtre" avec "Calc_payments", choississez "Calc" pour le champ "Application", entrez "Payments" dans le champ "Nom du type de fichier", ne modifiez pas le champ "Extension de fichier"<br />
# Dans l'onglet "Transformation", sélectionnez les filtres XSLT créés précédemment en tant que filtres "XSLT pour export" et "XSLT pour import".<br />
# C'est fini, vous n'avez plus qu'à cliquer sur "OK".<br />
<br />
=== Appel des filtres avec les menus OOo ===<br />
Pour importer le fichier source XML de l'exemple, faites ceci :<br />
# Allez dans "Fichiers" > "Ouvrir..."<br />
# Allez dans le dossier où est enregistré le fichier '''payments.xml'''<br />
# Choississez le type de fichier "Payments (*.xml)" ou "Tous les fichiers"<br />
# Sélectionnez le fichier '''payments.xml'''<br />
# Cliquez sur "Ouvrir".<br />
<br />
Si tout s'est bien passé, vous devriez voir 4 colonnes avec en-têtes et 4 enregistrement.<br />
<br />
Maintenant, ajoutez un cinquième enregistrement à la suite. <br />
<br />
Vous pouvez exporter les enregistrements à l'aide de la boite de dialogue "Fichiers" > "Enregistrer sous...". Il suffit de choisir "Payments (*.xml)" comme type de fichier au moment de l'enregistrement.<br />
<br />
== Côté programmation Basic ==<br />
(en attente)<br />
<br />
[[Category:FR]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Filter_OptionsDocumentation/DevGuide/Spreadsheets/Filter Options2015-10-18T12:50:08Z<p>BMarcelly: /* Token 8, csv import */</p>
<hr />
<div>{{Documentation/DevGuide/SpreadsheetsTOC<br />
|SpreadsheetDocs2b=block<br />
|SpreadsheetDocsSaving=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/Spreadsheets/Saving Spreadsheet Documents<br />
|NextPage=Documentation/DevGuide/Spreadsheets/Printing Spreadsheet Documents<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/Spreadsheets/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:Filter Options}}<br />
Loading and saving {{PRODUCTNAME}} API documents is described in [[Documentation/DevGuide/OfficeDev/Handling Documents|Handling Documents]]. This section lists all the filter names for spreadsheet documents and describes the filter options for text file import.<br />
<br />
The filter name and options are passed on loading or saving a document in a sequence of <idl>com.sun.star.beans.PropertyValue</idl>s. The property <code>FilterName</code> contains the name and the property <code>FilterOptions</code> contains the filter options.<br />
<br />
{{Documentation/Note|All filter names are case-sensitive. For compatibility reasons the filter names will not be changed. Therefore, some of the filters seem to have "curious" names.}}<br />
<br />
The list of filter names (the last two columns show the possible directions of the filters):<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Filter name <br />
!Description <br />
!Import <br />
!Export <br />
|-<br />
|StarOffice XML (Calc) <br />
|Standard XML filter <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|calc_StarOffice_XML_Calc_Template <br />
|XML filter for templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 5.0 <br />
|The binary format of StarOffice Calc 5.x <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 5.0 Vorlage/Template <br />
|StarOffice Calc 5.x templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 4.0 <br />
|The binary format of StarCalc 4.x <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 4.0 Vorlage/Template <br />
|StarCalc 4.x templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 3.0 <br />
|The binary format of StarCalc 3.x <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 3.0 Vorlage/Template <br />
|StarCalc 3.x templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|HTML (StarCalc) <br />
|HTML filter <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|calc_HTML_WebQuery <br />
|HTML filter for external data queries <br />
|<center>●</center> <br />
| <br />
|-<br />
|MS Excel 97 <br />
|Microsoft Excel 97/2000/XP <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 97 Vorlage/Template <br />
|Microsoft Excel 97/2000/XP templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 95 <br />
|Microsoft Excel 5.0/95 <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 5.0/95 <br />
|Different name for the same filter <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 95 Vorlage/Template <br />
|Microsoft Excel 5.0/95 templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 5.0/95 Vorlage/Template <br />
|Different name for the same filter <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 4.0 <br />
|Microsoft Excel 2.1/3.0/4.0 <br />
|<center>●</center> <br />
| <br />
|-<br />
|MS Excel 4.0 Vorlage/Template <br />
|Microsoft Excel 2.1/3.0/4.0 templates <br />
|<center>●</center> <br />
| <br />
|-<br />
|Lotus <br />
|Lotus 1-2-3 <br />
|<center>●</center> <br />
| <br />
|-<br />
|Text - txt - csv (StarCalc) <br />
|Comma separated values <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|Rich Text Format (StarCalc) <br />
| <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|dBase <br />
| <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|SYLK <br />
|Symbolic Link <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|DIF <br />
|Data Interchange Format <br />
|<center>●</center> <br />
|<center>●</center> <br />
|}<br />
<br />
=== Filter Options for Lotus, dBase and DIF Filters ===<br />
<br />
These filters accept a string containing the numerical index of the used character set for single-byte characters, that is, 0 for the system character set.<br />
<br />
The numerical indexes assigned to the character sets:<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Character Set<br />
!Index<br />
|-<br />
|Unknown<br />
|0<br />
|-<br />
|Windows-1252/WinLatin 1 (Western)<br />
|1<br />
|-<br />
|Apple Macintosh (Western)<br />
|2<br />
|-<br />
|DOS/OS2-437/US (Western)<br />
|3<br />
|-<br />
|DOS/OS2-850/International (Western)<br />
|4<br />
|-<br />
|DOS/OS2-860/Portuguese (Western)<br />
|5<br />
|-<br />
|DOS/OS2-861/Icelandic (Western)<br />
|6<br />
|-<br />
|DOS/OS2-863/Canadian-French (Western)<br />
|7<br />
|-<br />
|DOS/OS2-865/Nordic (Western)<br />
|8<br />
|-<br />
|System default<br />
|9<br />
|-<br />
|Symbol<br />
|10<br />
|-<br />
|ASCII/US (Western)<br />
|11<br />
|-<br />
|ISO-8859-1 (Western)<br />
|12<br />
|-<br />
|ISO-8859-2 (Central European)<br />
|13<br />
|-<br />
|ISO-8859-3 (Latin 3)<br />
|14<br />
|-<br />
|ISO-8859-4 (Baltic)<br />
|15<br />
|-<br />
|ISO-8859-5 (Cyrillic)<br />
|16<br />
|-<br />
|ISO-8859-6 (Arabic)<br />
|17<br />
|-<br />
|ISO-8859-7 (Greek)<br />
|18<br />
|-<br />
|ISO-8859-8 (Hebrew)<br />
|19<br />
|-<br />
|ISO-8859-9 (Turkish)<br />
|20<br />
|-<br />
|ISO-8859-14 (Western)<br />
|21<br />
|-<br />
|ISO-8859-15/EURO (Western)<br />
|22<br />
|-<br />
|DOS/OS2-737 (Greek)<br />
|23<br />
|-<br />
|DOS/OS2-775 (Baltic)<br />
|24<br />
|-<br />
|DOS/OS2-852 (Central European)<br />
|25<br />
|-<br />
|DOS/OS2-855 (Cyrillic)<br />
|26<br />
|-<br />
|DOS/OS2-857 (Turkish)<br />
|27<br />
|-<br />
|DOS/OS2-862 (Hebrew)<br />
|28<br />
|-<br />
|DOS/OS2-864 (Arabic)<br />
|29<br />
|-<br />
|DOS/OS2-866/Russian (Cyrillic)<br />
|30<br />
|-<br />
|DOS/OS2-869/Modern (Greek)<br />
|31<br />
|-<br />
|DOS/Windows-874 (Thai)<br />
|32<br />
|-<br />
|Windows-1250/WinLatin 2 (Central European)<br />
|33<br />
|-<br />
|Windows-1251 (Cyrillic)<br />
|34<br />
|-<br />
|Windows-1253 (Greek)<br />
|35<br />
|-<br />
|Windows-1254 (Turkish)<br />
|36<br />
|-<br />
|Windows-1255 (Hebrew)<br />
|37<br />
|-<br />
|Windows-1256 (Arabic)<br />
|38<br />
|-<br />
|Windows-1257 (Baltic)<br />
|39<br />
|-<br />
|Windows-1258 (Vietnamese)<br />
|40<br />
|-<br />
|Apple Macintosh (Arabic)<br />
|41<br />
|-<br />
|Apple Macintosh (Central European)<br />
|42<br />
|-<br />
|Apple Macintosh/Croatian (Central European)<br />
|43<br />
|-<br />
|Apple Macintosh (Cyrillic)<br />
|44<br />
|-<br />
|''Not supported:'' Apple Macintosh (Devanagari)<br />
|45<br />
|-<br />
|''Not supported:'' Apple Macintosh (Farsi)<br />
|46<br />
|-<br />
|Apple Macintosh (Greek)<br />
|47<br />
|-<br />
|''Not supported:'' Apple Macintosh (Gujarati)<br />
|48<br />
|-<br />
|''Not supported:'' Apple Macintosh (Gurmukhi)<br />
|49<br />
|-<br />
|Apple Macintosh (Hebrew)<br />
|50<br />
|-<br />
|Apple Macintosh/Icelandic (Western)<br />
|51<br />
|-<br />
|Apple Macintosh/Romanian (Central European)<br />
|52<br />
|-<br />
|Apple Macintosh (Thai)<br />
|53<br />
|-<br />
|Apple Macintosh (Turkish)<br />
|54<br />
|-<br />
|Apple Macintosh/Ukrainian (Cyrillic)<br />
|55<br />
|-<br />
|Apple Macintosh (Chinese Simplified)<br />
|56<br />
|-<br />
|Apple Macintosh (Chinese Traditional)<br />
|57<br />
|-<br />
|Apple Macintosh (Japanese)<br />
|58<br />
|-<br />
|Apple Macintosh (Korean)<br />
|59<br />
|-<br />
|Windows-932 (Japanese)<br />
|60<br />
|-<br />
|Windows-936 (Chinese Simplified)<br />
|61<br />
|-<br />
|Windows-Wansung-949 (Korean)<br />
|62<br />
|-<br />
|Windows-950 (Chinese Traditional)<br />
|63<br />
|-<br />
|Shift-JIS (Japanese)<br />
|64<br />
|-<br />
|GB-2312 (Chinese Simplified)<br />
|65<br />
|-<br />
|GBT-12345 (Chinese Traditional)<br />
|66<br />
|-<br />
|GBK/GB-2312-80 (Chinese Simplified)<br />
|67<br />
|-<br />
|BIG5 (Chinese Traditional)<br />
|68<br />
|-<br />
|EUC-JP (Japanese)<br />
|69<br />
|-<br />
|EUC-CN (Chinese Simplified)<br />
|70<br />
|-<br />
|EUC-TW (Chinese Traditional)<br />
|71<br />
|-<br />
|ISO-2022-JP (Japanese)<br />
|72<br />
|-<br />
|ISO-2022-CN (Chinese Simplified)<br />
|73<br />
|-<br />
|KOI8-R (Cyrillic)<br />
|74<br />
|-<br />
|Unicode (UTF-7)<br />
|75<br />
|-<br />
|Unicode (UTF-8)<br />
|76<br />
|-<br />
|ISO-8859-10 (Central European)<br />
|77<br />
|-<br />
|ISO-8859-13 (Central European)<br />
|78<br />
|-<br />
|EUC-KR (Korean)<br />
|79<br />
|-<br />
|ISO-2022-KR (Korean)<br />
|80<br />
|-<br />
|JIS 0201 (Japanese)<br />
|81<br />
|-<br />
|JIS 0208 (Japanese)<br />
|82<br />
|-<br />
|JIS 0212 (Japanese)<br />
|83<br />
|-<br />
|Windows-Johab-1361 (Korean)<br />
|84<br />
|-<br />
|GB-18030 (Chinese Simplified)<br />
|85<br />
|-<br />
|BIG5-HKSCS (Chinese Traditional)<br />
|86<br />
|-<br />
|TIS 620 (Thai)<br />
|87<br />
|-<br />
|KOI8-U (Cyrillic)<br />
|88<br />
|-<br />
|ISCII Devanagari (Indian)<br />
|89<br />
|-<br />
|Unicode (Java's modified UTF-8)<br />
|90<br />
|-<br />
|Adobe Standard<br />
|91<br />
|-<br />
|Adobe Symbol<br />
|92<br />
|-<br />
|PT 154 (Windows Cyrillic Asian codepage <br />developed in ParaType)<br />
|93<br />
|-<br />
|Unicode UCS4<br />
|65534<br />
|-<br />
|Unicode UCS2<br />
|65535<br />
|}<br />
<br />
=== Filter Options for the CSV Filter ===<br />
<br />
This filter accepts an option string containing five to nine tokens, separated by commas. Tokens 6, to 9 are optional.<br />
<br />
==== Tokens 1 to 5 ====<br />
<br />
The following table shows an example string for a file with four columns of type date - number - number - number. In the table the tokens are numbered from (1) to (5). Each token is explained below.<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!rowspan="2"|Example Filter Options String <br />
!rowspan="2"|Field Separator (1) <br />
!rowspan="2"|Text Delimiter (2) <br />
!rowspan="2"|Character Set (3) <br />
!rowspan="2"|Number of First Line (4) <br />
!colspan="2"|Cell Format Codes for the four Columns (5) <br />
|-bgcolor=#EDEDED<br />
!Column <br />
!Code <br />
|-<br />
|File Format: <br />
Four columns<br />
date-num-num-num <br />
| , <br />
| " <br />
|System <br />
|line no. 1 <br />
|1<br><br />
2<br><br />
3<br><br />
4 <br />
|YY/MM/DD = 5<br><br />
Standard = 1<br><br />
Standard = 1<br><br />
Standard = 1 <br />
|-<br />
|Token <br />
|44 <br />
|34 <br />
|0 <br />
|1 <br />
|colspan="2"|1/5/2/1/3/1/4/1 <br />
|}<br />
<br />
For the filter options above, set the PropertyValue <code>FilterOptions</code> in the load arguments to "44,34,0,1,1/5/2/1/3/1/4/1". There are a number of possible settings for the five tokens.<br />
<br />
# Field separator(s) as ASCII values. Multiple values are separated by the slash sign ("/"), that is, if the values are separated by semicolons and horizontal tabulators, the token would be 59/9. To treat several consecutive separators as one, the four letters /MRG have to be appended to the token. If the file contains fixed width fields, the three letters FIX are used.<br />
# The text delimiter as ASCII value, that is, 34 for double quotes and 39 for single quotes.<br />
# The character set used in the file as described above.<br />
# Number of the first line to convert. The first line in the file has the number 1.<br />
# Cell format of the columns. The content of this token depends on the value of the first token.<br />
::* If value separators are used, the form of this token is column/format[/column/format/...] where column is the number of the column, with 1 being the leftmost column. The format is explained below.<br />
::* If the first token is FIX it has the form ''start/format''[''/start/format/...''], where start is the number of the first character for this field, with 0 being the leftmost character in a line. The format is explained below.<br />
::Format specifies which cell format should be used for a field during import:<br />
<br />
::{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Format Code <br />
!Meaning <br />
|-<br />
|1 <br />
|Standard <br />
|-<br />
|2 <br />
|Text <br />
|-<br />
|3 <br />
|MM/DD/YY <br />
|-<br />
|4 <br />
|DD/MM/YY <br />
|-<br />
|5 <br />
|YY/MM/DD <br />
|-<br />
|6 <br />
| - <br />
|-<br />
|7 <br />
| - <br />
|-<br />
|8 <br />
| - <br />
|-<br />
|9 <br />
|ignore field (do not import) <br />
|-<br />
|10 <br />
|US-English <br />
|}<br />
<br />
::The type code 10 indicates that the content of a field is US-English. This is useful if a field contains decimal numbers that are formatted according to the US system (using "." as decimal separator and "," as thousands separator). Using 10 as a format specifier for this field tells {{PRODUCTNAME}} API to correctly interpret its numerical content, even if the decimal and thousands separator in the current language are different.<br />
<br />
==== Token 6 : Language identifier ====<br />
<br />
This token is the equivalent of the "Language" listbox in the user interface for csv import.<br><br />
It is a String expressed in decimal notation. If the value is 0 or omitted, the language identifier of the user interface is used.<br />
<br />
The language identifier is based on the Microsoft language identifiers, for further information please see: <br />
<br />
Language Identifier Constants and Strings<br><br />
https://msdn.microsoft.com/en-us/library/windows/desktop/dd318693%28v=vs.85%29.aspx <br />
<br />
Use the decimal notation, example for English US : 1033 whereas Microsoft documentation uses hexadecimal notation 0x0409.<br />
==== Token 7, csv import ====<br />
<br />
This token is the equivalent of the check box "Quoted field as text".<br />
<br />
String, either <code>false</code> or <code>true</code>. Default value : <code>false</code>.<br />
<br />
==== Token 7, csv export ====<br />
<br />
This token is the equivalent of the check box "Quote all text cells".<br />
<br />
String, either <code>false</code> or <code>true</code>. Default value : <code>false</code>.<br />
<br />
==== Token 8, csv import ====<br />
<br />
This token is the equivalent of the check box "Detect special numbers".<br />
<br />
String, either <code>false</code> or <code>true</code>. Default value : <code>false</code>.<br />
<br />
==== Token 8, csv export ====<br />
<br />
This token has no UI equivalent. If <code>true</code>, the number cells are stored as numbers. If <code>false</code>, the numbers are stored as text, with text delimiters.<br />
<br />
String, either <code>false</code> or <code>true</code>. Default value : <code>true</code>.<br />
<br />
==== Token 9, csv import ====<br />
<br />
Not used : only 8 tokens are used.<br />
<br />
==== Token 9, csv export ====<br />
<br />
This token is the equivalent of the check box "Save cell contents as shown".<br />
<br />
String, either <code>false</code> or <code>true</code>. Default value : <code>true</code>.<br />
<br />
==== Examples ====<br />
<br />
Import from UTF-8, Language German, Comma separated, Text delimiter <code>"</code>, Quoted field as text:<br />
<br><code>44,34,76,1,,1031,true,true</code><br />
<br />
Export to Windows-1252, Field delimiter : comma, Text delimiter : quote, Save cell contents as shown:<br />
<br><code>44,34,ANSI,1,,0,false,true,true</code><br />
<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Spreadsheet Documents]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Filter_OptionsDocumentation/DevGuide/Spreadsheets/Filter Options2015-10-18T12:49:37Z<p>BMarcelly: /* Token 7, csv export */</p>
<hr />
<div>{{Documentation/DevGuide/SpreadsheetsTOC<br />
|SpreadsheetDocs2b=block<br />
|SpreadsheetDocsSaving=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/Spreadsheets/Saving Spreadsheet Documents<br />
|NextPage=Documentation/DevGuide/Spreadsheets/Printing Spreadsheet Documents<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/Spreadsheets/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:Filter Options}}<br />
Loading and saving {{PRODUCTNAME}} API documents is described in [[Documentation/DevGuide/OfficeDev/Handling Documents|Handling Documents]]. This section lists all the filter names for spreadsheet documents and describes the filter options for text file import.<br />
<br />
The filter name and options are passed on loading or saving a document in a sequence of <idl>com.sun.star.beans.PropertyValue</idl>s. The property <code>FilterName</code> contains the name and the property <code>FilterOptions</code> contains the filter options.<br />
<br />
{{Documentation/Note|All filter names are case-sensitive. For compatibility reasons the filter names will not be changed. Therefore, some of the filters seem to have "curious" names.}}<br />
<br />
The list of filter names (the last two columns show the possible directions of the filters):<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Filter name <br />
!Description <br />
!Import <br />
!Export <br />
|-<br />
|StarOffice XML (Calc) <br />
|Standard XML filter <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|calc_StarOffice_XML_Calc_Template <br />
|XML filter for templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 5.0 <br />
|The binary format of StarOffice Calc 5.x <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 5.0 Vorlage/Template <br />
|StarOffice Calc 5.x templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 4.0 <br />
|The binary format of StarCalc 4.x <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 4.0 Vorlage/Template <br />
|StarCalc 4.x templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 3.0 <br />
|The binary format of StarCalc 3.x <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 3.0 Vorlage/Template <br />
|StarCalc 3.x templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|HTML (StarCalc) <br />
|HTML filter <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|calc_HTML_WebQuery <br />
|HTML filter for external data queries <br />
|<center>●</center> <br />
| <br />
|-<br />
|MS Excel 97 <br />
|Microsoft Excel 97/2000/XP <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 97 Vorlage/Template <br />
|Microsoft Excel 97/2000/XP templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 95 <br />
|Microsoft Excel 5.0/95 <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 5.0/95 <br />
|Different name for the same filter <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 95 Vorlage/Template <br />
|Microsoft Excel 5.0/95 templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 5.0/95 Vorlage/Template <br />
|Different name for the same filter <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 4.0 <br />
|Microsoft Excel 2.1/3.0/4.0 <br />
|<center>●</center> <br />
| <br />
|-<br />
|MS Excel 4.0 Vorlage/Template <br />
|Microsoft Excel 2.1/3.0/4.0 templates <br />
|<center>●</center> <br />
| <br />
|-<br />
|Lotus <br />
|Lotus 1-2-3 <br />
|<center>●</center> <br />
| <br />
|-<br />
|Text - txt - csv (StarCalc) <br />
|Comma separated values <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|Rich Text Format (StarCalc) <br />
| <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|dBase <br />
| <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|SYLK <br />
|Symbolic Link <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|DIF <br />
|Data Interchange Format <br />
|<center>●</center> <br />
|<center>●</center> <br />
|}<br />
<br />
=== Filter Options for Lotus, dBase and DIF Filters ===<br />
<br />
These filters accept a string containing the numerical index of the used character set for single-byte characters, that is, 0 for the system character set.<br />
<br />
The numerical indexes assigned to the character sets:<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Character Set<br />
!Index<br />
|-<br />
|Unknown<br />
|0<br />
|-<br />
|Windows-1252/WinLatin 1 (Western)<br />
|1<br />
|-<br />
|Apple Macintosh (Western)<br />
|2<br />
|-<br />
|DOS/OS2-437/US (Western)<br />
|3<br />
|-<br />
|DOS/OS2-850/International (Western)<br />
|4<br />
|-<br />
|DOS/OS2-860/Portuguese (Western)<br />
|5<br />
|-<br />
|DOS/OS2-861/Icelandic (Western)<br />
|6<br />
|-<br />
|DOS/OS2-863/Canadian-French (Western)<br />
|7<br />
|-<br />
|DOS/OS2-865/Nordic (Western)<br />
|8<br />
|-<br />
|System default<br />
|9<br />
|-<br />
|Symbol<br />
|10<br />
|-<br />
|ASCII/US (Western)<br />
|11<br />
|-<br />
|ISO-8859-1 (Western)<br />
|12<br />
|-<br />
|ISO-8859-2 (Central European)<br />
|13<br />
|-<br />
|ISO-8859-3 (Latin 3)<br />
|14<br />
|-<br />
|ISO-8859-4 (Baltic)<br />
|15<br />
|-<br />
|ISO-8859-5 (Cyrillic)<br />
|16<br />
|-<br />
|ISO-8859-6 (Arabic)<br />
|17<br />
|-<br />
|ISO-8859-7 (Greek)<br />
|18<br />
|-<br />
|ISO-8859-8 (Hebrew)<br />
|19<br />
|-<br />
|ISO-8859-9 (Turkish)<br />
|20<br />
|-<br />
|ISO-8859-14 (Western)<br />
|21<br />
|-<br />
|ISO-8859-15/EURO (Western)<br />
|22<br />
|-<br />
|DOS/OS2-737 (Greek)<br />
|23<br />
|-<br />
|DOS/OS2-775 (Baltic)<br />
|24<br />
|-<br />
|DOS/OS2-852 (Central European)<br />
|25<br />
|-<br />
|DOS/OS2-855 (Cyrillic)<br />
|26<br />
|-<br />
|DOS/OS2-857 (Turkish)<br />
|27<br />
|-<br />
|DOS/OS2-862 (Hebrew)<br />
|28<br />
|-<br />
|DOS/OS2-864 (Arabic)<br />
|29<br />
|-<br />
|DOS/OS2-866/Russian (Cyrillic)<br />
|30<br />
|-<br />
|DOS/OS2-869/Modern (Greek)<br />
|31<br />
|-<br />
|DOS/Windows-874 (Thai)<br />
|32<br />
|-<br />
|Windows-1250/WinLatin 2 (Central European)<br />
|33<br />
|-<br />
|Windows-1251 (Cyrillic)<br />
|34<br />
|-<br />
|Windows-1253 (Greek)<br />
|35<br />
|-<br />
|Windows-1254 (Turkish)<br />
|36<br />
|-<br />
|Windows-1255 (Hebrew)<br />
|37<br />
|-<br />
|Windows-1256 (Arabic)<br />
|38<br />
|-<br />
|Windows-1257 (Baltic)<br />
|39<br />
|-<br />
|Windows-1258 (Vietnamese)<br />
|40<br />
|-<br />
|Apple Macintosh (Arabic)<br />
|41<br />
|-<br />
|Apple Macintosh (Central European)<br />
|42<br />
|-<br />
|Apple Macintosh/Croatian (Central European)<br />
|43<br />
|-<br />
|Apple Macintosh (Cyrillic)<br />
|44<br />
|-<br />
|''Not supported:'' Apple Macintosh (Devanagari)<br />
|45<br />
|-<br />
|''Not supported:'' Apple Macintosh (Farsi)<br />
|46<br />
|-<br />
|Apple Macintosh (Greek)<br />
|47<br />
|-<br />
|''Not supported:'' Apple Macintosh (Gujarati)<br />
|48<br />
|-<br />
|''Not supported:'' Apple Macintosh (Gurmukhi)<br />
|49<br />
|-<br />
|Apple Macintosh (Hebrew)<br />
|50<br />
|-<br />
|Apple Macintosh/Icelandic (Western)<br />
|51<br />
|-<br />
|Apple Macintosh/Romanian (Central European)<br />
|52<br />
|-<br />
|Apple Macintosh (Thai)<br />
|53<br />
|-<br />
|Apple Macintosh (Turkish)<br />
|54<br />
|-<br />
|Apple Macintosh/Ukrainian (Cyrillic)<br />
|55<br />
|-<br />
|Apple Macintosh (Chinese Simplified)<br />
|56<br />
|-<br />
|Apple Macintosh (Chinese Traditional)<br />
|57<br />
|-<br />
|Apple Macintosh (Japanese)<br />
|58<br />
|-<br />
|Apple Macintosh (Korean)<br />
|59<br />
|-<br />
|Windows-932 (Japanese)<br />
|60<br />
|-<br />
|Windows-936 (Chinese Simplified)<br />
|61<br />
|-<br />
|Windows-Wansung-949 (Korean)<br />
|62<br />
|-<br />
|Windows-950 (Chinese Traditional)<br />
|63<br />
|-<br />
|Shift-JIS (Japanese)<br />
|64<br />
|-<br />
|GB-2312 (Chinese Simplified)<br />
|65<br />
|-<br />
|GBT-12345 (Chinese Traditional)<br />
|66<br />
|-<br />
|GBK/GB-2312-80 (Chinese Simplified)<br />
|67<br />
|-<br />
|BIG5 (Chinese Traditional)<br />
|68<br />
|-<br />
|EUC-JP (Japanese)<br />
|69<br />
|-<br />
|EUC-CN (Chinese Simplified)<br />
|70<br />
|-<br />
|EUC-TW (Chinese Traditional)<br />
|71<br />
|-<br />
|ISO-2022-JP (Japanese)<br />
|72<br />
|-<br />
|ISO-2022-CN (Chinese Simplified)<br />
|73<br />
|-<br />
|KOI8-R (Cyrillic)<br />
|74<br />
|-<br />
|Unicode (UTF-7)<br />
|75<br />
|-<br />
|Unicode (UTF-8)<br />
|76<br />
|-<br />
|ISO-8859-10 (Central European)<br />
|77<br />
|-<br />
|ISO-8859-13 (Central European)<br />
|78<br />
|-<br />
|EUC-KR (Korean)<br />
|79<br />
|-<br />
|ISO-2022-KR (Korean)<br />
|80<br />
|-<br />
|JIS 0201 (Japanese)<br />
|81<br />
|-<br />
|JIS 0208 (Japanese)<br />
|82<br />
|-<br />
|JIS 0212 (Japanese)<br />
|83<br />
|-<br />
|Windows-Johab-1361 (Korean)<br />
|84<br />
|-<br />
|GB-18030 (Chinese Simplified)<br />
|85<br />
|-<br />
|BIG5-HKSCS (Chinese Traditional)<br />
|86<br />
|-<br />
|TIS 620 (Thai)<br />
|87<br />
|-<br />
|KOI8-U (Cyrillic)<br />
|88<br />
|-<br />
|ISCII Devanagari (Indian)<br />
|89<br />
|-<br />
|Unicode (Java's modified UTF-8)<br />
|90<br />
|-<br />
|Adobe Standard<br />
|91<br />
|-<br />
|Adobe Symbol<br />
|92<br />
|-<br />
|PT 154 (Windows Cyrillic Asian codepage <br />developed in ParaType)<br />
|93<br />
|-<br />
|Unicode UCS4<br />
|65534<br />
|-<br />
|Unicode UCS2<br />
|65535<br />
|}<br />
<br />
=== Filter Options for the CSV Filter ===<br />
<br />
This filter accepts an option string containing five to nine tokens, separated by commas. Tokens 6, to 9 are optional.<br />
<br />
==== Tokens 1 to 5 ====<br />
<br />
The following table shows an example string for a file with four columns of type date - number - number - number. In the table the tokens are numbered from (1) to (5). Each token is explained below.<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!rowspan="2"|Example Filter Options String <br />
!rowspan="2"|Field Separator (1) <br />
!rowspan="2"|Text Delimiter (2) <br />
!rowspan="2"|Character Set (3) <br />
!rowspan="2"|Number of First Line (4) <br />
!colspan="2"|Cell Format Codes for the four Columns (5) <br />
|-bgcolor=#EDEDED<br />
!Column <br />
!Code <br />
|-<br />
|File Format: <br />
Four columns<br />
date-num-num-num <br />
| , <br />
| " <br />
|System <br />
|line no. 1 <br />
|1<br><br />
2<br><br />
3<br><br />
4 <br />
|YY/MM/DD = 5<br><br />
Standard = 1<br><br />
Standard = 1<br><br />
Standard = 1 <br />
|-<br />
|Token <br />
|44 <br />
|34 <br />
|0 <br />
|1 <br />
|colspan="2"|1/5/2/1/3/1/4/1 <br />
|}<br />
<br />
For the filter options above, set the PropertyValue <code>FilterOptions</code> in the load arguments to "44,34,0,1,1/5/2/1/3/1/4/1". There are a number of possible settings for the five tokens.<br />
<br />
# Field separator(s) as ASCII values. Multiple values are separated by the slash sign ("/"), that is, if the values are separated by semicolons and horizontal tabulators, the token would be 59/9. To treat several consecutive separators as one, the four letters /MRG have to be appended to the token. If the file contains fixed width fields, the three letters FIX are used.<br />
# The text delimiter as ASCII value, that is, 34 for double quotes and 39 for single quotes.<br />
# The character set used in the file as described above.<br />
# Number of the first line to convert. The first line in the file has the number 1.<br />
# Cell format of the columns. The content of this token depends on the value of the first token.<br />
::* If value separators are used, the form of this token is column/format[/column/format/...] where column is the number of the column, with 1 being the leftmost column. The format is explained below.<br />
::* If the first token is FIX it has the form ''start/format''[''/start/format/...''], where start is the number of the first character for this field, with 0 being the leftmost character in a line. The format is explained below.<br />
::Format specifies which cell format should be used for a field during import:<br />
<br />
::{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Format Code <br />
!Meaning <br />
|-<br />
|1 <br />
|Standard <br />
|-<br />
|2 <br />
|Text <br />
|-<br />
|3 <br />
|MM/DD/YY <br />
|-<br />
|4 <br />
|DD/MM/YY <br />
|-<br />
|5 <br />
|YY/MM/DD <br />
|-<br />
|6 <br />
| - <br />
|-<br />
|7 <br />
| - <br />
|-<br />
|8 <br />
| - <br />
|-<br />
|9 <br />
|ignore field (do not import) <br />
|-<br />
|10 <br />
|US-English <br />
|}<br />
<br />
::The type code 10 indicates that the content of a field is US-English. This is useful if a field contains decimal numbers that are formatted according to the US system (using "." as decimal separator and "," as thousands separator). Using 10 as a format specifier for this field tells {{PRODUCTNAME}} API to correctly interpret its numerical content, even if the decimal and thousands separator in the current language are different.<br />
<br />
==== Token 6 : Language identifier ====<br />
<br />
This token is the equivalent of the "Language" listbox in the user interface for csv import.<br><br />
It is a String expressed in decimal notation. If the value is 0 or omitted, the language identifier of the user interface is used.<br />
<br />
The language identifier is based on the Microsoft language identifiers, for further information please see: <br />
<br />
Language Identifier Constants and Strings<br><br />
https://msdn.microsoft.com/en-us/library/windows/desktop/dd318693%28v=vs.85%29.aspx <br />
<br />
Use the decimal notation, example for English US : 1033 whereas Microsoft documentation uses hexadecimal notation 0x0409.<br />
==== Token 7, csv import ====<br />
<br />
This token is the equivalent of the check box "Quoted field as text".<br />
<br />
String, either <code>false</code> or <code>true</code>. Default value : <code>false</code>.<br />
<br />
==== Token 7, csv export ====<br />
<br />
This token is the equivalent of the check box "Quote all text cells".<br />
<br />
String, either <code>false</code> or <code>true</code>. Default value : <code>false</code>.<br />
<br />
==== Token 8, csv import ====<br />
<br />
This token is the equivalent of the check box "Detect special numbers".<br />
<br />
String, either <code>false</code> or <code>true</code>. Default value : is <code>false</code>.<br />
<br />
==== Token 8, csv export ====<br />
<br />
This token has no UI equivalent. If <code>true</code>, the number cells are stored as numbers. If <code>false</code>, the numbers are stored as text, with text delimiters.<br />
<br />
String, either <code>false</code> or <code>true</code>. Default value : <code>true</code>.<br />
<br />
==== Token 9, csv import ====<br />
<br />
Not used : only 8 tokens are used.<br />
<br />
==== Token 9, csv export ====<br />
<br />
This token is the equivalent of the check box "Save cell contents as shown".<br />
<br />
String, either <code>false</code> or <code>true</code>. Default value : <code>true</code>.<br />
<br />
==== Examples ====<br />
<br />
Import from UTF-8, Language German, Comma separated, Text delimiter <code>"</code>, Quoted field as text:<br />
<br><code>44,34,76,1,,1031,true,true</code><br />
<br />
Export to Windows-1252, Field delimiter : comma, Text delimiter : quote, Save cell contents as shown:<br />
<br><code>44,34,ANSI,1,,0,false,true,true</code><br />
<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Spreadsheet Documents]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Filter_OptionsDocumentation/DevGuide/Spreadsheets/Filter Options2015-10-18T12:48:15Z<p>BMarcelly: /* Filter Options for the CSV Filter */ Token 7 to 9, for import and for export</p>
<hr />
<div>{{Documentation/DevGuide/SpreadsheetsTOC<br />
|SpreadsheetDocs2b=block<br />
|SpreadsheetDocsSaving=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/Spreadsheets/Saving Spreadsheet Documents<br />
|NextPage=Documentation/DevGuide/Spreadsheets/Printing Spreadsheet Documents<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/Spreadsheets/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:Filter Options}}<br />
Loading and saving {{PRODUCTNAME}} API documents is described in [[Documentation/DevGuide/OfficeDev/Handling Documents|Handling Documents]]. This section lists all the filter names for spreadsheet documents and describes the filter options for text file import.<br />
<br />
The filter name and options are passed on loading or saving a document in a sequence of <idl>com.sun.star.beans.PropertyValue</idl>s. The property <code>FilterName</code> contains the name and the property <code>FilterOptions</code> contains the filter options.<br />
<br />
{{Documentation/Note|All filter names are case-sensitive. For compatibility reasons the filter names will not be changed. Therefore, some of the filters seem to have "curious" names.}}<br />
<br />
The list of filter names (the last two columns show the possible directions of the filters):<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Filter name <br />
!Description <br />
!Import <br />
!Export <br />
|-<br />
|StarOffice XML (Calc) <br />
|Standard XML filter <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|calc_StarOffice_XML_Calc_Template <br />
|XML filter for templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 5.0 <br />
|The binary format of StarOffice Calc 5.x <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 5.0 Vorlage/Template <br />
|StarOffice Calc 5.x templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 4.0 <br />
|The binary format of StarCalc 4.x <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 4.0 Vorlage/Template <br />
|StarCalc 4.x templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 3.0 <br />
|The binary format of StarCalc 3.x <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 3.0 Vorlage/Template <br />
|StarCalc 3.x templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|HTML (StarCalc) <br />
|HTML filter <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|calc_HTML_WebQuery <br />
|HTML filter for external data queries <br />
|<center>●</center> <br />
| <br />
|-<br />
|MS Excel 97 <br />
|Microsoft Excel 97/2000/XP <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 97 Vorlage/Template <br />
|Microsoft Excel 97/2000/XP templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 95 <br />
|Microsoft Excel 5.0/95 <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 5.0/95 <br />
|Different name for the same filter <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 95 Vorlage/Template <br />
|Microsoft Excel 5.0/95 templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 5.0/95 Vorlage/Template <br />
|Different name for the same filter <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 4.0 <br />
|Microsoft Excel 2.1/3.0/4.0 <br />
|<center>●</center> <br />
| <br />
|-<br />
|MS Excel 4.0 Vorlage/Template <br />
|Microsoft Excel 2.1/3.0/4.0 templates <br />
|<center>●</center> <br />
| <br />
|-<br />
|Lotus <br />
|Lotus 1-2-3 <br />
|<center>●</center> <br />
| <br />
|-<br />
|Text - txt - csv (StarCalc) <br />
|Comma separated values <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|Rich Text Format (StarCalc) <br />
| <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|dBase <br />
| <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|SYLK <br />
|Symbolic Link <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|DIF <br />
|Data Interchange Format <br />
|<center>●</center> <br />
|<center>●</center> <br />
|}<br />
<br />
=== Filter Options for Lotus, dBase and DIF Filters ===<br />
<br />
These filters accept a string containing the numerical index of the used character set for single-byte characters, that is, 0 for the system character set.<br />
<br />
The numerical indexes assigned to the character sets:<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Character Set<br />
!Index<br />
|-<br />
|Unknown<br />
|0<br />
|-<br />
|Windows-1252/WinLatin 1 (Western)<br />
|1<br />
|-<br />
|Apple Macintosh (Western)<br />
|2<br />
|-<br />
|DOS/OS2-437/US (Western)<br />
|3<br />
|-<br />
|DOS/OS2-850/International (Western)<br />
|4<br />
|-<br />
|DOS/OS2-860/Portuguese (Western)<br />
|5<br />
|-<br />
|DOS/OS2-861/Icelandic (Western)<br />
|6<br />
|-<br />
|DOS/OS2-863/Canadian-French (Western)<br />
|7<br />
|-<br />
|DOS/OS2-865/Nordic (Western)<br />
|8<br />
|-<br />
|System default<br />
|9<br />
|-<br />
|Symbol<br />
|10<br />
|-<br />
|ASCII/US (Western)<br />
|11<br />
|-<br />
|ISO-8859-1 (Western)<br />
|12<br />
|-<br />
|ISO-8859-2 (Central European)<br />
|13<br />
|-<br />
|ISO-8859-3 (Latin 3)<br />
|14<br />
|-<br />
|ISO-8859-4 (Baltic)<br />
|15<br />
|-<br />
|ISO-8859-5 (Cyrillic)<br />
|16<br />
|-<br />
|ISO-8859-6 (Arabic)<br />
|17<br />
|-<br />
|ISO-8859-7 (Greek)<br />
|18<br />
|-<br />
|ISO-8859-8 (Hebrew)<br />
|19<br />
|-<br />
|ISO-8859-9 (Turkish)<br />
|20<br />
|-<br />
|ISO-8859-14 (Western)<br />
|21<br />
|-<br />
|ISO-8859-15/EURO (Western)<br />
|22<br />
|-<br />
|DOS/OS2-737 (Greek)<br />
|23<br />
|-<br />
|DOS/OS2-775 (Baltic)<br />
|24<br />
|-<br />
|DOS/OS2-852 (Central European)<br />
|25<br />
|-<br />
|DOS/OS2-855 (Cyrillic)<br />
|26<br />
|-<br />
|DOS/OS2-857 (Turkish)<br />
|27<br />
|-<br />
|DOS/OS2-862 (Hebrew)<br />
|28<br />
|-<br />
|DOS/OS2-864 (Arabic)<br />
|29<br />
|-<br />
|DOS/OS2-866/Russian (Cyrillic)<br />
|30<br />
|-<br />
|DOS/OS2-869/Modern (Greek)<br />
|31<br />
|-<br />
|DOS/Windows-874 (Thai)<br />
|32<br />
|-<br />
|Windows-1250/WinLatin 2 (Central European)<br />
|33<br />
|-<br />
|Windows-1251 (Cyrillic)<br />
|34<br />
|-<br />
|Windows-1253 (Greek)<br />
|35<br />
|-<br />
|Windows-1254 (Turkish)<br />
|36<br />
|-<br />
|Windows-1255 (Hebrew)<br />
|37<br />
|-<br />
|Windows-1256 (Arabic)<br />
|38<br />
|-<br />
|Windows-1257 (Baltic)<br />
|39<br />
|-<br />
|Windows-1258 (Vietnamese)<br />
|40<br />
|-<br />
|Apple Macintosh (Arabic)<br />
|41<br />
|-<br />
|Apple Macintosh (Central European)<br />
|42<br />
|-<br />
|Apple Macintosh/Croatian (Central European)<br />
|43<br />
|-<br />
|Apple Macintosh (Cyrillic)<br />
|44<br />
|-<br />
|''Not supported:'' Apple Macintosh (Devanagari)<br />
|45<br />
|-<br />
|''Not supported:'' Apple Macintosh (Farsi)<br />
|46<br />
|-<br />
|Apple Macintosh (Greek)<br />
|47<br />
|-<br />
|''Not supported:'' Apple Macintosh (Gujarati)<br />
|48<br />
|-<br />
|''Not supported:'' Apple Macintosh (Gurmukhi)<br />
|49<br />
|-<br />
|Apple Macintosh (Hebrew)<br />
|50<br />
|-<br />
|Apple Macintosh/Icelandic (Western)<br />
|51<br />
|-<br />
|Apple Macintosh/Romanian (Central European)<br />
|52<br />
|-<br />
|Apple Macintosh (Thai)<br />
|53<br />
|-<br />
|Apple Macintosh (Turkish)<br />
|54<br />
|-<br />
|Apple Macintosh/Ukrainian (Cyrillic)<br />
|55<br />
|-<br />
|Apple Macintosh (Chinese Simplified)<br />
|56<br />
|-<br />
|Apple Macintosh (Chinese Traditional)<br />
|57<br />
|-<br />
|Apple Macintosh (Japanese)<br />
|58<br />
|-<br />
|Apple Macintosh (Korean)<br />
|59<br />
|-<br />
|Windows-932 (Japanese)<br />
|60<br />
|-<br />
|Windows-936 (Chinese Simplified)<br />
|61<br />
|-<br />
|Windows-Wansung-949 (Korean)<br />
|62<br />
|-<br />
|Windows-950 (Chinese Traditional)<br />
|63<br />
|-<br />
|Shift-JIS (Japanese)<br />
|64<br />
|-<br />
|GB-2312 (Chinese Simplified)<br />
|65<br />
|-<br />
|GBT-12345 (Chinese Traditional)<br />
|66<br />
|-<br />
|GBK/GB-2312-80 (Chinese Simplified)<br />
|67<br />
|-<br />
|BIG5 (Chinese Traditional)<br />
|68<br />
|-<br />
|EUC-JP (Japanese)<br />
|69<br />
|-<br />
|EUC-CN (Chinese Simplified)<br />
|70<br />
|-<br />
|EUC-TW (Chinese Traditional)<br />
|71<br />
|-<br />
|ISO-2022-JP (Japanese)<br />
|72<br />
|-<br />
|ISO-2022-CN (Chinese Simplified)<br />
|73<br />
|-<br />
|KOI8-R (Cyrillic)<br />
|74<br />
|-<br />
|Unicode (UTF-7)<br />
|75<br />
|-<br />
|Unicode (UTF-8)<br />
|76<br />
|-<br />
|ISO-8859-10 (Central European)<br />
|77<br />
|-<br />
|ISO-8859-13 (Central European)<br />
|78<br />
|-<br />
|EUC-KR (Korean)<br />
|79<br />
|-<br />
|ISO-2022-KR (Korean)<br />
|80<br />
|-<br />
|JIS 0201 (Japanese)<br />
|81<br />
|-<br />
|JIS 0208 (Japanese)<br />
|82<br />
|-<br />
|JIS 0212 (Japanese)<br />
|83<br />
|-<br />
|Windows-Johab-1361 (Korean)<br />
|84<br />
|-<br />
|GB-18030 (Chinese Simplified)<br />
|85<br />
|-<br />
|BIG5-HKSCS (Chinese Traditional)<br />
|86<br />
|-<br />
|TIS 620 (Thai)<br />
|87<br />
|-<br />
|KOI8-U (Cyrillic)<br />
|88<br />
|-<br />
|ISCII Devanagari (Indian)<br />
|89<br />
|-<br />
|Unicode (Java's modified UTF-8)<br />
|90<br />
|-<br />
|Adobe Standard<br />
|91<br />
|-<br />
|Adobe Symbol<br />
|92<br />
|-<br />
|PT 154 (Windows Cyrillic Asian codepage <br />developed in ParaType)<br />
|93<br />
|-<br />
|Unicode UCS4<br />
|65534<br />
|-<br />
|Unicode UCS2<br />
|65535<br />
|}<br />
<br />
=== Filter Options for the CSV Filter ===<br />
<br />
This filter accepts an option string containing five to nine tokens, separated by commas. Tokens 6, to 9 are optional.<br />
<br />
==== Tokens 1 to 5 ====<br />
<br />
The following table shows an example string for a file with four columns of type date - number - number - number. In the table the tokens are numbered from (1) to (5). Each token is explained below.<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!rowspan="2"|Example Filter Options String <br />
!rowspan="2"|Field Separator (1) <br />
!rowspan="2"|Text Delimiter (2) <br />
!rowspan="2"|Character Set (3) <br />
!rowspan="2"|Number of First Line (4) <br />
!colspan="2"|Cell Format Codes for the four Columns (5) <br />
|-bgcolor=#EDEDED<br />
!Column <br />
!Code <br />
|-<br />
|File Format: <br />
Four columns<br />
date-num-num-num <br />
| , <br />
| " <br />
|System <br />
|line no. 1 <br />
|1<br><br />
2<br><br />
3<br><br />
4 <br />
|YY/MM/DD = 5<br><br />
Standard = 1<br><br />
Standard = 1<br><br />
Standard = 1 <br />
|-<br />
|Token <br />
|44 <br />
|34 <br />
|0 <br />
|1 <br />
|colspan="2"|1/5/2/1/3/1/4/1 <br />
|}<br />
<br />
For the filter options above, set the PropertyValue <code>FilterOptions</code> in the load arguments to "44,34,0,1,1/5/2/1/3/1/4/1". There are a number of possible settings for the five tokens.<br />
<br />
# Field separator(s) as ASCII values. Multiple values are separated by the slash sign ("/"), that is, if the values are separated by semicolons and horizontal tabulators, the token would be 59/9. To treat several consecutive separators as one, the four letters /MRG have to be appended to the token. If the file contains fixed width fields, the three letters FIX are used.<br />
# The text delimiter as ASCII value, that is, 34 for double quotes and 39 for single quotes.<br />
# The character set used in the file as described above.<br />
# Number of the first line to convert. The first line in the file has the number 1.<br />
# Cell format of the columns. The content of this token depends on the value of the first token.<br />
::* If value separators are used, the form of this token is column/format[/column/format/...] where column is the number of the column, with 1 being the leftmost column. The format is explained below.<br />
::* If the first token is FIX it has the form ''start/format''[''/start/format/...''], where start is the number of the first character for this field, with 0 being the leftmost character in a line. The format is explained below.<br />
::Format specifies which cell format should be used for a field during import:<br />
<br />
::{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Format Code <br />
!Meaning <br />
|-<br />
|1 <br />
|Standard <br />
|-<br />
|2 <br />
|Text <br />
|-<br />
|3 <br />
|MM/DD/YY <br />
|-<br />
|4 <br />
|DD/MM/YY <br />
|-<br />
|5 <br />
|YY/MM/DD <br />
|-<br />
|6 <br />
| - <br />
|-<br />
|7 <br />
| - <br />
|-<br />
|8 <br />
| - <br />
|-<br />
|9 <br />
|ignore field (do not import) <br />
|-<br />
|10 <br />
|US-English <br />
|}<br />
<br />
::The type code 10 indicates that the content of a field is US-English. This is useful if a field contains decimal numbers that are formatted according to the US system (using "." as decimal separator and "," as thousands separator). Using 10 as a format specifier for this field tells {{PRODUCTNAME}} API to correctly interpret its numerical content, even if the decimal and thousands separator in the current language are different.<br />
<br />
==== Token 6 : Language identifier ====<br />
<br />
This token is the equivalent of the "Language" listbox in the user interface for csv import.<br><br />
It is a String expressed in decimal notation. If the value is 0 or omitted, the language identifier of the user interface is used.<br />
<br />
The language identifier is based on the Microsoft language identifiers, for further information please see: <br />
<br />
Language Identifier Constants and Strings<br><br />
https://msdn.microsoft.com/en-us/library/windows/desktop/dd318693%28v=vs.85%29.aspx <br />
<br />
Use the decimal notation, example for English US : 1033 whereas Microsoft documentation uses hexadecimal notation 0x0409.<br />
==== Token 7, csv import ====<br />
<br />
This token is the equivalent of the check box "Quoted field as text".<br />
<br />
String, either <code>false</code> or <code>true</code>. Default value : <code>false</code>.<br />
<br />
==== Token 7, csv export ====<br />
<br />
This token is the equivalent of the check box "Quote all text cells".<br />
<br />
String, either <code>false</code> or <code>true</code>. Default value : is <code>false</code>.<br />
<br />
==== Token 8, csv import ====<br />
<br />
This token is the equivalent of the check box "Detect special numbers".<br />
<br />
String, either <code>false</code> or <code>true</code>. Default value : is <code>false</code>.<br />
<br />
==== Token 8, csv export ====<br />
<br />
This token has no UI equivalent. If <code>true</code>, the number cells are stored as numbers. If <code>false</code>, the numbers are stored as text, with text delimiters.<br />
<br />
String, either <code>false</code> or <code>true</code>. Default value : <code>true</code>.<br />
<br />
==== Token 9, csv import ====<br />
<br />
Not used : only 8 tokens are used.<br />
<br />
==== Token 9, csv export ====<br />
<br />
This token is the equivalent of the check box "Save cell contents as shown".<br />
<br />
String, either <code>false</code> or <code>true</code>. Default value : <code>true</code>.<br />
<br />
==== Examples ====<br />
<br />
Import from UTF-8, Language German, Comma separated, Text delimiter <code>"</code>, Quoted field as text:<br />
<br><code>44,34,76,1,,1031,true,true</code><br />
<br />
Export to Windows-1252, Field delimiter : comma, Text delimiter : quote, Save cell contents as shown:<br />
<br><code>44,34,ANSI,1,,0,false,true,true</code><br />
<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Spreadsheet Documents]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/ProUNO/PropertiesDocumentation/DevGuide/ProUNO/Properties2015-08-21T07:01:14Z<p>BMarcelly: Added header : Interface attributes</p>
<hr />
<div>{{Documentation/DevGuide/ProUNOTOC<br />
|ProUNO2b=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/ProUNO/Using UNO Interfaces<br />
|NextPage=Documentation/DevGuide/ProUNO/Collections and Containers<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/ProUNO/{{SUBPAGENAME}}}}<br />
{{DISPLAYTITLE:Properties}}<br />
<!--<idltopic>com.sun.star.beans.XPropertySet;com.sun.star.beans.XMultiPropertySet;com.sun.star.beans.XFastPropertySet;com.sun.star.beans.XPropertySetInfo;com.sun.star.beans.XPropertyState</idltopic>--><br />
Properties are name-value pairs belonging to a service and determine the characteristics of an object in a service instance. Usually, properties are used for non-structural attributes, such as font, size or color of objects, whereas get and set methods are used for structural attributes like a parent or sub-object.<br />
<br />
In almost all cases, <idl>com.sun.star.beans.XPropertySet</idl> is used to access properties by name. Other interfaces, for example, are <idl>com.sun.star.beans.XPropertyAccess</idl> which is used to set and retrieve all properties at once or <idl>com.sun.star.beans.XMultiPropertySet</idl> which is used to access several specified properties at once. This is useful on remote connections. Additionally, there are interfaces to access properties by numeric ID, such as <idl>com.sun.star.beans.XFastPropertySet</idl>.<br />
<br />
==== Example: query and change the properties ====<br />
<br />
The following example demonstrates how to query and change the properties of a given text document cursor using its XPropertySet interface:<br />
<source lang="java"><br />
// get an XPropertySet, here the one of a text cursor<br />
XPropertySet xCursorProps = (XPropertySet) <br />
UnoRuntime.queryInterface(XPropertySet.class, mxDocCursor);<br />
<br />
// get the character weight property <br />
Object aCharWeight = xCursorProps.getPropertyValue("CharWeight");<br />
float fCharWeight = AnyConverter.toFloat(aCharWeight);<br />
System.out.println("before: CharWeight=" + fCharWeight);<br />
<br />
// set the character weight property to BOLD<br />
xCursorProps.setPropertyValue("CharWeight", new Float(com.sun.star.awt.FontWeight.BOLD));<br />
<br />
// get the character weight property again<br />
aCharWeight = xCursorProps.getPropertyValue("CharWeight");<br />
fCharWeight = AnyConverter.toFloat(aCharWeight);<br />
System.out.println("after: CharWeight=" + fCharWeight);<br />
</source><br />
A possible output of this code could be:<br />
<br />
before: CharWeight=100.0<br />
after: CharWeight=150.0<br />
<br />
{{Documentation/Caution|The sequence of property names must be sorted.}}<br />
<br />
==== Example: dealing with multiple properties at once ====<br />
<br />
The following example deals with multiple properties at once:<br />
<source lang="java"><br />
// get an XMultiPropertySet, here the one of the first paragraph<br />
XEnumerationAccess xEnumAcc = (XEnumerationAccess) UnoRuntime.queryInterface(<br />
XEnumerationAccess.class, mxDocText);<br />
XEnumeration xEnum = xEnumAcc.createEnumeration();<br />
Object aPara = xEnum.nextElement();<br />
XMultiPropertySet xParaProps = (XMultiPropertySet) UnoRuntime.queryInterface(<br />
XMultiPropertySet.class, aPara);<br />
<br />
// get three property values with a single UNO call<br />
String[] aNames = new String[3];<br />
aNames[0] = "CharColor";<br />
aNames[1] = "CharFontName";<br />
aNames[2] = "CharWeight";<br />
Object[] aValues = xParaProps.getPropertyValues(aNames);<br />
<br />
// print the three values<br />
System.out.println("CharColor=" + AnyConverter.toLong(aValues[0]));<br />
System.out.println("CharFontName=" + AnyConverter.toString(aValues[1]));<br />
System.out.println("CharWeight=" + AnyConverter.toFloat(aValues[2]));<br />
</source><br />
Properties can be assigned flags to determine a specific behavior of the property, such as read-only, bound, constrained or void. Possible flags are specified in <idl>com.sun.star.beans.PropertyAttribute</idl>. Read-only properties cannot be set. Bound properties broadcast changes of their value to registered listeners and constrained properties veto changes to these listeners.<br />
<br />
Properties might have a status specifying where the value comes from. See <idl>com.sun.star.beans.XPropertyState</idl>. The value determines if the value comes from the object, a style sheet or if it cannot be determined at all. For example, in a multi-selection with multiple values within this selection.<br />
<br />
==== Example: obtain status information of property values ====<br />
<br />
The following example shows how to find out status information about property values:<br />
<source lang="java"><br />
// get an XPropertySet, here the one of a text cursor<br />
XPropertySet xCursorProps = (XPropertySet) UnoRuntime.queryInterface(<br />
XPropertySet.class, mxDocCursor);<br />
<br />
// insert "first" in NORMAL character weight<br />
mxDocText.insertString(mxDocCursor, "first ", true);<br />
xCursorProps.setPropertyValue("CharWeight", new Float(com.sun.star.awt.FontWeight.NORMAL));<br />
<br />
// append "second" in BOLD character weight<br />
mxDocCursor.collapseToEnd();<br />
mxDocText.insertString(mxDocCursor, "second", true);<br />
xCursorProps.setPropertyValue("CharWeight", new Float(com.sun.star.awt.FontWeight.BOLD));<br />
<br />
// try to get the character weight property of BOTH words<br />
mxDocCursor.gotoStart(true);<br />
try {<br />
Object aCharWeight = xCursorProps.getPropertyValue("CharWeight");<br />
float fCharWeight = AnyConverter.toFloat(aCharWeight );<br />
System.out.println("CharWeight=" + fCharWeight);<br />
} catch (NullPointerException e) { <br />
System.out.println("CharWeight property is NULL");<br />
}<br />
<br />
// query the XPropertState interface of the cursor properties<br />
XPropertyState xCursorPropsState = (XPropertyState) UnoRuntime.queryInterface(<br />
XPropertyState.class, xCursorProps);<br />
<br />
// get the status of the character weight property<br />
PropertyState eCharWeightState = xCursorPropsState.getPropertyState("CharWeight");<br />
System.out.print("CharWeight property state has ");<br />
if (eCharWeightState == PropertyState.AMBIGUOUS_VALUE)<br />
System.out.println("an ambiguous value");<br />
else<br />
System.out.println("a clear value");<br />
</source><br />
The property state of character weight is queried for a string like this:<br />
<br />
first '''second'''<br />
<br />
And the output is:<br />
<br />
CharWeight property is NULL<br />
CharWeight property state has an ambiguous value<br />
<br />
The description of properties available for a certain object is given by <idl>com.sun.star.beans.XPropertySetInfo</idl>. Multiple objects can share the same property information for their description. This makes it easier for introspective caches that are used in scripting languages where the properties are accessed directly, without directly calling the methods of the interfaces mentioned above.<br />
<br />
==== Example: find out which properties an object provides ====<br />
<br />
This example shows how to find out which properties an object provides using <idl>com.sun.star.beans.XPropertySetInfo</idl>:<br />
<source lang="java"><br />
try {<br />
// get an XPropertySet, here the one of a text cursor<br />
XPropertySet xCursorProps = (XPropertySet)UnoRuntime.queryInterface(<br />
XPropertySet.class, mxDocCursor);<br />
<br />
// get the property info interface of this XPropertySet<br />
XPropertySetInfo xCursorPropsInfo = xCursorProps.getPropertySetInfo();<br />
<br />
// get all properties (NOT the values) from XPropertySetInfo<br />
Property[] aProps = xCursorPropsInfo.getProperties();<br />
int i;<br />
for (i = 0; i < aProps.length; ++i) {<br />
// number of property within this info object<br />
System.out.print("Property #" + i);<br />
<br />
// name of property<br />
System.out.print(": Name<" + aProps[i].Name);<br />
<br />
// handle of property (only for XFastPropertySet)<br />
System.out.print("> Handle<" + aProps[i].Handle);<br />
<br />
// type of property<br />
System.out.print("> " + aProps[i].Type.toString());<br />
<br />
// attributes (flags)<br />
System.out.print(" Attributes<");<br />
short nAttribs = aProps[i].Attributes;<br />
if ((nAttribs & PropertyAttribute.MAYBEVOID) != 0)<br />
System.out.print("MAYBEVOID|");<br />
if ((nAttribs & PropertyAttribute.BOUND) != 0)<br />
System.out.print("BOUND|");<br />
if ((nAttribs & PropertyAttribute.CONSTRAINED) != 0)<br />
System.out.print("CONSTRAINED|");<br />
if ((nAttribs & PropertyAttribute.READONLY) != 0)<br />
System.out.print("READONLY|");<br />
if ((nAttribs & PropertyAttribute.TRANSIENT) != 0)<br />
System.out.print("TRANSIENT|");<br />
if ((nAttribs & PropertyAttribute.MAYBEAMBIGUOUS ) != 0)<br />
System.out.print("MAYBEAMBIGUOUS|");<br />
if ((nAttribs & PropertyAttribute.MAYBEDEFAULT) != 0)<br />
System.out.print("MAYBEDEFAULT|");<br />
if ((nAttribs & PropertyAttribute.REMOVEABLE) != 0)<br />
System.out.print("REMOVEABLE|");<br />
System.out.println("0>");<br />
}<br />
} catch (Exception e) {<br />
// If anything goes wrong, give the user a stack trace<br />
e.printStackTrace(System.out);<br />
}<br />
</source><br />
The following is an example output for the code above. The output shows the names of the text cursor properties, and their handle, type and property attributes. The handle is not unique, since the specific object does not implement <idl>com.sun.star.beans.XFastPropertySet</idl>, so proper handles are not needed here.<br />
<br />
Using default connect string: socket,host=localhost,port=8100<br />
Opening an empty Writer document<br />
Property #0: Name<BorderDistance> Handle<93> Type<long> Attributes<MAYBEVOID|0><br />
Property #1: Name<BottomBorder> Handle<93> Type<com.sun.star.table.BorderLine> Attributes<MAYBEVOID|0><br />
Property #2: Name<BottomBorderDistance> Handle<93> Type<long> Attributes<MAYBEVOID|0><br />
Property #3: Name<BreakType> Handle<81> Type<com.sun.star.style.BreakType> Attributes<MAYBEVOID|0><br />
<br />
...<br />
<br />
Property #133: Name<TopBorderDistance> Handle<93> Type<long> Attributes<MAYBEVOID|0><br />
Property #134: Name<UnvisitedCharStyleName> Handle<38> =Type<string> Attributes<MAYBEVOID|0><br />
Property #135: Name<VisitedCharStyleName> Handle<38> Type<string> Attributes<MAYBEVOID|0><br />
<br />
In some cases properties are used to specify the options in a sequence of <idl>com.sun.star.beans.PropertyValue</idl>. See <idl>com.sun.star.view.PrintOptions</idl> or <idl>com.sun.star.document.MediaDescriptor</idl> for examples of properties in sequences. These are not accessed by the methods mentioned above, but by accessing the sequence specified in the language binding.<br />
<br />
==== Example: sequences of property values ====<br />
<br />
This example illustrates how to deal with sequences of property values:<br />
<source lang="java"><br />
// create a sequence of PropertyValue<br />
PropertyValue[] aArgs = new PropertyValue[2];<br />
<br />
// set name/value pairs (other fields are irrelevant here)<br />
aArgs[0] = new PropertyValue();<br />
aArgs[0].Name = "FilterName";<br />
aArgs[0].Value = "HTML (StarWriter)";<br />
aArgs[1] = new PropertyValue();<br />
aArgs[1].Name = "Overwrite";<br />
aArgs[1].Value = Boolean.TRUE;<br />
<br />
// use this sequence of PropertyValue as an argument<br />
// where a service with properties but without any interfaces is specified<br />
com.sun.star.frame.XStorable xStorable = (com.sun.star.frame.XStorable) UnoRuntime.queryInterface(<br />
com.sun.star.frame.XStorable.class, mxDoc);<br />
xStorable.storeAsURL("file:///tmp/devmanual-test.html", aArgs);<br />
</source><br />
Usually the properties supported by an object, as well as their type and flags are fixed over the lifetime of the object. There may be exceptions. If the properties can be added and removed externally, the interface <idl>com.sun.star.beans.XPropertyContainer</idl> has to be used. In this case, the fixed <idl>com.sun.star.beans.XPropertySetInfo</idl> changes its supplied information over the lifetime of the object. Listeners for such changes can register at <idl>com.sun.star.beans.XPropertyChangeListener</idl>.<br />
<br />
{{Documentation/Tip|If you use a component from other processes or remotely, try to adhere to the rule to use <idl>com.sun.star.beans.XPropertyAccess</idl> and <idl>com.sun.star.beans.XMultiPropertySet</idl> instead of having a separate call for each single property.}}<br />
<br />
The following diagram shows the relationship between the property-related interfaces.<br />
<br />
[[Image:Properties.png|none|thumb|400px|The relationship between property related interfaces]]<br />
<br />
=== Interface attributes ===<br />
<br />
Starting with {{PRODUCTNAME}} {{OOo2.x}}, interface attributes are comparable in expressiveness to the properties described above:<br />
<br />
* A <code>[property] T P</code> (with type <code>T</code> and name <code>P</code>) corresponds to an <code>[attribute] T P</code>.<br />
* A <code>[property, readonly] T P</code> corresponds to an <code>[attribute, readonly] T P</code>.<br />
* A <code>[property, bound] T P</code> corresponds to an <code>[attribute, bound] T P</code>.<br />
* A <code>[property, maybeambiguous] T P</code> corresponds to an <code>[attribute] com.sun.star.beans.Ambiguous<T> P</code>.<br />
* A <code>[property, maybedefault] T P</code> corresponds to an <code>[attribute] com.sun.star.beans.Defaulted<T> P</code>.<br />
* A <code>[property, maybevoid] T P</code> corresponds to an <code>[attribute] com.sun.star.beans.Optional<T> P</code>.<br />
* A <code>[property, optional] T P</code> corresponds to an <code>[attribute] T P { get raises (com.sun.star.beans.UnknownPropertyException); set raises (com.sun.star.beans.UnknownPropertyException); }</code>.<br />
* A <code>[property, constrained] T P</code> corresponds to an <code>[attribute] T P { set raises (com.sun.star.beans.PropertyVetoException); }</code>.<br />
<br />
Interface attributes offer the following advantages compared to properties:<br />
<br />
* The attributes an object supports follows directly from the description of the interface types the object supports.<br />
* Accessing an interface attribute is type-safe, whereas accessing a property uses the generic any. This is an advantage mainly in statically typed languages like Java and C++, where accessing an interface attribute typically also requires less code to be written than for accessing a generic property.<br />
<br />
The main disadvantage is that the set of interface attributes supported by an object is static, so that scenarios that exploit the dynamic nature of <code>XpropertySet</code>, and so on, do not map well to interface attributes. In cases where it might be useful to have all the interface attributes supported by an object also accessible via <code>XPropertySet</code> etc., the Java and C++ language bindings offer experimental, not yet published support to do just that.See [http://www.openoffice.org www.openoffice.org] to find out more.<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Professional UNO]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/Scripting/Scripting_Framework_URI_SpecificationDocumentation/DevGuide/Scripting/Scripting Framework URI Specification2015-08-07T11:52:50Z<p>BMarcelly: /* MACROPARAM */</p>
<hr />
<div>{{Documentation/DevGuide/ScriptingTOC<br />
|Scripting2d=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/Scripting/Writing a LanguageScriptProvider UNO Component From Scratch<br />
|NextPage=Documentation/DevGuide/Scripting/Storage of Scripts<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/Scripting/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:Scripting Framework URI Specification}}<br />
__NOTOC__<br />
=== General syntax ===<br />
The URI is a case-sensitive string. It is composed of fixed terms and three parameters:<br />
<code>vnd.sun.star.script:MACROPARAM?language=LANGPARAM&location=LOCPARAM</code><br />
<br />
where:<br />
* <code>MACROPARAM</code> identifies the script.<br />
* <code>LANGPARAM</code> identifies the <code>LanguageScriptProvider</code> needed to execute the script as described. Current language values : Basic, BeanShell, Java, JavaScript, Python <br />
* <code>LOCPARAM</code> identifies the container of the script, i.e. My Macros, or {{PRODUCTNAME}} Macros, or within the current document, or in an extension.<br />
<br />
As the syntax of these parameters depends on each <code>LanguageScriptProvider</code> they are described hereafter for each implemented language. Terms like <code>myLibrary</code>, <code>myMacro</code> are placeholders that stand for the names used in a real case.<br />
<br />
=== Basic script ===<br />
A Basic script is usually called : a macro. It may be a Sub or a Function.<br />
<br />
The Basic script is supposed to be created through the user interface, see section [[Documentation/DevGuide/Scripting/Editing,_Creating_and_Managing_Macros|Editing, Creating and Managing Macros]].<br />
==== LANGPARAM ====<br />
'''<code>Basic</code>'''<br />
==== LOCPARAM ====<br />
* macro in a library of My Macros : '''<code>application</code>'''<br />
* macro in a library of {{PRODUCTNAME}} Macros : '''<code>application</code>'''<br />
* macro in an extension installed for the current user : '''<code>application</code>'''<br />
* macro in an extension installed for all users : '''<code>application</code>'''<br />
* macro in a library of the document that calls the macro : '''<code>document</code>'''<br />
==== MACROPARAM ====<br />
The Basic macro <code>myMacro</code> is stored in module <code>myModule</code> itself stored in library <code>myLibrary</code>.<br />
* General case : the value of MACROPARAM is : '''<code>myLibrary.myModule.myMacro</code>'''<br />
* Basic script in an extension : same as above. The directory <code>myLibrary</code> containing the files constituting the Basic library must be stored in the extension package (see description in section [[Documentation/DevGuide/Basic/Application_Library_Container|Basic / Application Library Container]]).<br />
<br />
Remember that, unlike usual calls in Basic, you must respect the majuscules and minuscules of library, module, macro names.<br />
<br />
=== BeanShell script ===<br />
The BeanShell script is supposed to be created through the user interface, see section [[Documentation/DevGuide/Scripting/Editing,_Creating_and_Managing_Macros|Editing, Creating and Managing Macros]].<br />
==== LANGPARAM ====<br />
'''<code>BeanShell</code>'''<br />
==== LOCPARAM ====<br />
* script in a library of My Macros : '''<code>user</code>'''<br />
* script in a library of {{PRODUCTNAME}} Macros : '''<code>share</code>'''<br />
* script in an extension installed for the current user : '''<code>user:uno_packages/myExtension.oxt</code>''' where '''myExtension.oxt''' is the file name of the extension package.<br />
* script in an extension installed for all users : '''<code>share:uno_packages/myExtension.oxt</code>'''<br />
* script in a library of the document that calls the script : '''<code>document</code>'''<br />
==== MACROPARAM ====<br />
The BeanShell script <code>myMacro.bsh</code> is stored in library <code>myLibrary</code>.<br />
* General case : the value of MACROPARAM is : '''<code>myLibrary.myMacro.bsh</code>'''<br />
* BeanShell script in an extension : same as above. The directory <code>myLibrary</code> containing the BeanShell script file and '''parcel-descriptor.xml''' file must be stored in the extension package.<br />
<br />
=== Java script ===<br />
Java scripts are macros in compiled Java. This is different from language JavaScript. See section [[Documentation/DevGuide/Scripting/Writing_Macros#Compiling_and_Deploying_Java_macros|Scripting / Writing Macros / Compiling and Deploying Java macros]].<br />
==== LANGPARAM ====<br />
'''<code>Java</code>'''<br />
==== LOCPARAM ====<br />
* script in a library of My Macros : '''<code>user</code>'''<br />
* script in a library of {{PRODUCTNAME}} Macros : '''<code>share</code>'''<br />
* script in an extension installed for the current user : '''<code>user:uno_packages/myExtension.oxt</code>''' where '''myExtension.oxt''' is the file name of the extension package.<br />
* script in an extension installed for all users : '''<code>share:uno_packages/myExtension.oxt</code>'''<br />
* script in a library of the document that calls the script : '''<code>document</code>'''<br />
==== MACROPARAM ====<br />
The Java script file <code>myMacro.jar</code> is stored in directory <code>myLibrary</code>. The Java method to be executed is <code>myMethod</code> (this is the value of <code>functionname</code> element of the '''parcel-descriptor.xml''' file).<br />
* General case : the value of MACROPARAM is : '''<code>myLibrary.myMethod</code>'''<br />
* Java compiled script in an extension : same as above. The directory <code>myLibrary</code> must be stored in the extension package.<br />
<br />
=== JavaScript script ===<br />
The JavaScript script is supposed to be created through the user interface, see section [[Documentation/DevGuide/Scripting/Editing,_Creating_and_Managing_Macros|Editing, Creating and Managing Macros]].<br />
==== LANGPARAM ====<br />
'''<code>JavaScript</code>'''<br />
==== LOCPARAM ====<br />
* script in a library of My Macros : '''<code>user</code>'''<br />
* script in a library of {{PRODUCTNAME}} Macros : '''<code>share</code>'''<br />
* script in an extension installed for the current user : '''<code>user:uno_packages/myExtension.oxt</code>''' where '''myExtension.oxt''' is the file name of the extension package.<br />
* script in an extension installed for all users : '''<code>share:uno_packages/myExtension.oxt</code>'''<br />
* script in a library of the document that calls the script : '''<code>document</code>'''<br />
==== MACROPARAM ====<br />
The JavaScript file <code>myMacro.js</code> is stored in library <code>myLibrary</code>.<br />
* General case : the value of MACROPARAM is : '''<code>myLibrary.myMacro.js</code>'''<br />
* JavaScript script in an extension : same as above. The directory <code>myLibrary</code> containing the JavaScript file and '''parcel-descriptor.xml''' file must be stored in the extension package.<br />
<br />
=== Python script ===<br />
The location of a Python script is described in [[Python_as_a_macro_language|Python as a macro language]].<br />
==== LANGPARAM ====<br />
'''<code>Python</code>'''<br />
==== LOCPARAM ====<br />
* script in a library of My Macros : '''<code>user</code>'''<br />
* script in a library of {{PRODUCTNAME}} Macros : '''<code>share</code>'''<br />
* script in an extension installed for the current user : '''<code>user:uno_packages</code>'''<br />
* script in an extension installed for all users : '''<code>share:uno_packages</code>'''<br />
* script in a library of the document that calls the script : '''<code>document</code>'''<br />
==== MACROPARAM ====<br />
* General case : the Python module <code>myModule.py</code> is stored in directory <code>Scripts/python</code> of the user or share directory of the installation, or of the document. The name of the Python function to be executed is <code>myFunction</code>. The value of MACROPARAM is : '''<code>myModule.py$myFunction</code>'''<br />
* Python script in an extension : '''myExtension.oxt''' is the file name of the extension package. The Python module is stored in directory <code>myScript</code> in this package. The value of MACROPARAM is : '''<code>myExtension.oxt|myScript|myModule.py$myFunction</code>'''<br />
<br />
=== Complete URI examples ===<br />
These URI's call a script stored in My Macros<br />
vnd.sun.star.script:myLibrary.myModule.myMacro?language=Basic&location=application<br />
vnd.sun.star.script:myLibrary.myMacro.bsh?language=BeanShell&location=user<br />
vnd.sun.star.script:myLibrary.myMethod?language=Java&location=user<br />
vnd.sun.star.script:myLibrary.myMacro.js?language=JavaScript&location=user<br />
vnd.sun.star.script:myModule.py$myFunction?language=Python&location=user<br />
<br />
<br />
These URI's call a script stored in an extension ''installed for all users''<br />
vnd.sun.star.script:myLibrary.myModule.myMacro?language=Basic&location=application<br />
vnd.sun.star.script:myLibrary.myMacro.bsh?language=BeanShell&location=share:uno_packages/myExtension.oxt<br />
vnd.sun.star.script:myLibrary.myMethod?language=Java&location=share:uno_packages/myExtension.oxt<br />
vnd.sun.star.script:myLibrary.myMacro.js?language=JavaScript&location=share:uno_packages/myExtension.oxt<br />
vnd.sun.star.script:myExtension.oxt|myScript|myModule.py$myFunction?language=Python&location=share:uno_packages<br />
<br />
{{Documentation/Caution|As a consequence of the current URI syntax, an extension calling a non-Basic script must be created either for one user, or for all users, not both. You need one extension for each installation case, see {{bug|102542}}}}.<br />
<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Scripting]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/Extensions/Extension_LayersDocumentation/DevGuide/Extensions/Extension Layers2015-08-07T08:47:06Z<p>BMarcelly: Corrected page title</p>
<hr />
<div>{{Documentation/DevGuide/ExtensionsTOC<br />
|Extensions2a=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/Extensions/Location of Installed Extensions<br />
|NextPage=Documentation/DevGuide/Extensions/Checklist for Writing Extensions<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/Extensions/{{SUBPAGENAME}}}}<br />
{{DISPLAYTITLE:Extension Layers}}<br />
__NOTOC__<br />
The Extension Manager uses two extension layers, the user and the shared layer. Extensions installed in the shared layer can be used by all users whereas those in the user layer can only be used by the user who installed them. An extension can be installed in either layer or both. <br />
<br />
This system was developed many years ago. Since then new features were added, such as extension versioning, online update, bundled extensions, etc. During that time it became obvious that there are some problems with the original design. This document tries to explain them. <br />
==Current problems==<br />
<br />
=== Hiding ===<br />
The idea of layers is that extensions in the top layer '''hide''' the same extensions in the layer below. In other words, the extension in the highest layer will be given preference, when resources from the extension are requested. Because the user layer is the top layer, a shared extension is only used when the same extension does not exist in the user layer. The version of the extension has no influence.<br />
<br />
This, however, is only a simplified model. An extension is never used as a whole. Instead clients access the particular contents, such as components, configuration data, etc. And it is also these contents which obscure the same content in a lower layer. For example, an extension contains a UNO service, which is installed in both layers. When the client instantiates it then the one from the top layer is used.<br />
<br />
There are situations where contents of the shared extensions are still used, although they should be hidden and therefore not usable. Assuming there are version 1 and version 2 of an extension. Then the different versions may have different content. For example, version 1 may contain a service ''foo'' which is not contained in version 2. If now version 1 is installed in the shared layer and version 2 in the user layer then ''foo'' is still around and can be instantiated. Foo may access resources which are also delivered with this extension and are also available in version 2 which is in the user layer. Resources in version 2, which hide those from version 1 (same node in xcu or same service), can be incompatible, so that foo fails.<br />
<br />
A service may also need files which are part of the same extension and which are only directly accessible. That is there is no API, such as the registry or service manager, which can provide the content. A "running" service does not know from which layer it comes from. To get the install location it can use the [[Documentation/DevGuide/Extensions/Location of Installed Extensions|PackageInformationProvider]]. This service will first look into user layer and if the extension cannot be found, then it will look into the shared layer. If now the service from the shared layer needs some file from its extension, then it may accidentally use the one from a different version of the extension in the user layer. This file can be incompatible or not even exist and make the service fail.<br />
<br />
Another example can be constructed using registry values, which are contained in xcu files. Let's assume that version 1 of an extension adds a menu ''foo'' and version 2 adds menu ''bar''. If one extension is installed in the share and the other in the user layer, then both menus appear. This is because the nodes of the configuration files are merged into the configuration and not the xcu files itself. That is, if the extensions contain an xcu file with the same name, then the xcu file of the last installed extension will NOT replace the one from the other extension. The second xcu file can, however, change the values for nodes which have been defined by the first xcu.<br />
<br />
These examples prove that the layering (in terms of hiding the items from the layer below) on extension level does not work, although it does for the respective [[Documentation/DevGuide/Extensions/Deployment Items|deployment items]]. And it may be safe to say, that this goes against the user's expectation.<br />
<br />
===Unclear behavior===<br />
It may be unclear to users how the behavior is when the same extension is installed as user and shared extension. If there is a shared extension and the same extension is installed as user extension, then the user should be informed that the currently installed extension will become 'inactive'. Then, when the user extension is uninstalled, the user should be informed that the shared extension will become 'active' again.<br />
<br />
=== Extension versions ===<br />
<br />
As already observed, the version of an extension has no influence on the decision if the extension from the user or the shared layer is used. At the time of developing the extension framework there was no support for versioned extensions, so one did not have to care about them. Later, we recognized that an extension version is useful for users. For example, if one has an extension installed and is installing the same extension again, then one is being informed about what extension has the later version (so one can decide which is the best for them). <br />
<br />
I think the general expectation is that the latest version is the best. Therefore it should be natural that OOo uses always that one. However, this is not the case and users may unintentionally prevent, that they use the latest extension. For example, OOo comes with a bundled English dictionary. Now a user installs, intentionally or not, the same extension and forgets about it. The administrator updates OOo regularly, which also updates the dictionary with the latest version. But the user would still use the old dictionary, because that is the one from the user layer which hides the one from the shared layer.<br />
<br />
One could think now of a notification for the user but there are some questions:<br />
*when does OOo check for this situation? <br />
*how can this be explained to the user? <br />
The first question, is easily answered: At every start-up.<br />
<br />
The second question is more difficult.Think about a message, such as: "Dear user. You cannot use the latest version of the french dictionary, which is installed in the shared/bundled layer. Instead the dictionary which you installed earlier is used. You need to uninstall it, if you want the new version ...." <br />
Many users would probably not understand this. So the easiest and natural way is simply to use the latest version of the extension indepedent of what layer it is installed in. The term layer should then be replaced, by repository, indicating that the location does not include a preference – just think about the picture of one layer above the other compared to repositories which are arranged in one row. <br />
<br />
=== Layer location ===<br />
<br />
The shared layer is located within the OOo installation. The benefit is that normal users cannot modify it. The layer will be modified after installation of OOo when an extensions is added, deleted, enabled or disabled. Depending on the operation system, this may be against the system guidelines. For example, it would be not allowed on Windows Vista/ 7. However, to allow “legacy application” to work Microsoft invented the virtual store. <br />
<br />
=== Clean uninstallation ===<br />
<br />
Modification of the shared layer will also prevent the clean uninstallation of OOo. This is because the native installer does not “own” the files/folder which were added by the extension manager. For example, on Linux the path /opt/openoffice.org3/share/uno_packages will remain on the system. On OpenSolaris the shared extensions (with the same directory structure) will be copied to /var/lost+found on uninstallation.<br />
<br />
=== No Separation of shared and bundled extensions ===<br />
The rule is, whatever a user installed should not be removed by OOo. This is also valid for shared extensions. Today a bundled extension is nothing else than a shared extension and therefore can be modified by users, provided they have sufficient file access rights. They can install the same extension as one, which was installed as bundled extension, in the shared layer. This means that the original bundled extension is replaced by the recently installed shared extension. This can happen in two scenarios. The first one is during an online update of the extension and the second is when the extension is “manually” installed. In these cases users intentionally choose to replace the original extension. Therefore this extension may not be deleted when uninstalling OOo. This, however, requires to know that the bundled extension was replaced, but there is currently no way to recognize this.<br />
<br />
<br />
===Selection of extensions in setup===<br />
Like many other features, bundled extensions should be selectable in the dialog of the installer. The installer can also be invoked later to add or remove particular features. The problem is, that the extensions which the installer “sees” are not the same as “seen” by the extension manager. The setup copies an oxt file to ../share/extension/install and then invokes a post-install script (Unix) or a custom action (Windows) which runs unopkg to install the extension properly. The extension is then unzipped to ../share/uno_packages/cache/uno_packages and some data are added to the extension manager database. The installer only knows the file that it copied to the ../share/extension/install folder. If it is there then it is regarded as installed – otherwise not.<br />
<br />
For an extension to show up in the dialog of the extension manager, there are two conditions which need to be met. First, it must be unpacked in the uno_packages folder. And second, there must be an appropriate entry in the extension manager database, indicating that it is installed. Therefore it would be possible that the installer displayed an extension as being installed but the extension manager did not. This may of course happen the other way round as well.<br />
<br />
Even if the installer would copy the uncompressed extension directly to ../share/uno_packages/cache/uno_packages, both dialogs could show a different status. One could assume that the installer and extension manager regard an extension as installed if the the respective folder exists. But this does not work, because the extension manager does not remove immediately the extension when it is being uninstalled. The reason is, that files from the extension can still be in use in the process. Only after restarting OOo and the extension manager, the extension's folder will be finally removed.<br />
<br />
===Code execution during installation===<br />
Copying extensions into the office installation during setup is not sufficient to make them usable. Only after the extension manager has processed them, OOo can make use of them. Therefore the installer invokes the extension manager after an extension has been copied. Unfortunately this requires different solutions for different platforms. RPM (Linux) and PKG (Solaris) use post-install/pre-install scripts which are executed after the copying step. But there are installation scenarios on Solaris, where code execution is not allowed during the setup. For example, the installer is running on Solaris Sparc and installs OOo on a Solaris Intel Machine machine. Therefore OOo uses a “postrun” service which invokes the extension manager when the system is rebooted. OpenSolaris prohibits code execution completely. The setup needs to install an SMF service which is triggered after the setup. Windows needs a 'custom action' which is compiled native code. The Mac dmg file already contains the processed extensions. That is, the extension manager processes the extension while building the dmg file.<br />
<br />
It is obvious that the current situation is complex and one understands why testing and bug finding are rather difficult.<br />
<br />
===Extension Manager database===<br />
The database is created when the extension manager is started for the first time. The database contains different files and folders which are completely unknown to the installer. Therefore the installer will not remove them. This is another reason why the OpenOffice.org folder remains on the system after uninstalling OOo.<br />
<br />
=== License of shared extension cannot be displayed to users ===<br />
Only the one who installs the extension can see the license.<br />
<br />
<br />
<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Extensions]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Extensions_developmentExtensions development2015-07-09T21:40:22Z<p>BMarcelly: /* Books on OpenOffice.org Basic Programming */ update last reference</p>
<hr />
<div>{{Extensions}}<br />
Developing extensions is an efficient way to bring value to OpenOffice.org without diving into core sources. Obviously all developers willing to [[Main_Page|develop at OpenOffice.org sources level]] are welcomed.<br />
<br />
OpenOffice.org enables third party tools creation through UNO bridges, allowing using many languages.<br />
<br />
The principle is to create UNO packages that can be listed in the OpenOffice.org [http://extensions.services.openoffice.org Extensions repository] and installed by end-users easily.<br />
<br />
This section gives newcomers as well as experienced developers some hints for developing Extensions in various languages and provides tools and frameworks to facilitate that development.<br />
<br />
Popular Extensions may be integrated into OpenOffice.org, so it is important to follow common policies from beginning to ease this merging.<br />
<br />
Finally, extension developers are invited to join our [http://openoffice.apache.org/mailing-lists.html#api-mailing-list-public API mailing list] to ask questions and share ideas.<br />
<br />
==== Starting in a language ====<br />
Addons can be written in various languages. Each section gives starting information to help you create your addon. Each section is dedicated to a language. It deals with specific points concerning the Extensions aspect. Resources regarding the OpenOffice.org API can be found on the [http://api.openoffice.org API project] and the UNO bridge language issues are at [http://udk.openoffice.org UDK project]. The [http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/OpenOffice.org_Developers_Guide OpenOffice.org Developer's Guide] is a valuable source of information as well.<br />
<br />
The translations of these pages are welcomed and [[Extensions#Translating_these_pages|guidelines are available]].<br />
<br />
* [[Extensions_development_python|Starting in Python]]<br />
* [[Extensions_development_basic|Starting in Basic]] and [[Documentation/BASIC_Guide|Documentation BASIC Guide]]<br />
* [[Extensions_development_java|Starting in Java]]<br />
* [[Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno|Introduction to C++ and UNO]] and [[Using_Cpp_with_the_OOo_SDK|Using C++ with OOoSDK]]<br />
* [[Extensions_development_vfp|Starting in Visual FoxPro (French)]]<br />
* [[Non-code_extensions|Non programmatic Extensions]]<br />
* [[Extensions_packaging|Extensions packaging]]<br />
* [[Extensions_Integration_into_Installation_Set|Extensions Integration into Installation Set]]<br />
* [[Spellchecker_Integration_into_Installation_Set|Adding Spellchecker Extensions into Installation Set]]<br />
* [[Filter_extensions|Import and Export filter extensions using code or xslt]]<br />
<br />
==== Articles, Tutorials & Reference Information ====<br />
<br />
* [[Framework/Article/Generic_UNO_Interfaces_for_complex_toolbar_controls|Generic UNO Interfaces for complex toolbar controls]] <br />
<br />
* [[Framework/Article/Addon_Menu_Toolbar_Merging|Addon Menu Toolbar Merging]] <br />
<br />
* [[Framework/Tutorial/Popup_Menu_Controller|Popup Menu Controller]]<br />
<br />
* [[Framework/Tutorial/Statusbar_Controller|Statusbar Controller]]<br />
<br />
* [[Documentation/DevGuide/Extensions/Extensions|DevGuide -- Extensions]]<br />
<br />
==== Books on OpenOffice.org Basic Programming ====<br />
<br />
* [http://www.amazon.com/OpenOffice-org-Macros-Explained-Andrew-Pitonyak/dp/1930919514/ OpenOffice.org Macros Explained] by Andrew Pitonyak<br />
* [http://www.lulu.com/content/2905912 OpenOffice.org Basic Crash Course] by Dmitri Popov<br />
* [http://www.amazon.com/Learn-OpenOffice-org-Spreadsheet-Macro-Programming/dp/1847190979/ Learn OpenOffice.org Spreadsheet Macro Programming] by Mark, Alexander Bain<br />
* [http://www.amazon.de/Makros-OpenOffice-org-2-3-StarBasic-OpenOffice/dp/3836211114/ Makros in OpenOffice.org 2.3] von Thomas Krumbein (in German)<br />
* [http://www.eyrolles.com/Informatique/Livre/programmation-openoffice-org-et-libreoffice-9782212132472 Programmation OpenOffice.org et LibreOffice] de Bernard Marcelly, Laurent Godard (in French)<br />
<br />
==== Tools & Frameworks ====<br />
<br />
* [http://codesnippets.services.openoffice.org Code snippets available in many languages]<br />
* [[API/Samples|Code snippets in the Wiki]] (Sample extensions, etc.)<br />
* [[Extensions_development_translation|Translation framework]]<br />
* [[Extensions_Packager|Extensions Packager]] - BasicAddonBuilder - Extension Compiler<br />
* Predefined wizards<br />
* [[Extensions_introspection|Introspection Tools]]: discover the API<br />
* [[OpenOffice_Eclipse_Integration|OpenOffice.org Eclipse Integration]] - OpenOffice.org development with Eclipse<br />
* [[OpenOffice_NetBeans_Integration|OpenOffice.org NetBeans Integration]] - plug-in for NetBeans providing some nice features to simplify the development with and for OpenOffice.org (highlevel wizards, UNOIDL and xcu syntax highlighting, code completion, integrated API reference, ...)<br />
* [[Extension_Development_with_IntelliJ_IDEA|Extension Development with IntelliJ IDEA]]: simple introduction how you can use the IntelliJ IDEA to develop OpenOffice.org extensions.<br />
* [[OpenOffice_Maven2_Integration|OpenOffice.org Maven 2 integration]] - Maven plugin to build OpenOffice.org extensions.<br />
* [[OpenOffice_CMake_Integration|OpenOffice.org CMake integration]] - CMake module for development of OpenOffice.org extensions and other OpenOffice.org-relate projects.<br />
<br />
==== Best Practices ====<br />
* [[Extensions_best_practices|How to write OO.o GUI Extensions today]]<br />
<br />
==== Project: Enhancing the Extensions Infrastructure of OpenOffice.org ====<br />
* [[Extensions_improvements_proposal|Project Proposal (agreed by the Community June 2006)]]<br />
* [[Extensions_improvements_plan_and_status|Project Status]]<br />
<br />
==== Improving the Extension Manager ====<br />
* [[Extensions_feature_ideas|Feature ideas]]<br />
[[Category:Extensions]]<br />
[[Category:Build_System]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Filter_OptionsDocumentation/DevGuide/Spreadsheets/Filter Options2015-07-08T09:50:39Z<p>BMarcelly: /* Filter Options for the CSV Filter */ document tokens 6,7,8</p>
<hr />
<div>{{Documentation/DevGuide/SpreadsheetsTOC<br />
|SpreadsheetDocs2b=block<br />
|SpreadsheetDocsSaving=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/Spreadsheets/Saving Spreadsheet Documents<br />
|NextPage=Documentation/DevGuide/Spreadsheets/Printing Spreadsheet Documents<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/Spreadsheets/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:Filter Options}}<br />
Loading and saving {{PRODUCTNAME}} API documents is described in [[Documentation/DevGuide/OfficeDev/Handling Documents|Handling Documents]]. This section lists all the filter names for spreadsheet documents and describes the filter options for text file import.<br />
<br />
The filter name and options are passed on loading or saving a document in a sequence of <idl>com.sun.star.beans.PropertyValue</idl>s. The property <code>FilterName</code> contains the name and the property <code>FilterOptions</code> contains the filter options.<br />
<br />
{{Documentation/Note|All filter names are case-sensitive. For compatibility reasons the filter names will not be changed. Therefore, some of the filters seem to have "curious" names.}}<br />
<br />
The list of filter names (the last two columns show the possible directions of the filters):<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Filter name <br />
!Description <br />
!Import <br />
!Export <br />
|-<br />
|StarOffice XML (Calc) <br />
|Standard XML filter <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|calc_StarOffice_XML_Calc_Template <br />
|XML filter for templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 5.0 <br />
|The binary format of StarOffice Calc 5.x <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 5.0 Vorlage/Template <br />
|StarOffice Calc 5.x templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 4.0 <br />
|The binary format of StarCalc 4.x <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 4.0 Vorlage/Template <br />
|StarCalc 4.x templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 3.0 <br />
|The binary format of StarCalc 3.x <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|StarCalc 3.0 Vorlage/Template <br />
|StarCalc 3.x templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|HTML (StarCalc) <br />
|HTML filter <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|calc_HTML_WebQuery <br />
|HTML filter for external data queries <br />
|<center>●</center> <br />
| <br />
|-<br />
|MS Excel 97 <br />
|Microsoft Excel 97/2000/XP <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 97 Vorlage/Template <br />
|Microsoft Excel 97/2000/XP templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 95 <br />
|Microsoft Excel 5.0/95 <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 5.0/95 <br />
|Different name for the same filter <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 95 Vorlage/Template <br />
|Microsoft Excel 5.0/95 templates <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 5.0/95 Vorlage/Template <br />
|Different name for the same filter <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|MS Excel 4.0 <br />
|Microsoft Excel 2.1/3.0/4.0 <br />
|<center>●</center> <br />
| <br />
|-<br />
|MS Excel 4.0 Vorlage/Template <br />
|Microsoft Excel 2.1/3.0/4.0 templates <br />
|<center>●</center> <br />
| <br />
|-<br />
|Lotus <br />
|Lotus 1-2-3 <br />
|<center>●</center> <br />
| <br />
|-<br />
|Text - txt - csv (StarCalc) <br />
|Comma separated values <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|Rich Text Format (StarCalc) <br />
| <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|dBase <br />
| <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|SYLK <br />
|Symbolic Link <br />
|<center>●</center> <br />
|<center>●</center> <br />
|-<br />
|DIF <br />
|Data Interchange Format <br />
|<center>●</center> <br />
|<center>●</center> <br />
|}<br />
<br />
=== Filter Options for Lotus, dBase and DIF Filters ===<br />
<br />
These filters accept a string containing the numerical index of the used character set for single-byte characters, that is, 0 for the system character set.<br />
<br />
The numerical indexes assigned to the character sets:<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Character Set<br />
!Index<br />
|-<br />
|Unknown<br />
|0<br />
|-<br />
|Windows-1252/WinLatin 1 (Western)<br />
|1<br />
|-<br />
|Apple Macintosh (Western)<br />
|2<br />
|-<br />
|DOS/OS2-437/US (Western)<br />
|3<br />
|-<br />
|DOS/OS2-850/International (Western)<br />
|4<br />
|-<br />
|DOS/OS2-860/Portuguese (Western)<br />
|5<br />
|-<br />
|DOS/OS2-861/Icelandic (Western)<br />
|6<br />
|-<br />
|DOS/OS2-863/Canadian-French (Western)<br />
|7<br />
|-<br />
|DOS/OS2-865/Nordic (Western)<br />
|8<br />
|-<br />
|System default<br />
|9<br />
|-<br />
|Symbol<br />
|10<br />
|-<br />
|ASCII/US (Western)<br />
|11<br />
|-<br />
|ISO-8859-1 (Western)<br />
|12<br />
|-<br />
|ISO-8859-2 (Central European)<br />
|13<br />
|-<br />
|ISO-8859-3 (Latin 3)<br />
|14<br />
|-<br />
|ISO-8859-4 (Baltic)<br />
|15<br />
|-<br />
|ISO-8859-5 (Cyrillic)<br />
|16<br />
|-<br />
|ISO-8859-6 (Arabic)<br />
|17<br />
|-<br />
|ISO-8859-7 (Greek)<br />
|18<br />
|-<br />
|ISO-8859-8 (Hebrew)<br />
|19<br />
|-<br />
|ISO-8859-9 (Turkish)<br />
|20<br />
|-<br />
|ISO-8859-14 (Western)<br />
|21<br />
|-<br />
|ISO-8859-15/EURO (Western)<br />
|22<br />
|-<br />
|DOS/OS2-737 (Greek)<br />
|23<br />
|-<br />
|DOS/OS2-775 (Baltic)<br />
|24<br />
|-<br />
|DOS/OS2-852 (Central European)<br />
|25<br />
|-<br />
|DOS/OS2-855 (Cyrillic)<br />
|26<br />
|-<br />
|DOS/OS2-857 (Turkish)<br />
|27<br />
|-<br />
|DOS/OS2-862 (Hebrew)<br />
|28<br />
|-<br />
|DOS/OS2-864 (Arabic)<br />
|29<br />
|-<br />
|DOS/OS2-866/Russian (Cyrillic)<br />
|30<br />
|-<br />
|DOS/OS2-869/Modern (Greek)<br />
|31<br />
|-<br />
|DOS/Windows-874 (Thai)<br />
|32<br />
|-<br />
|Windows-1250/WinLatin 2 (Central European)<br />
|33<br />
|-<br />
|Windows-1251 (Cyrillic)<br />
|34<br />
|-<br />
|Windows-1253 (Greek)<br />
|35<br />
|-<br />
|Windows-1254 (Turkish)<br />
|36<br />
|-<br />
|Windows-1255 (Hebrew)<br />
|37<br />
|-<br />
|Windows-1256 (Arabic)<br />
|38<br />
|-<br />
|Windows-1257 (Baltic)<br />
|39<br />
|-<br />
|Windows-1258 (Vietnamese)<br />
|40<br />
|-<br />
|Apple Macintosh (Arabic)<br />
|41<br />
|-<br />
|Apple Macintosh (Central European)<br />
|42<br />
|-<br />
|Apple Macintosh/Croatian (Central European)<br />
|43<br />
|-<br />
|Apple Macintosh (Cyrillic)<br />
|44<br />
|-<br />
|''Not supported:'' Apple Macintosh (Devanagari)<br />
|45<br />
|-<br />
|''Not supported:'' Apple Macintosh (Farsi)<br />
|46<br />
|-<br />
|Apple Macintosh (Greek)<br />
|47<br />
|-<br />
|''Not supported:'' Apple Macintosh (Gujarati)<br />
|48<br />
|-<br />
|''Not supported:'' Apple Macintosh (Gurmukhi)<br />
|49<br />
|-<br />
|Apple Macintosh (Hebrew)<br />
|50<br />
|-<br />
|Apple Macintosh/Icelandic (Western)<br />
|51<br />
|-<br />
|Apple Macintosh/Romanian (Central European)<br />
|52<br />
|-<br />
|Apple Macintosh (Thai)<br />
|53<br />
|-<br />
|Apple Macintosh (Turkish)<br />
|54<br />
|-<br />
|Apple Macintosh/Ukrainian (Cyrillic)<br />
|55<br />
|-<br />
|Apple Macintosh (Chinese Simplified)<br />
|56<br />
|-<br />
|Apple Macintosh (Chinese Traditional)<br />
|57<br />
|-<br />
|Apple Macintosh (Japanese)<br />
|58<br />
|-<br />
|Apple Macintosh (Korean)<br />
|59<br />
|-<br />
|Windows-932 (Japanese)<br />
|60<br />
|-<br />
|Windows-936 (Chinese Simplified)<br />
|61<br />
|-<br />
|Windows-Wansung-949 (Korean)<br />
|62<br />
|-<br />
|Windows-950 (Chinese Traditional)<br />
|63<br />
|-<br />
|Shift-JIS (Japanese)<br />
|64<br />
|-<br />
|GB-2312 (Chinese Simplified)<br />
|65<br />
|-<br />
|GBT-12345 (Chinese Traditional)<br />
|66<br />
|-<br />
|GBK/GB-2312-80 (Chinese Simplified)<br />
|67<br />
|-<br />
|BIG5 (Chinese Traditional)<br />
|68<br />
|-<br />
|EUC-JP (Japanese)<br />
|69<br />
|-<br />
|EUC-CN (Chinese Simplified)<br />
|70<br />
|-<br />
|EUC-TW (Chinese Traditional)<br />
|71<br />
|-<br />
|ISO-2022-JP (Japanese)<br />
|72<br />
|-<br />
|ISO-2022-CN (Chinese Simplified)<br />
|73<br />
|-<br />
|KOI8-R (Cyrillic)<br />
|74<br />
|-<br />
|Unicode (UTF-7)<br />
|75<br />
|-<br />
|Unicode (UTF-8)<br />
|76<br />
|-<br />
|ISO-8859-10 (Central European)<br />
|77<br />
|-<br />
|ISO-8859-13 (Central European)<br />
|78<br />
|-<br />
|EUC-KR (Korean)<br />
|79<br />
|-<br />
|ISO-2022-KR (Korean)<br />
|80<br />
|-<br />
|JIS 0201 (Japanese)<br />
|81<br />
|-<br />
|JIS 0208 (Japanese)<br />
|82<br />
|-<br />
|JIS 0212 (Japanese)<br />
|83<br />
|-<br />
|Windows-Johab-1361 (Korean)<br />
|84<br />
|-<br />
|GB-18030 (Chinese Simplified)<br />
|85<br />
|-<br />
|BIG5-HKSCS (Chinese Traditional)<br />
|86<br />
|-<br />
|TIS 620 (Thai)<br />
|87<br />
|-<br />
|KOI8-U (Cyrillic)<br />
|88<br />
|-<br />
|ISCII Devanagari (Indian)<br />
|89<br />
|-<br />
|Unicode (Java's modified UTF-8)<br />
|90<br />
|-<br />
|Adobe Standard<br />
|91<br />
|-<br />
|Adobe Symbol<br />
|92<br />
|-<br />
|PT 154 (Windows Cyrillic Asian codepage <br />developed in ParaType)<br />
|93<br />
|-<br />
|Unicode UCS4<br />
|65534<br />
|-<br />
|Unicode UCS2<br />
|65535<br />
|}<br />
<br />
=== Filter Options for the CSV Filter ===<br />
<br />
This filter accepts an option string containing five to eight tokens, separated by commas. Tokens 6, 7, 8 are optional.<br />
<br />
The following table shows an example string for a file with four columns of type date - number - number - number. In the table the tokens are numbered from (1) to (5). Each token is explained below.<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!rowspan="2"|Example Filter Options String <br />
!rowspan="2"|Field Separator (1) <br />
!rowspan="2"|Text Delimiter (2) <br />
!rowspan="2"|Character Set (3) <br />
!rowspan="2"|Number of First Line (4) <br />
!colspan="2"|Cell Format Codes for the four Columns (5) <br />
|-bgcolor=#EDEDED<br />
!Column <br />
!Code <br />
|-<br />
|File Format: <br />
Four columns<br />
date-num-num-num <br />
| , <br />
| " <br />
|System <br />
|line no. 1 <br />
|1<br><br />
2<br><br />
3<br><br />
4 <br />
|YY/MM/DD = 5<br><br />
Standard = 1<br><br />
Standard = 1<br><br />
Standard = 1 <br />
|-<br />
|Token <br />
|44 <br />
|34 <br />
|0 <br />
|1 <br />
|colspan="2"|1/5/2/1/3/1/4/1 <br />
|}<br />
<br />
For the filter options above, set the PropertyValue <code>FilterOptions</code> in the load arguments to "44,34,0,1,1/5/2/1/3/1/4/1". There are a number of possible settings for the five tokens.<br />
<br />
# Field separator(s) as ASCII values. Multiple values are separated by the slash sign ("/"), that is, if the values are separated by semicolons and horizontal tabulators, the token would be 59/9. To treat several consecutive separators as one, the four letters /MRG have to be appended to the token. If the file contains fixed width fields, the three letters FIX are used.<br />
# The text delimiter as ASCII value, that is, 34 for double quotes and 39 for single quotes.<br />
# The character set used in the file as described above.<br />
# Number of the first line to convert. The first line in the file has the number 1.<br />
# Cell format of the columns. The content of this token depends on the value of the first token.<br />
::* If value separators are used, the form of this token is column/format[/column/format/...] where column is the number of the column, with 1 being the leftmost column. The format is explained below.<br />
::* If the first token is FIX it has the form ''start/format''[''/start/format/...''], where start is the number of the first character for this field, with 0 being the leftmost character in a line. The format is explained below.<br />
::Format specifies which cell format should be used for a field during import:<br />
<br />
::{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Format Code <br />
!Meaning <br />
|-<br />
|1 <br />
|Standard <br />
|-<br />
|2 <br />
|Text <br />
|-<br />
|3 <br />
|MM/DD/YY <br />
|-<br />
|4 <br />
|DD/MM/YY <br />
|-<br />
|5 <br />
|YY/MM/DD <br />
|-<br />
|6 <br />
| - <br />
|-<br />
|7 <br />
| - <br />
|-<br />
|8 <br />
| - <br />
|-<br />
|9 <br />
|ignore field (do not import) <br />
|-<br />
|10 <br />
|US-English <br />
|}<br />
<br />
::The type code 10 indicates that the content of a field is US-English. This is useful if a field contains decimal numbers that are formatted according to the US system (using "." as decimal separator and "," as thousands separator). Using 10 as a format specifier for this field tells {{PRODUCTNAME}} API to correctly interpret its numerical content, even if the decimal and thousands separator in the current language are different.<br />
<br />
<br />
Token 6 : Language identifier<br />
<br />
This token is the equivalent of the "Language" listbox in the user interface for csv import.<br><br />
It is a String expressed in decimal notation. If the value is 0 or omitted, the language identifier of the user interface is used.<br />
<br />
The language identifier is based on the Microsoft language identifiers, for further information please see: <br />
<br />
Language Identifier Constants and Strings<br><br />
https://msdn.microsoft.com/en-us/library/windows/desktop/dd318693%28v=vs.85%29.aspx <br />
<br />
Use the decimal notation, example for English US : 1033 whereas Microsoft documentation uses hexadecimal notation 0x0409.<br />
<br />
<br />
Token 7 : Quoted string as text<br />
<br />
String, either <code>false</code> or <code>true</code>. The default value is <code>false</code>.<br />
This token is the equivalent of the check box of same name in the user interface for csv import.<br />
<br />
<br />
Token 8 : Detect special number<br />
<br />
String, either <code>false</code> or <code>true</code>. The default value is <code>false</code>.<br />
This token is the equivalent of the check box of same name in the user interface for csv import.<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Spreadsheet Documents]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/OfficeDev/Predefined_VariablesDocumentation/DevGuide/OfficeDev/Predefined Variables2015-07-08T08:32:18Z<p>BMarcelly: Replaced obsolete links to Microsoft doc. Added remark on decimal notation.</p>
<hr />
<div>{{Documentation/DevGuide/OfficeDevTOC<br />
|OfficeDev2b=block<br />
|OfficeDevPath=block<br />
|OfficeDevPathOrg=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/OfficeDev/Path Variables<br />
|NextPage=Documentation/DevGuide/OfficeDev/Custom Path Variables<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/OfficeDev/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:Predefined Variables}}<br />
The path substitution service supports a number of predefined path variables. They provide information about the paths that {{PRODUCTNAME}} currently uses. They are implemented as read-only values and cannot be modified.<br />
<br />
The predefined path variables can be separated into three distinct groups. The first group of variables specifies a ''single path'', the second group specifies a ''list of paths'' that are separated by the shell or operating system dependent character, and the third group specifies only a ''part of a path''.<br />
<br />
All predefined variable names are case insensitive, as opposed to the user-defined variables that are described below.<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!colspan="3"|Predefined variables supported by service <idl>com.sun.star.util.PathSubstitution</idl> <br />
|-<br />
|<code>$(home)</code><br />
|Single path <br />
|The absolute path to the home directory of the current user. Under Windows this depends on the specific versions: usually the ''<drive>:\Documents and Settings\<username>\Application Data'' under Windows 2000/XP and ''<drive>:\Windows\Profiles\<username>\Application Data'' under Windows NT and Win9x, ME with multi user support. Windows 9x and ME without multi-user support ''<drive>:\Windows\Application Data''. <br />
|-<br />
|<code>$(inst)</code><br><br />
<code>$(instpath)</code><br><br />
<code>$(insturl)</code> <br />
|Single path <br />
|The absolute installation path of {{PRODUCTNAME}}. Normally the share and ''program'' folders are located inside the installation folder. The <code>$(instpath)</code> and <code>$(insturl)</code> variables are aliases to <code>$(inst)</code> - they are included for downward compatibility and should not be used. <br />
|-<br />
|<code>$(prog)</code><br><br />
<code>$(progpath)</code><br><br />
<code>$(progurl)</code> <br />
|Single path <br />
|The absolute path of the program folder of {{PRODUCTNAME}}. Normally the executable and the shared libraries are located in this folder. The <code>$(progpath)</code> and <code>$(progurl)</code> variables are aliases to <code>$(prog)</code> - they are supported for downward compatibility and should not be used. <br />
|-<br />
|<code>$(temp)</code> <br />
|Single path <br />
|The absolute path of the current temporary directory used by {{PRODUCTNAME}}. <br />
|-<br />
|<code>$(user)</code><br><br />
<code>$(userpath)</code><br><br />
<code>$(userurl)</code> <br />
|Single path <br />
|The absolute path to the user installation folder of {{PRODUCTNAME}}. The <code>$(userpath)</code> and <code>$(userurl)</code> variables are aliases to <code>$(user)</code> - they are supported for downward compatibility and should not be used. <br />
|-<br />
|<code>$(work)</code> <br />
|Single path <br />
|The absolute path of the working directory of the user. Under Windows this is the ''My Documents'' folder. Under Unix this is the ''home'' directory of the user. <br />
|-<br />
|<code>$(path)</code> <br />
|List of paths <br />
|The value of the PATH environment variable of the {{PRODUCTNAME}} process. The single paths are separated by a ';' character independent of the system. <br />
|-<br />
|<code>$(lang)</code> <br />
|Part of a path <br />
|The country code used by {{PRODUCTNAME}}, see the table Mapping ISO 639/3166 to <code>$(lang)</code> below for examples. <br />
|-<br />
|<code>$(langid)</code> <br />
|Part of a path <br />
|The language identifier used by {{PRODUCTNAME}}. An identifier is composed of a primary language identifier and a sublanguage identifier such as 0x0009=English (primary language identifier), 0x0409=English US (composed language code). The language identifier is based on the Microsoft language identifiers, for further information please see:<br />
<br />
Language Identifier Constants and Strings<br><br />
https://msdn.microsoft.com/en-us/library/windows/desktop/dd318693%28v=vs.85%29.aspx<br />
<br />
The language identifier returned by <code>$(langid)</code> is a string expressed in decimal notation. Example for English US : 1033 whereas Microsoft documentation uses hexadecimal notation : 0x0409<br />
|-<br />
|<code>$(vlang)</code> <br />
|Part of a path <br />
|The language used by {{PRODUCTNAME}} as an English string, for example, "german" for a German version of {{PRODUCTNAME}}. <br />
|}<br />
<br />
The values of $(lang), $(langid) and $(vlang) are based on the property ooLocale in the configuration branch ''org.openoffice.Setup/L10N'', that is normally located in the share directory. This property follows the ISO 639-1/ISO3166 standards that define identification codes for languages and countries. The ooLocale property is written by the setup application during installation time. The following are examples of table Mapping ISO 639/3166 to $(vlang):<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!colspan="4"|Mapping from ISO639-1/ISO3166 to $(lang) and $(vlang) <br />
|-<br />
|'''ISO 639-1''' <br />
|'''ISO 3166''' <br />
|'''$(lang)''' <br />
|'''$(vlang)''' <br />
|-<br />
|ar <br />
|* <br />
|96 <br />
|arabic <br />
|-<br />
|ca <br />
|AD <br />
|37 <br />
|catalan <br />
|-<br />
|ca <br />
|ES <br />
|37 <br />
|catalan <br />
|-<br />
|cs <br />
|* <br />
|42 <br />
|czech <br />
|-<br />
|cz <br />
|* <br />
|42 <br />
|czech <br />
|-<br />
|da <br />
|DK <br />
|45 <br />
|danish <br />
|-<br />
|de <br />
|* <br />
|49 <br />
|german <br />
|-<br />
|el <br />
|* <br />
|30 <br />
|greek <br />
|-<br />
|en <br />
|* <br />
|1 <br />
|english <br />
|-<br />
|en <br />
|GB <br />
|1 <br />
|english_uk <br />
|-<br />
|es <br />
|* <br />
|34 <br />
|spanish <br />
|-<br />
|fi <br />
|FI <br />
|35 <br />
|finnish <br />
|-<br />
|fr <br />
|* <br />
|33 <br />
|french <br />
|-<br />
|he <br />
|* <br />
|97 <br />
|hebrew <br />
|-<br />
|hu <br />
|HU <br />
|36 <br />
|hungarian <br />
|-<br />
|it <br />
|* <br />
|39 <br />
|italian <br />
|-<br />
|ja <br />
|JP <br />
|81 <br />
|japanese <br />
|-<br />
|ko <br />
|* <br />
|82 <br />
|korean <br />
|-<br />
|nb <br />
|NO <br />
|47 <br />
|norwegian <br />
|-<br />
|nl <br />
|* <br />
|31 <br />
|dutch <br />
|-<br />
|nn <br />
|NO <br />
|47 <br />
|norwegian <br />
|-<br />
|no <br />
|NO <br />
|47 <br />
|norwegian <br />
|-<br />
|pl <br />
|PL <br />
|48 <br />
|polish <br />
|-<br />
|pt <br />
|BR <br />
|55 <br />
|portuguese_brazilian <br />
|-<br />
|pt <br />
|PT <br />
|3 <br />
|portuguese <br />
|-<br />
|ru <br />
|RU <br />
|7 <br />
|russian <br />
|-<br />
|sk <br />
|SK <br />
|43 <br />
|slovak <br />
|-<br />
|sv <br />
|* <br />
|46 <br />
|swedish <br />
|-<br />
|th <br />
|TH <br />
|66 <br />
|thai <br />
|-<br />
|tr <br />
|TR <br />
|90 <br />
|turkish <br />
|-<br />
|zh <br />
|CN <br />
|86 <br />
|chinese_simplified <br />
|-<br />
|zh <br />
|TW <br />
|88 <br />
|chinese_traditional <br />
|}<br />
<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Office Development]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/Basic/Accessing_the_UNO_APIDocumentation/DevGuide/Basic/Accessing the UNO API2015-06-21T10:49:15Z<p>BMarcelly: added : ThisDatabaseDocument</p>
<hr />
<div>{{Documentation/DevGuide/BasicTOC<br />
|Basic2b=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/Basic/Specific UNO Functions<br />
|NextPage=Documentation/DevGuide/Basic/Special Behavior of OpenOffice.org Basic<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/Basic/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:Accessing the UNO API}}<br />
In [[Documentation/DevGuide/ProUNO/Basic/OpenOffice.org Basic|OpenOffice.org Basic]], the interaction between Basic and UNO is described on an elementary level. This section describes the interface between Basic and the UNO API at the level of the {{PRODUCTNAME}} application. <br />
<br />
This is realized by two predefined Basic properties:<br />
<br />
* <code>StarDesktop</code><br />
* <code>ThisComponent</code><br />
<br />
The property <code>StarDesktop</code> gives access to the global {{PRODUCTNAME}} application API while the property <code>ThisComponent</code> accesses the document related API.<br />
<br />
=== StarDesktop ===<br />
<br />
The property <code>StarDesktop</code> is a shortcut for the service <idl>com.sun.star.frame.Desktop</idl>. <br />
<br />
Example:<br />
<br />
<source lang="oobas"><br />
MsgBox StarDesktop.Dbg_SupportedInterfaces<br />
<br />
' is the same as<br />
<br />
Dim oDesktop<br />
oDesktop = CreateUnoService( "com.sun.star.frame.Desktop" )<br />
MsgBox oDesktop.Dbg_SupportedInterfaces<br />
</source><br />
<br />
The displayed message box differs slightly because <code>Dbg_SupportedInterfaces</code> displays "StarDesktop" as an object type of the desktop object in the first case and "com.sun.star.frame.Desktop" in the second. But the two objects are the same.<br />
<br />
=== ThisComponent ===<br />
<br />
The property <code>ThisComponent</code> is used from document Basic, where it represents the document the Basic belongs to. The type of object accessed by <code>ThisComponent</code> depends on the document type. The following example shows the differences.<br />
<br />
Basic module in a {{PRODUCTNAME}} document:<br />
<br />
<source lang="oobas"><br />
Sub Main<br />
MsgBox ThisComponent.Dbg_SupportedInterfaces<br />
End Sub<br />
</source><br />
<br />
The execution of this Basic routine shows different results for a Text, Spreadsheet and Presentation document. Depending on the document type, a different set of interfaces are supported by the object. A portion of the interfaces are common to all these document types representing the general functionality that documents of any type offer. In particular, all {{PRODUCTNAME}} documents support the <idl>com.sun.star.document.OfficeDocument</idl> service, including the interfaces <idl>com.sun.star.frame.XStorable</idl> and <idl>com.sun.star.view.XPrintable</idl>. Another interface is <idl>com.sun.star.frame.XModel</idl>.<br />
<br />
The following list shows the interfaces supported by all document types:<br />
<br />
* <idl>com.sun.star.beans.XPropertySet</idl><br />
* <idl>com.sun.star.container.XChild</idl><br />
* <idl>com.sun.star.document.XDocumentInfoSupplier</idl><br />
* <idl>com.sun.star.document.XEventBroadcaster</idl><br />
* <idl>com.sun.star.document.XViewDataSupplier</idl><br />
* <idl>com.sun.star.document.XEventsSupplier</idl><br />
* <idl>com.sun.star.document.XLinkTargetSupplier</idl><br />
* <idl>com.sun.star.frame.XModel</idl><br />
* <idl>com.sun.star.frame.XStorable</idl><br />
* <idl>com.sun.star.lang.XServiceInfo</idl><br />
* <idl>com.sun.star.lang.XMultiServiceFactory</idl><br />
* <idl>com.sun.star.lang.XEventListener</idl><br />
* <idl>com.sun.star.style.XStyleFamiliesSupplier</idl><br />
* <idl>com.sun.star.util.XModifiable</idl><br />
* <idl>com.sun.star.view.XPrintable</idl><br />
<br />
For more information about the functionality of these interfaces, see [[Documentation/DevGuide/OfficeDev/Frame-Controller-Model Paradigm in OpenOffice.org|Frame-Controller-Model Paradigm in OpenOffice.org]]. This section also goes into detail about the general document API.<br />
<br />
In addition to the common services or interfaces, each document type supports specific services or interfaces. The following list outlines the supported services and important interfaces:<br />
<br />
A Text document supports:<br />
<br />
* The service <idl>com.sun.star.text.TextDocument</idl> supports the interface <idl>com.sun.star.text.XTextDocument</idl>. <br />
* Several interfaces, especially from the <idlmodule>com.sun.star.text</idlmodule> package.<br />
<br />
A Spreadsheet document supports:<br />
<br />
* The service <idl>com.sun.star.sheet.SpreadsheetDocument</idl>,<br />
* The service <idl>com.sun.star.sheet.SpreadsheetDocumentSettings</idl>.<br />
* Several other interfaces, especially from the <idlmodule>com.sun.star.sheet</idlmodule> package.<br />
<br />
Presentation and Drawing documents support:<br />
<br />
* The service <idl>com.sun.star.drawing.DrawingDocument</idl>.<br />
* Several other interfaces, especially from the <idlmodule>com.sun.star.drawing</idlmodule> package.<br />
<br />
The usage of these services and interfaces is explained in the document type specific chapters [[Documentation/DevGuide/Text/Text Documents|Text Documents]], [[Documentation/DevGuide/Spreadsheets/Spreadsheet Documents|Spreadsheet Documents]] and [[Documentation/DevGuide/Drawings/Drawing Documents and Presentation Documents|Drawing Documents and Presentation Documents]].<br />
<br />
As previously mentioned, <code>ThisComponent</code> is used from document Basic, but it is also possible to use it from application Basic. In an application wide Basic module, <code>ThisComponent</code> is identical to the current component that can also be accessed through <code>StarDesktop.CurrentComponent</code>. The only difference between the two is that if the BasicIDE is active, <code>StarDesktop.CurrentComponent</code> refers to the BasicIDE itself while <code>ThisComponent</code> always refers to the component that was active before the BasicIDE became the top window.<br />
<br />
=== ThisDatabaseDocument===<br />
<br />
The property <code>ThisDatabaseDocument</code>, introduced since {{OOo}} 3.1, is only used from a Basic code which is embedded in a Base document. It refers to the Base document model.<br />
<br />
Typically, when a macro is started by an event from a Form of the Base document, <code>ThisDatabaseDocument</code> represents the Base document, whereas <code>ThisComponent</code> refers to the Form document.<br />
<br />
<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Basic and Dialogs]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Basic/Instantiating_UNO_ServicesDocumentation/DevGuide/ProUNO/Basic/Instantiating UNO Services2015-06-21T10:31:46Z<p>BMarcelly: /* Build in properties */ added : ThisDatabaseDocument</p>
<hr />
<div>{{Documentation/DevGuide/ProUNOTOC<br />
|ProUNO2c=block<br />
|Basic=block<br />
|UNOObjects=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/ProUNO/Basic/Handling UNO Objects<br />
|NextPage=Documentation/DevGuide/ProUNO/Basic/Getting Information about UNO Objects<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/ProUNO/Basic/{{SUBPAGENAME}}}}<br />
{{DISPLAYTITLE:Instantiating UNO Services}}<br />
<!--<idltopic>com.sun.star.lang.ServiceManager</idltopic>--><br />
In Basic, instantiate services using the Basic Runtime Library (RTL) function <code>createUnoService()</code>. This function expects a fully qualified service name and returns an object supporting this service, if it is available:<br />
<source lang="oobas"><br />
oSimpleFileAccess = CreateUnoService( "com.sun.star.ucb.SimpleFileAccess" )<br />
</source><br />
This call instantiates the <idl>com.sun.star.ucb.SimpleFileAccess</idl> service. To ensure that the function was successful, the returned object can be checked with the <code>IsNull</code> function:<br />
<source lang="oobas"><br />
oSimpleFileAccess = CreateUnoService( "com.sun.star.ucb.SimpleFileAccess" )<br />
bError = IsNull( oSimpleFileAccess )' bError is set to False<br />
<br />
oNoService = CreateUnoService( "com.sun.star.nowhere.ThisServiceDoesNotExist" )<br />
bError = IsNull( oNoService )' bError is set to True<br />
</source><br />
Instead of using <code>CreateUnoService()</code> to instantiate a service, it is also possible to get the global UNO <idl>com.sun.star.lang.ServiceManager</idl> of the {{PRODUCTNAME}} process by calling <code>GetProcessServiceManager()</code>. Once obtained, use <code>createInstance()</code> directly:<br />
<source lang="oobas"><br />
oServiceMgr = GetProcessServiceManager()<br />
oSimpleFileAccess = oServiceMgr.createInstance( "com.sun.star.ucb.SimpleFileAccess" )<br />
<br />
' is the same as<br />
<br />
oSimpleFileAccess = CreateUnoService( "com.sun.star.ucb.SimpleFileAccess" )<br />
</source><br />
The advantage of <code>GetProcessServiceManager()</code> is that additional information and pass in arguments is received when services are instantiated using the service manager. For instance, to initialize a service with arguments, the <code>createInstanceWithArguments()</code> method of <idl>com.sun.star.lang.XMultiServiceFactory</idl> has to be used at the service manager, because there is no appropriate Basic RTL function to do that. Example:<br />
<source lang="oobas"><br />
Dim args(1)<br />
args(0) = "Important information"<br />
args(1) = "Even more important information"<br />
oService = oServiceMgr.createInstanceWithArguments _<br />
( "com.sun.star.nowhere.ServiceThatNeedsInitialization", args() )<br />
</source><br />
The object returned by <code>GetProcessServiceManager()</code> is a normal Basic UNO object supporting <idl>com.sun.star.lang.ServiceManager</idl>. Its properties and methods are accessed as described above.<br />
<br />
=== Using new-style service constructors ===<br />
<br />
Beginning with OpenOffice.org 3.2 OpenOffice.org Basic supports UNO new-style service constructors.<br />
For more details see section [[Documentation/DevGuide/ProUNO/Services|Services]].<br />
For the sample service used above constructors could be defined like this:<br />
<br />
<source lang="idl"><br />
module com { module sun { module star { module nowhere {<br />
<br />
service ServiceThatNeedsInitialization: XFoo { <br />
create1([in] long arg);<br />
create2([in] string important1, [in] string important2);<br />
};<br />
<br />
}; }; }; };<br />
</source><br />
<br />
UNO services are mapped to OpenOffice.org Basic objects. They have to be addressed by<br />
using the complete UNO namespace path. The constructors can be accessed as methods of<br />
these service objects:<br />
<br />
<source lang="oobas"><br />
Dim oServiceObj<br />
oServiceObj = com.sun.star.nowhere.ServiceThatNeedsInitialization<br />
Dim oInstance As Object<br />
oInstance = oServiceObj.create2( "Useless", "Invalid" )<br />
</source><br />
<br />
Of course the service object doesn't need to be stored in a variable before,<br />
the instantiation can also be done in one single statement:<br />
<br />
<source lang="oobas"><br />
Dim oInstance As Object<br />
oInstance = com.sun.star.nowhere.ServiceThatNeedsInitialization.create1( 42 )<br />
</source><br />
<br />
Internally the UNO default context is used to create the and passed to the service.<br />
It's also possible to use an own context instead by adding it as first argument:<br />
<br />
<source lang="oobas"><br />
Dim oMyContext As Object<br />
oMyContext = GetContextFromSomewhere()<br />
oInstance = oServiceObj.create1( oMyContext, 42 )<br />
</source><br />
<br />
If a new-style service only has an implicit constructor it's mapped to a method<br />
"create" without parameters in OpenOffice.org Basic.<br />
<br />
=== Build in properties ===<br />
<br />
The Basic RTL provides special properties as API entry points. They are described in more detail in [[Documentation/DevGuide/Basic/Features of OpenOffice.org Basic|Features of OpenOffice.org Basic]]:<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!{{PRODUCTNAME}} Basic RTL Property !! Description <br />
|-<br />
|ThisComponent <br />
|Only exists in Basic code which is embedded in a Writer, Calc, Draw or Impress document. It contains the document model the Basic code is embedded in. <br />
|-<br />
|ThisDatabaseDocument <br />
|Only exists in Basic code which is embedded in a Base document. It contains the document model the Basic code is embedded in, i.e. the Base document. Useful when a macro is started by an event from a Form document contained in the Base document.<br />
|-<br />
|StarDesktop <br />
|The <idl>com.sun.star.frame.Desktop</idl> singleton of the office application. It loads document components and handles the document windows. For instance, the document in the top window can be retrieved using <code>oDoc = StarDesktop.CurrentComponent</code>. <br />
|}<br />
<br />
{{Documentation/Tip|<tt>ThisComponent</tt> is recommended over <tt>StarDesktop.CurrentComponent</tt>, for convenience in developing and debugging from the IDE. If the BasicIDE is active, StarDesktop.CurrentComponent refers to the BasicIDE itself while ThisComponent always refers to the component that was active before the BasicIDE became the top window.}}<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Professional UNO]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Access_to_Formulas,_Values_and_ErrorsDocumentation/DevGuide/Spreadsheets/Access to Formulas, Values and Errors2015-05-29T08:58:48Z<p>BMarcelly: Replaced html table syntax by wiki table syntax</p>
<hr />
<div>{{Documentation/DevGuide/SpreadsheetsTOC<br />
|SpreadsheetDocs2c=block<br />
|SpreadsheetDocsStruct=block<br />
|SpreadsheetDocsCells=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/Spreadsheets/Properties of SheetCell<br />
|NextPage=Documentation/DevGuide/Spreadsheets/Access to Text Content<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/Spreadsheets/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:Access to Formulas, Values and Errors}}<br />
The cell interface <idl>com.sun.star.table.XCell</idl> provides methods to access the value, formula, content type, and error code of a single cell:<br />
<br />
void setValue( [in] double nValue)<br />
double getValue() <br />
void setFormula( [in] string aFormula)<br />
string getFormula() <br />
com::sun::star::table::CellContentType getType()<br />
long getError()<br />
<br />
The value of a cell is a floating-point number. To set a formula to a cell, the whole formula string has to be passed including the leading equality sign. The function names must be in English.<br />
<br />
{{Documentation/Tip|It is possible to set simple strings or even values with special number formats. In this case, the formula string consists only of a string constant or of the number as it would be entered in the table (for instance date, time, or currency values).}}<br />
<br />
The method <code>getType()</code> returns a value of the enumeration <idl>com.sun.star.table.CellContentType</idl> indicating the type of the cell content.<br />
<br />
The following code fragment shows how to access and modify the content, and formatting of single cells. The <code>xRange</code> is an existing cell range (a <idl>com.sun.star.table.XCellRange</idl> interface, described in [[Documentation/DevGuide/Spreadsheets/Cell Ranges|Cell Ranges]]). The method <code>getCellByPosition()</code> is provided by this interface. <br />
<!--[SOURCE:Spreadsheet/GeneralTableSample.java]--><br />
<br />
com.sun.star.beans.XPropertySet xPropSet = null;<br />
com.sun.star.table.XCell xCell = null;<br />
<br />
// *** Access and modify a VALUE CELL ***<br />
xCell = xRange.getCellByPosition(0, 0);<br />
// Set cell value.<br />
xCell.setValue(1234);<br />
<br />
// Get cell value.<br />
double nDblValue = xCell.getValue() * 2;<br />
xRange.getCellByPosition(0, 1).setValue(nDblValue);<br />
<br />
// *** Create a FORMULA CELL and query error type ***<br />
xCell = xRange.getCellByPosition(0, 2);<br />
// Set formula string.<br />
xCell.setFormula("=1/0");<br />
<br />
// Get error type.<br />
boolean bValid = (xCell.getError() == 0);<br />
// Get formula string.<br />
String aText = "The formula " + xCell.getFormula() + " is ";<br />
aText += bValid ? "valid." : "erroneous.";<br />
<br />
// *** Insert a TEXT CELL using the XText interface ***<br />
xCell = xRange.getCellByPosition( 0, 3 );<br />
com.sun.star.text.XText xCellText = (com.sun.star.text.XText)<br />
UnoRuntime.queryInterface( com.sun.star.text.XText.class, xCell );<br />
com.sun.star.text.XTextCursor xTextCursor = xCellText.createTextCursor();<br />
xCellText.insertString( xTextCursor, aText, false );<br />
<br />
// *** Change cell properties ***<br />
int nValue = bValid ? 0x00FF00 : 0xFF4040;<br />
xPropSet = (com.sun.star.beans.XPropertySet) UnoRuntime.queryInterface(<br />
com.sun.star.beans.XPropertySet.class, xCell);<br />
xPropSet.setPropertyValue("CellBackColor", new Integer(nValue));<br />
<br />
Note that since the only data attributes a cell has for representing numbers is value and formula, other types available in OpenOffice.org Calc have to be translated before you can use them. See <idl>com.sun.star.util.NumberFormat</idl> for the standard formats.<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
<br />
|-bgcolor=#EDEDED<br />
<br />
!NumberFormat<br />
<br />
!Mapping to double<br />
<br />
|-<br />
<br />
|DATE<br />
<br />
|1 = one day; day 1 is 1899-12-31<br />
<br />
|-<br />
<br />
|TIME<br />
<br />
|Fraction of a 24h day (1 = 24 hours)<br />
<br />
|-<br />
<br />
|PERCENT<br />
<br />
|1 = 100%<br />
<br />
|-<br />
<br />
|CURRENCY<br />
<br />
|1 = $1, £1 etc<br />
<br />
|-<br />
<br />
|LOGICAL<br />
<br />
|FALSE if zero, TRUE otherwise<br />
<br />
|}<br />
<br />
How this value will be shown to the user depends on the cell's [[Documentation/DevGuide/OfficeDev/Number_Formats|Number Format]].<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Spreadsheet Documents]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/View_PanesDocumentation/DevGuide/Spreadsheets/View Panes2015-05-29T08:44:17Z<p>BMarcelly: Replaced wikitable class by the usual table syntax</p>
<hr />
<div>{{Documentation/DevGuide/SpreadsheetsTOC<br />
|SpreadsheetDocs2e=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/Spreadsheets/Spreadsheet Document Controller<br />
|NextPage=Documentation/DevGuide/Spreadsheets/View Settings<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/Spreadsheets/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:View Panes}}<br />
<!--<idltopic>com.sun.star.sheet.SpreadsheetViewPane</idltopic>--><br />
The <idl>com.sun.star.sheet.SpreadsheetViewPane</idl> service represents a pane in a view that shows a rectangular area of the document. The exposed area of a view pane always starts at a cell boundary. The <idl>com.sun.star.sheet.XViewPane</idl> interface's <code>getFirstVisibleColumn()</code>, <code>getFirstVisibleRow()</code>, <code>setFirstVisibleColumn()</code> and <code>setFirstVisibleRow()</code> methods query and set the start of the exposed area. The <code>getVisibleRange()</code> method returns a <idl>com.sun.star.table.CellRangeAddress</idl> struct describing which cells are shown in the pane. Columns or rows that are only partly visible at the right or lower edge of the view are not included.<br />
<br />
The <idl>com.sun.star.sheet.XCellRangeReferrer</idl> interface gives direct access to the same cell range of exposed cells that are addressed by the <code>getVisibleRange()</code> return value.<br />
<br />
The <idl>com.sun.star.view.XControlAccess</idl> interface's <code>getControl()</code> method gives access to a control model's control for the view pane. Refer to the chapter [[Documentation/DevGuide/Forms/Models and Views|Models and Views]] for additional information.<br />
<br />
The example below retrieves the cell range that is shown in the second pane. It is the lower left one after freezing both columns and rows, and assigns a cell background: <br />
<!--[SOURCE:Spreadsheet/ViewSample.java]--><br />
<br />
// get the cell range shown in the second pane and assign a cell background to them<br />
com.sun.star.container.XIndexAccess xIndex = (com.sun.star.container.XIndexAccess)<br />
UnoRuntime.queryInterface(com.sun.star.container.XIndexAccess.class, xController);<br />
Object aPane = xIndex.getByIndex(1);<br />
com.sun.star.sheet.XCellRangeReferrer xRefer = (com.sun.star.sheet.XCellRangeReferrer)<br />
UnoRuntime.queryInterface(com.sun.star.sheet.XCellRangeReferrer.class, aPane);<br />
com.sun.star.table.XCellRange xRange = xRefer.getReferredCells();<br />
com.sun.star.beans.XPropertySet xRangeProp = (com.sun.star.beans.XPropertySet)<br />
UnoRuntime.queryInterface(com.sun.star.beans.XPropertySet.class, xRange);<br />
xRangeProp.setPropertyValue("IsCellBackgroundTransparent", new Boolean(false));<br />
xRangeProp.setPropertyValue("CellBackColor", new Integer(0xFFFFCC));<br />
<br />
The index container provides the available panes in a specific order, depending on how the view has been split.<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
<br />
|-bgcolor=#EDEDED<br />
<br />
!Index<br />
<br />
!No split<br />
<br />
!Vertical split<br />
<br />
!Horizontal split (*)<br />
<br />
!Vertical and horizontal split (*)<br />
<br />
|-<br />
<br />
|0<br />
<br />
|Entire window<br />
<br />
|Top pane<br />
<br />
|Left pane<br />
<br />
|Top left pane<br />
<br />
|-<br />
<br />
|1<br />
<br />
| --<br />
<br />
|Bottom pane<br />
<br />
|Right pane<br />
<br />
|Bottom left pane<br />
<br />
|-<br />
<br />
|2<br />
<br />
| --<br />
<br />
| --<br />
<br />
| --<br />
<br />
|Top right pane<br />
<br />
|-<br />
<br />
|3<br />
<br />
| --<br />
<br />
| --<br />
<br />
| --<br />
<br />
|Bottom right pane<br />
<br />
|}<br />
(*) If the sheet is in right-to-left layout mode, the panes are swapped too (e.g., pane 0 would be the right pane or the top right pane).<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Spreadsheet Documents]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Example:_Editing_Spreadsheet_CellsDocumentation/DevGuide/Spreadsheets/Example: Editing Spreadsheet Cells2015-05-29T07:35:02Z<p>BMarcelly: old fashioned table syntax caused copy problems</p>
<hr />
<div>{{Documentation/DevGuide/SpreadsheetsTOC<br />
|SpreadsheetDocs2a=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/Spreadsheets/Example: Adding a New Spreadsheet<br />
|NextPage=Documentation/DevGuide/Spreadsheets/Handling Spreadsheet Documents Files<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/Spreadsheets/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:Example: Editing Spreadsheet Cells}}<br />
The method <code>insertSpreadsheet()</code> returns a <idl>com.sun.star.sheet.XSpreadsheet</idl> interface. This interface is passed to the method below, which shows how to access and modify the content and formatting of single cells. The interface <idl>com.sun.star.sheet.XSpreadsheet</idl> returned by <code>insertSpreadsheet()</code> is derived from <idl>com.sun.star.table.XCellRange</idl>. By working with it, cells can be accessed immediately using <code>getCellByPosition()</code>: <br />
<!--[SOURCE:Spreadsheet/GeneralTableSample.java]--><br />
<source lang="Java"><br />
void cellWork(XSpreadsheet xRange) {<br />
<br />
com.sun.star.beans.XPropertySet xPropSet = null;<br />
com.sun.star.table.XCell xCell = null;<br />
<br />
// Access and modify a VALUE CELL<br />
xCell = xRange.getCellByPosition(0, 0);<br />
// Set cell value.<br />
xCell.setValue(1234);<br />
<br />
// Get cell value.<br />
double nDblValue = xCell.getValue() * 2;<br />
xRange.getCellByPosition(0, 1).setValue(nDblValue);<br />
<br />
// Create a FORMULA CELL<br />
xCell = xRange.getCellByPosition(0, 2);<br />
// Set formula string.<br />
xCell.setFormula("=1/0");<br />
<br />
// Get error type.<br />
boolean bValid = (xCell.getError() == 0);<br />
// Get formula string.<br />
String aText = "The formula " + xCell.getFormula() + " is ";<br />
aText += bValid ? "valid." : "erroneous.";<br />
<br />
// Insert a TEXT CELL using the XText interface<br />
xCell = xRange.getCellByPosition(0, 3);<br />
com.sun.star.text.XText xCellText = (com.sun.star.text.XText)<br />
UnoRuntime.queryInterface(com.sun.star.text.XText.class, xCell);<br />
com.sun.star.text.XTextCursor xTextCursor = xCellText.createTextCursor();<br />
xCellText.insertString(xTextCursor, aText, false);<br />
<br />
//--------------------<br />
// get the cell properties<br />
//--------------------<br />
<br />
xPropSet = (com.sun.star.beans.XPropertySet)<br />
UnoRuntime.queryInterface(com.sun.star.beans.XPropertySet.class,<br />
xCell);<br />
<br />
//--------------------<br />
// set the cell's background color<br />
//--------------------<br />
Integer bg_color = new Integer(0x008000);<br />
xPropSet.setPropertyValue("CellBackColor", bg_color);<br />
<br />
//--------------------<br />
// set the cell's foreground (text) color<br />
//--------------------<br />
Integer fg_color = new Integer(0x800000);<br />
xPropSet.setPropertyValue("CharColor", fg_color);<br />
<br />
//--------------------<br />
// set horizontal alignment to 'centered'<br />
//--------------------<br />
xPropSet.setPropertyValue("HoriJustify", com.sun.star.table.CellHoriJustify.CENTER);<br />
<br />
//--------------------<br />
// set vertical alignment to 'top'<br />
//--------------------<br />
xPropSet.setPropertyValue("VertJustify", com.sun.star.table.CellVertJustify.TOP);<br />
<br />
//--------------------<br />
// use bold font<br />
//--------------------<br />
xPropSet.setPropertyValue("CharWeight", com.sun.star.awt.FontWeight.BOLD);<br />
xPropSet.setPropertyValue("CharWeightAsian", com.sun.star.awt.FontWeight.BOLD);<br />
xPropSet.setPropertyValue("CharWeightComplex", com.sun.star.awt.FontWeight.BOLD);<br />
<br />
//--------------------<br />
// add a cell border <br />
//--------------------<br />
<br />
// one point seems to be 1/72 inch<br />
double lineWidthInPoints = 2.5;<br />
<br />
// convert to units of 1/100 mm<br />
short integerLineWidth = (short) Math.round(2540 / 72.0 * lineWidthInPoints);<br />
<br />
final String[] borderNames = {<br />
"LeftBorder", "RightBorder", "TopBorder", "BottomBorder"<br />
};<br />
<br />
for (int i = 0; i < borderNames.length; ++i)<br />
{<br />
com.sun.star.table.BorderLine borderLine = new com.sun.star.table.BorderLine();<br />
borderLine.OuterLineWidth = integerLineWidth;<br />
xPropSet.setPropertyValue(borderNames[i], borderLine);<br />
}<br />
<br />
}</source><br />
<br />
See also [[Documentation/DevGuide/FirstSteps/Example:_Working_with_a_Spreadsheet_Document|Working with a Spreadsheet Document (Example)]].<br />
<br />
Running [[Documentation/DevGuide/ProUNO/Properties#Example:_find_out_which_properties_an_object_provides|an example showing how to find out which properties an object provides]] (with an object of type <idl>com.sun.star.table.XCell</idl> instead of <code>mxDocCursor</code>), one gets for example the following properties (OpenOffice.org 2.4):<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
<br />
|-bgcolor=#EDEDED<br />
<br />
! Attribute Name<br />
! Type<br />
! Remark<br />
|-<br />
| AbsoluteName<br />
| string<br />
| READONLY<br />
|-<br />
| AsianVerticalMode <br />
| boolean<br />
|<br />
|-<br />
| BottomBorder <br />
| <idl>com.sun.star.table.BorderLine</idl><br />
|<br />
|-<br />
| CellBackColor<br />
| long<br />
|<br />
|-<br />
| CellProtection<br />
| <idl>com.sun.star.util.CellProtection</idl><br />
|<br />
|-<br />
| CellStyle<br />
| string<br />
|<br />
|-<br />
| CharColor<br />
| long<br />
|<br />
|-<br />
| CharContoured<br />
| boolean<br />
|<br />
|-<br />
| CharCrossedOut<br />
| boolean<br />
|<br />
|-<br />
| CharEmphasis<br />
| short<br />
|<br />
|-<br />
| CharFont<br />
| short<br />
|<br />
|-<br />
| CharFontCharSet<br />
| short<br />
|<br />
|-<br />
| CharFontCharSetAsian<br />
| short<br />
|<br />
|-<br />
| CharFontCharSetComplex<br />
| short<br />
|<br />
|-<br />
| CharFontFamily<br />
| short<br />
|<br />
|-<br />
| CharFontFamilyAsian<br />
| short<br />
|<br />
|-<br />
| CharFontFamilyComplex<br />
| short<br />
|<br />
|-<br />
| CharFontName<br />
| string<br />
|<br />
|-<br />
| CharFontNameAsian<br />
| string<br />
|<br />
|-<br />
| CharFontNameComplex<br />
| string<br />
|<br />
|-<br />
| CharFontPitch<br />
| short<br />
|<br />
|-<br />
| CharFontPitchAsian<br />
| short<br />
|<br />
|-<br />
| CharFontPitchComplex<br />
| short<br />
|<br />
|-<br />
| CharFontStyleName<br />
| string<br />
|<br />
|-<br />
| CharFontStyleNameAsian<br />
| string<br />
|<br />
|-<br />
| CharFontStyleNameComplex<br />
| string<br />
|<br />
|-<br />
| CharHeight<br />
| float<br />
|<br />
|-<br />
| CharHeightAsian<br />
| float<br />
|<br />
|-<br />
| CharHeightComplex<br />
| float<br />
|<br />
|-<br />
| CharLocale<br />
| <idl>com.sun.star.lang.Locale</idl><br />
|<br />
|-<br />
| CharLocaleAsian<br />
| <idl>com.sun.star.lang.Locale</idl><br />
|<br />
|-<br />
| CharLocaleComplex<br />
| <idl>com.sun.star.lang.Locale</idl><br />
|<br />
|-<br />
| CharPosture<br />
| <idl>com.sun.star.awt.FontSlant</idl><br />
|<br />
|-<br />
| CharPostureAsian<br />
| <idl>com.sun.star.awt.FontSlant</idl><br />
|<br />
|-<br />
| CharPostureComplex<br />
| <idl>com.sun.star.awt.FontSlant</idl><br />
|<br />
|-<br />
| CharRelief<br />
| short<br />
|<br />
|-<br />
| CharShadowed<br />
| boolean<br />
|<br />
|-<br />
| CharStrikeout<br />
| short<br />
|<br />
|-<br />
| CharUnderline<br />
| short<br />
|<br />
|-<br />
| CharUnderlineColor<br />
| long<br />
|<br />
|-<br />
| CharUnderlineHasColor<br />
| boolean<br />
|<br />
|-<br />
| CharWeight<br />
| float<br />
| see also <idl>com.sun.star.awt.FontWeight</idl><br />
|-<br />
| CharWeightAsian<br />
| float<br />
| see also <idl>com.sun.star.awt.FontWeight</idl><br />
|-<br />
| CharWeightComplex<br />
| float<br />
| see also <idl>com.sun.star.awt.FontWeight</idl><br />
|-<br />
| CharWordMode<br />
| boolean<br />
|<br />
|-<br />
| ChartColumnAsLabel<br />
| boolean<br />
|<br />
|-<br />
| ChartRowAsLabel<br />
| boolean<br />
|<br />
|-<br />
| ConditionalFormat<br />
| <idl>com.sun.star.sheet.XSheetConditionalEntries</idl><br />
|<br />
|-<br />
| ConditionalFormatLocal<br />
| <idl>com.sun.star.sheet.XSheetConditionalEntries</idl><br />
|<br />
|-<br />
| ConditionalFormatXML<br />
| <idl>com.sun.star.sheet.XSheetConditionalEntries</idl><br />
| READONLY<br />
|-<br />
| DiagonalBLTR<br />
| <idl>com.sun.star.table.BorderLine</idl><br />
|<br />
|-<br />
| DiagonalTLBR<br />
| <idl>com.sun.star.table.BorderLine</idl><br />
|<br />
|-<br />
| FormulaLocal<br />
| string<br />
|<br />
|-<br />
| FormulaResultType<br />
| <idl>com.sun.star.table.CellContentType</idl><br />
| READONLY<br />
|-<br />
| HoriJustify<br />
| <idl>com.sun.star.table.CellHoriJustify</idl><br />
|<br />
|-<br />
| IsCellBackgroundTransparent<br />
| boolean<br />
|<br />
|-<br />
| IsTextWrapped<br />
| boolean<br />
|<br />
|-<br />
| LeftBorder<br />
| <idl>com.sun.star.table.BorderLine</idl><br />
|<br />
|-<br />
| NumberFormat<br />
| long<br />
|<br />
|-<br />
| NumberingRules<br />
| <idl>com.sun.star.container.XIndexReplace</idl><br />
|<br />
|-<br />
| Orientation<br />
| <idl>com.sun.star.table.CellOrientation</idl><br />
|<br />
|-<br />
| ParaAdjust<br />
| short<br />
|<br />
|-<br />
| ParaBottomMargin<br />
| long<br />
|<br />
|-<br />
| ParaIndent<br />
| short<br />
|<br />
|-<br />
| ParaIsCharacterDistance<br />
| boolean<br />
|<br />
|-<br />
| ParaIsForbiddenRules<br />
| boolean<br />
|<br />
|-<br />
| ParaIsHangingPunctuation<br />
| boolean<br />
|<br />
|-<br />
| ParaIsHyphenation<br />
| boolean<br />
|<br />
|-<br />
| ParaLastLineAdjust<br />
| short<br />
|<br />
|-<br />
| ParaLeftMargin<br />
| long<br />
|<br />
|-<br />
| ParaRightMargin<br />
| long<br />
|<br />
|-<br />
| ParaTopMargin<br />
| long<br />
|<br />
|-<br />
| Position<br />
| <idl>com.sun.star.awt.Point</idl><br />
| READONLY<br />
|-<br />
| RightBorder<br />
| <idl>com.sun.star.table.BorderLine</idl><br />
|<br />
|-<br />
| RotateAngle<br />
| long<br />
|<br />
|-<br />
| RotateReference<br />
| <idl>com.sun.star.table.CellVertJustify</idl><br />
|<br />
|-<br />
| ShadowFormat<br />
| <idl>com.sun.star.table.ShadowFormat</idl><br />
|<br />
|-<br />
| ShrinkToFit<br />
| boolean<br />
|<br />
|-<br />
| Size<br />
| <idl>com.sun.star.awt.Size</idl><br />
| READONLY<br />
|-<br />
| TableBorder<br />
| <idl>com.sun.star.table.TableBorder</idl><br />
|<br />
|-<br />
| TopBorder<br />
| <idl>com.sun.star.table.BorderLine</idl><br />
|<br />
|-<br />
| UserDefinedAttributes<br />
| <idl>com.sun.star.container.XNameContainer</idl><br />
|<br />
|-<br />
| Validation<br />
| <idl>com.sun.star.beans.XPropertySet</idl><br />
|<br />
|-<br />
| ValidationLocal<br />
| <idl>com.sun.star.beans.XPropertySet</idl><br />
|<br />
|-<br />
| ValidationXML<br />
| <idl>com.sun.star.beans.XPropertySet</idl><br />
| READONLY<br />
|-<br />
| VertJustify<br />
| <idl>com.sun.star.table.CellVertJustify</idl><br />
|<br />
|-<br />
| WritingMode<br />
| short<br />
|<br />
|}<br />
<br />
<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Spreadsheet Documents]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/Text/Line_Numbering_and_Outline_NumberingDocumentation/DevGuide/Text/Line Numbering and Outline Numbering2015-05-25T14:40:04Z<p>BMarcelly: Documentation of GraphicBitmap and GraphicSize</p>
<hr />
<div>{{Documentation/DevGuide/TextTOC<br />
|Text2c=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/Text/Settings<br />
|NextPage=Documentation/DevGuide/Text/Text Sections<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/Text/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:Line Numbering and Outline Numbering}}<br />
{{PRODUCTNAME}} provides automatic numbering for texts. For instance, paragraphs can be numbered or listed with bullets in a hierarchical manner, chapter headings can be numbered and lines can be counted and numbered. <br />
<br />
=== Paragraph and Outline Numbering ===<br />
<br />
<idl>com.sun.star.text.NumberingRules</idl>The key for paragraph numbering is the paragraph property <code>NumberingRules</code>. This property is provided by paragraphs and numbering styles and is a member of <idl>com.sun.star.style.ParagraphProperties</idl>. <br />
<br />
A similar object controls outline numbering and is returned from the method:<br />
<br />
com::sun::star::container::XIndexReplace getChapterNumberingRules()<br />
<br />
at the <idl>com.sun.star.text.XChapterNumberingSupplier</idl> interface that is implemented at the document model. <br />
<br />
These objects provide an interface <idl>com.sun.star.container.XIndexReplace</idl>. Each element of the container represents a numbering level. The writer document provides ten numbering levels. The highest level is zero. Each level of the container consists of a sequence of <idl>com.sun.star.beans.PropertyValue</idl>.<br />
<br />
The two related objects differ in some of properties they provide. <br />
<br />
Both of them provide the following properties:<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!colspan="2"|Common Properties for Paragraph and Outline Numbering in <idl>com.sun.star.text.NumberingLevel</idl> <br />
|-<br />
|<idlm>com.sun.star.text.NumberingLevel:Adjust</idlm> <br />
|<code>short</code> - Adjustment of the numbering symbol defined in <idl>com.sun.star.text.HoriOrientation</idl>. <br />
|-<br />
|<idlm>com.sun.star.text.NumberingLevel:ParentNumbering</idlm> <br />
|<code>short</code> - Determines if higher numbering levels are included in the numbering, for example, 2.3.1.2. <br />
|-<br />
|<idlm>com.sun.star.text.NumberingLevel:Prefix</idlm><br><br />
<idlm>com.sun.star.text.NumberingLevel:Suffix</idlm> <br />
|<code>string</code> - Contains strings that surround the numbering symbol, for example, brackets. <br />
|-<br />
|<idlm>com.sun.star.text.NumberingLevel:CharStyleName</idlm> <br />
|<code>string</code> - Name of the character style that is applied to the number symbol. <br />
|-<br />
|<idlm>com.sun.star.text.NumberingLevel:StartWith</idlm> <br />
|<code>short</code> - Determines the value the numbering starts with. The default is one. <br />
|-<br />
|<idlm>com.sun.star.text.NumberingLevel:FirstLineOffset</idlm><br><br />
<idlm>com.sun.star.text.NumberingLevel:LeftMargin</idlm> <br />
|<code>long</code> - Influences the left indent and left margin of the numbering. <br />
|-<br />
|<idlm>com.sun.star.text.NumberingLevel:SymbolTextDistance</idlm> <br />
|<code>[optional] long</code> - Distance between the numbering symbol and the text of the paragraph. <br />
|-<br />
|<idlm>com.sun.star.text.NumberingLevel:NumberingType</idlm> <br />
|<code>short</code> - Determines the type of the numbering defined in <idl>com.sun.star.style.NumberingType</idl>. <br />
|}<br />
<br />
<br />
Only paragraphs have the following properties in their <code>NumberingRules</code> property:<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Paragraph NumberingRules Properties in <idl>com.sun.star.text.NumberingLevel</idl> <br />
!Description <br />
|-<br />
|<idlm>com.sun.star.text.NumberingLevel:BulletChar</idlm> <br />
|<code>string</code> - Determines the bullet character if the numbering type is set to <code>NumberingType::CHAR_SPECIAL</code>. <br />
|-<br />
|<idlm>com.sun.star.text.NumberingLevel:BulletFontName</idlm> <br />
|<code>string</code> - Determines the bullet font if the numbering type is set to <code>NumberingType::CHAR_SPECIAL</code>. <br />
|-<br />
|<idlm>com.sun.star.text.NumberingLevel:GraphicURL</idlm> <br />
|<code>string</code> - Determines the type, size and orientation of a graphic when the numbering type is set to <code>NumberingType::BITMAP</code>. <br />
|-<br />
|<idlm>com.sun.star.text.NumberingLevel:GraphicBitmap</idlm> <br />
|<idl>com.sun.star.awt.XBitmap</idl> - the bitmap containing the bullet.<br />
|-<br />
|<idlm>com.sun.star.text.NumberingLevel:GraphicSize</idlm> <br />
|<idl>com.sun.star.awt.Size</idl> - size of the graphic that is used as bullet.<br />
|-<br />
|<idlm>com.sun.star.text.NumberingLevel:VertOrient</idlm> <br />
|<code>short</code> - Vertical orientation of a graphic according to <idl>com.sun.star.text.VertOrientation</idl> <br />
|}<br />
<br />
<br />
Only the chapter numbering rules provide the following property:<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Property of <idl>com.sun.star.text.ChapterNumberingRule</idl> <br />
!Description <br />
|-<br />
|<idlm>com.sun.star.text.ChapterNumberingRule:HeadingStyleName</idlm> <br />
|<code>string</code> - Contains the name of the paragraph style that marks a paragraph as a chapter heading. <br />
|}<br />
<br />
<br />
{{Documentation/Note|Note that the NumberingRules service is returned by value like most properties in the {{PRODUCTNAME}} API, therefore you must get the rules from the <tt>XPropertySet</tt>, change them and put the <tt>NumberingRules</tt> object back into the property.}}<br />
<br />
The following is an example for the <code>NumberingRules</code> service: <br />
<!--[SOURCE:Text/TextDocuments.java]--><br />
<br />
/** This method demonstrates how to set numbering types and numbering levels using the<br />
com.sun.star.text.NumberingRules service<br />
*/<br />
protected void NumberingExample() {<br />
try {<br />
// Go to the end of the document<br />
mxDocCursor.gotoEnd(false);<br />
// Get the RelativeTextContentInsert interface of the document<br />
XRelativeTextContentInsert xRelative = (XRelativeTextContentInsert)<br />
UnoRuntime.queryInterface(XRelativeTextContentInsert.class, mxDocText);<br />
<br />
// Use the document's factory to create the NumberingRules service, and get it's<br />
// XIndexAccess interface<br />
XIndexAccess xNum = (XIndexAccess) UnoRuntime.queryInterface(XIndexAccess.class,<br />
mxDocFactory.createInstance("com.sun.star.text.NumberingRules"));<br />
<br />
// Also get the NumberingRule's XIndexReplace interface<br />
XIndexReplace xReplace = (XIndexReplace) UnoRuntime.queryInterface(<br />
XIndexReplace.class, xNum);<br />
<br />
// Create an array of XPropertySets, one for each of the three paragraphs we're about<br />
// to create<br />
XPropertySet xParas[] = new XPropertySet[3];<br />
for (int i = 0 ; i < 3 ; ++ i) {<br />
// Create a new paragraph<br />
XTextContent xNewPara = (XTextContent) UnoRuntime.queryInterface(<br />
XTextContent.class, mxDocFactory.createInstance(<br />
"com.sun.star.text.Paragraph"));<br />
<br />
// Get the XPropertySet interface of the new paragraph and put it in our array<br />
xParas[i] = (XPropertySet) UnoRuntime.queryInterface( <br />
XPropertySet.class, xNewPara);<br />
<br />
// Insert the new paragraph into the document after the fish section. As it is<br />
// an insert<br />
// relative to the fish section, the first paragraph inserted will be below<br />
// the next two<br />
xRelative.insertTextContentAfter (xNewPara, mxFishSection);<br />
<br />
// Separate from the above, but also needs to be done three times<br />
<br />
// Get the PropertyValue sequence for this numbering level<br />
PropertyValue[] aProps = (PropertyValue []) xNum.getByIndex(i);<br />
<br />
// Iterate over the PropertyValue's for this numbering level, looking for the<br />
// 'NumberingType' property<br />
for (int j = 0 ; j < aProps.length ; ++j) {<br />
if (aProps[j].Name.equals ("NumberingType")) {<br />
// Once we find it, set it's value to a new type, <br />
// dependent on which<br />
// numbering level we're currently on<br />
switch ( i ) {<br />
case 0 : aProps[j].Value = new Short(NumberingType.ROMAN_UPPER);<br />
break;<br />
case 1 : aProps[j].Value = new Short(NumberingType.CHARS_UPPER_LETTER);<br />
break;<br />
case 2 : aProps[j].Value = new Short(NumberingType.ARABIC);<br />
break;<br />
}<br />
// Put the updated PropertyValue sequence back into the<br />
// NumberingRules service<br />
xReplace.replaceByIndex (i, aProps); <br />
break;<br />
}<br />
}<br />
}<br />
// Get the XParagraphCursor interface of our text cursor<br />
XParagraphCursor xParaCursor = (XParagraphCursor) UnoRuntime.queryInterface(<br />
XParagraphCursor.class, mxDocCursor);<br />
// Go to the end of the document, then select the preceding paragraphs<br />
mxDocCursor.gotoEnd(false);<br />
xParaCursor.gotoPreviousParagraph false);<br />
xParaCursor.gotoPreviousParagraph true);<br />
xParaCursor.gotoPreviousParagraph true);<br />
<br />
// Get the XPropertySet of the cursor's currently selected text<br />
XPropertySet xCursorProps = (XPropertySet) UnoRuntime.queryInterface(<br />
XPropertySet.class, mxDocCursor);<br />
<br />
// Set the updated Numbering rules to the cursor's property set<br />
xCursorProps.setPropertyValue ("NumberingRules", xNum);<br />
mxDocCursor.gotoEnd(false);<br />
<br />
// Set the first paragraph that was inserted to a numbering level of 2 (thus it will<br />
// have Arabic style numbering)<br />
xParas[0].setPropertyValue ("NumberingLevel", new Short ((short) 2));<br />
<br />
// Set the second paragraph that was inserted to a numbering level of 1 (thus it will<br />
// have 'Chars Upper Letter' style numbering)<br />
xParas[1].setPropertyValue ("NumberingLevel", new Short((short) 1));<br />
<br />
// Set the third paragraph that was inserted to a numbering level of 0 (thus it will<br />
// have 'Roman Upper' style numbering)<br />
xParas[2].setPropertyValue("NumberingLevel", new Short((short) 0));<br />
} catch (Exception e) {<br />
e.printStackTrace (System.out);<br />
}<br />
}<br />
<br />
=== Line Numbering ===<br />
<br />
<!--<idltopic>com.sun.star.text.LineNumberingProperties</idltopic>--><br />
The text document model supports the interface <idl>com.sun.star.text.XLineNumberingProperties</idl>. The provided object has the properties described in the service <idl>com.sun.star.text.LineNumberingProperties</idl>. It is used in conjunction with the paragraph properties <code>ParaLineNumberCount</code> and <code>ParaLineNumberStartValue</code>.<br />
<br />
=== Number Formats ===<br />
<br />
<!--<idltopic>com.sun.star.util.XNumberFormatsSupplier</idltopic>--><br />
The text document model provides access to the number formatter through aggregation, that is, it provides the interface <idl>com.sun.star.util.XNumberFormatsSupplier</idl> seamlessly.<br />
<br />
The number formatter is used to format numerical values. For details, refer to [[Documentation/DevGuide/OfficeDev/Number Formats|Number Formats]].<br />
<br />
In text, text fields with numeric content and table cells provide a property <code>NumberFormat</code> that contains a long value that refers to a number format.<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Text Documents]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/Text/Text_FieldsDocumentation/DevGuide/Text/Text Fields2015-05-25T14:18:33Z<p>BMarcelly: </p>
<hr />
<div>{{Documentation/DevGuide/TextTOC<br />
|Text2b=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/Text/Accessing Existing Tables<br />
|NextPage=Documentation/DevGuide/Text/Bookmarks<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/Text/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:Text Fields}}<br />
<!--<idltopic>com.sun.star.text.TextField;com.sun.star.text.XTextField;com.sun.star.text.fieldmaster</idltopic>--><br />
Text fields are text contents that add a second level of information to text ranges. Usually their appearance fuses together with the surrounding text, but actually the presented text comes from elsewhere. Field commands can insert the current date, page number, total page numbers, a cross-reference to another area of text, the content of certain database fields, and many variables, such as fields with changing values, into the document. There are some fields that contain their own data, where others get the data from an attached field master.<br />
<br />
[[Image:TextFields.png|none|thumb|400px|Text Fields and Text Field Masters]]<br />
<br />
Fields are created using the <idl>com.sun.star.lang.XMultiServiceFactory</idl> of the model before inserting them using <code>insertTextContent()</code>. The following text field services are available: <br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Text Field Service Name <br />
!Description <br />
|-<br />
|<idl>com.sun.star.text.textfield.Annotation</idl> <br />
|Annotation created through '''Insert - Note.''' <br />
|-<br />
|<idl>com.sun.star.text.textfield.Author</idl> <br />
|Shows the author of the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.Bibliography</idl> <br />
|Bibliographic entry created by '''Insert - Indexes and Tables - Bibliography Entry'''. The content is the source of the creation of bibliographic indexes. The sequence <code><PropertyValue></code> in the property "Fields" contains pairs of the name of the field and its content, such as: <br />
<br />
Identifier=ABC99<br />
BibliographicType=1<br />
<br />
The names of the fields are defined in <idl>com.sun.star.text.BibliographyDataField</idl>. A bibliographic entry depends on <idl>com.sun.star.text.fieldmaster.Bibliography</idl> <br />
|-<br />
|<idl>com.sun.star.text.textfield.Chapter</idl> <br />
|Show the chapter information. <br />
|-<br />
|<idl>com.sun.star.text.textfield.CharacterCount</idl> <br />
|Show the character count of the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.CombinedCharacters</idl> <br />
|Combines up to six characters as one text object that is formatted in two lines. <br />
|-<br />
|<idl>com.sun.star.text.textfield.ConditionalText</idl> <br />
|Inserts text depending on a condition. <br />
|-<br />
|<idl>com.sun.star.text.textfield.Database</idl> <br />
|The form letter field showing the content from a database. Depends on <idl>com.sun.star.text.fieldmaster.Database</idl>. <br />
|-<br />
|<idl>com.sun.star.text.textfield.DatabaseName</idl> <br />
|Shows the name of a database. <br />
|-<br />
|<idl>com.sun.star.text.textfield.DatabaseNextSet</idl> <br />
|Increments the cursor that points to a database selection. <br />
|-<br />
|<idl>com.sun.star.text.textfield.DatabaseNumberOfSet</idl> <br />
|Shows the set number of a database cursor. <br />
|-<br />
|<idl>com.sun.star.text.textfield.DatabaseSetNumber</idl> <br />
|Databases - Any Record. Sets the number of a database cursor. <br />
|-<br />
|<idl>com.sun.star.text.textfield.DateTime</idl> <br />
|Shows a date or time value. <br />
|-<br />
|<idl>com.sun.star.text.textfield.DDE</idl> <br />
|Shows the result of a DDE operation. Depends on <idl>com.sun.star.text.fieldmaster.DDE</idl>. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.ChangeAuthor</idl> <br />
|Shows the name of the author of the last change of the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.ChangeDateTime</idl> <br />
|Shows the date and time of the last change of the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.CreateAuthor</idl> <br />
|Shows the name of the creator of the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.CreateDateTime</idl> <br />
|Shows the date and time of the document creation. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Custom</idl> <br />
|Shows the content of an user defined field of the document info. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Description</idl> <br />
|Shows the description contained in the document information. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.EditTime</idl> <br />
|Shows the time of the editing of the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Info0</idl> <br />
|Shows the content of the first user defined info field of the document info. This service has been removed in OOo 3.0; use <idl>com.sun.star.text.textfield.docinfo.Custom</idl> instead.<br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Info1</idl> <br />
|Shows the content of the second user defined info field of the document info. This service has been removed in OOo 3.0; use <idl>com.sun.star.text.textfield.docinfo.Custom</idl> instead. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Info2</idl> <br />
|Shows the content of the third user defined info field of the document info. This service has been removed in OOo 3.0; use <idl>com.sun.star.text.textfield.docinfo.Custom</idl> instead.<br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Info3</idl> <br />
|Shows the content of the fourth user defined info field of the document info. This service has been removed in OOo 3.0; use <idl>com.sun.star.text.textfield.docinfo.Custom</idl> instead. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Keywords</idl> <br />
|Shows the keywords contained in the document info. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.PrintAuthor</idl> <br />
|Shows the name of the author of the last printing. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.PrintDateTime</idl> <br />
|Shows the date and time of the last printing. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Revision</idl> <br />
|Shows the revision contained in the document info. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Subject</idl> <br />
|Shows the subject contained in the document info. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Title</idl> <br />
|Shows the title contained in the document info. <br />
|-<br />
|<idl>com.sun.star.text.textfield.EmbeddedObjectCount</idl> <br />
|Shows the number of embedded objects contained in the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.ExtendedUser</idl> <br />
|Shows the user data of the Office user. <br />
|-<br />
|<idl>com.sun.star.text.textfield.FileName</idl> <br />
|Shows the file name (URL) of the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.GetExpression</idl> <br />
|Variables - Show Variable. Shows the value set by the previous occurrence of SetExpression. <br />
|-<br />
|<idl>com.sun.star.text.textfield.GetReference</idl> <br />
|References - Insert Reference. Shows a reference to a reference mark, bookmark, number range field, footnote or an endnote. <br />
|-<br />
|<idl>com.sun.star.text.textfield.GraphicObjectCount</idl> <br />
|Shows the number of graphic object in the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.HiddenParagraph</idl> <br />
|Depending on a condition, the field hides the paragraph it is contained in. <br />
|-<br />
|<idl>com.sun.star.text.textfield.HiddenText</idl> <br />
|Depending on a condition the field shows or hides a text. <br />
|-<br />
|<idl>com.sun.star.text.textfield.Input</idl> <br />
|The field activates a dialog to input a value that changes a related <code>User</code> field or <code>SetExpression</code> field. <br />
|-<br />
|<idl>com.sun.star.text.textfield.InputUser</idl> <br />
|The field activates a dialog to input a string that is displayed by the field. This field is not connected to variables. <br />
|-<br />
|<idl>com.sun.star.text.textfield.JumpEdit</idl> <br />
|A placeholder field with an attached interaction to insert text, a text table, text frame, graphic object or an OLE object. <br />
|-<br />
|<idl>com.sun.star.text.textfield.Macro</idl> <br />
|A field connected to a macro that is executed on a click to the field. To execute such a macro, use the dispatch (cf. Appendix). <br />
|-<br />
|<idl>com.sun.star.text.textfield.PageCount</idl> <br />
|Shows the number of pages of the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.PageNumber</idl> <br />
|Shows the page number (current, previous, next). <br />
|-<br />
|<idl>com.sun.star.text.textfield.ParagraphCount</idl> <br />
|Shows the number of paragraphs contained in the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.ReferencePageGet</idl> <br />
|Displays the page number with respect to the reference point, that is determined by the text field ReferencePageSet. <br />
|-<br />
|<idl>com.sun.star.text.textfield.ReferencePageSet</idl> <br />
|Inserts a starting point for additional page numbers that can be switched on or off. <br />
|-<br />
|<idl>com.sun.star.text.textfield.Script</idl> <br />
|Contains a script or a URL to a script. <br />
|-<br />
|<idl>com.sun.star.text.textfield.SetExpression</idl> <br />
|Variables - Set Variable. A variable field. The value is valid until the next occurrence of <code>SetExpression</code> field. The actual value depends on <idl>com.sun.star.text.fieldmaster.SetExpression</idl>. <br />
|-<br />
|<idl>com.sun.star.text.textfield.TableCount</idl> <br />
|Shows the number of text tables of the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.TableFormula</idl> <br />
|Contains a formula to calculate in a text table. <br />
|-<br />
|<idl>com.sun.star.text.textfield.TemplateName</idl> <br />
|Shows the name of the template the current document is created from. <br />
|-<br />
|<idl>com.sun.star.text.textfield.User</idl> <br />
|Variables - User Field. Creates a global document variable and displays it whenever this field occurs in the text. Depends on <idl>com.sun.star.text.fieldmaster.User</idl>. <br />
|-<br />
|<idl>com.sun.star.text.textfield.WordCount</idl> <br />
|Shows the number of words contained in the document. <br />
|}<br />
<br />
All fields support the interfaces <idl>com.sun.star.text.XTextField</idl>, <idl>com.sun.star.util.XUpdatable</idl>, <idl>com.sun.star.text.XDependentTextField</idl> and the service <idl>com.sun.star.text.TextContent</idl>.<br />
<br />
The method <code>getPresentation()</code> of the interface <idl>com.sun.star.text.XTextField</idl> returns the textual representation of the result of the text field operation, such as a date, time, variable value, or the command, such as CHAPTER, TIME (fixed) depending on the boolean parameter.<br />
<br />
The method <code>update()</code> of the interface <idl>com.sun.star.util.XUpdatable</idl> affects only the following field types:<br />
<br />
* Date and time fields are set to the current date and time.<br />
* The <code>ExtendedUser</code> fields that show parts of the user data set for {{PRODUCTNAME}}, such as the Name, City, Phone No. and the Author fields that are set to the current values.<br />
* The <code>FileName</code> fields are updated with the current name of the file.<br />
* The <code>DocInfo.XXX</code> fields are updated with the current document info of the document.<br />
<br />
All other fields ignore calls to <code>update()</code>.<br />
<br />
Some of these fields need a field master that provides the data that appears in the field. This applies to the field types <code>Database</code>, <code>SetExpression</code>, <code>DDE</code>, <code>User</code> and <code>Bibliography</code>. The interface <idl>com.sun.star.text.XDependentTextField</idl> handles these pairs of FieldMasters and TextFields. The method <code>attachTextFieldMaster()</code> must be called prior to inserting the field into the document. The method <code>getTextFieldMaster()</code> does not work unless the dependent field is inserted into the document.<br />
<br />
To create a valid text field master, the instance has to be created using the <idl>com.sun.star.lang.XMultiServiceFactory</idl> interface of the model with the appropriate service name:<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Text Field Master Service Names <br />
!Description <br />
|-<br />
|<idl>com.sun.star.text.fieldmaster.User</idl> <br />
|Contains the global variable that is created and displayed by the fieldtype <idl>com.sun.star.text.textfield.User</idl>. <br />
|-<br />
|<idl>com.sun.star.text.fieldmaster.DDE</idl> <br />
|The DDE command for a <idl>com.sun.star.text.textfield.DDE</idl>. <br />
|-<br />
|<idl>com.sun.star.text.fieldmaster.SetExpression</idl> <br />
|Numbering settings if the corresponding <idl>com.sun.star.text.textfield.SetExpression</idl> is a number range. A sub type of expression. <br />
|-<br />
|<idl>com.sun.star.text.fieldmaster.Database</idl> <br />
|Data source definition for a <idl>com.sun.star.text.textfield.Database</idl>. <br />
|-<br />
|<idl>com.sun.star.text.fieldmaster.Bibliography</idl> <br />
|Display settings and sorting for <idl>com.sun.star.text.textfield.Bibliography</idl>. <br />
|}<br />
<br />
The property Name has to be set after the field instance is created, except for the <code>Database</code> field master type where the properties <code>DatabaseName</code>, <code>DatabaseTableName</code>, <code>DataColumnName</code> and <code>DatabaseCommandType</code> are set instead of the <code>Name</code> property.<br />
<br />
To access existing text fields and field masters, use the interface <idl>com.sun.star.text.XTextFieldsSupplier</idl> that is implemented at the text document model. <br />
<br />
Its method <code>getTextFields()</code> returns a <idl>com.sun.star.text.TextFields</idl> container which is a <idl>com.sun.star.container.XEnumerationAccess</idl> and can be refreshed through the <code>refresh()</code> method in its interface <idl>com.sun.star.util.XRefreshable</idl>.<br />
<br />
Its method <code>getTextFieldMasters()</code> returns a <idl>com.sun.star.text.TextFieldMasters</idl> container holding the text field masters of the document. This container provides a <idl>com.sun.star.container.XNameAccess</idl> interface. All field masters, except for <code>Database</code> are named by the service name followed by the name of the field master. The <code>Database</code> field masters create their names by appending the <code>DatabaseName</code>, <code>DataTableName</code> and <code>DataColumnName</code> to the service name. <br />
<br />
Consider the following examples for this naming convention:<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|"com.sun.star.text.fieldmaster.SetExpression.Illustration" <br />
|Master for Illustration number range. Number ranges are built-in <code>SetExpression</code> fields present in every document. <br />
|-<br />
|"com.sun.star.text.fieldmaster.User.Company" <br />
|Master for <code>User</code> field (global document variable), inserted with display name Company. <br />
|-<br />
|"com.sun.star.text.fieldmaster.Database.Bibliography.biblio.Identifier" <br />
|Master for form letter field referring to the column <code>Identifier</code> in the built-in dbase database table biblio. <br />
|}<br />
<br />
Each text field master has a property <code>InstanceName</code> that contains its name in the format of the related container. <br />
<br />
Some <code>SetExpression</code> text field masters are always available if they are not deleted. These are the masters with the names Text, Illustration, Table and Drawing. They are predefined as number range field masters used for captions of text frames, graphics, text tables and drawings. Note that these predefined names are internal names that are usually not used at the user interface. <br />
<br />
The following methods show how to create and insert text fields. <br />
<!--[SOURCE:Text/TextDocuments.java]--><br />
<source lang="java"><br />
/** This method inserts both a date field and a user field containing the number '42'<br />
*/<br />
protected void TextFieldExample() {<br />
try {<br />
// Use the text document's factory to create a DateTime text field, <br />
// and access it's<br />
// XTextField interface<br />
XTextField xDateField = (XTextField) UnoRuntime.queryInterface(<br />
XTextField.class, mxDocFactory.createInstance(<br />
"com.sun.star.text.textfield.DateTime"));<br />
<br />
// Insert it at the end of the document<br />
mxDocText.insertTextContent ( mxDocText.getEnd(), xDateField, false );<br />
<br />
// Use the text document's factory to create a user text field, <br />
// and access it's XDependentTextField interface<br />
XDependentTextField xUserField = (XDependentTextField) UnoRuntime.queryInterface (<br />
XDependentTextField.class, mxDocFactory.createInstance(<br />
"com.sun.star.text.textfield.User"));<br />
<br />
// Create a fieldmaster for our newly created User Text field, and access it's <br />
// XPropertySet interface<br />
XPropertySet xMasterPropSet = (XPropertySet) UnoRuntime.queryInterface(<br />
XPropertySet.class, mxDocFactory.createInstance(<br />
"com.sun.star.text.fieldmaster.User"));<br />
<br />
// Set the name and value of the FieldMaster<br />
xMasterPropSet.setPropertyValue ("Name", "UserEmperor");<br />
xMasterPropSet.setPropertyValue ("Value", new Integer(42));<br />
<br />
// Attach the field master to the user field<br />
xUserField.attachTextFieldMaster (xMasterPropSet);<br />
<br />
// Move the cursor to the end of the document<br />
mxDocCursor.gotoEnd(false);<br />
// insert a paragraph break using the XSimpleText interface<br />
mxDocText.insertControlCharacter( <br />
mxDocCursor, ControlCharacter.PARAGRAPH_BREAK, false);<br />
<br />
// Insert the user field at the end of the document<br />
mxDocText.insertTextContent(mxDocText.getEnd(), xUserField, false);<br />
} catch (Exception e) {<br />
e.printStackTrace (System.out);<br />
}<br />
}<br />
</source><br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Text Documents]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/Text/Text_FieldsDocumentation/DevGuide/Text/Text Fields2015-05-25T14:07:37Z<p>BMarcelly: Align Left caused copy problems</p>
<hr />
<div>{{Documentation/DevGuide/TextTOC<br />
|Text2b=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/Text/Accessing Existing Tables<br />
|NextPage=Documentation/DevGuide/Text/Bookmarks<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/Text/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:Text Fields}}<br />
<!--<idltopic>com.sun.star.text.TextField;com.sun.star.text.XTextField;com.sun.star.text.fieldmaster</idltopic>--><br />
Text fields are text contents that add a second level of information to text ranges. Usually their appearance fuses together with the surrounding text, but actually the presented text comes from elsewhere. Field commands can insert the current date, page number, total page numbers, a cross-reference to another area of text, the content of certain database fields, and many variables, such as fields with changing values, into the document. There are some fields that contain their own data, where others get the data from an attached field master.<br />
<br />
[[Image:TextFields.png|none|thumb|400px|Text Fields and Text Field Masters]]<br />
<br />
Fields are created using the <idl>com.sun.star.lang.XMultiServiceFactory</idl> of the model before inserting them using <code>insertTextContent()</code>. The following text field services are available: <br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Text Field Service Name <br />
!Description <br />
|-<br />
|<idl>com.sun.star.text.textfield.Annotation</idl> <br />
|Annotation created through '''Insert - Note.''' <br />
|-<br />
|<idl>com.sun.star.text.textfield.Author</idl> <br />
|Shows the author of the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.Bibliography</idl> <br />
|Bibliographic entry created by '''Insert - Indexes and Tables - Bibliography Entry'''. The content is the source of the creation of bibliographic indexes. The sequence <code><PropertyValue></code> in the property "Fields" contains pairs of the name of the field and its content, such as: <br />
<br />
Identifier=ABC99<br />
BibliographicType=1<br />
<br />
The names of the fields are defined in <idl>com.sun.star.text.BibliographyDataField</idl>. A bibliographic entry depends on <idl>com.sun.star.text.fieldmaster.Bibliography</idl> <br />
|-<br />
|<idl>com.sun.star.text.textfield.Chapter</idl> <br />
|Show the chapter information. <br />
|-<br />
|<idl>com.sun.star.text.textfield.CharacterCount</idl> <br />
|Show the character count of the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.CombinedCharacters</idl> <br />
|Combines up to six characters as one text object that is formatted in two lines. <br />
|-<br />
|<idl>com.sun.star.text.textfield.ConditionalText</idl> <br />
|Inserts text depending on a condition. <br />
|-<br />
|<idl>com.sun.star.text.textfield.Database</idl> <br />
|The form letter field showing the content from a database. Depends on <idl>com.sun.star.text.fieldmaster.Database</idl>. <br />
|-<br />
|<idl>com.sun.star.text.textfield.DatabaseName</idl> <br />
|Shows the name of a database. <br />
|-<br />
|<idl>com.sun.star.text.textfield.DatabaseNextSet</idl> <br />
|Increments the cursor that points to a database selection. <br />
|-<br />
|<idl>com.sun.star.text.textfield.DatabaseNumberOfSet</idl> <br />
|Shows the set number of a database cursor. <br />
|-<br />
|<idl>com.sun.star.text.textfield.DatabaseSetNumber</idl> <br />
|Databases - Any Record. Sets the number of a database cursor. <br />
|-<br />
|<idl>com.sun.star.text.textfield.DateTime</idl> <br />
|Shows a date or time value. <br />
|-<br />
|<idl>com.sun.star.text.textfield.DDE</idl> <br />
|Shows the result of a DDE operation. Depends on <idl>com.sun.star.text.fieldmaster.DDE</idl>. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.ChangeAuthor</idl> <br />
|Shows the name of the author of the last change of the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.ChangeDateTime</idl> <br />
|Shows the date and time of the last change of the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.CreateAuthor</idl> <br />
|Shows the name of the creator of the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.CreateDateTime</idl> <br />
|Shows the date and time of the document creation. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Custom</idl> <br />
|Shows the content of an user defined field of the document info. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Description</idl> <br />
|Shows the description contained in the document information. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.EditTime</idl> <br />
|Shows the time of the editing of the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Info0</idl> <br />
|Shows the content of the first user defined info field of the document info. This service has been removed in OOo 3.0; use <idl>com.sun.star.text.textfield.docinfo.Custom</idl> instead.<br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Info1</idl> <br />
|Shows the content of the second user defined info field of the document info. This service has been removed in OOo 3.0; use <idl>com.sun.star.text.textfield.docinfo.Custom</idl> instead. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Info2</idl> <br />
|Shows the content of the third user defined info field of the document info. This service has been removed in OOo 3.0; use <idl>com.sun.star.text.textfield.docinfo.Custom</idl> instead.<br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Info3</idl> <br />
|Shows the content of the fourth user defined info field of the document info. This service has been removed in OOo 3.0; use <idl>com.sun.star.text.textfield.docinfo.Custom</idl> instead. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Keywords</idl> <br />
|Shows the keywords contained in the document info. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.PrintAuthor</idl> <br />
|Shows the name of the author of the last printing. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.PrintDateTime</idl> <br />
|Shows the date and time of the last printing. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Revision</idl> <br />
|Shows the revision contained in the document info. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Subject</idl> <br />
|Shows the subject contained in the document info. <br />
|-<br />
|<idl>com.sun.star.text.textfield.docinfo.Title</idl> <br />
|Shows the title contained in the document info. <br />
|-<br />
|<idl>com.sun.star.text.textfield.EmbeddedObjectCount</idl> <br />
|Shows the number of embedded objects contained in the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.ExtendedUser</idl> <br />
|Shows the user data of the Office user. <br />
|-<br />
|<idl>com.sun.star.text.textfield.FileName</idl> <br />
|Shows the file name (URL) of the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.GetExpression</idl> <br />
|Variables - Show Variable. Shows the value set by the previous occurrence of SetExpression. <br />
|-<br />
|<idl>com.sun.star.text.textfield.GetReference</idl> <br />
|References - Insert Reference. Shows a reference to a reference mark, bookmark, number range field, footnote or an endnote. <br />
|-<br />
|<idl>com.sun.star.text.textfield.GraphicObjectCount</idl> <br />
|Shows the number of graphic object in the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.HiddenParagraph</idl> <br />
|Depending on a condition, the field hides the paragraph it is contained in. <br />
|-<br />
|<idl>com.sun.star.text.textfield.HiddenText</idl> <br />
|Depending on a condition the field shows or hides a text. <br />
|-<br />
|<idl>com.sun.star.text.textfield.Input</idl> <br />
|The field activates a dialog to input a value that changes a related User field or <code>SetExpression<code> field. <br />
|-<br />
|<idl>com.sun.star.text.textfield.InputUser</idl> <br />
|The field activates a dialog to input a string that is displayed by the field. This field is not connected to variables. <br />
|-<br />
|<idl>com.sun.star.text.textfield.JumpEdit</idl> <br />
|A placeholder field with an attached interaction to insert text, a text table, text frame, graphic object or an OLE object. <br />
|-<br />
|<idl>com.sun.star.text.textfield.Macro</idl> <br />
|A field connected to a macro that is executed on a click to the field. To execute such a macro, use the dispatch (cf. Appendix). <br />
|-<br />
|<idl>com.sun.star.text.textfield.PageCount</idl> <br />
|Shows the number of pages of the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.PageNumber</idl> <br />
|Shows the page number (current, previous, next). <br />
|-<br />
|<idl>com.sun.star.text.textfield.ParagraphCount</idl> <br />
|Shows the number of paragraphs contained in the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.ReferencePageGet</idl> <br />
|Displays the page number with respect to the reference point, that is determined by the text field ReferencePageSet. <br />
|-<br />
|<idl>com.sun.star.text.textfield.ReferencePageSet</idl> <br />
|Inserts a starting point for additional page numbers that can be switched on or off. <br />
|-<br />
|<idl>com.sun.star.text.textfield.Script</idl> <br />
|Contains a script or a URL to a script. <br />
|-<br />
|<idl>com.sun.star.text.textfield.SetExpression</idl> <br />
|Variables - Set Variable. A variable field. The value is valid until the next occurrence of <code>SetExpression</code> field. The actual value depends on <idl>com.sun.star.text.fieldmaster.SetExpression</idl>. <br />
|-<br />
|<idl>com.sun.star.text.textfield.TableCount</idl> <br />
|Shows the number of text tables of the document. <br />
|-<br />
|<idl>com.sun.star.text.textfield.TableFormula</idl> <br />
|Contains a formula to calculate in a text table. <br />
|-<br />
|<idl>com.sun.star.text.textfield.TemplateName</idl> <br />
|Shows the name of the template the current document is created from. <br />
|-<br />
|<idl>com.sun.star.text.textfield.User</idl> <br />
|Variables - User Field. Creates a global document variable and displays it whenever this field occurs in the text. Depends on <idl>com.sun.star.text.fieldmaster.User</idl>. <br />
|-<br />
|<idl>com.sun.star.text.textfield.WordCount</idl> <br />
|Shows the number of words contained in the document. <br />
|}<br />
<br />
All fields support the interfaces <idl>com.sun.star.text.XTextField</idl>, <idl>com.sun.star.util.XUpdatable</idl>, <idl>com.sun.star.text.XDependentTextField</idl> and the service <idl>com.sun.star.text.TextContent</idl>.<br />
<br />
The method <code>getPresentation()</code> of the interface <idl>com.sun.star.text.XTextField</idl> returns the textual representation of the result of the text field operation, such as a date, time, variable value, or the command, such as CHAPTER, TIME (fixed) depending on the boolean parameter.<br />
<br />
The method <code>update()</code> of the interface <idl>com.sun.star.util.XUpdatable</idl> affects only the following field types:<br />
<br />
* Date and time fields are set to the current date and time.<br />
* The <code>ExtendedUser</code> fields that show parts of the user data set for {{PRODUCTNAME}}, such as the Name, City, Phone No. and the Author fields that are set to the current values.<br />
* The <code>FileName</code> fields are updated with the current name of the file.<br />
* The <code>DocInfo.XXX</code> fields are updated with the current document info of the document.<br />
<br />
All other fields ignore calls to <code>update()</code>.<br />
<br />
Some of these fields need a field master that provides the data that appears in the field. This applies to the field types <code>Database</code>, <code>SetExpression</code>, <code>DDE</code>, <code>User</code> and <code>Bibliography</code>. The interface <idl>com.sun.star.text.XDependentTextField</idl> handles these pairs of FieldMasters and TextFields. The method <code>attachTextFieldMaster()</code> must be called prior to inserting the field into the document. The method <code>getTextFieldMaster()</code> does not work unless the dependent field is inserted into the document.<br />
<br />
To create a valid text field master, the instance has to be created using the <idl>com.sun.star.lang.XMultiServiceFactory</idl> interface of the model with the appropriate service name:<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Text Field Master Service Names <br />
!Description <br />
|-<br />
|<idl>com.sun.star.text.fieldmaster.User</idl> <br />
|Contains the global variable that is created and displayed by the fieldtype <idl>com.sun.star.text.textfield.User</idl>. <br />
|-<br />
|<idl>com.sun.star.text.fieldmaster.DDE</idl> <br />
|The DDE command for a <idl>com.sun.star.text.textfield.DDE</idl>. <br />
|-<br />
|<idl>com.sun.star.text.fieldmaster.SetExpression</idl> <br />
|Numbering settings if the corresponding <idl>com.sun.star.text.textfield.SetExpression</idl> is a number range. A sub type of expression. <br />
|-<br />
|<idl>com.sun.star.text.fieldmaster.Database</idl> <br />
|Data source definition for a <idl>com.sun.star.text.textfield.Database</idl>. <br />
|-<br />
|<idl>com.sun.star.text.fieldmaster.Bibliography</idl> <br />
|Display settings and sorting for <idl>com.sun.star.text.textfield.Bibliography</idl>. <br />
|}<br />
<br />
The property Name has to be set after the field instance is created, except for the <code>Database</code> field master type where the properties <code>DatabaseName</code>, <code>DatabaseTableName</code>, <code>DataColumnName</code> and <code>DatabaseCommandType</code> are set instead of the <code>Name</code> property.<br />
<br />
To access existing text fields and field masters, use the interface <idl>com.sun.star.text.XTextFieldsSupplier</idl> that is implemented at the text document model. <br />
<br />
Its method <code>getTextFields()</code> returns a <idl>com.sun.star.text.TextFields</idl> container which is a <idl>com.sun.star.container.XEnumerationAccess</idl> and can be refreshed through the <code>refresh()</code> method in its interface <idl>com.sun.star.util.XRefreshable</idl>.<br />
<br />
Its method <code>getTextFieldMasters()</code> returns a <idl>com.sun.star.text.TextFieldMasters</idl> container holding the text field masters of the document. This container provides a <idl>com.sun.star.container.XNameAccess</idl> interface. All field masters, except for <code>Database</code> are named by the service name followed by the name of the field master. The <code>Database</code> field masters create their names by appending the <code>DatabaseName</code>, <code>DataTableName</code> and <code>DataColumnName</code> to the service name. <br />
<br />
Consider the following examples for this naming convention:<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|"com.sun.star.text.fieldmaster.SetExpression.Illustration" <br />
|Master for Illustration number range. Number ranges are built-in <code>SetExpression</code> fields present in every document. <br />
|-<br />
|"com.sun.star.text.fieldmaster.User.Company" <br />
|Master for <code>User</code> field (global document variable), inserted with display name Company. <br />
|-<br />
|"com.sun.star.text.fieldmaster.Database.Bibliography.biblio.Identifier" <br />
|Master for form letter field referring to the column <code>Identifier</code> in the built-in dbase database table biblio. <br />
|}<br />
<br />
Each text field master has a property <code>InstanceName</code> that contains its name in the format of the related container. <br />
<br />
Some <code>SetExpression</code> text field masters are always available if they are not deleted. These are the masters with the names Text, Illustration, Table and Drawing. They are predefined as number range field masters used for captions of text frames, graphics, text tables and drawings. Note that these predefined names are internal names that are usually not used at the user interface. <br />
<br />
The following methods show how to create and insert text fields. <br />
<!--[SOURCE:Text/TextDocuments.java]--><br />
<source lang="java"><br />
/** This method inserts both a date field and a user field containing the number '42'<br />
*/<br />
protected void TextFieldExample() {<br />
try {<br />
// Use the text document's factory to create a DateTime text field, <br />
// and access it's<br />
// XTextField interface<br />
XTextField xDateField = (XTextField) UnoRuntime.queryInterface(<br />
XTextField.class, mxDocFactory.createInstance(<br />
"com.sun.star.text.textfield.DateTime"));<br />
<br />
// Insert it at the end of the document<br />
mxDocText.insertTextContent ( mxDocText.getEnd(), xDateField, false );<br />
<br />
// Use the text document's factory to create a user text field, <br />
// and access it's XDependentTextField interface<br />
XDependentTextField xUserField = (XDependentTextField) UnoRuntime.queryInterface (<br />
XDependentTextField.class, mxDocFactory.createInstance(<br />
"com.sun.star.text.textfield.User"));<br />
<br />
// Create a fieldmaster for our newly created User Text field, and access it's <br />
// XPropertySet interface<br />
XPropertySet xMasterPropSet = (XPropertySet) UnoRuntime.queryInterface(<br />
XPropertySet.class, mxDocFactory.createInstance(<br />
"com.sun.star.text.fieldmaster.User"));<br />
<br />
// Set the name and value of the FieldMaster<br />
xMasterPropSet.setPropertyValue ("Name", "UserEmperor");<br />
xMasterPropSet.setPropertyValue ("Value", new Integer(42));<br />
<br />
// Attach the field master to the user field<br />
xUserField.attachTextFieldMaster (xMasterPropSet);<br />
<br />
// Move the cursor to the end of the document<br />
mxDocCursor.gotoEnd(false);<br />
// insert a paragraph break using the XSimpleText interface<br />
mxDocText.insertControlCharacter( <br />
mxDocCursor, ControlCharacter.PARAGRAPH_BREAK, false);<br />
<br />
// Insert the user field at the end of the document<br />
mxDocText.insertTextContent(mxDocText.getEnd(), xUserField, false);<br />
} catch (Exception e) {<br />
e.printStackTrace (System.out);<br />
}<br />
}<br />
</source><br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Text Documents]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/AppendixC/The_WebDAV_Content_ProviderDocumentation/DevGuide/AppendixC/The WebDAV Content Provider2015-05-25T10:09:12Z<p>BMarcelly: /* Commands and Properties */</p>
<hr />
<div>{{Documentation/DevGuide/AppendixCTOC<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/AppendixC/The FTP Content Provider<br />
|NextPage=Documentation/DevGuide/AppendixC/The Package Content Provider<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/AppendixC/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:The WebDAV Content Provider}}<br />
__NOTOC__<br />
The WebDAV Content Provider (DCP) implements a content provider for the Universal Content Broker (UCB). An overview is provided at URLs http://www.webdav.org and http://www.fileangel.org/docs/DAV_2min.html. It provides access to WebDAV and standard HTTP servers. The DCP communicates with the server by using the WebDAV protocol that is an extension to the HTTP protocol, or by using the plain HTTP protocol if the server is not WebDAV-enabled. <br />
<br />
=== DCP Contents ===<br />
<br />
The DCP provides two types of content: a folder or document that corresponds to a collection or non-collection, of nodes and leafs, in WebDAV, respectively.<br />
<br />
# A DCP folder is a container for other DCP Folders or Documents.<br />
# A DCP document is a container for document data or content. The data or content can be any type. A WebDAV server, like an HTTP server, does not mandate what type of data or content is contained within Documents. The type of data or content is defined by the <code>MediaType</code> property which is different from the content type returned from the <code>getContentType()</code> method. The <code>MediaType</code> property is mapped to the equivalent WebDAV property and the WebDAV server calculates the value.<br />
<br />
[[Image:dav-ucp.png|none|thumb|400px|WebDav Content Provider]]<br />
<br />
=== Creation of New DCP Contents ===<br />
<br />
<!--<idltopic>com.sun.star.ucb.XContentCreator</idltopic>--><br />
DCP folders implement the interface <idl>com.sun.star.ucb.XContentCreator</idl>. DCP documents and DCP folders support the command "<code>insert</code>". To create a new child of a DCP folder:<br />
<br />
# The parent folder creates a new content by calling its <code>createNewContent()</code> method. The content type for new folders is "<code>application/vnd.sun.star.webdav-collection</code>". To create a new document, use the type string "<code>application/http-content</code>".<br />
# Set a title for the new folder or document. The new child executes a "<code>setPropertyValues</code>" command that sets the property Title to a non-empty value.<br />
# The new child, not the parent, executes the command "<code>insert</code>". This commits the creation process and makes the newly-created content on the WebDAV server persistent.<br />
<br />
=== Authentication ===<br />
<br />
DAV resources that require authentication are accessed using the interaction handler mechanism of the UCB. The DAV content calls an interaction handler supplied by the client to let it handle an authentication request. The implementation of the interaction handler collects the user name or password from a location, for example, a login dialog, and supplies this data as an interaction response.<br />
<br />
=== Property Handling ===<br />
<br />
In addition to the mandatory UCB properties, the DCP supports reading and writing all DAV ''live'' and ''dead'' properties. Some DAV live properties are mapped in addition to the UCB properties and conversely, that is, ''DAV:creationdate'' is mapped to <code>DateCreated</code>. Adding and removing dead properties is also supported by the implementation of the <code>XPropertyContainer</code> interface of a DCP content.<br />
<br />
==== Property Values ====<br />
<br />
The DCP cannot determine the semantics of unknown properties, thus the values of such properties will always be presented as plain text, as they were returned from the server.<br />
<br />
==== Namespaces ====<br />
<br />
The following namespaces are known to the DCP:<br />
<br />
* DAV:<br />
* http://apache.org/dav/props/<br />
<br />
Properties with these namespaces are addressed using a UCB property name which is the concatenation of namespace and name, that is, DAV:getcontentlength.<br />
<br />
Dead properties with namespaces that are not well-known to the DCP are addressed using a special UCB property name string, that contains both the namespace and the property name. A special property name string must be similar to the following:<br />
<source lang="xml"><br />
<prop:the_propname xmlns:prop="the_namespace"> <br />
</source><br />
The DCP internally applies the namespace http://ucb.openoffice.org/dav/props/ to all UCB property names that:<br />
<br />
* are not predefined by the UCB API.<br />
* do not start with a well-known namespace.<br />
* do not use the special property name string to encode namespace and name.<br />
<br />
For example, a client does an <code>addProperty( .... "MyAdditionalProperty" ... )</code>. The resulting DAV property has the name <code>MyAdditionalProperty</code>, its namespace is http://ucb.openoffice.org/dav/props/. However, the DCP client never sees that namespace, but the client can always use the simple name <code>MyAdditionalProperty</code>.<br />
<br />
==== DAV / UCB Property Mapping ====<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|DAV:creationdate <br />
|DateCreated <br />
|-<br />
|DAV:getlastmodified <br />
|DateModified <br />
|-<br />
|DAV:getcontenttype <br />
|MediaType <br />
|-<br />
|DAV:getcontentlength <br />
|Size <br />
|-<br />
|DAV:resourcetype <br />
|(used to set IsFolder, IsDocument, ContentType) <br />
|}<br />
<br />
=== URL Scheme for DCP Contents ===<br />
<br />
Each DCP content has an identifier corresponding to the following scheme:<br />
<br />
vnd.sun.star.webdav://host:port/<path><br />
<br />
where <code><path></code> is a hierarchical path of the form<br />
<br />
<name>/<name>/.../<name><br />
<br />
where <code><name></code> is an encoded string according to the URL conventions.<br />
<br />
It is also possible to use standard HTTP URLs. The implementation determines if the requested resource is DAV enabled.<br />
<br />
Examples:<br />
<br />
vnd.sun.star.webdav://localhost/davhome/<br />
<br />
vnd.sun.star.webdav://davserver.com/Documents/report.sdw<br />
<br />
http://davserver.com/Documents/report.sdw<br />
<br />
{{Documentation/Note|Note that the WebDAV URL namespace model is the same as the HTTP URL namespace model.}}<br />
<br />
=== Commands and Properties ===<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
|<br />
!UCB Type (returned by XContent::getContentType )<br />
!Properties<br />
!Commands<br />
!Interfaces<br />
|-<br />
!Document<br />
|application/http-content <br />
|[readonly] ContentType<br><br />
[readonly] DateCreated<br><br />
[readonly] DateModified<br><br />
[readonly] IsDocument<br><br />
[readonly] IsFolder<br><br />
[readonly] MediaType<br><br />
[readonly] Size<br><br />
'Title' <br />
|getCommandInfo<br><br />
getPropertySetInfo<br><br />
getPropertyValues<br><br />
setPropertyValues<br><br />
insert<br><br />
delete<br><br />
open <br />
|<idls>com.sun.star.lang.XTypeProvider</idls><br><br />
<idls>com.sun.star.lang.XServiceInfo</idls><br><br />
<idls>com.sun.star.lang.XComponent</idls><br><br />
<idls>com.sun.star.ucb.XContent</idls><br><br />
<idls>com.sun.star.ucb.XCommandProcessor</idls><br><br />
<idls>com.sun.star.beans.XPropertiesChangeNotifier</idls><br><br />
<idls>com.sun.star.beans.XPropertyContainer</idls><br><br />
<idls>com.sun.star.beans.XPropertySetInfoChangeNotifier</idls><br><br />
<idls>com.sun.star.ucb.XCommandInfoChangeNotifier</idls><br><br />
<idls>com.sun.star.container.XChild</idls> <br />
|-<br />
!Folder<br />
|application/vnd.sun.star.webdav-collection <br />
|[readonly] ContentType<br><br />
[readonly] DateCreated<br><br />
[readonly] DateModified<br><br />
[readonly] IsDocument<br><br />
[readonly] IsFolder<br><br />
[readonly] MediaType<br><br />
[readonly] Size<br><br />
Title <br />
|getCommandInfo<br><br />
getPropertySetInfo<br><br />
getPropertyValues<br><br />
setPropertyValues<br><br />
insert<br><br />
delete<br><br />
open<br><br />
transfer <br />
|same as DCP Folder, plus <br />
<idls>com.sun.star.ucb.XContentCreator</idls> <br />
|}<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Appendix]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/AppendixC/The_FTP_Content_ProviderDocumentation/DevGuide/AppendixC/The FTP Content Provider2015-05-25T10:07:00Z<p>BMarcelly: /* Commands and Properties */</p>
<hr />
<div>{{Documentation/DevGuide/AppendixCTOC<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/AppendixC/The File Content Provider<br />
|NextPage=Documentation/DevGuide/AppendixC/The WebDAV Content Provider<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/AppendixC/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:The FTP Content Provider}}<br />
__NOTOC__<br />
The FTP content provider implements a content provider for the Universal Content Broker (UCB). It provides access to the contents, folders and documents, made available by FTP servers.<br />
<br />
=== FTP Contents ===<br />
<br />
The FTP Content Provider provides three different types of contents: ''accounts'', ''folders'' and ''documents''.<br />
<br />
# An FTP account is a content that represents an account for an FTP server. An account is uniquely determined by a combination of a user name and the host name of the FTP server. Anonymous FTP accounts have the string "anonymous" as a user name. An FTP account also represents the base directory, that is, the directory that is selected when the user logs in to the FTP server, and behaves like an FTP folder.<br />
# An FTP folder is a content that represents a directory on an FTP server. An FTP folder never has a content stream, but it can have FTP folders and FTP documents as children.<br />
# An FTP document is a content that represents a single file on an FTP server. An FTP document always has a content stream and never has children.<br />
<br />
[[Image:ftp-ucp.png|none|thumb|400px|Overview of an FTP Content Provider]]<br />
<br />
=== Creation of New FTP Content ===<br />
<br />
<!--<idltopic>com.sun.star.ucb.XContentCreator</idltopic>--><br />
FTP accounts and FTP folders implement the interface <idl>com.sun.star.ucb.XContentCreator</idl>. FTP folders and FTP documents support the command "insert"allowing all the FTP accounts and FTP folders to create new FTP folders and FTP documents. To create a new child of an FTP account or FTP folder:<br />
<br />
# The folder creates a new content by calling its <code>createNewContent()</code> method. The content type for new folders is "<code>application/vnd.sun.staroffice.ftp-folder</code>". To create a new document, use the type string "<code>application/vnd.sun.staroffice.ftp-file</code>".<br />
# Set a title at the new folder or document. The new child executes a "<code>setPropertyValues</code>" command that sets the property <code>Title</code> to a non-empty value.<br />
# The new child, not the parent, executes the command "insert". This commits the creation process. For documents, supply an <idl>com.sun.star.io.XInputStream</idl>, whose contents are transferred to the FTP server with the command's parameters.<br />
<br />
FTP accounts cannot be created the way new FTP folders or FTP documents are created. When you call the FTP content provider's <code>queryContent()</code> method with the URL of an FTP account, a content object representing that account, user name and host combination, is automatically created. The same as the URL of an already existing FTP folder or FTP document.<br />
<br />
=== URL Scheme for FTP Contents ===<br />
<br />
Each FTP content has an identifier corresponding to the following scheme (see also RFCs 1738, 2234, 2396, and 2732):<br />
<br />
ftp-URL ::= "ftp://" login *("/" segment)<br />
login ::= [user [":" password] "@"] hostport<br />
user ::= *(escaped / unreserved / "$" / "&" / "+" / "," / ";" / "=")<br />
password ::= *(escaped / unreserved / "$" / "&" / "+" / "," / ";" / "=")<br />
hostport ::= host [":" port]<br />
host ::= incomplete-hostname / hostname / IPv4address<br />
incomplete-hostname ::= *(domainlabel ".") domainlabel<br />
hostname ::= *(domainlabel ".") toplabel ["."]<br />
domainlabel ::= alphanum [*(alphanum / "-") alphanum]<br />
toplabel ::= ALPHA [*(alphanum / "-") alphanum]<br />
IPv4address ::= 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT<br />
port ::= *DIGIT<br />
segment ::= *pchar<br />
pchar ::= escaped / unreserved / "$" / "&" / "+" / "," / ":" / "=" / "@"<br />
escaped ::= "%" HEXDIG HEXDIG<br />
unreserved ::= alphanum / mark<br />
alphanum ::= ALPHA / DIGIT<br />
mark ::= "!" / "'" / "(" / ")" / "*" / "-" / "." / "_" / "~"<br />
<br />
FTP accounts have a login part, optionally followed by a single slash, and no segments. FTP folders have a login part followed by one or more nonempty segments that ''must be followed by a slash''. FTP documents have a login part followed by one or more nonempty segments that ''must not be followed by a slash'', that is, the FTP content provider uses a potential final slash of a URL to distinguish between folders and documents. Note that this is subject to change in future versions of the provider.<br />
<br />
Examples:<br />
<br />
''ftp://me@ftp.host''<br />
:The account of user "me" on the FTP server "ftp.host".<br />
<br />
''ftp://ftp.host/pub/doc1.txt''<br />
:A document on an anonymous FTP account.<br />
<br />
''ftp://me:secret@ftp.host/secret-documents/''<br />
:A folder within the account of user "me" with the password specified directly in the URL. Not recommended.<br />
<br />
=== Commands and Properties ===<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
|<br />
!UCB Type (returned by XContent::getContentType )<br />
!Properties<br />
!Commands<br />
!Interfaces<br />
|-<br />
!Account<br />
|application/vnd.sun.staroffice.ftp-box <br />
|[readonly] ContentType<br><br />
[readonly] IsDocument<br><br />
[readonly] IsFolder<br><br />
Title<br><br />
UserName<br><br />
Password<br><br />
FTPAccount<sup>1</sup><br><br />
ServerName<br><br />
ServerBase<sup>2</sup><br />
[readonly] DateCreated<br><br />
[readonly] DateModified<br><br />
[readonly] FolderCount<br><br />
[readonly] DocumentCount <br />
|getCommandInfo<br><br />
getPropertySetInfo<br><br />
getPropertyValues<br><br />
setPropertyValues<br><br />
open<br><br />
transfer<sup>3</sup> <br />
|<idls>com.sun.star.lang.XTypeProvider</idls><br><br />
<idls>com.sun.star.lang.XServiceInfo</idls><br><br />
<idls>com.sun.star.lang.XComponent</idls><br><br />
<idls>com.sun.star.ucb.XContent</idls><br><br />
<idls>com.sun.star.ucb.XCommandProcessor</idls><br><br />
<idls>com.sun.star.beans.XPropertiesChangeNotifier</idls><br><br />
<idls>com.sun.star.beans.XPropertyContainer</idls><br><br />
<idls>com.sun.star.beans.XPropertySetInfoChangeNotifier</idls><br><br />
<idls>com.sun.star.ucb.XCommandInfoChangeNotifier</idls><br><br />
<idls>com.sun.star.ucb.XContentCreator</idls> <br />
|-<br />
!Folder<br />
|application/vnd.sun.staroffice.ftp-folder <br />
|[readonly] ContentType<br><br />
[readonly] IsDocument<br><br />
[readonly] IsFolder<br><br />
Title<br><br />
[readonly] DateCreated<br><br />
[readonly] DateModified<br><br />
[readonly] FolderCount<br><br />
[readonly] DocumentCount <br />
|getCommandInfo<br><br />
getPropertySetInfo<br><br />
getPropertyValues<br><br />
setPropertyValues<br><br />
insert<br><br />
delete<br><br />
open<br><br />
transfer <br />
|same as FTP Account<br><br />
plus<br><br />
<idls>com.sun.star.container.XChild</idls><br />
|-<br />
!Document<br />
|application/vnd.sun.staroffice.ftp-file <br />
|[readonly] ContentType<br><br />
[readonly] IsDocument<br><br />
[readonly] IsFolder<br><br />
Title<br><br />
[readonly] DateCreated<br><br />
[readonly] DateModified<br><br />
[readonly] IsReadOnly<br><br />
[readonly] Size<br><br />
MediaType <br />
|getCommandInfo<br><br />
getPropertySetInfo<br><br />
getPropertyValues<br><br />
setPropertyValues<br><br />
insert<br><br />
delete<br><br />
open <br />
|same as FTP Folder minus<br><br />
<idls>com.sun.star.ucb.XContentCreator</idls> <br />
|}<br />
<br />
<sup>1</sup> The property <code>FTPAccount</code> is similar to <code>Password</code>. Some FTP servers not only require authentication through a password, but also through a second token called an "account".<br />
<br />
<sup>2</sup> The property <code>ServerBase</code> is used to override the default directory associated with an FTP account.<br />
<br />
<sup>3</sup> The "<code>transfer</code>" command only transfers contents within one FTP Account. It cannot transfer contents between different FTP accounts or between the FTP content provider and another content provider.<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Appendix]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/GUI/Roadmap_ControlDocumentation/DevGuide/GUI/Roadmap Control2015-05-25T09:40:40Z<p>BMarcelly: Inexistent property Activated is replaced by Interactive</p>
<hr />
<div>{{Documentation/DevGuide/GUITOC<br />
|GUI2b=block<br />
|GUIDialogCont=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/GUI/Pattern Field<br />
|NextPage=Documentation/DevGuide/GUI/File Control<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/GUI/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:Roadmap Control}}<br />
The roadmap control that supports the service <idl>com.sun.star.awt.UnoControlRoadmap</idl> is a container of roadmap items supporting <idl>com.sun.star.awt.RoadmapItem</idl>. The roadmap control was designed to give an overview about all existing steps in a dialog as done in all {{PRODUCTNAME}} wizards. The roadmap items are labels with some additional functionality as described later in the text. They are due to give the user a clue about "what is going on" on a certain dialog step. Roadmap items can be programmatically accessed by their respective index using the interface <idls>com.sun.star.container.XIndexContainer</idls> at the roadmap model that is described by <idl>com.sun.star.awt.UnoControlRoadmapModel</idl>. <br />
<br />
==== Roadmap Item ====<br />
<br />
Each roadmap item delivers the following information:<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!colspan="2"|Properties of <idl>com.sun.star.awt.RoadmapItem</idl> <br />
|-<br />
|<idlm>com.sun.star.awt.RoadmapItem:ID</idlm> <br />
|<code>short</code>. The ID uniquely identifies the roadmap item and can be used to refer to the value of a dialog step. <br />
|-<br />
|<idlm>com.sun.star.awt.RoadmapItem:Label</idlm> <br />
|The label of a roadmap item is displayed similar to the label of a fixed text control. Each label is prefixed with an index and a ". ". <br />
|-<br />
|<idlm>com.sun.star.awt.RoadmapItem:Interactive</idlm> <br />
|<code>boolean</code>. Setting <code>Interactive</code> to <code>true</code> will automatically change the mouse pointer to a <code>refhand</code> and underline the label for the time the mouse pointer resides over the roadmap item. Clicking the mouse pointer will then notify the roadmap container. The property <code>Interactive</code> is readonly because it is adapted from the container of the roadmap item, the roadmap model. When the user clicks on the roadmap item of an interactive roadmap the ID of the triggered roadmap item automatically gets selected - similarly to the selection of a list box item. Automatically the property <code>CurrentItemID</code> of the roadmap model is set to the value of the property <code>ID</code> of the roadmap item element. <br />
|-<br />
|<idlm>com.sun.star.awt.RoadmapItem:Enabled</idlm> <br />
|<code>boolean</code>. Determines whether a roadmap item is enabled or disabled. As roadmap items usually refer to a dialog step they are disabled when the the actions taking place on that step have become unnecessary for example because of user input. <br />
|}<br />
<br />
==== Roadmap Controlmodel ====<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!colspan="2"|Properties of <idl>com.sun.star.awt.UnoControlRoadmapModel</idl> <br />
|-<br />
|<idlm>com.sun.star.awt.UnoControlRoadmapModel:BackgroundColor</idlm> <br />
|<code>long</code>. Specifies the background color (RGB) of the control. The Default value is white. <br />
|-<br />
|<idlm>com.sun.star.awt.UnoControlRoadmapModel:Interactive</idlm><br />
|<code>boolean</code>. Determines whether the roadmap items are interactive or not. To have an interactive roadmap may demand some extra implementation work because the developer will then be responsible to check if for each roadmap item the necessary prerequisites are fulfilled to allow the user to enter the respective dialog step. <br />
|-<br />
|<idlm>com.sun.star.awt.UnoControlRoadmapModel:Complete</idlm> <br />
|<code>boolean</code>. Determines whether the control container is complete or not. It might occur that the exact roadmap of an assistant is not clear from the beginning because it contains one or several branches where the input of the user impacts the content of the roadmap. If it is unclear how the roadmap is moving on after a branch the following step after the branch is visualized with "<code>...</code>". In this case the property <code>Complete</code> is previously set to <code>false</code>. The steps afterwards are unavailable as long as the state of this branch is uncertain. <br />
|-<br />
|<idlm>com.sun.star.awt.UnoControlRoadmapModel:ImageURL</idlm> <br />
|<code>string</code>. Refers to an image that is displayed in the bottom right corner of the roadmap. The image is meant to contain a metaphor that can easily be associated with the task of the wizard or the subtask of an according step. <br />
|-<br />
|<idlm>com.sun.star.awt.UnoControlRoadmapModel:Text</idlm> <br />
|<code>string</code>. Specifies the bold and underlined text displayed in the top of the control <br />
|-<br />
|<idlm>com.sun.star.awt.UnoControlRoadmapModel:CurrentItemID</idlm> <br />
|<code>short</code>. Refers to the ID of the currently selected roadmap item. Initially this property is set to '-1' which is equal to 'undefined. <br />
|}<br />
<br />
==== Roadmap ====<br />
<br />
Specifies a Roadmap control. A roadmap implements the interface <idl>com.sun.star.awt.XItemEventBroadcaster</idl>, which is helpful to add an <code>ItemListener</code> to the roadmap, when the property <code>Interactive</code> of the roadmap model is set to <code>true</code>. The listener is then always notified about changes of the property <code>CurrentItemID</code> and has an opportunity to adjust the property Step of the dialog. <br />
<br />
The following example listings are supposed to give an idea how a roadmap can be used to control the displayed steps of a dialog:<br />
<source lang="java"><br />
// Globally available object variables of the roadmapmodel<br />
XPropertySet m_xRMPSet; <br />
XSingleServiceFactory m_xSSFRoadmap;<br />
XIndexContainer m_xRMIndexCont;<br />
<br />
public void addRoadmap(XItemListener _xItemListener) {<br />
try {<br />
// create a unique name by means of an own implementation...<br />
String sRoadmapName = createUniqueName(m_xDlgModelNameContainer, "Roadmap");<br />
<br />
XPropertySet xDialogModelPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, m_xMSFDialogModel); <br />
// Similar to the office assistants the roadmap is adjusted to the height of the dialog<br />
// where a certain space is left at the bottom for the buttons...<br />
int nDialogHeight = ((Integer) xDialogModelPropertySet.getPropertyValue("Height")).intValue();<br />
<br />
// instantiate the roadmapmodel...<br />
Object oRoadmapModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlRoadmapModel");<br />
<br />
// define the properties of the roadmapmodel<br />
XMultiPropertySet xRMMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oRoadmapModel);<br />
xRMMPSet.setPropertyValues( new String[] {"Complete", "Height", "Name", "PositionX", "PositionY", "Text", "Width" },<br />
new Object[] {Boolean.FALSE, new Integer(nDialogHeight - 26), sRoadmapName, new Integer(0), new Integer(0), "Steps", new Integer(85)});<br />
m_xRMPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, oRoadmapModel);<br />
<br />
// add the roadmapmodel to the dialog container..<br />
m_xDlgModelNameContainer.insertByName(sRoadmapName, oRoadmapModel); <br />
<br />
// the roadmapmodel is a SingleServiceFactory to instantiate the roadmapitems...<br />
m_xSSFRoadmap = (XSingleServiceFactory) UnoRuntime.queryInterface(XSingleServiceFactory.class, oRoadmapModel);<br />
m_xRMIndexCont = (XIndexContainer) UnoRuntime.queryInterface(XIndexContainer.class, oRoadmapModel); <br />
<br />
// add the itemlistener to the control...<br />
XControl xRMControl = this.m_xDlgContainer.getControl(sRoadmapName);<br />
XItemEventBroadcaster xRMBroadcaster = (XItemEventBroadcaster) UnoRuntime.queryInterface(XItemEventBroadcaster.class, xRMControl);<br />
xRMBroadcaster.addItemListener(new RoadmapItemStateChangeListener()); //_xItemListener); <br />
} catch (java.lang.Exception jexception) {<br />
jexception.printStackTrace(System.out);<br />
}}<br />
</source><br />
The following code snippet inserts a roadmap item into the roadmap control model. <br />
<source lang="java"><br />
/**<br />
* To fully understand the example one has to be aware that the passed "Index" parameter <br />
* refers to the position of the roadmap item in the roadmapmodel container <br />
* whereas the variable "_ID" directly references to a certain step of dialog.<br />
*/<br />
public void insertRoadmapItem(int Index, boolean _bEnabled, String _sLabel, int _ID) {<br />
try {<br />
// a roadmap is a SingleServiceFactory that can only create roadmapitems that are the only possible<br />
// element types of the container<br />
Object oRoadmapItem = m_xSSFRoadmap.createInstance();<br />
XPropertySet xRMItemPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, oRoadmapItem);<br />
xRMItemPSet.setPropertyValue("Label", _sLabel);<br />
// sometimes steps are supposed to be set disabled depending on the program logic...<br />
xRMItemPSet.setPropertyValue("Enabled", new Boolean(_bEnabled));<br />
// in this context the "ID" is meant to refer to a step of the dialog<br />
xRMItemPSet.setPropertyValue("ID", new Integer(_ID));<br />
m_xRMIndexCont.insertByIndex(Index, oRoadmapItem);<br />
} catch (com.sun.star.uno.Exception exception) {<br />
exception.printStackTrace(System.out);<br />
}}<br />
</source><br />
The following example demonstrates the way an <code>ItemListener</code> could evaluate the information of the roadmap control to adjust the step of the dialog:<br />
<source lang="java"><br />
public void itemStateChanged(com.sun.star.awt.ItemEvent itemEvent) {<br />
try {<br />
// get the new ID of the roadmap that is supposed to refer to the new step of the dialogmodel<br />
int nNewID = itemEvent.ItemId;<br />
XPropertySet xDialogModelPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, m_xMSFDialogModel); <br />
int nOldStep = ((Integer) xDialogModelPropertySet.getPropertyValue("Step")).intValue();<br />
// in the following line "ID" and "Step" are mixed together.<br />
// In fact in this case they denot the same<br />
if (nNewID != nOldStep){<br />
xDialogModelPropertySet.setPropertyValue("Step", new Integer(nNewID));<br />
}<br />
} catch (com.sun.star.uno.Exception exception) {<br />
exception.printStackTrace(System.out);<br />
}}<br />
<br />
</source><br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Graphical User Interfaces]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/GUI/Property_Propagation_Between_Model_and_ControlDocumentation/DevGuide/GUI/Property Propagation Between Model and Control2015-05-25T07:44:55Z<p>BMarcelly: Suppressed Table Align Left that causes copy problems</p>
<hr />
<div>{{Documentation/DevGuide/GUITOC<br />
|GUI2b=block<br />
|GUIDialogCont=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/GUI/Other Common Properties<br />
|NextPage=Documentation/DevGuide/GUI/Common Workflow to add Controls<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/GUI/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:Property Propagation Between Model and Control}}<br />
One particularity in the relationship of UNO controls and their models must be considered. Following the principles of the MVC paradigm all changes applied to the control model are directly propagated to the control and (its peer object). However, conversely ''not all'' changes applied to the control will notify the model. The general rule is that whenever an attribute of a control is ''modifiable by the user'', a change of this attribute is also propagated to the model. The following table sums up all methods which invocation at UNO controls is propagated to the respective control model. The controls and interfaces are described in detail in the following sections.<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!Control Service Name in module com.sun.star.awt <br />
!Interface in <idlmodule>com.sun.star.awt</idlmodule> <br />
!Method Name <br />
!Model Service in <idlmodule>com.sun.star.awt</idlmodule> <br />
!Affected Property at the model <br />
|-<br />
|UnoControlCheckBox <br />
|XCheckBox <br />
|[set|get]State <br />
|UnoControlCheckBoxModel <br />
|State <br />
|-<br />
|UnoControlRadioButton <br />
|XRadioButton <br />
|[set|get]State <br />
|UnoControlRadioButtonModel <br />
|State <br />
|-<br />
|UnoControlScrollBar <br />
|XScrollBar <br />
|[set|get]Value <br />
|UnoControlScrollBarModel <br />
|ScrollValue <br />
|-<br />
|UnoControlComboBox <br />
|XComboBox <br />
|[set|get]Item[s], add/removeItem <br />
|UnoControlComboBoxModel <br />
|Text, StringItemList <br />
|-<br />
|UnoControlListBox <br />
|XListBox <br />
|[set|get]Item[s], [add|remove]Item,<br />
<br />
selectItem, selectItemPos() <br />
|UnoControlListBoxModel <br />
|StringItemList*,<br />
<br />
SelectedItems <br />
|-<br />
|UnoControlEdit <br />
|XTextComponent <br />
|[set|get]Text; <br />
|UnoControlEditModel <br />
|Text <br />
|-<br />
|UnoControlCurrencyField <br />
|XCurrencyField<br />
<br />
XTextComponent <br />
|[set|get]Value,<br />
<br />
[set|get]Text <br />
|UnoControlCurrencyModel <br />
|Value <br />
|-<br />
|UnoControlDateField <br />
|XDateField<br />
<br />
XTextComponent <br />
|[set|get]Date,<br />
<br />
[set|get]Text <br />
|UnoControlDateModel <br />
|Date <br />
|-<br />
|UnoControlTimeField <br />
|XTimeField<br />
<br />
XTextComponent <br />
|[set|get]Time,<br />
<br />
[set|get]Text <br />
|UnoControlTimeModel <br />
|Time <br />
|-<br />
|UnoControlNumericField <br />
|XNumericField<br />
<br />
XTextComponent <br />
|[set|get]Value<br />
<br />
[set|get]Text <br />
|UnoControlNumericFieldModel <br />
|Value <br />
|-<br />
|UnoControlPatternField <br />
|XPatternField<br />
<br />
XTextComponent <br />
|[set|get]String,<br />
<br />
[set|get]Text <br />
|UnoControlPatternFieldModel <br />
|Text <br />
|}<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Graphical User Interfaces]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/Accessibility/XAccessibleImageDocumentation/DevGuide/Accessibility/XAccessibleImage2015-05-25T06:46:02Z<p>BMarcelly: </p>
<hr />
<div>{{Documentation/DevGuide/AccessibilityTOC<br />
|Accessibility2a=block<br />
|Accessibility2b=block<br />
|Accessibility2c=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/Accessibility/XAccessibleValue<br />
|NextPage=Documentation/DevGuide/Accessibility/XAccessibleAction<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/Accessibility/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:XAccessibleImage}}<br />
<!--<idltopic>com.sun.star.accessibility.XAccessibleImage</idltopic>--><br />
The main purpose of the <idls>com.sun.star.accessibility.XAccessibleImage</idls> interface is to be an indicator that an object represents an image or a bitmap. The functions of this interface do not add functionality that is not already present in the <idl>com.sun.star.accessibility.XAccessibleContext</idl> interface.<br />
<br />
The <idlm>com.sun.star.accessibility.XAccessibleImage:getAccessibleImageDescription</idlm>() function returns a localized description of the image. The functions <idlm>com.sun.star.accessibility.XAccessibleImage:getAccessibleImageHeight</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleImage:getAccessibleImageWidth</idlm>() return the size of the image in pixels.<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Accessibility]]</div>BMarcellyhttps://wiki.openoffice.org/wiki/Documentation/DevGuide/Database/XDatabaseMetaData_InterfaceDocumentation/DevGuide/Database/XDatabaseMetaData Interface2015-05-24T16:01:00Z<p>BMarcelly: Table Align Left was disturbing display</p>
<hr />
<div>{{Documentation/DevGuide/DatabaseTOC<br />
|Database2f=block<br />
|ShowPrevNext=block<br />
|PrevPage=Documentation/DevGuide/Database/Connection Service<br />
|NextPage=Documentation/DevGuide/Database/Driver Statements<br />
}}<br />
{{Documentation/DevGuideLanguages|Documentation/DevGuide/Database/{{SUBPAGENAME}}}} <br />
{{DISPLAYTITLE:XDatabaseMetaData Interface}}<br />
<!--<idltopic>com.sun.star.sdbc.XDatabaseMetaData</idltopic>--><br />
The <idl>com.sun.star.sdbc.XDatabaseMetaData</idl> interface is the largest interface existing in the SDBC API. This interface knows everything about the used database. It provides information, such as the available tables with their columns, keys and indexes, and information about identifiers that should be used. This chapter explains some of the methods that are frequently used and how they are used to achieve a robust Driver.<br />
<br />
{|border="1" cellpadding=4 style="border-collapse:collapse;"<br />
|-bgcolor=#EDEDED<br />
!colspan="2"|Important Methods of <idl>com.sun.star.sdbc.XDatabaseMetaData</idl> <br />
|-<br />
|<idlm>com.sun.star.sdbc.XDatabaseMetaData:isReadOnly</idlm>() <br />
|Returns the state of the database. When true, the database is not editable later in {{PRODUCTNAME}} API. <br />
|-<br />
|<idlm>com.sun.star.sdbc.XDatabaseMetaData:usesLocalFiles</idlm>() <br />
|Returns true when the catalog name of the database should not appear in the DatasourceBrowser of {{PRODUCTNAME}} API, otherwise false is returned. <br />
|-<br />
|<idlm>com.sun.star.sdbc.XDatabaseMetaData:supportsMixedCaseQuotedIdentifiers</idlm>() <br />
|When this method returns true,the quoted identifiers are case sensitive. For example, in a driver that supports mixed case quoted identifiers, SELECT * FROM "MyTable" retrieves data from a table with the case-sensitive name MyTable. <br />
|-<br />
|<idlm>com.sun.star.sdbc.XDatabaseMetaData:getTables</idlm>() <br />
|Returns a <code>ResultSet</code> object that returns a single row for each table that fits the search criteria, such as the catalog name, schema pattern, table name pattern and sequence of table types. The correct column count and names of the columns are found at [http://api.openoffice.org/docs/common/ref/com/sun/star/sdbc/XDatabaseMetaData.html#getTables com.sun.star.sdbc.XDatabaseMetaData:getTables](). If this method does not return any rows, this driver does not work with {{PRODUCTNAME}} API. <br />
|}<br />
<br />
Any other <code>getXXX()</code> method can be implemented step by step. For the the first step they return an empty <code>ResultSet</code> object that contains no rows. It is not allowed to return NULL here.<br />
<br />
The skeleton driver defines empty ResultSets for these get methods. <br />
<!--[SOURCE:Database/DriverSkeleton/SDriver.cxx]--><br />
<br />
Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTables( <br />
const Any& catalog, const ::rtl::OUString& schemaPattern, <br />
const ::rtl::OUString& tableNamePattern, const Sequence< ::rtl::OUString >& types ) <br />
throw(SQLException, RuntimeException)<br />
{<br />
// this returns an empty resultset where the column-names are already set<br />
// in special the metadata of the resultset already returns the right columns<br />
ODatabaseMetaDataResultSet* pResultSet = new ODatabaseMetaDataResultSet();<br />
Reference< XResultSet > xResultSet = pResultSet;<br />
pResultSet->setTablesMap();<br />
return xResultSet;<br />
}<br />
<br />
{{PDL1}}<br />
<br />
[[Category:Documentation/Developer's Guide/Database Access]]</div>BMarcelly