Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "scitems.hxx"
21 :
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>
33 :
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"
55 :
56 : #include "excdoc.hxx"
57 : #include "namebuff.hxx"
58 : #include "xeextlst.hxx"
59 :
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 :
73 : #include <math.h>
74 :
75 : #include <com/sun/star/document/XDocumentProperties.hpp>
76 : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
77 : #include <oox/token/tokens.hxx>
78 : #include <memory>
79 :
80 : using namespace oox;
81 :
82 0 : static OUString lcl_GetVbaTabName( SCTAB n )
83 : {
84 0 : OUString aRet = "__VBA__" + OUString::number( static_cast<sal_uInt16>(n) );
85 0 : return aRet;
86 : }
87 :
88 72 : static void lcl_AddBookviews( XclExpRecordList<>& aRecList, ExcTable& self )
89 : {
90 72 : aRecList.AppendNewRecord( new XclExpXmlStartElementRecord( XML_bookViews ) );
91 72 : aRecList.AppendNewRecord( new XclExpWindow1( self.GetRoot() ) );
92 72 : aRecList.AppendNewRecord( new XclExpXmlEndElementRecord( XML_bookViews ) );
93 72 : }
94 :
95 84 : static void lcl_AddCalcPr( XclExpRecordList<>& aRecList, ExcTable& self )
96 : {
97 84 : ScDocument& rDoc = self.GetDoc();
98 :
99 84 : aRecList.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_calcPr ) );
100 : // OOXTODO: calcCompleted, calcId, calcMode, calcOnSave,
101 : // concurrentCalc, concurrentManualCount,
102 : // forceFullCalc, fullCalcOnLoad, fullPrecision
103 84 : aRecList.AppendNewRecord( new XclCalccount( rDoc ) );
104 84 : aRecList.AppendNewRecord( new XclRefmode( rDoc ) );
105 84 : aRecList.AppendNewRecord( new XclIteration( rDoc ) );
106 84 : aRecList.AppendNewRecord( new XclDelta( rDoc ) );
107 84 : aRecList.AppendNewRecord( new XclExpBoolRecord(0x005F, true) ); // SAVERECALC
108 84 : aRecList.AppendNewRecord( new XclExpXmlEndSingleElementRecord() ); // XML_calcPr
109 84 : }
110 :
111 72 : static void lcl_AddWorkbookProtection( XclExpRecordList<>& aRecList, ExcTable& self )
112 : {
113 72 : aRecList.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_workbookProtection ) );
114 :
115 72 : const ScDocProtection* pProtect = self.GetDoc().GetDocProtection();
116 72 : if (pProtect && pProtect->isProtected())
117 : {
118 0 : aRecList.AppendNewRecord( new XclExpWindowProtection(pProtect->isOptionEnabled(ScDocProtection::WINDOWS)) );
119 0 : aRecList.AppendNewRecord( new XclExpProtection(pProtect->isOptionEnabled(ScDocProtection::STRUCTURE)) );
120 0 : aRecList.AppendNewRecord( new XclExpPassHash(pProtect->getPasswordHash(PASSHASH_XL)) );
121 : }
122 :
123 72 : aRecList.AppendNewRecord( new XclExpXmlEndSingleElementRecord() ); // XML_workbookProtection
124 72 : }
125 :
126 129 : static void lcl_AddScenariosAndFilters( XclExpRecordList<>& aRecList, const XclExpRoot& rRoot, SCTAB nScTab )
127 : {
128 : // Scenarios
129 129 : aRecList.AppendNewRecord( new ExcEScenarioManager( rRoot, nScTab ) );
130 : // filter
131 129 : aRecList.AppendRecord( rRoot.GetFilterManager().CreateRecord( nScTab ) );
132 129 : }
133 :
134 72 : ExcTable::ExcTable( const XclExpRoot& rRoot ) :
135 : XclExpRoot( rRoot ),
136 : mnScTab( SCTAB_GLOBAL ),
137 : nExcTab( EXC_NOTAB ),
138 72 : pTabNames( new NameBuffer( 0, 16 ) ),
139 144 : mxNoteList( new XclExpNoteList )
140 : {
141 72 : }
142 :
143 129 : ExcTable::ExcTable( const XclExpRoot& rRoot, SCTAB nScTab ) :
144 : XclExpRoot( rRoot ),
145 : mnScTab( nScTab ),
146 129 : nExcTab( rRoot.GetTabInfo().GetXclTab( nScTab ) ),
147 129 : pTabNames( new NameBuffer( 0, 16 ) ),
148 387 : mxNoteList( new XclExpNoteList )
149 : {
150 129 : }
151 :
152 531 : ExcTable::~ExcTable()
153 : {
154 201 : delete pTabNames;
155 330 : }
156 :
157 1156 : void ExcTable::Add( XclExpRecordBase* pRec )
158 : {
159 : OSL_ENSURE( pRec, "-ExcTable::Add(): pRec is NULL!" );
160 1156 : aRecList.AppendNewRecord( pRec );
161 1156 : }
162 :
163 17 : void ExcTable::FillAsHeaderBinary( ExcBoundsheetList& rBoundsheetList )
164 : {
165 17 : InitializeGlobals();
166 :
167 17 : RootData& rR = GetOldRoot();
168 17 : ScDocument& rDoc = GetDoc();
169 17 : XclExpTabInfo& rTabInfo = GetTabInfo();
170 :
171 17 : if ( GetBiff() <= EXC_BIFF5 )
172 0 : Add( new ExcBofW );
173 : else
174 17 : Add( new ExcBofW8 );
175 :
176 : SCTAB nC;
177 17 : OUString aTmpString;
178 17 : SCTAB nScTabCount = rTabInfo.GetScTabCount();
179 17 : sal_uInt16 nExcTabCount = rTabInfo.GetXclTabCount();
180 17 : sal_uInt16 nCodenames = static_cast< sal_uInt16 >( GetExtDocOptions().GetCodeNameCount() );
181 :
182 17 : SfxObjectShell* pShell = GetDocShell();
183 17 : sal_uInt16 nWriteProtHash = pShell ? pShell->GetModifyPasswordHash() : 0;
184 17 : bool bRecommendReadOnly = pShell && pShell->IsLoadReadonly();
185 :
186 17 : if( (nWriteProtHash > 0) || bRecommendReadOnly )
187 0 : Add( new XclExpEmptyRecord( EXC_ID_WRITEPROT ) );
188 :
189 : // TODO: correct codepage for BIFF5?
190 17 : sal_uInt16 nCodePage = XclTools::GetXclCodePage( (GetBiff() <= EXC_BIFF5) ? RTL_TEXTENCODING_MS_1252 : RTL_TEXTENCODING_UNICODE );
191 :
192 17 : if( GetBiff() <= EXC_BIFF5 )
193 : {
194 0 : Add( new XclExpEmptyRecord( EXC_ID_INTERFACEHDR ) );
195 0 : Add( new XclExpUInt16Record( EXC_ID_MMS, 0 ) );
196 0 : Add( new XclExpEmptyRecord( EXC_ID_TOOLBARHDR ) );
197 0 : Add( new XclExpEmptyRecord( EXC_ID_TOOLBAREND ) );
198 0 : Add( new XclExpEmptyRecord( EXC_ID_INTERFACEEND ) );
199 0 : Add( new ExcDummy_00 );
200 : }
201 : else
202 : {
203 17 : if( IsDocumentEncrypted() )
204 0 : Add( new XclExpFileEncryption( GetRoot() ) );
205 17 : Add( new XclExpInterfaceHdr( nCodePage ) );
206 17 : Add( new XclExpUInt16Record( EXC_ID_MMS, 0 ) );
207 17 : Add( new XclExpInterfaceEnd );
208 17 : Add( new XclExpWriteAccess );
209 : }
210 :
211 17 : Add( new XclExpFileSharing( GetRoot(), nWriteProtHash, bRecommendReadOnly ) );
212 17 : Add( new XclExpUInt16Record( EXC_ID_CODEPAGE, nCodePage ) );
213 :
214 17 : if( GetBiff() == EXC_BIFF8 )
215 : {
216 17 : Add( new XclExpBoolRecord( EXC_ID_DSF, false ) );
217 17 : Add( new XclExpEmptyRecord( EXC_ID_XL9FILE ) );
218 17 : rR.pTabId = new XclExpChTrTabId( std::max( nExcTabCount, nCodenames ) );
219 17 : Add( rR.pTabId );
220 17 : if( HasVbaStorage() )
221 : {
222 0 : Add( new XclObproj );
223 0 : const OUString& rCodeName = GetExtDocOptions().GetDocSettings().maGlobCodeName;
224 0 : if( !rCodeName.isEmpty() )
225 0 : Add( new XclCodename( rCodeName ) );
226 : }
227 : }
228 :
229 17 : Add( new XclExpUInt16Record( EXC_ID_FNGROUPCOUNT, 14 ) );
230 :
231 : // first setup table names and contents
232 :
233 46 : for( nC = 0 ; nC < nScTabCount ; nC++ )
234 29 : if( rTabInfo.IsExportTab( nC ) )
235 : {
236 29 : rDoc.GetName( nC, aTmpString );
237 29 : *pTabNames << aTmpString;
238 : }
239 :
240 17 : if ( GetBiff() <= EXC_BIFF5 )
241 : {
242 : // global link table: EXTERNCOUNT, EXTERNSHEET, NAME
243 0 : aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
244 0 : aRecList.AppendRecord( CreateRecord( EXC_ID_NAME ) );
245 : }
246 :
247 : // document protection options
248 17 : lcl_AddWorkbookProtection( aRecList, *this );
249 :
250 17 : if( GetBiff() == EXC_BIFF8 )
251 : {
252 17 : Add( new XclExpProt4Rev );
253 17 : Add( new XclExpProt4RevPass );
254 : }
255 :
256 17 : lcl_AddBookviews( aRecList, *this );
257 :
258 17 : Add( new XclExpXmlStartSingleElementRecord( XML_workbookPr ) );
259 17 : if ( GetBiff() == EXC_BIFF8 && GetOutput() != EXC_OUTPUT_BINARY )
260 : {
261 0 : Add( new XclExpBoolRecord(0x0040, false, XML_backupFile ) ); // BACKUP
262 0 : Add( new XclExpBoolRecord(0x008D, false, XML_showObjects ) ); // HIDEOBJ
263 : }
264 :
265 17 : if ( GetBiff() == EXC_BIFF8 )
266 : {
267 17 : Add( new XclExpBoolRecord(0x0040, false) ); // BACKUP
268 17 : Add( new XclExpBoolRecord(0x008D, false) ); // HIDEOBJ
269 : }
270 :
271 17 : if( GetBiff() <= EXC_BIFF5 )
272 : {
273 0 : Add( new ExcDummy_040 );
274 0 : Add( new Exc1904( rDoc ) );
275 0 : Add( new ExcDummy_041 );
276 : }
277 : else
278 : {
279 : // BIFF8
280 17 : Add( new Exc1904( rDoc ) );
281 17 : Add( new XclExpBoolRecord( 0x000E, !rDoc.GetDocOptions().IsCalcAsShown() ) );
282 17 : Add( new XclExpBoolRecord(0x01B7, false) ); // REFRESHALL
283 17 : Add( new XclExpBoolRecord(0x00DA, false) ); // BOOKBOOL
284 : }
285 :
286 : // Formatting: FONT, FORMAT, XF, STYLE, PALETTE
287 17 : aRecList.AppendRecord( CreateRecord( EXC_ID_FONTLIST ) );
288 17 : aRecList.AppendRecord( CreateRecord( EXC_ID_FORMATLIST ) );
289 17 : aRecList.AppendRecord( CreateRecord( EXC_ID_XFLIST ) );
290 17 : aRecList.AppendRecord( CreateRecord( EXC_ID_PALETTE ) );
291 :
292 17 : if( GetBiff() <= EXC_BIFF5 )
293 : {
294 : // Bundlesheet
295 0 : for( nC = 0 ; nC < nScTabCount ; nC++ )
296 0 : if( rTabInfo.IsExportTab( nC ) )
297 : {
298 0 : ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet( rR, nC ) );
299 0 : aRecList.AppendRecord( xBoundsheet );
300 0 : rBoundsheetList.AppendRecord( xBoundsheet );
301 : }
302 : }
303 : else
304 : {
305 : // Pivot Cache
306 17 : GetPivotTableManager().CreatePivotTables();
307 17 : aRecList.AppendRecord( GetPivotTableManager().CreatePivotCachesRecord() );
308 :
309 : // Change tracking
310 17 : if( rDoc.GetChangeTrack() )
311 : {
312 1 : rR.pUserBViewList = new XclExpUserBViewList( *rDoc.GetChangeTrack() );
313 1 : Add( rR.pUserBViewList );
314 : }
315 :
316 : // Natural Language Formulas Flag
317 17 : aRecList.AppendNewRecord( new XclExpBoolRecord( EXC_ID_USESELFS, GetDoc().GetDocOptions().IsLookUpColRowNames() ) );
318 :
319 : // Bundlesheet
320 46 : for( nC = 0 ; nC < nScTabCount ; nC++ )
321 29 : if( rTabInfo.IsExportTab( nC ) )
322 : {
323 29 : ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet8( rR, nC ) );
324 29 : aRecList.AppendRecord( xBoundsheet );
325 29 : rBoundsheetList.AppendRecord( xBoundsheet );
326 : }
327 :
328 17 : for( SCTAB nAdd = 0; nC < static_cast<SCTAB>(nCodenames) ; nC++, nAdd++ )
329 : {
330 0 : aTmpString = lcl_GetVbaTabName( nAdd );
331 0 : ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet8( aTmpString ) );
332 0 : aRecList.AppendRecord( xBoundsheet );
333 0 : rBoundsheetList.AppendRecord( xBoundsheet );
334 0 : }
335 :
336 : // COUNTRY - in BIFF8 in workbook globals
337 17 : Add( new XclExpCountry( GetRoot() ) );
338 :
339 : // link table: SUPBOOK, XCT, CRN, EXTERNNAME, EXTERNSHEET, NAME
340 17 : aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
341 17 : aRecList.AppendRecord( CreateRecord( EXC_ID_NAME ) );
342 :
343 17 : Add( new XclExpRecalcId );
344 :
345 : // MSODRAWINGGROUP per-document data
346 17 : aRecList.AppendRecord( GetObjectManager().CreateDrawingGroup() );
347 : // Shared string table: SST, EXTSST
348 17 : aRecList.AppendRecord( CreateRecord( EXC_ID_SST ) );
349 :
350 17 : Add( new XclExpBookExt );
351 : }
352 :
353 17 : Add( new ExcEof );
354 17 : }
355 :
356 55 : void ExcTable::FillAsHeaderXml( ExcBoundsheetList& rBoundsheetList )
357 : {
358 55 : InitializeGlobals();
359 :
360 55 : RootData& rR = GetOldRoot();
361 55 : ScDocument& rDoc = GetDoc();
362 55 : XclExpTabInfo& rTabInfo = GetTabInfo();
363 :
364 : SCTAB nC;
365 55 : OUString aTmpString;
366 55 : SCTAB nScTabCount = rTabInfo.GetScTabCount();
367 55 : sal_uInt16 nExcTabCount = rTabInfo.GetXclTabCount();
368 55 : sal_uInt16 nCodenames = static_cast< sal_uInt16 >( GetExtDocOptions().GetCodeNameCount() );
369 :
370 55 : rR.pTabId = new XclExpChTrTabId( std::max( nExcTabCount, nCodenames ) );
371 55 : Add( rR.pTabId );
372 :
373 : // first setup table names and contents
374 :
375 155 : for( nC = 0 ; nC < nScTabCount ; nC++ )
376 100 : if( rTabInfo.IsExportTab( nC ) )
377 : {
378 100 : rDoc.GetName( nC, aTmpString );
379 100 : *pTabNames << aTmpString;
380 : }
381 :
382 55 : Add( new XclExpXmlStartSingleElementRecord( XML_workbookPr ) );
383 55 : Add( new XclExpBoolRecord(0x0040, false, XML_backupFile ) ); // BACKUP
384 55 : Add( new XclExpBoolRecord(0x008D, false, XML_showObjects ) ); // HIDEOBJ
385 :
386 55 : Add( new Exc1904( rDoc ) );
387 : // OOXTODO: The following /workbook/workbookPr attributes are mapped
388 : // to various BIFF records that are not currently supported:
389 : //
390 : // XML_allowRefreshQuery: QSISTAG 802h: fEnableRefresh
391 : // XML_autoCompressPictures: COMPRESSPICTURES 89Bh: fAutoCompressPictures
392 : // XML_checkCompatibility: COMPAT12 88Ch: fNoCompatChk
393 : // XML_codeName: "Calc"
394 : // XML_defaultThemeVersion: ???
395 : // XML_filterPrivacy: BOOKEXT 863h: fFilterPrivacy
396 : // XML_hidePivotFieldList: BOOKBOOL DAh: fHidePivotTableFList
397 : // XML_promptedSolutions: BOOKEXT 863h: fBuggedUserAboutSolution
398 : // XML_publishItems: NAMEPUBLISH 893h: fPublished
399 : // XML_saveExternalLinkValues: BOOKBOOL DAh: fNoSavSupp
400 : // XML_showBorderUnselectedTables: BOOKBOOL DAh: fHideBorderUnsels
401 : // XML_showInkAnnotation: BOOKEXT 863h: fShowInkAnnotation
402 : // XML_showPivotChart: PIVOTCHARTBITS 859h: fGXHide??
403 : // XML_updateLinks: BOOKBOOL DAh: grbitUpdateLinks
404 55 : Add( new XclExpXmlEndSingleElementRecord() ); // XML_workbookPr
405 :
406 : // Formatting: FONT, FORMAT, XF, STYLE, PALETTE
407 55 : aRecList.AppendNewRecord( new XclExpXmlStyleSheet( *this ) );
408 :
409 : // Change tracking
410 55 : if( rDoc.GetChangeTrack() )
411 : {
412 1 : rR.pUserBViewList = new XclExpUserBViewList( *rDoc.GetChangeTrack() );
413 1 : Add( rR.pUserBViewList );
414 : }
415 :
416 55 : lcl_AddWorkbookProtection( aRecList, *this );
417 55 : lcl_AddBookviews( aRecList, *this );
418 :
419 : // Bundlesheet
420 55 : aRecList.AppendNewRecord( new XclExpXmlStartElementRecord( XML_sheets ) );
421 155 : for( nC = 0 ; nC < nScTabCount ; nC++ )
422 100 : if( rTabInfo.IsExportTab( nC ) )
423 : {
424 100 : ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet8( rR, nC ) );
425 100 : aRecList.AppendRecord( xBoundsheet );
426 100 : rBoundsheetList.AppendRecord( xBoundsheet );
427 : }
428 55 : aRecList.AppendNewRecord( new XclExpXmlEndElementRecord( XML_sheets ) );
429 :
430 55 : for( SCTAB nAdd = 0; nC < static_cast<SCTAB>(nCodenames) ; nC++, nAdd++ )
431 : {
432 0 : aTmpString = lcl_GetVbaTabName( nAdd );
433 0 : ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet8( aTmpString ) );
434 0 : aRecList.AppendRecord( xBoundsheet );
435 0 : rBoundsheetList.AppendRecord( xBoundsheet );
436 0 : }
437 :
438 : // link table: SUPBOOK, XCT, CRN, EXTERNNAME, EXTERNSHEET, NAME
439 55 : aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
440 55 : aRecList.AppendRecord( CreateRecord( EXC_ID_NAME ) );
441 :
442 55 : lcl_AddCalcPr( aRecList, *this );
443 :
444 : // MSODRAWINGGROUP per-document data
445 55 : aRecList.AppendRecord( GetObjectManager().CreateDrawingGroup() );
446 : // Shared string table: SST, EXTSST
447 55 : aRecList.AppendRecord( CreateRecord( EXC_ID_SST ) );
448 55 : }
449 :
450 29 : void ExcTable::FillAsTableBinary( SCTAB nCodeNameIdx )
451 : {
452 29 : InitializeTable( mnScTab );
453 :
454 29 : RootData& rR = GetOldRoot();
455 29 : XclBiff eBiff = GetBiff();
456 29 : ScDocument& rDoc = GetDoc();
457 :
458 : OSL_ENSURE( (mnScTab >= 0L) && (mnScTab <= MAXTAB), "-ExcTable::Table(): mnScTab - no ordinary table!" );
459 : OSL_ENSURE( nExcTab <= static_cast<sal_uInt16>(MAXTAB), "-ExcTable::Table(): nExcTab - no ordinary table!" );
460 :
461 : // create a new OBJ list for this sheet (may be used by notes, autofilter, data validation)
462 29 : if( eBiff == EXC_BIFF8 )
463 29 : GetObjectManager().StartSheet();
464 :
465 : // cell table: DEFROWHEIGHT, DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
466 29 : mxCellTable.reset( new XclExpCellTable( GetRoot() ) );
467 :
468 : //export cell notes
469 29 : std::vector<sc::NoteEntry> aNotes;
470 29 : rDoc.GetAllNoteEntries(aNotes);
471 38 : for (std::vector<sc::NoteEntry>::const_iterator it = aNotes.begin(), itEnd = aNotes.end(); it != itEnd; ++it)
472 : {
473 9 : if (it->maPos.Tab() != mnScTab)
474 6 : continue;
475 :
476 3 : mxNoteList->AppendNewRecord(new XclExpNote(GetRoot(), it->maPos, it->mpNote, OUString()));
477 : }
478 :
479 : // WSBOOL needs data from page settings, create it here, add it later
480 58 : std::shared_ptr< XclExpPageSettings > xPageSett( new XclExpPageSettings( GetRoot() ) );
481 29 : bool bFitToPages = xPageSett->GetPageData().mbFitToPages;
482 :
483 29 : if( eBiff <= EXC_BIFF5 )
484 : {
485 0 : Add( new ExcBof );
486 0 : Add( new ExcDummy_02a );
487 : }
488 : else
489 : {
490 29 : Add( new ExcBof8 );
491 29 : lcl_AddCalcPr( aRecList, *this );
492 : }
493 :
494 : // GUTS (count & size of outline icons)
495 29 : aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_GUTS ) );
496 : // DEFROWHEIGHT, created by the cell table
497 29 : aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID2_DEFROWHEIGHT ) );
498 :
499 : // COUNTRY - in BIFF5/7 in every worksheet
500 29 : if( eBiff <= EXC_BIFF5 )
501 0 : Add( new XclExpCountry( GetRoot() ) );
502 :
503 29 : Add( new XclExpWsbool( bFitToPages ) );
504 :
505 : // page settings (SETUP and various other records)
506 29 : aRecList.AppendRecord( xPageSett );
507 :
508 29 : const ScTableProtection* pTabProtect = rDoc.GetTabProtection(mnScTab);
509 29 : if (pTabProtect && pTabProtect->isProtected())
510 : {
511 0 : Add( new XclExpProtection(true) );
512 0 : Add( new XclExpBoolRecord(0x00DD, pTabProtect->isOptionEnabled(ScTableProtection::SCENARIOS)) );
513 0 : Add( new XclExpBoolRecord(0x0063, pTabProtect->isOptionEnabled(ScTableProtection::OBJECTS)) );
514 0 : Add( new XclExpPassHash(pTabProtect->getPasswordHash(PASSHASH_XL)) );
515 : }
516 :
517 : // local link table: EXTERNCOUNT, EXTERNSHEET
518 29 : if( eBiff <= EXC_BIFF5 )
519 0 : aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
520 :
521 29 : if ( eBiff == EXC_BIFF8 )
522 29 : lcl_AddScenariosAndFilters( aRecList, GetRoot(), mnScTab );
523 :
524 : // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
525 29 : aRecList.AppendRecord( mxCellTable );
526 :
527 : // MERGEDCELLS record, generated by the cell table
528 29 : aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_MERGEDCELLS ) );
529 : // label ranges
530 29 : if( eBiff == EXC_BIFF8 )
531 29 : Add( new XclExpLabelranges( GetRoot() ) );
532 : // data validation (DVAL and list of DV records), generated by the cell table
533 29 : aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_DVAL ) );
534 :
535 29 : if( eBiff == EXC_BIFF8 )
536 : {
537 : // all MSODRAWING and OBJ stuff of this sheet goes here
538 29 : aRecList.AppendRecord( GetObjectManager().ProcessDrawing( GetSdrPage( mnScTab ) ) );
539 : // pivot tables
540 29 : aRecList.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab ) );
541 : }
542 :
543 : // list of NOTE records, generated by the cell table
544 29 : aRecList.AppendRecord( mxNoteList );
545 :
546 : // sheet view settings: WINDOW2, SCL, PANE, SELECTION
547 29 : aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
548 :
549 29 : if( eBiff == EXC_BIFF8 )
550 : {
551 : // sheet protection options
552 29 : Add( new XclExpSheetProtectOptions( GetRoot(), mnScTab ) );
553 :
554 : // enhanced protections if there are
555 29 : if (pTabProtect)
556 : {
557 0 : const ::std::vector<ScEnhancedProtection>& rProts( pTabProtect->getEnhancedProtection());
558 0 : for (::std::vector<ScEnhancedProtection>::const_iterator it( rProts.begin()), itEnd( rProts.end());
559 : it != itEnd; ++it)
560 : {
561 0 : Add( new XclExpSheetEnhancedProtection( GetRoot(), *it));
562 : }
563 : }
564 :
565 : // web queries
566 29 : Add( new XclExpWebQueryBuffer( GetRoot() ) );
567 :
568 : // conditional formats
569 29 : Add( new XclExpCondFormatBuffer( GetRoot(), XclExtLstRef() ) );
570 :
571 29 : if( HasVbaStorage() )
572 0 : if( nCodeNameIdx < GetExtDocOptions().GetCodeNameCount() )
573 0 : Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx ) ) );
574 : }
575 :
576 : // list of HLINK records, generated by the cell table
577 29 : aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_HLINK ) );
578 :
579 : // change tracking
580 29 : if( rR.pUserBViewList )
581 : {
582 3 : XclExpUserBViewList::const_iterator iter;
583 9 : for ( iter = rR.pUserBViewList->begin(); iter != rR.pUserBViewList->end(); ++iter)
584 : {
585 6 : Add( new XclExpUsersViewBegin( (*iter)->GetGUID(), nExcTab ) );
586 6 : Add( new XclExpUsersViewEnd );
587 : }
588 : }
589 :
590 : // EOF
591 58 : Add( new ExcEof );
592 29 : }
593 :
594 100 : void ExcTable::FillAsTableXml()
595 : {
596 100 : InitializeTable( mnScTab );
597 :
598 100 : ScDocument& rDoc = GetDoc();
599 :
600 : OSL_ENSURE( (mnScTab >= 0L) && (mnScTab <= MAXTAB), "-ExcTable::Table(): mnScTab - no ordinary table!" );
601 : OSL_ENSURE( nExcTab <= static_cast<sal_uInt16>(MAXTAB), "-ExcTable::Table(): nExcTab - no ordinary table!" );
602 :
603 : // create a new OBJ list for this sheet (may be used by notes, autofilter, data validation)
604 100 : GetObjectManager().StartSheet();
605 :
606 : // cell table: DEFROWHEIGHT, DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
607 100 : mxCellTable.reset( new XclExpCellTable( GetRoot() ) );
608 :
609 : //export cell notes
610 100 : std::vector<sc::NoteEntry> aNotes;
611 100 : rDoc.GetAllNoteEntries(aNotes);
612 100 : for (std::vector<sc::NoteEntry>::const_iterator it = aNotes.begin(), itEnd = aNotes.end(); it != itEnd; ++it)
613 : {
614 0 : if (it->maPos.Tab() != mnScTab)
615 0 : continue;
616 :
617 0 : mxNoteList->AppendNewRecord(new XclExpNote(GetRoot(), it->maPos, it->mpNote, OUString()));
618 : }
619 :
620 : // WSBOOL needs data from page settings, create it here, add it later
621 200 : std::shared_ptr< XclExpPageSettings > xPageSett( new XclExpPageSettings( GetRoot() ) );
622 200 : XclExtLstRef xExtLst( new XclExtLst( GetRoot() ) );
623 100 : bool bFitToPages = xPageSett->GetPageData().mbFitToPages;
624 :
625 100 : Color aTabColor = GetRoot().GetDoc().GetTabBgColor(mnScTab);
626 100 : Add(new XclExpXmlSheetPr(bFitToPages, mnScTab, aTabColor, &GetFilterManager()));
627 :
628 : // GUTS (count & size of outline icons)
629 100 : aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_GUTS ) );
630 : // DEFROWHEIGHT, created by the cell table
631 100 : aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID2_DEFROWHEIGHT ) );
632 :
633 100 : aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID3_DIMENSIONS ) );
634 :
635 : // sheet view settings: WINDOW2, SCL, PANE, SELECTION
636 100 : aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
637 :
638 : // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
639 100 : aRecList.AppendRecord( mxCellTable );
640 :
641 : // list of NOTE records, generated by the cell table
642 : // not in the worksheet file
643 100 : if( mxNoteList != 0 && !mxNoteList->IsEmpty() )
644 0 : aRecList.AppendNewRecord( new XclExpComments( mnScTab, *mxNoteList ) );
645 :
646 100 : const ScTableProtection* pTabProtect = rDoc.GetTabProtection(mnScTab);
647 100 : if (pTabProtect && pTabProtect->isProtected())
648 1 : Add( new XclExpSheetProtection(true, mnScTab) );
649 :
650 100 : lcl_AddScenariosAndFilters( aRecList, GetRoot(), mnScTab );
651 :
652 : // MERGEDCELLS record, generated by the cell table
653 100 : aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_MERGEDCELLS ) );
654 :
655 : // conditional formats
656 100 : Add( new XclExpCondFormatBuffer( GetRoot(), xExtLst ) );
657 :
658 : // data validation (DVAL and list of DV records), generated by the cell table
659 100 : aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_DVAL ) );
660 :
661 : // list of HLINK records, generated by the cell table
662 200 : XclExpRecordRef xHyperlinks = mxCellTable->CreateRecord( EXC_ID_HLINK );
663 100 : XclExpHyperlinkList* xHyperlinkList = dynamic_cast<XclExpHyperlinkList*>(xHyperlinks.get());
664 100 : if( xHyperlinkList != NULL && !xHyperlinkList->IsEmpty() )
665 : {
666 0 : aRecList.AppendNewRecord( new XclExpXmlStartElementRecord( XML_hyperlinks ) );
667 0 : aRecList.AppendRecord( xHyperlinks );
668 0 : aRecList.AppendNewRecord( new XclExpXmlEndElementRecord( XML_hyperlinks ) );
669 : }
670 :
671 100 : aRecList.AppendRecord( xPageSett );
672 :
673 : // all MSODRAWING and OBJ stuff of this sheet goes here
674 100 : aRecList.AppendRecord( GetObjectManager().ProcessDrawing( GetSdrPage( mnScTab ) ) );
675 :
676 100 : XclExpImgData* pImgData = xPageSett->getGraphicExport();
677 100 : if (pImgData)
678 0 : aRecList.AppendRecord(std::shared_ptr<XclExpRecordBase>(pImgData));
679 :
680 200 : aRecList.AppendRecord( xExtLst );
681 100 : }
682 :
683 0 : void ExcTable::FillAsEmptyTable( SCTAB nCodeNameIdx )
684 : {
685 0 : InitializeTable( mnScTab );
686 :
687 0 : if( HasVbaStorage() && (nCodeNameIdx < GetExtDocOptions().GetCodeNameCount()) )
688 : {
689 0 : if( GetBiff() <= EXC_BIFF5 )
690 : {
691 0 : Add( new ExcBof );
692 : }
693 : else
694 : {
695 0 : Add( new ExcBof8 );
696 0 : Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx ) ) );
697 : }
698 : // sheet view settings: WINDOW2, SCL, PANE, SELECTION
699 0 : aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
700 0 : Add( new ExcEof );
701 : }
702 0 : }
703 :
704 46 : void ExcTable::Write( XclExpStream& rStrm )
705 : {
706 46 : SetCurrScTab( mnScTab );
707 46 : if( mxCellTable.get() )
708 29 : mxCellTable->Finalize();
709 46 : aRecList.Save( rStrm );
710 46 : }
711 :
712 155 : void ExcTable::WriteXml( XclExpXmlStream& rStrm )
713 : {
714 155 : if (!GetTabInfo().IsExportTab(mnScTab))
715 : {
716 : // header export.
717 55 : SetCurrScTab(mnScTab);
718 55 : if (mxCellTable)
719 0 : mxCellTable->Finalize();
720 55 : aRecList.SaveXml(rStrm);
721 :
722 210 : return;
723 : }
724 :
725 : // worksheet export
726 100 : OUString sSheetName = XclXmlUtils::GetStreamName( "xl/", "worksheets/sheet", mnScTab+1 );
727 :
728 200 : sax_fastparser::FSHelperPtr pWorksheet = rStrm.GetStreamForPath( sSheetName );
729 :
730 100 : rStrm.PushStream( pWorksheet );
731 :
732 : pWorksheet->startElement( XML_worksheet,
733 : XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
734 : FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
735 100 : FSEND );
736 :
737 100 : SetCurrScTab( mnScTab );
738 100 : if (mxCellTable)
739 100 : mxCellTable->Finalize();
740 100 : aRecList.SaveXml( rStrm );
741 :
742 100 : XclExpXmlPivotTables* pPT = GetXmlPivotTableManager().GetTablesBySheet(mnScTab);
743 100 : if (pPT)
744 2 : pPT->SaveXml(rStrm);
745 :
746 100 : rStrm.GetCurrentStream()->endElement( XML_worksheet );
747 200 : rStrm.PopStream();
748 : }
749 :
750 72 : ExcDocument::ExcDocument( const XclExpRoot& rRoot ) :
751 : XclExpRoot( rRoot ),
752 : aHeader( rRoot ),
753 72 : pExpChangeTrack( NULL )
754 : {
755 72 : }
756 :
757 161 : ExcDocument::~ExcDocument()
758 : {
759 72 : maTableList.RemoveAllRecords(); // for the following assertion!
760 72 : delete pExpChangeTrack;
761 89 : }
762 :
763 72 : void ExcDocument::ReadDoc()
764 : {
765 72 : InitializeConvert();
766 :
767 72 : if (GetOutput() == EXC_OUTPUT_BINARY)
768 17 : aHeader.FillAsHeaderBinary(maBoundsheetList);
769 : else
770 : {
771 55 : aHeader.FillAsHeaderXml(maBoundsheetList);
772 55 : GetXmlPivotTableManager().Initialize();
773 : }
774 :
775 72 : SCTAB nScTab = 0, nScTabCount = GetTabInfo().GetScTabCount();
776 72 : SCTAB nCodeNameIdx = 0, nCodeNameCount = GetExtDocOptions().GetCodeNameCount();
777 :
778 201 : for( ; nScTab < nScTabCount; ++nScTab )
779 : {
780 129 : if( GetTabInfo().IsExportTab( nScTab ) )
781 : {
782 129 : ExcTableList::RecordRefType xTab( new ExcTable( GetRoot(), nScTab ) );
783 129 : maTableList.AppendRecord( xTab );
784 129 : if (GetOutput() == EXC_OUTPUT_BINARY)
785 29 : xTab->FillAsTableBinary(nCodeNameIdx);
786 : else
787 100 : xTab->FillAsTableXml();
788 :
789 129 : ++nCodeNameIdx;
790 : }
791 : }
792 72 : for( ; nCodeNameIdx < nCodeNameCount; ++nScTab, ++nCodeNameIdx )
793 : {
794 0 : ExcTableList::RecordRefType xTab( new ExcTable( GetRoot(), nScTab ) );
795 0 : maTableList.AppendRecord( xTab );
796 0 : xTab->FillAsEmptyTable( nCodeNameIdx );
797 0 : }
798 :
799 72 : if ( GetBiff() == EXC_BIFF8 )
800 : {
801 : // complete temporary Escher stream
802 72 : GetObjectManager().EndDocument();
803 :
804 : // change tracking
805 72 : if ( GetDoc().GetChangeTrack() )
806 2 : pExpChangeTrack = new XclExpChangeTrack( GetRoot() );
807 : }
808 72 : }
809 :
810 17 : void ExcDocument::Write( SvStream& rSvStrm )
811 : {
812 17 : if( !maTableList.IsEmpty() )
813 : {
814 17 : InitializeSave();
815 :
816 17 : XclExpStream aXclStrm( rSvStrm, GetRoot() );
817 :
818 17 : aHeader.Write( aXclStrm );
819 :
820 : OSL_ENSURE( maTableList.GetSize() == maBoundsheetList.GetSize(),
821 : "ExcDocument::Write - different number of sheets and BOUNDSHEET records" );
822 :
823 46 : for( size_t nTab = 0, nTabCount = maTableList.GetSize(); nTab < nTabCount; ++nTab )
824 : {
825 : // set current stream position in BOUNDSHEET record
826 29 : ExcBoundsheetRef xBoundsheet = maBoundsheetList.GetRecord( nTab );
827 29 : if( xBoundsheet.get() )
828 29 : xBoundsheet->SetStreamPos( aXclStrm.GetSvStreamPos() );
829 : // write the table
830 29 : maTableList.GetRecord( nTab )->Write( aXclStrm );
831 29 : }
832 :
833 : // write the table stream positions into the BOUNDSHEET records
834 46 : for( size_t nBSheet = 0, nBSheetCount = maBoundsheetList.GetSize(); nBSheet < nBSheetCount; ++nBSheet )
835 46 : maBoundsheetList.GetRecord( nBSheet )->UpdateStreamPos( aXclStrm );
836 : }
837 17 : if( pExpChangeTrack )
838 1 : pExpChangeTrack->Write();
839 17 : }
840 :
841 55 : void ExcDocument::WriteXml( XclExpXmlStream& rStrm )
842 : {
843 55 : SfxObjectShell* pDocShell = GetDocShell();
844 :
845 : using namespace ::com::sun::star;
846 55 : uno::Reference<document::XDocumentPropertiesSupplier> xDPS( pDocShell->GetModel(), uno::UNO_QUERY_THROW );
847 110 : uno::Reference<document::XDocumentProperties> xDocProps = xDPS->getDocumentProperties();
848 :
849 55 : rStrm.exportDocumentProperties( xDocProps );
850 :
851 55 : sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
852 : rWorkbook->startElement( XML_workbook,
853 : XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
854 : FSNS(XML_xmlns, XML_r), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
855 55 : FSEND );
856 : rWorkbook->singleElement( XML_fileVersion,
857 : XML_appName, "Calc",
858 : // OOXTODO: XML_codeName
859 : // OOXTODO: XML_lastEdited
860 : // OOXTODO: XML_lowestEdited
861 : // OOXTODO: XML_rupBuild
862 55 : FSEND );
863 :
864 55 : if( !maTableList.IsEmpty() )
865 : {
866 55 : InitializeSave();
867 :
868 55 : aHeader.WriteXml( rStrm );
869 :
870 155 : for( size_t nTab = 0, nTabCount = maTableList.GetSize(); nTab < nTabCount; ++nTab )
871 : {
872 : // write the table
873 100 : maTableList.GetRecord( nTab )->WriteXml( rStrm );
874 : }
875 : }
876 :
877 55 : if( pExpChangeTrack )
878 1 : pExpChangeTrack->WriteXml( rStrm );
879 :
880 55 : XclExpXmlPivotCaches& rCaches = GetXmlPivotTableManager().GetCaches();
881 55 : if (rCaches.HasCaches())
882 2 : rCaches.SaveXml(rStrm);
883 :
884 55 : rWorkbook->endElement( XML_workbook );
885 110 : rWorkbook.reset();
886 85 : }
887 :
888 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|