Difference between revisions of "Constructing Helpers"
SergeMoutou (Talk | contribs) m (→Presentation) |
SergeMoutou (Talk | contribs) m (→Presentation) |
||
Line 318: | Line 318: | ||
== Presentation == | == Presentation == | ||
− | The reflection helper goal is to provide Object informations on methods, interfaces, services and properties. | + | The reflection helper goal is to provide Object informations on methods, interfaces, services and properties. Have a look : |
+ | * in to [[SDKCppLanguage#Sequences|Sequences]], [[SDKCppLanguage#Any|Any]], [[SDKCppLanguage#To_go_further_:_the_Constant_Type_Problem|UNO constants in C++]] [[SDKCppLanguage#To_go_further_:_the_Enumeration_Type_Problem|UNO enumeration]] in this document | ||
+ | * in to 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> | ||
+ | * in to the following UNO constants <idl>com.sun.star.beans.MethodConcept</idl>, <idl>com.sun.star.beans.PropertyConcept</idl> | ||
+ | * in to the following UNO struct <idl>com.sun.star.beans.Property</idl> | ||
+ | * in to the following UNO Enumeration <idl>com.sun.star.reflection.ParamMode</idl>. | ||
We begin to give the ReflectionHelper.hpp file : | We begin to give the ReflectionHelper.hpp file : |
Revision as of 09:12, 11 April 2009
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.
Contents
Desktop Helper
The GAP's Helper
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 :
//Listing 1 Gap helper // C++ // SimpleOOConection.hpp #ifndef SIMPLEOOCONNECTION_HPP_ #define SIMPLEOOCONNECTION_HPP_ #endif #include<iostream> #include <cppuhelper/bootstrap.hxx> #include <com/sun/star/bridge/XUnoUrlResolver.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> using namespace std; using namespace com::sun::star::uno; using namespace com::sun::star::lang; using namespace com::sun::star::bridge; using namespace rtl; using namespace cppu; class SimpleOOConnection { public : SimpleOOConnection(); Reference< XMultiServiceFactory > connect_ooffice(const char *url); private : int iNoOfConnection_; };
This code use com.sun.star.bridge.XUnoUrlResolver and com.sun.star.lang.XMultiServiceFactory interfaces.
And now the implementation file :
//Listing 2 // C++ #include "SimpleOOConnection.hpp" // int SimpleOOConnection::iNoOfConnection_=0; SimpleOOConnection::SimpleOOConnection() { iNoOfConnection_++; } Reference< XMultiServiceFactory > SimpleOOConnection::connect_ooffice(const char *url) { // create the initial component context cout<<endl; cout<<url<<"HI"<<endl; //Initiating Local Component Context Reference< XComponentContext > rComponentContext = defaultBootstrap_InitialComponentContext(); /** * This local Context contents small Service Manager tha konws how to create services that are neccessary to talk to other * component context.One such service is com.sun.star.bridge.UnoUrlResolver So it ask local Service Manager to create this * service. */ // retrieve the Local Service Manager from the Local context i.e We get Just servicemanager here Reference< XMultiComponentFactory > rServiceManager = rComponentContext->getServiceManager(); // here we instantiate a sample service with the service com.sun.star.bridge.UnoUrlResolver . Created by local service manager. Reference< XInterface > rInstance = rServiceManager->createInstanceWithContext( OUString::createFromAscii("com.sun.star.bridge.UnoUrlResolver" ),rComponentContext ); // Query for the XUnoUrlResolver interface fro sample service Reference< XUnoUrlResolver > rResolver( rInstance, UNO_QUERY ); //Now it uses UnoUrlResolver to get component context together with service manager from server side try { // resolve the uno-url rInstance = rResolver->resolve( OUString::createFromAscii(url ) ); // query for the simpler XMultiServiceFactory interface, sufficient for scripting Reference< XMultiServiceFactory > rOfficeServiceManager (rInstance, UNO_QUERY); return(rOfficeServiceManager); } catch( Exception &e ) { OString o = OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ); printf( "Error: %s\n", o.pData->buffer ); return('\0'); } }
where service com.sun.star.bridge.UnoUrlResolver is used.
Simple Desktop Helper
The snippet below uses com.sun.star.uno.XInterface, com.sun.star.frame.XComponentLoader, com.sun.star.lang.XMultiServiceFactory and com/sun/star/frame/XDesktop interfaces and also com.sun.star.frame.Desktop and com.sun.star.bridge.UnoUrlResolver services.
We first give the header file :
//Listing 3 Header file of the desktop helper // C++ //********* DesktopHelper class : header DesktopHelper.hpp #include <com/sun/star/uno/XInterface.hpp> #include <com/sun/star/frame/XComponentLoader.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/frame/XDesktop.hpp> using namespace com::sun::star::uno; using namespace com::sun::star::frame; using namespace com::sun::star::lang; class DesktopHelper { public : DesktopHelper(); Reference< XInterface > Desktop; Reference< XComponentLoader > xComponentLoader; Reference< XMultiServiceFactory > xSVMG; Reference< XDesktop > xDesktop; private : Reference< XMultiServiceFactory > ooConnect(); };
and the corresponding implementation :
//Listing 4 Desktop helper implementation // C++ //****** DesktopHelper class : implementation DesktopHelper.cxx #include <stdio.h> #include <com/sun/star/bridge/XUnoUrlResolver.hpp> #include <cppuhelper/bootstrap.hxx> using namespace com::sun::star::bridge; using rtl::OUString; using rtl::OString; using namespace cppu; DesktopHelper::DesktopHelper(){ xSVMG = ooConnect(); if( xSVMG.is() ){ printf( "Connected sucessfully to the office\n" ); } //get the desktop service using createInstance returns an XInterface type Reference< XInterface > Desktop = xSVMG->createInstance( OUString::createFromAscii( "com.sun.star.frame.Desktop" )); //query for the XComponentLoader interface xComponentLoader = Reference< XComponentLoader > (Desktop, UNO_QUERY); if( xComponentLoader.is() ){ printf( "XComponentloader successfully instanciated\n" ); } xDesktop = Reference< XDesktop > (Desktop,UNO_QUERY); } Reference< XMultiServiceFactory > DesktopHelper::ooConnect(){ // create the initial component context Reference< XComponentContext > rComponentContext = defaultBootstrap_InitialComponentContext(); // retrieve the servicemanager from the context Reference< XMultiComponentFactory > rServiceManager = rComponentContext->getServiceManager(); // instantiate a sample service with the servicemanager. Reference< XInterface > rInstance = rServiceManager->createInstanceWithContext( OUString::createFromAscii("com.sun.star.bridge.UnoUrlResolver" ),rComponentContext ); // Query for the XUnoUrlResolver interface Reference< XUnoUrlResolver > rResolver( rInstance, UNO_QUERY ); if( ! rResolver.is() ){ printf( "Error: Couldn't instantiate com.sun.star.bridge.UnoUrlResolver service\n" ); return NULL; } try { // resolve the uno-url rInstance = rResolver->resolve( OUString::createFromAscii( "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" ) ); if( ! rInstance.is() ){ printf( "StarOffice.ServiceManager is not exported from remote counterpart\n" ); return NULL; } // query for the simpler XMultiServiceFactory interface, sufficient for scripting Reference< XMultiServiceFactory > rOfficeServiceManager (rInstance, UNO_QUERY); if( ! rOfficeServiceManager.is() ){ printf( "XMultiServiceFactory interface is not exported for StarOffice.ServiceManager\n" ); return NULL; } return rOfficeServiceManager; } catch( Exception &e ){ OString o = OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ); printf( "Error: %s\n", o.pData->buffer ); return NULL; } return NULL; }
Desktop Helper with message box
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. Have a look in the corresponding interfaces : com.sun.star.uno.XInterface, com.sun.star.frame.XComponentLoader, com.sun.star.lang.XMultiServiceFactory, com.sun.star.frame.XDesktop, com.sun.star.awt.XToolkit before starting to read the code. It is also important to have look here where the mesage box is described.
The new class definition is :
//Listing 5 A second desktop helper (header file) // C++ //********* DesktopHelper class : header DesktopHelper.hpp #include <com/sun/star/uno/XInterface.hpp> #include <com/sun/star/frame/XComponentLoader.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/frame/XDesktop.hpp> #include <com/sun/star/awt/XToolkit.hpp> using namespace com::sun::star::uno; using namespace com::sun::star::frame; using namespace com::sun::star::lang; using namespace com::sun::star::awt; class DesktopHelper { public : DesktopHelper(); void ShowMessageBox( const OUString& aTitle, const OUString& aMsgText ); Reference< XInterface > Desktop; Reference< XComponentLoader > xComponentLoader; Reference< XMultiServiceFactory > xSVMG; Reference< XDesktop > xDesktop; sal_Int16 endMsgbox; private : Reference< XMultiServiceFactory > ooConnect(); sal_Bool useMsgbox; Reference< XToolkit > xToolkit; Reference< XFrame > xFrame; };
and the new constructor :
//Listing 6 A second desktop helper (implementation file) // C++ DesktopHelper::DesktopHelper(){ useMsgbox = false; endMsgbox = 0; xSVMG = ooConnect(); if( xSVMG.is() ){ printf( "Connected sucessfully to the office\n" ); } //get the desktop service using createInstance returns an XInterface type Reference< XInterface > Desktop = xSVMG->createInstance( OUString::createFromAscii( "com.sun.star.frame.Desktop" )); //query for the XComponentLoader interface xComponentLoader = Reference< XComponentLoader > (Desktop, UNO_QUERY); if( xComponentLoader.is() ){ printf( "XComponentloader successfully instanciated\n" ); } xDesktop = Reference< XDesktop > (Desktop,UNO_QUERY); xToolkit = Reference< XToolkit >( xSVMG->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.Toolkit" ))), UNO_QUERY ); xFrame = xDesktop->getCurrentFrame(); if (xFrame.is() && xToolkit.is()) useMsgbox = true; }
The method to print out a message is :
//Listing 7 ShowMessageBox function (XMessageBox interface is deprecated) // C++ void DesktopHelper::ShowMessageBox( const OUString& aTitle, const OUString& aMsgText ) { if ( useMsgbox ) { // describe window properties. WindowDescriptor aDescriptor; aDescriptor.Type = WindowClass_MODALTOP; aDescriptor.WindowServiceName = OUString( RTL_CONSTASCII_USTRINGPARAM( "infobox" )); aDescriptor.ParentIndex = -1; aDescriptor.Parent = Reference< XWindowPeer > (xFrame->getContainerWindow(), UNO_QUERY ); aDescriptor.Bounds = Rectangle(300,200,300,200); aDescriptor.WindowAttributes = WindowAttribute::BORDER | WindowAttribute::MOVEABLE | WindowAttribute::CLOSEABLE; Reference< XWindowPeer > xPeer = xToolkit->createWindow( aDescriptor ); if ( xPeer.is() ) { Reference< XMessageBox > xMsgBox( xPeer, UNO_QUERY ); if ( xMsgBox.is() ) { xMsgBox->setCaptionText( aTitle ); xMsgBox->setMessageText( aMsgText ); endMsgbox = xMsgBox->execute(); } } } // else would be good to use cout }
The way to use this new feature is shown in the above listing :
//Listing 8 Using the Desktop Helper // C++ DesktopHelper *aDesktop = new (DesktopHelper); aDesktop->ShowMessageBox( OUString::createFromAscii("try"), OUString::createFromAscii("Hello")); while (! aDesktop->endMsgbox); printf("That's all folks !\n");
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.
Reflection Helper
Presentation
The reflection helper goal is to provide Object informations on methods, interfaces, services and properties. Have a look :
- in to Sequences, Any, UNO constants in C++ UNO enumeration in this document
- in to following interfaces com.sun.star.lang.XMultiServiceFactory, com.sun.star.beans.XIntrospection, com.sun.star.beans.XIntrospectionAccess, com.sun.star.lang.XTypeProvider, com.sun.star.reflection.XIdlMethod, com.sun.star.lang.XServiceInfo
- in to the following UNO constants com.sun.star.beans.MethodConcept, com.sun.star.beans.PropertyConcept
- in to the following UNO struct com.sun.star.beans.Property
- in to the following UNO Enumeration com.sun.star.reflection.ParamMode.
We begin to give the ReflectionHelper.hpp file :
//Listing 11 Header file for reflection helper // C++ // ReflectionHelper.hpp #include <rtl/ustring.hxx> #include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/uno/Any.hxx> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/beans/XIntrospection.hpp> #include <com/sun/star/beans/XIntrospectionAccess.hpp> #include <com/sun/star/lang/XTypeProvider.hpp> #include <com/sun/star/beans/MethodConcept.hpp> #include <com/sun/star/reflection/XIdlMethod.hpp> #include <com/sun/star/uno/Type.hxx> #include <com/sun/star/beans/Property.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/reflection/ParamMode.hpp> using rtl::OUString; using namespace com::sun::star::reflection; using namespace com::sun::star::beans; using namespace com::sun::star::lang; using namespace com::sun::star::uno; class ReflectionHelper { public: ReflectionHelper(Any any,Reference< XMultiServiceFactory > oSVM); Sequence < OUString > getMethods(), getTypes(), getServices(), getPropertiesWithoutValues(), getPropertiesWithValues(); private: Any toInspect; Reference< XMultiServiceFactory > xServiceManager; Reference< XIntrospection >xIntrospection; Reference< XIntrospectionAccess > xIntrospec; Reference< XTypeProvider > xTypeProvider; OUString getValueName(Any object); OUString getParamMode(ParamMode paramMode); // methods Sequence< Reference< XIdlMethod > > mMethods; // Interfaces Sequence< Type > types; // Services Reference< XServiceInfo > xServiceInfo; // Sequence< OUString > services; // Properties Sequence< Property > Properties; };
You can find the complete class implementation here in lising 14
Application
A simple utilisation could be :
//Listing 13 // C++ Any toInspect; // I want to inspect rDesktop object : toInspect <<= rDesktop; // need a service manager ReflectionHelper *Reflect = new (ReflectionHelper)(toInspect,rServiceManager); // get all the methods Sequence< OUString > mMethods = Reflect -> getMethods(); printf("******** methods : (%d)\n",mMethods.getLength()); for (int i=0;i<mMethods.getLength();i++){ // do what you want with mMethods[i] : for instance OString OStr = OUStringToOString( mMethods[i], RTL_TEXTENCODING_ASCII_US ); printf("%s\n",OStr.pData->buffer ); }
It's the great values of helpers : they make code simpler and more easy to read.
Printing out Reflection's Results in a Dialog
A fast way of printing out results would be a Dialog and the goal of this chapter is to speak from this topic.
hpp File of the Complete Class
We present again the complete class :
//Listing 15 // C++ // ReflectionHelper.hpp class ReflectionHelper { public: ReflectionHelper(Any any,Reference< XMultiServiceFactory > oSVM); Sequence < OUString > getMethods(), getTypes(), getServices(), getPropertiesWithoutValues(), getPropertiesWithValues(); // Print out void printOut(); private: Any toInspect; Reference< XMultiServiceFactory > xServiceManager; Reference< XIntrospection >xIntrospection; Reference< XIntrospectionAccess > xIntrospec; Reference< XTypeProvider > xTypeProvider; OUString getValueName(Any object); OUString getParamMode(ParamMode paramMode); // methods Sequence< Reference< XIdlMethod > > mMethods; // Interfaces Sequence< Type > types; // Services Reference< XServiceInfo > xServiceInfo; // Sequence< OUString > services; // Properties Sequence< Property > Properties; };
A new method is added : printOut which know how to print results in a run time dialog box.
New Implementation Code
The corresponding implementation's code is now given. Notice the reference of listing 14 in the code. Here is a direct link into the corresponding listing 14.
//Listing 16 // C++ // constructor ReflectionHelper::ReflectionHelper(Any any,Reference< XMultiServiceFactory > oSVM) : toInspect(any), xServiceManager(oSVM){ xIntrospection = Reference< XIntrospection >( xServiceManager->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.beans.Introspection" ))), UNO_QUERY ); xIntrospec = xIntrospection->inspect(toInspect); mMethods = xIntrospec -> getMethods(MethodConcept::ALL); xTypeProvider = Reference< XTypeProvider> (toInspect,UNO_QUERY); types = xTypeProvider->getTypes(); xServiceInfo = Reference< XServiceInfo>(toInspect,UNO_QUERY); Properties = xIntrospec -> getProperties(PropertyConcept::ALL); } Sequence < OUString > ReflectionHelper::getServices() { return xServiceInfo->getSupportedServiceNames(); } Sequence < OUString > ReflectionHelper::getMethods(){ // See Listing 14 to find the corresponding code. } Sequence < OUString > ReflectionHelper::getTypes(){ // See Listing 14 to find the corresponding code. } // to improve : change all the tests with getCppuType : probably quicker than a string test OUString ReflectionHelper::getValueName(Any object){ // See Listing 14 to find the corresponding code. } // Get properties with values : only those computed in getValueName Sequence < OUString > ReflectionHelper::getPropertiesWithValues(){ // See Listing 14 to find the corresponding code. } // Get properties without values but types Sequence < OUString > ReflectionHelper::getPropertiesWithoutValues(){ // See Listing 14 to find the corresponding code. } // Don't forget to add : #include <com/sun/star/reflection/ParamMode.hpp> // Don't forget to add "com.sun.star.reflection.ParamMode \" in the makefile OUString ReflectionHelper::getParamMode(ParamMode paramMode) { // See Listing 14 to find the corresponding code. } void ReflectionHelper::printOut(){ Reference< XInterface > xdialogModel = xServiceManager->createInstance( OUString::createFromAscii("com.sun.star.awt.UnoControlDialogModel")); #ifdef DEBUG if (xdialogModel.is()) printf("OK XDialogModel\n"); else printf("Error ... XDialodModel\n"); #endif Any val; Reference< XPropertySet > xPSetDialog(xdialogModel,UNO_QUERY); #ifdef DEBUG if (xPSetDialog.is()) printf("OK XPropertySet\n"); else printf("Error ... XPropertySet\n"); #endif sal_Int32 value=100; val<<=value; xPSetDialog->setPropertyValue(OUString::createFromAscii("PositionX"),val); xPSetDialog->setPropertyValue(OUString::createFromAscii("PositionY"),val); value=300;val<<=value; xPSetDialog->setPropertyValue(OUString::createFromAscii("Width"),val); value=200;val<<=value; xPSetDialog->setPropertyValue(OUString::createFromAscii("Height"),val); val <<=OUString::createFromAscii("Runtime Dialog Demo"); xPSetDialog->setPropertyValue(OUString::createFromAscii("Title"),val); Reference< XMultiServiceFactory > xMultiServiceFactory( xdialogModel,UNO_QUERY); ///***************** //******** in the above line xMultiServiceFactory instead xServiceManager !!!!!! //Reference< XInterface > xbuttonModel = xServiceManager>createInstance( .... Reference< XInterface > xbuttonModel = xMultiServiceFactory->createInstance( OUString::createFromAscii("com.sun.star.awt.UnoControlButtonModel")); #ifdef DEBUG if (xbuttonModel.is()) printf("OK UnoControlButtonModel\n"); else printf("Error ... UnoControlButtonModel\n"); #endif Reference< XPropertySet > xPSetButton(xbuttonModel,UNO_QUERY); #ifdef DEBUG if (xPSetButton.is()) printf("OK XPropertySet\n"); else printf("Error ... XPropertySet\n"); #endif value=20; val <<= value; xPSetButton->setPropertyValue(OUString::createFromAscii("PositionX"),val); value=170; val <<= value; xPSetButton->setPropertyValue(OUString::createFromAscii("PositionY"),val); value=50; val <<= value; xPSetButton->setPropertyValue(OUString::createFromAscii("Width"),val); value=14; val <<= value; xPSetButton->setPropertyValue(OUString::createFromAscii("Height"),val); val <<=OUString::createFromAscii("Button1"); xPSetButton->setPropertyValue(OUString::createFromAscii("Name"),val); xPSetButton->setPropertyValue(OUString::createFromAscii("TabIndex"),makeAny((short)0)); val <<=OUString::createFromAscii(">>"); xPSetButton->setPropertyValue(OUString::createFromAscii("Label"),val); // second button : OK button // we need a second button modedl Reference< XInterface > xbuttonModel2 = xMultiServiceFactory->createInstance( OUString::createFromAscii("com.sun.star.awt.UnoControlButtonModel")); #ifdef DEBUG if (xbuttonModel.is()) printf("OK UnoControlButtonModel\n"); else printf("Error ... UnoControlButtonModel\n"); #endif Reference< XPropertySet > xPSetButton2(xbuttonModel2,UNO_QUERY); #ifdef DEBUG if (xPSetButton2.is()) printf("OK XPropertySet\n"); else printf("Error ... XPropertySet\n"); #endif // *** The following property is not position-independant !!!!! // Don't forget to add : #include <com/sun/star/awt/PushButtonType.hpp> // Don't forget to add "com.sun.star.awt.PushButtonType \" in the makefile // short is found with Inspector val <<= (short)PushButtonType_OK; xPSetButton2->setPropertyValue(OUString::createFromAscii("PushButtonType"),val); value=220; val <<= value; xPSetButton2->setPropertyValue(OUString::createFromAscii("PositionX"),val); value=170; val <<= value; xPSetButton2->setPropertyValue(OUString::createFromAscii("PositionY"),val); value=50; val <<= value; xPSetButton2->setPropertyValue(OUString::createFromAscii("Width"),val); value=14; val <<= value; xPSetButton2->setPropertyValue(OUString::createFromAscii("Height"),val); val <<=OUString::createFromAscii("Button2"); xPSetButton2->setPropertyValue(OUString::createFromAscii("Name"),val); xPSetButton2->setPropertyValue(OUString::createFromAscii("TabIndex"),makeAny((short)1)); val <<=OUString::createFromAscii("OK"); xPSetButton2->setPropertyValue(OUString::createFromAscii("Label"),val); Reference< XInterface > xlabelModel = xMultiServiceFactory->createInstance( OUString::createFromAscii("com.sun.star.awt.UnoControlEditModel")); #ifdef DEBUG if (xlabelModel.is()) printf("OK EditModel\n"); else printf("Error ... EditModel\n"); #endif Reference< XPropertySet > xPSetLabel(xlabelModel,UNO_QUERY); #ifdef DEBUG if (xPSetLabel.is()) printf("OK XPropertySet2\n"); else printf("Error ... XPropertySet2\n"); #endif value=10; val <<= value; xPSetLabel->setPropertyValue(OUString::createFromAscii("PositionX"),val); value=10; val <<= value; xPSetLabel->setPropertyValue(OUString::createFromAscii("PositionY"),val); value=280; val <<= value; xPSetLabel->setPropertyValue(OUString::createFromAscii("Width"),val); value=150; val <<= value; xPSetLabel->setPropertyValue(OUString::createFromAscii("Height"),val); xPSetLabel->setPropertyValue(OUString::createFromAscii("HScroll"),makeAny((sal_Bool)true)); xPSetLabel->setPropertyValue(OUString::createFromAscii("VScroll"),makeAny((sal_Bool)true)); xPSetLabel->setPropertyValue(OUString::createFromAscii("MultiLine"),makeAny((sal_Bool)true)); xPSetLabel->setPropertyValue(OUString::createFromAscii("HardLineBreaks"),makeAny((sal_Bool)true)); val <<=OUString::createFromAscii("Label1"); xPSetLabel->setPropertyValue(OUString::createFromAscii("Name"),val); xPSetLabel->setPropertyValue(OUString::createFromAscii("TabIndex"),makeAny((short)2)); // insert all the control in container Reference< XNameContainer > xNameCont(xdialogModel,UNO_QUERY); #ifdef DEBUG if (xNameCont.is()) printf("OK XNameContainer\n"); else printf("Error ... XNameContainer\n"); #endif val <<= xbuttonModel; // We insert first the button xNameCont->insertByName(OUString::createFromAscii("Button1") ,val); #ifdef DEBUG printf("First\n"); #endif val <<= xbuttonModel2; xNameCont->insertByName(OUString::createFromAscii("Button2") ,val); //printf("First\n"); // We insert now the text control val <<= xlabelModel; xNameCont->insertByName(OUString::createFromAscii("Label1") , val); // create the dialog control and set the model Reference< XInterface >dialog = xServiceManager->createInstance( OUString::createFromAscii("com.sun.star.awt.UnoControlDialog")); #ifdef DEBUG if (dialog.is()) printf("OK dialog\n"); else printf("Error ... dialog\n"); #endif Reference< XControl > xControl(dialog,UNO_QUERY); #ifdef DEBUG if (xControl.is()) printf("OK XControl\n"); else printf("Error ... XControl\n"); #endif Reference< XControlModel > xControlModel(xdialogModel,UNO_QUERY); #ifdef DEBUG if (xControlModel.is()) printf("OK xControlModel\n"); else printf("Error ... xControlModel\n"); #endif xControl->setModel(xControlModel); // add an action listener to the button control Reference< XControlContainer > xControlCont(dialog,UNO_QUERY); #ifdef DEBUG if (xControlCont.is()) printf("OK xControlContainer\n"); else printf("Error ... xControlContainer\n"); #endif Reference< XInterface > objectButton=xControlCont->getControl(OUString::createFromAscii("Button1")); #ifdef DEBUG if (objectButton.is()) printf("OK objectButton\n"); else printf("Error ... objectButton\n"); #endif Reference< XButton > xButton(objectButton,UNO_QUERY); ActionListenerImpl *xListener = new ActionListenerImpl( xControlCont,this ); Reference< XActionListener > xActionListener = static_cast< XActionListener* > ( xListener ); xButton->addActionListener( xActionListener ); // create a peer Reference< XToolkit >xToolkit = Reference< XToolkit >( xServiceManager->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.Toolkit" ))), UNO_QUERY ); #ifdef DEBUG if (xToolkit.is()) printf ("XToolkit OK...\n"); else printf("XToolkit Error\n"); #endif Reference< XWindow > xWindow(xControl,UNO_QUERY); xWindow->setVisible(true); xControl->createPeer(xToolkit,NULL); Reference< XDialog > xDialog(dialog,UNO_QUERY); xDialog->execute(); Reference< XComponent > xComponent(dialog,UNO_QUERY); xComponent->dispose(); }
We need also an event listener (see Calc Event Listener and First Dialog). The corresponding code is :
//Listing 17 action performed event listener // C++ // Don't forget the #include <cppuhelper/implbase1.hxx> typedef ::cppu::WeakImplHelper1< ::com::sun::star::awt::XActionListener > ActionListenerHelper; /** action listener */ class ActionListenerImpl : public ActionListenerHelper { private : sal_Int32 _nCounts; Reference< XControlContainer > _xControlCont; //XControlContainer _xControlCont; ReflectionHelper *refHelp; Sequence <OUString> methods,properties,services,types; public : ActionListenerImpl(const Reference< XControlContainer >& xControlCont,ReflectionHelper *rHelper) { _xControlCont = xControlCont; _nCounts = 0; refHelp = rHelper; methods = refHelp->getMethods(); properties = refHelp->getPropertiesWithValues(); services = refHelp->getServices(); types = refHelp->getTypes(); } // XEventListener virtual void SAL_CALL disposing (const com::sun::star::lang::EventObject& aEventObj ) throw(::com::sun::star::uno::RuntimeException) { // _xControlCont = NULL; #ifdef DEBUG printf("object listened to will be disposed\n"); #endif } // XActionListener virtual void SAL_CALL actionPerformed (const ::com::sun::star::awt::ActionEvent& rEvent ) throw ( RuntimeException) { OUString OUStr; // set label text Reference< XControl > label = _xControlCont->getControl(OUString::createFromAscii("Label1")); // Don't forget to add : #include <com/sun/star/awt/XTextComponent.hpp> // Don't forget to add "com.sun.star.awt.XTextComponent \" in the makefile Reference< XTextComponent > xLabel(label,UNO_QUERY); switch (_nCounts%4){ case 0 : for (int i=0;i<methods.getLength();i++){ if(i==0) xLabel->setText(methods[i] + OUString::createFromAscii("\n"));else xLabel->insertText (xLabel->getSelection(), methods[i] + OUString::createFromAscii("\n")); } xLabel->insertText (xLabel->getSelection(), OUString::createFromAscii("******** Methods : ") + OUStr.valueOf((sal_Int32)methods.getLength())+ OUString::createFromAscii("\n")); break; case 1 :for (int i=0;i<properties.getLength();i++){ if(i==0) xLabel->setText(properties[i] + OUString::createFromAscii("\n"));else xLabel->insertText (xLabel->getSelection(), properties[i] + OUString::createFromAscii("\n")); } xLabel->insertText (xLabel->getSelection(), OUString::createFromAscii("******** Properties : ") + OUStr.valueOf((sal_Int32)properties.getLength())+ OUString::createFromAscii("\n")); break; case 2 :for (int i=0;i<services.getLength();i++){ if(i==0) xLabel->setText(services[i] + OUString::createFromAscii("\n"));else xLabel->insertText (xLabel->getSelection(), services[i] + OUString::createFromAscii("\n")); } xLabel->insertText (xLabel->getSelection(), OUString::createFromAscii("******** Services : ") + OUStr.valueOf((sal_Int32)services.getLength())+ OUString::createFromAscii("\n")); break; case 3 :for (int i=0;i<types.getLength();i++){ if(i==0) xLabel->setText(types[i] + OUString::createFromAscii("\n"));else xLabel->insertText (xLabel->getSelection(), types[i] + OUString::createFromAscii("\n")); } xLabel->insertText (xLabel->getSelection(), OUString::createFromAscii("******** Types - Interfaces : ") + OUStr.valueOf((sal_Int32)types.getLength())+ OUString::createFromAscii("\n")); break; } // increase click counter _nCounts++; } };
Using this helper is easy : here is an example :
//Listing 18 Using this helper // C++ main( ) { //retrieve an instance of the remote service manager Reference< XMultiServiceFactory > xServiceManager; xServiceManager = ooConnect(); if( xServiceManager.is() ){ printf( "Connected sucessfully to the office\n" ); } //get the desktop service using createInstance returns an XInterface type Reference< XInterface > Desktop = xServiceManager->createInstance( OUString::createFromAscii( "com.sun.star.frame.Desktop" )); //query for the XComponentLoader interface Reference< XComponentLoader > rComponentLoader (Desktop, UNO_QUERY); if( rComponentLoader.is() ){ printf( "XComponentloader successfully instanciated\n" ); } Any toInspect; // I want to inspect rDesktop object : toInspect <<= rComponentLoader; // need a service manager ReflectionHelper *Reflect = new (ReflectionHelper)(toInspect,xServiceManager); Reflect->printOut(); return 0; }
The corresponding result is given in the Figure below :
After launching this dialog, please click on ">>" button to see the other informations on services, interfaces and properties.
See also
- C++ and UNO tutorial
- XIntrospection Interface
- XIdlReflection Interface
- Writing a Program to Control OpenOffice.org, by Franco Pingiori — Part 1 and Part 2, Linux Journal
- Bernard Marcelly's XRay OOoBasic tool and a XRay tool description in this wiki.
- See The New Object Inspector
- Extensions Introspection