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