1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <rtl/math.hxx>
21 #include <rtl/character.hxx>
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>
34 #include <formulacell.hxx>
35 #include <document.hxx>
41 #include "lotfilter.hxx"
42 #include <lotform.hxx>
43 #include <lotrange.hxx>
51 static sal_uInt16 nDefWidth
= sal_uInt16( TWIPS_PER_CHAR
* 10 );
53 void NI(LotusContext
& /*rContext*/, SvStream
& r
, sal_uInt16 n
)
58 void OP_BOF(LotusContext
& /*rContext*/, SvStream
& r
, sal_uInt16
/*n*/)
60 r
.SeekRel( 2 ); // skip version number
63 void OP_EOF(LotusContext
& rContext
, SvStream
& /*r*/, sal_uInt16
/*n*/)
68 void OP_Integer(LotusContext
& rContext
, SvStream
& r
, sal_uInt16
/*n*/)
71 sal_uInt16
nTmpCol(0), nTmpRow(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
));
77 if (ValidColRow(nCol
, nRow
))
79 rContext
.pDoc
->EnsureTable(0);
80 rContext
.pDoc
->SetValue(ScAddress(nCol
, nRow
, 0), static_cast<double>(nValue
));
82 // 0 digits in fractional part!
83 SetFormat(rContext
, nCol
, nRow
, 0, nFormat
, 0);
87 void OP_Number(LotusContext
& rContext
, SvStream
& r
, sal_uInt16
/*n*/)
90 sal_uInt16
nTmpCol(0), nTmpRow(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
));
96 if (ValidColRow(nCol
, nRow
))
98 fValue
= ::rtl::math::round( fValue
, 15 );
99 rContext
.pDoc
->EnsureTable(0);
100 rContext
.pDoc
->SetValue(ScAddress(nCol
, nRow
, 0), fValue
);
102 SetFormat(rContext
, nCol
, nRow
, 0, nFormat
, nFractionalFloat
);
106 void OP_Label(LotusContext
& rContext
, SvStream
& r
, sal_uInt16 n
)
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
));
114 n
-= std::min
<sal_uInt16
>(n
, 5);
116 std::unique_ptr
<sal_Char
[]> pText(new sal_Char
[n
+ 1]);
117 r
.ReadBytes(pText
.get(), n
);
120 if (ValidColRow(nCol
, nRow
))
122 nFormat
&= 0x80; // don't change Bit 7
123 nFormat
|= 0x75; // protected does not matter, special-text is set
125 PutFormString(rContext
, nCol
, nRow
, 0, pText
.get());
127 SetFormat(rContext
, nCol
, nRow
, 0, nFormat
, nFractionalStd
);
131 void OP_Formula(LotusContext
&rContext
, SvStream
& r
, sal_uInt16
/*n*/)
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
);
140 SCCOL
nCol(static_cast<SCCOL
>(nTmpCol
));
141 SCROW
nRow(static_cast<SCROW
>(nTmpRow
));
143 std::unique_ptr
<ScTokenArray
> pResult
;
144 sal_Int32 nBytesLeft
= nFormulaSize
;
145 ScAddress
aAddress(nCol
, nRow
, 0);
147 svl::SharedStringPool
& rSPool
= rContext
.pLotusRoot
->pDoc
->GetSharedStringPool();
148 LotusToSc
aConv(rContext
, r
, rSPool
, rContext
.pLotusRoot
->eCharsetQ
, false);
149 aConv
.Reset( aAddress
);
150 aConv
.Convert( pResult
, nBytesLeft
);
154 if (ValidColRow(nCol
, nRow
))
156 ScFormulaCell
* pCell
= new ScFormulaCell(rContext
.pLotusRoot
->pDoc
, aAddress
, std::move(pResult
));
157 pCell
->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE
);
158 rContext
.pDoc
->EnsureTable(0);
159 rContext
.pDoc
->SetFormulaCell(ScAddress(nCol
, nRow
, 0), pCell
);
161 // nFormat = Default -> number of digits in fractional part like Float
162 SetFormat(rContext
, nCol
, nRow
, 0, nFormat
, nFractionalFloat
);
166 void OP_ColumnWidth(LotusContext
& rContext
, SvStream
& r
, sal_uInt16
/*n*/)
168 sal_uInt16
nTmpCol(0);
169 sal_uInt8
nWidthSpaces(0);
170 r
.ReadUInt16(nTmpCol
).ReadUChar(nWidthSpaces
);
171 SCCOL
nCol(static_cast<SCCOL
>(nTmpCol
));
175 nCol
= SanitizeCol(nCol
);
179 // assuming 10cpi character set
180 nBreite
= static_cast<sal_uInt16
>( TWIPS_PER_CHAR
* nWidthSpaces
);
183 rContext
.pDoc
->SetColHidden(nCol
, nCol
, 0, true);
187 rContext
.pDoc
->SetColWidth(nCol
, 0, nBreite
);
191 void OP_NamedRange(LotusContext
& rContext
, SvStream
& r
, sal_uInt16
/*n*/)
193 // POST: don't save for invalid coordinates
194 sal_uInt16 nColSt
, nRowSt
, nColEnd
, nRowEnd
;
196 sal_Char cBuffer
[ 16+1 ];
197 r
.ReadBytes(cBuffer
, 16);
200 r
.ReadUInt16( nColSt
).ReadUInt16( nRowSt
).ReadUInt16( nColEnd
).ReadUInt16( nRowEnd
);
202 if (ValidColRow( static_cast<SCCOL
>(nColSt
), nRowSt
) && ValidColRow( static_cast<SCCOL
>(nColEnd
), nRowEnd
))
204 std::unique_ptr
<LotusRange
> pRange
;
206 if( nColSt
== nColEnd
&& nRowSt
== nRowEnd
)
207 pRange
.reset(new LotusRange( static_cast<SCCOL
> (nColSt
), static_cast<SCROW
> (nRowSt
) ));
209 pRange
.reset(new LotusRange( static_cast<SCCOL
> (nColSt
), static_cast<SCROW
> (nRowSt
),
210 static_cast<SCCOL
> (nColEnd
), static_cast<SCROW
> (nRowEnd
) ));
212 sal_Char cBuf
[sizeof(cBuffer
)+1];
213 if( rtl::isAsciiDigit( static_cast<unsigned char>(*cBuffer
) ) )
214 { // first char in name is a number -> prepend 'A'
216 strcpy( cBuf
+ 1, cBuffer
); // #100211# - checked
219 strcpy( cBuf
, cBuffer
); // #100211# - checked
221 OUString
aTmp( cBuf
, strlen(cBuf
), rContext
.pLotusRoot
->eCharsetQ
);
223 aTmp
= ScfTools::ConvertToScDefinedName( aTmp
);
225 rContext
.pLotusRoot
->maRangeNames
.Append( std::move(pRange
) );
229 void OP_SymphNamedRange(LotusContext
& rContext
, SvStream
& r
, sal_uInt16
/*n*/)
231 // POST:don't save for invalid coordinates
232 sal_uInt16 nColSt
, nRowSt
, nColEnd
, nRowEnd
;
235 sal_Char cBuffer
[ 16+1 ];
236 r
.ReadBytes(cBuffer
, 16);
239 r
.ReadUInt16( nColSt
).ReadUInt16( nRowSt
).ReadUInt16( nColEnd
).ReadUInt16( nRowEnd
).ReadUChar( nType
);
241 if (ValidColRow( static_cast<SCCOL
>(nColSt
), nRowSt
) && ValidColRow( static_cast<SCCOL
>(nColEnd
), nRowEnd
))
243 std::unique_ptr
<LotusRange
> pRange
;
246 pRange
.reset(new LotusRange( static_cast<SCCOL
> (nColSt
), static_cast<SCROW
> (nRowSt
) ));
248 pRange
.reset(new LotusRange( static_cast<SCCOL
> (nColSt
), static_cast<SCROW
> (nRowSt
),
249 static_cast<SCCOL
> (nColEnd
), static_cast<SCROW
> (nRowEnd
) ));
251 sal_Char cBuf
[sizeof(cBuffer
)+1];
252 if( rtl::isAsciiDigit( static_cast<unsigned char>(*cBuffer
) ) )
253 { // first char in name is a number -> prepend 'A'
255 strcpy( cBuf
+ 1, cBuffer
); // #100211# - checked
258 strcpy( cBuf
, cBuffer
); // #100211# - checked
260 OUString
aTmp( cBuf
, strlen(cBuf
), rContext
.pLotusRoot
->eCharsetQ
);
261 aTmp
= ScfTools::ConvertToScDefinedName( aTmp
);
263 rContext
.pLotusRoot
->maRangeNames
.Append( std::move(pRange
) );
267 void OP_Footer(LotusContext
& /*rContext*/, SvStream
& r
, sal_uInt16 n
)
272 void OP_Header(LotusContext
& /*rContext*/, SvStream
& r
, sal_uInt16 n
)
277 void OP_Margins(LotusContext
& /*rContext*/, SvStream
& r
, sal_uInt16 n
)
282 void OP_HiddenCols(LotusContext
& rContext
, SvStream
& r
, sal_uInt16
/*n*/)
284 sal_uInt16 nByte
, nBit
;
289 for( nByte
= 0 ; nByte
< 32 ; nByte
++ ) // 32 Bytes with ...
291 r
.ReadUChar( nCurrent
);
292 for( nBit
= 0 ; nBit
< 8 ; nBit
++ ) // ...each 8 Bits = 256 Bits
294 if( nCurrent
& 0x01 ) // is lowest Bit set?
297 rContext
.pDoc
->SetColHidden(nCount
, nCount
, 0, true);
301 nCurrent
= nCurrent
/ 2; // the next please...
306 void OP_Window1(LotusContext
& rContext
, SvStream
& r
, sal_uInt16 n
)
308 r
.SeekRel( 4 ); // skip Cursor Pos
310 sal_uInt8 nDefaultFormat
; // -> op.cpp, standard cell format
311 r
.ReadUChar(nDefaultFormat
);
313 r
.SeekRel( 1 ); // skip 'unused'
315 r
.ReadUInt16( nDefWidth
);
319 r
.SeekRel( n
- 8 ); // skip the rest
321 nDefWidth
= static_cast<sal_uInt16
>( TWIPS_PER_CHAR
* nDefWidth
);
323 const bool bFuzzing
= utl::ConfigManager::IsFuzzing();
325 // instead of default, set all Cols in SC by hand
326 for (SCCOL nCol
= 0 ; nCol
<= rContext
.pDoc
->MaxCol() ; nCol
++)
328 rContext
.pDoc
->SetColWidth( nCol
, 0, nDefWidth
);
334 void OP_Blank(LotusContext
& rContext
, SvStream
& r
, sal_uInt16
/*n*/)
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
));
342 SetFormat(rContext
, nCol
, nRow
, 0, nFormat
, nFractionalFloat
);
345 void OP_BOF123(LotusContext
& /*rContext*/, SvStream
& r
, sal_uInt16
/*n*/)
350 void OP_EOF123(LotusContext
& rContext
, SvStream
& /*r*/, sal_uInt16
/*n*/)
352 rContext
.bEOF
= true;
355 void OP_Label123(LotusContext
& rContext
, SvStream
& r
, sal_uInt16 n
)
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
));
364 n
-= std::min
<sal_uInt16
>(n
, 4);
366 std::unique_ptr
<sal_Char
[]> pText(new sal_Char
[n
+ 1]);
367 r
.ReadBytes(pText
.get(), n
);
370 PutFormString(rContext
, nCol
, nRow
, nTab
, pText
.get());
373 void OP_Number123(LotusContext
& rContext
, SvStream
& r
, sal_uInt16
/*n*/)
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
));
383 if (ValidColRow(nCol
, nRow
) && nTab
<= rContext
.pDoc
->GetMaxTableNumber())
385 double fValue
= Snum32ToDouble( nValue
);
386 rContext
.pDoc
->EnsureTable(nTab
);
387 rContext
.pDoc
->SetValue(ScAddress(nCol
,nRow
,nTab
), fValue
);
391 void OP_Formula123(LotusContext
& rContext
, SvStream
& r
, sal_uInt16 n
)
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
401 std::unique_ptr
<ScTokenArray
> pResult
;
402 sal_Int32 nBytesLeft
= (n
> 12) ? n
- 12 : 0;
403 ScAddress
aAddress( nCol
, nRow
, nTab
);
405 svl::SharedStringPool
& rSPool
= rContext
.pLotusRoot
->pDoc
->GetSharedStringPool();
406 LotusToSc
aConv(rContext
, r
, rSPool
, rContext
.pLotusRoot
->eCharsetQ
, true);
407 aConv
.Reset( aAddress
);
408 aConv
.Convert( pResult
, nBytesLeft
);
412 if (ValidColRow(nCol
, nRow
) && nTab
<= rContext
.pDoc
->GetMaxTableNumber())
414 ScFormulaCell
* pCell
= new ScFormulaCell(rContext
.pLotusRoot
->pDoc
, aAddress
, std::move(pResult
));
415 pCell
->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE
);
416 rContext
.pDoc
->EnsureTable(nTab
);
417 rContext
.pDoc
->SetFormulaCell(ScAddress(nCol
,nRow
,nTab
), pCell
);
421 void OP_IEEENumber123(LotusContext
& rContext
, SvStream
& r
, sal_uInt16
/*n*/)
423 sal_uInt16
nTmpRow(0);
424 sal_uInt8
nTmpCol(0), nTmpTab(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
));
431 if (ValidColRow(nCol
, nRow
) && nTab
<= rContext
.pDoc
->GetMaxTableNumber())
433 rContext
.pDoc
->EnsureTable(nTab
);
434 rContext
.pDoc
->SetValue(ScAddress(nCol
,nRow
,nTab
), dValue
);
438 void OP_Note123(LotusContext
& rContext
, SvStream
& r
, sal_uInt16 n
)
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
));
447 n
-= std::min
<sal_uInt16
>(n
, 4);
449 std::unique_ptr
<sal_Char
[]> pText(new sal_Char
[n
+ 1]);
450 r
.ReadBytes(pText
.get(), n
);
453 OUString
aNoteText(pText
.get(), strlen(pText
.get()), rContext
.pLotusRoot
->eCharsetQ
);
456 ScAddress
aPos(nCol
, nRow
, nTab
);
457 ScNoteUtil::CreateNoteFromString( *rContext
.pDoc
, aPos
, aNoteText
, false, false );
460 void OP_HorAlign123(LotusContext
& /*rContext*/, sal_uInt8 nAlignPattern
, SfxItemSet
& rPatternItemSet
)
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.
465 // LEFT:001, RIGHT:010, CENTER:011, JUSTIFY:110,
466 // LEFT-Text/RIGHT-NUMBER:100, DEFAULT:000
468 nAlignPattern
= ( nAlignPattern
& 0x07);
470 switch (nAlignPattern
)
473 rPatternItemSet
.Put( SvxHorJustifyItem( SvxCellHorJustify::Left
, ATTR_HOR_JUSTIFY
) );
476 rPatternItemSet
.Put( SvxHorJustifyItem( SvxCellHorJustify::Right
, ATTR_HOR_JUSTIFY
) );
479 rPatternItemSet
.Put( SvxHorJustifyItem( SvxCellHorJustify::Center
, ATTR_HOR_JUSTIFY
) );
482 rPatternItemSet
.Put( SvxHorJustifyItem( SvxCellHorJustify::Standard
, ATTR_HOR_JUSTIFY
) );
485 rPatternItemSet
.Put( SvxHorJustifyItem( SvxCellHorJustify::Block
, ATTR_HOR_JUSTIFY
) );
488 rPatternItemSet
.Put( SvxHorJustifyItem( SvxCellHorJustify::Standard
, ATTR_HOR_JUSTIFY
) );
493 void OP_VerAlign123(LotusContext
& /*rContext*/, sal_uInt8 nAlignPattern
, SfxItemSet
& rPatternItemSet
)
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.
498 // TOP:001, MIDDLE:010, DOWN:100, DEFAULT:000
500 nAlignPattern
= ( nAlignPattern
& 0x07);
502 switch (nAlignPattern
)
505 rPatternItemSet
.Put( SvxVerJustifyItem(SvxCellVerJustify::Standard
, ATTR_VER_JUSTIFY
) );
508 rPatternItemSet
.Put( SvxVerJustifyItem(SvxCellVerJustify::Top
, ATTR_VER_JUSTIFY
) );
511 rPatternItemSet
.Put( SvxVerJustifyItem(SvxCellVerJustify::Center
, ATTR_VER_JUSTIFY
) );
514 rPatternItemSet
.Put( SvxVerJustifyItem(SvxCellVerJustify::Bottom
, ATTR_VER_JUSTIFY
) );
517 rPatternItemSet
.Put( SvxVerJustifyItem(SvxCellVerJustify::Standard
, ATTR_VER_JUSTIFY
) );
522 void OP_CreatePattern123(LotusContext
& rContext
, SvStream
& r
, sal_uInt16 n
)
524 sal_uInt16 nCode
,nPatternId
;
526 ScPatternAttr
aPattern(rContext
.pDoc
->GetPool());
527 SfxItemSet
& rItemSet
= aPattern
.GetItemSet();
529 r
.ReadUInt16( nCode
);
530 n
-= std::min
<sal_uInt16
>(n
, 2);
532 if ( nCode
== 0x0fd2 )
534 r
.ReadUInt16( nPatternId
);
536 sal_uInt8 Hor_Align
, Ver_Align
, temp
;
537 bool bIsBold
,bIsUnderLine
,bIsItalics
;
544 bIsBold
= (temp
& 0x01);
545 bIsItalics
= (temp
& 0x02);
546 bIsUnderLine
= (temp
& 0x04);
549 rItemSet
.Put( SvxWeightItem(WEIGHT_BOLD
,ATTR_FONT_WEIGHT
) );
551 rItemSet
.Put( SvxPostureItem(ITALIC_NORMAL
, ATTR_FONT_POSTURE
) );
553 rItemSet
.Put( SvxUnderlineItem( LINESTYLE_SINGLE
, ATTR_FONT_UNDERLINE
) );
558 r
.ReadUChar( Hor_Align
);
559 OP_HorAlign123(rContext
, Hor_Align
, rItemSet
);
561 r
.ReadUChar( Ver_Align
);
562 OP_VerAlign123(rContext
, Ver_Align
, rItemSet
);
564 rContext
.aLotusPatternPool
.emplace( nPatternId
, aPattern
);
565 n
-= std::min
<sal_uInt16
>(n
, 20);
570 void OP_SheetName123(LotusContext
& rContext
, SvStream
& rStream
, sal_uInt16 nLength
)
574 rStream
.SeekRel(nLength
);
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
);
583 ::std::vector
<sal_Char
> sSheetName
;
584 sSheetName
.reserve(nLength
-4);
585 for (sal_uInt16 i
= 4; i
< nLength
; ++i
)
588 rStream
.ReadChar( c
);
589 sSheetName
.push_back(c
);
592 if (!ValidTab(nSheetNum
))
594 // coverity[tainted_data : FALSE] - ValidTab has sanitized nSheetNum
595 rContext
.pDoc
->MakeTable(nSheetNum
);
596 if (!sSheetName
.empty())
598 OUString
aName(sSheetName
.data(), strlen(sSheetName
.data()), rContext
.eCharVon
);
599 rContext
.pDoc
->RenameTab(nSheetNum
, aName
);
603 void OP_ApplyPatternArea123(LotusContext
& rContext
, SvStream
& rStream
)
605 sal_uInt16 nOpcode
, nLength
;
606 sal_uInt16 nCol
= 0, nColCount
= 0, nRow
= 0, nRowCount
= 0, nTab
= 0, nData
, nTabCount
= 0, nLevel
= 0;
610 rStream
.ReadUInt16( nOpcode
).ReadUInt16( nLength
);
613 case ROW_FORMAT_MARKER
:
616 case COL_FORMAT_MARKER
:
620 nTab
= nTab
+ nTabCount
;
621 nCol
= 0; nColCount
= 0;
622 nRow
= 0; nRowCount
= 0;
625 case LOTUS_FORMAT_INDEX
:
628 rStream
.ReadUInt16( nData
);
629 rStream
.SeekRel( nLength
- 2 );
631 nTabCount
= SanitizeTab(nData
);
632 else if( nLevel
== 2 )
634 nCol
= nCol
+ nColCount
;
636 if ( nCol
> 0xff ) // 256 is the max col size supported by 123
639 else if( nLevel
== 3 )
641 nRow
= nRow
+ nRowCount
;
643 if ( nRow
> 0x1fff ) // 8192 is the max row size supported by 123
648 rStream
.SeekRel( nLength
);
650 case LOTUS_FORMAT_INFO
:
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
++)
660 rContext
.pDoc
->ApplyPatternAreaTab( nCol
, nRow
, nCol
+ nColCount
- 1, nRow
+ nRowCount
- 1, static_cast< SCTAB
>( nTab
+ i
), loc
->second
);
664 rStream
.SeekRel( nLength
);
667 rStream
.SeekRel( nLength
);
671 while( nLevel
&& rStream
.good() );
673 rContext
.aLotusPatternPool
.clear();
676 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */