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