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