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