summaryrefslogtreecommitdiff
path: root/binfilter/bf_sc/source/core/tool
diff options
context:
space:
mode:
Diffstat (limited to 'binfilter/bf_sc/source/core/tool')
-rw-r--r--binfilter/bf_sc/source/core/tool/makefile.mk107
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_addincol.cxx1119
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_addinhelpid.cxx221
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_addinlis.cxx192
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_adiasync.cxx148
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_appoptio.cxx678
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_autoform.cxx906
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_callform.cxx318
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_cellform.cxx219
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_chartarr.cxx1203
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_chartlis.cxx354
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_chgtrack.cxx3853
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_chgviset.cxx161
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_collect.cxx374
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_compiler.cxx3240
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_consoli.cxx606
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_dbcolect.cxx979
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_ddelink.cxx154
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_detdata.cxx142
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_detfunc.cxx1695
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_docoptio.cxx410
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_editutil.cxx511
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_hints.cxx128
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_indexmap.cxx67
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_inputopt.cxx267
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_interpr1.cxx5432
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_interpr2.cxx2149
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_interpr3.cxx3764
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_interpr4.cxx3249
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_interpr5.cxx4062
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_interpr6.cxx182
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_optutil.cxx75
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_printopt.cxx107
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_prnsave.cxx122
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_progress.cxx129
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_rangelst.cxx555
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_rangenam.cxx578
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_rangeseq.cxx342
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_rangeutl.cxx243
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_rechead.cxx233
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_refdata.cxx298
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_refreshtimer.cxx67
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_refupdat.cxx768
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_scmatrix.cxx565
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_subtotal.cxx144
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_token.cxx1819
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_unitconv.cxx179
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_userlist.cxx241
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_viewopti.cxx675
-rw-r--r--binfilter/bf_sc/source/core/tool/sc_zforauto.cxx86
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*) &rArr;
+/*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: */