1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
31 //------------------------------------------------------------------------
33 #include <tools/solar.h>
34 #include <rtl/math.hxx>
44 #include "scitems.hxx"
45 #include "patattr.hxx"
46 #include "docpool.hxx"
47 #include <svx/algitem.hxx>
48 #include <editeng/postitem.hxx>
49 #include <editeng/udlnitem.hxx>
50 #include <editeng/wghtitem.hxx>
53 #include "rangenam.hxx"
54 #include "document.hxx"
62 #include "lotform.hxx"
63 #include "lotrange.hxx"
76 #if defined( MAC ) || defined( ICC )
80 extern sal_Char
* pAnsi
; // -> memory.cxx, Puffer zum Umwandeln von OEM->ANSI
81 extern sal_Char
* pErgebnis
; // -> memory.cxx, Ergebnispuffer
82 extern WKTYP eTyp
; // -> filter.cxx, aktueller Dateityp
83 extern BOOL bEOF
; // -> filter.cxx, zeigt Dateiende an
84 extern sal_Char
* pPuffer0
; // -> memory.cxx
85 extern sal_Char
* pPuffer1
;
86 extern BYTE nDefaultFormat
; // -> tool.cxx, Default-Zellenformat
87 extern ScDocument
* pDoc
; // -> filter.cxx, Aufhaenger zum Dokumentzugriff
88 extern BYTE
* pFormelBuffer
; // -> memory.cxx, fuer
89 extern CharSet eCharVon
; // -> filter.cxx, character set specified
91 static UINT16 nDefWidth
= ( UINT16
) ( TWIPS_PER_CHAR
* 10 );
93 extern std::map
<UINT16
, ScPatternAttr
> aLotusPatternPool
;
95 void NI( SvStream
& r
, UINT16 n
)
101 void OP_BOF( SvStream
& r
, UINT16
/*n*/ )
103 r
.SeekRel( 2 ); // Versionsnummer ueberlesen
107 void OP_EOF( SvStream
& /*r*/, UINT16
/*n*/ )
113 void OP_Integer( SvStream
& r
, UINT16
/*n*/ )
120 r
>> nFormat
>> nCol
>> nRow
>> nValue
;
122 ScValueCell
* pZelle
= new ScValueCell( ( double ) nValue
);
123 pDoc
->PutCell( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), nTab
, pZelle
, ( BOOL
) TRUE
);
125 // 0 Stellen nach'm Komma!
126 SetFormat( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), nTab
, nFormat
, 0 );
130 void OP_Number( SvStream
& r
, UINT16
/*n*/ )
137 r
>> nFormat
>> nCol
>> nRow
>> fValue
;
139 fValue
= ::rtl::math::round( fValue
, 15 );
140 ScValueCell
* pZelle
= new ScValueCell( fValue
);
141 pDoc
->PutCell( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), nTab
, pZelle
, ( BOOL
) TRUE
);
143 SetFormat( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), nTab
, nFormat
, nDezFloat
);
147 void OP_Label( SvStream
& r
, UINT16 n
)
153 r
>> nFormat
>> nCol
>> nRow
;
156 sal_Char
* pText
= new sal_Char
[n
+ 1];
160 nFormat
&= 0x80; // Bit 7 belassen
161 nFormat
|= 0x75; // protected egal, special-text gesetzt
163 PutFormString( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), nTab
, pText
);
165 SetFormat( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), nTab
, nFormat
, nDezStd
);
171 //UNUSED2009-05 void OP_Text( SvStream& r, UINT16 n ) // WK3
173 //UNUSED2009-05 UINT16 nRow;
174 //UNUSED2009-05 BYTE nCol, nTab;
175 //UNUSED2009-05 sal_Char pText[ 256 ];
177 //UNUSED2009-05 r >> nRow >> nTab >> nCol;
178 //UNUSED2009-05 n -= 4;
180 //UNUSED2009-05 r.Read( pText, n );
181 //UNUSED2009-05 pText[ n ] = 0; // zur Sicherheit Nullterminator anhaengen
183 //UNUSED2009-05 PutFormString( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), static_cast<SCTAB> (nTab), pText );
187 void OP_Formula( SvStream
& r
, UINT16
/*n*/ )
190 UINT16 nCol
, nRow
, nFormulaSize
;
193 r
>> nFormat
>> nCol
>> nRow
;
194 r
.SeekRel( 8 ); // Ergebnis ueberspringen
197 const ScTokenArray
* pErg
;
198 INT32 nBytesLeft
= nFormulaSize
;
199 ScAddress
aAddress( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), nTab
);
201 LotusToSc
aConv( r
, pLotusRoot
->eCharsetQ
, FALSE
);
202 aConv
.Reset( aAddress
);
203 aConv
.Convert( pErg
, nBytesLeft
);
205 ScFormulaCell
* pZelle
= new ScFormulaCell( pLotusRoot
->pDoc
, aAddress
, pErg
);
207 pZelle
->AddRecalcMode( RECALCMODE_ONLOAD_ONCE
);
209 pDoc
->PutCell( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), nTab
, pZelle
, ( BOOL
) TRUE
);
211 // nFormat = Standard -> Nachkommastellen wie Float
212 SetFormat( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), nTab
, nFormat
, nDezFloat
);
216 void OP_ColumnWidth( SvStream
& r
, UINT16
/*n*/ )
218 UINT16 nCol
, nBreite
;
222 r
>> nCol
>> nWidthSpaces
;
225 // Annahme: 10cpi-Zeichensatz
226 nBreite
= ( UINT16
) ( TWIPS_PER_CHAR
* nWidthSpaces
);
229 pDoc
->SetColHidden(static_cast<SCCOL
>(nCol
), static_cast<SCCOL
>(nCol
), 0, true);
233 pDoc
->SetColWidth( static_cast<SCCOL
> (nCol
), nTab
, nBreite
);
237 void OP_NamedRange( SvStream
& r
, UINT16
/*n*/ )
239 // POST: waren Koordinaten ungueltig, wird nicht gespeichert
240 UINT16 nColSt
, nRowSt
, nColEnd
, nRowEnd
;
241 sal_Char cPuffer
[ 32 ];
243 r
.Read( cPuffer
, 16 );
245 r
>> nColSt
>> nRowSt
>> nColEnd
>> nRowEnd
;
249 if( nColSt
== nColEnd
&& nRowSt
== nRowEnd
)
250 pRange
= new LotusRange( static_cast<SCCOL
> (nColSt
), static_cast<SCROW
> (nRowSt
) );
252 pRange
= new LotusRange( static_cast<SCCOL
> (nColSt
), static_cast<SCROW
> (nRowSt
), static_cast<SCCOL
> (nColEnd
), static_cast<SCROW
> (nRowEnd
) );
254 if( isdigit( *cPuffer
) )
255 { // erstes Zeichen im Namen eine Zahl -> 'A' vor Namen setzen
257 strcpy( pAnsi
+ 1, cPuffer
); // #100211# - checked
260 strcpy( pAnsi
, cPuffer
); // #100211# - checked
262 String
aTmp( pAnsi
, pLotusRoot
->eCharsetQ
);
264 ScfTools::ConvertToScDefinedName( aTmp
);
266 pLotusRoot
->pRangeNames
->Append( pRange
, aTmp
);
270 void OP_SymphNamedRange( SvStream
& r
, UINT16
/*n*/ )
272 // POST: waren Koordinaten ungueltig, wird nicht gespeichert
273 UINT16 nColSt
, nRowSt
, nColEnd
, nRowEnd
;
276 sal_Char cPuffer
[ 32 ];
278 r
.Read( cPuffer
, 16 );
282 r
>> nColSt
>> nRowSt
>> nColEnd
>> nRowEnd
>> nType
;
287 pRange
= new LotusRange( static_cast<SCCOL
> (nColSt
), static_cast<SCROW
> (nRowSt
) );
289 pRange
= new LotusRange( static_cast<SCCOL
> (nColSt
), static_cast<SCROW
> (nRowSt
), static_cast<SCCOL
> (nColEnd
), static_cast<SCROW
> (nRowEnd
) );
291 if( isdigit( *cPuffer
) )
292 { // erstes Zeichen im Namen eine Zahl -> 'A' vor Namen setzen
294 strcpy( pAnsi
+ 1, cPuffer
); // #100211# - checked
297 strcpy( pAnsi
, cPuffer
); // #100211# - checked
299 String
aTmp( pAnsi
, pLotusRoot
->eCharsetQ
);
300 ScfTools::ConvertToScDefinedName( aTmp
);
302 pLotusRoot
->pRangeNames
->Append( pRange
, aTmp
);
306 void OP_Footer( SvStream
& r
, UINT16 n
)
312 void OP_Header( SvStream
& r
, UINT16 n
)
318 void OP_Margins( SvStream
& r
, UINT16 n
)
324 void OP_HiddenCols( SvStream
& r
, UINT16
/*n*/ )
331 for( nByte
= 0 ; nByte
< 32 ; nByte
++ ) // 32 Bytes mit ...
334 for( nBit
= 0 ; nBit
< 8 ; nBit
++ ) // ...jeweils 8 Bits = 256 Bits
336 if( nAkt
& 0x01 ) // unterstes Bit gesetzt?
338 pDoc
->SetColHidden(nCount
, nCount
, 0, true);
341 nAkt
= nAkt
/ 2; // der Naechste bitte...
347 void OP_Window1( SvStream
& r
, UINT16 n
)
349 r
.SeekRel( 4 ); // Cursor Pos ueberspringen
353 r
.SeekRel( 1 ); // 'unused' ueberspringen
357 r
.SeekRel( n
- 8 ); // und den Rest ueberspringen
359 nDefWidth
= ( UINT16
) ( TWIPS_PER_CHAR
* nDefWidth
);
361 // statt Defaulteinstellung in SC alle Cols zu Fuss setzen
362 for( SCCOL nCol
= 0 ; nCol
<= MAXCOL
; nCol
++ )
363 pDoc
->SetColWidth( nCol
, 0, nDefWidth
);
367 void OP_Blank( SvStream
& r
, UINT16
/*n*/ )
371 r
>> nFormat
>> nCol
>> nRow
;
373 SetFormat( static_cast<SCCOL
> (nCol
), static_cast<SCROW
> (nRow
), 0, nFormat
, nDezFloat
);
376 void OP_BOF123( SvStream
& r
, UINT16
/*n*/ )
382 void OP_EOF123( SvStream
& /*r*/, UINT16
/*n*/ )
387 void OP_Label123( SvStream
& r
, UINT16 n
)
391 r
>> nRow
>> nTab
>> nCol
;
394 sal_Char
* pText
= new sal_Char
[n
+ 1];
398 PutFormString( static_cast<SCCOL
>(nCol
), static_cast<SCROW
>(nRow
), static_cast<SCTAB
>(nTab
), pText
);
403 void OP_Number123( SvStream
& r
, UINT16
/*n*/ )
409 r
>> nRow
>> nTab
>> nCol
>> nValue
;
410 double fValue
= Snum32ToDouble( nValue
);
412 ScValueCell
*pCell
= new ScValueCell( fValue
);
413 pDoc
->PutCell( static_cast<SCCOL
>(nCol
), static_cast<SCROW
>(nRow
), static_cast<SCTAB
>(nTab
), pCell
, (BOOL
) TRUE
);
416 void OP_Formula123( SvStream
& r
, UINT16 n
)
421 r
>> nRow
>> nTab
>> nCol
;
422 r
.SeekRel( 8 ); // Result- jump over
424 const ScTokenArray
* pErg
;
425 INT32 nBytesLeft
= n
- 12;
426 ScAddress
aAddress( nCol
, nRow
, nTab
);
428 LotusToSc
aConv( r
, pLotusRoot
->eCharsetQ
, TRUE
);
429 aConv
.Reset( aAddress
);
430 aConv
.Convert( pErg
, nBytesLeft
);
432 ScFormulaCell
* pCell
= new ScFormulaCell( pLotusRoot
->pDoc
, aAddress
, pErg
);
434 pCell
->AddRecalcMode( RECALCMODE_ONLOAD_ONCE
);
436 pDoc
->PutCell( static_cast<SCCOL
>(nCol
), static_cast<SCROW
>(nRow
), static_cast<SCTAB
>(nTab
), pCell
, (BOOL
) TRUE
);
439 void OP_IEEENumber123( SvStream
& r
, UINT16
/*n*/ )
445 r
>> nRow
>> nTab
>> nCol
>> dValue
;
447 ScValueCell
*pCell
= new ScValueCell(dValue
);
448 pDoc
->PutCell( static_cast<SCCOL
>(nCol
), static_cast<SCROW
>(nRow
), static_cast<SCTAB
>(nTab
), pCell
, (BOOL
) TRUE
);
451 void OP_Note123( SvStream
& r
, UINT16 n
)
455 r
>> nRow
>> nTab
>> nCol
;
458 sal_Char
* pText
= new sal_Char
[n
+ 1];
462 String
aNoteText(pText
,pLotusRoot
->eCharsetQ
);
465 ScAddress
aPos( static_cast<SCCOL
>(nCol
), static_cast<SCROW
>(nRow
), static_cast<SCTAB
>(nTab
) );
466 ScNoteUtil::CreateNoteFromString( *pDoc
, aPos
, aNoteText
, false, false );
469 void OP_HorAlign123( BYTE nAlignPattern
, SfxItemSet
& rPatternItemSet
)
471 // pre: Pattern is stored in the last 3 bites of the 21st byte
472 // post: Appropriate Horizontal Alignement is set in rPattern according to the bit pattern.
474 // LEFT:001, RIGHT:010, CENTER:011, JUSTIFY:110,
475 // LEFT-Text/RIGHT-NUMBER:100, DEFAULT:000
477 nAlignPattern
= ( nAlignPattern
& 0x07);
479 switch (nAlignPattern
)
482 rPatternItemSet
.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_LEFT
, ATTR_HOR_JUSTIFY
) );
485 rPatternItemSet
.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_RIGHT
, ATTR_HOR_JUSTIFY
) );
488 rPatternItemSet
.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER
, ATTR_HOR_JUSTIFY
) );
491 rPatternItemSet
.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD
, ATTR_HOR_JUSTIFY
) );
494 rPatternItemSet
.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_BLOCK
, ATTR_HOR_JUSTIFY
) );
497 rPatternItemSet
.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD
, ATTR_HOR_JUSTIFY
) );
502 void OP_VerAlign123( BYTE nAlignPattern
,SfxItemSet
& rPatternItemSet
)
504 // pre: Pattern is stored in the last 3 bites of the 22nd byte
505 // post: Appropriate Verticle Alignement is set in rPattern according to the bit pattern.
507 // TOP:001, MIDDLE:010, DOWN:100, DEFAULT:000
509 nAlignPattern
= ( nAlignPattern
& 0x07);
511 switch (nAlignPattern
)
514 rPatternItemSet
.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_STANDARD
, ATTR_VER_JUSTIFY
) );
517 rPatternItemSet
.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_TOP
, ATTR_VER_JUSTIFY
) );
520 rPatternItemSet
.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_CENTER
, ATTR_VER_JUSTIFY
) );
523 rPatternItemSet
.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_BOTTOM
, ATTR_VER_JUSTIFY
) );
526 rPatternItemSet
.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_STANDARD
, ATTR_VER_JUSTIFY
) );
531 void OP_CreatePattern123( SvStream
& r
, UINT16 n
)
533 UINT16 nCode
,nPatternId
;
535 ScPatternAttr
aPattern(pDoc
->GetPool());
536 SfxItemSet
& rItemSet
= aPattern
.GetItemSet();
541 if ( nCode
== 0x0fd2 )
545 BYTE Hor_Align
, Ver_Align
, temp
;
546 BOOL bIsBold
,bIsUnderLine
,bIsItalics
;
553 bIsBold
= (temp
& 0x01);
554 bIsItalics
= (temp
& 0x02);
555 bIsUnderLine
= (temp
& 0x04);
558 rItemSet
.Put( SvxWeightItem(WEIGHT_BOLD
,ATTR_FONT_WEIGHT
) );
560 rItemSet
.Put( SvxPostureItem(ITALIC_NORMAL
, ATTR_FONT_POSTURE
) );
562 rItemSet
.Put( SvxUnderlineItem( UNDERLINE_SINGLE
, ATTR_FONT_UNDERLINE
) );
568 OP_HorAlign123( Hor_Align
, rItemSet
);
571 OP_VerAlign123( Ver_Align
, rItemSet
);
573 aLotusPatternPool
.insert( std::map
<UINT16
, ScPatternAttr
>::value_type( nPatternId
, aPattern
) );
579 void OP_SheetName123( SvStream
& rStream
, USHORT nLength
)
583 rStream
.SeekRel(nLength
);
587 // B0 36 [sheet number (2 bytes?)] [sheet name (null terminated char array)]
590 rStream
>> nDummy
; // ignore the first 2 bytes (B0 36).
592 SCTAB nSheetNum
= static_cast<SCTAB
>(nDummy
);
593 pDoc
->MakeTable(nSheetNum
);
595 ::std::vector
<sal_Char
> sSheetName
;
596 sSheetName
.reserve(nLength
-4);
597 for (USHORT i
= 4; i
< nLength
; ++i
)
601 sSheetName
.push_back(c
);
604 if (!sSheetName
.empty())
606 String
aName(&sSheetName
[0], eCharVon
);
607 pDoc
->RenameTab(nSheetNum
, aName
);
611 void OP_ApplyPatternArea123( SvStream
& rStream
)
613 UINT16 nOpcode
, nLength
;
614 UINT16 nCol
= 0, nColCount
= 0, nRow
= 0, nRowCount
= 0, nTab
= 0, nData
, nTabCount
= 0, nLevel
= 0;
618 rStream
>> nOpcode
>> nLength
;
621 case ROW_FORMAT_MARKER
:
624 case COL_FORMAT_MARKER
:
628 nTab
= nTab
+ nTabCount
;
629 nCol
= 0; nColCount
= 0;
630 nRow
= 0; nRowCount
= 0;
633 case LOTUS_FORMAT_INDEX
:
637 rStream
.SeekRel( nLength
- 2 );
640 else if( nLevel
== 2 )
642 nCol
= nCol
+ nColCount
;
644 if ( nCol
> 0xff ) // 256 is the max col size supported by 123
647 else if( nLevel
== 3 )
649 nRow
= nRow
+ nRowCount
;
651 if ( nRow
> 0x1fff ) // 8192 is the max row size supported by 123
656 rStream
.SeekRel( nLength
);
658 case LOTUS_FORMAT_INFO
:
662 rStream
.SeekRel( nLength
- 2 );
663 for( int i
= 0; i
< nTabCount
; i
++)
665 std::map
<UINT16
, ScPatternAttr
>::iterator loc
= aLotusPatternPool
.find( nData
);
667 // #126338# apparently, files with invalid index occur in the wild -> don't crash then
668 DBG_ASSERT( loc
!= aLotusPatternPool
.end(), "invalid format index" );
669 if ( loc
!= aLotusPatternPool
.end() )
670 pDoc
->ApplyPatternAreaTab( nCol
, nRow
, nCol
+ nColCount
- 1, nRow
+ nRowCount
- 1, static_cast< SCTAB
>( nTab
+ i
), loc
->second
);
674 rStream
.SeekRel( nLength
);
677 rStream
.SeekRel( nLength
);
681 while( nLevel
&& !rStream
.IsEof() );
683 aLotusPatternPool
.clear();