/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" #include "excform.hxx" #include #include "cell.hxx" #include "document.hxx" #include "rangenam.hxx" #include "global.hxx" #include "formula/errorcodes.hxx" #include "imp_op.hxx" #include "root.hxx" #include "xltracer.hxx" #include "xihelper.hxx" #include "xilink.hxx" #include "xiname.hxx" using ::std::vector; const sal_uInt16 ExcelToSc::nRowMask = 0x3FFF; const sal_uInt16 ExcelToSc::nLastInd = 399; void ImportExcel::Formula25() { XclAddress aXclPos; sal_uInt16 nXF = 0, nFormLen; double fCurVal; sal_uInt8 nFlag0; sal_Bool bShrFmla; aIn >> aXclPos; if( GetBiff() == EXC_BIFF2 ) {// BIFF2 sal_uInt8 nDummy; aIn.Ignore( 3 ); aIn >> fCurVal; aIn.Ignore( 1 ); aIn >> nDummy; nFormLen = nDummy; bShrFmla = sal_False; } else {// BIFF5 aIn >> nXF >> fCurVal >> nFlag0; aIn.Ignore( 5 ); aIn >> nFormLen; bShrFmla = nFlag0 & 0x08; // shared or not shared } Formula( aXclPos, nXF, nFormLen, fCurVal, bShrFmla ); } void ImportExcel::Formula3() { Formula4(); } void ImportExcel::Formula4() { XclAddress aXclPos; sal_uInt16 nXF, nFormLen; double fCurVal; sal_uInt8 nFlag0; aIn >> aXclPos >> nXF >> fCurVal >> nFlag0; aIn.Ignore( 1 ); aIn >> nFormLen; Formula( aXclPos, nXF, nFormLen, fCurVal, sal_False ); } void ImportExcel::Formula( const XclAddress& rXclPos, sal_uInt16 nXF, sal_uInt16 nFormLen, double& rCurVal, sal_Bool bShrFmla ) { ConvErr eErr = ConvOK; ScAddress aScPos( ScAddress::UNINITIALIZED ); if( GetAddressConverter().ConvertAddress( aScPos, rXclPos, GetCurrScTab(), true ) ) { // jetzt steht Lesemarke auf Formel, Laenge in nFormLen const ScTokenArray* pErgebnis = 0; sal_Bool bConvert; pFormConv->Reset( aScPos ); if( bShrFmla ) bConvert = !pFormConv->GetShrFmla( pErgebnis, maStrm, nFormLen ); else bConvert = sal_True; if( bConvert ) eErr = pFormConv->Convert( pErgebnis, maStrm, nFormLen, true, FT_CellFormula); ScFormulaCell* pZelle = NULL; if( pErgebnis ) { pZelle = new ScFormulaCell( pD, aScPos, pErgebnis ); pD->PutCell( aScPos.Col(), aScPos.Row(), aScPos.Tab(), pZelle, (sal_Bool)sal_True ); } else { CellType eCellType; ScBaseCell* pBaseCell; pD->GetCellType( aScPos.Col(), aScPos.Row(), aScPos.Tab(), eCellType ); if( eCellType == CELLTYPE_FORMULA ) { pD->GetCell( aScPos.Col(), aScPos.Row(), aScPos.Tab(), pBaseCell ); pZelle = ( ScFormulaCell* ) pBaseCell; if( pZelle ) pZelle->AddRecalcMode( RECALCMODE_ONLOAD_ONCE ); } } if( pZelle ) { if( eErr != ConvOK ) ExcelToSc::SetError( *pZelle, eErr ); #if 0 else ExcelToSc::SetCurVal( *pZelle, rCurVal ); #else (void)rCurVal; #endif } GetXFRangeBuffer().SetXF( aScPos, nXF ); } } ExcelToSc::ExcelToSc( const XclImpRoot& rRoot ) : ExcelConverterBase( 512 ), XclImpRoot( rRoot ), maFuncProv( rRoot ), meBiff( rRoot.GetBiff() ) { } ExcelToSc::~ExcelToSc() { } void ExcelToSc::GetDummy( const ScTokenArray*& pErgebnis ) { aPool.Store( CREATE_STRING( "Dummy()" ) ); aPool >> aStack; pErgebnis = aPool[ aStack.Get() ]; } // if bAllowArrays is false stream seeks to first byte after // otherwise it will seek to the first byte after the additional content (eg // inline arrays) following ConvErr ExcelToSc::Convert( const ScTokenArray*& pErgebnis, XclImpStream& aIn, sal_Size nFormulaLen, bool bAllowArrays, const FORMULA_TYPE eFT ) { RootData& rR = GetOldRoot(); sal_uInt8 nOp, nLen, nByte; sal_uInt16 nUINT16; sal_Int16 nINT16; double fDouble; String aString; sal_Bool bError = sal_False; sal_Bool bArrayFormula = sal_False; TokenId nMerk0; const sal_Bool bRangeName = eFT == FT_RangeName; const sal_Bool bSharedFormula = eFT == FT_SharedFormula; const sal_Bool bConditional = eFT == FT_Conditional; const sal_Bool bRNorSF = bRangeName || bSharedFormula || bConditional; ScSingleRefData aSRD; ScComplexRefData aCRD; ExtensionTypeVec aExtensions; bExternName = sal_False; if( eStatus != ConvOK ) { aIn.Ignore( nFormulaLen ); return eStatus; } if( nFormulaLen == 0 ) { aPool.Store( CREATE_STRING( "-/-" ) ); aPool >> aStack; pErgebnis = aPool[ aStack.Get() ]; return ConvOK; } sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen; while( (aIn.GetRecPos() < nEndPos) && !bError ) { aIn >> nOp; // #98524# always reset flags aSRD.InitFlags(); aCRD.InitFlags(); switch( nOp ) // Buch Seite: { // SDK4 SDK5 case 0x01: // Array Formula [325 ] // Array Formula or Shared Formula [ 277] case 0x02: // Data Table [325 277] nUINT16 = 3; if( meBiff != EXC_BIFF2 ) nUINT16++; aIn.Ignore( nUINT16 ); bArrayFormula = sal_True; break; case 0x03: // Addition [312 264] aStack >> nMerk0; aPool << aStack << ocAdd << nMerk0; aPool >> aStack; break; case 0x04: // Subtraction [313 264] // SECOMD-TOP minus TOP aStack >> nMerk0; aPool << aStack << ocSub << nMerk0; aPool >> aStack; break; case 0x05: // Multiplication [313 264] aStack >> nMerk0; aPool << aStack << ocMul << nMerk0; aPool >> aStack; break; case 0x06: // Division [313 264] // divide TOP by SECOND-TOP aStack >> nMerk0; aPool << aStack << ocDiv << nMerk0; aPool >> aStack; break; case 0x07: // Exponetiation [313 265] // raise SECOND-TOP to power of TOP aStack >> nMerk0; aPool << aStack << ocPow << nMerk0; aPool >> aStack; break; case 0x08: // Concatenation [313 265] // append TOP to SECOND-TOP aStack >> nMerk0; aPool << aStack << ocAmpersand << nMerk0; aPool >> aStack; break; case 0x09: // Less Than [313 265] // SECOND-TOP < TOP aStack >> nMerk0; aPool << aStack << ocLess << nMerk0; aPool >> aStack; break; case 0x0A: // Less Than or Equal [313 265] // SECOND-TOP <= TOP aStack >> nMerk0; aPool << aStack << ocLessEqual << nMerk0; aPool >> aStack; break; case 0x0B: // Equal [313 265] // SECOND-TOP == TOP aStack >> nMerk0; aPool << aStack << ocEqual << nMerk0; aPool >> aStack; break; case 0x0C: // Greater Than or Equal [313 265] // SECOND-TOP == TOP aStack >> nMerk0; aPool << aStack << ocGreaterEqual << nMerk0; aPool >> aStack; break; case 0x0D: // Greater Than [313 265] // SECOND-TOP == TOP aStack >> nMerk0; aPool << aStack << ocGreater << nMerk0; aPool >> aStack; break; case 0x0E: // Not Equal [313 265] // SECOND-TOP == TOP aStack >> nMerk0; aPool << aStack << ocNotEqual << nMerk0; aPool >> aStack; break; case 0x0F: // Intersection [314 265] aStack >> nMerk0; aPool << aStack << ocIntersect << nMerk0; aPool >> aStack; break; case 0x10: // Union [314 265] // ocSep behelfsweise statt 'ocUnion' aStack >> nMerk0; //#100928# aPool << ocOpen << aStack << ocSep << nMerk0 << ocClose; aPool << aStack << ocSep << nMerk0; // doesn't fit exactly, but is more Excel-like aPool >> aStack; break; case 0x11: // Range [314 265] aStack >> nMerk0; aPool << aStack << ocRange << nMerk0; aPool >> aStack; break; case 0x12: // Unary Plus [312 264] aPool << ocAdd << aStack; aPool >> aStack; break; case 0x13: // Unary Minus [312 264] aPool << ocNegSub << aStack; aPool >> aStack; break; case 0x14: // Percent Sign [312 264] aPool << aStack << ocPercentSign; aPool >> aStack; break; case 0x15: // Parenthesis [326 278] aPool << ocOpen << aStack << ocClose; aPool >> aStack; break; case 0x16: // Missing Argument [314 266] aPool << ocMissing; aPool >> aStack; GetTracer().TraceFormulaMissingArg(); break; case 0x17: // String Constant [314 266] aIn >> nLen; aString = aIn.ReadRawByteString( nLen ); aStack << aPool.Store( aString ); break; case 0x19: // Special Attribute [327 279] { sal_uInt16 nData, nFakt; sal_uInt8 nOpt; aIn >> nOpt; if( meBiff == EXC_BIFF2 ) { nData = aIn.ReaduInt8(); nFakt = 1; } else { aIn >> nData; nFakt = 2; } if( nOpt & 0x04 ) {// nFakt -> Bytes oder Words ueberlesen AttrChoose nData++; aIn.Ignore( nData * nFakt ); } else if( nOpt & 0x10 ) // AttrSum DoMulArgs( ocSum, 1 ); } break; case 0x1A: // External Reference [330 ] switch( meBiff ) { case EXC_BIFF2: aIn.Ignore( 7 ); break; case EXC_BIFF3: case EXC_BIFF4: aIn.Ignore( 10 ); break; case EXC_BIFF5: DBG_WARNING( "-ExcelToSc::Convert(): 0x1A gibt's nicht in Biff5!" ); default: DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" ); } break; case 0x1B: // End External Reference [330 ] switch( meBiff ) { case EXC_BIFF2: aIn.Ignore( 3 ); break; case EXC_BIFF3: case EXC_BIFF4: aIn.Ignore( 4 ); break; case EXC_BIFF5: DBG_WARNING( "-ExcelToSc::Convert(): 0x1B gibt's nicht in Biff5!" ); default: DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" ); } break; case 0x1C: // Error Value [314 266] { aIn >> nByte; #if 0 // erAck aPool.StoreError( XclTools::GetScErrorCode( nByte ) ); #else DefTokenId eOc; switch( nByte ) { case EXC_ERR_NULL: case EXC_ERR_DIV0: case EXC_ERR_VALUE: case EXC_ERR_REF: case EXC_ERR_NAME: case EXC_ERR_NUM: eOc = ocStop; break; case EXC_ERR_NA: eOc = ocNotAvail; break; default: eOc = ocNoName; } aPool << eOc; if( eOc != ocStop ) aPool << ocOpen << ocClose; #endif aPool >> aStack; } break; case 0x1D: // Boolean [315 266] aIn >> nByte; if( nByte == 0 ) aPool << ocFalse << ocOpen << ocClose; else aPool << ocTrue << ocOpen << ocClose; aPool >> aStack; break; case 0x1E: // Integer [315 266] aIn >> nUINT16; aStack << aPool.Store( ( double ) nUINT16 ); break; case 0x1F: // Number [315 266] aIn >> fDouble; aStack << aPool.Store( fDouble ); break; case 0x40: case 0x60: case 0x20: // Array Constant [317 268] aIn >> nByte >> nUINT16; aIn.Ignore( (meBiff == EXC_BIFF2) ? 3 : 4 ); if( bAllowArrays ) { aStack << aPool.StoreMatrix(); aExtensions.push_back( EXTENSION_ARRAY ); } else { aPool << ocBad; aPool >> aStack; } break; case 0x41: case 0x61: case 0x21: // Function, Fixed Number of Arguments [333 282] { sal_uInt16 nXclFunc; if( meBiff <= EXC_BIFF3 ) nXclFunc = aIn.ReaduInt8(); else aIn >> nXclFunc; if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) ) DoMulArgs( pFuncInfo->meOpCode, pFuncInfo->mnMaxParamCount, pFuncInfo->mnMinParamCount ); else DoMulArgs( ocNoName, 0 ); } break; case 0x42: case 0x62: case 0x22: // Function, Variable Number of Arg. [333 283] { sal_uInt16 nXclFunc; sal_uInt8 nParamCount; aIn >> nParamCount; nParamCount &= 0x7F; if( meBiff <= EXC_BIFF3 ) nXclFunc = aIn.ReaduInt8(); else aIn >> nXclFunc; if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclFunc( nXclFunc ) ) DoMulArgs( pFuncInfo->meOpCode, nParamCount, pFuncInfo->mnMinParamCount ); else DoMulArgs( ocNoName, 0 ); } break; case 0x43: case 0x63: case 0x23: // Name [318 269] { aIn >> nUINT16; switch( meBiff ) { case EXC_BIFF2: aIn.Ignore( 5 ); break; case EXC_BIFF3: case EXC_BIFF4: aIn.Ignore( 8 ); break; case EXC_BIFF5: aIn.Ignore( 12 ); break; default: DBG_ERROR( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" ); } const XclImpName* pName = GetNameManager().GetName( nUINT16 ); if(pName && !pName->GetScRangeData()) aStack << aPool.Store( ocMacro, pName->GetXclName() ); else aStack << aPool.Store( nUINT16 ); } break; case 0x44: case 0x64: case 0x24: // Cell Reference [319 270] case 0x4A: case 0x6A: case 0x2A: // Deleted Cell Reference [323 273] aIn >> nUINT16 >> nByte; aSRD.nCol = static_cast(nByte); aSRD.nRow = nUINT16 & 0x3FFF; aSRD.nRelTab = 0; aSRD.SetTabRel( sal_True ); aSRD.SetFlag3D( bRangeName ); ExcRelToScRel( nUINT16, nByte, aSRD, bRangeName ); switch ( nOp ) { case 0x4A: case 0x6A: case 0x2A: // Deleted Cell Reference [323 273] // no information which part is deleted, set both aSRD.SetColDeleted( sal_True ); aSRD.SetRowDeleted( sal_True ); } aStack << aPool.Store( aSRD ); break; case 0x45: case 0x65: case 0x25: // Area Reference [320 270] case 0x4B: case 0x6B: case 0x2B: // Deleted Area Refernce [323 273] { sal_uInt16 nRowFirst, nRowLast; sal_uInt8 nColFirst, nColLast; ScSingleRefData& rSRef1 = aCRD.Ref1; ScSingleRefData& rSRef2 = aCRD.Ref2; aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast; rSRef1.nRelTab = rSRef2.nRelTab = 0; rSRef1.SetTabRel( sal_True ); rSRef2.SetTabRel( sal_True ); rSRef1.SetFlag3D( bRangeName ); rSRef2.SetFlag3D( bRangeName ); ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName ); ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName ); if( IsComplColRange( nColFirst, nColLast ) ) SetComplCol( aCRD ); else if( IsComplRowRange( nRowFirst, nRowLast ) ) SetComplRow( aCRD ); switch ( nOp ) { case 0x4B: case 0x6B: case 0x2B: // Deleted Area Refernce [323 273] // no information which part is deleted, set all rSRef1.SetColDeleted( sal_True ); rSRef1.SetRowDeleted( sal_True ); rSRef2.SetColDeleted( sal_True ); rSRef2.SetRowDeleted( sal_True ); } aStack << aPool.Store( aCRD ); } break; case 0x46: case 0x66: case 0x26: // Constant Reference Subexpression [321 271] aExtensions.push_back( EXTENSION_MEMAREA ); // fall through case 0x47: case 0x67: case 0x27: // Erroneous Constant Reference Subexpr. [322 272] case 0x48: case 0x68: case 0x28: // Incomplete Constant Reference Subexpr.[331 281] aIn.Ignore( (meBiff == EXC_BIFF2) ? 4 : 6 ); break; case 0x4C: case 0x6C: case 0x2C: // Cell Reference Within a Name [323 ] // Cell Reference Within a Shared Formula[ 273] { aIn >> nUINT16 >> nByte; // >> Attribute, Row >> Col aSRD.nRelTab = 0; aSRD.SetTabRel( sal_True ); aSRD.SetFlag3D( bRangeName ); ExcRelToScRel( nUINT16, nByte, aSRD, bRNorSF ); aStack << aPool.Store( aSRD ); } break; case 0x4D: case 0x6D: case 0x2D: // Area Reference Within a Name [324 ] { // Area Reference Within a Shared Formula[ 274] sal_uInt16 nRowFirst, nRowLast; sal_uInt8 nColFirst, nColLast; aCRD.Ref1.nRelTab = aCRD.Ref2.nRelTab = 0; aCRD.Ref1.SetTabRel( sal_True ); aCRD.Ref2.SetTabRel( sal_True ); aCRD.Ref1.SetFlag3D( bRangeName ); aCRD.Ref2.SetFlag3D( bRangeName ); aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast; ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF ); ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRNorSF ); if( IsComplColRange( nColFirst, nColLast ) ) SetComplCol( aCRD ); else if( IsComplRowRange( nRowFirst, nRowLast ) ) SetComplRow( aCRD ); aStack << aPool.Store( aCRD ); } break; case 0x49: case 0x69: case 0x29: // Variable Reference Subexpression [331 281] case 0x4E: case 0x6E: case 0x2E: // Reference Subexpression Within a Name [332 282] case 0x4F: case 0x6F: case 0x2F: // Incomplete Reference Subexpression... [332 282] aIn.Ignore( (meBiff == EXC_BIFF2) ? 1 : 2 ); break; case 0x58: case 0x78: case 0x38: // Command-Equivalent Function [333 ] aString.AssignAscii( "COMM_EQU_FUNC" ); aIn >> nByte; aString += String::CreateFromInt32( nByte ); aIn >> nByte; aStack << aPool.Store( aString ); DoMulArgs( ocPush, nByte + 1 ); break; case 0x59: case 0x79: case 0x39: // Name or External Name [ 275] aIn >> nINT16; aIn.Ignore( 8 ); aIn >> nUINT16; if( nINT16 >= 0 ) { const ExtName* pExtName = rR.pExtNameBuff->GetNameByIndex( nINT16, nUINT16 ); if( pExtName && pExtName->IsDDE() && rR.pExtSheetBuff->IsLink( ( sal_uInt16 ) nINT16 ) ) { String aAppl, aExtDoc; TokenId nPar1, nPar2; rR.pExtSheetBuff->GetLink( ( sal_uInt16 ) nINT16 , aAppl, aExtDoc ); nPar1 = aPool.Store( aAppl ); nPar2 = aPool.Store( aExtDoc ); nMerk0 = aPool.Store( pExtName->aName ); aPool << ocDde << ocOpen << nPar1 << ocSep << nPar2 << ocSep << nMerk0 << ocClose; GetDoc().CreateDdeLink( aAppl, aExtDoc, pExtName->aName, SC_DDE_DEFAULT ); } else aPool << ocBad; aPool >> aStack; } else aStack << aPool.Store( nUINT16 ); aIn.Ignore( 12 ); break; case 0x5A: case 0x7A: case 0x3A: // 3-D Cell Reference [ 275] case 0x5C: case 0x7C: case 0x3C: // Deleted 3-D Cell Reference [ 277] { sal_uInt16 nTabFirst, nTabLast, nRow; sal_Int16 nExtSheet; sal_uInt8 nCol; aIn >> nExtSheet; aIn.Ignore( 8 ); aIn >> nTabFirst >> nTabLast >> nRow >> nCol; if( nExtSheet >= 0 ) { // von extern if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) ) { nTabFirst = nTabLast; nExtSheet = 0; // gefunden } else { aPool << ocBad; aPool >> aStack; nExtSheet = 1; // verhindert Erzeugung einer SingleRef } } if( nExtSheet <= 0 ) { // in aktuellem Workbook aSRD.nTab = static_cast(nTabFirst); aSRD.SetFlag3D( sal_True ); aSRD.SetTabRel( sal_False ); ExcRelToScRel( nRow, nCol, aSRD, bRangeName ); switch ( nOp ) { case 0x5C: case 0x7C: case 0x3C: // Deleted 3-D Cell Reference [ 277] // no information which part is deleted, set both aSRD.SetColDeleted( sal_True ); aSRD.SetRowDeleted( sal_True ); } if ( !ValidTab(static_cast(nTabFirst)) ) aSRD.SetTabDeleted( sal_True ); if( nTabLast != nTabFirst ) { aCRD.Ref1 = aCRD.Ref2 = aSRD; aCRD.Ref2.nTab = static_cast(nTabLast); aCRD.Ref2.SetTabDeleted( !ValidTab(static_cast(nTabLast)) ); aStack << aPool.Store( aCRD ); } else aStack << aPool.Store( aSRD ); } } break; case 0x5B: case 0x7B: case 0x3B: // 3-D Area Reference [ 276] case 0x5D: case 0x7D: case 0x3D: // Deleted 3-D Area Reference [ 277] { sal_uInt16 nTabFirst, nTabLast, nRowFirst, nRowLast; sal_Int16 nExtSheet; sal_uInt8 nColFirst, nColLast; aIn >> nExtSheet; aIn.Ignore( 8 ); aIn >> nTabFirst >> nTabLast >> nRowFirst >> nRowLast >> nColFirst >> nColLast; if( nExtSheet >= 0 ) // von extern { if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) ) { nTabFirst = nTabLast; nExtSheet = 0; // gefunden } else { aPool << ocBad; aPool >> aStack; nExtSheet = 1; // verhindert Erzeugung einer CompleteRef } } if( nExtSheet <= 0 ) {// in aktuellem Workbook // erster Teil des Bereichs ScSingleRefData& rR1 = aCRD.Ref1; ScSingleRefData& rR2 = aCRD.Ref2; rR1.nTab = static_cast(nTabFirst); rR2.nTab = static_cast(nTabLast); rR1.SetFlag3D( sal_True ); rR1.SetTabRel( sal_False ); rR2.SetFlag3D( nTabFirst != nTabLast ); rR2.SetTabRel( sal_False ); ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName ); ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName ); if( IsComplColRange( nColFirst, nColLast ) ) SetComplCol( aCRD ); else if( IsComplRowRange( nRowFirst, nRowLast ) ) SetComplRow( aCRD ); switch ( nOp ) { case 0x5D: case 0x7D: case 0x3D: // Deleted 3-D Area Reference [ 277] // no information which part is deleted, set all rR1.SetColDeleted( sal_True ); rR1.SetRowDeleted( sal_True ); rR2.SetColDeleted( sal_True ); rR2.SetRowDeleted( sal_True ); } if ( !ValidTab(static_cast(nTabFirst)) ) rR1.SetTabDeleted( sal_True ); if ( !ValidTab(static_cast(nTabLast)) ) rR2.SetTabDeleted( sal_True ); aStack << aPool.Store( aCRD ); }//ENDE in aktuellem Workbook } break; default: bError = sal_True; } bError |= !aIn.IsValid(); } ConvErr eRet; if( bError ) { aPool << ocBad; aPool >> aStack; pErgebnis = aPool[ aStack.Get() ]; eRet = ConvErrNi; } else if( aIn.GetRecPos() != nEndPos ) { aPool << ocBad; aPool >> aStack; pErgebnis = aPool[ aStack.Get() ]; eRet = ConvErrCount; } else if( bExternName ) { pErgebnis = aPool[ aStack.Get() ]; eRet = ConvErrExternal; } else if( bArrayFormula ) { pErgebnis = NULL; eRet = ConvOK; } else { pErgebnis = aPool[ aStack.Get() ]; eRet = ConvOK; } aIn.Seek( nEndPos ); if( eRet == ConvOK ) ReadExtensions( aExtensions, aIn ); return eRet; } // stream seeks to first byte after ConvErr ExcelToSc::Convert( _ScRangeListTabs& rRangeList, XclImpStream& aIn, sal_Size nFormulaLen, const FORMULA_TYPE eFT ) { RootData& rR = GetOldRoot(); sal_uInt8 nOp, nLen; sal_Size nIgnore; sal_uInt16 nUINT16; sal_uInt8 nByte; sal_Bool bError = sal_False; sal_Bool bArrayFormula = sal_False; const sal_Bool bRangeName = eFT == FT_RangeName; const sal_Bool bSharedFormula = eFT == FT_SharedFormula; const sal_Bool bRNorSF = bRangeName || bSharedFormula; ScSingleRefData aSRD; ScComplexRefData aCRD; aCRD.Ref1.nTab = aCRD.Ref2.nTab = aEingPos.Tab(); bExternName = sal_False; if( eStatus != ConvOK ) { aIn.Ignore( nFormulaLen ); return eStatus; } if( nFormulaLen == 0 ) return ConvOK; sal_Size nEndPos = aIn.GetRecPos() + nFormulaLen; while( (aIn.GetRecPos() < nEndPos) && !bError ) { aIn >> nOp; nIgnore = 0; // #98524# always reset flags aSRD.InitFlags(); aCRD.InitFlags(); switch( nOp ) // Buch Seite: { // SDK4 SDK5 case 0x01: // Array Formula [325 ] // Array Formula or Shared Formula [ 277] nIgnore = (meBiff == EXC_BIFF2) ? 3 : 4; bArrayFormula = sal_True; break; case 0x02: // Data Table [325 277] nIgnore = (meBiff == EXC_BIFF2) ? 3 : 4; break; case 0x03: // Addition [312 264] case 0x04: // Subtraction [313 264] case 0x05: // Multiplication [313 264] case 0x06: // Division [313 264] case 0x07: // Exponetiation [313 265] case 0x08: // Concatenation [313 265] case 0x09: // Less Than [313 265] case 0x0A: // Less Than or Equal [313 265] case 0x0B: // Equal [313 265] case 0x0C: // Greater Than or Equal [313 265] case 0x0D: // Greater Than [313 265] case 0x0E: // Not Equal [313 265] case 0x0F: // Intersection [314 265] case 0x10: // Union [314 265] case 0x11: // Range [314 265] case 0x12: // Unary Plus [312 264] case 0x13: // Unary Minus [312 264] case 0x14: // Percent Sign [312 264] case 0x15: // Parenthesis [326 278] case 0x16: // Missing Argument [314 266] break; case 0x17: // String Constant [314 266] aIn >> nLen; nIgnore = nLen; break; case 0x19: // Special Attribute [327 279] { sal_uInt16 nData, nFakt; sal_uInt8 nOpt; aIn >> nOpt; if( meBiff == EXC_BIFF2 ) { nData = aIn.ReaduInt8(); nFakt = 1; } else { aIn >> nData; nFakt = 2; } if( nOpt & 0x04 ) {// nFakt -> Bytes oder Words ueberlesen AttrChoose nData++; aIn.Ignore( nData * nFakt ); } } break; case 0x1A: // External Reference [330 ] switch( meBiff ) { case EXC_BIFF2: nIgnore = 7; break; case EXC_BIFF3: case EXC_BIFF4: nIgnore = 10; break; case EXC_BIFF5: DBG_WARNING( "-ExcelToSc::Convert(): 0x1A gibt's nicht in Biff5!" ); default: DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" ); } break; case 0x1B: // End External Reference [330 ] switch( meBiff ) { case EXC_BIFF2: nIgnore = 3; break; case EXC_BIFF3: case EXC_BIFF4: nIgnore = 4; break; case EXC_BIFF5: DBG_WARNING( "-ExcelToSc::Convert(): 0x1B gibt's nicht in Biff5!" ); default: DBG_WARNING( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" ); } break; case 0x1C: // Error Value [314 266] case 0x1D: // Boolean [315 266] nIgnore = 1; break; case 0x1E: // Integer [315 266] nIgnore = 2; break; case 0x1F: // Number [315 266] nIgnore = 8; break; case 0x40: case 0x60: case 0x20: // Array Constant [317 268] nIgnore = (meBiff == EXC_BIFF2) ? 6 : 7; break; case 0x41: case 0x61: case 0x21: // Function, Fixed Number of Arguments [333 282] nIgnore = (meBiff <= EXC_BIFF3) ? 1 : 2; break; case 0x42: case 0x62: case 0x22: // Function, Variable Number of Arg. [333 283] nIgnore = (meBiff <= EXC_BIFF3) ? 2 : 3; break; case 0x43: case 0x63: case 0x23: // Name [318 269] switch( meBiff ) { case EXC_BIFF2: nIgnore = 7; break; case EXC_BIFF3: case EXC_BIFF4: nIgnore = 10; break; case EXC_BIFF5: nIgnore = 14; break; default: DBG_ERROR( "-ExcelToSc::Convert(): Ein wenig vergesslich, was?" ); } break; case 0x44: case 0x64: case 0x24: // Cell Reference [319 270] aIn >> nUINT16 >> nByte; aSRD.nCol = static_cast(nByte); aSRD.nRow = nUINT16 & 0x3FFF; aSRD.nRelTab = 0; aSRD.SetTabRel( sal_True ); aSRD.SetFlag3D( bRangeName ); ExcRelToScRel( nUINT16, nByte, aSRD, bRangeName ); rRangeList.Append( aSRD ); break; case 0x45: case 0x65: case 0x25: // Area Reference [320 270] { sal_uInt16 nRowFirst, nRowLast; sal_uInt8 nColFirst, nColLast; ScSingleRefData &rSRef1 = aCRD.Ref1; ScSingleRefData &rSRef2 = aCRD.Ref2; aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast; rSRef1.nRelTab = rSRef2.nRelTab = 0; rSRef1.SetTabRel( sal_True ); rSRef2.SetTabRel( sal_True ); rSRef1.SetFlag3D( bRangeName ); rSRef2.SetFlag3D( bRangeName ); ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName ); ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName ); if( IsComplColRange( nColFirst, nColLast ) ) SetComplCol( aCRD ); else if( IsComplRowRange( nRowFirst, nRowLast ) ) SetComplRow( aCRD ); rRangeList.Append( aCRD ); } break; case 0x46: case 0x66: case 0x26: // Constant Reference Subexpression [321 271] case 0x47: case 0x67: case 0x27: // Erroneous Constant Reference Subexpr. [322 272] case 0x48: case 0x68: case 0x28: // Incomplete Constant Reference Subexpr.[331 281] nIgnore = (meBiff == EXC_BIFF2) ? 4 : 6; break; case 0x4A: case 0x6A: case 0x2A: // Deleted Cell Reference [323 273] nIgnore = 3; break; case 0x4B: case 0x6B: case 0x2B: // Deleted Area Refernce [323 273] nIgnore = 6; break; case 0x4C: case 0x6C: case 0x2C: // Cell Reference Within a Name [323 ] // Cell Reference Within a Shared Formula[ 273] { aIn >> nUINT16 >> nByte; // >> Attribute, Row >> Col aSRD.nRelTab = 0; aSRD.SetTabRel( sal_True ); aSRD.SetFlag3D( bRangeName ); ExcRelToScRel( nUINT16, nByte, aSRD, bRNorSF ); rRangeList.Append( aSRD ); } break; case 0x4D: case 0x6D: case 0x2D: // Area Reference Within a Name [324 ] { // Area Reference Within a Shared Formula[ 274] sal_uInt16 nRowFirst, nRowLast; sal_uInt8 nColFirst, nColLast; aCRD.Ref1.nRelTab = aCRD.Ref2.nRelTab = 0; aCRD.Ref1.SetTabRel( sal_True ); aCRD.Ref2.SetTabRel( sal_True ); aCRD.Ref1.SetFlag3D( bRangeName ); aCRD.Ref2.SetFlag3D( bRangeName ); aIn >> nRowFirst >> nRowLast >> nColFirst >> nColLast; ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRNorSF ); ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRNorSF ); if( IsComplColRange( nColFirst, nColLast ) ) SetComplCol( aCRD ); else if( IsComplRowRange( nRowFirst, nRowLast ) ) SetComplRow( aCRD ); rRangeList.Append( aCRD ); } break; case 0x49: case 0x69: case 0x29: // Variable Reference Subexpression [331 281] case 0x4E: case 0x6E: case 0x2E: // Reference Subexpression Within a Name [332 282] case 0x4F: case 0x6F: case 0x2F: // Incomplete Reference Subexpression... [332 282] nIgnore = (meBiff == EXC_BIFF2) ? 1 : 2; break; case 0x58: case 0x78: case 0x38: // Command-Equivalent Function [333 ] nIgnore = 2; break; case 0x59: case 0x79: case 0x39: // Name or External Name [ 275] nIgnore = 24; break; case 0x5A: case 0x7A: case 0x3A: // 3-D Cell Reference [ 275] { sal_uInt16 nTabFirst, nTabLast, nRow; sal_Int16 nExtSheet; sal_uInt8 nCol; aIn >> nExtSheet; aIn.Ignore( 8 ); aIn >> nTabFirst >> nTabLast >> nRow >> nCol; if( nExtSheet >= 0 ) // von extern { if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) ) { nTabFirst = nTabLast; nExtSheet = 0; // gefunden } else { aPool << ocBad; aPool >> aStack; nExtSheet = 1; // verhindert Erzeugung einer SingleRef } } if( nExtSheet <= 0 ) {// in aktuellem Workbook sal_Bool b3D = ( static_cast(nTabFirst) != aEingPos.Tab() ) || bRangeName; aSRD.nTab = static_cast(nTabFirst); aSRD.SetFlag3D( b3D ); aSRD.SetTabRel( sal_False ); ExcRelToScRel( nRow, nCol, aSRD, bRangeName ); if( nTabLast != nTabFirst ) { aCRD.Ref1 = aSRD; aCRD.Ref2.nCol = aSRD.nCol; aCRD.Ref2.nRow = aSRD.nRow; aCRD.Ref2.nTab = static_cast(nTabLast); b3D = ( static_cast(nTabLast) != aEingPos.Tab() ); aCRD.Ref2.SetFlag3D( b3D ); aCRD.Ref2.SetTabRel( sal_False ); rRangeList.Append( aCRD ); } else rRangeList.Append( aSRD ); } } break; case 0x5B: case 0x7B: case 0x3B: // 3-D Area Reference [ 276] { sal_uInt16 nTabFirst, nTabLast, nRowFirst, nRowLast; sal_Int16 nExtSheet; sal_uInt8 nColFirst, nColLast; aIn >> nExtSheet; aIn.Ignore( 8 ); aIn >> nTabFirst >> nTabLast >> nRowFirst >> nRowLast >> nColFirst >> nColLast; if( nExtSheet >= 0 ) // von extern { if( rR.pExtSheetBuff->GetScTabIndex( nExtSheet, nTabLast ) ) { nTabFirst = nTabLast; nExtSheet = 0; // gefunden } else { aPool << ocBad; aPool >> aStack; nExtSheet = 1; // verhindert Erzeugung einer CompleteRef } } if( nExtSheet <= 0 ) {// in aktuellem Workbook // erster Teil des Bereichs ScSingleRefData &rR1 = aCRD.Ref1; ScSingleRefData &rR2 = aCRD.Ref2; rR1.nTab = static_cast(nTabFirst); rR2.nTab = static_cast(nTabLast); rR1.SetFlag3D( ( static_cast(nTabFirst) != aEingPos.Tab() ) || bRangeName ); rR1.SetTabRel( sal_False ); rR2.SetFlag3D( ( static_cast(nTabLast) != aEingPos.Tab() ) || bRangeName ); rR2.SetTabRel( sal_False ); ExcRelToScRel( nRowFirst, nColFirst, aCRD.Ref1, bRangeName ); ExcRelToScRel( nRowLast, nColLast, aCRD.Ref2, bRangeName ); if( IsComplColRange( nColFirst, nColLast ) ) SetComplCol( aCRD ); else if( IsComplRowRange( nRowFirst, nRowLast ) ) SetComplRow( aCRD ); rRangeList.Append( aCRD ); }//ENDE in aktuellem Workbook } break; case 0x5C: case 0x7C: case 0x3C: // Deleted 3-D Cell Reference [ 277] nIgnore = 17; break; case 0x5D: case 0x7D: case 0x3D: // Deleted 3-D Area Reference [ 277] nIgnore = 20; break; default: bError = sal_True; } bError |= !aIn.IsValid(); aIn.Ignore( nIgnore ); } ConvErr eRet; if( bError ) eRet = ConvErrNi; else if( aIn.GetRecPos() != nEndPos ) eRet = ConvErrCount; else if( bExternName ) eRet = ConvErrExternal; else if( bArrayFormula ) eRet = ConvOK; else eRet = ConvOK; aIn.Seek( nEndPos ); return eRet; } ConvErr ExcelToSc::ConvertExternName( const ScTokenArray*& /*rpArray*/, XclImpStream& /*rStrm*/, sal_Size /*nFormulaLen*/, const String& /*rUrl*/, const vector& /*rTabNames*/ ) { // not implemented ... return ConvErrNi; } sal_Bool ExcelToSc::GetAbsRefs( ScRangeList& rRangeList, XclImpStream& rStrm, sal_Size nLen ) { DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF5 ); if( GetBiff() != EXC_BIFF5 ) return sal_False; sal_uInt8 nOp; sal_uInt16 nRow1, nRow2; sal_uInt8 nCol1, nCol2; SCTAB nTab1, nTab2; sal_uInt16 nTabFirst, nTabLast; sal_Int16 nRefIdx; sal_Size nSeek; sal_Size nEndPos = rStrm.GetRecPos() + nLen; while( rStrm.IsValid() && (rStrm.GetRecPos() < nEndPos) ) { rStrm >> nOp; nSeek = 0; switch( nOp ) { case 0x44: case 0x64: case 0x24: // Cell Reference [319 270] case 0x4C: case 0x6C: case 0x2C: // Cell Reference Within a Name [323 ] // Cell Reference Within a Shared Formula[ 273] rStrm >> nRow1 >> nCol1; nRow2 = nRow1; nCol2 = nCol1; nTab1 = nTab2 = GetCurrScTab(); goto _common; case 0x45: case 0x65: case 0x25: // Area Reference [320 270] case 0x4D: case 0x6D: case 0x2D: // Area Reference Within a Name [324 ] // Area Reference Within a Shared Formula[ 274] rStrm >> nRow1 >> nRow2 >> nCol1 >> nCol2; nTab1 = nTab2 = GetCurrScTab(); goto _common; case 0x5A: case 0x7A: case 0x3A: // 3-D Cell Reference [ 275] rStrm >> nRefIdx; rStrm.Ignore( 8 ); rStrm >> nTabFirst >> nTabLast >> nRow1 >> nCol1; nRow2 = nRow1; nCol2 = nCol1; goto _3d_common; case 0x5B: case 0x7B: case 0x3B: // 3-D Area Reference [ 276] rStrm >> nRefIdx; rStrm.Ignore( 8 ); rStrm >> nTabFirst >> nTabLast >> nRow1 >> nRow2 >> nCol1 >> nCol2; _3d_common: nTab1 = static_cast< SCTAB >( nTabFirst ); nTab2 = static_cast< SCTAB >( nTabLast ); // #122885# skip references to deleted sheets if( (nRefIdx >= 0) || !ValidTab( nTab1 ) || (nTab1 != nTab2) ) break; goto _common; _common: // do not check abs/rel flags, linked controls have set them! // if( !(( nCol1 & 0xC000 ) || ( nCol2 & 0xC000 )) ) { ScRange aScRange; nRow1 &= 0x3FFF; nRow2 &= 0x3FFF; if( GetAddressConverter().ConvertRange( aScRange, XclRange( nCol1, nRow1, nCol2, nRow2 ), nTab1, nTab2, true ) ) rRangeList.Append( aScRange ); } break; case 0x03: // Addition [312 264] case 0x04: // Subtraction [313 264] case 0x05: // Multiplication [313 264] case 0x06: // Division [313 264] case 0x07: // Exponetiation [313 265] case 0x08: // Concatenation [313 265] case 0x09: // Less Than [313 265] case 0x0A: // Less Than or Equal [313 265] case 0x0B: // Equal [313 265] case 0x0C: // Greater Than or Equal [313 265] case 0x0D: // Greater Than [313 265] case 0x0E: // Not Equal [313 265] case 0x0F: // Intersection [314 265] case 0x10: // Union [314 265] case 0x11: // Range [314 265] case 0x12: // Unary Plus [312 264] case 0x13: // Unary Minus [312 264] case 0x14: // Percent Sign [312 264] case 0x15: // Parenthesis [326 278] case 0x16: // Missing Argument [314 266] break; case 0x1C: // Error Value [314 266] case 0x1D: // Boolean [315 266] nSeek = 1; break; case 0x1E: // Integer [315 266] case 0x41: case 0x61: case 0x21: // Function, Fixed Number of Arguments [333 282] case 0x49: case 0x69: case 0x29: // Variable Reference Subexpression [331 281] case 0x4E: case 0x6E: case 0x2E: // Reference Subexpression Within a Name [332 282] case 0x4F: case 0x6F: case 0x2F: // Incomplete Reference Subexpression... [332 282] case 0x58: case 0x78: case 0x38: // Command-Equivalent Function [333 ] nSeek = 2; break; case 0x42: case 0x62: case 0x22: // Function, Variable Number of Arg. [333 283] case 0x4A: case 0x6A: case 0x2A: // Deleted Cell Reference [323 273] nSeek = 3; break; case 0x01: // Array Formula [325 ] // Array Formula or Shared Formula [ 277] case 0x02: // Data Table [325 277] nSeek = 4; break; case 0x46: case 0x66: case 0x26: // Constant Reference Subexpression [321 271] case 0x47: case 0x67: case 0x27: // Erroneous Constant Reference Subexpr. [322 272] case 0x48: case 0x68: case 0x28: // Incomplete Constant Reference Subexpr.[331 281] case 0x4B: case 0x6B: case 0x2B: // Deleted Area Refernce [323 273] nSeek = 6; break; case 0x40: case 0x60: case 0x20: // Array Constant [317 268] nSeek = 7; break; case 0x1F: // Number [315 266] nSeek = 8; break; case 0x43: case 0x63: case 0x23: // Name [318 269] nSeek = 14; break; case 0x5C: case 0x7C: case 0x3C: // Deleted 3-D Cell Reference [ 277] nSeek = 17; break; case 0x5D: case 0x7D: case 0x3D: // Deleted 3-D Area Reference [ 277] nSeek = 20; break; case 0x59: case 0x79: case 0x39: // Name or External Name [ 275] nSeek = 24; break; case 0x17: // String Constant [314 266] nSeek = rStrm.ReaduInt8(); break; case 0x19: // Special Attribute [327 279] { sal_uInt8 nOpt; sal_uInt16 nData; rStrm >> nOpt >> nData; if( nOpt & 0x04 ) nSeek = nData * 2 + 2; } break; } rStrm.Ignore( nSeek ); } rStrm.Seek( nEndPos ); return rRangeList.Count() != 0; } static DefTokenId missArgForZeroList[] = { ocCount, ocCount2, ocAverage, ocMin, ocMinA, ocMax, ocMaxA, ocStDev, ocStDevA, ocVar, ocVarP, ocAveDev, ocKurt, ocSchiefe, ocVarPA, ocVarA, ocDevSq }; #define missArgForZeroCount sizeof(missArgForZeroList)/sizeof(DefTokenId) sal_Bool lcl_isInMissArgForZeroList(DefTokenId id) { for (sal_uInt32 nIndex = 0; nIndex < missArgForZeroCount; nIndex++) if(missArgForZeroList[nIndex] == id) return sal_True; return sal_False; } void ExcelToSc::DoMulArgs( DefTokenId eId, sal_uInt8 nAnz, sal_uInt8 nMinParamCount ) { TokenId eParam[ 256 ]; sal_Int32 nLauf; if( eId == ocCeil || eId == ocFloor ) { aStack << aPool.Store( 1.0 ); // default, da in Excel nicht vorhanden nAnz++; } for( nLauf = 0; aStack.HasMoreTokens() && (nLauf < nAnz); nLauf++ ) aStack >> eParam[ nLauf ]; // #i70925# reduce parameter count, if no more tokens available on token stack if( nLauf < nAnz ) nAnz = static_cast< sal_uInt8 >( nLauf ); if( nAnz > 0 && eId == ocExternal ) { TokenId n = eParam[ nAnz - 1 ]; //##### GRUETZE FUER BASIC-FUNCS RICHTEN! if( const String* pExt = aPool.GetExternal( n ) ) { if( const XclFunctionInfo* pFuncInfo = maFuncProv.GetFuncInfoFromXclMacroName( *pExt ) ) aPool << pFuncInfo->meOpCode; else aPool << n; nAnz--; } else aPool << eId; } else aPool << eId; aPool << ocOpen; if( nAnz > 0 ) { // attention: 0 = last parameter, nAnz-1 = first parameter sal_Int16 nNull = -1; // skip this parameter sal_Int16 nSkipEnd = -1; // skip all parameters <= nSkipEnd sal_Int16 nLast = nAnz - 1; // Funktionen, bei denen Parameter wegfallen muessen if( eId == ocPercentrank && nAnz == 3 ) nSkipEnd = 0; // letzten Parameter bei Bedarf weglassen // Joost-Spezialfaelle else if( eId == ocIf || lcl_isInMissArgForZeroList(eId)) { sal_uInt16 nNullParam = 0; for( nLauf = 0 ; nLauf < nAnz ; nLauf++ ) { if( aPool.IsSingleOp( eParam[ nLauf ], ocMissing ) ) { if( !nNullParam ) nNullParam = (sal_uInt16) aPool.Store( ( double ) 0.0 ); eParam[ nLauf ] = nNullParam; } } } // FIXME: ideally we'd want to import all missing args, but this // conflicts with lots of fn's understanding of nParams - we need // a function table, and pre-call argument normalisation 1st. sal_Int16 nLastRemovable = nLast - nMinParamCount; // #84453# skip missing parameters at end of parameter list while( nSkipEnd < nLastRemovable && aPool.IsSingleOp( eParam[ nSkipEnd + 1 ], ocMissing ) ) nSkipEnd++; // fprintf (stderr, "Fn %d nSkipEnd %d nLast %d nMinParamCnt %d %d\n", // eId, nSkipEnd, nLast, nMinParamCount, nLastRemovable); // [Parameter{;Parameter}] if( nLast > nSkipEnd ) { aPool << eParam[ nLast ]; for( nLauf = nLast - 1 ; nLauf > nSkipEnd ; nLauf-- ) { if( nLauf != nNull ) aPool << ocSep << eParam[ nLauf ]; } } } aPool << ocClose; aPool >> aStack; } void ExcelToSc::ExcRelToScRel( sal_uInt16 nRow, sal_uInt8 nCol, ScSingleRefData &rSRD, const sal_Bool bName ) { if( bName ) { // C O L if( nRow & 0x4000 ) {// rel Col rSRD.SetColRel( sal_True ); rSRD.nRelCol = static_cast(static_cast(nCol)); } else {// abs Col rSRD.SetColRel( sal_False ); rSRD.nCol = static_cast(nCol); } // R O W if( nRow & 0x8000 ) {// rel Row rSRD.SetRowRel( sal_True ); if( nRow & 0x2000 ) // Bit 13 gesetzt? // -> Row negativ rSRD.nRelRow = static_cast(static_cast(nRow | 0xC000)); else // -> Row positiv rSRD.nRelRow = static_cast(nRow & nRowMask); } else {// abs Row rSRD.SetRowRel( sal_False ); rSRD.nRow = static_cast(nRow & nRowMask); } // T A B // #67965# abs needed if rel in shared formula for ScCompiler UpdateNameReference if ( rSRD.IsTabRel() && !rSRD.IsFlag3D() ) rSRD.nTab = GetCurrScTab(); } else { // C O L rSRD.SetColRel( ( nRow & 0x4000 ) > 0 ); rSRD.nCol = static_cast(nCol); // R O W rSRD.SetRowRel( ( nRow & 0x8000 ) > 0 ); rSRD.nRow = static_cast(nRow & nRowMask); if ( rSRD.IsColRel() ) rSRD.nRelCol = rSRD.nCol - aEingPos.Col(); if ( rSRD.IsRowRel() ) rSRD.nRelRow = rSRD.nRow - aEingPos.Row(); // T A B // #i10184# abs needed if rel in shared formula for ScCompiler UpdateNameReference if ( rSRD.IsTabRel() && !rSRD.IsFlag3D() ) rSRD.nTab = GetCurrScTab() + rSRD.nRelTab; } } const ScTokenArray* ExcelToSc::GetBoolErr( XclBoolError eType ) { sal_uInt16 nError; aPool.Reset(); aStack.Reset(); DefTokenId eOc; switch( eType ) { case xlErrNull: eOc = ocStop; nError = errNoCode; break; case xlErrDiv0: eOc = ocStop; nError = errDivisionByZero; break; case xlErrValue: eOc = ocStop; nError = errNoValue; break; case xlErrRef: eOc = ocStop; nError = errNoRef; break; case xlErrName: eOc = ocStop; nError = errNoName; break; case xlErrNum: eOc = ocStop; nError = errIllegalFPOperation; break; case xlErrNA: eOc = ocNotAvail; nError = NOTAVAILABLE; break; case xlErrTrue: eOc = ocTrue; nError = 0; break; case xlErrFalse: eOc = ocFalse; nError = 0; break; case xlErrUnknown: eOc = ocStop; nError = errUnknownState; break; default: DBG_ERROR( "ExcelToSc::GetBoolErr - wrong enum!" ); eOc = ocNoName; nError = errUnknownState; } aPool << eOc; if( eOc != ocStop ) aPool << ocOpen << ocClose; aPool >> aStack; const ScTokenArray* pErgebnis = aPool[ aStack.Get() ]; if( nError ) ( ( ScTokenArray* ) pErgebnis )->SetCodeError( nError ); ( ( ScTokenArray* ) pErgebnis )->SetRecalcModeNormal(); return pErgebnis; } // if a shared formula was found, stream seeks to first byte after , // else stream pointer stays unchanged sal_Bool ExcelToSc::GetShrFmla( const ScTokenArray*& rpErgebnis, XclImpStream& aIn, sal_Size nFormulaLen ) { sal_uInt8 nOp; sal_Bool bRet = sal_True; if( nFormulaLen == 0 ) bRet = sal_False; else { aIn.PushPosition(); aIn >> nOp; if( nOp == 0x01 ) // Shared Formula [ 277] { sal_uInt16 nCol, nRow; aIn >> nRow >> nCol; aStack << aPool.Store( GetOldRoot().pShrfmlaBuff->Find( ScAddress( static_cast(nCol), static_cast(nRow), GetCurrScTab() ) ) ); bRet = sal_True; } else bRet = sal_False; aIn.PopPosition(); } if( bRet ) { aIn.Ignore( nFormulaLen ); rpErgebnis = aPool[ aStack.Get() ]; } else rpErgebnis = NULL; return bRet; } #if 0 sal_Bool ExcelToSc::SetCurVal( ScFormulaCell &rCell, double &rfCurVal ) { sal_uInt16 nInd; sal_uInt8 nType; sal_uInt8 nVal; sal_Bool bString = sal_False; #ifdef OSL_BIGENDIAN // Code fuer alle anstaendigen Prozessoren nType = *( ( ( sal_uInt8 * ) &rfCurVal ) + 7 ); nVal = *( ( ( sal_uInt8 * ) &rfCurVal ) + 5 ); nInd = *( ( sal_uInt16 * ) &rfCurVal ); #else // fuer Schund-Prozessoren nType = *( ( sal_uInt8 * ) &rfCurVal ); nVal = *( ( ( sal_uInt8 * ) &rfCurVal ) + 2 ); nInd = *( ( ( sal_uInt16 * ) &rfCurVal ) + 3 ); #endif if( ( sal_uInt16 ) ~nInd ) // Wert ist Float rCell.SetHybridDouble( rfCurVal ); else { switch( nType ) { case 0: // String bString = sal_True; break; case 1: // Bool if( nVal ) rfCurVal = 1.0; else rfCurVal = 0.0; rCell.SetHybridDouble( rfCurVal ); break; case 2: // Error rCell.SetErrCode( XclTools::GetScErrorCode( nVal ) ); break; } } return bString; } #endif void ExcelToSc::SetError( ScFormulaCell &rCell, const ConvErr eErr ) { sal_uInt16 nInd; switch( eErr ) { case ConvErrNi: nInd = errUnknownToken; break; case ConvErrNoMem: nInd = errCodeOverflow; break; case ConvErrExternal: nInd = errNoName; break; case ConvErrCount: nInd = errCodeOverflow; break; default: nInd = errNoCode; // hier fiel mir nichts // Besseres ein... } rCell.SetErrCode( nInd ); } void ExcelToSc::SetComplCol( ScComplexRefData &rCRD ) { ScSingleRefData &rSRD = rCRD.Ref2; if( rSRD.IsColRel() ) rSRD.nRelCol = MAXCOL - aEingPos.Col(); else rSRD.nCol = MAXCOL; } void ExcelToSc::SetComplRow( ScComplexRefData &rCRD ) { ScSingleRefData &rSRD = rCRD.Ref2; if( rSRD.IsRowRel() ) rSRD.nRelRow = MAXROW - aEingPos.Row(); else rSRD.nRow = MAXROW; } void ExcelToSc::ReadExtensionArray( unsigned int n, XclImpStream& aIn ) { // printf( "inline array;\n" ); sal_uInt8 nByte; sal_uInt16 nUINT16; double fDouble; String aString; ScMatrix* pMatrix; aIn >> nByte >> nUINT16; SCSIZE nC, nCols; SCSIZE nR, nRows; if( GetBiff() == EXC_BIFF8 ) { nCols = nByte + 1; nRows = nUINT16 + 1; } else { nCols = nByte ? nByte : 256; nRows = nUINT16; } pMatrix = aPool.GetMatrix( n ); if( NULL != pMatrix ) { pMatrix->Resize(nCols, nRows); pMatrix->GetDimensions( nC, nR); if( nC != nCols || nR != nRows ) { DBG_ERRORFILE( "ExcelToSc::ReadExtensionArray - matrix size mismatch" ); pMatrix = NULL; } } else { DBG_ERRORFILE( "ExcelToSc::ReadExtensionArray - missing matrix" ); } for( nR = 0 ; nR < nRows; nR++ ) { for( nC = 0 ; nC < nCols; nC++ ) { aIn >> nByte; switch( nByte ) { case EXC_CACHEDVAL_EMPTY: aIn.Ignore( 8 ); if( NULL != pMatrix ) { pMatrix->PutEmpty( nC, nR ); } break; case EXC_CACHEDVAL_DOUBLE: aIn >> fDouble; if( NULL != pMatrix ) { pMatrix->PutDouble( fDouble, nC, nR ); } break; case EXC_CACHEDVAL_STRING: if( GetBiff() == EXC_BIFF8 ) { aIn >> nUINT16; aString = aIn.ReadUniString( nUINT16 ); } else { aIn >> nByte; aString = aIn.ReadRawByteString( nByte ); } if( NULL != pMatrix ) { pMatrix->PutString( aString, nC, nR ); } break; case EXC_CACHEDVAL_BOOL: aIn >> nByte; aIn.Ignore( 7 ); if( NULL != pMatrix ) { pMatrix->PutBoolean( nByte != 0, nC, nR ); } break; case EXC_CACHEDVAL_ERROR: aIn >> nByte; aIn.Ignore( 7 ); if( NULL != pMatrix ) { pMatrix->PutError( XclTools::GetScErrorCode( nByte ), nC, nR ); } break; } } } } void ExcelToSc::ReadExtensionNlr( XclImpStream& aIn ) { // printf( "natural lang fmla;\n" ); sal_uInt32 nFlags; aIn >> nFlags; sal_uInt32 nCount = nFlags & EXC_TOK_NLR_ADDMASK; aIn.Ignore( nCount * 4 ); // Drop the cell positions } void ExcelToSc::ReadExtensionMemArea( XclImpStream& aIn ) { // printf( "mem area;\n" ); sal_uInt16 nCount; aIn >> nCount; aIn.Ignore( nCount * ((GetBiff() == EXC_BIFF8) ? 8 : 6) ); // drop the ranges } void ExcelToSc::ReadExtensions( const ExtensionTypeVec& rExtensions, XclImpStream& aIn ) { unsigned int nArray = 0; for( unsigned int i = 0 ; i < rExtensions.size() ; i++ ) { ExtensionType eType = rExtensions[i]; switch( eType ) { case EXTENSION_ARRAY: ReadExtensionArray( nArray++, aIn ); break; case EXTENSION_NLR: ReadExtensionNlr( aIn ); break; case EXTENSION_MEMAREA: ReadExtensionMemArea( aIn ); break; } } }