diff options
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/refupdatecontext.hxx | 3 | ||||
-rw-r--r-- | sc/source/core/data/documen3.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/refupdatecontext.cxx | 9 | ||||
-rw-r--r-- | sc/source/core/tool/token.cxx | 104 |
4 files changed, 97 insertions, 21 deletions
diff --git a/sc/inc/refupdatecontext.hxx b/sc/inc/refupdatecontext.hxx index 2f337675f4a3..91607ea66f9f 100644 --- a/sc/inc/refupdatecontext.hxx +++ b/sc/inc/refupdatecontext.hxx @@ -40,7 +40,8 @@ struct RefUpdateContext RefUpdateContext(); - bool hasDelta() const; + bool isInserted() const; + bool isDeleted() const; }; struct RefUpdateResult diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index 53769ef443e4..04973f4db031 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -981,7 +981,7 @@ void ScDocument::UpdateReference( return; boost::scoped_ptr<sc::ExpandRefsSwitch> pExpandRefsSwitch; - if (rCxt.meMode == URM_INSDEL && rCxt.hasDelta()) + if (rCxt.isInserted()) pExpandRefsSwitch.reset(new sc::ExpandRefsSwitch(*this, SC_MOD()->GetInputOptions().GetExpandRefs())); size_t nFirstTab, nLastTab; diff --git a/sc/source/core/data/refupdatecontext.cxx b/sc/source/core/data/refupdatecontext.cxx index 9f39f44a6443..1ba6a6b92c5c 100644 --- a/sc/source/core/data/refupdatecontext.cxx +++ b/sc/source/core/data/refupdatecontext.cxx @@ -14,9 +14,14 @@ namespace sc { RefUpdateContext::RefUpdateContext() : meMode(URM_INSDEL), mnColDelta(0), mnRowDelta(0), mnTabDelta(0) {} -bool RefUpdateContext::hasDelta() const +bool RefUpdateContext::isInserted() const { - return (mnColDelta > 0 || mnRowDelta > 0 || mnTabDelta > 0); + return (meMode == URM_INSDEL) && (mnColDelta > 0 || mnRowDelta > 0 || mnTabDelta > 0); +} + +bool RefUpdateContext::isDeleted() const +{ + return (meMode == URM_INSDEL) && (mnColDelta < 0 || mnRowDelta < 0 || mnTabDelta < 0); } RefUpdateResult::RefUpdateResult() : mbValueChanged(false), mbRangeSizeModified(false) {} diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index 981e89890303..30bef7b4fce5 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -2195,28 +2195,45 @@ void ScTokenArray::AdjustAbsoluteRefs( const ScDocument* pOldDoc, const ScAddres namespace { -ScRange getDeletedRange( const sc::RefUpdateContext& rCxt ) +ScRange getSelectedRange( const sc::RefUpdateContext& rCxt ) { - ScRange aDeletedRange(ScAddress::INITIALIZE_INVALID); + ScRange aSelectedRange(ScAddress::INITIALIZE_INVALID); if (rCxt.mnColDelta < 0) { // Delete and shift to left. - aDeletedRange.aStart = ScAddress(rCxt.maRange.aStart.Col()+rCxt.mnColDelta, rCxt.maRange.aStart.Row(), rCxt.maRange.aStart.Tab()); - aDeletedRange.aEnd = ScAddress(rCxt.maRange.aStart.Col()-1, rCxt.maRange.aEnd.Row(), rCxt.maRange.aEnd.Tab()); + aSelectedRange.aStart = ScAddress(rCxt.maRange.aStart.Col()+rCxt.mnColDelta, rCxt.maRange.aStart.Row(), rCxt.maRange.aStart.Tab()); + aSelectedRange.aEnd = ScAddress(rCxt.maRange.aStart.Col()-1, rCxt.maRange.aEnd.Row(), rCxt.maRange.aEnd.Tab()); } else if (rCxt.mnRowDelta < 0) { // Delete and shift up. - aDeletedRange.aStart = ScAddress(rCxt.maRange.aStart.Col(), rCxt.maRange.aStart.Row()+rCxt.mnRowDelta, rCxt.maRange.aStart.Tab()); - aDeletedRange.aEnd = ScAddress(rCxt.maRange.aEnd.Col(), rCxt.maRange.aStart.Row()-1, rCxt.maRange.aEnd.Tab()); + aSelectedRange.aStart = ScAddress(rCxt.maRange.aStart.Col(), rCxt.maRange.aStart.Row()+rCxt.mnRowDelta, rCxt.maRange.aStart.Tab()); + aSelectedRange.aEnd = ScAddress(rCxt.maRange.aEnd.Col(), rCxt.maRange.aStart.Row()-1, rCxt.maRange.aEnd.Tab()); } else if (rCxt.mnTabDelta < 0) { // Deleting sheets. // TODO : Figure out what to do here. } + else if (rCxt.mnColDelta > 0) + { + // Insert and shift to the right. + aSelectedRange.aStart = rCxt.maRange.aStart; + aSelectedRange.aEnd = ScAddress(rCxt.maRange.aStart.Col()+rCxt.mnColDelta-1, rCxt.maRange.aEnd.Row(), rCxt.maRange.aEnd.Tab()); + } + else if (rCxt.mnRowDelta > 0) + { + // Insert and shift down. + aSelectedRange.aStart = rCxt.maRange.aStart; + aSelectedRange.aEnd = ScAddress(rCxt.maRange.aEnd.Col(), rCxt.maRange.aStart.Row()+rCxt.mnRowDelta-1, rCxt.maRange.aEnd.Tab()); + } + else if (rCxt.mnTabDelta > 0) + { + // Inserting sheets. + // TODO : Figure out what to do here. + } - return aDeletedRange; + return aSelectedRange; } void setRefDeleted( ScSingleRefData& rRef, const sc::RefUpdateContext& rCxt ) @@ -2279,11 +2296,48 @@ bool shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const Sc return false; } +bool expandRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rInsertedRange ) +{ + 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. + return false; + + if (rInsertedRange.aStart.Col() == rRefRange.aStart.Col()) + // Inserted range is at the left end. No expansion. + return false; + + // Move the last column position to the right. + SCCOL nDelta = rInsertedRange.aEnd.Col() - rInsertedRange.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. + return false; + + if (rInsertedRange.aStart.Row() == rRefRange.aStart.Row()) + // Inserted range is at the top end. No expansion. + return false; + + // Move the last row position down. + SCROW nDelta = rInsertedRange.aEnd.Row() - rInsertedRange.aStart.Row() + 1; + rRefRange.aEnd.IncRow(nDelta); + return true; + } + return false; +} + } sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos ) { - ScRange aDeletedRange = getDeletedRange(rCxt); + ScRange aSelectedRange = getSelectedRange(rCxt); sc::RefUpdateResult aRes; ScAddress aNewPos = rOldPos; @@ -2303,7 +2357,7 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon ScSingleRefData& rRef = pToken->GetSingleRef(); ScAddress aAbs = rRef.toAbs(rOldPos); - if (aDeletedRange.In(aAbs)) + if (rCxt.isDeleted() && aSelectedRange.In(aAbs)) { // This reference is in the deleted region. setRefDeleted(rRef, rCxt); @@ -2322,20 +2376,36 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon ScComplexRefData& rRef = pToken->GetDoubleRef(); ScRange aAbs = rRef.toAbs(rOldPos); - if (aDeletedRange.In(aAbs)) + if (rCxt.isDeleted()) { - // This reference is in the deleted region. - setRefDeleted(rRef, rCxt); - aRes.mbValueChanged = true; - break; + if (aSelectedRange.In(aAbs)) + { + // This reference is in the deleted region. + setRefDeleted(rRef, rCxt); + aRes.mbValueChanged = true; + break; + } + else if (aSelectedRange.Intersects(aAbs)) + { + if (shrinkRange(rCxt, aAbs, aSelectedRange)) + { + // The reference range has been shrunk. + rRef.SetRange(aAbs, aNewPos); + aRes.mbValueChanged = true; + aRes.mbRangeSizeModified = true; + break; + } + } } - else if (aDeletedRange.Intersects(aAbs)) + + if (rCxt.isInserted() && aSelectedRange.Intersects(aAbs)) { - if (shrinkRange(rCxt, aAbs, aDeletedRange)) + if (expandRange(rCxt, aAbs, aSelectedRange)) { - // The reference range has been shrunk. + // The reference range has been expanded. rRef.SetRange(aAbs, aNewPos); aRes.mbValueChanged = true; + aRes.mbRangeSizeModified = true; break; } } |