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