/* -*- 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 * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" #include "lotimpop.hxx" #include #include "attrib.hxx" #include "document.hxx" #include "rangenam.hxx" #include "cell.hxx" #include "patattr.hxx" #include "docpool.hxx" #include "compiler.hxx" #include "global.hxx" #include "root.hxx" #include "lotfntbf.hxx" #include "lotform.hxx" #include "tool.h" #include "namebuff.hxx" #include "lotrange.hxx" #include "lotattr.hxx" static osl::Mutex aLotImpSemaphore; ImportLotus::ImportLotus( SvStream& aStream, ScDocument* pDoc, CharSet eQ ) : ImportTyp( pDoc, eQ ), pIn( &aStream ), aConv( *pIn, eQ, false ) { // good point to start locking of import lotus aLotImpSemaphore.acquire(); pLotusRoot = new LOTUS_ROOT; pLotusRoot->pDoc = pDoc; pLotusRoot->pRangeNames = new LotusRangeList; pLotusRoot->pScRangeName = pDoc->GetRangeName(); pLotusRoot->eCharsetQ = eQ; pLotusRoot->eFirstType = Lotus_X; pLotusRoot->eActType = Lotus_X; pLotusRoot->pRngNmBffWK3 = new RangeNameBufferWK3; pFontBuff = pLotusRoot->pFontBuff = new LotusFontBuffer; pLotusRoot->pAttrTable = new LotAttrTable; } ImportLotus::~ImportLotus() { delete pLotusRoot->pRangeNames; delete pLotusRoot->pRngNmBffWK3; delete pFontBuff; delete pLotusRoot->pAttrTable; delete pLotusRoot; #ifdef DBG_UTIL pLotusRoot = NULL; #endif // no need 4 pLotusRoot anymore aLotImpSemaphore.release(); } void ImportLotus::Bof( void ) { sal_uInt16 nFileCode, nFileSub, nSaveCnt; sal_uInt8 nMajorId, nMinorId, nFlags; Read( nFileCode ); Read( nFileSub ); Read( pLotusRoot->aActRange ); Read( nSaveCnt ); Read( nMajorId ); Read( nMinorId ); Skip( 1 ); Read( nFlags ); if( nFileSub == 0x0004 ) { if( nFileCode == 0x1000 ) {// <= WK3 pLotusRoot->eFirstType = pLotusRoot->eActType = Lotus_WK3; } else if( nFileCode == 0x1002 ) {// WK4 pLotusRoot->eFirstType = pLotusRoot->eActType = Lotus_WK4; } } } sal_Bool ImportLotus::BofFm3( void ) { sal_uInt16 nFileCode, nFileSub; Read( nFileCode ); Read( nFileSub ); return ( nFileCode == 0x8007 && ( nFileSub == 0x0000 || nFileSub == 0x00001 ) ); } void ImportLotus::Columnwidth( sal_uInt16 nRecLen ) { DBG_ASSERT( nRecLen >= 4, "*ImportLotus::Columnwidth(): Record zu kurz!" ); sal_uInt8 nLTab, nWindow2; sal_uInt16 nCnt = ( nRecLen - 4 ) / 2; Read( nLTab ); Read( nWindow2 ); if( !pD->HasTable( static_cast (nLTab) ) ) pD->MakeTable( static_cast (nLTab) ); if( !nWindow2 ) { Skip( 2 ); sal_uInt8 nCol, nSpaces; while( nCnt ) { Read( nCol ); Read( nSpaces ); // ACHTUNG: Korrekturfaktor nach 'Augenmass' ermittelt! pD->SetColWidth( static_cast (nCol), static_cast (nLTab), ( sal_uInt16 ) ( TWIPS_PER_CHAR * 1.28 * nSpaces ) ); nCnt--; } } } void ImportLotus::Hiddencolumn( sal_uInt16 nRecLen ) { DBG_ASSERT( nRecLen >= 4, "*ImportLotus::Hiddencolumn(): Record zu kurz!" ); sal_uInt8 nLTab, nWindow2; sal_uInt16 nCnt = ( nRecLen - 4 ) / 2; Read( nLTab ); Read( nWindow2 ); if( !nWindow2 ) { Skip( 2 ); sal_uInt8 nCol; while( nCnt ) { Read( nCol ); pD->SetColHidden(static_cast(nCol), static_cast(nCol), static_cast(nLTab), true); nCnt--; } } } void ImportLotus::Userrange( void ) { sal_uInt16 nRangeType; ScRange aScRange; sal_Char* pBuffer = new sal_Char[ 32 ]; Read( nRangeType ); pIn->Read( pBuffer, 16 ); pBuffer[ 16 ] = ( sal_Char ) 0x00; // zur Sicherheit... String aName( pBuffer, eQuellChar ); Read( aScRange ); pLotusRoot->pRngNmBffWK3->Add( aName, aScRange ); delete[] pBuffer; } void ImportLotus::Errcell( void ) { ScAddress aA; Read( aA ); pD->PutCell( aA.Col(), aA.Row(), aA.Tab(), new ScStringCell( CREATE_STRING( "#ERR!" ) ), (sal_Bool)sal_True ); } void ImportLotus::Nacell( void ) { ScAddress aA; Read( aA ); pD->PutCell( aA.Col(), aA.Row(), aA.Tab(), new ScStringCell( CREATE_STRING( "#NA!" ) ), (sal_Bool)sal_True ); } void ImportLotus::Labelcell( void ) { ScAddress aA; String aLabel; sal_Char cAlign; Read( aA ); Read( cAlign ); Read( aLabel ); // aLabel.Convert( pLotusRoot->eCharsetQ ); pD->PutCell( aA.Col(), aA.Row(), aA.Tab(), new ScStringCell( aLabel ), (sal_Bool)sal_True ); } void ImportLotus::Numbercell( void ) { ScAddress aAddr; double fVal; Read( aAddr ); Read( fVal ); pD->PutCell( aAddr.Col(), aAddr.Row(), aAddr.Tab(), new ScValueCell( fVal ), (sal_Bool)sal_True ); } void ImportLotus::Smallnumcell( void ) { ScAddress aAddr; sal_Int16 nVal; Read( aAddr ); Read( nVal ); pD->PutCell( aAddr.Col(), aAddr.Row(), aAddr.Tab(), new ScValueCell( SnumToDouble( nVal ) ), ( sal_Bool ) sal_True ); } ScFormulaCell *ImportLotus::Formulacell( sal_uInt16 n ) { DBG_ASSERT( pIn, "-ImportLotus::Formulacell(): Null-Stream -> Rums!" ); ScAddress aAddr; Read( aAddr ); Skip( 10 ); n -= 14; const ScTokenArray* pErg; sal_Int32 nRest = n; aConv.Reset( aAddr ); aConv.SetWK3(); aConv.Convert( pErg, nRest ); ScFormulaCell* pZelle = new ScFormulaCell( pD, aAddr, pErg ); pZelle->AddRecalcMode( RECALCMODE_ONLOAD_ONCE ); pD->PutCell( aAddr.Col(), aAddr.Row(), aAddr.Tab(), pZelle, (sal_Bool)sal_True ); return NULL; } void ImportLotus::Read( String &r ) { ScfTools::AppendCString( *pIn, r, eQuellChar ); } void ImportLotus::RowPresentation( sal_uInt16 nRecLen ) { DBG_ASSERT( nRecLen > 4, "*ImportLotus::RowPresentation(): Record zu kurz!" ); sal_uInt8 nLTab, nFlags; sal_uInt16 nRow, nHeight; sal_uInt16 nCnt = ( nRecLen - 4 ) / 8; Read( nLTab ); Skip( 1 ); while( nCnt ) { Read( nRow ); Read( nHeight ); Skip( 2 ); Read( nFlags ); Skip( 1 ); if( nFlags & 0x02 ) // Fixed / Strech to fit fonts { // fixed // Height in Lotus in 1/32 Points nHeight *= 20; // -> 32 * TWIPS nHeight /= 32; // -> TWIPS pD->SetRowFlags( static_cast (nRow), static_cast (nLTab), pD->GetRowFlags( static_cast (nRow), static_cast (nLTab) ) | CR_MANUALSIZE ); pD->SetRowHeight( static_cast (nRow), static_cast (nLTab), nHeight ); } nCnt--; } } void ImportLotus::NamedSheet( void ) { sal_uInt16 nLTab; String aName; Read( nLTab ); Read( aName ); if( pD->HasTable( static_cast (nLTab) ) ) pD->RenameTab( static_cast (nLTab), aName ); else pD->InsertTab( static_cast (nLTab), aName ); } void ImportLotus::Font_Face( void ) { sal_uInt8 nNum; String aName; Read( nNum ); // ACHTUNG: QUICK-HACK gegen unerklaerliche Loops if( nNum > 7 ) return; // ACHTUNG Read( aName ); pFontBuff->SetName( nNum, aName ); } void ImportLotus::Font_Type( void ) { static const sal_uInt16 nAnz = 8; sal_uInt16 nCnt; sal_uInt16 nType; for( nCnt = 0 ; nCnt < nAnz ; nCnt++ ) { Read( nType ); pFontBuff->SetType( nCnt, nType ); } } void ImportLotus::Font_Ysize( void ) { static const sal_uInt16 nAnz = 8; sal_uInt16 nCnt; sal_uInt16 nSize; for( nCnt = 0 ; nCnt < nAnz ; nCnt++ ) { Read( nSize ); pFontBuff->SetHeight( nCnt, nSize ); } } void ImportLotus::_Row( const sal_uInt16 nRecLen ) { DBG_ASSERT( nExtTab >= 0, "*ImportLotus::_Row(): Kann hier nicht sein!" ); sal_uInt16 nRow; sal_uInt16 nHeight; sal_uInt16 nCntDwn = ( nRecLen - 4 ) / 5; SCCOL nColCnt = 0; sal_uInt8 nRepeats; LotAttrWK3 aAttr; sal_Bool bCenter = false; SCCOL nCenterStart = 0, nCenterEnd = 0; Read( nRow ); Read( nHeight ); nHeight &= 0x0FFF; nHeight *= 22; if( nHeight ) pD->SetRowHeight( static_cast (nRow), static_cast (nExtTab), nHeight ); while( nCntDwn ) { Read( aAttr ); Read( nRepeats ); if( aAttr.HasStyles() ) pLotusRoot->pAttrTable->SetAttr( nColCnt, static_cast ( nColCnt + nRepeats ), static_cast (nRow), aAttr ); // hier und NICHT in class LotAttrTable, weil nur Attributiert wird, // wenn die anderen Attribute gesetzt sind // -> bei Center-Attribute wird generell zentriert gesetzt if( aAttr.IsCentered() ) { if( bCenter ) { if( pD->HasData( nColCnt, static_cast (nRow), static_cast (nExtTab) ) ) {// neue Center nach vorheriger Center pD->DoMerge( static_cast (nExtTab), nCenterStart, static_cast (nRow), nCenterEnd, static_cast (nRow) ); nCenterStart = nColCnt; } } else {// ganz neue Center bCenter = sal_True; nCenterStart = nColCnt; } nCenterEnd = nColCnt + static_cast(nRepeats); } else { if( bCenter ) {// evtl. alte Center bemachen pD->DoMerge( static_cast (nExtTab), nCenterStart, static_cast (nRow), nCenterEnd, static_cast (nRow) ); bCenter = false; } } nColCnt = nColCnt + static_cast(nRepeats); nColCnt++; nCntDwn--; } if( bCenter ) // evtl. alte Center bemachen pD->DoMerge( static_cast (nExtTab), nCenterStart, static_cast (nRow), nCenterEnd, static_cast (nRow) ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */