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 #include "oox/xls/workbookhelper.hxx"
25
26 #include <com/sun/star/container/XIndexAccess.hpp>
27 #include <com/sun/star/container/XNameContainer.hpp>
28 #include <com/sun/star/document/XActionLockable.hpp>
29 #include <com/sun/star/sheet/XDatabaseRange.hpp>
30 #include <com/sun/star/sheet/XDatabaseRanges.hpp>
31 #include <com/sun/star/sheet/XNamedRange2.hpp>
32 #include <com/sun/star/sheet/XNamedRanges2.hpp>
33 #include <com/sun/star/sheet/XSpreadsheet.hpp>
34 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
35 #include <com/sun/star/style/XStyle.hpp>
36 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
37 #include <com/sun/star/table/CellAddress.hpp>
38 #include <osl/thread.h>
39 #include "oox/drawingml/theme.hxx"
40 #include "oox/helper/progressbar.hxx"
41 #include "oox/helper/propertyset.hxx"
42 #include "oox/ole/vbaproject.hxx"
43 #include "oox/xls/addressconverter.hxx"
44 #include "oox/xls/biffinputstream.hxx"
45 #include "oox/xls/biffcodec.hxx"
46 #include "oox/xls/connectionsbuffer.hxx"
47 #include "oox/xls/defnamesbuffer.hxx"
48 #include "oox/xls/excelchartconverter.hxx"
49 #include "oox/xls/excelfilter.hxx"
50 #include "oox/xls/externallinkbuffer.hxx"
51 #include "oox/xls/formulaparser.hxx"
52 #include "oox/xls/pagesettings.hxx"
53 #include "oox/xls/pivotcachebuffer.hxx"
54 #include "oox/xls/pivottablebuffer.hxx"
55 #include "oox/xls/scenariobuffer.hxx"
56 #include "oox/xls/sharedstringsbuffer.hxx"
57 #include "oox/xls/stylesbuffer.hxx"
58 #include "oox/xls/tablebuffer.hxx"
59 #include "oox/xls/themebuffer.hxx"
60 #include "oox/xls/unitconverter.hxx"
61 #include "oox/xls/viewsettings.hxx"
62 #include "oox/xls/workbooksettings.hxx"
63 #include "oox/xls/worksheetbuffer.hxx"
64
65 namespace oox {
66 namespace xls {
67
68 // ============================================================================
69
70 using namespace ::com::sun::star::awt;
71 using namespace ::com::sun::star::container;
72 using namespace ::com::sun::star::document;
73 using namespace ::com::sun::star::lang;
74 using namespace ::com::sun::star::sheet;
75 using namespace ::com::sun::star::style;
76 using namespace ::com::sun::star::table;
77 using namespace ::com::sun::star::uno;
78
79 using ::oox::core::BinaryFilterBase;
80 using ::oox::core::FilterBase;
81 using ::oox::core::FragmentHandler;
82 using ::oox::core::XmlFilterBase;
83 using ::oox::drawingml::Theme;
84 using ::rtl::OUString;
85
86 // ============================================================================
87
operator ()(const OUString & rName1,const OUString & rName2) const88 bool IgnoreCaseCompare::operator()( const OUString& rName1, const OUString& rName2 ) const
89 {
90 // there is no wrapper in rtl::OUString, TODO: compare with collator
91 return ::rtl_ustr_compareIgnoreAsciiCase_WithLength(
92 rName1.getStr(), rName1.getLength(), rName2.getStr(), rName2.getLength() ) < 0;
93 }
94
95 // ============================================================================
96
97 class WorkbookGlobals
98 {
99 public:
100 explicit WorkbookGlobals( ExcelFilter& rFilter );
101 explicit WorkbookGlobals( ExcelBiffFilter& rFilter, BiffType eBiff );
102 ~WorkbookGlobals();
103
104 /** Returns true, if this helper refers to a valid document. */
isValid() const105 inline bool isValid() const { return mxDoc.is(); }
106
107 // filter -----------------------------------------------------------------
108
109 /** Returns the base filter object (base class of all filters). */
getBaseFilter() const110 inline FilterBase& getBaseFilter() const { return mrBaseFilter; }
111 /** Returns the filter progress bar. */
getProgressBar() const112 inline SegmentProgressBar& getProgressBar() const { return *mxProgressBar; }
113 /** Returns the file type of the current filter. */
getFilterType() const114 inline FilterType getFilterType() const { return meFilterType; }
115 /** Returns true, if the file is a multi-sheet document, or false if single-sheet. */
isWorkbookFile() const116 inline bool isWorkbookFile() const { return mbWorkbook; }
117 /** Returns the VBA project storage. */
getVbaProjectStorage() const118 inline StorageRef getVbaProjectStorage() const { return mxVbaPrjStrg; }
119 /** Returns the index of the current Calc sheet, if filter currently processes a sheet. */
getCurrentSheetIndex() const120 inline sal_Int16 getCurrentSheetIndex() const { return mnCurrSheet; }
121
122 /** Sets the VBA project storage used to import VBA source code and forms. */
setVbaProjectStorage(const StorageRef & rxVbaPrjStrg)123 inline void setVbaProjectStorage( const StorageRef& rxVbaPrjStrg ) { mxVbaPrjStrg = rxVbaPrjStrg; }
124 /** Sets the index of the current Calc sheet, if filter currently processes a sheet. */
setCurrentSheetIndex(sal_Int16 nSheet)125 inline void setCurrentSheetIndex( sal_Int16 nSheet ) { mnCurrSheet = nSheet; }
126
127 // document model ---------------------------------------------------------
128
129 /** Returns a reference to the source/target spreadsheet document model. */
getDocument() const130 inline Reference< XSpreadsheetDocument > getDocument() const { return mxDoc; }
131 /** Returns the cell or page styles container from the Calc document. */
132 Reference< XNameContainer > getStyleFamily( bool bPageStyles ) const;
133 /** Returns the specified cell or page style from the Calc document. */
134 Reference< XStyle > getStyleObject( const OUString& rStyleName, bool bPageStyle ) const;
135 /** Creates and returns a defined name on-the-fly in the Calc document. */
136 Reference< XNamedRange2 > createNamedRangeObject( OUString& orScope, OUString& orName, sal_Int32 nNameFlags ) const;
137 /** Creates and returns a database range on-the-fly in the Calc document. */
138 Reference< XDatabaseRange > createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const;
139 /** Creates and returns a com.sun.star.style.Style object for cells or pages. */
140 Reference< XStyle > createStyleObject( OUString& orStyleName, bool bPageStyle ) const;
141
142 // buffers ----------------------------------------------------------------
143
144 /** Returns the global workbook settings object. */
getWorkbookSettings() const145 inline WorkbookSettings& getWorkbookSettings() const { return *mxWorkbookSettings; }
146 /** Returns the workbook and sheet view settings object. */
getViewSettings() const147 inline ViewSettings& getViewSettings() const { return *mxViewSettings; }
148 /** Returns the worksheet buffer containing sheet names and properties. */
getWorksheets() const149 inline WorksheetBuffer& getWorksheets() const { return *mxWorksheets; }
150 /** Returns the office theme object read from the theme substorage. */
getTheme() const151 inline ThemeBuffer& getTheme() const { return *mxTheme; }
152 /** Returns all cell formatting objects read from the styles substream. */
getStyles() const153 inline StylesBuffer& getStyles() const { return *mxStyles; }
154 /** Returns the shared strings read from the shared strings substream. */
getSharedStrings() const155 inline SharedStringsBuffer& getSharedStrings() const { return *mxSharedStrings; }
156 /** Returns the external links read from the external links substream. */
getExternalLinks() const157 inline ExternalLinkBuffer& getExternalLinks() const { return *mxExtLinks; }
158 /** Returns the defined names read from the workbook globals. */
getDefinedNames() const159 inline DefinedNamesBuffer& getDefinedNames() const { return *mxDefNames; }
160 /** Returns the tables collection (equivalent to Calc's database ranges). */
getTables() const161 inline TableBuffer& getTables() const { return *mxTables; }
162 /** Returns the scenarios collection. */
getScenarios() const163 inline ScenarioBuffer& getScenarios() const { return *mxScenarios; }
164 /** Returns the collection of external data connections. */
getConnections() const165 inline ConnectionsBuffer& getConnections() const { return *mxConnections; }
166 /** Returns the collection of pivot caches. */
getPivotCaches() const167 inline PivotCacheBuffer& getPivotCaches() const { return *mxPivotCaches; }
168 /** Returns the collection of pivot tables. */
getPivotTables()169 inline PivotTableBuffer& getPivotTables() { return *mxPivotTables; }
170
171 // converters -------------------------------------------------------------
172
173 /** Returns the import formula parser. */
getFormulaParser() const174 inline FormulaParser& getFormulaParser() const { return *mxFmlaParser; }
175 /** Returns the measurement unit converter. */
getUnitConverter() const176 inline UnitConverter& getUnitConverter() const { return *mxUnitConverter; }
177 /** Returns the converter for string to cell address/range conversion. */
getAddressConverter() const178 inline AddressConverter& getAddressConverter() const { return *mxAddrConverter; }
179 /** Returns the chart object converter. */
getChartConverter() const180 inline ExcelChartConverter& getChartConverter() const { return *mxChartConverter; }
181 /** Returns the page/print settings converter. */
getPageSettingsConverter() const182 inline PageSettingsConverter& getPageSettingsConverter() const { return *mxPageSettConverter; }
183
184 // OOXML/BIFF12 specific --------------------------------------------------
185
186 /** Returns the base OOXML/BIFF12 filter object. */
getOoxFilter() const187 inline XmlFilterBase& getOoxFilter() const { return *mpOoxFilter; }
188
189 // BIFF2-BIFF8 specific ---------------------------------------------------
190
191 /** Returns the base BIFF filter object. */
getBiffFilter() const192 inline BinaryFilterBase& getBiffFilter() const { return *mpBiffFilter; }
193 /** Returns the BIFF type in binary filter. */
getBiff() const194 inline BiffType getBiff() const { return meBiff; }
195 /** Returns the text encoding used to import/export byte strings. */
getTextEncoding() const196 inline rtl_TextEncoding getTextEncoding() const { return meTextEnc; }
197 /** Sets the text encoding to import/export byte strings. */
198 void setTextEncoding( rtl_TextEncoding eTextEnc );
199 /** Sets code page read from a CODEPAGE record for byte string import. */
200 void setCodePage( sal_uInt16 nCodePage );
201 /** Sets text encoding from the default application font, if CODEPAGE record is missing. */
202 void setAppFontEncoding( rtl_TextEncoding eAppFontEnc );
203 /** Enables workbook file mode, used for BIFF4 workspace files. */
204 void setIsWorkbookFile();
205 /** Recreates global buffers that are used per sheet in specific BIFF versions. */
206 void createBuffersPerSheet( sal_Int16 nSheet );
207 /** Returns the codec helper that stores the encoder/decoder object. */
getCodecHelper()208 inline BiffCodecHelper& getCodecHelper() { return *mxCodecHelper; }
209
210 private:
211 /** Initializes some basic members and sets needed document properties. */
212 void initialize( bool bWorkbookFile );
213 /** Finalizes the filter process (sets some needed document properties). */
214 void finalize();
215
216 private:
217 typedef ::std::auto_ptr< SegmentProgressBar > ProgressBarPtr;
218 typedef ::std::auto_ptr< WorkbookSettings > WorkbookSettPtr;
219 typedef ::std::auto_ptr< ViewSettings > ViewSettingsPtr;
220 typedef ::std::auto_ptr< WorksheetBuffer > WorksheetBfrPtr;
221 typedef ::boost::shared_ptr< ThemeBuffer > ThemeBfrRef;
222 typedef ::std::auto_ptr< StylesBuffer > StylesBfrPtr;
223 typedef ::std::auto_ptr< SharedStringsBuffer > SharedStrBfrPtr;
224 typedef ::std::auto_ptr< ExternalLinkBuffer > ExtLinkBfrPtr;
225 typedef ::std::auto_ptr< DefinedNamesBuffer > DefNamesBfrPtr;
226 typedef ::std::auto_ptr< TableBuffer > TableBfrPtr;
227 typedef ::std::auto_ptr< ScenarioBuffer > ScenarioBfrPtr;
228 typedef ::std::auto_ptr< ConnectionsBuffer > ConnectionsBfrPtr;
229 typedef ::std::auto_ptr< PivotCacheBuffer > PivotCacheBfrPtr;
230 typedef ::std::auto_ptr< PivotTableBuffer > PivotTableBfrPtr;
231 typedef ::std::auto_ptr< FormulaParser > FormulaParserPtr;
232 typedef ::std::auto_ptr< UnitConverter > UnitConvPtr;
233 typedef ::std::auto_ptr< AddressConverter > AddressConvPtr;
234 typedef ::std::auto_ptr< ExcelChartConverter > ExcelChartConvPtr;
235 typedef ::std::auto_ptr< PageSettingsConverter > PageSettConvPtr;
236 typedef ::std::auto_ptr< BiffCodecHelper > BiffCodecHelperPtr;
237
238 OUString maCellStyles; /// Style family name for cell styles.
239 OUString maPageStyles; /// Style family name for page styles.
240 OUString maCellStyleServ; /// Service name for a cell style.
241 OUString maPageStyleServ; /// Service name for a page style.
242 Reference< XSpreadsheetDocument > mxDoc; /// Document model.
243 FilterBase& mrBaseFilter; /// Base filter object.
244 ExcelFilterBase& mrExcelBase; /// Base object for registration of this structure.
245 FilterType meFilterType; /// File type of the filter.
246 ProgressBarPtr mxProgressBar; /// The progress bar.
247 StorageRef mxVbaPrjStrg; /// Storage containing the VBA project.
248 sal_Int16 mnCurrSheet; /// Current sheet index in Calc dcument.
249 bool mbWorkbook; /// True = multi-sheet file.
250
251 // buffers
252 WorkbookSettPtr mxWorkbookSettings; /// Global workbook settings.
253 ViewSettingsPtr mxViewSettings; /// Workbook and sheet view settings.
254 WorksheetBfrPtr mxWorksheets; /// Sheet info buffer.
255 ThemeBfrRef mxTheme; /// Formatting theme from theme substream.
256 StylesBfrPtr mxStyles; /// All cell style objects from styles substream.
257 SharedStrBfrPtr mxSharedStrings; /// All strings from shared strings substream.
258 ExtLinkBfrPtr mxExtLinks; /// All external links.
259 DefNamesBfrPtr mxDefNames; /// All defined names.
260 TableBfrPtr mxTables; /// All tables (database ranges).
261 ScenarioBfrPtr mxScenarios; /// All scenarios.
262 ConnectionsBfrPtr mxConnections; /// All external data connections.
263 PivotCacheBfrPtr mxPivotCaches; /// All pivot caches in the document.
264 PivotTableBfrPtr mxPivotTables; /// All pivot tables in the document.
265
266 // converters
267 FormulaParserPtr mxFmlaParser; /// Import formula parser.
268 UnitConvPtr mxUnitConverter; /// General unit converter.
269 AddressConvPtr mxAddrConverter; /// Cell address and cell range address converter.
270 ExcelChartConvPtr mxChartConverter; /// Chart object converter.
271 PageSettConvPtr mxPageSettConverter; /// Page/print settings converter.
272
273 // OOXML/BIFF12 specific
274 XmlFilterBase* mpOoxFilter; /// Base OOXML/BIFF12 filter object.
275
276 // BIFF2-BIFF8 specific
277 BinaryFilterBase* mpBiffFilter; /// Base BIFF2-BIFF8 filter object.
278 BiffCodecHelperPtr mxCodecHelper; /// Encoder/decoder helper.
279 BiffType meBiff; /// BIFF version for BIFF import/export.
280 rtl_TextEncoding meTextEnc; /// BIFF byte string text encoding.
281 bool mbHasCodePage; /// True = CODEPAGE record exists in imported stream.
282 };
283
284 // ----------------------------------------------------------------------------
285
WorkbookGlobals(ExcelFilter & rFilter)286 WorkbookGlobals::WorkbookGlobals( ExcelFilter& rFilter ) :
287 mrBaseFilter( rFilter ),
288 mrExcelBase( rFilter ),
289 meFilterType( FILTER_OOXML ),
290 mpOoxFilter( &rFilter ),
291 mpBiffFilter( 0 ),
292 meBiff( BIFF_UNKNOWN )
293 {
294 // register at the filter, needed for virtual callbacks (even during construction)
295 mrExcelBase.registerWorkbookGlobals( *this );
296 initialize( true );
297 }
298
WorkbookGlobals(ExcelBiffFilter & rFilter,BiffType eBiff)299 WorkbookGlobals::WorkbookGlobals( ExcelBiffFilter& rFilter, BiffType eBiff ) :
300 mrBaseFilter( rFilter ),
301 mrExcelBase( rFilter ),
302 meFilterType( FILTER_BIFF ),
303 mpOoxFilter( 0 ),
304 mpBiffFilter( &rFilter ),
305 meBiff( eBiff )
306 {
307 // register at the filter, needed for virtual callbacks (even during construction)
308 mrExcelBase.registerWorkbookGlobals( *this );
309 initialize( eBiff >= BIFF5 );
310 }
311
~WorkbookGlobals()312 WorkbookGlobals::~WorkbookGlobals()
313 {
314 finalize();
315 mrExcelBase.unregisterWorkbookGlobals();
316 }
317
318 // document model -------------------------------------------------------------
319
getStyleFamily(bool bPageStyles) const320 Reference< XNameContainer > WorkbookGlobals::getStyleFamily( bool bPageStyles ) const
321 {
322 Reference< XNameContainer > xStylesNC;
323 try
324 {
325 Reference< XStyleFamiliesSupplier > xFamiliesSup( mxDoc, UNO_QUERY_THROW );
326 Reference< XNameAccess > xFamiliesNA( xFamiliesSup->getStyleFamilies(), UNO_QUERY_THROW );
327 xStylesNC.set( xFamiliesNA->getByName( bPageStyles ? maPageStyles : maCellStyles ), UNO_QUERY );
328 }
329 catch( Exception& )
330 {
331 }
332 OSL_ENSURE( xStylesNC.is(), "WorkbookGlobals::getStyleFamily - cannot access style family" );
333 return xStylesNC;
334 }
335
getStyleObject(const OUString & rStyleName,bool bPageStyle) const336 Reference< XStyle > WorkbookGlobals::getStyleObject( const OUString& rStyleName, bool bPageStyle ) const
337 {
338 Reference< XStyle > xStyle;
339 try
340 {
341 Reference< XNameContainer > xStylesNC( getStyleFamily( bPageStyle ), UNO_SET_THROW );
342 xStyle.set( xStylesNC->getByName( rStyleName ), UNO_QUERY );
343 }
344 catch( Exception& )
345 {
346 }
347 OSL_ENSURE( xStyle.is(), "WorkbookGlobals::getStyleObject - cannot access style object" );
348 return xStyle;
349 }
350
createNamedRangeObject(OUString & orScope,OUString & orName,sal_Int32 nNameFlags) const351 Reference< XNamedRange2 > WorkbookGlobals::createNamedRangeObject( OUString& orScope, OUString& orName, sal_Int32 nNameFlags ) const
352 {
353 // create the name and insert it into the Calc document
354 Reference< XNamedRange2 > xNamedRange;
355 if( orName.getLength() > 0 ) try
356 {
357 // find an unused name
358 PropertySet aDocProps( mxDoc );
359 Reference< XNamedRanges2 > xNamedRanges( aDocProps.getAnyProperty( PROP_NamedRanges2 ), UNO_QUERY_THROW );
360 Reference< XNameAccess > xNameAccess( xNamedRanges, UNO_QUERY_THROW );
361 orName = ContainerHelper::getUnusedName( xNameAccess, orName, '_' );
362 // create the named range
363 xNamedRanges->addNewByScopeName( orScope, orName, OUString(), CellAddress( 0, 0, 0 ), nNameFlags );
364 xNamedRange.set( xNamedRanges->getByScopeName( orScope, orName ), UNO_QUERY );
365 }
366 catch( Exception& )
367 {
368 }
369 OSL_ENSURE( xNamedRange.is(), "WorkbookGlobals::createNamedRangeObject - cannot create defined name" );
370 return xNamedRange;
371 }
372
createDatabaseRangeObject(OUString & orName,const CellRangeAddress & rRangeAddr) const373 Reference< XDatabaseRange > WorkbookGlobals::createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const
374 {
375 // validate cell range
376 CellRangeAddress aDestRange = rRangeAddr;
377 bool bValidRange = getAddressConverter().validateCellRange( aDestRange, true, true );
378
379 // create database range and insert it into the Calc document
380 Reference< XDatabaseRange > xDatabaseRange;
381 if( bValidRange && (orName.getLength() > 0) ) try
382 {
383 // find an unused name
384 PropertySet aDocProps( mxDoc );
385 Reference< XDatabaseRanges > xDatabaseRanges( aDocProps.getAnyProperty( PROP_DatabaseRanges ), UNO_QUERY_THROW );
386 Reference< XNameAccess > xNameAccess( xDatabaseRanges, UNO_QUERY_THROW );
387 orName = ContainerHelper::getUnusedName( xNameAccess, orName, '_' );
388 // create the database range
389 xDatabaseRanges->addNewByName( orName, aDestRange );
390 xDatabaseRange.set( xDatabaseRanges->getByName( orName ), UNO_QUERY );
391 }
392 catch( Exception& )
393 {
394 }
395 OSL_ENSURE( xDatabaseRange.is(), "WorkbookGlobals::createDatabaseRangeObject - cannot create database range" );
396 return xDatabaseRange;
397 }
398
createStyleObject(OUString & orStyleName,bool bPageStyle) const399 Reference< XStyle > WorkbookGlobals::createStyleObject( OUString& orStyleName, bool bPageStyle ) const
400 {
401 Reference< XStyle > xStyle;
402 try
403 {
404 Reference< XNameContainer > xStylesNC( getStyleFamily( bPageStyle ), UNO_SET_THROW );
405 xStyle.set( mrBaseFilter.getModelFactory()->createInstance( bPageStyle ? maPageStyleServ : maCellStyleServ ), UNO_QUERY_THROW );
406 orStyleName = ContainerHelper::insertByUnusedName( xStylesNC, orStyleName, ' ', Any( xStyle ), false );
407 }
408 catch( Exception& )
409 {
410 }
411 OSL_ENSURE( xStyle.is(), "WorkbookGlobals::createStyleObject - cannot create style" );
412 return xStyle;
413 }
414
415 // BIFF specific --------------------------------------------------------------
416
setTextEncoding(rtl_TextEncoding eTextEnc)417 void WorkbookGlobals::setTextEncoding( rtl_TextEncoding eTextEnc )
418 {
419 if( eTextEnc != RTL_TEXTENCODING_DONTKNOW )
420 meTextEnc = eTextEnc;
421 }
422
setCodePage(sal_uInt16 nCodePage)423 void WorkbookGlobals::setCodePage( sal_uInt16 nCodePage )
424 {
425 setTextEncoding( BiffHelper::calcTextEncodingFromCodePage( nCodePage ) );
426 mbHasCodePage = true;
427 }
428
setAppFontEncoding(rtl_TextEncoding eAppFontEnc)429 void WorkbookGlobals::setAppFontEncoding( rtl_TextEncoding eAppFontEnc )
430 {
431 if( !mbHasCodePage )
432 setTextEncoding( eAppFontEnc );
433 }
434
setIsWorkbookFile()435 void WorkbookGlobals::setIsWorkbookFile()
436 {
437 OSL_ENSURE( meBiff == BIFF4, "WorkbookGlobals::setIsWorkbookFile - invalid call" );
438 mbWorkbook = true;
439 }
440
createBuffersPerSheet(sal_Int16 nSheet)441 void WorkbookGlobals::createBuffersPerSheet( sal_Int16 nSheet )
442 {
443 switch( meBiff )
444 {
445 case BIFF2:
446 case BIFF3:
447 OSL_ENSURE( nSheet == 0, "WorkbookGlobals::createBuffersPerSheet - unexpected sheet index" );
448 mxDefNames->setLocalCalcSheet( nSheet );
449 break;
450
451 case BIFF4:
452 OSL_ENSURE( mbWorkbook || (nSheet == 0), "WorkbookGlobals::createBuffersPerSheet - unexpected sheet index" );
453 // #i11183# sheets in BIFF4W files have own styles and names
454 if( nSheet > 0 )
455 {
456 mxStyles.reset( new StylesBuffer( *this ) );
457 mxDefNames.reset( new DefinedNamesBuffer( *this ) );
458 mxExtLinks.reset( new ExternalLinkBuffer( *this ) );
459 }
460 mxDefNames->setLocalCalcSheet( nSheet );
461 break;
462
463 case BIFF5:
464 // BIFF5 stores external references per sheet
465 if( nSheet > 0 )
466 mxExtLinks.reset( new ExternalLinkBuffer( *this ) );
467 break;
468
469 case BIFF8:
470 break;
471
472 case BIFF_UNKNOWN:
473 break;
474 }
475 }
476
477 // private --------------------------------------------------------------------
478
initialize(bool bWorkbookFile)479 void WorkbookGlobals::initialize( bool bWorkbookFile )
480 {
481 maCellStyles = CREATE_OUSTRING( "CellStyles" );
482 maPageStyles = CREATE_OUSTRING( "PageStyles" );
483 maCellStyleServ = CREATE_OUSTRING( "com.sun.star.style.CellStyle" );
484 maPageStyleServ = CREATE_OUSTRING( "com.sun.star.style.PageStyle" );
485 mnCurrSheet = -1;
486 mbWorkbook = bWorkbookFile;
487 meTextEnc = osl_getThreadTextEncoding();
488 mbHasCodePage = false;
489
490 // the spreadsheet document
491 mxDoc.set( mrBaseFilter.getModel(), UNO_QUERY );
492 OSL_ENSURE( mxDoc.is(), "WorkbookGlobals::initialize - no spreadsheet document" );
493
494 mxWorkbookSettings.reset( new WorkbookSettings( *this ) );
495 mxViewSettings.reset( new ViewSettings( *this ) );
496 mxWorksheets.reset( new WorksheetBuffer( *this ) );
497 mxTheme.reset( new ThemeBuffer( *this ) );
498 mxStyles.reset( new StylesBuffer( *this ) );
499 mxSharedStrings.reset( new SharedStringsBuffer( *this ) );
500 mxExtLinks.reset( new ExternalLinkBuffer( *this ) );
501 mxDefNames.reset( new DefinedNamesBuffer( *this ) );
502 mxTables.reset( new TableBuffer( *this ) );
503 mxScenarios.reset( new ScenarioBuffer( *this ) );
504 mxConnections.reset( new ConnectionsBuffer( *this ) );
505 mxPivotCaches.reset( new PivotCacheBuffer( *this ) );
506 mxPivotTables.reset( new PivotTableBuffer( *this ) );
507
508 mxUnitConverter.reset( new UnitConverter( *this ) );
509 mxAddrConverter.reset( new AddressConverter( *this ) );
510 mxChartConverter.reset( new ExcelChartConverter( *this ) );
511 mxPageSettConverter.reset( new PageSettingsConverter( *this ) );
512
513 // set some document properties needed during import
514 if( mrBaseFilter.isImportFilter() )
515 {
516 PropertySet aPropSet( mxDoc );
517 // enable editing read-only documents (e.g. from read-only files)
518 aPropSet.setProperty( PROP_IsChangeReadOnlyEnabled, true );
519 // #i76026# disable Undo while loading the document
520 aPropSet.setProperty( PROP_IsUndoEnabled, false );
521 // #i79826# disable calculating automatic row height while loading the document
522 aPropSet.setProperty( PROP_IsAdjustHeightEnabled, false );
523 // disable automatic update of linked sheets and DDE links
524 aPropSet.setProperty( PROP_IsExecuteLinkEnabled, false );
525 // #i79890# disable automatic update of defined names
526 Reference< XActionLockable > xLockable( aPropSet.getAnyProperty( PROP_NamedRanges ), UNO_QUERY );
527 if( xLockable.is() )
528 xLockable->addActionLock();
529
530 //! TODO: localize progress bar text
531 mxProgressBar.reset( new SegmentProgressBar( mrBaseFilter.getStatusIndicator(), CREATE_OUSTRING( "Loading..." ) ) );
532 mxFmlaParser.reset( new FormulaParser( *this ) );
533 }
534 else if( mrBaseFilter.isExportFilter() )
535 {
536 //! TODO: localize progress bar text
537 mxProgressBar.reset( new SegmentProgressBar( mrBaseFilter.getStatusIndicator(), CREATE_OUSTRING( "Saving..." ) ) );
538 }
539
540 // filter specific
541 switch( getFilterType() )
542 {
543 case FILTER_BIFF:
544 mxCodecHelper.reset( new BiffCodecHelper( *this ) );
545 break;
546
547 case FILTER_OOXML:
548 break;
549
550 case FILTER_UNKNOWN:
551 break;
552 }
553 }
554
finalize()555 void WorkbookGlobals::finalize()
556 {
557 // set some document properties needed after import
558 if( mrBaseFilter.isImportFilter() )
559 {
560 PropertySet aPropSet( mxDoc );
561 // #i74668# do not insert default sheets
562 aPropSet.setProperty( PROP_IsLoaded, true );
563 // #i79890# enable automatic update of defined names (before IsAdjustHeightEnabled!)
564 Reference< XActionLockable > xLockable( aPropSet.getAnyProperty( PROP_NamedRanges ), UNO_QUERY );
565 if( xLockable.is() )
566 xLockable->removeActionLock();
567 // enable automatic update of linked sheets and DDE links
568 aPropSet.setProperty( PROP_IsExecuteLinkEnabled, true );
569 // #i79826# enable updating automatic row height after loading the document
570 aPropSet.setProperty( PROP_IsAdjustHeightEnabled, true );
571 // #i76026# enable Undo after loading the document
572 aPropSet.setProperty( PROP_IsUndoEnabled, true );
573 // disable editing read-only documents (e.g. from read-only files)
574 aPropSet.setProperty( PROP_IsChangeReadOnlyEnabled, false );
575 // #111099# open forms in alive mode (has no effect, if no controls in document)
576 aPropSet.setProperty( PROP_ApplyFormDesignMode, false );
577 }
578 }
579
580 // ============================================================================
581
~WorkbookHelper()582 WorkbookHelper::~WorkbookHelper()
583 {
584 }
585
constructGlobals(ExcelFilter & rFilter)586 /*static*/ WorkbookGlobalsRef WorkbookHelper::constructGlobals( ExcelFilter& rFilter )
587 {
588 WorkbookGlobalsRef xBookGlob( new WorkbookGlobals( rFilter ) );
589 if( !xBookGlob->isValid() )
590 xBookGlob.reset();
591 return xBookGlob;
592 }
593
constructGlobals(ExcelBiffFilter & rFilter,BiffType eBiff)594 /*static*/ WorkbookGlobalsRef WorkbookHelper::constructGlobals( ExcelBiffFilter& rFilter, BiffType eBiff )
595 {
596 WorkbookGlobalsRef xBookGlob( new WorkbookGlobals( rFilter, eBiff ) );
597 if( !xBookGlob->isValid() )
598 xBookGlob.reset();
599 return xBookGlob;
600 }
601
602 // filter ---------------------------------------------------------------------
603
getBaseFilter() const604 FilterBase& WorkbookHelper::getBaseFilter() const
605 {
606 return mrBookGlob.getBaseFilter();
607 }
608
getFilterType() const609 FilterType WorkbookHelper::getFilterType() const
610 {
611 return mrBookGlob.getFilterType();
612 }
613
getProgressBar() const614 SegmentProgressBar& WorkbookHelper::getProgressBar() const
615 {
616 return mrBookGlob.getProgressBar();
617 }
618
isWorkbookFile() const619 bool WorkbookHelper::isWorkbookFile() const
620 {
621 return mrBookGlob.isWorkbookFile();
622 }
623
getCurrentSheetIndex() const624 sal_Int16 WorkbookHelper::getCurrentSheetIndex() const
625 {
626 return mrBookGlob.getCurrentSheetIndex();
627 }
628
setVbaProjectStorage(const StorageRef & rxVbaPrjStrg)629 void WorkbookHelper::setVbaProjectStorage( const StorageRef& rxVbaPrjStrg )
630 {
631 mrBookGlob.setVbaProjectStorage( rxVbaPrjStrg );
632 }
633
setCurrentSheetIndex(sal_Int16 nSheet)634 void WorkbookHelper::setCurrentSheetIndex( sal_Int16 nSheet )
635 {
636 mrBookGlob.setCurrentSheetIndex( nSheet );
637 }
638
finalizeWorkbookImport()639 void WorkbookHelper::finalizeWorkbookImport()
640 {
641 // workbook settings, document and sheet view settings
642 mrBookGlob.getWorkbookSettings().finalizeImport();
643 mrBookGlob.getViewSettings().finalizeImport();
644
645 /* Insert all pivot tables. Must be done after loading all sheets, because
646 data pilots expect existing source data on creation. */
647 mrBookGlob.getPivotTables().finalizeImport();
648
649 /* Insert scenarios after all sheet processing is done, because new hidden
650 sheets are created for scenarios which would confuse code that relies
651 on certain sheet indexes. Must be done after pivot tables too. */
652 mrBookGlob.getScenarios().finalizeImport();
653
654 /* Set 'Default' page style to automatic page numbering (default is manual
655 number 1). Otherwise hidden sheets (e.g. for scenarios) which have
656 'Default' page style will break automatic page numbering for following
657 sheets. Automatic numbering is set by passing the value 0. */
658 PropertySet aDefPageStyle( getStyleObject( CREATE_OUSTRING( "Default" ), true ) );
659 aDefPageStyle.setProperty< sal_Int16 >( PROP_FirstPageNumber, 0 );
660
661 /* Import the VBA project (after finalizing workbook settings which
662 contains the workbook code name). */
663 StorageRef xVbaPrjStrg = mrBookGlob.getVbaProjectStorage();
664 if( xVbaPrjStrg.get() && xVbaPrjStrg->isStorage() )
665 getBaseFilter().getVbaProject().importVbaProject( *xVbaPrjStrg, getBaseFilter().getGraphicHelper() );
666 }
667
668 // document model -------------------------------------------------------------
669
getDocument() const670 Reference< XSpreadsheetDocument > WorkbookHelper::getDocument() const
671 {
672 return mrBookGlob.getDocument();
673 }
674
getSheetFromDoc(sal_Int16 nSheet) const675 Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( sal_Int16 nSheet ) const
676 {
677 Reference< XSpreadsheet > xSheet;
678 try
679 {
680 Reference< XIndexAccess > xSheetsIA( getDocument()->getSheets(), UNO_QUERY_THROW );
681 xSheet.set( xSheetsIA->getByIndex( nSheet ), UNO_QUERY_THROW );
682 }
683 catch( Exception& )
684 {
685 }
686 return xSheet;
687 }
688
getSheetFromDoc(const OUString & rSheet) const689 Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( const OUString& rSheet ) const
690 {
691 Reference< XSpreadsheet > xSheet;
692 try
693 {
694 Reference< XNameAccess > xSheetsNA( getDocument()->getSheets(), UNO_QUERY_THROW );
695 xSheet.set( xSheetsNA->getByName( rSheet ), UNO_QUERY );
696 }
697 catch( Exception& )
698 {
699 }
700 return xSheet;
701 }
702
getCellFromDoc(const CellAddress & rAddress) const703 Reference< XCell > WorkbookHelper::getCellFromDoc( const CellAddress& rAddress ) const
704 {
705 Reference< XCell > xCell;
706 try
707 {
708 Reference< XSpreadsheet > xSheet( getSheetFromDoc( rAddress.Sheet ), UNO_SET_THROW );
709 xCell = xSheet->getCellByPosition( rAddress.Column, rAddress.Row );
710 }
711 catch( Exception& )
712 {
713 }
714 return xCell;
715 }
716
getCellRangeFromDoc(const CellRangeAddress & rRange) const717 Reference< XCellRange > WorkbookHelper::getCellRangeFromDoc( const CellRangeAddress& rRange ) const
718 {
719 Reference< XCellRange > xRange;
720 try
721 {
722 Reference< XSpreadsheet > xSheet( getSheetFromDoc( rRange.Sheet ), UNO_SET_THROW );
723 xRange = xSheet->getCellRangeByPosition( rRange.StartColumn, rRange.StartRow, rRange.EndColumn, rRange.EndRow );
724 }
725 catch( Exception& )
726 {
727 }
728 return xRange;
729 }
730
getStyleFamily(bool bPageStyles) const731 Reference< XNameContainer > WorkbookHelper::getStyleFamily( bool bPageStyles ) const
732 {
733 return mrBookGlob.getStyleFamily( bPageStyles );
734 }
735
getStyleObject(const OUString & rStyleName,bool bPageStyle) const736 Reference< XStyle > WorkbookHelper::getStyleObject( const OUString& rStyleName, bool bPageStyle ) const
737 {
738 return mrBookGlob.getStyleObject( rStyleName, bPageStyle );
739 }
740
createNamedRangeObject(OUString & orName,sal_Int32 nSheetId,sal_Int32 nNameFlags) const741 Reference< XNamedRange2 > WorkbookHelper::createNamedRangeObject( OUString& orName, sal_Int32 nSheetId, sal_Int32 nNameFlags ) const
742 {
743 OUString orScope = nSheetId >= 0? getWorksheets().getCalcSheetName(nSheetId) : OUString();
744 return mrBookGlob.createNamedRangeObject( orScope, orName, nNameFlags );
745 }
746
createDatabaseRangeObject(OUString & orName,const CellRangeAddress & rRangeAddr) const747 Reference< XDatabaseRange > WorkbookHelper::createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const
748 {
749 return mrBookGlob.createDatabaseRangeObject( orName, rRangeAddr );
750 }
751
createStyleObject(OUString & orStyleName,bool bPageStyle) const752 Reference< XStyle > WorkbookHelper::createStyleObject( OUString& orStyleName, bool bPageStyle ) const
753 {
754 return mrBookGlob.createStyleObject( orStyleName, bPageStyle );
755 }
756
757 // buffers --------------------------------------------------------------------
758
getWorkbookSettings() const759 WorkbookSettings& WorkbookHelper::getWorkbookSettings() const
760 {
761 return mrBookGlob.getWorkbookSettings();
762 }
763
getViewSettings() const764 ViewSettings& WorkbookHelper::getViewSettings() const
765 {
766 return mrBookGlob.getViewSettings();
767 }
768
getWorksheets() const769 WorksheetBuffer& WorkbookHelper::getWorksheets() const
770 {
771 return mrBookGlob.getWorksheets();
772 }
773
getTheme() const774 ThemeBuffer& WorkbookHelper::getTheme() const
775 {
776 return mrBookGlob.getTheme();
777 }
778
getStyles() const779 StylesBuffer& WorkbookHelper::getStyles() const
780 {
781 return mrBookGlob.getStyles();
782 }
783
getSharedStrings() const784 SharedStringsBuffer& WorkbookHelper::getSharedStrings() const
785 {
786 return mrBookGlob.getSharedStrings();
787 }
788
getExternalLinks() const789 ExternalLinkBuffer& WorkbookHelper::getExternalLinks() const
790 {
791 return mrBookGlob.getExternalLinks();
792 }
793
getDefinedNames() const794 DefinedNamesBuffer& WorkbookHelper::getDefinedNames() const
795 {
796 return mrBookGlob.getDefinedNames();
797 }
798
getTables() const799 TableBuffer& WorkbookHelper::getTables() const
800 {
801 return mrBookGlob.getTables();
802 }
803
getScenarios() const804 ScenarioBuffer& WorkbookHelper::getScenarios() const
805 {
806 return mrBookGlob.getScenarios();
807 }
808
getConnections() const809 ConnectionsBuffer& WorkbookHelper::getConnections() const
810 {
811 return mrBookGlob.getConnections();
812 }
813
getPivotCaches() const814 PivotCacheBuffer& WorkbookHelper::getPivotCaches() const
815 {
816 return mrBookGlob.getPivotCaches();
817 }
818
getPivotTables() const819 PivotTableBuffer& WorkbookHelper::getPivotTables() const
820 {
821 return mrBookGlob.getPivotTables();
822 }
823
824 // converters -----------------------------------------------------------------
825
getFormulaParser() const826 FormulaParser& WorkbookHelper::getFormulaParser() const
827 {
828 return mrBookGlob.getFormulaParser();
829 }
830
getUnitConverter() const831 UnitConverter& WorkbookHelper::getUnitConverter() const
832 {
833 return mrBookGlob.getUnitConverter();
834 }
835
getAddressConverter() const836 AddressConverter& WorkbookHelper::getAddressConverter() const
837 {
838 return mrBookGlob.getAddressConverter();
839 }
840
getChartConverter() const841 ExcelChartConverter& WorkbookHelper::getChartConverter() const
842 {
843 return mrBookGlob.getChartConverter();
844 }
845
getPageSettingsConverter() const846 PageSettingsConverter& WorkbookHelper::getPageSettingsConverter() const
847 {
848 return mrBookGlob.getPageSettingsConverter();
849 }
850
851 // OOXML/BIFF12 specific ------------------------------------------------------
852
getOoxFilter() const853 XmlFilterBase& WorkbookHelper::getOoxFilter() const
854 {
855 OSL_ENSURE( mrBookGlob.getFilterType() == FILTER_OOXML, "WorkbookHelper::getOoxFilter - invalid call" );
856 return mrBookGlob.getOoxFilter();
857 }
858
importOoxFragment(const::rtl::Reference<FragmentHandler> & rxHandler)859 bool WorkbookHelper::importOoxFragment( const ::rtl::Reference< FragmentHandler >& rxHandler )
860 {
861 return getOoxFilter().importFragment( rxHandler );
862 }
863
864 // BIFF specific --------------------------------------------------------------
865
getBiffFilter() const866 BinaryFilterBase& WorkbookHelper::getBiffFilter() const
867 {
868 OSL_ENSURE( mrBookGlob.getFilterType() == FILTER_BIFF, "WorkbookHelper::getBiffFilter - invalid call" );
869 return mrBookGlob.getBiffFilter();
870 }
871
getBiff() const872 BiffType WorkbookHelper::getBiff() const
873 {
874 return mrBookGlob.getBiff();
875 }
876
getTextEncoding() const877 rtl_TextEncoding WorkbookHelper::getTextEncoding() const
878 {
879 return mrBookGlob.getTextEncoding();
880 }
881
setTextEncoding(rtl_TextEncoding eTextEnc)882 void WorkbookHelper::setTextEncoding( rtl_TextEncoding eTextEnc )
883 {
884 mrBookGlob.setTextEncoding( eTextEnc );
885 }
886
setCodePage(sal_uInt16 nCodePage)887 void WorkbookHelper::setCodePage( sal_uInt16 nCodePage )
888 {
889 mrBookGlob.setCodePage( nCodePage );
890 }
891
setAppFontEncoding(rtl_TextEncoding eAppFontEnc)892 void WorkbookHelper::setAppFontEncoding( rtl_TextEncoding eAppFontEnc )
893 {
894 mrBookGlob.setAppFontEncoding( eAppFontEnc );
895 }
896
setIsWorkbookFile()897 void WorkbookHelper::setIsWorkbookFile()
898 {
899 mrBookGlob.setIsWorkbookFile();
900 }
901
createBuffersPerSheet(sal_Int16 nSheet)902 void WorkbookHelper::createBuffersPerSheet( sal_Int16 nSheet )
903 {
904 mrBookGlob.createBuffersPerSheet( nSheet );
905 }
906
getCodecHelper() const907 BiffCodecHelper& WorkbookHelper::getCodecHelper() const
908 {
909 return mrBookGlob.getCodecHelper();
910 }
911
912 // ============================================================================
913
914 } // namespace xls
915 } // namespace oox
916