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