Difference between revisions of "Calc/Add-In/CompleteAddIn"

From Apache OpenOffice Wiki
< Calc‎ | Add-In
Jump to: navigation, search
(The fourth method)
(The complete Code)
Line 105: Line 105:
 
The code is not complete with this four method. If you want to create a component you have to add code, if you want to make a scriptable component you still add more code and if you want to create an AddIn you have to add more.
 
The code is not complete with this four method. If you want to create a component you have to add code, if you want to make a scriptable component you still add more code and if you want to create an AddIn you have to add more.
  
==The complete Code==
+
==The XAddIn Interface==
 +
Every add-in have to implement the XAddIn interface. As usual it is described by an IDL file :
 +
<pre><nowiki>
 +
// IDL
 +
module com { module sun { module star { module sheet {
 +
interface XAddIn: com::sun::star::lang::XLocalizable
 +
{
 +
  string getProgrammaticFuntionName( [in] string aDisplayName );
 +
  string getDisplayFunctionName( [in] string aProgrammaticName );
 +
  string getFunctionDescription( [in] string aProgrammaticName );
 +
  string getDisplayArgumentName(
 +
  [in] string aProgrammaticFunctionName,
 +
  [in] long nArgument );
 +
  string getArgumentDescription(
 +
  [in] string aProgrammaticFunctionName,
 +
  [in] long nArgument );
 +
  string getProgrammaticCategoryName( [in] string aProgrammaticFunctionName );
 +
  string getDisplayCategoryName( [in] string aProgrammaticFunctionName );
 +
};
 +
}; }; }; };
 +
</nowiki></pre>
 +
The corresponding C++ code is given now without explanation (for the moment)
 +
<pre><nowiki>
 +
// 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 )
 +
{ // a nested if implementation would be better
 +
  OUString aProgName, aRet;
 +
  aProgName = aProgrammaticName;
 +
  if (aProgName.equalsAscii("methodOne")) aRet = OUString::createFromAscii("method1");
 +
  if (aProgName.equalsAscii("methodTwo")) aRet = OUString::createFromAscii("method2");
 +
  if (aProgName.equalsAscii("methodThree")) aRet = OUString::createFromAscii("method3");
 +
  if (aProgName.equalsAscii("methodFour")) aRet = OUString::createFromAscii("method4");
 +
  return aRet;
 +
}
 +
 
 +
OUString SAL_CALL MyService2Impl::getFunctionDescription( const OUString& aProgrammaticName ) throw( uno::RuntimeException )
 +
{ // a nested if implementation would be better
 +
  OUString aRet;
 +
  if (aProgrammaticName.equalsAscii("methodOne"))
 +
    aRet = OUString::createFromAscii("methodOne() : 1st try");
 +
  if (aProgrammaticName.equalsAscii("methodTwo"))
 +
    aRet = OUString::createFromAscii("methodTwo() : 1st try");
 +
  if (aProgrammaticName.equalsAscii("methodThree"))
 +
    aRet = OUString::createFromAscii("methodThree() : 1st try");
 +
  return aRet;
 +
}
 +
 
 +
OUString SAL_CALL MyService2Impl::getDisplayArgumentName(
 +
const OUString& aProgrammaticName, sal_Int32 nArgument ) throw( uno::RuntimeException )
 +
{
 +
  OUString aRet;
 +
  if (aProgrammaticName.equalsAscii("methodOne")||aProgrammaticName.equalsAscii("methodTwo"))
 +
    aRet = OUString::createFromAscii("a string");
 +
  if (aProgrammaticName.equalsAscii("methodThree")||aProgrammaticName.equalsAscii("methodFour"))
 +
    aRet = OUString::createFromAscii("a Cell Range");
 +
  return aRet;
 +
}
 +
 
 +
OUString SAL_CALL MyService2Impl::getArgumentDescription(
 +
const OUString& aProgrammaticName, sal_Int32 nArgument ) throw( uno::RuntimeException )
 +
{
 +
  OUString aRet;
 +
  if (aProgrammaticName.equalsAscii("methodOne")||aProgrammaticName.equalsAscii("methodTwo"))
 +
    aRet = OUString::createFromAscii("method1/2:a string or a cell with a string is required");
 +
  if (aProgrammaticName.equalsAscii("methodThree")||aProgrammaticName.equalsAscii("methodFour"))
 +
    aRet = OUString::createFromAscii("method3/4:a cell range is required");
 +
  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 );
 +
}
 +
</nowiki></pre>
  
 
==See also==
 
==See also==

Revision as of 16:30, 17 April 2006

We start from an example of SDK slightly modified :

<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/Components/CppComponent

This example contains two files but I only use one file (and one service).

IDL File

Here is the corresponding IDL file :

// IDL
#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 );
long methodThree( [in] sequence< sequence< long > > aValList );
sequence< sequence< long > > methodFour( [in] sequence< sequence< long > > aValList );
};
service MyService2
{
interface XSomething;
interface com::sun::star::lang::XInitialization;
interface com::sun::star::lang::XServiceName;
interface com::sun::star::sheet::XAddIn;
};
};

Four method named methodOne, methodTwo, methodThree and methodFour will be implemented.

Implementing in C++ the four methods

We first give the C++ code of the four method presented in IDL file.

The two first Methods

The two first methods are similar :

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;
}

They only take a string (from a OOoCalc Cell) and add a message and put all the message+string in the result cell.

The third Method

The third method is more complicated : it returns a value calculed from a cell range (the sum).

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;
}

The fourth Method

The goal of the fourth method is to show how we can implement a matrix function : starting from a cell range and obtaining a celle range.

//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;
}

What is done by this example is not great : only add four to every cells of the cell range. The code is not complete with this four method. If you want to create a component you have to add code, if you want to make a scriptable component you still add more code and if you want to create an AddIn you have to add more.

The XAddIn Interface

Every add-in have to implement the XAddIn interface. As usual it is described by an IDL file :

// IDL
module com { module sun { module star { module sheet {
interface XAddIn: com::sun::star::lang::XLocalizable
{
  string getProgrammaticFuntionName( [in] string aDisplayName );
  string getDisplayFunctionName( [in] string aProgrammaticName );
  string getFunctionDescription( [in] string aProgrammaticName );
  string getDisplayArgumentName(
  [in] string aProgrammaticFunctionName,
  [in] long nArgument );
  string getArgumentDescription(
  [in] string aProgrammaticFunctionName,
  [in] long nArgument );
  string getProgrammaticCategoryName( [in] string aProgrammaticFunctionName );
  string getDisplayCategoryName( [in] string aProgrammaticFunctionName );
};
}; }; }; };

The corresponding C++ code is given now without explanation (for the moment)

// 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 )
{ // a nested if implementation would be better
  OUString aProgName, aRet;
  aProgName = aProgrammaticName;
  if (aProgName.equalsAscii("methodOne")) aRet = OUString::createFromAscii("method1");
  if (aProgName.equalsAscii("methodTwo")) aRet = OUString::createFromAscii("method2");
  if (aProgName.equalsAscii("methodThree")) aRet = OUString::createFromAscii("method3");
  if (aProgName.equalsAscii("methodFour")) aRet = OUString::createFromAscii("method4");
  return aRet;
}

OUString SAL_CALL MyService2Impl::getFunctionDescription( const OUString& aProgrammaticName ) throw( uno::RuntimeException )
{ // a nested if implementation would be better
  OUString aRet;
  if (aProgrammaticName.equalsAscii("methodOne"))
    aRet = OUString::createFromAscii("methodOne() : 1st try");
  if (aProgrammaticName.equalsAscii("methodTwo"))
    aRet = OUString::createFromAscii("methodTwo() : 1st try");
  if (aProgrammaticName.equalsAscii("methodThree"))
    aRet = OUString::createFromAscii("methodThree() : 1st try");
  return aRet;
}

OUString SAL_CALL MyService2Impl::getDisplayArgumentName(
const OUString& aProgrammaticName, sal_Int32 nArgument ) throw( uno::RuntimeException )
{
  OUString aRet;
  if (aProgrammaticName.equalsAscii("methodOne")||aProgrammaticName.equalsAscii("methodTwo"))
    aRet = OUString::createFromAscii("a string");
  if (aProgrammaticName.equalsAscii("methodThree")||aProgrammaticName.equalsAscii("methodFour"))
    aRet = OUString::createFromAscii("a Cell Range");
  return aRet;
}

OUString SAL_CALL MyService2Impl::getArgumentDescription(
const OUString& aProgrammaticName, sal_Int32 nArgument ) throw( uno::RuntimeException )
{
  OUString aRet;
  if (aProgrammaticName.equalsAscii("methodOne")||aProgrammaticName.equalsAscii("methodTwo"))
    aRet = OUString::createFromAscii("method1/2:a string or a cell with a string is required");
  if (aProgrammaticName.equalsAscii("methodThree")||aProgrammaticName.equalsAscii("methodFour"))
    aRet = OUString::createFromAscii("method3/4:a cell range is required");
  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 );
}

See also

Personal tools