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 .
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>
39 #include <formulacell.hxx>
40 #include <document.hxx>
41 #include <globstr.hrc>
42 #include <scresid.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>
62 #include <xiescher.hxx>
63 #include <xicontent.hxx>
65 #include <excform.hxx>
66 #include <documentimport.hxx>
72 using namespace ::com::sun::star
;
74 ImportTyp::ImportTyp(ScDocument
& rDoc
, rtl_TextEncoding eQ
)
81 ImportTyp::~ImportTyp()
85 ImportExcel::ImportExcel( XclImpRootData
& rImpData
, SvStream
& rStrm
):
86 ImportTyp( rImpData
.mrDoc
, rImpData
.meTextEnc
),
87 XclImpRoot( rImpData
),
88 maStrm( rStrm
, GetRoot() ),
90 maScOleSize( ScAddress::INITIALIZE_INVALID
),
91 pColOutlineBuff(nullptr),
92 pRowOutlineBuff(nullptr),
94 mpLastFormula(nullptr),
99 mbBiff2HasXfsValid(false)
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
);
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();
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());
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))
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;
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. */
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). */
209 nXFIdx
= mnIxfeIndex
;
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
);
220 nXFIdx
= aIn
.ReaduInt16();
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
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
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()
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()
286 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
287 if( GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
289 sal_uInt16 nXFIdx
= ReadXFIndex( aScPos
, true );
291 nValue
= maStrm
.ReaduInt16();
293 GetXFRangeBuffer().SetXF( aScPos
, nXFIdx
);
294 GetDocImport().setNumericCell(aScPos
, nValue
);
298 void ImportExcel::ReadNumber()
303 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
304 if( GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
306 sal_uInt16 nXFIdx
= ReadXFIndex( aScPos
, maStrm
.GetRecId() == EXC_ID2_NUMBER
);
308 fValue
= maStrm
.ReadDouble();
310 GetXFRangeBuffer().SetXF( aScPos
, nXFIdx
);
311 GetDocImport().setNumericCell(aScPos
, fValue
);
315 void ImportExcel::ReadLabel()
320 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
321 if( !GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
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()
350 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
351 if( !GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
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
);
362 GetXFRangeBuffer().SetXF( aScPos
, nXFIdx
);
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()
378 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
379 if( GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
381 sal_uInt16 nXFIdx
= ReadXFIndex( aScPos
, false );
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();
402 if( !GetRoot().GetDoc().ValidRow( nRow
) )
405 nRowHeight
= aIn
.ReaduInt16(); // specify direct in Twips
408 if( GetBiff() == EXC_BIFF2
)
409 {// -------------------- BIFF2
410 pColRowBuff
->SetHeight( nRow
, nRowHeight
);
413 {// -------------------- BIFF5
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()
428 maStrm
.DisableDecryption();
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!
447 void ImportExcel::SheetPassword()
449 if (GetRoot().GetBiff() != EXC_BIFF8
)
452 GetRoot().GetSheetProtectBuffer().ReadPasswordHash( aIn
, GetCurrScTab() );
455 void ImportExcel::Externsheet()
457 OUString aUrl
, aTabName
;
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
)
469 GetRoot().GetDocProtectBuffer().ReadWinProtect( aIn
);
472 void ImportExcel::Columndefault()
473 {// Default Cell Attributes
474 sal_uInt16 nColMic
, nColMac
;
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" );
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()
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
)
509 nFormLen
= aIn
.ReaduInt8();
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!");
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()
542 n1904
= aIn
.ReaduInt16();
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()
558 nOpt
= aIn
.ReaduInt16();
559 nRes
= aIn
.ReaduInt32();
561 aIn
.ReadByteString( false ); // name
563 if( ( nOpt
& 0x0001 ) || ( ( nOpt
& 0xFFFE ) == 0x0000 ) )
565 pExcRoot
->pExtNameBuff
->AddName( mnLastRefIdx
);
567 else if( nOpt
& 0x0010 )
569 pExcRoot
->pExtNameBuff
->AddOLE( mnLastRefIdx
, nRes
); // nRes is storage ID
573 pExcRoot
->pExtNameBuff
->AddDDE( mnLastRefIdx
);
577 void ImportExcel::Colwidth()
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
)
607 GetRoot().GetSheetProtectBuffer().ReadProtect( aIn
, GetCurrScTab() );
610 void ImportExcel::DocProtect()
612 if (GetRoot().GetBiff() != EXC_BIFF8
)
615 GetRoot().GetDocProtectBuffer().ReadDocProtect( aIn
);
618 void ImportExcel::DocPassword()
620 if (GetRoot().GetBiff() != EXC_BIFF8
)
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();
643 SAL_WARN("sc", "*ImportExcel::DefColWidth(): pColRowBuff is NULL!");
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
;
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() )
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
);
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()
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
;
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
);
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()
759 ScVObjMode eOle
, eChart
, eDraw
;
761 nHide
= aIn
.ReaduInt16();
763 ScViewOptions
aOpts( rD
.GetViewOptions() );
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
;
773 eOle
= VOBJ_MODE_HIDE
;
774 eChart
= VOBJ_MODE_HIDE
;
775 eDraw
= VOBJ_MODE_HIDE
;
778 eOle
= VOBJ_MODE_SHOW
;
779 eChart
= VOBJ_MODE_SHOW
;
780 eDraw
= VOBJ_MODE_SHOW
;
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() );
796 SAL_WARN("sc", "*ImportExcel::Standardwidth(): pColRowBuff is NULL!");
799 pColRowBuff
->SetDefWidth( nScWidth
, true );
802 void ImportExcel::Shrfmla()
806 case EXC_ID2_FORMULA
:
807 case EXC_ID3_FORMULA
:
808 case EXC_ID4_FORMULA
:
809 // This record MUST immediately follow a FORMULA record.
816 // The last FORMULA record should have left this data.
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
);
837 SAL_WARN("sc", "+ImportExcel::Shrfmla(): ScTokenArray is NULL!");
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. */
882 XclAddress
aCurrXclPos(aXclPos
);
885 if (aXclPos
.mnCol
> aCurrXclPos
.mnCol
)
887 if (aIn
.GetRecLeft() <= 2)
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
));
903 void ImportExcel::Mulblank()
905 /* rw (2 bytes): An Rw structure that specifies a row containing the blank
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. */
926 XclAddress
aCurrXclPos(aXclPos
);
929 if (aXclPos
.mnCol
> aCurrXclPos
.mnCol
)
931 if (aIn
.GetRecLeft() <= 2)
934 sal_uInt16 nXF
= aIn
.ReaduInt16();
936 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
937 if( GetAddressConverter().ConvertAddress( aScPos
, aCurrXclPos
, GetCurrScTab(), true ) )
938 GetXFRangeBuffer().SetBlankXF( aScPos
, nXF
);
943 void ImportExcel::Rstring()
948 nXFIdx
= aIn
.ReaduInt16();
950 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
951 if( !GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
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();
975 if (maStrm
.GetRecLeft() < 8)
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() );
988 void ImportExcel::Olesize()
990 XclRange
aXclOleSize( ScAddress::UNINITIALIZED
);
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();
1005 SCROW nScRow
= static_cast< SCROW
>( nRow
);
1007 if( !GetRoot().GetDoc().ValidRow( nScRow
) )
1010 nRowHeight
= aIn
.ReaduInt16(); // specify direct in Twips
1013 nRowHeight
= nRowHeight
& 0x7FFF; // Bit 15: Row Height not changed manually
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();
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!");
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();
1087 SAL_WARN("sc", "*ImportExcel::Defrowheight345(): pColRowBuff is NULL!");
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,
1128 aTabOpParam
.aRefFormulaEnd
.Set(
1129 static_cast<SCCOL
>(nLastCol
),
1130 static_cast<SCROW
>(nFirstRow
- 1), nTab
, false,
1132 aTabOpParam
.aRefColCell
.Set( static_cast<SCCOL
>(nInpCol
),
1133 static_cast<SCROW
>(nInpRow
), nTab
, false, false,
1137 case ScTabOpParam::Row
:
1138 aTabOpParam
.aRefFormulaCell
.Set(
1139 static_cast<SCCOL
>(nFirstCol
- 1),
1140 static_cast<SCROW
>(nFirstRow
), nTab
, false, false,
1142 aTabOpParam
.aRefFormulaEnd
.Set(
1143 static_cast<SCCOL
>(nFirstCol
- 1),
1144 static_cast<SCROW
>(nLastRow
), nTab
, false, false,
1146 aTabOpParam
.aRefRowCell
.Set( static_cast<SCCOL
>(nInpCol
),
1147 static_cast<SCROW
>(nInpRow
), nTab
, false, false,
1151 case ScTabOpParam::Both
: // TWO-INPUT
1152 aTabOpParam
.aRefFormulaCell
.Set(
1153 static_cast<SCCOL
>(nFirstCol
- 1),
1154 static_cast<SCROW
>(nFirstRow
- 1), nTab
, false,
1156 aTabOpParam
.aRefRowCell
.Set( static_cast<SCCOL
>(nInpCol
),
1157 static_cast<SCROW
>(nInpRow
), nTab
, false, false,
1159 aTabOpParam
.aRefColCell
.Set( static_cast<SCCOL
>(nInpCol2
),
1160 static_cast<SCROW
>(nInpRow2
), nTab
, false, false,
1165 ScDocumentImport
& rDoc
= GetDocImport();
1166 ScRange
aTabOpRange(nCol
, nRow
, nTab
, nLastCol
, nLastRow
, nTab
);
1167 rDoc
.setTableOpCells(aTabOpRange
, aTabOpParam
);
1172 bTabTruncated
= true;
1173 GetTracer().TraceInvalidRow(nLastRow
, rD
.MaxRow());
1177 void ImportExcel::Bof4()
1179 sal_uInt16 nSubType
;
1180 maStrm
.DisableDecryption();
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
;
1200 maStrm
.DisableDecryption();
1201 nVers
= maStrm
.ReaduInt16();
1202 nSubType
= maStrm
.ReaduInt16( );
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();
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
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();
1337 if( GetRoot().GetPrintAreaBuffer().HasRanges() )
1339 for( SCTAB n
= 0 ; n
< nLast
; n
++ )
1341 p
= GetRoot().GetPrintAreaBuffer().First(n
);
1344 rD
.ClearPrintRanges( n
);
1347 rD
.AddPrintRange( n
, *p
);
1348 p
= GetRoot().GetPrintAreaBuffer().Next();
1353 // #i4063# no print ranges -> print entire sheet
1354 rD
.SetPrintEntireSheet( n
);
1357 GetTracer().TracePrintRange();
1360 if( !GetRoot().GetTitleAreaBuffer().HasRanges() )
1363 for( SCTAB n
= 0 ; n
< nLast
; n
++ )
1365 p
= GetRoot().GetTitleAreaBuffer().First(n
);
1368 bool bRowVirgin
= true;
1369 bool bColVirgin
= true;
1373 if( p
->aStart
.Col() == 0 && p
->aEnd
.Col() == rD
.MaxCol() && bRowVirgin
)
1375 rD
.SetRepeatRowRange( n
, std::unique_ptr
<ScRange
>(new ScRange(*p
)) );
1379 if( p
->aStart
.Row() == 0 && p
->aEnd
.Row() == rD
.MaxRow() && bColVirgin
)
1381 rD
.SetRepeatColRange( n
, std::unique_ptr
<ScRange
>(new ScRange(*p
)) );
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
) ),
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: */