2011-01-11 22:18:52 +01:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
|
|
/*************************************************************************
|
|
|
|
*
|
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
*
|
|
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
|
|
*
|
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
|
|
*
|
|
|
|
* This file is part of OpenOffice.org.
|
|
|
|
*
|
|
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
|
|
* only, as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Lesser General Public License version 3 for more details
|
|
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
|
|
* <http://www.openoffice.org/license.html>
|
|
|
|
* for a copy of the LGPLv3 License.
|
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
#include "funcdesc.hxx"
|
|
|
|
|
|
|
|
#include "addincol.hxx"
|
|
|
|
#include "appoptio.hxx"
|
|
|
|
#include "callform.hxx"
|
|
|
|
#include "compiler.hxx"
|
|
|
|
#include "global.hxx"
|
|
|
|
#include "sc.hrc"
|
|
|
|
#include "scmod.hxx"
|
|
|
|
#include "scresid.hxx"
|
|
|
|
|
|
|
|
#include <rtl/ustring.hxx>
|
|
|
|
#include <rtl/ustrbuf.hxx>
|
|
|
|
#include <tools/list.hxx>
|
|
|
|
#include <tools/rcid.h>
|
|
|
|
#include <tools/resid.hxx>
|
|
|
|
#include <tools/string.hxx>
|
|
|
|
#include <unotools/collatorwrapper.hxx>
|
|
|
|
|
|
|
|
#include <numeric>
|
|
|
|
|
|
|
|
class ScFuncRes : public Resource
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ScFuncRes( ResId&, ScFuncDesc*, bool & rbSuppressed );
|
|
|
|
|
|
|
|
private:
|
2011-01-16 23:05:25 +01:00
|
|
|
sal_uInt16 GetNum();
|
2011-01-11 22:18:52 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class ScResourcePublisher : public Resource
|
|
|
|
{
|
|
|
|
private:
|
2011-01-16 23:05:25 +01:00
|
|
|
void FreeResource() { Resource::FreeResource(); }
|
2011-01-11 22:18:52 +01:00
|
|
|
public:
|
2011-01-16 23:05:25 +01:00
|
|
|
ScResourcePublisher( const ScResId& rId ) : Resource( rId ) {}
|
|
|
|
~ScResourcePublisher() { FreeResource(); }
|
|
|
|
bool IsAvailableRes( const ResId& rId ) const
|
2011-01-11 22:18:52 +01:00
|
|
|
{ return Resource::IsAvailableRes( rId ); }
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
// class ScFuncDesc:
|
2011-01-23 18:47:48 +01:00
|
|
|
//========================================================================
|
2011-01-11 22:18:52 +01:00
|
|
|
|
|
|
|
ScFuncDesc::ScFuncDesc() :
|
|
|
|
pFuncName (NULL),
|
|
|
|
pFuncDesc (NULL),
|
|
|
|
ppDefArgNames (NULL),
|
|
|
|
ppDefArgDescs (NULL),
|
|
|
|
pDefArgFlags (NULL),
|
|
|
|
nFIndex (0),
|
|
|
|
nCategory (0),
|
|
|
|
nArgCount (0),
|
|
|
|
nHelpId (0),
|
|
|
|
bIncomplete (false),
|
|
|
|
bHasSuppressedArgs(false)
|
|
|
|
{}
|
|
|
|
|
|
|
|
ScFuncDesc::~ScFuncDesc()
|
|
|
|
{
|
|
|
|
Clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScFuncDesc::Clear()
|
|
|
|
{
|
|
|
|
sal_uInt16 nArgs = nArgCount;
|
|
|
|
if (nArgs >= VAR_ARGS) nArgs -= VAR_ARGS-1;
|
|
|
|
if (nArgs)
|
|
|
|
{
|
|
|
|
for (sal_uInt16 i=0; i<nArgs; i++ )
|
|
|
|
{
|
|
|
|
delete ppDefArgNames[i];
|
|
|
|
delete ppDefArgDescs[i];
|
|
|
|
}
|
|
|
|
delete [] ppDefArgNames;
|
|
|
|
delete [] ppDefArgDescs;
|
|
|
|
delete [] pDefArgFlags;
|
|
|
|
}
|
|
|
|
nArgCount = 0;
|
|
|
|
ppDefArgNames = NULL;
|
|
|
|
ppDefArgDescs = NULL;
|
|
|
|
pDefArgFlags = NULL;
|
|
|
|
|
|
|
|
delete pFuncName;
|
|
|
|
pFuncName = NULL;
|
|
|
|
|
|
|
|
delete pFuncDesc;
|
|
|
|
pFuncDesc = NULL;
|
|
|
|
|
|
|
|
nFIndex = 0;
|
|
|
|
nCategory = 0;
|
|
|
|
nHelpId = 0;
|
|
|
|
bIncomplete = false;
|
|
|
|
bHasSuppressedArgs = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
::rtl::OUString ScFuncDesc::GetParamList() const
|
|
|
|
{
|
|
|
|
::rtl::OUString sep(ScCompiler::GetNativeSymbol(ocSep));
|
|
|
|
|
|
|
|
::rtl::OUStringBuffer aSig;
|
|
|
|
|
|
|
|
if ( nArgCount > 0 )
|
|
|
|
{
|
|
|
|
if ( nArgCount < VAR_ARGS )
|
|
|
|
{
|
|
|
|
sal_uInt16 nLastSuppressed = nArgCount;
|
|
|
|
sal_uInt16 nLastAdded = nArgCount;
|
|
|
|
for ( sal_uInt16 i=0; i<nArgCount; i++ )
|
|
|
|
{
|
|
|
|
if (pDefArgFlags[i].bSuppress)
|
|
|
|
nLastSuppressed = i;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nLastAdded = i;
|
|
|
|
aSig.append(*(ppDefArgNames[i]));
|
|
|
|
if ( i != nArgCount-1 )
|
|
|
|
{
|
|
|
|
aSig.append(sep);
|
|
|
|
aSig.appendAscii( " " );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// If only suppressed parameters follow the last added parameter,
|
|
|
|
// remove one "; "
|
|
|
|
if (nLastSuppressed < nArgCount && nLastAdded < nLastSuppressed &&
|
|
|
|
aSig.getLength() >= 2)
|
|
|
|
aSig.setLength(aSig.getLength() - 2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sal_uInt16 nFix = nArgCount - VAR_ARGS;
|
|
|
|
for ( sal_uInt16 nArg = 0; nArg < nFix; nArg++ )
|
|
|
|
{
|
|
|
|
if (!pDefArgFlags[nArg].bSuppress)
|
|
|
|
{
|
|
|
|
aSig.append(*(ppDefArgNames[nArg]));
|
|
|
|
aSig.append(sep);
|
|
|
|
aSig.appendAscii( " " );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* NOTE: Currently there are no suppressed var args parameters. If
|
|
|
|
* there were, we'd have to cope with it here and above for the fix
|
|
|
|
* parameters. For now parameters are always added, so no special
|
|
|
|
* treatment of a trailing "; " necessary. */
|
|
|
|
aSig.append(*(ppDefArgNames[nFix]));
|
|
|
|
aSig.append(sal_Unicode('1'));
|
|
|
|
aSig.append(sep);
|
|
|
|
aSig.append(sal_Unicode(' '));
|
|
|
|
aSig.append(*(ppDefArgNames[nFix]));
|
|
|
|
aSig.append(sal_Unicode('2'));
|
|
|
|
aSig.append(sep);
|
|
|
|
aSig.appendAscii(" ... ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return aSig.makeStringAndClear();
|
|
|
|
}
|
|
|
|
|
|
|
|
::rtl::OUString ScFuncDesc::getSignature() const
|
|
|
|
{
|
|
|
|
::rtl::OUStringBuffer aSig;
|
|
|
|
|
|
|
|
if(pFuncName)
|
|
|
|
{
|
|
|
|
aSig.append(*pFuncName);
|
|
|
|
|
|
|
|
::rtl::OUString aParamList = GetParamList();
|
|
|
|
if( aParamList.getLength() )
|
|
|
|
{
|
|
|
|
aSig.appendAscii( "( " );
|
|
|
|
aSig.append(aParamList);
|
|
|
|
// U+00A0 (NBSP) prevents automatic line break
|
|
|
|
aSig.append( static_cast< sal_Unicode >(0xA0) );
|
|
|
|
aSig.appendAscii( ")" );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
aSig.appendAscii( "()" );
|
|
|
|
}
|
|
|
|
return aSig.makeStringAndClear();
|
|
|
|
}
|
|
|
|
|
|
|
|
::rtl::OUString ScFuncDesc::getFormula( const ::std::vector< ::rtl::OUString >& _aArguments ) const
|
|
|
|
{
|
2011-01-18 09:43:17 -05:00
|
|
|
::rtl::OUString sep = ScCompiler::GetNativeSymbol(ocSep);
|
2011-01-11 22:18:52 +01:00
|
|
|
|
|
|
|
::rtl::OUStringBuffer aFormula;
|
|
|
|
|
|
|
|
if(pFuncName)
|
|
|
|
{
|
|
|
|
aFormula.append( *pFuncName );
|
|
|
|
|
|
|
|
aFormula.appendAscii( "(" );
|
|
|
|
::std::vector< ::rtl::OUString >::const_iterator aIter = _aArguments.begin();
|
|
|
|
::std::vector< ::rtl::OUString >::const_iterator aEnd = _aArguments.end();
|
|
|
|
|
|
|
|
if ( nArgCount > 0 && aIter != aEnd )
|
|
|
|
{
|
2011-01-16 23:05:25 +01:00
|
|
|
bool bLastArg = ( aIter->getLength() == 0 );
|
2011-01-11 22:18:52 +01:00
|
|
|
|
|
|
|
while( aIter != aEnd && !bLastArg )
|
|
|
|
{
|
|
|
|
aFormula.append( *(aIter) );
|
|
|
|
if ( aIter != (aEnd-1) )
|
|
|
|
{
|
|
|
|
bLastArg = !( (aIter+1)->getLength() > 0 );
|
|
|
|
if ( !bLastArg )
|
|
|
|
aFormula.append( sep );
|
|
|
|
}
|
|
|
|
|
|
|
|
++aIter;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
aFormula.appendAscii( ")" );
|
|
|
|
}
|
|
|
|
return aFormula.makeStringAndClear();
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_uInt16 ScFuncDesc::GetSuppressedArgCount() const
|
|
|
|
{
|
|
|
|
if (!bHasSuppressedArgs || !pDefArgFlags)
|
|
|
|
return nArgCount;
|
|
|
|
|
|
|
|
sal_uInt16 nArgs = nArgCount;
|
|
|
|
if (nArgs >= VAR_ARGS)
|
|
|
|
nArgs -= VAR_ARGS - 1;
|
|
|
|
sal_uInt16 nCount = nArgs;
|
|
|
|
for (sal_uInt16 i=0; i < nArgs; ++i)
|
|
|
|
{
|
|
|
|
if (pDefArgFlags[i].bSuppress)
|
|
|
|
--nCount;
|
|
|
|
}
|
|
|
|
if (nArgCount >= VAR_ARGS)
|
|
|
|
nCount += VAR_ARGS - 1;
|
|
|
|
return nCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
::rtl::OUString ScFuncDesc::getFunctionName() const
|
|
|
|
{
|
|
|
|
::rtl::OUString sRet;
|
|
|
|
if ( pFuncName )
|
|
|
|
sRet = *pFuncName;
|
|
|
|
return sRet;
|
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
const formula::IFunctionCategory* ScFuncDesc::getCategory() const
|
|
|
|
{
|
|
|
|
return ScGlobal::GetStarCalcFunctionMgr()->getCategory(nCategory);
|
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
::rtl::OUString ScFuncDesc::getDescription() const
|
|
|
|
{
|
|
|
|
::rtl::OUString sRet;
|
|
|
|
if ( pFuncDesc )
|
|
|
|
sRet = *pFuncDesc;
|
|
|
|
return sRet;
|
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
xub_StrLen ScFuncDesc::getSuppressedArgumentCount() const
|
|
|
|
{
|
|
|
|
return GetSuppressedArgCount();
|
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
void ScFuncDesc::fillVisibleArgumentMapping(::std::vector<sal_uInt16>& _rArguments) const
|
|
|
|
{
|
|
|
|
if (!bHasSuppressedArgs || !pDefArgFlags)
|
|
|
|
{
|
|
|
|
_rArguments.resize( nArgCount);
|
|
|
|
::std::iota( _rArguments.begin(), _rArguments.end(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
_rArguments.reserve( nArgCount);
|
|
|
|
sal_uInt16 nArgs = nArgCount;
|
|
|
|
if (nArgs >= VAR_ARGS)
|
|
|
|
nArgs -= VAR_ARGS - 1;
|
|
|
|
for (sal_uInt16 i=0; i < nArgs; ++i)
|
|
|
|
{
|
|
|
|
if (!pDefArgFlags[i].bSuppress)
|
|
|
|
_rArguments.push_back(i);
|
|
|
|
}
|
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
void ScFuncDesc::initArgumentInfo() const
|
|
|
|
{
|
|
|
|
// get the full argument description
|
|
|
|
// (add-in has to be instantiated to get the type information)
|
|
|
|
|
|
|
|
if ( bIncomplete && pFuncName )
|
|
|
|
{
|
|
|
|
ScUnoAddInCollection& rAddIns = *ScGlobal::GetAddInCollection();
|
2011-01-16 23:05:25 +01:00
|
|
|
::rtl::OUString aIntName(rAddIns.FindFunction( *pFuncName, true )); // pFuncName is upper-case
|
2011-01-11 22:18:52 +01:00
|
|
|
|
2011-01-16 23:05:25 +01:00
|
|
|
if ( aIntName.getLength() )
|
2011-01-11 22:18:52 +01:00
|
|
|
{
|
|
|
|
// GetFuncData with bComplete=true loads the component and updates
|
|
|
|
// the global function list if needed.
|
|
|
|
|
|
|
|
rAddIns.GetFuncData( aIntName, true );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( bIncomplete )
|
|
|
|
{
|
|
|
|
DBG_ERRORFILE( "couldn't initialize add-in function" );
|
2011-01-16 23:05:25 +01:00
|
|
|
const_cast<ScFuncDesc*>(this)->bIncomplete = false; // even if there was an error, don't try again
|
2011-01-11 22:18:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
long ScFuncDesc::getHelpId() const
|
|
|
|
{
|
|
|
|
return (long)nHelpId;
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_uInt32 ScFuncDesc::getParameterCount() const
|
|
|
|
{
|
|
|
|
return nArgCount;
|
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
::rtl::OUString ScFuncDesc::getParameterName(sal_uInt32 _nPos) const
|
|
|
|
{
|
|
|
|
return *(ppDefArgNames[_nPos]);
|
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
::rtl::OUString ScFuncDesc::getParameterDescription(sal_uInt32 _nPos) const
|
|
|
|
{
|
|
|
|
return *(ppDefArgDescs[_nPos]);
|
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
bool ScFuncDesc::isParameterOptional(sal_uInt32 _nPos) const
|
|
|
|
{
|
|
|
|
return pDefArgFlags[_nPos].bOptional;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===================================================================
|
|
|
|
// class ScFunctionList:
|
|
|
|
//===================================================================
|
|
|
|
|
|
|
|
ScFunctionList::ScFunctionList() :
|
|
|
|
nMaxFuncNameLen ( 0 )
|
|
|
|
{
|
2011-01-16 23:05:25 +01:00
|
|
|
ScFuncDesc* pDesc = NULL;
|
|
|
|
xub_StrLen nStrLen = 0;
|
2011-01-11 22:18:52 +01:00
|
|
|
FuncCollection* pFuncColl;
|
2011-01-16 23:05:25 +01:00
|
|
|
sal_uInt16 nDescBlock[] =
|
2011-01-11 22:18:52 +01:00
|
|
|
{
|
|
|
|
RID_SC_FUNCTION_DESCRIPTIONS1,
|
|
|
|
RID_SC_FUNCTION_DESCRIPTIONS2
|
|
|
|
};
|
|
|
|
|
|
|
|
aFunctionList.Clear();
|
|
|
|
|
2011-01-18 09:43:17 -05:00
|
|
|
for (sal_uInt16 k = 0; k < SAL_N_ELEMENTS(nDescBlock); ++k)
|
2011-01-11 22:18:52 +01:00
|
|
|
{
|
|
|
|
::std::auto_ptr<ScResourcePublisher> pBlock( new ScResourcePublisher( ScResId( nDescBlock[k] ) ) );
|
|
|
|
// Browse for all possible OpCodes. This is not the fastest method, but
|
|
|
|
// otherwise the sub resources within the resource blocks and the
|
|
|
|
// resource blocks themselfs would had to be ordered according to
|
|
|
|
// OpCodes, which is utopian..
|
2011-01-18 09:43:17 -05:00
|
|
|
for (sal_uInt16 i = 0; i <= SC_OPCODE_LAST_OPCODE_ID; ++i)
|
2011-01-11 22:18:52 +01:00
|
|
|
{
|
|
|
|
ScResId aRes(i);
|
|
|
|
aRes.SetRT(RSC_RESOURCE);
|
|
|
|
// Sub resource of OpCode available?
|
|
|
|
if (pBlock->IsAvailableRes(aRes))
|
|
|
|
{
|
|
|
|
pDesc = new ScFuncDesc;
|
|
|
|
bool bSuppressed = false;
|
|
|
|
ScFuncRes aSubRes( aRes, pDesc, bSuppressed);
|
|
|
|
// Instead of dealing with this exceptional case at 1001 places
|
|
|
|
// we simply don't add an entirely suppressed function to the
|
|
|
|
// list and delete it.
|
|
|
|
if (bSuppressed)
|
|
|
|
delete pDesc;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pDesc->nFIndex = i;
|
|
|
|
aFunctionList.Insert( pDesc, LIST_APPEND );
|
|
|
|
|
|
|
|
nStrLen = (*(pDesc->pFuncName)).getLength();
|
|
|
|
if (nStrLen > nMaxFuncNameLen)
|
|
|
|
nMaxFuncNameLen = nStrLen;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-16 23:05:25 +01:00
|
|
|
sal_uInt16 nNextId = SC_OPCODE_LAST_OPCODE_ID + 1; // FuncID for AddIn functions
|
|
|
|
|
|
|
|
// Interpretation of AddIn list
|
2011-01-18 09:43:17 -05:00
|
|
|
::rtl::OUString aDefArgNameValue = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("value"));
|
|
|
|
::rtl::OUString aDefArgNameString = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("string"));
|
|
|
|
::rtl::OUString aDefArgNameValues = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("values"));
|
|
|
|
::rtl::OUString aDefArgNameStrings = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("strings"));
|
|
|
|
::rtl::OUString aDefArgNameCells = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cells"));
|
|
|
|
::rtl::OUString aDefArgNameNone = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("none"));
|
|
|
|
::rtl::OUString aDefArgDescValue = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("a value"));
|
|
|
|
::rtl::OUString aDefArgDescString = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("a string"));
|
|
|
|
::rtl::OUString aDefArgDescValues = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("array of values"));
|
|
|
|
::rtl::OUString aDefArgDescStrings = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("array of strings"));
|
|
|
|
::rtl::OUString aDefArgDescCells = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("range of cells"));
|
|
|
|
::rtl::OUString aDefArgDescNone = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("none"));
|
|
|
|
|
2011-01-16 23:05:25 +01:00
|
|
|
::rtl::OUString aArgName, aArgDesc;
|
2011-01-11 22:18:52 +01:00
|
|
|
pFuncColl = ScGlobal::GetFuncCollection();
|
2011-01-18 09:43:17 -05:00
|
|
|
for (sal_uInt16 i = 0; i < pFuncColl->GetCount(); ++i)
|
2011-01-11 22:18:52 +01:00
|
|
|
{
|
|
|
|
pDesc = new ScFuncDesc;
|
|
|
|
FuncData *pAddInFuncData = (FuncData*)pFuncColl->At(i);
|
2011-01-16 23:05:25 +01:00
|
|
|
sal_uInt16 nArgs = pAddInFuncData->GetParamCount() - 1;
|
|
|
|
pAddInFuncData->getParamDesc( aArgName, aArgDesc, 0 );
|
|
|
|
pDesc->nFIndex = nNextId++; // ??? OpCode vergeben
|
2011-01-11 22:18:52 +01:00
|
|
|
pDesc->nCategory = ID_FUNCTION_GRP_ADDINS;
|
|
|
|
pDesc->pFuncName = new ::rtl::OUString(pAddInFuncData->GetInternalName());
|
|
|
|
pDesc->pFuncName->toAsciiUpperCase();
|
|
|
|
|
|
|
|
::rtl::OUStringBuffer aBuf(aArgDesc);
|
|
|
|
aBuf.append(sal_Unicode('\n'));
|
|
|
|
aBuf.appendAscii("( AddIn: ");
|
|
|
|
aBuf.append(pAddInFuncData->GetModuleName());
|
|
|
|
aBuf.appendAscii(" )");
|
|
|
|
pDesc->pFuncDesc = new ::rtl::OUString(aBuf.makeStringAndClear());
|
|
|
|
|
|
|
|
pDesc->nArgCount = nArgs;
|
|
|
|
if (nArgs)
|
|
|
|
{
|
|
|
|
pDesc->pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgs];
|
|
|
|
pDesc->ppDefArgNames = new ::rtl::OUString*[nArgs];
|
|
|
|
pDesc->ppDefArgDescs = new ::rtl::OUString*[nArgs];
|
2011-01-18 09:43:17 -05:00
|
|
|
for (sal_uInt16 j = 0; j < nArgs; ++j)
|
2011-01-11 22:18:52 +01:00
|
|
|
{
|
|
|
|
pDesc->pDefArgFlags[j].bOptional = false;
|
|
|
|
pDesc->pDefArgFlags[j].bSuppress = false;
|
2011-01-16 23:05:25 +01:00
|
|
|
pAddInFuncData->getParamDesc( aArgName, aArgDesc, j+1 );
|
|
|
|
if ( aArgName.getLength() )
|
2011-01-11 22:18:52 +01:00
|
|
|
pDesc->ppDefArgNames[j] = new ::rtl::OUString( aArgName );
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (pAddInFuncData->GetParamType(j+1))
|
|
|
|
{
|
|
|
|
case PTR_DOUBLE:
|
|
|
|
pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameValue );
|
|
|
|
break;
|
|
|
|
case PTR_STRING:
|
|
|
|
pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameString );
|
|
|
|
break;
|
|
|
|
case PTR_DOUBLE_ARR:
|
|
|
|
pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameValues );
|
|
|
|
break;
|
|
|
|
case PTR_STRING_ARR:
|
|
|
|
pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameStrings );
|
|
|
|
break;
|
|
|
|
case PTR_CELL_ARR:
|
|
|
|
pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameCells );
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameNone );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-01-16 23:05:25 +01:00
|
|
|
if ( aArgDesc.getLength() )
|
2011-01-11 22:18:52 +01:00
|
|
|
pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aArgDesc );
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (pAddInFuncData->GetParamType(j+1))
|
|
|
|
{
|
|
|
|
case PTR_DOUBLE:
|
|
|
|
pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescValue );
|
|
|
|
break;
|
|
|
|
case PTR_STRING:
|
|
|
|
pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescString );
|
|
|
|
break;
|
|
|
|
case PTR_DOUBLE_ARR:
|
|
|
|
pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescValues );
|
|
|
|
break;
|
|
|
|
case PTR_STRING_ARR:
|
|
|
|
pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescStrings );
|
|
|
|
break;
|
|
|
|
case PTR_CELL_ARR:
|
|
|
|
pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescCells );
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescNone );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
aFunctionList.Insert(pDesc, LIST_APPEND);
|
|
|
|
nStrLen = (*(pDesc->pFuncName)).getLength();
|
|
|
|
if ( nStrLen > nMaxFuncNameLen)
|
|
|
|
nMaxFuncNameLen = nStrLen;
|
|
|
|
}
|
|
|
|
|
2011-01-16 23:05:25 +01:00
|
|
|
// StarOne AddIns
|
2011-01-11 22:18:52 +01:00
|
|
|
|
|
|
|
ScUnoAddInCollection* pUnoAddIns = ScGlobal::GetAddInCollection();
|
|
|
|
long nUnoCount = pUnoAddIns->GetFuncCount();
|
|
|
|
for (long nFunc=0; nFunc<nUnoCount; nFunc++)
|
|
|
|
{
|
|
|
|
pDesc = new ScFuncDesc;
|
|
|
|
pDesc->nFIndex = nNextId++;
|
|
|
|
|
|
|
|
if ( pUnoAddIns->FillFunctionDesc( nFunc, *pDesc ) )
|
|
|
|
{
|
|
|
|
aFunctionList.Insert(pDesc, LIST_APPEND);
|
|
|
|
nStrLen = (*(pDesc->pFuncName)).getLength();
|
|
|
|
if (nStrLen > nMaxFuncNameLen)
|
|
|
|
nMaxFuncNameLen = nStrLen;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
delete pDesc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ScFunctionList::~ScFunctionList()
|
|
|
|
{
|
|
|
|
const ScFuncDesc* pDesc = First();
|
|
|
|
while (pDesc)
|
|
|
|
{
|
|
|
|
delete pDesc;
|
|
|
|
pDesc = Next();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_uInt32 ScFunctionCategory::getCount() const
|
|
|
|
{
|
|
|
|
return m_pCategory->Count();
|
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
const formula::IFunctionManager* ScFunctionCategory::getFunctionManager() const
|
|
|
|
{
|
|
|
|
return m_pMgr;
|
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
::rtl::OUString ScFunctionCategory::getName() const
|
|
|
|
{
|
|
|
|
if ( !m_sName.getLength() )
|
|
|
|
m_sName = ScFunctionMgr::GetCategoryName(m_nCategory+1);
|
|
|
|
return m_sName;
|
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
const formula::IFunctionDescription* ScFunctionCategory::getFunction(sal_uInt32 _nPos) const
|
|
|
|
{
|
2011-01-16 23:05:25 +01:00
|
|
|
const ScFuncDesc* pDesc = NULL;
|
2011-01-11 22:18:52 +01:00
|
|
|
sal_uInt32 i = 0;
|
|
|
|
for (pDesc = (const ScFuncDesc*)m_pCategory->First(); i < _nPos && pDesc; pDesc = (const ScFuncDesc*)m_pCategory->Next(),++i)
|
|
|
|
;
|
|
|
|
return pDesc;
|
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
sal_uInt32 ScFunctionCategory::getNumber() const
|
|
|
|
{
|
|
|
|
return m_nCategory;
|
|
|
|
}
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
// class ScFunctionMgr:
|
2011-01-23 18:47:48 +01:00
|
|
|
//========================================================================
|
2011-01-11 22:18:52 +01:00
|
|
|
|
2011-01-18 09:43:17 -05:00
|
|
|
ScFunctionMgr::ScFunctionMgr() :
|
|
|
|
pFuncList( ScGlobal::GetStarCalcFunctionList() ),
|
|
|
|
pCurCatList( NULL )
|
2011-01-11 22:18:52 +01:00
|
|
|
{
|
2011-01-23 18:47:48 +01:00
|
|
|
DBG_ASSERT( pFuncList, "Functionlist not found." );
|
2011-01-16 23:05:25 +01:00
|
|
|
sal_uInt32 nCount = pFuncList->GetCount();
|
2011-01-18 09:43:17 -05:00
|
|
|
ScFuncDesc* pDesc;
|
2011-01-16 23:05:25 +01:00
|
|
|
List* pRootList;
|
|
|
|
sal_uInt32 n;
|
2011-01-11 22:18:52 +01:00
|
|
|
|
2011-01-18 09:43:17 -05:00
|
|
|
for (sal_uInt16 i = 0; i < MAX_FUNCCAT; ++i) // create category lists
|
2011-01-11 22:18:52 +01:00
|
|
|
aCatLists[i] = new List;
|
|
|
|
|
2011-01-16 23:05:25 +01:00
|
|
|
pRootList = aCatLists[0]; // create cumulative list ("All")
|
2011-01-11 22:18:52 +01:00
|
|
|
CollatorWrapper* pCaseCollator = ScGlobal::GetCaseCollator();
|
|
|
|
for ( n=0; n<nCount; n++ )
|
|
|
|
{
|
2011-01-16 23:05:25 +01:00
|
|
|
sal_uInt32 nTmpCnt=0;
|
2011-01-11 22:18:52 +01:00
|
|
|
pDesc = pFuncList->GetFunction(n);
|
|
|
|
for (nTmpCnt = 0; nTmpCnt < n; nTmpCnt++)
|
|
|
|
{
|
2011-01-16 23:05:25 +01:00
|
|
|
// it's case sensitiv, but special characters have to be put the right place
|
2011-01-18 09:43:17 -05:00
|
|
|
const ScFuncDesc* pTmpDesc = static_cast<const ScFuncDesc*>(
|
|
|
|
pRootList->GetObject(nTmpCnt));
|
2011-01-11 22:18:52 +01:00
|
|
|
if ( pCaseCollator->compareString(*pDesc->pFuncName, *pTmpDesc->pFuncName ) == COMPARE_LESS )
|
|
|
|
break;
|
|
|
|
}
|
2011-01-18 09:43:17 -05:00
|
|
|
pRootList->Insert(static_cast<void*>(pDesc), nTmpCnt); // insert the right place
|
2011-01-11 22:18:52 +01:00
|
|
|
}
|
|
|
|
|
2011-01-16 23:05:25 +01:00
|
|
|
for ( n=0; n<nCount; n++ ) // copy to group list
|
2011-01-11 22:18:52 +01:00
|
|
|
{
|
2011-01-18 09:43:17 -05:00
|
|
|
pDesc = static_cast<ScFuncDesc*>(pRootList->GetObject(n));
|
2011-01-23 18:47:48 +01:00
|
|
|
DBG_ASSERT((pDesc->nCategory) < MAX_FUNCCAT, "Unknown category");
|
2011-01-11 22:18:52 +01:00
|
|
|
if ((pDesc->nCategory) < MAX_FUNCCAT)
|
2011-01-18 09:43:17 -05:00
|
|
|
aCatLists[pDesc->nCategory]->Insert(static_cast<void*>(pDesc), LIST_APPEND);
|
2011-01-11 22:18:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ScFunctionMgr::~ScFunctionMgr()
|
|
|
|
{
|
2011-01-18 09:43:17 -05:00
|
|
|
for (sal_uInt16 i = 0; i < MAX_FUNCCAT; ++i)
|
2011-01-11 22:18:52 +01:00
|
|
|
delete aCatLists[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
const ScFuncDesc* ScFunctionMgr::Get( const ::rtl::OUString& rFName ) const
|
|
|
|
{
|
2011-01-16 23:05:25 +01:00
|
|
|
const ScFuncDesc* pDesc = NULL;
|
2011-01-11 22:18:52 +01:00
|
|
|
if (rFName.getLength() <= pFuncList->GetMaxFuncNameLen())
|
|
|
|
for (pDesc = First(0); pDesc; pDesc = Next())
|
|
|
|
if (rFName.equalsIgnoreAsciiCase(*pDesc->pFuncName))
|
|
|
|
break;
|
|
|
|
return pDesc;
|
|
|
|
}
|
|
|
|
|
2011-01-16 23:05:25 +01:00
|
|
|
const ScFuncDesc* ScFunctionMgr::Get( sal_uInt16 nFIndex ) const
|
2011-01-11 22:18:52 +01:00
|
|
|
{
|
2011-01-16 23:05:25 +01:00
|
|
|
const ScFuncDesc* pDesc;
|
2011-01-11 22:18:52 +01:00
|
|
|
for (pDesc = First(0); pDesc; pDesc = Next())
|
|
|
|
if (pDesc->nFIndex == nFIndex)
|
|
|
|
break;
|
|
|
|
return pDesc;
|
|
|
|
}
|
|
|
|
|
2011-01-16 23:05:25 +01:00
|
|
|
const ScFuncDesc* ScFunctionMgr::First( sal_uInt16 nCategory ) const
|
2011-01-11 22:18:52 +01:00
|
|
|
{
|
|
|
|
DBG_ASSERT( nCategory < MAX_FUNCCAT, "Unbekannte Kategorie" );
|
|
|
|
|
|
|
|
if ( nCategory < MAX_FUNCCAT )
|
|
|
|
{
|
|
|
|
pCurCatList = aCatLists[nCategory];
|
|
|
|
return (const ScFuncDesc*)pCurCatList->First();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pCurCatList = NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const ScFuncDesc* ScFunctionMgr::Next() const
|
|
|
|
{
|
|
|
|
if ( pCurCatList )
|
|
|
|
return (const ScFuncDesc*)pCurCatList->Next();
|
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
sal_uInt32 ScFunctionMgr::getCount() const
|
|
|
|
{
|
|
|
|
return MAX_FUNCCAT - 1;
|
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
const formula::IFunctionCategory* ScFunctionMgr::getCategory(sal_uInt32 nCategory) const
|
|
|
|
{
|
|
|
|
formula::IFunctionCategory* pRet = NULL;
|
|
|
|
if ( nCategory < (MAX_FUNCCAT-1) )
|
|
|
|
{
|
|
|
|
pRet = new ScFunctionCategory(const_cast<ScFunctionMgr*>(this),aCatLists[nCategory+1],nCategory); // aCatLists[0] is "all"
|
|
|
|
}
|
|
|
|
return pRet;
|
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
const formula::IFunctionDescription* ScFunctionMgr::getFunctionByName(const ::rtl::OUString& _sFunctionName) const
|
|
|
|
{
|
|
|
|
return Get(_sFunctionName);
|
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
void ScFunctionMgr::fillLastRecentlyUsedFunctions(::std::vector< const formula::IFunctionDescription*>& _rLastRUFunctions) const
|
|
|
|
{
|
|
|
|
const ScAppOptions& rAppOpt = SC_MOD()->GetAppOptions();
|
2011-01-16 23:05:25 +01:00
|
|
|
sal_uInt16 nLRUFuncCount = Min( rAppOpt.GetLRUFuncListCount(), (sal_uInt16)LRU_MAX );
|
|
|
|
sal_uInt16* pLRUListIds = rAppOpt.GetLRUFuncList();
|
2011-01-11 22:18:52 +01:00
|
|
|
|
|
|
|
if ( pLRUListIds )
|
|
|
|
{
|
2011-01-18 09:43:17 -05:00
|
|
|
for (sal_uInt16 i = 0; i < nLRUFuncCount; ++i)
|
2011-01-11 22:18:52 +01:00
|
|
|
_rLastRUFunctions.push_back( Get( pLRUListIds[i] ) );
|
|
|
|
}
|
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
::rtl::OUString ScFunctionMgr::GetCategoryName(sal_uInt32 _nCategoryNumber )
|
|
|
|
{
|
|
|
|
if ( _nCategoryNumber > SC_FUNCGROUP_COUNT )
|
|
|
|
{
|
|
|
|
DBG_ERROR("Invalid category number!");
|
|
|
|
return ::rtl::OUString();
|
|
|
|
}
|
|
|
|
|
|
|
|
::std::auto_ptr<ScResourcePublisher> pCategories( new ScResourcePublisher( ScResId( RID_FUNCTION_CATEGORIES ) ) );
|
2011-01-18 09:43:17 -05:00
|
|
|
return ResId::toString(ScResId(static_cast<sal_uInt16>(_nCategoryNumber)));
|
2011-01-11 22:18:52 +01:00
|
|
|
}
|
2011-01-23 18:47:48 +01:00
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
sal_Unicode ScFunctionMgr::getSingleToken(const formula::IFunctionManager::EToken _eToken) const
|
|
|
|
{
|
|
|
|
switch(_eToken)
|
|
|
|
{
|
|
|
|
case eOk:
|
|
|
|
return ScCompiler::GetNativeSymbol(ocOpen).GetChar(0);
|
|
|
|
case eClose:
|
|
|
|
return ScCompiler::GetNativeSymbol(ocClose).GetChar(0);
|
|
|
|
case eSep:
|
|
|
|
return ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
|
|
|
|
case eArrayOpen:
|
|
|
|
return ScCompiler::GetNativeSymbol(ocArrayOpen).GetChar(0);
|
|
|
|
case eArrayClose:
|
|
|
|
return ScCompiler::GetNativeSymbol(ocArrayClose).GetChar(0);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-01-23 18:47:48 +01:00
|
|
|
//========================================================================
|
|
|
|
// class ScFuncRes:
|
|
|
|
//========================================================================
|
|
|
|
|
2011-01-11 22:18:52 +01:00
|
|
|
ScFuncRes::ScFuncRes( ResId &aRes, ScFuncDesc* pDesc, bool & rbSuppressed )
|
|
|
|
: Resource(aRes)
|
|
|
|
{
|
|
|
|
rbSuppressed = (bool)GetNum();
|
|
|
|
pDesc->nCategory = GetNum();
|
2011-01-16 23:05:25 +01:00
|
|
|
pDesc->nHelpId = GetNum() + 32768; //! Hack, see scfuncs.src
|
2011-01-11 22:18:52 +01:00
|
|
|
pDesc->nArgCount = GetNum();
|
2011-01-16 23:05:25 +01:00
|
|
|
sal_uInt16 nArgs = pDesc->nArgCount;
|
2011-01-11 22:18:52 +01:00
|
|
|
if (nArgs >= VAR_ARGS)
|
|
|
|
nArgs -= VAR_ARGS - 1;
|
|
|
|
if (nArgs)
|
|
|
|
{
|
|
|
|
pDesc->pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgs];
|
2011-01-18 09:43:17 -05:00
|
|
|
for (sal_uInt16 i = 0; i < nArgs; ++i)
|
2011-01-11 22:18:52 +01:00
|
|
|
{
|
|
|
|
pDesc->pDefArgFlags[i].bOptional = (bool)GetNum();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Need to read the value from the resource even if nArgs==0 to advance the
|
|
|
|
// resource position pointer, so this can't be in the if(nArgs) block above.
|
2011-01-16 23:05:25 +01:00
|
|
|
sal_uInt16 nSuppressed = GetNum();
|
2011-01-11 22:18:52 +01:00
|
|
|
if (nSuppressed)
|
|
|
|
{
|
|
|
|
if (nSuppressed > nArgs)
|
|
|
|
{
|
|
|
|
DBG_ERROR3( "ScFuncRes: suppressed parameters count mismatch on OpCode %u: suppressed %d > params %d",
|
|
|
|
aRes.GetId(), (int)nSuppressed, (int)nArgs);
|
|
|
|
nSuppressed = nArgs; // sanitize
|
|
|
|
}
|
2011-01-18 09:43:17 -05:00
|
|
|
for (sal_uInt16 i = 0; i < nSuppressed; ++i)
|
2011-01-11 22:18:52 +01:00
|
|
|
{
|
2011-01-16 23:05:25 +01:00
|
|
|
sal_uInt16 nParam = GetNum();
|
2011-01-11 22:18:52 +01:00
|
|
|
if (nParam < nArgs)
|
|
|
|
{
|
|
|
|
if (pDesc->nArgCount >= VAR_ARGS && nParam == nArgs-1)
|
|
|
|
{
|
|
|
|
DBG_ERROR3( "ScFuncRes: VAR_ARGS parameters can't be suppressed, on OpCode %u: param %d == arg %d-1",
|
|
|
|
aRes.GetId(), (int)nParam, (int)nArgs);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pDesc->pDefArgFlags[nParam].bSuppress = true;
|
|
|
|
pDesc->bHasSuppressedArgs = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DBG_ERROR3( "ScFuncRes: suppressed parameter exceeds count on OpCode %u: param %d >= args %d",
|
|
|
|
aRes.GetId(), (int)nParam, (int)nArgs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pDesc->pFuncName = new ::rtl::OUString( ScCompiler::GetNativeSymbol( static_cast<OpCode>( aRes.GetId())));
|
|
|
|
pDesc->pFuncDesc = new ::rtl::OUString( ResId::toString(ScResId(1)));
|
|
|
|
|
|
|
|
if (nArgs)
|
|
|
|
{
|
|
|
|
pDesc->ppDefArgNames = new ::rtl::OUString*[nArgs];
|
|
|
|
pDesc->ppDefArgDescs = new ::rtl::OUString*[nArgs];
|
2011-01-18 09:43:17 -05:00
|
|
|
for (sal_uInt16 i = 0; i < nArgs; ++i)
|
2011-01-11 22:18:52 +01:00
|
|
|
{
|
|
|
|
pDesc->ppDefArgNames[i] = new ::rtl::OUString(ResId::toString(ScResId(2*(i+1) )));
|
|
|
|
pDesc->ppDefArgDescs[i] = new ::rtl::OUString(ResId::toString(ScResId(2*(i+1)+1)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FreeResource();
|
|
|
|
}
|
|
|
|
|
2011-01-16 23:05:25 +01:00
|
|
|
sal_uInt16 ScFuncRes::GetNum()
|
2011-01-11 22:18:52 +01:00
|
|
|
{
|
|
|
|
return ReadShortRes();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|