diff options
author | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2012-04-11 21:35:59 +0200 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2012-04-11 22:03:25 +0200 |
commit | f61cbce529d039bb0e208e81cf66974cc4428420 (patch) | |
tree | 5bf31db12d5ff5ac4a799778bde4f4017bfbd5fb | |
parent | a78a7ee9f7b1db56a6fa7e082f410db5a8db2f18 (diff) |
make ScTable::FillSeries work correctly with hidden rows/columns
-rw-r--r-- | sc/inc/table.hxx | 1 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 5 | ||||
-rw-r--r-- | sc/source/core/data/table4.cxx | 280 |
3 files changed, 180 insertions, 106 deletions
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 2261718fd803..6393bfa99bae 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -675,6 +675,7 @@ public: SCROW GetLastChangedRow() const; bool IsDataFiltered(SCCOL nColStart, SCROW nRowStart, SCCOL nColEnd, SCROW nRowEnd) const; + bool IsDataFiltered(const ScRange& rRange) const; sal_uInt8 GetColFlags( SCCOL nCol ) const; sal_uInt8 GetRowFlags( SCROW nRow ) const; diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 646e0d8e4ace..c6fed2b5c436 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -2821,6 +2821,11 @@ bool ScTable::IsDataFiltered(SCCOL nColStart, SCROW nRowStart, SCCOL nColEnd, SC return false; } +bool ScTable::IsDataFiltered(const ScRange& rRange) const +{ + return IsDataFiltered(rRange.aStart.Col(), rRange.aStart.Row(), + rRange.aEnd.Col(), rRange.aEnd.Row()); +} void ScTable::SetRowFlags( SCROW nRow, sal_uInt8 nNewFlags ) { diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx index e3d57beeeab7..fa23055f54c4 100644 --- a/sc/source/core/data/table4.cxx +++ b/sc/source/core/data/table4.cxx @@ -489,6 +489,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, sal_uLong nIEnd; sal_uLong nISrcStart; sal_uLong nISrcEnd; + ScRange aFillRange; if (bVertical) { @@ -500,6 +501,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, nISrcEnd = nRow2; nIStart = nRow2 + 1; nIEnd = nRow2 + nFillCount; + aFillRange = ScRange(nCol1, nRow2+1, 0, nCol2, nRow2 + nFillCount, 0); } else { @@ -507,6 +509,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, nISrcEnd = nRow1; nIStart = nRow1 - 1; nIEnd = nRow1 - nFillCount; + aFillRange = ScRange(nCol1, nRow1-1, 0, nCol2, nRow2 - nFillCount, 0); } } else @@ -519,6 +522,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, nISrcEnd = nCol2; nIStart = nCol2 + 1; nIEnd = nCol2 + nFillCount; + aFillRange = ScRange(nCol2 + 1, nRow1, 0, nCol2 + nFillCount, nRow2, 0); } else { @@ -526,12 +530,13 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, nISrcEnd = nCol1; nIStart = nCol1 - 1; nIEnd = nCol1 - nFillCount; + aFillRange = ScRange(nCol1 - 1, nRow1, 0, nCol1 - nFillCount, nRow2, 0); } } sal_uLong nIMin = nIStart; sal_uLong nIMax = nIEnd; PutInOrder(nIMin,nIMax); - bool bHasFiltered = IsDataFiltered(nCol1, nRow1, nCol2, nRow2); + bool bHasFiltered = IsDataFiltered(aFillRange.aStart.Col(), aFillRange.aStart.Row(), aFillRange.aEnd.Col(), aFillRange.aEnd.Row()); if (!bHasFiltered) { @@ -776,7 +781,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, eCellType = CELLTYPE_NONE; } - bRowFiltered = mpFilteredRows->getValue(nRow); + bRowFiltered = RowHidden(nRow); if (!bRowFiltered) { @@ -1022,7 +1027,7 @@ String ScTable::GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW n aValue = ((ScStringCell*)pCell)->GetString(); else aValue = ((ScEditCell*)pCell)->GetString(); - if ( !(nScFillModeMouseModifier & KEY_MOD1) && !IsDataFiltered(nCol1, nRow1, nCol2, nRow2) ) + if ( !(nScFillModeMouseModifier & KEY_MOD1) && !IsDataFiltered(nCol1, nRow1, nEndX, nEndY) ) { sal_Int32 nVal; sal_uInt16 nCellDigits = 0; // look at each source cell individually @@ -1043,7 +1048,7 @@ String ScTable::GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW n { // dabei kann's keinen Ueberlauf geben... double nVal = ((ScValueCell*)pCell)->GetValue(); - if ( !(nScFillModeMouseModifier & KEY_MOD1) && !IsDataFiltered(nCol1, nRow1, nCol2, nRow2) ) + if ( !(nScFillModeMouseModifier & KEY_MOD1) && !IsDataFiltered(nCol1, nRow1, nEndX, nEndY) ) nVal += (double) nDelta; Color* pColor; @@ -1250,6 +1255,23 @@ void ScTable::IncDate(double& rVal, sal_uInt16& nDayOfMonth, double nStep, FillD rVal = aDate - aNullDate; } +namespace +{ + +bool HiddenRowColumn(sal_uLong nRowColumn, bool bVertical, ScTable* pTable) +{ + if(bVertical) + { + return pTable->RowHidden(static_cast<SCROW>(nRowColumn)); + } + else + { + return pTable->ColHidden(static_cast<SCCOL>(nRowColumn)); + } +} + +} + void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, sal_uLong nFillCount, FillDir eFillDir, FillCmd eFillCmd, FillDateCmd eFillDateCmd, double nStepValue, double nMaxValue, sal_uInt16 nArgMinDigits, @@ -1271,6 +1293,7 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, sal_uLong nIStart; sal_uLong nIEnd; sal_uLong nISource; + ScRange aFillRange; if (bVertical) { @@ -1284,12 +1307,14 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, nISource = nRow1; nIStart = nRow1 + 1; nIEnd = nRow1 + nFillCount; + aFillRange = ScRange(nCol1, nRow1 + 1, nTab, nCol2, nRow1 + nFillCount, nTab); } else { nISource = nRow2; nIStart = nRow2 - 1; nIEnd = nRow2 - nFillCount; + aFillRange = ScRange(nCol1, nRow2 -1, nTab, nCol2, nRow2 - nFillCount, nTab); } } else @@ -1304,12 +1329,14 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, nISource = nCol1; nIStart = nCol1 + 1; nIEnd = nCol1 + nFillCount; + aFillRange = ScRange(nCol1 + 1, nRow1, nTab, nCol1 + nFillCount, nRow2, nTab); } else { nISource = nCol2; nIStart = nCol2 - 1; nIEnd = nCol2 - nFillCount; + aFillRange = ScRange(nCol2 - 1, nRow1, nTab, nCol2 - nFillCount, nRow2, nTab); } } @@ -1317,10 +1344,15 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, sal_uLong nIMax = nIEnd; PutInOrder(nIMin,nIMax); sal_uInt16 nDel = bAttribs ? IDF_AUTOFILL : (IDF_AUTOFILL & IDF_CONTENTS); - if (bVertical) - DeleteArea(nCol1, static_cast<SCROW>(nIMin), nCol2, static_cast<SCROW>(nIMax), nDel); - else - DeleteArea(static_cast<SCCOL>(nIMin), nRow1, static_cast<SCCOL>(nIMax), nRow2, nDel); + + bool bIsFiltered = IsDataFiltered(aFillRange); + if (!bIsFiltered) + { + if (bVertical) + DeleteArea(nCol1, static_cast<SCROW>(nIMin), nCol2, static_cast<SCROW>(nIMax), nDel); + else + DeleteArea(static_cast<SCCOL>(nIMin), nRow1, static_cast<SCCOL>(nIMax), nRow2, nDel); + } sal_uLong nProgress = 0; if (pProgress) @@ -1344,11 +1376,29 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, { const ScPatternAttr* pSrcPattern = aCol[nCol].GetPattern(static_cast<SCROW>(nRow)); if (bVertical) - aCol[nCol].SetPatternArea( static_cast<SCROW>(nIMin), - static_cast<SCROW>(nIMax), *pSrcPattern, true ); + { + // if not filtered use the faster method + // hidden cols/rows should be skiped + if(!bIsFiltered) + { + aCol[nCol].SetPatternArea( static_cast<SCROW>(nIMin), + static_cast<SCROW>(nIMax), *pSrcPattern, true ); + } + else + { + for(SCROW nAtRow = static_cast<SCROW>(nIMin); nAtRow <= static_cast<SCROW>(nIMax); ++nAtRow) + { + if(!RowHidden(nAtRow)) + aCol[nCol].SetPatternArea( static_cast<SCROW>(nAtRow), + static_cast<SCROW>(nAtRow), *pSrcPattern, true); + } + + } + } else for (SCCOL nAtCol = static_cast<SCCOL>(nIMin); nAtCol <= sal::static_int_cast<SCCOL>(nIMax); nAtCol++) - aCol[nAtCol].SetPattern(static_cast<SCROW>(nRow), *pSrcPattern, true); + if(!ColHidden(nAtCol)) + aCol[nAtCol].SetPattern(static_cast<SCROW>(nRow), *pSrcPattern, true); } if (pSrcCell) @@ -1361,7 +1411,7 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, { for (rInner = nIMin; rInner <= nIMax; rInner++) { - if (pDocument->RowFiltered( rInner, nTab)) + if(HiddenRowColumn(rInner, bVertical, this)) continue; sal_uLong nInd = nActFormCnt; FillFormula(nInd, bFirst, (ScFormulaCell*)pSrcCell, @@ -1375,7 +1425,7 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, { for (rInner = nIMin; rInner <= nIMax; rInner++) { - if (pDocument->RowFiltered( rInner, nTab)) + if(HiddenRowColumn(rInner, bVertical, this)) continue; ScAddress aDestPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), nTab ); aCol[nCol].Insert( aDestPos.Row(), pSrcCell->Clone( *pDocument ) ); @@ -1402,62 +1452,75 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, rInner = nIStart; while (true) // #i53728# with "for (;;)" old solaris/x86 compiler mis-optimizes { - if (!bError && !bOverflow) + if(!ColHidden(nCol) && !RowHidden(nRow)) { - switch (eFillCmd) + if (!bError && !bOverflow) { - case FILL_LINEAR: - { - // use multiplication instead of repeated addition - // to avoid accumulating rounding errors - nVal = nStartVal; - double nAdd = nStepValue; - if ( !SubTotal::SafeMult( nAdd, (double) ++nIndex ) || - !SubTotal::SafePlus( nVal, nAdd ) ) - bError = true; - } - break; - case FILL_GROWTH: - if (!SubTotal::SafeMult(nVal, nStepValue)) - bError = true; - break; - case FILL_DATE: - if (fabs(nVal) > _D_MAX_LONG_) - bError = true; - else - IncDate(nVal, nDayOfMonth, nStepValue, eFillDateCmd); - break; - default: + switch (eFillCmd) { - // added to avoid warnings + case FILL_LINEAR: + { + // use multiplication instead of repeated addition + // to avoid accumulating rounding errors + nVal = nStartVal; + double nAdd = nStepValue; + if ( !SubTotal::SafeMult( nAdd, (double) ++nIndex ) || + !SubTotal::SafePlus( nVal, nAdd ) ) + bError = true; + } + break; + case FILL_GROWTH: + if (!SubTotal::SafeMult(nVal, nStepValue)) + bError = true; + break; + case FILL_DATE: + if (fabs(nVal) > _D_MAX_LONG_) + bError = true; + else + IncDate(nVal, nDayOfMonth, nStepValue, eFillDateCmd); + break; + default: + { + // added to avoid warnings + } } - } - if (nStepValue >= 0) - { - if (nVal > nMaxValue) // Zielwert erreicht? + if (nStepValue >= 0) { - nVal = nMaxValue; - bOverflow = true; + if (nVal > nMaxValue) // Zielwert erreicht? + { + nVal = nMaxValue; + bOverflow = true; + } } - } - else - { - if (nVal < nMaxValue) + else { - nVal = nMaxValue; - bOverflow = true; + if (nVal < nMaxValue) + { + nVal = nMaxValue; + bOverflow = true; + } } } - } - if (bError) - aCol[nCol].SetError(static_cast<SCROW>(nRow), errNoValue); - else if (!bOverflow) - aCol[nCol].SetValue(static_cast<SCROW>(nRow), nVal); + if (bError) + aCol[nCol].SetError(static_cast<SCROW>(nRow), errNoValue); + else if (bOverflow) + aCol[nCol].SetError(static_cast<SCROW>(nRow), errIllegalFPOperation); + else + aCol[nCol].SetValue(static_cast<SCROW>(nRow), nVal); + } - if (rInner == nIEnd) break; - if (bPositive) ++rInner; else --rInner; + if (rInner == nIEnd) + break; + if (bPositive) + { + ++rInner; + } + else + { + --rInner; + } } nProgress += nIMax - nIMin + 1; if(pProgress) @@ -1497,68 +1560,73 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, rInner = nIStart; while (true) // #i53728# with "for (;;)" old solaris/x86 compiler mis-optimizes { - if (!bError && !bOverflow) + if(!ColHidden(nCol) && !RowHidden(nRow)) { - switch (eFillCmd) + if (!bError && !bOverflow) { - case FILL_LINEAR: - { - // use multiplication instead of repeated addition - // to avoid accumulating rounding errors - nVal = nStartVal; - double nAdd = nStepValue; - if ( !SubTotal::SafeMult( nAdd, (double) ++nIndex ) || - !SubTotal::SafePlus( nVal, nAdd ) ) - bError = true; - } - break; - case FILL_GROWTH: - if (!SubTotal::SafeMult(nVal, nStepValue)) - bError = true; - break; - default: + switch (eFillCmd) { - // added to avoid warnings + case FILL_LINEAR: + { + // use multiplication instead of repeated addition + // to avoid accumulating rounding errors + nVal = nStartVal; + double nAdd = nStepValue; + if ( !SubTotal::SafeMult( nAdd, (double) ++nIndex ) || + !SubTotal::SafePlus( nVal, nAdd ) ) + bError = true; + } + break; + case FILL_GROWTH: + if (!SubTotal::SafeMult(nVal, nStepValue)) + bError = true; + break; + default: + { + // added to avoid warnings + } } - } - if (nStepValue >= 0) - { - if (nVal > nMaxValue) // Zielwert erreicht? + if (nStepValue >= 0) { - nVal = nMaxValue; - bOverflow = true; + if (nVal > nMaxValue) // Zielwert erreicht? + { + nVal = nMaxValue; + bOverflow = true; + } } - } - else - { - if (nVal < nMaxValue) + else { - nVal = nMaxValue; - bOverflow = true; + if (nVal < nMaxValue) + { + nVal = nMaxValue; + bOverflow = true; + } } } - } - if (bError) - aCol[nCol].SetError(static_cast<SCROW>(nRow), errNoValue); - else if (!bOverflow) - { - nStringValue = (sal_Int32)nVal; - String aStr; - if ( nHeadNoneTail < 0 ) - { - aCol[nCol].Insert( static_cast<SCROW>(nRow), - lcl_getSuffixCell( pDocument, - nStringValue, nMinDigits, aValue, - eCellType, bIsOrdinalSuffix )); - } + if (bError) + aCol[nCol].SetError(static_cast<SCROW>(nRow), errNoValue); + else if (bOverflow) + aCol[nCol].SetError(static_cast<SCROW>(nRow), errIllegalFPOperation); else { - aStr = aValue; - aStr += lcl_ValueString( nStringValue, nMinDigits ); - ScStringCell* pCell = new ScStringCell( aStr ); - aCol[nCol].Insert( static_cast<SCROW>(nRow), pCell ); + nStringValue = (sal_Int32)nVal; + String aStr; + if ( nHeadNoneTail < 0 ) + { + aCol[nCol].Insert( static_cast<SCROW>(nRow), + lcl_getSuffixCell( pDocument, + nStringValue, nMinDigits, aValue, + eCellType, bIsOrdinalSuffix )); + } + else + { + aStr = aValue; + aStr += lcl_ValueString( nStringValue, nMinDigits ); + ScStringCell* pCell = new ScStringCell( aStr ); + aCol[nCol].Insert( static_cast<SCROW>(nRow), pCell ); + } } } |