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