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