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 "worksheethelper.hxx"
21 :
22 : #include <algorithm>
23 : #include <list>
24 : #include <utility>
25 : #include <com/sun/star/awt/Point.hpp>
26 : #include <com/sun/star/awt/Size.hpp>
27 : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
28 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
29 : #include <com/sun/star/sheet/TableValidationVisibility.hpp>
30 : #include <com/sun/star/sheet/ValidationType.hpp>
31 : #include <com/sun/star/sheet/ValidationAlertStyle.hpp>
32 : #include <com/sun/star/sheet/XCellAddressable.hpp>
33 : #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
34 : #include <com/sun/star/sheet/XFormulaTokens.hpp>
35 : #include <com/sun/star/sheet/XLabelRanges.hpp>
36 : #include <com/sun/star/sheet/XMultiFormulaTokens.hpp>
37 : #include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
38 : #include <com/sun/star/sheet/XSheetCondition2.hpp>
39 : #include <com/sun/star/sheet/XSheetOutline.hpp>
40 : #include <com/sun/star/sheet/XSpreadsheet.hpp>
41 : #include <com/sun/star/table/XColumnRowRange.hpp>
42 : #include <com/sun/star/text/WritingMode2.hpp>
43 : #include <com/sun/star/text/XText.hpp>
44 : #include <rtl/ustrbuf.hxx>
45 : #include "oox/core/filterbase.hxx"
46 : #include "oox/helper/propertyset.hxx"
47 : #include "addressconverter.hxx"
48 : #include "autofilterbuffer.hxx"
49 : #include "cell.hxx"
50 : #include "commentsbuffer.hxx"
51 : #include "condformatbuffer.hxx"
52 : #include "convuno.hxx"
53 : #include "document.hxx"
54 : #include "drawingfragment.hxx"
55 : #include "drawingmanager.hxx"
56 : #include "formulaparser.hxx"
57 : #include "pagesettings.hxx"
58 : #include "querytablebuffer.hxx"
59 : #include "sharedstringsbuffer.hxx"
60 : #include "sheetdatabuffer.hxx"
61 : #include "stylesbuffer.hxx"
62 : #include "tokenuno.hxx"
63 : #include "unitconverter.hxx"
64 : #include "viewsettings.hxx"
65 : #include "workbooksettings.hxx"
66 : #include "worksheetbuffer.hxx"
67 : #include "worksheetsettings.hxx"
68 : #include "formulabuffer.hxx"
69 :
70 : namespace oox {
71 : namespace xls {
72 :
73 : // ============================================================================
74 :
75 : using namespace ::com::sun::star;
76 : using namespace ::com::sun::star::beans;
77 : using namespace ::com::sun::star::drawing;
78 : using namespace ::com::sun::star::lang;
79 : using namespace ::com::sun::star::sheet;
80 : using namespace ::com::sun::star::table;
81 : using namespace ::com::sun::star::text;
82 : using namespace ::com::sun::star::uno;
83 : using namespace ::com::sun::star::util;
84 :
85 : using ::rtl::OUString;
86 : using ::rtl::OUStringBuffer;
87 :
88 : // ============================================================================
89 :
90 : namespace {
91 :
92 153 : void lclUpdateProgressBar( const ISegmentProgressBarRef& rxProgressBar, const CellRangeAddress& rUsedArea, sal_Int32 nRow )
93 : {
94 153 : if( rxProgressBar.get() && (rUsedArea.StartRow <= nRow) && (nRow <= rUsedArea.EndRow) )
95 : {
96 153 : double fPosition = static_cast< double >( nRow - rUsedArea.StartRow + 1 ) / (rUsedArea.EndRow - rUsedArea.StartRow + 1);
97 153 : if( rxProgressBar->getPosition() < fPosition )
98 153 : rxProgressBar->setPosition( fPosition );
99 : }
100 153 : }
101 :
102 125 : void lclUpdateProgressBar( const ISegmentProgressBarRef& rxProgressBar, double fPosition )
103 : {
104 125 : if( rxProgressBar.get() )
105 125 : rxProgressBar->setPosition( fPosition );
106 125 : }
107 :
108 : } // namespace
109 :
110 : // ============================================================================
111 : // ============================================================================
112 :
113 89 : ColumnModel::ColumnModel() :
114 : maRange( -1 ),
115 : mfWidth( 0.0 ),
116 : mnXfId( -1 ),
117 : mnLevel( 0 ),
118 : mbShowPhonetic( false ),
119 : mbHidden( false ),
120 89 : mbCollapsed( false )
121 : {
122 89 : }
123 :
124 12 : bool ColumnModel::isMergeable( const ColumnModel& rModel ) const
125 : {
126 : return
127 : (maRange.mnFirst <= rModel.maRange.mnFirst) &&
128 : (rModel.maRange.mnFirst <= maRange.mnLast + 1) &&
129 : (mfWidth == rModel.mfWidth) &&
130 : // ignore mnXfId, cell formatting is always set directly
131 : (mnLevel == rModel.mnLevel) &&
132 : (mbHidden == rModel.mbHidden) &&
133 12 : (mbCollapsed == rModel.mbCollapsed);
134 : }
135 :
136 : // ----------------------------------------------------------------------------
137 :
138 225 : RowModel::RowModel() :
139 : mnRow( -1 ),
140 : mfHeight( 0.0 ),
141 : mnXfId( -1 ),
142 : mnLevel( 0 ),
143 : mbCustomHeight( false ),
144 : mbCustomFormat( false ),
145 : mbShowPhonetic( false ),
146 : mbHidden( false ),
147 : mbCollapsed( false ),
148 : mbThickTop( false ),
149 225 : mbThickBottom( false )
150 : {
151 225 : }
152 :
153 55 : void RowModel::insertColSpan( const ValueRange& rColSpan )
154 : {
155 55 : if( (0 <= rColSpan.mnFirst) && (rColSpan.mnFirst <= rColSpan.mnLast) )
156 55 : maColSpans.insert( rColSpan );
157 55 : }
158 :
159 120 : bool RowModel::isMergeable( const RowModel& rModel ) const
160 : {
161 : return
162 : // ignore maColSpans - is handled separately in SheetDataBuffer class
163 : (mfHeight == rModel.mfHeight) &&
164 : // ignore mnXfId, mbCustomFormat, mbShowPhonetic - cell formatting is always set directly
165 : (mnLevel == rModel.mnLevel) &&
166 : (mbCustomHeight == rModel.mbCustomHeight) &&
167 : (mbHidden == rModel.mbHidden) &&
168 120 : (mbCollapsed == rModel.mbCollapsed);
169 : }
170 :
171 : // ----------------------------------------------------------------------------
172 :
173 0 : PageBreakModel::PageBreakModel() :
174 : mnColRow( 0 ),
175 0 : mbManual( false )
176 : {
177 0 : }
178 :
179 : // ----------------------------------------------------------------------------
180 :
181 0 : HyperlinkModel::HyperlinkModel()
182 : {
183 0 : }
184 :
185 : // ----------------------------------------------------------------------------
186 :
187 0 : ValidationModel::ValidationModel() :
188 : mnType( XML_none ),
189 : mnOperator( XML_between ),
190 : mnErrorStyle( XML_stop ),
191 : mbShowInputMsg( false ),
192 : mbShowErrorMsg( false ),
193 : mbNoDropDown( false ),
194 0 : mbAllowBlank( false )
195 : {
196 0 : }
197 :
198 0 : void ValidationModel::setBiffType( sal_uInt8 nType )
199 : {
200 : static const sal_Int32 spnTypeIds[] = {
201 : XML_none, XML_whole, XML_decimal, XML_list, XML_date, XML_time, XML_textLength, XML_custom };
202 0 : mnType = STATIC_ARRAY_SELECT( spnTypeIds, nType, XML_none );
203 0 : }
204 :
205 0 : void ValidationModel::setBiffOperator( sal_uInt8 nOperator )
206 : {
207 : static const sal_Int32 spnOperators[] = {
208 : XML_between, XML_notBetween, XML_equal, XML_notEqual,
209 : XML_greaterThan, XML_lessThan, XML_greaterThanOrEqual, XML_lessThanOrEqual };
210 0 : mnOperator = STATIC_ARRAY_SELECT( spnOperators, nOperator, XML_TOKEN_INVALID );
211 0 : }
212 :
213 0 : void ValidationModel::setBiffErrorStyle( sal_uInt8 nErrorStyle )
214 : {
215 : static const sal_Int32 spnErrorStyles[] = { XML_stop, XML_warning, XML_information };
216 0 : mnErrorStyle = STATIC_ARRAY_SELECT( spnErrorStyles, nErrorStyle, XML_stop );
217 0 : }
218 :
219 : // ============================================================================
220 : // ============================================================================
221 :
222 50 : class WorksheetGlobals : public WorkbookHelper
223 : {
224 : public:
225 : explicit WorksheetGlobals(
226 : const WorkbookHelper& rHelper,
227 : const ISegmentProgressBarRef& rxProgressBar,
228 : WorksheetType eSheetType,
229 : sal_Int16 nSheet );
230 :
231 : /** Returns true, if this helper refers to an existing Calc sheet. */
232 25 : inline bool isValidSheet() const { return mxSheet.is(); }
233 :
234 : /** Returns the type of this sheet. */
235 75 : inline WorksheetType getSheetType() const { return meSheetType; }
236 : /** Returns the index of the current sheet. */
237 449 : inline sal_Int16 getSheetIndex() const { return maUsedArea.Sheet; }
238 : /** Returns the XSpreadsheet interface of the current sheet. */
239 87 : inline const Reference< XSpreadsheet >& getSheet() const { return mxSheet; }
240 :
241 : /** Returns the XCell interface for the passed cell address. */
242 : Reference< XCell > getCell( const CellAddress& rAddress ) const;
243 : /** Returns the XCellRange interface for the passed cell range address. */
244 : Reference< XCellRange > getCellRange( const CellRangeAddress& rRange ) const;
245 : /** Returns the XSheetCellRanges interface for the passed cell range addresses. */
246 : Reference< XSheetCellRanges > getCellRangeList( const ApiCellRangeList& rRanges ) const;
247 :
248 : /** Returns the XCellRange interface for a column. */
249 : Reference< XCellRange > getColumn( sal_Int32 nCol ) const;
250 : /** Returns the XCellRange interface for a row. */
251 : Reference< XCellRange > getRow( sal_Int32 nRow ) const;
252 :
253 : /** Returns the XTableColumns interface for a range of columns. */
254 : Reference< XTableColumns > getColumns( const ValueRange& rColRange ) const;
255 : /** Returns the XTableRows interface for a range of rows. */
256 : Reference< XTableRows > getRows( const ValueRange& rRowRange ) const;
257 :
258 : /** Returns the XDrawPage interface of the draw page of the current sheet. */
259 : Reference< XDrawPage > getDrawPage() const;
260 : /** Returns the size of the entire drawing page in 1/100 mm. */
261 : const awt::Size& getDrawPageSize() const;
262 :
263 : /** Returns the absolute position of the top-left corner of the cell in 1/100 mm. */
264 : awt::Point getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const;
265 : /** Returns the size of the cell in 1/100 mm. */
266 : awt::Size getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const;
267 :
268 : /** Returns the address of the cell that contains the passed point in 1/100 mm. */
269 : CellAddress getCellAddressFromPosition( const awt::Point& rPosition ) const;
270 : /** Returns the cell range address that contains the passed rectangle in 1/100 mm. */
271 : CellRangeAddress getCellRangeFromRectangle( const awt::Rectangle& rRect ) const;
272 :
273 : /** Returns the buffer for cell contents and cell formatting. */
274 26 : inline SheetDataBuffer& getSheetData() { return maSheetData; }
275 : /** Returns the conditional formatting in this sheet. */
276 28 : inline CondFormatBuffer& getCondFormats() { return maCondFormats; }
277 : /** Returns the buffer for all cell comments in this sheet. */
278 1 : inline CommentsBuffer& getComments() { return maComments; }
279 : /** Returns the auto filters for the sheet. */
280 1 : inline AutoFilterBuffer& getAutoFilters() { return maAutoFilters; }
281 : /** Returns the buffer for all web query tables in this sheet. */
282 0 : inline QueryTableBuffer& getQueryTables() { return maQueryTables; }
283 : /** Returns the worksheet settings object. */
284 20 : inline WorksheetSettings& getWorksheetSettings() { return maSheetSett; }
285 : /** Returns the page/print settings for this sheet. */
286 137 : inline PageSettings& getPageSettings() { return maPageSett; }
287 : /** Returns the view settings for this sheet. */
288 46 : inline SheetViewSettings& getSheetViewSettings() { return maSheetViewSett; }
289 : /** Returns the VML drawing page for this sheet (OOXML/BIFF12 only). */
290 5 : inline VmlDrawing& getVmlDrawing() { return *mxVmlDrawing; }
291 : /** returns the ExtLst entries that need to be filled */
292 0 : inline ExtLst& getExtLst() { return maExtLst; }
293 :
294 : /** Returns the BIFF drawing page for this sheet (BIFF2-BIFF8 only). */
295 0 : inline BiffSheetDrawing& getBiffDrawing() const { return *mxBiffDrawing; }
296 :
297 : /** Changes the current sheet type. */
298 : inline void setSheetType( WorksheetType eSheetType ) { meSheetType = eSheetType; }
299 : /** Sets a column or row page break described in the passed struct. */
300 : void setPageBreak( const PageBreakModel& rModel, bool bRowBreak );
301 : /** Inserts the hyperlink URL into the spreadsheet. */
302 : void setHyperlink( const HyperlinkModel& rModel );
303 : /** Inserts the data validation settings into the spreadsheet. */
304 : void setValidation( const ValidationModel& rModel );
305 : /** Sets the path to the DrawingML fragment of this sheet. */
306 : void setDrawingPath( const OUString& rDrawingPath );
307 : /** Sets the path to the legacy VML drawing fragment of this sheet. */
308 : void setVmlDrawingPath( const OUString& rVmlDrawingPath );
309 :
310 : /** Extends the used area of this sheet by the passed cell position. */
311 : void extendUsedArea( const CellAddress& rAddress );
312 : /** Extends the used area of this sheet by the passed cell range. */
313 : void extendUsedArea( const CellRangeAddress& rRange );
314 : /** Extends the shape bounding box by the position and size of the passed rectangle. */
315 : void extendShapeBoundingBox( const awt::Rectangle& rShapeRect );
316 :
317 : /** Sets base width for all columns (without padding pixels). This value
318 : is only used, if base width has not been set with setDefaultColumnWidth(). */
319 : void setBaseColumnWidth( sal_Int32 nWidth );
320 : /** Sets default width for all columns. This function overrides the base
321 : width set with the setBaseColumnWidth() function. */
322 : void setDefaultColumnWidth( double fWidth );
323 : /** Sets column settings for a specific column range.
324 : @descr Column default formatting is converted directly, other settings
325 : are cached and converted in the finalizeImport() call. */
326 : void setColumnModel( const ColumnModel& rModel );
327 : /** Converts column default cell formatting. */
328 : void convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) const;
329 :
330 : /** Sets default height and hidden state for all unused rows in the sheet. */
331 : void setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom );
332 : /** Sets row settings for a specific row.
333 : @descr Row default formatting is converted directly, other settings
334 : are cached and converted in the finalizeImport() call. */
335 : void setRowModel( const RowModel& rModel );
336 :
337 : /** Initial conversion before importing the worksheet. */
338 : void initializeWorksheetImport();
339 : /** Final conversion after importing the worksheet. */
340 : void finalizeWorksheetImport();
341 :
342 : private:
343 : typedef ::std::vector< sal_Int32 > OutlineLevelVec;
344 : typedef ::std::pair< ColumnModel, sal_Int32 > ColumnModelRange;
345 : typedef ::std::map< sal_Int32, ColumnModelRange > ColumnModelRangeMap;
346 : typedef ::std::pair< RowModel, sal_Int32 > RowModelRange;
347 : typedef ::std::map< sal_Int32, RowModelRange > RowModelRangeMap;
348 : typedef ::std::list< HyperlinkModel > HyperlinkModelList;
349 : typedef ::std::list< ValidationModel > ValidationModelList;
350 :
351 : /** Inserts all imported hyperlinks into their cell ranges. */
352 : void finalizeHyperlinkRanges() const;
353 : /** Generates the final URL for the passed hyperlink. */
354 : OUString getHyperlinkUrl( const HyperlinkModel& rHyperlink ) const;
355 : /** Inserts a hyperlinks into the specified cell. */
356 : void insertHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const;
357 :
358 : /** Inserts all imported data validations into their cell ranges. */
359 : void finalizeValidationRanges() const;
360 :
361 : /** Converts column properties for all columns in the sheet. */
362 : void convertColumns();
363 : /** Converts column properties. */
364 : void convertColumns( OutlineLevelVec& orColLevels, const ValueRange& rColRange, const ColumnModel& rModel );
365 :
366 : /** Converts row properties for all rows in the sheet. */
367 : void convertRows();
368 : /** Converts row properties. */
369 : void convertRows( OutlineLevelVec& orRowLevels, const ValueRange& rRowRange, const RowModel& rModel, double fDefHeight = -1.0 );
370 :
371 : /** Converts outline grouping for the passed column or row. */
372 : void convertOutlines( OutlineLevelVec& orLevels, sal_Int32 nColRow, sal_Int32 nLevel, bool bCollapsed, bool bRows );
373 : /** Groups columns or rows for the given range. */
374 : void groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastColRow, bool bCollapsed, bool bRows );
375 :
376 : /** Imports the drawings of the sheet (DML, VML, DFF) and updates the used area. */
377 : void finalizeDrawings();
378 :
379 : private:
380 : typedef ::std::auto_ptr< VmlDrawing > VmlDrawingPtr;
381 : typedef ::std::auto_ptr< BiffSheetDrawing > BiffSheetDrawingPtr;
382 :
383 : const OUString maSheetCellRanges; /// Service name for a SheetCellRanges object.
384 : const OUString maUrlTextField; /// Service name for a URL text field.
385 : const CellAddress& mrMaxApiPos; /// Reference to maximum Calc cell address from address converter.
386 : CellRangeAddress maUsedArea; /// Used area of the sheet, and sheet index of the sheet.
387 : ColumnModel maDefColModel; /// Default column formatting.
388 : ColumnModelRangeMap maColModels; /// Ranges of columns sorted by first column index.
389 : RowModel maDefRowModel; /// Default row formatting.
390 : RowModelRangeMap maRowModels; /// Ranges of rows sorted by first row index.
391 : HyperlinkModelList maHyperlinks; /// Cell ranges containing hyperlinks.
392 : ValidationModelList maValidations; /// Cell ranges containing data validation settings.
393 : SheetDataBuffer maSheetData; /// Buffer for cell contents and cell formatting.
394 : CondFormatBuffer maCondFormats; /// Buffer for conditional formatting.
395 : CommentsBuffer maComments; /// Buffer for all cell comments in this sheet.
396 : AutoFilterBuffer maAutoFilters; /// Sheet auto filters (not associated to a table).
397 : QueryTableBuffer maQueryTables; /// Buffer for all web query tables in this sheet.
398 : WorksheetSettings maSheetSett; /// Global settings for this sheet.
399 : PageSettings maPageSett; /// Page/print settings for this sheet.
400 : SheetViewSettings maSheetViewSett; /// View settings for this sheet.
401 : VmlDrawingPtr mxVmlDrawing; /// Collection of all VML shapes.
402 : ExtLst maExtLst; /// List of extended elements
403 : BiffSheetDrawingPtr mxBiffDrawing; /// Collection of all BIFF/DFF shapes.
404 : OUString maDrawingPath; /// Path to DrawingML fragment.
405 : OUString maVmlDrawingPath; /// Path to legacy VML drawing fragment.
406 : awt::Size maDrawPageSize; /// Current size of the drawing page in 1/100 mm.
407 : awt::Rectangle maShapeBoundingBox; /// Bounding box for all shapes from all drawings.
408 : ISegmentProgressBarRef mxProgressBar; /// Sheet progress bar.
409 : ISegmentProgressBarRef mxRowProgress; /// Progress bar for row/cell processing.
410 : ISegmentProgressBarRef mxFinalProgress; /// Progress bar for finalization.
411 : WorksheetType meSheetType; /// Type of this sheet.
412 : Reference< XSpreadsheet > mxSheet; /// Reference to the current sheet.
413 : bool mbHasDefWidth; /// True = default column width is set from defaultColWidth attribute.
414 : };
415 :
416 : // ----------------------------------------------------------------------------
417 :
418 25 : WorksheetGlobals::WorksheetGlobals( const WorkbookHelper& rHelper, const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) :
419 : WorkbookHelper( rHelper ),
420 : maSheetCellRanges( "com.sun.star.sheet.SheetCellRanges" ),
421 : maUrlTextField( "com.sun.star.text.TextField.URL" ),
422 25 : mrMaxApiPos( rHelper.getAddressConverter().getMaxApiAddress() ),
423 : maUsedArea( nSheet, SAL_MAX_INT32, SAL_MAX_INT32, -1, -1 ),
424 : maSheetData( *this ),
425 : maCondFormats( *this ),
426 : maComments( *this ),
427 : maAutoFilters( *this ),
428 : maQueryTables( *this ),
429 : maSheetSett( *this ),
430 : maPageSett( *this ),
431 : maSheetViewSett( *this ),
432 : mxProgressBar( rxProgressBar ),
433 : meSheetType( eSheetType ),
434 50 : mbHasDefWidth( false )
435 : {
436 25 : mxSheet = getSheetFromDoc( nSheet );
437 25 : if( !mxSheet.is() )
438 0 : maUsedArea.Sheet = -1;
439 :
440 : // default column settings (width and hidden state may be updated later)
441 25 : maDefColModel.mfWidth = 8.5;
442 25 : maDefColModel.mnXfId = -1;
443 25 : maDefColModel.mnLevel = 0;
444 25 : maDefColModel.mbHidden = false;
445 25 : maDefColModel.mbCollapsed = false;
446 :
447 : // default row settings (height and hidden state may be updated later)
448 25 : maDefRowModel.mfHeight = 0.0;
449 25 : maDefRowModel.mnXfId = -1;
450 25 : maDefRowModel.mnLevel = 0;
451 25 : maDefRowModel.mbCustomHeight = false;
452 25 : maDefRowModel.mbCustomFormat = false;
453 25 : maDefRowModel.mbShowPhonetic = false;
454 25 : maDefRowModel.mbHidden = false;
455 25 : maDefRowModel.mbCollapsed = false;
456 :
457 : // buffers
458 25 : switch( getFilterType() )
459 : {
460 : case FILTER_OOXML:
461 25 : mxVmlDrawing.reset( new VmlDrawing( *this ) );
462 25 : break;
463 : case FILTER_BIFF:
464 0 : mxBiffDrawing.reset( new BiffSheetDrawing( *this ) );
465 0 : break;
466 : case FILTER_UNKNOWN:
467 0 : break;
468 : }
469 :
470 : // prepare progress bars
471 25 : if( mxProgressBar.get() )
472 : {
473 25 : mxRowProgress = mxProgressBar->createSegment( 0.5 );
474 25 : mxFinalProgress = mxProgressBar->createSegment( 0.5 );
475 : }
476 25 : }
477 :
478 16 : Reference< XCell > WorksheetGlobals::getCell( const CellAddress& rAddress ) const
479 : {
480 16 : Reference< XCell > xCell;
481 16 : if( mxSheet.is() ) try
482 : {
483 16 : xCell = mxSheet->getCellByPosition( rAddress.Column, rAddress.Row );
484 : }
485 0 : catch( Exception& )
486 : {
487 : }
488 16 : return xCell;
489 : }
490 :
491 166 : Reference< XCellRange > WorksheetGlobals::getCellRange( const CellRangeAddress& rRange ) const
492 : {
493 166 : Reference< XCellRange > xRange;
494 166 : if( mxSheet.is() ) try
495 : {
496 166 : xRange = mxSheet->getCellRangeByPosition( rRange.StartColumn, rRange.StartRow, rRange.EndColumn, rRange.EndRow );
497 : }
498 0 : catch( Exception& )
499 : {
500 : }
501 166 : return xRange;
502 : }
503 :
504 0 : Reference< XSheetCellRanges > WorksheetGlobals::getCellRangeList( const ApiCellRangeList& rRanges ) const
505 : {
506 0 : Reference< XSheetCellRanges > xRanges;
507 0 : if( mxSheet.is() && !rRanges.empty() ) try
508 : {
509 0 : xRanges.set( getBaseFilter().getModelFactory()->createInstance( maSheetCellRanges ), UNO_QUERY_THROW );
510 0 : Reference< XSheetCellRangeContainer > xRangeCont( xRanges, UNO_QUERY_THROW );
511 0 : xRangeCont->addRangeAddresses( ContainerHelper::vectorToSequence( rRanges ), sal_False );
512 : }
513 0 : catch( Exception& )
514 : {
515 : }
516 0 : return xRanges;
517 : }
518 :
519 0 : Reference< XCellRange > WorksheetGlobals::getColumn( sal_Int32 nCol ) const
520 : {
521 0 : Reference< XCellRange > xColumn;
522 : try
523 : {
524 0 : Reference< XColumnRowRange > xColRowRange( mxSheet, UNO_QUERY_THROW );
525 0 : Reference< XTableColumns > xColumns( xColRowRange->getColumns(), UNO_SET_THROW );
526 0 : xColumn.set( xColumns->getByIndex( nCol ), UNO_QUERY );
527 : }
528 0 : catch( Exception& )
529 : {
530 : }
531 0 : return xColumn;
532 : }
533 :
534 0 : Reference< XCellRange > WorksheetGlobals::getRow( sal_Int32 nRow ) const
535 : {
536 0 : Reference< XCellRange > xRow;
537 : try
538 : {
539 0 : Reference< XColumnRowRange > xColRowRange( mxSheet, UNO_QUERY_THROW );
540 0 : Reference< XTableRows > xRows( xColRowRange->getRows(), UNO_SET_THROW );
541 0 : xRow.set( xRows->getByIndex( nRow ), UNO_QUERY );
542 : }
543 0 : catch( Exception& )
544 : {
545 : }
546 0 : return xRow;
547 : }
548 :
549 57 : Reference< XTableColumns > WorksheetGlobals::getColumns( const ValueRange& rColRange ) const
550 : {
551 57 : Reference< XTableColumns > xColumns;
552 57 : sal_Int32 nLastCol = ::std::min( rColRange.mnLast, mrMaxApiPos.Column );
553 57 : if( (0 <= rColRange.mnFirst) && (rColRange.mnFirst <= nLastCol) )
554 : {
555 40 : Reference< XColumnRowRange > xRange( getCellRange( CellRangeAddress( getSheetIndex(), rColRange.mnFirst, 0, nLastCol, 0 ) ), UNO_QUERY );
556 40 : if( xRange.is() )
557 40 : xColumns = xRange->getColumns();
558 : }
559 57 : return xColumns;
560 : }
561 :
562 69 : Reference< XTableRows > WorksheetGlobals::getRows( const ValueRange& rRowRange ) const
563 : {
564 69 : Reference< XTableRows > xRows;
565 69 : sal_Int32 nLastRow = ::std::min( rRowRange.mnLast, mrMaxApiPos.Row );
566 69 : if( (0 <= rRowRange.mnFirst) && (rRowRange.mnFirst <= nLastRow) )
567 : {
568 69 : Reference< XColumnRowRange > xRange( getCellRange( CellRangeAddress( getSheetIndex(), 0, rRowRange.mnFirst, 0, nLastRow ) ), UNO_QUERY );
569 69 : if( xRange.is() )
570 69 : xRows = xRange->getRows();
571 : }
572 69 : return xRows;
573 : }
574 :
575 27 : Reference< XDrawPage > WorksheetGlobals::getDrawPage() const
576 : {
577 27 : Reference< XDrawPage > xDrawPage;
578 : try
579 : {
580 27 : xDrawPage = Reference< XDrawPageSupplier >( mxSheet, UNO_QUERY_THROW )->getDrawPage();
581 : }
582 0 : catch( Exception& )
583 : {
584 : }
585 27 : return xDrawPage;
586 : }
587 :
588 2 : const awt::Size& WorksheetGlobals::getDrawPageSize() const
589 : {
590 : OSL_ENSURE( (maDrawPageSize.Width > 0) && (maDrawPageSize.Height > 0), "WorksheetGlobals::getDrawPageSize - called too early, size invalid" );
591 2 : return maDrawPageSize;
592 : }
593 :
594 13 : awt::Point WorksheetGlobals::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const
595 : {
596 13 : awt::Point aPoint;
597 13 : PropertySet aCellProp( getCell( CellAddress( getSheetIndex(), nCol, nRow ) ) );
598 13 : aCellProp.getProperty( aPoint, PROP_Position );
599 13 : return aPoint;
600 : }
601 :
602 0 : awt::Size WorksheetGlobals::getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const
603 : {
604 0 : awt::Size aSize;
605 0 : PropertySet aCellProp( getCell( CellAddress( getSheetIndex(), nCol, nRow ) ) );
606 0 : aCellProp.getProperty( aSize, PROP_Size );
607 0 : return aSize;
608 : }
609 :
610 : namespace {
611 :
612 12 : inline sal_Int32 lclGetMidAddr( sal_Int32 nBegAddr, sal_Int32 nEndAddr, sal_Int32 nBegPos, sal_Int32 nEndPos, sal_Int32 nSearchPos )
613 : {
614 : // use sal_Int64 to prevent integer overflow
615 12 : return nBegAddr + 1 + static_cast< sal_Int32 >( static_cast< sal_Int64 >( nEndAddr - nBegAddr - 2 ) * (nSearchPos - nBegPos) / (nEndPos - nBegPos) );
616 : }
617 :
618 4 : bool lclPrepareInterval( sal_Int32 nBegAddr, sal_Int32& rnMidAddr, sal_Int32 nEndAddr,
619 : sal_Int32 nBegPos, sal_Int32 nEndPos, sal_Int32 nSearchPos )
620 : {
621 : // searched position before nBegPos -> use nBegAddr
622 4 : if( nSearchPos <= nBegPos )
623 : {
624 0 : rnMidAddr = nBegAddr;
625 0 : return false;
626 : }
627 :
628 : // searched position after nEndPos, or begin next to end -> use nEndAddr
629 4 : if( (nSearchPos >= nEndPos) || (nBegAddr + 1 >= nEndAddr) )
630 : {
631 0 : rnMidAddr = nEndAddr;
632 0 : return false;
633 : }
634 :
635 : /* Otherwise find mid address according to position. lclGetMidAddr() will
636 : return an address between nBegAddr and nEndAddr. */
637 4 : rnMidAddr = lclGetMidAddr( nBegAddr, nEndAddr, nBegPos, nEndPos, nSearchPos );
638 4 : return true;
639 : }
640 :
641 12 : bool lclUpdateInterval( sal_Int32& rnBegAddr, sal_Int32& rnMidAddr, sal_Int32& rnEndAddr,
642 : sal_Int32& rnBegPos, sal_Int32 nMidPos, sal_Int32& rnEndPos, sal_Int32 nSearchPos )
643 : {
644 : // nSearchPos < nMidPos: use the interval [begin,mid] in the next iteration
645 12 : if( nSearchPos < nMidPos )
646 : {
647 : // if rnBegAddr is next to rnMidAddr, the latter is the column/row in question
648 4 : if( rnBegAddr + 1 >= rnMidAddr )
649 0 : return false;
650 : // otherwise, set interval end to mid
651 4 : rnEndPos = nMidPos;
652 4 : rnEndAddr = rnMidAddr;
653 4 : rnMidAddr = lclGetMidAddr( rnBegAddr, rnEndAddr, rnBegPos, rnEndPos, nSearchPos );
654 4 : return true;
655 : }
656 :
657 : // nSearchPos > nMidPos: use the interval [mid,end] in the next iteration
658 8 : if( nSearchPos > nMidPos )
659 : {
660 : // if rnMidAddr is next to rnEndAddr, the latter is the column/row in question
661 8 : if( rnMidAddr + 1 >= rnEndAddr )
662 : {
663 4 : rnMidAddr = rnEndAddr;
664 4 : return false;
665 : }
666 : // otherwise, set interval start to mid
667 4 : rnBegPos = nMidPos;
668 4 : rnBegAddr = rnMidAddr;
669 4 : rnMidAddr = lclGetMidAddr( rnBegAddr, rnEndAddr, rnBegPos, rnEndPos, nSearchPos );
670 4 : return true;
671 : }
672 :
673 : // nSearchPos == nMidPos: rnMidAddr is the column/row in question, do not loop anymore
674 0 : return false;
675 : }
676 :
677 : } // namespace
678 :
679 2 : CellAddress WorksheetGlobals::getCellAddressFromPosition( const awt::Point& rPosition ) const
680 : {
681 : // starting cell address and its position in drawing layer (top-left edge)
682 2 : sal_Int32 nBegCol = 0;
683 2 : sal_Int32 nBegRow = 0;
684 2 : awt::Point aBegPos( 0, 0 );
685 :
686 : // end cell address and its position in drawing layer (bottom-right edge)
687 2 : sal_Int32 nEndCol = mrMaxApiPos.Column + 1;
688 2 : sal_Int32 nEndRow = mrMaxApiPos.Row + 1;
689 2 : awt::Point aEndPos( maDrawPageSize.Width, maDrawPageSize.Height );
690 :
691 : // starting point for interval search
692 : sal_Int32 nMidCol, nMidRow;
693 2 : bool bLoopCols = lclPrepareInterval( nBegCol, nMidCol, nEndCol, aBegPos.X, aEndPos.X, rPosition.X );
694 2 : bool bLoopRows = lclPrepareInterval( nBegRow, nMidRow, nEndRow, aBegPos.Y, aEndPos.Y, rPosition.Y );
695 2 : awt::Point aMidPos = getCellPosition( nMidCol, nMidRow );
696 :
697 : /* The loop will find the column/row index of the cell right of/below
698 : the cell containing the passed point, unless the point is located at
699 : the top or left border of the containing cell. */
700 10 : while( bLoopCols || bLoopRows )
701 : {
702 6 : bLoopCols = bLoopCols && lclUpdateInterval( nBegCol, nMidCol, nEndCol, aBegPos.X, aMidPos.X, aEndPos.X, rPosition.X );
703 6 : bLoopRows = bLoopRows && lclUpdateInterval( nBegRow, nMidRow, nEndRow, aBegPos.Y, aMidPos.Y, aEndPos.Y, rPosition.Y );
704 6 : aMidPos = getCellPosition( nMidCol, nMidRow );
705 : }
706 :
707 : /* The cell left of/above the current search position contains the passed
708 : point, unless the point is located on the top/left border of the cell,
709 : or the last column/row of the sheet has been reached. */
710 2 : if( aMidPos.X > rPosition.X ) --nMidCol;
711 2 : if( aMidPos.Y > rPosition.Y ) --nMidRow;
712 2 : return CellAddress( getSheetIndex(), nMidCol, nMidRow );
713 : }
714 :
715 1 : CellRangeAddress WorksheetGlobals::getCellRangeFromRectangle( const awt::Rectangle& rRect ) const
716 : {
717 1 : CellAddress aStartAddr = getCellAddressFromPosition( awt::Point( rRect.X, rRect.Y ) );
718 1 : awt::Point aBotRight( rRect.X + rRect.Width, rRect.Y + rRect.Height );
719 1 : CellAddress aEndAddr = getCellAddressFromPosition( aBotRight );
720 1 : bool bMultiCols = aStartAddr.Column < aEndAddr.Column;
721 1 : bool bMultiRows = aStartAddr.Row < aEndAddr.Row;
722 1 : if( bMultiCols || bMultiRows )
723 : {
724 : /* Reduce end position of the cell range to previous column or row, if
725 : the rectangle ends exactly between two columns or rows. */
726 1 : awt::Point aEndPos = getCellPosition( aEndAddr.Column, aEndAddr.Row );
727 1 : if( bMultiCols && (aBotRight.X <= aEndPos.X) )
728 0 : --aEndAddr.Column;
729 1 : if( bMultiRows && (aBotRight.Y <= aEndPos.Y) )
730 0 : --aEndAddr.Row;
731 : }
732 1 : return CellRangeAddress( getSheetIndex(), aStartAddr.Column, aStartAddr.Row, aEndAddr.Column, aEndAddr.Row );
733 : }
734 :
735 0 : void WorksheetGlobals::setPageBreak( const PageBreakModel& rModel, bool bRowBreak )
736 : {
737 0 : if( rModel.mbManual && (rModel.mnColRow > 0) )
738 : {
739 0 : PropertySet aPropSet( bRowBreak ? getRow( rModel.mnColRow ) : getColumn( rModel.mnColRow ) );
740 0 : aPropSet.setProperty( PROP_IsStartOfNewPage, true );
741 : }
742 0 : }
743 :
744 0 : void WorksheetGlobals::setHyperlink( const HyperlinkModel& rModel )
745 : {
746 0 : maHyperlinks.push_back( rModel );
747 0 : }
748 :
749 0 : void WorksheetGlobals::setValidation( const ValidationModel& rModel )
750 : {
751 0 : maValidations.push_back( rModel );
752 0 : }
753 :
754 2 : void WorksheetGlobals::setDrawingPath( const OUString& rDrawingPath )
755 : {
756 2 : maDrawingPath = rDrawingPath;
757 2 : }
758 :
759 2 : void WorksheetGlobals::setVmlDrawingPath( const OUString& rVmlDrawingPath )
760 : {
761 2 : maVmlDrawingPath = rVmlDrawingPath;
762 2 : }
763 :
764 731 : void WorksheetGlobals::extendUsedArea( const CellAddress& rAddress )
765 : {
766 731 : maUsedArea.StartColumn = ::std::min( maUsedArea.StartColumn, rAddress.Column );
767 731 : maUsedArea.StartRow = ::std::min( maUsedArea.StartRow, rAddress.Row );
768 731 : maUsedArea.EndColumn = ::std::max( maUsedArea.EndColumn, rAddress.Column );
769 731 : maUsedArea.EndRow = ::std::max( maUsedArea.EndRow, rAddress.Row );
770 731 : }
771 :
772 20 : void WorksheetGlobals::extendUsedArea( const CellRangeAddress& rRange )
773 : {
774 20 : extendUsedArea( CellAddress( rRange.Sheet, rRange.StartColumn, rRange.StartRow ) );
775 20 : extendUsedArea( CellAddress( rRange.Sheet, rRange.EndColumn, rRange.EndRow ) );
776 20 : }
777 :
778 1 : void WorksheetGlobals::extendShapeBoundingBox( const awt::Rectangle& rShapeRect )
779 : {
780 1 : if( (maShapeBoundingBox.Width == 0) && (maShapeBoundingBox.Height == 0) )
781 : {
782 : // width and height of maShapeBoundingBox are assumed to be zero on first cell
783 1 : maShapeBoundingBox = rShapeRect;
784 : }
785 : else
786 : {
787 0 : sal_Int32 nEndX = ::std::max( maShapeBoundingBox.X + maShapeBoundingBox.Width, rShapeRect.X + rShapeRect.Width );
788 0 : sal_Int32 nEndY = ::std::max( maShapeBoundingBox.Y + maShapeBoundingBox.Height, rShapeRect.Y + rShapeRect.Height );
789 0 : maShapeBoundingBox.X = ::std::min( maShapeBoundingBox.X, rShapeRect.X );
790 0 : maShapeBoundingBox.Y = ::std::min( maShapeBoundingBox.Y, rShapeRect.Y );
791 0 : maShapeBoundingBox.Width = nEndX - maShapeBoundingBox.X;
792 0 : maShapeBoundingBox.Height = nEndY - maShapeBoundingBox.Y;
793 : }
794 1 : }
795 :
796 9 : void WorksheetGlobals::setBaseColumnWidth( sal_Int32 nWidth )
797 : {
798 : // do not modify width, if setDefaultColumnWidth() has been used
799 9 : if( !mbHasDefWidth && (nWidth > 0) )
800 : {
801 : // #i3006# add 5 pixels padding to the width
802 9 : const UnitConverter& rUnitConv = getUnitConverter();
803 : maDefColModel.mfWidth = rUnitConv.scaleFromMm100(
804 9 : rUnitConv.scaleToMm100( nWidth, UNIT_DIGIT ) + rUnitConv.scaleToMm100( 5, UNIT_SCREENX ), UNIT_DIGIT );
805 : }
806 9 : }
807 :
808 9 : void WorksheetGlobals::setDefaultColumnWidth( double fWidth )
809 : {
810 : // overrides a width set with setBaseColumnWidth()
811 9 : if( fWidth > 0.0 )
812 : {
813 0 : maDefColModel.mfWidth = fWidth;
814 0 : mbHasDefWidth = true;
815 : }
816 9 : }
817 :
818 32 : void WorksheetGlobals::setColumnModel( const ColumnModel& rModel )
819 : {
820 : // convert 1-based OOXML column indexes to 0-based API column indexes
821 32 : sal_Int32 nFirstCol = rModel.maRange.mnFirst - 1;
822 32 : sal_Int32 nLastCol = rModel.maRange.mnLast - 1;
823 32 : if( getAddressConverter().checkCol( nFirstCol, true ) && (nFirstCol <= nLastCol) )
824 : {
825 : // validate last column index
826 32 : if( !getAddressConverter().checkCol( nLastCol, true ) )
827 17 : nLastCol = mrMaxApiPos.Column;
828 : // try to find entry in column model map that is able to merge with the passed model
829 32 : bool bInsertModel = true;
830 32 : if( !maColModels.empty() )
831 : {
832 : // find first column model range following nFirstCol (nFirstCol < aIt->first), or end of map
833 12 : ColumnModelRangeMap::iterator aIt = maColModels.upper_bound( nFirstCol );
834 : OSL_ENSURE( aIt == maColModels.end(), "WorksheetGlobals::setColModel - columns are unsorted" );
835 : // if inserting before another column model, get last free column
836 : OSL_ENSURE( (aIt == maColModels.end()) || (nLastCol < aIt->first), "WorksheetGlobals::setColModel - multiple models of the same column" );
837 12 : if( aIt != maColModels.end() )
838 0 : nLastCol = ::std::min( nLastCol, aIt->first - 1 );
839 12 : if( aIt != maColModels.begin() )
840 : {
841 : // go to previous map element (which may be able to merge with the passed model)
842 12 : --aIt;
843 : // the usage of upper_bound() above ensures that aIt->first is less than or equal to nFirstCol now
844 12 : sal_Int32& rnLastMapCol = aIt->second.second;
845 : OSL_ENSURE( rnLastMapCol < nFirstCol, "WorksheetGlobals::setColModel - multiple models of the same column" );
846 12 : nFirstCol = ::std::max( rnLastMapCol + 1, nFirstCol );
847 12 : if( (rnLastMapCol + 1 == nFirstCol) && (nFirstCol <= nLastCol) && aIt->second.first.isMergeable( rModel ) )
848 : {
849 : // can merge with existing model, update last column index
850 0 : rnLastMapCol = nLastCol;
851 0 : bInsertModel = false;
852 : }
853 : }
854 : }
855 32 : if( nFirstCol <= nLastCol )
856 : {
857 : // insert the column model, if it has not been merged with another
858 32 : if( bInsertModel )
859 32 : maColModels[ nFirstCol ] = ColumnModelRange( rModel, nLastCol );
860 : // set column formatting directly
861 32 : convertColumnFormat( nFirstCol, nLastCol, rModel.mnXfId );
862 : }
863 : }
864 32 : }
865 :
866 32 : void WorksheetGlobals::convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) const
867 : {
868 32 : CellRangeAddress aRange( getSheetIndex(), nFirstCol, 0, nLastCol, mrMaxApiPos.Row );
869 32 : if( getAddressConverter().validateCellRange( aRange, true, false ) )
870 : {
871 32 : PropertySet aPropSet( getCellRange( aRange ) );
872 32 : getStyles().writeCellXfToPropertySet( aPropSet, nXfId );
873 : }
874 32 : }
875 :
876 9 : void WorksheetGlobals::setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom )
877 : {
878 9 : maDefRowModel.mfHeight = fHeight;
879 9 : maDefRowModel.mbCustomHeight = bCustomHeight;
880 9 : maDefRowModel.mbHidden = bHidden;
881 9 : maDefRowModel.mbThickTop = bThickTop;
882 9 : maDefRowModel.mbThickBottom = bThickBottom;
883 9 : }
884 :
885 153 : void WorksheetGlobals::setRowModel( const RowModel& rModel )
886 : {
887 : // convert 1-based OOXML row index to 0-based API row index
888 153 : sal_Int32 nRow = rModel.mnRow - 1;
889 153 : if( getAddressConverter().checkRow( nRow, true ) )
890 : {
891 : // try to find entry in row model map that is able to merge with the passed model
892 153 : bool bInsertModel = true;
893 153 : bool bUnusedRow = true;
894 153 : if( !maRowModels.empty() )
895 : {
896 : // find first row model range following nRow (nRow < aIt->first), or end of map
897 134 : RowModelRangeMap::iterator aIt = maRowModels.upper_bound( nRow );
898 : OSL_ENSURE( aIt == maRowModels.end(), "WorksheetGlobals::setRowModel - rows are unsorted" );
899 134 : if( aIt != maRowModels.begin() )
900 : {
901 : // go to previous map element (which may be able to merge with the passed model)
902 134 : --aIt;
903 : // the usage of upper_bound() above ensures that aIt->first is less than or equal to nRow now
904 134 : sal_Int32& rnLastMapRow = aIt->second.second;
905 134 : bUnusedRow = rnLastMapRow < nRow;
906 : OSL_ENSURE( bUnusedRow, "WorksheetGlobals::setRowModel - multiple models of the same row" );
907 134 : if( (rnLastMapRow + 1 == nRow) && aIt->second.first.isMergeable( rModel ) )
908 : {
909 : // can merge with existing model, update last row index
910 106 : ++rnLastMapRow;
911 106 : bInsertModel = false;
912 : }
913 : }
914 : }
915 153 : if( bUnusedRow )
916 : {
917 : // insert the row model, if it has not been merged with another
918 153 : if( bInsertModel )
919 47 : maRowModels[ nRow ] = RowModelRange( rModel, nRow );
920 : // set row formatting
921 153 : maSheetData.setRowFormat( nRow, rModel.mnXfId, rModel.mbCustomFormat );
922 : // set column spans
923 153 : maSheetData.setColSpans( nRow, rModel.maColSpans );
924 : }
925 : }
926 153 : lclUpdateProgressBar( mxRowProgress, maUsedArea, nRow );
927 153 : }
928 :
929 25 : void WorksheetGlobals::initializeWorksheetImport()
930 : {
931 : // set default cell style for unused cells
932 25 : PropertySet aPropSet( mxSheet );
933 25 : aPropSet.setProperty( PROP_CellStyle, getStyles().getDefaultStyleName() );
934 :
935 : /* Remember the current sheet index in global data, needed by global
936 : objects, e.g. the chart converter. */
937 25 : setCurrentSheetIndex( getSheetIndex() );
938 25 : }
939 :
940 25 : void WorksheetGlobals::finalizeWorksheetImport()
941 : {
942 25 : lclUpdateProgressBar( mxRowProgress, 1.0 );
943 25 : maSheetData.finalizeImport();
944 25 : lclUpdateProgressBar( mxFinalProgress, 0.25 );
945 25 : finalizeHyperlinkRanges();
946 25 : finalizeValidationRanges();
947 25 : maAutoFilters.finalizeImport( getSheetIndex() );
948 25 : maQueryTables.finalizeImport();
949 25 : maSheetSett.finalizeImport();
950 25 : maPageSett.finalizeImport();
951 25 : maSheetViewSett.finalizeImport();
952 :
953 25 : lclUpdateProgressBar( mxFinalProgress, 0.5 );
954 25 : convertColumns();
955 25 : convertRows();
956 25 : lclUpdateProgressBar( mxFinalProgress, 0.75 );
957 25 : finalizeDrawings();
958 25 : lclUpdateProgressBar( mxFinalProgress, 1.0 );
959 :
960 : // forget current sheet index in global data
961 25 : setCurrentSheetIndex( -1 );
962 25 : }
963 :
964 : // private --------------------------------------------------------------------
965 :
966 25 : void WorksheetGlobals::finalizeHyperlinkRanges() const
967 : {
968 25 : for( HyperlinkModelList::const_iterator aIt = maHyperlinks.begin(), aEnd = maHyperlinks.end(); aIt != aEnd; ++aIt )
969 : {
970 0 : OUString aUrl = getHyperlinkUrl( *aIt );
971 : // try to insert URL into each cell of the range
972 0 : if( !aUrl.isEmpty() )
973 0 : for( CellAddress aAddress( getSheetIndex(), aIt->maRange.StartColumn, aIt->maRange.StartRow ); aAddress.Row <= aIt->maRange.EndRow; ++aAddress.Row )
974 0 : for( aAddress.Column = aIt->maRange.StartColumn; aAddress.Column <= aIt->maRange.EndColumn; ++aAddress.Column )
975 0 : insertHyperlink( aAddress, aUrl );
976 0 : }
977 25 : }
978 :
979 0 : OUString WorksheetGlobals::getHyperlinkUrl( const HyperlinkModel& rHyperlink ) const
980 : {
981 0 : OUStringBuffer aUrlBuffer;
982 0 : if( !rHyperlink.maTarget.isEmpty() )
983 0 : aUrlBuffer.append( getBaseFilter().getAbsoluteUrl( rHyperlink.maTarget ) );
984 0 : if( !rHyperlink.maLocation.isEmpty() )
985 0 : aUrlBuffer.append( sal_Unicode( '#' ) ).append( rHyperlink.maLocation );
986 0 : OUString aUrl = aUrlBuffer.makeStringAndClear();
987 :
988 : // convert '#SheetName!A1' to '#SheetName.A1'
989 0 : if( !aUrl.isEmpty() && (aUrl[ 0 ] == '#') )
990 : {
991 0 : sal_Int32 nSepPos = aUrl.lastIndexOf( '!' );
992 0 : if( nSepPos > 0 )
993 : {
994 : // replace the exclamation mark with a period
995 0 : aUrl = aUrl.replaceAt( nSepPos, 1, OUString( sal_Unicode( '.' ) ) );
996 : // #i66592# convert sheet names that have been renamed on import
997 0 : OUString aSheetName = aUrl.copy( 1, nSepPos - 1 );
998 0 : OUString aCalcName = getWorksheets().getCalcSheetName( aSheetName );
999 0 : if( !aCalcName.isEmpty() )
1000 0 : aUrl = aUrl.replaceAt( 1, nSepPos - 1, aCalcName );
1001 : }
1002 : }
1003 :
1004 0 : return aUrl;
1005 : }
1006 :
1007 0 : void WorksheetGlobals::insertHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const
1008 : {
1009 0 : Reference< XCell > xCell = getCell( rAddress );
1010 0 : if( xCell.is() ) switch( xCell->getType() )
1011 : {
1012 : // #i54261# restrict creation of URL field to text cells
1013 : case CellContentType_TEXT:
1014 : {
1015 0 : Reference< XText > xText( xCell, UNO_QUERY );
1016 0 : if( xText.is() )
1017 : {
1018 : // create a URL field object and set its properties
1019 0 : Reference< XTextContent > xUrlField( getBaseFilter().getModelFactory()->createInstance( maUrlTextField ), UNO_QUERY );
1020 : OSL_ENSURE( xUrlField.is(), "WorksheetGlobals::insertHyperlink - cannot create text field" );
1021 0 : if( xUrlField.is() )
1022 : {
1023 : // properties of the URL field
1024 0 : PropertySet aPropSet( xUrlField );
1025 0 : aPropSet.setProperty( PROP_URL, rUrl );
1026 0 : aPropSet.setProperty( PROP_Representation, xText->getString() );
1027 : try
1028 : {
1029 : // insert the field into the cell
1030 0 : xText->setString( OUString() );
1031 0 : Reference< XTextRange > xRange( xText->createTextCursor(), UNO_QUERY_THROW );
1032 0 : xText->insertTextContent( xRange, xUrlField, sal_False );
1033 : }
1034 0 : catch( const Exception& )
1035 : {
1036 : OSL_FAIL( "WorksheetData::insertHyperlink - cannot insert text field" );
1037 0 : }
1038 0 : }
1039 0 : }
1040 : }
1041 0 : break;
1042 :
1043 : // fix for #i31050# disabled, HYPERLINK is not able to return numeric value (#i91351#)
1044 : #if 0
1045 : // #i31050# replace number with HYPERLINK function
1046 : case CellContentType_VALUE:
1047 : {
1048 : Reference< XFormulaTokens > xTokens( xCell, UNO_QUERY );
1049 : ApiTokenSequence aTokens = getFormulaParser().convertNumberToHyperlink( rUrl, xCell->getValue() );
1050 : OSL_ENSURE( xTokens.is(), "WorksheetHelper::insertHyperlink - missing formula token interface" );
1051 : if( xTokens.is() && aTokens.hasElements() )
1052 : xTokens->setTokens( aTokens );
1053 : }
1054 : break;
1055 : #endif
1056 :
1057 : default:;
1058 0 : }
1059 0 : }
1060 :
1061 25 : void WorksheetGlobals::finalizeValidationRanges() const
1062 : {
1063 25 : for( ValidationModelList::const_iterator aIt = maValidations.begin(), aEnd = maValidations.end(); aIt != aEnd; ++aIt )
1064 : {
1065 0 : PropertySet aPropSet( getCellRangeList( aIt->maRanges ) );
1066 :
1067 0 : Reference< XPropertySet > xValidation( aPropSet.getAnyProperty( PROP_Validation ), UNO_QUERY );
1068 0 : if( xValidation.is() )
1069 : {
1070 0 : PropertySet aValProps( xValidation );
1071 :
1072 : // convert validation type to API enum
1073 0 : ValidationType eType = ValidationType_ANY;
1074 0 : switch( aIt->mnType )
1075 : {
1076 0 : case XML_custom: eType = ValidationType_CUSTOM; break;
1077 0 : case XML_date: eType = ValidationType_DATE; break;
1078 0 : case XML_decimal: eType = ValidationType_DECIMAL; break;
1079 0 : case XML_list: eType = ValidationType_LIST; break;
1080 0 : case XML_none: eType = ValidationType_ANY; break;
1081 0 : case XML_textLength: eType = ValidationType_TEXT_LEN; break;
1082 0 : case XML_time: eType = ValidationType_TIME; break;
1083 0 : case XML_whole: eType = ValidationType_WHOLE; break;
1084 : default: OSL_FAIL( "WorksheetData::finalizeValidationRanges - unknown validation type" );
1085 : }
1086 0 : aValProps.setProperty( PROP_Type, eType );
1087 :
1088 : // convert error alert style to API enum
1089 0 : ValidationAlertStyle eAlertStyle = ValidationAlertStyle_STOP;
1090 0 : switch( aIt->mnErrorStyle )
1091 : {
1092 0 : case XML_information: eAlertStyle = ValidationAlertStyle_INFO; break;
1093 0 : case XML_stop: eAlertStyle = ValidationAlertStyle_STOP; break;
1094 0 : case XML_warning: eAlertStyle = ValidationAlertStyle_WARNING; break;
1095 : default: OSL_FAIL( "WorksheetData::finalizeValidationRanges - unknown error style" );
1096 : }
1097 0 : aValProps.setProperty( PROP_ErrorAlertStyle, eAlertStyle );
1098 :
1099 : // convert dropdown style to API visibility constants
1100 0 : sal_Int16 nVisibility = aIt->mbNoDropDown ? TableValidationVisibility::INVISIBLE : TableValidationVisibility::UNSORTED;
1101 0 : aValProps.setProperty( PROP_ShowList, nVisibility );
1102 :
1103 : // messages
1104 0 : aValProps.setProperty( PROP_ShowInputMessage, aIt->mbShowInputMsg );
1105 0 : aValProps.setProperty( PROP_InputTitle, aIt->maInputTitle );
1106 0 : aValProps.setProperty( PROP_InputMessage, aIt->maInputMessage );
1107 0 : aValProps.setProperty( PROP_ShowErrorMessage, aIt->mbShowErrorMsg );
1108 0 : aValProps.setProperty( PROP_ErrorTitle, aIt->maErrorTitle );
1109 0 : aValProps.setProperty( PROP_ErrorMessage, aIt->maErrorMessage );
1110 :
1111 : // allow blank cells
1112 0 : aValProps.setProperty( PROP_IgnoreBlankCells, aIt->mbAllowBlank );
1113 :
1114 : try
1115 : {
1116 : // condition operator
1117 0 : Reference< XSheetCondition2 > xSheetCond( xValidation, UNO_QUERY_THROW );
1118 0 : xSheetCond->setConditionOperator( CondFormatBuffer::convertToApiOperator( aIt->mnOperator ) );
1119 :
1120 : // condition formulas
1121 0 : Reference< XMultiFormulaTokens > xTokens( xValidation, UNO_QUERY_THROW );
1122 0 : xTokens->setTokens( 0, aIt->maTokens1 );
1123 0 : xTokens->setTokens( 1, aIt->maTokens2 );
1124 : }
1125 0 : catch( Exception& )
1126 : {
1127 : }
1128 :
1129 : // write back validation settings to cell range(s)
1130 0 : aPropSet.setProperty( PROP_Validation, xValidation );
1131 : }
1132 0 : }
1133 25 : }
1134 :
1135 25 : void WorksheetGlobals::convertColumns()
1136 : {
1137 25 : sal_Int32 nNextCol = 0;
1138 25 : sal_Int32 nMaxCol = mrMaxApiPos.Column;
1139 : // stores first grouped column index for each level
1140 25 : OutlineLevelVec aColLevels;
1141 :
1142 57 : for( ColumnModelRangeMap::iterator aIt = maColModels.begin(), aEnd = maColModels.end(); aIt != aEnd; ++aIt )
1143 : {
1144 : // column indexes are stored 0-based in maColModels
1145 32 : ValueRange aColRange( ::std::max( aIt->first, nNextCol ), ::std::min( aIt->second.second, nMaxCol ) );
1146 : // process gap between two column models, use default column model
1147 32 : if( nNextCol < aColRange.mnFirst )
1148 0 : convertColumns( aColLevels, ValueRange( nNextCol, aColRange.mnFirst - 1 ), maDefColModel );
1149 : // process the column model
1150 32 : convertColumns( aColLevels, aColRange, aIt->second.first );
1151 : // cache next column to be processed
1152 32 : nNextCol = aColRange.mnLast + 1;
1153 : }
1154 :
1155 : // remaining default columns to end of sheet
1156 25 : convertColumns( aColLevels, ValueRange( nNextCol, nMaxCol ), maDefColModel );
1157 : // close remaining column outlines spanning to end of sheet
1158 25 : convertOutlines( aColLevels, nMaxCol + 1, 0, false, false );
1159 25 : }
1160 :
1161 57 : void WorksheetGlobals::convertColumns( OutlineLevelVec& orColLevels,
1162 : const ValueRange& rColRange, const ColumnModel& rModel )
1163 : {
1164 57 : PropertySet aPropSet( getColumns( rColRange ) );
1165 :
1166 : // column width: convert 'number of characters' to column width in 1/100 mm
1167 57 : sal_Int32 nWidth = getUnitConverter().scaleToMm100( rModel.mfWidth, UNIT_DIGIT );
1168 : // macro sheets have double width
1169 57 : if( meSheetType == SHEETTYPE_MACROSHEET )
1170 0 : nWidth *= 2;
1171 57 : if( nWidth > 0 )
1172 57 : aPropSet.setProperty( PROP_Width, nWidth );
1173 :
1174 : // hidden columns: TODO: #108683# hide columns later?
1175 57 : if( rModel.mbHidden )
1176 0 : aPropSet.setProperty( PROP_IsVisible, false );
1177 :
1178 : // outline settings for this column range
1179 57 : convertOutlines( orColLevels, rColRange.mnFirst, rModel.mnLevel, rModel.mbCollapsed, false );
1180 57 : }
1181 :
1182 25 : void WorksheetGlobals::convertRows()
1183 : {
1184 25 : sal_Int32 nNextRow = 0;
1185 25 : sal_Int32 nMaxRow = mrMaxApiPos.Row;
1186 : // stores first grouped row index for each level
1187 25 : OutlineLevelVec aRowLevels;
1188 :
1189 72 : for( RowModelRangeMap::iterator aIt = maRowModels.begin(), aEnd = maRowModels.end(); aIt != aEnd; ++aIt )
1190 : {
1191 : // row indexes are stored 0-based in maRowModels
1192 47 : ValueRange aRowRange( ::std::max( aIt->first, nNextRow ), ::std::min( aIt->second.second, nMaxRow ) );
1193 : // process gap between two row models, use default row model
1194 47 : if( nNextRow < aRowRange.mnFirst )
1195 17 : convertRows( aRowLevels, ValueRange( nNextRow, aRowRange.mnFirst - 1 ), maDefRowModel );
1196 : // process the row model
1197 47 : convertRows( aRowLevels, aRowRange, aIt->second.first, maDefRowModel.mfHeight );
1198 : // cache next row to be processed
1199 47 : nNextRow = aRowRange.mnLast + 1;
1200 : }
1201 :
1202 : // remaining default rows to end of sheet
1203 25 : convertRows( aRowLevels, ValueRange( nNextRow, nMaxRow ), maDefRowModel );
1204 : // close remaining row outlines spanning to end of sheet
1205 25 : convertOutlines( aRowLevels, nMaxRow + 1, 0, false, true );
1206 25 : }
1207 :
1208 89 : void WorksheetGlobals::convertRows( OutlineLevelVec& orRowLevels,
1209 : const ValueRange& rRowRange, const RowModel& rModel, double fDefHeight )
1210 : {
1211 : // row height: convert points to row height in 1/100 mm
1212 89 : double fHeight = (rModel.mfHeight >= 0.0) ? rModel.mfHeight : fDefHeight;
1213 89 : sal_Int32 nHeight = getUnitConverter().scaleToMm100( fHeight, UNIT_POINT );
1214 89 : if( nHeight > 0 )
1215 : {
1216 : /* always import the row height, ensures better layout */
1217 67 : PropertySet aPropSet( getRows( rRowRange ) );
1218 67 : aPropSet.setProperty( PROP_Height, nHeight );
1219 : }
1220 :
1221 : // hidden rows: TODO: #108683# hide rows later?
1222 89 : if( rModel.mbHidden )
1223 : {
1224 2 : PropertySet aPropSet( getRows( rRowRange ) );
1225 : // #i116460# Use VisibleFlag instead of IsVisible: directly set the flag,
1226 : // without drawing layer update etc. (only possible before shapes are inserted)
1227 2 : aPropSet.setProperty( PROP_VisibleFlag, false );
1228 : }
1229 :
1230 : // outline settings for this row range
1231 89 : convertOutlines( orRowLevels, rRowRange.mnFirst, rModel.mnLevel, rModel.mbCollapsed, true );
1232 89 : }
1233 :
1234 196 : void WorksheetGlobals::convertOutlines( OutlineLevelVec& orLevels,
1235 : sal_Int32 nColRow, sal_Int32 nLevel, bool bCollapsed, bool bRows )
1236 : {
1237 : /* It is ensured from caller functions, that this function is called
1238 : without any gaps between the processed column or row ranges. */
1239 :
1240 : OSL_ENSURE( nLevel >= 0, "WorksheetGlobals::convertOutlines - negative outline level" );
1241 196 : nLevel = ::std::max< sal_Int32 >( nLevel, 0 );
1242 :
1243 196 : sal_Int32 nSize = orLevels.size();
1244 196 : if( nSize < nLevel )
1245 : {
1246 : // Outline level increased. Push the begin column position.
1247 0 : for( sal_Int32 nIndex = nSize; nIndex < nLevel; ++nIndex )
1248 0 : orLevels.push_back( nColRow );
1249 : }
1250 196 : else if( nLevel < nSize )
1251 : {
1252 : // Outline level decreased. Pop them all out.
1253 0 : for( sal_Int32 nIndex = nLevel; nIndex < nSize; ++nIndex )
1254 : {
1255 0 : sal_Int32 nFirstInLevel = orLevels.back();
1256 0 : orLevels.pop_back();
1257 0 : groupColumnsOrRows( nFirstInLevel, nColRow - 1, bCollapsed, bRows );
1258 0 : bCollapsed = false; // collapse only once
1259 : }
1260 : }
1261 196 : }
1262 :
1263 0 : void WorksheetGlobals::groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastColRow, bool bCollapse, bool bRows )
1264 : {
1265 : try
1266 : {
1267 0 : Reference< XSheetOutline > xOutline( mxSheet, UNO_QUERY_THROW );
1268 0 : if( bRows )
1269 : {
1270 0 : CellRangeAddress aRange( getSheetIndex(), 0, nFirstColRow, 0, nLastColRow );
1271 0 : xOutline->group( aRange, TableOrientation_ROWS );
1272 0 : if( bCollapse )
1273 0 : xOutline->hideDetail( aRange );
1274 : }
1275 : else
1276 : {
1277 0 : CellRangeAddress aRange( getSheetIndex(), nFirstColRow, 0, nLastColRow, 0 );
1278 0 : xOutline->group( aRange, TableOrientation_COLUMNS );
1279 0 : if( bCollapse )
1280 0 : xOutline->hideDetail( aRange );
1281 0 : }
1282 : }
1283 0 : catch( Exception& )
1284 : {
1285 : }
1286 0 : }
1287 :
1288 25 : void WorksheetGlobals::finalizeDrawings()
1289 : {
1290 : // calculate the current drawing page size (after rows/columns are imported)
1291 25 : PropertySet aRangeProp( getCellRange( CellRangeAddress( getSheetIndex(), 0, 0, mrMaxApiPos.Column, mrMaxApiPos.Row ) ) );
1292 25 : aRangeProp.getProperty( maDrawPageSize, PROP_Size );
1293 :
1294 25 : switch( getFilterType() )
1295 : {
1296 : case FILTER_OOXML:
1297 : // import DML and VML
1298 25 : if( !maDrawingPath.isEmpty() )
1299 2 : importOoxFragment( new DrawingFragment( *this, maDrawingPath ) );
1300 25 : if( !maVmlDrawingPath.isEmpty() )
1301 2 : importOoxFragment( new VmlDrawingFragment( *this, maVmlDrawingPath ) );
1302 25 : break;
1303 :
1304 : case FILTER_BIFF:
1305 : // convert BIFF3-BIFF5 drawing objects, or import and convert DFF stream
1306 0 : getBiffDrawing().finalizeImport();
1307 0 : break;
1308 :
1309 : case FILTER_UNKNOWN:
1310 0 : break;
1311 : }
1312 :
1313 : // comments (after callout shapes have been imported from VML/DFF)
1314 25 : maComments.finalizeImport();
1315 :
1316 : /* Extend used area of the sheet by cells covered with drawing objects.
1317 : Needed if the imported document is inserted as "OLE object from file"
1318 : and thus does not provide an OLE size property by itself. */
1319 25 : if( (maShapeBoundingBox.Width > 0) || (maShapeBoundingBox.Height > 0) )
1320 1 : extendUsedArea( getCellRangeFromRectangle( maShapeBoundingBox ) );
1321 :
1322 : // if no used area is set, default to A1
1323 25 : if( maUsedArea.StartColumn > maUsedArea.EndColumn )
1324 6 : maUsedArea.StartColumn = maUsedArea.EndColumn = 0;
1325 25 : if( maUsedArea.StartRow > maUsedArea.EndRow )
1326 6 : maUsedArea.StartRow = maUsedArea.EndRow = 0;
1327 :
1328 : /* Register the used area of this sheet in global view settings. The
1329 : global view settings will set the visible area if this document is an
1330 : embedded OLE object. */
1331 25 : getViewSettings().setSheetUsedArea( maUsedArea );
1332 :
1333 : /* #i103686# Set right-to-left sheet layout. Must be done after all
1334 : drawing shapes to simplify calculation of shape coordinates. */
1335 25 : if( maSheetViewSett.isSheetRightToLeft() )
1336 : {
1337 0 : PropertySet aPropSet( mxSheet );
1338 0 : aPropSet.setProperty( PROP_TableLayout, WritingMode2::RL_TB );
1339 25 : }
1340 25 : }
1341 :
1342 : // ============================================================================
1343 : // ============================================================================
1344 :
1345 229 : WorksheetHelper::WorksheetHelper( WorksheetGlobals& rSheetGlob ) :
1346 : WorkbookHelper( rSheetGlob ),
1347 229 : mrSheetGlob( rSheetGlob )
1348 : {
1349 229 : }
1350 :
1351 25 : /*static*/ WorksheetGlobalsRef WorksheetHelper::constructGlobals( const WorkbookHelper& rHelper,
1352 : const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet )
1353 : {
1354 25 : WorksheetGlobalsRef xSheetGlob( new WorksheetGlobals( rHelper, rxProgressBar, eSheetType, nSheet ) );
1355 25 : if( !xSheetGlob->isValidSheet() )
1356 0 : xSheetGlob.reset();
1357 25 : return xSheetGlob;
1358 : }
1359 :
1360 75 : WorksheetType WorksheetHelper::getSheetType() const
1361 : {
1362 75 : return mrSheetGlob.getSheetType();
1363 : }
1364 :
1365 217 : sal_Int16 WorksheetHelper::getSheetIndex() const
1366 : {
1367 217 : return mrSheetGlob.getSheetIndex();
1368 : }
1369 :
1370 87 : const Reference< XSpreadsheet >& WorksheetHelper::getSheet() const
1371 : {
1372 87 : return mrSheetGlob.getSheet();
1373 : }
1374 :
1375 3 : Reference< XCell > WorksheetHelper::getCell( const CellAddress& rAddress ) const
1376 : {
1377 3 : return mrSheetGlob.getCell( rAddress );
1378 : }
1379 :
1380 0 : Reference< XCellRange > WorksheetHelper::getCellRange( const CellRangeAddress& rRange ) const
1381 : {
1382 0 : return mrSheetGlob.getCellRange( rRange );
1383 : }
1384 :
1385 27 : Reference< XDrawPage > WorksheetHelper::getDrawPage() const
1386 : {
1387 27 : return mrSheetGlob.getDrawPage();
1388 : }
1389 :
1390 4 : awt::Point WorksheetHelper::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const
1391 : {
1392 4 : return mrSheetGlob.getCellPosition( nCol, nRow );
1393 : }
1394 :
1395 0 : awt::Size WorksheetHelper::getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const
1396 : {
1397 0 : return mrSheetGlob.getCellSize( nCol, nRow );
1398 : }
1399 :
1400 2 : awt::Size WorksheetHelper::getDrawPageSize() const
1401 : {
1402 2 : return mrSheetGlob.getDrawPageSize();
1403 : }
1404 :
1405 26 : SheetDataBuffer& WorksheetHelper::getSheetData() const
1406 : {
1407 26 : return mrSheetGlob.getSheetData();
1408 : }
1409 :
1410 28 : CondFormatBuffer& WorksheetHelper::getCondFormats() const
1411 : {
1412 28 : return mrSheetGlob.getCondFormats();
1413 : }
1414 :
1415 1 : CommentsBuffer& WorksheetHelper::getComments() const
1416 : {
1417 1 : return mrSheetGlob.getComments();
1418 : }
1419 :
1420 1 : AutoFilterBuffer& WorksheetHelper::getAutoFilters() const
1421 : {
1422 1 : return mrSheetGlob.getAutoFilters();
1423 : }
1424 :
1425 0 : QueryTableBuffer& WorksheetHelper::getQueryTables() const
1426 : {
1427 0 : return mrSheetGlob.getQueryTables();
1428 : }
1429 :
1430 20 : WorksheetSettings& WorksheetHelper::getWorksheetSettings() const
1431 : {
1432 20 : return mrSheetGlob.getWorksheetSettings();
1433 : }
1434 :
1435 137 : PageSettings& WorksheetHelper::getPageSettings() const
1436 : {
1437 137 : return mrSheetGlob.getPageSettings();
1438 : }
1439 :
1440 46 : SheetViewSettings& WorksheetHelper::getSheetViewSettings() const
1441 : {
1442 46 : return mrSheetGlob.getSheetViewSettings();
1443 : }
1444 :
1445 5 : VmlDrawing& WorksheetHelper::getVmlDrawing() const
1446 : {
1447 5 : return mrSheetGlob.getVmlDrawing();
1448 : }
1449 :
1450 0 : ExtLst& WorksheetHelper::getExtLst() const
1451 : {
1452 0 : return mrSheetGlob.getExtLst();
1453 : }
1454 :
1455 0 : void WorksheetHelper::setPageBreak( const PageBreakModel& rModel, bool bRowBreak )
1456 : {
1457 0 : mrSheetGlob.setPageBreak( rModel, bRowBreak );
1458 0 : }
1459 :
1460 0 : void WorksheetHelper::setHyperlink( const HyperlinkModel& rModel )
1461 : {
1462 0 : mrSheetGlob.setHyperlink( rModel );
1463 0 : }
1464 :
1465 0 : void WorksheetHelper::setValidation( const ValidationModel& rModel )
1466 : {
1467 0 : mrSheetGlob.setValidation( rModel );
1468 0 : }
1469 :
1470 2 : void WorksheetHelper::setDrawingPath( const OUString& rDrawingPath )
1471 : {
1472 2 : mrSheetGlob.setDrawingPath( rDrawingPath );
1473 2 : }
1474 :
1475 2 : void WorksheetHelper::setVmlDrawingPath( const OUString& rVmlDrawingPath )
1476 : {
1477 2 : mrSheetGlob.setVmlDrawingPath( rVmlDrawingPath );
1478 2 : }
1479 :
1480 691 : void WorksheetHelper::extendUsedArea( const CellAddress& rAddress )
1481 : {
1482 691 : mrSheetGlob.extendUsedArea( rAddress );
1483 691 : }
1484 :
1485 19 : void WorksheetHelper::extendUsedArea( const CellRangeAddress& rRange )
1486 : {
1487 19 : mrSheetGlob.extendUsedArea( rRange );
1488 19 : }
1489 :
1490 1 : void WorksheetHelper::extendShapeBoundingBox( const awt::Rectangle& rShapeRect )
1491 : {
1492 1 : mrSheetGlob.extendShapeBoundingBox( rShapeRect );
1493 1 : }
1494 :
1495 9 : void WorksheetHelper::setBaseColumnWidth( sal_Int32 nWidth )
1496 : {
1497 9 : mrSheetGlob.setBaseColumnWidth( nWidth );
1498 9 : }
1499 :
1500 9 : void WorksheetHelper::setDefaultColumnWidth( double fWidth )
1501 : {
1502 9 : mrSheetGlob.setDefaultColumnWidth( fWidth );
1503 9 : }
1504 :
1505 32 : void WorksheetHelper::setColumnModel( const ColumnModel& rModel )
1506 : {
1507 32 : mrSheetGlob.setColumnModel( rModel );
1508 32 : }
1509 :
1510 9 : void WorksheetHelper::setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom )
1511 : {
1512 9 : mrSheetGlob.setDefaultRowSettings( fHeight, bCustomHeight, bHidden, bThickTop, bThickBottom );
1513 9 : }
1514 :
1515 153 : void WorksheetHelper::setRowModel( const RowModel& rModel )
1516 : {
1517 153 : mrSheetGlob.setRowModel( rModel );
1518 153 : }
1519 :
1520 579 : void WorksheetHelper::putValue( const CellAddress& rAddress, double fValue ) const
1521 : {
1522 579 : ScAddress aAddress;
1523 579 : ScUnoConversion::FillScAddress( aAddress, rAddress );
1524 579 : getScDocument().SetValue( aAddress.Col(), aAddress.Row(), aAddress.Tab(), fValue );
1525 579 : }
1526 :
1527 23 : void WorksheetHelper::setCellFormulaValue( const ::com::sun::star::table::CellAddress& rAddress,
1528 : double fValue )
1529 : {
1530 23 : getFormulaBuffer().setCellFormulaValue( rAddress, fValue );
1531 23 : }
1532 :
1533 76 : void WorksheetHelper::putString( const CellAddress& rAddress, const OUString& rText ) const
1534 : {
1535 76 : ScAddress aAddress;
1536 76 : ScUnoConversion::FillScAddress( aAddress, rAddress );
1537 76 : ScBaseCell* pNewCell = NULL;
1538 76 : ScDocument& rDoc = getScDocument();
1539 76 : if ( !rText.isEmpty() )
1540 76 : pNewCell = ScBaseCell::CreateTextCell( rText, &rDoc );
1541 76 : if ( pNewCell )
1542 76 : rDoc.PutCell( aAddress, pNewCell );
1543 : else
1544 0 : rDoc.SetString( aAddress.Col(), aAddress.Row(), aAddress.Tab(), rText );
1545 76 : }
1546 :
1547 2 : void WorksheetHelper::putRichString( const CellAddress& rAddress, const RichString& rString, const Font* pFirstPortionFont ) const
1548 : {
1549 2 : Reference< XText > xText( getCell( rAddress ), UNO_QUERY );
1550 : OSL_ENSURE( xText.is(), "WorksheetHelper::putRichString - missing text interface" );
1551 : /* Passing false will always append the portions to the XText. This is
1552 : essential for special rich formatting attributes at the leading text
1553 : portion supported by edit cells only, e.g. font escapement. */
1554 2 : rString.convert( xText, false, pFirstPortionFont );
1555 2 : }
1556 :
1557 0 : void WorksheetHelper::putFormulaTokens( const CellAddress& rAddress, const ApiTokenSequence& rTokens ) const
1558 : {
1559 0 : ScDocument& rDoc = getScDocument();
1560 0 : ScTokenArray aTokenArray;
1561 0 : ScAddress aCellPos;
1562 0 : ScUnoConversion::FillScAddress( aCellPos, rAddress );
1563 0 : ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, rTokens );
1564 0 : ScBaseCell* pNewCell = new ScFormulaCell( &rDoc, aCellPos, &aTokenArray );
1565 0 : rDoc.PutCell( aCellPos, pNewCell, sal_True );
1566 0 : }
1567 :
1568 25 : void WorksheetHelper::initializeWorksheetImport()
1569 : {
1570 25 : mrSheetGlob.initializeWorksheetImport();
1571 25 : }
1572 :
1573 25 : void WorksheetHelper::finalizeWorksheetImport()
1574 : {
1575 25 : mrSheetGlob.finalizeWorksheetImport();
1576 25 : }
1577 :
1578 27 : void WorksheetHelper::setCellFormula( const ::com::sun::star::table::CellAddress& rTokenAddress, const rtl::OUString& rTokenStr )
1579 : {
1580 27 : getFormulaBuffer().setCellFormula( rTokenAddress, rTokenStr );
1581 27 : }
1582 :
1583 7 : void WorksheetHelper::setCellFormula( const ::com::sun::star::table::CellAddress& rTokenAddress, sal_Int32 nSharedId )
1584 : {
1585 7 : getFormulaBuffer().setCellFormula( rTokenAddress, nSharedId );
1586 7 : }
1587 :
1588 0 : void WorksheetHelper::setCellArrayFormula( const ::com::sun::star::table::CellRangeAddress& rRangeAddress, const ::com::sun::star::table::CellAddress& rTokenAddress, const rtl::OUString& rTokenStr )
1589 : {
1590 0 : getFormulaBuffer().setCellArrayFormula( rRangeAddress, rTokenAddress, rTokenStr );
1591 0 : }
1592 :
1593 1 : void WorksheetHelper::createSharedFormulaMapEntry( const ::com::sun::star::table::CellAddress& rAddress, sal_Int32 nSharedId, const rtl::OUString& rTokens )
1594 : {
1595 1 : getFormulaBuffer().createSharedFormulaMapEntry( rAddress, nSharedId, rTokens );
1596 1 : }
1597 :
1598 : // ============================================================================
1599 : // ============================================================================
1600 :
1601 : } // namespace xls
1602 9 : } // namespace oox
1603 :
1604 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|