diff options
Diffstat (limited to 'oox/source/xls/worksheethelper.cxx')
-rw-r--r-- | oox/source/xls/worksheethelper.cxx | 1316 |
1 files changed, 358 insertions, 958 deletions
diff --git a/oox/source/xls/worksheethelper.cxx b/oox/source/xls/worksheethelper.cxx index 48ffac388cfd..69d17b47a570 100644 --- a/oox/source/xls/worksheethelper.cxx +++ b/oox/source/xls/worksheethelper.cxx @@ -42,7 +42,6 @@ #include <com/sun/star/sheet/XFormulaTokens.hpp> #include <com/sun/star/sheet/XLabelRanges.hpp> #include <com/sun/star/sheet/XMultiFormulaTokens.hpp> -#include <com/sun/star/sheet/XMultipleOperation.hpp> #include <com/sun/star/sheet/XSheetCellRangeContainer.hpp> #include <com/sun/star/sheet/XSheetCondition.hpp> #include <com/sun/star/sheet/XSheetOutline.hpp> @@ -50,24 +49,20 @@ #include <com/sun/star/table/XColumnRowRange.hpp> #include <com/sun/star/text/WritingMode2.hpp> #include <com/sun/star/text/XText.hpp> -#include <com/sun/star/util/NumberFormat.hpp> -#include <com/sun/star/util/XMergeable.hpp> -#include <com/sun/star/util/XNumberFormatTypes.hpp> -#include <com/sun/star/util/XNumberFormatsSupplier.hpp> #include <rtl/ustrbuf.hxx> #include "oox/core/filterbase.hxx" -#include "oox/helper/containerhelper.hxx" #include "oox/helper/propertyset.hxx" #include "oox/xls/addressconverter.hxx" #include "oox/xls/autofilterbuffer.hxx" #include "oox/xls/commentsbuffer.hxx" #include "oox/xls/condformatbuffer.hxx" #include "oox/xls/drawingfragment.hxx" +#include "oox/xls/drawingmanager.hxx" #include "oox/xls/formulaparser.hxx" #include "oox/xls/pagesettings.hxx" #include "oox/xls/querytablebuffer.hxx" -#include "oox/xls/sharedformulabuffer.hxx" #include "oox/xls/sharedstringsbuffer.hxx" +#include "oox/xls/sheetdatabuffer.hxx" #include "oox/xls/stylesbuffer.hxx" #include "oox/xls/unitconverter.hxx" #include "oox/xls/viewsettings.hxx" @@ -113,107 +108,13 @@ void lclUpdateProgressBar( const ISegmentProgressBarRef& rxProgressBar, double f rxProgressBar->setPosition( fPosition ); } -// ---------------------------------------------------------------------------- - -struct ValueRange -{ - sal_Int32 mnFirst; - sal_Int32 mnLast; - - inline explicit ValueRange( sal_Int32 nValue ) : mnFirst( nValue ), mnLast( nValue ) {} - inline explicit ValueRange( sal_Int32 nFirst, sal_Int32 nLast ) : mnFirst( nFirst ), mnLast( nLast ) {} -}; - -typedef ::std::vector< ValueRange > ValueRangeVector; - -// ---------------------------------------------------------------------------- - -struct ValueRangeComp -{ - inline bool operator()( const ValueRange& rRange, sal_Int32 nValue ) const { return rRange.mnLast < nValue; } -}; - -typedef ::std::vector< ValueRange > ValueRangeVector; - -// ---------------------------------------------------------------------------- - -class ValueRangeSet -{ -public: - inline explicit ValueRangeSet() {} - - void insert( sal_Int32 nValue ); - void intersect( ValueRangeVector& orRanges, sal_Int32 nFirst, sal_Int32 nLast ) const; - -private: - ValueRangeVector maData; -}; - -void ValueRangeSet::insert( sal_Int32 nValue ) -{ - // find the first range that contains nValue or that follows nValue - ValueRangeVector::iterator aBeg = maData.begin(); - ValueRangeVector::iterator aEnd = maData.end(); - ValueRangeVector::iterator aNext = ::std::lower_bound( aBeg, aEnd, nValue, ValueRangeComp() ); - - // nothing to do if found range contains nValue - if( (aNext == aEnd) || (nValue < aNext->mnFirst) ) - { - ValueRangeVector::iterator aPrev = (aNext == aBeg) ? aEnd : (aNext - 1); - bool bJoinPrev = (aPrev != aEnd) && (aPrev->mnLast + 1 == nValue); - bool bJoinNext = (aNext != aEnd) && (aNext->mnFirst - 1 == nValue); - if( bJoinPrev && bJoinNext ) - { - aPrev->mnLast = aNext->mnLast; - maData.erase( aNext ); - } - else if( bJoinPrev ) - ++aPrev->mnLast; - else if( bJoinNext ) - --aNext->mnFirst; - else - maData.insert( aNext, ValueRange( nValue ) ); - } -} - -void ValueRangeSet::intersect( ValueRangeVector& orRanges, sal_Int32 nFirst, sal_Int32 nLast ) const -{ - orRanges.clear(); - // find the range that contains nFirst or the first range that follows nFirst - ValueRangeVector::const_iterator aIt = ::std::lower_bound( maData.begin(), maData.end(), nFirst, ValueRangeComp() ); - for( ValueRangeVector::const_iterator aEnd = maData.end(); (aIt != aEnd) && (aIt->mnFirst <= nLast); ++aIt ) - orRanges.push_back( ValueRange( ::std::max( aIt->mnFirst, nFirst ), ::std::min( aIt->mnLast, nLast ) ) ); -} - } // namespace // ============================================================================ // ============================================================================ -void CellModel::reset() -{ - mxCell.clear(); - maValueStr = maFormulaRef = OUString(); - mnCellType = mnFormulaType = XML_TOKEN_INVALID; - mnSharedId = mnXfId = mnNumFmtId = -1; - mbHasValueStr = mbShowPhonetic = false; -} - -// ---------------------------------------------------------------------------- - -DataTableModel::DataTableModel() : - mb2dTable( false ), - mbRowTable( false ), - mbRef1Deleted( false ), - mbRef2Deleted( false ) -{ -} - -// ---------------------------------------------------------------------------- - ColumnModel::ColumnModel() : - mnFirstCol( -1 ), - mnLastCol( -1 ), + maRange( -1 ), mfWidth( 0.0 ), mnXfId( -1 ), mnLevel( 0 ), @@ -223,27 +124,22 @@ ColumnModel::ColumnModel() : { } -bool ColumnModel::tryExpand( const ColumnModel& rModel ) +bool ColumnModel::isMergeable( const ColumnModel& rModel ) const { - bool bExpandable = - (mnFirstCol <= rModel.mnFirstCol) && - (rModel.mnFirstCol <= mnLastCol + 1) && - (mfWidth == rModel.mfWidth) && + return + (maRange.mnFirst <= rModel.maRange.mnFirst) && + (rModel.maRange.mnFirst <= maRange.mnLast + 1) && + (mfWidth == rModel.mfWidth) && // ignore mnXfId, cell formatting is always set directly - (mnLevel == rModel.mnLevel) && - (mbHidden == rModel.mbHidden) && - (mbCollapsed == rModel.mbCollapsed); - - if( bExpandable ) - mnLastCol = rModel.mnLastCol; - return bExpandable; + (mnLevel == rModel.mnLevel) && + (mbHidden == rModel.mbHidden) && + (mbCollapsed == rModel.mbCollapsed); } // ---------------------------------------------------------------------------- RowModel::RowModel() : - mnFirstRow( -1 ), - mnLastRow( -1 ), + mnRow( -1 ), mfHeight( 0.0 ), mnXfId( -1 ), mnLevel( 0 ), @@ -257,21 +153,22 @@ RowModel::RowModel() : { } -bool RowModel::tryExpand( const RowModel& rModel ) +void RowModel::insertColSpan( const ValueRange& rColSpan ) { - bool bExpandable = - (mnFirstRow <= rModel.mnFirstRow) && - (rModel.mnFirstRow <= mnLastRow + 1) && - (mfHeight == rModel.mfHeight) && - // ignore mnXfId, mbCustomFormat, mbShowPhonetic - cell formatting is always set directly - (mnLevel == rModel.mnLevel) && - (mbCustomHeight == rModel.mbCustomHeight) && - (mbHidden == rModel.mbHidden) && - (mbCollapsed == rModel.mbCollapsed); + if( (0 <= rColSpan.mnFirst) && (rColSpan.mnFirst <= rColSpan.mnLast) ) + maColSpans.insert( rColSpan ); +} - if( bExpandable ) - mnLastRow = rModel.mnLastRow; - return bExpandable; +bool RowModel::isMergeable( const RowModel& rModel ) const +{ + return + // ignore maColSpans - is handled separately in SheetDataBuffer class + (mfHeight == rModel.mfHeight) && + // ignore mnXfId, mbCustomFormat, mbShowPhonetic - cell formatting is always set directly + (mnLevel == rModel.mnLevel) && + (mbCustomHeight == rModel.mbCustomHeight) && + (mbHidden == rModel.mbHidden) && + (mbCollapsed == rModel.mbCollapsed); } // ---------------------------------------------------------------------------- @@ -325,10 +222,10 @@ void ValidationModel::setBiffErrorStyle( sal_uInt8 nErrorStyle ) // ============================================================================ // ============================================================================ -class WorksheetData : public WorkbookHelper +class WorksheetGlobals : public WorkbookHelper { public: - explicit WorksheetData( + explicit WorksheetGlobals( const WorkbookHelper& rHelper, const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, @@ -337,16 +234,12 @@ public: /** Returns true, if this helper refers to an existing Calc sheet. */ inline bool isValidSheet() const { return mxSheet.is(); } - /** Returns a cell formula simulating the passed boolean value. */ - const OUString& getBooleanFormula( bool bValue ) const; - /** Returns the type of this sheet. */ inline WorksheetType getSheetType() const { return meSheetType; } /** Returns the index of the current sheet. */ inline sal_Int16 getSheetIndex() const { return maUsedArea.Sheet; } /** Returns the XSpreadsheet interface of the current sheet. */ - inline const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet >& - getSheet() const { return mxSheet; } + inline const Reference< XSpreadsheet >& getSheet() const { return mxSheet; } /** Returns the XCell interface for the passed cell address. */ Reference< XCell > getCell( const CellAddress& rAddress ) const; @@ -361,14 +254,14 @@ public: Reference< XCellRange > getRow( sal_Int32 nRow ) const; /** Returns the XTableColumns interface for a range of columns. */ - Reference< XTableColumns > getColumns( sal_Int32 nFirstCol, sal_Int32 nLastCol ) const; + Reference< XTableColumns > getColumns( const ValueRange& rColRange ) const; /** Returns the XTableRows interface for a range of rows. */ - Reference< XTableRows > getRows( sal_Int32 nFirstRow, sal_Int32 nLastRow ) const; + Reference< XTableRows > getRows( const ValueRange& rRowRange ) const; /** Returns the XDrawPage interface of the draw page of the current sheet. */ Reference< XDrawPage > getDrawPage() const; /** Returns the size of the entire drawing page in 1/100 mm. */ - Size getDrawPageSize() const; + const Size& getDrawPageSize() const; /** Returns the absolute position of the top-left corner of the cell in 1/100 mm. */ Point getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const; @@ -376,14 +269,12 @@ public: Size getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const; /** Returns the address of the cell that contains the passed point in 1/100 mm. */ - CellAddress getCellAddressFromPosition( const Point& rPosition, const Size& rDrawPageSize ) const; + CellAddress getCellAddressFromPosition( const Point& rPosition ) const; /** Returns the cell range address that contains the passed rectangle in 1/100 mm. */ CellRangeAddress getCellRangeFromRectangle( const Rectangle& rRect ) const; - /** Returns the worksheet settings object. */ - inline WorksheetSettings& getWorksheetSettings() { return maSheetSett; } - /** Returns the buffer containing all shared formulas in this sheet. */ - inline SharedFormulaBuffer& getSharedFormulas() { return maSharedFmlas; } + /** Returns the buffer for cell contents and cell formatting. */ + inline SheetDataBuffer& getSheetData() { return maSheetData; } /** Returns the conditional formattings in this sheet. */ inline CondFormatBuffer& getCondFormats() { return maCondFormats; } /** Returns the buffer for all cell comments in this sheet. */ @@ -392,19 +283,19 @@ public: inline AutoFilterBuffer& getAutoFilters() { return maAutoFilters; } /** Returns the buffer for all web query tables in this sheet. */ inline QueryTableBuffer& getQueryTables() { return maQueryTables; } + /** Returns the worksheet settings object. */ + inline WorksheetSettings& getWorksheetSettings() { return maSheetSett; } /** Returns the page/print settings for this sheet. */ inline PageSettings& getPageSettings() { return maPageSett; } /** Returns the view settings for this sheet. */ inline SheetViewSettings& getSheetViewSettings() { return maSheetViewSett; } - /** Returns the VML drawing page for this sheet (OOXML/BIFF12 only!). */ + /** Returns the VML drawing page for this sheet (OOXML/BIFF12 only). */ inline VmlDrawing& getVmlDrawing() { return *mxVmlDrawing; } + /** Returns the BIFF drawing page for this sheet (BIFF2-BIFF8 only). */ + inline BiffSheetDrawing& getBiffDrawing() const { return *mxBiffDrawing; } /** Changes the current sheet type. */ inline void setSheetType( WorksheetType eSheetType ) { meSheetType = eSheetType; } - /** Stores the cell format at the passed address. */ - void setCellFormat( const CellModel& rModel ); - /** Merges the cells in the passed cell range. */ - void setMergedRange( const CellRangeAddress& rRange ); /** Sets a column or row page break described in the passed struct. */ void setPageBreak( const PageBreakModel& rModel, bool bRowBreak ); /** Inserts the hyperlink URL into the spreadsheet. */ @@ -433,6 +324,8 @@ public: @descr Column default formatting is converted directly, other settings are cached and converted in the finalizeImport() call. */ void setColumnModel( const ColumnModel& rModel ); + /** Converts column default cell formatting. */ + void convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) const; /** Sets default height and hidden state for all unused rows in the sheet. */ void setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom ); @@ -440,11 +333,8 @@ public: @descr Row default formatting is converted directly, other settings are cached and converted in the finalizeImport() call. */ void setRowModel( const RowModel& rModel ); - - /** Converts column default cell formatting. */ - void convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) const; - /** Converts row default cell formatting. */ - void convertRowFormat( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ) const; + /** Specifies that the passed row needs to set its height manually. */ + void setManualRowHeight( sal_Int32 nRow ); /** Initial conversion before importing the worksheet. */ void initializeWorksheetImport(); @@ -453,57 +343,13 @@ public: private: typedef ::std::vector< sal_Int32 > OutlineLevelVec; - typedef ::std::map< sal_Int32, ColumnModel > ColumnModelMap; - typedef ::std::map< sal_Int32, RowModel > RowModelMap; + typedef ::std::pair< ColumnModel, sal_Int32 > ColumnModelRange; + typedef ::std::map< sal_Int32, ColumnModelRange > ColumnModelRangeMap; + typedef ::std::pair< RowModel, sal_Int32 > RowModelRange; + typedef ::std::map< sal_Int32, RowModelRange > RowModelRangeMap; typedef ::std::list< HyperlinkModel > HyperlinkModelList; typedef ::std::list< ValidationModel > ValidationModelList; - struct XfIdRowRange - { - sal_Int32 mnFirstRow; /// Index of first row. - sal_Int32 mnLastRow; /// Index of last row. - sal_Int32 mnXfId; /// XF identifier for the row range. - - explicit XfIdRowRange(); - bool intersects( const CellRangeAddress& rRange ) const; - void set( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ); - bool tryExpand( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ); - }; - - struct XfIdRange - { - CellRangeAddress maRange; /// The formatted cell range. - sal_Int32 mnXfId; /// XF identifier for the range. - sal_Int32 mnNumFmtId; /// Number format id overriding the XF. - - void set( const CellModel& rModel ); - bool tryExpand( const CellModel& rModel ); - bool tryMerge( const XfIdRange& rXfIdRange ); - }; - - struct MergedRange - { - CellRangeAddress maRange; /// The formatted cell range. - sal_Int32 mnHorAlign; /// Horizontal alignment in the range. - - explicit MergedRange( const CellRangeAddress& rRange ); - explicit MergedRange( const CellAddress& rAddress, sal_Int32 nHorAlign ); - bool tryExpand( const CellAddress& rAddress, sal_Int32 nHorAlign ); - }; - - typedef ::std::pair< sal_Int32, sal_Int32 > RowColKey; - typedef ::std::map< RowColKey, XfIdRange > XfIdRangeMap; - typedef ::std::list< MergedRange > MergedRangeList; - - /** Writes all cell formatting attributes to the passed row range. */ - void writeXfIdRowRangeProperties( const XfIdRowRange& rXfIdRowRange ) const; - /** Writes all cell formatting attributes to the passed cell range. */ - void writeXfIdRangeProperties( const XfIdRange& rXfIdRange ) const; - /** Tries to merge the ranges last inserted in maXfIdRanges with existing ranges. */ - void mergeXfIdRanges(); - /** Finalizes the remaining ranges in maXfIdRanges. */ - void finalizeXfIdRanges(); - /** Inserts all imported hyperlinks into their cell ranges. */ void finalizeHyperlinkRanges() const; /** Generates the final URL for the passed hyperlink. */ @@ -514,60 +360,52 @@ private: /** Inserts all imported data validations into their cell ranges. */ void finalizeValidationRanges() const; - /** Merges all cached merged ranges and updates right/bottom cell borders. */ - void finalizeMergedRanges(); - /** Merges the passed merged range and updates right/bottom cell borders. */ - void finalizeMergedRange( const CellRangeAddress& rRange ); - /** Converts column properties for all columns in the sheet. */ void convertColumns(); /** Converts column properties. */ - void convertColumns( OutlineLevelVec& orColLevels, sal_Int32 nFirstCol, sal_Int32 nLastCol, const ColumnModel& rModel ); + void convertColumns( OutlineLevelVec& orColLevels, const ValueRange& rColRange, const ColumnModel& rModel ); /** Converts row properties for all rows in the sheet. */ void convertRows(); /** Converts row properties. */ - void convertRows( OutlineLevelVec& orRowLevels, sal_Int32 nFirstRow, sal_Int32 nLastRow, const RowModel& rModel, double fDefHeight = -1.0 ); + void convertRows( OutlineLevelVec& orRowLevels, const ValueRange& rRowRange, const RowModel& rModel, double fDefHeight = -1.0 ); /** Converts outline grouping for the passed column or row. */ void convertOutlines( OutlineLevelVec& orLevels, sal_Int32 nColRow, sal_Int32 nLevel, bool bCollapsed, bool bRows ); /** Groups columns or rows for the given range. */ void groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastColRow, bool bCollapsed, bool bRows ); - /** Imports the drawings of the sheet (DML, VML), and updates the used area. */ + /** Imports the drawings of the sheet (DML, VML, DFF) and updates the used area. */ void finalizeDrawings(); private: - typedef ::std::auto_ptr< VmlDrawing > VmlDrawingPtr; + typedef ::std::auto_ptr< VmlDrawing > VmlDrawingPtr; + typedef ::std::auto_ptr< BiffSheetDrawing > BiffSheetDrawingPtr; - const OUString maTrueFormula; /// Replacement formula for TRUE boolean cells. - const OUString maFalseFormula; /// Replacement formula for FALSE boolean cells. const OUString maSheetCellRanges; /// Service name for a SheetCellRanges object. const OUString maUrlTextField; /// Service name for a URL text field. const CellAddress& mrMaxApiPos; /// Reference to maximum Calc cell address from address converter. CellRangeAddress maUsedArea; /// Used area of the sheet, and sheet index of the sheet. ColumnModel maDefColModel; /// Default column formatting. - ColumnModelMap maColModels; /// Columns sorted by first column index. + ColumnModelRangeMap maColModels; /// Ranges of columns sorted by first column index. RowModel maDefRowModel; /// Default row formatting. - RowModelMap maRowModels; /// Rows sorted by row index. + RowModelRangeMap maRowModels; /// Ranges of rows sorted by first row index. HyperlinkModelList maHyperlinks; /// Cell ranges containing hyperlinks. ValidationModelList maValidations; /// Cell ranges containing data validation settings. - XfIdRowRange maXfIdRowRange; /// Cached XF identifier for a range of rows. - XfIdRangeMap maXfIdRanges; /// Collected XF identifiers for cell ranges. - MergedRangeList maMergedRanges; /// Merged cell ranges. - MergedRangeList maCenterFillRanges; /// Merged cell ranges from 'center across' or 'fill' alignment. ValueRangeSet maManualRowHeights; /// Rows that need manual height independent from own settings. - WorksheetSettings maSheetSett; /// Global settings for this sheet. - SharedFormulaBuffer maSharedFmlas; /// Buffer for shared formulas in this sheet. + SheetDataBuffer maSheetData; /// Buffer for cell contents and cell formatting. CondFormatBuffer maCondFormats; /// Buffer for conditional formattings. CommentsBuffer maComments; /// Buffer for all cell comments in this sheet. AutoFilterBuffer maAutoFilters; /// Sheet auto filters (not associated to a table). QueryTableBuffer maQueryTables; /// Buffer for all web query tables in this sheet. + WorksheetSettings maSheetSett; /// Global settings for this sheet. PageSettings maPageSett; /// Page/print settings for this sheet. SheetViewSettings maSheetViewSett; /// View settings for this sheet. VmlDrawingPtr mxVmlDrawing; /// Collection of all VML shapes. + BiffSheetDrawingPtr mxBiffDrawing; /// Collection of all BIFF/DFF shapes. OUString maDrawingPath; /// Path to DrawingML fragment. OUString maVmlDrawingPath; /// Path to legacy VML drawing fragment. + Size maDrawPageSize; /// Current size of the drawing page in 1/100 mm. Rectangle maShapeBoundingBox; /// Bounding box for all shapes from all drawings. ISegmentProgressBarRef mxProgressBar; /// Sheet progress bar. ISegmentProgressBarRef mxRowProgress; /// Progress bar for row/cell processing. @@ -579,20 +417,18 @@ private: // ---------------------------------------------------------------------------- -WorksheetData::WorksheetData( const WorkbookHelper& rHelper, const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : +WorksheetGlobals::WorksheetGlobals( const WorkbookHelper& rHelper, const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : WorkbookHelper( rHelper ), - maTrueFormula( CREATE_OUSTRING( "=TRUE()" ) ), - maFalseFormula( CREATE_OUSTRING( "=FALSE()" ) ), maSheetCellRanges( CREATE_OUSTRING( "com.sun.star.sheet.SheetCellRanges" ) ), maUrlTextField( CREATE_OUSTRING( "com.sun.star.text.TextField.URL" ) ), mrMaxApiPos( rHelper.getAddressConverter().getMaxApiAddress() ), maUsedArea( nSheet, SAL_MAX_INT32, SAL_MAX_INT32, -1, -1 ), - maSheetSett( *this ), - maSharedFmlas( *this ), + maSheetData( *this ), maCondFormats( *this ), maComments( *this ), maAutoFilters( *this ), maQueryTables( *this ), + maSheetSett( *this ), maPageSett( *this ), maSheetViewSett( *this ), mxProgressBar( rxProgressBar ), @@ -621,8 +457,17 @@ WorksheetData::WorksheetData( const WorkbookHelper& rHelper, const ISegmentProgr maDefRowModel.mbCollapsed = false; // buffers - if( getFilterType() == FILTER_OOXML ) - mxVmlDrawing.reset( new VmlDrawing( *this ) ); + switch( getFilterType() ) + { + case FILTER_OOXML: + mxVmlDrawing.reset( new VmlDrawing( *this ) ); + break; + case FILTER_BIFF: + mxBiffDrawing.reset( new BiffSheetDrawing( *this ) ); + break; + case FILTER_UNKNOWN: + break; + } // prepare progress bars if( mxProgressBar.get() ) @@ -632,12 +477,7 @@ WorksheetData::WorksheetData( const WorkbookHelper& rHelper, const ISegmentProgr } } -const OUString& WorksheetData::getBooleanFormula( bool bValue ) const -{ - return bValue ? maTrueFormula : maFalseFormula; -} - -Reference< XCell > WorksheetData::getCell( const CellAddress& rAddress ) const +Reference< XCell > WorksheetGlobals::getCell( const CellAddress& rAddress ) const { Reference< XCell > xCell; if( mxSheet.is() ) try @@ -650,7 +490,7 @@ Reference< XCell > WorksheetData::getCell( const CellAddress& rAddress ) const return xCell; } -Reference< XCellRange > WorksheetData::getCellRange( const CellRangeAddress& rRange ) const +Reference< XCellRange > WorksheetGlobals::getCellRange( const CellRangeAddress& rRange ) const { Reference< XCellRange > xRange; if( mxSheet.is() ) try @@ -663,12 +503,12 @@ Reference< XCellRange > WorksheetData::getCellRange( const CellRangeAddress& rRa return xRange; } -Reference< XSheetCellRanges > WorksheetData::getCellRangeList( const ApiCellRangeList& rRanges ) const +Reference< XSheetCellRanges > WorksheetGlobals::getCellRangeList( const ApiCellRangeList& rRanges ) const { Reference< XSheetCellRanges > xRanges; if( mxSheet.is() && !rRanges.empty() ) try { - xRanges.set( getDocumentFactory()->createInstance( maSheetCellRanges ), UNO_QUERY_THROW ); + xRanges.set( getBaseFilter().getModelFactory()->createInstance( maSheetCellRanges ), UNO_QUERY_THROW ); Reference< XSheetCellRangeContainer > xRangeCont( xRanges, UNO_QUERY_THROW ); xRangeCont->addRangeAddresses( ContainerHelper::vectorToSequence( rRanges ), sal_False ); } @@ -678,7 +518,7 @@ Reference< XSheetCellRanges > WorksheetData::getCellRangeList( const ApiCellRang return xRanges; } -Reference< XCellRange > WorksheetData::getColumn( sal_Int32 nCol ) const +Reference< XCellRange > WorksheetGlobals::getColumn( sal_Int32 nCol ) const { Reference< XCellRange > xColumn; try @@ -693,7 +533,7 @@ Reference< XCellRange > WorksheetData::getColumn( sal_Int32 nCol ) const return xColumn; } -Reference< XCellRange > WorksheetData::getRow( sal_Int32 nRow ) const +Reference< XCellRange > WorksheetGlobals::getRow( sal_Int32 nRow ) const { Reference< XCellRange > xRow; try @@ -708,33 +548,33 @@ Reference< XCellRange > WorksheetData::getRow( sal_Int32 nRow ) const return xRow; } -Reference< XTableColumns > WorksheetData::getColumns( sal_Int32 nFirstCol, sal_Int32 nLastCol ) const +Reference< XTableColumns > WorksheetGlobals::getColumns( const ValueRange& rColRange ) const { Reference< XTableColumns > xColumns; - nLastCol = ::std::min( nLastCol, mrMaxApiPos.Column ); - if( (0 <= nFirstCol) && (nFirstCol <= nLastCol) ) + sal_Int32 nLastCol = ::std::min( rColRange.mnLast, mrMaxApiPos.Column ); + if( (0 <= rColRange.mnFirst) && (rColRange.mnFirst <= nLastCol) ) { - Reference< XColumnRowRange > xRange( getCellRange( CellRangeAddress( getSheetIndex(), nFirstCol, 0, nLastCol, 0 ) ), UNO_QUERY ); + Reference< XColumnRowRange > xRange( getCellRange( CellRangeAddress( getSheetIndex(), rColRange.mnFirst, 0, nLastCol, 0 ) ), UNO_QUERY ); if( xRange.is() ) xColumns = xRange->getColumns(); } return xColumns; } -Reference< XTableRows > WorksheetData::getRows( sal_Int32 nFirstRow, sal_Int32 nLastRow ) const +Reference< XTableRows > WorksheetGlobals::getRows( const ValueRange& rRowRange ) const { Reference< XTableRows > xRows; - nLastRow = ::std::min( nLastRow, mrMaxApiPos.Row ); - if( (0 <= nFirstRow) && (nFirstRow <= nLastRow) ) + sal_Int32 nLastRow = ::std::min( rRowRange.mnLast, mrMaxApiPos.Row ); + if( (0 <= rRowRange.mnFirst) && (rRowRange.mnFirst <= nLastRow) ) { - Reference< XColumnRowRange > xRange( getCellRange( CellRangeAddress( getSheetIndex(), 0, nFirstRow, 0, nLastRow ) ), UNO_QUERY ); + Reference< XColumnRowRange > xRange( getCellRange( CellRangeAddress( getSheetIndex(), 0, rRowRange.mnFirst, 0, nLastRow ) ), UNO_QUERY ); if( xRange.is() ) xRows = xRange->getRows(); } return xRows; } -Reference< XDrawPage > WorksheetData::getDrawPage() const +Reference< XDrawPage > WorksheetGlobals::getDrawPage() const { Reference< XDrawPage > xDrawPage; try @@ -747,15 +587,13 @@ Reference< XDrawPage > WorksheetData::getDrawPage() const return xDrawPage; } -Size WorksheetData::getDrawPageSize() const +const Size& WorksheetGlobals::getDrawPageSize() const { - Size aSize; - PropertySet aRangeProp( getCellRange( CellRangeAddress( getSheetIndex(), 0, 0, mrMaxApiPos.Column, mrMaxApiPos.Row ) ) ); - aRangeProp.getProperty( aSize, PROP_Size ); - return aSize; + OSL_ENSURE( (maDrawPageSize.Width > 0) && (maDrawPageSize.Height > 0), "WorksheetGlobals::getDrawPageSize - called too early, size invalid" ); + return maDrawPageSize; } -Point WorksheetData::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const +Point WorksheetGlobals::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const { Point aPoint; PropertySet aCellProp( getCell( CellAddress( getSheetIndex(), nCol, nRow ) ) ); @@ -763,7 +601,7 @@ Point WorksheetData::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const return aPoint; } -Size WorksheetData::getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const +Size WorksheetGlobals::getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const { Size aSize; PropertySet aCellProp( getCell( CellAddress( getSheetIndex(), nCol, nRow ) ) ); @@ -840,7 +678,7 @@ bool lclUpdateInterval( sal_Int32& rnBegAddr, sal_Int32& rnMidAddr, sal_Int32& r } // namespace -CellAddress WorksheetData::getCellAddressFromPosition( const Point& rPosition, const Size& rDrawPageSize ) const +CellAddress WorksheetGlobals::getCellAddressFromPosition( const Point& rPosition ) const { // starting cell address and its position in drawing layer (top-left edge) sal_Int32 nBegCol = 0; @@ -850,7 +688,7 @@ CellAddress WorksheetData::getCellAddressFromPosition( const Point& rPosition, c // end cell address and its position in drawing layer (bottom-right edge) sal_Int32 nEndCol = mrMaxApiPos.Column + 1; sal_Int32 nEndRow = mrMaxApiPos.Row + 1; - Point aEndPos( rDrawPageSize.Width, rDrawPageSize.Height ); + Point aEndPos( maDrawPageSize.Width, maDrawPageSize.Height ); // starting point for interval search sal_Int32 nMidCol, nMidRow; @@ -876,12 +714,11 @@ CellAddress WorksheetData::getCellAddressFromPosition( const Point& rPosition, c return CellAddress( getSheetIndex(), nMidCol, nMidRow ); } -CellRangeAddress WorksheetData::getCellRangeFromRectangle( const Rectangle& rRect ) const +CellRangeAddress WorksheetGlobals::getCellRangeFromRectangle( const Rectangle& rRect ) const { - Size aPageSize = getDrawPageSize(); - CellAddress aStartAddr = getCellAddressFromPosition( Point( rRect.X, rRect.Y ), aPageSize ); + CellAddress aStartAddr = getCellAddressFromPosition( Point( rRect.X, rRect.Y ) ); Point aBotRight( rRect.X + rRect.Width, rRect.Y + rRect.Height ); - CellAddress aEndAddr = getCellAddressFromPosition( aBotRight, aPageSize ); + CellAddress aEndAddr = getCellAddressFromPosition( aBotRight ); bool bMultiCols = aStartAddr.Column < aEndAddr.Column; bool bMultiRows = aStartAddr.Row < aEndAddr.Row; if( bMultiCols || bMultiRows ) @@ -897,62 +734,7 @@ CellRangeAddress WorksheetData::getCellRangeFromRectangle( const Rectangle& rRec return CellRangeAddress( getSheetIndex(), aStartAddr.Column, aStartAddr.Row, aEndAddr.Column, aEndAddr.Row ); } -void WorksheetData::setCellFormat( const CellModel& rModel ) -{ - if( rModel.mxCell.is() && ((rModel.mnXfId >= 0) || (rModel.mnNumFmtId >= 0)) ) - { - // try to merge existing ranges and to write some formatting properties - if( !maXfIdRanges.empty() ) - { - // get row index of last inserted cell - sal_Int32 nLastRow = maXfIdRanges.rbegin()->second.maRange.StartRow; - // row changed - try to merge ranges of last row with existing ranges - if( rModel.maAddress.Row != nLastRow ) - { - mergeXfIdRanges(); - // write format properties of all ranges above last row and remove them - XfIdRangeMap::iterator aIt = maXfIdRanges.begin(), aEnd = maXfIdRanges.end(); - while( aIt != aEnd ) - { - // check that range cannot be merged with current row, and that range is not in cached row range - if( (aIt->second.maRange.EndRow < nLastRow) && !maXfIdRowRange.intersects( aIt->second.maRange ) ) - { - writeXfIdRangeProperties( aIt->second ); - maXfIdRanges.erase( aIt++ ); - } - else - ++aIt; - } - } - } - - // try to expand last existing range, or create new range entry - if( maXfIdRanges.empty() || !maXfIdRanges.rbegin()->second.tryExpand( rModel ) ) - maXfIdRanges[ RowColKey( rModel.maAddress.Row, rModel.maAddress.Column ) ].set( rModel ); - - // update merged ranges for 'center across selection' and 'fill' - if( const Xf* pXf = getStyles().getCellXf( rModel.mnXfId ).get() ) - { - sal_Int32 nHorAlign = pXf->getAlignment().getModel().mnHorAlign; - if( (nHorAlign == XML_centerContinuous) || (nHorAlign == XML_fill) ) - { - /* start new merged range, if cell is not empty (#108781#), - or try to expand last range with empty cell */ - if( rModel.mnCellType != XML_TOKEN_INVALID ) - maCenterFillRanges.push_back( MergedRange( rModel.maAddress, nHorAlign ) ); - else if( !maCenterFillRanges.empty() ) - maCenterFillRanges.rbegin()->tryExpand( rModel.maAddress, nHorAlign ); - } - } - } -} - -void WorksheetData::setMergedRange( const CellRangeAddress& rRange ) -{ - maMergedRanges.push_back( MergedRange( rRange ) ); -} - -void WorksheetData::setPageBreak( const PageBreakModel& rModel, bool bRowBreak ) +void WorksheetGlobals::setPageBreak( const PageBreakModel& rModel, bool bRowBreak ) { if( rModel.mbManual && (rModel.mnColRow > 0) ) { @@ -961,27 +743,27 @@ void WorksheetData::setPageBreak( const PageBreakModel& rModel, bool bRowBreak ) } } -void WorksheetData::setHyperlink( const HyperlinkModel& rModel ) +void WorksheetGlobals::setHyperlink( const HyperlinkModel& rModel ) { maHyperlinks.push_back( rModel ); } -void WorksheetData::setValidation( const ValidationModel& rModel ) +void WorksheetGlobals::setValidation( const ValidationModel& rModel ) { maValidations.push_back( rModel ); } -void WorksheetData::setDrawingPath( const OUString& rDrawingPath ) +void WorksheetGlobals::setDrawingPath( const OUString& rDrawingPath ) { maDrawingPath = rDrawingPath; } -void WorksheetData::setVmlDrawingPath( const OUString& rVmlDrawingPath ) +void WorksheetGlobals::setVmlDrawingPath( const OUString& rVmlDrawingPath ) { maVmlDrawingPath = rVmlDrawingPath; } -void WorksheetData::extendUsedArea( const CellAddress& rAddress ) +void WorksheetGlobals::extendUsedArea( const CellAddress& rAddress ) { maUsedArea.StartColumn = ::std::min( maUsedArea.StartColumn, rAddress.Column ); maUsedArea.StartRow = ::std::min( maUsedArea.StartRow, rAddress.Row ); @@ -989,13 +771,13 @@ void WorksheetData::extendUsedArea( const CellAddress& rAddress ) maUsedArea.EndRow = ::std::max( maUsedArea.EndRow, rAddress.Row ); } -void WorksheetData::extendUsedArea( const CellRangeAddress& rRange ) +void WorksheetGlobals::extendUsedArea( const CellRangeAddress& rRange ) { extendUsedArea( CellAddress( rRange.Sheet, rRange.StartColumn, rRange.StartRow ) ); extendUsedArea( CellAddress( rRange.Sheet, rRange.EndColumn, rRange.EndRow ) ); } -void WorksheetData::extendShapeBoundingBox( const Rectangle& rShapeRect ) +void WorksheetGlobals::extendShapeBoundingBox( const Rectangle& rShapeRect ) { if( (maShapeBoundingBox.Width == 0) && (maShapeBoundingBox.Height == 0) ) { @@ -1013,7 +795,7 @@ void WorksheetData::extendShapeBoundingBox( const Rectangle& rShapeRect ) } } -void WorksheetData::setBaseColumnWidth( sal_Int32 nWidth ) +void WorksheetGlobals::setBaseColumnWidth( sal_Int32 nWidth ) { // do not modify width, if setDefaultColumnWidth() has been used if( !mbHasDefWidth && (nWidth > 0) ) @@ -1025,7 +807,7 @@ void WorksheetData::setBaseColumnWidth( sal_Int32 nWidth ) } } -void WorksheetData::setDefaultColumnWidth( double fWidth ) +void WorksheetGlobals::setDefaultColumnWidth( double fWidth ) { // overrides a width set with setBaseColumnWidth() if( fWidth > 0.0 ) @@ -1035,22 +817,65 @@ void WorksheetData::setDefaultColumnWidth( double fWidth ) } } -void WorksheetData::setColumnModel( const ColumnModel& rModel ) +void WorksheetGlobals::setColumnModel( const ColumnModel& rModel ) { // convert 1-based OOXML column indexes to 0-based API column indexes - sal_Int32 nFirstCol = rModel.mnFirstCol - 1; - sal_Int32 nLastCol = rModel.mnLastCol - 1; - if( (0 <= nFirstCol) && (nFirstCol <= mrMaxApiPos.Column) ) + sal_Int32 nFirstCol = rModel.maRange.mnFirst - 1; + sal_Int32 nLastCol = rModel.maRange.mnLast - 1; + if( getAddressConverter().checkCol( nFirstCol, true ) && (nFirstCol <= nLastCol) ) + { + // validate last column index + if( !getAddressConverter().checkCol( nLastCol, true ) ) + nLastCol = mrMaxApiPos.Column; + // try to find entry in column model map that is able to merge with the passed model + bool bInsertModel = true; + if( !maColModels.empty() ) + { + // find first column model range following nFirstCol (nFirstCol < aIt->first), or end of map + ColumnModelRangeMap::iterator aIt = maColModels.upper_bound( nFirstCol ); + OSL_ENSURE( aIt == maColModels.end(), "WorksheetGlobals::setColModel - columns are unsorted" ); + // if inserting before another column model, get last free column + OSL_ENSURE( (aIt == maColModels.end()) || (nLastCol < aIt->first), "WorksheetGlobals::setColModel - multiple models of the same column" ); + if( aIt != maColModels.end() ) + nLastCol = ::std::min( nLastCol, aIt->first - 1 ); + if( aIt != maColModels.begin() ) + { + // go to previous map element (which may be able to merge with the passed model) + --aIt; + // the usage of upper_bound() above ensures that aIt->first is less than or equal to nFirstCol now + sal_Int32& rnLastMapCol = aIt->second.second; + OSL_ENSURE( rnLastMapCol < nFirstCol, "WorksheetGlobals::setColModel - multiple models of the same column" ); + nFirstCol = ::std::max( rnLastMapCol + 1, nFirstCol ); + if( (rnLastMapCol + 1 == nFirstCol) && (nFirstCol <= nLastCol) && aIt->second.first.isMergeable( rModel ) ) + { + // can merge with existing model, update last column index + rnLastMapCol = nLastCol; + bInsertModel = false; + } + } + } + if( nFirstCol <= nLastCol ) + { + // insert the column model, if it has not been merged with another + if( bInsertModel ) + maColModels[ nFirstCol ] = ColumnModelRange( rModel, nLastCol ); + // set column formatting directly + convertColumnFormat( nFirstCol, nLastCol, rModel.mnXfId ); + } + } +} + +void WorksheetGlobals::convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) const +{ + CellRangeAddress aRange( getSheetIndex(), nFirstCol, 0, nLastCol, mrMaxApiPos.Row ); + if( getAddressConverter().validateCellRange( aRange, true, false ) ) { - // set column formatting directly, nLastCol is checked inside the function - convertColumnFormat( nFirstCol, nLastCol, rModel.mnXfId ); - // expand last entry or add new entry - if( maColModels.empty() || !maColModels.rbegin()->second.tryExpand( rModel ) ) - maColModels[ nFirstCol ] = rModel; + PropertySet aPropSet( getCellRange( aRange ) ); + getStyles().writeCellXfToPropertySet( aPropSet, nXfId ); } } -void WorksheetData::setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom ) +void WorksheetGlobals::setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom ) { maDefRowModel.mfHeight = fHeight; maDefRowModel.mbCustomHeight = bCustomHeight; @@ -1059,83 +884,79 @@ void WorksheetData::setDefaultRowSettings( double fHeight, bool bCustomHeight, b maDefRowModel.mbThickBottom = bThickBottom; } -void WorksheetData::setRowModel( const RowModel& rModel ) +void WorksheetGlobals::setRowModel( const RowModel& rModel ) { - // convert 1-based OOXML row indexes to 0-based API row indexes - sal_Int32 nFirstRow = rModel.mnFirstRow - 1; - sal_Int32 nLastRow = rModel.mnLastRow - 1; - if( (0 <= nFirstRow) && (nFirstRow <= mrMaxApiPos.Row) ) + // convert 1-based OOXML row index to 0-based API row index + sal_Int32 nRow = rModel.mnRow - 1; + if( getAddressConverter().checkRow( nRow, true ) ) { - // set row formatting - if( rModel.mbCustomFormat ) + // try to find entry in row model map that is able to merge with the passed model + bool bInsertModel = true; + bool bUnusedRow = true; + if( !maRowModels.empty() ) { - // try to expand cached row range, if formatting is equal - if( (maXfIdRowRange.mnLastRow < 0) || !maXfIdRowRange.tryExpand( nFirstRow, nLastRow, rModel.mnXfId ) ) + // find first row model range following nRow (nRow < aIt->first), or end of map + RowModelRangeMap::iterator aIt = maRowModels.upper_bound( nRow ); + OSL_ENSURE( aIt == maRowModels.end(), "WorksheetGlobals::setRowModel - rows are unsorted" ); + if( aIt != maRowModels.begin() ) { - writeXfIdRowRangeProperties( maXfIdRowRange ); - maXfIdRowRange.set( nFirstRow, nLastRow, rModel.mnXfId ); + // go to previous map element (which may be able to merge with the passed model) + --aIt; + // the usage of upper_bound() above ensures that aIt->first is less than or equal to nRow now + sal_Int32& rnLastMapRow = aIt->second.second; + bUnusedRow = rnLastMapRow < nRow; + OSL_ENSURE( bUnusedRow, "WorksheetGlobals::setRowModel - multiple models of the same row" ); + if( (rnLastMapRow + 1 == nRow) && aIt->second.first.isMergeable( rModel ) ) + { + // can merge with existing model, update last row index + ++rnLastMapRow; + bInsertModel = false; + } } } - else if( maXfIdRowRange.mnLastRow >= 0 ) + if( bUnusedRow ) { - // finish last cached row range - writeXfIdRowRangeProperties( maXfIdRowRange ); - maXfIdRowRange.set( -1, -1, -1 ); + // insert the row model, if it has not been merged with another + if( bInsertModel ) + maRowModels[ nRow ] = RowModelRange( rModel, nRow ); + // set row formatting + maSheetData.setRowFormat( nRow, rModel.mnXfId, rModel.mbCustomFormat ); + // set column spans + maSheetData.setColSpans( nRow, rModel.maColSpans ); } - - // expand last entry or add new entry - if( maRowModels.empty() || !maRowModels.rbegin()->second.tryExpand( rModel ) ) - maRowModels[ nFirstRow ] = rModel; - } - lclUpdateProgressBar( mxRowProgress, maUsedArea, nLastRow ); -} - -void WorksheetData::convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) const -{ - CellRangeAddress aRange( getSheetIndex(), nFirstCol, 0, nLastCol, mrMaxApiPos.Row ); - if( getAddressConverter().validateCellRange( aRange, true, false ) ) - { - PropertySet aPropSet( getCellRange( aRange ) ); - getStyles().writeCellXfToPropertySet( aPropSet, nXfId ); } + lclUpdateProgressBar( mxRowProgress, maUsedArea, nRow ); } -void WorksheetData::convertRowFormat( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ) const +void WorksheetGlobals::setManualRowHeight( sal_Int32 nRow ) { - CellRangeAddress aRange( getSheetIndex(), 0, nFirstRow, mrMaxApiPos.Column, nLastRow ); - if( getAddressConverter().validateCellRange( aRange, true, false ) ) - { - PropertySet aPropSet( getCellRange( aRange ) ); - getStyles().writeCellXfToPropertySet( aPropSet, nXfId ); - } + maManualRowHeights.insert( nRow ); } -void WorksheetData::initializeWorksheetImport() +void WorksheetGlobals::initializeWorksheetImport() { // set default cell style for unused cells PropertySet aPropSet( mxSheet ); aPropSet.setProperty( PROP_CellStyle, getStyles().getDefaultStyleName() ); - /* Remember current sheet index in global data, needed by some global + /* Remember the current sheet index in global data, needed by global objects, e.g. the chart converter. */ setCurrentSheetIndex( getSheetIndex() ); } -void WorksheetData::finalizeWorksheetImport() +void WorksheetGlobals::finalizeWorksheetImport() { lclUpdateProgressBar( mxRowProgress, 1.0 ); - finalizeXfIdRanges(); + maSheetData.finalizeImport(); lclUpdateProgressBar( mxFinalProgress, 0.25 ); finalizeHyperlinkRanges(); finalizeValidationRanges(); - finalizeMergedRanges(); maAutoFilters.finalizeImport( getSheetIndex() ); - maSheetSett.finalizeImport(); maCondFormats.finalizeImport(); maQueryTables.finalizeImport(); + maSheetSett.finalizeImport(); maPageSett.finalizeImport(); maSheetViewSett.finalizeImport(); - maSheetSett.finalizeImport(); lclUpdateProgressBar( mxFinalProgress, 0.5 ); convertColumns(); @@ -1144,159 +965,13 @@ void WorksheetData::finalizeWorksheetImport() finalizeDrawings(); lclUpdateProgressBar( mxFinalProgress, 1.0 ); - // reset current sheet index in global data + // forget current sheet index in global data setCurrentSheetIndex( -1 ); } // private -------------------------------------------------------------------- -WorksheetData::XfIdRowRange::XfIdRowRange() : - mnFirstRow( -1 ), - mnLastRow( -1 ), - mnXfId( -1 ) -{ -} - -bool WorksheetData::XfIdRowRange::intersects( const CellRangeAddress& rRange ) const -{ - return (rRange.StartRow <= mnLastRow) && (mnFirstRow <= rRange.EndRow); -} - -void WorksheetData::XfIdRowRange::set( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ) -{ - mnFirstRow = nFirstRow; - mnLastRow = nLastRow; - mnXfId = nXfId; -} - -bool WorksheetData::XfIdRowRange::tryExpand( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ) -{ - if( mnXfId == nXfId ) - { - if( mnLastRow + 1 == nFirstRow ) - { - mnLastRow = nLastRow; - return true; - } - if( mnFirstRow == nLastRow + 1 ) - { - mnFirstRow = nFirstRow; - return true; - } - } - return false; -} - -void WorksheetData::XfIdRange::set( const CellModel& rModel ) -{ - maRange.Sheet = rModel.maAddress.Sheet; - maRange.StartColumn = maRange.EndColumn = rModel.maAddress.Column; - maRange.StartRow = maRange.EndRow = rModel.maAddress.Row; - mnXfId = rModel.mnXfId; - mnNumFmtId = rModel.mnNumFmtId; -} - -bool WorksheetData::XfIdRange::tryExpand( const CellModel& rModel ) -{ - if( (mnXfId == rModel.mnXfId) && (mnNumFmtId == rModel.mnNumFmtId) && - (maRange.StartRow == rModel.maAddress.Row) && - (maRange.EndRow == rModel.maAddress.Row) && - (maRange.EndColumn + 1 == rModel.maAddress.Column) ) - { - ++maRange.EndColumn; - return true; - } - return false; -} - -bool WorksheetData::XfIdRange::tryMerge( const XfIdRange& rXfIdRange ) -{ - if( (mnXfId == rXfIdRange.mnXfId) && - (mnNumFmtId == rXfIdRange.mnNumFmtId) && - (maRange.EndRow + 1 == rXfIdRange.maRange.StartRow) && - (maRange.StartColumn == rXfIdRange.maRange.StartColumn) && - (maRange.EndColumn == rXfIdRange.maRange.EndColumn) ) - { - maRange.EndRow = rXfIdRange.maRange.EndRow; - return true; - } - return false; -} - - -WorksheetData::MergedRange::MergedRange( const CellRangeAddress& rRange ) : - maRange( rRange ), - mnHorAlign( XML_TOKEN_INVALID ) -{ -} - -WorksheetData::MergedRange::MergedRange( const CellAddress& rAddress, sal_Int32 nHorAlign ) : - maRange( rAddress.Sheet, rAddress.Column, rAddress.Row, rAddress.Column, rAddress.Row ), - mnHorAlign( nHorAlign ) -{ -} - -bool WorksheetData::MergedRange::tryExpand( const CellAddress& rAddress, sal_Int32 nHorAlign ) -{ - if( (mnHorAlign == nHorAlign) && (maRange.StartRow == rAddress.Row) && - (maRange.EndRow == rAddress.Row) && (maRange.EndColumn + 1 == rAddress.Column) ) - { - ++maRange.EndColumn; - return true; - } - return false; -} - -void WorksheetData::writeXfIdRowRangeProperties( const XfIdRowRange& rXfIdRowRange ) const -{ - if( (rXfIdRowRange.mnLastRow >= 0) && (rXfIdRowRange.mnXfId >= 0) ) - convertRowFormat( rXfIdRowRange.mnFirstRow, rXfIdRowRange.mnLastRow, rXfIdRowRange.mnXfId ); -} - -void WorksheetData::writeXfIdRangeProperties( const XfIdRange& rXfIdRange ) const -{ - StylesBuffer& rStyles = getStyles(); - PropertyMap aPropMap; - if( rXfIdRange.mnXfId >= 0 ) - rStyles.writeCellXfToPropertyMap( aPropMap, rXfIdRange.mnXfId ); - if( rXfIdRange.mnNumFmtId >= 0 ) - rStyles.writeNumFmtToPropertyMap( aPropMap, rXfIdRange.mnNumFmtId ); - PropertySet aPropSet( getCellRange( rXfIdRange.maRange ) ); - aPropSet.setProperties( aPropMap ); -} - -void WorksheetData::mergeXfIdRanges() -{ - if( !maXfIdRanges.empty() ) - { - // get row index of last range - sal_Int32 nLastRow = maXfIdRanges.rbegin()->second.maRange.StartRow; - // process all ranges located in the same row of the last range - XfIdRangeMap::iterator aMergeIt = maXfIdRanges.end(); - while( (aMergeIt != maXfIdRanges.begin()) && ((--aMergeIt)->second.maRange.StartRow == nLastRow) ) - { - const XfIdRange& rMergeXfIdRange = aMergeIt->second; - // try to find a range that can be merged with rMergeRange - bool bFound = false; - for( XfIdRangeMap::iterator aIt = maXfIdRanges.begin(); !bFound && (aIt != aMergeIt); ++aIt ) - if( (bFound = aIt->second.tryMerge( rMergeXfIdRange )) == true ) - maXfIdRanges.erase( aMergeIt++ ); - } - } -} - -void WorksheetData::finalizeXfIdRanges() -{ - // write default formatting of remaining row range - writeXfIdRowRangeProperties( maXfIdRowRange ); - // try to merge remaining inserted ranges - mergeXfIdRanges(); - // write all formatting - for( XfIdRangeMap::const_iterator aIt = maXfIdRanges.begin(), aEnd = maXfIdRanges.end(); aIt != aEnd; ++aIt ) - writeXfIdRangeProperties( aIt->second ); -} - -void WorksheetData::finalizeHyperlinkRanges() const +void WorksheetGlobals::finalizeHyperlinkRanges() const { for( HyperlinkModelList::const_iterator aIt = maHyperlinks.begin(), aEnd = maHyperlinks.end(); aIt != aEnd; ++aIt ) { @@ -1309,7 +984,7 @@ void WorksheetData::finalizeHyperlinkRanges() const } } -OUString WorksheetData::getHyperlinkUrl( const HyperlinkModel& rHyperlink ) const +OUString WorksheetGlobals::getHyperlinkUrl( const HyperlinkModel& rHyperlink ) const { OUStringBuffer aUrlBuffer; if( rHyperlink.maTarget.getLength() > 0 ) @@ -1337,20 +1012,20 @@ OUString WorksheetData::getHyperlinkUrl( const HyperlinkModel& rHyperlink ) cons return aUrl; } -void WorksheetData::insertHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const +void WorksheetGlobals::insertHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const { Reference< XCell > xCell = getCell( rAddress ); if( xCell.is() ) switch( xCell->getType() ) { // #i54261# restrict creation of URL field to text cells - case ::com::sun::star::table::CellContentType_TEXT: + case CellContentType_TEXT: { Reference< XText > xText( xCell, UNO_QUERY ); if( xText.is() ) { // create a URL field object and set its properties - Reference< XTextContent > xUrlField( getDocumentFactory()->createInstance( maUrlTextField ), UNO_QUERY ); - OSL_ENSURE( xUrlField.is(), "WorksheetData::insertHyperlink - cannot create text field" ); + Reference< XTextContent > xUrlField( getBaseFilter().getModelFactory()->createInstance( maUrlTextField ), UNO_QUERY ); + OSL_ENSURE( xUrlField.is(), "WorksheetGlobals::insertHyperlink - cannot create text field" ); if( xUrlField.is() ) { // properties of the URL field @@ -1366,7 +1041,7 @@ void WorksheetData::insertHyperlink( const CellAddress& rAddress, const OUString } catch( const Exception& ) { - OSL_ENSURE( false, "WorksheetData::insertHyperlink - cannot insert text field" ); + OSL_ENSURE( false, "WorksheetGlobals::insertHyperlink - cannot insert text field" ); } } } @@ -1376,15 +1051,13 @@ void WorksheetData::insertHyperlink( const CellAddress& rAddress, const OUString // fix for #i31050# disabled, HYPERLINK is not able to return numeric value (#i91351#) #if 0 // #i31050# replace number with HYPERLINK function - case ::com::sun::star::table::CellContentType_VALUE: + case CellContentType_VALUE: { Reference< XFormulaTokens > xTokens( xCell, UNO_QUERY ); - OSL_ENSURE( xTokens.is(), "WorksheetHelper::insertHyperlink - missing formula interface" ); - if( xTokens.is() ) - { - SimpleFormulaContext aContext( xTokens, false, false ); - getFormulaParser().convertNumberToHyperlink( aContext, rUrl, xCell->getValue() ); - } + ApiTokenSequence aTokens = getFormulaParser().convertNumberToHyperlink( rUrl, xCell->getValue() ); + OSL_ENSURE( xTokens.is(), "WorksheetHelper::insertHyperlink - missing formula token interface" ); + if( xTokens.is() && aTokens.hasElements() ) + xTokens->setTokens( aTokens ); } break; #endif @@ -1393,7 +1066,7 @@ void WorksheetData::insertHyperlink( const CellAddress& rAddress, const OUString } } -void WorksheetData::finalizeValidationRanges() const +void WorksheetGlobals::finalizeValidationRanges() const { for( ValidationModelList::const_iterator aIt = maValidations.begin(), aEnd = maValidations.end(); aIt != aEnd; ++aIt ) { @@ -1403,37 +1076,36 @@ void WorksheetData::finalizeValidationRanges() const if( xValidation.is() ) { PropertySet aValProps( xValidation ); - namespace csss = ::com::sun::star::sheet; // convert validation type to API enum - ValidationType eType = csss::ValidationType_ANY; + ValidationType eType = ValidationType_ANY; switch( aIt->mnType ) { - case XML_custom: eType = csss::ValidationType_CUSTOM; break; - case XML_date: eType = csss::ValidationType_DATE; break; - case XML_decimal: eType = csss::ValidationType_DECIMAL; break; - case XML_list: eType = csss::ValidationType_LIST; break; - case XML_none: eType = csss::ValidationType_ANY; break; - case XML_textLength: eType = csss::ValidationType_TEXT_LEN; break; - case XML_time: eType = csss::ValidationType_TIME; break; - case XML_whole: eType = csss::ValidationType_WHOLE; break; - default: OSL_ENSURE( false, "WorksheetData::finalizeValidationRanges - unknown validation type" ); + case XML_custom: eType = ValidationType_CUSTOM; break; + case XML_date: eType = ValidationType_DATE; break; + case XML_decimal: eType = ValidationType_DECIMAL; break; + case XML_list: eType = ValidationType_LIST; break; + case XML_none: eType = ValidationType_ANY; break; + case XML_textLength: eType = ValidationType_TEXT_LEN; break; + case XML_time: eType = ValidationType_TIME; break; + case XML_whole: eType = ValidationType_WHOLE; break; + default: OSL_ENSURE( false, "WorksheetGlobals::finalizeValidationRanges - unknown validation type" ); } aValProps.setProperty( PROP_Type, eType ); // convert error alert style to API enum - ValidationAlertStyle eAlertStyle = csss::ValidationAlertStyle_STOP; + ValidationAlertStyle eAlertStyle = ValidationAlertStyle_STOP; switch( aIt->mnErrorStyle ) { - case XML_information: eAlertStyle = csss::ValidationAlertStyle_INFO; break; - case XML_stop: eAlertStyle = csss::ValidationAlertStyle_STOP; break; - case XML_warning: eAlertStyle = csss::ValidationAlertStyle_WARNING; break; - default: OSL_ENSURE( false, "WorksheetData::finalizeValidationRanges - unknown error style" ); + case XML_information: eAlertStyle = ValidationAlertStyle_INFO; break; + case XML_stop: eAlertStyle = ValidationAlertStyle_STOP; break; + case XML_warning: eAlertStyle = ValidationAlertStyle_WARNING; break; + default: OSL_ENSURE( false, "WorksheetGlobals::finalizeValidationRanges - unknown error style" ); } aValProps.setProperty( PROP_ErrorAlertStyle, eAlertStyle ); // convert dropdown style to API visibility constants - sal_Int16 nVisibility = aIt->mbNoDropDown ? csss::TableValidationVisibility::INVISIBLE : csss::TableValidationVisibility::UNSORTED; + sal_Int16 nVisibility = aIt->mbNoDropDown ? TableValidationVisibility::INVISIBLE : TableValidationVisibility::UNSORTED; aValProps.setProperty( PROP_ShowList, nVisibility ); // messages @@ -1468,99 +1140,36 @@ void WorksheetData::finalizeValidationRanges() const } } -void WorksheetData::finalizeMergedRanges() -{ - MergedRangeList::const_iterator aIt, aEnd; - for( aIt = maMergedRanges.begin(), aEnd = maMergedRanges.end(); aIt != aEnd; ++aIt ) - finalizeMergedRange( aIt->maRange ); - for( aIt = maCenterFillRanges.begin(), aEnd = maCenterFillRanges.end(); aIt != aEnd; ++aIt ) - finalizeMergedRange( aIt->maRange ); -} - -void WorksheetData::finalizeMergedRange( const CellRangeAddress& rRange ) -{ - bool bMultiCol = rRange.StartColumn < rRange.EndColumn; - bool bMultiRow = rRange.StartRow < rRange.EndRow; - - if( bMultiCol || bMultiRow ) try - { - // merge the cell range - Reference< XMergeable > xMerge( getCellRange( rRange ), UNO_QUERY_THROW ); - xMerge->merge( sal_True ); - - // if merging this range worked (no overlapping merged ranges), update cell borders - Reference< XCell > xTopLeft( getCell( CellAddress( getSheetIndex(), rRange.StartColumn, rRange.StartRow ) ), UNO_SET_THROW ); - PropertySet aTopLeftProp( xTopLeft ); - - // copy right border of top-right cell to right border of top-left cell - if( bMultiCol ) - { - PropertySet aTopRightProp( getCell( CellAddress( getSheetIndex(), rRange.EndColumn, rRange.StartRow ) ) ); - BorderLine aLine; - if( aTopRightProp.getProperty( aLine, PROP_RightBorder ) ) - aTopLeftProp.setProperty( PROP_RightBorder, aLine ); - } - - // copy bottom border of bottom-left cell to bottom border of top-left cell - if( bMultiRow ) - { - PropertySet aBottomLeftProp( getCell( CellAddress( getSheetIndex(), rRange.StartColumn, rRange.EndRow ) ) ); - BorderLine aLine; - if( aBottomLeftProp.getProperty( aLine, PROP_BottomBorder ) ) - aTopLeftProp.setProperty( PROP_BottomBorder, aLine ); - } - - // #i93609# merged range in a single row: test if manual row height is needed - if( !bMultiRow ) - { - bool bTextWrap = aTopLeftProp.getBoolProperty( PROP_IsTextWrapped ); - if( !bTextWrap && (xTopLeft->getType() == ::com::sun::star::table::CellContentType_TEXT) ) - { - Reference< XText > xText( xTopLeft, UNO_QUERY ); - bTextWrap = xText.is() && (xText->getString().indexOf( '\x0A' ) >= 0); - } - if( bTextWrap ) - maManualRowHeights.insert( rRange.StartRow ); - } - } - catch( Exception& ) - { - } -} - -void WorksheetData::convertColumns() +void WorksheetGlobals::convertColumns() { sal_Int32 nNextCol = 0; sal_Int32 nMaxCol = mrMaxApiPos.Column; // stores first grouped column index for each level OutlineLevelVec aColLevels; - for( ColumnModelMap::const_iterator aIt = maColModels.begin(), aEnd = maColModels.end(); aIt != aEnd; ++aIt ) + for( ColumnModelRangeMap::iterator aIt = maColModels.begin(), aEnd = maColModels.end(); aIt != aEnd; ++aIt ) { - // convert 1-based OOXML column indexes to 0-based API column indexes - sal_Int32 nFirstCol = ::std::max( aIt->second.mnFirstCol - 1, nNextCol ); - sal_Int32 nLastCol = ::std::min( aIt->second.mnLastCol - 1, nMaxCol ); - + // column indexes are stored 0-based in maColModels + ValueRange aColRange( ::std::max( aIt->first, nNextCol ), ::std::min( aIt->second.second, nMaxCol ) ); // process gap between two column models, use default column model - if( nNextCol < nFirstCol ) - convertColumns( aColLevels, nNextCol, nFirstCol - 1, maDefColModel ); + if( nNextCol < aColRange.mnFirst ) + convertColumns( aColLevels, ValueRange( nNextCol, aColRange.mnFirst - 1 ), maDefColModel ); // process the column model - convertColumns( aColLevels, nFirstCol, nLastCol, aIt->second ); - + convertColumns( aColLevels, aColRange, aIt->second.first ); // cache next column to be processed - nNextCol = nLastCol + 1; + nNextCol = aColRange.mnLast + 1; } // remaining default columns to end of sheet - convertColumns( aColLevels, nNextCol, nMaxCol, maDefColModel ); + convertColumns( aColLevels, ValueRange( nNextCol, nMaxCol ), maDefColModel ); // close remaining column outlines spanning to end of sheet convertOutlines( aColLevels, nMaxCol + 1, 0, false, false ); } -void WorksheetData::convertColumns( OutlineLevelVec& orColLevels, - sal_Int32 nFirstCol, sal_Int32 nLastCol, const ColumnModel& rModel ) +void WorksheetGlobals::convertColumns( OutlineLevelVec& orColLevels, + const ValueRange& rColRange, const ColumnModel& rModel ) { - PropertySet aPropSet( getColumns( nFirstCol, nLastCol ) ); + PropertySet aPropSet( getColumns( rColRange ) ); // column width: convert 'number of characters' to column width in 1/100 mm sal_Int32 nWidth = getUnitConverter().scaleToMm100( rModel.mfWidth, UNIT_DIGIT ); @@ -1575,54 +1184,55 @@ void WorksheetData::convertColumns( OutlineLevelVec& orColLevels, aPropSet.setProperty( PROP_IsVisible, false ); // outline settings for this column range - convertOutlines( orColLevels, nFirstCol, rModel.mnLevel, rModel.mbCollapsed, false ); + convertOutlines( orColLevels, rColRange.mnFirst, rModel.mnLevel, rModel.mbCollapsed, false ); } -void WorksheetData::convertRows() +void WorksheetGlobals::convertRows() { sal_Int32 nNextRow = 0; sal_Int32 nMaxRow = mrMaxApiPos.Row; // stores first grouped row index for each level OutlineLevelVec aRowLevels; - for( RowModelMap::const_iterator aIt = maRowModels.begin(), aEnd = maRowModels.end(); aIt != aEnd; ++aIt ) + for( RowModelRangeMap::iterator aIt = maRowModels.begin(), aEnd = maRowModels.end(); aIt != aEnd; ++aIt ) { - // convert 1-based OOXML row indexes to 0-based API row indexes - sal_Int32 nFirstRow = ::std::max( aIt->second.mnFirstRow - 1, nNextRow ); - sal_Int32 nLastRow = ::std::min( aIt->second.mnLastRow - 1, nMaxRow ); - + // row indexes are stored 0-based in maRowModels + ValueRange aRowRange( ::std::max( aIt->first, nNextRow ), ::std::min( aIt->second.second, nMaxRow ) ); // process gap between two row models, use default row model - if( nNextRow < nFirstRow ) - convertRows( aRowLevels, nNextRow, nFirstRow - 1, maDefRowModel ); + if( nNextRow < aRowRange.mnFirst ) + convertRows( aRowLevels, ValueRange( nNextRow, aRowRange.mnFirst - 1 ), maDefRowModel ); // process the row model - convertRows( aRowLevels, nFirstRow, nLastRow, aIt->second, maDefRowModel.mfHeight ); - + convertRows( aRowLevels, aRowRange, aIt->second.first, maDefRowModel.mfHeight ); // cache next row to be processed - nNextRow = nLastRow + 1; + nNextRow = aRowRange.mnLast + 1; } // remaining default rows to end of sheet - convertRows( aRowLevels, nNextRow, nMaxRow, maDefRowModel ); + convertRows( aRowLevels, ValueRange( nNextRow, nMaxRow ), maDefRowModel ); // close remaining row outlines spanning to end of sheet convertOutlines( aRowLevels, nMaxRow + 1, 0, false, true ); } -void WorksheetData::convertRows( OutlineLevelVec& orRowLevels, - sal_Int32 nFirstRow, sal_Int32 nLastRow, const RowModel& rModel, double fDefHeight ) +void WorksheetGlobals::convertRows( OutlineLevelVec& orRowLevels, + const ValueRange& rRowRange, const RowModel& rModel, double fDefHeight ) { // row height: convert points to row height in 1/100 mm double fHeight = (rModel.mfHeight >= 0.0) ? rModel.mfHeight : fDefHeight; sal_Int32 nHeight = getUnitConverter().scaleToMm100( fHeight, UNIT_POINT ); if( nHeight > 0 ) { + /* Get all rows that have custom height inside the passed row model. + If the model has the custom height flag set, all its rows have + custom height, otherwise get all rows specified in the class member + maManualRowHeights that are inside the passed row model. */ ValueRangeVector aManualRows; if( rModel.mbCustomHeight ) - aManualRows.push_back( ValueRange( nFirstRow, nLastRow ) ); + aManualRows.push_back( rRowRange ); else - maManualRowHeights.intersect( aManualRows, nFirstRow, nLastRow ); + aManualRows = maManualRowHeights.getIntersection( rRowRange ); for( ValueRangeVector::const_iterator aIt = aManualRows.begin(), aEnd = aManualRows.end(); aIt != aEnd; ++aIt ) { - PropertySet aPropSet( getRows( aIt->mnFirst, aIt->mnLast ) ); + PropertySet aPropSet( getRows( *aIt ) ); aPropSet.setProperty( PROP_Height, nHeight ); } } @@ -1630,21 +1240,21 @@ void WorksheetData::convertRows( OutlineLevelVec& orRowLevels, // hidden rows: TODO: #108683# hide rows later? if( rModel.mbHidden ) { - PropertySet aPropSet( getRows( nFirstRow, nLastRow ) ); + PropertySet aPropSet( getRows( rRowRange ) ); aPropSet.setProperty( PROP_IsVisible, false ); } // outline settings for this row range - convertOutlines( orRowLevels, nFirstRow, rModel.mnLevel, rModel.mbCollapsed, true ); + convertOutlines( orRowLevels, rRowRange.mnFirst, rModel.mnLevel, rModel.mbCollapsed, true ); } -void WorksheetData::convertOutlines( OutlineLevelVec& orLevels, +void WorksheetGlobals::convertOutlines( OutlineLevelVec& orLevels, sal_Int32 nColRow, sal_Int32 nLevel, bool bCollapsed, bool bRows ) { /* It is ensured from caller functions, that this function is called without any gaps between the processed column or row ranges. */ - OSL_ENSURE( nLevel >= 0, "WorksheetData::convertOutlines - negative outline level" ); + OSL_ENSURE( nLevel >= 0, "WorksheetGlobals::convertOutlines - negative outline level" ); nLevel = ::std::max< sal_Int32 >( nLevel, 0 ); sal_Int32 nSize = orLevels.size(); @@ -1667,7 +1277,7 @@ void WorksheetData::convertOutlines( OutlineLevelVec& orLevels, } } -void WorksheetData::groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastColRow, bool bCollapse, bool bRows ) +void WorksheetGlobals::groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastColRow, bool bCollapse, bool bRows ) { try { @@ -1675,14 +1285,14 @@ void WorksheetData::groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastC if( bRows ) { CellRangeAddress aRange( getSheetIndex(), 0, nFirstColRow, 0, nLastColRow ); - xOutline->group( aRange, ::com::sun::star::table::TableOrientation_ROWS ); + xOutline->group( aRange, TableOrientation_ROWS ); if( bCollapse ) xOutline->hideDetail( aRange ); } else { CellRangeAddress aRange( getSheetIndex(), nFirstColRow, 0, nLastColRow, 0 ); - xOutline->group( aRange, ::com::sun::star::table::TableOrientation_COLUMNS ); + xOutline->group( aRange, TableOrientation_COLUMNS ); if( bCollapse ) xOutline->hideDetail( aRange ); } @@ -1692,8 +1302,12 @@ void WorksheetData::groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastC } } -void WorksheetData::finalizeDrawings() +void WorksheetGlobals::finalizeDrawings() { + // calculate the current drawing page size (after rows/columns are imported) + PropertySet aRangeProp( getCellRange( CellRangeAddress( getSheetIndex(), 0, 0, mrMaxApiPos.Column, mrMaxApiPos.Row ) ) ); + aRangeProp.getProperty( maDrawPageSize, PROP_Size ); + switch( getFilterType() ) { case FILTER_OOXML: @@ -1705,7 +1319,8 @@ void WorksheetData::finalizeDrawings() break; case FILTER_BIFF: - // TODO: import DFF shapes + // convert BIFF3-BIFF5 drawing objects, or import and convert DFF stream + getBiffDrawing().finalizeImport(); break; case FILTER_UNKNOWN: @@ -1737,109 +1352,56 @@ void WorksheetData::finalizeDrawings() if( maSheetViewSett.isSheetRightToLeft() ) { PropertySet aPropSet( mxSheet ); - aPropSet.setProperty( PROP_TableLayout, ::com::sun::star::text::WritingMode2::RL_TB ); + aPropSet.setProperty( PROP_TableLayout, WritingMode2::RL_TB ); } } // ============================================================================ // ============================================================================ -WorksheetHelper::WorksheetHelper( WorksheetData& rSheetData ) : - WorkbookHelper( rSheetData ), - mrSheetData( rSheetData ) +WorksheetHelper::WorksheetHelper( WorksheetGlobals& rSheetGlob ) : + WorkbookHelper( rSheetGlob ), + mrSheetGlob( rSheetGlob ) { } +/*static*/ WorksheetGlobalsRef WorksheetHelper::constructGlobals( const WorkbookHelper& rHelper, + const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) +{ + WorksheetGlobalsRef xSheetGlob( new WorksheetGlobals( rHelper, rxProgressBar, eSheetType, nSheet ) ); + if( !xSheetGlob->isValidSheet() ) + xSheetGlob.reset(); + return xSheetGlob; +} + WorksheetType WorksheetHelper::getSheetType() const { - return mrSheetData.getSheetType(); + return mrSheetGlob.getSheetType(); } sal_Int16 WorksheetHelper::getSheetIndex() const { - return mrSheetData.getSheetIndex(); + return mrSheetGlob.getSheetIndex(); } const Reference< XSpreadsheet >& WorksheetHelper::getSheet() const { - return mrSheetData.getSheet(); + return mrSheetGlob.getSheet(); } Reference< XCell > WorksheetHelper::getCell( const CellAddress& rAddress ) const { - return mrSheetData.getCell( rAddress ); -} - -Reference< XCell > WorksheetHelper::getCell( const OUString& rAddressStr, CellAddress* opAddress ) const -{ - CellAddress aAddress; - if( getAddressConverter().convertToCellAddress( aAddress, rAddressStr, mrSheetData.getSheetIndex(), true ) ) - { - if( opAddress ) *opAddress = aAddress; - return mrSheetData.getCell( aAddress ); - } - return Reference< XCell >(); -} - -Reference< XCell > WorksheetHelper::getCell( const BinAddress& rBinAddress, CellAddress* opAddress ) const -{ - CellAddress aAddress; - if( getAddressConverter().convertToCellAddress( aAddress, rBinAddress, mrSheetData.getSheetIndex(), true ) ) - { - if( opAddress ) *opAddress = aAddress; - return mrSheetData.getCell( aAddress ); - } - return Reference< XCell >(); + return mrSheetGlob.getCell( rAddress ); } Reference< XCellRange > WorksheetHelper::getCellRange( const CellRangeAddress& rRange ) const { - return mrSheetData.getCellRange( rRange ); -} - -Reference< XCellRange > WorksheetHelper::getCellRange( const OUString& rRangeStr, CellRangeAddress* opRange ) const -{ - CellRangeAddress aRange; - if( getAddressConverter().convertToCellRange( aRange, rRangeStr, mrSheetData.getSheetIndex(), true, true ) ) - { - if( opRange ) *opRange = aRange; - return mrSheetData.getCellRange( aRange ); - } - return Reference< XCellRange >(); -} - -Reference< XCellRange > WorksheetHelper::getCellRange( const BinRange& rBinRange, CellRangeAddress* opRange ) const -{ - CellRangeAddress aRange; - if( getAddressConverter().convertToCellRange( aRange, rBinRange, mrSheetData.getSheetIndex(), true, true ) ) - { - if( opRange ) *opRange = aRange; - return mrSheetData.getCellRange( aRange ); - } - return Reference< XCellRange >(); + return mrSheetGlob.getCellRange( rRange ); } Reference< XSheetCellRanges > WorksheetHelper::getCellRangeList( const ApiCellRangeList& rRanges ) const { - return mrSheetData.getCellRangeList( rRanges ); -} - -Reference< XSheetCellRanges > WorksheetHelper::getCellRangeList( - const OUString& rRangesStr, ApiCellRangeList* opRanges ) const -{ - ApiCellRangeList aRanges; - getAddressConverter().convertToCellRangeList( aRanges, rRangesStr, mrSheetData.getSheetIndex(), true ); - if( opRanges ) *opRanges = aRanges; - return mrSheetData.getCellRangeList( aRanges ); -} - -Reference< XSheetCellRanges > WorksheetHelper::getCellRangeList( - const BinRangeList& rBinRanges, ApiCellRangeList* opRanges ) const -{ - ApiCellRangeList aRanges; - getAddressConverter().convertToCellRangeList( aRanges, rBinRanges, mrSheetData.getSheetIndex(), true ); - if( opRanges ) *opRanges = aRanges; - return mrSheetData.getCellRangeList( aRanges ); + return mrSheetGlob.getCellRangeList( rRanges ); } CellAddress WorksheetHelper::getCellAddress( const Reference< XCell >& rxCell ) @@ -1864,267 +1426,112 @@ CellRangeAddress WorksheetHelper::getRangeAddress( const Reference< XCellRange > Reference< XCellRange > WorksheetHelper::getColumn( sal_Int32 nCol ) const { - return mrSheetData.getColumn( nCol ); + return mrSheetGlob.getColumn( nCol ); } Reference< XCellRange > WorksheetHelper::getRow( sal_Int32 nRow ) const { - return mrSheetData.getRow( nRow ); + return mrSheetGlob.getRow( nRow ); } -Reference< XTableColumns > WorksheetHelper::getColumns( sal_Int32 nFirstCol, sal_Int32 nLastCol ) const +Reference< XTableColumns > WorksheetHelper::getColumns( const ValueRange& rColRange ) const { - return mrSheetData.getColumns( nFirstCol, nLastCol ); + return mrSheetGlob.getColumns( rColRange ); } -Reference< XTableRows > WorksheetHelper::getRows( sal_Int32 nFirstRow, sal_Int32 nLastRow ) const +Reference< XTableRows > WorksheetHelper::getRows( const ValueRange& rRowRange ) const { - return mrSheetData.getRows( nFirstRow, nLastRow ); + return mrSheetGlob.getRows( rRowRange ); } Reference< XDrawPage > WorksheetHelper::getDrawPage() const { - return mrSheetData.getDrawPage(); + return mrSheetGlob.getDrawPage(); } Point WorksheetHelper::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const { - return mrSheetData.getCellPosition( nCol, nRow ); + return mrSheetGlob.getCellPosition( nCol, nRow ); } Size WorksheetHelper::getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const { - return mrSheetData.getCellSize( nCol, nRow ); + return mrSheetGlob.getCellSize( nCol, nRow ); } Size WorksheetHelper::getDrawPageSize() const { - return mrSheetData.getDrawPageSize(); + return mrSheetGlob.getDrawPageSize(); } -WorksheetSettings& WorksheetHelper::getWorksheetSettings() const -{ - return mrSheetData.getWorksheetSettings(); -} - -SharedFormulaBuffer& WorksheetHelper::getSharedFormulas() const +SheetDataBuffer& WorksheetHelper::getSheetData() const { - return mrSheetData.getSharedFormulas(); + return mrSheetGlob.getSheetData(); } CondFormatBuffer& WorksheetHelper::getCondFormats() const { - return mrSheetData.getCondFormats(); + return mrSheetGlob.getCondFormats(); } CommentsBuffer& WorksheetHelper::getComments() const { - return mrSheetData.getComments(); + return mrSheetGlob.getComments(); } AutoFilterBuffer& WorksheetHelper::getAutoFilters() const { - return mrSheetData.getAutoFilters(); + return mrSheetGlob.getAutoFilters(); } QueryTableBuffer& WorksheetHelper::getQueryTables() const { - return mrSheetData.getQueryTables(); + return mrSheetGlob.getQueryTables(); } -PageSettings& WorksheetHelper::getPageSettings() const -{ - return mrSheetData.getPageSettings(); -} - -SheetViewSettings& WorksheetHelper::getSheetViewSettings() const -{ - return mrSheetData.getSheetViewSettings(); -} - -VmlDrawing& WorksheetHelper::getVmlDrawing() const -{ - return mrSheetData.getVmlDrawing(); -} - -void WorksheetHelper::setStringCell( const Reference< XCell >& rxCell, const OUString& rText ) const -{ - OSL_ENSURE( rxCell.is(), "WorksheetHelper::setStringCell - missing cell interface" ); - Reference< XText > xText( rxCell, UNO_QUERY ); - if( xText.is() ) - xText->setString( rText ); -} - -void WorksheetHelper::setSharedStringCell( const Reference< XCell >& rxCell, sal_Int32 nStringId, sal_Int32 nXfId ) const -{ - OSL_ENSURE( rxCell.is(), "WorksheetHelper::setSharedStringCell - missing cell interface" ); - getSharedStrings().convertString( Reference< XText >( rxCell, UNO_QUERY ), nStringId, nXfId ); -} - -void WorksheetHelper::setDateTimeCell( const Reference< XCell >& rxCell, const DateTime& rDateTime ) const -{ - OSL_ENSURE( rxCell.is(), "WorksheetHelper::setDateTimeCell - missing cell interface" ); - // write serial date/time value into the cell - double fSerial = getUnitConverter().calcSerialFromDateTime( rDateTime ); - rxCell->setValue( fSerial ); - // set appropriate number format - using namespace ::com::sun::star::util::NumberFormat; - sal_Int16 nStdFmt = (fSerial < 1.0) ? TIME : (((rDateTime.Hours > 0) || (rDateTime.Minutes > 0) || (rDateTime.Seconds > 0)) ? DATETIME : DATE); - setStandardNumFmt( rxCell, nStdFmt ); -} - -void WorksheetHelper::setBooleanCell( const Reference< XCell >& rxCell, bool bValue ) const +WorksheetSettings& WorksheetHelper::getWorksheetSettings() const { - OSL_ENSURE( rxCell.is(), "WorksheetHelper::setBooleanCell - missing cell interface" ); - rxCell->setFormula( mrSheetData.getBooleanFormula( bValue ) ); + return mrSheetGlob.getWorksheetSettings(); } -void WorksheetHelper::setErrorCell( const Reference< XCell >& rxCell, const OUString& rErrorCode ) const +PageSettings& WorksheetHelper::getPageSettings() const { - setErrorCell( rxCell, getUnitConverter().calcBiffErrorCode( rErrorCode ) ); + return mrSheetGlob.getPageSettings(); } -void WorksheetHelper::setErrorCell( const Reference< XCell >& rxCell, sal_uInt8 nErrorCode ) const +SheetViewSettings& WorksheetHelper::getSheetViewSettings() const { - Reference< XFormulaTokens > xTokens( rxCell, UNO_QUERY ); - OSL_ENSURE( xTokens.is(), "WorksheetHelper::setErrorCell - missing formula interface" ); - if( xTokens.is() ) - { - SimpleFormulaContext aContext( xTokens, false, false ); - getFormulaParser().convertErrorToFormula( aContext, nErrorCode ); - } + return mrSheetGlob.getSheetViewSettings(); } -void WorksheetHelper::setCell( CellModel& orModel ) const +VmlDrawing& WorksheetHelper::getVmlDrawing() const { - OSL_ENSURE( orModel.mxCell.is(), "WorksheetHelper::setCell - missing cell interface" ); - if( orModel.mbHasValueStr ) switch( orModel.mnCellType ) - { - case XML_b: - setBooleanCell( orModel.mxCell, orModel.maValueStr.toDouble() != 0.0 ); - // #108770# set 'Standard' number format for all Boolean cells - orModel.mnNumFmtId = 0; - break; - case XML_n: - orModel.mxCell->setValue( orModel.maValueStr.toDouble() ); - break; - case XML_e: - setErrorCell( orModel.mxCell, orModel.maValueStr ); - break; - case XML_str: - setStringCell( orModel.mxCell, orModel.maValueStr ); - break; - case XML_s: - setSharedStringCell( orModel.mxCell, orModel.maValueStr.toInt32(), orModel.mnXfId ); - break; - } + return mrSheetGlob.getVmlDrawing(); } -void WorksheetHelper::setStandardNumFmt( const Reference< XCell >& rxCell, sal_Int16 nStdNumFmt ) const +BiffSheetDrawing& WorksheetHelper::getBiffDrawing() const { - try - { - Reference< XNumberFormatsSupplier > xNumFmtsSupp( getDocument(), UNO_QUERY_THROW ); - Reference< XNumberFormatTypes > xNumFmtTypes( xNumFmtsSupp->getNumberFormats(), UNO_QUERY_THROW ); - sal_Int32 nIndex = xNumFmtTypes->getStandardFormat( nStdNumFmt, Locale() ); - PropertySet aPropSet( rxCell ); - aPropSet.setProperty( PROP_NumberFormat, nIndex ); - } - catch( Exception& ) - { - } + return mrSheetGlob.getBiffDrawing(); } void WorksheetHelper::setSheetType( WorksheetType eSheetType ) { - mrSheetData.setSheetType( eSheetType ); -} - -void WorksheetHelper::setCellFormat( const CellModel& rModel ) -{ - mrSheetData.setCellFormat( rModel ); -} - -void WorksheetHelper::setMergedRange( const CellRangeAddress& rRange ) -{ - mrSheetData.setMergedRange( rRange ); + mrSheetGlob.setSheetType( eSheetType ); } void WorksheetHelper::setPageBreak( const PageBreakModel& rModel, bool bRowBreak ) { - mrSheetData.setPageBreak( rModel, bRowBreak ); + mrSheetGlob.setPageBreak( rModel, bRowBreak ); } void WorksheetHelper::setHyperlink( const HyperlinkModel& rModel ) { - mrSheetData.setHyperlink( rModel ); + mrSheetGlob.setHyperlink( rModel ); } void WorksheetHelper::setValidation( const ValidationModel& rModel ) { - mrSheetData.setValidation( rModel ); -} - -void WorksheetHelper::setTableOperation( const CellRangeAddress& rRange, const DataTableModel& rModel ) const -{ - OSL_ENSURE( getAddressConverter().checkCellRange( rRange, true, false ), "WorksheetHelper::setTableOperation - invalid range" ); - bool bOk = false; - if( !rModel.mbRef1Deleted && (rModel.maRef1.getLength() > 0) && (rRange.StartColumn > 0) && (rRange.StartRow > 0) ) - { - CellRangeAddress aOpRange = rRange; - CellAddress aRef1, aRef2; - if( getAddressConverter().convertToCellAddress( aRef1, rModel.maRef1, mrSheetData.getSheetIndex(), true ) ) try - { - if( rModel.mb2dTable ) - { - if( !rModel.mbRef2Deleted && getAddressConverter().convertToCellAddress( aRef2, rModel.maRef2, mrSheetData.getSheetIndex(), true ) ) - { - // API call expects input values inside operation range - --aOpRange.StartColumn; - --aOpRange.StartRow; - // formula range is top-left cell of operation range - CellRangeAddress aFormulaRange( mrSheetData.getSheetIndex(), aOpRange.StartColumn, aOpRange.StartRow, aOpRange.StartColumn, aOpRange.StartRow ); - // set multiple operation - Reference< XMultipleOperation > xMultOp( mrSheetData.getCellRange( aOpRange ), UNO_QUERY_THROW ); - xMultOp->setTableOperation( aFormulaRange, ::com::sun::star::sheet::TableOperationMode_BOTH, aRef2, aRef1 ); - bOk = true; - } - } - else if( rModel.mbRowTable ) - { - // formula range is column to the left of operation range - CellRangeAddress aFormulaRange( mrSheetData.getSheetIndex(), aOpRange.StartColumn - 1, aOpRange.StartRow, aOpRange.StartColumn - 1, aOpRange.EndRow ); - // API call expects input values (top row) inside operation range - --aOpRange.StartRow; - // set multiple operation - Reference< XMultipleOperation > xMultOp( mrSheetData.getCellRange( aOpRange ), UNO_QUERY_THROW ); - xMultOp->setTableOperation( aFormulaRange, ::com::sun::star::sheet::TableOperationMode_ROW, aRef1, aRef1 ); - bOk = true; - } - else - { - // formula range is row above operation range - CellRangeAddress aFormulaRange( mrSheetData.getSheetIndex(), aOpRange.StartColumn, aOpRange.StartRow - 1, aOpRange.EndColumn, aOpRange.StartRow - 1 ); - // API call expects input values (left column) inside operation range - --aOpRange.StartColumn; - // set multiple operation - Reference< XMultipleOperation > xMultOp( mrSheetData.getCellRange( aOpRange ), UNO_QUERY_THROW ); - xMultOp->setTableOperation( aFormulaRange, ::com::sun::star::sheet::TableOperationMode_COLUMN, aRef1, aRef1 ); - bOk = true; - } - } - catch( Exception& ) - { - } - } - - // on error: fill cell range with error codes - if( !bOk ) - { - for( CellAddress aPos( mrSheetData.getSheetIndex(), rRange.StartColumn, rRange.StartRow ); aPos.Row <= rRange.EndRow; ++aPos.Row ) - for( aPos.Column = rRange.StartColumn; aPos.Column <= rRange.EndColumn; ++aPos.Column ) - setErrorCell( mrSheetData.getCell( aPos ), BIFF_ERR_REF ); - } + mrSheetGlob.setValidation( rModel ); } void WorksheetHelper::setLabelRanges( const ApiCellRangeList& rColRanges, const ApiCellRangeList& rRowRanges ) @@ -2181,107 +1588,100 @@ void WorksheetHelper::setLabelRanges( const ApiCellRangeList& rColRanges, const void WorksheetHelper::setDrawingPath( const OUString& rDrawingPath ) { - mrSheetData.setDrawingPath( rDrawingPath ); + mrSheetGlob.setDrawingPath( rDrawingPath ); } void WorksheetHelper::setVmlDrawingPath( const OUString& rVmlDrawingPath ) { - mrSheetData.setVmlDrawingPath( rVmlDrawingPath ); + mrSheetGlob.setVmlDrawingPath( rVmlDrawingPath ); } void WorksheetHelper::extendUsedArea( const CellAddress& rAddress ) { - mrSheetData.extendUsedArea( rAddress ); + mrSheetGlob.extendUsedArea( rAddress ); } void WorksheetHelper::extendUsedArea( const CellRangeAddress& rRange ) { - mrSheetData.extendUsedArea( rRange ); + mrSheetGlob.extendUsedArea( rRange ); } void WorksheetHelper::extendShapeBoundingBox( const Rectangle& rShapeRect ) { - mrSheetData.extendShapeBoundingBox( rShapeRect ); + mrSheetGlob.extendShapeBoundingBox( rShapeRect ); } void WorksheetHelper::setBaseColumnWidth( sal_Int32 nWidth ) { - mrSheetData.setBaseColumnWidth( nWidth ); + mrSheetGlob.setBaseColumnWidth( nWidth ); } void WorksheetHelper::setDefaultColumnWidth( double fWidth ) { - mrSheetData.setDefaultColumnWidth( fWidth ); + mrSheetGlob.setDefaultColumnWidth( fWidth ); } void WorksheetHelper::setDefaultColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) { - mrSheetData.convertColumnFormat( nFirstCol, nLastCol, nXfId ); + mrSheetGlob.convertColumnFormat( nFirstCol, nLastCol, nXfId ); } void WorksheetHelper::setColumnModel( const ColumnModel& rModel ) { - mrSheetData.setColumnModel( rModel ); + mrSheetGlob.setColumnModel( rModel ); } void WorksheetHelper::setDefaultRowSettings( double fHeight, bool bCustomHeight, bool bHidden, bool bThickTop, bool bThickBottom ) { - mrSheetData.setDefaultRowSettings( fHeight, bCustomHeight, bHidden, bThickTop, bThickBottom ); + mrSheetGlob.setDefaultRowSettings( fHeight, bCustomHeight, bHidden, bThickTop, bThickBottom ); } void WorksheetHelper::setRowModel( const RowModel& rModel ) { - mrSheetData.setRowModel( rModel ); -} - -void WorksheetHelper::initializeWorksheetImport() -{ - mrSheetData.initializeWorksheetImport(); + mrSheetGlob.setRowModel( rModel ); } -void WorksheetHelper::finalizeWorksheetImport() +void WorksheetHelper::setManualRowHeight( sal_Int32 nRow ) { - mrSheetData.finalizeWorksheetImport(); + mrSheetGlob.setManualRowHeight( nRow ); } -// ============================================================================ - -namespace prv { - -WorksheetDataOwner::WorksheetDataOwner( WorksheetDataRef xSheetData ) : - mxSheetData( xSheetData ) +void WorksheetHelper::putValue( const CellAddress& rAddress, double fValue ) const { + Reference< XCell > xCell = getCell( rAddress ); + OSL_ENSURE( xCell.is(), "WorksheetHelper::putValue - missing cell interface" ); + if( xCell.is() ) xCell->setValue( fValue ); } -WorksheetDataOwner::~WorksheetDataOwner() +void WorksheetHelper::putString( const CellAddress& rAddress, const OUString& rText ) const { + Reference< XText > xText( getCell( rAddress ), UNO_QUERY ); + OSL_ENSURE( xText.is(), "WorksheetHelper::putString - missing text interface" ); + if( xText.is() ) xText->setString( rText ); } -} // namespace prv - -// ---------------------------------------------------------------------------- - -WorksheetHelperRoot::WorksheetHelperRoot( const WorkbookHelper& rHelper, const ISegmentProgressBarRef& rxProgressBar, WorksheetType eSheetType, sal_Int16 nSheet ) : - prv::WorksheetDataOwner( prv::WorksheetDataRef( new WorksheetData( rHelper, rxProgressBar, eSheetType, nSheet ) ) ), - WorksheetHelper( *mxSheetData ) +void WorksheetHelper::putRichString( const CellAddress& rAddress, const RichString& rString, const Font* pFirstPortionFont ) const { + Reference< XText > xText( getCell( rAddress ), UNO_QUERY ); + OSL_ENSURE( xText.is(), "WorksheetHelper::putRichString - missing text interface" ); + rString.convert( xText, pFirstPortionFont ); } -WorksheetHelperRoot::WorksheetHelperRoot( const WorksheetHelper& rHelper ) : - prv::WorksheetDataOwner( prv::WorksheetDataRef() ), - WorksheetHelper( rHelper ) +void WorksheetHelper::putFormulaTokens( const CellAddress& rAddress, const ApiTokenSequence& rTokens ) const { + Reference< XFormulaTokens > xTokens( getCell( rAddress ), UNO_QUERY ); + OSL_ENSURE( xTokens.is(), "WorksheetHelper::putFormulaTokens - missing token interface" ); + if( xTokens.is() ) xTokens->setTokens( rTokens ); } -WorksheetHelperRoot::WorksheetHelperRoot( const WorksheetHelperRoot& rHelper ) : - prv::WorksheetDataOwner( rHelper.mxSheetData ), - WorksheetHelper( rHelper ) +void WorksheetHelper::initializeWorksheetImport() { + mrSheetGlob.initializeWorksheetImport(); } -bool WorksheetHelperRoot::isValidSheet() const +void WorksheetHelper::finalizeWorksheetImport() { - return mxSheetData->isValidSheet(); + mrSheetGlob.finalizeWorksheetImport(); } // ============================================================================ |