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