Update to m13
[ooovba.git] / sc / source / filter / xlsx / xlsx-excdoc.cxx
blob29ab49917204e8c5b67722d51a45876106f9f3ea
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: excdoc.cxx,v $
10 * $Revision: 1.69.60.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 #include "xlsx/xladdress.hxx"
35 #include "xlsx/xlconst.hxx"
36 #include "xlsx/xlformula.hxx"
37 #include "xlsx/xetable.hxx"
39 //------------------------------------------------------------------------
41 #include "scitems.hxx"
43 #include <comphelper/processfactory.hxx>
44 #include <svx/svdobj.hxx>
45 #include <svx/svditer.hxx>
46 #include <svx/svdpage.hxx>
47 #include <svx/lrspitem.hxx>
48 #include <svx/ulspitem.hxx>
49 #include <svtools/intitem.hxx>
50 #include <svtools/zformat.hxx>
51 #include <sot/storage.hxx>
52 #include <sfx2/objsh.hxx>
53 #include <tools/urlobj.hxx>
54 #include <rtl/ustring.hxx>
56 #include "cell.hxx"
57 #include "dociter.hxx"
58 #include "document.hxx"
59 #include "rangenam.hxx"
60 #include "dbcolect.hxx"
61 #include "global.hxx"
62 #include "globstr.hrc"
63 #include "progress.hxx"
64 #include "conditio.hxx"
65 #include "dpobject.hxx"
66 #include "attrib.hxx"
67 #include "scextopt.hxx"
68 #include "stlsheet.hxx"
69 #include "stlpool.hxx"
70 #include "olinetab.hxx"
71 #include "unonames.hxx"
72 #include "convuno.hxx"
73 #include "patattr.hxx"
74 #include "docoptio.hxx"
75 #include "tabprotection.hxx"
77 #include "excdoc.hxx"
78 #include "namebuff.hxx"
80 #include "xcl97rec.hxx"
81 #include "xcl97esc.hxx"
82 #include "xetable.hxx"
83 #include "xelink.hxx"
84 #include "xename.hxx"
85 #include "xepage.hxx"
86 #include "xeview.hxx"
87 #include "xecontent.hxx"
88 #include "xeescher.hxx"
89 #include "xepivot.hxx"
90 #include "XclExpChangeTrack.hxx"
92 #include <math.h>
94 #include <com/sun/star/document/XDocumentProperties.hpp>
95 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
96 #include <oox/core/tokens.hxx>
98 using ::rtl::OString;
100 static String lcl_GetVbaTabName( SCTAB n )
102 String aRet( RTL_CONSTASCII_USTRINGPARAM( "__VBA__" ) );
103 aRet += String::CreateFromInt32( static_cast<sal_uInt16>(n) );
104 return aRet;
108 static void lcl_AddBookviews( XclExpRecordList<>& aRecList, ExcTable& self )
110 aRecList.AppendNewRecord( new XclExpXmlStartElementRecord( XML_bookViews ) );
111 aRecList.AppendNewRecord( new XclExpWindow1( self.GetRoot() ) );
112 aRecList.AppendNewRecord( new XclExpXmlEndElementRecord( XML_bookViews ) );
115 static void lcl_AddCalcPr( XclExpRecordList<>& aRecList, ExcTable& self )
117 ScDocument& rDoc = self.GetDoc();
119 aRecList.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_calcPr ) );
120 // OOXTODO: calcCompleted, calcId, calcMode, calcOnSave,
121 // concurrentCalc, concurrentManualCount,
122 // forceFullCalc, fullCalcOnLoad, fullPrecision
123 aRecList.AppendNewRecord( new XclCalccount( rDoc ) );
124 aRecList.AppendNewRecord( new XclRefmode( rDoc ) );
125 aRecList.AppendNewRecord( new XclIteration( rDoc ) );
126 aRecList.AppendNewRecord( new XclDelta( rDoc ) );
127 aRecList.AppendNewRecord( new XclExpBoolRecord(0x005F, true) ); // SAVERECALC
128 aRecList.AppendNewRecord( new XclExpXmlEndSingleElementRecord() ); // XML_calcPr
131 static void lcl_AddWorkbookProtection( XclExpRecordList<>& aRecList, ExcTable& self )
133 aRecList.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_workbookProtection ) );
135 const ScDocProtection* pProtect = self.GetDoc().GetDocProtection();
136 if (pProtect && pProtect->isProtected())
138 aRecList.AppendNewRecord( new XclExpWindowProtection(pProtect->isOptionEnabled(ScDocProtection::WINDOWS)) );
139 aRecList.AppendNewRecord( new XclExpProtection(pProtect->isOptionEnabled(ScDocProtection::STRUCTURE)) );
140 #if ENABLE_SHEET_PROTECTION
141 aRecList.AppendNewRecord( new XclExpPassHash(pProtect->getPasswordHash(PASSHASH_XL)) );
142 #endif
145 aRecList.AppendNewRecord( new XclExpXmlEndSingleElementRecord() ); // XML_workbookProtection
148 static void lcl_AddScenariosAndFilters( XclExpRecordList<>& aRecList, ExcTable& self, SCTAB mnScTab )
150 // Scenarios
151 aRecList.AppendNewRecord( new ExcEScenarioManager( self.GetDoc(), mnScTab ) );
152 // filter
153 aRecList.AppendRecord( self.GetFilterManager().CreateRecord( mnScTab ) );
157 ExcTable::ExcTable( const XclExpRoot& rRoot ) :
158 XclExpRoot( rRoot ),
159 mnScTab( SCTAB_GLOBAL ),
160 nExcTab( EXC_NOTAB ),
161 pTabNames( new NameBuffer( 0, 16 ) )
166 ExcTable::ExcTable( const XclExpRoot& rRoot, SCTAB nScTab ) :
167 XclExpRoot( rRoot ),
168 mnScTab( nScTab ),
169 nExcTab( rRoot.GetTabInfo().GetXclTab( nScTab ) ),
170 pTabNames( new NameBuffer( 0, 16 ) )
175 ExcTable::~ExcTable()
177 delete pTabNames;
181 void ExcTable::Add( XclExpRecordBase* pRec )
183 DBG_ASSERT( pRec, "-ExcTable::Add(): pRec ist NULL!" );
184 aRecList.AppendNewRecord( pRec );
188 void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList )
190 InitializeGlobals();
192 RootData& rR = GetOldRoot();
193 ScDocument& rDoc = GetDoc();
194 XclExpTabInfo& rTabInfo = GetTabInfo();
196 if ( GetBiff() <= EXC_BIFF5 )
197 Add( new ExcBofW );
198 else
199 Add( new ExcBofW8 );
201 SCTAB nC;
202 String aTmpString;
203 SCTAB nScTabCount = rTabInfo.GetScTabCount();
204 UINT16 nExcTabCount = rTabInfo.GetXclTabCount();
205 UINT16 nCodenames = static_cast< UINT16 >( GetExtDocOptions().GetCodeNameCount() );
207 rR.pObjRecs = NULL; // per sheet
209 if( GetBiff() <= EXC_BIFF5 )
210 Add( new ExcDummy_00 );
211 else
213 if ( IsDocumentEncrypted() )
214 Add( new XclExpFilePass(GetRoot()) );
216 Add( new XclExpInterfaceHdr );
217 Add( new XclExpMMS );
218 Add( new XclExpInterfaceEnd );
219 Add( new XclExpWriteAccess );
220 Add( new XclExpCodePage );
221 Add( new XclExpDSF );
222 Add( new XclExpExcel9File );
223 rR.pTabId = new XclExpChTrTabId( Max( nExcTabCount, nCodenames ) );
224 Add( rR.pTabId );
225 if( HasVbaStorage() )
227 Add( new XclObproj );
228 const String& rCodeName = GetExtDocOptions().GetDocSettings().maGlobCodeName;
229 if( rCodeName.Len() )
230 Add( new XclCodename( rCodeName ) );
233 Add( new XclExpFnGroupCount );
236 // erst Namen- und Tabellen-Eintraege aufbauen
237 String aName;
239 for( nC = 0 ; nC < nScTabCount ; nC++ )
240 if( rTabInfo.IsExportTab( nC ) )
242 rDoc.GetName( nC, aTmpString );
243 *pTabNames << aTmpString;
246 if ( GetBiff() <= EXC_BIFF5 )
248 // global link table: EXTERNCOUNT, EXTERNSHEET, NAME
249 aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
250 aRecList.AppendRecord( CreateRecord( EXC_ID_NAME ) );
253 // document protection options
254 if( GetOutput() == EXC_OUTPUT_BINARY )
256 lcl_AddWorkbookProtection( aRecList, *this );
258 if( GetBiff() == EXC_BIFF8 )
260 Add( new XclExpProt4Rev );
261 Add( new XclExpProt4RevPass );
264 lcl_AddBookviews( aRecList, *this );
267 Add( new XclExpXmlStartSingleElementRecord( XML_workbookPr ) );
268 if ( GetBiff() == EXC_BIFF8 && GetOutput() != EXC_OUTPUT_BINARY )
270 Add( new XclExpBoolRecord(0x0040, false, XML_backupFile ) ); // BACKUP
271 Add( new XclExpBoolRecord(0x008D, false, XML_showObjects ) ); // HIDEOBJ
274 if ( GetBiff() == EXC_BIFF8 )
276 Add( new XclExpBoolRecord(0x0040, false) ); // BACKUP
277 Add( new XclExpBoolRecord(0x008D, false) ); // HIDEOBJ
280 if( GetBiff() <= EXC_BIFF5 )
282 Add( new ExcDummy_040 );
283 Add( new Exc1904( rDoc ) );
284 Add( new ExcDummy_041 );
286 else
288 // BIFF8
289 Add( new Exc1904( rDoc ) );
290 Add( new XclExpBoolRecord( 0x000E, !rDoc.GetDocOptions().IsCalcAsShown() ) );
291 Add( new XclExpBoolRecord(0x01B7, false) ); // REFRESHALL
292 Add( new XclExpBoolRecord(0x00DA, false) ); // BOOKBOOL
294 // OOXTODO: The following /workbook/workbookPr attributes are mapped
295 // to various BIFF records that are not currently supported:
297 // XML_allowRefreshQuery: QSISTAG 802h: fEnableRefresh
298 // XML_autoCompressPictures: COMPRESSPICTURES 89Bh: fAutoCompressPictures
299 // XML_checkCompatibility: COMPAT12 88Ch: fNoCompatChk
300 // XML_codeName: "Calc"
301 // XML_defaultThemeVersion: ???
302 // XML_filterPrivacy: BOOKEXT 863h: fFilterPrivacy
303 // XML_hidePivotFieldList: BOOKBOOL DAh: fHidePivotTableFList
304 // XML_promptedSolutions: BOOKEXT 863h: fBuggedUserAboutSolution
305 // XML_publishItems: NAMEPUBLISH 893h: fPublished
306 // XML_saveExternalLinkValues: BOOKBOOL DAh: fNoSavSupp
307 // XML_showBorderUnselectedTables: BOOKBOOL DAh: fHideBorderUnsels
308 // XML_showInkAnnotation: BOOKEXT 863h: fShowInkAnnotation
309 // XML_showPivotChart: PIVOTCHARTBITS 859h: fGXHide??
310 // XML_updateLinks: BOOKBOOL DAh: grbitUpdateLinks
312 Add( new XclExpXmlEndSingleElementRecord() ); // XML_workbookPr
314 // Formatting: FONT, FORMAT, XF, STYLE, PALETTE
315 if( GetOutput() != EXC_OUTPUT_BINARY )
317 aRecList.AppendNewRecord( new XclExpXmlStyleSheet( *this ) );
319 else
321 aRecList.AppendRecord( CreateRecord( EXC_ID_FONTLIST ) );
322 aRecList.AppendRecord( CreateRecord( EXC_ID_FORMATLIST ) );
323 aRecList.AppendRecord( CreateRecord( EXC_ID_XFLIST ) );
324 aRecList.AppendRecord( CreateRecord( EXC_ID_PALETTE ) );
328 if( GetBiff() <= EXC_BIFF5 )
330 // Bundlesheet
331 for( nC = 0 ; nC < nScTabCount ; nC++ )
332 if( rTabInfo.IsExportTab( nC ) )
334 ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet( rR, nC ) );
335 aRecList.AppendRecord( xBoundsheet );
336 rBoundsheetList.AppendRecord( xBoundsheet );
339 else
341 // Pivot Cache
342 GetPivotTableManager().CreatePivotTables();
343 aRecList.AppendRecord( GetPivotTableManager().CreatePivotCachesRecord() );
345 // Change tracking
346 if( rDoc.GetChangeTrack() )
348 rR.pUserBViewList = new XclExpUserBViewList( *rDoc.GetChangeTrack() );
349 Add( rR.pUserBViewList );
352 // Natural Language Formulas Flag
353 aRecList.AppendNewRecord( new XclExpBoolRecord( EXC_ID_USESELFS, GetDoc().GetDocOptions().IsLookUpColRowNames() ) );
355 if( GetOutput() != EXC_OUTPUT_BINARY )
357 lcl_AddWorkbookProtection( aRecList, *this );
358 lcl_AddBookviews( aRecList, *this );
361 // Bundlesheet
362 aRecList.AppendNewRecord( new XclExpXmlStartElementRecord( XML_sheets ) );
363 for( nC = 0 ; nC < nScTabCount ; nC++ )
364 if( rTabInfo.IsExportTab( nC ) )
366 ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet8( rR, nC ) );
367 aRecList.AppendRecord( xBoundsheet );
368 rBoundsheetList.AppendRecord( xBoundsheet );
370 aRecList.AppendNewRecord( new XclExpXmlEndElementRecord( XML_sheets ) );
372 for( SCTAB nAdd = 0; nC < static_cast<SCTAB>(nCodenames) ; nC++, nAdd++ )
374 aTmpString = lcl_GetVbaTabName( nAdd );
375 ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet8( aTmpString ) );
376 aRecList.AppendRecord( xBoundsheet );
377 rBoundsheetList.AppendRecord( xBoundsheet );
380 // COUNTRY - in BIFF8 in workbook globals
381 Add( new XclExpCountry( GetRoot() ) );
382 // link table: SUPBOOK, XCT, CRN, EXTERNNAME, EXTERNSHEET, NAME
383 aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
384 aRecList.AppendRecord( CreateRecord( EXC_ID_NAME ) );
386 if( GetOutput() != EXC_OUTPUT_BINARY )
387 lcl_AddCalcPr( aRecList, *this );
389 Add( new XclExpRecalcId );
391 // MSODRAWINGGROUP per-document data
392 Add( new XclMsodrawinggroup( rR, ESCHER_DggContainer ) );
393 // Shared string table: SST, EXTSST
394 aRecList.AppendRecord( CreateRecord( EXC_ID_SST ) );
396 Add( new XclExpBookExt );
399 Add( new ExcEof );
403 void ExcTable::FillAsTable( size_t nCodeNameIdx )
405 InitializeTable( mnScTab );
407 RootData& rR = GetOldRoot();
408 XclBiff eBiff = GetBiff();
409 ScDocument& rDoc = GetDoc();
411 DBG_ASSERT( (mnScTab >= 0L) && (mnScTab <= MAXTAB), "-ExcTable::Table(): mnScTab - no ordinary table!" );
412 DBG_ASSERT( nExcTab <= static_cast<sal_uInt16>(MAXTAB), "-ExcTable::Table(): nExcTab - no ordinary table!" );
414 if ( eBiff == EXC_BIFF8 )
415 // list holding OBJ records and creating MSODRAWING per-sheet data
416 rR.pObjRecs = new XclObjList( GetRoot(), mnScTab );
418 // cell table: DEFROWHEIGHT, DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
419 mxCellTable.reset( new XclExpCellTable( GetRoot() ) );
421 if( GetOutput() != EXC_OUTPUT_BINARY )
423 FillAsXmlTable( nCodeNameIdx );
424 return;
428 // WSBOOL needs data from page settings, create it here, add it later
429 ScfRef< XclExpPageSettings > xPageSett( new XclExpPageSettings( GetRoot() ) );
430 bool bFitToPages = xPageSett->GetPageData().mbFitToPages;
432 if( eBiff <= EXC_BIFF5 )
434 Add( new ExcBof );
435 Add( new ExcDummy_02a );
437 else
439 Add( new ExcBof8 );
440 lcl_AddCalcPr( aRecList, *this );
443 // GUTS (count & size of outline icons)
444 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_GUTS ) );
445 // DEFROWHEIGHT, created by the cell table
446 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID2_DEFROWHEIGHT ) );
448 // COUNTRY - in BIFF5/7 in every worksheet
449 if( eBiff <= EXC_BIFF5 )
450 Add( new XclExpCountry( GetRoot() ) );
452 Add( new XclExpWsbool( bFitToPages ) );
454 // page settings (SETUP and various other records)
455 aRecList.AppendRecord( xPageSett );
457 const ScTableProtection* pTabProtect = rDoc.GetTabProtection(mnScTab);
458 if (pTabProtect && pTabProtect->isProtected())
460 Add( new XclExpProtection(true) );
461 Add( new XclExpBoolRecord(0x00DD, pTabProtect->isOptionEnabled(ScTableProtection::SCENARIOS)) );
462 Add( new XclExpBoolRecord(0x0063, pTabProtect->isOptionEnabled(ScTableProtection::OBJECTS)) );
463 #if ENABLE_SHEET_PROTECTION
464 Add( new XclExpPassHash(pTabProtect->getPasswordHash(PASSHASH_XL)) );
465 #endif
468 // local link table: EXTERNCOUNT, EXTERNSHEET
469 if( eBiff <= EXC_BIFF5 )
470 aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
472 if ( eBiff == EXC_BIFF8 )
473 lcl_AddScenariosAndFilters( aRecList, *this, mnScTab );
475 // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
476 aRecList.AppendRecord( mxCellTable );
478 // MERGEDCELLS record, generated by the cell table
479 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_MERGEDCELLS ) );
480 // label ranges
481 if( eBiff == EXC_BIFF8 )
482 Add( new XclExpLabelranges( GetRoot() ) );
483 // data validation (DVAL and list of DV records), generated by the cell table
484 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_DVAL ) );
486 if( eBiff == EXC_BIFF8 )
488 rR.pEscher->AddSdrPage();
489 //! close Escher group shape and ESCHER_DgContainer
490 //! opened by XclObjList ctor MSODRAWING
491 rR.pObjRecs->EndSheet();
492 // all MSODRAWING and OBJ stuff of this sheet goes here
493 Add( rR.pObjRecs );
495 // pivot tables
496 aRecList.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab ) );
499 // list of NOTE records, generated by the cell table
500 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_NOTE ) );
502 // sheet view settings: WINDOW2, SCL, PANE, SELECTION
503 aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
505 if( eBiff == EXC_BIFF8 )
507 // sheet protection options
508 Add( new XclExpSheetProtectOptions( GetRoot(), mnScTab ) );
510 // web queries
511 Add( new XclExpWebQueryBuffer( GetRoot() ) );
513 // conditional formats
514 Add( new XclExpCondFormatBuffer( GetRoot() ) );
516 if( HasVbaStorage() )
517 if( nCodeNameIdx < GetExtDocOptions().GetCodeNameCount() )
518 Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx ) ) );
521 // list of HLINK records, generated by the cell table
522 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_HLINK ) );
524 // change tracking
525 if( rR.pUserBViewList )
527 for( const XclExpUserBView* pBView = rR.pUserBViewList->First(); pBView; pBView = rR.pUserBViewList->Next() )
529 Add( new XclExpUsersViewBegin( pBView->GetGUID(), nExcTab ) );
530 Add( new XclExpUsersViewEnd );
534 // EOF
535 Add( new ExcEof );
538 void ExcTable::FillAsXmlTable( size_t nCodeNameIdx )
540 RootData& rR = GetOldRoot();
542 // WSBOOL needs data from page settings, create it here, add it later
543 ScfRef< XclExpPageSettings > xPageSett( new XclExpPageSettings( GetRoot() ) );
544 bool bFitToPages = xPageSett->GetPageData().mbFitToPages;
546 Add( new ExcBof8 );
548 Add( new XclExpWsbool( bFitToPages, mnScTab, &GetFilterManager() ) );
550 // GUTS (count & size of outline icons)
551 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_GUTS ) );
552 // DEFROWHEIGHT, created by the cell table
553 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID2_DEFROWHEIGHT ) );
555 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID3_DIMENSIONS ) );
557 // sheet view settings: WINDOW2, SCL, PANE, SELECTION
558 aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
560 // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
561 aRecList.AppendRecord( mxCellTable );
563 // label ranges
564 Add( new XclExpLabelranges( GetRoot() ) );
566 rR.pEscher->AddSdrPage();
567 //! close Escher group shape and ESCHER_DgContainer
568 //! opened by XclObjList ctor MSODRAWING
569 rR.pObjRecs->EndSheet();
571 // pivot tables
572 aRecList.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab ) );
574 // list of NOTE records, generated by the cell table
575 XclExpRecordRef xNotes = mxCellTable->CreateRecord( EXC_ID_NOTE );
576 XclExpRecordList< XclExpNote >* xNoteList = dynamic_cast< XclExpRecordList< XclExpNote >* >( xNotes.get() );
577 if( xNoteList != NULL )
578 aRecList.AppendNewRecord( new XclExpComments( mnScTab, *xNoteList ) );
580 // web queries
581 Add( new XclExpWebQueryBuffer( GetRoot() ) );
583 lcl_AddScenariosAndFilters( aRecList, *this, mnScTab );
585 // MERGEDCELLS record, generated by the cell table
586 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_MERGEDCELLS ) );
588 // conditional formats
589 Add( new XclExpCondFormatBuffer( GetRoot() ) );
591 if( HasVbaStorage() )
592 if( nCodeNameIdx < GetExtDocOptions().GetCodeNameCount() )
593 Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx ) ) );
595 // data validation (DVAL and list of DV records), generated by the cell table
596 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_DVAL ) );
598 // list of HLINK records, generated by the cell table
599 XclExpRecordRef xHyperlinks = mxCellTable->CreateRecord( EXC_ID_HLINK );
600 XclExpHyperlinkList* xHyperlinkList = dynamic_cast<XclExpHyperlinkList*>(xHyperlinks.get());
601 if( xHyperlinkList != NULL && !xHyperlinkList->IsEmpty() )
603 aRecList.AppendNewRecord( new XclExpXmlStartElementRecord( XML_hyperlinks ) );
604 aRecList.AppendRecord( xHyperlinks );
605 aRecList.AppendNewRecord( new XclExpXmlEndElementRecord( XML_hyperlinks ) );
608 aRecList.AppendRecord( xPageSett );
610 // change tracking
611 if( rR.pUserBViewList )
613 for( const XclExpUserBView* pBView = rR.pUserBViewList->First(); pBView; pBView = rR.pUserBViewList->Next() )
615 Add( new XclExpUsersViewBegin( pBView->GetGUID(), nExcTab ) );
616 Add( new XclExpUsersViewEnd );
620 // all MSODRAWING and OBJ stuff of this sheet goes here
621 Add( rR.pObjRecs );
623 // EOF
624 Add( new ExcEof );
628 void ExcTable::FillAsEmptyTable( size_t nCodeNameIdx )
630 InitializeTable( mnScTab );
632 if( HasVbaStorage() && (nCodeNameIdx < GetExtDocOptions().GetCodeNameCount()) )
634 if( GetBiff() <= EXC_BIFF5 )
636 Add( new ExcBof );
638 else
640 Add( new ExcBof8 );
641 Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx ) ) );
643 // sheet view settings: WINDOW2, SCL, PANE, SELECTION
644 aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
645 Add( new ExcEof );
650 void ExcTable::Write( XclExpStream& rStrm )
652 SetCurrScTab( mnScTab );
653 if( mxCellTable.get() )
654 mxCellTable->Finalize();
655 aRecList.Save( rStrm );
659 void ExcTable::WriteXml( XclExpXmlStream& rStrm )
661 if (GetTabInfo().IsExportTab( mnScTab ) )
663 // worksheet export
664 String sSheetName = XclXmlUtils::GetStreamName( "xl/", "worksheets/sheet", mnScTab+1 );
666 sax_fastparser::FSHelperPtr pWorksheet = rStrm.GetStreamForPath( sSheetName );
668 rStrm.PushStream( pWorksheet );
670 pWorksheet->startElement( XML_worksheet,
671 XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
672 FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
673 FSEND );
676 SetCurrScTab( mnScTab );
677 if( mxCellTable.get() )
678 mxCellTable->Finalize();
679 aRecList.SaveXml( rStrm );
681 if (GetTabInfo().IsExportTab( mnScTab ) )
683 rStrm.GetCurrentStream()->endElement( XML_worksheet );
684 rStrm.PopStream();
689 ExcDocument::ExcDocument( const XclExpRoot& rRoot ) :
690 XclExpRoot( rRoot ),
691 aHeader( rRoot ),
692 pExpChangeTrack( NULL )
697 ExcDocument::~ExcDocument()
699 maTableList.RemoveAllRecords(); //! for the following assertion
700 delete pExpChangeTrack;
704 void ExcDocument::ReadDoc( void )
706 InitializeConvert();
708 aHeader.FillAsHeader( maBoundsheetList );
710 SCTAB nScTab = 0, nScTabCount = GetTabInfo().GetScTabCount();
711 size_t nCodeNameIdx = 0, nCodeNameCount = GetExtDocOptions().GetCodeNameCount();
713 for( ; nScTab < nScTabCount; ++nScTab )
715 if( GetTabInfo().IsExportTab( nScTab ) )
717 ExcTableList::RecordRefType xTab( new ExcTable( GetRoot(), nScTab ) );
718 maTableList.AppendRecord( xTab );
719 xTab->FillAsTable( nCodeNameIdx );
720 ++nCodeNameIdx;
723 for( ; nCodeNameIdx < nCodeNameCount; ++nScTab, ++nCodeNameIdx )
725 ExcTableList::RecordRefType xTab( new ExcTable( GetRoot(), nScTab ) );
726 maTableList.AppendRecord( xTab );
727 xTab->FillAsEmptyTable( nCodeNameIdx );
730 if ( GetBiff() == EXC_BIFF8 )
732 // complete temporary Escher stream
733 GetOldRoot().pEscher->GetEx()->EndDocument();
735 // change tracking
736 if ( GetDoc().GetChangeTrack() )
737 pExpChangeTrack = new XclExpChangeTrack( GetRoot() );
742 void ExcDocument::Write( SvStream& rSvStrm )
744 if( !maTableList.IsEmpty() )
746 InitializeSave();
748 if ( GetBiff() == EXC_BIFF8 )
749 GetOldRoot().pEscher->GetStrm().Seek(0); // ready for take off
751 XclExpStream aXclStrm( rSvStrm, GetRoot() );
753 aHeader.Write( aXclStrm );
755 DBG_ASSERT( maTableList.GetSize() == maBoundsheetList.GetSize(),
756 "ExcDocument::Write - different number of sheets and BOUNDSHEET records" );
758 for( size_t nTab = 0, nTabCount = maTableList.GetSize(); nTab < nTabCount; ++nTab )
760 // set current stream position in BOUNDSHEET record
761 ExcBoundsheetRef xBoundsheet = maBoundsheetList.GetRecord( nTab );
762 if( xBoundsheet.get() )
763 xBoundsheet->SetStreamPos( aXclStrm.GetSvStreamPos() );
764 // write the table
765 maTableList.GetRecord( nTab )->Write( aXclStrm );
768 // write the table stream positions into the BOUNDSHEET records
769 for( size_t nBSheet = 0, nBSheetCount = maBoundsheetList.GetSize(); nBSheet < nBSheetCount; ++nBSheet )
770 maBoundsheetList.GetRecord( nBSheet )->UpdateStreamPos( aXclStrm );
772 if( pExpChangeTrack )
773 pExpChangeTrack->Write();
776 void ExcDocument::WriteXml( XclExpXmlStream& rStrm )
778 SfxObjectShell* pDocShell = GetDocShell();
780 using namespace ::com::sun::star;
781 uno::Reference<document::XDocumentPropertiesSupplier> xDPS( pDocShell->GetModel(), uno::UNO_QUERY_THROW );
782 uno::Reference<document::XDocumentProperties> xDocProps = xDPS->getDocumentProperties();
784 rStrm.exportDocumentProperties( xDocProps );
786 sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
787 rWorkbook->startElement( XML_workbook,
788 XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
789 FSNS(XML_xmlns, XML_r), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
790 FSEND );
791 rWorkbook->singleElement( XML_fileVersion,
792 XML_appName, "Calc",
793 // OOXTODO: XML_codeName
794 // OOXTODO: XML_lastEdited
795 // OOXTODO: XML_lowestEdited
796 // OOXTODO: XML_rupBuild
797 FSEND );
799 if( !maTableList.IsEmpty() )
801 InitializeSave();
803 GetOldRoot().pEscher->GetStrm().Seek(0); // ready for take off
805 aHeader.WriteXml( rStrm );
807 for( size_t nTab = 0, nTabCount = maTableList.GetSize(); nTab < nTabCount; ++nTab )
809 // set current stream position in BOUNDSHEET record
810 #if 0
811 ExcBoundsheetRef xBoundsheet = maBoundsheetList.GetRecord( nTab );
812 if( xBoundsheet.get() )
813 xBoundsheet->SetStreamPos( aXclStrm.GetSvStreamPos() );
814 #endif
815 // write the table
816 maTableList.GetRecord( nTab )->WriteXml( rStrm );
820 if( pExpChangeTrack )
821 pExpChangeTrack->WriteXml( rStrm );
823 rWorkbook->endElement( XML_workbook );
824 rWorkbook.reset();
826 rStrm.commit();