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 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 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 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 123 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 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 152 void RowModel::insertColSpan( const ValueRange& rColSpan ) 153 { 154 if( (0 <= rColSpan.mnFirst) && (rColSpan.mnFirst <= rColSpan.mnLast) ) 155 maColSpans.insert( rColSpan ); 156 } 157 158 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 172 PageBreakModel::PageBreakModel() : 173 mnColRow( 0 ), 174 mbManual( false ) 175 { 176 } 177 178 // ---------------------------------------------------------------------------- 179 180 HyperlinkModel::HyperlinkModel() 181 { 182 } 183 184 // ---------------------------------------------------------------------------- 185 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 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 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 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. */ 231 inline bool isValidSheet() const { return mxSheet.is(); } 232 233 /** Returns the type of this sheet. */ 234 inline WorksheetType getSheetType() const { return meSheetType; } 235 /** Returns the index of the current sheet. */ 236 inline sal_Int16 getSheetIndex() const { return maUsedArea.Sheet; } 237 /** Returns the XSpreadsheet interface of the current sheet. */ 238 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. */ 273 inline SheetDataBuffer& getSheetData() { return maSheetData; } 274 /** Returns the conditional formattings in this sheet. */ 275 inline CondFormatBuffer& getCondFormats() { return maCondFormats; } 276 /** Returns the buffer for all cell comments in this sheet. */ 277 inline CommentsBuffer& getComments() { return maComments; } 278 /** Returns the auto filters for the sheet. */ 279 inline AutoFilterBuffer& getAutoFilters() { return maAutoFilters; } 280 /** Returns the buffer for all web query tables in this sheet. */ 281 inline QueryTableBuffer& getQueryTables() { return maQueryTables; } 282 /** Returns the worksheet settings object. */ 283 inline WorksheetSettings& getWorksheetSettings() { return maSheetSett; } 284 /** Returns the page/print settings for this sheet. */ 285 inline PageSettings& getPageSettings() { return maPageSett; } 286 /** Returns the view settings for this sheet. */ 287 inline SheetViewSettings& getSheetViewSettings() { return maSheetViewSett; } 288 /** Returns the VML drawing page for this sheet (OOXML/BIFF12 only). */ 289 inline VmlDrawing& getVmlDrawing() { return *mxVmlDrawing; } 290 /** Returns the BIFF drawing page for this sheet (BIFF2-BIFF8 only). */ 291 inline BiffSheetDrawing& getBiffDrawing() const { return *mxBiffDrawing; } 292 293 /** Changes the current sheet type. */ 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 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 476 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 489 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 502 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 517 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 532 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 547 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 560 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 573 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 586 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 592 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 600 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 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 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 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 677 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 713 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 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 742 void WorksheetGlobals::setHyperlink( const HyperlinkModel& rModel ) 743 { 744 maHyperlinks.push_back( rModel ); 745 } 746 747 void WorksheetGlobals::setValidation( const ValidationModel& rModel ) 748 { 749 maValidations.push_back( rModel ); 750 } 751 752 void WorksheetGlobals::setDrawingPath( const OUString& rDrawingPath ) 753 { 754 maDrawingPath = rDrawingPath; 755 } 756 757 void WorksheetGlobals::setVmlDrawingPath( const OUString& rVmlDrawingPath ) 758 { 759 maVmlDrawingPath = rVmlDrawingPath; 760 } 761 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 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 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 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 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 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 864 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 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 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 927 void WorksheetGlobals::setManualRowHeight( sal_Int32 nRow ) 928 { 929 maManualRowHeights.insert( nRow ); 930 } 931 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 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 970 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 983 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 1011 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 1065 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 // convert validation type to API enum 1077 ValidationType eType = ValidationType_ANY; 1078 switch( aIt->mnType ) 1079 { 1080 case XML_custom: eType = ValidationType_CUSTOM; break; 1081 case XML_date: eType = ValidationType_DATE; break; 1082 case XML_decimal: eType = ValidationType_DECIMAL; break; 1083 case XML_list: eType = ValidationType_LIST; break; 1084 case XML_none: eType = ValidationType_ANY; break; 1085 case XML_textLength: eType = ValidationType_TEXT_LEN; break; 1086 case XML_time: eType = ValidationType_TIME; break; 1087 case XML_whole: eType = ValidationType_WHOLE; break; 1088 default: OSL_ENSURE( false, "WorksheetGlobals::finalizeValidationRanges - unknown validation type" ); 1089 } 1090 aValProps.setProperty( PROP_Type, eType ); 1091 1092 // convert error alert style to API enum 1093 ValidationAlertStyle eAlertStyle = ValidationAlertStyle_STOP; 1094 switch( aIt->mnErrorStyle ) 1095 { 1096 case XML_information: eAlertStyle = ValidationAlertStyle_INFO; break; 1097 case XML_stop: eAlertStyle = ValidationAlertStyle_STOP; break; 1098 case XML_warning: eAlertStyle = ValidationAlertStyle_WARNING; break; 1099 default: OSL_ENSURE( false, "WorksheetGlobals::finalizeValidationRanges - unknown error style" ); 1100 } 1101 aValProps.setProperty( PROP_ErrorAlertStyle, eAlertStyle ); 1102 1103 // convert dropdown style to API visibility constants 1104 sal_Int16 nVisibility = aIt->mbNoDropDown ? TableValidationVisibility::INVISIBLE : TableValidationVisibility::UNSORTED; 1105 aValProps.setProperty( PROP_ShowList, nVisibility ); 1106 1107 // messages 1108 aValProps.setProperty( PROP_ShowInputMessage, aIt->mbShowInputMsg ); 1109 aValProps.setProperty( PROP_InputTitle, aIt->maInputTitle ); 1110 aValProps.setProperty( PROP_InputMessage, aIt->maInputMessage ); 1111 aValProps.setProperty( PROP_ShowErrorMessage, aIt->mbShowErrorMsg ); 1112 aValProps.setProperty( PROP_ErrorTitle, aIt->maErrorTitle ); 1113 aValProps.setProperty( PROP_ErrorMessage, aIt->maErrorMessage ); 1114 1115 // allow blank cells 1116 aValProps.setProperty( PROP_IgnoreBlankCells, aIt->mbAllowBlank ); 1117 1118 try 1119 { 1120 // condition operator 1121 Reference< XSheetCondition > xSheetCond( xValidation, UNO_QUERY_THROW ); 1122 xSheetCond->setOperator( CondFormatBuffer::convertToApiOperator( aIt->mnOperator ) ); 1123 1124 // condition formulas 1125 Reference< XMultiFormulaTokens > xTokens( xValidation, UNO_QUERY_THROW ); 1126 xTokens->setTokens( 0, aIt->maTokens1 ); 1127 xTokens->setTokens( 1, aIt->maTokens2 ); 1128 } 1129 catch( Exception& ) 1130 { 1131 } 1132 1133 // write back validation settings to cell range(s) 1134 aPropSet.setProperty( PROP_Validation, xValidation ); 1135 } 1136 } 1137 } 1138 1139 void WorksheetGlobals::convertColumns() 1140 { 1141 sal_Int32 nNextCol = 0; 1142 sal_Int32 nMaxCol = mrMaxApiPos.Column; 1143 // stores first grouped column index for each level 1144 OutlineLevelVec aColLevels; 1145 1146 for( ColumnModelRangeMap::iterator aIt = maColModels.begin(), aEnd = maColModels.end(); aIt != aEnd; ++aIt ) 1147 { 1148 // column indexes are stored 0-based in maColModels 1149 ValueRange aColRange( ::std::max( aIt->first, nNextCol ), ::std::min( aIt->second.second, nMaxCol ) ); 1150 // process gap between two column models, use default column model 1151 if( nNextCol < aColRange.mnFirst ) 1152 convertColumns( aColLevels, ValueRange( nNextCol, aColRange.mnFirst - 1 ), maDefColModel ); 1153 // process the column model 1154 convertColumns( aColLevels, aColRange, aIt->second.first ); 1155 // cache next column to be processed 1156 nNextCol = aColRange.mnLast + 1; 1157 } 1158 1159 // remaining default columns to end of sheet 1160 convertColumns( aColLevels, ValueRange( nNextCol, nMaxCol ), maDefColModel ); 1161 // close remaining column outlines spanning to end of sheet 1162 convertOutlines( aColLevels, nMaxCol + 1, 0, false, false ); 1163 } 1164 1165 void WorksheetGlobals::convertColumns( OutlineLevelVec& orColLevels, 1166 const ValueRange& rColRange, const ColumnModel& rModel ) 1167 { 1168 PropertySet aPropSet( getColumns( rColRange ) ); 1169 1170 // column width: convert 'number of characters' to column width in 1/100 mm 1171 sal_Int32 nWidth = getUnitConverter().scaleToMm100( rModel.mfWidth, UNIT_DIGIT ); 1172 // macro sheets have double width 1173 if( meSheetType == SHEETTYPE_MACROSHEET ) 1174 nWidth *= 2; 1175 if( nWidth > 0 ) 1176 aPropSet.setProperty( PROP_Width, nWidth ); 1177 1178 // hidden columns: TODO: #108683# hide columns later? 1179 if( rModel.mbHidden ) 1180 aPropSet.setProperty( PROP_IsVisible, false ); 1181 1182 // outline settings for this column range 1183 convertOutlines( orColLevels, rColRange.mnFirst, rModel.mnLevel, rModel.mbCollapsed, false ); 1184 } 1185 1186 void WorksheetGlobals::convertRows() 1187 { 1188 sal_Int32 nNextRow = 0; 1189 sal_Int32 nMaxRow = mrMaxApiPos.Row; 1190 // stores first grouped row index for each level 1191 OutlineLevelVec aRowLevels; 1192 1193 for( RowModelRangeMap::iterator aIt = maRowModels.begin(), aEnd = maRowModels.end(); aIt != aEnd; ++aIt ) 1194 { 1195 // row indexes are stored 0-based in maRowModels 1196 ValueRange aRowRange( ::std::max( aIt->first, nNextRow ), ::std::min( aIt->second.second, nMaxRow ) ); 1197 // process gap between two row models, use default row model 1198 if( nNextRow < aRowRange.mnFirst ) 1199 convertRows( aRowLevels, ValueRange( nNextRow, aRowRange.mnFirst - 1 ), maDefRowModel ); 1200 // process the row model 1201 convertRows( aRowLevels, aRowRange, aIt->second.first, maDefRowModel.mfHeight ); 1202 // cache next row to be processed 1203 nNextRow = aRowRange.mnLast + 1; 1204 } 1205 1206 // remaining default rows to end of sheet 1207 convertRows( aRowLevels, ValueRange( nNextRow, nMaxRow ), maDefRowModel ); 1208 // close remaining row outlines spanning to end of sheet 1209 convertOutlines( aRowLevels, nMaxRow + 1, 0, false, true ); 1210 } 1211 1212 void WorksheetGlobals::convertRows( OutlineLevelVec& orRowLevels, 1213 const ValueRange& rRowRange, const RowModel& rModel, double fDefHeight ) 1214 { 1215 // row height: convert points to row height in 1/100 mm 1216 double fHeight = (rModel.mfHeight >= 0.0) ? rModel.mfHeight : fDefHeight; 1217 sal_Int32 nHeight = getUnitConverter().scaleToMm100( fHeight, UNIT_POINT ); 1218 if( nHeight > 0 ) 1219 { 1220 /* Get all rows that have custom height inside the passed row model. 1221 If the model has the custom height flag set, all its rows have 1222 custom height, otherwise get all rows specified in the class member 1223 maManualRowHeights that are inside the passed row model. */ 1224 ValueRangeVector aManualRows; 1225 if( rModel.mbCustomHeight ) 1226 aManualRows.push_back( rRowRange ); 1227 else 1228 aManualRows = maManualRowHeights.getIntersection( rRowRange ); 1229 for( ValueRangeVector::const_iterator aIt = aManualRows.begin(), aEnd = aManualRows.end(); aIt != aEnd; ++aIt ) 1230 { 1231 PropertySet aPropSet( getRows( *aIt ) ); 1232 aPropSet.setProperty( PROP_Height, nHeight ); 1233 } 1234 } 1235 1236 // hidden rows: TODO: #108683# hide rows later? 1237 if( rModel.mbHidden ) 1238 { 1239 PropertySet aPropSet( getRows( rRowRange ) ); 1240 /* #i116460# Use VisibleFlag instead of IsVisible: directly set the 1241 flag, without drawing layer update etc. (only possible before 1242 shapes are inserted). */ 1243 aPropSet.setProperty( PROP_VisibleFlag, false ); 1244 } 1245 1246 // outline settings for this row range 1247 convertOutlines( orRowLevels, rRowRange.mnFirst, rModel.mnLevel, rModel.mbCollapsed, true ); 1248 } 1249 1250 void WorksheetGlobals::convertOutlines( OutlineLevelVec& orLevels, 1251 sal_Int32 nColRow, sal_Int32 nLevel, bool bCollapsed, bool bRows ) 1252 { 1253 /* It is ensured from caller functions, that this function is called 1254 without any gaps between the processed column or row ranges. */ 1255 1256 OSL_ENSURE( nLevel >= 0, "WorksheetGlobals::convertOutlines - negative outline level" ); 1257 nLevel = ::std::max< sal_Int32 >( nLevel, 0 ); 1258 1259 sal_Int32 nSize = orLevels.size(); 1260 if( nSize < nLevel ) 1261 { 1262 // Outline level increased. Push the begin column position. 1263 for( sal_Int32 nIndex = nSize; nIndex < nLevel; ++nIndex ) 1264 orLevels.push_back( nColRow ); 1265 } 1266 else if( nLevel < nSize ) 1267 { 1268 // Outline level decreased. Pop them all out. 1269 for( sal_Int32 nIndex = nLevel; nIndex < nSize; ++nIndex ) 1270 { 1271 sal_Int32 nFirstInLevel = orLevels.back(); 1272 orLevels.pop_back(); 1273 groupColumnsOrRows( nFirstInLevel, nColRow - 1, bCollapsed, bRows ); 1274 bCollapsed = false; // collapse only once 1275 } 1276 } 1277 } 1278 1279 void WorksheetGlobals::groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastColRow, bool bCollapse, bool bRows ) 1280 { 1281 try 1282 { 1283 Reference< XSheetOutline > xOutline( mxSheet, UNO_QUERY_THROW ); 1284 if( bRows ) 1285 { 1286 CellRangeAddress aRange( getSheetIndex(), 0, nFirstColRow, 0, nLastColRow ); 1287 xOutline->group( aRange, TableOrientation_ROWS ); 1288 if( bCollapse ) 1289 xOutline->hideDetail( aRange ); 1290 } 1291 else 1292 { 1293 CellRangeAddress aRange( getSheetIndex(), nFirstColRow, 0, nLastColRow, 0 ); 1294 xOutline->group( aRange, TableOrientation_COLUMNS ); 1295 if( bCollapse ) 1296 xOutline->hideDetail( aRange ); 1297 } 1298 } 1299 catch( Exception& ) 1300 { 1301 } 1302 } 1303 1304 void WorksheetGlobals::finalizeDrawings() 1305 { 1306 // calculate the current drawing page size (after rows/columns are imported) 1307 PropertySet aRangeProp( getCellRange( CellRangeAddress( getSheetIndex(), 0, 0, mrMaxApiPos.Column, mrMaxApiPos.Row ) ) ); 1308 aRangeProp.getProperty( maDrawPageSize, PROP_Size ); 1309 1310 switch( getFilterType() ) 1311 { 1312 case FILTER_OOXML: 1313 // import DML and VML 1314 if( maDrawingPath.getLength() > 0 ) 1315 importOoxFragment( new DrawingFragment( *this, maDrawingPath ) ); 1316 if( maVmlDrawingPath.getLength() > 0 ) 1317 importOoxFragment( new VmlDrawingFragment( *this, maVmlDrawingPath ) ); 1318 break; 1319 1320 case FILTER_BIFF: 1321 // convert BIFF3-BIFF5 drawing objects, or import and convert DFF stream 1322 getBiffDrawing().finalizeImport(); 1323 break; 1324 1325 case FILTER_UNKNOWN: 1326 break; 1327 } 1328 1329 // comments (after callout shapes have been imported from VML/DFF) 1330 maComments.finalizeImport(); 1331 1332 /* Extend used area of the sheet by cells covered with drawing objects. 1333 Needed if the imported document is inserted as "OLE object from file" 1334 and thus does not provide an OLE size property by itself. */ 1335 if( (maShapeBoundingBox.Width > 0) || (maShapeBoundingBox.Height > 0) ) 1336 extendUsedArea( getCellRangeFromRectangle( maShapeBoundingBox ) ); 1337 1338 // if no used area is set, default to A1 1339 if( maUsedArea.StartColumn > maUsedArea.EndColumn ) 1340 maUsedArea.StartColumn = maUsedArea.EndColumn = 0; 1341 if( maUsedArea.StartRow > maUsedArea.EndRow ) 1342 maUsedArea.StartRow = maUsedArea.EndRow = 0; 1343 1344 /* Register the used area of this sheet in global view settings. The 1345 global view settings will set the visible area if this document is an 1346 embedded OLE object. */ 1347 getViewSettings().setSheetUsedArea( maUsedArea ); 1348 1349 /* #i103686# Set right-to-left sheet layout. Must be done after all 1350 drawing shapes to simplify calculation of shape coordinates. */ 1351 if( maSheetViewSett.isSheetRightToLeft() ) 1352 { 1353 PropertySet aPropSet( mxSheet ); 1354 aPropSet.setProperty( PROP_TableLayout, WritingMode2::RL_TB ); 1355 } 1356 } 1357 1358 // ============================================================================ 1359 // ============================================================================ 1360 1361 WorksheetHelper::WorksheetHelper( WorksheetGlobals& rSheetGlob ) : 1362 WorkbookHelper( rSheetGlob ), 1363 mrSheetGlob( rSheetGlob ) 1364 { 1365 } 1366 1367 /*static*/ WorksheetGlobalsRef WorksheetHelper::constructGlobals( const WorkbookHelper& rHelper, 1368 const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) 1369 { 1370 WorksheetGlobalsRef xSheetGlob( new WorksheetGlobals( rHelper, rxProgressBar, eSheetType, nSheet ) ); 1371 if( !xSheetGlob->isValidSheet() ) 1372 xSheetGlob.reset(); 1373 return xSheetGlob; 1374 } 1375 1376 WorksheetType WorksheetHelper::getSheetType() const 1377 { 1378 return mrSheetGlob.getSheetType(); 1379 } 1380 1381 sal_Int16 WorksheetHelper::getSheetIndex() const 1382 { 1383 return mrSheetGlob.getSheetIndex(); 1384 } 1385 1386 const Reference< XSpreadsheet >& WorksheetHelper::getSheet() const 1387 { 1388 return mrSheetGlob.getSheet(); 1389 } 1390 1391 Reference< XCell > WorksheetHelper::getCell( const CellAddress& rAddress ) const 1392 { 1393 return mrSheetGlob.getCell( rAddress ); 1394 } 1395 1396 Reference< XCellRange > WorksheetHelper::getCellRange( const CellRangeAddress& rRange ) const 1397 { 1398 return mrSheetGlob.getCellRange( rRange ); 1399 } 1400 1401 Reference< XSheetCellRanges > WorksheetHelper::getCellRangeList( const ApiCellRangeList& rRanges ) const 1402 { 1403 return mrSheetGlob.getCellRangeList( rRanges ); 1404 } 1405 1406 CellAddress WorksheetHelper::getCellAddress( const Reference< XCell >& rxCell ) 1407 { 1408 CellAddress aAddress; 1409 Reference< XCellAddressable > xAddressable( rxCell, UNO_QUERY ); 1410 OSL_ENSURE( xAddressable.is(), "WorksheetHelper::getCellAddress - cell reference not addressable" ); 1411 if( xAddressable.is() ) 1412 aAddress = xAddressable->getCellAddress(); 1413 return aAddress; 1414 } 1415 1416 CellRangeAddress WorksheetHelper::getRangeAddress( const Reference< XCellRange >& rxRange ) 1417 { 1418 CellRangeAddress aRange; 1419 Reference< XCellRangeAddressable > xAddressable( rxRange, UNO_QUERY ); 1420 OSL_ENSURE( xAddressable.is(), "WorksheetHelper::getRangeAddress - cell range reference not addressable" ); 1421 if( xAddressable.is() ) 1422 aRange = xAddressable->getRangeAddress(); 1423 return aRange; 1424 } 1425 1426 Reference< XCellRange > WorksheetHelper::getColumn( sal_Int32 nCol ) const 1427 { 1428 return mrSheetGlob.getColumn( nCol ); 1429 } 1430 1431 Reference< XCellRange > WorksheetHelper::getRow( sal_Int32 nRow ) const 1432 { 1433 return mrSheetGlob.getRow( nRow ); 1434 } 1435 1436 Reference< XTableColumns > WorksheetHelper::getColumns( const ValueRange& rColRange ) const 1437 { 1438 return mrSheetGlob.getColumns( rColRange ); 1439 } 1440 1441 Reference< XTableRows > WorksheetHelper::getRows( const ValueRange& rRowRange ) const 1442 { 1443 return mrSheetGlob.getRows( rRowRange ); 1444 } 1445 1446 Reference< XDrawPage > WorksheetHelper::getDrawPage() const 1447 { 1448 return mrSheetGlob.getDrawPage(); 1449 } 1450 1451 Point WorksheetHelper::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const 1452 { 1453 return mrSheetGlob.getCellPosition( nCol, nRow ); 1454 } 1455 1456 Size WorksheetHelper::getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const 1457 { 1458 return mrSheetGlob.getCellSize( nCol, nRow ); 1459 } 1460 1461 Size WorksheetHelper::getDrawPageSize() const 1462 { 1463 return mrSheetGlob.getDrawPageSize(); 1464 } 1465 1466 SheetDataBuffer& WorksheetHelper::getSheetData() const 1467 { 1468 return mrSheetGlob.getSheetData(); 1469 } 1470 1471 CondFormatBuffer& WorksheetHelper::getCondFormats() const 1472 { 1473 return mrSheetGlob.getCondFormats(); 1474 } 1475 1476 CommentsBuffer& WorksheetHelper::getComments() const 1477 { 1478 return mrSheetGlob.getComments(); 1479 } 1480 1481 AutoFilterBuffer& WorksheetHelper::getAutoFilters() const 1482 { 1483 return mrSheetGlob.getAutoFilters(); 1484 } 1485 1486 QueryTableBuffer& WorksheetHelper::getQueryTables() const 1487 { 1488 return mrSheetGlob.getQueryTables(); 1489 } 1490 1491 WorksheetSettings& WorksheetHelper::getWorksheetSettings() const 1492 { 1493 return mrSheetGlob.getWorksheetSettings(); 1494 } 1495 1496 PageSettings& WorksheetHelper::getPageSettings() const 1497 { 1498 return mrSheetGlob.getPageSettings(); 1499 } 1500 1501 SheetViewSettings& WorksheetHelper::getSheetViewSettings() const 1502 { 1503 return mrSheetGlob.getSheetViewSettings(); 1504 } 1505 1506 VmlDrawing& WorksheetHelper::getVmlDrawing() const 1507 { 1508 return mrSheetGlob.getVmlDrawing(); 1509 } 1510 1511 BiffSheetDrawing& WorksheetHelper::getBiffDrawing() const 1512 { 1513 return mrSheetGlob.getBiffDrawing(); 1514 } 1515 1516 void WorksheetHelper::setSheetType( WorksheetType eSheetType ) 1517 { 1518 mrSheetGlob.setSheetType( eSheetType ); 1519 } 1520 1521 void WorksheetHelper::setPageBreak( const PageBreakModel& rModel, bool bRowBreak ) 1522 { 1523 mrSheetGlob.setPageBreak( rModel, bRowBreak ); 1524 } 1525 1526 void WorksheetHelper::setHyperlink( const HyperlinkModel& rModel ) 1527 { 1528 mrSheetGlob.setHyperlink( rModel ); 1529 } 1530 1531 void WorksheetHelper::setValidation( const ValidationModel& rModel ) 1532 { 1533 mrSheetGlob.setValidation( rModel ); 1534 } 1535 1536 void WorksheetHelper::setLabelRanges( const ApiCellRangeList& rColRanges, const ApiCellRangeList& rRowRanges ) 1537 { 1538 const CellAddress& rMaxPos = getAddressConverter().getMaxApiAddress(); 1539 PropertySet aPropSet( getSheet() ); 1540 1541 if( !rColRanges.empty() ) 1542 { 1543 Reference< XLabelRanges > xLabelRanges( aPropSet.getAnyProperty( PROP_ColumnLabelRanges ), UNO_QUERY ); 1544 if( xLabelRanges.is() ) 1545 { 1546 for( ApiCellRangeList::const_iterator aIt = rColRanges.begin(), aEnd = rColRanges.end(); aIt != aEnd; ++aIt ) 1547 { 1548 CellRangeAddress aDataRange = *aIt; 1549 if( aDataRange.EndRow < rMaxPos.Row ) 1550 { 1551 aDataRange.StartRow = aDataRange.EndRow + 1; 1552 aDataRange.EndRow = rMaxPos.Row; 1553 } 1554 else if( aDataRange.StartRow > 0 ) 1555 { 1556 aDataRange.EndRow = aDataRange.StartRow - 1; 1557 aDataRange.StartRow = 0; 1558 } 1559 xLabelRanges->addNew( *aIt, aDataRange ); 1560 } 1561 } 1562 } 1563 1564 if( !rRowRanges.empty() ) 1565 { 1566 Reference< XLabelRanges > xLabelRanges( aPropSet.getAnyProperty( PROP_RowLabelRanges ), UNO_QUERY ); 1567 if( xLabelRanges.is() ) 1568 { 1569 for( ApiCellRangeList::const_iterator aIt = rRowRanges.begin(), aEnd = rRowRanges.end(); aIt != aEnd; ++aIt ) 1570 { 1571 CellRangeAddress aDataRange = *aIt; 1572 if( aDataRange.EndColumn < rMaxPos.Column ) 1573 { 1574 aDataRange.StartColumn = aDataRange.EndColumn + 1; 1575 aDataRange.EndColumn = rMaxPos.Column; 1576 } 1577 else if( aDataRange.StartColumn > 0 ) 1578 { 1579 aDataRange.EndColumn = aDataRange.StartColumn - 1; 1580 aDataRange.StartColumn = 0; 1581 } 1582 xLabelRanges->addNew( *aIt, aDataRange ); 1583 } 1584 } 1585 } 1586 } 1587 1588 void WorksheetHelper::setDrawingPath( const OUString& rDrawingPath ) 1589 { 1590 mrSheetGlob.setDrawingPath( rDrawingPath ); 1591 } 1592 1593 void WorksheetHelper::setVmlDrawingPath( const OUString& rVmlDrawingPath ) 1594 { 1595 mrSheetGlob.setVmlDrawingPath( rVmlDrawingPath ); 1596 } 1597 1598 void WorksheetHelper::extendUsedArea( const CellAddress& rAddress ) 1599 { 1600 mrSheetGlob.extendUsedArea( rAddress ); 1601 } 1602 1603 void WorksheetHelper::extendUsedArea( const CellRangeAddress& rRange ) 1604 { 1605 mrSheetGlob.extendUsedArea( rRange ); 1606 } 1607 1608 void WorksheetHelper::extendShapeBoundingBox( const Rectangle& rShapeRect ) 1609 { 1610 mrSheetGlob.extendShapeBoundingBox( rShapeRect ); 1611 } 1612 1613 void WorksheetHelper::setBaseColumnWidth( sal_Int32 nWidth ) 1614 { 1615 mrSheetGlob.setBaseColumnWidth( nWidth ); 1616 } 1617 1618 void WorksheetHelper::setDefaultColumnWidth( double fWidth ) 1619 { 1620 mrSheetGlob.setDefaultColumnWidth( fWidth ); 1621 } 1622 1623 void WorksheetHelper::setDefaultColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) 1624 { 1625 mrSheetGlob.convertColumnFormat( nFirstCol, nLastCol, nXfId ); 1626 } 1627 1628 void WorksheetHelper::setColumnModel( const ColumnModel& rModel ) 1629 { 1630 mrSheetGlob.setColumnModel( rModel ); 1631 } 1632 1633 void WorksheetHelper::setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom ) 1634 { 1635 mrSheetGlob.setDefaultRowSettings( fHeight, bCustomHeight, bHidden, bThickTop, bThickBottom ); 1636 } 1637 1638 void WorksheetHelper::setRowModel( const RowModel& rModel ) 1639 { 1640 mrSheetGlob.setRowModel( rModel ); 1641 } 1642 1643 void WorksheetHelper::setManualRowHeight( sal_Int32 nRow ) 1644 { 1645 mrSheetGlob.setManualRowHeight( nRow ); 1646 } 1647 1648 void WorksheetHelper::putValue( const CellAddress& rAddress, double fValue ) const 1649 { 1650 Reference< XCell > xCell = getCell( rAddress ); 1651 OSL_ENSURE( xCell.is(), "WorksheetHelper::putValue - missing cell interface" ); 1652 if( xCell.is() ) xCell->setValue( fValue ); 1653 } 1654 1655 void WorksheetHelper::putString( const CellAddress& rAddress, const OUString& rText ) const 1656 { 1657 Reference< XText > xText( getCell( rAddress ), UNO_QUERY ); 1658 OSL_ENSURE( xText.is(), "WorksheetHelper::putString - missing text interface" ); 1659 if( xText.is() ) xText->setString( rText ); 1660 } 1661 1662 void WorksheetHelper::putRichString( const CellAddress& rAddress, const RichString& rString, const Font* pFirstPortionFont ) const 1663 { 1664 Reference< XText > xText( getCell( rAddress ), UNO_QUERY ); 1665 OSL_ENSURE( xText.is(), "WorksheetHelper::putRichString - missing text interface" ); 1666 /* Passing false will always append the portions to the XText. This is 1667 essential for special rich formatting attributes at the leading text 1668 portion supported by edit cells only, e.g. font escapement. */ 1669 rString.convert( xText, false, pFirstPortionFont ); 1670 } 1671 1672 void WorksheetHelper::putFormulaTokens( const CellAddress& rAddress, const ApiTokenSequence& rTokens ) const 1673 { 1674 Reference< XFormulaTokens > xTokens( getCell( rAddress ), UNO_QUERY ); 1675 OSL_ENSURE( xTokens.is(), "WorksheetHelper::putFormulaTokens - missing token interface" ); 1676 if( xTokens.is() ) xTokens->setTokens( rTokens ); 1677 } 1678 1679 void WorksheetHelper::initializeWorksheetImport() 1680 { 1681 mrSheetGlob.initializeWorksheetImport(); 1682 } 1683 1684 void WorksheetHelper::finalizeWorksheetImport() 1685 { 1686 mrSheetGlob.finalizeWorksheetImport(); 1687 } 1688 1689 // ============================================================================ 1690 // ============================================================================ 1691 1692 } // namespace xls 1693 } // namespace oox 1694