1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26
27 //------------------------------------------------------------------------
28
29 #include <tools/solar.h>
30 #include <rtl/math.hxx>
31
32 #include <stdio.h>
33 #include <string.h>
34 #include <math.h>
35 #include <ctype.h>
36 #include <stdlib.h>
37
38 #include "scitems.hxx"
39 #include "patattr.hxx"
40 #include "docpool.hxx"
41 #include <svx/algitem.hxx>
42 #include <editeng/postitem.hxx>
43 #include <editeng/udlnitem.hxx>
44 #include <editeng/wghtitem.hxx>
45
46 #include "cell.hxx"
47 #include "rangenam.hxx"
48 #include "document.hxx"
49 #include "postit.hxx"
50
51 #include "op.h"
52 #include "optab.h"
53 #include "tool.h"
54 #include "decl.h"
55 #include "lotform.hxx"
56 #include "lotrange.hxx"
57
58 #include "root.hxx"
59
60 #include "ftools.hxx"
61
62 #include <vector>
63 #include <map>
64
65 extern WKTYP eTyp; // -> filter.cxx, aktueller Dateityp
66 extern sal_Bool bEOF; // -> filter.cxx, zeigt Dateiende an
67 extern sal_uInt8 nDefaultFormat; // -> tool.cxx, Default-Zellenformat
68 extern ScDocument* pDoc; // -> filter.cxx, Aufhaenger zum Dokumentzugriff
69 extern CharSet eCharVon; // -> filter.cxx, character set specified
70
71 static sal_uInt16 nDefWidth = ( sal_uInt16 ) ( TWIPS_PER_CHAR * 10 );
72
73 extern std::map<sal_uInt16, ScPatternAttr> aLotusPatternPool;
74
NI(SvStream & r,sal_uInt16 n)75 void NI( SvStream& r, sal_uInt16 n )
76 {
77 r.SeekRel( n );
78 }
79
80
OP_BOF(SvStream & r,sal_uInt16)81 void OP_BOF( SvStream& r, sal_uInt16 /*n*/ )
82 {
83 r.SeekRel( 2 ); // Versionsnummer ueberlesen
84 }
85
86
OP_EOF(SvStream &,sal_uInt16)87 void OP_EOF( SvStream& /*r*/, sal_uInt16 /*n*/ )
88 {
89 bEOF = sal_True;
90 }
91
92
OP_Integer(SvStream & r,sal_uInt16)93 void OP_Integer( SvStream& r, sal_uInt16 /*n*/ )
94 {
95 sal_uInt8 nFormat;
96 sal_uInt16 nCol, nRow;
97 SCTAB nTab = 0;
98 sal_Int16 nValue;
99
100 r >> nFormat >> nCol >> nRow >> nValue;
101
102 if (ValidColRow( static_cast<SCCOL>(nCol), nRow))
103 {
104 ScValueCell* pZelle = new ScValueCell( ( double ) nValue );
105 pDoc->PutCell( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, pZelle, ( sal_Bool ) sal_True );
106
107 // 0 Stellen nach'm Komma!
108 SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, nFormat, 0 );
109 }
110 }
111
112
OP_Number(SvStream & r,sal_uInt16)113 void OP_Number( SvStream& r, sal_uInt16 /*n*/ )
114 {
115 sal_uInt8 nFormat;
116 sal_uInt16 nCol, nRow;
117 SCTAB nTab = 0;
118 double fValue;
119
120 r >> nFormat >> nCol >> nRow >> fValue;
121
122 if (ValidColRow( static_cast<SCCOL>(nCol), nRow))
123 {
124 fValue = ::rtl::math::round( fValue, 15 );
125 ScValueCell* pZelle = new ScValueCell( fValue );
126 pDoc->PutCell( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, pZelle, ( sal_Bool ) sal_True );
127
128 SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, nFormat, nDezFloat );
129 }
130 }
131
132
OP_Label(SvStream & r,sal_uInt16 n)133 void OP_Label( SvStream& r, sal_uInt16 n )
134 {
135 sal_uInt8 nFormat;
136 sal_uInt16 nCol, nRow;
137 SCTAB nTab = 0;
138
139 r >> nFormat >> nCol >> nRow;
140
141 n -= (n > 5) ? 5 : n;
142
143 sal_Char* pText = new sal_Char[n + 1];
144 r.Read( pText, n );
145 pText[n] = 0;
146
147 if (ValidColRow( static_cast<SCCOL>(nCol), nRow))
148 {
149 nFormat &= 0x80; // Bit 7 belassen
150 nFormat |= 0x75; // protected egal, special-text gesetzt
151
152 PutFormString( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, pText );
153
154 SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, nFormat, nDezStd );
155 }
156
157 delete [] pText;
158 }
159
160
OP_Formula(SvStream & r,sal_uInt16)161 void OP_Formula( SvStream& r, sal_uInt16 /*n*/ )
162 {
163 sal_uInt8 nFormat;
164 sal_uInt16 nCol, nRow, nFormulaSize;
165 SCTAB nTab = 0;
166
167 r >> nFormat >> nCol >> nRow;
168 r.SeekRel( 8 ); // Ergebnis ueberspringen
169 r >> nFormulaSize;
170
171 const ScTokenArray* pErg;
172 sal_Int32 nBytesLeft = nFormulaSize;
173 ScAddress aAddress( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab );
174
175 LotusToSc aConv( r, pLotusRoot->eCharsetQ, sal_False );
176 aConv.Reset( aAddress );
177 aConv.Convert( pErg, nBytesLeft );
178
179 if (ValidColRow( static_cast<SCCOL>(nCol), nRow))
180 {
181 ScFormulaCell* pZelle = new ScFormulaCell( pLotusRoot->pDoc, aAddress, pErg );
182
183 pZelle->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
184
185 pDoc->PutCell( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, pZelle, ( sal_Bool ) sal_True );
186
187 // nFormat = Standard -> Nachkommastellen wie Float
188 SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), nTab, nFormat, nDezFloat );
189 }
190 }
191
192
OP_ColumnWidth(SvStream & r,sal_uInt16)193 void OP_ColumnWidth( SvStream& r, sal_uInt16 /*n*/ )
194 {
195 sal_uInt16 nCol, nBreite;
196 sal_uInt8 nWidthSpaces;
197 SCTAB nTab = 0;
198
199 r >> nCol >> nWidthSpaces;
200
201 if (ValidCol( static_cast<SCCOL>(nCol)))
202 {
203 if( nWidthSpaces )
204 // Annahme: 10cpi-Zeichensatz
205 nBreite = ( sal_uInt16 ) ( TWIPS_PER_CHAR * nWidthSpaces );
206 else
207 {
208 pDoc->SetColHidden(static_cast<SCCOL>(nCol), static_cast<SCCOL>(nCol), 0, true);
209 nBreite = nDefWidth;
210 }
211
212 pDoc->SetColWidth( static_cast<SCCOL> (nCol), nTab, nBreite );
213 }
214 }
215
216
OP_NamedRange(SvStream & r,sal_uInt16)217 void OP_NamedRange( SvStream& r, sal_uInt16 /*n*/ )
218 {
219 // POST: waren Koordinaten ungueltig, wird nicht gespeichert
220 sal_uInt16 nColSt, nRowSt, nColEnd, nRowEnd;
221
222 sal_Char cPuffer[ 16+1 ];
223 r.Read( cPuffer, 16 );
224 cPuffer[ 16 ] = 0;
225
226 r >> nColSt >> nRowSt >> nColEnd >> nRowEnd;
227
228 if (ValidColRow( static_cast<SCCOL>(nColSt), nRowSt) && ValidColRow( static_cast<SCCOL>(nColEnd), nRowEnd))
229 {
230 LotusRange* pRange;
231
232 if( nColSt == nColEnd && nRowSt == nRowEnd )
233 pRange = new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt) );
234 else
235 pRange = new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt),
236 static_cast<SCCOL> (nColEnd), static_cast<SCROW> (nRowEnd) );
237
238 sal_Char cBuf[sizeof(cPuffer)+1];
239 if( isdigit( *cPuffer ) )
240 { // erstes Zeichen im Namen eine Zahl -> 'A' vor Namen setzen
241 cBuf[0] = 'A';
242 strcpy( cBuf + 1, cPuffer ); // #100211# - checked
243 }
244 else
245 strcpy( cBuf, cPuffer ); // #100211# - checked
246
247 String aTmp( cBuf, pLotusRoot->eCharsetQ );
248
249 ScfTools::ConvertToScDefinedName( aTmp );
250
251 pLotusRoot->pRangeNames->Append( pRange, aTmp );
252 }
253 }
254
255
OP_SymphNamedRange(SvStream & r,sal_uInt16)256 void OP_SymphNamedRange( SvStream& r, sal_uInt16 /*n*/ )
257 {
258 // POST: waren Koordinaten ungueltig, wird nicht gespeichert
259 sal_uInt16 nColSt, nRowSt, nColEnd, nRowEnd;
260 sal_uInt8 nType;
261
262 sal_Char cPuffer[ 16+1 ];
263 r.Read( cPuffer, 16 );
264 cPuffer[ 16 ] = 0;
265
266 r >> nColSt >> nRowSt >> nColEnd >> nRowEnd >> nType;
267
268 if (ValidColRow( static_cast<SCCOL>(nColSt), nRowSt) && ValidColRow( static_cast<SCCOL>(nColEnd), nRowEnd))
269 {
270 LotusRange* pRange;
271
272 if( nType )
273 pRange = new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt) );
274 else
275 pRange = new LotusRange( static_cast<SCCOL> (nColSt), static_cast<SCROW> (nRowSt),
276 static_cast<SCCOL> (nColEnd), static_cast<SCROW> (nRowEnd) );
277
278 sal_Char cBuf[sizeof(cPuffer)+1];
279 if( isdigit( *cPuffer ) )
280 { // erstes Zeichen im Namen eine Zahl -> 'A' vor Namen setzen
281 cBuf[0] = 'A';
282 strcpy( cBuf + 1, cPuffer ); // #100211# - checked
283 }
284 else
285 strcpy( cBuf, cPuffer ); // #100211# - checked
286
287 String aTmp( cBuf, pLotusRoot->eCharsetQ );
288 ScfTools::ConvertToScDefinedName( aTmp );
289
290 pLotusRoot->pRangeNames->Append( pRange, aTmp );
291 }
292 }
293
294
OP_Footer(SvStream & r,sal_uInt16 n)295 void OP_Footer( SvStream& r, sal_uInt16 n )
296 {
297 r.SeekRel( n );
298 }
299
300
OP_Header(SvStream & r,sal_uInt16 n)301 void OP_Header( SvStream& r, sal_uInt16 n )
302 {
303 r.SeekRel( n );
304 }
305
306
OP_Margins(SvStream & r,sal_uInt16 n)307 void OP_Margins( SvStream& r, sal_uInt16 n )
308 {
309 r.SeekRel( n );
310 }
311
312
OP_HiddenCols(SvStream & r,sal_uInt16)313 void OP_HiddenCols( SvStream& r, sal_uInt16 /*n*/ )
314 {
315 sal_uInt16 nByte, nBit;
316 SCCOL nCount;
317 sal_uInt8 nAkt;
318 nCount = 0;
319
320 for( nByte = 0 ; nByte < 32 ; nByte++ ) // 32 Bytes mit ...
321 {
322 r >> nAkt;
323 for( nBit = 0 ; nBit < 8 ; nBit++ ) // ...jeweils 8 Bits = 256 Bits
324 {
325 if( nAkt & 0x01 ) // unterstes Bit gesetzt?
326 // -> Hidden Col
327 pDoc->SetColHidden(nCount, nCount, 0, true);
328
329 nCount++;
330 nAkt = nAkt / 2; // der Naechste bitte...
331 }
332 }
333 }
334
335
OP_Window1(SvStream & r,sal_uInt16 n)336 void OP_Window1( SvStream& r, sal_uInt16 n )
337 {
338 r.SeekRel( 4 ); // Cursor Pos ueberspringen
339
340 r >> nDefaultFormat;
341
342 r.SeekRel( 1 ); // 'unused' ueberspringen
343
344 r >> nDefWidth;
345
346 r.SeekRel( n - 8 ); // und den Rest ueberspringen
347
348 nDefWidth = ( sal_uInt16 ) ( TWIPS_PER_CHAR * nDefWidth );
349
350 // statt Defaulteinstellung in SC alle Cols zu Fuss setzen
351 for( SCCOL nCol = 0 ; nCol <= MAXCOL ; nCol++ )
352 pDoc->SetColWidth( nCol, 0, nDefWidth );
353 }
354
355
OP_Blank(SvStream & r,sal_uInt16)356 void OP_Blank( SvStream& r, sal_uInt16 /*n*/ )
357 {
358 sal_uInt16 nCol, nRow;
359 sal_uInt8 nFormat;
360 r >> nFormat >> nCol >> nRow;
361
362 SetFormat( static_cast<SCCOL> (nCol), static_cast<SCROW> (nRow), 0, nFormat, nDezFloat );
363 }
364
OP_BOF123(SvStream & r,sal_uInt16)365 void OP_BOF123( SvStream& r, sal_uInt16 /*n*/ )
366 {
367 r.SeekRel( 26 );
368 }
369
370
OP_EOF123(SvStream &,sal_uInt16)371 void OP_EOF123( SvStream& /*r*/, sal_uInt16 /*n*/ )
372 {
373 bEOF = sal_True;
374 }
375
OP_Label123(SvStream & r,sal_uInt16 n)376 void OP_Label123( SvStream& r, sal_uInt16 n )
377 {
378 sal_uInt8 nTab, nCol;
379 sal_uInt16 nRow;
380 r >> nRow >> nTab >> nCol;
381 n -= (n > 4) ? 4 : n;
382
383 sal_Char* pText = new sal_Char[n + 1];
384 r.Read( pText, n );
385 pText[ n ] = 0;
386
387 PutFormString( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), pText );
388
389 delete []pText;
390 }
391
OP_Number123(SvStream & r,sal_uInt16)392 void OP_Number123( SvStream& r, sal_uInt16 /*n*/ )
393 {
394 sal_uInt8 nCol,nTab;
395 sal_uInt16 nRow;
396 sal_uInt32 nValue;
397
398 r >> nRow >> nTab >> nCol >> nValue;
399
400 if (ValidColRow( static_cast<SCCOL>(nCol), nRow) && nTab < pDoc->GetMaxTableNumber())
401 {
402 double fValue = Snum32ToDouble( nValue );
403
404 ScValueCell *pCell = new ScValueCell( fValue );
405 pDoc->PutCell( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), pCell, (sal_Bool) sal_True );
406 }
407 }
408
OP_Formula123(SvStream & r,sal_uInt16 n)409 void OP_Formula123( SvStream& r, sal_uInt16 n )
410 {
411 sal_uInt8 nCol,nTab;
412 sal_uInt16 nRow;
413
414 r >> nRow >> nTab >> nCol;
415 r.SeekRel( 8 ); // Result- jump over
416
417 const ScTokenArray* pErg;
418 sal_Int32 nBytesLeft = (n > 12) ? n - 12 : 0;
419 ScAddress aAddress( nCol, nRow, nTab );
420
421 LotusToSc aConv( r, pLotusRoot->eCharsetQ, sal_True );
422 aConv.Reset( aAddress );
423 aConv.Convert( pErg, nBytesLeft );
424
425 if (ValidColRow( static_cast<SCCOL>(nCol), nRow) && nTab < pDoc->GetMaxTableNumber())
426 {
427 ScFormulaCell* pCell = new ScFormulaCell( pLotusRoot->pDoc, aAddress, pErg );
428
429 pCell->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
430
431 pDoc->PutCell( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), pCell, (sal_Bool) sal_True );
432 }
433 }
434
OP_IEEENumber123(SvStream & r,sal_uInt16)435 void OP_IEEENumber123( SvStream& r, sal_uInt16 /*n*/ )
436 {
437 sal_uInt8 nCol,nTab;
438 sal_uInt16 nRow;
439 double dValue;
440
441 r >> nRow >> nTab >> nCol >> dValue;
442
443 if (ValidColRow( static_cast<SCCOL>(nCol), nRow) && nTab < pDoc->GetMaxTableNumber())
444 {
445 ScValueCell *pCell = new ScValueCell(dValue);
446 pDoc->PutCell( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab), pCell, (sal_Bool) sal_True );
447 }
448 }
449
OP_Note123(SvStream & r,sal_uInt16 n)450 void OP_Note123( SvStream& r, sal_uInt16 n)
451 {
452 sal_uInt8 nTab, nCol;
453 sal_uInt16 nRow;
454 r >> nRow >> nTab >> nCol;
455 n -= (n > 4) ? 4 : n;
456
457 sal_Char* pText = new sal_Char[n + 1];
458 r.Read( pText, n );
459 pText[ n ] = 0;
460
461 String aNoteText(pText,pLotusRoot->eCharsetQ);
462 delete [] pText;
463
464 ScAddress aPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab) );
465 ScNoteUtil::CreateNoteFromString( *pDoc, aPos, aNoteText, false, false );
466 }
467
OP_HorAlign123(sal_uInt8 nAlignPattern,SfxItemSet & rPatternItemSet)468 void OP_HorAlign123( sal_uInt8 nAlignPattern, SfxItemSet& rPatternItemSet )
469 {
470 // pre: Pattern is stored in the last 3 bites of the 21st byte
471 // post: Appropriate Horizontal Alignement is set in rPattern according to the bit pattern.
472 //
473 // LEFT:001, RIGHT:010, CENTER:011, JUSTIFY:110,
474 // LEFT-Text/RIGHT-NUMBER:100, DEFAULT:000
475
476 nAlignPattern = ( nAlignPattern & 0x07);
477
478 switch (nAlignPattern)
479 {
480 case 1:
481 rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_LEFT, ATTR_HOR_JUSTIFY ) );
482 break;
483 case 2:
484 rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_RIGHT, ATTR_HOR_JUSTIFY ) );
485 break;
486 case 3:
487 rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY) );
488 break;
489 case 4:
490 rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD, ATTR_HOR_JUSTIFY ) );
491 break;
492 case 6:
493 rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_BLOCK, ATTR_HOR_JUSTIFY ) );
494 break;
495 default:
496 rPatternItemSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD, ATTR_HOR_JUSTIFY ) );
497 break;
498 }
499 }
500
OP_VerAlign123(sal_uInt8 nAlignPattern,SfxItemSet & rPatternItemSet)501 void OP_VerAlign123( sal_uInt8 nAlignPattern,SfxItemSet& rPatternItemSet )
502 {
503 // pre: Pattern is stored in the last 3 bites of the 22nd byte
504 // post: Appropriate Verticle Alignement is set in rPattern according to the bit pattern.
505 //
506 // TOP:001, MIDDLE:010, DOWN:100, DEFAULT:000
507
508 nAlignPattern = ( nAlignPattern & 0x07);
509
510 switch (nAlignPattern)
511 {
512 case 0:
513 rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_STANDARD, ATTR_VER_JUSTIFY) );
514 break;
515 case 1:
516 rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_TOP, ATTR_VER_JUSTIFY) );
517 break;
518 case 2:
519 rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_CENTER, ATTR_VER_JUSTIFY) );
520 break;
521 case 4:
522 rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_BOTTOM, ATTR_VER_JUSTIFY) );
523 break;
524 default:
525 rPatternItemSet.Put( SvxVerJustifyItem(SVX_VER_JUSTIFY_STANDARD, ATTR_VER_JUSTIFY) );
526 break;
527 }
528 }
529
OP_CreatePattern123(SvStream & r,sal_uInt16 n)530 void OP_CreatePattern123( SvStream& r, sal_uInt16 n)
531 {
532 sal_uInt16 nCode,nPatternId;
533
534 ScPatternAttr aPattern(pDoc->GetPool());
535 SfxItemSet& rItemSet = aPattern.GetItemSet();
536
537 r >> nCode;
538 n -= (n > 2) ? 2 : n;
539
540 if ( nCode == 0x0fd2 )
541 {
542 r >> nPatternId;
543
544 sal_uInt8 Hor_Align, Ver_Align, temp;
545 sal_Bool bIsBold,bIsUnderLine,bIsItalics;
546
547 r.SeekRel(12);
548
549 // Read 17th Byte
550 r >> temp;
551
552 bIsBold = (temp & 0x01);
553 bIsItalics = (temp & 0x02);
554 bIsUnderLine = (temp & 0x04);
555
556 if ( bIsBold )
557 rItemSet.Put( SvxWeightItem(WEIGHT_BOLD,ATTR_FONT_WEIGHT) );
558 if ( bIsItalics )
559 rItemSet.Put( SvxPostureItem(ITALIC_NORMAL, ATTR_FONT_POSTURE ) );
560 if ( bIsUnderLine )
561 rItemSet.Put( SvxUnderlineItem( UNDERLINE_SINGLE, ATTR_FONT_UNDERLINE ) );
562
563 r.SeekRel(3);
564
565 // Read 21st Byte
566 r >> Hor_Align;
567 OP_HorAlign123( Hor_Align, rItemSet );
568
569 r >> Ver_Align;
570 OP_VerAlign123( Ver_Align, rItemSet );
571
572 aLotusPatternPool.insert( std::map<sal_uInt16, ScPatternAttr>::value_type( nPatternId, aPattern ) );
573 n -= (n > 20) ? 20 : n;
574 }
575 r.SeekRel(n);
576 }
577
OP_SheetName123(SvStream & rStream,sal_uInt16 nLength)578 void OP_SheetName123( SvStream& rStream, sal_uInt16 nLength )
579 {
580 if (nLength <= 4)
581 {
582 rStream.SeekRel(nLength);
583 return;
584 }
585
586 // B0 36 [sheet number (2 bytes?)] [sheet name (null terminated char array)]
587
588 sal_uInt16 nDummy;
589 rStream >> nDummy; // ignore the first 2 bytes (B0 36).
590 rStream >> nDummy;
591 SCTAB nSheetNum = static_cast<SCTAB>(nDummy);
592 pDoc->MakeTable(nSheetNum);
593
594 ::std::vector<sal_Char> sSheetName;
595 sSheetName.reserve(nLength-4);
596 for (sal_uInt16 i = 4; i < nLength; ++i)
597 {
598 sal_Char c;
599 rStream >> c;
600 sSheetName.push_back(c);
601 }
602
603 if (!sSheetName.empty())
604 {
605 String aName(&sSheetName[0], eCharVon);
606 pDoc->RenameTab(nSheetNum, aName);
607 }
608 }
609
OP_ApplyPatternArea123(SvStream & rStream)610 void OP_ApplyPatternArea123( SvStream& rStream )
611 {
612 sal_uInt16 nOpcode, nLength;
613 sal_uInt16 nCol = 0, nColCount = 0, nRow = 0, nRowCount = 0, nTab = 0, nData, nTabCount = 0, nLevel = 0;
614
615 do
616 {
617 rStream >> nOpcode >> nLength;
618 switch ( nOpcode )
619 {
620 case ROW_FORMAT_MARKER:
621 nLevel++;
622 break;
623 case COL_FORMAT_MARKER:
624 nLevel--;
625 if( nLevel == 1 )
626 {
627 nTab = nTab + nTabCount;
628 nCol = 0; nColCount = 0;
629 nRow = 0; nRowCount = 0;
630 }
631 break;
632 case LOTUS_FORMAT_INDEX:
633 if( nLength >= 2 )
634 {
635 rStream >> nData;
636 rStream.SeekRel( nLength - 2 );
637 if( nLevel == 1 )
638 nTabCount = nData;
639 else if( nLevel == 2 )
640 {
641 nCol = nCol + nColCount;
642 nColCount = nData;
643 if ( nCol > 0xff ) // 256 is the max col size supported by 123
644 nCol = 0;
645 }
646 else if( nLevel == 3 )
647 {
648 nRow = nRow + nRowCount;
649 nRowCount = nData;
650 if ( nRow > 0x1fff ) // 8192 is the max row size supported by 123
651 nRow = 0;
652 }
653 }
654 else
655 rStream.SeekRel( nLength );
656 break;
657 case LOTUS_FORMAT_INFO:
658 if( nLength >= 2 )
659 {
660 rStream >> nData;
661 rStream.SeekRel( nLength - 2 );
662 std::map<sal_uInt16, ScPatternAttr>::iterator loc = aLotusPatternPool.find( nData );
663 // #126338# apparently, files with invalid index occur in the wild -> don't crash then
664 if ( loc != aLotusPatternPool.end() )
665 for( int i = 0; i < nTabCount; i++)
666 {
667 pDoc->ApplyPatternAreaTab( nCol, nRow, nCol + nColCount - 1, nRow + nRowCount - 1, static_cast< SCTAB >( nTab + i ), loc->second );
668 }
669 }
670 else
671 rStream.SeekRel( nLength );
672 break;
673 default:
674 rStream.SeekRel( nLength );
675 break;
676 }
677 }
678 while( nLevel && !rStream.IsEof() );
679
680 aLotusPatternPool.clear();
681 }
682