Files
libreoffice/sc/source/ui/unoobj/funcuno.cxx
2000-12-21 12:59:04 +00:00

743 lines
25 KiB
C++

/*************************************************************************
*
* $RCSfile: funcuno.cxx,v $
*
* $Revision: 1.5 $
*
* last change: $Author: nn $ $Date: 2000-12-21 13:59:04 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library 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 for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (the "License"); You may not use this file
* except in compliance with the License. You may obtain a copy of the
* License at http://www.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
#ifdef PCH
#include "ui_pch.hxx"
#endif
#pragma hdrstop
#include <tools/debug.hxx>
#include <sfx2/app.hxx>
#include <svtools/itemprop.hxx>
#include "funcuno.hxx"
#include "miscuno.hxx"
#include "cellsuno.hxx"
#include "unoguard.hxx"
#include "scdll.hxx"
#include "document.hxx"
#include "compiler.hxx"
#include "callform.hxx"
#include "addincol.hxx"
#include "rangeseq.hxx"
#include "cell.hxx"
#include "docoptio.hxx"
#include "optuno.hxx"
// for lcl_CopyData:
#include "markdata.hxx"
#include "patattr.hxx"
#include "docpool.hxx"
#include "attrib.hxx"
using namespace com::sun::star;
//------------------------------------------------------------------------
// registered as implementation for service FunctionAccess,
// also supports service SpreadsheetDocumentSettings (to set null date etc.)
#define SCFUNCTIONACCESS_SERVICE "com.sun.star.sheet.FunctionAccess"
#define SCDOCSETTINGS_SERVICE "com.sun.star.sheet.SpreadsheetDocumentSettings"
//------------------------------------------------------------------------
// helper to use cached document if not in use, temporary document otherwise
class ScTempDocSource
{
private:
ScTempDocCache& rCache;
ScDocument* pTempDoc;
static ScDocument* CreateDocument(); // create and initialize doc
public:
ScTempDocSource( ScTempDocCache& rDocCache );
~ScTempDocSource();
ScDocument* GetDocument();
};
//------------------------------------------------------------------------
// static
ScDocument* ScTempDocSource::CreateDocument()
{
ScDocument* pDoc = new ScDocument; // SCDOCMODE_DOCUMENT
pDoc->MakeTable( 0 );
return pDoc;
}
ScTempDocSource::ScTempDocSource( ScTempDocCache& rDocCache ) :
rCache( rDocCache ),
pTempDoc( NULL )
{
if ( rCache.IsInUse() )
pTempDoc = CreateDocument();
else
{
rCache.SetInUse( TRUE );
if ( !rCache.GetDocument() )
rCache.SetDocument( CreateDocument() );
}
}
ScTempDocSource::~ScTempDocSource()
{
if ( pTempDoc )
delete pTempDoc;
else
rCache.SetInUse( FALSE );
}
ScDocument* ScTempDocSource::GetDocument()
{
if ( pTempDoc )
return pTempDoc;
else
return rCache.GetDocument();
}
//------------------------------------------------------------------------
ScTempDocCache::ScTempDocCache() :
pDoc( NULL ),
bInUse( FALSE )
{
}
ScTempDocCache::~ScTempDocCache()
{
DBG_ASSERT( !bInUse, "ScTempDocCache dtor: bInUse" );
delete pDoc;
}
void ScTempDocCache::SetDocument( ScDocument* pNew )
{
DBG_ASSERT( !pDoc, "ScTempDocCache::SetDocument: already set" );
pDoc = pNew;
}
void ScTempDocCache::Clear()
{
DBG_ASSERT( !bInUse, "ScTempDocCache::Clear: bInUse" );
delete pDoc;
pDoc = NULL;
}
//------------------------------------------------------------------------
// copy results from one document into another
//! merge this with ScAreaLink::Refresh
//! copy directly without a clipboard document?
BOOL lcl_CopyData( ScDocument* pSrcDoc, const ScRange& rSrcRange,
ScDocument* pDestDoc, const ScAddress& rDestPos )
{
USHORT nSrcTab = rSrcRange.aStart.Tab();
USHORT nDestTab = rDestPos.Tab();
ScRange aNewRange( rDestPos, ScAddress(
rSrcRange.aEnd.Col() - rSrcRange.aStart.Col() + rDestPos.Col(),
rSrcRange.aEnd.Row() - rSrcRange.aStart.Row() + rDestPos.Row(),
nDestTab ) );
ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
ScMarkData aSourceMark;
aSourceMark.SelectOneTable( nSrcTab ); // for CopyToClip
aSourceMark.SetMarkArea( rSrcRange );
pSrcDoc->CopyToClip( rSrcRange.aStart.Col(),rSrcRange.aStart.Row(),
rSrcRange.aEnd.Col(),rSrcRange.aEnd.Row(),
FALSE, pClipDoc, FALSE, &aSourceMark );
if ( pClipDoc->HasAttrib( 0,0,nSrcTab, MAXCOL,MAXROW,nSrcTab,
HASATTR_MERGED | HASATTR_OVERLAPPED ) )
{
ScPatternAttr aPattern( pSrcDoc->GetPool() );
aPattern.GetItemSet().Put( ScMergeAttr() ); // Defaults
aPattern.GetItemSet().Put( ScMergeFlagAttr() );
pClipDoc->ApplyPatternAreaTab( 0,0, MAXCOL,MAXROW, nSrcTab, aPattern );
}
ScMarkData aDestMark;
aDestMark.SelectOneTable( nDestTab );
aDestMark.SetMarkArea( aNewRange );
pDestDoc->CopyFromClip( aNewRange, aDestMark, IDF_ALL & ~IDF_FORMULA, NULL, pClipDoc, FALSE );
delete pClipDoc;
return TRUE;
}
//------------------------------------------------------------------------
ScFunctionAccess::ScFunctionAccess() :
bInvalid( FALSE ),
pOptions( NULL )
{
StartListening( *SFX_APP() ); // for SFX_HINT_DEINITIALIZING
}
ScFunctionAccess::~ScFunctionAccess()
{
delete pOptions;
}
void ScFunctionAccess::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
{
if ( rHint.ISA(SfxSimpleHint) &&
((SfxSimpleHint&)rHint).GetId() == SFX_HINT_DEINITIALIZING )
{
// document must not be used anymore
aDocCache.Clear();
bInvalid = TRUE;
}
}
// stuff for exService_...
uno::Reference<uno::XInterface> SAL_CALL ScFunctionAccess_CreateInstance(
const uno::Reference<lang::XMultiServiceFactory>& )
{
ScUnoGuard aGuard;
SC_DLL()->Load(); // load module
static uno::Reference< uno::XInterface > xInst = (::cppu::OWeakObject*) new ScFunctionAccess;
return xInst;
}
rtl::OUString ScFunctionAccess::getImplementationName_Static()
{
return rtl::OUString::createFromAscii( "stardiv.StarCalc.ScFunctionAccess" );
}
uno::Sequence<rtl::OUString> ScFunctionAccess::getSupportedServiceNames_Static()
{
uno::Sequence<rtl::OUString> aRet(1);
rtl::OUString* pArray = aRet.getArray();
pArray[0] = rtl::OUString::createFromAscii( SCFUNCTIONACCESS_SERVICE );
return aRet;
}
// XServiceInfo
rtl::OUString SAL_CALL ScFunctionAccess::getImplementationName() throw(uno::RuntimeException)
{
return rtl::OUString::createFromAscii( "ScFunctionAccess" );
}
sal_Bool SAL_CALL ScFunctionAccess::supportsService( const rtl::OUString& rServiceName )
throw(uno::RuntimeException)
{
String aServiceStr = rServiceName;
return aServiceStr.EqualsAscii( SCFUNCTIONACCESS_SERVICE ) ||
aServiceStr.EqualsAscii( SCDOCSETTINGS_SERVICE );
}
uno::Sequence<rtl::OUString> SAL_CALL ScFunctionAccess::getSupportedServiceNames()
throw(uno::RuntimeException)
{
uno::Sequence<rtl::OUString> aRet(2);
rtl::OUString* pArray = aRet.getArray();
pArray[0] = rtl::OUString::createFromAscii( SCFUNCTIONACCESS_SERVICE );
pArray[1] = rtl::OUString::createFromAscii( SCDOCSETTINGS_SERVICE );
return aRet;
}
// XPropertySet (document settings)
uno::Reference<beans::XPropertySetInfo> SAL_CALL ScFunctionAccess::getPropertySetInfo()
throw(uno::RuntimeException)
{
ScUnoGuard aGuard;
static uno::Reference<beans::XPropertySetInfo> aRef =
new SfxItemPropertySetInfo( ScDocOptionsHelper::GetPropertyMap() );
return aRef;
}
void SAL_CALL ScFunctionAccess::setPropertyValue(
const rtl::OUString& aPropertyName, const uno::Any& aValue )
throw(beans::UnknownPropertyException, beans::PropertyVetoException,
lang::IllegalArgumentException, lang::WrappedTargetException,
uno::RuntimeException)
{
ScUnoGuard aGuard;
if ( !pOptions )
pOptions = new ScDocOptions();
// options aren't initialized from configuration - always get the same default behaviour
BOOL bDone = ScDocOptionsHelper::setPropertyValue( *pOptions, aPropertyName, aValue );
if (!bDone)
throw beans::UnknownPropertyException();
}
uno::Any SAL_CALL ScFunctionAccess::getPropertyValue( const rtl::OUString& aPropertyName )
throw(beans::UnknownPropertyException, lang::WrappedTargetException,
uno::RuntimeException)
{
ScUnoGuard aGuard;
if ( !pOptions )
pOptions = new ScDocOptions();
// options aren't initialized from configuration - always get the same default behaviour
return ScDocOptionsHelper::getPropertyValue( *pOptions, aPropertyName );
}
SC_IMPL_DUMMY_PROPERTY_LISTENER( ScFunctionAccess )
// XFunctionAccess
BOOL lcl_AddFunctionToken( ScTokenArray& rArray, const rtl::OUString& rName )
{
// function names are always case-insensitive
String aUpper( rName );
ScGlobal::pCharClass->toUpper( aUpper );
// same options as in ScCompiler::IsOpCode:
// 1. built-in function name
DBG_ASSERT( ScCompiler::pSymbolTableEnglish, "no symbol table" );
if (!ScCompiler::pSymbolTableEnglish)
return FALSE;
for ( USHORT nPos=0; nPos<ScCompiler::nAnzStrings; nPos++ )
if ( ScCompiler::pSymbolTableEnglish[nPos] == aUpper )
{
rArray.AddOpCode( (OpCode) nPos );
return TRUE;
}
// 2. old add in functions
USHORT nIndex;
if ( ScGlobal::GetFuncCollection()->SearchFunc( aUpper, nIndex ) )
{
rArray.AddExternal( aUpper.GetBuffer() );
return TRUE;
}
// 3. new (uno) add in functions
String aIntName = ScGlobal::GetAddInCollection()->FindFunction( aUpper, FALSE );
if (aIntName.Len())
{
rArray.AddExternal( aIntName.GetBuffer() ); // international name
return TRUE;
}
return FALSE; // no valid function name
}
void lcl_AddRef( ScTokenArray& rArray, long nStartRow, long nColCount, long nRowCount )
{
ComplRefData aRef;
aRef.InitFlags();
aRef.Ref1.nTab = 0;
aRef.Ref2.nTab = 0;
aRef.Ref1.nCol = 0;
aRef.Ref1.nRow = (USHORT) nStartRow;
aRef.Ref2.nCol = (USHORT) (nColCount - 1);
aRef.Ref2.nRow = (USHORT) (nStartRow + nRowCount - 1);
rArray.AddDoubleReference(aRef);
}
uno::Any SAL_CALL ScFunctionAccess::callFunction( const rtl::OUString& aName,
const uno::Sequence<uno::Any>& aArguments )
throw(container::NoSuchElementException, lang::IllegalArgumentException,
uno::RuntimeException)
{
ScUnoGuard aGuard;
if (bInvalid)
throw uno::RuntimeException();
// use cached document if not in use, temporary document otherwise
// (deleted in ScTempDocSource dtor)
ScTempDocSource aSource( aDocCache );
ScDocument* pDoc = aSource.GetDocument();
if (!ScCompiler::pSymbolTableEnglish)
{
ScCompiler aComp( pDoc, ScAddress() );
aComp.SetCompileEnglish( TRUE ); // setup english symbol table
}
//
// find function
//
ScTokenArray aTokenArr;
if ( !lcl_AddFunctionToken( aTokenArr, aName ) )
{
// function not found
throw container::NoSuchElementException();
}
//
// set options (null date, etc.)
//
if ( pOptions )
pDoc->SetDocOptions( *pOptions );
//
// add arguments to token array
//
BOOL bArgErr = FALSE;
BOOL bOverflow = FALSE;
long nDocRow = 0;
long nArgCount = aArguments.getLength();
const uno::Any* pArgArr = aArguments.getConstArray();
aTokenArr.AddOpCode(ocOpen);
for (long nPos=0; nPos<nArgCount; nPos++)
{
if ( nPos > 0 )
aTokenArr.AddOpCode(ocSep);
const uno::Any& rArg = pArgArr[nPos];
uno::TypeClass eClass = rArg.getValueTypeClass();
uno::Type aType = rArg.getValueType();
if ( eClass == uno::TypeClass_SHORT ||
eClass == uno::TypeClass_LONG ||
eClass == uno::TypeClass_DOUBLE )
{
double fVal;
rArg >>= fVal;
aTokenArr.AddDouble( fVal );
}
else if ( eClass == uno::TypeClass_STRING )
{
rtl::OUString aUStr;
rArg >>= aUStr;
String aStr( aUStr );
aTokenArr.AddString( aStr.GetBuffer() );
}
else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<sal_Int16> > *)0 ) ) )
{
uno::Sequence< uno::Sequence<sal_Int16> > aRowSeq;
rArg >>= aRowSeq;
long nStartRow = nDocRow;
long nMaxColCount = 0;
long nRowCount = aRowSeq.getLength();
const uno::Sequence<sal_Int16>* pRowArr = aRowSeq.getConstArray();
for (long nRow=0; nRow<nRowCount; nRow++)
{
long nColCount = pRowArr[nRow].getLength();
if ( nColCount > nMaxColCount )
nMaxColCount = nColCount;
const sal_Int16* pColArr = pRowArr[nRow].getConstArray();
for (long nCol=0; nCol<nColCount; nCol++)
if ( nCol <= MAXCOL && nDocRow <= MAXROW )
pDoc->SetValue( (USHORT) nCol, (USHORT) nDocRow, 0, pColArr[nCol] );
else
bOverflow = TRUE;
++nDocRow;
}
if ( nRowCount && nMaxColCount && !bOverflow )
lcl_AddRef( aTokenArr, nStartRow, nMaxColCount, nRowCount );
}
else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<sal_Int32> > *)0 ) ) )
{
uno::Sequence< uno::Sequence<sal_Int32> > aRowSeq;
rArg >>= aRowSeq;
long nStartRow = nDocRow;
long nMaxColCount = 0;
long nRowCount = aRowSeq.getLength();
const uno::Sequence<sal_Int32>* pRowArr = aRowSeq.getConstArray();
for (long nRow=0; nRow<nRowCount; nRow++)
{
long nColCount = pRowArr[nRow].getLength();
if ( nColCount > nMaxColCount )
nMaxColCount = nColCount;
const sal_Int32* pColArr = pRowArr[nRow].getConstArray();
for (long nCol=0; nCol<nColCount; nCol++)
if ( nCol <= MAXCOL && nDocRow <= MAXROW )
pDoc->SetValue( (USHORT) nCol, (USHORT) nDocRow, 0, pColArr[nCol] );
else
bOverflow = TRUE;
++nDocRow;
}
if ( nRowCount && nMaxColCount && !bOverflow )
lcl_AddRef( aTokenArr, nStartRow, nMaxColCount, nRowCount );
}
else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<double> > *)0 ) ) )
{
uno::Sequence< uno::Sequence<double> > aRowSeq;
rArg >>= aRowSeq;
long nStartRow = nDocRow;
long nMaxColCount = 0;
long nRowCount = aRowSeq.getLength();
const uno::Sequence<double>* pRowArr = aRowSeq.getConstArray();
for (long nRow=0; nRow<nRowCount; nRow++)
{
long nColCount = pRowArr[nRow].getLength();
if ( nColCount > nMaxColCount )
nMaxColCount = nColCount;
const double* pColArr = pRowArr[nRow].getConstArray();
for (long nCol=0; nCol<nColCount; nCol++)
if ( nCol <= MAXCOL && nDocRow <= MAXROW )
pDoc->SetValue( (USHORT) nCol, (USHORT) nDocRow, 0, pColArr[nCol] );
else
bOverflow = TRUE;
++nDocRow;
}
if ( nRowCount && nMaxColCount && !bOverflow )
lcl_AddRef( aTokenArr, nStartRow, nMaxColCount, nRowCount );
}
else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<rtl::OUString> > *)0 ) ) )
{
uno::Sequence< uno::Sequence<rtl::OUString> > aRowSeq;
rArg >>= aRowSeq;
long nStartRow = nDocRow;
long nMaxColCount = 0;
long nRowCount = aRowSeq.getLength();
const uno::Sequence<rtl::OUString>* pRowArr = aRowSeq.getConstArray();
for (long nRow=0; nRow<nRowCount; nRow++)
{
long nColCount = pRowArr[nRow].getLength();
if ( nColCount > nMaxColCount )
nMaxColCount = nColCount;
const rtl::OUString* pColArr = pRowArr[nRow].getConstArray();
for (long nCol=0; nCol<nColCount; nCol++)
if ( nCol <= MAXCOL && nDocRow <= MAXROW )
{
if ( pColArr[nCol].getLength() )
pDoc->PutCell( (USHORT) nCol, (USHORT) nDocRow, 0,
new ScStringCell( pColArr[nCol] ) );
}
else
bOverflow = TRUE;
++nDocRow;
}
if ( nRowCount && nMaxColCount && !bOverflow )
lcl_AddRef( aTokenArr, nStartRow, nMaxColCount, nRowCount );
}
else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<uno::Any> > *)0 ) ) )
{
uno::Sequence< uno::Sequence<uno::Any> > aRowSeq;
rArg >>= aRowSeq;
long nStartRow = nDocRow;
long nMaxColCount = 0;
long nRowCount = aRowSeq.getLength();
const uno::Sequence<uno::Any>* pRowArr = aRowSeq.getConstArray();
for (long nRow=0; nRow<nRowCount; nRow++)
{
long nColCount = pRowArr[nRow].getLength();
if ( nColCount > nMaxColCount )
nMaxColCount = nColCount;
const uno::Any* pColArr = pRowArr[nRow].getConstArray();
for (long nCol=0; nCol<nColCount; nCol++)
if ( nCol <= MAXCOL && nDocRow <= MAXROW )
{
const uno::Any& rElement = pColArr[nCol];
uno::TypeClass eElemClass = rElement.getValueTypeClass();
if ( eElemClass == uno::TypeClass_VOID )
{
// leave empty
}
else if ( eElemClass == uno::TypeClass_SHORT ||
eElemClass == uno::TypeClass_LONG ||
eElemClass == uno::TypeClass_DOUBLE )
{
double fVal;
rElement >>= fVal;
pDoc->SetValue( (USHORT) nCol, (USHORT) nDocRow, 0, fVal );
}
else if ( eElemClass == uno::TypeClass_STRING )
{
rtl::OUString aUStr;
rElement >>= aUStr;
if ( aUStr.getLength() )
pDoc->PutCell( (USHORT) nCol, (USHORT) nDocRow, 0,
new ScStringCell( aUStr ) );
}
else
bArgErr = TRUE; // invalid type
}
else
bOverflow = TRUE;
++nDocRow;
}
if ( nRowCount && nMaxColCount && !bOverflow )
lcl_AddRef( aTokenArr, nStartRow, nMaxColCount, nRowCount );
}
else if ( aType.equals( getCppuType( (uno::Reference<table::XCellRange>*)0 ) ) )
{
// currently, only our own cell ranges are supported
uno::Reference<table::XCellRange> xRange;
rArg >>= xRange;
ScCellRangesBase* pImpl = ScCellRangesBase::getImplementation( xRange );
if ( pImpl )
{
ScDocument* pSrcDoc = pImpl->GetDocument();
const ScRangeList& rRanges = pImpl->GetRangeList();
if ( pSrcDoc && rRanges.Count() == 1 )
{
ScRange aSrcRange = *rRanges.GetObject(0);
long nStartRow = nDocRow;
long nColCount = aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1;
long nRowCount = aSrcRange.aEnd.Row() - aSrcRange.aStart.Row() + 1;
if ( nStartRow + nRowCount > MAXROW )
bOverflow = TRUE;
else
{
// copy data
if ( !lcl_CopyData( pSrcDoc, aSrcRange, pDoc, ScAddress( 0, (USHORT)nDocRow, 0 ) ) )
bOverflow = TRUE;
}
nDocRow += nRowCount;
if ( !bOverflow )
lcl_AddRef( aTokenArr, nStartRow, nColCount, nRowCount );
}
else
bArgErr = TRUE;
}
else
bArgErr = TRUE;
}
else
bArgErr = TRUE; // invalid type
}
aTokenArr.AddOpCode(ocClose);
aTokenArr.AddOpCode(ocStop);
//
// execute formula
//
uno::Any aRet;
if ( !bArgErr && !bOverflow && nDocRow <= MAXROW )
{
ScAddress aFormulaPos( 0, (USHORT)nDocRow, 0 );
ScFormulaCell* pFormula = new ScFormulaCell( pDoc, aFormulaPos, &aTokenArr, MM_FORMULA );
pDoc->PutCell( aFormulaPos, pFormula ); //! necessary?
// call GetMatrix before GetErrCode because GetMatrix always recalculates
// if there is no matrix result
ScMatrix* pMat = NULL;
pFormula->GetMatrix(&pMat);
USHORT nErrCode = pFormula->GetErrCode();
if ( nErrCode == 0 )
{
if ( pMat )
{
// array result
ScRangeToSequence::FillMixedArray( aRet, pMat );
}
else if ( pFormula->IsValue() )
{
// numeric value
aRet <<= (double) pFormula->GetValue();
}
else
{
// string result
String aStrVal;
pFormula->GetString( aStrVal );
aRet <<= rtl::OUString( aStrVal );
}
}
else if ( nErrCode == NOVALUE )
{
// #N/A: leave result empty, no exception
}
else
{
// any other error: IllegalArgumentException
bArgErr = TRUE;
}
pDoc->DeleteAreaTab( 0, 0, MAXCOL, MAXROW, 0, IDF_ALL );
}
if (bOverflow)
throw uno::RuntimeException();
if (bArgErr)
throw lang::IllegalArgumentException();
return aRet;
}