diff options
Diffstat (limited to 'binfilter/bf_sc/source/core/tool')
50 files changed, 44116 insertions, 0 deletions
diff --git a/binfilter/bf_sc/source/core/tool/makefile.mk b/binfilter/bf_sc/source/core/tool/makefile.mk new file mode 100644 index 000000000000..927c2cd32f95 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/makefile.mk @@ -0,0 +1,107 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +EXTERNAL_WARNINGS_NOT_ERRORS := TRUE +PRJ=..$/..$/..$/.. +BFPRJ=..$/..$/.. + +PRJNAME=binfilter +TARGET=sc_tool + +NO_HIDS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(BFPRJ)$/util$/makefile.pmk +INC+= -I$(PRJ)$/inc$/bf_sc +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/sc_adiasync.obj \ + $(SLO)$/sc_appoptio.obj \ + $(SLO)$/sc_autoform.obj \ + $(SLO)$/sc_callform.obj \ + $(SLO)$/sc_cellform.obj \ + $(SLO)$/sc_chartarr.obj \ + $(SLO)$/sc_chartlis.obj \ + $(SLO)$/sc_chgtrack.obj \ + $(SLO)$/sc_chgviset.obj \ + $(SLO)$/sc_collect.obj \ + $(SLO)$/sc_compiler.obj \ + $(SLO)$/sc_consoli.obj \ + $(SLO)$/sc_dbcolect.obj \ + $(SLO)$/sc_ddelink.obj \ + $(SLO)$/sc_detfunc.obj \ + $(SLO)$/sc_detdata.obj \ + $(SLO)$/sc_docoptio.obj \ + $(SLO)$/sc_editutil.obj \ + $(SLO)$/sc_indexmap.obj \ + $(SLO)$/sc_interpr1.obj \ + $(SLO)$/sc_interpr2.obj \ + $(SLO)$/sc_interpr3.obj \ + $(SLO)$/sc_interpr4.obj \ + $(SLO)$/sc_interpr5.obj \ + $(SLO)$/sc_interpr6.obj \ + $(SLO)$/sc_progress.obj \ + $(SLO)$/sc_rangenam.obj \ + $(SLO)$/sc_rangelst.obj \ + $(SLO)$/sc_rangeutl.obj \ + $(SLO)$/sc_rechead.obj \ + $(SLO)$/sc_refupdat.obj \ + $(SLO)$/sc_refdata.obj \ + $(SLO)$/sc_scmatrix.obj \ + $(SLO)$/sc_subtotal.obj \ + $(SLO)$/sc_token.obj \ + $(SLO)$/sc_unitconv.obj \ + $(SLO)$/sc_userlist.obj \ + $(SLO)$/sc_viewopti.obj \ + $(SLO)$/sc_inputopt.obj \ + $(SLO)$/sc_printopt.obj \ + $(SLO)$/sc_optutil.obj \ + $(SLO)$/sc_zforauto.obj \ + $(SLO)$/sc_hints.obj \ + $(SLO)$/sc_prnsave.obj \ + $(SLO)$/sc_addincol.obj \ + $(SLO)$/sc_addinlis.obj \ + $(SLO)$/sc_addinhelpid.obj \ + $(SLO)$/sc_rangeseq.obj \ + $(SLO)$/sc_refreshtimer.obj + +EXCEPTIONSFILES= \ + $(SLO)$/sc_addincol.obj + +# [kh] POWERPC compiler problem +.IF "$(OS)$(COM)$(CPUNAME)"=="LINUXGCCPOWERPC" +NOOPTFILES= \ + $(SLO)$/sc_subtotal.obj +.ENDIF + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/binfilter/bf_sc/source/core/tool/sc_addincol.cxx b/binfilter/bf_sc/source/core/tool/sc_addincol.cxx new file mode 100644 index 000000000000..e1fced76bac2 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_addincol.cxx @@ -0,0 +1,1119 @@ +/* -*- 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 <comphelper/processfactory.hxx> +#include <tools/debug.hxx> +#include <i18npool/mslangid.hxx> +#include <vcl/svapp.hxx> +#include <bf_sfx2/objsh.hxx> +#include <unotools/charclass.hxx> + +#include <com/sun/star/container/XContentEnumerationAccess.hpp> +#include <com/sun/star/lang/XServiceName.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/reflection/XIdlClass.hpp> +#include <com/sun/star/reflection/XIdlClassProvider.hpp> +#include <com/sun/star/beans/XIntrospectionAccess.hpp> +#include <com/sun/star/beans/XIntrospection.hpp> +#include <com/sun/star/beans/MethodConcept.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/table/XCellRange.hpp> +#include <com/sun/star/lang/Locale.hpp> +#include <com/sun/star/sheet/XCompatibilityNames.hpp> + +#include "addincol.hxx" +#include "addinhelpid.hxx" +#include "compiler.hxx" +#include "scmatrix.hxx" +#include "addinlis.hxx" +#include "scfuncs.hrc" +#include <legacysmgr/legacy_binfilters_smgr.hxx> +namespace binfilter { +using namespace ::com::sun::star; + +//------------------------------------------------------------------------ + +#define SC_CALLERPOS_NONE (-1) + +#define SCADDINSUPPLIER_SERVICE "com.sun.star.sheet.AddIn" + +//------------------------------------------------------------------------ + + +#define SC_FUNCGROUP_COUNT ID_FUNCTION_GRP_ADDINS + +static const sal_Char* __FAR_DATA aFuncNames[SC_FUNCGROUP_COUNT] = + { + // array index = ID - 1 (ID starts at 1) + // all upper case + "Database", // ID_FUNCTION_GRP_DATABASE + "Date&Time", // ID_FUNCTION_GRP_DATETIME + "Financial", // ID_FUNCTION_GRP_FINANZ + "Information", // ID_FUNCTION_GRP_INFO + "Logical", // ID_FUNCTION_GRP_LOGIC + "Mathematical", // ID_FUNCTION_GRP_MATH + "Matrix", // ID_FUNCTION_GRP_MATRIX + "Statistical", // ID_FUNCTION_GRP_STATISTIC + "Spreadsheet", // ID_FUNCTION_GRP_TABLE + "Text", // ID_FUNCTION_GRP_TEXT + "Add-In" // ID_FUNCTION_GRP_ADDINS + }; + + +//------------------------------------------------------------------------ + +struct ScAddInArgDesc +{ + String aName; + String aDescription; + ScAddInArgumentType eType; + BOOL bOptional; +}; + +class ScUnoAddInFuncData +{ +private: + String aOriginalName; // kept in formula + String aLocalName; // for display + String aUpperName; // for entering formulas + String aUpperLocal; // for entering formulas + String aDescription; + uno::Reference<reflection::XIdlMethod> xFunction; + uno::Any aObject; + long nArgCount; + ScAddInArgDesc* pArgDescs; + long nCallerPos; + USHORT nCategory; + USHORT nHelpId; + mutable uno::Sequence<sheet::LocalizedName> aCompNames; + mutable BOOL bCompInitialized; + +public: + ScUnoAddInFuncData( const String& rNam, const String& rLoc, + const String& rDesc, + USHORT nCat, USHORT nHelp, + const uno::Reference<reflection::XIdlMethod>& rFunc, + const uno::Any& rO, + long nAC, const ScAddInArgDesc* pAD, + long nCP ); + ~ScUnoAddInFuncData(); + + const String& GetOriginalName() const { return aOriginalName; } + const String& GetLocalName() const { return aLocalName; } + const String& GetUpperName() const { return aUpperName; } + const String& GetUpperLocal() const { return aUpperLocal; } + const uno::Reference<reflection::XIdlMethod>& GetFunction() const + { return xFunction; } + const uno::Any& GetObject() const { return aObject; } + long GetArgumentCount() const { return nArgCount; } + const ScAddInArgDesc* GetArguments() const { return pArgDescs; } + long GetCallerPos() const { return nCallerPos; } + const String& GetDescription() const { return aDescription; } + USHORT GetCategory() const { return nCategory; } + USHORT GetHelpId() const { return nHelpId; } + + const uno::Sequence<sheet::LocalizedName>& GetCompNames() const; +}; + +//------------------------------------------------------------------------ + +/*N*/ ScUnoAddInFuncData::ScUnoAddInFuncData( const String& rNam, const String& rLoc, +/*N*/ const String& rDesc, +/*N*/ USHORT nCat, USHORT nHelp, +/*N*/ const uno::Reference<reflection::XIdlMethod>& rFunc, +/*N*/ const uno::Any& rO, +/*N*/ long nAC, const ScAddInArgDesc* pAD, +/*N*/ long nCP ) : +/*N*/ aOriginalName( rNam ), +/*N*/ aUpperName( rNam ), +/*N*/ aLocalName( rLoc ), +/*N*/ aUpperLocal( rLoc ), +/*N*/ aDescription( rDesc ), +/*N*/ nCategory( nCat ), +/*N*/ nHelpId( nHelp ), +/*N*/ xFunction( rFunc ), +/*N*/ aObject( rO ), +/*N*/ nArgCount( nAC ), +/*N*/ nCallerPos( nCP ), +/*N*/ bCompInitialized( FALSE ) +/*N*/ { +/*N*/ if ( nArgCount ) +/*N*/ { +/*N*/ pArgDescs = new ScAddInArgDesc[nArgCount]; +/*N*/ for (long i=0; i<nArgCount; i++) +/*N*/ pArgDescs[i] = pAD[i]; +/*N*/ } +/*N*/ else +/*N*/ pArgDescs = NULL; +/*N*/ +/*N*/ ScGlobal::pCharClass->toUpper(aUpperName); +/*N*/ ScGlobal::pCharClass->toUpper(aUpperLocal); +/*N*/ } + +/*N*/ ScUnoAddInFuncData::~ScUnoAddInFuncData() +/*N*/ { +/*N*/ delete[] pArgDescs; +/*N*/ } + + +//------------------------------------------------------------------------ + +/*N*/ BOOL lcl_ConvertToDouble( const uno::Any& rAny, double& rOut ) +/*N*/ { +/*N*/ BOOL bRet = FALSE; +/*N*/ uno::TypeClass eClass = rAny.getValueTypeClass(); +/*N*/ switch (eClass) +/*N*/ { +/*N*/ //! extract integer values +/*N*/ case uno::TypeClass_ENUM: +/*N*/ case uno::TypeClass_BOOLEAN: +/*N*/ case uno::TypeClass_CHAR: +/*N*/ case uno::TypeClass_BYTE: +/*N*/ case uno::TypeClass_SHORT: +/*N*/ case uno::TypeClass_UNSIGNED_SHORT: +/*N*/ case uno::TypeClass_LONG: +/*N*/ case uno::TypeClass_UNSIGNED_LONG: +/*N*/ case uno::TypeClass_FLOAT: +/*N*/ case uno::TypeClass_DOUBLE: +/*N*/ rAny >>= rOut; +/*N*/ bRet = TRUE; +/*N*/ break; +/*N*/ } +/*N*/ if (!bRet) +/*N*/ rOut = 0.0; +/*N*/ return bRet; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ ScUnoAddInCollection::ScUnoAddInCollection() : +/*N*/ nFuncCount( 0 ), +/*N*/ ppFuncData( NULL ), +/*N*/ pExactHashMap( NULL ), +/*N*/ pNameHashMap( NULL ), +/*N*/ pLocalHashMap( NULL ), +/*N*/ bInitialized( FALSE ) +/*N*/ { +/*N*/ } + +/*N*/ ScUnoAddInCollection::~ScUnoAddInCollection() +/*N*/ { +/*N*/ delete pExactHashMap; +/*N*/ delete pNameHashMap; +/*N*/ delete pLocalHashMap; +/*N*/ if ( ppFuncData ) +/*N*/ { +/*N*/ for ( long i=0; i<nFuncCount; i++ ) +/*N*/ delete ppFuncData[i]; +/*N*/ delete[] ppFuncData; +/*N*/ } +/*N*/ } + +/*N*/ void ScUnoAddInCollection::Initialize() +/*N*/ { +/*N*/ DBG_ASSERT( !bInitialized, "Initialize twice?" ); +/*N*/ +/*N*/ uno::Reference<lang::XMultiServiceFactory> xManager = ::legacy_binfilters::getLegacyProcessServiceFactory(); +/*N*/ uno::Reference<container::XContentEnumerationAccess> xEnAc( xManager, uno::UNO_QUERY ); +/*N*/ if ( xEnAc.is() ) +/*N*/ { +/*N*/ uno::Reference<container::XEnumeration> xEnum = +/*N*/ xEnAc->createContentEnumeration( +/*N*/ ::rtl::OUString::createFromAscii(SCADDINSUPPLIER_SERVICE) ); +/*N*/ if ( xEnum.is() ) +/*N*/ { +/*N*/ // loop through all AddIns +/*N*/ while ( xEnum->hasMoreElements() ) +/*N*/ { +/*N*/ uno::Any aAddInAny = xEnum->nextElement(); +/*N*/ //? if ( aAddInAny.getReflection()->getTypeClass() == uno::TypeClass_INTERFACE ) +/*N*/ { +/*N*/ uno::Reference<uno::XInterface> xIntFac; +/*N*/ aAddInAny >>= xIntFac; +/*N*/ if ( xIntFac.is() ) +/*N*/ { +/*N*/ uno::Reference<lang::XSingleServiceFactory> xFac( xIntFac, uno::UNO_QUERY ); +/*N*/ if ( xFac.is() ) +/*N*/ { +/*N*/ uno::Reference<uno::XInterface> xInterface = xFac->createInstance(); +/*N*/ ReadFromAddIn( xInterface ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ bInitialized = TRUE; // with or without functions +/*N*/ } + + + +/*N*/ USHORT lcl_GetCategory( const String& rName ) +/*N*/ { +/*N*/ for (USHORT i=0; i<SC_FUNCGROUP_COUNT; i++) +/*N*/ if ( rName.EqualsAscii( aFuncNames[i] ) ) +/*N*/ return i+1; // IDs start at 1 +/*N*/ +/*N*/ return ID_FUNCTION_GRP_ADDINS; // if not found, use Add-In group +/*N*/ } + +/*N*/ inline BOOL IsTypeName( const ::rtl::OUString& rName, const uno::Type& rType ) +/*N*/ { +/*N*/ return rName == rType.getTypeName(); +/*N*/ } + +/*N*/ BOOL lcl_ValidReturnType( const uno::Reference<reflection::XIdlClass>& xClass ) +/*N*/ { +/*N*/ // this must match with ScUnoAddInCall::SetResult +/*N*/ +/*N*/ if ( !xClass.is() ) return FALSE; +/*N*/ +/*N*/ switch (xClass->getTypeClass()) +/*N*/ { +/*N*/ // case uno::TypeClass_VOID: +/*N*/ // ??? +/*N*/ +/*N*/ case uno::TypeClass_ANY: // variable type +/*N*/ case uno::TypeClass_ENUM: //! ??? +/*N*/ case uno::TypeClass_BOOLEAN: +/*N*/ case uno::TypeClass_CHAR: +/*N*/ case uno::TypeClass_BYTE: +/*N*/ case uno::TypeClass_SHORT: +/*N*/ case uno::TypeClass_UNSIGNED_SHORT: +/*N*/ case uno::TypeClass_LONG: +/*N*/ case uno::TypeClass_UNSIGNED_LONG: +/*N*/ case uno::TypeClass_FLOAT: +/*N*/ case uno::TypeClass_DOUBLE: +/*N*/ case uno::TypeClass_STRING: +/*N*/ return TRUE; // values or string +/*N*/ +/*N*/ case uno::TypeClass_INTERFACE: +/*N*/ { +/*N*/ // return type XInterface may contain a XVolatileResult +/*N*/ //! XIdlClass needs getType() method! +/*N*/ +/*N*/ ::rtl::OUString sName = xClass->getName(); +/*N*/ return ( +/*N*/ IsTypeName( sName, getCppuType((uno::Reference<sheet::XVolatileResult>*)0) ) || +/*N*/ IsTypeName( sName, getCppuType((uno::Reference<uno::XInterface>*)0) ) ); +/*N*/ } +/*N*/ +/*N*/ default: +/*N*/ { +/*N*/ // nested sequences for arrays +/*N*/ //! XIdlClass needs getType() method! +/*N*/ +/*N*/ ::rtl::OUString sName = xClass->getName(); +/*N*/ return ( +/*N*/ IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<INT32> >*)0) ) || +/*N*/ IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<double> >*)0) ) || +/*N*/ IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<rtl::OUString> >*)0) ) || +/*N*/ IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<uno::Any> >*)0) ) ); +/*N*/ } +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/*N*/ ScAddInArgumentType lcl_GetArgType( const uno::Reference<reflection::XIdlClass>& xClass ) +/*N*/ { +/*N*/ if (!xClass.is()) +/*N*/ return SC_ADDINARG_NONE; +/*N*/ +/*N*/ uno::TypeClass eType = xClass->getTypeClass(); +/*N*/ +/*N*/ if ( eType == uno::TypeClass_LONG ) //! other integer types? +/*N*/ return SC_ADDINARG_INTEGER; +/*N*/ +/*N*/ if ( eType == uno::TypeClass_DOUBLE ) +/*N*/ return SC_ADDINARG_DOUBLE; +/*N*/ +/*N*/ if ( eType == uno::TypeClass_STRING ) +/*N*/ return SC_ADDINARG_STRING; +/*N*/ +/*N*/ //! XIdlClass needs getType() method! +/*N*/ ::rtl::OUString sName = xClass->getName(); +/*N*/ +/*N*/ if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<INT32> >*)0) )) +/*N*/ return SC_ADDINARG_INTEGER_ARRAY; +/*N*/ +/*N*/ if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<double> >*)0) )) +/*N*/ return SC_ADDINARG_DOUBLE_ARRAY; +/*N*/ +/*N*/ if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<rtl::OUString> >*)0) )) +/*N*/ return SC_ADDINARG_STRING_ARRAY; +/*N*/ +/*N*/ if (IsTypeName( sName, getCppuType((uno::Sequence< uno::Sequence<uno::Any> >*)0) )) +/*N*/ return SC_ADDINARG_MIXED_ARRAY; +/*N*/ +/*N*/ if (IsTypeName( sName, getCppuType((uno::Any*)0) )) +/*N*/ return SC_ADDINARG_VALUE_OR_ARRAY; +/*N*/ +/*N*/ if (IsTypeName( sName, getCppuType((uno::Reference<table::XCellRange>*)0) )) +/*N*/ return SC_ADDINARG_CELLRANGE; +/*N*/ +/*N*/ if (IsTypeName( sName, getCppuType((uno::Reference<beans::XPropertySet>*)0) )) +/*N*/ return SC_ADDINARG_CALLER; +/*N*/ +/*N*/ if (IsTypeName( sName, getCppuType((uno::Sequence<uno::Any>*)0) )) +/*N*/ return SC_ADDINARG_VARARGS; +/*N*/ +/*N*/ return SC_ADDINARG_NONE; +/*N*/ } + +/*N*/ void ScUnoAddInCollection::ReadFromAddIn( const uno::Reference<uno::XInterface>& xInterface ) +/*N*/ { +/*N*/ uno::Reference<sheet::XAddIn> xAddIn( xInterface, uno::UNO_QUERY ); +/*N*/ uno::Reference<lang::XServiceName> xName( xInterface, uno::UNO_QUERY ); +/*N*/ if ( xAddIn.is() && xName.is() ) +/*N*/ { +/*N*/ // AddIns must use the language for which the office is installed +/*N*/ LanguageType eOfficeLang = Application::GetSettings().GetUILanguage(); +/*N*/ +/*N*/ lang::Locale aLocale( MsLangId::convertLanguageToLocale( eOfficeLang )); +/*N*/ xAddIn->setLocale( aLocale ); +/*N*/ +/*N*/ String aServiceName = String( xName->getServiceName() ); +/*N*/ ScUnoAddInHelpIdGenerator aHelpIdGenerator( xName->getServiceName() ); +/*N*/ +/*N*/ //! pass XIntrospection to ReadFromAddIn +/*N*/ +/*N*/ uno::Reference<lang::XMultiServiceFactory> xManager = ::legacy_binfilters::getLegacyProcessServiceFactory(); +/*N*/ if ( xManager.is() ) +/*N*/ { +/*N*/ uno::Reference<beans::XIntrospection> xIntro( +/*N*/ xManager->createInstance(::rtl::OUString::createFromAscii( +/*N*/ "com.sun.star.beans.Introspection" )), +/*N*/ uno::UNO_QUERY ); +/*N*/ if ( xIntro.is() ) +/*N*/ { +/*N*/ uno::Any aObject; +/*N*/ aObject <<= xAddIn; +/*N*/ uno::Reference<beans::XIntrospectionAccess> xAcc = xIntro->inspect(aObject); +/*N*/ if (xAcc.is()) +/*N*/ { +/*N*/ uno::Sequence< uno::Reference<reflection::XIdlMethod> > aMethods = +/*N*/ xAcc->getMethods( beans::MethodConcept::ALL ); +/*N*/ long nNewCount = aMethods.getLength(); +/*N*/ if ( nNewCount ) +/*N*/ { +/*N*/ long nOld = nFuncCount; +/*N*/ nFuncCount = nNewCount+nOld; +/*N*/ if ( nOld ) +/*N*/ { +/*N*/ ScUnoAddInFuncData** ppNew = new ScUnoAddInFuncData*[nFuncCount]; +/*N*/ for (long i=0; i<nOld; i++) +/*N*/ ppNew[i] = ppFuncData[i]; +/*N*/ delete[] ppFuncData; +/*N*/ ppFuncData = ppNew; +/*N*/ } +/*N*/ else +/*N*/ ppFuncData = new ScUnoAddInFuncData*[nFuncCount]; +/*N*/ +/*N*/ //! TODO: adjust bucket count? +/*N*/ if ( !pExactHashMap ) +/*N*/ pExactHashMap = new ScAddInHashMap; +/*N*/ if ( !pNameHashMap ) +/*N*/ pNameHashMap = new ScAddInHashMap; +/*N*/ if ( !pLocalHashMap ) +/*N*/ pLocalHashMap = new ScAddInHashMap; +/*N*/ +/*N*/ const uno::Reference<reflection::XIdlMethod>* pArray = aMethods.getConstArray(); +/*N*/ for (long nFuncPos=0; nFuncPos<nNewCount; nFuncPos++) +/*N*/ { +/*N*/ ppFuncData[nFuncPos+nOld] = NULL; +/*N*/ +/*N*/ uno::Reference<reflection::XIdlMethod> xFunc = pArray[nFuncPos]; +/*N*/ if (xFunc.is()) +/*N*/ { +/*N*/ // leave out internal functions +/*N*/ uno::Reference<reflection::XIdlClass> xClass = +/*N*/ xFunc->getDeclaringClass(); +/*N*/ BOOL bSkip = TRUE; +/*N*/ if ( xClass.is() ) +/*N*/ { +/*N*/ //! XIdlClass needs getType() method! +/*N*/ ::rtl::OUString sName = xClass->getName(); +/*N*/ bSkip = ( +/*N*/ IsTypeName( sName, +/*N*/ getCppuType((uno::Reference<uno::XInterface>*)0) ) || +/*N*/ IsTypeName( sName, +/*N*/ getCppuType((uno::Reference<reflection::XIdlClassProvider>*)0) ) || +/*N*/ IsTypeName( sName, +/*N*/ getCppuType((uno::Reference<lang::XServiceName>*)0) ) || +/*N*/ IsTypeName( sName, +/*N*/ getCppuType((uno::Reference<lang::XServiceInfo>*)0) ) || +/*N*/ IsTypeName( sName, +/*N*/ getCppuType((uno::Reference<sheet::XAddIn>*)0) ) ); +/*N*/ } +/*N*/ if (!bSkip) +/*N*/ { +/*N*/ uno::Reference<reflection::XIdlClass> xReturn = +/*N*/ xFunc->getReturnType(); +/*N*/ if ( !lcl_ValidReturnType( xReturn ) ) +/*N*/ bSkip = TRUE; +/*N*/ } +/*N*/ if (!bSkip) +/*N*/ { +/*N*/ ::rtl::OUString aFuncU = xFunc->getName(); +/*N*/ +/*N*/ // stored function name: (service name).(function) +/*N*/ String aFuncName = aServiceName; +/*N*/ aFuncName += '.'; +/*N*/ aFuncName += String( aFuncU ); +/*N*/ +/*N*/ BOOL bValid = TRUE; +/*N*/ long nVisibleCount = 0; +/*N*/ long nCallerPos = SC_CALLERPOS_NONE; +/*N*/ +/*N*/ uno::Sequence<reflection::ParamInfo> aParams = +/*N*/ xFunc->getParameterInfos(); +/*N*/ long nParamCount = aParams.getLength(); +/*N*/ const reflection::ParamInfo* pParArr = aParams.getConstArray(); +/*N*/ long nParamPos; +/*N*/ for (nParamPos=0; nParamPos<nParamCount; nParamPos++) +/*N*/ { +/*N*/ if ( pParArr[nParamPos].aMode != reflection::ParamMode_IN ) +/*N*/ bValid = FALSE; +/*N*/ uno::Reference<reflection::XIdlClass> xParClass = +/*N*/ pParArr[nParamPos].aType; +/*N*/ ScAddInArgumentType eArgType = lcl_GetArgType( xParClass ); +/*N*/ if ( eArgType == SC_ADDINARG_NONE ) +/*N*/ bValid = FALSE; +/*N*/ else if ( eArgType == SC_ADDINARG_CALLER ) +/*N*/ nCallerPos = nParamPos; +/*N*/ else +/*N*/ ++nVisibleCount; +/*N*/ } +/*N*/ if (bValid) +/*N*/ { +/*N*/ USHORT nCategory = lcl_GetCategory( +/*N*/ String( +/*N*/ xAddIn->getProgrammaticCategoryName( +/*N*/ aFuncU ) ) ); +/*N*/ +/*N*/ USHORT nHelpId = aHelpIdGenerator.GetHelpId( aFuncU ); +/*N*/ +/*N*/ ::rtl::OUString aLocalU; +/*N*/ try +/*N*/ { +/*N*/ aLocalU = xAddIn-> +/*N*/ getDisplayFunctionName( aFuncU ); +/*N*/ } +/*N*/ catch(uno::Exception&) +/*N*/ { +/*N*/ aLocalU = ::rtl::OUString::createFromAscii( "###" ); +/*N*/ } +/*N*/ String aLocalName = String( aLocalU ); +/*N*/ +/*N*/ ::rtl::OUString aDescU; +/*N*/ try +/*N*/ { +/*N*/ aDescU = xAddIn-> +/*N*/ getFunctionDescription( aFuncU ); +/*N*/ } +/*N*/ catch(uno::Exception&) +/*N*/ { +/*N*/ aDescU = ::rtl::OUString::createFromAscii( "###" ); +/*N*/ } +/*N*/ String aDescription = String( aDescU ); +/*N*/ +/*N*/ ScAddInArgDesc* pVisibleArgs = NULL; +/*N*/ if ( nVisibleCount > 0 ) +/*N*/ { +/*N*/ ScAddInArgDesc aDesc; +/*N*/ pVisibleArgs = new ScAddInArgDesc[nVisibleCount]; +/*N*/ long nDestPos = 0; +/*N*/ for (nParamPos=0; nParamPos<nParamCount; nParamPos++) +/*N*/ { +/*N*/ uno::Reference<reflection::XIdlClass> xParClass = +/*N*/ pParArr[nParamPos].aType; +/*N*/ ScAddInArgumentType eArgType = lcl_GetArgType( xParClass ); +/*N*/ if ( eArgType != SC_ADDINARG_CALLER ) +/*N*/ { +/*N*/ ::rtl::OUString aArgName; +/*N*/ try +/*N*/ { +/*N*/ aArgName = xAddIn-> +/*N*/ getDisplayArgumentName( aFuncU, nParamPos ); +/*N*/ } +/*N*/ catch(uno::Exception&) +/*N*/ { +/*N*/ aArgName = ::rtl::OUString::createFromAscii( "###" ); +/*N*/ } +/*N*/ ::rtl::OUString aArgDesc; +/*N*/ try +/*N*/ { +/*N*/ aArgDesc = xAddIn-> +/*N*/ getArgumentDescription( aFuncU, nParamPos ); +/*N*/ } +/*N*/ catch(uno::Exception&) +/*N*/ { +/*N*/ aArgName = ::rtl::OUString::createFromAscii( "###" ); +/*N*/ } +/*N*/ +/*N*/ BOOL bOptional = +/*N*/ ( eArgType == SC_ADDINARG_VALUE_OR_ARRAY || +/*N*/ eArgType == SC_ADDINARG_VARARGS ); +/*N*/ +/*N*/ aDesc.eType = eArgType; +/*N*/ aDesc.aName = String( aArgName ); +/*N*/ aDesc.aDescription = String( aArgDesc ); +/*N*/ aDesc.bOptional = bOptional; +/*N*/ +/*N*/ pVisibleArgs[nDestPos++] = aDesc; +/*N*/ } +/*N*/ } +/*N*/ DBG_ASSERT( nDestPos==nVisibleCount, "wrong count" ); +/*N*/ } +/*N*/ +/*N*/ ppFuncData[nFuncPos+nOld] = new ScUnoAddInFuncData( +/*N*/ aFuncName, aLocalName, aDescription, +/*N*/ nCategory, nHelpId, +/*N*/ xFunc, aObject, +/*N*/ nVisibleCount, pVisibleArgs, nCallerPos ); +/*N*/ +/*N*/ const ScUnoAddInFuncData* pData = +/*N*/ ppFuncData[nFuncPos+nOld]; +/*N*/ pExactHashMap->insert( +/*N*/ ScAddInHashMap::value_type( +/*N*/ pData->GetOriginalName(), +/*N*/ pData ) ); +/*N*/ pNameHashMap->insert( +/*N*/ ScAddInHashMap::value_type( +/*N*/ pData->GetUpperName(), +/*N*/ pData ) ); +/*N*/ pLocalHashMap->insert( +/*N*/ ScAddInHashMap::value_type( +/*N*/ pData->GetUpperLocal(), +/*N*/ pData ) ); +/*N*/ +/*N*/ delete[] pVisibleArgs; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ String ScUnoAddInCollection::FindFunction( const String& rUpperName, BOOL bLocalFirst ) +/*N*/ { +/*N*/ if (!bInitialized) +/*N*/ Initialize(); +/*N*/ +/*N*/ if (nFuncCount == 0) +/*N*/ return EMPTY_STRING; +/*N*/ +/*N*/ if ( bLocalFirst ) +/*N*/ { +/*N*/ // first scan all local names (used for entering formulas) +/*N*/ +/*N*/ ScAddInHashMap::const_iterator iLook( pLocalHashMap->find( rUpperName ) ); +/*N*/ if ( iLook != pLocalHashMap->end() ) +/*?*/ return iLook->second->GetOriginalName(); +/*N*/ +/*N*/ #if 0 +/*N*/ // after that, scan international names (really?) +/*N*/ +/*N*/ iLook = pNameHashMap->find( rUpperName ); +/*N*/ if ( iLook != pNameHashMap->end() ) +/*N*/ return iLook->second->GetOriginalName(); +/*N*/ #endif +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // first scan international names (used when calling a function) +/*N*/ //! before that, check for exact match??? +/*N*/ +/*N*/ ScAddInHashMap::const_iterator iLook( pNameHashMap->find( rUpperName ) ); +/*N*/ if ( iLook != pNameHashMap->end() ) +/*N*/ return iLook->second->GetOriginalName(); +/*N*/ +/*N*/ // after that, scan all local names (to allow replacing old AddIns with Uno) +/*N*/ +/*N*/ iLook = pLocalHashMap->find( rUpperName ); +/*N*/ if ( iLook != pLocalHashMap->end() ) +/*N*/ return iLook->second->GetOriginalName(); +/*N*/ } +/*N*/ +/*N*/ return EMPTY_STRING; +/*N*/ } + +/*N*/ const ScUnoAddInFuncData* ScUnoAddInCollection::GetFuncData( const String& rName ) +/*N*/ { +/*N*/ if (!bInitialized) +/*?*/ Initialize(); +/*N*/ +/*N*/ // rName must be the exact internal name +/*N*/ +/*N*/ ScAddInHashMap::const_iterator iLook( pExactHashMap->find( rName ) ); +/*N*/ if ( iLook != pExactHashMap->end() ) +/*N*/ return iLook->second; +/*N*/ +/*N*/ return NULL; +/*N*/ } + + + + + + +//------------------------------------------------------------------------ + +/*N*/ ScUnoAddInCall::ScUnoAddInCall( ScUnoAddInCollection& rColl, const String& rName, +/*N*/ long nParamCount ) : +/*N*/ nErrCode( errNoCode ), // before function was called +/*N*/ bHasString( TRUE ), +/*N*/ fValue( 0.0 ), +/*N*/ pMatrix( NULL ), +/*N*/ bValidCount( FALSE ) +/*N*/ { +/*N*/ pFuncData = rColl.GetFuncData( rName ); +/*N*/ DBG_ASSERT( pFuncData, "Function Data missing" ); +/*N*/ if ( pFuncData ) +/*N*/ { +/*N*/ long nDescCount = pFuncData->GetArgumentCount(); +/*N*/ const ScAddInArgDesc* pArgs = pFuncData->GetArguments(); +/*N*/ long nVarCount = 0; +/*N*/ +/*N*/ // is aVarArg sequence needed? +/*N*/ if ( nParamCount >= nDescCount && nDescCount > 0 && +/*N*/ pArgs[nDescCount-1].eType == SC_ADDINARG_VARARGS ) +/*N*/ { +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 long nVarCount = nParamCount - ( nDescCount - 1 ); // size of last argument +/*N*/ } +/*N*/ else if ( nParamCount <= nDescCount ) +/*N*/ { +/*N*/ // all args behind nParamCount must be optional +/*N*/ bValidCount = TRUE; +/*N*/ for (long i=nParamCount; i<nDescCount; i++) +/*?*/ if ( !pArgs[i].bOptional ) +/*?*/ bValidCount = FALSE; +/*N*/ } +/*N*/ // else invalid (too many arguments) +/*N*/ +/*N*/ if ( bValidCount ) +/*N*/ aArgs.realloc( nDescCount ); // sequence must always match function signature +/*N*/ } +/*N*/ } + +/*N*/ ScUnoAddInCall::~ScUnoAddInCall() +/*N*/ { +/*N*/ // pFuncData is deleted with ScUnoAddInCollection +/*N*/ +/*N*/ delete pMatrix; +/*N*/ } + +/*N*/ BOOL ScUnoAddInCall::ValidParamCount() +/*N*/ { +/*N*/ return bValidCount; +/*N*/ } + +/*N*/ ScAddInArgumentType ScUnoAddInCall::GetArgType( long nPos ) +/*N*/ { +/*N*/ if ( pFuncData ) +/*N*/ { +/*N*/ long nCount = pFuncData->GetArgumentCount(); +/*N*/ const ScAddInArgDesc* pArgs = pFuncData->GetArguments(); +/*N*/ +/*N*/ // if last arg is sequence, use "any" type +/*N*/ if ( nCount > 0 && nPos >= nCount-1 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS ) +/*N*/ return SC_ADDINARG_VALUE_OR_ARRAY; +/*N*/ +/*N*/ if ( nPos < nCount ) +/*N*/ return pArgs[nPos].eType; +/*N*/ } +/*N*/ return SC_ADDINARG_VALUE_OR_ARRAY; //! error code !!!! +/*N*/ } + +/*N*/ BOOL ScUnoAddInCall::NeedsCaller() const +/*N*/ { +/*N*/ return pFuncData && pFuncData->GetCallerPos() != SC_CALLERPOS_NONE; +/*N*/ } + +/*N*/ void ScUnoAddInCall::SetCaller( const uno::Reference<uno::XInterface>& rInterface ) +/*N*/ { +/*N*/ xCaller = rInterface; +/*N*/ } + +/*N*/ void ScUnoAddInCall::SetCallerFromObjectShell( SfxObjectShell* pObjSh ) +/*N*/ { +/*N*/ if (pObjSh) +/*N*/ { +/*N*/ uno::Reference<uno::XInterface> xInt( pObjSh->GetBaseModel(), uno::UNO_QUERY ); +/*N*/ SetCaller( xInt ); +/*N*/ } +/*N*/ } + +/*N*/ void ScUnoAddInCall::SetParam( long nPos, const uno::Any& rValue ) +/*N*/ { +/*N*/ if ( pFuncData ) +/*N*/ { +/*N*/ long nCount = pFuncData->GetArgumentCount(); +/*N*/ const ScAddInArgDesc* pArgs = pFuncData->GetArguments(); +/*N*/ if ( nCount > 0 && nPos >= nCount-1 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS ) +/*N*/ { +/*N*/ long nVarPos = nPos-(nCount-1); +/*N*/ if ( nVarPos < aVarArg.getLength() ) +/*N*/ aVarArg.getArray()[nVarPos] = rValue; +/*N*/ else +/*N*/ DBG_ERROR("wrong argument number"); +/*N*/ } +/*N*/ else if ( nPos < aArgs.getLength() ) +/*N*/ aArgs.getArray()[nPos] = rValue; +/*N*/ else +/*N*/ DBG_ERROR("wrong argument number"); +/*N*/ } +/*N*/ } + +/*N*/ void ScUnoAddInCall::ExecuteCall() +/*N*/ { +/*N*/ if ( !pFuncData ) +/*N*/ return; +/*N*/ +/*N*/ long nCount = pFuncData->GetArgumentCount(); +/*N*/ const ScAddInArgDesc* pArgs = pFuncData->GetArguments(); +/*N*/ if ( nCount > 0 && pArgs[nCount-1].eType == SC_ADDINARG_VARARGS ) +/*N*/ { +/*N*/ // insert aVarArg as last argument +/*N*/ //! after inserting caller (to prevent copying twice)? +/*N*/ +/*N*/ DBG_ASSERT( aArgs.getLength() == nCount, "wrong argument count" ); +/*N*/ aArgs.getArray()[nCount-1] <<= aVarArg; +/*N*/ } +/*N*/ +/*N*/ if ( pFuncData->GetCallerPos() != SC_CALLERPOS_NONE ) +/*N*/ { +/*N*/ uno::Any aCallerAny; +/*N*/ aCallerAny <<= xCaller; +/*N*/ +/*N*/ long nUserLen = aArgs.getLength(); +/*N*/ long nCallPos = pFuncData->GetCallerPos(); +/*N*/ if (nCallPos>nUserLen) // should not happen +/*N*/ { +/*N*/ DBG_ERROR("wrong CallPos"); +/*N*/ nCallPos = nUserLen; +/*N*/ } +/*N*/ +/*N*/ long nDestLen = nUserLen + 1; +/*N*/ uno::Sequence<uno::Any> aRealArgs( nDestLen ); +/*N*/ uno::Any* pDest = aRealArgs.getArray(); +/*N*/ +/*N*/ const uno::Any* pSource = aArgs.getConstArray(); +/*N*/ long nSrcPos = 0; +/*N*/ +/*N*/ for ( long nDestPos = 0; nDestPos < nDestLen; nDestPos++ ) +/*N*/ { +/*N*/ if ( nDestPos == nCallPos ) +/*N*/ pDest[nDestPos] = aCallerAny; +/*N*/ else +/*N*/ pDest[nDestPos] = pSource[nSrcPos++]; +/*N*/ } +/*N*/ +/*N*/ ExecuteCallWithArgs( aRealArgs ); +/*N*/ } +/*N*/ else +/*N*/ ExecuteCallWithArgs( aArgs ); +/*N*/ } + +/*N*/ void ScUnoAddInCall::ExecuteCallWithArgs(uno::Sequence<uno::Any>& rCallArgs) +/*N*/ { +/*N*/ // rCallArgs may not match argument descriptions (because of caller) +/*N*/ +/*N*/ uno::Reference<reflection::XIdlMethod> xFunction; +/*N*/ uno::Any aObject; +/*N*/ if ( pFuncData ) +/*N*/ { +/*N*/ xFunction = pFuncData->GetFunction(); +/*N*/ aObject = pFuncData->GetObject(); +/*N*/ } +/*N*/ +/*N*/ if ( xFunction.is() ) +/*N*/ { +/*N*/ uno::Any aAny; +/*N*/ nErrCode = 0; +/*N*/ +/*N*/ try +/*N*/ { +/*N*/ aAny = xFunction->invoke( aObject, rCallArgs ); +/*N*/ } +/*N*/ catch(lang::IllegalArgumentException&) +/*N*/ { +/*N*/ nErrCode = errIllegalArgument; +/*N*/ } +/*N*/ #if 0 +/*N*/ catch(FloatingPointException&) +/*N*/ { +/*N*/ nErrCode = errIllegalFPOperation; +/*N*/ } +/*N*/ #endif +/*N*/ catch(reflection::InvocationTargetException& rWrapped) +/*N*/ { +/*N*/ if ( rWrapped.TargetException.getValueType().equals( +/*N*/ getCppuType( (lang::IllegalArgumentException*)0 ) ) ) +/*N*/ nErrCode = errIllegalArgument; +/*N*/ else +/*N*/ nErrCode = errNoValue; +/*N*/ } +/*N*/ catch(uno::Exception&) +/*N*/ { +/*N*/ nErrCode = errNoValue; +/*N*/ } +/*N*/ +/*N*/ if (!nErrCode) +/*N*/ SetResult( aAny ); // convert result to Calc types +/*N*/ } +/*N*/ } + +/*N*/ void ScUnoAddInCall::SetResult( const uno::Any& rNewRes ) +/*N*/ { +/*N*/ nErrCode = 0; +/*N*/ xVarRes = NULL; +/*N*/ +/*N*/ // Reflection* pRefl = rNewRes.getReflection(); +/*N*/ +/*N*/ uno::TypeClass eClass = rNewRes.getValueTypeClass(); +/*N*/ uno::Type aType = rNewRes.getValueType(); +/*N*/ switch (eClass) +/*N*/ { +/*N*/ case uno::TypeClass_VOID: +/*N*/ nErrCode = NOVALUE; // #nv +/*N*/ break; +/*N*/ +/*N*/ case uno::TypeClass_ENUM: +/*N*/ case uno::TypeClass_BOOLEAN: +/*N*/ case uno::TypeClass_CHAR: +/*N*/ case uno::TypeClass_BYTE: +/*N*/ case uno::TypeClass_SHORT: +/*N*/ case uno::TypeClass_UNSIGNED_SHORT: +/*N*/ case uno::TypeClass_LONG: +/*N*/ case uno::TypeClass_UNSIGNED_LONG: +/*N*/ case uno::TypeClass_FLOAT: +/*N*/ case uno::TypeClass_DOUBLE: +/*N*/ lcl_ConvertToDouble( rNewRes, fValue ); +/*N*/ bHasString = FALSE; +/*N*/ break; +/*N*/ +/*N*/ case uno::TypeClass_STRING: +/*N*/ { +/*N*/ ::rtl::OUString aUStr; +/*N*/ rNewRes >>= aUStr; +/*N*/ aString = String( aUStr ); +/*N*/ bHasString = TRUE; +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ case uno::TypeClass_INTERFACE: +/*N*/ { +/*N*/ //! directly extract XVolatileResult from any? +/*N*/ uno::Reference<uno::XInterface> xInterface; +/*N*/ rNewRes >>= xInterface; +/*N*/ if ( xInterface.is() ) +/*N*/ xVarRes = uno::Reference<sheet::XVolatileResult>( xInterface, uno::UNO_QUERY ); +/*N*/ +/*N*/ if (!xVarRes.is()) +/*N*/ nErrCode = errNoValue; // unknown interface +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ default: +/*N*/ if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<INT32> > *)0 ) ) ) +/*N*/ { +/*N*/ const uno::Sequence< uno::Sequence<INT32> >* pRowSeq = NULL; +/*N*/ +/*N*/ //! use pointer from any! +/*N*/ uno::Sequence< uno::Sequence<INT32> > aSequence; +/*N*/ if ( rNewRes >>= aSequence ) +/*N*/ pRowSeq = &aSequence; +/*N*/ +/*N*/ if ( pRowSeq ) +/*N*/ { +/*N*/ long nRowCount = pRowSeq->getLength(); +/*N*/ const uno::Sequence<INT32>* pRowArr = pRowSeq->getConstArray(); +/*N*/ long nMaxColCount = 0; +/*N*/ long nCol, nRow; +/*N*/ for (nRow=0; nRow<nRowCount; nRow++) +/*N*/ { +/*N*/ long nTmp = pRowArr[nRow].getLength(); +/*N*/ if ( nTmp > nMaxColCount ) +/*N*/ nMaxColCount = nTmp; +/*N*/ } +/*N*/ if ( nMaxColCount && nRowCount ) +/*N*/ { +/*N*/ pMatrix = new ScMatrix( (USHORT)nMaxColCount, (USHORT)nRowCount ); +/*N*/ for (nRow=0; nRow<nRowCount; nRow++) +/*N*/ { +/*N*/ long nColCount = pRowArr[nRow].getLength(); +/*N*/ const INT32* pColArr = pRowArr[nRow].getConstArray(); +/*N*/ for (nCol=0; nCol<nColCount; nCol++) +/*N*/ pMatrix->PutDouble( pColArr[nCol], (USHORT)nCol, (USHORT)nRow ); +/*N*/ for (nCol=nColCount; nCol<nMaxColCount; nCol++) +/*N*/ pMatrix->PutDouble( 0.0, (USHORT)nCol, (USHORT)nRow ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<double> > *)0 ) ) ) +/*N*/ { +/*N*/ const uno::Sequence< uno::Sequence<double> >* pRowSeq = NULL; +/*N*/ +/*N*/ //! use pointer from any! +/*N*/ uno::Sequence< uno::Sequence<double> > aSequence; +/*N*/ if ( rNewRes >>= aSequence ) +/*N*/ pRowSeq = &aSequence; +/*N*/ +/*N*/ if ( pRowSeq ) +/*N*/ { +/*N*/ long nRowCount = pRowSeq->getLength(); +/*N*/ const uno::Sequence<double>* pRowArr = pRowSeq->getConstArray(); +/*N*/ long nMaxColCount = 0; +/*N*/ long nCol, nRow; +/*N*/ for (nRow=0; nRow<nRowCount; nRow++) +/*N*/ { +/*N*/ long nTmp = pRowArr[nRow].getLength(); +/*N*/ if ( nTmp > nMaxColCount ) +/*N*/ nMaxColCount = nTmp; +/*N*/ } +/*N*/ if ( nMaxColCount && nRowCount ) +/*N*/ { +/*N*/ pMatrix = new ScMatrix( (USHORT)nMaxColCount, (USHORT)nRowCount ); +/*N*/ for (nRow=0; nRow<nRowCount; nRow++) +/*N*/ { +/*N*/ long nColCount = pRowArr[nRow].getLength(); +/*N*/ const double* pColArr = pRowArr[nRow].getConstArray(); +/*N*/ for (nCol=0; nCol<nColCount; nCol++) +/*N*/ pMatrix->PutDouble( pColArr[nCol], (USHORT)nCol, (USHORT)nRow ); +/*N*/ for (nCol=nColCount; nCol<nMaxColCount; nCol++) +/*N*/ pMatrix->PutDouble( 0.0, (USHORT)nCol, (USHORT)nRow ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<rtl::OUString> > *)0 ) ) ) +/*N*/ { +/*N*/ const uno::Sequence< uno::Sequence<rtl::OUString> >* pRowSeq = NULL; +/*N*/ +/*N*/ //! use pointer from any! +/*N*/ uno::Sequence< uno::Sequence<rtl::OUString> > aSequence; +/*N*/ if ( rNewRes >>= aSequence ) +/*N*/ pRowSeq = &aSequence; +/*N*/ +/*N*/ if ( pRowSeq ) +/*N*/ { +/*N*/ long nRowCount = pRowSeq->getLength(); +/*N*/ const uno::Sequence<rtl::OUString>* pRowArr = pRowSeq->getConstArray(); +/*N*/ long nMaxColCount = 0; +/*N*/ long nCol, nRow; +/*N*/ for (nRow=0; nRow<nRowCount; nRow++) +/*N*/ { +/*N*/ long nTmp = pRowArr[nRow].getLength(); +/*N*/ if ( nTmp > nMaxColCount ) +/*N*/ nMaxColCount = nTmp; +/*N*/ } +/*N*/ if ( nMaxColCount && nRowCount ) +/*N*/ { +/*N*/ pMatrix = new ScMatrix( (USHORT)nMaxColCount, (USHORT)nRowCount ); +/*N*/ for (nRow=0; nRow<nRowCount; nRow++) +/*N*/ { +/*N*/ long nColCount = pRowArr[nRow].getLength(); +/*N*/ const ::rtl::OUString* pColArr = pRowArr[nRow].getConstArray(); +/*N*/ for (nCol=0; nCol<nColCount; nCol++) +/*N*/ pMatrix->PutString( String( pColArr[nCol] ), +/*N*/ (USHORT)nCol, (USHORT)nRow ); +/*N*/ for (nCol=nColCount; nCol<nMaxColCount; nCol++) +/*N*/ pMatrix->PutString( EMPTY_STRING, (USHORT)nCol, (USHORT)nRow ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<uno::Any> > *)0 ) ) ) +/*N*/ { +/*N*/ const uno::Sequence< uno::Sequence<uno::Any> >* pRowSeq = NULL; +/*N*/ +/*N*/ //! use pointer from any! +/*N*/ uno::Sequence< uno::Sequence<uno::Any> > aSequence; +/*N*/ if ( rNewRes >>= aSequence ) +/*N*/ pRowSeq = &aSequence; +/*N*/ +/*N*/ if ( pRowSeq ) +/*N*/ { +/*N*/ long nRowCount = pRowSeq->getLength(); +/*N*/ const uno::Sequence<uno::Any>* pRowArr = pRowSeq->getConstArray(); +/*N*/ long nMaxColCount = 0; +/*N*/ long nCol, nRow; +/*N*/ for (nRow=0; nRow<nRowCount; nRow++) +/*N*/ { +/*N*/ long nTmp = pRowArr[nRow].getLength(); +/*N*/ if ( nTmp > nMaxColCount ) +/*N*/ nMaxColCount = nTmp; +/*N*/ } +/*N*/ if ( nMaxColCount && nRowCount ) +/*N*/ { +/*N*/ ::rtl::OUString aUStr; +/*N*/ pMatrix = new ScMatrix( (USHORT)nMaxColCount, (USHORT)nRowCount ); +/*N*/ for (nRow=0; nRow<nRowCount; nRow++) +/*N*/ { +/*N*/ long nColCount = pRowArr[nRow].getLength(); +/*N*/ const uno::Any* pColArr = pRowArr[nRow].getConstArray(); +/*N*/ for (nCol=0; nCol<nColCount; nCol++) +/*N*/ { +/*N*/ //Reflection* pRefl = pColArr[nCol].getReflection(); +/*N*/ //if ( pRefl->equals( *OUString_getReflection() ) ) +/*N*/ if ( pColArr[nCol] >>= aUStr ) +/*N*/ pMatrix->PutString( String( aUStr ), +/*N*/ (USHORT)nCol, (USHORT)nRow ); +/*N*/ else +/*N*/ { +/*N*/ // try to convert to double, empty if not possible +/*N*/ +/*N*/ double fCellVal; +/*N*/ if ( lcl_ConvertToDouble( pColArr[nCol], fCellVal ) ) +/*N*/ pMatrix->PutDouble( fCellVal, (USHORT)nCol, (USHORT)nRow ); +/*N*/ else +/*N*/ pMatrix->PutEmpty( (USHORT)nCol, (USHORT)nRow ); +/*N*/ } +/*N*/ } +/*N*/ for (nCol=nColCount; nCol<nMaxColCount; nCol++) +/*N*/ pMatrix->PutString( EMPTY_STRING, (USHORT)nCol, (USHORT)nRow ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if (!pMatrix) // no array found +/*N*/ nErrCode = errNoValue; //! code for error in return type??? +/*N*/ } +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_addinhelpid.cxx b/binfilter/bf_sc/source/core/tool/sc_addinhelpid.cxx new file mode 100644 index 000000000000..31321aaa35d2 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_addinhelpid.cxx @@ -0,0 +1,221 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// ============================================================================ + +#include "addinhelpid.hxx" + +#include "bf_sc.hrc" +namespace binfilter { + + +// ============================================================================ + +// A struct containing the built-in function name and the built-in help ID. +struct ScUnoAddInHelpId +{ + const sal_Char* pFuncName; + sal_uInt16 nHelpId; +}; + + +// ---------------------------------------------------------------------------- + +// Help IDs for Analysis AddIn. MUST BE SORTED for binary search. +const ScUnoAddInHelpId pAnalysisHelpIds[] = +{ + { "getAccrint" , HID_AAI_FUNC_ACCRINT }, + { "getAccrintm" , HID_AAI_FUNC_ACCRINTM }, + { "getAmordegrc" , HID_AAI_FUNC_AMORDEGRC }, + { "getAmorlinc" , HID_AAI_FUNC_AMORLINC }, + { "getBesseli" , HID_AAI_FUNC_BESSELI }, + { "getBesselj" , HID_AAI_FUNC_BESSELJ }, + { "getBesselk" , HID_AAI_FUNC_BESSELK }, + { "getBessely" , HID_AAI_FUNC_BESSELY }, + { "getBin2Dec" , HID_AAI_FUNC_BIN2DEC }, + { "getBin2Hex" , HID_AAI_FUNC_BIN2HEX }, + { "getBin2Oct" , HID_AAI_FUNC_BIN2OCT }, + { "getComplex" , HID_AAI_FUNC_COMPLEX }, + { "getConvert" , HID_AAI_FUNC_CONVERT }, + { "getCoupdaybs" , HID_AAI_FUNC_COUPDAYBS }, + { "getCoupdays" , HID_AAI_FUNC_COUPDAYS }, + { "getCoupdaysnc" , HID_AAI_FUNC_COUPDAYSNC }, + { "getCoupncd" , HID_AAI_FUNC_COUPNCD }, + { "getCoupnum" , HID_AAI_FUNC_COUPNUM }, + { "getCouppcd" , HID_AAI_FUNC_COUPPCD }, + { "getCumipmt" , HID_AAI_FUNC_CUMIPMT }, + { "getCumprinc" , HID_AAI_FUNC_CUMPRINC }, + { "getDec2Bin" , HID_AAI_FUNC_DEC2BIN }, + { "getDec2Hex" , HID_AAI_FUNC_DEC2HEX }, + { "getDec2Oct" , HID_AAI_FUNC_DEC2OCT }, + { "getDelta" , HID_AAI_FUNC_DELTA }, + { "getDisc" , HID_AAI_FUNC_DISC }, + { "getDollarde" , HID_AAI_FUNC_DOLLARDE }, + { "getDollarfr" , HID_AAI_FUNC_DOLLARFR }, + { "getDuration" , HID_AAI_FUNC_DURATION }, + { "getEdate" , HID_AAI_FUNC_EDATE }, + { "getEffect" , HID_AAI_FUNC_EFFECT }, + { "getEomonth" , HID_AAI_FUNC_EOMONTH }, + { "getErf" , HID_AAI_FUNC_ERF }, + { "getErfc" , HID_AAI_FUNC_ERFC }, + { "getFactdouble" , HID_AAI_FUNC_FACTDOUBLE }, + { "getFvschedule" , HID_AAI_FUNC_FVSCHEDULE }, + { "getGcd" , HID_AAI_FUNC_GCD }, + { "getGestep" , HID_AAI_FUNC_GESTEP }, + { "getHex2Bin" , HID_AAI_FUNC_HEX2BIN }, + { "getHex2Dec" , HID_AAI_FUNC_HEX2DEC }, + { "getHex2Oct" , HID_AAI_FUNC_HEX2OCT }, + { "getImabs" , HID_AAI_FUNC_IMABS }, + { "getImaginary" , HID_AAI_FUNC_IMAGINARY }, + { "getImargument" , HID_AAI_FUNC_IMARGUMENT }, + { "getImconjugate" , HID_AAI_FUNC_IMCONJUGATE }, + { "getImcos" , HID_AAI_FUNC_IMCOS }, + { "getImdiv" , HID_AAI_FUNC_IMDIV }, + { "getImexp" , HID_AAI_FUNC_IMEXP }, + { "getImln" , HID_AAI_FUNC_IMLN }, + { "getImlog10" , HID_AAI_FUNC_IMLOG10 }, + { "getImlog2" , HID_AAI_FUNC_IMLOG2 }, + { "getImpower" , HID_AAI_FUNC_IMPOWER }, + { "getImproduct" , HID_AAI_FUNC_IMPRODUCT }, + { "getImreal" , HID_AAI_FUNC_IMREAL }, + { "getImsin" , HID_AAI_FUNC_IMSIN }, + { "getImsqrt" , HID_AAI_FUNC_IMSQRT }, + { "getImsub" , HID_AAI_FUNC_IMSUB }, + { "getImsum" , HID_AAI_FUNC_IMSUM }, + { "getIntrate" , HID_AAI_FUNC_INTRATE }, + { "getIseven" , HID_AAI_FUNC_ISEVEN }, + { "getIsodd" , HID_AAI_FUNC_ISODD }, + { "getLcm" , HID_AAI_FUNC_LCM }, + { "getMduration" , HID_AAI_FUNC_MDURATION }, + { "getMround" , HID_AAI_FUNC_MROUND }, + { "getMultinomial" , HID_AAI_FUNC_MULTINOMIAL }, + { "getNetworkdays" , HID_AAI_FUNC_NETWORKDAYS }, + { "getNominal" , HID_AAI_FUNC_NOMINAL }, + { "getOct2Bin" , HID_AAI_FUNC_OCT2BIN }, + { "getOct2Dec" , HID_AAI_FUNC_OCT2DEZ }, + { "getOct2Hex" , HID_AAI_FUNC_OCT2HEX }, + { "getOddfprice" , HID_AAI_FUNC_ODDFPRICE }, + { "getOddfyield" , HID_AAI_FUNC_ODDFYIELD }, + { "getOddlprice" , HID_AAI_FUNC_ODDLPRICE }, + { "getOddlyield" , HID_AAI_FUNC_ODDLYIELD }, + { "getPrice" , HID_AAI_FUNC_PRICE }, + { "getPricedisc" , HID_AAI_FUNC_PRICEDISC }, + { "getPricemat" , HID_AAI_FUNC_PRICEMAT }, + { "getQuotient" , HID_AAI_FUNC_QUOTIENT }, + { "getRandbetween" , HID_AAI_FUNC_RANDBETWEEN }, + { "getReceived" , HID_AAI_FUNC_RECEIVED }, + { "getSeriessum" , HID_AAI_FUNC_SERIESSUM }, + { "getSqrtpi" , HID_AAI_FUNC_SQRTPI }, + { "getTbilleq" , HID_AAI_FUNC_TBILLEQ }, + { "getTbillprice" , HID_AAI_FUNC_TBILLPRICE }, + { "getTbillyield" , HID_AAI_FUNC_TBILLYIELD }, + { "getWeeknum" , HID_AAI_FUNC_WEEKNUM }, + { "getWorkday" , HID_AAI_FUNC_WORKDAY }, + { "getXirr" , HID_AAI_FUNC_XIRR }, + { "getXnpv" , HID_AAI_FUNC_XNPV }, + { "getYearfrac" , HID_AAI_FUNC_YEARFRAC }, + { "getYield" , HID_AAI_FUNC_YIELD }, + { "getYielddisc" , HID_AAI_FUNC_YIELDDISC }, + { "getYieldmat" , HID_AAI_FUNC_YIELDMAT } +}; + + +// ---------------------------------------------------------------------------- + +// Help IDs for DateFunc AddIn. MUST BE SORTED for binary search. +const ScUnoAddInHelpId pDateFuncHelpIds[] = +{ + { "getDaysInMonth" , HID_DAI_FUNC_DAYSINMONTH }, + { "getDaysInYear" , HID_DAI_FUNC_DAYSINYEAR }, + { "getDiffMonths" , HID_DAI_FUNC_DIFFMONTHS }, + { "getDiffWeeks" , HID_DAI_FUNC_DIFFWEEKS }, + { "getDiffYears" , HID_DAI_FUNC_DIFFYEARS }, + { "getRot13" , HID_DAI_FUNC_ROT13 }, + { "getWeeksInYear" , HID_DAI_FUNC_WEEKSINYEAR } +}; + + +// ============================================================================ + +/*N*/ ScUnoAddInHelpIdGenerator::ScUnoAddInHelpIdGenerator( const ::rtl::OUString& rServiceName ) +/*N*/ { +/*N*/ SetServiceName( rServiceName ); +/*N*/ } + +/*N*/ void ScUnoAddInHelpIdGenerator::SetServiceName( const ::rtl::OUString& rServiceName ) +/*N*/ { +/*N*/ pCurrHelpIds = NULL; +/*N*/ sal_uInt32 nSize = 0; +/*N*/ +/*N*/ if( rServiceName.equalsAscii( "com.sun.star.sheet.addin.Analysis" ) ) +/*N*/ { +/*N*/ pCurrHelpIds = pAnalysisHelpIds; +/*N*/ nSize = sizeof( pAnalysisHelpIds ); +/*N*/ } +/*N*/ else if( rServiceName.equalsAscii( "com.sun.star.sheet.addin.DateFunctions" ) ) +/*N*/ { +/*N*/ pCurrHelpIds = pDateFuncHelpIds; +/*N*/ nSize = sizeof( pDateFuncHelpIds ); +/*N*/ } +/*N*/ +/*N*/ nArrayCount = nSize / sizeof( ScUnoAddInHelpId ); +/*N*/ } + +/*N*/ sal_uInt16 ScUnoAddInHelpIdGenerator::GetHelpId( const ::rtl::OUString& rFuncName ) const +/*N*/ { +/*N*/ if( !pCurrHelpIds || !nArrayCount ) +/*N*/ return 0; +/*N*/ +/*N*/ const ScUnoAddInHelpId* pFirst = pCurrHelpIds; +/*N*/ const ScUnoAddInHelpId* pLast = pCurrHelpIds + nArrayCount - 1; +/*N*/ +/*N*/ while( pFirst <= pLast ) +/*N*/ { +/*N*/ const ScUnoAddInHelpId* pMiddle = pFirst + (pLast - pFirst) / 2; +/*N*/ sal_Int32 nResult = rFuncName.compareToAscii( pMiddle->pFuncName ); +/*N*/ if( !nResult ) +/*N*/ return pMiddle->nHelpId; +/*N*/ else if( nResult < 0 ) +/*N*/ pLast = pMiddle - 1; +/*N*/ else +/*N*/ pFirst = pMiddle + 1; +/*N*/ } +/*N*/ +/*N*/ return 0; +/*N*/ } + + +// ============================================================================ + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_addinlis.cxx b/binfilter/bf_sc/source/core/tool/sc_addinlis.cxx new file mode 100644 index 000000000000..03f85bec1bda --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_addinlis.cxx @@ -0,0 +1,192 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <bf_sfx2/objsh.hxx> +#include <vcl/svapp.hxx> + + +#include "addinlis.hxx" +#include "miscuno.hxx" // SC_IMPL_SERVICE_INFO +#include "document.hxx" +#include "bf_sc.hrc" +namespace binfilter { + +using namespace ::com::sun::star; + +//------------------------------------------------------------------------ + +//SMART_UNO_IMPLEMENTATION( ScAddInListener, UsrObject ); + +/*N*/ SC_SIMPLE_SERVICE_INFO( ScAddInListener, "ScAddInListener", "stardiv.one.sheet.AddInListener" ) + +//------------------------------------------------------------------------ + +/*N*/ List ScAddInListener::aAllListeners; + +//------------------------------------------------------------------------ + +/*N*/ // static +/*N*/ ScAddInListener* ScAddInListener::CreateListener( +/*N*/ uno::Reference<sheet::XVolatileResult> xVR, ScDocument* pDoc ) +/*N*/ { +/*N*/ ScAddInListener* pNew = new ScAddInListener( xVR, pDoc ); +/*N*/ +/*N*/ pNew->acquire(); // for aAllListeners +/*N*/ aAllListeners.Insert( pNew, LIST_APPEND ); +/*N*/ +/*N*/ if ( xVR.is() ) +/*N*/ xVR->addResultListener( pNew ); // after at least 1 ref exists! +/*N*/ +/*N*/ return pNew; +/*N*/ } + +/*N*/ ScAddInListener::ScAddInListener( uno::Reference<sheet::XVolatileResult> xVR, ScDocument* pDoc ) : +/*N*/ xVolRes( xVR ) +/*N*/ { +/*N*/ pDocs = new ScAddInDocs( 1, 1 ); +/*N*/ pDocs->Insert( pDoc ); +/*N*/ } + +/*N*/ ScAddInListener::~ScAddInListener() +/*N*/ { +/*N*/ delete pDocs; +/*N*/ } + +/*N*/ // static +/*N*/ ScAddInListener* ScAddInListener::Get( uno::Reference<sheet::XVolatileResult> xVR ) +/*N*/ { +/*N*/ sheet::XVolatileResult* pComp = xVR.get(); +/*N*/ +/*N*/ ULONG nCount = aAllListeners.Count(); +/*N*/ for (ULONG nPos=0; nPos<nCount; nPos++) +/*N*/ { +/*N*/ ScAddInListener* pLst = (ScAddInListener*)aAllListeners.GetObject(nPos); +/*N*/ if ( pComp == (sheet::XVolatileResult*)pLst->xVolRes.get() ) +/*N*/ return pLst; +/*N*/ } +/*N*/ return NULL; // not found +/*N*/ } + +//! move to some container object? +// static +/*N*/ void ScAddInListener::RemoveDocument( ScDocument* pDocumentP ) +/*N*/ { +/*N*/ ULONG nPos = aAllListeners.Count(); +/*N*/ while (nPos) +/*N*/ { +/*?*/ // loop backwards because elements are removed +/*?*/ --nPos; +/*?*/ ScAddInListener* pLst = (ScAddInListener*)aAllListeners.GetObject(nPos); +/*?*/ ScAddInDocs* p = pLst->pDocs; +/*?*/ USHORT nFoundPos; +/*?*/ if ( p->Seek_Entry( pDocumentP, &nFoundPos ) ) +/*?*/ { +/*?*/ p->Remove( nFoundPos ); +/*?*/ if ( p->Count() == 0 ) +/*?*/ { +/*?*/ // this AddIn is no longer used +/*?*/ // dont delete, just remove the ref for the list +/*?*/ +/*?*/ aAllListeners.Remove( nPos ); +/*?*/ +/*?*/ if ( pLst->xVolRes.is() ) +/*?*/ pLst->xVolRes->removeResultListener( pLst ); +/*?*/ +/*?*/ pLst->release(); // Ref for aAllListeners - pLst may be deleted here +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ } + +//------------------------------------------------------------------------ + +// XResultListener + +/*N*/ void SAL_CALL ScAddInListener::modified( const ::com::sun::star::sheet::ResultEvent& aEvent ) +/*N*/ throw(::com::sun::star::uno::RuntimeException) +/*N*/ { +/*N*/ SolarMutexGuard aGuard; //! or generate a UserEvent +/*N*/ +/*N*/ aResult = aEvent.Value; // store result +/*N*/ +/*N*/ if ( !HasListeners() ) +/*N*/ { +/*N*/ //! remove from list and removeListener, as in RemoveDocument ??? +/*N*/ +/*N*/ #if 0 +/*N*/ //! this will crash if called before first StartListening !!! +/*N*/ aAllListeners.Remove( this ); +/*N*/ if ( xVolRes.is() ) +/*N*/ xVolRes->removeResultListener( this ); +/*N*/ release(); // Ref for aAllListeners - this may be deleted here +/*N*/ return; +/*N*/ #endif +/*N*/ } +/*N*/ +/*N*/ // notify document of changes +/*N*/ +/*N*/ Broadcast( ScHint( SC_HINT_DATACHANGED, ScAddress( 0 ), NULL ) ); +/*N*/ +/*N*/ const ScDocument** ppDoc = (const ScDocument**) pDocs->GetData(); +/*N*/ USHORT nCount = pDocs->Count(); +/*N*/ for ( USHORT j=0; j<nCount; j++, ppDoc++ ) +/*N*/ { +/*N*/ ScDocument* pDoc = (ScDocument*)*ppDoc; +/*N*/ pDoc->TrackFormulas(); +/*N*/ pDoc->GetDocumentShell()->Broadcast( SfxSimpleHint( FID_DATACHANGED ) ); +/*N*/ pDoc->ResetChanged( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB) ); +/*N*/ } +/*N*/ } + +// XEventListener + +/*N*/ void SAL_CALL ScAddInListener::disposing( const ::com::sun::star::lang::EventObject& Source ) +/*N*/ throw(::com::sun::star::uno::RuntimeException) +/*N*/ { +/*N*/ // hold a ref so this is not deleted at removeResultListener +/*N*/ uno::Reference<sheet::XResultListener> xRef( this ); +/*N*/ +/*N*/ if ( xVolRes.is() ) +/*N*/ { +/*N*/ xVolRes->removeResultListener( this ); +/*N*/ xVolRes = NULL; +/*N*/ } +/*N*/ } + + +//------------------------------------------------------------------------ + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_adiasync.cxx b/binfilter/bf_sc/source/core/tool/sc_adiasync.cxx new file mode 100644 index 000000000000..d333d1e02993 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_adiasync.cxx @@ -0,0 +1,148 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +//------------------------------------------------------------------------ + +#include <bf_sfx2/objsh.hxx> + +#include "adiasync.hxx" +#include "document.hxx" +#include "bf_sc.hrc" // FID_DATACHANGED + +#include <osl/thread.h> +namespace binfilter { + + +//------------------------------------------------------------------------ + +#ifdef _MSC_VER +#pragma code_seg("SCSTATICS") +#endif + +ScAddInAsyncs theAddInAsyncTbl; +static ScAddInAsync aSeekObj; + +#ifdef _MSC_VER +#pragma code_seg() +#endif + + +/*N*/ SV_IMPL_OP_PTRARR_SORT( ScAddInAsyncs, ScAddInAsyncPtr ); + +/*N*/ SV_IMPL_PTRARR_SORT( ScAddInDocs, ScAddInDocPtr ); + + + + +/*N*/ ScAddInAsync::ScAddInAsync() : +/*N*/ SfxBroadcaster(), +/*N*/ nHandle( 0 ) +/*N*/ { // nur fuer aSeekObj ! +/*N*/ } + + + +/*N*/ ScAddInAsync::ScAddInAsync( ULONG nHandleP, USHORT nIndex, ScDocument* pDoc ) : +/*N*/ SfxBroadcaster(), +/*N*/ pStr( NULL ), +/*N*/ nHandle( nHandleP ), +/*N*/ bValid( FALSE ) +/*N*/ { +/*N*/ pDocs = new ScAddInDocs( 1, 1 ); +/*N*/ pDocs->Insert( pDoc ); +/*N*/ pFuncData = (FuncData*)ScGlobal::GetFuncCollection()->At(nIndex); +/*N*/ eType = pFuncData->GetAsyncType(); +/*N*/ theAddInAsyncTbl.Insert( this ); +/*N*/ } + + + +/*N*/ ScAddInAsync::~ScAddInAsync() +/*N*/ { +/*N*/ // aSeekObj hat das alles nicht, Handle 0 gibt es sonst nicht +/*N*/ if ( nHandle ) +/*N*/ { +/*?*/ // im dTor wg. theAddInAsyncTbl.DeleteAndDestroy in ScGlobal::Clear +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pFuncData->Unadvice( (double)nHandle ); +/*N*/ } +/*N*/ } + + + +/*N*/ ScAddInAsync* ScAddInAsync::Get( ULONG nHandleP ) +/*N*/ { +/*N*/ USHORT nPos; +/*N*/ ScAddInAsync* pRet = 0; +/*N*/ aSeekObj.nHandle = nHandleP; +/*N*/ if ( theAddInAsyncTbl.Seek_Entry( &aSeekObj, &nPos ) ) +/*N*/ pRet = theAddInAsyncTbl[ nPos ]; +/*N*/ aSeekObj.nHandle = 0; +/*N*/ return pRet; +/*N*/ } + + + + + + +/*N*/ void ScAddInAsync::RemoveDocument( ScDocument* pDocumentP ) +/*N*/ { +/*N*/ USHORT nPos = theAddInAsyncTbl.Count(); +/*N*/ if ( nPos ) +/*N*/ { +/*?*/ const ScAddInAsync** ppAsync = +/*?*/ (const ScAddInAsync**) theAddInAsyncTbl.GetData() + nPos - 1; +/*?*/ for ( ; nPos-- >0; ppAsync-- ) +/*?*/ { // rueckwaerts wg. Pointer-Aufrueckerei im Array +/*?*/ ScAddInDocs* p = ((ScAddInAsync*)*ppAsync)->pDocs; +/*?*/ USHORT nFoundPos; +/*?*/ if ( p->Seek_Entry( pDocumentP, &nFoundPos ) ) +/*?*/ { +/*?*/ p->Remove( nFoundPos ); +/*?*/ if ( p->Count() == 0 ) +/*?*/ { // dieses AddIn wird nicht mehr benutzt +/*?*/ ScAddInAsync* pAsync = (ScAddInAsync*)*ppAsync; +/*?*/ theAddInAsyncTbl.Remove( nPos ); +/*?*/ delete pAsync; +/*?*/ ppAsync = (const ScAddInAsync**) theAddInAsyncTbl.GetData() +/*?*/ + nPos; +/*?*/ } +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_appoptio.cxx b/binfilter/bf_sc/source/core/tool/sc_appoptio.cxx new file mode 100644 index 000000000000..df9b03a270dc --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_appoptio.cxx @@ -0,0 +1,678 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +//------------------------------------------------------------------ + + + +#include "appoptio.hxx" +#include "rechead.hxx" +#include "userlist.hxx" +#include "bf_sc.hrc" +#include "compiler.hrc" +#include "miscuno.hxx" +namespace binfilter { + +using namespace utl; +using namespace rtl; +using namespace ::com::sun::star::uno; + +// STATIC DATA ----------------------------------------------------------- + +#define SC_VERSION ((USHORT)304) + +//======================================================================== +// ScAppOptions - Applikations-Optionen +//======================================================================== + +/*N*/ ScAppOptions::ScAppOptions() : pLRUList( NULL ) +/*N*/ { +/*N*/ SetDefaults(); +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ ScAppOptions::ScAppOptions( const ScAppOptions& rCpy ) : pLRUList( NULL ) +/*N*/ { +/*N*/ *this = rCpy; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ ScAppOptions::~ScAppOptions() +/*N*/ { +/*N*/ delete [] pLRUList; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ void ScAppOptions::SetDefaults() +/*N*/ { +/*N*/ if ( ScOptionsUtil::IsMetricSystem() ) +/*N*/ eMetric = FUNIT_CM; // default for countries with metric system +/*N*/ else +/*N*/ eMetric = FUNIT_INCH; // default for others +/*N*/ +/*N*/ nZoom = 100; +/*N*/ eZoomType = SVX_ZOOM_PERCENT; +/*N*/ nStatusFunc = SUBTOTAL_FUNC_SUM; +/*N*/ bAutoComplete = TRUE; +/*N*/ bDetectiveAuto = TRUE; +/*N*/ +/*N*/ delete [] pLRUList; +/*N*/ pLRUList = new USHORT[5]; // sinnvoll vorbelegen +/*N*/ pLRUList[0] = SC_OPCODE_SUM; +/*N*/ pLRUList[1] = SC_OPCODE_AVERAGE; +/*N*/ pLRUList[2] = SC_OPCODE_MIN; +/*N*/ pLRUList[3] = SC_OPCODE_MAX; +/*N*/ pLRUList[4] = SC_OPCODE_IF; +/*N*/ nLRUFuncCount = 5; +/*N*/ +/*N*/ nTrackContentColor = COL_TRANSPARENT; +/*N*/ nTrackInsertColor = COL_TRANSPARENT; +/*N*/ nTrackDeleteColor = COL_TRANSPARENT; +/*N*/ nTrackMoveColor = COL_TRANSPARENT; +/*N*/ eLinkMode = LM_ON_DEMAND; +/*N*/ +/*N*/ nDefaultObjectSizeWidth = 8000; +/*N*/ nDefaultObjectSizeHeight = 5000; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ const ScAppOptions& ScAppOptions::operator=( const ScAppOptions& rCpy ) +/*N*/ { +/*N*/ eMetric = rCpy.eMetric; +/*N*/ eZoomType = rCpy.eZoomType; +/*N*/ nZoom = rCpy.nZoom; +/*N*/ SetLRUFuncList( rCpy.pLRUList, rCpy.nLRUFuncCount ); +/*N*/ nStatusFunc = rCpy.nStatusFunc; +/*N*/ bAutoComplete = rCpy.bAutoComplete; +/*N*/ bDetectiveAuto = rCpy.bDetectiveAuto; +/*N*/ nTrackContentColor = rCpy.nTrackContentColor; +/*N*/ nTrackInsertColor = rCpy.nTrackInsertColor; +/*N*/ nTrackDeleteColor = rCpy.nTrackDeleteColor; +/*N*/ nTrackMoveColor = rCpy.nTrackMoveColor; +/*N*/ eLinkMode = rCpy.eLinkMode; +/*N*/ nDefaultObjectSizeWidth = rCpy.nDefaultObjectSizeWidth; +/*N*/ nDefaultObjectSizeHeight = rCpy.nDefaultObjectSizeHeight; +/*N*/ return *this; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ SvStream& operator>>( SvStream& rStream, ScAppOptions& rOpt ) +/*N*/ { +/*N*/ rOpt.SetDefaults(); +/*N*/ +/*N*/ ScReadHeader aHdr( rStream ); +/*N*/ +/*N*/ BYTE n; +/*N*/ rStream >> n; rOpt.eMetric = (FieldUnit)n; +/*N*/ +/*N*/ if ( aHdr.BytesLeft() ) +/*N*/ { +/*N*/ rStream >> n; rOpt.nLRUFuncCount = (USHORT)n; +/*N*/ +/*N*/ delete [] rOpt.pLRUList; +/*N*/ rOpt.pLRUList = new USHORT[rOpt.nLRUFuncCount]; +/*N*/ +/*N*/ for ( USHORT i=0; i<rOpt.nLRUFuncCount; i++ ) +/*N*/ rStream >> rOpt.pLRUList[i]; +/*N*/ } +/*N*/ +/*N*/ // ab 31.10.95: globale benutzerdefinierte Listen einlesen :-/ +/*N*/ // (kleiner Hack :-/) +/*N*/ if ( aHdr.BytesLeft() ) +/*N*/ { +/*N*/ ScUserList* pUserList = ScGlobal::GetUserList(); +/*N*/ pUserList->Load( rStream ); +/*N*/ } +/*N*/ +/*N*/ // ab 11.12.95 (304) +/*N*/ // Zoom-Faktor +/*N*/ if ( aHdr.BytesLeft() ) +/*N*/ { +/*N*/ USHORT e; +/*N*/ rStream >> e; rOpt.eZoomType = (SvxZoomType)e; +/*N*/ rStream >> rOpt.nZoom; +/*N*/ } +/*N*/ +/*N*/ // ab 23.5.96: Funktion fuer Statusbar-Controller, Flag fuer Auto-Eingabe +/*N*/ if ( aHdr.BytesLeft() ) +/*N*/ { +/*N*/ rStream >> rOpt.nStatusFunc; +/*N*/ rStream >> rOpt.bAutoComplete; +/*N*/ } +/*N*/ +/*N*/ // ab 15.3.98: Farben fuer Change-Tracking +/*N*/ if ( aHdr.BytesLeft() ) +/*N*/ { +/*N*/ rStream >> rOpt.nTrackContentColor; +/*N*/ rStream >> rOpt.nTrackInsertColor; +/*N*/ rStream >> rOpt.nTrackDeleteColor; +/*N*/ rStream >> rOpt.nTrackMoveColor; +/*N*/ } +/*N*/ +/*N*/ // ab 22.6.98: Automatisches Detektiv-Update +/*N*/ if ( aHdr.BytesLeft() ) +/*N*/ rStream >> rOpt.bDetectiveAuto; +/*N*/ +/*N*/ if ( aHdr.BytesLeft() ) +/*N*/ { +/*N*/ BYTE nLinkMode; +/*N*/ rStream >> nLinkMode; +/*N*/ rOpt.eLinkMode=(ScLkUpdMode) nLinkMode; +/*N*/ } +/*N*/ +/*N*/ return rStream; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ SvStream& operator<<( SvStream& rStream, const ScAppOptions& rOpt ) +/*N*/ { +/*N*/ ScWriteHeader aHdr( rStream, 25 ); +/*N*/ +/*N*/ rStream << (BYTE)rOpt.eMetric; +/*N*/ rStream << (BYTE)rOpt.nLRUFuncCount; +/*N*/ +/*N*/ if ( rOpt.nLRUFuncCount > 0 ) +/*N*/ { +/*N*/ for ( USHORT i=0; i<rOpt.nLRUFuncCount; i++ ) +/*N*/ rStream << rOpt.pLRUList[i]; +/*N*/ } +/*N*/ +/*N*/ // ab 31.10.95: globale benutzerdefinierte Listen speichern +/*N*/ // (kleiner Hack :-/) +/*N*/ ScUserList* pUserList = ScGlobal::GetUserList(); +/*N*/ pUserList->Store( rStream ); +/*N*/ +/*N*/ // ab 11.12.95 (304) +/*N*/ // Zoom-Faktor +/*N*/ rStream << (USHORT)rOpt.eZoomType; +/*N*/ rStream << rOpt.nZoom; +/*N*/ +/*N*/ // ab 23.5.96: Funktion fuer Statusbar-Controller, Flag fuer Auto-Eingabe +/*N*/ rStream << rOpt.nStatusFunc; +/*N*/ rStream << rOpt.bAutoComplete; +/*N*/ +/*N*/ // ab 15.3.98: Farben fuer Change-Tracking +/*N*/ rStream << rOpt.nTrackContentColor; +/*N*/ rStream << rOpt.nTrackInsertColor; +/*N*/ rStream << rOpt.nTrackDeleteColor; +/*N*/ rStream << rOpt.nTrackMoveColor; +/*N*/ +/*N*/ // ab 22.6.98: Automatisches Detektiv-Update +/*N*/ rStream << rOpt.bDetectiveAuto; +/*N*/ rStream << (BYTE) rOpt.eLinkMode; +/*N*/ +/*N*/ return rStream; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ void ScAppOptions::SetLRUFuncList( const USHORT* pList, const USHORT nCount ) +/*N*/ { +/*N*/ delete [] pLRUList; +/*N*/ +/*N*/ nLRUFuncCount = nCount; +/*N*/ +/*N*/ if ( nLRUFuncCount > 0 ) +/*N*/ { +/*N*/ pLRUList = new USHORT[nLRUFuncCount]; +/*N*/ +/*N*/ for ( USHORT i=0; i<nLRUFuncCount; i++ ) +/*N*/ pLRUList[i] = pList[i]; +/*N*/ } +/*N*/ else +/*N*/ pLRUList = NULL; +/*N*/ } + +//================================================================== +// Config Item containing app options +//================================================================== + +/*N*/ void lcl_SetLastFunctions( ScAppOptions& rOpt, const Any& rValue ) +/*N*/ { +/*N*/ Sequence<sal_Int32> aSeq; +/*N*/ if ( rValue >>= aSeq ) +/*N*/ { +/*N*/ long nCount = aSeq.getLength(); +/*N*/ if ( nCount < USHRT_MAX ) +/*N*/ { +/*N*/ const sal_Int32* pArray = aSeq.getConstArray(); +/*N*/ USHORT* pUShorts = new USHORT[nCount]; +/*N*/ for (long i=0; i<nCount; i++) +/*N*/ pUShorts[i] = (USHORT) pArray[i]; +/*N*/ +/*N*/ rOpt.SetLRUFuncList( pUShorts, nCount ); +/*N*/ +/*N*/ delete[] pUShorts; +/*N*/ } +/*N*/ } +/*N*/ } + + +/*N*/ void lcl_SetSortList( const Any& rValue ) +/*N*/ { +/*N*/ Sequence<OUString> aSeq; +/*N*/ if ( rValue >>= aSeq ) +/*N*/ { +/*N*/ long nCount = aSeq.getLength(); +/*N*/ const OUString* pArray = aSeq.getConstArray(); +/*N*/ ScUserList aList; +/*N*/ +/*N*/ // if setting is "default", keep default values from ScUserList ctor +/*N*/ //! mark "default" in a safe way +/*N*/ BOOL bDefault = ( nCount == 1 && +/*N*/ pArray[0].equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "NULL" ) ) ); +/*N*/ +/*N*/ if (!bDefault) +/*N*/ { +/*?*/ aList.FreeAll(); +/*?*/ +/*?*/ for (long i=0; i<nCount; i++) +/*?*/ { +/*?*/ ScUserListData* pNew = new ScUserListData( pArray[i] ); +/*?*/ if ( !aList.Insert(pNew) ) +/*?*/ delete pNew; +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ ScGlobal::SetUserList( &aList ); +/*N*/ } +/*N*/ } + + +//------------------------------------------------------------------ + +#define CFGPATH_LAYOUT "Office.Calc/Layout" + +#define SCLAYOUTOPT_MEASURE 0 +#define SCLAYOUTOPT_STATUSBAR 1 +#define SCLAYOUTOPT_ZOOMVAL 2 +#define SCLAYOUTOPT_ZOOMTYPE 3 +#define SCLAYOUTOPT_COUNT 4 + +#define CFGPATH_INPUT "Office.Calc/Input" + +#define SCINPUTOPT_LASTFUNCS 0 +#define SCINPUTOPT_AUTOINPUT 1 +#define SCINPUTOPT_DET_AUTO 2 +#define SCINPUTOPT_COUNT 3 + +#define CFGPATH_REVISION "Office.Calc/Revision/Color" + +#define SCREVISOPT_CHANGE 0 +#define SCREVISOPT_INSERTION 1 +#define SCREVISOPT_DELETION 2 +#define SCREVISOPT_MOVEDENTRY 3 +#define SCREVISOPT_COUNT 4 + +#define CFGPATH_CONTENT "Office.Calc/Content/Update" + +#define SCCONTENTOPT_LINK 0 +#define SCCONTENTOPT_COUNT 1 + +#define CFGPATH_SORTLIST "Office.Calc/SortList" + +#define SCSORTLISTOPT_LIST 0 +#define SCSORTLISTOPT_COUNT 1 + +#define CFGPATH_MISC "Office.Calc/Misc" + +#define SCMISCOPT_DEFOBJWIDTH 0 +#define SCMISCOPT_DEFOBJHEIGHT 1 +#define SCMISCOPT_COUNT 2 + + +/*N*/ Sequence<OUString> ScAppCfg::GetLayoutPropertyNames() +/*N*/ { +/*N*/ static const char* aPropNames[] = +/*N*/ { +/*N*/ "Other/MeasureUnit/NonMetric", // SCLAYOUTOPT_MEASURE +/*N*/ "Other/StatusbarFunction", // SCLAYOUTOPT_STATUSBAR +/*N*/ "Zoom/Value", // SCLAYOUTOPT_ZOOMVAL +/*N*/ "Zoom/Type" // SCLAYOUTOPT_ZOOMTYPE +/*N*/ }; +/*N*/ Sequence<OUString> aNames(SCLAYOUTOPT_COUNT); +/*N*/ OUString* pNames = aNames.getArray(); +/*N*/ for(int i = 0; i < SCLAYOUTOPT_COUNT; i++) +/*N*/ pNames[i] = OUString::createFromAscii(aPropNames[i]); +/*N*/ +/*N*/ // adjust for metric system +/*N*/ if (ScOptionsUtil::IsMetricSystem()) +/*N*/ pNames[SCLAYOUTOPT_MEASURE] = OUString::createFromAscii( "Other/MeasureUnit/Metric" ); +/*N*/ +/*N*/ return aNames; +/*N*/ } + +/*N*/ Sequence<OUString> ScAppCfg::GetInputPropertyNames() +/*N*/ { +/*N*/ static const char* aPropNames[] = +/*N*/ { +/*N*/ "LastFunctions", // SCINPUTOPT_LASTFUNCS +/*N*/ "AutoInput", // SCINPUTOPT_AUTOINPUT +/*N*/ "DetectiveAuto" // SCINPUTOPT_DET_AUTO +/*N*/ }; +/*N*/ Sequence<OUString> aNames(SCINPUTOPT_COUNT); +/*N*/ OUString* pNames = aNames.getArray(); +/*N*/ for(int i = 0; i < SCINPUTOPT_COUNT; i++) +/*N*/ pNames[i] = OUString::createFromAscii(aPropNames[i]); +/*N*/ +/*N*/ return aNames; +/*N*/ } + +/*N*/ Sequence<OUString> ScAppCfg::GetRevisionPropertyNames() +/*N*/ { +/*N*/ static const char* aPropNames[] = +/*N*/ { +/*N*/ "Change", // SCREVISOPT_CHANGE +/*N*/ "Insertion", // SCREVISOPT_INSERTION +/*N*/ "Deletion", // SCREVISOPT_DELETION +/*N*/ "MovedEntry" // SCREVISOPT_MOVEDENTRY +/*N*/ }; +/*N*/ Sequence<OUString> aNames(SCREVISOPT_COUNT); +/*N*/ OUString* pNames = aNames.getArray(); +/*N*/ for(int i = 0; i < SCREVISOPT_COUNT; i++) +/*N*/ pNames[i] = OUString::createFromAscii(aPropNames[i]); +/*N*/ +/*N*/ return aNames; +/*N*/ } + +/*N*/ Sequence<OUString> ScAppCfg::GetContentPropertyNames() +/*N*/ { +/*N*/ static const char* aPropNames[] = +/*N*/ { +/*N*/ "Link" // SCCONTENTOPT_LINK +/*N*/ }; +/*N*/ Sequence<OUString> aNames(SCCONTENTOPT_COUNT); +/*N*/ OUString* pNames = aNames.getArray(); +/*N*/ for(int i = 0; i < SCCONTENTOPT_COUNT; i++) +/*N*/ pNames[i] = OUString::createFromAscii(aPropNames[i]); +/*N*/ +/*N*/ return aNames; +/*N*/ } + +/*N*/ Sequence<OUString> ScAppCfg::GetSortListPropertyNames() +/*N*/ { +/*N*/ static const char* aPropNames[] = +/*N*/ { +/*N*/ "List" // SCSORTLISTOPT_LIST +/*N*/ }; +/*N*/ Sequence<OUString> aNames(SCSORTLISTOPT_COUNT); +/*N*/ OUString* pNames = aNames.getArray(); +/*N*/ for(int i = 0; i < SCSORTLISTOPT_COUNT; i++) +/*N*/ pNames[i] = OUString::createFromAscii(aPropNames[i]); +/*N*/ +/*N*/ return aNames; +/*N*/ } + +/*N*/ Sequence<OUString> ScAppCfg::GetMiscPropertyNames() +/*N*/ { +/*N*/ static const char* aPropNames[] = +/*N*/ { +/*N*/ "DefaultObjectSize/Width", // SCMISCOPT_DEFOBJWIDTH +/*N*/ "DefaultObjectSize/Height" // SCMISCOPT_DEFOBJHEIGHT +/*N*/ }; +/*N*/ Sequence<OUString> aNames(SCMISCOPT_COUNT); +/*N*/ OUString* pNames = aNames.getArray(); +/*N*/ for(int i = 0; i < SCMISCOPT_COUNT; i++) +/*N*/ pNames[i] = OUString::createFromAscii(aPropNames[i]); +/*N*/ +/*N*/ return aNames; +/*N*/ } + + +/*N*/ ScAppCfg::ScAppCfg() : +/*N*/ aLayoutItem( OUString::createFromAscii( CFGPATH_LAYOUT ) ), +/*N*/ aInputItem( OUString::createFromAscii( CFGPATH_INPUT ) ), +/*N*/ aRevisionItem( OUString::createFromAscii( CFGPATH_REVISION ) ), +/*N*/ aContentItem( OUString::createFromAscii( CFGPATH_CONTENT ) ), +/*N*/ aSortListItem( OUString::createFromAscii( CFGPATH_SORTLIST ) ), +/*N*/ aMiscItem( OUString::createFromAscii( CFGPATH_MISC ) ) +/*N*/ { +/*N*/ sal_Int32 nIntVal; +/*N*/ +/*N*/ Sequence<OUString> aNames; +/*N*/ Sequence<Any> aValues; +/*N*/ const Any* pValues = NULL; +/*N*/ +/*N*/ aNames = GetLayoutPropertyNames(); +/*N*/ aValues = aLayoutItem.GetProperties(aNames); +/*N*/ aLayoutItem.EnableNotification(aNames); +/*N*/ pValues = aValues.getConstArray(); +/*N*/ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed"); +/*N*/ if(aValues.getLength() == aNames.getLength()) +/*N*/ { +/*N*/ for(int nProp = 0; nProp < aNames.getLength(); nProp++) +/*N*/ { +/*N*/ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing"); +/*N*/ if(pValues[nProp].hasValue()) +/*N*/ { +/*N*/ switch(nProp) +/*N*/ { +/*N*/ case SCLAYOUTOPT_MEASURE: +/*N*/ if (pValues[nProp] >>= nIntVal) SetAppMetric( (FieldUnit) nIntVal ); +/*N*/ break; +/*N*/ case SCLAYOUTOPT_STATUSBAR: +/*N*/ if (pValues[nProp] >>= nIntVal) SetStatusFunc( (USHORT) nIntVal ); +/*N*/ break; +/*N*/ case SCLAYOUTOPT_ZOOMVAL: +/*N*/ if (pValues[nProp] >>= nIntVal) SetZoom( (USHORT) nIntVal ); +/*N*/ break; +/*N*/ case SCLAYOUTOPT_ZOOMTYPE: +/*N*/ if (pValues[nProp] >>= nIntVal) SetZoomType( (SvxZoomType) nIntVal ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ aLayoutItem.SetCommitLink( LINK( this, ScAppCfg, LayoutCommitHdl ) ); +/*N*/ +/*N*/ aNames = GetInputPropertyNames(); +/*N*/ aValues = aInputItem.GetProperties(aNames); +/*N*/ aInputItem.EnableNotification(aNames); +/*N*/ pValues = aValues.getConstArray(); +/*N*/ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed"); +/*N*/ if(aValues.getLength() == aNames.getLength()) +/*N*/ { +/*N*/ for(int nProp = 0; nProp < aNames.getLength(); nProp++) +/*N*/ { +/*N*/ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing"); +/*N*/ if(pValues[nProp].hasValue()) +/*N*/ { +/*N*/ switch(nProp) +/*N*/ { +/*N*/ case SCINPUTOPT_LASTFUNCS: +/*N*/ lcl_SetLastFunctions( *this, pValues[nProp] ); +/*N*/ break; +/*N*/ case SCINPUTOPT_AUTOINPUT: +/*N*/ SetAutoComplete( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCINPUTOPT_DET_AUTO: +/*N*/ SetDetectiveAuto( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ aInputItem.SetCommitLink( LINK( this, ScAppCfg, InputCommitHdl ) ); +/*N*/ +/*N*/ aNames = GetRevisionPropertyNames(); +/*N*/ aValues = aRevisionItem.GetProperties(aNames); +/*N*/ aRevisionItem.EnableNotification(aNames); +/*N*/ pValues = aValues.getConstArray(); +/*N*/ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed"); +/*N*/ if(aValues.getLength() == aNames.getLength()) +/*N*/ { +/*N*/ for(int nProp = 0; nProp < aNames.getLength(); nProp++) +/*N*/ { +/*N*/ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing"); +/*N*/ if(pValues[nProp].hasValue()) +/*N*/ { +/*N*/ switch(nProp) +/*N*/ { +/*N*/ case SCREVISOPT_CHANGE: +/*N*/ if (pValues[nProp] >>= nIntVal) SetTrackContentColor( (ULONG) nIntVal ); +/*N*/ break; +/*N*/ case SCREVISOPT_INSERTION: +/*N*/ if (pValues[nProp] >>= nIntVal) SetTrackInsertColor( (ULONG) nIntVal ); +/*N*/ break; +/*N*/ case SCREVISOPT_DELETION: +/*N*/ if (pValues[nProp] >>= nIntVal) SetTrackDeleteColor( (ULONG) nIntVal ); +/*N*/ break; +/*N*/ case SCREVISOPT_MOVEDENTRY: +/*N*/ if (pValues[nProp] >>= nIntVal) SetTrackMoveColor( (ULONG) nIntVal ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ aRevisionItem.SetCommitLink( LINK( this, ScAppCfg, RevisionCommitHdl ) ); +/*N*/ +/*N*/ aNames = GetContentPropertyNames(); +/*N*/ aValues = aContentItem.GetProperties(aNames); +/*N*/ aContentItem.EnableNotification(aNames); +/*N*/ pValues = aValues.getConstArray(); +/*N*/ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed"); +/*N*/ if(aValues.getLength() == aNames.getLength()) +/*N*/ { +/*N*/ for(int nProp = 0; nProp < aNames.getLength(); nProp++) +/*N*/ { +/*N*/ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing"); +/*N*/ if(pValues[nProp].hasValue()) +/*N*/ { +/*N*/ switch(nProp) +/*N*/ { +/*N*/ case SCCONTENTOPT_LINK: +/*N*/ if (pValues[nProp] >>= nIntVal) SetLinkMode( (ScLkUpdMode) nIntVal ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ aContentItem.SetCommitLink( LINK( this, ScAppCfg, ContentCommitHdl ) ); +/*N*/ +/*N*/ aNames = GetSortListPropertyNames(); +/*N*/ aValues = aSortListItem.GetProperties(aNames); +/*N*/ aSortListItem.EnableNotification(aNames); +/*N*/ pValues = aValues.getConstArray(); +/*N*/ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed"); +/*N*/ if(aValues.getLength() == aNames.getLength()) +/*N*/ { +/*N*/ for(int nProp = 0; nProp < aNames.getLength(); nProp++) +/*N*/ { +/*N*/ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing"); +/*N*/ if(pValues[nProp].hasValue()) +/*N*/ { +/*N*/ switch(nProp) +/*N*/ { +/*N*/ case SCSORTLISTOPT_LIST: +/*N*/ lcl_SetSortList( pValues[nProp] ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ aSortListItem.SetCommitLink( LINK( this, ScAppCfg, SortListCommitHdl ) ); +/*N*/ +/*N*/ aNames = GetMiscPropertyNames(); +/*N*/ aValues = aMiscItem.GetProperties(aNames); +/*N*/ aMiscItem.EnableNotification(aNames); +/*N*/ pValues = aValues.getConstArray(); +/*N*/ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed"); +/*N*/ if(aValues.getLength() == aNames.getLength()) +/*N*/ { +/*N*/ for(int nProp = 0; nProp < aNames.getLength(); nProp++) +/*N*/ { +/*N*/ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing"); +/*N*/ if(pValues[nProp].hasValue()) +/*N*/ { +/*N*/ switch(nProp) +/*N*/ { +/*N*/ case SCMISCOPT_DEFOBJWIDTH: +/*N*/ if (pValues[nProp] >>= nIntVal) SetDefaultObjectSizeWidth( nIntVal ); +/*N*/ break; +/*N*/ case SCMISCOPT_DEFOBJHEIGHT: +/*N*/ if (pValues[nProp] >>= nIntVal) SetDefaultObjectSizeHeight( nIntVal ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ aMiscItem.SetCommitLink( LINK( this, ScAppCfg, MiscCommitHdl ) ); +/*N*/ } + +/*N*/ IMPL_LINK( ScAppCfg, LayoutCommitHdl, void *, EMPTYARG ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 Sequence<OUString> aNames = GetLayoutPropertyNames(); +/*N*/ return 0; +/*N*/ } + +/*N*/ IMPL_LINK( ScAppCfg, InputCommitHdl, void *, EMPTYARG ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 Sequence<OUString> aNames = GetInputPropertyNames(); +/*N*/ return 0; +/*N*/ } + +/*N*/ IMPL_LINK( ScAppCfg, RevisionCommitHdl, void *, EMPTYARG ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 Sequence<OUString> aNames = GetRevisionPropertyNames(); +/*N*/ return 0; +/*N*/ } + +/*N*/ IMPL_LINK( ScAppCfg, ContentCommitHdl, void *, EMPTYARG ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 Sequence<OUString> aNames = GetContentPropertyNames(); +/*N*/ return 0; +/*N*/ } + +/*N*/ IMPL_LINK( ScAppCfg, SortListCommitHdl, void *, EMPTYARG ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 Sequence<OUString> aNames = GetSortListPropertyNames(); +/*N*/ return 0; +/*N*/ } + +/*N*/ IMPL_LINK( ScAppCfg, MiscCommitHdl, void *, EMPTYARG ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 Sequence<OUString> aNames = GetMiscPropertyNames(); +/*N*/ return 0; +/*N*/ } + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_autoform.cxx b/binfilter/bf_sc/source/core/tool/sc_autoform.cxx new file mode 100644 index 000000000000..f467f84d810c --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_autoform.cxx @@ -0,0 +1,906 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#define READ_OLDVERS + +#include "autoform.hxx" + +#include <bf_sfx2/docfile.hxx> +#include <bf_svtools/pathoptions.hxx> +#include <vcl/outdev.hxx> +#include <bf_svx/dialmgr.hxx> +#include <bf_svx/dialogs.hrc> +#include <tools/urlobj.hxx> + +#include <tools/tenccvt.hxx> + +#include "globstr.hrc" +namespace binfilter { + +//------------------------------------------------------------------------ + +sal_Char *linker_dummy = ""; + +// Standard-Name ist jetzt STR_STYLENAME_STANDARD (wie Vorlagen) +//static const sal_Char __FAR_DATA cStandardName[] = "Standard"; + +static const sal_Char __FAR_DATA sAutoTblFmtName[] = "autotbl.fmt"; + +// bis SO5PF +const USHORT AUTOFORMAT_ID_X = 9501; +const USHORT AUTOFORMAT_ID_358 = 9601; +const USHORT AUTOFORMAT_DATA_ID_X = 9502; + +// ab SO5 +//! in nachfolgenden Versionen muss der Betrag dieser IDs groesser sein +const USHORT AUTOFORMAT_ID_504 = 9801; +const USHORT AUTOFORMAT_DATA_ID_504 = 9802; + +const USHORT AUTOFORMAT_ID_552 = 9901; +const USHORT AUTOFORMAT_DATA_ID_552 = 9902; + +// --- from 641 on: CJK and CTL font settings +const USHORT AUTOFORMAT_ID_641 = 10001; +const USHORT AUTOFORMAT_DATA_ID_641 = 10002; + +// aktuelle Version +const USHORT AUTOFORMAT_ID = AUTOFORMAT_ID_641; +const USHORT AUTOFORMAT_DATA_ID = AUTOFORMAT_DATA_ID_641; + + +#ifdef READ_OLDVERS +const USHORT AUTOFORMAT_OLD_ID_OLD = 4201; +const USHORT AUTOFORMAT_OLD_DATA_ID = 4202; +const USHORT AUTOFORMAT_OLD_ID_NEW = 4203; +#endif + + +// Struct mit Versionsnummern der Items + +/*N*/ struct ScAfVersions +/*N*/ { +/*N*/ public: +/*N*/ USHORT nFontVersion; +/*N*/ USHORT nFontHeightVersion; +/*N*/ USHORT nWeightVersion; +/*N*/ USHORT nPostureVersion; +/*N*/ USHORT nUnderlineVersion; +/*N*/ USHORT nCrossedOutVersion; +/*N*/ USHORT nContourVersion; +/*N*/ USHORT nShadowedVersion; +/*N*/ USHORT nColorVersion; +/*N*/ USHORT nBoxVersion; +/*N*/ USHORT nBrushVersion; +/*N*/ +/*N*/ USHORT nAdjustVersion; +/*N*/ +/*N*/ USHORT nHorJustifyVersion; +/*N*/ USHORT nVerJustifyVersion; +/*N*/ USHORT nOrientationVersion; +/*N*/ USHORT nMarginVersion; +/*N*/ USHORT nBoolVersion; +/*N*/ USHORT nInt32Version; +/*N*/ USHORT nRotateModeVersion; +/*N*/ +/*N*/ USHORT nNumFmtVersion; +/*N*/ +/*N*/ ScAfVersions(); +/*N*/ void Load( SvStream& rStream, USHORT nVer ); +/*N*/ static void Write(SvStream& rStream); +/*N*/ }; + +/*N*/ ScAfVersions::ScAfVersions() : +/*N*/ nFontVersion(0), +/*N*/ nFontHeightVersion(0), +/*N*/ nWeightVersion(0), +/*N*/ nPostureVersion(0), +/*N*/ nUnderlineVersion(0), +/*N*/ nCrossedOutVersion(0), +/*N*/ nContourVersion(0), +/*N*/ nShadowedVersion(0), +/*N*/ nColorVersion(0), +/*N*/ nBoxVersion(0), +/*N*/ nBrushVersion(0), +/*N*/ nAdjustVersion(0), +/*N*/ nHorJustifyVersion(0), +/*N*/ nVerJustifyVersion(0), +/*N*/ nOrientationVersion(0), +/*N*/ nMarginVersion(0), +/*N*/ nBoolVersion(0), +/*N*/ nInt32Version(0), +/*N*/ nRotateModeVersion(0), +/*N*/ nNumFmtVersion(0) +/*N*/ { +/*N*/ } + +/*N*/ void ScAfVersions::Load( SvStream& rStream, USHORT nVer ) +/*N*/ { +/*N*/ rStream >> nFontVersion; +/*N*/ rStream >> nFontHeightVersion; +/*N*/ rStream >> nWeightVersion; +/*N*/ rStream >> nPostureVersion; +/*N*/ rStream >> nUnderlineVersion; +/*N*/ rStream >> nCrossedOutVersion; +/*N*/ rStream >> nContourVersion; +/*N*/ rStream >> nShadowedVersion; +/*N*/ rStream >> nColorVersion; +/*N*/ rStream >> nBoxVersion; +/*N*/ rStream >> nBrushVersion; +/*N*/ rStream >> nAdjustVersion; +/*N*/ rStream >> nHorJustifyVersion; +/*N*/ rStream >> nVerJustifyVersion; +/*N*/ rStream >> nOrientationVersion; +/*N*/ rStream >> nMarginVersion; +/*N*/ rStream >> nBoolVersion; +/*N*/ if ( nVer >= AUTOFORMAT_ID_504 ) +/*N*/ { +/*N*/ rStream >> nInt32Version; +/*N*/ rStream >> nRotateModeVersion; +/*N*/ } +/*N*/ rStream >> nNumFmtVersion; +/*N*/ } + +/*N*/ void ScAfVersions::Write(SvStream& rStream) +/*N*/ { +/*N*/ rStream << SvxFontItem().GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ rStream << SvxFontHeightItem().GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ rStream << SvxWeightItem().GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ rStream << SvxPostureItem().GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ rStream << SvxUnderlineItem().GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ rStream << SvxCrossedOutItem().GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ rStream << SvxContourItem().GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ rStream << SvxShadowedItem().GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ rStream << SvxColorItem().GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ rStream << SvxBoxItem().GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ rStream << SvxBrushItem().GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ +/*N*/ rStream << SvxAdjustItem().GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ +/*N*/ rStream << SvxHorJustifyItem().GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ rStream << SvxVerJustifyItem().GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ rStream << SvxOrientationItem().GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ rStream << SvxMarginItem().GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ rStream << SfxBoolItem(ATTR_LINEBREAK).GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ rStream << SfxInt32Item(ATTR_ROTATE_VALUE).GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ rStream << SvxRotateModeItem(SVX_ROTATE_MODE_STANDARD,0).GetVersion(SOFFICE_FILEFORMAT_40); +/*N*/ +/*N*/ rStream << (USHORT)0; // Num-Format +/*N*/ } + +// --------------------------------------------------------------------------- + +/*N*/ ScAutoFormatDataField::ScAutoFormatDataField() : +/*N*/ aCJKFont( ATTR_CJK_FONT ), +/*N*/ aCJKHeight( 240, 100, ATTR_CJK_FONT_HEIGHT ), +/*N*/ aCJKWeight( WEIGHT_NORMAL, ATTR_CJK_FONT_WEIGHT ), +/*N*/ aCJKPosture( ITALIC_NONE, ATTR_CJK_FONT_POSTURE ), +/*N*/ aCTLFont( ATTR_CTL_FONT ), +/*N*/ aCTLHeight( 240, 100, ATTR_CTL_FONT_HEIGHT ), +/*N*/ aCTLWeight( WEIGHT_NORMAL, ATTR_CTL_FONT_WEIGHT ), +/*N*/ aCTLPosture( ITALIC_NONE, ATTR_CTL_FONT_POSTURE ), +/*N*/ aLinebreak( ATTR_LINEBREAK ), +/*N*/ aRotateAngle( ATTR_ROTATE_VALUE ), +/*N*/ aRotateMode( SVX_ROTATE_MODE_STANDARD, ATTR_ROTATE_MODE ) +/*N*/ { +/*N*/ } + +/*N*/ ScAutoFormatDataField::ScAutoFormatDataField( const ScAutoFormatDataField& rCopy ) : +/*N*/ aFont( rCopy.aFont ), +/*N*/ aHeight( rCopy.aHeight ), +/*N*/ aWeight( rCopy.aWeight ), +/*N*/ aPosture( rCopy.aPosture ), +/*N*/ aCJKFont( rCopy.aCJKFont ), +/*N*/ aCJKHeight( rCopy.aCJKHeight ), +/*N*/ aCJKWeight( rCopy.aCJKWeight ), +/*N*/ aCJKPosture( rCopy.aCJKPosture ), +/*N*/ aCTLFont( rCopy.aCTLFont ), +/*N*/ aCTLHeight( rCopy.aCTLHeight ), +/*N*/ aCTLWeight( rCopy.aCTLWeight ), +/*N*/ aCTLPosture( rCopy.aCTLPosture ), +/*N*/ aUnderline( rCopy.aUnderline ), +/*N*/ aCrossedOut( rCopy.aCrossedOut ), +/*N*/ aContour( rCopy.aContour ), +/*N*/ aShadowed( rCopy.aShadowed ), +/*N*/ aColor( rCopy.aColor ), +/*N*/ aBox( rCopy.aBox ), +/*N*/ aBackground( rCopy.aBackground ), +/*N*/ aAdjust( rCopy.aAdjust ), +/*N*/ aHorJustify( rCopy.aHorJustify ), +/*N*/ aVerJustify( rCopy.aVerJustify ), +/*N*/ aOrientation( rCopy.aOrientation ), +/*N*/ aMargin( rCopy.aMargin ), +/*N*/ aLinebreak( rCopy.aLinebreak ), +/*N*/ aRotateAngle( rCopy.aRotateAngle ), +/*N*/ aRotateMode( rCopy.aRotateMode ), +/*N*/ aNumFormat( rCopy.aNumFormat ) +/*N*/ { +/*N*/ } + +/*N*/ ScAutoFormatDataField::~ScAutoFormatDataField() +/*N*/ { +/*N*/ } + +/*N*/ void ScAutoFormatDataField::SetAdjust( const SvxAdjustItem& rAdjust ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 aAdjust.SetAdjust( rAdjust.GetAdjust() ); +/*N*/ } + +/*N*/ #define READ( aItem, ItemType, nVers ) \ +/*N*/ pNew = aItem.Create( rStream, nVers ); \ +/*N*/ aItem = *(ItemType*)pNew; \ +/*N*/ delete pNew; + +/*N*/ BOOL ScAutoFormatDataField::Load( SvStream& rStream, const ScAfVersions& rVersions, USHORT nVer ) +/*N*/ { +/*N*/ SfxPoolItem* pNew; +/*N*/ +/*N*/ READ( aFont, SvxFontItem, rVersions.nFontVersion) +/*N*/ READ( aHeight, SvxFontHeightItem, rVersions.nFontHeightVersion) +/*N*/ READ( aWeight, SvxWeightItem, rVersions.nWeightVersion) +/*N*/ READ( aPosture, SvxPostureItem, rVersions.nPostureVersion) +/*N*/ // --- from 641 on: CJK and CTL font settings +/*N*/ if( AUTOFORMAT_DATA_ID_641 <= nVer ) +/*N*/ { +/*N*/ READ( aCJKFont, SvxFontItem, rVersions.nFontVersion) +/*N*/ READ( aCJKHeight, SvxFontHeightItem, rVersions.nFontHeightVersion) +/*N*/ READ( aCJKWeight, SvxWeightItem, rVersions.nWeightVersion) +/*N*/ READ( aCJKPosture, SvxPostureItem, rVersions.nPostureVersion) +/*N*/ READ( aCTLFont, SvxFontItem, rVersions.nFontVersion) +/*N*/ READ( aCTLHeight, SvxFontHeightItem, rVersions.nFontHeightVersion) +/*N*/ READ( aCTLWeight, SvxWeightItem, rVersions.nWeightVersion) +/*N*/ READ( aCTLPosture, SvxPostureItem, rVersions.nPostureVersion) +/*N*/ } +/*N*/ READ( aUnderline, SvxUnderlineItem, rVersions.nUnderlineVersion) +/*N*/ READ( aCrossedOut, SvxCrossedOutItem, rVersions.nCrossedOutVersion) +/*N*/ READ( aContour, SvxContourItem, rVersions.nContourVersion) +/*N*/ READ( aShadowed, SvxShadowedItem, rVersions.nShadowedVersion) +/*N*/ READ( aColor, SvxColorItem, rVersions.nColorVersion) +/*N*/ READ( aBox, SvxBoxItem, rVersions.nBoxVersion) +/*N*/ READ( aBackground, SvxBrushItem, rVersions.nBrushVersion) +/*N*/ +/*N*/ pNew = aAdjust.Create( rStream, rVersions.nAdjustVersion ); +/*N*/ SetAdjust( *(SvxAdjustItem*)pNew ); +/*N*/ delete pNew; +/*N*/ +/*N*/ READ( aHorJustify, SvxHorJustifyItem, rVersions.nHorJustifyVersion) +/*N*/ READ( aVerJustify, SvxVerJustifyItem, rVersions.nVerJustifyVersion) +/*N*/ READ( aOrientation, SvxOrientationItem, rVersions.nOrientationVersion) +/*N*/ READ( aMargin, SvxMarginItem, rVersions.nMarginVersion) +/*N*/ +/*N*/ pNew = aLinebreak.Create( rStream, rVersions.nBoolVersion ); +/*N*/ SetLinebreak( *(SfxBoolItem*)pNew ); +/*N*/ delete pNew; +/*N*/ +/*N*/ if ( nVer >= AUTOFORMAT_DATA_ID_504 ) +/*N*/ { +/*N*/ pNew = aRotateAngle.Create( rStream, rVersions.nInt32Version ); +/*N*/ SetRotateAngle( *(SfxInt32Item*)pNew ); +/*N*/ delete pNew; +/*N*/ pNew = aRotateMode.Create( rStream, rVersions.nRotateModeVersion ); +/*N*/ SetRotateMode( *(SvxRotateModeItem*)pNew ); +/*N*/ delete pNew; +/*N*/ } +/*N*/ +/*N*/ if( 0 == rVersions.nNumFmtVersion ) +/*N*/ aNumFormat.Load( rStream ); +/*N*/ +/*N*/ // adjust charset in font +/*N*/ CharSet eSysSet = gsl_getSystemTextEncoding(); +/*N*/ CharSet eSrcSet = rStream.GetStreamCharSet(); +/*N*/ if( eSrcSet != eSysSet && aFont.GetCharSet() == eSrcSet ) +/*N*/ aFont.GetCharSet() = eSysSet; +/*N*/ +/*N*/ return (rStream.GetError() == 0); +/*N*/ } + +/*N*/ #ifdef READ_OLDVERS +/*N*/ BOOL ScAutoFormatDataField::LoadOld( SvStream& rStream, const ScAfVersions& rVersions ) +/*N*/ { +/*N*/ SfxPoolItem* pNew; +/*N*/ +/*N*/ aNumFormat.Load(rStream); +/*N*/ +/*N*/ READ( aFont, SvxFontItem, rVersions.nFontVersion) +/*N*/ READ( aHeight, SvxFontHeightItem, rVersions.nFontHeightVersion) +/*N*/ READ( aWeight, SvxWeightItem, rVersions.nWeightVersion) +/*N*/ READ( aPosture, SvxPostureItem, rVersions.nPostureVersion) +/*N*/ READ( aUnderline, SvxUnderlineItem, rVersions.nUnderlineVersion) +/*N*/ READ( aCrossedOut, SvxCrossedOutItem, rVersions.nCrossedOutVersion) +/*N*/ READ( aContour, SvxContourItem, rVersions.nContourVersion) +/*N*/ READ( aShadowed, SvxShadowedItem, rVersions.nShadowedVersion) +/*N*/ READ( aColor, SvxColorItem, rVersions.nColorVersion) +/*N*/ READ( aHorJustify, SvxHorJustifyItem, rVersions.nHorJustifyVersion) +/*N*/ READ( aVerJustify, SvxVerJustifyItem, rVersions.nVerJustifyVersion) +/*N*/ READ( aOrientation, SvxOrientationItem, rVersions.nOrientationVersion) +/*N*/ pNew = aLinebreak.Create( rStream, rVersions.nBoolVersion ); +/*N*/ SetLinebreak( *(SfxBoolItem*)pNew ); +/*N*/ delete pNew; +/*N*/ READ( aMargin, SvxMarginItem, rVersions.nMarginVersion) +/*N*/ READ( aBox, SvxBoxItem, rVersions.nBoxVersion) +/*N*/ READ( aBackground, SvxBrushItem, rVersions.nBrushVersion) +/*N*/ +/*N*/ return (rStream.GetError() == 0); +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ BOOL ScAutoFormatDataField::Save( SvStream& rStream ) +/*N*/ { +/*N*/ aFont.Store ( rStream, aFont.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aHeight.Store ( rStream, aHeight.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aWeight.Store ( rStream, aWeight.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aPosture.Store ( rStream, aPosture.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ // --- from 641 on: CJK and CTL font settings +/*N*/ aCJKFont.Store ( rStream, aCJKFont.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aCJKHeight.Store ( rStream, aCJKHeight.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aCJKWeight.Store ( rStream, aCJKWeight.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aCJKPosture.Store ( rStream, aCJKPosture.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aCTLFont.Store ( rStream, aCTLFont.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aCTLHeight.Store ( rStream, aCTLHeight.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aCTLWeight.Store ( rStream, aCTLWeight.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aCTLPosture.Store ( rStream, aCTLPosture.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ +/*N*/ aUnderline.Store ( rStream, aUnderline.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aCrossedOut.Store ( rStream, aCrossedOut.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aContour.Store ( rStream, aContour.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aShadowed.Store ( rStream, aShadowed.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aColor.Store ( rStream, aColor.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aBox.Store ( rStream, aBox.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aBackground.Store ( rStream, aBackground.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ +/*N*/ aAdjust.Store ( rStream, aAdjust.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ +/*N*/ aHorJustify.Store ( rStream, aHorJustify.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aVerJustify.Store ( rStream, aVerJustify.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aOrientation.Store ( rStream, aOrientation.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aMargin.Store ( rStream, aMargin.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aLinebreak.Store ( rStream, aLinebreak.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ // Rotation ab SO5 +/*N*/ aRotateAngle.Store ( rStream, aRotateAngle.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ aRotateMode.Store ( rStream, aRotateMode.GetVersion( SOFFICE_FILEFORMAT_40 ) ); +/*N*/ +/*N*/ aNumFormat.Save( rStream ); +/*N*/ +/*N*/ return (rStream.GetError() == 0); +/*N*/ } + + +// --------------------------------------------------------------------------- + +/*N*/ ScAutoFormatData::ScAutoFormatData() +/*N*/ { +/*N*/ nStrResId = USHRT_MAX; +/*N*/ +/*N*/ bIncludeValueFormat = +/*N*/ bIncludeFont = +/*N*/ bIncludeJustify = +/*N*/ bIncludeFrame = +/*N*/ bIncludeBackground = +/*N*/ bIncludeWidthHeight = TRUE; +/*N*/ +/*N*/ ppDataField = new ScAutoFormatDataField*[ 16 ]; +/*N*/ for( USHORT nIndex = 0; nIndex < 16; ++nIndex ) +/*N*/ ppDataField[ nIndex ] = new ScAutoFormatDataField; +/*N*/ } + +/*N*/ ScAutoFormatData::ScAutoFormatData( const ScAutoFormatData& rData ) : +/*N*/ aName( rData.aName ), +/*N*/ nStrResId( rData.nStrResId ), +/*N*/ bIncludeValueFormat( rData.bIncludeValueFormat ), +/*N*/ bIncludeFont( rData.bIncludeFont ), +/*N*/ bIncludeJustify( rData.bIncludeJustify ), +/*N*/ bIncludeFrame( rData.bIncludeFrame ), +/*N*/ bIncludeBackground( rData.bIncludeBackground ), +/*N*/ bIncludeWidthHeight( rData.bIncludeWidthHeight ) +/*N*/ { +/*N*/ ppDataField = new ScAutoFormatDataField*[ 16 ]; +/*N*/ for( USHORT nIndex = 0; nIndex < 16; ++nIndex ) +/*N*/ ppDataField[ nIndex ] = new ScAutoFormatDataField( rData.GetField( nIndex ) ); +/*N*/ } + +/*N*/ ScAutoFormatData::~ScAutoFormatData() +/*N*/ { +/*N*/ for( USHORT nIndex = 0; nIndex < 16; ++nIndex ) +/*N*/ delete ppDataField[ nIndex ]; +/*N*/ delete[] ppDataField; +/*N*/ } + +/*N*/ ScAutoFormatDataField& ScAutoFormatData::GetField( USHORT nIndex ) +/*N*/ { +/*N*/ DBG_ASSERT( (0 <= nIndex) && (nIndex < 16), "ScAutoFormatData::GetField - illegal index" ); +/*N*/ DBG_ASSERT( ppDataField && ppDataField[ nIndex ], "ScAutoFormatData::GetField - no data" ); +/*N*/ return *ppDataField[ nIndex ]; +/*N*/ } + +/*N*/ const ScAutoFormatDataField& ScAutoFormatData::GetField( USHORT nIndex ) const +/*N*/ { +/*N*/ DBG_ASSERT( (0 <= nIndex) && (nIndex < 16), "ScAutoFormatData::GetField - illegal index" ); +/*N*/ DBG_ASSERT( ppDataField && ppDataField[ nIndex ], "ScAutoFormatData::GetField - no data" ); +/*N*/ return *ppDataField[ nIndex ]; +/*N*/ } + +/*N*/ const SfxPoolItem* ScAutoFormatData::GetItem( USHORT nIndex, USHORT nWhich ) const +/*N*/ { +/*N*/ const ScAutoFormatDataField& rField = GetField( nIndex ); +/*N*/ switch( nWhich ) +/*N*/ { +/*N*/ case ATTR_FONT: return &rField.GetFont(); +/*N*/ case ATTR_FONT_HEIGHT: return &rField.GetHeight(); +/*N*/ case ATTR_FONT_WEIGHT: return &rField.GetWeight(); +/*N*/ case ATTR_FONT_POSTURE: return &rField.GetPosture(); +/*N*/ case ATTR_CJK_FONT: return &rField.GetCJKFont(); +/*N*/ case ATTR_CJK_FONT_HEIGHT: return &rField.GetCJKHeight(); +/*N*/ case ATTR_CJK_FONT_WEIGHT: return &rField.GetCJKWeight(); +/*N*/ case ATTR_CJK_FONT_POSTURE: return &rField.GetCJKPosture(); +/*N*/ case ATTR_CTL_FONT: return &rField.GetCTLFont(); +/*N*/ case ATTR_CTL_FONT_HEIGHT: return &rField.GetCTLHeight(); +/*N*/ case ATTR_CTL_FONT_WEIGHT: return &rField.GetCTLWeight(); +/*N*/ case ATTR_CTL_FONT_POSTURE: return &rField.GetCTLPosture(); +/*N*/ case ATTR_FONT_UNDERLINE: return &rField.GetUnderline(); +/*N*/ case ATTR_FONT_CROSSEDOUT: return &rField.GetCrossedOut(); +/*N*/ case ATTR_FONT_CONTOUR: return &rField.GetContour(); +/*N*/ case ATTR_FONT_SHADOWED: return &rField.GetShadowed(); +/*N*/ case ATTR_FONT_COLOR: return &rField.GetColor(); +/*N*/ case ATTR_BORDER: return &rField.GetBox(); +/*N*/ case ATTR_BACKGROUND: return &rField.GetBackground(); +/*N*/ case ATTR_HOR_JUSTIFY: return &rField.GetHorJustify(); +/*N*/ case ATTR_VER_JUSTIFY: return &rField.GetVerJustify(); +/*N*/ case ATTR_ORIENTATION: return &rField.GetOrientation(); +/*N*/ case ATTR_MARGIN: return &rField.GetMargin(); +/*N*/ case ATTR_LINEBREAK: return &rField.GetLinebreak(); +/*N*/ case ATTR_ROTATE_VALUE: return &rField.GetRotateAngle(); +/*N*/ case ATTR_ROTATE_MODE: return &rField.GetRotateMode(); +/*N*/ } +/*N*/ return NULL; +/*N*/ } + +/*N*/ void ScAutoFormatData::PutItem( USHORT nIndex, const SfxPoolItem& rItem ) +/*N*/ { +/*N*/ ScAutoFormatDataField& rField = GetField( nIndex ); +/*N*/ switch( rItem.Which() ) +/*N*/ { +/*N*/ case ATTR_FONT: rField.SetFont( (const SvxFontItem&)rItem ); break; +/*N*/ case ATTR_FONT_HEIGHT: rField.SetHeight( (const SvxFontHeightItem&)rItem ); break; +/*N*/ case ATTR_FONT_WEIGHT: rField.SetWeight( (const SvxWeightItem&)rItem ); break; +/*N*/ case ATTR_FONT_POSTURE: rField.SetPosture( (const SvxPostureItem&)rItem ); break; +/*N*/ case ATTR_CJK_FONT: rField.SetCJKFont( (const SvxFontItem&)rItem ); break; +/*N*/ case ATTR_CJK_FONT_HEIGHT: rField.SetCJKHeight( (const SvxFontHeightItem&)rItem ); break; +/*N*/ case ATTR_CJK_FONT_WEIGHT: rField.SetCJKWeight( (const SvxWeightItem&)rItem ); break; +/*N*/ case ATTR_CJK_FONT_POSTURE: rField.SetCJKPosture( (const SvxPostureItem&)rItem ); break; +/*N*/ case ATTR_CTL_FONT: rField.SetCTLFont( (const SvxFontItem&)rItem ); break; +/*N*/ case ATTR_CTL_FONT_HEIGHT: rField.SetCTLHeight( (const SvxFontHeightItem&)rItem ); break; +/*N*/ case ATTR_CTL_FONT_WEIGHT: rField.SetCTLWeight( (const SvxWeightItem&)rItem ); break; +/*N*/ case ATTR_CTL_FONT_POSTURE: rField.SetCTLPosture( (const SvxPostureItem&)rItem ); break; +/*N*/ case ATTR_FONT_UNDERLINE: rField.SetUnderline( (const SvxUnderlineItem&)rItem ); break; +/*N*/ case ATTR_FONT_CROSSEDOUT: rField.SetCrossedOut( (const SvxCrossedOutItem&)rItem ); break; +/*N*/ case ATTR_FONT_CONTOUR: rField.SetContour( (const SvxContourItem&)rItem ); break; +/*N*/ case ATTR_FONT_SHADOWED: rField.SetShadowed( (const SvxShadowedItem&)rItem ); break; +/*N*/ case ATTR_FONT_COLOR: rField.SetColor( (const SvxColorItem&)rItem ); break; +/*N*/ case ATTR_BORDER: rField.SetBox( (const SvxBoxItem&)rItem ); break; +/*N*/ case ATTR_BACKGROUND: rField.SetBackground( (const SvxBrushItem&)rItem ); break; +/*N*/ case ATTR_HOR_JUSTIFY: rField.SetHorJustify( (const SvxHorJustifyItem&)rItem ); break; +/*N*/ case ATTR_VER_JUSTIFY: rField.SetVerJustify( (const SvxVerJustifyItem&)rItem ); break; +/*N*/ case ATTR_ORIENTATION: rField.SetOrientation( (const SvxOrientationItem&)rItem );break; +/*N*/ case ATTR_MARGIN: rField.SetMargin( (const SvxMarginItem&)rItem ); break; +/*N*/ case ATTR_LINEBREAK: rField.SetLinebreak( (const SfxBoolItem&)rItem ); break; +/*N*/ case ATTR_ROTATE_VALUE: rField.SetRotateAngle( (const SfxInt32Item&)rItem ); break; +/*N*/ case ATTR_ROTATE_MODE: rField.SetRotateMode( (const SvxRotateModeItem&)rItem ); break; +/*N*/ } +/*N*/ } + + + + + + + +/*N*/ BOOL ScAutoFormatData::Load( SvStream& rStream, const ScAfVersions& rVersions ) +/*N*/ { +/*N*/ BOOL bRet = TRUE; +/*N*/ USHORT nVer = 0; +/*N*/ rStream >> nVer; +/*N*/ bRet = 0 == rStream.GetError(); +/*N*/ if( bRet && (nVer == AUTOFORMAT_DATA_ID_X || +/*N*/ (AUTOFORMAT_DATA_ID_504 <= nVer && nVer <= AUTOFORMAT_DATA_ID)) ) +/*N*/ { +/*N*/ CharSet eSysSet = gsl_getSystemTextEncoding(); +/*N*/ CharSet eSrcSet = rStream.GetStreamCharSet(); +/*N*/ +/*N*/ BOOL b; +/*N*/ rStream.ReadByteString( aName, eSrcSet ); +/*N*/ if( AUTOFORMAT_DATA_ID_552 <= nVer ) +/*N*/ { +/*N*/ rStream >> nStrResId; +/*N*/ USHORT nId = RID_SVXSTR_TBLAFMT_BEGIN + nStrResId; +/*N*/ if( RID_SVXSTR_TBLAFMT_BEGIN <= nId && +/*N*/ nId < RID_SVXSTR_TBLAFMT_END ) +/*N*/ { +/*N*/ aName = SVX_RESSTR( nId ); +/*N*/ } +/*N*/ else +/*N*/ nStrResId = USHRT_MAX; +/*N*/ } +/*N*/ +/*N*/ rStream >> b; bIncludeFont = b; +/*N*/ rStream >> b; bIncludeJustify = b; +/*N*/ rStream >> b; bIncludeFrame = b; +/*N*/ rStream >> b; bIncludeBackground = b; +/*N*/ rStream >> b; bIncludeValueFormat = b; +/*N*/ rStream >> b; bIncludeWidthHeight = b; +/*N*/ +/*N*/ bRet = 0 == rStream.GetError(); +/*N*/ for( USHORT i = 0; bRet && i < 16; ++i ) +/*N*/ bRet = GetField( i ).Load( rStream, rVersions, nVer ); +/*N*/ } +/*N*/ else +/*N*/ bRet = FALSE; +/*N*/ return bRet; +/*N*/ } + +/*N*/ #ifdef READ_OLDVERS +/*N*/ BOOL ScAutoFormatData::LoadOld( SvStream& rStream, const ScAfVersions& rVersions ) +/*N*/ { +/*N*/ BOOL bRet = TRUE; +/*N*/ USHORT nVal = 0; +/*N*/ rStream >> nVal; +/*N*/ bRet = (rStream.GetError() == 0); +/*N*/ if (bRet && (nVal == AUTOFORMAT_OLD_DATA_ID)) +/*N*/ { +/*N*/ rStream.ReadByteString( aName, rStream.GetStreamCharSet() ); +/*N*/ BOOL b; +/*N*/ rStream >> b; bIncludeFont = b; +/*N*/ rStream >> b; bIncludeJustify = b; +/*N*/ rStream >> b; bIncludeFrame = b; +/*N*/ rStream >> b; bIncludeBackground = b; +/*N*/ rStream >> b; bIncludeValueFormat = b; +/*N*/ rStream >> b; bIncludeWidthHeight = b; +/*N*/ +/*N*/ bRet = 0 == rStream.GetError(); +/*N*/ for (USHORT i=0; bRet && i < 16; i++) +/*N*/ bRet = GetField( i ).LoadOld( rStream, rVersions ); +/*N*/ } +/*N*/ else +/*N*/ bRet = FALSE; +/*N*/ return bRet; +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ BOOL ScAutoFormatData::Save(SvStream& rStream) +/*N*/ { +/*N*/ USHORT nVal = AUTOFORMAT_DATA_ID; +/*N*/ BOOL b; +/*N*/ rStream << nVal; +/*N*/ rStream.WriteByteString( aName, rStream.GetStreamCharSet() ); +/*N*/ +/*N*/ #if 0 +/*N*/ // This was an internal flag to allow creating AutoFormats with localized names +/*N*/ +/*N*/ if ( USHRT_MAX == nStrResId ) +/*N*/ { +/*N*/ String aIniVal( SFX_APP()->GetIniManager()->Get( +/*N*/ SFX_GROUP_WORKINGSET_IMPL, +/*N*/ String( RTL_CONSTASCII_USTRINGPARAM( "SaveTableAutoFmtNameId" )))); +/*N*/ if( 0 != aIniVal.ToInt32() ) +/*N*/ { +/*N*/ // check Name for ResId +/*N*/ for( USHORT nId = RID_SVXSTR_TBLAFMT_BEGIN; +/*N*/ RID_SVXSTR_TBLAFMT_END > nId; ++nId ) +/*N*/ { +/*N*/ String s( SVX_RES( nId ) ); +/*N*/ if( s == aName ) +/*N*/ { +/*N*/ nStrResId = nId - RID_SVXSTR_TBLAFMT_BEGIN; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ rStream << nStrResId; +/*N*/ rStream << ( b = bIncludeFont ); +/*N*/ rStream << ( b = bIncludeJustify ); +/*N*/ rStream << ( b = bIncludeFrame ); +/*N*/ rStream << ( b = bIncludeBackground ); +/*N*/ rStream << ( b = bIncludeValueFormat ); +/*N*/ rStream << ( b = bIncludeWidthHeight ); +/*N*/ +/*N*/ BOOL bRet = 0 == rStream.GetError(); +/*N*/ for (USHORT i = 0; bRet && (i < 16); i++) +/*N*/ bRet = GetField( i ).Save( rStream ); +/*N*/ +/*N*/ return bRet; +/*N*/ } + +//--------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------- + +/*N*/ ScAutoFormat::ScAutoFormat(USHORT nLim, USHORT nDel, BOOL bDup): +/*N*/ SortedCollection (nLim, nDel, bDup), +/*N*/ bSaveLater (FALSE) +/*N*/ { +/*N*/ // create default autoformat +/*N*/ ScAutoFormatData* pData = new ScAutoFormatData; +/*N*/ String aName(ScGlobal::GetRscString(STR_STYLENAME_STANDARD)); +/*N*/ pData->SetName(aName); +/*N*/ +/*N*/ // default font, default height +/*N*/ Font aStdFont = OutputDevice::GetDefaultFont( +/*N*/ DEFAULTFONT_LATIN_SPREADSHEET, LANGUAGE_ENGLISH_US, DEFAULTFONT_FLAGS_ONLYONE ); +/*N*/ SvxFontItem aFontItem( +/*N*/ aStdFont.GetFamily(), aStdFont.GetName(), aStdFont.GetStyleName(), +/*N*/ aStdFont.GetPitch(), aStdFont.GetCharSet() ); +/*N*/ +/*N*/ aStdFont = OutputDevice::GetDefaultFont( +/*N*/ DEFAULTFONT_CJK_SPREADSHEET, LANGUAGE_ENGLISH_US, DEFAULTFONT_FLAGS_ONLYONE ); +/*N*/ SvxFontItem aCJKFontItem( +/*N*/ aStdFont.GetFamily(), aStdFont.GetName(), aStdFont.GetStyleName(), +/*N*/ aStdFont.GetPitch(), aStdFont.GetCharSet(), ATTR_CJK_FONT ); +/*N*/ +/*N*/ aStdFont = OutputDevice::GetDefaultFont( +/*N*/ DEFAULTFONT_CTL_SPREADSHEET, LANGUAGE_ENGLISH_US, DEFAULTFONT_FLAGS_ONLYONE ); +/*N*/ SvxFontItem aCTLFontItem( +/*N*/ aStdFont.GetFamily(), aStdFont.GetName(), aStdFont.GetStyleName(), +/*N*/ aStdFont.GetPitch(), aStdFont.GetCharSet(), ATTR_CTL_FONT ); +/*N*/ +/*N*/ SvxFontHeightItem aHeight( 200 ); // 10 pt; +/*N*/ +/*N*/ // black thin border +/*N*/ Color aBlack( COL_BLACK ); +/*N*/ SvxBorderLine aLine( &aBlack, DEF_LINE_WIDTH_0 ); +/*N*/ SvxBoxItem aBox; +/*N*/ aBox.SetLine(&aLine, BOX_LINE_LEFT); +/*N*/ aBox.SetLine(&aLine, BOX_LINE_TOP); +/*N*/ aBox.SetLine(&aLine, BOX_LINE_RIGHT); +/*N*/ aBox.SetLine(&aLine, BOX_LINE_BOTTOM); +/*N*/ +/*N*/ Color aWhite(COL_WHITE); +/*N*/ Color aBlue(COL_BLUE); +/*N*/ SvxColorItem aWhiteText( aWhite ); +/*N*/ SvxColorItem aBlackText( aBlack ); +/*N*/ SvxBrushItem aBlueBack( aBlue ); +/*N*/ SvxBrushItem aWhiteBack( aWhite ); +/*N*/ SvxBrushItem aGray70Back( Color(0x4d, 0x4d, 0x4d) ); +/*N*/ SvxBrushItem aGray20Back( Color(0xcc, 0xcc, 0xcc) ); +/*N*/ +/*N*/ for (USHORT i=0; i<16; i++) +/*N*/ { +/*N*/ pData->PutItem( i, aBox ); +/*N*/ pData->PutItem( i, aFontItem ); +/*N*/ pData->PutItem( i, aCJKFontItem ); +/*N*/ pData->PutItem( i, aCTLFontItem ); +/*N*/ aHeight.SetWhich( ATTR_FONT_HEIGHT ); +/*N*/ pData->PutItem( i, aHeight ); +/*N*/ aHeight.SetWhich( ATTR_CJK_FONT_HEIGHT ); +/*N*/ pData->PutItem( i, aHeight ); +/*N*/ aHeight.SetWhich( ATTR_CTL_FONT_HEIGHT ); +/*N*/ pData->PutItem( i, aHeight ); +/*N*/ if (i<4) // top: white on blue +/*N*/ { +/*N*/ pData->PutItem( i, aWhiteText ); +/*N*/ pData->PutItem( i, aBlueBack ); +/*N*/ } +/*N*/ else if ( i%4 == 0 ) // left: white on gray70 +/*N*/ { +/*N*/ pData->PutItem( i, aWhiteText ); +/*N*/ pData->PutItem( i, aGray70Back ); +/*N*/ } +/*N*/ else if ( i%4 == 3 || i >= 12 ) // right and bottom: black on gray20 +/*N*/ { +/*N*/ pData->PutItem( i, aBlackText ); +/*N*/ pData->PutItem( i, aGray20Back ); +/*N*/ } +/*N*/ else // center: black on white +/*N*/ { +/*N*/ pData->PutItem( i, aBlackText ); +/*N*/ pData->PutItem( i, aWhiteBack ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ Insert(pData); +/*N*/ } + +/*N*/ ScAutoFormat::ScAutoFormat(const ScAutoFormat& rAutoFormat) : +/*N*/ SortedCollection (rAutoFormat), +/*N*/ bSaveLater (FALSE) +/*N*/ {} + +/*N*/ ScAutoFormat::~ScAutoFormat() +/*N*/ { +/*N*/ // Bei Aenderungen per StarOne wird nicht sofort gespeichert, sondern zuerst nur +/*N*/ // das SaveLater Flag gesetzt. Wenn das Flag noch gesetzt ist, jetzt speichern. +/*N*/ +/*N*/ if (bSaveLater) +/*N*/ Save(); +/*N*/ } + +/*N*/ void ScAutoFormat::SetSaveLater( BOOL bSet ) +/*N*/ { +/*N*/ bSaveLater = bSet; +/*N*/ } + + +/*N*/ BOOL ScAutoFormat::Load() +/*N*/ { +/*N*/ BOOL bRet = TRUE; +/*N*/ +/*N*/ INetURLObject aURL; +/*N*/ SvtPathOptions aPathOpt; +/*N*/ aURL.SetSmartURL( aPathOpt.GetUserConfigPath() ); +/*N*/ aURL.setFinalSlash(); +/*N*/ aURL.Append( String( RTL_CONSTASCII_USTRINGPARAM( sAutoTblFmtName ) ) ); +/*N*/ +/*N*/ SfxMedium aMedium( aURL.GetMainURL(INetURLObject::NO_DECODE), STREAM_READ, TRUE ); +/*N*/ SvStream* pStream = aMedium.GetInStream(); +/*N*/ bRet = (pStream && pStream->GetError() == 0); +/*N*/ if (bRet) +/*N*/ { +/*N*/ SvStream& rStream = *pStream; +/*N*/ // Achtung hier muss ein allgemeiner Header gelesen werden +/*N*/ USHORT nVal = 0; +/*N*/ rStream >> nVal; +/*N*/ bRet = 0 == rStream.GetError(); +/*N*/ +/*N*/ ScAfVersions aVersions; +/*N*/ +/*N*/ if (bRet) +/*N*/ { +/*N*/ if( nVal == AUTOFORMAT_ID_358 || +/*N*/ (AUTOFORMAT_ID_504 <= nVal && nVal <= AUTOFORMAT_ID) ) +/*N*/ { +/*N*/ UINT16 nFileVers = SOFFICE_FILEFORMAT_40; +/*N*/ BYTE nChrSet, nCnt; +/*N*/ long nPos = rStream.Tell(); +/*N*/ rStream >> nCnt >> nChrSet; +/*N*/ // if( 4 <= nCnt ) +/*N*/ // rStream >> nFileVers; +/*N*/ if( rStream.Tell() != ULONG(nPos + nCnt) ) +/*N*/ { +/*N*/ DBG_ERRORFILE( "Der Header enthaelt mehr/neuere Daten" ); +/*N*/ rStream.Seek( nPos + nCnt ); +/*N*/ } +/*N*/ rStream.SetStreamCharSet( GetSOLoadTextEncoding( nChrSet, nFileVers ) ); +/*N*/ rStream.SetVersion( nFileVers ); +/*N*/ } +/*N*/ +/*N*/ if( nVal == AUTOFORMAT_ID_358 || nVal == AUTOFORMAT_ID_X || +/*N*/ (AUTOFORMAT_ID_504 <= nVal && nVal <= AUTOFORMAT_ID) ) +/*N*/ { +/*N*/ aVersions.Load( rStream, nVal ); // Item-Versionen +/*N*/ +/*N*/ ScAutoFormatData* pData; +/*N*/ USHORT nAnz = 0; +/*N*/ rStream >> nAnz; +/*N*/ bRet = (rStream.GetError() == 0); +/*N*/ for (USHORT i=0; bRet && (i < nAnz); i++) +/*N*/ { +/*N*/ pData = new ScAutoFormatData(); +/*N*/ bRet = pData->Load(rStream, aVersions); +/*N*/ Insert(pData); +/*N*/ } +/*N*/ } +/*N*/ #ifdef READ_OLDVERS +/*N*/ else +/*N*/ { +/*N*/ if( AUTOFORMAT_OLD_ID_NEW == nVal ) +/*N*/ { +/*N*/ // alte Version der Versions laden +/*N*/ rStream >> aVersions.nFontVersion; +/*N*/ rStream >> aVersions.nFontHeightVersion; +/*N*/ rStream >> aVersions.nWeightVersion; +/*N*/ rStream >> aVersions.nPostureVersion; +/*N*/ rStream >> aVersions.nUnderlineVersion; +/*N*/ rStream >> aVersions.nCrossedOutVersion; +/*N*/ rStream >> aVersions.nContourVersion; +/*N*/ rStream >> aVersions.nShadowedVersion; +/*N*/ rStream >> aVersions.nColorVersion; +/*N*/ rStream >> aVersions.nHorJustifyVersion; +/*N*/ rStream >> aVersions.nVerJustifyVersion; +/*N*/ rStream >> aVersions.nOrientationVersion; +/*N*/ rStream >> aVersions.nBoolVersion; +/*N*/ rStream >> aVersions.nMarginVersion; +/*N*/ rStream >> aVersions.nBoxVersion; +/*N*/ rStream >> aVersions.nBrushVersion; +/*N*/ } +/*N*/ if( AUTOFORMAT_OLD_ID_OLD == nVal || +/*N*/ AUTOFORMAT_OLD_ID_NEW == nVal ) +/*N*/ { +/*N*/ ScAutoFormatData* pData; +/*N*/ USHORT nAnz = 0; +/*N*/ rStream >> nAnz; +/*N*/ bRet = 0 == rStream.GetError(); +/*N*/ for( USHORT i=0; bRet && (i < nAnz); ++i ) +/*N*/ { +/*N*/ pData = new ScAutoFormatData(); +/*N*/ bRet = pData->LoadOld( rStream, aVersions ); +/*N*/ Insert( pData ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ bRet = FALSE; +/*N*/ } +/*N*/ #endif +/*N*/ } +/*N*/ } +/*N*/ bSaveLater = FALSE; +/*N*/ return bRet; +/*N*/ } + +/*N*/ BOOL ScAutoFormat::Save() +/*N*/ { +/*N*/ BOOL bRet = TRUE; +/*N*/ +/*N*/ INetURLObject aURL; +/*N*/ SvtPathOptions aPathOpt; +/*N*/ aURL.SetSmartURL( aPathOpt.GetUserConfigPath() ); +/*N*/ aURL.setFinalSlash(); +/*N*/ aURL.Append( String( RTL_CONSTASCII_USTRINGPARAM( sAutoTblFmtName ) ) ); +/*N*/ +/*N*/ SfxMedium aMedium( aURL.GetMainURL(INetURLObject::NO_DECODE), STREAM_WRITE, TRUE ); +/*N*/ SvStream* pStream = aMedium.GetOutStream(); +/*N*/ bRet = (pStream && pStream->GetError() == 0); +/*N*/ if (bRet) +/*N*/ { +/*N*/ SvStream& rStream = *pStream; +/*N*/ rStream.SetVersion( SOFFICE_FILEFORMAT_40 ); +/*N*/ +/*N*/ // Achtung hier muss ein allgemeiner Header gespeichert werden +/*N*/ USHORT nVal = AUTOFORMAT_ID; +/*N*/ rStream << nVal +/*N*/ << (BYTE)2 // Anzahl von Zeichen des Headers incl. diesem +/*N*/ << (BYTE)::GetSOStoreTextEncoding( +/*N*/ gsl_getSystemTextEncoding(), rStream.GetVersion() ); +/*N*/ // << (BYTE)4 // Anzahl von Zeichen des Headers incl. diesem +/*N*/ // << (BYTE)::GetStoreCharSet(::GetSystemCharSet()) +/*N*/ // << (UNIT16)SOFFICE_FILEFORMAT_NOW; +/*N*/ ScAfVersions::Write(rStream); // Item-Versionen +/*N*/ +/*N*/ bRet = (rStream.GetError() == 0); +/*N*/ //----------------------------------------------------------- +/*N*/ rStream << (USHORT)(nCount - 1); +/*N*/ bRet = (rStream.GetError() == 0); +/*N*/ for (USHORT i=1; bRet && (i < nCount); i++) +/*N*/ bRet = ((ScAutoFormatData*)pItems[i])->Save(rStream); +/*N*/ rStream.Flush(); +/*N*/ +/*N*/ aMedium.Commit(); +/*N*/ } +/*N*/ bSaveLater = FALSE; +/*N*/ return bRet; +/*N*/ } + + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_callform.cxx b/binfilter/bf_sc/source/core/tool/sc_callform.cxx new file mode 100644 index 000000000000..294db281dbec --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_callform.cxx @@ -0,0 +1,318 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// INCLUDE --------------------------------------------------------------- + +#include <osl/module.hxx> + +#include "adiasync.hxx" +#include <tools/debug.hxx> +namespace binfilter { + + +//------------------------------------------------------------------------ + +extern "C" { + +typedef void (CALLTYPE* ExFuncPtr1)(void*); +typedef void (CALLTYPE* ExFuncPtr2)(void*, void*); +typedef void (CALLTYPE* ExFuncPtr3)(void*, void*, void*); +typedef void (CALLTYPE* ExFuncPtr4)(void*, void*, void*, void*); +typedef void (CALLTYPE* ExFuncPtr5)(void*, void*, void*, void*, void*); +typedef void (CALLTYPE* ExFuncPtr6)(void*, void*, void*, void*, void*, void*); +typedef void (CALLTYPE* ExFuncPtr7)(void*, void*, void*, void*, void*, void*, void*); +typedef void (CALLTYPE* ExFuncPtr8)(void*, void*, void*, void*, void*, void*, void*, void*); +typedef void (CALLTYPE* ExFuncPtr9)(void*, void*, void*, void*, void*, void*, void*, void*, void*); +typedef void (CALLTYPE* ExFuncPtr10)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*); +typedef void (CALLTYPE* ExFuncPtr11)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*); +typedef void (CALLTYPE* ExFuncPtr12)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*); +typedef void (CALLTYPE* ExFuncPtr13)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*); +typedef void (CALLTYPE* ExFuncPtr14)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*); +typedef void (CALLTYPE* ExFuncPtr15)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*); +typedef void (CALLTYPE* ExFuncPtr16)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*); + +typedef void (CALLTYPE* GetFuncCountPtr)(USHORT& nCount); +typedef void (CALLTYPE* GetFuncDataPtr) + (USHORT& nNo, sal_Char* pFuncName, USHORT& nParamCount, ParamType* peType, sal_Char* pInternalName); + +typedef void (CALLTYPE* SetLanguagePtr)( USHORT& nLanguage ); +typedef void (CALLTYPE* GetParamDesc) + (USHORT& nNo, USHORT& nParam, sal_Char* pName, sal_Char* pDesc ); + +typedef void (CALLTYPE* IsAsync) ( USHORT& nNo, + ParamType* peType ); +typedef void (CALLTYPE* Advice) ( USHORT& nNo, + AdvData& pfCallback ); +typedef void (CALLTYPE* Unadvice)( double& nHandle ); + +typedef void (CALLTYPE* FARPROC) ( void ); + +} + +#if defined(OS2) && defined(BLC) +#define GETFUNCTIONCOUNT "_GetFunctionCount" +#define GETFUNCTIONDATA "_GetFunctionData" +#define SETLANGUAGE "_SetLanguage" +#define GETPARAMDESC "_GetParameterDescription" +#define ISASYNC "_IsAsync" +#define ADVICE "_Advice" +#define UNADVICE "_Unadvice" +#else // Pascal oder extern "C" +#define GETFUNCTIONCOUNT "GetFunctionCount" +#define GETFUNCTIONDATA "GetFunctionData" +#define SETLANGUAGE "SetLanguage" +#define GETPARAMDESC "GetParameterDescription" +#define ISASYNC "IsAsync" +#define ADVICE "Advice" +#define UNADVICE "Unadvice" +#endif + +#define LIBFUNCNAME( name ) \ + (String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( name ) )) + +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/*N*/ FuncData::FuncData(const String& rIName) : +/*N*/ pModuleData (NULL), +/*N*/ aInternalName (rIName), +/*N*/ // aFuncName (""), +/*N*/ nNumber (0), +/*N*/ nParamCount (0), +/*N*/ eAsyncType (NONE) +/*N*/ { +/*N*/ for (USHORT i = 0; i < MAXFUNCPARAM; i++) +/*N*/ eParamType[i] = PTR_DOUBLE; +/*N*/ } + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + +/*N*/ FuncData::FuncData(const FuncData& rData) : +/*N*/ pModuleData (rData.pModuleData), +/*N*/ aInternalName (rData.aInternalName), +/*N*/ aFuncName (rData.aFuncName), +/*N*/ nNumber (rData.nNumber), +/*N*/ nParamCount (rData.nParamCount), +/*N*/ eAsyncType (rData.eAsyncType) +/*N*/ { +/*N*/ for (USHORT i = 0; i < MAXFUNCPARAM; i++) +/*N*/ eParamType[i] = rData.eParamType[i]; +/*N*/ } + +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/*N*/ short FuncCollection::Compare(DataObject* pKey1, DataObject* pKey2) const +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); return 0; //STRIP001 return (short) ScGlobal::pTransliteration->compareString( +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ BOOL FuncCollection::SearchFunc( const String& rName, USHORT& rIndex ) const +/*N*/ { +/*N*/ FuncData aDataObj(rName); +/*N*/ return Search( &aDataObj, rIndex ); +/*N*/ } + +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +class ModuleData : public DataObject +{ + friend class ModuleCollection; + String aName; + osl::Module* pInstance; +public: + ModuleData(const String& rStr, osl::Module* pInst) : aName (rStr), pInstance (pInst) {} + ModuleData(const ModuleData& rData) : aName (rData.aName) {pInstance = new osl::Module(aName);} + ~ModuleData() { delete pInstance; } + virtual DataObject* Clone() const { return new ModuleData(*this); } + + const String& GetName() const { return aName; } + osl::Module* GetInstance() const { return pInstance; } + void FreeInstance() { delete pInstance; pInstance = 0; } +}; + +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +/*N*/ class ModuleCollection : public SortedCollection +/*N*/ { +/*N*/ public: +/*N*/ ModuleCollection(USHORT nLim = 4, USHORT nDel = 4, BOOL bDup = FALSE) : SortedCollection ( nLim, nDel, bDup ) {} +/*N*/ ModuleCollection(const ModuleCollection& rModuleCollection) : SortedCollection ( rModuleCollection ) {} +/*N*/ +/*N*/ virtual DataObject* Clone() const { return new ModuleCollection(*this); } +/*N*/ ModuleData* operator[]( const USHORT nIndex) const {return (ModuleData*)At(nIndex);} + virtual short Compare(DataObject* pKey1, DataObject* pKey2) const{DBG_BF_ASSERT(0, "STRIP"); return 0;} //STRIP001 virtual short Compare(DataObject* pKey1, DataObject* pKey2) const; +/*N*/ }; + +/*N*/ #ifdef _MSC_VER +/*N*/ #pragma code_seg("SCSTATICS") +/*N*/ #endif +/*N*/ +/*N*/ static ModuleCollection aModuleCollection; +/*N*/ +/*N*/ #ifdef _MSC_VER +/*N*/ #pragma code_seg() +/*N*/ #endif + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + + +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + + +//------------------------------------------------------------------------ + +/*N*/ void ExitExternalFunc() +/*N*/ { +/*N*/ USHORT nCount = aModuleCollection.GetCount(); +/*N*/ for (USHORT i=0; i<nCount; i++) +/*N*/ { +/*?*/ ModuleData* pData = aModuleCollection[i]; +/*?*/ pData->FreeInstance(); +/*N*/ } +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ BOOL FuncData::Call(void** ppParam) +/*N*/ { +/*N*/ BOOL bRet = FALSE; + osl::Module* pLib = pModuleData->GetInstance(); +/*N*/ FARPROC fProc = (FARPROC)pLib->getSymbol(aFuncName); +/*N*/ if (fProc != NULL) +/*N*/ { +/*N*/ switch (nParamCount) +/*N*/ { +/*N*/ case 1 : +/*N*/ (*((ExFuncPtr1)fProc))(ppParam[0]); +/*N*/ bRet = TRUE; +/*N*/ break; +/*N*/ case 2 : +/*N*/ (*((ExFuncPtr2)fProc))(ppParam[0], ppParam[1]); +/*N*/ bRet = TRUE; +/*N*/ break; +/*N*/ case 3 : +/*N*/ (*((ExFuncPtr3)fProc))(ppParam[0], ppParam[1], ppParam[2]); +/*N*/ bRet = TRUE; +/*N*/ break; +/*N*/ case 4 : +/*N*/ (*((ExFuncPtr4)fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3]); +/*N*/ bRet = TRUE; +/*N*/ break; +/*N*/ case 5 : +/*N*/ (*((ExFuncPtr5)fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4]); +/*N*/ bRet = TRUE; +/*N*/ break; +/*N*/ case 6 : +/*N*/ (*((ExFuncPtr6)fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5]); +/*N*/ bRet = TRUE; +/*N*/ break; +/*N*/ case 7 : +/*N*/ (*((ExFuncPtr7)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], +/*N*/ ppParam[6]); +/*N*/ bRet = TRUE; +/*N*/ break; +/*N*/ case 8 : +/*N*/ (*((ExFuncPtr8)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], +/*N*/ ppParam[6], ppParam[7]); +/*N*/ bRet = TRUE; +/*N*/ break; +/*N*/ case 9 : +/*N*/ (*((ExFuncPtr9)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], +/*N*/ ppParam[6], ppParam[7], ppParam[8]); +/*N*/ bRet = TRUE; +/*N*/ break; +/*N*/ case 10 : +/*N*/ (*((ExFuncPtr10)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], +/*N*/ ppParam[6], ppParam[7], ppParam[8], ppParam[9]); +/*N*/ bRet = TRUE; +/*N*/ break; +/*N*/ case 11 : +/*N*/ (*((ExFuncPtr11)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], +/*N*/ ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10]); +/*N*/ bRet = TRUE; +/*N*/ break; +/*N*/ case 12: +/*N*/ (*((ExFuncPtr12)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], +/*N*/ ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11]); +/*N*/ bRet = TRUE; +/*N*/ break; +/*N*/ case 13: +/*N*/ (*((ExFuncPtr13)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], +/*N*/ ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11], +/*N*/ ppParam[12]); +/*N*/ bRet = TRUE; +/*N*/ break; +/*N*/ case 14 : +/*N*/ (*((ExFuncPtr14)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], +/*N*/ ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11], +/*N*/ ppParam[12], ppParam[13]); +/*N*/ bRet = TRUE; +/*N*/ break; +/*N*/ case 15 : +/*N*/ (*((ExFuncPtr15)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], +/*N*/ ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11], +/*N*/ ppParam[12], ppParam[13], ppParam[14]); +/*N*/ bRet = TRUE; +/*N*/ break; +/*N*/ case 16 : +/*N*/ (*((ExFuncPtr16)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], +/*N*/ ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11], +/*N*/ ppParam[12], ppParam[13], ppParam[14], ppParam[15]); +/*N*/ bRet = TRUE; +/*N*/ break; +/*N*/ default : break; +/*N*/ } +/*N*/ } +/*N*/ return bRet; +/*N*/ } + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_cellform.cxx b/binfilter/bf_sc/source/core/tool/sc_cellform.cxx new file mode 100644 index 000000000000..4fe9a23d06f7 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_cellform.cxx @@ -0,0 +1,219 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// INCLUDE --------------------------------------------------------------- + +#include <bf_sfx2/objsh.hxx> +#include <bf_svtools/zforlist.hxx> + +#include "cellform.hxx" +#include "cell.hxx" +#include "document.hxx" +#include "bf_sc.hrc" +namespace binfilter { + +// STATIC DATA ----------------------------------------------------------- + +// Err527 Workaround +const ScFormulaCell* pLastFormulaTreeTop = 0; + +// ----------------------------------------------------------------------- + +/*N*/ void ScCellFormat::GetString( ScBaseCell* pCell, ULONG nFormat, String& rString, +/*N*/ Color** ppColor, SvNumberFormatter& rFormatter, +/*N*/ BOOL bNullVals, +/*N*/ BOOL bFormula, +/*N*/ ScForceTextFmt eForceTextFmt ) +/*N*/ { +/*N*/ *ppColor = NULL; +/*N*/ if (&rFormatter==NULL) +/*N*/ { +/*N*/ rString.Erase(); +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ CellType eType = pCell->GetCellType(); +/*N*/ switch(eType) +/*N*/ { +/*N*/ case CELLTYPE_STRING: +/*N*/ { +/*N*/ String aCellString; +/*N*/ ((ScStringCell*)pCell)->GetString( aCellString ); +/*N*/ rFormatter.GetOutputString( aCellString, nFormat, rString, ppColor ); +/*N*/ } +/*N*/ break; +/*N*/ case CELLTYPE_EDIT: +/*N*/ { +/*N*/ String aCellString; +/*N*/ ((ScEditCell*)pCell)->GetString( aCellString ); +/*N*/ rFormatter.GetOutputString( aCellString, nFormat, rString, ppColor ); +/*N*/ } +/*N*/ break; +/*N*/ case CELLTYPE_VALUE: +/*N*/ { +/*N*/ double nValue = ((ScValueCell*)pCell)->GetValue(); +/*N*/ if ( !bNullVals && nValue == 0.0 ) +/*N*/ rString.Erase(); +/*N*/ else +/*N*/ { +/*N*/ if( eForceTextFmt == ftCheck ) +/*N*/ { +/*N*/ if( nFormat && rFormatter.IsTextFormat( nFormat ) ) +/*N*/ eForceTextFmt = ftForce; +/*N*/ } +/*N*/ if( eForceTextFmt == ftForce ) +/*N*/ { +/*?*/ String aTemp; +/*?*/ rFormatter.GetOutputString( nValue, 0, aTemp, ppColor ); +/*?*/ rFormatter.GetOutputString( aTemp, nFormat, rString, ppColor ); +/*N*/ } +/*N*/ else +/*N*/ rFormatter.GetOutputString( nValue, nFormat, rString, ppColor ); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case CELLTYPE_FORMULA: +/*N*/ { +/*N*/ ScFormulaCell* pFCell = (ScFormulaCell*)pCell; +/*N*/ if ( bFormula ) +/*?*/ pFCell->GetFormula( rString ); +/*N*/ else +/*N*/ { +/*N*/ // #62160# Ein via Interpreter gestartetes Makro, das hart +/*N*/ // auf Formelzellen zugreift, bekommt einen CellText, auch +/*N*/ // wenn dadurch ein weiterer Interpreter gestartet wird, +/*N*/ // aber nicht wenn diese Zelle gerade interpretiert wird. +/*N*/ // IdleCalc startet generell keine weiteren Interpreter, +/*N*/ // um keine Err522 (zirkulaer) zu bekommen. +/*N*/ if ( pFCell->GetDocument()->IsInInterpreter() && +/*N*/ (!pFCell->GetDocument()->GetMacroInterpretLevel() +/*N*/ || pFCell->IsRunning()) ) +/*N*/ { +/*?*/ rString.AssignAscii( RTL_CONSTASCII_STRINGPARAM("...") ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ USHORT nErrCode = pFCell->GetErrCode(); +/*N*/ if ( nErrCode == errInterpOverflow ) +/*N*/ { // maxrecursion ausbuegeln, Err527 Workaround +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 ScDocument* pDoc = pFCell->GetDocument(); +/*N*/ } +/*N*/ +/*N*/ // erst nach dem Interpretieren (GetErrCode) das Zahlformat holen: +/*N*/ if ( (nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 ) +/*N*/ nFormat = pFCell->GetStandardFormat( rFormatter, +/*N*/ nFormat ); +/*N*/ +/*N*/ if (nErrCode != 0) +/*N*/ rString = ScGlobal::GetErrorString(nErrCode); +/*N*/ else if ( pFCell->IsValue() ) +/*N*/ { +/*N*/ double fValue = pFCell->GetValue(); +/*N*/ if ( !bNullVals && fValue == 0.0 ) +/*?*/ rString.Erase(); +/*N*/ else +/*N*/ rFormatter.GetOutputString( fValue, nFormat, rString, ppColor ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ String aCellString; +/*N*/ pFCell->GetString( aCellString ); +/*N*/ rFormatter.GetOutputString( aCellString, nFormat, rString, ppColor ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ default: +/*N*/ rString.Erase(); +/*N*/ break; +/*N*/ } +/*N*/ } + +/*N*/ void ScCellFormat::GetInputString( ScBaseCell* pCell, ULONG nFormat, String& rString, +/*N*/ SvNumberFormatter& rFormatter ) +/*N*/ { +/*N*/ if (&rFormatter==NULL) +/*N*/ { +/*N*/ rString.Erase(); +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ CellType eType = pCell->GetCellType(); +/*N*/ switch(eType) +/*N*/ { +/*N*/ case CELLTYPE_STRING: +/*N*/ { +/*N*/ ((ScStringCell*)pCell)->GetString( rString ); +/*N*/ } +/*N*/ break; +/*?*/ case CELLTYPE_EDIT: +/*?*/ { +/*?*/ ((ScEditCell*)pCell)->GetString( rString ); +/*?*/ } +/*?*/ break; +/*?*/ case CELLTYPE_VALUE: +/*?*/ { +/*?*/ double nValue = ((ScValueCell*)pCell)->GetValue(); +/*?*/ rFormatter.GetInputLineString( nValue, nFormat, rString ); +/*?*/ } +/*?*/ break; +/*N*/ case CELLTYPE_FORMULA: +/*N*/ { +/*N*/ if (((ScFormulaCell*)pCell)->IsValue()) +/*N*/ { +/*?*/ double nValue = ((ScFormulaCell*)pCell)->GetValue(); +/*?*/ rFormatter.GetInputLineString( nValue, nFormat, rString ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ ((ScFormulaCell*)pCell)->GetString( rString ); +/*N*/ } +/*N*/ +/*N*/ USHORT nErrCode = ((ScFormulaCell*)pCell)->GetErrCode(); +/*N*/ if (nErrCode != 0) +/*N*/ { +/*?*/ rString.Erase(); +/*N*/ } +/*N*/ } +/*N*/ break; +/*?*/ default: +/*?*/ rString.Erase(); +/*?*/ break; +/*N*/ } +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_chartarr.cxx b/binfilter/bf_sc/source/core/tool/sc_chartarr.cxx new file mode 100644 index 000000000000..26e6b2416c9d --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_chartarr.cxx @@ -0,0 +1,1203 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// INCLUDE --------------------------------------------------------------- + +#include <bf_svtools/zforlist.hxx> +#include <bf_sch/schdll.hxx> +#include <bf_sch/memchrt.hxx> +#include <float.h> // DBL_MIN + +#include "chartarr.hxx" +#include "document.hxx" +#include "rechead.hxx" +#include "globstr.hrc" +#include "cell.hxx" +#include "docoptio.hxx" +namespace binfilter { + + +// ----------------------------------------------------------------------- + +// static +/*N*/ void ScChartArray::CopySettings( SchMemChart& rDest, const SchMemChart& rSource ) +/*N*/ { +/*N*/ rDest.SetMainTitle( rSource.GetMainTitle() ); +/*N*/ rDest.SetSubTitle( rSource.GetSubTitle() ); +/*N*/ rDest.SetXAxisTitle( rSource.GetXAxisTitle() ); +/*N*/ rDest.SetYAxisTitle( rSource.GetYAxisTitle() ); +/*N*/ rDest.SetZAxisTitle( rSource.GetZAxisTitle() ); +/*N*/ +/*N*/ const sal_Int32* pArr; +/*N*/ if ( rSource.GetRowCount() == rDest.GetRowCount() && +/*N*/ rSource.GetColCount() == rDest.GetColCount() ) +/*N*/ { +/*N*/ // don't copy column/row number formats here (are set in new MemChart object) +/*N*/ +/*N*/ if ( (pArr = rSource.GetRowTranslation()) ) rDest.SetRowTranslation( pArr ); +/*N*/ if ( (pArr = rSource.GetColTranslation()) ) rDest.SetColTranslation( pArr ); +/*N*/ rDest.SetTranslation( rSource.GetTranslation() ); +/*N*/ } +/*N*/ } + +// ----------------------------------------------------------------------- + +/*N*/ ScChartArray::ScChartArray( ScDocument* pDoc, const ScRangeListRef& rRangeList, +/*N*/ const String& rChartName ) : +/*N*/ aRangeListRef( rRangeList ), +/*N*/ aName( rChartName ), +/*N*/ pDocument( pDoc ), +/*N*/ pPositionMap( NULL ), +/*N*/ eGlue( SC_CHARTGLUE_NA ), +/*N*/ nStartCol(0), +/*N*/ nStartRow(0), +/*N*/ bColHeaders( FALSE ), +/*N*/ bRowHeaders( FALSE ), +/*N*/ bDummyUpperLeft( FALSE ), +/*N*/ bValid( TRUE ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 if ( aRangeListRef.Is() ) +/*N*/ } +/*N*/ +/*N*/ ScChartArray::ScChartArray( const ScChartArray& rArr ) : +/*N*/ aRangeListRef( rArr.aRangeListRef ), +/*N*/ aName(rArr.aName), +/*N*/ pDocument(rArr.pDocument), +/*N*/ pPositionMap( NULL ), +/*N*/ eGlue(rArr.eGlue), +/*N*/ nStartCol(rArr.nStartCol), +/*N*/ nStartRow(rArr.nStartRow), +/*N*/ bColHeaders(rArr.bColHeaders), +/*N*/ bRowHeaders(rArr.bRowHeaders), +/*N*/ bDummyUpperLeft( rArr.bDummyUpperLeft ), +/*N*/ bValid(rArr.bValid) +/*N*/ { +/*N*/ } +/*N*/ +/*N*/ ScChartArray::ScChartArray( ScDocument* pDoc, SvStream& rStream, ScMultipleReadHeader& rHdr ) : +/*N*/ pDocument( pDoc ), +/*N*/ pPositionMap( NULL ), +/*N*/ eGlue( SC_CHARTGLUE_NONE ), +/*N*/ bDummyUpperLeft( FALSE ), +/*N*/ bValid( TRUE ) +/*N*/ { +/*N*/ USHORT nCol2, nRow2, nTable; +/*N*/ +/*N*/ rHdr.StartEntry(); +/*N*/ +/*N*/ rStream >> nTable; +/*N*/ rStream >> nStartCol; +/*N*/ rStream >> nStartRow; +/*N*/ rStream >> nCol2; +/*N*/ rStream >> nRow2; +/*N*/ rStream.ReadByteString( aName, rStream.GetStreamCharSet() ); +/*N*/ rStream >> bColHeaders; +/*N*/ rStream >> bRowHeaders; +/*N*/ +/*N*/ rHdr.EndEntry(); +/*N*/ +/*N*/ SetRangeList( ScRange( nStartCol, nStartRow, nTable, nCol2, nRow2, nTable ) ); +/*N*/ } + +/*N*/ ScChartArray::ScChartArray( ScDocument* pDoc, const SchMemChart& rData ) : +/*N*/ pDocument( pDoc ), +/*N*/ pPositionMap( NULL ) +/*N*/ { +/*N*/ BOOL bInitOk = bValid = FALSE; +/*N*/ const SchChartRange& rChartRange = rData.GetChartRange(); +/*N*/ ::std::vector< SchCellRangeAddress >::const_iterator iRange = +/*N*/ rChartRange.maRanges.begin(); +/*N*/ if ( iRange != rChartRange.maRanges.end() ) +/*N*/ { // new SO6 chart format +/*N*/ bValid = TRUE; +/*N*/ bColHeaders = rChartRange.mbFirstRowContainsLabels; +/*N*/ bRowHeaders = rChartRange.mbFirstColumnContainsLabels; +/*N*/ aRangeListRef = new ScRangeList; +/*N*/ for ( ; iRange != rChartRange.maRanges.end(); ++iRange ) +/*N*/ { +/*N*/ const SchSingleCell& rAddr1 = (*iRange).maUpperLeft.maCells[0]; +/*N*/ const SchSingleCell& rAddr2 = (*iRange).maLowerRight.maCells[0]; +/*N*/ USHORT nTab = (USHORT) (*iRange).mnTableNumber; +/*N*/ ScRange aRange( +/*N*/ (USHORT) rAddr1.mnColumn, (USHORT) rAddr1.mnRow, nTab, +/*N*/ (USHORT) rAddr2.mnColumn, (USHORT) rAddr2.mnRow, nTab ); +/*N*/ aRangeListRef->Append( aRange ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { // old SO5 chart format +/*N*/ //! A similar routine is implemented in +/*N*/ //! SchMemChart::ConvertChartRangeForCalc() for OldToNew. If anything +/*N*/ //! is changed here it propably must be changed there too! +/*N*/ const sal_Unicode cTok = ';'; +/*N*/ xub_StrLen nToken; +/*N*/ String aPos = ((SchMemChart&)rData).SomeData1(); +/*N*/ if ( (nToken = aPos.GetTokenCount( cTok )) >= 5) +/*N*/ { +/*N*/ String aOpt = ((SchMemChart&)rData).SomeData2(); +/*N*/ xub_StrLen nOptToken = aOpt.GetTokenCount( cTok ); +/*N*/ BOOL bNewChart = (nOptToken >= 4); // as of 341/342 +/*N*/ USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; +/*N*/ xub_StrLen nInd = 0; +/*N*/ for ( xub_StrLen j=0; j < nToken; j+=5 ) +/*N*/ { +/*N*/ xub_StrLen nInd2 = nInd; +/*N*/ nTab1 = (USHORT) aPos.GetToken( 0, cTok, nInd ).ToInt32(); +/*N*/ // To make old versions (<341/342) skip it, the token separator +/*N*/ // is a ',' +/*N*/ if ( bNewChart ) +/*?*/ nTab2 = (USHORT) aPos.GetToken( 1, ',', nInd2 ).ToInt32(); +/*N*/ else +/*N*/ nTab2 = nTab1; +/*N*/ nCol1 = (USHORT) aPos.GetToken( 0, cTok, nInd ).ToInt32(); +/*N*/ nRow1 = (USHORT) aPos.GetToken( 0, cTok, nInd ).ToInt32(); +/*N*/ nCol2 = (USHORT) aPos.GetToken( 0, cTok, nInd ).ToInt32(); +/*N*/ nRow2 = (USHORT) aPos.GetToken( 0, cTok, nInd ).ToInt32(); +/*N*/ AddToRangeList( ScRange( nCol1, nRow1, nTab1, +/*N*/ nCol2, nRow2, nTab2 ) ); +/*N*/ } +/*N*/ bValid = TRUE; +/*N*/ +/*N*/ if (aOpt.Len() >= 2) +/*N*/ { +/*N*/ bColHeaders = ( aOpt.GetChar(0) != '0' ); +/*N*/ bRowHeaders = ( aOpt.GetChar(1) != '0' ); +/*N*/ if ( aOpt.Len() >= 3 ) +/*N*/ { +/*N*/ if ( bNewChart ) +/*N*/ { +/*N*/ bDummyUpperLeft = ( aOpt.GetChar(2) != '0' ); +/*N*/ xub_StrLen nInd = 4; // 111; +/*N*/ eGlue = (ScChartGlue) aOpt.GetToken( 0, cTok, nInd ).ToInt32(); +/*N*/ nStartCol = (USHORT) aOpt.GetToken( 0, cTok, nInd ).ToInt32(); +/*N*/ nStartRow = (USHORT) aOpt.GetToken( 0, cTok, nInd ).ToInt32(); +/*N*/ bInitOk = TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ bColHeaders = bRowHeaders = FALSE; +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ SetRangeList( ScRange() ); +/*?*/ bColHeaders = bRowHeaders = bValid = FALSE; +/*N*/ } +/*N*/ } +/*N*/ if ( !bInitOk ) +/*N*/ { // muessen in GlueState neu berechnet werden +/*N*/ InvalidateGlue(); +/*N*/ nStartCol = nStartRow = 0; +/*N*/ bDummyUpperLeft = FALSE; +/*N*/ } +/*N*/ } + +/*N*/ ScChartArray::~ScChartArray() +/*N*/ { +/*N*/ delete pPositionMap; +/*N*/ } + + + + +/*N*/ void ScChartArray::SetRangeList( const ScRange& rRange ) +/*N*/ { +/*N*/ aRangeListRef = new ScRangeList; +/*N*/ aRangeListRef->Append( rRange ); +/*N*/ InvalidateGlue(); +/*N*/ } + +/*N*/ void ScChartArray::AddToRangeList( const ScRange& rRange ) +/*N*/ { +/*N*/ if ( aRangeListRef.Is() ) +/*N*/ aRangeListRef->Append( rRange ); +/*N*/ else +/*N*/ SetRangeList( rRange ); +/*N*/ InvalidateGlue(); +/*N*/ } + +/*N*/ void ScChartArray::AddToRangeList( const ScRangeListRef& rAdd ) +/*N*/ { +/*N*/ if ( aRangeListRef.Is() ) +/*N*/ { +/*N*/ ULONG nCount = rAdd->Count(); +/*N*/ for (ULONG i=0; i<nCount; i++) +/*N*/ aRangeListRef->Join( *rAdd->GetObject(i) ); +/*N*/ } +/*N*/ else +/*N*/ SetRangeList( rAdd ); +/*N*/ InvalidateGlue(); +/*N*/ } + +/*N*/ void ScChartArray::GlueState() +/*N*/ { +/*N*/ if ( eGlue != SC_CHARTGLUE_NA ) +/*N*/ return; +/*N*/ bDummyUpperLeft = FALSE; +/*N*/ ScRangePtr pR; +/*N*/ if ( aRangeListRef->Count() <= 1 ) +/*N*/ { +/*?*/ if ( pR = aRangeListRef->First() ) +/*?*/ { +/*?*/ if ( pR->aStart.Tab() == pR->aEnd.Tab() ) +/*?*/ eGlue = SC_CHARTGLUE_NONE; +/*?*/ else +/*?*/ eGlue = SC_CHARTGLUE_COLS; // mehrere Tabellen spaltenweise +/*?*/ nStartCol = pR->aStart.Col(); +/*?*/ nStartRow = pR->aStart.Row(); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ InvalidateGlue(); +/*?*/ nStartCol = nStartRow = 0; +/*?*/ } +/*?*/ return; +/*N*/ } +/*N*/ ULONG nOldPos = aRangeListRef->GetCurPos(); +/*N*/ +/*N*/ pR = aRangeListRef->First(); +/*N*/ nStartCol = pR->aStart.Col(); +/*N*/ nStartRow = pR->aStart.Row(); +/*N*/ USHORT nMaxCols, nMaxRows, nEndCol, nEndRow; +/*N*/ nMaxCols = nMaxRows = nEndCol = nEndRow = 0; +/*N*/ do +/*N*/ { // umspannenden Bereich etc. feststellen +/*N*/ USHORT nTmp, n1, n2; +/*N*/ if ( (n1 = pR->aStart.Col()) < nStartCol ) +/*N*/ nStartCol = n1; +/*N*/ if ( (n2 = pR->aEnd.Col()) > nEndCol ) +/*N*/ nEndCol = n2; +/*N*/ if ( (nTmp = n2 - n1 + 1) > nMaxCols ) +/*N*/ nMaxCols = nTmp; +/*N*/ if ( (n1 = pR->aStart.Row()) < nStartRow ) +/*N*/ nStartRow = n1; +/*N*/ if ( (n2 = pR->aEnd.Row()) > nEndRow ) +/*N*/ nEndRow = n2; +/*N*/ if ( (nTmp = n2 - n1 + 1) > nMaxRows ) +/*N*/ nMaxRows = nTmp; +/*N*/ } while ( pR = aRangeListRef->Next() ); +/*N*/ USHORT nC = nEndCol - nStartCol + 1; +/*N*/ if ( nC == 1 ) +/*N*/ { +/*N*/ eGlue = SC_CHARTGLUE_ROWS; +/*N*/ return; +/*N*/ } +/*N*/ USHORT nR = nEndRow - nStartRow + 1; +/*N*/ if ( nR == 1 ) +/*N*/ { +/*N*/ eGlue = SC_CHARTGLUE_COLS; +/*N*/ return; +/*N*/ } +/*N*/ ULONG nCR = (ULONG)nC * nR; +/*N*/ //2do: +/* + Erstmal simpel ohne Bitmaskiererei, maximal koennten so 8MB alloziert + werden (256 Cols mal 32000 Rows), das liesse sich mit 2 Bit je Eintrag + auf 2MB reduzieren, andererseits ist es so schneller. + Weitere Platz-Optimierung waere, in dem Array nur die wirklich benutzten + Zeilen/Spalten abzulegen, wuerde aber ein weiteres durchlaufen der + RangeList und indirekten Zugriff auf das Array bedeuten. + */ +/*N*/ const BYTE nHole = 0; +/*N*/ const BYTE nOccu = 1; +/*N*/ const BYTE nFree = 2; +/*N*/ const BYTE nGlue = 3; +/*N*/ #ifdef WIN +/*?*/ // we hate 16bit, don't we? +/*?*/ BYTE huge* p; +/*?*/ BYTE huge* pA = (BYTE huge*) SvMemAlloc( nCR ); +/*?*/ if ( nCR > (ULONG)((USHORT)~0) ) +/*?*/ { // in 32k Bloecken initialisieren +/*?*/ ULONG j; +/*?*/ for ( j=0; j<nCR; j+=0x8000 ) +/*?*/ { +/*?*/ memset( pA+j, nHole, Min( (ULONG)0x8000, nCR-j ) ); +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ memset( pA, nHole, nCR * sizeof(BYTE) ); +/*N*/ #else +/*N*/ BYTE* p; +/*N*/ BYTE* pA = new BYTE[ nCR ]; +/*N*/ memset( pA, 0, nCR * sizeof(BYTE) ); +/*N*/ #endif +/*N*/ +/*N*/ USHORT nCol, nRow, nCol1, nRow1, nCol2, nRow2; +/*N*/ for ( pR = aRangeListRef->First(); pR; pR = aRangeListRef->Next() ) +/*N*/ { // Selektionen 2D als belegt markieren +/*N*/ nCol1 = pR->aStart.Col() - nStartCol; +/*N*/ nCol2 = pR->aEnd.Col() - nStartCol; +/*N*/ nRow1 = pR->aStart.Row() - nStartRow; +/*N*/ nRow2 = pR->aEnd.Row() - nStartRow; +/*N*/ for ( nCol = nCol1; nCol <= nCol2; nCol++ ) +/*N*/ { +/*N*/ p = pA + (ULONG)nCol * nR + nRow1; +/*N*/ for ( nRow = nRow1; nRow <= nRow2; nRow++, p++ ) +/*N*/ *p = nOccu; +/*N*/ } +/*N*/ } +/*N*/ BOOL bGlue = TRUE; +/*N*/ +/*N*/ BOOL bGlueCols = FALSE; +/*N*/ for ( nCol = 0; bGlue && nCol < nC; nCol++ ) +/*N*/ { // Spalten probieren durchzugehen und als frei markieren +/*N*/ p = pA + (ULONG)nCol * nR; +/*N*/ for ( nRow = 0; bGlue && nRow < nR; nRow++, p++ ) +/*N*/ { +/*N*/ if ( *p == nOccu ) +/*N*/ { // Wenn einer mittendrin liegt ist keine Zusammenfassung +/*N*/ // moeglich. Am Rand koennte ok sein, wenn in dieser Spalte +/*N*/ // in jeder belegten Zeile einer belegt ist. +/*N*/ if ( nRow > 0 && nCol > 0 ) +/*N*/ bGlue = FALSE; // nCol==0 kann DummyUpperLeft sein +/*N*/ else +/*N*/ nRow = nR; +/*N*/ } +/*N*/ else +/*N*/ *p = nFree; +/*N*/ } +/*N*/ if ( bGlue && *(p = (pA + ((((ULONG)nCol+1) * nR) - 1))) == nFree ) +/*N*/ { // Spalte als komplett frei markieren +/*N*/ *p = nGlue; +/*N*/ bGlueCols = TRUE; // mindestens eine freie Spalte +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ BOOL bGlueRows = FALSE; +/*N*/ for ( nRow = 0; bGlue && nRow < nR; nRow++ ) +/*N*/ { // Zeilen probieren durchzugehen und als frei markieren +/*N*/ p = pA + nRow; +/*N*/ for ( nCol = 0; bGlue && nCol < nC; nCol++, p+=nR ) +/*N*/ { +/*N*/ if ( *p == nOccu ) +/*N*/ { +/*N*/ if ( nCol > 0 && nRow > 0 ) +/*N*/ bGlue = FALSE; // nRow==0 kann DummyUpperLeft sein +/*N*/ else +/*N*/ nCol = nC; +/*N*/ } +/*N*/ else +/*N*/ *p = nFree; +/*N*/ } +/*N*/ if ( bGlue && *(p = (pA + ((((ULONG)nC-1) * nR) + nRow))) == nFree ) +/*N*/ { // Zeile als komplett frei markieren +/*N*/ *p = nGlue; +/*N*/ bGlueRows = TRUE; // mindestens eine freie Zeile +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // n=1: die linke obere Ecke koennte bei Beschriftung automagisch +/*N*/ // hinzugezogen werden +/*N*/ p = pA + 1; +/*N*/ for ( ULONG n = 1; bGlue && n < nCR; n++, p++ ) +/*N*/ { // ein unberuehrtes Feld heisst, dass es weder spaltenweise noch +/*N*/ // zeilenweise zu erreichen war, also nichts zusamenzufassen +/*N*/ if ( *p == nHole ) +/*N*/ bGlue = FALSE; +/*N*/ } +/*N*/ if ( bGlue ) +/*N*/ { +/*N*/ if ( bGlueCols && bGlueRows ) +/*N*/ eGlue = SC_CHARTGLUE_BOTH; +/*N*/ else if ( bGlueRows ) +/*N*/ eGlue = SC_CHARTGLUE_ROWS; +/*N*/ else +/*N*/ eGlue = SC_CHARTGLUE_COLS; +/*N*/ if ( *pA != nOccu ) +/*N*/ bDummyUpperLeft = TRUE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ eGlue = SC_CHARTGLUE_NONE; +/*N*/ } +/*N*/ +/*N*/ #ifdef WIN +/*?*/ SvMemFree( pA ); +/*N*/ #else +/*N*/ delete [] pA; +/*N*/ #endif +/*N*/ } + + +#ifdef _MSC_VER +#pragma optimize("",off) +#endif + +/*N*/ SchMemChart* ScChartArray::CreateMemChart() +/*N*/ { +/*N*/ ULONG nCount = aRangeListRef->Count(); +/*N*/ if ( nCount > 1 ) +/*N*/ return CreateMemChartMulti(); +/*N*/ else if ( nCount == 1 ) +/*N*/ { +/*N*/ ScRange* pR = aRangeListRef->First(); +/*N*/ if ( pR->aStart.Tab() != pR->aEnd.Tab() ) +/*?*/ return CreateMemChartMulti(); +/*N*/ else +/*N*/ return CreateMemChartSingle(); +/*N*/ } +/*N*/ else +/*?*/ return CreateMemChartMulti(); // kann 0 Range besser ab als Single +/*N*/ } + +/*N*/ SchMemChart* ScChartArray::CreateMemChartSingle() +/*N*/ { +/*N*/ USHORT i,nCol,nRow; +/*N*/ +/*N*/ // +/*N*/ // wirkliche Groesse (ohne versteckte Zeilen/Spalten) +/*N*/ // +/*N*/ +/*N*/ USHORT nColAdd = bRowHeaders ? 1 : 0; +/*N*/ USHORT nRowAdd = bColHeaders ? 1 : 0; +/*N*/ +/*N*/ USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; +/*N*/ aRangeListRef->First()->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); +/*N*/ +/*N*/ USHORT nStrCol = nCol1; // fuer Beschriftung merken +/*N*/ USHORT nStrRow = nRow1; +/*N*/ // Beschriftungen auch nach HiddenCols finden +/*N*/ while ( (pDocument->GetColFlags( nCol1, nTab1) & CR_HIDDEN) != 0 ) +/*N*/ nCol1++; +/*N*/ while ( (pDocument->GetRowFlags( nRow1, nTab1) & CR_HIDDEN) != 0 ) +/*N*/ nRow1++; +/*N*/ // falls alles hidden ist, bleibt die Beschriftung am Anfang +/*N*/ if ( nCol1 <= nCol2 ) +/*N*/ { +/*N*/ nStrCol = nCol1; +/*N*/ nCol1 += nColAdd; +/*N*/ } +/*N*/ if ( nRow1 <= nRow2 ) +/*N*/ { +/*N*/ nStrRow = nRow1; +/*N*/ nRow1 += nRowAdd; +/*N*/ } +/*N*/ +/*N*/ USHORT nTotalCols = ( nCol1 <= nCol2 ? nCol2 - nCol1 + 1 : 0 ); +/*N*/ USHORT* pCols = new USHORT[nTotalCols ? nTotalCols : 1]; +/*N*/ USHORT nColCount = 0; +/*N*/ for (i=0; i<nTotalCols; i++) +/*N*/ if ((pDocument->GetColFlags(nCol1+i,nTab1)&CR_HIDDEN)==0) +/*N*/ pCols[nColCount++] = nCol1+i; +/*N*/ +/*N*/ USHORT nTotalRows = ( nRow1 <= nRow2 ? nRow2 - nRow1 + 1 : 0 ); +/*N*/ USHORT* pRows = new USHORT[nTotalRows ? nTotalRows : 1]; +/*N*/ USHORT nRowCount = 0; +/*N*/ for (i=0; i<nTotalRows; i++) +/*N*/ if ((pDocument->GetRowFlags(nRow1+i,nTab1)&CR_HIDDEN)==0) +/*N*/ pRows[nRowCount++] = nRow1+i; +/*N*/ +/*N*/ BOOL bValidData = TRUE; +/*N*/ if ( !nColCount ) +/*N*/ { +/*N*/ bValidData = FALSE; +/*N*/ nColCount = 1; +/*N*/ pCols[0] = nStrCol; +/*N*/ } +/*N*/ if ( !nRowCount ) +/*N*/ { +/*N*/ bValidData = FALSE; +/*N*/ nRowCount = 1; +/*N*/ pRows[0] = nStrRow; +/*N*/ } +/*N*/ +/*N*/ // +/*N*/ // Daten +/*N*/ // +/*N*/ +/*N*/ SchMemChart* pMemChart = SchDLL::NewMemChart( nColCount, nRowCount ); +/*N*/ if (pMemChart) +/*N*/ { +/*N*/ SvNumberFormatter* pFormatter = pDocument->GetFormatTable(); +/*N*/ pMemChart->SetNumberFormatter( pFormatter ); +/*N*/ if ( bValidData ) +/*N*/ { +/*N*/ BOOL bCalcAsShown = pDocument->GetDocOptions().IsCalcAsShown(); +/*N*/ ScBaseCell* pCell; +/*N*/ for (nCol=0; nCol<nColCount; nCol++) +/*N*/ { +/*N*/ for (nRow=0; nRow<nRowCount; nRow++) +/*N*/ { +/*N*/ double nVal = DBL_MIN; // Hack fuer Chart, um leere Zellen zu erkennen +/*N*/ +/*N*/ pDocument->GetCell( pCols[nCol], pRows[nRow], nTab1, pCell ); +/*N*/ if (pCell) +/*N*/ { +/*N*/ CellType eType = pCell->GetCellType(); +/*N*/ if (eType == CELLTYPE_VALUE) +/*N*/ { +/*?*/ nVal = ((ScValueCell*)pCell)->GetValue(); +/*?*/ if ( bCalcAsShown && nVal != 0.0 ) +/*?*/ { +/*?*/ sal_uInt32 nFormat; +/*?*/ pDocument->GetNumberFormat( pCols[nCol], +/*?*/ pRows[nRow], nTab1, nFormat ); +/*?*/ nVal = pDocument->RoundValueAsShown( nVal, nFormat ); +/*?*/ } +/*N*/ } +/*N*/ else if (eType == CELLTYPE_FORMULA) +/*N*/ { +/*N*/ ScFormulaCell* pFCell = (ScFormulaCell*)pCell; +/*N*/ if ( (pFCell->GetErrCode() == 0) && pFCell->IsValue() ) +/*N*/ nVal = pFCell->GetValue(); +/*N*/ } +/*N*/ } +/*N*/ pMemChart->SetData(nCol, nRow, nVal); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ //! Flag, dass Daten ungueltig ?? +/*?*/ +/*?*/ for (nCol=0; nCol<nColCount; nCol++) +/*?*/ for (nRow=0; nRow<nRowCount; nRow++) +/*?*/ pMemChart->SetData( nCol, nRow, DBL_MIN ); +/*N*/ } +/*N*/ +/*N*/ // +/*N*/ // Spalten-Header +/*N*/ // +/*N*/ +/*N*/ for (nCol=0; nCol<nColCount; nCol++) +/*N*/ { +/*N*/ String aString, aColStr; +/*N*/ if (bColHeaders) +/*N*/ pDocument->GetString( pCols[nCol], nStrRow, nTab1, aString ); +/*N*/ if ( !aString.Len() ) +/*N*/ { +/*N*/ aString = ScGlobal::GetRscString(STR_COLUMN); +/*N*/ aString += ' '; +/*N*/ // aString += String::CreateFromInt32( pCols[nCol]+1 ); +/*N*/ ScAddress aPos( pCols[ nCol ], 0, 0 ); +/*N*/ aPos.Format( aColStr, SCA_VALID_COL, NULL ); +/*N*/ aString += aColStr; +/*N*/ } +/*N*/ pMemChart->SetColText(nCol, aString); +/*N*/ +/*N*/ ULONG nNumberAttr = pDocument->GetNumberFormat( ScAddress( +/*N*/ pCols[nCol], nRow1, nTab1 ) ); +/*N*/ pMemChart->SetNumFormatIdCol( nCol, nNumberAttr ); +/*N*/ } +/*N*/ +/*N*/ // +/*N*/ // Zeilen-Header +/*N*/ // +/*N*/ +/*N*/ for (nRow=0; nRow<nRowCount; nRow++) +/*N*/ { +/*N*/ String aString; +/*N*/ if (bRowHeaders) +/*N*/ { +/*N*/ ScAddress aAddr( nStrCol, pRows[nRow], nTab1 ); +/*N*/ pDocument->GetString( nStrCol, pRows[nRow], nTab1, aString ); +/*N*/ } +/*N*/ if ( !aString.Len() ) +/*N*/ { +/*N*/ aString = ScGlobal::GetRscString(STR_ROW); +/*N*/ aString += ' '; +/*N*/ aString += String::CreateFromInt32( pRows[nRow]+1 ); +/*N*/ } +/*N*/ pMemChart->SetRowText(nRow, aString); +/*N*/ +/*N*/ ULONG nNumberAttr = pDocument->GetNumberFormat( ScAddress( +/*N*/ nCol1, pRows[nRow], nTab1 ) ); +/*N*/ pMemChart->SetNumFormatIdRow( nRow, nNumberAttr ); +/*N*/ } +/*N*/ +/*N*/ // +/*N*/ // Titel +/*N*/ // +/*N*/ +/*N*/ pMemChart->SetMainTitle(ScGlobal::GetRscString(STR_CHART_MAINTITLE)); +/*N*/ pMemChart->SetSubTitle(ScGlobal::GetRscString(STR_CHART_SUBTITLE)); +/*N*/ pMemChart->SetXAxisTitle(ScGlobal::GetRscString(STR_CHART_XTITLE)); +/*N*/ pMemChart->SetYAxisTitle(ScGlobal::GetRscString(STR_CHART_YTITLE)); +/*N*/ pMemChart->SetZAxisTitle(ScGlobal::GetRscString(STR_CHART_ZTITLE)); +/*N*/ +/*N*/ // +/*N*/ // Zahlen-Typ +/*N*/ // +/*N*/ +/*N*/ ULONG nNumberAttr = pDocument->GetNumberFormat( ScAddress( +/*N*/ nCol1, nRow1, nTab1 ) ); +/*N*/ if (pFormatter) +/*N*/ pMemChart->SetDataType(pFormatter->GetType( nNumberAttr )); +/*N*/ +/*N*/ // +/*N*/ // Parameter-Strings +/*N*/ // +/*N*/ +/*N*/ SetExtraStrings( *pMemChart ); +/*N*/ } +/*N*/ else +/*N*/ DBG_ERROR("SchDLL::NewMemChart gibt 0 zurueck!"); +/*N*/ +/*N*/ // Aufraeumen +/*N*/ +/*N*/ delete[] pRows; +/*N*/ delete[] pCols; +/*N*/ +/*N*/ return pMemChart; +/*N*/ } + +/*N*/ SchMemChart* ScChartArray::CreateMemChartMulti() +/*N*/ { +/*N*/ CreatePositionMap(); +/*N*/ USHORT nColCount = pPositionMap->GetColCount(); +/*N*/ USHORT nRowCount = pPositionMap->GetRowCount(); +/*N*/ +/*N*/ USHORT nCol, nRow; +/*N*/ +/*N*/ // +/*N*/ // Daten +/*N*/ // +/*N*/ +/*N*/ SchMemChart* pMemChart = SchDLL::NewMemChart( nColCount, nRowCount ); +/*N*/ if (pMemChart) +/*N*/ { +/*N*/ pMemChart->SetNumberFormatter( pDocument->GetFormatTable() ); +/*N*/ BOOL bCalcAsShown = pDocument->GetDocOptions().IsCalcAsShown(); +/*N*/ ULONG nIndex = 0; +/*N*/ for ( nCol = 0; nCol < nColCount; nCol++ ) +/*N*/ { +/*N*/ for ( nRow = 0; nRow < nRowCount; nRow++, nIndex++ ) +/*N*/ { +/*N*/ double nVal = DBL_MIN; // Hack fuer Chart, um leere Zellen zu erkennen +/*N*/ const ScAddress* pPos = pPositionMap->GetPosition( nIndex ); +/*N*/ if ( pPos ) +/*N*/ { // sonst: Luecke +/*N*/ ScBaseCell* pCell = pDocument->GetCell( *pPos ); +/*N*/ if (pCell) +/*N*/ { +/*N*/ CellType eType = pCell->GetCellType(); +/*N*/ if (eType == CELLTYPE_VALUE) +/*N*/ { +/*?*/ nVal = ((ScValueCell*)pCell)->GetValue(); +/*?*/ if ( bCalcAsShown && nVal != 0.0 ) +/*?*/ { +/*?*/ ULONG nFormat = pDocument->GetNumberFormat( *pPos ); +/*?*/ nVal = pDocument->RoundValueAsShown( nVal, nFormat ); +/*?*/ } +/*N*/ } +/*N*/ else if (eType == CELLTYPE_FORMULA) +/*N*/ { +/*N*/ ScFormulaCell* pFCell = (ScFormulaCell*)pCell; +/*N*/ if ( (pFCell->GetErrCode() == 0) && pFCell->IsValue() ) +/*N*/ nVal = pFCell->GetValue(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ pMemChart->SetData(nCol, nRow, nVal); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //2do: Beschriftung bei Luecken +/*N*/ +/*N*/ // +/*N*/ // Spalten-Header +/*N*/ // +/*N*/ +/*N*/ USHORT nPosCol = 0; +/*N*/ for ( nCol = 0; nCol < nColCount; nCol++ ) +/*N*/ { +/*N*/ String aString, aColStr; +/*N*/ const ScAddress* pPos = pPositionMap->GetColHeaderPosition( nCol ); +/*N*/ if ( bColHeaders && pPos ) +/*N*/ pDocument->GetString( +/*N*/ pPos->Col(), pPos->Row(), pPos->Tab(), aString ); +/*N*/ if ( !aString.Len() ) +/*N*/ { +/*?*/ aString = ScGlobal::GetRscString(STR_COLUMN); +/*?*/ aString += ' '; +/*?*/ if ( pPos ) +/*?*/ nPosCol = pPos->Col() + 1; +/*?*/ else +/*?*/ nPosCol++; +/*?*/ ScAddress aPos( nPosCol - 1, 0, 0 ); +/*?*/ aPos.Format( aColStr, SCA_VALID_COL, NULL ); +/*?*/ // aString += String::CreateFromInt32( nPosCol ); +/*?*/ aString += aColStr; +/*N*/ } +/*N*/ pMemChart->SetColText(nCol, aString); +/*N*/ +/*N*/ ULONG nNumberAttr = 0; +/*N*/ pPos = pPositionMap->GetPosition( nCol, 0 ); +/*N*/ if ( pPos ) +/*N*/ nNumberAttr = pDocument->GetNumberFormat( *pPos ); +/*N*/ pMemChart->SetNumFormatIdCol( nCol, nNumberAttr ); +/*N*/ } +/*N*/ +/*N*/ // +/*N*/ // Zeilen-Header +/*N*/ // +/*N*/ +/*N*/ USHORT nPosRow = 0; +/*N*/ for ( nRow = 0; nRow < nRowCount; nRow++ ) +/*N*/ { +/*N*/ String aString; +/*N*/ const ScAddress* pPos = pPositionMap->GetRowHeaderPosition( nRow ); +/*N*/ if ( bRowHeaders && pPos ) +/*N*/ { +/*N*/ pDocument->GetString( +/*N*/ pPos->Col(), pPos->Row(), pPos->Tab(), aString ); +/*N*/ } +/*N*/ if ( !aString.Len() ) +/*N*/ { +/*?*/ aString = ScGlobal::GetRscString(STR_ROW); +/*?*/ aString += ' '; +/*?*/ if ( pPos ) +/*?*/ nPosRow = pPos->Row() + 1; +/*?*/ else +/*?*/ nPosRow++; +/*?*/ aString += String::CreateFromInt32( nPosRow ); +/*N*/ } +/*N*/ pMemChart->SetRowText(nRow, aString); +/*N*/ +/*N*/ ULONG nNumberAttr = 0; +/*N*/ pPos = pPositionMap->GetPosition( 0, nRow ); +/*N*/ if ( pPos ) +/*N*/ nNumberAttr = pDocument->GetNumberFormat( *pPos ); +/*N*/ pMemChart->SetNumFormatIdRow( nRow, nNumberAttr ); +/*N*/ } +/*N*/ +/*N*/ // +/*N*/ // Titel +/*N*/ // +/*N*/ +/*N*/ pMemChart->SetMainTitle(ScGlobal::GetRscString(STR_CHART_MAINTITLE)); +/*N*/ pMemChart->SetSubTitle(ScGlobal::GetRscString(STR_CHART_SUBTITLE)); +/*N*/ pMemChart->SetXAxisTitle(ScGlobal::GetRscString(STR_CHART_XTITLE)); +/*N*/ pMemChart->SetYAxisTitle(ScGlobal::GetRscString(STR_CHART_YTITLE)); +/*N*/ pMemChart->SetZAxisTitle(ScGlobal::GetRscString(STR_CHART_ZTITLE)); +/*N*/ +/*N*/ // +/*N*/ // Zahlen-Typ +/*N*/ // +/*N*/ +/*N*/ SvNumberFormatter* pFormatter = pDocument->GetFormatTable(); +/*N*/ if (pFormatter) +/*N*/ { +/*N*/ ULONG nIndex = 0; +/*N*/ ULONG nCount = pPositionMap->GetCount(); +/*N*/ const ScAddress* pPos; +/*N*/ do +/*N*/ { +/*N*/ pPos = pPositionMap->GetPosition( nIndex ); +/*N*/ } while ( !pPos && ++nIndex < nCount ); +/*N*/ ULONG nFormat = ( pPos ? pDocument->GetNumberFormat( *pPos ) : 0 ); +/*N*/ pMemChart->SetDataType( pFormatter->GetType( nFormat ) ); +/*N*/ } +/*N*/ +/*N*/ // +/*N*/ // Parameter-Strings +/*N*/ // +/*N*/ +/*N*/ SetExtraStrings( *pMemChart ); +/*N*/ } +/*N*/ else +/*N*/ DBG_ERROR("SchDLL::NewMemChart gibt 0 zurueck!"); +/*N*/ +/*N*/ return pMemChart; +/*N*/ } + +/*N*/ void ScChartArray::SetExtraStrings( SchMemChart& rMem ) +/*N*/ { +/*N*/ ScRangePtr pR; +/*N*/ USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; +/*N*/ #if 0 +/* now this is done in SchMemChart::ConvertChartRangeForCalc() for SO5 file format + const sal_Unicode cTok = ';'; + String aRef; + for ( pR = aRangeListRef->First(); pR; pR = aRangeListRef->Next() ) + { + pR->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); + if ( aRef.Len() ) + aRef += cTok; + aRef += String::CreateFromInt32( nTab1 ); + // hier ',' als TokenSep damit alte Versionen (<341/342) das ueberlesen + aRef += ','; aRef += String::CreateFromInt32( nTab2 ); + aRef += cTok; aRef += String::CreateFromInt32( nCol1 ); + aRef += cTok; aRef += String::CreateFromInt32( nRow1 ); + aRef += cTok; aRef += String::CreateFromInt32( nCol2 ); + aRef += cTok; aRef += String::CreateFromInt32( nRow2 ); + } + + String aFlags = bColHeaders ? '1' : '0'; + aFlags += bRowHeaders ? '1' : '0'; + aFlags += bDummyUpperLeft ? '1' : '0'; + aFlags += cTok; + aFlags += String::CreateFromInt32( eGlue ); + aFlags += cTok; + aFlags += String::CreateFromInt32( nStartCol ); + aFlags += cTok; + aFlags += String::CreateFromInt32( nStartRow ); + + rMem.SomeData1() = aRef; + rMem.SomeData2() = aFlags; +*/ +/*N*/ #endif +/*N*/ +/*N*/ String aSheetNames; +/*N*/ SchChartRange aChartRange; +/*N*/ aChartRange.mbFirstColumnContainsLabels = bRowHeaders; +/*N*/ aChartRange.mbFirstRowContainsLabels = bColHeaders; +/*N*/ aChartRange.mbKeepCopyOfData = sal_False; +/*N*/ for ( pR = aRangeListRef->First(); pR; pR = aRangeListRef->Next() ) +/*N*/ { +/*N*/ pR->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); +/*N*/ for ( USHORT nTab = nTab1; nTab <= nTab2; ++nTab ) +/*N*/ { +/*N*/ SchCellRangeAddress aCellRangeAddress; +/*N*/ SchSingleCell aCell; +/*N*/ aCell.mnColumn = nCol1; +/*N*/ aCell.mnRow = nRow1; +/*N*/ aCellRangeAddress.maUpperLeft.maCells.push_back( aCell ); +/*N*/ aCell.mnColumn = nCol2; +/*N*/ aCell.mnRow = nRow2; +/*N*/ aCellRangeAddress.maLowerRight.maCells.push_back( aCell ); +/*N*/ aCellRangeAddress.mnTableNumber = nTab; +/*N*/ String aName; +/*N*/ pDocument->GetName( nTab, aName ); +/*N*/ aCellRangeAddress.msTableName = aName; +/*N*/ aChartRange.maRanges.push_back( aCellRangeAddress ); +/*N*/ if ( aSheetNames.Len() ) +/*N*/ aSheetNames += ';'; +/*N*/ aSheetNames += aName; +/*N*/ } +/*N*/ } +/*N*/ rMem.SetChartRange( aChartRange ); +/*N*/ +/*N*/ // #90896# need that for OLE and clipboard of old binary file format +/*N*/ rMem.SomeData3() = aSheetNames; +/*N*/ +/*N*/ rMem.SetReadOnly( TRUE ); // Daten nicht im Chart per Daten-Fenster veraendern +/*N*/ } +/*N*/ +/*N*/ #ifdef _MSC_VER +/*N*/ #pragma optimize("",on) +/*N*/ #endif + + +/*N*/ const ScChartPositionMap* ScChartArray::GetPositionMap() +/*N*/ { +/*N*/ if ( !pPositionMap ) +/*N*/ CreatePositionMap(); +/*N*/ return pPositionMap; +/*N*/ } + + +/*N*/ void ScChartArray::CreatePositionMap() +/*N*/ { +/*N*/ if ( eGlue == SC_CHARTGLUE_NA && pPositionMap ) +/*N*/ { +/*?*/ delete pPositionMap; +/*?*/ pPositionMap = NULL; +/*N*/ } +/*N*/ +/*N*/ if ( pPositionMap ) +/*N*/ return ; +/*N*/ +/*N*/ USHORT nColAdd = bRowHeaders ? 1 : 0; +/*N*/ USHORT nRowAdd = bColHeaders ? 1 : 0; +/*N*/ +/*N*/ USHORT nCol, nRow, nTab, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; +/*N*/ +/*N*/ // +/*N*/ // wirkliche Groesse (ohne versteckte Zeilen/Spalten) +/*N*/ // +/*N*/ +/*N*/ USHORT nColCount, nRowCount; +/*N*/ nColCount = nRowCount = 0; +/*N*/ +/*N*/ GlueState(); +/*N*/ +/*N*/ BOOL bNoGlue = (eGlue == SC_CHARTGLUE_NONE); +/*N*/ Table* pCols = new Table; +/*N*/ Table* pNewRowTable = new Table; +/*N*/ ScAddress* pNewAddress = new ScAddress; +/*N*/ ScRangePtr pR; +/*N*/ Table* pCol; +/*N*/ ScAddress* pPos; +/*N*/ USHORT nNoGlueRow = 0; +/*N*/ for ( pR = aRangeListRef->First(); pR; pR = aRangeListRef->Next() ) +/*N*/ { +/*N*/ pR->GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); +/*N*/ for ( nTab = nTab1; nTab <= nTab2; nTab++ ) +/*N*/ { +/*N*/ // nTab im ColKey, um gleiche Col/Row in anderer Table haben zu koennen +/*N*/ ScAddress aInsCol( (bNoGlue ? 0 : nCol1), 0, nTab ); +/*N*/ for ( nCol = nCol1; nCol <= nCol2; nCol++, aInsCol.IncCol() ) +/*N*/ { +/*N*/ if ( (pDocument->GetColFlags( nCol, nTab) & CR_HIDDEN) == 0 ) +/*N*/ { +/*N*/ ULONG nInsCol = (ULONG)(UINT32) aInsCol; +/*N*/ if ( bNoGlue || eGlue == SC_CHARTGLUE_ROWS ) +/*N*/ { // meistens gleiche Cols +/*N*/ if ( !(pCol = (Table*) pCols->Get( nInsCol )) ) +/*N*/ { +/*N*/ pCols->Insert( nInsCol, pNewRowTable ); +/*N*/ pCol = pNewRowTable; +/*N*/ pNewRowTable = new Table; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { // meistens neue Cols +/*?*/ if ( pCols->Insert( nInsCol, pNewRowTable ) ) +/*?*/ { +/*?*/ pCol = pNewRowTable; +/*?*/ pNewRowTable = new Table; +/*?*/ } +/*?*/ else +/*?*/ pCol = (Table*) pCols->Get( nInsCol ); +/*N*/ } +/*N*/ // bei anderer Tabelle wurde bereits neuer ColKey erzeugt, +/*N*/ // die Zeilen muessen fuer's Dummy fuellen gleich sein! +/*N*/ ULONG nInsRow = (bNoGlue ? nNoGlueRow : nRow1); +/*N*/ for ( nRow = nRow1; nRow <= nRow2; nRow++, nInsRow++ ) +/*N*/ { +/*N*/ if ( (pDocument->GetRowFlags( nRow, nTab) & CR_HIDDEN) == 0 ) +/*N*/ { +/*N*/ if ( pCol->Insert( nInsRow, pNewAddress ) ) +/*N*/ { +/*N*/ pNewAddress->Set( nCol, nRow, nTab ); +/*N*/ pNewAddress = new ScAddress; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ // bei NoGlue werden zusammengehoerige Tabellen als ColGlue dargestellt +/*N*/ nNoGlueRow += nRow2 - nRow1 + 1; +/*N*/ } +/*N*/ delete pNewAddress; +/*N*/ delete pNewRowTable; +/*N*/ +/*N*/ // Anzahl der Daten +/*N*/ nColCount = (USHORT) pCols->Count(); +/*N*/ if ( pCol = (Table*) pCols->First() ) +/*N*/ { +/*N*/ if ( bDummyUpperLeft ) +/*?*/ pCol->Insert( 0, (void*)0 ); // Dummy fuer Beschriftung +/*N*/ nRowCount = (USHORT) pCol->Count(); +/*N*/ } +/*N*/ else +/*N*/ nRowCount = 0; +/*N*/ if ( nColCount ) +/*N*/ nColCount -= nColAdd; +/*N*/ if ( nRowCount ) +/*N*/ nRowCount -= nRowAdd; +/*N*/ +/*N*/ if ( nColCount==0 || nRowCount==0 ) +/*N*/ { // einen Eintrag ohne Daten erzeugen +/*?*/ pR = aRangeListRef->First(); +/*?*/ if ( pCols->Count() > 0 ) +/*?*/ pCol = (Table*) pCols->First(); +/*?*/ else +/*?*/ { +/*?*/ pCol = new Table; +/*?*/ pCols->Insert( 0, pCol ); +/*?*/ } +/*?*/ nColCount = 1; +/*?*/ if ( pCol->Count() > 0 ) +/*?*/ { // kann ja eigentlich nicht sein, wenn nColCount==0 || nRowCount==0 +/*?*/ pPos = (ScAddress*) pCol->First(); +/*?*/ if ( pPos ) +/*?*/ { +/*?*/ delete pPos; +/*?*/ pCol->Replace( pCol->GetCurKey(), (void*)0 ); +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ pCol->Insert( 0, (void*)0 ); +/*?*/ nRowCount = 1; +/*?*/ nColAdd = 0; +/*?*/ nRowAdd = 0; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( bNoGlue ) +/*N*/ { // Luecken mit Dummies fuellen, erste Spalte ist Master +/*?*/ Table* pFirstCol = (Table*) pCols->First(); +/*?*/ ULONG nCount = pFirstCol->Count(); +/*?*/ pFirstCol->First(); +/*?*/ for ( ULONG n = 0; n < nCount; n++, pFirstCol->Next() ) +/*?*/ { +/*?*/ ULONG nKey = pFirstCol->GetCurKey(); +/*?*/ pCols->First(); +/*?*/ while ( pCol = (Table*) pCols->Next() ) +/*?*/ pCol->Insert( nKey, (void*)0 ); // keine Daten +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ pPositionMap = new ScChartPositionMap( nColCount, nRowCount, +/*N*/ nColAdd, nRowAdd, *pCols ); +/*N*/ +/*N*/ // Aufraeumen +/*N*/ for ( pCol = (Table*) pCols->First(); pCol; pCol = (Table*) pCols->Next() ) +/*N*/ { //! nur Tables loeschen, nicht die ScAddress* +/*N*/ delete pCol; +/*N*/ } +/*N*/ delete pCols; +/*N*/ } + + +/*N*/ ScChartPositionMap::ScChartPositionMap( USHORT nChartCols, USHORT nChartRows, +/*N*/ USHORT nColAdd, USHORT nRowAdd, Table& rCols ) : +/*N*/ nCount( (ULONG) nChartCols * nChartRows ), +/*N*/ nColCount( nChartCols ), +/*N*/ nRowCount( nChartRows ), +/*N*/ ppData( new ScAddress* [ nChartCols * nChartRows ] ), +/*N*/ ppColHeader( new ScAddress* [ nChartCols ] ), +/*N*/ ppRowHeader( new ScAddress* [ nChartRows ] ) +/*N*/ { +/*N*/ DBG_ASSERT( nColCount && nRowCount, "ScChartPositionMap without dimension" ); +/*N*/ #ifdef WIN +/*N*/ #error ScChartPositionMap not implemented for 16-bit dumdums +/*N*/ #endif +/*N*/ +/*N*/ ScAddress* pPos; +/*N*/ USHORT nCol, nRow; +/*N*/ +/*N*/ Table* pCol = (Table*) rCols.First(); +/*N*/ +/*N*/ // Zeilen-Header +/*N*/ pPos = (ScAddress*) pCol->First(); +/*N*/ if ( nRowAdd ) +/*N*/ pPos = (ScAddress*) pCol->Next(); +/*N*/ if ( nColAdd ) +/*N*/ { // eigenstaendig +/*N*/ for ( nRow = 0; nRow < nRowCount; nRow++ ) +/*N*/ { +/*N*/ ppRowHeader[ nRow ] = pPos; +/*N*/ pPos = (ScAddress*) pCol->Next(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { // Kopie +/*?*/ for ( nRow = 0; nRow < nRowCount; nRow++ ) +/*?*/ { +/*?*/ ppRowHeader[ nRow ] = ( pPos ? new ScAddress( *pPos ) : NULL ); +/*?*/ pPos = (ScAddress*) pCol->Next(); +/*?*/ } +/*N*/ } +/*N*/ if ( nColAdd ) +/*N*/ pCol = (Table*) rCols.Next(); +/*N*/ +/*N*/ // Daten spaltenweise und Spalten-Header +/*N*/ ULONG nIndex = 0; +/*N*/ for ( nCol = 0; nCol < nColCount; nCol++ ) +/*N*/ { +/*N*/ if ( pCol ) +/*N*/ { +/*N*/ pPos = (ScAddress*) pCol->First(); +/*N*/ if ( nRowAdd ) +/*N*/ { +/*N*/ ppColHeader[ nCol ] = pPos; // eigenstaendig +/*N*/ pPos = (ScAddress*) pCol->Next(); +/*N*/ } +/*N*/ else +/*?*/ ppColHeader[ nCol ] = ( pPos ? new ScAddress( *pPos ) : NULL ); +/*N*/ for ( USHORT nRow = 0; nRow < nRowCount; nRow++, nIndex++ ) +/*N*/ { +/*N*/ ppData[ nIndex ] = pPos; +/*N*/ pPos = (ScAddress*) pCol->Next(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ ppColHeader[ nCol ] = NULL; +/*?*/ for ( nRow = 0; nRow < nRowCount; nRow++, nIndex++ ) +/*?*/ { +/*?*/ ppData[ nIndex ] = NULL; +/*?*/ } +/*N*/ } +/*N*/ pCol = (Table*) rCols.Next(); +/*N*/ } +/*N*/ } + + +/*N*/ ScChartPositionMap::~ScChartPositionMap() +/*N*/ { +/*N*/ for ( ULONG nIndex=0; nIndex < nCount; nIndex++ ) +/*N*/ { +/*N*/ delete ppData[nIndex]; +/*N*/ } +/*N*/ delete [] ppData; +/*N*/ +/*N*/ USHORT j; +/*N*/ for ( j=0; j < nColCount; j++ ) +/*N*/ { +/*N*/ delete ppColHeader[j]; +/*N*/ } +/*N*/ delete [] ppColHeader; +/*N*/ for ( j=0; j < nRowCount; j++ ) +/*N*/ { +/*N*/ delete ppRowHeader[j]; +/*N*/ } +/*N*/ delete [] ppRowHeader; +/*N*/ } + + + + + + +// +// Collection +// + + + +/*N*/ BOOL ScChartCollection::Load( ScDocument* pDoc, SvStream& rStream ) +/*N*/ { +/*N*/ BOOL bSuccess = TRUE; +/*N*/ USHORT nNewCount; +/*N*/ FreeAll(); +/*N*/ +/*N*/ ScMultipleReadHeader aHdr( rStream ); +/*N*/ +/*N*/ rStream >> nNewCount; +/*N*/ +/*N*/ for (USHORT i=0; i<nNewCount && bSuccess; i++) +/*N*/ { +/*?*/ ScChartArray* pObject = new ScChartArray( pDoc, rStream, aHdr ); +/*?*/ bSuccess = Insert( pObject ); +/*N*/ } +/*N*/ return bSuccess; +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_chartlis.cxx b/binfilter/bf_sc/source/core/tool/sc_chartlis.cxx new file mode 100644 index 000000000000..d26ff12480b1 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_chartlis.cxx @@ -0,0 +1,354 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <vcl/svapp.hxx> + +#include "chartlis.hxx" +#include "document.hxx" +#include <tools/debug.hxx> +namespace binfilter { + +using namespace ::com::sun::star; + + +//2do: DocOption TimeOut? +#define SC_CHARTTIMEOUT 1000 // eine Sekunde keine Aenderung/KeyEvent + + +// ==================================================================== + +/*N*/ class ScChartUnoData +/*N*/ { +/*N*/ uno::Reference< chart::XChartDataChangeEventListener > xListener; +/*N*/ uno::Reference< chart::XChartData > xSource; +/*N*/ +/*N*/ public: +/*N*/ ScChartUnoData( const uno::Reference< chart::XChartDataChangeEventListener >& rL, +/*N*/ const uno::Reference< chart::XChartData >& rS ) : +/*N*/ xListener( rL ), xSource( rS ) {} +/*N*/ ~ScChartUnoData() {} +/*N*/ +/*N*/ const uno::Reference< chart::XChartDataChangeEventListener >& GetListener() const { return xListener; } +/*N*/ const uno::Reference< chart::XChartData >& GetSource() const { return xSource; } +/*N*/ }; + + +// === ScChartListener ================================================ + +/*N*/ ScChartListener::ScChartListener( const String& rName, ScDocument* pDocP, +/*N*/ const ScRange& rRange ) : +/*N*/ StrData( rName ), +/*N*/ pDoc( pDocP ), +/*N*/ pUnoData( NULL ), +/*N*/ bUsed( FALSE ), +/*N*/ bDirty( FALSE ), +/*N*/ bSeriesRangesScheduled( FALSE ) +/*N*/ { +/*N*/ SetRangeList( rRange ); +/*N*/ } + +/*N*/ ScChartListener::ScChartListener( const String& rName, ScDocument* pDocP, +/*N*/ const ScRangeListRef& rRangeList ) : +/*N*/ StrData( rName ), +/*N*/ aRangeListRef( rRangeList ), +/*N*/ pDoc( pDocP ), +/*N*/ pUnoData( NULL ), +/*N*/ bUsed( FALSE ), +/*N*/ bDirty( FALSE ), +/*N*/ bSeriesRangesScheduled( FALSE ) +/*N*/ { +/*N*/ } + +/*N*/ ScChartListener::ScChartListener( const ScChartListener& r ) : +/*N*/ StrData( r ), +/*N*/ pDoc( r.pDoc ), +/*N*/ pUnoData( NULL ), +/*N*/ bUsed( FALSE ), +/*N*/ bDirty( r.bDirty ), +/*N*/ bSeriesRangesScheduled( r.bSeriesRangesScheduled ) +/*N*/ { +/*N*/ if ( r.pUnoData ) +/*N*/ pUnoData = new ScChartUnoData( *r.pUnoData ); +/*N*/ if ( r.aRangeListRef.Is() ) +/*N*/ aRangeListRef = new ScRangeList( *r.aRangeListRef ); +/*N*/ } + +/*N*/ ScChartListener::~ScChartListener() +/*N*/ { +/*N*/ if ( GetBroadcasterCount() ) +/*N*/ EndListeningTo(); +/*N*/ delete pUnoData; +/*N*/ } + +/*N*/ DataObject* ScChartListener::Clone() const +/*N*/ { + DBG_BF_ASSERT(0, "STRIP");return NULL; //STRIP001 return new ScChartListener( *this ); +/*N*/ } + +/*N*/ void ScChartListener::SetUno( +/*N*/ const uno::Reference< chart::XChartDataChangeEventListener >& rListener, +/*N*/ const uno::Reference< chart::XChartData >& rSource ) +/*N*/ { +/*N*/ // DBG_ASSERT( rListener.is() && rSource.is(), "Nullpointer bei SetUno" ); +/*N*/ delete pUnoData; +/*N*/ pUnoData = new ScChartUnoData( rListener, rSource ); +/*N*/ } + +/*N*/ uno::Reference< chart::XChartDataChangeEventListener > ScChartListener::GetUnoListener() const +/*N*/ { +/*N*/ if ( pUnoData ) +/*N*/ return pUnoData->GetListener(); +/*N*/ return uno::Reference< chart::XChartDataChangeEventListener >(); +/*N*/ } + +/*N*/ uno::Reference< chart::XChartData > ScChartListener::GetUnoSource() const +/*N*/ { +/*N*/ if ( pUnoData ) +/*N*/ return pUnoData->GetSource(); +/*N*/ return uno::Reference< chart::XChartData >(); +/*N*/ } + +/*N*/ void __EXPORT ScChartListener::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) +/*N*/ { +/*N*/ const ScHint* p = PTR_CAST( ScHint, &rHint ); +/*N*/ if( p && (p->GetId() & (SC_HINT_DATACHANGED | SC_HINT_DYING)) ) +/*N*/ { +/*N*/ bDirty = TRUE; +/*N*/ pDoc->GetChartListenerCollection()->StartTimer(); +/*N*/ } +/*N*/ } + +/*N*/ void ScChartListener::Update() +/*N*/ { +/*N*/ if ( pDoc->IsInInterpreter() ) +/*N*/ { // #73482# If interpreting do nothing and restart timer so we don't +/*?*/ // interfere with interpreter and don't produce an Err522 or similar. +/*?*/ // This may happen if we are rescheduled via Basic function. +/*?*/ pDoc->GetChartListenerCollection()->StartTimer(); +/*?*/ return ; +/*N*/ } +/*N*/ if ( pUnoData ) +/*N*/ { +/*?*/ bDirty = FALSE; +/*?*/ //! irgendwann mal erkennen, was sich innerhalb des Charts geaendert hat +/*?*/ chart::ChartDataChangeEvent aEvent( pUnoData->GetSource(), +/*?*/ chart::ChartDataChangeType_ALL, +/*?*/ 0, 0, 0, 0 ); +/*?*/ pUnoData->GetListener()->chartDataChanged( aEvent ); +/*N*/ } +/*N*/ else if ( pDoc->GetAutoCalc() ) +/*N*/ { +/*N*/ bDirty = FALSE; +/*N*/ pDoc->UpdateChart( GetString(), NULL ); +/*N*/ } +/*N*/ } + +/*N*/ void ScChartListener::StartListeningTo() +/*N*/ { +/*N*/ if ( aRangeListRef.Is() ) +/*N*/ for ( ScRangePtr pR = aRangeListRef->First(); pR; +/*N*/ pR = aRangeListRef->Next() ) +/*N*/ { +/*N*/ if ( pR->aStart == pR->aEnd ) +/*?*/ pDoc->StartListeningCell( pR->aStart, this ); +/*N*/ else +/*N*/ pDoc->StartListeningArea( *pR, this ); +/*N*/ } +/*N*/ } + +/*N*/ void ScChartListener::EndListeningTo() +/*N*/ { +/*N*/ if ( aRangeListRef.Is() ) +/*N*/ for ( ScRangePtr pR = aRangeListRef->First(); pR; +/*N*/ pR = aRangeListRef->Next() ) +/*N*/ { +/*N*/ if ( pR->aStart == pR->aEnd ) +/*?*/ pDoc->EndListeningCell( pR->aStart, this ); +/*N*/ else +/*N*/ pDoc->EndListeningArea( *pR, this ); +/*N*/ } +/*N*/ } + + +/*N*/ void ScChartListener::SetRangeList( const ScRange& rRange ) +/*N*/ { +/*N*/ aRangeListRef = new ScRangeList; +/*N*/ aRangeListRef->Append( rRange ); +/*N*/ } + + + + + + + + + + +// === ScChartListenerCollection ====================================== + +/*N*/ ScChartListenerCollection::ScChartListenerCollection( ScDocument* pDocP ) : +/*N*/ StrCollection( 4, 4, FALSE ), +/*N*/ pDoc( pDocP ) +/*N*/ { +/*N*/ aTimer.SetTimeoutHdl( LINK( this, ScChartListenerCollection, TimerHdl ) ); +/*N*/ } + + +/*N*/ ScChartListenerCollection::~ScChartListenerCollection() +/*N*/ { +/*N*/ // #96783# remove ChartListener objects before aTimer dtor is called, because +/*N*/ // ScChartListener::EndListeningTo may cause ScChartListenerCollection::StartTimer +/*N*/ // to be called if an empty ScNoteCell is deleted +/*N*/ +/*N*/ if (GetCount()) +/*N*/ FreeAll(); +/*N*/ } + +/*N*/ DataObject* ScChartListenerCollection::Clone() const +/*N*/ { + DBG_BF_ASSERT(0, "STRIP");return NULL;//STRIP001 return new ScChartListenerCollection( *this ); +/*N*/ } + + +/*N*/ void ScChartListenerCollection::ChangeListening( const String& rName, +/*N*/ const ScRangeListRef& rRangeListRef, BOOL bDirty ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 ScChartListener aCLSearcher( rName, pDoc, rRangeListRef ); +/*N*/ } + +/*N*/ void ScChartListenerCollection::FreeUnused() +/*N*/ { +/*N*/ // rueckwaerts wg. Pointer-Aufrueckerei im Array +/*N*/ for ( USHORT nIndex = nCount; nIndex-- >0; ) +/*N*/ { +/*N*/ ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ]; +/*N*/ // Uno-Charts nicht rauskicken +/*N*/ // (werden per FreeUno von aussen geloescht) +/*N*/ if ( !pCL->IsUno() ) +/*N*/ { +/*N*/ if ( pCL->IsUsed() ) +/*N*/ pCL->SetUsed( FALSE ); +/*N*/ else +/*?*/ Free( pCL ); +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void ScChartListenerCollection::FreeUno( const uno::Reference< chart::XChartDataChangeEventListener >& rListener, +/*N*/ const uno::Reference< chart::XChartData >& rSource ) +/*N*/ { +/*N*/ // rueckwaerts wg. Pointer-Aufrueckerei im Array +/*N*/ for ( USHORT nIndex = nCount; nIndex-- >0; ) +/*N*/ { +/*N*/ ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ]; +/*N*/ if ( pCL->IsUno() && +/*N*/ pCL->GetUnoListener() == rListener && +/*N*/ pCL->GetUnoSource() == rSource ) +/*N*/ { +/*N*/ Free( pCL ); +/*N*/ } +/*N*/ //! sollte nur einmal vorkommen? +/*N*/ } +/*N*/ } + +/*N*/ void ScChartListenerCollection::StartTimer() +/*N*/ { +/*N*/ aTimer.SetTimeout( SC_CHARTTIMEOUT ); +/*N*/ aTimer.Start(); +/*N*/ } + +/*N*/ IMPL_LINK( ScChartListenerCollection, TimerHdl, Timer*, pTimer ) +/*N*/ { +/*N*/ if ( Application::AnyInput( INPUT_KEYBOARD ) ) +/*N*/ { +/*?*/ aTimer.Start(); +/*?*/ return 0; +/*N*/ } +/*N*/ UpdateDirtyCharts(); +/*N*/ return 0; +/*N*/ } + +/*N*/ void ScChartListenerCollection::UpdateDirtyCharts() +/*N*/ { +/*N*/ for ( USHORT nIndex = 0; nIndex < nCount; nIndex++ ) +/*N*/ { +/*N*/ ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ]; +/*N*/ if ( pCL->IsDirty() ) +/*N*/ pCL->Update(); +/*N*/ if ( aTimer.IsActive() && !pDoc->IsImportingXML()) +/*N*/ break; // da kam einer dazwischen +/*N*/ } +/*N*/ } + + +/*N*/ void ScChartListenerCollection::SetDirty() +/*N*/ { +/*N*/ for ( USHORT nIndex = 0; nIndex < nCount; nIndex++ ) +/*N*/ { +/*?*/ ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ]; +/*?*/ pCL->SetDirty( TRUE ); +/*N*/ } +/*N*/ StartTimer(); +/*N*/ } + + + + + + +/*N*/ void ScChartListenerCollection::UpdateScheduledSeriesRanges() +/*N*/ { +/*N*/ for ( USHORT nIndex = 0; nIndex < nCount; nIndex++ ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ]; +/*N*/ } +/*N*/ } + + +/*N*/ void ScChartListenerCollection::UpdateSeriesRangesContainingTab( USHORT nTab ) +/*N*/ { +/*N*/ ScRange aRange( 0, 0, nTab, MAXCOL, MAXROW, nTab ); +/*N*/ for ( USHORT nIndex = 0; nIndex < nCount; nIndex++ ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ]; +/*N*/ } +/*N*/ } + + + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_chgtrack.cxx b/binfilter/bf_sc/source/core/tool/sc_chgtrack.cxx new file mode 100644 index 000000000000..512852a0c954 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_chgtrack.cxx @@ -0,0 +1,3853 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <bf_svtools/zforlist.hxx> +#include <bf_svtools/isethint.hxx> +#include <bf_svtools/itempool.hxx> +#include <bf_sfx2/app.hxx> +#include <bf_svtools/useroptions.hxx> +#include <bf_sfx2/sfxsids.hrc> +#include <bf_svx/adritem.hxx> + +#include "cell.hxx" +#include "dociter.hxx" +#include "rechead.hxx" +#include "scerrors.hxx" +#include "scmod.hxx" // SC_MOD +#include "inputopt.hxx" // GetExpandRefs +#include "patattr.hxx" +#include "hints.hxx" + +#include "globstr.hrc" + +#define SC_CHGTRACK_CXX +#include "chgtrack.hxx" + +#include "refupdat.hxx" + +namespace binfilter { + +/*N*/ DECLARE_STACK( ScChangeActionStack, ScChangeAction* ) + +const USHORT nMemPoolChangeActionCellListEntry = (0x2000 - 64) / sizeof(ScChangeActionCellListEntry); +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( ScChangeActionCellListEntry, nMemPoolChangeActionCellListEntry, nMemPoolChangeActionCellListEntry )//STRIP008 ; + +const USHORT nMemPoolChangeActionLinkEntry = (0x8000 - 64) / sizeof(ScChangeActionLinkEntry); +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( ScChangeActionLinkEntry, nMemPoolChangeActionLinkEntry, nMemPoolChangeActionLinkEntry )//STRIP008 ; + +// loaded MSB > eigenes => inkompatibel +#define SC_CHGTRACK_FILEFORMAT_FIRST 0x0001 +#define SC_CHGTRACK_FILEFORMAT 0x0001 + +// --- ScChangeAction ------------------------------------------------------ + +/*N*/ ScChangeAction::ScChangeAction( ScChangeActionType eTypeP, const ScRange& rRange ) +/*N*/ : +/*N*/ aBigRange( rRange ), +/*N*/ pNext( NULL ), +/*N*/ pPrev( NULL ), +/*N*/ pLinkAny( NULL ), +/*N*/ pLinkDeletedIn( NULL ), +/*N*/ pLinkDeleted( NULL ), +/*N*/ pLinkDependent( NULL ), +/*N*/ nAction( 0 ), +/*N*/ nRejectAction( 0 ), +/*N*/ eType( eTypeP ), +/*N*/ eState( SC_CAS_VIRGIN ) +/*N*/ { +/*N*/ aDateTime.ConvertToUTC(); +/*N*/ } + +/*N*/ ScChangeAction::ScChangeAction( ScChangeActionType eTypeP, const ScBigRange& rRange, +/*N*/ const ULONG nTempAction, const ULONG nTempRejectAction, +/*N*/ const ScChangeActionState eTempState, const DateTime& aTempDateTime, +/*N*/ const String& aTempUser, const String& aTempComment) +/*N*/ : +/*N*/ aBigRange( rRange ), +/*N*/ pNext( NULL ), +/*N*/ pPrev( NULL ), +/*N*/ pLinkAny( NULL ), +/*N*/ pLinkDeletedIn( NULL ), +/*N*/ pLinkDeleted( NULL ), +/*N*/ pLinkDependent( NULL ), +/*N*/ nAction( nTempAction ), +/*N*/ nRejectAction( nTempRejectAction ), +/*N*/ eType( eTypeP ), +/*N*/ eState( eTempState ), +/*N*/ aDateTime( aTempDateTime ), +/*N*/ aUser( aTempUser ), +/*N*/ aComment( aTempComment ) +/*N*/ { +/*N*/ } + +/*N*/ ScChangeAction::ScChangeAction( ScChangeActionType eTypeP, const ScBigRange& rRange, +/*N*/ const ULONG nTempAction) +/*N*/ : +/*N*/ aBigRange( rRange ), +/*N*/ pNext( NULL ), +/*N*/ pPrev( NULL ), +/*N*/ pLinkAny( NULL ), +/*N*/ pLinkDeletedIn( NULL ), +/*N*/ pLinkDeleted( NULL ), +/*N*/ pLinkDependent( NULL ), +/*N*/ nAction( nTempAction ), +/*N*/ nRejectAction( 0 ), +/*N*/ eType( eTypeP ), +/*N*/ eState( SC_CAS_VIRGIN ) +/*N*/ { +/*N*/ aDateTime.ConvertToUTC(); +/*N*/ } + +/*N*/ ScChangeAction::ScChangeAction( SvStream& rStrm, ScMultipleReadHeader& rHdr, +/*N*/ ScChangeTrack* pTrack ) +/*N*/ : +/*N*/ pNext( NULL ), +/*N*/ pPrev( NULL ), +/*N*/ pLinkAny( NULL ), +/*N*/ pLinkDeletedIn( NULL ), +/*N*/ pLinkDeleted( NULL ), +/*N*/ pLinkDependent( NULL ) +/*N*/ { +/*N*/ // ScChangeTrack speichert aUser als Index auf Collection und eType selber +/*N*/ UINT32 n32; +/*N*/ UINT16 n16; +/*N*/ rStrm >> aBigRange; +/*N*/ rStrm >> n32; aDateTime.SetDate( n32 ); +/*N*/ rStrm >> n32; aDateTime.SetTime( n32 ); +/*N*/ rStrm >> n32; nAction = n32; +/*N*/ rStrm >> n32; nRejectAction = n32; +/*N*/ rStrm >> n16; eState = (ScChangeActionState) n16; +/*N*/ rStrm.ReadByteString( aComment, rStrm.GetStreamCharSet() ); +/*N*/ // LinkEntries in zweiter Runde +/*N*/ } + + +/*N*/ ScChangeAction::~ScChangeAction() +/*N*/ { +/*N*/ RemoveAllLinks(); +/*N*/ } + + +/*N*/ BOOL ScChangeAction::Store( SvStream& rStrm, ScMultipleWriteHeader& rHdr ) const +/*N*/ { +/*N*/ // ScChangeTrack speichert aUser als Index auf Collection und eType selber +/*N*/ rStrm << aBigRange; +/*N*/ rStrm << (UINT32) aDateTime.GetDate(); +/*N*/ rStrm << (UINT32) aDateTime.GetTime(); +/*N*/ rStrm << (UINT32) nAction; +/*N*/ rStrm << (UINT32) nRejectAction; +/*N*/ rStrm << (UINT16) eState; +/*N*/ rStrm.WriteByteString( aComment, rStrm.GetStreamCharSet() ); +/*N*/ // LinkEntries in zweiter Runde +/*N*/ +/*N*/ return TRUE; +/*N*/ } + + +/*N*/ BOOL ScChangeAction::StoreLinks( SvStream& rStrm ) const +/*N*/ { +/*N*/ BOOL bOk = ScChangeAction::StoreLinkChain( pLinkDeleted, rStrm ); +/*N*/ bOk &= ScChangeAction::StoreLinkChain( pLinkDependent, rStrm ); +/*N*/ return bOk; +/*N*/ } + + +/*N*/ BOOL ScChangeAction::LoadLinks( SvStream& rStrm, ScChangeTrack* pTrack ) // Changetracking.sdc +/*N*/ { +/*N*/ BOOL bOk = ScChangeAction::LoadLinkChain( this, &pLinkDeleted, rStrm, +/*N*/ pTrack, TRUE ); +/*N*/ bOk &= ScChangeAction::LoadLinkChain( this, &pLinkDependent, rStrm, +/*N*/ pTrack, FALSE ); +/*N*/ return bOk; +/*N*/ } + + +/*N*/ BOOL ScChangeAction::IsTouchable() const +/*N*/ { +/*N*/ //! sequence order of execution is significant +/*N*/ if ( IsRejected() || GetType() == SC_CAT_REJECT || IsDeletedIn() ) +/*N*/ return FALSE; +/*N*/ // content may reject and be touchable if on top +/*N*/ if ( GetType() == SC_CAT_CONTENT ) +/*N*/ return ((ScChangeActionContent*)this)->IsTopContent(); +/*N*/ if ( IsRejecting() ) +/*N*/ return FALSE; +/*N*/ return TRUE; +/*N*/ } + +/*N*/ BOOL ScChangeAction::IsInternalRejectable() const +/*N*/ { +/*N*/ //! sequence order of execution is significant +/*N*/ if ( !IsVirgin() ) +/*N*/ return FALSE; +/*N*/ if ( IsDeletedIn() ) +/*N*/ return FALSE; +/*N*/ if ( GetType() == SC_CAT_CONTENT ) +/*N*/ { +/*N*/ ScChangeActionContent* pNextContent = +/*N*/ ((ScChangeActionContent*)this)->GetNextContent(); +/*N*/ if ( pNextContent == NULL ) +/*N*/ return TRUE; // *this is TopContent +/*N*/ return pNextContent->IsRejected(); // *this is next rejectable +/*N*/ } +/*N*/ return IsTouchable(); +/*N*/ } + + +/*N*/ void ScChangeAction::RemoveAllLinks() +/*N*/ { +/*N*/ RemoveAllAnyLinks(); +/*N*/ RemoveAllDeletedIn(); +/*N*/ RemoveAllDeleted(); +/*N*/ RemoveAllDependent(); +/*N*/ } + + +/*N*/ void ScChangeAction::RemoveAllAnyLinks() +/*N*/ { +/*N*/ while ( pLinkAny ) +/*N*/ delete pLinkAny; // rueckt sich selbst hoch +/*N*/ } + + +/*N*/ BOOL ScChangeAction::RemoveDeletedIn( const ScChangeAction* p ) +/*N*/ { +/*N*/ BOOL bRemoved = FALSE; +/*N*/ ScChangeActionLinkEntry* pL = GetDeletedIn(); +/*N*/ while ( pL ) +/*N*/ { +/*N*/ ScChangeActionLinkEntry* pNextLink = pL->GetNext(); +/*N*/ if ( pL->GetAction() == p ) +/*N*/ { +/*N*/ delete pL; +/*N*/ bRemoved = TRUE; +/*N*/ } +/*N*/ pL = pNextLink; +/*N*/ } +/*N*/ return bRemoved; +/*N*/ } + + +/*N*/ BOOL ScChangeAction::IsDeletedIn( const ScChangeAction* p ) const +/*N*/ { +/*N*/ ScChangeActionLinkEntry* pL = GetDeletedIn(); +/*N*/ while ( pL ) +/*N*/ { +/*N*/ if ( pL->GetAction() == p ) +/*N*/ return TRUE; +/*N*/ pL = pL->GetNext(); +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + + +/*N*/ void ScChangeAction::RemoveAllDeletedIn() +/*N*/ { +/*N*/ //! nicht vom evtl. TopContent sondern wirklich dieser +/*N*/ while ( pLinkDeletedIn ) +/*N*/ delete pLinkDeletedIn; // rueckt sich selbst hoch +/*N*/ } + + +/*N*/ BOOL ScChangeAction::IsDeletedInDelType( ScChangeActionType eDelType ) const +/*N*/ { +/*N*/ ScChangeAction* p; +/*N*/ ScChangeActionLinkEntry* pL = GetDeletedIn(); +/*N*/ if ( pL ) +/*N*/ { +/*N*/ // InsertType fuer MergePrepare/MergeOwn +/*N*/ ScChangeActionType eInsType; +/*N*/ switch ( eDelType ) +/*N*/ { +/*N*/ case SC_CAT_DELETE_COLS : +/*N*/ eInsType = SC_CAT_INSERT_COLS; +/*N*/ break; +/*N*/ case SC_CAT_DELETE_ROWS : +/*N*/ eInsType = SC_CAT_INSERT_ROWS; +/*N*/ break; +/*N*/ case SC_CAT_DELETE_TABS : +/*N*/ eInsType = SC_CAT_INSERT_TABS; +/*N*/ break; +/*N*/ default: +/*N*/ eInsType = SC_CAT_NONE; +/*N*/ } +/*N*/ while ( pL ) +/*N*/ { +/*N*/ if ( (p = pL->GetAction()) && +/*N*/ (p->GetType() == eDelType || p->GetType() == eInsType) ) +/*N*/ return TRUE; +/*N*/ pL = pL->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + + +/*N*/ void ScChangeAction::SetDeletedIn( ScChangeAction* p ) // Changetracking.sdc +/*N*/ { +/*N*/ ScChangeActionLinkEntry* pLink1 = AddDeletedIn( p ); +/*N*/ ScChangeActionLinkEntry* pLink2; +/*N*/ if ( GetType() == SC_CAT_CONTENT ) +/*N*/ pLink2 = p->AddDeleted( ((ScChangeActionContent*)this)->GetTopContent() ); +/*N*/ else +/*N*/ pLink2 = p->AddDeleted( this ); +/*N*/ pLink1->SetLink( pLink2 ); +/*N*/ } + + +/*N*/ void ScChangeAction::RemoveAllDeleted() +/*N*/ { +/*N*/ while ( pLinkDeleted ) +/*N*/ delete pLinkDeleted; // rueckt sich selbst hoch +/*N*/ } + + +/*N*/ void ScChangeAction::RemoveAllDependent() +/*N*/ { +/*N*/ while ( pLinkDependent ) +/*N*/ delete pLinkDependent; // rueckt sich selbst hoch +/*N*/ } + + +/*N*/ void ScChangeAction::UpdateReference( const ScChangeTrack* pTrack, +/*N*/ UpdateRefMode eMode, const ScBigRange& rRange, +/*N*/ INT32 nDx, INT32 nDy, INT32 nDz ) +/*N*/ { +/*N*/ ScRefUpdate::Update( eMode, rRange, nDx, nDy, nDz, GetBigRange() ); +/*N*/ } + + +/*N*/ String ScChangeAction::GetRefString( const ScBigRange& rRange, +/*N*/ ScDocument* pDoc, BOOL bFlag3D ) const +/*N*/ { +/*N*/ String aStr; +/*N*/ USHORT nFlags = ( rRange.IsValid( pDoc ) ? SCA_VALID : 0 ); +/*N*/ if ( !nFlags ) +/*N*/ aStr = ScGlobal::GetRscString( STR_NOREF_STR ); +/*N*/ else +/*N*/ { +/*N*/ ScRange aTmpRange( rRange.MakeRange() ); +/*N*/ switch ( GetType() ) +/*N*/ { +/*N*/ case SC_CAT_INSERT_COLS : +/*N*/ case SC_CAT_DELETE_COLS : +/*N*/ if ( bFlag3D ) +/*N*/ { +/*N*/ pDoc->GetName( aTmpRange.aStart.Tab(), aStr ); +/*N*/ aStr += '.'; +/*N*/ } +/*N*/ aStr += binfilter::ColToAlpha( aTmpRange.aStart.Col() ); +/*N*/ aStr += ':'; +/*N*/ aStr += binfilter::ColToAlpha( aTmpRange.aEnd.Col() ); +/*N*/ break; +/*N*/ case SC_CAT_INSERT_ROWS : +/*N*/ case SC_CAT_DELETE_ROWS : +/*N*/ if ( bFlag3D ) +/*N*/ { +/*N*/ pDoc->GetName( aTmpRange.aStart.Tab(), aStr ); +/*N*/ aStr += '.'; +/*N*/ } +/*N*/ aStr += String::CreateFromInt32( aTmpRange.aStart.Row() + 1 ); +/*N*/ aStr += ':'; +/*N*/ aStr += String::CreateFromInt32( aTmpRange.aEnd.Row() + 1 ); +/*N*/ break; +/*N*/ default: +/*N*/ if ( bFlag3D || GetType() == SC_CAT_INSERT_TABS ) +/*N*/ nFlags |= SCA_TAB_3D; +/*N*/ aTmpRange.Format( aStr, nFlags, pDoc ); +/*N*/ } +/*N*/ if ( (bFlag3D && IsDeleteType()) || IsDeletedIn() ) +/*N*/ { +/*N*/ aStr.Insert( '(', 0 ); +/*N*/ aStr += ')'; +/*N*/ } +/*N*/ } +/*N*/ return aStr; +/*N*/ } + + +/*N*/ void ScChangeAction::GetRefString( String& rStr, ScDocument* pDoc, +/*N*/ BOOL bFlag3D ) const +/*N*/ { +/*N*/ rStr = GetRefString( GetBigRange(), pDoc, bFlag3D ); +/*N*/ } + + +/*N*/ void ScChangeAction::Accept() +/*N*/ { +/*N*/ if ( IsVirgin() ) +/*N*/ { +/*N*/ SetState( SC_CAS_ACCEPTED ); +/*N*/ DeleteCellEntries(); +/*N*/ } +/*N*/ } + + +/*N*/ void ScChangeAction::SetRejected() +/*N*/ { +/*N*/ if ( IsVirgin() ) +/*N*/ { +/*N*/ SetState( SC_CAS_REJECTED ); +/*N*/ RemoveAllLinks(); +/*N*/ DeleteCellEntries(); +/*N*/ } +/*N*/ } + + +/*N*/ void ScChangeAction::RejectRestoreContents( ScChangeTrack* pTrack, +/*N*/ short nDx, short nDy ) +/*N*/ { +/*N*/ // Liste der Contents aufbauen +/*N*/ ScChangeActionCellListEntry* pListContents = NULL; +/*N*/ for ( ScChangeActionLinkEntry* pL = pLinkDeleted; pL; pL = pL->GetNext() ) +/*N*/ { +/*N*/ ScChangeAction* p = pL->GetAction(); +/*N*/ if ( p && p->GetType() == SC_CAT_CONTENT ) +/*N*/ { +/*N*/ ScChangeActionCellListEntry* pE = new ScChangeActionCellListEntry( +/*N*/ (ScChangeActionContent*) p, pListContents ); +/*N*/ pListContents = pE; +/*N*/ } +/*N*/ } +/*N*/ SetState( SC_CAS_REJECTED ); // vor UpdateReference fuer Move +/*N*/ pTrack->UpdateReference( this, TRUE ); // LinkDeleted freigeben +/*N*/ DBG_ASSERT( !pLinkDeleted, "ScChangeAction::RejectRestoreContents: pLinkDeleted != NULL" ); +/*N*/ // Liste der Contents abarbeiten und loeschen +/*N*/ ScDocument* pDoc = pTrack->GetDocument(); +/*N*/ ScChangeActionCellListEntry* pE = pListContents; +/*N*/ while ( pE ) +/*N*/ { +/*N*/ if ( !pE->pContent->IsDeletedIn() && +/*N*/ pE->pContent->GetBigRange().aStart.IsValid( pDoc ) ) +/*N*/ pE->pContent->PutNewValueToDoc( pDoc, nDx, nDy ); +/*N*/ ScChangeActionCellListEntry* pNext; +/*N*/ pNext = pE->pNext; +/*N*/ delete pE; +/*N*/ pE = pNext; +/*N*/ } +/*N*/ DeleteCellEntries(); // weg mit den generierten +/*N*/ } + + +// static +/*N*/ void ScChangeAction::StoreCell( ScBaseCell* pCell, SvStream& rStrm, +/*N*/ ScMultipleWriteHeader& rHdr ) +/*N*/ { +/*N*/ if ( pCell ) +/*N*/ { +/*N*/ CellType eCellType = pCell->GetCellType(); +/*N*/ switch( eCellType ) +/*N*/ { +/*N*/ case CELLTYPE_VALUE: +/*N*/ rStrm << (BYTE) eCellType; +/*N*/ ((ScValueCell*)pCell)->Save( rStrm ); +/*N*/ break; +/*N*/ case CELLTYPE_STRING: +/*N*/ rStrm << (BYTE) eCellType; +/*N*/ ((ScStringCell*)pCell)->Save( rStrm ); +/*N*/ break; +/*N*/ case CELLTYPE_EDIT: +/*N*/ rStrm << (BYTE) eCellType; +/*N*/ ((ScEditCell*)pCell)->Save( rStrm ); +/*N*/ break; +/*N*/ case CELLTYPE_FORMULA: +/*N*/ rStrm << (BYTE) eCellType; +/*N*/ rStrm << ((ScFormulaCell*)pCell)->aPos; +/*N*/ ((ScFormulaCell*)pCell)->Save( rStrm, rHdr ); +/*N*/ break; +/*N*/ default: +/*N*/ DBG_ERROR( "ScChangeAction::StoreCell: unknown CellType" ); +/*N*/ rStrm << (BYTE) CELLTYPE_NONE; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ rStrm << (BYTE) CELLTYPE_NONE; +/*N*/ } + + +// static +/*N*/ ScBaseCell* ScChangeAction::LoadCell( SvStream& rStrm, +/*N*/ ScMultipleReadHeader& rHdr, ScDocument* pDoc, USHORT nVer ) +/*N*/ { +/*N*/ ScBaseCell* pCell; +/*N*/ BYTE nByte; +/*N*/ rStrm >> nByte; +/*N*/ switch ( (CellType) nByte ) +/*N*/ { +/*N*/ case CELLTYPE_VALUE: +/*N*/ { +/*N*/ pCell = new ScValueCell( rStrm, nVer ); +/*N*/ } +/*N*/ break; +/*N*/ case CELLTYPE_STRING: +/*N*/ { +/*N*/ pCell = new ScStringCell( rStrm, nVer ); +/*N*/ } +/*N*/ break; +/*N*/ case CELLTYPE_EDIT: +/*N*/ { +/*N*/ pCell = new ScEditCell( rStrm, nVer, pDoc ); +/*N*/ } +/*N*/ break; +/*N*/ case CELLTYPE_FORMULA: +/*N*/ { +/*N*/ ScAddress aPos; +/*N*/ rStrm >> aPos; +/*N*/ pCell = new ScFormulaCell( pDoc, aPos, rStrm, rHdr ); +/*N*/ ((ScFormulaCell*)pCell)->SetInChangeTrack( TRUE ); +/*N*/ } +/*N*/ break; +/*N*/ case CELLTYPE_NONE : +/*N*/ pCell = NULL; +/*N*/ break; +/*N*/ default: +/*N*/ DBG_ERROR( "ScChangeAction::LoadCell: unknown CellType" ); +/*N*/ rStrm.SetError( SVSTREAM_FILEFORMAT_ERROR ); +/*N*/ pCell = NULL; +/*N*/ } +/*N*/ return pCell; +/*N*/ } + + +// static +/*N*/ BOOL ScChangeAction::StoreLinkChain( ScChangeActionLinkEntry* pLinkFirst, +/*N*/ SvStream& rStrm ) +/*N*/ { +/*N*/ BOOL bOk = TRUE; +/*N*/ UINT32 nCount = 0; +/*N*/ if ( pLinkFirst ) +/*N*/ { +/*N*/ // rueckwaerts speichern, damit onLoad mit Insert die Reihenfolge wieder stimmt +/*N*/ Stack* pStack = new Stack; +/*N*/ for ( ScChangeActionLinkEntry* pL = pLinkFirst; pL; pL = pL->GetNext() ) +/*N*/ { +/*N*/ ++nCount; +/*N*/ pStack->Push( pL ); +/*N*/ } +/*N*/ rStrm << nCount; +/*N*/ ScChangeActionLinkEntry* pHere; +/*N*/ while ( pHere = (ScChangeActionLinkEntry*) pStack->Pop() ) +/*N*/ { +/*N*/ ScChangeAction* p = pHere->GetAction(); +/*N*/ rStrm << (UINT32) ( p ? p->GetActionNumber() : 0 ); +/*N*/ } +/*N*/ delete pStack; +/*N*/ } +/*N*/ else +/*N*/ rStrm << nCount; +/*N*/ return bOk; +/*N*/ } + + +// static +/*N*/ BOOL ScChangeAction::LoadLinkChain( ScChangeAction* pOfAction, // Changetracking.sdc +/*N*/ ScChangeActionLinkEntry** ppLinkFirst, SvStream& rStrm, +/*N*/ ScChangeTrack* pTrack, BOOL bLinkDeleted ) +/*N*/ { +/*N*/ BOOL bOk = TRUE; +/*N*/ UINT32 nCount; +/*N*/ rStrm >> nCount; +/*N*/ for ( UINT32 j = 0; j < nCount; j++ ) +/*N*/ { +/*N*/ ScChangeAction* pAct = NULL; +/*N*/ UINT32 nAct; +/*N*/ rStrm >> nAct; +/*N*/ if ( nAct ) +/*N*/ { +/*N*/ pAct = pTrack->GetActionOrGenerated( nAct ); +/*N*/ DBG_ASSERT( pAct, "ScChangeAction::LoadLinkChain: missing Action" ); +/*N*/ } +/*N*/ if ( bLinkDeleted ) +/*N*/ { +/*N*/ if ( pAct ) +/*N*/ pAct->SetDeletedIn( pOfAction ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ ScChangeActionLinkEntry* pLink = new ScChangeActionLinkEntry( +/*N*/ ppLinkFirst, pAct ); +/*N*/ if ( pAct ) +/*N*/ pAct->AddLink( pOfAction, pLink ); +/*N*/ } +/*N*/ } +/*N*/ return bOk; +/*N*/ } + + +/*N*/ void ScChangeAction::SetDeletedInThis( ULONG nActionNumber, +/*N*/ const ScChangeTrack* pTrack ) +/*N*/ { +/*N*/ if ( nActionNumber ) +/*N*/ { +/*N*/ ScChangeAction* pAct = pTrack->GetActionOrGenerated( nActionNumber ); +/*N*/ DBG_ASSERT( pAct, "ScChangeAction::SetDeletedInThis: missing Action" ); +/*N*/ if ( pAct ) +/*N*/ pAct->SetDeletedIn( this ); +/*N*/ } +/*N*/ } + + +/*N*/ void ScChangeAction::AddDependent( ULONG nActionNumber, +/*N*/ const ScChangeTrack* pTrack ) +/*N*/ { +/*N*/ if ( nActionNumber ) +/*N*/ { +/*N*/ ScChangeAction* pAct = pTrack->GetActionOrGenerated( nActionNumber ); +/*N*/ DBG_ASSERT( pAct, "ScChangeAction::AddDependent: missing Action" ); +/*N*/ if ( pAct ) +/*N*/ { +/*N*/ ScChangeActionLinkEntry* pLink = AddDependent( pAct ); +/*N*/ pAct->AddLink( this, pLink ); +/*N*/ } +/*N*/ } +/*N*/ } + +// static +/*N*/ BOOL ScChangeAction::StoreCellList( ScChangeActionCellListEntry* pFirstCell, +/*N*/ SvStream& rStrm ) +/*N*/ { +/*N*/ UINT32 nCount = 0; +/*N*/ for ( const ScChangeActionCellListEntry* pE = pFirstCell; pE; +/*N*/ pE = pE->pNext ) +/*N*/ ++nCount; +/*N*/ rStrm << nCount; +/*N*/ +/*N*/ if ( nCount ) +/*N*/ { +/*N*/ for ( const ScChangeActionCellListEntry* pE = pFirstCell; pE; +/*N*/ pE = pE->pNext ) +/*N*/ { // Store/Load vertauscht die Reihenfolge, aber das ist hierbei egal +/*N*/ rStrm << (UINT32) pE->pContent->GetActionNumber(); +/*N*/ } +/*N*/ } +/*N*/ return TRUE; +/*N*/ } + + +/*N*/ BOOL ScChangeAction::LoadCellList( ScChangeAction* pOfAction, +/*N*/ ScChangeActionCellListEntry*& pFirstCell, SvStream& rStrm, +/*N*/ ScChangeTrack* pTrack ) +/*N*/ { +/*N*/ UINT32 nCount; +/*N*/ rStrm >> nCount; +/*N*/ if ( nCount ) +/*N*/ { +/*N*/ for ( UINT32 j = 0; j < nCount; j++ ) +/*N*/ { +/*N*/ ScChangeActionContent* pContent; +/*N*/ UINT32 nContent; +/*N*/ rStrm >> nContent; +/*N*/ pContent = (ScChangeActionContent*) pTrack->GetActionOrGenerated( nContent ); +/*N*/ if ( pContent ) +/*N*/ pOfAction->AddContent( pContent ); +/*N*/ else +/*N*/ DBG_ERROR( "ScChangeActionDel::LoadLinks: missing Content" ); +/*N*/ } +/*N*/ } +/*N*/ return TRUE; +/*N*/ } + + +// --- ScChangeActionIns --------------------------------------------------- + +/*N*/ ScChangeActionIns::ScChangeActionIns( const ScRange& rRange ) +/*N*/ : ScChangeAction( SC_CAT_NONE, rRange ) +/*N*/ { +/*N*/ if ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == MAXCOL ) +/*N*/ { +/*N*/ aBigRange.aStart.SetCol( nInt32Min ); +/*N*/ aBigRange.aEnd.SetCol( nInt32Max ); +/*N*/ if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW ) +/*N*/ { +/*N*/ SetType( SC_CAT_INSERT_TABS ); +/*N*/ aBigRange.aStart.SetRow( nInt32Min ); +/*N*/ aBigRange.aEnd.SetRow( nInt32Max ); +/*N*/ } +/*N*/ else +/*N*/ SetType( SC_CAT_INSERT_ROWS ); +/*N*/ } +/*N*/ else if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW ) +/*N*/ { +/*N*/ SetType( SC_CAT_INSERT_COLS ); +/*N*/ aBigRange.aStart.SetRow( nInt32Min ); +/*N*/ aBigRange.aEnd.SetRow( nInt32Max ); +/*N*/ } +/*N*/ else +/*N*/ DBG_ERROR( "ScChangeActionIns: Block not supported!" ); +/*N*/ } + + +/*N*/ ScChangeActionIns::ScChangeActionIns( SvStream& rStrm, +/*N*/ ScMultipleReadHeader& rHdr, ScChangeTrack* pTrack ) +/*N*/ : +/*N*/ ScChangeAction( rStrm, rHdr, pTrack ) +/*N*/ { +/*N*/ } + +/*N*/ ScChangeActionIns::ScChangeActionIns(const ULONG nActionNumber, const ScChangeActionState eState, const ULONG nRejectingNumber, +/*N*/ const ScBigRange& aBigRange, const String& aUser, const DateTime& aDateTime, const String& sComment, +/*N*/ const ScChangeActionType eType) +/*N*/ : +/*N*/ ScChangeAction(eType, aBigRange, nActionNumber, nRejectingNumber, eState, aDateTime, aUser, sComment) +/*N*/ { +/*N*/ } + +/*N*/ ScChangeActionIns::~ScChangeActionIns() +/*N*/ { +/*N*/ } + + +/*N*/ BOOL ScChangeActionIns::Store( SvStream& rStrm, ScMultipleWriteHeader& rHdr ) const +/*N*/ { +/*N*/ BOOL bOk = ScChangeAction::Store( rStrm, rHdr ); +/*N*/ return bOk; +/*N*/ } + + +/*N*/ void ScChangeActionIns::GetDescription( String& rStr, ScDocument* pDoc, +/*N*/ BOOL bSplitRange ) const +/*N*/ { +/*N*/ USHORT nWhatId; +/*N*/ switch ( GetType() ) +/*N*/ { +/*N*/ case SC_CAT_INSERT_COLS : +/*N*/ nWhatId = STR_COLUMN; +/*N*/ break; +/*N*/ case SC_CAT_INSERT_ROWS : +/*N*/ nWhatId = STR_ROW; +/*N*/ break; +/*N*/ default: +/*N*/ nWhatId = STR_AREA; +/*N*/ } +/*N*/ +/*N*/ String aRsc( ScGlobal::GetRscString( STR_CHANGED_INSERT ) ); +/*N*/ xub_StrLen nPos = aRsc.SearchAscii( "#1" ); +/*N*/ rStr += aRsc.Copy( 0, nPos ); +/*N*/ rStr += ScGlobal::GetRscString( nWhatId ); +/*N*/ rStr += ' '; +/*N*/ rStr += GetRefString( GetBigRange(), pDoc ); +/*N*/ rStr += aRsc.Copy( nPos+2 ); +/*N*/ } + + +/*N*/ BOOL ScChangeActionIns::Reject( ScDocument* pDoc ) +/*N*/ { +/*N*/ if ( !aBigRange.IsValid( pDoc ) ) +/*N*/ return FALSE; +/*N*/ +/*N*/ ScRange aRange( aBigRange.MakeRange() ); +/*N*/ if ( !pDoc->IsBlockEditable( aRange.aStart.Tab(), aRange.aStart.Col(), +/*N*/ aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row() ) ) +/*N*/ return FALSE; +/*N*/ +/*N*/ switch ( GetType() ) +/*N*/ { +/*N*/ case SC_CAT_INSERT_COLS : +/*N*/ pDoc->DeleteCol( aRange ); +/*N*/ break; +/*N*/ case SC_CAT_INSERT_ROWS : +/*N*/ pDoc->DeleteRow( aRange ); +/*N*/ break; +/*N*/ case SC_CAT_INSERT_TABS : +/*N*/ pDoc->DeleteTab( aRange.aStart.Tab() ); +/*N*/ break; +/*N*/ } +/*N*/ SetState( SC_CAS_REJECTED ); +/*N*/ RemoveAllLinks(); +/*N*/ return TRUE; +/*N*/ } + + +// --- ScChangeActionDel --------------------------------------------------- + +/*N*/ ScChangeActionDel::ScChangeActionDel( const ScRange& rRange, +/*N*/ short nDxP, short nDyP, ScChangeTrack* pTrackP ) +/*N*/ : +/*N*/ ScChangeAction( SC_CAT_NONE, rRange ), +/*N*/ pTrack( pTrackP ), +/*N*/ pFirstCell( NULL ), +/*N*/ pLinkMove( NULL ), +/*N*/ pCutOff( NULL ), +/*N*/ nCutOff( 0 ), +/*N*/ nDx( nDxP ), +/*N*/ nDy( nDyP ) +/*N*/ { +/*N*/ if ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == MAXCOL ) +/*N*/ { +/*N*/ aBigRange.aStart.SetCol( nInt32Min ); +/*N*/ aBigRange.aEnd.SetCol( nInt32Max ); +/*N*/ if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW ) +/*N*/ { +/*N*/ SetType( SC_CAT_DELETE_TABS ); +/*N*/ aBigRange.aStart.SetRow( nInt32Min ); +/*N*/ aBigRange.aEnd.SetRow( nInt32Max ); +/*N*/ } +/*N*/ else +/*N*/ SetType( SC_CAT_DELETE_ROWS ); +/*N*/ } +/*N*/ else if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW ) +/*N*/ { +/*N*/ SetType( SC_CAT_DELETE_COLS ); +/*N*/ aBigRange.aStart.SetRow( nInt32Min ); +/*N*/ aBigRange.aEnd.SetRow( nInt32Max ); +/*N*/ } +/*N*/ else +/*N*/ DBG_ERROR( "ScChangeActionDel: Block not supported!" ); +/*N*/ } + + +/*N*/ ScChangeActionDel::ScChangeActionDel( SvStream& rStrm, +/*N*/ ScMultipleReadHeader& rHdr, ScDocument* pDoc, USHORT nVer, +/*N*/ ScChangeTrack* pTrackP ) +/*N*/ : +/*N*/ ScChangeAction( rStrm, rHdr, pTrackP ), +/*N*/ pTrack( pTrackP ), +/*N*/ pFirstCell( NULL ), +/*N*/ pLinkMove( NULL ) +/*N*/ { +/*N*/ UINT32 n32; +/*N*/ INT16 n16s; +/*N*/ rStrm >> n32; pCutOff = (ScChangeActionIns*)(ULONG) n32; +/*N*/ rStrm >> n16s; nCutOff = n16s; +/*N*/ rStrm >> n16s; nDx = n16s; +/*N*/ rStrm >> n16s; nDy = n16s; +/*N*/ } + +/*N*/ ScChangeActionDel::ScChangeActionDel(const ULONG nActionNumber, const ScChangeActionState eState, const ULONG nRejectingNumber, +/*N*/ const ScBigRange& aBigRange, const String& aUser, const DateTime& aDateTime, const String &sComment, +/*N*/ const ScChangeActionType eType, const short nD, ScChangeTrack* pTrackP) // wich of nDx and nDy is set is depend on the type +/*N*/ : +/*N*/ ScChangeAction(eType, aBigRange, nActionNumber, nRejectingNumber, eState, aDateTime, aUser, sComment), +/*N*/ pTrack( pTrackP ), +/*N*/ pFirstCell( NULL ), +/*N*/ pLinkMove( NULL ), +/*N*/ pCutOff( NULL ), +/*N*/ nCutOff( 0 ), +/*N*/ nDx( 0 ), +/*N*/ nDy( 0 ) +/*N*/ { +/*N*/ if (eType == SC_CAT_DELETE_COLS) +/*N*/ nDx = nD; +/*N*/ else if (eType == SC_CAT_DELETE_ROWS) +/*N*/ nDy = nD; +/*N*/ } + +/*N*/ ScChangeActionDel::~ScChangeActionDel() +/*N*/ { +/*N*/ DeleteCellEntries(); +/*N*/ while ( pLinkMove ) +/*N*/ delete pLinkMove; +/*N*/ } + + +/*N*/ BOOL ScChangeActionDel::Store( SvStream& rStrm, ScMultipleWriteHeader& rHdr ) const +/*N*/ { +/*N*/ BOOL bOk = ScChangeAction::Store( rStrm, rHdr ); +/*N*/ rStrm << (UINT32) ( pCutOff ? pCutOff->GetActionNumber() : 0 ); +/*N*/ rStrm << (INT16) nCutOff; +/*N*/ rStrm << (INT16) nDx; +/*N*/ rStrm << (INT16) nDy; +/*N*/ return bOk; +/*N*/ } + + +/*N*/ BOOL ScChangeActionDel::StoreLinks( SvStream& rStrm ) const +/*N*/ { +/*N*/ BOOL bOk = ScChangeAction::StoreLinks( rStrm ); +/*N*/ UINT32 nCount = 0; +/*N*/ if ( pLinkMove ) +/*N*/ { +/*N*/ // rueckwaerts speichern, damit onLoad mit Insert die Reihenfolge wieder stimmt +/*N*/ Stack* pStack = new Stack; +/*N*/ for ( ScChangeActionDelMoveEntry* pL = pLinkMove; pL; pL = pL->GetNext() ) +/*N*/ { +/*N*/ ++nCount; +/*N*/ pStack->Push( pL ); +/*N*/ } +/*N*/ rStrm << nCount; +/*N*/ ScChangeActionDelMoveEntry* pHere; +/*N*/ while ( pHere = (ScChangeActionDelMoveEntry*) pStack->Pop() ) +/*N*/ { +/*N*/ ScChangeAction* p = pHere->GetAction(); +/*N*/ rStrm << (UINT32) ( p ? p->GetActionNumber() : 0 ); +/*N*/ rStrm << (INT16) pHere->GetCutOffFrom(); +/*N*/ rStrm << (INT16) pHere->GetCutOffTo(); +/*N*/ } +/*N*/ delete pStack; +/*N*/ } +/*N*/ else +/*N*/ rStrm << nCount; +/*N*/ +/*N*/ bOk &= ScChangeAction::StoreCellList( pFirstCell, rStrm ); +/*N*/ +/*N*/ return bOk; +/*N*/ } + + +/*N*/ BOOL ScChangeActionDel::LoadLinks( SvStream& rStrm, ScChangeTrack* pTrack ) +/*N*/ { +/*N*/ BOOL bOk = ScChangeAction::LoadLinks( rStrm, pTrack ); +/*N*/ UINT32 nCount; +/*N*/ rStrm >> nCount; +/*N*/ for ( UINT32 j = 0; j < nCount; j++ ) +/*N*/ { +/*N*/ ScChangeActionMove* pAct = NULL; +/*N*/ UINT32 nAct; +/*N*/ rStrm >> nAct; +/*N*/ if ( nAct ) +/*N*/ { +/*N*/ pAct = (ScChangeActionMove*) pTrack->GetAction( nAct ); +/*N*/ DBG_ASSERT( pAct, "ScChangeActionDel::LoadLinks: missing Move" ); +/*N*/ } +/*N*/ INT16 nFrom, nTo; +/*N*/ rStrm >> nFrom >> nTo; +/*N*/ ScChangeActionDelMoveEntry* pLink = new ScChangeActionDelMoveEntry( +/*N*/ &pLinkMove, pAct, nFrom, nTo ); +/*N*/ if ( pAct ) +/*N*/ pAct->AddLink( this, pLink ); +/*N*/ } +/*N*/ if ( pCutOff ) +/*N*/ { +/*N*/ pCutOff = (ScChangeActionIns*) pTrack->GetAction( (ULONG) pCutOff ); +/*N*/ DBG_ASSERT( pCutOff, "ScChangeActionDel::LoadLinks: missing Insert" ); +/*N*/ } +/*N*/ +/*N*/ bOk &= ScChangeAction::LoadCellList( this, pFirstCell, rStrm, pTrack ); +/*N*/ +/*N*/ return bOk; +/*N*/ } + +/*N*/ void ScChangeActionDel::AddContent( ScChangeActionContent* pContent ) +/*N*/ { +/*N*/ ScChangeActionCellListEntry* pE = new ScChangeActionCellListEntry( +/*N*/ pContent, pFirstCell ); +/*N*/ pFirstCell = pE; +/*N*/ } + + +/*N*/ void ScChangeActionDel::DeleteCellEntries() +/*N*/ { +/*N*/ pTrack->DeleteCellEntries( pFirstCell, this ); +/*N*/ } + + +/*N*/ BOOL ScChangeActionDel::IsBaseDelete() const +/*N*/ { +/*N*/ return !GetDx() && !GetDy(); +/*N*/ } + + +/*N*/ BOOL ScChangeActionDel::IsTopDelete() const +/*N*/ { +/*N*/ const ScChangeAction* p = GetNext(); +/*N*/ if ( !p || p->GetType() != GetType() ) +/*N*/ return TRUE; +/*N*/ return ((ScChangeActionDel*)p)->IsBaseDelete(); +/*N*/ } + + +/*N*/ BOOL ScChangeActionDel::IsMultiDelete() const +/*N*/ { +/*N*/ if ( GetDx() || GetDy() ) +/*N*/ return TRUE; +/*N*/ const ScChangeAction* p = GetNext(); +/*N*/ if ( !p || p->GetType() != GetType() ) +/*N*/ return FALSE; +/*N*/ const ScChangeActionDel* pDel = (const ScChangeActionDel*) p; +/*N*/ if ( (pDel->GetDx() > GetDx() || pDel->GetDy() > GetDy()) && +/*N*/ pDel->GetBigRange() == aBigRange ) +/*N*/ return TRUE; +/*N*/ return FALSE; +/*N*/ } + + +/*N*/ void ScChangeActionDel::UpdateReference( const ScChangeTrack* pTrack, +/*N*/ UpdateRefMode eMode, const ScBigRange& rRange, +/*N*/ INT32 nDx, INT32 nDy, INT32 nDz ) +/*N*/ { +/*N*/ ScRefUpdate::Update( eMode, rRange, nDx, nDy, nDz, GetBigRange() ); +/*N*/ if ( !IsDeletedIn() ) +/*N*/ return ; +/*N*/ // evtl. in "druntergerutschten" anpassen +/*N*/ for ( ScChangeActionLinkEntry* pL = pLinkDeleted; pL; pL = pL->GetNext() ) +/*N*/ { +/*N*/ ScChangeAction* p = pL->GetAction(); +/*N*/ if ( p && p->GetType() == SC_CAT_CONTENT && +/*N*/ !GetBigRange().In( p->GetBigRange() ) ) +/*N*/ { +/*N*/ switch ( GetType() ) +/*N*/ { +/*N*/ case SC_CAT_DELETE_COLS : +/*N*/ p->GetBigRange().aStart.SetCol( GetBigRange().aStart.Col() ); +/*N*/ p->GetBigRange().aEnd.SetCol( GetBigRange().aStart.Col() ); +/*N*/ break; +/*N*/ case SC_CAT_DELETE_ROWS : +/*N*/ p->GetBigRange().aStart.SetRow( GetBigRange().aStart.Row() ); +/*N*/ p->GetBigRange().aEnd.SetRow( GetBigRange().aStart.Row() ); +/*N*/ break; +/*N*/ case SC_CAT_DELETE_TABS : +/*N*/ p->GetBigRange().aStart.SetTab( GetBigRange().aStart.Tab() ); +/*N*/ p->GetBigRange().aEnd.SetTab( GetBigRange().aStart.Tab() ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + + +/*N*/ ScBigRange ScChangeActionDel::GetOverAllRange() const +/*N*/ { +/*N*/ ScBigRange aTmpRange( GetBigRange() ); +/*N*/ aTmpRange.aEnd.SetCol( aTmpRange.aEnd.Col() + GetDx() ); +/*N*/ aTmpRange.aEnd.SetRow( aTmpRange.aEnd.Row() + GetDy() ); +/*N*/ return aTmpRange; +/*N*/ } + + +/*N*/ void ScChangeActionDel::GetDescription( String& rStr, ScDocument* pDoc, +/*N*/ BOOL bSplitRange ) const +/*N*/ { +/*N*/ USHORT nWhatId; +/*N*/ switch ( GetType() ) +/*N*/ { +/*N*/ case SC_CAT_DELETE_COLS : +/*N*/ nWhatId = STR_COLUMN; +/*N*/ break; +/*N*/ case SC_CAT_DELETE_ROWS : +/*N*/ nWhatId = STR_ROW; +/*N*/ break; +/*N*/ default: +/*N*/ nWhatId = STR_AREA; +/*N*/ } +/*N*/ +/*N*/ ScBigRange aTmpRange( GetBigRange() ); +/*N*/ if ( !IsRejected() ) +/*N*/ { +/*N*/ if ( bSplitRange ) +/*N*/ { +/*N*/ aTmpRange.aStart.SetCol( aTmpRange.aStart.Col() + GetDx() ); +/*N*/ aTmpRange.aStart.SetRow( aTmpRange.aStart.Row() + GetDy() ); +/*N*/ } +/*N*/ aTmpRange.aEnd.SetCol( aTmpRange.aEnd.Col() + GetDx() ); +/*N*/ aTmpRange.aEnd.SetRow( aTmpRange.aEnd.Row() + GetDy() ); +/*N*/ } +/*N*/ +/*N*/ String aRsc( ScGlobal::GetRscString( STR_CHANGED_DELETE ) ); +/*N*/ xub_StrLen nPos = aRsc.SearchAscii( "#1" ); +/*N*/ rStr += aRsc.Copy( 0, nPos ); +/*N*/ rStr += ScGlobal::GetRscString( nWhatId ); +/*N*/ rStr += ' '; +/*N*/ rStr += GetRefString( aTmpRange, pDoc ); +/*N*/ rStr += aRsc.Copy( nPos+2 ); +/*N*/ } + + +/*N*/ BOOL ScChangeActionDel::Reject( ScDocument* pDoc ) +/*N*/ { +/*N*/ if ( !aBigRange.IsValid( pDoc ) && GetType() != SC_CAT_DELETE_TABS ) +/*N*/ return FALSE; +/*N*/ +/*N*/ BOOL bOk = TRUE; +/*N*/ +/*N*/ if ( IsTopDelete() ) +/*N*/ { // den kompletten Bereich in einem Rutsch restaurieren +/*N*/ ScBigRange aTmpRange( GetOverAllRange() ); +/*N*/ if ( !aTmpRange.IsValid( pDoc ) ) +/*N*/ { +/*N*/ if ( GetType() == SC_CAT_DELETE_TABS ) +/*N*/ { // wird Tab angehaengt? +/*N*/ if ( aTmpRange.aStart.Tab() > pDoc->GetMaxTableNumber() ) +/*N*/ bOk = FALSE; +/*N*/ } +/*N*/ else +/*N*/ bOk = FALSE; +/*N*/ } +/*N*/ if ( bOk ) +/*N*/ { +/*N*/ ScRange aRange( aTmpRange.MakeRange() ); +/*N*/ // InDelete... fuer Formel UpdateReference in Document +/*N*/ pTrack->SetInDeleteRange( aRange ); +/*N*/ pTrack->SetInDeleteTop( TRUE ); +/*N*/ pTrack->SetInDeleteUndo( TRUE ); +/*N*/ pTrack->SetInDelete( TRUE ); +/*N*/ switch ( GetType() ) +/*N*/ { +/*N*/ case SC_CAT_DELETE_COLS : +/*N*/ if ( !(aRange.aStart.Col() == 0 && aRange.aEnd.Col() == MAXCOL) ) +/*N*/ { // nur wenn nicht TabDelete +/*N*/ if ( bOk = pDoc->CanInsertCol( aRange ) ) +/*N*/ bOk = pDoc->InsertCol( aRange ); +/*N*/ } +/*N*/ break; +/*N*/ case SC_CAT_DELETE_ROWS : +/*N*/ if ( bOk = pDoc->CanInsertRow( aRange ) ) +/*N*/ bOk = pDoc->InsertRow( aRange ); +/*N*/ break; +/*N*/ case SC_CAT_DELETE_TABS : +/*N*/ { +/*N*/ //2do: Tabellennamen merken? +/*N*/ String aName; +/*N*/ pDoc->CreateValidTabName( aName ); +/*N*/ if ( bOk = pDoc->ValidNewTabName( aName ) ) +/*N*/ bOk = pDoc->InsertTab( aRange.aStart.Tab(), aName ); +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ pTrack->SetInDelete( FALSE ); +/*N*/ pTrack->SetInDeleteUndo( FALSE ); +/*N*/ } +/*N*/ if ( !bOk ) +/*N*/ { +/*N*/ pTrack->SetInDeleteTop( FALSE ); +/*N*/ return FALSE; +/*N*/ } +/*N*/ // InDeleteTop fuer UpdateReference-Undo behalten +/*N*/ } +/*N*/ +/*N*/ // setzt rejected und ruft UpdateReference-Undo und DeleteCellEntries +/*N*/ RejectRestoreContents( pTrack, GetDx(), GetDy() ); +/*N*/ +/*N*/ pTrack->SetInDeleteTop( FALSE ); +/*N*/ RemoveAllLinks(); +/*N*/ return TRUE; +/*N*/ } + + +/*N*/ void ScChangeActionDel::UndoCutOffMoves() +/*N*/ { // abgeschnittene Moves wiederherstellen, Entries/Links deleten +/*N*/ while ( pLinkMove ) +/*N*/ { +/*N*/ ScChangeActionMove* pMove = pLinkMove->GetMove(); +/*N*/ short nFrom = pLinkMove->GetCutOffFrom(); +/*N*/ short nTo = pLinkMove->GetCutOffTo(); +/*N*/ switch ( GetType() ) +/*N*/ { +/*N*/ case SC_CAT_DELETE_COLS : +/*N*/ if ( nFrom > 0 ) +/*N*/ pMove->GetFromRange().aStart.IncCol( -nFrom ); +/*N*/ else if ( nFrom < 0 ) +/*N*/ pMove->GetFromRange().aEnd.IncCol( -nFrom ); +/*N*/ if ( nTo > 0 ) +/*N*/ pMove->GetBigRange().aStart.IncCol( -nTo ); +/*N*/ else if ( nTo < 0 ) +/*N*/ pMove->GetBigRange().aEnd.IncCol( -nTo ); +/*N*/ break; +/*N*/ case SC_CAT_DELETE_ROWS : +/*N*/ if ( nFrom > 0 ) +/*N*/ pMove->GetFromRange().aStart.IncRow( -nFrom ); +/*N*/ else if ( nFrom < 0 ) +/*N*/ pMove->GetFromRange().aEnd.IncRow( -nFrom ); +/*N*/ if ( nTo > 0 ) +/*N*/ pMove->GetBigRange().aStart.IncRow( -nTo ); +/*N*/ else if ( nTo < 0 ) +/*N*/ pMove->GetBigRange().aEnd.IncRow( -nTo ); +/*N*/ break; +/*N*/ case SC_CAT_DELETE_TABS : +/*N*/ if ( nFrom > 0 ) +/*N*/ pMove->GetFromRange().aStart.IncTab( -nFrom ); +/*N*/ else if ( nFrom < 0 ) +/*N*/ pMove->GetFromRange().aEnd.IncTab( -nFrom ); +/*N*/ if ( nTo > 0 ) +/*N*/ pMove->GetBigRange().aStart.IncTab( -nTo ); +/*N*/ else if ( nTo < 0 ) +/*N*/ pMove->GetBigRange().aEnd.IncTab( -nTo ); +/*N*/ break; +/*N*/ } +/*N*/ delete pLinkMove; // rueckt sich selbst hoch +/*N*/ } +/*N*/ } + +/*N*/ void ScChangeActionDel::UndoCutOffInsert() +/*N*/ { // abgeschnittenes Insert wiederherstellen +/*N*/ if ( pCutOff ) +/*N*/ { +/*N*/ switch ( pCutOff->GetType() ) +/*N*/ { +/*N*/ case SC_CAT_INSERT_COLS : +/*N*/ if ( nCutOff < 0 ) +/*N*/ pCutOff->GetBigRange().aEnd.IncCol( -nCutOff ); +/*N*/ else +/*N*/ pCutOff->GetBigRange().aStart.IncCol( -nCutOff ); +/*N*/ break; +/*N*/ case SC_CAT_INSERT_ROWS : +/*N*/ if ( nCutOff < 0 ) +/*N*/ pCutOff->GetBigRange().aEnd.IncRow( -nCutOff ); +/*N*/ else +/*N*/ pCutOff->GetBigRange().aStart.IncRow( -nCutOff ); +/*N*/ break; +/*N*/ case SC_CAT_INSERT_TABS : +/*N*/ if ( nCutOff < 0 ) +/*N*/ pCutOff->GetBigRange().aEnd.IncTab( -nCutOff ); +/*N*/ else +/*N*/ pCutOff->GetBigRange().aStart.IncTab( -nCutOff ); +/*N*/ break; +/*N*/ } +/*N*/ SetCutOffInsert( NULL, 0 ); +/*N*/ } +/*N*/ } + + +// --- ScChangeActionMove -------------------------------------------------- + +/*N*/ ScChangeActionMove::ScChangeActionMove( SvStream& rStrm, +/*N*/ ScMultipleReadHeader& rHdr, ScChangeTrack* pTrackP ) +/*N*/ : +/*N*/ ScChangeAction( rStrm, rHdr, pTrackP ), +/*N*/ pTrack( pTrackP ), +/*N*/ pFirstCell( NULL ), +/*N*/ nStartLastCut(0), +/*N*/ nEndLastCut(0) +/*N*/ { +/*N*/ rStrm >> aFromRange; +/*N*/ } + +/*N*/ ScChangeActionMove::ScChangeActionMove(const ULONG nActionNumber, const ScChangeActionState eState, const ULONG nRejectingNumber, +/*N*/ const ScBigRange& aToBigRange, const String& aUser, const DateTime& aDateTime, const String &sComment, +/*N*/ const ScBigRange& aFromBigRange, ScChangeTrack* pTrackP) // wich of nDx and nDy is set is depend on the type +/*N*/ : +/*N*/ ScChangeAction(SC_CAT_MOVE, aToBigRange, nActionNumber, nRejectingNumber, eState, aDateTime, aUser, sComment), +/*N*/ aFromRange(aFromBigRange), +/*N*/ pTrack( pTrackP ), +/*N*/ pFirstCell( NULL ), +/*N*/ nStartLastCut(0), +/*N*/ nEndLastCut(0) +/*N*/ { +/*N*/ } + +/*N*/ ScChangeActionMove::~ScChangeActionMove() +/*N*/ { +/*N*/ DeleteCellEntries(); +/*N*/ } + + +/*N*/ BOOL ScChangeActionMove::Store( SvStream& rStrm, ScMultipleWriteHeader& rHdr ) const +/*N*/ { +/*N*/ BOOL bOk = ScChangeAction::Store( rStrm, rHdr ); +/*N*/ rStrm << aFromRange; +/*N*/ return bOk; +/*N*/ } + + +/*N*/ BOOL ScChangeActionMove::StoreLinks( SvStream& rStrm ) const +/*N*/ { +/*N*/ BOOL bOk = ScChangeAction::StoreLinks( rStrm ); +/*N*/ bOk &= ScChangeAction::StoreCellList( pFirstCell, rStrm ); +/*N*/ return bOk; +/*N*/ } + + +/*N*/ BOOL ScChangeActionMove::LoadLinks( SvStream& rStrm, ScChangeTrack* pTrack ) +/*N*/ { +/*N*/ BOOL bOk = ScChangeAction::LoadLinks( rStrm, pTrack ); +/*N*/ bOk &= ScChangeAction::LoadCellList( this, pFirstCell, rStrm, pTrack ); +/*N*/ return bOk; +/*N*/ } + + +/*N*/ void ScChangeActionMove::AddContent( ScChangeActionContent* pContent ) +/*N*/ { +/*N*/ ScChangeActionCellListEntry* pE = new ScChangeActionCellListEntry( +/*N*/ pContent, pFirstCell ); +/*N*/ pFirstCell = pE; +/*N*/ } + + +/*N*/ void ScChangeActionMove::DeleteCellEntries() +/*N*/ { +/*N*/ pTrack->DeleteCellEntries( pFirstCell, this ); +/*N*/ } + + +/*N*/ void ScChangeActionMove::UpdateReference( const ScChangeTrack* pTrack, +/*N*/ UpdateRefMode eMode, const ScBigRange& rRange, +/*N*/ INT32 nDx, INT32 nDy, INT32 nDz ) +/*N*/ { +/*N*/ ScRefUpdate::Update( eMode, rRange, nDx, nDy, nDz, aFromRange ); +/*N*/ ScRefUpdate::Update( eMode, rRange, nDx, nDy, nDz, GetBigRange() ); +/*N*/ } + + +/*N*/ void ScChangeActionMove::GetDelta( INT32& nDx, INT32& nDy, INT32& nDz ) const +/*N*/ { +/*N*/ const ScBigAddress& rToPos = GetBigRange().aStart; +/*N*/ const ScBigAddress& rFromPos = GetFromRange().aStart; +/*N*/ nDx = rToPos.Col() - rFromPos.Col(); +/*N*/ nDy = rToPos.Row() - rFromPos.Row(); +/*N*/ nDz = rToPos.Tab() - rFromPos.Tab(); +/*N*/ } + + +/*N*/ void ScChangeActionMove::GetDescription( String& rStr, ScDocument* pDoc, +/*N*/ BOOL bSplitRange ) const +/*N*/ { +/*N*/ BOOL bFlag3D = ( GetFromRange().aStart.Tab() != GetBigRange().aStart.Tab() ); +/*N*/ +/*N*/ String aRsc( ScGlobal::GetRscString( STR_CHANGED_MOVE ) ); +/*N*/ +/*N*/ xub_StrLen nPos = 0; +/*N*/ String aTmpStr = ScChangeAction::GetRefString( GetFromRange(), pDoc, bFlag3D ); +/*N*/ nPos = aRsc.SearchAscii( "#1", nPos ); +/*N*/ aRsc.Erase( nPos, 2 ); +/*N*/ aRsc.Insert( aTmpStr, nPos ); +/*N*/ nPos += aTmpStr.Len(); +/*N*/ +/*N*/ aTmpStr = ScChangeAction::GetRefString( GetBigRange(), pDoc, bFlag3D ); +/*N*/ nPos = aRsc.SearchAscii( "#2", nPos ); +/*N*/ aRsc.Erase( nPos, 2 ); +/*N*/ aRsc.Insert( aTmpStr, nPos ); +/*N*/ nPos += aTmpStr.Len(); +/*N*/ +/*N*/ rStr += aRsc; +/*N*/ } + + +/*N*/ void ScChangeActionMove::GetRefString( String& rStr, ScDocument* pDoc, +/*N*/ BOOL bFlag3D ) const +/*N*/ { +/*N*/ if ( !bFlag3D ) +/*N*/ bFlag3D = ( GetFromRange().aStart.Tab() != GetBigRange().aStart.Tab() ); +/*N*/ rStr = ScChangeAction::GetRefString( GetFromRange(), pDoc, bFlag3D ); +/*N*/ rStr += ','; +/*N*/ rStr += ' '; +/*N*/ rStr += ScChangeAction::GetRefString( GetBigRange(), pDoc, bFlag3D ); +/*N*/ } + + +/*N*/ BOOL ScChangeActionMove::Reject( ScDocument* pDoc ) +/*N*/ { +/*N*/ if ( !(aBigRange.IsValid( pDoc ) && aFromRange.IsValid( pDoc )) ) +/*N*/ return FALSE; +/*N*/ +/*N*/ ScRange aToRange( aBigRange.MakeRange() ); +/*N*/ ScRange aFrmRange( aFromRange.MakeRange() ); +/*N*/ +/*N*/ BOOL bOk = pDoc->IsBlockEditable( aToRange.aStart.Tab(), +/*N*/ aToRange.aStart.Col(), aToRange.aStart.Row(), +/*N*/ aToRange.aEnd.Col(), aToRange.aEnd.Row() ); +/*N*/ if ( bOk ) +/*N*/ bOk = pDoc->IsBlockEditable( aFrmRange.aStart.Tab(), +/*N*/ aFrmRange.aStart.Col(), aFrmRange.aStart.Row(), +/*N*/ aFrmRange.aEnd.Col(), aFrmRange.aEnd.Row() ); +/*N*/ if ( !bOk ) +/*N*/ return FALSE; +/*N*/ +/*N*/ pTrack->LookUpContents( aToRange, pDoc, 0, 0, 0 ); // zu movende Contents +/*N*/ +/*N*/ pDoc->DeleteAreaTab( aToRange, IDF_ALL ); +/*N*/ pDoc->DeleteAreaTab( aFrmRange, IDF_ALL ); +/*N*/ // Formeln im Dokument anpassen +/*N*/ pDoc->UpdateReference( URM_MOVE, +/*N*/ aFrmRange.aStart.Col(), aFrmRange.aStart.Row(), aFrmRange.aStart.Tab(), +/*N*/ aFrmRange.aEnd.Col(), aFrmRange.aEnd.Row(), aFrmRange.aEnd.Tab(), +/*N*/ (short) aFrmRange.aStart.Col() - aToRange.aStart.Col(), +/*N*/ (short) aFrmRange.aStart.Row() - aToRange.aStart.Row(), +/*N*/ (short) aFrmRange.aStart.Tab() - aToRange.aStart.Tab(), NULL ); +/*N*/ +/*N*/ // LinkDependent freigeben, nachfolgendes UpdateReference-Undo setzt +/*N*/ // ToRange->FromRange Dependents +/*N*/ RemoveAllDependent(); +/*N*/ +/*N*/ // setzt rejected und ruft UpdateReference-Undo und DeleteCellEntries +/*N*/ RejectRestoreContents( pTrack, 0, 0 ); +/*N*/ +/*N*/ while ( pLinkDependent ) +/*N*/ { +/*N*/ ScChangeAction* p = pLinkDependent->GetAction(); +/*N*/ if ( p && p->GetType() == SC_CAT_CONTENT ) +/*N*/ { +/*N*/ ScChangeActionContent* pContent = (ScChangeActionContent*) p; +/*N*/ if ( !pContent->IsDeletedIn() && +/*N*/ pContent->GetBigRange().aStart.IsValid( pDoc ) ) +/*N*/ pContent->PutNewValueToDoc( pDoc, 0, 0 ); +/*N*/ // in LookUpContents generierte loeschen +/*N*/ if ( pTrack->IsGenerated( pContent->GetActionNumber() ) && +/*N*/ !pContent->IsDeletedIn() ) +/*N*/ { +/*N*/ pLinkDependent->UnLink(); //! sonst wird der mitgeloescht +/*N*/ pTrack->DeleteGeneratedDelContent( pContent ); +/*N*/ } +/*N*/ } +/*N*/ delete pLinkDependent; +/*N*/ } +/*N*/ +/*N*/ RemoveAllLinks(); +/*N*/ return TRUE; +/*N*/ } + + +// --- ScChangeActionContent ----------------------------------------------- + +const USHORT nMemPoolChangeActionContent = (0x8000 - 64) / sizeof(ScChangeActionContent); +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( ScChangeActionContent, nMemPoolChangeActionContent, nMemPoolChangeActionContent )//STRIP008 ; + + +/*N*/ ScChangeActionContent::ScChangeActionContent( SvStream& rStrm, +/*N*/ ScMultipleReadHeader& rHdr, ScDocument* pDoc, USHORT nVer, +/*N*/ ScChangeTrack* pTrack ) +/*N*/ : +/*N*/ ScChangeAction( rStrm, rHdr, pTrack ), +/*N*/ pNextInSlot( NULL ), +/*N*/ ppPrevInSlot( NULL ) +/*N*/ { +/*N*/ UINT32 n32; // Changetracking.sdc +/*N*/ rStrm.ReadByteString( aOldValue, rStrm.GetStreamCharSet() ); +/*N*/ rStrm.ReadByteString( aNewValue, rStrm.GetStreamCharSet() ); +/*N*/ rStrm >> n32; pNextContent = (ScChangeActionContent*)(ULONG) n32; +/*N*/ rStrm >> n32; pPrevContent = (ScChangeActionContent*)(ULONG) n32; +/*N*/ +/*N*/ { +/*N*/ ScMultipleReadHeader aDataHdr( rStrm ); +/*N*/ pOldCell = ScChangeAction::LoadCell( rStrm, aDataHdr, pDoc, nVer ); +/*N*/ pNewCell = ScChangeAction::LoadCell( rStrm, aDataHdr, pDoc, nVer ); +/*N*/ } +/*N*/ } + +/*N*/ ScChangeActionContent::ScChangeActionContent( const ULONG nActionNumber, +/*N*/ const ScChangeActionState eState, const ULONG nRejectingNumber, +/*N*/ const ScBigRange& aBigRange, const String& aUser, +/*N*/ const DateTime& aDateTime, const String& sComment, +/*N*/ ScBaseCell* pTempOldCell, ScDocument* pDoc, const String& sResult ) +/*N*/ : +/*N*/ ScChangeAction(SC_CAT_CONTENT, aBigRange, nActionNumber, nRejectingNumber, eState, aDateTime, aUser, sComment), +/*N*/ pOldCell(pTempOldCell), +/*N*/ pNewCell(NULL), +/*N*/ pNextContent(NULL), +/*N*/ pPrevContent(NULL), +/*N*/ pNextInSlot(NULL), +/*N*/ ppPrevInSlot(NULL), +/*N*/ aOldValue(sResult) +/*N*/ +/*N*/ { +/*N*/ if (pOldCell) +/*N*/ ScChangeActionContent::SetCell( aOldValue, pOldCell, 0, pDoc ); +/*N*/ } + +/*N*/ ScChangeActionContent::ScChangeActionContent( const ULONG nActionNumber, +/*N*/ ScBaseCell* pTempNewCell, const ScBigRange& aBigRange, +/*N*/ ScDocument* pDoc ) +/*N*/ : +/*N*/ ScChangeAction(SC_CAT_CONTENT, aBigRange, nActionNumber), +/*N*/ pNewCell(pTempNewCell), +/*N*/ pOldCell(NULL), +/*N*/ pNextContent(NULL), +/*N*/ pPrevContent(NULL), +/*N*/ pNextInSlot(NULL), +/*N*/ ppPrevInSlot(NULL) +/*N*/ { +/*N*/ if (pNewCell) +/*N*/ ScChangeActionContent::SetCell( aNewValue, pNewCell, 0, pDoc ); +/*N*/ } + +/*N*/ ScChangeActionContent::~ScChangeActionContent() +/*N*/ { +/*N*/ ClearTrack(); +/*N*/ } + + +/*N*/ void ScChangeActionContent::ClearTrack() +/*N*/ { +/*N*/ RemoveFromSlot(); +/*N*/ if ( pPrevContent ) +/*N*/ pPrevContent->pNextContent = pNextContent; +/*N*/ if ( pNextContent ) +/*N*/ pNextContent->pPrevContent = pPrevContent; +/*N*/ } + + +/*N*/ BOOL ScChangeActionContent::Store( SvStream& rStrm, ScMultipleWriteHeader& rHdr ) const +/*N*/ { +/*N*/ BOOL bOk = ScChangeAction::Store( rStrm, rHdr ); +/*N*/ rStrm.WriteByteString( aOldValue, rStrm.GetStreamCharSet() ); +/*N*/ rStrm.WriteByteString( aNewValue, rStrm.GetStreamCharSet() ); +/*N*/ rStrm << (UINT32) ( pNextContent ? pNextContent->GetActionNumber() : 0 ); +/*N*/ rStrm << (UINT32) ( pPrevContent ? pPrevContent->GetActionNumber() : 0 ); +/*N*/ +/*N*/ { +/*N*/ ScMultipleWriteHeader aDataHdr( rStrm ); +/*N*/ ScChangeAction::StoreCell( pOldCell, rStrm, aDataHdr ); +/*N*/ ScChangeAction::StoreCell( pNewCell, rStrm, aDataHdr ); +/*N*/ } +/*N*/ +/*N*/ return bOk; +/*N*/ } + + +/*N*/ BOOL ScChangeActionContent::StoreLinks( SvStream& rStrm ) const +/*N*/ { +/*N*/ BOOL bOk = ScChangeAction::StoreLinks( rStrm ); +/*N*/ return bOk; +/*N*/ } + + +/*N*/ BOOL ScChangeActionContent::LoadLinks( SvStream& rStrm, ScChangeTrack* pTrack ) +/*N*/ { +/*N*/ BOOL bOk = ScChangeAction::LoadLinks( rStrm, pTrack ); +/*N*/ if ( pNextContent ) +/*N*/ { +/*N*/ pNextContent = (ScChangeActionContent*) pTrack->GetAction( +/*N*/ (ULONG) pNextContent ); +/*N*/ DBG_ASSERT( pNextContent, +/*N*/ "ScChangeActionContent::LoadLinks: missing NextContent" ); +/*N*/ } +/*N*/ if ( pPrevContent ) +/*N*/ { +/*N*/ pPrevContent = (ScChangeActionContent*) pTrack->GetAction( +/*N*/ (ULONG) pPrevContent ); +/*N*/ DBG_ASSERT( pPrevContent, +/*N*/ "ScChangeActionContent::LoadLinks: missing PrevContent" ); +/*N*/ } +/*N*/ return bOk; +/*N*/ } + + +/*N*/ ScChangeActionContent* ScChangeActionContent::GetTopContent() const // Changetracking.sdc +/*N*/ { +/*N*/ if ( pNextContent ) +/*N*/ { +/*N*/ ScChangeActionContent* pContent = pNextContent; +/*N*/ while ( pContent->pNextContent ) +/*N*/ pContent = pContent->pNextContent; +/*N*/ return pContent; +/*N*/ } +/*N*/ return (ScChangeActionContent*) this; +/*N*/ } + + +/*N*/ ScChangeActionLinkEntry* ScChangeActionContent::GetDeletedIn() const +/*N*/ { +/*N*/ if ( pNextContent ) +/*N*/ return GetTopContent()->pLinkDeletedIn; +/*N*/ return pLinkDeletedIn; +/*N*/ } + + +/*N*/ ScChangeActionLinkEntry** ScChangeActionContent::GetDeletedInAddress() +/*N*/ { +/*N*/ if ( pNextContent ) +/*N*/ return GetTopContent()->GetDeletedInAddress(); +/*N*/ return &pLinkDeletedIn; +/*N*/ } + + +/*N*/ void ScChangeActionContent::SetOldValue( const ScBaseCell* pCell, +/*N*/ const ScDocument* pFromDoc, ScDocument* pToDoc ) +/*N*/ { +/*N*/ ScChangeActionContent::SetValue( aOldValue, pOldCell, +/*N*/ aBigRange.aStart.MakeAddress(), pCell, pFromDoc, pToDoc ); +/*N*/ } + + +/*N*/ void ScChangeActionContent::SetNewValue( const ScBaseCell* pCell, +/*N*/ ScDocument* pDoc ) +/*N*/ { +/*N*/ ScChangeActionContent::SetValue( aNewValue, pNewCell, +/*N*/ aBigRange.aStart.MakeAddress(), pCell, pDoc, pDoc ); +/*N*/ } + + +/*N*/ void ScChangeActionContent::SetNewCell( ScBaseCell* pCell, ScDocument* pDoc ) +/*N*/ { +/*N*/ DBG_ASSERT( !pNewCell, "ScChangeActionContent::SetNewCell: overwriting existing cell" ); +/*N*/ pNewCell = pCell; +/*N*/ ScChangeActionContent::SetCell( aNewValue, pNewCell, 0, pDoc ); +/*N*/ } + +/*N*/ void ScChangeActionContent::GetOldString( String& rStr ) const +/*N*/ { +/*N*/ GetValueString( rStr, aOldValue, pOldCell ); +/*N*/ } + + +/*N*/ void ScChangeActionContent::GetNewString( String& rStr ) const +/*N*/ { +/*N*/ GetValueString( rStr, aNewValue, pNewCell ); +/*N*/ } + + +/*N*/ void ScChangeActionContent::GetDescription( String& rStr, ScDocument* pDoc, +/*N*/ BOOL bSplitRange ) const +/*N*/ { +/*N*/ +/*N*/ String aRsc( ScGlobal::GetRscString( STR_CHANGED_CELL ) ); +/*N*/ +/*N*/ String aTmpStr; +/*N*/ GetRefString( aTmpStr, pDoc ); +/*N*/ +/*N*/ xub_StrLen nPos = 0; +/*N*/ nPos = aRsc.SearchAscii( "#1", nPos ); +/*N*/ aRsc.Erase( nPos, 2 ); +/*N*/ aRsc.Insert( aTmpStr, nPos ); +/*N*/ nPos += aTmpStr.Len(); +/*N*/ +/*N*/ GetOldString( aTmpStr ); +/*N*/ if ( !aTmpStr.Len() ) +/*N*/ aTmpStr = ScGlobal::GetRscString( STR_CHANGED_BLANK ); +/*N*/ nPos = aRsc.SearchAscii( "#2", nPos ); +/*N*/ aRsc.Erase( nPos, 2 ); +/*N*/ aRsc.Insert( aTmpStr, nPos ); +/*N*/ nPos += aTmpStr.Len(); +/*N*/ +/*N*/ GetNewString( aTmpStr ); +/*N*/ if ( !aTmpStr.Len() ) +/*N*/ aTmpStr = ScGlobal::GetRscString( STR_CHANGED_BLANK ); +/*N*/ nPos = aRsc.SearchAscii( "#3", nPos ); +/*N*/ aRsc.Erase( nPos, 2 ); +/*N*/ aRsc.Insert( aTmpStr, nPos ); +/*N*/ +/*N*/ rStr += aRsc; +/*N*/ } + + +/*N*/ void ScChangeActionContent::GetRefString( String& rStr, ScDocument* pDoc, +/*N*/ BOOL bFlag3D ) const +/*N*/ { +/*N*/ USHORT nFlags = ( GetBigRange().IsValid( pDoc ) ? SCA_VALID : 0 ); +/*N*/ if ( nFlags ) +/*N*/ { +/*N*/ const ScBaseCell* pCell = GetNewCell(); +/*N*/ if ( ScChangeActionContent::GetContentCellType( pCell ) == SC_CACCT_MATORG ) +/*N*/ { +/*N*/ ScBigRange aBigRange( GetBigRange() ); +/*N*/ USHORT nC, nR; +/*N*/ ((const ScFormulaCell*)pCell)->GetMatColsRows( nC, nR ); +/*N*/ aBigRange.aEnd.IncCol( nC-1 ); +/*N*/ aBigRange.aEnd.IncRow( nR-1 ); +/*N*/ rStr = ScChangeAction::GetRefString( aBigRange, pDoc, bFlag3D ); +/*N*/ +/*N*/ return ; +/*N*/ } +/*N*/ +/*N*/ ScAddress aTmpAddress( GetBigRange().aStart.MakeAddress() ); +/*N*/ if ( bFlag3D ) +/*N*/ nFlags |= SCA_TAB_3D; +/*N*/ aTmpAddress.Format( rStr, nFlags, pDoc ); +/*N*/ if ( IsDeletedIn() ) +/*N*/ { +/*N*/ rStr.Insert( '(', 0 ); +/*N*/ rStr += ')'; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ rStr = ScGlobal::GetRscString( STR_NOREF_STR ); +/*N*/ } + + +/*N*/ BOOL ScChangeActionContent::Reject( ScDocument* pDoc ) +/*N*/ { +/*N*/ if ( !aBigRange.IsValid( pDoc ) ) +/*N*/ return FALSE; +/*N*/ +/*N*/ PutOldValueToDoc( pDoc, 0, 0 ); +/*N*/ +/*N*/ SetState( SC_CAS_REJECTED ); +/*N*/ RemoveAllLinks(); +/*N*/ +/*N*/ return TRUE; +/*N*/ } + + +/*N*/ ScChangeActionContentCellType ScChangeActionContent::GetContentCellType( const ScBaseCell* pCell ) +/*N*/ { +/*N*/ if ( pCell ) +/*N*/ { +/*N*/ switch ( pCell->GetCellType() ) +/*N*/ { +/*N*/ case CELLTYPE_VALUE : +/*N*/ case CELLTYPE_STRING : +/*N*/ case CELLTYPE_EDIT : +/*N*/ return SC_CACCT_NORMAL; +/*N*/ break; +/*N*/ case CELLTYPE_FORMULA : +/*N*/ switch ( ((const ScFormulaCell*)pCell)->GetMatrixFlag() ) +/*N*/ { +/*N*/ case MM_NONE : +/*N*/ return SC_CACCT_NORMAL; +/*N*/ break; +/*N*/ case MM_FORMULA : +/*N*/ case MM_FAKE : +/*N*/ return SC_CACCT_MATORG; +/*N*/ break; +/*N*/ case MM_REFERENCE : +/*N*/ return SC_CACCT_MATREF; +/*N*/ break; +/*N*/ } +/*N*/ return SC_CACCT_NORMAL; +/*N*/ break; +/*N*/ default: +/*N*/ return SC_CACCT_NONE; +/*N*/ } +/*N*/ } +/*N*/ return SC_CACCT_NONE; +/*N*/ } + + +// static +/*N*/ BOOL ScChangeActionContent::NeedsNumberFormat( const ScBaseCell* pCell ) +/*N*/ { +/*N*/ return pCell && pCell->GetCellType() == CELLTYPE_VALUE; +/*N*/ } + + +// static +/*N*/ void ScChangeActionContent::SetValue( String& rStr, ScBaseCell*& pCell, +/*N*/ const ScAddress& rPos, const ScBaseCell* pOrgCell, +/*N*/ const ScDocument* pFromDoc, ScDocument* pToDoc ) +/*N*/ { +/*N*/ if ( ScChangeActionContent::NeedsNumberFormat( pOrgCell ) ) +/*N*/ ScChangeActionContent::SetValue( rStr, pCell, +/*N*/ pFromDoc->GetNumberFormat( rPos ), pOrgCell, pFromDoc, pToDoc ); +/*N*/ else +/*N*/ ScChangeActionContent::SetValue( rStr, pCell, +/*N*/ 0, pOrgCell, pFromDoc, pToDoc ); +/*N*/ } + + +// static +/*N*/ void ScChangeActionContent::SetValue( String& rStr, ScBaseCell*& pCell, +/*N*/ ULONG nFormat, const ScBaseCell* pOrgCell, +/*N*/ const ScDocument* pFromDoc, ScDocument* pToDoc ) +/*N*/ { +/*N*/ rStr.Erase(); +/*N*/ if ( pCell ) +/*N*/ pCell->Delete(); +/*N*/ if ( ScChangeActionContent::GetContentCellType( pOrgCell ) ) +/*N*/ { +/*N*/ pCell = pOrgCell->Clone( pToDoc ); +/*N*/ switch ( pOrgCell->GetCellType() ) +/*N*/ { +/*N*/ case CELLTYPE_VALUE : +/*N*/ { // z.B. Datum auch als solches merken +/*N*/ double nValue = ((ScValueCell*)pOrgCell)->GetValue(); +/*N*/ pFromDoc->GetFormatTable()->GetInputLineString( nValue, +/*N*/ nFormat, rStr ); +/*N*/ } +/*N*/ break; +/*N*/ case CELLTYPE_FORMULA : +/*N*/ ((ScFormulaCell*)pCell)->SetInChangeTrack( TRUE ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ pCell = NULL; +/*N*/ } + + +// static +/*N*/ void ScChangeActionContent::SetCell( String& rStr, ScBaseCell* pCell, +/*N*/ ULONG nFormat, const ScDocument* pDoc ) +/*N*/ { +/*N*/ rStr.Erase(); +/*N*/ if ( pCell ) +/*N*/ { +/*N*/ switch ( pCell->GetCellType() ) +/*N*/ { +/*N*/ case CELLTYPE_VALUE : +/*N*/ { // e.g. remember date as date string +/*N*/ double nValue = ((ScValueCell*)pCell)->GetValue(); +/*N*/ pDoc->GetFormatTable()->GetInputLineString( nValue, +/*N*/ nFormat, rStr ); +/*N*/ } +/*N*/ break; +/*N*/ case CELLTYPE_FORMULA : +/*N*/ ((ScFormulaCell*)pCell)->SetInChangeTrack( TRUE ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } + + +/*N*/ void ScChangeActionContent::GetValueString( String& rStr, +/*N*/ const String& rValue, const ScBaseCell* pCell ) const +/*N*/ { +/*N*/ if ( !rValue.Len() ) +/*N*/ { +/*N*/ if ( pCell ) +/*N*/ { +/*N*/ switch ( pCell->GetCellType() ) +/*N*/ { +/*N*/ case CELLTYPE_STRING : +/*N*/ ((ScStringCell*)pCell)->GetString( rStr ); +/*N*/ break; +/*N*/ case CELLTYPE_EDIT : +/*N*/ ((ScEditCell*)pCell)->GetString( rStr ); +/*N*/ break; +/*N*/ case CELLTYPE_VALUE : // ist immer in rValue +/*N*/ rStr = rValue; +/*N*/ break; +/*N*/ case CELLTYPE_FORMULA : +/*N*/ GetFormulaString( rStr, (ScFormulaCell*) pCell ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ rStr.Erase(); +/*N*/ } +/*N*/ else +/*N*/ rStr = rValue; +/*N*/ } + + +/*N*/ void ScChangeActionContent::GetFormulaString( String& rStr, +/*N*/ const ScFormulaCell* pCell ) const +/*N*/ { +/*N*/ ScAddress aPos( aBigRange.aStart.MakeAddress() ); +/*N*/ if ( aPos == pCell->aPos || IsDeletedIn() ) +/*N*/ pCell->GetFormula( rStr ); +/*N*/ else +/*N*/ { +/*N*/ DBG_ERROR( "ScChangeActionContent::GetFormulaString: aPos != pCell->aPos" ); +/*N*/ ScFormulaCell* pNew = (ScFormulaCell*) pCell->Clone( +/*N*/ pCell->GetDocument(), aPos, TRUE ); // TRUE: bNoListening +/*N*/ pNew->GetFormula( rStr ); +/*N*/ delete pNew; +/*N*/ } +/*N*/ } + + +/*N*/ void ScChangeActionContent::PutOldValueToDoc( ScDocument* pDoc, +/*N*/ short nDx, short nDy ) const +/*N*/ { +/*N*/ PutValueToDoc( pOldCell, aOldValue, pDoc, nDx, nDy ); +/*N*/ } + + +/*N*/ void ScChangeActionContent::PutNewValueToDoc( ScDocument* pDoc, +/*N*/ short nDx, short nDy ) const +/*N*/ { +/*N*/ PutValueToDoc( pNewCell, aNewValue, pDoc, nDx, nDy ); +/*N*/ } + + +/*N*/ void ScChangeActionContent::PutValueToDoc( ScBaseCell* pCell, +/*N*/ const String& rValue, ScDocument* pDoc, short nDx, short nDy ) const +/*N*/ { +/*N*/ ScAddress aPos( aBigRange.aStart.MakeAddress() ); +/*N*/ if ( nDx ) +/*N*/ aPos.IncCol( nDx ); +/*N*/ if ( nDy ) +/*N*/ aPos.IncRow( nDy ); +/*N*/ if ( !rValue.Len() ) +/*N*/ { +/*N*/ if ( pCell ) +/*N*/ { +/*N*/ switch ( pCell->GetCellType() ) +/*N*/ { +/*N*/ case CELLTYPE_VALUE : // ist immer in rValue +/*N*/ pDoc->SetString( aPos.Col(), aPos.Row(), aPos.Tab(), rValue ); +/*N*/ break; +/*N*/ default: +/*N*/ switch ( ScChangeActionContent::GetContentCellType( pCell ) ) +/*N*/ { +/*N*/ case SC_CACCT_MATORG : +/*N*/ { +/*N*/ USHORT nC, nR; +/*N*/ ((const ScFormulaCell*)pCell)->GetMatColsRows( nC, nR ); +/*N*/ DBG_ASSERT( nC>0 && nR>0, "ScChangeActionContent::PutValueToDoc: MatColsRows?" ); +/*N*/ ScRange aRange( aPos ); +/*N*/ if ( nC > 1 ) +/*N*/ aRange.aEnd.IncCol( nC-1 ); +/*N*/ if ( nR > 1 ) +/*N*/ aRange.aEnd.IncRow( nR-1 ); +/*N*/ ScMarkData aDestMark; +/*N*/ aDestMark.SelectOneTable( aPos.Tab() ); +/*N*/ aDestMark.SetMarkArea( aRange ); +/*N*/ pDoc->InsertMatrixFormula( aPos.Col(), aPos.Row(), +/*N*/ aRange.aEnd.Col(), aRange.aEnd.Row(), +/*N*/ aDestMark, EMPTY_STRING, +/*N*/ ((const ScFormulaCell*)pCell)->GetCode() ); +/*N*/ } +/*N*/ break; +/*N*/ case SC_CACCT_MATREF : +/*N*/ // nothing +/*N*/ break; +/*N*/ default: +/*N*/ pDoc->PutCell( aPos, pCell->Clone( pDoc ) ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ pDoc->PutCell( aPos, NULL ); +/*N*/ } +/*N*/ else +/*N*/ pDoc->SetString( aPos.Col(), aPos.Row(), aPos.Tab(), rValue ); +/*N*/ } + + +/*N*/ void lcl_InvalidateReference( ScToken& rTok, const ScBigAddress& rPos ) +/*N*/ { +/*N*/ SingleRefData& rRef1 = rTok.GetSingleRef(); +/*N*/ if ( rPos.Col() < 0 || MAXCOL < rPos.Col() ) +/*N*/ { +/*N*/ rRef1.nCol = (INT16)(~0); +/*N*/ rRef1.nRelCol = (INT16)(~0); +/*N*/ rRef1.SetColDeleted( TRUE ); +/*N*/ } +/*N*/ if ( rPos.Row() < 0 || MAXROW < rPos.Row() ) +/*N*/ { +/*N*/ rRef1.nRow = (INT16)(~0); +/*N*/ rRef1.nRelRow = (INT16)(~0); +/*N*/ rRef1.SetRowDeleted( TRUE ); +/*N*/ } +/*N*/ if ( rPos.Tab() < 0 || MAXTAB < rPos.Tab() ) +/*N*/ { +/*N*/ rRef1.nTab = (INT16)(~0); +/*N*/ rRef1.nRelTab = (INT16)(~0); +/*N*/ rRef1.SetTabDeleted( TRUE ); +/*N*/ } +/*N*/ if ( rTok.GetType() == svDoubleRef ) +/*N*/ { +/*N*/ SingleRefData& rRef2 = rTok.GetDoubleRef().Ref2; +/*N*/ if ( rPos.Col() < 0 || MAXCOL < rPos.Col() ) +/*N*/ { +/*N*/ rRef2.nCol = (INT16)(~0); +/*N*/ rRef2.nRelCol = (INT16)(~0); +/*N*/ rRef2.SetColDeleted( TRUE ); +/*N*/ } +/*N*/ if ( rPos.Row() < 0 || MAXROW < rPos.Row() ) +/*N*/ { +/*N*/ rRef2.nRow = (INT16)(~0); +/*N*/ rRef2.nRelRow = (INT16)(~0); +/*N*/ rRef2.SetRowDeleted( TRUE ); +/*N*/ } +/*N*/ if ( rPos.Tab() < 0 || MAXTAB < rPos.Tab() ) +/*N*/ { +/*N*/ rRef2.nTab = (INT16)(~0); +/*N*/ rRef2.nRelTab = (INT16)(~0); +/*N*/ rRef2.SetTabDeleted( TRUE ); +/*N*/ } +/*N*/ } +/*N*/ } + + +/*N*/ void ScChangeActionContent::UpdateReference( const ScChangeTrack* pTrack, +/*N*/ UpdateRefMode eMode, const ScBigRange& rRange, +/*N*/ INT32 nDx, INT32 nDy, INT32 nDz ) +/*N*/ { +/*N*/ USHORT nOldSlot = ScChangeTrack::ComputeContentSlot( aBigRange.aStart.Row() ); +/*N*/ ScRefUpdate::Update( eMode, rRange, nDx, nDy, nDz, aBigRange ); +/*N*/ USHORT nNewSlot = ScChangeTrack::ComputeContentSlot( aBigRange.aStart.Row() ); +/*N*/ if ( nNewSlot != nOldSlot ) +/*N*/ { +/*N*/ RemoveFromSlot(); +/*N*/ InsertInSlot( &(pTrack->GetContentSlots()[nNewSlot]) ); +/*N*/ } +/*N*/ +/*N*/ if ( pTrack->IsInDelete() && !pTrack->IsInDeleteTop() ) +/*N*/ return ; // Formeln nur kompletten Bereich updaten +/*N*/ +/*N*/ BOOL bOldFormula = ( pOldCell && pOldCell->GetCellType() == CELLTYPE_FORMULA ); +/*N*/ BOOL bNewFormula = ( pNewCell && pNewCell->GetCellType() == CELLTYPE_FORMULA ); +/*N*/ if ( bOldFormula || bNewFormula ) +/*N*/ { // via ScFormulaCell UpdateReference anpassen (dort) +/*N*/ if ( pTrack->IsInDelete() ) +/*N*/ { +/*N*/ const ScRange& rDelRange = pTrack->GetInDeleteRange(); +/*N*/ if ( nDx > 0 ) +/*N*/ nDx = rDelRange.aEnd.Col() - rDelRange.aStart.Col() + 1; +/*N*/ else if ( nDx < 0 ) +/*N*/ nDx = -(rDelRange.aEnd.Col() - rDelRange.aStart.Col() + 1); +/*N*/ if ( nDy > 0 ) +/*N*/ nDy = rDelRange.aEnd.Row() - rDelRange.aStart.Row() + 1; +/*N*/ else if ( nDy < 0 ) +/*N*/ nDy = -(rDelRange.aEnd.Row() - rDelRange.aStart.Row() + 1); +/*N*/ if ( nDz > 0 ) +/*N*/ nDz = rDelRange.aEnd.Tab() - rDelRange.aStart.Tab() + 1; +/*N*/ else if ( nDz < 0 ) +/*N*/ nDz = -(rDelRange.aEnd.Tab() - rDelRange.aStart.Tab() + 1); +/*N*/ } +/*N*/ ScBigRange aTmpRange( rRange ); +/*N*/ switch ( eMode ) +/*N*/ { +/*N*/ case URM_INSDEL : +/*N*/ if ( nDx < 0 || nDy < 0 || nDz < 0 ) +/*N*/ { // Delete startet dort hinter geloeschtem Bereich, +/*N*/ // Position wird dort angepasst. +/*N*/ if ( nDx ) +/*N*/ aTmpRange.aStart.IncCol( -nDx ); +/*N*/ if ( nDy ) +/*N*/ aTmpRange.aStart.IncRow( -nDy ); +/*N*/ if ( nDz ) +/*N*/ aTmpRange.aStart.IncTab( -nDz ); +/*N*/ } +/*N*/ break; +/*N*/ case URM_MOVE : +/*N*/ // Move ist hier Quelle, dort Ziel, +/*N*/ // Position muss vorher angepasst sein. +/*N*/ if ( bOldFormula ) +/*N*/ ((ScFormulaCell*)pOldCell)->aPos = aBigRange.aStart.MakeAddress(); +/*N*/ if ( bNewFormula ) +/*N*/ ((ScFormulaCell*)pNewCell)->aPos = aBigRange.aStart.MakeAddress(); +/*N*/ if ( nDx ) +/*N*/ { +/*N*/ aTmpRange.aStart.IncCol( nDx ); +/*N*/ aTmpRange.aEnd.IncCol( nDx ); +/*N*/ } +/*N*/ if ( nDy ) +/*N*/ { +/*N*/ aTmpRange.aStart.IncRow( nDy ); +/*N*/ aTmpRange.aEnd.IncRow( nDy ); +/*N*/ } +/*N*/ if ( nDz ) +/*N*/ { +/*N*/ aTmpRange.aStart.IncTab( nDz ); +/*N*/ aTmpRange.aEnd.IncTab( nDz ); +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ ScRange aRange( aTmpRange.MakeRange() ); +/*N*/ if ( bOldFormula ) +/*N*/ ((ScFormulaCell*)pOldCell)->UpdateReference( eMode, aRange, +/*N*/ (short) nDx, (short) nDy, (short) nDz, NULL ); +/*N*/ if ( bNewFormula ) +/*N*/ ((ScFormulaCell*)pNewCell)->UpdateReference( eMode, aRange, +/*N*/ (short) nDx, (short) nDy, (short) nDz, NULL ); +/*N*/ if ( !aBigRange.aStart.IsValid( pTrack->GetDocument() ) ) +/*N*/ { //! HACK! +/*N*/ //! UpdateReference kann nicht mit Positionen ausserhalb des +/*N*/ //! Dokuments umgehen, deswegen alles auf #REF! setzen +/*N*/ //2do: make it possible! das bedeutet grossen Umbau von ScAddress etc.! +/*N*/ const ScBigAddress& rPos = aBigRange.aStart; +/*N*/ if ( bOldFormula ) +/*N*/ { +/*N*/ ScToken* t; +/*N*/ ScTokenArray* pArr = ((ScFormulaCell*)pOldCell)->GetCode(); +/*N*/ pArr->Reset(); +/*N*/ while ( t = pArr->GetNextReference() ) +/*N*/ lcl_InvalidateReference( *t, rPos ); +/*N*/ pArr->Reset(); +/*N*/ while ( t = pArr->GetNextReferenceRPN() ) +/*N*/ lcl_InvalidateReference( *t, rPos ); +/*N*/ } +/*N*/ if ( bNewFormula ) +/*N*/ { +/*N*/ ScToken* t; +/*N*/ ScTokenArray* pArr = ((ScFormulaCell*)pNewCell)->GetCode(); +/*N*/ pArr->Reset(); +/*N*/ while ( t = pArr->GetNextReference() ) +/*N*/ lcl_InvalidateReference( *t, rPos ); +/*N*/ pArr->Reset(); +/*N*/ while ( t = pArr->GetNextReferenceRPN() ) +/*N*/ lcl_InvalidateReference( *t, rPos ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + + +// --- ScChangeActionReject ------------------------------------------------ + +/*N*/ ScChangeActionReject::ScChangeActionReject( SvStream& rStrm, +/*N*/ ScMultipleReadHeader& rHdr, ScChangeTrack* pTrack ) +/*N*/ : +/*N*/ ScChangeAction( rStrm, rHdr, pTrack ) +/*N*/ { +/*N*/ } + +/*N*/ ScChangeActionReject::ScChangeActionReject(const ULONG nActionNumber, const ScChangeActionState eState, const ULONG nRejectingNumber, +/*N*/ const ScBigRange& aBigRange, const String& aUser, const DateTime& aDateTime, const String& sComment) +/*N*/ : +/*N*/ ScChangeAction(SC_CAT_CONTENT, aBigRange, nActionNumber, nRejectingNumber, eState, aDateTime, aUser, sComment) +/*N*/ { +/*N*/ } + +/*N*/ BOOL ScChangeActionReject::Store( SvStream& rStrm, ScMultipleWriteHeader& rHdr ) const +/*N*/ { +/*N*/ BOOL bOk = ScChangeAction::Store( rStrm, rHdr ); +/*N*/ return TRUE; +/*N*/ } + + +// --- ScChangeTrack ------------------------------------------------------- + +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( ScChangeTrackMsgInfo, 16, 16 )//STRIP008 ; + +const USHORT ScChangeTrack::nContentRowsPerSlot = InitContentRowsPerSlot(); +const USHORT ScChangeTrack::nContentSlots = + (MAXROW+1) / InitContentRowsPerSlot() + 2; + +// static +/*N*/ USHORT ScChangeTrack::InitContentRowsPerSlot() +/*N*/ { +/*N*/ const USHORT nMaxSlots = 0xffe0 / sizeof( ScChangeActionContent* ) - 2; +/*N*/ USHORT nRowsPerSlot = (MAXROW+1) / nMaxSlots; +/*N*/ if ( nRowsPerSlot * nMaxSlots < (MAXROW+1) ) +/*N*/ ++nRowsPerSlot; +/*N*/ return nRowsPerSlot; +/*N*/ } + + +/*N*/ ScChangeTrack::ScChangeTrack( ScDocument* pDocP ) : // Changetracking.sdc +/*N*/ pDoc( pDocP ) +/*N*/ { +/*N*/ Init(); +/*N*/ StartListening( *SfxGetpApp() ); +/*N*/ ppContentSlots = new ScChangeActionContent* [ nContentSlots ]; +/*N*/ memset( ppContentSlots, 0, nContentSlots * sizeof( ScChangeActionContent* ) ); +/*N*/ } + +/*N*/ ScChangeTrack::ScChangeTrack( ScDocument* pDocP, const StrCollection& aTempUserCollection) : +/*N*/ pDoc( pDocP ), +/*N*/ aUserCollection(aTempUserCollection) +/*N*/ { +/*N*/ Init(); +/*N*/ StartListening( *SfxGetpApp() ); +/*N*/ ppContentSlots = new ScChangeActionContent* [ nContentSlots ]; +/*N*/ memset( ppContentSlots, 0, nContentSlots * sizeof( ScChangeActionContent* ) ); +/*N*/ } + +/*N*/ ScChangeTrack::~ScChangeTrack() // Changetracking.sdc +/*N*/ { +/*N*/ DtorClear(); +/*N*/ delete [] ppContentSlots; +/*N*/ } + + +/*N*/ void ScChangeTrack::Init() // Changetracking.sdc +/*N*/ { +/*N*/ pFirst = NULL; +/*N*/ pLast = NULL; +/*N*/ pFirstGeneratedDelContent = NULL; +/*N*/ pLastCutMove = NULL; +/*N*/ pLinkInsertCol = NULL; +/*N*/ pLinkInsertRow = NULL; +/*N*/ pLinkInsertTab = NULL; +/*N*/ pLinkMove = NULL; +/*N*/ pBlockModifyMsg = NULL; +/*N*/ nActionMax = 0; +/*N*/ nGeneratedMin = SC_CHGTRACK_GENERATED_START; +/*N*/ nMarkLastSaved = 0; +/*N*/ nStartLastCut = 0; +/*N*/ nEndLastCut = 0; +/*N*/ nLastMerge = 0; +/*N*/ eMergeState = SC_CTMS_NONE; +/*N*/ nLoadedFileFormatVersion = SC_CHGTRACK_FILEFORMAT; +/*N*/ bLoadSave = FALSE; +/*N*/ bInDelete = FALSE; +/*N*/ bInDeleteTop = FALSE; +/*N*/ bInDeleteUndo = FALSE; +/*N*/ bInPasteCut = FALSE; +/*N*/ bUseFixDateTime = FALSE; +/*N*/ bTime100thSeconds = TRUE; +/*N*/ +/*N*/ SvtUserOptions aUserOpt; +/*N*/ aUser = aUserOpt.GetFirstName(); +/*N*/ aUser += ' '; +/*N*/ aUser += aUserOpt.GetLastName(); +/*N*/ aUserCollection.Insert( new StrData( aUser ) ); +/*N*/ } + + +/*N*/ void ScChangeTrack::DtorClear() // Changetracking.sdc +/*N*/ { +/*N*/ ScChangeAction* p; +/*N*/ ScChangeAction* pNext; +/*N*/ for ( p = GetFirst(); p; p = pNext ) +/*N*/ { +/*N*/ pNext = p->GetNext(); +/*N*/ delete p; +/*N*/ } +/*N*/ for ( p = pFirstGeneratedDelContent; p; p = pNext ) +/*N*/ { +/*N*/ pNext = p->GetNext(); +/*N*/ delete p; +/*N*/ } +/*N*/ for ( p = aPasteCutTable.First(); p; p = aPasteCutTable.Next() ) +/*N*/ { +/*N*/ delete p; +/*N*/ } +/*N*/ delete pLastCutMove; +/*N*/ ClearMsgQueue(); +/*N*/ } + + +/*N*/ void ScChangeTrack::ClearMsgQueue() // Changetracking.sdc +/*N*/ { +/*N*/ if ( pBlockModifyMsg ) +/*N*/ { +/*N*/ delete pBlockModifyMsg; +/*N*/ pBlockModifyMsg = NULL; +/*N*/ } +/*N*/ ScChangeTrackMsgInfo* pMsgInfo; +/*N*/ while ( pMsgInfo = aMsgStackTmp.Pop() ) +/*N*/ delete pMsgInfo; +/*N*/ while ( pMsgInfo = aMsgStackFinal.Pop() ) +/*N*/ delete pMsgInfo; +/*N*/ while ( pMsgInfo = aMsgQueue.Get() ) +/*N*/ delete pMsgInfo; +/*N*/ } + + +/*N*/ void ScChangeTrack::Clear() // Changetracking.sdc +/*N*/ { +/*N*/ DtorClear(); +/*N*/ aTable.Clear(); +/*N*/ aGeneratedTable.Clear(); +/*N*/ aPasteCutTable.Clear(); +/*N*/ aUserCollection.FreeAll(); +/*N*/ aUser.Erase(); +/*N*/ Init(); +/*N*/ } + + +/*N*/ void __EXPORT ScChangeTrack::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) +/*N*/ { +/*N*/ if ( !pDoc->IsInDtorClear() ) +/*N*/ { +/*N*/ const SfxItemSetHint* pHint = PTR_CAST( SfxItemSetHint, &rHint ); +/*N*/ if ( pHint ) +/*N*/ { +/*N*/ const SfxItemSet& rSet = pHint->GetItemSet(); +/*N*/ const SfxPoolItem* pItem; +/*N*/ if ( rSet.GetItemState( +/*N*/ rSet.GetPool()->GetWhich( SID_ATTR_ADDRESS ), +/*N*/ TRUE, &pItem ) == SFX_ITEM_SET ) +/*N*/ { +/*N*/ USHORT nOldCount = aUserCollection.GetCount(); +/*N*/ +/*N*/ String aStr( ((SvxAddressItem*)pItem)->GetFirstName() ); +/*N*/ aStr += ' '; +/*N*/ aStr += ((SvxAddressItem*)pItem)->GetName(); +/*N*/ SetUser( aStr ); +/*N*/ +/*N*/ if ( aUserCollection.GetCount() != nOldCount ) +/*N*/ { +/*N*/ // New user in collection -> have to repaint because +/*N*/ // colors may be different now (#106697#). +/*N*/ // (Has to be done in the Notify handler, to be sure +/*N*/ // the user collection has already been updated) +/*N*/ +/*N*/ SfxObjectShell* pDocSh = pDoc->GetDocumentShell(); +/*N*/ if (pDocSh) +/*N*/ pDocSh->Broadcast( ScPaintHint( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB), PAINT_GRID ) ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + + +/*N*/ void ScChangeTrack::SetUser( const String& rUser ) // Changetracking.sdc +/*N*/ { +/*N*/ if ( IsLoadSave() ) +/*N*/ return ; // nicht die Collection zerschiessen +/*N*/ +/*N*/ aUser = rUser; +/*N*/ StrData* pStrData = new StrData( aUser ); +/*N*/ if ( !aUserCollection.Insert( pStrData ) ) +/*N*/ delete pStrData; +/*N*/ } + + +/*N*/ void ScChangeTrack::StartBlockModify( ScChangeTrackMsgType eMsgType, +/*N*/ ULONG nStartAction ) +/*N*/ { +/*N*/ if ( aModifiedLink.IsSet() ) +/*N*/ { +/*N*/ if ( pBlockModifyMsg ) +/*N*/ aMsgStackTmp.Push( pBlockModifyMsg ); // Block im Block +/*N*/ pBlockModifyMsg = new ScChangeTrackMsgInfo; +/*N*/ pBlockModifyMsg->eMsgType = eMsgType; +/*N*/ pBlockModifyMsg->nStartAction = nStartAction; +/*N*/ } +/*N*/ } + + +/*N*/ void ScChangeTrack::EndBlockModify( ULONG nEndAction ) +/*N*/ { +/*N*/ if ( aModifiedLink.IsSet() ) +/*N*/ { +/*N*/ if ( pBlockModifyMsg ) +/*N*/ { +/*N*/ if ( pBlockModifyMsg->nStartAction <= nEndAction ) +/*N*/ { +/*N*/ pBlockModifyMsg->nEndAction = nEndAction; +/*N*/ // Blocks in Blocks aufgeloest +/*N*/ aMsgStackFinal.Push( pBlockModifyMsg ); +/*N*/ } +/*N*/ else +/*N*/ delete pBlockModifyMsg; +/*N*/ pBlockModifyMsg = aMsgStackTmp.Pop(); // evtl. Block im Block +/*N*/ } +/*N*/ if ( !pBlockModifyMsg ) +/*N*/ { +/*N*/ BOOL bNew = FALSE; +/*N*/ ScChangeTrackMsgInfo* pMsg; +/*N*/ while ( pMsg = aMsgStackFinal.Pop() ) +/*N*/ { +/*N*/ aMsgQueue.Put( pMsg ); +/*N*/ bNew = TRUE; +/*N*/ } +/*N*/ if ( bNew ) +/*N*/ aModifiedLink.Call( this ); +/*N*/ } +/*N*/ } +/*N*/ } + + +/*N*/ void ScChangeTrack::NotifyModified( ScChangeTrackMsgType eMsgType, +/*N*/ ULONG nStartAction, ULONG nEndAction ) +/*N*/ { +/*N*/ if ( aModifiedLink.IsSet() ) +/*N*/ { +/*N*/ if ( !pBlockModifyMsg || pBlockModifyMsg->eMsgType != eMsgType || +/*N*/ (IsGenerated( nStartAction ) && +/*N*/ (eMsgType == SC_CTM_APPEND || eMsgType == SC_CTM_REMOVE)) ) +/*N*/ { // Append innerhalb von Append z.B. nicht +/*N*/ StartBlockModify( eMsgType, nStartAction ); +/*N*/ EndBlockModify( nEndAction ); +/*N*/ } +/*N*/ } +/*N*/ } + + +/*N*/ void lcl_EnsureSorting( StrCollection& rCollection ) // Changetracking.sdc +/*N*/ { +/*N*/ BOOL bSorted = TRUE; +/*N*/ USHORT nCount = rCollection.GetCount(); +/*N*/ USHORT i; +/*N*/ for (i=0; i+1<nCount; i++) +/*N*/ if ( rCollection.Compare( rCollection[i], rCollection[i+1] ) != -1 ) +/*N*/ bSorted = FALSE; +/*N*/ +/*N*/ if ( !bSorted ) +/*N*/ { +/*N*/ // if not sorted, rebuild collection +/*N*/ StrCollection aNewColl; +/*N*/ for (i=0; i<nCount; i++) +/*N*/ { +/*N*/ DataObject* pNewObj = rCollection[i]->Clone(); +/*N*/ if (!aNewColl.Insert(pNewObj)) +/*N*/ delete pNewObj; +/*N*/ } +/*N*/ rCollection = aNewColl; +/*N*/ } +/*N*/ } + + +/*N*/ BOOL ScChangeTrack::Load( SvStream& rStrm, USHORT nVer ) // Changetracking.sdc +/*N*/ { +/*N*/ BOOL bOk = TRUE; +/*N*/ SetLoadSave( TRUE ); +/*N*/ +/*N*/ ScReadHeader aGlobalHdr( rStrm ); +/*N*/ +/*N*/ BYTE n8; +/*N*/ UINT16 n16; +/*N*/ UINT32 n32; +/*N*/ +/*N*/ rStrm >> n16; nLoadedFileFormatVersion = n16; +/*N*/ if ( (nLoadedFileFormatVersion & 0xFF00) > (SC_CHGTRACK_FILEFORMAT & 0xFF00) ) +/*N*/ { // inkompatible neuere Version +/*N*/ Clear(); +/*N*/ rStrm.SetError( SCWARN_IMPORT_INFOLOST ); +/*N*/ return FALSE; +/*N*/ } +/*N*/ +/*N*/ aUserCollection.Load( rStrm ); +/*N*/ +/*N*/ ULONG nCount, nLastAction, nGeneratedCount; +/*N*/ rStrm >> n32; nCount = n32; +/*N*/ rStrm >> n32; nActionMax = n32; +/*N*/ rStrm >> n32; nLastAction = n32; +/*N*/ +/*N*/ rStrm >> n32; nGeneratedCount = n32; +/*N*/ +/*N*/ // GeneratedDelContents laden +/*N*/ { +/*N*/ ScMultipleReadHeader aHdr( rStrm ); +/*N*/ for ( ULONG j = 0; j < nGeneratedCount && bOk; j++ ) +/*N*/ { +/*N*/ ScChangeActionContent* pAct; +/*N*/ +/*N*/ aHdr.StartEntry(); +/*N*/ +/*N*/ ScChangeActionType eType; +/*N*/ rStrm >> n8; eType = (ScChangeActionType) n8; +/*N*/ +/*N*/ switch ( eType ) +/*N*/ { +/*N*/ case SC_CAT_CONTENT : +/*N*/ pAct = new ScChangeActionContent( rStrm, aHdr, pDoc, nVer, this ); +/*N*/ break; +/*N*/ default: +/*N*/ DBG_ERROR( "ScChangeTrack::Load: unknown GeneratedType" ); +/*N*/ pAct = NULL; +/*N*/ bOk = FALSE; +/*N*/ } +/*N*/ +/*N*/ aHdr.EndEntry(); +/*N*/ +/*N*/ if ( pAct ) +/*N*/ { +/*N*/ pAct->SetType( eType ); +/*N*/ if ( pFirstGeneratedDelContent ) +/*N*/ pFirstGeneratedDelContent->pPrev = pAct; +/*N*/ pAct->pNext = pFirstGeneratedDelContent; +/*N*/ pFirstGeneratedDelContent = pAct; +/*N*/ aGeneratedTable.Insert( pAct->GetActionNumber(), pAct ); +/*N*/ } +/*N*/ } +/*N*/ rStrm >> n32; nGeneratedMin = n32; +/*N*/ } +/*N*/ +/*N*/ if ( bOk ) +/*N*/ bOk = ( nGeneratedCount == aGeneratedTable.Count() ); +/*N*/ DBG_ASSERT( bOk, "ScChangeTrack::Load: Generated failed" ); +/*N*/ +/*N*/ +/*N*/ // erste Runde: Actions laden +/*N*/ { +/*N*/ ScMultipleReadHeader aHdr( rStrm ); +/*N*/ for ( ULONG j = 0; j < nCount && bOk; j++ ) +/*N*/ { +/*N*/ ScChangeAction* pAct; +/*N*/ +/*N*/ aHdr.StartEntry(); +/*N*/ +/*N*/ USHORT nUserIndex; +/*N*/ rStrm >> n16; nUserIndex = n16; +/*N*/ +/*N*/ ScChangeActionType eType; +/*N*/ rStrm >> n8; eType = (ScChangeActionType) n8; +/*N*/ +/*N*/ switch ( eType ) +/*N*/ { +/*N*/ case SC_CAT_INSERT_COLS : +/*N*/ case SC_CAT_INSERT_ROWS : +/*N*/ case SC_CAT_INSERT_TABS : +/*N*/ pAct = new ScChangeActionIns( rStrm, aHdr, this ); +/*N*/ break; +/*N*/ case SC_CAT_DELETE_COLS : +/*N*/ case SC_CAT_DELETE_ROWS : +/*N*/ case SC_CAT_DELETE_TABS : +/*N*/ pAct = new ScChangeActionDel( rStrm, aHdr, pDoc, nVer, this ); +/*N*/ break; +/*N*/ case SC_CAT_MOVE : +/*N*/ pAct = new ScChangeActionMove( rStrm, aHdr, this ); +/*N*/ break; +/*N*/ case SC_CAT_CONTENT : +/*N*/ pAct = new ScChangeActionContent( rStrm, aHdr, pDoc, nVer, this ); +/*N*/ break; +/*N*/ case SC_CAT_REJECT : +/*N*/ pAct = new ScChangeActionReject( rStrm, aHdr, this ); +/*N*/ break; +/*N*/ default: +/*N*/ DBG_ERROR( "ScChangeTrack::Load: unknown ScChangeActionType" ); +/*N*/ pAct = NULL; +/*N*/ bOk = FALSE; +/*N*/ } +/*N*/ +/*N*/ aHdr.EndEntry(); +/*N*/ +/*N*/ if ( pAct ) +/*N*/ { +/*N*/ pAct->SetType( eType ); +/*N*/ if ( nUserIndex != 0xffff ) +/*N*/ { +/*N*/ StrData* pUser = (StrData*) aUserCollection.At( nUserIndex ); +/*N*/ if ( pUser ) +/*N*/ pAct->SetUser( pUser->GetString() ); +/*N*/ } +/*N*/ AppendLoaded( pAct ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( pLast ) +/*N*/ nMarkLastSaved = pLast->GetActionNumber(); +/*N*/ +/*N*/ if ( bOk ) +/*N*/ bOk = ( nMarkLastSaved == nLastAction && nCount == aTable.Count() ); +/*N*/ DBG_ASSERT( bOk, "ScChangeTrack::Load: failed" ); +/*N*/ +/*N*/ // zweite Runde: Links laden und alles verpointern +/*N*/ { +/*N*/ ScMultipleReadHeader aHdr( rStrm ); +/*N*/ for ( ScChangeAction* p = GetFirst(); p && bOk; p = p->GetNext() ) +/*N*/ { +/*N*/ aHdr.StartEntry(); +/*N*/ bOk = p->LoadLinks( rStrm, this ); +/*N*/ aHdr.EndEntry(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ SetLoadSave( FALSE ); +/*N*/ +/*N*/ // versions between 583 and 633 had the sorting wrong -> correct (after loading the actions) +/*N*/ lcl_EnsureSorting( aUserCollection ); +/*N*/ +/*N*/ // den aktuellen User erst einfuegen, wenn die Actions bereits ihre User haben +/*N*/ SetUser( aUser ); +/*N*/ +/*N*/ if ( !bOk ) +/*N*/ { +/*N*/ Clear(); // eindeutiger Zustand +/*N*/ rStrm.SetError( SCWARN_IMPORT_INFOLOST ); +/*N*/ } +/*N*/ +/*N*/ return bOk; +/*N*/ } + + +/*N*/ BOOL ScChangeTrack::Store( SvStream& rStrm ) +/*N*/ { +/*N*/ BOOL bOk = TRUE; +/*N*/ SetLoadSave( TRUE ); +/*N*/ +/*N*/ ScWriteHeader aGlobalHdr( rStrm ); +/*N*/ +/*N*/ rStrm << (UINT16) SC_CHGTRACK_FILEFORMAT; +/*N*/ +/*N*/ aUserCollection.Store( rStrm ); +/*N*/ +/*N*/ ULONG nCount = aTable.Count(); +/*N*/ ULONG nLastAction = ( pLast ? pLast->GetActionNumber() : 0 ); +/*N*/ ULONG nGeneratedCount = aGeneratedTable.Count(); +/*N*/ rStrm << (UINT32) nCount << (UINT32) nActionMax << (UINT32) nLastAction; +/*N*/ rStrm << (UINT32) nGeneratedCount; +/*N*/ +/*N*/ // GeneratedDelContents speichern +/*N*/ ULONG nSave = 0; +/*N*/ { +/*N*/ ScMultipleWriteHeader aHdr( rStrm ); +/*N*/ ULONG nNewGeneratedMin = SC_CHGTRACK_GENERATED_START; +/*N*/ for ( ScChangeAction* p = pFirstGeneratedDelContent; p && bOk; +/*N*/ p = p->GetNext() ) +/*N*/ { +/*N*/ ++nSave; +/*N*/ aHdr.StartEntry(); +/*N*/ rStrm << (BYTE) p->GetType(); +/*N*/ bOk = p->Store( rStrm, aHdr ); +/*N*/ aHdr.EndEntry(); +/*N*/ ULONG nAct = p->GetActionNumber(); +/*N*/ if ( nNewGeneratedMin > nAct ) +/*N*/ nNewGeneratedMin = nAct; +/*N*/ } +/*N*/ nGeneratedMin = nNewGeneratedMin; // evtl. unbenutzten Bereich freigeben +/*N*/ rStrm << (UINT32) nGeneratedMin; +/*N*/ } +/*N*/ +/*N*/ if ( bOk ) +/*N*/ bOk = ( nGeneratedCount == nSave ); +/*N*/ DBG_ASSERT( bOk, "ScChangeTrack::Store: failed" ); +/*N*/ +/*N*/ // erste Runde: Actions speichern +/*N*/ nSave = 0; +/*N*/ { +/*N*/ ScMultipleWriteHeader aHdr( rStrm ); +/*N*/ StrData* pUserSearch = new StrData( aUser ); +/*N*/ USHORT nUserIndex; +/*N*/ for ( ScChangeAction* p = GetFirst(); p && bOk; p = p->GetNext() ) +/*N*/ { +/*N*/ ++nSave; +/*N*/ aHdr.StartEntry(); +/*N*/ +/*N*/ pUserSearch->SetString( p->GetUser() ); +/*N*/ if ( aUserCollection.Search( pUserSearch, nUserIndex ) ) +/*N*/ rStrm << (UINT16) nUserIndex; +/*N*/ else +/*N*/ rStrm << (UINT16) 0xffff; +/*N*/ rStrm << (BYTE) p->GetType(); +/*N*/ +/*N*/ bOk = p->Store( rStrm, aHdr ); +/*N*/ +/*N*/ aHdr.EndEntry(); +/*N*/ } +/*N*/ delete pUserSearch; +/*N*/ } +/*N*/ +/*N*/ if ( pLast ) +/*N*/ nMarkLastSaved = pLast->GetActionNumber(); +/*N*/ +/*N*/ if ( bOk ) +/*N*/ bOk = ( nCount == nSave ); +/*N*/ DBG_ASSERT( bOk, "ScChangeTrack::Store: failed" ); +/*N*/ +/*N*/ // zweite Runde: Links speichern +/*N*/ { +/*N*/ ScMultipleWriteHeader aHdr( rStrm ); +/*N*/ for ( ScChangeAction* p = GetFirst(); p && bOk; p = p->GetNext() ) +/*N*/ { +/*N*/ aHdr.StartEntry(); +/*N*/ bOk = p->StoreLinks( rStrm ); +/*N*/ aHdr.EndEntry(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ SetLoadSave( FALSE ); +/*N*/ return bOk; +/*N*/ } + + +/*N*/ void ScChangeTrack::MasterLinks( ScChangeAction* pAppend ) +/*N*/ { +/*N*/ ScChangeActionType eType = pAppend->GetType(); +/*N*/ +/*N*/ if ( eType == SC_CAT_CONTENT ) +/*N*/ { +/*N*/ if ( !IsGenerated( pAppend->GetActionNumber() ) ) +/*N*/ { +/*N*/ USHORT nSlot = ComputeContentSlot( +/*N*/ pAppend->GetBigRange().aStart.Row() ); +/*N*/ ((ScChangeActionContent*)pAppend)->InsertInSlot( +/*N*/ &ppContentSlots[nSlot] ); +/*N*/ } +/*N*/ return ; +/*N*/ } +/*N*/ +/*N*/ if ( pAppend->IsRejecting() ) +/*N*/ return ; // Rejects haben keine Abhaengigkeiten +/*N*/ +/*N*/ switch ( eType ) +/*N*/ { +/*N*/ case SC_CAT_INSERT_COLS : +/*N*/ { +/*N*/ ScChangeActionLinkEntry* pLink = new ScChangeActionLinkEntry( +/*N*/ &pLinkInsertCol, pAppend ); +/*N*/ pAppend->AddLink( NULL, pLink ); +/*N*/ } +/*N*/ break; +/*N*/ case SC_CAT_INSERT_ROWS : +/*N*/ { +/*N*/ ScChangeActionLinkEntry* pLink = new ScChangeActionLinkEntry( +/*N*/ &pLinkInsertRow, pAppend ); +/*N*/ pAppend->AddLink( NULL, pLink ); +/*N*/ } +/*N*/ break; +/*N*/ case SC_CAT_INSERT_TABS : +/*N*/ { +/*N*/ ScChangeActionLinkEntry* pLink = new ScChangeActionLinkEntry( +/*N*/ &pLinkInsertTab, pAppend ); +/*N*/ pAppend->AddLink( NULL, pLink ); +/*N*/ } +/*N*/ break; +/*N*/ case SC_CAT_MOVE : +/*N*/ { +/*N*/ ScChangeActionLinkEntry* pLink = new ScChangeActionLinkEntry( +/*N*/ &pLinkMove, pAppend ); +/*N*/ pAppend->AddLink( NULL, pLink ); +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ } + + +/*N*/ void ScChangeTrack::AppendLoaded( ScChangeAction* pAppend ) +/*N*/ { +/*N*/ aTable.Insert( pAppend->GetActionNumber(), pAppend ); // Changetracking.sdc +/*N*/ if ( !pLast ) +/*N*/ pFirst = pLast = pAppend; +/*N*/ else +/*N*/ { +/*N*/ pLast->pNext = pAppend; +/*N*/ pAppend->pPrev = pLast; +/*N*/ pLast = pAppend; +/*N*/ } +/*N*/ MasterLinks( pAppend ); +/*N*/ } + + +/*N*/ void ScChangeTrack::Append( ScChangeAction* pAppend, ULONG nAction ) +/*N*/ { +/*N*/ if ( nActionMax < nAction ) +/*N*/ nActionMax = nAction; +/*N*/ pAppend->SetUser( aUser ); +/*N*/ if ( bUseFixDateTime ) +/*N*/ pAppend->SetDateTimeUTC( aFixDateTime ); +/*N*/ pAppend->SetActionNumber( nAction ); +/*N*/ aTable.Insert( nAction, pAppend ); +/*N*/ // UpdateReference Inserts vor Dependencies. +/*N*/ // Delete rejectendes Insert hatte UpdateReference mit Delete-Undo. +/*N*/ // UpdateReference auch wenn pLast==NULL, weil pAppend ein Delete sein +/*N*/ // kann, dass DelContents generiert haben kann +/*N*/ if ( pAppend->IsInsertType() && !pAppend->IsRejecting() ) +/*N*/ UpdateReference( pAppend, FALSE ); +/*N*/ if ( !pLast ) +/*N*/ pFirst = pLast = pAppend; +/*N*/ else +/*N*/ { +/*N*/ pLast->pNext = pAppend; +/*N*/ pAppend->pPrev = pLast; +/*N*/ pLast = pAppend; +/*N*/ Dependencies( pAppend ); +/*N*/ } +/*N*/ // UpdateReference Inserts nicht nach Dependencies. +/*N*/ // Move rejectendes Move hatte UpdateReference mit Move-Undo, Inhalt in +/*N*/ // ToRange nicht deleten. +/*N*/ if ( !pAppend->IsInsertType() && +/*N*/ !(pAppend->GetType() == SC_CAT_MOVE && pAppend->IsRejecting()) ) +/*N*/ UpdateReference( pAppend, FALSE ); +/*N*/ MasterLinks( pAppend ); +/*N*/ +/*N*/ if ( aModifiedLink.IsSet() ) +/*N*/ { +/*N*/ NotifyModified( SC_CTM_APPEND, nAction, nAction ); +/*N*/ if ( pAppend->GetType() == SC_CAT_CONTENT ) +/*N*/ { +/*N*/ ScChangeActionContent* pContent = (ScChangeActionContent*) pAppend; +/*N*/ if ( pContent = pContent->GetPrevContent() ) +/*N*/ { +/*N*/ ULONG nMod = pContent->GetActionNumber(); +/*N*/ NotifyModified( SC_CTM_CHANGE, nMod, nMod ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ NotifyModified( SC_CTM_CHANGE, pFirst->GetActionNumber(), +/*N*/ pLast->GetActionNumber() ); +/*N*/ } +/*N*/ } + + +/*N*/ void ScChangeTrack::Append( ScChangeAction* pAppend ) +/*N*/ { +/*N*/ Append( pAppend, ++nActionMax ); +/*N*/ } + + +/*N*/ void ScChangeTrack::AppendDeleteRange( const ScRange& rRange, +/*N*/ ScDocument* pRefDoc, short nDz, ULONG nRejectingInsert ) +/*N*/ { +/*N*/ SetInDeleteRange( rRange ); +/*N*/ StartBlockModify( SC_CTM_APPEND, GetActionMax() + 1 ); +/*N*/ USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; +/*N*/ rRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); +/*N*/ for ( USHORT nTab = nTab1; nTab <= nTab2; nTab++ ) +/*N*/ { +/*N*/ if ( !pRefDoc || nTab < pRefDoc->GetTableCount() ) +/*N*/ { +/*N*/ if ( nCol1 == 0 && nCol2 == MAXCOL ) +/*N*/ { // ganze Zeilen und/oder Tabellen +/*N*/ if ( nRow1 == 0 && nRow2 == MAXROW ) +/*N*/ { // ganze Tabellen +/*N*/ //2do: geht nicht auch komplette Tabelle als ganzes? +/*N*/ ScRange aRange( 0, 0, nTab, 0, MAXROW, nTab ); +/*N*/ for ( USHORT nCol = nCol1; nCol <= nCol2; nCol++ ) +/*N*/ { // spaltenweise ist weniger als zeilenweise +/*N*/ aRange.aStart.SetCol( nCol ); +/*N*/ aRange.aEnd.SetCol( nCol ); +/*N*/ if ( nCol == nCol2 ) +/*N*/ SetInDeleteTop( TRUE ); +/*N*/ AppendOneDeleteRange( aRange, pRefDoc, nCol-nCol1, 0, +/*N*/ nTab-nTab1 + nDz, nRejectingInsert ); +/*N*/ } +/*N*/ //! immer noch InDeleteTop +/*N*/ AppendOneDeleteRange( rRange, pRefDoc, 0, 0, +/*N*/ nTab-nTab1 + nDz, nRejectingInsert ); +/*N*/ } +/*N*/ else +/*N*/ { // ganze Zeilen +/*N*/ ScRange aRange( 0, 0, nTab, MAXCOL, 0, nTab ); +/*N*/ for ( USHORT nRow = nRow1; nRow <= nRow2; nRow++ ) +/*N*/ { +/*N*/ aRange.aStart.SetRow( nRow ); +/*N*/ aRange.aEnd.SetRow( nRow ); +/*N*/ if ( nRow == nRow2 ) +/*N*/ SetInDeleteTop( TRUE ); +/*N*/ AppendOneDeleteRange( aRange, pRefDoc, 0, nRow-nRow1, +/*N*/ 0, nRejectingInsert ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else if ( nRow1 == 0 && nRow2 == MAXROW ) +/*N*/ { // ganze Spalten +/*N*/ ScRange aRange( 0, 0, nTab, 0, MAXROW, nTab ); +/*N*/ for ( USHORT nCol = nCol1; nCol <= nCol2; nCol++ ) +/*N*/ { +/*N*/ aRange.aStart.SetCol( nCol ); +/*N*/ aRange.aEnd.SetCol( nCol ); +/*N*/ if ( nCol == nCol2 ) +/*N*/ SetInDeleteTop( TRUE ); +/*N*/ AppendOneDeleteRange( aRange, pRefDoc, nCol-nCol1, 0, +/*N*/ 0, nRejectingInsert ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ DBG_ERROR( "ScChangeTrack::AppendDeleteRange: Block not supported!" ); +/*N*/ SetInDeleteTop( FALSE ); +/*N*/ } +/*N*/ } +/*N*/ EndBlockModify( GetActionMax() ); +/*N*/ } + + +/*N*/ void ScChangeTrack::AppendOneDeleteRange( const ScRange& rOrgRange, +/*N*/ ScDocument* pRefDoc, short nDx, short nDy, short nDz, +/*N*/ ULONG nRejectingInsert ) +/*N*/ { +/*N*/ ScRange aTrackRange( rOrgRange ); +/*N*/ if ( nDx ) +/*N*/ { +/*N*/ aTrackRange.aStart.IncCol( -nDx ); +/*N*/ aTrackRange.aEnd.IncCol( -nDx ); +/*N*/ } +/*N*/ if ( nDy ) +/*N*/ { +/*N*/ aTrackRange.aStart.IncRow( -nDy ); +/*N*/ aTrackRange.aEnd.IncRow( -nDy ); +/*N*/ } +/*N*/ if ( nDz ) +/*N*/ { +/*N*/ aTrackRange.aStart.IncTab( -nDz ); +/*N*/ aTrackRange.aEnd.IncTab( -nDz ); +/*N*/ } +/*N*/ ScChangeActionDel* pAct = new ScChangeActionDel( aTrackRange, nDx, nDy, +/*N*/ this ); +/*N*/ // TabDelete keine Contents, sind in einzelnen Spalten +/*N*/ if ( !(rOrgRange.aStart.Col() == 0 && rOrgRange.aStart.Row() == 0 && +/*N*/ rOrgRange.aEnd.Col() == MAXCOL && rOrgRange.aEnd.Row() == MAXROW) ) +/*N*/ LookUpContents( rOrgRange, pRefDoc, -nDx, -nDy, -nDz ); +/*N*/ if ( nRejectingInsert ) +/*N*/ { +/*N*/ pAct->SetRejectAction( nRejectingInsert ); +/*N*/ pAct->SetState( SC_CAS_ACCEPTED ); +/*N*/ } +/*N*/ Append( pAct ); +/*N*/ } + + +/*N*/ void ScChangeTrack::LookUpContents( const ScRange& rOrgRange, +/*N*/ ScDocument* pRefDoc, short nDx, short nDy, short nDz ) +/*N*/ { +/*N*/ if ( pRefDoc ) +/*N*/ { +/*N*/ ScAddress aPos; +/*N*/ ScBigAddress aBigPos; +/*N*/ ScCellIterator aIter( pRefDoc, rOrgRange ); +/*N*/ ScBaseCell* pCell = aIter.GetFirst(); +/*N*/ while ( pCell ) +/*N*/ { +/*N*/ if ( ScChangeActionContent::GetContentCellType( pCell ) ) +/*N*/ { +/*N*/ aBigPos.Set( aIter.GetCol() + nDx, aIter.GetRow() + nDy, +/*N*/ aIter.GetTab() + nDz ); +/*N*/ ScChangeActionContent* pContent = SearchContentAt( aBigPos, NULL ); +/*N*/ if ( !pContent ) +/*N*/ { // nicht getrackte Contents +/*N*/ aPos.Set( aIter.GetCol() + nDx, aIter.GetRow() + nDy, +/*N*/ aIter.GetTab() + nDz ); +/*N*/ GenerateDelContent( aPos, pCell, pRefDoc ); +/*N*/ //! der Content wird hier _nicht_ per AddContent hinzugefuegt, +/*N*/ //! sondern in UpdateReference, um z.B. auch kreuzende Deletes +/*N*/ //! korrekt zu erfassen +/*N*/ } +/*N*/ } +/*N*/ pCell = aIter.GetNext(); +/*N*/ } +/*N*/ } +/*N*/ } + + +/*N*/ void ScChangeTrack::DeleteCellEntries( ScChangeActionCellListEntry*& pCellList, +/*N*/ ScChangeAction* pDeletor ) +/*N*/ { +/*N*/ ScChangeActionCellListEntry* pE = pCellList; +/*N*/ while ( pE ) +/*N*/ { +/*N*/ ScChangeActionCellListEntry* pNext = pE->pNext; +/*N*/ pE->pContent->RemoveDeletedIn( pDeletor ); +/*N*/ if ( IsGenerated( pE->pContent->GetActionNumber() ) && +/*N*/ !pE->pContent->IsDeletedIn() ) +/*N*/ DeleteGeneratedDelContent( pE->pContent ); +/*N*/ delete pE; +/*N*/ pE = pNext; +/*N*/ } +/*N*/ pCellList = NULL; +/*N*/ } + + +/*N*/ ScChangeActionContent* ScChangeTrack::GenerateDelContent( +/*N*/ const ScAddress& rPos, const ScBaseCell* pCell, +/*N*/ const ScDocument* pFromDoc ) +/*N*/ { +/*N*/ ScChangeActionContent* pContent = new ScChangeActionContent( +/*N*/ ScRange( rPos ) ); +/*N*/ pContent->SetActionNumber( --nGeneratedMin ); +/*N*/ // nur NewValue +/*N*/ ScChangeActionContent::SetValue( pContent->aNewValue, pContent->pNewCell, +/*N*/ rPos, pCell, pFromDoc, pDoc ); +/*N*/ // pNextContent und pPrevContent werden nicht gesetzt +/*N*/ if ( pFirstGeneratedDelContent ) +/*N*/ { // vorne reinhaengen +/*N*/ pFirstGeneratedDelContent->pPrev = pContent; +/*N*/ pContent->pNext = pFirstGeneratedDelContent; +/*N*/ } +/*N*/ pFirstGeneratedDelContent = pContent; +/*N*/ aGeneratedTable.Insert( nGeneratedMin, pContent ); +/*N*/ NotifyModified( SC_CTM_APPEND, nGeneratedMin, nGeneratedMin ); +/*N*/ return pContent; +/*N*/ } + + +/*N*/ void ScChangeTrack::DeleteGeneratedDelContent( ScChangeActionContent* pContent ) +/*N*/ { +/*N*/ ULONG nAct = pContent->GetActionNumber(); +/*N*/ aGeneratedTable.Remove( nAct ); +/*N*/ if ( pFirstGeneratedDelContent == pContent ) +/*N*/ pFirstGeneratedDelContent = (ScChangeActionContent*) pContent->pNext; +/*N*/ if ( pContent->pNext ) +/*N*/ pContent->pNext->pPrev = pContent->pPrev; +/*N*/ if ( pContent->pPrev ) +/*N*/ pContent->pPrev->pNext = pContent->pNext; +/*N*/ delete pContent; +/*N*/ NotifyModified( SC_CTM_REMOVE, nAct, nAct ); +/*N*/ if ( nAct == nGeneratedMin ) +/*N*/ ++nGeneratedMin; //! erst nach NotifyModified wg. IsGenerated +/*N*/ } + +/*N*/ ScChangeActionContent* ScChangeTrack::SearchContentAt( +/*N*/ const ScBigAddress& rPos, ScChangeAction* pButNotThis ) const +/*N*/ { +/*N*/ USHORT nSlot = ComputeContentSlot( rPos.Row() ); +/*N*/ for ( ScChangeActionContent* p = ppContentSlots[nSlot]; p; +/*N*/ p = p->GetNextInSlot() ) +/*N*/ { +/*N*/ if ( p != pButNotThis && !p->IsDeletedIn() && +/*N*/ p->GetBigRange().aStart == rPos ) +/*N*/ { +/*N*/ ScChangeActionContent* pContent = p->GetTopContent(); +/*N*/ if ( !pContent->IsDeletedIn() ) +/*N*/ return pContent; +/*N*/ } +/*N*/ } +/*N*/ return NULL; +/*N*/ } + + +/*N*/ void ScChangeTrack::AddDependentWithNotify( ScChangeAction* pParent, +/*N*/ ScChangeAction* pDependent ) +/*N*/ { +/*N*/ ScChangeActionLinkEntry* pLink = pParent->AddDependent( pDependent ); +/*N*/ pDependent->AddLink( pParent, pLink ); +/*N*/ if ( aModifiedLink.IsSet() ) +/*N*/ { +/*N*/ ULONG nMod = pParent->GetActionNumber(); +/*N*/ NotifyModified( SC_CTM_PARENT, nMod, nMod ); +/*N*/ } +/*N*/ } + + +/*N*/ void ScChangeTrack::Dependencies( ScChangeAction* pAct ) +/*N*/ { +/*N*/ // Finde die letzte Abhaengigkeit fuer jeweils Col/Row/Tab. +/*N*/ // Content an gleicher Position verketten. +/*N*/ // Move Abhaengigkeiten. +/*N*/ ScChangeActionType eActType = pAct->GetType(); +/*N*/ if ( eActType == SC_CAT_REJECT || +/*N*/ (eActType == SC_CAT_MOVE && pAct->IsRejecting()) ) +/*N*/ return ; // diese Rejects sind nicht abhaengig +/*N*/ +/*N*/ if ( eActType == SC_CAT_CONTENT ) +/*N*/ { +/*N*/ if ( !(((ScChangeActionContent*)pAct)->GetNextContent() || +/*N*/ ((ScChangeActionContent*)pAct)->GetPrevContent()) ) +/*N*/ { // Contents an gleicher Position verketten +/*N*/ ScChangeActionContent* pContent = SearchContentAt( +/*N*/ pAct->GetBigRange().aStart, pAct ); +/*N*/ if ( pContent ) +/*N*/ { +/*N*/ pContent->SetNextContent( (ScChangeActionContent*) pAct ); +/*N*/ ((ScChangeActionContent*)pAct)->SetPrevContent( pContent ); +/*N*/ } +/*N*/ } +/*N*/ const ScBaseCell* pCell = ((ScChangeActionContent*)pAct)->GetNewCell(); +/*N*/ if ( ScChangeActionContent::GetContentCellType( pCell ) == SC_CACCT_MATREF ) +/*N*/ { +/*N*/ ScAddress aOrg; +/*N*/ ((const ScFormulaCell*)pCell)->GetMatrixOrigin( aOrg ); +/*N*/ ScChangeActionContent* pContent = SearchContentAt( aOrg, pAct ); +/*N*/ if ( pContent && pContent->IsMatrixOrigin() ) +/*N*/ { +/*N*/ AddDependentWithNotify( pContent, pAct ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScChangeTrack::Dependencies: MatOrg not found" ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( !(pLinkInsertCol || pLinkInsertRow || pLinkInsertTab || pLinkMove) ) +/*N*/ return ; // keine Dependencies +/*N*/ if ( pAct->IsRejecting() ) +/*N*/ return ; // ausser Content keine Dependencies +/*N*/ +/*N*/ // Insert in einem entsprechenden Insert haengt davon ab, sonst muesste +/*N*/ // der vorherige Insert gesplittet werden. +/*N*/ // Sich kreuzende Inserts und Deletes sind nicht abhaengig. +/*N*/ // Alles andere ist abhaengig. +/*N*/ +/*N*/ // Der zuletzt eingelinkte Insert steht am Anfang einer Kette, +/*N*/ // also genau richtig +/*N*/ +/*N*/ const ScBigRange& rRange = pAct->GetBigRange(); +/*N*/ BOOL bActNoInsert = !pAct->IsInsertType(); +/*N*/ BOOL bActColDel = ( eActType == SC_CAT_DELETE_COLS ); +/*N*/ BOOL bActRowDel = ( eActType == SC_CAT_DELETE_ROWS ); +/*N*/ BOOL bActTabDel = ( eActType == SC_CAT_DELETE_TABS ); +/*N*/ +/*N*/ if ( pLinkInsertCol && (eActType == SC_CAT_INSERT_COLS || +/*N*/ (bActNoInsert && !bActRowDel && !bActTabDel)) ) +/*N*/ { +/*N*/ for ( ScChangeActionLinkEntry* pL = pLinkInsertCol; pL; pL = pL->GetNext() ) +/*N*/ { +/*N*/ ScChangeActionIns* pTest = (ScChangeActionIns*) pL->GetAction(); +/*N*/ if ( !pTest->IsRejected() && +/*N*/ pTest->GetBigRange().Intersects( rRange ) ) +/*N*/ { +/*N*/ AddDependentWithNotify( pTest, pAct ); +/*N*/ break; // for +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( pLinkInsertRow && (eActType == SC_CAT_INSERT_ROWS || +/*N*/ (bActNoInsert && !bActColDel && !bActTabDel)) ) +/*N*/ { +/*N*/ for ( ScChangeActionLinkEntry* pL = pLinkInsertRow; pL; pL = pL->GetNext() ) +/*N*/ { +/*N*/ ScChangeActionIns* pTest = (ScChangeActionIns*) pL->GetAction(); +/*N*/ if ( !pTest->IsRejected() && +/*N*/ pTest->GetBigRange().Intersects( rRange ) ) +/*N*/ { +/*N*/ AddDependentWithNotify( pTest, pAct ); +/*N*/ break; // for +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( pLinkInsertTab && (eActType == SC_CAT_INSERT_TABS || +/*N*/ (bActNoInsert && !bActColDel && !bActRowDel)) ) +/*N*/ { +/*N*/ for ( ScChangeActionLinkEntry* pL = pLinkInsertTab; pL; pL = pL->GetNext() ) +/*N*/ { +/*N*/ ScChangeActionIns* pTest = (ScChangeActionIns*) pL->GetAction(); +/*N*/ if ( !pTest->IsRejected() && +/*N*/ pTest->GetBigRange().Intersects( rRange ) ) +/*N*/ { +/*N*/ AddDependentWithNotify( pTest, pAct ); +/*N*/ break; // for +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( pLinkMove ) +/*N*/ { +/*N*/ if ( eActType == SC_CAT_CONTENT ) +/*N*/ { // Content ist von FromRange abhaengig +/*N*/ const ScBigAddress& rPos = rRange.aStart; +/*N*/ for ( ScChangeActionLinkEntry* pL = pLinkMove; pL; pL = pL->GetNext() ) +/*N*/ { +/*N*/ ScChangeActionMove* pTest = (ScChangeActionMove*) pL->GetAction(); +/*N*/ if ( !pTest->IsRejected() && +/*N*/ pTest->GetFromRange().In( rPos ) ) +/*N*/ { +/*N*/ AddDependentWithNotify( pTest, pAct ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else if ( eActType == SC_CAT_MOVE ) +/*N*/ { // Move FromRange ist von ToRange abhaengig +/*N*/ const ScBigRange& rFromRange = ((ScChangeActionMove*)pAct)->GetFromRange(); +/*N*/ for ( ScChangeActionLinkEntry* pL = pLinkMove; pL; pL = pL->GetNext() ) +/*N*/ { +/*N*/ ScChangeActionMove* pTest = (ScChangeActionMove*) pL->GetAction(); +/*N*/ if ( !pTest->IsRejected() && +/*N*/ pTest->GetBigRange().Intersects( rFromRange ) ) +/*N*/ { +/*N*/ AddDependentWithNotify( pTest, pAct ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { // Inserts und Deletes sind abhaengig, sobald sie FromRange oder +/*N*/ // ToRange kreuzen +/*N*/ for ( ScChangeActionLinkEntry* pL = pLinkMove; pL; pL = pL->GetNext() ) +/*N*/ { +/*N*/ ScChangeActionMove* pTest = (ScChangeActionMove*) pL->GetAction(); +/*N*/ if ( !pTest->IsRejected() && +/*N*/ (pTest->GetFromRange().Intersects( rRange ) || +/*N*/ pTest->GetBigRange().Intersects( rRange )) ) +/*N*/ { +/*N*/ AddDependentWithNotify( pTest, pAct ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + + +/*N*/ void ScChangeTrack::Remove( ScChangeAction* pRemove ) +/*N*/ { +/*N*/ // aus Track ausklinken +/*N*/ ULONG nAct = pRemove->GetActionNumber(); +/*N*/ aTable.Remove( nAct ); +/*N*/ if ( nAct == nActionMax ) +/*N*/ --nActionMax; +/*N*/ if ( pRemove == pLast ) +/*N*/ pLast = pRemove->pPrev; +/*N*/ if ( pRemove == pFirst ) +/*N*/ pFirst = pRemove->pNext; +/*N*/ if ( nAct == nMarkLastSaved ) +/*N*/ nMarkLastSaved = +/*N*/ ( pRemove->pPrev ? pRemove->pPrev->GetActionNumber() : 0 ); +/*N*/ +/*N*/ // aus der globalen Kette ausklinken +/*N*/ if ( pRemove->pNext ) +/*N*/ pRemove->pNext->pPrev = pRemove->pPrev; +/*N*/ if ( pRemove->pPrev ) +/*N*/ pRemove->pPrev->pNext = pRemove->pNext; +/*N*/ +/*N*/ // Dependencies nicht loeschen, passiert on delete automatisch durch +/*N*/ // LinkEntry, ohne Listen abzuklappern +/*N*/ +/*N*/ if ( aModifiedLink.IsSet() ) +/*N*/ { +/*N*/ NotifyModified( SC_CTM_REMOVE, nAct, nAct ); +/*N*/ if ( pRemove->GetType() == SC_CAT_CONTENT ) +/*N*/ { +/*N*/ ScChangeActionContent* pContent = (ScChangeActionContent*) pRemove; +/*N*/ if ( pContent = pContent->GetPrevContent() ) +/*N*/ { +/*N*/ ULONG nMod = pContent->GetActionNumber(); +/*N*/ NotifyModified( SC_CTM_CHANGE, nMod, nMod ); +/*N*/ } +/*N*/ } +/*N*/ else if ( pLast ) +/*N*/ NotifyModified( SC_CTM_CHANGE, pFirst->GetActionNumber(), +/*N*/ pLast->GetActionNumber() ); +/*N*/ } +/*N*/ +/*N*/ if ( IsInPasteCut() && pRemove->GetType() == SC_CAT_CONTENT ) +/*N*/ { //! Content wird wiederverwertet +/*N*/ ScChangeActionContent* pContent = (ScChangeActionContent*) pRemove; +/*N*/ pContent->RemoveAllLinks(); +/*N*/ pContent->ClearTrack(); +/*N*/ pContent->pNext = pContent->pPrev = NULL; +/*N*/ pContent->pNextContent = pContent->pPrevContent = NULL; +/*N*/ } +/*N*/ } + + +/*N*/ void ScChangeTrack::UpdateReference( ScChangeAction* pAct, BOOL bUndo ) +/*N*/ { +/*N*/ ScChangeActionType eActType = pAct->GetType(); +/*N*/ if ( eActType == SC_CAT_CONTENT || eActType == SC_CAT_REJECT ) +/*N*/ return ; +/*N*/ +/*N*/ //! Formelzellen haengen nicht im Dokument +/*N*/ BOOL bOldAutoCalc = pDoc->GetAutoCalc(); +/*N*/ pDoc->SetAutoCalc( FALSE ); +/*N*/ BOOL bOldNoListening = pDoc->GetNoListening(); +/*N*/ pDoc->SetNoListening( TRUE ); +/*N*/ //! Formelzellen ExpandRefs synchronisiert zu denen im Dokument +/*N*/ BOOL bOldExpandRefs = pDoc->IsExpandRefs(); +/*N*/ if ( (!bUndo && pAct->IsInsertType()) || (bUndo && pAct->IsDeleteType()) ) +/*N*/ pDoc->SetExpandRefs( SC_MOD()->GetInputOptions().GetExpandRefs() ); +/*N*/ +/*N*/ if ( pAct->IsDeleteType() ) +/*N*/ { +/*N*/ SetInDeleteUndo( bUndo ); +/*N*/ SetInDelete( TRUE ); +/*N*/ } +/*N*/ else if ( GetMergeState() == SC_CTMS_OWN ) +/*N*/ { +/*N*/ // Referenzen von Formelzellen wiederherstellen, +/*N*/ // vorheriges MergePrepare war bei einem Insert wie ein Delete +/*N*/ if ( pAct->IsInsertType() ) +/*N*/ SetInDeleteUndo( TRUE ); +/*N*/ } +/*N*/ +/*N*/ //! erst die generated, als waeren sie vorher getrackt worden +/*N*/ if ( pFirstGeneratedDelContent ) +/*N*/ UpdateReference( (ScChangeAction**)&pFirstGeneratedDelContent, pAct, +/*N*/ bUndo ); +/*N*/ UpdateReference( &pFirst, pAct, bUndo ); +/*N*/ +/*N*/ SetInDelete( FALSE ); +/*N*/ SetInDeleteUndo( FALSE ); +/*N*/ +/*N*/ pDoc->SetExpandRefs( bOldExpandRefs ); +/*N*/ pDoc->SetNoListening( bOldNoListening ); +/*N*/ pDoc->SetAutoCalc( bOldAutoCalc ); +/*N*/ } + + +/*N*/ void ScChangeTrack::UpdateReference( ScChangeAction** ppFirstAction, +/*N*/ ScChangeAction* pAct, BOOL bUndo ) +/*N*/ { +/*N*/ ScChangeActionType eActType = pAct->GetType(); +/*N*/ BOOL bGeneratedDelContents = +/*N*/ ( ppFirstAction == (ScChangeAction**)&pFirstGeneratedDelContent ); +/*N*/ const ScBigRange& rOrgRange = pAct->GetBigRange(); +/*N*/ ScBigRange aRange( rOrgRange ); +/*N*/ ScBigRange aDelRange( rOrgRange ); +/*N*/ INT32 nDx, nDy, nDz; +/*N*/ nDx = nDy = nDz = 0; +/*N*/ UpdateRefMode eMode = URM_INSDEL; +/*N*/ BOOL bDel = FALSE; +/*N*/ switch ( eActType ) +/*N*/ { +/*N*/ case SC_CAT_INSERT_COLS : +/*N*/ aRange.aEnd.SetCol( nInt32Max ); +/*N*/ nDx = rOrgRange.aEnd.Col() - rOrgRange.aStart.Col() + 1; +/*N*/ break; +/*N*/ case SC_CAT_INSERT_ROWS : +/*N*/ aRange.aEnd.SetRow( nInt32Max ); +/*N*/ nDy = rOrgRange.aEnd.Row() - rOrgRange.aStart.Row() + 1; +/*N*/ break; +/*N*/ case SC_CAT_INSERT_TABS : +/*N*/ aRange.aEnd.SetTab( nInt32Max ); +/*N*/ nDz = rOrgRange.aEnd.Tab() - rOrgRange.aStart.Tab() + 1; +/*N*/ break; +/*N*/ case SC_CAT_DELETE_COLS : +/*N*/ aRange.aEnd.SetCol( nInt32Max ); +/*N*/ nDx = -(rOrgRange.aEnd.Col() - rOrgRange.aStart.Col() + 1); +/*N*/ aDelRange.aEnd.SetCol( aDelRange.aStart.Col() - nDx - 1 ); +/*N*/ bDel = TRUE; +/*N*/ break; +/*N*/ case SC_CAT_DELETE_ROWS : +/*N*/ aRange.aEnd.SetRow( nInt32Max ); +/*N*/ nDy = -(rOrgRange.aEnd.Row() - rOrgRange.aStart.Row() + 1); +/*N*/ aDelRange.aEnd.SetRow( aDelRange.aStart.Row() - nDy - 1 ); +/*N*/ bDel = TRUE; +/*N*/ break; +/*N*/ case SC_CAT_DELETE_TABS : +/*N*/ aRange.aEnd.SetTab( nInt32Max ); +/*N*/ nDz = -(rOrgRange.aEnd.Tab() - rOrgRange.aStart.Tab() + 1); +/*N*/ aDelRange.aEnd.SetTab( aDelRange.aStart.Tab() - nDz - 1 ); +/*N*/ bDel = TRUE; +/*N*/ break; +/*N*/ case SC_CAT_MOVE : +/*N*/ eMode = URM_MOVE; +/*N*/ ((ScChangeActionMove*)pAct)->GetDelta( nDx, nDy, nDz ); +/*N*/ break; +/*N*/ default: +/*N*/ DBG_ERROR( "ScChangeTrack::UpdateReference: unknown Type" ); +/*N*/ } +/*N*/ if ( bUndo ) +/*N*/ { +/*N*/ nDx = -nDx; +/*N*/ nDy = -nDy; +/*N*/ nDz = -nDz; +/*N*/ } +/*N*/ if ( bDel ) +/*N*/ { //! fuer diesen Mechanismus gilt: +/*N*/ //! es gibt nur ganze, einfache geloeschte Spalten/Zeilen +/*N*/ ScChangeActionDel* pActDel = (ScChangeActionDel*) pAct; +/*N*/ if ( !bUndo ) +/*N*/ { // Delete +/*N*/ ScChangeActionType eInsType; // fuer Insert-Undo-"Deletes" +/*N*/ switch ( eActType ) +/*N*/ { +/*N*/ case SC_CAT_DELETE_COLS : +/*N*/ eInsType = SC_CAT_INSERT_COLS; +/*N*/ break; +/*N*/ case SC_CAT_DELETE_ROWS : +/*N*/ eInsType = SC_CAT_INSERT_ROWS; +/*N*/ break; +/*N*/ case SC_CAT_DELETE_TABS : +/*N*/ eInsType = SC_CAT_INSERT_TABS; +/*N*/ break; +/*N*/ } +/*N*/ for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() ) +/*N*/ { +/*N*/ if ( p == pAct ) +/*N*/ continue; // for +/*N*/ BOOL bUpdate = TRUE; +/*N*/ if ( GetMergeState() == SC_CTMS_OTHER && +/*N*/ p->GetActionNumber() <= GetLastMerge() ) +/*N*/ { // Delete in mergendem Dokument, Action im zu mergenden +/*N*/ if ( p->IsInsertType() ) +/*N*/ { +/*N*/ // Bei Insert Referenzen nur anpassen, wenn das Delete +/*N*/ // das Insert nicht schneidet. +/*N*/ if ( !aDelRange.Intersects( p->GetBigRange() ) ) +/*N*/ p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz ); +/*N*/ bUpdate = FALSE; +/*N*/ } +/*N*/ else if ( p->GetType() == SC_CAT_CONTENT && +/*N*/ p->IsDeletedInDelType( eInsType ) ) +/*N*/ { // Content in Insert-Undo-"Delete" +/*N*/ // Nicht anpassen, wenn dieses Delete in dem +/*N*/ // Insert-"Delete" sein wuerde (ist nur verschoben). +/*N*/ if ( aDelRange.In( p->GetBigRange().aStart ) ) +/*N*/ bUpdate = FALSE; +/*N*/ else +/*N*/ { +/*N*/ const ScChangeActionLinkEntry* pLink = p->GetDeletedIn(); +/*N*/ while ( pLink && bUpdate ) +/*N*/ { +/*N*/ const ScChangeAction* pDel = pLink->GetAction(); +/*N*/ if ( pDel && pDel->GetType() == eInsType && +/*N*/ pDel->GetBigRange().In( aDelRange ) ) +/*N*/ bUpdate = FALSE; +/*N*/ pLink = pLink->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( !bUpdate ) +/*N*/ continue; // for +/*N*/ } +/*N*/ if ( aDelRange.In( p->GetBigRange() ) ) +/*N*/ { +/*N*/ // Innerhalb eines gerade geloeschten Bereiches nicht +/*N*/ // anpassen, stattdessen dem Bereich zuordnen. +/*N*/ // Mehrfache geloeschte Bereiche "stapeln". +/*N*/ // Kreuzende Deletes setzen mehrfach geloescht. +/*N*/ if ( !p->IsDeletedInDelType( eActType ) ) +/*N*/ { +/*N*/ p->SetDeletedIn( pActDel ); +/*N*/ // GeneratedDelContent in zu loeschende Liste aufnehmen +/*N*/ if ( bGeneratedDelContents ) +/*N*/ pActDel->AddContent( (ScChangeActionContent*) p ); +/*N*/ } +/*N*/ bUpdate = FALSE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Eingefuegte Bereiche abschneiden, wenn Start/End im +/*N*/ // Delete liegt, aber das Insert nicht komplett innerhalb +/*N*/ // des Delete liegt bzw. das Delete nicht komplett im +/*N*/ // Insert. Das Delete merkt sich, welchem Insert es was +/*N*/ // abgeschnitten hat, es kann auch nur ein einziges Insert +/*N*/ // sein (weil Delete einspaltig/einzeilig ist). +/*N*/ // Abgeschnittene Moves kann es viele geben. +/*N*/ //! Ein Delete ist immer einspaltig/einzeilig, deswegen 1 +/*N*/ //! ohne die Ueberlappung auszurechnen. +/*N*/ switch ( p->GetType() ) +/*N*/ { +/*N*/ case SC_CAT_INSERT_COLS : +/*N*/ if ( eActType == SC_CAT_DELETE_COLS ) +/*N*/ { +/*N*/ if ( aDelRange.In( p->GetBigRange().aStart ) ) +/*N*/ { +/*N*/ pActDel->SetCutOffInsert( +/*N*/ (ScChangeActionIns*) p, 1 ); +/*N*/ p->GetBigRange().aStart.IncCol( 1 ); +/*N*/ } +/*N*/ else if ( aDelRange.In( p->GetBigRange().aEnd ) ) +/*N*/ { +/*N*/ pActDel->SetCutOffInsert( +/*N*/ (ScChangeActionIns*) p, -1 ); +/*N*/ p->GetBigRange().aEnd.IncCol( -1 ); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case SC_CAT_INSERT_ROWS : +/*N*/ if ( eActType == SC_CAT_DELETE_ROWS ) +/*N*/ { +/*N*/ if ( aDelRange.In( p->GetBigRange().aStart ) ) +/*N*/ { +/*N*/ pActDel->SetCutOffInsert( +/*N*/ (ScChangeActionIns*) p, 1 ); +/*N*/ p->GetBigRange().aStart.IncRow( 1 ); +/*N*/ } +/*N*/ else if ( aDelRange.In( p->GetBigRange().aEnd ) ) +/*N*/ { +/*N*/ pActDel->SetCutOffInsert( +/*N*/ (ScChangeActionIns*) p, -1 ); +/*N*/ p->GetBigRange().aEnd.IncRow( -1 ); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case SC_CAT_INSERT_TABS : +/*N*/ if ( eActType == SC_CAT_DELETE_TABS ) +/*N*/ { +/*N*/ if ( aDelRange.In( p->GetBigRange().aStart ) ) +/*N*/ { +/*N*/ pActDel->SetCutOffInsert( +/*N*/ (ScChangeActionIns*) p, 1 ); +/*N*/ p->GetBigRange().aStart.IncTab( 1 ); +/*N*/ } +/*N*/ else if ( aDelRange.In( p->GetBigRange().aEnd ) ) +/*N*/ { +/*N*/ pActDel->SetCutOffInsert( +/*N*/ (ScChangeActionIns*) p, -1 ); +/*N*/ p->GetBigRange().aEnd.IncTab( -1 ); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case SC_CAT_MOVE : +/*N*/ { +/*N*/ ScChangeActionMove* pMove = (ScChangeActionMove*) p; +/*N*/ short nFrom = 0; +/*N*/ short nTo = 0; +/*N*/ if ( aDelRange.In( pMove->GetBigRange().aStart ) ) +/*N*/ nTo = 1; +/*N*/ else if ( aDelRange.In( pMove->GetBigRange().aEnd ) ) +/*N*/ nTo = -1; +/*N*/ if ( aDelRange.In( pMove->GetFromRange().aStart ) ) +/*N*/ nFrom = 1; +/*N*/ else if ( aDelRange.In( pMove->GetFromRange().aEnd ) ) +/*N*/ nFrom = -1; +/*N*/ if ( nFrom ) +/*N*/ { +/*N*/ switch ( eActType ) +/*N*/ { +/*N*/ case SC_CAT_DELETE_COLS : +/*N*/ if ( nFrom > 0 ) +/*N*/ pMove->GetFromRange().aStart.IncCol( nFrom ); +/*N*/ else +/*N*/ pMove->GetFromRange().aEnd.IncCol( nFrom ); +/*N*/ break; +/*N*/ case SC_CAT_DELETE_ROWS : +/*N*/ if ( nFrom > 0 ) +/*N*/ pMove->GetFromRange().aStart.IncRow( nFrom ); +/*N*/ else +/*N*/ pMove->GetFromRange().aEnd.IncRow( nFrom ); +/*N*/ break; +/*N*/ case SC_CAT_DELETE_TABS : +/*N*/ if ( nFrom > 0 ) +/*N*/ pMove->GetFromRange().aStart.IncTab( nFrom ); +/*N*/ else +/*N*/ pMove->GetFromRange().aEnd.IncTab( nFrom ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ if ( nTo ) +/*N*/ { +/*N*/ switch ( eActType ) +/*N*/ { +/*N*/ case SC_CAT_DELETE_COLS : +/*N*/ if ( nTo > 0 ) +/*N*/ pMove->GetBigRange().aStart.IncCol( nTo ); +/*N*/ else +/*N*/ pMove->GetBigRange().aEnd.IncCol( nTo ); +/*N*/ break; +/*N*/ case SC_CAT_DELETE_ROWS : +/*N*/ if ( nTo > 0 ) +/*N*/ pMove->GetBigRange().aStart.IncRow( nTo ); +/*N*/ else +/*N*/ pMove->GetBigRange().aEnd.IncRow( nTo ); +/*N*/ break; +/*N*/ case SC_CAT_DELETE_TABS : +/*N*/ if ( nTo > 0 ) +/*N*/ pMove->GetBigRange().aStart.IncTab( nTo ); +/*N*/ else +/*N*/ pMove->GetBigRange().aEnd.IncTab( nTo ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ if ( nFrom || nTo ) +/*N*/ { +/*N*/ ScChangeActionDelMoveEntry* pLink = +/*N*/ pActDel->AddCutOffMove( pMove, nFrom, nTo ); +/*N*/ pMove->AddLink( pActDel, pLink ); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ if ( bUpdate ) +/*N*/ { +/*N*/ p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz ); +/*N*/ if ( p->GetType() == eActType && !p->IsRejected() && +/*N*/ !pActDel->IsDeletedIn() && +/*N*/ p->GetBigRange().In( aDelRange ) ) +/*N*/ pActDel->SetDeletedIn( p ); // "druntergerutscht" +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { // Undo Delete +/*N*/ ScChangeAction* pNextAction = NULL; +/*N*/ for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() ) +/*N*/ { +/*N*/ if ( p == pAct ) +/*N*/ continue; // for +/*N*/ BOOL bUpdate = TRUE; +/*N*/ if ( aDelRange.In( p->GetBigRange() ) ) +/*N*/ { +/*N*/ if ( p->IsDeletedInDelType( eActType ) ) +/*N*/ { +/*N*/ if ( p->IsDeletedIn( pActDel ) ) +/*N*/ { +/*N*/ if ( p->GetType() != SC_CAT_CONTENT || +/*N*/ ((ScChangeActionContent*)p)->IsTopContent() ) +/*N*/ { // erst der TopContent wird wirklich entfernt +/*N*/ p->RemoveDeletedIn( pActDel ); +/*N*/ // GeneratedDelContent _nicht_ aus Liste loeschen, +/*N*/ // wir brauchen ihn evtl. noch fuer Reject, +/*N*/ // geloescht wird in DeleteCellEntries +/*N*/ } +/*N*/ } +/*N*/ bUpdate = FALSE; +/*N*/ } +/*N*/ else if ( eActType != SC_CAT_DELETE_TABS && +/*N*/ p->IsDeletedInDelType( SC_CAT_DELETE_TABS ) ) +/*N*/ { // in geloeschten Tabellen nicht updaten, +/*N*/ // ausser wenn Tabelle verschoben wird +/*N*/ bUpdate = FALSE; +/*N*/ } +/*N*/ if ( p->GetType() == eActType && pActDel->IsDeletedIn( p ) ) +/*N*/ { +/*N*/ pActDel->RemoveDeletedIn( p ); // "druntergerutscht" +/*N*/ bUpdate = TRUE; +/*N*/ } +/*N*/ } +/*N*/ if ( bUpdate ) +/*N*/ p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz ); +/*N*/ } +/*N*/ if ( !bGeneratedDelContents ) +/*N*/ { // die werden sonst noch fuer das echte Undo gebraucht +/*N*/ pActDel->UndoCutOffInsert(); +/*N*/ pActDel->UndoCutOffMoves(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else if ( eActType == SC_CAT_MOVE ) +/*N*/ { +/*N*/ ScChangeActionMove* pActMove = (ScChangeActionMove*) pAct; +/*N*/ BOOL bLastCutMove = ( pActMove == pLastCutMove ); +/*N*/ const ScBigRange& rTo = pActMove->GetBigRange(); +/*N*/ const ScBigRange& rFrom = pActMove->GetFromRange(); +/*N*/ if ( !bUndo ) +/*N*/ { // Move +/*N*/ for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() ) +/*N*/ { +/*N*/ if ( p == pAct ) +/*N*/ continue; // for +/*N*/ if ( p->GetType() == SC_CAT_CONTENT ) +/*N*/ { +/*N*/ // Inhalt in Ziel deleten (Inhalt in Quelle moven) +/*N*/ if ( rTo.In( p->GetBigRange() ) ) +/*N*/ { +/*N*/ if ( !p->IsDeletedIn( pActMove ) ) +/*N*/ { +/*N*/ p->SetDeletedIn( pActMove ); +/*N*/ // GeneratedDelContent in zu loeschende Liste aufnehmen +/*N*/ if ( bGeneratedDelContents ) +/*N*/ pActMove->AddContent( (ScChangeActionContent*) p ); +/*N*/ } +/*N*/ } +/*N*/ else if ( bLastCutMove && +/*N*/ p->GetActionNumber() > nEndLastCut && +/*N*/ rFrom.In( p->GetBigRange() ) ) +/*N*/ { // Paste Cut: neuer Content nach Cut eingefuegt, bleibt. +/*N*/ // Aufsplitten der ContentChain +/*N*/ ScChangeActionContent *pHere, *pTmp; +/*N*/ pHere = (ScChangeActionContent*) p; +/*N*/ while ( (pTmp = pHere->GetPrevContent()) && +/*N*/ pTmp->GetActionNumber() > nEndLastCut ) +/*N*/ pHere = pTmp; +/*N*/ if ( pTmp ) +/*N*/ { // wird TopContent des Move +/*N*/ pTmp->SetNextContent( NULL ); +/*N*/ pHere->SetPrevContent( NULL ); +/*N*/ } +/*N*/ do +/*N*/ { // Abhaengigkeit vom FromRange herstellen +/*N*/ AddDependentWithNotify( pActMove, pHere ); +/*N*/ } while ( pHere = pHere->GetNextContent() ); +/*N*/ } +/*N*/ else +/*N*/ p->UpdateReference( this, eMode, rFrom, nDx, nDy, nDz ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { // Undo Move +/*N*/ BOOL bActRejected = pActMove->IsRejected(); +/*N*/ for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() ) +/*N*/ { +/*N*/ if ( p == pAct ) +/*N*/ continue; // for +/*N*/ if ( p->GetType() == SC_CAT_CONTENT ) +/*N*/ { +/*N*/ // Inhalt in Ziel moven, wenn nicht deleted, sonst undelete +/*N*/ if ( p->IsDeletedIn( pActMove ) ) +/*N*/ { +/*N*/ if ( ((ScChangeActionContent*)p)->IsTopContent() ) +/*N*/ { // erst der TopContent wird wirklich entfernt +/*N*/ p->RemoveDeletedIn( pActMove ); +/*N*/ // GeneratedDelContent _nicht_ aus Liste loeschen, +/*N*/ // wir brauchen ihn evtl. noch fuer Reject, +/*N*/ // geloescht wird in DeleteCellEntries +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ p->UpdateReference( this, eMode, rTo, nDx, nDy, nDz ); +/*N*/ if ( bActRejected && +/*N*/ ((ScChangeActionContent*)p)->IsTopContent() && +/*N*/ rFrom.In( p->GetBigRange() ) ) +/*N*/ { // Abhaengigkeit herstellen, um Content zu schreiben +/*N*/ ScChangeActionLinkEntry* pLink = +/*N*/ pActMove->AddDependent( p ); +/*N*/ p->AddLink( pActMove, pLink ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { // Insert / Undo Insert +/*N*/ switch ( GetMergeState() ) +/*N*/ { +/*N*/ case SC_CTMS_NONE : +/*N*/ case SC_CTMS_OTHER : +/*N*/ { +/*N*/ for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() ) +/*N*/ { +/*N*/ if ( p == pAct ) +/*N*/ continue; // for +/*N*/ p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz ); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case SC_CTMS_PREPARE : +/*N*/ { +/*N*/ // in Insert-Undo "Deleten" +/*N*/ const ScChangeActionLinkEntry* pLink = pAct->GetFirstDependentEntry(); +/*N*/ while ( pLink ) +/*N*/ { +/*N*/ ScChangeAction* p = (ScChangeAction*) pLink->GetAction(); +/*N*/ if ( p ) +/*N*/ p->SetDeletedIn( pAct ); +/*N*/ pLink = pLink->GetNext(); +/*N*/ } +/*N*/ for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() ) +/*N*/ { +/*N*/ if ( p == pAct ) +/*N*/ continue; // for +/*N*/ if ( !p->IsDeletedIn( pAct ) ) +/*N*/ p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz ); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case SC_CTMS_OWN : +/*N*/ { +/*N*/ for ( ScChangeAction* p = *ppFirstAction; p; p = p->GetNext() ) +/*N*/ { +/*N*/ if ( p == pAct ) +/*N*/ continue; // for +/*N*/ if ( !p->IsDeletedIn( pAct ) ) +/*N*/ p->UpdateReference( this, eMode, aRange, nDx, nDy, nDz ); +/*N*/ } +/*N*/ // in Insert-Undo "Delete" rueckgaengig +/*N*/ const ScChangeActionLinkEntry* pLink = pAct->GetFirstDependentEntry(); +/*N*/ while ( pLink ) +/*N*/ { +/*N*/ ScChangeAction* p = (ScChangeAction*) pLink->GetAction(); +/*N*/ if ( p ) +/*N*/ p->RemoveDeletedIn( pAct ); +/*N*/ pLink = pLink->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } + + +/*N*/ BOOL ScChangeTrack::Reject( ScChangeAction* pAct, ScChangeActionTable* pTable, +/*N*/ BOOL bRecursion ) +/*N*/ { +/*N*/ if ( !pAct->IsInternalRejectable() ) +/*N*/ return FALSE; +/*N*/ +/*N*/ BOOL bOk = TRUE; +/*N*/ BOOL bRejected = FALSE; +/*N*/ if ( pAct->IsInsertType() ) +/*N*/ { +/*N*/ if ( pAct->HasDependent() && !bRecursion ) +/*N*/ { +/*N*/ const ScBigRange& rRange = pAct->GetBigRange(); +/*N*/ DBG_ASSERT( pTable, "ScChangeTrack::Reject: Insert ohne Table" ); +/*N*/ for ( ScChangeAction* p = pTable->Last(); p && bOk; p = pTable->Prev() ) +/*N*/ { +/*N*/ // keine Contents restoren, die eh geloescht werden wuerden +/*N*/ if ( p->GetType() == SC_CAT_CONTENT ) +/*N*/ p->SetRejected(); +/*N*/ else if ( p->IsDeleteType() ) +/*N*/ p->Accept(); // geloeschtes ins Nirvana +/*N*/ else +/*N*/ bOk = Reject( p, NULL, TRUE ); //! rekursiv +/*N*/ } +/*N*/ } +/*N*/ if ( bOk && (bRejected = pAct->Reject( pDoc )) ) +/*N*/ { +/*N*/ // pRefDoc NULL := geloeschte Zellen nicht speichern +/*N*/ AppendDeleteRange( pAct->GetBigRange().MakeRange(), NULL, (short) 0, +/*N*/ pAct->GetActionNumber() ); +/*N*/ } +/*N*/ } +/*N*/ else if ( pAct->IsDeleteType() ) +/*N*/ { +/*N*/ DBG_ASSERT( !pTable, "ScChangeTrack::Reject: Delete mit Table" ); +/*N*/ ScBigRange aDelRange; +/*N*/ ULONG nRejectAction = pAct->GetActionNumber(); +/*N*/ BOOL bTabDel, bTabDelOk; +/*N*/ if ( pAct->GetType() == SC_CAT_DELETE_TABS ) +/*N*/ { +/*N*/ bTabDel = TRUE; +/*N*/ aDelRange = pAct->GetBigRange(); +/*N*/ bOk = bTabDelOk = pAct->Reject( pDoc ); +/*N*/ if ( bOk ) +/*N*/ { +/*N*/ pAct = pAct->GetPrev(); +/*N*/ bOk = ( pAct && pAct->GetType() == SC_CAT_DELETE_COLS ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ bTabDel = bTabDelOk = FALSE; +/*N*/ ScChangeActionDel* pDel = (ScChangeActionDel*) pAct; +/*N*/ if ( bOk ) +/*N*/ { +/*N*/ aDelRange = pDel->GetOverAllRange(); +/*N*/ bOk = aDelRange.IsValid( pDoc ); +/*N*/ } +/*N*/ BOOL bOneOk = FALSE; +/*N*/ if ( bOk ) +/*N*/ { +/*N*/ ScChangeActionType eActType = pAct->GetType(); +/*N*/ switch ( eActType ) +/*N*/ { +/*N*/ case SC_CAT_DELETE_COLS : +/*N*/ aDelRange.aStart.SetCol( aDelRange.aEnd.Col() ); +/*N*/ break; +/*N*/ case SC_CAT_DELETE_ROWS : +/*N*/ aDelRange.aStart.SetRow( aDelRange.aEnd.Row() ); +/*N*/ break; +/*N*/ case SC_CAT_DELETE_TABS : +/*N*/ aDelRange.aStart.SetTab( aDelRange.aEnd.Tab() ); +/*N*/ break; +/*N*/ } +/*N*/ ScChangeAction* p = pAct; +/*N*/ BOOL bLoop = TRUE; +/*N*/ do +/*N*/ { +/*N*/ pDel = (ScChangeActionDel*) p; +/*N*/ bOk = pDel->Reject( pDoc ); +/*N*/ if ( bOk ) +/*N*/ { +/*N*/ if ( bOneOk ) +/*N*/ { +/*N*/ switch ( pDel->GetType() ) +/*N*/ { +/*N*/ case SC_CAT_DELETE_COLS : +/*N*/ aDelRange.aStart.IncCol( -1 ); +/*N*/ break; +/*N*/ case SC_CAT_DELETE_ROWS : +/*N*/ aDelRange.aStart.IncRow( -1 ); +/*N*/ break; +/*N*/ case SC_CAT_DELETE_TABS : +/*N*/ aDelRange.aStart.IncTab( -1 ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ bOneOk = TRUE; +/*N*/ } +/*N*/ if ( pDel->IsBaseDelete() ) +/*N*/ bLoop = FALSE; +/*N*/ else +/*N*/ p = p->GetPrev(); +/*N*/ } while ( bOk && bLoop && p && p->GetType() == eActType && +/*N*/ !((ScChangeActionDel*)p)->IsTopDelete() ); +/*N*/ } +/*N*/ bRejected = bOk; +/*N*/ if ( bOneOk || (bTabDel && bTabDelOk) ) +/*N*/ { +/*N*/ // Delete-Reject machte UpdateReference Undo +/*N*/ ScChangeActionIns* pReject = new ScChangeActionIns( +/*N*/ aDelRange.MakeRange() ); +/*N*/ pReject->SetRejectAction( nRejectAction ); +/*N*/ pReject->SetState( SC_CAS_ACCEPTED ); +/*N*/ Append( pReject ); +/*N*/ } +/*N*/ } +/*N*/ else if ( pAct->GetType() == SC_CAT_MOVE ) +/*N*/ { +/*N*/ if ( pAct->HasDependent() && !bRecursion ) +/*N*/ { +/*N*/ const ScBigRange& rRange = pAct->GetBigRange(); +/*N*/ DBG_ASSERT( pTable, "ScChangeTrack::Reject: Move ohne Table" ); +/*N*/ for ( ScChangeAction* p = pTable->Last(); p && bOk; p = pTable->Prev() ) +/*N*/ { +/*N*/ bOk = Reject( p, NULL, TRUE ); //! rekursiv +/*N*/ } +/*N*/ } +/*N*/ if ( bOk && (bRejected = pAct->Reject( pDoc )) ) +/*N*/ { +/*N*/ ScChangeActionMove* pReject = new ScChangeActionMove( +/*N*/ pAct->GetBigRange().MakeRange(), +/*N*/ ((ScChangeActionMove*)pAct)->GetFromRange().MakeRange(), this ); +/*N*/ pReject->SetRejectAction( pAct->GetActionNumber() ); +/*N*/ pReject->SetState( SC_CAS_ACCEPTED ); +/*N*/ Append( pReject ); +/*N*/ } +/*N*/ } +/*N*/ else if ( pAct->GetType() == SC_CAT_CONTENT ) +/*N*/ { +/*N*/ ScRange aRange; +/*N*/ ScChangeActionContent* pReject; +/*N*/ if ( bRecursion ) +/*N*/ pReject = NULL; +/*N*/ else +/*N*/ { +/*N*/ aRange = pAct->GetBigRange().aStart.MakeAddress(); +/*N*/ pReject = new ScChangeActionContent( aRange ); +/*N*/ pReject->SetOldValue( pDoc->GetCell( aRange.aStart ), pDoc, pDoc ); +/*N*/ } +/*N*/ if ( (bRejected = pAct->Reject( pDoc )) && !bRecursion ) +/*N*/ { +/*N*/ pReject->SetNewValue( pDoc->GetCell( aRange.aStart ), pDoc ); +/*N*/ pReject->SetRejectAction( pAct->GetActionNumber() ); +/*N*/ pReject->SetState( SC_CAS_ACCEPTED ); +/*N*/ Append( pReject ); +/*N*/ } +/*N*/ else if ( pReject ) +/*N*/ delete pReject; +/*N*/ } +/*N*/ else +/*N*/ DBG_ERROR( "ScChangeTrack::Reject: say what?" ); +/*N*/ +/*N*/ return bRejected; +/*N*/ } + + +ULONG ScChangeTrack::AddLoadedGenerated(ScBaseCell* pNewCell, const ScBigRange& aBigRange ) +{ +/*N*/ ScChangeActionContent* pAct = new ScChangeActionContent( --nGeneratedMin, pNewCell, aBigRange, pDoc ); +/*N*/ if ( pAct ) +/*N*/ { +/*N*/ if ( pFirstGeneratedDelContent ) +/*N*/ pFirstGeneratedDelContent->pPrev = pAct; +/*N*/ pAct->pNext = pFirstGeneratedDelContent; +/*N*/ pFirstGeneratedDelContent = pAct; +/*N*/ aGeneratedTable.Insert( pAct->GetActionNumber(), pAct ); +/*N*/ return pAct->GetActionNumber(); +/*N*/ } +/*N*/ return 0; +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_chgviset.cxx b/binfilter/bf_sc/source/core/tool/sc_chgviset.cxx new file mode 100644 index 000000000000..64da1b2236eb --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_chgviset.cxx @@ -0,0 +1,161 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <unotools/textsearch.hxx> + +#include "chgviset.hxx" +#include "rechead.hxx" +namespace binfilter { +// ----------------------------------------------------------------------- +/*N*/ ScChangeViewSettings::~ScChangeViewSettings() +/*N*/ { +/*N*/ if(pCommentSearcher!=NULL) +/*?*/ delete pCommentSearcher; +/*N*/ } + + +// #i49161# this is needed to save documents with change tracking +ScChangeViewSettings& ScChangeViewSettings::operator=( const ScChangeViewSettings& r ) +{ + SetTheComment(r.aComment); + + aFirstDateTime =r.aFirstDateTime; + aLastDateTime =r.aLastDateTime; + aAuthorToShow =r.aAuthorToShow; + aRangeList =r.aRangeList; + eDateMode =r.eDateMode; + bShowIt =r.bShowIt; + bIsDate =r.bIsDate; + bIsAuthor =r.bIsAuthor; + bIsComment =r.bIsComment; + bIsRange =r.bIsRange; + bEveryoneButMe =r.bEveryoneButMe; + bShowAccepted =r.bShowAccepted; + bShowRejected =r.bShowRejected; + + return *this; +} + + +/*N*/ void ScChangeViewSettings::SetTheComment(const String& rString) +/*N*/ { +/*N*/ aComment=rString; +/*N*/ if(pCommentSearcher!=NULL) +/*N*/ { +/*N*/ delete pCommentSearcher; +/*N*/ pCommentSearcher=NULL; +/*N*/ } +/*N*/ +/*N*/ if(rString.Len()>0) +/*N*/ { +/*N*/ utl::SearchParam aSearchParam( rString, +/*N*/ utl::SearchParam::SRCH_REGEXP,FALSE,FALSE,FALSE ); +/*N*/ +/*N*/ pCommentSearcher = new utl::TextSearch( aSearchParam, *ScGlobal::pCharClass ); +/*N*/ } +/*N*/ } + +/*N*/ void ScChangeViewSettings::Load( SvStream& rStream, USHORT nVer ) +/*N*/ { +/*N*/ ScReadHeader aHdr( rStream ); +/*N*/ +/*N*/ BYTE nByte; +/*N*/ UINT32 nDT; +/*N*/ rStream >> bShowIt; +/*N*/ rStream >> bIsDate; +/*N*/ rStream >> nByte; eDateMode = (ScChgsDateMode)nByte; +/*N*/ rStream >> nDT; aFirstDateTime.SetDate( nDT ); +/*N*/ rStream >> nDT; aFirstDateTime.SetTime( nDT ); +/*N*/ rStream >> nDT; aLastDateTime.SetDate( nDT ); +/*N*/ rStream >> nDT; aLastDateTime.SetTime( nDT ); +/*N*/ rStream >> bIsAuthor; +/*N*/ rStream >> bEveryoneButMe; +/*N*/ rStream.ReadByteString( aAuthorToShow, rStream.GetStreamCharSet() ); +/*N*/ rStream >> bIsRange; +/*N*/ aRangeList.Load( rStream, nVer ); +/*N*/ if ( aHdr.BytesLeft() ) +/*N*/ { +/*N*/ rStream >> bShowAccepted; +/*N*/ rStream >> bShowRejected; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ bShowAccepted = FALSE; +/*N*/ bShowRejected = FALSE; +/*N*/ } +/*N*/ +/*N*/ // Zusaetzlich Kommentar-Informationen lesen (src509) +/*N*/ if ( aHdr.BytesLeft() ) //#59103# +/*N*/ { +/*N*/ rStream >> bIsComment; +/*N*/ rStream.ReadByteString( aComment, rStream.GetStreamCharSet() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ bIsComment = FALSE; +/*N*/ aComment.Erase(); +/*N*/ } +/*N*/ SetTheComment(aComment); +/*N*/ } + +/*N*/ void ScChangeViewSettings::Store( SvStream& rStream ) const +/*N*/ { +/*N*/ ScWriteHeader aHdr( rStream, 42 ); // Groesse, wenn String und RangeList leer sind +/*N*/ +/*N*/ rStream << bShowIt; +/*N*/ rStream << bIsDate; +/*N*/ rStream << (BYTE) eDateMode; +/*N*/ rStream << (UINT32) aFirstDateTime.GetDate(); +/*N*/ rStream << (UINT32) aFirstDateTime.GetTime(); +/*N*/ rStream << (UINT32) aLastDateTime.GetDate(); +/*N*/ rStream << (UINT32) aLastDateTime.GetTime(); +/*N*/ rStream << bIsAuthor; +/*N*/ rStream << bEveryoneButMe; +/*N*/ rStream.WriteByteString( aAuthorToShow, rStream.GetStreamCharSet() ); +/*N*/ rStream << bIsRange; +/*N*/ aRangeList.Store( rStream ); +/*N*/ rStream << bShowAccepted; +/*N*/ rStream << bShowRejected; +/*N*/ +/*N*/ // Zusaetzlich Kommentar-Informationen schreiben (src509) +/*N*/ if(bIsComment || aComment.Len()>0) //#59103# +/*N*/ { +/*N*/ rStream << bIsComment; +/*N*/ rStream.WriteByteString( aComment, rStream.GetStreamCharSet() ); +/*N*/ } +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_collect.cxx b/binfilter/bf_sc/source/core/tool/sc_collect.cxx new file mode 100644 index 000000000000..19116fd89860 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_collect.cxx @@ -0,0 +1,374 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <string.h> + + +#include "rechead.hxx" +#include "collect.hxx" +#include "document.hxx" +#include <tools/debug.hxx>// fuer TypedStrData Konstruktor +namespace binfilter { + +// ----------------------------------------------------------------------- + +/*N*/ DataObject::~DataObject() +/*N*/ { +/*N*/ } + +//------------------------------------------------------------------------ +// Collection +//------------------------------------------------------------------------ + +/*N*/ void lcl_DeleteDataObjects( DataObject** p, USHORT nCount ) +/*N*/ { +/*N*/ if ( p ) +/*N*/ { +/*N*/ for (USHORT i = 0; i < nCount; i++) delete p[i]; +/*N*/ delete[] p; +/*N*/ p = NULL; +/*N*/ } +/*N*/ } + +/*N*/ Collection::Collection(USHORT nLim, USHORT nDel) : +/*N*/ nCount ( 0 ), +/*N*/ nLimit ( nLim ), +/*N*/ nDelta ( nDel ), +/*N*/ pItems ( NULL ) +/*N*/ { +/*N*/ if (nDelta > MAXDELTA) +/*N*/ nDelta = MAXDELTA; +/*N*/ else if (nDelta == 0) +/*N*/ nDelta = 1; +/*N*/ if (nLimit > MAXCOLLECTIONSIZE) +/*N*/ nLimit = MAXCOLLECTIONSIZE; +/*N*/ else if (nLimit < nDelta) +/*N*/ nLimit = nDelta; +/*N*/ pItems = new DataObject*[nLimit]; +/*N*/ } + +/*N*/ Collection::Collection(const Collection& rCollection) +/*N*/ : nCount ( 0 ), +/*N*/ nLimit ( 0 ), +/*N*/ nDelta ( 0 ), +/*N*/ pItems ( NULL ) +/*N*/ { +/*N*/ *this = rCollection; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ Collection::~Collection() +/*N*/ { +/*N*/ lcl_DeleteDataObjects( pItems, nCount ); +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ void Collection::AtFree(USHORT nIndex) +/*N*/ { +/*N*/ if ((pItems) && (nIndex < nCount)) +/*N*/ { +/*N*/ delete pItems[nIndex]; +/*N*/ --nCount; // before memmove +/*N*/ memmove ( &pItems[nIndex], &pItems[nIndex + 1], (nCount - nIndex) * sizeof(DataObject*)); +/*N*/ pItems[nCount] = NULL; +/*N*/ } +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ void Collection::Free(DataObject* pDataObject) +/*N*/ { +/*N*/ AtFree(IndexOf(pDataObject)); +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ void Collection::FreeAll() +/*N*/ { +/*N*/ lcl_DeleteDataObjects( pItems, nCount ); +/*N*/ nCount = 0; +/*N*/ pItems = new DataObject*[nLimit]; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ BOOL Collection::AtInsert(USHORT nIndex, DataObject* pDataObject) +/*N*/ { +/*N*/ if ((nCount < MAXCOLLECTIONSIZE) && (nIndex <= nCount) && pItems) +/*N*/ { +/*N*/ if (nCount == nLimit) +/*N*/ { +/*N*/ DataObject** pNewItems = new DataObject*[nLimit + nDelta]; +/*N*/ if (!pNewItems) +/*N*/ return FALSE; +/*N*/ nLimit += nDelta; +/*N*/ memmove(pNewItems, pItems, nCount * sizeof(DataObject*)); +/*N*/ delete[] pItems; +/*N*/ pItems = pNewItems; +/*N*/ } +/*N*/ if (nCount > nIndex) +/*N*/ memmove(&pItems[nIndex + 1], &pItems[nIndex], (nCount - nIndex) * sizeof(DataObject*)); +/*N*/ pItems[nIndex] = pDataObject; +/*N*/ nCount++; +/*N*/ return TRUE; +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ BOOL Collection::Insert(DataObject* pDataObject) +/*N*/ { +/*N*/ return AtInsert(nCount, pDataObject); +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ DataObject* Collection::At(USHORT nIndex) const +/*N*/ { +/*N*/ if (nIndex < nCount) +/*N*/ return pItems[nIndex]; +/*N*/ else +/*N*/ return NULL; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ USHORT Collection::IndexOf(DataObject* pDataObject) const +/*N*/ { +/*N*/ USHORT nIndex = 0xffff; +/*N*/ for (USHORT i = 0; ((i < nCount) && (nIndex == 0xffff)); i++) +/*N*/ { +/*N*/ if (pItems[i] == pDataObject) nIndex = i; +/*N*/ } +/*N*/ return nIndex; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ Collection& Collection::operator=( const Collection& r ) +/*N*/ { +/*N*/ lcl_DeleteDataObjects( pItems, nCount ); +/*N*/ +/*N*/ nCount = r.nCount; +/*N*/ nLimit = r.nLimit; +/*N*/ nDelta = r.nDelta; +/*N*/ pItems = new DataObject*[nLimit]; +/*N*/ for ( USHORT i=0; i<nCount; i++ ) +/*N*/ pItems[i] = r.pItems[i]->Clone(); +/*N*/ +/*N*/ return *this; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ DataObject* Collection::Clone() const +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); return NULL; //STRIP001 return new Collection(*this); +/*N*/ } + +//------------------------------------------------------------------------ +// SortedCollection +//------------------------------------------------------------------------ + +/*N*/ SortedCollection::SortedCollection(USHORT nLim, USHORT nDel, BOOL bDup) : +/*N*/ Collection (nLim, nDel), +/*N*/ bDuplicates ( bDup) +/*N*/ { +/*N*/ } + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + +/*N*/ BOOL SortedCollection::Search(DataObject* pDataObject, USHORT& rIndex) const +/*N*/ { +/*N*/ rIndex = nCount; +/*N*/ BOOL bFound = FALSE; +/*N*/ short nLo = 0; +/*N*/ short nHi = nCount - 1; +/*N*/ short nIndex; +/*N*/ short nCompare; +/*N*/ while (nLo <= nHi) +/*N*/ { +/*N*/ nIndex = (nLo + nHi) / 2; +/*N*/ nCompare = Compare(pItems[nIndex], pDataObject); +/*N*/ if (nCompare < 0) +/*N*/ nLo = nIndex + 1; +/*N*/ else +/*N*/ { +/*N*/ nHi = nIndex - 1; +/*N*/ if (nCompare == 0) +/*N*/ { +/*N*/ bFound = TRUE; +/*N*/ nLo = nIndex; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ rIndex = nLo; +/*N*/ return bFound; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ BOOL SortedCollection::Insert(DataObject* pDataObject) +/*N*/ { +/*N*/ USHORT nIndex; +/*N*/ BOOL bFound = Search(pDataObject, nIndex); +/*N*/ if (bFound) +/*N*/ { +/*N*/ if (bDuplicates) +/*N*/ return AtInsert(nIndex, pDataObject); +/*N*/ else +/*N*/ return FALSE; +/*N*/ } +/*N*/ else +/*N*/ return AtInsert(nIndex, pDataObject); +/*N*/ } + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + +// IsEqual - komplette Inhalte vergleichen + + +//------------------------------------------------------------------------ + +/*N*/ DataObject* StrData::Clone() const +/*N*/ { + return new StrData(*this); // #i49161# this is needed +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ short StrCollection::Compare(DataObject* pKey1, DataObject* pKey2) const +/*N*/ { +/*N*/ StringCompare eComp = ((StrData*)pKey1)->aStr.CompareTo(((StrData*)pKey2)->aStr); +/*N*/ if (eComp == COMPARE_EQUAL) +/*N*/ return 0; +/*N*/ else if (eComp == COMPARE_LESS) +/*N*/ return -1; +/*N*/ else +/*N*/ return 1; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ DataObject* StrCollection::Clone() const +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); return NULL;//STRIP001 return new StrCollection(*this); +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ void StrCollection::Load( SvStream& rStream ) // Changetracking.sdc +/*N*/ { +/*N*/ ScReadHeader aHdr( rStream ); +/*N*/ lcl_DeleteDataObjects( pItems, nCount ); +/*N*/ BOOL bDups; +/*N*/ rStream >> bDups; +/*N*/ SetDups( bDups ); +/*N*/ rStream >> nCount >> nLimit >> nDelta; +/*N*/ pItems = new DataObject*[nLimit]; +/*N*/ String aStr; +/*N*/ rtl_TextEncoding eSet = rStream.GetStreamCharSet(); +/*N*/ for ( USHORT i=0; i<nCount; i++ ) +/*N*/ { +/*N*/ rStream.ReadByteString( aStr, eSet ); +/*N*/ pItems[i] = new StrData( aStr ); +/*N*/ } +/*N*/ } + +/*N*/ void StrCollection::Store( SvStream& rStream ) const +/*N*/ { +/*N*/ ScWriteHeader aHdr( rStream ); +/*N*/ BOOL bDups = IsDups(); +/*N*/ rStream << bDups << nCount << nLimit << nDelta; +/*N*/ rtl_TextEncoding eSet = rStream.GetStreamCharSet(); +/*N*/ for ( USHORT i=0; i<nCount; i++ ) +/*N*/ { +/*N*/ rStream.WriteByteString( ((StrData*)pItems[i])->GetString(), eSet ); +/*N*/ } +/*N*/ } + +//------------------------------------------------------------------------ +// TypedStrCollection +//------------------------------------------------------------------------ + +/*N*/ TypedStrData::TypedStrData( ScDocument* pDoc, USHORT nCol, USHORT nRow, USHORT nTab, +/*N*/ BOOL bAllStrings ) +/*N*/ { +/*N*/ if ( pDoc->HasValueData( nCol, nRow, nTab ) ) +/*N*/ { +/*?*/ pDoc->GetValue( nCol, nRow, nTab, nValue ); +/*?*/ if (bAllStrings) +/*?*/ pDoc->GetString( nCol, nRow, nTab, aStrValue ); +/*?*/ nStrType = 0; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pDoc->GetString( nCol, nRow, nTab, aStrValue ); +/*N*/ nValue = 0.0; +/*N*/ nStrType = 1; //! Typ uebergeben ? +/*N*/ } +/*N*/ } + +/*N*/ DataObject* TypedStrData::Clone() const +/*N*/ { +/*N*/ return new TypedStrData(*this); +/*N*/ } + + +/*N*/ short TypedStrCollection::Compare( DataObject* pKey1, DataObject* pKey2 ) const +/*N*/ { +/*N*/ short nResult = 0; +DBG_BF_ASSERT(0, "STRIP"); //STRIP001 //STRIP001 if ( pKey1 && pKey2 ) +/*N*/ return nResult; +/*N*/ } + + + // Gross-/Kleinschreibung anpassen + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_compiler.cxx b/binfilter/bf_sc/source/core/tool/sc_compiler.cxx new file mode 100644 index 000000000000..c238b6360f25 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_compiler.cxx @@ -0,0 +1,3240 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// INCLUDE --------------------------------------------------------------- + +#include <bf_sfx2/app.hxx> +#include <bf_sfx2/objsh.hxx> +#include "bf_basic/sbmeth.hxx" +#include "bf_basic/sbstar.hxx" +#include <bf_svtools/zforlist.hxx> +#include <tools/rcid.h> +#include <tools/solar.h> +#include <tools/urlobj.hxx> +#include <rtl/math.hxx> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include "rangenam.hxx" +#include "dbcolect.hxx" +#include "document.hxx" +#include "callform.hxx" +#include "addincol.hxx" +#include "refupdat.hxx" +#include "scresid.hxx" +#include "bf_sc.hrc" +#include "globstr.hrc" +#include "cell.hxx" +#include "dociter.hxx" +#include "docoptio.hxx" +namespace binfilter { + + +/*N*/ String* ScCompiler::pSymbolTableNative = NULL; +/*N*/ String* ScCompiler::pSymbolTableEnglish = NULL; +/*N*/ USHORT ScCompiler::nAnzStrings = 0; +/*N*/ ULONG* ScCompiler::pCharTable = 0; +/*N*/ ScOpCodeHashMap* ScCompiler::pSymbolHashMapNative = NULL; +/*N*/ ScOpCodeHashMap* ScCompiler::pSymbolHashMapEnglish = NULL; + +/*N*/ enum ScanState +/*N*/ { +/*N*/ ssGetChar, +/*N*/ ssGetBool, +/*N*/ ssGetString, +/*N*/ ssSkipString, +/*N*/ ssGetIdent, +/*N*/ ssStop +/*N*/ }; + +/*N*/ struct ScArrayStack +/*N*/ { +/*N*/ ScArrayStack* pNext; +/*N*/ ScTokenArray* pArr; +/*N*/ BOOL bTemp; +/*N*/ }; + +/*N*/ static sal_Char* pInternal[ 5 ] = { "GAME", "SPEW", "TTT", "STARCALCTEAM", "ANTWORT" }; + + +///////////////////////////////////////////////////////////////////////// + +/*N*/ short lcl_GetRetFormat( OpCode eOpCode ) +/*N*/ { +/*N*/ switch (eOpCode) +/*N*/ { +/*N*/ case ocEqual: +/*N*/ case ocNotEqual: +/*N*/ case ocLess: +/*N*/ case ocGreater: +/*N*/ case ocLessEqual: +/*N*/ case ocGreaterEqual: +/*N*/ case ocAnd: +/*N*/ case ocOr: +/*N*/ case ocNot: +/*N*/ case ocTrue: +/*N*/ case ocFalse: +/*N*/ case ocIsEmpty: +/*N*/ case ocIsString: +/*N*/ case ocIsNonString: +/*N*/ case ocIsLogical: +/*N*/ case ocIsRef: +/*N*/ case ocIsValue: +/*N*/ case ocIsFormula: +/*N*/ case ocIsNV: +/*N*/ case ocIsErr: +/*N*/ case ocIsError: +/*N*/ case ocIsEven: +/*N*/ case ocIsOdd: +/*N*/ case ocExact: +/*N*/ return NUMBERFORMAT_LOGICAL; +/*N*/ case ocGetActDate: +/*N*/ case ocGetDate: +/*N*/ case ocEasterSunday : +/*N*/ return NUMBERFORMAT_DATE; +/*N*/ case ocGetActTime: +/*N*/ return NUMBERFORMAT_DATETIME; +/*N*/ case ocGetTime: +/*N*/ return NUMBERFORMAT_TIME; +/*N*/ case ocNBW: +/*N*/ case ocBW: +/*N*/ case ocDIA: +/*N*/ case ocGDA: +/*N*/ case ocGDA2: +/*N*/ case ocVBD: +/*N*/ case ocLIA: +/*N*/ case ocRMZ: +/*N*/ case ocZW: +/*N*/ case ocZinsZ: +/*N*/ case ocKapz: +/*N*/ case ocKumZinsZ: +/*N*/ case ocKumKapZ: +/*N*/ return NUMBERFORMAT_CURRENCY; +/*N*/ case ocZins: +/*N*/ case ocIKV: +/*N*/ case ocMIRR: +/*N*/ case ocZGZ: +/*N*/ case ocEffektiv: +/*N*/ case ocNominal: +/*N*/ case ocPercentSign: +/*N*/ return NUMBERFORMAT_PERCENT; +/*N*/ // case ocSum: +/*N*/ // case ocSumSQ: +/*N*/ // case ocProduct: +/*N*/ // case ocAverage: +/*N*/ // return -1; +/*N*/ default: +/*N*/ return NUMBERFORMAT_NUMBER; +/*N*/ } +/*N*/ return NUMBERFORMAT_NUMBER; +/*N*/ } + +///////////////////////////////////////////////////////////////////////// + +/*N*/ class ScOpCodeList : public Resource // temp object fuer Resource +/*N*/ { +/*N*/ public: +/*N*/ ScOpCodeList( USHORT, String[], ScOpCodeHashMap& ); +/*N*/ }; + +/*N*/ ScOpCodeList::ScOpCodeList( USHORT nRID, String pSymbolTable[], ScOpCodeHashMap& rHashMap ) +/*N*/ : +/*N*/ Resource( ScResId( nRID ) ) +/*N*/ { +/*N*/ for (USHORT i = 0; i <= SC_OPCODE_LAST_OPCODE_ID; i++) +/*N*/ { +/*N*/ ScResId aRes(i); +/*N*/ aRes.SetRT(RSC_STRING); +/*N*/ if (IsAvailableRes(aRes)) +/*N*/ { +/*N*/ pSymbolTable[i] = aRes; +/*N*/ rHashMap.insert( ScOpCodeHashMap::value_type( pSymbolTable[i], (OpCode) i ) ); +/*N*/ } +/*N*/ } +/*N*/ FreeResource(); +/*N*/ } + + +/*N*/ class ScCompilerRecursionGuard +/*N*/ { +/*N*/ private: +/*N*/ short& rRecursion; +/*N*/ public: +/*N*/ ScCompilerRecursionGuard( short& rRec ) +/*N*/ : rRecursion( rRec ) { ++rRecursion; } +/*N*/ ~ScCompilerRecursionGuard() { --rRecursion; } +/*N*/ }; + + +/*N*/ void ScCompiler::Init() +/*N*/ { +/*N*/ pSymbolTableNative = new String[SC_OPCODE_LAST_OPCODE_ID+1]; +/*N*/ pSymbolHashMapNative = new ScOpCodeHashMap( SC_OPCODE_LAST_OPCODE_ID+1 ); +/*N*/ ScOpCodeList aOpCodeListNative( RID_SC_FUNCTION_NAMES, pSymbolTableNative, +/*N*/ *pSymbolHashMapNative ); +/*N*/ nAnzStrings = SC_OPCODE_LAST_OPCODE_ID+1; +/*N*/ +/*N*/ pCharTable = new ULONG [128]; +/*N*/ USHORT i; +/*N*/ for (i = 0; i < 128; i++) +/*N*/ pCharTable[i] = SC_COMPILER_C_ILLEGAL; +/*N*/ /* */ pCharTable[32] = SC_COMPILER_C_CHAR_DONTCARE | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; +/*N*/ /* ! */ pCharTable[33] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; +/*N*/ /* " */ pCharTable[34] = SC_COMPILER_C_CHAR_STRING | SC_COMPILER_C_STRING_SEP; +/*N*/ /* # */ pCharTable[35] = SC_COMPILER_C_WORD_SEP; +/*N*/ /* $ */ pCharTable[36] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT; +/*N*/ /* % */ pCharTable[37] = SC_COMPILER_C_VALUE; +/*N*/ /* & */ pCharTable[38] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; +/*N*/ /* ' */ pCharTable[39] = SC_COMPILER_C_NAME_SEP; +/*N*/ /* ( */ pCharTable[40] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; +/*N*/ /* ) */ pCharTable[41] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; +/*N*/ /* * */ pCharTable[42] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; +/*N*/ /* + */ pCharTable[43] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_EXP | SC_COMPILER_C_VALUE_SIGN; +/*N*/ /* , */ pCharTable[44] = SC_COMPILER_C_CHAR_VALUE | SC_COMPILER_C_VALUE; +/*N*/ /* - */ pCharTable[45] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_EXP | SC_COMPILER_C_VALUE_SIGN; +/*N*/ /* . */ pCharTable[46] = SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_VALUE | SC_COMPILER_C_VALUE | SC_COMPILER_C_IDENT; +/*N*/ /* / */ pCharTable[47] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; +/*N*/ for (i = 48; i < 58; i++) +/*N*/ /* 0-9 */ pCharTable[i] = SC_COMPILER_C_CHAR_VALUE | SC_COMPILER_C_WORD | SC_COMPILER_C_VALUE | SC_COMPILER_C_VALUE_EXP | SC_COMPILER_C_VALUE_VALUE | SC_COMPILER_C_IDENT; +/*N*/ /* : */ pCharTable[58] = SC_COMPILER_C_WORD | SC_COMPILER_C_IDENT; +/*N*/ /* ; */ pCharTable[59] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; +/*N*/ /* < */ pCharTable[60] = SC_COMPILER_C_CHAR_BOOL | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; +/*N*/ /* = */ pCharTable[61] = SC_COMPILER_C_CHAR | SC_COMPILER_C_BOOL | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; +/*N*/ /* > */ pCharTable[62] = SC_COMPILER_C_CHAR_BOOL | SC_COMPILER_C_BOOL | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; +/*N*/ /* ? */ pCharTable[63] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD; +/*N*/ /* @ */ // FREI +/*N*/ for (i = 65; i < 91; i++) +/*N*/ /* A-Z */ pCharTable[i] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT; +/*N*/ /* [ */ // FREI +/*N*/ /* \ */ // FREI +/*N*/ /* ] */ // FREI +/*N*/ /* ^ */ pCharTable[94] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; +/*N*/ /* _ */ pCharTable[95] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT; +/*N*/ /* ` */ // FREI +/*N*/ for (i = 97; i < 123; i++) +/*N*/ /* a-z */ pCharTable[i] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT; +/*N*/ /* { */ // FREI +/*N*/ /* | */ // FREI +/*N*/ /* } */ // FREI +/*N*/ /* ~ */ // FREI +/*N*/ /* 127 */ // FREI +/*N*/ } + +/*N*/ void ScCompiler::DeInit() +/*N*/ { +/*N*/ if (pSymbolTableNative) +/*N*/ { +/*N*/ delete [] pSymbolTableNative; +/*N*/ pSymbolTableNative = NULL; +/*N*/ } +/*N*/ if (pSymbolTableEnglish) +/*N*/ { +/*?*/ delete [] pSymbolTableEnglish; +/*?*/ pSymbolTableEnglish = NULL; +/*N*/ } +/*N*/ if ( pSymbolHashMapNative ) +/*N*/ { +/*?*/ pSymbolHashMapNative->clear(); +/*?*/ delete pSymbolHashMapNative; +/*?*/ pSymbolHashMapNative = NULL; +/*N*/ } +/*N*/ if ( pSymbolHashMapEnglish ) +/*N*/ { +/*?*/ pSymbolHashMapEnglish->clear(); +/*?*/ delete pSymbolHashMapEnglish; +/*?*/ pSymbolHashMapEnglish = NULL; +/*N*/ } +/*N*/ delete [] pCharTable; +/*N*/ pCharTable = NULL; +/*N*/ } + +/*N*/ void ScCompiler::SetCompileEnglish( BOOL bCompileEnglish ) +/*N*/ { +/*N*/ if ( bCompileEnglish ) +/*N*/ { +/*N*/ if ( !pSymbolTableEnglish ) +/*N*/ { +/*N*/ pSymbolTableEnglish = new String[SC_OPCODE_LAST_OPCODE_ID+1]; +/*N*/ pSymbolHashMapEnglish = new ScOpCodeHashMap( SC_OPCODE_LAST_OPCODE_ID+1 ); +/*N*/ ScOpCodeList aOpCodeListEnglish( RID_SC_FUNCTION_NAMES_ENGLISH, +/*N*/ pSymbolTableEnglish, *pSymbolHashMapEnglish ); +/*N*/ } +/*N*/ pSymbolTable = pSymbolTableEnglish; +/*N*/ pSymbolHashMap = pSymbolHashMapEnglish; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pSymbolTable = pSymbolTableNative; +/*N*/ pSymbolHashMap = pSymbolHashMapNative; +/*N*/ } +/*N*/ } + +//-----------------------Funktionen der Klasse ScCompiler---------------------- + +/*N*/ ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos, +/*N*/ const ScTokenArray& rArr ) +/*N*/ : +/*N*/ aPos( rPos ), +/*N*/ pSymbolTable( pSymbolTableNative ), +/*N*/ pSymbolHashMap( pSymbolHashMapNative ), +/*N*/ nRecursion(0), +/*N*/ bAutoCorrect( FALSE ), +/*N*/ bCorrected( FALSE ), +/*N*/ bCompileForFAP( FALSE ), +/*N*/ bIgnoreErrors( FALSE ), +/*N*/ bCompileXML( FALSE ), +/*N*/ bImportXML ( FALSE ) +/*N*/ { +/*N*/ if (!nAnzStrings) +/*?*/ Init(); +/*N*/ pArr = (ScTokenArray*) ⇒ +/*N*/ pDoc = pDocument; +/*N*/ nMaxTab = pDoc->GetTableCount() - 1; +/*N*/ pStack = NULL; +/*N*/ nNumFmt = NUMBERFORMAT_UNDEFINED; +/*N*/ } + +/*N*/ ScCompiler::ScCompiler(ScDocument* pDocument, const ScAddress& rPos ) +/*N*/ : +/*N*/ aPos( rPos ), +/*N*/ pSymbolTable( pSymbolTableNative ), +/*N*/ pSymbolHashMap( pSymbolHashMapNative ), +/*N*/ nRecursion(0), +/*N*/ bAutoCorrect( FALSE ), +/*N*/ bCorrected( FALSE ), +/*N*/ bCompileForFAP( FALSE ), +/*N*/ bIgnoreErrors( FALSE ), +/*N*/ bCompileXML( FALSE ), +/*N*/ bImportXML ( FALSE ) +/*N*/ { +/*N*/ if (!nAnzStrings) +/*?*/ Init(); +/*N*/ pDoc = pDocument; +/*N*/ nMaxTab = pDoc->GetTableCount() - 1; +/*N*/ pStack = NULL; +/*N*/ nNumFmt = NUMBERFORMAT_UNDEFINED; +/*N*/ } + + +/*N*/ void ScCompiler::MakeColStr( ::rtl::OUStringBuffer& rBuffer, USHORT nCol ) +/*N*/ { +/*N*/ if ( nCol > MAXCOL ) +/*?*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE)); +/*N*/ else +/*N*/ { +/*N*/ if (nCol < 26) +/*N*/ rBuffer.append( sal_Unicode('A' + (sal_uChar) nCol)); +/*N*/ else +/*N*/ { +/*?*/ USHORT nLoCol = nCol % 26; +/*?*/ USHORT nHiCol = (nCol / 26) - 1; +/*?*/ rBuffer.append( sal_Unicode('A' + (sal_uChar)nHiCol) ); +/*?*/ rBuffer.append( sal_Unicode('A' + (sal_uChar)nLoCol) ); +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void ScCompiler::MakeRowStr( ::rtl::OUStringBuffer& rBuffer, USHORT nRow ) +/*N*/ { +/*N*/ if ( nRow > MAXROW ) +/*?*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE)); +/*N*/ else +/*N*/ rBuffer.append(sal_Int32(nRow + 1)); +/*N*/ } + +/*N*/ String ScCompiler::MakeTabStr( USHORT nTab, String& aDoc ) +/*N*/ { +/*N*/ String aString; +/*N*/ if (!pDoc->GetName(nTab, aString)) +/*?*/ aString = ScGlobal::GetRscString(STR_NO_REF_TABLE); +/*N*/ else +/*N*/ { +/*N*/ if ( aString.GetChar(0) == '\'' ) +/*N*/ { // "'Doc'#Tab" +/*N*/ xub_StrLen nPos, nLen = 1; +/*N*/ while( (nPos = aString.Search( '\'', nLen )) != STRING_NOTFOUND ) +/*N*/ nLen = nPos + 1; +/*N*/ if ( aString.GetChar(nLen) == SC_COMPILER_FILE_TAB_SEP ) +/*N*/ { +/*N*/ aDoc = aString.Copy( 0, nLen + 1 ); +/*N*/ aString.Erase( 0, nLen + 1 ); +/*N*/ aDoc = INetURLObject::decode( aDoc, INET_HEX_ESCAPE, +/*N*/ INetURLObject::DECODE_UNAMBIGUOUS ); +/*N*/ } +/*N*/ else +/*?*/ aDoc.Erase(); +/*N*/ } +/*N*/ else +/*N*/ aDoc.Erase(); +/*N*/ CheckTabQuotes( aString ); +/*N*/ } +/*N*/ aString += '.'; +/*N*/ return aString; +/*N*/ } + +/*N*/ void ScCompiler::CheckTabQuotes( String& rString ) +/*N*/ { +/*N*/ register const sal_Unicode* p = rString.GetBuffer(); +/*N*/ register const sal_Unicode* const pEnd = p + rString.Len(); +/*N*/ while ( p < pEnd ) +/*N*/ { +/*N*/ if( !IsWordChar( *p ) ) +/*N*/ { +/*N*/ rString.Insert( '\'', 0 ); +/*N*/ rString += '\''; +/*N*/ return ; +/*N*/ } +/*N*/ p++; +/*N*/ } +/*N*/ if ( CharClass::isAsciiNumeric( rString ) ) +/*N*/ { +/*N*/ rString.Insert( '\'', 0 ); +/*N*/ rString += '\''; +/*N*/ } +/*N*/ } + +/*N*/ void ScCompiler::MakeRefStr( ::rtl::OUStringBuffer& rBuffer, ComplRefData& rRef, BOOL bSingleRef ) +/*N*/ { +/*N*/ if (bCompileXML) +/*N*/ rBuffer.append(sal_Unicode('[')); +/*N*/ ComplRefData aRef( rRef ); +/*N*/ // falls abs/rel nicht separat: Relativ- in Abs-Referenzen wandeln! +/*N*/ // AdjustReference( aRef.Ref1 ); +/*N*/ // if( !bSingleRef ) +/*N*/ // AdjustReference( aRef.Ref2 ); +/*N*/ aRef.Ref1.CalcAbsIfRel( aPos ); +/*N*/ if( !bSingleRef ) +/*N*/ aRef.Ref2.CalcAbsIfRel( aPos ); +/*N*/ if( aRef.Ref1.IsFlag3D() ) +/*N*/ { +/*N*/ if (aRef.Ref1.IsTabDeleted()) +/*N*/ { +/*?*/ if (!aRef.Ref1.IsTabRel()) +/*?*/ rBuffer.append(sal_Unicode('$')); +/*?*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE)); +/*?*/ rBuffer.append(sal_Unicode('.')); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ String aDoc; +/*N*/ String aRefStr( MakeTabStr( aRef.Ref1.nTab, aDoc ) ); +/*N*/ rBuffer.append(aDoc); +/*N*/ if (!aRef.Ref1.IsTabRel()) rBuffer.append(sal_Unicode('$')); +/*N*/ rBuffer.append(aRefStr); +/*N*/ } +/*N*/ } +/*N*/ else if (bCompileXML) +/*N*/ rBuffer.append(sal_Unicode('.')); +/*N*/ if (!aRef.Ref1.IsColRel()) +/*N*/ rBuffer.append(sal_Unicode('$')); +/*N*/ if ( aRef.Ref1.IsColDeleted() ) +/*?*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE)); +/*N*/ else +/*N*/ MakeColStr(rBuffer, aRef.Ref1.nCol ); +/*N*/ if (!aRef.Ref1.IsRowRel()) +/*N*/ rBuffer.append(sal_Unicode('$')); +/*N*/ if ( aRef.Ref1.IsRowDeleted() ) +/*?*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE)); +/*N*/ else +/*N*/ MakeRowStr( rBuffer, aRef.Ref1.nRow ); +/*N*/ if (!bSingleRef) +/*N*/ { +/*N*/ rBuffer.append(sal_Unicode(':')); +/*N*/ if (aRef.Ref2.IsFlag3D() || aRef.Ref2.nTab != aRef.Ref1.nTab) +/*N*/ { +/*?*/ if (aRef.Ref2.IsTabDeleted()) +/*?*/ { +/*?*/ if (!aRef.Ref2.IsTabRel()) +/*?*/ rBuffer.append(sal_Unicode('$')); +/*?*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE)); +/*?*/ rBuffer.append(sal_Unicode('.')); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ String aDoc; +/*?*/ String aRefStr( MakeTabStr( aRef.Ref2.nTab, aDoc ) ); +/*?*/ rBuffer.append(aDoc); +/*?*/ if (!aRef.Ref2.IsTabRel()) rBuffer.append(sal_Unicode('$')); +/*?*/ rBuffer.append(aRefStr); +/*?*/ } +/*N*/ } +/*N*/ else if (bCompileXML) +/*N*/ rBuffer.append(sal_Unicode('.')); +/*N*/ if (!aRef.Ref2.IsColRel()) +/*N*/ rBuffer.append(sal_Unicode('$')); +/*N*/ if ( aRef.Ref2.IsColDeleted() ) +/*N*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE)); +/*N*/ else +/*N*/ MakeColStr( rBuffer, aRef.Ref2.nCol ); +/*N*/ if (!aRef.Ref2.IsRowRel()) +/*N*/ rBuffer.append(sal_Unicode('$')); +/*N*/ if ( aRef.Ref2.IsRowDeleted() ) +/*N*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE)); +/*N*/ else +/*N*/ MakeRowStr( rBuffer, aRef.Ref2.nRow ); +/*N*/ } +/*N*/ if (bCompileXML) +/*N*/ rBuffer.append(sal_Unicode(']')); +/*N*/ } + +//--------------------------------------------------------------------------- + +/*N*/ void ScCompiler::SetError(USHORT nError) +/*N*/ { +/*N*/ if( !pArr->GetError() ) +/*N*/ pArr->nError = nError; +/*N*/ } + + +/*N*/ sal_Unicode* lcl_UnicodeStrNCpy( sal_Unicode* pDst, const sal_Unicode* pSrc, xub_StrLen nMax ) +/*N*/ { +/*N*/ const sal_Unicode* const pStop = pDst + nMax; +/*N*/ while ( *pSrc && pDst < pStop ) +/*N*/ { +/*N*/ *pDst++ = *pSrc++; +/*N*/ } +/*N*/ *pDst = 0; +/*N*/ return pDst; +/*N*/ } + + +//--------------------------------------------------------------------------- +// NextSymbol +//--------------------------------------------------------------------------- +// Zerlegt die Formel in einzelne Symbole fuer die weitere +// Verarbeitung (Turing-Maschine). +//--------------------------------------------------------------------------- +// Ausgangs Zustand = GetChar +//---------------+-------------------+-----------------------+--------------- +// Alter Zustand | gelesenes Zeichen | Aktion | Neuer Zustand +//---------------+-------------------+-----------------------+--------------- +// GetChar | ;()+-*/^=& | Symbol=Zeichen | Stop +// | <> | Symbol=Zeichen | GetBool +// | $ Buchstabe | Symbol=Zeichen | GetWord +// | Ziffer | Symbol=Zeichen | GetValue +// | " | Keine | GetString +// | Sonst | Keine | GetChar +//---------------+-------------------+-----------------------+--------------- +// GetBool | => | Symbol=Symbol+Zeichen | Stop +// | Sonst | Dec(CharPos) | Stop +//---------------+-------------------+-----------------------+--------------- +// GetWord | SepSymbol | Dec(CharPos) | Stop +// | ()+-*/^=<>&~ | | +// | Leerzeichen | Dec(CharPos) | Stop +// | $_:. | | +// | Buchstabe,Ziffer | Symbol=Symbol+Zeichen | GetWord +// | Sonst | Fehler | Stop +//---------------|-------------------+-----------------------+--------------- +// GetValue | ;()*/^=<>& | | +// | Leerzeichen | Dec(CharPos) | Stop +// | Ziffer E+-%,. | Symbol=Symbol+Zeichen | GetValue +// | Sonst | Fehler | Stop +//---------------+-------------------+-----------------------+--------------- +// GetString | " | Keine | Stop +// | Sonst | Symbol=Symbol+Zeichen | GetString +//---------------+-------------------+-----------------------+--------------- + +/*N*/ xub_StrLen ScCompiler::NextSymbol() +/*N*/ { +/*N*/ cSymbol[MAXSTRLEN-1] = 0; // Stopper +/*N*/ sal_Unicode* pSym = cSymbol; +/*N*/ const sal_Unicode* const pStart = aFormula.GetBuffer(); +/*N*/ const sal_Unicode* pSrc = pStart + nSrcPos; +/*N*/ BOOL bi18n = FALSE; +/*N*/ sal_Unicode c = *pSrc; +/*N*/ sal_Unicode cLast = 0; +/*N*/ BOOL bQuote = FALSE; +/*N*/ ScanState eState = ssGetChar; +/*N*/ xub_StrLen nSpaces = 0; +/*N*/ // try to parse simple tokens before calling i18n parser +/*N*/ while ((c != 0) && (eState != ssStop) ) +/*N*/ { +/*N*/ pSrc++; +/*N*/ ULONG nMask = GetCharTableFlags( c ); +/*N*/ switch (eState) +/*N*/ { +/*N*/ case ssGetChar : +/*N*/ { +/*N*/ if( nMask & SC_COMPILER_C_CHAR ) +/*N*/ { +/*N*/ *pSym++ = c; +/*N*/ eState = ssStop; +/*N*/ } +/*N*/ else if( nMask & SC_COMPILER_C_CHAR_BOOL ) +/*N*/ { +/*N*/ *pSym++ = c; +/*N*/ eState = ssGetBool; +/*N*/ } +/*N*/ else if( nMask & SC_COMPILER_C_CHAR_STRING ) +/*N*/ { +/*N*/ *pSym++ = c; +/*N*/ eState = ssGetString; +/*N*/ } +/*N*/ else if( nMask & SC_COMPILER_C_CHAR_DONTCARE ) +/*N*/ { +/*N*/ nSpaces++; +/*N*/ } +/*N*/ else if( nMask & SC_COMPILER_C_CHAR_IDENT ) +/*N*/ { // try to get a simple ASCII identifier before calling +/*N*/ // i18n, to gain performance during import +/*N*/ *pSym++ = c; +/*N*/ eState = ssGetIdent; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ bi18n = TRUE; +/*N*/ eState = ssStop; +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case ssGetIdent: +/*N*/ { +/*N*/ if ( nMask & SC_COMPILER_C_IDENT ) +/*N*/ { // this catches also $Sheet1.A1:A$2, for example +/*N*/ *pSym++ = c; +/*N*/ } +/*N*/ else if ( 128 <= c || '\'' == c ) +/*N*/ { // High values need reparsing with i18n, +/*N*/ // single quoted $'sheet' names too (otherwise we'd had to +/*N*/ // implement everything twice). +/*N*/ pSrc = pStart + nSrcPos + nSpaces; +/*N*/ pSym = cSymbol; +/*N*/ c = *pSrc; +/*N*/ bi18n = TRUE; +/*N*/ eState = ssStop; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pSrc--; +/*N*/ eState = ssStop; +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case ssGetBool : +/*N*/ { +/*N*/ if( nMask & SC_COMPILER_C_BOOL ) +/*N*/ { +/*N*/ *pSym++ = c; +/*N*/ eState = ssStop; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pSrc--; +/*N*/ eState = ssStop; +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case ssGetString : +/*N*/ { +/*N*/ if( nMask & SC_COMPILER_C_STRING_SEP ) +/*N*/ { +/*N*/ if ( !bQuote ) +/*N*/ { +/*N*/ if ( *pSrc == '"' ) +/*N*/ bQuote = TRUE; // "" => literal " +/*N*/ else +/*N*/ eState = ssStop; +/*N*/ } +/*N*/ else +/*N*/ bQuote = FALSE; +/*N*/ } +/*N*/ if ( !bQuote ) +/*N*/ { +/*N*/ if( pSym == &cSymbol[ MAXSTRLEN-1 ] ) +/*N*/ { +/*N*/ SetError(errStringOverflow); +/*N*/ eState = ssSkipString; +/*N*/ } +/*N*/ else +/*N*/ *pSym++ = c; +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case ssSkipString: +/*N*/ if( nMask & SC_COMPILER_C_STRING_SEP ) +/*N*/ eState = ssStop; +/*N*/ break; +/*N*/ } +/*N*/ cLast = c; +/*N*/ c = *pSrc; +/*N*/ } +/*N*/ if ( bi18n ) +/*N*/ { +/*N*/ using namespace ::com::sun::star::i18n; +/*N*/ nSrcPos += nSpaces; +/*N*/ sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER | +/*N*/ KParseTokens::ASC_UNDERSCORE | KParseTokens::ASC_DOLLAR; +/*N*/ sal_Int32 nContFlags = nStartFlags | KParseTokens::ASC_DOT | +/*N*/ KParseTokens::ASC_COLON; +/*N*/ // '?' allowed in range names because of Xcl :-/ +/*N*/ static const String aAddAllowed( '?' ); +/*N*/ String aSymbol; +/*N*/ USHORT nErr = 0; +/*N*/ do +/*N*/ { +/*N*/ bi18n = FALSE; +/*N*/ // special case $'sheetname' +/*N*/ if ( pStart[nSrcPos] == '$' && pStart[nSrcPos+1] == '\'' ) +/*N*/ aSymbol += pStart[nSrcPos++]; +/*N*/ +/*N*/ ParseResult aRes = ScGlobal::pCharClass->parseAnyToken( aFormula, +/*N*/ nSrcPos, nStartFlags, aAddAllowed, nContFlags, aAddAllowed ); +/*N*/ +/*N*/ if ( !aRes.TokenType ) +/*N*/ SetError( nErr = errIllegalChar ); // parsed chars as string +/*N*/ if ( aRes.EndPos <= nSrcPos ) +/*N*/ { // ?!? +/*?*/ SetError( nErr = errIllegalChar ); +/*?*/ nSrcPos = aFormula.Len(); +/*?*/ aSymbol.Erase(); +/*?*/ } +/*N*/ else +/*N*/ { +/*N*/ aSymbol.Append( pStart + nSrcPos, aRes.EndPos - nSrcPos ); +/*N*/ nSrcPos = (xub_StrLen) aRes.EndPos; +/*N*/ if ( aRes.TokenType & KParseType::SINGLE_QUOTE_NAME ) +/*N*/ { // special cases 'sheetname'. 'filename'# +/*N*/ c = pStart[nSrcPos]; +/*N*/ bi18n = (c == '.' || c == SC_COMPILER_FILE_TAB_SEP); +/*N*/ if ( bi18n ) +/*N*/ aSymbol += pStart[nSrcPos++]; +/*N*/ } +/*N*/ else if ( aRes.TokenType & KParseType::IDENTNAME ) +/*N*/ { // special cases reference:[$]'sheetname' +/*N*/ c = aSymbol.GetChar( aSymbol.Len()-1 ); +/*N*/ bi18n = ((c == ':' || c == '$') && pStart[nSrcPos] == '\''); +/*N*/ } +/*N*/ } +/*N*/ } while ( bi18n && !nErr ); +/*N*/ xub_StrLen nLen = aSymbol.Len(); +/*N*/ if ( nLen >= MAXSTRLEN ) +/*N*/ { +/*?*/ SetError( errStringOverflow ); +/*?*/ nLen = MAXSTRLEN-1; +/*N*/ } +/*N*/ lcl_UnicodeStrNCpy( cSymbol, aSymbol.GetBuffer(), nLen ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nSrcPos = pSrc - pStart; +/*N*/ *pSym = 0; +/*N*/ } +/*N*/ if ( bAutoCorrect ) +/*N*/ aCorrectedSymbol = cSymbol; +/*N*/ return nSpaces; +/*N*/ } + +//--------------------------------------------------------------------------- +// Symbol in Token Umwandeln +//--------------------------------------------------------------------------- + +/*N*/ BOOL ScCompiler::IsOpCode( const String& rName ) +/*N*/ { +/*N*/ ScOpCodeHashMap::const_iterator iLook( pSymbolHashMap->find( rName ) ); +/*N*/ BOOL bFound = (iLook != pSymbolHashMap->end()); +/*N*/ if (bFound) +/*N*/ { +/*N*/ ScRawToken aToken; +/*N*/ aToken.SetOpCode( iLook->second ); +/*N*/ pRawToken = aToken.Clone(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ USHORT nIndex; +/*N*/ bFound = ScGlobal::GetFuncCollection()->SearchFunc(cSymbol, nIndex); +/*N*/ if( bFound ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); /*N*/ ScRawToken aToken; +/*N*/ /*?*/ aToken.SetExternal( cSymbol ); +/*N*/ /*?*/ pRawToken = aToken.Clone(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // bLocalFirst=FALSE for english +/*N*/ String aIntName = ScGlobal::GetAddInCollection()-> +/*N*/ FindFunction( rName, ( pSymbolTable != pSymbolTableEnglish ) ); +/*N*/ if (aIntName.Len()) +/*N*/ { +/*N*/ ScRawToken aToken; +/*N*/ aToken.SetExternal( aIntName.GetBuffer() ); // international name +/*N*/ pRawToken = aToken.Clone(); +/*N*/ bFound = TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( bFound && pRawToken->GetOpCode() == ocSub && +/*N*/ (eLastOp == ocOpen || eLastOp == ocSep || +/*N*/ (eLastOp > ocEndDiv && eLastOp < ocEndBinOp /*ocEndUnOp*/))) +/*N*/ pRawToken->NewOpCode( ocNegSub ); +/*N*/ return bFound; +/*N*/ } + +/*N*/ BOOL ScCompiler::IsOpCode2( const String& rName ) +/*N*/ { +/*N*/ BOOL bFound = FALSE; +/*N*/ +/*N*/ USHORT i = 0; +/*N*/ for( i = ocInternalBegin; i <= ocInternalEnd && !bFound; i++ ) +/*N*/ bFound = rName.EqualsAscii( pInternal[ i-ocInternalBegin ] ); +/*N*/ +/*N*/ if (bFound) +/*N*/ { +/*?*/ ScRawToken aToken; +/*?*/ aToken.SetOpCode( (OpCode) --i ); +/*?*/ pRawToken = aToken.Clone(); +/*N*/ } +/*N*/ return bFound; +/*N*/ } + +/*N*/ BOOL ScCompiler::IsValue( const String& rSym ) +/*N*/ { +/*N*/ double fVal; +/*N*/ sal_uInt32 nIndex = ( pSymbolTable == pSymbolTableEnglish ? +/*N*/ pDoc->GetFormatTable()->GetStandardIndex( LANGUAGE_ENGLISH_US ) : 0 ); +/*N*/ // ULONG nIndex = 0; +/*N*/ //// ULONG nIndex = pDoc->GetFormatTable()->GetStandardIndex(ScGlobal::eLnge); +/*N*/ if (pDoc->GetFormatTable()->IsNumberFormat( rSym, nIndex, fVal ) ) +/*N*/ { +/*N*/ USHORT nType = pDoc->GetFormatTable()->GetType(nIndex); +/*N*/ const sal_Unicode* p = aFormula.GetBuffer() + nSrcPos; +/*N*/ while( *p == ' ' ) +/*N*/ p++; +/*N*/ if ( *p == '(' && nType == NUMBERFORMAT_LOGICAL) +/*N*/ return FALSE; +/*N*/ else if( aFormula.GetChar(nSrcPos) == '.' ) +/*N*/ // Numerischer Tabellenname? +/*N*/ return FALSE; +/*N*/ else +/*N*/ { +/*N*/ if( nType == NUMBERFORMAT_TEXT ) +/*N*/ // HACK: Die Zahl ist zu gross! +/*N*/ SetError( errIllegalArgument ); +/*N*/ ScRawToken aToken; +/*N*/ aToken.SetDouble( fVal ); +/*N*/ pRawToken = aToken.Clone(); +/*N*/ return TRUE; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ return FALSE; +/*N*/ } + +/*N*/ BOOL ScCompiler::IsString() +/*N*/ { +/*N*/ register const sal_Unicode* p = cSymbol; +/*N*/ while ( *p ) +/*N*/ p++; +/*N*/ xub_StrLen nLen = p - cSymbol - 1; +/*N*/ BOOL bQuote = ((cSymbol[0] == '"') && (cSymbol[nLen] == '"')); +/*N*/ if ((bQuote ? nLen-2 : nLen) > MAXSTRLEN-1) +/*N*/ { +/*?*/ SetError(errStringOverflow); +/*?*/ return FALSE; +/*N*/ } +/*N*/ if ( bQuote ) +/*N*/ { +/*?*/ cSymbol[nLen] = '\0'; +/*?*/ ScRawToken aToken; +/*?*/ aToken.SetString( cSymbol+1 ); +/*?*/ pRawToken = aToken.Clone(); +/*?*/ return TRUE; +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/*N*/ BOOL ScCompiler::IsReference( const String& rName ) +/*N*/ { +/*N*/ // Has to be called before IsValue +/*N*/ sal_Unicode ch1 = rName.GetChar(0); +/*N*/ sal_Unicode cDecSep = ( pSymbolTable == pSymbolTableEnglish ? '.' : +/*N*/ ScGlobal::pLocaleData->getNumDecimalSep().GetChar(0) ); +/*N*/ if ( ch1 == cDecSep ) +/*N*/ return FALSE; +/*N*/ // Who was that imbecile introducing '.' as the sheet name separator!?! +/*N*/ if ( CharClass::isAsciiNumeric( ch1 ) ) +/*N*/ { // Numerical sheet name is valid. +/*N*/ // But English 1.E2 or 1.E+2 is value 100, 1.E-2 is 0.01 +/*N*/ // Don't create a #REF! of values. +/*N*/ const xub_StrLen nPos = rName.Search( '.' ); +/*N*/ if ( nPos == STRING_NOTFOUND ) +/*N*/ return FALSE; +/*N*/ sal_Unicode const * const pTabSep = rName.GetBuffer() + nPos; +/*N*/ sal_Unicode ch2 = pTabSep[1]; // maybe a column identifier +/*N*/ if ( !(ch2 == '$' || CharClass::isAsciiAlpha( ch2 )) ) +/*N*/ return FALSE; +/*?*/ if ( cDecSep == '.' && (ch2 == 'E' || ch2 == 'e') // E + - digit +/*?*/ && (GetCharTableFlags( pTabSep[2] ) & SC_COMPILER_C_VALUE_EXP) ) +/*?*/ { // #91053# +/*?*/ // If it is an 1.E2 expression check if "1" is an existent sheet +/*?*/ // name. If so, a desired value 1.E2 would have to be entered as +/*?*/ // 1E2 or 1.0E2 or 1.E+2, sorry. Another possibility would be to +/*?*/ // require numerical sheet names always being entered quoted, which +/*?*/ // is not desirable (too many 1999, 2000, 2001 sheets in use). +/*?*/ // Furthermore, XML files created with versions prior to SRC640e +/*?*/ // wouldn't contain the quotes added by MakeTabStr()/CheckTabQuotes() +/*?*/ // and would produce wrong formulas if the conditions here are met. +/*?*/ // If you can live with these restrictions you may remove the +/*?*/ // check and return an unconditional FALSE. +/*?*/ String aTabName( rName.Copy( 0, nPos ) ); +/*?*/ USHORT nTab; +/*?*/ if ( !pDoc->GetTable( aTabName, nTab ) ) +/*?*/ return FALSE; +/*?*/ // If sheet "1" exists and the expression is 1.E+2 continue as +/*?*/ // usual, the ScRange/ScAddress parser will take care of it. +/*?*/ } +/*N*/ } +/*N*/ ScRange aRange( aPos, aPos ); +/*N*/ USHORT nFlags = aRange.Parse( rName, pDoc ); +/*N*/ if( nFlags & SCA_VALID ) +/*N*/ { +/*N*/ ScRawToken aToken; +/*N*/ ComplRefData aRef; +/*N*/ aRef.InitRange( aRange ); +/*N*/ aRef.Ref1.SetColRel( (nFlags & SCA_COL_ABSOLUTE) == 0 ); +/*N*/ aRef.Ref1.SetRowRel( (nFlags & SCA_ROW_ABSOLUTE) == 0 ); +/*N*/ aRef.Ref1.SetTabRel( (nFlags & SCA_TAB_ABSOLUTE) == 0 ); +/*N*/ if ( !(nFlags & SCA_VALID_TAB) ) +/*?*/ aRef.Ref1.SetTabDeleted( TRUE ); // #REF! +/*N*/ aRef.Ref1.SetFlag3D( ( nFlags & SCA_TAB_3D ) != 0 ); +/*N*/ aRef.Ref2.SetColRel( (nFlags & SCA_COL2_ABSOLUTE) == 0 ); +/*N*/ aRef.Ref2.SetRowRel( (nFlags & SCA_ROW2_ABSOLUTE) == 0 ); +/*N*/ aRef.Ref2.SetTabRel( (nFlags & SCA_TAB2_ABSOLUTE) == 0 ); +/*N*/ if ( !(nFlags & SCA_VALID_TAB2) ) +/*?*/ aRef.Ref2.SetTabDeleted( TRUE ); // #REF! +/*N*/ aRef.Ref2.SetFlag3D( ( nFlags & SCA_TAB2_3D ) != 0 ); +/*N*/ aRef.CalcRelFromAbs( aPos ); +/*N*/ aToken.SetDoubleReference( aRef ); +/*N*/ pRawToken = aToken.Clone(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ ScAddress aAddr( aPos ); +/*N*/ nFlags = aAddr.Parse( rName, pDoc ); +/*N*/ // Irgend etwas muss gueltig sein, +/*N*/ // damit Tabelle1.blah oder blah.a1 als (falsche) ref erkannt wird +/*N*/ if( nFlags & ( SCA_VALID_COL|SCA_VALID_ROW|SCA_VALID_TAB ) ) +/*N*/ { +/*N*/ ScRawToken aToken; +/*N*/ SingleRefData aRef; +/*N*/ aRef.InitAddress( aAddr ); +/*N*/ aRef.SetColRel( (nFlags & SCA_COL_ABSOLUTE) == 0 ); +/*N*/ aRef.SetRowRel( (nFlags & SCA_ROW_ABSOLUTE) == 0 ); +/*N*/ aRef.SetTabRel( (nFlags & SCA_TAB_ABSOLUTE) == 0 ); +/*N*/ aRef.SetFlag3D( ( nFlags & SCA_TAB_3D ) != 0 ); +/*N*/ // Die Referenz ist wirklich ungueltig! +/*N*/ if( !( nFlags & SCA_VALID ) ) +/*N*/ { +/*N*/ if( !( nFlags & SCA_VALID_COL ) ) +/*N*/ aRef.nCol = MAXCOL+1; +/*N*/ if( !( nFlags & SCA_VALID_ROW ) ) +/*N*/ aRef.nRow = MAXROW+1; +/*N*/ if( !( nFlags & SCA_VALID_TAB ) ) +/*N*/ aRef.nTab = MAXTAB+3; +/*N*/ nFlags |= SCA_VALID; +/*N*/ } +/*N*/ aRef.CalcRelFromAbs( aPos ); +/*N*/ aToken.SetSingleReference( aRef ); +/*N*/ pRawToken = aToken.Clone(); +/*N*/ } +/*N*/ } +/*N*/ return ( nFlags & SCA_VALID ) != 0; +/*N*/ } + +/*N*/ BOOL ScCompiler::IsMacro( const String& rName ) +/*N*/ { +/*N*/ StarBASIC* pObj = 0; +/*N*/ SfxObjectShell* pDocSh = pDoc->GetDocumentShell(); +/*N*/ +/*N*/ SfxApplication* pSfxApp = SFX_APP(); +/*N*/ pSfxApp->EnterBasicCall(); // Dok-Basic anlegen etc. +/*N*/ +/*N*/ if( pDocSh )//XXX +/*N*/ pObj = pDocSh->GetBasic(); +/*N*/ else +/*?*/ pObj = pSfxApp->GetBasic(); +/*N*/ +/*N*/ SbxMethod* pMeth = (SbxMethod*) pObj->Find( rName, SbxCLASS_METHOD ); +/*N*/ if( !pMeth ) +/*N*/ { +/*N*/ pSfxApp->LeaveBasicCall(); +/*N*/ return FALSE; +/*N*/ } +/*N*/ // Es sollte schon eine BASIC-Function sein! +/*N*/ if( pMeth->GetType() == SbxVOID +/*N*/ || ( pMeth->IsFixed() && pMeth->GetType() == SbxEMPTY ) +/*N*/ || !pMeth->ISA(SbMethod) ) +/*N*/ { +/*N*/ pSfxApp->LeaveBasicCall(); +/*N*/ return FALSE; +/*N*/ } +/*?*/ DBG_BF_ASSERT(0, "STRIP"); /*N*/ ScRawToken aToken; +/*N*/ /*?*/ aToken.SetExternal( rName.GetBuffer() ); +/*N*/ /*?*/ aToken.eOp = ocMacro; +/*N*/ /*?*/ pRawToken = aToken.Clone(); +/*N*/ /*?*/ pSfxApp->LeaveBasicCall(); +/*?*/ return TRUE; +/*N*/ } + +/*N*/ BOOL ScCompiler::IsNamedRange( const String& rName ) +/*N*/ { +/*N*/ USHORT n; +/*N*/ ScRangeName* pRangeName = pDoc->GetRangeName(); +/*N*/ if (pRangeName->SearchName( rName, n ) ) +/*N*/ { +/*N*/ ScRangeData* pData = (*pRangeName)[n]; +/*N*/ ScRawToken aToken; +/*N*/ aToken.SetName( pData->GetIndex() ); +/*N*/ pRawToken = aToken.Clone(); +/*N*/ return TRUE; +/*N*/ } +/*N*/ else +/*N*/ return FALSE; +/*N*/ } + +/*N*/ BOOL ScCompiler::IsDBRange( const String& rName ) +/*N*/ { +/*N*/ USHORT n; +/*N*/ ScDBCollection* pDBColl = pDoc->GetDBCollection(); +/*N*/ if (pDBColl->SearchName( rName, n ) ) +/*N*/ { +/*?*/ ScDBData* pData = (*pDBColl)[n]; +/*?*/ ScRawToken aToken; +/*?*/ aToken.SetName( pData->GetIndex() ); +/*?*/ aToken.eOp = ocDBArea; +/*?*/ pRawToken = aToken.Clone(); +/*?*/ return TRUE; +/*N*/ } +/*N*/ else +/*N*/ return FALSE; +/*N*/ } + +/*N*/ BOOL ScCompiler::IsColRowName( const String& rName ) +/*N*/ { +/*N*/ BOOL bInList = FALSE; +/*N*/ BOOL bFound = FALSE; +/*N*/ SingleRefData aRef; +/*N*/ String aName( rName ); +/*N*/ DeQuote( aName ); +/*N*/ USHORT nThisTab = aPos.Tab(); +/*N*/ for ( short jThisTab = 1; jThisTab >= 0 && !bInList; jThisTab-- ) +/*N*/ { // #50300# zuerst Bereiche auf dieser Tabelle pruefen, falls doppelte Namen +/*N*/ for ( short jRow=0; jRow<2 && !bInList; jRow++ ) +/*N*/ { +/*N*/ ScRangePairList* pRL; +/*N*/ if ( !jRow ) +/*N*/ pRL = pDoc->GetColNameRanges(); +/*N*/ else +/*N*/ pRL = pDoc->GetRowNameRanges(); +/*N*/ for ( ScRangePair* pR = pRL->First(); pR && !bInList; pR = pRL->Next() ) +/*N*/ { +/*?*/ const ScRange& rNameRange = pR->GetRange(0); +/*?*/ if ( jThisTab && !(rNameRange.aStart.Tab() <= nThisTab && +/*?*/ nThisTab <= rNameRange.aEnd.Tab()) ) +/*?*/ continue; // for +/*?*/ ScCellIterator aIter( pDoc, rNameRange ); +/*?*/ for ( ScBaseCell* pCell = aIter.GetFirst(); pCell && !bInList; +/*?*/ pCell = aIter.GetNext() ) +/*?*/ { +/*?*/ // GPF wenn Zelle via CompileNameFormula auf Zelle ohne Code +/*?*/ // trifft und HasStringData/Interpret/Compile ausgefuehrt wird +/*?*/ // und das ganze dann auch noch rekursiv.. +/*?*/ // ausserdem wird *diese* Zelle hier nicht angefasst, da noch +/*?*/ // kein RPN existiert +/*?*/ CellType eType = pCell->GetCellType(); +/*?*/ BOOL bOk = (eType == CELLTYPE_FORMULA ? +/*?*/ ((ScFormulaCell*)pCell)->GetCode()->GetCodeLen() > 0 +/*?*/ && ((ScFormulaCell*)pCell)->aPos != aPos // noIter +/*?*/ : TRUE ); +/*?*/ if ( bOk && pCell->HasStringData() ) +/*?*/ { +/*?*/ String aStr; +/*?*/ switch ( eType ) +/*?*/ { +/*?*/ case CELLTYPE_STRING: +/*?*/ ((ScStringCell*)pCell)->GetString( aStr ); +/*?*/ break; +/*?*/ case CELLTYPE_FORMULA: +/*?*/ ((ScFormulaCell*)pCell)->GetString( aStr ); +/*?*/ break; +/*?*/ case CELLTYPE_EDIT: +/*?*/ ((ScEditCell*)pCell)->GetString( aStr ); +/*?*/ break; +/*?*/ } +/*?*/ if ( ScGlobal::pTransliteration->isEqual( aStr, aName ) ) +/*?*/ { +/*?*/ aRef.InitFlags(); +/*?*/ aRef.nCol = aIter.GetCol(); +/*?*/ aRef.nRow = aIter.GetRow(); +/*?*/ aRef.nTab = aIter.GetTab(); +/*?*/ if ( !jRow ) +/*?*/ aRef.SetColRel( TRUE ); // ColName +/*?*/ else +/*?*/ aRef.SetRowRel( TRUE ); // RowName +/*?*/ aRef.CalcRelFromAbs( aPos ); +/*?*/ bInList = bFound = TRUE; +/*?*/ } +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( !bInList && pDoc->GetDocOptions().IsLookUpColRowNames() ) +/*N*/ { // in der aktuellen Tabelle suchen +/*N*/ long nDistance, nMax; +/*N*/ long nMyCol = (long) aPos.Col(); +/*N*/ long nMyRow = (long) aPos.Row(); +/*N*/ BOOL bTwo = FALSE; +/*N*/ ScAddress aOne( 0, 0, aPos.Tab() ); +/*N*/ ScAddress aTwo( MAXCOL, MAXROW, aPos.Tab() ); +/*N*/ ScCellIterator aIter( pDoc, ScRange( aOne, aTwo ) ); +/*N*/ for ( ScBaseCell* pCell = aIter.GetFirst(); pCell; pCell = aIter.GetNext() ) +/*N*/ { +/*N*/ if ( bFound ) +/*N*/ { // aufhoeren wenn alles andere weiter liegt +/*N*/ if ( nMax < (long)aIter.GetCol() ) +/*N*/ break; // aIter +/*N*/ } +/*N*/ CellType eType = pCell->GetCellType(); +/*N*/ BOOL bOk = (eType == CELLTYPE_FORMULA ? +/*N*/ ((ScFormulaCell*)pCell)->GetCode()->GetCodeLen() > 0 +/*N*/ && ((ScFormulaCell*)pCell)->aPos != aPos // noIter +/*N*/ : TRUE ); +/*N*/ if ( bOk && pCell->HasStringData() ) +/*N*/ { +/*N*/ String aStr; +/*N*/ switch ( eType ) +/*N*/ { +/*N*/ case CELLTYPE_STRING: +/*N*/ ((ScStringCell*)pCell)->GetString( aStr ); +/*N*/ break; +/*N*/ case CELLTYPE_FORMULA: +/*N*/ ((ScFormulaCell*)pCell)->GetString( aStr ); +/*N*/ break; +/*N*/ case CELLTYPE_EDIT: +/*N*/ ((ScEditCell*)pCell)->GetString( aStr ); +/*N*/ break; +/*N*/ } +/*N*/ if ( ScGlobal::pTransliteration->isEqual( aStr, aName ) ) +/*N*/ { +/*N*/ USHORT nCol = aIter.GetCol(); +/*N*/ USHORT nRow = aIter.GetRow(); +/*N*/ long nC = nMyCol - nCol; +/*N*/ long nR = nMyRow - nRow; +/*N*/ if ( bFound ) +/*N*/ { +/*?*/ long nD = nC * nC + nR * nR; +/*?*/ if ( nD < nDistance ) +/*?*/ { +/*?*/ if ( nC < 0 || nR < 0 ) +/*?*/ { // rechts oder unterhalb +/*?*/ bTwo = TRUE; +/*?*/ aTwo.Set( nCol, nRow, aIter.GetTab() ); +/*?*/ nMax = Max( nMyCol + Abs( nC ), nMyRow + Abs( nR ) ); +/*?*/ nDistance = nD; +/*?*/ } +/*?*/ else if ( !(nRow < aOne.Row() && nMyRow >= (long)aOne.Row()) ) +/*?*/ { // links oben, nur wenn nicht weiter oberhalb +/*?*/ // des bisherigen und nMyRow darunter +/*?*/ // (CellIter geht spaltenweise!) +/*?*/ bTwo = FALSE; +/*?*/ aOne.Set( nCol, nRow, aIter.GetTab() ); +/*?*/ nMax = Max( nMyCol + nC, nMyRow + nR ); +/*?*/ nDistance = nD; +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aOne.Set( nCol, nRow, aIter.GetTab() ); +/*N*/ nDistance = nC * nC + nR * nR; +/*N*/ nMax = Max( nMyCol + Abs( nC ), nMyRow + Abs( nR ) ); +/*N*/ } +/*N*/ bFound = TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( bFound ) +/*N*/ { +/*N*/ ScAddress aAdr; +/*N*/ if ( bTwo ) +/*N*/ { +/*?*/ if ( nMyCol >= (long)aOne.Col() && nMyRow >= (long)aOne.Row() ) +/*?*/ aAdr = aOne; // links oben hat Vorrang +/*?*/ else +/*?*/ { +/*?*/ if ( nMyCol < (long)aOne.Col() ) +/*?*/ { // zwei rechts +/*?*/ if ( nMyRow >= (long)aTwo.Row() ) +/*?*/ aAdr = aTwo; // direkt rechts +/*?*/ else +/*?*/ aAdr = aOne; +/*?*/ } +/*?*/ else +/*?*/ { // zwei unten oder unten und rechts, der naechstgelegene +/*?*/ long nC1 = nMyCol - aOne.Col(); +/*?*/ long nR1 = nMyRow - aOne.Row(); +/*?*/ long nC2 = nMyCol - aTwo.Col(); +/*?*/ long nR2 = nMyRow - aTwo.Row(); +/*?*/ if ( nC1 * nC1 + nR1 * nR1 <= nC2 * nC2 + nR2 * nR2 ) +/*?*/ aAdr = aOne; +/*?*/ else +/*?*/ aAdr = aTwo; +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ aAdr = aOne; +/*N*/ aRef.InitAddress( aAdr ); +/*N*/ if ( (aRef.nRow != MAXROW && pDoc->HasStringData( +/*N*/ aRef.nCol, aRef.nRow + 1, aRef.nTab )) +/*N*/ || (aRef.nRow != 0 && pDoc->HasStringData( +/*N*/ aRef.nCol, aRef.nRow - 1, aRef.nTab )) ) +/*N*/ aRef.SetRowRel( TRUE ); // RowName +/*N*/ else +/*N*/ aRef.SetColRel( TRUE ); // ColName +/*N*/ aRef.CalcRelFromAbs( aPos ); +/*N*/ } +/*N*/ } +/*N*/ if ( bFound ) +/*N*/ { +/*N*/ ScRawToken aToken; +/*N*/ aToken.SetSingleReference( aRef ); +/*N*/ aToken.eOp = ocColRowName; +/*N*/ pRawToken = aToken.Clone(); +/*N*/ return TRUE; +/*N*/ } +/*N*/ else +/*N*/ return FALSE; +/*N*/ } + +//--------------------------------------------------------------------------- + +/*N*/ void ScCompiler::AutoCorrectParsedSymbol() +/*N*/ { +/*N*/ xub_StrLen nPos = aCorrectedSymbol.Len(); +/*N*/ if ( nPos ) +/*N*/ { +/*N*/ nPos--; +/*N*/ const sal_Unicode cQuote = '\"'; +/*N*/ const sal_Unicode cx = 'x'; +/*N*/ const sal_Unicode cX = 'X'; +/*N*/ sal_Unicode c1 = aCorrectedSymbol.GetChar( 0 ); +/*N*/ sal_Unicode c2 = aCorrectedSymbol.GetChar( nPos ); +/*N*/ if ( c1 == cQuote && c2 != cQuote ) +/*N*/ { // "... +/*N*/ // was kein Wort bildet gehoert nicht dazu. +/*N*/ // Don't be pedantic: c < 128 should be sufficient here. +/*N*/ while ( nPos && ((aCorrectedSymbol.GetChar(nPos) < 128) && +/*N*/ ((GetCharTableFlags( aCorrectedSymbol.GetChar(nPos) ) & +/*N*/ (SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_DONTCARE)) == 0)) ) +/*N*/ nPos--; +/*N*/ if ( nPos == MAXSTRLEN - 2 ) +/*N*/ aCorrectedSymbol.SetChar( nPos, cQuote ); // '"' als 255. Zeichen +/*N*/ else +/*N*/ aCorrectedSymbol.Insert( cQuote, nPos + 1 ); +/*N*/ bCorrected = TRUE; +/*N*/ } +/*N*/ else if ( c1 != cQuote && c2 == cQuote ) +/*N*/ { // ..." +/*N*/ aCorrectedSymbol.Insert( cQuote, 0 ); +/*N*/ bCorrected = TRUE; +/*N*/ } +/*N*/ else if ( nPos == 0 && (c1 == cx || c1 == cX) ) +/*N*/ { // x => * +/*N*/ aCorrectedSymbol = pSymbolTable[ocMul]; +/*N*/ bCorrected = TRUE; +/*N*/ } +/*N*/ else if ( (GetCharTableFlags( c1 ) & SC_COMPILER_C_CHAR_VALUE) +/*N*/ && (GetCharTableFlags( c2 ) & SC_COMPILER_C_CHAR_VALUE) ) +/*N*/ { +/*N*/ xub_StrLen nXcount; +/*N*/ if ( (nXcount = aCorrectedSymbol.GetTokenCount( cx )) > 1 ) +/*N*/ { // x => * +/*N*/ xub_StrLen nIndex = 0; +/*N*/ sal_Unicode c = pSymbolTable[ocMul].GetChar(0); +/*N*/ while ( (nIndex = aCorrectedSymbol.SearchAndReplace( +/*N*/ cx, c, nIndex )) != STRING_NOTFOUND ) +/*N*/ nIndex++; +/*N*/ bCorrected = TRUE; +/*N*/ } +/*N*/ if ( (nXcount = aCorrectedSymbol.GetTokenCount( cX )) > 1 ) +/*N*/ { // X => * +/*N*/ xub_StrLen nIndex = 0; +/*N*/ sal_Unicode c = pSymbolTable[ocMul].GetChar(0); +/*N*/ while ( (nIndex = aCorrectedSymbol.SearchAndReplace( +/*N*/ cX, c, nIndex )) != STRING_NOTFOUND ) +/*N*/ nIndex++; +/*N*/ bCorrected = TRUE; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ String aSymbol( aCorrectedSymbol ); +/*N*/ String aDoc; +/*N*/ xub_StrLen nPos; +/*N*/ if ( aSymbol.GetChar(0) == '\'' +/*N*/ && ((nPos = aSymbol.SearchAscii( "'#" )) != STRING_NOTFOUND) ) +/*N*/ { // 'Doc'# abspalten, kann d:\... und sonstwas sein +/*N*/ aDoc = aSymbol.Copy( 0, nPos + 2 ); +/*N*/ aSymbol.Erase( 0, nPos + 2 ); +/*N*/ } +/*N*/ xub_StrLen nRefs = aSymbol.GetTokenCount( ':' ); +/*N*/ BOOL bColons; +/*N*/ if ( nRefs > 2 ) +/*N*/ { // doppelte oder zuviele ':'? B:2::C10 => B2:C10 +/*N*/ bColons = TRUE; +/*N*/ xub_StrLen nIndex = 0; +/*N*/ String aTmp1( aSymbol.GetToken( 0, ':', nIndex ) ); +/*N*/ xub_StrLen nLen1 = aTmp1.Len(); +/*N*/ String aSym, aTmp2; +/*N*/ BOOL bLastAlp, bNextNum; +/*N*/ bLastAlp = bNextNum = TRUE; +/*N*/ xub_StrLen nStrip = 0; +/*N*/ xub_StrLen nCount = nRefs; +/*N*/ for ( xub_StrLen j=1; j<nCount; j++ ) +/*N*/ { +/*N*/ aTmp2 = aSymbol.GetToken( 0, ':', nIndex ); +/*N*/ xub_StrLen nLen2 = aTmp2.Len(); +/*N*/ if ( nLen1 || nLen2 ) +/*N*/ { +/*N*/ if ( nLen1 ) +/*N*/ { +/*N*/ aSym += aTmp1; +/*N*/ bLastAlp = CharClass::isAsciiAlpha( aTmp1 ); +/*N*/ } +/*N*/ if ( nLen2 ) +/*N*/ { +/*N*/ bNextNum = CharClass::isAsciiNumeric( aTmp2 ); +/*N*/ if ( bLastAlp == bNextNum && nStrip < 1 ) +/*N*/ { // muss abwechselnd nur Zahl/String sein, +/*N*/ // nur innerhalb einer Ref strippen +/*N*/ nRefs--; +/*N*/ nStrip++; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ xub_StrLen nSymLen = aSym.Len(); +/*N*/ if ( nSymLen +/*N*/ && (aSym.GetChar( nSymLen - 1 ) != ':') ) +/*N*/ aSym += ':'; +/*N*/ nStrip = 0; +/*N*/ } +/*N*/ bLastAlp = !bNextNum; +/*N*/ } +/*N*/ else +/*N*/ { // :: +/*N*/ nRefs--; +/*N*/ if ( nLen1 ) +/*N*/ { // B10::C10 ? naechste Runde ':' anhaengen +/*N*/ if ( !bLastAlp && !CharClass::isAsciiNumeric( aTmp1 ) ) +/*N*/ nStrip++; +/*N*/ } +/*N*/ bNextNum = !bLastAlp; +/*N*/ } +/*N*/ aTmp1 = aTmp2; +/*N*/ nLen1 = nLen2; +/*N*/ } +/*N*/ else +/*N*/ nRefs--; +/*N*/ } +/*N*/ aSymbol = aSym; +/*N*/ aSymbol += aTmp1; +/*N*/ } +/*N*/ else +/*N*/ bColons = FALSE; +/*N*/ if ( nRefs && nRefs <= 2 ) +/*N*/ { // Referenzdreher? 4A => A4 etc. +/*N*/ String aTab[2], aRef[2]; +/*N*/ if ( nRefs == 2 ) +/*N*/ { +/*N*/ aRef[0] = aSymbol.GetToken( 0, ':' ); +/*N*/ aRef[1] = aSymbol.GetToken( 1, ':' ); +/*N*/ } +/*N*/ else +/*N*/ aRef[0] = aSymbol; +/*N*/ +/*N*/ BOOL bChanged = FALSE; +/*N*/ BOOL bOk = TRUE; +/*N*/ USHORT nMask = SCA_VALID | SCA_VALID_COL | SCA_VALID_ROW; +/*N*/ for ( int j=0; j<nRefs; j++ ) +/*N*/ { +/*N*/ xub_StrLen nTmp = 0; +/*N*/ xub_StrLen nPos = STRING_NOTFOUND; +/*N*/ while ( (nTmp = aRef[j].Search( '.', nTmp )) != STRING_NOTFOUND ) +/*N*/ nPos = nTmp++; // der letzte zaehlt +/*N*/ if ( nPos != STRING_NOTFOUND ) +/*N*/ { +/*N*/ aTab[j] = aRef[j].Copy( 0, nPos + 1 ); // mit '.' +/*N*/ aRef[j].Erase( 0, nPos + 1 ); +/*N*/ } +/*N*/ String aOld( aRef[j] ); +/*N*/ String aStr2; +/*N*/ const sal_Unicode* p = aRef[j].GetBuffer(); +/*N*/ while ( *p && CharClass::isAsciiNumeric( *p ) ) +/*N*/ aStr2 += *p++; +/*N*/ aRef[j] = String( p ); +/*N*/ aRef[j] += aStr2; +/*N*/ if ( bColons || aRef[j] != aOld ) +/*N*/ { +/*N*/ bChanged = TRUE; +/*N*/ ScAddress aAdr; +/*N*/ bOk &= ((aAdr.Parse( aRef[j], pDoc ) & nMask) == nMask); +/*N*/ } +/*N*/ } +/*N*/ if ( bChanged && bOk ) +/*N*/ { +/*N*/ aCorrectedSymbol = aDoc; +/*N*/ aCorrectedSymbol += aTab[0]; +/*N*/ aCorrectedSymbol += aRef[0]; +/*N*/ if ( nRefs == 2 ) +/*N*/ { +/*N*/ aCorrectedSymbol += ':'; +/*N*/ aCorrectedSymbol += aTab[1]; +/*N*/ aCorrectedSymbol += aRef[1]; +/*N*/ } +/*N*/ bCorrected = TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ BOOL ScCompiler::NextNewToken() +/*N*/ { +/*N*/ xub_StrLen nSpaces = NextSymbol(); +/*N*/ ScRawToken aToken; +/*N*/ if( cSymbol[0] ) +/*N*/ { +/*N*/ if( nSpaces ) +/*N*/ { +/*N*/ aToken.SetOpCode( ocSpaces ); +/*N*/ aToken.cByte = (BYTE) ( nSpaces > 255 ? 255 : nSpaces ); +/*N*/ if( !pArr->AddToken( aToken ) ) +/*N*/ { +/*?*/ SetError(errCodeOverflow); return FALSE; +/*N*/ } +/*N*/ } +/*N*/ if ( (cSymbol[0] == '#' || cSymbol[0] == '$') && cSymbol[1] == 0 && +/*N*/ !bAutoCorrect ) +/*N*/ { // #101100# special case to speed up broken [$]#REF documents +/*N*/ String aBad( aFormula.Copy( nSrcPos-1 ) ); +/*N*/ eLastOp = pArr->AddBad( aBad )->GetOpCode(); +/*N*/ return FALSE; +/*N*/ } +/*N*/ if( !IsString() ) +/*N*/ { +/*N*/ BOOL bMayBeFuncName; +/*N*/ if ( cSymbol[0] < 128 ) +/*N*/ bMayBeFuncName = CharClass::isAsciiAlpha( cSymbol[0] ); +/*N*/ else +/*N*/ { +/*N*/ String aTmpStr( cSymbol[0] ); +/*N*/ bMayBeFuncName = ScGlobal::pCharClass->isLetter( aTmpStr, 0 ); +/*N*/ } +/*N*/ if ( bMayBeFuncName ) +/*N*/ { // a function name must be followed by a parenthesis +/*N*/ const sal_Unicode* p = aFormula.GetBuffer() + nSrcPos; +/*N*/ while( *p == ' ' ) +/*N*/ p++; +/*N*/ bMayBeFuncName = ( *p == '(' ); +/*N*/ } +/*N*/ else +/*N*/ bMayBeFuncName = TRUE; // operators and other opcodes +/*N*/ +/*N*/ String aOrg( cSymbol ); // evtl. Dateinamen in IsReference erhalten +/*N*/ String aUpper( ScGlobal::pCharClass->upper( aOrg ) ); +/*N*/ // Spalte DM konnte nicht referiert werden, IsReference vor IsValue +/*N*/ // #42016# italian ARCTAN.2 gab #REF! => IsOpCode vor IsReference +/*N*/ if ( !(bMayBeFuncName && IsOpCode( aUpper )) +/*N*/ && !IsReference( aOrg ) +/*N*/ && !IsValue( aUpper ) +/*N*/ && !IsNamedRange( aUpper ) +/*N*/ && !IsDBRange( aUpper ) +/*N*/ && !IsColRowName( aUpper ) +/*N*/ && !(bMayBeFuncName && IsMacro( aUpper )) +/*N*/ && !(bMayBeFuncName && IsOpCode2( aUpper )) ) +/*N*/ { +/*N*/ SetError( errNoName ); +/*N*/ if ( bAutoCorrect ) +/*N*/ { // provide single token information and continue +/*?*/ ScGlobal::pCharClass->toLower( aUpper ); +/*?*/ aToken.SetString( aUpper.GetBuffer() ); +/*?*/ aToken.NewOpCode( ocBad ); +/*?*/ pRawToken = aToken.Clone(); +/*?*/ AutoCorrectParsedSymbol(); +/*N*/ } +/*N*/ else +/*N*/ { // we don't need single token information, just a bad formula +/*N*/ String aBad( aFormula.Copy( nSrcPos - aOrg.Len() ) ); +/*N*/ eLastOp = pArr->AddBad( aBad )->GetOpCode(); +/*N*/ return FALSE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return TRUE; +/*N*/ } +/*N*/ else +/*N*/ return FALSE; +/*N*/ } + +/*N*/ ScTokenArray* ScCompiler::CompileString( const String& rFormula ) +/*N*/ { +/*N*/ ScTokenArray aArr; +/*N*/ pArr = &aArr; +/*N*/ aFormula = rFormula; +/*N*/ aFormula.EraseLeadingChars(); +/*N*/ aFormula.EraseTrailingChars(); +/*N*/ nSrcPos = 0; +/*N*/ bCorrected = FALSE; +/*N*/ if ( bAutoCorrect ) +/*N*/ { +/*?*/ aCorrectedFormula.Erase(); +/*?*/ aCorrectedSymbol.Erase(); +/*N*/ } +/*N*/ BYTE nForced = 0; // ==Formel forciert Recalc auch wenn nicht sichtbar +/*N*/ if( aFormula.GetChar(nSrcPos) == '=' ) +/*N*/ { +/*N*/ nSrcPos++; +/*N*/ nForced++; +/*N*/ if ( bAutoCorrect ) +/*N*/ aCorrectedFormula += '='; +/*N*/ } +/*N*/ if( aFormula.GetChar(nSrcPos) == '=' ) +/*N*/ { +/*N*/ nSrcPos++; +/*N*/ nForced++; +/*N*/ if ( bAutoCorrect ) +/*N*/ aCorrectedFormula += '='; +/*N*/ } +/*N*/ short nBrackets = 0; +/*N*/ eLastOp = ocOpen; +/*N*/ while( NextNewToken() ) +/*N*/ { +/*N*/ if( pRawToken->GetOpCode() == ocOpen ) +/*N*/ nBrackets++; +/*N*/ else if( pRawToken->GetOpCode() == ocClose ) +/*N*/ { +/*N*/ if( !nBrackets ) +/*N*/ { +/*?*/ SetError( errPairExpected ); +/*?*/ if ( bAutoCorrect ) +/*?*/ { +/*?*/ bCorrected = TRUE; +/*?*/ aCorrectedSymbol.Erase(); +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ nBrackets--; +/*N*/ } +/*N*/ if( !pArr->Add( pRawToken->CreateToken() ) ) +/*N*/ { +/*?*/ SetError(errCodeOverflow); break; +/*N*/ } +/*N*/ eLastOp = pRawToken->GetOpCode(); +/*N*/ if ( bAutoCorrect ) +/*N*/ aCorrectedFormula += aCorrectedSymbol; +/*N*/ } +/*N*/ if ( eLastOp != ocBad ) +/*N*/ { // bei ocBad ist der Rest der Formel String, es wuerden zuviele +/*N*/ // Klammern erscheinen +/*N*/ ScByteToken aToken( ocClose ); +/*N*/ while( nBrackets-- ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); /*N*/ if( !pArr->AddToken( aToken ) ) +/*N*/ /*?*/ { +/*N*/ /*?*/ SetError(errCodeOverflow); break; +/*N*/ /*?*/ } +/*N*/ /*?*/ if ( bAutoCorrect ) +/*N*/ /*?*/ aCorrectedFormula += pSymbolTable[ocClose]; +/*N*/ } +/*N*/ } +/*N*/ if ( nForced >= 2 ) +/*?*/ pArr->SetRecalcModeForced(); +/*N*/ // pArr merken, falls danach CompileTokenArray() kommt +/*N*/ return pArr = new ScTokenArray( aArr ); +/*N*/ } + +/*N*/ void ScCompiler::PushTokenArray( ScTokenArray* pa, BOOL bTemp ) +/*N*/ { +/*N*/ if ( bAutoCorrect && !pStack ) +/*N*/ { // #61426# don't merge stacked subroutine code into entered formula +/*?*/ aCorrectedFormula += aCorrectedSymbol; +/*?*/ aCorrectedSymbol.Erase(); +/*N*/ } +/*N*/ ScArrayStack* p = new ScArrayStack; +/*N*/ p->pNext = pStack; +/*N*/ p->pArr = pArr; +/*N*/ p->bTemp = bTemp; +/*N*/ pStack = p; +/*N*/ pArr = pa; +/*N*/ } + +/*N*/ void ScCompiler::PopTokenArray() +/*N*/ { +/*N*/ if( pStack ) +/*N*/ { +/*N*/ ScArrayStack* p = pStack; +/*N*/ pStack = p->pNext; +/*N*/ p->pArr->nRefs += pArr->nRefs; +/*N*/ // special RecalcMode aus SharedFormula uebernehmen +/*N*/ if ( pArr->IsRecalcModeAlways() ) +/*?*/ p->pArr->SetRecalcModeAlways(); +/*N*/ else if ( !pArr->IsRecalcModeNormal() && p->pArr->IsRecalcModeNormal() ) +/*?*/ p->pArr->SetMaskedRecalcMode( pArr->GetRecalcMode() ); +/*N*/ p->pArr->SetCombinedBitsRecalcMode( pArr->GetRecalcMode() ); +/*N*/ if( p->bTemp ) +/*N*/ delete pArr; +/*N*/ pArr = p->pArr; +/*N*/ delete p; +/*N*/ } +/*N*/ } + +/*N*/ BOOL ScCompiler::GetToken() +/*N*/ { +/*N*/ static const short nRecursionMax = 42; +/*N*/ ScCompilerRecursionGuard aRecursionGuard( nRecursion ); +/*N*/ if ( nRecursion > nRecursionMax ) +/*N*/ { +/*?*/ SetError( errStackOverflow ); +/*?*/ pToken = new ScByteToken( ocStop ); +/*?*/ return FALSE; +/*N*/ } +/*N*/ if ( bAutoCorrect && !pStack ) +/*N*/ { // #61426# don't merge stacked subroutine code into entered formula +/*?*/ aCorrectedFormula += aCorrectedSymbol; +/*?*/ aCorrectedSymbol.Erase(); +/*N*/ } +/*N*/ BOOL bStop = FALSE; +/*N*/ if( pArr->GetError() && !bIgnoreErrors ) +/*N*/ bStop = TRUE; +/*N*/ else +/*N*/ { +/*N*/ short nWasColRowName; +/*N*/ if ( pArr->nIndex +/*N*/ && pArr->pCode[ pArr->nIndex-1 ]->GetOpCode() == ocColRowName ) +/*N*/ nWasColRowName = 1; +/*N*/ else +/*N*/ nWasColRowName = 0; +/*N*/ pToken = pArr->Next(); +/*N*/ while( pToken && pToken->GetOpCode() == ocSpaces ) +/*N*/ { +/*N*/ if ( nWasColRowName ) +/*N*/ nWasColRowName++; +/*N*/ if ( bAutoCorrect && !pStack ) +/*?*/ CreateStringFromToken( aCorrectedFormula, pToken, FALSE ); +/*N*/ pToken = pArr->Next(); +/*N*/ } +/*N*/ if ( bAutoCorrect && !pStack && pToken ) +/*?*/ CreateStringFromToken( aCorrectedSymbol, pToken, FALSE ); +/*N*/ if( !pToken ) +/*N*/ { +/*N*/ if( pStack ) +/*N*/ { +/*N*/ PopTokenArray(); +/*N*/ return GetToken(); +/*N*/ } +/*N*/ else +/*N*/ bStop = TRUE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( nWasColRowName >= 2 && pToken->GetOpCode() == ocColRowName ) +/*N*/ { // aus einem ocSpaces ein ocIntersect im RPN machen +/*?*/ pToken = new ScByteToken( ocIntersect ); +/*?*/ pArr->nIndex--; // ganz schweinisch.. +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if( bStop ) +/*N*/ { +/*N*/ pToken = new ScByteToken( ocStop ); +/*N*/ return FALSE; +/*N*/ } +/*N*/ if( pToken->GetOpCode() == ocSubTotal ) +/*N*/ glSubTotal = TRUE; +/*N*/ else if( pToken->GetOpCode() == ocName ) +/*N*/ { +/*N*/ ScRangeData* pRangeData = pDoc->GetRangeName()->FindIndex( pToken->GetIndex() ); +/*N*/ if (pRangeData) +/*N*/ { +/*N*/ USHORT nErr = pRangeData->GetErrCode(); +/*N*/ if( nErr ) +/*N*/ SetError( errNoName ); +/*N*/ else if ( !bCompileForFAP ) +/*N*/ { +/*N*/ ScTokenArray* pNew; +/*N*/ // #35168# Bereichsformel klammern +/*N*/ // #37680# aber nur wenn nicht schon Klammern da, +/*N*/ // geklammerte ocSep geht nicht, z.B. SUMME((...;...)) +/*N*/ // und wenn nicht direkt zwischen ocSep/Klammer, +/*N*/ // z.B. SUMME(...;(...;...)) nicht, SUMME(...;(...)*3) ja +/*N*/ // kurz: wenn kein eigenstaendiger Ausdruck +/*N*/ ScToken* p1 = pArr->PeekPrevNoSpaces(); +/*N*/ ScToken* p2 = pArr->PeekNextNoSpaces(); +/*N*/ OpCode eOp1 = (p1 ? p1->GetOpCode() : ocSep); +/*N*/ OpCode eOp2 = (p2 ? p2->GetOpCode() : ocSep); +/*N*/ BOOL bBorder1 = (eOp1 == ocSep || eOp1 == ocOpen); +/*N*/ BOOL bBorder2 = (eOp2 == ocSep || eOp2 == ocClose); +/*N*/ BOOL bAddPair = !(bBorder1 && bBorder2); +/*N*/ if ( bAddPair ) +/*N*/ { +/*N*/ pNew = new ScTokenArray; +/*N*/ pNew->AddOpCode( ocClose ); +/*N*/ PushTokenArray( pNew, TRUE ); +/*N*/ pNew->Reset(); +/*N*/ } +/*N*/ pNew = pRangeData->GetCode()->Clone(); +/*N*/ PushTokenArray( pNew, TRUE ); +/*N*/ if( pRangeData->HasReferences() ) +/*N*/ { +/*N*/ SetRelNameReference(); +/*N*/ MoveRelWrap(); +/*N*/ } +/*N*/ pNew->Reset(); +/*N*/ if ( bAddPair ) +/*N*/ { +/*N*/ pNew = new ScTokenArray; +/*N*/ pNew->AddOpCode( ocOpen ); +/*N*/ PushTokenArray( pNew, TRUE ); +/*N*/ pNew->Reset(); +/*N*/ } +/*N*/ return GetToken(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ SetError(errNoName); +/*N*/ } +/*N*/ else if( pToken->GetOpCode() == ocColRowName ) +/*N*/ { +/*N*/ SingleRefData& rRef = pToken->GetSingleRef(); +/*N*/ rRef.CalcAbsIfRel( aPos ); +/*N*/ if ( !rRef.Valid() ) +/*N*/ { +/*N*/ SetError( errNoRef ); +/*N*/ return TRUE; +/*N*/ } +/*N*/ USHORT nCol = rRef.nCol; +/*N*/ USHORT nRow = rRef.nRow; +/*N*/ USHORT nTab = rRef.nTab; +/*N*/ ScAddress aLook( nCol, nRow, nTab ); +/*N*/ BOOL bColName = rRef.IsColRel(); +/*N*/ USHORT nMyCol = aPos.Col(); +/*N*/ USHORT nMyRow = aPos.Row(); +/*N*/ BOOL bInList = FALSE; +/*N*/ BOOL bValidName = FALSE; +/*N*/ ScRangePairList* pRL = (bColName ? +/*N*/ pDoc->GetColNameRanges() : pDoc->GetRowNameRanges()); +/*N*/ ScRange aRange; +/*N*/ for ( ScRangePair* pR = pRL->First(); pR; pR = pRL->Next() ) +/*N*/ { +/*?*/ if ( pR->GetRange(0).In( aLook ) ) +/*?*/ { +/*?*/ bInList = bValidName = TRUE; +/*?*/ aRange = pR->GetRange(1); +/*?*/ if ( bColName ) +/*?*/ { +/*?*/ aRange.aStart.SetCol( nCol ); +/*?*/ aRange.aEnd.SetCol( nCol ); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ aRange.aStart.SetRow( nRow ); +/*?*/ aRange.aEnd.SetRow( nRow ); +/*?*/ } +/*?*/ break; // for +/*?*/ } +/*N*/ } +/*N*/ if ( !bInList && pDoc->GetDocOptions().IsLookUpColRowNames() ) +/*N*/ { // automagically oder durch kopieren entstanden und NamePos nicht in Liste +/*N*/ BOOL bString = pDoc->HasStringData( nCol, nRow, nTab ); +/*N*/ if ( !bString && !pDoc->GetCell( aLook ) ) +/*N*/ bString = TRUE; // leere Zelle ist ok +/*N*/ if ( bString ) +/*N*/ { //! korrespondiert mit ScInterpreter::ScColRowNameAuto +/*N*/ bValidName = TRUE; +/*N*/ if ( bColName ) +/*N*/ { // ColName +/*N*/ USHORT nStartRow = nRow + 1; +/*N*/ if ( nStartRow > MAXROW ) +/*N*/ nStartRow = MAXROW; +/*N*/ USHORT nMaxRow = MAXROW; +/*N*/ if ( nMyCol == nCol ) +/*N*/ { // Formelzelle in gleicher Col +/*?*/ if ( nMyRow == nStartRow ) +/*?*/ { // direkt unter dem Namen den Rest nehmen +/*?*/ nStartRow++; +/*?*/ if ( nStartRow > MAXROW ) +/*?*/ nStartRow = MAXROW; +/*?*/ } +/*?*/ else if ( nMyRow > nStartRow ) +/*?*/ { // weiter unten vom Namen bis zur Formelzelle +/*?*/ nMaxRow = nMyRow - 1; +/*?*/ } +/*N*/ } +/*N*/ for ( ScRangePair* pR = pRL->First(); pR; pR = pRL->Next() ) +/*N*/ { // naechster definierter ColNameRange unten ist Row-Begrenzung +/*?*/ const ScRange& rRange = pR->GetRange(1); +/*?*/ if ( rRange.aStart.Col() <= nCol && nCol <= rRange.aEnd.Col() ) +/*?*/ { // gleicher Col Bereich +/*?*/ USHORT nTmp = rRange.aStart.Row(); +/*?*/ if ( nStartRow < nTmp && nTmp <= nMaxRow ) +/*?*/ nMaxRow = nTmp - 1; +/*?*/ } +/*N*/ } +/*N*/ aRange.aStart.Set( nCol, nStartRow, nTab ); +/*N*/ aRange.aEnd.Set( nCol, nMaxRow, nTab ); +/*N*/ } +/*N*/ else +/*N*/ { // RowName +/*N*/ USHORT nStartCol = nCol + 1; +/*N*/ if ( nStartCol > MAXCOL ) +/*N*/ nStartCol = MAXCOL; +/*N*/ USHORT nMaxCol = MAXCOL; +/*N*/ if ( nMyRow == nRow ) +/*N*/ { // Formelzelle in gleicher Row +/*N*/ if ( nMyCol == nStartCol ) +/*N*/ { // direkt neben dem Namen den Rest nehmen +/*N*/ nStartCol++; +/*N*/ if ( nStartCol > MAXCOL ) +/*N*/ nStartCol = MAXCOL; +/*N*/ } +/*N*/ else if ( nMyCol > nStartCol ) +/*N*/ { // weiter rechts vom Namen bis zur Formelzelle +/*N*/ nMaxCol = nMyCol - 1; +/*N*/ } +/*N*/ } +/*N*/ for ( ScRangePair* pR = pRL->First(); pR; pR = pRL->Next() ) +/*N*/ { // naechster definierter RowNameRange rechts ist Col-Begrenzung +/*?*/ const ScRange& rRange = pR->GetRange(1); +/*?*/ if ( rRange.aStart.Row() <= nRow && nRow <= rRange.aEnd.Row() ) +/*?*/ { // gleicher Row Bereich +/*?*/ USHORT nTmp = rRange.aStart.Col(); +/*?*/ if ( nStartCol < nTmp && nTmp <= nMaxCol ) +/*?*/ nMaxCol = nTmp - 1; +/*?*/ } +/*N*/ } +/*N*/ aRange.aStart.Set( nStartCol, nRow, nTab ); +/*N*/ aRange.aEnd.Set( nMaxCol, nRow, nTab ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( bValidName ) +/*N*/ { +/*N*/ // Und nun der Zauber zur Unterscheidung zwischen +/*N*/ // Bereich und einer einzelnen Zelle daraus, die +/*N*/ // positionsabhaengig von der Formelzelle gewaehlt wird. +/*N*/ // Ist ein direkter Nachbar ein binaerer Operator (ocAdd etc.) +/*N*/ // so wird eine SingleRef passend zur Col/Row generiert, +/*N*/ // ocColRowName bzw. ocIntersect als Nachbar => Range. +/*N*/ // Spezialfall: Beschriftung gilt fuer eine einzelne Zelle, +/*N*/ // dann wird eine positionsunabhaengige SingleRef generiert. +/*N*/ BOOL bSingle = (aRange.aStart == aRange.aEnd); +/*N*/ BOOL bFound; +/*N*/ if ( bSingle ) +/*N*/ bFound = TRUE; +/*N*/ else +/*N*/ { +/*N*/ ScToken* p1 = pArr->PeekPrevNoSpaces(); +/*N*/ ScToken* p2 = pArr->PeekNextNoSpaces(); +/*N*/ // Anfang/Ende einer Formel => Single +/*N*/ OpCode eOp1 = p1 ? p1->GetOpCode() : ocAdd; +/*N*/ OpCode eOp2 = p2 ? p2->GetOpCode() : ocAdd; +/*N*/ if ( eOp1 != ocColRowName && eOp1 != ocIntersect +/*N*/ && eOp2 != ocColRowName && eOp2 != ocIntersect ) +/*N*/ { +/*N*/ if ( (ocEndDiv < eOp1 && eOp1 < ocEndBinOp) +/*N*/ || (ocEndDiv < eOp2 && eOp2 < ocEndBinOp) ) +/*N*/ bSingle = TRUE; +/*N*/ } +/*N*/ if ( bSingle ) +/*N*/ { // Col bzw. Row muss zum Range passen +/*N*/ if ( bColName ) +/*N*/ { +/*N*/ bFound = (aRange.aStart.Row() <= nMyRow +/*N*/ && nMyRow <= aRange.aEnd.Row()); +/*N*/ if ( bFound ) +/*N*/ aRange.aStart.SetRow( nMyRow ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ bFound = (aRange.aStart.Col() <= nMyCol +/*N*/ && nMyCol <= aRange.aEnd.Col()); +/*N*/ if ( bFound ) +/*?*/ aRange.aStart.SetCol( nMyCol ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ bFound = TRUE; +/*N*/ } +/*N*/ if ( !bFound ) +/*N*/ SetError(errNoRef); +/*N*/ else if ( !bCompileForFAP ) +/*N*/ { +/*N*/ ScTokenArray* pNew = new ScTokenArray; +/*N*/ if ( bSingle ) +/*N*/ { +/*N*/ SingleRefData aRefData; +/*N*/ aRefData.InitAddress( aRange.aStart ); +/*N*/ if ( bColName ) +/*N*/ aRefData.SetColRel( TRUE ); +/*N*/ else +/*?*/ aRefData.SetRowRel( TRUE ); +/*N*/ aRefData.CalcRelFromAbs( aPos ); +/*N*/ pNew->AddSingleReference( aRefData ); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ ComplRefData aRefData; +/*?*/ aRefData.InitRange( aRange ); +/*?*/ if ( bColName ) +/*?*/ { +/*?*/ aRefData.Ref1.SetColRel( TRUE ); +/*?*/ aRefData.Ref2.SetColRel( TRUE ); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ aRefData.Ref1.SetRowRel( TRUE ); +/*?*/ aRefData.Ref2.SetRowRel( TRUE ); +/*?*/ } +/*?*/ aRefData.CalcRelFromAbs( aPos ); +/*?*/ if ( bInList ) +/*?*/ pNew->AddDoubleReference( aRefData ); +/*?*/ else +/*?*/ { // automagically +/*?*/ pNew->Add( new ScDoubleRefToken( ocColRowNameAuto, +/*?*/ aRefData ) ); +/*?*/ } +/*N*/ } +/*N*/ PushTokenArray( pNew, TRUE ); +/*N*/ pNew->Reset(); +/*N*/ return GetToken(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ SetError(errNoName); +/*N*/ } +/*N*/ else if( pToken->GetOpCode() == ocDBArea ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); /*N*/ ScDBData* pDBData = pDoc->GetDBCollection()->FindIndex( pToken->GetIndex() ); +/*N*/ /*?*/ if ( !pDBData ) +/*N*/ /*?*/ SetError(errNoName); +/*N*/ /*?*/ else if ( !bCompileForFAP ) +/*N*/ /*?*/ { +/*N*/ /*?*/ ComplRefData aRefData; +/*N*/ /*?*/ aRefData.InitFlags(); +/*N*/ /*?*/ pDBData->GetArea( (USHORT&) aRefData.Ref1.nTab, +/*N*/ /*?*/ (USHORT&) aRefData.Ref1.nCol, +/*N*/ /*?*/ (USHORT&) aRefData.Ref1.nRow, +/*N*/ /*?*/ (USHORT&) aRefData.Ref2.nCol, +/*N*/ /*?*/ (USHORT&) aRefData.Ref2.nRow); +/*N*/ /*?*/ aRefData.Ref2.nTab = aRefData.Ref1.nTab; +/*N*/ /*?*/ aRefData.CalcRelFromAbs( aPos ); +/*N*/ /*?*/ ScTokenArray* pNew = new ScTokenArray; +/*N*/ /*?*/ pNew->AddDoubleReference( aRefData ); +/*N*/ /*?*/ PushTokenArray( pNew, TRUE ); +/*N*/ /*?*/ pNew->Reset(); +/*N*/ /*?*/ return GetToken(); +/*N*/ /*?*/ } +/*N*/ } +/*N*/ else if( pToken->GetType() == svSingleRef ) +/*N*/ { +/*N*/ // if (!pDoc->HasTable( pToken->aRef.Ref1.nTab ) ) +/*N*/ // SetError(errNoRef); +/*N*/ pArr->nRefs++; +/*N*/ } +/*N*/ else if( pToken->GetType() == svDoubleRef ) +/*N*/ { +/*N*/ // if (!pDoc->HasTable( pToken->aRef.Ref1.nTab ) || +/*N*/ // !pDoc->HasTable( pToken->aRef.Ref2.nTab )) +/*N*/ // SetError(errNoRef); +/*N*/ pArr->nRefs++; +/*N*/ } +/*N*/ return TRUE; +/*N*/ } + +/*N*/ OpCode ScCompiler::NextToken() +/*N*/ { +/*N*/ if( !GetToken() ) +/*N*/ return ocStop; +/*N*/ OpCode eOp = pToken->GetOpCode(); +/*N*/ // #38815# CompileTokenArray mit zurueckgesetztem Fehler gibt wieder Fehler +/*N*/ if ( eOp == ocBad ) +/*N*/ SetError( errNoName ); +/*N*/ // Vor einem Push muss ein Operator kommen +/*N*/ if ( (eOp == ocPush || eOp == ocColRowNameAuto) && +/*N*/ !( (eLastOp == ocOpen) || (eLastOp == ocSep) || +/*N*/ ((eLastOp > ocEndDiv) && (eLastOp < ocEndUnOp))) ) +/*?*/ SetError(errOperatorExpected); +/*N*/ // Operator und Plus = Operator +/*N*/ BOOL bLastOp = ( eLastOp == ocOpen || eLastOp == ocSep || +/*N*/ (eLastOp > ocEndDiv && eLastOp < ocEndUnOp) +/*N*/ ); +/*N*/ if( bLastOp && eOp == ocAdd ) +/*N*/ eOp = NextToken(); +/*N*/ else +/*N*/ { +/*N*/ // Vor einem Operator darf kein weiterer Operator stehen +/*N*/ // Aber AND, OR ist OK +/*N*/ if ( eOp != ocAnd && eOp != ocOr +/*N*/ && ( eOp > ocEndDiv && eOp < ocEndBinOp ) +/*N*/ && ( eLastOp == ocOpen || eLastOp == ocSep +/*N*/ || (eLastOp > ocEndDiv && eLastOp < ocEndUnOp)) ) +/*N*/ { +/*?*/ SetError(errVariableExpected); +/*?*/ if ( bAutoCorrect && !pStack ) +/*?*/ { +/*?*/ if ( eOp == eLastOp || eLastOp == ocOpen ) +/*?*/ { // doppelten Operator verwerfen +/*?*/ aCorrectedSymbol.Erase(); +/*?*/ bCorrected = TRUE; +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ xub_StrLen nPos = aCorrectedFormula.Len(); +/*?*/ if ( nPos ) +/*?*/ { +/*?*/ nPos--; +/*?*/ sal_Unicode c = aCorrectedFormula.GetChar( nPos ); +/*?*/ switch ( eOp ) +/*?*/ { // Operatoren vertauschen +/*?*/ case ocGreater: +/*?*/ if ( c == pSymbolTable[ocEqual].GetChar(0) ) +/*?*/ { // >= ist richtig statt => +/*?*/ aCorrectedFormula.SetChar( nPos, +/*?*/ pSymbolTable[ocGreater].GetChar(0) ); +/*?*/ aCorrectedSymbol = c; +/*?*/ bCorrected = TRUE; +/*?*/ } +/*?*/ break; +/*?*/ case ocLess: +/*?*/ if ( c == pSymbolTable[ocEqual].GetChar(0) ) +/*?*/ { // <= ist richtig statt =< +/*?*/ aCorrectedFormula.SetChar( nPos, +/*?*/ pSymbolTable[ocLess].GetChar(0) ); +/*?*/ aCorrectedSymbol = c; +/*?*/ bCorrected = TRUE; +/*?*/ } +/*?*/ else if ( c == pSymbolTable[ocGreater].GetChar(0) ) +/*?*/ { // <> ist richtig statt >< +/*?*/ aCorrectedFormula.SetChar( nPos, +/*?*/ pSymbolTable[ocLess].GetChar(0) ); +/*?*/ aCorrectedSymbol = c; +/*?*/ bCorrected = TRUE; +/*?*/ } +/*?*/ break; +/*?*/ case ocMul: +/*?*/ if ( c == pSymbolTable[ocSub].GetChar(0) ) +/*?*/ { // *- statt -* +/*?*/ aCorrectedFormula.SetChar( nPos, +/*?*/ pSymbolTable[ocMul].GetChar(0) ); +/*?*/ aCorrectedSymbol = c; +/*?*/ bCorrected = TRUE; +/*?*/ } +/*?*/ break; +/*?*/ case ocDiv: +/*?*/ if ( c == pSymbolTable[ocSub].GetChar(0) ) +/*?*/ { // /- statt -/ +/*?*/ aCorrectedFormula.SetChar( nPos, +/*?*/ pSymbolTable[ocDiv].GetChar(0) ); +/*?*/ aCorrectedSymbol = c; +/*?*/ bCorrected = TRUE; +/*?*/ } +/*?*/ break; +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ eLastOp = eOp; +/*N*/ } +/*N*/ return eOp; +/*N*/ } + +//--------------------------------------------------------------------------- + +/*N*/ BOOL ScCompiler::CompileTokenArray() +/*N*/ { +/*N*/ glSubTotal = FALSE; +/*N*/ bCorrected = FALSE; +/*N*/ if( !pArr->nError || bIgnoreErrors ) +/*N*/ { +/*N*/ if ( bAutoCorrect ) +/*N*/ { +/*?*/ aCorrectedFormula.Erase(); +/*?*/ aCorrectedSymbol.Erase(); +/*N*/ } +/*N*/ pArr->nRefs = 0; // wird neu gezaehlt +/*N*/ pArr->DelRPN(); +/*N*/ pStack = NULL; +/*N*/ ScToken* pData[ MAXCODE ]; +/*N*/ pCode = pData; +/*N*/ BOOL bWasForced = pArr->IsRecalcModeForced(); +/*N*/ if ( bWasForced ) +/*N*/ { +/*N*/ if ( bAutoCorrect ) +/*N*/ aCorrectedFormula = '='; +/*N*/ } +/*N*/ pArr->ClearRecalcMode(); +/*N*/ pArr->Reset(); +/*N*/ eLastOp = ocOpen; +/*N*/ pc = 0; +/*N*/ NextToken(); +/*N*/ Expression(); +/*N*/ +/*N*/ USHORT nErrorBeforePop = pArr->nError; +/*N*/ +/*N*/ while( pStack ) +/*?*/ PopTokenArray(); +/*N*/ if( pc ) +/*N*/ { +/*N*/ pArr->pRPN = new ScToken*[ pc ]; +/*N*/ pArr->nRPN = pc; +/*N*/ memcpy( pArr->pRPN, pData, pc * sizeof( ScToken* ) ); +/*N*/ } +/*N*/ +/*N*/ if( !pArr->nError && nErrorBeforePop ) +/*N*/ pArr->nError = nErrorBeforePop; // einmal Fehler, immer Fehler +/*N*/ +/*N*/ if( pArr->nError && !bIgnoreErrors ) +/*N*/ pArr->DelRPN(); +/*N*/ +/*N*/ if ( bWasForced ) +/*?*/ pArr->SetRecalcModeForced(); +/*N*/ } +/*N*/ if( nNumFmt == NUMBERFORMAT_UNDEFINED ) +/*N*/ nNumFmt = NUMBERFORMAT_NUMBER; +/*N*/ return glSubTotal; +/*N*/ } + +//--------------------------------------------------------------------------- +// Token in den Code Eintragen +//--------------------------------------------------------------------------- + +/*N*/ void ScCompiler::PutCode( ScToken* p ) +/*N*/ { +/*N*/ if( pc >= MAXCODE-1 ) +/*N*/ { +/*?*/ if ( pc == MAXCODE-1 ) +/*?*/ { +/*?*/ p = new ScByteToken( ocStop ); +/*?*/ *pCode++ = p; +/*?*/ ++pc; +/*?*/ p->IncRef(); +/*?*/ } +/*?*/ SetError(errCodeOverflow); +/*?*/ return; +/*N*/ } +/*N*/ if( pArr->GetError() && !bCompileForFAP ) +/*N*/ return; +/*N*/ *pCode++ = p; pc++; +/*N*/ p->IncRef(); +/*N*/ } + +//--------------------------------------------------------------------------- +// UPN-Erzeugung (durch Rekursion) +//--------------------------------------------------------------------------- + +/*N*/ void ScCompiler::Factor() +/*N*/ { +/*N*/ if ( pArr->GetError() && !bIgnoreErrors ) +/*N*/ return; +/*N*/ ScTokenRef pFacToken; +/*N*/ OpCode eOp = pToken->GetOpCode(); +/*N*/ if( eOp == ocPush || eOp == ocColRowNameAuto || eOp == ocMatRef || +/*N*/ eOp == ocDBArea +/*N*/ || (bCompileForFAP && ((eOp == ocName) || (eOp == ocDBArea) +/*N*/ || (eOp == ocColRowName) || (eOp == ocBad))) +/*N*/ ) +/*N*/ { +/*N*/ PutCode( pToken ); +/*N*/ eOp = NextToken(); +/*N*/ if( eOp == ocOpen ) +/*N*/ { +/*?*/ // PUSH( ist ein Fehler, der durch eine unbekannte +/*?*/ // Funktion hervorgerufen wird. +/*?*/ SetError( +/*?*/ ( pToken->GetType() == svString +/*?*/ || pToken->GetType() == svSingleRef ) +/*?*/ ? errNoName : errOperatorExpected ); +/*?*/ if ( bAutoCorrect && !pStack ) +/*?*/ { // Multiplikation annehmen +/*?*/ aCorrectedFormula += pSymbolTable[ocMul]; +/*?*/ bCorrected = TRUE; +/*?*/ NextToken(); +/*?*/ eOp = Expression(); +/*?*/ if( eOp != ocClose ) +/*?*/ SetError(errPairExpected); +/*?*/ else +/*?*/ eOp = NextToken(); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ else if( eOp == ocOpen ) +/*N*/ { +/*N*/ NextToken(); +/*N*/ eOp = Expression(); +/*N*/ if( eOp != ocClose ) +/*N*/ SetError(errPairExpected); +/*N*/ else +/*N*/ eOp = NextToken(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( nNumFmt == NUMBERFORMAT_UNDEFINED ) +/*N*/ nNumFmt = lcl_GetRetFormat( eOp ); +/*N*/ if( eOp > ocEndUnOp && eOp < ocEndNoPar) +/*N*/ { +/*N*/ // Diese Funktionen muessen immer neu berechnet werden +/*N*/ switch( eOp ) +/*N*/ { +/*N*/ case ocRandom: +/*N*/ case ocGetActDate: +/*N*/ case ocGetActTime: +/*N*/ pArr->SetRecalcModeAlways(); +/*N*/ break; +/*N*/ } +/*N*/ pFacToken = pToken; +/*N*/ eOp = NextToken(); +/*N*/ if (eOp != ocOpen) +/*N*/ { +/*?*/ SetError(errPairExpected); +/*?*/ PutCode( pFacToken ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ eOp = NextToken(); +/*N*/ if (eOp != ocClose) +/*?*/ SetError(errPairExpected); +/*N*/ PutCode(pFacToken); +/*N*/ eOp = NextToken(); +/*N*/ } +/*N*/ } +/*N*/ // Spezialfall NICHT() und NEG() +/*N*/ else if( eOp == ocNot || eOp == ocNeg +/*N*/ || ( eOp > ocEndNoPar && eOp < ocEnd1Par) ) +/*N*/ { +/*N*/ // Functions that have to be always recalculated +/*N*/ switch( eOp ) +/*N*/ { +/*N*/ case ocFormula: +/*?*/ pArr->SetRecalcModeAlways(); +/*N*/ break; +/*N*/ } +/*N*/ pFacToken = pToken; +/*N*/ eOp = NextToken(); +/*N*/ if( nNumFmt == NUMBERFORMAT_UNDEFINED && eOp == ocNot ) +/*N*/ nNumFmt = NUMBERFORMAT_LOGICAL; +/*N*/ if (eOp == ocOpen) +/*N*/ { +/*N*/ NextToken(); +/*N*/ eOp = Expression(); +/*N*/ } +/*N*/ else +/*N*/ SetError(errPairExpected); +/*N*/ if (eOp != ocClose) +/*N*/ SetError(errPairExpected); +/*N*/ else if ( !pArr->GetError() ) +/*N*/ pFacToken->SetByte( 1 ); +/*N*/ PutCode( pFacToken ); +/*N*/ eOp = NextToken(); +/*N*/ } +/*N*/ else if ((eOp > ocEnd1Par && eOp < ocEnd2Par) +/*N*/ || eOp == ocExternal +/*N*/ || eOp == ocMacro +/*N*/ || eOp == ocAnd +/*N*/ || eOp == ocOr +/*N*/ || ( eOp >= ocInternalBegin && eOp <= ocInternalEnd ) +/*N*/ || (bCompileForFAP && ((eOp == ocIf) || (eOp == ocChose))) +/*N*/ ) +/*N*/ { +/*N*/ OpCode eFuncOp = eOp; +/*N*/ pFacToken = pToken; +/*N*/ eOp = NextToken(); +/*N*/ BOOL bNoParam = FALSE; +/*N*/ BOOL bNoPair = FALSE; +/*N*/ BYTE nMultiAreaSep = 0; +/*N*/ if (eOp == ocOpen) +/*N*/ { +/*N*/ eOp = NextToken(); +/*N*/ if ( eFuncOp == ocIndex && eOp == ocOpen ) +/*N*/ { // Mehrfachbereiche +/*?*/ BYTE SepCount = 0; +/*?*/ do +/*?*/ { +/*?*/ eOp = NextToken(); +/*?*/ if ( eOp != ocClose ) +/*?*/ { +/*?*/ SepCount++; +/*?*/ eOp = Expression(); +/*?*/ } +/*?*/ } while ( (eOp == ocSep) && (!pArr->GetError() || bIgnoreErrors) ); +/*?*/ if ( eOp != ocClose ) +/*?*/ SetError(errPairExpected); +/*?*/ eOp = NextToken(); +/*?*/ if ( eOp == ocSep ) +/*?*/ { +/*?*/ nMultiAreaSep = 1; +/*?*/ eOp = NextToken(); +/*?*/ } +/*?*/ if ( SepCount == 0 ) +/*?*/ { +/*?*/ if ( eOp == ocClose ) +/*?*/ bNoParam = TRUE; +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ PutCode( new ScByteToken( ocPush, SepCount ) ); +/*?*/ if ( eOp != ocClose ) +/*?*/ eOp = Expression(); +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if (eOp == ocClose) +/*N*/ bNoParam = TRUE; +/*N*/ else +/*N*/ eOp = Expression(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ if (pFacToken->GetOpCode() == ocMultiArea) +/*?*/ { +/*?*/ bNoPair = TRUE; +/*?*/ NextToken(); +/*?*/ eOp = Expression(); +/*?*/ } +/*?*/ else +/*?*/ SetError(errPairExpected); +/*N*/ } +/*N*/ BYTE SepCount = nMultiAreaSep; +/*N*/ if( !bNoParam ) +/*N*/ { +/*N*/ SepCount++; +/*N*/ while ( (eOp == ocSep) && (!pArr->GetError() || bIgnoreErrors) ) +/*N*/ { +/*N*/ SepCount++; +/*N*/ NextToken(); +/*N*/ eOp = Expression(); +/*N*/ } +/*N*/ } +/*N*/ if ((eOp != ocClose) && !bNoPair ) +/*N*/ SetError(errPairExpected); +/*N*/ else +/*N*/ eOp = NextToken(); +/*N*/ // Jumps are just normal functions for the FunctionAutoPilot tree view +/*N*/ if ( bCompileForFAP && pFacToken->GetType() == svJump ) +/*?*/ pFacToken = new ScFAPToken( pFacToken->GetOpCode(), SepCount, pFacToken ); +/*N*/ else +/*N*/ pFacToken->SetByte( SepCount ); +/*N*/ PutCode( pFacToken ); +/*N*/ // Diese Funktionen muessen immer neu berechnet werden +/*N*/ switch( eFuncOp ) +/*N*/ { +/*?*/ // ocIndirect muesste sonst bei jedem Interpret StopListening +/*?*/ // und StartListening fuer ein RefTripel ausfuehren +/*?*/ case ocIndirect: +/*?*/ // ocOffset und ocIndex liefern indirekte Refs +/*?*/ case ocOffset: +/*?*/ case ocIndex: +/*?*/ pArr->SetRecalcModeAlways(); +/*?*/ break; +/*?*/ // Functions recalculated on every document load. +/*?*/ // Don't use SetRecalcModeOnLoad which would override ModeAlways +/*N*/ case ocConvert : +/*N*/ pArr->AddRecalcMode( RECALCMODE_ONLOAD ); +/*N*/ break; +/*?*/ // wird die referierte verschoben, aendert sich der Wert +/*?*/ case ocColumn : +/*?*/ case ocRow : +/*?*/ case ocCell : // CELL needs recalc on move for some possible type values +/*?*/ pArr->SetRecalcModeOnRefMove(); +/*?*/ break; +/*N*/ } +/*N*/ } +/*N*/ else if (eOp == ocIf || eOp == ocChose) +/*N*/ { +/*N*/ // Die PC-Staende sind -1 +/*N*/ pFacToken = pToken; +/*N*/ if ( eOp == ocIf ) +/*N*/ pFacToken->GetJump()[ 0 ] = 3; // if, else, behind +/*N*/ else +/*?*/ pFacToken->GetJump()[ 0 ] = MAXJUMPCOUNT+1; +/*N*/ eOp = NextToken(); +/*N*/ if (eOp == ocOpen) +/*N*/ { +/*N*/ NextToken(); +/*N*/ eOp = Expression(); +/*N*/ } +/*N*/ else +/*N*/ SetError(errPairExpected); +/*N*/ short nJumpCount = 0; +/*N*/ PutCode( pFacToken ); +/*N*/ // #36253# bei AutoCorrect (da pArr->nError ignoriert wird) +/*N*/ // unbegrenztes ocIf gibt GPF weil ScRawToken::Clone den JumpBuffer +/*N*/ // anhand von nJump[0]*2+2 alloziert, was bei ocIf 3*2+2 ist +/*N*/ const short nJumpMax = +/*N*/ (pFacToken->GetOpCode() == ocIf ? 3 : MAXJUMPCOUNT); +/*N*/ while ( (nJumpCount < (MAXJUMPCOUNT - 1)) && (eOp == ocSep) +/*N*/ && (!pArr->GetError() || bIgnoreErrors) ) +/*N*/ { +/*N*/ if ( ++nJumpCount <= nJumpMax ) +/*N*/ pFacToken->GetJump()[nJumpCount] = pc-1; +/*N*/ NextToken(); +/*N*/ eOp = Expression(); +/*N*/ PutCode( pToken ); // Als Terminator des Teilausdrucks +/*N*/ } +/*N*/ if (eOp != ocClose) +/*N*/ SetError(errPairExpected); +/*N*/ else +/*N*/ { +/*N*/ eOp = NextToken(); +/*N*/ // auch ohne AutoCorrect gibt es hier ohne nJumpMax bei +/*N*/ // mehr als 3 Parametern in ocIf einen Ueberschreiber, +/*N*/ // das war auch schon in der 312 so (jaja, die Tester..) +/*N*/ if ( ++nJumpCount <= nJumpMax ) +/*N*/ pFacToken->GetJump()[ nJumpCount ] = pc-1; +/*N*/ if ((pFacToken->GetOpCode() == ocIf && (nJumpCount > 3)) || +/*N*/ (nJumpCount >= MAXJUMPCOUNT)) +/*N*/ SetError(errIllegalParameter); +/*N*/ else +/*N*/ pFacToken->GetJump()[ 0 ] = nJumpCount; +/*N*/ } +/*N*/ } +/*N*/ else if ( eOp == ocBad ) +/*N*/ { +/*?*/ SetError( errNoName ); +/*N*/ } +/*N*/ else if ( eOp == ocClose ) +/*N*/ { +/*?*/ SetError( errParameterExpected ); +/*N*/ } +/*N*/ else if ( eOp == ocMissing ) +/*N*/ { // #84460# May occur if imported from Xcl. +/*?*/ // The real value for missing parameters depends on the function +/*?*/ // where it is used, interpreter would have to handle this. +/*?*/ // If it does remove this error case here, that could also be the +/*?*/ // time to generate ocMissing in between subsequent ocSep. +/*?*/ // Xcl import should map missings to values if possible. +/*?*/ SetError( errParameterExpected ); +/*N*/ } +/*N*/ else if ( eOp == ocSep ) +/*N*/ { // Subsequent ocSep +/*N*/ SetError( errParameterExpected ); +/*N*/ if ( bAutoCorrect && !pStack ) +/*N*/ { +/*?*/ aCorrectedSymbol.Erase(); +/*?*/ bCorrected = TRUE; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ SetError( errUnknownToken ); +/*?*/ if ( bAutoCorrect && !pStack ) +/*?*/ { +/*?*/ if ( eOp == ocStop ) +/*?*/ { // trailing operator w/o operand +/*?*/ xub_StrLen nLen = aCorrectedFormula.Len(); +/*?*/ if ( nLen ) +/*?*/ aCorrectedFormula.Erase( nLen - 1 ); +/*?*/ aCorrectedSymbol.Erase(); +/*?*/ bCorrected = TRUE; +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +//--------------------------------------------------------------------------- + +/*N*/ void ScCompiler::Unary() +/*N*/ { +/*N*/ if( pToken->GetOpCode() == ocAdd ) +/*?*/ GetToken(); +/*N*/ else if ( pToken->GetOpCode() > ocNot && pToken->GetOpCode() < ocEndUnOp ) +/*N*/ { +/*?*/ ScTokenRef p = pToken; +/*?*/ NextToken(); +/*?*/ Factor(); +/*?*/ PutCode( p ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ Factor(); +/*N*/ while ( pToken->GetOpCode() == ocPercentSign ) +/*N*/ { // this operator _follows_ its operand +/*?*/ PutCode( pToken ); +/*?*/ NextToken(); +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void ScCompiler::PowLine() +/*N*/ { +/*N*/ Unary(); +/*N*/ while (pToken->GetOpCode() == ocPow) +/*N*/ { +/*?*/ ScTokenRef p = pToken; +/*?*/ NextToken(); +/*?*/ Unary(); +/*?*/ PutCode(p); +/*N*/ } +/*N*/ } + +//--------------------------------------------------------------------------- + +/*N*/ void ScCompiler::UnionCutLine() +/*N*/ { +/*N*/ PowLine(); +/*N*/ while (pToken->GetOpCode() == ocIntersect) +/*N*/ { +/*?*/ ScTokenRef p = pToken; +/*?*/ NextToken(); +/*?*/ PowLine(); +/*?*/ PutCode(p); +/*N*/ } +/*N*/ } + +//--------------------------------------------------------------------------- + +/*N*/ void ScCompiler::MulDivLine() +/*N*/ { +/*N*/ UnionCutLine(); +/*N*/ while (pToken->GetOpCode() == ocMul || pToken->GetOpCode() == ocDiv) +/*N*/ { +/*N*/ ScTokenRef p = pToken; +/*N*/ NextToken(); +/*N*/ UnionCutLine(); +/*N*/ PutCode(p); +/*N*/ } +/*N*/ } + +//--------------------------------------------------------------------------- + +/*N*/ void ScCompiler::AddSubLine() +/*N*/ { +/*N*/ MulDivLine(); +/*N*/ while (pToken->GetOpCode() == ocAdd || pToken->GetOpCode() == ocSub) +/*N*/ { +/*N*/ ScTokenRef p = pToken; +/*N*/ NextToken(); +/*N*/ MulDivLine(); +/*N*/ PutCode(p); +/*N*/ } +/*N*/ } + +//--------------------------------------------------------------------------- + +/*N*/ void ScCompiler::ConcatLine() +/*N*/ { +/*N*/ AddSubLine(); +/*N*/ while (pToken->GetOpCode() == ocAmpersand) +/*N*/ { +/*N*/ ScTokenRef p = pToken; +/*N*/ NextToken(); +/*N*/ AddSubLine(); +/*N*/ PutCode(p); +/*N*/ } +/*N*/ } + +//--------------------------------------------------------------------------- + +/*N*/ void ScCompiler::CompareLine() +/*N*/ { +/*N*/ ConcatLine(); +/*N*/ while (pToken->GetOpCode() >= ocEqual && pToken->GetOpCode() <= ocGreaterEqual) +/*N*/ { +/*N*/ ScTokenRef p = pToken; +/*N*/ NextToken(); +/*N*/ ConcatLine(); +/*N*/ PutCode(p); +/*N*/ } +/*N*/ } + +//--------------------------------------------------------------------------- + +/*N*/ void ScCompiler::NotLine() +/*N*/ { +/*N*/ CompareLine(); +/*N*/ while (pToken->GetOpCode() == ocNot) +/*N*/ { +/*?*/ ScTokenRef p = pToken; +/*?*/ NextToken(); +/*?*/ CompareLine(); +/*?*/ PutCode(p); +/*N*/ } +/*N*/ } + +//--------------------------------------------------------------------------- + +/*N*/ OpCode ScCompiler::Expression() +/*N*/ { +/*N*/ static const short nRecursionMax = 42; +/*N*/ ScCompilerRecursionGuard aRecursionGuard( nRecursion ); +/*N*/ if ( nRecursion > nRecursionMax ) +/*N*/ { +/*?*/ SetError( errStackOverflow ); +/*?*/ return ocStop; //! stattdessen Token generieren? +/*N*/ } +/*N*/ NotLine(); +/*N*/ while (pToken->GetOpCode() == ocAnd || pToken->GetOpCode() == ocOr) +/*N*/ { +/*?*/ ScTokenRef p = pToken; +/*?*/ pToken->SetByte( 2 ); // 2 parameters! +/*?*/ NextToken(); +/*?*/ NotLine(); +/*?*/ PutCode(p); +/*N*/ } +/*N*/ return pToken->GetOpCode(); +/*N*/ } + +// Referenz aus benanntem Bereich mit relativen Angaben + +/*N*/ void ScCompiler::SetRelNameReference() +/*N*/ { +/*N*/ pArr->Reset(); +/*N*/ for( ScToken* t = pArr->GetNextReference(); t; +/*N*/ t = pArr->GetNextReference() ) +/*N*/ { +/*N*/ SingleRefData& rRef1 = t->GetSingleRef(); +/*N*/ if ( rRef1.IsColRel() || rRef1.IsRowRel() || rRef1.IsTabRel() ) +/*?*/ rRef1.SetRelName( TRUE ); +/*N*/ if ( t->GetType() == svDoubleRef ) +/*N*/ { +/*?*/ SingleRefData& rRef2 = t->GetDoubleRef().Ref2; +/*?*/ if ( rRef2.IsColRel() || rRef2.IsRowRel() || rRef2.IsTabRel() ) +/*?*/ rRef2.SetRelName( TRUE ); +/*N*/ } +/*N*/ } +/*N*/ } + +// nur relative aus RangeName mit Wrap an Position anpassen +/*N*/ void ScCompiler::MoveRelWrap() +/*N*/ { +/*N*/ pArr->Reset(); +/*N*/ for( ScToken* t = pArr->GetNextReference(); t; +/*N*/ t = pArr->GetNextReference() ) +/*N*/ { +/*N*/ if ( t->GetType() == svSingleRef ) +/*N*/ ScRefUpdate::MoveRelWrap( pDoc, aPos, SingleDoubleRefModifier( t->GetSingleRef() ).Ref() ); +/*N*/ else +/*?*/ ScRefUpdate::MoveRelWrap( pDoc, aPos, t->GetDoubleRef() ); +/*N*/ } +/*N*/ } + +/*N*/ BOOL ScCompiler::UpdateNameReference(UpdateRefMode eUpdateRefMode, +/*N*/ const ScRange& r, +/*N*/ short nDx, short nDy, short nDz, +/*N*/ BOOL& rChanged) +/*N*/ { +/*N*/ BOOL bRet = FALSE; // wird gesetzt, wenn rel-Ref +/*N*/ rChanged = FALSE; +/*N*/ pArr->Reset(); +/*N*/ for( ScToken* t = pArr->GetNextReference(); t; +/*N*/ t = pArr->GetNextReference() ) +/*N*/ { +/*N*/ SingleDoubleRefModifier aMod( *t ); +/*N*/ ComplRefData& rRef = aMod.Ref(); +/*N*/ if (!rRef.Ref1.IsColRel() && !rRef.Ref1.IsRowRel() && +/*N*/ (!rRef.Ref1.IsFlag3D() || !rRef.Ref1.IsTabRel()) && +/*N*/ ( t->GetType() == svSingleRef || +/*N*/ (!rRef.Ref2.IsColRel() && !rRef.Ref2.IsRowRel() && +/*N*/ (!rRef.Ref2.IsFlag3D() || !rRef.Ref2.IsTabRel())))) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); /*N*/ if (ScRefUpdate::Update( pDoc, eUpdateRefMode, aPos, +/*N*/ /*?*/ r, nDx, nDy, nDz, rRef ) != UR_NOTHING ) +/*N*/ /*?*/ rChanged = TRUE; +/*N*/ } +/*N*/ else +/*N*/ bRet = TRUE; +/*N*/ } +/*N*/ return bRet; +/*N*/ } + + +/*N*/ ScRangeData* ScCompiler::UpdateInsertTab( USHORT nTable, BOOL bIsName ) +/*N*/ { +/*N*/ ScRangeData* pRangeData = NULL; +/*N*/ short nTab; +/*N*/ USHORT nPosTab = aPos.Tab(); // _nach_ evtl. Increment! +/*N*/ USHORT nOldPosTab = ((nPosTab > nTable) ? (nPosTab - 1) : nPosTab); +/*N*/ BOOL bIsRel = FALSE; +/*N*/ ScToken* t; +/*N*/ pArr->Reset(); +/*N*/ if (bIsName) +/*?*/ t = pArr->GetNextReference(); +/*N*/ else +/*N*/ t = pArr->GetNextReferenceOrName(); +/*N*/ while( t ) +/*N*/ { +/*N*/ if( t->GetOpCode() == ocName ) +/*N*/ { +/*?*/ if (!bIsName) +/*?*/ { +/*?*/ ScRangeData* pName = pDoc->GetRangeName()->FindIndex(t->GetIndex()); +/*?*/ if (pName && pName->HasType(RT_SHAREDMOD)) +/*?*/ pRangeData = pName; +/*?*/ } +/*N*/ } +/*N*/ else if( t->GetType() != svIndex ) // es kann ein DB-Bereich sein !!! +/*N*/ { +/*N*/ if ( !(bIsName && t->GetSingleRef().IsTabRel()) ) +/*N*/ { // Namen nur absolute anpassen +/*N*/ SingleRefData& rRef = t->GetSingleRef(); +/*N*/ if ( rRef.IsTabRel() ) +/*N*/ { +/*N*/ nTab = rRef.nRelTab + nOldPosTab; +/*N*/ if ( nTab < 0 ) +/*?*/ nTab += pDoc->GetTableCount(); // was a wrap +/*N*/ } +/*N*/ else +/*N*/ nTab = rRef.nTab; +/*N*/ if ( nTable <= nTab ) +/*N*/ rRef.nTab = nTab + 1; +/*N*/ rRef.nRelTab = rRef.nTab - nPosTab; +/*N*/ } +/*N*/ else +/*N*/ bIsRel = TRUE; +/*N*/ if ( t->GetType() == svDoubleRef ) +/*N*/ { +/*N*/ if ( !(bIsName && t->GetDoubleRef().Ref2.IsTabRel()) ) +/*N*/ { // Namen nur absolute anpassen +/*N*/ SingleRefData& rRef = t->GetDoubleRef().Ref2; +/*N*/ if ( rRef.IsTabRel() ) +/*N*/ { +/*N*/ nTab = rRef.nRelTab + nOldPosTab; +/*N*/ if ( nTab < 0 ) +/*?*/ nTab += pDoc->GetTableCount(); // was a wrap +/*N*/ } +/*N*/ else +/*N*/ nTab = rRef.nTab; +/*N*/ if ( nTable <= nTab ) +/*N*/ rRef.nTab = nTab + 1; +/*N*/ rRef.nRelTab = rRef.nTab - nPosTab; +/*N*/ } +/*N*/ else +/*N*/ bIsRel = TRUE; +/*N*/ } +/*N*/ if ( bIsName && bIsRel ) +/*N*/ pRangeData = (ScRangeData*) this; // wird in rangenam nicht dereferenziert +/*N*/ } +/*N*/ if (bIsName) +/*?*/ t = pArr->GetNextReference(); +/*N*/ else +/*N*/ t = pArr->GetNextReferenceOrName(); +/*N*/ } +/*N*/ if ( !bIsName ) +/*N*/ { +/*N*/ pArr->Reset(); +/*N*/ for ( t = pArr->GetNextReferenceRPN(); t; +/*N*/ t = pArr->GetNextReferenceRPN() ) +/*N*/ { +/*N*/ if ( t->GetRef() == 1 ) +/*N*/ { +/*N*/ SingleRefData& rRef1 = t->GetSingleRef(); +/*N*/ if ( !(rRef1.IsRelName() && rRef1.IsTabRel()) ) +/*N*/ { // Namen nur absolute anpassen +/*N*/ if ( rRef1.IsTabRel() ) +/*N*/ { +/*?*/ nTab = rRef1.nRelTab + nOldPosTab; +/*?*/ if ( nTab < 0 ) +/*?*/ nTab += pDoc->GetTableCount(); // was a wrap +/*N*/ } +/*N*/ else +/*N*/ nTab = rRef1.nTab; +/*N*/ if ( nTable <= nTab ) +/*N*/ rRef1.nTab = nTab + 1; +/*N*/ rRef1.nRelTab = rRef1.nTab - nPosTab; +/*N*/ } +/*N*/ if ( t->GetType() == svDoubleRef ) +/*N*/ { +/*?*/ SingleRefData& rRef2 = t->GetDoubleRef().Ref2; +/*?*/ if ( !(rRef2.IsRelName() && rRef2.IsTabRel()) ) +/*?*/ { // Namen nur absolute anpassen +/*?*/ if ( rRef2.IsTabRel() ) +/*?*/ { +/*?*/ nTab = rRef2.nRelTab + nOldPosTab; +/*?*/ if ( nTab < 0 ) +/*?*/ nTab += pDoc->GetTableCount(); // was a wrap +/*?*/ } +/*?*/ else +/*?*/ nTab = rRef2.nTab; +/*?*/ if ( nTable <= nTab ) +/*?*/ rRef2.nTab = nTab + 1; +/*?*/ rRef2.nRelTab = rRef2.nTab - nPosTab; +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return pRangeData; +/*N*/ } + +/*N*/ ScRangeData* ScCompiler::UpdateDeleteTab(USHORT nTable, BOOL bIsMove, BOOL bIsName, +/*N*/ BOOL& rChanged) +/*N*/ { +/*N*/ ScRangeData* pRangeData = NULL; +/*N*/ USHORT nTab, nTab2; +/*N*/ USHORT nPosTab = aPos.Tab(); // _nach_ evtl. Decrement! +/*N*/ USHORT nOldPosTab = ((nPosTab >= nTable) ? (nPosTab + 1) : nPosTab); +/*N*/ rChanged = FALSE; +/*N*/ BOOL bIsRel = FALSE; +/*N*/ ScToken* t; +/*N*/ pArr->Reset(); +/*N*/ if (bIsName) +/*N*/ t = pArr->GetNextReference(); +/*N*/ else +/*N*/ t = pArr->GetNextReferenceOrName(); +/*N*/ while( t ) +/*N*/ { +/*N*/ if( t->GetOpCode() == ocName ) +/*N*/ { +/*N*/ if (!bIsName) +/*N*/ { +/*N*/ ScRangeData* pName = pDoc->GetRangeName()->FindIndex(t->GetIndex()); +/*N*/ if (pName && pName->HasType(RT_SHAREDMOD)) +/*N*/ pRangeData = pName; +/*N*/ } +/*N*/ rChanged = TRUE; +/*N*/ } +/*N*/ else if( t->GetType() != svIndex ) // es kann ein DB-Bereich sein !!! +/*N*/ { +/*N*/ if ( !(bIsName && t->GetSingleRef().IsTabRel()) ) +/*N*/ { // Namen nur absolute anpassen +/*N*/ SingleRefData& rRef = t->GetSingleRef(); +/*N*/ if ( rRef.IsTabRel() ) +/*N*/ nTab = rRef.nRelTab + nOldPosTab; +/*N*/ else +/*N*/ nTab = rRef.nTab; +/*N*/ if ( nTable < nTab ) +/*N*/ { +/*N*/ rRef.nTab = nTab - 1; +/*N*/ rChanged = TRUE; +/*N*/ } +/*N*/ else if ( nTable == nTab ) +/*N*/ { +/*N*/ if ( t->GetType() == svDoubleRef ) +/*N*/ { +/*N*/ SingleRefData& rRef2 = t->GetDoubleRef().Ref2; +/*N*/ if ( rRef2.IsTabRel() ) +/*N*/ nTab2 = rRef2.nRelTab + nOldPosTab; +/*N*/ else +/*N*/ nTab2 = rRef2.nTab; +/*N*/ if ( nTab == nTab2 +/*N*/ || (nTab+1) >= pDoc->GetTableCount() ) +/*N*/ { +/*N*/ rRef.nTab = MAXTAB+1; +/*N*/ rRef.SetTabDeleted( TRUE ); +/*N*/ } +/*N*/ // else: nTab zeigt spaeter auf jetziges nTable+1 +/*N*/ // => Bereich verkleinert +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ rRef.nTab = MAXTAB+1; +/*N*/ rRef.SetTabDeleted( TRUE ); +/*N*/ } +/*N*/ rChanged = TRUE; +/*N*/ } +/*N*/ rRef.nRelTab = rRef.nTab - nPosTab; +/*N*/ } +/*N*/ else +/*N*/ bIsRel = TRUE; +/*N*/ if ( t->GetType() == svDoubleRef ) +/*N*/ { +/*N*/ if ( !(bIsName && t->GetDoubleRef().Ref2.IsTabRel()) ) +/*N*/ { // Namen nur absolute anpassen +/*N*/ SingleRefData& rRef = t->GetDoubleRef().Ref2; +/*N*/ if ( rRef.IsTabRel() ) +/*N*/ nTab = rRef.nRelTab + nOldPosTab; +/*N*/ else +/*N*/ nTab = rRef.nTab; +/*N*/ if ( nTable < nTab ) +/*N*/ { +/*N*/ rRef.nTab = nTab - 1; +/*N*/ rChanged = TRUE; +/*N*/ } +/*N*/ else if ( nTable == nTab ) +/*N*/ { +/*N*/ if ( !t->GetDoubleRef().Ref1.IsTabDeleted() ) +/*N*/ rRef.nTab = nTab - 1; // Bereich verkleinern +/*N*/ else +/*N*/ { +/*N*/ rRef.nTab = MAXTAB+1; +/*N*/ rRef.SetTabDeleted( TRUE ); +/*N*/ } +/*N*/ rChanged = TRUE; +/*N*/ } +/*N*/ rRef.nRelTab = rRef.nTab - nPosTab; +/*N*/ } +/*N*/ else +/*N*/ bIsRel = TRUE; +/*N*/ } +/*N*/ if ( bIsName && bIsRel ) +/*N*/ pRangeData = (ScRangeData*) this; // wird in rangenam nicht dereferenziert +/*N*/ } +/*N*/ if (bIsName) +/*N*/ t = pArr->GetNextReference(); +/*N*/ else +/*N*/ t = pArr->GetNextReferenceOrName(); +/*N*/ } +/*N*/ if ( !bIsName ) +/*N*/ { +/*N*/ pArr->Reset(); +/*N*/ for ( t = pArr->GetNextReferenceRPN(); t; +/*N*/ t = pArr->GetNextReferenceRPN() ) +/*N*/ { +/*N*/ if ( t->GetRef() == 1 ) +/*N*/ { +/*N*/ SingleRefData& rRef1 = t->GetSingleRef(); +/*N*/ if ( !(rRef1.IsRelName() && rRef1.IsTabRel()) ) +/*N*/ { // Namen nur absolute anpassen +/*N*/ if ( rRef1.IsTabRel() ) +/*N*/ nTab = rRef1.nRelTab + nOldPosTab; +/*N*/ else +/*N*/ nTab = rRef1.nTab; +/*N*/ if ( nTable < nTab ) +/*N*/ { +/*N*/ rRef1.nTab = nTab - 1; +/*N*/ rChanged = TRUE; +/*N*/ } +/*N*/ else if ( nTable == nTab ) +/*N*/ { +/*N*/ if ( t->GetType() == svDoubleRef ) +/*N*/ { +/*N*/ SingleRefData& rRef2 = t->GetDoubleRef().Ref2; +/*N*/ if ( rRef2.IsTabRel() ) +/*N*/ nTab2 = rRef2.nRelTab + nOldPosTab; +/*N*/ else +/*N*/ nTab2 = rRef2.nTab; +/*N*/ if ( nTab == nTab2 +/*N*/ || (nTab+1) >= pDoc->GetTableCount() ) +/*N*/ { +/*N*/ rRef1.nTab = MAXTAB+1; +/*N*/ rRef1.SetTabDeleted( TRUE ); +/*N*/ } +/*N*/ // else: nTab zeigt spaeter auf jetziges nTable+1 +/*N*/ // => Bereich verkleinert +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ rRef1.nTab = MAXTAB+1; +/*N*/ rRef1.SetTabDeleted( TRUE ); +/*N*/ } +/*N*/ rChanged = TRUE; +/*N*/ } +/*N*/ rRef1.nRelTab = rRef1.nTab - nPosTab; +/*N*/ } +/*N*/ if ( t->GetType() == svDoubleRef ) +/*N*/ { +/*N*/ SingleRefData& rRef2 = t->GetDoubleRef().Ref2; +/*N*/ if ( !(rRef2.IsRelName() && rRef2.IsTabRel()) ) +/*N*/ { // Namen nur absolute anpassen +/*N*/ if ( rRef2.IsTabRel() ) +/*N*/ nTab = rRef2.nRelTab + nOldPosTab; +/*N*/ else +/*N*/ nTab = rRef2.nTab; +/*N*/ if ( nTable < nTab ) +/*N*/ { +/*N*/ rRef2.nTab = nTab - 1; +/*N*/ rChanged = TRUE; +/*N*/ } +/*N*/ else if ( nTable == nTab ) +/*N*/ { +/*N*/ if ( !rRef1.IsTabDeleted() ) +/*N*/ rRef2.nTab = nTab - 1; // Bereich verkleinern +/*N*/ else +/*N*/ { +/*N*/ rRef2.nTab = MAXTAB+1; +/*N*/ rRef2.SetTabDeleted( TRUE ); +/*N*/ } +/*N*/ rChanged = TRUE; +/*N*/ } +/*N*/ rRef2.nRelTab = rRef2.nTab - nPosTab; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return pRangeData; +/*N*/ } + +/*N*/ ScToken* ScCompiler::CreateStringFromToken( String& rFormula, ScToken* pToken, +/*N*/ BOOL bAllowArrAdvance ) +/*N*/ { +/*N*/ ::rtl::OUStringBuffer aBuffer; +/*N*/ ScToken* p = CreateStringFromToken( aBuffer, pToken, bAllowArrAdvance ); +/*N*/ rFormula += aBuffer; +/*N*/ return p; +/*N*/ } + +/*N*/ ScToken* ScCompiler::CreateStringFromToken( ::rtl::OUStringBuffer& rBuffer, ScToken* pToken, +/*N*/ BOOL bAllowArrAdvance ) +/*N*/ { +/*N*/ BOOL bNext = TRUE; +/*N*/ BOOL bSpaces = FALSE; +/*N*/ ScToken* t = pToken; +/*N*/ OpCode eOp = t->GetOpCode(); +/*N*/ if( eOp >= ocAnd && eOp <= ocOr ) +/*N*/ { +/*N*/ // AND, OR infix? +/*N*/ if ( bAllowArrAdvance ) +/*N*/ t = pArr->Next(); +/*N*/ else +/*N*/ t = pArr->PeekNext(); +/*N*/ bNext = FALSE; +/*N*/ bSpaces = ( !t || t->GetOpCode() != ocOpen ); +/*N*/ } +/*N*/ if( bSpaces ) +/*?*/ rBuffer.append(sal_Unicode(' ')); +/*N*/ +/*N*/ if( eOp == ocSpaces ) +/*N*/ { // most times it's just one blank +/*N*/ BYTE n = t->GetByte(); +/*N*/ for ( BYTE j=0; j<n; ++j ) +/*N*/ { +/*N*/ rBuffer.append(sal_Unicode(' ')); +/*N*/ } +/*N*/ } +/*N*/ else if( eOp >= ocInternalBegin && eOp <= ocInternalEnd ) +/*?*/ rBuffer.appendAscii( pInternal[ eOp - ocInternalBegin ] ); +/*N*/ else if( (USHORT) eOp < nAnzStrings) // Keyword: +/*N*/ rBuffer.append(pSymbolTable[eOp]); +/*N*/ else +/*N*/ { +/*?*/ DBG_ERROR("Unbekannter OpCode"); +/*?*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF)); +/*N*/ } +/*N*/ if( bNext ) switch( t->GetType() ) +/*N*/ { +/*N*/ case svDouble: +/*N*/ { +/*N*/ if ( pSymbolTable == pSymbolTableEnglish ) +/*N*/ { // Don't go via number formatter, slows down XML export +/*N*/ // significantly because on every formula the number formatter +/*N*/ // has to switch to/from English/native language. +/*N*/ ::rtl::math::doubleToUStringBuffer( rBuffer, t->GetDouble(), +/*N*/ rtl_math_StringFormat_Automatic, +/*N*/ rtl_math_DecimalPlaces_Max, '.', TRUE ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ ::rtl::math::doubleToUStringBuffer( rBuffer, t->GetDouble(), +/*N*/ rtl_math_StringFormat_Automatic, +/*N*/ rtl_math_DecimalPlaces_Max, +/*N*/ ScGlobal::pLocaleData->getNumDecimalSep().GetChar(0), +/*N*/ TRUE ); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case svString: +/*N*/ if( eOp == ocBad ) +/*N*/ rBuffer.append(t->GetString()); +/*N*/ else +/*N*/ { +/*N*/ if (bImportXML) +/*?*/ rBuffer.append(t->GetString()); +/*N*/ else +/*N*/ { +/*N*/ rBuffer.append(sal_Unicode('"')); +/*N*/ if ( ScGlobal::UnicodeStrChr( t->GetString().GetBuffer(), '"' ) == NULL ) +/*N*/ rBuffer.append(t->GetString()); +/*N*/ else +/*N*/ { +/*?*/ String aStr( t->GetString() ); +/*?*/ xub_StrLen nPos = 0; +/*?*/ while ( (nPos = aStr.Search( '"', nPos)) != STRING_NOTFOUND ) +/*?*/ { +/*?*/ aStr.Insert( '"', nPos ); +/*?*/ nPos += 2; +/*?*/ } +/*?*/ rBuffer.append(aStr); +/*N*/ } +/*N*/ rBuffer.append(sal_Unicode('"')); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case svSingleRef: +/*N*/ { +/*N*/ SingleRefData& rRef = t->GetSingleRef(); +/*N*/ ComplRefData aRef; +/*N*/ aRef.Ref1 = aRef.Ref2 = rRef; +/*N*/ if ( eOp == ocColRowName ) +/*N*/ { +/*N*/ rRef.CalcAbsIfRel( aPos ); +/*N*/ if ( pDoc->HasStringData( rRef.nCol, rRef.nRow, rRef.nTab ) ) +/*N*/ { +/*N*/ String aStr; +/*N*/ pDoc->GetString( rRef.nCol, rRef.nRow, rRef.nTab, aStr ); +/*N*/ EnQuote( aStr ); +/*N*/ rBuffer.append(aStr); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF)); +/*?*/ MakeRefStr( rBuffer, aRef, TRUE ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ MakeRefStr( rBuffer, aRef, TRUE ); +/*N*/ } +/*N*/ break; +/*N*/ case svDoubleRef: +/*N*/ MakeRefStr( rBuffer, t->GetDoubleRef(), FALSE ); +/*N*/ break; +/*N*/ case svIndex: +/*N*/ { +/*N*/ ::rtl::OUStringBuffer aBuffer; +/*N*/ switch ( eOp ) +/*N*/ { +/*N*/ case ocName: +/*N*/ { +/*N*/ ScRangeData* pData = pDoc->GetRangeName()->FindIndex(t->GetIndex()); +/*N*/ if (pData) +/*N*/ { +/*N*/ if (pData->HasType(RT_SHARED)) +/*N*/ pData->UpdateSymbol( aBuffer, aPos, +/*N*/ pSymbolTable == pSymbolTableEnglish, +/*N*/ bCompileXML ); +/*N*/ else +/*N*/ aBuffer.append(pData->GetName()); +/*N*/ } +/*N*/ } +/*N*/ break; +/*?*/ case ocDBArea: +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); /*N*/ ScDBData* pDBData = pDoc->GetDBCollection()->FindIndex(t->GetIndex()); +/*N*/ /*?*/ if (pDBData) +/*N*/ /*?*/ aBuffer.append(pDBData->GetName()); +/*?*/ } +/*?*/ break; +/*?*/ } +/*N*/ if ( aBuffer.getLength() ) +/*N*/ rBuffer.append(aBuffer); +/*N*/ else +/*?*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF)); +/*N*/ break; +/*N*/ } +/*N*/ case svExternal: +/*N*/ { +/*N*/ // show translated name of StarOne AddIns +/*N*/ String aAddIn( t->GetExternal() ); +/*N*/ if ( pSymbolTable != pSymbolTableEnglish ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 ScGlobal::GetAddInCollection()->LocalizeString( aAddIn ); +/*N*/ rBuffer.append(aAddIn); +/*N*/ } +/*N*/ break; +/*N*/ case svByte: +/*N*/ case svJump: +/*N*/ case svFAP: +/*N*/ case svMissing: +/*N*/ break; // Opcodes +/*N*/ default: +/*N*/ DBG_ERROR("ScCompiler:: GetStringFromToken errUnknownVariable"); +/*N*/ } // of switch +/*N*/ if( bSpaces ) +/*?*/ rBuffer.append(sal_Unicode(' ')); +/*N*/ if ( bAllowArrAdvance ) +/*N*/ { +/*N*/ if( bNext ) +/*N*/ t = pArr->Next(); +/*N*/ return t; +/*N*/ } +/*N*/ return pToken; +/*N*/ } + +/*N*/ void ScCompiler::CreateStringFromTokenArray( String& rFormula ) +/*N*/ { +/*N*/ ::rtl::OUStringBuffer aBuffer( pArr->GetLen() * 2 ); +/*N*/ CreateStringFromTokenArray( aBuffer ); +/*N*/ rFormula = aBuffer; +/*N*/ } + +/*N*/ void ScCompiler::CreateStringFromTokenArray( ::rtl::OUStringBuffer& rBuffer ) +/*N*/ { +/*N*/ rBuffer.setLength(0); +/*N*/ if( !pArr->GetLen() ) +/*N*/ return; +/*N*/ +/*N*/ // at least one char per token, plus some are references, some are function names +/*N*/ rBuffer.ensureCapacity( pArr->GetLen() * 2 ); +/*N*/ +/*N*/ if ( pArr->IsRecalcModeForced() ) +/*?*/ rBuffer.append(sal_Unicode('=')); +/*N*/ ScToken* t = pArr->First(); +/*N*/ while( t ) +/*N*/ t = CreateStringFromToken( rBuffer, t, TRUE ); +/*N*/ } + +/*N*/ BOOL ScCompiler::EnQuote( String& rStr ) +/*N*/ { +/*N*/ sal_Int32 nType = ScGlobal::pCharClass->getStringType( rStr, 0, rStr.Len() ); +/*N*/ if ( !CharClass::isNumericType( nType ) +/*N*/ && CharClass::isAlphaNumericType( nType ) ) +/*N*/ return FALSE; +/*N*/ xub_StrLen nPos = 0; +/*N*/ while ( (nPos = rStr.Search( '\'', nPos)) != STRING_NOTFOUND ) +/*N*/ { +/*N*/ rStr.Insert( '\\', nPos ); +/*N*/ nPos += 2; +/*N*/ } +/*N*/ rStr.Insert( '\'', 0 ); +/*N*/ rStr += '\''; +/*N*/ return TRUE; +/*N*/ } + + +/*N*/ BOOL ScCompiler::DeQuote( String& rStr ) +/*N*/ { +/*N*/ xub_StrLen nLen = rStr.Len(); +/*N*/ if ( nLen > 1 && rStr.GetChar(0) == '\'' && rStr.GetChar( nLen-1 ) == '\'' ) +/*N*/ { +/*N*/ rStr.Erase( nLen-1, 1 ); +/*N*/ rStr.Erase( 0, 1 ); +/*N*/ xub_StrLen nPos = 0; +/*N*/ while ( (nPos = rStr.SearchAscii( "\\\'", nPos)) != STRING_NOTFOUND ) +/*N*/ { +/*N*/ rStr.Erase( nPos, 1 ); +/*N*/ ++nPos; +/*N*/ } +/*N*/ return TRUE; +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_consoli.cxx b/binfilter/bf_sc/source/core/tool/sc_consoli.cxx new file mode 100644 index 000000000000..6b0a27de380a --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_consoli.cxx @@ -0,0 +1,606 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// INCLUDE --------------------------------------------------------------- + +#include <tools/debug.hxx> +#include <math.h> +#include <string.h> +#include "consoli.hxx" +#include "document.hxx" +#include "globstr.hrc" +#include "subtotal.hxx" +#include "cell.hxx" +namespace binfilter { + +#define SC_CONS_NOTFOUND 0xFFFF + +// STATIC DATA ----------------------------------------------------------- + +/* Strings bei Gelegenheit ganz raus... +static USHORT nFuncRes[] = { // Reihenfolge wie bei enum ScSubTotalFunc + 0, // none + STR_PIVOTFUNC_AVG, + STR_PIVOTFUNC_COUNT, + STR_PIVOTFUNC_COUNT2, + STR_PIVOTFUNC_MAX, + STR_PIVOTFUNC_MIN, + STR_PIVOTFUNC_PROD, + STR_PIVOTFUNC_STDDEV, + STR_PIVOTFUNC_STDDEV2, + STR_PIVOTFUNC_SUM, + STR_PIVOTFUNC_VAR, + STR_PIVOTFUNC_VAR2 }; +*/ + +/*N*/ static OpCode eOpCodeTable[] = { // Reihenfolge wie bei enum ScSubTotalFunc +/*N*/ ocBad, // none +/*N*/ ocAverage, +/*N*/ ocCount, +/*N*/ ocCount2, +/*N*/ ocMax, +/*N*/ ocMin, +/*N*/ ocProduct, +/*N*/ ocStDev, +/*N*/ ocStDevP, +/*N*/ ocSum, +/*N*/ ocVar, +/*N*/ ocVarP }; + +// ----------------------------------------------------------------------- + +/*N*/ void lcl_AddString( String**& pData, USHORT& nCount, const String& rInsert ) +/*N*/ { +/*N*/ String** pOldData = pData; +/*N*/ pData = new String*[ nCount+1 ]; +/*N*/ if (pOldData) +/*N*/ { +/*N*/ memmove( pData, pOldData, nCount * sizeof(String*) ); +/*N*/ delete[] pOldData; +/*N*/ } +/*N*/ pData[nCount] = new String(rInsert); +/*N*/ ++nCount; +/*N*/ } + +// ----------------------------------------------------------------------- + +/*N*/ ScConsData::ScConsData() : +/*N*/ eFunction(SUBTOTAL_FUNC_SUM), +/*N*/ bReference(FALSE), +/*N*/ bColByName(FALSE), +/*N*/ bRowByName(FALSE), +/*N*/ bSubTitles(FALSE), +/*N*/ nColCount(0), +/*N*/ ppColHeaders(NULL), +/*N*/ nRowCount(0), +/*N*/ ppRowHeaders(NULL), +/*N*/ ppCount(NULL), +/*N*/ ppSum(NULL), +/*N*/ ppSumSqr(NULL), +/*N*/ ppRefs(NULL), +/*N*/ ppUsed(NULL), +/*N*/ nDataCount(0), +/*N*/ nTitleCount(0), +/*N*/ ppTitles(NULL), +/*N*/ ppTitlePos(NULL), +/*N*/ bCornerUsed(FALSE) +/*N*/ { +/*N*/ } + +/*N*/ ScConsData::~ScConsData() +/*N*/ { +/*N*/ DeleteData(); +/*N*/ } + + +/*N*/ #define DELETEARR(ppArray,nCount) \ +/*N*/ { \ +/*N*/ USHORT i; \ +/*N*/ if (ppArray) \ +/*N*/ for(i=0; i<nCount; i++) \ +/*N*/ delete[] ppArray[i]; \ +/*N*/ delete[] ppArray; \ +/*N*/ ppArray = NULL; \ +/*N*/ } +/*N*/ +/*N*/ #define DELETESTR(ppArray,nCount) \ +/*N*/ { \ +/*N*/ USHORT i; \ +/*N*/ if (ppArray) \ +/*N*/ for(i=0; i<nCount; i++) \ +/*N*/ delete ppArray[i]; \ +/*N*/ delete[] ppArray; \ +/*N*/ ppArray = NULL; \ +/*N*/ } + +/*N*/ void ScConsData::DeleteData() +/*N*/ { +/*N*/ USHORT i; +/*N*/ +/*N*/ if (ppRefs) +/*N*/ for (i=0; i<nColCount; i++) +/*N*/ { +/*N*/ for (USHORT j=0; j<nRowCount; j++) +/*N*/ if (ppUsed[i][j]) +/*N*/ ppRefs[i][j].Clear(); +/*N*/ delete[] ppRefs[i]; +/*N*/ } +/*N*/ delete[] ppRefs; +/*N*/ ppRefs = NULL; +/*N*/ +/*N*/ // DELETEARR( ppData1, nColCount ); +/*N*/ // DELETEARR( ppData2, nColCount ); +/*N*/ DELETEARR( ppCount, nColCount ); +/*N*/ DELETEARR( ppSum, nColCount ); +/*N*/ DELETEARR( ppSumSqr,nColCount ); +/*N*/ DELETEARR( ppUsed, nColCount ); // erst nach ppRefs !!! +/*N*/ DELETEARR( ppTitlePos, nRowCount ); +/*N*/ DELETESTR( ppColHeaders, nColCount ); +/*N*/ DELETESTR( ppRowHeaders, nRowCount ); +/*N*/ DELETESTR( ppTitles, nTitleCount ); +/*N*/ nTitleCount = 0; +/*N*/ nDataCount = 0; +/*N*/ +/*N*/ if (bColByName) nColCount = 0; // sonst stimmt ppColHeaders nicht +/*N*/ if (bRowByName) nRowCount = 0; +/*N*/ +/*N*/ bCornerUsed = FALSE; +/*N*/ aCornerText.Erase(); +/*N*/ } + +/*N*/ #undef DELETEARR +/*N*/ #undef DELETESTR + +/*N*/ void ScConsData::InitData( BOOL bDelete ) +/*N*/ { +/*N*/ USHORT i; +/*N*/ if (bDelete) +/*N*/ DeleteData(); +/*N*/ +/*N*/ if (bReference && nColCount && !ppRefs) +/*N*/ { +/*N*/ ppRefs = new ScReferenceList*[nColCount]; +/*N*/ for (i=0; i<nColCount; i++) +/*N*/ ppRefs[i] = new ScReferenceList[nRowCount]; +/*N*/ } +/*N*/ else if (nColCount && !ppCount) +/*N*/ { +/*N*/ ppCount = new double*[nColCount]; +/*N*/ ppSum = new double*[nColCount]; +/*N*/ ppSumSqr = new double*[nColCount]; +/*N*/ for (i=0; i<nColCount; i++) +/*N*/ { +/*N*/ ppCount[i] = new double[nRowCount]; +/*N*/ ppSum[i] = new double[nRowCount]; +/*N*/ ppSumSqr[i] = new double[nRowCount]; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if (nColCount && !ppUsed) +/*N*/ { +/*N*/ ppUsed = new BOOL*[nColCount]; +/*N*/ for (i=0; i<nColCount; i++) +/*N*/ { +/*N*/ ppUsed[i] = new BOOL[nRowCount]; +/*N*/ memset( ppUsed[i], 0, nRowCount * sizeof(BOOL) ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if (nRowCount && nDataCount && !ppTitlePos) +/*N*/ { +/*N*/ ppTitlePos = new USHORT*[nRowCount]; +/*N*/ for (i=0; i<nRowCount; i++) +/*N*/ { +/*N*/ ppTitlePos[i] = new USHORT[nDataCount]; +/*N*/ memset( ppTitlePos[i], 0, nDataCount * sizeof(USHORT) ); //! unnoetig ? +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // CornerText: einzelner String +/*N*/ } + +/*N*/ void ScConsData::DoneFields() +/*N*/ { +/*N*/ InitData(FALSE); +/*N*/ } + +/*N*/ void ScConsData::SetSize( USHORT nCols, USHORT nRows ) +/*N*/ { +/*N*/ DeleteData(); +/*N*/ nColCount = nCols; +/*N*/ nRowCount = nRows; +/*N*/ } + +/*N*/ void ScConsData::GetSize( USHORT& rCols, USHORT& rRows ) const +/*N*/ { +/*N*/ rCols = nColCount; +/*N*/ rRows = nRowCount; +/*N*/ } + +/*N*/ void ScConsData::SetFlags( ScSubTotalFunc eFunc, BOOL bColName, BOOL bRowName, BOOL bRef ) +/*N*/ { +/*N*/ DeleteData(); +/*N*/ bReference = bRef; +/*N*/ bColByName = bColName; +/*N*/ if (bColName) nColCount = 0; +/*N*/ bRowByName = bRowName; +/*N*/ if (bRowName) nRowCount = 0; +/*N*/ eFunction = eFunc; +/*N*/ } + +/*N*/ void ScConsData::AddFields( ScDocument* pSrcDoc, USHORT nTab, +/*N*/ USHORT nCol1, USHORT nRow1, USHORT nCol2, USHORT nRow2 ) +/*N*/ { +/*N*/ ++nDataCount; +/*N*/ +/*N*/ String aTitle; +/*N*/ +/*N*/ USHORT nStartCol = nCol1; +/*N*/ USHORT nStartRow = nRow1; +/*N*/ if (bColByName) ++nStartRow; +/*N*/ if (bRowByName) ++nStartCol; +/*N*/ +/*N*/ if (bColByName) +/*N*/ { +/*N*/ for (USHORT nCol=nStartCol; nCol<=nCol2; nCol++) +/*N*/ { +/*N*/ pSrcDoc->GetString( nCol, nRow1, nTab, aTitle ); +/*N*/ if (aTitle.Len()) +/*N*/ { +/*N*/ BOOL bFound = FALSE; +/*N*/ for (USHORT i=0; i<nColCount && !bFound; i++) +/*N*/ if ( *ppColHeaders[i] == aTitle ) +/*N*/ bFound = TRUE; +/*N*/ if (!bFound) +/*N*/ lcl_AddString( ppColHeaders, nColCount, aTitle ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if (bRowByName) +/*N*/ { +/*N*/ for (USHORT nRow=nStartRow; nRow<=nRow2; nRow++) +/*N*/ { +/*N*/ pSrcDoc->GetString( nCol1, nRow, nTab, aTitle ); +/*N*/ if (aTitle.Len()) +/*N*/ { +/*N*/ BOOL bFound = FALSE; +/*N*/ for (USHORT i=0; i<nRowCount && !bFound; i++) +/*N*/ if ( *ppRowHeaders[i] == aTitle ) +/*N*/ bFound = TRUE; +/*N*/ if (!bFound) +/*N*/ lcl_AddString( ppRowHeaders, nRowCount, aTitle ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void ScConsData::AddName( const String& rName ) +/*N*/ { +/*N*/ USHORT nArrX; +/*N*/ USHORT nArrY; +/*N*/ +/*N*/ if (bReference) +/*N*/ { +/*N*/ lcl_AddString( ppTitles, nTitleCount, rName ); +/*N*/ +/*N*/ for (nArrY=0; nArrY<nRowCount; nArrY++) +/*N*/ { +/*N*/ // Daten auf gleiche Laenge bringen +/*N*/ +/*N*/ USHORT nMax = 0; +/*N*/ for (nArrX=0; nArrX<nColCount; nArrX++) +/*N*/ if (ppUsed[nArrX][nArrY]) +/*N*/ nMax = Max( nMax, ppRefs[nArrX][nArrY].GetCount() ); +/*N*/ +/*N*/ for (nArrX=0; nArrX<nColCount; nArrX++) +/*N*/ { +/*N*/ if (!ppUsed[nArrX][nArrY]) +/*N*/ { +/*N*/ ppUsed[nArrX][nArrY] = TRUE; +/*N*/ ppRefs[nArrX][nArrY].Init(); +/*N*/ } +/*N*/ ppRefs[nArrX][nArrY].SetFullSize(nMax); +/*N*/ } +/*N*/ +/*N*/ // Positionen eintragen +/*N*/ +/*N*/ if (ppTitlePos) +/*N*/ if (nTitleCount < nDataCount) +/*N*/ ppTitlePos[nArrY][nTitleCount] = nMax; +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ double lcl_CalcData( ScSubTotalFunc eFunc, +/*N*/ double fCount, double fSum, double fSumSqr) +/*N*/ { +/*N*/ if (fCount < 0.0) +/*N*/ return 0.0; +/*N*/ double fVal = 0.0; +/*N*/ switch (eFunc) +/*N*/ { +/*N*/ case SUBTOTAL_FUNC_CNT: +/*N*/ case SUBTOTAL_FUNC_CNT2: +/*N*/ fVal = fCount; +/*N*/ break; +/*N*/ case SUBTOTAL_FUNC_SUM: +/*N*/ case SUBTOTAL_FUNC_MAX: +/*N*/ case SUBTOTAL_FUNC_MIN: +/*N*/ case SUBTOTAL_FUNC_PROD: +/*N*/ fVal = fSum; +/*N*/ break; +/*N*/ case SUBTOTAL_FUNC_AVE: +/*N*/ if (fCount > 0.0) +/*N*/ fVal = fSum / fCount; +/*N*/ else +/*N*/ fCount = -MAXDOUBLE; +/*N*/ break; +/*N*/ case SUBTOTAL_FUNC_STD: +/*N*/ { +/*N*/ if (fCount > 1 && SubTotal::SafeMult(fSum, fSum)) +/*N*/ fVal = sqrt((fSumSqr - fSum/fCount)/(fCount-1.0)); +/*N*/ else +/*N*/ fCount = -MAXDOUBLE; +/*N*/ } +/*N*/ break; +/*N*/ case SUBTOTAL_FUNC_STDP: +/*N*/ { +/*N*/ if (fCount > 0 && SubTotal::SafeMult(fSum, fSum)) +/*N*/ fVal = sqrt((fSumSqr - fSum/fCount)/fCount); +/*N*/ else +/*N*/ fCount = -MAXDOUBLE; +/*N*/ } +/*N*/ break; +/*N*/ case SUBTOTAL_FUNC_VAR: +/*N*/ { +/*N*/ if (fCount > 1 && SubTotal::SafeMult(fSum, fSum)) +/*N*/ fVal = (fSumSqr - fSum/fCount)/(fCount-1.0); +/*N*/ else +/*N*/ fCount = -MAXDOUBLE; +/*N*/ } +/*N*/ break; +/*N*/ case SUBTOTAL_FUNC_VARP: +/*N*/ { +/*N*/ if (fCount > 0 && SubTotal::SafeMult(fSum, fSum)) +/*N*/ fVal = (fSumSqr - fSum/fCount)/fCount; +/*N*/ else +/*N*/ fCount = -MAXDOUBLE; +/*N*/ } +/*N*/ break; +/*N*/ default: +/*N*/ { +/*N*/ DBG_ERROR("unbekannte Funktion bei Consoli::CalcData"); +/*N*/ fCount = -MAXDOUBLE; +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ return fVal; +/*N*/ } + +/*N*/ void ScConsData::AddData( ScDocument* pSrcDoc, USHORT nTab, +/*N*/ USHORT nCol1, USHORT nRow1, USHORT nCol2, USHORT nRow2 ) +/*N*/ { +/*N*/ PutInOrder(nCol1,nCol2); +/*N*/ PutInOrder(nRow1,nRow2); +/*N*/ if ( nCol2 >= nCol1 + nColCount && !bColByName ) +/*N*/ { +/*N*/ DBG_ASSERT(0,"Bereich zu gross"); +/*N*/ nCol2 = nCol1 + nColCount - 1; +/*N*/ } +/*N*/ if ( nRow2 >= nRow1 + nRowCount && !bRowByName ) +/*N*/ { +/*N*/ DBG_ASSERT(0,"Bereich zu gross"); +/*N*/ nRow2 = nRow1 + nRowCount - 1; +/*N*/ } +/*N*/ +/*N*/ USHORT nCol; +/*N*/ USHORT nRow; +/*N*/ +/*N*/ // Ecke links oben +/*N*/ +/*N*/ if ( bColByName && bRowByName ) +/*N*/ { +/*N*/ String aThisCorner; +/*N*/ pSrcDoc->GetString(nCol1,nRow1,nTab,aThisCorner); +/*N*/ if (bCornerUsed) +/*N*/ { +/*N*/ if (aCornerText != aThisCorner) +/*N*/ aCornerText.Erase(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aCornerText = aThisCorner; +/*N*/ bCornerUsed = TRUE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // Titel suchen +/*N*/ +/*N*/ USHORT nStartCol = nCol1; +/*N*/ USHORT nStartRow = nRow1; +/*N*/ if (bColByName) ++nStartRow; +/*N*/ if (bRowByName) ++nStartCol; +/*N*/ String aTitle; +/*N*/ USHORT* pDestCols = NULL; +/*N*/ USHORT* pDestRows = NULL; +/*N*/ if (bColByName) +/*N*/ { +/*N*/ pDestCols = new USHORT[nCol2-nStartCol+1]; +/*N*/ for (nCol=nStartCol; nCol<=nCol2; nCol++) +/*N*/ { +/*N*/ pSrcDoc->GetString(nCol,nRow1,nTab,aTitle); +/*N*/ USHORT nPos = SC_CONS_NOTFOUND; +/*N*/ if (aTitle.Len()) +/*N*/ { +/*N*/ BOOL bFound = FALSE; +/*N*/ for (USHORT i=0; i<nColCount && !bFound; i++) +/*N*/ if ( *ppColHeaders[i] == aTitle ) +/*N*/ { +/*N*/ nPos = i; +/*N*/ bFound = TRUE; +/*N*/ } +/*N*/ DBG_ASSERT(bFound, "Spalte nicht gefunden"); +/*N*/ } +/*N*/ pDestCols[nCol-nStartCol] = nPos; +/*N*/ } +/*N*/ } +/*N*/ if (bRowByName) +/*N*/ { +/*N*/ pDestRows = new USHORT[nRow2-nStartRow+1]; +/*N*/ for (nRow=nStartRow; nRow<=nRow2; nRow++) +/*N*/ { +/*N*/ pSrcDoc->GetString(nCol1,nRow,nTab,aTitle); +/*N*/ USHORT nPos = SC_CONS_NOTFOUND; +/*N*/ if (aTitle.Len()) +/*N*/ { +/*N*/ BOOL bFound = FALSE; +/*N*/ for (USHORT i=0; i<nRowCount && !bFound; i++) +/*N*/ if ( *ppRowHeaders[i] == aTitle ) +/*N*/ { +/*N*/ nPos = i; +/*N*/ bFound = TRUE; +/*N*/ } +/*N*/ DBG_ASSERT(bFound, "Zeile nicht gefunden"); +/*N*/ } +/*N*/ pDestRows[nRow-nStartRow] = nPos; +/*N*/ } +/*N*/ } +/*N*/ nCol1 = nStartCol; +/*N*/ nRow1 = nStartRow; +/*N*/ +/*N*/ // Daten +/*N*/ +/*N*/ BOOL bAnyCell = ( eFunction == SUBTOTAL_FUNC_CNT2 ); +/*N*/ for (nCol=nCol1; nCol<=nCol2; nCol++) +/*N*/ { +/*N*/ USHORT nArrX = nCol-nCol1; +/*N*/ if (bColByName) nArrX = pDestCols[nArrX]; +/*N*/ if (nArrX != SC_CONS_NOTFOUND) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 for (nRow=nRow1; nRow<=nRow2; nRow++) +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ delete[] pDestCols; +/*N*/ delete[] pDestRows; +/*N*/ } + +// fertige Daten ins Dokument schreiben +//! optimieren nach Spalten? + +/*N*/ void ScConsData::OutputToDocument( ScDocument* pDestDoc, USHORT nCol, USHORT nRow, USHORT nTab ) +/*N*/ { +/*N*/ OpCode eOpCode = eOpCodeTable[eFunction]; +/*N*/ +/*N*/ USHORT nArrX; +/*N*/ USHORT nArrY; +/*N*/ USHORT nCount; +/*N*/ USHORT nPos; +/*N*/ USHORT i; +/*N*/ +/*N*/ // Ecke links oben +/*N*/ +/*N*/ if ( bColByName && bRowByName && aCornerText.Len() ) +/*N*/ pDestDoc->SetString( nCol, nRow, nTab, aCornerText ); +/*N*/ +/*N*/ // Titel +/*N*/ +/*N*/ USHORT nStartCol = nCol; +/*N*/ USHORT nStartRow = nRow; +/*N*/ if (bColByName) ++nStartRow; +/*N*/ if (bRowByName) ++nStartCol; +/*N*/ +/*N*/ if (bColByName) +/*N*/ for (i=0; i<nColCount; i++) +/*N*/ pDestDoc->SetString( nStartCol+i, nRow, nTab, *ppColHeaders[i] ); +/*N*/ if (bRowByName) +/*N*/ for (i=0; i<nRowCount; i++) +/*N*/ pDestDoc->SetString( nCol, nStartRow+i, nTab, *ppRowHeaders[i] ); +/*N*/ +/*N*/ nCol = nStartCol; +/*N*/ nRow = nStartRow; +/*N*/ +/*N*/ // Daten +/*N*/ +/*N*/ if ( ppCount && ppUsed ) // Werte direkt einfuegen +/*N*/ { +/*N*/ for (nArrX=0; nArrX<nColCount; nArrX++) +/*N*/ for (nArrY=0; nArrY<nRowCount; nArrY++) +/*N*/ if (ppUsed[nArrX][nArrY]) +/*N*/ { +/*N*/ double fVal = lcl_CalcData( eFunction, ppCount[nArrX][nArrY], +/*N*/ ppSum[nArrX][nArrY], +/*N*/ ppSumSqr[nArrX][nArrY]); +/*N*/ if (ppCount[nArrX][nArrY] < 0.0) +/*N*/ pDestDoc->SetError( nCol+nArrX, nRow+nArrY, nTab, errNoValue ); +/*N*/ else +/*N*/ pDestDoc->SetValue( nCol+nArrX, nRow+nArrY, nTab, fVal ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( ppRefs && ppUsed ) // Referenzen einfuegen +/*N*/ { +/*N*/ //! unterscheiden, ob nach Kategorien aufgeteilt +/*N*/ String aString; +/*N*/ +/*N*/ SingleRefData aSRef; // Daten fuer Referenz-Formelzellen +/*N*/ aSRef.InitFlags(); +/*N*/ aSRef.SetFlag3D(TRUE); +/*N*/ +/*N*/ ComplRefData aCRef; // Daten fuer Summen-Zellen +/*N*/ aCRef.InitFlags(); +/*N*/ aCRef.Ref1.SetColRel(TRUE); aCRef.Ref1.SetRowRel(TRUE); aCRef.Ref1.SetTabRel(TRUE); +/*N*/ aCRef.Ref2.SetColRel(TRUE); aCRef.Ref2.SetRowRel(TRUE); aCRef.Ref2.SetTabRel(TRUE); +/*N*/ +/*N*/ for (nArrY=0; nArrY<nRowCount; nArrY++) +/*N*/ { +/*N*/ USHORT nNeeded = 0; +/*N*/ for (nArrX=0; nArrX<nColCount; nArrX++) +/*N*/ if (ppUsed[nArrX][nArrY]) +/*N*/ nNeeded = Max( nNeeded, ppRefs[nArrX][nArrY].GetCount() ); +/*N*/ +/*N*/ if (nNeeded) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pDestDoc->InsertRow( 0,nTab, MAXCOL,nTab, nRow+nArrY, nNeeded ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_dbcolect.cxx b/binfilter/bf_sc/source/core/tool/sc_dbcolect.cxx new file mode 100644 index 000000000000..61bed284accb --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_dbcolect.cxx @@ -0,0 +1,979 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <tools/debug.hxx> +#include <unotools/transliterationwrapper.hxx> + +#include "dbcolect.hxx" +#include "rechead.hxx" +#include "document.hxx" +#include "globstr.hrc" +namespace binfilter { + + +//--------------------------------------------------------------------------------------- + +/*N*/ ScDBData::ScDBData( const String& rName, +/*N*/ USHORT nTab, +/*N*/ USHORT nCol1, USHORT nRow1, USHORT nCol2, USHORT nRow2, +/*N*/ BOOL bByR, BOOL bHasH) : +/*N*/ aName (rName), +/*N*/ nTable (nTab), +/*N*/ nStartCol (nCol1), +/*N*/ nStartRow (nRow1), +/*N*/ nEndCol (nCol2), +/*N*/ nEndRow (nRow2), +/*N*/ bByRow (bByR), +/*N*/ bDoSize (FALSE), +/*N*/ bKeepFmt (FALSE), +/*N*/ bStripData (FALSE), +/*N*/ bHasHeader (bHasH), +/*N*/ bDBSelection(FALSE), +/*N*/ nIndex (0), +/*N*/ nExportIndex(0), +/*N*/ bIsAdvanced (FALSE), +/*N*/ bAutoFilter (FALSE), +/*N*/ bModified (FALSE) +/*N*/ { +/*N*/ USHORT i; +/*N*/ +/*N*/ ScSortParam aSortParam; +/*N*/ ScQueryParam aQueryParam; +/*N*/ ScSubTotalParam aSubTotalParam; +/*N*/ ScImportParam aImportParam; +/*N*/ +/*N*/ for (i=0; i<MAXQUERY; i++) +/*N*/ pQueryStr[i] = new String; +/*N*/ +/*N*/ for (i=0; i<MAXSUBTOTAL; i++) +/*N*/ { +/*N*/ nSubTotals[i] = 0; +/*N*/ pSubTotals[i] = NULL; +/*N*/ pFunctions[i] = NULL; +/*N*/ } +/*N*/ +/*N*/ SetSortParam( aSortParam ); +/*N*/ SetQueryParam( aQueryParam ); +/*N*/ SetSubTotalParam( aSubTotalParam ); +/*N*/ SetImportParam( aImportParam ); +/*N*/ } + +/*N*/ ScDBData::ScDBData( SvStream& rStream, ScMultipleReadHeader& rHdr ) : +/*N*/ // nicht in der Datei: +/*N*/ bAutoFilter (FALSE), +/*N*/ bModified (FALSE), +/*N*/ nExportIndex (0), +/*N*/ // nicht in alten Versionen: +/*N*/ bDoSize (FALSE), +/*N*/ bKeepFmt (FALSE), +/*N*/ bStripData (FALSE), +/*N*/ nIndex (0), +/*N*/ bIsAdvanced (FALSE), +/*N*/ bDBSelection (FALSE), +/*N*/ bDBSql (TRUE), +/*N*/ nDBType (ScDbTable), +/*N*/ nSubUserIndex (0), +/*N*/ bSortUserDef (FALSE), +/*N*/ nSortUserIndex (0) +/*N*/ { +/*N*/ rHdr.StartEntry(); +/*N*/ +/*N*/ USHORT i; +/*N*/ USHORT j; +/*N*/ BYTE nDummy; +/*N*/ rtl_TextEncoding eCharSet = rStream.GetStreamCharSet(); +/*N*/ +/*N*/ rStream.ReadByteString( aName, eCharSet ); +/*N*/ rStream >> nTable; +/*N*/ rStream >> nStartCol; +/*N*/ rStream >> nStartRow; +/*N*/ rStream >> nEndCol; +/*N*/ rStream >> nEndRow; +/*N*/ rStream >> bByRow; +/*N*/ rStream >> bHasHeader; +/*N*/ rStream >> bSortCaseSens; +/*N*/ rStream >> bIncludePattern; +/*N*/ rStream >> bSortInplace; +/*N*/ rStream >> nSortDestTab; +/*N*/ rStream >> nSortDestCol; +/*N*/ rStream >> nSortDestRow; +/*N*/ rStream >> bQueryInplace; +/*N*/ rStream >> bQueryCaseSens; +/*N*/ rStream >> bQueryRegExp; +/*N*/ rStream >> bQueryDuplicate; +/*N*/ rStream >> nQueryDestTab; +/*N*/ rStream >> nQueryDestCol; +/*N*/ rStream >> nQueryDestRow; +/*N*/ rStream >> bSubRemoveOnly; +/*N*/ rStream >> bSubReplace; +/*N*/ rStream >> bSubPagebreak; +/*N*/ rStream >> bSubCaseSens; +/*N*/ rStream >> bSubDoSort; +/*N*/ rStream >> bSubAscending; +/*N*/ rStream >> bSubIncludePattern; +/*N*/ rStream >> bSubUserDef; +/*N*/ rStream >> bDBImport; +/*N*/ +/*N*/ rStream.ReadByteString( aDBName, eCharSet ); +/*N*/ rStream.ReadByteString( aDBStatement, eCharSet ); +/*N*/ rStream >> bDBNative; +/*N*/ +/*N*/ for (i=0; i<MAXSORT; i++) +/*N*/ { +/*N*/ rStream >> bDoSort[i]; +/*N*/ rStream >> nSortField[i]; +/*N*/ rStream >> bAscending[i]; +/*N*/ } +/*N*/ for (i=0; i<MAXQUERY; i++) +/*N*/ { +/*N*/ rStream >> bDoQuery[i]; +/*N*/ rStream >> nQueryField[i]; +/*N*/ rStream >> nDummy; eQueryOp[i] = (ScQueryOp) nDummy; +/*N*/ rStream >> bQueryByString[i]; +/*N*/ pQueryStr[i] = new String; +/*N*/ rStream.ReadByteString( *pQueryStr[i], eCharSet ); +/*N*/ rStream >> nQueryVal[i]; +/*N*/ rStream >> nDummy; eQueryConnect[i] = (ScQueryConnect) nDummy; +/*N*/ } +/*N*/ for (i=0; i<MAXSUBTOTAL; i++) +/*N*/ { +/*N*/ rStream >> bDoSubTotal[i]; +/*N*/ rStream >> nSubField[i]; +/*N*/ +/*N*/ USHORT nCount; +/*N*/ rStream >> nCount; +/*N*/ nSubTotals[i] = nCount; +/*N*/ +/*N*/ pSubTotals[i] = nCount ? new USHORT [nCount] : NULL; +/*N*/ pFunctions[i] = nCount ? new ScSubTotalFunc [nCount] : NULL; +/*N*/ +/*N*/ for (j=0; j<nCount; j++) +/*N*/ { +/*N*/ rStream >> pSubTotals[i][j]; +/*N*/ rStream >> nDummy; pFunctions[i][j] = (ScSubTotalFunc)nDummy; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if (rHdr.BytesLeft()) +/*N*/ rStream >> nIndex; +/*N*/ +/*N*/ if (rHdr.BytesLeft()) +/*N*/ rStream >> bDBSelection; +/*N*/ +/*N*/ if (rHdr.BytesLeft()) +/*N*/ rStream >> bDBSql; // Default = TRUE +/*N*/ +/*N*/ if (rHdr.BytesLeft()) +/*N*/ { +/*N*/ rStream >> nSubUserIndex; +/*N*/ rStream >> bSortUserDef; +/*N*/ rStream >> nSortUserIndex; +/*N*/ } +/*N*/ +/*N*/ if (rHdr.BytesLeft()) +/*N*/ { +/*N*/ rStream >> bDoSize; +/*N*/ rStream >> bKeepFmt; +/*N*/ } +/*N*/ +/*N*/ if (rHdr.BytesLeft()) +/*N*/ rStream >> bStripData; +/*N*/ +/*N*/ if (rHdr.BytesLeft()) +/*N*/ rStream >> nDBType; // Default = ScDbTable +/*N*/ +/*N*/ if (rHdr.BytesLeft()) +/*N*/ { +/*N*/ rStream >> bIsAdvanced; // Default = FALSE +/*N*/ if (bIsAdvanced) +/*N*/ rStream >> aAdvSource; +/*N*/ } +/*N*/ +/*N*/ // aSortLocale / aSortAlgorithm are not in binary file format +/*N*/ +/*N*/ rHdr.EndEntry(); +/*N*/ +/*N*/ // #43070# rottes Dokument?!? +/*N*/ // nEndCol war 258 +/*N*/ // und auch die CellInfo pPattern in ScOutputData FindRotated waren NULL +/*N*/ if ( nStartCol > MAXCOL ) +/*N*/ { +/*N*/ DBG_ERRORFILE( "nStartCol > MAXCOL" ); +/*N*/ nStartCol = MAXCOL; +/*N*/ } +/*N*/ if ( nStartRow > MAXROW ) +/*N*/ { +/*N*/ DBG_ERRORFILE( "nStartRow > MAXROW" ); +/*N*/ nStartRow = MAXROW; +/*N*/ } +/*N*/ if ( nEndCol > MAXCOL ) +/*N*/ { +/*N*/ DBG_ERRORFILE( "nEndCol > MAXCOL" ); +/*N*/ nEndCol = MAXCOL; +/*N*/ } +/*N*/ if ( nEndRow > MAXROW ) +/*N*/ { +/*N*/ DBG_ERRORFILE( "nEndRow > MAXROW" ); +/*N*/ nEndRow = MAXROW; +/*N*/ } +/*N*/ if ( nQueryDestCol > MAXCOL ) +/*N*/ { +/*N*/ DBG_ERRORFILE( "nQueryDestCol > MAXCOL" ); +/*N*/ nQueryDestCol = MAXCOL; +/*N*/ } +/*N*/ if ( nQueryDestRow > MAXROW ) +/*N*/ { +/*N*/ DBG_ERRORFILE( "nQueryDestRow > MAXROW" ); +/*N*/ nQueryDestRow = MAXROW; +/*N*/ } +/*N*/ } + +/*N*/ BOOL ScDBData::Store( SvStream& rStream, ScMultipleWriteHeader& rHdr ) const +/*N*/ { +/*N*/ rHdr.StartEntry(); +/*N*/ +/*N*/ USHORT i; +/*N*/ USHORT j; +/*N*/ rtl_TextEncoding eCharSet = rStream.GetStreamCharSet(); +/*N*/ +/*N*/ rStream.WriteByteString( aName, eCharSet ); +/*N*/ rStream << nTable; +/*N*/ rStream << nStartCol; +/*N*/ rStream << nStartRow; +/*N*/ rStream << nEndCol; +/*N*/ rStream << nEndRow; +/*N*/ rStream << bByRow; +/*N*/ rStream << bHasHeader; +/*N*/ rStream << bSortCaseSens; +/*N*/ rStream << bIncludePattern; +/*N*/ rStream << bSortInplace; +/*N*/ rStream << nSortDestTab; +/*N*/ rStream << nSortDestCol; +/*N*/ rStream << nSortDestRow; +/*N*/ rStream << bQueryInplace; +/*N*/ rStream << bQueryCaseSens; +/*N*/ rStream << bQueryRegExp; +/*N*/ rStream << bQueryDuplicate; +/*N*/ rStream << nQueryDestTab; +/*N*/ rStream << nQueryDestCol; +/*N*/ rStream << nQueryDestRow; +/*N*/ rStream << bSubRemoveOnly; +/*N*/ rStream << bSubReplace; +/*N*/ rStream << bSubPagebreak; +/*N*/ rStream << bSubCaseSens; +/*N*/ rStream << bSubDoSort; +/*N*/ rStream << bSubAscending; +/*N*/ rStream << bSubIncludePattern; +/*N*/ rStream << bSubUserDef; +/*N*/ rStream << bDBImport; +/*N*/ +/*N*/ rStream.WriteByteString( aDBName, eCharSet ); +/*N*/ rStream.WriteByteString( aDBStatement, eCharSet ); +/*N*/ rStream << bDBNative; +/*N*/ +/*N*/ for (i=0; i<MAXSORT; i++) +/*N*/ { +/*N*/ rStream << bDoSort[i]; +/*N*/ rStream << nSortField[i]; +/*N*/ rStream << bAscending[i]; +/*N*/ } +/*N*/ for (i=0; i<MAXQUERY; i++) +/*N*/ { +/*N*/ rStream << bDoQuery[i]; +/*N*/ rStream << nQueryField[i]; +/*N*/ rStream << (BYTE) eQueryOp[i]; +/*N*/ rStream << bQueryByString[i]; +/*N*/ rStream.WriteByteString( *pQueryStr[i], eCharSet ); +/*N*/ rStream << nQueryVal[i]; +/*N*/ rStream << (BYTE) eQueryConnect[i]; +/*N*/ } +/*N*/ for (i=0; i<MAXSUBTOTAL; i++) +/*N*/ { +/*N*/ rStream << bDoSubTotal[i]; +/*N*/ rStream << nSubField[i]; +/*N*/ +/*N*/ USHORT nCount = nSubTotals[i]; +/*N*/ rStream << nCount; +/*N*/ for (j=0; j<nCount; j++) +/*N*/ { +/*N*/ rStream << pSubTotals[i][j]; +/*N*/ rStream << (BYTE)pFunctions[i][j]; +/*N*/ } +/*N*/ } +/*N*/ rStream << nIndex; // seit 24.10.95 +/*N*/ +/*N*/ rStream << bDBSelection; +/*N*/ +/*N*/ rStream << bDBSql; // seit 4.2.97 +/*N*/ +/*N*/ rStream << nSubUserIndex; // seit 5.2.97 +/*N*/ rStream << bSortUserDef; +/*N*/ rStream << nSortUserIndex; +/*N*/ +/*N*/ rStream << bDoSize; // seit 13.2.97 +/*N*/ rStream << bKeepFmt; +/*N*/ +/*N*/ rStream << bStripData; // seit 23.2.97 +/*N*/ +/*N*/ if( rStream.GetVersion() > SOFFICE_FILEFORMAT_40 ) +/*N*/ { +/*N*/ // folgendes gab's in der 4.0 noch nicht +/*N*/ +/*N*/ // alte Versionen suchen immer nach Tables und Queries +/*N*/ rStream << nDBType; // seit 20.11.97 +/*N*/ +/*N*/ // starting from 591, store advanced filter source range +/*N*/ // only if set, to avoid unneccessary warnings +/*N*/ if (bIsAdvanced) +/*N*/ { +/*?*/ rStream << (BOOL) TRUE; +/*?*/ rStream << aAdvSource; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // aSortLocale / aSortAlgorithm are not in binary file format +/*N*/ +/*N*/ rHdr.EndEntry(); +/*N*/ return TRUE; +/*N*/ } + +/*N*/ ScDBData::ScDBData( const ScDBData& rData ) : +/*N*/ ScRefreshTimer ( rData ), +/*N*/ aName (rData.aName), +/*N*/ nTable (rData.nTable), +/*N*/ nStartCol (rData.nStartCol), +/*N*/ nStartRow (rData.nStartRow), +/*N*/ nEndCol (rData.nEndCol), +/*N*/ nEndRow (rData.nEndRow), +/*N*/ bByRow (rData.bByRow), +/*N*/ bHasHeader (rData.bHasHeader), +/*N*/ bDoSize (rData.bDoSize), +/*N*/ bKeepFmt (rData.bKeepFmt), +/*N*/ bStripData (rData.bStripData), +/*N*/ bSortCaseSens (rData.bSortCaseSens), +/*N*/ bIncludePattern (rData.bIncludePattern), +/*N*/ bSortInplace (rData.bSortInplace), +/*N*/ nSortDestTab (rData.nSortDestTab), +/*N*/ nSortDestCol (rData.nSortDestCol), +/*N*/ nSortDestRow (rData.nSortDestRow), +/*N*/ bSortUserDef (rData.bSortUserDef), +/*N*/ nSortUserIndex (rData.nSortUserIndex), +/*N*/ aSortLocale (rData.aSortLocale), +/*N*/ aSortAlgorithm (rData.aSortAlgorithm), +/*N*/ bQueryInplace (rData.bQueryInplace), +/*N*/ bQueryCaseSens (rData.bQueryCaseSens), +/*N*/ bQueryRegExp (rData.bQueryRegExp), +/*N*/ bQueryDuplicate (rData.bQueryDuplicate), +/*N*/ nQueryDestTab (rData.nQueryDestTab), +/*N*/ nQueryDestCol (rData.nQueryDestCol), +/*N*/ nQueryDestRow (rData.nQueryDestRow), +/*N*/ bIsAdvanced (rData.bIsAdvanced), +/*N*/ aAdvSource (rData.aAdvSource), +/*N*/ bSubRemoveOnly (rData.bSubRemoveOnly), +/*N*/ bSubReplace (rData.bSubReplace), +/*N*/ bSubPagebreak (rData.bSubPagebreak), +/*N*/ bSubCaseSens (rData.bSubCaseSens), +/*N*/ bSubDoSort (rData.bSubDoSort), +/*N*/ bSubAscending (rData.bSubAscending), +/*N*/ bSubIncludePattern (rData.bSubIncludePattern), +/*N*/ bSubUserDef (rData.bSubUserDef), +/*N*/ nSubUserIndex (rData.nSubUserIndex), +/*N*/ bDBImport (rData.bDBImport), +/*N*/ aDBName (rData.aDBName), +/*N*/ aDBStatement (rData.aDBStatement), +/*N*/ bDBNative (rData.bDBNative), +/*N*/ bDBSelection (rData.bDBSelection), +/*N*/ bDBSql (rData.bDBSql), +/*N*/ nDBType (rData.nDBType), +/*N*/ nIndex (rData.nIndex), +/*N*/ nExportIndex (rData.nExportIndex), +/*N*/ bAutoFilter (rData.bAutoFilter), +/*N*/ bModified (rData.bModified) +/*N*/ { +/*N*/ USHORT i; +/*N*/ USHORT j; +/*N*/ +/*N*/ for (i=0; i<MAXSORT; i++) +/*N*/ { +/*N*/ bDoSort[i] = rData.bDoSort[i]; +/*N*/ nSortField[i] = rData.nSortField[i]; +/*N*/ bAscending[i] = rData.bAscending[i]; +/*N*/ } +/*N*/ for (i=0; i<MAXQUERY; i++) +/*N*/ { +/*N*/ bDoQuery[i] = rData.bDoQuery[i]; +/*N*/ nQueryField[i] = rData.nQueryField[i]; +/*N*/ eQueryOp[i] = rData.eQueryOp[i]; +/*N*/ bQueryByString[i] = rData.bQueryByString[i]; +/*N*/ pQueryStr[i] = new String( *(rData.pQueryStr[i]) ); +/*N*/ nQueryVal[i] = rData.nQueryVal[i]; +/*N*/ eQueryConnect[i] = rData.eQueryConnect[i]; +/*N*/ } +/*N*/ for (i=0; i<MAXSUBTOTAL; i++) +/*N*/ { +/*N*/ bDoSubTotal[i] = rData.bDoSubTotal[i]; +/*N*/ nSubField[i] = rData.nSubField[i]; +/*N*/ +/*N*/ USHORT nCount = rData.nSubTotals[i]; +/*N*/ nSubTotals[i] = nCount; +/*N*/ pFunctions[i] = nCount ? new ScSubTotalFunc [nCount] : NULL; +/*N*/ pSubTotals[i] = nCount ? new USHORT [nCount] : NULL; +/*N*/ +/*N*/ for (j=0; j<nCount; j++) +/*N*/ { +/*N*/ pSubTotals[i][j] = rData.pSubTotals[i][j]; +/*N*/ pFunctions[i][j] = rData.pFunctions[i][j]; +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ ScDBData& ScDBData::operator= (const ScDBData& rData) +/*N*/ { +/*N*/ USHORT i; +/*N*/ USHORT j; +/*N*/ +/*N*/ ScRefreshTimer::operator=( rData ); +/*N*/ aName = rData.aName; +/*N*/ nTable = rData.nTable; +/*N*/ nStartCol = rData.nStartCol; +/*N*/ nStartRow = rData.nStartRow; +/*N*/ nEndCol = rData.nEndCol; +/*N*/ nEndRow = rData.nEndRow; +/*N*/ bByRow = rData.bByRow; +/*N*/ bHasHeader = rData.bHasHeader; +/*N*/ bDoSize = rData.bDoSize; +/*N*/ bKeepFmt = rData.bKeepFmt; +/*N*/ bStripData = rData.bStripData; +/*N*/ bSortCaseSens = rData.bSortCaseSens; +/*N*/ bIncludePattern = rData.bIncludePattern; +/*N*/ bSortInplace = rData.bSortInplace; +/*N*/ nSortDestTab = rData.nSortDestTab; +/*N*/ nSortDestCol = rData.nSortDestCol; +/*N*/ nSortDestRow = rData.nSortDestRow; +/*N*/ bSortUserDef = rData.bSortUserDef; +/*N*/ nSortUserIndex = rData.nSortUserIndex; +/*N*/ aSortLocale = rData.aSortLocale; +/*N*/ aSortAlgorithm = rData.aSortAlgorithm; +/*N*/ bQueryInplace = rData.bQueryInplace; +/*N*/ bQueryCaseSens = rData.bQueryCaseSens; +/*N*/ bQueryRegExp = rData.bQueryRegExp; +/*N*/ bQueryDuplicate = rData.bQueryDuplicate; +/*N*/ nQueryDestTab = rData.nQueryDestTab; +/*N*/ nQueryDestCol = rData.nQueryDestCol; +/*N*/ nQueryDestRow = rData.nQueryDestRow; +/*N*/ bIsAdvanced = rData.bIsAdvanced; +/*N*/ aAdvSource = rData.aAdvSource; +/*N*/ bSubRemoveOnly = rData.bSubRemoveOnly; +/*N*/ bSubReplace = rData.bSubReplace; +/*N*/ bSubPagebreak = rData.bSubPagebreak; +/*N*/ bSubCaseSens = rData.bSubCaseSens; +/*N*/ bSubDoSort = rData.bSubDoSort; +/*N*/ bSubAscending = rData.bSubAscending; +/*N*/ bSubIncludePattern = rData.bSubIncludePattern; +/*N*/ bSubUserDef = rData.bSubUserDef; +/*N*/ nSubUserIndex = rData.nSubUserIndex; +/*N*/ bDBImport = rData.bDBImport; +/*N*/ aDBName = rData.aDBName; +/*N*/ aDBStatement = rData.aDBStatement; +/*N*/ bDBNative = rData.bDBNative; +/*N*/ bDBSelection = rData.bDBSelection; +/*N*/ bDBSql = rData.bDBSql; +/*N*/ nDBType = rData.nDBType; +/*N*/ nIndex = rData.nIndex; +/*N*/ nExportIndex = rData.nExportIndex; +/*N*/ bAutoFilter = rData.bAutoFilter; +/*N*/ +/*N*/ for (i=0; i<MAXSORT; i++) +/*N*/ { +/*N*/ bDoSort[i] = rData.bDoSort[i]; +/*N*/ nSortField[i] = rData.nSortField[i]; +/*N*/ bAscending[i] = rData.bAscending[i]; +/*N*/ } +/*N*/ for (i=0; i<MAXQUERY; i++) +/*N*/ { +/*N*/ bDoQuery[i] = rData.bDoQuery[i]; +/*N*/ nQueryField[i] = rData.nQueryField[i]; +/*N*/ eQueryOp[i] = rData.eQueryOp[i]; +/*N*/ bQueryByString[i] = rData.bQueryByString[i]; +/*N*/ *pQueryStr[i] = *rData.pQueryStr[i]; +/*N*/ nQueryVal[i] = rData.nQueryVal[i]; +/*N*/ eQueryConnect[i] = rData.eQueryConnect[i]; +/*N*/ } +/*N*/ for (i=0; i<MAXSUBTOTAL; i++) +/*N*/ { +/*N*/ bDoSubTotal[i] = rData.bDoSubTotal[i]; +/*N*/ nSubField[i] = rData.nSubField[i]; +/*N*/ USHORT nCount = rData.nSubTotals[i]; +/*N*/ nSubTotals[i] = nCount; +/*N*/ +/*N*/ delete[] pSubTotals[i]; +/*N*/ delete[] pFunctions[i]; +/*N*/ +/*N*/ pSubTotals[i] = nCount ? new USHORT [nCount] : NULL; +/*N*/ pFunctions[i] = nCount ? new ScSubTotalFunc [nCount] : NULL; +/*N*/ for (j=0; j<nCount; j++) +/*N*/ { +/*N*/ pSubTotals[i][j] = rData.pSubTotals[i][j]; +/*N*/ pFunctions[i][j] = rData.pFunctions[i][j]; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ return *this; +/*N*/ } + + +/*N*/ ScDBData::~ScDBData() +/*N*/ { +/*N*/ StopRefreshTimer(); +/*N*/ USHORT i; +/*N*/ +/*N*/ for (i=0; i<MAXQUERY; i++) +/*N*/ delete pQueryStr[i]; +/*N*/ for (i=0; i<MAXSUBTOTAL; i++) +/*N*/ { +/*N*/ delete[] pSubTotals[i]; +/*N*/ delete[] pFunctions[i]; +/*N*/ } +/*N*/ } + +/*N*/ BOOL ScDBData::IsBeyond(USHORT nMaxRow) const +/*N*/ { +/*N*/ return ( nStartRow > nMaxRow || +/*N*/ nEndRow > nMaxRow || +/*N*/ nQueryDestRow > nMaxRow ); +/*N*/ } + + + +/*N*/ void ScDBData::GetArea(USHORT& rTab, USHORT& rCol1, USHORT& rRow1, USHORT& rCol2, USHORT& rRow2) const +/*N*/ { +/*N*/ rTab = nTable; +/*N*/ rCol1 = nStartCol; +/*N*/ rRow1 = nStartRow; +/*N*/ rCol2 = nEndCol; +/*N*/ rRow2 = nEndRow; +/*N*/ } + +/*N*/ void ScDBData::GetArea(ScRange& rRange) const +/*N*/ { +/*N*/ rRange = ScRange( nStartCol,nStartRow,nTable, nEndCol,nEndRow,nTable ); +/*N*/ } + +/*N*/ void ScDBData::SetArea(USHORT nTab, USHORT nCol1, USHORT nRow1, USHORT nCol2, USHORT nRow2) +/*N*/ { +/*N*/ nTable = nTab; +/*N*/ nStartCol = nCol1; +/*N*/ nStartRow = nRow1; +/*N*/ nEndCol = nCol2; +/*N*/ nEndRow = nRow2; +/*N*/ } + + +/*N*/ void ScDBData::GetSortParam( ScSortParam& rSortParam ) const +/*N*/ { +/*N*/ rSortParam.nCol1 = nStartCol; +/*N*/ rSortParam.nRow1 = nStartRow; +/*N*/ rSortParam.nCol2 = nEndCol; +/*N*/ rSortParam.nRow2 = nEndRow; +/*N*/ rSortParam.bByRow = bByRow; +/*N*/ rSortParam.bHasHeader = bHasHeader; +/*N*/ rSortParam.bCaseSens = bSortCaseSens; +/*N*/ rSortParam.bInplace = bSortInplace; +/*N*/ rSortParam.nDestTab = nSortDestTab; +/*N*/ rSortParam.nDestCol = nSortDestCol; +/*N*/ rSortParam.nDestRow = nSortDestRow; +/*N*/ rSortParam.bIncludePattern = bIncludePattern; +/*N*/ rSortParam.bUserDef = bSortUserDef; +/*N*/ rSortParam.nUserIndex = nSortUserIndex; +/*N*/ for (USHORT i=0; i<MAXSORT; i++) +/*N*/ { +/*N*/ rSortParam.bDoSort[i] = bDoSort[i]; +/*N*/ rSortParam.nField[i] = nSortField[i]; +/*N*/ rSortParam.bAscending[i] = bAscending[i]; +/*N*/ } +/*N*/ rSortParam.aCollatorLocale = aSortLocale; +/*N*/ rSortParam.aCollatorAlgorithm = aSortAlgorithm; +/*N*/ } + +/*N*/ void ScDBData::SetSortParam( const ScSortParam& rSortParam ) +/*N*/ { +/*N*/ bSortCaseSens = rSortParam.bCaseSens; +/*N*/ bIncludePattern = rSortParam.bIncludePattern; +/*N*/ bSortInplace = rSortParam.bInplace; +/*N*/ nSortDestTab = rSortParam.nDestTab; +/*N*/ nSortDestCol = rSortParam.nDestCol; +/*N*/ nSortDestRow = rSortParam.nDestRow; +/*N*/ bSortUserDef = rSortParam.bUserDef; +/*N*/ nSortUserIndex = rSortParam.nUserIndex; +/*N*/ for (USHORT i=0; i<MAXSORT; i++) +/*N*/ { +/*N*/ bDoSort[i] = rSortParam.bDoSort[i]; +/*N*/ nSortField[i] = rSortParam.nField[i]; +/*N*/ bAscending[i] = rSortParam.bAscending[i]; +/*N*/ } +/*N*/ aSortLocale = rSortParam.aCollatorLocale; +/*N*/ aSortAlgorithm = rSortParam.aCollatorAlgorithm; +/*N*/ +/*N*/ //#98317#; set the orientation +/*N*/ bByRow = rSortParam.bByRow; +/*N*/ } + +/*N*/ void ScDBData::GetQueryParam( ScQueryParam& rQueryParam ) const +/*N*/ { +/*N*/ rQueryParam.nCol1 = nStartCol; +/*N*/ rQueryParam.nRow1 = nStartRow; +/*N*/ rQueryParam.nCol2 = nEndCol; +/*N*/ rQueryParam.nRow2 = nEndRow; +/*N*/ rQueryParam.nTab = nTable; +/*N*/ rQueryParam.bByRow = bByRow; +/*N*/ rQueryParam.bHasHeader = bHasHeader; +/*N*/ rQueryParam.bInplace = bQueryInplace; +/*N*/ rQueryParam.bCaseSens = bQueryCaseSens; +/*N*/ rQueryParam.bRegExp = bQueryRegExp; +/*N*/ rQueryParam.bDuplicate = bQueryDuplicate; +/*N*/ rQueryParam.nDestTab = nQueryDestTab; +/*N*/ rQueryParam.nDestCol = nQueryDestCol; +/*N*/ rQueryParam.nDestRow = nQueryDestRow; +/*N*/ +/*N*/ rQueryParam.Resize( MAXQUERY ); +/*N*/ for (USHORT i=0; i<MAXQUERY; i++) +/*N*/ { +/*N*/ ScQueryEntry& rEntry = rQueryParam.GetEntry(i); +/*N*/ +/*N*/ rEntry.bDoQuery = bDoQuery[i]; +/*N*/ rEntry.nField = nQueryField[i]; +/*N*/ rEntry.eOp = eQueryOp[i]; +/*N*/ rEntry.bQueryByString = bQueryByString[i]; +/*N*/ *rEntry.pStr = *pQueryStr[i]; +/*N*/ rEntry.nVal = nQueryVal[i]; +/*N*/ rEntry.eConnect = eQueryConnect[i]; +/*N*/ } +/*N*/ } + +/*N*/ void ScDBData::SetQueryParam(const ScQueryParam& rQueryParam) +/*N*/ { +/*N*/ DBG_ASSERT( rQueryParam.GetEntryCount() <= MAXQUERY || +/*N*/ !rQueryParam.GetEntry(MAXQUERY).bDoQuery, +/*N*/ "zuviele Eintraege bei ScDBData::SetQueryParam" ); +/*N*/ +/*N*/ // set bIsAdvanced to FALSE for everything that is not from the +/*N*/ // advanced filter dialog +/*N*/ bIsAdvanced = FALSE; +/*N*/ +/*N*/ bQueryInplace = rQueryParam.bInplace; +/*N*/ bQueryCaseSens = rQueryParam.bCaseSens; +/*N*/ bQueryRegExp = rQueryParam.bRegExp; +/*N*/ bQueryDuplicate = rQueryParam.bDuplicate; +/*N*/ nQueryDestTab = rQueryParam.nDestTab; +/*N*/ nQueryDestCol = rQueryParam.nDestCol; +/*N*/ nQueryDestRow = rQueryParam.nDestRow; +/*N*/ for (USHORT i=0; i<MAXQUERY; i++) +/*N*/ { +/*N*/ ScQueryEntry& rEntry = rQueryParam.GetEntry(i); +/*N*/ +/*N*/ bDoQuery[i] = rEntry.bDoQuery; +/*N*/ nQueryField[i] = rEntry.nField; +/*N*/ eQueryOp[i] = rEntry.eOp; +/*N*/ bQueryByString[i] = rEntry.bQueryByString; +/*N*/ *pQueryStr[i] = *rEntry.pStr; +/*N*/ nQueryVal[i] = rEntry.nVal; +/*N*/ eQueryConnect[i] = rEntry.eConnect; +/*N*/ } +/*N*/ } + +/*N*/ void ScDBData::SetAdvancedQuerySource(const ScRange* pSource) +/*N*/ { +/*N*/ if (pSource) +/*N*/ { +/*N*/ aAdvSource = *pSource; +/*N*/ bIsAdvanced = TRUE; +/*N*/ } +/*N*/ else +/*N*/ bIsAdvanced = FALSE; +/*N*/ } + +/*N*/ BOOL ScDBData::GetAdvancedQuerySource(ScRange& rSource) const +/*N*/ { +/*N*/ rSource = aAdvSource; +/*N*/ return bIsAdvanced; +/*N*/ } + +/*N*/ void ScDBData::GetSubTotalParam(ScSubTotalParam& rSubTotalParam) const +/*N*/ { +/*N*/ USHORT i; +/*N*/ USHORT j; +/*N*/ +/*N*/ rSubTotalParam.nCol1 = nStartCol; +/*N*/ rSubTotalParam.nRow1 = nStartRow; +/*N*/ rSubTotalParam.nCol2 = nEndCol; +/*N*/ rSubTotalParam.nRow2 = nEndRow; +/*N*/ +/*N*/ rSubTotalParam.bRemoveOnly = bSubRemoveOnly; +/*N*/ rSubTotalParam.bReplace = bSubReplace; +/*N*/ rSubTotalParam.bPagebreak = bSubPagebreak; +/*N*/ rSubTotalParam.bCaseSens = bSubCaseSens; +/*N*/ rSubTotalParam.bDoSort = bSubDoSort; +/*N*/ rSubTotalParam.bAscending = bSubAscending; +/*N*/ rSubTotalParam.bIncludePattern = bSubIncludePattern; +/*N*/ rSubTotalParam.bUserDef = bSubUserDef; +/*N*/ rSubTotalParam.nUserIndex = nSubUserIndex; +/*N*/ +/*N*/ for (i=0; i<MAXSUBTOTAL; i++) +/*N*/ { +/*N*/ rSubTotalParam.bGroupActive[i] = bDoSubTotal[i]; +/*N*/ rSubTotalParam.nField[i] = nSubField[i]; +/*N*/ USHORT nCount = nSubTotals[i]; +/*N*/ +/*N*/ rSubTotalParam.nSubTotals[i] = nCount; +/*N*/ delete[] rSubTotalParam.pSubTotals[i]; +/*N*/ delete[] rSubTotalParam.pFunctions[i]; +/*N*/ rSubTotalParam.pSubTotals[i] = nCount ? new USHORT[nCount] : NULL; +/*N*/ rSubTotalParam.pFunctions[i] = nCount ? new ScSubTotalFunc[nCount] +/*N*/ : NULL; +/*N*/ for (j=0; j<nCount; j++) +/*N*/ { +/*N*/ rSubTotalParam.pSubTotals[i][j] = pSubTotals[i][j]; +/*N*/ rSubTotalParam.pFunctions[i][j] = pFunctions[i][j]; +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void ScDBData::SetSubTotalParam(const ScSubTotalParam& rSubTotalParam) +/*N*/ { +/*N*/ USHORT i; +/*N*/ USHORT j; +/*N*/ +/*N*/ bSubRemoveOnly = rSubTotalParam.bRemoveOnly; +/*N*/ bSubReplace = rSubTotalParam.bReplace; +/*N*/ bSubPagebreak = rSubTotalParam.bPagebreak; +/*N*/ bSubCaseSens = rSubTotalParam.bCaseSens; +/*N*/ bSubDoSort = rSubTotalParam.bDoSort; +/*N*/ bSubAscending = rSubTotalParam.bAscending; +/*N*/ bSubIncludePattern = rSubTotalParam.bIncludePattern; +/*N*/ bSubUserDef = rSubTotalParam.bUserDef; +/*N*/ nSubUserIndex = rSubTotalParam.nUserIndex; +/*N*/ +/*N*/ for (i=0; i<MAXSUBTOTAL; i++) +/*N*/ { +/*N*/ bDoSubTotal[i] = rSubTotalParam.bGroupActive[i]; +/*N*/ nSubField[i] = rSubTotalParam.nField[i]; +/*N*/ USHORT nCount = rSubTotalParam.nSubTotals[i]; +/*N*/ +/*N*/ nSubTotals[i] = nCount; +/*N*/ delete[] pSubTotals[i]; +/*N*/ delete[] pFunctions[i]; +/*N*/ pSubTotals[i] = nCount ? new USHORT [nCount] : NULL; +/*N*/ pFunctions[i] = nCount ? new ScSubTotalFunc [nCount] : NULL; +/*N*/ for (j=0; j<nCount; j++) +/*N*/ { +/*N*/ pSubTotals[i][j] = rSubTotalParam.pSubTotals[i][j]; +/*N*/ pFunctions[i][j] = rSubTotalParam.pFunctions[i][j]; +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void ScDBData::GetImportParam(ScImportParam& rImportParam) const +/*N*/ { +/*N*/ rImportParam.nCol1 = nStartCol; +/*N*/ rImportParam.nRow1 = nStartRow; +/*N*/ rImportParam.nCol2 = nEndCol; +/*N*/ rImportParam.nRow2 = nEndRow; +/*N*/ +/*N*/ rImportParam.bImport = bDBImport; +/*N*/ rImportParam.aDBName = aDBName; +/*N*/ rImportParam.aStatement = aDBStatement; +/*N*/ rImportParam.bNative = bDBNative; +/*N*/ rImportParam.bSql = bDBSql; +/*N*/ rImportParam.nType = nDBType; +/*N*/ } + +/*N*/ void ScDBData::SetImportParam(const ScImportParam& rImportParam) +/*N*/ { +/*N*/ bDBImport = rImportParam.bImport; +/*N*/ aDBName = rImportParam.aDBName; +/*N*/ aDBStatement = rImportParam.aStatement; +/*N*/ bDBNative = rImportParam.bNative; +/*N*/ bDBSql = rImportParam.bSql; +/*N*/ nDBType = rImportParam.nType; +/*N*/ } + + + + +/*N*/ DataObject* ScDBData::Clone() const +/*N*/ { +/*N*/ return new ScDBData(*this); +/*N*/ } + + +//--------------------------------------------------------------------------------------- +// Compare zum Sortieren + +/*N*/ short ScDBCollection::Compare(DataObject* pKey1, DataObject* pKey2) const +/*N*/ { +/*N*/ const String& rStr1 = ((ScDBData*)pKey1)->GetName(); +/*N*/ const String& rStr2 = ((ScDBData*)pKey2)->GetName(); +/*N*/ return (short) ScGlobal::pTransliteration->compareString( rStr1, rStr2 ); +/*N*/ } + +// IsEqual - alles gleich + + +/*N*/ ScDBData* ScDBCollection::GetDBAtCursor(USHORT nCol, USHORT nRow, USHORT nTab, BOOL bStartOnly) const +/*N*/ { +/*N*/ ScDBData* pNoNameData = NULL; +/*N*/ if (pItems) +/*N*/ { +/*N*/ const String& rNoName = ScGlobal::GetRscString( STR_DB_NONAME ); +/*N*/ +/*N*/ for (USHORT i = 0; i < nCount; i++) +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 if (((ScDBData*)pItems[i])->IsDBAtCursor(nCol, nRow, nTab, bStartOnly)) +/*N*/ } +/*N*/ return pNoNameData; // "unbenannt" nur zurueck, wenn sonst nichts gefunden +/*N*/ } + +/*N*/ ScDBData* ScDBCollection::GetDBAtArea(USHORT nTab, USHORT nCol1, USHORT nRow1, USHORT nCol2, USHORT nRow2) const +/*N*/ { +/*N*/ ScDBData* pNoNameData = NULL; +/*N*/ if (pItems) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 const String& rNoName = ScGlobal::GetRscString( STR_DB_NONAME ); +/*N*/ } +/*N*/ return pNoNameData; // "unbenannt" nur zurueck, wenn sonst nichts gefunden +/*N*/ } + +/*N*/ BOOL ScDBCollection::SearchName( const String& rName, USHORT& rIndex ) const +/*N*/ { +/*N*/ ScDBData aDataObj( rName, 0,0,0,0,0 ); +/*N*/ return Search( &aDataObj, rIndex ); +/*N*/ } + +/*N*/ BOOL ScDBCollection::Load( SvStream& rStream ) +/*N*/ { +/*N*/ BOOL bSuccess = TRUE; +/*N*/ USHORT nNewCount; +/*N*/ +/*N*/ while( nCount > 0 ) +/*?*/ AtFree(0); // alles loeschen +/*N*/ +/*N*/ ScMultipleReadHeader aHdr( rStream ); +/*N*/ +/*N*/ rStream >> nNewCount; +/*N*/ for (USHORT i=0; i<nNewCount && bSuccess; i++) +/*N*/ { +/*N*/ ScDBData* pData = new ScDBData( rStream, aHdr ); +/*N*/ Insert( pData ); +/*N*/ } +/*N*/ if (aHdr.BytesLeft()) // ... Erweiterungen +/*N*/ rStream >> nEntryIndex; +/*N*/ return bSuccess; +/*N*/ } + +/*N*/ BOOL ScDBCollection::Store( SvStream& rStream ) const +/*N*/ { +/*N*/ ScMultipleWriteHeader aHdr( rStream ); +/*N*/ +/*N*/ USHORT i; +/*N*/ USHORT nSaveCount = nCount; +/*N*/ USHORT nSaveMaxRow = pDoc->GetSrcMaxRow(); +/*N*/ if ( nSaveMaxRow < MAXROW ) +/*N*/ { +/*N*/ nSaveCount = 0; +/*N*/ for (i=0; i<nCount; i++) +/*N*/ if ( !((const ScDBData*)At(i))->IsBeyond(nSaveMaxRow) ) +/*N*/ ++nSaveCount; +/*N*/ +/*N*/ if ( nSaveCount < nCount ) +/*N*/ pDoc->SetLostData(); // Warnung ausgeben +/*N*/ } +/*N*/ +/*N*/ rStream << nSaveCount; +/*N*/ +/*N*/ BOOL bSuccess = TRUE; +/*N*/ for (i=0; i<nCount && bSuccess; i++) +/*N*/ { +/*N*/ const ScDBData* pDBData = (const ScDBData*)At(i); +/*N*/ if ( nSaveMaxRow == MAXROW || !pDBData->IsBeyond(nSaveMaxRow) ) +/*N*/ bSuccess = pDBData->Store( rStream, aHdr ); +/*N*/ } +/*N*/ +/*N*/ rStream << nEntryIndex; // seit 24.10.95 +/*N*/ +/*N*/ return bSuccess; +/*N*/ } + +/*N*/ void ScDBCollection::UpdateReference(UpdateRefMode eUpdateRefMode, +/*N*/ USHORT nCol1, USHORT nRow1, USHORT nTab1, +/*N*/ USHORT nCol2, USHORT nRow2, USHORT nTab2, +/*N*/ short nDx, short nDy, short nDz ) +/*N*/ { +/*N*/ for (USHORT i=0; i<nCount; i++) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 USHORT theCol1; +/*N*/ } +/*N*/ } + + + + +/*N*/ ScDBData* ScDBCollection::FindIndex(USHORT nIndex) +/*N*/ { +/*N*/ USHORT i = 0; +/*N*/ while (i < nCount) +/*N*/ { +/*N*/ if ((*this)[i]->GetIndex() == nIndex) +/*N*/ return (*this)[i]; +/*N*/ i++; +/*N*/ } +/*N*/ return NULL; +/*N*/ } + +/*N*/ BOOL ScDBCollection::Insert(DataObject* pDataObject) +/*N*/ { +/*N*/ ScDBData* pData = (ScDBData*) pDataObject; +/*N*/ if (!pData->GetIndex()) // schon gesetzt? +/*N*/ pData->SetIndex(nEntryIndex++); +/*N*/ BOOL bInserted = SortedCollection::Insert(pDataObject); +/*N*/ if ( bInserted && pData->HasImportParam() && !pData->HasImportSelection() ) +/*N*/ { +/*?*/ pData->SetRefreshHandler( GetRefreshHandler() ); +/*?*/ pData->SetRefreshControl( pDoc->GetRefreshTimerControlAddress() ); +/*N*/ } +/*N*/ return bInserted; +/*N*/ } + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_ddelink.cxx b/binfilter/bf_sc/source/core/tool/sc_ddelink.cxx new file mode 100644 index 000000000000..808bc4b91396 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_ddelink.cxx @@ -0,0 +1,154 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// INCLUDE --------------------------------------------------------------- + +#include <bf_svtools/zforlist.hxx> + +#include "ddelink.hxx" +#include "document.hxx" +#include "scmatrix.hxx" +#include "rechead.hxx" +#include "bf_sc.hrc" +#include "hints.hxx" +namespace binfilter { + +/*N*/ TYPEINIT2(ScDdeLink,::binfilter::SvBaseLink,SfxBroadcaster); + +#ifdef PM2 +#define DDE_TXT_ENCODING RTL_TEXTENCODING_IBM_850 +#else +#define DDE_TXT_ENCODING RTL_TEXTENCODING_MS_1252 +#endif + +/*N*/ BOOL ScDdeLink::bIsInUpdate = FALSE; + +//------------------------------------------------------------------------ + +/*N*/ ScDdeLink::ScDdeLink( ScDocument* pD, const String& rA, const String& rT, const String& rI, +/*N*/ BYTE nM ) : +/*N*/ ::binfilter::SvBaseLink(::binfilter::LINKUPDATE_ALWAYS,FORMAT_STRING), +/*N*/ pDoc( pD ), +/*N*/ aAppl( rA ), +/*N*/ aTopic( rT ), +/*N*/ aItem( rI ), +/*N*/ nMode( nM ), +/*N*/ pResult( NULL ), +/*N*/ bNeedUpdate( FALSE ) +/*N*/ { +/*N*/ } + +/*N*/ __EXPORT ScDdeLink::~ScDdeLink() +/*N*/ { +/*N*/ // Verbindung aufheben +/*N*/ +/*N*/ delete pResult; +/*N*/ } + +/*N*/ ScDdeLink::ScDdeLink( ScDocument* pD, SvStream& rStream, ScMultipleReadHeader& rHdr ) : +/*N*/ ::binfilter::SvBaseLink(::binfilter::LINKUPDATE_ALWAYS,FORMAT_STRING), +/*N*/ pDoc( pD ), +/*N*/ pResult( NULL ), +/*N*/ bNeedUpdate( FALSE ) +/*N*/ { +/*N*/ rHdr.StartEntry(); +/*N*/ +/*N*/ rtl_TextEncoding eCharSet = rStream.GetStreamCharSet(); +/*N*/ rStream.ReadByteString( aAppl, eCharSet ); +/*N*/ rStream.ReadByteString( aTopic, eCharSet ); +/*N*/ rStream.ReadByteString( aItem, eCharSet ); +/*N*/ +/*N*/ BOOL bHasValue; +/*N*/ rStream >> bHasValue; +/*N*/ if ( bHasValue ) +/*N*/ pResult = new ScMatrix( rStream ); +/*N*/ +/*N*/ if (rHdr.BytesLeft()) // neu in 388b und der 364w (RealTime-Client) Version +/*N*/ rStream >> nMode; +/*N*/ else +/*N*/ nMode = SC_DDE_DEFAULT; +/*N*/ +/*N*/ rHdr.EndEntry(); +/*N*/ } + +/*N*/ void ScDdeLink::Store( SvStream& rStream, ScMultipleWriteHeader& rHdr ) const +/*N*/ { +/*N*/ rHdr.StartEntry(); +/*N*/ +/*N*/ rtl_TextEncoding eCharSet = rStream.GetStreamCharSet(); +/*N*/ rStream.WriteByteString( aAppl, eCharSet ); +/*N*/ rStream.WriteByteString( aTopic, eCharSet ); +/*N*/ rStream.WriteByteString( aItem, eCharSet ); +/*N*/ +/*N*/ BOOL bHasValue = ( pResult != NULL ); +/*N*/ rStream << bHasValue; +/*N*/ if (bHasValue) +/*N*/ pResult->Store( rStream ); +/*N*/ +/*N*/ if( rStream.GetVersion() > SOFFICE_FILEFORMAT_40 ) // nicht bei 4.0 Export +/*N*/ rStream << nMode; // seit 388b +/*N*/ +/*N*/ // Links mit Mode != SC_DDE_DEFAULT werden bei 4.0 Export komplett weggelassen +/*N*/ // (aus ScDocument::SaveDdeLinks) +/*N*/ +/*N*/ rHdr.EndEntry(); +/*N*/ } + +/*N*/ void __EXPORT ScDdeLink::DataChanged( const String& rMimeType, +/*N*/ const ::com::sun::star::uno::Any & rValue ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 // wir koennen nur Strings... +/*N*/ } + + + + +/*N*/ void ScDdeLink::TryUpdate() +/*N*/ { +/*N*/ if (bIsInUpdate) +/*N*/ bNeedUpdate = TRUE; // kann jetzt nicht ausgefuehrt werden +/*N*/ else +/*N*/ { +/*N*/ bIsInUpdate = TRUE; +/*N*/ //Application::Reschedule(); //! OS/2-Simulation +/*N*/ pDoc->IncInDdeLinkUpdate(); +/*N*/ Update(); +/*N*/ pDoc->DecInDdeLinkUpdate(); +/*N*/ bIsInUpdate = FALSE; +/*N*/ bNeedUpdate = FALSE; +/*N*/ } +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_detdata.cxx b/binfilter/bf_sc/source/core/tool/sc_detdata.cxx new file mode 100644 index 000000000000..b0fd6efb2983 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_detdata.cxx @@ -0,0 +1,142 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// INCLUDE --------------------------------------------------------------- + +#include <tools/debug.hxx> + +#include "detdata.hxx" +#include "refupdat.hxx" +#include "rechead.hxx" +namespace binfilter { + +//------------------------------------------------------------------------ + +/*N*/ SV_IMPL_PTRARR( ScDetOpArr_Impl, ScDetOpDataPtr ); + +//------------------------------------------------------------------------ + +/*N*/ ScDetOpList::ScDetOpList(const ScDetOpList& rList) : +/*N*/ bHasAddError( FALSE ) +/*N*/ { +/*N*/ USHORT nCount = rList.Count(); +/*N*/ +/*N*/ for (USHORT i=0; i<nCount; i++) +/*N*/ Append( new ScDetOpData(*rList[i]) ); +/*N*/ } + +/*N*/ void ScDetOpList::UpdateReference( ScDocument* pDoc, UpdateRefMode eUpdateRefMode, +/*N*/ const ScRange& rRange, short nDx, short nDy, short nDz ) +/*N*/ { +/*N*/ USHORT nCount = Count(); +/*N*/ for (USHORT i=0; i<nCount; i++) +/*N*/ { +/*N*/ ScAddress aPos = (*this)[i]->GetPos(); +/*N*/ USHORT nCol1 = aPos.Col(); +/*N*/ USHORT nRow1 = aPos.Row(); +/*N*/ USHORT nTab1 = aPos.Tab(); +/*N*/ USHORT nCol2 = nCol1; +/*N*/ USHORT nRow2 = nRow1; +/*N*/ USHORT nTab2 = nTab1; +/*N*/ +/*N*/ ScRefUpdateRes eRes = +/*N*/ ScRefUpdate::Update( pDoc, eUpdateRefMode, +/*N*/ rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(), +/*N*/ rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(), nDx, nDy, nDz, +/*N*/ nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); +/*N*/ if ( eRes != UR_NOTHING ) +/*N*/ (*this)[i]->SetPos( ScAddress( nCol1, nRow1, nTab1 ) ); +/*N*/ } +/*N*/ } + +/*N*/ void ScDetOpList::Append( ScDetOpData* pData ) +/*N*/ { +/*N*/ if ( pData->GetOperation() == SCDETOP_ADDERROR ) +/*N*/ bHasAddError = TRUE; +/*N*/ +/*N*/ Insert( pData, Count() ); +/*N*/ } + + + +/*N*/ void ScDetOpList::Load( SvStream& rStream ) +/*N*/ { +/*N*/ ScMultipleReadHeader aHdr( rStream ); +/*N*/ +/*N*/ USHORT nNewCount; +/*N*/ rStream >> nNewCount; +/*N*/ +/*N*/ ScAddress aPos; +/*N*/ USHORT nOper; +/*N*/ +/*N*/ for (USHORT i=0; i<nNewCount; i++) +/*N*/ { +/*N*/ // 1) Position (ScAddress) +/*N*/ // 2) Operation (USHORT) +/*N*/ +/*N*/ aHdr.StartEntry(); +/*N*/ +/*N*/ rStream >> aPos; +/*N*/ rStream >> nOper; +/*N*/ Append( new ScDetOpData( aPos, (ScDetOpType) nOper ) ); +/*N*/ +/*N*/ aHdr.EndEntry(); +/*N*/ } +/*N*/ } + +/*N*/ void ScDetOpList::Store( SvStream& rStream ) const +/*N*/ { +/*N*/ ScMultipleWriteHeader aHdr( rStream ); +/*N*/ +/*N*/ USHORT nCount = Count(); +/*N*/ rStream << nCount; +/*N*/ +/*N*/ for (USHORT i=0; i<nCount; i++) +/*N*/ { +/*N*/ // 1) Position (ScAddress) +/*N*/ // 2) Operation (USHORT) +/*N*/ +/*N*/ aHdr.StartEntry(); +/*N*/ +/*N*/ ScDetOpData* pData = (*this)[i]; +/*N*/ rStream << pData->GetPos(); +/*N*/ rStream << (USHORT) pData->GetOperation(); +/*N*/ +/*N*/ aHdr.EndEntry(); +/*N*/ } +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_detfunc.cxx b/binfilter/bf_sc/source/core/tool/sc_detfunc.cxx new file mode 100644 index 000000000000..1e677adcda46 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_detfunc.cxx @@ -0,0 +1,1695 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// INCLUDE --------------------------------------------------------------- + +#include "scitems.hxx" +#include <bf_svtools/colorcfg.hxx> +#include <bf_svx/outlobj.hxx> + +#include <bf_svx/xdef.hxx> + +#include <bf_svx/svditer.hxx> +#include <bf_svx/svdocapt.hxx> +#include <bf_svx/svdocirc.hxx> +#include <bf_svx/svdopath.hxx> +#include <bf_svx/svdpage.hxx> +#include <bf_svx/svdundo.hxx> +#include <bf_svx/xflclit.hxx> +#include <bf_svx/xlnclit.hxx> +#include <bf_svx/xlnedcit.hxx> +#include <bf_svx/xlnedit.hxx> +#include <bf_svx/xlnedwit.hxx> +#include <bf_svx/xlnstcit.hxx> +#include <bf_svx/xlnstit.hxx> +#include <bf_svx/xlnstwit.hxx> +#include <bf_svx/xlnwtit.hxx> + +#include "detfunc.hxx" +#include "document.hxx" +#include "dociter.hxx" +#include "drwlayer.hxx" +#include "userdat.hxx" +#include "validat.hxx" +#include "cell.hxx" +#include "docpool.hxx" +#include "patattr.hxx" +#include "scmod.hxx" +namespace binfilter { + +//------------------------------------------------------------------------ + +// #99319# line ends are now created with an empty name. +// The checkForUniqueItem method then finds a unique name for the item's value. +#define SC_LINEEND_NAME EMPTY_STRING + +//------------------------------------------------------------------------ + +enum DetInsertResult { // Return-Werte beim Einfuegen in einen Level + DET_INS_CONTINUE, + DET_INS_INSERTED, + DET_INS_EMPTY, + DET_INS_CIRCULAR }; + +// maximale Textlaenge (Zeichen), die noch in "kleines" Objekt passt +#define SC_NOTE_SMALLTEXT 100 + +//------------------------------------------------------------------------ + +//-/class ScPublicAttrObj : public SdrAttrObj +//-/{ +//-/private: +//-/ ScPublicAttrObj() {} // wird nicht angelegt +//-/public: +//-/ const XLineAttrSetItem* GetLineAttr() { return pLineAttr; } +//-/}; + +//------------------------------------------------------------------------ + +/*N*/ class ScDetectiveData +/*N*/ { +/*N*/ private: +/*N*/ SfxItemSet aBoxSet; +/*N*/ SfxItemSet aArrowSet; +/*N*/ SfxItemSet aToTabSet; +/*N*/ SfxItemSet aFromTabSet; +/*N*/ SfxItemSet aCircleSet; //! einzeln ? +/*N*/ USHORT nMaxLevel; +/*N*/ +/*N*/ public: +/*N*/ ScDetectiveData( SdrModel* pModel ); +/*N*/ +/*N*/ SfxItemSet& GetBoxSet() { return aBoxSet; } +/*N*/ SfxItemSet& GetArrowSet() { return aArrowSet; } +/*N*/ SfxItemSet& GetToTabSet() { return aToTabSet; } +/*N*/ SfxItemSet& GetFromTabSet() { return aFromTabSet; } +/*N*/ SfxItemSet& GetCircleSet() { return aCircleSet; } +/*N*/ +/*N*/ void SetMaxLevel( USHORT nVal ) { nMaxLevel = nVal; } +/*N*/ USHORT GetMaxLevel() const { return nMaxLevel; } +/*N*/ }; + +/*N*/ class ScCommentData +/*N*/ { +/*N*/ private: +/*N*/ SfxItemSet aCaptionSet; +/*N*/ +/*N*/ public: +/*N*/ ScCommentData( ScDocument* pDoc, SdrModel* pModel ); +/*N*/ +/*N*/ SfxItemSet& GetCaptionSet() { return aCaptionSet; } +/*N*/ }; + +//------------------------------------------------------------------------ + +/*N*/ ColorData ScDetectiveFunc::nArrowColor = 0; +/*N*/ ColorData ScDetectiveFunc::nErrorColor = 0; +/*N*/ ColorData ScDetectiveFunc::nCommentColor = 0; +/*N*/ BOOL ScDetectiveFunc::bColorsInitialized = FALSE; + +//------------------------------------------------------------------------ + +/*N*/ BOOL lcl_HasThickLine( SdrObject& rObj ) // detective.sdc +/*N*/ { +/*N*/ // thin lines get width 0 -> everything greater 0 is a thick line +/*N*/ +/*N*/ return ( ((const XLineWidthItem&)rObj.GetItem(XATTR_LINEWIDTH)).GetValue() > 0 ); +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ ScDetectiveData::ScDetectiveData( SdrModel* pModel ) : +/*N*/ aBoxSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END ), +/*N*/ aArrowSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END ), +/*N*/ aToTabSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END ), +/*N*/ aFromTabSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END ), +/*N*/ aCircleSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END ) +/*N*/ { +/*N*/ nMaxLevel = 0; +/*N*/ +/*N*/ aBoxSet.Put( XLineColorItem( EMPTY_STRING, Color( ScDetectiveFunc::GetArrowColor() ) ) ); +/*N*/ aBoxSet.Put( XFillStyleItem( XFILL_NONE ) ); +/*N*/ +/*N*/ // #66479# Standard-Linienenden (wie aus XLineEndList::Create) selber zusammenbasteln, +/*N*/ // um von den konfigurierten Linienenden unabhaengig zu sein +/*N*/ +/*N*/ XPolygon aTriangle(4); +/*N*/ aTriangle[0].X()=10; aTriangle[0].Y()= 0; +/*N*/ aTriangle[1].X()= 0; aTriangle[1].Y()=30; +/*N*/ aTriangle[2].X()=20; aTriangle[2].Y()=30; +/*N*/ aTriangle[3].X()=10; aTriangle[3].Y()= 0; // #99319# line end polygon must be closed +/*N*/ +/*N*/ XPolygon aSquare(5); +/*N*/ aSquare[0].X()= 0; aSquare[0].Y()= 0; +/*N*/ aSquare[1].X()=10; aSquare[1].Y()= 0; +/*N*/ aSquare[2].X()=10; aSquare[2].Y()=10; +/*N*/ aSquare[3].X()= 0; aSquare[3].Y()=10; +/*N*/ aSquare[4].X()= 0; aSquare[4].Y()= 0; // #99319# line end polygon must be closed +/*N*/ +/*N*/ XPolygon aCircle(Point(0,0),100,100); +/*N*/ +/*N*/ String aName = SC_LINEEND_NAME; +/*N*/ +/*N*/ aArrowSet.Put( XLineStartItem( aName, aCircle ) ); +/*N*/ aArrowSet.Put( XLineStartWidthItem( 200 ) ); +/*N*/ aArrowSet.Put( XLineStartCenterItem( TRUE ) ); +/*N*/ aArrowSet.Put( XLineEndItem( aName, aTriangle ) ); +/*N*/ aArrowSet.Put( XLineEndWidthItem( 200 ) ); +/*N*/ aArrowSet.Put( XLineEndCenterItem( FALSE ) ); +/*N*/ +/*N*/ aToTabSet.Put( XLineStartItem( aName, aCircle ) ); +/*N*/ aToTabSet.Put( XLineStartWidthItem( 200 ) ); +/*N*/ aToTabSet.Put( XLineStartCenterItem( TRUE ) ); +/*N*/ aToTabSet.Put( XLineEndItem( aName, aSquare ) ); +/*N*/ aToTabSet.Put( XLineEndWidthItem( 300 ) ); +/*N*/ aToTabSet.Put( XLineEndCenterItem( FALSE ) ); +/*N*/ +/*N*/ aFromTabSet.Put( XLineStartItem( aName, aSquare ) ); +/*N*/ aFromTabSet.Put( XLineStartWidthItem( 300 ) ); +/*N*/ aFromTabSet.Put( XLineStartCenterItem( TRUE ) ); +/*N*/ aFromTabSet.Put( XLineEndItem( aName, aTriangle ) ); +/*N*/ aFromTabSet.Put( XLineEndWidthItem( 200 ) ); +/*N*/ aFromTabSet.Put( XLineEndCenterItem( FALSE ) ); +/*N*/ +/*N*/ aCircleSet.Put( XLineColorItem( String(), Color( ScDetectiveFunc::GetErrorColor() ) ) ); +/*N*/ aCircleSet.Put( XFillStyleItem( XFILL_NONE ) ); +/*N*/ USHORT nWidth = 55; // 54 = 1 Pixel +/*N*/ aCircleSet.Put( XLineWidthItem( nWidth ) ); +/*N*/ } + +/*N*/ ScCommentData::ScCommentData( ScDocument* pDoc, SdrModel* pModel ) : +/*N*/ aCaptionSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END, +/*N*/ EE_CHAR_START, EE_CHAR_END, 0 ) +/*N*/ { +/*N*/ XPolygon aTriangle(4); +/*N*/ aTriangle[0].X()=10; aTriangle[0].Y()= 0; +/*N*/ aTriangle[1].X()= 0; aTriangle[1].Y()=30; +/*N*/ aTriangle[2].X()=20; aTriangle[2].Y()=30; +/*N*/ aTriangle[3].X()=10; aTriangle[3].Y()= 0; // #99319# line end polygon must be closed +/*N*/ +/*N*/ String aName = SC_LINEEND_NAME; +/*N*/ +/*N*/ aCaptionSet.Put( XLineStartItem( aName, aTriangle ) ); +/*N*/ aCaptionSet.Put( XLineStartWidthItem( 200 ) ); +/*N*/ aCaptionSet.Put( XLineStartCenterItem( FALSE ) ); +/*N*/ aCaptionSet.Put( XFillStyleItem( XFILL_SOLID ) ); +/*N*/ Color aYellow( ScDetectiveFunc::GetCommentColor() ); +/*N*/ aCaptionSet.Put( XFillColorItem( String(), aYellow ) ); +/*N*/ +/*N*/ // shadow +/*N*/ // SdrShadowItem has FALSE, instead the shadow is set for the rectangle +/*N*/ // only with SetSpecialTextBoxShadow when the object is created +/*N*/ // (item must be set to adjust objects from older files) +/*N*/ aCaptionSet.Put( SdrShadowItem( FALSE ) ); +/*N*/ aCaptionSet.Put( SdrShadowXDistItem( 100 ) ); +/*N*/ aCaptionSet.Put( SdrShadowYDistItem( 100 ) ); +/*N*/ +/*N*/ // text attributes +/*N*/ aCaptionSet.Put( SdrTextLeftDistItem( 100 ) ); +/*N*/ aCaptionSet.Put( SdrTextRightDistItem( 100 ) ); +/*N*/ aCaptionSet.Put( SdrTextUpperDistItem( 100 ) ); +/*N*/ aCaptionSet.Put( SdrTextLowerDistItem( 100 ) ); +/*N*/ +/*N*/ // #78943# do use the default cell style, so the user has a chance to +/*N*/ // modify the font for the annotations +/*N*/ ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)). +/*N*/ FillEditItemSet( &aCaptionSet ); +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ inline BOOL Intersect( USHORT nStartCol1, USHORT nStartRow1, USHORT nEndCol1, USHORT nEndRow1, +/*N*/ USHORT nStartCol2, USHORT nStartRow2, USHORT nEndCol2, USHORT nEndRow2 ) +/*N*/ { +/*N*/ return nEndCol1 >= nStartCol2 && nEndCol2 >= nStartCol1 && +/*N*/ nEndRow1 >= nStartRow2 && nEndRow2 >= nStartRow1; +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::HasError( const ScTripel& rStart, const ScTripel& rEnd, ScTripel& rErrPos ) +/*N*/ { +/*N*/ rErrPos = rStart; +/*N*/ USHORT nError = 0; +/*N*/ +/*N*/ ScCellIterator aCellIter( pDoc, rStart.GetCol(), rStart.GetRow(), rStart.GetTab(), +/*N*/ rEnd.GetCol(), rEnd.GetRow(), rEnd.GetTab() ); +/*N*/ ScBaseCell* pCell = aCellIter.GetFirst(); +/*N*/ while (pCell) +/*N*/ { +/*N*/ if (pCell->GetCellType() == CELLTYPE_FORMULA) +/*N*/ { +/*N*/ nError = ((ScFormulaCell*)pCell)->GetErrCode(); +/*N*/ if (nError) +/*N*/ rErrPos.Put( aCellIter.GetCol(), aCellIter.GetRow(), aCellIter.GetTab() ); +/*N*/ } +/*N*/ pCell = aCellIter.GetNext(); +/*N*/ } +/*N*/ +/*N*/ return (nError != 0); +/*N*/ } + +/*N*/ Point ScDetectiveFunc::GetDrawPos( USHORT nCol, USHORT nRow, BOOL bArrow ) +/*N*/ { +/*N*/ // MAXCOL/ROW+1 ist erlaubt fuer Ende von Rahmen +/*N*/ if (nCol > MAXCOL+1) +/*N*/ { +/*N*/ DBG_ERROR("falsche Col in ScDetectiveFunc::GetDrawPos"); +/*N*/ nCol = MAXCOL+1; +/*N*/ } +/*N*/ if (nRow > MAXROW+1) +/*N*/ { +/*N*/ DBG_ERROR("falsche Row in ScDetectiveFunc::GetDrawPos"); +/*N*/ nRow = MAXROW+1; +/*N*/ } +/*N*/ +/*N*/ Point aPos; +/*N*/ USHORT i; +/*N*/ USHORT nLocalTab = nTab; // nicht ueber this +/*N*/ +/*N*/ for (i=0; i<nCol; i++) +/*N*/ aPos.X() += pDoc->GetColWidth( i,nLocalTab ); +/*N*/ for (i=0; i<nRow; i++) +/*N*/ aPos.Y() += pDoc->FastGetRowHeight( i,nLocalTab ); +/*N*/ +/*N*/ if (bArrow) +/*N*/ { +/*N*/ if (nCol<=MAXCOL) +/*N*/ aPos.X() += pDoc->GetColWidth( nCol, nLocalTab ) / 4; +/*N*/ if (nCol<=MAXROW) +/*N*/ aPos.Y() += pDoc->GetRowHeight( nRow, nLocalTab ) / 2; +/*N*/ } +/*N*/ +/*N*/ aPos.X() = (long) ( aPos.X() * HMM_PER_TWIPS ); +/*N*/ aPos.Y() = (long) ( aPos.Y() * HMM_PER_TWIPS ); +/*N*/ +/*N*/ return aPos; +/*N*/ } + +/*N*/ BOOL lcl_IsOtherTab( const XPolygon& rPolygon ) +/*N*/ { +/*N*/ // test if rPolygon is the line end for "other table" (rectangle) +/*N*/ +/*N*/ USHORT nCount = rPolygon.GetPointCount(); +/*N*/ if ( nCount == 4 ) +/*N*/ { +/*N*/ // 4 points -> it is a rectangle (not closed) only if the first and last point are different +/*N*/ +/*N*/ return rPolygon[0] != rPolygon[3]; +/*N*/ } +/*N*/ else if ( nCount == 5 ) +/*N*/ { +/*N*/ // 5 points -> it is a rectangle (closed) only if the first and last point are equal +/*N*/ +/*N*/ return rPolygon[0] == rPolygon[4]; +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::HasArrow( USHORT nStartCol, USHORT nStartRow, USHORT nStartTab, +/*N*/ USHORT nEndCol, USHORT nEndRow, USHORT nEndTab ) +/*N*/ { +/*N*/ BOOL bStartAlien = ( nStartTab != nTab ); +/*N*/ BOOL bEndAlien = ( nEndTab != nTab ); +/*N*/ +/*N*/ if (bStartAlien && bEndAlien) +/*N*/ { +/*N*/ DBG_ERROR("bStartAlien && bEndAlien"); +/*N*/ return TRUE; +/*N*/ } +/*N*/ +/*N*/ Rectangle aStartRect; +/*N*/ Rectangle aEndRect; +/*N*/ if (!bStartAlien) +/*N*/ { +/*N*/ Point aStartPos = GetDrawPos( nStartCol, nStartRow, FALSE ); +/*N*/ Size aStartSize = Size( +/*N*/ (long) ( pDoc->GetColWidth( nStartCol, nTab) * HMM_PER_TWIPS ), +/*N*/ (long) ( pDoc->GetRowHeight( nStartRow, nTab) * HMM_PER_TWIPS ) ); +/*N*/ aStartRect = Rectangle( aStartPos, aStartSize ); +/*N*/ } +/*N*/ if (!bEndAlien) +/*N*/ { +/*N*/ Point aEndPos = GetDrawPos( nEndCol, nEndRow, FALSE ); +/*N*/ Size aEndSize = Size( +/*N*/ (long) ( pDoc->GetColWidth( nEndCol, nTab) * HMM_PER_TWIPS ), +/*N*/ (long) ( pDoc->GetRowHeight( nEndRow, nTab) * HMM_PER_TWIPS ) ); +/*N*/ aEndRect = Rectangle( aEndPos, aEndSize ); +/*N*/ } +/*N*/ +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ BOOL bFound = FALSE; +/*N*/ SdrObjListIter aIter( *pPage, IM_FLAT ); +/*N*/ SdrObject* pObject = aIter.Next(); +/*N*/ while (pObject && !bFound) +/*N*/ { +/*N*/ if ( pObject->GetLayer()==SC_LAYER_INTERN && +/*N*/ pObject->IsPolyObj() && pObject->GetPointCount()==2 ) +/*N*/ { +/*N*/ BOOL bObjStartAlien = +/*N*/ lcl_IsOtherTab( ((const XLineStartItem&)pObject->GetItem(XATTR_LINESTART)).GetValue() ); +/*N*/ BOOL bObjEndAlien = +/*N*/ lcl_IsOtherTab( ((const XLineEndItem&)pObject->GetItem(XATTR_LINEEND)).GetValue() ); +/*N*/ +/*N*/ //-/ BOOL bObjStartAlien = FALSE; +/*N*/ //-/ BOOL bObjEndAlien = FALSE; +/*N*/ //-/ const XLineAttrSetItem* pLineAttrs = +/*N*/ //-/ ((ScPublicAttrObj*)(SdrAttrObj*)pObject)->GetLineAttr(); +/*N*/ //-/ if (pLineAttrs) +/*N*/ //-/ { +/*N*/ //-/ const SfxItemSet& rSet = pLineAttrs->GetItemSet(); +/*N*/ //-/ bObjStartAlien = (((const XLineStartItem&)rSet.Get(XATTR_LINESTART)). +/*N*/ //-/ GetValue().GetPointCount() == 4 ); +/*N*/ //-/ bObjEndAlien = (((const XLineEndItem&)rSet.Get(XATTR_LINEEND)). +/*N*/ //-/ GetValue().GetPointCount() == 4 ); +/*N*/ //-/ } +/*N*/ +/*N*/ BOOL bStartHit = bStartAlien ? bObjStartAlien : +/*N*/ ( !bObjStartAlien && aStartRect.IsInside(pObject->GetPoint(0)) ); +/*N*/ BOOL bEndHit = bEndAlien ? bObjEndAlien : +/*N*/ ( !bObjEndAlien && aEndRect.IsInside(pObject->GetPoint(1)) ); +/*N*/ +/*N*/ if ( bStartHit && bEndHit ) +/*N*/ bFound = TRUE; +/*N*/ } +/*N*/ pObject = aIter.Next(); +/*N*/ } +/*N*/ +/*N*/ return bFound; +/*N*/ } + + +//------------------------------------------------------------------------ + +// InsertXXX: called from DrawEntry/DrawAlienEntry and InsertObject + +/*N*/ BOOL ScDetectiveFunc::InsertArrow( USHORT nCol, USHORT nRow, +/*N*/ USHORT nRefStartCol, USHORT nRefStartRow, +/*N*/ USHORT nRefEndCol, USHORT nRefEndRow, +/*N*/ BOOL bFromOtherTab, BOOL bRed, +/*N*/ ScDetectiveData& rData ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ +/*N*/ BOOL bArea = ( nRefStartCol != nRefEndCol || nRefStartRow != nRefEndRow ); +/*N*/ if (bArea && !bFromOtherTab) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ +/*N*/ Point aStartPos = GetDrawPos( nRefStartCol, nRefStartRow, TRUE ); +/*N*/ Point aEndPos = GetDrawPos( nCol, nRow, TRUE ); +/*N*/ +/*N*/ if (bFromOtherTab) +/*N*/ { +/*N*/ aStartPos = Point( aEndPos.X() - 1000, aEndPos.Y() - 1000 ); +/*N*/ if (aStartPos.X() < 0) +/*N*/ aStartPos.X() += 2000; +/*N*/ if (aStartPos.Y() < 0) +/*N*/ aStartPos.Y() += 2000; +/*N*/ } +/*N*/ +/*N*/ SfxItemSet& rAttrSet = bFromOtherTab ? rData.GetFromTabSet() : rData.GetArrowSet(); +/*N*/ +/*N*/ if (bArea && !bFromOtherTab) +/*N*/ rAttrSet.Put( XLineWidthItem( 50 ) ); // Bereich +/*N*/ else +/*N*/ rAttrSet.Put( XLineWidthItem( 0 ) ); // einzelne Referenz +/*N*/ +/*N*/ ColorData nColorData = ( bRed ? GetErrorColor() : GetArrowColor() ); +/*N*/ rAttrSet.Put( XLineColorItem( String(), Color( nColorData ) ) ); +/*N*/ Point aPointArr[2] = {aStartPos, aEndPos}; +/*N*/ SdrPathObj* pArrow = new SdrPathObj(OBJ_LINE, +/*N*/ XPolyPolygon(XPolygon(Polygon(2, aPointArr)))); +/*N*/ +/*N*/ pArrow->NbcSetLogicRect(Rectangle(aStartPos,aEndPos)); //! noetig ??? +/*N*/ +/*N*/ //-/ pArrow->SetAttributes( rAttrSet, FALSE ); +/*N*/ pArrow->SetItemSetAndBroadcast(rAttrSet); +/*N*/ +/*N*/ ScDrawLayer::SetAnchor( pArrow, SCA_CELL ); +/*N*/ pArrow->SetLayer( SC_LAYER_INTERN ); +/*N*/ pPage->InsertObject( pArrow ); +/*N*/ pModel->AddCalcUndo( new SdrUndoInsertObj( *pArrow ) ); +/*N*/ +/*N*/ ScDrawObjData* pData = ScDrawLayer::GetObjData( pArrow, TRUE ); +/*N*/ if (bFromOtherTab) +/*N*/ pData->bValidStart = FALSE; +/*N*/ else +/*N*/ { +/*N*/ pData->aStt.nCol = nRefStartCol; +/*N*/ pData->aStt.nRow = nRefStartRow; +/*N*/ pData->aStt.nTab = nTab; +/*N*/ pData->bValidStart = TRUE; +/*N*/ } +/*N*/ +/*N*/ pData->aEnd.nCol = nCol; +/*N*/ pData->aEnd.nRow = nRow; +/*N*/ pData->aEnd.nTab = nTab; +/*N*/ pData->bValidEnd = TRUE; +/*N*/ +/*N*/ return TRUE; +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::InsertToOtherTab( USHORT nStartCol, USHORT nStartRow, +/*N*/ USHORT nEndCol, USHORT nEndRow, BOOL bRed, +/*N*/ ScDetectiveData& rData ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ +/*N*/ BOOL bArea = ( nStartCol != nEndCol || nStartRow != nEndRow ); +/*N*/ if (bArea) +/*N*/ { +/*N*/ Point aStartCorner = GetDrawPos( nStartCol, nStartRow, FALSE ); +/*N*/ Point aEndCorner = GetDrawPos( nEndCol+1, nEndRow+1, FALSE ); +/*N*/ +/*N*/ SdrRectObj* pBox = new SdrRectObj(Rectangle(aStartCorner,aEndCorner)); +/*N*/ +/*N*/ //-/ pBox->SetAttributes( rData.GetBoxSet(), FALSE ); +/*N*/ pBox->SetItemSetAndBroadcast(rData.GetBoxSet()); +/*N*/ +/*N*/ ScDrawLayer::SetAnchor( pBox, SCA_CELL ); +/*N*/ pBox->SetLayer( SC_LAYER_INTERN ); +/*N*/ pPage->InsertObject( pBox ); +/*N*/ pModel->AddCalcUndo( new SdrUndoInsertObj( *pBox ) ); +/*N*/ +/*N*/ ScDrawObjData* pData = ScDrawLayer::GetObjData( pBox, TRUE ); +/*N*/ pData->aStt.nCol = nStartCol; +/*N*/ pData->aStt.nRow = nStartRow; +/*N*/ pData->aStt.nTab = nTab; +/*N*/ pData->aEnd.nCol = nEndCol; +/*N*/ pData->aEnd.nRow = nEndRow; +/*N*/ pData->aEnd.nTab = nTab; +/*N*/ pData->bValidStart = TRUE; +/*N*/ pData->bValidEnd = TRUE; +/*N*/ } +/*N*/ +/*N*/ Point aStartPos = GetDrawPos( nStartCol, nStartRow, TRUE ); +/*N*/ Point aEndPos = Point( aStartPos.X() + 1000, aStartPos.Y() - 1000 ); +/*N*/ if (aEndPos.Y() < 0) +/*N*/ aEndPos.Y() += 2000; +/*N*/ +/*N*/ SfxItemSet& rAttrSet = rData.GetToTabSet(); +/*N*/ if (bArea) +/*N*/ rAttrSet.Put( XLineWidthItem( 50 ) ); // Bereich +/*N*/ else +/*N*/ rAttrSet.Put( XLineWidthItem( 0 ) ); // einzelne Referenz +/*N*/ +/*N*/ ColorData nColorData = ( bRed ? GetErrorColor() : GetArrowColor() ); +/*N*/ rAttrSet.Put( XLineColorItem( String(), Color( nColorData ) ) ); +/*N*/ Point aPointArr[2] = {aStartPos, aEndPos}; +/*N*/ SdrPathObj* pArrow = new SdrPathObj(OBJ_LINE, +/*N*/ XPolyPolygon(XPolygon(Polygon(2, aPointArr)))); +/*N*/ +/*N*/ pArrow->NbcSetLogicRect(Rectangle(aStartPos,aEndPos)); //! noetig ??? +/*N*/ +/*N*/ //-/ pArrow->SetAttributes( rAttrSet, FALSE ); +/*N*/ pArrow->SetItemSetAndBroadcast(rAttrSet); +/*N*/ +/*N*/ ScDrawLayer::SetAnchor( pArrow, SCA_CELL ); +/*N*/ pArrow->SetLayer( SC_LAYER_INTERN ); +/*N*/ pPage->InsertObject( pArrow ); +/*N*/ pModel->AddCalcUndo( new SdrUndoInsertObj( *pArrow ) ); +/*N*/ +/*N*/ ScDrawObjData* pData = ScDrawLayer::GetObjData( pArrow, TRUE ); +/*N*/ pData->aStt.nCol = nStartCol; +/*N*/ pData->aStt.nRow = nStartRow; +/*N*/ pData->aStt.nTab = nTab; +/*N*/ pData->bValidStart = TRUE; +/*N*/ pData->bValidEnd = FALSE; +/*N*/ +/*N*/ return TRUE; +/*N*/ } + +//------------------------------------------------------------------------ + +// DrawEntry: Formel auf dieser Tabelle, +// Referenz auf dieser oder anderer +// DrawAlienEntry: Formel auf anderer Tabelle, +// Referenz auf dieser + +// return FALSE: da war schon ein Pfeil + +/*N*/ BOOL ScDetectiveFunc::DrawEntry( USHORT nCol, USHORT nRow, +/*N*/ const ScTripel& rRefStart, const ScTripel& rRefEnd, +/*N*/ ScDetectiveData& rData ) +/*N*/ { +/*N*/ if ( HasArrow( rRefStart.GetCol(), rRefStart.GetRow(), rRefStart.GetTab(), +/*N*/ nCol, nRow, nTab ) ) +/*N*/ return FALSE; +/*N*/ +/*N*/ ScTripel aErrorPos; +/*N*/ BOOL bError = HasError( rRefStart, rRefEnd, aErrorPos ); +/*N*/ BOOL bAlien = ( rRefEnd.GetTab() < nTab || rRefStart.GetTab() > nTab ); +/*N*/ +/*N*/ return InsertArrow( nCol, nRow, +/*N*/ rRefStart.GetCol(), rRefStart.GetRow(), +/*N*/ rRefEnd.GetCol(), rRefEnd.GetRow(), +/*N*/ bAlien, bError, rData ); +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::DrawAlienEntry( const ScTripel& rRefStart, const ScTripel& rRefEnd, +/*N*/ ScDetectiveData& rData ) +/*N*/ { +/*N*/ if ( HasArrow( rRefStart.GetCol(), rRefStart.GetRow(), rRefStart.GetTab(), +/*N*/ 0, 0, nTab+1 ) ) +/*N*/ return FALSE; +/*N*/ +/*N*/ ScTripel aErrorPos; +/*N*/ BOOL bError = HasError( rRefStart, rRefEnd, aErrorPos ); +/*N*/ +/*N*/ return InsertToOtherTab( rRefStart.GetCol(), rRefStart.GetRow(), +/*N*/ rRefEnd.GetCol(), rRefEnd.GetRow(), +/*N*/ bError, rData ); +/*N*/ } + +/*N*/ void ScDetectiveFunc::DrawCircle( USHORT nCol, USHORT nRow, ScDetectiveData& rData ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ +/*N*/ Point aStartPos = GetDrawPos( nCol, nRow, FALSE ); +/*N*/ Size aSize( (long) ( pDoc->GetColWidth(nCol, nTab) * HMM_PER_TWIPS ), +/*N*/ (long) ( pDoc->GetRowHeight(nRow, nTab) * HMM_PER_TWIPS ) ); +/*N*/ Rectangle aRect( aStartPos, aSize ); +/*N*/ aRect.Left() -= 250; +/*N*/ aRect.Right() += 250; +/*N*/ aRect.Top() -= 70; +/*N*/ aRect.Bottom() += 70; +/*N*/ +/*N*/ SdrCircObj* pCircle = new SdrCircObj( OBJ_CIRC, aRect ); +/*N*/ SfxItemSet& rAttrSet = rData.GetCircleSet(); +/*N*/ +/*N*/ //-/ pCircle->SetAttributes( rAttrSet, FALSE ); +/*N*/ pCircle->SetItemSetAndBroadcast(rAttrSet); +/*N*/ +/*N*/ ScDrawLayer::SetAnchor( pCircle, SCA_CELL ); +/*N*/ pCircle->SetLayer( SC_LAYER_INTERN ); +/*N*/ pPage->InsertObject( pCircle ); +/*N*/ pModel->AddCalcUndo( new SdrUndoInsertObj( *pCircle ) ); +/*N*/ +/*N*/ ScDrawObjData* pData = ScDrawLayer::GetObjData( pCircle, TRUE ); +/*N*/ pData->aStt.nCol = nCol; +/*N*/ pData->aStt.nRow = nRow; +/*N*/ pData->aStt.nTab = nTab; +/*N*/ pData->bValidStart = TRUE; +/*N*/ pData->bValidEnd = FALSE; +/*N*/ } + + +/*N*/ void ScDetectiveFunc::DeleteArrowsAt( USHORT nCol, USHORT nRow, BOOL bDestPnt ) +/*N*/ { +/*N*/ Point aPos = GetDrawPos( nCol, nRow, FALSE ); +/*N*/ Size aSize = Size( (long) ( pDoc->GetColWidth( nCol, nTab) * HMM_PER_TWIPS ), +/*N*/ (long) ( pDoc->GetRowHeight( nRow, nTab) * HMM_PER_TWIPS ) ); +/*N*/ Rectangle aRect( aPos, aSize ); +/*N*/ +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ pPage->RecalcObjOrdNums(); +/*N*/ +/*N*/ long nDelCount = 0; +/*N*/ ULONG nObjCount = pPage->GetObjCount(); +/*N*/ if (nObjCount) +/*N*/ { +/*N*/ SdrObject** ppObj = new SdrObject*[nObjCount]; +/*N*/ +/*N*/ SdrObjListIter aIter( *pPage, IM_FLAT ); +/*N*/ SdrObject* pObject = aIter.Next(); +/*N*/ while (pObject) +/*N*/ { +/*N*/ if ( pObject->GetLayer()==SC_LAYER_INTERN && +/*N*/ pObject->IsPolyObj() && pObject->GetPointCount()==2 ) +/*N*/ { +/*N*/ if (aRect.IsInside(pObject->GetPoint(bDestPnt))) // Start/Zielpunkt +/*N*/ ppObj[nDelCount++] = pObject; +/*N*/ } +/*N*/ +/*N*/ pObject = aIter.Next(); +/*N*/ } +/*N*/ +/*N*/ long i; +/*N*/ for (i=1; i<=nDelCount; i++) +/*N*/ pModel->AddCalcUndo( new SdrUndoRemoveObj( *ppObj[nDelCount-i] ) ); +/*N*/ +/*N*/ for (i=1; i<=nDelCount; i++) +/*N*/ pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() ); +/*N*/ +/*N*/ delete[] ppObj; +/*N*/ } +/*N*/ } + + // Box um Referenz loeschen + +#define SC_DET_TOLERANCE 50 + +/*N*/ inline BOOL RectIsPoints( const Rectangle& rRect, const Point& rStart, const Point& rEnd ) +/*N*/ { +/*N*/ return rRect.Left() >= rStart.X() - SC_DET_TOLERANCE +/*N*/ && rRect.Left() <= rStart.X() + SC_DET_TOLERANCE +/*N*/ && rRect.Right() >= rEnd.X() - SC_DET_TOLERANCE +/*N*/ && rRect.Right() <= rEnd.X() + SC_DET_TOLERANCE +/*N*/ && rRect.Top() >= rStart.Y() - SC_DET_TOLERANCE +/*N*/ && rRect.Top() <= rStart.Y() + SC_DET_TOLERANCE +/*N*/ && rRect.Bottom() >= rEnd.Y() - SC_DET_TOLERANCE +/*N*/ && rRect.Bottom() <= rEnd.Y() + SC_DET_TOLERANCE; +/*N*/ } + +#undef SC_DET_TOLERANCE + +/*N*/ void ScDetectiveFunc::DeleteBox( USHORT nCol1, USHORT nRow1, USHORT nCol2, USHORT nRow2 ) +/*N*/ { +/* String aStr; + aStr += nCol1; + aStr += '/'; + aStr += nRow1; + aStr += '/'; + aStr += nCol2; + aStr += '/'; + aStr += nRow2; + InfoBox(0,aStr).Execute(); +*/ +/*N*/ +/*N*/ Point aStartCorner = GetDrawPos( nCol1, nRow1, FALSE ); +/*N*/ Point aEndCorner = GetDrawPos( nCol2+1, nRow2+1, FALSE ); +/*N*/ Rectangle aObjRect; +/*N*/ +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ pPage->RecalcObjOrdNums(); +/*N*/ +/*N*/ long nDelCount = 0; +/*N*/ ULONG nObjCount = pPage->GetObjCount(); +/*N*/ if (nObjCount) +/*N*/ { +/*N*/ SdrObject** ppObj = new SdrObject*[nObjCount]; +/*N*/ +/*N*/ SdrObjListIter aIter( *pPage, IM_FLAT ); +/*N*/ SdrObject* pObject = aIter.Next(); +/*N*/ while (pObject) +/*N*/ { +/*N*/ if ( pObject->GetLayer() == SC_LAYER_INTERN && +/*N*/ pObject->Type() == TYPE(SdrRectObj) ) +/*N*/ { +/*N*/ aObjRect = ((SdrRectObj*)pObject)->GetLogicRect(); +/*N*/ if ( RectIsPoints( aObjRect, aStartCorner, aEndCorner ) ) +/*N*/ ppObj[nDelCount++] = pObject; +/*N*/ } +/*N*/ +/*N*/ pObject = aIter.Next(); +/*N*/ } +/*N*/ +/*N*/ long i; +/*N*/ for (i=1; i<=nDelCount; i++) +/*N*/ pModel->AddCalcUndo( new SdrUndoRemoveObj( *ppObj[nDelCount-i] ) ); +/*N*/ +/*N*/ for (i=1; i<=nDelCount; i++) +/*N*/ pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() ); +/*N*/ +/*N*/ delete[] ppObj; +/*N*/ } +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ USHORT ScDetectiveFunc::InsertPredLevelArea( const ScTripel& rRefStart, const ScTripel& rRefEnd, +/*N*/ ScDetectiveData& rData, USHORT nLevel ) +/*N*/ { +/*N*/ USHORT nResult = DET_INS_EMPTY; +/*N*/ +/*N*/ ScCellIterator aCellIter( pDoc, rRefStart.GetCol(), rRefStart.GetRow(), rRefStart.GetTab(), +/*N*/ rRefEnd.GetCol(), rRefEnd.GetRow(), rRefEnd.GetTab() ); +/*N*/ ScBaseCell* pCell = aCellIter.GetFirst(); +/*N*/ while (pCell) +/*N*/ { +/*N*/ if (pCell->GetCellType() == CELLTYPE_FORMULA) +/*N*/ switch( InsertPredLevel( aCellIter.GetCol(), aCellIter.GetRow(), rData, nLevel ) ) +/*N*/ { +/*N*/ case DET_INS_INSERTED: +/*N*/ nResult = DET_INS_INSERTED; +/*N*/ break; +/*N*/ case DET_INS_CONTINUE: +/*N*/ if (nResult != DET_INS_INSERTED) +/*N*/ nResult = DET_INS_CONTINUE; +/*N*/ break; +/*N*/ case DET_INS_CIRCULAR: +/*N*/ if (nResult == DET_INS_EMPTY) +/*N*/ nResult = DET_INS_CIRCULAR; +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ pCell = aCellIter.GetNext(); +/*N*/ } +/*N*/ +/*N*/ return nResult; +/*N*/ } + +/*N*/ USHORT ScDetectiveFunc::InsertPredLevel( USHORT nCol, USHORT nRow, ScDetectiveData& rData, +/*N*/ USHORT nLevel ) +/*N*/ { +/*N*/ ScBaseCell* pCell; +/*N*/ pDoc->GetCell( nCol, nRow, nTab, pCell ); +/*N*/ if (!pCell) +/*N*/ return DET_INS_EMPTY; +/*N*/ if (pCell->GetCellType() != CELLTYPE_FORMULA) +/*N*/ return DET_INS_EMPTY; +/*N*/ +/*N*/ ScFormulaCell* pFCell = (ScFormulaCell*)pCell; +/*N*/ if (pFCell->IsRunning()) +/*N*/ return DET_INS_CIRCULAR; +/*N*/ +/*N*/ if (pFCell->GetDirty()) +/*N*/ pFCell->Interpret(); // nach SetRunning geht's nicht mehr! +/*N*/ pFCell->SetRunning(TRUE); +/*N*/ +/*N*/ USHORT nResult = DET_INS_EMPTY; +/*N*/ +/*N*/ ScDetectiveRefIter aIter( (ScFormulaCell*) pCell ); +/*N*/ ScTripel aRefStart; +/*N*/ ScTripel aRefEnd; +/*N*/ while ( aIter.GetNextRef( aRefStart, aRefEnd ) ) +/*N*/ { +/*N*/ if (DrawEntry( nCol, nRow, aRefStart, aRefEnd, rData )) +/*N*/ { +/*N*/ nResult = DET_INS_INSERTED; // neuer Pfeil eingetragen +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // weiterverfolgen +/*N*/ +/*N*/ if ( nLevel < rData.GetMaxLevel() ) +/*N*/ { +/*N*/ USHORT nSubResult; +/*N*/ BOOL bArea = (aRefStart != aRefEnd); +/*N*/ if (bArea) +/*N*/ nSubResult = InsertPredLevelArea( aRefStart, aRefEnd, rData, nLevel+1 ); +/*N*/ else +/*N*/ nSubResult = InsertPredLevel( aRefStart.GetCol(), aRefStart.GetRow(), +/*N*/ rData, nLevel+1 ); +/*N*/ +/*N*/ switch (nSubResult) +/*N*/ { +/*N*/ case DET_INS_INSERTED: +/*N*/ nResult = DET_INS_INSERTED; +/*N*/ break; +/*N*/ case DET_INS_CONTINUE: +/*N*/ if (nResult != DET_INS_INSERTED) +/*N*/ nResult = DET_INS_CONTINUE; +/*N*/ break; +/*N*/ case DET_INS_CIRCULAR: +/*N*/ if (nResult == DET_INS_EMPTY) +/*N*/ nResult = DET_INS_CIRCULAR; +/*N*/ break; +/*N*/ // DET_INS_EMPTY: unveraendert lassen +/*N*/ } +/*N*/ } +/*N*/ else // nMaxLevel erreicht +/*N*/ if (nResult != DET_INS_INSERTED) +/*N*/ nResult = DET_INS_CONTINUE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pFCell->SetRunning(FALSE); +/*N*/ +/*N*/ return nResult; +/*N*/ } + +/*N*/ USHORT ScDetectiveFunc::FindPredLevelArea( const ScTripel& rRefStart, const ScTripel& rRefEnd, +/*N*/ USHORT nLevel, USHORT nDeleteLevel ) +/*N*/ { +/*N*/ USHORT nResult = nLevel; +/*N*/ +/*N*/ ScCellIterator aCellIter( pDoc, rRefStart.GetCol(), rRefStart.GetRow(), rRefStart.GetTab(), +/*N*/ rRefEnd.GetCol(), rRefEnd.GetRow(), rRefEnd.GetTab() ); +/*N*/ ScBaseCell* pCell = aCellIter.GetFirst(); +/*N*/ while (pCell) +/*N*/ { +/*N*/ if (pCell->GetCellType() == CELLTYPE_FORMULA) +/*N*/ { +/*N*/ USHORT nTemp = FindPredLevel( aCellIter.GetCol(), aCellIter.GetRow(), nLevel, nDeleteLevel ); +/*N*/ if (nTemp > nResult) +/*N*/ nResult = nTemp; +/*N*/ } +/*N*/ pCell = aCellIter.GetNext(); +/*N*/ } +/*N*/ +/*N*/ return nResult; +/*N*/ } + + // nDeleteLevel != 0 -> loeschen + +/*N*/ USHORT ScDetectiveFunc::FindPredLevel( USHORT nCol, USHORT nRow, USHORT nLevel, USHORT nDeleteLevel ) +/*N*/ { +/*N*/ DBG_ASSERT( nLevel<1000, "Level" ); +/*N*/ +/*N*/ ScBaseCell* pCell; +/*N*/ pDoc->GetCell( nCol, nRow, nTab, pCell ); +/*N*/ if (!pCell) +/*N*/ return nLevel; +/*N*/ if (pCell->GetCellType() != CELLTYPE_FORMULA) +/*N*/ return nLevel; +/*N*/ +/*N*/ ScFormulaCell* pFCell = (ScFormulaCell*)pCell; +/*N*/ if (pFCell->IsRunning()) +/*N*/ return nLevel; +/*N*/ +/*N*/ if (pFCell->GetDirty()) +/*N*/ pFCell->Interpret(); // nach SetRunning geht's nicht mehr! +/*N*/ pFCell->SetRunning(TRUE); +/*N*/ +/*N*/ USHORT nResult = nLevel; +/*N*/ BOOL bDelete = ( nDeleteLevel && nLevel == nDeleteLevel-1 ); +/*N*/ +/*N*/ if ( bDelete ) +/*N*/ { +/*N*/ DeleteArrowsAt( nCol, nRow, TRUE ); // Pfeile, die hierher zeigen +/*N*/ } +/*N*/ +/*N*/ ScDetectiveRefIter aIter( (ScFormulaCell*) pCell ); +/*N*/ ScTripel aRefStart; +/*N*/ ScTripel aRefEnd; +/*N*/ while ( aIter.GetNextRef( aRefStart, aRefEnd ) ) +/*N*/ { +/*N*/ BOOL bArea = ( aRefStart != aRefEnd ); +/*N*/ +/*N*/ if ( bDelete ) // Rahmen loeschen ? +/*N*/ { +/*N*/ if (bArea) +/*N*/ { +/*N*/ DeleteBox( aRefStart.GetCol(), aRefStart.GetRow(), aRefEnd.GetCol(), aRefEnd.GetRow() ); +/*N*/ } +/*N*/ } +/*N*/ else // weitersuchen +/*N*/ { +/*N*/ if ( HasArrow( aRefStart.GetCol(),aRefStart.GetRow(),aRefStart.GetTab(), +/*N*/ nCol,nRow,nTab ) ) +/*N*/ { +/*N*/ USHORT nTemp; +/*N*/ if (bArea) +/*N*/ nTemp = FindPredLevelArea( aRefStart, aRefEnd, nLevel+1, nDeleteLevel ); +/*N*/ else +/*N*/ nTemp = FindPredLevel( aRefStart.GetCol(),aRefStart.GetRow(), +/*N*/ nLevel+1, nDeleteLevel ); +/*N*/ if (nTemp > nResult) +/*N*/ nResult = nTemp; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pFCell->SetRunning(FALSE); +/*N*/ +/*N*/ return nResult; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ USHORT ScDetectiveFunc::InsertErrorLevel( USHORT nCol, USHORT nRow, ScDetectiveData& rData, +/*N*/ USHORT nLevel ) +/*N*/ { +/*N*/ ScBaseCell* pCell; +/*N*/ pDoc->GetCell( nCol, nRow, nTab, pCell ); +/*N*/ if (!pCell) +/*N*/ return DET_INS_EMPTY; +/*N*/ if (pCell->GetCellType() != CELLTYPE_FORMULA) +/*N*/ return DET_INS_EMPTY; +/*N*/ +/*N*/ ScFormulaCell* pFCell = (ScFormulaCell*)pCell; +/*N*/ if (pFCell->IsRunning()) +/*N*/ return DET_INS_CIRCULAR; +/*N*/ +/*N*/ if (pFCell->GetDirty()) +/*N*/ pFCell->Interpret(); // nach SetRunning geht's nicht mehr! +/*N*/ pFCell->SetRunning(TRUE); +/*N*/ +/*N*/ USHORT nResult = DET_INS_EMPTY; +/*N*/ +/*N*/ ScDetectiveRefIter aIter( (ScFormulaCell*) pCell ); +/*N*/ ScTripel aRefStart; +/*N*/ ScTripel aRefEnd; +/*N*/ ScTripel aErrorPos; +/*N*/ BOOL bHasError = FALSE; +/*N*/ while ( aIter.GetNextRef( aRefStart, aRefEnd ) ) +/*N*/ { +/*N*/ if (HasError( aRefStart, aRefEnd, aErrorPos )) +/*N*/ { +/*N*/ bHasError = TRUE; +/*N*/ if (DrawEntry( nCol, nRow, aErrorPos, aErrorPos, rData )) +/*N*/ nResult = DET_INS_INSERTED; +/*N*/ +/*N*/ // und weiterverfolgen +/*N*/ +/*N*/ if ( nLevel < rData.GetMaxLevel() ) // praktisch immer +/*N*/ { +/*N*/ if (InsertErrorLevel( aErrorPos.GetCol(), aErrorPos.GetRow(), +/*N*/ rData, nLevel+1 ) == DET_INS_INSERTED) +/*N*/ nResult = DET_INS_INSERTED; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pFCell->SetRunning(FALSE); +/*N*/ +/*N*/ // Blaetter ? +/*N*/ if (!bHasError) +/*N*/ if (InsertPredLevel( nCol, nRow, rData, rData.GetMaxLevel() ) == DET_INS_INSERTED) +/*N*/ nResult = DET_INS_INSERTED; +/*N*/ +/*N*/ return nResult; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ USHORT ScDetectiveFunc::InsertSuccLevel( USHORT nCol1, USHORT nRow1, USHORT nCol2, USHORT nRow2, +/*N*/ ScDetectiveData& rData, USHORT nLevel ) +/*N*/ { +/*N*/ // ueber ganzes Dokument +/*N*/ +/*N*/ USHORT nResult = DET_INS_EMPTY; +/*N*/ // ScCellIterator aCellIter( pDoc, 0,0, nTab, MAXCOL,MAXROW, nTab ); +/*N*/ ScCellIterator aCellIter( pDoc, 0,0,0, MAXCOL,MAXROW,MAXTAB ); // alle Tabellen +/*N*/ ScBaseCell* pCell = aCellIter.GetFirst(); +/*N*/ while (pCell) +/*N*/ { +/*N*/ if (pCell->GetCellType() == CELLTYPE_FORMULA) +/*N*/ { +/*N*/ ScFormulaCell* pFCell = (ScFormulaCell*)pCell; +/*N*/ BOOL bRunning = pFCell->IsRunning(); +/*N*/ +/*N*/ if (pFCell->GetDirty()) +/*N*/ pFCell->Interpret(); // nach SetRunning geht's nicht mehr! +/*N*/ pFCell->SetRunning(TRUE); +/*N*/ +/*N*/ ScDetectiveRefIter aIter( (ScFormulaCell*) pCell ); +/*N*/ ScTripel aRefStart; +/*N*/ ScTripel aRefEnd; +/*N*/ while ( aIter.GetNextRef( aRefStart, aRefEnd ) ) +/*N*/ { +/*N*/ if (aRefStart.GetTab() <= nTab && aRefEnd.GetTab() >= nTab) +/*N*/ { +/*N*/ if (Intersect( nCol1,nRow1,nCol2,nRow2, +/*N*/ aRefStart.GetCol(),aRefStart.GetRow(), +/*N*/ aRefEnd.GetCol(),aRefEnd.GetRow() )) +/*N*/ { +/*N*/ BOOL bAlien = ( aCellIter.GetTab() != nTab ); +/*N*/ BOOL bDrawRet; +/*N*/ if (bAlien) +/*N*/ bDrawRet = DrawAlienEntry( aRefStart, aRefEnd, rData ); +/*N*/ else +/*N*/ bDrawRet = DrawEntry( aCellIter.GetCol(), aCellIter.GetRow(), +/*N*/ aRefStart, aRefEnd, rData ); +/*N*/ if (bDrawRet) +/*N*/ { +/*N*/ nResult = DET_INS_INSERTED; // neuer Pfeil eingetragen +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if (bRunning) +/*N*/ { +/*N*/ if (nResult == DET_INS_EMPTY) +/*N*/ nResult = DET_INS_CIRCULAR; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // weiterverfolgen +/*N*/ +/*N*/ if ( nLevel < rData.GetMaxLevel() ) +/*N*/ { +/*N*/ USHORT nSubResult = InsertSuccLevel( +/*N*/ aCellIter.GetCol(), aCellIter.GetRow(), +/*N*/ aCellIter.GetCol(), aCellIter.GetRow(), +/*N*/ rData, nLevel+1 ); +/*N*/ switch (nSubResult) +/*N*/ { +/*N*/ case DET_INS_INSERTED: +/*N*/ nResult = DET_INS_INSERTED; +/*N*/ break; +/*N*/ case DET_INS_CONTINUE: +/*N*/ if (nResult != DET_INS_INSERTED) +/*N*/ nResult = DET_INS_CONTINUE; +/*N*/ break; +/*N*/ case DET_INS_CIRCULAR: +/*N*/ if (nResult == DET_INS_EMPTY) +/*N*/ nResult = DET_INS_CIRCULAR; +/*N*/ break; +/*N*/ // DET_INS_EMPTY: unveraendert lassen +/*N*/ } +/*N*/ } +/*N*/ else // nMaxLevel erreicht +/*N*/ if (nResult != DET_INS_INSERTED) +/*N*/ nResult = DET_INS_CONTINUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ pFCell->SetRunning(bRunning); +/*N*/ } +/*N*/ pCell = aCellIter.GetNext(); +/*N*/ } +/*N*/ +/*N*/ return nResult; +/*N*/ } + +/*N*/ USHORT ScDetectiveFunc::FindSuccLevel( USHORT nCol1, USHORT nRow1, USHORT nCol2, USHORT nRow2, +/*N*/ USHORT nLevel, USHORT nDeleteLevel ) +/*N*/ { +/*N*/ DBG_ASSERT( nLevel<1000, "Level" ); +/*N*/ +/*N*/ USHORT nResult = nLevel; +/*N*/ BOOL bDelete = ( nDeleteLevel && nLevel == nDeleteLevel-1 ); +/*N*/ +/*N*/ ScCellIterator aCellIter( pDoc, 0,0, nTab, MAXCOL,MAXROW, nTab ); +/*N*/ ScBaseCell* pCell = aCellIter.GetFirst(); +/*N*/ while (pCell) +/*N*/ { +/*N*/ if (pCell->GetCellType() == CELLTYPE_FORMULA) +/*N*/ { +/*N*/ ScFormulaCell* pFCell = (ScFormulaCell*)pCell; +/*N*/ BOOL bRunning = pFCell->IsRunning(); +/*N*/ +/*N*/ if (pFCell->GetDirty()) +/*N*/ pFCell->Interpret(); // nach SetRunning geht's nicht mehr! +/*N*/ pFCell->SetRunning(TRUE); +/*N*/ +/*N*/ ScDetectiveRefIter aIter( (ScFormulaCell*) pCell ); +/*N*/ ScTripel aRefStart; +/*N*/ ScTripel aRefEnd; +/*N*/ while ( aIter.GetNextRef( aRefStart, aRefEnd ) ) +/*N*/ { +/*N*/ if (aRefStart.GetTab() <= nTab && aRefEnd.GetTab() >= nTab) +/*N*/ { +/*N*/ if (Intersect( nCol1,nRow1,nCol2,nRow2, +/*N*/ aRefStart.GetCol(),aRefStart.GetRow(), +/*N*/ aRefEnd.GetCol(),aRefEnd.GetRow() )) +/*N*/ { +/*N*/ if ( bDelete ) // Pfeile, die hier anfangen +/*N*/ { +/*N*/ if (aRefStart != aRefEnd) +/*N*/ { +/*N*/ DeleteBox( aRefStart.GetCol(), aRefStart.GetRow(), +/*N*/ aRefEnd.GetCol(), aRefEnd.GetRow() ); +/*N*/ } +/*N*/ DeleteArrowsAt( aRefStart.GetCol(), aRefStart.GetRow(), FALSE ); +/*N*/ } +/*N*/ else if ( !bRunning && +/*N*/ HasArrow( aRefStart.GetCol(),aRefStart.GetRow(),aRefStart.GetTab(), +/*N*/ aCellIter.GetCol(),aCellIter.GetRow(),aCellIter.GetTab() ) ) +/*N*/ { +/*N*/ USHORT nTemp = FindSuccLevel( aCellIter.GetCol(), aCellIter.GetRow(), +/*N*/ aCellIter.GetCol(), aCellIter.GetRow(), +/*N*/ nLevel+1, nDeleteLevel ); +/*N*/ if (nTemp > nResult) +/*N*/ nResult = nTemp; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pFCell->SetRunning(bRunning); +/*N*/ } +/*N*/ pCell = aCellIter.GetNext(); +/*N*/ } +/*N*/ +/*N*/ return nResult; +/*N*/ } + + +// +// -------------------------------------------------------------------------------- +// + +/*N*/ BOOL ScDetectiveFunc::ShowPred( USHORT nCol, USHORT nRow ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return FALSE; +/*N*/ +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ ScDetectiveData aData( pModel ); +/*N*/ +/*N*/ USHORT nMaxLevel = 0; +/*N*/ USHORT nResult = DET_INS_CONTINUE; +/*N*/ while (nResult == DET_INS_CONTINUE && nMaxLevel < 1000) +/*N*/ { +/*N*/ aData.SetMaxLevel( nMaxLevel ); +/*N*/ nResult = InsertPredLevel( nCol, nRow, aData, 0 ); +/*N*/ ++nMaxLevel; +/*N*/ } +/*N*/ +/*N*/ return ( nResult == DET_INS_INSERTED ); +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::ShowSucc( USHORT nCol, USHORT nRow ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return FALSE; +/*N*/ +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ ScDetectiveData aData( pModel ); +/*N*/ +/*N*/ USHORT nMaxLevel = 0; +/*N*/ USHORT nResult = DET_INS_CONTINUE; +/*N*/ while (nResult == DET_INS_CONTINUE && nMaxLevel < 1000) +/*N*/ { +/*N*/ aData.SetMaxLevel( nMaxLevel ); +/*N*/ nResult = InsertSuccLevel( nCol, nRow, nCol, nRow, aData, 0 ); +/*N*/ ++nMaxLevel; +/*N*/ } +/*N*/ +/*N*/ return ( nResult == DET_INS_INSERTED ); +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::ShowError( USHORT nCol, USHORT nRow ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return FALSE; +/*N*/ +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ ScTripel aPos( nCol, nRow, nTab ); +/*N*/ ScTripel aErrPos; +/*N*/ if ( !HasError( aPos,aPos,aErrPos ) ) +/*N*/ return FALSE; +/*N*/ +/*N*/ ScDetectiveData aData( pModel ); +/*N*/ +/*N*/ aData.SetMaxLevel( 1000 ); +/*N*/ USHORT nResult = InsertErrorLevel( nCol, nRow, aData, 0 ); +/*N*/ +/*N*/ return ( nResult == DET_INS_INSERTED ); +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::DeleteSucc( USHORT nCol, USHORT nRow ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return FALSE; +/*N*/ +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ USHORT nLevelCount = FindSuccLevel( nCol, nRow, nCol, nRow, 0, 0 ); +/*N*/ if ( nLevelCount ) +/*N*/ FindSuccLevel( nCol, nRow, nCol, nRow, 0, nLevelCount ); // loeschen +/*N*/ +/*N*/ return ( nLevelCount != 0 ); +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::DeletePred( USHORT nCol, USHORT nRow ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return FALSE; +/*N*/ +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ USHORT nLevelCount = FindPredLevel( nCol, nRow, 0, 0 ); +/*N*/ if ( nLevelCount ) +/*N*/ FindPredLevel( nCol, nRow, 0, nLevelCount ); // loeschen +/*N*/ +/*N*/ return ( nLevelCount != 0 ); +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::DeleteAll( ScDetectiveDelete eWhat ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return FALSE; +/*N*/ +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ pPage->RecalcObjOrdNums(); +/*N*/ +/*N*/ long nDelCount = 0; +/*N*/ ULONG nObjCount = pPage->GetObjCount(); +/*N*/ if (nObjCount) +/*N*/ { +/*N*/ SdrObject** ppObj = new SdrObject*[nObjCount]; +/*N*/ +/*N*/ SdrObjListIter aIter( *pPage, IM_FLAT ); +/*N*/ SdrObject* pObject = aIter.Next(); +/*N*/ while (pObject) +/*N*/ { +/*N*/ if ( pObject->GetLayer() == SC_LAYER_INTERN ) +/*N*/ { +/*N*/ BOOL bDoThis = TRUE; +/*N*/ if ( eWhat != SC_DET_ALL ) +/*N*/ { +/*N*/ BOOL bCircle = ( pObject->ISA(SdrCircObj) ); +/*N*/ BOOL bCaption = ( pObject->ISA(SdrCaptionObj) ); +/*N*/ if ( eWhat == SC_DET_DETECTIVE ) // Detektiv, aus Menue +/*N*/ bDoThis = !bCaption; // auch Kreise +/*N*/ else if ( eWhat == SC_DET_CIRCLES ) // Kreise, wenn neue erzeugt werden +/*N*/ bDoThis = bCircle; +/*N*/ else if ( eWhat == SC_DET_COMMENTS ) +/*N*/ bDoThis = bCaption; +/*N*/ else if ( eWhat == SC_DET_ARROWS ) // DetectiveRefresh +/*N*/ bDoThis = !bCaption && !bCircle; // don't include circles +/*N*/ else +/*N*/ DBG_ERROR("wat?"); +/*N*/ } +/*N*/ if ( bDoThis ) +/*N*/ ppObj[nDelCount++] = pObject; +/*N*/ } +/*N*/ +/*N*/ pObject = aIter.Next(); +/*N*/ } +/*N*/ +/*N*/ long i; +/*N*/ for (i=1; i<=nDelCount; i++) +/*N*/ pModel->AddCalcUndo( new SdrUndoRemoveObj( *ppObj[nDelCount-i] ) ); +/*N*/ +/*N*/ for (i=1; i<=nDelCount; i++) +/*N*/ pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() ); +/*N*/ +/*N*/ delete[] ppObj; +/*N*/ } +/*N*/ +/*N*/ return ( nDelCount != 0 ); +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::MarkInvalid(BOOL& rOverflow) +/*N*/ { +/*N*/ rOverflow = FALSE; +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return FALSE; +/*N*/ +/*N*/ BOOL bDeleted = DeleteAll( SC_DET_CIRCLES ); // nur die Kreise +/*N*/ +/*N*/ ScDetectiveData aData( pModel ); +/*N*/ long nInsCount = 0; +/*N*/ +/*N*/ // Stellen suchen, wo Gueltigkeit definiert ist +/*N*/ +/*N*/ ScDocAttrIterator aAttrIter( pDoc, nTab, 0,0,MAXCOL,MAXROW ); +/*N*/ USHORT nCol, nRow1, nRow2; +/*N*/ const ScPatternAttr* pPattern = aAttrIter.GetNext( nCol, nRow1, nRow2 ); +/*N*/ while ( pPattern && nInsCount < SC_DET_MAXCIRCLE ) +/*N*/ { +/*N*/ ULONG nIndex = ((const SfxUInt32Item&)pPattern->GetItem(ATTR_VALIDDATA)).GetValue(); +/*N*/ if (nIndex) +/*N*/ { +/*N*/ const ScValidationData* pData = pDoc->GetValidationEntry( nIndex ); +/*N*/ if ( pData ) +/*N*/ { +/*N*/ // Zellen in dem Bereich durchgehen +/*N*/ +/*N*/ BOOL bMarkEmpty = !pData->IsIgnoreBlank(); +/*N*/ USHORT nNextRow = nRow1; +/*N*/ USHORT nRow; +/*N*/ ScCellIterator aCellIter( pDoc, nCol,nRow1,nTab, nCol,nRow2,nTab ); +/*N*/ ScBaseCell* pCell = aCellIter.GetFirst(); +/*N*/ while ( pCell && nInsCount < SC_DET_MAXCIRCLE ) +/*N*/ { +/*N*/ USHORT nCellRow = aCellIter.GetRow(); +/*N*/ if ( bMarkEmpty ) +/*N*/ for ( nRow = nNextRow; nRow < nCellRow && nInsCount < SC_DET_MAXCIRCLE; nRow++ ) +/*N*/ { +/*N*/ DrawCircle( nCol, nRow, aData ); +/*N*/ ++nInsCount; +/*N*/ } +/*N*/ if ( !pData->IsDataValid( pCell, ScAddress( nCol, nCellRow, nTab ) ) ) +/*N*/ { +/*N*/ DrawCircle( nCol, nCellRow, aData ); +/*N*/ ++nInsCount; +/*N*/ } +/*N*/ nNextRow = nCellRow + 1; +/*N*/ pCell = aCellIter.GetNext(); +/*N*/ } +/*N*/ if ( bMarkEmpty ) +/*N*/ for ( nRow = nNextRow; nRow <= nRow2 && nInsCount < SC_DET_MAXCIRCLE; nRow++ ) +/*N*/ { +/*N*/ DrawCircle( nCol, nRow, aData ); +/*N*/ ++nInsCount; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pPattern = aAttrIter.GetNext( nCol, nRow1, nRow2 ); +/*N*/ } +/*N*/ +/*N*/ if ( nInsCount >= SC_DET_MAXCIRCLE ) +/*N*/ rOverflow = TRUE; +/*N*/ +/*N*/ return ( bDeleted || nInsCount != 0 ); +/*N*/ } + +/*N*/ SdrObject* ScDetectiveFunc::ShowCommentUser( USHORT nCol, USHORT nRow, const String& rUserText, +/*N*/ const Rectangle& rVisible, BOOL bLeft, BOOL bForce, +/*N*/ SdrPage* pDestPage ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel && !pDestPage) +/*N*/ return NULL; +/*N*/ +/*N*/ SdrObject* pObject = NULL; +/*N*/ ScPostIt aNote; +/*N*/ BOOL bFound = pDoc->GetNote( nCol, nRow, nTab, aNote ); +/*N*/ if ( bFound || bForce || rUserText.Len() ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SdrModel* pDestModel = pModel; +/*N*/ } +/*N*/ +/*N*/ return pObject; +/*N*/ } + +/*N*/ SdrObject* ScDetectiveFunc::ShowComment( USHORT nCol, USHORT nRow, BOOL bForce, SdrPage* pDestPage ) +/*N*/ { +/*N*/ return ShowCommentUser( nCol, nRow, String(), Rectangle(0,0,0,0), FALSE, bForce, pDestPage ); +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::HideComment( USHORT nCol, USHORT nRow ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return FALSE; +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ pPage->RecalcObjOrdNums(); +/*N*/ BOOL bDone = FALSE; +/*N*/ +/*N*/ SdrObjListIter aIter( *pPage, IM_FLAT ); +/*N*/ SdrObject* pObject = aIter.Next(); +/*N*/ while (pObject && !bDone) +/*N*/ { +/*N*/ if ( pObject->GetLayer() == SC_LAYER_INTERN && pObject->ISA( SdrCaptionObj ) ) +/*N*/ { +/*N*/ ScDrawObjData* pData = ScDrawLayer::GetObjData( pObject ); +/*N*/ if ( pData && nCol == pData->aStt.nCol && nRow == pData->aStt.nRow ) +/*N*/ { +/*N*/ pModel->AddCalcUndo( new SdrUndoRemoveObj( *pObject ) ); +/*N*/ pPage->RemoveObject( pObject->GetOrdNum() ); +/*N*/ bDone = TRUE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pObject = aIter.Next(); +/*N*/ } +/*N*/ +/*N*/ return bDone; +/*N*/ } + +/*N*/ void ScDetectiveFunc::UpdateAllComments() +/*N*/ { +/*N*/ // for all caption objects, update attributes and SpecialTextBoxShadow flag +/*N*/ // (on all tables - nTab is ignored!) +/*N*/ +/*N*/ // no undo actions, this is refreshed after undo +/*N*/ +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return; +/*N*/ +/*N*/ ScCommentData aData( pDoc, pModel ); +/*N*/ +/*N*/ USHORT nTabCount = pDoc->GetTableCount(); +/*N*/ for (USHORT nObjTab=0; nObjTab<nTabCount; nObjTab++) +/*N*/ { +/*N*/ SdrPage* pPage = pModel->GetPage(nObjTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ if (pPage) +/*N*/ { +/*N*/ SdrObjListIter aIter( *pPage, IM_FLAT ); +/*N*/ SdrObject* pObject = aIter.Next(); +/*N*/ while (pObject) +/*N*/ { +/*?*/ if ( pObject->GetLayer() == SC_LAYER_INTERN && pObject->ISA( SdrCaptionObj ) ) +/*?*/ { +/*?*/ SdrCaptionObj* pCaption = (SdrCaptionObj*)pObject; +/*?*/ +/*?*/ SfxItemSet& rAttrSet = aData.GetCaptionSet(); +/*?*/ +/*?*/ //-/ pCaption->SetAttributes( rAttrSet, FALSE ); +/*?*/ pCaption->SetItemSetAndBroadcast(rAttrSet); +/*?*/ +/*?*/ pCaption->SetSpecialTextBoxShadow(); +/*?*/ } +/*?*/ +/*?*/ pObject = aIter.Next(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void ScDetectiveFunc::UpdateAllArrowColors() // detective.sdc +/*N*/ { +/*N*/ // no undo actions necessary +/*N*/ +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return; +/*N*/ +/*N*/ USHORT nTabCount = pDoc->GetTableCount(); +/*N*/ for (USHORT nObjTab=0; nObjTab<nTabCount; nObjTab++) +/*N*/ { +/*N*/ SdrPage* pPage = pModel->GetPage(nObjTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ if (pPage) +/*N*/ { +/*N*/ SdrObjListIter aIter( *pPage, IM_FLAT ); +/*N*/ SdrObject* pObject = aIter.Next(); +/*N*/ while (pObject) +/*N*/ { +/*N*/ if ( pObject->GetLayer() == SC_LAYER_INTERN ) +/*N*/ { +/*N*/ BOOL bArrow = FALSE; +/*N*/ BOOL bError = FALSE; +/*N*/ +/*N*/ ScAddress aPos; +/*N*/ ScRange aSource; +/*N*/ BOOL bDummy; +/*N*/ ScDetectiveObjType eType = GetDetectiveObjectType( pObject, aPos, aSource, bDummy ); +/*N*/ if ( eType == SC_DETOBJ_ARROW || eType == SC_DETOBJ_TOOTHERTAB ) +/*N*/ { +/*N*/ // source is valid, determine error flag from source range +/*N*/ +/*N*/ ScTripel aStart( aSource.aStart.Col(), aSource.aStart.Row(), aSource.aStart.Tab() ); +/*N*/ ScTripel aEnd( aSource.aEnd.Col(), aSource.aEnd.Row(), aSource.aEnd.Tab() ); +/*N*/ ScTripel aErrPos; +/*N*/ if ( HasError( aStart, aEnd, aErrPos ) ) +/*N*/ bError = TRUE; +/*N*/ else +/*N*/ bArrow = TRUE; +/*N*/ } +/*N*/ else if ( eType == SC_DETOBJ_FROMOTHERTAB ) +/*N*/ { +/*N*/ // source range is no longer known, take error flag from formula itself +/*N*/ // (this means, if the formula has an error, all references to other tables +/*N*/ // are marked red) +/*N*/ +/*N*/ ScTripel aFormulaPos( aPos.Col(), aPos.Row(), aPos.Tab() ); +/*N*/ ScTripel aErrPos; +/*N*/ if ( HasError( aFormulaPos, aFormulaPos, aErrPos ) ) +/*N*/ bError = TRUE; +/*N*/ else +/*N*/ bArrow = TRUE; +/*N*/ } +/*N*/ else if ( eType == SC_DETOBJ_CIRCLE ) +/*N*/ { +/*N*/ // circles (error marks) are always red +/*N*/ +/*N*/ bError = TRUE; +/*N*/ } +/*N*/ else if ( eType == SC_DETOBJ_NONE ) +/*N*/ { +/*N*/ // frame for area reference has no ObjType, always gets arrow color +/*N*/ +/*N*/ if ( pObject->ISA( SdrRectObj ) && !pObject->ISA( SdrCaptionObj ) ) +/*N*/ { +/*N*/ bArrow = TRUE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( bArrow || bError ) +/*N*/ { +/*N*/ ColorData nColorData = ( bError ? GetErrorColor() : GetArrowColor() ); +/*N*/ pObject->SetItem( XLineColorItem( String(), Color( nColorData ) ) ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pObject = aIter.Next(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::FindFrameForObject( SdrObject* pObject, ScRange& rRange ) // detective.sdc +/*N*/ { +/*N*/ // find the rectangle for an arrow (always the object directly before the arrow) +/*N*/ // rRange must be initialized to the source cell of the arrow (start of area) +/*N*/ +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) return FALSE; +/*N*/ +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ if (!pPage) return FALSE; +/*N*/ +/*N*/ ULONG nPos = pPage->GetContainer().GetPos( pObject ); +/*N*/ if ( nPos != CONTAINER_ENTRY_NOTFOUND && nPos > 0 ) +/*N*/ { +/*N*/ SdrObject* pPrevObj = pPage->GetObj( nPos - 1 ); +/*N*/ if ( pPrevObj && pPrevObj->GetLayer() == SC_LAYER_INTERN && pPrevObj->ISA(SdrRectObj) ) +/*N*/ { +/*N*/ ScDrawObjData* pPrevData = ScDrawLayer::GetObjData( pPrevObj ); +/*N*/ if ( pPrevData && pPrevData->bValidStart && pPrevData->bValidEnd ) +/*N*/ { +/*N*/ if ( pPrevData->aStt.nCol == rRange.aStart.Col() && +/*N*/ pPrevData->aStt.nRow == rRange.aStart.Row() && +/*N*/ pPrevData->aStt.nTab == rRange.aStart.Tab() ) +/*N*/ { +/*N*/ rRange.aEnd.Set( pPrevData->aEnd.nCol, +/*N*/ pPrevData->aEnd.nRow, +/*N*/ pPrevData->aEnd.nTab ); +/*N*/ return TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/*N*/ ScDetectiveObjType ScDetectiveFunc::GetDetectiveObjectType( SdrObject* pObject, +/*N*/ ScAddress& rPosition, ScRange& rSource, BOOL& rRedLine ) +/*N*/ { +/*N*/ rRedLine = FALSE; // detective.sdc +/*N*/ ScDetectiveObjType eType = SC_DETOBJ_NONE; +/*N*/ +/*N*/ if ( pObject && pObject->GetLayer() == SC_LAYER_INTERN ) +/*N*/ { +/*N*/ ScDrawObjData* pData = ScDrawLayer::GetObjData( pObject ); +/*N*/ if ( pObject->IsPolyObj() && pObject->GetPointCount() == 2 ) +/*N*/ { +/*N*/ // line object -> arrow +/*N*/ +/*N*/ if ( pData->bValidStart ) +/*N*/ eType = ( pData->bValidEnd ) ? SC_DETOBJ_ARROW : SC_DETOBJ_TOOTHERTAB; +/*N*/ else if ( pData->bValidEnd ) +/*N*/ eType = SC_DETOBJ_FROMOTHERTAB; +/*N*/ +/*N*/ if ( pData->bValidStart ) +/*N*/ rSource = ScRange( pData->aStt.nCol, pData->aStt.nRow, pData->aStt.nTab ); +/*N*/ if ( pData->bValidEnd ) +/*N*/ rPosition = ScAddress( pData->aEnd.nCol, pData->aEnd.nRow, pData->aEnd.nTab ); +/*N*/ +/*N*/ if ( pData->bValidStart && lcl_HasThickLine( *pObject ) ) +/*N*/ { +/*N*/ // thick line -> look for frame before this object +/*N*/ +/*N*/ FindFrameForObject( pObject, rSource ); // modifies rSource +/*N*/ } +/*N*/ +/*N*/ ColorData nObjColor = ((const XLineColorItem&)pObject->GetItem(XATTR_LINECOLOR)).GetValue().GetColor(); +/*N*/ if ( nObjColor == GetErrorColor() && nObjColor != GetArrowColor() ) +/*N*/ rRedLine = TRUE; +/*N*/ } +/*N*/ else if ( pObject->ISA(SdrCircObj) ) +/*N*/ { +/*N*/ if ( pData->bValidStart ) +/*N*/ { +/*N*/ // cell position is returned in rPosition +/*N*/ +/*N*/ rPosition = ScAddress( pData->aStt.nCol, pData->aStt.nRow, pData->aStt.nTab ); +/*N*/ eType = SC_DETOBJ_CIRCLE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ return eType; +/*N*/ } + +/*N*/ void ScDetectiveFunc::InsertObject( ScDetectiveObjType eType, +/*N*/ const ScAddress& rPosition, const ScRange& rSource, +/*N*/ BOOL bRedLine ) +/*N*/ { +DBG_BF_ASSERT(0, "STRIP"); //STRIP001 ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ } + +// static +/*N*/ ColorData ScDetectiveFunc::GetArrowColor() +/*N*/ { +/*N*/ if (!bColorsInitialized) +/*N*/ InitializeColors(); +/*N*/ return nArrowColor; +/*N*/ } + +// static +/*N*/ ColorData ScDetectiveFunc::GetErrorColor() +/*N*/ { +/*N*/ if (!bColorsInitialized) +/*N*/ InitializeColors(); +/*N*/ return nErrorColor; +/*N*/ } + +// static +/*N*/ ColorData ScDetectiveFunc::GetCommentColor() +/*N*/ { +/*N*/ if (!bColorsInitialized) +/*N*/ InitializeColors(); +/*N*/ return nCommentColor; +/*N*/ } + +// static +/*N*/ void ScDetectiveFunc::InitializeColors() +/*N*/ { +/*N*/ // may be called several times to update colors from configuration +/*N*/ +/*N*/ const ColorConfig& rColorCfg = SC_MOD()->GetColorConfig(); +/*N*/ nArrowColor = rColorCfg.GetColorValue(CALCDETECTIVE).nColor; +/*N*/ nErrorColor = rColorCfg.GetColorValue(CALCDETECTIVEERROR).nColor; +/*N*/ nCommentColor = rColorCfg.GetColorValue(CALCNOTESBACKGROUND).nColor; +/*N*/ +/*N*/ bColorsInitialized = TRUE; +/*N*/ } + +// static + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_docoptio.cxx b/binfilter/bf_sc/source/core/tool/sc_docoptio.cxx new file mode 100644 index 000000000000..1ea7d1538e72 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_docoptio.cxx @@ -0,0 +1,410 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <bf_svtools/zforlist.hxx> + + +#include "docoptio.hxx" +#include "rechead.hxx" +#include "bf_sc.hrc" +#include "miscuno.hxx" +namespace binfilter { + +using namespace utl; +using namespace rtl; +using namespace ::com::sun::star::uno; + +//------------------------------------------------------------------------ + +#define SC_VERSION ((USHORT)251) + + +//------------------------------------------------------------------------ + +//! these functions should be moved to some header file +inline long HMMToTwips(long nHMM) { return (nHMM * 72 + 63) / 127; } + + +//------------------------------------------------------------------------ + +/*N*/ USHORT lcl_GetDefaultTabDist() +/*N*/ { +/*N*/ if ( ScOptionsUtil::IsMetricSystem() ) +/*N*/ return 709; // 1,25 cm +/*N*/ else +/*N*/ return 720; // 1/2" +/*N*/ } + +//======================================================================== +// ScDocOptions - Dokument-Optionen +//======================================================================== + +/*N*/ ScDocOptions::ScDocOptions() +/*N*/ { +/*N*/ ResetDocOptions(); +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ ScDocOptions::ScDocOptions( const ScDocOptions& rCpy ) +/*N*/ : bIsIgnoreCase( rCpy.bIsIgnoreCase ), +/*N*/ bIsIter( rCpy.bIsIter ), +/*N*/ nIterCount( rCpy.nIterCount ), +/*N*/ fIterEps( rCpy.fIterEps ), +/*N*/ nPrecStandardFormat( rCpy.nPrecStandardFormat ), +/*N*/ nDay( rCpy.nDay ), +/*N*/ nMonth( rCpy.nMonth ), +/*N*/ nYear( rCpy.nYear ), +/*N*/ nYear2000( rCpy.nYear2000 ), +/*N*/ nTabDistance( rCpy.nTabDistance ), +/*N*/ bCalcAsShown( rCpy.bCalcAsShown ), +/*N*/ bMatchWholeCell( rCpy.bMatchWholeCell ), +/*N*/ bDoAutoSpell( rCpy.bDoAutoSpell ), +/*N*/ bLookUpColRowNames( rCpy.bLookUpColRowNames ), +/*N*/ bFormulaRegexEnabled( rCpy.bFormulaRegexEnabled ) +/*N*/ { +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ ScDocOptions::~ScDocOptions() +/*N*/ { +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ void ScDocOptions::Save(SvStream& rStream, BOOL bConfig) const +/*N*/ { +/*N*/ ScWriteHeader aHdr( rStream, 28 ); +/*N*/ +/*N*/ rStream << bIsIgnoreCase; +/*N*/ rStream << bIsIter; +/*N*/ rStream << nIterCount; +/*N*/ rStream << fIterEps; +/*N*/ rStream << nPrecStandardFormat; +/*N*/ rStream << nDay; +/*N*/ rStream << nMonth; +/*N*/ rStream << nYear; +/*N*/ rStream << nTabDistance; +/*N*/ rStream << bCalcAsShown; +/*N*/ rStream << bMatchWholeCell; +/*N*/ rStream << bDoAutoSpell; +/*N*/ rStream << bLookUpColRowNames; +/*N*/ +/*N*/ if ( bConfig || rStream.GetVersion() > SOFFICE_FILEFORMAT_40 ) // nicht bei 4.0 Export +/*N*/ { +/*N*/ if ( !bConfig && 1901 <= nYear2000 && nYear2000 <= 1999 ) +/*N*/ { // fuer SO5 auf altes Format zweistellig abbilden +/*N*/ rStream << (USHORT) (nYear2000 - 1901); +/*N*/ } +/*N*/ else +/*N*/ { // neues Format vierstellig, beliebiges Jahrhundert +/*N*/ // erzeugt in SO5 vor src513e ein Warning beim Laden +/*N*/ rStream << (USHORT) 29; // Dummy, alter SO5 Default +/*N*/ rStream << nYear2000; // echter Wert +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void ScDocOptions::Load(SvStream& rStream) +/*N*/ { +/*N*/ ScReadHeader aHdr( rStream ); +/*N*/ +/*N*/ rStream >> bIsIgnoreCase; +/*N*/ rStream >> bIsIter; +/*N*/ rStream >> nIterCount; +/*N*/ rStream >> fIterEps; +/*N*/ rStream >> nPrecStandardFormat; +/*N*/ rStream >> nDay; +/*N*/ rStream >> nMonth; +/*N*/ rStream >> nYear; +/*N*/ if ( aHdr.BytesLeft() ) +/*N*/ rStream >> nTabDistance; +/*N*/ else +/*?*/ nTabDistance = lcl_GetDefaultTabDist(); +/*N*/ if ( aHdr.BytesLeft() ) +/*N*/ rStream >> bCalcAsShown; +/*N*/ else +/*N*/ bCalcAsShown = FALSE; +/*N*/ if ( aHdr.BytesLeft() ) +/*N*/ rStream >> bMatchWholeCell; +/*N*/ else +/*N*/ bMatchWholeCell = FALSE; +/*N*/ if ( aHdr.BytesLeft() ) +/*N*/ rStream >> bDoAutoSpell; +/*N*/ else +/*N*/ bDoAutoSpell = FALSE; +/*N*/ if ( aHdr.BytesLeft() ) +/*N*/ rStream >> bLookUpColRowNames; +/*N*/ else +/*N*/ bLookUpColRowNames = TRUE; +/*N*/ if ( aHdr.BytesLeft() ) +/*N*/ { +/*N*/ rStream >> nYear2000; // SO5 ab 24.06.98 +/*N*/ // SO51 ab src513e +/*N*/ if ( aHdr.BytesLeft() ) +/*N*/ rStream >> nYear2000; // der echte Wert +/*N*/ else +/*N*/ nYear2000 += 1901; // altes zweistelliges auf neues vierstelliges +/*N*/ } +/*N*/ else +/*N*/ nYear2000 = 18 + 1901; // alter Wert vor SO5 +/*N*/ } + +/*N*/ void ScDocOptions::ResetDocOptions() +/*N*/ { +/*N*/ bIsIgnoreCase = FALSE; +/*N*/ bIsIter = FALSE; +/*N*/ nIterCount = 100; +/*N*/ fIterEps = 1.0E-3; +/*N*/ nPrecStandardFormat = 2; +/*N*/ nDay = 30; +/*N*/ nMonth = 12; +/*N*/ nYear = 1899; +/*N*/ nYear2000 = SvNumberFormatter::GetYear2000Default(); +/*N*/ nTabDistance = lcl_GetDefaultTabDist(); +/*N*/ bCalcAsShown = FALSE; +/*N*/ bMatchWholeCell = TRUE; +/*N*/ bDoAutoSpell = FALSE; +/*N*/ bLookUpColRowNames = TRUE; +/*N*/ bFormulaRegexEnabled= TRUE; +/*N*/ } + +//======================================================================== +// ScTpCalcItem - Daten fuer die CalcOptions-TabPage +//======================================================================== + + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + + +//================================================================== +// Config Item containing document options +//================================================================== + +#define CFGPATH_CALC "Office.Calc/Calculate" + +#define SCCALCOPT_ITER_ITER 0 +#define SCCALCOPT_ITER_STEPS 1 +#define SCCALCOPT_ITER_MINCHG 2 +#define SCCALCOPT_DATE_DAY 3 +#define SCCALCOPT_DATE_MONTH 4 +#define SCCALCOPT_DATE_YEAR 5 +#define SCCALCOPT_DECIMALS 6 +#define SCCALCOPT_CASESENSITIVE 7 +#define SCCALCOPT_PRECISION 8 +#define SCCALCOPT_SEARCHCRIT 9 +#define SCCALCOPT_FINDLABEL 10 +#define SCCALCOPT_REGEX 11 +#define SCCALCOPT_COUNT 12 + +#define CFGPATH_DOCLAYOUT "Office.Calc/Layout/Other" + +#define SCDOCLAYOUTOPT_TABSTOP 0 +#define SCDOCLAYOUTOPT_COUNT 1 + + +/*N*/ Sequence<OUString> ScDocCfg::GetCalcPropertyNames() +/*N*/ { +/*N*/ static const char* aPropNames[] = +/*N*/ { +/*N*/ "IterativeReference/Iteration", // SCCALCOPT_ITER_ITER +/*N*/ "IterativeReference/Steps", // SCCALCOPT_ITER_STEPS +/*N*/ "IterativeReference/MinimumChange", // SCCALCOPT_ITER_MINCHG +/*N*/ "Other/Date/DD", // SCCALCOPT_DATE_DAY +/*N*/ "Other/Date/MM", // SCCALCOPT_DATE_MONTH +/*N*/ "Other/Date/YY", // SCCALCOPT_DATE_YEAR +/*N*/ "Other/DecimalPlaces", // SCCALCOPT_DECIMALS +/*N*/ "Other/CaseSensitive", // SCCALCOPT_CASESENSITIVE +/*N*/ "Other/Precision", // SCCALCOPT_PRECISION +/*N*/ "Other/SearchCriteria", // SCCALCOPT_SEARCHCRIT +/*N*/ "Other/FindLabel", // SCCALCOPT_FINDLABEL +/*N*/ "Other/RegularExpressions" // SCCALCOPT_REGEX +/*N*/ }; +/*N*/ Sequence<OUString> aNames(SCCALCOPT_COUNT); +/*N*/ OUString* pNames = aNames.getArray(); +/*N*/ for(int i = 0; i < SCCALCOPT_COUNT; i++) +/*N*/ pNames[i] = OUString::createFromAscii(aPropNames[i]); +/*N*/ +/*N*/ return aNames; +/*N*/ } + +/*N*/ Sequence<OUString> ScDocCfg::GetLayoutPropertyNames() +/*N*/ { +/*N*/ static const char* aPropNames[] = +/*N*/ { +/*N*/ "TabStop/NonMetric" // SCDOCLAYOUTOPT_TABSTOP +/*N*/ }; +/*N*/ Sequence<OUString> aNames(SCDOCLAYOUTOPT_COUNT); +/*N*/ OUString* pNames = aNames.getArray(); +/*N*/ for(int i = 0; i < SCDOCLAYOUTOPT_COUNT; i++) +/*N*/ pNames[i] = OUString::createFromAscii(aPropNames[i]); +/*N*/ +/*N*/ // adjust for metric system +/*N*/ if (ScOptionsUtil::IsMetricSystem()) +/*N*/ pNames[SCDOCLAYOUTOPT_TABSTOP] = OUString::createFromAscii( "TabStop/Metric" ); +/*N*/ +/*N*/ return aNames; +/*N*/ } + +/*N*/ ScDocCfg::ScDocCfg() : +/*N*/ aCalcItem( OUString::createFromAscii( CFGPATH_CALC ) ), +/*N*/ aLayoutItem( OUString::createFromAscii( CFGPATH_DOCLAYOUT ) ) +/*N*/ { +/*N*/ sal_Int32 nIntVal; +/*N*/ double fDoubleVal; +/*N*/ +/*N*/ Sequence<OUString> aNames; +/*N*/ Sequence<Any> aValues; +/*N*/ const Any* pValues = NULL; +/*N*/ +/*N*/ USHORT nDateDay, nDateMonth, nDateYear; +/*N*/ GetDate( nDateDay, nDateMonth, nDateYear ); +/*N*/ +/*N*/ aNames = GetCalcPropertyNames(); +/*N*/ aValues = aCalcItem.GetProperties(aNames); +/*N*/ aCalcItem.EnableNotification(aNames); +/*N*/ pValues = aValues.getConstArray(); +/*N*/ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed"); +/*N*/ if(aValues.getLength() == aNames.getLength()) +/*N*/ { +/*N*/ for(int nProp = 0; nProp < aNames.getLength(); nProp++) +/*N*/ { +/*N*/ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing"); +/*N*/ if(pValues[nProp].hasValue()) +/*N*/ { +/*N*/ switch(nProp) +/*N*/ { +/*N*/ case SCCALCOPT_ITER_ITER: +/*N*/ SetIter( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCCALCOPT_ITER_STEPS: +/*N*/ if (pValues[nProp] >>= nIntVal) SetIterCount( (USHORT) nIntVal ); +/*N*/ break; +/*N*/ case SCCALCOPT_ITER_MINCHG: +/*N*/ if (pValues[nProp] >>= fDoubleVal) SetIterEps( fDoubleVal ); +/*N*/ break; +/*N*/ case SCCALCOPT_DATE_DAY: +/*N*/ if (pValues[nProp] >>= nIntVal) nDateDay = (USHORT) nIntVal; +/*N*/ break; +/*N*/ case SCCALCOPT_DATE_MONTH: +/*N*/ if (pValues[nProp] >>= nIntVal) nDateMonth = (USHORT) nIntVal; +/*N*/ break; +/*N*/ case SCCALCOPT_DATE_YEAR: +/*N*/ if (pValues[nProp] >>= nIntVal) nDateYear = (USHORT) nIntVal; +/*N*/ break; +/*N*/ case SCCALCOPT_DECIMALS: +/*N*/ if (pValues[nProp] >>= nIntVal) SetStdPrecision( (USHORT) nIntVal ); +/*N*/ break; +/*N*/ case SCCALCOPT_CASESENSITIVE: +/*N*/ // content is reversed +/*N*/ SetIgnoreCase( !ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCCALCOPT_PRECISION: +/*N*/ SetCalcAsShown( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCCALCOPT_SEARCHCRIT: +/*N*/ SetMatchWholeCell( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCCALCOPT_FINDLABEL: +/*N*/ SetLookUpColRowNames( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCCALCOPT_REGEX : +/*N*/ SetFormulaRegexEnabled( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ aCalcItem.SetCommitLink( LINK( this, ScDocCfg, CalcCommitHdl ) ); +/*N*/ +/*N*/ SetDate( nDateDay, nDateMonth, nDateYear ); +/*N*/ +/*N*/ aNames = GetLayoutPropertyNames(); +/*N*/ aValues = aLayoutItem.GetProperties(aNames); +/*N*/ aLayoutItem.EnableNotification(aNames); +/*N*/ pValues = aValues.getConstArray(); +/*N*/ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed"); +/*N*/ if(aValues.getLength() == aNames.getLength()) +/*N*/ { +/*N*/ for(int nProp = 0; nProp < aNames.getLength(); nProp++) +/*N*/ { +/*N*/ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing"); +/*N*/ if(pValues[nProp].hasValue()) +/*N*/ { +/*N*/ switch(nProp) +/*N*/ { +/*N*/ case SCDOCLAYOUTOPT_TABSTOP: +/*N*/ // TabDistance in ScDocOptions is in twips +/*N*/ if (pValues[nProp] >>= nIntVal) +/*N*/ SetTabDistance( (USHORT) HMMToTwips( nIntVal ) ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ aLayoutItem.SetCommitLink( LINK( this, ScDocCfg, LayoutCommitHdl ) ); +/*N*/ } + +/*N*/ IMPL_LINK( ScDocCfg, CalcCommitHdl, void *, EMPTYARG ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 Sequence<OUString> aNames = GetCalcPropertyNames(); +/*N*/ return 0; +/*N*/ } + +/*N*/ IMPL_LINK( ScDocCfg, LayoutCommitHdl, void *, EMPTYARG ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 Sequence<OUString> aNames = GetLayoutPropertyNames(); +/*N*/ return 0; +/*N*/ } + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_editutil.cxx b/binfilter/bf_sc/source/core/tool/sc_editutil.cxx new file mode 100644 index 000000000000..dec195f79768 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_editutil.cxx @@ -0,0 +1,511 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "scitems.hxx" +#include <bf_svx/eeitem.hxx> +#define ITEMID_FIELD EE_FEATURE_FIELD + +#include <bf_svtools/colorcfg.hxx> +#include <bf_svx/editstat.hxx> + + +#include <bf_svtools/poolitem.hxx> + +#include <bf_svx/itemdata.hxx> + +#include <tools/date.hxx> + +#include <tools/time.hxx> + +#include <bf_svx/flditem.hxx> +#include <bf_svtools/inethist.hxx> +#include <bf_svtools/syslocale.hxx> +#ifndef _SVSTDARR_USHORTS +#define _SVSTDARR_USHORTS +#endif + +#include "editutil.hxx" +#include "docpool.hxx" +#include "patattr.hxx" +#include "scmod.hxx" +namespace binfilter { + +// STATIC DATA ----------------------------------------------------------- + +// Delimiters zusaetzlich zu EditEngine-Default: + +const sal_Char __FAR_DATA ScEditUtil::pCalcDelimiters[] = "=();+-*/^&<>"; + + +//------------------------------------------------------------------------ + +/*N*/ String ScEditUtil::ModifyDelimiters( const String& rOld ) +/*N*/ { +/*N*/ String aRet = rOld; +/*N*/ aRet.EraseAllChars( '_' ); // underscore is used in function argument names +/*N*/ aRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM( pCalcDelimiters ) ); +/*N*/ return aRet; +/*N*/ } + +/*N*/ String ScEditUtil::GetSpaceDelimitedString( const EditEngine& rEngine ) +/*N*/ { +/*N*/ String aRet; +/*N*/ USHORT nParCount = rEngine.GetParagraphCount(); +/*N*/ for (USHORT nPar=0; nPar<nParCount; nPar++) +/*N*/ { +/*N*/ if (nPar > 0) +/*N*/ aRet += ' '; +/*N*/ aRet += rEngine.GetText( nPar ); +/*N*/ } +/*N*/ return aRet; +/*N*/ } + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + +/*N*/ ScEditAttrTester::ScEditAttrTester( EditEngine* pEng ) : +/*N*/ pEngine( pEng ), +/*N*/ pEditAttrs( NULL ), +/*N*/ bNeedsObject( FALSE ), +/*N*/ bNeedsCellAttr( FALSE ) +/*N*/ { +/*N*/ if ( pEngine->GetParagraphCount() > 1 ) +/*N*/ { +/*N*/ bNeedsObject = TRUE; //! Zellatribute finden ? +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ const SfxPoolItem* pItem = NULL; +/*N*/ pEditAttrs = new SfxItemSet( pEngine->GetAttribs( +/*N*/ ESelection(0,0,0,pEngine->GetTextLen(0)) ) ); +/*N*/ const SfxItemPool* pEditPool = pEditAttrs->GetPool(); +/*N*/ +/*N*/ for (USHORT nId = EE_CHAR_START; nId <= EE_CHAR_END && !bNeedsObject; nId++) +/*N*/ { +/*N*/ SfxItemState eState = pEditAttrs->GetItemState( nId, FALSE, &pItem ); +/*N*/ if (eState == SFX_ITEM_DONTCARE) +/*N*/ bNeedsObject = TRUE; +/*N*/ else if (eState == SFX_ITEM_SET) +/*N*/ { +/*N*/ if ( nId == EE_CHAR_ESCAPEMENT || nId == EE_CHAR_PAIRKERNING || +/*N*/ nId == EE_CHAR_KERNING || nId == EE_CHAR_XMLATTRIBS ) +/*N*/ { +/*N*/ // Escapement and kerning are kept in EditEngine because there are no +/*N*/ // corresponding cell format items. User defined attributes are kept in +/*N*/ // EditEngine because "user attributes applied to all the text" is different +/*N*/ // from "user attributes applied to the cell". +/*N*/ +/*N*/ if ( *pItem != pEditPool->GetDefaultItem(nId) ) +/*N*/ bNeedsObject = TRUE; +/*N*/ } +/*N*/ else +/*N*/ if (!bNeedsCellAttr) +/*N*/ if ( *pItem != pEditPool->GetDefaultItem(nId) ) +/*N*/ bNeedsCellAttr = TRUE; +/*N*/ // SetDefaults an der EditEngine setzt Pool-Defaults +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // Feldbefehle enthalten? +/*N*/ +/*N*/ SfxItemState eFieldState = pEditAttrs->GetItemState( EE_FEATURE_FIELD, FALSE ); +/*N*/ if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET ) +/*N*/ bNeedsObject = TRUE; +/*N*/ +/*N*/ // not converted characters? +/*N*/ +/*N*/ SfxItemState eConvState = pEditAttrs->GetItemState( EE_FEATURE_NOTCONV, FALSE ); +/*N*/ if ( eConvState == SFX_ITEM_DONTCARE || eConvState == SFX_ITEM_SET ) +/*N*/ bNeedsObject = TRUE; +/*N*/ } +/*N*/ } + +/*N*/ ScEditAttrTester::~ScEditAttrTester() +/*N*/ { +/*N*/ delete pEditAttrs; +/*N*/ } + + +//------------------------------------------------------------------------ + +/*N*/ ScEnginePoolHelper::ScEnginePoolHelper( SfxItemPool* pEnginePoolP, +/*N*/ BOOL bDeleteEnginePoolP ) +/*N*/ : +/*N*/ pEnginePool( pEnginePoolP ), +/*N*/ bDeleteEnginePool( bDeleteEnginePoolP ), +/*N*/ pDefaults( NULL ), +/*N*/ bDeleteDefaults( FALSE ) +/*N*/ { +/*N*/ } + + +/*N*/ ScEnginePoolHelper::ScEnginePoolHelper( const ScEnginePoolHelper& rOrg ) +/*N*/ : +/*N*/ pEnginePool( rOrg.bDeleteEnginePool ? rOrg.pEnginePool->Clone() : rOrg.pEnginePool ), +/*N*/ bDeleteEnginePool( rOrg.bDeleteEnginePool ), +/*N*/ pDefaults( NULL ), +/*N*/ bDeleteDefaults( FALSE ) +/*N*/ { +/*N*/ } + + +/*N*/ ScEnginePoolHelper::~ScEnginePoolHelper() +/*N*/ { +/*N*/ if ( bDeleteDefaults ) +/*N*/ delete pDefaults; +/*N*/ if ( bDeleteEnginePool ) +/*N*/ delete pEnginePool; +/*N*/ } + + +//------------------------------------------------------------------------ + +/*N*/ ScEditEngineDefaulter::ScEditEngineDefaulter( SfxItemPool* pEnginePoolP, +/*N*/ BOOL bDeleteEnginePoolP ) +/*N*/ : +/*N*/ ScEnginePoolHelper( pEnginePoolP, bDeleteEnginePoolP ), +/*N*/ EditEngine( pEnginePoolP ) +/*N*/ { +/*N*/ // All EditEngines use ScGlobal::GetEditDefaultLanguage as DefaultLanguage. +/*N*/ // DefaultLanguage for InputHandler's EditEngine is updated later. +/*N*/ +/*N*/ SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() ); +/*N*/ } + + +/*N*/ ScEditEngineDefaulter::ScEditEngineDefaulter( const ScEditEngineDefaulter& rOrg ) +/*N*/ : +/*N*/ ScEnginePoolHelper( rOrg ), +/*N*/ EditEngine( pEnginePool ) +/*N*/ { +/*N*/ SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() ); +/*N*/ } + + +/*N*/ ScEditEngineDefaulter::~ScEditEngineDefaulter() +/*N*/ { +/*N*/ } + + +/*N*/ void ScEditEngineDefaulter::SetDefaults( const SfxItemSet& rSet, BOOL bRememberCopy ) +/*N*/ { +/*N*/ if ( bRememberCopy ) +/*N*/ { +/*N*/ if ( bDeleteDefaults ) +/*N*/ delete pDefaults; +/*N*/ pDefaults = new SfxItemSet( rSet ); +/*N*/ bDeleteDefaults = TRUE; +/*N*/ } +/*N*/ const SfxItemSet& rNewSet = bRememberCopy ? *pDefaults : rSet; +/*N*/ BOOL bUndo = IsUndoEnabled(); +/*N*/ EnableUndo( FALSE ); +/*N*/ BOOL bUpdateMode = GetUpdateMode(); +/*N*/ if ( bUpdateMode ) +/*N*/ SetUpdateMode( FALSE ); +/*N*/ USHORT nPara = GetParagraphCount(); +/*N*/ for ( USHORT j=0; j<nPara; j++ ) +/*N*/ { +/*N*/ SetParaAttribs( j, rNewSet ); +/*N*/ } +/*N*/ if ( bUpdateMode ) +/*N*/ SetUpdateMode( TRUE ); +/*N*/ if ( bUndo ) +/*N*/ EnableUndo( TRUE ); +/*N*/ } + + +/*N*/ void ScEditEngineDefaulter::SetDefaults( SfxItemSet* pSet, BOOL bTakeOwnership ) +/*N*/ { +/*N*/ if ( bDeleteDefaults ) +/*N*/ delete pDefaults; +/*N*/ pDefaults = pSet; +/*N*/ bDeleteDefaults = bTakeOwnership; +/*N*/ if ( pDefaults ) +/*N*/ SetDefaults( *pDefaults, FALSE ); +/*N*/ } + + + + +/*N*/ void ScEditEngineDefaulter::SetText( const EditTextObject& rTextObject ) +/*N*/ { +/*N*/ BOOL bUpdateMode = GetUpdateMode(); +/*N*/ if ( bUpdateMode ) +/*N*/ SetUpdateMode( FALSE ); +/*N*/ EditEngine::SetText( rTextObject ); +/*N*/ if ( pDefaults ) +/*N*/ SetDefaults( *pDefaults, FALSE ); +/*N*/ if ( bUpdateMode ) +/*N*/ SetUpdateMode( TRUE ); +/*N*/ } + +/*N*/ void ScEditEngineDefaulter::SetTextNewDefaults( const EditTextObject& rTextObject, +/*N*/ const SfxItemSet& rSet, BOOL bRememberCopy ) +/*N*/ { +/*N*/ BOOL bUpdateMode = GetUpdateMode(); +/*N*/ if ( bUpdateMode ) +/*N*/ SetUpdateMode( FALSE ); +/*N*/ EditEngine::SetText( rTextObject ); +/*N*/ SetDefaults( rSet, bRememberCopy ); +/*N*/ if ( bUpdateMode ) +/*N*/ SetUpdateMode( TRUE ); +/*N*/ } + +/*N*/ void ScEditEngineDefaulter::SetTextNewDefaults( const EditTextObject& rTextObject, +/*N*/ SfxItemSet* pSet, BOOL bTakeOwnership ) +/*N*/ { +/*N*/ BOOL bUpdateMode = GetUpdateMode(); +/*N*/ if ( bUpdateMode ) +/*?*/ SetUpdateMode( FALSE ); +/*N*/ EditEngine::SetText( rTextObject ); +/*N*/ SetDefaults( pSet, bTakeOwnership ); +/*N*/ if ( bUpdateMode ) +/*?*/ SetUpdateMode( TRUE ); +/*N*/ } + + +/*N*/ void ScEditEngineDefaulter::SetText( const String& rText ) +/*N*/ { +/*N*/ BOOL bUpdateMode = GetUpdateMode(); +/*N*/ if ( bUpdateMode ) +/*N*/ SetUpdateMode( FALSE ); +/*N*/ EditEngine::SetText( rText ); +/*N*/ if ( pDefaults ) +/*?*/ SetDefaults( *pDefaults, FALSE ); +/*N*/ if ( bUpdateMode ) +/*N*/ SetUpdateMode( TRUE ); +/*N*/ } + +/*N*/ void ScEditEngineDefaulter::SetTextNewDefaults( const String& rText, +/*N*/ const SfxItemSet& rSet, BOOL bRememberCopy ) +/*N*/ { +/*N*/ BOOL bUpdateMode = GetUpdateMode(); +/*N*/ if ( bUpdateMode ) +/*N*/ SetUpdateMode( FALSE ); +/*N*/ EditEngine::SetText( rText ); +/*N*/ SetDefaults( rSet, bRememberCopy ); +/*N*/ if ( bUpdateMode ) +/*N*/ SetUpdateMode( TRUE ); +/*N*/ } + +/*N*/ void ScEditEngineDefaulter::SetTextNewDefaults( const String& rText, +/*N*/ SfxItemSet* pSet, BOOL bTakeOwnership ) +/*N*/ { +/*N*/ BOOL bUpdateMode = GetUpdateMode(); +/*N*/ if ( bUpdateMode ) +/*?*/ SetUpdateMode( FALSE ); +/*N*/ EditEngine::SetText( rText ); +/*N*/ SetDefaults( pSet, bTakeOwnership ); +/*N*/ if ( bUpdateMode ) +/*?*/ SetUpdateMode( TRUE ); +/*N*/ } + + + +//------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------ +// Feldbefehle fuer Kopf- und Fusszeilen +//------------------------------------------------------------------------ + +// +// Zahlen aus \sw\source\core\doc\numbers.cxx +// + + + +/*N*/ String lcl_GetNumStr( USHORT nNo, SvxNumType eType ) +/*N*/ { +/*N*/ String aTmpStr( '0' ); +/*N*/ if( nNo ) +/*N*/ { +/*N*/ switch( eType ) +/*N*/ { +/*?*/ case SVX_CHARS_UPPER_LETTER: +/*?*/ case SVX_CHARS_LOWER_LETTER: +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 aTmpStr = lcl_GetCharStr( nNo ); +/*?*/ break; +/*?*/ +/*?*/ case SVX_ROMAN_UPPER: +/*?*/ case SVX_ROMAN_LOWER: +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 aTmpStr = lcl_GetRomanStr( nNo ); +/*?*/ break; +/*?*/ +/*?*/ case SVX_NUMBER_NONE: +/*?*/ aTmpStr.Erase(); +/*?*/ break; +/*?*/ +/*?*/ // CHAR_SPECIAL: +/*?*/ // ???? +/*?*/ +/*?*/ // case ARABIC: ist jetzt default +/*N*/ default: +/*N*/ aTmpStr = String::CreateFromInt32( nNo ); +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ if( SVX_CHARS_UPPER_LETTER == eType || SVX_ROMAN_UPPER == eType ) +/*N*/ aTmpStr.ToUpperAscii(); +/*N*/ } +/*N*/ return aTmpStr; +/*N*/ } + +/*N*/ ScHeaderFieldData::ScHeaderFieldData() +/*N*/ { +/*N*/ nPageNo = nTotalPages = 0; +/*N*/ eNumType = SVX_ARABIC; +/*N*/ } + +/*N*/ ScHeaderEditEngine::ScHeaderEditEngine( SfxItemPool* pEnginePool, BOOL bDeleteEnginePool ) +/*N*/ : ScEditEngineDefaulter( pEnginePool, bDeleteEnginePool ) +/*N*/ { +/*N*/ } + +/*N*/ String __EXPORT ScHeaderEditEngine::CalcFieldValue( const SvxFieldItem& rField, +/*N*/ USHORT nPara, USHORT nPos, +/*N*/ Color*& rTxtColor, Color*& rFldColor ) +/*N*/ { +/*N*/ String aRet; +/*N*/ const SvxFieldData* pFieldData = rField.GetField(); +/*N*/ if ( pFieldData ) +/*N*/ { +/*N*/ TypeId aType = pFieldData->Type(); +/*N*/ if (aType == TYPE(SvxPageField)) +/*N*/ aRet = lcl_GetNumStr( (USHORT)aData.nPageNo,aData.eNumType ); +/*N*/ else if (aType == TYPE(SvxPagesField)) +/*?*/ aRet = lcl_GetNumStr( (USHORT)aData.nTotalPages,aData.eNumType ); +/*N*/ else if (aType == TYPE(SvxTimeField)) +/*N*/ aRet = ScGlobal::pLocaleData->getTime(aData.aTime); +/*N*/ else if (aType == TYPE(SvxFileField)) +/*N*/ aRet = aData.aTitle; +/*N*/ else if (aType == TYPE(SvxExtFileField)) +/*N*/ { +/*?*/ switch ( ((const SvxExtFileField*)pFieldData)->GetFormat() ) +/*?*/ { +/*?*/ case SVXFILEFORMAT_FULLPATH : +/*?*/ aRet = aData.aLongDocName; +/*?*/ break; +/*?*/ default: +/*?*/ aRet = aData.aShortDocName; +/*?*/ } +/*N*/ } +/*N*/ else if (aType == TYPE(SvxTableField)) +/*N*/ aRet = aData.aTabName; +/*N*/ else if (aType == TYPE(SvxDateField)) +/*N*/ aRet = ScGlobal::pLocaleData->getDate(aData.aDate); +/*N*/ else +/*N*/ { +/*N*/ //DBG_ERROR("unbekannter Feldbefehl"); +/*N*/ aRet = '?'; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { + // #i75599# no assertion - can happen with old files +/*N*/ //DBG_ERROR("FieldData ist 0"); +/*N*/ aRet = '?'; +/*N*/ } +/*N*/ +/*N*/ return aRet; +/*N*/ } + +//------------------------------------------------------------------------ +// +// Feld-Daten +// +//------------------------------------------------------------------------ + +/*N*/ ScFieldEditEngine::ScFieldEditEngine( SfxItemPool* pEnginePool, +/*N*/ SfxItemPool* pTextObjectPool, BOOL bDeleteEnginePool ) +/*N*/ : +/*N*/ ScEditEngineDefaulter( pEnginePool, bDeleteEnginePool ), +/*N*/ bExecuteURL( TRUE ) +/*N*/ { +/*N*/ if ( pTextObjectPool ) +/*N*/ SetEditTextObjectPool( pTextObjectPool ); +/*N*/ // EE_CNTRL_URLSFXEXECUTE nicht, weil die Edit-Engine den ViewFrame nicht kennt +/*N*/ // wir haben keine StyleSheets fuer Text +/*N*/ SetControlWord( (GetControlWord() | EE_CNTRL_MARKFIELDS) & ~EE_CNTRL_RTFSTYLESHEETS ); +/*N*/ } + +/*N*/ String __EXPORT ScFieldEditEngine::CalcFieldValue( const SvxFieldItem& rField, +/*N*/ USHORT nPara, USHORT nPos, +/*N*/ Color*& rTxtColor, Color*& rFldColor ) +/*N*/ { +/*N*/ String aRet; +/*N*/ const SvxFieldData* pFieldData = rField.GetField(); +/*N*/ +/*N*/ if ( pFieldData ) +/*N*/ { +/*N*/ TypeId aType = pFieldData->Type(); +/*N*/ +/*N*/ if (aType == TYPE(SvxURLField)) +/*N*/ { +/*N*/ String aURL = ((const SvxURLField*)pFieldData)->GetURL(); +/*N*/ +/*N*/ switch ( ((const SvxURLField*)pFieldData)->GetFormat() ) +/*N*/ { +/*N*/ case SVXURLFORMAT_APPDEFAULT: //!!! einstellbar an App??? +/*N*/ case SVXURLFORMAT_REPR: +/*N*/ aRet = ((const SvxURLField*)pFieldData)->GetRepresentation(); +/*N*/ break; +/*N*/ +/*N*/ case SVXURLFORMAT_URL: +/*N*/ aRet = aURL; +/*N*/ break; +/*N*/ } +/*N*/ + ColorConfigEntry eEntry = INetURLHistory::GetOrCreate()->QueryUrl( aURL ) ? LINKSVISITED : LINKS; +/*N*/ rTxtColor = new Color( SC_MOD()->GetColorConfig().GetColorValue(eEntry).nColor ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ //DBG_ERROR("unbekannter Feldbefehl"); +/*N*/ aRet = '?'; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if (!aRet.Len()) // leer ist baeh +/*N*/ aRet = ' '; // Space ist Default der Editengine +/*N*/ +/*N*/ return aRet; +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_hints.cxx b/binfilter/bf_sc/source/core/tool/sc_hints.cxx new file mode 100644 index 000000000000..59d4d1c22be7 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_hints.cxx @@ -0,0 +1,128 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "hints.hxx" +namespace binfilter { + +// ----------------------------------------------------------------------- + +/*N*/ TYPEINIT1(ScPaintHint, SfxHint); +/*N*/ TYPEINIT1(ScUpdateRefHint, SfxHint); +/*N*/ TYPEINIT1(ScPointerChangedHint, SfxHint); +/*N*/ TYPEINIT1(ScLinkRefreshedHint, SfxHint); +/*N*/ TYPEINIT1(ScAutoStyleHint, SfxHint); + +// ----------------------------------------------------------------------- +// ScPaintHint - Angabe, was neu gezeichnet werden muss +// ----------------------------------------------------------------------- + +/*N*/ ScPaintHint::ScPaintHint( const ScRange& rRng, USHORT nPaint ) : +/*N*/ aRange( rRng ), +/*N*/ nParts( nPaint ), +/*N*/ bPrint( TRUE ) +/*N*/ { +/*N*/ } + +/*N*/ ScPaintHint::~ScPaintHint() +/*N*/ { +/*N*/ } + +// ----------------------------------------------------------------------- +// ScUpdateRefHint - Referenz-Updaterei +// ----------------------------------------------------------------------- + +/*N*/ ScUpdateRefHint::ScUpdateRefHint( UpdateRefMode eMode, const ScRange& rR, +/*N*/ short nX, short nY, short nZ ) : +/*N*/ eUpdateRefMode( eMode ), +/*N*/ aRange( rR ), +/*N*/ nDx( nX ), +/*N*/ nDy( nY ), +/*N*/ nDz( nZ ) +/*N*/ { +/*N*/ } + +/*N*/ ScUpdateRefHint::~ScUpdateRefHint() +/*N*/ { +/*N*/ } + +// ----------------------------------------------------------------------- +// ScPointerChangedHint - Pointer ist ungueltig geworden +// ----------------------------------------------------------------------- + +/*N*/ ScPointerChangedHint::ScPointerChangedHint( USHORT nF ) : +/*N*/ nFlags( nF ) +/*N*/ { +/*N*/ } + +/*N*/ ScPointerChangedHint::~ScPointerChangedHint() +/*N*/ { +/*N*/ } + +// ----------------------------------------------------------------------- +// ScLinkRefreshedHint - a link has been refreshed +// ----------------------------------------------------------------------- + +/*N*/ ScLinkRefreshedHint::ScLinkRefreshedHint() : +/*N*/ nLinkType( SC_LINKREFTYPE_NONE ), +/*N*/ nDdeMode( 0 ) +/*N*/ { +/*N*/ } + +/*N*/ ScLinkRefreshedHint::~ScLinkRefreshedHint() +/*N*/ { +/*N*/ } + +/*N*/ void ScLinkRefreshedHint::SetSheetLink( const String& rSourceUrl ) +/*N*/ { +/*N*/ nLinkType = SC_LINKREFTYPE_SHEET; +/*N*/ aUrl = rSourceUrl; +/*N*/ } + + +/*N*/ void ScLinkRefreshedHint::SetAreaLink( const ScAddress& rPos ) +/*N*/ { +/*N*/ nLinkType = SC_LINKREFTYPE_AREA; +/*N*/ aDestPos = rPos; +/*N*/ } + +// ----------------------------------------------------------------------- +// ScAutoStyleHint - STYLE() function has been called +// ----------------------------------------------------------------------- + + + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_indexmap.cxx b/binfilter/bf_sc/source/core/tool/sc_indexmap.cxx new file mode 100644 index 000000000000..1c0099a0ea8a --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_indexmap.cxx @@ -0,0 +1,67 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include <memory.h> + +#include "indexmap.hxx" +namespace binfilter { + + +/*N*/ ScIndexMap::ScIndexMap( USHORT nEntries ) +/*N*/ { +/*N*/ nCount = nEntries; +/*N*/ ULONG nC = nEntries ? ((ULONG) nEntries * 2) : 2; +/*N*/ pMap = new USHORT [ nC ]; +/*N*/ memset( pMap, 0, nC * sizeof(USHORT) ); +/*N*/ } + + +/*N*/ ScIndexMap::~ScIndexMap() +/*N*/ { +/*N*/ delete [] pMap; +/*N*/ } + + +/*N*/ void ScIndexMap::SetPair( USHORT nEntry, USHORT nIndex1, USHORT nIndex2 ) +/*N*/ { +/*N*/ if ( nEntry < nCount ) +/*N*/ { +/*N*/ ULONG nOff = (ULONG) nEntry * 2; +/*N*/ pMap[nOff] = nIndex1; +/*N*/ pMap[nOff+1] = nIndex2; +/*N*/ } +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_inputopt.cxx b/binfilter/bf_sc/source/core/tool/sc_inputopt.cxx new file mode 100644 index 000000000000..53a21892c88c --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_inputopt.cxx @@ -0,0 +1,267 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +//------------------------------------------------------------------ + +#include <tools/debug.hxx> + + +#include "inputopt.hxx" +#include "rechead.hxx" +#include "global.hxx" +#include "bf_sc.hrc" +#include "miscuno.hxx" +namespace binfilter { + +using namespace utl; +using namespace rtl; +using namespace ::com::sun::star::uno; + +//------------------------------------------------------------------ + +// Version, ab der das Item kompatibel ist +#define SC_VERSION ((USHORT)351) + + +//======================================================================== +// ScInputOptions - Eingabe-Optionen +//======================================================================== + +/*N*/ ScInputOptions::ScInputOptions() +/*N*/ { +/*N*/ SetDefaults(); +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ ScInputOptions::ScInputOptions( const ScInputOptions& rCpy ) +/*N*/ { +/*N*/ *this = rCpy; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ ScInputOptions::~ScInputOptions() +/*N*/ { +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ void ScInputOptions::SetDefaults() +/*N*/ { +/*N*/ nMoveDir = DIR_BOTTOM; +/*N*/ bMoveSelection = TRUE; +/*N*/ bEnterEdit = FALSE; +/*N*/ bExtendFormat = FALSE; +/*N*/ bRangeFinder = TRUE; +/*N*/ bExpandRefs = FALSE; +/*N*/ bMarkHeader = TRUE; +/*N*/ bUseTabCol = FALSE; +/*N*/ bTextWysiwyg = FALSE; +/*N*/ bReplCellsWarn = TRUE; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ const ScInputOptions& ScInputOptions::operator=( const ScInputOptions& rCpy ) +/*N*/ { +/*N*/ nMoveDir = rCpy.nMoveDir; +/*N*/ bMoveSelection = rCpy.bMoveSelection; +/*N*/ bEnterEdit = rCpy.bEnterEdit; +/*N*/ bExtendFormat = rCpy.bExtendFormat; +/*N*/ bRangeFinder = rCpy.bRangeFinder; +/*N*/ bExpandRefs = rCpy.bExpandRefs; +/*N*/ bMarkHeader = rCpy.bMarkHeader; +/*N*/ bUseTabCol = rCpy.bUseTabCol; +/*N*/ bTextWysiwyg = rCpy.bTextWysiwyg; +/*N*/ bReplCellsWarn = rCpy.bReplCellsWarn; +/*N*/ +/*N*/ return *this; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ SvStream& operator>>( SvStream& rStream, ScInputOptions& rOpt ) +/*N*/ { +/*N*/ rOpt.SetDefaults(); +/*N*/ +/*N*/ ScReadHeader aHdr( rStream ); +/*N*/ +/*N*/ rStream >> rOpt.nMoveDir; +/*N*/ rStream >> rOpt.bMoveSelection; +/*N*/ rStream >> rOpt.bEnterEdit; +/*N*/ rStream >> rOpt.bExtendFormat; +/*N*/ +/*N*/ if (aHdr.BytesLeft()) +/*N*/ rStream >> rOpt.bRangeFinder; // ab 363 +/*N*/ +/*N*/ if (aHdr.BytesLeft()) +/*N*/ rStream >> rOpt.bExpandRefs; // ab 364v +/*N*/ +/*N*/ if (aHdr.BytesLeft()) +/*N*/ rStream >> rOpt.bMarkHeader; // ab 364irgendwas +/*N*/ +/*N*/ if (aHdr.BytesLeft()) +/*N*/ rStream >> rOpt.bUseTabCol; // ab 373d +/*N*/ +/*N*/ // newer additions are not in old file format +/*N*/ +/*N*/ return rStream; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ SvStream& operator<<( SvStream& rStream, const ScInputOptions& rOpt ) +/*N*/ { +/*N*/ ScWriteHeader aHdr( rStream, 6 ); +/*N*/ +/*N*/ rStream << rOpt.nMoveDir; +/*N*/ rStream << rOpt.bMoveSelection; +/*N*/ rStream << rOpt.bEnterEdit; +/*N*/ rStream << rOpt.bExtendFormat; +/*N*/ rStream << rOpt.bRangeFinder; +/*N*/ rStream << rOpt.bExpandRefs; +/*N*/ rStream << rOpt.bMarkHeader; +/*N*/ rStream << rOpt.bUseTabCol; +/*N*/ +/*N*/ // newer additions are not in old file format +/*N*/ +/*N*/ return rStream; +/*N*/ } + +//================================================================== +// Config Item containing input options +//================================================================== + +#define CFGPATH_INPUT "Office.Calc/Input" + +#define SCINPUTOPT_MOVEDIR 0 +#define SCINPUTOPT_MOVESEL 1 +#define SCINPUTOPT_EDTEREDIT 2 +#define SCINPUTOPT_EXTENDFMT 3 +#define SCINPUTOPT_RANGEFIND 4 +#define SCINPUTOPT_EXPANDREFS 5 +#define SCINPUTOPT_MARKHEADER 6 +#define SCINPUTOPT_USETABCOL 7 +#define SCINPUTOPT_TEXTWYSIWYG 8 +#define SCINPUTOPT_REPLCELLSWARN 9 +#define SCINPUTOPT_COUNT 10 + +/*N*/ Sequence<OUString> ScInputCfg::GetPropertyNames() +/*N*/ { +/*N*/ static const char* aPropNames[] = +/*N*/ { +/*N*/ "MoveSelectionDirection", // SCINPUTOPT_MOVEDIR +/*N*/ "MoveSelection", // SCINPUTOPT_MOVESEL +/*N*/ "SwitchToEditMode", // SCINPUTOPT_EDTEREDIT +/*N*/ "ExpandFormatting", // SCINPUTOPT_EXTENDFMT +/*N*/ "ShowReference", // SCINPUTOPT_RANGEFIND +/*N*/ "ExpandReference", // SCINPUTOPT_EXPANDREFS +/*N*/ "HighlightSelection", // SCINPUTOPT_MARKHEADER +/*N*/ "UseTabCol", // SCINPUTOPT_USETABCOL +/*N*/ "UsePrinterMetrics", // SCINPUTOPT_TEXTWYSIWYG +/*N*/ "ReplaceCellsWarning" // SCINPUTOPT_REPLCELLSWARN +/*N*/ }; +/*N*/ Sequence<OUString> aNames(SCINPUTOPT_COUNT); +/*N*/ OUString* pNames = aNames.getArray(); +/*N*/ for(int i = 0; i < SCINPUTOPT_COUNT; i++) +/*N*/ pNames[i] = OUString::createFromAscii(aPropNames[i]); +/*N*/ +/*N*/ return aNames; +/*N*/ } + +/*N*/ ScInputCfg::ScInputCfg() : +/*N*/ ConfigItem( OUString::createFromAscii( CFGPATH_INPUT ) ) +/*N*/ { +/*N*/ sal_Int32 nIntVal; +/*N*/ +/*N*/ Sequence<OUString> aNames = GetPropertyNames(); +/*N*/ Sequence<Any> aValues = GetProperties(aNames); +/*N*/ EnableNotification(aNames); +/*N*/ const Any* pValues = aValues.getConstArray(); +/*N*/ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed"); +/*N*/ if(aValues.getLength() == aNames.getLength()) +/*N*/ { +/*N*/ for(int nProp = 0; nProp < aNames.getLength(); nProp++) +/*N*/ { +/*N*/ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing"); +/*N*/ if(pValues[nProp].hasValue()) +/*N*/ { +/*N*/ switch(nProp) +/*N*/ { +/*N*/ case SCINPUTOPT_MOVEDIR: +/*N*/ if ( pValues[nProp] >>= nIntVal ) +/*N*/ SetMoveDir( (USHORT)nIntVal ); +/*N*/ break; +/*N*/ case SCINPUTOPT_MOVESEL: +/*N*/ SetMoveSelection( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCINPUTOPT_EDTEREDIT: +/*N*/ SetEnterEdit( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCINPUTOPT_EXTENDFMT: +/*N*/ SetExtendFormat( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCINPUTOPT_RANGEFIND: +/*N*/ SetRangeFinder( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCINPUTOPT_EXPANDREFS: +/*N*/ SetExpandRefs( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCINPUTOPT_MARKHEADER: +/*N*/ SetMarkHeader( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCINPUTOPT_USETABCOL: +/*N*/ SetUseTabCol( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCINPUTOPT_TEXTWYSIWYG: +/*N*/ SetTextWysiwyg( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCINPUTOPT_REPLCELLSWARN: +/*N*/ SetReplaceCellsWarn( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + + +void ScInputCfg::Notify( const ::com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames ) {} +void ScInputCfg::Commit() {} + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_interpr1.cxx b/binfilter/bf_sc/source/core/tool/sc_interpr1.cxx new file mode 100644 index 000000000000..6cb607abc1d0 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_interpr1.cxx @@ -0,0 +1,5432 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// INCLUDE --------------------------------------------------------------- + +#ifdef RS6000 +#pragma options FLTTRAP +#include <fptrap.h> +#include <fpxcp.h> +#endif + +#include "scitems.hxx" +#include <bf_svx/langitem.hxx> +#include <bf_svx/algitem.hxx> +#include <unotools/textsearch.hxx> +#include <bf_svtools/zformat.hxx> +#include <tools/solar.h> +#include <bf_sfx2/docfile.hxx> +#include <bf_sfx2/printer.hxx> + +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include "interpre.hxx" +#include "patattr.hxx" +#include "dociter.hxx" +#include "scmatrix.hxx" +#include "docoptio.hxx" +#include "globstr.hrc" +#include "attrib.hxx" +namespace binfilter { + + +// PI jetzt als F_PI aus solar.h +//#define PI 3.1415926535897932 +//#define MINVALUE 1.7e-307 +//#define SQRT_2_PI 2.506628274631000 + +// globale Variablen + +/*N*/ #ifdef _MSC_VER +/*N*/ #pragma code_seg("SCSTATICS") +/*N*/ #endif + +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( ScTokenStack, 8, 4 ) +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( ScErrorStack, 8, 4 ) +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( ScInterpreter, 32, 16 ) + +/*N*/ #ifdef _MSC_VER +/*N*/ #pragma code_seg() +/*N*/ #endif + +/*N*/ ScTokenStack* ScInterpreter::pGlobalStack = NULL; +/*N*/ ScErrorStack* ScInterpreter::pGlobalErrorStack = NULL; +/*N*/ BOOL ScInterpreter::bGlobalStackInUse = FALSE; + + +//----------------------------------------------------------------------------- +// Funktionen +//----------------------------------------------------------------------------- + + +/*N*/ void ScInterpreter::ScIfJump() +/*N*/ { +/*N*/ const short* pJump = pCur->GetJump(); +/*N*/ short nJumpCount = pJump[ 0 ]; +/*N*/ if ( GetBool() ) +/*N*/ { // TRUE +/*N*/ if( nJumpCount >= 2 ) +/*N*/ { // then Zweig +/*N*/ nFuncFmtType = NUMBERFORMAT_UNDEFINED; +/*N*/ aCode.Jump( pJump[ 1 ], pJump[ nJumpCount ] ); +/*N*/ } +/*N*/ else +/*N*/ { // kein Parameter fuer then +/*?*/ nFuncFmtType = NUMBERFORMAT_LOGICAL; +/*?*/ PushInt(1); +/*?*/ aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { // FALSE +/*N*/ if( nJumpCount == 3 ) +/*N*/ { // else Zweig +/*N*/ nFuncFmtType = NUMBERFORMAT_UNDEFINED; +/*N*/ aCode.Jump( pJump[ 2 ], pJump[ nJumpCount ] ); +/*N*/ } +/*N*/ else +/*N*/ { // kein Parameter fuer else +/*?*/ nFuncFmtType = NUMBERFORMAT_LOGICAL; +/*?*/ PushInt(0); +/*?*/ aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] ); +/*N*/ } +/*N*/ } +/*N*/ } + + +void ScInterpreter::ScChoseJump() +{ + const short* pJump = pCur->GetJump(); + short nJumpCount = pJump[ 0 ]; + double nJumpIndex = ::rtl::math::approxFloor( GetDouble() ); + if ((nJumpIndex >= 1) && (nJumpIndex < nJumpCount)) + aCode.Jump( pJump[ (short) nJumpIndex ], pJump[ nJumpCount ] ); + else + SetError(errIllegalArgument); +} + + +/*N*/ short ScInterpreter::CompareFunc( const ScCompare& rComp ) +/*N*/ { +/*N*/ short nRes = 0; +/*N*/ if ( rComp.bEmpty[ 0 ] ) +/*N*/ { +/*?*/ if ( rComp.bEmpty[ 1 ] ) +/*?*/ ; // leere Zelle == leere Zelle, nRes 0 +/*?*/ else if( rComp.bVal[ 1 ] ) +/*?*/ { +/*?*/ if ( !::rtl::math::approxEqual( rComp.nVal[ 1 ], 0.0 ) ) +/*?*/ { +/*?*/ if ( rComp.nVal[ 1 ] < 0.0 ) +/*?*/ nRes = 1; // leere Zelle > -x +/*?*/ else +/*?*/ nRes = -1; // leere Zelle < x +/*?*/ } +/*?*/ // else: leere Zelle == 0.0 +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ if ( rComp.pVal[ 1 ]->Len() ) +/*?*/ nRes = -1; // leere Zelle < "..." +/*?*/ // else: leere Zelle == "" +/*?*/ } +/*N*/ } +/*N*/ else if ( rComp.bEmpty[ 1 ] ) +/*N*/ { +/*N*/ if( rComp.bVal[ 0 ] ) +/*N*/ { +/*N*/ if ( !::rtl::math::approxEqual( rComp.nVal[ 0 ], 0.0 ) ) +/*N*/ { +/*N*/ if ( rComp.nVal[ 0 ] < 0.0 ) +/*N*/ nRes = -1; // -x < leere Zelle +/*N*/ else +/*N*/ nRes = 1; // x > leere Zelle +/*N*/ } +/*N*/ // else: leere Zelle == 0.0 +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ if ( rComp.pVal[ 0 ]->Len() ) +/*?*/ nRes = 1; // "..." > leere Zelle +/*?*/ // else: "" == leere Zelle +/*N*/ } +/*N*/ } +/*N*/ else if( rComp.bVal[ 0 ] ) +/*N*/ { +/*N*/ if( rComp.bVal[ 1 ] ) +/*N*/ { +/*N*/ if ( !::rtl::math::approxEqual( rComp.nVal[ 0 ], rComp.nVal[ 1 ] ) ) +/*N*/ { +/*N*/ if( rComp.nVal[ 0 ] - rComp.nVal[ 1 ] < 0 ) +/*N*/ nRes = -1; +/*N*/ else +/*N*/ nRes = 1; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ nRes = -1; // Zahl ist kleiner als String +/*N*/ } +/*N*/ else if( rComp.bVal[ 1 ] ) +/*N*/ nRes = 1; // Zahl ist kleiner als String +/*N*/ else +/*N*/ { +/*N*/ if (pDok->GetDocOptions().IsIgnoreCase()) +/*?*/ nRes = (short) ScGlobal::pCollator->compareString( +/*?*/ *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] ); +/*N*/ else +/*?*/ nRes = (short) ScGlobal::pCaseCollator->compareString( +/*?*/ *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] ); +/*N*/ } +/*N*/ return nRes; +/*N*/ } + + +/*N*/ short ScInterpreter::Compare() +/*N*/ { +/*N*/ nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL; +/*N*/ String aVal1, aVal2; +/*N*/ ScCompare aComp( &aVal1, &aVal2 ); +/*N*/ for( short i = 1; i >= 0; i-- ) +/*N*/ { +/*N*/ switch ( GetStackType() ) +/*N*/ { +/*N*/ case svDouble: +/*N*/ aComp.nVal[ i ] = GetDouble(); +/*N*/ aComp.bVal[ i ] = TRUE; +/*N*/ break; +/*N*/ case svString: +/*N*/ *aComp.pVal[ i ] = GetString(); +/*N*/ aComp.bVal[ i ] = FALSE; +/*N*/ break; +/*N*/ case svDoubleRef : +/*N*/ case svSingleRef : +/*N*/ { +/*N*/ ScAddress aAdr; +/*N*/ if ( !PopDoubleRefOrSingleRef( aAdr ) ) +/*N*/ break; +/*N*/ ScBaseCell* pCell = GetCell( aAdr ); +/*N*/ if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE ) +/*N*/ { +/*N*/ if (HasCellStringData(pCell)) +/*N*/ { +/*N*/ GetCellString(*aComp.pVal[ i ], pCell); +/*N*/ aComp.bVal[ i ] = FALSE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aComp.nVal[ i ] = GetCellValue( aAdr, pCell ); +/*N*/ aComp.bVal[ i ] = TRUE; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ aComp.bEmpty[ i ] = TRUE; +/*N*/ } +/*N*/ break; +/*N*/ default: +/*N*/ SetError(errIllegalParameter); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ if( nGlobalError ) +/*N*/ return 0; +/*N*/ return CompareFunc( aComp ); +/*N*/ } + + +ScMatrix* ScInterpreter::CompareMat() +{ + nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL; + String aVal1, aVal2; + ScCompare aComp( &aVal1, &aVal2 ); + ScMatrix* pMat[2]; + pMat[0] = pMat[1] = NULL; + USHORT nMatInd[2]; + BOOL bTmpMat[2]; + bTmpMat[0] = bTmpMat[1] = FALSE; + ScAddress aAdr; + for( short i = 1; i >= 0; i-- ) + { + switch (GetStackType()) + { + case svDouble: + aComp.nVal[ i ] = GetDouble(); + aComp.bVal[ i ] = TRUE; + break; + case svString: + *aComp.pVal[ i ] = GetString(); + aComp.bVal[ i ] = FALSE; + break; + case svSingleRef: + { + PopSingleRef( aAdr ); + ScBaseCell* pCell = GetCell( aAdr ); + if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE ) + { + if (HasCellStringData(pCell)) + { + GetCellString(*aComp.pVal[ i ], pCell); + aComp.bVal[ i ] = FALSE; + } + else + { + aComp.nVal[ i ] = GetCellValue( aAdr, pCell ); + aComp.bVal[ i ] = TRUE; + } + } + else + aComp.bEmpty[ i ] = TRUE; + } + break; + case svDoubleRef: + bTmpMat[ i ] = TRUE; + case svMatrix: + pMat[ i ] = GetMatrix( nMatInd[ i ] ); + if ( !pMat[ i ] ) + SetError(errIllegalParameter); + break; + default: + SetError(errIllegalParameter); + break; + } + } + ScMatrix* pResMat = NULL; + if( !nGlobalError ) + { + USHORT nResMatInd; + if ( pMat[0] && pMat[1] ) + { + USHORT nC0, nR0, nC1, nR1; + pMat[0]->GetDimensions( nC0, nR0 ); + pMat[1]->GetDimensions( nC1, nR1 ); + USHORT nC = Max( nC0, nC1 ); + USHORT nR = Max( nR0, nR1 ); + pResMat = GetNewMat( nC, nR, nResMatInd ); + if ( !pResMat ) + return NULL; + for ( USHORT j=0; j<nC; j++ ) + { + for ( USHORT k=0; k<nR; k++ ) + { + if ( j < nC0 && j < nC1 && k < nR0 && k < nR1 ) + { + for ( short i=1; i>=0; i-- ) + { + if ( pMat[i]->IsString(j,k) ) + { + aComp.bVal[i] = FALSE; + *aComp.pVal[i] = pMat[i]->GetString(j,k); + aComp.bEmpty[i] = pMat[i]->IsEmpty(j,k); + } + else + { + aComp.bVal[i] = TRUE; + aComp.nVal[i] = pMat[i]->GetDouble(j,k); + aComp.bEmpty[i] = FALSE; + } + } + pResMat->PutDouble( CompareFunc( aComp ), j,k ); + } + else + pResMat->PutString( ScGlobal::GetRscString(STR_NO_VALUE), j,k ); + } + } + nRetMat = nResMatInd; + } + else if ( pMat[0] || pMat[1] ) + { + short i = ( pMat[0] ? 0 : 1); + USHORT nC, nR; + pMat[i]->GetDimensions( nC, nR ); + pResMat = GetNewMat( nC, nR, nResMatInd ); + if ( !pResMat ) + return NULL; + ULONG n = (ULONG) nC * nR; + for ( ULONG j=0; j<n; j++ ) + { + if ( pMat[i]->IsValue(j) ) + { + aComp.bVal[i] = TRUE; + aComp.nVal[i] = pMat[i]->GetDouble(j); + aComp.bEmpty[i] = FALSE; + } + else + { + aComp.bVal[i] = FALSE; + *aComp.pVal[i] = pMat[i]->GetString(j); + aComp.bEmpty[i] = pMat[i]->IsEmpty(j); + } + pResMat->PutDouble( CompareFunc( aComp ), j ); + } + nRetMat = nResMatInd; + } + } + for( short x=1; x >= 0; x-- ) + { + if ( bTmpMat[x] && pMat[x] ) + { + delete pMat[x]; + ResetNewMat( nMatInd[x] ); + } + } + return pResMat; +} + + +/*N*/ void ScInterpreter::ScEqual() +/*N*/ { +/*N*/ StackVar eType; +/*N*/ if ( ((eType = GetStackType(2)) == svMatrix) || +/*N*/ (bMatrixFormula && eType == svDoubleRef) || +/*N*/ ((eType = GetStackType(1)) == svMatrix) || +/*N*/ (bMatrixFormula && eType == svDoubleRef) +/*N*/ ) +/*N*/ { +/*?*/ ScMatrix* pMat = CompareMat(); +/*?*/ if ( !pMat ) +/*?*/ SetIllegalParameter(); +/*?*/ else +/*?*/ { +/*?*/ pMat->CompareEqual(); +/*?*/ PushMatrix( pMat ); +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ PushInt( Compare() == 0 ); +/*N*/ } + + +/*N*/ void ScInterpreter::ScNotEqual() +/*N*/ { +/*N*/ StackVar eType; +/*N*/ if ( ((eType = GetStackType(2)) == svMatrix) || +/*N*/ (bMatrixFormula && eType == svDoubleRef) || +/*N*/ ((eType = GetStackType(1)) == svMatrix) || +/*N*/ (bMatrixFormula && eType == svDoubleRef) +/*N*/ ) +/*N*/ { +/*?*/ ScMatrix* pMat = CompareMat(); +/*?*/ if ( !pMat ) +/*?*/ SetIllegalParameter(); +/*?*/ else +/*?*/ { +/*?*/ pMat->CompareNotEqual(); +/*?*/ PushMatrix( pMat ); +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ PushInt( Compare() != 0 ); +/*N*/ } + + +void ScInterpreter::ScLess() +{ + StackVar eType; + if ( ((eType = GetStackType(2)) == svMatrix) || + (bMatrixFormula && eType == svDoubleRef) || + ((eType = GetStackType(1)) == svMatrix) || + (bMatrixFormula && eType == svDoubleRef) + ) + { + ScMatrix* pMat = CompareMat(); + if ( !pMat ) + SetIllegalParameter(); + else + { + pMat->CompareLess(); + PushMatrix( pMat ); + } + } + else + PushInt( Compare() < 0 ); +} + + +void ScInterpreter::ScGreater() +{ + StackVar eType; + if ( ((eType = GetStackType(2)) == svMatrix) || + (bMatrixFormula && eType == svDoubleRef) || + ((eType = GetStackType(1)) == svMatrix) || + (bMatrixFormula && eType == svDoubleRef) + ) + { + ScMatrix* pMat = CompareMat(); + if ( !pMat ) + SetIllegalParameter(); + else + { + pMat->CompareGreater(); + PushMatrix( pMat ); + } + } + else + PushInt( Compare() > 0 ); +} + + +void ScInterpreter::ScLessEqual() +{ + StackVar eType; + if ( ((eType = GetStackType(2)) == svMatrix) || + (bMatrixFormula && eType == svDoubleRef) || + ((eType = GetStackType(1)) == svMatrix) || + (bMatrixFormula && eType == svDoubleRef) + ) + { + ScMatrix* pMat = CompareMat(); + if ( !pMat ) + SetIllegalParameter(); + else + { + pMat->CompareLessEqual(); + PushMatrix( pMat ); + } + } + else + PushInt( Compare() <= 0 ); +} + + +void ScInterpreter::ScGreaterEqual() +{ + StackVar eType; + if ( ((eType = GetStackType(2)) == svMatrix) || + (bMatrixFormula && eType == svDoubleRef) || + ((eType = GetStackType(1)) == svMatrix) || + (bMatrixFormula && eType == svDoubleRef) + ) + { + ScMatrix* pMat = CompareMat(); + if ( !pMat ) + SetIllegalParameter(); + else + { + pMat->CompareGreaterEqual(); + PushMatrix( pMat ); + } + } + else + PushInt( Compare() >= 0 ); +} + + +void ScInterpreter::ScAnd() +{ + nFuncFmtType = NUMBERFORMAT_LOGICAL; + BYTE nParamCount = GetByte(); + if ( MustHaveParamCountMin( nParamCount, 1 ) ) + { + BOOL bHaveValue = FALSE; + short nRes = TRUE; + while( nParamCount-- ) + { + if ( !nGlobalError ) + { + switch ( GetStackType() ) + { + case svDouble : + bHaveValue = TRUE; + nRes &= ( PopDouble() != 0.0 ); + break; + case svString : + Pop(); + SetError( errNoValue ); + break; + case svSingleRef : + { + ScAddress aAdr; + PopSingleRef( aAdr ); + if ( !nGlobalError ) + { + ScBaseCell* pCell = GetCell( aAdr ); + if ( HasCellValueData( pCell ) ) + { + bHaveValue = TRUE; + nRes &= ( GetCellValue( aAdr, pCell ) != 0.0 ); + } + // else: Xcl setzt hier keinen Fehler + } + } + break; + case svDoubleRef: + { + ScRange aRange; + PopDoubleRef( aRange ); + if ( !nGlobalError ) + { + double fVal; + USHORT nErr = 0; + ScValueIterator aValIter( pDok, aRange ); + if ( aValIter.GetFirst( fVal, nErr ) ) + { + bHaveValue = TRUE; + do + { + nRes &= ( fVal != 0.0 ); + } while ( (nErr == 0) && + aValIter.GetNext( fVal, nErr ) ); + } + SetError( nErr ); + } + } + break; + case svMatrix: + { + USHORT nMatInd; + ScMatrix* pMat = GetMatrix( nMatInd ); + if ( pMat ) + { + bHaveValue = TRUE; + nRes &= pMat->And(); + } + // else: GetMatrix hat errIllegalParameter gesetzt + } + break; + default: + Pop(); + SetError( errIllegalParameter ); + } + } + else + Pop(); + } + if ( bHaveValue ) + PushInt( nRes ); + else + SetNoValue(); + } +} + + +void ScInterpreter::ScOr() +{ + nFuncFmtType = NUMBERFORMAT_LOGICAL; + BYTE nParamCount = GetByte(); + if ( MustHaveParamCountMin( nParamCount, 1 ) ) + { + BOOL bHaveValue = FALSE; + short nRes = FALSE; + while( nParamCount-- ) + { + if ( !nGlobalError ) + { + switch ( GetStackType() ) + { + case svDouble : + bHaveValue = TRUE; + nRes |= ( PopDouble() != 0.0 ); + break; + case svString : + Pop(); + SetError( errNoValue ); + break; + case svSingleRef : + { + ScAddress aAdr; + PopSingleRef( aAdr ); + if ( !nGlobalError ) + { + ScBaseCell* pCell = GetCell( aAdr ); + if ( HasCellValueData( pCell ) ) + { + bHaveValue = TRUE; + nRes |= ( GetCellValue( aAdr, pCell ) != 0.0 ); + } + // else: Xcl setzt hier keinen Fehler + } + } + break; + case svDoubleRef: + { + ScRange aRange; + PopDoubleRef( aRange ); + if ( !nGlobalError ) + { + double fVal; + USHORT nErr = 0; + ScValueIterator aValIter( pDok, aRange ); + if ( aValIter.GetFirst( fVal, nErr ) ) + { + bHaveValue = TRUE; + do + { + nRes |= ( fVal != 0.0 ); + } while ( (nErr == 0) && + aValIter.GetNext( fVal, nErr ) ); + } + SetError( nErr ); + } + } + break; + case svMatrix: + { + bHaveValue = TRUE; + USHORT nMatInd; + ScMatrix* pMat = GetMatrix( nMatInd ); + if ( pMat ) + { + bHaveValue = TRUE; + nRes |= pMat->Or(); + } + // else: GetMatrix hat errIllegalParameter gesetzt + } + break; + default: + Pop(); + SetError( errIllegalParameter ); + } + } + else + Pop(); + } + if ( bHaveValue ) + PushInt( nRes ); + else + SetNoValue(); + } +} + + +void ScInterpreter::ScNeg() +{ + MatrixDoubleRefToMatrix(); + switch ( GetStackType() ) + { + case svMatrix : + { + USHORT nMatInd; + ScMatrix* pMat = GetMatrix( nMatInd ); + if ( pMat ) + { + USHORT nC, nR; + pMat->GetDimensions( nC, nR ); + USHORT nResMat; + ScMatrix* pResMat = GetNewMat( nC, nR, nResMat ); + if ( !pResMat ) + SetNoValue(); + else + { + ULONG nCount = nC * nR; + for ( ULONG j=0; j<nCount; ++j ) + { + if ( pMat->IsValueOrEmpty(j) ) + pResMat->PutDouble( -pMat->GetDouble(j), j ); + else + pResMat->PutString( + ScGlobal::GetRscString( STR_NO_VALUE ), j ); + } + nRetMat = nResMat; + PushMatrix( pResMat ); + } + } + } + break; + default: + PushDouble( -GetDouble() ); + } +} + + +void ScInterpreter::ScPercentSign() +{ + nFuncFmtType = NUMBERFORMAT_PERCENT; + const ScToken* pSaveCur = pCur; + BYTE nSavePar = cPar; + PushInt( 100 ); + cPar = 2; + ScByteToken aDivOp( ocDiv, cPar ); + pCur = &aDivOp; + ScDiv(); + pCur = pSaveCur; + cPar = nSavePar; +} + + +void ScInterpreter::ScNot() +{ + nFuncFmtType = NUMBERFORMAT_LOGICAL; + PushInt( GetDouble() == 0.0 ); +} + + +/*N*/ void ScInterpreter::ScPi() +/*N*/ { +/*N*/ PushDouble(F_PI); +/*N*/ } + + +void ScInterpreter::ScRandom() +{ + PushDouble((double)rand() / RAND_MAX); +} + + +void ScInterpreter::ScTrue() +{ + nFuncFmtType = NUMBERFORMAT_LOGICAL; + PushInt(1); +} + + +void ScInterpreter::ScFalse() +{ + nFuncFmtType = NUMBERFORMAT_LOGICAL; + PushInt(0); +} + + +void ScInterpreter::ScDeg() +{ + PushDouble((GetDouble() / F_PI) * 180.0); +} + + +void ScInterpreter::ScRad() +{ + PushDouble(GetDouble() * (F_PI / 180)); +} + + +/*N*/ void ScInterpreter::ScSin() +/*N*/ { +/*N*/ PushDouble(::rtl::math::sin(GetDouble())); +/*N*/ } + + +void ScInterpreter::ScCos() +{ + PushDouble(::rtl::math::cos(GetDouble())); +} + + +void ScInterpreter::ScTan() +{ + PushDouble(::rtl::math::tan(GetDouble())); +} + + +void ScInterpreter::ScCot() +{ + PushDouble(1.0 / ::rtl::math::tan(GetDouble())); +} + + +void ScInterpreter::ScArcSin() +{ + PushDouble(asin(GetDouble())); +} + + +void ScInterpreter::ScArcCos() +{ + PushDouble(acos(GetDouble())); +} + + +void ScInterpreter::ScArcTan() +{ + PushDouble(atan(GetDouble())); +} + + +void ScInterpreter::ScArcCot() +{ + PushDouble((F_PI2) - atan(GetDouble())); +} + + +void ScInterpreter::ScSinHyp() +{ + PushDouble(sinh(GetDouble())); +} + + +void ScInterpreter::ScCosHyp() +{ + PushDouble(cosh(GetDouble())); +} + + +void ScInterpreter::ScTanHyp() +{ + PushDouble(tanh(GetDouble())); +} + + +void ScInterpreter::ScCotHyp() +{ + PushDouble(1.0 / tanh(GetDouble())); +} + + +void ScInterpreter::ScArcSinHyp() +{ + double nVal = GetDouble(); + PushDouble(log(nVal + sqrt((nVal * nVal) + 1.0))); +} + + +void ScInterpreter::ScArcCosHyp() +{ + double nVal = GetDouble(); + if (nVal < 1.0) + SetIllegalArgument(); + else + PushDouble(log(nVal + sqrt((nVal * nVal) - 1.0))); +} + + +void ScInterpreter::ScArcTanHyp() +{ + double nVal = GetDouble(); + if (fabs(nVal) >= 1.0) + SetIllegalArgument(); + else + PushDouble(0.5 * log((1.0 + nVal) / (1.0 - nVal))); +} + + +void ScInterpreter::ScArcCotHyp() +{ + double nVal = GetDouble(); + if (fabs(nVal) <= 1.0) + SetIllegalArgument(); + else + PushDouble(0.5 * log((nVal + 1.0) / (nVal - 1.0))); +} + + +void ScInterpreter::ScExp() +{ + PushDouble(exp(GetDouble())); +} + + +void ScInterpreter::ScSqrt() +{ + double fVal = GetDouble(); + if (fVal >= 0.0) + PushDouble(sqrt(fVal)); + else + SetIllegalArgument(); +} + + +void ScInterpreter::ScIsEmpty() +{ + short nRes = 0; + nFuncFmtType = NUMBERFORMAT_LOGICAL; + switch ( GetStackType() ) + { + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) + break; + CellType eCellType = GetCellType( GetCell( aAdr ) ); + if((eCellType == CELLTYPE_NONE) || (eCellType == CELLTYPE_NOTE)) + nRes = 1; + } + break; + default: + Pop(); + } + nGlobalError = 0; + PushInt( nRes ); +} + + +short ScInterpreter::IsString() +{ + nFuncFmtType = NUMBERFORMAT_LOGICAL; + short nRes = 0; + switch ( GetStackType() ) + { + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) + break; + ScBaseCell* pCell = GetCell( aAdr ); + if (GetCellErrCode( pCell ) == 0) + { + switch ( GetCellType( pCell ) ) + { + case CELLTYPE_STRING : + case CELLTYPE_EDIT : + nRes = 1; + break; + case CELLTYPE_FORMULA : + nRes = !((ScFormulaCell*)pCell)->IsValue(); + break; + } + } + } + break; + case svString: + PopError(); + if ( !nGlobalError ) + nRes = 1; + break; + default: + Pop(); + } + nGlobalError = 0; + return nRes; +} + + +void ScInterpreter::ScIsString() +{ + PushInt( IsString() ); +} + + +void ScInterpreter::ScIsNonString() +{ + PushInt( !IsString() ); +} + + +void ScInterpreter::ScIsLogical(UINT16 aOldNumType) +{ + short nRes = 0; + switch ( GetStackType() ) + { + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) + break; + ScBaseCell* pCell = GetCell( aAdr ); + if (GetCellErrCode( pCell ) == 0) + { + if (HasCellValueData(pCell)) + { + ULONG nFormat = GetCellNumberFormat( aAdr, pCell ); + nRes = ( pFormatter->GetType(nFormat) + == NUMBERFORMAT_LOGICAL); + } + } + } + break; + default: + PopError(); + if ( !nGlobalError ) + nRes = ( nCurFmtType == NUMBERFORMAT_LOGICAL ); + } + nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL; + nGlobalError = 0; + PushInt( nRes ); +} + + +void ScInterpreter::ScType() +{ + short nType = 0; + switch ( GetStackType() ) + { + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) + break; + ScBaseCell* pCell = GetCell( aAdr ); + if (GetCellErrCode( pCell ) == 0) + { + switch ( GetCellType( pCell ) ) + { + case CELLTYPE_STRING : + case CELLTYPE_EDIT : + nType = 2; + break; + case CELLTYPE_VALUE : + { + ULONG nFormat = GetCellNumberFormat( aAdr, pCell ); + if (pFormatter->GetType(nFormat) + == NUMBERFORMAT_LOGICAL) + nType = 4; + else + nType = 1; + } + break; + case CELLTYPE_FORMULA : + nType = 8; + break; + default: + SetIllegalParameter(); + } + } + else + nType = 16; + } + break; + case svString: + PopError(); + if ( nGlobalError ) + { + nType = 16; + nGlobalError = 0; + } + else + nType = 2; + break; + default: + PopError(); + if ( nGlobalError ) + { + nType = 16; + nGlobalError = 0; + } + else + nType = 1; + } + PushInt( nType ); +} + + +inline BOOL lcl_FormatHasNegColor( const SvNumberformat* pFormat ) +{ + return pFormat && pFormat->GetColor( 1 ); +} + + +inline BOOL lcl_FormatHasOpenPar( const SvNumberformat* pFormat ) +{ + return pFormat && (pFormat->GetFormatstring().Search( '(' ) != STRING_NOTFOUND); +} + + +void ScInterpreter::ScCell() +{ // ATTRIBUTE ; [REF] + BYTE nParamCount = GetByte(); + if( MustHaveParamCount( nParamCount, 1, 2 ) ) + { + ScAddress aCellPos( aPos ); + BOOL bError = FALSE; + if( nParamCount == 2 ) + bError = !PopDoubleRefOrSingleRef( aCellPos ); + String aInfoType( GetString() ); + if( bError || nGlobalError ) + SetIllegalParameter(); + else + { + String aResult; + ScBaseCell* pCell = GetCell( aCellPos ); + + aInfoType.ToUpperAscii(); + +// *** ADDRESS INFO *** + if( aInfoType.EqualsAscii( "COL" ) ) + { // column number (1-based) + PushInt( aCellPos.Col() + 1 ); + } + else if( aInfoType.EqualsAscii( "ROW" ) ) + { // row number (1-based) + PushInt( aCellPos.Row() + 1 ); + } + else if( aInfoType.EqualsAscii( "SHEET" ) ) + { // table number (1-based) + PushInt( aCellPos.Tab() + 1 ); + } + else if( aInfoType.EqualsAscii( "ADDRESS" ) ) + { // address formatted as [['FILENAME'#]$TABLE.]$COL$ROW + USHORT nFlags = (aCellPos.Tab() == aPos.Tab()) ? (SCA_ABS) : (SCA_ABS_3D); + aCellPos.Format( aResult, nFlags, pDok ); + PushString( aResult ); + } + else if( aInfoType.EqualsAscii( "FILENAME" ) ) + { // file name and table name: 'FILENAME'#$TABLE + USHORT nTab = aCellPos.Tab(); + if( nTab < pDok->GetTableCount() ) + { + if( pDok->GetLinkMode( nTab ) == SC_LINK_VALUE ) + pDok->GetName( nTab, aResult ); + else + { + SfxObjectShell* pShell = pDok->GetDocumentShell(); + if( pShell && pShell->GetMedium() ) + { + aResult = (sal_Unicode) '\''; + aResult += pShell->GetMedium()->GetName(); + aResult.AppendAscii( "'#$" ); + String aTabName; + pDok->GetName( nTab, aTabName ); + aResult += aTabName; + } + } + } + PushString( aResult ); + } + else if( aInfoType.EqualsAscii( "COORD" ) ) + { // address, lotus 1-2-3 formatted: $TABLE:$COL$ROW + ScAddress( aCellPos.Tab(), 0, 0 ).Format( aResult, (SCA_COL_ABSOLUTE|SCA_VALID_COL) ); + aResult += ':'; + String aCellStr; + aCellPos.Format( aCellStr, (SCA_COL_ABSOLUTE|SCA_VALID_COL|SCA_ROW_ABSOLUTE|SCA_VALID_ROW) ); + aResult += aCellStr; + PushString( aResult ); + } + +// *** CELL PROPERTIES *** + else if( aInfoType.EqualsAscii( "CONTENTS" ) ) + { // contents of the cell, no formatting + if( pCell && pCell->HasStringData() ) + { + GetCellString( aResult, pCell ); + PushString( aResult ); + } + else + PushDouble( GetCellValue( aCellPos, pCell ) ); + } + else if( aInfoType.EqualsAscii( "TYPE" ) ) + { // b = blank; l = string (label); v = otherwise (value) + if( HasCellStringData( pCell ) ) + aResult = 'l'; + else + aResult = HasCellValueData( pCell ) ? 'v' : 'b'; + PushString( aResult ); + } + else if( aInfoType.EqualsAscii( "WIDTH" ) ) + { // column width (rounded off as count of zero characters in standard font and size) + Printer* pPrinter = pDok->GetPrinter(); + MapMode aOldMode( pPrinter->GetMapMode() ); + Font aOldFont( pPrinter->GetFont() ); + Font aDefFont; + + pPrinter->SetMapMode( MAP_TWIP ); + // font color doesn't matter here + pDok->GetDefPattern()->GetFont( aDefFont, SC_AUTOCOL_BLACK, pPrinter ); + pPrinter->SetFont( aDefFont ); + long nZeroWidth = pPrinter->GetTextWidth( String( '0' ) ); + pPrinter->SetFont( aOldFont ); + pPrinter->SetMapMode( aOldMode ); + int nZeroCount = (int)(pDok->GetColWidth( aCellPos.Col(), aCellPos.Tab() ) / nZeroWidth); + PushInt( nZeroCount ); + } + else if( aInfoType.EqualsAscii( "PREFIX" ) ) + { // ' = left; " = right; ^ = centered + if( HasCellStringData( pCell ) ) + { + const SvxHorJustifyItem* pJustAttr = (const SvxHorJustifyItem*) + pDok->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_HOR_JUSTIFY ); + switch( pJustAttr->GetValue() ) + { + case SVX_HOR_JUSTIFY_STANDARD: + case SVX_HOR_JUSTIFY_LEFT: + case SVX_HOR_JUSTIFY_BLOCK: aResult = '\''; break; + case SVX_HOR_JUSTIFY_CENTER: aResult = '^'; break; + case SVX_HOR_JUSTIFY_RIGHT: aResult = '"'; break; + case SVX_HOR_JUSTIFY_REPEAT: aResult = '\\'; break; + } + } + PushString( aResult ); + } + else if( aInfoType.EqualsAscii( "PROTECT" ) ) + { // 1 = cell locked + const ScProtectionAttr* pProtAttr = (const ScProtectionAttr*) + pDok->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_PROTECTION ); + PushInt( pProtAttr->GetProtection() ? 1 : 0 ); + } + +// *** FORMATTING *** + else if( aInfoType.EqualsAscii( "FORMAT" ) ) + { // specific format code for standard formats + ULONG nFormat = pDok->GetNumberFormat( aCellPos ); + BOOL bAppendPrec = TRUE; + USHORT nPrec, nLeading; + BOOL bThousand, bIsRed; + pFormatter->GetFormatSpecialInfo( nFormat, bThousand, bIsRed, nPrec, nLeading ); + + switch( pFormatter->GetType( nFormat ) ) + { + case NUMBERFORMAT_NUMBER: aResult = (bThousand ? ',' : 'F'); break; + case NUMBERFORMAT_CURRENCY: aResult = 'C'; break; + case NUMBERFORMAT_SCIENTIFIC: aResult = 'S'; break; + case NUMBERFORMAT_PERCENT: aResult = 'P'; break; + default: + { + bAppendPrec = FALSE; + switch( pFormatter->GetIndexTableOffset( nFormat ) ) + { + case NF_DATE_SYSTEM_SHORT: + case NF_DATE_SYS_DMMMYY: + case NF_DATE_SYS_DDMMYY: + case NF_DATE_SYS_DDMMYYYY: + case NF_DATE_SYS_DMMMYYYY: + case NF_DATE_DIN_DMMMYYYY: + case NF_DATE_SYS_DMMMMYYYY: + case NF_DATE_DIN_DMMMMYYYY: aResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D1" ) ); break; + case NF_DATE_SYS_DDMMM: aResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D2" ) ); break; + case NF_DATE_SYS_MMYY: aResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D3" ) ); break; + case NF_DATETIME_SYSTEM_SHORT_HHMM: + case NF_DATETIME_SYS_DDMMYYYY_HHMMSS: + aResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D4" ) ); break; + case NF_DATE_DIN_MMDD: aResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D5" ) ); break; + case NF_TIME_HHMMSSAMPM: aResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D6" ) ); break; + case NF_TIME_HHMMAMPM: aResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D7" ) ); break; + case NF_TIME_HHMMSS: aResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D8" ) ); break; + case NF_TIME_HHMM: aResult.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D9" ) ); break; + default: aResult = 'G'; + } + } + } + if( bAppendPrec ) + aResult += String::CreateFromInt32( nPrec ); + const SvNumberformat* pFormat = pFormatter->GetEntry( nFormat ); + if( lcl_FormatHasNegColor( pFormat ) ) + aResult += '-'; + if( lcl_FormatHasOpenPar( pFormat ) ) + aResult.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "()" ) ); + PushString( aResult ); + } + else if( aInfoType.EqualsAscii( "COLOR" ) ) + { // 1 = negative values are colored, otherwise 0 + const SvNumberformat* pFormat = pFormatter->GetEntry( pDok->GetNumberFormat( aCellPos ) ); + PushInt( lcl_FormatHasNegColor( pFormat ) ? 1 : 0 ); + } + else if( aInfoType.EqualsAscii( "PARENTHESES" ) ) + { // 1 = format string contains a '(' character, otherwise 0 + const SvNumberformat* pFormat = pFormatter->GetEntry( pDok->GetNumberFormat( aCellPos ) ); + PushInt( lcl_FormatHasOpenPar( pFormat ) ? 1 : 0 ); + } + else + SetIllegalArgument(); + } + } +} + + +void ScInterpreter::ScIsRef() +{ + nFuncFmtType = NUMBERFORMAT_LOGICAL; + short nRes = 0; + switch ( GetStackType() ) + { + case svSingleRef : + { + ScAddress aAdr; + PopSingleRef( aAdr ); + if ( !nGlobalError ) + nRes = 1; + } + break; + case svDoubleRef : + { + ScRange aRange; + PopDoubleRef( aRange ); + if ( !nGlobalError ) + nRes = 1; + } + break; + default: + Pop(); + } + nGlobalError = 0; + PushInt( nRes ); +} + + +void ScInterpreter::ScIsValue() +{ + nFuncFmtType = NUMBERFORMAT_LOGICAL; + short nRes = 0; + switch ( GetStackType() ) + { + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) + break; + ScBaseCell* pCell = GetCell( aAdr ); + if (GetCellErrCode( pCell ) == 0) + { + switch ( GetCellType( pCell ) ) + { + case CELLTYPE_VALUE : + nRes = 1; + break; + case CELLTYPE_FORMULA : + nRes = ((ScFormulaCell*)pCell)->IsValue(); + break; + } + } + } + break; + case svString: + Pop(); + break; + default: + PopError(); + if ( !nGlobalError ) + nRes = 1; + } + nGlobalError = 0; + PushInt( nRes ); +} + + +void ScInterpreter::ScIsFormula() +{ + nFuncFmtType = NUMBERFORMAT_LOGICAL; + short nRes = 0; + switch ( GetStackType() ) + { + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) + break; + nRes = (GetCellType( GetCell( aAdr ) ) == CELLTYPE_FORMULA); + } + break; + default: + Pop(); + } + nGlobalError = 0; + PushInt( nRes ); +} + + +void ScInterpreter::ScFormula() +{ + String aFormula; + switch ( GetStackType() ) + { + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) + break; + ScBaseCell* pCell = GetCell( aAdr ); + switch ( GetCellType( pCell ) ) + { + case CELLTYPE_FORMULA : + ((ScFormulaCell*)pCell)->GetFormula( aFormula ); + break; + default: + SetError( NOVALUE ); + } + } + break; + default: + Pop(); + SetError( NOVALUE ); + } + PushString( aFormula ); +} + + + +void ScInterpreter::ScIsNV() +{ + nFuncFmtType = NUMBERFORMAT_LOGICAL; + short nRes = 0; + switch ( GetStackType() ) + { + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + PopDoubleRefOrSingleRef( aAdr ); + if ( nGlobalError == NOVALUE ) + nRes = 1; + else + { + ScBaseCell* pCell = GetCell( aAdr ); + USHORT nErr = GetCellErrCode( pCell ); + nRes = (nErr == NOVALUE); + } + } + break; + default: + PopError(); + if ( nGlobalError == NOVALUE ) + nRes = 1; + } + nGlobalError = 0; + PushInt( nRes ); +} + + +void ScInterpreter::ScIsErr() +{ + nFuncFmtType = NUMBERFORMAT_LOGICAL; + short nRes = 0; + switch ( GetStackType() ) + { + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + PopDoubleRefOrSingleRef( aAdr ); + if ( nGlobalError && nGlobalError != NOVALUE ) + nRes = 1; + else + { + ScBaseCell* pCell = GetCell( aAdr ); + USHORT nErr = GetCellErrCode( pCell ); + nRes = (nErr && nErr != NOVALUE); + } + } + break; + default: + PopError(); + if ( nGlobalError && nGlobalError != NOVALUE ) + nRes = 1; + } + nGlobalError = 0; + PushInt( nRes ); +} + + +void ScInterpreter::ScIsError() +{ + nFuncFmtType = NUMBERFORMAT_LOGICAL; + short nRes = 0; + switch ( GetStackType() ) + { + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) + { + nRes = 1; + break; + } + if ( nGlobalError ) + nRes = 1; + else + { + ScBaseCell* pCell = GetCell( aAdr ); + nRes = (GetCellErrCode( pCell ) != 0); + } + } + break; + default: + PopError(); + if ( nGlobalError ) + nRes = 1; + } + nGlobalError = 0; + PushInt( nRes ); +} + + +short ScInterpreter::IsEven() +{ + nFuncFmtType = NUMBERFORMAT_LOGICAL; + short nRes = 0; + double fVal; + switch ( GetStackType() ) + { + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) + break; + ScBaseCell* pCell = GetCell( aAdr ); + USHORT nErr = GetCellErrCode( pCell ); + if (nErr != 0) + SetError(nErr); + else + { + switch ( GetCellType( pCell ) ) + { + case CELLTYPE_VALUE : + fVal = GetCellValue( aAdr, pCell ); + nRes = 1; + break; + case CELLTYPE_FORMULA : + if( ((ScFormulaCell*)pCell)->IsValue() ) + { + fVal = GetCellValue( aAdr, pCell ); + nRes = 1; + } + else + SetIllegalParameter(); + break; + default: + SetIllegalParameter(); + } + } + } + break; + case svDouble: + { + fVal = PopDouble(); + nRes = 1; + } + break; + default: + SetIllegalParameter(); + } + if (nRes) + nRes = ( fmod( ::rtl::math::approxFloor( fabs( fVal ) ), 2.0 ) < 0.5 ); + return nRes; +} + + +void ScInterpreter::ScIsEven() +{ + PushInt( IsEven() ); +} + + +void ScInterpreter::ScIsOdd() +{ + PushInt( !IsEven() ); +} + + +void ScInterpreter::ScN() +{ + USHORT nErr = nGlobalError; + nGlobalError = 0; + double fVal = GetDouble(); + if ( nGlobalError == NOVALUE || nGlobalError == errIllegalArgument ) + nGlobalError = 0; // N(#NV) und N("text") sind ok + if ( !nGlobalError && nErr != NOVALUE ) + nGlobalError = nErr; + PushDouble( fVal ); +} + + +void ScInterpreter::ScTrim() +{ // trimmt nicht nur sondern schnibbelt auch doppelte raus! + String aVal( GetString() ); + aVal.EraseLeadingChars(); + aVal.EraseTrailingChars(); + String aStr; + register const sal_Unicode* p = aVal.GetBuffer(); + register const sal_Unicode* const pEnd = p + aVal.Len(); + while ( p < pEnd ) + { + if ( *p != ' ' || p[-1] != ' ' ) // erster kann kein ' ' sein, -1 ist also ok + aStr += *p; + p++; + } + PushString( aStr ); +} + + +void ScInterpreter::ScUpper() +{ + String aString = GetString(); + ScGlobal::pCharClass->toUpper(aString); + PushString(aString); +} + + +void ScInterpreter::ScPropper() +{ +//2do: what to do with I18N-CJK ?!? + String aStr( GetString() ); + const xub_StrLen nLen = aStr.Len(); + // #i82487#,#i89963# don't try to write to empty string's BufferAccess + // (would crash now that the empty string is const) + if ( nLen > 0 ) + { + String aUpr( ScGlobal::pCharClass->upper( aStr ) ); + String aLwr( ScGlobal::pCharClass->lower( aStr ) ); + register sal_Unicode* pStr = aStr.GetBufferAccess(); + const sal_Unicode* pUpr = aUpr.GetBuffer(); + const sal_Unicode* pLwr = aLwr.GetBuffer(); + *pStr = *pUpr; + String aTmpStr( 'x' ); + xub_StrLen nPos = 1; + while( nPos < nLen ) + { + aTmpStr.SetChar( 0, pStr[nPos-1] ); + if ( !ScGlobal::pCharClass->isLetter( aTmpStr, 0 ) ) + pStr[nPos] = pUpr[nPos]; + else + pStr[nPos] = pLwr[nPos]; + nPos++; + } + aStr.ReleaseBufferAccess( nLen ); + } + PushString( aStr ); +} + + +void ScInterpreter::ScLower() +{ + String aString( GetString() ); + ScGlobal::pCharClass->toLower(aString); + PushString(aString); +} + + +void ScInterpreter::ScLen() +{ + String aStr( GetString() ); + PushDouble( aStr.Len() ); +} + + +void ScInterpreter::ScT() +{ + switch ( GetStackType() ) + { + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) + { + PushInt(0); + return ; + } + BOOL bValue = FALSE; + ScBaseCell* pCell = GetCell( aAdr ); + if ( GetCellErrCode( pCell ) == 0 ) + { + switch ( GetCellType( pCell ) ) + { + case CELLTYPE_VALUE : + bValue = TRUE; + break; + case CELLTYPE_FORMULA : + bValue = ((ScFormulaCell*)pCell)->IsValue(); + break; + } + } + if ( bValue ) + PushString( EMPTY_STRING ); + else + { + // wie GetString() + GetCellString( aTempStr, pCell ); + PushString( aTempStr ); + } + } + break; + case svDouble : + { + PopError(); + PushString( EMPTY_STRING ); + } + break; + case svString : + break; + default : + SetError(errUnknownOpCode); + PushInt(0); + + } +} + + +void ScInterpreter::ScValue() +{ + String aInputString = GetString(); + sal_uInt32 nFIndex = 0; // damit default Land/Spr. + double fVal; + if (pFormatter->IsNumberFormat(aInputString, nFIndex, fVal)) + PushDouble(fVal); + else + SetIllegalArgument(); +} + + +//2do: this should be a proper unicode string method +inline BOOL lcl_ScInterpreter_IsPrintable( sal_Unicode c ) +{ + return 0x20 <= c && c != 0x7f; +} + +void ScInterpreter::ScClean() +{ + String aStr( GetString() ); + for ( xub_StrLen i = 0; i < aStr.Len(); i++ ) + { + if ( !lcl_ScInterpreter_IsPrintable( aStr.GetChar( i ) ) ) + aStr.Erase(i,1); + } + PushString(aStr); +} + + +void ScInterpreter::ScCode() +{ +//2do: make it full range unicode? + const String& rStr = GetString(); + PushInt( (sal_uChar) ByteString::ConvertFromUnicode( rStr.GetChar(0), gsl_getSystemTextEncoding() ) ); +} + + +void ScInterpreter::ScChar() +{ +//2do: make it full range unicode? + double fVal = GetDouble(); + if (fVal < 0.0 || fVal >= 256.0) + SetIllegalArgument(); + else + { + String aStr( '0' ); + aStr.SetChar( 0, ByteString::ConvertToUnicode( (sal_Char) fVal, gsl_getSystemTextEncoding() ) ); + PushString( aStr ); + } +} + + +/*N*/ void ScInterpreter::ScMin( BOOL bTextAsZero ) +/*N*/ { +/*N*/ BYTE nParamCount = GetByte(); +/*N*/ double nMin = SC_DOUBLE_MAXVALUE; +/*N*/ double nVal = 0.0; +/*N*/ ScAddress aAdr; +/*N*/ ScRange aRange; +/*N*/ for (short i = 0; i < nParamCount; i++) +/*N*/ { +/*N*/ switch (GetStackType()) +/*N*/ { +/*?*/ case svDouble : +/*?*/ { +/*?*/ nVal = GetDouble(); +/*?*/ if (nMin > nVal) nMin = nVal; +/*?*/ nFuncFmtType = NUMBERFORMAT_NUMBER; +/*?*/ } +/*?*/ break; +/*?*/ case svSingleRef : +/*?*/ { +/*?*/ PopSingleRef( aAdr ); +/*?*/ ScBaseCell* pCell = GetCell( aAdr ); +/*?*/ if (HasCellValueData(pCell)) +/*?*/ { +/*?*/ nVal = GetCellValue( aAdr, pCell ); +/*?*/ CurFmtToFuncFmt(); +/*?*/ if (nMin > nVal) nMin = nVal; +/*?*/ } +/*?*/ else if ( bTextAsZero && HasCellStringData( pCell ) ) +/*?*/ { +/*?*/ if ( nMin > 0.0 ) +/*?*/ nMin = 0.0; +/*?*/ } +/*?*/ } +/*?*/ break; +/*N*/ case svDoubleRef : +/*N*/ { +/*N*/ USHORT nErr = 0; +/*N*/ PopDoubleRef( aRange ); +/*N*/ ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero ); +/*N*/ if (aValIter.GetFirst(nVal, nErr)) +/*N*/ { +/*N*/ if (nMin > nVal) +/*N*/ nMin = nVal; +/*N*/ aValIter.GetCurNumFmtInfo( nFuncFmtType, nFuncFmtIndex ); +/*N*/ while ((nErr == 0) && aValIter.GetNext(nVal, nErr)) +/*N*/ { +/*N*/ if (nMin > nVal) +/*N*/ nMin = nVal; +/*N*/ } +/*N*/ SetError(nErr); +/*N*/ } +/*N*/ } +/*N*/ break; +/*?*/ case svMatrix : +/*?*/ { +/*?*/ ScMatrix* pMat = PopMatrix(); +/*?*/ if (pMat) +/*?*/ { +/*?*/ USHORT nC, nR; +/*?*/ nFuncFmtType = NUMBERFORMAT_NUMBER; +/*?*/ pMat->GetDimensions(nC, nR); +/*?*/ if (pMat->IsNumeric()) +/*?*/ { +/*?*/ for (USHORT i = 0; i < nC; i++) +/*?*/ for (USHORT j = 0; j < nR; j++) +/*?*/ { +/*?*/ nVal = pMat->GetDouble(i,j); +/*?*/ if (nMin > nVal) nMin = nVal; +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ for (USHORT i = 0; i < nC; i++) +/*?*/ { +/*?*/ for (USHORT j = 0; j < nR; j++) +/*?*/ { +/*?*/ if (!pMat->IsString(i,j)) +/*?*/ { +/*?*/ nVal = pMat->GetDouble(i,j); +/*?*/ if (nMin > nVal) nMin = nVal; +/*?*/ } +/*?*/ else if ( bTextAsZero ) +/*?*/ { +/*?*/ if ( nMin > 0.0 ) +/*?*/ nMin = 0.0; +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ break; +/*?*/ case svString : +/*?*/ { +/*?*/ Pop(); +/*?*/ if ( bTextAsZero ) +/*?*/ { +/*?*/ if ( nMin > 0.0 ) +/*?*/ nMin = 0.0; +/*?*/ } +/*?*/ else +/*?*/ SetError(errIllegalParameter); +/*?*/ } +/*?*/ break; +/*?*/ default : +/*?*/ Pop(); +/*?*/ SetError(errIllegalParameter); +/*?*/ } +/*N*/ } +/*N*/ if (nMin == SC_DOUBLE_MAXVALUE) +/*?*/ SetIllegalArgument(); +/*N*/ else +/*N*/ PushDouble(nMin); +/*N*/ } +/*N*/ +/*N*/ #if defined(WIN) && defined(MSC) +/*N*/ #pragma optimize("",off) +/*N*/ #endif + +/*N*/ void ScInterpreter::ScMax( BOOL bTextAsZero ) +/*N*/ { +/*N*/ BYTE nParamCount = GetByte(); +/*N*/ double nMax = -SC_DOUBLE_MAXVALUE; +/*N*/ double nVal = 0.0; +/*N*/ ScAddress aAdr; +/*N*/ ScRange aRange; +/*N*/ for (short i = 0; i < nParamCount; i++) +/*N*/ { +/*N*/ switch (GetStackType()) +/*N*/ { +/*?*/ case svDouble : +/*?*/ { +/*?*/ nVal = GetDouble(); +/*?*/ if (nMax < nVal) nMax = nVal; +/*?*/ nFuncFmtType = NUMBERFORMAT_NUMBER; +/*?*/ } +/*?*/ break; +/*N*/ case svSingleRef : +/*N*/ { +/*N*/ PopSingleRef( aAdr ); +/*N*/ ScBaseCell* pCell = GetCell( aAdr ); +/*N*/ if (HasCellValueData(pCell)) +/*N*/ { +/*N*/ nVal = GetCellValue( aAdr, pCell ); +/*N*/ CurFmtToFuncFmt(); +/*N*/ if (nMax < nVal) nMax = nVal; +/*N*/ } +/*N*/ else if ( bTextAsZero && HasCellStringData( pCell ) ) +/*N*/ { +/*N*/ if ( nMax < 0.0 ) +/*N*/ nMax = 0.0; +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case svDoubleRef : +/*N*/ { +/*N*/ USHORT nErr = 0; +/*N*/ PopDoubleRef( aRange ); +/*N*/ ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero ); +/*N*/ if (aValIter.GetFirst(nVal, nErr)) +/*N*/ { +/*N*/ if (nMax < nVal) +/*N*/ nMax = nVal; +/*N*/ aValIter.GetCurNumFmtInfo( nFuncFmtType, nFuncFmtIndex ); +/*N*/ while ((nErr == 0) && aValIter.GetNext(nVal, nErr)) +/*N*/ { +/*N*/ if (nMax < nVal) +/*N*/ nMax = nVal; +/*N*/ } +/*N*/ SetError(nErr); +/*N*/ } +/*N*/ } +/*N*/ break; +/*?*/ case svMatrix : +/*?*/ { +/*?*/ ScMatrix* pMat = PopMatrix(); +/*?*/ if (pMat) +/*?*/ { +/*?*/ nFuncFmtType = NUMBERFORMAT_NUMBER; +/*?*/ USHORT nC, nR; +/*?*/ pMat->GetDimensions(nC, nR); +/*?*/ if (pMat->IsNumeric()) +/*?*/ { +/*?*/ for (USHORT i = 0; i < nC; i++) +/*?*/ for (USHORT j = 0; j < nR; j++) +/*?*/ { +/*?*/ nVal = pMat->GetDouble(i,j); +/*?*/ if (nMax < nVal) nMax = nVal; +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ for (USHORT i = 0; i < nC; i++) +/*?*/ { +/*?*/ for (USHORT j = 0; j < nR; j++) +/*?*/ { +/*?*/ if (!pMat->IsString(i,j)) +/*?*/ { +/*?*/ nVal = pMat->GetDouble(i,j); +/*?*/ if (nMax < nVal) nMax = nVal; +/*?*/ } +/*?*/ else if ( bTextAsZero ) +/*?*/ { +/*?*/ if ( nMax < 0.0 ) +/*?*/ nMax = 0.0; +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ break; +/*?*/ case svString : +/*?*/ { +/*?*/ Pop(); +/*?*/ if ( bTextAsZero ) +/*?*/ { +/*?*/ if ( nMax < 0.0 ) +/*?*/ nMax = 0.0; +/*?*/ } +/*?*/ else +/*?*/ SetError(errIllegalParameter); +/*?*/ } +/*?*/ break; +/*?*/ default : +/*?*/ Pop(); +/*?*/ SetError(errIllegalParameter); +/*N*/ } +/*N*/ } +/*N*/ if (nMax == -SC_DOUBLE_MAXVALUE) +/*N*/ SetIllegalArgument(); +/*N*/ else +/*N*/ PushDouble(nMax); +/*N*/ } +/*N*/ #if defined(WIN) && defined(MSC) +/*N*/ #pragma optimize("",on) +/*N*/ #endif + + +/*N*/ double ScInterpreter::IterateParameters( ScIterFunc eFunc, BOOL bTextAsZero ) +/*N*/ { +/*N*/ BYTE nParamCount = GetByte(); +/*N*/ double fRes = ( eFunc == ifPRODUCT ) ? 1.0 : 0.0; +/*N*/ double fVal = 0.0; +/*N*/ double fMem = 0.0; +/*N*/ BOOL bNull = TRUE; +/*N*/ ULONG nCount = 0; +/*N*/ ScAddress aAdr; +/*N*/ ScRange aRange; +/*N*/ for (short i = 0; i < nParamCount; i++) +/*N*/ { +/*N*/ switch (GetStackType()) +/*N*/ { +/*N*/ +/*?*/ case svString: +/*?*/ { +/*?*/ if( eFunc == ifCOUNT ) +/*?*/ { +/*?*/ String aStr( PopString() ); +/*?*/ sal_uInt32 nFIndex = 0; // damit default Land/Spr. +/*?*/ if ( bTextAsZero || pFormatter->IsNumberFormat(aStr, nFIndex, fVal)) +/*?*/ nCount++; +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ switch ( eFunc ) +/*?*/ { +/*?*/ case ifAVERAGE: +/*?*/ case ifSUM: +/*?*/ case ifSUMSQ: +/*?*/ case ifPRODUCT: +/*?*/ { +/*?*/ if ( bTextAsZero ) +/*?*/ { +/*?*/ Pop(); +/*?*/ nCount++; +/*?*/ if ( eFunc == ifPRODUCT ) +/*?*/ fRes = 0.0; +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ for ( ; i < nParamCount; i++ ) +/*?*/ Pop(); +/*?*/ SetError( errNoValue ); +/*?*/ } +/*?*/ } +/*?*/ break; +/*?*/ default: +/*?*/ Pop(); +/*?*/ nCount++; +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ break; +/*?*/ case svDouble : +/*?*/ fVal = GetDouble(); +/*?*/ nCount++; +/*?*/ switch( eFunc ) +/*?*/ { +/*?*/ case ifAVERAGE: +/*?*/ case ifSUM: +/*?*/ if ( bNull && fVal != 0.0 ) +/*?*/ { +/*?*/ bNull = FALSE; +/*?*/ fMem = fVal; +/*?*/ } +/*?*/ else +/*?*/ fRes += fVal; +/*?*/ break; +/*?*/ case ifSUMSQ: fRes += fVal * fVal; break; +/*?*/ case ifPRODUCT: fRes *= fVal; break; +/*?*/ } +/*?*/ nFuncFmtType = NUMBERFORMAT_NUMBER; +/*?*/ break; +/*?*/ case svSingleRef : +/*?*/ { +/*?*/ PopSingleRef( aAdr ); +/*?*/ ScBaseCell* pCell = GetCell( aAdr ); +/*?*/ if ( pCell ) +/*?*/ { +/*?*/ if( eFunc == ifCOUNT2 ) +/*?*/ { +/*?*/ CellType eCellType = pCell->GetCellType(); +/*?*/ if (eCellType != CELLTYPE_NONE && eCellType != CELLTYPE_NOTE) +/*?*/ nCount++; +/*?*/ } +/*?*/ else if ( pCell->HasValueData() ) +/*?*/ { +/*?*/ nCount++; +/*?*/ fVal = GetCellValue( aAdr, pCell ); +/*?*/ CurFmtToFuncFmt(); +/*?*/ switch( eFunc ) +/*?*/ { +/*?*/ case ifAVERAGE: +/*?*/ case ifSUM: +/*?*/ if ( bNull && fVal != 0.0 ) +/*?*/ { +/*?*/ bNull = FALSE; +/*?*/ fMem = fVal; +/*?*/ } +/*?*/ else +/*?*/ fRes += fVal; +/*?*/ break; +/*?*/ case ifSUMSQ: fRes += fVal * fVal; break; +/*?*/ case ifPRODUCT: fRes *= fVal; break; +/*?*/ } +/*?*/ } +/*?*/ else if ( bTextAsZero && pCell->HasStringData() ) +/*?*/ { +/*?*/ nCount++; +/*?*/ if ( eFunc == ifPRODUCT ) +/*?*/ fRes = 0.0; +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ break; +/*N*/ case svDoubleRef : +/*N*/ { +/*N*/ USHORT nErr = 0; +/*N*/ PopDoubleRef( aRange ); +/*N*/ if( eFunc == ifCOUNT2 ) +/*N*/ { +/*N*/ ScBaseCell* pCell; +/*N*/ ScCellIterator aIter( pDok, aRange, glSubTotal ); +/*N*/ if (pCell = aIter.GetFirst()) +/*N*/ { +/*N*/ do +/*N*/ { +/*N*/ CellType eType = pCell->GetCellType(); +/*N*/ if( eType != CELLTYPE_NONE && eType != CELLTYPE_NOTE ) +/*N*/ nCount++; +/*N*/ } +/*N*/ while ( pCell = aIter.GetNext()); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero ); +/*N*/ if (aValIter.GetFirst(fVal, nErr)) +/*N*/ { +/*N*/ // Schleife aus Performance-Gruenden nach innen verlegt: +/*N*/ aValIter.GetCurNumFmtInfo( nFuncFmtType, nFuncFmtIndex ); +/*N*/ switch( eFunc ) +/*N*/ { +/*N*/ case ifAVERAGE: +/*N*/ case ifSUM: +/*N*/ do +/*N*/ { +/*N*/ SetError(nErr); +/*N*/ if ( bNull && fVal != 0.0 ) +/*N*/ { +/*N*/ bNull = FALSE; +/*N*/ fMem = fVal; +/*N*/ } +/*N*/ else +/*N*/ fRes += fVal; +/*N*/ nCount++; +/*N*/ } +/*N*/ while (aValIter.GetNext(fVal, nErr)); +/*N*/ break; +/*N*/ case ifSUMSQ: +/*N*/ do +/*N*/ { +/*N*/ SetError(nErr); +/*N*/ fRes += fVal * fVal; +/*N*/ nCount++; +/*N*/ } +/*N*/ while (aValIter.GetNext(fVal, nErr)); +/*N*/ break; +/*N*/ case ifPRODUCT: +/*N*/ do +/*N*/ { +/*N*/ SetError(nErr); +/*N*/ fRes *= fVal; +/*N*/ nCount++; +/*N*/ } +/*N*/ while (aValIter.GetNext(fVal, nErr)); +/*N*/ break; +/*N*/ default: // count +/*N*/ do +/*N*/ { +/*N*/ SetError(nErr); +/*N*/ nCount++; +/*N*/ } +/*N*/ while (aValIter.GetNext(fVal, nErr)); +/*N*/ break; +/*N*/ } +/*N*/ SetError( nErr ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ break; +/*?*/ case svMatrix : +/*?*/ { +/*?*/ ScMatrix* pMat = PopMatrix(); +/*?*/ if (pMat) +/*?*/ { +/*?*/ USHORT nC, nR; +/*?*/ nFuncFmtType = NUMBERFORMAT_NUMBER; +/*?*/ pMat->GetDimensions(nC, nR); +/*?*/ if( eFunc == ifCOUNT2 ) +/*?*/ nCount += (ULONG) nC * nR; +/*?*/ else +/*?*/ { +/*?*/ for (USHORT i = 0; i < nC; i++) +/*?*/ { +/*?*/ for (USHORT j = 0; j < nR; j++) +/*?*/ { +/*?*/ if (!pMat->IsString(i,j)) +/*?*/ { +/*?*/ nCount++; +/*?*/ fVal = pMat->GetDouble(i,j); +/*?*/ switch( eFunc ) +/*?*/ { +/*?*/ case ifAVERAGE: +/*?*/ case ifSUM: +/*?*/ if ( bNull && fVal != 0.0 ) +/*?*/ { +/*?*/ bNull = FALSE; +/*?*/ fMem = fVal; +/*?*/ } +/*?*/ else +/*?*/ fRes += fVal; +/*?*/ break; +/*?*/ case ifSUMSQ: fRes += fVal * fVal; break; +/*?*/ case ifPRODUCT: fRes *= fVal; break; +/*?*/ } +/*?*/ } +/*?*/ else if ( bTextAsZero ) +/*?*/ { +/*?*/ nCount++; +/*?*/ if ( eFunc == ifPRODUCT ) +/*?*/ fRes = 0.0; +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ break; +/*?*/ default : +/*?*/ for ( ; i < nParamCount; i++ ) +/*?*/ Pop(); +/*?*/ SetError(errIllegalParameter); +/*N*/ } +/*N*/ } +/*N*/ switch( eFunc ) +/*N*/ { +/*N*/ case ifSUM: fRes = ::rtl::math::approxAdd( fRes, fMem ); break; +/*N*/ case ifAVERAGE: fRes = ::rtl::math::approxAdd( fRes, fMem ) / nCount; break; +/*N*/ case ifCOUNT2: +/*N*/ case ifCOUNT: fRes = nCount; break; +/*N*/ case ifPRODUCT: if ( !nCount ) fRes = 0.0; break; +/*N*/ } +/*N*/ // Bei Summen etc. macht ein BOOL-Ergebnis keinen Sinn +/*N*/ // und Anzahl ist immer Number (#38345#) +/*N*/ if( eFunc == ifCOUNT || nFuncFmtType == NUMBERFORMAT_LOGICAL ) +/*N*/ nFuncFmtType = NUMBERFORMAT_NUMBER; +/*N*/ return fRes; +/*N*/ } + + +void ScInterpreter::ScSumSQ() +{ + PushDouble( IterateParameters( ifSUMSQ ) ); +} + + +/*N*/ void ScInterpreter::ScSum() +/*N*/ { +/*N*/ PushDouble( IterateParameters( ifSUM ) ); +/*N*/ } + + +void ScInterpreter::ScProduct() +{ + PushDouble( IterateParameters( ifPRODUCT ) ); +} + + +/*N*/ void ScInterpreter::ScAverage( BOOL bTextAsZero ) +/*N*/ { +/*N*/ PushDouble( IterateParameters( ifAVERAGE, bTextAsZero ) ); +/*N*/ } + + +void ScInterpreter::ScCount() +{ + PushDouble( IterateParameters( ifCOUNT ) ); +} + + +/*N*/ void ScInterpreter::ScCount2() +/*N*/ { +/*N*/ PushDouble( IterateParameters( ifCOUNT2 ) ); +/*N*/ } + + +/*N*/ void ScInterpreter::GetStVarParams( double& rVal, double& rValCount, +/*N*/ BOOL bTextAsZero ) +/*N*/ { +/*N*/ BYTE nParamCount = GetByte(); +/*N*/ USHORT i; +/*N*/ double fSum = 0.0; +/*N*/ double fSumSqr = 0.0; +/*N*/ double fVal; +/*N*/ rValCount = 0.0; +/*N*/ ScAddress aAdr; +/*N*/ ScRange aRange; +/*N*/ for (i = 0; i < nParamCount; i++) +/*N*/ { +/*N*/ switch (GetStackType()) +/*N*/ { +/*N*/ case svDouble : +/*N*/ { +/*?*/ fVal = GetDouble(); +/*?*/ fSum += fVal; +/*?*/ fSumSqr += fVal*fVal; +/*?*/ rValCount++; +/*N*/ } +/*N*/ break; +/*N*/ case svSingleRef : +/*N*/ { +/*?*/ PopSingleRef( aAdr ); +/*?*/ ScBaseCell* pCell = GetCell( aAdr ); +/*?*/ if (HasCellValueData(pCell)) +/*?*/ { +/*?*/ fVal = GetCellValue( aAdr, pCell ); +/*?*/ fSum += fVal; +/*?*/ fSumSqr += fVal*fVal; +/*?*/ rValCount++; +/*?*/ } +/*?*/ else if ( bTextAsZero && HasCellStringData( pCell ) ) +/*?*/ rValCount++; +/*N*/ } +/*N*/ break; +/*N*/ case svDoubleRef : +/*N*/ { +/*N*/ USHORT nErr = 0; +/*N*/ PopDoubleRef( aRange ); +/*N*/ ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero ); +/*N*/ if (aValIter.GetFirst(fVal, nErr)) +/*N*/ { +/*N*/ do +/*N*/ { +/*N*/ fSum += fVal; +/*N*/ fSumSqr += fVal*fVal; +/*N*/ rValCount++; +/*N*/ } +/*N*/ while ((nErr == 0) && aValIter.GetNext(fVal, nErr)); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case svMatrix : +/*N*/ { +/*?*/ ScMatrix* pMat = PopMatrix(); +/*?*/ if (pMat) +/*?*/ { +/*?*/ USHORT nC, nR; +/*?*/ pMat->GetDimensions(nC, nR); +/*?*/ for (USHORT i = 0; i < nC; i++) +/*?*/ { +/*?*/ for (USHORT j = 0; j < nR; j++) +/*?*/ { +/*?*/ if (!pMat->IsString(i,j)) +/*?*/ { +/*?*/ fVal= pMat->GetDouble(i,j); +/*?*/ fSum += fVal; +/*?*/ fSumSqr += fVal * fVal; +/*?*/ rValCount++; +/*?*/ } +/*?*/ else if ( bTextAsZero ) +/*?*/ rValCount++; +/*?*/ } +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ break; +/*N*/ case svString : +/*N*/ { +/*?*/ if ( bTextAsZero ) +/*?*/ rValCount++; +/*?*/ else +/*?*/ { +/*?*/ Pop(); +/*?*/ SetError(errIllegalParameter); +/*?*/ } +/*N*/ } +/*N*/ default : +/*?*/ Pop(); +/*?*/ SetError(errIllegalParameter); +/*N*/ } +/*N*/ } +/*N*/ rVal = ::rtl::math::approxSub( fSumSqr, fSum*fSum/rValCount ); +/*N*/ } + + +void ScInterpreter::ScVar( BOOL bTextAsZero ) +{ + double nVal; + double nValCount; + GetStVarParams( nVal, nValCount, bTextAsZero ); + PushDouble(nVal / (nValCount - 1.0)); +} + + +void ScInterpreter::ScVarP( BOOL bTextAsZero ) +{ + double nVal; + double nValCount; + GetStVarParams( nVal, nValCount, bTextAsZero ); + PushDouble(nVal / nValCount); +} + + +void ScInterpreter::ScStDev( BOOL bTextAsZero ) +{ + double nVal; + double nValCount; + GetStVarParams( nVal, nValCount, bTextAsZero ); + PushDouble(sqrt(nVal / (nValCount - 1.0))); +} + + +/*N*/ void ScInterpreter::ScStDevP( BOOL bTextAsZero ) +/*N*/ { +/*N*/ double nVal; +/*N*/ double nValCount; +/*N*/ GetStVarParams( nVal, nValCount, bTextAsZero ); +/*N*/ PushDouble(sqrt(nVal / nValCount)); +/*N*/ } + + +void ScInterpreter::ScColumns() +{ + BYTE nParamCount = GetByte(); + ULONG nVal = 0; + USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; + for (USHORT i = 1; i <= nParamCount; i++) + { + switch ( GetStackType() ) + { + case svSingleRef: + PopError(); + nVal++; + break; + case svDoubleRef: + PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + nVal += (nTab2 - nTab1 + 1) * (nCol2 - nCol1 + 1); + break; + case svMatrix: + { + ScMatrix* pMat = PopMatrix(); + if (pMat) + { + USHORT nC, nR; + pMat->GetDimensions(nC, nR); + nVal += nC; + } + } + break; + default: + PopError(); + SetError(errIllegalParameter); + } + } + PushDouble((double)nVal); +} + + +void ScInterpreter::ScRows() +{ + BYTE nParamCount = GetByte(); + ULONG nVal = 0; + USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; + for (USHORT i = 1; i <= nParamCount; i++) + { + switch ( GetStackType() ) + { + case svSingleRef: + PopError(); + nVal++; + break; + case svDoubleRef: + PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + nVal += (nTab2 - nTab1 + 1) * (nRow2 - nRow1 + 1); + break; + case svMatrix: + { + ScMatrix* pMat = PopMatrix(); + if (pMat) + { + USHORT nC, nR; + pMat->GetDimensions(nC, nR); + nVal += nR; + } + } + break; + default: + PopError(); + SetError(errIllegalParameter); + } + } + PushDouble((double)nVal); +} + +void ScInterpreter::ScTables() +{ + BYTE nParamCount = GetByte(); + ULONG nVal; + if ( nParamCount == 0 ) + nVal = pDok->GetTableCount(); + else + { + nVal = 0; + USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; + for (USHORT i = 1; i <= nParamCount; i++) + { + switch ( GetStackType() ) + { + case svSingleRef: + PopError(); + nVal++; + break; + case svDoubleRef: + PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + nVal += (nTab2 - nTab1 + 1); + break; + case svMatrix: + PopError(); + nVal++; + break; + default: + PopError(); + SetError( errIllegalParameter ); + } + } + } + PushDouble( (double) nVal ); +} + + +void ScInterpreter::ScColumn() +{ + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 0, 1 ) ) + { + double nVal; + if (nParamCount == 0) + nVal = aPos.Col() + 1; + else + { + switch ( GetStackType() ) + { + case svSingleRef : + { + USHORT nCol1, nRow1, nTab1; + PopSingleRef( nCol1, nRow1, nTab1 ); + nVal = (double) (nCol1 + 1); + } + break; + case svDoubleRef : + { + USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; + PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); + if (nCol2 > nCol1) + { + USHORT nMatInd; + ScMatrix* pResMat = GetNewMat(nCol2-nCol1+1, 1, nMatInd); + if (pResMat) + { + for (USHORT i = nCol1; i <= nCol2; i++) + pResMat->PutDouble((double)(i+1), i-nCol1, 0); + PushMatrix(pResMat); + nRetMat = nMatInd; + return; + } + else + { + SetError( errIllegalParameter ); + nVal = 0.0; + } + } + else + nVal = (double) (nCol1 + 1); + } + break; + default: + SetError( errIllegalParameter ); + nVal = 0.0; + } + } + PushDouble( nVal ); + } +} + + +void ScInterpreter::ScRow() +{ + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 0, 1 ) ) + { + double nVal; + if (nParamCount == 0) + nVal = aPos.Row() + 1; + else + { + switch ( GetStackType() ) + { + case svSingleRef : + { + USHORT nCol1, nRow1, nTab1; + PopSingleRef( nCol1, nRow1, nTab1 ); + nVal = (double) (nRow1 + 1); + } + break; + case svDoubleRef : + { + USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; + PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); + if (nRow2 > nRow1) + { + USHORT nMatInd; + ScMatrix* pResMat = GetNewMat(1, nRow2-nRow1+1, nMatInd); + if (pResMat) + { + for (USHORT i = nRow1; i <= nRow2; i++) + pResMat->PutDouble((double)(i+1), 0, i-nRow1); + PushMatrix(pResMat); + nRetMat = nMatInd; + return; + } + else + { + SetError( errIllegalParameter ); + nVal = 0.0; + } + } + else + nVal = (double) (nRow1 + 1); + } + break; + default: + SetError( errIllegalParameter ); + nVal = 0.0; + } + } + PushDouble( nVal ); + } +} + +void ScInterpreter::ScTable() +{ + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 0, 1 ) ) + { + USHORT nVal = 0; + if ( nParamCount == 0 ) + nVal = aPos.Tab() + 1; + else + { + switch ( GetStackType() ) + { + case svString : + { + String aStr( PopString() ); + if ( pDok->GetTable( aStr, nVal ) ) + ++nVal; + else + SetError( errIllegalArgument ); + } + break; + case svSingleRef : + { + USHORT nCol1, nRow1, nTab1; + PopSingleRef( nCol1, nRow1, nTab1 ); + nVal = nTab1 + 1; + } + break; + case svDoubleRef : + { + USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; + PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); + nVal = nTab1 + 1; + } + break; + default: + SetError( errIllegalParameter ); + } + if ( nGlobalError ) + nVal = 0; + } + PushDouble( (double) nVal ); + } +} + + +/*N*/ void ScInterpreter::ScMatch() +/*N*/ { +/*N*/ BYTE nParamCount = GetByte(); +/*N*/ if ( MustHaveParamCount( nParamCount, 2, 3 ) ) +/*N*/ { +/*N*/ double fTyp; +/*N*/ if (nParamCount == 3) +/*N*/ fTyp = GetDouble(); +/*N*/ else +/*N*/ fTyp = 1.0; +/*N*/ USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; +/*N*/ if (GetStackType() == svDoubleRef) +/*N*/ { +/*N*/ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); +/*N*/ if (nTab1 != nTab2 || (nCol1 != nCol2 && nRow1 != nRow2)) +/*N*/ { +/*N*/ SetIllegalParameter(); +/*N*/ return; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SetIllegalParameter(); +/*N*/ return; +/*N*/ } +/*N*/ if (nGlobalError == 0) +/*N*/ { +/*N*/ double fVal; +/*N*/ String sStr; +/*N*/ ScQueryParam rParam; +/*N*/ rParam.nCol1 = nCol1; +/*N*/ rParam.nRow1 = nRow1; +/*N*/ rParam.nCol2 = nCol2; +/*N*/ rParam.bHasHeader = FALSE; +/*N*/ rParam.bInplace = TRUE; +/*N*/ rParam.bCaseSens = FALSE; +/*N*/ rParam.bRegExp = pDok->GetDocOptions().IsFormulaRegexEnabled(); +/*N*/ rParam.bDuplicate = FALSE; +/*N*/ +/*N*/ ScQueryEntry& rEntry = rParam.GetEntry(0); +/*N*/ rEntry.bDoQuery = TRUE; +/*N*/ if (fTyp < 0.0) +/*N*/ rEntry.eOp = SC_GREATER_EQUAL; +/*N*/ else if (fTyp > 0.0) +/*N*/ rEntry.eOp = SC_LESS_EQUAL; +/*N*/ switch ( GetStackType() ) +/*N*/ { +/*N*/ case svDouble: +/*N*/ { +/*N*/ fVal = GetDouble(); +/*N*/ rEntry.bQueryByString = FALSE; +/*N*/ rEntry.nVal = fVal; +/*N*/ } +/*N*/ break; +/*N*/ case svString: +/*N*/ { +/*N*/ sStr = GetString(); +/*N*/ rEntry.bQueryByString = TRUE; +/*N*/ *rEntry.pStr = sStr; +/*N*/ } +/*N*/ break; +/*N*/ case svDoubleRef : +/*N*/ case svSingleRef : +/*N*/ { +/*N*/ ScAddress aAdr; +/*N*/ if ( !PopDoubleRefOrSingleRef( aAdr ) ) +/*N*/ { +/*N*/ PushInt(0); +/*N*/ return ; +/*N*/ } +/*N*/ ScBaseCell* pCell = GetCell( aAdr ); +/*N*/ if (HasCellValueData(pCell)) +/*N*/ { +/*N*/ fVal = GetCellValue( aAdr, pCell ); +/*N*/ rEntry.bQueryByString = FALSE; +/*N*/ rEntry.nVal = fVal; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ GetCellString(sStr, pCell); +/*N*/ rEntry.bQueryByString = TRUE; +/*N*/ *rEntry.pStr = sStr; +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ default: +/*N*/ { +/*N*/ SetIllegalParameter(); +/*N*/ return; +/*N*/ } +/*N*/ } +/*N*/ if ( rEntry.bQueryByString ) +/*N*/ rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok ); +/*N*/ USHORT nDelta, nR, nC; +/*N*/ if (nCol1 == nCol2) +/*N*/ { // search row in column +/*N*/ rParam.nRow2 = nRow2; +/*N*/ rEntry.nField = nCol1; +/*N*/ ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE); +/*N*/ if (fTyp == 0.0) +/*N*/ { // EQUAL +/*N*/ if (aCellIter.GetFirst()) +/*N*/ nR = aCellIter.GetRow(); +/*N*/ else +/*N*/ { +/*N*/ SetNV(); +/*N*/ return; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { // <= or >= +/*N*/ aCellIter.SetStopOnMismatch( TRUE ); +/*N*/ if ( aCellIter.GetFirst() ) +/*N*/ { +/*N*/ do +/*N*/ { +/*N*/ nR = aCellIter.GetRow(); +/*N*/ } while ( aCellIter.GetNext() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SetNV(); +/*N*/ return; +/*N*/ } +/*N*/ } +/*N*/ nDelta = nR - nRow1; +/*N*/ } +/*N*/ else +/*N*/ { // search column in row +/*N*/ rParam.nRow2 = nRow1; +/*N*/ rEntry.nField = nCol1; +/*N*/ ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE); +/*N*/ // Advance Entry.nField in Iterator if column changed +/*N*/ aCellIter.SetAdvanceQueryParamEntryField( TRUE ); +/*N*/ if (fTyp == 0.0) +/*N*/ { // EQUAL +/*N*/ if ( aCellIter.GetFirst() ) +/*N*/ nC = aCellIter.GetCol(); +/*N*/ else +/*N*/ { +/*N*/ SetNV(); +/*N*/ return; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { // <= or >= +/*N*/ aCellIter.SetStopOnMismatch( TRUE ); +/*N*/ if ( aCellIter.GetFirst() ) +/*N*/ { +/*N*/ do +/*N*/ { +/*N*/ nC = aCellIter.GetCol(); +/*N*/ } while ( aCellIter.GetNext() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SetNV(); +/*N*/ return; +/*N*/ } +/*N*/ } +/*N*/ nDelta = nC - nCol1; +/*N*/ } +/*N*/ PushDouble((double) (nDelta + 1)); +/*N*/ } +/*N*/ else +/*N*/ SetIllegalParameter(); +/*N*/ } +/*N*/ } + + +void ScInterpreter::ScCountEmptyCells() +{ + if ( MustHaveParamCount( GetByte(), 1 ) ) + { + long nMaxCount = 0, nCount = 0; + CellType eCellType; + switch (GetStackType()) + { + case svSingleRef : + { + nMaxCount = 1; + ScAddress aAdr; + PopSingleRef( aAdr ); + eCellType = GetCellType( GetCell( aAdr ) ); + if (eCellType != CELLTYPE_NONE && eCellType != CELLTYPE_NOTE) + nCount = 1; + } + break; + case svDoubleRef : + { + USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; + PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + nMaxCount = (nRow2 - nRow1 + 1) * (nCol2 - nCol1 + 1) + * (nTab2 - nTab1 + 1); + ScBaseCell* pCell; + ScCellIterator aDocIter(pDok, nCol1, nRow1, nTab1, + nCol2, nRow2, nTab2, glSubTotal); + if (pCell = aDocIter.GetFirst()) + { + do + { + if ((eCellType = pCell->GetCellType()) != CELLTYPE_NONE + && eCellType != CELLTYPE_NOTE) + nCount++; + } while ( pCell = aDocIter.GetNext() ); + } + } + break; + default : SetError(errIllegalParameter); break; + } + PushDouble(nMaxCount - nCount); + } +} + + + void ScInterpreter::ScCountIf() + { + if ( MustHaveParamCount( GetByte(), 2 ) ) + { + String rString; + double fVal; + BOOL bIsString = TRUE; + switch ( GetStackType() ) + { + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) + { + PushInt(0); + return ; + } + ScBaseCell* pCell = GetCell( aAdr ); + switch ( GetCellType( pCell ) ) + { + case CELLTYPE_VALUE : + fVal = GetCellValue( aAdr, pCell ); + bIsString = FALSE; + break; + case CELLTYPE_FORMULA : + if( ((ScFormulaCell*)pCell)->IsValue() ) + { + fVal = GetCellValue( aAdr, pCell ); + bIsString = FALSE; + } + else + GetCellString(rString, pCell); + break; + case CELLTYPE_STRING : + case CELLTYPE_EDIT : + GetCellString(rString, pCell); + break; + default: + fVal = 0.0; + bIsString = FALSE; + } + } + break; + case svString: + rString = GetString(); + break; + default: + { + fVal = GetDouble(); + bIsString = FALSE; + } + } + USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; + switch ( GetStackType() ) + { + case svDoubleRef : + PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); + break; + case svSingleRef : + PopSingleRef( nCol1, nRow1, nTab1 ); + nCol2 = nCol1; + nRow2 = nRow1; + nTab2 = nTab1; + break; + default: + SetIllegalParameter(); + return ; + } + if ( nTab1 != nTab2 ) + { + SetIllegalParameter(); + return; + } + if (nCol1 > nCol2) + { + SetIllegalParameter(); + return; + } + if (nGlobalError == 0) + { + ScQueryParam rParam; + rParam.nRow1 = nRow1; + rParam.nRow2 = nRow2; + rParam.bHasHeader = FALSE; + rParam.bInplace = TRUE; + rParam.bCaseSens = FALSE; + rParam.bRegExp = pDok->GetDocOptions().IsFormulaRegexEnabled(); + rParam.bDuplicate = FALSE; + + ScQueryEntry& rEntry = rParam.GetEntry(0); + rEntry.bDoQuery = TRUE; + if (!bIsString) + { + rEntry.bQueryByString = FALSE; + rEntry.nVal = fVal; + rEntry.eOp = SC_EQUAL; + } + else if( rString.Len() ) + { + rParam.FillInExcelSyntax(rString,(USHORT) 0); + sal_uInt32 nIndex = 0; + rEntry.bQueryByString = + !(pFormatter->IsNumberFormat( + *rEntry.pStr, nIndex, rEntry.nVal)); + if ( rEntry.bQueryByString ) + rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok ); + } + else + { + PushInt( 0 ); + return; + } + double fSum = 0.0; + rParam.nCol1 = nCol1; + rParam.nCol2 = nCol2; + rEntry.nField = nCol1; + ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE); + // Entry.nField im Iterator bei Spaltenwechsel weiterschalten + aCellIter.SetAdvanceQueryParamEntryField( TRUE ); + if ( aCellIter.GetFirst() ) + { + do + { + fSum++; + } while ( aCellIter.GetNext() ); + } + PushDouble(fSum); + } + else + SetIllegalParameter(); + } + } + + + void ScInterpreter::ScSumIf() + { + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 2, 3 ) ) + { + USHORT nCol3, nRow3, nTab3, nCol4, nRow4, nTab4; + if (nParamCount == 3) + { + switch ( GetStackType() ) + { + case svDoubleRef : + PopDoubleRef( nCol3, nRow3, nTab3, nCol4, nRow4, nTab4 ); + break; + case svSingleRef : + PopSingleRef( nCol3, nRow3, nTab3 ); + nCol4 = nCol3; + nRow4 = nRow3; + nTab4 = nTab3; + break; + default: + SetIllegalParameter(); + return ; + } + if ( nTab3 != nTab4 ) + { + SetIllegalParameter(); + return; + } + } + String rString; + double fVal; + BOOL bIsString = TRUE; + switch ( GetStackType() ) + { + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) + { + PushInt(0); + return ; + } + ScBaseCell* pCell = GetCell( aAdr ); + switch ( GetCellType( pCell ) ) + { + case CELLTYPE_VALUE : + fVal = GetCellValue( aAdr, pCell ); + bIsString = FALSE; + break; + case CELLTYPE_FORMULA : + if( ((ScFormulaCell*)pCell)->IsValue() ) + { + fVal = GetCellValue( aAdr, pCell ); + bIsString = FALSE; + } + else + GetCellString(rString, pCell); + break; + case CELLTYPE_STRING : + case CELLTYPE_EDIT : + GetCellString(rString, pCell); + break; + default: + fVal = 0.0; + bIsString = FALSE; + } + } + break; + case svString: + rString = GetString(); + break; + default: + { + fVal = GetDouble(); + bIsString = FALSE; + } + } + USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; + switch ( GetStackType() ) + { + case svDoubleRef : + PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); + break; + case svSingleRef : + PopSingleRef( nCol1, nRow1, nTab1 ); + nCol2 = nCol1; + nRow2 = nRow1; + nTab2 = nTab1; + break; + default: + SetIllegalParameter(); + return ; + } + if ( nTab1 != nTab2 ) + { + SetIllegalParameter(); + return; + } + if (nParamCount != 3) + { + nCol3 = nCol1; + nRow3 = nRow1; + nTab3 = nTab1; + nCol4 = nCol2; + nRow4 = nRow2; + nTab4 = nTab2; + } + else if (nCol4 - nCol3 != nCol2 - nCol1 || + nRow4 - nRow3 != nRow2 - nRow1 || nCol1 > nCol2) + { + SetIllegalParameter(); + return; + } + if (nGlobalError == 0) + { + ScQueryParam rParam; + rParam.nRow1 = nRow1; + rParam.nRow2 = nRow2; + rParam.bHasHeader = FALSE; + rParam.bInplace = TRUE; + rParam.bCaseSens = FALSE; + rParam.bRegExp = pDok->GetDocOptions().IsFormulaRegexEnabled(); + rParam.bDuplicate = FALSE; + + ScQueryEntry& rEntry = rParam.GetEntry(0); + rEntry.bDoQuery = TRUE; + if (!bIsString) + { + rEntry.bQueryByString = FALSE; + rEntry.nVal = fVal; + rEntry.eOp = SC_EQUAL; + } + else + { + rParam.FillInExcelSyntax(rString,(USHORT) 0); + sal_uInt32 nIndex = 0; + rEntry.bQueryByString = + !(pFormatter->IsNumberFormat( + *rEntry.pStr, nIndex, rEntry.nVal)); + if ( rEntry.bQueryByString ) + rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok ); + } + double fSum = 0.0; + double fMem = 0.0; + BOOL bNull = TRUE; + ScAddress aAdr; + aAdr.SetTab( nTab3 ); + rParam.nCol1 = nCol1; + rParam.nCol2 = nCol2; + rEntry.nField = nCol1; + short nColDiff = nCol3 - nCol1; + short nRowDiff = nRow3 - nRow1; + ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE); + // Entry.nField im Iterator bei Spaltenwechsel weiterschalten + aCellIter.SetAdvanceQueryParamEntryField( TRUE ); + if ( aCellIter.GetFirst() ) + { + do + { + aAdr.SetCol( aCellIter.GetCol() + nColDiff ); + aAdr.SetRow( aCellIter.GetRow() + nRowDiff ); + ScBaseCell* pCell = GetCell( aAdr ); + if ( HasCellValueData(pCell) ) + { + fVal = GetCellValue( aAdr, pCell ); + if ( bNull && fVal != 0.0 ) + { + bNull = FALSE; + fMem = fVal; + } + else + fSum += fVal; + } + } while ( aCellIter.GetNext() ); + } + PushDouble( ::rtl::math::approxAdd( fSum, fMem ) ); + } + else + SetIllegalParameter(); + } + } + + + void ScInterpreter::ScLookup() + { + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 2, 3 ) ) + return ; + USHORT nC3 = 0, nC1 = 0; + USHORT nR3 = 0, nR1 = 0; + ScMatrix* pMat3 = NULL; + ScMatrix* pMat1 = NULL; + USHORT nCol1 = 0; + USHORT nRow1 = 0; + USHORT nTab1 = 0; + USHORT nCol2 = 0; + USHORT nRow2 = 0; + USHORT nTab2 = 0; + USHORT nCol3 = 0; + USHORT nRow3 = 0; + USHORT nTab3 = 0; + USHORT nCol4 = 0; + USHORT nRow4 = 0; + USHORT nTab4 = 0; + USHORT nDelta; + + // param 3: data range + if ( nParamCount == 3 ) + { + if (GetStackType() == svDoubleRef) + { + PopDoubleRef(nCol3, nRow3, nTab3, nCol4, nRow4, nTab4); + if (nTab3 != nTab4 || (nCol3 != nCol4 && nRow3 != nRow4)) + { + SetIllegalParameter(); + return; + } + } + else if (GetStackType() == svMatrix) + { + pMat3 = PopMatrix(); + if (pMat3) + { + pMat3->GetDimensions(nC3, nR3); + if (nC3 != 1 && nR3 != 1) + { + SetIllegalParameter(); + return; + } + } + else + { + SetIllegalParameter(); + return; + } + } + else + { + SetIllegalParameter(); + return; + } + } + + // param 2: key range, or key range and data range + if (GetStackType() == svDoubleRef) + { + PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + if ( nTab1 != nTab2 || (nParamCount == 3 && nCol1 != nCol2 && nRow1 != nRow2) ) + { + SetIllegalParameter(); + return; + } + } + else if (GetStackType() == svMatrix) + { + pMat1 = PopMatrix(); + if (pMat1) + { + pMat1->GetDimensions(nC1, nR1); + if (nC1 != 1 && nR1 != 1) + { + SetIllegalParameter(); + return; + } + } + else + { + SetIllegalParameter(); + return; + } + } + else + { + SetIllegalParameter(); + return; + } + BOOL bSpMatrix, bSpVector; + USHORT nMatCount, nVecCount; + if (pMat1 == NULL) + { + if (nRow1 == nRow2) + { + nMatCount = nCol2 - nCol1 + 1; + bSpMatrix = FALSE; + } + else + { + nMatCount = nRow2 - nRow1 + 1; + bSpMatrix = TRUE; + } + } + else + { + if (nR1 == 1) + { + nMatCount = nC1; + bSpMatrix = FALSE; + } + else + { + nMatCount = nR1; + bSpMatrix = TRUE; + } + } + if ( nParamCount < 3 ) + { + nVecCount = nMatCount; + bSpVector = bSpMatrix; + } + else if (pMat3 == NULL) + { + if (nRow3 == nRow4) + { + nVecCount = nCol4 - nCol3 + 1; + bSpVector = FALSE; + } + else + { + nVecCount = nRow4 - nRow3 + 1; + bSpVector = TRUE; + } + } + else + { + if (nR3 == 1) + { + nVecCount = nC3; + bSpVector = FALSE; + } + else + { + nVecCount = nR3; + bSpVector = TRUE; + } + } + if (nGlobalError == 0 && nVecCount == nMatCount) + { + String sStr; + ScQueryParam rParam; + rParam.nCol1 = nCol1; + rParam.nRow1 = nRow1; + rParam.nCol2 = (bSpMatrix ? nCol1 : nCol2); + rParam.nRow2 = (bSpMatrix ? nRow2 : nRow1); + rParam.bHasHeader = FALSE; + rParam.bInplace = TRUE; + rParam.bCaseSens = FALSE; + rParam.bRegExp = pDok->GetDocOptions().IsFormulaRegexEnabled(); + rParam.bDuplicate = FALSE; + + ScQueryEntry& rEntry = rParam.GetEntry(0); + rEntry.bDoQuery = TRUE; + rEntry.eOp = SC_LESS_EQUAL; + rEntry.nField = nCol1; + switch ( GetStackType() ) + { + case svDouble: + { + rEntry.bQueryByString = FALSE; + rEntry.nVal = GetDouble(); + } + break; + case svString: + { + sStr = GetString(); + rEntry.bQueryByString = TRUE; + *rEntry.pStr = sStr; + } + break; + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) + { + PushInt(0); + return ; + } + ScBaseCell* pCell = GetCell( aAdr ); + if (HasCellValueData(pCell)) + { + rEntry.bQueryByString = FALSE; + rEntry.nVal = GetCellValue( aAdr, pCell ); + } + else + { + if ( GetCellType( pCell ) == CELLTYPE_NOTE ) + { + rEntry.bQueryByString = FALSE; + rEntry.nVal = 0.0; + } + else + { + GetCellString(sStr, pCell); + rEntry.bQueryByString = TRUE; + *rEntry.pStr = sStr; + } + } + } + break; + default: + { + SetIllegalParameter(); + return; + } + } + if ( rEntry.bQueryByString ) + rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok ); + if (pMat1) + { + if (rEntry.bQueryByString) + { + //!!!!!!! + //! TODO: enable regex on matrix strings + //!!!!!!! + BOOL bFound = FALSE; + sal_Int32 nRes; + String aParamStr = *rEntry.pStr; + USHORT i = 0; + for ( i = 0; i < nMatCount; i++) + { + if (!pMat1->IsValue(i)) + { + nRes = ScGlobal::pCollator->compareString( + pMat1->GetString(i), aParamStr ); + if (nRes == COMPARE_EQUAL) + { + bFound = TRUE; + nDelta = i; + } + else if (nRes == COMPARE_LESS) + i = nMatCount+1; + } + } + if (i == nMatCount+2 && !bFound) + { + SetNV(); + return; + } + else if (!bFound) + nDelta = i-1; + } + else + { + BOOL bFound = FALSE; + double fVal1; + USHORT i = 0; + for ( i = 0; i < nMatCount; i++) + { + if (pMat1->IsValue(i)) + fVal1 = pMat1->GetDouble(i); + else + fVal1 = MAXDOUBLE; + if (fVal1 == rEntry.nVal) + { + bFound = TRUE; + nDelta = i; + } + else if (fVal1 > rEntry.nVal) + i = nMatCount+1; + } + if (i == nMatCount+2 && !bFound) + { + SetNV(); + return; + } + else if (!bFound) + nDelta = i-1; + } + } + else if (bSpMatrix) // lookup in column + { + rEntry.eOp = SC_LESS_EQUAL; + ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE); + USHORT nC, nR; + if ( aCellIter.FindEqualOrSortedLastInRange( nC, nR ) ) + nDelta = nR - nRow1; + else + { + SetNV(); + return; + } + } + else // lookup in row + { + rEntry.eOp = SC_LESS_EQUAL; + ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE); + // advance Entry.nField in Iterator upon switching columns + aCellIter.SetAdvanceQueryParamEntryField( TRUE ); + USHORT nC, nR; + if ( aCellIter.FindEqualOrSortedLastInRange( nC, nR ) ) + nDelta = nC - nCol1; + else + { + SetNV(); + return; + } + } + } + else + { + SetIllegalParameter(); + return; + } + if (pMat3) + { + if (pMat3->IsValue(nDelta)) + PushDouble(pMat3->GetDouble(nDelta)); + else + PushString(pMat3->GetString(nDelta)); + } + else + { + ScAddress aAdr; + if ( nParamCount < 3 ) + { + if (bSpVector) + { + aAdr.SetCol( nCol2 ); // data in right col of key/data range + aAdr.SetRow( nRow1 + nDelta ); + } + else + { + aAdr.SetCol( nCol1 + nDelta ); + aAdr.SetRow( nRow2 ); // data in lower row of key/data range + } + aAdr.SetTab( nTab1 ); + } + else + { + if (bSpVector) + { + aAdr.SetCol( nCol3 ); + aAdr.SetRow( nRow3 + nDelta ); + } + else + { + aAdr.SetCol( nCol3 + nDelta ); + aAdr.SetRow( nRow3 ); + } + aAdr.SetTab( nTab3 ); + } + ScBaseCell* pCell = GetCell( aAdr ); + if (HasCellValueData(pCell)) + PushDouble(GetCellValue( aAdr, pCell )); + else + { + String aStr; + GetCellString(aStr, pCell); + PushString(aStr); + } + } + } + + + void ScInterpreter::ScHLookup() + { + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 3, 4 ) ) + { + BOOL bSorted; + if (nParamCount == 4) + bSorted = GetBool(); + else + bSorted = TRUE; + double fIndex = ::rtl::math::approxFloor( GetDouble() ) - 1.0; + ScMatrix* pMat = NULL; + USHORT nC = 0, nR = 0; + USHORT nCol1 = 0, nRow1 = 0, nTab1 = 0, nCol2 = 0, nRow2 = 0, nTab2 = 0; + if (GetStackType() == svDoubleRef) + { + PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + if (nTab1 != nTab2) + { + SetIllegalParameter(); + return; + } + } + else if (GetStackType() == svMatrix) + { + pMat = PopMatrix(); + if (pMat) + pMat->GetDimensions(nC, nR); + else + { + SetIllegalParameter(); + return; + } + } + else + { + SetIllegalParameter(); + return; + } + if ( fIndex < 0.0 || (pMat ? (fIndex >= nR) : (fIndex+nRow1 > nRow2)) ) + { + SetIllegalArgument(); + return; + } + USHORT nZIndex = (USHORT) fIndex; + if (!pMat) + nZIndex += nRow1; // Wertzeile + if (nGlobalError == 0) + { + String sStr; + ScQueryParam rParam; + rParam.nCol1 = nCol1; + rParam.nRow1 = nRow1; + rParam.nCol2 = nCol2; + rParam.nRow2 = nRow1; // nur in der ersten Zeile suchen + rParam.bHasHeader = FALSE; + rParam.bInplace = TRUE; + rParam.bCaseSens = FALSE; + rParam.bRegExp = pDok->GetDocOptions().IsFormulaRegexEnabled(); + rParam.bDuplicate = FALSE; + + ScQueryEntry& rEntry = rParam.GetEntry(0); + rEntry.bDoQuery = TRUE; + if ( bSorted ) + rEntry.eOp = SC_LESS_EQUAL; + switch ( GetStackType() ) + { + case svDouble: + { + rEntry.bQueryByString = FALSE; + rEntry.nVal = GetDouble(); + } + break; + case svString: + { + sStr = GetString(); + rEntry.bQueryByString = TRUE; + *rEntry.pStr = sStr; + } + break; + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) + { + PushInt(0); + return ; + } + ScBaseCell* pCell = GetCell( aAdr ); + if (HasCellValueData(pCell)) + { + rEntry.bQueryByString = FALSE; + rEntry.nVal = GetCellValue( aAdr, pCell ); + } + else + { + if ( GetCellType( pCell ) == CELLTYPE_NOTE ) + { + rEntry.bQueryByString = FALSE; + rEntry.nVal = 0.0; + } + else + { + GetCellString(sStr, pCell); + rEntry.bQueryByString = TRUE; + *rEntry.pStr = sStr; + } + } + } + break; + default: + { + SetIllegalParameter(); + return; + } + } + if ( rEntry.bQueryByString ) + rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok ); + if (pMat) + { + USHORT nMatCount = nC; + short nDelta = -1; + if (rEntry.bQueryByString) + { + //!!!!!!! + //! TODO: enable regex on matrix strings + //!!!!!!! + String aParamStr = *rEntry.pStr; + USHORT i; + if ( bSorted ) + { + for (i = 0; i < nMatCount; i++) + { + if (pMat->IsString(i, 0)) + { + if ( ScGlobal::pTransliteration->isEqual( + pMat->GetString(i,0), aParamStr ) ) + i = nMatCount+1; + else + nDelta = i; + } + else + nDelta = i; + } + } + else + { + for (i = 0; i < nMatCount; i++) + { + if (pMat->IsString(i, 0)) + { + if ( ScGlobal::pTransliteration->isEqual( + pMat->GetString(i,0), aParamStr ) ) + { + nDelta = i; + i = nMatCount + 1; + } + } + } + } + } + else + { + double fVal1; + USHORT i; + if ( bSorted ) + { + for (i = 0; i < nMatCount; i++) + { + if (!pMat->IsString(i, 0)) + fVal1 = pMat->GetDouble(i,0); + else + fVal1 = MAXDOUBLE; + if (fVal1 <= rEntry.nVal) + nDelta = i; + else + i = nMatCount+1; + } + } + else + { + for (i = 0; i < nMatCount; i++) + { + if (!pMat->IsString(i, 0)) + fVal1 = pMat->GetDouble(i,0); + else + fVal1 = MAXDOUBLE; + if (fVal1 == rEntry.nVal) + { + nDelta = i; + i = nMatCount + 1; + } + } + } + } + if ( nDelta >= 0 ) + { + if (!pMat->IsString(nDelta, nZIndex)) + PushDouble(pMat->GetDouble(nDelta, nZIndex)); + else + PushString(pMat->GetString(nDelta, nZIndex)); + } + else + SetNV(); + } + else + { + rEntry.nField = nCol1; + BOOL bFound = FALSE; + USHORT nC; + if ( bSorted ) + rEntry.eOp = SC_LESS_EQUAL; + ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE); + // advance Entry.nField in Iterator upon switching columns + aCellIter.SetAdvanceQueryParamEntryField( TRUE ); + if ( bSorted ) + { + USHORT nR; + bFound = aCellIter.FindEqualOrSortedLastInRange( nC, nR ); + } + else if ( aCellIter.GetFirst() ) + { + bFound = TRUE; + nC = aCellIter.GetCol(); + if ( bSorted ) + { + while ( aCellIter.GetNext() ) + nC = aCellIter.GetCol(); + } + } + if ( bFound ) + { + ScBaseCell* pCell; + ScAddress aAdr( nC, nZIndex, nTab1 ); + if ( HasCellValueData( pCell = GetCell( aAdr ) ) ) + PushDouble(GetCellValue( aAdr, pCell )); + else + { + String aStr; + GetCellString(aStr, pCell); + PushString(aStr); + } + } + else + SetNV(); + } + } + else + SetIllegalParameter(); + } + } + + +/*N*/ void ScInterpreter::ScVLookup() +/*N*/ { +/*N*/ BYTE nParamCount = GetByte(); +/*N*/ if ( MustHaveParamCount( nParamCount, 3, 4 ) ) +/*N*/ { +/*N*/ BOOL bSorted; +/*N*/ if (nParamCount == 4) +/*N*/ bSorted = GetBool(); +/*N*/ else +/*N*/ bSorted = TRUE; +/*N*/ double fIndex = ::rtl::math::approxFloor( GetDouble() ) - 1.0; +/*N*/ ScMatrix* pMat = NULL; +/*N*/ USHORT nC = 0, nR = 0; +/*N*/ USHORT nCol1 = 0, nRow1 = 0, nTab1 = 0, nCol2 = 0, nRow2 = 0, nTab2 = 0; +/*N*/ if (GetStackType() == svDoubleRef) +/*N*/ { +/*N*/ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); +/*N*/ if (nTab1 != nTab2) +/*N*/ { +/*?*/ SetIllegalParameter(); +/*?*/ return; +/*N*/ } +/*N*/ } +/*N*/ else if (GetStackType() == svMatrix) +/*N*/ { +/*?*/ pMat = PopMatrix(); +/*?*/ if (pMat) +/*?*/ pMat->GetDimensions(nC, nR); +/*?*/ else +/*?*/ { +/*?*/ SetIllegalParameter(); +/*?*/ return; +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ SetIllegalParameter(); +/*?*/ return; +/*N*/ } +/*N*/ if ( fIndex < 0.0 || (pMat ? (fIndex >= nC) : (fIndex+nCol1 > nCol2)) ) +/*N*/ { +/*?*/ SetIllegalArgument(); +/*?*/ return; +/*N*/ } +/*N*/ USHORT nSpIndex = (USHORT) fIndex; +/*N*/ if (!pMat) +/*N*/ nSpIndex += nCol1; // Wertspalte +/*N*/ if (nGlobalError == 0) +/*N*/ { +/*N*/ String sStr; +/*N*/ ScQueryParam rParam; +/*N*/ rParam.nCol1 = nCol1; +/*N*/ rParam.nRow1 = nRow1; +/*N*/ rParam.nCol2 = nCol1; // nur in der ersten Spalte suchen +/*N*/ rParam.nRow2 = nRow2; +/*N*/ rParam.bHasHeader = FALSE; +/*N*/ rParam.bInplace = TRUE; +/*N*/ rParam.bCaseSens = FALSE; +/*N*/ rParam.bRegExp = pDok->GetDocOptions().IsFormulaRegexEnabled(); +/*N*/ rParam.bDuplicate = FALSE; +/*N*/ +/*N*/ ScQueryEntry& rEntry = rParam.GetEntry(0); +/*N*/ rEntry.bDoQuery = TRUE; +/*N*/ if ( bSorted ) +/*N*/ rEntry.eOp = SC_LESS_EQUAL; +/*N*/ switch ( GetStackType() ) +/*N*/ { +/*N*/ case svDouble: +/*N*/ { +/*N*/ rEntry.bQueryByString = FALSE; +/*N*/ rEntry.nVal = GetDouble(); +/*N*/ } +/*N*/ break; +/*N*/ case svString: +/*N*/ { +/*?*/ sStr = GetString(); +/*?*/ rEntry.bQueryByString = TRUE; +/*?*/ *rEntry.pStr = sStr; +/*?*/ } +/*?*/ break; +/*N*/ case svDoubleRef : +/*N*/ case svSingleRef : +/*N*/ { +/*N*/ ScAddress aAdr; +/*N*/ if ( !PopDoubleRefOrSingleRef( aAdr ) ) +/*N*/ { +/*?*/ PushInt(0); +/*?*/ return ; +/*N*/ } +/*N*/ ScBaseCell* pCell = GetCell( aAdr ); +/*N*/ if (HasCellValueData(pCell)) +/*N*/ { +/*?*/ rEntry.bQueryByString = FALSE; +/*?*/ rEntry.nVal = GetCellValue( aAdr, pCell ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( GetCellType( pCell ) == CELLTYPE_NOTE ) +/*N*/ { +/*?*/ rEntry.bQueryByString = FALSE; +/*?*/ rEntry.nVal = 0.0; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ GetCellString(sStr, pCell); +/*N*/ rEntry.bQueryByString = TRUE; +/*N*/ *rEntry.pStr = sStr; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ default: +/*N*/ { +/*?*/ SetIllegalParameter(); +/*?*/ return; +/*N*/ } +/*N*/ } +/*N*/ if ( rEntry.bQueryByString ) +/*N*/ rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok ); +/*N*/ if (pMat) +/*N*/ { +/*?*/ USHORT nMatCount = nR; +/*?*/ short nDelta = -1; +/*?*/ if (rEntry.bQueryByString) +/*?*/ { +/*?*/ //!!!!!!! +/*?*/ //! TODO: enable regex on matrix strings +/*?*/ //!!!!!!! +/*?*/ String aParamStr = *rEntry.pStr; +/*?*/ USHORT i; +/*?*/ if ( bSorted ) +/*?*/ { +/*?*/ for (i = 0; i < nMatCount; i++) +/*?*/ { +/*?*/ if (pMat->IsString(0, i)) +/*?*/ { +/*?*/ if ( ScGlobal::pTransliteration->isEqual( +/*?*/ pMat->GetString(0,i), aParamStr ) ) +/*?*/ i = nMatCount+1; +/*?*/ else +/*?*/ nDelta = i; +/*?*/ } +/*?*/ else +/*?*/ nDelta = i; +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ for (i = 0; i < nMatCount; i++) +/*?*/ { +/*?*/ if (pMat->IsString(0, i)) +/*?*/ { +/*?*/ if ( ScGlobal::pTransliteration->isEqual( +/*?*/ pMat->GetString(0,i), aParamStr ) ) +/*?*/ { +/*?*/ nDelta = i; +/*?*/ i = nMatCount + 1; +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ double fVal1; +/*?*/ USHORT i; +/*?*/ if ( bSorted ) +/*?*/ { +/*?*/ for (i = 0; i < nMatCount; i++) +/*?*/ { +/*?*/ if (!pMat->IsString(0, i)) +/*?*/ fVal1 = pMat->GetDouble(0, i); +/*?*/ else +/*?*/ fVal1 = MAXDOUBLE; +/*?*/ if (fVal1 <= rEntry.nVal) +/*?*/ nDelta = i; +/*?*/ else +/*?*/ i = nMatCount+1; +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ for (i = 0; i < nMatCount; i++) +/*?*/ { +/*?*/ if (!pMat->IsString(0, i)) +/*?*/ fVal1 = pMat->GetDouble(0, i); +/*?*/ else +/*?*/ fVal1 = MAXDOUBLE; +/*?*/ if (fVal1 == rEntry.nVal) +/*?*/ { +/*?*/ nDelta = i; +/*?*/ i = nMatCount + 1; +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ if ( nDelta >= 0 ) +/*?*/ { +/*?*/ if (!pMat->IsString(nSpIndex, nDelta)) +/*?*/ PushDouble(pMat->GetDouble(nSpIndex, nDelta)); +/*?*/ else +/*?*/ PushString(pMat->GetString(nSpIndex, nDelta)); +/*?*/ } +/*?*/ else +/*?*/ SetNV(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ rEntry.nField = nCol1; +/*N*/ BOOL bFound = FALSE; +/*N*/ USHORT nR; +/*N*/ if ( bSorted ) +/*N*/ rEntry.eOp = SC_LESS_EQUAL; +/*N*/ ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE); +/*N*/ if ( bSorted ) +/*N*/ { +/*N*/ USHORT nC; +/*N*/ bFound = aCellIter.FindEqualOrSortedLastInRange( nC, nR ); +/*N*/ } +/*N*/ else if ( aCellIter.GetFirst() ) +/*N*/ { +/*N*/ bFound = TRUE; +/*N*/ nR = aCellIter.GetRow(); +/*N*/ if ( bSorted ) +/*N*/ { +/*?*/ while (aCellIter.GetNext()) +/*?*/ nR = aCellIter.GetRow(); +/*N*/ } +/*N*/ } +/*N*/ if ( bFound ) +/*N*/ { +/*N*/ ScBaseCell* pCell; +/*N*/ ScAddress aAdr( nSpIndex, nR, nTab1 ); +/*N*/ if ( HasCellValueData( pCell = GetCell( aAdr ) ) ) +/*N*/ PushDouble(GetCellValue( aAdr, pCell )); +/*N*/ else +/*N*/ { +/*N*/ String aStr; +/*N*/ GetCellString(aStr, pCell); +/*N*/ PushString(aStr); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ SetNV(); +/*N*/ } +/*N*/ } +/*N*/ else +/*?*/ SetIllegalParameter(); +/*N*/ } +/*N*/ } + +#if defined(WIN) && defined(MSC) +#pragma optimize("",off) +#endif + +/*N*/ void ScInterpreter::ScSubTotal() +/*N*/ { +/*N*/ BYTE nParamCount = GetByte(); +/*N*/ if ( MustHaveParamCountMin( nParamCount, 2 ) ) +/*N*/ { +/*N*/ // Wir muessen den 1. Parameter tief aus dem Stack herausfischen! +/*N*/ const ScToken* p = pStack[ sp - nParamCount ]; +/*N*/ PushTempToken( *p ); +/*N*/ int nFunc = (int) ::rtl::math::approxFloor( GetDouble() ); +/*N*/ if( nFunc < 1 || nFunc > 11 ) +/*N*/ SetIllegalParameter(); +/*N*/ else +/*N*/ { +/*N*/ cPar = nParamCount - 1; +/*N*/ glSubTotal = TRUE; +/*N*/ switch( nFunc ) +/*N*/ { +/*?*/ case SUBTOTAL_FUNC_AVE : ScAverage(); break; +/*?*/ case SUBTOTAL_FUNC_CNT : ScCount(); break; +/*?*/ case SUBTOTAL_FUNC_CNT2 : ScCount2(); break; +/*?*/ case SUBTOTAL_FUNC_MAX : ScMax(); break; +/*?*/ case SUBTOTAL_FUNC_MIN : ScMin(); break; +/*?*/ case SUBTOTAL_FUNC_PROD : ScProduct(); break; +/*?*/ case SUBTOTAL_FUNC_STD : ScStDev(); break; +/*N*/ case SUBTOTAL_FUNC_STDP : ScStDevP(); break; +/*?*/ case SUBTOTAL_FUNC_SUM : ScSum(); break; +/*?*/ case SUBTOTAL_FUNC_VAR : ScVar(); break; +/*?*/ case SUBTOTAL_FUNC_VARP : ScVarP(); break; +/*?*/ default : SetIllegalParameter(); break; +/*N*/ } +/*N*/ glSubTotal = FALSE; +/*N*/ } +/*N*/ // den abgefischten 1. Parameter entfernen +/*N*/ double nVal = GetDouble(); +/*N*/ Pop(); +/*N*/ PushDouble( nVal ); +/*N*/ } +/*N*/ } +#if defined(WIN) && defined(MSC) +#pragma optimize("",on) +#endif + + +BOOL ScInterpreter::GetDBParams(USHORT& rTab, ScQueryParam& rParam, + BOOL& rMissingField ) +{ + BOOL bRet = FALSE; + BOOL bAllowMissingField = FALSE; + if ( rMissingField ) + { + bAllowMissingField = TRUE; + rMissingField = FALSE; + } + if ( GetByte() == 3 ) + { + + USHORT nQCol1, nQRow1, nQTab1, nQCol2, nQRow2, nQTab2; + PopDoubleRef(nQCol1, nQRow1, nQTab1, nQCol2, nQRow2, nQTab2); + + BOOL bByVal = TRUE; + double nVal = 0.0; + String aStr; + ScRange aMissingRange; + BOOL bRangeFake = FALSE; + switch (GetStackType()) + { + case svDouble : + nVal = ::rtl::math::approxFloor( GetDouble() ); + if ( bAllowMissingField && nVal == 0.0 ) + rMissingField = TRUE; // fake missing parameter + break; + case svString : + bByVal = FALSE; + aStr = GetString(); + break; + case svSingleRef : + { + ScAddress aAdr; + PopSingleRef( aAdr ); + ScBaseCell* pCell = GetCell( aAdr ); + if (HasCellValueData(pCell)) + nVal = GetCellValue( aAdr, pCell ); + else + { + bByVal = FALSE; + GetCellString(aStr, pCell); + } + } + break; + case svDoubleRef : + if ( bAllowMissingField ) + { // fake missing parameter for old SO compatibility + bRangeFake = TRUE; + PopDoubleRef( aMissingRange ); + } + else + { + PopError(); + SetError( errIllegalParameter ); + } + break; + case svMissing : + PopError(); + if ( bAllowMissingField ) + rMissingField = TRUE; + else + SetError( errIllegalParameter ); + break; + default: + PopError(); + SetError( errIllegalParameter ); + } + + USHORT nDBCol1, nDBRow1, nDBTab1, nDBCol2, nDBRow2, nDBTab2; + PopDoubleRef(nDBCol1, nDBRow1, nDBTab1, nDBCol2, nDBRow2, nDBTab2); + + if ( nGlobalError == 0 && bRangeFake ) + { + // range parameter must match entire database range + if ( aMissingRange == ScRange( nDBCol1, nDBRow1, nDBTab1, nDBCol2, + nDBRow2, nDBTab2) ) + rMissingField = TRUE; + else + SetError( errIllegalParameter ); + } + + if (nGlobalError == 0) + { + USHORT nField = nDBCol1; + BOOL bFound = TRUE; + if ( rMissingField ) + ; // special case + else if ( bByVal ) + { + if ( nVal <= 0 || nVal > (nDBCol2 - nDBCol1 + 1) ) + bFound = FALSE; + else + nField = Min(nDBCol2, (USHORT)(nDBCol1 + (USHORT)nVal - 1)); + } + else + { + bFound = FALSE; + String aCellStr; + ScAddress aLook( nDBCol1, nDBRow1, nDBTab1 ); + while (!bFound && (aLook.Col() <= nDBCol2)) + { + ScBaseCell* pCell = GetCell( aLook ); + GetCellString( aCellStr, pCell ); + bFound = ScGlobal::pTransliteration->isEqual( aCellStr, aStr ); + if (!bFound) + aLook.IncCol(); + } + nField = aLook.Col(); + } + if (bFound) + { + rParam.nCol1 = nDBCol1; + rParam.nRow1 = nDBRow1; + rParam.nCol2 = nDBCol2; + rParam.nRow2 = nDBRow2; + rParam.nTab = nDBTab1; + rParam.bHasHeader = TRUE; + rParam.bByRow = TRUE; + rParam.bInplace = TRUE; + rParam.bCaseSens = FALSE; + rParam.bRegExp = FALSE; + rParam.bDuplicate = TRUE; + if (pDok->CreateQueryParam(nQCol1, nQRow1, nQCol2, nQRow2, nQTab1, rParam)) + { + // An allowed missing field parameter sets the result field + // to any of the query fields, just to be able to return + // some cell from the iterator. + if ( rMissingField ) + nField = rParam.GetEntry(0).nField; + + rParam.nCol1 = nField; + rParam.nCol2 = nField; + rTab = nDBTab1; + bRet = TRUE; + USHORT nCount = rParam.GetEntryCount(); + for ( USHORT i=0; i < nCount; i++ ) + { + ScQueryEntry& rEntry = rParam.GetEntry(i); + if ( rEntry.bDoQuery ) + { + sal_uInt32 nIndex = 0; + rEntry.bQueryByString = !pFormatter->IsNumberFormat( + *rEntry.pStr, nIndex, rEntry.nVal ); + if ( rEntry.bQueryByString && !rParam.bRegExp ) + rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok ); + } + else + break; // for + } + } + } + } + } + return bRet; +} + + + void ScInterpreter::DBIterator( ScIterFunc eFunc ) + { + USHORT nTab1; + double nErg = 0.0; + double fMem = 0.0; + BOOL bNull = TRUE; + ULONG nCount = 0; + ScQueryParam aQueryParam; + BOOL bMissingField = FALSE; + if ( GetDBParams( nTab1, aQueryParam, bMissingField) ) + { + double nVal; + USHORT nErr; + ScQueryValueIterator aValIter(pDok, nTab1, aQueryParam); + if ( aValIter.GetFirst(nVal, nErr) && !nErr ) + { + switch( eFunc ) + { + case ifPRODUCT: nErg = 1; break; + case ifMAX: nErg = MINDOUBLE; break; + case ifMIN: nErg = MAXDOUBLE; break; + } + do + { + nCount++; + switch( eFunc ) + { + case ifAVERAGE: + case ifSUM: + if ( bNull && nVal != 0.0 ) + { + bNull = FALSE; + fMem = nVal; + } + else + nErg += nVal; + break; + case ifSUMSQ: nErg += nVal * nVal; break; + case ifPRODUCT: nErg *= nVal; break; + case ifMAX: if( nVal > nErg ) nErg = nVal; break; + case ifMIN: if( nVal < nErg ) nErg = nVal; break; + } + } + while ( aValIter.GetNext(nVal, nErr) && !nErr ); + } + SetError(nErr); + } + else + SetIllegalParameter(); + switch( eFunc ) + { + case ifCOUNT: nErg = nCount; break; + case ifSUM: nErg = ::rtl::math::approxAdd( nErg, fMem ); break; + case ifAVERAGE: nErg = ::rtl::math::approxAdd( nErg, fMem ) / nCount; break; + } + PushDouble( nErg ); + } + + + void ScInterpreter::ScDBSum() + { + DBIterator( ifSUM ); + } + + + void ScInterpreter::ScDBCount() + { + USHORT nTab; + ScQueryParam aQueryParam; + BOOL bMissingField = TRUE; + if ( GetDBParams( nTab, aQueryParam, bMissingField) ) + { + ULONG nCount = 0; + if ( bMissingField ) + { // count all matching records + // TODO: currently the QueryIterators only return cell pointers of + // existing cells, so if a query matches an empty cell there's + // nothing returned, and therefor not counted! + // Since this has ever been the case and this code here only came + // into existance to fix #i6899 and it never worked before we'll + // have to live with it until we reimplement the iterators to also + // return empty cells, which would mean to adapt all callers of + // iterators. + ScQueryCellIterator aCellIter( pDok, nTab, aQueryParam); + if ( aCellIter.GetFirst() ) + { + do + { + nCount++; + } while ( aCellIter.GetNext() ); + } + } + else + { // count only matching records with a value in the "result" field + double nVal; + USHORT nErr = 0; + ScQueryValueIterator aValIter( pDok, nTab, aQueryParam); + if ( aValIter.GetFirst( nVal, nErr) && !nErr ) + { + do + { + nCount++; + } while ( aValIter.GetNext( nVal, nErr) && !nErr ); + } + SetError( nErr ); + } + PushDouble( nCount ); + } + else + SetIllegalParameter(); + } + + + void ScInterpreter::ScDBCount2() + { + USHORT nTab; + ScQueryParam aQueryParam; + BOOL bMissingField = FALSE; + if (GetDBParams( nTab, aQueryParam, bMissingField)) + { + ULONG nCount = 0; + ScQueryCellIterator aCellIter(pDok, nTab, aQueryParam); + if ( aCellIter.GetFirst() ) + { + do + { + nCount++; + } while ( aCellIter.GetNext() ); + } + PushDouble(nCount); + } + else + SetIllegalParameter(); + } + + + void ScInterpreter::ScDBAverage() + { + DBIterator( ifAVERAGE ); + } + + + void ScInterpreter::ScDBMax() + { + DBIterator( ifMAX ); + } + + + void ScInterpreter::ScDBMin() + { + DBIterator( ifMIN ); + } + + + void ScInterpreter::ScDBProduct() + { + DBIterator( ifPRODUCT ); + } + + + void ScInterpreter::GetDBStVarParams( double& rVal, double& rValCount ) + { + rValCount = 0.0; + double fSum = 0.0; + double fSumSqr = 0.0; + USHORT nTab; + ScQueryParam aQueryParam; + BOOL bMissingField = FALSE; + if (GetDBParams( nTab, aQueryParam, bMissingField)) + { + double fVal; + USHORT nErr; + ScQueryValueIterator aValIter(pDok, nTab, aQueryParam); + if (aValIter.GetFirst(fVal, nErr) && !nErr) + { + do + { + rValCount++; + fSum += fVal; + fSumSqr += fVal*fVal; + } + while ((nErr == 0) && aValIter.GetNext(fVal, nErr)); + } + SetError(nErr); + } + else + SetIllegalParameter(); + rVal = ::rtl::math::approxSub( fSumSqr, fSum*fSum/rValCount ); + } + + + void ScInterpreter::ScDBStdDev() + { + double fVal, fCount; + GetDBStVarParams( fVal, fCount ); + PushDouble( sqrt(fVal/(fCount-1))); + } + + + void ScInterpreter::ScDBStdDevP() + { + double fVal, fCount; + GetDBStVarParams( fVal, fCount ); + PushDouble( sqrt(fVal/fCount)); + } + + + void ScInterpreter::ScDBVar() + { + double fVal, fCount; + GetDBStVarParams( fVal, fCount ); + PushDouble(fVal/(fCount-1)); + } + + + void ScInterpreter::ScDBVarP() + { + double fVal, fCount; + GetDBStVarParams( fVal, fCount ); + PushDouble(fVal/fCount); + } + + +void ScInterpreter::ScIndirect() +{ + BYTE nParamCount = GetByte(); +/* + if (nParamCount == 2) + { + double fBool = GetDouble(); + if (fBool == 0.0) // nur TRUE erlaubt!! + { + SetIllegalParameter(); + return; + } + else + nParamCount = 1; + } +*/ + if ( MustHaveParamCount( nParamCount, 1 ) ) + { + USHORT nTab = aPos.Tab(); + String sRefStr( GetString() ); + ScRefTripel aRefTr, aRefTr2; + if ( ConvertDoubleRef( pDok, sRefStr, nTab, aRefTr, aRefTr2 ) ) + PushDoubleRef( aRefTr.GetCol(), aRefTr.GetRow(), aRefTr.GetTab(), + aRefTr2.GetCol(), aRefTr2.GetRow(), aRefTr2.GetTab() ); + else if ( ConvertSingleRef( pDok, sRefStr, nTab, aRefTr ) ) + PushSingleRef( aRefTr.GetCol(), aRefTr.GetRow(), aRefTr.GetTab() ); + else + SetIllegalArgument(); + } +} + + +void ScInterpreter::ScAdress() +{ + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 2, 4 ) ) + { + String sTabStr; + USHORT nAbs = 1; + if (nParamCount == 4) + sTabStr = GetString(); + if (nParamCount >= 3) + nAbs = (USHORT) ::rtl::math::approxFloor(GetDouble()); + USHORT nCol = (USHORT) ::rtl::math::approxFloor(GetDouble()); + USHORT nRow = (USHORT) ::rtl::math::approxFloor(GetDouble()); + if (nCol < 1 || nCol > MAXCOL + 1 || nRow < 1 || nRow > MAXROW + 1) + { + SetIllegalParameter(); + return; + } + else + { + nRow--; + nCol--; + } + String aRefStr; + ScTripel aScTr; + aScTr.SetCol(nCol); + aScTr.SetRow(nRow); + if (nAbs == 4) + aRefStr = aScTr.GetColRowString(); + else + { + aRefStr = aScTr.GetColRowString(TRUE); + if (nAbs == 2) + aRefStr.EraseLeadingChars('$'); + else if (nAbs == 3) + aRefStr.Erase(aRefStr.Search('$',1),1); + } + if ( sTabStr.Len() ) + { + aRefStr.Insert('.',0); + aRefStr.Insert(sTabStr,0); + } + PushString(aRefStr); + } +} + + +void ScInterpreter::ScOffset() +{ + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 3, 5 ) ) + { + short nColNew, nRowNew, nColPlus, nRowPlus; + if (nParamCount == 5) + nColNew = (short) ::rtl::math::approxFloor(GetDouble()); + if (nParamCount >= 4) + nRowNew = (short) ::rtl::math::approxFloor(GetDouble()); + nColPlus = (short) ::rtl::math::approxFloor(GetDouble()); + nRowPlus = (short) ::rtl::math::approxFloor(GetDouble()); + USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; + if ( (nParamCount == 5 && nColNew == 0) + || (nParamCount >= 4 && nRowNew == 0) ) + { + SetIllegalParameter(); + return; + } + if (GetStackType() == svSingleRef) + { + PopSingleRef(nCol1, nRow1, nTab1); + if (nParamCount == 3) + { + nCol1 = (USHORT)((short) nCol1 + nColPlus); + nRow1 = (USHORT)((short) nRow1 + nRowPlus); + if (nCol1 > MAXCOL || nRow1 > MAXROW) + SetIllegalParameter(); + else + PushSingleRef(nCol1, nRow1, nTab1); + } + else + { + if (nParamCount == 4) + nColNew = 1; + nCol1 = (USHORT)((short)nCol1+nColPlus); // ! nCol1 wird veraendert! + nRow1 = (USHORT)((short)nRow1+nRowPlus); + nCol2 = (USHORT)((short)nCol1+nColNew-1); + nRow2 = (USHORT)((short)nRow1+nRowNew-1); + if (nCol1 > MAXCOL || nRow1 > MAXROW || + nCol2 > MAXCOL || nRow2 > MAXROW) + SetIllegalParameter(); + else + PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1); + } + } + else if (GetStackType() == svDoubleRef) + { + PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + if (nParamCount < 5) + nColNew = nCol2 - nCol1 + 1; + if (nParamCount < 4) + nRowNew = nRow2 - nRow1 + 1; + nCol1 = (USHORT)((short)nCol1+nColPlus); + nRow1 = (USHORT)((short)nRow1+nRowPlus); + nCol2 = (USHORT)((short)nCol1+nColNew-1); + nRow2 = (USHORT)((short)nRow1+nRowNew-1); + if (nCol1 > MAXCOL || nRow1 > MAXROW || + nCol2 > MAXCOL || nRow2 > MAXROW || nTab1 != nTab2) + SetIllegalParameter(); + else + PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1); + } + else + SetIllegalParameter(); + } +} + + +void ScInterpreter::ScIndex() +{ + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 1, 4 ) ) + { + short nBereich, nMaxAnz, nCount; + USHORT nCol, nRow; + if (nParamCount == 4) + nBereich = (short) ::rtl::math::approxFloor(GetDouble()); + else + nBereich = 1; + if (nParamCount >= 3) + nCol = (USHORT) ::rtl::math::approxFloor(GetDouble()); + else + nCol = 0; + if (nParamCount >= 2) + nRow = (USHORT) ::rtl::math::approxFloor(GetDouble()); + else + nRow = 0; + if (GetStackType() == svByte) // vorher MultiSelektion? + nMaxAnz = (short) PopByte(); + else // sonst Einzelselektion + nMaxAnz = 1; + if (nBereich > nMaxAnz || nBereich < 1) + { + SetIllegalParameter(); + return; + } + if (GetStackType() == svMatrix) + { + if (nBereich != 1) + SetError(errIllegalParameter); + USHORT nMatInd1; + USHORT nOldSp = sp; + ScMatrix* pMat = GetMatrix(nMatInd1); + if (pMat) + { + USHORT nC, nR, nMatInd; + pMat->GetDimensions(nC, nR); + if (nC == 0 || nR == 0 || nCol > nC || nRow > nR) + SetIllegalArgument(); + else if (nCol == 0 && nRow == 0) + sp = nOldSp; + else if (nRow == 0) + { + ScMatrix* pResMat = GetNewMat(nC, 1, nMatInd); + if (pResMat) + { + USHORT nColMinus1 = nCol - 1; + for (USHORT i = 0; i < nC; i++) + if (!pMat->IsString(i, nColMinus1)) + pResMat->PutDouble(pMat->GetDouble(i, + nColMinus1), i, 0); + else + pResMat->PutString(pMat->GetString(i, + nColMinus1), i, 0); + PushMatrix(pResMat); + nRetMat = nMatInd; + } + else + SetNoValue(); + } + else if (nCol == 0) + { + ScMatrix* pResMat = GetNewMat(1, nR, nMatInd); + if (pResMat) + { + USHORT nRowMinus1 = nRow - 1; + for (USHORT i = 0; i < nR; i++) + if (!pMat->IsString(nRowMinus1, i)) + pResMat->PutDouble(pMat->GetDouble(nRowMinus1, + i), i); + else + pResMat->PutString(pMat->GetString(nRowMinus1, + i), i); + PushMatrix(pResMat); + nRetMat = nMatInd; + } + else + SetNoValue(); + } + else + { + if (!pMat->IsString(nCol-1, nRow-1)) + PushDouble(pMat->GetDouble(nCol-1, nRow-1)); + else + PushString(pMat->GetString(nCol-1, nRow-1)); + } + ResetNewMat(nMatInd1); + } + } + else if (GetStackType() == svSingleRef || GetStackType() == svDoubleRef) + { + ScAddress aDummyAdr; + ScRange aDummyRange; + USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 = MAXTAB+1; + nCount = nMaxAnz; // Refs liegen umgekehrt auf dem Stack! + while (nCount > nBereich && !nGlobalError) // erste Refs weg + { + nCount--; + if ( GetStackType() == svSingleRef ) + PopSingleRef( aDummyAdr ); + else if ( GetStackType() == svDoubleRef ) + PopDoubleRef( aDummyRange ); + } + while (nCount > nBereich-1 && !nGlobalError) // richtigen Teilbezug + { + nCount--; + if (GetStackType() == svSingleRef) + PopSingleRef(nCol1, nRow1, nTab1); + else if (GetStackType() == svDoubleRef) + PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + } + while (nCount > 0 && !nGlobalError) // restliche Refs weg + { + nCount--; + if ( GetStackType() == svSingleRef ) + PopSingleRef( aDummyAdr ); + else if ( GetStackType() == svDoubleRef ) + PopDoubleRef( aDummyRange ); + } + if (nTab2 == MAXTAB+1) // SingleRef + { + if (nCol > 1 || nRow > 1) + SetIllegalParameter(); + else + PushSingleRef(nCol1, nRow1, nTab1); + } + else // DoubleRef + { + if ( nTab1 != nTab2 || + (nCol > 0 && nCol1+nCol-1 > nCol2) || + (nRow > 0 && nRow1+nRow-1 > nRow2) ) + SetIllegalParameter(); + else if (nCol == 0 && nRow == 0) + { + if ( nCol1 == nCol2 && nRow1 == nRow2 ) + PushSingleRef( nCol1, nRow1, nTab1 ); + else + PushDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab1 ); + } + else if (nRow == 0) + { + if ( nRow1 == nRow2 ) + PushSingleRef( nCol1+nCol-1, nRow1, nTab1 ); + else + PushDoubleRef( nCol1+nCol-1, nRow1, nTab1, + nCol1+nCol-1, nRow2, nTab1 ); + } + else if (nCol == 0) + { + if ( nCol1 == nCol2 ) + PushSingleRef( nCol1, nRow1+nRow-1, nTab1 ); + else + PushDoubleRef(nCol1, nRow1+nRow-1, nTab1, + nCol2, nRow1+nRow-1, nTab1); + } + else + PushSingleRef(nCol1+nCol-1, nRow1+nRow-1, nTab1); + } + } + else + SetIllegalParameter(); + } +} + + +void ScInterpreter::ScMultiArea() +{ + // Hier ist nichts zu tun, der paramCount von ScMultiSelektion + // bleibt auf dem Stack !! + // Den muessen die nachfolgenden Funktionen (Index ...) wegraeumen !! +} + + +void ScInterpreter::ScAreas() +{ + BYTE nParamCount = GetByte(); + double fMaxAnz = 1.0; + ScAddress aDummyAdr; + ScRange aDummyRange; + for (USHORT i = 0; i < nParamCount && nGlobalError == 0; i++) + { + if (GetStackType() == svByte) // vorher MultiSelektion? + { + double fCount = 0.0; + fMaxAnz = (double) GetByte(); + while (fCount < fMaxAnz && !nGlobalError) // mehrere Refs + { + fCount++; + if (GetStackType() == svSingleRef) + PopSingleRef( aDummyAdr ); + else if (GetStackType() == svDoubleRef) + PopDoubleRef( aDummyRange ); + else + SetIllegalParameter(); + } + } + else if (GetStackType() == svSingleRef) + PopSingleRef( aDummyAdr ); + else if (GetStackType() == svDoubleRef) + PopDoubleRef( aDummyRange ); + else + SetIllegalParameter(); + } + if (nGlobalError == 0) + PushDouble((double)nParamCount + fMaxAnz - 1.0); +} + + +void ScInterpreter::ScCurrency() +{ + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 1, 2 ) ) + { + String aStr; + double fDec; + if (nParamCount == 2) + { + fDec = ::rtl::math::approxFloor(GetDouble()); + if (fDec < -15.0 || fDec > 15.0) + { + SetIllegalArgument(); + return; + } + } + else + fDec = 2.0; + double fVal = GetDouble(); + double fFac; + if ( fDec != 0.0 ) + fFac = pow( (double)10, fDec ); + else + fFac = 1.0; + if (fVal < 0.0) + fVal = ceil(fVal*fFac-0.5)/fFac; + else + fVal = floor(fVal*fFac+0.5)/fFac; + Color* pColor = NULL; + if ( fDec < 0.0 ) + fDec = 0.0; + ULONG nIndex = pFormatter->GetStandardFormat( + NUMBERFORMAT_CURRENCY, + ScGlobal::eLnge); + if ( (USHORT) fDec != pFormatter->GetFormatPrecision( nIndex ) ) + { + String sFormatString; + pFormatter->GenerateFormat(sFormatString, + nIndex, + ScGlobal::eLnge, + TRUE, // mit Tausenderpunkt + FALSE, // nicht rot + (USHORT) fDec,// Nachkommastellen + 1); // 1 Vorkommanull + if (!pFormatter->GetPreviewString(sFormatString, + fVal, + aStr, + &pColor, + ScGlobal::eLnge)) + SetError(errIllegalParameter); + } + else + { + pFormatter->GetOutputString(fVal, nIndex, aStr, &pColor); + } + PushString(aStr); + } +} + + +void ScInterpreter::ScReplace() +{ + if ( MustHaveParamCount( GetByte(), 4 ) ) + { + String aNewStr( GetString() ); + short nCount = (short) GetDouble(); + short nPos = (short) GetDouble(); + String aOldStr( GetString() ); + if( nPos < 1 || nCount < 1 ) + SetIllegalArgument(); + else + { + aOldStr.Erase( nPos-1, nCount ); + if ( CheckStringResultLen( aOldStr, aNewStr ) ) + aOldStr.Insert( aNewStr, nPos-1 ); + PushString( aOldStr ); + } + } +} + + +void ScInterpreter::ScFixed() +{ + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 1, 3 ) ) + { + String aStr; + double fDec; + BOOL bThousand; + if (nParamCount == 3) + bThousand = !GetBool(); // Param TRUE: keine Tausenderpunkte + else + bThousand = TRUE; + if (nParamCount >= 2) + { + fDec = ::rtl::math::approxFloor(GetDouble()); + if (fDec < -15.0 || fDec > 15.0) + { + SetIllegalArgument(); + return; + } + } + else + fDec = 2.0; + double fVal = GetDouble(); + double fFac; + if ( fDec != 0.0 ) + fFac = pow( (double)10, fDec ); + else + fFac = 1.0; + if (fVal < 0.0) + fVal = ceil(fVal*fFac-0.5)/fFac; + else + fVal = floor(fVal*fFac+0.5)/fFac; + Color* pColor = NULL; + String sFormatString; + if (fDec < 0.0) + fDec = 0.0; + ULONG nIndex = pFormatter->GetStandardFormat( + NUMBERFORMAT_NUMBER, + ScGlobal::eLnge); + pFormatter->GenerateFormat(sFormatString, + nIndex, + ScGlobal::eLnge, + bThousand, // mit Tausenderpunkt + FALSE, // nicht rot + (USHORT) fDec,// Nachkommastellen + 1); // 1 Vorkommanull + if (!pFormatter->GetPreviewString(sFormatString, + fVal, + aStr, + &pColor, + ScGlobal::eLnge)) + SetIllegalParameter(); + else + PushString(aStr); + } +} + + +void ScInterpreter::ScFind() +{ + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 2, 3 ) ) + { + double fAnz; + if (nParamCount == 3) + fAnz = GetDouble(); + else + fAnz = 1.0; + String sStr = GetString(); + if( fAnz < 1.0 || fAnz > (double) sStr.Len() ) + SetNoValue(); + else + { + xub_StrLen nPos = sStr.Search( GetString(), (xub_StrLen) fAnz - 1 ); + if (nPos == STRING_NOTFOUND) + SetNoValue(); + else + PushDouble((double)(nPos + 1)); + } + } +} + + +void ScInterpreter::ScExact() +{ + nFuncFmtType = NUMBERFORMAT_LOGICAL; + if ( MustHaveParamCount( GetByte(), 2 ) ) + { + String s1( GetString() ); + String s2( GetString() ); + PushInt( s1 == s2 ); + } +} + + +void ScInterpreter::ScLeft() +{ + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 1, 2 ) ) + { + xub_StrLen n; + if (nParamCount == 2) + { + double nVal = ::rtl::math::approxFloor(GetDouble()); + if ( nVal < 0.0 || nVal > STRING_MAXLEN ) + { + SetIllegalParameter(); + return ; + } + else + n = (xub_StrLen) nVal; + } + else + n = 1; + String aStr( GetString() ); + aStr.Erase( n ); + PushString( aStr ); + } +} + + +void ScInterpreter::ScRight() +{ + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 1, 2 ) ) + { + xub_StrLen n; + if (nParamCount == 2) + { + double nVal = ::rtl::math::approxFloor(GetDouble()); + if ( nVal < 0.0 || nVal > STRING_MAXLEN ) + { + SetIllegalParameter(); + return ; + } + else + n = (xub_StrLen) nVal; + } + else + n = 1; + String aStr( GetString() ); + if( n < aStr.Len() ) + aStr.Erase( 0, aStr.Len() - n ); + PushString( aStr ); + } +} + + +void ScInterpreter::ScSearch() +{ + double fAnz; + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 2, 3 ) ) + { + if (nParamCount == 3) + { + fAnz = ::rtl::math::approxFloor(GetDouble()); + if (fAnz > double(STRING_MAXLEN)) + { + SetIllegalParameter(); + return; + } + } + else + fAnz = 1.0; + String sStr = GetString(); + String SearchStr = GetString(); + xub_StrLen nPos = (xub_StrLen) fAnz - 1; + xub_StrLen nEndPos = sStr.Len(); + if( nPos >= nEndPos ) + SetNoValue(); + else + { + ::utl::SearchParam::SearchType eSearchType = + (MayBeRegExp( SearchStr, pDok ) ? + ::utl::SearchParam::SRCH_REGEXP : ::utl::SearchParam::SRCH_NORMAL); + ::utl::SearchParam sPar(SearchStr, eSearchType, FALSE, FALSE, FALSE); + ::utl::TextSearch sT( sPar, *ScGlobal::pCharClass ); + int nBool = sT.SearchFrwrd(sStr, &nPos, &nEndPos); + if (!nBool) + SetNoValue(); + else + PushDouble((double)(nPos) + 1); + } + } +} + + +void ScInterpreter::ScMid() +{ + if ( MustHaveParamCount( GetByte(), 3 ) ) + { + double fAnz = ::rtl::math::approxFloor(GetDouble()); + double fAnfang = ::rtl::math::approxFloor(GetDouble()); + const String& rStr = GetString(); + if (fAnfang < 1.0 || fAnz < 0.0 || fAnfang > double(STRING_MAXLEN) || fAnz > double(STRING_MAXLEN)) + SetIllegalParameter(); + else + PushString(rStr.Copy( (xub_StrLen) fAnfang - 1, (xub_StrLen) fAnz )); + } +} + + +/*N*/ void ScInterpreter::ScText() +/*N*/ { +/*N*/ if ( MustHaveParamCount( GetByte(), 2 ) ) +/*N*/ { +/*N*/ String sFormatString = GetString(); +/*N*/ double fVal = GetDouble(); +/*N*/ String aStr; +/*N*/ Color* pColor = NULL; +/*N*/ LanguageType eCellLang; +/*N*/ const ScPatternAttr* pPattern = pDok->GetPattern( +/*N*/ aPos.Col(), aPos.Row(), aPos.Tab() ); +/*N*/ if ( pPattern ) +/*N*/ eCellLang = ((const SvxLanguageItem&) +/*N*/ pPattern->GetItem( ATTR_LANGUAGE_FORMAT )).GetValue(); +/*N*/ else +/*?*/ eCellLang = ScGlobal::eLnge; +/*N*/ if ( !pFormatter->GetPreviewStringGuess( sFormatString, fVal, aStr, +/*N*/ &pColor, eCellLang ) ) +/*?*/ SetIllegalParameter(); +/*N*/ else +/*N*/ PushString(aStr); +/*N*/ } +/*N*/ } + + +void ScInterpreter::ScSubstitute() +{ + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 3, 4 ) ) + { + xub_StrLen nAnz; + if (nParamCount == 4) + { + double fAnz = ::rtl::math::approxFloor(GetDouble()); + if( fAnz < 1 || fAnz > STRING_MAXLEN ) + { + SetIllegalParameter(); + return; + } + else + nAnz = (xub_StrLen) fAnz; + } + else + nAnz = 0; + String sNewStr = GetString(); + String sOldStr = GetString(); + String sStr = GetString(); + xub_StrLen nPos = 0; + xub_StrLen nCount = 0; + xub_StrLen nNewLen = sNewStr.Len(); + xub_StrLen nOldLen = sOldStr.Len(); + while( TRUE ) + { + nPos = sStr.Search( sOldStr, nPos ); + if (nPos != STRING_NOTFOUND) + { + nCount++; + if( !nAnz || nCount == nAnz ) + { + sStr.Erase(nPos,nOldLen); + if ( CheckStringResultLen( sStr, sNewStr ) ) + { + sStr.Insert(sNewStr,nPos); + nPos += nNewLen; + } + else + break; + } + else + nPos++; + } + else + break; + } + PushString( sStr ); + } +} + + +void ScInterpreter::ScRept() +{ + if ( MustHaveParamCount( GetByte(), 2 ) ) + { + double fAnz = ::rtl::math::approxFloor(GetDouble()); + String aStr( GetString() ); + if ( fAnz < 0.0 ) + SetIllegalParameter(); + else if ( fAnz * aStr.Len() > STRING_MAXLEN ) + { + SetError( errStringOverflow ); + PushInt(0); + } + else if ( fAnz == 0.0 ) + PushString( EMPTY_STRING ); + else + { + xub_StrLen n = (xub_StrLen) fAnz; + const xub_StrLen nLen = aStr.Len(); + String aRes; + const sal_Unicode* const pSrc = aStr.GetBuffer(); + sal_Unicode* pDst = aRes.AllocBuffer( n * nLen ); + while( n-- ) + { + memcpy( pDst, pSrc, nLen * sizeof(sal_Unicode) ); + pDst += nLen; + } + PushString( aRes ); + } + } +} + + +void ScInterpreter::ScConcat() +{ + BYTE nParamCount = GetByte(); + String aRes; + while( nParamCount-- ) + { + const String& rStr = GetString(); + aRes.Insert( rStr, 0 ); + } + PushString( aRes ); +} + + +/*N*/ void ScInterpreter::ScErrorType() +/*N*/ { +/*N*/ USHORT nErr; +/*N*/ USHORT nOldError = nGlobalError; +/*N*/ nGlobalError = 0; +/*N*/ switch ( GetStackType() ) +/*N*/ { +/*N*/ case svDoubleRef : +/*N*/ { +/*N*/ ScRange aRange; +/*N*/ PopDoubleRef( aRange ); +/*N*/ if ( nGlobalError ) +/*N*/ nErr = nGlobalError; +/*N*/ else +/*N*/ { +/*N*/ ScAddress aAdr; +/*N*/ if ( DoubleRefToPosSingleRef( aRange, aAdr ) ) +/*N*/ nErr = pDok->GetErrCode( aAdr ); +/*N*/ else +/*N*/ nErr = nGlobalError; +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case svSingleRef : +/*N*/ { +/*N*/ ScAddress aAdr; +/*N*/ PopSingleRef( aAdr ); +/*N*/ if ( nGlobalError ) +/*N*/ nErr = nGlobalError; +/*N*/ else +/*N*/ nErr = pDok->GetErrCode( aAdr ); +/*N*/ } +/*N*/ break; +/*N*/ default: +/*N*/ PopError(); +/*N*/ nErr = nGlobalError; +/*N*/ } +/*N*/ if ( nErr ) +/*N*/ { +/*N*/ nGlobalError = 0; +/*N*/ PushDouble( nErr ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nGlobalError = nOldError; +/*N*/ SetNV(); +/*N*/ } +/*N*/ } + + +/*N*/ BOOL ScInterpreter::MayBeRegExp( const String& rStr, const ScDocument* pDoc ) +/*N*/ { +/*N*/ if ( pDoc && !pDoc->GetDocOptions().IsFormulaRegexEnabled() ) +/*N*/ return FALSE; +/*N*/ if ( !rStr.Len() || (rStr.Len() == 1 && rStr.GetChar(0) != '.') ) +/*N*/ return FALSE; // einzelnes Metazeichen kann keine RegExp sein +/*N*/ static const sal_Unicode cre[] = { '.','*','+','?','[',']','^','$','\\','<','>','(',')','|', 0 }; +/*N*/ const sal_Unicode* p1 = rStr.GetBuffer(); +/*N*/ sal_Unicode c1; +/*N*/ while ( c1 = *p1++ ) +/*N*/ { +/*N*/ const sal_Unicode* p2 = cre; +/*N*/ while ( *p2 ) +/*N*/ { +/*N*/ if ( c1 == *p2++ ) +/*N*/ return TRUE; +/*N*/ } +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_interpr2.cxx b/binfilter/bf_sc/source/core/tool/sc_interpr2.cxx new file mode 100644 index 000000000000..52bdf1dc6238 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_interpr2.cxx @@ -0,0 +1,2149 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// INCLUDE --------------------------------------------------------------- + +#include <bf_svx/linkmgr.hxx> +#include <bf_svtools/zforlist.hxx> +#include <string.h> +#include <math.h> +#include <sal/macros.h> + +#include "interpre.hxx" +#include "bf_sc.hrc" +#include "ddelink.hxx" +#include "scmatrix.hxx" +#include "dociter.hxx" +#include "unitconv.hxx" +#include "globstr.hrc" +#include "hints.hxx" + +namespace binfilter { + +// STATIC DATA ----------------------------------------------------------- + +#define D_TIMEFACTOR 86400.0 +#define SCdEpsilon 1.0E-7 + +//----------------------------------------------------------------------------- +// Datum und Zeit +//----------------------------------------------------------------------------- + +/*N*/ double ScInterpreter::GetDate(INT16 nYear, INT16 nMonth, INT16 nDay) +/*N*/ { +/*N*/ if ( nYear < 100 ) +/*?*/ nYear = pFormatter->ExpandTwoDigitYear( nYear ); +/*N*/ INT16 nY, nM; +/*N*/ if (nMonth > 0) +/*N*/ { +/*N*/ nY = nYear + (nMonth-1) / 12; +/*N*/ nM = ((nMonth-1) % 12) + 1; +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ nY = nYear + (nMonth-12) / 12; +/*?*/ nM = 12 - (-nMonth) % 12; +/*N*/ } +/*N*/ Date aDate(1, nM, nY); +/*N*/ aDate += nDay - 1; +/*N*/ if (aDate.IsValid()) +/*N*/ return (double) (aDate - *(pFormatter->GetNullDate())); +/*N*/ else +/*N*/ { +/*?*/ SetError(errNoValue); +/*?*/ return 0; +/*N*/ } +/*N*/ } + +//----------------------------------------------------------------------------- +// Funktionen +//----------------------------------------------------------------------------- + +/*N*/ void ScInterpreter::ScGetActDate() +/*N*/ { +/*N*/ nFuncFmtType = NUMBERFORMAT_DATE; +/*N*/ Date aActDate; +/*N*/ long nDiff = aActDate - *(pFormatter->GetNullDate()); +/*N*/ PushDouble((double) nDiff); +/*N*/ } + +void ScInterpreter::ScGetActTime() +{ + nFuncFmtType = NUMBERFORMAT_DATETIME; + Date aActDate; + long nDiff = aActDate - *(pFormatter->GetNullDate()); + Time aActTime; + double nTime = ((double)aActTime.Get100Sec() / 100 + + (double)(aActTime.GetSec() + + (aActTime.GetMin() * 60) + + (aActTime.GetHour() * 3600))) / D_TIMEFACTOR; + PushDouble( (double) nDiff + nTime ); +} + +void ScInterpreter::ScGetYear() +{ + Date aDate = *(pFormatter->GetNullDate()); + aDate += (long) ::rtl::math::approxFloor(GetDouble()); + PushDouble( (double) aDate.GetYear() ); +} + +void ScInterpreter::ScGetMonth() +{ + Date aDate = *(pFormatter->GetNullDate()); + aDate += (long) ::rtl::math::approxFloor(GetDouble()); + PushDouble( (double) aDate.GetMonth() ); +} + +/*N*/ void ScInterpreter::ScGetDay() +/*N*/ { +/*N*/ Date aDate = *(pFormatter->GetNullDate()); +/*N*/ aDate += (long)::rtl::math::approxFloor(GetDouble()); +/*N*/ PushDouble((double) aDate.GetDay()); +/*N*/ } + +void ScInterpreter::ScGetMin() +{ + double fTime = GetDouble(); + fTime -= ::rtl::math::approxFloor(fTime); // Datumsanteil weg + long nVal = (long)::rtl::math::approxFloor(fTime*D_TIMEFACTOR+0.5) % 3600; + PushDouble( (double) (nVal/60) ); +} + +void ScInterpreter::ScGetSec() +{ + double fTime = GetDouble(); + fTime -= ::rtl::math::approxFloor(fTime); // Datumsanteil weg + long nVal = (long)::rtl::math::approxFloor(fTime*D_TIMEFACTOR+0.5) % 60; + PushDouble( (double) nVal ); +} + +void ScInterpreter::ScGetHour() +{ + double fTime = GetDouble(); + fTime -= ::rtl::math::approxFloor(fTime); // Datumsanteil weg + long nVal = (long)::rtl::math::approxFloor(fTime*D_TIMEFACTOR+0.5) / 3600; + PushDouble((double) nVal); +} + +void ScInterpreter::ScGetDateValue() +{ + String aInputString = GetString(); + sal_uInt32 nFIndex = 0; // damit default Land/Spr. + double fVal; + if (pFormatter->IsNumberFormat(aInputString, nFIndex, fVal)) + { + short eType = pFormatter->GetType(nFIndex); + if (eType == NUMBERFORMAT_DATE || eType == NUMBERFORMAT_DATETIME) + PushDouble(fVal); + else + SetIllegalArgument(); + } + else + SetIllegalArgument(); +} + +/*N*/ void ScInterpreter::ScGetDayOfWeek() +/*N*/ { +/*N*/ BYTE nParamCount = GetByte(); +/*N*/ if ( MustHaveParamCount( nParamCount, 1, 2 ) ) +/*N*/ { +/*N*/ short nFlag; +/*N*/ if (nParamCount == 2) +/*?*/ nFlag = (short) ::rtl::math::approxFloor(GetDouble()); +/*N*/ else +/*N*/ nFlag = 1; +/*N*/ +/*N*/ Date aDate = *(pFormatter->GetNullDate()); +/*N*/ aDate += (long)::rtl::math::approxFloor(GetDouble()); +/*N*/ int nVal = (int) aDate.GetDayOfWeek(); +/*N*/ if (nFlag == 1) +/*N*/ { +/*N*/ if (nVal == 6) +/*N*/ nVal = 1; +/*N*/ else +/*N*/ nVal += 2; +/*N*/ } +/*N*/ else if (nFlag == 2) +/*N*/ nVal += 1; +/*N*/ PushInt( nVal ); +/*N*/ } +/*N*/ } + +/*N*/ void ScInterpreter::ScGetWeekOfYear() +/*N*/ { +/*N*/ if ( MustHaveParamCount( GetByte(), 2 ) ) +/*N*/ { +/*N*/ short nFlag = (short) ::rtl::math::approxFloor(GetDouble()); +/*N*/ +/*N*/ Date aDate = *(pFormatter->GetNullDate()); +/*N*/ aDate += (long)::rtl::math::approxFloor(GetDouble()); +/*N*/ PushInt( (int) aDate.GetWeekOfYear( nFlag == 1 ? SUNDAY : MONDAY )); +/*N*/ } +/*N*/ } + +/*N*/ void ScInterpreter::ScEasterSunday() +/*N*/ { +/*N*/ nFuncFmtType = NUMBERFORMAT_DATE; +/*N*/ if ( MustHaveParamCount( GetByte(), 1 ) ) +/*N*/ { +/*N*/ INT16 nDay, nMonth, nYear; +/*N*/ nYear = (INT16) ::rtl::math::approxFloor( GetDouble() ); +/*N*/ if ( nYear < 100 ) +/*?*/ nYear = pFormatter->ExpandTwoDigitYear( nYear ); +/*N*/ // don't worry, be happy :) +/*N*/ int B,C,D,E,F,G,H,I,K,L,M,N,O; +/*N*/ N = nYear % 19; +/*N*/ B = int(nYear / 100); +/*N*/ C = nYear % 100; +/*N*/ D = int(B / 4); +/*N*/ E = B % 4; +/*N*/ F = int((B + 8) / 25); +/*N*/ G = int((B - F + 1) / 3); +/*N*/ H = (19 * N + B - D - G + 15) % 30; +/*N*/ I = int(C / 4); +/*N*/ K = C % 4; +/*N*/ L = (32 + 2 * E + 2 * I - H - K) % 7; +/*N*/ M = int((N + 11 * H + 22 * L) / 451); +/*N*/ O = H + L - 7 * M + 114; +/*N*/ nDay = O % 31 + 1; +/*N*/ nMonth = int(O / 31); +/*N*/ PushDouble( GetDate( nYear, nMonth, nDay ) ); +/*N*/ } +/*N*/ } + +void ScInterpreter::ScGetDate() +{ + nFuncFmtType = NUMBERFORMAT_DATE; + if ( MustHaveParamCount( GetByte(), 3 ) ) + { + INT16 nDay = (INT16) ::rtl::math::approxFloor(GetDouble()); + INT16 nMonth = (INT16) ::rtl::math::approxFloor(GetDouble()); + INT16 nYear = (INT16) ::rtl::math::approxFloor(GetDouble()); + if (nYear < 0) + SetIllegalParameter(); + else + { + PushDouble(GetDate(nYear, nMonth, nDay)); + } + } +} + +void ScInterpreter::ScGetTime() +{ + nFuncFmtType = NUMBERFORMAT_TIME; + if ( MustHaveParamCount( GetByte(), 3 ) ) + { + double nSec = GetDouble(); + double nMin = GetDouble(); + double nHour = GetDouble(); + PushDouble( ( (nHour * 3600) + (nMin * 60) + nSec ) / D_TIMEFACTOR ); + } +} + +void ScInterpreter::ScGetDiffDate() +{ + if ( MustHaveParamCount( GetByte(), 2 ) ) + { + double nDate2 = GetDouble(); + double nDate1 = GetDouble(); + PushDouble(nDate1 - nDate2); + } +} + +void ScInterpreter::ScGetDiffDate360() +{ + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 2, 3 ) ) + { + BOOL bFlag; + if (nParamCount == 3) + bFlag = GetBool(); + else + bFlag = FALSE; + double nDate2 = GetDouble(); + double nDate1 = GetDouble(); + double fSign; + if (nGlobalError == 0) + { + if (nDate2 < nDate1) + { + fSign = nDate1; + nDate1 = nDate2; + nDate2 = fSign; + fSign = -1.0; + } + else + fSign = 1.0; + Date aDate1 = *(pFormatter->GetNullDate()); + aDate1 += (long) ::rtl::math::approxFloor(nDate1); + Date aDate2 = *(pFormatter->GetNullDate()); + aDate2 += (long) ::rtl::math::approxFloor(nDate2); + if (aDate1.GetDay() == 31) + aDate1 -= (ULONG) 1; + else if (!bFlag) + { + if (aDate1.GetMonth() == 2) + { + switch ( aDate1.GetDay() ) + { + case 28 : + if ( !aDate1.IsLeapYear() ) + aDate1.SetDay(30); + break; + case 29 : + aDate1.SetDay(30); + break; + } + } + } + if (aDate2.GetDay() == 31) + { + if (!bFlag && aDate1.GetDay() != 30) + aDate2 += (ULONG) 1; // -> 1. + else + aDate2.SetDay(30); + } + PushDouble( fSign * (double) + ( (double) aDate2.GetDay() + (double) aDate2.GetMonth() * 30.0 + + (double) aDate2.GetYear() * 360.0 + - (double) aDate1.GetDay() - (double) aDate1.GetMonth() * 30.0 + - (double)aDate1.GetYear() * 360.0) ); + } + else + SetIllegalParameter(); + } +} + +void ScInterpreter::ScGetTimeValue() +{ + String aInputString = GetString(); + sal_uInt32 nFIndex = 0; // damit default Land/Spr. + double fVal; + if (pFormatter->IsNumberFormat(aInputString, nFIndex, fVal)) + { + short eType = pFormatter->GetType(nFIndex); + if (eType == NUMBERFORMAT_TIME || eType == NUMBERFORMAT_DATETIME) + PushDouble(fVal); + else + SetIllegalArgument(); + } + else + SetIllegalArgument(); +} + +/*N*/ void ScInterpreter::ScPlusMinus() +/*N*/ { +/*N*/ double nVal = GetDouble(); +/*N*/ short n = 0; +/*N*/ if (nVal < 0.0) +/*N*/ n = -1; +/*N*/ else if (nVal > 0.0) +/*N*/ n = 1; +/*N*/ PushInt( n ); +/*N*/ } + +void ScInterpreter::ScAbs() +{ + PushDouble(fabs(GetDouble())); +} + +/*N*/ void ScInterpreter::ScInt() +/*N*/ { +/*N*/ PushDouble(::rtl::math::approxFloor(GetDouble())); +/*N*/ } + + +/*N*/ void ScInterpreter::RoundNumber( rtl_math_RoundingMode eMode ) +/*N*/ { +/*N*/ BYTE nParamCount = GetByte(); +/*N*/ if ( MustHaveParamCount( nParamCount, 1, 2 ) ) +/*N*/ { +/*N*/ double fVal = 0.0; +/*N*/ if (nParamCount == 1) +/*N*/ fVal = ::rtl::math::round( GetDouble(), 0, eMode ); +/*N*/ else +/*N*/ { +/*N*/ INT32 nDec = (INT32) ::rtl::math::approxFloor(GetDouble()); +/*N*/ if( nDec < -20 || nDec > 20 ) +/*N*/ SetIllegalArgument(); +/*N*/ else +/*N*/ fVal = ::rtl::math::round( GetDouble(), (short)nDec, eMode ); +/*N*/ } +/*N*/ PushDouble(fVal); +/*N*/ } +/*N*/ } + +void ScInterpreter::ScRound() +{ + RoundNumber( rtl_math_RoundingMode_Corrected ); +} + +void ScInterpreter::ScRoundDown() +{ + RoundNumber( rtl_math_RoundingMode_Down ); +} + +/*N*/ void ScInterpreter::ScRoundUp() +/*N*/ { +/*N*/ RoundNumber( rtl_math_RoundingMode_Up ); +/*N*/ } + +void ScInterpreter::ScCeil() +{ + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 2, 3 ) ) + { + BOOL bAbs = ( nParamCount == 3 ? GetBool() : FALSE ); + double fDec = GetDouble(); + double fVal = GetDouble(); + if ( fDec == 0.0 ) + PushInt(0); + else if (fVal*fDec < 0.0) + SetIllegalArgument(); + else + { + if ( !bAbs && fVal < 0.0 ) + PushDouble(::rtl::math::approxFloor(fVal/fDec) * fDec); + else + PushDouble(::rtl::math::approxCeil(fVal/fDec) * fDec); + } + } +} + +void ScInterpreter::ScFloor() +{ + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 2, 3 ) ) + { + BOOL bAbs = ( nParamCount == 3 ? GetBool() : FALSE ); + double fDec = GetDouble(); + double fVal = GetDouble(); + if ( fDec == 0.0 ) + PushInt(0); + else if (fVal*fDec < 0.0) + SetIllegalArgument(); + else + { + if ( !bAbs && fVal < 0.0 ) + PushDouble(::rtl::math::approxCeil(fVal/fDec) * fDec); + else + PushDouble(::rtl::math::approxFloor(fVal/fDec) * fDec); + } + } +} + +void ScInterpreter::ScEven() +{ + double fVal = GetDouble(); + if (fVal < 0.0) + PushDouble(::rtl::math::approxFloor(fVal/2.0) * 2.0); + else + PushDouble(::rtl::math::approxCeil(fVal/2.0) * 2.0); +} + +void ScInterpreter::ScOdd() +{ + double fVal = GetDouble(); + if (fVal >= 0.0) + { + fVal = ::rtl::math::approxCeil(fVal); + if (fmod(fVal, 2.0) == 0.0) + fVal += 1.0; + } + else + { + fVal = ::rtl::math::approxFloor(fVal); + if (fmod(fVal, 2.0) == 0.0) + fVal -= 1.0; + } + PushDouble(fVal); +} + +void ScInterpreter::ScArcTan2() +{ + if ( MustHaveParamCount( GetByte(), 2 ) ) + { + double nVal2 = GetDouble(); + double nVal1 = GetDouble(); + PushDouble(atan2(nVal2, nVal1)); + } +} + +void ScInterpreter::ScLog() +{ + if ( MustHaveParamCount( GetByte(), 2 ) ) + { + double nBase = GetDouble(); + double nVal = GetDouble(); + if (nVal > 0.0 && nBase > 0.0 && nBase != 1.0) + PushDouble(log(nVal) / log(nBase)); + else + SetIllegalArgument(); + } +} + +void ScInterpreter::ScLn() +{ + double fVal = GetDouble(); + if (fVal > 0.0) + PushDouble(log(fVal)); + else + SetIllegalArgument(); +} + +void ScInterpreter::ScLog10() +{ + double fVal = GetDouble(); + if (fVal > 0.0) + PushDouble(log10(fVal)); + else + SetIllegalArgument(); +} + +void ScInterpreter::ScNBW() +{ + nFuncFmtType = NUMBERFORMAT_CURRENCY; + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 2, 31 ) ) + { + double nVal = 0.0; + // Wir drehen den Stack um!! + ScToken* pTemp[ 31 ]; + for( short i = 0; i < nParamCount; i++ ) + pTemp[ i ] = pStack[ sp - i - 1 ]; + memcpy( &pStack[ sp - nParamCount ], pTemp, nParamCount * sizeof( ScToken* ) ); + if (nGlobalError == 0) + { + double nCount = 1.0; + double nZins = GetDouble(); + ScRange aRange; + for (short i = 2; i <= (short) nParamCount; i++) + { + switch (GetStackType()) + { + case svDouble : + { + nVal += (GetDouble() / pow(1.0 + nZins, nCount)); + nCount++; + } + break; + case svSingleRef : + { + nVal += (GetDouble() / pow(1.0 + nZins, nCount)); + nCount++; + } + break; + case svDoubleRef : + { + USHORT nErr = 0; + double nCellVal; + PopDoubleRef( aRange ); + ScValueIterator aValIter(pDok, aRange, glSubTotal); + if (aValIter.GetFirst(nCellVal, nErr)) + { + nVal += (nCellVal / pow(1.0 + nZins, nCount)); + nCount++; + while ((nErr == 0) && aValIter.GetNext(nCellVal, nErr)) + { + nVal += (nCellVal / pow(1.0 + nZins, nCount)); + nCount++; + } + SetError(nErr); + } + } + break; + default : SetError(errIllegalParameter); break; + } + } + } + PushDouble(nVal); + } +} + +#if defined(WIN) && defined(MSC) +#pragma optimize("",off) +#endif + +void ScInterpreter::ScIKV() +{ + double fSchaetzwert; + nFuncFmtType = NUMBERFORMAT_PERCENT; + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 1, 2 ) ) + return; + if (nParamCount == 2) + fSchaetzwert = GetDouble(); + else + fSchaetzwert = 0.1; + USHORT sPos = sp; // Stack-Position merken + double fEps = 1.0; + double x, xNeu, fWert, fZaehler, fNenner, nCount; + if (fSchaetzwert == -1.0) + x = 0.1; // default gegen Nulldivisionen + else + x = fSchaetzwert; // Startwert + switch (GetStackType()) + { + case svDoubleRef : + break; + case svDouble : + case svSingleRef : + default: + { + SetError(errIllegalParameter); + return; + } + } + const USHORT nIterationsMax = 20; + USHORT nItCount = 0; + ScRange aRange; + while (fEps > SCdEpsilon && nItCount < nIterationsMax) + { // Newton-Verfahren: + sp = sPos; // Stack zuruecksetzen + nCount = 0.0; + fZaehler = 0.0; + fNenner = 0.0; + USHORT nErr = 0; + PopDoubleRef( aRange ); + ScValueIterator aValIter(pDok, aRange, glSubTotal); + if (aValIter.GetFirst(fWert, nErr)) + { + fZaehler += fWert / pow(1.0+x,nCount); + fNenner += -nCount * fWert / pow(1.0+x,nCount+1.0); + nCount++; + while ((nErr == 0) && aValIter.GetNext(fWert, nErr)) + { + fZaehler += fWert / pow(1.0+x,nCount); + fNenner += -nCount * fWert / pow(1.0+x,nCount+1.0); + nCount++; + } + SetError(nErr); + } + xNeu = x - fZaehler / fNenner; // x(i+1) = x(i)-f(x(i))/f'(x(i)) + nItCount++; + fEps = fabs(xNeu - x); + x = xNeu; + } + if (fSchaetzwert == 0.0 && fabs(x) < SCdEpsilon) + x = 0.0; // auf Null normieren + if (fEps < SCdEpsilon) + PushDouble(x); + else + { + SetError(errNoConvergence); + PushInt(0); + } +} +#if defined(WIN) && defined(MSC) +#pragma optimize("",on) +#endif + + +void ScInterpreter::ScMIRR() +{ // range_of_values ; rate_invest ; rate_reinvest + nFuncFmtType = NUMBERFORMAT_PERCENT; + if( MustHaveParamCount( GetByte(), 3 ) ) + { + double fRate1_reinvest = GetDouble() + 1; + double fNPV_reinvest = 0.0; + double fPow_reinvest = 1.0; + + double fRate1_invest = GetDouble() + 1; + double fNPV_invest = 0.0; + double fPow_invest = 1.0; + + ScRange aRange; + PopDoubleRef( aRange ); + + if( nGlobalError ) + SetIllegalParameter(); + else + { + ScValueIterator aValIter( pDok, aRange, glSubTotal ); + double fCellValue; + ULONG nCount = 0; + USHORT nIterError = 0; + + BOOL bLoop = aValIter.GetFirst( fCellValue, nIterError ); + while( bLoop ) + { + if( fCellValue > 0.0 ) // reinvestments + fNPV_reinvest += fCellValue * fPow_reinvest; + else if( fCellValue < 0.0 ) // investments + fNPV_invest += fCellValue * fPow_invest; + fPow_reinvest /= fRate1_reinvest; + fPow_invest /= fRate1_invest; + nCount++; + + bLoop = aValIter.GetNext( fCellValue, nIterError ); + } + if( nIterError ) + SetError( nIterError ); + else + { + double fResult = -fNPV_reinvest / fNPV_invest; + fResult *= pow( fRate1_reinvest, double(nCount - 1) ); + fResult = pow( fResult, 1.0 / (nCount - 1) ); + PushDouble( fResult - 1.0 ); + } + } + } +} + + +void ScInterpreter::ScISPMT() +{ // rate ; period ; total_periods ; invest + if( MustHaveParamCount( GetByte(), 4 ) ) + { + double fInvest = GetDouble(); + double fTotal = GetDouble(); + double fPeriod = GetDouble(); + double fRate = GetDouble(); + + if( nGlobalError ) + SetIllegalParameter(); + else + PushDouble( fInvest * fRate * (fPeriod / fTotal - 1.0) ); + } +} + + +//----------------------- Finanzfunktionen ------------------------------------ + +double ScInterpreter::ScGetBw(double fZins, double fZzr, double fRmz, + double fZw, double fF) +{ + double fBw; + if (fZins == 0.0) + fBw = fZw + fRmz * fZzr; + else if (fF > 0.0) + fBw = (fZw * pow(1.0 + fZins, -fZzr)) + + (fRmz * (1.0 - pow(1.0 + fZins, -fZzr + 1.0)) / fZins) + + fRmz; + else + fBw = (fZw * pow(1.0 + fZins, -fZzr)) + + (fRmz * (1.0 - pow(1.0 + fZins, -fZzr)) / fZins); + return -fBw; +} + +void ScInterpreter::ScBW() +{ + nFuncFmtType = NUMBERFORMAT_CURRENCY; + double nRmz, nZzr, nZins, nZw = 0, nFlag = 0; + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 3, 5 ) ) + return; + if (nParamCount == 5) + nFlag = GetDouble(); + if (nParamCount >= 4) + nZw = GetDouble(); + nRmz = GetDouble(); + nZzr = GetDouble(); + nZins = GetDouble(); + PushDouble(ScGetBw(nZins, nZzr, nRmz, nZw, nFlag)); +} + +void ScInterpreter::ScDIA() +{ + nFuncFmtType = NUMBERFORMAT_CURRENCY; + if ( MustHaveParamCount( GetByte(), 4 ) ) + { + double nZr = GetDouble(); + double nDauer = GetDouble(); + double nRest = GetDouble(); + double nWert = GetDouble(); + double nDia = ((nWert - nRest) * (nDauer - nZr + 1.0)) / + ((nDauer * (nDauer + 1.0)) / 2.0); + PushDouble(nDia); + } +} + +double ScInterpreter::ScGetGDA(double fWert, double fRest, double fDauer, + double fPeriode, double fFaktor) +{ + double fGda, fZins, fAlterWert, fNeuerWert; + fZins = fFaktor / fDauer; + if (fZins >= 1.0) + { + fZins = 1.0; + if (fPeriode == 1.0) + fAlterWert = fWert; + else + fAlterWert = 0.0; + } + else + fAlterWert = fWert * pow(1.0 - fZins, fPeriode - 1.0); + fNeuerWert = fWert * pow(1.0 - fZins, fPeriode); + + if (fNeuerWert < fRest) + fGda = fAlterWert - fRest; + else + fGda = fAlterWert - fNeuerWert; + if (fGda < 0.0) + fGda = 0.0; + return fGda; +} + +void ScInterpreter::ScGDA() +{ + nFuncFmtType = NUMBERFORMAT_CURRENCY; + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 4, 5 ) ) + { + double nFaktor; + if (nParamCount == 5) + nFaktor = GetDouble(); + else + nFaktor = 2.0; + double nPeriode = GetDouble(); + double nDauer = GetDouble(); + double nRest = GetDouble(); + double nWert = GetDouble(); + if (nWert < 0.0 || nRest < 0.0 || nFaktor <= 0.0 || nRest > nWert + || nPeriode < 1.0 || nPeriode > nDauer) + SetIllegalParameter(); + else + PushDouble(ScGetGDA(nWert, nRest, nDauer, nPeriode, nFaktor)); + } +} + +void ScInterpreter::ScGDA2() +{ + nFuncFmtType = NUMBERFORMAT_CURRENCY; + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 4, 5 ) ) + return ; + double nMonate; + if (nParamCount == 4) + nMonate = 12.0; + else + nMonate = ::rtl::math::approxFloor(GetDouble()); + double nPeriode = GetDouble(); + double nDauer = GetDouble(); + double nRest = GetDouble(); + double nWert = GetDouble(); + if (nMonate < 1.0 || nMonate > 12.0 || nDauer > 1200.0 || nRest < 0.0 || + nPeriode > (nDauer + 1.0) || nRest > nWert || nWert < 0.0) + { + SetIllegalParameter(); + return; + } + double nAbRate = 1.0 - pow(nRest / nWert, 1.0 / nDauer); + nAbRate = ::rtl::math::approxFloor((nAbRate * 1000.0) + 0.5) / 1000.0; + double nErsteAbRate = nWert * nAbRate * nMonate / 12.0; + double nGda2; + if (::rtl::math::approxFloor(nPeriode) == 1) + nGda2 = nErsteAbRate; + else + { + double nSummAbRate = nErsteAbRate; + double nMin = nDauer; + if (nMin > nPeriode) nMin = nPeriode; + USHORT iMax = (USHORT)::rtl::math::approxFloor(nMin); + for (USHORT i = 2; i <= iMax; i++) + { + nGda2 = (nWert - nSummAbRate) * nAbRate; + nSummAbRate += nGda2; + } + if (nPeriode > nDauer) + nGda2 = ((nWert - nSummAbRate) * nAbRate * (12.0 - nMonate)) / 12.0; + } + PushDouble(nGda2); +} + + +double ScInterpreter::ScInterVDB(double fWert,double fRest,double fDauer, + double fDauer1,double fPeriode,double fFaktor) +{ + double fVdb=0; + double fIntEnd = ::rtl::math::approxCeil(fPeriode); + ULONG nLoopEnd = (ULONG) fIntEnd; + + double fTerm, fLia; + double fRestwert = fWert - fRest; + double fRestwert1 = fRestwert; + BOOL bNowLia = FALSE; + BOOL bFirstFlag=TRUE; + BOOL b2Flag=TRUE; + double fAbschlag=0; + + double fGda; + ULONG i; + fLia=0; + for ( i = 1; i <= nLoopEnd; i++) + { + if(!bNowLia) + { + fGda = ScGetGDA(fWert, fRest, fDauer, (double) i, fFaktor); + fLia = fRestwert/ (fDauer1 - (double) (i-1)); + + if (fLia > fGda) + { + fTerm = fLia; + bNowLia = TRUE; + } + else + { + fTerm = fGda; + fRestwert -= fGda; + } + } + else + { + fTerm = fLia; + } + + if ( i == nLoopEnd) + fTerm *= ( fPeriode + 1.0 - fIntEnd ); + + fVdb += fTerm; + } + return fVdb; +} + + +inline double DblMin( double a, double b ) +{ + return (a < b) ? a : b; +} + +void ScInterpreter::ScVDB() +{ + nFuncFmtType = NUMBERFORMAT_CURRENCY; + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 5, 7 ) ) + { + double fWert, fRest, fDauer, fAnfang, fEnde, fFaktor, fVdb = 0.0; + BOOL bFlag; + if (nParamCount == 7) + bFlag = GetBool(); + else + bFlag = FALSE; + if (nParamCount >= 6) + fFaktor = GetDouble(); + else + fFaktor = 2.0; + fEnde = GetDouble(); + fAnfang = GetDouble(); + fDauer = GetDouble(); + fRest = GetDouble(); + fWert = GetDouble(); + if (fAnfang < 0.0 || fEnde < fAnfang || fEnde > fDauer || fWert < 0.0 + || fRest > fWert || fFaktor <= 0.0) + SetIllegalParameter(); + else + { + double fIntStart = ::rtl::math::approxFloor(fAnfang); + double fIntEnd = ::rtl::math::approxCeil(fEnde); + ULONG nLoopStart = (ULONG) fIntStart; + ULONG nLoopEnd = (ULONG) fIntEnd; + + fVdb = 0.0; + if (bFlag) + { + for (ULONG i = nLoopStart + 1; i <= nLoopEnd; i++) + { + double fTerm = ScGetGDA(fWert, fRest, fDauer, (double) i, fFaktor); + + // Teilperioden am Anfang / Ende beruecksichtigen: + if ( i == nLoopStart+1 ) + fTerm *= ( DblMin( fEnde, fIntStart + 1.0 ) - fAnfang ); + else if ( i == nLoopEnd ) + fTerm *= ( fEnde + 1.0 - fIntEnd ); + + fVdb += fTerm; + } + } + else + { + + double fDauer1=fDauer; + double fPart; + + //@Die Frage aller Fragen: "Ist das hier richtig" + if(!::rtl::math::approxEqual(fAnfang,::rtl::math::approxFloor(fAnfang))) + { + if(fFaktor>1) + { + if(fAnfang>fDauer/2 || ::rtl::math::approxEqual(fAnfang,fDauer/2)) + { + fPart=fAnfang-fDauer/2; + fAnfang=fDauer/2; + fEnde-=fPart; + fDauer1+=1; + } + } + } + + fWert-=ScInterVDB(fWert,fRest,fDauer,fDauer1,fAnfang,fFaktor); + fVdb=ScInterVDB(fWert,fRest,fDauer,fDauer-fAnfang,fEnde-fAnfang,fFaktor); + } + } + PushDouble(fVdb); + } +} + +void ScInterpreter::ScLaufz() +{ + if ( MustHaveParamCount( GetByte(), 3 ) ) + { + double nZukunft = GetDouble(); + double nGegenwart = GetDouble(); + double nZins = GetDouble(); + PushDouble(log(nZukunft / nGegenwart) / log(1.0 + nZins)); + } +} + +void ScInterpreter::ScLIA() +{ + nFuncFmtType = NUMBERFORMAT_CURRENCY; + if ( MustHaveParamCount( GetByte(), 3 ) ) + { + double nDauer = GetDouble(); + double nRest = GetDouble(); + double nWert = GetDouble(); + PushDouble((nWert - nRest) / nDauer); + } +} + +double ScInterpreter::ScGetRmz(double fZins, double fZzr, double fBw, + double fZw, double fF) +{ + double fRmz; + if (fZins == 0.0) + fRmz = (fBw + fZw) / fZzr; + else + { + double fTerm = pow(1.0 + fZins, fZzr); + if (fF > 0.0) + fRmz = (fZw * fZins / (fTerm - 1.0) + + fBw * fZins / (1.0 - 1.0 / fTerm)) / (1.0+fZins); + else + fRmz = fZw * fZins / (fTerm - 1.0) + + fBw * fZins / (1.0 - 1.0 / fTerm); + } + return -fRmz; +} + +void ScInterpreter::ScRMZ() +{ + double nZins, nZzr, nBw, nZw = 0, nFlag = 0; + nFuncFmtType = NUMBERFORMAT_CURRENCY; + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 3, 5 ) ) + return; + if (nParamCount == 5) + nFlag = GetDouble(); + if (nParamCount >= 4) + nZw = GetDouble(); + nBw = GetDouble(); + nZzr = GetDouble(); + nZins = GetDouble(); + PushDouble(ScGetRmz(nZins, nZzr, nBw, nZw, nFlag)); +} + +void ScInterpreter::ScZGZ() +{ + nFuncFmtType = NUMBERFORMAT_PERCENT; + if ( MustHaveParamCount( GetByte(), 3 ) ) + { + double nZukunftswert = GetDouble(); + double nGegenwartswert = GetDouble(); + double nZeitraum = GetDouble(); + PushDouble(pow(nZukunftswert / nGegenwartswert, 1.0 / nZeitraum) - 1.0); + } +} + +double ScInterpreter::ScGetZw(double fZins, double fZzr, double fRmz, + double fBw, double fF) +{ + double fZw; + if (fZins == 0.0) + fZw = fBw + fRmz * fZzr; + else + { + double fTerm = pow(1.0 + fZins, fZzr); + if (fF > 0.0) + fZw = fBw * fTerm + fRmz*(1.0 + fZins)*(fTerm - 1.0)/fZins; + else + fZw = fBw * fTerm + fRmz*(fTerm - 1.0)/fZins; + } + return -fZw; +} + +void ScInterpreter::ScZW() +{ + double nZins, nZzr, nRmz, nBw = 0, nFlag = 0; + nFuncFmtType = NUMBERFORMAT_CURRENCY; + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 3, 5 ) ) + return; + if (nParamCount == 5) + nFlag = GetDouble(); + if (nParamCount >= 4) + nBw = GetDouble(); + nRmz = GetDouble(); + nZzr = GetDouble(); + nZins = GetDouble(); + PushDouble(ScGetZw(nZins, nZzr, nRmz, nBw, nFlag)); +} + +void ScInterpreter::ScZZR() +{ + double nZins, nRmz, nBw, nZw = 0, nFlag = 0; + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 3, 5 ) ) + return; + if (nParamCount == 5) + nFlag = GetDouble(); + if (nParamCount >= 4) + nZw = GetDouble(); + nBw = GetDouble(); + nRmz = GetDouble(); + nZins = GetDouble(); + if (nZins == 0.0) + PushDouble(-(nBw + nZw)/nRmz); + else if (nFlag > 0.0) + PushDouble(log(-(nZins*nZw-nRmz*(1.0+nZins))/(nZins*nBw+nRmz*(1.0+nZins))) + /log(1.0+nZins)); + else + PushDouble(log(-(nZins*nZw-nRmz)/(nZins*nBw+nRmz))/log(1.0+nZins)); +} + +double ScInterpreter::GetZinsIterationEps(double fZzr, double fRmz, double fBw, + double fZw, double fF, double& fSchaetzwert) +{ + double fEps = 1.0; + double x, xNeu, fTerm1, fTerm2; + if (fSchaetzwert == 0.0) + x = 0.1; // default gegen Nulldivisionen + else + x = fSchaetzwert; // Startwert + const USHORT nIterationsMax = 150; + USHORT nCount = 0; + while (fEps > SCdEpsilon && nCount < nIterationsMax) + { // Newton-Verfahren: + if (x == 0.0) + xNeu = x - + (fBw + fRmz*fZzr + fZw) / + (fBw*fZzr + fRmz*(fZzr*(fZzr-1.0) + 2*fF*fZzr)/2.0); + else + { + fTerm1 = pow(1.0+x, fZzr-1); + fTerm2 = fTerm1*(1.0+x); + xNeu = x*(1.0 - // x(i+1) = x(i) - f(x(i)) / f'(x(i)) + (x*fBw*fTerm2 + fRmz*(1.0+x*fF)*(fTerm2-1.0) + x*fZw) / + (x*x*fZzr*fBw*fTerm1 - fRmz*(fTerm2-1.0) + + x*fRmz*(1.0+x*fF)*fZzr*fTerm1) ); + } + nCount++; + fEps = fabs(xNeu - x); + x = xNeu; + } + if (fSchaetzwert == 0.0 && fabs(x) < SCdEpsilon) + x = 0.0; // auf Null normieren + fSchaetzwert = x; //n Rueckgabe + return fEps; +} + +void ScInterpreter::ScZins() +{ + double nZw = 0, nRmz, nZzr, nBw, nFlag = 0, nSchaetzwert = 0.1, fEps; + nFuncFmtType = NUMBERFORMAT_PERCENT; + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 3, 6 ) ) + return; + if (nParamCount == 6) + nSchaetzwert = GetDouble(); + if (nParamCount >= 5) + nFlag = GetDouble(); + if (nParamCount >= 4) + nZw = GetDouble(); + nBw = GetDouble(); + nRmz = GetDouble(); + nZzr = GetDouble(); + if (nFlag == 0.0) + fEps = GetZinsIterationEps(nZzr, nRmz, nBw, nZw, 0.0, nSchaetzwert); + else + fEps = GetZinsIterationEps(nZzr, nRmz, nBw, nZw, 1.0, nSchaetzwert); + if (fEps >= SCdEpsilon) + { + SetError(errNoConvergence); + nSchaetzwert = 0; + } + PushDouble(nSchaetzwert); +} + +double ScInterpreter::ScGetZinsZ(double fZins, double fZr, double fZzr, double fBw, + double fZw, double fF, double& fRmz) +{ + fRmz = ScGetRmz(fZins, fZzr, fBw, fZw, fF); // fuer kapz auch bei fZr == 1 + double fZinsZ; + nFuncFmtType = NUMBERFORMAT_CURRENCY; + if (fZr == 1.0) + { + if (fF > 0.0) + fZinsZ = 0.0; + else + fZinsZ = -fBw; + } + else + { + if (fF > 0.0) + fZinsZ = ScGetZw(fZins, fZr-2.0, fRmz, fBw, 1.0) - fRmz; + else + fZinsZ = ScGetZw(fZins, fZr-1.0, fRmz, fBw, 0.0); + } + return fZinsZ * fZins; +} + +void ScInterpreter::ScZinsZ() +{ + double nZins, nZr, nRmz, nZzr, nBw, nZw = 0, nFlag = 0; + nFuncFmtType = NUMBERFORMAT_CURRENCY; + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 4, 6 ) ) + return; + if (nParamCount == 6) + nFlag = GetDouble(); + if (nParamCount >= 5) + nZw = GetDouble(); + nBw = GetDouble(); + nZzr = GetDouble(); + nZr = GetDouble(); + nZins = GetDouble(); + if (nZr < 1.0 || nZr > nZzr) + SetIllegalParameter(); + else + PushDouble(ScGetZinsZ(nZins, nZr, nZzr, nBw, nZw, nFlag, nRmz)); +} + +void ScInterpreter::ScKapz() +{ + double nZins, nZr, nZzr, nBw, nZw = 0, nFlag = 0, nRmz, nZinsz; + nFuncFmtType = NUMBERFORMAT_CURRENCY; + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 4, 6 ) ) + return; + if (nParamCount == 6) + nFlag = GetDouble(); + if (nParamCount >= 5) + nZw = GetDouble(); + nBw = GetDouble(); + nZzr = GetDouble(); + nZr = GetDouble(); + nZins = GetDouble(); + if (nZr < 1.0 || nZr > nZzr) + SetIllegalParameter(); + else + { + nZinsz = ScGetZinsZ(nZins, nZr, nZzr, nBw, nZw, nFlag, nRmz); + PushDouble(nRmz - nZinsz); + } +} + +void ScInterpreter::ScKumZinsZ() +{ + nFuncFmtType = NUMBERFORMAT_CURRENCY; + if ( MustHaveParamCount( GetByte(), 6 ) ) + { + double fZins, fZzr, fBw, fAnfang, fEnde, fF, fRmz, fZinsZ; + fF = GetDouble(); + fEnde = ::rtl::math::approxFloor(GetDouble()); + fAnfang = ::rtl::math::approxFloor(GetDouble()); + fBw = GetDouble(); + fZzr = GetDouble(); + fZins = GetDouble(); + if (fAnfang < 1.0 || fEnde < fAnfang || fZins <= 0.0 || + fEnde > fZzr || fZzr <= 0.0 || fBw <= 0.0) + SetIllegalParameter(); + else + { + ULONG nAnfang = (ULONG) fAnfang; + ULONG nEnde = (ULONG) fEnde ; + fRmz = ScGetRmz(fZins, fZzr, fBw, 0.0, fF); + fZinsZ = 0.0; + if (nAnfang == 1) + { + if (fF <= 0.0) + fZinsZ = -fBw; + nAnfang++; + } + for (ULONG i = nAnfang; i <= nEnde; i++) + { + if (fF > 0.0) + fZinsZ += ScGetZw(fZins, (double)(i-2), fRmz, fBw, 1.0) - fRmz; + else + fZinsZ += ScGetZw(fZins, (double)(i-1), fRmz, fBw, 0.0); + } + fZinsZ *= fZins; + PushDouble(fZinsZ); + } + } +} + +void ScInterpreter::ScKumKapZ() +{ + nFuncFmtType = NUMBERFORMAT_CURRENCY; + if ( MustHaveParamCount( GetByte(), 6 ) ) + { + double fZins, fZzr, fBw, fAnfang, fEnde, fF, fRmz, fKapZ; + fF = GetDouble(); + fEnde = ::rtl::math::approxFloor(GetDouble()); + fAnfang = ::rtl::math::approxFloor(GetDouble()); + fBw = GetDouble(); + fZzr = GetDouble(); + fZins = GetDouble(); + if (fAnfang < 1.0 || fEnde < fAnfang || fZins <= 0.0 || + fEnde > fZzr || fZzr <= 0.0 || fBw <= 0.0) + SetIllegalParameter(); + else + { + fRmz = ScGetRmz(fZins, fZzr, fBw, 0.0, fF); + fKapZ = 0.0; + ULONG nAnfang = (ULONG) fAnfang; + ULONG nEnde = (ULONG) fEnde; + if (nAnfang == 1) + { + if (fF <= 0.0) + fKapZ = fRmz + fBw * fZins; + else + fKapZ = fRmz; + nAnfang++; + } + for (ULONG i = nAnfang; i <= nEnde; i++) + { + if (fF > 0.0) + fKapZ += fRmz - (ScGetZw(fZins, (double)(i-2), fRmz, fBw, 1.0) - fRmz) * fZins; + else + fKapZ += fRmz - ScGetZw(fZins, (double)(i-1), fRmz, fBw, 0.0) * fZins; + } + PushDouble(fKapZ); + } + } +} + +void ScInterpreter::ScEffektiv() +{ + nFuncFmtType = NUMBERFORMAT_PERCENT; + if ( MustHaveParamCount( GetByte(), 2 ) ) + { + double fPerioden = GetDouble(); + double fNominal = GetDouble(); + if (fPerioden < 1.0 || fNominal <= 0.0) + SetIllegalParameter(); + else + { + fPerioden = ::rtl::math::approxFloor(fPerioden); + PushDouble(pow(1.0 + fNominal/fPerioden, fPerioden) - 1.0); + } + } +} + +void ScInterpreter::ScNominal() +{ + nFuncFmtType = NUMBERFORMAT_PERCENT; + if ( MustHaveParamCount( GetByte(), 2 ) ) + { + double fPerioden = GetDouble(); + double fEffektiv = GetDouble(); + if (fPerioden < 1.0 || fEffektiv <= 0.0) + SetIllegalParameter(); + else + { + fPerioden = ::rtl::math::approxFloor(fPerioden); + PushDouble( (pow(fEffektiv + 1.0, 1.0 / fPerioden) - 1.0) * fPerioden ); + } + } +} + +/*N*/ void ScInterpreter::ScMod() +/*N*/ { +/*N*/ if ( MustHaveParamCount( GetByte(), 2 ) ) +/*N*/ { +/*N*/ double nVal2 = GetDouble(); +/*N*/ double nVal1 = GetDouble(); +/*N*/ PushDouble(nVal1 - (::rtl::math::approxFloor(nVal1 / nVal2) * nVal2)); +/*N*/ } +/*N*/ } + +void ScInterpreter::ScBackSolver() +{ + if ( MustHaveParamCount( GetByte(), 3 ) ) + { + BOOL bRet = FALSE; + ScAddress aVAdr, aFAdr; + double nVal = GetDouble(); + PopSingleRef( aFAdr ); + PopSingleRef( aVAdr ); + if (nGlobalError == 0) + { + ScBaseCell* pVCell = GetCell( aVAdr ); + // CELLTYPE_NOTE: kein Value aber von Formel referiert + BOOL bTempCell = (!pVCell || pVCell->GetCellType() == CELLTYPE_NOTE); + ScBaseCell* pFCell = GetCell( aFAdr ); + if ( ((pVCell && pVCell->GetCellType() == CELLTYPE_VALUE) || bTempCell) + && pFCell && pFCell->GetCellType() == CELLTYPE_FORMULA ) + { + ScRange aVRange( aVAdr, aVAdr ); // fuer SetDirty + double nSaveVal; + ScPostIt aNote; + BOOL bHasNote; + if ( bTempCell ) + { + if ( bHasNote = (pVCell != NULL) ) + bHasNote = pVCell->GetNote( aNote ); + nSaveVal = 0.0; + pVCell = new ScValueCell( nSaveVal ); + pDok->PutCell( aVAdr, pVCell ); + } + else + nSaveVal = GetCellValue( aVAdr, pVCell ); + const USHORT nMaxIter = 100; + const double nEps = 1E-10; + const double nDelta = 1E-3; + double nBestX = nSaveVal; + double nBestF, xn1, fn1; + ScFormulaCell* pFormula = (ScFormulaCell*) pFCell; + ScValueCell* pValue = (ScValueCell*) pVCell; + pFormula->Interpret(); + BOOL bError = ( pFormula->GetErrCode() != 0 ); + // bError always corresponds with fn + fn1 = pFormula->GetValue(); + fn1 -= nVal; + xn1 = nBestX; + nBestF = fabs(fn1); + if (nBestF < nDelta) + bRet = TRUE; + double xn = xn1 + nEps; + double fn = fn1; + double fs; + USHORT i = 0; + // Nach der Regula Falsi Methode + while (!bRet && (i < nMaxIter)) + { + i++; + pValue->SetValue(xn); + pDok->SetDirty( aVRange ); + pFormula->Interpret(); + bError = ( pFormula->GetErrCode() != 0 ); + fn = pFormula->GetValue(); + fn -= nVal; + if ( bError ) + { + // move closer to last valid value (xn1), keep xn1/fn1 + double fDiff = ( xn1 - xn ) / 2; + if (fabs(fDiff) < nEps) + fDiff = (fDiff < 0.0) ? -nEps : nEps; + xn += fDiff; + } + else if (fabs(fn) < nDelta) + { + nBestX = xn; + bRet = TRUE; + } + else + { + if (fabs(fn) + nDelta < nBestF) + { + nBestX = xn; + nBestF = fabs(fn); + } + if ((xn1 - xn) != 0) + { + fs = (fn1 - fn) / (xn1 - xn); + if (fabs(fs) < nEps) + if (fs < 0.0) + fs = -nEps; + else + fs = nEps; + } + else + fs = nEps; + xn1 = xn; + fn1 = fn; + xn = xn - (fn / fs); + } + } + double nX = ::rtl::math::approxFloor((nBestX / nDelta) + 0.5) * nDelta; + if ( bRet ) + { + pValue->SetValue( nX ); + pDok->SetDirty( aVRange ); + pFormula->Interpret(); + if ( fabs( pFormula->GetValue() - nVal ) > fabs( fn ) ) + nX = nBestX; + } + else if ( bError ) + { + nX = nBestX; + } + if ( bTempCell ) + { + if ( bHasNote ) + pVCell = new ScNoteCell( aNote ); + else + pVCell = NULL; + pDok->PutCell( aVAdr, pVCell ); + } + else + pValue->SetValue(nSaveVal); + pDok->SetDirty( aVRange ); + pFormula->Interpret(); + if (!bRet) + SetError(NOVALUE); + PushDouble(nX); + } + else + { + if (!bRet) + SetError(NOVALUE); + PushInt(0); // falsche Zelltypen + } + } + else + { + if (!bRet) + SetError(NOVALUE); + PushInt(0); // nGlobalError + } + } +} + +void ScInterpreter::ScIntersect() +{ + USHORT nCol11, nRow11, nTab11, nCol21, nRow21, nTab21, + nCol12, nRow12, nTab12, nCol22, nRow22, nTab22, + nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; + BYTE eStackVar = GetStackType(); + if (eStackVar == svDoubleRef) + PopDoubleRef(nCol11, nRow11, nTab11, nCol21, nRow21, nTab21); + else if (eStackVar == svSingleRef) + { + PopSingleRef(nCol11, nRow11, nTab11); + nCol21 = nCol11; + nRow21 = nRow11; + nTab21 = nTab11; + } + else + { + SetError(errNoRef); + PushInt(0); + return; + } + eStackVar = GetStackType(); + if (eStackVar == svDoubleRef) + PopDoubleRef(nCol12, nRow12, nTab12, nCol22, nRow22, nTab22); + else if (eStackVar == svSingleRef) + { + PopSingleRef(nCol12, nRow12, nTab12); + nCol22 = nCol12; + nRow22 = nRow12; + nTab22 = nTab12; + } + else + { + SetError(errNoRef); + PushInt(0); + return; + } + nCol1 = Max(nCol11, nCol12); + nRow1 = Max(nRow11, nRow12); + nTab1 = Max(nTab11, nTab12); + nCol2 = Min(nCol21, nCol22); + nRow2 = Min(nRow21, nRow22); + nTab2 = Min(nTab21, nTab22); + if (nCol2 < nCol1 || nRow2 < nRow1 || nTab2 < nTab1) + { + SetError(errNoRef); + PushInt(0); + } + else if (nCol2 == nCol1 && nRow2 == nRow1 && nTab2 == nTab1) + PushSingleRef(nCol1, nRow1, nTab1); + else + PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); +} + + +void ScInterpreter::ScCurrent() +{ + switch ( GetStackType() ) + { + case svDouble : + { + double nVal = PopDouble(); + PushDouble( nVal ); + PushDouble( nVal ); + } + break; + case svString : + { + const String& rStr = PopString(); + PushString( rStr ); + PushString( rStr ); + } + break; + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + if ( !PopDoubleRefOrSingleRef( aAdr ) ) + { + PushInt(0); + break; + } + ScBaseCell* pCell = GetCell( aAdr ); + // NoteCell entsteht auch durch Referenz auf leere Zelle + if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE ) + { + if ( HasCellValueData( pCell ) ) + { + double nVal = GetCellValue( aAdr, pCell ); + PushDouble( nVal ); + PushDouble( nVal ); + } + else + { + String aStr; + GetCellString( aStr, pCell ); + PushString( aStr ); + PushString( aStr ); + } + } + else + { + PushSingleRef( aAdr.Col(), aAdr.Row(), aAdr.Tab() ); + PushSingleRef( aAdr.Col(), aAdr.Row(), aAdr.Tab() ); + } + } + break; + default: + SetIllegalParameter(); + } +} + +void ScInterpreter::ScStyle() +{ + BYTE nParamCount = GetByte(); + if (nParamCount >= 1 && nParamCount <= 3) + { + String aStyle2; // Vorlage nach Timer + if (nParamCount >= 3) + aStyle2 = GetString(); + long nTimeOut = 0; // Timeout + if (nParamCount >= 2) + nTimeOut = (long)(GetDouble()*1000.0); + String aStyle1 = GetString(); // Vorlage fuer sofort + + if (nTimeOut < 0) + nTimeOut = 0; + + // + // Request ausfuehren, um Vorlage anzuwenden + // + + if ( !pDok->IsClipOrUndo() ) + { + SfxObjectShell* pShell = pDok->GetDocumentShell(); + if (pShell) + { + //! notify object shell directly + + ScRange aRange(aPos); + ScAutoStyleHint aHint( aRange, aStyle1, nTimeOut, aStyle2 ); + pShell->Broadcast( aHint ); + } + } + + PushDouble(0.0); + } + else + SetIllegalParameter(); +} + +ScDdeLink* lcl_GetDdeLink( SvxLinkManager* pLinkMgr, + const String& rA, const String& rT, const String& rI, BYTE nM ) +{ + USHORT nCount = pLinkMgr->GetLinks().Count(); + for (USHORT i=0; i<nCount; i++ ) + { + ::binfilter::SvBaseLink* pBase = *pLinkMgr->GetLinks()[i]; + if (pBase->ISA(ScDdeLink)) + { + ScDdeLink* pLink = (ScDdeLink*)pBase; + if ( pLink->GetAppl() == rA && + pLink->GetTopic() == rT && + pLink->GetItem() == rI && + pLink->GetMode() == nM ) + return pLink; + } + } + + return NULL; +} + +/*N*/ void ScInterpreter::ScDde() +/*N*/ { +/*N*/ // Applikation, Datei, Bereich +/*N*/ // Application, Topic, Item +/*N*/ +/*N*/ BYTE nParamCount = GetByte(); +/*N*/ if ( MustHaveParamCount( nParamCount, 3, 4 ) ) +/*N*/ { +/*N*/ BYTE nMode = SC_DDE_DEFAULT; +/*N*/ if (nParamCount == 4) +/*N*/ nMode = (BYTE) ::rtl::math::approxFloor(GetDouble()); +/*N*/ String aItem = GetString(); +/*N*/ String aTopic = GetString(); +/*N*/ String aAppl = GetString(); +/*N*/ +/*N*/ if (nMode < SC_DDE_DEFAULT || nMode > SC_DDE_TEXT) +/*N*/ nMode = SC_DDE_DEFAULT; +/*N*/ +/*N*/ // temporary documents (ScFunctionAccess) have no DocShell +/*N*/ // and no LinkManager -> abort +/*N*/ +/*N*/ SvxLinkManager* pLinkMgr = pDok->GetLinkManager(); +/*N*/ if (!pLinkMgr) +/*N*/ { +/*N*/ SetNoValue(); +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ // Nach dem Laden muss neu interpretiert werden (Verknuepfungen aufbauen) +/*N*/ +/*N*/ if ( pMyFormulaCell->GetCode()->IsRecalcModeNormal() ) +/*N*/ pMyFormulaCell->GetCode()->SetRecalcModeOnLoad(); +/*N*/ +/*N*/ // solange der Link nicht ausgewertet ist, Idle abklemmen +/*N*/ // (um zirkulaere Referenzen zu vermeiden) +/*N*/ +/*N*/ BOOL bOldDis = pDok->IsIdleDisabled(); +/*N*/ pDok->DisableIdle( TRUE ); +/*N*/ +/*N*/ // Link-Objekt holen / anlegen +/*N*/ +/*N*/ ScDdeLink* pLink = lcl_GetDdeLink( pLinkMgr, aAppl, aTopic, aItem, nMode ); +/*N*/ +/*N*/ //! Dde-Links (zusaetzlich) effizienter am Dokument speichern !!!!! +/*N*/ // ScDdeLink* pLink = pDok->GetDdeLink( aAppl, aTopic, aItem ); +/*N*/ +/*N*/ BOOL bWasError = ( pMyFormulaCell->GetCode()->GetError() != 0 ); +/*N*/ +/*N*/ if (!pLink) +/*N*/ { +/*N*/ pLink = new ScDdeLink( pDok, aAppl, aTopic, aItem, nMode ); +/*N*/ pLinkMgr->InsertDDELink( pLink, aAppl, aTopic, aItem ); +/*N*/ +/*N*/ //! asynchron auswerten ??? +/*N*/ pLink->TryUpdate(); // TryUpdate ruft Update nicht mehrfach auf +/*N*/ +/*N*/ // StartListening erst nach dem Update, sonst circular reference +/*N*/ pMyFormulaCell->StartListening( *pLink, TRUE ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( !pMyFormulaCell->IsListening( *pLink ) ) +/*N*/ pMyFormulaCell->StartListening( *pLink, TRUE ); +/*N*/ } +/*N*/ +/*N*/ // Wenn aus dem Reschedule beim Ausfuehren des Links ein Fehler +/*N*/ // (z.B. zirkulaere Referenz) entstanden ist, der vorher nicht da war, +/*N*/ // das Fehler-Flag zuruecksetzen: +/*N*/ +/*N*/ if ( pMyFormulaCell->GetCode()->GetError() && !bWasError ) +/*N*/ pMyFormulaCell->GetCode()->SetError(0); +/*N*/ +/*N*/ // Wert abfragen +/*N*/ +/*N*/ const ScMatrix* pLinkMat = pLink->GetResult(); +/*N*/ if (pLinkMat) +/*N*/ { +/*N*/ USHORT nC, nR, nMatInd; +/*N*/ pLinkMat->GetDimensions(nC, nR); +/*N*/ ScMatrix* pNewMat = GetNewMat( nC, nR, nMatInd ); +/*N*/ if (pNewMat) +/*N*/ { +/*N*/ pLinkMat->MatCopy(*pNewMat); // kopieren +/*N*/ PushMatrix( pNewMat ); +/*N*/ nRetMat = nMatInd; +/*N*/ } +/*N*/ // sonst Fehler schon in GetNewMat gesetzt +/*N*/ } +/*N*/ else +/*N*/ SetNV(); +/*N*/ +/*N*/ pDok->DisableIdle( bOldDis ); +/*N*/ } +/*N*/ } + +void ScInterpreter::ScBase() +{ // Value, Base [, MinLen] + BYTE nParamCount = GetByte(); + if ( MustHaveParamCount( nParamCount, 2, 3 ) ) + { + static const sal_Unicode __FAR_DATA pDigits[] = { + '0','1','2','3','4','5','6','7','8','9', + 'A','B','C','D','E','F','G','H','I','J','K','L','M', + 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z', + 0 + }; + static const int nDigits = (sizeof(pDigits)/sizeof(sal_Unicode))-1; + xub_StrLen nMinLen; + if ( nParamCount == 3 ) + { + double fLen = ::rtl::math::approxFloor( GetDouble() ); + if ( 1.0 <= fLen && fLen < STRING_MAXLEN ) + nMinLen = (xub_StrLen) fLen; + else if ( fLen == 0.0 ) + nMinLen = 1; + else + nMinLen = 0; // Error + } + else + nMinLen = 1; + double fBase = ::rtl::math::approxFloor( GetDouble() ); + double fVal = ::rtl::math::approxFloor( GetDouble() ); + double fChars = ((fVal > 0.0 && fBase > 0.0) ? + (ceil( log( fVal ) / log( fBase ) ) + 2.0) : + 2.0); + if ( fChars >= STRING_MAXLEN ) + nMinLen = 0; // Error + + if ( !nGlobalError && nMinLen && 2 <= fBase && fBase <= nDigits && 0 <= fVal ) + { + const xub_StrLen nConstBuf = 128; + sal_Unicode aBuf[nConstBuf]; + xub_StrLen nBuf = Max( (xub_StrLen) fChars, (xub_StrLen) (nMinLen+1) ); + sal_Unicode* pBuf = (nBuf <= nConstBuf ? aBuf : new sal_Unicode[nBuf]); + for ( xub_StrLen j = 0; j < nBuf; ++j ) + { + pBuf[j] = '0'; + } + sal_Unicode* p = pBuf + nBuf - 1; + *p = 0; + if ( fVal <= (ULONG)(~0) ) + { + ULONG nVal = (ULONG) fVal; + ULONG nBase = (ULONG) fBase; + while ( nVal && p > pBuf ) + { + *--p = pDigits[ nVal % nBase ]; + nVal /= nBase; + } + fVal = (double) nVal; + } + else + { + BOOL bDirt = FALSE; + while ( fVal && p > pBuf ) + { +//! mit fmod Rundungsfehler ab 2**48 +// double fDig = ::rtl::math::approxFloor( fmod( fVal, fBase ) ); +// so ist es etwas besser + double fInt = ::rtl::math::approxFloor( fVal / fBase ); + double fMult = fInt * fBase; +#if OSL_DEBUG_LEVEL > 1 + // #53943# =BASIS(1e308;36) => GPF mit + // nDig = (size_t) ::rtl::math::approxFloor( fVal - fMult ); + // trotz vorheriger Pruefung ob fVal >= fMult + double fDebug1 = fVal - fMult; + // fVal := 7,5975311883090e+290 + // fMult := 7,5975311883090e+290 + // fDebug1 := 1,3848924157003e+275 <- RoundOff-Error + // fVal != fMult, aber: ::rtl::math::approxEqual( fVal, fMult ) == TRUE + double fDebug2 = ::rtl::math::approxSub( fVal, fMult ); + // und ::rtl::math::approxSub( fVal, fMult ) == 0 + double fDebug3 = ( fInt ? fVal / fInt : 0.0 ); + // Nach dem strange fDebug1 und fVal < fMult ist eigentlich + // fDebug2 == fBase, trotzdem wird das mit einem Vergleich + // nicht erkannt, dann schlaegt bDirt zu und alles wird wieder gut.. +#endif + size_t nDig; + if ( fVal < fMult ) + { // da ist was gekippt + bDirt = TRUE; + nDig = 0; + } + else + { + double fDig = ::rtl::math::approxFloor( ::rtl::math::approxSub( fVal, fMult ) ); + if ( bDirt ) + { + bDirt = FALSE; + --fDig; + } + if ( fDig <= 0.0 ) + nDig = 0; + else if ( fDig >= fBase ) + nDig = ((size_t) fBase) - 1; + else + nDig = (size_t) fDig; + } + *--p = pDigits[ nDig ]; + fVal = fInt; + } + } + if ( fVal ) + { + SetError( errStringOverflow ); + PushInt(0); + } + else + { + if ( nBuf - (p - pBuf) <= nMinLen ) + p = pBuf + nBuf - 1 - nMinLen; + PushStringBuffer( p ); + } + if ( pBuf != aBuf ) + delete [] pBuf; + } + else + SetIllegalArgument(); + } +} + + +/*N*/ void ScInterpreter::ScDecimal() +/*N*/ { // Text, Base +/*N*/ if ( MustHaveParamCount( GetByte(), 2 ) ) +/*N*/ { +/*N*/ double fBase = ::rtl::math::approxFloor( GetDouble() ); +/*N*/ String aStr( GetString() ); +/*N*/ if ( !nGlobalError && 2 <= fBase && fBase <= 36 ) +/*N*/ { +/*N*/ double fVal = 0.0; +/*N*/ int nBase = (int) fBase; +/*N*/ register const sal_Unicode* p = aStr.GetBuffer(); +/*N*/ while ( *p == ' ' || *p == '\t' ) +/*N*/ p++; // strip leading white space +/*N*/ if ( nBase == 16 ) +/*N*/ { // evtl. hex-prefix strippen +/*N*/ if ( *p == 'x' || *p == 'X' ) +/*N*/ p++; +/*N*/ else if ( *p == '0' && (*(p+1) == 'x' || *(p+1) == 'X') ) +/*N*/ p += 2; +/*N*/ } +/*N*/ while ( *p ) +/*N*/ { +/*N*/ int n; +/*N*/ if ( '0' <= *p && *p <= '9' ) +/*N*/ n = *p - '0'; +/*N*/ else if ( 'A' <= *p && *p <= 'Z' ) +/*N*/ n = 10 + (*p - 'A'); +/*N*/ else if ( 'a' <= *p && *p <= 'z' ) +/*N*/ n = 10 + (*p - 'a'); +/*N*/ else +/*N*/ n = nBase; +/*N*/ if ( nBase <= n ) +/*N*/ { +/*N*/ if ( *(p+1) == 0 && +/*N*/ ( (nBase == 2 && (*p == 'b' || *p == 'B')) +/*N*/ ||(nBase == 16 && (*p == 'h' || *p == 'H')) ) +/*N*/ ) +/*N*/ ; // 101b und F00Dh sind ok +/*N*/ else +/*N*/ { +/*?*/ SetIllegalArgument(); +/*?*/ return ; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ fVal = fVal * fBase + n; +/*N*/ p++; +/*N*/ +/*N*/ } +/*N*/ PushDouble( fVal ); +/*N*/ } +/*N*/ else +/*?*/ SetIllegalArgument(); +/*N*/ } +/*N*/ } + + +/*N*/ void ScInterpreter::ScConvert() +/*N*/ { // Value, FromUnit, ToUnit +/*N*/ if ( MustHaveParamCount( GetByte(), 3 ) ) +/*N*/ { +/*N*/ String aToUnit( GetString() ); +/*N*/ String aFromUnit( GetString() ); +/*N*/ double fVal = GetDouble(); +/*N*/ if ( nGlobalError ) +/*?*/ SetIllegalArgument(); +/*N*/ else +/*N*/ { // erst die angegebene Reihenfolge suchen, wenn nicht gefunden den Kehrwert +/*N*/ double fConv; +/*N*/ if ( ScGlobal::GetUnitConverter()->GetValue( fConv, aFromUnit, aToUnit ) ) +/*?*/ PushDouble( fVal * fConv ); +/*N*/ else if ( ScGlobal::GetUnitConverter()->GetValue( fConv, aToUnit, aFromUnit ) ) +/*N*/ PushDouble( fVal / fConv ); +/*N*/ else +/*?*/ SetNV(); +/*N*/ } +/*N*/ } +/*N*/ } + + +void ScInterpreter::ScRoman() +{ // Value [Mode] + BYTE nParamCount = GetByte(); + if( MustHaveParamCount( nParamCount, 1, 2 ) ) + { + double fMode = (nParamCount == 2) ? ::rtl::math::approxFloor( GetDouble() ) : 0.0; + double fVal = ::rtl::math::approxFloor( GetDouble() ); + if( nGlobalError ) + SetIllegalParameter(); + else if( (fMode >= 0.0) && (fMode < 5.0) && (fVal >= 0.0) && (fVal < 4000.0) ) + { + static const sal_Unicode pChars[] = { 'M', 'D', 'C', 'L', 'X', 'V', 'I' }; + static const USHORT pValues[] = { 1000, 500, 100, 50, 10, 5, 1 }; + static const USHORT nMaxIndex = (USHORT)(SAL_N_ELEMENTS(pValues) - 1); + + String aRoman; + USHORT nVal = (USHORT) fVal; + USHORT nMode = (USHORT) fMode; + + for( UINT16 i = 0; i <= nMaxIndex / 2; i++ ) + { + USHORT nIndex = 2 * i; + USHORT nDigit = nVal / pValues[ nIndex ]; + + if( (nDigit % 5) == 4 ) + { + USHORT nIndex2 = (nDigit == 4) ? nIndex - 1 : nIndex - 2; + USHORT nSteps = 0; + while( (nSteps < nMode) && (nIndex < nMaxIndex) ) + { + nSteps++; + if( pValues[ nIndex2 ] - pValues[ nIndex + 1 ] <= nVal ) + nIndex++; + else + nSteps = nMode; + } + aRoman += pChars[ nIndex ]; + aRoman += pChars[ nIndex2 ]; + nVal += pValues[ nIndex ]; + nVal -= pValues[ nIndex2 ]; + } + else + { + if( nDigit > 4 ) + aRoman += pChars[ nIndex - 1 ]; + aRoman.Expand( aRoman.Len() + (nDigit % 5), pChars[ nIndex ] ); + nVal %= pValues[ nIndex ]; + } + } + + PushString( aRoman ); + } + else + SetIllegalArgument(); + } +} + + +BOOL lcl_GetArabicValue( sal_Unicode cChar, USHORT& rnValue, BOOL& rbIsDec ) +{ + switch( cChar ) + { + case 'M': rnValue = 1000; rbIsDec = TRUE; break; + case 'D': rnValue = 500; rbIsDec = FALSE; break; + case 'C': rnValue = 100; rbIsDec = TRUE; break; + case 'L': rnValue = 50; rbIsDec = FALSE; break; + case 'X': rnValue = 10; rbIsDec = TRUE; break; + case 'V': rnValue = 5; rbIsDec = FALSE; break; + case 'I': rnValue = 1; rbIsDec = TRUE; break; + default: return FALSE; + } + return TRUE; +} + + +void ScInterpreter::ScArabic() +{ + String aRoman( GetString() ); + if( nGlobalError ) + SetIllegalParameter(); + else + { + aRoman.ToUpperAscii(); + + USHORT nValue = 0; + USHORT nValidRest = 3999; + USHORT nCharIndex = 0; + USHORT nCharCount = aRoman.Len(); + BOOL bValid = TRUE; + + while( bValid && (nCharIndex < nCharCount) ) + { + USHORT nDigit1 = 0; + USHORT nDigit2 = 0; + BOOL bIsDec1 = FALSE; + BOOL bIsDec2 = FALSE; + bValid = lcl_GetArabicValue( aRoman.GetChar( nCharIndex ), nDigit1, bIsDec1 ); + if( bValid && (nCharIndex + 1 < nCharCount) ) + bValid = lcl_GetArabicValue( aRoman.GetChar( nCharIndex + 1 ), nDigit2, bIsDec2 ); + if( bValid ) + { + if( nDigit1 >= nDigit2 ) + { + nValue += nDigit1; + nValidRest %= (nDigit1 * (bIsDec1 ? 5 : 2)); + bValid = (nValidRest >= nDigit1); + if( bValid ) + nValidRest -= nDigit1; + nCharIndex++; + } + else if( nDigit1 * 2 != nDigit2 ) + { + USHORT nDiff = nDigit2 - nDigit1; + nValue += nDiff; + bValid = (nValidRest >= nDiff); + if( bValid ) + nValidRest = nDigit1 - 1; + nCharIndex += 2; + } + else + bValid = FALSE; + } + } + if( bValid ) + PushInt( nValue ); + else + SetIllegalArgument(); + } +} + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_interpr3.cxx b/binfilter/bf_sc/source/core/tool/sc_interpr3.cxx new file mode 100644 index 000000000000..1aaf13cb1038 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_interpr3.cxx @@ -0,0 +1,3764 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// INCLUDE --------------------------------------------------------------- + +#include <tools/solar.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include "interpre.hxx" +#include "dociter.hxx" +#include "scmatrix.hxx" +#include "globstr.hrc" +namespace binfilter { + +// STATIC DATA ----------------------------------------------------------- + +#define SCdEpsilon 1.0E-7 +#define SC_MAX_ITERATION_COUNT 20 +#define MAX_ANZ_DOUBLE_FOR_SORT 100000 +// PI jetzt als F_PI aus solar.h +//#define PI 3.1415926535897932 + +//----------------------------------------------------------------------------- + +class ScDistFunc +{ +public: + virtual double GetValue(double x) const = 0; +}; + +// iteration for inverse distributions + +//template< class T > double lcl_IterateInverse( const T& rFunction, double x0, double x1, BOOL& rConvError ) +double lcl_IterateInverse( const ScDistFunc& rFunction, double x0, double x1, BOOL& rConvError ) +{ + rConvError = FALSE; + double fEps = 1.0E-7; + + DBG_ASSERT(x0<x1, "IterateInverse: wrong interval"); + + // find enclosing interval + + double f0 = rFunction.GetValue(x0); + double f1 = rFunction.GetValue(x1); + double xs; + USHORT i; + for (i = 0; i < 1000 && f0*f1 > 0.0; i++) + { + if (fabs(f0) <= fabs(f1)) + { + xs = x0; + x0 += 2.0 * (x0 - x1); + if (x0 < 0.0) + x0 = 0.0; + x1 = xs; + f1 = f0; + f0 = rFunction.GetValue(x0); + } + else + { + xs = x1; + x1 += 2.0 * (x1 - x0); + x0 = xs; + f0 = f1; + f1 = rFunction.GetValue(x1); + } + } + + if (f0 == 0.0) + return x0; + if (f1 == 0.0) + return x1; + + // simple iteration + + double x00 = x0; + double x11 = x1; + double fs = 0.0; + for (i = 0; i < 100; i++) + { + xs = 0.5*(x0+x1); + if (fabs(f1-f0) >= fEps) + { + fs = rFunction.GetValue(xs); + if (f0*fs <= 0.0) + { + x1 = xs; + f1 = fs; + } + else + { + x0 = xs; + f0 = fs; + } + } + else + { + // add one step of regula falsi to improve precision + + if ( x0 != x1 ) + { + double regxs = (f1-f0)/(x1-x0); + if ( regxs != 0.0) + { + double regx = x1 - f1/regxs; + if (regx >= x00 && regx <= x11) + { + double regfs = rFunction.GetValue(regx); + if ( fabs(regfs) < fabs(fs) ) + xs = regx; + } + } + } + + return xs; + } + } + + rConvError = TRUE; + return 0.0; +} + +//----------------------------------------------------------------------------- +// Allgemeine Funktionen +//----------------------------------------------------------------------------- + +void ScInterpreter::ScNoName() +{ + SetError(errNoName); +} + +double ScInterpreter::phi(double x) +{ + return 0.39894228040143268 * exp(-(x * x) / 2.0); +} + +double ScInterpreter::taylor(double* pPolynom, USHORT nMax, double x) +{ + double nVal = pPolynom[nMax]; + for (short i = nMax-1; i >= 0; i--) + { + nVal = pPolynom[i] + (nVal * x); + } + return nVal; +} + +double ScInterpreter::gauss(double x) +{ + double t0[] = + { 0.39894228040143268, -0.06649038006690545, 0.00997355701003582, + -0.00118732821548045, 0.00011543468761616, -0.00000944465625950, + 0.00000066596935163, -0.00000004122667415, 0.00000000227352982, + 0.00000000011301172, 0.00000000000511243, -0.00000000000021218 }; + double t2[] = + { 0.47724986805182079, 0.05399096651318805, -0.05399096651318805, + 0.02699548325659403, -0.00449924720943234, -0.00224962360471617, + 0.00134977416282970, -0.00011783742691370, -0.00011515930357476, + 0.00003704737285544, 0.00000282690796889, -0.00000354513195524, + 0.00000037669563126, 0.00000019202407921, -0.00000005226908590, + -0.00000000491799345, 0.00000000366377919, -0.00000000015981997, + -0.00000000017381238, 0.00000000002624031, 0.00000000000560919, + -0.00000000000172127, -0.00000000000008634, 0.00000000000007894 }; + double t4[] = + { 0.49996832875816688, 0.00013383022576489, -0.00026766045152977, + 0.00033457556441221, -0.00028996548915725, 0.00018178605666397, + -0.00008252863922168, 0.00002551802519049, -0.00000391665839292, + -0.00000074018205222, 0.00000064422023359, -0.00000017370155340, + 0.00000000909595465, 0.00000000944943118, -0.00000000329957075, + 0.00000000029492075, 0.00000000011874477, -0.00000000004420396, + 0.00000000000361422, 0.00000000000143638, -0.00000000000045848 }; + double asympt[] = { -1.0, 1.0, -3.0, 15.0, -105.0 }; + + double xAbs = fabs(x); + USHORT xShort = (USHORT)::rtl::math::approxFloor(xAbs); + double nVal = 0.0; + if (xShort == 0) + nVal = taylor(t0, 11, (xAbs * xAbs)) * xAbs; + else if ((xShort >= 1) && (xShort <= 2)) + nVal = taylor(t2, 23, (xAbs - 2.0)); + else if ((xShort >= 3) && (xShort <= 4)) + nVal = taylor(t4, 20, (xAbs - 4.0)); + else + nVal = 0.5 + phi(xAbs) * taylor(asympt, 4, 1.0 / (xAbs * xAbs)) / xAbs; + if (x < 0.0) + return -nVal; + else + return nVal; +} + +#if defined(WIN) && defined(MSC) +#pragma optimize("",off) +#endif + +double ScInterpreter::gaussinv(double x) +{ + double c0, c1, c2, d1, d2, d3, q, t, z; + c0 = 2.515517; + c1 = 0.802853; + c2 = 0.010328; + d1 = 1.432788; + d2 = 0.189269; + d3 = 0.001308; + if (x < 0.5) + q = x; + else + q = 1.0-x; + t = sqrt(-log(q*q)); + z = t - (c0 + t*(c1 + t*c2)) / (1.0 + t*(d1 + t*(d2 + t*d3))); + if (x < 0.5) + z *= -1.0; + return z; +} +#if defined(WIN) && defined(MSC) +#pragma optimize("",on) +#endif + +double ScInterpreter::Fakultaet(double x) +{ + x = ::rtl::math::approxFloor(x); + if (x < 0.0) + return 0.0; + else if (x == 0.0) + return 1.0; + else if (x <= 170.0) + { + double fTemp = x; + while (fTemp > 2.0) + { + fTemp--; + x *= fTemp; + } + } + else + SetError(errNoValue); +/* // Stirlingsche Naeherung zu ungenau + else + x = pow(x/exp(1), x) * sqrt(x) * SQRT_2_PI * (1.0 + 1.0 / (12.0 * x)); +*/ + return x; +} + +double ScInterpreter::BinomKoeff(double n, double k) +{ + double nVal = 0.0; + k = ::rtl::math::approxFloor(k); + if (n < k) + nVal = 0.0; + else if (k == 0.0) + nVal = 1.0; + else + { + nVal = n/k; + n--; + k--; + while (k > 0.0) + { + nVal *= n/k; + k--; + n--; + } +/* + double f1 = n; // Zaehler + double f2 = k; // Nenner + n--; + k--; + while (k > 0.0) + { + f2 *= k; + f1 *= n; + k--; + n--; + } + nVal = f1 / f2; +*/ + } + return nVal; +} + +double ScInterpreter::GammaHelp(double& x, BOOL& bReflect) +{ + double c[6] = {76.18009173, -86.50532033, 24.01409822, + -1.231739516, 0.120858003E-2, -0.536382E-5}; + if (x >= 1.0) + { + bReflect = FALSE; + x -= 1.0; + } + else + { + bReflect = TRUE; + x = 1.0 - x; + } + double s, anum; + s = 1.0; + anum = x; + for (USHORT i = 0; i < 6; i++) + { + anum += 1.0; + s += c[i]/anum; + } + s *= 2.506628275; // sqrt(2*PI) + return s; +} + +double ScInterpreter::GetGamma(double x) +{ + BOOL bReflect; + double G = GammaHelp(x, bReflect); + G = pow(x+5.5,x+0.5)*G/exp(x+5.5); + if (bReflect) + G = F_PI*x/(G*::rtl::math::sin(F_PI*x)); + return G; +} + +double ScInterpreter::GetLogGamma(double x) +{ + BOOL bReflect; + double G = GammaHelp(x, bReflect); + G = (x+0.5)*log(x+5.5)+log(G)-(x+5.5); + if (bReflect) + G = log(F_PI*x)-G-log(::rtl::math::sin(F_PI*x)); + return G; +} + +double ScInterpreter::GetBetaDist(double x, double alpha, double beta) +{ + if (beta == 1.0) + return pow(x, alpha); + else if (alpha == 1.0) + return 1.0 - pow(1.0-x,beta); + double fEps = 1.0E-8; + BOOL bReflect; + double cf, fA, fB; + if (x < (alpha+1.0)/(alpha+beta+1.0)) + { + bReflect = FALSE; + fA = alpha; + fB = beta; + } + else + { + bReflect = TRUE; + fA = beta; + fB = alpha; + x = 1.0 - x; + } + if (x < fEps) + cf = 0.0; + else + { + double a1, b1, a2, b2, fnorm, rm, apl2m, d2m, d2m1, cfnew; + a1 = 1.0; b1 = 1.0; + b2 = 1.0 - (fA+fB)*x/(fA+1.0); + if (b2 == 0.0) + { + a2 = b2; + fnorm = 1.0; + cf = 1.0; + } + else + { + a2 = 1.0; + fnorm = 1.0/b2; + cf = a2*fnorm; + } + cfnew = 1.0; + for (USHORT j = 1; j <= 100; j++) + { + rm = (double) j; + apl2m = fA + 2.0*rm; + d2m = rm*(fB-rm)*x/((apl2m-1.0)*apl2m); + d2m1 = -(fA+rm)*(fA+fB+rm)*x/(apl2m*(apl2m+1.0)); + a1 = (a2+d2m*a1)*fnorm; + b1 = (b2+d2m*b1)*fnorm; + a2 = a1 + d2m1*a2*fnorm; + b2 = b1 + d2m1*b2*fnorm; + if (b2 != 0.0) + { + fnorm = 1.0/b2; + cfnew = a2*fnorm; + if (fabs(cf-cfnew)/cf < fEps) + j = 101; + else + cf = cfnew; + } + } + if (fB < fEps) + b1 = 69; // ln(1.0E30) + else + b1 = GetLogGamma(fA)+GetLogGamma(fB)-GetLogGamma(fA+fB); + + // cf *= pow(x, fA)*pow(1.0-x,fB)/(fA*exp(b1)); + // #108995# The formula above has 0 as results for the terms too easily, + // resulting in an error where the equivalent formula below still works: + // (x can't be 0 or 1, this is handled above) + cf *= exp( log(x)*fA + log(1.0-x)*fB - b1 ) / fA; + } + if (bReflect) + return 1.0-cf; + else + return cf; +} + +double ScInterpreter::GetFDist(double x, double fF1, double fF2) +{ + double arg = fF2/(fF2+fF1*x); + double alpha = fF2/2.0; + double beta = fF1/2.0; + return (GetBetaDist(arg, alpha, beta)); +/* + double Z = (pow(fF,1.0/3.0)*(1.0-2.0/(9.0*fF2)) - (1.0-2.0/(9.0*fF1))) / + sqrt(2.0/(9.0*fF1) + pow(fF,2.0/3.0)*2.0/(9.0*fF2)); + return (0.5-gauss(Z)); +*/ +} + +double ScInterpreter::GetTDist(double T, double fDF) +{ + return 0.5 * GetBetaDist(fDF/(fDF+T*T), fDF/2.0, 0.5); +/* + USHORT DF = (USHORT) fDF; + double A = T / sqrt(DF); + double B = 1.0 + A*A; + double R; + if (DF == 1) + R = 0.5 + atan(A)/F_PI; + else if (DF % 2 == 0) + { + double S0 = A/(2.0 * sqrt(B)); + double C0 = S0; + for (USHORT i = 2; i <= DF-2; i+=2) + { + C0 *= (1.0 - 1.0/(double)i)/B; + S0 += C0; + } + R = 0.5 + S0; + } + else + { + double S1 = A / (B * F_PI); + double C1 = S1; + for (USHORT i = 3; i <= DF-2; i+=2) + { + C1 *= (1.0 - 1.0/(double)i)/B; + S1 += C1; + } + R = 0.5 + atan(A)/F_PI + S1; + } + return 1.0 - R; +*/ +} + +double ScInterpreter::GetChiDist(double fChi, double fDF) +{ + return 1.0 - GetGammaDist(fChi/2.0, fDF/2.0, 1.0); +/* + double x = 1.0; + for (double i = fDF; i >= 2.0; i -= 2.0) + x *= fChi/i; + x *= exp(-fChi/2.0); + if (fmod(fDF, 2.0) != 0.0) + x *= sqrt(2.0*fChi/F_PI); + double S = 1.0; + double T = 1.0; + double G = fDF; + BOOL bStop = FALSE; + while (!bStop) + { + G += 2.0; + T *= fChi/G; + if (T < 1.0E-7) + bStop = TRUE; + else + S += T; + } + return 1.0 - x*S; +*/ +} + +void ScInterpreter::ScLogGamma() +{ + double x = GetDouble(); + if (x > 0.0) + PushDouble(GetLogGamma(x)); + else + SetIllegalArgument(); +} + +void ScInterpreter::ScBetaDist() +{ + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 3, 5 ) ) + return; + double fA, fB, alpha, beta, x; + if (nParamCount == 5) + fB = GetDouble(); + else + fB = 1.0; + if (nParamCount >= 4) + fA = GetDouble(); + else + fA = 0.0; + beta = GetDouble(); + alpha = GetDouble(); + x = GetDouble(); + if (x < fA || x > fB || fA == fB || alpha <= 0.0 || beta <= 0.0) + { + SetIllegalArgument(); + return; + } + x = (x-fA)/(fB-fA); // Skalierung auf (0,1) + PushDouble(GetBetaDist(x, alpha, beta)); +} + +void ScInterpreter::ScPhi() +{ + PushDouble(phi(GetDouble())); +} + +void ScInterpreter::ScGauss() +{ + PushDouble(gauss(GetDouble())); +} + +void ScInterpreter::ScFisher() +{ + double fVal = GetDouble(); + if (fabs(fVal) >= 1.0) + SetIllegalArgument(); + else + PushDouble(0.5*log((1.0+fVal)/(1.0-fVal))); +} + +void ScInterpreter::ScFisherInv() +{ + double fVal = GetDouble(); + PushDouble((exp(2.0*fVal)-1.0)/(exp(2.0*fVal)+1.0)); +} + +void ScInterpreter::ScFact() +{ + double nVal = GetDouble(); + if (nVal < 0.0) + SetIllegalArgument(); + else + PushDouble(Fakultaet(nVal)); +} + +void ScInterpreter::ScKombin() +{ + if ( MustHaveParamCount( GetByte(), 2 ) ) + { + double k = ::rtl::math::approxFloor(GetDouble()); + double n = ::rtl::math::approxFloor(GetDouble()); + if (k < 0.0 || n < 0.0 || k > n) + SetIllegalArgument(); + else + PushDouble(BinomKoeff(n, k)); + } +} + +void ScInterpreter::ScKombin2() +{ + if ( MustHaveParamCount( GetByte(), 2 ) ) + { + double k = ::rtl::math::approxFloor(GetDouble()); + double n = ::rtl::math::approxFloor(GetDouble()); + if (k < 0.0 || n < 0.0 || k > n) + SetIllegalArgument(); + else + PushDouble(BinomKoeff(n + k - 1, k)); + } +} + +void ScInterpreter::ScVariationen() +{ + if ( MustHaveParamCount( GetByte(), 2 ) ) + { + double k = ::rtl::math::approxFloor(GetDouble()); + double n = ::rtl::math::approxFloor(GetDouble()); + if (n < 0.0 || k < 0.0 || k > n) + SetIllegalArgument(); + else if (k == 0.0) + PushInt(1); // (n! / (n - 0)!) == 1 + else + { + double nVal = n; + for (ULONG i = (ULONG)k-1; i >= 1; i--) + nVal *= n-(double)i; + PushDouble(nVal); + } + } +} + +void ScInterpreter::ScVariationen2() +{ + if ( MustHaveParamCount( GetByte(), 2 ) ) + { + double k = ::rtl::math::approxFloor(GetDouble()); + double n = ::rtl::math::approxFloor(GetDouble()); + if (n < 0.0 || k < 0.0 || k > n) + SetIllegalArgument(); + else + PushDouble(pow(n,k)); + } +} + +void ScInterpreter::ScB() +{ + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 3, 4 ) ) + return ; + if (nParamCount == 3) + { + double x = ::rtl::math::approxFloor(GetDouble()); + double p = GetDouble(); + double n = ::rtl::math::approxFloor(GetDouble()); + if (n < 0.0 || x < 0.0 || x > n || p < 0.0 || p > 1.0) + SetIllegalArgument(); + else + { + double q = 1.0 - p; + double fFactor = pow(q, n); + if (fFactor == 0.0) + { + fFactor = pow(p, n); + if (fFactor == 0.0) + SetNoValue(); + else + { + ULONG max = (ULONG) (n - x); + for (ULONG i = 0; i < max && fFactor > 0.0; i++) + fFactor *= (n-i)/(i+1)*q/p; + PushDouble(fFactor); + } + } + else + { + ULONG max = (ULONG) x; + for (ULONG i = 0; i < max && fFactor > 0.0; i++) + fFactor *= (n-i)/(i+1)*p/q; + PushDouble(fFactor); + } + } + } + else if (nParamCount == 4) + { + double xe = GetDouble(); + double xs = GetDouble(); + double p = GetDouble(); + double n = GetDouble(); +// alter Stand 300-SC +// if ((xs < n) && (xe < n) && (p < 1.0)) +// { +// double Varianz = sqrt(n * p * (1.0 - p)); +// xs = fabs(xs - (n * p /* / 2.0 STE */ )); +// xe = fabs(xe - (n * p /* / 2.0 STE */ )); +//// STE double nVal = gauss((xs + 0.5) / Varianz) + gauss((xe + 0.5) / Varianz); +// double nVal = fabs(gauss(xs / Varianz) - gauss(xe / Varianz)); +// PushDouble(nVal); +// } + if (xe <= n && xs <= xe && + p < 1.0 && p > 0.0 && n >= 0.0 && xs >= 0.0 ) + { + double q = 1.0 - p; + double fFactor = pow(q, n); + if (fFactor == 0.0) + { + fFactor = pow(p, n); + if (fFactor == 0.0) + SetNoValue(); + else + { + double fSum = 0.0; + ULONG max; + if (xe < (ULONG) n) + max = (ULONG) (n-xe)-1; + else + max = 0; + ULONG i; + for (i = 0; i < max && fFactor > 0.0; i++) + fFactor *= (n-i)/(i+1)*q/p; + if (xs < (ULONG) n) + max = (ULONG) (n-xs); + else + fSum = fFactor; + for (; i < max && fFactor > 0.0; i++) + { + fFactor *= (n-i)/(i+1)*q/p; + fSum += fFactor; + } + PushDouble(fSum); + } + } + else + { + ULONG max; + double fSum; + if ( (ULONG) xs == 0) + { + fSum = fFactor; + max = 0; + } + else + { + max = (ULONG) xs-1; + fSum = 0.0; + } + ULONG i; + for (i = 0; i < max && fFactor > 0.0; i++) + fFactor *= (n-i)/(i+1)*p/q; + if ((ULONG)xe == 0) // beide 0 + fSum = fFactor; + else + max = (ULONG) xe; + for (; i < max && fFactor > 0.0; i++) + { + fFactor *= (n-i)/(i+1)*p/q; + fSum += fFactor; + } + PushDouble(fSum); + } + } + else + SetIllegalArgument(); + } +} + +void ScInterpreter::ScBinomDist() +{ + if ( MustHaveParamCount( GetByte(), 4 ) ) + { + double kum = GetDouble(); // 0 oder 1 + double p = GetDouble(); // p + double n = ::rtl::math::approxFloor(GetDouble()); // n + double x = ::rtl::math::approxFloor(GetDouble()); // x + double fFactor, q, fSum; + if (n < 0.0 || x < 0.0 || x > n || p < 0.0 || p > 1.0) + SetIllegalArgument(); + else if (kum == 0.0) // Dichte + { + q = 1.0 - p; + fFactor = pow(q, n); + if (fFactor == 0.0) + { + fFactor = pow(p, n); + if (fFactor == 0.0) + SetNoValue(); + else + { + ULONG max = (ULONG) (n - x); + for (ULONG i = 0; i < max && fFactor > 0.0; i++) + fFactor *= (n-i)/(i+1)*q/p; + PushDouble(fFactor); + } + } + else + { + ULONG max = (ULONG) x; + for (ULONG i = 0; i < max && fFactor > 0.0; i++) + fFactor *= (n-i)/(i+1)*p/q; + PushDouble(fFactor); + } + } + else // Verteilung + { + if (n == x) + PushDouble(1.0); + else + { + q = 1.0 - p; + fFactor = pow(q, n); + if (fFactor == 0.0) + { + fFactor = pow(p, n); + if (fFactor == 0.0) + SetNoValue(); + else + { + fSum = 1.0 - fFactor; + ULONG max = (ULONG) (n - x) - 1; + for (ULONG i = 0; i < max && fFactor > 0.0; i++) + { + fFactor *= (n-i)/(i+1)*q/p; + fSum -= fFactor; + } + if (fSum < 0.0) + PushDouble(0.0); + else + PushDouble(fSum); + } + } + else + { + double fSum = fFactor; + ULONG max = (ULONG) x; + for (ULONG i = 0; i < max && fFactor > 0.0; i++) + { + fFactor *= (n-i)/(i+1)*p/q; + fSum += fFactor; + } + PushDouble(fSum); + } + } + } + } +} + +void ScInterpreter::ScCritBinom() +{ + if ( MustHaveParamCount( GetByte(), 3 ) ) + { + double alpha = GetDouble(); // alpha + double p = GetDouble(); // p + double n = ::rtl::math::approxFloor(GetDouble()); + if (n < 0.0 || alpha <= 0.0 || alpha >= 1.0 || p < 0.0 || p > 1.0) + SetIllegalArgument(); + else + { + double q = 1.0 - p; + double fFactor = pow(q,n); + if (fFactor == 0.0) + { + fFactor = pow(p, n); + if (fFactor == 0.0) + SetNoValue(); + else + { + double fSum = 1.0 - fFactor; ULONG max = (ULONG) n; + ULONG i = 0; + for (i = 0; i < max && fSum >= alpha; i++) + { + fFactor *= (n-i)/(i+1)*q/p; + fSum -= fFactor; + } + PushDouble(n-i); + } + } + else + { + double fSum = fFactor; ULONG max = (ULONG) n; + ULONG i = 0; + for (i = 0; i < max && fSum < alpha; i++) + { + fFactor *= (n-i)/(i+1)*p/q; + fSum += fFactor; + } + PushDouble(i); + } + } + } +} + +void ScInterpreter::ScNegBinomDist() +{ + if ( MustHaveParamCount( GetByte(), 3 ) ) + { + double p = GetDouble(); // p + double r = GetDouble(); // r + double x = GetDouble(); // x + if (r < 0.0 || x < 0.0 || p < 0.0 || p > 1.0) + SetIllegalArgument(); + else + { + double q = 1.0 - p; + double fFactor = pow(p,r); + for (double i = 0.0; i < x; i++) + fFactor *= (i+r)/(i+1.0)*q; + PushDouble(fFactor); + } + } +} + +void ScInterpreter::ScNormDist() +{ + if ( MustHaveParamCount( GetByte(), 4 ) ) + { + double kum = GetDouble(); // 0 oder 1 + double sigma = GetDouble(); // Stdabw + double mue = GetDouble(); // Mittelwert + double x = GetDouble(); // x + if (sigma <= 0.0) + SetIllegalArgument(); + else if (kum == 0.0) // Dichte + PushDouble(phi((x-mue)/sigma)/sigma); + else // Verteilung + PushDouble(0.5 + gauss((x-mue)/sigma)); + } +} + +void ScInterpreter::ScLogNormDist() +{ + if ( MustHaveParamCount( GetByte(), 3 ) ) + { + double sigma = GetDouble(); // Stdabw + double mue = GetDouble(); // Mittelwert + double x = GetDouble(); // x + if (sigma <= 0.0 || x <= 0.0) + SetIllegalArgument(); + else + PushDouble(0.5 + gauss((log(x)-mue)/sigma)); + } +} + +void ScInterpreter::ScStdNormDist() +{ + PushDouble(0.5 + gauss(GetDouble())); +} + +void ScInterpreter::ScExpDist() +{ + if ( MustHaveParamCount( GetByte(), 3 ) ) + { + double kum = GetDouble(); // 0 oder 1 + double lambda = GetDouble(); // lambda + double x = GetDouble(); // x + if (lambda <= 0.0) + SetIllegalArgument(); + else if (kum == 0.0) // Dichte + { + if (x >= 0.0) + PushDouble(lambda * exp(-lambda*x)); + else + PushInt(0); + } + else // Verteilung + { + if (x > 0.0) + PushDouble(1.0 - exp(-lambda*x)); + else + PushInt(0); + } + } +} + +void ScInterpreter::ScTDist() +{ + if ( !MustHaveParamCount( GetByte(), 3 ) ) + return; + double fFlag = ::rtl::math::approxFloor(GetDouble()); + double fDF = ::rtl::math::approxFloor(GetDouble()); + double T = GetDouble(); + if (fDF < 1.0 || T < 0.0 || (fFlag != 1.0 && fFlag != 2.0) ) + { + SetIllegalArgument(); + return; + } + double R = GetTDist(T, fDF); + if (fFlag == 1.0) + PushDouble(R); + else + PushDouble(2.0*R); +} + +void ScInterpreter::ScFDist() +{ + if ( !MustHaveParamCount( GetByte(), 3 ) ) + return; + double fF2 = ::rtl::math::approxFloor(GetDouble()); + double fF1 = ::rtl::math::approxFloor(GetDouble()); + double fF = GetDouble(); + if (fF < 0.0 || fF1 < 1.0 || fF2 < 1.0 || fF1 >= 1.0E10 || fF2 >= 1.0E10) + { + SetIllegalArgument(); + return; + } + PushDouble(GetFDist(fF, fF1, fF2)); +} + +void ScInterpreter::ScChiDist() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + double fDF = ::rtl::math::approxFloor(GetDouble()); + double fChi = GetDouble(); + if (fDF < 1.0 || fDF >= 1.0E5 || fChi < 0.0 ) + { + SetIllegalArgument(); + return; + } + PushDouble(GetChiDist(fChi, fDF)); +} + +void ScInterpreter::ScWeibull() +{ + if ( MustHaveParamCount( GetByte(), 4 ) ) + { + double kum = GetDouble(); // 0 oder 1 + double beta = GetDouble(); // beta + double alpha = GetDouble(); // alpha + double x = GetDouble(); // x + if (alpha <= 0.0 || beta <= 0.0 || x < 0.0) + SetIllegalArgument(); + else if (kum == 0.0) // Dichte + PushDouble(alpha/pow(beta,alpha)*pow(x,alpha-1.0)* + exp(-pow(x/beta,alpha))); + else // Verteilung + PushDouble(1.0 - exp(-pow(x/beta,alpha))); + } +} + +void ScInterpreter::ScPoissonDist() +{ + if ( MustHaveParamCount( GetByte(), 3 ) ) + { + double kum = GetDouble(); // 0 oder 1 + double lambda = GetDouble(); // Mittelwert + double x = ::rtl::math::approxFloor(GetDouble()); // x + if (lambda < 0.0 || x < 0.0) + SetIllegalArgument(); + else if (kum == 0.0) // Dichte + { + if (lambda == 0.0) + PushInt(0); + else + PushDouble(exp(-lambda)*pow(lambda,x)/Fakultaet(x)); + } + else // Verteilung + { + if (lambda == 0.0) + PushInt(1); + else + { + double sum = 1.0; + double fFak = 1.0; + ULONG nEnd = (ULONG) x; + for (ULONG i = 1; i <= nEnd; i++) + { + fFak *= (double)i; + sum += pow( lambda, (double)i ) / fFak; + } + sum *= exp(-lambda); + PushDouble(sum); + } + } + } +} + +void ScInterpreter::ScHypGeomDist() +{ + if ( MustHaveParamCount( GetByte(), 4 ) ) + { + double N = ::rtl::math::approxFloor(GetDouble()); + double M = ::rtl::math::approxFloor(GetDouble()); + double n = ::rtl::math::approxFloor(GetDouble()); + double x = ::rtl::math::approxFloor(GetDouble()); + + if( (x < 0.0) || (n < x) || (M < x) || (N < n) || (N < M) || (x < n - N + M) ) + { + SetIllegalArgument(); + return; + } + double fFactor = + BinomKoeff( n, x ) / BinomKoeff( N, M ) * BinomKoeff( N - n, M - x ); + +/* + double fFactor; + if (x == n - N + M) + fFactor = BinomKoeff(M,x)/BinomKoeff(N,n); + else + { + double fIndex = N - M - n; + if (fIndex >= 0.0) + { + fFactor = BinomKoeff(N-M,n)/BinomKoeff(N,n); + for (double i = 0; i < x; i++) + fFactor *= (M-i)*(n-i)/((i+1.0)*(N-M-n+i+1.0)); + } + else + { + fFactor = BinomKoeff(M,-fIndex)/BinomKoeff(N,n); + for (double i = -fIndex + 1.0; i < x; i++) + fFactor *= (M-i)*(n-i)/((i+1)*(N-M-n+i+1.0)); + } + } +*/ + PushDouble(fFactor); + } +} + +void ScInterpreter::ScGammaDist() +{ + if ( !MustHaveParamCount( GetByte(), 4 ) ) + return; + double kum = GetDouble(); // 0 oder 1 + double beta = GetDouble(); + double alpha = GetDouble(); + double x = GetDouble(); // x + if (x < 0.0 || alpha <= 0.0 || beta <= 0.0) + SetIllegalArgument(); + else if (kum == 0.0) // Dichte + { + double G = GetGamma(alpha); + PushDouble(pow(x,alpha-1.0)/exp(x/beta)/pow(beta,alpha)/G); + } + else // Verteilung + PushDouble(GetGammaDist(x, alpha, beta)); +} + +void ScInterpreter::ScNormInv() +{ + if ( MustHaveParamCount( GetByte(), 3 ) ) + { + double sigma = GetDouble(); + double mue = GetDouble(); + double x = GetDouble(); + if (sigma <= 0.0 || x < 0.0 || x > 1.0) + SetIllegalArgument(); + else if (x == 0.0 || x == 1.0) + SetNoValue(); + else + PushDouble(gaussinv(x)*sigma + mue); + } +} + +void ScInterpreter::ScSNormInv() +{ + double x = GetDouble(); + if (x < 0.0 || x > 1.0) + SetIllegalArgument(); + else if (x == 0.0 || x == 1.0) + SetNoValue(); + else + PushDouble(gaussinv(x)); +} + +void ScInterpreter::ScLogNormInv() +{ + if ( MustHaveParamCount( GetByte(), 3 ) ) + { + double sigma = GetDouble(); // Stdabw + double mue = GetDouble(); // Mittelwert + double y = GetDouble(); // y + if (sigma <= 0.0 || y <= 0.0 || y >= 1.0) + SetIllegalArgument(); + else + PushDouble(exp(mue+sigma*gaussinv(y))); + } +} + +class ScGammaDistFunction : public ScDistFunc +{ + ScInterpreter& rInt; + double fp, fAlpha, fBeta; + +public: + ScGammaDistFunction( ScInterpreter& rI, double fpVal, double fAlphaVal, double fBetaVal ) : + rInt(rI), fp(fpVal), fAlpha(fAlphaVal), fBeta(fBetaVal) {} + + double GetValue( double x ) const { return fp - rInt.GetGammaDist(x, fAlpha, fBeta); } +}; + +void ScInterpreter::ScGammaInv() +{ + if ( !MustHaveParamCount( GetByte(), 3 ) ) + return; + double fBeta = GetDouble(); + double fAlpha = GetDouble(); + double fP = GetDouble(); + if (fAlpha <= 0.0 || fBeta <= 0.0 || fP < 0.0 || fP >= 1.0 ) + { + SetIllegalArgument(); + return; + } + if (fP == 0.0) + PushInt(0); + else + { + BOOL bConvError; + ScGammaDistFunction aFunc( *this, fP, fAlpha, fBeta ); + double fStart = fAlpha * fBeta; + double fVal = lcl_IterateInverse( aFunc, fStart*0.5, fStart, bConvError ); + if (bConvError) + SetError(errNoConvergence); + PushDouble(fVal); + } +} + +class ScBetaDistFunction : public ScDistFunc +{ + ScInterpreter& rInt; + double fp, fAlpha, fBeta; + +public: + ScBetaDistFunction( ScInterpreter& rI, double fpVal, double fAlphaVal, double fBetaVal ) : + rInt(rI), fp(fpVal), fAlpha(fAlphaVal), fBeta(fBetaVal) {} + + double GetValue( double x ) const { return fp - rInt.GetBetaDist(x, fAlpha, fBeta); } +}; + +void ScInterpreter::ScBetaInv() +{ + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 3, 5 ) ) + return; + double fP, fA, fB, fAlpha, fBeta; + if (nParamCount == 5) + fB = GetDouble(); + else + fB = 1.0; + if (nParamCount >= 4) + fA = GetDouble(); + else + fA = 0.0; + fBeta = GetDouble(); + fAlpha = GetDouble(); + fP = GetDouble(); + if (fP < 0.0 || fP >= 1.0 || fA == fB || fAlpha <= 0.0 || fBeta <= 0.0) + { + SetIllegalArgument(); + return; + } + if (fP == 0.0) + PushInt(0); + else + { + BOOL bConvError; + ScBetaDistFunction aFunc( *this, fP, fAlpha, fBeta ); + // 0..1 as range for iteration so it isn't extended beyond the valid range + double fVal = lcl_IterateInverse( aFunc, 0.0, 1.0, bConvError ); + if (bConvError) + { + SetError(errNoConvergence); + PushInt(0); + } + else + PushDouble(fA + fVal*(fB-fA)); // scale to (A,B) + } +} + + // Achtung: T, F und Chi + // sind monoton fallend, + // deshalb 1-Dist als Funktion + +class ScTDistFunction : public ScDistFunc +{ + ScInterpreter& rInt; + double fp, fDF; + +public: + ScTDistFunction( ScInterpreter& rI, double fpVal, double fDFVal ) : + rInt(rI), fp(fpVal), fDF(fDFVal) {} + + double GetValue( double x ) const { return fp - 2 * rInt.GetTDist(x, fDF); } +}; + +void ScInterpreter::ScTInv() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + double fDF = ::rtl::math::approxFloor(GetDouble()); + double fP = GetDouble(); + if (fDF < 1.0 || fDF >= 1.0E5 || fP <= 0.0 || fP > 1.0 ) + { + SetIllegalArgument(); + return; + } + + BOOL bConvError; + ScTDistFunction aFunc( *this, fP, fDF ); + double fVal = lcl_IterateInverse( aFunc, fDF*0.5, fDF, bConvError ); + if (bConvError) + SetError(errNoConvergence); + PushDouble(fVal); +} + +class ScFDistFunction : public ScDistFunc +{ + ScInterpreter& rInt; + double fp, fF1, fF2; + +public: + ScFDistFunction( ScInterpreter& rI, double fpVal, double fF1Val, double fF2Val ) : + rInt(rI), fp(fpVal), fF1(fF1Val), fF2(fF2Val) {} + + double GetValue( double x ) const { return fp - rInt.GetFDist(x, fF1, fF2); } +}; + +void ScInterpreter::ScFInv() +{ + if ( !MustHaveParamCount( GetByte(), 3 ) ) + return; + double fF2 = ::rtl::math::approxFloor(GetDouble()); + double fF1 = ::rtl::math::approxFloor(GetDouble()); + double fP = GetDouble(); + if (fP <= 0.0 || fF1 < 1.0 || fF2 < 1.0 || fF1 >= 1.0E10 || fF2 >= 1.0E10 || fP > 1.0) + { + SetIllegalArgument(); + return; + } + + BOOL bConvError; + ScFDistFunction aFunc( *this, fP, fF1, fF2 ); + double fVal = lcl_IterateInverse( aFunc, fF1*0.5, fF1, bConvError ); + if (bConvError) + SetError(errNoConvergence); + PushDouble(fVal); +} + +class ScChiDistFunction : public ScDistFunc +{ + ScInterpreter& rInt; + double fp, fDF; + +public: + ScChiDistFunction( ScInterpreter& rI, double fpVal, double fDFVal ) : + rInt(rI), fp(fpVal), fDF(fDFVal) {} + + double GetValue( double x ) const { return fp - rInt.GetChiDist(x, fDF); } +}; + +void ScInterpreter::ScChiInv() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + double fDF = ::rtl::math::approxFloor(GetDouble()); + double fP = GetDouble(); + if (fDF < 1.0 || fDF >= 1.0E5 || fP <= 0.0 || fP > 1.0 ) + { + SetIllegalArgument(); + return; + } + + BOOL bConvError; + ScChiDistFunction aFunc( *this, fP, fDF ); + double fVal = lcl_IterateInverse( aFunc, fDF*0.5, fDF, bConvError ); + if (bConvError) + SetError(errNoConvergence); + PushDouble(fVal); +} + +/***********************************************/ + +void ScInterpreter::ScConfidence() +{ + if ( MustHaveParamCount( GetByte(), 3 ) ) + { + double n = ::rtl::math::approxFloor(GetDouble()); + double sigma = GetDouble(); + double alpha = GetDouble(); + if (sigma <= 0.0 || alpha <= 0.0 || alpha >= 1.0 || n < 1.0) + SetIllegalArgument(); + else + PushDouble( gaussinv(1.0-alpha/2.0) * sigma/sqrt(n) ); + } +} + +void ScInterpreter::ScZTest() +{ + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 2, 3 ) ) + return; + double sigma, mue, x; + if (nParamCount == 3) + { + sigma = GetDouble(); + if (sigma <= 0.0) + { + SetIllegalArgument(); + return; + } + } + x = GetDouble(); + + double fSum = 0.0; + double fSumSqr = 0.0; + double fVal; + double rValCount = 0.0; + switch (GetStackType()) + { + case svDouble : + { + fVal = GetDouble(); + fSum += fVal; + fSumSqr += fVal*fVal; + rValCount++; + } + break; + case svSingleRef : + { + ScAddress aAdr; + PopSingleRef( aAdr ); + ScBaseCell* pCell = GetCell( aAdr ); + if (HasCellValueData(pCell)) + { + fVal = GetCellValue( aAdr, pCell ); + fSum += fVal; + fSumSqr += fVal*fVal; + rValCount++; + } + } + break; + case svDoubleRef : + { + ScRange aRange; + USHORT nErr = 0; + PopDoubleRef( aRange ); + ScValueIterator aValIter(pDok, aRange, glSubTotal); + if (aValIter.GetFirst(fVal, nErr)) + { + fSum += fVal; + fSumSqr += fVal*fVal; + rValCount++; + while ((nErr == 0) && aValIter.GetNext(fVal, nErr)) + { + fSum += fVal; + fSumSqr += fVal*fVal; + rValCount++; + } + SetError(nErr); + } + } + break; + case svMatrix : + { + ScMatrix* pMat = PopMatrix(); + if (pMat) + { + ULONG nCount = pMat->GetElementCount(); + if (pMat->IsNumeric()) + { + for ( ULONG i = 0; i < nCount; i++ ) + { + fVal= pMat->GetDouble(i); + fSum += fVal; + fSumSqr += fVal * fVal; + rValCount++; + } + } + else + { + for (ULONG i = 0; i < nCount; i++) + if (!pMat->IsString(i)) + { + fVal= pMat->GetDouble(i); + fSum += fVal; + fSumSqr += fVal * fVal; + rValCount++; + } + } + } + } + break; + default : SetError(errIllegalParameter); break; + } + if (rValCount <= 1.0) + SetNoValue(); + else + { + mue = fSum/rValCount; + if (nParamCount != 3) + sigma = (fSumSqr - fSum*fSum/rValCount)/(rValCount-1.0); + + PushDouble(0.5 - gauss((mue-x)/sqrt(sigma/rValCount))); + } +} + +void ScInterpreter::ScTTest() +{ + if ( !MustHaveParamCount( GetByte(), 4 ) ) + return; + double fTyp = ::rtl::math::approxFloor(GetDouble()); + double fAnz = ::rtl::math::approxFloor(GetDouble()); + if (fAnz != 1.0 && fAnz != 2.0) + { + SetIllegalArgument(); + return; + } + + USHORT nMatInd1, nMatInd2; + ScMatrix* pMat2 = GetMatrix(nMatInd2); + ScMatrix* pMat1 = GetMatrix(nMatInd1); + if (!pMat1 || !pMat2) + { + SetIllegalParameter(); + return; + } + double fT, fF; + USHORT nC1, nR1, nC2, nR2, i, j; + pMat1->GetDimensions(nC1, nR1); + pMat2->GetDimensions(nC2, nR2); + if (fTyp == 1.0) + { + if (nC1 != nC2 || nR1 != nR2) + { + SetIllegalParameter(); + return; + } + double fCount = 0.0; + double fSum1 = 0.0; + double fSum2 = 0.0; + double fSumSqrD = 0.0; + double fVal1, fVal2; + for (i = 0; i < nC1; i++) + for (j = 0; j < nR1; j++) + { + if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j)) + { + fVal1 = pMat1->GetDouble(i,j); + fVal2 = pMat2->GetDouble(i,j); + fSum1 += fVal1; + fSum2 += fVal2; + fSumSqrD += (fVal1 - fVal2)*(fVal1 - fVal2); + fCount++; + } + } + if (fCount < 1.0) + { + SetNoValue(); + return; + } + fT = sqrt(fCount-1.0) * fabs(fSum1 - fSum2) / + sqrt(fCount * fSumSqrD - (fSum1-fSum2)*(fSum1-fSum2)); + fF = fCount - 1.0; + } + else if (fTyp == 2.0) + { + double fCount1 = 0.0; + double fCount2 = 0.0; + double fSum1 = 0.0; + double fSumSqr1 = 0.0; + double fSum2 = 0.0; + double fSumSqr2 = 0.0; + double fVal; + for (i = 0; i < nC1; i++) + for (j = 0; j < nR1; j++) + { + if (!pMat1->IsString(i,j)) + { + fVal = pMat1->GetDouble(i,j); + fSum1 += fVal; + fSumSqr1 += fVal * fVal; + fCount1++; + } + } + for (i = 0; i < nC2; i++) + for (j = 0; j < nR2; j++) + { + if (!pMat2->IsString(i,j)) + { + fVal = pMat2->GetDouble(i,j); + fSum2 += fVal; + fSumSqr2 += fVal * fVal; + fCount2++; + } + } + if (fCount1 < 2.0 || fCount2 < 2.0) + { + SetNoValue(); + return; + } +#if 0 + // alter Templin-Code + double fS1 = (fSumSqr1-fSum1*fSum1/fCount1)/(fCount1-1.0)/fCount1; + double fS2 = (fSumSqr2-fSum2*fSum2/fCount2)/(fCount2-1.0)/fCount2; + if (fS1 + fS2 == 0.0) + { + SetNoValue(); + return; + } + fT = fabs(fSum1/fCount1 - fSum2/fCount2)/sqrt(fS1+fS2); + fF = fCount1 + fCount2 - 2; +#else + // laut Bronstein-Semendjajew + double fS1 = (fSumSqr1 - fSum1*fSum1/fCount1) / (fCount1 - 1.0); // Varianz + double fS2 = (fSumSqr2 - fSum2*fSum2/fCount2) / (fCount2 - 1.0); + fT = fabs( fSum1/fCount1 - fSum2/fCount2 ) / + sqrt( (fCount1-1.0)*fS1 + (fCount2-1.0)*fS2 ) * + sqrt( fCount1*fCount2*(fCount1+fCount2-2)/(fCount1+fCount2) ); + fF = fCount1 + fCount2 - 2; +#endif + } + else if (fTyp == 3.0) + { + double fCount1 = 0.0; + double fCount2 = 0.0; + double fSum1 = 0.0; + double fSumSqr1 = 0.0; + double fSum2 = 0.0; + double fSumSqr2 = 0.0; + double fVal; + for (i = 0; i < nC1; i++) + for (j = 0; j < nR1; j++) + { + if (!pMat1->IsString(i,j)) + { + fVal = pMat1->GetDouble(i,j); + fSum1 += fVal; + fSumSqr1 += fVal * fVal; + fCount1++; + } + } + for (i = 0; i < nC2; i++) + for (j = 0; j < nR2; j++) + { + if (!pMat2->IsString(i,j)) + { + fVal = pMat2->GetDouble(i,j); + fSum2 += fVal; + fSumSqr2 += fVal * fVal; + fCount2++; + } + } + if (fCount1 < 2.0 || fCount2 < 2.0) + { + SetNoValue(); + return; + } + double fS1 = (fSumSqr1-fSum1*fSum1/fCount1)/(fCount1-1.0)/fCount1; + double fS2 = (fSumSqr2-fSum2*fSum2/fCount2)/(fCount2-1.0)/fCount2; + if (fS1 + fS2 == 0.0) + { + SetNoValue(); + return; + } + fT = fabs(fSum1/fCount1 - fSum2/fCount2)/sqrt(fS1+fS2); + double c = fS1/(fS1+fS2); +// s.u. fF = ::rtl::math::approxFloor(1.0/(c*c/(fCount1-1.0)+(1.0-c)*(1.0-c)/(fCount2-1.0))); +// fF = ::rtl::math::approxFloor((fS1+fS2)*(fS1+fS2)/(fS1*fS1/(fCount1-1.0) + fS2*fS2/(fCount2-1.0))); + + // GetTDist wird mit GetBetaDist berechnet und kommt auch mit nicht ganzzahligen + // Freiheitsgraden klar. Dann stimmt das Ergebnis auch mit Excel ueberein (#52406#): + fF = 1.0/(c*c/(fCount1-1.0)+(1.0-c)*(1.0-c)/(fCount2-1.0)); + } + + else + { + SetIllegalArgument(); + return; + } + if (fAnz == 1.0) + PushDouble(GetTDist(fT, fF)); + else + PushDouble(2.0*GetTDist(fT, fF)); +} + +void ScInterpreter::ScFTest() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + USHORT nMatInd1, nMatInd2; + ScMatrix* pMat2 = GetMatrix(nMatInd2); + ScMatrix* pMat1 = GetMatrix(nMatInd1); + if (!pMat1 || !pMat2) + { + SetIllegalParameter(); + return; + } + USHORT nC1, nR1, nC2, nR2, i, j; + pMat1->GetDimensions(nC1, nR1); + pMat2->GetDimensions(nC2, nR2); + double fCount1 = 0.0; + double fCount2 = 0.0; + double fSum1 = 0.0; + double fSumSqr1 = 0.0; + double fSum2 = 0.0; + double fSumSqr2 = 0.0; + double fVal; + for (i = 0; i < nC1; i++) + for (j = 0; j < nR1; j++) + { + if (!pMat1->IsString(i,j)) + { + fVal = pMat1->GetDouble(i,j); + fSum1 += fVal; + fSumSqr1 += fVal * fVal; + fCount1++; + } + } + for (i = 0; i < nC2; i++) + for (j = 0; j < nR2; j++) + { + if (!pMat2->IsString(i,j)) + { + fVal = pMat2->GetDouble(i,j); + fSum2 += fVal; + fSumSqr2 += fVal * fVal; + fCount2++; + } + } + if (fCount1 < 2.0 || fCount2 < 2.0) + { + SetNoValue(); + return; + } + double fS1 = (fSumSqr1-fSum1*fSum1/fCount1)/(fCount1-1.0); + double fS2 = (fSumSqr2-fSum2*fSum2/fCount2)/(fCount2-1.0); + if (fS1 == 0.0 || fS2 == 0.0) + { + SetNoValue(); + return; + } + double fF, fF1, fF2; + if (fS1 > fS2) + { + fF = fS1/fS2; + fF1 = fCount1-1.0; + fF2 = fCount2-1.0; + } + else + { + fF = fS2/fS1; + fF1 = fCount2-1.0; + fF2 = fCount1-1.0; + } + PushDouble(2.0*GetFDist(fF, fF1, fF2)); +/* + double Z = (pow(fF,1.0/3.0)*(1.0-2.0/(9.0*fF2)) - (1.0-2.0/(9.0*fF1))) / + sqrt(2.0/(9.0*fF1) + pow(fF,2.0/3.0)*2.0/(9.0*fF2)); + PushDouble(1.0-2.0*gauss(Z)); +*/ +} + +void ScInterpreter::ScChiTest() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + USHORT nMatInd1, nMatInd2; + ScMatrix* pMat2 = GetMatrix(nMatInd2); + ScMatrix* pMat1 = GetMatrix(nMatInd1); + if (!pMat1 || !pMat2) + { + SetIllegalParameter(); + return; + } + USHORT nC1, nR1, nC2, nR2; + pMat1->GetDimensions(nC1, nR1); + pMat2->GetDimensions(nC2, nR2); + if (nR1 != nR2 || nC1 != nC2) + { + SetIllegalParameter(); + return; + } + double fChi = 0.0; + USHORT i, j; + double fValX, fValE; + for (i = 0; i < nC1; i++) + for (j = 0; j < nR1; j++) + { + if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j)) + { + fValX = pMat1->GetDouble(i,j); + fValE = pMat2->GetDouble(i,j); + fChi += (fValX-fValE)*(fValX-fValE)/fValE; + } + else + { + SetIllegalArgument(); + return; + } + } + double fDF; + if (nC1 == 1 || nR1 == 1) + { + fDF = (double)(nC1*nR1 - 1); + if (fDF == 0.0) + { + SetNoValue(); + return; + } + } + else + fDF = (double)(nC1-1)*(double)(nR1-1); + PushDouble(GetChiDist(fChi, fDF)); +/* + double fX, fS, fT, fG; + fX = 1.0; + for (double fi = fDF; fi >= 2.0; fi -= 2.0) + fX *= fChi/fi; + fX *= exp(-fChi/2.0); + if (fmod(fDF, 2.0) != 0.0) + fX *= sqrt(2.0*fChi/F_PI); + fS = 1.0; + fT = 1.0; + fG = fDF; + while (fT >= 1.0E-7) + { + fG += 2.0; + fT *= fChi/fG; + fS += fT; + } + PushDouble(1.0 - fX*fS); +*/ +} + +void ScInterpreter::ScKurt() +{ + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCountMin( nParamCount, 1 ) ) + return; + USHORT SaveSP = sp; + USHORT i; + double fSum = 0.0; + double fSumSqr = 0.0; + double fCount = 0.0; + double fVal; + ScAddress aAdr; + ScRange aRange; + for (i = 0; i < nParamCount; i++) + { + switch (GetStackType()) + { + case svDouble : + { + fVal = GetDouble(); + fSum += fVal; + fSumSqr += fVal*fVal; + fCount++; + } + break; + case svSingleRef : + { + PopSingleRef( aAdr ); + ScBaseCell* pCell = GetCell( aAdr ); + if (HasCellValueData(pCell)) + { + fVal = GetCellValue( aAdr, pCell ); + fSum += fVal; + fSumSqr += fVal*fVal; + fCount++; + } + } + break; + case svDoubleRef : + { + PopDoubleRef( aRange ); + USHORT nErr = 0; + ScValueIterator aValIter(pDok, aRange); + if (aValIter.GetFirst(fVal, nErr)) + { + fSum += fVal; + fSumSqr += fVal*fVal; + fCount++; + SetError(nErr); + while ((nErr == 0) && aValIter.GetNext(fVal, nErr)) + { + fSum += fVal; + fSumSqr += fVal*fVal; + fCount++; + } + SetError(nErr); + } + } + break; + case svMatrix : + { + ScMatrix* pMat = PopMatrix(); + if (pMat) + { + ULONG nCount = pMat->GetElementCount(); + if (pMat->IsNumeric()) + { + for (ULONG i = 0; i < nCount; i++) + { + fVal = pMat->GetDouble(i); + fSum += fVal; + fSumSqr += fVal*fVal; + fCount++; + } + } + else + { + for (ULONG i = 0; i < nCount; i++) + if (!pMat->IsString(i)) + { + fVal = pMat->GetDouble(i); + fSum += fVal; + fSumSqr += fVal*fVal; + fCount++; + } + } + } + } + break; + default : + SetError(errIllegalParameter); + break; + } + } + if (nGlobalError) + { + PushInt(0); + return; + } + double fMean = fSum / fCount; + double fSSqr = (fSumSqr - fSum*fSum/fCount)/(fCount-1.0); + sp = SaveSP; + fSum = 0.0; + // #55733# GCC Optimierungsfehler, GPF wenn die 4.0 als Konstante an pow() + // uebergeben wird, auch ein "const double fPow = 4.0;" GPF't, + double fPow = 4.0; + for (i = 0; i < nParamCount; i++) + { + switch (GetStackType()) + { + case svDouble : + fSum += pow(GetDouble()-fMean,fPow); + break; + case svSingleRef : + { + PopSingleRef( aAdr ); + ScBaseCell* pCell = GetCell( aAdr ); + if (HasCellValueData(pCell)) + fSum += pow(GetCellValue( aAdr, pCell ) - fMean, fPow); + } + break; + case svDoubleRef : + { + PopDoubleRef( aRange ); + USHORT nErr = 0; + ScValueIterator aValIter(pDok, aRange); + if (aValIter.GetFirst(fVal, nErr)) + { + fSum += pow(fVal - fMean, fPow); + while (aValIter.GetNext(fVal, nErr)) + fSum += pow(fVal - fMean, fPow); + } + } + break; + case svMatrix : + { + ScMatrix* pMat = PopMatrix(); + if (pMat) + { + ULONG nCount = pMat->GetElementCount(); + if (pMat->IsNumeric()) + { + for (ULONG i = 0; i < nCount; i++) + fSum += pow(pMat->GetDouble(i) - fMean, fPow); + } + else + { + for (ULONG i = 0; i < nCount; i++) + if (!pMat->IsString(i)) + fSum += pow(pMat->GetDouble(i) - fMean, fPow); + } + } + } + break; + default : SetError(errIllegalParameter); break; + } + } + PushDouble(fCount*(fCount+1.0)/((fCount-1.0)*(fCount-2.0)*(fCount-3.0)) + *fSum/(fSSqr*fSSqr) + - 3.0*(fCount-1.0)*(fCount-1.0)/((fCount-2.0)*(fCount-3.0))); +} + +void ScInterpreter::ScHarMean() +{ + BYTE nParamCount = GetByte(); + double nVal = 0.0; + ULONG nCount = 0; + ScAddress aAdr; + ScRange aRange; + for (short i = 0; i < nParamCount && (nGlobalError == 0); i++) + { + switch (GetStackType()) + { + case svDouble : + { + double x = GetDouble(); + if (x > 0.0) + { + nVal += 1.0/x; + nCount++; + } + else + SetIllegalArgument(); + break; + } + case svSingleRef : + { + PopSingleRef( aAdr ); + ScBaseCell* pCell = GetCell( aAdr ); + if (HasCellValueData(pCell)) + { + double x = GetCellValue( aAdr, pCell ); + if (x > 0.0) + { + nVal += 1.0/x; + nCount++; + } + else + SetIllegalArgument(); + } + break; + } + case svDoubleRef : + { + USHORT nErr = 0; + PopDoubleRef( aRange ); + double nCellVal; + ScValueIterator aValIter(pDok, aRange, glSubTotal); + if (aValIter.GetFirst(nCellVal, nErr)) + { + if (nCellVal > 0.0) + { + nVal += 1.0/nCellVal; + nCount++; + } + else + SetIllegalArgument(); + SetError(nErr); + while ((nErr == 0) && aValIter.GetNext(nCellVal, nErr)) + { + if (nCellVal > 0.0) + { + nVal += 1.0/nCellVal; + nCount++; + } + else + SetIllegalArgument(); + } + SetError(nErr); + } + } + break; + case svMatrix : + { + ScMatrix* pMat = PopMatrix(); + if (pMat) + { + ULONG nCount = pMat->GetElementCount(); + if (pMat->IsNumeric()) + { + for (ULONG i = 0; i < nCount; i++) + { + double x = pMat->GetDouble(i); + if (x > 0.0) + { + nVal += 1.0/x; + nCount++; + } + else + SetIllegalArgument(); + } + } + else + { + for (ULONG i = 0; i < nCount; i++) + if (!pMat->IsString(i)) + { + double x = pMat->GetDouble(i); + if (x > 0.0) + { + nVal += 1.0/x; + nCount++; + } + else + SetIllegalArgument(); + } + } + } + } + break; + default : SetError(errIllegalParameter); break; + } + } + if (nGlobalError == 0) + PushDouble((double)nCount/nVal); +} + +void ScInterpreter::ScGeoMean() +{ + BYTE nParamCount = GetByte(); + double nVal = 0.0; + ULONG nCount = 0; + ScAddress aAdr; + ScRange aRange; + for (short i = 0; i < nParamCount && (nGlobalError == 0); i++) + { + switch (GetStackType()) + { + case svDouble : + { + double x = GetDouble(); + if (x > 0.0) + { + nVal += log(x); + nCount++; + } + else + SetIllegalArgument(); + break; + } + case svSingleRef : + { + PopSingleRef( aAdr ); + ScBaseCell* pCell = GetCell( aAdr ); + if (HasCellValueData(pCell)) + { + double x = GetCellValue( aAdr, pCell ); + if (x > 0.0) + { + nVal += log(x); + nCount++; + } + else + SetIllegalArgument(); + } + break; + } + case svDoubleRef : + { + USHORT nErr = 0; + PopDoubleRef( aRange ); + double nCellVal; + ScValueIterator aValIter(pDok, aRange, glSubTotal); + if (aValIter.GetFirst(nCellVal, nErr)) + { + if (nCellVal > 0.0) + { + nVal += log(nCellVal); + nCount++; + } + else + SetIllegalArgument(); + SetError(nErr); + while ((nErr == 0) && aValIter.GetNext(nCellVal, nErr)) + { + if (nCellVal > 0.0) + { + nVal += log(nCellVal); + nCount++; + } + else + SetIllegalArgument(); + } + SetError(nErr); + } + } + break; + case svMatrix : + { + ScMatrix* pMat = PopMatrix(); + if (pMat) + { + ULONG nCount = pMat->GetElementCount(); + if (pMat->IsNumeric()) + { + for (ULONG i = 0; i < nCount; i++) + { + double x = pMat->GetDouble(i); + if (x > 0.0) + { + nVal += log(x); + nCount++; + } + else + SetIllegalArgument(); + } + } + else + { + for (ULONG i = 0; i < nCount; i++) + if (!pMat->IsString(i)) + { + double x = pMat->GetDouble(i); + if (x > 0.0) + { + nVal += log(x); + nCount++; + } + else + SetIllegalArgument(); + } + } + } + } + break; + default : SetError(errIllegalParameter); break; + } + } + if (nGlobalError == 0) + PushDouble(exp(nVal/(double)nCount)); +} + +void ScInterpreter::ScStandard() +{ + if ( MustHaveParamCount( GetByte(), 3 ) ) + { + double sigma = GetDouble(); + double mue = GetDouble(); + double x = GetDouble(); + if (sigma <= 0.0) + SetIllegalArgument(); + else + PushDouble((x-mue)/sigma); + } +} + +void ScInterpreter::ScSkew() +{ + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCountMin( nParamCount, 1 ) ) + return; + USHORT SaveSP = sp; + USHORT i; + double fSum = 0.0; + double fSumSqr = 0.0; + double fCount = 0.0; + double fVal; + ScAddress aAdr; + ScRange aRange; + for (i = 0; i < nParamCount; i++) + { + switch (GetStackType()) + { + case svDouble : + { + fVal = GetDouble(); + fSum += fVal; + fSumSqr += fVal*fVal; + fCount++; + } + break; + case svSingleRef : + { + PopSingleRef( aAdr ); + ScBaseCell* pCell = GetCell( aAdr ); + if (HasCellValueData(pCell)) + { + fVal = GetCellValue( aAdr, pCell ); + fSum += fVal; + fSumSqr += fVal*fVal; + fCount++; + } + } + break; + case svDoubleRef : + { + PopDoubleRef( aRange ); + USHORT nErr = 0; + ScValueIterator aValIter(pDok, aRange); + if (aValIter.GetFirst(fVal, nErr)) + { + fSum += fVal; + fSumSqr += fVal*fVal; + fCount++; + SetError(nErr); + while ((nErr == 0) && aValIter.GetNext(fVal, nErr)) + { + fSum += fVal; + fSumSqr += fVal*fVal; + fCount++; + } + SetError(nErr); + } + } + break; + case svMatrix : + { + ScMatrix* pMat = PopMatrix(); + if (pMat) + { + ULONG nCount = pMat->GetElementCount(); + if (pMat->IsNumeric()) + { + for (ULONG i = 0; i < nCount; i++) + { + fVal = pMat->GetDouble(i); + fSum += fVal; + fSumSqr += fVal*fVal; + fCount++; + } + } + else + { + for (ULONG i = 0; i < nCount; i++) + if (!pMat->IsString(i)) + { + fVal = pMat->GetDouble(i); + fSum += fVal; + fSumSqr += fVal*fVal; + fCount++; + } + } + } + } + break; + default : + SetError(errIllegalParameter); + break; + } + } + if (nGlobalError) + { + PushInt(0); + return; + } + double fMean = fSum / fCount; + double fSSqr = (fSumSqr - fSum*fSum/fCount)/(fCount-1.0); + sp = SaveSP; + fSum = 0.0; + double fPow = 3.0; // vorsichtshalber wg. #55733#, siehe ScKurt() + for (i = 0; i < nParamCount; i++) + { + switch (GetStackType()) + { + case svDouble : + fSum += pow(GetDouble()-fMean,fPow); + break; + case svSingleRef : + { + PopSingleRef( aAdr ); + ScBaseCell* pCell = GetCell( aAdr ); + if (HasCellValueData(pCell)) + fSum += pow(GetCellValue( aAdr, pCell ) - fMean, fPow); + } + break; + case svDoubleRef : + { + PopDoubleRef( aRange ); + USHORT nErr = 0; + ScValueIterator aValIter(pDok, aRange); + if (aValIter.GetFirst(fVal, nErr)) + { + fSum += pow(fVal - fMean, fPow); + while (aValIter.GetNext(fVal, nErr)) + fSum += pow(fVal - fMean, fPow); + } + } + break; + case svMatrix : + { + ScMatrix* pMat = PopMatrix(); + if (pMat) + { + ULONG nCount = pMat->GetElementCount(); + if (pMat->IsNumeric()) + { + for (ULONG i = 0; i < nCount; i++) + fSum += pow(pMat->GetDouble(i) - fMean, fPow); + } + else + { + for (ULONG i = 0; i < nCount; i++) + if (!pMat->IsString(i)) + fSum += pow(pMat->GetDouble(i) - fMean, fPow); + } + } + } + break; + default : SetError(errIllegalParameter); break; + } + } + PushDouble(fCount/((fCount-1.0)*(fCount-2.0))*fSum/(fSSqr*sqrt(fSSqr))); +} + +void ScInterpreter::ScMedian() +{ + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCountMin( nParamCount, 1 ) ) + return; + double* pSortArray = NULL; + ULONG nSize = 0; + GetSortArray(nParamCount, &pSortArray, nSize); + if (!pSortArray || nSize == 0 || nGlobalError) + SetNoValue(); + else + { +#ifdef WIN + double huge* pSArray = (double huge*) pSortArray; +#else + double* pSArray = pSortArray; +#endif + if (nSize % 2 == 0) + PushDouble((pSArray[nSize/2-1]+pSArray[nSize/2])/2.0); + else + PushDouble(pSArray[(nSize-1)/2]); + } + if (pSortArray) + { +#ifdef WIN + SvMemFree(pSortArray); +#else + delete [] pSortArray; +#endif + } + +} + +void ScInterpreter::ScPercentile() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + double alpha = GetDouble(); + if (alpha < 0.0 || alpha > 1.0) + { + SetIllegalArgument(); + return; + } + double* pSortArray = NULL; + ULONG nSize = 0; + GetSortArray(1, &pSortArray, nSize); + if (!pSortArray || nSize == 0 || nGlobalError) + SetNoValue(); + else + { +#ifdef WIN + double huge* pSArray = (double huge*) pSortArray; +#else + double* pSArray = pSortArray; +#endif + if (nSize == 1) + PushDouble(pSArray[0]); + else + { + ULONG nIndex = (ULONG)::rtl::math::approxFloor(alpha*(nSize-1)); + double fDiff = alpha*(nSize-1) - ::rtl::math::approxFloor(alpha*(nSize-1)); + DBG_ASSERT(nIndex >= 0 && nIndex < nSize, "ScPercentile: falscher Index (1)"); + if (fDiff == 0.0) + PushDouble(pSArray[nIndex]); + else + { + DBG_ASSERT(nIndex < nSize-1, "ScPercentile: falscher Index(2)"); + PushDouble(pSArray[nIndex] + + fDiff*(pSArray[nIndex+1]-pSArray[nIndex])); + } + } + } + if (pSortArray) + { +#ifdef WIN + SvMemFree(pSortArray); +#else + delete [] pSortArray; +#endif + } +} + +void ScInterpreter::ScQuartile() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + double fFlag = ::rtl::math::approxFloor(GetDouble()); + if (fFlag < 0.0 || fFlag > 4.0) + { + SetIllegalArgument(); + return; + } + double* pSortArray = NULL; + ULONG nSize = 0; + GetSortArray(1, &pSortArray, nSize); + if (!pSortArray || nSize == 0 || nGlobalError) + SetNoValue(); + else + { +#ifdef WIN + double huge* pSArray = (double huge*) pSortArray; +#else + double* pSArray = pSortArray; +#endif + if (nSize == 1) + PushDouble(pSArray[0]); + else + { + if (fFlag == 0.0) + PushDouble(pSArray[0]); + else if (fFlag == 1.0) + { + ULONG nIndex = (ULONG)::rtl::math::approxFloor(0.25*(nSize-1)); + double fDiff = 0.25*(nSize-1) - ::rtl::math::approxFloor(0.25*(nSize-1)); + DBG_ASSERT(nIndex >= 0 && nIndex < nSize, "ScQuartile: falscher Index (1)"); + if (fDiff == 0.0) + PushDouble(pSArray[nIndex]); + else + { + DBG_ASSERT(nIndex < nSize-1, "ScQuartile: falscher Index(2)"); + PushDouble(pSArray[nIndex] + + fDiff*(pSArray[nIndex+1]-pSArray[nIndex])); + } + } + else if (fFlag == 2.0) + { + if (nSize % 2 == 0) + PushDouble((pSArray[nSize/2-1]+pSArray[nSize/2])/2.0); + else + PushDouble(pSArray[(nSize-1)/2]); + } + else if (fFlag == 3.0) + { + ULONG nIndex = (ULONG)::rtl::math::approxFloor(0.75*(nSize-1)); + double fDiff = 0.75*(nSize-1) - ::rtl::math::approxFloor(0.75*(nSize-1)); + DBG_ASSERT(nIndex >= 0 && nIndex < nSize, "ScQuartile: falscher Index (3)"); + if (fDiff == 0.0) + PushDouble(pSArray[nIndex]); + else + { + DBG_ASSERT(nIndex < nSize-1, "ScQuartile: falscher Index(4)"); + PushDouble(pSArray[nIndex] + + fDiff*(pSArray[nIndex+1]-pSArray[nIndex])); + } + } + else + PushDouble(pSArray[nSize-1]); + } + } + if (pSortArray) + { +#ifdef WIN + SvMemFree(pSortArray); +#else + delete [] pSortArray; +#endif + } +} + +void ScInterpreter::ScModalValue() +{ + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCountMin( nParamCount, 1 ) ) + return; + double* pSortArray = NULL; + ULONG nSize = 0; + GetSortArray(nParamCount, &pSortArray, nSize); + if (!pSortArray || nSize == 0 || nGlobalError) + SetNoValue(); + else + { +#ifdef WIN + double huge* pSArray = (double huge*) pSortArray; +#else + double* pSArray = pSortArray; +#endif + ULONG nMaxIndex, nMax = 1, nCount = 1; + double nOldVal = pSArray[0]; + ULONG i = 0; + for (i = 1; i < nSize; i++) + { + if (pSArray[i] == nOldVal) + nCount++; + else + { + nOldVal = pSArray[i]; + if (nCount > nMax) + { + nMax = nCount; + nMaxIndex = i-1; + } + nCount = 1; + } + } + if (nCount > nMax) + { + nMax = nCount; + nMaxIndex = i-1; + } + if (nMax == 1 && nCount == 1) + SetNoValue(); + else if (nMax == 1) + PushDouble(nOldVal); + else + PushDouble(pSArray[nMaxIndex]); + } + if (pSortArray) + { +#ifdef WIN + SvMemFree(pSortArray); +#else + delete [] pSortArray; +#endif + } +} + +void ScInterpreter::ScLarge() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + double* pSortArray = NULL; + ULONG nSize = 0; + ULONG k = (ULONG) ::rtl::math::approxFloor(GetDouble()); + if (k <= 0) + { + SetIllegalArgument(); + return; + } + GetSortArray(1, &pSortArray, nSize); + if (!pSortArray || nSize == 0 || nGlobalError || nSize < k) + SetNoValue(); + else + { +#ifdef WIN + double huge* pSArray = (double huge*) pSortArray; +#else + double* pSArray = pSortArray; +#endif +/* + ULONG nCount = 1; + double nOldVal = pSArray[nSize-1]; + for (long i = nSize-2; i >= 0 && nCount < k; i--) + { + if (pSArray[i] != nOldVal) + { + nCount++; + nOldVal = pSArray[i]; + } + } + if (nCount < k) + SetNoValue(); + else + PushDouble(nOldVal); +*/ + PushDouble( pSArray[ nSize-k ] ); + } + if (pSortArray) + { +#ifdef WIN + SvMemFree(pSortArray); +#else + delete [] pSortArray; +#endif + } +} + +void ScInterpreter::ScSmall() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + double* pSortArray = NULL; + ULONG nSize = 0; + ULONG k = (ULONG) ::rtl::math::approxFloor(GetDouble()); + if (k <= 0) + { + SetIllegalArgument(); + return; + } + GetSortArray(1, &pSortArray, nSize); + if (!pSortArray || nSize == 0 || nGlobalError || nSize < k) + SetNoValue(); + else + { +#ifdef WIN + double huge* pSArray = (double huge*) pSortArray; +#else + double* pSArray = pSortArray; +#endif +/* + ULONG nCount = 1; + double nOldVal = pSArray[0]; + for (ULONG i = 1; i < nSize && nCount < k; i++) + { + if (pSArray[i] != nOldVal) + { + nCount++; + nOldVal = pSArray[i]; + } + } + if (nCount < k) + SetNoValue(); + else + PushDouble(nOldVal); +*/ + PushDouble( pSArray[ k-1 ] ); + } + if (pSortArray) + { +#ifdef WIN + SvMemFree(pSortArray); +#else + delete [] pSortArray; +#endif + } +} + +void ScInterpreter::ScPercentrank() +{ + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 2 ) ) + return; +/* wird nicht unterstuetzt + double fPrec; + if (nParamCount == 3) + { + fPrec = ::rtl::math::approxFloor(GetDouble()); + if (fPrec < 1.0) + { + SetIllegalArgument(); + return; + } + } + else + fPrec = 3.0; +*/ + double fNum = GetDouble(); + double* pSortArray = NULL; + ULONG nSize = 0; + GetSortArray(1, &pSortArray, nSize); + if (!pSortArray || nSize == 0 || nGlobalError) + SetNoValue(); + else + { +#ifdef WIN + double huge* pSArray = (double huge*) pSortArray; +#else + double* pSArray = pSortArray; +#endif + if (fNum < pSArray[0] || fNum > pSArray[nSize-1]) + SetNoValue(); + else if ( nSize == 1 ) + PushDouble(1.0); // fNum == pSArray[0], see test above + else + { + double fRes; + ULONG nOldCount = 0; + double fOldVal = pSArray[0]; + ULONG i; + for (i = 1; i < nSize && pSArray[i] < fNum; i++) + { + if (pSArray[i] != fOldVal) + { + nOldCount = i; + fOldVal = pSArray[i]; + } + } + if (pSArray[i] != fOldVal) + nOldCount = i; + if (fNum == pSArray[i]) + fRes = (double)nOldCount/(double)(nSize-1); + else + { + // #75312# nOldCount is the count of smaller entries + // fNum is between pSArray[nOldCount-1] and pSArray[nOldCount] + // use linear interpolation to find a position between the entries + + if ( nOldCount == 0 ) + { + DBG_ERROR("should not happen"); + fRes = 0.0; + } + else + { + double fFract = ( fNum - pSArray[nOldCount-1] ) / + ( pSArray[nOldCount] - pSArray[nOldCount-1] ); + fRes = ( (double)(nOldCount-1)+fFract )/(double)(nSize-1); + } + } + PushDouble(fRes); + } + } + if (pSortArray) + { +#ifdef WIN + SvMemFree(pSortArray); +#else + delete [] pSortArray; +#endif + } +} + +void ScInterpreter::ScTrimMean() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + double alpha = GetDouble(); + if (alpha < 0.0 || alpha >= 1.0) + { + SetIllegalArgument(); + return; + } + double* pSortArray = NULL; + ULONG nSize = 0; + GetSortArray(1, &pSortArray, nSize); + if (!pSortArray || nSize == 0 || nGlobalError) + SetNoValue(); + else + { + ppGlobSortArray = &pSortArray; +#ifdef WIN + double huge* pSArray = (double huge*) pSortArray; +#else + double* pSArray = pSortArray; +#endif + ULONG nIndex = (ULONG) ::rtl::math::approxFloor(alpha*(double)nSize); + if (nIndex % 2 != 0) + nIndex--; + nIndex /= 2; + DBG_ASSERT(nIndex >= 0 && nIndex < nSize, "ScTrimMean: falscher Index"); + double fSum = 0.0; + for (ULONG i = nIndex; i < nSize-nIndex; i++) + fSum += pSArray[i]; + PushDouble(fSum/(double)(nSize-2*nIndex)); + } + if (pSortArray) + { +#ifdef WIN + SvMemFree(pSortArray); +#else + delete [] pSortArray; +#endif + ppGlobSortArray = NULL; + } +} + +void ScInterpreter::GetSortArray(BYTE nParamCount, double** ppSortArray, ULONG& nSize) +{ + *ppSortArray = NULL; + nSize = 0; + + USHORT SaveSP = sp; + USHORT i; + ULONG rValCount = 0; + ScAddress aAdr; + ScRange aRange; + for (i = 0; i < nParamCount; i++) + { + switch (GetStackType()) + { + case svDouble : + PopDouble(); + rValCount++; + break; + case svSingleRef : + { + PopSingleRef( aAdr ); + ScBaseCell* pCell = GetCell( aAdr ); + if (HasCellValueData(pCell)) + rValCount++; + } + break; + case svDoubleRef : + { + PopDoubleRef( aRange ); + USHORT nErr = 0; + double nCellVal; + ScValueIterator aValIter(pDok, aRange); + if (aValIter.GetFirst(nCellVal, nErr)) + { + rValCount++; + SetError(nErr); + while ((nErr == 0) && aValIter.GetNext(nCellVal, nErr)) + rValCount++; + SetError(nErr); + } + } + break; + case svMatrix : + { + ScMatrix* pMat = PopMatrix(); + if (pMat) + { + ULONG nCount = pMat->GetElementCount(); + if (pMat->IsNumeric()) + rValCount += nCount; + else + { + for (ULONG i = 0; i < nCount; i++) + if (!pMat->IsString(i)) + rValCount++; + } + } + } + break; + default : + SetError(errIllegalParameter); + break; + } + } + if (rValCount > MAX_ANZ_DOUBLE_FOR_SORT || nGlobalError) + { + SetError(errStackOverflow); + return; + } + else if (rValCount == 0) + { + SetNoValue(); + return; + } +#ifdef WIN + *ppSortArray = (double*) SvMemAlloc( rValCount * sizeof(double)); + double huge* pSArray = (double huge*) (*ppSortArray); +#else + *ppSortArray = new double[rValCount]; + double* pSArray = *ppSortArray; +#endif + if (!*ppSortArray) + { + rValCount = 0; + SetError(errStackOverflow); + return; + } + sp = SaveSP; + ULONG nIndex = 0; + for (i = 0; i < nParamCount; i++) + { + switch (GetStackType()) + { + case svDouble : + pSArray[nIndex] = GetDouble(); + nIndex++; + break; + case svSingleRef : + { + PopSingleRef( aAdr ); + ScBaseCell* pCell = GetCell( aAdr ); + if (HasCellValueData(pCell)) + { + pSArray[nIndex] = GetCellValue( aAdr, pCell ); + nIndex++; + } + } + break; + case svDoubleRef : + { + PopDoubleRef( aRange ); + USHORT nErr; + double nCellVal; + ScValueIterator aValIter(pDok, aRange); + if (aValIter.GetFirst(nCellVal, nErr)) + { + pSArray[nIndex] = nCellVal; + nIndex++; + while (aValIter.GetNext(nCellVal, nErr)) + { + pSArray[nIndex] = nCellVal; + nIndex++; + } + } + } + break; + case svMatrix : + { + ScMatrix* pMat = PopMatrix(); + if (pMat) + { + ULONG nCount = pMat->GetElementCount(); + if (pMat->IsNumeric()) + { + for (ULONG i = 0; i < nCount; i++) + { + pSArray[nIndex] = pMat->GetDouble(i); + nIndex++; + } + } + else + { + for (ULONG i = 0; i < nCount; i++) + if (!pMat->IsString(i)) + { + pSArray[nIndex] = pMat->GetDouble(i); + nIndex++; + } + } + } + } + break; + default : SetError(errIllegalParameter); break; + } + } + DBG_ASSERT(nIndex == rValCount,"nIndex != rValCount"); + if (nGlobalError == 0) + { + double fVal; + USHORT nInd; + for (ULONG i = 0; (i + 4) <= rValCount-1; i += 4) + { + nInd = rand() % (int) (rValCount-1); + fVal = pSArray[i]; + pSArray[i] = pSArray[nInd]; + pSArray[nInd] = fVal; + } + QuickSort(0, rValCount-1, pSArray); + } + nSize = rValCount; +} + +void ScInterpreter::QuickSort(long nLo, long nHi, double* pSortArray) +{ +#ifdef WIN + double huge* pSArray = (double huge*) pSortArray; +#else + double* pSArray = pSortArray; +#endif + if (nHi - nLo == 1) + { + if (pSArray[nLo] > pSArray[nHi]) + { + double fVal; + fVal = pSArray[nLo]; + pSArray[nLo] = pSArray[nHi]; + pSArray[nHi] = fVal; + } + } + else + { + long ni = nLo; + long nj = nHi; + do + { + while (ni <= nHi && pSArray[ni] < pSArray[nLo]) ni++; + while (nj >= nLo && pSArray[nLo] < pSArray[nj]) nj--; + if (ni <= nj) + { + if (ni != nj) + { + double fVal; + fVal = pSArray[ni]; + pSArray[ni] = pSArray[nj]; + pSArray[nj] = fVal; + } + ni++; + nj--; + } + } + while (ni < nj); + if ((nj - nLo) < (nHi - ni)) + { + if (nLo < nj) QuickSort(nLo, nj, pSortArray); + if (ni < nHi) QuickSort(ni, nHi, pSortArray); + } + else + { + if (ni < nHi) QuickSort(ni, nHi, pSortArray); + if (nLo < nj) QuickSort(nLo, nj, pSortArray); + } + } +} + +void ScInterpreter::ScRank() +{ + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 2, 3 ) ) + return; + BOOL bDescending; + if (nParamCount == 3) + bDescending = GetBool(); + else + bDescending = FALSE; + double fCount = 1.0; + BOOL bValid = FALSE; + switch (GetStackType()) + { + case svDouble : + { + double x = GetDouble(); + double fVal = GetDouble(); + if (x == fVal) + bValid = TRUE; + break; + } + case svSingleRef : + { + ScAddress aAdr; + PopSingleRef( aAdr ); + double fVal = GetDouble(); + ScBaseCell* pCell = GetCell( aAdr ); + if (HasCellValueData(pCell)) + { + double x = GetCellValue( aAdr, pCell ); + if (x == fVal) + bValid = TRUE; + } + break; + } + case svDoubleRef : + { + ScRange aRange; + USHORT nErr = 0; + PopDoubleRef( aRange ); + double fVal = GetDouble(); + double nCellVal; + ScValueIterator aValIter(pDok, aRange, glSubTotal); + if (aValIter.GetFirst(nCellVal, nErr)) + { + if (nCellVal == fVal) + bValid = TRUE; + else if ((!bDescending && nCellVal > fVal) || + (bDescending && nCellVal < fVal) ) + fCount++; + SetError(nErr); + while ((nErr == 0) && aValIter.GetNext(nCellVal, nErr)) + { + if (nCellVal == fVal) + bValid = TRUE; + else if ((!bDescending && nCellVal > fVal) || + (bDescending && nCellVal < fVal) ) + fCount++; + } + } + SetError(nErr); + } + break; + case svMatrix : + { + ScMatrix* pMat = PopMatrix(); + double fVal = GetDouble(); + if (pMat) + { + ULONG nCount = pMat->GetElementCount(); + if (pMat->IsNumeric()) + { + for (ULONG i = 0; i < nCount; i++) + { + double x = pMat->GetDouble(i); + if (x == fVal) + bValid = TRUE; + else if ((!bDescending && x > fVal) || + (bDescending && x < fVal) ) + fCount++; + } + } + else + { + for (ULONG i = 0; i < nCount; i++) + if (!pMat->IsString(i)) + { + double x = pMat->GetDouble(i); + if (x == fVal) + bValid = TRUE; + else if ((!bDescending && x > fVal) || + (bDescending && x < fVal) ) + fCount++; + } + } + } + } + break; + default : SetError(errIllegalParameter); break; + } + if (bValid) + PushDouble(fCount); + else + SetNoValue(); +} + +void ScInterpreter::ScAveDev() +{ + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCountMin( nParamCount, 1 ) ) + return; + USHORT SaveSP = sp; + USHORT i; + double nMiddle = 0.0; + double rVal = 0.0; + double rValCount = 0.0; + ScAddress aAdr; + ScRange aRange; + for (i = 0; i < nParamCount; i++) + { + switch (GetStackType()) + { + case svDouble : + rVal += GetDouble(); + rValCount++; + break; + case svSingleRef : + { + PopSingleRef( aAdr ); + ScBaseCell* pCell = GetCell( aAdr ); + if (HasCellValueData(pCell)) + { + rVal += GetCellValue( aAdr, pCell ); + rValCount++; + } + } + break; + case svDoubleRef : + { + USHORT nErr = 0; + double nCellVal; + PopDoubleRef( aRange ); + ScValueIterator aValIter(pDok, aRange); + if (aValIter.GetFirst(nCellVal, nErr)) + { + rVal += nCellVal; + rValCount++; + SetError(nErr); + while ((nErr == 0) && aValIter.GetNext(nCellVal, nErr)) + { + rVal += nCellVal; + rValCount++; + } + SetError(nErr); + } + } + break; + case svMatrix : + { + ScMatrix* pMat = PopMatrix(); + if (pMat) + { + ULONG nCount = pMat->GetElementCount(); + if (pMat->IsNumeric()) + { + for (ULONG i = 0; i < nCount; i++) + { + rVal += pMat->GetDouble(i); + rValCount++; + } + } + else + { + for (ULONG i = 0; i < nCount; i++) + if (!pMat->IsString(i)) + { + rVal += pMat->GetDouble(i); + rValCount++; + } + } + } + } + break; + default : + SetError(errIllegalParameter); + break; + } + } + if (nGlobalError) + { + PushInt(0); + return; + } + nMiddle = rVal / rValCount; + sp = SaveSP; + rVal = 0.0; + for (i = 0; i < nParamCount; i++) + { + switch (GetStackType()) + { + case svDouble : + rVal += fabs(GetDouble() - nMiddle); + break; + case svSingleRef : + { + PopSingleRef( aAdr ); + ScBaseCell* pCell = GetCell( aAdr ); + if (HasCellValueData(pCell)) + rVal += fabs(GetCellValue( aAdr, pCell ) - nMiddle); + } + break; + case svDoubleRef : + { + USHORT nErr = 0; + double nCellVal; + PopDoubleRef( aRange ); + ScValueIterator aValIter(pDok, aRange); + if (aValIter.GetFirst(nCellVal, nErr)) + { + rVal += (fabs(nCellVal - nMiddle)); + while (aValIter.GetNext(nCellVal, nErr)) + rVal += fabs(nCellVal - nMiddle); + } + } + break; + case svMatrix : + { + ScMatrix* pMat = PopMatrix(); + if (pMat) + { + ULONG nCount = pMat->GetElementCount(); + if (pMat->IsNumeric()) + { + for (ULONG i = 0; i < nCount; i++) + rVal += fabs(pMat->GetDouble(i) - nMiddle); + } + else + { + for (ULONG i = 0; i < nCount; i++) + if (!pMat->IsString(i)) + rVal += fabs(pMat->GetDouble(i) - nMiddle); + } + } + } + break; + default : SetError(errIllegalParameter); break; + } + } + PushDouble(rVal / rValCount); +} + +void ScInterpreter::ScDevSq() +{ + double nVal; + double nValCount; + GetStVarParams(nVal, nValCount); + PushDouble(nVal); +} + +void ScInterpreter::ScProbability() +{ + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 3, 4 ) ) + return; + double fUp, fLo; + fUp = GetDouble(); + if (nParamCount == 4) + fLo = GetDouble(); + else + fLo = fUp; + if (fLo > fUp) + { + double fTemp = fLo; + fLo = fUp; + fUp = fTemp; + } + USHORT nMatInd1, nMatInd2; + ScMatrix* pMatP = GetMatrix(nMatInd1); + ScMatrix* pMatW = GetMatrix(nMatInd2); + if (!pMatP || !pMatW) + SetIllegalParameter(); + else + { + USHORT nC1, nR1, nC2, nR2; + pMatP->GetDimensions(nC1, nR1); + pMatW->GetDimensions(nC2, nR2); + if (nC1 != nC2 || nR1 != nR2 || nC1 == 0 || nR1 == 0 || + nC2 == 0 || nR2 == 0) + SetNV(); + else + { + double fSum = 0.0; + double fRes = 0.0; + BOOL bStop = FALSE; + double fP, fW; + ULONG nCount1 = (ULONG) nC1 * nR1; + for ( ULONG i = 0; i < nCount1 && !bStop; i++ ) + { + if (pMatP->IsValue(i) && pMatW->IsValue(i)) + { + fP = pMatP->GetDouble(i); + fW = pMatW->GetDouble(i); + if (fP < 0.0 || fP > 1.0) + bStop = TRUE; + else + { + fSum += fP; + if (fW >= fLo && fW <= fUp) + fRes += fP; + } + } + else + SetIllegalArgument(); + } + if (bStop || fabs(fSum -1.0) > 1.0E-7) + SetNoValue(); + else + PushDouble(fRes); + } + } +} + +void ScInterpreter::ScCorrel() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + USHORT nMatInd1, nMatInd2; + ScMatrix* pMat1 = GetMatrix(nMatInd2); + ScMatrix* pMat2 = GetMatrix(nMatInd1); + if (!pMat1 || !pMat2) + { + SetIllegalParameter(); + return; + } + USHORT nC1, nR1, nC2, nR2; + pMat1->GetDimensions(nC1, nR1); + pMat2->GetDimensions(nC2, nR2); + if (nR1 != nR2 || nC1 != nC2) + { + SetIllegalParameter(); + return; + } + double fCount = 0.0; + double fSumX = 0.0; + double fSumSqrX = 0.0; + double fSumY = 0.0; + double fSumSqrY = 0.0; + double fSumXY = 0.0; + double fValX, fValY; + for (USHORT i = 0; i < nC1; i++) + for (USHORT j = 0; j < nR1; j++) + { + if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j)) + { + fValX = pMat1->GetDouble(i,j); + fValY = pMat2->GetDouble(i,j); + fSumX += fValX; + fSumSqrX += fValX * fValX; + fSumY += fValY; + fSumSqrY += fValY * fValY; + fSumXY += fValX*fValY; + fCount++; + } + } + if (fCount < 2.0) + SetNoValue(); + else + PushDouble( (fSumXY-fSumX*fSumY/fCount)/ + sqrt((fSumSqrX-fSumX*fSumX/fCount)* + (fSumSqrY-fSumY*fSumY/fCount))); +} + +void ScInterpreter::ScCovar() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + USHORT nMatInd1, nMatInd2; + ScMatrix* pMat1 = GetMatrix(nMatInd2); + ScMatrix* pMat2 = GetMatrix(nMatInd1); + if (!pMat1 || !pMat2) + { + SetIllegalParameter(); + return; + } + USHORT nC1, nR1, nC2, nR2; + pMat1->GetDimensions(nC1, nR1); + pMat2->GetDimensions(nC2, nR2); + if (nR1 != nR2 || nC1 != nC2) + { + SetIllegalParameter(); + return; + } + double fCount = 0.0; + double fSumX = 0.0; + double fSumY = 0.0; + double fSumXY = 0.0; + double fValX, fValY; + for (USHORT i = 0; i < nC1; i++) + for (USHORT j = 0; j < nR1; j++) + { + if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j)) + { + fValX = pMat1->GetDouble(i,j); + fValY = pMat2->GetDouble(i,j); + fSumX += fValX; + fSumY += fValY; + fSumXY += fValX*fValY; + fCount++; + } + } + if (fCount < 1.0) + SetNoValue(); + else + PushDouble( (fSumXY-fSumX*fSumY/fCount)/fCount); +} + +void ScInterpreter::ScPearson() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + USHORT nMatInd1, nMatInd2; + ScMatrix* pMat1 = GetMatrix(nMatInd2); + ScMatrix* pMat2 = GetMatrix(nMatInd1); + if (!pMat1 || !pMat2) + { + SetIllegalParameter(); + return; + } + USHORT nC1, nR1, nC2, nR2; + pMat1->GetDimensions(nC1, nR1); + pMat2->GetDimensions(nC2, nR2); + if (nR1 != nR2 || nC1 != nC2) + { + SetIllegalParameter(); + return; + } + double fCount = 0.0; + double fSumX = 0.0; + double fSumSqrX = 0.0; + double fSumY = 0.0; + double fSumSqrY = 0.0; + double fSumXY = 0.0; + double fValX, fValY; + for (USHORT i = 0; i < nC1; i++) + for (USHORT j = 0; j < nR1; j++) + { + if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j)) + { + fValX = pMat1->GetDouble(i,j); + fValY = pMat2->GetDouble(i,j); + fSumX += fValX; + fSumSqrX += fValX * fValX; + fSumY += fValY; + fSumSqrY += fValY * fValY; + fSumXY += fValX*fValY; + fCount++; + } + } + if (fCount < 2.0) + SetNoValue(); + else + PushDouble( (fCount*fSumXY-fSumX*fSumY)/ + sqrt((fCount*fSumSqrX-fSumX*fSumX)* + (fCount*fSumSqrY-fSumY*fSumY))); +} + +void ScInterpreter::ScRSQ() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + USHORT nMatInd1, nMatInd2; + ScMatrix* pMat1 = GetMatrix(nMatInd2); + ScMatrix* pMat2 = GetMatrix(nMatInd1); + if (!pMat1 || !pMat2) + { + SetIllegalParameter(); + return; + } + USHORT nC1, nR1, nC2, nR2; + pMat1->GetDimensions(nC1, nR1); + pMat2->GetDimensions(nC2, nR2); + if (nR1 != nR2 || nC1 != nC2) + { + SetIllegalParameter(); + return; + } + double fCount = 0.0; + double fSumX = 0.0; + double fSumSqrX = 0.0; + double fSumY = 0.0; + double fSumSqrY = 0.0; + double fSumXY = 0.0; + double fValX, fValY; + for (USHORT i = 0; i < nC1; i++) + for (USHORT j = 0; j < nR1; j++) + { + if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j)) + { + fValX = pMat1->GetDouble(i,j); + fValY = pMat2->GetDouble(i,j); + fSumX += fValX; + fSumSqrX += fValX * fValX; + fSumY += fValY; + fSumSqrY += fValY * fValY; + fSumXY += fValX*fValY; + fCount++; + } + } + if (fCount < 2.0) + SetNoValue(); + else + PushDouble( (fCount*fSumXY-fSumX*fSumY)*(fCount*fSumXY-fSumX*fSumY)/ + (fCount*fSumSqrX-fSumX*fSumX)/(fCount*fSumSqrY-fSumY*fSumY)); +} + +void ScInterpreter::ScSTEXY() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + USHORT nMatInd1, nMatInd2; + ScMatrix* pMat1 = GetMatrix(nMatInd2); + ScMatrix* pMat2 = GetMatrix(nMatInd1); + if (!pMat1 || !pMat2) + { + SetIllegalParameter(); + return; + } + USHORT nC1, nR1, nC2, nR2; + pMat1->GetDimensions(nC1, nR1); + pMat2->GetDimensions(nC2, nR2); + if (nR1 != nR2 || nC1 != nC2) + { + SetIllegalParameter(); + return; + } + double fCount = 0.0; + double fSumX = 0.0; + double fSumSqrX = 0.0; + double fSumY = 0.0; + double fSumSqrY = 0.0; + double fSumXY = 0.0; + double fValX, fValY; + for (USHORT i = 0; i < nC1; i++) + for (USHORT j = 0; j < nR1; j++) + { + if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j)) + { + fValX = pMat1->GetDouble(i,j); + fValY = pMat2->GetDouble(i,j); + fSumX += fValX; + fSumSqrX += fValX * fValX; + fSumY += fValY; + fSumSqrY += fValY * fValY; + fSumXY += fValX*fValY; + fCount++; + } + } + if (fCount < 3.0) + SetNoValue(); + else + PushDouble(sqrt((fCount*fSumSqrY - fSumY*fSumY - + (fCount*fSumXY -fSumX*fSumY)*(fCount*fSumXY -fSumX*fSumY)/ + (fCount*fSumSqrX-fSumX*fSumX) )/(fCount*(fCount-2.0)))); +} + +void ScInterpreter::ScSlope() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + USHORT nMatInd1, nMatInd2; + ScMatrix* pMat1 = GetMatrix(nMatInd2); + ScMatrix* pMat2 = GetMatrix(nMatInd1); + if (!pMat1 || !pMat2) + { + SetIllegalParameter(); + return; + } + USHORT nC1, nR1, nC2, nR2; + pMat1->GetDimensions(nC1, nR1); + pMat2->GetDimensions(nC2, nR2); + if (nR1 != nR2 || nC1 != nC2) + { + SetIllegalParameter(); + return; + } + double fCount = 0.0; + double fSumX = 0.0; + double fSumSqrX = 0.0; + double fSumY = 0.0; + double fSumXY = 0.0; + double fValX, fValY; + for (USHORT i = 0; i < nC1; i++) + for (USHORT j = 0; j < nR1; j++) + { + if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j)) + { + fValX = pMat1->GetDouble(i,j); + fValY = pMat2->GetDouble(i,j); + fSumX += fValX; + fSumSqrX += fValX * fValX; + fSumY += fValY; + fSumXY += fValX*fValY; + fCount++; + } + } + if (fCount < 1.0) + SetNoValue(); + else + PushDouble( (fCount*fSumXY-fSumX*fSumY)/ + (fCount*fSumSqrX-fSumX*fSumX) ); +} + +void ScInterpreter::ScIntercept() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + USHORT nMatInd1, nMatInd2; + ScMatrix* pMat1 = GetMatrix(nMatInd2); + ScMatrix* pMat2 = GetMatrix(nMatInd1); + if (!pMat1 || !pMat2) + { + SetIllegalParameter(); + return; + } + USHORT nC1, nR1, nC2, nR2; + pMat1->GetDimensions(nC1, nR1); + pMat2->GetDimensions(nC2, nR2); + if (nR1 != nR2 || nC1 != nC2) + { + SetIllegalParameter(); + return; + } + double fCount = 0.0; + double fSumX = 0.0; + double fSumSqrX = 0.0; + double fSumY = 0.0; + double fSumXY = 0.0; + double fValX, fValY; + for (USHORT i = 0; i < nC1; i++) + for (USHORT j = 0; j < nR1; j++) + { + if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j)) + { + fValX = pMat1->GetDouble(i,j); + fValY = pMat2->GetDouble(i,j); + fSumX += fValX; + fSumSqrX += fValX * fValX; + fSumY += fValY; + fSumXY += fValX*fValY; + fCount++; + } + } + if (fCount < 1.0) + SetNoValue(); + else + PushDouble( fSumY/fCount - (fCount*fSumXY-fSumX*fSumY)/ + (fCount*fSumSqrX-fSumX*fSumX)*fSumX/fCount ); + +} + +void ScInterpreter::ScForecast() +{ + if ( !MustHaveParamCount( GetByte(), 3 ) ) + return; + USHORT nMatInd1, nMatInd2; + ScMatrix* pMat1 = GetMatrix(nMatInd2); + ScMatrix* pMat2 = GetMatrix(nMatInd1); + if (!pMat1 || !pMat2) + { + SetIllegalParameter(); + return; + } + USHORT nC1, nR1, nC2, nR2; + pMat1->GetDimensions(nC1, nR1); + pMat2->GetDimensions(nC2, nR2); + if (nR1 != nR2 || nC1 != nC2) + { + SetIllegalParameter(); + return; + } + double fVal = GetDouble(); + double fCount = 0.0; + double fSumX = 0.0; + double fSumSqrX = 0.0; + double fSumY = 0.0; + double fSumXY = 0.0; + double fValX, fValY; + for (USHORT i = 0; i < nC1; i++) + for (USHORT j = 0; j < nR1; j++) + { + if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j)) + { + fValX = pMat1->GetDouble(i,j); + fValY = pMat2->GetDouble(i,j); + fSumX += fValX; + fSumSqrX += fValX * fValX; + fSumY += fValY; + fSumXY += fValX*fValY; + fCount++; + } + } + if (fCount < 1.0) + SetNoValue(); + else + PushDouble( fSumY/fCount + (fCount*fSumXY-fSumX*fSumY)/ + (fCount*fSumSqrX-fSumX*fSumX) * (fVal - fSumX/fCount) ); +} + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_interpr4.cxx b/binfilter/bf_sc/source/core/tool/sc_interpr4.cxx new file mode 100644 index 000000000000..01a17c5a6730 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_interpr4.cxx @@ -0,0 +1,3249 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// INCLUDE --------------------------------------------------------------- + +#ifdef RS6000 + +#pragma options FLTTRAP +#include <fptrap.h> +#include <fpxcp.h> + +#elif defined ( MAC ) + +#include <MAC_START.h> +#include <fp.h> +#include <MAC_END.h> +#include <ctype.h> + +#elif defined ( SOLARIS) + +#include <ieeefp.h> +#include <ctype.h> + +#elif defined ( ICC ) + +#include <ctype.h> + +#endif + + +#include <bf_sfx2/app.hxx> +#include "bf_basic/sbmeth.hxx" +#include "bf_basic/sbmod.hxx" +#include "bf_basic/sbstar.hxx" +#include "bf_basic/sbx.hxx" +#include <bf_svtools/zforlist.hxx> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <math.h> +#include <float.h> + + +using namespace ::com::sun::star; + +#include "interpre.hxx" +#include "dbcolect.hxx" +#include "addincol.hxx" +#include "dociter.hxx" +#include "scmatrix.hxx" +#include "bf_sc.hrc" +#include "cellsuno.hxx" +#include "optuno.hxx" +#include "rangeseq.hxx" +#include "addinlis.hxx" +namespace binfilter { + +// Implementiert in ui\miscdlgs\teamdlg.cxx + +extern void ShowTheTeam(); + +extern BOOL bOderSo; // in GLOBAL.CXX + +//-----------------------------statische Daten----------------- + +USHORT ScInterpreter::nGlobalError = 0; // fuer matherr + +#if SC_SPEW_ENABLED +ScSpew ScInterpreter::theSpew; +#endif + +//------------------------------------------------------------------------- +// Funktionen für den Zugriff auf das Document +//------------------------------------------------------------------------- + + +void ScInterpreter::ReplaceCell( ScAddress& rPos ) +{ + ScInterpreterTableOpParams* pTOp = pDok->aTableOpList.First(); + while (pTOp) + { + if ( rPos == pTOp->aOld1 ) + { + rPos = pTOp->aNew1; + return ; + } + else if ( rPos == pTOp->aOld2 ) + { + rPos = pTOp->aNew2; + return ; + } + else + pTOp = pDok->aTableOpList.Next(); + } +} + + +void ScInterpreter::ReplaceCell( USHORT& rCol, USHORT& rRow, USHORT& rTab ) +{ + ScAddress aCellPos( rCol, rRow, rTab ); + ScInterpreterTableOpParams* pTOp = pDok->aTableOpList.First(); + while (pTOp) + { + if ( aCellPos == pTOp->aOld1 ) + { + rCol = pTOp->aNew1.Col(); + rRow = pTOp->aNew1.Row(); + rTab = pTOp->aNew1.Tab(); + return ; + } + else if ( aCellPos == pTOp->aOld2 ) + { + rCol = pTOp->aNew2.Col(); + rRow = pTOp->aNew2.Row(); + rTab = pTOp->aNew2.Tab(); + return ; + } + else + pTOp = pDok->aTableOpList.Next(); + } +} + + +BOOL ScInterpreter::IsTableOpInRange( const ScRange& rRange ) +{ + if ( rRange.aStart == rRange.aEnd ) + return FALSE; // not considered to be a range in TableOp sense + + // we can't replace a single cell in a range + ScInterpreterTableOpParams* pTOp = pDok->aTableOpList.First(); + while (pTOp) + { + if ( rRange.In( pTOp->aOld1 ) ) + return TRUE; + if ( rRange.In( pTOp->aOld2 ) ) + return TRUE; + pTOp = pDok->aTableOpList.Next(); + } + return FALSE; +} + + +ULONG ScInterpreter::GetCellNumberFormat( const ScAddress& rPos, const ScBaseCell* pCell) +{ + ULONG nFormat; + USHORT nErr; + if ( pCell ) + { + if ( pCell->GetCellType() == CELLTYPE_FORMULA ) + nErr = ((ScFormulaCell*)pCell)->GetErrCode(); + else + nErr = 0; + nFormat = pDok->GetNumberFormat( rPos ); + if ( pCell->GetCellType() == CELLTYPE_FORMULA + && ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0) ) + nFormat = ((ScFormulaCell*)pCell)->GetStandardFormat( *pFormatter, + nFormat ); + } + else + { + nFormat = pDok->GetNumberFormat( rPos ); + nErr = 0; + } + SetError(nErr); + return nFormat; +} + + +// nur ValueCell, Formelzellen speichern das Ergebnis bereits gerundet +/*N*/ double ScInterpreter::GetValueCellValue( const ScAddress& rPos, const ScValueCell* pCell ) +/*N*/ { +/*N*/ double fVal = pCell->GetValue(); +/*N*/ if ( bCalcAsShown && fVal != 0.0 ) +/*N*/ { +/*?*/ ULONG nFormat = pDok->GetNumberFormat( rPos ); +/*?*/ fVal = pDok->RoundValueAsShown( fVal, nFormat ); +/*N*/ } +/*N*/ return fVal; +/*N*/ } + + +/*N*/ double ScInterpreter::GetCellValue( const ScAddress& rPos, const ScBaseCell* pCell ) +/*N*/ { +/*N*/ USHORT nErr = nGlobalError; +/*N*/ nGlobalError = 0; +/*N*/ double nVal = GetCellValueOrZero( rPos, pCell ); +/*N*/ if ( !nGlobalError || nGlobalError == errCellNoValue ) +/*N*/ nGlobalError = nErr; +/*N*/ return nVal; +/*N*/ } + + +/*N*/ double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, const ScBaseCell* pCell ) +/*N*/ { +/*N*/ double fValue; +/*N*/ if (pCell) +/*N*/ { +/*N*/ CellType eType = pCell->GetCellType(); +/*N*/ switch ( eType ) +/*N*/ { +/*N*/ case CELLTYPE_FORMULA: +/*N*/ { +/*N*/ ScFormulaCell* pFCell = (ScFormulaCell*) pCell; +/*N*/ USHORT nErr = pFCell->GetErrCode(); +/*N*/ if( !nErr ) +/*N*/ { +/*N*/ if (pFCell->IsValue()) +/*N*/ { +/*N*/ fValue = pFCell->GetValue(); +/*N*/ pDok->GetNumberFormatInfo( nCurFmtType, nCurFmtIndex, +/*N*/ rPos, *pFCell ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SetError(errCellNoValue); +/*N*/ fValue = 0.0; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ fValue = 0.0; +/*N*/ SetError(nErr); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case CELLTYPE_VALUE: +/*N*/ { +/*N*/ fValue = ((ScValueCell*)pCell)->GetValue(); +/*N*/ nCurFmtIndex = pDok->GetNumberFormat( rPos ); +/*N*/ nCurFmtType = pFormatter->GetType( nCurFmtIndex ); +/*N*/ if ( bCalcAsShown && fValue != 0.0 ) +/*?*/ fValue = pDok->RoundValueAsShown( fValue, nCurFmtIndex ); +/*N*/ } +/*N*/ break; +/*N*/ case CELLTYPE_STRING: +/*N*/ case CELLTYPE_EDIT: +/*?*/ #if 0 +/*?*/ // Xcl does it, but SUM(A1:A2) differs from A1+A2. No good. +/*?*/ { +/*?*/ String aStr; +/*?*/ if ( eType == CELLTYPE_STRING ) +/*?*/ ((ScStringCell*)pCell)->GetString( aStr ); +/*?*/ else +/*?*/ ((ScEditCell*)pCell)->GetString( aStr ); +/*?*/ ULONG nFIndex = 0; // damit default Land/Spr. +/*?*/ if ( !pFormatter->IsNumberFormat( aStr, nFIndex, fValue ) ) +/*?*/ { +/*?*/ SetError(errNoValue); +/*?*/ fValue = 0.0; +/*?*/ } +/*?*/ } +/*?*/ break; +/*?*/ #endif +/*N*/ default: +/*N*/ SetError(errCellNoValue); +/*N*/ fValue = 0.0; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ fValue = 0.0; +/*N*/ return fValue; +/*N*/ } + + +/*N*/ void ScInterpreter::GetCellString( String& rStr, const ScBaseCell* pCell ) +/*N*/ { +/*N*/ USHORT nErr = 0; +/*N*/ if (pCell) +/*N*/ { +/*N*/ switch (pCell->GetCellType()) +/*N*/ { +/*N*/ case CELLTYPE_STRING: +/*N*/ ((ScStringCell*) pCell)->GetString(rStr); +/*N*/ break; +/*?*/ case CELLTYPE_EDIT: +/*?*/ ((ScEditCell*) pCell)->GetString(rStr); +/*?*/ break; +/*N*/ case CELLTYPE_FORMULA: +/*N*/ { +/*N*/ ScFormulaCell* pFCell = (ScFormulaCell*) pCell; +/*N*/ nErr = pFCell->GetErrCode(); +/*N*/ if (pFCell->IsValue()) +/*N*/ { +/*?*/ double fVal = pFCell->GetValue(); +/*?*/ ULONG nIndex = pFormatter->GetStandardFormat( +/*?*/ NUMBERFORMAT_NUMBER, +/*?*/ ScGlobal::eLnge); +/*?*/ pFormatter->GetInputLineString(fVal, nIndex, rStr); +/*N*/ } +/*N*/ else +/*N*/ pFCell->GetString(rStr); +/*N*/ } +/*N*/ break; +/*?*/ case CELLTYPE_VALUE: +/*?*/ { +/*?*/ double fVal = ((ScValueCell*) pCell)->GetValue(); +/*?*/ ULONG nIndex = pFormatter->GetStandardFormat( +/*?*/ NUMBERFORMAT_NUMBER, +/*?*/ ScGlobal::eLnge); +/*?*/ pFormatter->GetInputLineString(fVal, nIndex, rStr); +/*?*/ } +/*?*/ break; +/*N*/ default: +/*N*/ rStr = ScGlobal::GetEmptyString(); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ else +/*?*/ rStr = ScGlobal::GetEmptyString(); +/*N*/ SetError(nErr); +/*N*/ } + + +USHORT ScInterpreter::GetCellErrCode( const ScBaseCell* pCell ) +{ + if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA ) + return ((ScFormulaCell*)pCell)->GetErrCode(); + return 0; +} + + +BOOL ScInterpreter::CreateDoubleArr(USHORT nCol1, USHORT nRow1, USHORT nTab1, + USHORT nCol2, USHORT nRow2, USHORT nTab2, BYTE* pCellArr) +{ + USHORT nCount = 0; + USHORT* p = (USHORT*) pCellArr; + *p++ = nCol1; + *p++ = nRow1; + *p++ = nTab1; + *p++ = nCol2; + *p++ = nRow2; + *p++ = nTab2; + USHORT* pCount = p; + *p++ = 0; + USHORT nPos = 14; + USHORT nTab = nTab1; + ScAddress aAdr; + while (nTab <= nTab2) + { + aAdr.SetTab( nTab ); + USHORT nRow = nRow1; + while (nRow <= nRow2) + { + aAdr.SetRow( nRow ); + USHORT nCol = nCol1; + while (nCol <= nCol2) + { + aAdr.SetCol( nCol ); + ScBaseCell* pCell = pDok->GetCell( aAdr ); + if (pCell) + { + USHORT nErr = 0; + double nVal = 0.0; + BOOL bOk = TRUE; + switch ( pCell->GetCellType() ) + { + case CELLTYPE_VALUE : + nVal = GetValueCellValue( aAdr, (ScValueCell*)pCell ); + break; + case CELLTYPE_FORMULA : + if (((ScFormulaCell*)pCell)->IsValue()) + { + nErr = ((ScFormulaCell*)pCell)->GetErrCode(); + nVal = ((ScFormulaCell*)pCell)->GetValue(); + } + else + bOk = FALSE; + break; + default : + bOk = FALSE; + break; + } + if (bOk) + { + if ((nPos + (4 * sizeof(USHORT)) + sizeof(double)) > MAXARRSIZE) + return FALSE; + *p++ = nCol; + *p++ = nRow; + *p++ = nTab; + *p++ = nErr; + memcpy( p, &nVal, sizeof(double)); + nPos += 8 + sizeof(double); + p = (USHORT*) ( pCellArr + nPos ); + nCount++; + } + } + nCol++; + } + nRow++; + } + nTab++; + } + *pCount = nCount; + return TRUE; +} + + +BOOL ScInterpreter::CreateStringArr(USHORT nCol1, USHORT nRow1, USHORT nTab1, + USHORT nCol2, USHORT nRow2, USHORT nTab2, + BYTE* pCellArr) +{ + USHORT nCount = 0; + USHORT* p = (USHORT*) pCellArr; + *p++ = nCol1; + *p++ = nRow1; + *p++ = nTab1; + *p++ = nCol2; + *p++ = nRow2; + *p++ = nTab2; + USHORT* pCount = p; + *p++ = 0; + USHORT nPos = 14; + USHORT nTab = nTab1; + while (nTab <= nTab2) + { + USHORT nRow = nRow1; + while (nRow <= nRow2) + { + USHORT nCol = nCol1; + while (nCol <= nCol2) + { + ScBaseCell* pCell; + pDok->GetCell(nCol, nRow, nTab, pCell); + if (pCell) + { + String aStr; + USHORT nErr = 0; + BOOL bOk = TRUE; + switch ( pCell->GetCellType() ) + { + case CELLTYPE_STRING : + ((ScStringCell*)pCell)->GetString(aStr); + break; + case CELLTYPE_EDIT : + ((ScEditCell*)pCell)->GetString(aStr); + break; + case CELLTYPE_FORMULA : + if (!((ScFormulaCell*)pCell)->IsValue()) + { + nErr = ((ScFormulaCell*)pCell)->GetErrCode(); + ((ScFormulaCell*)pCell)->GetString(aStr); + } + else + bOk = FALSE; + break; + default : + bOk = FALSE; + break; + } + if (bOk) + { + ByteString aTmp( aStr, osl_getThreadTextEncoding() ); + // In case the xub_StrLen will be longer than USHORT + // one day, and room for pad byte check. + if ( aTmp.Len() > ((USHORT)(~0)) - 2 ) + return FALSE; + // Append a 0-pad-byte if string length is not even + //! MUST be USHORT and not xub_StrLen + USHORT nStrLen = (USHORT) aTmp.Len(); + USHORT nLen = ( nStrLen + 2 ) & ~1; + + if (((ULONG)nPos + (5 * sizeof(USHORT)) + nLen) > MAXARRSIZE) + return FALSE; + *p++ = nCol; + *p++ = nRow; + *p++ = nTab; + *p++ = nErr; + *p++ = nLen; + memcpy( p, aTmp.GetBuffer(), nStrLen + 1); + nPos += 10 + nStrLen + 1; + BYTE* q = ( pCellArr + nPos ); + if( !nStrLen & 1 ) + *q++ = 0, nPos++; + p = (USHORT*) ( pCellArr + nPos ); + nCount++; + } + } + nCol++; + } + nRow++; + } + nTab++; + } + *pCount = nCount; + return TRUE; +} + + +BOOL ScInterpreter::CreateCellArr(USHORT nCol1, USHORT nRow1, USHORT nTab1, + USHORT nCol2, USHORT nRow2, USHORT nTab2, + BYTE* pCellArr) +{ + USHORT nCount = 0; + USHORT* p = (USHORT*) pCellArr; + *p++ = nCol1; + *p++ = nRow1; + *p++ = nTab1; + *p++ = nCol2; + *p++ = nRow2; + *p++ = nTab2; + USHORT* pCount = p; + *p++ = 0; + USHORT nPos = 14; + USHORT nTab = nTab1; + ScAddress aAdr; + while (nTab <= nTab2) + { + aAdr.SetTab( nTab ); + USHORT nRow = nRow1; + while (nRow <= nRow2) + { + aAdr.SetRow( nRow ); + USHORT nCol = nCol1; + while (nCol <= nCol2) + { + aAdr.SetCol( nCol ); + ScBaseCell* pCell = pDok->GetCell( aAdr ); + if (pCell) + { + USHORT nErr = 0; + USHORT nType = 0; // 0 = Zahl; 1 = String + double nVal = 0.0; + String aStr; + BOOL bOk = TRUE; + switch ( pCell->GetCellType() ) + { + case CELLTYPE_STRING : + ((ScStringCell*)pCell)->GetString(aStr); + nType = 1; + break; + case CELLTYPE_EDIT : + ((ScEditCell*)pCell)->GetString(aStr); + nType = 1; + break; + case CELLTYPE_VALUE : + nVal = GetValueCellValue( aAdr, (ScValueCell*)pCell ); + break; + case CELLTYPE_FORMULA : + nErr = ((ScFormulaCell*)pCell)->GetErrCode(); + if (((ScFormulaCell*)pCell)->IsValue()) + nVal = ((ScFormulaCell*)pCell)->GetValue(); + else + ((ScFormulaCell*)pCell)->GetString(aStr); + break; + default : + bOk = FALSE; + break; + } + if (bOk) + { + if ((nPos + (5 * sizeof(USHORT))) > MAXARRSIZE) + return FALSE; + *p++ = nCol; + *p++ = nRow; + *p++ = nTab; + *p++ = nErr; + *p++ = nType; + nPos += 10; + if (nType == 0) + { + if ((nPos + sizeof(double)) > MAXARRSIZE) + return FALSE; + memcpy( p, &nVal, sizeof(double)); + nPos += sizeof(double); + } + else + { + ByteString aTmp( aStr, osl_getThreadTextEncoding() ); + // In case the xub_StrLen will be longer than USHORT + // one day, and room for pad byte check. + if ( aTmp.Len() > ((USHORT)(~0)) - 2 ) + return FALSE; + // Append a 0-pad-byte if string length is not even + //! MUST be USHORT and not xub_StrLen + USHORT nStrLen = (USHORT) aTmp.Len(); + USHORT nLen = ( nStrLen + 2 ) & ~1; + if ( ((ULONG)nPos + 2 + nLen) > MAXARRSIZE) + return FALSE; + *p++ = nLen; + memcpy( p, aTmp.GetBuffer(), nStrLen + 1); + nPos += 2 + nStrLen + 1; + BYTE* q = ( pCellArr + nPos ); + if( !nStrLen & 1 ) + *q++ = 0, nPos++; + } + nCount++; + p = (USHORT*) ( pCellArr + nPos ); + } + } + nCol++; + } + nRow++; + } + nTab++; + } + *pCount = nCount; + return TRUE; +} + +//----------------------------------------------------------------------------- +// Stackoperationen +//----------------------------------------------------------------------------- + +// vorher wird ggf. ein Temp-Token geloescht. + + +/*N*/ void ScInterpreter::Push( ScToken& r ) +/*N*/ { +/*N*/ if ( sp >= MAXSTACK ) +/*N*/ SetError( errStackOverflow ); +/*N*/ else +/*N*/ { +/*N*/ nCurFmtType = NUMBERFORMAT_UNDEFINED; +/*N*/ r.IncRef(); +/*N*/ if( sp >= maxsp ) +/*N*/ maxsp = sp + 1; +/*N*/ else +/*N*/ pStack[ sp ]->DecRef(); +/*N*/ pStack[ sp ] = (ScToken*) &r; +/*N*/ pErrorStack[ sp ] = nGlobalError; +/*N*/ ++sp; +/*N*/ } +/*N*/ } + +// Schlichtes Wegwerfen von TOS + + +/*N*/ void ScInterpreter::Pop() +/*N*/ { +/*N*/ if( sp ) +/*N*/ sp--; +/*N*/ else +/*?*/ SetError(errUnknownStackVariable); +/*N*/ } + +// Schlichtes Wegwerfen von TOS mit Fehlercode setzen, fuer ocIsError etc. + + +void ScInterpreter::PopError() +{ + if( sp ) + { + sp--; + if ( !nGlobalError ) + nGlobalError = pErrorStack[ sp ]; + } + else + SetError(errUnknownStackVariable); +} + + +/*N*/ void ScInterpreter::PushTempToken( const ScToken& r ) +/*N*/ { +/*N*/ if ( sp >= MAXSTACK ) +/*?*/ SetError( errStackOverflow ); +/*N*/ else +/*N*/ { +/*N*/ ScToken* p = r.Clone(); +/*N*/ p->IncRef(); +/*N*/ if( sp >= maxsp ) +/*N*/ maxsp = sp + 1; +/*N*/ else +/*?*/ pStack[ sp ]->DecRef(); +/*N*/ pStack[ sp ] = p; +/*N*/ pErrorStack[ sp ] = nGlobalError; +/*N*/ ++sp; +/*N*/ } +/*N*/ } + + +//! The Token had to be allocated with `new' and must not be used after this +//! call because eventually it gets deleted in case of a errStackOverflow if +//! no RefCount was set! +/*N*/ void ScInterpreter::PushTempToken( ScToken* p ) +/*N*/ { +/*N*/ p->IncRef(); +/*N*/ if ( sp >= MAXSTACK ) +/*N*/ { +/*?*/ SetError( errStackOverflow ); +/*?*/ p->DecRef(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( sp >= maxsp ) +/*N*/ maxsp = sp + 1; +/*N*/ else +/*N*/ pStack[ sp ]->DecRef(); +/*N*/ pStack[ sp ] = p; +/*N*/ pErrorStack[ sp ] = nGlobalError; +/*N*/ ++sp; +/*N*/ } +/*N*/ } + + +/*N*/ double ScInterpreter::PopDouble() +/*N*/ { +/*N*/ nCurFmtType = NUMBERFORMAT_NUMBER; +/*N*/ nCurFmtIndex = 0; +/*N*/ if( sp ) +/*N*/ { +/*N*/ --sp; +/*N*/ ScToken* p = pStack[ sp ]; +/*N*/ if ( !nGlobalError ) +/*N*/ nGlobalError = pErrorStack[ sp ]; +/*N*/ if( p->GetType() == svDouble ) +/*N*/ return p->GetDouble(); +/*N*/ else if( p->GetType() == svMissing ) +/*N*/ return 0.0; +/*N*/ } +/*N*/ SetError(errUnknownStackVariable); +/*N*/ return 0.0; +/*N*/ } + + +BYTE ScInterpreter::PopByte() +{ + if( sp ) + { + --sp; + ScToken* p = pStack[ sp ]; + if ( !nGlobalError ) + nGlobalError = pErrorStack[ sp ]; + if( p->GetType() == svByte ) + return p->GetByte(); + else if( p->GetType() == svMissing ) + SetError( errIllegalParameter ); + } + SetError(errUnknownStackVariable); + return 0; +} + + +/*N*/ const String& ScInterpreter::PopString() +/*N*/ { +/*N*/ nCurFmtType = NUMBERFORMAT_TEXT; +/*N*/ nCurFmtIndex = 0; +/*N*/ if( sp ) +/*N*/ { +/*N*/ --sp; +/*N*/ ScToken* p = pStack[ sp ]; +/*N*/ if ( !nGlobalError ) +/*N*/ nGlobalError = pErrorStack[ sp ]; +/*N*/ if( p->GetType() == svString ) +/*N*/ return p->GetString(); +/*N*/ else if( p->GetType() == svMissing ) +/*N*/ return EMPTY_STRING; +/*N*/ } +/*N*/ SetError(errUnknownStackVariable); +/*N*/ return EMPTY_STRING; +/*N*/ } + + +void ScInterpreter::PopSingleRef(USHORT& rCol, USHORT &rRow, USHORT& rTab) +{ + if( sp ) + { + --sp; + ScToken* p = pStack[ sp ]; + if ( !nGlobalError ) + nGlobalError = pErrorStack[ sp ]; + if( p->GetType() == svSingleRef ) + { + const SingleRefData& rRef = p->GetSingleRef(); + if ( rRef.IsColRel() ) + rCol = aPos.Col() + rRef.nRelCol; + else + rCol = rRef.nCol; + if ( rRef.IsRowRel() ) + rRow = aPos.Row() + rRef.nRelRow; + else + rRow = rRef.nRow; + if ( rRef.IsTabRel() ) + rTab = aPos.Tab() + rRef.nRelTab; + else + rTab = rRef.nTab; + if( rCol < 0 || rCol > MAXCOL || rRef.IsColDeleted() ) + SetError( errNoRef ), rCol = 0; + if( rRow < 0 || rRow > MAXROW || rRef.IsRowDeleted() ) + SetError( errNoRef ), rRow = 0; + if( rTab < 0 || rTab >= pDok->GetTableCount() || rRef.IsTabDeleted() ) + SetError( errNoRef ), rTab = 0; + if ( pDok->aTableOpList.Count() > 0 ) + ReplaceCell( rCol, rRow, rTab ); + return; + } + else if( p->GetType() == svMissing ) + SetError( errIllegalParameter ); + } + SetError(errUnknownStackVariable); +} + + +/*N*/ void ScInterpreter::PopSingleRef( ScAddress& rAdr ) +/*N*/ { +/*N*/ if( sp ) +/*N*/ { +/*N*/ --sp; +/*N*/ ScToken* p = pStack[ sp ]; +/*N*/ if ( !nGlobalError ) +/*N*/ nGlobalError = pErrorStack[ sp ]; +/*N*/ if( p->GetType() == svSingleRef ) +/*N*/ { +/*N*/ short nCol, nRow, nTab; +/*N*/ const SingleRefData& rRef = p->GetSingleRef(); +/*N*/ if ( rRef.IsColRel() ) +/*N*/ nCol = aPos.Col() + rRef.nRelCol; +/*N*/ else +/*N*/ nCol = rRef.nCol; +/*N*/ if ( rRef.IsRowRel() ) +/*N*/ nRow = aPos.Row() + rRef.nRelRow; +/*N*/ else +/*N*/ nRow = rRef.nRow; +/*N*/ if ( rRef.IsTabRel() ) +/*N*/ nTab = aPos.Tab() + rRef.nRelTab; +/*N*/ else +/*N*/ nTab = rRef.nTab; +/*N*/ if( nCol < 0 || nCol > MAXCOL || rRef.IsColDeleted() ) +/*N*/ SetError( errNoRef ), nCol = 0; +/*N*/ if( nRow < 0 || nRow > MAXROW || rRef.IsRowDeleted() ) +/*N*/ SetError( errNoRef ), nRow = 0; +/*N*/ if( nTab < 0 || nTab >= pDok->GetTableCount() || rRef.IsTabDeleted() ) +/*N*/ SetError( errNoRef ), nTab = 0; +/*N*/ rAdr.Set( (USHORT)nCol, (USHORT)nRow, (USHORT)nTab ); +/*N*/ if ( pDok->aTableOpList.Count() > 0 ) +/*?*/ ReplaceCell( rAdr ); +/*N*/ return; +/*N*/ } +/*N*/ else if( p->GetType() == svMissing ) +/*N*/ SetError( errIllegalParameter ); +/*N*/ } +/*N*/ SetError(errUnknownStackVariable); +/*N*/ } + + +/*N*/ void ScInterpreter::PopDoubleRef(USHORT& rCol1, USHORT &rRow1, USHORT& rTab1, +/*N*/ USHORT& rCol2, USHORT &rRow2, USHORT& rTab2, +/*N*/ BOOL bDontCheckForTableOp ) +/*N*/ { +/*N*/ if( sp ) +/*N*/ { +/*N*/ --sp; +/*N*/ ScToken* p = pStack[ sp ]; +/*N*/ if ( !nGlobalError ) +/*N*/ nGlobalError = pErrorStack[ sp ]; +/*N*/ if( p->GetType() == svDoubleRef ) +/*N*/ { +/*N*/ const ComplRefData& rCRef = p->GetDoubleRef(); +/*N*/ USHORT nMaxTab = pDok->GetTableCount(); +/*N*/ { +/*N*/ const SingleRefData& rRef = rCRef.Ref1; +/*N*/ if ( rRef.IsColRel() ) +/*N*/ rCol1 = aPos.Col() + rRef.nRelCol; +/*N*/ else +/*N*/ rCol1 = rRef.nCol; +/*N*/ if ( rRef.IsRowRel() ) +/*N*/ rRow1 = aPos.Row() + rRef.nRelRow; +/*N*/ else +/*N*/ rRow1 = rRef.nRow; +/*N*/ if ( rRef.IsTabRel() ) +/*N*/ rTab1 = aPos.Tab() + rRef.nRelTab; +/*N*/ else +/*N*/ rTab1 = rRef.nTab; +/*N*/ if( rCol1 < 0 || rCol1 > MAXCOL || rRef.IsColDeleted() ) +/*N*/ SetError( errNoRef ), rCol1 = 0; +/*N*/ if( rRow1 < 0 || rRow1 > MAXROW || rRef.IsRowDeleted() ) +/*N*/ SetError( errNoRef ), rRow1 = 0; +/*N*/ if( rTab1 < 0 || rTab1 >= nMaxTab || rRef.IsTabDeleted() ) +/*N*/ SetError( errNoRef ), rTab1 = 0; +/*N*/ } +/*N*/ { +/*N*/ const SingleRefData& rRef = rCRef.Ref2; +/*N*/ if ( rRef.IsColRel() ) +/*N*/ rCol2 = aPos.Col() + rRef.nRelCol; +/*N*/ else +/*N*/ rCol2 = rRef.nCol; +/*N*/ if ( rRef.IsRowRel() ) +/*N*/ rRow2 = aPos.Row() + rRef.nRelRow; +/*N*/ else +/*N*/ rRow2 = rRef.nRow; +/*N*/ if ( rRef.IsTabRel() ) +/*N*/ rTab2 = aPos.Tab() + rRef.nRelTab; +/*N*/ else +/*N*/ rTab2 = rRef.nTab; +/*N*/ if( rCol2 < 0 || rCol2 > MAXCOL || rRef.IsColDeleted() ) +/*N*/ SetError( errNoRef ), rCol2 = 0; +/*N*/ if( rRow2 < 0 || rRow2 > MAXROW || rRef.IsRowDeleted() ) +/*N*/ SetError( errNoRef ), rRow2 = 0; +/*N*/ if( rTab2 < 0 || rTab2 >= nMaxTab || rRef.IsTabDeleted() ) +/*N*/ SetError( errNoRef ), rTab2 = 0; +/*N*/ } +/*N*/ if ( pDok->aTableOpList.Count() > 0 && !bDontCheckForTableOp ) +/*N*/ { +/*?*/ ScRange aRange( rCol1, rRow1, rTab1, rCol2, rRow2, rTab2 ); +/*?*/ if ( IsTableOpInRange( aRange ) ) +/*?*/ SetError( errIllegalParameter ); +/*N*/ } +/*N*/ return; +/*N*/ } +/*N*/ else if( p->GetType() == svMissing ) +/*N*/ SetError( errIllegalParameter ); +/*N*/ } +/*N*/ SetError(errUnknownStackVariable); +/*N*/ } + + +/*N*/ void ScInterpreter::PopDoubleRef( ScRange& rRange, BOOL bDontCheckForTableOp ) +/*N*/ { +/*N*/ if( sp ) +/*N*/ { +/*N*/ --sp; +/*N*/ ScToken* p = pStack[ sp ]; +/*N*/ if ( !nGlobalError ) +/*N*/ nGlobalError = pErrorStack[ sp ]; +/*N*/ if( p->GetType() == svDoubleRef ) +/*N*/ { +/*N*/ const ComplRefData& rCRef = p->GetDoubleRef(); +/*N*/ short nCol, nRow, nTab; +/*N*/ USHORT nMaxTab = pDok->GetTableCount(); +/*N*/ { +/*N*/ const SingleRefData& rRef = rCRef.Ref1; +/*N*/ if ( rRef.IsColRel() ) +/*N*/ nCol = aPos.Col() + rRef.nRelCol; +/*N*/ else +/*N*/ nCol = rRef.nCol; +/*N*/ if ( rRef.IsRowRel() ) +/*N*/ nRow = aPos.Row() + rRef.nRelRow; +/*N*/ else +/*N*/ nRow = rRef.nRow; +/*N*/ if ( rRef.IsTabRel() ) +/*N*/ nTab = aPos.Tab() + rRef.nRelTab; +/*N*/ else +/*N*/ nTab = rRef.nTab; +/*N*/ if( nCol < 0 || nCol > MAXCOL || rRef.IsColDeleted() ) +/*N*/ SetError( errNoRef ), nCol = 0; +/*N*/ if( nRow < 0 || nRow > MAXROW || rRef.IsRowDeleted() ) +/*N*/ SetError( errNoRef ), nRow = 0; +/*N*/ if( nTab < 0 || nTab >= nMaxTab || rRef.IsTabDeleted() ) +/*N*/ SetError( errNoRef ), nTab = 0; +/*N*/ rRange.aStart.Set( (USHORT)nCol, (USHORT)nRow, (USHORT)nTab ); +/*N*/ } +/*N*/ { +/*N*/ const SingleRefData& rRef = rCRef.Ref2; +/*N*/ if ( rRef.IsColRel() ) +/*N*/ nCol = aPos.Col() + rRef.nRelCol; +/*N*/ else +/*N*/ nCol = rRef.nCol; +/*N*/ if ( rRef.IsRowRel() ) +/*N*/ nRow = aPos.Row() + rRef.nRelRow; +/*N*/ else +/*N*/ nRow = rRef.nRow; +/*N*/ if ( rRef.IsTabRel() ) +/*N*/ nTab = aPos.Tab() + rRef.nRelTab; +/*N*/ else +/*N*/ nTab = rRef.nTab; +/*N*/ if( nCol < 0 || nCol > MAXCOL || rRef.IsColDeleted() ) +/*N*/ SetError( errNoRef ), nCol = 0; +/*N*/ if( nRow < 0 || nRow > MAXROW || rRef.IsRowDeleted() ) +/*N*/ SetError( errNoRef ), nRow = 0; +/*N*/ if( nTab < 0 || nTab >= nMaxTab || rRef.IsTabDeleted() ) +/*N*/ SetError( errNoRef ), nTab = 0; +/*N*/ rRange.aEnd.Set( (USHORT)nCol, (USHORT)nRow, (USHORT)nTab ); +/*N*/ } +/*N*/ if ( pDok->aTableOpList.Count() > 0 && !bDontCheckForTableOp ) +/*N*/ { +/*?*/ if ( IsTableOpInRange( rRange ) ) +/*?*/ SetError( errIllegalParameter ); +/*N*/ } +/*N*/ return; +/*N*/ } +/*?*/ else if( p->GetType() == svMissing ) +/*?*/ SetError( errIllegalParameter ); +/*?*/ } +/*?*/ SetError(errUnknownStackVariable); +/*N*/ } + + +BOOL ScInterpreter::PopDoubleRefOrSingleRef( ScAddress& rAdr ) +{ + switch ( GetStackType() ) + { + case svDoubleRef : + { + ScRange aRange; + PopDoubleRef( aRange, TRUE ); + return DoubleRefToPosSingleRef( aRange, rAdr ); + } + //break; + case svSingleRef : + { + PopSingleRef( rAdr ); + return TRUE; + } + //break; + default: + Pop(); + SetError( errNoRef ); + } + return FALSE; +} + + +/*N*/ void ScInterpreter::PopDoubleRefPushMatrix() +/*N*/ { +/*N*/ if ( GetStackType() == svDoubleRef ) +/*N*/ { +/*N*/ USHORT nMatInd; +/*N*/ ScMatrix* pMat = GetMatrix( nMatInd ); +/*N*/ if ( pMat ) +/*N*/ { +/*N*/ PushMatrix( pMat ); +/*N*/ nRetMat = nMatInd; +/*N*/ } +/*N*/ else +/*?*/ SetIllegalParameter(); +/*N*/ } +/*N*/ else +/*N*/ SetError( errNoRef ); +/*N*/ } + + +/*N*/ ScMatrix* ScInterpreter::PopMatrix() +/*N*/ { +/*N*/ if( sp ) +/*N*/ { +/*N*/ --sp; +/*N*/ ScToken* p = pStack[ sp ]; +/*N*/ if ( !nGlobalError ) +/*N*/ nGlobalError = pErrorStack[ sp ]; +/*N*/ if( p->GetType() == svMatrix ) +/*N*/ return p->GetMatrix(); +/*N*/ else if( p->GetType() == svMissing ) +/*N*/ SetError( errIllegalParameter ); +/*N*/ } +/*N*/ SetError(errUnknownVariable); +/*N*/ return NULL; +/*N*/ } + + + +/*N*/ void ScInterpreter::PushDouble(double nVal) +/*N*/ { +/*N*/ if (!::rtl::math::isFinite(nVal)) +/*N*/ { +/*N*/ if ( ::rtl::math::isNan( nVal ) ) +/*N*/ SetError(errNoValue); +/*N*/ else +/*N*/ SetError(errIllegalFPOperation); +/*N*/ nVal = 0.0; +/*N*/ } +/*N*/ PushTempToken( new ScDoubleToken( nVal ) ); +/*N*/ } + + +/*N*/ void ScInterpreter::PushInt(int nVal) +/*N*/ { +/*N*/ PushTempToken( new ScDoubleToken( nVal ) ); +/*N*/ } + + +void ScInterpreter::PushStringBuffer( const sal_Unicode* pString ) +{ + if ( pString ) + PushString( String( pString ) ); + else + PushString( EMPTY_STRING ); +} + + +/*N*/ void ScInterpreter::PushString( const String& rString ) +/*N*/ { +/*N*/ PushTempToken( new ScStringToken( rString ) ); +/*N*/ } + + +void ScInterpreter::PushSingleRef(USHORT nCol, USHORT nRow, USHORT nTab) +{ + SingleRefData aRef; + aRef.InitFlags(); + aRef.nCol = nCol; + aRef.nRow = nRow; + aRef.nTab = nTab; + PushTempToken( new ScSingleRefToken( aRef ) ); +} + + +void ScInterpreter::PushDoubleRef(USHORT nCol1, USHORT nRow1, USHORT nTab1, + USHORT nCol2, USHORT nRow2, USHORT nTab2) +{ + ComplRefData aRef; + aRef.InitFlags(); + aRef.Ref1.nCol = nCol1; + aRef.Ref1.nRow = nRow1; + aRef.Ref1.nTab = nTab1; + aRef.Ref2.nCol = nCol2; + aRef.Ref2.nRow = nRow2; + aRef.Ref2.nTab = nTab2; + PushTempToken( new ScDoubleRefToken( aRef ) ); +} + + +/*N*/ void ScInterpreter::PushMatrix(ScMatrix* pMat) +/*N*/ { +/*N*/ PushTempToken( new ScMatrixToken( pMat ) ); +/*N*/ } + + +void ScInterpreter::SetParameterExpected() +{ + SetError(errParameterExpected); + PushInt(0); +} + + +void ScInterpreter::SetIllegalParameter() +{ + SetError(errIllegalParameter); + PushInt(0); +} + + +/*N*/ void ScInterpreter::SetIllegalArgument() +/*N*/ { +/*N*/ SetError(errIllegalArgument); +/*N*/ PushInt(0); +/*N*/ } + + +void ScInterpreter::SetNV() +{ + SetError(NOVALUE); + PushInt(0); +} + + +/*N*/ void ScInterpreter::SetNoValue() +/*N*/ { +/*N*/ SetError(errNoValue); +/*N*/ PushInt(0); +/*N*/ } + + +/*N*/ StackVar ScInterpreter::GetStackType() +/*N*/ { +/*N*/ StackVar eRes; +/*N*/ if( sp ) +/*N*/ { +/*N*/ eRes = pStack[sp - 1]->GetType(); +/*N*/ if( eRes == svMissing ) +/*N*/ eRes = svDouble; // default! +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SetError(errUnknownStackVariable); +/*N*/ eRes = svErr; +/*N*/ } +/*N*/ return eRes; +/*N*/ } + + +/*N*/ StackVar ScInterpreter::GetStackType( BYTE nParam ) +/*N*/ { +/*N*/ StackVar eRes; +/*N*/ if( sp > nParam-1 ) +/*N*/ { +/*N*/ eRes = pStack[sp - nParam]->GetType(); +/*N*/ if( eRes == svMissing ) +/*N*/ eRes = svDouble; // default! +/*N*/ } +/*N*/ else +/*N*/ eRes = svErr; +/*N*/ return eRes; +/*N*/ } + + +BOOL ScInterpreter::DoubleRefToPosSingleRef( const ScRange& rRange, ScAddress& rAdr ) +{ + USHORT nMyCol = aPos.Col(); + USHORT nMyRow = aPos.Row(); + USHORT nMyTab = aPos.Tab(); + USHORT nCol, nRow, nTab; + nTab = rRange.aStart.Tab(); + BOOL bOk = FALSE; + if ( rRange.aStart.Col() <= nMyCol && nMyCol <= rRange.aEnd.Col() ) + { + nRow = rRange.aStart.Row(); + if ( nRow == rRange.aEnd.Row() ) + { + bOk = TRUE; + nCol = nMyCol; + } + else if ( nTab != nMyTab && nTab == rRange.aEnd.Tab() + && rRange.aStart.Row() <= nMyRow && nMyRow <= rRange.aEnd.Row() ) + { + bOk = TRUE; + nCol = nMyCol; + nRow = nMyRow; + } + } + else if ( rRange.aStart.Row() <= nMyRow && nMyRow <= rRange.aEnd.Row() ) + { + nCol = rRange.aStart.Col(); + if ( nCol == rRange.aEnd.Col() ) + { + bOk = TRUE; + nRow = nMyRow; + } + else if ( nTab != nMyTab && nTab == rRange.aEnd.Tab() + && rRange.aStart.Col() <= nMyCol && nMyCol <= rRange.aEnd.Col() ) + { + bOk = TRUE; + nCol = nMyCol; + nRow = nMyRow; + } + } + if ( bOk ) + { + if ( nTab == rRange.aEnd.Tab() ) + ; // all done + else if ( nTab <= nMyTab && nMyTab <= rRange.aEnd.Tab() ) + nTab = nMyTab; + else + bOk = FALSE; + if ( bOk ) + rAdr.Set( nCol, nRow, nTab ); + } + if ( !bOk ) + SetError( errNoValue ); + return bOk; +} + + +/*N*/ double ScInterpreter::GetDouble() +/*N*/ { +/*N*/ double nVal; +/*N*/ switch( GetStackType() ) +/*N*/ { +/*N*/ case svDouble: +/*N*/ nVal = PopDouble(); break; +/*N*/ case svString: +/*N*/ { +/*N*/ String aStr(PopString()); +/*N*/ sal_uInt32 nFIndex = 0; // damit default Land/Spr. +/*N*/ if(!pFormatter->IsNumberFormat( aStr, nFIndex, nVal ) ) +/*N*/ { +/*N*/ SetError(errIllegalArgument); +/*N*/ nVal = 0.0; +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case svSingleRef: +/*N*/ { +/*N*/ ScAddress aAdr; +/*N*/ PopSingleRef( aAdr ); +/*N*/ ScBaseCell* pCell = GetCell( aAdr ); +/*N*/ nVal = GetCellValue( aAdr, pCell ); +/*N*/ } +/*N*/ break; +/*?*/ case svDoubleRef: +/*?*/ { // positionsabhaengige SingleRef generieren +/*?*/ ScRange aRange; +/*?*/ PopDoubleRef( aRange ); +/*?*/ ScAddress aAdr; +/*?*/ if ( !nGlobalError && DoubleRefToPosSingleRef( aRange, aAdr ) ) +/*?*/ { +/*?*/ ScBaseCell* pCell = GetCell( aAdr ); +/*?*/ nVal = GetCellValue( aAdr, pCell ); +/*?*/ } +/*?*/ else +/*?*/ nVal = 0.0; +/*?*/ } +/*?*/ break; +/*?*/ default: +/*?*/ Pop(); +/*?*/ SetError(errIllegalParameter); +/*?*/ nVal = 0.0; +/*N*/ } +/*N*/ if ( nFuncFmtType == nCurFmtType ) +/*N*/ nFuncFmtIndex = nCurFmtIndex; +/*N*/ return nVal; +/*N*/ } + + +/*N*/ const String& ScInterpreter::GetString() +/*N*/ { +/*N*/ StackVar eRes = (StackVar) GetStackType(); +/*N*/ if( eRes == svDouble && pStack[ sp-1 ]->GetType() == svMissing ) +/*N*/ eRes = svString; +/*N*/ switch( eRes ) +/*N*/ { +/*?*/ case svDouble: +/*?*/ { +/*?*/ double fVal = PopDouble(); +/*?*/ ULONG nIndex = pFormatter->GetStandardFormat( +/*?*/ NUMBERFORMAT_NUMBER, +/*?*/ ScGlobal::eLnge); +/*?*/ pFormatter->GetInputLineString(fVal, nIndex, aTempStr); +/*?*/ return aTempStr; +/*?*/ } +/*?*/ //break; +/*N*/ case svString: +/*N*/ return PopString(); +/*N*/ //break; +/*N*/ case svSingleRef: +/*N*/ { +/*N*/ ScAddress aAdr; +/*N*/ PopSingleRef( aAdr ); +/*N*/ if (nGlobalError == 0) +/*N*/ { +/*N*/ ScBaseCell* pCell = GetCell( aAdr ); +/*N*/ GetCellString( aTempStr, pCell ); +/*N*/ return aTempStr; +/*N*/ } +/*N*/ else +/*N*/ return EMPTY_STRING; +/*N*/ } +/*N*/ //break; +/*?*/ case svDoubleRef: +/*?*/ { // positionsabhaengige SingleRef generieren +/*?*/ ScRange aRange; +/*?*/ PopDoubleRef( aRange ); +/*?*/ ScAddress aAdr; +/*?*/ if ( !nGlobalError && DoubleRefToPosSingleRef( aRange, aAdr ) ) +/*?*/ { +/*?*/ ScBaseCell* pCell = GetCell( aAdr ); +/*?*/ GetCellString( aTempStr, pCell ); +/*?*/ return aTempStr; +/*?*/ } +/*?*/ else +/*?*/ return EMPTY_STRING; +/*?*/ } +/*?*/ //break; +/*?*/ default: +/*?*/ Pop(); +/*?*/ SetError(errIllegalParameter); +/*N*/ } +/*N*/ return EMPTY_STRING; +/*N*/ } + + +/*N*/ void ScInterpreter::ScDBGet() +/*N*/ { +/*N*/ USHORT nTab; +/*N*/ ScQueryParam aQueryParam; +/*N*/ BOOL bMissingField = FALSE; +/*N*/ if (GetDBParams( nTab, aQueryParam, bMissingField)) +/*N*/ { +/*N*/ ScBaseCell* pCell; +/*N*/ ScQueryCellIterator aCellIter(pDok, nTab, aQueryParam); +/*N*/ if (pCell = aCellIter.GetFirst()) +/*N*/ { +/*N*/ if (aCellIter.GetNext()) +/*N*/ SetIllegalArgument(); +/*N*/ else +/*N*/ { +/*N*/ switch (pCell->GetCellType()) +/*N*/ { +/*N*/ case CELLTYPE_VALUE: +/*N*/ { +/*N*/ double rValue = ((ScValueCell*)pCell)->GetValue(); +/*N*/ if ( bCalcAsShown ) +/*N*/ { +/*N*/ ULONG nFormat; +/*N*/ nFormat = aCellIter.GetNumberFormat(); +/*N*/ rValue = pDok->RoundValueAsShown( rValue, nFormat ); +/*N*/ } +/*N*/ PushDouble(rValue); +/*N*/ } +/*N*/ break; +/*N*/ case CELLTYPE_STRING: +/*N*/ { +/*N*/ String rString; +/*N*/ ((ScStringCell*)pCell)->GetString(rString); +/*N*/ PushString(rString); +/*N*/ } +/*N*/ break; +/*N*/ case CELLTYPE_EDIT: +/*N*/ { +/*N*/ String rString; +/*N*/ ((ScEditCell*)pCell)->GetString(rString); +/*N*/ PushString(rString); +/*N*/ } +/*N*/ break; +/*N*/ case CELLTYPE_FORMULA: +/*N*/ { +/*N*/ USHORT rErr = ((ScFormulaCell*)pCell)->GetErrCode(); +/*N*/ if (rErr) +/*N*/ { +/*N*/ SetError(rErr); +/*N*/ PushInt(0); +/*N*/ } +/*N*/ else if (((ScFormulaCell*)pCell)->IsValue()) +/*N*/ { +/*N*/ double rValue = ((ScFormulaCell*)pCell)->GetValue(); +/*N*/ PushDouble(rValue); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ String rString; +/*N*/ ((ScFormulaCell*)pCell)->GetString(rString); +/*N*/ PushString(rString); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case CELLTYPE_NONE: +/*N*/ case CELLTYPE_NOTE: +/*N*/ default: +/*N*/ SetIllegalArgument(); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ SetNoValue(); +/*N*/ } +/*N*/ else +/*N*/ SetIllegalParameter(); +/*N*/ } + + +/*N*/ void ScInterpreter::ScExternal() +/*N*/ { +/*N*/ USHORT nIndex; +/*N*/ BYTE nParamCount = GetByte(); +/*N*/ String aUnoName; +/*N*/ String aFuncName( ScGlobal::pCharClass->upper( pCur->GetExternal() ) ); +/*N*/ if (ScGlobal::GetFuncCollection()->SearchFunc(aFuncName, nIndex)) +/*N*/ { +/*?*/ FuncData* pFuncData = (FuncData*)ScGlobal::GetFuncCollection()->At(nIndex); +/*?*/ if (nParamCount == pFuncData->GetParamCount() - 1) +/*?*/ { +/*?*/ ParamType eParamType[MAXFUNCPARAM]; +/*?*/ void* ppParam[MAXFUNCPARAM]; +/*?*/ double nVal[MAXFUNCPARAM]; +/*?*/ sal_Char* pStr[MAXFUNCPARAM]; +/*?*/ BYTE* pCellArr[MAXFUNCPARAM]; +/*?*/ short i; +/*?*/ +/*?*/ for (i = 0; i < MAXFUNCPARAM; i++) +/*?*/ { +/*?*/ eParamType[i] = pFuncData->GetParamType(i); +/*?*/ ppParam[i] = NULL; +/*?*/ nVal[i] = 0.0; +/*?*/ pStr[i] = NULL; +/*?*/ pCellArr[i] = NULL; +/*?*/ } +/*?*/ +/*?*/ for (i = nParamCount; (i > 0) && (nGlobalError == 0); i--) +/*?*/ { +/*?*/ BYTE nStackType = GetStackType(); +/*?*/ switch (eParamType[i]) +/*?*/ { +/*?*/ case PTR_DOUBLE : +/*?*/ { +/*?*/ nVal[i-1] = GetDouble(); +/*?*/ ppParam[i] = &nVal[i-1]; +/*?*/ } +/*?*/ break; +/*?*/ case PTR_STRING : +/*?*/ { +/*?*/ ByteString aStr( GetString(), osl_getThreadTextEncoding() ); +/*?*/ if ( aStr.Len() >= MAXSTRLEN ) +/*?*/ SetError( errStringOverflow ); +/*?*/ else +/*?*/ { +/*?*/ pStr[i-1] = new sal_Char[MAXSTRLEN]; +/*?*/ strncpy( pStr[i-1], aStr.GetBuffer(), MAXSTRLEN ); +/*?*/ pStr[i-1][MAXSTRLEN-1] = 0; +/*?*/ ppParam[i] = pStr[i-1]; +/*?*/ } +/*?*/ } +/*?*/ break; +/*?*/ case PTR_DOUBLE_ARR : +/*?*/ { +/*?*/ USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; +/*?*/ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); +/*?*/ pCellArr[i-1] = new BYTE[MAXARRSIZE]; +/*?*/ if (!CreateDoubleArr(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, pCellArr[i-1])) +/*?*/ SetError(errCodeOverflow); +/*?*/ else +/*?*/ ppParam[i] = pCellArr[i-1]; +/*?*/ } +/*?*/ break; +/*?*/ case PTR_STRING_ARR : +/*?*/ { +/*?*/ USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; +/*?*/ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); +/*?*/ pCellArr[i-1] = new BYTE[MAXARRSIZE]; +/*?*/ if (!CreateStringArr(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, pCellArr[i-1])) +/*?*/ SetError(errCodeOverflow); +/*?*/ else +/*?*/ ppParam[i] = pCellArr[i-1]; +/*?*/ } +/*?*/ break; +/*?*/ case PTR_CELL_ARR : +/*?*/ { +/*?*/ USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; +/*?*/ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); +/*?*/ pCellArr[i-1] = new BYTE[MAXARRSIZE]; +/*?*/ if (!CreateCellArr(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, pCellArr[i-1])) +/*?*/ SetError(errCodeOverflow); +/*?*/ else +/*?*/ ppParam[i] = pCellArr[i-1]; +/*?*/ } +/*?*/ break; +/*?*/ default : +/*?*/ SetError(errIllegalParameter); +/*?*/ break; +/*?*/ } +/*?*/ } +/*?*/ while ( i-- ) +/*?*/ Pop(); // im Fehlerfall (sonst ist i==0) Parameter wegpoppen +/*?*/ +/*?*/ if (nGlobalError == 0) +/*?*/ { +/*?*/ if ( pFuncData->GetAsyncType() == NONE ) +/*?*/ { +/*?*/ switch ( eParamType[0] ) +/*?*/ { +/*?*/ case PTR_DOUBLE : +/*?*/ { +/*?*/ double nErg = 0.0; +/*?*/ ppParam[0] = &nErg; +/*?*/ pFuncData->Call(ppParam); +/*?*/ PushDouble(nErg); +/*?*/ } +/*?*/ break; +/*?*/ case PTR_STRING : +/*?*/ { +/*?*/ sal_Char* pcErg = new sal_Char[MAXSTRLEN]; +/*?*/ ppParam[0] = pcErg; +/*?*/ pFuncData->Call(ppParam); +/*?*/ String aUni( pcErg, osl_getThreadTextEncoding() ); +/*?*/ PushString( aUni ); +/*?*/ delete[] pcErg; +/*?*/ } +/*?*/ break; +/*?*/ default: +/*?*/ SetError( errUnknownState ); +/*?*/ PushInt(0); +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ // nach dem Laden Asyncs wieder anwerfen +/*?*/ if ( pMyFormulaCell->GetCode()->IsRecalcModeNormal() ) +/*?*/ pMyFormulaCell->GetCode()->SetRecalcModeOnLoad(); +/*?*/ // garantiert identischer Handle bei identischem Aufruf?!? +/*?*/ // sonst schei*e ... +/*?*/ double nErg = 0.0; +/*?*/ ppParam[0] = &nErg; +/*?*/ pFuncData->Call(ppParam); +/*?*/ ULONG nHandle = ULONG( nErg ); +/*?*/ if ( nHandle >= 65536 ) +/*?*/ { +/*?*/ ScAddInAsync* pAs = ScAddInAsync::Get( nHandle ); +/*?*/ if ( !pAs ) +/*?*/ { +/*?*/ pAs = new ScAddInAsync( nHandle, nIndex, pDok ); +/*?*/ pMyFormulaCell->StartListening( *pAs, TRUE ); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ // falls per cut/copy/paste +/*?*/ if ( !pMyFormulaCell->IsListening( *pAs ) ) +/*?*/ pMyFormulaCell->StartListening( *pAs, TRUE ); +/*?*/ // in anderes Dokument? +/*?*/ if ( !pAs->HasDocument( pDok ) ) +/*?*/ pAs->AddDocument( pDok ); +/*?*/ } +/*?*/ if ( pAs->IsValid() ) +/*?*/ { +/*?*/ switch ( pAs->GetType() ) +/*?*/ { +/*?*/ case PTR_DOUBLE : +/*?*/ PushDouble( pAs->GetValue() ); +/*?*/ break; +/*?*/ case PTR_STRING : +/*?*/ PushString( pAs->GetString() ); +/*?*/ break; +/*?*/ default: +/*?*/ SetError( errUnknownState ); +/*?*/ PushInt(0); +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ SetNV(); +/*?*/ } +/*?*/ else +/*?*/ SetNoValue(); +/*?*/ } +/*?*/ } +/*?*/ +/*?*/ for (i = 0; i < MAXFUNCPARAM; i++) +/*?*/ { +/*?*/ delete[] pStr[i]; +/*?*/ delete[] pCellArr[i]; +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ while( nParamCount-- ) +/*?*/ Pop(); +/*?*/ SetError(errIllegalParameter); +/*?*/ PushInt(0); +/*?*/ } +/*N*/ } +/*N*/ else if ( ( aUnoName = ScGlobal::GetAddInCollection()->FindFunction(aFuncName, FALSE) ).Len() ) +/*N*/ { +/*N*/ // bLocalFirst=FALSE in FindFunction, cFunc should be the stored internal name +/*N*/ +/*N*/ ScUnoAddInCall aCall( *ScGlobal::GetAddInCollection(), aUnoName, nParamCount ); +/*N*/ +/*N*/ if ( !aCall.ValidParamCount() ) +/*N*/ SetError( errIllegalParameter ); +/*N*/ +/*N*/ if ( aCall.NeedsCaller() && !GetError() ) +/*N*/ { +/*N*/ SfxObjectShell* pShell = pDok->GetDocumentShell(); +/*N*/ if (pShell) +/*N*/ aCall.SetCallerFromObjectShell( pShell ); +/*N*/ else +/*N*/ { +/*?*/ // use temporary model object (without document) to supply options +/*?*/ aCall.SetCaller( static_cast<beans::XPropertySet*>( +/*?*/ new ScDocOptionsObj( pDok->GetDocOptions() ) ) ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ short nPar = nParamCount; +/*N*/ while ( nPar && !GetError() ) +/*N*/ { +/*N*/ --nPar; // 0 .. (nParamCount-1) +/*N*/ +/*N*/ ScAddInArgumentType eType = aCall.GetArgType( nPar ); +/*N*/ BYTE nStackType = GetStackType(); +/*N*/ +/*N*/ uno::Any aParam; +/*N*/ switch (eType) +/*N*/ { +/*N*/ case SC_ADDINARG_INTEGER: +/*N*/ { +/*N*/ double fVal = GetDouble(); +/*N*/ double fInt = (fVal >= 0.0) ? ::rtl::math::approxFloor( fVal ) : +/*N*/ ::rtl::math::approxCeil( fVal ); +/*N*/ if ( fInt >= LONG_MIN && fInt <= LONG_MAX ) +/*N*/ aParam <<= (INT32)fInt; +/*N*/ else +/*N*/ SetError(errIllegalArgument); +/*N*/ } +/*N*/ break; +/*N*/ +/*?*/ case SC_ADDINARG_DOUBLE: +/*?*/ aParam <<= (double) GetDouble(); +/*?*/ break; +/*?*/ +/*?*/ case SC_ADDINARG_STRING: +/*?*/ aParam <<= ::rtl::OUString( GetString() ); +/*?*/ break; +/*?*/ +/*?*/ case SC_ADDINARG_INTEGER_ARRAY: +/*?*/ switch( nStackType ) +/*?*/ { +/*?*/ case svDouble: +/*?*/ case svString: +/*?*/ case svSingleRef: +/*?*/ { +/*?*/ double fVal = GetDouble(); +/*?*/ double fInt = (fVal >= 0.0) ? ::rtl::math::approxFloor( fVal ) : +/*?*/ ::rtl::math::approxCeil( fVal ); +/*?*/ if ( fInt >= LONG_MIN && fInt <= LONG_MAX ) +/*?*/ { +/*?*/ INT32 nIntVal = (long)fInt; +/*?*/ uno::Sequence<INT32> aInner( &nIntVal, 1 ); +/*?*/ uno::Sequence< uno::Sequence<INT32> > aOuter( &aInner, 1 ); +/*?*/ aParam <<= aOuter; +/*?*/ } +/*?*/ else +/*?*/ SetError(errIllegalArgument); +/*?*/ } +/*?*/ break; +/*?*/ case svDoubleRef: +/*?*/ { +/*?*/ ScRange aRange; +/*?*/ PopDoubleRef( aRange ); +/*?*/ if (!ScRangeToSequence::FillLongArray( aParam, pDok, aRange )) +/*?*/ SetError(errIllegalParameter); +/*?*/ } +/*?*/ break; +/*?*/ case svMatrix: +/*?*/ if (!ScRangeToSequence::FillLongArray( aParam, PopMatrix() )) +/*?*/ SetError(errIllegalParameter); +/*?*/ break; +/*?*/ default: +/*?*/ Pop(); +/*?*/ SetError(errIllegalParameter); +/*?*/ } +/*?*/ break; +/*?*/ +/*?*/ case SC_ADDINARG_DOUBLE_ARRAY: +/*?*/ switch( nStackType ) +/*?*/ { +/*?*/ case svDouble: +/*?*/ case svString: +/*?*/ case svSingleRef: +/*?*/ { +/*?*/ double fVal = GetDouble(); +/*?*/ uno::Sequence<double> aInner( &fVal, 1 ); +/*?*/ uno::Sequence< uno::Sequence<double> > aOuter( &aInner, 1 ); +/*?*/ aParam <<= aOuter; +/*?*/ } +/*?*/ break; +/*?*/ case svDoubleRef: +/*?*/ { +/*?*/ ScRange aRange; +/*?*/ PopDoubleRef( aRange ); +/*?*/ if (!ScRangeToSequence::FillDoubleArray( aParam, pDok, aRange )) +/*?*/ SetError(errIllegalParameter); +/*?*/ } +/*?*/ break; +/*?*/ case svMatrix: +/*?*/ if (!ScRangeToSequence::FillDoubleArray( aParam, PopMatrix() )) +/*?*/ SetError(errIllegalParameter); +/*?*/ break; +/*?*/ default: +/*?*/ Pop(); +/*?*/ SetError(errIllegalParameter); +/*?*/ } +/*?*/ break; +/*?*/ +/*?*/ case SC_ADDINARG_STRING_ARRAY: +/*?*/ switch( nStackType ) +/*?*/ { +/*?*/ case svDouble: +/*?*/ case svString: +/*?*/ case svSingleRef: +/*?*/ { +/*?*/ ::rtl::OUString aString = ::rtl::OUString( GetString() ); +/*?*/ uno::Sequence<rtl::OUString> aInner( &aString, 1 ); +/*?*/ uno::Sequence< uno::Sequence<rtl::OUString> > aOuter( &aInner, 1 ); +/*?*/ aParam <<= aOuter; +/*?*/ } +/*?*/ break; +/*?*/ case svDoubleRef: +/*?*/ { +/*?*/ ScRange aRange; +/*?*/ PopDoubleRef( aRange ); +/*?*/ if (!ScRangeToSequence::FillStringArray( aParam, pDok, aRange )) +/*?*/ SetError(errIllegalParameter); +/*?*/ } +/*?*/ break; +/*?*/ case svMatrix: +/*?*/ if (!ScRangeToSequence::FillStringArray( aParam, PopMatrix(), pFormatter )) +/*?*/ SetError(errIllegalParameter); +/*?*/ break; +/*?*/ default: +/*?*/ Pop(); +/*?*/ SetError(errIllegalParameter); +/*?*/ } +/*?*/ break; +/*?*/ +/*?*/ case SC_ADDINARG_MIXED_ARRAY: +/*?*/ switch( nStackType ) +/*?*/ { +/*?*/ case svDouble: +/*?*/ case svString: +/*?*/ case svSingleRef: +/*?*/ { +/*?*/ uno::Any aElem; +/*?*/ if ( nStackType == svDouble ) +/*?*/ aElem <<= (double) GetDouble(); +/*?*/ else if ( nStackType == svString ) +/*?*/ aElem <<= ::rtl::OUString( GetString() ); +/*?*/ else +/*?*/ { +/*?*/ ScAddress aAdr; +/*?*/ if ( PopDoubleRefOrSingleRef( aAdr ) ) +/*?*/ { +/*?*/ ScBaseCell* pCell = GetCell( aAdr ); +/*?*/ if ( pCell && pCell->HasStringData() ) +/*?*/ { +/*?*/ String aStr; +/*?*/ GetCellString( aStr, pCell ); +/*?*/ aElem <<= ::rtl::OUString( aStr ); +/*?*/ } +/*?*/ else +/*?*/ aElem <<= (double) GetCellValue( aAdr, pCell ); +/*?*/ } +/*?*/ } +/*?*/ uno::Sequence<uno::Any> aInner( &aElem, 1 ); +/*?*/ uno::Sequence< uno::Sequence<uno::Any> > aOuter( &aInner, 1 ); +/*?*/ aParam <<= aOuter; +/*?*/ } +/*?*/ break; +/*?*/ case svDoubleRef: +/*?*/ { +/*?*/ ScRange aRange; +/*?*/ PopDoubleRef( aRange ); +/*?*/ if (!ScRangeToSequence::FillMixedArray( aParam, pDok, aRange )) +/*?*/ SetError(errIllegalParameter); +/*?*/ } +/*?*/ break; +/*?*/ case svMatrix: +/*?*/ if (!ScRangeToSequence::FillMixedArray( aParam, PopMatrix() )) +/*?*/ SetError(errIllegalParameter); +/*?*/ break; +/*?*/ default: +/*?*/ Pop(); +/*?*/ SetError(errIllegalParameter); +/*?*/ } +/*?*/ break; +/*?*/ +/*?*/ case SC_ADDINARG_VALUE_OR_ARRAY: +/*?*/ switch( nStackType ) +/*?*/ { +/*?*/ case svDouble: +/*?*/ aParam <<= (double) GetDouble(); +/*?*/ break; +/*?*/ case svString: +/*?*/ aParam <<= ::rtl::OUString( GetString() ); +/*?*/ break; +/*?*/ case svSingleRef: +/*?*/ { +/*?*/ ScAddress aAdr; +/*?*/ if ( PopDoubleRefOrSingleRef( aAdr ) ) +/*?*/ { +/*?*/ ScBaseCell* pCell = GetCell( aAdr ); +/*?*/ if ( pCell && pCell->HasStringData() ) +/*?*/ { +/*?*/ String aStr; +/*?*/ GetCellString( aStr, pCell ); +/*?*/ aParam <<= ::rtl::OUString( aStr ); +/*?*/ } +/*?*/ else +/*?*/ aParam <<= (double) GetCellValue( aAdr, pCell ); +/*?*/ } +/*?*/ } +/*?*/ break; +/*?*/ case svDoubleRef: +/*?*/ { +/*?*/ ScRange aRange; +/*?*/ PopDoubleRef( aRange ); +/*?*/ if (!ScRangeToSequence::FillMixedArray( aParam, pDok, aRange )) +/*?*/ SetError(errIllegalParameter); +/*?*/ } +/*?*/ break; +/*?*/ case svMatrix: +/*?*/ if (!ScRangeToSequence::FillMixedArray( aParam, PopMatrix() )) +/*?*/ SetError(errIllegalParameter); +/*?*/ break; +/*?*/ default: +/*?*/ Pop(); +/*?*/ SetError(errIllegalParameter); +/*?*/ } +/*?*/ break; +/*?*/ +/*?*/ case SC_ADDINARG_CELLRANGE: +/*?*/ switch( nStackType ) +/*?*/ { +/*?*/ case svSingleRef: +/*?*/ { +/*?*/ ScAddress aAdr; +/*?*/ PopSingleRef( aAdr ); +/*?*/ ScRange aRange( aAdr ); +/*?*/ uno::Reference<table::XCellRange> xObj = +/*?*/ ScCellRangeObj::CreateRangeFromDoc( pDok, aRange ); +/*?*/ if (xObj.is()) +/*?*/ aParam <<= xObj; +/*?*/ else +/*?*/ SetError(errIllegalParameter); +/*?*/ } +/*?*/ break; +/*?*/ case svDoubleRef: +/*?*/ { +/*?*/ ScRange aRange; +/*?*/ PopDoubleRef( aRange ); +/*?*/ uno::Reference<table::XCellRange> xObj = +/*?*/ ScCellRangeObj::CreateRangeFromDoc( pDok, aRange ); +/*?*/ if (xObj.is()) +/*?*/ aParam <<= xObj; +/*?*/ else +/*?*/ SetError(errIllegalParameter); +/*?*/ } +/*?*/ break; +/*?*/ default: +/*?*/ Pop(); +/*?*/ SetError(errIllegalParameter); +/*?*/ } +/*?*/ break; +/*?*/ +/*?*/ default: +/*?*/ Pop(); +/*?*/ SetError(errIllegalParameter); +/*N*/ } +/*N*/ aCall.SetParam( nPar, aParam ); +/*N*/ } +/*N*/ +/*N*/ while (nPar--) +/*?*/ Pop(); // in case of error, remove remaining args +/*N*/ +/*N*/ if ( !GetError() ) +/*N*/ { +/*N*/ aCall.ExecuteCall(); +/*N*/ +/*N*/ if ( aCall.HasVarRes() ) // handle async functions +/*N*/ { +/*?*/ if ( pMyFormulaCell->GetCode()->IsRecalcModeNormal() ) +/*?*/ pMyFormulaCell->GetCode()->SetRecalcModeOnLoad(); +/*?*/ +/*?*/ uno::Reference<sheet::XVolatileResult> xResult = aCall.GetVarRes(); +/*?*/ ScAddInListener* pLis = ScAddInListener::Get( xResult ); +/*?*/ if ( !pLis ) +/*?*/ { +/*?*/ pLis = ScAddInListener::CreateListener( xResult, pDok ); +/*?*/ pMyFormulaCell->StartListening( *pLis, TRUE ); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ if ( !pMyFormulaCell->IsListening( *pLis ) ) +/*?*/ pMyFormulaCell->StartListening( *pLis, TRUE ); +/*?*/ if ( !pLis->HasDocument( pDok ) ) +/*?*/ pLis->AddDocument( pDok ); +/*?*/ } +/*?*/ +/*?*/ aCall.SetResult( pLis->GetResult() ); // use result from async +/*N*/ } +/*N*/ +/*N*/ if ( aCall.GetErrCode() ) +/*N*/ { +/*?*/ SetError( aCall.GetErrCode() ); +/*?*/ PushInt(0); +/*N*/ } +/*N*/ else if ( aCall.HasMatrix() ) +/*N*/ { +/*?*/ const ScMatrix* pLinkMat = aCall.GetMatrix(); // not NULL +/*?*/ +/*?*/ USHORT nC, nR, nMatInd; // copy matrix result +/*?*/ pLinkMat->GetDimensions(nC, nR); +/*?*/ ScMatrix* pNewMat = GetNewMat( nC, nR, nMatInd ); +/*?*/ if (pNewMat) +/*?*/ { +/*?*/ pLinkMat->MatCopy(*pNewMat); +/*?*/ PushMatrix( pNewMat ); +/*?*/ nRetMat = nMatInd; +/*?*/ } // otherwise error code has been set in GetNewMat +/*N*/ } +/*N*/ else if ( aCall.HasString() ) +/*?*/ PushString( aCall.GetString() ); +/*N*/ else +/*N*/ PushDouble( aCall.GetValue() ); +/*N*/ } +/*N*/ else // error... +/*?*/ PushInt(0); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ while( nParamCount-- ) +/*N*/ Pop(); +/*N*/ SetError( errNoAddin ); +/*N*/ PushInt(0); +/*N*/ } +/*N*/ } + + +void ScInterpreter::ScMissing() +{ + PushTempToken( new ScMissingToken ); +} + + +/*N*/ void ScInterpreter::ScMacro() +/*N*/ { +/*N*/ SbxBase::ResetError(); +/*N*/ +/*N*/ BYTE nParamCount = GetByte(); +/*N*/ String aMacro( pCur->GetExternal() ); +/*N*/ +/*N*/ SfxObjectShell* pDocSh = pDok->GetDocumentShell(); +/*N*/ if ( !pDocSh || !pDok->CheckMacroWarn() ) +/*N*/ { +/*N*/ SetError( errNoValue ); // ohne DocShell kein CallBasic +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ // keine Sicherheitsabfrage mehr vorneweg (nur CheckMacroWarn), das passiert im CallBasic +/*N*/ +/*N*/ SfxApplication* pSfxApp = SFX_APP(); +/*N*/ pSfxApp->EnterBasicCall(); // Dok-Basic anlegen etc. +/*N*/ +/*N*/ // Wenn das Dok waehrend eines Basic-Calls geladen wurde, +/*N*/ // ist das Sbx-Objekt evtl. nicht angelegt (?) +/*N*/ // pDocSh->GetSbxObject(); +/*N*/ +/*N*/ // Funktion ueber den einfachen Namen suchen, +/*N*/ // dann aBasicStr, aMacroStr fuer SfxObjectShell::CallBasic zusammenbauen +/*N*/ +/*N*/ StarBASIC* pRoot = pDocSh->GetBasic(); +/*N*/ SbxVariable* pVar = pRoot->Find( aMacro, SbxCLASS_METHOD ); +/*N*/ if( !pVar || pVar->GetType() == SbxVOID || !pVar->ISA(SbMethod) ) +/*N*/ { +/*?*/ SetError( errNoMacro ); +/*?*/ pSfxApp->LeaveBasicCall(); +/*?*/ return; +/*N*/ } +/*N*/ +/*N*/ SbMethod* pMethod = (SbMethod*)pVar; +/*N*/ SbModule* pModule = pMethod->GetModule(); +/*N*/ SbxObject* pObject = pModule->GetParent(); +/*N*/ DBG_ASSERT(pObject->IsA(TYPE(StarBASIC)), "Kein Basic gefunden!"); +/*N*/ String aMacroStr = pObject->GetName(); +/*N*/ aMacroStr += '.'; +/*N*/ aMacroStr += pModule->GetName(); +/*N*/ aMacroStr += '.'; +/*N*/ aMacroStr += pMethod->GetName(); +/*N*/ String aBasicStr; +/*N*/ if (pObject->GetParent()) +/*N*/ aBasicStr = pObject->GetParent()->GetName(); // Dokumentenbasic +/*N*/ else +/*?*/ aBasicStr = SFX_APP()->GetName(); // Applikationsbasic +/*N*/ +/*N*/ // Parameter-Array zusammenbauen +/*N*/ +/*N*/ SbxArrayRef refPar = new SbxArray; +/*N*/ BOOL bOk = TRUE; +/*N*/ for( short i = nParamCount; i && bOk ; i-- ) +/*N*/ { +/*N*/ SbxVariable* pPar = refPar->Get( (USHORT) i ); +/*N*/ BYTE nStackType = GetStackType(); +/*N*/ switch( nStackType ) +/*N*/ { +/*?*/ case svDouble: +/*?*/ pPar->PutDouble( GetDouble() ); +/*?*/ break; +/*?*/ case svString: +/*?*/ pPar->PutString( GetString() ); +/*?*/ break; +/*N*/ case svSingleRef: +/*N*/ { +/*N*/ ScAddress aAdr; +/*N*/ PopSingleRef( aAdr ); +/*N*/ bOk = SetSbxVariable( pPar, aAdr ); +/*N*/ } +/*N*/ break; +/*?*/ case svDoubleRef: +/*?*/ { +/*?*/ USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; +/*?*/ PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); +/*?*/ if( nTab1 != nTab2 ) +/*?*/ { +/*?*/ SetError( errIllegalParameter ); +/*?*/ bOk = FALSE; +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ SbxDimArrayRef refArray = new SbxDimArray; +/*?*/ refArray->AddDim( 1, nRow2 - nRow1 + 1 ); +/*?*/ refArray->AddDim( 1, nCol2 - nCol1 + 1 ); +/*?*/ ScAddress aAdr( nCol1, nRow1, nTab1 ); +/*?*/ for( USHORT nRow = nRow1; bOk && nRow <= nRow2; nRow++ ) +/*?*/ { +/*?*/ aAdr.SetRow( nRow ); +/*?*/ short nIdx[ 2 ]; +/*?*/ nIdx[ 0 ] = nRow-nRow1+1; +/*?*/ for( USHORT nCol = nCol1; bOk && nCol <= nCol2; nCol++ ) +/*?*/ { +/*?*/ aAdr.SetCol( nCol ); +/*?*/ nIdx[ 1 ] = nCol-nCol1+1; +/*?*/ SbxVariable* p = refArray->Get( nIdx ); +/*?*/ bOk = SetSbxVariable( p, aAdr ); +/*?*/ } +/*?*/ } +/*?*/ pPar->PutObject( refArray ); +/*?*/ } +/*?*/ } +/*?*/ break; +/*?*/ case svMatrix: +/*?*/ { +/*?*/ ScMatrix* pMat = PopMatrix(); +/*?*/ USHORT nC, nR; +/*?*/ if (pMat) +/*?*/ { +/*?*/ pMat->GetDimensions(nC, nR); +/*?*/ SbxDimArrayRef refArray = new SbxDimArray; +/*?*/ refArray->AddDim( 1, nR ); +/*?*/ refArray->AddDim( 1, nC ); +/*?*/ for( USHORT j = 0; j < nR; j++ ) +/*?*/ { +/*?*/ short nIdx[ 2 ]; +/*?*/ nIdx[ 0 ] = j+1; +/*?*/ for( USHORT i = 0; i < nC; i++ ) +/*?*/ { +/*?*/ nIdx[ 1 ] = i+1; +/*?*/ SbxVariable* p = refArray->Get( nIdx ); +/*?*/ if (pMat->IsString(i, j)) +/*?*/ p->PutString( pMat->GetString(i, j) ); +/*?*/ else +/*?*/ p->PutDouble( pMat->GetDouble(i, j) ); +/*?*/ } +/*?*/ } +/*?*/ pPar->PutObject( refArray ); +/*?*/ } +/*?*/ else +/*?*/ SetError( errIllegalParameter ); +/*?*/ } +/*?*/ break; +/*?*/ default: +/*N*/ SetError( errIllegalParameter ); +/*N*/ bOk = FALSE; +/*N*/ } +/*N*/ } +/*N*/ if( bOk ) +/*N*/ { +/*N*/ pDok->LockTable( aPos.Tab() ); +/*N*/ SbxVariableRef refRes = new SbxVariable; +/*N*/ pDok->IncMacroInterpretLevel(); +/*N*/ ErrCode eRet = pDocSh->CallBasic( aMacroStr, aBasicStr, NULL, refPar, refRes ); +/*N*/ pDok->DecMacroInterpretLevel(); +/*N*/ pDok->UnlockTable( aPos.Tab() ); +/*N*/ +/*N*/ SbxDataType eResType = refRes->GetType(); +/*N*/ if ( eRet != ERRCODE_NONE ) +/*N*/ SetNoValue(); +/*N*/ else if( eResType >= SbxINTEGER && eResType <= SbxDOUBLE ) +/*?*/ PushDouble( refRes->GetDouble() ); +/*N*/ else if ( eResType & SbxARRAY ) +/*N*/ { +/*?*/ SbxBase* pElemObj = refRes->GetObject(); +/*?*/ SbxDimArray* pDimArray = PTR_CAST(SbxDimArray,pElemObj); +/*?*/ short nDim = pDimArray->GetDims(); +/*?*/ if ( 1 <= nDim && nDim <= 2 ) +/*?*/ { +/*?*/ short nCs, nCe, nRs, nRe; +/*?*/ USHORT nC, nR, nMatInd; +/*?*/ USHORT nColIdx, nRowIdx; +/*?*/ if ( nDim == 1 ) +/*?*/ { // array( cols ) eine Zeile, mehrere Spalten +/*?*/ pDimArray->GetDim( 1, nCs, nCe ); +/*?*/ nC = USHORT(nCe - nCs + 1); +/*?*/ nRs = nRe = 0; +/*?*/ nR = 1; +/*?*/ nColIdx = 0; +/*?*/ nRowIdx = 1; +/*?*/ } +/*?*/ else +/*?*/ { // array( rows, cols ) +/*?*/ pDimArray->GetDim( 1, nRs, nRe ); +/*?*/ nR = USHORT(nRe - nRs + 1); +/*?*/ pDimArray->GetDim( 2, nCs, nCe ); +/*?*/ nC = USHORT(nCe - nCs + 1); +/*?*/ nColIdx = 1; +/*?*/ nRowIdx = 0; +/*?*/ } +/*?*/ ScMatrix* pMat = GetNewMat( nC, nR, nMatInd ); +/*?*/ if ( pMat ) +/*?*/ { +/*?*/ SbxVariable* pV; +/*?*/ SbxDataType eType; +/*?*/ for ( USHORT j=0; j < nR; j++ ) +/*?*/ { +/*?*/ short nIdx[ 2 ]; +/*?*/ // bei eindimensionalem array( cols ) wird nIdx[1] +/*?*/ // von SbxDimArray::Get ignoriert +/*?*/ nIdx[ nRowIdx ] = nRs + j; +/*?*/ for ( USHORT i=0; i < nC; i++ ) +/*?*/ { +/*?*/ nIdx[ nColIdx ] = nCs + i; +/*?*/ pV = pDimArray->Get( nIdx ); +/*?*/ eType = pV->GetType(); +/*?*/ if ( eType >= SbxINTEGER && eType <= SbxDOUBLE ) +/*?*/ pMat->PutDouble( pV->GetDouble(), i, j ); +/*?*/ else +/*?*/ pMat->PutString( pV->GetString(), i, j ); +/*?*/ } +/*?*/ } +/*?*/ PushMatrix( pMat ); +/*?*/ nRetMat = nMatInd; +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ SetNoValue(); +/*N*/ } +/*N*/ else +/*?*/ PushString( refRes->GetString() ); +/*N*/ if( pVar->GetError() ) +/*?*/ SetNoValue(); +/*N*/ } +/*N*/ +/*N*/ pSfxApp->LeaveBasicCall(); +/*N*/ } + + +/*N*/ BOOL ScInterpreter::SetSbxVariable( SbxVariable* pVar, const ScAddress& rPos ) +/*N*/ { +/*N*/ BOOL bOk = TRUE; +/*N*/ ScBaseCell* pCell = pDok->GetCell( rPos ); +/*N*/ if (pCell) +/*N*/ { +/*N*/ USHORT nErr; +/*N*/ double nVal; +/*N*/ switch( pCell->GetCellType() ) +/*N*/ { +/*N*/ case CELLTYPE_VALUE : +/*N*/ nVal = GetValueCellValue( rPos, (ScValueCell*)pCell ); +/*N*/ pVar->PutDouble( nVal ); +/*N*/ break; +/*N*/ case CELLTYPE_STRING : +/*N*/ { +/*N*/ String aVal; +/*N*/ ((ScStringCell*)pCell)->GetString( aVal ); +/*N*/ pVar->PutString( aVal ); +/*N*/ break; +/*N*/ } +/*?*/ case CELLTYPE_EDIT : +/*?*/ { +/*?*/ String aVal; +/*?*/ ((ScEditCell*) pCell)->GetString( aVal ); +/*?*/ pVar->PutString( aVal ); +/*?*/ break; +/*?*/ } +/*N*/ case CELLTYPE_FORMULA : +/*N*/ nErr = ((ScFormulaCell*)pCell)->GetErrCode(); +/*N*/ if( !nErr ) +/*N*/ { +/*N*/ if( ((ScFormulaCell*)pCell)->IsValue() ) +/*N*/ { +/*N*/ nVal = ((ScFormulaCell*)pCell)->GetValue(); +/*N*/ pVar->PutDouble( nVal ); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ String aVal; +/*?*/ ((ScFormulaCell*)pCell)->GetString( aVal ); +/*?*/ pVar->PutString( aVal ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ SetError( nErr ), bOk = FALSE; +/*N*/ break; +/*?*/ default : +/*?*/ pVar->PutDouble( 0.0 ); +/*N*/ } +/*N*/ } +/*N*/ else +/*?*/ pVar->PutDouble( 0.0 ); +/*N*/ return bOk; +/*N*/ } + + +/*N*/ void ScInterpreter::ScTableOp() +/*N*/ { +/*N*/ BYTE nParamCount = GetByte(); +/*N*/ if (nParamCount != 3 && nParamCount != 5) +/*N*/ { +/*N*/ SetIllegalParameter(); +/*N*/ return; +/*N*/ } +/*N*/ ScInterpreterTableOpParams* pTableOp = new ScInterpreterTableOpParams; +/*N*/ if (nParamCount == 5) +/*N*/ { +/*N*/ PopSingleRef( pTableOp->aNew2 ); +/*N*/ PopSingleRef( pTableOp->aOld2 ); +/*N*/ } +/*N*/ PopSingleRef( pTableOp->aNew1 ); +/*N*/ PopSingleRef( pTableOp->aOld1 ); +/*N*/ PopSingleRef( pTableOp->aFormulaPos ); +/*N*/ +/*N*/ pTableOp->bValid = TRUE; +/*N*/ pDok->aTableOpList.Insert( pTableOp ); +/*N*/ pDok->IncInterpreterTableOpLevel(); +/*N*/ +/*N*/ BOOL bReuseLastParams = (pDok->aLastTableOpParams == *pTableOp); +/*N*/ if ( bReuseLastParams ) +/*N*/ { +/*N*/ pTableOp->aNotifiedFormulaPos = pDok->aLastTableOpParams.aNotifiedFormulaPos; +/*N*/ pTableOp->bRefresh = TRUE; +/*N*/ for ( ::std::vector< ScAddress >::const_iterator iBroadcast( +/*N*/ pTableOp->aNotifiedFormulaPos.begin() ); +/*N*/ iBroadcast != pTableOp->aNotifiedFormulaPos.end(); +/*N*/ ++iBroadcast ) +/*N*/ { // emulate broadcast and indirectly collect cell pointers +/*N*/ ScBaseCell* pCell = pDok->GetCell( *iBroadcast ); +/*N*/ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA ) +/*N*/ ((ScFormulaCell*)pCell)->SetTableOpDirty(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { // broadcast and indirectly collect cell pointers and positions +/*N*/ pDok->SetTableOpDirty( pTableOp->aOld1 ); +/*N*/ if ( nParamCount == 5 ) +/*N*/ pDok->SetTableOpDirty( pTableOp->aOld2 ); +/*N*/ } +/*N*/ pTableOp->bCollectNotifications = FALSE; +/*N*/ +/*N*/ ScBaseCell* pFCell = pDok->GetCell( pTableOp->aFormulaPos ); +/*N*/ if ( pFCell && pFCell->GetCellType() == CELLTYPE_FORMULA ) +/*N*/ ((ScFormulaCell*)pFCell)->SetDirtyVar(); +/*N*/ if ( HasCellValueData( pFCell ) ) +/*N*/ PushDouble( GetCellValue( pTableOp->aFormulaPos, pFCell )); +/*N*/ else +/*N*/ { +/*N*/ String aCellString; +/*N*/ GetCellString( aCellString, pFCell ); +/*N*/ PushString( aCellString ); +/*N*/ } +/*N*/ +/*N*/ pDok->aTableOpList.Remove( pTableOp ); +/*N*/ // set dirty again once more to be able to recalculate original +/*N*/ for ( ::std::vector< ScFormulaCell* >::const_iterator iBroadcast( +/*N*/ pTableOp->aNotifiedFormulaCells.begin() ); +/*N*/ iBroadcast != pTableOp->aNotifiedFormulaCells.end(); +/*N*/ ++iBroadcast ) +/*N*/ { +/*N*/ (*iBroadcast)->SetTableOpDirty(); +/*N*/ } +/*N*/ +/*N*/ // save these params for next incarnation +/*N*/ if ( !bReuseLastParams ) +/*N*/ pDok->aLastTableOpParams = *pTableOp; +/*N*/ +/*N*/ if ( pFCell && pFCell->GetCellType() == CELLTYPE_FORMULA ) +/*N*/ { +/*N*/ ((ScFormulaCell*)pFCell)->SetDirtyVar(); +/*N*/ ((ScFormulaCell*)pFCell)->GetErrCode(); // recalculate original +/*N*/ } +/*N*/ +/*N*/ // Reset all dirty flags so next incarnation does really collect all cell +/*N*/ // pointers during notifications and not just non-dirty ones, which may +/*N*/ // happen if a formula cell is used by more than one TableOp block. +/*N*/ for ( ::std::vector< ScFormulaCell* >::const_iterator iBroadcast2( +/*N*/ pTableOp->aNotifiedFormulaCells.begin() ); +/*N*/ iBroadcast2 != pTableOp->aNotifiedFormulaCells.end(); +/*N*/ ++iBroadcast2 ) +/*N*/ { +/*N*/ (*iBroadcast2)->ResetTableOpDirtyVar(); +/*N*/ } +/*N*/ delete pTableOp; +/*N*/ +/*N*/ pDok->DecInterpreterTableOpLevel(); +/*N*/ } + +void ScInterpreter::ScDBArea() +{ + ScDBData* pDBData = pDok->GetDBCollection()->FindIndex( pCur->GetIndex()); + if (pDBData) + { + ComplRefData aRefData; + aRefData.InitFlags(); + pDBData->GetArea( (USHORT&) aRefData.Ref1.nTab, + (USHORT&) aRefData.Ref1.nCol, + (USHORT&) aRefData.Ref1.nRow, + (USHORT&) aRefData.Ref2.nCol, + (USHORT&) aRefData.Ref2.nRow); + aRefData.Ref2.nTab = aRefData.Ref1.nTab; + aRefData.CalcRelFromAbs( aPos ); + PushTempToken( new ScDoubleRefToken( aRefData ) ); + } + else + SetError(errNoName); +} + + +void ScInterpreter::ScColRowNameAuto() +{ + ComplRefData aRefData( pCur->GetDoubleRef() ); + aRefData.CalcAbsIfRel( aPos ); + if ( aRefData.Valid() ) + { + INT16 nStartCol, nStartRow, nCol2, nRow2; + // evtl. Begrenzung durch definierte ColRowNameRanges merken + nCol2 = aRefData.Ref2.nCol; + nRow2 = aRefData.Ref2.nRow; + // DataArea der ersten Zelle + nStartCol = aRefData.Ref2.nCol = aRefData.Ref1.nCol; + nStartRow = aRefData.Ref2.nRow = aRefData.Ref1.nRow; + aRefData.Ref2.nTab = aRefData.Ref1.nTab; + pDok->GetDataArea( (USHORT) aRefData.Ref1.nTab, + (USHORT&) aRefData.Ref1.nCol, + (USHORT&) aRefData.Ref1.nRow, + (USHORT&) aRefData.Ref2.nCol, + (USHORT&) aRefData.Ref2.nRow, + TRUE ); + // DataArea im Ursprung begrenzen + aRefData.Ref1.nCol = nStartCol; + aRefData.Ref1.nRow = nStartRow; + + //! korrespondiert mit ScCompiler::GetToken + if ( aRefData.Ref1.IsColRel() ) + { // ColName + aRefData.Ref2.nCol = nStartCol; + // evtl. vorherige Begrenzung durch definierte ColRowNameRanges erhalten + if ( aRefData.Ref2.nRow > nRow2 ) + aRefData.Ref2.nRow = nRow2; + USHORT nMyRow; + if ( aPos.Col() == nStartCol + && nStartRow <= (nMyRow = aPos.Row()) && nMyRow <= aRefData.Ref2.nRow ) + { // Formel in gleicher Spalte und innerhalb des Range + if ( nMyRow == nStartRow ) + { // direkt unter dem Namen den Rest nehmen + nStartRow++; + if ( nStartRow > MAXROW ) + nStartRow = MAXROW; + aRefData.Ref1.nRow = nStartRow; + } + else + { // weiter unten vom Namen bis zur Formelzelle + aRefData.Ref2.nRow = nMyRow - 1; + } + } + } + else + { // RowName + aRefData.Ref2.nRow = nStartRow; + // evtl. vorherige Begrenzung durch definierte ColRowNameRanges erhalten + if ( aRefData.Ref2.nCol > nCol2 ) + aRefData.Ref2.nCol = nCol2; + USHORT nMyCol; + if ( aPos.Row() == nStartRow + && nStartCol <= (nMyCol = aPos.Col()) && nMyCol <= aRefData.Ref2.nCol ) + { // Formel in gleicher Zeile und innerhalb des Range + if ( nMyCol == nStartCol ) + { // direkt neben dem Namen den Rest nehmen + nStartCol++; + if ( nStartCol > MAXCOL ) + nStartCol = MAXCOL; + aRefData.Ref1.nCol = nStartCol; + } + else + { // weiter rechts vom Namen bis zur Formelzelle + aRefData.Ref2.nCol = nMyCol - 1; + } + } + } + aRefData.CalcRelFromAbs( aPos ); + } + else + SetError( errNoRef ); + PushTempToken( new ScDoubleRefToken( aRefData ) ); +} + +// --- internals ------------------------------------------------------------ + + +void ScInterpreter::ScAnswer() +{ + String aStr( GetString() ); + if( aStr.EqualsIgnoreCaseAscii( "Das Leben, das Universum und der ganze Rest" ) ) + { + PushInt( 42 ); + bOderSo = TRUE; + } + else + SetNoValue(); +} + + +void ScInterpreter::ScCalcTeam() +{ + static BOOL bShown = FALSE; + if( !bShown ) + { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 ShowTheTeam(); +/*N*/ String aTeam( RTL_CONSTASCII_USTRINGPARAM( "Ballach, Nebel, Rentz, Rathke, Marmion" ) ); +/*N*/ if ( (GetByte() == 1) && ::rtl::math::approxEqual( GetDouble(), 1996) ) +/*N*/ /*?*/ aTeam.AppendAscii( " (a word with 'B': -Olk, -Nietsch, -Daeumling)" ); +/*N*/ /*?*/ PushString( aTeam ); +/*N*/ /*?*/ bShown = TRUE; + } + else + PushInt( 42 ); +} + + +void ScInterpreter::ScSpewFunc() +{ + BOOL bRefresh = FALSE; + BOOL bClear = FALSE; + // Stack aufraeumen + BYTE nParamCount = GetByte(); + while ( nParamCount-- ) + { + switch ( GetStackType() ) + { + case svString: + case svSingleRef: + case svDoubleRef: + { + const sal_Unicode ch = GetString().GetChar(0); + if ( !bRefresh && ch < 256 ) + bRefresh = (tolower( (sal_uChar) ch ) == 'r'); + if ( !bClear && ch < 256 ) + bClear = (tolower( (sal_uChar) ch ) == 'c'); + } + break; + default: + Pop(); + } + } + String aStr; +#if SC_SPEW_ENABLED + if ( bRefresh ) + theSpew.Clear(); // GetSpew liest SpewRulesFile neu + theSpew.GetSpew( aStr ); + if ( bClear ) + theSpew.Clear(); // release Memory + xub_StrLen nPos = 0; + while ( (nPos = aStr.SearchAndReplace( '\n', ' ', nPos )) != STRING_NOTFOUND ) + nPos++; +#else + aStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "spitted out all spew :-(" ) ); +#endif + PushString( aStr ); +} + + +/*N*/ +/*N*/ //#define SC_INVADER_GPF // GPF wollen wir nicht :-( +/*N*/ // zum testen Environment-Variable SC_INVADER_GPF=xxx setzen +/*N*/ // 08.10.98: wenn PB optpath.cxx gefixt hat geht's wieder +/*N*/ +/*N*/ extern void StartInvader( Window* pParent ); // StarWars, Wrapper in SVX options/optpath.cxx +/*N*/ extern void Game(); // Froggie + +void ScInterpreter::ScTTT() +{ // Temporaerer Test-Tanz, zum auspropieren von Funktionen etc. + BOOL bOk = TRUE; + BYTE nParamCount = GetByte(); + // do something, nParamCount bei Pops runterzaehlen! + + if ( bOk && nParamCount ) + { + bOk = GetBool(); + --nParamCount; + } + // Stack aufraeumen + while ( nParamCount-- ) + Pop(); + static const sal_Unicode __FAR_DATA sEyes[] = { ',',';',':','|','8','B', 0 }; + static const sal_Unicode __FAR_DATA sGoods[] = { ')',']','}', 0 }; + static const sal_Unicode __FAR_DATA sBads[] = { '(','[','{','/', 0 }; + sal_Unicode aFace[4]; + if ( bOk ) + { + aFace[0] = sEyes[ rand() % ((sizeof( sEyes )/sizeof(sal_Unicode)) - 1) ]; + aFace[1] = '-'; + aFace[2] = sGoods[ rand() % ((sizeof( sGoods )/sizeof(sal_Unicode)) - 1) ]; + } + else + { + aFace[0] = ':'; + aFace[1] = '-'; + aFace[2] = sBads[ rand() % ((sizeof( sBads )/sizeof(sal_Unicode)) - 1) ]; + } + aFace[3] = 0; + PushStringBuffer( aFace ); +} + +// ------------------------------------------------------------------------- + + +/*N*/ ScInterpreter::ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, +/*N*/ const ScAddress& rPos, ScTokenArray& r ) : +/*N*/ pMyFormulaCell( pCell ), +/*N*/ pDok( pDoc ), +/*N*/ aCode( r ), +/*N*/ aPos( rPos ), +/*N*/ rArr( r ), +/*N*/ bCalcAsShown( pDoc->GetDocOptions().IsCalcAsShown() ), +/*N*/ pFormatter( pDoc->GetFormatTable() ) +/*N*/ { +/*N*/ // pStack = new ScToken*[ MAXSTACK ]; +/*N*/ +/*N*/ BYTE cMatFlag = pMyFormulaCell->GetMatrixFlag(); +/*N*/ bMatrixFormula = ( cMatFlag == MM_FORMULA || cMatFlag == MM_FAKE ); +/*N*/ if (!bGlobalStackInUse) +/*N*/ { +/*N*/ bGlobalStackInUse = TRUE; +/*N*/ if (!pGlobalStack) +/*N*/ pGlobalStack = new ScTokenStack; +/*N*/ if (!pGlobalErrorStack) +/*N*/ pGlobalErrorStack = new ScErrorStack; +/*N*/ pStackObj = pGlobalStack; +/*N*/ pErrorStackObj = pGlobalErrorStack; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pStackObj = new ScTokenStack; +/*N*/ pErrorStackObj = new ScErrorStack; +/*N*/ } +/*N*/ pStack = pStackObj->pPointer; +/*N*/ pErrorStack = pErrorStackObj->pPointer; +/*N*/ } + + +/*N*/ ScInterpreter::~ScInterpreter() +/*N*/ { +/*N*/ // delete pStack; +/*N*/ +/*N*/ if ( pStackObj == pGlobalStack ) +/*N*/ bGlobalStackInUse = FALSE; +/*N*/ else +/*N*/ { +/*N*/ delete pStackObj; +/*N*/ delete pErrorStackObj; +/*N*/ } +/*N*/ } + + +/*N*/ void ScInterpreter::GlobalExit() // static +/*N*/ { +/*N*/ DBG_ASSERT(!bGlobalStackInUse, "wer benutzt noch den TokenStack?"); +/*N*/ DELETEZ(pGlobalStack); +/*N*/ DELETEZ(pGlobalErrorStack); +/*N*/ } + + +/*N*/ StackVar ScInterpreter::Interpret() +/*N*/ { +/*N*/ short nRetTypeExpr = NUMBERFORMAT_UNDEFINED; +/*N*/ ULONG nRetIndexExpr = 0; +/*N*/ USHORT nErrorFunction = 0; +/*N*/ USHORT nErrorFunctionCount = 0; +/*N*/ USHORT nStackBase; +/*N*/ +/*N*/ nGlobError = nGlobalError; +/*N*/ nGlobalError = 0; +/*N*/ nMatCount = 0; +/*N*/ bMatDel = FALSE; +/*N*/ ppGlobSortArray = NULL; +/*N*/ nStackBase = sp = maxsp = 0; +/*N*/ nRetFmtType = NUMBERFORMAT_UNDEFINED; +/*N*/ nFuncFmtType = NUMBERFORMAT_UNDEFINED; +/*N*/ nFuncFmtIndex = nCurFmtIndex = nRetFmtIndex = 0; +/*N*/ nResult = 0; +/*N*/ pResult = NULL; +/*N*/ eResult = svDouble; +/*N*/ glSubTotal = FALSE; +/*N*/ UINT16 nOldOpCode = ocStop; +/*N*/ + // Once upon a time we used to have FP exceptions on, and there was a + // Windows printer driver that kept switching off exceptions, so we had to + // switch them back on again every time. Who knows if there isn't a driver + // that keeps switching exceptions on, now that we run with exceptions off, + // so reassure exceptions are really off. +/*N*/ SAL_MATH_FPEXCEPTIONS_OFF(); + +/*N*/ aCode.Reset(); +/*N*/ while( ( pCur = aCode.Next() ) != NULL +/*N*/ && (!nGlobalError || nErrorFunction <= nErrorFunctionCount) ) +/*N*/ { +/*N*/ OpCode eOp = pCur->GetOpCode(); +/*N*/ cPar = pCur->GetByte(); +/*N*/ if ( eOp == ocPush ) +/*N*/ { +/*N*/ Push( (ScToken&) *pCur ); +/*N*/ if ( sp <= MAXSTACK ) +/*N*/ pErrorStack[ sp - 1 ] = 0; // RPN-Code Push ohne Fehler +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // bisheriger Ausdruck bestimmt das aktuelle Format +/*N*/ nCurFmtType = nRetTypeExpr; +/*N*/ nCurFmtIndex = nRetIndexExpr; +/*N*/ // default Funtionsformat, andere werden bei Bedarf gesetzt +/*N*/ nFuncFmtType = NUMBERFORMAT_NUMBER; +/*N*/ nFuncFmtIndex = 0; +/*N*/ +/*N*/ if ( eOp == ocIf || eOp == ocChose ) +/*N*/ nStackBase = sp; // nicht die Jumps vertueddeln +/*N*/ else +/*N*/ nStackBase = sp - pCur->GetParamCount(); +/*N*/ if ( nStackBase > sp ) +/*N*/ nStackBase = sp; // underflow?!? +/*N*/ +/*N*/ switch( eOp ) +/*N*/ { + case ocSep: + case ocClose: // vom Compiler gepusht + case ocMissing : ScMissing(); break; +/*N*/ case ocMacro : ScMacro(); break; + case ocDBArea : ScDBArea(); break; + case ocColRowNameAuto : ScColRowNameAuto(); break; +// gesondert case ocPush : Push( (ScToken&) *pCur ); break; +/*N*/ case ocIf : ScIfJump(); break; + case ocChose : ScChoseJump(); break; +/*N*/ case ocAdd : ScAdd(); break; +/*N*/ case ocSub : ScSub(); break; +/*N*/ case ocMul : ScMul(); break; +/*N*/ case ocDiv : ScDiv(); break; +/*N*/ case ocAmpersand : ScAmpersand(); break; + case ocPow : ScPow(); break; +/*N*/ case ocEqual : ScEqual(); break; +/*N*/ case ocNotEqual : ScNotEqual(); break; + case ocLess : ScLess(); break; + case ocGreater : ScGreater(); break; + case ocLessEqual : ScLessEqual(); break; + case ocGreaterEqual : ScGreaterEqual(); break; + case ocAnd : ScAnd(); break; + case ocOr : ScOr(); break; + case ocIntersect : ScIntersect(); break; + case ocNot : ScNot(); break; + case ocNegSub : + case ocNeg : ScNeg(); break; + case ocPercentSign : ScPercentSign(); break; +/*N*/ case ocPi : ScPi(); break; + case ocRandom : ScRandom(); break; + case ocTrue : ScTrue(); break; + case ocFalse : ScFalse(); break; +/*N*/ case ocGetActDate : ScGetActDate(); break; + case ocGetActTime : ScGetActTime(); break; + case ocNoValue : nGlobalError = NOVALUE; + PushInt(0); break; + case ocDeg : ScDeg(); break; + case ocRad : ScRad(); break; +/*N*/ case ocSin : ScSin(); break; + case ocCos : ScCos(); break; + case ocTan : ScTan(); break; + case ocCot : ScCot(); break; + case ocArcSin : ScArcSin(); break; + case ocArcCos : ScArcCos(); break; + case ocArcTan : ScArcTan(); break; + case ocArcCot : ScArcCot(); break; + case ocSinHyp : ScSinHyp(); break; + case ocCosHyp : ScCosHyp(); break; + case ocTanHyp : ScTanHyp(); break; + case ocCotHyp : ScCotHyp(); break; + case ocArcSinHyp : ScArcSinHyp(); break; + case ocArcCosHyp : ScArcCosHyp(); break; + case ocArcTanHyp : ScArcTanHyp(); break; + case ocArcCotHyp : ScArcCotHyp(); break; + case ocExp : ScExp(); break; + case ocLn : ScLn(); break; + case ocLog10 : ScLog10(); break; + case ocSqrt : ScSqrt(); break; + case ocFact : ScFact(); break; + case ocGetYear : ScGetYear(); break; + case ocGetMonth : ScGetMonth(); break; +/*N*/ case ocGetDay : ScGetDay(); break; +/*N*/ case ocGetDayOfWeek : ScGetDayOfWeek(); break; +/*N*/ case ocWeek : ScGetWeekOfYear(); break; +/*N*/ case ocEasterSunday : ScEasterSunday(); break; + case ocGetHour : ScGetHour(); break; + case ocGetMin : ScGetMin(); break; + case ocGetSec : ScGetSec(); break; +/*N*/ case ocPlusMinus : ScPlusMinus(); break; + case ocAbs : ScAbs(); break; +/*N*/ case ocInt : ScInt(); break; + case ocEven : ScEven(); break; + case ocOdd : ScOdd(); break; + case ocPhi : ScPhi(); break; + case ocGauss : ScGauss(); break; + case ocStdNormDist : ScStdNormDist(); break; + case ocFisher : ScFisher(); break; + case ocFisherInv : ScFisherInv(); break; + case ocIsEmpty : ScIsEmpty(); break; + case ocIsString : ScIsString(); break; + case ocIsNonString : ScIsNonString(); break; + case ocIsLogical : ScIsLogical(nOldOpCode); break; + case ocType : ScType(); break; + case ocCell : ScCell(); break; + case ocIsRef : ScIsRef(); break; + case ocIsValue : ScIsValue(); break; + case ocIsFormula : ScIsFormula(); break; + case ocFormula : ScFormula(); break; + case ocIsNV : ScIsNV(); break; + case ocIsErr : ScIsErr(); break; + case ocIsError : ScIsError(); break; + case ocIsEven : ScIsEven(); break; + case ocIsOdd : ScIsOdd(); break; + case ocN : ScN(); break; + case ocGetDateValue : ScGetDateValue(); break; + case ocGetTimeValue : ScGetTimeValue(); break; + case ocCode : ScCode(); break; + case ocTrim : ScTrim(); break; + case ocUpper : ScUpper(); break; + case ocPropper : ScPropper(); break; + case ocLower : ScLower(); break; + case ocLen : ScLen(); break; + case ocT : ScT(); break; + case ocClean : ScClean(); break; + case ocValue : ScValue(); break; + case ocChar : ScChar(); break; + case ocArcTan2 : ScArcTan2(); break; +/*N*/ case ocMod : ScMod(); break; + case ocPower : ScPower(); break; + case ocRound : ScRound(); break; +/*N*/ case ocRoundUp : ScRoundUp(); break; + case ocTrunc : + case ocRoundDown : ScRoundDown(); break; + case ocCeil : ScCeil(); break; + case ocFloor : ScFloor(); break; + case ocSumProduct : ScSumProduct(); break; + case ocSumSQ : ScSumSQ(); break; + case ocSumX2MY2 : ScSumX2MY2(); break; + case ocSumX2DY2 : ScSumX2DY2(); break; + case ocSumXMY2 : ScSumXMY2(); break; + case ocLog : ScLog(); break; + case ocGGT : ScGGT(); break; + case ocKGV : ScKGV(); break; + case ocGetDate : ScGetDate(); break; + case ocGetTime : ScGetTime(); break; + case ocGetDiffDate : ScGetDiffDate(); break; + case ocGetDiffDate360 : ScGetDiffDate360(); break; +/*N*/ case ocMin : ScMin( FALSE ); break; + case ocMinA : ScMin( TRUE ); break; +/*N*/ case ocMax : ScMax( FALSE ); break; + case ocMaxA : ScMax( TRUE ); break; +/*N*/ case ocSum : ScSum(); break; + case ocProduct : ScProduct(); break; + case ocNBW : ScNBW(); break; + case ocIKV : ScIKV(); break; + case ocMIRR : ScMIRR(); break; + case ocISPMT : ScISPMT(); break; +/*N*/ case ocAverage : ScAverage( FALSE ); break; + case ocAverageA : ScAverage( TRUE ); break; + case ocCount : ScCount(); break; +/*N*/ case ocCount2 : ScCount2(); break; + case ocVar : ScVar( FALSE ); break; + case ocVarA : ScVar( TRUE ); break; + case ocVarP : ScVarP( FALSE ); break; + case ocVarPA : ScVarP( TRUE ); break; + case ocStDev : ScStDev( FALSE ); break; + case ocStDevA : ScStDev( TRUE ); break; + case ocStDevP : ScStDevP( FALSE ); break; + case ocStDevPA : ScStDevP( TRUE ); break; + case ocBW : ScBW(); break; + case ocDIA : ScDIA(); break; + case ocGDA : ScGDA(); break; + case ocGDA2 : ScGDA2(); break; + case ocVBD : ScVDB(); break; + case ocLaufz : ScLaufz(); break; + case ocLIA : ScLIA(); break; + case ocRMZ : ScRMZ(); break; + case ocColumns : ScColumns(); break; + case ocRows : ScRows(); break; + case ocTables : ScTables(); break; + case ocColumn : ScColumn(); break; + case ocRow : ScRow(); break; + case ocTable : ScTable(); break; + case ocZGZ : ScZGZ(); break; + case ocZW : ScZW(); break; + case ocZZR : ScZZR(); break; + case ocZins : ScZins(); break; + case ocZinsZ : ScZinsZ(); break; + case ocKapz : ScKapz(); break; + case ocKumZinsZ : ScKumZinsZ(); break; + case ocKumKapZ : ScKumKapZ(); break; + case ocEffektiv : ScEffektiv(); break; + case ocNominal : ScNominal(); break; +/*N*/ case ocSubTotal : ScSubTotal(); break; + case ocDBSum : ScDBSum(); break; + case ocDBCount : ScDBCount(); break; + case ocDBCount2 : ScDBCount2(); break; + case ocDBAverage : ScDBAverage(); break; + case ocDBGet : ScDBGet(); break; + case ocDBMax : ScDBMax(); break; + case ocDBMin : ScDBMin(); break; + case ocDBProduct : ScDBProduct(); break; + case ocDBStdDev : ScDBStdDev(); break; + case ocDBStdDevP : ScDBStdDevP(); break; + case ocDBVar : ScDBVar(); break; + case ocDBVarP : ScDBVarP(); break; + case ocIndirect : ScIndirect(); break; + case ocAdress : ScAdress(); break; + case ocMatch : ScMatch(); break; + case ocCountEmptyCells : ScCountEmptyCells(); break; + case ocCountIf : ScCountIf(); break; + case ocSumIf : ScSumIf(); break; + case ocLookup : ScLookup(); break; +/*N*/ case ocVLookup : ScVLookup(); break; + case ocHLookup : ScHLookup(); break; + case ocIndex : ScIndex(); break; + case ocMultiArea : ScMultiArea(); break; + case ocOffset : ScOffset(); break; + case ocAreas : ScAreas(); break; + case ocCurrency : ScCurrency(); break; + case ocReplace : ScReplace(); break; + case ocFixed : ScFixed(); break; + case ocFind : ScFind(); break; + case ocExact : ScExact(); break; + case ocLeft : ScLeft(); break; + case ocRight : ScRight(); break; + case ocSearch : ScSearch(); break; + case ocMid : ScMid(); break; +/*N*/ case ocText : ScText(); break; + case ocSubstitute : ScSubstitute(); break; + case ocRept : ScRept(); break; + case ocConcat : ScConcat(); break; + case ocMatValue : ScMatValue(); break; + case ocMatrixUnit : ScEMat(); break; + case ocMatDet : ScMatDet(); break; + case ocMatInv : ScMatInv(); break; + case ocMatMult : ScMatMult(); break; + case ocMatTrans : ScMatTrans(); break; +/*N*/ case ocMatRef : ScMatRef(); break; + case ocBackSolver : ScBackSolver(); break; + case ocB : ScB(); break; + case ocNormDist : ScNormDist(); break; + case ocExpDist : ScExpDist(); break; + case ocBinomDist : ScBinomDist(); break; + case ocPoissonDist : ScPoissonDist(); break; + case ocKombin : ScKombin(); break; + case ocKombin2 : ScKombin2(); break; + case ocVariationen : ScVariationen(); break; + case ocVariationen2 : ScVariationen2(); break; + case ocHypGeomDist : ScHypGeomDist(); break; + case ocLogNormDist : ScLogNormDist(); break; + case ocTDist : ScTDist(); break; + case ocFDist : ScFDist(); break; + case ocChiDist : ScChiDist(); break; + case ocStandard : ScStandard(); break; + case ocAveDev : ScAveDev(); break; + case ocDevSq : ScDevSq(); break; + case ocKurt : ScKurt(); break; + case ocSchiefe : ScSkew(); break; + case ocModalValue : ScModalValue(); break; + case ocMedian : ScMedian(); break; + case ocGeoMean : ScGeoMean(); break; + case ocHarMean : ScHarMean(); break; + case ocWeibull : ScWeibull(); break; + case ocKritBinom : ScCritBinom(); break; + case ocNegBinomVert : ScNegBinomDist(); break; + case ocNoName : ScNoName(); break; + case ocZTest : ScZTest(); break; + case ocTTest : ScTTest(); break; + case ocFTest : ScFTest(); break; + case ocRank : ScRank(); break; + case ocPercentile : ScPercentile(); break; + case ocPercentrank : ScPercentrank(); break; + case ocLarge : ScLarge(); break; + case ocSmall : ScSmall(); break; + case ocFrequency : ScFrequency(); break; + case ocQuartile : ScQuartile(); break; + case ocNormInv : ScNormInv(); break; + case ocSNormInv : ScSNormInv(); break; + case ocConfidence : ScConfidence(); break; + case ocTrimMean : ScTrimMean(); break; + case ocProb : ScProbability(); break; + case ocCorrel : ScCorrel(); break; + case ocCovar : ScCovar(); break; + case ocPearson : ScPearson(); break; + case ocRSQ : ScRSQ(); break; + case ocSTEYX : ScSTEXY(); break; + case ocSlope : ScSlope(); break; + case ocIntercept : ScIntercept(); break; + case ocTrend : ScTrend(); break; + case ocGrowth : ScGrowth(); break; + case ocRGP : ScRGP(); break; + case ocRKP : ScRKP(); break; + case ocForecast : ScForecast(); break; + case ocGammaLn : ScLogGamma(); break; + case ocGammaDist : ScGammaDist(); break; + case ocGammaInv : ScGammaInv(); break; + case ocChiTest : ScChiTest(); break; + case ocChiInv : ScChiInv(); break; + case ocTInv : ScTInv(); break; + case ocFInv : ScFInv(); break; + case ocLogInv : ScLogNormInv(); break; + case ocBetaDist : ScBetaDist(); break; + case ocBetaInv : ScBetaInv(); break; +/*N*/ case ocExternal : ScExternal(); break; + case ocTableOp : ScTableOp(); break; +// case ocErrCell : ScErrCell(); break; + case ocStop : break; + case ocErrorType : ScErrorType(); break; + case ocCurrent : ScCurrent(); break; + case ocStyle : ScStyle(); break; + case ocDde : ScDde(); break; + case ocBase : ScBase(); break; +/*N*/ case ocDecimal : ScDecimal(); break; +/*N*/ case ocConvert : ScConvert(); break; + case ocRoman : ScRoman(); break; + case ocArabic : ScArabic(); break; + case ocAnswer : ScAnswer(); break; + case ocTeam : ScCalcTeam(); break; + case ocTTT : ScTTT(); break; + case ocSpew : ScSpewFunc(); break; + case ocGame : ScGame(); break; +/*N*/ default : SetError(errUnknownOpCode); PushInt(0); break; +/*N*/ } +/*N*/ +/*N*/ // aeussere Funktion bestimmt das Format eines Ausdrucks +/*N*/ if ( nFuncFmtType != NUMBERFORMAT_UNDEFINED ) +/*N*/ { +/*N*/ nRetTypeExpr = nFuncFmtType; +/*N*/ // nur fuer Waehrungsformate den FormatIndex uebernehmen +/*N*/ nRetIndexExpr = ( nFuncFmtType == NUMBERFORMAT_CURRENCY ? +/*N*/ nFuncFmtIndex : 0 ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // Funktionen, die einen Fehlercode auswerten und nGlobalError direkt auf 0 setzen +/*N*/ // usage: switch( OpCode ) { OCERRFUNCCASE( ++n ) } +/*N*/ #define CASEOCERRFUNC( statement ) \ +/*N*/ case ocErrorType : \ +/*N*/ case ocIsEmpty : \ +/*N*/ case ocIsErr : \ +/*N*/ case ocIsError : \ +/*N*/ case ocIsFormula : \ +/*N*/ case ocIsLogical : \ +/*N*/ case ocIsNV : \ +/*N*/ case ocIsNonString : \ +/*N*/ case ocIsRef : \ +/*N*/ case ocIsString : \ +/*N*/ case ocIsValue : \ +/*N*/ case ocN : \ +/*N*/ case ocType : \ +/*N*/ statement; +/*N*/ +/*N*/ switch ( eOp ) +/*N*/ { +/*N*/ CASEOCERRFUNC( ++nErrorFunction ) +/*N*/ } +/*N*/ if ( nGlobalError ) +/*N*/ { +/*N*/ if ( !nErrorFunctionCount ) +/*N*/ { // Anzahl der Fehlercode-Funktionen in Formel +/*N*/ for ( ScToken* t = rArr.FirstRPN(); t; t = rArr.NextRPN() ) +/*N*/ { +/*N*/ switch ( t->GetOpCode() ) +/*N*/ { +/*N*/ CASEOCERRFUNC( ++nErrorFunctionCount ) +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( nErrorFunction >= nErrorFunctionCount ) +/*N*/ ++nErrorFunction; // das war's, Fehler => Abbruch +/*N*/ else +/*N*/ { +/*?*/ if ( eOp != ocPush && sp > nStackBase + 1 ) +/*?*/ { // Stack abraeumen, geht davon aus, dass jede Funktion +/*?*/ // prinzipiell ein Ergebnis pusht, im Fehlerfall kann dies +/*?*/ // ein zufaelliger Wert sein +/*?*/ const ScToken* pResult = pStack[ sp - 1 ]; +/*?*/ while ( sp > nStackBase ) +/*?*/ Pop(); +/*?*/ PushTempToken( *pResult ); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ nOldOpCode = eOp; +/*N*/ } +/*N*/ +/*N*/ // Ende: Returnwert holen +/*N*/ +/*N*/ if( sp ) +/*N*/ { +/*N*/ pCur = pStack[ sp-1 ]; +/*N*/ if( pCur->GetOpCode() == ocPush ) +/*N*/ { +/*N*/ if ( !nGlobalError ) +/*N*/ nGlobalError = pErrorStack[ sp-1 ]; +/*N*/ switch( eResult = pCur->GetType() ) +/*N*/ { +/*N*/ case svDouble : +/*N*/ nResult = pCur->GetDouble(); +/*N*/ if ( nFuncFmtType == NUMBERFORMAT_UNDEFINED ) +/*N*/ { +/*N*/ nRetTypeExpr = NUMBERFORMAT_NUMBER; +/*N*/ nRetIndexExpr = 0; +/*N*/ } +/*N*/ break; +/*N*/ case svString : +/*N*/ nRetTypeExpr = NUMBERFORMAT_TEXT; +/*N*/ nRetIndexExpr = 0; +/*N*/ aResult = PopString(); +/*N*/ break; +/*N*/ case svSingleRef : +/*N*/ { +/*N*/ ScAddress aAdr; +/*N*/ PopSingleRef( aAdr ); +/*N*/ if( !nGlobalError ) +/*N*/ { +/*N*/ ScBaseCell* pCell = pDok->GetCell( aAdr ); +/*N*/ if( pCell && pCell->HasStringData() ) +/*N*/ { +/*N*/ GetCellString( aResult, pCell ); +/*N*/ nRetTypeExpr = NUMBERFORMAT_TEXT; +/*N*/ nRetIndexExpr = 0; +/*N*/ eResult = svString; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nResult = GetCellValue( aAdr, pCell ); +/*N*/ nRetTypeExpr = nCurFmtType; +/*N*/ nRetIndexExpr = nCurFmtIndex; +/*N*/ eResult = svDouble; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case svDoubleRef : +/*N*/ { +/*?*/ if ( bMatrixFormula ) +/*?*/ { // Matrix erzeugen fuer {=A1:A5} +/*?*/ PopDoubleRefPushMatrix(); +/*?*/ // kein break, weiter mit svMatrix +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ ScRange aRange; +/*?*/ PopDoubleRef( aRange ); +/*?*/ ScAddress aAdr; +/*?*/ if ( !nGlobalError && DoubleRefToPosSingleRef( aRange, aAdr ) ) +/*?*/ { +/*?*/ ScBaseCell* pCell = pDok->GetCell( aAdr ); +/*?*/ if( pCell && pCell->HasStringData() ) +/*?*/ { +/*?*/ GetCellString( aResult, pCell ); +/*?*/ nRetTypeExpr = NUMBERFORMAT_TEXT; +/*?*/ nRetIndexExpr = 0; +/*?*/ eResult = svString; +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ nResult = GetCellValue( aAdr, pCell ); +/*?*/ nRetTypeExpr = nCurFmtType; +/*?*/ nRetIndexExpr = nCurFmtIndex; +/*?*/ eResult = svDouble; +/*?*/ } +/*?*/ } +/*?*/ break; +/*?*/ } +/*?*/ } +/*?*/ // kein break +/*N*/ case svMatrix : +/*N*/ pResult = PopMatrix(); +/*N*/ if (pResult) +/*N*/ { +/*N*/ BOOL bIsString; +/*N*/ const MatValue* pMatVal = pResult->Get(0, 0, bIsString); +/*N*/ if ( pMatVal ) +/*N*/ { +/*N*/ if (bIsString) +/*N*/ { +/*?*/ aResult = pMatVal->GetString(); +/*?*/ eResult = svString; +/*?*/ nRetTypeExpr = NUMBERFORMAT_TEXT; +/*?*/ nRetIndexExpr = 0; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nResult = pMatVal->fVal; +/*N*/ eResult = svDouble; +/*N*/ if ( nRetTypeExpr != NUMBERFORMAT_LOGICAL ) +/*N*/ nRetTypeExpr = NUMBERFORMAT_NUMBER; +/*N*/ nRetIndexExpr = 0; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ SetError(errUnknownStackVariable); +/*N*/ DBG_ASSERT(nRetMat <= MAX_ANZ_MAT, +/*N*/ "ScInterpreter::nRetMat falsch"); +/*N*/ ResetNewMat(nRetMat); // Matrix nicht loeschen +/*N*/ } +/*N*/ else +/*N*/ eResult = svDouble; +/*N*/ break; +/*N*/ default : +/*N*/ SetError(errUnknownStackVariable); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ SetError(errUnknownStackVariable); +/*N*/ } +/*N*/ else +/*N*/ SetError(errNoCode); +/*N*/ +/*N*/ if (!::rtl::math::isFinite(nResult)) +/*N*/ { +/*N*/ if ( ::rtl::math::isNan( nResult ) ) +/*N*/ SetError(errNoValue); +/*N*/ else +/*N*/ SetError(errIllegalFPOperation); +/*N*/ nResult = 0.0; +/*N*/ } +/*N*/ +/*N*/ if( nRetTypeExpr != NUMBERFORMAT_UNDEFINED ) +/*N*/ { +/*N*/ nRetFmtType = nRetTypeExpr; +/*N*/ nRetFmtIndex = nRetIndexExpr; +/*N*/ } +/*N*/ else if( nFuncFmtType != NUMBERFORMAT_UNDEFINED ) +/*N*/ { +/*N*/ nRetFmtType = nFuncFmtType; +/*N*/ nRetFmtIndex = nFuncFmtIndex; +/*N*/ } +/*N*/ else +/*N*/ nRetFmtType = NUMBERFORMAT_NUMBER; +/*N*/ // nur fuer Waehrungsformate den FormatIndex uebernehmen +/*N*/ if ( nRetFmtType != NUMBERFORMAT_CURRENCY ) +/*N*/ nRetFmtIndex = 0; +/*N*/ +/*N*/ // grrr.. EiterZirkel! +/*N*/ // Fehler nur zuruecksetzen wenn nicht errCircularReference ohne Iterationen +/*N*/ if ( nGlobalError || !(rArr.GetError() == errCircularReference && !pDok->GetDocOptions().IsIter()) ) +/*N*/ rArr.SetError( nGlobalError ); +/*N*/ +/*N*/ if (ppGlobSortArray) +/*?*/ #ifdef WIN +/*?*/ SvMemFree(*ppGlobSortArray); +/*?*/ #else +/*?*/ delete [] (*ppGlobSortArray); +/*?*/ #endif +/*N*/ if (bMatDel) +/*N*/ { +/*N*/ for (USHORT i = 0; i < MAX_ANZ_MAT; i++) +/*N*/ delete ppTempMatArray[i]; +/*N*/ delete [] ppTempMatArray; +/*N*/ } +/*N*/ // Tokens im ExprStack freigeben +/*N*/ ScToken** p = pStack; +/*N*/ while( maxsp-- ) +/*N*/ (*p++)->DecRef(); +/*N*/ nGlobalError = nGlobError; +/*N*/ return eResult; +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_interpr5.cxx b/binfilter/bf_sc/source/core/tool/sc_interpr5.cxx new file mode 100644 index 000000000000..1af8655046e9 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_interpr5.cxx @@ -0,0 +1,4062 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <string.h> + +#include <bf_svtools/zforlist.hxx> + +#include "interpre.hxx" +#include "dociter.hxx" +#include "scmatrix.hxx" +#include "globstr.hrc" +namespace binfilter { + +// STATIC DATA ----------------------------------------------------------- + +#define SCdEpsilon 1.0E-7 + + +// ----------------------------------------------------------------------- + +double ScInterpreter::ScGetGGT(double fx, double fy) +{ + if (fy == 0.0 || fx == 0.0) + { + SetError(errIllegalArgument); + return 1.0; + } + else + { + double fz = fmod(fx, fy); + while (fz > 0.0) + { + fx = fy; + fy = fz; + fz = fmod(fx, fy); + } + return fy; + } +} + +void ScInterpreter::ScGGT() +{ + BYTE nParamCount = GetByte(); + if ( MustHaveParamCountMin( nParamCount, 1 ) ) + { + double fSign = 1.0; + double fx, fy = 0.0; + switch (GetStackType()) + { + case svDouble : + case svString: + case svSingleRef: + { + fy = GetDouble(); + if (fy < 0.0) + { + fy *= -1.0; + fSign *= -1.0; + } + } + break; + case svDoubleRef : + { + ScRange aRange; + USHORT nErr = 0; + PopDoubleRef( aRange ); + double nCellVal; + ScValueIterator aValIter(pDok, aRange, glSubTotal); + if (aValIter.GetFirst(nCellVal, nErr)) + { + fy = nCellVal; + if (fy < 0.0) + { + fy *= -1.0; + fSign *= -1.0; + } + while (nErr == 0 && aValIter.GetNext(nCellVal, nErr)) + { + fx = nCellVal; + if (fx < 0.0) + { + fx *= -1.0; + fSign *= -1.0; + } + fy = ScGetGGT(fx, fy); + } + SetError(nErr); + } + else + SetError(errIllegalArgument); + } + break; + case svMatrix : + { + ScMatrix* pMat = PopMatrix(); + if (pMat) + { + USHORT nC, nR; + pMat->GetDimensions(nC, nR); + if (nC == 0 || nR == 0) + SetError(errIllegalArgument); + else + { + if (!pMat->IsValue(0)) + { + SetIllegalArgument(); + return; + } + fy = pMat->GetDouble(0); + if (fy < 0.0) + { + fy *= -1.0; + fSign *= -1.0; + } + ULONG nCount = (ULONG) nC * nR; + for ( ULONG j = 1; j < nCount; j++ ) + { + if (!pMat->IsValue(j)) + { + SetIllegalArgument(); + return; + } + fx = pMat->GetDouble(j); + if (fx < 0.0) + { + fx *= -1.0; + fSign *= -1.0; + } + fy = ScGetGGT(fx, fy); + } + } + } + } + break; + default : SetError(errIllegalParameter); break; + } + ScRange aRange; + for (short i = 0; i < (short) nParamCount - 1; i++) + { + switch (GetStackType()) + { + case svDouble : + case svString: + case svSingleRef: + { + fx = GetDouble(); + if (fx < 0.0) + { + fx *= -1.0; + fSign *= -1.0; + } + fy = ScGetGGT(fx, fy); + } + break; + case svDoubleRef : + { + USHORT nErr = 0; + PopDoubleRef( aRange ); + double nCellVal; + ScValueIterator aValIter(pDok, aRange, glSubTotal); + if (aValIter.GetFirst(nCellVal, nErr)) + { + fx = nCellVal; + if (fx < 0.0) + { + fx *= -1.0; + fSign *= -1.0; + } + fy = ScGetGGT(fx, fy); + while (nErr == 0 && aValIter.GetNext(nCellVal, nErr)) + { + fx = nCellVal; + if (fx < 0.0) + { + fx *= -1.0; + fSign *= -1.0; + } + fy = ScGetGGT(fx, fy); + } + SetError(nErr); + } + else + SetError(errIllegalArgument); + } + break; + case svMatrix : + { + ScMatrix* pMat = PopMatrix(); + if (pMat) + { + USHORT nC, nR; + pMat->GetDimensions(nC, nR); + if (nC == 0 || nR == 0) + SetError(errIllegalArgument); + else + { + if (!pMat->IsValue(0)) + { + SetIllegalArgument(); + return; + } + fx = pMat->GetDouble(0); + if (fx < 0.0) + { + fx *= -1.0; + fSign *= -1.0; + } + fy = ScGetGGT(fx, fy); + ULONG nCount = (ULONG) nC * nR; + for ( ULONG j = 1; j < nCount; j++ ) + { + if (!pMat->IsValue(j)) + { + SetIllegalArgument(); + return; + } + fx = pMat->GetDouble(j); + if (fx < 0.0) + { + fx *= -1.0; + fSign *= -1.0; + } + fy = ScGetGGT(fx, fy); + } + } + } + } + break; + default : SetError(errIllegalParameter); break; + } + } + if (fSign == -1.0) + PushDouble(-fy); + else + PushDouble(fy); + } +} + +void ScInterpreter:: ScKGV() +{ + BYTE nParamCount = GetByte(); + if ( MustHaveParamCountMin( nParamCount, 1 ) ) + { + double fSign = 1.0; + double fx, fy = 0.0; + switch (GetStackType()) + { + case svDouble : + case svString: + case svSingleRef: + { + fy = GetDouble(); + if (fy < 0.0) + { + fy *= -1.0; + fSign *= -1.0; + } + } + break; + case svDoubleRef : + { + ScRange aRange; + USHORT nErr = 0; + PopDoubleRef( aRange ); + double nCellVal; + ScValueIterator aValIter(pDok, aRange, glSubTotal); + if (aValIter.GetFirst(nCellVal, nErr)) + { + fy = nCellVal; + if (fy < 0.0) + { + fy *= -1.0; + fSign *= -1.0; + } + while (nErr == 0 && aValIter.GetNext(nCellVal, nErr)) + { + fx = nCellVal; + if (fx < 0.0) + { + fx *= -1.0; + fSign *= -1.0; + } + fy = fx * fy / ScGetGGT(fx, fy); + } + SetError(nErr); + } + else + SetError(errIllegalArgument); + } + break; + case svMatrix : + { + ScMatrix* pMat = PopMatrix(); + if (pMat) + { + USHORT nC, nR; + pMat->GetDimensions(nC, nR); + if (nC == 0 || nR == 0) + SetError(errIllegalArgument); + else + { + if (!pMat->IsValue(0)) + { + SetIllegalArgument(); + return; + } + fy = pMat->GetDouble(0); + if (fy < 0.0) + { + fy *= -1.0; + fSign *= -1.0; + } + ULONG nCount = (ULONG) nC * nR; + for ( ULONG j = 1; j < nCount; j++ ) + { + if (!pMat->IsValue(j)) + { + SetIllegalArgument(); + return; + } + fx = pMat->GetDouble(j); + if (fx < 0.0) + { + fx *= -1.0; + fSign *= -1.0; + } + fy = fx * fy / ScGetGGT(fx, fy); + } + } + } + } + break; + default : SetError(errIllegalParameter); break; + } + ScRange aRange; + for (short i = 0; i < (short) nParamCount - 1; i++) + { + switch (GetStackType()) + { + case svDouble : + case svString: + case svSingleRef: + { + fx = GetDouble(); + if (fx < 0.0) + { + fx *= -1.0; + fSign *= -1.0; + } + fy = fx * fy / ScGetGGT(fx, fy); + } + break; + case svDoubleRef : + { + USHORT nErr = 0; + PopDoubleRef( aRange ); + double nCellVal; + ScValueIterator aValIter(pDok, aRange, glSubTotal); + if (aValIter.GetFirst(nCellVal, nErr)) + { + fx = nCellVal; + if (fx < 0.0) + { + fx *= -1.0; + fSign *= -1.0; + } + fy = fx * fy / ScGetGGT(fx, fy); + while (nErr == 0 && aValIter.GetNext(nCellVal, nErr)) + { + fx = nCellVal; + if (fx < 0.0) + { + fx *= -1.0; + fSign *= -1.0; + } + fy = fx * fy / ScGetGGT(fx, fy); + } + SetError(nErr); + } + else + SetError(errIllegalArgument); + } + break; + case svMatrix : + { + ScMatrix* pMat = PopMatrix(); + if (pMat) + { + USHORT nC, nR; + pMat->GetDimensions(nC, nR); + if (nC == 0 || nR == 0) + SetError(errIllegalArgument); + else + { + if (!pMat->IsValue(0)) + { + SetIllegalArgument(); + return; + } + fx = pMat->GetDouble(0); + if (fx < 0.0) + { + fx *= -1.0; + fSign *= -1.0; + } + fy = fx * fy / ScGetGGT(fx, fy); + ULONG nCount = (ULONG) nC * nR; + for ( ULONG j = 1; j < nCount; j++ ) + { + if (!pMat->IsValue(j)) + { + SetIllegalArgument(); + return; + } + fx = pMat->GetDouble(j); + if (fx < 0.0) + { + fx *= -1.0; + fSign *= -1.0; + } + fy = fx * fy / ScGetGGT(fx, fy); + } + } + } + } + break; + default : SetError(errIllegalParameter); break; + } + } + if (fSign == -1.0) + PushDouble(-fy); + else + PushDouble(fy); + } +} + +/*N*/ ScMatrix* ScInterpreter::GetNewMat(USHORT nC, USHORT nR, USHORT& nMatInd) +/*N*/ { +/*N*/ if (nMatCount == MAX_ANZ_MAT) +/*N*/ { +/*N*/ DBG_ERROR("ScInterpreter::GetNewMat: Matrixueberlauf"); +/*N*/ SetError(errCodeOverflow); +/*N*/ nMatInd = MAX_ANZ_MAT; +/*N*/ return NULL; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if (!bMatDel) // beim ersten Mal +/*N*/ { +/*N*/ ppTempMatArray = new ScMatrix* [MAX_ANZ_MAT]; +/*N*/ for (USHORT i = 0; i < MAX_ANZ_MAT; i++) +/*N*/ ppTempMatArray[i] = NULL; +/*N*/ bMatDel = TRUE; +/*N*/ } +/*N*/ ppTempMatArray[nMatCount] = new ScMatrix(nC, nR); +/*N*/ nMatInd = nMatCount++; +/*N*/ return ppTempMatArray[nMatInd]; +/*N*/ } +/*N*/ } + +/*N*/ void ScInterpreter::ResetNewMat(USHORT nIndex) +/*N*/ { +/*N*/ if (nIndex < MAX_ANZ_MAT) +/*N*/ { +/*N*/ ppTempMatArray[nIndex] = NULL; +/*N*/ if (nIndex == nMatCount - 1) +/*N*/ nMatCount--; +/*N*/ } +/*N*/ } + +/*N*/ ScMatrix* ScInterpreter::GetMatrix(USHORT& nMatInd) +/*N*/ { +/*N*/ ScMatrix* pMat = NULL; +/*N*/ switch (GetStackType()) +/*N*/ { +/*?*/ case svSingleRef : +/*?*/ { +/*?*/ ScAddress aAdr; +/*?*/ PopSingleRef( aAdr ); +/*?*/ pMat = GetNewMat(1, 1, nMatInd); +/*?*/ if (pMat) +/*?*/ { +/*?*/ ScBaseCell* pCell = GetCell( aAdr ); +/*?*/ if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE ) +/*?*/ { +/*?*/ if (HasCellValueData(pCell)) +/*?*/ pMat->PutDouble(GetCellValue(aAdr, pCell), 0); +/*?*/ else +/*?*/ { +/*?*/ String aStr; +/*?*/ GetCellString(aStr, pCell); +/*?*/ pMat->PutString(aStr, 0); +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ pMat->PutEmpty( 0 ); +/*?*/ } +/*?*/ else +/*?*/ SetError(errCodeOverflow); +/*?*/ } +/*?*/ break; +/*N*/ case svDoubleRef: +/*N*/ { +/*N*/ USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; +/*N*/ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); +/*N*/ if (nTab1 == nTab2) +/*N*/ { +/*N*/ USHORT i, j; +/*N*/ if ( (ULONG) (nRow2 - nRow1 + 1) * (nCol2 - nCol1 + 1) > +/*N*/ ScMatrix::GetElementsMax() ) +/*N*/ SetError(errStackOverflow); +/*N*/ else +/*N*/ { +/*N*/ pMat = GetNewMat(nCol2 - nCol1 + 1, nRow2 - nRow1 + 1, nMatInd); +/*N*/ if (pMat) +/*N*/ { +/*N*/ ScAddress aAdr( nCol1, nRow1, nTab1 ); +/*N*/ for (i = nRow1; i <= nRow2; i++) +/*N*/ { +/*N*/ aAdr.SetRow( i ); +/*N*/ for (j = nCol1; j <= nCol2; j++) +/*N*/ { +/*N*/ aAdr.SetCol( j ); +/*N*/ ScBaseCell* pCell = GetCell( aAdr ); +/*N*/ if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE ) +/*N*/ { +/*N*/ if (HasCellValueData(pCell)) +/*N*/ pMat->PutDouble( +/*N*/ GetCellValue( aAdr, pCell ), +/*N*/ j-nCol1, i-nRow1); +/*N*/ else +/*N*/ { +/*?*/ String aStr; +/*?*/ GetCellString(aStr, pCell); +/*?*/ pMat->PutString(aStr, j-nCol1, i-nRow1); +/*N*/ } +/*N*/ } +/*N*/ else +/*?*/ pMat->PutEmpty( j-nCol1, i-nRow1 ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ SetError(errCodeOverflow); +/*N*/ } +/*N*/ } +/*N*/ else // keine 2D-Matrix +/*N*/ { +/*N*/ nMatInd = MAX_ANZ_MAT; +/*N*/ SetError(errIllegalParameter); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case svMatrix: +/*N*/ pMat = PopMatrix(); +/*N*/ nMatInd = MAX_ANZ_MAT; +/*N*/ break; +/*?*/ default: +/*?*/ Pop(); +/*?*/ nMatInd = MAX_ANZ_MAT; +/*?*/ SetError(errIllegalParameter); +/*?*/ break; +/*N*/ } +/*N*/ return pMat; +/*N*/ } + +void ScInterpreter::ScMatValue() +{ + if ( MustHaveParamCount( GetByte(), 3 ) ) + { + USHORT nR = (USHORT) ::rtl::math::approxFloor(GetDouble()); // 0 bis nAnz - 1 + USHORT nC = (USHORT) ::rtl::math::approxFloor(GetDouble()); // 0 bis nAnz - 1 + switch (GetStackType()) + { + case svSingleRef : + { + ScAddress aAdr; + PopSingleRef( aAdr ); + ScBaseCell* pCell = GetCell( aAdr ); + if (pCell && pCell->GetCellType() == CELLTYPE_FORMULA) + { + USHORT nErrCode = ((ScFormulaCell*)pCell)->GetErrCode(); + if (nErrCode != 0) + { + SetError(nErrCode); + PushInt(0); + } + else + { + ScMatrix* pMat; + ((ScFormulaCell*)pCell)->GetMatrix(&pMat); + if (pMat) + { + USHORT nCl, nRw; + pMat->GetDimensions(nCl, nRw); + if (nC < nCl && nR < nRw) + { + BOOL bIsString; + const MatValue* pMatVal = pMat->Get(nC, nR, bIsString); + if (bIsString) + PushString( pMatVal->GetString() ); + else + PushDouble(pMatVal->fVal); + } + else + SetNoValue(); + } + else + SetNoValue(); + } + } + else + SetIllegalParameter(); + } + break; + case svDoubleRef : + { + USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; + PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + if (nCol2 - nCol1 >= nR && nRow2 - nRow1 >= nC && nTab1 == nTab2) + { + ScAddress aAdr( nCol1 + nR, nRow1 + nC, nTab1 ); + ScBaseCell* pCell = GetCell( aAdr ); + if (HasCellValueData(pCell)) + PushDouble(GetCellValue( aAdr, pCell )); + else + { + String aStr; + GetCellString(aStr, pCell); + PushString(aStr); + } + } + else + SetNoValue(); + } + break; + case svMatrix: + { + ScMatrix* pMat = PopMatrix(); + if (pMat) + { + USHORT nCl, nRw; + pMat->GetDimensions(nCl, nRw); + if (nC < nCl && nR < nRw) + { + BOOL bIsString; + const MatValue* pMatVal = pMat->Get(nC, nR, bIsString); + if (bIsString) + PushString( pMatVal->GetString() ); + else + PushDouble(pMatVal->fVal); + } + else + SetNoValue(); + } + else + SetNoValue(); + } + break; + default: + Pop(); + SetIllegalParameter(); + break; + } + } +} + +void ScInterpreter::ScEMat() +{ + if ( MustHaveParamCount( GetByte(), 1 ) ) + { + ULONG nDim = (ULONG) ::rtl::math::approxFloor(GetDouble()); + if ( nDim * nDim > ScMatrix::GetElementsMax() || nDim == 0) + SetIllegalArgument(); + else + { + USHORT nMatInd; + ScMatrix* pRMat = GetNewMat((USHORT)nDim, (USHORT)nDim, nMatInd); + if (pRMat) + { + MEMat(pRMat, (USHORT) nDim); + nRetMat = nMatInd; + PushMatrix(pRMat); + } + else + SetError(errStackOverflow); + } + } +} + +void ScInterpreter::MEMat(ScMatrix* mM, USHORT n) +{ + mM->FillDouble(0.0, 0, 0, n-1, n-1); + for (USHORT i = 0; i < n; i++) + mM->PutDouble(1.0, i, i); +} + +void ScInterpreter::MFastMult(ScMatrix* pA, ScMatrix* pB, ScMatrix* pR, + USHORT n, USHORT m, USHORT l) + // Multipliziert n x m Mat a mit m x l Mat b nach Mat r +{ + double sum; + for (USHORT i = 0; i < n; i++) + { + for (USHORT j = 0; j < l; j++) + { + sum = 0.0; + for (USHORT k = 0; k < m; k++) + sum += pA->GetDouble(i,k)*pB->GetDouble(k,j); + pR->PutDouble(sum, i, j); + } + } +} + +void ScInterpreter::MFastSub(ScMatrix* pA, ScMatrix* pB, ScMatrix* pR, + USHORT n, USHORT m) + // Subtrahiert n x m Mat a - m x l Mat b nach Mat r +{ + for (USHORT i = 0; i < n; i++) + { + for (USHORT j = 0; j < m; j++) + pR->PutDouble(pA->GetDouble(i,j) - pB->GetDouble(i,j), i, j); + } +} + +void ScInterpreter::MFastTrans(ScMatrix* pA, ScMatrix* pR, + USHORT n, USHORT m) + // Transponiert n x m Mat a nach Mat r +{ + for (USHORT i = 0; i < n; i++) + for (USHORT j = 0; j < m; j++) + pR->PutDouble(pA->GetDouble(i, j), j, i); +} + +BOOL ScInterpreter::MFastBackSubst(ScMatrix* pA, ScMatrix* pR, USHORT n, BOOL bIsUpper) + // Führt Rückwaertsersetzung der Dreickesmatrix Mat a nach Mat r durch + // 2 Versionen fuer obere (U) oder untere (L- Unit) Dreiecksmatrizen +{ + short i, j, k; + double fSum; + if (!bIsUpper) // L-Matrix, immer invertierbar + { + MEMat(pR, n); + for (i = 1; i < (short) n; i++) + { + for (j = 0; j < i; j++) + { + fSum = 0.0; + for (k = 0; k < i; k++) + fSum += pA->GetDouble(i,k) * pR->GetDouble(k,j); + pR->PutDouble(-fSum, i, j); + } + } + } + else // U-Matrix + { + for (i = 0; i < (short) n; i++) // Ist invertierbar? + if (fabs(pA->GetDouble(i,i)) < SCdEpsilon) + return FALSE; + pR->FillDoubleLowerLeft(0.0, n-1); // untere Haelfte + pR->PutDouble(1.0/pA->GetDouble(n-1, n-1), n-1, n-1); // n-1, n-1 + for (i = (short) n-2; i >= 0; i--) + { + for (j = (short) n-1; j > i; j--) + { + fSum = 0.0; + for (k = (short) n-1; k > i; k--) + fSum += pA->GetDouble(i, k) * pR->GetDouble(k, j); + pR->PutDouble(-fSum/pA->GetDouble(i, i), i, j); + } + fSum = 0.0; // Hauptdiagonale: + for (k = (short) n-1; k > i; k--) + fSum += pA->GetDouble(i, k) * pR->GetDouble(k, j); + pR->PutDouble((1.0-fSum)/pA->GetDouble(i, i), i, i); + } + } + return TRUE; +} + +BOOL ScInterpreter::ScMatLUP(ScMatrix* mA, USHORT m, USHORT p, + ScMatrix* mL, ScMatrix* mU, ScMatrix* mP, + ULONG& rPermutCounter, BOOL& bIsInvertable) + // Returnwert = False <=> Matrixarray voll + // BIsInvertable = False: <= mA hat nicht Rang m +{ + USHORT nMatInd1, nMatInd2, nMatInd3, nMatInd4, nMatInd5; + USHORT i, j; + if (m == 1) + { + mL->PutDouble(1.0,0,0); + for (j = 0; j < p; j++) + if (fabs(mA->GetDouble(0, j)) >= SCdEpsilon) + break; + if (j == p) + { + bIsInvertable = FALSE; + return TRUE; + } + MEMat(mP, p); + if (j > 0 && j < p) + { + mP->PutDouble(0.0, 0, 0); + mP->PutDouble(1.0, j, 0); + mP->PutDouble(0.0, j, j); + mP->PutDouble(1.0, 0, j); + rPermutCounter++; + } + MFastMult(mA, mP, mU, m, p, p); + } + else + { + USHORT md2 = m/2; + ScMatrix* mB = GetNewMat(md2, p, nMatInd1); + ScMatrix* mC = GetNewMat(md2, p, nMatInd2); + ScMatrix* mL1 = GetNewMat(md2, md2, nMatInd3); + ScMatrix* mU1 = GetNewMat(md2, p, nMatInd4); + ScMatrix* mP1 = GetNewMat(p, p, nMatInd5); + if (!mB || !mC || !mL1 || !mU1 || !mP1 ) + return FALSE; + for (i = 0; i < md2; i++) + { + for (j = 0; j < p; j++) + { + mB->PutDouble(mA->GetDouble(i, j), i, j); + mC->PutDouble(mA->GetDouble(md2+i,j), i, j); + } + } + if (!ScMatLUP(mB, md2, p, mL1, mU1, mP1, rPermutCounter, bIsInvertable)) + return FALSE; + if (!bIsInvertable) + { + ResetNewMat(nMatInd5); + ResetNewMat(nMatInd4); + ResetNewMat(nMatInd3); + ResetNewMat(nMatInd2); + ResetNewMat(nMatInd1); + delete mP1; + delete mU1; + delete mL1; + delete mC; + delete mB; + return TRUE; + } + USHORT nMatInd6, nMatInd7, nMatInd8, nMatInd9, nMatInd10; + USHORT nMatInd11, nMatInd12, nMatInd13; + ScMatrix* mE = GetNewMat(md2, md2, nMatInd6); + ScMatrix* mF = GetNewMat(md2, md2, nMatInd7); + ScMatrix* mEInv = GetNewMat(md2, md2, nMatInd8); + ScMatrix* mG = GetNewMat(md2, p, nMatInd9); + ScMatrix* mGs = GetNewMat(md2, p - md2, nMatInd10); + ScMatrix* mU2 = GetNewMat(md2, p - md2, nMatInd11); + ScMatrix* mP2 = GetNewMat(p - md2, p - md2, nMatInd12); + if (!mP2 || !mU2 || !mGs|| !mG || !mEInv || !mF || !mE) + return FALSE; + MFastTrans(mP1, mP, p, p); // mP = mP1 hoch -1 + ScMatrix* mD = mB; // mB wird nicht mehr gebraucht + MFastMult(mC, mP, mD, md2, p, p); + for (i = 0; i < md2; i++) + { + for (j = 0; j < md2; j++) + { + mE->PutDouble(mU1->GetDouble(i, j), i, j); + mF->PutDouble(mD->GetDouble(i, j), i, j); + } + } + BOOL bEInvok = MFastBackSubst(mE, mEInv, md2, TRUE); // MeInv = E hoch -1 + if (!bEInvok) + { + bIsInvertable = FALSE; + ResetNewMat(nMatInd12); + ResetNewMat(nMatInd11); + ResetNewMat(nMatInd10); + ResetNewMat(nMatInd9); + ResetNewMat(nMatInd8); + ResetNewMat(nMatInd7); + ResetNewMat(nMatInd6); + ResetNewMat(nMatInd5); + ResetNewMat(nMatInd4); + ResetNewMat(nMatInd3); + ResetNewMat(nMatInd2); + ResetNewMat(nMatInd1); + delete mP2; + delete mU2; + delete mGs; + delete mG; + delete mEInv; + delete mF; + delete mE; + delete mP1; + delete mU1; + delete mL1; + delete mC; + delete mB; + return TRUE; + } + ScMatrix* mFEInv = mE; // mE wird nicht mehr gebraucht. + MFastMult(mF, mEInv, mFEInv, md2, md2, md2); + ScMatrix* mFEInvU1 = mC; // mC wird nicht mehr gebraucht + MFastMult(mFEInv, mU1, mFEInvU1, md2, md2, p); + MFastSub(mD, mFEInvU1, mG, md2, p); + for (i = 0; i < md2; i++) + { + for (j = 0; j < p-md2; j++) + mGs->PutDouble(mG->GetDouble(i, md2+j), i, j); + } + ScMatrix* mL2 = mF; // mF wird nicht mehr gebraucht + if (!ScMatLUP(mGs, md2, p - md2, mL2, mU2, mP2, rPermutCounter, bIsInvertable)) + return FALSE; + if (!bIsInvertable) + { + ResetNewMat(nMatInd12); + ResetNewMat(nMatInd11); + ResetNewMat(nMatInd10); + ResetNewMat(nMatInd9); + ResetNewMat(nMatInd8); + ResetNewMat(nMatInd7); + ResetNewMat(nMatInd6); + ResetNewMat(nMatInd5); + ResetNewMat(nMatInd4); + ResetNewMat(nMatInd3); + ResetNewMat(nMatInd2); + ResetNewMat(nMatInd1); + delete mP2; + delete mU2; + delete mGs; + delete mG; + delete mEInv; + delete mF; + delete mE; + delete mP1; + delete mU1; + delete mL1; + delete mC; + delete mB; + return TRUE; + } + ScMatrix* mP3 = GetNewMat(p, p, nMatInd13); + if (!mP3) + return FALSE; + MEMat(mP3, p); + for (i = md2; i < p; i++) + { + for (j = md2; j < p; j++) + mP3->PutDouble(mP2->GetDouble(i-md2, j-md2), i, j); + } + MFastMult(mP3, mP1, mP, p, p, p); // Ergebnis P !! + ScMatrix* mP3Inv = mP1; // mP1 wird nicht mehr gebraucht; + MFastTrans(mP3, mP3Inv, p, p); + ScMatrix* mH = mD; // mD wird nicht mehr gebraucht + MFastMult(mU1, mP3Inv, mH, md2, p, p); + MEMat(mL, m); // Ergebnis L : + for (i = 0; i < md2; i++) + { + for (j = 0; j < i; j++) + mL->PutDouble(mL1->GetDouble(i, j), i, j); + } + for (i = md2; i < m; i++) + for (j = md2; j < i; j++) + mL->PutDouble(mL2->GetDouble(i-md2, j-md2), i, j); + for (i = md2; i < m; i++) + for (j = 0; j < md2; j++) + mL->PutDouble(mFEInv->GetDouble(i-md2, j), i, j); + // Ergebnis U: + mU->FillDoubleLowerLeft(0.0, m-1); + for (i = 0; i < md2; i++) + for (j = i; j < p; j++) + mU->PutDouble(mH->GetDouble(i, j), i, j); + for (i = md2; i < m; i++) + for (j = i; j < p; j++) + mU->PutDouble(mU2->GetDouble(i - md2, j - md2), i, j); + ResetNewMat(nMatInd13); // alle wieder freigeben; + ResetNewMat(nMatInd12); + ResetNewMat(nMatInd11); + ResetNewMat(nMatInd10); + ResetNewMat(nMatInd9); + ResetNewMat(nMatInd8); + ResetNewMat(nMatInd7); + ResetNewMat(nMatInd6); + ResetNewMat(nMatInd5); + ResetNewMat(nMatInd4); + ResetNewMat(nMatInd3); + ResetNewMat(nMatInd2); + ResetNewMat(nMatInd1); + delete mP3; + delete mP2; + delete mU2; + delete mGs; + delete mG; + delete mEInv; + delete mF; + delete mE; + delete mP1; + delete mU1; + delete mL1; + delete mC; + delete mB; + } + return TRUE; +} + +void ScInterpreter::ScMatDet() +{ + if ( MustHaveParamCount( GetByte(), 1 ) ) + { + USHORT nMatInd; + ScMatrix* pMat = GetMatrix(nMatInd); + if (!pMat) + { + SetIllegalParameter(); + return; + } + if ( !pMat->IsNumeric() ) + { + SetNoValue(); + return; + } + USHORT nC, nR; + pMat->GetDimensions(nC, nR); + if ( nC != nR || nC == 0 || (ULONG) nC * nC > ScMatrix::GetElementsMax() ) + SetIllegalParameter(); + else + { + double fVal = log((double)nC) / log(2.0); + if (fVal - floor(fVal) != 0.0) + fVal = floor(fVal) + 1.0; + USHORT nDim = (USHORT) pow(2.0, fVal); + USHORT nMatInd1, nMatInd2, nMatInd3; + USHORT nMatInd4 = MAX_ANZ_MAT; + ScMatrix* pU = GetNewMat(nDim, nDim, nMatInd1); + ScMatrix* pL = GetNewMat(nDim, nDim, nMatInd2); + ScMatrix* pP = GetNewMat(nDim, nDim, nMatInd3); + ScMatrix* pA; + if (nC == nDim) + pA = pMat; + else + { + pA = GetNewMat(nDim, nDim, nMatInd4); + MEMat(pA, nDim); + for (USHORT i = 0; i < nC; i++) + for (USHORT j = 0; j < nC; j++) + { + pA->PutDouble(pMat->GetDouble(i, j), i, j); + } + } + ULONG nPermutCounter = 0; + BOOL bIsInvertable = TRUE; + BOOL bOk = ScMatLUP(pA, nDim, nDim, pL, pU, pP, + nPermutCounter, bIsInvertable); + ResetNewMat(nMatInd4); + ResetNewMat(nMatInd3); + ResetNewMat(nMatInd2); + if (nC != nDim) + delete pA; + delete pP; + delete pL; + if (bOk) + { + if (!bIsInvertable) + PushInt(0); + else + { + double fDet = 1.0; + for (USHORT i = 0; i < nC; i++) + fDet *= pU->GetDouble(i, i); + if (nPermutCounter % 2 != 0) + fDet *= -1.0; + PushDouble(fDet); + } + } + else + { + SetError(errCodeOverflow); + PushInt(0); + } + ResetNewMat(nMatInd1); + delete pU; + } + } +} + +void ScInterpreter::ScMatInv() +{ + if ( MustHaveParamCount( GetByte(), 1 ) ) + { + USHORT nMatInd; + ScMatrix* pMat = GetMatrix(nMatInd); + if (!pMat) + { + SetIllegalParameter(); + return; + } + if ( !pMat->IsNumeric() ) + { + SetNoValue(); + return; + } + USHORT nC, nR; + pMat->GetDimensions(nC, nR); + if ( nC != nR || nC == 0 || (ULONG) nC * nC > ScMatrix::GetElementsMax() ) + SetIllegalParameter(); + else + { + double fVal = log((double)nC) / log(2.0); + if (fVal - floor(fVal) != 0.0) + fVal = floor(fVal) + 1.0; + USHORT nDim = (USHORT) pow(2.0, fVal); + USHORT nMatInd1, nMatInd2, nMatInd3; + USHORT nMatInd4 = MAX_ANZ_MAT; + ScMatrix* pU = GetNewMat(nDim, nDim, nMatInd1); + ScMatrix* pL = GetNewMat(nDim, nDim, nMatInd2); + ScMatrix* pP = GetNewMat(nDim, nDim, nMatInd3); + ScMatrix* pA; + if (nC == nDim) + pA = pMat; + else + { + pA = GetNewMat(nDim, nDim, nMatInd4); + MEMat(pA, nDim); + for (USHORT i = 0; i < nC; i++) + for (USHORT j = 0; j < nC; j++) + { + pA->PutDouble(pMat->GetDouble(i, j), i, j); + } + } + ULONG nPermutCounter = 0; + BOOL bIsInvertable = TRUE; + BOOL bOk = ScMatLUP(pA, nDim, nDim, pL, pU, pP, + nPermutCounter, bIsInvertable); + if (bOk) + { + if (!bIsInvertable) + SetNoValue(); + else + { + USHORT nMatInd5; + ScMatrix* pUInv = GetNewMat(nDim, nDim, nMatInd5); + if (!pUInv) + PushInt(0); + else + { + bOk = MFastBackSubst(pU, pUInv, nDim, TRUE); + if (!bOk) + SetNoValue(); + else + { + ScMatrix* pPInv = pU; + MFastTrans(pP, pPInv, nDim, nDim); + ScMatrix* pPInvUInv = pP; + MFastMult(pPInv, pUInv, pPInvUInv, nDim, nDim, nDim); + ScMatrix* pLInv = pPInv; + MFastBackSubst(pL, pLInv, nDim, FALSE); + if (nDim == nC) + MFastMult(pPInvUInv, pLInv, pMat, nDim, nDim, nDim); + else + { + MFastMult(pPInvUInv, pLInv, pL, nDim, nDim, nDim); + for (USHORT i = 0; i < nC; i++) + for (USHORT j = 0; j < nC; j++) + pMat->PutDouble(pL->GetDouble(i, j), i, j); + } + PushMatrix(pMat); + if (nMatInd != MAX_ANZ_MAT) // vorher neue Matrix + nRetMat = nMatInd; // sonst nRetMat wie vorher + ResetNewMat(nMatInd5); + delete pUInv; + } + } + } + } + else + { + SetError(errCodeOverflow); + PushInt(0); + } + ResetNewMat(nMatInd4); + ResetNewMat(nMatInd3); + ResetNewMat(nMatInd2); + ResetNewMat(nMatInd1); + if (nC != nDim) + delete pA; + delete pP; + delete pL; + delete pU; + } + } +} + +void ScInterpreter::ScMatMult() +{ + if ( MustHaveParamCount( GetByte(), 2 ) ) + { + USHORT nMatInd1, nMatInd2; + ScMatrix* pMat2 = GetMatrix(nMatInd2); + ScMatrix* pMat1 = GetMatrix(nMatInd1); + ScMatrix* pRMat; + if (pMat1 && pMat2) + { + if ( pMat1->IsNumeric() && pMat2->IsNumeric() ) + { + USHORT nC1, nR1, nC2, nR2; + pMat1->GetDimensions(nC1, nR1); + pMat2->GetDimensions(nC2, nR2); + if (nC1 != nR2) + SetIllegalParameter(); + else + { + USHORT nMatInd; + pRMat = GetNewMat(nC2, nR1, nMatInd); // Matrixabsicherung + if (pRMat) + { + double sum; + for (USHORT i = 0; i < nR1; i++) + { + for (USHORT j = 0; j < nC2; j++) + { + sum = 0.0; + for (USHORT k = 0; k < nC1; k++) + { + sum += pMat1->GetDouble(k,i)*pMat2->GetDouble(j,k); + } + pRMat->PutDouble(sum, j, i); + } + } + PushMatrix(pRMat); + nRetMat = nMatInd; + } + else + SetNoValue(); + } + } + else + SetNoValue(); + } + else + SetIllegalParameter(); + } +} + +void ScInterpreter::ScMatTrans() +{ + if ( MustHaveParamCount( GetByte(), 1 ) ) + { + USHORT nMatInd, nMatInd1; + ScMatrix* pMat = GetMatrix(nMatInd); + ScMatrix* pRMat; + if (pMat) + { + USHORT nC, nR; + pMat->GetDimensions(nC, nR); + pRMat = GetNewMat(nR, nC, nMatInd1); + pMat->MatTrans(*pRMat); + PushMatrix(pRMat); + nRetMat = nMatInd1; + } + else + SetIllegalParameter(); + } +} + +/*N*/ ScMatrix* ScInterpreter::MatAdd(ScMatrix* pMat1, ScMatrix* pMat2) +/*N*/ { +/*N*/ USHORT nC1, nR1, nC2, nR2, nMinC, nMinR, i, j; +/*N*/ pMat1->GetDimensions(nC1, nR1); +/*N*/ pMat2->GetDimensions(nC2, nR2); +/*N*/ if (nC1 < nC2) +/*N*/ nMinC = nC1; +/*N*/ else +/*N*/ nMinC = nC2; +/*N*/ if (nR1 < nR2) +/*N*/ nMinR = nR1; +/*N*/ else +/*N*/ nMinR = nR2; +/*N*/ USHORT nMatInd; +/*N*/ ScMatrix* pResMat = GetNewMat(nMinC, nMinR, nMatInd); +/*N*/ if (pResMat) +/*N*/ { +/*N*/ for (i = 0; i < nMinC; i++) +/*N*/ { +/*N*/ for (j = 0; j < nMinR; j++) +/*N*/ { +/*N*/ if (pMat1->IsValueOrEmpty(i,j) && pMat2->IsValueOrEmpty(i,j)) +/*N*/ pResMat->PutDouble( ::rtl::math::approxAdd( pMat1->GetDouble(i,j), +/*N*/ pMat2->GetDouble(i,j)), i, j); +/*N*/ else +/*?*/ pResMat->PutString(ScGlobal::GetRscString( +/*N*/ STR_NO_VALUE), i, j); +/*N*/ } +/*N*/ } +/*N*/ nRetMat = nMatInd; +/*N*/ } +/*N*/ return pResMat; +/*N*/ } + +ScMatrix* ScInterpreter::MatSub(ScMatrix* pMat1, ScMatrix* pMat2) +{ + USHORT nC1, nR1, nC2, nR2, nMinC, nMinR, i, j; + pMat1->GetDimensions(nC1, nR1); + pMat2->GetDimensions(nC2, nR2); + if (nC1 < nC2) + nMinC = nC1; + else + nMinC = nC2; + if (nR1 < nR2) + nMinR = nR1; + else + nMinR = nR2; + USHORT nMatInd; + ScMatrix* pResMat = GetNewMat(nMinC, nMinR, nMatInd); + if (pResMat) + { + for (i = 0; i < nMinC; i++) + { + for (j = 0; j < nMinR; j++) + { + if (pMat1->IsValueOrEmpty(i,j) && pMat2->IsValueOrEmpty(i,j)) + pResMat->PutDouble( ::rtl::math::approxSub( pMat1->GetDouble(i,j), + pMat2->GetDouble(i,j)), i, j); + else + pResMat->PutString(ScGlobal::GetRscString( + STR_NO_VALUE), i, j); + } + } + nRetMat = nMatInd; + } + return pResMat; +} + +/*N*/ ScMatrix* ScInterpreter::MatMul(ScMatrix* pMat1, ScMatrix* pMat2) +/*N*/ { +/*N*/ USHORT nC1, nR1, nC2, nR2, nMinC, nMinR, i, j; +/*N*/ pMat1->GetDimensions(nC1, nR1); +/*N*/ pMat2->GetDimensions(nC2, nR2); +/*N*/ if (nC1 < nC2) +/*N*/ nMinC = nC1; +/*N*/ else +/*N*/ nMinC = nC2; +/*N*/ if (nR1 < nR2) +/*N*/ nMinR = nR1; +/*N*/ else +/*N*/ nMinR = nR2; +/*N*/ USHORT nMatInd; +/*N*/ ScMatrix* pResMat = GetNewMat(nMinC, nMinR, nMatInd); +/*N*/ if (pResMat) +/*N*/ { +/*N*/ for (i = 0; i < nMinC; i++) +/*N*/ { +/*N*/ for (j = 0; j < nMinR; j++) +/*N*/ { +/*N*/ if (pMat1->IsValueOrEmpty(i,j) && pMat2->IsValueOrEmpty(i,j)) +/*N*/ pResMat->PutDouble(pMat1->GetDouble(i,j) * +/*N*/ pMat2->GetDouble(i,j), i, j); +/*N*/ else +/*?*/ pResMat->PutString(ScGlobal::GetRscString( +/*N*/ STR_NO_VALUE), i, j); +/*N*/ } +/*N*/ } +/*N*/ nRetMat = nMatInd; +/*N*/ } +/*N*/ return pResMat; +/*N*/ } + +ScMatrix* ScInterpreter::MatDiv(ScMatrix* pMat1, ScMatrix* pMat2) +{ + USHORT nC1, nR1, nC2, nR2, nMinC, nMinR, i, j; + pMat1->GetDimensions(nC1, nR1); + pMat2->GetDimensions(nC2, nR2); + if (nC1 < nC2) + nMinC = nC1; + else + nMinC = nC2; + if (nR1 < nR2) + nMinR = nR1; + else + nMinR = nR2; + USHORT nMatInd; + ScMatrix* pResMat = GetNewMat(nMinC, nMinR, nMatInd); + if (pResMat) + { + for (i = 0; i < nMinC; i++) + { + for (j = 0; j < nMinR; j++) + { + if (pMat1->IsValueOrEmpty(i,j) && pMat2->IsValueOrEmpty(i,j)) + pResMat->PutDouble(pMat1->GetDouble(i,j) / + pMat2->GetDouble(i,j), i, j); + else + pResMat->PutString(ScGlobal::GetRscString( + STR_NO_VALUE), i, j); + } + } + nRetMat = nMatInd; + } + return pResMat; +} + +ScMatrix* ScInterpreter::MatPow(ScMatrix* pMat1, ScMatrix* pMat2) +{ + USHORT nC1, nR1, nC2, nR2, nMinC, nMinR, i, j; + pMat1->GetDimensions(nC1, nR1); + pMat2->GetDimensions(nC2, nR2); + if (nC1 < nC2) + nMinC = nC1; + else + nMinC = nC2; + if (nR1 < nR2) + nMinR = nR1; + else + nMinR = nR2; + USHORT nMatInd; + ScMatrix* pResMat = GetNewMat(nMinC, nMinR, nMatInd); + if (pResMat) + { + for (i = 0; i < nMinC; i++) + { + for (j = 0; j < nMinR; j++) + { + if (pMat1->IsValueOrEmpty(i,j) && pMat2->IsValueOrEmpty(i,j)) + pResMat->PutDouble(pow(pMat1->GetDouble(i,j), + pMat2->GetDouble(i,j)), i, j); + else + pResMat->PutString(ScGlobal::GetRscString( + STR_NO_VALUE), i, j); + } + } + nRetMat = nMatInd; + } + return pResMat; +} + +ScMatrix* ScInterpreter::MatConcat(ScMatrix* pMat1, ScMatrix* pMat2) +{ + USHORT nC1, nR1, nC2, nR2, nMinC, nMinR, i, j; + pMat1->GetDimensions(nC1, nR1); + pMat2->GetDimensions(nC2, nR2); + if (nC1 < nC2) + nMinC = nC1; + else + nMinC = nC2; + if (nR1 < nR2) + nMinR = nR1; + else + nMinR = nR2; + USHORT nMatInd; + ScMatrix* pResMat = GetNewMat(nMinC, nMinR, nMatInd); + if (pResMat) + { + for (i = 0; i < nMinC; i++) + { + for (j = 0; j < nMinR; j++) + { + if (pMat1->IsString(i,j) && pMat2->IsString(i,j)) + { + String aTmp( pMat1->GetString(i,j) ); + aTmp += pMat2->GetString(i,j); + pResMat->PutString( aTmp , i, j); + } + else + pResMat->PutString(ScGlobal::GetRscString( + STR_NO_VALUE), i, j); +//! TODO: Xcl does concatenate value strings + } + } + nRetMat = nMatInd; + } + return pResMat; +} + + +// fuer DATE, TIME, DATETIME +/*N*/ void lcl_GetDiffDateTimeFmtType( short& nFuncFmt, short nFmt1, short nFmt2 ) +/*N*/ { +/*N*/ if ( nFmt1 != NUMBERFORMAT_UNDEFINED || nFmt2 != NUMBERFORMAT_UNDEFINED ) +/*N*/ { +/*N*/ if ( nFmt1 == nFmt2 ) +/*N*/ { +/*N*/ if ( nFmt1 == NUMBERFORMAT_TIME || nFmt1 == NUMBERFORMAT_DATETIME ) +/*N*/ nFuncFmt = NUMBERFORMAT_TIME; // Zeiten ergeben Zeit +/*N*/ // else: nichts besonderes, Zahl (Datum - Datum := Tage) +/*N*/ } +/*N*/ else if ( nFmt1 == NUMBERFORMAT_UNDEFINED ) +/*N*/ nFuncFmt = nFmt2; // z.B. Datum + Tage := Datum +/*N*/ else if ( nFmt2 == NUMBERFORMAT_UNDEFINED ) +/*N*/ nFuncFmt = nFmt1; +/*N*/ else +/*N*/ { +/*N*/ if ( nFmt1 == NUMBERFORMAT_DATE || nFmt2 == NUMBERFORMAT_DATE || +/*N*/ nFmt1 == NUMBERFORMAT_DATETIME || nFmt2 == NUMBERFORMAT_DATETIME ) +/*N*/ { +/*N*/ if ( nFmt1 == NUMBERFORMAT_TIME || nFmt2 == NUMBERFORMAT_TIME ) +/*N*/ nFuncFmt = NUMBERFORMAT_DATETIME; // Datum + Zeit +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + + +/*N*/ void ScInterpreter::ScAdd() +/*N*/ { +/*N*/ ScMatrix* pMat1 = NULL; +/*N*/ ScMatrix* pMat2 = NULL; +/*N*/ double fVal1 = 0.0, fVal2 = 0.0; +/*N*/ USHORT nMatInd1, nMatInd2; +/*N*/ short nFmt1, nFmt2; +/*N*/ nFmt1 = nFmt2 = NUMBERFORMAT_UNDEFINED; +/*N*/ short nFmtCurrencyType = nCurFmtType; +/*N*/ ULONG nFmtCurrencyIndex = nCurFmtIndex; +/*N*/ short nFmtPercentType = nCurFmtType; +/*N*/ MatrixDoubleRefToMatrix(); +/*N*/ if ( GetStackType() == svMatrix ) +/*N*/ pMat2 = GetMatrix(nMatInd2); +/*N*/ else +/*N*/ { +/*N*/ fVal2 = GetDouble(); +/*N*/ switch ( nCurFmtType ) +/*N*/ { +/*N*/ case NUMBERFORMAT_DATE : +/*N*/ case NUMBERFORMAT_TIME : +/*N*/ case NUMBERFORMAT_DATETIME : +/*N*/ nFmt2 = nCurFmtType; +/*N*/ break; +/*N*/ case NUMBERFORMAT_CURRENCY : +/*N*/ nFmtCurrencyType = nCurFmtType; +/*N*/ nFmtCurrencyIndex = nCurFmtIndex; +/*N*/ break; +/*N*/ case NUMBERFORMAT_PERCENT : +/*N*/ nFmtPercentType = NUMBERFORMAT_PERCENT; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ MatrixDoubleRefToMatrix(); +/*N*/ if ( GetStackType() == svMatrix ) +/*N*/ pMat1 = GetMatrix(nMatInd1); +/*N*/ else +/*N*/ { +/*N*/ fVal1 = GetDouble(); +/*N*/ switch ( nCurFmtType ) +/*N*/ { +/*N*/ case NUMBERFORMAT_DATE : +/*N*/ case NUMBERFORMAT_TIME : +/*N*/ case NUMBERFORMAT_DATETIME : +/*N*/ nFmt1 = nCurFmtType; +/*N*/ break; +/*N*/ case NUMBERFORMAT_CURRENCY : +/*N*/ nFmtCurrencyType = nCurFmtType; +/*N*/ nFmtCurrencyIndex = nCurFmtIndex; +/*N*/ break; +/*N*/ case NUMBERFORMAT_PERCENT : +/*N*/ nFmtPercentType = NUMBERFORMAT_PERCENT; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ if (pMat1 && pMat2) +/*N*/ { +/*N*/ ScMatrix* pResMat = MatAdd(pMat1, pMat2); +/*N*/ if (!pResMat) +/*?*/ SetNoValue(); +/*N*/ else +/*N*/ PushMatrix(pResMat); +/*N*/ } +/*N*/ else if (pMat1 || pMat2) +/*N*/ { +/*?*/ double fVal; +/*?*/ ScMatrix* pMat = pMat1; +/*?*/ if (!pMat) +/*?*/ { +/*?*/ fVal = fVal1; +/*?*/ pMat = pMat2; +/*?*/ } +/*?*/ else +/*?*/ fVal = fVal2; +/*?*/ USHORT nC, nR; +/*?*/ pMat->GetDimensions(nC, nR); +/*?*/ USHORT nMatInd; +/*?*/ ScMatrix* pResMat = GetNewMat(nC, nR, nMatInd); +/*?*/ if (pResMat) +/*?*/ { +/*?*/ ULONG nCount = (ULONG) nC * nR; +/*?*/ for ( ULONG i = 0; i < nCount; i++ ) +/*?*/ { +/*?*/ if (pMat->IsValue(i)) +/*?*/ pResMat->PutDouble( ::rtl::math::approxAdd( pMat->GetDouble(i), fVal), i); +/*?*/ else +/*?*/ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); +/*?*/ } +/*?*/ PushMatrix(pResMat); +/*?*/ nRetMat = nMatInd; +/*?*/ } +/*?*/ else +/*?*/ SetNoValue(); +/*N*/ } +/*N*/ else +/*N*/ PushDouble( ::rtl::math::approxAdd( fVal1, fVal2 ) ); +/*N*/ if ( nFmtCurrencyType == NUMBERFORMAT_CURRENCY ) +/*N*/ { +/*N*/ nFuncFmtType = nFmtCurrencyType; +/*N*/ nFuncFmtIndex = nFmtCurrencyIndex; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ lcl_GetDiffDateTimeFmtType( nFuncFmtType, nFmt1, nFmt2 ); +/*N*/ if ( nFmtPercentType == NUMBERFORMAT_PERCENT && nFuncFmtType == NUMBERFORMAT_NUMBER ) +/*N*/ nFuncFmtType = NUMBERFORMAT_PERCENT; +/*N*/ } +/*N*/ } + +/*N*/ void ScInterpreter::ScAmpersand() +/*N*/ { +/*N*/ ScMatrix* pMat1 = NULL; +/*N*/ ScMatrix* pMat2 = NULL; +/*N*/ String sStr1, sStr2; +/*N*/ USHORT nMatInd1, nMatInd2; +/*N*/ MatrixDoubleRefToMatrix(); +/*N*/ if ( GetStackType() == svMatrix ) +/*?*/ pMat2 = GetMatrix(nMatInd2); +/*N*/ else +/*N*/ sStr2 = GetString(); +/*N*/ MatrixDoubleRefToMatrix(); +/*N*/ if ( GetStackType() == svMatrix ) +/*?*/ pMat1 = GetMatrix(nMatInd1); +/*N*/ else +/*N*/ sStr1 = GetString(); +/*N*/ if (pMat1 && pMat2) +/*N*/ { +/*?*/ ScMatrix* pResMat = MatConcat(pMat1, pMat2); +/*?*/ if (!pResMat) +/*?*/ SetNoValue(); +/*?*/ else +/*?*/ PushMatrix(pResMat); +/*N*/ } +/*N*/ else if (pMat1 || pMat2) +/*N*/ { +/*?*/ String sStr; +/*?*/ BOOL bFlag; +/*?*/ ScMatrix* pMat = pMat1; +/*?*/ if (!pMat) +/*?*/ { +/*?*/ sStr = sStr1; +/*?*/ pMat = pMat2; +/*?*/ bFlag = TRUE; // double - Matrix +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ sStr = sStr2; +/*?*/ bFlag = FALSE; // Matrix - double +/*?*/ } +/*?*/ USHORT nC, nR; +/*?*/ pMat->GetDimensions(nC, nR); +/*?*/ USHORT nMatInd; +/*?*/ ScMatrix* pResMat = GetNewMat(nC, nR, nMatInd); +/*?*/ if (pResMat) +/*?*/ { +/*?*/ ULONG nCount = (ULONG) nC * nR; +/*?*/ if (bFlag) +/*?*/ { +/*?*/ for ( ULONG i = 0; i < nCount; i++ ) +/*?*/ if (!pMat->IsValue(i)) +/*?*/ { +/*?*/ String sS = sStr; +/*?*/ sS += pMat->GetString(i); +/*?*/ pResMat->PutString(sS, i); +/*?*/ } +/*?*/ else +/*?*/ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ for ( ULONG i = 0; i < nCount; i++ ) +/*?*/ if (!pMat->IsValue(i)) +/*?*/ { +/*?*/ String sS = pMat->GetString(i); +/*?*/ sS += sStr; +/*?*/ pResMat->PutString(sS, i); +/*?*/ } +/*?*/ else +/*?*/ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); +/*?*/ } +/*?*/ PushMatrix(pResMat); +/*?*/ nRetMat = nMatInd; +/*?*/ } +/*?*/ else +/*?*/ SetNoValue(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( CheckStringResultLen( sStr1, sStr2 ) ) +/*N*/ sStr1 += sStr2; +/*N*/ PushString(sStr1); +/*N*/ } +/*N*/ } + +/*N*/ void ScInterpreter::ScSub() +/*N*/ { +/*N*/ ScMatrix* pMat1 = NULL; +/*N*/ ScMatrix* pMat2 = NULL; +/*N*/ double fVal1 = 0.0, fVal2 = 0.0; +/*N*/ USHORT nMatInd1, nMatInd2; +/*N*/ short nFmt1, nFmt2; +/*N*/ nFmt1 = nFmt2 = NUMBERFORMAT_UNDEFINED; +/*N*/ short nFmtCurrencyType = nCurFmtType; +/*N*/ ULONG nFmtCurrencyIndex = nCurFmtIndex; +/*N*/ short nFmtPercentType = nCurFmtType; +/*N*/ MatrixDoubleRefToMatrix(); +/*N*/ if ( GetStackType() == svMatrix ) +/*N*/ pMat2 = GetMatrix(nMatInd2); +/*N*/ else +/*N*/ { +/*N*/ fVal2 = GetDouble(); +/*N*/ switch ( nCurFmtType ) +/*N*/ { +/*N*/ case NUMBERFORMAT_DATE : +/*N*/ case NUMBERFORMAT_TIME : +/*N*/ case NUMBERFORMAT_DATETIME : +/*N*/ nFmt2 = nCurFmtType; +/*N*/ break; +/*N*/ case NUMBERFORMAT_CURRENCY : +/*N*/ nFmtCurrencyType = nCurFmtType; +/*N*/ nFmtCurrencyIndex = nCurFmtIndex; +/*N*/ break; +/*N*/ case NUMBERFORMAT_PERCENT : +/*N*/ nFmtPercentType = NUMBERFORMAT_PERCENT; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ MatrixDoubleRefToMatrix(); +/*N*/ if ( GetStackType() == svMatrix ) +/*?*/ pMat1 = GetMatrix(nMatInd1); +/*N*/ else +/*N*/ { +/*N*/ fVal1 = GetDouble(); +/*N*/ switch ( nCurFmtType ) +/*N*/ { +/*N*/ case NUMBERFORMAT_DATE : +/*N*/ case NUMBERFORMAT_TIME : +/*N*/ case NUMBERFORMAT_DATETIME : +/*N*/ nFmt1 = nCurFmtType; +/*N*/ break; +/*N*/ case NUMBERFORMAT_CURRENCY : +/*N*/ nFmtCurrencyType = nCurFmtType; +/*N*/ nFmtCurrencyIndex = nCurFmtIndex; +/*N*/ break; +/*N*/ case NUMBERFORMAT_PERCENT : +/*N*/ nFmtPercentType = NUMBERFORMAT_PERCENT; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ if (pMat1 && pMat2) +/*N*/ { +/*?*/ ScMatrix* pResMat = MatSub(pMat1, pMat2); +/*?*/ if (!pResMat) +/*?*/ SetNoValue(); +/*?*/ else +/*?*/ PushMatrix(pResMat); +/*N*/ } +/*N*/ else if (pMat1 || pMat2) +/*N*/ { +/*N*/ double fVal; +/*N*/ BOOL bFlag; +/*N*/ ScMatrix* pMat = pMat1; +/*N*/ if (!pMat) +/*N*/ { +/*N*/ fVal = fVal1; +/*N*/ pMat = pMat2; +/*N*/ bFlag = TRUE; // double - Matrix +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ fVal = fVal2; +/*N*/ bFlag = FALSE; // Matrix - double +/*N*/ } +/*N*/ USHORT nC, nR; +/*N*/ pMat->GetDimensions(nC, nR); +/*N*/ USHORT nMatInd; +/*N*/ ScMatrix* pResMat = GetNewMat(nC, nR, nMatInd); +/*N*/ if (pResMat) +/*N*/ { // mehr klammern wg. compiler macke +/*N*/ ULONG nCount = (ULONG) nC * nR; +/*N*/ if (bFlag) +/*N*/ { for ( ULONG i = 0; i < nCount; i++ ) +/*N*/ { if (pMat->IsValue(i)) +/*N*/ pResMat->PutDouble( ::rtl::math::approxSub( fVal, pMat->GetDouble(i)), i); +/*N*/ else +/*?*/ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); +/*N*/ } +/*N*/ } +/*N*/ else +/*?*/ { for ( ULONG i = 0; i < nCount; i++ ) +/*?*/ { if (pMat->IsValue(i)) +/*?*/ pResMat->PutDouble( ::rtl::math::approxSub( pMat->GetDouble(i), fVal), i); +/*?*/ else +/*?*/ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); +/*?*/ } +/*N*/ } +/*N*/ PushMatrix(pResMat); +/*N*/ nRetMat = nMatInd; +/*N*/ } +/*N*/ else +/*?*/ SetNoValue(); +/*N*/ } +/*N*/ else +/*N*/ PushDouble( ::rtl::math::approxSub( fVal1, fVal2 ) ); +/*N*/ if ( nFmtCurrencyType == NUMBERFORMAT_CURRENCY ) +/*N*/ { +/*N*/ nFuncFmtType = nFmtCurrencyType; +/*N*/ nFuncFmtIndex = nFmtCurrencyIndex; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ lcl_GetDiffDateTimeFmtType( nFuncFmtType, nFmt1, nFmt2 ); +/*N*/ if ( nFmtPercentType == NUMBERFORMAT_PERCENT && nFuncFmtType == NUMBERFORMAT_NUMBER ) +/*N*/ nFuncFmtType = NUMBERFORMAT_PERCENT; +/*N*/ } +/*N*/ } + +/*N*/ void ScInterpreter::ScMul() +/*N*/ { +/*N*/ ScMatrix* pMat1 = NULL; +/*N*/ ScMatrix* pMat2 = NULL; +/*N*/ double fVal1 = 0.0, fVal2 = 0.0; +/*N*/ USHORT nMatInd1, nMatInd2; +/*N*/ short nFmtCurrencyType = nCurFmtType; +/*N*/ ULONG nFmtCurrencyIndex = nCurFmtIndex; +/*N*/ MatrixDoubleRefToMatrix(); +/*N*/ if ( GetStackType() == svMatrix ) +/*N*/ pMat2 = GetMatrix(nMatInd2); +/*N*/ else +/*N*/ { +/*N*/ fVal2 = GetDouble(); +/*N*/ switch ( nCurFmtType ) +/*N*/ { +/*N*/ case NUMBERFORMAT_CURRENCY : +/*N*/ nFmtCurrencyType = nCurFmtType; +/*N*/ nFmtCurrencyIndex = nCurFmtIndex; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ MatrixDoubleRefToMatrix(); +/*N*/ if ( GetStackType() == svMatrix ) +/*N*/ pMat1 = GetMatrix(nMatInd1); +/*N*/ else +/*N*/ { +/*N*/ fVal1 = GetDouble(); +/*N*/ switch ( nCurFmtType ) +/*N*/ { +/*N*/ case NUMBERFORMAT_CURRENCY : +/*N*/ nFmtCurrencyType = nCurFmtType; +/*N*/ nFmtCurrencyIndex = nCurFmtIndex; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ if (pMat1 && pMat2) +/*N*/ { +/*N*/ ScMatrix* pResMat = MatMul(pMat1, pMat2); +/*N*/ if (!pResMat) +/*?*/ SetNoValue(); +/*N*/ else +/*N*/ PushMatrix(pResMat); +/*N*/ } +/*N*/ else if (pMat1 || pMat2) +/*N*/ { +/*N*/ double fVal; +/*N*/ ScMatrix* pMat = pMat1; +/*N*/ if (!pMat) +/*N*/ { +/*N*/ fVal = fVal1; +/*N*/ pMat = pMat2; +/*N*/ } +/*N*/ else +/*N*/ fVal = fVal2; +/*N*/ USHORT nC, nR; +/*N*/ pMat->GetDimensions(nC, nR); +/*N*/ USHORT nMatInd; +/*N*/ ScMatrix* pResMat = GetNewMat(nC, nR, nMatInd); +/*N*/ if (pResMat) +/*N*/ { +/*N*/ ULONG nCount = (ULONG) nC * nR; +/*N*/ for ( ULONG i = 0; i < nCount; i++ ) +/*N*/ if (pMat->IsValue(i)) +/*N*/ pResMat->PutDouble(pMat->GetDouble(i)*fVal, i); +/*N*/ else +/*N*/ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); +/*N*/ PushMatrix(pResMat); +/*N*/ nRetMat = nMatInd; +/*N*/ } +/*N*/ else +/*?*/ SetNoValue(); +/*N*/ } +/*N*/ else +/*N*/ PushDouble(fVal1 * fVal2); +/*N*/ if ( nFmtCurrencyType == NUMBERFORMAT_CURRENCY ) +/*N*/ { +/*N*/ nFuncFmtType = nFmtCurrencyType; +/*N*/ nFuncFmtIndex = nFmtCurrencyIndex; +/*N*/ } +/*N*/ } + +/*N*/ void ScInterpreter::ScDiv() +/*N*/ { +/*N*/ ScMatrix* pMat1 = NULL; +/*N*/ ScMatrix* pMat2 = NULL; +/*N*/ double fVal1 = 0.0, fVal2 = 0.0; +/*N*/ USHORT nMatInd1, nMatInd2; +/*N*/ short nFmtCurrencyType = nCurFmtType; +/*N*/ ULONG nFmtCurrencyIndex = nCurFmtIndex; +/*N*/ short nFmtCurrencyType2 = NUMBERFORMAT_UNDEFINED; +/*N*/ MatrixDoubleRefToMatrix(); +/*N*/ if ( GetStackType() == svMatrix ) +/*?*/ pMat2 = GetMatrix(nMatInd2); +/*N*/ else +/*N*/ { +/*N*/ fVal2 = GetDouble(); +/*N*/ // hier kein Currency uebernehmen, 123kg/456DM sind nicht DM +/*N*/ nFmtCurrencyType2 = nCurFmtType; +/*N*/ } +/*N*/ MatrixDoubleRefToMatrix(); +/*N*/ if ( GetStackType() == svMatrix ) +/*?*/ pMat1 = GetMatrix(nMatInd1); +/*N*/ else +/*N*/ { +/*N*/ fVal1 = GetDouble(); +/*N*/ switch ( nCurFmtType ) +/*N*/ { +/*N*/ case NUMBERFORMAT_CURRENCY : +/*N*/ nFmtCurrencyType = nCurFmtType; +/*N*/ nFmtCurrencyIndex = nCurFmtIndex; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ if (pMat1 && pMat2) +/*N*/ { +/*?*/ ScMatrix* pResMat = MatDiv(pMat1, pMat2); +/*?*/ if (!pResMat) +/*?*/ SetNoValue(); +/*?*/ else +/*?*/ PushMatrix(pResMat); +/*N*/ } +/*N*/ else if (pMat1 || pMat2) +/*N*/ { +/*?*/ double fVal; +/*?*/ BOOL bFlag; +/*?*/ ScMatrix* pMat = pMat1; +/*?*/ if (!pMat) +/*?*/ { +/*?*/ fVal = fVal1; +/*?*/ pMat = pMat2; +/*?*/ bFlag = TRUE; // double - Matrix +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ fVal = fVal2; +/*?*/ bFlag = FALSE; // Matrix - double +/*?*/ } +/*?*/ USHORT nC, nR; +/*?*/ pMat->GetDimensions(nC, nR); +/*?*/ USHORT nMatInd; +/*?*/ ScMatrix* pResMat = GetNewMat(nC, nR, nMatInd); +/*?*/ if (pResMat) +/*?*/ { +/*?*/ ULONG nCount = (ULONG) nC * nR; +/*?*/ if (bFlag) +/*?*/ { for ( ULONG i = 0; i < nCount; i++ ) +/*?*/ if (pMat->IsValue(i)) +/*?*/ pResMat->PutDouble(fVal / pMat->GetDouble(i), i); +/*?*/ else +/*?*/ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); +/*?*/ } +/*?*/ else +/*?*/ { for ( ULONG i = 0; i < nCount; i++ ) +/*?*/ if (pMat->IsValue(i)) +/*?*/ pResMat->PutDouble(pMat->GetDouble(i) / fVal, i); +/*?*/ else +/*?*/ pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); +/*?*/ } +/*?*/ PushMatrix(pResMat); +/*?*/ nRetMat = nMatInd; +/*?*/ } +/*?*/ else +/*?*/ SetNoValue(); +/*N*/ } +/*N*/ else +/*N*/ PushDouble(fVal1 / fVal2); +/*N*/ if ( nFmtCurrencyType == NUMBERFORMAT_CURRENCY && nFmtCurrencyType2 != NUMBERFORMAT_CURRENCY ) +/*N*/ { // auch DM/DM ist nicht DM bzw. DEM/EUR nicht DEM +/*N*/ nFuncFmtType = nFmtCurrencyType; +/*N*/ nFuncFmtIndex = nFmtCurrencyIndex; +/*N*/ } +/*N*/ } + +void ScInterpreter::ScPower() +{ + if ( MustHaveParamCount( GetByte(), 2 ) ) + ScPow(); +} + +void ScInterpreter::ScPow() +{ + ScMatrix* pMat1 = NULL; + ScMatrix* pMat2 = NULL; + double fVal1 = 0.0, fVal2 = 0.0; + USHORT nMatInd1, nMatInd2; + MatrixDoubleRefToMatrix(); + if ( GetStackType() == svMatrix ) + pMat2 = GetMatrix(nMatInd2); + else + fVal2 = GetDouble(); + MatrixDoubleRefToMatrix(); + if ( GetStackType() == svMatrix ) + pMat1 = GetMatrix(nMatInd1); + else + fVal1 = GetDouble(); + if (pMat1 && pMat2) + { + ScMatrix* pResMat = MatPow(pMat1, pMat2); + if (!pResMat) + SetNoValue(); + else + PushMatrix(pResMat); + } + else if (pMat1 || pMat2) + { + double fVal; + BOOL bFlag; + ScMatrix* pMat = pMat1; + if (!pMat) + { + fVal = fVal1; + pMat = pMat2; + bFlag = TRUE; // double - Matrix + } + else + { + fVal = fVal2; + bFlag = FALSE; // Matrix - double + } + USHORT nC, nR; + pMat->GetDimensions(nC, nR); + USHORT nMatInd; + ScMatrix* pResMat = GetNewMat(nC, nR, nMatInd); + if (pResMat) + { + ULONG nCount = (ULONG) nC * nR; + if (bFlag) + { for ( ULONG i = 0; i < nCount; i++ ) + if (pMat->IsValue(i)) + pResMat->PutDouble(pow(fVal,pMat->GetDouble(i)), i); + else + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); + } + else + { for ( ULONG i = 0; i < nCount; i++ ) + if (pMat->IsValue(i)) + pResMat->PutDouble(pow(pMat->GetDouble(i),fVal), i); + else + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); + } + PushMatrix(pResMat); + nRetMat = nMatInd; + } + else + SetNoValue(); + } + else + PushDouble(pow(fVal1,fVal2)); +} + +void ScInterpreter::ScSumProduct() +{ + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 1, 30 ) ) + return; + + ScMatrix* pMat1 = NULL; + ScMatrix* pMat2 = NULL; + ScMatrix* pMat = NULL; + USHORT nMatInd1, nMatInd2; + pMat2 = GetMatrix(nMatInd2); + if (!pMat2) + { + SetIllegalParameter(); + return; + } + USHORT nC, nR, nC1, nR1; + pMat2->GetDimensions(nC, nR); + pMat = pMat2; + for (USHORT i = 1; i < nParamCount; i++) + { + pMat1 = GetMatrix(nMatInd1); + if (!pMat1) + { + SetIllegalParameter(); + return; + } + pMat1->GetDimensions(nC1, nR1); + if (nC1 != nC || nR1 != nR) + { + SetNoValue(); + return; + } + ScMatrix* pResMat = MatMul(pMat1, pMat); + if (!pResMat) + { + SetNoValue(); + return; + } + else + pMat = pResMat; + } + double fSum = 0.0; + ULONG nCount = pMat->GetElementCount(); + for (ULONG j = 0; j < nCount; j++) + if (!pMat->IsString(j)) + fSum += pMat->GetDouble(j); + PushDouble(fSum); +} + +void ScInterpreter::ScSumX2MY2() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + ScMatrix* pMat1 = NULL; + ScMatrix* pMat2 = NULL; + USHORT nMatInd1, nMatInd2, i, j; + pMat2 = GetMatrix(nMatInd2); + pMat1 = GetMatrix(nMatInd1); + if (!pMat2 || !pMat1) + { + SetIllegalParameter(); + return; + } + USHORT nC2, nR2, nC1, nR1; + pMat2->GetDimensions(nC2, nR2); + pMat1->GetDimensions(nC1, nR1); + if (nC1 != nC2 || nR1 != nR2) + { + SetNoValue(); + return; + } + double fVal, fSum = 0.0; + for (i = 0; i < nC1; i++) + for (j = 0; j < nR1; j++) + if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j)) + { + fVal = pMat1->GetDouble(i,j); + fSum += fVal * fVal; + fVal = pMat2->GetDouble(i,j); + fSum -= fVal * fVal; + } + PushDouble(fSum); +} + +void ScInterpreter::ScSumX2DY2() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + ScMatrix* pMat1 = NULL; + ScMatrix* pMat2 = NULL; + USHORT nMatInd1, nMatInd2, i, j; + pMat2 = GetMatrix(nMatInd2); + pMat1 = GetMatrix(nMatInd1); + if (!pMat2 || !pMat1) + { + SetIllegalParameter(); + return; + } + USHORT nC2, nR2, nC1, nR1; + pMat2->GetDimensions(nC2, nR2); + pMat1->GetDimensions(nC1, nR1); + if (nC1 != nC2 || nR1 != nR2) + { + SetNoValue(); + return; + } + double fVal, fSum = 0.0; + for (i = 0; i < nC1; i++) + for (j = 0; j < nR1; j++) + if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j)) + { + fVal = pMat1->GetDouble(i,j); + fSum += fVal * fVal; + fVal = pMat2->GetDouble(i,j); + fSum += fVal * fVal; + } + PushDouble(fSum); +} + +void ScInterpreter::ScSumXMY2() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + ScMatrix* pMat1 = NULL; + ScMatrix* pMat2 = NULL; + USHORT nMatInd1, nMatInd2; + pMat2 = GetMatrix(nMatInd2); + pMat1 = GetMatrix(nMatInd1); + if (!pMat2 || !pMat1) + { + SetIllegalParameter(); + return; + } + USHORT nC2, nR2, nC1, nR1; + pMat2->GetDimensions(nC2, nR2); + pMat1->GetDimensions(nC1, nR1); + if (nC1 != nC2 || nR1 != nR2) + { + SetNoValue(); + return; + } + ScMatrix* pResMat = MatSub(pMat1, pMat2); + if (!pResMat) + { + SetNoValue(); + return; + } + else + { + double fVal, fSum = 0.0; + ULONG nCount = pResMat->GetElementCount(); + for (ULONG i = 0; i < nCount; i++) + if (!pResMat->IsString(i)) + { + fVal = pResMat->GetDouble(i); + fSum += fVal * fVal; + } + PushDouble(fSum); + } +} + +void ScInterpreter::ScFrequency() +{ + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + USHORT nMatInd; + double* pSortArray1 = NULL; + ULONG nSize1 = 0; + GetSortArray(1, &pSortArray1, nSize1); + if (nGlobalError) + SetNoValue(); + double* pSortArray2 = NULL; + ULONG nSize2 = 0; + GetSortArray(1, &pSortArray2, nSize2); + if (!pSortArray2 || nSize2 == 0 || nGlobalError) + { + if (pSortArray1) + delete pSortArray1; + if (pSortArray2) + delete pSortArray2; + SetNoValue(); + return; + } + ScMatrix* pResMat = GetNewMat(1,(USHORT)nSize1+1,nMatInd); + if (!pResMat) + { + if (pSortArray1) + delete pSortArray1; + if (pSortArray2) + delete pSortArray2; + SetNoValue(); + return; + } + + USHORT j; + ULONG i = 0; + ULONG nCount; + for (j = 0; j < nSize1; j++) + { + nCount = 0; + while (i < nSize2 && pSortArray2[i] <= pSortArray1[j]) + { + nCount++; + i++; + } + pResMat->PutDouble((double) nCount, j); + } + pResMat->PutDouble((double) (nSize2-i), j); + if (pSortArray1) + delete pSortArray1; + if (pSortArray2) + delete pSortArray2; + PushMatrix(pResMat); + nRetMat = nMatInd; +} + +BOOL ScInterpreter::RGetVariances( ScMatrix* pV, ScMatrix* pX, + USHORT nC, USHORT nR, BOOL bSwapColRow, BOOL bZeroConstant ) +{ // multiple Regression: Varianzen der Koeffizienten + // bSwapColRow==TRUE : Koeffizienten in Zeilen statt Spalten angeordnet + USHORT i, j, k, nMatInd; + double sum; + ScMatrix* pC = GetNewMat(nC, nC, nMatInd); + if ( !pC ) + return FALSE; + // X transformiert mit X multipziert, X'X Matrix + if ( !bZeroConstant ) + { // in der X-Designmatrix existiert ein gedachtes X0j==1 + if ( bSwapColRow ) + { + for ( i=0; i<nC; i++ ) + { + for ( j=0; j<nC; j++ ) + { + sum = 0.0; + for ( k=0; k<nR; k++ ) + { + sum += (j==0 ? 1 : pX->GetDouble(k,j-1)) + * (i==0 ? 1 : pX->GetDouble(k,i-1)); + } + pC->PutDouble(sum, i, j); + } + } + } + else + { + for ( i=0; i<nC; i++ ) + { + for ( j=0; j<nC; j++ ) + { + sum = 0.0; + for ( k=0; k<nR; k++ ) + { + sum += (j==0 ? 1 : pX->GetDouble(j-1,k)) + * (i==0 ? 1 : pX->GetDouble(i-1,k)); + } + pC->PutDouble(sum, i, j); + } + } + } + } + else + { + if ( bSwapColRow ) + { + for ( i=0; i<nC; i++ ) + { + for ( j=0; j<nC; j++ ) + { + sum = 0.0; + for ( k=0; k<nR; k++ ) + { + sum += pX->GetDouble(k,j) * pX->GetDouble(k,i); + } + pC->PutDouble(sum, i, j); + } + } + } + else + { + for ( i=0; i<nC; i++ ) + { + for ( j=0; j<nC; j++ ) + { + sum = 0.0; + for ( k=0; k<nR; k++ ) + { + sum += pX->GetDouble(j,k) * pX->GetDouble(i,k); + } + pC->PutDouble(sum, i, j); + } + } + } + } + // X'X Inverse + BOOL bOk = TRUE; + USHORT nErr = nGlobalError; + PushMatrix(pC); + BYTE nTmp = cPar; + cPar = 1; + ScMatInv(); + cPar = nTmp; + if ( nGlobalError ) + { + nGlobalError = nErr; + bOk = FALSE; + } + else + { + Pop(); // pC bleibt erhalten + // Varianzen auf der Diagonalen, andere sind Kovarianzen + for (i = 0; i < nC; i++) + pV->PutDouble(pC->GetDouble(i, i), i); + } + delete pC; + ResetNewMat(nMatInd); + return bOk; +} + +void ScInterpreter::ScRGP() +{ + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 1, 4 ) ) + return; + BOOL bConstant, bStats; + if (nParamCount == 4) + bStats = GetBool(); + else + bStats = FALSE; + if (nParamCount >= 3) + bConstant = GetBool(); + else + bConstant = TRUE; + USHORT nMatInd1, nMatInd2; + ScMatrix* pMatX; + ScMatrix* pMatY; + if (nParamCount >= 2) + pMatX = GetMatrix(nMatInd2); + else + pMatX = NULL; + pMatY = GetMatrix(nMatInd1); + if (!pMatY) + { + SetIllegalParameter(); + return; + } + BYTE nCase; // 1 = normal, 2,3 = mehrfach + USHORT nCX, nRX, nCY, nRY, M, N; + pMatY->GetDimensions(nCY, nRY); + ULONG nCountY = (ULONG) nCY * nRY; + for ( ULONG i = 0; i < nCountY; i++ ) + if (!pMatY->IsValue(i)) + { + SetIllegalArgument(); + return; + } + if (pMatX) + { + pMatX->GetDimensions(nCX, nRX); + ULONG nCountX = (ULONG) nCX * nRX; + for ( ULONG i = 0; i < nCountX; i++ ) + if (!pMatX->IsValue(i)) + { + SetIllegalArgument(); + return; + } + if (nCX == nCY && nRX == nRY) + nCase = 1; // einfache Regression + else if (nCY != 1 && nRY != 1) + { + SetIllegalParameter(); + return; + } + else if (nCY == 1) + { + if (nRX != nRY) + { + SetIllegalParameter(); + return; + } + else + { + nCase = 2; // zeilenweise + N = nRY; + M = nCX; + } + } + else if (nCX != nCY) + { + SetIllegalParameter(); + return; + } + else + { + nCase = 3; // spaltenweise + N = nCY; + M = nRX; + } + } + else + { + pMatX = GetNewMat(nCY, nRY, nMatInd2); + if (!pMatX) + { + SetIllegalParameter(); + return; + } + for ( ULONG i = 1; i <= nCountY; i++ ) + pMatX->PutDouble((double)i, i-1); + nCase = 1; + } + USHORT nMatInd; + ScMatrix* pResMat; + if (nCase == 1) + { + if (!bStats) + pResMat = GetNewMat(2,1,nMatInd); + else + pResMat = GetNewMat(2,5,nMatInd); + if (!pResMat) + { + SetIllegalParameter(); + return; + } + double fCount = 0.0; + double fSumX = 0.0; + double fSumSqrX = 0.0; + double fSumY = 0.0; + double fSumSqrY = 0.0; + double fSumXY = 0.0; + double fValX, fValY; + for (USHORT i = 0; i < nCY; i++) + for (USHORT j = 0; j < nRY; j++) + { + fValX = pMatX->GetDouble(i,j); + fValY = pMatY->GetDouble(i,j); + fSumX += fValX; + fSumSqrX += fValX * fValX; + fSumY += fValY; + fSumSqrY += fValY * fValY; + fSumXY += fValX*fValY; + fCount++; + } + if (fCount < 1.0) + SetNoValue(); + else + { + double f1 = fCount*fSumXY-fSumX*fSumY; + double fX = fCount*fSumSqrX-fSumX*fSumX; + double b, m; + if (bConstant) + { + b = fSumY/fCount - f1/fX*fSumX/fCount; + m = f1/fX; + } + else + { + b = 0.0; + m = fSumXY/fSumSqrX; + } + pResMat->PutDouble(m, 0, 0); + pResMat->PutDouble(b, 1, 0); + if (bStats) + { + double fY = fCount*fSumSqrY-fSumY*fSumY; + double fSyx = fSumSqrY-b*fSumY-m*fSumXY; + double fR2 = f1*f1/(fX*fY); + pResMat->PutDouble (fR2, 0, 2); + if (fCount < 3.0) + { + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 1 ); + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 1 ); + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2 ); + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3 ); + } + else + { + pResMat->PutDouble(sqrt(fSyx*fCount/(fX*(fCount-2.0))), 0, 1); + pResMat->PutDouble(sqrt(fSyx*fSumSqrX/fX/(fCount-2.0)), 1, 1); + pResMat->PutDouble( + sqrt((fCount*fSumSqrY - fSumY*fSumY - f1*f1/fX)/ + (fCount*(fCount-2.0))), 1, 2); + if (fR2 == 1.0) + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3 ); + else + pResMat->PutDouble(fR2*(fCount-2.0)/(1.0-fR2), 0, 3); + } + pResMat->PutDouble(((double)(nCY*nRY))-2.0, 1, 3); + pResMat->PutDouble(fY/fCount-fSyx, 0, 4); + pResMat->PutDouble(fSyx, 1, 4); + } + } + } + else + { + USHORT nMatInd10, nMatInd12, nMatInd13, i, j, k; + if (!bStats) + pResMat = GetNewMat(M+1,1,nMatInd); + else + pResMat = GetNewMat(M+1,5,nMatInd); + if (!pResMat) + { + SetIllegalParameter(); + return; + } + BOOL bVariancesOk = TRUE; + ScMatrix* pQ = GetNewMat(M+1, M+2, nMatInd10); + ScMatrix* pE = GetNewMat(M+2, 1, nMatInd12); + ScMatrix* pV = GetNewMat(M+1, 1, nMatInd13); + pE->PutDouble(0.0, M+1); + pQ->FillDouble(0.0, 0, 0, M, M+1); + if (nCase == 2) + { + for (k = 0; k < N; k++) + { + double Yk = pMatY->GetDouble(k); + pE->PutDouble( pE->GetDouble(M+1)+Yk*Yk, M+1 ); + double sumYk = pQ->GetDouble(0, M+1) + Yk; + pQ->PutDouble( sumYk, 0, M+1 ); + pE->PutDouble( sumYk, 0 ); + for (i = 0; i < M; i++) + { + double Xik = pMatX->GetDouble(i,k); + double sumXik = pQ->GetDouble(0, i+1) + Xik; + pQ->PutDouble( sumXik, 0, i+1); + pQ->PutDouble( sumXik, i+1, 0); + double sumXikYk = pQ->GetDouble(i+1, M+1) + Xik * Yk; + pQ->PutDouble( sumXikYk, i+1, M+1); + pE->PutDouble( sumXikYk, i+1); + for (j = i; j < M; j++) + { + double sumXikXjk = pQ->GetDouble(j+1, i+1) + + Xik * pMatX->GetDouble(j,k); + pQ->PutDouble( sumXikXjk, j+1, i+1); + pQ->PutDouble( sumXikXjk, i+1, j+1); + } + } + } + } + else + { + for (k = 0; k < N; k++) + { + double Yk = pMatY->GetDouble(k); + pE->PutDouble( pE->GetDouble(M+1)+Yk*Yk, M+1 ); + double sumYk = pQ->GetDouble(0, M+1) + Yk; + pQ->PutDouble( sumYk, 0, M+1 ); + pE->PutDouble( sumYk, 0 ); + for (i = 0; i < M; i++) + { + double Xki = pMatX->GetDouble(k,i); + double sumXki = pQ->GetDouble(0, i+1) + Xki; + pQ->PutDouble( sumXki, 0, i+1); + pQ->PutDouble( sumXki, i+1, 0); + double sumXkiYk = pQ->GetDouble(i+1, M+1) + Xki * Yk; + pQ->PutDouble( sumXkiYk, i+1, M+1); + pE->PutDouble( sumXkiYk, i+1); + for (j = i; j < M; j++) + { + double sumXkiXkj = pQ->GetDouble(j+1, i+1) + + Xki * pMatX->GetDouble(k,j); + pQ->PutDouble( sumXkiXkj, j+1, i+1); + pQ->PutDouble( sumXkiXkj, i+1, j+1); + } + } + } + } + pQ->PutDouble((double)N, 0, 0); + if (bConstant) + { + USHORT S, L; + for (S = 0; S < M+1; S++) + { + i = S; + while (i < M+1 && pQ->GetDouble(i, S) == 0.0) + i++; + if (i >= M+1) + { + SetNoValue(); + delete pQ; + delete pE; + delete pV; + ResetNewMat(nMatInd13); + ResetNewMat(nMatInd12); + ResetNewMat(nMatInd10); + return; + } + double fVal; + for (L = 0; L < M+2; L++) + { + fVal = pQ->GetDouble(S, L); + pQ->PutDouble(pQ->GetDouble(i, L), S, L); + pQ->PutDouble(fVal, i, L); + } + fVal = 1.0/pQ->GetDouble(S, S); + for (L = 0; L < M+2; L++) + pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); + for (i = 0; i < M+1; i++) + { + if (i != S) + { + fVal = -pQ->GetDouble(i, S); + for (L = 0; L < M+2; L++) + pQ->PutDouble( + pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); + } + } + } + } + else + { + USHORT S, L; + for (S = 1; S < M+1; S++) + { + i = S; + while (i < M+1 && pQ->GetDouble(i, S) == 0.0) + i++; + if (i >= M+1) + { + SetNoValue(); + delete pQ; + delete pE; + delete pV; + ResetNewMat(nMatInd13); + ResetNewMat(nMatInd12); + ResetNewMat(nMatInd10); + return; + } + double fVal; + for (L = 1; L < M+2; L++) + { + fVal = pQ->GetDouble(S, L); + pQ->PutDouble(pQ->GetDouble(i, L), S, L); + pQ->PutDouble(fVal, i, L); + } + fVal = 1.0/pQ->GetDouble(S, S); + for (L = 1; L < M+2; L++) + pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); + for (i = 1; i < M+1; i++) + { + if (i != S) + { + fVal = -pQ->GetDouble(i, S); + for (L = 1; L < M+2; L++) + pQ->PutDouble( + pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); + } + } + pQ->PutDouble(0.0, 0, M+1); // Konstante b + } + } + // mn ... m1, b + for (i = 0; i < M+1; i++) + pResMat->PutDouble(pQ->GetDouble(M-i,M+1), i, 0); + if (bStats) + { + // pE[0] := Sigma i=1...n (Yi) + // pE[k] := Sigma i=1...n (Xki*Yi) + // pE[M+1] := Sigma i=1...n (Yi**2) + // pQ[0,M+1]:= B + // pQ[k,M+1]:= Mk + double fSQR, fSQT, fSQE; + fSQT = pE->GetDouble(M+1) + - pE->GetDouble(0) * pE->GetDouble(0) / (double)N; + fSQR = pE->GetDouble(M+1); + for (i = 0; i < M+1; i++) + fSQR -= pQ->GetDouble(i, M+1) * pE->GetDouble(i); + fSQE = fSQT-fSQR; + // r2 (Bestimmtheitsmass, 0...1) + if (fSQT == 0.0) + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 2); + else + pResMat->PutDouble (fSQE/fSQT, 0, 2); + // ssReg (Regressions-Quadratsumme) + pResMat->PutDouble(fSQE, 0, 4); + // ssResid (Residual-Quadratsumme, Summe der Abweichungsquadrate) + pResMat->PutDouble(fSQR, 1, 4); + for (i = 2; i < 5; i++) + for (j = 2; j < M+1; j++) + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), j, i); + if (bConstant) + { + if (N-M-1 == 0) + { + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2); + for (i = 0; i < M+1; i++) + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i, 1); + } + else + { + double fSE2 = fSQR/(N-M-1); + // sey (Standardfehler des Schaetzwertes y) + pResMat->PutDouble(sqrt(fSE2), 1, 2); + // sen...se1 (Standardfehler der Koeffizienten mn...m1) + // seb (Standardfehler der Konstanten b) + if ( RGetVariances( pV, pMatX, M+1, N, nCase != 2, FALSE ) ) + { + for (i = 0; i < M+1; i++) + pResMat->PutDouble( sqrt(fSE2 * pV->GetDouble(i)), M-i, 1 ); + } + else + { + for (i = 0; i < M+1; i++) + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), i, 1); + } + } + // F (F-Statistik) + if (fSQR == 0.0) + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3); + else + pResMat->PutDouble(((double)(N-M-1))*fSQE/fSQR/((double)M),0, 3); + // df (Freiheitsgrad) + pResMat->PutDouble(((double)(N-M-1)), 1, 3); + } + else + { + if (N-M == 0) + { + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2); + for (i = 0; i < M+1; i++) + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i, 1); + } + else + { + double fSE2 = fSQR/(N-M); + pResMat->PutDouble(sqrt(fSE2), 1, 2); + if ( RGetVariances( pV, pMatX, M, N, nCase != 2, TRUE ) ) + { + for (i = 0; i < M; i++) + pResMat->PutDouble( sqrt(fSE2 * pV->GetDouble(i)), M-i-1, 1 ); + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), M, 1); + } + else + { + for (i = 0; i < M+1; i++) + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), i, 1); + } + } + if (fSQR == 0.0) + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3); + else + pResMat->PutDouble(((double)(N-M))*fSQE/fSQR/((double)M),0, 3); + pResMat->PutDouble(((double)(N-M)), 1, 3); + } + } + delete pQ; + delete pE; + delete pV; + ResetNewMat(nMatInd13); + ResetNewMat(nMatInd12); + ResetNewMat(nMatInd10); + } + PushMatrix(pResMat); + nRetMat = nMatInd; +} + +void ScInterpreter::ScRKP() +{ + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 1, 4 ) ) + return; + BOOL bConstant, bStats; + if (nParamCount == 4) + bStats = GetBool(); + else + bStats = FALSE; + if (nParamCount >= 3) + bConstant = GetBool(); + else + bConstant = TRUE; + USHORT nMatInd1, nMatInd2; + ScMatrix* pMatX; + ScMatrix* pMatY; + if (nParamCount >= 2) + pMatX = GetMatrix(nMatInd2); + else + pMatX = NULL; + pMatY = GetMatrix(nMatInd1); + if (!pMatY) + { + SetIllegalParameter(); + return; + } + BYTE nCase; // 1 = normal, 2,3 = mehrfach + USHORT nCX, nRX, nCY, nRY, M, N; + pMatY->GetDimensions(nCY, nRY); + ULONG nCountY = (ULONG) nCY * nRY; + ULONG i; + for (i = 0; i < nCountY; i++) + if (!pMatY->IsValue(i)) + { + SetIllegalArgument(); + return; + } + for (i = 0; i < nCountY; i++) + { + if (pMatY->GetDouble(i) <= 0.0) + { + SetIllegalArgument(); + return; + } + else + pMatY->PutDouble(log(pMatY->GetDouble(i)), i); + } + if (pMatX) + { + pMatX->GetDimensions(nCX, nRX); + ULONG nCountX = (ULONG) nCX * nRX; + for (i = 0; i < nCountX; i++) + if (!pMatX->IsValue(i)) + { + SetIllegalArgument(); + return; + } + if (nCX == nCY && nRX == nRY) + nCase = 1; // einfache Regression + else if (nCY != 1 && nRY != 1) + { + SetIllegalParameter(); + return; + } + else if (nCY == 1) + { + if (nRX != nRY) + { + SetIllegalParameter(); + return; + } + else + { + nCase = 2; // zeilenweise + N = nRY; + M = nCX; + } + } + else if (nCX != nCY) + { + SetIllegalParameter(); + return; + } + else + { + nCase = 3; // spaltenweise + N = nCY; + M = nRX; + } + } + else + { + pMatX = GetNewMat(nCY, nRY, nMatInd2); + if (!pMatX) + { + SetIllegalParameter(); + return; + } + for ( ULONG i = 1; i <= nCountY; i++ ) + pMatX->PutDouble((double)i, i-1); + nCase = 1; + } + USHORT nMatInd; + ScMatrix* pResMat; + if (nCase == 1) + { + if (!bStats) + pResMat = GetNewMat(2,1,nMatInd); + else + pResMat = GetNewMat(2,5,nMatInd); + if (!pResMat) + { + SetIllegalParameter(); + return; + } + double fCount = 0.0; + double fSumX = 0.0; + double fSumSqrX = 0.0; + double fSumY = 0.0; + double fSumSqrY = 0.0; + double fSumXY = 0.0; + double fValX, fValY; + for (USHORT i = 0; i < nCY; i++) + for (USHORT j = 0; j < nRY; j++) + { + fValX = pMatX->GetDouble(i,j); + fValY = pMatY->GetDouble(i,j); + fSumX += fValX; + fSumSqrX += fValX * fValX; + fSumY += fValY; + fSumSqrY += fValY * fValY; + fSumXY += fValX*fValY; + fCount++; + } + if (fCount < 1.0) + SetNoValue(); + else + { + double f1 = fCount*fSumXY-fSumX*fSumY; + double fX = fCount*fSumSqrX-fSumX*fSumX; + double b, m; + if (bConstant) + { + b = fSumY/fCount - f1/fX*fSumX/fCount; + m = f1/fX; + } + else + { + b = 0.0; + m = fSumXY/fSumSqrX; + } + pResMat->PutDouble(exp(m), 0, 0); + pResMat->PutDouble(exp(b), 1, 0); + if (bStats) + { + double fY = fCount*fSumSqrY-fSumY*fSumY; + double fSyx = fSumSqrY-b*fSumY-m*fSumXY; + double fR2 = f1*f1/(fX*fY); + pResMat->PutDouble (fR2, 0, 2); + if (fCount < 3.0) + { + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 1 ); + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 1 ); + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2 ); + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3 ); + } + else + { + pResMat->PutDouble(sqrt(fSyx*fCount/(fX*(fCount-2.0))), 0, 1); + pResMat->PutDouble(sqrt(fSyx*fSumSqrX/fX/(fCount-2.0)), 1, 1); + pResMat->PutDouble( + sqrt((fCount*fSumSqrY - fSumY*fSumY - f1*f1/fX)/ + (fCount*(fCount-2.0))), 1, 2); + if (fR2 == 1.0) + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3 ); + else + pResMat->PutDouble(fR2*(fCount-2.0)/(1.0-fR2), 0, 3); + } + pResMat->PutDouble(((double)(nCY*nRY))-2.0, 1, 3); + pResMat->PutDouble(fY/fCount-fSyx, 0, 4); + pResMat->PutDouble(fSyx, 1, 4); + } + } + } + else + { + USHORT nMatInd10, nMatInd12, nMatInd13, i, j, k; + if (!bStats) + pResMat = GetNewMat(M+1,1,nMatInd); + else + pResMat = GetNewMat(M+1,5,nMatInd); + if (!pResMat) + { + SetIllegalParameter(); + return; + } + ScMatrix* pQ = GetNewMat(M+1, M+2, nMatInd10); + ScMatrix* pE = GetNewMat(M+2, 1, nMatInd12); + ScMatrix* pV = GetNewMat(M+1, 1, nMatInd13); + pE->PutDouble(0.0, M+1); + pQ->FillDouble(0.0, 0, 0, M, M+1); + if (nCase == 2) + { + for (k = 0; k < N; k++) + { + double Yk = pMatY->GetDouble(k); + pE->PutDouble( pE->GetDouble(M+1)+Yk*Yk, M+1 ); + double sumYk = pQ->GetDouble(0, M+1) + Yk; + pQ->PutDouble( sumYk, 0, M+1 ); + pE->PutDouble( sumYk, 0 ); + for (i = 0; i < M; i++) + { + double Xik = pMatX->GetDouble(i,k); + double sumXik = pQ->GetDouble(0, i+1) + Xik; + pQ->PutDouble( sumXik, 0, i+1); + pQ->PutDouble( sumXik, i+1, 0); + double sumXikYk = pQ->GetDouble(i+1, M+1) + Xik * Yk; + pQ->PutDouble( sumXikYk, i+1, M+1); + pE->PutDouble( sumXikYk, i+1); + for (j = i; j < M; j++) + { + double sumXikXjk = pQ->GetDouble(j+1, i+1) + + Xik * pMatX->GetDouble(j,k); + pQ->PutDouble( sumXikXjk, j+1, i+1); + pQ->PutDouble( sumXikXjk, i+1, j+1); + } + } + } + } + else + { + for (k = 0; k < N; k++) + { + double Yk = pMatY->GetDouble(k); + pE->PutDouble( pE->GetDouble(M+1)+Yk*Yk, M+1 ); + double sumYk = pQ->GetDouble(0, M+1) + Yk; + pQ->PutDouble( sumYk, 0, M+1 ); + pE->PutDouble( sumYk, 0 ); + for (i = 0; i < M; i++) + { + double Xki = pMatX->GetDouble(k,i); + double sumXki = pQ->GetDouble(0, i+1) + Xki; + pQ->PutDouble( sumXki, 0, i+1); + pQ->PutDouble( sumXki, i+1, 0); + double sumXkiYk = pQ->GetDouble(i+1, M+1) + Xki * Yk; + pQ->PutDouble( sumXkiYk, i+1, M+1); + pE->PutDouble( sumXkiYk, i+1); + for (j = i; j < M; j++) + { + double sumXkiXkj = pQ->GetDouble(j+1, i+1) + + Xki * pMatX->GetDouble(k,j); + pQ->PutDouble( sumXkiXkj, j+1, i+1); + pQ->PutDouble( sumXkiXkj, i+1, j+1); + } + } + } + } + pQ->PutDouble((double)N, 0, 0); + if (bConstant) + { + USHORT S, L; + for (S = 0; S < M+1; S++) + { + i = S; + while (i < M+1 && pQ->GetDouble(i, S) == 0.0) + i++; + if (i >= M+1) + { + SetNoValue(); + delete pQ; + delete pE; + delete pV; + ResetNewMat(nMatInd13); + ResetNewMat(nMatInd12); + ResetNewMat(nMatInd10); + return; + } + double fVal; + for (L = 0; L < M+2; L++) + { + fVal = pQ->GetDouble(S, L); + pQ->PutDouble(pQ->GetDouble(i, L), S, L); + pQ->PutDouble(fVal, i, L); + } + fVal = 1.0/pQ->GetDouble(S, S); + for (L = 0; L < M+2; L++) + pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); + for (i = 0; i < M+1; i++) + { + if (i != S) + { + fVal = -pQ->GetDouble(i, S); + for (L = 0; L < M+2; L++) + pQ->PutDouble( + pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); + } + } + } + } + else + { + USHORT S, L; + for (S = 1; S < M+1; S++) + { + i = S; + while (i < M+1 && pQ->GetDouble(i, S) == 0.0) + i++; + if (i >= M+1) + { + SetNoValue(); + delete pQ; + delete pE; + delete pV; + ResetNewMat(nMatInd13); + ResetNewMat(nMatInd12); + ResetNewMat(nMatInd10); + return; + } + double fVal; + for (L = 1; L < M+2; L++) + { + fVal = pQ->GetDouble(S, L); + pQ->PutDouble(pQ->GetDouble(i, L), S, L); + pQ->PutDouble(fVal, i, L); + } + fVal = 1.0/pQ->GetDouble(S, S); + for (L = 1; L < M+2; L++) + pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); + for (i = 1; i < M+1; i++) + { + if (i != S) + { + fVal = -pQ->GetDouble(i, S); + for (L = 1; L < M+2; L++) + pQ->PutDouble( + pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); + } + } + pQ->PutDouble(0.0, 0, M+1); + } + } + for (i = 0; i < M+1; i++) + pResMat->PutDouble(exp(pQ->GetDouble(M-i,M+1)), i, 0); + if (bStats) + { + double fSQR, fSQT, fSQE; + fSQT = pE->GetDouble(M+1)-pE->GetDouble(0)*pE->GetDouble(0)/((double)N); + fSQR = pE->GetDouble(M+1); + for (i = 0; i < M+1; i++) + fSQR += -pQ->GetDouble(i, M+1)*pE->GetDouble(i); + fSQE = fSQT-fSQR; + if (fSQT == 0.0) + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 2); + else + pResMat->PutDouble (fSQE/fSQT, 0, 2); + pResMat->PutDouble(fSQE, 0, 4); + pResMat->PutDouble(fSQR, 1, 4); + for (i = 2; i < 5; i++) + for (j = 2; j < M+1; j++) + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), j, i); + if (bConstant) + { + if (N-M-1 == 0) + { + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2); + for (i = 0; i < M+1; i++) + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i, 1); + } + else + { + double fSE2 = fSQR/(N-M-1); + pResMat->PutDouble(sqrt(fSE2), 1, 2); + if ( RGetVariances( pV, pMatX, M+1, N, nCase != 2, FALSE ) ) + { + for (i = 0; i < M+1; i++) + pResMat->PutDouble( sqrt(fSE2 * pV->GetDouble(i)), M-i, 1 ); + } + else + { + for (i = 0; i < M+1; i++) + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), i, 1); + } + } + if (fSQR == 0.0) + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3); + else + pResMat->PutDouble(((double)(N-M-1))*fSQE/fSQR/((double)M),0, 3); + pResMat->PutDouble(((double)(N-M-1)), 1, 3); + } + else + { + if (N-M == 0) + { + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2); + for (i = 0; i < M+1; i++) + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i, 1); + } + else + { + double fSE2 = fSQR/(N-M); + pResMat->PutDouble(sqrt(fSE2), 1, 2); + if ( RGetVariances( pV, pMatX, M, N, nCase != 2, TRUE ) ) + { + for (i = 0; i < M; i++) + pResMat->PutDouble( sqrt(fSE2 * pV->GetDouble(i)), M-i-1, 1 ); + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), M, 1); + } + else + { + for (i = 0; i < M+1; i++) + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), i, 1); + } + } + if (fSQR == 0.0) + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3); + else + pResMat->PutDouble(((double)(N-M))*fSQE/fSQR/((double)M),0, 3); + pResMat->PutDouble(((double)(N-M)), 1, 3); + } + } + delete pQ; + delete pE; + delete pV; + ResetNewMat(nMatInd13); + ResetNewMat(nMatInd12); + ResetNewMat(nMatInd10); + } + PushMatrix(pResMat); + nRetMat = nMatInd; +} + + +void ScInterpreter::ScTrend() +{ + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 1, 4 ) ) + return; + BOOL bConstant; + if (nParamCount == 4) + bConstant = GetBool(); + else + bConstant = TRUE; + USHORT nMatInd1, nMatInd2, nMatInd3; + ScMatrix* pMatX; + ScMatrix* pMatY; + ScMatrix* pMatNewX; + if (nParamCount >= 3) + pMatNewX = GetMatrix(nMatInd3); + else + pMatNewX = NULL; + if (nParamCount >= 2) + pMatX = GetMatrix(nMatInd2); + else + pMatX = NULL; + pMatY = GetMatrix(nMatInd1); + if (!pMatY) + { + SetIllegalParameter(); + return; + } + BYTE nCase; // 1 = normal, 2,3 = mehrfach + USHORT nCX, nRX, nCY, nRY, M, N; + pMatY->GetDimensions(nCY, nRY); + ULONG nCountY = (ULONG) nCY * nRY; + ULONG i; + for (i = 0; i < nCountY; i++) + if (!pMatY->IsValue(i)) + { + SetIllegalArgument(); + return; + } + if (pMatX) + { + pMatX->GetDimensions(nCX, nRX); + ULONG nCountX = (ULONG) nCX * nRX; + for (i = 0; i < nCountX; i++) + if (!pMatX->IsValue(i)) + { + SetIllegalArgument(); + return; + } + if (nCX == nCY && nRX == nRY) + nCase = 1; // einfache Regression + else if (nCY != 1 && nRY != 1) + { + SetIllegalParameter(); + return; + } + else if (nCY == 1) + { + if (nRX != nRY) + { + SetIllegalParameter(); + return; + } + else + { + nCase = 2; // zeilenweise + N = nRY; + M = nCX; + } + } + else if (nCX != nCY) + { + SetIllegalParameter(); + return; + } + else + { + nCase = 3; // spaltenweise + N = nCY; + M = nRX; + } + } + else + { + pMatX = GetNewMat(nCY, nRY, nMatInd2); + nCX = nCY; + nRX = nRY; + if (!pMatX) + { + SetIllegalParameter(); + return; + } + for (i = 1; i <= nCountY; i++) + pMatX->PutDouble((double)i, i-1); + nCase = 1; + } + USHORT nCXN, nRXN; + ULONG nCountXN; + if (!pMatNewX) + { + nCXN = nCX; + nRXN = nRX; + nCountXN = (ULONG) nCXN * nRXN; + pMatNewX = pMatX; + } + else + { + pMatNewX->GetDimensions(nCXN, nRXN); + if ((nCase == 2 && nCX != nCXN) || (nCase == 3 && nRX != nRXN)) + { + SetIllegalArgument(); + return; + } + nCountXN = (ULONG) nCXN * nRXN; + for ( ULONG i = 0; i < nCountXN; i++ ) + if (!pMatNewX->IsValue(i)) + { + SetIllegalArgument(); + return; + } + } + USHORT nMatInd; + ScMatrix* pResMat; + if (nCase == 1) + { + double fCount = 0.0; + double fSumX = 0.0; + double fSumSqrX = 0.0; + double fSumY = 0.0; + double fSumSqrY = 0.0; + double fSumXY = 0.0; + double fValX, fValY; + for (USHORT i = 0; i < nCY; i++) + for (USHORT j = 0; j < nRY; j++) + { + fValX = pMatX->GetDouble(i,j); + fValY = pMatY->GetDouble(i,j); + fSumX += fValX; + fSumSqrX += fValX * fValX; + fSumY += fValY; + fSumSqrY += fValY * fValY; + fSumXY += fValX*fValY; + fCount++; + } + if (fCount < 1.0) + { + SetNoValue(); + return; + } + else + { + double f1 = fCount*fSumXY-fSumX*fSumY; + double fX = fCount*fSumSqrX-fSumX*fSumX; + double b, m; + if (bConstant) + { + b = fSumY/fCount - f1/fX*fSumX/fCount; + m = f1/fX; + } + else + { + b = 0.0; + m = fSumXY/fSumSqrX; + } + pResMat = GetNewMat(nCXN, nRXN, nMatInd); + if (!pResMat) + { + SetIllegalParameter(); + return; + } + for (i = 0; i < nCountXN; i++) + pResMat->PutDouble(pMatNewX->GetDouble(i)*m+b, i); + } + } + else + { + USHORT nMatInd10, nMatInd12, i, j, k; + ScMatrix* pQ = GetNewMat(M+1, M+2, nMatInd10); + ScMatrix* pE = GetNewMat(M+2, 1, nMatInd12); + pE->PutDouble(0.0, M+1); + pQ->FillDouble(0.0, 0, 0, M, M+1); + if (nCase == 2) + { + for (k = 0; k < N; k++) + { + pE->PutDouble( + pE->GetDouble(M+1)+pMatY->GetDouble(k)*pMatY->GetDouble(k), M+1); + pQ->PutDouble(pQ->GetDouble(0, M+1) + pMatY->GetDouble(k), 0, M+1); + pE->PutDouble(pQ->GetDouble(0, M+1), 0); + for (i = 0; i < M; i++) + { + pQ->PutDouble(pQ->GetDouble(0, i+1)+pMatX->GetDouble(i,k), 0, i+1); + pQ->PutDouble(pQ->GetDouble(0, i+1), i+1, 0); + pQ->PutDouble(pQ->GetDouble(i+1, M+1) + + pMatX->GetDouble(i,k)*pMatY->GetDouble(k), i+1, M+1); + pE->PutDouble(pQ->GetDouble(i+1, M+1), i+1); + for (j = i; j < M; j++) + { + pQ->PutDouble(pQ->GetDouble(j+1, i+1) + + pMatX->GetDouble(i,k)*pMatX->GetDouble(j,k), j+1, i+1); + pQ->PutDouble(pQ->GetDouble(j+1, i+1), i+1, j+1); + } + } + } + } + else + { + for (k = 0; k < N; k++) + { + pE->PutDouble( + pE->GetDouble(M+1)+pMatY->GetDouble(k)*pMatY->GetDouble(k), M+1); + pQ->PutDouble(pQ->GetDouble(0, M+1) + pMatY->GetDouble(k), 0, M+1); + pE->PutDouble(pQ->GetDouble(0, M+1), 0); + for (i = 0; i < M; i++) + { + pQ->PutDouble(pQ->GetDouble(0, i+1)+pMatX->GetDouble(k,i), 0, i+1); + pQ->PutDouble(pQ->GetDouble(0, i+1), i+1, 0); + pQ->PutDouble(pQ->GetDouble(i+1, M+1) + + pMatX->GetDouble(k,i)*pMatY->GetDouble(k), i+1, M+1); + pE->PutDouble(pQ->GetDouble(i+1, M+1), i+1); + for (j = i; j < M; j++) + { + pQ->PutDouble(pQ->GetDouble(j+1, i+1) + + pMatX->GetDouble(k, i)*pMatX->GetDouble(k, j), j+1, i+1); + pQ->PutDouble(pQ->GetDouble(j+1, i+1), i+1, j+1); + } + } + } + } + pQ->PutDouble((double)N, 0, 0); + if (bConstant) + { + USHORT S, L; + for (S = 0; S < M+1; S++) + { + i = S; + while (i < M+1 && pQ->GetDouble(i, S) == 0.0) + i++; + if (i >= M+1) + { + SetNoValue(); + delete pQ; + delete pE; + ResetNewMat(nMatInd12); + ResetNewMat(nMatInd10); + return; + } + double fVal; + for (L = 0; L < M+2; L++) + { + fVal = pQ->GetDouble(S, L); + pQ->PutDouble(pQ->GetDouble(i, L), S, L); + pQ->PutDouble(fVal, i, L); + } + fVal = 1.0/pQ->GetDouble(S, S); + for (L = 0; L < M+2; L++) + pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); + for (i = 0; i < M+1; i++) + { + if (i != S) + { + fVal = -pQ->GetDouble(i, S); + for (L = 0; L < M+2; L++) + pQ->PutDouble( + pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); + } + } + } + } + else + { + USHORT S, L; + for (S = 1; S < M+1; S++) + { + i = S; + while (i < M+1 && pQ->GetDouble(i, S) == 0.0) + i++; + if (i >= M+1) + { + SetNoValue(); + delete pQ; + delete pE; + ResetNewMat(nMatInd12); + ResetNewMat(nMatInd10); + return; + } + double fVal; + for (L = 1; L < M+2; L++) + { + fVal = pQ->GetDouble(S, L); + pQ->PutDouble(pQ->GetDouble(i, L), S, L); + pQ->PutDouble(fVal, i, L); + } + fVal = 1.0/pQ->GetDouble(S, S); + for (L = 1; L < M+2; L++) + pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); + for (i = 1; i < M+1; i++) + { + if (i != S) + { + fVal = -pQ->GetDouble(i, S); + for (L = 1; L < M+2; L++) + pQ->PutDouble( + pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); + } + } + pQ->PutDouble(0.0, 0, M+1); + } + } + if (nCase == 2) + { + pResMat = GetNewMat(1, nRXN, nMatInd); + if (!pResMat) + { + SetIllegalParameter(); + return; + } + double fVal; + for (i = 0; i < nRXN; i++) + { + fVal = pQ->GetDouble(0, M+1); + for (j = 0; j < M; j++) + fVal += pQ->GetDouble(j+1, M+1)*pMatNewX->GetDouble(j, i); + pResMat->PutDouble(fVal, i); + } + } + else + { + pResMat = GetNewMat(nCXN, 1, nMatInd); + if (!pResMat) + { + SetIllegalParameter(); + return; + } + double fVal; + for (i = 0; i < nCXN; i++) + { + fVal = pQ->GetDouble(0, M+1); + for (j = 0; j < M; j++) + fVal += pQ->GetDouble(j+1, M+1)*pMatNewX->GetDouble(i, j); + pResMat->PutDouble(fVal, i); + } + } + delete pQ; + delete pE; + ResetNewMat(nMatInd12); + ResetNewMat(nMatInd10); + } + PushMatrix(pResMat); + nRetMat = nMatInd; +} + +void ScInterpreter::ScGrowth() +{ + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 1, 4 ) ) + return; + BOOL bConstant; + if (nParamCount == 4) + bConstant = GetBool(); + else + bConstant = TRUE; + USHORT nMatInd1, nMatInd2, nMatInd3; + ScMatrix* pMatX; + ScMatrix* pMatY; + ScMatrix* pMatNewX; + if (nParamCount >= 3) + pMatNewX = GetMatrix(nMatInd3); + else + pMatNewX = NULL; + if (nParamCount >= 2) + pMatX = GetMatrix(nMatInd2); + else + pMatX = NULL; + pMatY = GetMatrix(nMatInd1); + if (!pMatY) + { + SetIllegalParameter(); + return; + } + BYTE nCase; // 1 = normal, 2,3 = mehrfach + USHORT nCX, nRX, nCY, nRY, M, N; + pMatY->GetDimensions(nCY, nRY); + ULONG nCountY = (ULONG) nCY * nRY; + ULONG i; + for (i = 0; i < nCountY; i++) + if (!pMatY->IsValue(i)) + { + SetIllegalArgument(); + return; + } + for (i = 0; i < nCountY; i++) + { + if (pMatY->GetDouble(i) <= 0.0) + { + SetIllegalArgument(); + return; + } + else + pMatY->PutDouble(log(pMatY->GetDouble(i)), i); + } + if (pMatX) + { + pMatX->GetDimensions(nCX, nRX); + ULONG nCountX = (ULONG) nCX * nRX; + for ( ULONG i = 0; i < nCountX; i++ ) + if (!pMatX->IsValue(i)) + { + SetIllegalArgument(); + return; + } + if (nCX == nCY && nRX == nRY) + nCase = 1; // einfache Regression + else if (nCY != 1 && nRY != 1) + { + SetIllegalParameter(); + return; + } + else if (nCY == 1) + { + if (nRX != nRY) + { + SetIllegalParameter(); + return; + } + else + { + nCase = 2; // zeilenweise + N = nRY; + M = nCX; + } + } + else if (nCX != nCY) + { + SetIllegalParameter(); + return; + } + else + { + nCase = 3; // spaltenweise + N = nCY; + M = nRX; + } + } + else + { + pMatX = GetNewMat(nCY, nRY, nMatInd2); + nCX = nCY; + nRX = nRY; + if (!pMatX) + { + SetIllegalParameter(); + return; + } + for (i = 1; i <= nCountY; i++) + pMatX->PutDouble((double)i, i-1); + nCase = 1; + } + USHORT nCXN, nRXN; + ULONG nCountXN; + if (!pMatNewX) + { + nCXN = nCX; + nRXN = nRX; + nCountXN = (ULONG) nCXN * nRXN; + pMatNewX = pMatX; + } + else + { + pMatNewX->GetDimensions(nCXN, nRXN); + if ((nCase == 2 && nCX != nCXN) || (nCase == 3 && nRX != nRXN)) + { + SetIllegalArgument(); + return; + } + nCountXN = (ULONG) nCXN * nRXN; + for ( ULONG i = 0; i < nCountXN; i++ ) + if (!pMatNewX->IsValue(i)) + { + SetIllegalArgument(); + return; + } + } + USHORT nMatInd; + ScMatrix* pResMat; + if (nCase == 1) + { + double fCount = 0.0; + double fSumX = 0.0; + double fSumSqrX = 0.0; + double fSumY = 0.0; + double fSumSqrY = 0.0; + double fSumXY = 0.0; + double fValX, fValY; + for (USHORT i = 0; i < nCY; i++) + for (USHORT j = 0; j < nRY; j++) + { + fValX = pMatX->GetDouble(i,j); + fValY = pMatY->GetDouble(i,j); + fSumX += fValX; + fSumSqrX += fValX * fValX; + fSumY += fValY; + fSumSqrY += fValY * fValY; + fSumXY += fValX*fValY; + fCount++; + } + if (fCount < 1.0) + { + SetNoValue(); + return; + } + else + { + double f1 = fCount*fSumXY-fSumX*fSumY; + double fX = fCount*fSumSqrX-fSumX*fSumX; + double b, m; + if (bConstant) + { + b = fSumY/fCount - f1/fX*fSumX/fCount; + m = f1/fX; + } + else + { + b = 0.0; + m = fSumXY/fSumSqrX; + } + pResMat = GetNewMat(nCXN, nRXN, nMatInd); + if (!pResMat) + { + SetIllegalParameter(); + return; + } + for (i = 0; i < nCountXN; i++) + pResMat->PutDouble(exp(pMatNewX->GetDouble(i)*m+b), i); + } + } + else + { + USHORT nMatInd10, nMatInd12, i, j, k; + ScMatrix* pQ = GetNewMat(M+1, M+2, nMatInd10); + ScMatrix* pE = GetNewMat(M+2, 1, nMatInd12); + pE->PutDouble(0.0, M+1); + pQ->FillDouble(0.0, 0, 0, M, M+1); + if (nCase == 2) + { + for (k = 0; k < N; k++) + { + pE->PutDouble( + pE->GetDouble(M+1)+pMatY->GetDouble(k)*pMatY->GetDouble(k), M+1); + pQ->PutDouble(pQ->GetDouble(0, M+1) + pMatY->GetDouble(k), 0, M+1); + pE->PutDouble(pQ->GetDouble(0, M+1), 0); + for (i = 0; i < M; i++) + { + pQ->PutDouble(pQ->GetDouble(0, i+1)+pMatX->GetDouble(i,k), 0, i+1); + pQ->PutDouble(pQ->GetDouble(0, i+1), i+1, 0); + pQ->PutDouble(pQ->GetDouble(i+1, M+1) + + pMatX->GetDouble(i,k)*pMatY->GetDouble(k), i+1, M+1); + pE->PutDouble(pQ->GetDouble(i+1, M+1), i+1); + for (j = i; j < M; j++) + { + pQ->PutDouble(pQ->GetDouble(j+1, i+1) + + pMatX->GetDouble(i,k)*pMatX->GetDouble(j,k), j+1, i+1); + pQ->PutDouble(pQ->GetDouble(j+1, i+1), i+1, j+1); + } + } + } + } + else + { + for (k = 0; k < N; k++) + { + pE->PutDouble( + pE->GetDouble(M+1)+pMatY->GetDouble(k)*pMatY->GetDouble(k), M+1); + pQ->PutDouble(pQ->GetDouble(0, M+1) + pMatY->GetDouble(k), 0, M+1); + pE->PutDouble(pQ->GetDouble(0, M+1), 0); + for (i = 0; i < M; i++) + { + pQ->PutDouble(pQ->GetDouble(0, i+1)+pMatX->GetDouble(k,i), 0, i+1); + pQ->PutDouble(pQ->GetDouble(0, i+1), i+1, 0); + pQ->PutDouble(pQ->GetDouble(i+1, M+1) + + pMatX->GetDouble(k,i)*pMatY->GetDouble(k), i+1, M+1); + pE->PutDouble(pQ->GetDouble(i+1, M+1), i+1); + for (j = i; j < M; j++) + { + pQ->PutDouble(pQ->GetDouble(j+1, i+1) + + pMatX->GetDouble(k, i)*pMatX->GetDouble(k, j), j+1, i+1); + pQ->PutDouble(pQ->GetDouble(j+1, i+1), i+1, j+1); + } + } + } + } + pQ->PutDouble((double)N, 0, 0); + if (bConstant) + { + USHORT S, L; + for (S = 0; S < M+1; S++) + { + i = S; + while (i < M+1 && pQ->GetDouble(i, S) == 0.0) + i++; + if (i >= M+1) + { + SetNoValue(); + delete pQ; + delete pE; + ResetNewMat(nMatInd12); + ResetNewMat(nMatInd10); + return; + } + double fVal; + for (L = 0; L < M+2; L++) + { + fVal = pQ->GetDouble(S, L); + pQ->PutDouble(pQ->GetDouble(i, L), S, L); + pQ->PutDouble(fVal, i, L); + } + fVal = 1.0/pQ->GetDouble(S, S); + for (L = 0; L < M+2; L++) + pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); + for (i = 0; i < M+1; i++) + { + if (i != S) + { + fVal = -pQ->GetDouble(i, S); + for (L = 0; L < M+2; L++) + pQ->PutDouble( + pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); + } + } + } + } + else + { + USHORT S, L; + for (S = 1; S < M+1; S++) + { + i = S; + while (i < M+1 && pQ->GetDouble(i, S) == 0.0) + i++; + if (i >= M+1) + { + SetNoValue(); + delete pQ; + delete pE; + ResetNewMat(nMatInd12); + ResetNewMat(nMatInd10); + return; + } + double fVal; + for (L = 1; L < M+2; L++) + { + fVal = pQ->GetDouble(S, L); + pQ->PutDouble(pQ->GetDouble(i, L), S, L); + pQ->PutDouble(fVal, i, L); + } + fVal = 1.0/pQ->GetDouble(S, S); + for (L = 1; L < M+2; L++) + pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); + for (i = 1; i < M+1; i++) + { + if (i != S) + { + fVal = -pQ->GetDouble(i, S); + for (L = 1; L < M+2; L++) + pQ->PutDouble( + pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); + } + } + pQ->PutDouble(0.0, 0, M+1); + } + } + if (nCase == 2) + { + pResMat = GetNewMat(1, nRXN, nMatInd); + if (!pResMat) + { + SetIllegalParameter(); + return; + } + double fVal; + for (i = 0; i < nRXN; i++) + { + fVal = pQ->GetDouble(0, M+1); + for (j = 0; j < M; j++) + fVal += pQ->GetDouble(j+1, M+1)*pMatNewX->GetDouble(j, i); + pResMat->PutDouble(exp(fVal), i); + } + } + else + { + pResMat = GetNewMat(nCXN, 1, nMatInd); + if (!pResMat) + { + SetIllegalParameter(); + return; + } + double fVal; + for (i = 0; i < nCXN; i++) + { + fVal = pQ->GetDouble(0, M+1); + for (j = 0; j < M; j++) + fVal += pQ->GetDouble(j+1, M+1)*pMatNewX->GetDouble(i, j); + pResMat->PutDouble(exp(fVal), i); + } + } + delete pQ; + delete pE; + ResetNewMat(nMatInd12); + ResetNewMat(nMatInd10); + } + PushMatrix(pResMat); + nRetMat = nMatInd; +} + +/*N*/ void ScInterpreter::ScMatRef() +/*N*/ { +/*N*/ // Falls Deltarefs drin sind... +/*N*/ Push( (ScToken&) *pCur ); +/*N*/ ScAddress aAdr; +/*N*/ PopSingleRef( aAdr ); +/*N*/ ScFormulaCell* pCell = (ScFormulaCell*) GetCell( aAdr ); +/*N*/ if( pCell && pCell->GetCellType() == CELLTYPE_FORMULA ) +/*N*/ { +/*N*/ ScMatrix* pMat; +/*N*/ pCell->GetMatrix( &pMat ); +/*N*/ if( pMat ) +/*N*/ { +/*N*/ USHORT nCl, nRw; +/*N*/ pMat->GetDimensions( nCl, nRw ); +/*N*/ USHORT nC = aPos.Col() - aAdr.Col(); +/*N*/ USHORT nR = aPos.Row() - aAdr.Row(); +/*N*/ if (nC < nCl && nR < nRw) +/*N*/ { +/*N*/ BOOL bIsString; +/*N*/ const MatValue* pMatVal = pMat->Get(nC, nR, bIsString); +/*N*/ if (bIsString) +/*?*/ PushString( pMatVal->GetString() ); +/*N*/ else +/*N*/ { +/*N*/ PushDouble(pMatVal->fVal); +/*N*/ pDok->GetNumberFormatInfo( nCurFmtType, nCurFmtIndex, aAdr, *pCell ); +/*N*/ nFuncFmtType = nCurFmtType; +/*N*/ nFuncFmtIndex = nCurFmtIndex; +/*N*/ } +/*N*/ } +/*N*/ else +/*?*/ SetNV(); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ // Ist gar keine Ergebnis-Matrix, dann bitte den Wert holen! +/*?*/ USHORT nErr = pCell->GetErrCode(); +/*?*/ SetError( nErr ); +/*?*/ if( pCell->IsValue() ) +/*?*/ PushDouble( pCell->GetValue() ); +/*?*/ else +/*?*/ { +/*?*/ String aVal; +/*?*/ pCell->GetString( aVal ); +/*?*/ PushString( aVal ); +/*?*/ } +/*?*/ pDok->GetNumberFormatInfo( nCurFmtType, nCurFmtIndex, aAdr, *pCell ); +/*?*/ nFuncFmtType = nCurFmtType; +/*?*/ nFuncFmtIndex = nCurFmtIndex; +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ SetError( errNoRef ); +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_interpr6.cxx b/binfilter/bf_sc/source/core/tool/sc_interpr6.cxx new file mode 100644 index 000000000000..398e1adc94d6 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_interpr6.cxx @@ -0,0 +1,182 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <basegfx/numeric/ftools.hxx> + + +#include "interpre.hxx" +namespace binfilter { + + +//! #66556# for os2icci3 this function MUST be compiled without optimizations, +//! otherwise it won't work at all or even worse will produce false results! +double ScInterpreter::GetGammaDist(double x, double alpha, double beta) +{ + if (x == 0.0) + return 0.0; + + x /= beta; + double gamma = alpha; + + double c = 0.918938533204672741; + double d[10] = { + 0.833333333333333333E-1, + -0.277777777777777778E-2, + 0.793650793650793651E-3, + -0.595238095238095238E-3, + 0.841750841750841751E-3, + -0.191752691752691753E-2, + 0.641025641025641025E-2, + -0.295506535947712418E-1, + 0.179644372368830573, + -0.139243221690590111E1 + }; + + int ipr = 6; + + double dx = x; + double dgamma = gamma; + int maxit = 10000; + + double z = dgamma; + double den = 1.0; + while ( z < 10.0 ) //! approx? + { + den *= z; + z += 1.0; + } + + double z2 = z*z; + double z3 = z*z2; + double z4 = z2*z2; + double z5 = z2*z3; + double a = ( z - 0.5 ) * log(z) - z + c; + double b = d[0]/z + d[1]/z3 + d[2]/z5 + d[3]/(z2*z5) + d[4]/(z4*z5) + + d[5]/(z*z5*z5) + d[6]/(z3*z5*z5) + d[7]/(z5*z5*z5) + d[8]/(z2*z5*z5*z5); + // double g = exp(a+b) / den; + + double sum = 1.0 / dgamma; + double term = 1.0 / dgamma; + double cut1 = dx - dgamma; + double cut2 = dx * 10000000000.0; + + for ( int i=1; i<=maxit; i++ ) + { + double ai = i; + term = dx * term / ( dgamma + ai ); + sum += term; + double cutoff = cut1 + ( cut2 * term / sum ); + if ( ai > cutoff ) + { + double t = sum; + // return pow( dx, dgamma ) * exp( -dx ) * t / g; + return exp( dgamma * log(dx) - dx - a - b ) * t * den; + } + } + +// DBG_ERROR("GetGammaDist bricht nicht ab"); + + return 1.0; // should not happen ... +} + +#if 0 +//! this algorithm doesn't work right in every cases! +double ScInterpreter::GetGammaDist(double x, double alpha, double beta) +{ + if (x == 0.0) + return 0.0; + double fEps = 1.0E-6; + double fGamma; + double G = GetLogGamma(alpha); + x /= beta; + G = alpha*log(x)-x-G; + if (x <= alpha+1.0) + { + if (x < fEps || fabs(G) >= 500.0) + fGamma = 0.0; + else + { + double fF = 1.0/alpha; + double fS = fF; + double anum = alpha; + for (USHORT i = 0; i < 100; i++) + { + anum += 1.0; + fF *= x/anum; + fS += fF; + if (fF < fEps) + i = 100; + } + fGamma = fS*exp(G); + } + } + else + { + if (fabs(G) >= 500.0) + fGamma = 1.0; + else + { + double a0, b0, a1, b1, cf, fnorm, a2j, a2j1, cfnew; + a0 = 0.0; b0 = 1.0; a1 = 1.0; + b1 = x; + cf = fEps; + fnorm = 1.0; + cfnew = 0.0; + for (USHORT j = 1; j <= 100; j++) + { + a2j = ((double) j) - alpha; + a2j1 = (double) j; + a0 = (a1+a2j*a0); // *fnorm; + b0 = (b1+a2j*b0); // *fnorm; + a1 = (x*a0+a2j1*a1)*fnorm; + b1 = (x*b0+a2j1*b1)*fnorm; + if (b1 != 0.0) + { + fnorm = 1.0/b1; + cfnew = a1*fnorm; + if (fabs(cf-cfnew)/cf < fEps) + j = 101; + else + cf = cfnew; + } + } + fGamma = 1.0 - exp(G)*cfnew; + } + } + return fGamma; +} +#endif + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_optutil.cxx b/binfilter/bf_sc/source/core/tool/sc_optutil.cxx new file mode 100644 index 000000000000..518a50bbe454 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_optutil.cxx @@ -0,0 +1,75 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include "optutil.hxx" +#include "global.hxx" // for pSysLocale + +#include <bf_svtools/syslocale.hxx> +namespace binfilter { + +//------------------------------------------------------------------ + +// static +/*N*/ BOOL ScOptionsUtil::IsMetricSystem() +/*N*/ { +/*N*/ //! which language should be used here - system language or installed office language? +/*N*/ +/*N*/ // MeasurementSystem eSys = Application::GetAppInternational().GetMeasurementSystem(); +/*N*/ MeasurementSystem eSys = ScGlobal::pLocaleData->getMeasurementSystemEnum(); +/*N*/ +/*N*/ return ( eSys == MEASURE_METRIC ); +/*N*/ } + +//------------------------------------------------------------------ + +/*N*/ ScLinkConfigItem::ScLinkConfigItem( const ::rtl::OUString rSubTree ) : +/*N*/ ConfigItem( rSubTree ) +/*N*/ { +/*N*/ } + +/*N*/ void ScLinkConfigItem::SetCommitLink( const Link& rLink ) +/*N*/ { +/*N*/ aCommitLink = rLink; +/*N*/ } + +void ScLinkConfigItem::Notify( const com::sun::star::uno::Sequence< rtl::OUString >& ) +{ +} + +void ScLinkConfigItem::Commit() +{ +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_printopt.cxx b/binfilter/bf_sc/source/core/tool/sc_printopt.cxx new file mode 100644 index 000000000000..b9a4e55b8f5b --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_printopt.cxx @@ -0,0 +1,107 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include "printopt.hxx" +namespace binfilter { + +using namespace utl; +using namespace rtl; +using namespace ::com::sun::star::uno; + +// ----------------------------------------------------------------------- + + +// ----------------------------------------------------------------------- + +/*N*/ ScPrintOptions::ScPrintOptions() +/*N*/ { +/*N*/ SetDefaults(); +/*N*/ } + +/*N*/ ScPrintOptions::ScPrintOptions( const ScPrintOptions& rCpy ) : +/*N*/ bSkipEmpty( rCpy.bSkipEmpty ), +/*N*/ bAllSheets( rCpy.bAllSheets ) +/*N*/ { +/*N*/ } + +/*N*/ ScPrintOptions::~ScPrintOptions() +/*N*/ { +/*N*/ } + +/*N*/ void ScPrintOptions::SetDefaults() +/*N*/ { +/*N*/ bSkipEmpty = FALSE; +/*N*/ bAllSheets = TRUE; +/*N*/ } + + + + +// ----------------------------------------------------------------------- + + + + + + + + +// ----------------------------------------------------------------------- + +#define CFGPATH_PRINT "Office.Calc/Print" + +#define SCPRINTOPT_EMPTYPAGES 0 +#define SCPRINTOPT_ALLSHEETS 1 +#define SCPRINTOPT_COUNT 2 + + +/*N*/ ScPrintCfg::ScPrintCfg() : +/*N*/ ConfigItem( OUString::createFromAscii( CFGPATH_PRINT ) ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 Sequence<OUString> aNames = GetPropertyNames(); +/*N*/ } + + +void ScPrintCfg::Notify( const ::com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames ) +{ +} +void ScPrintCfg::Commit() +{ +} + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_prnsave.cxx b/binfilter/bf_sc/source/core/tool/sc_prnsave.cxx new file mode 100644 index 000000000000..c8acfe2f30ce --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_prnsave.cxx @@ -0,0 +1,122 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// INCLUDE --------------------------------------------------------------- + +#include <tools/debug.hxx> + +#include "prnsave.hxx" +#include "global.hxx" +namespace binfilter { + +// STATIC DATA ----------------------------------------------------------- + +//------------------------------------------------------------------ + +// +// Daten pro Tabelle +// + +/*N*/ ScPrintSaverTab::ScPrintSaverTab() : +/*N*/ nPrintCount(0), +/*N*/ pPrintRanges(NULL), +/*N*/ pRepeatCol(NULL), +/*N*/ pRepeatRow(NULL) +/*N*/ { +/*N*/ } + +/*N*/ ScPrintSaverTab::~ScPrintSaverTab() +/*N*/ { +/*N*/ delete[] pPrintRanges; +/*N*/ delete pRepeatCol; +/*N*/ delete pRepeatRow; +/*N*/ } + +/*N*/ void ScPrintSaverTab::SetAreas( USHORT nCount, const ScRange* pRanges ) +/*N*/ { +/*N*/ delete[] pPrintRanges; +/*N*/ if (nCount && pRanges) +/*N*/ { +/*N*/ nPrintCount = nCount; +/*N*/ pPrintRanges = new ScRange[nCount]; +/*N*/ for (USHORT i=0; i<nCount; i++) +/*N*/ pPrintRanges[i] = pRanges[i]; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nPrintCount = 0; +/*N*/ pPrintRanges = NULL; +/*N*/ } +/*N*/ } + +/*N*/ void ScPrintSaverTab::SetRepeat( const ScRange* pCol, const ScRange* pRow ) +/*N*/ { +/*N*/ delete pRepeatCol; +/*N*/ pRepeatCol = pCol ? new ScRange(*pCol) : NULL; +/*N*/ delete pRepeatRow; +/*N*/ pRepeatRow = pRow ? new ScRange(*pRow) : NULL; +/*N*/ } + + + +// +// Daten fuer das ganze Dokument +// + +/*N*/ ScPrintRangeSaver::ScPrintRangeSaver( USHORT nCount ) : +/*N*/ nTabCount( nCount ) +/*N*/ { +/*N*/ if (nCount) +/*N*/ pData = new ScPrintSaverTab[nCount]; +/*N*/ else +/*N*/ pData = NULL; +/*N*/ } + +/*N*/ ScPrintRangeSaver::~ScPrintRangeSaver() +/*N*/ { +/*N*/ delete[] pData; +/*N*/ } + +/*N*/ ScPrintSaverTab& ScPrintRangeSaver::GetTabData(USHORT nTab) +/*N*/ { +/*N*/ DBG_ASSERT(nTab<nTabCount,"ScPrintRangeSaver Tab zu gross"); +/*N*/ return pData[nTab]; +/*N*/ } + + + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_progress.cxx b/binfilter/bf_sc/source/core/tool/sc_progress.cxx new file mode 100644 index 000000000000..0e0872b647ce --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_progress.cxx @@ -0,0 +1,129 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +//------------------------------------------------------------------------ + +#include <bf_sfx2/app.hxx> +#include <bf_sfx2/objsh.hxx> +#include <bf_sfx2/sfxsids.hrc> + +#define SC_PROGRESS_CXX +#include "progress.hxx" +#include "globstr.hrc" +namespace binfilter { + + + +static ScProgress theDummyInterpretProgress; +SfxProgress* ScProgress::pGlobalProgress = NULL; +ULONG ScProgress::nGlobalRange = 0; +ULONG ScProgress::nGlobalPercent = 0; +BOOL ScProgress::bGlobalNoUserBreak = TRUE; +ScProgress* ScProgress::pInterpretProgress = &theDummyInterpretProgress; +ScProgress* ScProgress::pOldInterpretProgress = NULL; +ULONG ScProgress::nInterpretProgress = 0; +BOOL ScProgress::bAllowInterpretProgress = TRUE; +ScDocument* ScProgress::pInterpretDoc; +BOOL ScProgress::bIdleWasDisabled = FALSE; + + + +/*N*/ ScProgress::ScProgress( SfxObjectShell* pObjSh, const String& rText, +/*N*/ ULONG nRange, BOOL bAllDocs, BOOL bWait ) +/*N*/ { +/*N*/ +/*N*/ if ( pGlobalProgress || SfxProgress::GetActiveProgress( NULL ) ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 if ( lcl_IsHiddenDocument(pObjSh) ) +/*N*/ } +/*N*/ else if ( SFX_APP()->IsDowning() ) +/*N*/ { +/*N*/ // kommt vor z.B. beim Speichern des Clipboard-Inhalts als OLE beim Beenden +/*N*/ // Dann wuerde ein SfxProgress wild im Speicher rummuellen +/*N*/ //! Soll das so sein ??? +/*N*/ +/*N*/ pProgress = NULL; +/*N*/ } +/*N*/ else if ( pObjSh && ( pObjSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED || +/*N*/ pObjSh->GetProgress() ) ) +/*N*/ { +/*N*/ // #62808# no own progress for embedded objects, +/*N*/ // #73633# no second progress if the document already has one +/*N*/ +/*N*/ pProgress = NULL; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pProgress = new SfxProgress( pObjSh, rText, nRange, bAllDocs, bWait ); +/*N*/ pGlobalProgress = pProgress; +/*N*/ nGlobalRange = nRange; +/*N*/ nGlobalPercent = 0; +/*N*/ bGlobalNoUserBreak = TRUE; +/*N*/ } +/*N*/ } + + +/*N*/ ScProgress::ScProgress() : +/*N*/ pProgress( NULL ) +/*N*/ { // DummyInterpret +/*N*/ } + + +/*N*/ ScProgress::~ScProgress() +/*N*/ { +/*N*/ if ( pProgress ) +/*N*/ { +/*N*/ delete pProgress; +/*N*/ pGlobalProgress = NULL; +/*N*/ nGlobalRange = 0; +/*N*/ nGlobalPercent = 0; +/*N*/ bGlobalNoUserBreak = TRUE; +/*N*/ } +/*N*/ } + + +// static + + + +// static + + + +// static + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_rangelst.cxx b/binfilter/bf_sc/source/core/tool/sc_rangelst.cxx new file mode 100644 index 000000000000..a0e670a5e5dc --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_rangelst.cxx @@ -0,0 +1,555 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +//------------------------------------------------------------------------ + +#define SC_RANGELST_CXX //fuer ICC + +#include <stdlib.h> // qsort + +#include "document.hxx" +#include "refupdat.hxx" +#include "rechead.hxx" +namespace binfilter { + + +// === ScRangeList ==================================================== + +/*N*/ ScRangeList::~ScRangeList() +/*N*/ { +/*N*/ for ( ScRangePtr pR = First(); pR; pR = Next() ) +/*N*/ delete pR; +/*N*/ } + +/*N*/ void ScRangeList::RemoveAll() +/*N*/ { +/*N*/ for ( ScRangePtr pR = First(); pR; pR = Next() ) +/*N*/ delete pR; +/*N*/ Clear(); +/*N*/ } + +/*N*/ USHORT ScRangeList::Parse( const String& rStr, ScDocument* pDoc, USHORT nMask ) +/*N*/ { +/*N*/ if ( rStr.Len() ) +/*N*/ { +/*N*/ nMask |= SCA_VALID; // falls das jemand vergessen sollte +/*N*/ USHORT nResult = (USHORT)~0; // alle Bits setzen +/*N*/ ScRange aRange; +/*N*/ String aOne; +/*N*/ USHORT nTab = 0; +/*N*/ if ( pDoc ) +/*N*/ { +/*N*/ //! erste markierte Tabelle gibts nicht mehr am Dokument +/*N*/ //! -> uebergeben? oder spaeter an den Ranges setzen +/*N*/ } +/*N*/ else +/*N*/ nTab = 0; +/*N*/ USHORT nTCount = rStr.GetTokenCount(); +/*N*/ for ( USHORT i=0; i<nTCount; i++ ) +/*N*/ { +/*N*/ aOne = rStr.GetToken(i); +/*N*/ if ( aOne.Search( ':' ) == STRING_NOTFOUND ) +/*N*/ { // Range muss es sein +/*N*/ String aStrTmp( aOne ); +/*N*/ aOne += ':'; +/*N*/ aOne += aStrTmp; +/*N*/ } +/*N*/ aRange.aStart.SetTab( nTab ); // Default Tab wenn nicht angegeben +/*N*/ USHORT nRes = aRange.Parse( aOne, pDoc ); +/*N*/ if ( (nRes & nMask) == nMask ) +/*N*/ Append( aRange ); +/*N*/ nResult &= nRes; // alle gemeinsamen Bits bleiben erhalten +/*N*/ } +/*N*/ return nResult; // SCA_VALID gesetzt wenn alle ok +/*N*/ } +/*N*/ else +/*N*/ return 0; +/*N*/ } + + +/*N*/ void ScRangeList::Format( String& rStr, USHORT nFlags, ScDocument* pDoc ) const +/*N*/ { +/*N*/ rStr.Erase(); +/*N*/ ULONG nCnt = Count(); +/*N*/ for ( ULONG nIdx = 0; nIdx < nCnt; nIdx++ ) +/*N*/ { +/*N*/ String aStr; +/*N*/ GetObject( nIdx )->Format( aStr, nFlags, pDoc ); +/*N*/ if ( nIdx ) +/*N*/ rStr += ';'; +/*N*/ rStr += aStr; +/*N*/ } +/*N*/ } + + +/*N*/ void ScRangeList::Join( const ScRange& r, BOOL bIsInList ) +/*N*/ { +/*N*/ if ( !Count() ) +/*N*/ { +/*N*/ Append( r ); +/*N*/ return ; +/*N*/ } +/*N*/ USHORT nCol1 = r.aStart.Col(); +/*N*/ USHORT nRow1 = r.aStart.Row(); +/*N*/ USHORT nTab1 = r.aStart.Tab(); +/*N*/ USHORT nCol2 = r.aEnd.Col(); +/*N*/ USHORT nRow2 = r.aEnd.Row(); +/*N*/ USHORT nTab2 = r.aEnd.Tab(); +/*N*/ ScRangePtr pOver = (ScRangePtr) &r; // fies aber wahr wenn bInList +/*N*/ ULONG nOldPos; +/*N*/ if ( bIsInList ) +/*N*/ { // merken um ggbf. zu loeschen bzw. wiederherzustellen +/*N*/ nOldPos = GetPos( pOver ); +/*N*/ } +/*N*/ BOOL bJoinedInput = FALSE; +/*N*/ for ( ScRangePtr p = First(); p && pOver; p = Next() ) +/*N*/ { +/*N*/ if ( p == pOver ) +/*N*/ continue; // derselbe, weiter mit dem naechsten +/*N*/ BOOL bJoined = FALSE; +/*N*/ if ( p->In( r ) ) +/*N*/ { // Range r in Range p enthalten oder identisch +/*N*/ if ( bIsInList ) +/*N*/ bJoined = TRUE; // weg mit Range r +/*N*/ else +/*N*/ { // das war's dann +/*N*/ bJoinedInput = TRUE; // nicht anhaengen +/*N*/ break; // for +/*N*/ } +/*N*/ } +/*N*/ else if ( r.In( *p ) ) +/*N*/ { // Range p in Range r enthalten, r zum neuen Range machen +/*N*/ *p = r; +/*N*/ bJoined = TRUE; +/*N*/ } +/*N*/ if ( !bJoined && p->aStart.Tab() == nTab1 && p->aEnd.Tab() == nTab2 ) +/*N*/ { // 2D +/*N*/ if ( p->aStart.Col() == nCol1 && p->aEnd.Col() == nCol2 ) +/*N*/ { +/*N*/ if ( p->aStart.Row() == nRow2+1 ) +/*N*/ { // oben +/*?*/ p->aStart.SetRow( nRow1 ); +/*?*/ bJoined = TRUE; +/*N*/ } +/*N*/ else if ( p->aEnd.Row() == nRow1-1 ) +/*N*/ { // unten +/*N*/ p->aEnd.SetRow( nRow2 ); +/*N*/ bJoined = TRUE; +/*N*/ } +/*N*/ } +/*N*/ else if ( p->aStart.Row() == nRow1 && p->aEnd.Row() == nRow2 ) +/*N*/ { +/*N*/ if ( p->aStart.Col() == nCol2+1 ) +/*N*/ { // links +/*?*/ p->aStart.SetCol( nCol1 ); +/*?*/ bJoined = TRUE; +/*N*/ } +/*N*/ else if ( p->aEnd.Col() == nCol1-1 ) +/*N*/ { // rechts +/*N*/ p->aEnd.SetCol( nCol2 ); +/*N*/ bJoined = TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( bJoined ) +/*N*/ { +/*N*/ if ( bIsInList ) +/*N*/ { // innerhalb der Liste Range loeschen +/*N*/ Remove( nOldPos ); +/*N*/ delete pOver; +/*N*/ pOver = NULL; +/*N*/ if ( nOldPos ) +/*N*/ nOldPos--; // Seek richtig aufsetzen +/*N*/ } +/*N*/ bJoinedInput = TRUE; +/*N*/ Join( *p, TRUE ); // rekursiv! +/*N*/ } +/*N*/ } +/*N*/ if ( bIsInList ) +/*N*/ Seek( nOldPos ); +/*N*/ else if ( !bJoinedInput ) +/*N*/ Append( r ); +/*N*/ } + + + + +/*N*/ BOOL ScRangeList::Store( SvStream& rStream ) const +/*N*/ { +/*N*/ BOOL bOk = TRUE; +/*N*/ ULONG nCount = Count(); +/*N*/ ULONG nBytes = sizeof(UINT32) + nCount * sizeof(ScRange); +/*N*/ ScWriteHeader aHdr( rStream, nBytes ); +/*N*/ rStream << (UINT32) nCount; +/*N*/ for ( ULONG j = 0; j < nCount && bOk; j++ ) +/*N*/ { +/*N*/ rStream << *GetObject( j ); +/*N*/ if( rStream.GetError() != SVSTREAM_OK ) +/*N*/ bOk = FALSE; +/*N*/ } +/*N*/ return bOk; +/*N*/ } + + +/*N*/ BOOL ScRangeList::Load( SvStream& rStream, USHORT nVer ) +/*N*/ { +/*N*/ BOOL bOk = TRUE; +/*N*/ ScReadHeader aHdr( rStream ); +/*N*/ ScRange aRange; +/*N*/ UINT32 n; +/*N*/ rStream >> n; +/*N*/ ULONG nCount = n; +/*N*/ for ( ULONG j = 0; j < nCount && bOk; j++ ) +/*N*/ { +/*N*/ rStream >> aRange; +/*N*/ Append( aRange ); +/*N*/ if( rStream.GetError() != SVSTREAM_OK ) +/*N*/ bOk = FALSE; +/*N*/ } +/*N*/ return bOk; +/*N*/ } + + +/*N*/ BOOL ScRangeList::UpdateReference( UpdateRefMode eUpdateRefMode, +/*N*/ ScDocument* pDoc, const ScRange& rWhere, +/*N*/ short nDx, short nDy, short nDz ) +/*N*/ { +/*N*/ BOOL bChanged = FALSE; +/*N*/ if ( Count() ) +/*N*/ { +/*N*/ USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; +/*N*/ rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); +/*N*/ for ( ScRange* pR = First(); pR; pR = Next() ) +/*N*/ { +/*N*/ USHORT theCol1, theRow1, theTab1, theCol2, theRow2, theTab2; +/*N*/ pR->GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 ); +/*N*/ if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, +/*N*/ nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, +/*N*/ nDx, nDy, nDz, +/*N*/ theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 ) +/*N*/ != UR_NOTHING ) +/*N*/ { +/*?*/ bChanged = TRUE; +/*?*/ pR->aStart.Set( theCol1, theRow1, theTab1 ); +/*?*/ pR->aEnd.Set( theCol2, theRow2, theTab2 ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return bChanged; +/*N*/ } + + + + + + +/*N*/ ScRangeList::ScRangeList( const ScRangeList& rList ) +/*N*/ { +/*N*/ ULONG nCount = rList.Count(); +/*N*/ for ( ULONG j = 0; j < nCount; j++ ) +/*N*/ Append( *rList.GetObject( j ) ); +/*N*/ } + + + + +/*N*/ ScRangeList& ScRangeList::operator=(const ScRangeList& rList) +/*N*/ { +/*N*/ RemoveAll(); +/*N*/ +/*N*/ ULONG nCount = rList.Count(); +/*N*/ for ( ULONG j = 0; j < nCount; j++ ) +/*N*/ Append( *rList.GetObject( j ) ); +/*N*/ +/*N*/ return *this; +/*N*/ } + + + + + + + + +// === ScRangePairList ==================================================== + +/*N*/ ScRangePairList::~ScRangePairList() +/*N*/ { +/*N*/ for ( ScRangePair* pR = First(); pR; pR = Next() ) +/*?*/ delete pR; +/*N*/ } + + +/*N*/ void ScRangePairList::Join( const ScRangePair& r, BOOL bIsInList ) +/*N*/ { +/*N*/ if ( !Count() ) +/*N*/ { +/*N*/ Append( r ); +/*N*/ return ; +/*N*/ } +/*N*/ const ScRange& r1 = r.GetRange(0); +/*N*/ const ScRange& r2 = r.GetRange(1); +/*N*/ USHORT nCol1 = r1.aStart.Col(); +/*N*/ USHORT nRow1 = r1.aStart.Row(); +/*N*/ USHORT nTab1 = r1.aStart.Tab(); +/*N*/ USHORT nCol2 = r1.aEnd.Col(); +/*N*/ USHORT nRow2 = r1.aEnd.Row(); +/*N*/ USHORT nTab2 = r1.aEnd.Tab(); +/*N*/ ScRangePair* pOver = (ScRangePair*) &r; // fies aber wahr wenn bInList +/*N*/ ULONG nOldPos; +/*N*/ if ( bIsInList ) +/*N*/ { // merken um ggbf. zu loeschen bzw. wiederherzustellen +/*N*/ nOldPos = GetPos( pOver ); +/*N*/ } +/*N*/ BOOL bJoinedInput = FALSE; +/*N*/ for ( ScRangePair* p = First(); p && pOver; p = Next() ) +/*N*/ { +/*N*/ if ( p == pOver ) +/*N*/ continue; // derselbe, weiter mit dem naechsten +/*N*/ BOOL bJoined = FALSE; +/*N*/ ScRange& rp1 = p->GetRange(0); +/*N*/ ScRange& rp2 = p->GetRange(1); +/*N*/ if ( rp2 == r2 ) +/*N*/ { // nur wenn Range2 gleich ist +/*N*/ if ( rp1.In( r1 ) ) +/*N*/ { // RangePair r in RangePair p enthalten oder identisch +/*N*/ if ( bIsInList ) +/*N*/ bJoined = TRUE; // weg mit RangePair r +/*N*/ else +/*N*/ { // das war's dann +/*N*/ bJoinedInput = TRUE; // nicht anhaengen +/*N*/ break; // for +/*N*/ } +/*N*/ } +/*N*/ else if ( r1.In( rp1 ) ) +/*N*/ { // RangePair p in RangePair r enthalten, r zum neuen RangePair machen +/*N*/ *p = r; +/*N*/ bJoined = TRUE; +/*N*/ } +/*N*/ } +/*N*/ if ( !bJoined && rp1.aStart.Tab() == nTab1 && rp1.aEnd.Tab() == nTab2 +/*N*/ && rp2.aStart.Tab() == r2.aStart.Tab() +/*N*/ && rp2.aEnd.Tab() == r2.aEnd.Tab() ) +/*N*/ { // 2D, Range2 muss genauso nebeneinander liegen wie Range1 +/*N*/ if ( rp1.aStart.Col() == nCol1 && rp1.aEnd.Col() == nCol2 +/*N*/ && rp2.aStart.Col() == r2.aStart.Col() +/*N*/ && rp2.aEnd.Col() == r2.aEnd.Col() ) +/*N*/ { +/*N*/ if ( rp1.aStart.Row() == nRow2+1 +/*N*/ && rp2.aStart.Row() == r2.aEnd.Row()+1 ) +/*N*/ { // oben +/*N*/ rp1.aStart.SetRow( nRow1 ); +/*N*/ rp2.aStart.SetRow( r2.aStart.Row() ); +/*N*/ bJoined = TRUE; +/*N*/ } +/*N*/ else if ( rp1.aEnd.Row() == nRow1-1 +/*N*/ && rp2.aEnd.Row() == r2.aStart.Row()-1 ) +/*N*/ { // unten +/*N*/ rp1.aEnd.SetRow( nRow2 ); +/*N*/ rp2.aEnd.SetRow( r2.aEnd.Row() ); +/*N*/ bJoined = TRUE; +/*N*/ } +/*N*/ } +/*N*/ else if ( rp1.aStart.Row() == nRow1 && rp1.aEnd.Row() == nRow2 +/*N*/ && rp2.aStart.Row() == r2.aStart.Row() +/*N*/ && rp2.aEnd.Row() == r2.aEnd.Row() ) +/*N*/ { +/*N*/ if ( rp1.aStart.Col() == nCol2+1 +/*N*/ && rp2.aStart.Col() == r2.aEnd.Col()+1 ) +/*N*/ { // links +/*N*/ rp1.aStart.SetCol( nCol1 ); +/*N*/ rp2.aStart.SetCol( r2.aStart.Col() ); +/*N*/ bJoined = TRUE; +/*N*/ } +/*N*/ else if ( rp1.aEnd.Col() == nCol1-1 +/*N*/ && rp2.aEnd.Col() == r2.aEnd.Col()-1 ) +/*N*/ { // rechts +/*N*/ rp1.aEnd.SetCol( nCol2 ); +/*N*/ rp2.aEnd.SetCol( r2.aEnd.Col() ); +/*N*/ bJoined = TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( bJoined ) +/*N*/ { +/*N*/ if ( bIsInList ) +/*N*/ { // innerhalb der Liste RangePair loeschen +/*N*/ Remove( nOldPos ); +/*N*/ delete pOver; +/*N*/ pOver = NULL; +/*N*/ if ( nOldPos ) +/*N*/ nOldPos--; // Seek richtig aufsetzen +/*N*/ } +/*N*/ bJoinedInput = TRUE; +/*N*/ Join( *p, TRUE ); // rekursiv! +/*N*/ } +/*N*/ } +/*N*/ if ( bIsInList ) +/*N*/ Seek( nOldPos ); +/*N*/ else if ( !bJoinedInput ) +/*N*/ Append( r ); +/*N*/ } + + + + +/*N*/ BOOL ScRangePairList::Store( SvStream& rStream ) const +/*N*/ { +/*N*/ BOOL bOk = TRUE; +/*N*/ ULONG nCount = Count(); +/*N*/ ULONG nBytes = sizeof(UINT32) + nCount * sizeof(ScRangePair); +/*N*/ ScWriteHeader aHdr( rStream, nBytes ); +/*N*/ rStream << (UINT32) nCount; +/*N*/ for ( ULONG j = 0; j < nCount && bOk; j++ ) +/*N*/ { +/*N*/ rStream << *GetObject( j ); +/*N*/ if( rStream.GetError() != SVSTREAM_OK ) +/*N*/ bOk = FALSE; +/*N*/ } +/*N*/ return bOk; +/*N*/ } + + +/*N*/ BOOL ScRangePairList::Load( SvStream& rStream, USHORT nVer ) +/*N*/ { +/*N*/ BOOL bOk = TRUE; +/*N*/ ScReadHeader aHdr( rStream ); +/*N*/ ScRangePair aRangePair; +/*N*/ ScRange aRange; +/*N*/ UINT32 n; +/*N*/ rStream >> n; +/*N*/ ULONG nCount = n; +/*N*/ for ( ULONG j = 0; j < nCount && bOk; j++ ) +/*N*/ { +/*N*/ if ( nVer < SC_COLROWNAME_RANGEPAIR ) +/*N*/ { // aus technical Beta 4.0 versuchen mit altem Verhalten zu uebernehmen +/*N*/ rStream >> aRange; +/*N*/ aRangePair.GetRange(0) = aRange; +/*N*/ ScRange& r = aRangePair.GetRange(1); +/*N*/ r = aRange; +/*N*/ USHORT nCol2 = aRange.aEnd.Col(); +/*N*/ USHORT nRow2 = aRange.aEnd.Row(); +/*N*/ if ( nCol2 - aRange.aStart.Col() >= nRow2 - aRange.aStart.Row() ) +/*N*/ { // ColNames +/*N*/ r.aStart.SetRow( (USHORT) Min( (ULONG)nRow2 + 1, (ULONG)MAXROW ) ); +/*N*/ r.aEnd.SetRow( MAXROW ); +/*N*/ } +/*N*/ else +/*N*/ { // RowNames +/*N*/ r.aStart.SetCol( (USHORT) Min( (ULONG)(nCol2 + 1), (ULONG)MAXCOL ) ); +/*N*/ r.aEnd.SetCol( MAXCOL ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ rStream >> aRangePair; +/*N*/ Append( aRangePair ); +/*N*/ if( rStream.GetError() != SVSTREAM_OK ) +/*N*/ bOk = FALSE; +/*N*/ } +/*N*/ return bOk; +/*N*/ } + + +/*N*/ BOOL ScRangePairList::UpdateReference( UpdateRefMode eUpdateRefMode, +/*N*/ ScDocument* pDoc, const ScRange& rWhere, +/*N*/ short nDx, short nDy, short nDz ) +/*N*/ { +/*N*/ BOOL bChanged = FALSE; +/*N*/ if ( Count() ) +/*N*/ { +/*?*/ USHORT nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; +/*?*/ rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); +/*?*/ for ( ScRangePair* pR = First(); pR; pR = Next() ) +/*?*/ { +/*?*/ for ( USHORT j=0; j<2; j++ ) +/*?*/ { +/*?*/ ScRange& rRange = pR->GetRange(j); +/*?*/ USHORT theCol1, theRow1, theTab1, theCol2, theRow2, theTab2; +/*?*/ rRange.GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 ); +/*?*/ if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, +/*?*/ nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, +/*?*/ nDx, nDy, nDz, +/*?*/ theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 ) +/*?*/ != UR_NOTHING ) +/*?*/ { +/*?*/ bChanged = TRUE; +/*?*/ rRange.aStart.Set( theCol1, theRow1, theTab1 ); +/*?*/ rRange.aEnd.Set( theCol2, theRow2, theTab2 ); +/*?*/ } +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ return bChanged; +/*N*/ } + + +/*N*/ ScRangePair* ScRangePairList::Find( const ScRange& rRange ) const +/*N*/ { +/*N*/ ULONG nCount = Count(); +/*N*/ for ( ULONG j = 0; j < nCount; j++ ) +/*N*/ { +/*N*/ ScRangePair* pR = GetObject( j ); +/*N*/ if ( pR->GetRange(0) == rRange ) +/*N*/ return pR; +/*N*/ } +/*N*/ return NULL; +/*N*/ } + + +/*N*/ ScRangePairList* ScRangePairList::Clone() const +/*N*/ { +/*N*/ ScRangePairList* pNew = new ScRangePairList; +/*N*/ ULONG nCount = Count(); +/*N*/ for ( ULONG j = 0; j < nCount; j++ ) +/*N*/ { +/*N*/ pNew->Append( *GetObject( j ) ); +/*N*/ } +/*N*/ return pNew; +/*N*/ } + + +struct ScRangePairNameSort +{ + ScRangePair* pPair; + ScDocument* pDoc; +}; + + + + + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_rangenam.cxx b/binfilter/bf_sc/source/core/tool/sc_rangenam.cxx new file mode 100644 index 000000000000..ee8426d0661f --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_rangenam.cxx @@ -0,0 +1,578 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +//------------------------------------------------------------------------ + +#include <tools/debug.hxx> +#include <string.h> +#include <unotools/collatorwrapper.hxx> +#include <unotools/transliterationwrapper.hxx> + +#include "rangenam.hxx" +#include "compiler.hxx" +#include "rechead.hxx" +#include "document.hxx" +namespace binfilter { + + +//======================================================================== +// ScRangeData +//======================================================================== + +// Interner ctor fuer das Suchen nach einem Index + +/*N*/ ScRangeData::ScRangeData( USHORT n ) +/*N*/ : nIndex( n ), pCode( NULL ), bModified( FALSE ) +/*N*/ {} + +/*N*/ ScRangeData::ScRangeData( ScDocument* pDok, +/*N*/ const String& rName, +/*N*/ const String& rSymbol, +/*N*/ const ScAddress& rAddress, +/*N*/ RangeType nType, +/*N*/ BOOL bEnglish ) : +/*N*/ aName ( rName ), +/*N*/ aPos ( rAddress ), +/*N*/ eType ( nType ), +/*N*/ pDoc ( pDok ), +/*N*/ nIndex ( 0 ), +/*N*/ nExportIndex( 0 ), +/*N*/ pCode ( NULL ), +/*N*/ bModified ( FALSE ) +/*N*/ { +/*N*/ if (rSymbol.Len() > 0) +/*N*/ { +/*N*/ ScCompiler aComp( pDoc, aPos ); +/*N*/ aComp.SetCompileEnglish(bEnglish); +/*N*/ pCode = aComp.CompileString( rSymbol ); +/*N*/ if( !pCode->GetError() ) +/*N*/ { +/*N*/ pCode->Reset(); +/*N*/ ScToken* p = pCode->GetNextReference(); +/*N*/ if( p )// genau eine Referenz als erstes +/*N*/ { +/*N*/ if( p->GetType() == svSingleRef ) +/*N*/ eType = eType | RT_ABSPOS; +/*N*/ else +/*N*/ eType = eType | RT_ABSAREA; +/*N*/ } +/*N*/ // ggf. den Fehlercode wg. unvollstaendiger Formel setzen! +/*N*/ // Dies ist fuer die manuelle Eingabe +/*N*/ aComp.CompileTokenArray(); +/*N*/ pCode->DelRPN(); +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ ScRangeData::ScRangeData(const ScRangeData& rScRangeData) : +/*N*/ aName (rScRangeData.aName), +/*N*/ aPos (rScRangeData.aPos), +/*N*/ eType (rScRangeData.eType), +/*N*/ pDoc (rScRangeData.pDoc), +/*N*/ nIndex (rScRangeData.nIndex), +/*N*/ pCode (rScRangeData.pCode ? rScRangeData.pCode->Clone() : new ScTokenArray), // echte Kopie erzeugen (nicht copy-ctor) +/*N*/ bModified (rScRangeData.bModified) +/*N*/ {} + +/*N*/ ScRangeData::~ScRangeData() +/*N*/ { +/*N*/ delete pCode; +/*N*/ } + +/*N*/ DataObject* ScRangeData::Clone() const +/*N*/ { +/*N*/ return new ScRangeData(*this); +/*N*/ } + +/*N*/ ScRangeData::ScRangeData +/*N*/ ( SvStream& rStream, ScMultipleReadHeader& rHdr, USHORT nVer ) +/*N*/ : pCode ( new ScTokenArray ), +/*N*/ bModified (FALSE) +/*N*/ +/*N*/ { +/*N*/ rHdr.StartEntry(); +/*N*/ +/*N*/ if( nVer >= SC_NEW_TOKEN_ARRAYS ) +/*N*/ { +/*N*/ UINT32 nPos; +/*N*/ BYTE nData; +/*N*/ rStream.ReadByteString( aName, rStream.GetStreamCharSet() ); +/*N*/ rStream >> nPos >> eType >> nIndex >> nData; +/*N*/ if( nData & 0x0F ) +/*?*/ rStream.SeekRel( nData & 0x0F ); +/*N*/ aPos = ScAddress( nPos ); +/*N*/ pCode->Load( rStream, nVer, aPos ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ UINT16 nTokLen, r, c, t; +/*N*/ rStream.ReadByteString( aName, rStream.GetStreamCharSet() ); +/*N*/ rStream >> c >> r >> t >> eType >> nIndex >> nTokLen; +/*N*/ aPos.Set( c, r, t ); +/*N*/ if( nTokLen ) +/*N*/ pCode->Load30( rStream, aPos ); +/*N*/ } +/*N*/ +/*N*/ rHdr.EndEntry(); +/*N*/ } + +/*N*/ BOOL ScRangeData::Store +/*N*/ ( SvStream& rStream, ScMultipleWriteHeader& rHdr ) const +/*N*/ { +/*N*/ rHdr.StartEntry(); +/*N*/ +/*N*/ rStream.WriteByteString( aName, rStream.GetStreamCharSet() ); +/*N*/ rStream << (UINT32) aPos << eType << nIndex << (BYTE) 0x00; +/*N*/ pCode->Store( rStream, aPos ); +/*N*/ +/*N*/ rHdr.EndEntry(); +/*N*/ return TRUE; +/*N*/ } + +/*N*/ BOOL ScRangeData::IsBeyond( USHORT nMaxRow ) const +/*N*/ { +/*N*/ if ( aPos.Row() > nMaxRow ) +/*N*/ return TRUE; +/*N*/ +/*N*/ ScToken* t; +/*N*/ pCode->Reset(); +/*N*/ while ( t = pCode->GetNextReference() ) +/*N*/ if ( t->GetSingleRef().nRow > nMaxRow || +/*N*/ (t->GetType() == svDoubleRef && +/*N*/ t->GetDoubleRef().Ref2.nRow > nMaxRow) ) +/*N*/ return TRUE; +/*N*/ +/*N*/ return FALSE; +/*N*/ } + + +/*N*/ void ScRangeData::GetSymbol (String& rSymbol) const +/*N*/ { +/*N*/ ScCompiler aScComp(pDoc, aPos, *pCode); +/*N*/ aScComp.CreateStringFromTokenArray( rSymbol ); +/*N*/ } + +/*N*/ void ScRangeData::GetEnglishSymbol (String& rSymbol, BOOL bCompileXML) const +/*N*/ { +/*N*/ ScCompiler aScComp(pDoc, aPos, *pCode); +/*N*/ aScComp.SetCompileEnglish( TRUE ); +/*N*/ aScComp.SetCompileXML( bCompileXML ); +/*N*/ aScComp.CreateStringFromTokenArray( rSymbol ); +/*N*/ } + +/*N*/ void ScRangeData::UpdateSymbol( String& rSymbol, const ScAddress& rPos, +/*N*/ BOOL bEnglish, BOOL bCompileXML ) +/*N*/ { +/*N*/ ScTokenArray* pTemp = pCode->Clone(); +/*N*/ ScCompiler aComp( pDoc, rPos, *pTemp ); +/*N*/ aComp.SetCompileEnglish( bEnglish ); +/*N*/ aComp.SetCompileXML( bCompileXML ); +/*N*/ aComp.MoveRelWrap(); +/*N*/ aComp.CreateStringFromTokenArray( rSymbol ); +/*N*/ delete pTemp; +/*N*/ } + +/*N*/ void ScRangeData::UpdateSymbol( ::rtl::OUStringBuffer& rBuffer, const ScAddress& rPos, +/*N*/ BOOL bEnglish, BOOL bCompileXML ) +/*N*/ { +/*N*/ ScTokenArray* pTemp = pCode->Clone(); +/*N*/ ScCompiler aComp( pDoc, rPos, *pTemp ); +/*N*/ aComp.SetCompileEnglish( bEnglish ); +/*N*/ aComp.SetCompileXML( bCompileXML ); +/*N*/ aComp.MoveRelWrap(); +/*N*/ aComp.CreateStringFromTokenArray( rBuffer ); +/*N*/ delete pTemp; +/*N*/ } + +/*N*/ void ScRangeData::UpdateReference( UpdateRefMode eUpdateRefMode, +/*N*/ const ScRange& r, +/*N*/ short nDx, short nDy, short nDz ) +/*N*/ { +/*N*/ BOOL bChanged = FALSE; +/*N*/ +/*N*/ pCode->Reset(); +/*N*/ if( pCode->GetNextReference() ) +/*N*/ { +/*N*/ ScCompiler aComp( pDoc, aPos, *pCode ); +/*N*/ BOOL bRelRef = aComp.UpdateNameReference( eUpdateRefMode, r, +/*N*/ nDx, nDy, nDz, +/*N*/ bChanged); +/*N*/ if (eType&RT_SHARED) +/*N*/ { +/*N*/ if (bRelRef) +/*N*/ eType = eType | RT_SHAREDMOD; +/*N*/ else +/*N*/ eType = eType & ~RT_SHAREDMOD; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ bModified = bChanged; +/*N*/ } + + + + + + + +/*N*/ BOOL ScRangeData::IsReference( ScRange& rRange ) const +/*N*/ { +/*N*/ BOOL bIs = FALSE; +/*N*/ if ( eType & ( RT_ABSAREA | RT_REFAREA | RT_ABSPOS ) ) +/*N*/ if ( pCode ) +/*N*/ return pCode->IsReference( rRange ); +/*N*/ +/*N*/ return bIs; +/*N*/ } + + +// wie beim Uebernehmen von Namen in Excel + +/*N*/ void ScRangeData::MakeValidName( String& rName ) // static +/*N*/ { +/*N*/ if (!ScCompiler::HasCharTable()) +/*N*/ ScCompiler::Init(); +/*N*/ +/*N*/ // ungueltige Zeichen vorne weglassen +/*N*/ xub_StrLen nPos = 0; +/*N*/ xub_StrLen nLen = rName.Len(); +/*N*/ while ( nPos < nLen && !ScCompiler::IsWordChar( rName.GetChar(nPos) ) ) +/*N*/ ++nPos; +/*N*/ if ( nPos>0 ) +/*N*/ rName.Erase(0,nPos); +/*N*/ +/*N*/ // wenn vorne ein ungueltiges Anfangszeichen steht, '_' davor +/*N*/ if ( rName.Len() && !ScCompiler::IsCharWordChar( rName.GetChar(0) ) ) +/*N*/ rName.Insert('_',0); +/*N*/ +/*N*/ // ungueltige durch '_' ersetzen +/*N*/ nLen = rName.Len(); +/*N*/ for (nPos=0; nPos<nLen; nPos++) +/*N*/ { +/*N*/ if ( !ScCompiler::IsWordChar( rName.GetChar(nPos) ) ) +/*N*/ rName.SetChar( nPos, '_' ); +/*N*/ } +/*N*/ +/*N*/ // Name darf keine Referenz beinhalten, wie in IsNameValid +/*N*/ BOOL bOk; +/*N*/ do +/*N*/ { +/*N*/ bOk = TRUE; +/*N*/ ScRange aRange; +/*N*/ if( aRange.Parse( rName, NULL ) ) +/*N*/ bOk = FALSE; +/*N*/ else +/*N*/ { +/*N*/ ScAddress aAddr; +/*N*/ if ( aAddr.Parse( rName, NULL ) ) +/*N*/ bOk = FALSE; +/*N*/ } +/*N*/ if ( !bOk ) +/*N*/ { //! Range Parse auch bei Bereich mit ungueltigem Tabellennamen gueltig +/*N*/ //! Address Parse dito, Name erzeugt deswegen bei Compile ein #REF! +/*N*/ if ( rName.SearchAndReplace( ':', '_' ) == STRING_NOTFOUND +/*N*/ && rName.SearchAndReplace( '.', '_' ) == STRING_NOTFOUND ) +/*N*/ rName.Insert('_',0); +/*N*/ } +/*N*/ } while ( !bOk ); +/*N*/ } + + + +/*N*/ USHORT ScRangeData::GetErrCode() +/*N*/ { +/*N*/ return pCode ? pCode->GetError() : 0; +/*N*/ } + +/*N*/ BOOL ScRangeData::HasReferences() const +/*N*/ { +/*N*/ pCode->Reset(); +/*N*/ return BOOL( pCode->GetNextReference() != NULL ); +/*N*/ } + +// bei TransferTab von einem in ein anderes Dokument anpassen, +// um Referenzen auf die eigene Tabelle mitzubekommen + + + +/*N*/ void ScRangeData::ReplaceRangeNamesInUse( const ScIndexMap& rMap ) +/*N*/ { +/*N*/ BOOL bCompile = FALSE; +/*N*/ for ( ScToken* p = pCode->First(); p; p = pCode->Next() ) +/*N*/ { +/*N*/ if ( p->GetOpCode() == ocName ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 USHORT nIndex = p->GetIndex(); +/*N*/ } +/*N*/ } +/*N*/ if ( bCompile ) +/*N*/ { +/*N*/ ScCompiler aComp( pDoc, aPos, *pCode ); +/*N*/ aComp.CompileTokenArray(); +/*N*/ } +/*N*/ } + + +/*N*/ void ScRangeData::ValidateTabRefs() +/*N*/ { +/*N*/ // try to make sure all relative references and the reference position +/*N*/ // are within existing tables, so they can be represented as text +/*N*/ // (if the range of used tables is more than the existing tables, +/*N*/ // the result may still contain invalid tables, because the relative +/*N*/ // references aren't changed so formulas stay the same) +/*N*/ +/*N*/ // find range of used tables +/*N*/ +/*N*/ USHORT nMinTab = aPos.Tab(); +/*N*/ USHORT nMaxTab = nMinTab; +/*N*/ ScToken* t; +/*N*/ pCode->Reset(); +/*N*/ while ( t = pCode->GetNextReference() ) +/*N*/ { +/*N*/ SingleRefData& rRef1 = t->GetSingleRef(); +/*N*/ if ( rRef1.IsTabRel() && !rRef1.IsTabDeleted() ) +/*N*/ { +/*N*/ if ( rRef1.nTab < nMinTab ) +/*N*/ nMinTab = rRef1.nTab; +/*N*/ if ( rRef1.nTab > nMaxTab ) +/*N*/ nMaxTab = rRef1.nTab; +/*N*/ } +/*N*/ if ( t->GetType() == svDoubleRef ) +/*N*/ { +/*N*/ SingleRefData& rRef2 = t->GetDoubleRef().Ref2; +/*N*/ if ( rRef2.IsTabRel() && !rRef2.IsTabDeleted() ) +/*N*/ { +/*?*/ if ( rRef2.nTab < nMinTab ) +/*?*/ nMinTab = rRef2.nTab; +/*?*/ if ( rRef2.nTab > nMaxTab ) +/*?*/ nMaxTab = rRef2.nTab; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ USHORT nTabCount = pDoc->GetTableCount(); +/*N*/ if ( nMaxTab >= nTabCount && nMinTab > 0 ) +/*N*/ { +/*?*/ // move position and relative tab refs +/*?*/ // The formulas that use the name are not changed by this +/*?*/ +/*?*/ USHORT nMove = nMinTab; +/*?*/ aPos.SetTab( aPos.Tab() - nMove ); +/*?*/ +/*?*/ pCode->Reset(); +/*?*/ while ( t = pCode->GetNextReference() ) +/*?*/ { +/*?*/ SingleRefData& rRef1 = t->GetSingleRef(); +/*?*/ if ( rRef1.IsTabRel() && !rRef1.IsTabDeleted() ) +/*?*/ rRef1.nTab -= nMove; +/*?*/ if ( t->GetType() == svDoubleRef ) +/*?*/ { +/*?*/ SingleRefData& rRef2 = t->GetDoubleRef().Ref2; +/*?*/ if ( rRef2.IsTabRel() && !rRef2.IsTabDeleted() ) +/*?*/ rRef2.nTab -= nMove; +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ } + + +/*N*/ int +/*N*/ #ifdef WNT +/*N*/ __cdecl +/*N*/ #endif +/*N*/ ScRangeData::QsortNameCompare( const void* p1, const void* p2 ) +/*N*/ { +/*N*/ return (int) ScGlobal::pCollator->compareString( +/*N*/ (*(const ScRangeData**)p1)->aName, +/*N*/ (*(const ScRangeData**)p2)->aName ); +/*N*/ } + + +//======================================================================== +// ScRangeName +//======================================================================== + +/*N*/ ScRangeName::ScRangeName(const ScRangeName& rScRangeName, ScDocument* pDocument) : +/*N*/ SortedCollection ( rScRangeName ), +/*N*/ pDoc ( pDocument ), +/*N*/ nSharedMaxIndex (rScRangeName.nSharedMaxIndex) +/*N*/ { +/*N*/ for (USHORT i = 0; i < nCount; i++) +/*N*/ { +/*N*/ ((ScRangeData*)At(i))->SetDocument(pDocument); +/*N*/ ((ScRangeData*)At(i))->SetIndex(((ScRangeData*)rScRangeName.At(i))->GetIndex()); +/*N*/ } +/*N*/ } + +/*N*/ short ScRangeName::Compare(DataObject* pKey1, DataObject* pKey2) const +/*N*/ { +/*N*/ USHORT i1 = ((ScRangeData*)pKey1)->GetIndex(); +/*N*/ USHORT i2 = ((ScRangeData*)pKey2)->GetIndex(); +/*N*/ return (short) i1 - (short) i2; +/*N*/ } + +/*N*/ BOOL ScRangeName::SearchName( const String& rName, USHORT& rIndex ) const +/*N*/ { +/*N*/ USHORT i = 0; +/*N*/ while (i < nCount) +/*N*/ { +/*N*/ String aName; +/*N*/ ((*this)[i])->GetName( aName ); +/*N*/ if ( ScGlobal::pTransliteration->isEqual( aName, rName ) ) +/*N*/ { +/*N*/ rIndex = i; +/*N*/ return TRUE; +/*N*/ } +/*N*/ i++; +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/*N*/ BOOL ScRangeName::Load( SvStream& rStream, USHORT nVer ) +/*N*/ { +/*N*/ BOOL bSuccess = TRUE; +/*N*/ USHORT nNewCount; +/*N*/ +/*N*/ while( nCount > 0 ) +/*?*/ AtFree(0); // alles loeschen +/*N*/ +/*N*/ ScMultipleReadHeader aHdr( rStream ); +/*N*/ +/*N*/ USHORT nDummy; +/*N*/ if( nVer >= SC_NEW_TOKEN_ARRAYS ) +/*N*/ rStream >> nSharedMaxIndex >> nNewCount; +/*N*/ else +/*N*/ rStream >> nSharedMaxIndex >> nDummy >> nNewCount; +/*N*/ for (USHORT i=0; i<nNewCount && bSuccess; i++) +/*N*/ { +/*N*/ ScRangeData* pData = new ScRangeData( rStream, aHdr, nVer ); +/*N*/ pData->SetDocument(pDoc); +/*N*/ Insert( pData ); +/*N*/ if( rStream.GetError() != SVSTREAM_OK ) +/*N*/ bSuccess = FALSE; +/*N*/ } +/*N*/ return bSuccess; +/*N*/ } + +/*N*/ BOOL ScRangeName::Store( SvStream& rStream ) const +/*N*/ { +/*N*/ ScMultipleWriteHeader aHdr( rStream ); +/*N*/ +/*N*/ USHORT i; +/*N*/ USHORT nSaveCount = nCount; +/*N*/ USHORT nSaveMaxRow = pDoc->GetSrcMaxRow(); +/*N*/ if ( nSaveMaxRow < MAXROW ) +/*N*/ { +/*N*/ nSaveCount = 0; +/*N*/ for (i=0; i<nCount; i++) +/*N*/ if ( !((const ScRangeData*)At(i))->IsBeyond(nSaveMaxRow) ) +/*N*/ ++nSaveCount; +/*N*/ +/*N*/ if ( nSaveCount < nCount ) +/*?*/ pDoc->SetLostData(); // Warnung ausgeben +/*N*/ } +/*N*/ +/*N*/ rStream << nSharedMaxIndex << nSaveCount; +/*N*/ BOOL bSuccess = TRUE; +/*N*/ +/*N*/ for (i=0; i<nCount && bSuccess; i++) +/*N*/ { +/*N*/ const ScRangeData* pRangeData = (const ScRangeData*)At(i); +/*N*/ if ( nSaveMaxRow == MAXROW || !pRangeData->IsBeyond(nSaveMaxRow) ) +/*N*/ bSuccess = pRangeData->Store( rStream, aHdr ); +/*N*/ } +/*N*/ +/*N*/ return bSuccess; +/*N*/ } + +/*N*/ void ScRangeName::UpdateReference( UpdateRefMode eUpdateRefMode, +/*N*/ const ScRange& rRange, +/*N*/ short nDx, short nDy, short nDz ) +/*N*/ { +/*N*/ for (USHORT i=0; i<nCount; i++) +/*N*/ ((ScRangeData*)pItems[i])->UpdateReference(eUpdateRefMode, rRange, +/*N*/ nDx, nDy, nDz); +/*N*/ } + + + + +/*N*/ BOOL ScRangeName::Insert(DataObject* pDataObject) +/*N*/ { +/*N*/ if (!((ScRangeData*)pDataObject)->GetIndex()) // schon gesetzt? +/*N*/ { +/*N*/ ((ScRangeData*)pDataObject)->SetIndex( GetEntryIndex() ); +/*N*/ } +/*N*/ +/*N*/ return SortedCollection::Insert(pDataObject); +/*N*/ } + +// Suche nach einem freien Index + +/*N*/ USHORT ScRangeName::GetEntryIndex() +/*N*/ { +/*N*/ USHORT nLast = 0; +/*N*/ for ( USHORT i = 0; i < nCount; i++ ) +/*N*/ { +/*N*/ USHORT nIdx = ((ScRangeData*)pItems[i])->GetIndex(); +/*N*/ if( nIdx > nLast ) +/*N*/ { +/*N*/ nLast = nIdx; +/*N*/ } +/*N*/ } +/*N*/ return nLast + 1; +/*N*/ } + +/*N*/ ScRangeData* ScRangeName::FindIndex( USHORT nIndex ) +/*N*/ { +/*N*/ ScRangeData aDataObj( nIndex ); +/*N*/ USHORT n; +/*N*/ if( Search( &aDataObj, n ) ) +/*N*/ return (*this)[ n ]; +/*N*/ else +/*N*/ return NULL; +/*N*/ } + + + +/*N*/ void ScRangeName::UpdateTabRef(USHORT nOldTable, USHORT nFlag, USHORT nNewTable) +/*N*/ { +/*N*/ for (USHORT i=0; i<nCount; i++) +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 ((ScRangeData*)pItems[i])->UpdateTabRef(nOldTable, nFlag, nNewTable); +/*N*/ } + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_rangeseq.cxx b/binfilter/bf_sc/source/core/tool/sc_rangeseq.cxx new file mode 100644 index 000000000000..32eb2c18f305 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_rangeseq.cxx @@ -0,0 +1,342 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <bf_svtools/zforlist.hxx> +#include <rtl/math.hxx> +#include <tools/debug.hxx> + + +#include "rangeseq.hxx" +#include "document.hxx" +#include "scmatrix.hxx" +#include "cell.hxx" +namespace binfilter { + +using namespace ::com::sun::star; + +//------------------------------------------------------------------------ + +/*N*/ long lcl_DoubleToLong( double fVal ) +/*N*/ { +/*N*/ double fInt = (fVal >= 0.0) ? ::rtl::math::approxFloor( fVal ) : +/*N*/ ::rtl::math::approxCeil( fVal ); +/*N*/ if ( fInt >= LONG_MIN && fInt <= LONG_MAX ) +/*N*/ return (long)fInt; +/*N*/ else +/*N*/ return 0; // out of range +/*N*/ } + +/*N*/ BOOL ScRangeToSequence::FillLongArray( uno::Any& rAny, ScDocument* pDoc, const ScRange& rRange ) +/*N*/ { +/*N*/ USHORT nTab = rRange.aStart.Tab(); +/*N*/ USHORT nStartCol = rRange.aStart.Col(); +/*N*/ USHORT nStartRow = rRange.aStart.Row(); +/*N*/ long nColCount = rRange.aEnd.Col() + 1 - rRange.aStart.Col(); +/*N*/ long nRowCount = rRange.aEnd.Row() + 1 - rRange.aStart.Row(); +/*N*/ +/*N*/ uno::Sequence< uno::Sequence<INT32> > aRowSeq( nRowCount ); +/*N*/ uno::Sequence<INT32>* pRowAry = aRowSeq.getArray(); +/*N*/ for (long nRow = 0; nRow < nRowCount; nRow++) +/*N*/ { +/*N*/ uno::Sequence<INT32> aColSeq( nColCount ); +/*N*/ INT32* pColAry = aColSeq.getArray(); +/*N*/ for (long nCol = 0; nCol < nColCount; nCol++) +/*N*/ pColAry[nCol] = lcl_DoubleToLong( pDoc->GetValue( +/*N*/ ScAddress( (USHORT)(nStartCol+nCol), (USHORT)(nStartRow+nRow), nTab ) ) ); +/*N*/ +/*N*/ pRowAry[nRow] = aColSeq; +/*N*/ } +/*N*/ +/*N*/ rAny <<= aRowSeq; +/*N*/ return TRUE; //! check for errors +/*N*/ } + + +/*N*/ BOOL ScRangeToSequence::FillLongArray( uno::Any& rAny, const ScMatrix* pMatrix ) +/*N*/ { +/*N*/ if (!pMatrix) +/*N*/ return FALSE; +/*N*/ +/*N*/ USHORT nColCount, nRowCount; +/*N*/ pMatrix->GetDimensions( nColCount, nRowCount ); +/*N*/ +/*N*/ uno::Sequence< uno::Sequence<INT32> > aRowSeq( nRowCount ); +/*N*/ uno::Sequence<INT32>* pRowAry = aRowSeq.getArray(); +/*N*/ for (USHORT nRow = 0; nRow < nRowCount; nRow++) +/*N*/ { +/*N*/ uno::Sequence<INT32> aColSeq( nColCount ); +/*N*/ INT32* pColAry = aColSeq.getArray(); +/*N*/ for (USHORT nCol = 0; nCol < nColCount; nCol++) +/*N*/ if ( pMatrix->IsString( nCol, nRow ) ) +/*N*/ pColAry[nCol] = 0; +/*N*/ else +/*N*/ pColAry[nCol] = lcl_DoubleToLong( pMatrix->GetDouble( nCol, nRow ) ); +/*N*/ +/*N*/ pRowAry[nRow] = aColSeq; +/*N*/ } +/*N*/ +/*N*/ rAny <<= aRowSeq; +/*N*/ return TRUE; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ BOOL ScRangeToSequence::FillDoubleArray( uno::Any& rAny, ScDocument* pDoc, const ScRange& rRange ) +/*N*/ { +/*N*/ USHORT nTab = rRange.aStart.Tab(); +/*N*/ USHORT nStartCol = rRange.aStart.Col(); +/*N*/ USHORT nStartRow = rRange.aStart.Row(); +/*N*/ long nColCount = rRange.aEnd.Col() + 1 - rRange.aStart.Col(); +/*N*/ long nRowCount = rRange.aEnd.Row() + 1 - rRange.aStart.Row(); +/*N*/ +/*N*/ uno::Sequence< uno::Sequence<double> > aRowSeq( nRowCount ); +/*N*/ uno::Sequence<double>* pRowAry = aRowSeq.getArray(); +/*N*/ for (long nRow = 0; nRow < nRowCount; nRow++) +/*N*/ { +/*N*/ uno::Sequence<double> aColSeq( nColCount ); +/*N*/ double* pColAry = aColSeq.getArray(); +/*N*/ for (long nCol = 0; nCol < nColCount; nCol++) +/*N*/ pColAry[nCol] = pDoc->GetValue( +/*N*/ ScAddress( (USHORT)(nStartCol+nCol), (USHORT)(nStartRow+nRow), nTab ) ); +/*N*/ +/*N*/ pRowAry[nRow] = aColSeq; +/*N*/ } +/*N*/ +/*N*/ rAny <<= aRowSeq; +/*N*/ return TRUE; //! check for errors +/*N*/ } + + +/*N*/ BOOL ScRangeToSequence::FillDoubleArray( uno::Any& rAny, const ScMatrix* pMatrix ) +/*N*/ { +/*N*/ if (!pMatrix) +/*N*/ return FALSE; +/*N*/ +/*N*/ USHORT nColCount, nRowCount; +/*N*/ pMatrix->GetDimensions( nColCount, nRowCount ); +/*N*/ +/*N*/ uno::Sequence< uno::Sequence<double> > aRowSeq( nRowCount ); +/*N*/ uno::Sequence<double>* pRowAry = aRowSeq.getArray(); +/*N*/ for (USHORT nRow = 0; nRow < nRowCount; nRow++) +/*N*/ { +/*N*/ uno::Sequence<double> aColSeq( nColCount ); +/*N*/ double* pColAry = aColSeq.getArray(); +/*N*/ for (USHORT nCol = 0; nCol < nColCount; nCol++) +/*N*/ if ( pMatrix->IsString( nCol, nRow ) ) +/*N*/ pColAry[nCol] = 0.0; +/*N*/ else +/*N*/ pColAry[nCol] = pMatrix->GetDouble( nCol, nRow ); +/*N*/ +/*N*/ pRowAry[nRow] = aColSeq; +/*N*/ } +/*N*/ +/*N*/ rAny <<= aRowSeq; +/*N*/ return TRUE; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ BOOL ScRangeToSequence::FillStringArray( uno::Any& rAny, ScDocument* pDoc, const ScRange& rRange ) +/*N*/ { +/*N*/ USHORT nTab = rRange.aStart.Tab(); +/*N*/ USHORT nStartCol = rRange.aStart.Col(); +/*N*/ USHORT nStartRow = rRange.aStart.Row(); +/*N*/ long nColCount = rRange.aEnd.Col() + 1 - rRange.aStart.Col(); +/*N*/ long nRowCount = rRange.aEnd.Row() + 1 - rRange.aStart.Row(); +/*N*/ +/*N*/ String aDocStr; +/*N*/ +/*N*/ uno::Sequence< uno::Sequence<rtl::OUString> > aRowSeq( nRowCount ); +/*N*/ uno::Sequence<rtl::OUString>* pRowAry = aRowSeq.getArray(); +/*N*/ for (long nRow = 0; nRow < nRowCount; nRow++) +/*N*/ { +/*N*/ uno::Sequence<rtl::OUString> aColSeq( nColCount ); +/*N*/ ::rtl::OUString* pColAry = aColSeq.getArray(); +/*N*/ for (long nCol = 0; nCol < nColCount; nCol++) +/*N*/ { +/*N*/ pDoc->GetString( (USHORT)(nStartCol+nCol), (USHORT)(nStartRow+nRow), nTab, aDocStr ); +/*N*/ pColAry[nCol] = ::rtl::OUString( aDocStr ); +/*N*/ } +/*N*/ pRowAry[nRow] = aColSeq; +/*N*/ } +/*N*/ +/*N*/ rAny <<= aRowSeq; +/*N*/ return TRUE; //! check for errors +/*N*/ } + + +/*N*/ BOOL ScRangeToSequence::FillStringArray( uno::Any& rAny, const ScMatrix* pMatrix, +/*N*/ SvNumberFormatter* pFormatter ) +/*N*/ { +/*N*/ if (!pMatrix) +/*N*/ return FALSE; +/*N*/ +/*N*/ USHORT nColCount, nRowCount; +/*N*/ pMatrix->GetDimensions( nColCount, nRowCount ); +/*N*/ +/*N*/ uno::Sequence< uno::Sequence<rtl::OUString> > aRowSeq( nRowCount ); +/*N*/ uno::Sequence<rtl::OUString>* pRowAry = aRowSeq.getArray(); +/*N*/ for (USHORT nRow = 0; nRow < nRowCount; nRow++) +/*N*/ { +/*N*/ uno::Sequence<rtl::OUString> aColSeq( nColCount ); +/*N*/ ::rtl::OUString* pColAry = aColSeq.getArray(); +/*N*/ for (USHORT nCol = 0; nCol < nColCount; nCol++) +/*N*/ { +/*N*/ String aStr; +/*N*/ if ( pMatrix->IsString( nCol, nRow ) ) +/*N*/ { +/*N*/ if ( !pMatrix->IsEmpty( nCol, nRow ) ) +/*N*/ aStr = pMatrix->GetString( nCol, nRow ); +/*N*/ } +/*N*/ else if ( pFormatter ) +/*N*/ { +/*N*/ double fVal = pMatrix->GetDouble( nCol, nRow ); +/*N*/ Color* pColor; +/*N*/ pFormatter->GetOutputString( fVal, 0, aStr, &pColor ); +/*N*/ } +/*N*/ pColAry[nCol] = ::rtl::OUString( aStr ); +/*N*/ } +/*N*/ +/*N*/ pRowAry[nRow] = aColSeq; +/*N*/ } +/*N*/ +/*N*/ rAny <<= aRowSeq; +/*N*/ return TRUE; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ double lcl_GetValueFromCell( ScBaseCell& rCell ) +/*N*/ { +/*N*/ //! ScBaseCell member function? +/*N*/ +/*N*/ CellType eType = rCell.GetCellType(); +/*N*/ if ( eType == CELLTYPE_VALUE ) +/*N*/ return ((ScValueCell&)rCell).GetValue(); +/*N*/ else if ( eType == CELLTYPE_FORMULA ) +/*N*/ return ((ScFormulaCell&)rCell).GetValue(); // called only if result is value +/*N*/ +/*N*/ DBG_ERROR( "GetValueFromCell: wrong type" ); +/*N*/ return 0; +/*N*/ } + +/*N*/ BOOL ScRangeToSequence::FillMixedArray( uno::Any& rAny, ScDocument* pDoc, const ScRange& rRange, +/*N*/ BOOL bAllowNV ) +/*N*/ { +/*N*/ USHORT nTab = rRange.aStart.Tab(); +/*N*/ USHORT nStartCol = rRange.aStart.Col(); +/*N*/ USHORT nStartRow = rRange.aStart.Row(); +/*N*/ long nColCount = rRange.aEnd.Col() + 1 - rRange.aStart.Col(); +/*N*/ long nRowCount = rRange.aEnd.Row() + 1 - rRange.aStart.Row(); +/*N*/ +/*N*/ String aDocStr; +/*N*/ BOOL bHasErrors = FALSE; +/*N*/ +/*N*/ uno::Sequence< uno::Sequence<uno::Any> > aRowSeq( nRowCount ); +/*N*/ uno::Sequence<uno::Any>* pRowAry = aRowSeq.getArray(); +/*N*/ for (long nRow = 0; nRow < nRowCount; nRow++) +/*N*/ { +/*N*/ uno::Sequence<uno::Any> aColSeq( nColCount ); +/*N*/ uno::Any* pColAry = aColSeq.getArray(); +/*N*/ for (long nCol = 0; nCol < nColCount; nCol++) +/*N*/ { +/*N*/ uno::Any& rElement = pColAry[nCol]; +/*N*/ +/*N*/ ScAddress aPos( (USHORT)(nStartCol+nCol), (USHORT)(nStartRow+nRow), nTab ); +/*N*/ ScBaseCell* pCell = pDoc->GetCell( aPos ); +/*N*/ if ( pCell ) +/*N*/ { +/*N*/ if ( pCell->GetCellType() == CELLTYPE_FORMULA && +/*N*/ ((ScFormulaCell*)pCell)->GetErrCode() != 0 ) +/*N*/ { +/*N*/ // if NV is allowed, leave empty for errors +/*N*/ bHasErrors = TRUE; +/*N*/ } +/*N*/ else if ( pCell->HasValueData() ) +/*N*/ rElement <<= (double) lcl_GetValueFromCell( *pCell ); +/*N*/ else +/*N*/ rElement <<= ::rtl::OUString( pCell->GetStringData() ); +/*N*/ } +/*N*/ else +/*N*/ rElement <<= ::rtl::OUString(); // empty: empty string +/*N*/ } +/*N*/ pRowAry[nRow] = aColSeq; +/*N*/ } +/*N*/ +/*N*/ rAny <<= aRowSeq; +/*N*/ return bAllowNV || !bHasErrors; +/*N*/ } + + +/*N*/ BOOL ScRangeToSequence::FillMixedArray( uno::Any& rAny, const ScMatrix* pMatrix ) +/*N*/ { +/*N*/ if (!pMatrix) +/*N*/ return FALSE; +/*N*/ +/*N*/ USHORT nColCount, nRowCount; +/*N*/ pMatrix->GetDimensions( nColCount, nRowCount ); +/*N*/ +/*N*/ uno::Sequence< uno::Sequence<uno::Any> > aRowSeq( nRowCount ); +/*N*/ uno::Sequence<uno::Any>* pRowAry = aRowSeq.getArray(); +/*N*/ for (USHORT nRow = 0; nRow < nRowCount; nRow++) +/*N*/ { +/*N*/ uno::Sequence<uno::Any> aColSeq( nColCount ); +/*N*/ uno::Any* pColAry = aColSeq.getArray(); +/*N*/ for (USHORT nCol = 0; nCol < nColCount; nCol++) +/*N*/ { +/*N*/ if ( pMatrix->IsString( nCol, nRow ) ) +/*N*/ { +/*N*/ String aStr; +/*N*/ if ( !pMatrix->IsEmpty( nCol, nRow ) ) +/*N*/ aStr = pMatrix->GetString( nCol, nRow ); +/*N*/ pColAry[nCol] <<= ::rtl::OUString( aStr ); +/*N*/ } +/*N*/ else +/*N*/ pColAry[nCol] <<= (double) pMatrix->GetDouble( nCol, nRow ); +/*N*/ } +/*N*/ +/*N*/ pRowAry[nRow] = aColSeq; +/*N*/ } +/*N*/ +/*N*/ rAny <<= aRowSeq; +/*N*/ return TRUE; +/*N*/ } + + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_rangeutl.cxx b/binfilter/bf_sc/source/core/tool/sc_rangeutl.cxx new file mode 100644 index 000000000000..cdd96ca1dd25 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_rangeutl.cxx @@ -0,0 +1,243 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// INCLUDE --------------------------------------------------------------- + +#include <tools/debug.hxx> + +#include "rangeutl.hxx" +#include "document.hxx" +#include "dbcolect.hxx" +#include "rangenam.hxx" +#include "globstr.hrc" +namespace binfilter { + + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + +/*N*/ BOOL ScRangeUtil::IsAbsArea( const String& rAreaStr, +/*N*/ ScDocument* pDoc, +/*N*/ USHORT nTab, +/*N*/ String* pCompleteStr, +/*N*/ ScRefTripel* pStartPos, +/*N*/ ScRefTripel* pEndPos ) const +/*N*/ { +/*N*/ BOOL bIsAbsArea = FALSE; +/*N*/ ScRefTripel startPos; +/*N*/ ScRefTripel endPos; +/*N*/ +/*N*/ bIsAbsArea = ConvertDoubleRef( pDoc, rAreaStr, nTab, startPos, endPos ); +/*N*/ +/*N*/ if ( bIsAbsArea ) +/*N*/ { +/*N*/ startPos.SetRelCol( FALSE ); +/*N*/ startPos.SetRelRow( FALSE ); +/*N*/ startPos.SetRelTab( FALSE ); +/*N*/ endPos .SetRelCol( FALSE ); +/*N*/ endPos .SetRelRow( FALSE ); +/*N*/ endPos .SetRelTab( FALSE ); +/*N*/ +/*N*/ if ( pCompleteStr ) +/*N*/ { +/*N*/ *pCompleteStr = startPos.GetRefString( pDoc, MAXTAB+1 ); +/*N*/ *pCompleteStr += ':'; +/*N*/ *pCompleteStr += endPos .GetRefString( pDoc, nTab ); +/*N*/ } +/*N*/ +/*N*/ if ( pStartPos && pEndPos ) +/*N*/ { +/*N*/ *pStartPos = startPos; +/*N*/ *pEndPos = endPos; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ return bIsAbsArea; +/*N*/ } + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + +/*N*/ BOOL ScRangeUtil::MakeRangeFromName ( +/*N*/ const String& rName, +/*N*/ ScDocument* pDoc, +/*N*/ USHORT nCurTab, +/*N*/ ScRange& rRange, +/*N*/ RutlNameScope eScope +/*N*/ ) const +/*N*/ { +/*N*/ BOOL bResult=FALSE; +/*N*/ ScRangeUtil aRangeUtil; +/*N*/ USHORT nTab, nColStart, nColEnd, nRowStart, nRowEnd; +/*N*/ +/*N*/ if( eScope==RUTL_NAMES ) +/*N*/ { +/*N*/ ScRangeName& rRangeNames = *(pDoc->GetRangeName()); +/*N*/ USHORT nAt = 0; +/*N*/ +/*N*/ if ( rRangeNames.SearchName( rName, nAt ) ) +/*N*/ { +/*N*/ ScRangeData* pData = rRangeNames[nAt]; +/*N*/ String aStrArea; +/*N*/ ScRefTripel aStartPos; +/*N*/ ScRefTripel aEndPos; +/*N*/ +/*N*/ pData->GetSymbol( aStrArea ); +/*N*/ +/*N*/ if ( IsAbsArea( aStrArea, pDoc, nCurTab, +/*N*/ NULL, &aStartPos, &aEndPos ) ) +/*N*/ { +/*N*/ nTab = aStartPos.GetTab(); +/*N*/ nColStart = aStartPos.GetCol(); +/*N*/ nRowStart = aStartPos.GetRow(); +/*N*/ nColEnd = aEndPos.GetCol(); +/*N*/ nRowEnd = aEndPos.GetRow(); +/*N*/ bResult = TRUE; +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 CutPosString( aStrArea, aStrArea ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else if( eScope==RUTL_DBASE ) +/*N*/ { +/*N*/ ScDBCollection& rDbNames = *(pDoc->GetDBCollection()); +/*N*/ USHORT nAt = 0; +/*N*/ +/*N*/ if ( rDbNames.SearchName( rName, nAt ) ) +/*N*/ { +/*N*/ ScDBData* pData = rDbNames[nAt]; +/*N*/ +/*N*/ pData->GetArea( nTab, nColStart, nRowStart, +/*N*/ nColEnd, nRowEnd ); +/*N*/ bResult = TRUE; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ DBG_ERROR( "ScRangeUtil::MakeRangeFromName" ); +/*N*/ } +/*N*/ +/*N*/ if( bResult ) +/*N*/ { +/*N*/ rRange = ScRange( nColStart, nRowStart, nTab, nColEnd, nRowEnd, nTab ); +/*N*/ } +/*N*/ +/*N*/ return bResult; +/*N*/ } + +//======================================================================== + +/*N*/ ScArea::ScArea( USHORT tab, +/*N*/ USHORT colStart, USHORT rowStart, +/*N*/ USHORT colEnd, USHORT rowEnd ) : +/*N*/ nTab ( tab ), +/*N*/ nColStart( colStart ), nRowStart( rowStart ), +/*N*/ nColEnd ( colEnd ), nRowEnd ( rowEnd ) +/*N*/ { +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ ScArea::ScArea( const ScArea& r ) : +/*N*/ nTab ( r.nTab ), +/*N*/ nColStart( r.nColStart ), nRowStart( r.nRowStart ), +/*N*/ nColEnd ( r.nColEnd ), nRowEnd ( r.nRowEnd ) +/*N*/ { +/*N*/ } + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + +/*N*/ ScArea& ScArea::operator=( const ScArea& r ) +/*N*/ { +/*N*/ nTab = r.nTab; +/*N*/ nColStart = r.nColStart; +/*N*/ nRowStart = r.nRowStart; +/*N*/ nColEnd = r.nColEnd; +/*N*/ nRowEnd = r.nRowEnd; +/*N*/ return *this; +/*N*/ } + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + +/*N*/ SvStream& operator>> ( SvStream& rStream, ScArea& rArea ) +/*N*/ { +/*N*/ rStream >> rArea.nTab; +/*N*/ rStream >> rArea.nColStart; +/*N*/ rStream >> rArea.nRowStart; +/*N*/ rStream >> rArea.nColEnd; +/*N*/ rStream >> rArea.nRowEnd; +/*N*/ return rStream; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ SvStream& operator<< ( SvStream& rStream, const ScArea& rArea ) +/*N*/ { +/*N*/ rStream << rArea.nTab; +/*N*/ rStream << rArea.nColStart; +/*N*/ rStream << rArea.nRowStart; +/*N*/ rStream << rArea.nColEnd; +/*N*/ rStream << rArea.nRowEnd; +/*N*/ return rStream; +/*N*/ } + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + + + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_rechead.cxx b/binfilter/bf_sc/source/core/tool/sc_rechead.cxx new file mode 100644 index 000000000000..50dc0c6180e6 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_rechead.cxx @@ -0,0 +1,233 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// INCLUDE --------------------------------------------------------------- + +#include <tools/debug.hxx> + +#include "rechead.hxx" +#include "scerrors.hxx" +namespace binfilter { + +// STATIC DATA ----------------------------------------------------------- + +// ======================================================================= + +/*N*/ ScReadHeader::ScReadHeader(SvStream& rNewStream) : +/*N*/ rStream( rNewStream ) +/*N*/ { +/*N*/ sal_uInt32 nDataSize; +/*N*/ rStream >> nDataSize; +/*N*/ nDataEnd = rStream.Tell() + nDataSize; +/*N*/ } + +/*N*/ ScReadHeader::~ScReadHeader() +/*N*/ { +/*N*/ ULONG nReadEnd = rStream.Tell(); +/*N*/ DBG_ASSERT( nReadEnd <= nDataEnd, "zuviele Bytes gelesen" ); +/*N*/ if ( nReadEnd != nDataEnd ) +/*N*/ { +/*?*/ if ( rStream.GetError() == SVSTREAM_OK ) +/*?*/ rStream.SetError( SCWARN_IMPORT_INFOLOST ); +/*?*/ rStream.Seek(nDataEnd); // Rest ueberspringen +/*N*/ } +/*N*/ } + +/*N*/ ULONG ScReadHeader::BytesLeft() const +/*N*/ { +/*N*/ ULONG nReadEnd = rStream.Tell(); +/*N*/ if (nReadEnd <= nDataEnd) +/*N*/ return nDataEnd-nReadEnd; +/*N*/ +/*N*/ DBG_ERROR("Fehler bei ScReadHeader::BytesLeft"); +/*N*/ return 0; +/*N*/ } + +// ----------------------------------------------------------------------- + +/*N*/ ScWriteHeader::ScWriteHeader(SvStream& rNewStream, sal_uInt32 nDefault) : +/*N*/ rStream( rNewStream ) +/*N*/ { +/*N*/ nDataSize = nDefault; +/*N*/ rStream << nDataSize; +/*N*/ +/*N*/ nDataPos = rStream.Tell(); +/*N*/ } + +/*N*/ ScWriteHeader::~ScWriteHeader() +/*N*/ { +/*N*/ ULONG nPos = rStream.Tell(); +/*N*/ +/*N*/ if ( nPos - nDataPos != nDataSize ) // Default getroffen? +/*N*/ { +/*N*/ nDataSize = nPos - nDataPos; +/*N*/ rStream.Seek(nDataPos - sizeof(sal_uInt32)); +/*N*/ rStream << nDataSize; // Groesse am Anfang eintragen +/*N*/ rStream.Seek(nPos); +/*N*/ } +/*N*/ } + +// ======================================================================= + +/*N*/ ScMultipleReadHeader::ScMultipleReadHeader(SvStream& rNewStream) : +/*N*/ rStream( rNewStream ) +/*N*/ { +/*N*/ sal_uInt32 nDataSize; +/*N*/ rStream >> nDataSize; +/*N*/ ULONG nDataPos = rStream.Tell(); +/*N*/ nTotalEnd = nDataPos + nDataSize; +/*N*/ nEntryEnd = nTotalEnd; +/*N*/ +/*N*/ rStream.SeekRel(nDataSize); +/*N*/ USHORT nID; +/*N*/ rStream >> nID; +/*N*/ if (nID != SCID_SIZES) +/*N*/ { +/*N*/ DBG_ERROR("SCID_SIZES nicht gefunden"); +/*N*/ if ( rStream.GetError() == SVSTREAM_OK ) +/*N*/ rStream.SetError( SVSTREAM_FILEFORMAT_ERROR ); +/*N*/ +/*N*/ // alles auf 0, damit BytesLeft() wenigstens abbricht +/*N*/ pBuf = NULL; pMemStream = NULL; +/*N*/ nEntryEnd = nDataPos; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ sal_uInt32 nSizeTableLen; +/*N*/ rStream >> nSizeTableLen; +/*N*/ pBuf = new BYTE[nSizeTableLen]; +/*N*/ rStream.Read( pBuf, nSizeTableLen ); +/*N*/ pMemStream = new SvMemoryStream( (char*)pBuf, nSizeTableLen, STREAM_READ ); +/*N*/ } +/*N*/ +/*N*/ nEndPos = rStream.Tell(); +/*N*/ rStream.Seek( nDataPos ); +/*N*/ } + +/*N*/ ScMultipleReadHeader::~ScMultipleReadHeader() +/*N*/ { +/*N*/ if ( pMemStream && pMemStream->Tell() != pMemStream->GetEndOfData() ) +/*N*/ { +/*N*/ DBG_ERRORFILE( "Sizes nicht vollstaendig gelesen" ); +/*N*/ if ( rStream.GetError() == SVSTREAM_OK ) +/*N*/ rStream.SetError( SCWARN_IMPORT_INFOLOST ); +/*N*/ } +/*N*/ delete pMemStream; +/*N*/ delete[] pBuf; +/*N*/ +/*N*/ rStream.Seek(nEndPos); +/*N*/ } + +/*N*/ void ScMultipleReadHeader::EndEntry() +/*N*/ { +/*N*/ ULONG nPos = rStream.Tell(); +/*N*/ DBG_ASSERT( nPos <= nEntryEnd, "zuviel gelesen" ); +/*N*/ if ( nPos != nEntryEnd ) +/*N*/ { +/*?*/ if ( rStream.GetError() == SVSTREAM_OK ) +/*?*/ rStream.SetError( SCWARN_IMPORT_INFOLOST ); +/*?*/ rStream.Seek( nEntryEnd ); // Rest ueberspringen +/*N*/ } +/*N*/ +/*N*/ nEntryEnd = nTotalEnd; // den ganzen Rest, wenn kein StartEntry kommt +/*N*/ } + +/*N*/ void ScMultipleReadHeader::StartEntry() +/*N*/ { +/*N*/ ULONG nPos = rStream.Tell(); +/*N*/ sal_uInt32 nEntrySize; +/*N*/ (*pMemStream) >> nEntrySize; +/*N*/ +/*N*/ nEntryEnd = nPos + nEntrySize; +/*N*/ DBG_ASSERT( nEntryEnd <= nTotalEnd, "zuviele Eintraege gelesen" ); +/*N*/ } + +/*N*/ ULONG ScMultipleReadHeader::BytesLeft() const +/*N*/ { +/*N*/ ULONG nReadEnd = rStream.Tell(); +/*N*/ if (nReadEnd <= nEntryEnd) +/*N*/ return nEntryEnd-nReadEnd; +/*N*/ +/*N*/ DBG_ERROR("Fehler bei ScMultipleReadHeader::BytesLeft"); +/*N*/ return 0; +/*N*/ } + +// ----------------------------------------------------------------------- + +/*N*/ ScMultipleWriteHeader::ScMultipleWriteHeader(SvStream& rNewStream, sal_uInt32 nDefault) : +/*N*/ rStream( rNewStream ), +/*N*/ aMemStream( 4096, 4096 ) +/*N*/ { +/*N*/ nDataSize = nDefault; +/*N*/ rStream << nDataSize; +/*N*/ +/*N*/ nDataPos = rStream.Tell(); +/*N*/ nEntryStart = nDataPos; +/*N*/ } + +/*N*/ ScMultipleWriteHeader::~ScMultipleWriteHeader() +/*N*/ { +/*N*/ ULONG nDataEnd = rStream.Tell(); +/*N*/ +/*N*/ rStream << (USHORT) SCID_SIZES; +/*N*/ rStream << static_cast<sal_uInt32>(aMemStream.Tell()); +/*N*/ rStream.Write( aMemStream.GetData(), aMemStream.Tell() ); +/*N*/ +/*N*/ if ( nDataEnd - nDataPos != nDataSize ) // Default getroffen? +/*N*/ { +/*N*/ nDataSize = nDataEnd - nDataPos; +/*N*/ ULONG nPos = rStream.Tell(); +/*N*/ rStream.Seek(nDataPos-sizeof(sal_uInt32)); +/*N*/ rStream << nDataSize; // Groesse am Anfang eintragen +/*N*/ rStream.Seek(nPos); +/*N*/ } +/*N*/ } + +/*N*/ void ScMultipleWriteHeader::EndEntry() +/*N*/ { +/*N*/ ULONG nPos = rStream.Tell(); +/*N*/ aMemStream << static_cast<sal_uInt32>(nPos - nEntryStart); +/*N*/ } + +/*N*/ void ScMultipleWriteHeader::StartEntry() +/*N*/ { +/*N*/ ULONG nPos = rStream.Tell(); +/*N*/ nEntryStart = nPos; +/*N*/ } + + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_refdata.cxx b/binfilter/bf_sc/source/core/tool/sc_refdata.cxx new file mode 100644 index 000000000000..7912eea6d3a8 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_refdata.cxx @@ -0,0 +1,298 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "refdata.hxx" +namespace binfilter { + + +/*N*/ void SingleRefData::CalcRelFromAbs( const ScAddress& rPos ) +/*N*/ { +/*N*/ nRelCol = nCol - rPos.Col(); +/*N*/ nRelRow = nRow - rPos.Row(); +/*N*/ nRelTab = nTab - rPos.Tab(); +/*N*/ } + + +/*N*/ void SingleRefData::SmartRelAbs( const ScAddress& rPos ) +/*N*/ { +/*N*/ if ( Flags.bColRel ) +/*N*/ nCol = nRelCol + rPos.Col(); +/*N*/ else +/*N*/ nRelCol = nCol - rPos.Col(); +/*N*/ +/*N*/ if ( Flags.bRowRel ) +/*N*/ nRow = nRelRow + rPos.Row(); +/*N*/ else +/*N*/ nRelRow = nRow - rPos.Row(); +/*N*/ +/*N*/ if ( Flags.bTabRel ) +/*N*/ nTab = nRelTab + rPos.Tab(); +/*N*/ else +/*N*/ nRelTab = nTab - rPos.Tab(); +/*N*/ } + + +/*N*/ void SingleRefData::CalcAbsIfRel( const ScAddress& rPos ) +/*N*/ { +/*N*/ if ( Flags.bColRel ) +/*N*/ { +/*N*/ nCol = nRelCol + rPos.Col(); +/*N*/ if ( !VALIDCOL( nCol ) ) +/*N*/ Flags.bColDeleted = TRUE; +/*N*/ } +/*N*/ if ( Flags.bRowRel ) +/*N*/ { +/*N*/ nRow = nRelRow + rPos.Row(); +/*N*/ if ( !VALIDROW( nRow ) ) +/*N*/ Flags.bRowDeleted = TRUE; +/*N*/ } +/*N*/ if ( Flags.bTabRel ) +/*N*/ { +/*N*/ nTab = nRelTab + rPos.Tab(); +/*N*/ if ( !VALIDTAB( nTab ) ) +/*N*/ Flags.bTabDeleted = TRUE; +/*N*/ } +/*N*/ } + + +/*N*/ void SingleRefData::OldBoolsToNewFlags( const OldSingleRefBools& rBools ) +/*N*/ { +/*N*/ switch ( rBools.bRelCol ) +/*N*/ { +/*N*/ case SR_DELETED : +/*?*/ Flags.bColRel = TRUE; // der war verlorengegangen +/*?*/ Flags.bColDeleted = TRUE; +/*?*/ break; +/*N*/ case SR_ABSOLUTE : +/*N*/ Flags.bColRel = FALSE; +/*N*/ Flags.bColDeleted = FALSE; +/*N*/ break; +/*N*/ case SR_RELABS : +/*N*/ case SR_RELATIVE : +/*N*/ default: +/*N*/ Flags.bColRel = TRUE; +/*N*/ Flags.bColDeleted = FALSE; +/*N*/ } +/*N*/ switch ( rBools.bRelRow ) +/*N*/ { +/*N*/ case SR_DELETED : +/*?*/ Flags.bRowRel = TRUE; // der war verlorengegangen +/*?*/ Flags.bRowDeleted = TRUE; +/*?*/ break; +/*N*/ case SR_ABSOLUTE : +/*N*/ Flags.bRowRel = FALSE; +/*N*/ Flags.bRowDeleted = FALSE; +/*N*/ break; +/*N*/ case SR_RELABS : +/*N*/ case SR_RELATIVE : +/*N*/ default: +/*N*/ Flags.bRowRel = TRUE; +/*N*/ Flags.bRowDeleted = FALSE; +/*N*/ } +/*N*/ switch ( rBools.bRelTab ) +/*N*/ { +/*N*/ case SR_DELETED : +/*?*/ Flags.bTabRel = TRUE; // der war verlorengegangen +/*?*/ Flags.bTabDeleted = TRUE; +/*?*/ break; +/*N*/ case SR_ABSOLUTE : +/*N*/ Flags.bTabRel = FALSE; +/*N*/ Flags.bTabDeleted = FALSE; +/*N*/ break; +/*N*/ case SR_RELABS : +/*N*/ case SR_RELATIVE : +/*N*/ default: +/*N*/ Flags.bTabRel = TRUE; +/*N*/ Flags.bTabDeleted = FALSE; +/*N*/ } +/*N*/ Flags.bFlag3D = (rBools.bOldFlag3D & SRF_3D ? TRUE : FALSE); +/*N*/ Flags.bRelName = (rBools.bOldFlag3D & SRF_RELNAME ? TRUE : FALSE); +/*N*/ if ( !Flags.bFlag3D ) +/*N*/ Flags.bTabRel = TRUE; // ist bei einigen aelteren Dokumenten nicht gesetzt +/*N*/ } + + +/* + bis Release 3.1 sah Store so aus + + BYTE n = ( ( r.bOldFlag3D & 0x03 ) << 6 ) // RelName, 3D + | ( ( r.bRelTab & 0x03 ) << 4 ) // Relative, RelAbs + | ( ( r.bRelRow & 0x03 ) << 2 ) + | ( r.bRelCol & 0x03 ); + + bis Release 3.1 sah Load so aus + + r.bRelCol = ( n & 0x03 ); + r.bRelRow = ( ( n >> 2 ) & 0x03 ); + r.bRelTab = ( ( n >> 4 ) & 0x03 ); + r.bOldFlag3D = ( ( n >> 6 ) & 0x03 ); + + bRelCol == SR_DELETED war identisch mit bRelCol == (SR_RELATIVE | SR_RELABS) + leider.. + 3.1 liest Zukunft: Deleted wird nicht unbedingt erkannt, nur wenn auch Relativ. + Aber immer noch nCol > MAXCOL und gut sollte sein.. + */ + +/*N*/ BYTE SingleRefData::CreateStoreByteFromFlags() const +/*N*/ { +/*N*/ return (BYTE)( +/*N*/ ( (Flags.bRelName & 0x01) << 7 ) +/*N*/ | ( (Flags.bFlag3D & 0x01) << 6 ) +/*N*/ | ( (Flags.bTabDeleted & 0x01) << 5 ) +/*N*/ | ( (Flags.bTabRel & 0x01) << 4 ) +/*N*/ | ( (Flags.bRowDeleted & 0x01) << 3 ) +/*N*/ | ( (Flags.bRowRel & 0x01) << 2 ) +/*N*/ | ( (Flags.bColDeleted & 0x01) << 1 ) +/*N*/ | (Flags.bColRel & 0x01) +/*N*/ ); +/*N*/ } + + +/*N*/ void SingleRefData::CreateFlagsFromLoadByte( BYTE n ) +/*N*/ { +/*N*/ Flags.bColRel = (n & 0x01 ); +/*N*/ Flags.bColDeleted = ( (n >> 1) & 0x01 ); +/*N*/ Flags.bRowRel = ( (n >> 2) & 0x01 ); +/*N*/ Flags.bRowDeleted = ( (n >> 3) & 0x01 ); +/*N*/ Flags.bTabRel = ( (n >> 4) & 0x01 ); +/*N*/ Flags.bTabDeleted = ( (n >> 5) & 0x01 ); +/*N*/ Flags.bFlag3D = ( (n >> 6) & 0x01 ); +/*N*/ Flags.bRelName = ( (n >> 7) & 0x01 ); +/*N*/ } + + +/*N*/ BOOL SingleRefData::operator==( const SingleRefData& r ) const +/*N*/ { +/*N*/ return bFlags == r.bFlags && +/*N*/ (Flags.bColRel ? nRelCol == r.nRelCol : nCol == r.nCol) && +/*N*/ (Flags.bRowRel ? nRelRow == r.nRelRow : nRow == r.nRow) && +/*N*/ (Flags.bTabRel ? nRelTab == r.nRelTab : nTab == r.nTab); +/*N*/ } + + +// Abs-Refs muessen vorher aktualisiert werden! +// wird in refupdat.cxx mit MoveRelWrap verwendet +/*N*/ void ComplRefData::PutInOrder() +/*N*/ { +/*N*/ register short n1, n2; +/*N*/ register BOOL bTmp; +/*N*/ BYTE nRelState1, nRelState2; +/*N*/ if ( Ref1.Flags.bRelName ) +/*?*/ nRelState1 = +/*?*/ ((Ref1.Flags.bTabRel & 0x01) << 2) +/*?*/ | ((Ref1.Flags.bRowRel & 0x01) << 1) +/*?*/ | ((Ref1.Flags.bColRel & 0x01)); +/*N*/ else +/*N*/ nRelState1 = 0; +/*N*/ if ( Ref2.Flags.bRelName ) +/*?*/ nRelState2 = +/*?*/ ((Ref2.Flags.bTabRel & 0x01) << 2) +/*?*/ | ((Ref2.Flags.bRowRel & 0x01) << 1) +/*?*/ | ((Ref2.Flags.bColRel & 0x01)); +/*N*/ else +/*N*/ nRelState2 = 0; +/*N*/ if ( (n1 = Ref1.nCol) > (n2 = Ref2.nCol) ) +/*N*/ { +/*?*/ Ref1.nCol = n2; +/*?*/ Ref2.nCol = n1; +/*?*/ n1 = Ref1.nRelCol; +/*?*/ Ref1.nRelCol = Ref2.nRelCol; +/*?*/ Ref2.nRelCol = n1; +/*?*/ if ( Ref1.Flags.bRelName && Ref1.Flags.bColRel ) +/*?*/ nRelState2 |= 1; +/*?*/ else +/*?*/ nRelState2 &= ~1; +/*?*/ if ( Ref2.Flags.bRelName && Ref2.Flags.bColRel ) +/*?*/ nRelState1 |= 1; +/*?*/ else +/*?*/ nRelState1 &= ~1; +/*?*/ bTmp = Ref1.Flags.bColRel; +/*?*/ Ref1.Flags.bColRel = Ref2.Flags.bColRel; +/*?*/ Ref2.Flags.bColRel = bTmp; +/*?*/ bTmp = Ref1.Flags.bColDeleted; +/*?*/ Ref1.Flags.bColDeleted = Ref2.Flags.bColDeleted; +/*?*/ Ref2.Flags.bColDeleted = bTmp; +/*N*/ } +/*N*/ if ( (n1 = Ref1.nRow) > (n2 = Ref2.nRow) ) +/*N*/ { +/*?*/ Ref1.nRow = n2; +/*?*/ Ref2.nRow = n1; +/*?*/ n1 = Ref1.nRelRow; +/*?*/ Ref1.nRelRow = Ref2.nRelRow; +/*?*/ Ref2.nRelRow = n1; +/*?*/ if ( Ref1.Flags.bRelName && Ref1.Flags.bRowRel ) +/*?*/ nRelState2 |= 2; +/*?*/ else +/*?*/ nRelState2 &= ~2; +/*?*/ if ( Ref2.Flags.bRelName && Ref2.Flags.bRowRel ) +/*?*/ nRelState1 |= 2; +/*?*/ else +/*?*/ nRelState1 &= ~2; +/*?*/ bTmp = Ref1.Flags.bRowRel; +/*?*/ Ref1.Flags.bRowRel = Ref2.Flags.bRowRel; +/*?*/ Ref2.Flags.bRowRel = bTmp; +/*?*/ bTmp = Ref1.Flags.bRowDeleted; +/*?*/ Ref1.Flags.bRowDeleted = Ref2.Flags.bRowDeleted; +/*?*/ Ref2.Flags.bRowDeleted = bTmp; +/*N*/ } +/*N*/ if ( (n1 = Ref1.nTab) > (n2 = Ref2.nTab) ) +/*N*/ { +/*?*/ Ref1.nTab = n2; +/*?*/ Ref2.nTab = n1; +/*?*/ n1 = Ref1.nRelTab; +/*?*/ Ref1.nRelTab = Ref2.nRelTab; +/*?*/ Ref2.nRelTab = n1; +/*?*/ if ( Ref1.Flags.bRelName && Ref1.Flags.bTabRel ) +/*?*/ nRelState2 |= 4; +/*?*/ else +/*?*/ nRelState2 &= ~4; +/*?*/ if ( Ref2.Flags.bRelName && Ref2.Flags.bTabRel ) +/*?*/ nRelState1 |= 4; +/*?*/ else +/*?*/ nRelState1 &= ~4; +/*?*/ bTmp = Ref1.Flags.bTabRel; +/*?*/ Ref1.Flags.bTabRel = Ref2.Flags.bTabRel; +/*?*/ Ref2.Flags.bTabRel = bTmp; +/*?*/ bTmp = Ref1.Flags.bTabDeleted; +/*?*/ Ref1.Flags.bTabDeleted = Ref2.Flags.bTabDeleted; +/*?*/ Ref2.Flags.bTabDeleted = bTmp; +/*?*/ bTmp = Ref1.Flags.bFlag3D; +/*?*/ Ref1.Flags.bFlag3D = Ref2.Flags.bFlag3D; +/*?*/ Ref2.Flags.bFlag3D = bTmp; +/*N*/ } +/*N*/ Ref1.Flags.bRelName = ( nRelState1 ? TRUE : FALSE ); +/*N*/ Ref2.Flags.bRelName = ( nRelState2 ? TRUE : FALSE ); +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_refreshtimer.cxx b/binfilter/bf_sc/source/core/tool/sc_refreshtimer.cxx new file mode 100644 index 000000000000..392942d34b05 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_refreshtimer.cxx @@ -0,0 +1,67 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "refreshtimer.hxx" +#include <tools/debug.hxx>//STRIP001 +namespace binfilter { + +/*N*/ ScRefreshTimerProtector::ScRefreshTimerProtector( ScRefreshTimerControl * const * pp ) +/*N*/ : +/*N*/ ppControl( pp ) +/*N*/ { +/*N*/ if ( ppControl && *ppControl ) +/*N*/ { +/*N*/ (*ppControl)->SetAllowRefresh( FALSE ); +/*N*/ // wait for any running refresh in another thread to finnish +/*N*/ ::osl::MutexGuard aGuard( (*ppControl)->GetMutex() ); +/*N*/ } +/*N*/ } + + +/*N*/ ScRefreshTimer::~ScRefreshTimer() +/*N*/ { +/*N*/ if ( IsActive() ) +/*?*/ Stop(); +/*N*/ RemoveFromControl(); +/*N*/ } + + +/*N*/ void ScRefreshTimer::SetRefreshDelay( ULONG nSeconds ) +/*N*/ { +/*N*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 BOOL bActive = IsActive(); +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_refupdat.cxx b/binfilter/bf_sc/source/core/tool/sc_refupdat.cxx new file mode 100644 index 000000000000..3965c1bb0376 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_refupdat.cxx @@ -0,0 +1,768 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// INCLUDE --------------------------------------------------------------- + + +#include "refupdat.hxx" +#include "compiler.hxx" +#include "chgtrack.hxx" +namespace binfilter { + +//------------------------------------------------------------------------ + +/*N*/ BOOL lcl_MoveStart( short& rRef, short nStart, short nDelta, short nMask ) +/*N*/ { +/*N*/ BOOL bCut = FALSE; +/*N*/ if ( rRef >= nStart ) +/*N*/ rRef += nDelta; +/*N*/ else if ( nDelta < 0 && rRef >= nStart + nDelta ) +/*N*/ rRef = nStart + nDelta; //! begrenzen ??? +/*N*/ if ( rRef < 0 ) +/*N*/ { +/*N*/ rRef = 0; +/*N*/ bCut = TRUE; +/*N*/ } +/*N*/ else if ( rRef > nMask ) +/*N*/ { +/*N*/ rRef = nMask; +/*N*/ bCut = TRUE; +/*N*/ } +/*N*/ return bCut; +/*N*/ } + +/*N*/ BOOL lcl_MoveEnd( short& rRef, short nStart, short nDelta, short nMask ) +/*N*/ { +/*N*/ BOOL bCut = FALSE; +/*N*/ if ( rRef >= nStart ) +/*N*/ rRef += nDelta; +/*N*/ else if ( nDelta < 0 && rRef >= nStart + nDelta ) +/*N*/ rRef = nStart + nDelta - 1; //! begrenzen ??? +/*N*/ if ( rRef < 0 ) +/*N*/ { +/*N*/ rRef = 0; +/*N*/ bCut = TRUE; +/*N*/ } +/*N*/ else if ( rRef > nMask ) +/*N*/ { +/*N*/ rRef = nMask; +/*N*/ bCut = TRUE; +/*N*/ } +/*N*/ return bCut; +/*N*/ } + + +/*N*/ BOOL lcl_MoveItCut( short& rRef, short nDelta, short nMask ) +/*N*/ { +/*N*/ BOOL bCut = FALSE; +/*N*/ rRef += nDelta; +/*N*/ if ( rRef < 0 ) +/*N*/ { +/*N*/ rRef = 0; +/*N*/ bCut = TRUE; +/*N*/ } +/*N*/ else if ( rRef > nMask ) +/*N*/ { +/*N*/ rRef = nMask; +/*N*/ bCut = TRUE; +/*N*/ } +/*N*/ return bCut; +/*N*/ } + +/*N*/ void lcl_MoveItWrap( short& rRef, short nDelta, short nMask ) +/*N*/ { +/*N*/ rRef += nDelta; +/*N*/ if ( rRef < 0 ) +/*N*/ rRef += nMask+1; +/*N*/ else if ( rRef > nMask ) +/*N*/ rRef -= nMask+1; +/*N*/ } + +/*N*/ BOOL lcl_MoveRefPart( short& rRef1Val, BOOL& rRef1Del, +/*N*/ short& rRef2Val, BOOL& rRef2Del, +/*N*/ short nStart, short nEnd, short nDelta, short nMask ) +/*N*/ { +/*N*/ if ( nDelta ) +/*N*/ { +/*N*/ BOOL bDel, bCut1, bCut2; +/*N*/ bDel = bCut1 = bCut2 = FALSE; +/*N*/ short n; +/*N*/ if ( nDelta < 0 ) +/*N*/ { +/*N*/ n = nStart + nDelta; +/*N*/ if ( n <= rRef1Val && rRef1Val < nStart +/*N*/ && n <= rRef2Val && rRef2Val < nStart ) +/*N*/ bDel = TRUE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ n = nEnd + nDelta; +/*N*/ if ( nEnd < rRef1Val && rRef1Val <= n +/*N*/ && nEnd < rRef2Val && rRef2Val <= n ) +/*N*/ bDel = TRUE; +/*N*/ } +/*N*/ if ( bDel ) +/*N*/ { // geloeschte mitverschieben +/*N*/ rRef1Val += nDelta; +/*N*/ rRef2Val += nDelta; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( rRef1Del ) +/*N*/ rRef1Val += nDelta; +/*N*/ else +/*N*/ bCut1 = lcl_MoveStart( rRef1Val, nStart, nDelta, nMask ); +/*N*/ if ( rRef2Del ) +/*N*/ rRef2Val += nDelta; +/*N*/ else +/*N*/ bCut2 = lcl_MoveEnd( rRef2Val, nStart, nDelta, nMask ); +/*N*/ } +/*N*/ if ( bDel || (bCut1 && bCut2) ) +/*N*/ rRef1Del = rRef2Del = TRUE; +/*N*/ return bDel || bCut1 || bCut2 || rRef1Del || rRef2Del; +/*N*/ } +/*N*/ else +/*N*/ return FALSE; +/*N*/ } + +/*N*/ #if OSL_DEBUG_LEVEL < 2 +/*N*/ inline +/*N*/ #endif +/*N*/ BOOL IsExpand( short n1, short n2, short nStart, short nD ) +/*N*/ { //! vor normalem Move... +/*N*/ return +/*N*/ nD > 0 // Insert +/*N*/ && n1 < n2 // mindestens zwei Cols/Rows/Tabs in Ref +/*N*/ && ( +/*N*/ (nStart <= n1 && n1 < nStart + nD) // n1 innerhalb des Insert +/*N*/ || (n2 + 1 == nStart) // n2 direkt vor Insert +/*N*/ ); // n1 < nStart <= n2 wird sowieso expanded! +/*N*/ } + + +/*N*/ #if OSL_DEBUG_LEVEL < 2 +/*N*/ inline +/*N*/ #endif +/*N*/ void Expand( short& n1, short& n2, short nStart, short nD ) +/*N*/ { //! nach normalem Move..., nur wenn IsExpand vorher TRUE war! +/*N*/ //! erst das Ende +/*N*/ if ( n2 + 1 == nStart ) +/*N*/ { // am Ende +/*N*/ n2 += nD; +/*N*/ return; +/*N*/ } +/*N*/ // am Anfang +/*N*/ n1 -= nD; +/*N*/ } + + +/*N*/ BOOL lcl_IsWrapBig( INT32 nRef, INT32 nDelta ) +/*N*/ { +/*N*/ if ( nRef > 0 && nDelta > 0 ) +/*N*/ return nRef + nDelta <= 0; +/*N*/ else if ( nRef < 0 && nDelta < 0 ) +/*N*/ return nRef + nDelta >= 0; +/*N*/ return FALSE; +/*N*/ } + + +/*N*/ BOOL lcl_MoveBig( INT32& rRef, INT32 nStart, INT32 nDelta ) +/*N*/ { +/*N*/ BOOL bCut = FALSE; +/*N*/ if ( rRef >= nStart ) +/*N*/ { +/*N*/ if ( nDelta > 0 ) +/*N*/ bCut = lcl_IsWrapBig( rRef, nDelta ); +/*N*/ if ( bCut ) +/*N*/ rRef = nInt32Max; +/*N*/ else +/*N*/ rRef += nDelta; +/*N*/ } +/*N*/ return bCut; +/*N*/ } + +/*N*/ BOOL lcl_MoveItCutBig( INT32& rRef, INT32 nDelta ) +/*N*/ { +/*N*/ BOOL bCut = lcl_IsWrapBig( rRef, nDelta ); +/*N*/ rRef += nDelta; +/*N*/ return bCut; +/*N*/ } + + +/*N*/ ScRefUpdateRes ScRefUpdate::Update( ScDocument* pDoc, UpdateRefMode eUpdateRefMode, +/*N*/ USHORT nCol1, USHORT nRow1, USHORT nTab1, +/*N*/ USHORT nCol2, USHORT nRow2, USHORT nTab2, +/*N*/ short nDx, short nDy, short nDz, +/*N*/ USHORT& theCol1, USHORT& theRow1, USHORT& theTab1, +/*N*/ USHORT& theCol2, USHORT& theRow2, USHORT& theTab2 ) +/*N*/ { +/*N*/ ScRefUpdateRes eRet = UR_NOTHING; +/*N*/ +/*N*/ USHORT oldCol1 = theCol1; +/*N*/ USHORT oldRow1 = theRow1; +/*N*/ USHORT oldTab1 = theTab1; +/*N*/ USHORT oldCol2 = theCol2; +/*N*/ USHORT oldRow2 = theRow2; +/*N*/ USHORT oldTab2 = theTab2; +/*N*/ +/*N*/ BOOL bCut1, bCut2; +/*N*/ +/*N*/ if (eUpdateRefMode == URM_INSDEL) +/*N*/ { +/*N*/ BOOL bExpand = pDoc->IsExpandRefs(); +/*N*/ if ( nDx && (theRow1 >= nRow1) && (theRow2 <= nRow2) && +/*N*/ (theTab1 >= nTab1) && (theTab2 <= nTab2) ) +/*N*/ { +/*N*/ BOOL bExp = (bExpand && IsExpand( theCol1, theCol2, nCol1, nDx )); +/*N*/ bCut1 = lcl_MoveStart( (short&) theCol1, nCol1, nDx, MAXCOL ); +/*N*/ bCut2 = lcl_MoveEnd( (short&) theCol2, nCol1, nDx, MAXCOL ); +/*N*/ if ( theCol2 < theCol1 ) +/*N*/ { +/*N*/ eRet = UR_INVALID; +/*N*/ theCol2 = theCol1; +/*N*/ } +/*N*/ else if ( bCut1 || bCut2 ) +/*N*/ eRet = UR_UPDATED; +/*N*/ if ( bExp ) +/*N*/ { +/*N*/ Expand( (short&) theCol1, (short&) theCol2, nCol1, nDx ); +/*N*/ eRet = UR_UPDATED; +/*N*/ } +/*N*/ } +/*N*/ if ( nDy && (theCol1 >= nCol1) && (theCol2 <= nCol2) && +/*N*/ (theTab1 >= nTab1) && (theTab2 <= nTab2) ) +/*N*/ { +/*?*/ BOOL bExp = (bExpand && IsExpand( theRow1, theRow2, nRow1, nDy )); +/*?*/ bCut1 = lcl_MoveStart( (short&) theRow1, nRow1, nDy, MAXROW ); +/*?*/ bCut2 = lcl_MoveEnd( (short&) theRow2, nRow1, nDy, MAXROW ); +/*?*/ if ( theRow2 < theRow1 ) +/*?*/ { +/*?*/ eRet = UR_INVALID; +/*?*/ theRow2 = theRow1; +/*?*/ } +/*?*/ else if ( bCut1 || bCut2 ) +/*?*/ eRet = UR_UPDATED; +/*?*/ if ( bExp ) +/*?*/ { +/*?*/ Expand( (short&) theRow1, (short&) theRow2, nRow1, nDy ); +/*?*/ eRet = UR_UPDATED; +/*?*/ } +/*N*/ } +/*N*/ if ( nDz && (theCol1 >= nCol1) && (theCol2 <= nCol2) && +/*N*/ (theRow1 >= nRow1) && (theRow2 <= nRow2) ) +/*N*/ { +/*N*/ short nMaxTab = pDoc->GetTableCount() - 1; +/*N*/ nMaxTab += nDz; // auf die neue Anzahl anpassen +/*N*/ BOOL bExp = (bExpand && IsExpand( theTab1, theTab2, nTab1, nDz )); +/*N*/ bCut1 = lcl_MoveStart( (short&) theTab1, nTab1, nDz, nMaxTab ); +/*N*/ bCut2 = lcl_MoveEnd( (short&) theTab2, nTab1, nDz, nMaxTab ); +/*N*/ if ( theTab2 < theTab1 ) +/*N*/ { +/*N*/ eRet = UR_INVALID; +/*N*/ theTab2 = theTab1; +/*N*/ } +/*N*/ else if ( bCut1 || bCut2 ) +/*N*/ eRet = UR_UPDATED; +/*N*/ if ( bExp ) +/*N*/ { +/*?*/ Expand( (short&) theTab1, (short&) theTab2, nTab1, nDz ); +/*?*/ eRet = UR_UPDATED; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else if (eUpdateRefMode == URM_MOVE) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 if ((theCol1 >= nCol1-nDx) && (theRow1 >= nRow1-nDy) && (theTab1 >= nTab1-nDz) && +/*N*/ } +/*N*/ else if (eUpdateRefMode == URM_REORDER) +/*N*/ { +/*?*/ // bisher nur fuer nDz (MoveTab) +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 DBG_ASSERT ( !nDx && !nDy, "URM_REORDER fuer x und y noch nicht implementiert" ); +/*N*/ } +/*N*/ +/*N*/ if ( eRet == UR_NOTHING ) +/*N*/ { +/*N*/ if (oldCol1 != theCol1 +/*N*/ || oldRow1 != theRow1 +/*N*/ || oldTab1 != theTab1 +/*N*/ || oldCol2 != theCol2 +/*N*/ || oldRow2 != theRow2 +/*N*/ || oldTab2 != theTab2 +/*N*/ ) +/*N*/ eRet = UR_UPDATED; +/*N*/ } +/*N*/ return eRet; +/*N*/ } + + +// simples UpdateReference fuer ScBigRange (ScChangeAction/ScChangeTrack) +// Referenzen koennen auch ausserhalb des Dokuments liegen! +// Ganze Spalten/Zeilen (nInt32Min..nInt32Max) bleiben immer solche! +/*N*/ ScRefUpdateRes ScRefUpdate::Update( UpdateRefMode eUpdateRefMode, +/*N*/ const ScBigRange& rWhere, INT32 nDx, INT32 nDy, INT32 nDz, +/*N*/ ScBigRange& rWhat ) +/*N*/ { +/*N*/ ScRefUpdateRes eRet = UR_NOTHING; +/*N*/ const ScBigRange aOldRange( rWhat ); +/*N*/ +/*N*/ INT32 nCol1, nRow1, nTab1, nCol2, nRow2, nTab2; +/*N*/ INT32 theCol1, theRow1, theTab1, theCol2, theRow2, theTab2; +/*N*/ rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); +/*N*/ rWhat.GetVars( theCol1, theRow1, theTab1, theCol2, theRow2, theTab2 ); +/*N*/ +/*N*/ BOOL bCut1, bCut2; +/*N*/ +/*N*/ if (eUpdateRefMode == URM_INSDEL) +/*N*/ { +/*N*/ if ( nDx && (theRow1 >= nRow1) && (theRow2 <= nRow2) && +/*N*/ (theTab1 >= nTab1) && (theTab2 <= nTab2) && +/*N*/ !(theCol1 == nInt32Min && theCol2 == nInt32Max) ) +/*N*/ { +/*N*/ bCut1 = lcl_MoveBig( theCol1, nCol1, nDx ); +/*N*/ bCut2 = lcl_MoveBig( theCol2, nCol1, nDx ); +/*N*/ if ( bCut1 || bCut2 ) +/*N*/ eRet = UR_UPDATED; +/*N*/ rWhat.aStart.SetCol( theCol1 ); +/*N*/ rWhat.aEnd.SetCol( theCol2 ); +/*N*/ } +/*N*/ if ( nDy && (theCol1 >= nCol1) && (theCol2 <= nCol2) && +/*N*/ (theTab1 >= nTab1) && (theTab2 <= nTab2) && +/*N*/ !(theRow1 == nInt32Min && theRow2 == nInt32Max) ) +/*N*/ { +/*N*/ bCut1 = lcl_MoveBig( theRow1, nRow1, nDy ); +/*N*/ bCut2 = lcl_MoveBig( theRow2, nRow1, nDy ); +/*N*/ if ( bCut1 || bCut2 ) +/*N*/ eRet = UR_UPDATED; +/*N*/ rWhat.aStart.SetRow( theRow1 ); +/*N*/ rWhat.aEnd.SetRow( theRow2 ); +/*N*/ } +/*N*/ if ( nDz && (theCol1 >= nCol1) && (theCol2 <= nCol2) && +/*N*/ (theRow1 >= nRow1) && (theRow2 <= nRow2) && +/*N*/ !(theTab1 == nInt32Min && theTab2 == nInt32Max) ) +/*N*/ { +/*N*/ bCut1 = lcl_MoveBig( theTab1, nTab1, nDz ); +/*N*/ bCut2 = lcl_MoveBig( theTab2, nTab1, nDz ); +/*N*/ if ( bCut1 || bCut2 ) +/*N*/ eRet = UR_UPDATED; +/*N*/ rWhat.aStart.SetTab( theTab1 ); +/*N*/ rWhat.aEnd.SetTab( theTab2 ); +/*N*/ } +/*N*/ } +/*N*/ else if (eUpdateRefMode == URM_MOVE) +/*N*/ { +/*N*/ if ( rWhere.In( rWhat ) ) +/*N*/ { +/*N*/ if ( nDx && !(theCol1 == nInt32Min && theCol2 == nInt32Max) ) +/*N*/ { +/*N*/ bCut1 = lcl_MoveItCutBig( theCol1, nDx ); +/*N*/ bCut2 = lcl_MoveItCutBig( theCol2, nDx ); +/*N*/ if ( bCut1 || bCut2 ) +/*N*/ eRet = UR_UPDATED; +/*N*/ rWhat.aStart.SetCol( theCol1 ); +/*N*/ rWhat.aEnd.SetCol( theCol2 ); +/*N*/ } +/*N*/ if ( nDy && !(theRow1 == nInt32Min && theRow2 == nInt32Max) ) +/*N*/ { +/*N*/ bCut1 = lcl_MoveItCutBig( theRow1, nDy ); +/*N*/ bCut2 = lcl_MoveItCutBig( theRow2, nDy ); +/*N*/ if ( bCut1 || bCut2 ) +/*N*/ eRet = UR_UPDATED; +/*N*/ rWhat.aStart.SetRow( theRow1 ); +/*N*/ rWhat.aEnd.SetRow( theRow2 ); +/*N*/ } +/*N*/ if ( nDz && !(theTab1 == nInt32Min && theTab2 == nInt32Max) ) +/*N*/ { +/*N*/ bCut1 = lcl_MoveItCutBig( theTab1, nDz ); +/*N*/ bCut2 = lcl_MoveItCutBig( theTab2, nDz ); +/*N*/ if ( bCut1 || bCut2 ) +/*N*/ eRet = UR_UPDATED; +/*N*/ rWhat.aStart.SetTab( theTab1 ); +/*N*/ rWhat.aEnd.SetTab( theTab2 ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( eRet == UR_NOTHING && rWhat != aOldRange ) +/*N*/ eRet = UR_UPDATED; +/*N*/ +/*N*/ return eRet; +/*N*/ } + + +// vor dem Aufruf muessen die Abs-Refs aktualisiert werden! +/*N*/ ScRefUpdateRes ScRefUpdate::Update( ScDocument* pDoc, UpdateRefMode eMode, +/*N*/ const ScAddress& rPos, const ScRange& r, +/*N*/ short nDx, short nDy, short nDz, +/*N*/ ComplRefData& rRef ) +/*N*/ { +/*N*/ ScRefUpdateRes eRet = UR_NOTHING; +/*N*/ +/*N*/ short nCol1 = r.aStart.Col(); +/*N*/ short nRow1 = r.aStart.Row(); +/*N*/ short nTab1 = r.aStart.Tab(); +/*N*/ short nCol2 = r.aEnd.Col(); +/*N*/ short nRow2 = r.aEnd.Row(); +/*N*/ short nTab2 = r.aEnd.Tab(); +/*N*/ +/*N*/ if( eMode == URM_INSDEL ) +/*N*/ { +/*N*/ BOOL bExpand = pDoc->IsExpandRefs(); +/*N*/ +/*N*/ const ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack(); +/*N*/ BOOL bInDeleteUndo = +/*N*/ ( pChangeTrack ? pChangeTrack->IsInDeleteUndo() : FALSE ); +/*N*/ +/*N*/ USHORT oldCol1 = rRef.Ref1.nCol; +/*N*/ USHORT oldRow1 = rRef.Ref1.nRow; +/*N*/ USHORT oldTab1 = rRef.Ref1.nTab; +/*N*/ USHORT oldCol2 = rRef.Ref2.nCol; +/*N*/ USHORT oldRow2 = rRef.Ref2.nRow; +/*N*/ USHORT oldTab2 = rRef.Ref2.nTab; +/*N*/ +/*N*/ BOOL bRef1ColDel = rRef.Ref1.IsColDeleted(); +/*N*/ BOOL bRef2ColDel = rRef.Ref2.IsColDeleted(); +/*N*/ BOOL bRef1RowDel = rRef.Ref1.IsRowDeleted(); +/*N*/ BOOL bRef2RowDel = rRef.Ref2.IsRowDeleted(); +/*N*/ BOOL bRef1TabDel = rRef.Ref1.IsTabDeleted(); +/*N*/ BOOL bRef2TabDel = rRef.Ref2.IsTabDeleted(); +/*N*/ +/*N*/ if( nDx && +/*N*/ ((rRef.Ref1.nRow >= nRow1 +/*N*/ && rRef.Ref2.nRow <= nRow2) || (bRef1RowDel || bRef2RowDel)) +/*N*/ && +/*N*/ ((rRef.Ref1.nTab >= nTab1 +/*N*/ && rRef.Ref2.nTab <= nTab2) || (bRef1TabDel || bRef2TabDel)) +/*N*/ ) +/*N*/ { +/*N*/ BOOL bExp = (bExpand && !bInDeleteUndo && IsExpand( rRef.Ref1.nCol, +/*N*/ rRef.Ref2.nCol, nCol1, nDx )); +/*N*/ if ( lcl_MoveRefPart( rRef.Ref1.nCol, bRef1ColDel, +/*N*/ rRef.Ref2.nCol, bRef2ColDel, +/*N*/ nCol1, nCol2, nDx, MAXCOL ) ) +/*N*/ { +/*N*/ eRet = UR_UPDATED; +/*N*/ if ( bInDeleteUndo && (bRef1ColDel || bRef2ColDel) ) +/*N*/ { +/*N*/ if ( bRef1ColDel && nCol1 <= rRef.Ref1.nCol && +/*N*/ rRef.Ref1.nCol <= nCol1 + nDx ) +/*N*/ rRef.Ref1.SetColDeleted( FALSE ); +/*N*/ if ( bRef2ColDel && nCol1 <= rRef.Ref2.nCol && +/*N*/ rRef.Ref2.nCol <= nCol1 + nDx ) +/*N*/ rRef.Ref2.SetColDeleted( FALSE ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( bRef1ColDel ) +/*N*/ rRef.Ref1.SetColDeleted( TRUE ); +/*N*/ if ( bRef2ColDel ) +/*N*/ rRef.Ref2.SetColDeleted( TRUE ); +/*N*/ } +/*N*/ } +/*N*/ if ( bExp ) +/*N*/ { +/*N*/ Expand( rRef.Ref1.nCol, rRef.Ref2.nCol, nCol1, nDx ); +/*N*/ eRet = UR_UPDATED; +/*N*/ } +/*N*/ } +/*N*/ if( nDy && +/*N*/ ((rRef.Ref1.nCol >= nCol1 +/*N*/ && rRef.Ref2.nCol <= nCol2) || (bRef1ColDel || bRef2ColDel)) +/*N*/ && +/*N*/ ((rRef.Ref1.nTab >= nTab1 +/*N*/ && rRef.Ref2.nTab <= nTab2) || (bRef1TabDel || bRef2TabDel)) +/*N*/ ) +/*N*/ { +/*N*/ BOOL bExp = (bExpand && !bInDeleteUndo && IsExpand( rRef.Ref1.nRow, +/*N*/ rRef.Ref2.nRow, nRow1, nDy )); +/*N*/ if ( lcl_MoveRefPart( rRef.Ref1.nRow, bRef1RowDel, +/*N*/ rRef.Ref2.nRow, bRef2RowDel, +/*N*/ nRow1, nRow2, nDy, MAXROW ) ) +/*N*/ { +/*N*/ eRet = UR_UPDATED; +/*N*/ if ( bInDeleteUndo && (bRef1RowDel || bRef2RowDel) ) +/*N*/ { +/*N*/ if ( bRef1RowDel && nRow1 <= rRef.Ref1.nRow && +/*N*/ rRef.Ref1.nRow <= nRow1 + nDy ) +/*N*/ rRef.Ref1.SetRowDeleted( FALSE ); +/*N*/ if ( bRef2RowDel && nRow1 <= rRef.Ref2.nRow && +/*N*/ rRef.Ref2.nRow <= nRow1 + nDy ) +/*N*/ rRef.Ref2.SetRowDeleted( FALSE ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( bRef1RowDel ) +/*N*/ rRef.Ref1.SetRowDeleted( TRUE ); +/*N*/ if ( bRef2RowDel ) +/*N*/ rRef.Ref2.SetRowDeleted( TRUE ); +/*N*/ } +/*N*/ } +/*N*/ if ( bExp ) +/*N*/ { +/*N*/ Expand( rRef.Ref1.nRow, rRef.Ref2.nRow, nRow1, nDy ); +/*N*/ eRet = UR_UPDATED; +/*N*/ } +/*N*/ } +/*N*/ if( nDz && +/*N*/ ((rRef.Ref1.nCol >= nCol1 +/*N*/ && rRef.Ref2.nCol <= nCol2) || (bRef1ColDel || bRef2ColDel)) +/*N*/ && +/*N*/ ((rRef.Ref1.nRow >= nRow1 +/*N*/ && rRef.Ref2.nRow <= nRow2) || (bRef1RowDel || bRef2RowDel)) +/*N*/ ) +/*N*/ { +/*N*/ BOOL bExp = (bExpand && !bInDeleteUndo && IsExpand( rRef.Ref1.nTab, +/*N*/ rRef.Ref2.nTab, nTab1, nDz )); +/*N*/ short nMaxTab = (short) pDoc->GetTableCount() - 1; +/*N*/ if ( lcl_MoveRefPart( rRef.Ref1.nTab, bRef1TabDel, +/*N*/ rRef.Ref2.nTab, bRef2TabDel, +/*N*/ nTab1, nTab2, nDz, nMaxTab ) ) +/*N*/ { +/*N*/ eRet = UR_UPDATED; +/*N*/ if ( bInDeleteUndo && (bRef1TabDel || bRef2TabDel) ) +/*N*/ { +/*N*/ if ( bRef1TabDel && nTab1 <= rRef.Ref1.nTab && +/*N*/ rRef.Ref1.nTab <= nTab1 + nDz ) +/*N*/ rRef.Ref1.SetTabDeleted( FALSE ); +/*N*/ if ( bRef2TabDel && nTab1 <= rRef.Ref2.nTab && +/*N*/ rRef.Ref2.nTab <= nTab1 + nDz ) +/*N*/ rRef.Ref2.SetTabDeleted( FALSE ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( bRef1TabDel ) +/*N*/ rRef.Ref1.SetTabDeleted( TRUE ); +/*N*/ if ( bRef2TabDel ) +/*N*/ rRef.Ref2.SetTabDeleted( TRUE ); +/*N*/ } +/*N*/ } +/*N*/ if ( bExp ) +/*N*/ { +/*N*/ Expand( rRef.Ref1.nTab, rRef.Ref2.nTab, nTab1, nDz ); +/*N*/ eRet = UR_UPDATED; +/*N*/ } +/*N*/ } +/*N*/ if ( eRet == UR_NOTHING ) +/*N*/ { +/*N*/ if (oldCol1 != rRef.Ref1.nCol +/*N*/ || oldRow1 != rRef.Ref1.nRow +/*N*/ || oldTab1 != rRef.Ref1.nTab +/*N*/ || oldCol2 != rRef.Ref2.nCol +/*N*/ || oldRow2 != rRef.Ref2.nRow +/*N*/ || oldTab2 != rRef.Ref2.nTab +/*N*/ ) +/*N*/ eRet = UR_UPDATED; +/*N*/ } +/*N*/ rRef.CalcRelFromAbs( rPos ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( eMode == URM_MOVE ) +/*N*/ { +/*N*/ if ( rRef.Ref1.nCol >= nCol1-nDx +/*N*/ && rRef.Ref1.nRow >= nRow1-nDy +/*N*/ && rRef.Ref1.nTab >= nTab1-nDz +/*N*/ && rRef.Ref2.nCol <= nCol2-nDx +/*N*/ && rRef.Ref2.nRow <= nRow2-nDy +/*N*/ && rRef.Ref2.nTab <= nTab2-nDz ) +/*N*/ { +/*N*/ eRet = Move( pDoc, rPos, nDx, nDy, nDz, rRef, FALSE, TRUE ); // immer verschieben +/*N*/ } +/*N*/ else if ( nDz && r.In( rPos ) ) +/*N*/ { +/*N*/ rRef.Ref1.SetFlag3D( TRUE ); +/*N*/ rRef.Ref2.SetFlag3D( TRUE ); +/*N*/ eRet = UR_UPDATED; +/*N*/ rRef.CalcRelFromAbs( rPos ); +/*N*/ } +/*N*/ else +/*N*/ rRef.CalcRelFromAbs( rPos ); +/*N*/ } +/*N*/ else if( eMode == URM_COPY && r.In( rPos ) ) +/*N*/ eRet = Move( pDoc, rPos, nDx, nDy, nDz, rRef, FALSE, FALSE ); // nur relative +/*N*/ // sollte nicht mehr verwendet werden muessen +/*N*/ else +/*N*/ rRef.CalcRelFromAbs( rPos ); +/*N*/ } +/*N*/ return eRet; +/*N*/ } + +// vor dem Aufruf muessen die Abs-Refs aktualisiert werden! +/*N*/ ScRefUpdateRes ScRefUpdate::Move( ScDocument* pDoc, const ScAddress& rPos, +/*N*/ short nDx, short nDy, short nDz, +/*N*/ ComplRefData& rRef, BOOL bWrap, BOOL bAbsolute ) +/*N*/ { +/*N*/ ScRefUpdateRes eRet = UR_NOTHING; +/*N*/ +/*N*/ USHORT oldCol1 = rRef.Ref1.nCol; +/*N*/ USHORT oldRow1 = rRef.Ref1.nRow; +/*N*/ USHORT oldTab1 = rRef.Ref1.nTab; +/*N*/ USHORT oldCol2 = rRef.Ref2.nCol; +/*N*/ USHORT oldRow2 = rRef.Ref2.nRow; +/*N*/ USHORT oldTab2 = rRef.Ref2.nTab; +/*N*/ +/*N*/ BOOL bCut1, bCut2; +/*N*/ if ( nDx ) +/*N*/ { +/*N*/ bCut1 = bCut2 = FALSE; +/*N*/ if( bAbsolute || rRef.Ref1.IsColRel() ) +/*N*/ { +/*N*/ if( bWrap ) +/*N*/ lcl_MoveItWrap( (short&) rRef.Ref1.nCol, nDx, MAXCOL ); +/*N*/ else +/*N*/ bCut1 = lcl_MoveItCut( (short&) rRef.Ref1.nCol, nDx, MAXCOL ); +/*N*/ } +/*N*/ if( bAbsolute || rRef.Ref2.IsColRel() ) +/*N*/ { +/*N*/ if( bWrap ) +/*N*/ lcl_MoveItWrap( (short&) rRef.Ref2.nCol, nDx, MAXCOL ); +/*N*/ else +/*N*/ bCut2 = lcl_MoveItCut( (short&) rRef.Ref2.nCol, nDx, MAXCOL ); +/*N*/ } +/*N*/ if ( bCut1 || bCut2 ) +/*N*/ eRet = UR_UPDATED; +/*N*/ if ( bCut1 && bCut2 ) +/*N*/ { +/*N*/ rRef.Ref1.SetColDeleted( TRUE ); +/*N*/ rRef.Ref2.SetColDeleted( TRUE ); +/*N*/ } +/*N*/ } +/*N*/ if ( nDy ) +/*N*/ { +/*N*/ bCut1 = bCut2 = FALSE; +/*N*/ if( bAbsolute || rRef.Ref1.IsRowRel() ) +/*N*/ { +/*N*/ if( bWrap ) +/*N*/ lcl_MoveItWrap( (short&) rRef.Ref1.nRow, nDy, MAXROW ); +/*N*/ else +/*N*/ bCut1 = lcl_MoveItCut( (short&) rRef.Ref1.nRow, nDy, MAXROW ); +/*N*/ } +/*N*/ if( bAbsolute || rRef.Ref2.IsRowRel() ) +/*N*/ { +/*N*/ if( bWrap ) +/*N*/ lcl_MoveItWrap( (short&) rRef.Ref2.nRow, nDy, MAXROW ); +/*N*/ else +/*N*/ bCut2 = lcl_MoveItCut( (short&) rRef.Ref2.nRow, nDy, MAXROW ); +/*N*/ } +/*N*/ if ( bCut1 || bCut2 ) +/*N*/ eRet = UR_UPDATED; +/*N*/ if ( bCut1 && bCut2 ) +/*N*/ { +/*N*/ rRef.Ref1.SetRowDeleted( TRUE ); +/*N*/ rRef.Ref2.SetRowDeleted( TRUE ); +/*N*/ } +/*N*/ } +/*N*/ if ( nDz ) +/*N*/ { +/*N*/ bCut1 = bCut2 = FALSE; +/*N*/ short nMaxTab = (short) pDoc->GetTableCount() - 1; +/*N*/ if( bAbsolute || rRef.Ref1.IsTabRel() ) +/*N*/ { +/*N*/ if( bWrap ) +/*N*/ lcl_MoveItWrap( (short&) rRef.Ref1.nTab, nDz, nMaxTab ); +/*N*/ else +/*N*/ bCut1 = lcl_MoveItCut( (short&) rRef.Ref1.nTab, nDz, nMaxTab ); +/*N*/ rRef.Ref1.SetFlag3D( rPos.Tab() != rRef.Ref1.nTab ); +/*N*/ } +/*N*/ if( bAbsolute || rRef.Ref2.IsTabRel() ) +/*N*/ { +/*N*/ if( bWrap ) +/*N*/ lcl_MoveItWrap( (short&) rRef.Ref2.nTab, nDz, nMaxTab ); +/*N*/ else +/*N*/ bCut2 = lcl_MoveItCut( (short&) rRef.Ref2.nTab, nDz, nMaxTab ); +/*N*/ rRef.Ref2.SetFlag3D( rPos.Tab() != rRef.Ref2.nTab ); +/*N*/ } +/*N*/ if ( bCut1 || bCut2 ) +/*N*/ eRet = UR_UPDATED; +/*N*/ if ( bCut1 && bCut2 ) +/*N*/ { +/*N*/ rRef.Ref1.SetTabDeleted( TRUE ); +/*N*/ rRef.Ref2.SetTabDeleted( TRUE ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( eRet == UR_NOTHING ) +/*N*/ { +/*N*/ if (oldCol1 != rRef.Ref1.nCol +/*N*/ || oldRow1 != rRef.Ref1.nRow +/*N*/ || oldTab1 != rRef.Ref1.nTab +/*N*/ || oldCol2 != rRef.Ref2.nCol +/*N*/ || oldRow2 != rRef.Ref2.nRow +/*N*/ || oldTab2 != rRef.Ref2.nTab +/*N*/ ) +/*N*/ eRet = UR_UPDATED; +/*N*/ } +/*N*/ if ( bWrap && eRet != UR_NOTHING ) +/*N*/ rRef.PutInOrder(); +/*N*/ rRef.CalcRelFromAbs( rPos ); +/*N*/ return eRet; +/*N*/ } + +/*N*/ void ScRefUpdate::MoveRelWrap( ScDocument* pDoc, const ScAddress& rPos, +/*N*/ ComplRefData& rRef ) +/*N*/ { +/*N*/ if( rRef.Ref1.IsColRel() ) +/*N*/ { +/*N*/ rRef.Ref1.nCol = rRef.Ref1.nRelCol + rPos.Col(); +/*N*/ lcl_MoveItWrap( (short&) rRef.Ref1.nCol, 0, MAXCOL ); +/*N*/ } +/*N*/ if( rRef.Ref2.IsColRel() ) +/*N*/ { +/*N*/ rRef.Ref2.nCol = rRef.Ref2.nRelCol + rPos.Col(); +/*N*/ lcl_MoveItWrap( (short&) rRef.Ref2.nCol, 0, MAXCOL ); +/*N*/ } +/*N*/ if( rRef.Ref1.IsRowRel() ) +/*N*/ { +/*N*/ rRef.Ref1.nRow = rRef.Ref1.nRelRow + rPos.Row(); +/*N*/ lcl_MoveItWrap( (short&) rRef.Ref1.nRow, 0, MAXROW ); +/*N*/ } +/*N*/ if( rRef.Ref2.IsRowRel() ) +/*N*/ { +/*N*/ rRef.Ref2.nRow = rRef.Ref2.nRelRow + rPos.Row(); +/*N*/ lcl_MoveItWrap( (short&) rRef.Ref2.nRow, 0, MAXROW ); +/*N*/ } +/*?*/ short nMaxTab = (short) pDoc->GetTableCount() - 1; +/*?*/ if( rRef.Ref1.IsTabRel() ) +/*N*/ { +/*N*/ rRef.Ref1.nTab = rRef.Ref1.nRelTab + rPos.Tab(); +/*N*/ lcl_MoveItWrap( (short&) rRef.Ref1.nTab, 0, nMaxTab ); +/*N*/ } +/*N*/ if( rRef.Ref2.IsTabRel() ) +/*N*/ { +/*N*/ rRef.Ref2.nTab = rRef.Ref2.nRelTab + rPos.Tab(); +/*N*/ lcl_MoveItWrap( (short&) rRef.Ref2.nTab, 0, nMaxTab ); +/*N*/ } +/*N*/ rRef.PutInOrder(); +/*N*/ rRef.CalcRelFromAbs( rPos ); +/*N*/ } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_scmatrix.cxx b/binfilter/bf_sc/source/core/tool/sc_scmatrix.cxx new file mode 100644 index 000000000000..1c429d542438 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_scmatrix.cxx @@ -0,0 +1,565 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +//------------------------------------------------------------------------ + +#include <tools/debug.hxx> +#include <math.h> + +#include "scmatrix.hxx" + +#include <rtl/math.hxx> +namespace binfilter { + +//------------------------------------------------------------------------ + +/*N*/ void ScMatrix::CreateMatrix(USHORT nC, USHORT nR) // nur fuer ctor +/*N*/ { +/*N*/ nAnzCol = nC; +/*N*/ nAnzRow = nR; +/*N*/ ULONG nCount = (ULONG) nAnzCol * nAnzRow; +/*N*/ if ( !nCount || nCount > GetElementsMax() ) +/*N*/ { +/*N*/ DBG_ERRORFILE("ScMatrix::CreateMatrix: dimension error"); +/*N*/ nAnzCol = nAnzRow = 1; +/*N*/ pMat = new MatValue[1]; +/*N*/ } +/*N*/ else +/*N*/ pMat = new MatValue[nCount]; +/*N*/ bIsString = NULL; +/*N*/ } + +/*N*/ ScMatrix::~ScMatrix() +/*N*/ { +/*N*/ DeleteIsString(); +/*N*/ delete [] pMat; +/*N*/ } + +/*N*/ ScMatrix* ScMatrix::Clone() const +/*N*/ { +/*N*/ ScMatrix* pScMat = new ScMatrix(nAnzCol, nAnzRow); +/*N*/ MatCopy(*pScMat); +/*N*/ return pScMat; +/*N*/ } + +// +// File format: USHORT columns, USHORT rows, (columns*rows) entries: +// BYTE type ( CELLTYPE_NONE, CELLTYPE_VALUE, CELLTYPE_STRING ); nothing, double or String +// + +/*N*/ ScMatrix::ScMatrix(SvStream& rStream) +/*N*/ { +/*N*/ USHORT nC, nR; +/*N*/ +/*N*/ rStream >> nC; +/*N*/ rStream >> nR; +/*N*/ +/*N*/ CreateMatrix(nC, nR); +/*N*/ DBG_ASSERT( pMat, "pMat == NULL" ); +/*N*/ +/*N*/ String aMatStr; +/*N*/ double fVal; +/*N*/ rtl_TextEncoding eCharSet = rStream.GetStreamCharSet(); +/*N*/ ULONG nCount = (ULONG) nAnzCol * nAnzRow; +/*N*/ ULONG nReadCount = (ULONG) nC * nR; +/*N*/ for (ULONG i=0; i<nReadCount; i++) +/*N*/ { +/*N*/ BYTE nType; +/*N*/ rStream >> nType; +/*N*/ if ( nType == CELLTYPE_VALUE ) +/*N*/ { +/*N*/ if ( i < nCount ) +/*N*/ rStream >> pMat[i].fVal; +/*N*/ else +/*N*/ rStream >> fVal; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // For unknown types read and forget string (upwards compatibility) +/*N*/ +/*N*/ if ( nType != CELLTYPE_NONE ) +/*N*/ rStream.ReadByteString( aMatStr, eCharSet ); +/*N*/ +/*N*/ if ( i < nCount ) +/*N*/ { +/*N*/ if (!bIsString) +/*N*/ ResetIsString(); // init string flags +/*N*/ bIsString[i] = ( nType == CELLTYPE_NONE ? SC_MATVAL_EMPTY : SC_MATVAL_STRING ); +/*N*/ +/*N*/ if ( nType == CELLTYPE_STRING ) +/*N*/ pMat[i].pS = new String(aMatStr); +/*N*/ else +/*N*/ pMat[i].pS = NULL; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void ScMatrix::Store(SvStream& rStream) const +/*N*/ { +/*N*/ ULONG nCount = (ULONG) nAnzCol * nAnzRow; +/*N*/ // Don't store matrix with more than USHORT max elements, old versions +/*N*/ // might get confused in loops for(USHORT i=0; i<nC*nR; i++) +/*N*/ if ( !pMat || nCount > ((USHORT)(~0)) ) +/*N*/ { +/*N*/ DBG_ASSERT( pMat, "ScMatrix::Store: pMat == NULL" ); +/*N*/ // We can't store a 0 dimension because old versions rely on some +/*N*/ // matrix being present, e.g. DDE link results, and old versions didn't +/*N*/ // create a matrix if dimension was 0. Store an error result. +/*N*/ rStream << (USHORT) 1; +/*N*/ rStream << (USHORT) 1; +/*N*/ rStream << (BYTE) CELLTYPE_VALUE; +/*N*/ double fVal; +/*N*/ ::rtl::math::setNan( &fVal ); +/*N*/ rStream << fVal; +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ rStream << nAnzCol; +/*N*/ rStream << nAnzRow; +/*N*/ +/*N*/ String aMatStr; +/*N*/ rtl_TextEncoding eCharSet = rStream.GetStreamCharSet(); +/*N*/ for (ULONG i=0; i<nCount; i++) +/*N*/ { +/*N*/ BYTE nType = CELLTYPE_VALUE; +/*N*/ if ( bIsString && bIsString[i] ) +/*N*/ { +/*N*/ if ( pMat[i].pS ) +/*N*/ aMatStr = *pMat[i].pS; +/*N*/ else +/*N*/ aMatStr.Erase(); +/*N*/ +/*N*/ if ( bIsString[i] == SC_MATVAL_STRING ) +/*N*/ nType = CELLTYPE_STRING; +/*N*/ else +/*N*/ nType = CELLTYPE_NONE; +/*N*/ } +/*N*/ rStream << nType; +/*N*/ if ( nType == CELLTYPE_VALUE ) +/*N*/ rStream << pMat[i].fVal; +/*N*/ else if ( nType == CELLTYPE_STRING ) +/*N*/ rStream.WriteByteString( aMatStr, eCharSet ); +/*N*/ } +/*N*/ } + +/*N*/ void ScMatrix::ResetIsString() +/*N*/ { +/*N*/ ULONG nCount = (ULONG) nAnzCol * nAnzRow; +/*N*/ if (bIsString) +/*N*/ { +/*N*/ for (ULONG i = 0; i < nCount; i++) +/*N*/ { +/*N*/ if ( bIsString[i] ) +/*N*/ delete pMat[i].pS; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ bIsString = new BYTE[nCount]; +/*N*/ memset( bIsString, 0, nCount * sizeof( BYTE ) ); +/*N*/ } + +/*N*/ void ScMatrix::DeleteIsString() +/*N*/ { +/*N*/ if ( bIsString ) +/*N*/ { +/*?*/ ULONG nCount = (ULONG) nAnzCol * nAnzRow; +/*?*/ for ( ULONG i = 0; i < nCount; i++ ) +/*?*/ { +/*?*/ if ( bIsString[i] ) +/*?*/ delete pMat[i].pS; +/*?*/ } +/*?*/ delete [] bIsString; +/*?*/ bIsString = NULL; +/*N*/ } +/*N*/ } + +/*N*/ void ScMatrix::PutDouble(double fVal, USHORT nC, USHORT nR) +/*N*/ { +/*N*/ if (nC < nAnzCol && nR < nAnzRow) +/*N*/ PutDouble( fVal, (ULONG) nC * nAnzRow + nR ); +/*N*/ else +/*N*/ DBG_ERRORFILE("ScMatrix::PutDouble: dimension error"); +/*N*/ } + + + +/*N*/ void ScMatrix::PutString(const String& rStr, USHORT nC, USHORT nR) +/*N*/ { +/*N*/ if (nC < nAnzCol && nR < nAnzRow) +/*N*/ PutString( rStr, (ULONG) nC * nAnzRow + nR ); +/*N*/ else +/*N*/ DBG_ERRORFILE("ScMatrix::PutString: dimension error"); +/*N*/ } + +/*N*/ void ScMatrix::PutString(const String& rStr, ULONG nIndex) +/*N*/ { +/*N*/ if (bIsString == NULL) +/*N*/ ResetIsString(); +/*N*/ if ( bIsString[nIndex] && pMat[nIndex].pS ) +/*N*/ *(pMat[nIndex].pS) = rStr; +/*N*/ else +/*N*/ pMat[nIndex].pS = new String(rStr); +/*N*/ bIsString[nIndex] = SC_MATVAL_STRING; +/*N*/ } + +/*N*/ void ScMatrix::PutStringEntry( const String* pStr, BYTE bFlag, ULONG nIndex ) +/*N*/ { +/*N*/ DBG_ASSERT( bFlag, "ScMatrix::PutStringEntry: bFlag == 0" ); +/*N*/ if (bIsString == NULL) +/*N*/ ResetIsString(); +/*N*/ if ( bIsString[nIndex] && pMat[nIndex].pS ) +/*N*/ { +/*N*/ if ( pStr ) +/*N*/ *(pMat[nIndex].pS) = *pStr; +/*N*/ else +/*N*/ pMat[nIndex].pS->Erase(); +/*N*/ } +/*N*/ else +/*N*/ pMat[nIndex].pS = (pStr ? new String(*pStr) : NULL); +/*N*/ bIsString[nIndex] = bFlag; +/*N*/ } + +/*N*/ void ScMatrix::PutEmpty(USHORT nC, USHORT nR) +/*N*/ { +/*N*/ if (nC < nAnzCol && nR < nAnzRow) +/*N*/ PutEmpty( (ULONG) nC * nAnzRow + nR ); +/*N*/ else +/*N*/ DBG_ERRORFILE("ScMatrix::PutString: dimension error"); +/*N*/ } + +/*N*/ void ScMatrix::PutEmpty(ULONG nIndex) +/*N*/ { +/*N*/ if (bIsString == NULL) +/*N*/ ResetIsString(); +/*N*/ if ( bIsString[nIndex] && pMat[nIndex].pS ) +/*N*/ delete pMat[nIndex].pS; +/*N*/ bIsString[nIndex] = SC_MATVAL_EMPTY; +/*N*/ pMat[nIndex].pS = NULL; +/*N*/ pMat[nIndex].fVal = 0.0; +/*N*/ } + +/*N*/ double ScMatrix::GetDouble(USHORT nC, USHORT nR) const +/*N*/ { +/*N*/ if (nC < nAnzCol && nR < nAnzRow) +/*N*/ return GetDouble( (ULONG) nC * nAnzRow + nR ); +/*N*/ else +/*N*/ { +/*N*/ DBG_ERRORFILE("ScMatrix::GetDouble: dimension error"); +/*N*/ return 0.0; +/*N*/ } +/*N*/ } + +/*N*/ const String& ScMatrix::GetString(USHORT nC, USHORT nR) const +/*N*/ { +/*N*/ if (nC < nAnzCol && nR < nAnzRow) +/*N*/ { +/*N*/ ULONG nIndex = (ULONG) nC * nAnzRow + nR; +/*N*/ if ( IsString( nIndex ) ) +/*N*/ return GetString( nIndex ); +/*N*/ else +/*N*/ DBG_ERRORFILE("ScMatrix::GetString: access error, no string"); +/*N*/ } +/*N*/ else +/*N*/ DBG_ERRORFILE("ScMatrix::GetString: dimension error"); +/*N*/ return ScGlobal::GetEmptyString(); +/*N*/ } + +/*N*/ const MatValue* ScMatrix::Get(USHORT nC, USHORT nR, BOOL& bString) const +/*N*/ { +/*N*/ if (nC < nAnzCol && nR < nAnzRow) +/*N*/ { +/*N*/ ULONG nIndex = (ULONG) nC * nAnzRow + nR; +/*N*/ if (bIsString && bIsString[nIndex]) +/*N*/ bString = TRUE; +/*N*/ else +/*N*/ bString = FALSE; +/*N*/ return &pMat[nIndex]; +/*N*/ } +/*N*/ else +/*N*/ DBG_ERRORFILE("ScMatrix::Get: dimension error"); +/*N*/ return NULL; +/*N*/ } + +/*N*/ void ScMatrix::MatCopy(ScMatrix& mRes) const +/*N*/ { +/*N*/ if (nAnzCol != mRes.nAnzCol || nAnzRow != mRes.nAnzRow) +/*N*/ { +/*N*/ DBG_ERRORFILE("ScMatrix::MatCopy: dimension error"); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if (bIsString) +/*N*/ { +/*N*/ mRes.ResetIsString(); +/*N*/ for (USHORT i = 0; i < nAnzCol; i++) +/*N*/ { +/*N*/ ULONG nStart = (ULONG) i * nAnzRow; +/*N*/ for (USHORT j = 0; j < nAnzRow; j++) +/*N*/ { +/*N*/ if ( bIsString[nStart+j] ) +/*N*/ mRes.PutStringEntry( pMat[nStart+j].pS, +/*N*/ bIsString[nStart+j], nStart+j ); +/*N*/ else +/*N*/ mRes.pMat[nStart+j].fVal = pMat[nStart+j].fVal; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ mRes.DeleteIsString(); +/*N*/ ULONG nCount = (ULONG) nAnzCol * nAnzRow; +/*N*/ for (ULONG i = 0; i < nCount; i++) +/*N*/ mRes.pMat[i].fVal = pMat[i].fVal; +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void ScMatrix::MatTrans(ScMatrix& mRes) const +/*N*/ { +/*N*/ if (nAnzCol != mRes.nAnzRow || nAnzRow != mRes.nAnzCol) +/*N*/ { +/*N*/ DBG_ERRORFILE("ScMatrix::MatTrans: dimension error"); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if (bIsString) +/*N*/ { +/*N*/ mRes.ResetIsString(); +/*N*/ for ( ULONG i = 0; i < nAnzCol; i++ ) +/*N*/ { +/*N*/ ULONG nStart = i * nAnzRow; +/*N*/ for ( ULONG j = 0; j < nAnzRow; j++ ) +/*N*/ { +/*N*/ if ( bIsString[nStart+j] ) +/*N*/ mRes.PutStringEntry( pMat[nStart+j].pS, +/*N*/ bIsString[nStart+j], j*mRes.nAnzRow+i ); +/*N*/ else +/*N*/ mRes.pMat[j*mRes.nAnzRow+i].fVal = pMat[nStart+j].fVal; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ mRes.DeleteIsString(); +/*N*/ for ( ULONG i = 0; i < nAnzCol; i++ ) +/*N*/ { +/*N*/ ULONG nStart = i * nAnzRow; +/*N*/ for ( ULONG j = 0; j < nAnzRow; j++ ) +/*N*/ { +/*N*/ mRes.pMat[j*mRes.nAnzRow+i].fVal = pMat[nStart+j].fVal; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + + +/*N*/ void ScMatrix::FillDouble( double fVal, USHORT nC1, USHORT nR1, +/*N*/ USHORT nC2, USHORT nR2 ) +/*N*/ { +/*N*/ if (nC2 < nAnzCol && nR2 < nAnzRow) +/*N*/ { +/*N*/ if ( nC1 == 0 && nR1 == 0 && nC2 == nAnzCol-1 && nR2 == nAnzRow-1 ) +/*N*/ { +/*N*/ ULONG nEnd = (ULONG) nAnzCol * nAnzRow; +/*N*/ for ( ULONG j=0; j<nEnd; j++ ) +/*N*/ pMat[j].fVal = fVal; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ for ( USHORT i=nC1; i<=nC2; i++ ) +/*N*/ { +/*N*/ ULONG nOff1 = (ULONG) i * nAnzRow + nR1; +/*N*/ ULONG nOff2 = nOff1 + nR2 - nR1; +/*N*/ for ( ULONG j=nOff1; j<=nOff2; j++ ) +/*N*/ pMat[j].fVal = fVal; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ DBG_ERRORFILE("ScMatrix::FillDouble: dimension error"); +/*N*/ } + +/*N*/ void ScMatrix::FillDoubleLowerLeft( double fVal, USHORT nC2 ) +/*N*/ { +/*N*/ if (nC2 < nAnzCol && nC2 < nAnzRow) +/*N*/ { +/*N*/ for ( USHORT i=1; i<=nC2; i++ ) +/*N*/ { +/*N*/ ULONG nOff1 = (ULONG) i * nAnzRow; +/*N*/ ULONG nOff2 = nOff1 + i; +/*N*/ for ( ULONG j=nOff1; j<nOff2; j++ ) +/*N*/ pMat[j].fVal = fVal; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ DBG_ERRORFILE("ScMatrix::FillDoubleLowerLeft: dimension error"); +/*N*/ } + +/*N*/ void ScMatrix::CompareEqual() +/*N*/ { +/*N*/ ULONG n = (ULONG) nAnzCol * nAnzRow; +/*N*/ if ( bIsString ) +/*N*/ { +/*N*/ for ( ULONG j=0; j<n; j++ ) +/*N*/ if ( !bIsString[j]) // else: #WERT! +/*N*/ pMat[j].fVal = (pMat[j].fVal == 0.0); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ for ( ULONG j=0; j<n; j++ ) +/*N*/ pMat[j].fVal = (pMat[j].fVal == 0.0); +/*N*/ } +/*N*/ } + +/*N*/ void ScMatrix::CompareNotEqual() +/*N*/ { +/*N*/ ULONG n = (ULONG) nAnzCol * nAnzRow; +/*N*/ if ( bIsString ) +/*N*/ { +/*N*/ for ( ULONG j=0; j<n; j++ ) +/*N*/ if ( !bIsString[j]) // else: #WERT! +/*N*/ pMat[j].fVal = (pMat[j].fVal != 0.0); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ for ( ULONG j=0; j<n; j++ ) +/*N*/ pMat[j].fVal = (pMat[j].fVal != 0.0); +/*N*/ } +/*N*/ } + +/*N*/ void ScMatrix::CompareLess() +/*N*/ { +/*N*/ ULONG n = (ULONG) nAnzCol * nAnzRow; +/*N*/ if ( bIsString ) +/*N*/ { +/*N*/ for ( ULONG j=0; j<n; j++ ) +/*N*/ if ( !bIsString[j]) // else: #WERT! +/*N*/ pMat[j].fVal = (pMat[j].fVal < 0.0); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ for ( ULONG j=0; j<n; j++ ) +/*N*/ pMat[j].fVal = (pMat[j].fVal < 0.0); +/*N*/ } +/*N*/ } + +/*N*/ void ScMatrix::CompareGreater() +/*N*/ { +/*N*/ ULONG n = (ULONG) nAnzCol * nAnzRow; +/*N*/ if ( bIsString ) +/*N*/ { +/*N*/ for ( ULONG j=0; j<n; j++ ) +/*N*/ if ( !bIsString[j]) // else: #WERT! +/*N*/ pMat[j].fVal = (pMat[j].fVal > 0.0); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ for ( ULONG j=0; j<n; j++ ) +/*N*/ pMat[j].fVal = (pMat[j].fVal > 0.0); +/*N*/ } +/*N*/ } + +/*N*/ void ScMatrix::CompareLessEqual() +/*N*/ { +/*N*/ ULONG n = (ULONG) nAnzCol * nAnzRow; +/*N*/ if ( bIsString ) +/*N*/ { +/*N*/ for ( ULONG j=0; j<n; j++ ) +/*N*/ if ( !bIsString[j]) // else: #WERT! +/*N*/ pMat[j].fVal = (pMat[j].fVal <= 0.0); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ for ( ULONG j=0; j<n; j++ ) +/*N*/ pMat[j].fVal = (pMat[j].fVal <= 0.0); +/*N*/ } +/*N*/ } + +/*N*/ void ScMatrix::CompareGreaterEqual() +/*N*/ { +/*N*/ ULONG n = (ULONG) nAnzCol * nAnzRow; +/*N*/ if ( bIsString ) +/*N*/ { +/*N*/ for ( ULONG j=0; j<n; j++ ) +/*N*/ if ( !bIsString[j]) // else: #WERT! +/*N*/ pMat[j].fVal = (pMat[j].fVal >= 0.0); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ for ( ULONG j=0; j<n; j++ ) +/*N*/ pMat[j].fVal = (pMat[j].fVal >= 0.0); +/*N*/ } +/*N*/ } + +/*N*/ BOOL ScMatrix::And() +/*N*/ { +/*N*/ ULONG n = (ULONG) nAnzCol * nAnzRow; +/*N*/ BOOL bAnd = TRUE; +/*N*/ if ( bIsString ) +/*N*/ { +/*N*/ for ( ULONG j=0; bAnd && j<n; j++ ) +/*N*/ if ( bIsString[j] ) +/*N*/ bAnd = FALSE; // we're assuming a CompareMat +/*N*/ else +/*N*/ bAnd = (pMat[j].fVal != 0.0); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ for ( ULONG j=0; bAnd && j<n; j++ ) +/*N*/ bAnd = (pMat[j].fVal != 0.0); +/*N*/ } +/*N*/ return bAnd; +/*N*/ } + +/*N*/ BOOL ScMatrix::Or() +/*N*/ { +/*N*/ ULONG n = (ULONG) nAnzCol * nAnzRow; +/*N*/ BOOL bOr = FALSE; +/*N*/ if ( bIsString ) +/*N*/ { +/*N*/ for ( ULONG j=0; !bOr && j<n; j++ ) +/*N*/ if ( !bIsString[j] ) +/*N*/ bOr = (pMat[j].fVal != 0.0); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ for ( ULONG j=0; !bOr && j<n; j++ ) +/*N*/ bOr = (pMat[j].fVal != 0.0); +/*N*/ } +/*N*/ return bOr; +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_subtotal.cxx b/binfilter/bf_sc/source/core/tool/sc_subtotal.cxx new file mode 100644 index 000000000000..823141b1012e --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_subtotal.cxx @@ -0,0 +1,144 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef RS6000 + +#include <fptrap.h> +#include <fpxcp.h> + +#elif defined ( MAC ) + +#include <MAC_START.h> +#include <fp.h> +#include <MAC_END.h> + +#endif + + +#include <float.h> +#ifdef SOLARIS +#include <ieeefp.h> +#endif +#include <signal.h> + +#include "subtotal.hxx" +#include "interpre.hxx" +namespace binfilter { + +// STATIC DATA ----------------------------------------------------------- + +jmp_buf SubTotal::aGlobalJumpBuf; + +// ----------------------------------------------------------------------- + +/*N*/ SubTotal::SubTotal() +/*N*/ { +/*N*/ nIndex = 0; //! test fuer Pivot +/*N*/ +/*N*/ nCount = 0; +/*N*/ nCount2 = 0; +/*N*/ nSum = 0.0; +/*N*/ nSumSqr = 0.0; +/*N*/ nMax = -MAXDOUBLE; +/*N*/ nMin = MAXDOUBLE; +/*N*/ nProduct = 1.0; +/*N*/ bSumOk = TRUE; +/*N*/ bSumSqrOk = TRUE; +/*N*/ bProductOk = TRUE; +/*N*/ } + + +/*N*/ SubTotal::~SubTotal() +/*N*/ { +/*N*/ } + + + + +/*N*/ void SubTotal::Update( double nVal ) +/*N*/ { +/*N*/ SAL_MATH_FPEXCEPTIONS_OFF(); +/*N*/ nCount++; +/*N*/ nCount2++; +/*N*/ if (nVal > nMax) nMax = nVal; +/*N*/ if (nVal < nMin) nMin = nVal; +/*N*/ nProgress = 0; +/*N*/ if (bSumOk) nSum += nVal; +/*N*/ nProgress = 1; +/*N*/ if (bProductOk) nProduct *= nVal; +/*N*/ nProgress = 2; +/*N*/ if (bSumSqrOk) nSumSqr += nVal*nVal; +/*N*/ if (!::rtl::math::isFinite(nSum)) +/*N*/ bSumOk = FALSE; +/*N*/ if (!::rtl::math::isFinite(nProduct)) +/*N*/ bProductOk = FALSE; +/*N*/ if (!::rtl::math::isFinite(nSumSqr)) +/*N*/ bSumSqrOk = FALSE; +/*N*/ } + + + + + + + + +/*N*/ BOOL SubTotal::SafePlus(double& fVal1, double fVal2) +/*N*/ { +/*N*/ BOOL bOk = TRUE; +/*N*/ SAL_MATH_FPEXCEPTIONS_OFF(); +/*N*/ fVal1 += fVal2; +/*N*/ if (!::rtl::math::isFinite(fVal1)) +/*N*/ { +/*N*/ bOk = FALSE; +/*N*/ if (fVal2 > 0.0) +/*N*/ fVal1 = DBL_MAX; +/*N*/ else +/*N*/ fVal1 = -DBL_MAX; +/*N*/ } +/*N*/ return bOk; +/*N*/ } + + +/*N*/ BOOL SubTotal::SafeMult(double& fVal1, double fVal2) +/*N*/ { +/*N*/ BOOL bOk = TRUE; +/*N*/ SAL_MATH_FPEXCEPTIONS_OFF(); +/*N*/ fVal1 *= fVal2; +/*N*/ if (!::rtl::math::isFinite(fVal1)) +/*N*/ { +/*N*/ bOk = FALSE; +/*N*/ fVal1 = DBL_MAX; +/*N*/ } +/*N*/ return bOk; +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_token.cxx b/binfilter/bf_sc/source/core/tool/sc_token.cxx new file mode 100644 index 000000000000..fe98c35eb5c6 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_token.cxx @@ -0,0 +1,1819 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// INCLUDE --------------------------------------------------------------- + +#if STLPORT_VERSION<321 +#include <stddef.h> +#else +#include <cstddef> +#endif +#include <string.h> + +#include <tools/debug.hxx> + +#include "compiler.hxx" +#include "rechead.hxx" +namespace binfilter { + +/*N*/ struct ImpTokenIterator +/*N*/ { +/*N*/ ImpTokenIterator* pNext; +/*N*/ ScTokenArray* pArr; +/*N*/ short nPC; +/*N*/ +/*N*/ DECL_FIXEDMEMPOOL_NEWDEL( ImpTokenIterator ); +/*N*/ }; + +// ImpTokenIterator wird je Interpreter angelegt, mehrfache auch durch +// SubCode via ScTokenIterator Push/Pop moeglich +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( ImpTokenIterator, 32, 16 )//STRIP008 ; + +// Align MemPools on 4k boundaries - 64 bytes (4k is a MUST for OS/2) + +// Since RawTokens are temporary for the compiler, don't align on 4k and waste memory. +// ScRawToken size is FixMembers + MAXSTRLEN ~= 264 +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( ScRawToken, 8, 4 )//STRIP008 ; +// Some ScDoubleRawToken, FixMembers + sizeof(double) ~= 16 +/*N*/ const USHORT nMemPoolDoubleRawToken = 0x0400 / sizeof(ScDoubleRawToken); +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( ScDoubleRawToken, nMemPoolDoubleRawToken, nMemPoolDoubleRawToken )//STRIP008 ; + +// Need a whole bunch of ScSingleRefToken +/*N*/ const USHORT nMemPoolSingleRefToken = (0x4000 - 64) / sizeof(ScSingleRefToken); +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( ScSingleRefToken, nMemPoolSingleRefToken, nMemPoolSingleRefToken )//STRIP008 ; +// Need a lot of ScDoubleToken +/*N*/ const USHORT nMemPoolDoubleToken = (0x3000 - 64) / sizeof(ScDoubleToken); +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( ScDoubleToken, nMemPoolDoubleToken, nMemPoolDoubleToken )//STRIP008 ; +// Need a lot of ScByteToken +/*N*/ const USHORT nMemPoolByteToken = (0x3000 - 64) / sizeof(ScByteToken); +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( ScByteToken, nMemPoolByteToken, nMemPoolByteToken )//STRIP008 ; +// Need quite a lot of ScDoubleRefToken +/*N*/ const USHORT nMemPoolDoubleRefToken = (0x2000 - 64) / sizeof(ScDoubleRefToken); +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( ScDoubleRefToken, nMemPoolDoubleRefToken, nMemPoolDoubleRefToken )//STRIP008 ; +// Need several ScStringToken +/*N*/ const USHORT nMemPoolStringToken = (0x1000 - 64) / sizeof(ScStringToken); +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( ScStringToken, nMemPoolStringToken, nMemPoolStringToken )//STRIP008 ; + + +// --- helpers -------------------------------------------------------------- + +/*N*/ inline BOOL lcl_IsReference( OpCode eOp, StackVar eType ) +/*N*/ { +/*N*/ return +/*N*/ (eOp == ocPush && (eType == svSingleRef || eType == svDoubleRef)) +/*N*/ || (eOp == ocColRowNameAuto && eType == svDoubleRef) +/*N*/ || (eOp == ocColRowName && eType == svSingleRef) +/*N*/ || (eOp == ocMatRef && eType == svSingleRef) +/*N*/ ; +/*N*/ } + + +// --- class ScRawToken ----------------------------------------------------- + +/*N*/ xub_StrLen ScRawToken::GetStrLen( const sal_Unicode* pStr ) +/*N*/ { +/*N*/ if ( !pStr ) +/*N*/ return 0; +/*N*/ register const sal_Unicode* p = pStr; +/*N*/ while ( *p ) +/*N*/ p++; +/*N*/ return p - pStr; +/*N*/ } + + +/*N*/ void ScRawToken::SetOpCode( OpCode e ) +/*N*/ { +/*N*/ eOp = e; +/*N*/ if( eOp == ocIf ) +/*N*/ { +/*N*/ eType = svJump; nJump[ 0 ] = 3; // If, Else, Behind +/*N*/ } +/*N*/ else if( eOp == ocChose ) +/*N*/ { +/*N*/ eType = svJump; nJump[ 0 ] = MAXJUMPCOUNT+1; +/*N*/ } +/*N*/ else if( eOp == ocMissing ) +/*N*/ eType = svMissing; +/*N*/ else +/*N*/ eType = svByte, cByte = 0; +/*N*/ nRefCnt = 0; +/*N*/ } + +/*N*/ void ScRawToken::SetString( const sal_Unicode* pStr ) +/*N*/ { +/*N*/ eOp = ocPush; +/*N*/ eType = svString; +/*N*/ if ( pStr ) +/*N*/ { +/*N*/ xub_StrLen nLen = GetStrLen( pStr ) + 1; +/*N*/ if( nLen > MAXSTRLEN ) +/*N*/ nLen = MAXSTRLEN; +/*N*/ memcpy( cStr, pStr, GetStrLenBytes( nLen ) ); +/*N*/ cStr[ nLen-1 ] = 0; +/*N*/ } +/*N*/ else +/*N*/ cStr[0] = 0; +/*N*/ nRefCnt = 0; +/*N*/ } + +/*N*/ void ScRawToken::SetSingleReference( const SingleRefData& rRef ) +/*N*/ { +/*N*/ eOp = ocPush; +/*N*/ eType = svSingleRef; +/*N*/ aRef.Ref1 = +/*N*/ aRef.Ref2 = rRef; +/*N*/ nRefCnt = 0; +/*N*/ } + +/*N*/ void ScRawToken::SetDoubleReference( const ComplRefData& rRef ) +/*N*/ { +/*N*/ eOp = ocPush; +/*N*/ eType = svDoubleRef; +/*N*/ aRef = rRef; +/*N*/ nRefCnt = 0; +/*N*/ } + +/*N*/ void ScRawToken::SetDouble(double rVal) +/*N*/ { +/*N*/ eOp = ocPush; +/*N*/ eType = svDouble; +/*N*/ nValue = rVal; +/*N*/ nRefCnt = 0; +/*N*/ } + +/*N*/ void ScRawToken::SetName( USHORT n ) +/*N*/ { +/*N*/ eOp = ocName; +/*N*/ eType = svIndex; +/*N*/ nIndex = n; +/*N*/ nRefCnt = 0; +/*N*/ } + +/*N*/ void ScRawToken::SetExternal( const sal_Unicode* pStr ) +/*N*/ { +/*N*/ eOp = ocExternal; +/*N*/ eType = svExternal; +/*N*/ xub_StrLen nLen = GetStrLen( pStr ) + 1; +/*N*/ if( nLen >= MAXSTRLEN ) +/*N*/ nLen = MAXSTRLEN-1; +/*N*/ // Platz fuer Byte-Parameter lassen! +/*N*/ memcpy( cStr+1, pStr, GetStrLenBytes( nLen ) ); +/*N*/ cStr[ nLen+1 ] = 0; +/*N*/ nRefCnt = 0; +/*N*/ } + +/*N*/ ScRawToken* ScRawToken::Clone() const +/*N*/ { +/*N*/ ScRawToken* p; +/*N*/ if ( eType == svDouble ) +/*N*/ { +/*N*/ p = (ScRawToken*) new ScDoubleRawToken; +/*N*/ p->eOp = eOp; +/*N*/ p->eType = eType; +/*N*/ p->nValue = nValue; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ USHORT n = offsetof( ScRawToken, cByte ); +/*N*/ switch( eType ) +/*N*/ { +/*N*/ case svByte: n++; break; +/*N*/ case svDouble: n += sizeof(double); break; +/*N*/ case svString: n += GetStrLenBytes( cStr ) + GetStrLenBytes( 1 ); break; +/*N*/ case svSingleRef: +/*N*/ case svDoubleRef: n += sizeof(aRef); break; +/*N*/ case svMatrix: n += sizeof(ScMatrix*); break; +/*N*/ case svIndex: n += sizeof(USHORT); break; +/*N*/ case svJump: n += nJump[ 0 ] * 2 + 2; break; +/*N*/ case svExternal: n += GetStrLenBytes( cStr+1 ) + GetStrLenBytes( 2 ); break; +/*N*/ default: n += *((BYTE*)cStr); // read in unknown! +/*N*/ } +/*N*/ p = (ScRawToken*) new BYTE[ n ]; +/*N*/ memcpy( p, this, n * sizeof(BYTE) ); +/*N*/ } +/*N*/ p->nRefCnt = 0; +/*N*/ p->bRaw = FALSE; +/*N*/ return p; +/*N*/ } + + +/*N*/ ScToken* ScRawToken::CreateToken() const +/*N*/ { +/*N*/ switch ( GetType() ) +/*N*/ { +/*N*/ case svByte : +/*N*/ return new ScByteToken( eOp, cByte ); +/*N*/ break; +/*N*/ case svDouble : +/*N*/ return new ScDoubleToken( eOp, nValue ); +/*N*/ break; +/*N*/ case svString : +/*N*/ return new ScStringToken( eOp, String( cStr ) ); +/*N*/ break; +/*N*/ case svSingleRef : +/*N*/ return new ScSingleRefToken( eOp, aRef.Ref1 ); +/*N*/ break; +/*N*/ case svDoubleRef : +/*N*/ return new ScDoubleRefToken( eOp, aRef ); +/*N*/ break; +/*?*/ case svMatrix : +/*?*/ return new ScMatrixToken( eOp, pMat ); +/*?*/ break; +/*N*/ case svIndex : +/*N*/ return new ScIndexToken( eOp, nIndex ); +/*N*/ break; +/*N*/ case svJump : +/*N*/ return new ScJumpToken( eOp, (short*) nJump ); +/*N*/ break; +/*N*/ case svExternal : +/*N*/ return new ScExternalToken( eOp, cByte, String( cStr+1 ) ); +/*N*/ break; +/*N*/ case svFAP : +/*?*/ return new ScFAPToken( eOp, cByte, NULL ); +/*?*/ break; +/*?*/ case svMissing : +/*?*/ return new ScMissingToken( eOp ); +/*?*/ break; +/*?*/ case svErr : +/*?*/ return new ScErrToken( eOp ); +/*?*/ break; +/*?*/ default: +/*?*/ // read in unknown! +/*?*/ return new ScUnknownToken( eOp, GetType(), (BYTE*) cStr ); +/*N*/ } +/*N*/ } + + +/*N*/ void ScRawToken::Delete() +/*N*/ { +/*N*/ if ( bRaw ) +/*?*/ delete this; // FixedMemPool ScRawToken +/*N*/ else +/*N*/ { // created per Clone +/*N*/ switch ( eType ) +/*N*/ { +/*N*/ case svDouble : +/*N*/ delete (ScDoubleRawToken*) this; // FixedMemPool ScDoubleRawToken +/*N*/ break; +/*N*/ default: +/*N*/ delete [] (BYTE*) this; +/*N*/ } +/*N*/ } +/*N*/ } + + +// --- class ScToken -------------------------------------------------------- + +/*N*/ SingleRefData lcl_ScToken_InitSingleRef() +/*N*/ { +/*N*/ SingleRefData aRef; +/*N*/ aRef.InitAddress( ScAddress() ); +/*N*/ return aRef; +/*N*/ } + +/*N*/ ComplRefData lcl_ScToken_InitDoubleRef() +/*N*/ { +/*N*/ ComplRefData aRef; +/*N*/ aRef.Ref1 = lcl_ScToken_InitSingleRef(); +/*N*/ aRef.Ref2 = aRef.Ref1; +/*N*/ return aRef; +/*N*/ } + +/*N*/ SingleRefData ScToken::aDummySingleRef = lcl_ScToken_InitSingleRef(); +/*N*/ ComplRefData ScToken::aDummyDoubleRef = lcl_ScToken_InitDoubleRef(); +/*N*/ String ScToken::aDummyString; + + +/*N*/ ScToken::~ScToken() +/*N*/ { +/*N*/ } + + +/*N*/ BYTE ScToken::GetParamCount() const +/*N*/ { +/*N*/ if ( eOp <= ocEndDiv && eOp != ocExternal && eOp != ocMacro && +/*N*/ eOp != ocIf && eOp != ocChose && eOp != ocPercentSign ) +/*N*/ return 0; // parameters and specials +/*N*/ // ocIf and ocChose not for FAP, have cByte then +/*N*/ //2do: BOOL parameter whether FAP or not? +/*N*/ else if ( GetByte() ) +/*N*/ return GetByte(); // all functions, also ocExternal and ocMacro +/*N*/ else if ( ocEndDiv < eOp && eOp <= ocEndBinOp ) +/*N*/ return 2; // binary +/*N*/ else if ( (ocEndBinOp < eOp && eOp <= ocEndUnOp) || eOp == ocPercentSign ) +/*N*/ return 1; // unary +/*N*/ else if ( ocEndUnOp < eOp && eOp <= ocEndNoPar ) +/*N*/ return 0; // no parameter +/*N*/ else if ( ocEndNoPar < eOp && eOp <= ocEnd1Par ) +/*N*/ return 1; // one parameter +/*N*/ else +/*N*/ return 0; // all the rest, no Parameter, or +/*N*/ // if so then it should be in cByte +/*N*/ } + + +/*N*/ ScToken* ScToken::Clone() const +/*N*/ { +/*N*/ switch ( GetType() ) +/*N*/ { +/*N*/ case svByte : +/*N*/ return new ScByteToken( *static_cast<const ScByteToken*>(this) ); +/*N*/ break; +/*N*/ case svDouble : +/*N*/ return new ScDoubleToken( *static_cast<const ScDoubleToken*>(this) ); +/*N*/ break; +/*N*/ case svString : +/*N*/ return new ScStringToken( *static_cast<const ScStringToken*>(this) ); +/*N*/ break; +/*N*/ case svSingleRef : +/*N*/ return new ScSingleRefToken( *static_cast<const ScSingleRefToken*>(this) ); +/*N*/ break; +/*N*/ case svDoubleRef : +/*N*/ return new ScDoubleRefToken( *static_cast<const ScDoubleRefToken*>(this) ); +/*N*/ break; +/*?*/ case svMatrix : +/*?*/ return new ScMatrixToken( *static_cast<const ScMatrixToken*>(this) ); +/*?*/ break; +/*?*/ case svIndex : +/*?*/ return new ScIndexToken( *static_cast<const ScIndexToken*>(this) ); +/*?*/ break; +/*N*/ case svJump : +/*N*/ return new ScJumpToken( *static_cast<const ScJumpToken*>(this) ); +/*N*/ break; +/*?*/ case svExternal : +/*?*/ return new ScExternalToken( *static_cast<const ScExternalToken*>(this) ); +/*?*/ break; +/*?*/ case svFAP : +/*?*/ return new ScFAPToken( *static_cast<const ScFAPToken*>(this) ); +/*?*/ break; +/*?*/ case svMissing : +/*?*/ return new ScMissingToken( *static_cast<const ScMissingToken*>(this) ); +/*?*/ break; +/*?*/ case svErr : +/*?*/ return new ScErrToken( *static_cast<const ScErrToken*>(this) ); +/*?*/ break; +/*?*/ default: +/*?*/ // read in unknown! +/*?*/ return new ScUnknownToken( *static_cast<const ScUnknownToken*>(this) ); +/*N*/ } +/*N*/ } + +/*N*/ BOOL ScToken::operator==( const ScToken& rToken ) const +/*N*/ { +/*N*/ // don't compare reference count! +/*N*/ return eOp == rToken.eOp && eType == rToken.eType; +/*N*/ } + + +// TextEqual: if same formula entered (for optimization in sort) +/*N*/ BOOL ScToken::TextEqual( const ScToken& rToken ) const +/*N*/ { +/*N*/ if ( eType == svSingleRef || eType == svDoubleRef ) +/*N*/ { +/*N*/ // in relative Refs only compare relative parts +/*N*/ +/*N*/ if ( eOp != rToken.eOp || eType != rToken.eType ) +/*N*/ return FALSE; +/*N*/ +/*N*/ ComplRefData aTemp1; +/*N*/ if ( eType == svSingleRef ) +/*N*/ { +/*N*/ aTemp1.Ref1 = GetSingleRef(); +/*N*/ aTemp1.Ref2 = aTemp1.Ref1; +/*N*/ } +/*N*/ else +/*N*/ aTemp1 = GetDoubleRef(); +/*N*/ +/*N*/ ComplRefData aTemp2; +/*N*/ if ( rToken.eType == svSingleRef ) +/*N*/ { +/*N*/ aTemp2.Ref1 = rToken.GetSingleRef(); +/*N*/ aTemp2.Ref2 = aTemp2.Ref1; +/*N*/ } +/*N*/ else +/*N*/ aTemp2 = rToken.GetDoubleRef(); +/*N*/ +/*N*/ ScAddress aPos; +/*N*/ aTemp1.SmartRelAbs(aPos); +/*N*/ aTemp2.SmartRelAbs(aPos); +/*N*/ +/*N*/ // memcmp doesn't work because of the alignment byte after bFlags. +/*N*/ // After SmartRelAbs only absolute parts have to be compared. +/*N*/ return aTemp1.Ref1.nCol == aTemp2.Ref1.nCol && +/*N*/ aTemp1.Ref1.nRow == aTemp2.Ref1.nRow && +/*N*/ aTemp1.Ref1.nTab == aTemp2.Ref1.nTab && +/*N*/ aTemp1.Ref1.bFlags == aTemp2.Ref1.bFlags && +/*N*/ aTemp1.Ref2.nCol == aTemp2.Ref2.nCol && +/*N*/ aTemp1.Ref2.nRow == aTemp2.Ref2.nRow && +/*N*/ aTemp1.Ref2.nTab == aTemp2.Ref2.nTab && +/*N*/ aTemp1.Ref2.bFlags == aTemp2.Ref2.bFlags; +/*N*/ } +/*N*/ else +/*N*/ return *this == rToken; // else normal operator== +/*N*/ } + +// --- virtual dummy methods ------------------------------------------------- + +/*N*/ BYTE ScToken::GetByte() const +/*N*/ { +/*N*/ // ok to be called for any derived class +/*N*/ return 0; +/*N*/ } + +/*N*/ void ScToken::SetByte( BYTE n ) +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScToken::SetByte: virtual dummy called" ); +/*N*/ } + +/*N*/ double ScToken::GetDouble() const +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScToken::GetDouble: virtual dummy called" ); +/*N*/ return 0.0; +/*N*/ } + +/*N*/ const String& ScToken::GetString() const +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScToken::GetString: virtual dummy called" ); +/*N*/ return aDummyString; +/*N*/ } + +/*N*/ const SingleRefData& ScToken::GetSingleRef() const +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScToken::GetSingleRef: virtual dummy called" ); +/*N*/ return aDummySingleRef; +/*N*/ } + +/*N*/ SingleRefData& ScToken::GetSingleRef() +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScToken::GetSingleRef: virtual dummy called" ); +/*N*/ return aDummySingleRef; +/*N*/ } + +/*N*/ const ComplRefData& ScToken::GetDoubleRef() const +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScToken::GetDoubleRef: virtual dummy called" ); +/*N*/ return aDummyDoubleRef; +/*N*/ } + +/*N*/ ComplRefData& ScToken::GetDoubleRef() +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScToken::GetDoubleRef: virtual dummy called" ); +/*N*/ return aDummyDoubleRef; +/*N*/ } + +/*N*/ const SingleRefData& ScToken::GetSingleRef2() const +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScToken::GetSingleRef2: virtual dummy called" ); +/*N*/ return aDummySingleRef; +/*N*/ } + +/*N*/ SingleRefData& ScToken::GetSingleRef2() +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScToken::GetSingleRef2: virtual dummy called" ); +/*N*/ return aDummySingleRef; +/*N*/ } + +/*N*/ void ScToken::CalcAbsIfRel( const ScAddress& rPos ) +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScToken::CalcAbsIfRel: virtual dummy called" ); +/*N*/ } + +/*N*/ void ScToken::CalcRelFromAbs( const ScAddress& rPos ) +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScToken::CalcRelFromAbs: virtual dummy called" ); +/*N*/ } + +/*N*/ ScMatrix* ScToken::GetMatrix() const +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScToken::GetMatrix: virtual dummy called" ); +/*N*/ return NULL; +/*N*/ } + +/*N*/ USHORT ScToken::GetIndex() const +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScToken::GetIndex: virtual dummy called" ); +/*N*/ return 0; +/*N*/ } + +/*N*/ void ScToken::SetIndex( USHORT n ) +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScToken::SetIndex: virtual dummy called" ); +/*N*/ } + +/*N*/ short* ScToken::GetJump() const +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScToken::GetJump: virtual dummy called" ); +/*N*/ return NULL; +/*N*/ } + +/*N*/ const String& ScToken::GetExternal() const +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScToken::GetExternal: virtual dummy called" ); +/*N*/ return aDummyString; +/*N*/ } + +/*N*/ BYTE* ScToken::GetUnknown() const +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScToken::GetUnknown: virtual dummy called" ); +/*N*/ return NULL; +/*N*/ } + +/*N*/ ScToken* ScToken::GetFAPOrigToken() const +/*N*/ { +/*N*/ DBG_ERRORFILE( "ScToken::GetFAPOrigToken: virtual dummy called" ); +/*N*/ return NULL; +/*N*/ } + + +// real implementations of virtual functions + +/*N*/ BYTE ScByteToken::GetByte() const { return nByte; } +/*N*/ void ScByteToken::SetByte( BYTE n ) { nByte = n; } +/*N*/ BOOL ScByteToken::operator==( const ScToken& r ) const +/*N*/ { +/*N*/ return ScToken::operator==( r ) && nByte == r.GetByte(); +/*N*/ } + + +/*N*/ ScToken* ScFAPToken::GetFAPOrigToken() const { return pOrigToken; } +/*N*/ BOOL ScFAPToken::operator==( const ScToken& r ) const +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); return FALSE;/*N*/ return ScToken::operator==( r ) && pOrigToken == r.GetFAPOrigToken(); +/*N*/ } + + +/*N*/ double ScDoubleToken::GetDouble() const { return fDouble; } +/*N*/ BOOL ScDoubleToken::operator==( const ScToken& r ) const +/*N*/ { +/*N*/ return ScToken::operator==( r ) && fDouble == r.GetDouble(); +/*N*/ } + + +/*N*/ const String& ScStringToken::GetString() const { return aString; } +/*N*/ BOOL ScStringToken::operator==( const ScToken& r ) const +/*N*/ { +/*N*/ return ScToken::operator==( r ) && aString == r.GetString(); +/*N*/ } + + +/*N*/ const SingleRefData& ScSingleRefToken::GetSingleRef() const { return aSingleRef; } +/*N*/ SingleRefData& ScSingleRefToken::GetSingleRef() { return aSingleRef; } +/*N*/ void ScSingleRefToken::CalcAbsIfRel( const ScAddress& rPos ) +/*N*/ { aSingleRef.CalcAbsIfRel( rPos ); } +/*N*/ void ScSingleRefToken::CalcRelFromAbs( const ScAddress& rPos ) +/*N*/ { aSingleRef.CalcRelFromAbs( rPos ); } +/*N*/ BOOL ScSingleRefToken::operator==( const ScToken& r ) const +/*N*/ { +/*N*/ return ScToken::operator==( r ) && aSingleRef == r.GetSingleRef(); +/*N*/ } + + +/*N*/ const SingleRefData& ScDoubleRefToken::GetSingleRef() const { return aDoubleRef.Ref1; } +/*N*/ SingleRefData& ScDoubleRefToken::GetSingleRef() { return aDoubleRef.Ref1; } +/*N*/ const ComplRefData& ScDoubleRefToken::GetDoubleRef() const { return aDoubleRef; } +/*N*/ ComplRefData& ScDoubleRefToken::GetDoubleRef() { return aDoubleRef; } +/*N*/ const SingleRefData& ScDoubleRefToken::GetSingleRef2() const { return aDoubleRef.Ref2; } +/*N*/ SingleRefData& ScDoubleRefToken::GetSingleRef2() { return aDoubleRef.Ref2; } +/*N*/ void ScDoubleRefToken::CalcAbsIfRel( const ScAddress& rPos ) +/*N*/ { aDoubleRef.CalcAbsIfRel( rPos ); } +/*N*/ void ScDoubleRefToken::CalcRelFromAbs( const ScAddress& rPos ) +/*N*/ { aDoubleRef.CalcRelFromAbs( rPos ); } +/*N*/ BOOL ScDoubleRefToken::operator==( const ScToken& r ) const +/*N*/ { +/*N*/ return ScToken::operator==( r ) && aDoubleRef == r.GetDoubleRef(); +/*N*/ } + + +/*N*/ ScMatrix* ScMatrixToken::GetMatrix() const { return pMatrix; } +/*N*/ BOOL ScMatrixToken::operator==( const ScToken& r ) const +/*N*/ { +/*N*/ return ScToken::operator==( r ) && pMatrix == r.GetMatrix(); +/*N*/ } + + +/*N*/ USHORT ScIndexToken::GetIndex() const { return nIndex; } +/*N*/ void ScIndexToken::SetIndex( USHORT n ) { nIndex = n; } +/*N*/ BOOL ScIndexToken::operator==( const ScToken& r ) const +/*N*/ { +/*N*/ return ScToken::operator==( r ) && nIndex == r.GetIndex(); +/*N*/ } + + +/*N*/ short* ScJumpToken::GetJump() const { return pJump; } +/*N*/ BOOL ScJumpToken::operator==( const ScToken& r ) const +/*N*/ { +/*N*/ return ScToken::operator==( r ) && pJump[0] == r.GetJump()[0] && +/*N*/ memcmp( pJump+1, r.GetJump()+1, pJump[0] * sizeof(short) ) == 0; +/*N*/ } +/*N*/ ScJumpToken::~ScJumpToken() +/*N*/ { +/*N*/ delete [] pJump; +/*N*/ } + + +/*N*/ const String& ScExternalToken::GetExternal() const { return aExternal; } +/*N*/ BYTE ScExternalToken::GetByte() const { return nByte; } +/*N*/ void ScExternalToken::SetByte( BYTE n ) { nByte = n; } +/*N*/ BOOL ScExternalToken::operator==( const ScToken& r ) const +/*N*/ { +/*N*/ return ScToken::operator==( r ) && nByte == r.GetByte() && +/*N*/ aExternal == r.GetExternal(); +/*N*/ } + + +/*N*/ double ScMissingToken::GetDouble() const { return 0.0; } +/*N*/ const String& ScMissingToken::GetString() const { return aDummyString; } +/*N*/ BOOL ScMissingToken::operator==( const ScToken& r ) const +/*N*/ { +/*N*/ return ScToken::operator==( r ); +/*N*/ } + + +/*N*/ BOOL ScErrToken::operator==( const ScToken& r ) const +/*N*/ { +/*N*/ return ScToken::operator==( r ); +/*N*/ } + + +/*N*/ BYTE* ScUnknownToken::GetUnknown() const { return pUnknown; } +/*N*/ BOOL ScUnknownToken::operator==( const ScToken& r ) const +/*N*/ { +/*N*/ return ScToken::operator==( r ) && pUnknown[0] == r.GetUnknown()[0] && +/*N*/ memcmp( pUnknown+1, r.GetUnknown()+1, pUnknown[0] * sizeof(BYTE) ) == 0; +/*N*/ } +/*N*/ ScUnknownToken::~ScUnknownToken() +/*N*/ { +/*N*/ delete [] pUnknown; +/*N*/ } + + +////////////////////////////////////////////////////////////////////////// + +/*N*/ ScToken* ScTokenArray::GetNextReference() +/*N*/ { +/*N*/ while( nIndex < nLen ) +/*N*/ { +/*N*/ ScToken* t = pCode[ nIndex++ ]; +/*N*/ switch( t->GetType() ) +/*N*/ { +/*N*/ case svSingleRef: +/*N*/ case svDoubleRef: +/*N*/ return t; +/*N*/ } +/*N*/ } +/*N*/ return NULL; +/*N*/ } + +/*N*/ ScToken* ScTokenArray::GetNextReferenceRPN() +/*N*/ { +/*N*/ while( nIndex < nRPN ) +/*N*/ { +/*N*/ ScToken* t = pRPN[ nIndex++ ]; +/*N*/ switch( t->GetType() ) +/*N*/ { +/*N*/ case svSingleRef: +/*N*/ case svDoubleRef: +/*N*/ return t; +/*N*/ } +/*N*/ } +/*N*/ return NULL; +/*N*/ } + +/*N*/ ScToken* ScTokenArray::GetNextReferenceOrName() +/*N*/ { +/*N*/ for( ScToken* t = Next(); t; t = Next() ) +/*N*/ { +/*N*/ switch( t->GetType() ) +/*N*/ { +/*N*/ case svSingleRef: +/*N*/ case svDoubleRef: +/*N*/ case svIndex: +/*N*/ return t; +/*N*/ } +/*N*/ } +/*N*/ return NULL; +/*N*/ } + +/*N*/ ScToken* ScTokenArray::GetNextOpCodeRPN( OpCode eOp ) +/*N*/ { +/*N*/ while( nIndex < nRPN ) +/*N*/ { +/*?*/ ScToken* t = pRPN[ nIndex++ ]; +/*?*/ if ( t->GetOpCode() == eOp ) +/*?*/ return t; +/*N*/ } +/*N*/ return NULL; +/*N*/ } + +/*N*/ ScToken* ScTokenArray::Next() +/*N*/ { +/*N*/ if( pCode && nIndex < nLen ) +/*N*/ return pCode[ nIndex++ ]; +/*N*/ else +/*N*/ return NULL; +/*N*/ } + +/*N*/ ScToken* ScTokenArray::NextRPN() +/*N*/ { +/*N*/ if( pRPN && nIndex < nRPN ) +/*N*/ return pRPN[ nIndex++ ]; +/*N*/ else +/*N*/ return NULL; +/*N*/ } + +/*N*/ void ScTokenArray::DelRPN() +/*N*/ { +/*N*/ if( nRPN ) +/*N*/ { +/*N*/ ScToken** p = pRPN; +/*N*/ for( USHORT i = 0; i < nRPN; i++ ) +/*N*/ { +/*N*/ (*p++)->DecRef(); +/*N*/ } +/*N*/ delete [] pRPN; +/*N*/ } +/*N*/ pRPN = NULL; +/*N*/ nRPN = nIndex = 0; +/*N*/ } + +/*N*/ ScToken* ScTokenArray::PeekNext() +/*N*/ { +/*N*/ if( pCode && nIndex < nLen ) +/*N*/ return pCode[ nIndex ]; +/*N*/ else +/*N*/ return NULL; +/*N*/ } + +/*N*/ ScToken* ScTokenArray::PeekNextNoSpaces() +/*N*/ { +/*N*/ if( pCode && nIndex < nLen ) +/*N*/ { +/*N*/ USHORT j = nIndex; +/*N*/ while ( pCode[j]->GetOpCode() == ocSpaces && j < nLen ) +/*N*/ j++; +/*N*/ if ( j < nLen ) +/*N*/ return pCode[ j ]; +/*N*/ else +/*N*/ return NULL; +/*N*/ } +/*N*/ else +/*N*/ return NULL; +/*N*/ } + +/*N*/ ScToken* ScTokenArray::PeekPrevNoSpaces() +/*N*/ { +/*N*/ if( pCode && nIndex > 1 ) +/*N*/ { +/*?*/ USHORT j = nIndex - 2; +/*?*/ while ( pCode[j]->GetOpCode() == ocSpaces && j > 0 ) +/*?*/ j--; +/*?*/ if ( j > 0 || pCode[j]->GetOpCode() != ocSpaces ) +/*?*/ return pCode[ j ]; +/*?*/ else +/*?*/ return NULL; +/*N*/ } +/*N*/ else +/*N*/ return NULL; +/*N*/ } + +/*N*/ BOOL ScTokenArray::HasOpCodeRPN( OpCode eOp ) const +/*N*/ { +/*N*/ for ( USHORT j=0; j < nRPN; j++ ) +/*N*/ { +/*N*/ if ( pRPN[j]->GetOpCode() == eOp ) +/*N*/ return TRUE; +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/*N*/ BOOL ScTokenArray::HasNameOrColRowName() const +/*N*/ { +/*N*/ for ( USHORT j=0; j < nLen; j++ ) +/*N*/ { +/*N*/ if( pCode[j]->GetType() == svIndex || pCode[j]->GetOpCode() == ocColRowName ) +/*N*/ return TRUE; +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/*N*/ BOOL ScTokenArray::ImplGetReference( ScRange& rRange, BOOL bValidOnly ) const +/*N*/ { +/*N*/ BOOL bIs = FALSE; +/*N*/ if ( pCode && nLen == 1 ) +/*N*/ { +/*N*/ const ScToken* pToken = pCode[0]; +/*N*/ if ( pToken ) +/*N*/ { +/*N*/ if ( pToken->GetType() == svSingleRef ) +/*N*/ { +/*N*/ const SingleRefData& rRef = ((const ScSingleRefToken*)pToken)->GetSingleRef(); +/*N*/ rRange.aStart = rRange.aEnd = ScAddress( rRef.nCol, rRef.nRow, rRef.nTab ); +/*N*/ bIs = !bValidOnly || !rRef.IsDeleted(); +/*N*/ } +/*N*/ else if ( pToken->GetType() == svDoubleRef ) +/*N*/ { +/*N*/ const ComplRefData& rCompl = ((const ScDoubleRefToken*)pToken)->GetDoubleRef(); +/*N*/ const SingleRefData& rRef1 = rCompl.Ref1; +/*N*/ const SingleRefData& rRef2 = rCompl.Ref2; +/*N*/ rRange.aStart = ScAddress( rRef1.nCol, rRef1.nRow, rRef1.nTab ); +/*N*/ rRange.aEnd = ScAddress( rRef2.nCol, rRef2.nRow, rRef2.nTab ); +/*N*/ bIs = !bValidOnly || (!rRef1.IsDeleted() && !rRef2.IsDeleted()); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return bIs; +/*N*/ } + +/*N*/ BOOL ScTokenArray::IsReference( ScRange& rRange ) const +/*N*/ { +/*N*/ return ImplGetReference( rRange, FALSE ); +/*N*/ } + +/*N*/ inline void lcl_GetAddress( ScAddress& rAddress, const ScToken& rToken ) +/*N*/ { +/*N*/ if ( rToken.GetType() == svSingleRef ) +/*N*/ { +/*N*/ const SingleRefData& rRef = ((const ScSingleRefToken&)rToken).GetSingleRef(); +/*N*/ rAddress.Set( rRef.nCol, rRef.nRow, rRef.nTab ); +/*N*/ } +/*N*/ } + +/*N*/ void ScTokenArray::Load30( SvStream& rStream, const ScAddress& rPos ) +/*N*/ { +/*N*/ Clear(); +/*N*/ ScToken* pToks[ MAXCODE ]; +/*N*/ ScRawToken t; +/*N*/ for( nLen = 0; nLen < MAXCODE; nLen++ ) +/*N*/ { +/*N*/ t.Load30( rStream ); +/*N*/ if( t.GetOpCode() == ocStop ) +/*N*/ break; +/*N*/ else if( t.GetOpCode() == ocPush +/*N*/ && ( t.GetType() == svSingleRef || t.GetType() == svDoubleRef ) ) +/*N*/ { +/*N*/ nRefs++; +/*N*/ t.aRef.CalcRelFromAbs( rPos ); +/*N*/ } +/*N*/ ScToken* p = pToks[ nLen ] = t.CreateToken(); +/*N*/ p->IncRef(); +/*N*/ } +/*N*/ pCode = new ScToken*[ nLen ]; +/*N*/ memcpy( pCode, pToks, nLen * sizeof( ScToken* ) ); +/*N*/ } + +/*N*/ void ScTokenArray::Load( SvStream& rStream, USHORT nVer, const ScAddress& rPos ) +/*N*/ { +/*N*/ Clear(); +/*N*/ // 0x10 - nRefs +/*N*/ // 0x20 - nError +/*N*/ // 0x40 - TokenArray +/*N*/ // 0x80 - CodeArray +/*N*/ BYTE cData; +/*N*/ rStream >> cData; +/*N*/ if( cData & 0x0F ) +/*?*/ rStream.SeekRel( cData & 0x0F ); +/*N*/ if ( nVer < SC_RECALC_MODE_BITS ) +/*N*/ { +/*N*/ BYTE cMode; +/*N*/ rStream >> cMode; +/*N*/ ImportRecalcMode40( (ScRecalcMode40) cMode ); +/*N*/ } +/*N*/ else +/*N*/ rStream >> nMode; +/*N*/ if( cData & 0x10 ) +/*N*/ rStream >> nRefs; +/*N*/ if( cData & 0x20 ) +/*N*/ rStream >> nError; +/*N*/ ScToken* pToks[ MAXCODE ]; +/*N*/ ScToken** pp = pToks; +/*N*/ ScRawToken t; +/*N*/ if( cData & 0x40 ) +/*N*/ { +/*N*/ rStream >> nLen; +/*N*/ for( USHORT i = 0; i < nLen; i++ ) +/*N*/ { +/*N*/ t.Load( rStream, nVer ); +/*N*/ if ( t.GetType() == svSingleRef || t.GetType() == svDoubleRef ) +/*N*/ t.aRef.CalcRelFromAbs( rPos ); +/*N*/ // gespeichert wurde und wird immer absolut +/*N*/ *pp = t.CreateToken(); +/*N*/ (*pp++)->IncRef(); +/*N*/ } +/*N*/ pCode = new ScToken*[ nLen ]; +/*N*/ memcpy( pCode, pToks, nLen * sizeof( ScToken* ) ); +/*N*/ } +/*N*/ pp = pToks; +/*N*/ if( cData & 0x80 ) +/*N*/ { +/*N*/ rStream >> nRPN; +/*N*/ for( USHORT i = 0; i < nRPN; i++, pp++ ) +/*N*/ { +/*N*/ BYTE b1, b2 = 0; +/*N*/ UINT16 nIdx; +/*N*/ rStream >> b1; +/*N*/ // 0xFF - Token folgt +/*N*/ // 0x40-0x7F - untere 6 Bits, 1 Byte mit 8 weiteren Bits +/*N*/ // 0x00-0x3F - Index +/*N*/ if( b1 == 0xFF ) +/*N*/ { +/*N*/ t.Load( rStream, nVer ); +/*N*/ if ( t.GetType() == svSingleRef || t.GetType() == svDoubleRef ) +/*N*/ t.aRef.CalcRelFromAbs( rPos ); +/*N*/ // gespeichert wurde und wird immer absolut +/*N*/ *pp = t.CreateToken(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( b1 & 0x40 ) +/*N*/ { +/*N*/ rStream >> b2; +/*N*/ nIdx = ( b1 & 0x3F ) | ( b2 << 6 ); +/*N*/ } +/*N*/ else +/*N*/ nIdx = b1; +/*N*/ *pp = pCode[ nIdx ]; +/*N*/ } +/*N*/ (*pp)->IncRef(); +/*N*/ // #73616# CONVERT function recalculated on each load +/*N*/ if ( nVer < SC_CONVERT_RECALC_ON_LOAD && (*pp)->GetOpCode() == ocConvert ) +/*N*/ AddRecalcMode( RECALCMODE_ONLOAD ); +/*N*/ } +/*N*/ pRPN = new ScToken*[ nRPN ]; +/*N*/ memcpy( pRPN, pToks, nRPN * sizeof( ScToken* ) ); +/*N*/ // Aeltere Versionen: kein UPN-Array laden +/*N*/ if( nVer < SC_NEWIF ) +/*?*/ DelRPN(); +/*N*/ } +/*N*/ } + +/*N*/ void ScTokenArray::Store( SvStream& rStream, const ScAddress& rPos ) const +/*N*/ { +/*N*/ // 0x10 - nRefs +/*N*/ // 0x20 - nError +/*N*/ // 0x40 - TokenArray +/*N*/ // 0x80 - CodeArray +/*N*/ BYTE cFlags = 0; +/*N*/ if( nRefs ) +/*N*/ cFlags |= 0x10; +/*N*/ if( nError ) +/*N*/ cFlags |= 0x20; +/*N*/ if( nLen ) +/*N*/ cFlags |= 0x40; +/*N*/ if( nRPN ) +/*N*/ cFlags |= 0x80; +/*N*/ rStream << cFlags; +/*N*/ // Hier ggf. Zusatzdaten! +/*N*/ if ( rStream.GetVersion() <= SOFFICE_FILEFORMAT_40 ) +/*N*/ rStream << (BYTE) ExportRecalcMode40(); +/*N*/ else +/*N*/ rStream << (BYTE) nMode; +/*N*/ if( cFlags & 0x10 ) +/*N*/ rStream << (INT16) nRefs; +/*N*/ if( cFlags & 0x20 ) +/*N*/ rStream << (UINT16) nError; +/*N*/ if( cFlags & 0x40 ) +/*N*/ { +/*N*/ rStream << nLen; +/*N*/ ScToken** p = pCode; +/*N*/ for( USHORT i = 0; i < nLen; i++, p++ ) +/*N*/ { +/*N*/ // gespeichert wurde und wird immer absolut +/*N*/ switch ( (*p)->GetType() ) +/*N*/ { +/*N*/ case svSingleRef : +/*N*/ (*p)->GetSingleRef().CalcAbsIfRel( rPos ); +/*N*/ break; +/*N*/ case svDoubleRef : +/*N*/ (*p)->GetDoubleRef().CalcAbsIfRel( rPos ); +/*N*/ break; +/*N*/ } +/*N*/ (*p)->Store( rStream ); +/*N*/ } +/*N*/ } +/*N*/ if( cFlags & 0x80 ) +/*N*/ { +/*N*/ rStream << nRPN; +/*N*/ ScToken** p = pRPN; +/*N*/ for( USHORT i = 0; i < nRPN; i++, p++ ) +/*N*/ { +/*N*/ ScToken* t = *p; +/*N*/ USHORT nIdx = 0xFFFF; +/*N*/ if( t->GetRef() > 1 ) +/*N*/ { +/*N*/ ScToken** p2 = pCode; +/*N*/ for( USHORT j = 0; j < nLen; j++, p2++ ) +/*N*/ { +/*N*/ if( *p2 == t ) +/*N*/ { +/*N*/ nIdx = j; break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ // 0xFF - Token folgt +/*N*/ // 0x40-0x7F - untere 6 Bits, 1 Byte mit 8 weiteren Bits +/*N*/ // 0x00-0x3F - Index +/*N*/ if( nIdx == 0xFFFF ) +/*N*/ { +/*N*/ // gespeichert wurde und wird immer absolut +/*N*/ switch ( t->GetType() ) +/*N*/ { +/*N*/ case svSingleRef : +/*N*/ t->GetSingleRef().CalcAbsIfRel( rPos ); +/*N*/ break; +/*?*/ case svDoubleRef : +/*?*/ t->GetDoubleRef().CalcAbsIfRel( rPos ); +/*?*/ break; +/*N*/ } +/*N*/ rStream << (BYTE) 0xFF; +/*N*/ t->Store( rStream ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( nIdx < 0x40 ) +/*N*/ rStream << (BYTE) nIdx; +/*N*/ else +/*N*/ rStream << (BYTE) ( ( nIdx & 0x3F ) | 0x40 ) +/*N*/ << (BYTE) ( nIdx >> 6 ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +//////////////////////////////////////////////////////////////////////////// + +/*N*/ ScTokenArray::ScTokenArray() +/*N*/ { +/*N*/ pCode = NULL; pRPN = NULL; +/*N*/ nError = nLen = nIndex = nRPN = nRefs = 0; +/*M*/ bReplacedSharedFormula = FALSE; +/*N*/ ClearRecalcMode(); +/*N*/ } + +/*N*/ ScTokenArray::ScTokenArray( const ScTokenArray& rArr ) +/*N*/ { +/*N*/ Assign( rArr ); +/*N*/ } + +/*N*/ ScTokenArray::~ScTokenArray() +/*N*/ { +/*N*/ Clear(); +/*N*/ } + +/*N*/ void ScTokenArray::Assign( const ScTokenArray& r ) +/*N*/ { +/*N*/ nLen = r.nLen; +/*N*/ nRPN = r.nRPN; +/*N*/ nIndex = r.nIndex; +/*N*/ nError = r.nError; +/*N*/ nRefs = r.nRefs; +/*N*/ nMode = r.nMode; +/*M*/ bReplacedSharedFormula = FALSE; +/*N*/ pCode = NULL; +/*N*/ pRPN = NULL; +/*N*/ ScToken** pp; +/*N*/ if( nLen ) +/*N*/ { +/*N*/ pp = pCode = new ScToken*[ nLen ]; +/*N*/ memcpy( pp, r.pCode, nLen * sizeof( ScToken* ) ); +/*N*/ for( USHORT i = 0; i < nLen; i++ ) +/*N*/ (*pp++)->IncRef(); +/*N*/ } +/*N*/ if( nRPN ) +/*N*/ { +/*?*/ pp = pRPN = new ScToken*[ nRPN ]; +/*?*/ memcpy( pp, r.pRPN, nRPN * sizeof( ScToken* ) ); +/*?*/ for( USHORT i = 0; i < nRPN; i++ ) +/*?*/ (*pp++)->IncRef(); +/*N*/ } +/*N*/ } + +/*N*/ ScTokenArray& ScTokenArray::operator=( const ScTokenArray& rArr ) +/*N*/ { +/*N*/ Clear(); +/*N*/ Assign( rArr ); +/*N*/ return *this; +/*N*/ } + +/*N*/ ScTokenArray* ScTokenArray::Clone() const +/*N*/ { +/*N*/ ScTokenArray* p = new ScTokenArray; +/*N*/ p->nLen = nLen; +/*N*/ p->nRPN = nRPN; +/*N*/ p->nRefs = nRefs; +/*N*/ p->nMode = nMode; +/*N*/ p->nError = nError; +/*N*/ ScToken** pp; +/*N*/ if( nLen ) +/*N*/ { +/*N*/ pp = p->pCode = new ScToken*[ nLen ]; +/*N*/ memcpy( pp, pCode, nLen * sizeof( ScToken* ) ); +/*N*/ for( USHORT i = 0; i < nLen; i++, pp++ ) +/*N*/ { +/*N*/ *pp = (*pp)->Clone(); +/*N*/ (*pp)->IncRef(); +/*N*/ } +/*N*/ } +/*N*/ if( nRPN ) +/*N*/ { +/*N*/ pp = p->pRPN = new ScToken*[ nRPN ]; +/*N*/ memcpy( pp, pRPN, nRPN * sizeof( ScToken* ) ); +/*N*/ for( USHORT i = 0; i < nRPN; i++, pp++ ) +/*N*/ { +/*N*/ ScToken* t = *pp; +/*N*/ if( t->GetRef() > 1 ) +/*N*/ { +/*N*/ ScToken** p2 = pCode; +/*N*/ USHORT nIdx = 0xFFFF; +/*N*/ for( USHORT j = 0; j < nLen; j++, p2++ ) +/*N*/ { +/*N*/ if( *p2 == t ) +/*N*/ { +/*N*/ nIdx = j; break; +/*N*/ } +/*N*/ } +/*N*/ if( nIdx == 0xFFFF ) +/*?*/ *pp = t->Clone(); +/*N*/ else +/*N*/ *pp = p->pCode[ nIdx ]; +/*N*/ } +/*N*/ else +/*N*/ *pp = t->Clone(); +/*N*/ (*pp)->IncRef(); +/*N*/ } +/*N*/ } +/*N*/ return p; +/*N*/ } + +/*N*/ void ScTokenArray::Clear() +/*N*/ { +/*N*/ if( nRPN ) DelRPN(); +/*N*/ if( pCode ) +/*N*/ { +/*N*/ ScToken** p = pCode; +/*N*/ for( USHORT i = 0; i < nLen; i++ ) +/*N*/ { +/*N*/ (*p++)->DecRef(); +/*N*/ } +/*N*/ delete [] pCode; +/*N*/ } +/*N*/ pCode = NULL; pRPN = NULL; +/*N*/ nError = nLen = nIndex = nRPN = nRefs = 0; +/*M*/ bReplacedSharedFormula = FALSE; +/*N*/ ClearRecalcMode(); +/*N*/ } + +/*N*/ ScToken* ScTokenArray::AddToken( const ScRawToken& r ) +/*N*/ { +/*N*/ return Add( r.CreateToken() ); +/*N*/ } + +/*N*/ ScToken* ScTokenArray::AddToken( const ScToken& r ) +/*N*/ { +/*N*/ return Add( r.Clone() ); +/*N*/ } + +// Wird auch vom Compiler genutzt. Das Token ist per new angelegt! + +/*N*/ ScToken* ScTokenArray::Add( ScToken* t ) +/*N*/ { +/*N*/ if( !pCode ) +/*N*/ pCode = new ScToken*[ MAXCODE ]; +/*N*/ if( nLen < MAXCODE-1 ) +/*N*/ { +/*N*/ pCode[ nLen++ ] = t; +/*N*/ if( t->GetOpCode() == ocPush +/*N*/ && ( t->GetType() == svSingleRef || t->GetType() == svDoubleRef ) ) +/*N*/ nRefs++; +/*N*/ t->IncRef(); +/*N*/ return t; +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ t->Delete(); +/*?*/ if ( nLen == MAXCODE-1 ) +/*?*/ { +/*?*/ t = new ScByteToken( ocStop ); +/*?*/ pCode[ nLen++ ] = t; +/*?*/ t->IncRef(); +/*?*/ } +/*?*/ return NULL; +/*N*/ } +/*N*/ } + +/*N*/ ScToken* ScTokenArray::AddOpCode( OpCode e ) +/*N*/ { +/*N*/ ScRawToken t; +/*N*/ t.SetOpCode( e ); +/*N*/ return AddToken( t ); +/*N*/ } + +/*N*/ ScToken* ScTokenArray::AddString( const sal_Unicode* pStr ) +/*N*/ { +/*N*/ return AddString( String( pStr ) ); +/*N*/ } + +/*N*/ ScToken* ScTokenArray::AddString( const String& rStr ) +/*N*/ { +/*N*/ return Add( new ScStringToken( rStr ) ); +/*N*/ } + +/*N*/ ScToken* ScTokenArray::AddDouble( double fVal ) +/*N*/ { +/*N*/ return Add( new ScDoubleToken( fVal ) ); +/*N*/ } + +/*N*/ ScToken* ScTokenArray::AddSingleReference( const SingleRefData& rRef ) +/*N*/ { +/*N*/ return Add( new ScSingleRefToken( rRef ) ); +/*N*/ } + +/*N*/ ScToken* ScTokenArray::AddDoubleReference( const ComplRefData& rRef ) +/*N*/ { +/*N*/ return Add( new ScDoubleRefToken( rRef ) ); +/*N*/ } + +/*N*/ ScToken* ScTokenArray::AddExternal( const sal_Unicode* pStr ) +/*N*/ { +/*N*/ return AddExternal( String( pStr ) ); +/*N*/ } + +/*N*/ ScToken* ScTokenArray::AddExternal( const String& rStr ) +/*N*/ { +/*N*/ return Add( new ScExternalToken( ocExternal, rStr ) ); +/*N*/ } + +/*N*/ ScToken* ScTokenArray::AddBad( const String& rStr ) +/*N*/ { +/*N*/ return Add( new ScStringToken( ocBad, rStr ) ); +/*N*/ } + +/*N*/ void ScTokenArray::ImportRecalcMode40( ScRecalcMode40 eMode ) +/*N*/ { +/*N*/ switch ( eMode ) +/*N*/ { +/*N*/ case RC_NORMAL : +/*N*/ nMode = RECALCMODE_NORMAL; +/*N*/ break; +/*?*/ case RC_ALWAYS : +/*?*/ nMode = RECALCMODE_ALWAYS; +/*?*/ break; +/*?*/ case RC_ONLOAD : +/*?*/ nMode = RECALCMODE_ONLOAD; +/*?*/ break; +/*?*/ case RC_ONLOAD_ONCE : +/*?*/ nMode = RECALCMODE_ONLOAD_ONCE; +/*?*/ break; +/*?*/ case RC_FORCED : +/*?*/ nMode = RECALCMODE_NORMAL | RECALCMODE_FORCED; +/*?*/ break; +/*?*/ case RC_ONREFMOVE : +/*?*/ nMode = RECALCMODE_NORMAL | RECALCMODE_ONREFMOVE; +/*?*/ break; +/*?*/ default: +/*?*/ DBG_ERRORFILE( "ScTokenArray::ImportRecalcMode40: unknown ScRecalcMode40" ); +/*?*/ nMode = RECALCMODE_NORMAL; +/*N*/ } +/*N*/ } + + +/*N*/ ScRecalcMode40 ScTokenArray::ExportRecalcMode40() const +/*N*/ { +/*N*/ //! Reihenfolge ist wichtig +/*N*/ if ( nMode & RECALCMODE_ALWAYS ) +/*N*/ return RC_ALWAYS; +/*N*/ if ( nMode & RECALCMODE_ONLOAD ) +/*N*/ return RC_ONLOAD; +/*N*/ if ( nMode & RECALCMODE_FORCED ) +/*N*/ return RC_FORCED; +/*N*/ if ( nMode & RECALCMODE_ONREFMOVE ) +/*N*/ return RC_ONREFMOVE; +/*N*/ // kommt eigentlich nicht vor weil in Calc bereits umgesetzt, +/*N*/ // und woanders gibt es keinen 4.0-Export, deswegen als letztes +/*N*/ if ( nMode & RECALCMODE_ONLOAD_ONCE ) +/*N*/ return RC_ONLOAD_ONCE; +/*N*/ return RC_NORMAL; +/*N*/ } + + +/*N*/ void ScTokenArray::AddRecalcMode( ScRecalcMode nBits ) +/*N*/ { +/*N*/ //! Reihenfolge ist wichtig +/*N*/ if ( nBits & RECALCMODE_ALWAYS ) +/*?*/ SetRecalcModeAlways(); +/*N*/ else if ( !IsRecalcModeAlways() ) +/*N*/ { +/*N*/ if ( nBits & RECALCMODE_ONLOAD ) +/*N*/ SetRecalcModeOnLoad(); +/*N*/ else if ( nBits & RECALCMODE_ONLOAD_ONCE && !IsRecalcModeOnLoad() ) +/*?*/ SetRecalcModeOnLoadOnce(); +/*N*/ } +/*N*/ SetCombinedBitsRecalcMode( nBits ); +/*N*/ } + + +/*N*/ BOOL ScTokenArray::HasMatrixDoubleRefOps() +/*N*/ { +/*N*/ if ( pRPN && nRPN ) +/*N*/ { +/*N*/ // RPN-Interpreter Simulation +/*N*/ // als Ergebnis jeder Funktion wird einfach ein Double angenommen +/*N*/ ScToken** pStack = new ScToken* [nRPN]; +/*N*/ ScToken* pResult = new ScDoubleToken( ocPush, 0.0 ); +/*N*/ short sp = 0; +/*N*/ for ( USHORT j = 0; j < nRPN; j++ ) +/*N*/ { +/*N*/ ScToken* t = pRPN[j]; +/*N*/ OpCode eOp = t->GetOpCode(); +/*N*/ BYTE nParams = t->GetParamCount(); +/*N*/ switch ( eOp ) +/*N*/ { +/*N*/ case ocAdd : +/*N*/ case ocSub : +/*N*/ case ocMul : +/*N*/ case ocDiv : +/*N*/ case ocPow : +/*N*/ case ocPower : +/*N*/ case ocAmpersand : +/*N*/ case ocEqual : +/*N*/ case ocNotEqual : +/*N*/ case ocLess : +/*N*/ case ocGreater : +/*N*/ case ocLessEqual : +/*N*/ case ocGreaterEqual : +/*N*/ { +/*N*/ for ( BYTE k = nParams; k; k-- ) +/*N*/ { +/*N*/ if ( sp >= k && pStack[sp-k]->GetType() == svDoubleRef ) +/*N*/ { +/*?*/ pResult->Delete(); +/*?*/ delete [] pStack; +/*?*/ return TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ if ( eOp == ocPush || lcl_IsReference( eOp, t->GetType() ) ) +/*N*/ pStack[sp++] = t; +/*N*/ else if ( eOp == ocIf || eOp == ocChose ) +/*N*/ { // Jumps ignorieren, vorheriges Result (Condition) poppen +/*N*/ if ( sp ) +/*N*/ --sp; +/*N*/ } +/*N*/ else +/*N*/ { // pop parameters, push result +/*N*/ sp -= nParams; +/*N*/ if ( sp < 0 ) +/*N*/ { +/*N*/ DBG_ERROR( "ScTokenArray::HasMatrixDoubleRefOps: sp < 0" ); +/*N*/ sp = 0; +/*N*/ } +/*N*/ pStack[sp++] = pResult; +/*N*/ } +/*N*/ } +/*N*/ pResult->Delete(); +/*N*/ delete [] pStack; +/*N*/ } +/*N*/ +/*N*/ return FALSE; +/*N*/ } + +/////////////////////////////////////////////////////////////////////////// + +/*N*/ void ScRawToken::Load30( SvStream& rStream ) +/*N*/ { +/*N*/ UINT16 nOp; +/*N*/ BYTE n; +/*N*/ nRefCnt = 0; +/*N*/ rStream >> nOp; +/*N*/ eOp = (OpCode) nOp; +/*N*/ switch( eOp ) +/*N*/ { +/*N*/ case ocIf: +/*?*/ eType = svJump; nJump[ 0 ] = 3; break; // then, else, behind +/*N*/ case ocChose: +/*?*/ eType = svJump; nJump[ 0 ] = MAXJUMPCOUNT+1; break; +/*N*/ case ocPush: +/*N*/ rStream >> n; +/*N*/ eType = (StackVar) n; +/*N*/ switch( eType ) +/*N*/ { +/*N*/ case svByte: +/*?*/ rStream >> cByte; +/*?*/ break; +/*N*/ case svDouble: +/*N*/ rStream >> nValue; +/*N*/ break; +/*N*/ case svString: +/*N*/ { +/*?*/ sal_Char c[ MAXSTRLEN+1 ]; +/*?*/ rStream >> nOp; +/*?*/ if( nOp > MAXSTRLEN-1 ) +/*?*/ { +/*?*/ DBG_ERROR("Dokument huehnerich"); +/*?*/ USHORT nDiff = nOp - (MAXSTRLEN-1); +/*?*/ nOp = MAXSTRLEN-1; +/*?*/ rStream.Read( c, nOp ); +/*?*/ rStream.SeekRel( nDiff ); +/*?*/ } +/*?*/ else +/*?*/ rStream.Read( c, nOp ); +/*?*/ CharSet eSrc = rStream.GetStreamCharSet(); +/*?*/ for ( BYTE j=0; j<nOp; j++ ) +/*?*/ cStr[j] = ByteString::ConvertToUnicode( c[j], eSrc ); +/*?*/ cStr[ nOp ] = 0; +/*?*/ break; +/*N*/ } +/*N*/ case svSingleRef: +/*N*/ { +/*N*/ OldSingleRefBools aBools; +/*N*/ rStream >> aRef.Ref1.nCol +/*N*/ >> aRef.Ref1.nRow +/*N*/ >> aRef.Ref1.nTab +/*N*/ >> aBools.bRelCol +/*N*/ >> aBools.bRelRow +/*N*/ >> aBools.bRelTab +/*N*/ >> aBools.bOldFlag3D; +/*N*/ aRef.Ref1.OldBoolsToNewFlags( aBools ); +/*N*/ aRef.Ref2 = aRef.Ref1; +/*N*/ break; +/*N*/ } +/*N*/ case svDoubleRef: +/*N*/ { +/*N*/ OldSingleRefBools aBools1; +/*N*/ OldSingleRefBools aBools2; +/*N*/ rStream >> aRef.Ref1.nCol +/*N*/ >> aRef.Ref1.nRow +/*N*/ >> aRef.Ref1.nTab +/*N*/ >> aRef.Ref2.nCol +/*N*/ >> aRef.Ref2.nRow +/*N*/ >> aRef.Ref2.nTab +/*N*/ >> aBools1.bRelCol +/*N*/ >> aBools1.bRelRow +/*N*/ >> aBools1.bRelTab +/*N*/ >> aBools2.bRelCol +/*N*/ >> aBools2.bRelRow +/*N*/ >> aBools2.bRelTab +/*N*/ >> aBools1.bOldFlag3D +/*N*/ >> aBools2.bOldFlag3D; +/*N*/ aRef.Ref1.OldBoolsToNewFlags( aBools1 ); +/*N*/ aRef.Ref2.OldBoolsToNewFlags( aBools2 ); +/*N*/ break; +/*N*/ } +/*N*/ default: DBG_ERROR("Unknown Stack Variable"); +/*N*/ break; +/*N*/ } +/*N*/ break; +/*N*/ case ocName: +/*?*/ eType = svIndex; +/*?*/ rStream >> nIndex; +/*?*/ break; +/*?*/ case ocExternal: +/*?*/ { +/*?*/ sal_Char c[ MAXSTRLEN+1 ]; +/*?*/ eType = svExternal; +/*?*/ rStream >> nOp; +/*?*/ // lieber ein rottes Dokument als stack overwrite +/*?*/ if( nOp > MAXSTRLEN-2 ) +/*?*/ { +/*?*/ DBG_ERROR("Dokument huehnerich"); +/*?*/ USHORT nDiff = nOp - (MAXSTRLEN-2); +/*?*/ nOp = MAXSTRLEN-2; +/*?*/ rStream.Read( c, nOp ); +/*?*/ rStream.SeekRel( nDiff ); +/*?*/ } +/*?*/ else +/*?*/ rStream.Read( c, nOp ); +/*?*/ CharSet eSrc = rStream.GetStreamCharSet(); +/*?*/ for ( BYTE j=1; j<nOp; j++ ) +/*?*/ cStr[j] = ByteString::ConvertToUnicode( c[j-1], eSrc ); +/*?*/ cStr[ 0 ] = 0; //! parameter count is what?!? +/*?*/ cStr[ nOp ] = 0; +/*?*/ break; +/*?*/ } +/*N*/ default: +/*N*/ eType = svByte; +/*N*/ cByte = 0; +/*N*/ } +/*N*/ } + +// Bei unbekannten Tokens steht in cStr (k)ein Pascal-String (cStr[0] = Laenge), +// der nur gepuffert wird. cStr[0] = GESAMT-Laenge inkl. [0] !!! + +/*N*/ void ScRawToken::Load( SvStream& rStream, USHORT nVer ) +/*N*/ { +/*N*/ BYTE n; +/*N*/ UINT16 nOp; +/*N*/ USHORT i; +/*N*/ rStream >> nOp >> n; +/*N*/ eOp = (OpCode) nOp; +/*N*/ eType = (StackVar) n; +/*N*/ switch( eType ) +/*N*/ { +/*N*/ case svByte: +/*N*/ rStream >> cByte; +/*N*/ break; +/*N*/ case svDouble: +/*N*/ rStream >> nValue; +/*N*/ break; +/*N*/ case svExternal: +/*N*/ { +/*N*/ sal_Char c[ MAXSTRLEN+1 ]; +/*N*/ rStream >> cByte >> n; +/*N*/ if( n > MAXSTRLEN-2 ) +/*N*/ { +/*?*/ DBG_ERRORFILE( "bad string array boundary" ); +/*?*/ USHORT nDiff = n - (MAXSTRLEN-2); +/*?*/ n = MAXSTRLEN-2; +/*?*/ rStream.Read( c+1, n ); +/*?*/ rStream.SeekRel( nDiff ); +/*N*/ } +/*N*/ else +/*N*/ rStream.Read( c+1, n ); +/*N*/ //! parameter count is in cByte (cStr[0] little endian) +/*N*/ CharSet eSrc = rStream.GetStreamCharSet(); +/*N*/ for ( BYTE j=1; j<n+1; j++ ) +/*N*/ cStr[j] = ByteString::ConvertToUnicode( c[j], eSrc ); +/*N*/ cStr[ n+1 ] = 0; +/*N*/ break; +/*N*/ } +/*N*/ case svString: +/*N*/ { +/*N*/ sal_Char c[ MAXSTRLEN+1 ]; +/*N*/ rStream >> n; +/*N*/ if( n > MAXSTRLEN-1 ) +/*N*/ { +/*?*/ DBG_ERRORFILE( "bad string array boundary" ); +/*?*/ USHORT nDiff = n - (MAXSTRLEN-1); +/*?*/ n = MAXSTRLEN-1; +/*?*/ rStream.Read( c, n ); +/*?*/ rStream.SeekRel( nDiff ); +/*N*/ } +/*N*/ else +/*N*/ rStream.Read( c, n ); +/*N*/ cStr[ n ] = 0; +/*N*/ CharSet eSrc = rStream.GetStreamCharSet(); +/*N*/ for ( BYTE j=0; j<n; j++ ) +/*N*/ cStr[j] = ByteString::ConvertToUnicode( c[j], eSrc ); +/*N*/ cStr[ n ] = 0; +/*N*/ break; +/*N*/ } +/*N*/ case svSingleRef: +/*N*/ case svDoubleRef: +/*N*/ { +/*N*/ SingleRefData& r = aRef.Ref1; +/*N*/ rStream >> r.nCol +/*N*/ >> r.nRow +/*N*/ >> r.nTab +/*N*/ >> n; +/*N*/ if ( nVer < SC_RELATIVE_REFS ) +/*N*/ { +/*N*/ OldSingleRefBools aBools; +/*N*/ aBools.bRelCol = ( n & 0x03 ); +/*N*/ aBools.bRelRow = ( ( n >> 2 ) & 0x03 ); +/*N*/ aBools.bRelTab = ( ( n >> 4 ) & 0x03 ); +/*N*/ aBools.bOldFlag3D = ( ( n >> 6 ) & 0x03 ); +/*N*/ r.OldBoolsToNewFlags( aBools ); +/*N*/ } +/*N*/ else +/*N*/ r.CreateFlagsFromLoadByte( n ); +/*N*/ if( eType == svSingleRef ) +/*N*/ aRef.Ref2 = r; +/*N*/ else +/*N*/ { +/*N*/ SingleRefData& r = aRef.Ref2; +/*N*/ rStream >> r.nCol +/*N*/ >> r.nRow +/*N*/ >> r.nTab +/*N*/ >> n; +/*N*/ if ( nVer < SC_RELATIVE_REFS ) +/*N*/ { +/*N*/ OldSingleRefBools aBools; +/*N*/ aBools.bRelCol = ( n & 0x03 ); +/*N*/ aBools.bRelRow = ( ( n >> 2 ) & 0x03 ); +/*N*/ aBools.bRelTab = ( ( n >> 4 ) & 0x03 ); +/*N*/ aBools.bOldFlag3D = ( ( n >> 6 ) & 0x03 ); +/*N*/ r.OldBoolsToNewFlags( aBools ); +/*N*/ } +/*N*/ else +/*N*/ r.CreateFlagsFromLoadByte( n ); +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ case svIndex: +/*N*/ rStream >> nIndex; +/*N*/ break; +/*N*/ case svJump: +/*N*/ rStream >> n; +/*N*/ nJump[ 0 ] = n; +/*N*/ for( i = 1; i <= n; i++ ) +/*N*/ rStream >> nJump[ i ]; +/*N*/ break; +/*?*/ case svMissing: +/*?*/ case svErr: +/*?*/ break; +/*?*/ default: +/*?*/ { +/*?*/ rStream >> n; +/*?*/ if( n > MAXSTRLEN-2 ) +/*?*/ { +/*?*/ DBG_ERRORFILE( "bad unknown token type array boundary" ); +/*?*/ USHORT nDiff = n - (MAXSTRLEN-2); +/*?*/ n = MAXSTRLEN-2; +/*?*/ rStream.Read( ((BYTE*)cStr)+1, n ); +/*?*/ rStream.SeekRel( nDiff ); +/*?*/ ++n; +/*?*/ } +/*?*/ else if ( n > 1 ) +/*?*/ rStream.Read( ((BYTE*)cStr)+1, n-1 ); +/*?*/ else if ( n == 0 ) +/*?*/ { +/*?*/ DBG_ERRORFILE( "unknown token type length==0" ); +/*?*/ n = 1; +/*?*/ } +/*?*/ *((BYTE*)cStr) = n; // length including length byte +/*?*/ } +/*N*/ } +/*N*/ } + +/*N*/ void ScToken::Store( SvStream& rStream ) const +/*N*/ { +/*N*/ short i; +/*N*/ rStream << (UINT16) eOp << (BYTE) eType; +/*N*/ switch( eType ) +/*N*/ { +/*N*/ case svByte: +/*N*/ rStream << GetByte(); +/*N*/ break; +/*N*/ case svDouble: +/*N*/ rStream << GetDouble(); +/*N*/ break; +/*N*/ case svExternal: +/*N*/ { +/*N*/ ByteString aTmp( GetExternal(), rStream.GetStreamCharSet() ); +/*N*/ aTmp.Erase( 255 ); // old SO5 can't handle more +/*N*/ rStream << GetByte() +/*N*/ << (UINT8) aTmp.Len(); +/*N*/ rStream.Write( aTmp.GetBuffer(), (UINT8) aTmp.Len() ); +/*N*/ } +/*N*/ break; +/*N*/ case svString: +/*N*/ { +/*N*/ ByteString aTmp( GetString(), rStream.GetStreamCharSet() ); +/*N*/ aTmp.Erase( 255 ); // old SO5 can't handle more +/*N*/ rStream << (UINT8) aTmp.Len(); +/*N*/ rStream.Write( aTmp.GetBuffer(), (UINT8) aTmp.Len() ); +/*N*/ } +/*N*/ break; +/*N*/ case svSingleRef: +/*N*/ { +/*N*/ const SingleRefData& r = GetSingleRef(); +/*N*/ BYTE n = r.CreateStoreByteFromFlags(); +/*N*/ rStream << (INT16) r.nCol +/*N*/ << (INT16) r.nRow +/*N*/ << (INT16) r.nTab +/*N*/ << (BYTE) n; +/*N*/ } +/*N*/ break; +/*N*/ case svDoubleRef: +/*N*/ { +/*N*/ const ComplRefData& rRef = GetDoubleRef(); +/*N*/ const SingleRefData& r1 = rRef.Ref1; +/*N*/ BYTE n = r1.CreateStoreByteFromFlags(); +/*N*/ rStream << (INT16) r1.nCol +/*N*/ << (INT16) r1.nRow +/*N*/ << (INT16) r1.nTab +/*N*/ << (BYTE) n; +/*N*/ const SingleRefData& r2 = rRef.Ref2; +/*N*/ n = r2.CreateStoreByteFromFlags(); +/*N*/ rStream << (INT16) r2.nCol +/*N*/ << (INT16) r2.nRow +/*N*/ << (INT16) r2.nTab +/*N*/ << (BYTE) n; +/*N*/ } +/*N*/ break; +/*N*/ case svIndex: +/*N*/ rStream << (UINT16) GetIndex(); +/*N*/ break; +/*N*/ case svJump: +/*N*/ { +/*N*/ short* pJump = GetJump(); +/*N*/ rStream << (BYTE) pJump[ 0 ]; +/*N*/ for( i = 1; i <= pJump[ 0 ]; i++ ) +/*N*/ rStream << (UINT16) pJump[ i ]; +/*N*/ } +/*N*/ break; +/*?*/ case svMissing: +/*?*/ case svErr: +/*?*/ break; +/*?*/ default: +/*?*/ { +/*?*/ BYTE* pUnknown = GetUnknown(); +/*?*/ if ( pUnknown ) +/*?*/ rStream.Write( pUnknown, pUnknown[ 0 ] ); +/*?*/ } +/*N*/ } +/*N*/ } + +/*----------------------------------------------------------------------*/ + +/*N*/ ScTokenIterator::ScTokenIterator( const ScTokenArray& rArr ) +/*N*/ { +/*N*/ pCur = NULL; +/*N*/ Push( (ScTokenArray*) &rArr ); +/*N*/ } + +/*N*/ ScTokenIterator::~ScTokenIterator() +/*N*/ { +/*N*/ while( pCur ) +/*N*/ Pop(); +/*N*/ } + +/*N*/ void ScTokenIterator::Push( ScTokenArray* pArr ) +/*N*/ { +/*N*/ ImpTokenIterator* p = new ImpTokenIterator; +/*N*/ p->pArr = pArr; +/*N*/ p->nPC = -1; +/*N*/ p->pNext = pCur; +/*N*/ pCur = p; +/*N*/ } + +/*N*/ void ScTokenIterator::Pop() +/*N*/ { +/*N*/ ImpTokenIterator* p = pCur; +/*N*/ if( p ) +/*N*/ { +/*N*/ pCur = p->pNext; +/*N*/ delete p; +/*N*/ } +/*N*/ } + +/*N*/ void ScTokenIterator::Reset() +/*N*/ { +/*N*/ while( pCur->pNext ) +/*?*/ Pop(); +/*N*/ pCur->nPC = -1; +/*N*/ } + +/*N*/ const ScToken* ScTokenIterator::Next() +/*N*/ { +/*N*/ const ScToken* t = NULL; +/*N*/ if( ++pCur->nPC < pCur->pArr->nRPN ) +/*N*/ { +/*N*/ t = pCur->pArr->pRPN[ pCur->nPC ]; +/*N*/ // ein derartiger Opcode endet einen WENN- oder WAHL-Bereich +/*N*/ if( t->GetOpCode() == ocSep || t->GetOpCode() == ocClose ) +/*N*/ t = NULL; +/*N*/ } +/*N*/ if( !t && pCur->pNext ) +/*N*/ { +/*N*/ Pop(); t = Next(); +/*N*/ } +/*N*/ return t; +/*N*/ } + +// Die PC-Werte sind -1! + +/*N*/ void ScTokenIterator::Jump( short nStart, short nNext ) +/*N*/ { +/*N*/ pCur->nPC = nNext; +/*N*/ if( nStart != nNext ) +/*N*/ { +/*N*/ Push( pCur->pArr ); +/*N*/ pCur->nPC = nStart; +/*N*/ } +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_unitconv.cxx b/binfilter/bf_sc/source/core/tool/sc_unitconv.cxx new file mode 100644 index 000000000000..f06952cf4ded --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_unitconv.cxx @@ -0,0 +1,179 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include "unitconv.hxx" +#include "viewopti.hxx" //! move ScLinkConfigItem to separate header! +namespace binfilter { + +using namespace utl; +using namespace rtl; +using namespace ::com::sun::star::uno; + +// -------------------------------------------------------------------- + +/*N*/ const sal_Unicode cDelim = 0x01; // Delimiter zwischen From und To + + +// --- ScUnitConverterData -------------------------------------------- + +/*N*/ ScUnitConverterData::ScUnitConverterData( const String& rFromUnit, +/*N*/ const String& rToUnit, double fVal ) +/*N*/ : +/*N*/ StrData( rFromUnit ), +/*N*/ fValue( fVal ) +/*N*/ { +/*N*/ String aTmp; +/*N*/ ScUnitConverterData::BuildIndexString( aTmp, rFromUnit, rToUnit ); +/*N*/ SetString( aTmp ); +/*N*/ } + + +/*N*/ ScUnitConverterData::ScUnitConverterData( const ScUnitConverterData& r ) +/*N*/ : +/*N*/ StrData( r ), +/*N*/ fValue( r.fValue ) +/*N*/ { +/*N*/ } + + +/*N*/ DataObject* ScUnitConverterData::Clone() const +/*N*/ { +/*N*/ return new ScUnitConverterData( *this ); +/*N*/ } + + +// static +/*N*/ void ScUnitConverterData::BuildIndexString( String& rStr, +/*N*/ const String& rFromUnit, const String& rToUnit ) +/*N*/ { +/*N*/ #if 1 +/*N*/ // case sensitive +/*N*/ rStr = rFromUnit; +/*N*/ rStr += cDelim; +/*N*/ rStr += rToUnit; +/*N*/ #else +/*N*/ // not case sensitive +/*N*/ rStr = rFromUnit; +/*N*/ String aTo( rToUnit ); +/*N*/ ScGlobal::pCharClass->toUpper( rStr ); +/*N*/ ScGlobal::pCharClass->toUpper( aTo ); +/*N*/ rStr += cDelim; +/*N*/ rStr += aTo; +/*N*/ #endif +/*N*/ } + + +// --- ScUnitConverter ------------------------------------------------ + +/*N*/ #define CFGPATH_UNIT "Office.Calc/UnitConversion" +/*N*/ #define CFGSTR_UNIT_FROM "FromUnit" +/*N*/ #define CFGSTR_UNIT_TO "ToUnit" +/*N*/ #define CFGSTR_UNIT_FACTOR "Factor" + +/*N*/ ScUnitConverter::ScUnitConverter( USHORT nInit, USHORT nDelta ) : +/*N*/ StrCollection( nInit, nDelta, FALSE ) +/*N*/ { +/*N*/ // read from configuration - "convert.ini" is no longer used +/*N*/ //! config item as member to allow change of values +/*N*/ +/*N*/ ScLinkConfigItem aConfigItem( OUString::createFromAscii( CFGPATH_UNIT ) ); +/*N*/ +/*N*/ // empty node name -> use the config item's path itself +/*N*/ OUString aEmptyString; +/*N*/ Sequence<OUString> aNodeNames = aConfigItem.GetNodeNames( aEmptyString ); +/*N*/ +/*N*/ long nNodeCount = aNodeNames.getLength(); +/*N*/ if ( nNodeCount ) +/*N*/ { +/*N*/ const OUString* pNodeArray = aNodeNames.getConstArray(); +/*N*/ Sequence<OUString> aValNames( nNodeCount * 3 ); +/*N*/ OUString* pValNameArray = aValNames.getArray(); +/*N*/ const OUString sSlash('/'); +/*N*/ +/*N*/ long nIndex = 0; +/*N*/ for (long i=0; i<nNodeCount; i++) +/*N*/ { +/*N*/ OUString sPrefix = pNodeArray[i]; +/*N*/ sPrefix += sSlash; +/*N*/ +/*N*/ pValNameArray[nIndex] = sPrefix; +/*N*/ pValNameArray[nIndex++] += OUString::createFromAscii( CFGSTR_UNIT_FROM ); +/*N*/ pValNameArray[nIndex] = sPrefix; +/*N*/ pValNameArray[nIndex++] += OUString::createFromAscii( CFGSTR_UNIT_TO ); +/*N*/ pValNameArray[nIndex] = sPrefix; +/*N*/ pValNameArray[nIndex++] += OUString::createFromAscii( CFGSTR_UNIT_FACTOR ); +/*N*/ } +/*N*/ +/*N*/ Sequence<Any> aProperties = aConfigItem.GetProperties(aValNames); +/*N*/ +/*N*/ if (aProperties.getLength() == aValNames.getLength()) +/*N*/ { +/*N*/ const Any* pProperties = aProperties.getConstArray(); +/*N*/ +/*N*/ OUString sFromUnit; +/*N*/ OUString sToUnit; +/*N*/ double fFactor; +/*N*/ +/*N*/ nIndex = 0; +/*N*/ for (long i=0; i<nNodeCount; i++) +/*N*/ { +/*N*/ pProperties[nIndex++] >>= sFromUnit; +/*N*/ pProperties[nIndex++] >>= sToUnit; +/*N*/ pProperties[nIndex++] >>= fFactor; +/*N*/ +/*N*/ ScUnitConverterData* pNew = new ScUnitConverterData( sFromUnit, sToUnit, fFactor ); +/*N*/ if ( !Insert( pNew ) ) +/*N*/ delete pNew; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ BOOL ScUnitConverter::GetValue( double& fValue, const String& rFromUnit, +/*N*/ const String& rToUnit ) const +/*N*/ { +/*N*/ ScUnitConverterData aSearch( rFromUnit, rToUnit ); +/*N*/ USHORT nIndex; +/*N*/ if ( Search( &aSearch, nIndex ) ) +/*N*/ { +/*N*/ fValue = ((const ScUnitConverterData*)(At( nIndex )))->GetValue(); +/*N*/ return TRUE; +/*N*/ } +/*N*/ fValue = 1.0; +/*N*/ return FALSE; +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_userlist.cxx b/binfilter/bf_sc/source/core/tool/sc_userlist.cxx new file mode 100644 index 000000000000..84218b5ebf0c --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_userlist.cxx @@ -0,0 +1,241 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +//------------------------------------------------------------------------ + +#include <unotools/charclass.hxx> +#include <string.h> + +#include "global.hxx" +#include "userlist.hxx" + +#include <unotools/localedatawrapper.hxx> +namespace binfilter { + +// STATIC DATA ----------------------------------------------------------- + + +//------------------------------------------------------------------------ + +/*N*/ void ScUserListData::InitTokens() +/*N*/ { +/*N*/ sal_Unicode cSep = ScGlobal::cListDelimiter; +/*N*/ nTokenCount = (USHORT) aStr.GetTokenCount(cSep); +/*N*/ if (nTokenCount) +/*N*/ { +/*N*/ pSubStrings = new String[nTokenCount]; +/*N*/ pUpperSub = new String[nTokenCount]; +/*N*/ for (USHORT i=0; i<nTokenCount; i++) +/*N*/ { +/*N*/ pUpperSub[i] = pSubStrings[i] = aStr.GetToken((xub_StrLen)i,cSep); +/*N*/ ScGlobal::pCharClass->toUpper(pUpperSub[i]); +/*N*/ } +/*N*/ } +/*N*/ else +/*?*/ pSubStrings = pUpperSub = NULL; +/*N*/ } + +/*N*/ ScUserListData::ScUserListData(const String& rStr) : +/*N*/ aStr(rStr) +/*N*/ { +/*N*/ InitTokens(); +/*N*/ } + +/*N*/ ScUserListData::ScUserListData(const ScUserListData& rData) : +/*N*/ aStr(rData.aStr) +/*N*/ { +/*N*/ InitTokens(); +/*N*/ } + +/*N*/ __EXPORT ScUserListData::~ScUserListData() +/*N*/ { +/*N*/ delete[] pSubStrings; +/*N*/ delete[] pUpperSub; +/*N*/ } + +/*N*/ ScUserListData::ScUserListData( SvStream& rStream ) +/*N*/ { +/*N*/ rStream.ReadByteString( aStr, rStream.GetStreamCharSet() ); +/*N*/ InitTokens(); +/*N*/ } + +/*N*/ BOOL ScUserListData::Store( SvStream& rStream ) const +/*N*/ { +/*N*/ rStream.WriteByteString( aStr, rStream.GetStreamCharSet() ); +/*N*/ return TRUE; +/*N*/ } + + + +/*N*/ BOOL ScUserListData::GetSubIndex(const String& rSubStr, USHORT& rIndex) const +/*N*/ { +/*N*/ USHORT i; +/*N*/ for (i=0; i<nTokenCount; i++) +/*N*/ if (rSubStr == pSubStrings[i]) +/*N*/ { +/*N*/ rIndex = i; +/*N*/ return TRUE; +/*N*/ } +/*N*/ +/*N*/ String aUpStr = rSubStr; +/*N*/ ScGlobal::pCharClass->toUpper(aUpStr); +/*N*/ for (i=0; i<nTokenCount; i++) +/*N*/ if (aUpStr == pUpperSub[i]) +/*N*/ { +/*N*/ rIndex = i; +/*N*/ return TRUE; +/*N*/ } +/*N*/ +/*N*/ return FALSE; +/*N*/ } + + + + +/*N*/ ScUserList::ScUserList(USHORT nLim, USHORT nDel) : +/*N*/ Collection ( nLim, nDel ) +/*N*/ { +/*N*/ using namespace ::com::sun::star; +/*N*/ +/*N*/ sal_Unicode cDelimiter = ScGlobal::cListDelimiter; +/*N*/ uno::Sequence< i18n::CalendarItem > xCal; +/*N*/ +/*N*/ uno::Sequence< i18n::Calendar > xCalendars( +/*N*/ ScGlobal::pLocaleData->getAllCalendars() ); +/*N*/ +/*N*/ for ( sal_Int32 j = 0; j < xCalendars.getLength(); ++j ) +/*N*/ { +/*N*/ xCal = xCalendars[j].Days; +/*N*/ if ( xCal.getLength() ) +/*N*/ { +/*N*/ String sDayShort, sDayLong; +/*N*/ sal_Int32 i; +/*N*/ sal_Int32 nCount = xCal.getLength() - 1; +/*N*/ for (i = 0; i < nCount; i++) +/*N*/ { +/*N*/ sDayShort += String( xCal[i].AbbrevName ); +/*N*/ sDayShort += cDelimiter; +/*N*/ sDayLong += String( xCal[i].FullName ); +/*N*/ sDayLong += cDelimiter; +/*N*/ } +/*N*/ sDayShort += String( xCal[i].AbbrevName ); +/*N*/ sDayLong += String( xCal[i].FullName ); +/*N*/ +/*N*/ if ( !HasEntry( sDayShort ) ) +/*N*/ Insert( new ScUserListData( sDayShort )); +/*N*/ if ( !HasEntry( sDayLong ) ) +/*N*/ Insert( new ScUserListData( sDayLong )); +/*N*/ } +/*N*/ +/*N*/ xCal = xCalendars[j].Months; +/*N*/ if ( xCal.getLength() ) +/*N*/ { +/*N*/ String sMonthShort, sMonthLong; +/*N*/ sal_Int32 i; +/*N*/ sal_Int32 nCount = xCal.getLength() - 1; +/*N*/ for (i = 0; i < nCount; i++) +/*N*/ { +/*N*/ sMonthShort += String( xCal[i].AbbrevName ); +/*N*/ sMonthShort += cDelimiter; +/*N*/ sMonthLong += String( xCal[i].FullName ); +/*N*/ sMonthLong += cDelimiter; +/*N*/ } +/*N*/ sMonthShort += String( xCal[i].AbbrevName ); +/*N*/ sMonthLong += String( xCal[i].FullName ); +/*N*/ +/*N*/ if ( !HasEntry( sMonthShort ) ) +/*N*/ Insert( new ScUserListData( sMonthShort )); +/*N*/ if ( !HasEntry( sMonthLong ) ) +/*N*/ Insert( new ScUserListData( sMonthLong )); +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ BOOL ScUserList::Load( SvStream& rStream ) +/*N*/ { +/*N*/ BOOL bSuccess = TRUE; +/*N*/ USHORT nNewCount; +/*N*/ +/*N*/ while( nCount > 0 ) +/*N*/ AtFree(0); // alles loeschen +/*N*/ +/*N*/ rStream >> nNewCount; +/*N*/ +/*N*/ for ( USHORT i=0; i<nNewCount && bSuccess; i++ ) +/*N*/ Insert( new ScUserListData( rStream ) ); +/*N*/ +/*N*/ return bSuccess; +/*N*/ } + +/*N*/ BOOL ScUserList::Store( SvStream& rStream ) const +/*N*/ { +/*N*/ BOOL bSuccess = TRUE; +/*N*/ +/*N*/ rStream << nCount; +/*N*/ +/*N*/ for ( USHORT i=0; i<nCount && bSuccess; i++ ) +/*N*/ bSuccess = ((const ScUserListData*)At(i))->Store( rStream ); +/*N*/ +/*N*/ return bSuccess; +/*N*/ } + +/*N*/ DataObject* ScUserList::Clone() const +/*N*/ { +/*N*/ return ( new ScUserList( *this ) ); +/*N*/ } + +/*N*/ ScUserListData* ScUserList::GetData(const String& rSubStr) const +/*N*/ { +/*N*/ USHORT nIndex; +/*N*/ USHORT i = 0; +/*N*/ for (i=0; i < nCount; i++) +/*N*/ if (((ScUserListData*)pItems[i])->GetSubIndex(rSubStr, nIndex)) +/*?*/ return (ScUserListData*)pItems[i]; +/*N*/ return NULL; +/*N*/ } + + + +/*N*/ BOOL ScUserList::HasEntry( const String& rStr ) const +/*N*/ { +/*N*/ for ( USHORT i=0; i<nCount; i++) +/*N*/ { +/*N*/ const ScUserListData* pMyData = (ScUserListData*) At(i); +/*N*/ if ( pMyData->aStr == rStr ) +/*N*/ return TRUE; +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_viewopti.cxx b/binfilter/bf_sc/source/core/tool/sc_viewopti.cxx new file mode 100644 index 000000000000..83d97e80056f --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_viewopti.cxx @@ -0,0 +1,675 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + + +#include "globstr.hrc" +#include "viewopti.hxx" +#include "rechead.hxx" +#include "bf_sc.hrc" +#include "miscuno.hxx" +namespace binfilter { + +using namespace utl; +using namespace rtl; +using namespace ::com::sun::star::uno; + +//------------------------------------------------------------------ + + +#define SC_VERSION ((USHORT)302) + + +//======================================================================== +// class ScGridOptions +//======================================================================== + + +/*N*/ void ScGridOptions::SetDefaults() +/*N*/ { +/*N*/ *this = ScGridOptions(); +/*N*/ +/*N*/ // Raster-Defaults sind jetzt zwischen den Apps unterschiedlich +/*N*/ // darum hier selber eintragen (alles in 1/100mm) +/*N*/ +/*N*/ if ( ScOptionsUtil::IsMetricSystem() ) +/*N*/ { +/*N*/ nFldDrawX = 1000; // 1cm +/*N*/ nFldDrawY = 1000; +/*N*/ nFldSnapX = 1000; +/*N*/ nFldSnapY = 1000; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nFldDrawX = 1270; // 0,5" +/*N*/ nFldDrawY = 1270; +/*N*/ nFldSnapX = 1270; +/*N*/ nFldSnapY = 1270; +/*N*/ } +/*N*/ nFldDivisionX = 1; +/*N*/ nFldDivisionY = 1; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ const ScGridOptions& ScGridOptions::operator=( const ScGridOptions& rCpy ) +/*N*/ { +/*N*/ nFldDrawX = rCpy.nFldDrawX; // UINT32 +/*N*/ nFldDrawX = rCpy.nFldDrawX; +/*N*/ nFldDivisionX = rCpy.nFldDivisionX; +/*N*/ nFldDrawY = rCpy.nFldDrawY; +/*N*/ nFldDivisionY = rCpy.nFldDivisionY; +/*N*/ nFldSnapX = rCpy.nFldSnapX; +/*N*/ nFldSnapY = rCpy.nFldSnapY; +/*N*/ bUseGridsnap = rCpy.bUseGridsnap; // BitBool +/*N*/ bSynchronize = rCpy.bSynchronize; +/*N*/ bGridVisible = rCpy.bGridVisible; +/*N*/ bEqualGrid = rCpy.bEqualGrid; +/*N*/ +/*N*/ return *this; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ int ScGridOptions::operator==( const ScGridOptions& rCpy ) const +/*N*/ { +/*N*/ return ( nFldDrawX == rCpy.nFldDrawX +/*N*/ && nFldDrawX == rCpy.nFldDrawX +/*N*/ && nFldDivisionX == rCpy.nFldDivisionX +/*N*/ && nFldDrawY == rCpy.nFldDrawY +/*N*/ && nFldDivisionY == rCpy.nFldDivisionY +/*N*/ && nFldSnapX == rCpy.nFldSnapX +/*N*/ && nFldSnapY == rCpy.nFldSnapY +/*N*/ && bUseGridsnap == rCpy.bUseGridsnap +/*N*/ && bSynchronize == rCpy.bSynchronize +/*N*/ && bGridVisible == rCpy.bGridVisible +/*N*/ && bEqualGrid == rCpy.bEqualGrid ); +/*N*/ } + + +//------------------------------------------------------------------------ + +/*N*/ SvStream& operator>>( SvStream& rStream, ScGridOptions& rOpt ) +/*N*/ { +/*N*/ BYTE nDummy; +/*N*/ rStream >> rOpt.nFldDrawX; +/*N*/ rStream >> rOpt.nFldDrawY; +/*N*/ rStream >> rOpt.nFldDivisionX; +/*N*/ rStream >> rOpt.nFldDivisionY; +/*N*/ rStream >> rOpt.nFldSnapX; +/*N*/ rStream >> rOpt.nFldSnapY; +/*N*/ rStream >> nDummy; rOpt.bUseGridsnap = (BOOL)nDummy; +/*N*/ rStream >> nDummy; rOpt.bSynchronize = (BOOL)nDummy; +/*N*/ rStream >> nDummy; rOpt.bGridVisible = (BOOL)nDummy; +/*N*/ rStream >> nDummy; rOpt.bEqualGrid = (BOOL)nDummy; +/*N*/ +/*N*/ return rStream; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ SvStream& operator<<( SvStream& rStream, const ScGridOptions& rOpt ) +/*N*/ { +/*N*/ rStream << rOpt.nFldDrawX; +/*N*/ rStream << rOpt.nFldDrawY; +/*N*/ rStream << rOpt.nFldDivisionX; +/*N*/ rStream << rOpt.nFldDivisionY; +/*N*/ rStream << rOpt.nFldSnapX; +/*N*/ rStream << rOpt.nFldSnapY; +/*N*/ rStream << (BOOL)rOpt.bUseGridsnap; +/*N*/ rStream << (BOOL)rOpt.bSynchronize; +/*N*/ rStream << (BOOL)rOpt.bGridVisible; +/*N*/ rStream << (BOOL)rOpt.bEqualGrid; +/*N*/ +/*N*/ return rStream; +/*N*/ } + +//======================================================================== +// class ScViewOptions +//======================================================================== + +/*N*/ ScViewOptions::ScViewOptions() +/*N*/ { +/*N*/ SetDefaults(); +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ ScViewOptions::ScViewOptions( const ScViewOptions& rCpy ) +/*N*/ { +/*N*/ *this = rCpy; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ __EXPORT ScViewOptions::~ScViewOptions() +/*N*/ { +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ void ScViewOptions::SetDefaults() +/*N*/ { +/*N*/ aOptArr[ VOPT_FORMULAS ] = +/*N*/ aOptArr[ VOPT_SYNTAX ] = +/*N*/ aOptArr[ VOPT_HELPLINES ] = +/*N*/ aOptArr[ VOPT_BIGHANDLES ] = FALSE; +/*N*/ aOptArr[ VOPT_NOTES ] = +/*N*/ aOptArr[ VOPT_NULLVALS ] = +/*N*/ aOptArr[ VOPT_VSCROLL ] = +/*N*/ aOptArr[ VOPT_HSCROLL ] = +/*N*/ aOptArr[ VOPT_TABCONTROLS ] = +/*N*/ aOptArr[ VOPT_OUTLINER ] = +/*N*/ aOptArr[ VOPT_HEADER ] = +/*N*/ aOptArr[ VOPT_GRID ] = +/*N*/ aOptArr[ VOPT_ANCHOR ] = +/*N*/ aOptArr[ VOPT_PAGEBREAKS ] = +/*N*/ aOptArr[ VOPT_SOLIDHANDLES] = +/*N*/ aOptArr[ VOPT_CLIPMARKS ] = TRUE; +/*N*/ +/*N*/ aModeArr[VOBJ_TYPE_OLE ] = +/*N*/ aModeArr[VOBJ_TYPE_CHART] = +/*N*/ aModeArr[VOBJ_TYPE_DRAW ] = VOBJ_MODE_SHOW; +/*N*/ +/*N*/ aGridCol = Color( SC_STD_GRIDCOLOR ); +/*N*/ aGridColName = ScGlobal::GetRscString( STR_GRIDCOLOR ); +/*N*/ +/*N*/ aGridOpt.SetDefaults(); +/*N*/ +/*N*/ bHideAutoSpell = FALSE; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ Color ScViewOptions::GetGridColor( String* pStrName ) const +/*N*/ { +/*N*/ if ( pStrName ) +/*N*/ *pStrName = aGridColName; +/*N*/ +/*N*/ return aGridCol; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ const ScViewOptions& ScViewOptions::operator=( const ScViewOptions& rCpy ) +/*N*/ { +/*N*/ USHORT i; +/*N*/ +/*N*/ for ( i=0; i<MAX_OPT; i++ ) aOptArr [i] = rCpy.aOptArr[i]; +/*N*/ for ( i=0; i<MAX_TYPE; i++ ) aModeArr[i] = rCpy.aModeArr[i]; +/*N*/ +/*N*/ aGridCol = rCpy.aGridCol; +/*N*/ aGridColName = rCpy.aGridColName; +/*N*/ aGridOpt = rCpy.aGridOpt; +/*N*/ bHideAutoSpell = rCpy.bHideAutoSpell; +/*N*/ +/*N*/ return *this; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ int ScViewOptions::operator==( const ScViewOptions& rOpt ) const +/*N*/ { +/*N*/ BOOL bEqual = TRUE; +/*N*/ USHORT i; +/*N*/ +/*N*/ for ( i=0; i<MAX_OPT && bEqual; i++ ) bEqual = (aOptArr [i] == rOpt.aOptArr[i]); +/*N*/ for ( i=0; i<MAX_TYPE && bEqual; i++ ) bEqual = (aModeArr[i] == rOpt.aModeArr[i]); +/*N*/ +/*N*/ bEqual = bEqual && (aGridCol == rOpt.aGridCol); +/*N*/ bEqual = bEqual && (aGridColName == rOpt.aGridColName); +/*N*/ bEqual = bEqual && (aGridOpt == rOpt.aGridOpt); +/*N*/ bEqual = bEqual && (bHideAutoSpell == rOpt.bHideAutoSpell); +/*N*/ +/*N*/ return bEqual; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ SvStream& operator>>( SvStream& rStream, ScViewOptions& rOpt ) +/*N*/ { +/*N*/ USHORT i; +/*N*/ BYTE n; +/*N*/ +/*N*/ ScReadHeader aHdr( rStream ); +/*N*/ +/*N*/ for ( i=0; i<=VOPT_GRID; i++ ) // kompatibel bleiben -> nur bis VOPT_GRID +/*N*/ rStream >> rOpt.aOptArr[i]; +/*N*/ +/*N*/ for ( i=0; i<MAX_TYPE; i++ ) +/*N*/ rStream >> n, rOpt.aModeArr[i] = (ScVObjMode)n; +/*N*/ +/*N*/ rStream >> rOpt.aGridCol; +/*N*/ rStream.ReadByteString( rOpt.aGridColName, rStream.GetStreamCharSet() ); +/*N*/ +/*N*/ if( aHdr.BytesLeft() ) +/*N*/ rStream >> rOpt.aOptArr[VOPT_HELPLINES]; +/*N*/ +/*N*/ if( aHdr.BytesLeft() ) +/*N*/ rStream >> rOpt.aGridOpt; +/*N*/ +/*N*/ if( aHdr.BytesLeft() ) +/*N*/ rStream >> rOpt.bHideAutoSpell; +/*N*/ +/*N*/ if( aHdr.BytesLeft() ) +/*N*/ rStream >> rOpt.aOptArr[VOPT_ANCHOR]; +/*N*/ +/*N*/ if( aHdr.BytesLeft() ) +/*N*/ rStream >> rOpt.aOptArr[VOPT_PAGEBREAKS]; +/*N*/ +/*N*/ if( aHdr.BytesLeft() ) +/*N*/ rStream >> rOpt.aOptArr[VOPT_SOLIDHANDLES]; +/*N*/ +/*N*/ if( aHdr.BytesLeft() ) +/*N*/ rStream >> rOpt.aOptArr[VOPT_CLIPMARKS]; +/*N*/ +/*N*/ if( aHdr.BytesLeft() ) +/*N*/ rStream >> rOpt.aOptArr[VOPT_BIGHANDLES]; +/*N*/ +/*N*/ return rStream; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ void ScViewOptions::Save(SvStream& rStream, BOOL bConfig) const +/*N*/ { +/*N*/ USHORT i; +/*N*/ +/*N*/ ScWriteHeader aHdr( rStream, 68 ); +/*N*/ +/*N*/ for ( i=0; i<=VOPT_GRID; i++ ) // kompatibel bleiben -> nur bis VOPT_GRID +/*N*/ rStream << aOptArr[i]; +/*N*/ +/*N*/ for ( i=0; i<MAX_TYPE; i++ ) +/*N*/ rStream << (BYTE)aModeArr[i]; +/*N*/ +/*N*/ rStream << aGridCol; +/*N*/ rStream.WriteByteString( aGridColName, rStream.GetStreamCharSet() ); +/*N*/ rStream << aOptArr[VOPT_HELPLINES]; +/*N*/ rStream << aGridOpt; +/*N*/ rStream << bHideAutoSpell; +/*N*/ rStream << aOptArr[VOPT_ANCHOR]; +/*N*/ rStream << aOptArr[VOPT_PAGEBREAKS]; +/*N*/ rStream << aOptArr[VOPT_SOLIDHANDLES]; +/*N*/ +/*N*/ if ( bConfig || rStream.GetVersion() > SOFFICE_FILEFORMAT_40 ) // nicht bei 4.0 Export +/*N*/ { +/*N*/ rStream << aOptArr[VOPT_CLIPMARKS]; +/*N*/ +/*N*/ // big handles are not saved in 5.0-documents to avoid warning messages +/*N*/ //! save to files after 5.0 !!! +/*N*/ +/*N*/ if ( bConfig ) +/*N*/ rStream << aOptArr[VOPT_BIGHANDLES]; +/*N*/ } +/*N*/ } + +//------------------------------------------------------------------------ + + +//======================================================================== +// ScTpViewItem - Daten fuer die ViewOptions-TabPage +//======================================================================== + + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------ + + +//================================================================== +// Config Item containing view options +//================================================================== + +#define CFGPATH_LAYOUT "Office.Calc/Layout" + +#define SCLAYOUTOPT_GRIDLINES 0 +#define SCLAYOUTOPT_GRIDCOLOR 1 +#define SCLAYOUTOPT_PAGEBREAK 2 +#define SCLAYOUTOPT_GUIDE 3 +#define SCLAYOUTOPT_SIMPLECONT 4 +#define SCLAYOUTOPT_LARGECONT 5 +#define SCLAYOUTOPT_COLROWHDR 6 +#define SCLAYOUTOPT_HORISCROLL 7 +#define SCLAYOUTOPT_VERTSCROLL 8 +#define SCLAYOUTOPT_SHEETTAB 9 +#define SCLAYOUTOPT_OUTLINE 10 +#define SCLAYOUTOPT_COUNT 11 + +#define CFGPATH_DISPLAY "Office.Calc/Content/Display" + +#define SCDISPLAYOPT_FORMULA 0 +#define SCDISPLAYOPT_ZEROVALUE 1 +#define SCDISPLAYOPT_NOTETAG 2 +#define SCDISPLAYOPT_VALUEHI 3 +#define SCDISPLAYOPT_ANCHOR 4 +#define SCDISPLAYOPT_TEXTOVER 5 +#define SCDISPLAYOPT_OBJECTGRA 6 +#define SCDISPLAYOPT_CHART 7 +#define SCDISPLAYOPT_DRAWING 8 +#define SCDISPLAYOPT_COUNT 9 + +#define CFGPATH_GRID "Office.Calc/Grid" + +#define SCGRIDOPT_RESOLU_X 0 +#define SCGRIDOPT_RESOLU_Y 1 +#define SCGRIDOPT_SUBDIV_X 2 +#define SCGRIDOPT_SUBDIV_Y 3 +#define SCGRIDOPT_OPTION_X 4 +#define SCGRIDOPT_OPTION_Y 5 +#define SCGRIDOPT_SNAPTOGRID 6 +#define SCGRIDOPT_SYNCHRON 7 +#define SCGRIDOPT_VISIBLE 8 +#define SCGRIDOPT_SIZETOGRID 9 +#define SCGRIDOPT_COUNT 10 + + +/*N*/ Sequence<OUString> ScViewCfg::GetLayoutPropertyNames() +/*N*/ { +/*N*/ static const char* aPropNames[] = +/*N*/ { +/*N*/ "Line/GridLine", // SCLAYOUTOPT_GRIDLINES +/*N*/ "Line/GridLineColor", // SCLAYOUTOPT_GRIDCOLOR +/*N*/ "Line/PageBreak", // SCLAYOUTOPT_PAGEBREAK +/*N*/ "Line/Guide", // SCLAYOUTOPT_GUIDE +/*N*/ "Line/SimpleControlPoint", // SCLAYOUTOPT_SIMPLECONT +/*N*/ "Line/LargeControlPoint", // SCLAYOUTOPT_LARGECONT +/*N*/ "Window/ColumnRowHeader", // SCLAYOUTOPT_COLROWHDR +/*N*/ "Window/HorizontalScroll", // SCLAYOUTOPT_HORISCROLL +/*N*/ "Window/VerticalScroll", // SCLAYOUTOPT_VERTSCROLL +/*N*/ "Window/SheetTab", // SCLAYOUTOPT_SHEETTAB +/*N*/ "Window/OutlineSymbol" // SCLAYOUTOPT_OUTLINE +/*N*/ }; +/*N*/ Sequence<OUString> aNames(SCLAYOUTOPT_COUNT); +/*N*/ OUString* pNames = aNames.getArray(); +/*N*/ for(int i = 0; i < SCLAYOUTOPT_COUNT; i++) +/*N*/ pNames[i] = OUString::createFromAscii(aPropNames[i]); +/*N*/ +/*N*/ return aNames; +/*N*/ } + +/*N*/ Sequence<OUString> ScViewCfg::GetDisplayPropertyNames() +/*N*/ { +/*N*/ static const char* aPropNames[] = +/*N*/ { +/*N*/ "Formula", // SCDISPLAYOPT_FORMULA +/*N*/ "ZeroValue", // SCDISPLAYOPT_ZEROVALUE +/*N*/ "NoteTag", // SCDISPLAYOPT_NOTETAG +/*N*/ "ValueHighlighting", // SCDISPLAYOPT_VALUEHI +/*N*/ "Anchor", // SCDISPLAYOPT_ANCHOR +/*N*/ "TextOverflow", // SCDISPLAYOPT_TEXTOVER +/*N*/ "ObjectGraphic", // SCDISPLAYOPT_OBJECTGRA +/*N*/ "Chart", // SCDISPLAYOPT_CHART +/*N*/ "DrawingObject" // SCDISPLAYOPT_DRAWING +/*N*/ }; +/*N*/ Sequence<OUString> aNames(SCDISPLAYOPT_COUNT); +/*N*/ OUString* pNames = aNames.getArray(); +/*N*/ for(int i = 0; i < SCDISPLAYOPT_COUNT; i++) +/*N*/ pNames[i] = OUString::createFromAscii(aPropNames[i]); +/*N*/ +/*N*/ return aNames; +/*N*/ } + +/*N*/ Sequence<OUString> ScViewCfg::GetGridPropertyNames() +/*N*/ { +/*N*/ static const char* aPropNames[] = +/*N*/ { +/*N*/ "Resolution/XAxis/NonMetric", // SCGRIDOPT_RESOLU_X +/*N*/ "Resolution/YAxis/NonMetric", // SCGRIDOPT_RESOLU_Y +/*N*/ "Subdivision/XAxis", // SCGRIDOPT_SUBDIV_X +/*N*/ "Subdivision/YAxis", // SCGRIDOPT_SUBDIV_Y +/*N*/ "Option/XAxis/NonMetric", // SCGRIDOPT_OPTION_X +/*N*/ "Option/YAxis/NonMetric", // SCGRIDOPT_OPTION_Y +/*N*/ "Option/SnapToGrid", // SCGRIDOPT_SNAPTOGRID +/*N*/ "Option/Synchronize", // SCGRIDOPT_SYNCHRON +/*N*/ "Option/VisibleGrid", // SCGRIDOPT_VISIBLE +/*N*/ "Option/SizeToGrid" // SCGRIDOPT_SIZETOGRID +/*N*/ }; +/*N*/ Sequence<OUString> aNames(SCGRIDOPT_COUNT); +/*N*/ OUString* pNames = aNames.getArray(); +/*N*/ for(int i = 0; i < SCGRIDOPT_COUNT; i++) +/*N*/ pNames[i] = OUString::createFromAscii(aPropNames[i]); +/*N*/ +/*N*/ // adjust for metric system +/*N*/ if (ScOptionsUtil::IsMetricSystem()) +/*N*/ { +/*N*/ pNames[SCGRIDOPT_RESOLU_X] = OUString::createFromAscii( "Resolution/XAxis/Metric" ); +/*N*/ pNames[SCGRIDOPT_RESOLU_Y] = OUString::createFromAscii( "Resolution/YAxis/Metric" ); +/*N*/ pNames[SCGRIDOPT_OPTION_X] = OUString::createFromAscii( "Option/XAxis/Metric" ); +/*N*/ pNames[SCGRIDOPT_OPTION_Y] = OUString::createFromAscii( "Option/YAxis/Metric" ); +/*N*/ } +/*N*/ +/*N*/ return aNames; +/*N*/ } + + +/*N*/ ScViewCfg::ScViewCfg() : +/*N*/ aLayoutItem( OUString::createFromAscii( CFGPATH_LAYOUT ) ), +/*N*/ aDisplayItem( OUString::createFromAscii( CFGPATH_DISPLAY ) ), +/*N*/ aGridItem( OUString::createFromAscii( CFGPATH_GRID ) ) +/*N*/ { +/*N*/ sal_Int32 nIntVal; +/*N*/ +/*N*/ Sequence<OUString> aNames = GetLayoutPropertyNames(); +/*N*/ Sequence<Any> aValues = aLayoutItem.GetProperties(aNames); +/*N*/ aLayoutItem.EnableNotification(aNames); +/*N*/ const Any* pValues = aValues.getConstArray(); +/*N*/ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed"); +/*N*/ if(aValues.getLength() == aNames.getLength()) +/*N*/ { +/*N*/ for(int nProp = 0; nProp < aNames.getLength(); nProp++) +/*N*/ { +/*N*/ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing"); +/*N*/ if(pValues[nProp].hasValue()) +/*N*/ { +/*N*/ switch(nProp) +/*N*/ { +/*N*/ case SCLAYOUTOPT_GRIDCOLOR: +/*N*/ if ( pValues[nProp] >>= nIntVal ) +/*N*/ SetGridColor( Color(nIntVal), EMPTY_STRING ); +/*N*/ break; +/*N*/ case SCLAYOUTOPT_GRIDLINES: +/*N*/ SetOption( VOPT_GRID, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCLAYOUTOPT_PAGEBREAK: +/*N*/ SetOption( VOPT_PAGEBREAKS, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCLAYOUTOPT_GUIDE: +/*N*/ SetOption( VOPT_HELPLINES, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCLAYOUTOPT_SIMPLECONT: +/*N*/ // content is reversed +/*N*/ SetOption( VOPT_SOLIDHANDLES, !ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCLAYOUTOPT_LARGECONT: +/*N*/ SetOption( VOPT_BIGHANDLES, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCLAYOUTOPT_COLROWHDR: +/*N*/ SetOption( VOPT_HEADER, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCLAYOUTOPT_HORISCROLL: +/*N*/ SetOption( VOPT_HSCROLL, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCLAYOUTOPT_VERTSCROLL: +/*N*/ SetOption( VOPT_VSCROLL, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCLAYOUTOPT_SHEETTAB: +/*N*/ SetOption( VOPT_TABCONTROLS, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCLAYOUTOPT_OUTLINE: +/*N*/ SetOption( VOPT_OUTLINER, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ aLayoutItem.SetCommitLink( LINK( this, ScViewCfg, LayoutCommitHdl ) ); +/*N*/ +/*N*/ aNames = GetDisplayPropertyNames(); +/*N*/ aValues = aDisplayItem.GetProperties(aNames); +/*N*/ aDisplayItem.EnableNotification(aNames); +/*N*/ pValues = aValues.getConstArray(); +/*N*/ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed"); +/*N*/ if(aValues.getLength() == aNames.getLength()) +/*N*/ { +/*N*/ for(int nProp = 0; nProp < aNames.getLength(); nProp++) +/*N*/ { +/*N*/ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing"); +/*N*/ if(pValues[nProp].hasValue()) +/*N*/ { +/*N*/ switch(nProp) +/*N*/ { +/*N*/ case SCDISPLAYOPT_FORMULA: +/*N*/ SetOption( VOPT_FORMULAS, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCDISPLAYOPT_ZEROVALUE: +/*N*/ SetOption( VOPT_NULLVALS, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCDISPLAYOPT_NOTETAG: +/*N*/ SetOption( VOPT_NOTES, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCDISPLAYOPT_VALUEHI: +/*N*/ SetOption( VOPT_SYNTAX, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCDISPLAYOPT_ANCHOR: +/*N*/ SetOption( VOPT_ANCHOR, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCDISPLAYOPT_TEXTOVER: +/*N*/ SetOption( VOPT_CLIPMARKS, ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCDISPLAYOPT_OBJECTGRA: +/*N*/ if ( pValues[nProp] >>= nIntVal ) +/*N*/ SetObjMode( VOBJ_TYPE_OLE, (ScVObjMode) nIntVal ); +/*N*/ break; +/*N*/ case SCDISPLAYOPT_CHART: +/*N*/ if ( pValues[nProp] >>= nIntVal ) +/*N*/ SetObjMode( VOBJ_TYPE_CHART, (ScVObjMode) nIntVal ); +/*N*/ break; +/*N*/ case SCDISPLAYOPT_DRAWING: +/*N*/ if ( pValues[nProp] >>= nIntVal ) +/*N*/ SetObjMode( VOBJ_TYPE_DRAW, (ScVObjMode) nIntVal ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ aDisplayItem.SetCommitLink( LINK( this, ScViewCfg, DisplayCommitHdl ) ); +/*N*/ +/*N*/ ScGridOptions aGrid = GetGridOptions(); //! initialization necessary? +/*N*/ aNames = GetGridPropertyNames(); +/*N*/ aValues = aGridItem.GetProperties(aNames); +/*N*/ aGridItem.EnableNotification(aNames); +/*N*/ pValues = aValues.getConstArray(); +/*N*/ DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed"); +/*N*/ if(aValues.getLength() == aNames.getLength()) +/*N*/ { +/*N*/ for(int nProp = 0; nProp < aNames.getLength(); nProp++) +/*N*/ { +/*N*/ DBG_ASSERT(pValues[nProp].hasValue(), "property value missing"); +/*N*/ if(pValues[nProp].hasValue()) +/*N*/ { +/*N*/ switch(nProp) +/*N*/ { +/*N*/ case SCGRIDOPT_RESOLU_X: +/*N*/ if (pValues[nProp] >>= nIntVal) aGrid.SetFldDrawX( nIntVal ); +/*N*/ break; +/*N*/ case SCGRIDOPT_RESOLU_Y: +/*N*/ if (pValues[nProp] >>= nIntVal) aGrid.SetFldDrawY( nIntVal ); +/*N*/ break; +/*N*/ case SCGRIDOPT_SUBDIV_X: +/*N*/ if (pValues[nProp] >>= nIntVal) aGrid.SetFldDivisionX( nIntVal ); +/*N*/ break; +/*N*/ case SCGRIDOPT_SUBDIV_Y: +/*N*/ if (pValues[nProp] >>= nIntVal) aGrid.SetFldDivisionY( nIntVal ); +/*N*/ break; +/*N*/ case SCGRIDOPT_OPTION_X: +/*N*/ if (pValues[nProp] >>= nIntVal) aGrid.SetFldSnapX( nIntVal ); +/*N*/ break; +/*N*/ case SCGRIDOPT_OPTION_Y: +/*N*/ if (pValues[nProp] >>= nIntVal) aGrid.SetFldSnapY( nIntVal ); +/*N*/ break; +/*N*/ case SCGRIDOPT_SNAPTOGRID: +/*N*/ aGrid.SetUseGridSnap( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCGRIDOPT_SYNCHRON: +/*N*/ aGrid.SetSynchronize( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCGRIDOPT_VISIBLE: +/*N*/ aGrid.SetGridVisible( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ case SCGRIDOPT_SIZETOGRID: +/*N*/ aGrid.SetEqualGrid( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ SetGridOptions( aGrid ); +/*N*/ aGridItem.SetCommitLink( LINK( this, ScViewCfg, GridCommitHdl ) ); +/*N*/ } + +/*N*/ IMPL_LINK( ScViewCfg, LayoutCommitHdl, void *, EMPTYARG ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 Sequence<OUString> aNames = GetLayoutPropertyNames(); +/*N*/ return 0; +/*N*/ } + +/*N*/ IMPL_LINK( ScViewCfg, DisplayCommitHdl, void *, EMPTYARG ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 Sequence<OUString> aNames = GetDisplayPropertyNames(); +/*N*/ return 0; +/*N*/ } + +/*N*/ IMPL_LINK( ScViewCfg, GridCommitHdl, void *, EMPTYARG ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 const ScGridOptions& rGrid = GetGridOptions(); +/*N*/ return 0; +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sc/source/core/tool/sc_zforauto.cxx b/binfilter/bf_sc/source/core/tool/sc_zforauto.cxx new file mode 100644 index 000000000000..8d9d2cd141bd --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_zforauto.cxx @@ -0,0 +1,86 @@ +/* -*- 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. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +//------------------------------------------------------------------------ + +#include <bf_svtools/zformat.hxx> +#include <vcl/svapp.hxx> +#include <tools/debug.hxx> + +#include "zforauto.hxx" +#include "global.hxx" +namespace binfilter { + +static const sal_Char __FAR_DATA pStandardName[] = "Standard"; + +//------------------------------------------------------------------------ + +/*N*/ ScNumFormatAbbrev::ScNumFormatAbbrev() : +/*N*/ eLnge (LANGUAGE_SYSTEM), +/*N*/ eSysLnge (LANGUAGE_GERMAN), // sonst passt "Standard" nicht +/*N*/ sFormatstring ( RTL_CONSTASCII_USTRINGPARAM( pStandardName ) ) +/*N*/ { +/*N*/ } + +/*N*/ ScNumFormatAbbrev::ScNumFormatAbbrev(const ScNumFormatAbbrev& aFormat) : +/*N*/ eLnge (aFormat.eLnge), +/*N*/ eSysLnge (aFormat.eSysLnge), +/*N*/ sFormatstring (aFormat.sFormatstring) +/*N*/ { +/*N*/ } + +/*N*/ void ScNumFormatAbbrev::Load( SvStream& rStream ) +/*N*/ { +/*N*/ USHORT nSysLang, nLang; +/*N*/ rStream.ReadByteString( sFormatstring, rStream.GetStreamCharSet() ); +/*N*/ rStream >> nSysLang >> nLang; +/*N*/ eLnge = (LanguageType) nLang; +/*N*/ eSysLnge = (LanguageType) nSysLang; +/*N*/ if ( eSysLnge == LANGUAGE_SYSTEM ) // old versions did write it +/*N*/ eSysLnge = Application::GetSettings().GetLanguage(); +/*N*/ } + +/*N*/ void ScNumFormatAbbrev::Save( SvStream& rStream ) const +/*N*/ { +/*N*/ rStream.WriteByteString( sFormatstring, rStream.GetStreamCharSet() ); +/*N*/ rStream << (USHORT) eSysLnge << (USHORT) eLnge; +/*N*/ } + + + + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |