sc/source/filter/inc/sheetdatabuffer.hxx | 19 ++++ sc/source/filter/inc/stylesbuffer.hxx | 4 + sc/source/filter/oox/sheetdatabuffer.cxx | 122 +++++++++++++++++++++++++++---- sc/source/filter/oox/stylesbuffer.cxx | 64 ++++++++++++++++ 4 files changed, 193 insertions(+), 16 deletions(-)
New commits: commit 9ae9b2f665b3caa9cc584512c26dfa899e1d2d45 Author: Noel Power <[email protected]> Date: Fri May 24 09:52:12 2013 +0100 reorg styles code slightly, process normal (and row ) style in own method Change-Id: I701d12cf8f672824d7cfca1e995f02040fdd3095 diff --git a/sc/source/filter/inc/sheetdatabuffer.hxx b/sc/source/filter/inc/sheetdatabuffer.hxx index 103418a..563145e 100644 --- a/sc/source/filter/inc/sheetdatabuffer.hxx +++ b/sc/source/filter/inc/sheetdatabuffer.hxx @@ -192,7 +192,7 @@ private: /** Writes all cell formatting attributes to the passed cell range list. (depreciates writeXfIdRangeProperties) */ void writeXfIdRangeListProperties( sal_Int32 nXfId, sal_Int32 nNumFmtId, const ApiCellRangeList& rRanges ) const; void applyCellMerging( const ::com::sun::star::table::CellRangeAddress& rRange ); - + void addColXfStyle( sal_Int32 nXfId, sal_Int32 nFormatId, const ::com::sun::star::table::CellRangeAddress& rAddress, bool bProcessRowRange = false ); private: /** Stores cell range address and formula token array of an array formula. */ typedef ::std::pair< ::com::sun::star::table::CellRangeAddress, ApiTokenSequence > ArrayFormula; @@ -217,6 +217,22 @@ private: typedef ::std::pair< sal_Int32, sal_Int32 > XfIdNumFmtKey; typedef ::std::map< XfIdNumFmtKey, ApiCellRangeList > XfIdRangeListMap; + typedef ::std::pair< sal_Int32, sal_Int32 > RowRange; + struct RowRangeStyle + { + sal_Int32 mnStartRow; + sal_Int32 mnEndRow; + XfIdNumFmtKey mnNumFmt; + }; + struct StyleRowRangeComp + { + bool operator() (const RowRangeStyle& lhs, const RowRangeStyle& rhs) const + { + return lhs.mnEndRow<rhs.mnStartRow; + } + }; + typedef ::std::set< RowRangeStyle, StyleRowRangeComp > RowStyles; + typedef ::std::map< sal_Int32, RowStyles > ColStyles; /** Stores information about a merged cell range. */ struct MergedRange { @@ -230,6 +246,7 @@ private: }; typedef ::std::list< MergedRange > MergedRangeList; + ColStyles maStylesPerColumn; /// Stores cell styles by column ( in row ranges ) CellBlockBuffer maCellBlocks; /// Manages all open cell blocks. ArrayFormulaList maArrayFormulas; /// All array formulas in the sheet. TableOperationList maTableOperations; /// All table operations in the sheet. diff --git a/sc/source/filter/oox/sheetdatabuffer.cxx b/sc/source/filter/oox/sheetdatabuffer.cxx index 48b5e8e..174842a 100644 --- a/sc/source/filter/oox/sheetdatabuffer.cxx +++ b/sc/source/filter/oox/sheetdatabuffer.cxx @@ -346,6 +346,66 @@ void addIfNotInMyMap( StylesBuffer& rStyles, std::map< std::pair< sal_Int32, sal } } +void SheetDataBuffer::addColXfStyle( sal_Int32 nXfId, sal_Int32 nFormatId, const ::com::sun::star::table::CellRangeAddress& rAddress, bool bProcessRowRange ) +{ + RowRangeStyle aStyleRows; + aStyleRows.mnNumFmt.first = nXfId; + aStyleRows.mnNumFmt.second = nFormatId; + aStyleRows.mnStartRow = rAddress.StartRow; + aStyleRows.mnEndRow = rAddress.EndRow; + for ( sal_Int32 nCol = rAddress.StartColumn; nCol <= rAddress.EndColumn; ++nCol ) + { + if ( !bProcessRowRange ) + maStylesPerColumn[ nCol ].insert( aStyleRows ); + else + { + RowStyles& rRowStyles = maStylesPerColumn[ nCol ]; + // If the rowrange style includes rows already + // allocated to a style then we need to split + // the range style Rows into sections ( to + // occupy only rows that have no style definition ) + + // We dont want to set any rowstyle 'rows' + // for rows where there is an existing 'style' ) + std::vector< RowRangeStyle > aRangeRowsSplits; + + RowStyles::iterator rows_it = rRowStyles.begin(); + RowStyles::iterator rows_end = rRowStyles.end(); + bool bAddRange = true; + for ( ; rows_it != rows_end; ++rows_it ) + { + const RowRangeStyle& r = *rows_it; + // if row is completely within existing style, discard it + if ( aStyleRows.mnStartRow >= r.mnStartRow && aStyleRows.mnEndRow <= r.mnEndRow ) + bAddRange = false; + else if ( aStyleRows.mnStartRow <= r.mnStartRow ) + { + // not intersecting at all?, if so finish as none left + // to check ( row ranges are in ascending order + if ( aStyleRows.mnEndRow < r.mnStartRow ) + break; + else if ( aStyleRows.mnEndRow <= r.mnEndRow ) + { + aStyleRows.mnEndRow = r.mnStartRow - 1; + break; + } + if ( aStyleRows.mnStartRow < r.mnStartRow ) + { + RowRangeStyle aSplit = aStyleRows; + aSplit.mnEndRow = r.mnStartRow - 1; + aRangeRowsSplits.push_back( aSplit ); + } + } + } + std::vector< RowRangeStyle >::iterator splits_it = aRangeRowsSplits.begin(); + std::vector< RowRangeStyle >::iterator splits_end = aRangeRowsSplits.end(); + for ( ; splits_it != splits_end; ++splits_it ) + rRowStyles.insert( *splits_it ); + if ( bAddRange ) + rRowStyles.insert( aStyleRows ); + } + } +} void SheetDataBuffer::finalizeImport() { // insert all cells of all open cell blocks @@ -362,49 +422,19 @@ void SheetDataBuffer::finalizeImport() // write default formatting of remaining row range maXfIdRowRangeList[ maXfIdRowRange.mnXfId ].push_back( maXfIdRowRange.maRowRange ); - typedef ::std::pair< sal_Int32, sal_Int32 > RowRange; - struct RowRangeStyle - { - sal_Int32 mnStartRow; - sal_Int32 mnEndRow; - XfIdNumFmtKey mnNumFmt; - }; - struct StyleRowRangeComp - { - bool operator() (const RowRangeStyle& lhs, const RowRangeStyle& rhs) const - { - return lhs.mnEndRow<rhs.mnStartRow; - } - }; - - typedef ::std::set< RowRangeStyle, StyleRowRangeComp > RowStyles; - typedef ::std::map< sal_Int32, RowStyles > ColStyles; - - ColStyles aStylesPerColumn; - StylesBuffer& rStyles = getStyles(); - std::map< std::pair< sal_Int32, sal_Int32 >, ApiCellRangeList > rangeStyleListMap; - for( XfIdRangeListMap::const_iterator aIt = maXfIdRangeLists.begin(), aEnd = maXfIdRangeLists.end(); aIt != aEnd; ++aIt ) + { addIfNotInMyMap( getStyles(), rangeStyleListMap, aIt->first.first, aIt->first.second, aIt->second ); - + } // gather all ranges that have the same style and apply them in bulk for ( std::map< std::pair< sal_Int32, sal_Int32 >, ApiCellRangeList >::iterator it = rangeStyleListMap.begin(), it_end = rangeStyleListMap.end(); it != it_end; ++it ) { const ApiCellRangeList& rRanges( it->second ); for ( ApiCellRangeList::const_iterator it_range = rRanges.begin(), it_rangeend = rRanges.end(); it_range!=it_rangeend; ++it_range ) - { - RowRangeStyle aStyleRows; - aStyleRows.mnNumFmt.first = it->first.first; - aStyleRows.mnNumFmt.second = it->first.second; - aStyleRows.mnStartRow = it_range->StartRow; - aStyleRows.mnEndRow = it_range->EndRow; - for ( sal_Int32 nCol = it_range->StartColumn; nCol <= it_range->EndColumn; ++nCol ) - aStylesPerColumn[ nCol ].insert( aStyleRows ); - } + addColXfStyle( it->first.first, it->first.second, *it_range ); } - // process row ranges for each column, don't overwrite any existing row entries for a column for ( std::map< sal_Int32, std::vector< ValueRange > >::iterator it = maXfIdRowRangeList.begin(), it_end = maXfIdRowRangeList.end(); it != it_end; ++it ) { ApiCellRangeList rangeList; @@ -412,64 +442,17 @@ void SheetDataBuffer::finalizeImport() // get all row ranges for id for ( std::vector< ValueRange >::iterator rangeIter = it->second.begin(), rangeIter_end = it->second.end(); rangeIter != rangeIter_end; ++rangeIter ) { - RowRangeStyle aStyleRows; - aStyleRows.mnNumFmt.first = it->first; - if ( aStyleRows.mnNumFmt.first == -1 ) // dud + if ( it->first == -1 ) // it's a dud skip it continue; - aStyleRows.mnNumFmt.second = -1; - aStyleRows.mnStartRow = rangeIter->mnFirst; - aStyleRows.mnEndRow = rangeIter->mnLast; - for ( sal_Int32 nCol = 0; nCol <= rAddrConv.getMaxApiAddress().Column; ++nCol ) - { - RowStyles& rRowStyles = aStylesPerColumn[ nCol ]; - // If the rowrange style includes rows already - // allocated to a style then we need to split - // the range style Rows into sections ( to - // occupy only rows that have no style definition ) - - // We dont want to set any rowstyle 'rows' - // for rows where there is an existing 'style' ) - std::vector< RowRangeStyle > aRangeRowsSplits; - - RowStyles::iterator rows_it = rRowStyles.begin(); - RowStyles::iterator rows_end = rRowStyles.end(); - bool bAddRange = true; - for ( ; rows_it != rows_end; ++rows_it ) - { - const RowRangeStyle& r = *rows_it; - // if row is completely within existing style, discard it - if ( aStyleRows.mnStartRow >= r.mnStartRow && aStyleRows.mnEndRow <= r.mnEndRow ) - bAddRange = false; - else if ( aStyleRows.mnStartRow <= r.mnStartRow ) - { - // not intersecting at all?, if so finish as none left - // to check ( row ranges are in ascending order - if ( aStyleRows.mnEndRow < r.mnStartRow ) - break; - else if ( aStyleRows.mnEndRow <= r.mnEndRow ) - { - aStyleRows.mnEndRow = r.mnStartRow - 1; - break; - } - if ( aStyleRows.mnStartRow < r.mnStartRow ) - { - RowRangeStyle aSplit = aStyleRows; - aSplit.mnEndRow = r.mnStartRow - 1; - aRangeRowsSplits.push_back( aSplit ); - } - } - } - std::vector< RowRangeStyle >::iterator splits_it = aRangeRowsSplits.begin(); - std::vector< RowRangeStyle >::iterator splits_end = aRangeRowsSplits.end(); - for ( ; splits_it != splits_end; ++splits_it ) - rRowStyles.insert( *splits_it ); - if ( bAddRange ) - rRowStyles.insert( aStyleRows ); - } + CellRangeAddress aRange( getSheetIndex(), 0, rangeIter->mnFirst, rAddrConv.getMaxApiAddress().Column, rangeIter->mnLast ); + + addColXfStyle( it->first, -1, aRange, true ); } } + ScDocument& rDoc = getScDocument(); - for ( ColStyles::iterator col = aStylesPerColumn.begin(), col_end = aStylesPerColumn.end(); col != col_end; ++col ) + StylesBuffer& rStyles = getStyles(); + for ( ColStyles::iterator col = maStylesPerColumn.begin(), col_end = maStylesPerColumn.end(); col != col_end; ++col ) { RowStyles& rRowStyles = col->second; std::list<ScAttrEntry> aAttrs; @@ -497,6 +480,7 @@ void SheetDataBuffer::finalizeImport() rDoc.SetAttrEntries(nScCol, getSheetIndex(), pData, static_cast<SCSIZE>(nAttrSize)); } + // merge all cached merged ranges and update right/bottom cell borders for( MergedRangeList::iterator aIt = maMergedRanges.begin(), aEnd = maMergedRanges.end(); aIt != aEnd; ++aIt ) applyCellMerging( aIt->maRange ); commit 4190fd92c6426f40e5ef65a77f3d31e7527db0b9 Author: Noel Power <[email protected]> Date: Thu May 23 11:50:28 2013 +0100 improve cell style xls[x|m] import performance This change reorganizes the styles by column ( and by row ranges in that column ) so we can apply ScAttrEntry entries directly via Document.SetAttrEntries(...) this is what the binary filter does also. Change-Id: Ice1130d7afccf0be77db24a12f2515eca9c88713 diff --git a/sc/source/filter/inc/stylesbuffer.hxx b/sc/source/filter/inc/stylesbuffer.hxx index 77654c7..2195ab0 100644 --- a/sc/source/filter/inc/stylesbuffer.hxx +++ b/sc/source/filter/inc/stylesbuffer.hxx @@ -35,6 +35,8 @@ #include "stlsheet.hxx" #include <editeng/svxenum.hxx> #include <editeng/frmdir.hxx> +#include "attarray.hxx" +#include <list> class ScMarkData; namespace com { namespace sun { namespace star { @@ -719,6 +721,8 @@ public: inline const Protection& getProtection() const { return maProtection; } void writeToMarkData( ::ScMarkData& rMarkData, sal_Int32 nNumFmtId ); + void applyPatternToAttrList( ::std::list<ScAttrEntry>& rAttrs, SCROW nRow1, SCROW nRow2, + sal_uInt32 nForceScNumFmt ); /** Writes all formatting attributes to the passed property map. */ void writeToPropertyMap( PropertyMap& rPropMap ) const; /** Writes all formatting attributes to the passed property set. */ diff --git a/sc/source/filter/oox/sheetdatabuffer.cxx b/sc/source/filter/oox/sheetdatabuffer.cxx index 11a057d..48b5e8e 100644 --- a/sc/source/filter/oox/sheetdatabuffer.cxx +++ b/sc/source/filter/oox/sheetdatabuffer.cxx @@ -361,6 +361,50 @@ void SheetDataBuffer::finalizeImport() // write default formatting of remaining row range maXfIdRowRangeList[ maXfIdRowRange.mnXfId ].push_back( maXfIdRowRange.maRowRange ); + + typedef ::std::pair< sal_Int32, sal_Int32 > RowRange; + struct RowRangeStyle + { + sal_Int32 mnStartRow; + sal_Int32 mnEndRow; + XfIdNumFmtKey mnNumFmt; + }; + struct StyleRowRangeComp + { + bool operator() (const RowRangeStyle& lhs, const RowRangeStyle& rhs) const + { + return lhs.mnEndRow<rhs.mnStartRow; + } + }; + + typedef ::std::set< RowRangeStyle, StyleRowRangeComp > RowStyles; + typedef ::std::map< sal_Int32, RowStyles > ColStyles; + + ColStyles aStylesPerColumn; + StylesBuffer& rStyles = getStyles(); + + std::map< std::pair< sal_Int32, sal_Int32 >, ApiCellRangeList > rangeStyleListMap; + + for( XfIdRangeListMap::const_iterator aIt = maXfIdRangeLists.begin(), aEnd = maXfIdRangeLists.end(); aIt != aEnd; ++aIt ) + addIfNotInMyMap( getStyles(), rangeStyleListMap, aIt->first.first, aIt->first.second, aIt->second ); + + // gather all ranges that have the same style and apply them in bulk + for ( std::map< std::pair< sal_Int32, sal_Int32 >, ApiCellRangeList >::iterator it = rangeStyleListMap.begin(), it_end = rangeStyleListMap.end(); it != it_end; ++it ) + { + const ApiCellRangeList& rRanges( it->second ); + for ( ApiCellRangeList::const_iterator it_range = rRanges.begin(), it_rangeend = rRanges.end(); it_range!=it_rangeend; ++it_range ) + { + RowRangeStyle aStyleRows; + aStyleRows.mnNumFmt.first = it->first.first; + aStyleRows.mnNumFmt.second = it->first.second; + aStyleRows.mnStartRow = it_range->StartRow; + aStyleRows.mnEndRow = it_range->EndRow; + for ( sal_Int32 nCol = it_range->StartColumn; nCol <= it_range->EndColumn; ++nCol ) + aStylesPerColumn[ nCol ].insert( aStyleRows ); + } + } + + // process row ranges for each column, don't overwrite any existing row entries for a column for ( std::map< sal_Int32, std::vector< ValueRange > >::iterator it = maXfIdRowRangeList.begin(), it_end = maXfIdRowRangeList.end(); it != it_end; ++it ) { ApiCellRangeList rangeList; @@ -368,27 +412,91 @@ void SheetDataBuffer::finalizeImport() // get all row ranges for id for ( std::vector< ValueRange >::iterator rangeIter = it->second.begin(), rangeIter_end = it->second.end(); rangeIter != rangeIter_end; ++rangeIter ) { - CellRangeAddress aRange( getSheetIndex(), 0, rangeIter->mnFirst, rAddrConv.getMaxApiAddress().Column, rangeIter->mnLast ); - rangeList.push_back( aRange ); + RowRangeStyle aStyleRows; + aStyleRows.mnNumFmt.first = it->first; + if ( aStyleRows.mnNumFmt.first == -1 ) // dud + continue; + aStyleRows.mnNumFmt.second = -1; + aStyleRows.mnStartRow = rangeIter->mnFirst; + aStyleRows.mnEndRow = rangeIter->mnLast; + for ( sal_Int32 nCol = 0; nCol <= rAddrConv.getMaxApiAddress().Column; ++nCol ) + { + RowStyles& rRowStyles = aStylesPerColumn[ nCol ]; + // If the rowrange style includes rows already + // allocated to a style then we need to split + // the range style Rows into sections ( to + // occupy only rows that have no style definition ) + + // We dont want to set any rowstyle 'rows' + // for rows where there is an existing 'style' ) + std::vector< RowRangeStyle > aRangeRowsSplits; + + RowStyles::iterator rows_it = rRowStyles.begin(); + RowStyles::iterator rows_end = rRowStyles.end(); + bool bAddRange = true; + for ( ; rows_it != rows_end; ++rows_it ) + { + const RowRangeStyle& r = *rows_it; + // if row is completely within existing style, discard it + if ( aStyleRows.mnStartRow >= r.mnStartRow && aStyleRows.mnEndRow <= r.mnEndRow ) + bAddRange = false; + else if ( aStyleRows.mnStartRow <= r.mnStartRow ) + { + // not intersecting at all?, if so finish as none left + // to check ( row ranges are in ascending order + if ( aStyleRows.mnEndRow < r.mnStartRow ) + break; + else if ( aStyleRows.mnEndRow <= r.mnEndRow ) + { + aStyleRows.mnEndRow = r.mnStartRow - 1; + break; + } + if ( aStyleRows.mnStartRow < r.mnStartRow ) + { + RowRangeStyle aSplit = aStyleRows; + aSplit.mnEndRow = r.mnStartRow - 1; + aRangeRowsSplits.push_back( aSplit ); + } + } + } + std::vector< RowRangeStyle >::iterator splits_it = aRangeRowsSplits.begin(); + std::vector< RowRangeStyle >::iterator splits_end = aRangeRowsSplits.end(); + for ( ; splits_it != splits_end; ++splits_it ) + rRowStyles.insert( *splits_it ); + if ( bAddRange ) + rRowStyles.insert( aStyleRows ); + } + } + } + ScDocument& rDoc = getScDocument(); + for ( ColStyles::iterator col = aStylesPerColumn.begin(), col_end = aStylesPerColumn.end(); col != col_end; ++col ) + { + RowStyles& rRowStyles = col->second; + std::list<ScAttrEntry> aAttrs; + SCCOL nScCol = static_cast< SCCOL >( col->first ); + for ( RowStyles::iterator rRows = rRowStyles.begin(), rRows_end = rRowStyles.end(); rRows != rRows_end; ++rRows ) + { + Xf* pXf = rStyles.getCellXf( rRows->mnNumFmt.first ).get(); + + if ( pXf ) + pXf->applyPatternToAttrList( aAttrs, rRows->mnStartRow, rRows->mnEndRow, rRows->mnNumFmt.second ); } - ScRangeList aList; - for ( ApiCellRangeList::const_iterator itRange = rangeList.begin(), itRange_end = rangeList.end(); itRange!=itRange_end; ++itRange ) + if (aAttrs.empty() || aAttrs.back().nRow != MAXROW) { - ScRange* pRange = new ScRange(); - ScUnoConversion::FillScRange( *pRange, *itRange ); - aList.push_back( pRange ); + ScAttrEntry aEntry; + aEntry.nRow = MAXROW; + aEntry.pPattern = rDoc.GetDefPattern(); + aAttrs.push_back(aEntry); } - ScMarkData aMark; - aMark.MarkFromRangeList( aList, false ); - getStyles().writeCellXfToMarkData( aMark, it->first, -1 ); + size_t nAttrSize = aAttrs.size(); + ScAttrEntry* pData = new ScAttrEntry[nAttrSize]; + std::list<ScAttrEntry>::const_iterator itr = aAttrs.begin(), itrEnd = aAttrs.end(); + for (size_t i = 0; itr != itrEnd; ++itr, ++i) + pData[i] = *itr; + + rDoc.SetAttrEntries(nScCol, getSheetIndex(), pData, static_cast<SCSIZE>(nAttrSize)); } - std::map< std::pair< sal_Int32, sal_Int32 >, ApiCellRangeList > rangeStyleListMap; - // gather all ranges that have the same style and apply them in bulk - for( XfIdRangeListMap::const_iterator aIt = maXfIdRangeLists.begin(), aEnd = maXfIdRangeLists.end(); aIt != aEnd; ++aIt ) - addIfNotInMyMap( getStyles(), rangeStyleListMap, aIt->first.first, aIt->first.second, aIt->second ); - for ( std::map< std::pair< sal_Int32, sal_Int32 >, ApiCellRangeList >::iterator it = rangeStyleListMap.begin(), it_end = rangeStyleListMap.end(); it != it_end; ++it ) - writeXfIdRangeListProperties( it->first.first, it->first.second, it->second ); // merge all cached merged ranges and update right/bottom cell borders for( MergedRangeList::iterator aIt = maMergedRanges.begin(), aEnd = maMergedRanges.end(); aIt != aEnd; ++aIt ) applyCellMerging( aIt->maRange ); diff --git a/sc/source/filter/oox/stylesbuffer.cxx b/sc/source/filter/oox/stylesbuffer.cxx index 0d0467d..bc990fb 100644 --- a/sc/source/filter/oox/stylesbuffer.cxx +++ b/sc/source/filter/oox/stylesbuffer.cxx @@ -2281,6 +2281,70 @@ FontRef Xf::getFont() const return getStyles().getFont( maModel.mnFontId ); } +void Xf::applyPatternToAttrList( ::std::list<ScAttrEntry>& rAttrs, SCROW nRow1, SCROW nRow2, + sal_uInt32 nNumFmtId ) +{ + createPattern(); + ScPatternAttr& rPat = *mpPattern; + ScDocument& rDoc = getScDocument(); + if ( isCellXf() ) + { + StylesBuffer& rStyles = getStyles(); + rStyles.createCellStyle( maModel.mnStyleXfId ); + + mpStyleSheet = rStyles.getCellStyleSheet( maModel.mnStyleXfId ); + if ( mpStyleSheet ) + { + //rDoc.ApplySelectionStyle( static_cast<ScStyleSheet&>(*mpStyleSheet), rMarkData ); + rPat.SetStyleSheet(mpStyleSheet, false); + } + else + { + ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool(); + if (pStylePool) + { + ScStyleSheet* pStyleSheet = static_cast<ScStyleSheet*>( + pStylePool->Find( + ScGlobal::GetRscString(STR_STYLENAME_STANDARD), SFX_STYLE_FAMILY_PARA)); + + if (pStyleSheet) + rPat.SetStyleSheet( pStyleSheet, false ); + } + } + } + if ( nNumFmtId >= 0 ) + { + ScPatternAttr aNumPat(rDoc.GetPool()); + getStyles().writeNumFmtToItemSet( aNumPat.GetItemSet(), nNumFmtId ); + rPat.GetItemSet().Put(aNumPat.GetItemSet()); + } + if (rPat.GetStyleName()) + { + // Check for a gap between the last entry and this one. + bool bHasGap = false; + if (rAttrs.empty() && nRow1 > 0) + // First attribute range doesn't start at row 0. + bHasGap = true; + + if (!rAttrs.empty() && rAttrs.back().nRow + 1 < nRow1) + bHasGap = true; + + if (bHasGap) + { + // Fill this gap with the default pattern. + ScAttrEntry aEntry; + aEntry.nRow = nRow1 - 1; + aEntry.pPattern = rDoc.GetDefPattern(); + rAttrs.push_back(aEntry); + } + + ScAttrEntry aEntry; + aEntry.nRow = nRow2; + aEntry.pPattern = static_cast<const ScPatternAttr*>(&rDoc.GetPool()->Put(rPat)); + rAttrs.push_back(aEntry); + } +} + void Xf::writeToMarkData( ::ScMarkData& rMarkData, sal_Int32 nNumFmtId ) { createPattern(); _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
