Developpement/Cpp/Component/RelectionHelper
From Apache OpenOffice Wiki
The ReflectionHelper class
See the corresponding section for the state of this code. This class is composed with two source files.
//******************************* Version 0.4 Jul 2009 ****************
#ifndef REFLECTIONHELPER_H
#define REFLECTIONHELPER_H
#include <rtl/ustring.hxx>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/lang/XMultiComponentFactory.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 toInspect,Reference< XMultiComponentFactory > const & oSVM, Reference< XComponentContext > const & xContext);
Sequence < OUString > getMethods(),
getTypes(),
getServices(),
getPropertiesWithoutValues(),
getPropertiesWithValues();
Sequence< Reference< XIdlMethod > > getIdlMethods();
Reference< XIdlMethod > getXIdlMethodByName(OUString aName);
void getTypeAndValue(Any toInspect);
sal_Bool m_simpleObject;
OUString m_OUStrAnyTypeAndValue; // for simple object data
// Print out
// void printOut(); //perhaps const ?
private:
Any m_toInspect;
Reference< XMultiComponentFactory > m_xServiceManager;
Reference< XIntrospection >m_xIntrospection;
Reference< XIntrospectionAccess > m_xIntrospec;
Reference< XTypeProvider > m_xTypeProvider;
Reference< XComponentContext > m_xContext;
OUString getValueName(Any object);
OUString getParamMode(ParamMode paramMode);
// methods
Sequence< Reference< XIdlMethod > > mMethods;
// Interfaces
Sequence< Type > types;
// Services
Reference< XServiceInfo > m_xServiceInfo;
// Sequence< OUString > services;
// Properties
Sequence< Property > Properties;
// protected methods
protected:
Sequence< OUString > convert2SeqOUStrInDEBUGMODE(Sequence < sal_Int8 > seqBytes);
// same as "convert2SeqOUStrInDEBUGMODE" but in one OUString
OUString convert2OUStrInDEBUGMODE(Sequence < sal_Int8 > seqBytes);
};
#endif //REFLECTIONHELPER_H
And now the corresponding implementation :
// C++
// Serge Moutou
// with help of <OpenOffice1.1_SDK>/examples/java/Inspector
// and Bernard Marcelly XRay tool
// version 0.1 (22 Dec 2004)
// version 0.2 (4 Jun 2005) added printout in a dialog
// version 0.2.1 (4 Apr 2009) added name of parameters in methods
// version 0.3 (23 Apr 2009) added DEBUG MODE for []bytes properties
// version 0.4 (28 Jul 2009) changed to be used with a component:
// ****** constructor uses XMultiComponentFactoty instead of XMultiServiceFactory
// To do : Exception Handling, to go further with properties values
//#include <org/openoffice/cpp/XInstanceIspector.hpp>
#include "./ReflectionHelper.hpp"
#include <com/sun/star/reflection/XIdlClass.hpp>
#include <com/sun/star/beans/PropertyConcept.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
//#include <com/sun/star/reflection/ParamMode.hpp> done in ReflectionHelper.hpp
#include <com/sun/star/container/XNameContainer.hpp>
//#include <cppuhelper/implbase1.hxx>
#include <com/sun/star/awt/XTextComponent.hpp>
//#include <com/sun/star/awt/XActionListener.hpp>
#include <com/sun/star/awt/XToolkit.hpp>
#include <com/sun/star/awt/XControlContainer.hpp>
//#include <com/sun/star/awt/PushButtonType.hpp>
//#include <com/sun/star/awt/XButton.hpp>
//#include <com/sun/star/awt/XWindow.hpp>
//#include <com/sun/star/awt/XDialog.hpp>
//#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <rtl/ustring.hxx>
#include <rtl/string.hxx>
//#define DEBUG
using namespace com::sun::star::awt;
//using namespace com::sun::star::frame;
using namespace com::sun::star::lang;
using namespace com::sun::star::container;
// Inspector constructor
ReflectionHelper::ReflectionHelper(Any toInspect, Reference< XMultiComponentFactory > const & oSVM,
Reference< XComponentContext > const & xContext)
: m_toInspect(toInspect), m_xServiceManager(oSVM), m_xContext(xContext) {
m_xIntrospection = Reference< XIntrospection >( m_xServiceManager->createInstanceWithContext(
OUString::createFromAscii("com.sun.star.beans.Introspection" ),m_xContext), UNO_QUERY_THROW);
getTypeAndValue(m_toInspect);
}
//FIXME:Bad idea to take a method of ReflectionHelper for that ?
//**** modify data member and then doesn't keep coherence in data ?
void ReflectionHelper::getTypeAndValue(Any toInspect){
// what kind of object object ?
OUString OUStrAnyTypeAndValue, OUStrTypeValue;
switch (toInspect.pType->eTypeClass)
{
// const defined in <OOo_SDK>/include/typelib/typeclass.h
case typelib_TypeClass_VOID:
OUStrAnyTypeAndValue = OUString::createFromAscii("(")+ OUStrAnyTypeAndValue+
OUString::createFromAscii(")");
m_simpleObject = sal_True;
m_OUStrAnyTypeAndValue = OUStrAnyTypeAndValue;
break;
case typelib_TypeClass_BOOLEAN:
sal_Bool MyBool;
toInspect >>= MyBool;
OUStrAnyTypeAndValue = OUString::createFromAscii("(")+ OUStrAnyTypeAndValue+
OUString::createFromAscii(")=") + OUStrTypeValue.valueOf((sal_Bool) MyBool);
m_simpleObject=sal_True;
m_OUStrAnyTypeAndValue = OUStrAnyTypeAndValue;
break;
// all in a 32 bit data at the moment
case typelib_TypeClass_BYTE:
case typelib_TypeClass_CHAR:
case typelib_TypeClass_SHORT:
case typelib_TypeClass_UNSIGNED_SHORT:
case typelib_TypeClass_UNSIGNED_LONG:
case typelib_TypeClass_LONG:
sal_Int32 *MyLong;
MyLong = (sal_Int32*) toInspect.getValue();
OUStrAnyTypeAndValue = OUString::createFromAscii("(")+ OUStrAnyTypeAndValue+
OUString::createFromAscii(")=") + OUStrTypeValue.valueOf((sal_Int32) *MyLong);
m_simpleObject = sal_True;
m_OUStrAnyTypeAndValue = OUStrAnyTypeAndValue;
break;
// all in the double data at the moment
case typelib_TypeClass_FLOAT:
case typelib_TypeClass_DOUBLE:
double *myDouble;
myDouble = (double*) toInspect.getValue();
OUStrAnyTypeAndValue = OUString::createFromAscii("(")+ OUStrAnyTypeAndValue+
OUString::createFromAscii(")=") + OUStrTypeValue.valueOf((double) *myDouble);
m_simpleObject = sal_True;
m_OUStrAnyTypeAndValue = OUStrAnyTypeAndValue;
break;
/* case typelib_TypeClass_HYPER:
break;
case typelib_TypeClass_ANY:
break; */
case typelib_TypeClass_STRING:
toInspect >>= OUStrTypeValue;
OUStrAnyTypeAndValue = OUString::createFromAscii("(")+ OUStrAnyTypeAndValue+
OUString::createFromAscii(")=")+OUStrTypeValue;
m_simpleObject = sal_True;
m_OUStrAnyTypeAndValue = OUStrAnyTypeAndValue;
break;
case typelib_TypeClass_SEQUENCE:
if (toInspect.getValueTypeName() == OUString::createFromAscii("[]byte")) {
Sequence< sal_Int8 > SeqByte;
toInspect >>= SeqByte;
OUString OUStr=OUString::createFromAscii("([]byte)");
/* OUStr = OUString::createFromAscii("Length:");
OUStr=OUStr.concat(OUStr.valueOf((sal_Int32) SeqByte.getLength())+
OUString::createFromAscii(" : "));*/
OUStrAnyTypeAndValue=OUStr + convert2OUStrInDEBUGMODE(SeqByte); //0.3 version
m_simpleObject = sal_True;
m_OUStrAnyTypeAndValue = OUStrAnyTypeAndValue;
} else
if (toInspect.getValueTypeName() == OUString::createFromAscii("[]string")) {
Sequence< OUString > SeqOUStr;
OUString OUStr;
toInspect >>= SeqOUStr;
OUStr = OUString::createFromAscii("Length:");
OUStr=OUStr.concat(OUStr.valueOf((sal_Int32) SeqOUStr.getLength())+
OUString::createFromAscii(" : "));
for (sal_Int32 i=0; i<SeqOUStr.getLength(); i++){
OUStr=OUStr.concat(OUString::createFromAscii("\"")
+SeqOUStr[i]
+ OUString::createFromAscii("\""));
}
OUStrAnyTypeAndValue = OUString::createFromAscii("([]string) ") + OUStr;
m_simpleObject = sal_True;
m_OUStrAnyTypeAndValue = OUStrAnyTypeAndValue;
}
break;
case typelib_TypeClass_INTERFACE:
m_xIntrospec = m_xIntrospection->inspect(toInspect);
mMethods = m_xIntrospec -> getMethods(MethodConcept::ALL);
m_xTypeProvider = Reference< XTypeProvider> (toInspect,UNO_QUERY);
types = m_xTypeProvider->getTypes();
m_xServiceInfo = Reference< XServiceInfo>(toInspect,UNO_QUERY);
Properties = m_xIntrospec -> getProperties(PropertyConcept::ALL);
m_simpleObject = sal_False;
break;
/* case typelib_TypeClass_TYPE: break;
case typelib_TypeClass_ARRAY: break;
case typelib_TypeClass_SERVICE: break;
case typelib_TypeClass_INTERFACE_METHOD: break;
case typelib_TypeClass_INTERFACE_ATTRIBUTE:break;
case typelib_TypeClass_ENUM: break;
case typelib_TypeClass_STRUCT:break; */
//default:
} // switch
}
//OK
Sequence < OUString > ReflectionHelper::getServices() {
return m_xServiceInfo->getSupportedServiceNames();
}
//OK
Sequence < OUString > ReflectionHelper::getMethods(){
Sequence< OUString > methods(mMethods.getLength());
for (int i=0;i<mMethods.getLength();i++){
OUString params;
params=OUString::createFromAscii("(");
Sequence< ParamInfo > ParamInfos = mMethods[i]->getParameterInfos();
if (ParamInfos.getLength() > 0) {
for (int j=0;j<ParamInfos.getLength();j++){
Reference< XIdlClass > xIdlClass = ParamInfos[j].aType;
if (j == 0)
// first parameter has no leading comma
params += OUString::createFromAscii("[") + getParamMode(ParamInfos[j].aMode)+
OUString::createFromAscii("]") +
xIdlClass->getName() + OUString::createFromAscii(" ") + ParamInfos[j].aName;
else
params += OUString::createFromAscii(",[") + getParamMode(ParamInfos[j].aMode)+
OUString::createFromAscii("]")+
xIdlClass->getName() + OUString::createFromAscii(" ") + ParamInfos[j].aName;
}
}
params += OUString::createFromAscii(")");
methods[i] = mMethods[i]->getReturnType()->getName()+OUString::createFromAscii(" ")+
mMethods[i]->getName()+params;
}
return methods;
}
Sequence< Reference< XIdlMethod > > ReflectionHelper::getIdlMethods(){
return mMethods;
}
// added for 0.4 version
Reference< XIdlMethod > ReflectionHelper::getXIdlMethodByName(OUString aName){
Reference< XIdlMethod > xIdlMethod = m_xIntrospec->getMethod(aName,MethodConcept::ALL);
return xIdlMethod;
}
// OK
Sequence < OUString > ReflectionHelper::getTypes(){
Sequence< OUString > interfaces(types.getLength());
for (int i=0;i<types.getLength();i++){
interfaces[i] = types[i].getTypeName();
}
return interfaces;
}
// to improve : change all the tests with getCppuType : probably quicker than a string test
OUString ReflectionHelper::getValueName(Any object){
OUString OUStr;
OUStr = OUString::createFromAscii("!! Unable to compute values !!");
if (object.hasValue()) {
if (object.isExtractableTo(getCppuBooleanType())){
sal_Bool MyBool;
object >>= MyBool;
return OUStr.valueOf((sal_Bool) MyBool);
} else
if (object.getValueTypeName() == OUString::createFromAscii("string")) {
OUString *MyOUStr;
MyOUStr = (OUString *) object.getValue();
OUStr = OUString::createFromAscii("\"");
return OUStr + *MyOUStr + OUString::createFromAscii("\"");
} else
if (object.getValueTypeName() == OUString::createFromAscii("long")) {
sal_Int32 *MyLong;
MyLong = (sal_Int32*) object.getValue();
return OUStr.valueOf((sal_Int32) *MyLong);
} else
if (object.getValueTypeName() == OUString::createFromAscii("short")) {
sal_Int16 *MyShort;
MyShort = (sal_Int16*) object.getValue();
return OUStr.valueOf((sal_Int32) *MyShort);
} else
if (object.getValueTypeName() == OUString::createFromAscii("[]byte")) {
Sequence< sal_Int8 > SeqByte;
object >>= SeqByte;
OUString OUStr=convert2OUStrInDEBUGMODE(SeqByte); //0.3 version
return OUStr;
} else
if (object.getValueTypeName() == OUString::createFromAscii("[]string")) {
Sequence< OUString > SeqOUStr;
object >>= SeqOUStr;
OUStr = OUString::createFromAscii("Length:");
OUStr=OUStr.concat(OUStr.valueOf((sal_Int32) SeqOUStr.getLength())+
OUString::createFromAscii(" : "));
for (sal_Int32 i=0; i<SeqOUStr.getLength(); i++){
OUStr=OUStr.concat(OUString::createFromAscii("\"")
+SeqOUStr[i]
+ OUString::createFromAscii("\""));
}
return OUStr;
} else return OUStr;
} else return OUStr;
}
// OK
// Get properties with values : only those computed in getValueName
// améliorer avec :
// voir SDK2.3.1 portable IUT <SDK>/examples/cpp/extensions/source/objectbrowser/uno_lang.cxx
Sequence < OUString > ReflectionHelper::getPropertiesWithValues(){
Sequence< OUString > propWithVal(Properties.getLength());
for (int i=0;i<Properties.getLength();i++){
Type typ = getCppuType( (const Reference< XPropertySet > *)0);
Reference< XPropertySet > rPropertySet(m_xIntrospec->queryAdapter(typ),UNO_QUERY);
Reference< XPropertySetInfo > rPropertySetInfo=rPropertySet->getPropertySetInfo();
Any object;
if (rPropertySetInfo->hasPropertyByName(Properties[i].Name)){
object <<= rPropertySet->getPropertyValue(Properties[i].Name);
//if (object.hasValue()) printf("Valeur trouvee : \n");
propWithVal[i] = Properties[i].Name + OUString::createFromAscii(" = (")+
Properties[i].Type.getTypeName() + OUString::createFromAscii(") ")
+ getValueName(object);
//+ object.getValueTypeName();
}
}
return propWithVal;
}
// OK
// Get properties without values but types
Sequence < OUString > ReflectionHelper::getPropertiesWithoutValues(){
Sequence< OUString > propWithVal(Properties.getLength());
for (int i=0;i<Properties.getLength();i++){
Type typ = getCppuType( (const Reference< XPropertySet > *)0);
Reference< XPropertySet > xPropertySet(m_xIntrospec->queryAdapter(typ),UNO_QUERY);
Reference< XPropertySetInfo > xPropertySetInfo=xPropertySet->getPropertySetInfo();
if (xPropertySetInfo->hasPropertyByName(Properties[i].Name)){
propWithVal[i] = Properties[i].Name + OUString::createFromAscii(" = (")+
Properties[i].Type.getTypeName() + OUString::createFromAscii(")");
}
}
return propWithVal;
}
// 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) {
OUString toReturn;
toReturn = OUString::createFromAscii("");
if (paramMode == ParamMode_IN) toReturn = OUString::createFromAscii("IN"); else
if (paramMode == ParamMode_OUT) toReturn = OUString::createFromAscii("OUT"); else
if (paramMode == ParamMode_INOUT) toReturn = OUString::createFromAscii("INOUT");
return toReturn;
}
// added for 0.3 version
Sequence< OUString > ReflectionHelper::convert2SeqOUStrInDEBUGMODE(Sequence < sal_Int8 > seqBytes){
sal_Int8 Hexa[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
sal_Int32 lin,col;
sal_Char line[80];
sal_Int32 len,sequenceSize,index;
len=seqBytes.getLength();
sequenceSize=(len>>4)+2;
if ((len&0XFFF0)==len) sequenceSize--; //if len%16==0
Sequence< OUString > SeqOUStr(sequenceSize);
// First line with length
SeqOUStr[0] = OUString::createFromAscii("Length:")+
OUString::valueOf((sal_Int32) seqBytes.getLength())+
OUString::createFromAscii(" ");
len = len&0XFFF0; // remove the modulo 16
for(lin=0;lin<len;lin=lin+16){
for(col=0;col<16;col++){
line[3*col]=Hexa[((unsigned char)seqBytes[lin+col])>>4];
line[3*col+1]=Hexa[seqBytes[lin+col]&0x0F];
line[3*col+2]=' ';
if ((seqBytes[lin+col]<128)&&(seqBytes[lin+col]>20)) line[50+col]=seqBytes[lin+col];
else line[50+col]='.';
} /* end of for */
line[66]=0; /* end of cstring...*/
line[48]=' ';line[49]=' ';
// ready to add the OUString in Sequence
if ((lin%16)==0) index = lin/16+1; else index=lin/16+2;
SeqOUStr[index]=OUString::createFromAscii(line);
} /* end of for */
// the last line is more complicated because not complete
// we only keep modulo
len=seqBytes.getLength()&0x000F;
if (len>0) { // only a line here if non-empty
for (lin=0;lin<len;lin++){
col=lin;
line[3*col]=Hexa[((unsigned char)seqBytes[lin])>>4];
line[3*col+1]=Hexa[seqBytes[lin]&0x0F];
line[3*col+2]=' ';
if ((seqBytes[lin]<128)&&(seqBytes[lin]>20)) line[50+col]=seqBytes[lin];
else line[50+col]='.';
}
// we complete the line
for (++col;col<16;col++){
line[3*col]=' ';line[3*col+1]=' ';line[3*col+2]=' ';line[50+col]=' ';
}
line[66]=0; /* end of string...*/
line[48]=' ';line[49]=' ';
// ready to add the OUString in Sequence
SeqOUStr[lin/16+2]=OUString::createFromAscii(line);
} //end if
return SeqOUStr;
}
// added for 0.3 version
OUString ReflectionHelper::convert2OUStrInDEBUGMODE(Sequence < sal_Int8 > seqBytes){
Sequence <OUString> SeqOUStr = convert2SeqOUStrInDEBUGMODE(seqBytes);
OUString OUStr;
for(sal_Int32 i=0;i<SeqOUStr.getLength();i++)
OUStr = OUStr+SeqOUStr[i]+OUString::createFromAscii("\n");
return OUStr;
}
The Component Code
The component IDL file is as follows
TO DO
The corresponding c++ code is :
/***************************************************************************************************
***************************************************************************************************
*
* service implementation: foo.Counter
* exported interfaces: foo.XCounter
*
* simple example component implementing a counter
*
***************************************************************************************************
**************************************************************************************************/
#include <rtl/ustring.hxx>
#include <rtl/string.hxx>
#include <cppuhelper/queryinterface.hxx> // helper for queryInterface() impl
#include <cppuhelper/factory.hxx> // helper for component factory
// New
#include <cppuhelper/implbase3.hxx> // "3" implementing three interfaces
#include <cppuhelper/implementationentry.hxx>
#include <com/sun/star/awt/XDialog.hpp>
#include <com/sun/star/awt/XNumericField.hpp>
#include <com/sun/star/awt/XControl.hpp>
#include <com/sun/star/awt/XControlContainer.hpp>
#include <com/sun/star/awt/XDialogEventHandler.hpp>
#include <com/sun/star/awt/XDialogProvider2.hpp>
#include <com/sun/star/awt/XTextComponent.hpp>
#include <com/sun/star/awt/tree/XTreeControl.hpp>
#include <com/sun/star/awt/tree/XMutableTreeDataModel.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
// generated c++ interfaces
//#include <com/sun/star/lang/XSingleServiceFactory.hpp>
//#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/frame/XDesktop.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/frame/XModel.hpp>
//#include <com/sun/star/lang/WrappedTargetException.hpp>
//#include <com/sun/star/reflection/XIdlClass.hpp>
//#include <com/sun/star/reflection/XIdlMethod.hpp>
#include <com/sun/star/registry/XRegistryKey.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <foo/XCountable.hpp>
// Java Inspector
//#include <org/openoffice/XInstanceInspector.hpp>
//ReflectionHelper
#include "ReflectionHelper.hpp"
// FIXME : change the service name
#define SERVICENAME "foo.Counter"
#define IMPLNAME "com.sun.star.comp.example.cpp.Counter"
using namespace ::rtl;
using namespace ::osl;
using namespace ::cppu;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::awt::tree;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::registry;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::beans;
//using namespace ::com::sun::star::relflection;
using namespace ::foo;
//using namespace ::org::openoffice;
//==================================================================================================
namespace my_sc_impl
{
static Sequence< OUString > getSupportedServiceNames_MyCounterImpl()
{
static Sequence < OUString > *pNames = 0;
if( ! pNames )
{
// MutexGuard guard( Mutex::getGlobalMutex() );
if( !pNames )
{
static Sequence< OUString > seqNames(1);
seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
pNames = &seqNames;
}
}
return *pNames;
}
static OUString getImplementationName_MyCounterImpl()
{
static OUString *pImplName = 0;
if( ! pImplName )
{
// MutexGuard guard( Mutex::getGlobalMutex() );
if( ! pImplName )
{
static OUString implName( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) );
pImplName = &implName;
}
}
return *pImplName;
}
// New
class MyCounterImpl : public ::cppu::WeakImplHelper3<
XCountable, XServiceInfo, XDialogEventHandler >
{
// to obtain other services if needed
Reference< XMultiComponentFactory > m_xMCF;
Reference< XComponentContext > m_xContext;
// Reference< XInstanceInspector > m_xInspector;
// sal_Int32 m_nCount;
Reference< XMutableTreeDataModel > m_xMutTreeDatMod;
Reference< XDialog > m_xDialog;
Any m_toInspect;
public:
// added this constructor 06/06/09
inline MyCounterImpl( Reference< XComponentContext > const & xContext) throw ()
: m_xContext( xContext ) {
m_xMCF=m_xContext->getServiceManager();
// Reference< XMutableTreeDataModel > xTreeMutDatMod(xTreeControl,UNO_QUERY); //NO NO NO:hangs the office : see below
m_xMutTreeDatMod = Reference< XMutableTreeDataModel > (m_xMCF->createInstanceWithContext(
OUString::createFromAscii("com.sun.star.awt.tree.MutableTreeDataModel"),m_xContext),UNO_QUERY_THROW);
Reference< XDialogProvider2 > xDialog2(m_xMCF->createInstanceWithContext(
OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DialogProvider2" ) ),
m_xContext),
UNO_QUERY_THROW );
m_xDialog=xDialog2->createDialogWithHandler(
OUString::createFromAscii( "vnd.sun.star.script:Standard.SimpleTreeDialog?location=application" ),
(XCountable *)this);
// If you want to use java Inspector
// m_xInspector = Reference< XInstanceInspector > (m_xMCF->createInstanceWithContext(
// OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.InstanceInspector" ) ),
// m_xContext),
// UNO_QUERY_THROW );
}
virtual ~MyCounterImpl() {}
// XServiceInfo specification
virtual OUString SAL_CALL getImplementationName( ) throw(RuntimeException);
virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException);
virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(RuntimeException);
static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static( );
// XCountable specification
virtual void SAL_CALL myInspect(const Any &toInspect) throw (RuntimeException);
// XDialogEventHandler specification
virtual sal_Bool SAL_CALL callHandlerMethod(const Reference< XDialog >& xDialog,const Any& EventObject,const OUString& MethodName )
throw(WrappedTargetException, RuntimeException);
virtual Sequence< OUString > SAL_CALL getSupportedMethodNames() throw (RuntimeException);
};
// XCountable implementation
//*************************************************************************
void SAL_CALL MyCounterImpl::myInspect(const Any &toInspect) throw (RuntimeException){
// use of ReflectionHelper
ReflectionHelper RefHelp(toInspect,m_xMCF,m_xContext);
// Constructing the Tree 24th Jul 2009 (dynamic Tree)
m_toInspect = toInspect;
Reference< XControlContainer > xControlContainer(m_xDialog,UNO_QUERY);
Reference< XControl > xControl = xControlContainer->getControl(OUString::createFromAscii("TreeControl"));
Reference< XServiceInfo > xServiceInfo(toInspect,UNO_QUERY);
OUString implName(xServiceInfo->getImplementationName());
Any any;
any <<= implName;
Reference< XMutableTreeNode > xMTN=m_xMutTreeDatMod->createNode(any,sal_True);
m_xMutTreeDatMod->setRoot(xMTN);
any <<= OUString::createFromAscii("Methods");
Reference< XMutableTreeNode > xChildNode = m_xMutTreeDatMod->createNode(any,sal_True);
xMTN->appendChild(xChildNode);
Sequence< OUString > SeqMethods = RefHelp.getMethods();
for (sal_Int32 i=0;i<SeqMethods.getLength();i++) {
any <<= SeqMethods[i];
Reference< XMutableTreeNode > xChildNode2 = m_xMutTreeDatMod->createNode(any,sal_True);
xChildNode->appendChild(xChildNode2);
}
any <<= OUString::createFromAscii("Interfaces");
xChildNode = m_xMutTreeDatMod->createNode(any,sal_True);
xMTN->appendChild(xChildNode);
Sequence< OUString > SeqTypes = RefHelp.getTypes();
for (sal_Int32 i=0;i<SeqTypes.getLength();i++) {
any <<= SeqTypes[i];
Reference< XMutableTreeNode > xChildNode2 = m_xMutTreeDatMod->createNode(any,sal_True);
xChildNode->appendChild(xChildNode2);
}
any <<= OUString::createFromAscii("Services");
xChildNode = m_xMutTreeDatMod->createNode(any,sal_True);
xMTN->appendChild(xChildNode);
Sequence< OUString > SeqServices = RefHelp.getServices();
for (sal_Int32 i=0;i<SeqServices.getLength();i++) {
any <<= SeqServices[i];
Reference< XMutableTreeNode > xChildNode2 = m_xMutTreeDatMod->createNode(any,sal_True);
xChildNode->appendChild(xChildNode2);
}
any <<= OUString::createFromAscii("Properties");
xChildNode = m_xMutTreeDatMod->createNode(any,sal_True);
xMTN->appendChild(xChildNode);
Sequence< OUString > SeqProperties = RefHelp.getPropertiesWithValues();
for (sal_Int32 i=0;i<SeqProperties.getLength();i++) {
any <<= SeqProperties[i];
Reference< XMutableTreeNode > xChildNode2 = m_xMutTreeDatMod->createNode(any,sal_True);
xChildNode->appendChild(xChildNode2);
}
// set the model to see the tree in control (two hours to find four lines below)
// translation of oTreeModel = oTreeCtrl.Model and oTreeModel.DataModel = oMutableTreeDataModel
Reference< XControlModel > xControlModel=xControl->getModel();
Reference< XPropertySet > xPropertySet( xControlModel,UNO_QUERY);
any <<= m_xMutTreeDatMod;
xPropertySet->setPropertyValue(OUString::createFromAscii("DataModel"),any);
// put the new node name in text control
OUString OUStrMethodName = m_toInspect.getValueTypeName();
xControl = xControlContainer->getControl(OUString::createFromAscii("lbDescription"));
Reference< XTextComponent > xTextComponent(xControl,UNO_QUERY);
xTextComponent->setText(OUStrMethodName);
// execute dialog
m_xDialog->execute();
}
// XDialogEventHandler implementation
sal_Bool SAL_CALL MyCounterImpl::callHandlerMethod(const Reference< XDialog >& xDialog,const Any& EventObject,const OUString & MethodName ) throw(WrappedTargetException, RuntimeException ){
if (MethodName.equalsAscii("LosingFocus")){//When Losing Focus in Tree control
// not used in this example
return sal_True;
}
if (MethodName.equalsAscii("Invoke")){//add a child to the selected node -- not done
// First retrieve the selection
Reference< XControlContainer > xControlContainer(xDialog,UNO_QUERY);
Reference< XControl > xControl = xControlContainer->getControl(OUString::createFromAscii("TreeControl"));
// com.sun.star.awt.tree.XTreeControl
Reference< XTreeControl > xTreeControl(xControl,UNO_QUERY);
Any any=xTreeControl->getSelection();
// Parent
Reference< XMutableTreeNode > xParentNode;
any >>= xParentNode;
// adding invoke result
// sal_Int32 nb=xParentNode->getChildCount();
// Child
OUString OUStr,OUStrMethodName(OUString::createFromAscii("notFound"));
any=xParentNode->getDisplayValue();
any >>= OUStr;
//FIXME: parsing is too simple
// if ( OUStr.match(OUString::createFromAscii("()"),OUStr.getLength()-2) ) { // zero arguments
if ( OUStr.endsWithAsciiL("()",2) ) { // zero arguments
//FIXME check if parent Node is really a "method"
sal_Int32 beginIndex=OUStr.indexOfAsciiL(" ",1);
sal_Int32 length = OUStr.indexOfAsciiL("()",1)-beginIndex;
OUStr = OUStr.copy(beginIndex+1,length-1);
//FIXME: keep this data in a member field to avoid constructor call for a second time
ReflectionHelper RefHelp(m_toInspect,m_xMCF,m_xContext);
//FIXME: hangs the office with exception if bad method name
//****** it occurs when invoke a method with parameter !!!
//****** because of bad parsing
Reference < XIdlMethod > xIdlMethod = RefHelp.getXIdlMethodByName(OUStr);
// FIXME: is this check good enough ?
if (xIdlMethod.is()) {
//Sequence<Reference <XIdlClass> > seqXIdlClass = xIdlMethod->getParameterTypes();
// OUStrMethodName = xIdlMethod->getName();
Sequence < Any >SeqAny(0);
any=xIdlMethod->invoke(m_toInspect,SeqAny);
OUStrMethodName = any.getValueTypeName();
//any >>= OUStrMethodName;
RefHelp.getTypeAndValue(any);
if (RefHelp.m_simpleObject)
OUStrMethodName = RefHelp.m_OUStrAnyTypeAndValue;
else
OUStrMethodName = any.getValueTypeName();
} // if (xIdlMethod.is())
} //if ( OUStr.endsWithAsciiL("()",2) ) { // zero arguments
// put the new node name in text control
xControl = xControlContainer->getControl(OUString::createFromAscii("lbDescription"));
Reference< XTextComponent > xTextComponent(xControl,UNO_QUERY);
xTextComponent->setText(OUStrMethodName);
/* any <<= OUStr;
Reference< XMutableTreeNode > xChildMutTreeNode = m_xMutTreeDatMod->createNode(any ,sal_True);
// Java Introspection
// any <<= xChildMutTreeNode;
// m_xInspector->inspect(any,OUString::createFromAscii("Inspector"));
xParentNode->appendChild(xChildMutTreeNode); */
return sal_True;
}
return sal_False;
}
Sequence< OUString > SAL_CALL MyCounterImpl::getSupportedMethodNames() throw (RuntimeException){
Sequence< OUString > SeqOUStr(2);
SeqOUStr[0]=OUString::createFromAscii("LosingFocus");
SeqOUStr[1]=OUString::createFromAscii("Invoke");
return SeqOUStr;
}
// XServiceInfo implementation
//*************************************************************************
OUString SAL_CALL MyCounterImpl::getImplementationName( )
throw(RuntimeException)
{
return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) );
}
//*************************************************************************
sal_Bool SAL_CALL MyCounterImpl::supportsService( const OUString& ServiceName )
throw(RuntimeException)
{
return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(SERVICENAME) );
}
//*************************************************************************
Sequence<OUString> SAL_CALL MyCounterImpl::getSupportedServiceNames( )
throw(RuntimeException)
{
return getSupportedServiceNames_Static();
}
//*************************************************************************
Sequence<OUString> SAL_CALL MyCounterImpl::getSupportedServiceNames_Static( )
{
Sequence<OUString> names(1);
names[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
return names;
}
//*****New vesion with context management
Reference< XInterface > SAL_CALL MyCounterImpl_createInstance(
Reference< XComponentContext > const & xContext )
SAL_THROW( () )
{
return static_cast< ::cppu::OWeakObject * >( new MyCounterImpl( xContext ) );
}
}
//##################################################################################################
//#### EXPORTED ####################################################################################
//##################################################################################################
/* New ****/
/* shared lib exports implemented without helpers in service_impl1.cxx */
namespace my_sc_impl
{
static struct ::cppu::ImplementationEntry s_component_entries [] =
{
{ // MyCounterImpl_create replaced by MyCounterImpl_createInstance 19/05/09
MyCounterImpl_createInstance, getImplementationName_MyCounterImpl,
getSupportedServiceNames_MyCounterImpl, ::cppu::createSingleComponentFactory,
0, 0
},
{ 0, 0, 0, 0, 0, 0 }
};
}
extern "C"
{
void SAL_CALL component_getImplementationEnvironment(
sal_Char const ** ppEnvTypeName, uno_Environment ** ppEnv )
{
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}
sal_Bool SAL_CALL component_writeInfo(
XMultiServiceFactory * xMgr, XRegistryKey * xRegistry )
{
return ::cppu::component_writeInfoHelper(
xMgr, xRegistry, ::my_sc_impl::s_component_entries );
}
void * SAL_CALL component_getFactory(
sal_Char const * implName, XMultiServiceFactory * xMgr,
XRegistryKey * xRegistry )
{
return ::cppu::component_getFactoryHelper(
implName, xMgr, xRegistry, ::my_sc_impl::s_component_entries );
}
}