diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-07-19 20:31:08 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-07-24 23:29:35 -0400 |
commit | 27d02ddc7fc4e11bc4429839729ea3d6f7322245 (patch) | |
tree | adbc5ea0432fe8a180a55895e0c504afd32b6018 /sc | |
parent | af4af279a2a75bc1316c9abed8906187f2936b4e (diff) |
Properly handle optional edge expansion of referenced ranges.
Change-Id: I499189f4f76eee4b963f643364d1fad26cf69785
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/colorscale.hxx | 2 | ||||
-rw-r--r-- | sc/inc/refupdatecontext.hxx | 6 | ||||
-rw-r--r-- | sc/source/core/data/colorscale.cxx | 15 | ||||
-rw-r--r-- | sc/source/core/data/column.cxx | 12 | ||||
-rw-r--r-- | sc/source/core/data/documen2.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 10 | ||||
-rw-r--r-- | sc/source/core/data/refupdatecontext.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/tool/chgtrack.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/tool/token.cxx | 81 |
10 files changed, 101 insertions, 39 deletions
diff --git a/sc/inc/colorscale.hxx b/sc/inc/colorscale.hxx index 944148378986..e22042600ccc 100644 --- a/sc/inc/colorscale.hxx +++ b/sc/inc/colorscale.hxx @@ -69,7 +69,7 @@ public: formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_DEFAULT); void UpdateMoveTab(SCTAB nOldTab, SCTAB nNewTab, SCTAB nTabNo); - void UpdateReference( UpdateRefMode eUpdateRefMode, + void UpdateReference( ScDocument* pDoc, UpdateRefMode eUpdateRefMode, const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz ); const ScTokenArray* GetFormula() const; diff --git a/sc/inc/refupdatecontext.hxx b/sc/inc/refupdatecontext.hxx index 91607ea66f9f..8067c3b4fdf2 100644 --- a/sc/inc/refupdatecontext.hxx +++ b/sc/inc/refupdatecontext.hxx @@ -13,10 +13,14 @@ #include "global.hxx" #include "address.hxx" +class ScDocument; + namespace sc { struct RefUpdateContext { + ScDocument& mrDoc; + /** * update mode - insert/delete, copy, or move. The reorder mode (which * corresponds with the reordering of sheets) is not used with this @@ -38,7 +42,7 @@ struct RefUpdateContext /** Amount and direction of movement in the sheet direction. */ SCTAB mnTabDelta; - RefUpdateContext(); + RefUpdateContext(ScDocument& rDoc); bool isInserted() const; bool isDeleted() const; diff --git a/sc/source/core/data/colorscale.cxx b/sc/source/core/data/colorscale.cxx index 6169e52c4c3a..a1f440c7b9c7 100644 --- a/sc/source/core/data/colorscale.cxx +++ b/sc/source/core/data/colorscale.cxx @@ -244,13 +244,14 @@ void ScColorScaleEntry::UpdateMoveTab( SCTAB nOldTab, SCTAB nNewTab, SCTAB nTabN } } -void ScColorScaleEntry::UpdateReference( UpdateRefMode eUpdateRefMode, - const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz ) +void ScColorScaleEntry::UpdateReference( + ScDocument* pDoc, UpdateRefMode eUpdateRefMode, const ScRange& rRange, + SCsCOL nDx, SCsROW nDy, SCsTAB nDz ) { if (!mpCell) return; - sc::RefUpdateContext aCxt; + sc::RefUpdateContext aCxt(*pDoc); aCxt.meMode = eUpdateRefMode; aCxt.maRange = rRange; aCxt.mnColDelta = nDx; @@ -586,7 +587,7 @@ void ScColorScaleFormat::UpdateReference( UpdateRefMode eUpdateRefMode, { for(iterator itr = begin(); itr != end(); ++itr) { - itr->UpdateReference(eUpdateRefMode, rRange, nDx, nDy, nDz); + itr->UpdateReference(mpDoc, eUpdateRefMode, rRange, nDx, nDy, nDz); } } @@ -699,8 +700,8 @@ condformat::ScFormatEntryType ScDataBarFormat::GetType() const void ScDataBarFormat::UpdateReference( UpdateRefMode eRefMode, const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz ) { - mpFormatData->mpUpperLimit->UpdateReference( eRefMode, rRange, nDx, nDy, nDz ); - mpFormatData->mpLowerLimit->UpdateReference( eRefMode, rRange, nDx, nDy, nDz ); + mpFormatData->mpUpperLimit->UpdateReference( mpDoc, eRefMode, rRange, nDx, nDy, nDz ); + mpFormatData->mpLowerLimit->UpdateReference( mpDoc, eRefMode, rRange, nDx, nDy, nDz ); } bool ScDataBarFormat::NeedsRepaint() const @@ -1012,7 +1013,7 @@ void ScIconSetFormat::UpdateReference( UpdateRefMode eUpdateRefMode, { for(iterator itr = begin(); itr != end(); ++itr) { - itr->UpdateReference( eUpdateRefMode, rRange, nDx, nDy, nDz ); + itr->UpdateReference( mpDoc, eUpdateRefMode, rRange, nDx, nDy, nDz ); } } diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index ac1ede1cf5eb..23a740f9ccc4 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -1119,10 +1119,10 @@ namespace { /** * Adjust references in formula cell with respect to column-wise relocation. */ -void updateRefInFormulaCell( ScFormulaCell& rCell, SCCOL nCol, SCTAB nTab, SCCOL nColDiff ) +void updateRefInFormulaCell( ScDocument* pDoc, ScFormulaCell& rCell, SCCOL nCol, SCTAB nTab, SCCOL nColDiff ) { rCell.aPos.SetCol(nCol); - sc::RefUpdateContext aCxt; + sc::RefUpdateContext aCxt(*pDoc); aCxt.meMode = URM_MOVE; aCxt.maRange = ScRange(ScAddress(nCol, 0, nTab), ScAddress(nCol, MAXROW, nTab)); aCxt.mnColDelta = nColDiff; @@ -1139,14 +1139,14 @@ void ScColumn::SwapCell( SCROW nRow, ScColumn& rCol) if (aPos1.first->type == sc::element_type_formula) { ScFormulaCell& rCell = *sc::formula_block::at(*aPos1.first->data, aPos1.second); - updateRefInFormulaCell(rCell, rCol.nCol, nTab, rCol.nCol - nCol); + updateRefInFormulaCell(pDocument, rCell, rCol.nCol, nTab, rCol.nCol - nCol); sc::SharedFormulaUtil::unshareFormulaCell(aPos1, rCell); } if (aPos2.first->type == sc::element_type_formula) { ScFormulaCell& rCell = *sc::formula_block::at(*aPos2.first->data, aPos2.second); - updateRefInFormulaCell(rCell, nCol, nTab, nCol - rCol.nCol); + updateRefInFormulaCell(pDocument, rCell, nCol, nTab, nCol - rCol.nCol); sc::SharedFormulaUtil::unshareFormulaCell(aPos2, rCell); } @@ -2036,7 +2036,7 @@ void ScColumn::CopyScenarioFrom( const ScColumn& rSrcCol ) // UpdateUsed not needed, already done in TestCopyScenario (obsolete comment ?) - sc::RefUpdateContext aRefCxt; + sc::RefUpdateContext aRefCxt(*pDocument); aRefCxt.meMode = URM_COPY; aRefCxt.maRange = ScRange(nCol, nStart, nTab, nCol, nEnd, nTab); aRefCxt.mnTabDelta = nTab - rSrcCol.nTab; @@ -2067,7 +2067,7 @@ void ScColumn::CopyScenarioTo( ScColumn& rDestCol ) const // UpdateUsed not needed, is already done in TestCopyScenario (obsolete comment ?) - sc::RefUpdateContext aRefCxt; + sc::RefUpdateContext aRefCxt(*pDocument); aRefCxt.meMode = URM_COPY; aRefCxt.maRange = ScRange(rDestCol.nCol, nStart, rDestCol.nTab, rDestCol.nCol, nEnd, rDestCol.nTab); aRefCxt.mnTabDelta = rDestCol.nTab - nTab; diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index dade7bee21b6..d5ddbd40400f 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -849,7 +849,7 @@ bool ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM maTabs[nNewPos]->SetTabBgColor(maTabs[nOldPos]->GetTabBgColor()); SCTAB nDz = nNewPos - nOldPos; - sc::RefUpdateContext aRefCxt; + sc::RefUpdateContext aRefCxt(*this); aRefCxt.meMode = URM_COPY; aRefCxt.maRange = ScRange(0, 0, nNewPos, MAXCOL, MAXROW, nNewPos); aRefCxt.mnTabDelta = nDz; @@ -968,7 +968,7 @@ sal_uLong ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos, if ( !bResultsOnly ) { - sc::RefUpdateContext aRefCxt; + sc::RefUpdateContext aRefCxt(*this); aRefCxt.meMode = URM_COPY; aRefCxt.maRange = ScRange(0, 0, nDestPos, MAXCOL, MAXROW, nDestPos); aRefCxt.mnTabDelta = nDestPos - nSrcPos; diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index aa2377579ce2..dfc17cf90766 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -1164,7 +1164,7 @@ bool ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab, lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ); - sc::RefUpdateContext aCxt; + sc::RefUpdateContext aCxt(*this); aCxt.meMode = URM_INSDEL; aCxt.maRange = ScRange(nStartCol, nStartRow, nTabRangeStart, nEndCol, MAXROW, nTabRangeEnd); aCxt.mnRowDelta = nSize; @@ -1267,7 +1267,7 @@ void ScDocument::DeleteRow( SCCOL nStartCol, SCTAB nStartTab, if ( ValidRow(nStartRow+nSize) ) { lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ); - sc::RefUpdateContext aCxt; + sc::RefUpdateContext aCxt(*this); aCxt.meMode = URM_INSDEL; aCxt.maRange = ScRange(nStartCol, nStartRow+nSize, nTabRangeStart, nEndCol, MAXROW, nTabRangeEnd); aCxt.mnRowDelta = -(static_cast<SCROW>(nSize)); @@ -1373,7 +1373,7 @@ bool ScDocument::InsertCol( SCROW nStartRow, SCTAB nStartTab, lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ); - sc::RefUpdateContext aCxt; + sc::RefUpdateContext aCxt(*this); aCxt.meMode = URM_INSDEL; aCxt.maRange = ScRange(nStartCol, nStartRow, nTabRangeStart, MAXCOL, nEndRow, nTabRangeEnd); aCxt.mnColDelta = nSize; @@ -1466,7 +1466,7 @@ void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTA if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) ) { lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ); - sc::RefUpdateContext aCxt; + sc::RefUpdateContext aCxt(*this); aCxt.meMode = URM_INSDEL; aCxt.maRange = ScRange(sal::static_int_cast<SCCOL>(nStartCol+nSize), nStartRow, nTabRangeStart, MAXCOL, nEndRow, nTabRangeEnd); aCxt.mnColDelta = -(static_cast<SCCOL>(nSize)); @@ -2446,7 +2446,7 @@ void ScDocument::CopyBlockFromClip( && rClipTabs[(nClipTab + nFollow + 1) % static_cast<SCTAB>(rClipTabs.size())] ) ++nFollow; - sc::RefUpdateContext aRefCxt; + sc::RefUpdateContext aRefCxt(*this); aRefCxt.maRange = ScRange(nCol1, nRow1, i, nCol2, nRow2, i+nFollow); aRefCxt.mnColDelta = nDx; aRefCxt.mnRowDelta = nDy; diff --git a/sc/source/core/data/refupdatecontext.cxx b/sc/source/core/data/refupdatecontext.cxx index 1ba6a6b92c5c..f1ad64c8c408 100644 --- a/sc/source/core/data/refupdatecontext.cxx +++ b/sc/source/core/data/refupdatecontext.cxx @@ -11,8 +11,8 @@ namespace sc { -RefUpdateContext::RefUpdateContext() : - meMode(URM_INSDEL), mnColDelta(0), mnRowDelta(0), mnTabDelta(0) {} +RefUpdateContext::RefUpdateContext(ScDocument& rDoc) : + mrDoc(rDoc), meMode(URM_INSDEL), mnColDelta(0), mnRowDelta(0), mnTabDelta(0) {} bool RefUpdateContext::isInserted() const { diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index c8bb3ae35b48..f54912bce8d6 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -3512,7 +3512,7 @@ void ScTable::CopyData( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW n if (aCell.meType == CELLTYPE_FORMULA) { - sc::RefUpdateContext aCxt; + sc::RefUpdateContext aCxt(*pDocument); aCxt.meMode = URM_COPY; aCxt.maRange = aRange; aCxt.mnColDelta = nDestCol - nStartCol; diff --git a/sc/source/core/tool/chgtrack.cxx b/sc/source/core/tool/chgtrack.cxx index 29dfcc66fe18..6b132adfb1ce 100644 --- a/sc/source/core/tool/chgtrack.cxx +++ b/sc/source/core/tool/chgtrack.cxx @@ -1303,7 +1303,7 @@ bool ScChangeActionMove::Reject( ScDocument* pDoc ) pDoc->DeleteAreaTab( aToRange, IDF_ALL ); pDoc->DeleteAreaTab( aFrmRange, IDF_ALL ); // Formeln im Dokument anpassen - sc::RefUpdateContext aCxt; + sc::RefUpdateContext aCxt(*pDoc); aCxt.meMode = URM_MOVE; aCxt.maRange = aFrmRange; aCxt.mnColDelta = aFrmRange.aStart.Col() - aToRange.aStart.Col(); @@ -2098,7 +2098,7 @@ void ScChangeActionContent::UpdateReference( const ScChangeTrack* pTrack, } ScRange aRange( aTmpRange.MakeRange() ); - sc::RefUpdateContext aRefCxt; + sc::RefUpdateContext aRefCxt(*pTrack->GetDocument()); aRefCxt.meMode = eMode; aRefCxt.maRange = aRange; aRefCxt.mnColDelta = nDx; diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index 30bef7b4fce5..659588139d80 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -2296,43 +2296,91 @@ bool shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const Sc return false; } -bool expandRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rInsertedRange ) +bool expandRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rSelectedRange ) { + if (!rSelectedRange.Intersects(rRefRange)) + return false; + if (rCxt.mnColDelta > 0) { // Insert and shifting right. - if (rRefRange.aStart.Row() < rInsertedRange.aStart.Row() || rInsertedRange.aEnd.Row() < rRefRange.aEnd.Row()) - // Inserted range is only partially overlapping in vertical direction. Bail out. + if (rRefRange.aStart.Row() < rSelectedRange.aStart.Row() || rSelectedRange.aEnd.Row() < rRefRange.aEnd.Row()) + // Selected range is only partially overlapping in vertical direction. Bail out. return false; - if (rInsertedRange.aStart.Col() == rRefRange.aStart.Col()) - // Inserted range is at the left end. No expansion. + if (!rCxt.mrDoc.IsExpandRefs() && rSelectedRange.aStart.Col() == rRefRange.aStart.Col()) + // Selected range is at the left end and the edge expansion is turned off. No expansion. return false; // Move the last column position to the right. - SCCOL nDelta = rInsertedRange.aEnd.Col() - rInsertedRange.aStart.Col() + 1; + SCCOL nDelta = rSelectedRange.aEnd.Col() - rSelectedRange.aStart.Col() + 1; rRefRange.aEnd.IncCol(nDelta); return true; } else if (rCxt.mnRowDelta > 0) { // Insert and shifting down. - if (rRefRange.aStart.Col() < rInsertedRange.aStart.Col() || rInsertedRange.aEnd.Col() < rRefRange.aEnd.Col()) - // Inserted range is only partially overlapping in horizontal direction. Bail out. + if (rRefRange.aStart.Col() < rSelectedRange.aStart.Col() || rSelectedRange.aEnd.Col() < rRefRange.aEnd.Col()) + // Selected range is only partially overlapping in horizontal direction. Bail out. return false; - if (rInsertedRange.aStart.Row() == rRefRange.aStart.Row()) - // Inserted range is at the top end. No expansion. + if (!rCxt.mrDoc.IsExpandRefs() && rSelectedRange.aStart.Row() == rRefRange.aStart.Row()) + // Selected range is at the top end and the edge expansion is turned off. No expansion. return false; // Move the last row position down. - SCROW nDelta = rInsertedRange.aEnd.Row() - rInsertedRange.aStart.Row() + 1; + SCROW nDelta = rSelectedRange.aEnd.Row() - rSelectedRange.aStart.Row() + 1; rRefRange.aEnd.IncRow(nDelta); return true; } return false; } +/** + * Check if the referenced range is expandable when the selected range is + * not overlapping the referenced range. + */ +bool expandRangeByEdge( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rSelectedRange ) +{ + if (!rCxt.mrDoc.IsExpandRefs()) + // Edge-expansion is turned off. + return false; + + if (rCxt.mnColDelta > 0) + { + // Insert and shift right. + if (rRefRange.aStart.Row() < rSelectedRange.aStart.Row() || rSelectedRange.aEnd.Row() < rRefRange.aEnd.Row()) + // Selected range is only partially overlapping in vertical direction. Bail out. + return false; + + if (rSelectedRange.aStart.Col() - rRefRange.aEnd.Col() != 1) + // Selected range is not immediately adjacent. Bail out. + return false; + + // Move the last column position to the right. + SCCOL nDelta = rSelectedRange.aEnd.Col() - rSelectedRange.aStart.Col() + 1; + rRefRange.aEnd.IncCol(nDelta); + return true; + } + else if (rCxt.mnRowDelta > 0) + { + if (rRefRange.aStart.Col() < rSelectedRange.aStart.Col() || rSelectedRange.aEnd.Col() < rRefRange.aEnd.Col()) + // Selected range is only partially overlapping in horizontal direction. Bail out. + return false; + + if (rSelectedRange.aStart.Row() - rRefRange.aEnd.Row() != 1) + // Selected range is not immediately adjacent. Bail out. + return false; + + // Move the last row position down. + SCROW nDelta = rSelectedRange.aEnd.Row() - rSelectedRange.aStart.Row() + 1; + rRefRange.aEnd.IncRow(nDelta); + return true; + } + + return false; +} + } sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos ) @@ -2398,7 +2446,7 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon } } - if (rCxt.isInserted() && aSelectedRange.Intersects(aAbs)) + if (rCxt.isInserted()) { if (expandRange(rCxt, aAbs, aSelectedRange)) { @@ -2408,6 +2456,15 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon aRes.mbRangeSizeModified = true; break; } + + if (expandRangeByEdge(rCxt, aAbs, aSelectedRange)) + { + // The reference range has been expanded on the edge. + rRef.SetRange(aAbs, aNewPos); + aRes.mbValueChanged = true; + aRes.mbRangeSizeModified = true; + break; + } } if (rCxt.maRange.In(aAbs)) |