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>
75 #include <com/sun/star/document/XDocumentProperties.hpp>
76 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
77 #include <oox/token/tokens.hxx>
82 static OUString
lcl_GetVbaTabName( SCTAB n
)
84 OUString aRet
= "__VBA__" + OUString::number( static_cast<sal_uInt16
>(n
) );
88 static void lcl_AddBookviews( XclExpRecordList
<>& aRecList
, ExcTable
& self
)
90 aRecList
.AppendNewRecord( new XclExpXmlStartElementRecord( XML_bookViews
) );
91 aRecList
.AppendNewRecord( new XclExpWindow1( self
.GetRoot() ) );
92 aRecList
.AppendNewRecord( new XclExpXmlEndElementRecord( XML_bookViews
) );
95 static void lcl_AddCalcPr( XclExpRecordList
<>& aRecList
, ExcTable
& self
)
97 ScDocument
& rDoc
= self
.GetDoc();
99 aRecList
.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_calcPr
) );
100 // OOXTODO: calcCompleted, calcId, calcMode, calcOnSave,
101 // concurrentCalc, concurrentManualCount,
102 // forceFullCalc, fullCalcOnLoad, fullPrecision
103 aRecList
.AppendNewRecord( new XclCalccount( rDoc
) );
104 aRecList
.AppendNewRecord( new XclRefmode( rDoc
) );
105 aRecList
.AppendNewRecord( new XclIteration( rDoc
) );
106 aRecList
.AppendNewRecord( new XclDelta( rDoc
) );
107 aRecList
.AppendNewRecord( new XclExpBoolRecord(0x005F, true) ); // SAVERECALC
108 aRecList
.AppendNewRecord( new XclExpXmlEndSingleElementRecord() ); // XML_calcPr
111 static void lcl_AddWorkbookProtection( XclExpRecordList
<>& aRecList
, ExcTable
& self
)
113 aRecList
.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_workbookProtection
) );
115 const ScDocProtection
* pProtect
= self
.GetDoc().GetDocProtection();
116 if (pProtect
&& pProtect
->isProtected())
118 aRecList
.AppendNewRecord( new XclExpWindowProtection(pProtect
->isOptionEnabled(ScDocProtection::WINDOWS
)) );
119 aRecList
.AppendNewRecord( new XclExpProtection(pProtect
->isOptionEnabled(ScDocProtection::STRUCTURE
)) );
120 aRecList
.AppendNewRecord( new XclExpPassHash(pProtect
->getPasswordHash(PASSHASH_XL
)) );
123 aRecList
.AppendNewRecord( new XclExpXmlEndSingleElementRecord() ); // XML_workbookProtection
126 static void lcl_AddScenariosAndFilters( XclExpRecordList
<>& aRecList
, const XclExpRoot
& rRoot
, SCTAB nScTab
)
129 aRecList
.AppendNewRecord( new ExcEScenarioManager( rRoot
, nScTab
) );
131 aRecList
.AppendRecord( rRoot
.GetFilterManager().CreateRecord( nScTab
) );
134 ExcTable::ExcTable( const XclExpRoot
& rRoot
) :
136 mnScTab( SCTAB_GLOBAL
),
137 nExcTab( EXC_NOTAB
),
138 pTabNames( new NameBuffer( 0, 16 ) ),
139 mxNoteList( new XclExpNoteList
)
143 ExcTable::ExcTable( const XclExpRoot
& rRoot
, SCTAB nScTab
) :
146 nExcTab( rRoot
.GetTabInfo().GetXclTab( nScTab
) ),
147 pTabNames( new NameBuffer( 0, 16 ) ),
148 mxNoteList( new XclExpNoteList
)
152 ExcTable::~ExcTable()
157 void ExcTable::Add( XclExpRecordBase
* pRec
)
159 OSL_ENSURE( pRec
, "-ExcTable::Add(): pRec is NULL!" );
160 aRecList
.AppendNewRecord( pRec
);
163 void ExcTable::FillAsHeaderBinary( ExcBoundsheetList
& rBoundsheetList
)
167 RootData
& rR
= GetOldRoot();
168 ScDocument
& rDoc
= GetDoc();
169 XclExpTabInfo
& rTabInfo
= GetTabInfo();
171 if ( GetBiff() <= EXC_BIFF5
)
178 SCTAB nScTabCount
= rTabInfo
.GetScTabCount();
179 sal_uInt16 nExcTabCount
= rTabInfo
.GetXclTabCount();
180 sal_uInt16 nCodenames
= static_cast< sal_uInt16
>( GetExtDocOptions().GetCodeNameCount() );
182 SfxObjectShell
* pShell
= GetDocShell();
183 sal_uInt16 nWriteProtHash
= pShell
? pShell
->GetModifyPasswordHash() : 0;
184 bool bRecommendReadOnly
= pShell
&& pShell
->IsLoadReadonly();
186 if( (nWriteProtHash
> 0) || bRecommendReadOnly
)
187 Add( new XclExpEmptyRecord( EXC_ID_WRITEPROT
) );
189 // TODO: correct codepage for BIFF5?
190 sal_uInt16 nCodePage
= XclTools::GetXclCodePage( (GetBiff() <= EXC_BIFF5
) ? RTL_TEXTENCODING_MS_1252
: RTL_TEXTENCODING_UNICODE
);
192 if( GetBiff() <= EXC_BIFF5
)
194 Add( new XclExpEmptyRecord( EXC_ID_INTERFACEHDR
) );
195 Add( new XclExpUInt16Record( EXC_ID_MMS
, 0 ) );
196 Add( new XclExpEmptyRecord( EXC_ID_TOOLBARHDR
) );
197 Add( new XclExpEmptyRecord( EXC_ID_TOOLBAREND
) );
198 Add( new XclExpEmptyRecord( EXC_ID_INTERFACEEND
) );
199 Add( new ExcDummy_00
);
203 if( IsDocumentEncrypted() )
204 Add( new XclExpFileEncryption( GetRoot() ) );
205 Add( new XclExpInterfaceHdr( nCodePage
) );
206 Add( new XclExpUInt16Record( EXC_ID_MMS
, 0 ) );
207 Add( new XclExpInterfaceEnd
);
208 Add( new XclExpWriteAccess
);
211 Add( new XclExpFileSharing( GetRoot(), nWriteProtHash
, bRecommendReadOnly
) );
212 Add( new XclExpUInt16Record( EXC_ID_CODEPAGE
, nCodePage
) );
214 if( GetBiff() == EXC_BIFF8
)
216 Add( new XclExpBoolRecord( EXC_ID_DSF
, false ) );
217 Add( new XclExpEmptyRecord( EXC_ID_XL9FILE
) );
218 rR
.pTabId
= new XclExpChTrTabId( std::max( nExcTabCount
, nCodenames
) );
220 if( HasVbaStorage() )
222 Add( new XclObproj
);
223 const OUString
& rCodeName
= GetExtDocOptions().GetDocSettings().maGlobCodeName
;
224 if( !rCodeName
.isEmpty() )
225 Add( new XclCodename( rCodeName
) );
229 Add( new XclExpUInt16Record( EXC_ID_FNGROUPCOUNT
, 14 ) );
231 // first setup table names and contents
233 for( nC
= 0 ; nC
< nScTabCount
; nC
++ )
234 if( rTabInfo
.IsExportTab( nC
) )
236 rDoc
.GetName( nC
, aTmpString
);
237 *pTabNames
<< aTmpString
;
240 if ( GetBiff() <= EXC_BIFF5
)
242 // global link table: EXTERNCOUNT, EXTERNSHEET, NAME
243 aRecList
.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET
) );
244 aRecList
.AppendRecord( CreateRecord( EXC_ID_NAME
) );
247 // document protection options
248 lcl_AddWorkbookProtection( aRecList
, *this );
250 if( GetBiff() == EXC_BIFF8
)
252 Add( new XclExpProt4Rev
);
253 Add( new XclExpProt4RevPass
);
256 lcl_AddBookviews( aRecList
, *this );
258 Add( new XclExpXmlStartSingleElementRecord( XML_workbookPr
) );
259 if ( GetBiff() == EXC_BIFF8
&& GetOutput() != EXC_OUTPUT_BINARY
)
261 Add( new XclExpBoolRecord(0x0040, false, XML_backupFile
) ); // BACKUP
262 Add( new XclExpBoolRecord(0x008D, false, XML_showObjects
) ); // HIDEOBJ
265 if ( GetBiff() == EXC_BIFF8
)
267 Add( new XclExpBoolRecord(0x0040, false) ); // BACKUP
268 Add( new XclExpBoolRecord(0x008D, false) ); // HIDEOBJ
271 if( GetBiff() <= EXC_BIFF5
)
273 Add( new ExcDummy_040
);
274 Add( new Exc1904( rDoc
) );
275 Add( new ExcDummy_041
);
280 Add( new Exc1904( rDoc
) );
281 Add( new XclExpBoolRecord( 0x000E, !rDoc
.GetDocOptions().IsCalcAsShown() ) );
282 Add( new XclExpBoolRecord(0x01B7, false) ); // REFRESHALL
283 Add( new XclExpBoolRecord(0x00DA, false) ); // BOOKBOOL
286 // Formatting: FONT, FORMAT, XF, STYLE, PALETTE
287 aRecList
.AppendRecord( CreateRecord( EXC_ID_FONTLIST
) );
288 aRecList
.AppendRecord( CreateRecord( EXC_ID_FORMATLIST
) );
289 aRecList
.AppendRecord( CreateRecord( EXC_ID_XFLIST
) );
290 aRecList
.AppendRecord( CreateRecord( EXC_ID_PALETTE
) );
292 if( GetBiff() <= EXC_BIFF5
)
295 for( nC
= 0 ; nC
< nScTabCount
; nC
++ )
296 if( rTabInfo
.IsExportTab( nC
) )
298 ExcBoundsheetList::RecordRefType
xBoundsheet( new ExcBundlesheet( rR
, nC
) );
299 aRecList
.AppendRecord( xBoundsheet
);
300 rBoundsheetList
.AppendRecord( xBoundsheet
);
306 GetPivotTableManager().CreatePivotTables();
307 aRecList
.AppendRecord( GetPivotTableManager().CreatePivotCachesRecord() );
310 if( rDoc
.GetChangeTrack() )
312 rR
.pUserBViewList
= new XclExpUserBViewList( *rDoc
.GetChangeTrack() );
313 Add( rR
.pUserBViewList
);
316 // Natural Language Formulas Flag
317 aRecList
.AppendNewRecord( new XclExpBoolRecord( EXC_ID_USESELFS
, GetDoc().GetDocOptions().IsLookUpColRowNames() ) );
320 for( nC
= 0 ; nC
< nScTabCount
; nC
++ )
321 if( rTabInfo
.IsExportTab( nC
) )
323 ExcBoundsheetList::RecordRefType
xBoundsheet( new ExcBundlesheet8( rR
, nC
) );
324 aRecList
.AppendRecord( xBoundsheet
);
325 rBoundsheetList
.AppendRecord( xBoundsheet
);
328 for( SCTAB nAdd
= 0; nC
< static_cast<SCTAB
>(nCodenames
) ; nC
++, nAdd
++ )
330 aTmpString
= lcl_GetVbaTabName( nAdd
);
331 ExcBoundsheetList::RecordRefType
xBoundsheet( new ExcBundlesheet8( aTmpString
) );
332 aRecList
.AppendRecord( xBoundsheet
);
333 rBoundsheetList
.AppendRecord( xBoundsheet
);
336 // COUNTRY - in BIFF8 in workbook globals
337 Add( new XclExpCountry( GetRoot() ) );
339 // link table: SUPBOOK, XCT, CRN, EXTERNNAME, EXTERNSHEET, NAME
340 aRecList
.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET
) );
341 aRecList
.AppendRecord( CreateRecord( EXC_ID_NAME
) );
343 Add( new XclExpRecalcId
);
345 // MSODRAWINGGROUP per-document data
346 aRecList
.AppendRecord( GetObjectManager().CreateDrawingGroup() );
347 // Shared string table: SST, EXTSST
348 aRecList
.AppendRecord( CreateRecord( EXC_ID_SST
) );
350 Add( new XclExpBookExt
);
356 void ExcTable::FillAsHeaderXml( ExcBoundsheetList
& rBoundsheetList
)
360 RootData
& rR
= GetOldRoot();
361 ScDocument
& rDoc
= GetDoc();
362 XclExpTabInfo
& rTabInfo
= GetTabInfo();
366 SCTAB nScTabCount
= rTabInfo
.GetScTabCount();
367 sal_uInt16 nExcTabCount
= rTabInfo
.GetXclTabCount();
368 sal_uInt16 nCodenames
= static_cast< sal_uInt16
>( GetExtDocOptions().GetCodeNameCount() );
370 rR
.pTabId
= new XclExpChTrTabId( std::max( nExcTabCount
, nCodenames
) );
373 // first setup table names and contents
375 for( nC
= 0 ; nC
< nScTabCount
; nC
++ )
376 if( rTabInfo
.IsExportTab( nC
) )
378 rDoc
.GetName( nC
, aTmpString
);
379 *pTabNames
<< aTmpString
;
382 Add( new XclExpXmlStartSingleElementRecord( XML_workbookPr
) );
383 Add( new XclExpBoolRecord(0x0040, false, XML_backupFile
) ); // BACKUP
384 Add( new XclExpBoolRecord(0x008D, false, XML_showObjects
) ); // HIDEOBJ
386 Add( new Exc1904( rDoc
) );
387 // OOXTODO: The following /workbook/workbookPr attributes are mapped
388 // to various BIFF records that are not currently supported:
390 // XML_allowRefreshQuery: QSISTAG 802h: fEnableRefresh
391 // XML_autoCompressPictures: COMPRESSPICTURES 89Bh: fAutoCompressPictures
392 // XML_checkCompatibility: COMPAT12 88Ch: fNoCompatChk
393 // XML_codeName: "Calc"
394 // XML_defaultThemeVersion: ???
395 // XML_filterPrivacy: BOOKEXT 863h: fFilterPrivacy
396 // XML_hidePivotFieldList: BOOKBOOL DAh: fHidePivotTableFList
397 // XML_promptedSolutions: BOOKEXT 863h: fBuggedUserAboutSolution
398 // XML_publishItems: NAMEPUBLISH 893h: fPublished
399 // XML_saveExternalLinkValues: BOOKBOOL DAh: fNoSavSupp
400 // XML_showBorderUnselectedTables: BOOKBOOL DAh: fHideBorderUnsels
401 // XML_showInkAnnotation: BOOKEXT 863h: fShowInkAnnotation
402 // XML_showPivotChart: PIVOTCHARTBITS 859h: fGXHide??
403 // XML_updateLinks: BOOKBOOL DAh: grbitUpdateLinks
404 Add( new XclExpXmlEndSingleElementRecord() ); // XML_workbookPr
406 // Formatting: FONT, FORMAT, XF, STYLE, PALETTE
407 aRecList
.AppendNewRecord( new XclExpXmlStyleSheet( *this ) );
410 if( rDoc
.GetChangeTrack() )
412 rR
.pUserBViewList
= new XclExpUserBViewList( *rDoc
.GetChangeTrack() );
413 Add( rR
.pUserBViewList
);
416 lcl_AddWorkbookProtection( aRecList
, *this );
417 lcl_AddBookviews( aRecList
, *this );
420 aRecList
.AppendNewRecord( new XclExpXmlStartElementRecord( XML_sheets
) );
421 for( nC
= 0 ; nC
< nScTabCount
; nC
++ )
422 if( rTabInfo
.IsExportTab( nC
) )
424 ExcBoundsheetList::RecordRefType
xBoundsheet( new ExcBundlesheet8( rR
, nC
) );
425 aRecList
.AppendRecord( xBoundsheet
);
426 rBoundsheetList
.AppendRecord( xBoundsheet
);
428 aRecList
.AppendNewRecord( new XclExpXmlEndElementRecord( XML_sheets
) );
430 for( SCTAB nAdd
= 0; nC
< static_cast<SCTAB
>(nCodenames
) ; nC
++, nAdd
++ )
432 aTmpString
= lcl_GetVbaTabName( nAdd
);
433 ExcBoundsheetList::RecordRefType
xBoundsheet( new ExcBundlesheet8( aTmpString
) );
434 aRecList
.AppendRecord( xBoundsheet
);
435 rBoundsheetList
.AppendRecord( xBoundsheet
);
438 // link table: SUPBOOK, XCT, CRN, EXTERNNAME, EXTERNSHEET, NAME
439 aRecList
.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET
) );
440 aRecList
.AppendRecord( CreateRecord( EXC_ID_NAME
) );
442 lcl_AddCalcPr( aRecList
, *this );
444 // MSODRAWINGGROUP per-document data
445 aRecList
.AppendRecord( GetObjectManager().CreateDrawingGroup() );
446 // Shared string table: SST, EXTSST
447 aRecList
.AppendRecord( CreateRecord( EXC_ID_SST
) );
450 void ExcTable::FillAsTableBinary( SCTAB nCodeNameIdx
)
452 InitializeTable( mnScTab
);
454 RootData
& rR
= GetOldRoot();
455 XclBiff eBiff
= GetBiff();
456 ScDocument
& rDoc
= GetDoc();
458 OSL_ENSURE( (mnScTab
>= 0L) && (mnScTab
<= MAXTAB
), "-ExcTable::Table(): mnScTab - no ordinary table!" );
459 OSL_ENSURE( nExcTab
<= static_cast<sal_uInt16
>(MAXTAB
), "-ExcTable::Table(): nExcTab - no ordinary table!" );
461 // create a new OBJ list for this sheet (may be used by notes, autofilter, data validation)
462 if( eBiff
== EXC_BIFF8
)
463 GetObjectManager().StartSheet();
465 // cell table: DEFROWHEIGHT, DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
466 mxCellTable
.reset( new XclExpCellTable( GetRoot() ) );
469 std::vector
<sc::NoteEntry
> aNotes
;
470 rDoc
.GetAllNoteEntries(aNotes
);
471 for (std::vector
<sc::NoteEntry
>::const_iterator it
= aNotes
.begin(), itEnd
= aNotes
.end(); it
!= itEnd
; ++it
)
473 if (it
->maPos
.Tab() != mnScTab
)
476 mxNoteList
->AppendNewRecord(new XclExpNote(GetRoot(), it
->maPos
, it
->mpNote
, OUString()));
479 // WSBOOL needs data from page settings, create it here, add it later
480 std::shared_ptr
< XclExpPageSettings
> xPageSett( new XclExpPageSettings( GetRoot() ) );
481 bool bFitToPages
= xPageSett
->GetPageData().mbFitToPages
;
483 if( eBiff
<= EXC_BIFF5
)
486 Add( new ExcDummy_02a
);
491 lcl_AddCalcPr( aRecList
, *this );
494 // GUTS (count & size of outline icons)
495 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_GUTS
) );
496 // DEFROWHEIGHT, created by the cell table
497 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID2_DEFROWHEIGHT
) );
499 // COUNTRY - in BIFF5/7 in every worksheet
500 if( eBiff
<= EXC_BIFF5
)
501 Add( new XclExpCountry( GetRoot() ) );
503 Add( new XclExpWsbool( bFitToPages
) );
505 // page settings (SETUP and various other records)
506 aRecList
.AppendRecord( xPageSett
);
508 const ScTableProtection
* pTabProtect
= rDoc
.GetTabProtection(mnScTab
);
509 if (pTabProtect
&& pTabProtect
->isProtected())
511 Add( new XclExpProtection(true) );
512 Add( new XclExpBoolRecord(0x00DD, pTabProtect
->isOptionEnabled(ScTableProtection::SCENARIOS
)) );
513 Add( new XclExpBoolRecord(0x0063, pTabProtect
->isOptionEnabled(ScTableProtection::OBJECTS
)) );
514 Add( new XclExpPassHash(pTabProtect
->getPasswordHash(PASSHASH_XL
)) );
517 // local link table: EXTERNCOUNT, EXTERNSHEET
518 if( eBiff
<= EXC_BIFF5
)
519 aRecList
.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET
) );
521 if ( eBiff
== EXC_BIFF8
)
522 lcl_AddScenariosAndFilters( aRecList
, GetRoot(), mnScTab
);
524 // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
525 aRecList
.AppendRecord( mxCellTable
);
527 // MERGEDCELLS record, generated by the cell table
528 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_MERGEDCELLS
) );
530 if( eBiff
== EXC_BIFF8
)
531 Add( new XclExpLabelranges( GetRoot() ) );
532 // data validation (DVAL and list of DV records), generated by the cell table
533 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_DVAL
) );
535 if( eBiff
== EXC_BIFF8
)
537 // all MSODRAWING and OBJ stuff of this sheet goes here
538 aRecList
.AppendRecord( GetObjectManager().ProcessDrawing( GetSdrPage( mnScTab
) ) );
540 aRecList
.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab
) );
543 // list of NOTE records, generated by the cell table
544 aRecList
.AppendRecord( mxNoteList
);
546 // sheet view settings: WINDOW2, SCL, PANE, SELECTION
547 aRecList
.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab
) );
549 if( eBiff
== EXC_BIFF8
)
551 // sheet protection options
552 Add( new XclExpSheetProtectOptions( GetRoot(), mnScTab
) );
554 // enhanced protections if there are
557 const ::std::vector
<ScEnhancedProtection
>& rProts( pTabProtect
->getEnhancedProtection());
558 for (::std::vector
<ScEnhancedProtection
>::const_iterator
it( rProts
.begin()), itEnd( rProts
.end());
561 Add( new XclExpSheetEnhancedProtection( GetRoot(), *it
));
566 Add( new XclExpWebQueryBuffer( GetRoot() ) );
568 // conditional formats
569 Add( new XclExpCondFormatBuffer( GetRoot(), XclExtLstRef() ) );
571 if( HasVbaStorage() )
572 if( nCodeNameIdx
< GetExtDocOptions().GetCodeNameCount() )
573 Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx
) ) );
576 // list of HLINK records, generated by the cell table
577 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_HLINK
) );
580 if( rR
.pUserBViewList
)
582 XclExpUserBViewList::const_iterator iter
;
583 for ( iter
= rR
.pUserBViewList
->begin(); iter
!= rR
.pUserBViewList
->end(); ++iter
)
585 Add( new XclExpUsersViewBegin( (*iter
)->GetGUID(), nExcTab
) );
586 Add( new XclExpUsersViewEnd
);
594 void ExcTable::FillAsTableXml()
596 InitializeTable( mnScTab
);
598 ScDocument
& rDoc
= GetDoc();
600 OSL_ENSURE( (mnScTab
>= 0L) && (mnScTab
<= MAXTAB
), "-ExcTable::Table(): mnScTab - no ordinary table!" );
601 OSL_ENSURE( nExcTab
<= static_cast<sal_uInt16
>(MAXTAB
), "-ExcTable::Table(): nExcTab - no ordinary table!" );
603 // create a new OBJ list for this sheet (may be used by notes, autofilter, data validation)
604 GetObjectManager().StartSheet();
606 // cell table: DEFROWHEIGHT, DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
607 mxCellTable
.reset( new XclExpCellTable( GetRoot() ) );
610 std::vector
<sc::NoteEntry
> aNotes
;
611 rDoc
.GetAllNoteEntries(aNotes
);
612 for (std::vector
<sc::NoteEntry
>::const_iterator it
= aNotes
.begin(), itEnd
= aNotes
.end(); it
!= itEnd
; ++it
)
614 if (it
->maPos
.Tab() != mnScTab
)
617 mxNoteList
->AppendNewRecord(new XclExpNote(GetRoot(), it
->maPos
, it
->mpNote
, OUString()));
620 // WSBOOL needs data from page settings, create it here, add it later
621 std::shared_ptr
< XclExpPageSettings
> xPageSett( new XclExpPageSettings( GetRoot() ) );
622 XclExtLstRef
xExtLst( new XclExtLst( GetRoot() ) );
623 bool bFitToPages
= xPageSett
->GetPageData().mbFitToPages
;
625 Color aTabColor
= GetRoot().GetDoc().GetTabBgColor(mnScTab
);
626 Add(new XclExpXmlSheetPr(bFitToPages
, mnScTab
, aTabColor
, &GetFilterManager()));
628 // GUTS (count & size of outline icons)
629 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_GUTS
) );
630 // DEFROWHEIGHT, created by the cell table
631 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID2_DEFROWHEIGHT
) );
633 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID3_DIMENSIONS
) );
635 // sheet view settings: WINDOW2, SCL, PANE, SELECTION
636 aRecList
.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab
) );
638 // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
639 aRecList
.AppendRecord( mxCellTable
);
641 // list of NOTE records, generated by the cell table
642 // not in the worksheet file
643 if( mxNoteList
!= 0 && !mxNoteList
->IsEmpty() )
644 aRecList
.AppendNewRecord( new XclExpComments( mnScTab
, *mxNoteList
) );
646 const ScTableProtection
* pTabProtect
= rDoc
.GetTabProtection(mnScTab
);
647 if (pTabProtect
&& pTabProtect
->isProtected())
648 Add( new XclExpSheetProtection(true, mnScTab
) );
650 lcl_AddScenariosAndFilters( aRecList
, GetRoot(), mnScTab
);
652 // MERGEDCELLS record, generated by the cell table
653 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_MERGEDCELLS
) );
655 // conditional formats
656 Add( new XclExpCondFormatBuffer( GetRoot(), xExtLst
) );
658 // data validation (DVAL and list of DV records), generated by the cell table
659 aRecList
.AppendRecord( mxCellTable
->CreateRecord( EXC_ID_DVAL
) );
661 // list of HLINK records, generated by the cell table
662 XclExpRecordRef xHyperlinks
= mxCellTable
->CreateRecord( EXC_ID_HLINK
);
663 XclExpHyperlinkList
* xHyperlinkList
= dynamic_cast<XclExpHyperlinkList
*>(xHyperlinks
.get());
664 if( xHyperlinkList
!= NULL
&& !xHyperlinkList
->IsEmpty() )
666 aRecList
.AppendNewRecord( new XclExpXmlStartElementRecord( XML_hyperlinks
) );
667 aRecList
.AppendRecord( xHyperlinks
);
668 aRecList
.AppendNewRecord( new XclExpXmlEndElementRecord( XML_hyperlinks
) );
671 aRecList
.AppendRecord( xPageSett
);
673 // all MSODRAWING and OBJ stuff of this sheet goes here
674 aRecList
.AppendRecord( GetObjectManager().ProcessDrawing( GetSdrPage( mnScTab
) ) );
676 XclExpImgData
* pImgData
= xPageSett
->getGraphicExport();
678 aRecList
.AppendRecord(std::shared_ptr
<XclExpRecordBase
>(pImgData
));
680 aRecList
.AppendRecord( xExtLst
);
683 void ExcTable::FillAsEmptyTable( SCTAB nCodeNameIdx
)
685 InitializeTable( mnScTab
);
687 if( HasVbaStorage() && (nCodeNameIdx
< GetExtDocOptions().GetCodeNameCount()) )
689 if( GetBiff() <= EXC_BIFF5
)
696 Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx
) ) );
698 // sheet view settings: WINDOW2, SCL, PANE, SELECTION
699 aRecList
.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab
) );
704 void ExcTable::Write( XclExpStream
& rStrm
)
706 SetCurrScTab( mnScTab
);
707 if( mxCellTable
.get() )
708 mxCellTable
->Finalize();
709 aRecList
.Save( rStrm
);
712 void ExcTable::WriteXml( XclExpXmlStream
& rStrm
)
714 if (!GetTabInfo().IsExportTab(mnScTab
))
717 SetCurrScTab(mnScTab
);
719 mxCellTable
->Finalize();
720 aRecList
.SaveXml(rStrm
);
726 OUString sSheetName
= XclXmlUtils::GetStreamName( "xl/", "worksheets/sheet", mnScTab
+1 );
728 sax_fastparser::FSHelperPtr pWorksheet
= rStrm
.GetStreamForPath( sSheetName
);
730 rStrm
.PushStream( pWorksheet
);
732 pWorksheet
->startElement( XML_worksheet
,
733 XML_xmlns
, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
734 FSNS( XML_xmlns
, XML_r
), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
737 SetCurrScTab( mnScTab
);
739 mxCellTable
->Finalize();
740 aRecList
.SaveXml( rStrm
);
742 XclExpXmlPivotTables
* pPT
= GetXmlPivotTableManager().GetTablesBySheet(mnScTab
);
746 rStrm
.GetCurrentStream()->endElement( XML_worksheet
);
750 ExcDocument::ExcDocument( const XclExpRoot
& rRoot
) :
753 pExpChangeTrack( NULL
)
757 ExcDocument::~ExcDocument()
759 maTableList
.RemoveAllRecords(); // for the following assertion!
760 delete pExpChangeTrack
;
763 void ExcDocument::ReadDoc()
767 if (GetOutput() == EXC_OUTPUT_BINARY
)
768 aHeader
.FillAsHeaderBinary(maBoundsheetList
);
771 aHeader
.FillAsHeaderXml(maBoundsheetList
);
772 GetXmlPivotTableManager().Initialize();
775 SCTAB nScTab
= 0, nScTabCount
= GetTabInfo().GetScTabCount();
776 SCTAB nCodeNameIdx
= 0, nCodeNameCount
= GetExtDocOptions().GetCodeNameCount();
778 for( ; nScTab
< nScTabCount
; ++nScTab
)
780 if( GetTabInfo().IsExportTab( nScTab
) )
782 ExcTableList::RecordRefType
xTab( new ExcTable( GetRoot(), nScTab
) );
783 maTableList
.AppendRecord( xTab
);
784 if (GetOutput() == EXC_OUTPUT_BINARY
)
785 xTab
->FillAsTableBinary(nCodeNameIdx
);
787 xTab
->FillAsTableXml();
792 for( ; nCodeNameIdx
< nCodeNameCount
; ++nScTab
, ++nCodeNameIdx
)
794 ExcTableList::RecordRefType
xTab( new ExcTable( GetRoot(), nScTab
) );
795 maTableList
.AppendRecord( xTab
);
796 xTab
->FillAsEmptyTable( nCodeNameIdx
);
799 if ( GetBiff() == EXC_BIFF8
)
801 // complete temporary Escher stream
802 GetObjectManager().EndDocument();
805 if ( GetDoc().GetChangeTrack() )
806 pExpChangeTrack
= new XclExpChangeTrack( GetRoot() );
810 void ExcDocument::Write( SvStream
& rSvStrm
)
812 if( !maTableList
.IsEmpty() )
816 XclExpStream
aXclStrm( rSvStrm
, GetRoot() );
818 aHeader
.Write( aXclStrm
);
820 OSL_ENSURE( maTableList
.GetSize() == maBoundsheetList
.GetSize(),
821 "ExcDocument::Write - different number of sheets and BOUNDSHEET records" );
823 for( size_t nTab
= 0, nTabCount
= maTableList
.GetSize(); nTab
< nTabCount
; ++nTab
)
825 // set current stream position in BOUNDSHEET record
826 ExcBoundsheetRef xBoundsheet
= maBoundsheetList
.GetRecord( nTab
);
827 if( xBoundsheet
.get() )
828 xBoundsheet
->SetStreamPos( aXclStrm
.GetSvStreamPos() );
830 maTableList
.GetRecord( nTab
)->Write( aXclStrm
);
833 // write the table stream positions into the BOUNDSHEET records
834 for( size_t nBSheet
= 0, nBSheetCount
= maBoundsheetList
.GetSize(); nBSheet
< nBSheetCount
; ++nBSheet
)
835 maBoundsheetList
.GetRecord( nBSheet
)->UpdateStreamPos( aXclStrm
);
837 if( pExpChangeTrack
)
838 pExpChangeTrack
->Write();
841 void ExcDocument::WriteXml( XclExpXmlStream
& rStrm
)
843 SfxObjectShell
* pDocShell
= GetDocShell();
845 using namespace ::com::sun::star
;
846 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS( pDocShell
->GetModel(), uno::UNO_QUERY_THROW
);
847 uno::Reference
<document::XDocumentProperties
> xDocProps
= xDPS
->getDocumentProperties();
849 rStrm
.exportDocumentProperties( xDocProps
);
851 sax_fastparser::FSHelperPtr
& rWorkbook
= rStrm
.GetCurrentStream();
852 rWorkbook
->startElement( XML_workbook
,
853 XML_xmlns
, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
854 FSNS(XML_xmlns
, XML_r
), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
856 rWorkbook
->singleElement( XML_fileVersion
,
858 // OOXTODO: XML_codeName
859 // OOXTODO: XML_lastEdited
860 // OOXTODO: XML_lowestEdited
861 // OOXTODO: XML_rupBuild
864 if( !maTableList
.IsEmpty() )
868 aHeader
.WriteXml( rStrm
);
870 for( size_t nTab
= 0, nTabCount
= maTableList
.GetSize(); nTab
< nTabCount
; ++nTab
)
873 maTableList
.GetRecord( nTab
)->WriteXml( rStrm
);
877 if( pExpChangeTrack
)
878 pExpChangeTrack
->WriteXml( rStrm
);
880 XclExpXmlPivotCaches
& rCaches
= GetXmlPivotTableManager().GetCaches();
881 if (rCaches
.HasCaches())
882 rCaches
.SaveXml(rStrm
);
884 const ScCalcConfig
& rCalcConfig
= GetDoc().GetCalcConfig();
885 formula::FormulaGrammar::AddressConvention eConv
= rCalcConfig
.meStringRefAddressSyntax
;
887 // don't save "unspecified" string ref syntax ... query formula grammar
888 // and save that instead
889 if( eConv
== formula::FormulaGrammar::CONV_UNSPECIFIED
)
891 eConv
= GetDoc().GetAddressConvention();
894 // write if it has been read|imported or explicitly changed
895 // or if ref syntax isn't what would be native for our file format
896 // i.e. ExcelA1 in this case
897 if ( rCalcConfig
.mbHasStringRefSyntax
||
898 (eConv
!= formula::FormulaGrammar::CONV_XL_A1
) )
900 XclExtLstRef
xExtLst( new XclExtLst( GetRoot() ) );
901 xExtLst
->AddRecord( XclExpExtRef( new XclExpExtCalcPr( GetRoot(), eConv
)) );
902 xExtLst
->SaveXml(rStrm
);
905 rWorkbook
->endElement( XML_workbook
);
909 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */