1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
10 * $Revision: 1.18.126.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 //------------------------------------------------------------------------
36 #include <tools/solar.h>
37 #include <rtl/math.hxx>
47 #include "scitems.hxx"
48 #include "patattr.hxx"
49 #include "docpool.hxx"
50 #include <svx/algitem.hxx>
51 #include <svx/postitem.hxx>
52 #include <svx/udlnitem.hxx>
53 #include <svx/wghtitem.hxx>
56 #include "rangenam.hxx"
57 #include "document.hxx"
65 #include "lotform.hxx"
66 #include "lotrange.hxx"
79 #if defined( MAC ) || defined( ICC )
83 extern sal_Char
* pAnsi
; // -> memory.cxx, Puffer zum Umwandeln von OEM->ANSI
84 extern sal_Char
* pErgebnis
; // -> memory.cxx, Ergebnispuffer
85 extern WKTYP eTyp
; // -> filter.cxx, aktueller Dateityp
86 extern BOOL bEOF
; // -> filter.cxx, zeigt Dateiende an
87 extern sal_Char
* pPuffer0
; // -> memory.cxx
88 extern sal_Char
* pPuffer1
;
89 extern BYTE nDefaultFormat
; // -> tool.cxx, Default-Zellenformat
90 extern ScDocument
* pDoc
; // -> filter.cxx, Aufhaenger zum Dokumentzugriff
91 extern BYTE
* pFormelBuffer
; // -> memory.cxx, fuer
92 extern CharSet eCharVon
; // -> filter.cxx, character set specified
94 static UINT16 nDefWidth
= ( UINT16
) ( TWIPS_PER_CHAR
* 10 );
96 extern std::map
<UINT16
, ScPatternAttr
> aLotusPatternPool
;
98 void NI( SvStream
& r
, UINT16 n
)
104 void OP_BOF( SvStream
& r
, UINT16
/*n*/ )
106 r
.SeekRel( 2 ); // Versionsnummer ueberlesen
110 void OP_EOF( SvStream
& /*r*/, UINT16
/*n*/ )
116 void OP_Integer( SvStream
& r
, UINT16
/*n*/ )
123 r
>> nFormat
>> nCol
>> nRow
>> nValue
;
125 ScValueCell
* pZelle
= new ScValueCell( ( double ) nValue
);
126 pDoc
->PutCell( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), nTab
, pZelle
, ( BOOL
) TRUE
);
128 // 0 Stellen nach'm Komma!
129 SetFormat( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), nTab
, nFormat
, 0 );
133 void OP_Number( SvStream
& r
, UINT16
/*n*/ )
140 r
>> nFormat
>> nCol
>> nRow
>> fValue
;
142 fValue
= ::rtl::math::round( fValue
, 15 );
143 ScValueCell
* pZelle
= new ScValueCell( fValue
);
144 pDoc
->PutCell( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), nTab
, pZelle
, ( BOOL
) TRUE
);
146 SetFormat( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), nTab
, nFormat
, nDezFloat
);
150 void OP_Label( SvStream
& r
, UINT16 n
)
156 r
>> nFormat
>> nCol
>> nRow
;
159 sal_Char
* pText
= new sal_Char
[n
+ 1];
163 nFormat
&= 0x80; // Bit 7 belassen
164 nFormat
|= 0x75; // protected egal, special-text gesetzt
166 PutFormString( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), nTab
, pText
);
168 SetFormat( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), nTab
, nFormat
, nDezStd
);
174 //UNUSED2009-05 void OP_Text( SvStream& r, UINT16 n ) // WK3
176 //UNUSED2009-05 UINT16 nRow;
177 //UNUSED2009-05 BYTE nCol, nTab;
178 //UNUSED2009-05 sal_Char pText[ 256 ];
180 //UNUSED2009-05 r >> nRow >> nTab >> nCol;
181 //UNUSED2009-05 n -= 4;
183 //UNUSED2009-05 r.Read( pText, n );
184 //UNUSED2009-05 pText[ n ] = 0; // zur Sicherheit Nullterminator anhaengen
186 //UNUSED2009-05 PutFormString( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), static_cast<SCTAB> (nTab), pText );
190 void OP_Formula( SvStream
& r
, UINT16
/*n*/ )
193 UINT16 nCol
, nRow
, nFormulaSize
;
196 r
>> nFormat
>> nCol
>> nRow
;
197 r
.SeekRel( 8 ); // Ergebnis ueberspringen
200 const ScTokenArray
* pErg
;
201 INT32 nBytesLeft
= nFormulaSize
;
202 ScAddress
aAddress( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), nTab
);
204 LotusToSc
aConv( r
, pLotusRoot
->eCharsetQ
, FALSE
);
205 aConv
.Reset( aAddress
);
206 aConv
.Convert( pErg
, nBytesLeft
);
208 ScFormulaCell
* pZelle
= new ScFormulaCell( pLotusRoot
->pDoc
, aAddress
, pErg
);
210 pZelle
->AddRecalcMode( RECALCMODE_ONLOAD_ONCE
);
212 pDoc
->PutCell( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), nTab
, pZelle
, ( BOOL
) TRUE
);
214 // nFormat = Standard -> Nachkommastellen wie Float
215 SetFormat( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), nTab
, nFormat
, nDezFloat
);
219 void OP_ColumnWidth( SvStream
& r
, UINT16
/*n*/ )
221 UINT16 nCol
, nBreite
;
225 r
>> nCol
>> nWidthSpaces
;
228 // Annahme: 10cpi-Zeichensatz
229 nBreite
= ( UINT16
) ( TWIPS_PER_CHAR
* nWidthSpaces
);
232 pDoc
->SetColHidden(static_cast<SCCOL
>(nCol
), static_cast<SCCOL
>(nCol
), 0, true);
236 pDoc
->SetColWidth( static_cast<SCCOL
> (nCol
), nTab
, nBreite
);
240 void OP_NamedRange( SvStream
& r
, UINT16
/*n*/ )
242 // POST: waren Koordinaten ungueltig, wird nicht gespeichert
243 UINT16 nColSt
, nRowSt
, nColEnd
, nRowEnd
;
244 sal_Char cPuffer
[ 32 ];
246 r
.Read( cPuffer
, 16 );
248 r
>> nColSt
>> nRowSt
>> nColEnd
>> nRowEnd
;
252 if( nColSt
== nColEnd
&& nRowSt
== nRowEnd
)
253 pRange
= new LotusRange( static_cast<SCCOL
> (nColSt
), static_cast<SCROW
> (nRowSt
) );
255 pRange
= new LotusRange( static_cast<SCCOL
> (nColSt
), static_cast<SCROW
> (nRowSt
), static_cast<SCCOL
> (nColEnd
), static_cast<SCROW
> (nRowEnd
) );
257 if( isdigit( *cPuffer
) )
258 { // erstes Zeichen im Namen eine Zahl -> 'A' vor Namen setzen
260 strcpy( pAnsi
+ 1, cPuffer
); // #100211# - checked
263 strcpy( pAnsi
, cPuffer
); // #100211# - checked
265 String
aTmp( pAnsi
, pLotusRoot
->eCharsetQ
);
267 ScfTools::ConvertToScDefinedName( aTmp
);
269 pLotusRoot
->pRangeNames
->Append( pRange
, aTmp
);
273 void OP_SymphNamedRange( SvStream
& r
, UINT16
/*n*/ )
275 // POST: waren Koordinaten ungueltig, wird nicht gespeichert
276 UINT16 nColSt
, nRowSt
, nColEnd
, nRowEnd
;
279 sal_Char cPuffer
[ 32 ];
281 r
.Read( cPuffer
, 16 );
285 r
>> nColSt
>> nRowSt
>> nColEnd
>> nRowEnd
>> nType
;
290 pRange
= new LotusRange( static_cast<SCCOL
> (nColSt
), static_cast<SCROW
> (nRowSt
) );
292 pRange
= new LotusRange( static_cast<SCCOL
> (nColSt
), static_cast<SCROW
> (nRowSt
), static_cast<SCCOL
> (nColEnd
), static_cast<SCROW
> (nRowEnd
) );
294 if( isdigit( *cPuffer
) )
295 { // erstes Zeichen im Namen eine Zahl -> 'A' vor Namen setzen
297 strcpy( pAnsi
+ 1, cPuffer
); // #100211# - checked
300 strcpy( pAnsi
, cPuffer
); // #100211# - checked
302 String
aTmp( pAnsi
, pLotusRoot
->eCharsetQ
);
303 ScfTools::ConvertToScDefinedName( aTmp
);
305 pLotusRoot
->pRangeNames
->Append( pRange
, aTmp
);
309 void OP_Footer( SvStream
& r
, UINT16 n
)
315 void OP_Header( SvStream
& r
, UINT16 n
)
321 void OP_Margins( SvStream
& r
, UINT16 n
)
327 void OP_HiddenCols( SvStream
& r
, UINT16
/*n*/ )
334 for( nByte
= 0 ; nByte
< 32 ; nByte
++ ) // 32 Bytes mit ...
337 for( nBit
= 0 ; nBit
< 8 ; nBit
++ ) // ...jeweils 8 Bits = 256 Bits
339 if( nAkt
& 0x01 ) // unterstes Bit gesetzt?
341 pDoc
->SetColHidden(nCount
, nCount
, 0, true);
344 nAkt
= nAkt
/ 2; // der Naechste bitte...
350 void OP_Window1( SvStream
& r
, UINT16 n
)
352 r
.SeekRel( 4 ); // Cursor Pos ueberspringen
356 r
.SeekRel( 1 ); // 'unused' ueberspringen
360 r
.SeekRel( n
- 8 ); // und den Rest ueberspringen
362 nDefWidth
= ( UINT16
) ( TWIPS_PER_CHAR
* nDefWidth
);
364 // statt Defaulteinstellung in SC alle Cols zu Fuss setzen
365 for( SCCOL nCol
= 0 ; nCol
<= MAXCOL
; nCol
++ )
366 pDoc
->SetColWidth( nCol
, 0, nDefWidth
);
370 void OP_Blank( SvStream
& r
, UINT16
/*n*/ )
374 r
>> nFormat
>> nCol
>> nRow
;
376 SetFormat( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), 0, nFormat
, nDezFloat
);
379 void OP_BOF123( SvStream
& r
, UINT16
/*n*/ )
385 void OP_EOF123( SvStream
& /*r*/, UINT16
/*n*/ )
390 void OP_Label123( SvStream
& r
, UINT16 n
)
394 r
>> nRow
>> nTab
>> nCol
;
397 sal_Char
* pText
= new sal_Char
[n
+ 1];
401 PutFormString( static_cast<SCCOL
>(nCol
), static_cast<SCROW
>(nRow
), static_cast<SCTAB
>(nTab
), pText
);
406 void OP_Number123( SvStream
& r
, UINT16
/*n*/ )
412 r
>> nRow
>> nTab
>> nCol
>> nValue
;
413 double fValue
= Snum32ToDouble( nValue
);
415 ScValueCell
*pCell
= new ScValueCell( fValue
);
416 pDoc
->PutCell( static_cast<SCCOL
>(nCol
), static_cast<SCROW
>(nRow
), static_cast<SCTAB
>(nTab
), pCell
, (BOOL
) TRUE
);
419 void OP_Formula123( SvStream
& r
, UINT16 n
)
424 r
>> nRow
>> nTab
>> nCol
;
425 r
.SeekRel( 8 ); // Result- jump over
427 const ScTokenArray
* pErg
;
428 INT32 nBytesLeft
= n
- 12;
429 ScAddress
aAddress( nCol
, nRow
, nTab
);
431 LotusToSc
aConv( r
, pLotusRoot
->eCharsetQ
, TRUE
);
432 aConv
.Reset( aAddress
);
433 aConv
.Convert( pErg
, nBytesLeft
);
435 ScFormulaCell
* pCell
= new ScFormulaCell( pLotusRoot
->pDoc
, aAddress
, pErg
);
437 pCell
->AddRecalcMode( RECALCMODE_ONLOAD_ONCE
);
439 pDoc
->PutCell( static_cast<SCCOL
>(nCol
), static_cast<SCROW
>(nRow
), static_cast<SCTAB
>(nTab
), pCell
, (BOOL
) TRUE
);
442 void OP_IEEENumber123( SvStream
& r
, UINT16
/*n*/ )
448 r
>> nRow
>> nTab
>> nCol
>> dValue
;
450 ScValueCell
*pCell
= new ScValueCell(dValue
);
451 pDoc
->PutCell( static_cast<SCCOL
>(nCol
), static_cast<SCROW
>(nRow
), static_cast<SCTAB
>(nTab
), pCell
, (BOOL
) TRUE
);
454 void OP_Note123( SvStream
& r
, UINT16 n
)
458 r
>> nRow
>> nTab
>> nCol
;
461 sal_Char
* pText
= new sal_Char
[n
+ 1];
465 String
aNoteText(pText
,pLotusRoot
->eCharsetQ
);
468 ScAddress
aPos( static_cast<SCCOL
>(nCol
), static_cast<SCROW
>(nRow
), static_cast<SCTAB
>(nTab
) );
469 ScNoteUtil::CreateNoteFromString( *pDoc
, aPos
, aNoteText
, false, false );
472 void OP_HorAlign123( BYTE nAlignPattern
, SfxItemSet
& rPatternItemSet
)
474 // pre: Pattern is stored in the last 3 bites of the 21st byte
475 // post: Appropriate Horizontal Alignement is set in rPattern according to the bit pattern.
477 // LEFT:001, RIGHT:010, CENTER:011, JUSTIFY:110,
478 // LEFT-Text/RIGHT-NUMBER:100, DEFAULT:000
480 nAlignPattern
= ( nAlignPattern
& 0x07);
482 switch (nAlignPattern
)
485 rPatternItemSet
.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_LEFT
, ATTR_HOR_JUSTIFY
) );
488 rPatternItemSet
.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_RIGHT
, ATTR_HOR_JUSTIFY
) );
491 rPatternItemSet
.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER
, ATTR_HOR_JUSTIFY
) );
494 rPatternItemSet
.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD
, ATTR_HOR_JUSTIFY
) );
497 rPatternItemSet
.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_BLOCK
, ATTR_HOR_JUSTIFY
) );
500 rPatternItemSet
.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD
, ATTR_HOR_JUSTIFY
) );
505 void OP_VerAlign123( BYTE nAlignPattern
,SfxItemSet
& rPatternItemSet
)
507 // pre: Pattern is stored in the last 3 bites of the 22nd byte
508 // post: Appropriate Verticle Alignement is set in rPattern according to the bit pattern.
510 // TOP:001, MIDDLE:010, DOWN:100, DEFAULT:000
512 nAlignPattern
= ( nAlignPattern
& 0x07);
514 switch (nAlignPattern
)
517 rPatternItemSet
.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_STANDARD
, ATTR_VER_JUSTIFY
) );
520 rPatternItemSet
.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_TOP
, ATTR_VER_JUSTIFY
) );
523 rPatternItemSet
.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_CENTER
, ATTR_VER_JUSTIFY
) );
526 rPatternItemSet
.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_BOTTOM
, ATTR_VER_JUSTIFY
) );
529 rPatternItemSet
.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_STANDARD
, ATTR_VER_JUSTIFY
) );
534 void OP_CreatePattern123( SvStream
& r
, UINT16 n
)
536 UINT16 nCode
,nPatternId
;
538 ScPatternAttr
aPattern(pDoc
->GetPool());
539 SfxItemSet
& rItemSet
= aPattern
.GetItemSet();
544 if ( nCode
== 0x0fd2 )
548 BYTE Hor_Align
, Ver_Align
, temp
;
549 BOOL bIsBold
,bIsUnderLine
,bIsItalics
;
556 bIsBold
= (temp
& 0x01);
557 bIsItalics
= (temp
& 0x02);
558 bIsUnderLine
= (temp
& 0x04);
561 rItemSet
.Put( SvxWeightItem(WEIGHT_BOLD
,ATTR_FONT_WEIGHT
) );
563 rItemSet
.Put( SvxPostureItem(ITALIC_NORMAL
, ATTR_FONT_POSTURE
) );
565 rItemSet
.Put( SvxUnderlineItem( UNDERLINE_SINGLE
, ATTR_FONT_UNDERLINE
) );
571 OP_HorAlign123( Hor_Align
, rItemSet
);
574 OP_VerAlign123( Ver_Align
, rItemSet
);
576 aLotusPatternPool
.insert( std::map
<UINT16
, ScPatternAttr
>::value_type( nPatternId
, aPattern
) );
582 void OP_SheetName123( SvStream
& rStream
, USHORT nLength
)
586 rStream
.SeekRel(nLength
);
590 // B0 36 [sheet number (2 bytes?)] [sheet name (null terminated char array)]
593 rStream
>> nDummy
; // ignore the first 2 bytes (B0 36).
595 SCTAB nSheetNum
= static_cast<SCTAB
>(nDummy
);
596 pDoc
->MakeTable(nSheetNum
);
598 ::std::vector
<sal_Char
> sSheetName
;
599 sSheetName
.reserve(nLength
-4);
600 for (USHORT i
= 4; i
< nLength
; ++i
)
604 sSheetName
.push_back(c
);
607 if (!sSheetName
.empty())
609 String
aName(&sSheetName
[0], eCharVon
);
610 pDoc
->RenameTab(nSheetNum
, aName
);
614 void OP_ApplyPatternArea123( SvStream
& rStream
)
616 UINT16 nOpcode
, nLength
;
617 UINT16 nCol
= 0, nColCount
= 0, nRow
= 0, nRowCount
= 0, nTab
= 0, nData
, nTabCount
= 0, nLevel
= 0;
621 rStream
>> nOpcode
>> nLength
;
624 case ROW_FORMAT_MARKER
:
627 case COL_FORMAT_MARKER
:
631 nTab
= nTab
+ nTabCount
;
632 nCol
= 0; nColCount
= 0;
633 nRow
= 0; nRowCount
= 0;
636 case LOTUS_FORMAT_INDEX
:
640 rStream
.SeekRel( nLength
- 2 );
643 else if( nLevel
== 2 )
645 nCol
= nCol
+ nColCount
;
647 if ( nCol
> 0xff ) // 256 is the max col size supported by 123
650 else if( nLevel
== 3 )
652 nRow
= nRow
+ nRowCount
;
654 if ( nRow
> 0x1fff ) // 8192 is the max row size supported by 123
659 rStream
.SeekRel( nLength
);
661 case LOTUS_FORMAT_INFO
:
665 rStream
.SeekRel( nLength
- 2 );
666 for( int i
= 0; i
< nTabCount
; i
++)
668 std::map
<UINT16
, ScPatternAttr
>::iterator loc
= aLotusPatternPool
.find( nData
);
670 // #126338# apparently, files with invalid index occur in the wild -> don't crash then
671 DBG_ASSERT( loc
!= aLotusPatternPool
.end(), "invalid format index" );
672 if ( loc
!= aLotusPatternPool
.end() )
673 pDoc
->ApplyPatternAreaTab( nCol
, nRow
, nCol
+ nColCount
- 1, nRow
+ nRowCount
- 1, static_cast< SCTAB
>( nTab
+ i
), loc
->second
);
677 rStream
.SeekRel( nLength
);
680 rStream
.SeekRel( nLength
);
684 while( nLevel
&& !rStream
.IsEof() );
686 aLotusPatternPool
.clear();