Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / filter / excel / excdoc.cxx
bloba1a2a75443d4bea88e0c63a49761f85ac0934c3e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
38 #include "dbdata.hxx"
39 #include "global.hxx"
40 #include "globstr.hrc"
41 #include "progress.hxx"
42 #include "conditio.hxx"
43 #include "dpobject.hxx"
44 #include "attrib.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"
54 #include "postit.hxx"
56 #include "excdoc.hxx"
57 #include "namebuff.hxx"
58 #include "xeextlst.hxx"
60 #include "xcl97rec.hxx"
61 #include "xcl97esc.hxx"
62 #include "xetable.hxx"
63 #include "xelink.hxx"
64 #include "xename.hxx"
65 #include "xepage.hxx"
66 #include "xeview.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"
74 #include <math.h>
76 #include <com/sun/star/document/XDocumentProperties.hpp>
77 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
78 #include <oox/token/tokens.hxx>
79 #include <memory>
81 using namespace oox;
83 static OUString lcl_GetVbaTabName( SCTAB n )
85 OUString aRet = "__VBA__" + OUString::number( static_cast<sal_uInt16>(n) );
86 return aRet;
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 )
129 // Scenarios
130 aRecList.AppendNewRecord( new ExcEScenarioManager( rRoot, nScTab ) );
131 // filter
132 aRecList.AppendRecord( rRoot.GetFilterManager().CreateRecord( nScTab ) );
135 ExcTable::ExcTable( const XclExpRoot& rRoot ) :
136 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 ) :
145 XclExpRoot( rRoot ),
146 mnScTab( nScTab ),
147 nExcTab( rRoot.GetTabInfo().GetXclTab( nScTab ) ),
148 pTabNames( new NameBuffer( nullptr, 16 ) ),
149 mxNoteList( new XclExpNoteList )
153 ExcTable::~ExcTable()
155 delete pTabNames;
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 )
166 InitializeGlobals();
168 RootData& rR = GetOldRoot();
169 ScDocument& rDoc = GetDoc();
170 XclExpTabInfo& rTabInfo = GetTabInfo();
172 if ( GetBiff() <= EXC_BIFF5 )
173 Add( new ExcBofW );
174 else
175 Add( new ExcBofW8 );
177 SCTAB nC;
178 OUString aTmpString;
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 );
202 else
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 ) );
220 Add( rR.pTabId );
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 );
278 else
280 // BIFF8
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 )
295 // Bundlesheet
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 );
304 else
306 // Pivot Cache
307 GetPivotTableManager().CreatePivotTables();
308 aRecList.AppendRecord( GetPivotTableManager().CreatePivotCachesRecord() );
310 // Change tracking
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() ) );
320 // Bundlesheet
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 );
354 Add( new ExcEof );
357 void ExcTable::FillAsHeaderXml( ExcBoundsheetList& rBoundsheetList )
359 InitializeGlobals();
361 RootData& rR = GetOldRoot();
362 ScDocument& rDoc = GetDoc();
363 XclExpTabInfo& rTabInfo = GetTabInfo();
365 SCTAB nC;
366 OUString aTmpString;
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 ) );
372 Add( rR.pTabId );
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 ) );
410 // Change tracking
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 );
420 // Bundlesheet
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() ) );
469 //export cell notes
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)
475 continue;
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 )
486 Add( new ExcBof );
487 Add( new ExcDummy_02a );
489 else
491 Add( new ExcBof8 );
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 ) );
530 // label ranges
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 ) ) );
540 // pivot tables
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
556 if (pTabProtect)
558 const ::std::vector<ScEnhancedProtection>& rProts( pTabProtect->getEnhancedProtection());
559 for (::std::vector<ScEnhancedProtection>::const_iterator it( rProts.begin()), itEnd( rProts.end());
560 it != itEnd; ++it)
562 Add( new XclExpSheetEnhancedProtection( GetRoot(), *it));
566 // web queries
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 ) );
580 // change tracking
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 );
591 // EOF
592 Add( new ExcEof );
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() ) );
610 //export cell notes
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)
616 continue;
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();
678 if (pImgData)
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 )
695 Add( new ExcBof );
697 else
699 Add( new ExcBof8 );
700 Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx ) ) );
702 // sheet view settings: WINDOW2, SCL, PANE, SELECTION
703 aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
704 Add( new ExcEof );
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))
720 // header export.
721 SetCurrScTab(mnScTab);
722 if (mxCellTable)
723 mxCellTable->Finalize();
724 aRecList.SaveXml(rStrm);
726 return;
729 // worksheet export
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",
739 FSEND );
741 SetCurrScTab( mnScTab );
742 if (mxCellTable)
743 mxCellTable->Finalize();
744 aRecList.SaveXml( rStrm );
746 XclExpXmlPivotTables* pPT = GetXmlPivotTableManager().GetTablesBySheet(mnScTab);
747 if (pPT)
748 pPT->SaveXml(rStrm);
750 rStrm.GetCurrentStream()->endElement( XML_worksheet );
751 rStrm.PopStream();
754 ExcDocument::ExcDocument( const XclExpRoot& rRoot ) :
755 XclExpRoot( rRoot ),
756 aHeader( rRoot ),
757 pExpChangeTrack( nullptr )
761 ExcDocument::~ExcDocument()
763 maTableList.RemoveAllRecords(); // for the following assertion!
764 delete pExpChangeTrack;
767 void ExcDocument::ReadDoc()
769 InitializeConvert();
771 if (GetOutput() == EXC_OUTPUT_BINARY)
772 aHeader.FillAsHeaderBinary(maBoundsheetList);
773 else
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);
791 else
792 xTab->FillAsTableXml();
794 ++nCodeNameIdx;
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();
809 // change tracking
810 if ( GetDoc().GetChangeTrack() )
811 pExpChangeTrack = new XclExpChangeTrack( GetRoot() );
815 void ExcDocument::Write( SvStream& rSvStrm )
817 if( !maTableList.IsEmpty() )
819 InitializeSave();
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() );
834 // write the table
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",
860 FSEND );
861 rWorkbook->singleElement( XML_fileVersion,
862 XML_appName, "Calc",
863 // OOXTODO: XML_codeName
864 // OOXTODO: XML_lastEdited
865 // OOXTODO: XML_lowestEdited
866 // OOXTODO: XML_rupBuild
867 FSEND );
869 if( !maTableList.IsEmpty() )
871 InitializeSave();
873 aHeader.WriteXml( rStrm );
875 for( size_t nTab = 0, nTabCount = maTableList.GetSize(); nTab < nTabCount; ++nTab )
877 // write the table
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 );
911 rWorkbook.reset();
914 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */