LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/filter/oox - worksheethelper.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 439 685 64.1 %
Date: 2013-07-09 Functions: 94 123 76.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10