diff options
author | Kohei Yoshida <kohei.yoshida@suse.com> | 2011-10-28 17:38:25 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@suse.com> | 2011-10-28 20:59:30 -0400 |
commit | adefe9fce8bec3fb3c01eaa5deab7c22a1f09953 (patch) | |
tree | 205c7d1545e2fad112ed15727e3160552caabb3c | |
parent | 418a35f4861e863feb39eec73f4a39a87fbcb1f3 (diff) |
bnc#726152: Avoid adjusting cell-anchored objects on other sheets.
The old code would incorrectly move anchors from one sheet to another
when updating the anchors of an object that was not on current sheet.
That can happen e.g. when modifying a cell value which triggers a
(cell-anchored) chart object on another sheet to get updated.
Interestingly, this issue ended up causing a write error during file
save in some situations, and in others silenting removing the affected
chart objects on save.
-rw-r--r-- | sc/source/ui/view/drawvie3.cxx | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/sc/source/ui/view/drawvie3.cxx b/sc/source/ui/view/drawvie3.cxx index 400384a38712..7c976a208b1c 100644 --- a/sc/source/ui/view/drawvie3.cxx +++ b/sc/source/ui/view/drawvie3.cxx @@ -139,6 +139,42 @@ ScAnchorType ScDrawView::GetAnchorType() const return SCA_DONTKNOW; } +namespace { + +/** + * Updated the anchors of any non-note object that is cell anchored which + * has been moved since the last anchors for its position was calculated. + */ +void adjustAnchoredPosition(const SdrHint& rHint, const ScDocument& rDoc, SCTAB nTab) +{ + if (rHint.GetKind() != HINT_OBJCHG && rHint.GetKind() != HINT_OBJINSERTED) + return; + + SdrObject* pObj = const_cast<SdrObject*>(rHint.GetObject()); + if (!pObj) + return; + + ScDrawObjData *pAnchor = ScDrawLayer::GetObjData(pObj); + if (!pAnchor) + return; + + if (pAnchor->mbNote) + return; + + if (pAnchor->maLastRect == pObj->GetLogicRect()) + return; + + if (pAnchor->maStart.Tab() != nTab) + // The object is not anchored on the current sheet. Skip it. + // TODO: In the future, we may want to adjust objects that are + // anchored on all selected sheets. + return; + + ScDrawLayer::SetCellAnchoredFromPosition(*pObj, rDoc, pAnchor->maStart.Tab()); +} + +} + void ScDrawView::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) { if (rHint.ISA(ScTabDeletedHint)) // Tabelle geloescht @@ -159,15 +195,7 @@ void ScDrawView::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) else if ( rHint.ISA( SdrHint ) ) { if (const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint )) - { - //Update the anchors of any non note object that is cell anchored which has - //been moved since the last anchors for its position was calculated - if (pSdrHint->GetKind() == HINT_OBJCHG || pSdrHint->GetKind() == HINT_OBJINSERTED) - if (SdrObject* pObj = const_cast<SdrObject*>(pSdrHint->GetObject())) - if (ScDrawObjData *pAnchor = ScDrawLayer::GetObjData(pObj)) - if (!pAnchor->mbNote && pAnchor->maLastRect != pObj->GetLogicRect()) - ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *pDoc, nTab); - } + adjustAnchoredPosition(*pSdrHint, *pDoc, nTab); FmFormView::Notify( rBC,rHint ); } else |