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