diff options
Diffstat (limited to 'sc/source/filter/lotus/op.cxx')
-rw-r--r-- | sc/source/filter/lotus/op.cxx | 684 |
1 files changed, 684 insertions, 0 deletions
diff --git a/sc/source/filter/lotus/op.cxx b/sc/source/filter/lotus/op.cxx new file mode 100644 index 000000000000..4ab0c8bb3b14 --- /dev/null +++ b/sc/source/filter/lotus/op.cxx @@ -0,0 +1,684 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +//------------------------------------------------------------------------ + +#include <tools/solar.h> +#include <rtl/math.hxx> + +#include <stdio.h> +#include <string.h> +#include <math.h> +#include <ctype.h> +#if defined( ICC ) +#include <stdlib.h> +#endif + +#include "scitems.hxx" +#include "patattr.hxx" +#include "docpool.hxx" +#include <svx/algitem.hxx> +#include <editeng/postitem.hxx> +#include <editeng/udlnitem.hxx> +#include <editeng/wghtitem.hxx> + +#include "cell.hxx" +#include "rangenam.hxx" +#include "document.hxx" +#include "postit.hxx" + +#include "op.h" +#include "optab.h" +#include "tool.h" +//#include "math.h" +#include "decl.h" +#include "lotform.hxx" +#include "lotrange.hxx" + +#include "root.hxx" + +#include "ftools.hxx" + +#include <vector> +#include <map> + +#include <stdio.h> +#include <string.h> +#include <math.h> +#include <ctype.h> +#if defined( MAC ) || defined( ICC ) +#include <stdlib.h> +#endif + +extern sal_Char* pAnsi; // -> memory.cxx, Puffer zum Umwandeln von OEM->ANSI +extern sal_Char* pErgebnis; // -> memory.cxx, Ergebnispuffer +extern WKTYP eTyp; // -> filter.cxx, aktueller Dateityp +extern BOOL bEOF; // -> filter.cxx, zeigt Dateiende an +extern sal_Char* pPuffer0; // -> memory.cxx +extern sal_Char* pPuffer1; +extern BYTE nDefaultFormat; // -> tool.cxx, Default-Zellenformat +extern ScDocument* pDoc; // -> filter.cxx, Aufhaenger zum Dokumentzugriff +extern BYTE* pFormelBuffer; // -> memory.cxx, fuer +extern CharSet eCharVon; // -> filter.cxx, character set specified + +static UINT16 nDefWidth = ( UINT16 ) ( TWIPS_PER_CHAR * 10 ); + +extern std::map<UINT16, ScPatternAttr> aLotusPatternPool; + +void NI( SvStream& r, UINT16 n ) +{ + r.SeekRel( n ); +} + + +void OP_BOF( SvStream& r, UINT16 /*n*/ ) +{ + r.SeekRel( 2 ); // Versionsnummer ueberlesen +} + + +void OP_EOF( SvStream& /*r*/, UINT16 /*n*/ ) +{ + bEOF = TRUE; +} + + +void OP_Integer( SvStream& r, UINT16 /*n*/ ) +{ + BYTE nFormat; + UINT16 nCol, nRow; + SCTAB nTab = 0; + INT16 nValue; + + r >> nFormat >> nCol >> nRow >> nValue; + + ScValueCell* pZelle = new ScValueCell( ( double ) nValue ); + pDoc->PutCell( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, pZelle, ( BOOL ) TRUE ); + + // 0 Stellen nach'm Komma! + SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, nFormat, 0 ); +} + + +void OP_Number( SvStream& r, UINT16 /*n*/ ) +{ + BYTE nFormat; + UINT16 nCol, nRow; + SCTAB nTab = 0; + double fValue; + + r >> nFormat >> nCol >> nRow >> fValue; + + fValue = ::rtl::math::round( fValue, 15 ); + ScValueCell* pZelle = new ScValueCell( fValue ); + pDoc->PutCell( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, pZelle, ( BOOL ) TRUE ); + + SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, nFormat, nDezFloat ); +} + + +void OP_Label( SvStream& r, UINT16 n ) +{ + BYTE nFormat; + UINT16 nCol, nRow; + SCTAB nTab = 0; + + r >> nFormat >> nCol >> nRow; + n -= 5; + + sal_Char* pText = new sal_Char[n + 1]; + r.Read( pText, n ); + pText[n] = 0; + + nFormat &= 0x80; // Bit 7 belassen + nFormat |= 0x75; // protected egal, special-text gesetzt + + PutFormString( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, pText ); + + SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, nFormat, nDezStd ); + + delete [] pText; +} + + +//UNUSED2009-05 void OP_Text( SvStream& r, UINT16 n ) // WK3 +//UNUSED2009-05 { +//UNUSED2009-05 UINT16 nRow; +//UNUSED2009-05 BYTE nCol, nTab; +//UNUSED2009-05 sal_Char pText[ 256 ]; +//UNUSED2009-05 +//UNUSED2009-05 r >> nRow >> nTab >> nCol; +//UNUSED2009-05 n -= 4; +//UNUSED2009-05 +//UNUSED2009-05 r.Read( pText, n ); +//UNUSED2009-05 pText[ n ] = 0; // zur Sicherheit Nullterminator anhaengen +//UNUSED2009-05 +//UNUSED2009-05 PutFormString( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), static_cast<SCTAB> (nTab), pText ); +//UNUSED2009-05 } + + +void OP_Formula( SvStream& r, UINT16 /*n*/ ) +{ + BYTE nFormat; + UINT16 nCol, nRow, nFormulaSize; + SCTAB nTab = 0; + + r >> nFormat >> nCol >> nRow; + r.SeekRel( 8 ); // Ergebnis ueberspringen + r >> nFormulaSize; + + const ScTokenArray* pErg; + INT32 nBytesLeft = nFormulaSize; + ScAddress aAddress( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab ); + + LotusToSc aConv( r, pLotusRoot->eCharsetQ, FALSE ); + aConv.Reset( aAddress ); + aConv.Convert( pErg, nBytesLeft ); + + ScFormulaCell* pZelle = new ScFormulaCell( pLotusRoot->pDoc, aAddress, pErg ); + + pZelle->AddRecalcMode( RECALCMODE_ONLOAD_ONCE ); + + pDoc->PutCell( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, pZelle, ( BOOL ) TRUE ); + + // nFormat = Standard -> Nachkommastellen wie Float + SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, nFormat, nDezFloat ); +} + + +void OP_ColumnWidth( SvStream& r, UINT16 /*n*/ ) +{ + UINT16 nCol, nBreite; + BYTE nWidthSpaces; + SCTAB nTab = 0; + + r >> nCol >> nWidthSpaces; + + if( nWidthSpaces ) + // Annahme: 10cpi-Zeichensatz + nBreite = ( UINT16 ) ( TWIPS_PER_CHAR * nWidthSpaces ); + else + { + pDoc->SetColHidden(static_cast<SCCOL>(nCol), static_cast<SCCOL>(nCol), 0, true); + nBreite = nDefWidth; + } + + pDoc->SetColWidth( static_cast<SCCOL> (nCol), nTab, nBreite ); +} + + +void OP_NamedRange( SvStream& r, UINT16 /*n*/ ) + { + // POST: waren Koordinaten ungueltig, wird nicht gespeichert + UINT16 nColSt, nRowSt, nColEnd, nRowEnd; + sal_Char cPuffer[ 32 ]; + + r.Read( cPuffer, 16 ); + + r >> nColSt >> nRowSt >> nColEnd >> nRowEnd; + + LotusRange* pRange; + + if( nColSt == nColEnd && nRowSt == nRowEnd ) + pRange = new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt) ); + else + pRange = new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt), static_cast<SCCOL> (nColEnd), static_cast<SCROW> (nRowEnd) ); + + if( isdigit( *cPuffer ) ) + { // erstes Zeichen im Namen eine Zahl -> 'A' vor Namen setzen + *pAnsi = 'A'; + strcpy( pAnsi + 1, cPuffer ); // #100211# - checked + } + else + strcpy( pAnsi, cPuffer ); // #100211# - checked + + String aTmp( pAnsi, pLotusRoot->eCharsetQ ); + + ScfTools::ConvertToScDefinedName( aTmp ); + + pLotusRoot->pRangeNames->Append( pRange, aTmp ); +} + + +void OP_SymphNamedRange( SvStream& r, UINT16 /*n*/ ) +{ + // POST: waren Koordinaten ungueltig, wird nicht gespeichert + UINT16 nColSt, nRowSt, nColEnd, nRowEnd; + BYTE nType; + sal_Char* pName; + sal_Char cPuffer[ 32 ]; + + r.Read( cPuffer, 16 ); + cPuffer[ 16 ] = 0; + pName = cPuffer; + + r >> nColSt >> nRowSt >> nColEnd >> nRowEnd >> nType; + + LotusRange* pRange; + + if( nType ) + pRange = new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt) ); + else + pRange = new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt), static_cast<SCCOL> (nColEnd), static_cast<SCROW> (nRowEnd) ); + + if( isdigit( *cPuffer ) ) + { // erstes Zeichen im Namen eine Zahl -> 'A' vor Namen setzen + *pAnsi = 'A'; + strcpy( pAnsi + 1, cPuffer ); // #100211# - checked + } + else + strcpy( pAnsi, cPuffer ); // #100211# - checked + + String aTmp( pAnsi, pLotusRoot->eCharsetQ ); + ScfTools::ConvertToScDefinedName( aTmp ); + + pLotusRoot->pRangeNames->Append( pRange, aTmp ); +} + + +void OP_Footer( SvStream& r, UINT16 n ) +{ + r.SeekRel( n ); +} + + +void OP_Header( SvStream& r, UINT16 n ) +{ + r.SeekRel( n ); +} + + +void OP_Margins( SvStream& r, UINT16 n ) +{ + r.SeekRel( n ); +} + + +void OP_HiddenCols( SvStream& r, UINT16 /*n*/ ) +{ + UINT16 nByte, nBit; + SCCOL nCount; + BYTE nAkt; + nCount = 0; + + for( nByte = 0 ; nByte < 32 ; nByte++ ) // 32 Bytes mit ... + { + r >> nAkt; + for( nBit = 0 ; nBit < 8 ; nBit++ ) // ...jeweils 8 Bits = 256 Bits + { + if( nAkt & 0x01 ) // unterstes Bit gesetzt? + // -> Hidden Col + pDoc->SetColHidden(nCount, nCount, 0, true); + + nCount++; + nAkt = nAkt / 2; // der Naechste bitte... + } + } +} + + +void OP_Window1( SvStream& r, UINT16 n ) +{ + r.SeekRel( 4 ); // Cursor Pos ueberspringen + + r >> nDefaultFormat; + + r.SeekRel( 1 ); // 'unused' ueberspringen + + r >> nDefWidth; + + r.SeekRel( n - 8 ); // und den Rest ueberspringen + + nDefWidth = ( UINT16 ) ( TWIPS_PER_CHAR * nDefWidth ); + + // statt Defaulteinstellung in SC alle Cols zu Fuss setzen + for( SCCOL nCol = 0 ; nCol <= MAXCOL ; nCol++ ) + pDoc->SetColWidth( nCol, 0, nDefWidth ); +} + + +void OP_Blank( SvStream& r, UINT16 /*n*/ ) +{ + UINT16 nCol, nRow; + BYTE nFormat; + r >> nFormat >> nCol >> nRow; + + SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), 0, nFormat, nDezFloat ); +} + +void OP_BOF123( SvStream& r, UINT16 /*n*/ ) +{ + r.SeekRel( 26 ); +} + + +void OP_EOF123( SvStream& /*r*/, UINT16 /*n*/ ) +{ + bEOF = TRUE; +} + +void OP_Label123( SvStream& r, UINT16 n ) +{ + BYTE nTab, nCol; + UINT16 nRow; + r >> nRow >> nTab >> nCol; + n -= 4; + + sal_Char* pText = new sal_Char[n + 1]; + r.Read( pText, n ); + pText[ n ] = 0; + + PutFormString( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), pText ); + + delete []pText; +} + +void OP_Number123( SvStream& r, UINT16 /*n*/ ) +{ + BYTE nCol,nTab; + UINT16 nRow; + UINT32 nValue; + + r >> nRow >> nTab >> nCol >> nValue; + double fValue = Snum32ToDouble( nValue ); + + ScValueCell *pCell = new ScValueCell( fValue ); + pDoc->PutCell( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), pCell, (BOOL) TRUE ); +} + +void OP_Formula123( SvStream& r, UINT16 n ) +{ + BYTE nCol,nTab; + UINT16 nRow; + + r >> nRow >> nTab >> nCol; + r.SeekRel( 8 ); // Result- jump over + + const ScTokenArray* pErg; + INT32 nBytesLeft = n - 12; + ScAddress aAddress( nCol, nRow, nTab ); + + LotusToSc aConv( r, pLotusRoot->eCharsetQ, TRUE ); + aConv.Reset( aAddress ); + aConv.Convert( pErg, nBytesLeft ); + + ScFormulaCell* pCell = new ScFormulaCell( pLotusRoot->pDoc, aAddress, pErg ); + + pCell->AddRecalcMode( RECALCMODE_ONLOAD_ONCE ); + + pDoc->PutCell( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), pCell, (BOOL) TRUE ); +} + +void OP_IEEENumber123( SvStream& r, UINT16 /*n*/ ) +{ + BYTE nCol,nTab; + UINT16 nRow; + double dValue; + + r >> nRow >> nTab >> nCol >> dValue; + + ScValueCell *pCell = new ScValueCell(dValue); + pDoc->PutCell( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), pCell, (BOOL) TRUE ); +} + +void OP_Note123( SvStream& r, UINT16 n) +{ + BYTE nTab, nCol; + UINT16 nRow; + r >> nRow >> nTab >> nCol; + n -= 4; + + sal_Char* pText = new sal_Char[n + 1]; + r.Read( pText, n ); + pText[ n ] = 0; + + String aNoteText(pText,pLotusRoot->eCharsetQ); + delete [] pText; + + ScAddress aPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab) ); + ScNoteUtil::CreateNoteFromString( *pDoc, aPos, aNoteText, false, false ); +} + +void OP_HorAlign123( BYTE nAlignPattern, SfxItemSet& rPatternItemSet ) +{ +// pre: Pattern is stored in the last 3 bites of the 21st byte +// post: Appropriate Horizontal Alignement is set in rPattern according to the bit pattern. +// +// LEFT:001, RIGHT:010, CENTER:011, JUSTIFY:110, +// LEFT-Text/RIGHT-NUMBER:100, DEFAULT:000 + + nAlignPattern = ( nAlignPattern & 0x07); + + switch (nAlignPattern) + { + case 1: + rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_LEFT, ATTR_HOR_JUSTIFY ) ); + break; + case 2: + rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_RIGHT, ATTR_HOR_JUSTIFY ) ); + break; + case 3: + rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY) ); + break; + case 4: + rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD, ATTR_HOR_JUSTIFY ) ); + break; + case 6: + rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_BLOCK, ATTR_HOR_JUSTIFY ) ); + break; + default: + rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD, ATTR_HOR_JUSTIFY ) ); + break; + } +} + +void OP_VerAlign123( BYTE nAlignPattern,SfxItemSet& rPatternItemSet ) +{ +// pre: Pattern is stored in the last 3 bites of the 22nd byte +// post: Appropriate Verticle Alignement is set in rPattern according to the bit pattern. +// +// TOP:001, MIDDLE:010, DOWN:100, DEFAULT:000 + + nAlignPattern = ( nAlignPattern & 0x07); + + switch (nAlignPattern) + { + case 0: + rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_STANDARD, ATTR_VER_JUSTIFY) ); + break; + case 1: + rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_TOP, ATTR_VER_JUSTIFY) ); + break; + case 2: + rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_CENTER, ATTR_VER_JUSTIFY) ); + break; + case 4: + rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_BOTTOM, ATTR_VER_JUSTIFY) ); + break; + default: + rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_STANDARD, ATTR_VER_JUSTIFY) ); + break; + } +} + +void OP_CreatePattern123( SvStream& r, UINT16 n) +{ + UINT16 nCode,nPatternId; + + ScPatternAttr aPattern(pDoc->GetPool()); + SfxItemSet& rItemSet = aPattern.GetItemSet(); + + r >> nCode; + n = n - 2; + + if ( nCode == 0x0fd2 ) + { + r >> nPatternId; + + BYTE Hor_Align, Ver_Align, temp; + BOOL bIsBold,bIsUnderLine,bIsItalics; + + r.SeekRel(12); + + // Read 17th Byte + r >> temp; + + bIsBold = (temp & 0x01); + bIsItalics = (temp & 0x02); + bIsUnderLine = (temp & 0x04); + + if ( bIsBold ) + rItemSet.Put( SvxWeightItem(WEIGHT_BOLD,ATTR_FONT_WEIGHT) ); + if ( bIsItalics ) + rItemSet.Put( SvxPostureItem(ITALIC_NORMAL, ATTR_FONT_POSTURE ) ); + if ( bIsUnderLine ) + rItemSet.Put( SvxUnderlineItem( UNDERLINE_SINGLE, ATTR_FONT_UNDERLINE ) ); + + r.SeekRel(3); + + // Read 21st Byte + r >> Hor_Align; + OP_HorAlign123( Hor_Align, rItemSet ); + + r >> Ver_Align; + OP_VerAlign123( Ver_Align, rItemSet ); + + aLotusPatternPool.insert( std::map<UINT16, ScPatternAttr>::value_type( nPatternId, aPattern ) ); + n = n - 20; + } + r.SeekRel(n); +} + +void OP_SheetName123( SvStream& rStream, USHORT nLength ) +{ + if (nLength <= 4) + { + rStream.SeekRel(nLength); + return; + } + + // B0 36 [sheet number (2 bytes?)] [sheet name (null terminated char array)] + + sal_uInt16 nDummy; + rStream >> nDummy; // ignore the first 2 bytes (B0 36). + rStream >> nDummy; + SCTAB nSheetNum = static_cast<SCTAB>(nDummy); + pDoc->MakeTable(nSheetNum); + + ::std::vector<sal_Char> sSheetName; + sSheetName.reserve(nLength-4); + for (USHORT i = 4; i < nLength; ++i) + { + sal_Char c; + rStream >> c; + sSheetName.push_back(c); + } + + if (!sSheetName.empty()) + { + String aName(&sSheetName[0], eCharVon); + pDoc->RenameTab(nSheetNum, aName); + } +} + +void OP_ApplyPatternArea123( SvStream& rStream ) +{ + UINT16 nOpcode, nLength; + UINT16 nCol = 0, nColCount = 0, nRow = 0, nRowCount = 0, nTab = 0, nData, nTabCount = 0, nLevel = 0; + + do + { + rStream >> nOpcode >> nLength; + switch ( nOpcode ) + { + case ROW_FORMAT_MARKER: + nLevel++; + break; + case COL_FORMAT_MARKER: + nLevel--; + if( nLevel == 1 ) + { + nTab = nTab + nTabCount; + nCol = 0; nColCount = 0; + nRow = 0; nRowCount = 0; + } + break; + case LOTUS_FORMAT_INDEX: + if( nLength >= 2 ) + { + rStream >> nData; + rStream.SeekRel( nLength - 2 ); + if( nLevel == 1 ) + nTabCount = nData; + else if( nLevel == 2 ) + { + nCol = nCol + nColCount; + nColCount = nData; + if ( nCol > 0xff ) // 256 is the max col size supported by 123 + nCol = 0; + } + else if( nLevel == 3 ) + { + nRow = nRow + nRowCount; + nRowCount = nData; + if ( nRow > 0x1fff ) // 8192 is the max row size supported by 123 + nRow = 0; + } + } + else + rStream.SeekRel( nLength ); + break; + case LOTUS_FORMAT_INFO: + if( nLength >= 2 ) + { + rStream >> nData; + rStream.SeekRel( nLength - 2 ); + for( int i = 0; i < nTabCount; i++) + { + std::map<UINT16, ScPatternAttr>::iterator loc = aLotusPatternPool.find( nData ); + + // #126338# apparently, files with invalid index occur in the wild -> don't crash then + DBG_ASSERT( loc != aLotusPatternPool.end(), "invalid format index" ); + if ( loc != aLotusPatternPool.end() ) + pDoc->ApplyPatternAreaTab( nCol, nRow, nCol + nColCount - 1, nRow + nRowCount - 1, static_cast< SCTAB >( nTab + i ), loc->second ); + } + } + else + rStream.SeekRel( nLength ); + break; + default: + rStream.SeekRel( nLength ); + break; + } + } + while( nLevel && !rStream.IsEof() ); + + aLotusPatternPool.clear(); +} |