1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sfx2/objsh.hxx>
21 #include <rtl/ustring.hxx>
23 #include <document.hxx>
24 #include <scextopt.hxx>
25 #include <docoptio.hxx>
26 #include <tabprotection.hxx>
31 #include <xeextlst.hxx>
32 #include <biffhelper.hxx>
34 #include <xcl97rec.hxx>
35 #include <xetable.hxx>
39 #include <xecontent.hxx>
40 #include <xeescher.hxx>
41 #include <xepivot.hxx>
42 #include <XclExpChangeTrack.hxx>
43 #include <xepivotxml.hxx>
44 #include <xedbdata.hxx>
45 #include <xlcontent.hxx>
48 #include <xltools.hxx>
50 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
51 #include <oox/token/tokens.hxx>
52 #include <oox/token/namespaces.hxx>
57 static OUString
lcl_GetVbaTabName( SCTAB n
)
59 OUString aRet
= "__VBA__" + OUString::number( static_cast<sal_uInt16
>(n
) );
63 static void lcl_AddBookviews( XclExpRecordList
<>& aRecList
, const ExcTable
& self
)
65 aRecList
.AppendNewRecord( new XclExpXmlStartElementRecord( XML_bookViews
) );
66 aRecList
.AppendNewRecord( new XclExpWindow1( self
.GetRoot() ) );
67 aRecList
.AppendNewRecord( new XclExpXmlEndElementRecord( XML_bookViews
) );
70 static void lcl_AddCalcPr( XclExpRecordList
<>& aRecList
, const ExcTable
& self
)
72 ScDocument
& rDoc
= self
.GetDoc();
74 aRecList
.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_calcPr
) );
75 // OOXTODO: calcCompleted, calcId, calcMode, calcOnSave,
76 // concurrentCalc, concurrentManualCount,
77 // forceFullCalc, fullCalcOnLoad, fullPrecision
78 aRecList
.AppendNewRecord( new XclCalccount( rDoc
) );
79 aRecList
.AppendNewRecord( new XclRefmode( rDoc
) );
80 aRecList
.AppendNewRecord( new XclIteration( rDoc
) );
81 aRecList
.AppendNewRecord( new XclDelta( rDoc
) );
82 aRecList
.AppendNewRecord( new XclExpBoolRecord(oox::xls::BIFF_ID_SAVERECALC
, true) );
83 aRecList
.AppendNewRecord( new XclExpXmlEndSingleElementRecord() ); // XML_calcPr
86 static void lcl_AddWorkbookProtection( XclExpRecordList
<>& aRecList
, const ExcTable
& self
)
88 aRecList
.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_workbookProtection
) );
90 const ScDocProtection
* pProtect
= self
.GetDoc().GetDocProtection();
91 if (pProtect
&& pProtect
->isProtected())
93 aRecList
.AppendNewRecord( new XclExpWindowProtection(pProtect
->isOptionEnabled(ScDocProtection::WINDOWS
)) );
94 aRecList
.AppendNewRecord( new XclExpProtection(pProtect
->isOptionEnabled(ScDocProtection::STRUCTURE
)) );
95 aRecList
.AppendNewRecord( new XclExpPassHash(pProtect
->getPasswordHash(PASSHASH_XL
)) );
98 aRecList
.AppendNewRecord( new XclExpXmlEndSingleElementRecord() ); // XML_workbookProtection
101 static void lcl_AddScenariosAndFilters( XclExpRecordList
<>& aRecList
, const XclExpRoot
& rRoot
, SCTAB nScTab
)
104 aRecList
.AppendNewRecord( new ExcEScenarioManager( rRoot
, nScTab
) );
106 aRecList
.AppendRecord( rRoot
.GetFilterManager().CreateRecord( nScTab
) );
109 ExcTable::ExcTable( const XclExpRoot
& rRoot
) :
111 mnScTab( SCTAB_GLOBAL
),
112 nExcTab( EXC_NOTAB
),
113 mxNoteList( new XclExpNoteList
)
117 ExcTable::ExcTable( const XclExpRoot
& rRoot
, SCTAB nScTab
) :
120 nExcTab( rRoot
.GetTabInfo().GetXclTab( nScTab
) ),
121 mxNoteList( new XclExpNoteList
)
125 ExcTable::~ExcTable()
129 void ExcTable::Add( XclExpRecordBase
* pRec
)
131 OSL_ENSURE( pRec
, "-ExcTable::Add(): pRec is NULL!" );
132 aRecList
.AppendNewRecord( pRec
);
135 void ExcTable::FillAsHeaderBinary( ExcBoundsheetList
& rBoundsheetList
)
139 RootData
& rR
= GetOldRoot();
140 ScDocument
& rDoc
= GetDoc();
141 XclExpTabInfo
& rTabInfo
= GetTabInfo();
143 if ( GetBiff() <= EXC_BIFF5
)
148 sal_uInt16 nExcTabCount
= rTabInfo
.GetXclTabCount();
149 sal_uInt16 nCodenames
= static_cast< sal_uInt16
>( GetExtDocOptions().GetCodeNameCount() );
151 SfxObjectShell
* pShell
= GetDocShell();
152 sal_uInt16 nWriteProtHash
= pShell
? pShell
->GetModifyPasswordHash() : 0;
153 bool bRecommendReadOnly
= pShell
&& pShell
->IsLoadReadonly();
155 if( (nWriteProtHash
> 0) || bRecommendReadOnly
)
156 Add( new XclExpEmptyRecord( EXC_ID_WRITEPROT
) );
158 // TODO: correct codepage for BIFF5?
159 sal_uInt16 nCodePage
= XclTools::GetXclCodePage( (GetBiff() <= EXC_BIFF5
) ? RTL_TEXTENCODING_MS_1252
: RTL_TEXTENCODING_UNICODE
);
161 if( GetBiff() <= EXC_BIFF5
)
163 Add( new XclExpEmptyRecord( EXC_ID_INTERFACEHDR
) );
164 Add( new XclExpUInt16Record( EXC_ID_MMS
, 0 ) );
165 Add( new XclExpEmptyRecord( EXC_ID_TOOLBARHDR
) );
166 Add( new XclExpEmptyRecord( EXC_ID_TOOLBAREND
) );
167 Add( new XclExpEmptyRecord( EXC_ID_INTERFACEEND
) );
168 Add( new ExcDummy_00
);
172 if( IsDocumentEncrypted() )
173 Add( new XclExpFileEncryption( GetRoot() ) );
174 Add( new XclExpInterfaceHdr( nCodePage
) );
175 Add( new XclExpUInt16Record( EXC_ID_MMS
, 0 ) );
176 Add( new XclExpInterfaceEnd
);
177 Add( new XclExpWriteAccess
);
180 Add( new XclExpFileSharing( GetRoot(), nWriteProtHash
, bRecommendReadOnly
) );
181 Add( new XclExpUInt16Record( EXC_ID_CODEPAGE
, nCodePage
) );
183 if( GetBiff() == EXC_BIFF8
)
185 Add( new XclExpBoolRecord( EXC_ID_DSF
, false ) );
186 Add( new XclExpEmptyRecord( EXC_ID_XL9FILE
) );
187 rR
.pTabId
= new XclExpChTrTabId( std::max( nExcTabCount
, nCodenames
) );
189 if( HasVbaStorage() )
191 Add( new XclObproj
);
192 const OUString
& rCodeName
= GetExtDocOptions().GetDocSettings().maGlobCodeName
;
193 if( !rCodeName
.isEmpty() )
194 Add( new XclCodename( rCodeName
) );
198 Add( new XclExpUInt16Record( EXC_ID_FNGROUPCOUNT
, 14 ) );
200 if ( GetBiff() <= EXC_BIFF5
)
202 // global link table: EXTERNCOUNT, EXTERNSHEET, NAME
203 aRecList
.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET
) );
204 aRecList
.AppendRecord( CreateRecord( EXC_ID_NAME
) );
207 // document protection options
208 lcl_AddWorkbookProtection( aRecList
, *this );
210 if( GetBiff() == EXC_BIFF8
)
212 Add( new XclExpProt4Rev
);
213 Add( new XclExpProt4RevPass
);
216 lcl_AddBookviews( aRecList
, *this );
218 Add( new XclExpXmlStartSingleElementRecord( XML_workbookPr
) );
219 if ( GetBiff() == EXC_BIFF8
&& GetOutput() != EXC_OUTPUT_BINARY
)
221 Add( new XclExpBoolRecord(0x0040, false, XML_backupFile
) ); // BACKUP
222 Add( new XclExpBoolRecord(0x008D, false, XML_showObjects
) ); // HIDEOBJ
225 if ( GetBiff() == EXC_BIFF8
)
227 Add( new XclExpBoolRecord(0x0040, false) ); // BACKUP
228 Add( new XclExpBoolRecord(0x008D, false) ); // HIDEOBJ
231 if( GetBiff() <= EXC_BIFF5
)
233 Add( new ExcDummy_040
);
234 Add( new Exc1904( rDoc
) );
235 Add( new ExcDummy_041
);
240 Add( new Exc1904( rDoc
) );
241 Add( new XclExpBoolRecord( 0x000E, !rDoc
.GetDocOptions().IsCalcAsShown() ) );
242 Add( new XclExpBoolRecord(0x01B7, false) ); // REFRESHALL
243 Add( new XclExpBoolRecord(0x00DA, false) ); // BOOKBOOL
246 // Formatting: FONT, FORMAT, XF, STYLE, PALETTE
247 aRecList
.AppendRecord( CreateRecord( EXC_ID_FONTLIST
) );
248 aRecList
.AppendRecord( CreateRecord( EXC_ID_FORMATLIST
) );
249 aRecList
.AppendRecord( CreateRecord( EXC_ID_XFLIST
) );
250 aRecList
.AppendRecord( CreateRecord( EXC_ID_PALETTE
) );
253 SCTAB nScTabCount
= rTabInfo
.GetScTabCount();
254 if( GetBiff() <= EXC_BIFF5
)
257 for( nC
= 0 ; nC
< nScTabCount
; nC
++ )
258 if( rTabInfo
.IsExportTab( nC
) )
260 ExcBoundsheetList::RecordRefType
xBoundsheet( new ExcBundlesheet( rR
, nC
) );
261 aRecList
.AppendRecord( xBoundsheet
);
262 rBoundsheetList
.AppendRecord( xBoundsheet
);
268 GetPivotTableManager().CreatePivotTables();
269 aRecList
.AppendRecord( GetPivotTableManager().CreatePivotCachesRecord() );
272 if( rDoc
.GetChangeTrack() )
274 rR
.pUserBViewList
= new XclExpUserBViewList( *rDoc
.GetChangeTrack() );
275 Add( rR
.pUserBViewList
);
278 // Natural Language Formulas Flag
279 aRecList
.AppendNewRecord( new XclExpBoolRecord( EXC_ID_USESELFS
, GetDoc().GetDocOptions().IsLookUpColRowNames() ) );
282 for( nC
= 0 ; nC
< nScTabCount
; nC
++ )
283 if( rTabInfo
.IsExportTab( nC
) )
285 ExcBoundsheetList::RecordRefType
xBoundsheet( new ExcBundlesheet8( rR
, nC
) );
286 aRecList
.AppendRecord( xBoundsheet
);
287 rBoundsheetList
.AppendRecord( xBoundsheet
);
291 for( SCTAB nAdd
= 0; nC
< static_cast<SCTAB
>(nCodenames
) ; nC
++, nAdd
++ )
293 aTmpString
= lcl_GetVbaTabName( nAdd
);
294 ExcBoundsheetList::RecordRefType
xBoundsheet( new ExcBundlesheet8( aTmpString
) );
295 aRecList
.AppendRecord( xBoundsheet
);
296 rBoundsheetList
.AppendRecord( xBoundsheet
);
299 // COUNTRY - in BIFF8 in workbook globals
300 Add( new XclExpCountry( GetRoot() ) );
302 // link table: SUPBOOK, XCT, CRN, EXTERNNAME, EXTERNSHEET, NAME
303 aRecList
.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET
) );
304 aRecList
.AppendRecord( CreateRecord( EXC_ID_NAME
) );
306 Add( new XclExpRecalcId
);
308 // MSODRAWINGGROUP per-document data
309 aRecList
.AppendRecord( GetObjectManager().CreateDrawingGroup() );
310 // Shared string table: SST, EXTSST
311 aRecList
.AppendRecord( CreateRecord( EXC_ID_SST
) );
313 Add( new XclExpBookExt
);
319 void ExcTable::FillAsHeaderXml( ExcBoundsheetList
& rBoundsheetList
)
323 RootData
& rR
= GetOldRoot();
324 ScDocument
& rDoc
= GetDoc();
325 XclExpTabInfo
& rTabInfo
= GetTabInfo();
327 sal_uInt16 nExcTabCount
= rTabInfo
.GetXclTabCount();
328 sal_uInt16 nCodenames
= static_cast< sal_uInt16
>( GetExtDocOptions().GetCodeNameCount() );
330 rR
.pTabId
= new XclExpChTrTabId( std::max( nExcTabCount
, nCodenames
) );
333 Add( new XclExpXmlStartSingleElementRecord( XML_workbookPr
) );
334 Add( new XclExpBoolRecord(0x0040, false, XML_backupFile
) ); // BACKUP
335 Add( new XclExpBoolRecord(0x008D, false, XML_showObjects
) ); // HIDEOBJ
337 Add( new Exc1904( rDoc
) );
338 // OOXTODO: The following /workbook/workbookPr attributes are mapped
339 // to various BIFF records that are not currently supported:
341 // XML_allowRefreshQuery: QSISTAG 802h: fEnableRefresh
342 // XML_autoCompressPictures: COMPRESSPICTURES 89Bh: fAutoCompressPictures
343 // XML_checkCompatibility: COMPAT12 88Ch: fNoCompatChk
344 // XML_codeName: "Calc"
345 // XML_defaultThemeVersion: ???
346 // XML_filterPrivacy: BOOKEXT 863h: fFilterPrivacy
347 // XML_hidePivotFieldList: BOOKBOOL DAh: fHidePivotTableFList
348 // XML_promptedSolutions: BOOKEXT 863h: fBuggedUserAboutSolution
349 // XML_publishItems: NAMEPUBLISH 893h: fPublished
350 // XML_saveExternalLinkValues: BOOKBOOL DAh: fNoSavSupp
351 // XML_showBorderUnselectedTables: BOOKBOOL DAh: fHideBorderUnsels
352 // XML_showInkAnnotation: BOOKEXT 863h: fShowInkAnnotation
353 // XML_showPivotChart: PIVOTCHARTBITS 859h: fGXHide??
354 // XML_updateLinks: BOOKBOOL DAh: grbitUpdateLinks
355 Add( new XclExpXmlEndSingleElementRecord() ); // XML_workbookPr
357 // Formatting: FONT, FORMAT, XF, STYLE, PALETTE
358 aRecList
.AppendNewRecord( new XclExpXmlStyleSheet( *this ) );
361 if( rDoc
.GetChangeTrack() )
363 rR
.pUserBViewList
= new XclExpUserBViewList( *rDoc
.GetChangeTrack() );
364 Add( rR
.pUserBViewList
);
367 lcl_AddWorkbookProtection( aRecList
, *this );
368 lcl_AddBookviews( aRecList
, *this );
372 SCTAB nScTabCount
= rTabInfo
.GetScTabCount();
373 aRecList
.AppendNewRecord( new XclExpXmlStartElementRecord( XML_sheets
) );
374 for( nC
= 0 ; nC
< nScTabCount
; nC
++ )
375 if( rTabInfo
.IsExportTab( nC
) )
377 ExcBoundsheetList::RecordRefType
xBoundsheet( new ExcBundlesheet8( rR
, nC
) );
378 aRecList
.AppendRecord( xBoundsheet
);
379 rBoundsheetList
.AppendRecord( xBoundsheet
);
381 aRecList
.AppendNewRecord( new XclExpXmlEndElementRecord( XML_sheets
) );
384 for( SCTAB nAdd
= 0; nC
< static_cast<SCTAB
>(nCodenames
) ; nC
++, nAdd
++ )
386 aTmpString
= lcl_GetVbaTabName( nAdd
);
387 ExcBoundsheetList::RecordRefType
xBoundsheet( new ExcBundlesheet8( aTmpString
) );
388 aRecList
.AppendRecord( xBoundsheet
);
389 rBoundsheetList
.AppendRecord( xBoundsheet
);
392 // link table: SUPBOOK, XCT, CRN, EXTERNNAME, EXTERNSHEET, NAME
393 aRecList
.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET
) );
394 aRecList
.AppendRecord( CreateRecord( EXC_ID_NAME
) );
396 lcl_AddCalcPr( aRecList
, *this );
398 // MSODRAWINGGROUP per-document data
399 aRecList
.AppendRecord( GetObjectManager().CreateDrawingGroup() );
400 // Shared string table: SST, EXTSST
401 aRecList
.AppendRecord( CreateRecord( EXC_ID_SST
) );
404 void ExcTable::FillAsTableBinary( SCTAB nCodeNameIdx
)
406 InitializeTable( mnScTab
);
408 RootData
& rR
= GetOldRoot();
409 XclBiff eBiff
= GetBiff();
410 ScDocument
& rDoc
= GetDoc();
412 OSL_ENSURE( (mnScTab
>= 0) && (mnScTab
<= MAXTAB
), "-ExcTable::Table(): mnScTab - no ordinary table!" );
413 OSL_ENSURE( nExcTab
<= static_cast<sal_uInt16
>(MAXTAB
), "-ExcTable::Table(): nExcTab - no ordinary table!" );
415 // create a new OBJ list for this sheet (may be used by notes, autofilter, data validation)
416 if( eBiff
== EXC_BIFF8
)
417 GetObjectManager().StartSheet();
419 // cell table: DEFROWHEIGHT, DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
420 mxCellTable
.reset( new XclExpCellTable( GetRoot() ) );
423 std::vector
<sc::NoteEntry
> aNotes
;
424 rDoc
.GetAllNoteEntries(aNotes
);
425 for (const auto& rNote
: aNotes
)
427 if (rNote
.maPos
.Tab() != mnScTab
)
430 mxNoteList
->AppendNewRecord(new XclExpNote(GetRoot(), rNote
.maPos
, rNote
.mpNote
, OUString()));
433 // WSBOOL needs data from page settings, create it here, add it later
434 std::shared_ptr
< XclExpPageSettings
> xPageSett( new XclExpPageSettings( GetRoot() ) );
435 bool bFitToPages
= xPageSett
->GetPageData().mbFitToPages
;
437 if( eBiff
<= EXC_BIFF5
)
440 Add( new ExcDummy_02a
);
445 lcl_AddCalcPr( aRecList
, *this );
448 // GUTS (count & size of outline icons)
449 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_GUTS
) );
450 // DEFROWHEIGHT, created by the cell table
451 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID2_DEFROWHEIGHT
) );
453 // COUNTRY - in BIFF5/7 in every worksheet
454 if( eBiff
<= EXC_BIFF5
)
455 Add( new XclExpCountry( GetRoot() ) );
457 Add( new XclExpWsbool( bFitToPages
) );
459 // page settings (SETUP and various other records)
460 aRecList
.AppendRecord( xPageSett
);
462 const ScTableProtection
* pTabProtect
= rDoc
.GetTabProtection(mnScTab
);
463 if (pTabProtect
&& pTabProtect
->isProtected())
465 Add( new XclExpProtection(true) );
466 Add( new XclExpBoolRecord(oox::xls::BIFF_ID_SCENPROTECT
, pTabProtect
->isOptionEnabled(ScTableProtection::SCENARIOS
)) );
467 if (pTabProtect
->isOptionEnabled(ScTableProtection::OBJECTS
))
468 Add( new XclExpBoolRecord(oox::xls::BIFF_ID_OBJECTPROTECT
, true ));
469 Add( new XclExpPassHash(pTabProtect
->getPasswordHash(PASSHASH_XL
)) );
472 // local link table: EXTERNCOUNT, EXTERNSHEET
473 if( eBiff
<= EXC_BIFF5
)
474 aRecList
.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET
) );
476 if ( eBiff
== EXC_BIFF8
)
477 lcl_AddScenariosAndFilters( aRecList
, GetRoot(), mnScTab
);
479 // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
480 aRecList
.AppendRecord( mxCellTable
);
482 // MERGEDCELLS record, generated by the cell table
483 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_MERGEDCELLS
) );
485 if( eBiff
== EXC_BIFF8
)
486 Add( new XclExpLabelranges( GetRoot() ) );
487 // data validation (DVAL and list of DV records), generated by the cell table
488 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_DVAL
) );
490 if( eBiff
== EXC_BIFF8
)
492 // all MSODRAWING and OBJ stuff of this sheet goes here
493 aRecList
.AppendRecord( GetObjectManager().ProcessDrawing( GetSdrPage( mnScTab
) ) );
495 aRecList
.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab
) );
498 // list of NOTE records, generated by the cell table
499 aRecList
.AppendRecord( mxNoteList
);
501 // sheet view settings: WINDOW2, SCL, PANE, SELECTION
502 aRecList
.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab
) );
504 if( eBiff
== EXC_BIFF8
)
506 // sheet protection options
507 Add( new XclExpSheetProtectOptions( GetRoot(), mnScTab
) );
509 // enhanced protections if there are
512 const ::std::vector
<ScEnhancedProtection
>& rProts( pTabProtect
->getEnhancedProtection());
513 for (const auto& rProt
: rProts
)
515 Add( new XclExpSheetEnhancedProtection( GetRoot(), rProt
));
520 Add( new XclExpWebQueryBuffer( GetRoot() ) );
522 // conditional formats
523 Add( new XclExpCondFormatBuffer( GetRoot(), XclExtLstRef() ) );
525 if( HasVbaStorage() )
526 if( nCodeNameIdx
< GetExtDocOptions().GetCodeNameCount() )
527 Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx
) ) );
530 // list of HLINK records, generated by the cell table
531 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_HLINK
) );
534 if( rR
.pUserBViewList
)
536 XclExpUserBViewList::const_iterator iter
;
537 for ( iter
= rR
.pUserBViewList
->cbegin(); iter
!= rR
.pUserBViewList
->cend(); ++iter
)
539 Add( new XclExpUsersViewBegin( (*iter
).GetGUID(), nExcTab
) );
540 Add( new XclExpUsersViewEnd
);
548 void ExcTable::FillAsTableXml()
550 InitializeTable( mnScTab
);
552 ScDocument
& rDoc
= GetDoc();
554 OSL_ENSURE( (mnScTab
>= 0) && (mnScTab
<= MAXTAB
), "-ExcTable::Table(): mnScTab - no ordinary table!" );
555 OSL_ENSURE( nExcTab
<= static_cast<sal_uInt16
>(MAXTAB
), "-ExcTable::Table(): nExcTab - no ordinary table!" );
557 // create a new OBJ list for this sheet (may be used by notes, autofilter, data validation)
558 GetObjectManager().StartSheet();
560 // cell table: DEFROWHEIGHT, DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
561 mxCellTable
.reset( new XclExpCellTable( GetRoot() ) );
564 std::vector
<sc::NoteEntry
> aNotes
;
565 rDoc
.GetAllNoteEntries(aNotes
);
566 for (const auto& rNote
: aNotes
)
568 if (rNote
.maPos
.Tab() != mnScTab
)
571 mxNoteList
->AppendNewRecord(new XclExpNote(GetRoot(), rNote
.maPos
, rNote
.mpNote
, OUString()));
574 // WSBOOL needs data from page settings, create it here, add it later
575 std::shared_ptr
< XclExpPageSettings
> xPageSett( new XclExpPageSettings( GetRoot() ) );
576 XclExtLstRef
xExtLst( new XclExtLst( GetRoot() ) );
577 bool bFitToPages
= xPageSett
->GetPageData().mbFitToPages
;
579 Color aTabColor
= GetRoot().GetDoc().GetTabBgColor(mnScTab
);
580 Add(new XclExpXmlSheetPr(bFitToPages
, mnScTab
, aTabColor
, &GetFilterManager()));
582 // GUTS (count & size of outline icons)
583 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_GUTS
) );
584 // DEFROWHEIGHT, created by the cell table
585 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID2_DEFROWHEIGHT
) );
587 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID3_DIMENSIONS
) );
589 // sheet view settings: WINDOW2, SCL, PANE, SELECTION
590 aRecList
.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab
) );
592 // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
593 aRecList
.AppendRecord( mxCellTable
);
595 // list of NOTE records, generated by the cell table
596 // not in the worksheet file
597 if( mxNoteList
!= nullptr && !mxNoteList
->IsEmpty() )
598 aRecList
.AppendNewRecord( new XclExpComments( mnScTab
, *mxNoteList
) );
600 const ScTableProtection
* pTabProtect
= rDoc
.GetTabProtection(mnScTab
);
601 if (pTabProtect
&& pTabProtect
->isProtected())
602 Add( new XclExpSheetProtection(true, mnScTab
) );
604 lcl_AddScenariosAndFilters( aRecList
, GetRoot(), mnScTab
);
606 // MERGEDCELLS record, generated by the cell table
607 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_MERGEDCELLS
) );
609 // conditional formats
610 Add( new XclExpCondFormatBuffer( GetRoot(), xExtLst
) );
612 // data validation (DVAL and list of DV records), generated by the cell table
613 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_DVAL
) );
615 // list of HLINK records, generated by the cell table
616 XclExpRecordRef xHyperlinks
= mxCellTable
->CreateRecord( EXC_ID_HLINK
);
617 XclExpHyperlinkList
* pHyperlinkList
= dynamic_cast<XclExpHyperlinkList
*>(xHyperlinks
.get());
618 if( pHyperlinkList
!= nullptr && !pHyperlinkList
->IsEmpty() )
620 aRecList
.AppendNewRecord( new XclExpXmlStartElementRecord( XML_hyperlinks
) );
621 aRecList
.AppendRecord( xHyperlinks
);
622 aRecList
.AppendNewRecord( new XclExpXmlEndElementRecord( XML_hyperlinks
) );
625 aRecList
.AppendRecord( xPageSett
);
627 // all MSODRAWING and OBJ stuff of this sheet goes here
628 aRecList
.AppendRecord( GetObjectManager().ProcessDrawing( GetSdrPage( mnScTab
) ) );
630 XclExpImgData
* pImgData
= xPageSett
->getGraphicExport();
632 aRecList
.AppendRecord(std::shared_ptr
<XclExpRecordBase
>(pImgData
));
634 // <tableParts> after <drawing> and before <extLst>
635 aRecList
.AppendRecord( GetTablesManager().GetTablesBySheet( mnScTab
));
637 aRecList
.AppendRecord( xExtLst
);
640 void ExcTable::FillAsEmptyTable( SCTAB nCodeNameIdx
)
642 InitializeTable( mnScTab
);
644 if( HasVbaStorage() && (nCodeNameIdx
< GetExtDocOptions().GetCodeNameCount()) )
646 if( GetBiff() <= EXC_BIFF5
)
653 Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx
) ) );
655 // sheet view settings: WINDOW2, SCL, PANE, SELECTION
656 aRecList
.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab
) );
661 void ExcTable::Write( XclExpStream
& rStrm
)
663 SetCurrScTab( mnScTab
);
664 if( mxCellTable
.get() )
665 mxCellTable
->Finalize(true);
666 aRecList
.Save( rStrm
);
669 void ExcTable::WriteXml( XclExpXmlStream
& rStrm
)
671 if (!GetTabInfo().IsExportTab(mnScTab
))
674 SetCurrScTab(mnScTab
);
676 mxCellTable
->Finalize(false);
677 aRecList
.SaveXml(rStrm
);
683 OUString sSheetName
= XclXmlUtils::GetStreamName( "xl/", "worksheets/sheet", mnScTab
+1 );
685 sax_fastparser::FSHelperPtr pWorksheet
= rStrm
.GetStreamForPath( sSheetName
);
687 rStrm
.PushStream( pWorksheet
);
689 pWorksheet
->startElement( XML_worksheet
,
690 XML_xmlns
, rStrm
.getNamespaceURL(OOX_NS(xls
)).toUtf8(),
691 FSNS(XML_xmlns
, XML_r
), rStrm
.getNamespaceURL(OOX_NS(officeRel
)).toUtf8() );
693 SetCurrScTab( mnScTab
);
695 mxCellTable
->Finalize(false);
696 aRecList
.SaveXml( rStrm
);
698 XclExpXmlPivotTables
* pPT
= GetXmlPivotTableManager().GetTablesBySheet(mnScTab
);
702 rStrm
.GetCurrentStream()->endElement( XML_worksheet
);
706 ExcDocument::ExcDocument( const XclExpRoot
& rRoot
) :
712 ExcDocument::~ExcDocument()
714 maTableList
.RemoveAllRecords(); // for the following assertion!
717 void ExcDocument::ReadDoc()
721 if (GetOutput() == EXC_OUTPUT_BINARY
)
722 aHeader
.FillAsHeaderBinary(maBoundsheetList
);
725 aHeader
.FillAsHeaderXml(maBoundsheetList
);
726 GetXmlPivotTableManager().Initialize();
727 GetTablesManager().Initialize(); // Move outside conditions if we wanted to support BIFF.
730 SCTAB nScTab
= 0, nScTabCount
= GetTabInfo().GetScTabCount();
731 SCTAB nCodeNameIdx
= 0, nCodeNameCount
= GetExtDocOptions().GetCodeNameCount();
733 for( ; nScTab
< nScTabCount
; ++nScTab
)
735 if( GetTabInfo().IsExportTab( nScTab
) )
737 ExcTableList::RecordRefType
xTab( new ExcTable( GetRoot(), nScTab
) );
738 maTableList
.AppendRecord( xTab
);
739 if (GetOutput() == EXC_OUTPUT_BINARY
)
740 xTab
->FillAsTableBinary(nCodeNameIdx
);
742 xTab
->FillAsTableXml();
747 for( ; nCodeNameIdx
< nCodeNameCount
; ++nScTab
, ++nCodeNameIdx
)
749 ExcTableList::RecordRefType
xTab( new ExcTable( GetRoot(), nScTab
) );
750 maTableList
.AppendRecord( xTab
);
751 xTab
->FillAsEmptyTable( nCodeNameIdx
);
754 if ( GetBiff() == EXC_BIFF8
)
756 // complete temporary Escher stream
757 GetObjectManager().EndDocument();
760 if ( GetDoc().GetChangeTrack() )
761 m_xExpChangeTrack
.reset(new XclExpChangeTrack( GetRoot() ));
765 void ExcDocument::Write( SvStream
& rSvStrm
)
767 if( !maTableList
.IsEmpty() )
771 XclExpStream
aXclStrm( rSvStrm
, GetRoot() );
773 aHeader
.Write( aXclStrm
);
775 OSL_ENSURE( maTableList
.GetSize() == maBoundsheetList
.GetSize(),
776 "ExcDocument::Write - different number of sheets and BOUNDSHEET records" );
778 for( size_t nTab
= 0, nTabCount
= maTableList
.GetSize(); nTab
< nTabCount
; ++nTab
)
780 // set current stream position in BOUNDSHEET record
781 ExcBoundsheetRef xBoundsheet
= maBoundsheetList
.GetRecord( nTab
);
782 if( xBoundsheet
.get() )
783 xBoundsheet
->SetStreamPos( aXclStrm
.GetSvStreamPos() );
785 maTableList
.GetRecord( nTab
)->Write( aXclStrm
);
788 // write the table stream positions into the BOUNDSHEET records
789 for( size_t nBSheet
= 0, nBSheetCount
= maBoundsheetList
.GetSize(); nBSheet
< nBSheetCount
; ++nBSheet
)
790 maBoundsheetList
.GetRecord( nBSheet
)->UpdateStreamPos( aXclStrm
);
792 if( m_xExpChangeTrack
)
793 m_xExpChangeTrack
->Write();
796 void ExcDocument::WriteXml( XclExpXmlStream
& rStrm
)
798 SfxObjectShell
* pDocShell
= GetDocShell();
800 using namespace ::com::sun::star
;
801 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS( pDocShell
->GetModel(), uno::UNO_QUERY_THROW
);
802 uno::Reference
<document::XDocumentProperties
> xDocProps
= xDPS
->getDocumentProperties();
804 rStrm
.exportDocumentProperties(xDocProps
, pDocShell
->IsSecurityOptOpenReadOnly());
805 rStrm
.exportCustomFragments();
807 sax_fastparser::FSHelperPtr
& rWorkbook
= rStrm
.GetCurrentStream();
808 rWorkbook
->startElement( XML_workbook
,
809 XML_xmlns
, rStrm
.getNamespaceURL(OOX_NS(xls
)).toUtf8(),
810 FSNS(XML_xmlns
, XML_r
), rStrm
.getNamespaceURL(OOX_NS(officeRel
)).toUtf8() );
811 rWorkbook
->singleElement( XML_fileVersion
,
813 // OOXTODO: XML_codeName
814 // OOXTODO: XML_lastEdited
815 // OOXTODO: XML_lowestEdited
816 // OOXTODO: XML_rupBuild
819 if( !maTableList
.IsEmpty() )
823 aHeader
.WriteXml( rStrm
);
825 for( size_t nTab
= 0, nTabCount
= maTableList
.GetSize(); nTab
< nTabCount
; ++nTab
)
828 maTableList
.GetRecord( nTab
)->WriteXml( rStrm
);
832 if( m_xExpChangeTrack
)
833 m_xExpChangeTrack
->WriteXml( rStrm
);
835 XclExpXmlPivotCaches
& rCaches
= GetXmlPivotTableManager().GetCaches();
836 if (rCaches
.HasCaches())
837 rCaches
.SaveXml(rStrm
);
839 const ScCalcConfig
& rCalcConfig
= GetDoc().GetCalcConfig();
840 formula::FormulaGrammar::AddressConvention eConv
= rCalcConfig
.meStringRefAddressSyntax
;
842 // don't save "unspecified" string ref syntax ... query formula grammar
843 // and save that instead
844 if( eConv
== formula::FormulaGrammar::CONV_UNSPECIFIED
)
846 eConv
= GetDoc().GetAddressConvention();
849 // write if it has been read|imported or explicitly changed
850 // or if ref syntax isn't what would be native for our file format
851 // i.e. ExcelA1 in this case
852 if ( rCalcConfig
.mbHasStringRefSyntax
||
853 (eConv
!= formula::FormulaGrammar::CONV_XL_A1
) )
855 XclExtLstRef
xExtLst( new XclExtLst( GetRoot() ) );
856 xExtLst
->AddRecord( XclExpExtRef( new XclExpExtCalcPr( GetRoot(), eConv
)) );
857 xExtLst
->SaveXml(rStrm
);
860 rWorkbook
->endElement( XML_workbook
);
864 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */