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