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 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 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 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 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 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 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 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 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 1381 WorksheetHelper::WorksheetHelper( WorksheetGlobals& rSheetGlob ) : 1382 WorkbookHelper( rSheetGlob ), 1383 mrSheetGlob( rSheetGlob ) 1384 { 1385 } 1386 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 1396 WorksheetType WorksheetHelper::getSheetType() const 1397 { 1398 return mrSheetGlob.getSheetType(); 1399 } 1400 1401 sal_Int16 WorksheetHelper::getSheetIndex() const 1402 { 1403 return mrSheetGlob.getSheetIndex(); 1404 } 1405 1406 const Reference< XSpreadsheet >& WorksheetHelper::getSheet() const 1407 { 1408 return mrSheetGlob.getSheet(); 1409 } 1410 1411 Reference< XCell > WorksheetHelper::getCell( const CellAddress& rAddress ) const 1412 { 1413 return mrSheetGlob.getCell( rAddress ); 1414 } 1415 1416 Reference< XCellRange > WorksheetHelper::getCellRange( const CellRangeAddress& rRange ) const 1417 { 1418 return mrSheetGlob.getCellRange( rRange ); 1419 } 1420 1421 Reference< XSheetCellRanges > WorksheetHelper::getCellRangeList( const ApiCellRangeList& rRanges ) const 1422 { 1423 return mrSheetGlob.getCellRangeList( rRanges ); 1424 } 1425 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 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 1446 Reference< XCellRange > WorksheetHelper::getColumn( sal_Int32 nCol ) const 1447 { 1448 return mrSheetGlob.getColumn( nCol ); 1449 } 1450 1451 Reference< XCellRange > WorksheetHelper::getRow( sal_Int32 nRow ) const 1452 { 1453 return mrSheetGlob.getRow( nRow ); 1454 } 1455 1456 Reference< XTableColumns > WorksheetHelper::getColumns( const ValueRange& rColRange ) const 1457 { 1458 return mrSheetGlob.getColumns( rColRange ); 1459 } 1460 1461 Reference< XTableRows > WorksheetHelper::getRows( const ValueRange& rRowRange ) const 1462 { 1463 return mrSheetGlob.getRows( rRowRange ); 1464 } 1465 1466 Reference< XDrawPage > WorksheetHelper::getDrawPage() const 1467 { 1468 return mrSheetGlob.getDrawPage(); 1469 } 1470 1471 Point WorksheetHelper::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const 1472 { 1473 return mrSheetGlob.getCellPosition( nCol, nRow ); 1474 } 1475 1476 Size WorksheetHelper::getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const 1477 { 1478 return mrSheetGlob.getCellSize( nCol, nRow ); 1479 } 1480 1481 Size WorksheetHelper::getDrawPageSize() const 1482 { 1483 return mrSheetGlob.getDrawPageSize(); 1484 } 1485 1486 SheetDataBuffer& WorksheetHelper::getSheetData() const 1487 { 1488 return mrSheetGlob.getSheetData(); 1489 } 1490 1491 CondFormatBuffer& WorksheetHelper::getCondFormats() const 1492 { 1493 return mrSheetGlob.getCondFormats(); 1494 } 1495 1496 CommentsBuffer& WorksheetHelper::getComments() const 1497 { 1498 return mrSheetGlob.getComments(); 1499 } 1500 1501 AutoFilterBuffer& WorksheetHelper::getAutoFilters() const 1502 { 1503 return mrSheetGlob.getAutoFilters(); 1504 } 1505 1506 QueryTableBuffer& WorksheetHelper::getQueryTables() const 1507 { 1508 return mrSheetGlob.getQueryTables(); 1509 } 1510 1511 WorksheetSettings& WorksheetHelper::getWorksheetSettings() const 1512 { 1513 return mrSheetGlob.getWorksheetSettings(); 1514 } 1515 1516 PageSettings& WorksheetHelper::getPageSettings() const 1517 { 1518 return mrSheetGlob.getPageSettings(); 1519 } 1520 1521 SheetViewSettings& WorksheetHelper::getSheetViewSettings() const 1522 { 1523 return mrSheetGlob.getSheetViewSettings(); 1524 } 1525 1526 VmlDrawing& WorksheetHelper::getVmlDrawing() const 1527 { 1528 return mrSheetGlob.getVmlDrawing(); 1529 } 1530 1531 BiffSheetDrawing& WorksheetHelper::getBiffDrawing() const 1532 { 1533 return mrSheetGlob.getBiffDrawing(); 1534 } 1535 1536 void WorksheetHelper::setSheetType( WorksheetType eSheetType ) 1537 { 1538 mrSheetGlob.setSheetType( eSheetType ); 1539 } 1540 1541 void WorksheetHelper::setPageBreak( const PageBreakModel& rModel, bool bRowBreak ) 1542 { 1543 mrSheetGlob.setPageBreak( rModel, bRowBreak ); 1544 } 1545 1546 void WorksheetHelper::setHyperlink( const HyperlinkModel& rModel ) 1547 { 1548 mrSheetGlob.setHyperlink( rModel ); 1549 } 1550 1551 void WorksheetHelper::setValidation( const ValidationModel& rModel ) 1552 { 1553 mrSheetGlob.setValidation( rModel ); 1554 } 1555 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 1608 void WorksheetHelper::setDrawingPath( const OUString& rDrawingPath ) 1609 { 1610 mrSheetGlob.setDrawingPath( rDrawingPath ); 1611 } 1612 1613 void WorksheetHelper::setVmlDrawingPath( const OUString& rVmlDrawingPath ) 1614 { 1615 mrSheetGlob.setVmlDrawingPath( rVmlDrawingPath ); 1616 } 1617 1618 void WorksheetHelper::extendUsedArea( const CellAddress& rAddress ) 1619 { 1620 mrSheetGlob.extendUsedArea( rAddress ); 1621 } 1622 1623 void WorksheetHelper::extendUsedArea( const CellRangeAddress& rRange ) 1624 { 1625 mrSheetGlob.extendUsedArea( rRange ); 1626 } 1627 1628 void WorksheetHelper::extendShapeBoundingBox( const Rectangle& rShapeRect ) 1629 { 1630 mrSheetGlob.extendShapeBoundingBox( rShapeRect ); 1631 } 1632 1633 void WorksheetHelper::setBaseColumnWidth( sal_Int32 nWidth ) 1634 { 1635 mrSheetGlob.setBaseColumnWidth( nWidth ); 1636 } 1637 1638 void WorksheetHelper::setDefaultColumnWidth( double fWidth ) 1639 { 1640 mrSheetGlob.setDefaultColumnWidth( fWidth ); 1641 } 1642 1643 void WorksheetHelper::setDefaultColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) 1644 { 1645 mrSheetGlob.convertColumnFormat( nFirstCol, nLastCol, nXfId ); 1646 } 1647 1648 void WorksheetHelper::setColumnModel( const ColumnModel& rModel ) 1649 { 1650 mrSheetGlob.setColumnModel( rModel ); 1651 } 1652 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 1658 void WorksheetHelper::setRowModel( const RowModel& rModel ) 1659 { 1660 mrSheetGlob.setRowModel( rModel ); 1661 } 1662 1663 void WorksheetHelper::setManualRowHeight( sal_Int32 nRow ) 1664 { 1665 mrSheetGlob.setManualRowHeight( nRow ); 1666 } 1667 1668 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 1675 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 1682 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 1692 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 1699 void WorksheetHelper::initializeWorksheetImport() 1700 { 1701 mrSheetGlob.initializeWorksheetImport(); 1702 } 1703 1704 void WorksheetHelper::finalizeWorksheetImport() 1705 { 1706 mrSheetGlob.finalizeWorksheetImport(); 1707 } 1708 1709 // ============================================================================ 1710 // ============================================================================ 1711 1712 } // namespace xls 1713 } // namespace oox 1714