blob: ddc238dcdd936905262220ceee05d681e866ddd0 [file] [log] [blame]
/**************************************************************
*
* 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 "lotimpop.hxx"
#include <vos/mutex.hxx>
#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 vos:: OMutex aLotImpSemaphore;
LOTUS_ROOT::LOTUS_ROOT( ScDocument* pDocP, CharSet eQ )
:
pDoc( pDocP),
pRangeNames( new LotusRangeList),
pScRangeName( pDocP->GetRangeName()),
eCharsetQ( eQ),
eFirstType( Lotus_X),
eActType( Lotus_X),
pRngNmBffWK3( new RangeNameBufferWK3),
pFontBuff( new LotusFontBuffer)
{
pLotusRoot = this; // #122841# the singleton global var is already needed for LotAttrTable
pAttrTable = new LotAttrTable;
}
LOTUS_ROOT::~LOTUS_ROOT()
{
delete pRangeNames;
delete pRngNmBffWK3;
delete pFontBuff;
delete pAttrTable;
}
ImportLotus::ImportLotus( SvStream& aStream, ScDocument* pDoc, CharSet eQ ) :
ImportTyp( pDoc, eQ ),
pIn( &aStream ),
aConv( *pIn, eQ, sal_False )
{
// good point to start locking of import lotus
aLotImpSemaphore.acquire();
pLotusRoot = new LOTUS_ROOT( pDoc, eQ);
}
ImportLotus::~ImportLotus()
{
delete pLotusRoot;
pLotusRoot = NULL;
// 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) ? 0 : ( nRecLen - 4 ) / 2;
Read( nLTab );
Read( nWindow2 );
if( !pD->HasTable( static_cast<SCTAB> (nLTab) ) )
pD->MakeTable( static_cast<SCTAB> (nLTab) );
if( !nWindow2 )
{
Skip( 2 );
sal_uInt8 nCol, nSpaces;
while( nCnt )
{
Read( nCol );
Read( nSpaces );
// ACHTUNG: Korrekturfaktor nach 'Augenmass' ermittelt!
pD->SetColWidth( static_cast<SCCOL> (nCol), static_cast<SCTAB> (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) ? 0 : ( nRecLen - 4 ) / 2;
Read( nLTab );
Read( nWindow2 );
if( !nWindow2 )
{
Skip( 2 );
sal_uInt8 nCol;
while( nCnt )
{
Read( nCol );
pD->SetColHidden(static_cast<SCCOL>(nCol), static_cast<SCCOL>(nCol), static_cast<SCTAB>(nLTab), true);
nCnt--;
}
}
}
void ImportLotus::Userrange( void )
{
sal_uInt16 nRangeType;
ScRange aScRange;
Read( nRangeType );
sal_Char aBuffer[ 17 ];
pIn->Read( aBuffer, 16 );
aBuffer[ 16 ] = 0;
String aName( aBuffer, eQuellChar );
Read( aScRange );
pLotusRoot->pRngNmBffWK3->Add( aName, aScRange );
}
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 -= (n > 14) ? 14 : n;
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) ? 0 : ( 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<SCROW> (nRow), static_cast<SCTAB> (nLTab), pD->GetRowFlags( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab) ) | CR_MANUALSIZE );
pD->SetRowHeight( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab), nHeight );
}
nCnt--;
}
}
void ImportLotus::NamedSheet( void )
{
sal_uInt16 nLTab;
String aName;
Read( nLTab );
Read( aName );
if( pD->HasTable( static_cast<SCTAB> (nLTab) ) )
pD->RenameTab( static_cast<SCTAB> (nLTab), aName );
else
pD->InsertTab( static_cast<SCTAB> (nLTab), aName );
}
void ImportLotus::Font_Face( void )
{
sal_uInt8 nNum;
String aName;
Read( nNum );
if( nNum >= LotusFontBuffer::nSize )
return; // nonsense
Read( aName );
pLotusRoot->pFontBuff->SetName( nNum, aName );
}
void ImportLotus::Font_Type( void )
{
for( sal_uInt16 nCnt = 0 ; nCnt < LotusFontBuffer::nSize ; nCnt++ )
{
sal_uInt16 nType;
Read( nType );
pLotusRoot->pFontBuff->SetType( nCnt, nType );
}
}
void ImportLotus::Font_Ysize( void )
{
for( sal_uInt16 nCnt = 0 ; nCnt < LotusFontBuffer::nSize ; nCnt++ )
{
sal_uInt16 nSize;
Read( nSize );
pLotusRoot->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) ? 0 : ( nRecLen - 4 ) / 5;
SCCOL nColCnt = 0;
sal_uInt8 nRepeats;
LotAttrWK3 aAttr;
sal_Bool bCenter = sal_False;
SCCOL nCenterStart = 0, nCenterEnd = 0;
Read( nRow );
Read( nHeight );
nHeight &= 0x0FFF;
nHeight *= 22;
if( nHeight )
pD->SetRowHeight( static_cast<SCROW> (nRow), static_cast<SCTAB> (nExtTab), nHeight );
while( nCntDwn )
{
Read( aAttr );
Read( nRepeats );
if( aAttr.HasStyles() )
pLotusRoot->pAttrTable->SetAttr(
nColCnt, static_cast<SCCOL> ( nColCnt + nRepeats ), static_cast<SCROW> (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<SCROW> (nRow), static_cast<SCTAB> (nExtTab) ) )
{// neue Center nach vorheriger Center
pD->DoMerge( static_cast<SCTAB> (nExtTab), nCenterStart, static_cast<SCROW> (nRow), nCenterEnd, static_cast<SCROW> (nRow) );
nCenterStart = nColCnt;
}
}
else
{// ganz neue Center
bCenter = sal_True;
nCenterStart = nColCnt;
}
nCenterEnd = nColCnt + static_cast<SCCOL>(nRepeats);
}
else
{
if( bCenter )
{// evtl. alte Center bemachen
pD->DoMerge( static_cast<SCTAB> (nExtTab), nCenterStart, static_cast<SCROW> (nRow), nCenterEnd, static_cast<SCROW> (nRow) );
bCenter = sal_False;
}
}
nColCnt = nColCnt + static_cast<SCCOL>(nRepeats);
nColCnt++;
nCntDwn--;
}
if( bCenter )
// evtl. alte Center bemachen
pD->DoMerge( static_cast<SCTAB> (nExtTab), nCenterStart, static_cast<SCROW> (nRow), nCenterEnd, static_cast<SCROW> (nRow) );
}