xref: /aoo4110/main/sc/source/filter/excel/excdoc.cxx (revision b1cdbd2c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 
28 //------------------------------------------------------------------------
29 
30 #include "scitems.hxx"
31 
32 #include <comphelper/processfactory.hxx>
33 #include <svx/svdobj.hxx>
34 #include <svx/svditer.hxx>
35 #include <svx/svdpage.hxx>
36 #include <editeng/lrspitem.hxx>
37 #include <editeng/ulspitem.hxx>
38 #include <svl/intitem.hxx>
39 #include <svl/zformat.hxx>
40 #include <sot/storage.hxx>
41 #include <sfx2/objsh.hxx>
42 #include <tools/urlobj.hxx>
43 #include <rtl/ustring.hxx>
44 
45 #include "cell.hxx"
46 #include "dociter.hxx"
47 #include "document.hxx"
48 #include "rangenam.hxx"
49 #include "dbcolect.hxx"
50 #include "global.hxx"
51 #include "globstr.hrc"
52 #include "progress.hxx"
53 #include "conditio.hxx"
54 #include "dpobject.hxx"
55 #include "attrib.hxx"
56 #include "scextopt.hxx"
57 #include "stlsheet.hxx"
58 #include "stlpool.hxx"
59 #include "olinetab.hxx"
60 #include "unonames.hxx"
61 #include "convuno.hxx"
62 #include "patattr.hxx"
63 #include "docoptio.hxx"
64 #include "tabprotection.hxx"
65 
66 #include "excdoc.hxx"
67 #include "namebuff.hxx"
68 
69 #include "xcl97rec.hxx"
70 #include "xcl97esc.hxx"
71 #include "xetable.hxx"
72 #include "xelink.hxx"
73 #include "xename.hxx"
74 #include "xepage.hxx"
75 #include "xeview.hxx"
76 #include "xecontent.hxx"
77 #include "xeescher.hxx"
78 #include "xepivot.hxx"
79 #include "XclExpChangeTrack.hxx"
80 
81 #include <math.h>
82 
83 using namespace ::oox;
84 using ::rtl::OString;
85 
lcl_GetVbaTabName(SCTAB n)86 static String lcl_GetVbaTabName( SCTAB n )
87 {
88 	String	aRet( RTL_CONSTASCII_USTRINGPARAM( "__VBA__" ) );
89 	aRet += String::CreateFromInt32( static_cast<sal_uInt16>(n) );
90 	return aRet;
91 }
92 
93 
lcl_AddBookviews(XclExpRecordList<> & aRecList,ExcTable & self)94 static void lcl_AddBookviews( XclExpRecordList<>& aRecList, ExcTable& self )
95 {
96     aRecList.AppendNewRecord( new XclExpXmlStartElementRecord( XML_bookViews ) );
97     aRecList.AppendNewRecord( new XclExpWindow1( self.GetRoot() ) );
98     aRecList.AppendNewRecord( new XclExpXmlEndElementRecord( XML_bookViews ) );
99 }
100 
lcl_AddCalcPr(XclExpRecordList<> & aRecList,ExcTable & self)101 static void lcl_AddCalcPr( XclExpRecordList<>& aRecList, ExcTable& self )
102 {
103     ScDocument& rDoc = self.GetDoc();
104 
105     aRecList.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_calcPr ) );
106     // OOXTODO: calcCompleted, calcId, calcMode, calcOnSave,
107     //          concurrentCalc, concurrentManualCount,
108     //          forceFullCalc, fullCalcOnLoad, fullPrecision
109     aRecList.AppendNewRecord( new XclCalccount( rDoc ) );
110     aRecList.AppendNewRecord( new XclRefmode( rDoc ) );
111     aRecList.AppendNewRecord( new XclIteration( rDoc ) );
112     aRecList.AppendNewRecord( new XclDelta( rDoc ) );
113     aRecList.AppendNewRecord( new XclExpBoolRecord(0x005F, true) ); // SAVERECALC
114     aRecList.AppendNewRecord( new XclExpXmlEndSingleElementRecord() );  // XML_calcPr
115 }
116 
117 #if 0
118 // removed during rebase, because scsheetprotection02 is not yet up-stream :-(
119 static void lcl_AddWorkbookProtection( XclExpRecordList<>& aRecList, ExcTable& self )
120 {
121     aRecList.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_workbookProtection ) );
122     const ScDocProtection* pProtect = self.GetDoc().GetDocProtection();
123     if (pProtect && pProtect->isProtected())
124     {
125         aRecList.AppendNewRecord( new XclExpWindowProtection(pProtect->isOptionEnabled(ScDocProtection::WINDOWS)) );
126         aRecList.AppendNewRecord( new XclExpProtection(pProtect->isOptionEnabled(ScDocProtection::STRUCTURE)) );
127         aRecList.AppendNewRecord( new XclExpPassHash(pProtect->getPasswordHash(PASSHASH_XL)) );
128     }
129 
130     if( self.GetBiff() == EXC_BIFF8 )
131     {
132         aRecList.AppendNewRecord( new XclExpProt4Rev );
133         aRecList.AppendNewRecord( new XclExpProt4RevPass );
134     }
135     aRecList.AppendNewRecord( new XclExpXmlEndSingleElementRecord() );   // XML_workbookProtection
136 }
137 #endif
138 
lcl_AddScenariosAndFilters(XclExpRecordList<> & aRecList,const XclExpRoot & rRoot,SCTAB nScTab)139 static void lcl_AddScenariosAndFilters( XclExpRecordList<>& aRecList, const XclExpRoot& rRoot, SCTAB nScTab )
140 {
141     // Scenarios
142     aRecList.AppendNewRecord( new ExcEScenarioManager( rRoot, nScTab ) );
143     // filter
144     aRecList.AppendRecord( rRoot.GetFilterManager().CreateRecord( nScTab ) );
145 }
146 
147 
ExcTable(const XclExpRoot & rRoot)148 ExcTable::ExcTable( const XclExpRoot& rRoot ) :
149     XclExpRoot( rRoot ),
150     mnScTab( SCTAB_GLOBAL ),
151     nExcTab( EXC_NOTAB ),
152     pTabNames( new NameBuffer( 0, 16 ) )
153 {
154 }
155 
156 
ExcTable(const XclExpRoot & rRoot,SCTAB nScTab)157 ExcTable::ExcTable( const XclExpRoot& rRoot, SCTAB nScTab ) :
158     XclExpRoot( rRoot ),
159     mnScTab( nScTab ),
160     nExcTab( rRoot.GetTabInfo().GetXclTab( nScTab ) ),
161     pTabNames( new NameBuffer( 0, 16 ) )
162 {
163 }
164 
165 
~ExcTable()166 ExcTable::~ExcTable()
167 {
168     delete pTabNames;
169 }
170 
171 
Add(XclExpRecordBase * pRec)172 void ExcTable::Add( XclExpRecordBase* pRec )
173 {
174     DBG_ASSERT( pRec, "-ExcTable::Add(): pRec ist NULL!" );
175     aRecList.AppendNewRecord( pRec );
176 }
177 
178 
FillAsHeader(ExcBoundsheetList & rBoundsheetList)179 void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList )
180 {
181     InitializeGlobals();
182 
183     RootData& rR = GetOldRoot();
184     ScDocument& rDoc = GetDoc();
185     XclExpTabInfo& rTabInfo = GetTabInfo();
186 
187     if ( GetBiff() <= EXC_BIFF5 )
188 		Add( new ExcBofW );
189 	else
190 		Add( new ExcBofW8 );
191 
192 	SCTAB	nC;
193 	String	aTmpString;
194     SCTAB  nScTabCount     = rTabInfo.GetScTabCount();
195     sal_uInt16  nExcTabCount    = rTabInfo.GetXclTabCount();
196     sal_uInt16  nCodenames      = static_cast< sal_uInt16 >( GetExtDocOptions().GetCodeNameCount() );
197 
198     SfxObjectShell* pShell = GetDocShell();
199     sal_uInt16 nWriteProtHash = pShell ? pShell->GetModifyPasswordHash() : 0;
200     bool bRecommendReadOnly = pShell && pShell->IsLoadReadonly();
201 
202     if( (nWriteProtHash > 0) || bRecommendReadOnly )
203         Add( new XclExpEmptyRecord( EXC_ID_WRITEPROT ) );
204 
205     // TODO: correct codepage for BIFF5?
206     sal_uInt16 nCodePage = XclTools::GetXclCodePage( (GetBiff() <= EXC_BIFF5) ? RTL_TEXTENCODING_MS_1252 : RTL_TEXTENCODING_UNICODE );
207 
208     if( GetBiff() <= EXC_BIFF5 )
209     {
210         Add( new XclExpEmptyRecord( EXC_ID_INTERFACEHDR ) );
211         Add( new XclExpUInt16Record( EXC_ID_MMS, 0 ) );
212         Add( new XclExpEmptyRecord( EXC_ID_TOOLBARHDR ) );
213         Add( new XclExpEmptyRecord( EXC_ID_TOOLBAREND ) );
214         Add( new XclExpEmptyRecord( EXC_ID_INTERFACEEND ) );
215         Add( new ExcDummy_00 );
216     }
217 	else
218 	{
219         if( IsDocumentEncrypted() )
220             Add( new XclExpFileEncryption( GetRoot() ) );
221         Add( new XclExpInterfaceHdr( nCodePage ) );
222         Add( new XclExpUInt16Record( EXC_ID_MMS, 0 ) );
223         Add( new XclExpInterfaceEnd );
224         Add( new XclExpWriteAccess );
225     }
226 
227     Add( new XclExpFileSharing( GetRoot(), nWriteProtHash, bRecommendReadOnly ) );
228     Add( new XclExpUInt16Record( EXC_ID_CODEPAGE, nCodePage ) );
229 
230     if( GetBiff() == EXC_BIFF8 )
231     {
232         Add( new XclExpBoolRecord( EXC_ID_DSF, false ) );
233         Add( new XclExpEmptyRecord( EXC_ID_XL9FILE ) );
234 		rR.pTabId = new XclExpChTrTabId( Max( nExcTabCount, nCodenames ) );
235 		Add( rR.pTabId );
236         if( HasVbaStorage() )
237 		{
238 			Add( new XclObproj );
239             const String& rCodeName = GetExtDocOptions().GetDocSettings().maGlobCodeName;
240             if( rCodeName.Len() )
241                 Add( new XclCodename( rCodeName ) );
242 		}
243 	}
244 
245     Add( new XclExpUInt16Record( EXC_ID_FNGROUPCOUNT, 14 ) );
246 
247 	// erst Namen- und Tabellen-Eintraege aufbauen
248 	String			aName;
249 
250 	for( nC = 0 ; nC < nScTabCount ; nC++ )
251         if( rTabInfo.IsExportTab( nC ) )
252 		{
253 			rDoc.GetName( nC, aTmpString );
254             *pTabNames << aTmpString;
255 		}
256 
257     if ( GetBiff() <= EXC_BIFF5 )
258 	{
259         // global link table: EXTERNCOUNT, EXTERNSHEET, NAME
260         aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
261         aRecList.AppendRecord( CreateRecord( EXC_ID_NAME ) );
262     }
263 
264     // document protection options
265     const ScDocProtection* pProtect = GetDoc().GetDocProtection();
266     if (pProtect && pProtect->isProtected())
267     {
268         Add( new XclExpWindowProtection(pProtect->isOptionEnabled(ScDocProtection::WINDOWS)) );
269         Add( new XclExpProtection(pProtect->isOptionEnabled(ScDocProtection::STRUCTURE)) );
270 #if ENABLE_SHEET_PROTECTION
271         Add( new XclExpPassHash(pProtect->getPasswordHash(PASSHASH_XL)) );
272 #endif
273     }
274 
275     if( GetBiff() == EXC_BIFF8 )
276     {
277         Add( new XclExpProt4Rev );
278         Add( new XclExpProt4RevPass );
279     }
280 
281     // document protection options
282     if( GetOutput() == EXC_OUTPUT_BINARY )
283     {
284         //lcl_AddWorkbookProtection( aRecList, *this );
285         lcl_AddBookviews( aRecList, *this );
286     }
287 
288     Add( new XclExpXmlStartSingleElementRecord( XML_workbookPr ) );
289 
290     if ( GetBiff() == EXC_BIFF8 )
291     {
292         Add( new XclExpBoolRecord(0x0040, false) ); // BACKUP
293         Add( new XclExpBoolRecord(0x008D, false) ); // HIDEOBJ
294     }
295 
296     if( GetBiff() <= EXC_BIFF5 )
297     {
298 		Add( new ExcDummy_040 );
299 		Add( new Exc1904( rDoc ) );
300 		Add( new ExcDummy_041 );
301     }
302     else
303     {
304         // BIFF8
305         Add( new Exc1904( rDoc ) );
306         Add( new XclExpBoolRecord( 0x000E, !rDoc.GetDocOptions().IsCalcAsShown() ) );
307         Add( new XclExpBoolRecord(0x01B7, false) ); // REFRESHALL
308         Add( new XclExpBoolRecord(0x00DA, false) ); // BOOKBOOL
309         // OOXTODO: The following /workbook/workbookPr attributes are mapped
310         //          to various BIFF records that are not currently supported:
311         //
312         //          XML_allowRefreshQuery:          QSISTAG 802h: fEnableRefresh
313         //          XML_autoCompressPictures:       COMPRESSPICTURES 89Bh: fAutoCompressPictures
314         //          XML_checkCompatibility:         COMPAT12 88Ch: fNoCompatChk
315         //          XML_codeName:                   "Calc"
316         //          XML_defaultThemeVersion:        ???
317         //          XML_filterPrivacy:              BOOKEXT 863h: fFilterPrivacy
318         //          XML_hidePivotFieldList:         BOOKBOOL DAh: fHidePivotTableFList
319         //          XML_promptedSolutions:          BOOKEXT 863h: fBuggedUserAboutSolution
320         //          XML_publishItems:               NAMEPUBLISH 893h: fPublished
321         //          XML_saveExternalLinkValues:     BOOKBOOL DAh: fNoSavSupp
322         //          XML_showBorderUnselectedTables: BOOKBOOL DAh: fHideBorderUnsels
323         //          XML_showInkAnnotation:          BOOKEXT 863h: fShowInkAnnotation
324         //          XML_showPivotChart:             PIVOTCHARTBITS 859h: fGXHide??
325         //          XML_updateLinks:                BOOKBOOL DAh: grbitUpdateLinks
326     }
327     Add( new XclExpXmlEndSingleElementRecord() );   // XML_workbookPr
328 
329     // Formatting: FONT, FORMAT, XF, STYLE, PALETTE
330     if( GetOutput() != EXC_OUTPUT_BINARY )
331     {
332         aRecList.AppendNewRecord( new XclExpXmlStyleSheet( *this ) );
333     }
334     else
335     {
336         aRecList.AppendRecord( CreateRecord( EXC_ID_FONTLIST ) );
337         aRecList.AppendRecord( CreateRecord( EXC_ID_FORMATLIST ) );
338         aRecList.AppendRecord( CreateRecord( EXC_ID_XFLIST ) );
339         aRecList.AppendRecord( CreateRecord( EXC_ID_PALETTE ) );
340     }
341 
342 
343     if( GetBiff() <= EXC_BIFF5 )
344     {
345 		// Bundlesheet
346 		for( nC = 0 ; nC < nScTabCount ; nC++ )
347             if( rTabInfo.IsExportTab( nC ) )
348 			{
349                 ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet( rR, nC ) );
350                 aRecList.AppendRecord( xBoundsheet );
351                 rBoundsheetList.AppendRecord( xBoundsheet );
352 			}
353 	}
354 	else
355 	{
356 		// Pivot Cache
357         GetPivotTableManager().CreatePivotTables();
358         aRecList.AppendRecord( GetPivotTableManager().CreatePivotCachesRecord() );
359 
360 		// Change tracking
361 		if( rDoc.GetChangeTrack() )
362 		{
363 			rR.pUserBViewList = new XclExpUserBViewList( *rDoc.GetChangeTrack() );
364 			Add( rR.pUserBViewList );
365 		}
366 
367 		// Natural Language Formulas Flag
368         aRecList.AppendNewRecord( new XclExpBoolRecord( EXC_ID_USESELFS, GetDoc().GetDocOptions().IsLookUpColRowNames() ) );
369 
370         if( GetOutput() != EXC_OUTPUT_BINARY )
371         {
372             //lcl_AddWorkbookProtection( aRecList, *this );
373             lcl_AddBookviews( aRecList, *this );
374         }
375 
376 		// Bundlesheet
377 		aRecList.AppendNewRecord( new XclExpXmlStartElementRecord( XML_sheets ) );
378 		for( nC = 0 ; nC < nScTabCount ; nC++ )
379             if( rTabInfo.IsExportTab( nC ) )
380 			{
381                 ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet8( rR, nC ) );
382                 aRecList.AppendRecord( xBoundsheet );
383                 rBoundsheetList.AppendRecord( xBoundsheet );
384 			}
385 		aRecList.AppendNewRecord( new XclExpXmlEndElementRecord( XML_sheets ) );
386 
387 		for( SCTAB nAdd = 0; nC < static_cast<SCTAB>(nCodenames) ; nC++, nAdd++ )
388 		{
389 			aTmpString = lcl_GetVbaTabName( nAdd );
390             ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet8( aTmpString ) );
391             aRecList.AppendRecord( xBoundsheet );
392             rBoundsheetList.AppendRecord( xBoundsheet );
393 		}
394 
395         // COUNTRY - in BIFF8 in workbook globals
396         Add( new XclExpCountry( GetRoot() ) );
397         // link table: SUPBOOK, XCT, CRN, EXTERNNAME, EXTERNSHEET, NAME
398         aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
399         aRecList.AppendRecord( CreateRecord( EXC_ID_NAME ) );
400 
401         if( GetOutput() != EXC_OUTPUT_BINARY )
402             lcl_AddCalcPr( aRecList, *this );
403 
404         Add( new XclExpRecalcId );
405 
406 		// MSODRAWINGGROUP per-document data
407         aRecList.AppendRecord( GetObjectManager().CreateDrawingGroup() );
408         // Shared string table: SST, EXTSST
409         aRecList.AppendRecord( CreateRecord( EXC_ID_SST ) );
410 
411         Add( new XclExpBookExt );
412 	}
413 
414 	Add( new ExcEof );
415 }
416 
417 
FillAsTable(SCTAB nCodeNameIdx)418 void ExcTable::FillAsTable( SCTAB nCodeNameIdx )
419 {
420     InitializeTable( mnScTab );
421 
422     RootData& rR = GetOldRoot();
423     XclBiff eBiff = GetBiff();
424     ScDocument& rDoc = GetDoc();
425 
426     DBG_ASSERT( (mnScTab >= 0L) && (mnScTab <= MAXTAB), "-ExcTable::Table(): mnScTab - no ordinary table!" );
427     DBG_ASSERT( nExcTab <= static_cast<sal_uInt16>(MAXTAB), "-ExcTable::Table(): nExcTab - no ordinary table!" );
428 
429     // create a new OBJ list for this sheet (may be used by notes, autofilter, data validation)
430     if( eBiff == EXC_BIFF8 )
431         GetObjectManager().StartSheet();
432 
433     // cell table: DEFROWHEIGHT, DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
434     mxCellTable.reset( new XclExpCellTable( GetRoot() ) );
435 
436     if( GetOutput() != EXC_OUTPUT_BINARY )
437     {
438         FillAsXmlTable( nCodeNameIdx );
439         return;
440     }
441 
442 
443     // WSBOOL needs data from page settings, create it here, add it later
444     ScfRef< XclExpPageSettings > xPageSett( new XclExpPageSettings( GetRoot() ) );
445     bool bFitToPages = xPageSett->GetPageData().mbFitToPages;
446 
447     if( eBiff <= EXC_BIFF5 )
448 	{
449 		Add( new ExcBof );
450         Add( new ExcDummy_02a );
451     }
452     else
453     {
454         Add( new ExcBof8 );
455         lcl_AddCalcPr( aRecList, *this );
456     }
457 
458     // GUTS (count & size of outline icons)
459     aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_GUTS ) );
460     // DEFROWHEIGHT, created by the cell table
461     aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID2_DEFROWHEIGHT ) );
462 
463     // COUNTRY - in BIFF5/7 in every worksheet
464     if( eBiff <= EXC_BIFF5 )
465         Add( new XclExpCountry( GetRoot() ) );
466 
467     Add( new XclExpWsbool( bFitToPages ) );
468 
469     // page settings (SETUP and various other records)
470     aRecList.AppendRecord( xPageSett );
471 
472     const ScTableProtection* pTabProtect = rDoc.GetTabProtection(mnScTab);
473     if (pTabProtect && pTabProtect->isProtected())
474     {
475         Add( new XclExpProtection(true) );
476         Add( new XclExpBoolRecord(0x00DD, pTabProtect->isOptionEnabled(ScTableProtection::SCENARIOS)) );
477         Add( new XclExpBoolRecord(0x0063, pTabProtect->isOptionEnabled(ScTableProtection::OBJECTS)) );
478 #if ENABLE_SHEET_PROTECTION
479         Add( new XclExpPassHash(pTabProtect->getPasswordHash(PASSHASH_XL)) );
480 #endif
481     }
482 
483     // local link table: EXTERNCOUNT, EXTERNSHEET
484     if( eBiff <= EXC_BIFF5 )
485         aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
486 
487     if ( eBiff == EXC_BIFF8 )
488         lcl_AddScenariosAndFilters( aRecList, GetRoot(), mnScTab );
489 
490     // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
491     aRecList.AppendRecord( mxCellTable );
492 
493     // MERGEDCELLS record, generated by the cell table
494     aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_MERGEDCELLS ) );
495     // label ranges
496     if( eBiff == EXC_BIFF8 )
497         Add( new XclExpLabelranges( GetRoot() ) );
498     // data validation (DVAL and list of DV records), generated by the cell table
499     aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_DVAL ) );
500 
501     if( eBiff == EXC_BIFF8 )
502 	{
503         // all MSODRAWING and OBJ stuff of this sheet goes here
504         aRecList.AppendRecord( GetObjectManager().ProcessDrawing( GetSdrPage( mnScTab ) ) );
505 		// pivot tables
506         aRecList.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab ) );
507 	}
508 
509     // list of NOTE records, generated by the cell table
510     aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_NOTE ) );
511 
512     // sheet view settings: WINDOW2, SCL, PANE, SELECTION
513     aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
514 
515     if( eBiff == EXC_BIFF8 )
516 	{
517         // sheet protection options
518         Add( new XclExpSheetProtectOptions( GetRoot(), mnScTab ) );
519 
520 		// web queries
521         Add( new XclExpWebQueryBuffer( GetRoot() ) );
522 
523 		// conditional formats
524         Add( new XclExpCondFormatBuffer( GetRoot() ) );
525 
526         if( HasVbaStorage() )
527             if( nCodeNameIdx < GetExtDocOptions().GetCodeNameCount() )
528                 Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx ) ) );
529 	}
530 
531     // list of HLINK records, generated by the cell table
532     aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_HLINK ) );
533 
534 	// change tracking
535 	if( rR.pUserBViewList )
536 	{
537 		for( const XclExpUserBView* pBView = rR.pUserBViewList->First(); pBView; pBView = rR.pUserBViewList->Next() )
538 		{
539 			Add( new XclExpUsersViewBegin( pBView->GetGUID(), nExcTab ) );
540 			Add( new XclExpUsersViewEnd );
541 		}
542 	}
543 
544 	// EOF
545 	Add( new ExcEof );
546 }
547 
FillAsXmlTable(SCTAB nCodeNameIdx)548 void ExcTable::FillAsXmlTable( SCTAB nCodeNameIdx )
549 {
550     RootData& rR = GetOldRoot();
551 
552     // WSBOOL needs data from page settings, create it here, add it later
553     ScfRef< XclExpPageSettings > xPageSett( new XclExpPageSettings( GetRoot() ) );
554     bool bFitToPages = xPageSett->GetPageData().mbFitToPages;
555 
556     Add( new ExcBof8 );
557 
558     Add( new XclExpWsbool( bFitToPages, mnScTab, &GetFilterManager() ) );
559 
560     // GUTS (count & size of outline icons)
561     aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_GUTS ) );
562     // DEFROWHEIGHT, created by the cell table
563     aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID2_DEFROWHEIGHT ) );
564 
565     aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID3_DIMENSIONS ) );
566 
567     // sheet view settings: WINDOW2, SCL, PANE, SELECTION
568     aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
569 
570     // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
571     aRecList.AppendRecord( mxCellTable );
572 
573     // label ranges
574     Add( new XclExpLabelranges( GetRoot() ) );
575 
576     // DFF not needed in MSOOXML export
577 //    GetObjectManager().AddSdrPage();
578 //    //! close Escher group shape and ESCHER_DgContainer
579 //    //! opened by XclExpObjList ctor MSODRAWING
580 //    rR.pObjRecs->EndSheet();
581 //    // all MSODRAWING and OBJ stuff of this sheet goes here
582 //    Add( rR.pObjRecs );
583 
584     // pivot tables
585     aRecList.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab ) );
586 
587     // list of NOTE records, generated by the cell table
588     XclExpRecordRef xNotes = mxCellTable->CreateRecord( EXC_ID_NOTE );
589     XclExpRecordList< XclExpNote >* xNoteList = dynamic_cast< XclExpRecordList< XclExpNote >* >( xNotes.get() );
590     if( xNoteList != NULL )
591         aRecList.AppendNewRecord( new XclExpComments( mnScTab, *xNoteList ) );
592 
593     // web queries
594     Add( new XclExpWebQueryBuffer( GetRoot() ) );
595 
596     lcl_AddScenariosAndFilters( aRecList, GetRoot(), mnScTab );
597 
598     // MERGEDCELLS record, generated by the cell table
599     aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_MERGEDCELLS ) );
600 
601     // conditional formats
602     Add( new XclExpCondFormatBuffer( GetRoot() ) );
603 
604     if( HasVbaStorage() )
605         if( nCodeNameIdx < GetExtDocOptions().GetCodeNameCount() )
606             Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx ) ) );
607 
608     // data validation (DVAL and list of DV records), generated by the cell table
609     aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_DVAL ) );
610 
611     // list of HLINK records, generated by the cell table
612     XclExpRecordRef xHyperlinks = mxCellTable->CreateRecord( EXC_ID_HLINK );
613     XclExpHyperlinkList* xHyperlinkList = dynamic_cast<XclExpHyperlinkList*>(xHyperlinks.get());
614     if( xHyperlinkList != NULL && !xHyperlinkList->IsEmpty() )
615     {
616         aRecList.AppendNewRecord( new XclExpXmlStartElementRecord( XML_hyperlinks ) );
617         aRecList.AppendRecord( xHyperlinks );
618         aRecList.AppendNewRecord( new XclExpXmlEndElementRecord( XML_hyperlinks ) );
619     }
620 
621     aRecList.AppendRecord( xPageSett );
622 
623     // change tracking
624     if( rR.pUserBViewList )
625     {
626         for( const XclExpUserBView* pBView = rR.pUserBViewList->First(); pBView; pBView = rR.pUserBViewList->Next() )
627         {
628             Add( new XclExpUsersViewBegin( pBView->GetGUID(), nExcTab ) );
629             Add( new XclExpUsersViewEnd );
630         }
631     }
632 
633     // EOF
634     Add( new ExcEof );
635 }
636 
637 
FillAsEmptyTable(SCTAB nCodeNameIdx)638 void ExcTable::FillAsEmptyTable( SCTAB nCodeNameIdx )
639 {
640     InitializeTable( mnScTab );
641 
642     if( HasVbaStorage() && (nCodeNameIdx < GetExtDocOptions().GetCodeNameCount()) )
643     {
644         if( GetBiff() <= EXC_BIFF5 )
645         {
646             Add( new ExcBof );
647         }
648         else
649         {
650             Add( new ExcBof8 );
651             Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx ) ) );
652         }
653         // sheet view settings: WINDOW2, SCL, PANE, SELECTION
654         aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
655         Add( new ExcEof );
656     }
657 }
658 
659 
Write(XclExpStream & rStrm)660 void ExcTable::Write( XclExpStream& rStrm )
661 {
662     SetCurrScTab( mnScTab );
663     if( mxCellTable.get() )
664         mxCellTable->Finalize();
665     aRecList.Save( rStrm );
666 }
667 
668 
WriteXml(XclExpXmlStream & rStrm)669 void ExcTable::WriteXml( XclExpXmlStream& rStrm )
670 {
671     if (GetTabInfo().IsExportTab( mnScTab ) )
672     {
673         // worksheet export
674         String sSheetName = XclXmlUtils::GetStreamName( "xl/", "worksheets/sheet", mnScTab+1 );
675 
676         sax_fastparser::FSHelperPtr pWorksheet = rStrm.GetStreamForPath( sSheetName );
677 
678         rStrm.PushStream( pWorksheet );
679 
680         pWorksheet->startElement( XML_worksheet,
681                 XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
682                 FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
683                 FSEND );
684     }
685 
686     SetCurrScTab( mnScTab );
687     if( mxCellTable.get() )
688         mxCellTable->Finalize();
689     aRecList.SaveXml( rStrm );
690 
691     if (GetTabInfo().IsExportTab( mnScTab ) )
692     {
693         rStrm.GetCurrentStream()->endElement( XML_worksheet );
694         rStrm.PopStream();
695     }
696 }
697 
698 
ExcDocument(const XclExpRoot & rRoot)699 ExcDocument::ExcDocument( const XclExpRoot& rRoot ) :
700     XclExpRoot( rRoot ),
701     aHeader( rRoot ),
702 	pExpChangeTrack( NULL )
703 {
704 }
705 
706 
~ExcDocument()707 ExcDocument::~ExcDocument()
708 {
709     maTableList.RemoveAllRecords();    //! for the following assertion
710     delete pExpChangeTrack;
711 }
712 
713 
ReadDoc(void)714 void ExcDocument::ReadDoc( void )
715 {
716     InitializeConvert();
717 
718     aHeader.FillAsHeader( maBoundsheetList );
719 
720     SCTAB nScTab = 0, nScTabCount = GetTabInfo().GetScTabCount();
721     SCTAB nCodeNameIdx = 0, nCodeNameCount = GetExtDocOptions().GetCodeNameCount();
722 
723     for( ; nScTab < nScTabCount; ++nScTab )
724     {
725         if( GetTabInfo().IsExportTab( nScTab ) )
726         {
727             ExcTableList::RecordRefType xTab( new ExcTable( GetRoot(), nScTab ) );
728             maTableList.AppendRecord( xTab );
729             xTab->FillAsTable( nCodeNameIdx );
730             ++nCodeNameIdx;
731         }
732     }
733     for( ; nCodeNameIdx < nCodeNameCount; ++nScTab, ++nCodeNameIdx )
734     {
735         ExcTableList::RecordRefType xTab( new ExcTable( GetRoot(), nScTab ) );
736         maTableList.AppendRecord( xTab );
737         xTab->FillAsEmptyTable( nCodeNameIdx );
738     }
739 
740     if ( GetBiff() == EXC_BIFF8 )
741 	{
742 		// complete temporary Escher stream
743         GetObjectManager().EndDocument();
744 
745 		// change tracking
746         if ( GetDoc().GetChangeTrack() )
747             pExpChangeTrack = new XclExpChangeTrack( GetRoot() );
748 	}
749 }
750 
751 
Write(SvStream & rSvStrm)752 void ExcDocument::Write( SvStream& rSvStrm )
753 {
754     if( !maTableList.IsEmpty() )
755 	{
756         InitializeSave();
757 
758         XclExpStream aXclStrm( rSvStrm, GetRoot() );
759 
760 		aHeader.Write( aXclStrm );
761 
762         DBG_ASSERT( maTableList.GetSize() == maBoundsheetList.GetSize(),
763             "ExcDocument::Write - different number of sheets and BOUNDSHEET records" );
764 
765         for( size_t nTab = 0, nTabCount = maTableList.GetSize(); nTab < nTabCount; ++nTab )
766 		{
767             // set current stream position in BOUNDSHEET record
768             ExcBoundsheetRef xBoundsheet = maBoundsheetList.GetRecord( nTab );
769             if( xBoundsheet.get() )
770                 xBoundsheet->SetStreamPos( aXclStrm.GetSvStreamPos() );
771             // write the table
772             maTableList.GetRecord( nTab )->Write( aXclStrm );
773 		}
774 
775         // write the table stream positions into the BOUNDSHEET records
776         for( size_t nBSheet = 0, nBSheetCount = maBoundsheetList.GetSize(); nBSheet < nBSheetCount; ++nBSheet )
777             maBoundsheetList.GetRecord( nBSheet )->UpdateStreamPos( aXclStrm );
778 	}
779 	if( pExpChangeTrack )
780 		pExpChangeTrack->Write();
781 }
782 
WriteXml(SvStream & rStrm)783 void ExcDocument::WriteXml( SvStream& rStrm )
784 {
785     if( !maTableList.IsEmpty() )
786     {
787         InitializeSave();
788 
789         XclExpXmlStream aStrm( ::comphelper::getProcessComponentContext(), rStrm, GetRoot() );
790 
791         sax_fastparser::FSHelperPtr& rWorkbook = aStrm.GetCurrentStream();
792         rWorkbook->startElement( XML_workbook,
793                 XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
794                 FSNS(XML_xmlns, XML_r), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
795                 FSEND );
796         rWorkbook->singleElement( XML_fileVersion,
797                 XML_appName, "Calc",
798                 // OOXTODO: XML_codeName
799                 // OOXTODO: XML_lastEdited
800                 // OOXTODO: XML_lowestEdited
801                 // OOXTODO: XML_rupBuild
802                 FSEND );
803 
804         aHeader.WriteXml( aStrm );
805 
806         for( size_t nTab = 0, nTabCount = maTableList.GetSize(); nTab < nTabCount; ++nTab )
807         {
808             // set current stream position in BOUNDSHEET record
809 #if 0
810             ExcBoundsheetRef xBoundsheet = maBoundsheetList.GetRecord( nTab );
811             if( xBoundsheet.get() )
812                 xBoundsheet->SetStreamPos( aXclStrm.GetSvStreamPos() );
813 #endif
814             // write the table
815             maTableList.GetRecord( nTab )->WriteXml( aStrm );
816         }
817 
818         rWorkbook->endElement( XML_workbook );
819         rWorkbook.reset();
820         aStrm.commitStorage();
821     }
822 #if 0
823     if( pExpChangeTrack )
824         pExpChangeTrack->WriteXml();
825 #endif
826 }
827 
828