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