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 1446 : 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 1446 : 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 22 : inline bool isValid() const { return mxDoc.is(); }
115 :
116 : // filter -----------------------------------------------------------------
117 :
118 : /** Returns the base filter object (base class of all filters). */
119 1058 : inline FilterBase& getBaseFilter() const { return mrBaseFilter; }
120 : /** Returns the filter progress bar. */
121 166 : inline SegmentProgressBar& getProgressBar() const { return *mxProgressBar; }
122 : /** Returns the file type of the current filter. */
123 732 : 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 22 : 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 100 : inline void setCurrentSheetIndex( sal_Int16 nSheet ) { mnCurrSheet = nSheet; }
135 :
136 : // document model ---------------------------------------------------------
137 :
138 2702 : inline ScDocument& getScDocument() const
139 : {
140 2702 : if ( !mpDoc )
141 : {
142 22 : if ( mxDoc.get() )
143 : {
144 22 : ScModelObj* pModel = dynamic_cast< ScModelObj* >( mxDoc.get() );
145 22 : ScDocShell* pDocShell = NULL;
146 22 : if ( pModel )
147 22 : pDocShell = (ScDocShell*)pModel->GetEmbeddedObject();
148 22 : if ( pDocShell )
149 22 : mpDoc = pDocShell->GetDocument();
150 : }
151 : }
152 2702 : if ( !mpDoc )
153 0 : throw RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Workbookhelper::getScDocument(): Failed to access ScDocument from model" ) ), Reference< XInterface >() );
154 2702 : return *mpDoc;
155 : }
156 :
157 : /** Returns a reference to the source/target spreadsheet document model. */
158 558 : 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 138 : inline FormulaBuffer& getFormulaBuffer() const { return *mxFormulaBuffer; }
177 : /** Returns the global workbook settings object. */
178 88 : inline WorkbookSettings& getWorkbookSettings() const { return *mxWorkbookSettings; }
179 : /** Returns the workbook and sheet view settings object. */
180 172 : inline ViewSettings& getViewSettings() const { return *mxViewSettings; }
181 : /** Returns the worksheet buffer containing sheet names and properties. */
182 154 : inline WorksheetBuffer& getWorksheets() const { return *mxWorksheets; }
183 : /** Returns the office theme object read from the theme substorage. */
184 690 : inline ThemeBuffer& getTheme() const { return *mxTheme; }
185 : /** Returns all cell formatting objects read from the styles substream. */
186 3458 : inline StylesBuffer& getStyles() const { return *mxStyles; }
187 : /** Returns the shared strings read from the shared strings substream. */
188 318 : inline SharedStringsBuffer& getSharedStrings() const { return *mxSharedStrings; }
189 : /** Returns the external links read from the external links substream. */
190 14 : inline ExternalLinkBuffer& getExternalLinks() const { return *mxExtLinks; }
191 : /** Returns the defined names read from the workbook globals. */
192 94 : inline DefinedNamesBuffer& getDefinedNames() const { return *mxDefNames; }
193 : /** Returns the tables collection (equivalent to Calc's database ranges). */
194 22 : inline TableBuffer& getTables() const { return *mxTables; }
195 : /** Returns the scenarios collection. */
196 22 : 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 22 : inline PivotTableBuffer& getPivotTables() { return *mxPivotTables; }
203 :
204 : // converters -------------------------------------------------------------
205 :
206 : /** Returns the import formula parser. */
207 182 : inline FormulaParser& getFormulaParser() const { return *mxFmlaParser; }
208 : /** Returns the measurement unit converter. */
209 938 : inline UnitConverter& getUnitConverter() const { return *mxUnitConverter; }
210 : /** Returns the converter for string to cell address/range conversion. */
211 990 : 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 50 : inline PageSettingsConverter& getPageSettingsConverter() const { return *mxPageSettConverter; }
216 :
217 : // OOXML/BIFF12 specific --------------------------------------------------
218 :
219 : /** Returns the base OOXML/BIFF12 filter object. */
220 324 : inline XmlFilterBase& getOoxFilter() const { return *mpOoxFilter; }
221 :
222 : // BIFF2-BIFF8 specific ---------------------------------------------------
223 :
224 : /** Returns the BIFF type in binary filter. */
225 22 : 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 22 : WorkbookGlobals::WorkbookGlobals( ExcelFilter& rFilter ) :
310 : mrBaseFilter( rFilter ),
311 : mrExcelBase( rFilter ),
312 : meFilterType( FILTER_OOXML ),
313 : mpOoxFilter( &rFilter ),
314 : meBiff( BIFF_UNKNOWN ),
315 22 : mpDoc( NULL )
316 : {
317 : // register at the filter, needed for virtual callbacks (even during construction)
318 22 : mrExcelBase.registerWorkbookGlobals( *this );
319 22 : initialize( true );
320 22 : }
321 :
322 44 : WorkbookGlobals::~WorkbookGlobals()
323 : {
324 22 : finalize();
325 22 : mrExcelBase.unregisterWorkbookGlobals();
326 22 : }
327 :
328 : // document model -------------------------------------------------------------
329 :
330 188 : Reference< XNameContainer > WorkbookGlobals::getStyleFamily( bool bPageStyles ) const
331 : {
332 188 : Reference< XNameContainer > xStylesNC;
333 : try
334 : {
335 188 : Reference< XStyleFamiliesSupplier > xFamiliesSup( mxDoc, UNO_QUERY_THROW );
336 188 : Reference< XNameAccess > xFamiliesNA( xFamiliesSup->getStyleFamilies(), UNO_QUERY_THROW );
337 188 : 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 188 : return xStylesNC;
344 : }
345 :
346 22 : Reference< XStyle > WorkbookGlobals::getStyleObject( const OUString& rStyleName, bool bPageStyle ) const
347 : {
348 22 : Reference< XStyle > xStyle;
349 : try
350 : {
351 22 : Reference< XNameContainer > xStylesNC( getStyleFamily( bPageStyle ), UNO_SET_THROW );
352 22 : 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 22 : return xStyle;
359 : }
360 24 : ScRangeData* lcl_addNewByNameAndTokens( ScDocument& rDoc, ScRangeName* pNames, const OUString& rName, const Sequence<FormulaToken>& rTokens, sal_Int16 nIndex, sal_Int32 nUnoType )
361 : {
362 24 : bool bDone = false;
363 24 : sal_uInt16 nNewType = RT_NAME;
364 24 : if ( nUnoType & NamedRangeFlag::FILTER_CRITERIA ) nNewType |= RT_CRITERIA;
365 24 : if ( nUnoType & NamedRangeFlag::PRINT_AREA ) nNewType |= RT_PRINTAREA;
366 24 : if ( nUnoType & NamedRangeFlag::COLUMN_HEADER ) nNewType |= RT_COLHEADER;
367 24 : if ( nUnoType & NamedRangeFlag::ROW_HEADER ) nNewType |= RT_ROWHEADER;
368 24 : ScTokenArray aTokenArray;
369 24 : (void)ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, rTokens );
370 24 : ScRangeData* pNew = new ScRangeData( &rDoc, rName, aTokenArray, ScAddress(), nNewType );
371 24 : pNew->GuessPosition();
372 24 : if ( nIndex )
373 22 : pNew->SetIndex( nIndex );
374 24 : if ( pNames->insert(pNew) )
375 24 : bDone = true;
376 24 : if (!bDone)
377 0 : throw RuntimeException();
378 24 : return pNew;
379 : }
380 :
381 : namespace {
382 :
383 24 : rtl::OUString findUnusedName( const ScRangeName* pRangeName, const rtl::OUString& rSuggestedName )
384 : {
385 24 : rtl::OUString aNewName = rSuggestedName;
386 24 : sal_Int32 nIndex = 0;
387 48 : while(pRangeName->findByUpperName(ScGlobal::pCharClass->uppercase(aNewName)))
388 0 : aNewName = rtl::OUStringBuffer(rSuggestedName).append( '_' ).append( nIndex++ ).makeStringAndClear();
389 :
390 24 : return aNewName;
391 : }
392 :
393 : }
394 :
395 14 : 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 14 : ScRangeData* pScRangeData = NULL;
399 14 : if( !orName.isEmpty() )
400 : {
401 14 : ScDocument& rDoc = getScDocument();
402 14 : ScRangeName* pNames = rDoc.GetRangeName();
403 : // find an unused name
404 14 : orName = findUnusedName( pNames, orName );
405 : // create the named range
406 14 : pScRangeData = lcl_addNewByNameAndTokens( rDoc, pNames, orName, rTokens, nIndex, nNameFlags );
407 : }
408 14 : return pScRangeData;
409 : }
410 :
411 :
412 10 : 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 10 : ScRangeData* pScRangeData = NULL;
416 10 : if( !orName.isEmpty() )
417 : {
418 10 : ScDocument& rDoc = getScDocument();
419 10 : ScRangeName* pNames = rDoc.GetRangeName( nTab );
420 : // find an unused name
421 10 : orName = findUnusedName( pNames, orName );
422 : // create the named range
423 10 : pScRangeData = lcl_addNewByNameAndTokens( rDoc, pNames, orName, rTokens, nIndex, nNameFlags );
424 : }
425 10 : 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 2 : Reference< XDatabaseRange > WorkbookGlobals::createUnnamedDatabaseRangeObject( const CellRangeAddress& rRangeAddr ) const
455 : {
456 : // validate cell range
457 2 : CellRangeAddress aDestRange = rRangeAddr;
458 2 : bool bValidRange = getAddressConverter().validateCellRange( aDestRange, true, true );
459 :
460 : // create database range and insert it into the Calc document
461 2 : Reference< XDatabaseRange > xDatabaseRange;
462 2 : if( bValidRange ) try
463 : {
464 2 : ScDocument& rDoc = getScDocument();
465 2 : if( rDoc.GetTableCount() <= aDestRange.Sheet )
466 0 : throw ::com::sun::star::lang::IndexOutOfBoundsException();
467 2 : ScRange aScRange;
468 2 : ScUnoConversion::FillScRange(aScRange, aDestRange);
469 2 : ScDBData* pNewDBData = new ScDBData( STR_DB_LOCAL_NONAME, aScRange.aStart.Tab(),
470 2 : aScRange.aStart.Col(), aScRange.aStart.Row(),
471 6 : aScRange.aEnd.Col(), aScRange.aEnd.Row() );
472 2 : rDoc.SetAnonymousDBData( aScRange.aStart.Tab() , pNewDBData );
473 2 : ScDocShell* pDocSh = static_cast< ScDocShell* >(rDoc.GetDocumentShell());
474 2 : 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 2 : return xDatabaseRange;
481 : }
482 :
483 122 : Reference< XStyle > WorkbookGlobals::createStyleObject( OUString& orStyleName, bool bPageStyle ) const
484 : {
485 122 : Reference< XStyle > xStyle;
486 : try
487 : {
488 122 : Reference< XNameContainer > xStylesNC( getStyleFamily( bPageStyle ), UNO_SET_THROW );
489 122 : xStyle.set( mrBaseFilter.getModelFactory()->createInstance( bPageStyle ? maPageStyleServ : maCellStyleServ ), UNO_QUERY_THROW );
490 122 : 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 122 : return xStyle;
497 : }
498 :
499 : // BIFF specific --------------------------------------------------------------
500 :
501 : // private --------------------------------------------------------------------
502 :
503 22 : void WorkbookGlobals::initialize( bool bWorkbookFile )
504 : {
505 22 : maCellStyles = "CellStyles";
506 22 : maPageStyles = "PageStyles";
507 22 : maCellStyleServ = "com.sun.star.style.CellStyle";
508 22 : maPageStyleServ = "com.sun.star.style.PageStyle";
509 22 : mnCurrSheet = -1;
510 22 : mbWorkbook = bWorkbookFile;
511 22 : meTextEnc = osl_getThreadTextEncoding();
512 22 : mbHasCodePage = false;
513 :
514 : // the spreadsheet document
515 22 : mxDoc.set( mrBaseFilter.getModel(), UNO_QUERY );
516 : OSL_ENSURE( mxDoc.is(), "WorkbookGlobals::initialize - no spreadsheet document" );
517 :
518 22 : mxFormulaBuffer.reset( new FormulaBuffer( *this ) );
519 22 : mxWorkbookSettings.reset( new WorkbookSettings( *this ) );
520 22 : mxViewSettings.reset( new ViewSettings( *this ) );
521 22 : mxWorksheets.reset( new WorksheetBuffer( *this ) );
522 22 : mxTheme.reset( new ThemeBuffer( *this ) );
523 22 : mxStyles.reset( new StylesBuffer( *this ) );
524 22 : mxSharedStrings.reset( new SharedStringsBuffer( *this ) );
525 22 : mxExtLinks.reset( new ExternalLinkBuffer( *this ) );
526 22 : mxDefNames.reset( new DefinedNamesBuffer( *this ) );
527 22 : mxTables.reset( new TableBuffer( *this ) );
528 22 : mxScenarios.reset( new ScenarioBuffer( *this ) );
529 22 : mxConnections.reset( new ConnectionsBuffer( *this ) );
530 22 : mxPivotCaches.reset( new PivotCacheBuffer( *this ) );
531 22 : mxPivotTables.reset( new PivotTableBuffer( *this ) );
532 :
533 22 : mxUnitConverter.reset( new UnitConverter( *this ) );
534 22 : mxAddrConverter.reset( new AddressConverter( *this ) );
535 22 : mxChartConverter.reset( new ExcelChartConverter( *this ) );
536 22 : mxPageSettConverter.reset( new PageSettingsConverter( *this ) );
537 :
538 : // set some document properties needed during import
539 22 : if( mrBaseFilter.isImportFilter() )
540 : {
541 22 : PropertySet aPropSet( mxDoc );
542 : // enable editing read-only documents (e.g. from read-only files)
543 22 : aPropSet.setProperty( PROP_IsChangeReadOnlyEnabled, true );
544 : // #i76026# disable Undo while loading the document
545 22 : aPropSet.setProperty( PROP_IsUndoEnabled, false );
546 : // #i79826# disable calculating automatic row height while loading the document
547 22 : aPropSet.setProperty( PROP_IsAdjustHeightEnabled, false );
548 : // disable automatic update of linked sheets and DDE links
549 22 : aPropSet.setProperty( PROP_IsExecuteLinkEnabled, false );
550 : // #i79890# disable automatic update of defined names
551 22 : Reference< XActionLockable > xLockable( aPropSet.getAnyProperty( PROP_NamedRanges ), UNO_QUERY );
552 22 : if( xLockable.is() )
553 22 : xLockable->addActionLock();
554 :
555 : //! TODO: localize progress bar text
556 22 : mxProgressBar.reset( new SegmentProgressBar( mrBaseFilter.getStatusIndicator(), "Loading..." ) );
557 22 : mxFmlaParser.reset( new FormulaParser( *this ) );
558 :
559 : //prevent unnecessary broadcasts and "half way listeners" as
560 : //is done in ScDocShell::BeforeXMLLoading() for ods
561 22 : 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 22 : switch( getFilterType() )
570 : {
571 : case FILTER_BIFF:
572 0 : mxCodecHelper.reset( new BiffCodecHelper( *this ) );
573 0 : break;
574 :
575 : case FILTER_OOXML:
576 22 : break;
577 :
578 : case FILTER_UNKNOWN:
579 0 : break;
580 : }
581 22 : }
582 :
583 22 : void WorkbookGlobals::finalize()
584 : {
585 : // set some document properties needed after import
586 22 : if( mrBaseFilter.isImportFilter() )
587 : {
588 22 : PropertySet aPropSet( mxDoc );
589 : // #i74668# do not insert default sheets
590 22 : aPropSet.setProperty( PROP_IsLoaded, true );
591 : // #i79890# enable automatic update of defined names (before IsAdjustHeightEnabled!)
592 22 : Reference< XActionLockable > xLockable( aPropSet.getAnyProperty( PROP_NamedRanges ), UNO_QUERY );
593 22 : if( xLockable.is() )
594 22 : xLockable->removeActionLock();
595 : // enable automatic update of linked sheets and DDE links
596 22 : aPropSet.setProperty( PROP_IsExecuteLinkEnabled, true );
597 : // #i79826# enable updating automatic row height after loading the document
598 22 : aPropSet.setProperty( PROP_IsAdjustHeightEnabled, true );
599 :
600 : // Insert all pivot tables. Must be done after loading all sheets and
601 : // formulas, because data pilots expect existing source data on
602 : // creation.
603 22 : getPivotTables().finalizeImport();
604 :
605 : // #i76026# enable Undo after loading the document
606 22 : aPropSet.setProperty( PROP_IsUndoEnabled, true );
607 : // disable editing read-only documents (e.g. from read-only files)
608 22 : aPropSet.setProperty( PROP_IsChangeReadOnlyEnabled, false );
609 : // #111099# open forms in alive mode (has no effect, if no controls in document)
610 22 : aPropSet.setProperty( PROP_ApplyFormDesignMode, false );
611 :
612 : //stop preventing establishment of listeners as is done in
613 : //ScDocShell::AfterXMLLoading() for ods
614 22 : getScDocument().SetInsertingFromOtherDoc(false);
615 : }
616 22 : }
617 :
618 : // ============================================================================
619 :
620 7520 : WorkbookHelper::~WorkbookHelper()
621 : {
622 7520 : }
623 :
624 22 : /*static*/ WorkbookGlobalsRef WorkbookHelper::constructGlobals( ExcelFilter& rFilter )
625 : {
626 22 : WorkbookGlobalsRef xBookGlob( new WorkbookGlobals( rFilter ) );
627 22 : if( !xBookGlob->isValid() )
628 0 : xBookGlob.reset();
629 22 : return xBookGlob;
630 : }
631 :
632 : // filter ---------------------------------------------------------------------
633 :
634 1058 : FilterBase& WorkbookHelper::getBaseFilter() const
635 : {
636 1058 : return mrBookGlob.getBaseFilter();
637 : }
638 :
639 710 : FilterType WorkbookHelper::getFilterType() const
640 : {
641 710 : return mrBookGlob.getFilterType();
642 : }
643 :
644 166 : SegmentProgressBar& WorkbookHelper::getProgressBar() const
645 : {
646 166 : return mrBookGlob.getProgressBar();
647 : }
648 :
649 0 : bool WorkbookHelper::isWorkbookFile() const
650 : {
651 0 : return mrBookGlob.isWorkbookFile();
652 : }
653 :
654 0 : sal_Int16 WorkbookHelper::getCurrentSheetIndex() const
655 : {
656 0 : return mrBookGlob.getCurrentSheetIndex();
657 : }
658 :
659 0 : void WorkbookHelper::setVbaProjectStorage( const StorageRef& rxVbaPrjStrg )
660 : {
661 0 : mrBookGlob.setVbaProjectStorage( rxVbaPrjStrg );
662 0 : }
663 :
664 100 : void WorkbookHelper::setCurrentSheetIndex( sal_Int16 nSheet )
665 : {
666 100 : mrBookGlob.setCurrentSheetIndex( nSheet );
667 100 : }
668 :
669 22 : void WorkbookHelper::finalizeWorkbookImport()
670 : {
671 : // workbook settings, document and sheet view settings
672 22 : mrBookGlob.getWorkbookSettings().finalizeImport();
673 22 : mrBookGlob.getViewSettings().finalizeImport();
674 :
675 : // need to import formulas before scenarios
676 22 : mrBookGlob.getFormulaBuffer().finalizeImport();
677 : /* Insert scenarios after all sheet processing is done, because new hidden
678 : sheets are created for scenarios which would confuse code that relies
679 : on certain sheet indexes. Must be done after pivot tables too. */
680 22 : mrBookGlob.getScenarios().finalizeImport();
681 :
682 : /* Set 'Default' page style to automatic page numbering (default is manual
683 : number 1). Otherwise hidden sheets (e.g. for scenarios) which have
684 : 'Default' page style will break automatic page numbering for following
685 : sheets. Automatic numbering is set by passing the value 0. */
686 22 : PropertySet aDefPageStyle( getStyleObject( "Default", true ) );
687 22 : aDefPageStyle.setProperty< sal_Int16 >( PROP_FirstPageNumber, 0 );
688 :
689 : /* Import the VBA project (after finalizing workbook settings which
690 : contains the workbook code name). */
691 22 : StorageRef xVbaPrjStrg = mrBookGlob.getVbaProjectStorage();
692 22 : if( xVbaPrjStrg.get() && xVbaPrjStrg->isStorage() )
693 0 : getBaseFilter().getVbaProject().importVbaProject( *xVbaPrjStrg, getBaseFilter().getGraphicHelper() );
694 22 : }
695 :
696 : // document model -------------------------------------------------------------
697 :
698 2632 : ScDocument& WorkbookHelper::getScDocument() const
699 : {
700 2632 : return mrBookGlob.getScDocument();
701 : }
702 :
703 558 : Reference< XSpreadsheetDocument > WorkbookHelper::getDocument() const
704 : {
705 558 : return mrBookGlob.getDocument();
706 : }
707 :
708 122 : Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( sal_Int16 nSheet ) const
709 : {
710 122 : Reference< XSpreadsheet > xSheet;
711 : try
712 : {
713 122 : Reference< XIndexAccess > xSheetsIA( getDocument()->getSheets(), UNO_QUERY_THROW );
714 122 : xSheet.set( xSheetsIA->getByIndex( nSheet ), UNO_QUERY_THROW );
715 : }
716 0 : catch( Exception& )
717 : {
718 : }
719 122 : return xSheet;
720 : }
721 :
722 0 : Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( const OUString& rSheet ) const
723 : {
724 0 : Reference< XSpreadsheet > xSheet;
725 : try
726 : {
727 0 : Reference< XNameAccess > xSheetsNA( getDocument()->getSheets(), UNO_QUERY_THROW );
728 0 : xSheet.set( xSheetsNA->getByName( rSheet ), UNO_QUERY );
729 : }
730 0 : catch( Exception& )
731 : {
732 : }
733 0 : return xSheet;
734 : }
735 :
736 22 : Reference< XCellRange > WorkbookHelper::getCellRangeFromDoc( const CellRangeAddress& rRange ) const
737 : {
738 22 : Reference< XCellRange > xRange;
739 : try
740 : {
741 22 : Reference< XSpreadsheet > xSheet( getSheetFromDoc( rRange.Sheet ), UNO_SET_THROW );
742 22 : xRange = xSheet->getCellRangeByPosition( rRange.StartColumn, rRange.StartRow, rRange.EndColumn, rRange.EndRow );
743 : }
744 0 : catch( Exception& )
745 : {
746 : }
747 22 : return xRange;
748 : }
749 :
750 44 : Reference< XNameContainer > WorkbookHelper::getStyleFamily( bool bPageStyles ) const
751 : {
752 44 : return mrBookGlob.getStyleFamily( bPageStyles );
753 : }
754 :
755 22 : Reference< XStyle > WorkbookHelper::getStyleObject( const OUString& rStyleName, bool bPageStyle ) const
756 : {
757 22 : return mrBookGlob.getStyleObject( rStyleName, bPageStyle );
758 : }
759 :
760 14 : ScRangeData* WorkbookHelper::createNamedRangeObject( OUString& orName, const Sequence< FormulaToken>& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags ) const
761 : {
762 14 : return mrBookGlob.createNamedRangeObject( orName, rTokens, nIndex, nNameFlags );
763 : }
764 :
765 10 : ScRangeData* WorkbookHelper::createLocalNamedRangeObject( OUString& orName, const Sequence< FormulaToken>& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags, sal_Int32 nTab ) const
766 : {
767 10 : return mrBookGlob.createLocalNamedRangeObject( orName, rTokens, nIndex, nNameFlags, nTab );
768 : }
769 :
770 0 : Reference< XDatabaseRange > WorkbookHelper::createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const
771 : {
772 0 : return mrBookGlob.createDatabaseRangeObject( orName, rRangeAddr );
773 : }
774 :
775 2 : Reference< XDatabaseRange > WorkbookHelper::createUnnamedDatabaseRangeObject( const CellRangeAddress& rRangeAddr ) const
776 : {
777 2 : return mrBookGlob.createUnnamedDatabaseRangeObject( rRangeAddr );
778 : }
779 :
780 122 : Reference< XStyle > WorkbookHelper::createStyleObject( OUString& orStyleName, bool bPageStyle ) const
781 : {
782 122 : return mrBookGlob.createStyleObject( orStyleName, bPageStyle );
783 : }
784 :
785 : // buffers --------------------------------------------------------------------
786 :
787 116 : FormulaBuffer& WorkbookHelper::getFormulaBuffer() const
788 : {
789 116 : return mrBookGlob.getFormulaBuffer();
790 : }
791 :
792 66 : WorkbookSettings& WorkbookHelper::getWorkbookSettings() const
793 : {
794 66 : return mrBookGlob.getWorkbookSettings();
795 : }
796 :
797 150 : ViewSettings& WorkbookHelper::getViewSettings() const
798 : {
799 150 : return mrBookGlob.getViewSettings();
800 : }
801 :
802 154 : WorksheetBuffer& WorkbookHelper::getWorksheets() const
803 : {
804 154 : return mrBookGlob.getWorksheets();
805 : }
806 :
807 690 : ThemeBuffer& WorkbookHelper::getTheme() const
808 : {
809 690 : return mrBookGlob.getTheme();
810 : }
811 :
812 3458 : StylesBuffer& WorkbookHelper::getStyles() const
813 : {
814 3458 : return mrBookGlob.getStyles();
815 : }
816 :
817 318 : SharedStringsBuffer& WorkbookHelper::getSharedStrings() const
818 : {
819 318 : return mrBookGlob.getSharedStrings();
820 : }
821 :
822 14 : ExternalLinkBuffer& WorkbookHelper::getExternalLinks() const
823 : {
824 14 : return mrBookGlob.getExternalLinks();
825 : }
826 :
827 94 : DefinedNamesBuffer& WorkbookHelper::getDefinedNames() const
828 : {
829 94 : return mrBookGlob.getDefinedNames();
830 : }
831 :
832 22 : TableBuffer& WorkbookHelper::getTables() const
833 : {
834 22 : return mrBookGlob.getTables();
835 : }
836 :
837 0 : ScenarioBuffer& WorkbookHelper::getScenarios() const
838 : {
839 0 : return mrBookGlob.getScenarios();
840 : }
841 :
842 0 : ConnectionsBuffer& WorkbookHelper::getConnections() const
843 : {
844 0 : return mrBookGlob.getConnections();
845 : }
846 :
847 0 : PivotCacheBuffer& WorkbookHelper::getPivotCaches() const
848 : {
849 0 : return mrBookGlob.getPivotCaches();
850 : }
851 :
852 0 : PivotTableBuffer& WorkbookHelper::getPivotTables() const
853 : {
854 0 : return mrBookGlob.getPivotTables();
855 : }
856 :
857 : // converters -----------------------------------------------------------------
858 :
859 182 : FormulaParser& WorkbookHelper::getFormulaParser() const
860 : {
861 182 : return mrBookGlob.getFormulaParser();
862 : }
863 :
864 938 : UnitConverter& WorkbookHelper::getUnitConverter() const
865 : {
866 938 : return mrBookGlob.getUnitConverter();
867 : }
868 :
869 988 : AddressConverter& WorkbookHelper::getAddressConverter() const
870 : {
871 988 : return mrBookGlob.getAddressConverter();
872 : }
873 :
874 0 : ExcelChartConverter* WorkbookHelper::getChartConverter() const
875 : {
876 0 : return mrBookGlob.getChartConverter();
877 : }
878 :
879 50 : PageSettingsConverter& WorkbookHelper::getPageSettingsConverter() const
880 : {
881 50 : return mrBookGlob.getPageSettingsConverter();
882 : }
883 :
884 : // OOXML/BIFF12 specific ------------------------------------------------------
885 :
886 324 : XmlFilterBase& WorkbookHelper::getOoxFilter() const
887 : {
888 : OSL_ENSURE( mrBookGlob.getFilterType() == FILTER_OOXML, "WorkbookHelper::getOoxFilter - invalid call" );
889 324 : return mrBookGlob.getOoxFilter();
890 : }
891 :
892 108 : bool WorkbookHelper::importOoxFragment( const ::rtl::Reference< FragmentHandler >& rxHandler )
893 : {
894 108 : return getOoxFilter().importFragment( rxHandler );
895 : }
896 :
897 : // BIFF specific --------------------------------------------------------------
898 :
899 22 : BiffType WorkbookHelper::getBiff() const
900 : {
901 22 : return mrBookGlob.getBiff();
902 : }
903 :
904 0 : rtl_TextEncoding WorkbookHelper::getTextEncoding() const
905 : {
906 0 : return mrBookGlob.getTextEncoding();
907 : }
908 :
909 0 : BiffCodecHelper& WorkbookHelper::getCodecHelper() const
910 : {
911 0 : return mrBookGlob.getCodecHelper();
912 : }
913 :
914 : // ============================================================================
915 :
916 : } // namespace xls
917 24 : } // namespace oox
918 :
919 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|