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 <sfx2/docfile.hxx>
28 #include <svx/svxids.hrc>
29 #include <svl/zforlist.hxx>
30 #include <unotools/configmgr.hxx>
31 #include <sal/log.hxx>
33 #include <sfx2/objsh.hxx>
34 #include <tools/urlobj.hxx>
37 #include <formulacell.hxx>
38 #include <document.hxx>
39 #include <globstr.hrc>
40 #include <scresid.hxx>
42 #include <olinetab.hxx>
43 #include <stlpool.hxx>
44 #include <viewopti.hxx>
45 #include <docoptio.hxx>
46 #include <scextopt.hxx>
47 #include <unonames.hxx>
48 #include <paramisc.hxx>
49 #include <colrowst.hxx>
50 #include <otlnbuff.hxx>
51 #include <xistyle.hxx>
53 #include <namebuff.hxx>
54 #include <xltools.hxx>
55 #include <xltable.hxx>
56 #include <xltracer.hxx>
57 #include <xihelper.hxx>
60 #include <xiescher.hxx>
61 #include <xicontent.hxx>
63 #include <excform.hxx>
64 #include <documentimport.hxx>
70 using namespace ::com::sun::star
;
72 const double ImportExcel::fExcToTwips
= TWIPS_PER_CHAR
/ 256.0;
74 ImportTyp::ImportTyp( ScDocument
* pDoc
, rtl_TextEncoding eQ
)
80 ImportTyp::~ImportTyp()
84 ImportExcel::ImportExcel( XclImpRootData
& rImpData
, SvStream
& rStrm
):
85 ImportTyp( &rImpData
.mrDoc
, rImpData
.meTextEnc
),
86 XclImpRoot( rImpData
),
87 maStrm( rStrm
, GetRoot() ),
89 maScOleSize( ScAddress::INITIALIZE_INVALID
),
90 pColOutlineBuff(nullptr),
91 pRowOutlineBuff(nullptr),
93 mpLastFormula(nullptr),
98 mbBiff2HasXfsValid(false)
102 // fill in root data - after new's without root as parameter
103 pExcRoot
= &GetOldRoot();
104 pExcRoot
->pIR
= this; // ExcRoot -> XclImpRoot
105 pExcRoot
->eDateiTyp
= BiffX
;
106 pExcRoot
->pExtSheetBuff
.reset( new ExtSheetBuffer( pExcRoot
) ); //&aExtSheetBuff;
107 pExcRoot
->pShrfmlaBuff
.reset( new SharedFormulaBuffer( pExcRoot
) ); //&aShrfrmlaBuff;
108 pExcRoot
->pExtNameBuff
.reset( new ExtNameBuff ( *this ) );
110 pOutlineListBuffer
.reset(new XclImpOutlineListBuffer
);
113 pFormConv
.reset(new ExcelToSc( GetRoot() ));
114 pExcRoot
->pFmlaConverter
= pFormConv
.get();
116 bTabTruncated
= false;
118 // Excel document per Default on 31.12.1899, accords to Excel settings with 1.1.1900
119 ScDocOptions aOpt
= pD
->GetDocOptions();
120 aOpt
.SetDate( 30, 12, 1899 );
121 pD
->SetDocOptions( aOpt
);
122 pD
->GetFormatTable()->ChangeNullDate( 30, 12, 1899 );
124 ScDocOptions
aDocOpt( pD
->GetDocOptions() );
125 aDocOpt
.SetIgnoreCase( true ); // always in Excel
126 aDocOpt
.SetFormulaRegexEnabled( false ); // regular expressions? what's that?
127 aDocOpt
.SetFormulaWildcardsEnabled( true ); // Excel uses wildcard expressions
128 aDocOpt
.SetLookUpColRowNames( false ); // default: no natural language refs
129 pD
->SetDocOptions( aDocOpt
);
132 ImportExcel::~ImportExcel()
134 GetDoc().SetSrcCharSet( GetTextEncoding() );
136 pOutlineListBuffer
.reset();
141 void ImportExcel::SetLastFormula( SCCOL nCol
, SCROW nRow
, double fVal
, sal_uInt16 nXF
, ScFormulaCell
* pCell
)
143 LastFormulaMapType::iterator it
= maLastFormulaCells
.find(nCol
);
144 if (it
== maLastFormulaCells
.end())
146 std::pair
<LastFormulaMapType::iterator
, bool> r
=
147 maLastFormulaCells
.emplace(nCol
, LastFormula());
151 it
->second
.mnCol
= nCol
;
152 it
->second
.mnRow
= nRow
;
153 it
->second
.mpCell
= pCell
;
154 it
->second
.mfValue
= fVal
;
155 it
->second
.mnXF
= nXF
;
157 mpLastFormula
= &it
->second
;
160 void ImportExcel::ReadFileSharing()
162 sal_uInt16 nRecommendReadOnly
, nPasswordHash
;
163 nRecommendReadOnly
= maStrm
.ReaduInt16();
164 nPasswordHash
= maStrm
.ReaduInt16();
166 if( (nRecommendReadOnly
!= 0) || (nPasswordHash
!= 0) )
168 if( SfxItemSet
* pItemSet
= GetMedium().GetItemSet() )
169 pItemSet
->Put( SfxBoolItem( SID_DOC_READONLY
, true ) );
171 if( SfxObjectShell
* pShell
= GetDocShell() )
173 if( nRecommendReadOnly
!= 0 )
174 pShell
->SetLoadReadonly( true );
175 if( nPasswordHash
!= 0 )
176 pShell
->SetModifyPasswordHash( nPasswordHash
);
181 sal_uInt16
ImportExcel::ReadXFIndex( const ScAddress
& rScPos
, bool bBiff2
)
183 sal_uInt16 nXFIdx
= 0;
186 /* #i71453# On first call, check if the file contains XF records (by
187 trying to access the first XF with index 0). If there are no XFs,
188 the explicit formatting information contained in each cell record
189 will be used instead. */
190 if( !mbBiff2HasXfsValid
)
192 mbBiff2HasXfsValid
= true;
193 mbBiff2HasXfs
= GetXFBuffer().GetXF( 0 ) != nullptr;
195 // read formatting information (includes the XF identifier)
196 sal_uInt8 nFlags1
, nFlags2
, nFlags3
;
197 nFlags1
= maStrm
.ReaduInt8();
198 nFlags2
= maStrm
.ReaduInt8();
199 nFlags3
= maStrm
.ReaduInt8();
200 /* If the file contains XFs, extract and set the XF identifier,
201 otherwise get the explicit formatting. */
204 nXFIdx
= ::extract_value
< sal_uInt16
>( nFlags1
, 0, 6 );
205 /* If the identifier is equal to 63, then the real identifier is
206 contained in the preceding IXFE record (stored in mnBiff2XfId). */
208 nXFIdx
= mnIxfeIndex
;
212 /* Let the XclImpXF class do the conversion of the imported
213 formatting. The XF buffer is empty, therefore will not do any
214 conversion based on the XF index later on. */
215 XclImpXF::ApplyPatternForBiff2CellFormat( GetRoot(), rScPos
, nFlags1
, nFlags2
, nFlags3
);
219 nXFIdx
= aIn
.ReaduInt16();
223 void ImportExcel::ReadDimensions()
225 XclRange aXclUsedArea
;
226 if( (maStrm
.GetRecId() == EXC_ID2_DIMENSIONS
) || (GetBiff() <= EXC_BIFF5
) )
228 maStrm
>> aXclUsedArea
;
229 if( (aXclUsedArea
.GetColCount() > 1) && (aXclUsedArea
.GetRowCount() > 1) )
231 // Excel stores first unused row/column index
232 --aXclUsedArea
.maLast
.mnCol
;
233 --aXclUsedArea
.maLast
.mnRow
;
234 // create the Calc range
235 SCTAB nScTab
= GetCurrScTab();
236 ScRange
& rScUsedArea
= GetExtDocOptions().GetOrCreateTabSettings( nScTab
).maUsedArea
;
237 GetAddressConverter().ConvertRange( rScUsedArea
, aXclUsedArea
, nScTab
, nScTab
, false );
238 // if any error occurs in ConvertRange(), rScUsedArea keeps untouched
243 sal_uInt32 nXclRow1
= 0, nXclRow2
= 0;
244 nXclRow1
= maStrm
.ReaduInt32();
245 nXclRow2
= maStrm
.ReaduInt32();
246 aXclUsedArea
.maFirst
.mnCol
= maStrm
.ReaduInt16();
247 aXclUsedArea
.maLast
.mnCol
= maStrm
.ReaduInt16();
248 if( (nXclRow1
< nXclRow2
) && (aXclUsedArea
.GetColCount() > 1) &&
249 (nXclRow1
<= static_cast< sal_uInt32
>( GetScMaxPos().Row() )) )
251 // Excel stores first unused row/column index
253 --aXclUsedArea
.maLast
.mnCol
;
254 // convert row indexes to 16-bit values
255 aXclUsedArea
.maFirst
.mnRow
= static_cast< sal_uInt16
>( nXclRow1
);
256 aXclUsedArea
.maLast
.mnRow
= limit_cast
< sal_uInt16
>( nXclRow2
, aXclUsedArea
.maFirst
.mnRow
, SAL_MAX_UINT16
);
257 // create the Calc range
258 SCTAB nScTab
= GetCurrScTab();
259 ScRange
& rScUsedArea
= GetExtDocOptions().GetOrCreateTabSettings( nScTab
).maUsedArea
;
260 GetAddressConverter().ConvertRange( rScUsedArea
, aXclUsedArea
, nScTab
, nScTab
, false );
261 // if any error occurs in ConvertRange(), rScUsedArea keeps untouched
266 void ImportExcel::ReadBlank()
271 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
272 if( GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
274 sal_uInt16 nXFIdx
= ReadXFIndex( aScPos
, maStrm
.GetRecId() == EXC_ID2_BLANK
);
276 GetXFRangeBuffer().SetBlankXF( aScPos
, nXFIdx
);
280 void ImportExcel::ReadInteger()
285 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
286 if( GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
288 sal_uInt16 nXFIdx
= ReadXFIndex( aScPos
, true );
290 nValue
= maStrm
.ReaduInt16();
292 GetXFRangeBuffer().SetXF( aScPos
, nXFIdx
);
293 GetDocImport().setNumericCell(aScPos
, nValue
);
297 void ImportExcel::ReadNumber()
302 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
303 if( GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
305 sal_uInt16 nXFIdx
= ReadXFIndex( aScPos
, maStrm
.GetRecId() == EXC_ID2_NUMBER
);
307 fValue
= maStrm
.ReadDouble();
309 GetXFRangeBuffer().SetXF( aScPos
, nXFIdx
);
310 GetDocImport().setNumericCell(aScPos
, fValue
);
314 void ImportExcel::ReadLabel()
319 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
320 if( GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
322 /* Record ID BIFF XF type String type
323 0x0004 2-7 3 byte 8-bit length, byte string
324 0x0004 8 3 byte 16-bit length, unicode string
325 0x0204 2-7 2 byte 16-bit length, byte string
326 0x0204 8 2 byte 16-bit length, unicode string */
327 bool bBiff2
= maStrm
.GetRecId() == EXC_ID2_LABEL
;
328 sal_uInt16 nXFIdx
= ReadXFIndex( aScPos
, bBiff2
);
329 XclStrFlags nFlags
= (bBiff2
&& (GetBiff() <= EXC_BIFF5
)) ? XclStrFlags::EightBitLength
: XclStrFlags::NONE
;
330 XclImpString aString
;
332 // #i63105# use text encoding from FONT record
333 rtl_TextEncoding eOldTextEnc
= GetTextEncoding();
334 if( const XclImpFont
* pFont
= GetXFBuffer().GetFont( nXFIdx
) )
335 SetTextEncoding( pFont
->GetFontEncoding() );
336 aString
.Read( maStrm
, nFlags
);
337 SetTextEncoding( eOldTextEnc
);
339 GetXFRangeBuffer().SetXF( aScPos
, nXFIdx
);
340 XclImpStringHelper::SetToDocument(GetDocImport(), aScPos
, GetRoot(), aString
, nXFIdx
);
344 void ImportExcel::ReadBoolErr()
349 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
350 if( GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
352 sal_uInt16 nXFIdx
= ReadXFIndex( aScPos
, maStrm
.GetRecId() == EXC_ID2_BOOLERR
);
353 sal_uInt8 nValue
, nType
;
354 nValue
= maStrm
.ReaduInt8();
355 nType
= maStrm
.ReaduInt8();
357 if( nType
== EXC_BOOLERR_BOOL
)
358 GetXFRangeBuffer().SetBoolXF( aScPos
, nXFIdx
);
360 GetXFRangeBuffer().SetXF( aScPos
, nXFIdx
);
363 std::unique_ptr
<ScTokenArray
> pScTokArr
= ErrorToFormula( nType
!= EXC_BOOLERR_BOOL
, nValue
, fValue
);
364 ScFormulaCell
* pCell
= pScTokArr
365 ? new ScFormulaCell(pD
, aScPos
, std::move(pScTokArr
))
366 : new ScFormulaCell(pD
, aScPos
);
367 pCell
->SetHybridDouble( fValue
);
368 GetDocImport().setFormulaCell(aScPos
, pCell
);
372 void ImportExcel::ReadRk()
377 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
378 if( GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
380 sal_uInt16 nXFIdx
= ReadXFIndex( aScPos
, false );
382 nRk
= maStrm
.ReadInt32();
384 GetXFRangeBuffer().SetXF( aScPos
, nXFIdx
);
385 GetDocImport().setNumericCell(aScPos
, XclTools::GetDoubleFromRK(nRk
));
389 void ImportExcel::Window1()
391 GetDocViewSettings().ReadWindow1( maStrm
);
394 void ImportExcel::Row25()
396 sal_uInt16 nRow
, nRowHeight
;
398 nRow
= aIn
.ReaduInt16();
401 if( ValidRow( nRow
) )
403 nRowHeight
= aIn
.ReaduInt16(); // specify direct in Twips
406 if( GetBiff() == EXC_BIFF2
)
407 {// -------------------- BIFF2
408 pColRowBuff
->SetHeight( nRow
, nRowHeight
);
411 {// -------------------- BIFF5
414 aIn
.Ignore( 2 ); // reserved
415 nGrbit
= aIn
.ReaduInt16();
417 sal_uInt8 nLevel
= ::extract_value
< sal_uInt8
>( nGrbit
, 0, 3 );
418 pRowOutlineBuff
->SetLevel( nRow
, nLevel
, ::get_flag( nGrbit
, EXC_ROW_COLLAPSED
) );
419 pColRowBuff
->SetRowSettings( nRow
, nRowHeight
, nGrbit
);
424 void ImportExcel::Bof2()
427 maStrm
.DisableDecryption();
429 nSubType
= maStrm
.ReaduInt16();
431 if( nSubType
== 0x0020 ) // Chart
432 pExcRoot
->eDateiTyp
= Biff2C
;
433 else if( nSubType
== 0x0040 ) // Macro
434 pExcRoot
->eDateiTyp
= Biff2M
;
435 else // #i51490# Excel interprets invalid indexes as worksheet
436 pExcRoot
->eDateiTyp
= Biff2
;
439 void ImportExcel::Eof()
441 // POST: cannot be called after an invalid table!
446 void ImportExcel::SheetPassword()
448 if (GetRoot().GetBiff() != EXC_BIFF8
)
451 GetRoot().GetSheetProtectBuffer().ReadPasswordHash( aIn
, GetCurrScTab() );
454 void ImportExcel::Externsheet()
456 OUString aUrl
, aTabName
;
458 OUString
aEncodedUrl( aIn
.ReadByteString( false ) );
459 XclImpUrlHelper::DecodeUrl( aUrl
, aTabName
, bSameWorkBook
, *pExcRoot
->pIR
, aEncodedUrl
);
460 mnLastRefIdx
= pExcRoot
->pExtSheetBuff
->Add( aUrl
, aTabName
, bSameWorkBook
);
463 void ImportExcel:: WinProtection()
465 if (GetRoot().GetBiff() != EXC_BIFF8
)
468 GetRoot().GetDocProtectBuffer().ReadWinProtect( aIn
);
471 void ImportExcel::Columndefault()
472 {// Default Cell Attributes
473 sal_uInt16 nColMic
, nColMac
;
476 nColMic
= aIn
.ReaduInt16();
477 nColMac
= aIn
.ReaduInt16();
479 OSL_ENSURE( aIn
.GetRecLeft() == static_cast<std::size_t>(nColMac
- nColMic
) * 3 + 2,
480 "ImportExcel::Columndefault - wrong record size" );
484 if( nColMac
> pD
->MaxCol() )
485 nColMac
= static_cast<sal_uInt16
>(pD
->MaxCol());
487 for( sal_uInt16 nCol
= nColMic
; nCol
<= nColMac
; nCol
++ )
489 nOpt0
= aIn
.ReaduInt8();
490 aIn
.Ignore( 2 ); // only 0. Attribut-Byte used
492 if( nOpt0
& 0x80 ) // Col hidden?
493 pColRowBuff
->HideCol( nCol
);
497 void ImportExcel::Array25()
500 sal_uInt16 nFirstRow
= aIn
.ReaduInt16();
501 sal_uInt16 nLastRow
= aIn
.ReaduInt16();
502 sal_uInt8 nFirstCol
= aIn
.ReaduInt8();
503 sal_uInt8 nLastCol
= aIn
.ReaduInt8();
505 if( GetBiff() == EXC_BIFF2
)
508 nFormLen
= aIn
.ReaduInt8();
513 nFormLen
= aIn
.ReaduInt16();
516 std::unique_ptr
<ScTokenArray
> pResult
;
518 if (ValidColRow(nLastCol
, nLastRow
))
520 // the read mark is now on the formula, length in nFormLen
522 pFormConv
->Reset( ScAddress( static_cast<SCCOL
>(nFirstCol
),
523 static_cast<SCROW
>(nFirstRow
), GetCurrScTab() ) );
524 pFormConv
->Convert(pResult
, maStrm
, nFormLen
, true);
526 SAL_WARN_IF(!pResult
, "sc", "*ImportExcel::Array25(): ScTokenArray is NULL!");
531 ScDocumentImport
& rDoc
= GetDocImport();
532 ScRange
aArrayRange(nFirstCol
, nFirstRow
, GetCurrScTab(), nLastCol
, nLastRow
, GetCurrScTab());
533 rDoc
.setMatrixCells(aArrayRange
, *pResult
, formula::FormulaGrammar::GRAM_ENGLISH_XL_A1
);
537 void ImportExcel::Rec1904()
541 n1904
= aIn
.ReaduInt16();
545 ScDocOptions aOpt
= pD
->GetDocOptions();
546 aOpt
.SetDate( 1, 1, 1904 );
547 pD
->SetDocOptions( aOpt
);
548 pD
->GetFormatTable()->ChangeNullDate( 1, 1, 1904 );
552 void ImportExcel::Externname25()
557 nOpt
= aIn
.ReaduInt16();
558 nRes
= aIn
.ReaduInt32();
560 aIn
.ReadByteString( false ); // name
562 if( ( nOpt
& 0x0001 ) || ( ( nOpt
& 0xFFFE ) == 0x0000 ) )
564 pExcRoot
->pExtNameBuff
->AddName( mnLastRefIdx
);
566 else if( nOpt
& 0x0010 )
568 pExcRoot
->pExtNameBuff
->AddOLE( mnLastRefIdx
, nRes
); // nRes is storage ID
572 pExcRoot
->pExtNameBuff
->AddDDE( mnLastRefIdx
);
576 void ImportExcel::Colwidth()
578 sal_uInt8 nColFirst
, nColLast
;
579 sal_uInt16 nColWidth
;
581 nColFirst
= aIn
.ReaduInt8();
582 nColLast
= aIn
.ReaduInt8();
583 nColWidth
= aIn
.ReaduInt16();
585 //TODO: add a check for the unlikely case of changed MAXCOL (-> XclImpAddressConverter)
586 // if( nColLast > pD->MaxCol() )
587 // nColLast = static_cast<sal_uInt16>(pD->MaxCol());
589 sal_uInt16 nScWidth
= XclTools::GetScColumnWidth( nColWidth
, GetCharWidth() );
590 pColRowBuff
->SetWidthRange( nColFirst
, nColLast
, nScWidth
);
593 void ImportExcel::Defrowheight2()
595 sal_uInt16 nDefHeight
;
596 nDefHeight
= maStrm
.ReaduInt16();
597 nDefHeight
&= 0x7FFF;
598 pColRowBuff
->SetDefHeight( nDefHeight
, EXC_DEFROW_UNSYNCED
);
601 void ImportExcel::SheetProtect()
603 if (GetRoot().GetBiff() != EXC_BIFF8
)
606 GetRoot().GetSheetProtectBuffer().ReadProtect( aIn
, GetCurrScTab() );
609 void ImportExcel::DocProtect()
611 if (GetRoot().GetBiff() != EXC_BIFF8
)
614 GetRoot().GetDocProtectBuffer().ReadDocProtect( aIn
);
617 void ImportExcel::DocPasssword()
619 if (GetRoot().GetBiff() != EXC_BIFF8
)
622 GetRoot().GetDocProtectBuffer().ReadPasswordHash( aIn
);
625 void ImportExcel::Codepage()
627 SetCodePage( maStrm
.ReaduInt16() );
630 void ImportExcel::Ixfe()
632 mnIxfeIndex
= maStrm
.ReaduInt16();
635 void ImportExcel::DefColWidth()
637 // stored as entire characters -> convert to 1/256 of characters (as in COLINFO)
638 double fDefWidth
= 256.0 * maStrm
.ReaduInt16();
642 SAL_WARN("sc", "*ImportExcel::DefColWidth(): pColRowBuff is NULL!");
646 // #i3006# additional space for default width - Excel adds space depending on font size
647 long nFontHt
= GetFontBuffer().GetAppFontData().mnHeight
;
648 fDefWidth
+= XclTools::GetXclDefColWidthCorrection( nFontHt
);
650 sal_uInt16 nScWidth
= XclTools::GetScColumnWidth( limit_cast
< sal_uInt16
>( fDefWidth
), GetCharWidth() );
651 pColRowBuff
->SetDefWidth( nScWidth
);
654 void ImportExcel::Colinfo()
655 {// Column Formatting Information
656 sal_uInt16 nColFirst
, nColLast
, nColWidth
, nXF
;
659 nColFirst
= aIn
.ReaduInt16();
660 nColLast
= aIn
.ReaduInt16();
661 nColWidth
= aIn
.ReaduInt16();
662 nXF
= aIn
.ReaduInt16();
663 nOpt
= aIn
.ReaduInt16();
665 if( nColFirst
> pD
->MaxCol() )
668 if( nColLast
> pD
->MaxCol() )
669 nColLast
= static_cast<sal_uInt16
>(pD
->MaxCol());
671 bool bHidden
= ::get_flag( nOpt
, EXC_COLINFO_HIDDEN
);
672 bool bCollapsed
= ::get_flag( nOpt
, EXC_COLINFO_COLLAPSED
);
673 sal_uInt8 nLevel
= ::extract_value
< sal_uInt8
>( nOpt
, 8, 3 );
674 pColOutlineBuff
->SetLevelRange( nColFirst
, nColLast
, nLevel
, bCollapsed
);
677 pColRowBuff
->HideColRange( nColFirst
, nColLast
);
679 sal_uInt16 nScWidth
= XclTools::GetScColumnWidth( nColWidth
, GetCharWidth() );
680 pColRowBuff
->SetWidthRange( nColFirst
, nColLast
, nScWidth
);
681 pColRowBuff
->SetDefaultXF( nColFirst
, nColLast
, nXF
);
684 void ImportExcel::Wsbool()
687 nFlags
= aIn
.ReaduInt16();
689 pRowOutlineBuff
->SetButtonMode( ::get_flag( nFlags
, EXC_WSBOOL_ROWBELOW
) );
690 pColOutlineBuff
->SetButtonMode( ::get_flag( nFlags
, EXC_WSBOOL_COLBELOW
) );
692 GetPageSettings().SetFitToPages( ::get_flag( nFlags
, EXC_WSBOOL_FITTOPAGE
) );
695 void ImportExcel::Boundsheet()
697 sal_uInt16 nGrbit
= 0;
699 if( GetBiff() == EXC_BIFF5
)
701 aIn
.DisableDecryption();
702 maSheetOffsets
.push_back( aIn
.ReaduInt32() );
703 aIn
.EnableDecryption();
704 nGrbit
= aIn
.ReaduInt16();
707 OUString
aName( aIn
.ReadByteString( false ) );
709 SCTAB nScTab
= nBdshtTab
;
712 OSL_ENSURE( !pD
->HasTable( nScTab
), "ImportExcel::Boundsheet - sheet exists already" );
713 pD
->MakeTable( nScTab
);
716 if( ( nGrbit
& 0x0001 ) || ( nGrbit
& 0x0002 ) )
717 pD
->SetVisible( nScTab
, false );
719 if( !pD
->RenameTab( nScTab
, aName
) )
721 pD
->CreateValidTabName( aName
);
722 pD
->RenameTab( nScTab
, aName
);
728 void ImportExcel::Country()
730 sal_uInt16 nUICountry
, nDocCountry
;
731 nUICountry
= maStrm
.ReaduInt16();
732 nDocCountry
= maStrm
.ReaduInt16();
734 // Store system language in XclRoot
735 LanguageType eLanguage
= ::msfilter::ConvertCountryToLanguage( static_cast< ::msfilter::CountryId
>( nDocCountry
) );
736 if( eLanguage
!= LANGUAGE_DONTKNOW
)
737 SetDocLanguage( eLanguage
);
739 // Set Excel UI language in add-in name translator
740 eLanguage
= ::msfilter::ConvertCountryToLanguage( static_cast< ::msfilter::CountryId
>( nUICountry
) );
741 if( eLanguage
!= LANGUAGE_DONTKNOW
)
742 SetUILanguage( eLanguage
);
745 void ImportExcel::ReadUsesElfs()
747 if( maStrm
.ReaduInt16() != 0 )
749 ScDocOptions aDocOpt
= GetDoc().GetDocOptions();
750 aDocOpt
.SetLookUpColRowNames( true );
751 GetDoc().SetDocOptions( aDocOpt
);
755 void ImportExcel::Hideobj()
758 ScVObjMode eOle
, eChart
, eDraw
;
760 nHide
= aIn
.ReaduInt16();
762 ScViewOptions
aOpts( pD
->GetViewOptions() );
766 case 1: // Placeholders
767 eOle
= VOBJ_MODE_SHOW
; // in Excel 97 only charts as place holder are displayed
768 eChart
= VOBJ_MODE_SHOW
; //#i80528# VOBJ_MODE_DUMMY replaced by VOBJ_MODE_SHOW now
769 eDraw
= VOBJ_MODE_SHOW
;
772 eOle
= VOBJ_MODE_HIDE
;
773 eChart
= VOBJ_MODE_HIDE
;
774 eDraw
= VOBJ_MODE_HIDE
;
777 eOle
= VOBJ_MODE_SHOW
;
778 eChart
= VOBJ_MODE_SHOW
;
779 eDraw
= VOBJ_MODE_SHOW
;
783 aOpts
.SetObjMode( VOBJ_TYPE_OLE
, eOle
);
784 aOpts
.SetObjMode( VOBJ_TYPE_CHART
, eChart
);
785 aOpts
.SetObjMode( VOBJ_TYPE_DRAW
, eDraw
);
787 pD
->SetViewOptions( aOpts
);
790 void ImportExcel::Standardwidth()
792 sal_uInt16 nScWidth
= XclTools::GetScColumnWidth( maStrm
.ReaduInt16(), GetCharWidth() );
795 SAL_WARN("sc", "*ImportExcel::Standardwidth(): pColRowBuff is NULL!");
798 pColRowBuff
->SetDefWidth( nScWidth
, true );
801 void ImportExcel::Shrfmla()
805 case EXC_ID2_FORMULA
:
806 case EXC_ID3_FORMULA
:
807 case EXC_ID4_FORMULA
:
808 // This record MUST immediately follow a FORMULA record.
815 // The last FORMULA record should have left this data.
819 sal_uInt16 nLenExpr
= aIn
.ReaduInt16();
821 // read mark is now on the formula
823 std::unique_ptr
<ScTokenArray
> pResult
;
825 // The shared range in this record is erroneous more than half the time.
826 // Don't ever rely on it. Use the one from the formula cell above.
827 SCCOL nCol1
= mpLastFormula
->mnCol
;
828 SCROW nRow1
= mpLastFormula
->mnRow
;
830 ScAddress
aPos(nCol1
, nRow1
, GetCurrScTab());
831 pFormConv
->Reset(aPos
);
832 pFormConv
->Convert( pResult
, maStrm
, nLenExpr
, true, FT_SharedFormula
);
836 SAL_WARN("sc", "+ImportExcel::Shrfmla(): ScTokenArray is NULL!");
840 pExcRoot
->pShrfmlaBuff
->Store(aPos
, *pResult
);
842 // Create formula cell for the last formula record.
844 ScDocumentImport
& rDoc
= GetDocImport();
846 ScFormulaCell
* pCell
= new ScFormulaCell(pD
, aPos
, std::move(pResult
));
847 pCell
->GetCode()->WrapReference(aPos
, EXC_MAXCOL8
, EXC_MAXROW8
);
848 rDoc
.getDoc().CheckLinkFormulaNeedingCheck( *pCell
->GetCode());
849 rDoc
.getDoc().EnsureTable(aPos
.Tab());
850 rDoc
.setFormulaCell(aPos
, pCell
);
851 pCell
->SetNeedNumberFormat(false);
852 if (rtl::math::isFinite(mpLastFormula
->mfValue
))
853 pCell
->SetResultDouble(mpLastFormula
->mfValue
);
855 GetXFRangeBuffer().SetXF(aPos
, mpLastFormula
->mnXF
);
856 mpLastFormula
->mpCell
= pCell
;
859 void ImportExcel::Mulrk()
867 for( XclAddress
aCurrXclPos( aXclPos
); (aXclPos
.mnCol
<= aCurrXclPos
.mnCol
) && (aIn
.GetRecLeft() > 2); ++aCurrXclPos
.mnCol
)
869 nXF
= aIn
.ReaduInt16();
870 nRkNum
= aIn
.ReadInt32();
872 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
873 if( GetAddressConverter().ConvertAddress( aScPos
, aCurrXclPos
, GetCurrScTab(), true ) )
875 GetXFRangeBuffer().SetXF( aScPos
, nXF
);
876 GetDocImport().setNumericCell(aScPos
, XclTools::GetDoubleFromRK(nRkNum
));
881 void ImportExcel::Mulblank()
888 for( XclAddress
aCurrXclPos( aXclPos
); (aXclPos
.mnCol
<= aCurrXclPos
.mnCol
) && (aIn
.GetRecLeft() > 2); ++aCurrXclPos
.mnCol
)
890 nXF
= aIn
.ReaduInt16();
892 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
893 if( GetAddressConverter().ConvertAddress( aScPos
, aCurrXclPos
, GetCurrScTab(), true ) )
894 GetXFRangeBuffer().SetBlankXF( aScPos
, nXF
);
898 void ImportExcel::Rstring()
903 nXFIdx
= aIn
.ReaduInt16();
905 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
906 if( GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
908 // unformatted Unicode string with separate formatting information
909 XclImpString aString
;
911 // #i63105# use text encoding from FONT record
912 rtl_TextEncoding eOldTextEnc
= GetTextEncoding();
913 if( const XclImpFont
* pFont
= GetXFBuffer().GetFont( nXFIdx
) )
914 SetTextEncoding( pFont
->GetFontEncoding() );
915 aString
.Read( maStrm
);
916 SetTextEncoding( eOldTextEnc
);
918 // character formatting runs
919 if( !aString
.IsRich() )
920 aString
.ReadFormats( maStrm
);
922 GetXFRangeBuffer().SetXF( aScPos
, nXFIdx
);
923 XclImpStringHelper::SetToDocument(GetDocImport(), aScPos
, *this, aString
, nXFIdx
);
927 void ImportExcel::Cellmerging()
929 XclImpAddressConverter
& rAddrConv
= GetAddressConverter();
930 SCTAB nScTab
= GetCurrScTab();
933 nCount
= maStrm
.ReaduInt16();
934 for( sal_uInt16 nIdx
= 0; (nIdx
< nCount
) && (maStrm
.GetRecLeft() >= 8); ++nIdx
)
937 maStrm
>> aXclRange
; // 16-bit rows and columns
938 ScRange
aScRange( ScAddress::UNINITIALIZED
);
939 if( rAddrConv
.ConvertRange( aScRange
, aXclRange
, nScTab
, nScTab
, true ) )
940 GetXFRangeBuffer().SetMerge( aScRange
.aStart
.Col(), aScRange
.aStart
.Row(), aScRange
.aEnd
.Col(), aScRange
.aEnd
.Row() );
944 void ImportExcel::Olesize()
946 XclRange
aXclOleSize( ScAddress::UNINITIALIZED
);
948 aXclOleSize
.Read( maStrm
, false );
950 SCTAB nScTab
= GetCurrScTab();
951 GetAddressConverter().ConvertRange( maScOleSize
, aXclOleSize
, nScTab
, nScTab
, false );
954 void ImportExcel::Row34()
956 sal_uInt16 nRow
, nRowHeight
, nGrbit
, nXF
;
958 nRow
= aIn
.ReaduInt16();
961 SCROW nScRow
= static_cast< SCROW
>( nRow
);
963 if( ValidRow( nScRow
) )
965 nRowHeight
= aIn
.ReaduInt16(); // specify direct in Twips
968 nRowHeight
= nRowHeight
& 0x7FFF; // Bit 15: Row Height not changed manually
970 nRowHeight
= (GetBiff() == EXC_BIFF2
) ? 0x25 : 0x225;
972 nGrbit
= aIn
.ReaduInt16();
973 nXF
= aIn
.ReaduInt16();
975 sal_uInt8 nLevel
= ::extract_value
< sal_uInt8
>( nGrbit
, 0, 3 );
976 pRowOutlineBuff
->SetLevel( nScRow
, nLevel
, ::get_flag( nGrbit
, EXC_ROW_COLLAPSED
) );
977 pColRowBuff
->SetRowSettings( nScRow
, nRowHeight
, nGrbit
);
979 if( nGrbit
& EXC_ROW_USEDEFXF
)
980 GetXFRangeBuffer().SetRowDefXF( nScRow
, nXF
& EXC_ROW_XFMASK
);
984 void ImportExcel::Bof3()
987 maStrm
.DisableDecryption();
989 nSubType
= maStrm
.ReaduInt16();
991 OSL_ENSURE( nSubType
!= 0x0100, "*ImportExcel::Bof3(): Biff3 as Workbook?!" );
992 if( nSubType
== 0x0100 ) // Book
993 pExcRoot
->eDateiTyp
= Biff3W
;
994 else if( nSubType
== 0x0020 ) // Chart
995 pExcRoot
->eDateiTyp
= Biff3C
;
996 else if( nSubType
== 0x0040 ) // Macro
997 pExcRoot
->eDateiTyp
= Biff3M
;
998 else // #i51490# Excel interprets invalid indexes as worksheet
999 pExcRoot
->eDateiTyp
= Biff3
;
1002 void ImportExcel::Array34()
1004 sal_uInt16 nFirstRow
, nLastRow
, nFormLen
;
1005 sal_uInt8 nFirstCol
, nLastCol
;
1007 nFirstRow
= aIn
.ReaduInt16();
1008 nLastRow
= aIn
.ReaduInt16();
1009 nFirstCol
= aIn
.ReaduInt8();
1010 nLastCol
= aIn
.ReaduInt8();
1011 aIn
.Ignore( (GetBiff() >= EXC_BIFF5
) ? 6 : 2 );
1012 nFormLen
= aIn
.ReaduInt16();
1014 std::unique_ptr
<ScTokenArray
> pResult
;
1016 if( ValidColRow( nLastCol
, nLastRow
) )
1018 // the read mark is now on the formula, length in nFormLen
1020 pFormConv
->Reset( ScAddress( static_cast<SCCOL
>(nFirstCol
),
1021 static_cast<SCROW
>(nFirstRow
), GetCurrScTab() ) );
1022 pFormConv
->Convert( pResult
, maStrm
, nFormLen
, true );
1024 SAL_WARN_IF(!pResult
, "sc", "+ImportExcel::Array34(): ScTokenArray is NULL!");
1029 ScDocumentImport
& rDoc
= GetDocImport();
1030 ScRange
aArrayRange(nFirstCol
, nFirstRow
, GetCurrScTab(), nLastCol
, nLastRow
, GetCurrScTab());
1031 rDoc
.setMatrixCells(aArrayRange
, *pResult
, formula::FormulaGrammar::GRAM_ENGLISH_XL_A1
);
1035 void ImportExcel::Defrowheight345()
1037 sal_uInt16 nFlags
, nDefHeight
;
1038 nFlags
= maStrm
.ReaduInt16();
1039 nDefHeight
= maStrm
.ReaduInt16();
1043 SAL_WARN("sc", "*ImportExcel::Defrowheight345(): pColRowBuff is NULL!");
1047 pColRowBuff
->SetDefHeight( nDefHeight
, nFlags
);
1050 void ImportExcel::TableOp()
1052 sal_uInt16 nFirstRow
, nLastRow
;
1053 sal_uInt8 nFirstCol
, nLastCol
;
1055 sal_uInt16 nInpRow
, nInpCol
, nInpRow2
, nInpCol2
;
1057 nFirstRow
= aIn
.ReaduInt16();
1058 nLastRow
= aIn
.ReaduInt16();
1059 nFirstCol
= aIn
.ReaduInt8();
1060 nLastCol
= aIn
.ReaduInt8();
1061 nGrbit
= aIn
.ReaduInt16();
1062 nInpRow
= aIn
.ReaduInt16();
1063 nInpCol
= aIn
.ReaduInt16();
1064 nInpRow2
= aIn
.ReaduInt16();
1065 nInpCol2
= aIn
.ReaduInt16();
1067 if (utl::ConfigManager::IsFuzzing())
1069 //shrink to smallish arbitrary value to not timeout
1070 nLastRow
= std::min
<sal_uInt16
>(nLastRow
, MAXROW_30
);
1073 if( ValidColRow( nLastCol
, nLastRow
) )
1075 if( nFirstCol
&& nFirstRow
)
1077 ScTabOpParam aTabOpParam
;
1078 aTabOpParam
.meMode
= (nGrbit
& EXC_TABLEOP_BOTH
) ? ScTabOpParam::Both
: ((nGrbit
& EXC_TABLEOP_ROW
) ? ScTabOpParam::Row
: ScTabOpParam::Column
);
1079 sal_uInt16 nCol
= nFirstCol
- 1;
1080 sal_uInt16 nRow
= nFirstRow
- 1;
1081 SCTAB nTab
= GetCurrScTab();
1082 switch (aTabOpParam
.meMode
)
1084 case ScTabOpParam::Column
:
1085 aTabOpParam
.aRefFormulaCell
.Set(
1086 static_cast<SCCOL
>(nFirstCol
),
1087 static_cast<SCROW
>(nFirstRow
- 1), nTab
, false,
1089 aTabOpParam
.aRefFormulaEnd
.Set(
1090 static_cast<SCCOL
>(nLastCol
),
1091 static_cast<SCROW
>(nFirstRow
- 1), nTab
, false,
1093 aTabOpParam
.aRefColCell
.Set( static_cast<SCCOL
>(nInpCol
),
1094 static_cast<SCROW
>(nInpRow
), nTab
, false, false,
1098 case ScTabOpParam::Row
:
1099 aTabOpParam
.aRefFormulaCell
.Set(
1100 static_cast<SCCOL
>(nFirstCol
- 1),
1101 static_cast<SCROW
>(nFirstRow
), nTab
, false, false,
1103 aTabOpParam
.aRefFormulaEnd
.Set(
1104 static_cast<SCCOL
>(nFirstCol
- 1),
1105 static_cast<SCROW
>(nLastRow
), nTab
, false, false,
1107 aTabOpParam
.aRefRowCell
.Set( static_cast<SCCOL
>(nInpCol
),
1108 static_cast<SCROW
>(nInpRow
), nTab
, false, false,
1112 case ScTabOpParam::Both
: // TWO-INPUT
1113 aTabOpParam
.aRefFormulaCell
.Set(
1114 static_cast<SCCOL
>(nFirstCol
- 1),
1115 static_cast<SCROW
>(nFirstRow
- 1), nTab
, false,
1117 aTabOpParam
.aRefRowCell
.Set( static_cast<SCCOL
>(nInpCol
),
1118 static_cast<SCROW
>(nInpRow
), nTab
, false, false,
1120 aTabOpParam
.aRefColCell
.Set( static_cast<SCCOL
>(nInpCol2
),
1121 static_cast<SCROW
>(nInpRow2
), nTab
, false, false,
1126 ScDocumentImport
& rDoc
= GetDocImport();
1127 ScRange
aTabOpRange(nCol
, nRow
, nTab
, nLastCol
, nLastRow
, nTab
);
1128 rDoc
.setTableOpCells(aTabOpRange
, aTabOpParam
);
1133 bTabTruncated
= true;
1134 GetTracer().TraceInvalidRow(nLastRow
, pD
->MaxRow());
1138 void ImportExcel::Bof4()
1140 sal_uInt16 nSubType
;
1141 maStrm
.DisableDecryption();
1143 nSubType
= maStrm
.ReaduInt16();
1145 if( nSubType
== 0x0100 ) // Book
1146 pExcRoot
->eDateiTyp
= Biff4W
;
1147 else if( nSubType
== 0x0020 ) // Chart
1148 pExcRoot
->eDateiTyp
= Biff4C
;
1149 else if( nSubType
== 0x0040 ) // Macro
1150 pExcRoot
->eDateiTyp
= Biff4M
;
1151 else // #i51490# Excel interprets invalid indexes as worksheet
1152 pExcRoot
->eDateiTyp
= Biff4
;
1155 void ImportExcel::Bof5()
1157 //POST: eDateiTyp = Type of the file to be read
1158 sal_uInt16 nSubType
, nVers
;
1161 maStrm
.DisableDecryption();
1162 nVers
= maStrm
.ReaduInt16();
1163 nSubType
= maStrm
.ReaduInt16( );
1167 case 0x0005: eDatei
= Biff5W
; break; // workbook globals
1168 case 0x0006: eDatei
= Biff5V
; break; // VB module
1169 case 0x0010: eDatei
= Biff5
; break; // worksheet
1170 case 0x0020: eDatei
= Biff5C
; break; // chart
1171 case 0x0040: eDatei
= Biff5M4
; break; // macro sheet
1173 pExcRoot
->eDateiTyp
= BiffX
;
1177 if( nVers
== 0x0600 && (GetBiff() == EXC_BIFF8
) )
1178 eDatei
= static_cast<BiffTyp
>( eDatei
- Biff5
+ Biff8
);
1180 pExcRoot
->eDateiTyp
= eDatei
;
1183 void ImportExcel::EndSheet()
1185 pExcRoot
->pExtSheetBuff
->Reset();
1187 if( GetBiff() <= EXC_BIFF5
)
1189 pExcRoot
->pExtNameBuff
->Reset();
1196 void ImportExcel::NewTable()
1198 SCTAB nTab
= GetCurrScTab();
1199 if( nTab
> 0 && !pD
->HasTable( nTab
) )
1200 pD
->MakeTable( nTab
);
1202 if (nTab
== 0 && GetBiff() == EXC_BIFF2
)
1204 // For Excel 2.1 Worksheet file, we need to set the file name as the
1206 INetURLObject
aURL(GetDocUrl());
1207 pD
->RenameTab(0, aURL
.getBase());
1210 pExcRoot
->pShrfmlaBuff
->Clear();
1211 maLastFormulaCells
.clear();
1212 mpLastFormula
= nullptr;
1214 InitializeTable( nTab
);
1216 XclImpOutlineDataBuffer
* pNewItem
= new XclImpOutlineDataBuffer( GetRoot(), nTab
);
1217 pOutlineListBuffer
->push_back( std::unique_ptr
<XclImpOutlineDataBuffer
>(pNewItem
) );
1218 pExcRoot
->pColRowBuff
= pColRowBuff
= pNewItem
->GetColRowBuff();
1219 pColOutlineBuff
= pNewItem
->GetColOutline();
1220 pRowOutlineBuff
= pNewItem
->GetRowOutline();
1223 std::unique_ptr
<ScTokenArray
> ImportExcel::ErrorToFormula( bool bErrOrVal
, sal_uInt8 nError
, double& rVal
)
1225 return pFormConv
->GetBoolErr( XclTools::ErrorToEnum( rVal
, bErrOrVal
, nError
) );
1228 void ImportExcel::AdjustRowHeight()
1230 /* Speed up chart import: import all sheets without charts, then
1231 update row heights (here), last load all charts -> do not any longer
1232 update inside of ScDocShell::ConvertFrom() (causes update of existing
1233 charts during each and every change of row height). */
1234 if( ScModelObj
* pDocObj
= GetDocModelObj() )
1235 pDocObj
->UpdateAllRowHeights();
1238 void ImportExcel::PostDocLoad()
1240 /* Set automatic page numbering in Default page style (default is "page number = 1").
1241 Otherwise hidden tables (i.e. for scenarios) which have Default page style will
1242 break automatic page numbering. */
1243 if( SfxStyleSheetBase
* pStyleSheet
= GetStyleSheetPool().Find( ScResId( STR_STYLENAME_STANDARD
), SfxStyleFamily::Page
) )
1244 pStyleSheet
->GetItemSet().Put( SfxUInt16Item( ATTR_PAGE_FIRSTPAGENO
, 0 ) );
1246 // outlines for all sheets, sets hidden rows and columns (#i11776# after filtered ranges)
1247 for (auto& rxBuffer
: *pOutlineListBuffer
)
1248 rxBuffer
->Convert();
1250 // document view settings (before visible OLE area)
1251 GetDocViewSettings().Finalize();
1253 // process all drawing objects (including OLE, charts, controls; after hiding rows/columns; before visible OLE area)
1254 GetObjectManager().ConvertObjects();
1256 // visible area (used if this document is an embedded OLE object)
1257 if( SfxObjectShell
* pDocShell
= GetDocShell() )
1259 // visible area if embedded
1260 const ScExtDocSettings
& rDocSett
= GetExtDocOptions().GetDocSettings();
1261 SCTAB nDisplScTab
= rDocSett
.mnDisplTab
;
1263 /* #i44077# If a new OLE object is inserted from file, there is no
1264 OLESIZE record in the Excel file. Calculate used area from file
1265 contents (used cells and drawing objects). */
1266 if( !maScOleSize
.IsValid() )
1268 // used area of displayed sheet (cell contents)
1269 if( const ScExtTabSettings
* pTabSett
= GetExtDocOptions().GetTabSettings( nDisplScTab
) )
1270 maScOleSize
= pTabSett
->maUsedArea
;
1271 // add all valid drawing objects
1272 ScRange aScObjArea
= GetObjectManager().GetUsedArea( nDisplScTab
);
1273 if( aScObjArea
.IsValid() )
1274 maScOleSize
.ExtendTo( aScObjArea
);
1277 // valid size found - set it at the document
1278 if( maScOleSize
.IsValid() )
1280 pDocShell
->SetVisArea( GetDoc().GetMMRect(
1281 maScOleSize
.aStart
.Col(), maScOleSize
.aStart
.Row(),
1282 maScOleSize
.aEnd
.Col(), maScOleSize
.aEnd
.Row(), nDisplScTab
) );
1283 GetDoc().SetVisibleTab( nDisplScTab
);
1287 // open forms in alive mode (has no effect, if no controls in document)
1288 if( ScModelObj
* pDocObj
= GetDocModelObj() )
1289 pDocObj
->setPropertyValue( SC_UNO_APPLYFMDES
, uno::Any( false ) );
1291 // enables extended options to be set to the view after import
1292 GetExtDocOptions().SetChanged( true );
1294 // root data owns the extended document options -> create a new object
1295 GetDoc().SetExtDocOptions( std::make_unique
<ScExtDocOptions
>( GetExtDocOptions() ) );
1297 const SCTAB nLast
= pD
->GetTableCount();
1300 if( pExcRoot
->pPrintRanges
->HasRanges() )
1302 for( SCTAB n
= 0 ; n
< nLast
; n
++ )
1304 p
= pExcRoot
->pPrintRanges
->First(n
);
1307 pD
->ClearPrintRanges( n
);
1310 pD
->AddPrintRange( n
, *p
);
1311 p
= pExcRoot
->pPrintRanges
->Next();
1316 // #i4063# no print ranges -> print entire sheet
1317 pD
->SetPrintEntireSheet( n
);
1320 GetTracer().TracePrintRange();
1323 if( pExcRoot
->pPrintTitles
->HasRanges() )
1325 for( SCTAB n
= 0 ; n
< nLast
; n
++ )
1327 p
= pExcRoot
->pPrintTitles
->First(n
);
1330 bool bRowVirgin
= true;
1331 bool bColVirgin
= true;
1335 if( p
->aStart
.Col() == 0 && p
->aEnd
.Col() == pD
->MaxCol() && bRowVirgin
)
1337 pD
->SetRepeatRowRange( n
, std::unique_ptr
<ScRange
>(new ScRange(*p
)) );
1341 if( p
->aStart
.Row() == 0 && p
->aEnd
.Row() == pD
->MaxRow() && bColVirgin
)
1343 pD
->SetRepeatColRange( n
, std::unique_ptr
<ScRange
>(new ScRange(*p
)) );
1347 p
= pExcRoot
->pPrintTitles
->Next();
1354 XclImpOutlineDataBuffer::XclImpOutlineDataBuffer( const XclImpRoot
& rRoot
, SCTAB nScTab
) :
1355 XclImpRoot( rRoot
),
1356 mxColOutlineBuff( new XclImpOutlineBuffer( rRoot
.GetXclMaxPos().Col() + 1 ) ),
1357 mxRowOutlineBuff( new XclImpOutlineBuffer( rRoot
.GetXclMaxPos().Row() + 1 ) ),
1358 mxColRowBuff( new XclImpColRowSettings( rRoot
) ),
1363 XclImpOutlineDataBuffer::~XclImpOutlineDataBuffer()
1367 void XclImpOutlineDataBuffer::Convert()
1369 mxColOutlineBuff
->SetOutlineArray( &GetDoc().GetOutlineTable( mnScTab
, true )->GetColArray() );
1370 mxColOutlineBuff
->MakeScOutline();
1372 mxRowOutlineBuff
->SetOutlineArray( &GetDoc().GetOutlineTable( mnScTab
, true )->GetRowArray() );
1373 mxRowOutlineBuff
->MakeScOutline();
1375 mxColRowBuff
->ConvertHiddenFlags( mnScTab
);
1378 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */