Difference between revisions of "Constructing Helpers"

From Apache OpenOffice Wiki
Jump to: navigation, search
m (Presentation)
m (New Implementation Code)
Line 807: Line 807:
  
 
After launching this dialog, please click on ">>" button to see the other informations on services, interfaces and properties.
 
After launching this dialog, please click on ">>" button to see the other informations on services, interfaces and properties.
 +
{{Documentation/Caution|
 +
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.}}
  
  

Revision as of 10:00, 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.

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 :

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 :

MyInspector.png


After launching this dialog, please click on ">>" button to see the other informations on services, interfaces and properties.

Documentation caution.png

Because it's hard to maintain code cut in many parts as above, I have added a Snippet here. This snippet will be the more recent complete class code.


See also

Personal tools