| View previous topic :: View next topic |
| Author |
Message |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
Posted: Sat Dec 31, 2005 12:29 pm Post subject: Add-In in C++ |
|
|
I finally carried out my first add-in in C++. This code is a draft but I hope to do beter in the futur.
I posted my first component in July 2004 and since this day I have anounced an add-in in C++ many times. If I only achieve this add-in today it's only because there is no example of add-in in the SDK (only in Java). We can find one example only in OOo source code but this example is a big one. I wanted only doing a very simple example and I didn't know if the makefile of a component is working for an add-in. The answer is YES it works.
I started from an example of SDK slightly modified :
<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/Components/CppComponent
I use only one file instead two for the example.
Here is the corresponding IDL file :
| Code: |
#include <com/sun/star/uno/XInterface.idl>
#include <com/sun/star/lang/XInitialization.idl>
#include <com/sun/star/lang/XServiceName.idl>
#include <com/sun/star/lang/XLocalizable.idl>
#include <com/sun/star/sheet/XAddIn.idl>
module my_module
{
interface XSomething : com::sun::star::uno::XInterface
{
string methodOne( [in] string val );
string methodTwo( [in] string val );
};
service MyService2
{
interface XSomething;
interface com::sun::star::lang::XInitialization;
interface com::sun::star::lang::XServiceName;
interface com::sun::star::sheet::XAddIn;
};
};
|
Here is the corresponding C++ code (service2_impl.cxx)
| Code: |
//C++
#include <cppuhelper/implbase5.hxx> // "5" implementing five interfaces
#include <cppuhelper/factory.hxx>
#include <cppuhelper/implementationentry.hxx>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/lang/XServiceName.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/sheet/XAddIn.hpp>
#include <com/sun/star/lang/XLocalizable.hpp>
#include <my_module/XSomething.hpp>
using namespace ::rtl; // for OUString
using namespace ::com::sun::star; // for odk interfaces
using namespace ::com::sun::star::uno; // for basic types
using namespace ::com::sun::star::sheet;
namespace my_sc_impl
{
static Sequence< OUString > getSupportedServiceNames_MyService2Impl()
{
static Sequence < OUString > *pNames = 0;
if( ! pNames )
{
// MutexGuard guard( Mutex::getGlobalMutex() );
if( !pNames )
{
static Sequence< OUString > seqNames(2);
seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("my_module.MyService2"));
seqNames.getArray()[1] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.AddIn"));
pNames = &seqNames;
}
}
return *pNames;
}
static OUString getImplementationName_MyService2Impl()
{
static OUString *pImplName = 0;
if( ! pImplName )
{
// MutexGuard guard( Mutex::getGlobalMutex() );
if( ! pImplName )
{
static OUString implName( RTL_CONSTASCII_USTRINGPARAM("my_module.my_sc_implementation.MyService2") );
pImplName = &implName;
}
}
return *pImplName;
}
class MyService2Impl : public ::cppu::WeakImplHelper5<
::my_module::XSomething, lang::XServiceInfo, lang::XInitialization, lang::XServiceName,
XAddIn>
{
OUString m_arg;
public:
// focus on five given interfaces,
// no need to implement XInterface, XTypeProvider, XWeak, XAddin and XServiceName
// XInitialization will be called upon createInstanceWithArguments[AndContext]()
virtual void SAL_CALL initialize( Sequence< Any > const & args )
throw (Exception);
// XSomething
virtual OUString SAL_CALL methodOne( OUString const & str )
throw (RuntimeException);
virtual OUString SAL_CALL methodTwo( OUString const & str )
throw (RuntimeException);
// XServiceName
virtual OUString SAL_CALL getServiceName() throw( uno::RuntimeException );
// XServiceInfo
virtual OUString SAL_CALL getImplementationName()
throw (RuntimeException);
virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName )
throw (RuntimeException);
virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
throw (RuntimeException);
// XAddIn
virtual OUString SAL_CALL getProgrammaticFuntionName( const OUString& aDisplayName ) throw( uno::RuntimeException );
virtual OUString SAL_CALL getDisplayFunctionName( const OUString& aProgrammaticName ) throw( uno::RuntimeException );
virtual OUString SAL_CALL getFunctionDescription( const OUString& aProgrammaticName ) throw( uno::RuntimeException );
virtual OUString SAL_CALL getDisplayArgumentName(
const OUString& aProgrammaticName, sal_Int32 nArgument ) throw( uno::RuntimeException );
virtual OUString SAL_CALL getArgumentDescription(
const OUString& aProgrammaticName, sal_Int32 nArgument ) throw( uno::RuntimeException );
virtual OUString SAL_CALL getProgrammaticCategoryName(
const OUString& aProgrammaticName ) throw( uno::RuntimeException );
virtual OUString SAL_CALL getDisplayCategoryName(
const OUString& aProgrammaticName ) throw( uno::RuntimeException );
// XLocalizable
virtual void SAL_CALL MyService2Impl::setLocale( const lang::Locale& eLocale ) throw( uno::RuntimeException );
virtual lang::Locale SAL_CALL MyService2Impl::getLocale() throw( uno::RuntimeException );
};
// XInitialization implemention
void MyService2Impl::initialize( Sequence< Any > const & args )
throw (Exception)
{
if (1 != args.getLength())
{
throw lang::IllegalArgumentException(
OUString( RTL_CONSTASCII_USTRINGPARAM("give a string instanciating this component!") ),
(::cppu::OWeakObject *)this, // resolve to XInterface reference
0 ); // argument pos
}
if (! (args[ 0 ] >>= m_arg))
{
throw lang::IllegalArgumentException(
OUString( RTL_CONSTASCII_USTRINGPARAM("no string given as argument!") ),
(::cppu::OWeakObject *)this, // resolve to XInterface reference
0 ); // argument pos
}
}
// XServiceName
OUString SAL_CALL MyService2Impl::getServiceName() throw( uno::RuntimeException )
{
// name of specific AddIn service
return OUString::createFromAscii( "my_module.MyService2" );
}
// XSomething implementation
OUString MyService2Impl::methodOne( OUString const & str )
throw (RuntimeException)
{
return OUString( RTL_CONSTASCII_USTRINGPARAM(
"called methodOne() of MyService2 implementation: ") ) + m_arg + str;
}
OUString MyService2Impl::methodTwo( OUString const & str )
throw (RuntimeException)
{
return OUString( RTL_CONSTASCII_USTRINGPARAM(
"called methodTwo() of MyService2 implementation: ") ) + m_arg + str;
}
// XAddIn
OUString SAL_CALL MyService2Impl::getProgrammaticFuntionName( const OUString& aDisplayName ) throw( uno::RuntimeException )
{
// not used by calc
// (but should be implemented for other uses of the AddIn service)
return OUString();
}
OUString SAL_CALL MyService2Impl::getDisplayFunctionName( const OUString& aProgrammaticName ) throw( uno::RuntimeException )
{
OUString aRet( RTL_CONSTASCII_USTRINGPARAM("methodOne"));
return aRet;
}
OUString SAL_CALL MyService2Impl::getFunctionDescription( const OUString& aProgrammaticName ) throw( uno::RuntimeException )
{
OUString aRet( RTL_CONSTASCII_USTRINGPARAM("methodOne() : un 1er essai"));
return aRet;
}
OUString SAL_CALL MyService2Impl::getDisplayArgumentName(
const OUString& aProgrammaticName, sal_Int32 nArgument ) throw( uno::RuntimeException )
{
OUString aRet( RTL_CONSTASCII_USTRINGPARAM("Une chaine"));
return aRet;
}
OUString SAL_CALL MyService2Impl::getArgumentDescription(
const OUString& aProgrammaticName, sal_Int32 nArgument ) throw( uno::RuntimeException )
{
OUString aRet( RTL_CONSTASCII_USTRINGPARAM("Une chaine de caracteres"));
return aRet;
}
OUString SAL_CALL MyService2Impl::getProgrammaticCategoryName(
const OUString& aProgrammaticName ) throw( uno::RuntimeException )
{
OUString aRet( RTL_CONSTASCII_USTRINGPARAM("Add-In"));
return aRet;
}
OUString SAL_CALL MyService2Impl::getDisplayCategoryName(
const OUString& aProgrammaticName ) throw( uno::RuntimeException )
{
return getProgrammaticCategoryName( aProgrammaticName );
}
// XServiceInfo implementation
OUString MyService2Impl::getImplementationName()
throw (RuntimeException)
{
// unique implementation name
return OUString( RTL_CONSTASCII_USTRINGPARAM("my_module.my_sc_impl.MyService2") );
}
sal_Bool MyService2Impl::supportsService( OUString const & serviceName )
throw (RuntimeException)
{
// this object only supports one service, so the test is simple
// modified *********
if (serviceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("my_module.MyService2") ))
return true;
if (serviceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.sheet.AddIn") ))
return true;
else return false;
}
Sequence< OUString > MyService2Impl::getSupportedServiceNames()
throw (RuntimeException)
{
return getSupportedServiceNames_MyService2Impl();
}
Reference< XInterface > SAL_CALL create_MyService2Impl(
Reference< XComponentContext > const & xContext )
SAL_THROW( () )
{
return static_cast< lang::XTypeProvider * >( new MyService2Impl() );
}
// XLocalizable
void SAL_CALL MyService2Impl::setLocale( const lang::Locale& eLocale ) throw( uno::RuntimeException )
{
}
lang::Locale SAL_CALL MyService2Impl::getLocale() throw( uno::RuntimeException )
{
}
}
/* shared lib exports implemented without helpers in service_impl1.cxx */
namespace my_sc_impl
{
static struct ::cppu::ImplementationEntry s_component_entries [] =
{
{
create_MyService2Impl, getImplementationName_MyService2Impl,
getSupportedServiceNames_MyService2Impl, ::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(
lang::XMultiServiceFactory * xMgr, registry::XRegistryKey * xRegistry )
{
return ::cppu::component_writeInfoHelper(
xMgr, xRegistry, ::my_sc_impl::s_component_entries );
}
void * SAL_CALL component_getFactory(
sal_Char const * implName, lang::XMultiServiceFactory * xMgr,
registry::XRegistryKey * xRegistry )
{
return ::cppu::component_getFactoryHelper(
implName, xMgr, xRegistry, ::my_sc_impl::s_component_entries );
}
}
|
You have only to simplify the makefile (because you only use one C++ code file and you will see your add-in in the add-In cathegory of OOoCalc.
I have said it's a draft because I see two times methodone. For the moment I don't see why. But it's 21:28 here and my wife wait for me. Sorry this evening is particular and I have no time to go further.
Happy New year
eric ehlers has writen add-ins here : http://quantlib.org/quantlibaddin/ (QuantLibAddin) _________________ Linux & Windows OOo3.0
UNO & C++ : WIKI
http://wiki.services.openoffice.org/wiki/Using_Cpp_with_the_OOo_SDK
In French
http://wiki.services.openoffice.org/wiki/Documentation/FR/Cpp_Guide
Last edited by SergeM on Fri Jan 20, 2006 2:25 pm; edited 1 time in total |
|
| Back to top |
|
 |
LarsB OOo Advocate


Joined: 31 Aug 2005 Posts: 445 Location: Hamburg, Germany
|
Posted: Sun Jan 01, 2006 3:28 am Post subject: Cool work |
|
|
Hi,
cool work. I think a really good library for OpenOffice Add in development
is something that is really missed. I believe, if such a library would exist,
we would see a lot if nice Add Ins for OO
| Quote: | | But it's 21:28 here and my wife wait for me. Sorry this evening is particular and I have no time to go further. |
Funny, I was forced by my girlfriend to turn off at ~20:00 and to avoid trouble I followed here advice
Cheers
LarsB _________________ AODC - A free OpenDocument Converter
AODL - An independent OpenDocument Library C#
EmbeddedOpenOffice .net UserControl C#
EmbeddedOpenOffice Visual Studio .net Add In
http://www.OpenDocument4all.com/ |
|
| Back to top |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
|
| Back to top |
|
 |
LarsB OOo Advocate


Joined: 31 Aug 2005 Posts: 445 Location: Hamburg, Germany
|
Posted: Tue Jan 03, 2006 8:36 am Post subject: Thanks |
|
|
Hi,
thanks for the picture and the additional info. Currently I'm really busy, because
I'm working on the next releases of AODL and AODC., but after I finished these
I guess I will play a little bit with the add in possibilities
Cheers
LarsB _________________ AODC - A free OpenDocument Converter
AODL - An independent OpenDocument Library C#
EmbeddedOpenOffice .net UserControl C#
EmbeddedOpenOffice Visual Studio .net Add In
http://www.OpenDocument4all.com/ |
|
| Back to top |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
|
| Back to top |
|
 |
LarsB OOo Advocate


Joined: 31 Aug 2005 Posts: 445 Location: Hamburg, Germany
|
Posted: Fri Jan 06, 2006 12:28 am Post subject: C# add in possible |
|
|
Hi SergeM,
I mean this in generally, but it would be great if writing add ins in C# would be possible.
Cheers
LarsB _________________ AODC - A free OpenDocument Converter
AODL - An independent OpenDocument Library C#
EmbeddedOpenOffice .net UserControl C#
EmbeddedOpenOffice Visual Studio .net Add In
http://www.OpenDocument4all.com/ |
|
| Back to top |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
|
| Back to top |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
Posted: Sat Jan 07, 2006 1:26 pm Post subject: |
|
|
First correction of the addin to see two different methods.
Replace
| Code: |
OUString SAL_CALL MyService2Impl::getDisplayFunctionName( const OUString& aProgrammaticName ) throw( uno::RuntimeException )
{
OUString aRet( RTL_CONSTASCII_USTRINGPARAM("methodOne"));
return aRet;
}
|
by
| Code: |
OUString SAL_CALL MyService2Impl::getDisplayFunctionName( const OUString& aProgrammaticName ) throw( uno::RuntimeException )
{
OUString aProgName, aRet;
aProgName = aProgrammaticName;
if (aProgName.equalsAscii("methodOne")) aRet = OUString::createFromAscii("method1");
if (aProgName.equalsAscii("methodTwo")) aRet = OUString::createFromAscii("method2");
return aRet;
}
|
and you will see METHOD1 and METHOD2 in the Functions Autopilot. _________________ Linux & Windows OOo3.0
UNO & C++ : WIKI
http://wiki.services.openoffice.org/wiki/Using_Cpp_with_the_OOo_SDK
In French
http://wiki.services.openoffice.org/wiki/Documentation/FR/Cpp_Guide
Last edited by SergeM on Fri Jan 13, 2006 1:14 pm; edited 1 time in total |
|
| Back to top |
|
 |
LarsB OOo Advocate


Joined: 31 Aug 2005 Posts: 445 Location: Hamburg, Germany
|
Posted: Mon Jan 09, 2006 7:29 am Post subject: Thanks for your reply |
|
|
Hi SergeM,
Thanks for your reply. I will try it out as soon as possible and if it's possible I will post it into the forum
Cheers
LarsB _________________ AODC - A free OpenDocument Converter
AODL - An independent OpenDocument Library C#
EmbeddedOpenOffice .net UserControl C#
EmbeddedOpenOffice Visual Studio .net Add In
http://www.OpenDocument4all.com/ |
|
| Back to top |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
Posted: Fri Jan 13, 2006 1:18 pm Post subject: |
|
|
And now i have understood what "const OUString& aProgrammaticName" parameter is the other corrections are :
| Code: |
OUString SAL_CALL MyService2Impl::getFunctionDescription( const OUString& aProgrammaticName ) throw( uno::RuntimeException )
{
OUString aRet;
if (aProgrammaticName.equalsAscii("methodOne"))
aRet = OUString::createFromAscii("methodOne() : 1st try");
if (aProgrammaticName.equalsAscii("methodTwo"))
aRet = OUString::createFromAscii("methodTwo() : 1st try");
return aRet;
}
OUString SAL_CALL MyService2Impl::getDisplayArgumentName(
const OUString& aProgrammaticName, sal_Int32 nArgument ) throw( uno::RuntimeException )
{
OUString aRet;
if (aProgrammaticName.equalsAscii("methodOne"))
aRet = OUString::createFromAscii("a string");
if (aProgrammaticName.equalsAscii("methodTwo"))
aRet = OUString::createFromAscii("a string");
return aRet;
}
OUString SAL_CALL MyService2Impl::getArgumentDescription(
const OUString& aProgrammaticName, sal_Int32 nArgument ) throw( uno::RuntimeException )
{
OUString aRet;
if (aProgrammaticName.equalsAscii("methodOne"))
aRet = OUString::createFromAscii("method1:a string or a cell with a string is required");
if (aProgrammaticName.equalsAscii("methodTwo"))
aRet = OUString::createFromAscii("method2:a string or a cell with a string is required");
return aRet;
}
|
I think now all is OK. It only stays Internationalization to do ... _________________ Linux & Windows OOo3.0
UNO & C++ : WIKI
http://wiki.services.openoffice.org/wiki/Using_Cpp_with_the_OOo_SDK
In French
http://wiki.services.openoffice.org/wiki/Documentation/FR/Cpp_Guide |
|
| Back to top |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
Posted: Sat Jan 21, 2006 8:40 am Post subject: |
|
|
I have added two functions to see how things work.
I was interested to do something with sequence of sequence. Here is the IDL file.
| Code: |
interface XSomething : com::sun::star::uno::XInterface
{
string methodOne( [in] string val );
string methodTwo( [in] string val );
long methodThree( [in] sequence< sequence< long > > aValList );
sequence< sequence< long > > methodFour( [in] sequence< sequence< long > > aValList );
};
|
I give only the C++ code of the new methods :
| Code: |
sal_Int32 MyService2Impl::methodThree(const Sequence< Sequence< sal_Int32 > > &aValList )
throw (RuntimeException)
{ sal_Int32 n1, n2;
sal_Int32 nE1 = aValList.getLength();
sal_Int32 nE2;
sal_Int32 temp=0;
for( n1 = 0 ; n1 < nE1 ; n1++ )
{
const Sequence< sal_Int32 > rList = aValList[ n1 ];
nE2 = rList.getLength();
const sal_Int32* pList = rList.getConstArray();
for( n2 = 0 ; n2 < nE2 ; n2++ )
{
temp += pList[ n2 ];
}
}
return temp;
}
//It's a matrix operation should be called like : {=METHODFOUR(A1:B4)}
Sequence< Sequence< sal_Int32 > > MyService2Impl::methodFour(
const Sequence< Sequence< sal_Int32 > > &aValList )throw (RuntimeException)
{ sal_Int32 n1, n2;
sal_Int32 nE1 = aValList.getLength();
sal_Int32 nE2;
Sequence< Sequence< sal_Int32 > > temp = aValList;
for( n1 = 0 ; n1 < nE1 ; n1++ )
{
Sequence< sal_Int32 > rList = temp[ n1 ];
nE2 = rList.getLength();
for( n2 = 0 ; n2 < nE2 ; n2++ )
{
rList[ n2 ] += 4;
}
temp[n1]=rList;
}
return temp;
}
|
The methodthree is only an example which return the sum of all the cells of a cell range.
As mentioned in comment the methodfour is a matrix operation : it only add 4 to every cell of a cell range. _________________ Linux & Windows OOo3.0
UNO & C++ : WIKI
http://wiki.services.openoffice.org/wiki/Using_Cpp_with_the_OOo_SDK
In French
http://wiki.services.openoffice.org/wiki/Documentation/FR/Cpp_Guide |
|
| Back to top |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
|
| Back to top |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
|
| Back to top |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3211 Location: Troyes France
|
|
| Back to top |
|
 |
|