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 "scitems.hxx"
22 #include <comphelper/processfactory.hxx>
23 #include <svx/svdobj.hxx>
24 #include <svx/svditer.hxx>
25 #include <svx/svdpage.hxx>
26 #include <editeng/lrspitem.hxx>
27 #include <editeng/ulspitem.hxx>
28 #include <svl/intitem.hxx>
29 #include <svl/zformat.hxx>
30 #include <sot/storage.hxx>
31 #include <sfx2/objsh.hxx>
32 #include <rtl/ustring.hxx>
34 #include "formulacell.hxx"
35 #include "dociter.hxx"
36 #include "document.hxx"
37 #include "rangenam.hxx"
40 #include "globstr.hrc"
41 #include "progress.hxx"
42 #include "conditio.hxx"
43 #include "dpobject.hxx"
45 #include "scextopt.hxx"
46 #include "stlsheet.hxx"
47 #include "stlpool.hxx"
48 #include "olinetab.hxx"
49 #include "unonames.hxx"
50 #include "convuno.hxx"
51 #include "patattr.hxx"
52 #include "docoptio.hxx"
53 #include "tabprotection.hxx"
57 #include "namebuff.hxx"
58 #include "xeextlst.hxx"
60 #include "xcl97rec.hxx"
61 #include "xcl97esc.hxx"
62 #include "xetable.hxx"
67 #include "xecontent.hxx"
68 #include "xeescher.hxx"
69 #include "xepivot.hxx"
70 #include "XclExpChangeTrack.hxx"
71 #include <xepivotxml.hxx>
72 #include "xedbdata.hxx"
76 #include <com/sun/star/document/XDocumentProperties.hpp>
77 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
78 #include <oox/token/tokens.hxx>
83 static OUString
lcl_GetVbaTabName( SCTAB n
)
85 OUString aRet
= "__VBA__" + OUString::number( static_cast<sal_uInt16
>(n
) );
89 static void lcl_AddBookviews( XclExpRecordList
<>& aRecList
, ExcTable
& self
)
91 aRecList
.AppendNewRecord( new XclExpXmlStartElementRecord( XML_bookViews
) );
92 aRecList
.AppendNewRecord( new XclExpWindow1( self
.GetRoot() ) );
93 aRecList
.AppendNewRecord( new XclExpXmlEndElementRecord( XML_bookViews
) );
96 static void lcl_AddCalcPr( XclExpRecordList
<>& aRecList
, ExcTable
& self
)
98 ScDocument
& rDoc
= self
.GetDoc();
100 aRecList
.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_calcPr
) );
101 // OOXTODO: calcCompleted, calcId, calcMode, calcOnSave,
102 // concurrentCalc, concurrentManualCount,
103 // forceFullCalc, fullCalcOnLoad, fullPrecision
104 aRecList
.AppendNewRecord( new XclCalccount( rDoc
) );
105 aRecList
.AppendNewRecord( new XclRefmode( rDoc
) );
106 aRecList
.AppendNewRecord( new XclIteration( rDoc
) );
107 aRecList
.AppendNewRecord( new XclDelta( rDoc
) );
108 aRecList
.AppendNewRecord( new XclExpBoolRecord(0x005F, true) ); // SAVERECALC
109 aRecList
.AppendNewRecord( new XclExpXmlEndSingleElementRecord() ); // XML_calcPr
112 static void lcl_AddWorkbookProtection( XclExpRecordList
<>& aRecList
, ExcTable
& self
)
114 aRecList
.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_workbookProtection
) );
116 const ScDocProtection
* pProtect
= self
.GetDoc().GetDocProtection();
117 if (pProtect
&& pProtect
->isProtected())
119 aRecList
.AppendNewRecord( new XclExpWindowProtection(pProtect
->isOptionEnabled(ScDocProtection::WINDOWS
)) );
120 aRecList
.AppendNewRecord( new XclExpProtection(pProtect
->isOptionEnabled(ScDocProtection::STRUCTURE
)) );
121 aRecList
.AppendNewRecord( new XclExpPassHash(pProtect
->getPasswordHash(PASSHASH_XL
)) );
124 aRecList
.AppendNewRecord( new XclExpXmlEndSingleElementRecord() ); // XML_workbookProtection
127 static void lcl_AddScenariosAndFilters( XclExpRecordList
<>& aRecList
, const XclExpRoot
& rRoot
, SCTAB nScTab
)
130 aRecList
.AppendNewRecord( new ExcEScenarioManager( rRoot
, nScTab
) );
132 aRecList
.AppendRecord( rRoot
.GetFilterManager().CreateRecord( nScTab
) );
135 ExcTable::ExcTable( const XclExpRoot
& rRoot
) :
137 mnScTab( SCTAB_GLOBAL
),
138 nExcTab( EXC_NOTAB
),
139 pTabNames( new NameBuffer( nullptr, 16 ) ),
140 mxNoteList( new XclExpNoteList
)
144 ExcTable::ExcTable( const XclExpRoot
& rRoot
, SCTAB nScTab
) :
147 nExcTab( rRoot
.GetTabInfo().GetXclTab( nScTab
) ),
148 pTabNames( new NameBuffer( nullptr, 16 ) ),
149 mxNoteList( new XclExpNoteList
)
153 ExcTable::~ExcTable()
158 void ExcTable::Add( XclExpRecordBase
* pRec
)
160 OSL_ENSURE( pRec
, "-ExcTable::Add(): pRec is NULL!" );
161 aRecList
.AppendNewRecord( pRec
);
164 void ExcTable::FillAsHeaderBinary( ExcBoundsheetList
& rBoundsheetList
)
168 RootData
& rR
= GetOldRoot();
169 ScDocument
& rDoc
= GetDoc();
170 XclExpTabInfo
& rTabInfo
= GetTabInfo();
172 if ( GetBiff() <= EXC_BIFF5
)
179 SCTAB nScTabCount
= rTabInfo
.GetScTabCount();
180 sal_uInt16 nExcTabCount
= rTabInfo
.GetXclTabCount();
181 sal_uInt16 nCodenames
= static_cast< sal_uInt16
>( GetExtDocOptions().GetCodeNameCount() );
183 SfxObjectShell
* pShell
= GetDocShell();
184 sal_uInt16 nWriteProtHash
= pShell
? pShell
->GetModifyPasswordHash() : 0;
185 bool bRecommendReadOnly
= pShell
&& pShell
->IsLoadReadonly();
187 if( (nWriteProtHash
> 0) || bRecommendReadOnly
)
188 Add( new XclExpEmptyRecord( EXC_ID_WRITEPROT
) );
190 // TODO: correct codepage for BIFF5?
191 sal_uInt16 nCodePage
= XclTools::GetXclCodePage( (GetBiff() <= EXC_BIFF5
) ? RTL_TEXTENCODING_MS_1252
: RTL_TEXTENCODING_UNICODE
);
193 if( GetBiff() <= EXC_BIFF5
)
195 Add( new XclExpEmptyRecord( EXC_ID_INTERFACEHDR
) );
196 Add( new XclExpUInt16Record( EXC_ID_MMS
, 0 ) );
197 Add( new XclExpEmptyRecord( EXC_ID_TOOLBARHDR
) );
198 Add( new XclExpEmptyRecord( EXC_ID_TOOLBAREND
) );
199 Add( new XclExpEmptyRecord( EXC_ID_INTERFACEEND
) );
200 Add( new ExcDummy_00
);
204 if( IsDocumentEncrypted() )
205 Add( new XclExpFileEncryption( GetRoot() ) );
206 Add( new XclExpInterfaceHdr( nCodePage
) );
207 Add( new XclExpUInt16Record( EXC_ID_MMS
, 0 ) );
208 Add( new XclExpInterfaceEnd
);
209 Add( new XclExpWriteAccess
);
212 Add( new XclExpFileSharing( GetRoot(), nWriteProtHash
, bRecommendReadOnly
) );
213 Add( new XclExpUInt16Record( EXC_ID_CODEPAGE
, nCodePage
) );
215 if( GetBiff() == EXC_BIFF8
)
217 Add( new XclExpBoolRecord( EXC_ID_DSF
, false ) );
218 Add( new XclExpEmptyRecord( EXC_ID_XL9FILE
) );
219 rR
.pTabId
= new XclExpChTrTabId( std::max( nExcTabCount
, nCodenames
) );
221 if( HasVbaStorage() )
223 Add( new XclObproj
);
224 const OUString
& rCodeName
= GetExtDocOptions().GetDocSettings().maGlobCodeName
;
225 if( !rCodeName
.isEmpty() )
226 Add( new XclCodename( rCodeName
) );
230 Add( new XclExpUInt16Record( EXC_ID_FNGROUPCOUNT
, 14 ) );
232 // first setup table names and contents
234 for( nC
= 0 ; nC
< nScTabCount
; nC
++ )
235 if( rTabInfo
.IsExportTab( nC
) )
237 rDoc
.GetName( nC
, aTmpString
);
238 *pTabNames
<< aTmpString
;
241 if ( GetBiff() <= EXC_BIFF5
)
243 // global link table: EXTERNCOUNT, EXTERNSHEET, NAME
244 aRecList
.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET
) );
245 aRecList
.AppendRecord( CreateRecord( EXC_ID_NAME
) );
248 // document protection options
249 lcl_AddWorkbookProtection( aRecList
, *this );
251 if( GetBiff() == EXC_BIFF8
)
253 Add( new XclExpProt4Rev
);
254 Add( new XclExpProt4RevPass
);
257 lcl_AddBookviews( aRecList
, *this );
259 Add( new XclExpXmlStartSingleElementRecord( XML_workbookPr
) );
260 if ( GetBiff() == EXC_BIFF8
&& GetOutput() != EXC_OUTPUT_BINARY
)
262 Add( new XclExpBoolRecord(0x0040, false, XML_backupFile
) ); // BACKUP
263 Add( new XclExpBoolRecord(0x008D, false, XML_showObjects
) ); // HIDEOBJ
266 if ( GetBiff() == EXC_BIFF8
)
268 Add( new XclExpBoolRecord(0x0040, false) ); // BACKUP
269 Add( new XclExpBoolRecord(0x008D, false) ); // HIDEOBJ
272 if( GetBiff() <= EXC_BIFF5
)
274 Add( new ExcDummy_040
);
275 Add( new Exc1904( rDoc
) );
276 Add( new ExcDummy_041
);
281 Add( new Exc1904( rDoc
) );
282 Add( new XclExpBoolRecord( 0x000E, !rDoc
.GetDocOptions().IsCalcAsShown() ) );
283 Add( new XclExpBoolRecord(0x01B7, false) ); // REFRESHALL
284 Add( new XclExpBoolRecord(0x00DA, false) ); // BOOKBOOL
287 // Formatting: FONT, FORMAT, XF, STYLE, PALETTE
288 aRecList
.AppendRecord( CreateRecord( EXC_ID_FONTLIST
) );
289 aRecList
.AppendRecord( CreateRecord( EXC_ID_FORMATLIST
) );
290 aRecList
.AppendRecord( CreateRecord( EXC_ID_XFLIST
) );
291 aRecList
.AppendRecord( CreateRecord( EXC_ID_PALETTE
) );
293 if( GetBiff() <= EXC_BIFF5
)
296 for( nC
= 0 ; nC
< nScTabCount
; nC
++ )
297 if( rTabInfo
.IsExportTab( nC
) )
299 ExcBoundsheetList::RecordRefType
xBoundsheet( new ExcBundlesheet( rR
, nC
) );
300 aRecList
.AppendRecord( xBoundsheet
);
301 rBoundsheetList
.AppendRecord( xBoundsheet
);
307 GetPivotTableManager().CreatePivotTables();
308 aRecList
.AppendRecord( GetPivotTableManager().CreatePivotCachesRecord() );
311 if( rDoc
.GetChangeTrack() )
313 rR
.pUserBViewList
= new XclExpUserBViewList( *rDoc
.GetChangeTrack() );
314 Add( rR
.pUserBViewList
);
317 // Natural Language Formulas Flag
318 aRecList
.AppendNewRecord( new XclExpBoolRecord( EXC_ID_USESELFS
, GetDoc().GetDocOptions().IsLookUpColRowNames() ) );
321 for( nC
= 0 ; nC
< nScTabCount
; nC
++ )
322 if( rTabInfo
.IsExportTab( nC
) )
324 ExcBoundsheetList::RecordRefType
xBoundsheet( new ExcBundlesheet8( rR
, nC
) );
325 aRecList
.AppendRecord( xBoundsheet
);
326 rBoundsheetList
.AppendRecord( xBoundsheet
);
329 for( SCTAB nAdd
= 0; nC
< static_cast<SCTAB
>(nCodenames
) ; nC
++, nAdd
++ )
331 aTmpString
= lcl_GetVbaTabName( nAdd
);
332 ExcBoundsheetList::RecordRefType
xBoundsheet( new ExcBundlesheet8( aTmpString
) );
333 aRecList
.AppendRecord( xBoundsheet
);
334 rBoundsheetList
.AppendRecord( xBoundsheet
);
337 // COUNTRY - in BIFF8 in workbook globals
338 Add( new XclExpCountry( GetRoot() ) );
340 // link table: SUPBOOK, XCT, CRN, EXTERNNAME, EXTERNSHEET, NAME
341 aRecList
.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET
) );
342 aRecList
.AppendRecord( CreateRecord( EXC_ID_NAME
) );
344 Add( new XclExpRecalcId
);
346 // MSODRAWINGGROUP per-document data
347 aRecList
.AppendRecord( GetObjectManager().CreateDrawingGroup() );
348 // Shared string table: SST, EXTSST
349 aRecList
.AppendRecord( CreateRecord( EXC_ID_SST
) );
351 Add( new XclExpBookExt
);
357 void ExcTable::FillAsHeaderXml( ExcBoundsheetList
& rBoundsheetList
)
361 RootData
& rR
= GetOldRoot();
362 ScDocument
& rDoc
= GetDoc();
363 XclExpTabInfo
& rTabInfo
= GetTabInfo();
367 SCTAB nScTabCount
= rTabInfo
.GetScTabCount();
368 sal_uInt16 nExcTabCount
= rTabInfo
.GetXclTabCount();
369 sal_uInt16 nCodenames
= static_cast< sal_uInt16
>( GetExtDocOptions().GetCodeNameCount() );
371 rR
.pTabId
= new XclExpChTrTabId( std::max( nExcTabCount
, nCodenames
) );
374 // first setup table names and contents
376 for( nC
= 0 ; nC
< nScTabCount
; nC
++ )
377 if( rTabInfo
.IsExportTab( nC
) )
379 rDoc
.GetName( nC
, aTmpString
);
380 *pTabNames
<< aTmpString
;
383 Add( new XclExpXmlStartSingleElementRecord( XML_workbookPr
) );
384 Add( new XclExpBoolRecord(0x0040, false, XML_backupFile
) ); // BACKUP
385 Add( new XclExpBoolRecord(0x008D, false, XML_showObjects
) ); // HIDEOBJ
387 Add( new Exc1904( rDoc
) );
388 // OOXTODO: The following /workbook/workbookPr attributes are mapped
389 // to various BIFF records that are not currently supported:
391 // XML_allowRefreshQuery: QSISTAG 802h: fEnableRefresh
392 // XML_autoCompressPictures: COMPRESSPICTURES 89Bh: fAutoCompressPictures
393 // XML_checkCompatibility: COMPAT12 88Ch: fNoCompatChk
394 // XML_codeName: "Calc"
395 // XML_defaultThemeVersion: ???
396 // XML_filterPrivacy: BOOKEXT 863h: fFilterPrivacy
397 // XML_hidePivotFieldList: BOOKBOOL DAh: fHidePivotTableFList
398 // XML_promptedSolutions: BOOKEXT 863h: fBuggedUserAboutSolution
399 // XML_publishItems: NAMEPUBLISH 893h: fPublished
400 // XML_saveExternalLinkValues: BOOKBOOL DAh: fNoSavSupp
401 // XML_showBorderUnselectedTables: BOOKBOOL DAh: fHideBorderUnsels
402 // XML_showInkAnnotation: BOOKEXT 863h: fShowInkAnnotation
403 // XML_showPivotChart: PIVOTCHARTBITS 859h: fGXHide??
404 // XML_updateLinks: BOOKBOOL DAh: grbitUpdateLinks
405 Add( new XclExpXmlEndSingleElementRecord() ); // XML_workbookPr
407 // Formatting: FONT, FORMAT, XF, STYLE, PALETTE
408 aRecList
.AppendNewRecord( new XclExpXmlStyleSheet( *this ) );
411 if( rDoc
.GetChangeTrack() )
413 rR
.pUserBViewList
= new XclExpUserBViewList( *rDoc
.GetChangeTrack() );
414 Add( rR
.pUserBViewList
);
417 lcl_AddWorkbookProtection( aRecList
, *this );
418 lcl_AddBookviews( aRecList
, *this );
421 aRecList
.AppendNewRecord( new XclExpXmlStartElementRecord( XML_sheets
) );
422 for( nC
= 0 ; nC
< nScTabCount
; nC
++ )
423 if( rTabInfo
.IsExportTab( nC
) )
425 ExcBoundsheetList::RecordRefType
xBoundsheet( new ExcBundlesheet8( rR
, nC
) );
426 aRecList
.AppendRecord( xBoundsheet
);
427 rBoundsheetList
.AppendRecord( xBoundsheet
);
429 aRecList
.AppendNewRecord( new XclExpXmlEndElementRecord( XML_sheets
) );
431 for( SCTAB nAdd
= 0; nC
< static_cast<SCTAB
>(nCodenames
) ; nC
++, nAdd
++ )
433 aTmpString
= lcl_GetVbaTabName( nAdd
);
434 ExcBoundsheetList::RecordRefType
xBoundsheet( new ExcBundlesheet8( aTmpString
) );
435 aRecList
.AppendRecord( xBoundsheet
);
436 rBoundsheetList
.AppendRecord( xBoundsheet
);
439 // link table: SUPBOOK, XCT, CRN, EXTERNNAME, EXTERNSHEET, NAME
440 aRecList
.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET
) );
441 aRecList
.AppendRecord( CreateRecord( EXC_ID_NAME
) );
443 lcl_AddCalcPr( aRecList
, *this );
445 // MSODRAWINGGROUP per-document data
446 aRecList
.AppendRecord( GetObjectManager().CreateDrawingGroup() );
447 // Shared string table: SST, EXTSST
448 aRecList
.AppendRecord( CreateRecord( EXC_ID_SST
) );
451 void ExcTable::FillAsTableBinary( SCTAB nCodeNameIdx
)
453 InitializeTable( mnScTab
);
455 RootData
& rR
= GetOldRoot();
456 XclBiff eBiff
= GetBiff();
457 ScDocument
& rDoc
= GetDoc();
459 OSL_ENSURE( (mnScTab
>= 0) && (mnScTab
<= MAXTAB
), "-ExcTable::Table(): mnScTab - no ordinary table!" );
460 OSL_ENSURE( nExcTab
<= static_cast<sal_uInt16
>(MAXTAB
), "-ExcTable::Table(): nExcTab - no ordinary table!" );
462 // create a new OBJ list for this sheet (may be used by notes, autofilter, data validation)
463 if( eBiff
== EXC_BIFF8
)
464 GetObjectManager().StartSheet();
466 // cell table: DEFROWHEIGHT, DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
467 mxCellTable
.reset( new XclExpCellTable( GetRoot() ) );
470 std::vector
<sc::NoteEntry
> aNotes
;
471 rDoc
.GetAllNoteEntries(aNotes
);
472 for (std::vector
<sc::NoteEntry
>::const_iterator it
= aNotes
.begin(), itEnd
= aNotes
.end(); it
!= itEnd
; ++it
)
474 if (it
->maPos
.Tab() != mnScTab
)
477 mxNoteList
->AppendNewRecord(new XclExpNote(GetRoot(), it
->maPos
, it
->mpNote
, OUString()));
480 // WSBOOL needs data from page settings, create it here, add it later
481 std::shared_ptr
< XclExpPageSettings
> xPageSett( new XclExpPageSettings( GetRoot() ) );
482 bool bFitToPages
= xPageSett
->GetPageData().mbFitToPages
;
484 if( eBiff
<= EXC_BIFF5
)
487 Add( new ExcDummy_02a
);
492 lcl_AddCalcPr( aRecList
, *this );
495 // GUTS (count & size of outline icons)
496 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_GUTS
) );
497 // DEFROWHEIGHT, created by the cell table
498 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID2_DEFROWHEIGHT
) );
500 // COUNTRY - in BIFF5/7 in every worksheet
501 if( eBiff
<= EXC_BIFF5
)
502 Add( new XclExpCountry( GetRoot() ) );
504 Add( new XclExpWsbool( bFitToPages
) );
506 // page settings (SETUP and various other records)
507 aRecList
.AppendRecord( xPageSett
);
509 const ScTableProtection
* pTabProtect
= rDoc
.GetTabProtection(mnScTab
);
510 if (pTabProtect
&& pTabProtect
->isProtected())
512 Add( new XclExpProtection(true) );
513 Add( new XclExpBoolRecord(0x00DD, pTabProtect
->isOptionEnabled(ScTableProtection::SCENARIOS
)) );
514 Add( new XclExpBoolRecord(0x0063, pTabProtect
->isOptionEnabled(ScTableProtection::OBJECTS
)) );
515 Add( new XclExpPassHash(pTabProtect
->getPasswordHash(PASSHASH_XL
)) );
518 // local link table: EXTERNCOUNT, EXTERNSHEET
519 if( eBiff
<= EXC_BIFF5
)
520 aRecList
.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET
) );
522 if ( eBiff
== EXC_BIFF8
)
523 lcl_AddScenariosAndFilters( aRecList
, GetRoot(), mnScTab
);
525 // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
526 aRecList
.AppendRecord( mxCellTable
);
528 // MERGEDCELLS record, generated by the cell table
529 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_MERGEDCELLS
) );
531 if( eBiff
== EXC_BIFF8
)
532 Add( new XclExpLabelranges( GetRoot() ) );
533 // data validation (DVAL and list of DV records), generated by the cell table
534 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_DVAL
) );
536 if( eBiff
== EXC_BIFF8
)
538 // all MSODRAWING and OBJ stuff of this sheet goes here
539 aRecList
.AppendRecord( GetObjectManager().ProcessDrawing( GetSdrPage( mnScTab
) ) );
541 aRecList
.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab
) );
544 // list of NOTE records, generated by the cell table
545 aRecList
.AppendRecord( mxNoteList
);
547 // sheet view settings: WINDOW2, SCL, PANE, SELECTION
548 aRecList
.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab
) );
550 if( eBiff
== EXC_BIFF8
)
552 // sheet protection options
553 Add( new XclExpSheetProtectOptions( GetRoot(), mnScTab
) );
555 // enhanced protections if there are
558 const ::std::vector
<ScEnhancedProtection
>& rProts( pTabProtect
->getEnhancedProtection());
559 for (::std::vector
<ScEnhancedProtection
>::const_iterator
it( rProts
.begin()), itEnd( rProts
.end());
562 Add( new XclExpSheetEnhancedProtection( GetRoot(), *it
));
567 Add( new XclExpWebQueryBuffer( GetRoot() ) );
569 // conditional formats
570 Add( new XclExpCondFormatBuffer( GetRoot(), XclExtLstRef() ) );
572 if( HasVbaStorage() )
573 if( nCodeNameIdx
< GetExtDocOptions().GetCodeNameCount() )
574 Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx
) ) );
577 // list of HLINK records, generated by the cell table
578 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_HLINK
) );
581 if( rR
.pUserBViewList
)
583 XclExpUserBViewList::const_iterator iter
;
584 for ( iter
= rR
.pUserBViewList
->begin(); iter
!= rR
.pUserBViewList
->end(); ++iter
)
586 Add( new XclExpUsersViewBegin( (*iter
)->GetGUID(), nExcTab
) );
587 Add( new XclExpUsersViewEnd
);
595 void ExcTable::FillAsTableXml()
597 InitializeTable( mnScTab
);
599 ScDocument
& rDoc
= GetDoc();
601 OSL_ENSURE( (mnScTab
>= 0) && (mnScTab
<= MAXTAB
), "-ExcTable::Table(): mnScTab - no ordinary table!" );
602 OSL_ENSURE( nExcTab
<= static_cast<sal_uInt16
>(MAXTAB
), "-ExcTable::Table(): nExcTab - no ordinary table!" );
604 // create a new OBJ list for this sheet (may be used by notes, autofilter, data validation)
605 GetObjectManager().StartSheet();
607 // cell table: DEFROWHEIGHT, DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
608 mxCellTable
.reset( new XclExpCellTable( GetRoot() ) );
611 std::vector
<sc::NoteEntry
> aNotes
;
612 rDoc
.GetAllNoteEntries(aNotes
);
613 for (std::vector
<sc::NoteEntry
>::const_iterator it
= aNotes
.begin(), itEnd
= aNotes
.end(); it
!= itEnd
; ++it
)
615 if (it
->maPos
.Tab() != mnScTab
)
618 mxNoteList
->AppendNewRecord(new XclExpNote(GetRoot(), it
->maPos
, it
->mpNote
, OUString()));
621 // WSBOOL needs data from page settings, create it here, add it later
622 std::shared_ptr
< XclExpPageSettings
> xPageSett( new XclExpPageSettings( GetRoot() ) );
623 XclExtLstRef
xExtLst( new XclExtLst( GetRoot() ) );
624 bool bFitToPages
= xPageSett
->GetPageData().mbFitToPages
;
626 Color aTabColor
= GetRoot().GetDoc().GetTabBgColor(mnScTab
);
627 Add(new XclExpXmlSheetPr(bFitToPages
, mnScTab
, aTabColor
, &GetFilterManager()));
629 // GUTS (count & size of outline icons)
630 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_GUTS
) );
631 // DEFROWHEIGHT, created by the cell table
632 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID2_DEFROWHEIGHT
) );
634 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID3_DIMENSIONS
) );
636 // sheet view settings: WINDOW2, SCL, PANE, SELECTION
637 aRecList
.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab
) );
639 // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
640 aRecList
.AppendRecord( mxCellTable
);
642 // list of NOTE records, generated by the cell table
643 // not in the worksheet file
644 if( mxNoteList
!= nullptr && !mxNoteList
->IsEmpty() )
645 aRecList
.AppendNewRecord( new XclExpComments( mnScTab
, *mxNoteList
) );
647 const ScTableProtection
* pTabProtect
= rDoc
.GetTabProtection(mnScTab
);
648 if (pTabProtect
&& pTabProtect
->isProtected())
649 Add( new XclExpSheetProtection(true, mnScTab
) );
651 lcl_AddScenariosAndFilters( aRecList
, GetRoot(), mnScTab
);
653 // MERGEDCELLS record, generated by the cell table
654 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_MERGEDCELLS
) );
656 // conditional formats
657 Add( new XclExpCondFormatBuffer( GetRoot(), xExtLst
) );
659 // data validation (DVAL and list of DV records), generated by the cell table
660 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_DVAL
) );
662 // list of HLINK records, generated by the cell table
663 XclExpRecordRef xHyperlinks
= mxCellTable
->CreateRecord( EXC_ID_HLINK
);
664 XclExpHyperlinkList
* pHyperlinkList
= dynamic_cast<XclExpHyperlinkList
*>(xHyperlinks
.get());
665 if( pHyperlinkList
!= nullptr && !pHyperlinkList
->IsEmpty() )
667 aRecList
.AppendNewRecord( new XclExpXmlStartElementRecord( XML_hyperlinks
) );
668 aRecList
.AppendRecord( xHyperlinks
);
669 aRecList
.AppendNewRecord( new XclExpXmlEndElementRecord( XML_hyperlinks
) );
672 aRecList
.AppendRecord( xPageSett
);
674 // all MSODRAWING and OBJ stuff of this sheet goes here
675 aRecList
.AppendRecord( GetObjectManager().ProcessDrawing( GetSdrPage( mnScTab
) ) );
677 XclExpImgData
* pImgData
= xPageSett
->getGraphicExport();
679 aRecList
.AppendRecord(std::shared_ptr
<XclExpRecordBase
>(pImgData
));
681 // <tableParts> after <drawing> and before <extLst>
682 aRecList
.AppendRecord( GetTablesManager().GetTablesBySheet( mnScTab
));
684 aRecList
.AppendRecord( xExtLst
);
687 void ExcTable::FillAsEmptyTable( SCTAB nCodeNameIdx
)
689 InitializeTable( mnScTab
);
691 if( HasVbaStorage() && (nCodeNameIdx
< GetExtDocOptions().GetCodeNameCount()) )
693 if( GetBiff() <= EXC_BIFF5
)
700 Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx
) ) );
702 // sheet view settings: WINDOW2, SCL, PANE, SELECTION
703 aRecList
.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab
) );
708 void ExcTable::Write( XclExpStream
& rStrm
)
710 SetCurrScTab( mnScTab
);
711 if( mxCellTable
.get() )
712 mxCellTable
->Finalize();
713 aRecList
.Save( rStrm
);
716 void ExcTable::WriteXml( XclExpXmlStream
& rStrm
)
718 if (!GetTabInfo().IsExportTab(mnScTab
))
721 SetCurrScTab(mnScTab
);
723 mxCellTable
->Finalize();
724 aRecList
.SaveXml(rStrm
);
730 OUString sSheetName
= XclXmlUtils::GetStreamName( "xl/", "worksheets/sheet", mnScTab
+1 );
732 sax_fastparser::FSHelperPtr pWorksheet
= rStrm
.GetStreamForPath( sSheetName
);
734 rStrm
.PushStream( pWorksheet
);
736 pWorksheet
->startElement( XML_worksheet
,
737 XML_xmlns
, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
738 FSNS( XML_xmlns
, XML_r
), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
741 SetCurrScTab( mnScTab
);
743 mxCellTable
->Finalize();
744 aRecList
.SaveXml( rStrm
);
746 XclExpXmlPivotTables
* pPT
= GetXmlPivotTableManager().GetTablesBySheet(mnScTab
);
750 rStrm
.GetCurrentStream()->endElement( XML_worksheet
);
754 ExcDocument::ExcDocument( const XclExpRoot
& rRoot
) :
757 pExpChangeTrack( nullptr )
761 ExcDocument::~ExcDocument()
763 maTableList
.RemoveAllRecords(); // for the following assertion!
764 delete pExpChangeTrack
;
767 void ExcDocument::ReadDoc()
771 if (GetOutput() == EXC_OUTPUT_BINARY
)
772 aHeader
.FillAsHeaderBinary(maBoundsheetList
);
775 aHeader
.FillAsHeaderXml(maBoundsheetList
);
776 GetXmlPivotTableManager().Initialize();
777 GetTablesManager().Initialize(); // Move outside conditions if we wanted to support BIFF.
780 SCTAB nScTab
= 0, nScTabCount
= GetTabInfo().GetScTabCount();
781 SCTAB nCodeNameIdx
= 0, nCodeNameCount
= GetExtDocOptions().GetCodeNameCount();
783 for( ; nScTab
< nScTabCount
; ++nScTab
)
785 if( GetTabInfo().IsExportTab( nScTab
) )
787 ExcTableList::RecordRefType
xTab( new ExcTable( GetRoot(), nScTab
) );
788 maTableList
.AppendRecord( xTab
);
789 if (GetOutput() == EXC_OUTPUT_BINARY
)
790 xTab
->FillAsTableBinary(nCodeNameIdx
);
792 xTab
->FillAsTableXml();
797 for( ; nCodeNameIdx
< nCodeNameCount
; ++nScTab
, ++nCodeNameIdx
)
799 ExcTableList::RecordRefType
xTab( new ExcTable( GetRoot(), nScTab
) );
800 maTableList
.AppendRecord( xTab
);
801 xTab
->FillAsEmptyTable( nCodeNameIdx
);
804 if ( GetBiff() == EXC_BIFF8
)
806 // complete temporary Escher stream
807 GetObjectManager().EndDocument();
810 if ( GetDoc().GetChangeTrack() )
811 pExpChangeTrack
= new XclExpChangeTrack( GetRoot() );
815 void ExcDocument::Write( SvStream
& rSvStrm
)
817 if( !maTableList
.IsEmpty() )
821 XclExpStream
aXclStrm( rSvStrm
, GetRoot() );
823 aHeader
.Write( aXclStrm
);
825 OSL_ENSURE( maTableList
.GetSize() == maBoundsheetList
.GetSize(),
826 "ExcDocument::Write - different number of sheets and BOUNDSHEET records" );
828 for( size_t nTab
= 0, nTabCount
= maTableList
.GetSize(); nTab
< nTabCount
; ++nTab
)
830 // set current stream position in BOUNDSHEET record
831 ExcBoundsheetRef xBoundsheet
= maBoundsheetList
.GetRecord( nTab
);
832 if( xBoundsheet
.get() )
833 xBoundsheet
->SetStreamPos( aXclStrm
.GetSvStreamPos() );
835 maTableList
.GetRecord( nTab
)->Write( aXclStrm
);
838 // write the table stream positions into the BOUNDSHEET records
839 for( size_t nBSheet
= 0, nBSheetCount
= maBoundsheetList
.GetSize(); nBSheet
< nBSheetCount
; ++nBSheet
)
840 maBoundsheetList
.GetRecord( nBSheet
)->UpdateStreamPos( aXclStrm
);
842 if( pExpChangeTrack
)
843 pExpChangeTrack
->Write();
846 void ExcDocument::WriteXml( XclExpXmlStream
& rStrm
)
848 SfxObjectShell
* pDocShell
= GetDocShell();
850 using namespace ::com::sun::star
;
851 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS( pDocShell
->GetModel(), uno::UNO_QUERY_THROW
);
852 uno::Reference
<document::XDocumentProperties
> xDocProps
= xDPS
->getDocumentProperties();
854 rStrm
.exportDocumentProperties( xDocProps
);
856 sax_fastparser::FSHelperPtr
& rWorkbook
= rStrm
.GetCurrentStream();
857 rWorkbook
->startElement( XML_workbook
,
858 XML_xmlns
, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
859 FSNS(XML_xmlns
, XML_r
), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
861 rWorkbook
->singleElement( XML_fileVersion
,
863 // OOXTODO: XML_codeName
864 // OOXTODO: XML_lastEdited
865 // OOXTODO: XML_lowestEdited
866 // OOXTODO: XML_rupBuild
869 if( !maTableList
.IsEmpty() )
873 aHeader
.WriteXml( rStrm
);
875 for( size_t nTab
= 0, nTabCount
= maTableList
.GetSize(); nTab
< nTabCount
; ++nTab
)
878 maTableList
.GetRecord( nTab
)->WriteXml( rStrm
);
882 if( pExpChangeTrack
)
883 pExpChangeTrack
->WriteXml( rStrm
);
885 XclExpXmlPivotCaches
& rCaches
= GetXmlPivotTableManager().GetCaches();
886 if (rCaches
.HasCaches())
887 rCaches
.SaveXml(rStrm
);
889 const ScCalcConfig
& rCalcConfig
= GetDoc().GetCalcConfig();
890 formula::FormulaGrammar::AddressConvention eConv
= rCalcConfig
.meStringRefAddressSyntax
;
892 // don't save "unspecified" string ref syntax ... query formula grammar
893 // and save that instead
894 if( eConv
== formula::FormulaGrammar::CONV_UNSPECIFIED
)
896 eConv
= GetDoc().GetAddressConvention();
899 // write if it has been read|imported or explicitly changed
900 // or if ref syntax isn't what would be native for our file format
901 // i.e. ExcelA1 in this case
902 if ( rCalcConfig
.mbHasStringRefSyntax
||
903 (eConv
!= formula::FormulaGrammar::CONV_XL_A1
) )
905 XclExtLstRef
xExtLst( new XclExtLst( GetRoot() ) );
906 xExtLst
->AddRecord( XclExpExtRef( new XclExpExtCalcPr( GetRoot(), eConv
)) );
907 xExtLst
->SaveXml(rStrm
);
910 rWorkbook
->endElement( XML_workbook
);
914 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */