LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / sc / source / filter / excel / impop.cxx
blobc23f8f1643095175d9f8d8461f29c564a21abb66
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <memory>
21 #include <imp_op.hxx>
23 #include <filter/msfilter/countryid.hxx>
25 #include <scitems.hxx>
27 #include <o3tl/safeint.hxx>
28 #include <sfx2/docfile.hxx>
29 #include <svx/svxids.hrc>
30 #include <svl/numformat.hxx>
31 #include <svl/zforlist.hxx>
32 #include <unotools/configmgr.hxx>
33 #include <sal/log.hxx>
35 #include <sfx2/objsh.hxx>
36 #include <tools/urlobj.hxx>
37 #include <docuno.hxx>
39 #include <formulacell.hxx>
40 #include <document.hxx>
41 #include <globstr.hrc>
42 #include <scresid.hxx>
43 #include <global.hxx>
44 #include <olinetab.hxx>
45 #include <stlpool.hxx>
46 #include <viewopti.hxx>
47 #include <docoptio.hxx>
48 #include <scextopt.hxx>
49 #include <unonames.hxx>
50 #include <paramisc.hxx>
51 #include <colrowst.hxx>
52 #include <otlnbuff.hxx>
53 #include <xistyle.hxx>
55 #include <namebuff.hxx>
56 #include <xltools.hxx>
57 #include <xltable.hxx>
58 #include <xltracer.hxx>
59 #include <xihelper.hxx>
60 #include <xipage.hxx>
61 #include <xiview.hxx>
62 #include <xiescher.hxx>
63 #include <xicontent.hxx>
65 #include <excform.hxx>
66 #include <documentimport.hxx>
68 #if defined(_WIN32)
69 #include <math.h>
70 #endif
72 using namespace ::com::sun::star;
74 ImportTyp::ImportTyp(ScDocument& rDoc, rtl_TextEncoding eQ)
75 : eQuellChar(eQ)
76 , rD(rDoc)
81 ImportTyp::~ImportTyp()
85 ImportExcel::ImportExcel( XclImpRootData& rImpData, SvStream& rStrm ):
86 ImportTyp( rImpData.mrDoc, rImpData.meTextEnc ),
87 XclImpRoot( rImpData ),
88 maStrm( rStrm, GetRoot() ),
89 aIn( maStrm ),
90 maScOleSize( ScAddress::INITIALIZE_INVALID ),
91 pColOutlineBuff(nullptr),
92 pRowOutlineBuff(nullptr),
93 pColRowBuff(nullptr),
94 mpLastFormula(nullptr),
95 mnLastRefIdx( 0 ),
96 mnIxfeIndex( 0 ),
97 mnLastRecId(0),
98 mbBiff2HasXfs(false),
99 mbBiff2HasXfsValid(false)
101 nBdshtTab = 0;
103 // fill in root data - after new's without root as parameter
104 pExcRoot = &GetOldRoot();
105 pExcRoot->pIR = this; // ExcRoot -> XclImpRoot
106 pExcRoot->eDateiTyp = BiffX;
107 pExcRoot->pExtSheetBuff.reset( new ExtSheetBuffer( pExcRoot ) ); //&aExtSheetBuff;
108 pExcRoot->pShrfmlaBuff.reset( new SharedFormulaBuffer( pExcRoot ) ); //&aShrfrmlaBuff;
109 pExcRoot->pExtNameBuff.reset( new ExtNameBuff ( *this ) );
111 pOutlineListBuffer.reset(new XclImpOutlineListBuffer);
113 // from Biff8 on
114 pFormConv.reset(new ExcelToSc( GetRoot() ));
115 pExcRoot->pFmlaConverter = pFormConv.get();
117 bTabTruncated = false;
119 // Excel document per Default on 31.12.1899, accords to Excel settings with 1.1.1900
120 ScDocOptions aOpt = rD.GetDocOptions();
121 aOpt.SetDate( 30, 12, 1899 );
122 rD.SetDocOptions( aOpt );
123 rD.GetFormatTable()->ChangeNullDate( 30, 12, 1899 );
125 ScDocOptions aDocOpt( rD.GetDocOptions() );
126 aDocOpt.SetIgnoreCase( true ); // always in Excel
127 aDocOpt.SetFormulaRegexEnabled( false ); // regular expressions? what's that?
128 aDocOpt.SetFormulaWildcardsEnabled( true ); // Excel uses wildcard expressions
129 aDocOpt.SetLookUpColRowNames( false ); // default: no natural language refs
130 rD.SetDocOptions( aDocOpt );
133 ImportExcel::~ImportExcel()
135 GetDoc().SetSrcCharSet( GetTextEncoding() );
137 pOutlineListBuffer.reset();
139 pFormConv.reset();
142 void ImportExcel::SetLastFormula( SCCOL nCol, SCROW nRow, double fVal, sal_uInt16 nXF, ScFormulaCell* pCell )
144 LastFormulaMapType::iterator it = maLastFormulaCells.find(nCol);
145 if (it == maLastFormulaCells.end())
147 std::pair<LastFormulaMapType::iterator, bool> r =
148 maLastFormulaCells.emplace(nCol, LastFormula());
149 it = r.first;
152 it->second.mnCol = nCol;
153 it->second.mnRow = nRow;
154 it->second.mpCell = pCell;
155 it->second.mfValue = fVal;
156 it->second.mnXF = nXF;
158 mpLastFormula = &it->second;
161 void ImportExcel::ReadFileSharing()
163 sal_uInt16 nRecommendReadOnly, nPasswordHash;
164 nRecommendReadOnly = maStrm.ReaduInt16();
165 nPasswordHash = maStrm.ReaduInt16();
167 if((nRecommendReadOnly == 0) && (nPasswordHash == 0))
168 return;
170 if( SfxItemSet* pItemSet = GetMedium().GetItemSet() )
171 pItemSet->Put( SfxBoolItem( SID_DOC_READONLY, true ) );
173 if( SfxObjectShell* pShell = GetDocShell() )
175 if( nRecommendReadOnly != 0 )
176 pShell->SetLoadReadonly( true );
177 if( nPasswordHash != 0 )
178 pShell->SetModifyPasswordHash( nPasswordHash );
182 sal_uInt16 ImportExcel::ReadXFIndex( const ScAddress& rScPos, bool bBiff2 )
184 sal_uInt16 nXFIdx = 0;
185 if( bBiff2 )
187 /* #i71453# On first call, check if the file contains XF records (by
188 trying to access the first XF with index 0). If there are no XFs,
189 the explicit formatting information contained in each cell record
190 will be used instead. */
191 if( !mbBiff2HasXfsValid )
193 mbBiff2HasXfsValid = true;
194 mbBiff2HasXfs = GetXFBuffer().GetXF( 0 ) != nullptr;
196 // read formatting information (includes the XF identifier)
197 sal_uInt8 nFlags1, nFlags2, nFlags3;
198 nFlags1 = maStrm.ReaduInt8();
199 nFlags2 = maStrm.ReaduInt8();
200 nFlags3 = maStrm.ReaduInt8();
201 /* If the file contains XFs, extract and set the XF identifier,
202 otherwise get the explicit formatting. */
203 if( mbBiff2HasXfs )
205 nXFIdx = ::extract_value< sal_uInt16 >( nFlags1, 0, 6 );
206 /* If the identifier is equal to 63, then the real identifier is
207 contained in the preceding IXFE record (stored in mnBiff2XfId). */
208 if( nXFIdx == 63 )
209 nXFIdx = mnIxfeIndex;
211 else
213 /* Let the XclImpXF class do the conversion of the imported
214 formatting. The XF buffer is empty, therefore will not do any
215 conversion based on the XF index later on. */
216 XclImpXF::ApplyPatternForBiff2CellFormat( GetRoot(), rScPos, nFlags1, nFlags2, nFlags3 );
219 else
220 nXFIdx = aIn.ReaduInt16();
221 return nXFIdx;
224 void ImportExcel::ReadDimensions()
226 XclRange aXclUsedArea;
227 if( (maStrm.GetRecId() == EXC_ID2_DIMENSIONS) || (GetBiff() <= EXC_BIFF5) )
229 maStrm >> aXclUsedArea;
230 if( (aXclUsedArea.GetColCount() > 1) && (aXclUsedArea.GetRowCount() > 1) )
232 // Excel stores first unused row/column index
233 --aXclUsedArea.maLast.mnCol;
234 --aXclUsedArea.maLast.mnRow;
235 // create the Calc range
236 SCTAB nScTab = GetCurrScTab();
237 ScRange& rScUsedArea = GetExtDocOptions().GetOrCreateTabSettings( nScTab ).maUsedArea;
238 GetAddressConverter().ConvertRange( rScUsedArea, aXclUsedArea, nScTab, nScTab, false );
239 // if any error occurs in ConvertRange(), rScUsedArea keeps untouched
242 else
244 sal_uInt32 nXclRow1 = 0, nXclRow2 = 0;
245 nXclRow1 = maStrm.ReaduInt32();
246 nXclRow2 = maStrm.ReaduInt32();
247 aXclUsedArea.maFirst.mnCol = maStrm.ReaduInt16();
248 aXclUsedArea.maLast.mnCol = maStrm.ReaduInt16();
249 if( (nXclRow1 < nXclRow2) && (aXclUsedArea.GetColCount() > 1) &&
250 (nXclRow1 <= o3tl::make_unsigned( GetScMaxPos().Row() )) )
252 // Excel stores first unused row/column index
253 --nXclRow2;
254 --aXclUsedArea.maLast.mnCol;
255 // convert row indexes to 16-bit values
256 aXclUsedArea.maFirst.mnRow = static_cast< sal_uInt16 >( nXclRow1 );
257 aXclUsedArea.maLast.mnRow = limit_cast< sal_uInt16 >( nXclRow2, aXclUsedArea.maFirst.mnRow, SAL_MAX_UINT16 );
258 // create the Calc range
259 SCTAB nScTab = GetCurrScTab();
260 ScRange& rScUsedArea = GetExtDocOptions().GetOrCreateTabSettings( nScTab ).maUsedArea;
261 GetAddressConverter().ConvertRange( rScUsedArea, aXclUsedArea, nScTab, nScTab, false );
262 // if any error occurs in ConvertRange(), rScUsedArea keeps untouched
267 void ImportExcel::ReadBlank()
269 XclAddress aXclPos;
270 aIn >> aXclPos;
272 ScAddress aScPos( ScAddress::UNINITIALIZED );
273 if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
275 sal_uInt16 nXFIdx = ReadXFIndex( aScPos, maStrm.GetRecId() == EXC_ID2_BLANK );
277 GetXFRangeBuffer().SetBlankXF( aScPos, nXFIdx );
281 void ImportExcel::ReadInteger()
283 XclAddress aXclPos;
284 maStrm >> aXclPos;
286 ScAddress aScPos( ScAddress::UNINITIALIZED );
287 if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
289 sal_uInt16 nXFIdx = ReadXFIndex( aScPos, true );
290 sal_uInt16 nValue;
291 nValue = maStrm.ReaduInt16();
293 GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
294 GetDocImport().setNumericCell(aScPos, nValue);
298 void ImportExcel::ReadNumber()
300 XclAddress aXclPos;
301 maStrm >> aXclPos;
303 ScAddress aScPos( ScAddress::UNINITIALIZED );
304 if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
306 sal_uInt16 nXFIdx = ReadXFIndex( aScPos, maStrm.GetRecId() == EXC_ID2_NUMBER );
307 double fValue;
308 fValue = maStrm.ReadDouble();
310 GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
311 GetDocImport().setNumericCell(aScPos, fValue);
315 void ImportExcel::ReadLabel()
317 XclAddress aXclPos;
318 maStrm >> aXclPos;
320 ScAddress aScPos( ScAddress::UNINITIALIZED );
321 if( !GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
322 return;
324 /* Record ID BIFF XF type String type
325 0x0004 2-7 3 byte 8-bit length, byte string
326 0x0004 8 3 byte 16-bit length, unicode string
327 0x0204 2-7 2 byte 16-bit length, byte string
328 0x0204 8 2 byte 16-bit length, unicode string */
329 bool bBiff2 = maStrm.GetRecId() == EXC_ID2_LABEL;
330 sal_uInt16 nXFIdx = ReadXFIndex( aScPos, bBiff2 );
331 XclStrFlags nFlags = (bBiff2 && (GetBiff() <= EXC_BIFF5)) ? XclStrFlags::EightBitLength : XclStrFlags::NONE;
332 XclImpString aString;
334 // #i63105# use text encoding from FONT record
335 rtl_TextEncoding eOldTextEnc = GetTextEncoding();
336 if( const XclImpFont* pFont = GetXFBuffer().GetFont( nXFIdx ) )
337 SetTextEncoding( pFont->GetFontEncoding() );
338 aString.Read( maStrm, nFlags );
339 SetTextEncoding( eOldTextEnc );
341 GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
342 XclImpStringHelper::SetToDocument(GetDocImport(), aScPos, GetRoot(), aString, nXFIdx);
345 void ImportExcel::ReadBoolErr()
347 XclAddress aXclPos;
348 maStrm >> aXclPos;
350 ScAddress aScPos( ScAddress::UNINITIALIZED );
351 if( !GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
352 return;
354 sal_uInt16 nXFIdx = ReadXFIndex( aScPos, maStrm.GetRecId() == EXC_ID2_BOOLERR );
355 sal_uInt8 nValue, nType;
356 nValue = maStrm.ReaduInt8();
357 nType = maStrm.ReaduInt8();
359 if( nType == EXC_BOOLERR_BOOL )
360 GetXFRangeBuffer().SetBoolXF( aScPos, nXFIdx );
361 else
362 GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
364 double fValue;
365 std::unique_ptr<ScTokenArray> pScTokArr = ErrorToFormula( nType != EXC_BOOLERR_BOOL, nValue, fValue );
366 ScFormulaCell* pCell = pScTokArr
367 ? new ScFormulaCell(rD, aScPos, std::move(pScTokArr))
368 : new ScFormulaCell(rD, aScPos);
369 pCell->SetHybridDouble( fValue );
370 GetDocImport().setFormulaCell(aScPos, pCell);
373 void ImportExcel::ReadRk()
375 XclAddress aXclPos;
376 maStrm >> aXclPos;
378 ScAddress aScPos( ScAddress::UNINITIALIZED );
379 if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
381 sal_uInt16 nXFIdx = ReadXFIndex( aScPos, false );
382 sal_Int32 nRk;
383 nRk = maStrm.ReadInt32();
385 GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
386 GetDocImport().setNumericCell(aScPos, XclTools::GetDoubleFromRK(nRk));
390 void ImportExcel::Window1()
392 GetDocViewSettings().ReadWindow1( maStrm );
395 void ImportExcel::Row25()
397 sal_uInt16 nRow, nRowHeight;
399 nRow = aIn.ReaduInt16();
400 aIn.Ignore( 4 );
402 if( !GetRoot().GetDoc().ValidRow( nRow ) )
403 return;
405 nRowHeight = aIn.ReaduInt16(); // specify direct in Twips
406 aIn.Ignore( 2 );
408 if( GetBiff() == EXC_BIFF2 )
409 {// -------------------- BIFF2
410 pColRowBuff->SetHeight( nRow, nRowHeight );
412 else
413 {// -------------------- BIFF5
414 sal_uInt16 nGrbit;
416 aIn.Ignore( 2 ); // reserved
417 nGrbit = aIn.ReaduInt16();
419 sal_uInt8 nLevel = ::extract_value< sal_uInt8 >( nGrbit, 0, 3 );
420 pRowOutlineBuff->SetLevel( nRow, nLevel, ::get_flag( nGrbit, EXC_ROW_COLLAPSED ) );
421 pColRowBuff->SetRowSettings( nRow, nRowHeight, nGrbit );
425 void ImportExcel::Bof2()
427 sal_uInt16 nSubType;
428 maStrm.DisableDecryption();
429 maStrm.Ignore( 2 );
430 nSubType = maStrm.ReaduInt16();
432 if( nSubType == 0x0020 ) // Chart
433 pExcRoot->eDateiTyp = Biff2C;
434 else if( nSubType == 0x0040 ) // Macro
435 pExcRoot->eDateiTyp = Biff2M;
436 else // #i51490# Excel interprets invalid indexes as worksheet
437 pExcRoot->eDateiTyp = Biff2;
440 void ImportExcel::Eof()
442 // POST: cannot be called after an invalid table!
443 EndSheet();
444 IncCurrScTab();
447 void ImportExcel::SheetPassword()
449 if (GetRoot().GetBiff() != EXC_BIFF8)
450 return;
452 GetRoot().GetSheetProtectBuffer().ReadPasswordHash( aIn, GetCurrScTab() );
455 void ImportExcel::Externsheet()
457 OUString aUrl, aTabName;
458 bool bSameWorkBook;
459 OUString aEncodedUrl( aIn.ReadByteString( false ) );
460 XclImpUrlHelper::DecodeUrl( aUrl, aTabName, bSameWorkBook, *pExcRoot->pIR, aEncodedUrl );
461 mnLastRefIdx = pExcRoot->pExtSheetBuff->Add( aUrl, aTabName, bSameWorkBook );
464 void ImportExcel:: WinProtection()
466 if (GetRoot().GetBiff() != EXC_BIFF8)
467 return;
469 GetRoot().GetDocProtectBuffer().ReadWinProtect( aIn );
472 void ImportExcel::Columndefault()
473 {// Default Cell Attributes
474 sal_uInt16 nColMic, nColMac;
475 sal_uInt8 nOpt0;
477 nColMic = aIn.ReaduInt16();
478 nColMac = aIn.ReaduInt16();
480 OSL_ENSURE( aIn.GetRecLeft() == static_cast<std::size_t>(nColMac - nColMic) * 3 + 2,
481 "ImportExcel::Columndefault - wrong record size" );
483 nColMac--;
485 if( nColMac > rD.MaxCol() )
486 nColMac = static_cast<sal_uInt16>(rD.MaxCol());
488 for( sal_uInt16 nCol = nColMic ; nCol <= nColMac ; nCol++ )
490 nOpt0 = aIn.ReaduInt8();
491 aIn.Ignore( 2 ); // only 0. Attribute-Byte used
493 if( nOpt0 & 0x80 ) // Col hidden?
494 pColRowBuff->HideCol( nCol );
498 void ImportExcel::Array25()
500 sal_uInt16 nFormLen;
501 sal_uInt16 nFirstRow = aIn.ReaduInt16();
502 sal_uInt16 nLastRow = aIn.ReaduInt16();
503 sal_uInt8 nFirstCol = aIn.ReaduInt8();
504 sal_uInt8 nLastCol = aIn.ReaduInt8();
506 if( GetBiff() == EXC_BIFF2 )
507 {// BIFF2
508 aIn.Ignore( 1 );
509 nFormLen = aIn.ReaduInt8();
511 else
512 {// BIFF5
513 aIn.Ignore( 6 );
514 nFormLen = aIn.ReaduInt16();
517 std::unique_ptr<ScTokenArray> pResult;
519 if (GetRoot().GetDoc().ValidColRow(nLastCol, nLastRow))
521 // the read mark is now on the formula, length in nFormLen
523 pFormConv->Reset( ScAddress( static_cast<SCCOL>(nFirstCol),
524 static_cast<SCROW>(nFirstRow), GetCurrScTab() ) );
525 pFormConv->Convert(pResult, maStrm, nFormLen, true);
527 SAL_WARN_IF(!pResult, "sc", "*ImportExcel::Array25(): ScTokenArray is NULL!");
530 if (pResult)
532 ScDocumentImport& rDoc = GetDocImport();
533 ScRange aArrayRange(nFirstCol, nFirstRow, GetCurrScTab(), nLastCol, nLastRow, GetCurrScTab());
534 rDoc.setMatrixCells(aArrayRange, *pResult, formula::FormulaGrammar::GRAM_ENGLISH_XL_A1);
538 void ImportExcel::Rec1904()
540 sal_uInt16 n1904;
542 n1904 = aIn.ReaduInt16();
544 if( n1904 )
545 {// 1904 date system
546 ScDocOptions aOpt = rD.GetDocOptions();
547 aOpt.SetDate( 1, 1, 1904 );
548 rD.SetDocOptions( aOpt );
549 rD.GetFormatTable()->ChangeNullDate( 1, 1, 1904 );
553 void ImportExcel::Externname25()
555 sal_uInt32 nRes;
556 sal_uInt16 nOpt;
558 nOpt = aIn.ReaduInt16();
559 nRes = aIn.ReaduInt32();
561 aIn.ReadByteString( false ); // name
563 if( ( nOpt & 0x0001 ) || ( ( nOpt & 0xFFFE ) == 0x0000 ) )
564 {// external name
565 pExcRoot->pExtNameBuff->AddName( mnLastRefIdx );
567 else if( nOpt & 0x0010 )
568 {// ole link
569 pExcRoot->pExtNameBuff->AddOLE( mnLastRefIdx, nRes ); // nRes is storage ID
571 else
572 {// dde link
573 pExcRoot->pExtNameBuff->AddDDE( mnLastRefIdx );
577 void ImportExcel::Colwidth()
578 {// Column Width
579 sal_uInt8 nColFirst, nColLast;
580 sal_uInt16 nColWidth;
582 nColFirst = aIn.ReaduInt8();
583 nColLast = aIn.ReaduInt8();
584 nColWidth = aIn.ReaduInt16();
586 //TODO: add a check for the unlikely case of changed MAXCOL (-> XclImpAddressConverter)
587 // if( nColLast > rD.MaxCol() )
588 // nColLast = static_cast<sal_uInt16>(rD.MaxCol());
590 sal_uInt16 nScWidth = XclTools::GetScColumnWidth( nColWidth, GetCharWidth() );
591 pColRowBuff->SetWidthRange( nColFirst, nColLast, nScWidth );
594 void ImportExcel::Defrowheight2()
596 sal_uInt16 nDefHeight;
597 nDefHeight = maStrm.ReaduInt16();
598 nDefHeight &= 0x7FFF;
599 pColRowBuff->SetDefHeight( nDefHeight, EXC_DEFROW_UNSYNCED );
602 void ImportExcel::SheetProtect()
604 if (GetRoot().GetBiff() != EXC_BIFF8)
605 return;
607 GetRoot().GetSheetProtectBuffer().ReadProtect( aIn, GetCurrScTab() );
610 void ImportExcel::DocProtect()
612 if (GetRoot().GetBiff() != EXC_BIFF8)
613 return;
615 GetRoot().GetDocProtectBuffer().ReadDocProtect( aIn );
618 void ImportExcel::DocPassword()
620 if (GetRoot().GetBiff() != EXC_BIFF8)
621 return;
623 GetRoot().GetDocProtectBuffer().ReadPasswordHash( aIn );
626 void ImportExcel::Codepage()
628 SetCodePage( maStrm.ReaduInt16() );
631 void ImportExcel::Ixfe()
633 mnIxfeIndex = maStrm.ReaduInt16();
636 void ImportExcel::DefColWidth()
638 // stored as entire characters -> convert to 1/256 of characters (as in COLINFO)
639 double fDefWidth = 256.0 * maStrm.ReaduInt16();
641 if (!pColRowBuff)
643 SAL_WARN("sc", "*ImportExcel::DefColWidth(): pColRowBuff is NULL!");
644 return;
647 // #i3006# additional space for default width - Excel adds space depending on font size
648 tools::Long nFontHt = GetFontBuffer().GetAppFontData().mnHeight;
649 fDefWidth += XclTools::GetXclDefColWidthCorrection( nFontHt );
651 sal_uInt16 nScWidth = XclTools::GetScColumnWidth( limit_cast< sal_uInt16 >( fDefWidth ), GetCharWidth() );
652 pColRowBuff->SetDefWidth( nScWidth );
655 void ImportExcel::Colinfo()
656 {// Column Formatting Information
657 sal_uInt16 nColFirst, nColLast, nColWidth, nXF;
658 sal_uInt16 nOpt;
660 nColFirst = aIn.ReaduInt16();
661 nColLast = aIn.ReaduInt16();
662 nColWidth = aIn.ReaduInt16();
663 nXF = aIn.ReaduInt16();
664 nOpt = aIn.ReaduInt16();
666 if( nColFirst > rD.MaxCol() )
667 return;
669 if( nColLast > rD.MaxCol() )
670 nColLast = static_cast<sal_uInt16>(rD.MaxCol());
672 bool bHidden = ::get_flag( nOpt, EXC_COLINFO_HIDDEN );
673 bool bCollapsed = ::get_flag( nOpt, EXC_COLINFO_COLLAPSED );
674 sal_uInt8 nLevel = ::extract_value< sal_uInt8 >( nOpt, 8, 3 );
675 pColOutlineBuff->SetLevelRange( nColFirst, nColLast, nLevel, bCollapsed );
677 if( bHidden )
678 pColRowBuff->HideColRange( nColFirst, nColLast );
680 sal_uInt16 nScWidth = XclTools::GetScColumnWidth( nColWidth, GetCharWidth() );
681 pColRowBuff->SetWidthRange( nColFirst, nColLast, nScWidth );
682 pColRowBuff->SetDefaultXF( nColFirst, nColLast, nXF );
685 void ImportExcel::Wsbool()
687 sal_uInt16 nFlags;
688 nFlags = aIn.ReaduInt16();
690 pRowOutlineBuff->SetButtonMode( ::get_flag( nFlags, EXC_WSBOOL_ROWBELOW ) );
691 pColOutlineBuff->SetButtonMode( ::get_flag( nFlags, EXC_WSBOOL_COLBELOW ) );
693 GetPageSettings().SetFitToPages( ::get_flag( nFlags, EXC_WSBOOL_FITTOPAGE ) );
696 void ImportExcel::Boundsheet()
698 sal_uInt16 nGrbit = 0;
700 if( GetBiff() == EXC_BIFF5 )
702 aIn.DisableDecryption();
703 maSheetOffsets.push_back( aIn.ReaduInt32() );
704 aIn.EnableDecryption();
705 nGrbit = aIn.ReaduInt16();
708 OUString aName( aIn.ReadByteString( false ) );
710 SCTAB nScTab = nBdshtTab;
711 if( nScTab > 0 )
713 OSL_ENSURE( !rD.HasTable( nScTab ), "ImportExcel::Boundsheet - sheet exists already" );
714 rD.MakeTable( nScTab );
717 if( ( nGrbit & 0x0001 ) || ( nGrbit & 0x0002 ) )
718 rD.SetVisible( nScTab, false );
720 if( !rD.RenameTab( nScTab, aName ) )
722 rD.CreateValidTabName( aName );
723 rD.RenameTab( nScTab, aName );
726 nBdshtTab++;
729 void ImportExcel::Country()
731 sal_uInt16 nUICountry, nDocCountry;
732 nUICountry = maStrm.ReaduInt16();
733 nDocCountry = maStrm.ReaduInt16();
735 // Store system language in XclRoot
736 LanguageType eLanguage = ::msfilter::ConvertCountryToLanguage( static_cast< ::msfilter::CountryId >( nDocCountry ) );
737 if( eLanguage != LANGUAGE_DONTKNOW )
738 SetDocLanguage( eLanguage );
740 // Set Excel UI language in add-in name translator
741 eLanguage = ::msfilter::ConvertCountryToLanguage( static_cast< ::msfilter::CountryId >( nUICountry ) );
742 if( eLanguage != LANGUAGE_DONTKNOW )
743 SetUILanguage( eLanguage );
746 void ImportExcel::ReadUsesElfs()
748 if( maStrm.ReaduInt16() != 0 )
750 ScDocOptions aDocOpt = GetDoc().GetDocOptions();
751 aDocOpt.SetLookUpColRowNames( true );
752 GetDoc().SetDocOptions( aDocOpt );
756 void ImportExcel::Hideobj()
758 sal_uInt16 nHide;
759 ScVObjMode eOle, eChart, eDraw;
761 nHide = aIn.ReaduInt16();
763 ScViewOptions aOpts( rD.GetViewOptions() );
765 switch( nHide )
767 case 1: // Placeholders
768 eOle = VOBJ_MODE_SHOW; // in Excel 97 only charts as place holder are displayed
769 eChart = VOBJ_MODE_SHOW; //#i80528# VOBJ_MODE_DUMMY replaced by VOBJ_MODE_SHOW now
770 eDraw = VOBJ_MODE_SHOW;
771 break;
772 case 2: // Hide all
773 eOle = VOBJ_MODE_HIDE;
774 eChart = VOBJ_MODE_HIDE;
775 eDraw = VOBJ_MODE_HIDE;
776 break;
777 default: // Show all
778 eOle = VOBJ_MODE_SHOW;
779 eChart = VOBJ_MODE_SHOW;
780 eDraw = VOBJ_MODE_SHOW;
781 break;
784 aOpts.SetObjMode( VOBJ_TYPE_OLE, eOle );
785 aOpts.SetObjMode( VOBJ_TYPE_CHART, eChart );
786 aOpts.SetObjMode( VOBJ_TYPE_DRAW, eDraw );
788 rD.SetViewOptions( aOpts );
791 void ImportExcel::Standardwidth()
793 sal_uInt16 nScWidth = XclTools::GetScColumnWidth( maStrm.ReaduInt16(), GetCharWidth() );
794 if (!pColRowBuff)
796 SAL_WARN("sc", "*ImportExcel::Standardwidth(): pColRowBuff is NULL!");
797 return;
799 pColRowBuff->SetDefWidth( nScWidth, true );
802 void ImportExcel::Shrfmla()
804 switch (mnLastRecId)
806 case EXC_ID2_FORMULA:
807 case EXC_ID3_FORMULA:
808 case EXC_ID4_FORMULA:
809 // This record MUST immediately follow a FORMULA record.
810 break;
811 default:
812 return;
815 if (!mpLastFormula)
816 // The last FORMULA record should have left this data.
817 return;
819 aIn.Ignore( 8 );
820 sal_uInt16 nLenExpr = aIn.ReaduInt16();
822 // read mark is now on the formula
824 std::unique_ptr<ScTokenArray> pResult;
826 // The shared range in this record is erroneous more than half the time.
827 // Don't ever rely on it. Use the one from the formula cell above.
828 SCCOL nCol1 = mpLastFormula->mnCol;
829 SCROW nRow1 = mpLastFormula->mnRow;
831 ScAddress aPos(nCol1, nRow1, GetCurrScTab());
832 pFormConv->Reset(aPos);
833 pFormConv->Convert( pResult, maStrm, nLenExpr, true, FT_SharedFormula );
835 if (!pResult)
837 SAL_WARN("sc", "+ImportExcel::Shrfmla(): ScTokenArray is NULL!");
838 return;
841 pExcRoot->pShrfmlaBuff->Store(aPos, *pResult);
843 // Create formula cell for the last formula record.
845 ScDocumentImport& rDoc = GetDocImport();
847 ScFormulaCell* pCell = new ScFormulaCell(rD, aPos, std::move(pResult));
848 pCell->GetCode()->WrapReference(aPos, EXC_MAXCOL8, EXC_MAXROW8);
849 rDoc.getDoc().CheckLinkFormulaNeedingCheck( *pCell->GetCode());
850 rDoc.getDoc().EnsureTable(aPos.Tab());
851 rDoc.setFormulaCell(aPos, pCell);
852 pCell->SetNeedNumberFormat(false);
853 if (std::isfinite(mpLastFormula->mfValue))
854 pCell->SetResultDouble(mpLastFormula->mfValue);
856 GetXFRangeBuffer().SetXF(aPos, mpLastFormula->mnXF);
857 mpLastFormula->mpCell = pCell;
860 void ImportExcel::Mulrk()
862 /* rw (2 bytes): An Rw structure that specifies the row containing the
863 cells with numeric data.
865 colFirst (2 bytes): A Col structure that specifies the first column in
866 the series of numeric cells within the sheet. The value of colFirst.col
867 MUST be less than or equal to 254.
869 rgrkrec (variable): An array of RkRec structures. Each element in the
870 array specifies an RkRec in the row. The number of entries in the array
871 MUST be equal to the value given by the following formula:
873 Number of entries in rgrkrec = (colLast.col – colFirst.col +1)
875 colLast (2 bytes): A Col structure that specifies the last column in
876 the set of numeric cells within the sheet. This colLast.col value MUST
877 be greater than the colFirst.col value. */
879 XclAddress aXclPos;
880 aIn >> aXclPos;
882 XclAddress aCurrXclPos(aXclPos);
883 while (true)
885 if (aXclPos.mnCol > aCurrXclPos.mnCol)
886 break;
887 if (aIn.GetRecLeft() <= 2)
888 break;
890 sal_uInt16 nXF = aIn.ReaduInt16();
891 sal_Int32 nRkNum = aIn.ReadInt32();
893 ScAddress aScPos( ScAddress::UNINITIALIZED );
894 if( GetAddressConverter().ConvertAddress( aScPos, aCurrXclPos, GetCurrScTab(), true ) )
896 GetXFRangeBuffer().SetXF( aScPos, nXF );
897 GetDocImport().setNumericCell(aScPos, XclTools::GetDoubleFromRK(nRkNum));
899 ++aCurrXclPos.mnCol;
903 void ImportExcel::Mulblank()
905 /* rw (2 bytes): An Rw structure that specifies a row containing the blank
906 cells.
908 colFirst (2 bytes): A Col structure that specifies the first column in
909 the series of blank cells within the sheet. The value of colFirst.col
910 MUST be less than or equal to 254.
912 rgixfe (variable): An array of IXFCell structures. Each element of this
913 array contains an IXFCell structure corresponding to a blank cell in the
914 series. The number of entries in the array MUST be equal to the value
915 given by the following formula:
917 Number of entries in rgixfe = (colLast.col – colFirst.col +1)
919 colLast (2 bytes): A Col structure that specifies the last column in
920 the series of blank cells within the sheet. This colLast.col value MUST
921 be greater than colFirst.col value. */
923 XclAddress aXclPos;
924 aIn >> aXclPos;
926 XclAddress aCurrXclPos(aXclPos);
927 while (true)
929 if (aXclPos.mnCol > aCurrXclPos.mnCol)
930 break;
931 if (aIn.GetRecLeft() <= 2)
932 break;
934 sal_uInt16 nXF = aIn.ReaduInt16();
936 ScAddress aScPos( ScAddress::UNINITIALIZED );
937 if( GetAddressConverter().ConvertAddress( aScPos, aCurrXclPos, GetCurrScTab(), true ) )
938 GetXFRangeBuffer().SetBlankXF( aScPos, nXF );
939 ++aCurrXclPos.mnCol;
943 void ImportExcel::Rstring()
945 XclAddress aXclPos;
946 sal_uInt16 nXFIdx;
947 aIn >> aXclPos;
948 nXFIdx = aIn.ReaduInt16();
950 ScAddress aScPos( ScAddress::UNINITIALIZED );
951 if( !GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
952 return;
954 // unformatted Unicode string with separate formatting information
955 XclImpString aString;
956 aString.Read( maStrm );
958 // character formatting runs
959 if( !aString.IsRich() )
960 aString.ReadFormats( maStrm );
962 GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
963 XclImpStringHelper::SetToDocument(GetDocImport(), aScPos, *this, aString, nXFIdx);
966 void ImportExcel::Cellmerging()
968 XclImpAddressConverter& rAddrConv = GetAddressConverter();
969 SCTAB nScTab = GetCurrScTab();
971 sal_uInt16 nCount = maStrm.ReaduInt16();
972 sal_uInt16 nIdx = 0;
973 while (true)
975 if (maStrm.GetRecLeft() < 8)
976 break;
977 if (nIdx >= nCount)
978 break;
979 XclRange aXclRange;
980 maStrm >> aXclRange; // 16-bit rows and columns
981 ScRange aScRange( ScAddress::UNINITIALIZED );
982 if( rAddrConv.ConvertRange( aScRange, aXclRange, nScTab, nScTab, true ) )
983 GetXFRangeBuffer().SetMerge( aScRange.aStart.Col(), aScRange.aStart.Row(), aScRange.aEnd.Col(), aScRange.aEnd.Row() );
984 ++nIdx;
988 void ImportExcel::Olesize()
990 XclRange aXclOleSize( ScAddress::UNINITIALIZED );
991 maStrm.Ignore( 2 );
992 aXclOleSize.Read( maStrm, false );
994 SCTAB nScTab = GetCurrScTab();
995 GetAddressConverter().ConvertRange( maScOleSize, aXclOleSize, nScTab, nScTab, false );
998 void ImportExcel::Row34()
1000 sal_uInt16 nRow, nRowHeight, nGrbit, nXF;
1002 nRow = aIn.ReaduInt16();
1003 aIn.Ignore( 4 );
1005 SCROW nScRow = static_cast< SCROW >( nRow );
1007 if( !GetRoot().GetDoc().ValidRow( nScRow ) )
1008 return;
1010 nRowHeight = aIn.ReaduInt16(); // specify direct in Twips
1011 aIn.Ignore( 4 );
1013 nRowHeight = nRowHeight & 0x7FFF; // Bit 15: Row Height not changed manually
1014 if( !nRowHeight )
1015 nRowHeight = (GetBiff() == EXC_BIFF2) ? 0x25 : 0x225;
1017 nGrbit = aIn.ReaduInt16();
1018 nXF = aIn.ReaduInt16();
1020 sal_uInt8 nLevel = ::extract_value< sal_uInt8 >( nGrbit, 0, 3 );
1021 pRowOutlineBuff->SetLevel( nScRow, nLevel, ::get_flag( nGrbit, EXC_ROW_COLLAPSED ) );
1022 pColRowBuff->SetRowSettings( nScRow, nRowHeight, nGrbit );
1024 if( nGrbit & EXC_ROW_USEDEFXF )
1025 GetXFRangeBuffer().SetRowDefXF( nScRow, nXF & EXC_ROW_XFMASK );
1028 void ImportExcel::Bof3()
1030 sal_uInt16 nSubType;
1031 maStrm.DisableDecryption();
1032 maStrm.Ignore( 2 );
1033 nSubType = maStrm.ReaduInt16();
1035 OSL_ENSURE( nSubType != 0x0100, "*ImportExcel::Bof3(): Biff3 as Workbook?!" );
1036 if( nSubType == 0x0100 ) // Book
1037 pExcRoot->eDateiTyp = Biff3W;
1038 else if( nSubType == 0x0020 ) // Chart
1039 pExcRoot->eDateiTyp = Biff3C;
1040 else if( nSubType == 0x0040 ) // Macro
1041 pExcRoot->eDateiTyp = Biff3M;
1042 else // #i51490# Excel interprets invalid indexes as worksheet
1043 pExcRoot->eDateiTyp = Biff3;
1046 void ImportExcel::Array34()
1048 sal_uInt16 nFirstRow, nLastRow, nFormLen;
1049 sal_uInt8 nFirstCol, nLastCol;
1051 nFirstRow = aIn.ReaduInt16();
1052 nLastRow = aIn.ReaduInt16();
1053 nFirstCol = aIn.ReaduInt8();
1054 nLastCol = aIn.ReaduInt8();
1055 aIn.Ignore( (GetBiff() >= EXC_BIFF5) ? 6 : 2 );
1056 nFormLen = aIn.ReaduInt16();
1058 std::unique_ptr<ScTokenArray> pResult;
1060 if( GetRoot().GetDoc().ValidColRow( nLastCol, nLastRow ) )
1062 // the read mark is now on the formula, length in nFormLen
1064 pFormConv->Reset( ScAddress( static_cast<SCCOL>(nFirstCol),
1065 static_cast<SCROW>(nFirstRow), GetCurrScTab() ) );
1066 pFormConv->Convert( pResult, maStrm, nFormLen, true );
1068 SAL_WARN_IF(!pResult, "sc", "+ImportExcel::Array34(): ScTokenArray is NULL!");
1071 if (pResult)
1073 ScDocumentImport& rDoc = GetDocImport();
1074 ScRange aArrayRange(nFirstCol, nFirstRow, GetCurrScTab(), nLastCol, nLastRow, GetCurrScTab());
1075 rDoc.setMatrixCells(aArrayRange, *pResult, formula::FormulaGrammar::GRAM_ENGLISH_XL_A1);
1079 void ImportExcel::Defrowheight345()
1081 sal_uInt16 nFlags, nDefHeight;
1082 nFlags = maStrm.ReaduInt16();
1083 nDefHeight = maStrm.ReaduInt16();
1085 if (!pColRowBuff)
1087 SAL_WARN("sc", "*ImportExcel::Defrowheight345(): pColRowBuff is NULL!");
1088 return;
1091 pColRowBuff->SetDefHeight( nDefHeight, nFlags );
1094 void ImportExcel::TableOp()
1096 sal_uInt16 nFirstRow = aIn.ReaduInt16();
1097 sal_uInt16 nLastRow = aIn.ReaduInt16();
1098 sal_uInt8 nFirstCol = aIn.ReaduInt8();
1099 sal_uInt8 nLastCol = aIn.ReaduInt8();
1100 sal_uInt16 nGrbit = aIn.ReaduInt16();
1101 sal_uInt16 nInpRow = aIn.ReaduInt16();
1102 sal_uInt16 nInpCol = aIn.ReaduInt16();
1103 sal_uInt16 nInpRow2 = aIn.ReaduInt16();
1104 sal_uInt16 nInpCol2 = aIn.ReaduInt16();
1106 if (utl::ConfigManager::IsFuzzing())
1108 //shrink to smallish arbitrary value to not timeout
1109 nLastRow = std::min<sal_uInt16>(nLastRow, MAXROW_30 / 2);
1112 if( GetRoot().GetDoc().ValidColRow( nLastCol, nLastRow ) )
1114 if( nFirstCol && nFirstRow )
1116 ScTabOpParam aTabOpParam;
1117 aTabOpParam.meMode = (nGrbit & EXC_TABLEOP_BOTH) ? ScTabOpParam::Both : ((nGrbit & EXC_TABLEOP_ROW) ? ScTabOpParam::Row : ScTabOpParam::Column);
1118 sal_uInt16 nCol = nFirstCol - 1;
1119 sal_uInt16 nRow = nFirstRow - 1;
1120 SCTAB nTab = GetCurrScTab();
1121 switch (aTabOpParam.meMode)
1123 case ScTabOpParam::Column:
1124 aTabOpParam.aRefFormulaCell.Set(
1125 static_cast<SCCOL>(nFirstCol),
1126 static_cast<SCROW>(nFirstRow - 1), nTab, false,
1127 false, false );
1128 aTabOpParam.aRefFormulaEnd.Set(
1129 static_cast<SCCOL>(nLastCol),
1130 static_cast<SCROW>(nFirstRow - 1), nTab, false,
1131 false, false );
1132 aTabOpParam.aRefColCell.Set( static_cast<SCCOL>(nInpCol),
1133 static_cast<SCROW>(nInpRow), nTab, false, false,
1134 false );
1135 nRow++;
1136 break;
1137 case ScTabOpParam::Row:
1138 aTabOpParam.aRefFormulaCell.Set(
1139 static_cast<SCCOL>(nFirstCol - 1),
1140 static_cast<SCROW>(nFirstRow), nTab, false, false,
1141 false );
1142 aTabOpParam.aRefFormulaEnd.Set(
1143 static_cast<SCCOL>(nFirstCol - 1),
1144 static_cast<SCROW>(nLastRow), nTab, false, false,
1145 false );
1146 aTabOpParam.aRefRowCell.Set( static_cast<SCCOL>(nInpCol),
1147 static_cast<SCROW>(nInpRow), nTab, false, false,
1148 false );
1149 nCol++;
1150 break;
1151 case ScTabOpParam::Both: // TWO-INPUT
1152 aTabOpParam.aRefFormulaCell.Set(
1153 static_cast<SCCOL>(nFirstCol - 1),
1154 static_cast<SCROW>(nFirstRow - 1), nTab, false,
1155 false, false );
1156 aTabOpParam.aRefRowCell.Set( static_cast<SCCOL>(nInpCol),
1157 static_cast<SCROW>(nInpRow), nTab, false, false,
1158 false );
1159 aTabOpParam.aRefColCell.Set( static_cast<SCCOL>(nInpCol2),
1160 static_cast<SCROW>(nInpRow2), nTab, false, false,
1161 false );
1162 break;
1165 ScDocumentImport& rDoc = GetDocImport();
1166 ScRange aTabOpRange(nCol, nRow, nTab, nLastCol, nLastRow, nTab);
1167 rDoc.setTableOpCells(aTabOpRange, aTabOpParam);
1170 else
1172 bTabTruncated = true;
1173 GetTracer().TraceInvalidRow(nLastRow, rD.MaxRow());
1177 void ImportExcel::Bof4()
1179 sal_uInt16 nSubType;
1180 maStrm.DisableDecryption();
1181 maStrm.Ignore( 2 );
1182 nSubType = maStrm.ReaduInt16();
1184 if( nSubType == 0x0100 ) // Book
1185 pExcRoot->eDateiTyp = Biff4W;
1186 else if( nSubType == 0x0020 ) // Chart
1187 pExcRoot->eDateiTyp = Biff4C;
1188 else if( nSubType == 0x0040 ) // Macro
1189 pExcRoot->eDateiTyp = Biff4M;
1190 else // #i51490# Excel interprets invalid indexes as worksheet
1191 pExcRoot->eDateiTyp = Biff4;
1194 void ImportExcel::Bof5()
1196 //POST: eDateiTyp = Type of the file to be read
1197 sal_uInt16 nSubType, nVers;
1198 BiffTyp eDatei;
1200 maStrm.DisableDecryption();
1201 nVers = maStrm.ReaduInt16();
1202 nSubType = maStrm.ReaduInt16( );
1204 switch( nSubType )
1206 case 0x0005: eDatei = Biff5W; break; // workbook globals
1207 case 0x0006: eDatei = Biff5V; break; // VB module
1208 case 0x0020: eDatei = Biff5C; break; // chart
1209 case 0x0040: eDatei = Biff5M4; break; // macro sheet
1210 case 0x0010: // worksheet
1211 default: eDatei = Biff5; break; // tdf#144732 Excel interprets invalid indexes as worksheet
1214 if( nVers == 0x0600 && (GetBiff() == EXC_BIFF8) )
1215 eDatei = static_cast<BiffTyp>( eDatei - Biff5 + Biff8 );
1217 pExcRoot->eDateiTyp = eDatei;
1220 void ImportExcel::EndSheet()
1222 pExcRoot->pExtSheetBuff->Reset();
1224 if( GetBiff() <= EXC_BIFF5 )
1226 pExcRoot->pExtNameBuff->Reset();
1227 mnLastRefIdx = 0;
1230 FinalizeTable();
1233 void ImportExcel::NewTable()
1235 SCTAB nTab = GetCurrScTab();
1236 if( nTab > 0 && !rD.HasTable( nTab ) )
1237 rD.MakeTable( nTab );
1239 if (nTab == 0 && GetBiff() == EXC_BIFF2)
1241 // For Excel 2.1 Worksheet file, we need to set the file name as the
1242 // sheet name.
1243 INetURLObject aURL(GetDocUrl());
1244 rD.RenameTab(0, aURL.getBase());
1247 pExcRoot->pShrfmlaBuff->Clear();
1248 maLastFormulaCells.clear();
1249 mpLastFormula = nullptr;
1251 InitializeTable( nTab );
1253 XclImpOutlineDataBuffer* pNewItem = new XclImpOutlineDataBuffer( GetRoot(), nTab );
1254 pOutlineListBuffer->push_back( std::unique_ptr<XclImpOutlineDataBuffer>(pNewItem) );
1255 pExcRoot->pColRowBuff = pColRowBuff = pNewItem->GetColRowBuff();
1256 pColOutlineBuff = pNewItem->GetColOutline();
1257 pRowOutlineBuff = pNewItem->GetRowOutline();
1260 std::unique_ptr<ScTokenArray> ImportExcel::ErrorToFormula( bool bErrOrVal, sal_uInt8 nError, double& rVal )
1262 return pFormConv->GetBoolErr( XclTools::ErrorToEnum( rVal, bErrOrVal, nError ) );
1265 void ImportExcel::AdjustRowHeight()
1267 /* Speed up chart import: import all sheets without charts, then
1268 update row heights (here), last load all charts -> do not any longer
1269 update inside of ScDocShell::ConvertFrom() (causes update of existing
1270 charts during each and every change of row height). */
1271 if( ScModelObj* pDocObj = GetDocModelObj() )
1272 pDocObj->UpdateAllRowHeights();
1275 void ImportExcel::PostDocLoad()
1277 /* Set automatic page numbering in Default page style (default is "page number = 1").
1278 Otherwise hidden tables (i.e. for scenarios) which have Default page style will
1279 break automatic page numbering. */
1280 if( SfxStyleSheetBase* pStyleSheet = GetStyleSheetPool().Find( ScResId( STR_STYLENAME_STANDARD ), SfxStyleFamily::Page ) )
1281 pStyleSheet->GetItemSet().Put( SfxUInt16Item( ATTR_PAGE_FIRSTPAGENO, 0 ) );
1283 // outlines for all sheets, sets hidden rows and columns (#i11776# after filtered ranges)
1284 for (auto& rxBuffer : *pOutlineListBuffer)
1285 rxBuffer->Convert();
1287 // document view settings (before visible OLE area)
1288 GetDocViewSettings().Finalize();
1290 // process all drawing objects (including OLE, charts, controls; after hiding rows/columns; before visible OLE area)
1291 GetObjectManager().ConvertObjects();
1293 // visible area (used if this document is an embedded OLE object)
1294 if( SfxObjectShell* pDocShell = GetDocShell() )
1296 // visible area if embedded
1297 const ScExtDocSettings& rDocSett = GetExtDocOptions().GetDocSettings();
1298 SCTAB nDisplScTab = rDocSett.mnDisplTab;
1300 /* #i44077# If a new OLE object is inserted from file, there is no
1301 OLESIZE record in the Excel file. Calculate used area from file
1302 contents (used cells and drawing objects). */
1303 if( !maScOleSize.IsValid() )
1305 // used area of displayed sheet (cell contents)
1306 if( const ScExtTabSettings* pTabSett = GetExtDocOptions().GetTabSettings( nDisplScTab ) )
1307 maScOleSize = pTabSett->maUsedArea;
1308 // add all valid drawing objects
1309 ScRange aScObjArea = GetObjectManager().GetUsedArea( nDisplScTab );
1310 if( aScObjArea.IsValid() )
1311 maScOleSize.ExtendTo( aScObjArea );
1314 // valid size found - set it at the document
1315 if( maScOleSize.IsValid() )
1317 pDocShell->SetVisArea( GetDoc().GetMMRect(
1318 maScOleSize.aStart.Col(), maScOleSize.aStart.Row(),
1319 maScOleSize.aEnd.Col(), maScOleSize.aEnd.Row(), nDisplScTab ) );
1320 GetDoc().SetVisibleTab( nDisplScTab );
1324 // open forms in alive mode (has no effect, if no controls in document)
1325 if( ScModelObj* pDocObj = GetDocModelObj() )
1326 pDocObj->setPropertyValue( SC_UNO_APPLYFMDES, uno::Any( false ) );
1328 // enables extended options to be set to the view after import
1329 GetExtDocOptions().SetChanged( true );
1331 // root data owns the extended document options -> create a new object
1332 GetDoc().SetExtDocOptions( std::make_unique<ScExtDocOptions>( GetExtDocOptions() ) );
1334 const SCTAB nLast = rD.GetTableCount();
1335 const ScRange* p;
1337 if( GetRoot().GetPrintAreaBuffer().HasRanges() )
1339 for( SCTAB n = 0 ; n < nLast ; n++ )
1341 p = GetRoot().GetPrintAreaBuffer().First(n);
1342 if( p )
1344 rD.ClearPrintRanges( n );
1345 while( p )
1347 rD.AddPrintRange( n, *p );
1348 p = GetRoot().GetPrintAreaBuffer().Next();
1351 else
1353 // #i4063# no print ranges -> print entire sheet
1354 rD.SetPrintEntireSheet( n );
1357 GetTracer().TracePrintRange();
1360 if( !GetRoot().GetTitleAreaBuffer().HasRanges() )
1361 return;
1363 for( SCTAB n = 0 ; n < nLast ; n++ )
1365 p = GetRoot().GetTitleAreaBuffer().First(n);
1366 if( p )
1368 bool bRowVirgin = true;
1369 bool bColVirgin = true;
1371 while( p )
1373 if( p->aStart.Col() == 0 && p->aEnd.Col() == rD.MaxCol() && bRowVirgin )
1375 rD.SetRepeatRowRange( n, std::unique_ptr<ScRange>(new ScRange(*p)) );
1376 bRowVirgin = false;
1379 if( p->aStart.Row() == 0 && p->aEnd.Row() == rD.MaxRow() && bColVirgin )
1381 rD.SetRepeatColRange( n, std::unique_ptr<ScRange>(new ScRange(*p)) );
1382 bColVirgin = false;
1385 p = GetRoot().GetTitleAreaBuffer().Next();
1391 XclImpOutlineDataBuffer::XclImpOutlineDataBuffer( const XclImpRoot& rRoot, SCTAB nScTab ) :
1392 XclImpRoot( rRoot ),
1393 mxColOutlineBuff( std::make_shared<XclImpOutlineBuffer>( rRoot.GetXclMaxPos().Col() + 1 ) ),
1394 mxRowOutlineBuff( std::make_shared<XclImpOutlineBuffer>( rRoot.GetXclMaxPos().Row() + 1 ) ),
1395 mxColRowBuff( std::make_shared<XclImpColRowSettings>( rRoot ) ),
1396 mnScTab( nScTab )
1400 XclImpOutlineDataBuffer::~XclImpOutlineDataBuffer()
1404 void XclImpOutlineDataBuffer::Convert()
1406 mxColOutlineBuff->SetOutlineArray( &GetDoc().GetOutlineTable( mnScTab, true )->GetColArray() );
1407 mxColOutlineBuff->MakeScOutline();
1409 mxRowOutlineBuff->SetOutlineArray( &GetDoc().GetOutlineTable( mnScTab, true )->GetRowArray() );
1410 mxRowOutlineBuff->MakeScOutline();
1412 mxColRowBuff->ConvertHiddenFlags( mnScTab );
1415 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */