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 <comphelper/configuration.hxx>
32 #include <sal/log.hxx>
34 #include <sfx2/objsh.hxx>
35 #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),
100 mbFuzzing(comphelper::IsFuzzing())
104 // fill in root data - after new's without root as parameter
105 pExcRoot
= &GetOldRoot();
106 pExcRoot
->pIR
= this; // ExcRoot -> XclImpRoot
107 pExcRoot
->eDateiTyp
= BiffX
;
108 pExcRoot
->pExtSheetBuff
.reset( new ExtSheetBuffer( pExcRoot
) ); //&aExtSheetBuff;
109 pExcRoot
->pShrfmlaBuff
.reset( new SharedFormulaBuffer( pExcRoot
) ); //&aShrfrmlaBuff;
110 pExcRoot
->pExtNameBuff
.reset( new ExtNameBuff ( *this ) );
112 pOutlineListBuffer
.reset(new XclImpOutlineListBuffer
);
115 pFormConv
.reset(new ExcelToSc( GetRoot() ));
116 pExcRoot
->pFmlaConverter
= pFormConv
.get();
118 bTabTruncated
= false;
120 // Excel document per Default on 31.12.1899, accords to Excel settings with 1.1.1900
121 ScDocOptions aOpt
= rD
.GetDocOptions();
122 aOpt
.SetDate( 30, 12, 1899 );
123 rD
.SetDocOptions( aOpt
);
124 rD
.GetFormatTable()->ChangeNullDate( 30, 12, 1899 );
126 ScDocOptions
aDocOpt( rD
.GetDocOptions() );
127 aDocOpt
.SetIgnoreCase( true ); // always in Excel
128 aDocOpt
.SetFormulaRegexEnabled( false ); // regular expressions? what's that?
129 aDocOpt
.SetFormulaWildcardsEnabled( true ); // Excel uses wildcard expressions
130 aDocOpt
.SetLookUpColRowNames( false ); // default: no natural language refs
131 rD
.SetDocOptions( aDocOpt
);
134 ImportExcel::~ImportExcel()
136 GetDoc().SetSrcCharSet( GetTextEncoding() );
138 pOutlineListBuffer
.reset();
143 void ImportExcel::SetLastFormula( SCCOL nCol
, SCROW nRow
, double fVal
, sal_uInt16 nXF
, ScFormulaCell
* pCell
)
145 LastFormulaMapType::iterator it
= maLastFormulaCells
.find(nCol
);
146 if (it
== maLastFormulaCells
.end())
148 std::pair
<LastFormulaMapType::iterator
, bool> r
=
149 maLastFormulaCells
.emplace(nCol
, LastFormula());
153 it
->second
.mnCol
= nCol
;
154 it
->second
.mnRow
= nRow
;
155 it
->second
.mpCell
= pCell
;
156 it
->second
.mfValue
= fVal
;
157 it
->second
.mnXF
= nXF
;
159 mpLastFormula
= &it
->second
;
162 void ImportExcel::ReadFileSharing()
164 sal_uInt16 nRecommendReadOnly
, nPasswordHash
;
165 nRecommendReadOnly
= maStrm
.ReaduInt16();
166 nPasswordHash
= maStrm
.ReaduInt16();
168 if((nRecommendReadOnly
== 0) && (nPasswordHash
== 0))
171 GetMedium().GetItemSet().Put( SfxBoolItem( SID_DOC_READONLY
, true ) );
173 if( ScDocShell
* 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
= maStrm
.ReaduInt32();
245 sal_uInt32 nXclRow2
= maStrm
.ReaduInt32();
246 aXclUsedArea
.maFirst
.mnCol
= maStrm
.ReaduInt16();
247 aXclUsedArea
.maLast
.mnCol
= maStrm
.ReaduInt16();
248 if( nXclRow2
!= 0 && (nXclRow1
< nXclRow2
) && (aXclUsedArea
.GetColCount() > 1) &&
249 (nXclRow1
<= o3tl::make_unsigned( GetScMaxPos().Row() )) )
251 // Excel stores first unused row/column index
253 aXclUsedArea
.maLast
.mnCol
= o3tl::sanitizing_dec(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 ) )
323 /* Record ID BIFF XF type String type
324 0x0004 2-7 3 byte 8-bit length, byte string
325 0x0004 8 3 byte 16-bit length, unicode string
326 0x0204 2-7 2 byte 16-bit length, byte string
327 0x0204 8 2 byte 16-bit length, unicode string */
328 bool bBiff2
= maStrm
.GetRecId() == EXC_ID2_LABEL
;
329 sal_uInt16 nXFIdx
= ReadXFIndex( aScPos
, bBiff2
);
330 XclStrFlags nFlags
= (bBiff2
&& (GetBiff() <= EXC_BIFF5
)) ? XclStrFlags::EightBitLength
: XclStrFlags::NONE
;
331 XclImpString aString
;
333 // #i63105# use text encoding from FONT record
334 rtl_TextEncoding eOldTextEnc
= GetTextEncoding();
335 if( const XclImpFont
* pFont
= GetXFBuffer().GetFont( nXFIdx
) )
336 SetTextEncoding( pFont
->GetFontEncoding() );
337 aString
.Read( maStrm
, nFlags
);
338 SetTextEncoding( eOldTextEnc
);
340 GetXFRangeBuffer().SetXF( aScPos
, nXFIdx
);
341 XclImpStringHelper::SetToDocument(GetDocImport(), aScPos
, GetRoot(), aString
, nXFIdx
);
344 void ImportExcel::ReadBoolErr()
349 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
350 if( !GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
353 sal_uInt16 nXFIdx
= ReadXFIndex( aScPos
, maStrm
.GetRecId() == EXC_ID2_BOOLERR
);
354 sal_uInt8 nValue
, nType
;
355 nValue
= maStrm
.ReaduInt8();
356 nType
= maStrm
.ReaduInt8();
358 if( nType
== EXC_BOOLERR_BOOL
)
359 GetXFRangeBuffer().SetBoolXF( aScPos
, nXFIdx
);
361 GetXFRangeBuffer().SetXF( aScPos
, nXFIdx
);
364 std::unique_ptr
<ScTokenArray
> pScTokArr
= ErrorToFormula( nType
!= EXC_BOOLERR_BOOL
, nValue
, fValue
);
365 ScFormulaCell
* pCell
= pScTokArr
366 ? new ScFormulaCell(rD
, aScPos
, std::move(pScTokArr
))
367 : new ScFormulaCell(rD
, aScPos
);
368 pCell
->SetHybridDouble( fValue
);
369 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( !GetRoot().GetDoc().ValidRow( nRow
) )
404 nRowHeight
= aIn
.ReaduInt16(); // specify direct in Twips
407 if( GetBiff() == EXC_BIFF2
)
408 {// -------------------- BIFF2
409 pColRowBuff
->SetHeight( nRow
, nRowHeight
);
412 {// -------------------- BIFF5
415 aIn
.Ignore( 2 ); // reserved
416 nGrbit
= aIn
.ReaduInt16();
418 sal_uInt8 nLevel
= ::extract_value
< sal_uInt8
>( nGrbit
, 0, 3 );
419 pRowOutlineBuff
->SetLevel( nRow
, nLevel
, ::get_flag( nGrbit
, EXC_ROW_COLLAPSED
) );
420 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
= aIn
.ReaduInt16();
474 sal_uInt16 nColMac
= aIn
.ReaduInt16();
476 OSL_ENSURE( aIn
.GetRecLeft() == static_cast<std::size_t>(nColMac
- nColMic
) * 3 + 2,
477 "ImportExcel::Columndefault - wrong record size" );
481 SAL_WARN("sc", "dodgy column defaults");
485 assert(nColMac
> 0 && "coverity 2023.12.2");
489 if( nColMac
> rD
.MaxCol() )
490 nColMac
= static_cast<sal_uInt16
>(rD
.MaxCol());
492 for( sal_uInt16 nCol
= nColMic
; nCol
<= nColMac
; nCol
++ )
494 sal_uInt8 nOpt0
= aIn
.ReaduInt8();
495 aIn
.Ignore( 2 ); // only 0. Attribute-Byte used
497 if( nOpt0
& 0x80 ) // Col hidden?
498 pColRowBuff
->HideCol( nCol
);
502 void ImportExcel::Array25()
505 sal_uInt16 nFirstRow
= aIn
.ReaduInt16();
506 sal_uInt16 nLastRow
= aIn
.ReaduInt16();
507 sal_uInt8 nFirstCol
= aIn
.ReaduInt8();
508 sal_uInt8 nLastCol
= aIn
.ReaduInt8();
510 if( GetBiff() == EXC_BIFF2
)
513 nFormLen
= aIn
.ReaduInt8();
518 nFormLen
= aIn
.ReaduInt16();
521 std::unique_ptr
<ScTokenArray
> pResult
;
523 if (GetRoot().GetDoc().ValidColRow(nLastCol
, nLastRow
))
525 // the read mark is now on the formula, length in nFormLen
527 pFormConv
->Reset( ScAddress( static_cast<SCCOL
>(nFirstCol
),
528 static_cast<SCROW
>(nFirstRow
), GetCurrScTab() ) );
529 pFormConv
->Convert(pResult
, maStrm
, nFormLen
, true);
531 SAL_WARN_IF(!pResult
, "sc", "*ImportExcel::Array25(): ScTokenArray is NULL!");
536 ScDocumentImport
& rDoc
= GetDocImport();
537 ScRange
aArrayRange(nFirstCol
, nFirstRow
, GetCurrScTab(), nLastCol
, nLastRow
, GetCurrScTab());
538 rDoc
.setMatrixCells(aArrayRange
, *pResult
, formula::FormulaGrammar::GRAM_ENGLISH_XL_A1
);
542 void ImportExcel::Rec1904()
546 n1904
= aIn
.ReaduInt16();
550 ScDocOptions aOpt
= rD
.GetDocOptions();
551 aOpt
.SetDate( 1, 1, 1904 );
552 rD
.SetDocOptions( aOpt
);
553 rD
.GetFormatTable()->ChangeNullDate( 1, 1, 1904 );
557 void ImportExcel::Externname25()
562 nOpt
= aIn
.ReaduInt16();
563 nRes
= aIn
.ReaduInt32();
565 aIn
.ReadByteString( false ); // name
567 if( ( nOpt
& 0x0001 ) || ( ( nOpt
& 0xFFFE ) == 0x0000 ) )
569 pExcRoot
->pExtNameBuff
->AddName( mnLastRefIdx
);
571 else if( nOpt
& 0x0010 )
573 pExcRoot
->pExtNameBuff
->AddOLE( mnLastRefIdx
, nRes
); // nRes is storage ID
577 pExcRoot
->pExtNameBuff
->AddDDE( mnLastRefIdx
);
581 void ImportExcel::Colwidth()
583 sal_uInt8 nColFirst
, nColLast
;
584 sal_uInt16 nColWidth
;
586 nColFirst
= aIn
.ReaduInt8();
587 nColLast
= aIn
.ReaduInt8();
588 nColWidth
= aIn
.ReaduInt16();
590 //TODO: add a check for the unlikely case of changed MAXCOL (-> XclImpAddressConverter)
591 // if( nColLast > rD.MaxCol() )
592 // nColLast = static_cast<sal_uInt16>(rD.MaxCol());
594 sal_uInt16 nScWidth
= XclTools::GetScColumnWidth( nColWidth
, GetCharWidth() );
595 pColRowBuff
->SetWidthRange( nColFirst
, nColLast
, nScWidth
);
598 void ImportExcel::Defrowheight2()
600 sal_uInt16 nDefHeight
;
601 nDefHeight
= maStrm
.ReaduInt16();
602 nDefHeight
&= 0x7FFF;
603 pColRowBuff
->SetDefHeight( nDefHeight
, EXC_DEFROW_UNSYNCED
);
606 void ImportExcel::SheetProtect()
608 if (GetRoot().GetBiff() != EXC_BIFF8
)
611 GetRoot().GetSheetProtectBuffer().ReadProtect( aIn
, GetCurrScTab() );
614 void ImportExcel::DocProtect()
616 if (GetRoot().GetBiff() != EXC_BIFF8
)
619 GetRoot().GetDocProtectBuffer().ReadDocProtect( aIn
);
622 void ImportExcel::DocPassword()
624 if (GetRoot().GetBiff() != EXC_BIFF8
)
627 GetRoot().GetDocProtectBuffer().ReadPasswordHash( aIn
);
630 void ImportExcel::Codepage()
632 SetCodePage( maStrm
.ReaduInt16() );
635 void ImportExcel::Ixfe()
637 mnIxfeIndex
= maStrm
.ReaduInt16();
640 void ImportExcel::DefColWidth()
642 // stored as entire characters -> convert to 1/256 of characters (as in COLINFO)
643 double fDefWidth
= 256.0 * maStrm
.ReaduInt16();
647 SAL_WARN("sc", "*ImportExcel::DefColWidth(): pColRowBuff is NULL!");
651 // #i3006# additional space for default width - Excel adds space depending on font size
652 tools::Long nFontHt
= GetFontBuffer().GetAppFontData().mnHeight
;
653 fDefWidth
+= XclTools::GetXclDefColWidthCorrection( nFontHt
);
655 sal_uInt16 nScWidth
= XclTools::GetScColumnWidth( limit_cast
< sal_uInt16
>( fDefWidth
), GetCharWidth() );
656 pColRowBuff
->SetDefWidth( nScWidth
);
659 void ImportExcel::Colinfo()
660 {// Column Formatting Information
661 sal_uInt16 nColFirst
, nColLast
, nColWidth
, nXF
;
664 nColFirst
= aIn
.ReaduInt16();
665 nColLast
= aIn
.ReaduInt16();
666 nColWidth
= aIn
.ReaduInt16();
667 nXF
= aIn
.ReaduInt16();
668 nOpt
= aIn
.ReaduInt16();
670 if( nColFirst
> rD
.MaxCol() )
673 if( nColLast
> rD
.MaxCol() )
674 nColLast
= static_cast<sal_uInt16
>(rD
.MaxCol());
676 bool bHidden
= ::get_flag( nOpt
, EXC_COLINFO_HIDDEN
);
677 bool bCollapsed
= ::get_flag( nOpt
, EXC_COLINFO_COLLAPSED
);
678 sal_uInt8 nLevel
= ::extract_value
< sal_uInt8
>( nOpt
, 8, 3 );
679 pColOutlineBuff
->SetLevelRange( nColFirst
, nColLast
, nLevel
, bCollapsed
);
682 pColRowBuff
->HideColRange( nColFirst
, nColLast
);
684 sal_uInt16 nScWidth
= XclTools::GetScColumnWidth( nColWidth
, GetCharWidth() );
685 pColRowBuff
->SetWidthRange( nColFirst
, nColLast
, nScWidth
);
686 pColRowBuff
->SetDefaultXF( nColFirst
, nColLast
, nXF
);
689 void ImportExcel::Wsbool()
692 nFlags
= aIn
.ReaduInt16();
694 pRowOutlineBuff
->SetButtonMode( ::get_flag( nFlags
, EXC_WSBOOL_ROWBELOW
) );
695 pColOutlineBuff
->SetButtonMode( ::get_flag( nFlags
, EXC_WSBOOL_COLBELOW
) );
697 GetPageSettings().SetFitToPages( ::get_flag( nFlags
, EXC_WSBOOL_FITTOPAGE
) );
700 void ImportExcel::Boundsheet()
702 sal_uInt16 nGrbit
= 0;
704 if( GetBiff() == EXC_BIFF5
)
706 aIn
.DisableDecryption();
707 maSheetOffsets
.push_back( aIn
.ReaduInt32() );
708 aIn
.EnableDecryption();
709 nGrbit
= aIn
.ReaduInt16();
712 OUString
aName( aIn
.ReadByteString( false ) );
714 SCTAB nScTab
= nBdshtTab
;
717 OSL_ENSURE( !rD
.HasTable( nScTab
), "ImportExcel::Boundsheet - sheet exists already" );
718 rD
.MakeTable( nScTab
);
721 if( ( nGrbit
& 0x0001 ) || ( nGrbit
& 0x0002 ) )
722 rD
.SetVisible( nScTab
, false );
724 if( !rD
.RenameTab( nScTab
, aName
) )
726 rD
.CreateValidTabName( aName
);
727 rD
.RenameTab( nScTab
, aName
);
733 void ImportExcel::Country()
735 sal_uInt16 nUICountry
, nDocCountry
;
736 nUICountry
= maStrm
.ReaduInt16();
737 nDocCountry
= maStrm
.ReaduInt16();
739 // Store system language in XclRoot
740 LanguageType eLanguage
= ::msfilter::ConvertCountryToLanguage( static_cast< ::msfilter::CountryId
>( nDocCountry
) );
741 if( eLanguage
!= LANGUAGE_DONTKNOW
)
742 SetDocLanguage( eLanguage
);
744 // Set Excel UI language in add-in name translator
745 eLanguage
= ::msfilter::ConvertCountryToLanguage( static_cast< ::msfilter::CountryId
>( nUICountry
) );
746 if( eLanguage
!= LANGUAGE_DONTKNOW
)
747 SetUILanguage( eLanguage
);
750 void ImportExcel::ReadUsesElfs()
752 if( maStrm
.ReaduInt16() != 0 )
754 ScDocOptions aDocOpt
= GetDoc().GetDocOptions();
755 aDocOpt
.SetLookUpColRowNames( true );
756 GetDoc().SetDocOptions( aDocOpt
);
760 void ImportExcel::Hideobj()
763 ScVObjMode eOle
, eChart
, eDraw
;
765 nHide
= aIn
.ReaduInt16();
767 ScViewOptions
aOpts( rD
.GetViewOptions() );
771 case 1: // Placeholders
772 eOle
= VOBJ_MODE_SHOW
; // in Excel 97 only charts as place holder are displayed
773 eChart
= VOBJ_MODE_SHOW
; //#i80528# VOBJ_MODE_DUMMY replaced by VOBJ_MODE_SHOW now
774 eDraw
= VOBJ_MODE_SHOW
;
777 eOle
= VOBJ_MODE_HIDE
;
778 eChart
= VOBJ_MODE_HIDE
;
779 eDraw
= VOBJ_MODE_HIDE
;
782 eOle
= VOBJ_MODE_SHOW
;
783 eChart
= VOBJ_MODE_SHOW
;
784 eDraw
= VOBJ_MODE_SHOW
;
788 aOpts
.SetObjMode( VOBJ_TYPE_OLE
, eOle
);
789 aOpts
.SetObjMode( VOBJ_TYPE_CHART
, eChart
);
790 aOpts
.SetObjMode( VOBJ_TYPE_DRAW
, eDraw
);
792 rD
.SetViewOptions( aOpts
);
795 void ImportExcel::Standardwidth()
797 sal_uInt16 nScWidth
= XclTools::GetScColumnWidth( maStrm
.ReaduInt16(), GetCharWidth() );
800 SAL_WARN("sc", "*ImportExcel::Standardwidth(): pColRowBuff is NULL!");
803 pColRowBuff
->SetDefWidth( nScWidth
, true );
806 void ImportExcel::Shrfmla()
810 case EXC_ID2_FORMULA
:
811 case EXC_ID3_FORMULA
:
812 case EXC_ID4_FORMULA
:
813 // This record MUST immediately follow a FORMULA record.
820 // The last FORMULA record should have left this data.
824 sal_uInt16 nLenExpr
= aIn
.ReaduInt16();
826 // read mark is now on the formula
828 std::unique_ptr
<ScTokenArray
> pResult
;
830 // The shared range in this record is erroneous more than half the time.
831 // Don't ever rely on it. Use the one from the formula cell above.
832 SCCOL nCol1
= mpLastFormula
->mnCol
;
833 SCROW nRow1
= mpLastFormula
->mnRow
;
835 ScAddress
aPos(nCol1
, nRow1
, GetCurrScTab());
836 pFormConv
->Reset(aPos
);
837 pFormConv
->Convert( pResult
, maStrm
, nLenExpr
, true, FT_SharedFormula
);
841 SAL_WARN("sc", "+ImportExcel::Shrfmla(): ScTokenArray is NULL!");
845 pExcRoot
->pShrfmlaBuff
->Store(aPos
, *pResult
);
847 // Create formula cell for the last formula record.
849 ScDocumentImport
& rDoc
= GetDocImport();
851 ScFormulaCell
* pCell
= new ScFormulaCell(rD
, aPos
, std::move(pResult
));
852 pCell
->GetCode()->WrapReference(aPos
, EXC_MAXCOL8
, EXC_MAXROW8
);
853 rDoc
.getDoc().CheckLinkFormulaNeedingCheck( *pCell
->GetCode());
854 rDoc
.getDoc().EnsureTable(aPos
.Tab());
855 rDoc
.setFormulaCell(aPos
, pCell
);
856 pCell
->SetNeedNumberFormat(false);
857 if (std::isfinite(mpLastFormula
->mfValue
))
858 pCell
->SetResultDouble(mpLastFormula
->mfValue
);
860 GetXFRangeBuffer().SetXF(aPos
, mpLastFormula
->mnXF
);
861 mpLastFormula
->mpCell
= pCell
;
864 void ImportExcel::Mulrk()
866 /* rw (2 bytes): An Rw structure that specifies the row containing the
867 cells with numeric data.
869 colFirst (2 bytes): A Col structure that specifies the first column in
870 the series of numeric cells within the sheet. The value of colFirst.col
871 MUST be less than or equal to 254.
873 rgrkrec (variable): An array of RkRec structures. Each element in the
874 array specifies an RkRec in the row. The number of entries in the array
875 MUST be equal to the value given by the following formula:
877 Number of entries in rgrkrec = (colLast.col – colFirst.col +1)
879 colLast (2 bytes): A Col structure that specifies the last column in
880 the set of numeric cells within the sheet. This colLast.col value MUST
881 be greater than the colFirst.col value. */
886 XclAddress
aCurrXclPos(aXclPos
);
889 if (aXclPos
.mnCol
> aCurrXclPos
.mnCol
)
891 if (aIn
.GetRecLeft() <= 2)
894 sal_uInt16 nXF
= aIn
.ReaduInt16();
895 sal_Int32 nRkNum
= aIn
.ReadInt32();
897 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
898 if( GetAddressConverter().ConvertAddress( aScPos
, aCurrXclPos
, GetCurrScTab(), true ) )
900 GetXFRangeBuffer().SetXF( aScPos
, nXF
);
901 GetDocImport().setNumericCell(aScPos
, XclTools::GetDoubleFromRK(nRkNum
));
907 void ImportExcel::Mulblank()
909 /* rw (2 bytes): An Rw structure that specifies a row containing the blank
912 colFirst (2 bytes): A Col structure that specifies the first column in
913 the series of blank cells within the sheet. The value of colFirst.col
914 MUST be less than or equal to 254.
916 rgixfe (variable): An array of IXFCell structures. Each element of this
917 array contains an IXFCell structure corresponding to a blank cell in the
918 series. The number of entries in the array MUST be equal to the value
919 given by the following formula:
921 Number of entries in rgixfe = (colLast.col – colFirst.col +1)
923 colLast (2 bytes): A Col structure that specifies the last column in
924 the series of blank cells within the sheet. This colLast.col value MUST
925 be greater than colFirst.col value. */
930 XclAddress
aCurrXclPos(aXclPos
);
933 if (aXclPos
.mnCol
> aCurrXclPos
.mnCol
)
935 if (aIn
.GetRecLeft() <= 2)
938 sal_uInt16 nXF
= aIn
.ReaduInt16();
940 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
941 if( GetAddressConverter().ConvertAddress( aScPos
, aCurrXclPos
, GetCurrScTab(), true ) )
942 GetXFRangeBuffer().SetBlankXF( aScPos
, nXF
);
947 void ImportExcel::Rstring()
952 nXFIdx
= aIn
.ReaduInt16();
954 ScAddress
aScPos( ScAddress::UNINITIALIZED
);
955 if( !GetAddressConverter().ConvertAddress( aScPos
, aXclPos
, GetCurrScTab(), true ) )
958 // unformatted Unicode string with separate formatting information
959 XclImpString aString
;
960 aString
.Read( maStrm
);
962 // character formatting runs
963 if( !aString
.IsRich() )
964 aString
.ReadFormats( maStrm
);
966 GetXFRangeBuffer().SetXF( aScPos
, nXFIdx
);
967 XclImpStringHelper::SetToDocument(GetDocImport(), aScPos
, *this, aString
, nXFIdx
);
970 void ImportExcel::Cellmerging()
972 XclImpAddressConverter
& rAddrConv
= GetAddressConverter();
973 SCTAB nScTab
= GetCurrScTab();
975 sal_uInt16 nCount
= maStrm
.ReaduInt16();
979 if (maStrm
.GetRecLeft() < 8)
984 maStrm
>> aXclRange
; // 16-bit rows and columns
985 ScRange
aScRange( ScAddress::UNINITIALIZED
);
986 if( rAddrConv
.ConvertRange( aScRange
, aXclRange
, nScTab
, nScTab
, true ) )
988 const bool bTooSlowForFuzzing
= mbFuzzing
&& (aScRange
.aEnd
.Col() > 512 || aScRange
.aEnd
.Row() > 512);
989 if (!bTooSlowForFuzzing
)
990 GetXFRangeBuffer().SetMerge( aScRange
.aStart
.Col(), aScRange
.aStart
.Row(), aScRange
.aEnd
.Col(), aScRange
.aEnd
.Row() );
996 void ImportExcel::Olesize()
998 XclRange
aXclOleSize( ScAddress::UNINITIALIZED
);
1000 aXclOleSize
.Read( maStrm
, false );
1002 SCTAB nScTab
= GetCurrScTab();
1003 GetAddressConverter().ConvertRange( maScOleSize
, aXclOleSize
, nScTab
, nScTab
, false );
1006 void ImportExcel::Row34()
1008 sal_uInt16 nRow
, nRowHeight
, nGrbit
, nXF
;
1010 nRow
= aIn
.ReaduInt16();
1013 SCROW nScRow
= static_cast< SCROW
>( nRow
);
1015 if( !GetRoot().GetDoc().ValidRow( nScRow
) )
1018 nRowHeight
= aIn
.ReaduInt16(); // specify direct in Twips
1021 nRowHeight
= nRowHeight
& 0x7FFF; // Bit 15: Row Height not changed manually
1023 nRowHeight
= (GetBiff() == EXC_BIFF2
) ? 0x25 : 0x225;
1025 nGrbit
= aIn
.ReaduInt16();
1026 nXF
= aIn
.ReaduInt16();
1028 sal_uInt8 nLevel
= ::extract_value
< sal_uInt8
>( nGrbit
, 0, 3 );
1029 pRowOutlineBuff
->SetLevel( nScRow
, nLevel
, ::get_flag( nGrbit
, EXC_ROW_COLLAPSED
) );
1030 pColRowBuff
->SetRowSettings( nScRow
, nRowHeight
, nGrbit
);
1032 if( nGrbit
& EXC_ROW_USEDEFXF
)
1033 GetXFRangeBuffer().SetRowDefXF( nScRow
, nXF
& EXC_ROW_XFMASK
);
1036 void ImportExcel::Bof3()
1038 sal_uInt16 nSubType
;
1039 maStrm
.DisableDecryption();
1041 nSubType
= maStrm
.ReaduInt16();
1043 OSL_ENSURE( nSubType
!= 0x0100, "*ImportExcel::Bof3(): Biff3 as Workbook?!" );
1044 if( nSubType
== 0x0100 ) // Book
1045 pExcRoot
->eDateiTyp
= Biff3W
;
1046 else if( nSubType
== 0x0020 ) // Chart
1047 pExcRoot
->eDateiTyp
= Biff3C
;
1048 else if( nSubType
== 0x0040 ) // Macro
1049 pExcRoot
->eDateiTyp
= Biff3M
;
1050 else // #i51490# Excel interprets invalid indexes as worksheet
1051 pExcRoot
->eDateiTyp
= Biff3
;
1054 void ImportExcel::Array34()
1056 sal_uInt16 nFirstRow
, nLastRow
, nFormLen
;
1057 sal_uInt8 nFirstCol
, nLastCol
;
1059 nFirstRow
= aIn
.ReaduInt16();
1060 nLastRow
= aIn
.ReaduInt16();
1061 nFirstCol
= aIn
.ReaduInt8();
1062 nLastCol
= aIn
.ReaduInt8();
1063 aIn
.Ignore( (GetBiff() >= EXC_BIFF5
) ? 6 : 2 );
1064 nFormLen
= aIn
.ReaduInt16();
1066 std::unique_ptr
<ScTokenArray
> pResult
;
1068 if( GetRoot().GetDoc().ValidColRow( nLastCol
, nLastRow
) )
1070 // the read mark is now on the formula, length in nFormLen
1072 pFormConv
->Reset( ScAddress( static_cast<SCCOL
>(nFirstCol
),
1073 static_cast<SCROW
>(nFirstRow
), GetCurrScTab() ) );
1074 pFormConv
->Convert( pResult
, maStrm
, nFormLen
, true );
1076 SAL_WARN_IF(!pResult
, "sc", "+ImportExcel::Array34(): ScTokenArray is NULL!");
1081 ScDocumentImport
& rDoc
= GetDocImport();
1082 ScRange
aArrayRange(nFirstCol
, nFirstRow
, GetCurrScTab(), nLastCol
, nLastRow
, GetCurrScTab());
1083 rDoc
.setMatrixCells(aArrayRange
, *pResult
, formula::FormulaGrammar::GRAM_ENGLISH_XL_A1
);
1087 void ImportExcel::Defrowheight345()
1089 sal_uInt16 nFlags
, nDefHeight
;
1090 nFlags
= maStrm
.ReaduInt16();
1091 nDefHeight
= maStrm
.ReaduInt16();
1095 SAL_WARN("sc", "*ImportExcel::Defrowheight345(): pColRowBuff is NULL!");
1099 pColRowBuff
->SetDefHeight( nDefHeight
, nFlags
);
1102 void ImportExcel::TableOp()
1104 sal_uInt16 nFirstRow
= aIn
.ReaduInt16();
1105 sal_uInt16 nLastRow
= aIn
.ReaduInt16();
1106 sal_uInt8 nFirstCol
= aIn
.ReaduInt8();
1107 sal_uInt8 nLastCol
= aIn
.ReaduInt8();
1108 sal_uInt16 nGrbit
= aIn
.ReaduInt16();
1109 sal_uInt16 nInpRow
= aIn
.ReaduInt16();
1110 sal_uInt16 nInpCol
= aIn
.ReaduInt16();
1111 sal_uInt16 nInpRow2
= aIn
.ReaduInt16();
1112 sal_uInt16 nInpCol2
= aIn
.ReaduInt16();
1116 //shrink to smallish arbitrary value to not timeout
1117 nLastRow
= std::min
<sal_uInt16
>(nLastRow
, MAXROW_30
/ 2);
1120 if( GetRoot().GetDoc().ValidColRow( nLastCol
, nLastRow
) )
1122 if( nFirstCol
&& nFirstRow
)
1124 ScTabOpParam aTabOpParam
;
1125 aTabOpParam
.meMode
= (nGrbit
& EXC_TABLEOP_BOTH
) ? ScTabOpParam::Both
: ((nGrbit
& EXC_TABLEOP_ROW
) ? ScTabOpParam::Row
: ScTabOpParam::Column
);
1126 sal_uInt16 nCol
= nFirstCol
- 1;
1127 sal_uInt16 nRow
= nFirstRow
- 1;
1128 SCTAB nTab
= GetCurrScTab();
1129 switch (aTabOpParam
.meMode
)
1131 case ScTabOpParam::Column
:
1132 aTabOpParam
.aRefFormulaCell
.Set(
1133 static_cast<SCCOL
>(nFirstCol
),
1134 static_cast<SCROW
>(nFirstRow
- 1), nTab
, false,
1136 aTabOpParam
.aRefFormulaEnd
.Set(
1137 static_cast<SCCOL
>(nLastCol
),
1138 static_cast<SCROW
>(nFirstRow
- 1), nTab
, false,
1140 aTabOpParam
.aRefColCell
.Set( static_cast<SCCOL
>(nInpCol
),
1141 static_cast<SCROW
>(nInpRow
), nTab
, false, false,
1145 case ScTabOpParam::Row
:
1146 aTabOpParam
.aRefFormulaCell
.Set(
1147 static_cast<SCCOL
>(nFirstCol
- 1),
1148 static_cast<SCROW
>(nFirstRow
), nTab
, false, false,
1150 aTabOpParam
.aRefFormulaEnd
.Set(
1151 static_cast<SCCOL
>(nFirstCol
- 1),
1152 static_cast<SCROW
>(nLastRow
), nTab
, false, false,
1154 aTabOpParam
.aRefRowCell
.Set( static_cast<SCCOL
>(nInpCol
),
1155 static_cast<SCROW
>(nInpRow
), nTab
, false, false,
1159 case ScTabOpParam::Both
: // TWO-INPUT
1160 aTabOpParam
.aRefFormulaCell
.Set(
1161 static_cast<SCCOL
>(nFirstCol
- 1),
1162 static_cast<SCROW
>(nFirstRow
- 1), nTab
, false,
1164 aTabOpParam
.aRefRowCell
.Set( static_cast<SCCOL
>(nInpCol
),
1165 static_cast<SCROW
>(nInpRow
), nTab
, false, false,
1167 aTabOpParam
.aRefColCell
.Set( static_cast<SCCOL
>(nInpCol2
),
1168 static_cast<SCROW
>(nInpRow2
), nTab
, false, false,
1173 ScDocumentImport
& rDoc
= GetDocImport();
1174 ScRange
aTabOpRange(nCol
, nRow
, nTab
, nLastCol
, nLastRow
, nTab
);
1175 rDoc
.setTableOpCells(aTabOpRange
, aTabOpParam
);
1180 bTabTruncated
= true;
1181 GetTracer().TraceInvalidRow(nLastRow
, rD
.MaxRow());
1185 void ImportExcel::Bof4()
1187 sal_uInt16 nSubType
;
1188 maStrm
.DisableDecryption();
1190 nSubType
= maStrm
.ReaduInt16();
1192 if( nSubType
== 0x0100 ) // Book
1193 pExcRoot
->eDateiTyp
= Biff4W
;
1194 else if( nSubType
== 0x0020 ) // Chart
1195 pExcRoot
->eDateiTyp
= Biff4C
;
1196 else if( nSubType
== 0x0040 ) // Macro
1197 pExcRoot
->eDateiTyp
= Biff4M
;
1198 else // #i51490# Excel interprets invalid indexes as worksheet
1199 pExcRoot
->eDateiTyp
= Biff4
;
1202 void ImportExcel::Bof5()
1204 //POST: eDateiTyp = Type of the file to be read
1205 sal_uInt16 nSubType
, nVers
;
1208 maStrm
.DisableDecryption();
1209 nVers
= maStrm
.ReaduInt16();
1210 nSubType
= maStrm
.ReaduInt16( );
1214 case 0x0005: eDatei
= Biff5W
; break; // workbook globals
1215 case 0x0006: eDatei
= Biff5V
; break; // VB module
1216 case 0x0020: eDatei
= Biff5C
; break; // chart
1217 case 0x0040: eDatei
= Biff5M4
; break; // macro sheet
1218 case 0x0010: // worksheet
1219 default: eDatei
= Biff5
; break; // tdf#144732 Excel interprets invalid indexes as worksheet
1222 if( nVers
== 0x0600 && (GetBiff() == EXC_BIFF8
) )
1223 eDatei
= static_cast<BiffTyp
>( eDatei
- Biff5
+ Biff8
);
1225 pExcRoot
->eDateiTyp
= eDatei
;
1228 void ImportExcel::EndSheet()
1230 pExcRoot
->pExtSheetBuff
->Reset();
1232 if( GetBiff() <= EXC_BIFF5
)
1234 pExcRoot
->pExtNameBuff
->Reset();
1241 void ImportExcel::NewTable()
1243 SCTAB nTab
= GetCurrScTab();
1244 if( nTab
> 0 && !rD
.HasTable( nTab
) )
1245 rD
.MakeTable( nTab
);
1247 if (nTab
== 0 && GetBiff() == EXC_BIFF2
)
1249 // For Excel 2.1 Worksheet file, we need to set the file name as the
1251 INetURLObject
aURL(GetDocUrl());
1252 rD
.RenameTab(0, aURL
.getBase());
1255 pExcRoot
->pShrfmlaBuff
->Clear();
1256 maLastFormulaCells
.clear();
1257 mpLastFormula
= nullptr;
1259 InitializeTable( nTab
);
1261 XclImpOutlineDataBuffer
* pNewItem
= new XclImpOutlineDataBuffer( GetRoot(), nTab
);
1262 pOutlineListBuffer
->push_back( std::unique_ptr
<XclImpOutlineDataBuffer
>(pNewItem
) );
1263 pExcRoot
->pColRowBuff
= pColRowBuff
= pNewItem
->GetColRowBuff();
1264 pColOutlineBuff
= pNewItem
->GetColOutline();
1265 pRowOutlineBuff
= pNewItem
->GetRowOutline();
1268 std::unique_ptr
<ScTokenArray
> ImportExcel::ErrorToFormula( bool bErrOrVal
, sal_uInt8 nError
, double& rVal
)
1270 return pFormConv
->GetBoolErr( XclTools::ErrorToEnum( rVal
, bErrOrVal
, nError
) );
1273 void ImportExcel::AdjustRowHeight()
1275 /* Speed up chart import: import all sheets without charts, then
1276 update row heights (here), last load all charts -> do not any longer
1277 update inside of ScDocShell::ConvertFrom() (causes update of existing
1278 charts during each and every change of row height). */
1279 if( ScModelObj
* pDocObj
= GetDocModelObj() )
1280 pDocObj
->UpdateAllRowHeights();
1283 void ImportExcel::PostDocLoad()
1285 /* Set automatic page numbering in Default page style (default is "page number = 1").
1286 Otherwise hidden tables (i.e. for scenarios) which have Default page style will
1287 break automatic page numbering. */
1288 if( SfxStyleSheetBase
* pStyleSheet
= GetStyleSheetPool().Find( ScResId( STR_STYLENAME_STANDARD
), SfxStyleFamily::Page
) )
1289 pStyleSheet
->GetItemSet().Put( SfxUInt16Item( ATTR_PAGE_FIRSTPAGENO
, 0 ) );
1291 // outlines for all sheets, sets hidden rows and columns (#i11776# after filtered ranges)
1292 for (auto& rxBuffer
: *pOutlineListBuffer
)
1293 rxBuffer
->Convert();
1295 // document view settings (before visible OLE area)
1296 GetDocViewSettings().Finalize();
1298 // process all drawing objects (including OLE, charts, controls; after hiding rows/columns; before visible OLE area)
1299 GetObjectManager().ConvertObjects();
1301 // visible area (used if this document is an embedded OLE object)
1302 if( ScDocShell
* pDocShell
= GetDocShell() )
1304 // visible area if embedded
1305 const ScExtDocSettings
& rDocSett
= GetExtDocOptions().GetDocSettings();
1306 SCTAB nDisplScTab
= rDocSett
.mnDisplTab
;
1308 /* #i44077# If a new OLE object is inserted from file, there is no
1309 OLESIZE record in the Excel file. Calculate used area from file
1310 contents (used cells and drawing objects). */
1311 if( !maScOleSize
.IsValid() )
1313 // used area of displayed sheet (cell contents)
1314 if( const ScExtTabSettings
* pTabSett
= GetExtDocOptions().GetTabSettings( nDisplScTab
) )
1315 maScOleSize
= pTabSett
->maUsedArea
;
1316 // add all valid drawing objects
1317 ScRange aScObjArea
= GetObjectManager().GetUsedArea( nDisplScTab
);
1318 if( aScObjArea
.IsValid() )
1319 maScOleSize
.ExtendTo( aScObjArea
);
1322 // valid size found - set it at the document
1323 if( maScOleSize
.IsValid() )
1325 pDocShell
->SetVisArea( GetDoc().GetMMRect(
1326 maScOleSize
.aStart
.Col(), maScOleSize
.aStart
.Row(),
1327 maScOleSize
.aEnd
.Col(), maScOleSize
.aEnd
.Row(), nDisplScTab
) );
1328 GetDoc().SetVisibleTab( nDisplScTab
);
1332 // open forms in alive mode (has no effect, if no controls in document)
1333 if( ScModelObj
* pDocObj
= GetDocModelObj() )
1334 pDocObj
->setPropertyValue( SC_UNO_APPLYFMDES
, uno::Any( false ) );
1336 // enables extended options to be set to the view after import
1337 GetExtDocOptions().SetChanged( true );
1339 // root data owns the extended document options -> create a new object
1340 GetDoc().SetExtDocOptions( std::make_unique
<ScExtDocOptions
>( GetExtDocOptions() ) );
1342 const SCTAB nLast
= rD
.GetTableCount();
1345 if( GetRoot().GetPrintAreaBuffer().HasRanges() )
1347 for( SCTAB n
= 0 ; n
< nLast
; n
++ )
1349 p
= GetRoot().GetPrintAreaBuffer().First(n
);
1352 rD
.ClearPrintRanges( n
);
1355 rD
.AddPrintRange( n
, *p
);
1356 p
= GetRoot().GetPrintAreaBuffer().Next();
1361 // #i4063# no print ranges -> print entire sheet
1362 rD
.SetPrintEntireSheet( n
);
1365 GetTracer().TracePrintRange();
1368 if( !GetRoot().GetTitleAreaBuffer().HasRanges() )
1371 for( SCTAB n
= 0 ; n
< nLast
; n
++ )
1373 p
= GetRoot().GetTitleAreaBuffer().First(n
);
1376 bool bRowVirgin
= true;
1377 bool bColVirgin
= true;
1381 if( p
->aStart
.Col() == 0 && p
->aEnd
.Col() == rD
.MaxCol() && bRowVirgin
)
1383 rD
.SetRepeatRowRange( n
, *p
);
1387 if( p
->aStart
.Row() == 0 && p
->aEnd
.Row() == rD
.MaxRow() && bColVirgin
)
1389 rD
.SetRepeatColRange( n
, *p
);
1393 p
= GetRoot().GetTitleAreaBuffer().Next();
1399 XclImpOutlineDataBuffer::XclImpOutlineDataBuffer( const XclImpRoot
& rRoot
, SCTAB nScTab
) :
1400 XclImpRoot( rRoot
),
1401 mxColOutlineBuff( std::make_shared
<XclImpOutlineBuffer
>( rRoot
.GetXclMaxPos().Col() + 1 ) ),
1402 mxRowOutlineBuff( std::make_shared
<XclImpOutlineBuffer
>( rRoot
.GetXclMaxPos().Row() + 1 ) ),
1403 mxColRowBuff( std::make_shared
<XclImpColRowSettings
>( rRoot
) ),
1408 XclImpOutlineDataBuffer::~XclImpOutlineDataBuffer()
1412 void XclImpOutlineDataBuffer::Convert()
1414 mxColOutlineBuff
->SetOutlineArray( &GetDoc().GetOutlineTable( mnScTab
, true )->GetColArray() );
1415 mxColOutlineBuff
->MakeScOutline();
1417 mxRowOutlineBuff
->SetOutlineArray( &GetDoc().GetOutlineTable( mnScTab
, true )->GetRowArray() );
1418 mxRowOutlineBuff
->MakeScOutline();
1420 mxColRowBuff
->ConvertHiddenFlags( mnScTab
);
1423 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */