diff options
34 files changed, 355 insertions, 56 deletions
diff --git a/sc/inc/drwlayer.hxx b/sc/inc/drwlayer.hxx index 9f7bc566f84a..c37937a7f7c9 100644 --- a/sc/inc/drwlayer.hxx +++ b/sc/inc/drwlayer.hxx @@ -177,6 +177,8 @@ public: static void SetPageAnchored( SdrObject& ); static void SetCellAnchored( SdrObject&, const ScDrawObjData &rAnchor ); + // Updates rAnchor based on position of rObj + static void GetCellAnchorFromPosition( SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab ); static void SetCellAnchoredFromPosition( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab ); static void UpdateCellAnchorFromPositionEnd( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab ); static ScAnchorType GetAnchorType( const SdrObject& ); diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx index 0034d92caca2..129f1da48803 100644 --- a/sc/source/core/data/drwlayer.cxx +++ b/sc/source/core/data/drwlayer.cxx @@ -1748,33 +1748,39 @@ void ScDrawLayer::SetCellAnchored( SdrObject &rObj, const ScDrawObjData &rAnchor pAnchor->maEndOffset = rAnchor.maEndOffset; } + void ScDrawLayer::SetCellAnchoredFromPosition( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab ) { + ScDrawObjData aAnchor; + GetCellAnchorFromPosition( rObj, aAnchor, rDoc, nTab ); + SetCellAnchored( rObj, aAnchor ); +} + +void ScDrawLayer::GetCellAnchorFromPosition( SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab ) +{ Rectangle aObjRect(rObj.GetLogicRect()); ScRange aRange = rDoc.GetRange( nTab, aObjRect ); Rectangle aCellRect; - ScDrawObjData aAnchor; - aAnchor.maStart = aRange.aStart; + rAnchor.maStart = aRange.aStart; aCellRect = rDoc.GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab() ); - aAnchor.maStartOffset.Y() = aObjRect.Top()-aCellRect.Top(); + rAnchor.maStartOffset.Y() = aObjRect.Top()-aCellRect.Top(); if (!rDoc.IsNegativePage(nTab)) - aAnchor.maStartOffset.X() = aObjRect.Left()-aCellRect.Left(); + rAnchor.maStartOffset.X() = aObjRect.Left()-aCellRect.Left(); else - aAnchor.maStartOffset.X() = aCellRect.Right()-aObjRect.Right(); + rAnchor.maStartOffset.X() = aCellRect.Right()-aObjRect.Right(); - aAnchor.maEnd = aRange.aEnd; + rAnchor.maEnd = aRange.aEnd; aCellRect = rDoc.GetMMRect( aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Tab() ); - aAnchor.maEndOffset.Y() = aObjRect.Bottom()-aCellRect.Top(); + rAnchor.maEndOffset.Y() = aObjRect.Bottom()-aCellRect.Top(); if (!rDoc.IsNegativePage(nTab)) - aAnchor.maEndOffset.X() = aObjRect.Right()-aCellRect.Left(); + rAnchor.maEndOffset.X() = aObjRect.Right()-aCellRect.Left(); else - aAnchor.maEndOffset.X() = aCellRect.Right()-aObjRect.Left(); + rAnchor.maEndOffset.X() = aCellRect.Right()-aObjRect.Left(); - SetCellAnchored( rObj, aAnchor ); } void ScDrawLayer::UpdateCellAnchorFromPositionEnd( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab ) diff --git a/sc/source/ui/drawfunc/fuconarc.cxx b/sc/source/ui/drawfunc/fuconarc.cxx index a0b2bed7110d..e7507b6e6703 100644 --- a/sc/source/ui/drawfunc/fuconarc.cxx +++ b/sc/source/ui/drawfunc/fuconarc.cxx @@ -74,8 +74,14 @@ sal_Bool FuConstArc::MouseButtonDown( const MouseEvent& rMEvt ) if ( rMEvt.IsLeft() && !pView->IsAction() ) { Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) ); + // Hack to align object to nearest grid position where object + // would be anchored ( if it were cell anchored ) + // Get grid offset for current position ( note: aPnt is + // also adjusted ) + Point aGridOff = CurrentGridSyncOffsetAndPos( aPnt ); pWindow->CaptureMouse(); pView->BegCreateObj( aPnt ); + pView->GetCreateObj()->SetGridOffset( aGridOff ); bReturn = sal_True; } return bReturn; diff --git a/sc/source/ui/drawfunc/fuconcustomshape.cxx b/sc/source/ui/drawfunc/fuconcustomshape.cxx index 80322d1948db..532a803ea093 100644 --- a/sc/source/ui/drawfunc/fuconcustomshape.cxx +++ b/sc/source/ui/drawfunc/fuconcustomshape.cxx @@ -83,6 +83,12 @@ sal_Bool FuConstCustomShape::MouseButtonDown(const MouseEvent& rMEvt) if ( rMEvt.IsLeft() && !pView->IsAction() ) { Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) ); + // Hack to align object to nearest grid position where object + // would be anchored ( if it were cell anchored ) + // Get grid offset for current position ( note: aPnt is + // also adjusted ) + Point aGridOff = CurrentGridSyncOffsetAndPos( aPnt ); + pWindow->CaptureMouse(); pView->BegCreateObj(aPnt); @@ -95,6 +101,7 @@ sal_Bool FuConstCustomShape::MouseButtonDown(const MouseEvent& rMEvt) bForceNoFillStyle = sal_True; if ( bForceNoFillStyle ) pObj->SetMergedItem( XFillStyleItem( XFILL_NONE ) ); + pObj->SetGridOffset( aGridOff ); } bReturn = sal_True; diff --git a/sc/source/ui/drawfunc/fuconrec.cxx b/sc/source/ui/drawfunc/fuconrec.cxx index 8ef1ce7ab1ef..9a77e4e9d343 100644 --- a/sc/source/ui/drawfunc/fuconrec.cxx +++ b/sc/source/ui/drawfunc/fuconrec.cxx @@ -82,7 +82,11 @@ sal_Bool FuConstRectangle::MouseButtonDown(const MouseEvent& rMEvt) if ( rMEvt.IsLeft() && !pView->IsAction() ) { Point aPos( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) ); - + // Hack to align object to nearest grid position where object + // would be anchored ( if it were cell anchored ) + // Get grid offset for current position ( note: aPnt is + // also adjusted ) + Point aGridOff = CurrentGridSyncOffsetAndPos( aPos ); pWindow->CaptureMouse(); if ( pView->GetCurrentObjIdentifier() == OBJ_CAPTION ) @@ -95,6 +99,8 @@ sal_Bool FuConstRectangle::MouseButtonDown(const MouseEvent& rMEvt) } else bReturn = pView->BegCreateObj(aPos); + if ( bReturn ) + pView->GetCreateObj()->SetGridOffset( aGridOff ); } return bReturn; } diff --git a/sc/source/ui/drawfunc/fuconstr.cxx b/sc/source/ui/drawfunc/fuconstr.cxx index e7786de03d8a..320b70182ad5 100644 --- a/sc/source/ui/drawfunc/fuconstr.cxx +++ b/sc/source/ui/drawfunc/fuconstr.cxx @@ -39,6 +39,8 @@ #include "futext.hxx" #include "sc.hrc" #include "drawview.hxx" +#include "document.hxx" +#include "gridwin.hxx" // Maximal erlaubte Mausbewegung um noch Drag&Drop zu starten //! fusel,fuconstr,futext - zusammenfassen! @@ -75,6 +77,39 @@ sal_uInt8 FuConstruct::Command(const CommandEvent& rCEvt) return FuDraw::Command( rCEvt ); } +// Calculate and return offset at current zoom. rInOutPos is adjusted by +// the calculated offset. rInOutPos now points to the position than when +// scaled to 100% actually would be at the position you see at the current zoom +// ( relative to the grid ) note: units are expected to be in 100th mm +Point FuConstruct::CurrentGridSyncOffsetAndPos( Point& rInOutPos ) +{ + Point aRetGridOff; + ScViewData* pViewData = pViewShell->GetViewData(); + ScDocument* pDoc = pViewData ? pViewData->GetDocument() : NULL; + if ( pViewData && pDoc ) + { + // rInOutPos mightn't be where you think it is if there is zoom + // involved. Lets calculate where aPos would be at 100% zoom + // that's the actual correct position for the object ( when you + // restore the zoom. + Rectangle aObjRect( rInOutPos, rInOutPos ); + ScRange aRange = pDoc->GetRange( pView->GetTab(), aObjRect ); + ScAddress aOldStt = aRange.aStart; + Point aOldPos( pDoc->GetColOffset( aOldStt.Col(), aOldStt.Tab() ), pDoc->GetRowOffset( aOldStt.Row(), aOldStt.Tab() ) ); + aOldPos.X() = sc::TwipsToHMM( aOldPos.X() ); + aOldPos.Y() = sc::TwipsToHMM( aOldPos.Y() ); + ScSplitPos eWhich = pViewData->GetActivePart(); + ScGridWindow* pGridWin = (ScGridWindow*)pViewData->GetActiveWin(); + // and equiv screen pos + Point aScreenPos = pViewShell->GetViewData()->GetScrPos( aOldStt.Col(), aOldStt.Row(), eWhich, sal_True ); + MapMode aDrawMode = pGridWin->GetDrawMapMode(); + Point aCurPosHmm = pGridWin->PixelToLogic(aScreenPos, aDrawMode ); + Point aOff = ( rInOutPos - aCurPosHmm ); + rInOutPos = aOldPos + aOff; + aRetGridOff = aCurPosHmm - aOldPos; + } + return aRetGridOff; +} /************************************************************************* |* |* MouseButtonDown-event @@ -144,6 +179,12 @@ sal_Bool FuConstruct::MouseMove(const MouseEvent& rMEvt) Point aPix(rMEvt.GetPosPixel()); Point aPnt( pWindow->PixelToLogic(aPix) ); + // if object is being created then more than likely the mouse + // position has been 'adjusted' for the current zoom, need to + // restore the mouse position here to ensure resize works as expected + if ( pView->GetCreateObj() ) + aPnt -= pView->GetCreateObj()->GetGridOffset(); + if ( pView->IsAction() ) { ForceScroll(aPix); diff --git a/sc/source/ui/drawfunc/fuconuno.cxx b/sc/source/ui/drawfunc/fuconuno.cxx index 924ab3e60aad..ba0e4b71613a 100644 --- a/sc/source/ui/drawfunc/fuconuno.cxx +++ b/sc/source/ui/drawfunc/fuconuno.cxx @@ -76,8 +76,15 @@ sal_Bool FuConstUnoControl::MouseButtonDown(const MouseEvent& rMEvt) if ( rMEvt.IsLeft() && !pView->IsAction() ) { Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) ); + // Hack to align object to nearest grid position where object + // would be anchored ( if it were cell anchored ) + // Get grid offset for current position ( note: aPnt is + // also adjusted ) + Point aGridOff = CurrentGridSyncOffsetAndPos( aPnt ); + pWindow->CaptureMouse(); pView->BegCreateObj(aPnt); + pView->GetCreateObj()->SetGridOffset( aGridOff ); bReturn = sal_True; } return bReturn; diff --git a/sc/source/ui/drawfunc/futext.cxx b/sc/source/ui/drawfunc/futext.cxx index 2505ada36399..f014ad29f169 100644 --- a/sc/source/ui/drawfunc/futext.cxx +++ b/sc/source/ui/drawfunc/futext.cxx @@ -314,7 +314,15 @@ sal_Bool FuText::MouseButtonDown(const MouseEvent& rMEvt) /********************************************************** * Objekt erzeugen **********************************************************/ - pView->BegCreateObj(aMDPos, (OutputDevice*) NULL); + // Hack to align object to nearest grid position where object + // would be anchored ( if it were cell anchored ) + // Get grid offset for current position ( note: aPnt is + // also adjusted ) + Point aGridOff = CurrentGridSyncOffsetAndPos( aMDPos ); + + bool bRet = pView->BegCreateObj(aMDPos, (OutputDevice*) NULL); + if ( bRet ) + pView->GetCreateObj()->SetGridOffset( aGridOff ); } } } @@ -359,14 +367,19 @@ sal_Bool FuText::MouseMove(const MouseEvent& rMEvt) aDragTimer.Stop(); } + Point aPix(rMEvt.GetPosPixel()); + Point aPnt(pWindow->PixelToLogic(aPix)); + // if object is being created then more than likely the mouse + // position has been 'adjusted' for the current zoom, need to + // restore the mouse position here to ensure resize works as expected + if ( pView->GetCreateObj() ) + aPnt -= pView->GetCreateObj()->GetGridOffset(); + if ( pView->MouseMove(rMEvt, pWindow) ) return (sal_True); // Event von der SdrView ausgewertet if ( pView->IsAction() ) { - Point aPix(rMEvt.GetPosPixel()); - Point aPnt(pWindow->PixelToLogic(aPix)); - ForceScroll(aPix); pView->MovAction(aPnt); } diff --git a/sc/source/ui/inc/drawview.hxx b/sc/source/ui/inc/drawview.hxx index 6574cac15d0b..650d6d9e46e9 100644 --- a/sc/source/ui/inc/drawview.hxx +++ b/sc/source/ui/inc/drawview.hxx @@ -139,6 +139,7 @@ public: ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > CopyToTransferable(); static void CheckOle( const SdrMarkList& rMarkList, sal_Bool& rAnyOle, sal_Bool& rOneOle ); + virtual void SyncForGrid( SdrObject* pObj ); }; diff --git a/sc/source/ui/inc/fuconstr.hxx b/sc/source/ui/inc/fuconstr.hxx index 2f4c0d5dd290..c50feba8db7c 100644 --- a/sc/source/ui/inc/fuconstr.hxx +++ b/sc/source/ui/inc/fuconstr.hxx @@ -46,6 +46,10 @@ class FuConstruct : public FuDraw virtual void Activate(); virtual void Deactivate(); + + // Returns grid sync offset for rInOutPos, additionally adjusts rInOutPos + // by the offset + Point CurrentGridSyncOffsetAndPos( Point& rInOutPos); }; diff --git a/sc/source/ui/view/drawview.cxx b/sc/source/ui/view/drawview.cxx index adea01304019..85e5402f9d39 100644 --- a/sc/source/ui/view/drawview.cxx +++ b/sc/source/ui/view/drawview.cxx @@ -59,6 +59,7 @@ #include "userdat.hxx" #include "postit.hxx" #include "undocell.hxx" +#include "gridwin.hxx" #include "sc.hrc" @@ -330,6 +331,20 @@ void ScDrawView::RecalcScale() ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, pDev,aZoomX,aZoomY,nPPTX,nPPTY, aScaleX,aScaleY ); + SdrPageView* pPV = GetSdrPageView(); + if ( pViewData && pPV ) + { + if ( SdrPage* pPage = pPV->GetPage() ) + { + sal_uLong nCount = pPage->GetObjCount(); + for ( sal_uLong i = 0; i < nCount; i++ ) + { + SdrObject* pObj = pPage->GetObj( i ); + // Align objects to nearset grid position + SyncForGrid( pObj ); + } + } + } } void ScDrawView::DoConnect(SdrOle2Obj* pOleObj) @@ -741,4 +756,49 @@ void ScDrawView::MarkDropObj( SdrObject* pObj ) } } +// In order to counteract the effects of rounding due to the nature of how the +// grid positions are calcuated and drawn we calculate the offset needed at the +// current zoom to be applied to an SrdObject when it is drawn in order to make +// sure that it's position relative to the nearest cell anchor doesn't change. +// Of course not all shape(s)/control(s) are cell anchored, if the +// object doesn't have a cell anchor we synthesise a temporary anchor. +void ScDrawView::SyncForGrid( SdrObject* pObj ) +{ + // process members of a group shape separately + if ( pObj->ISA( SdrObjGroup ) ) + { + SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList(); + for ( sal_uLong i = 0, nCount = pLst->GetObjCount(); i < nCount; ++i ) + SyncForGrid( pLst->GetObj( i ) ); } + ScSplitPos eWhich = pViewData->GetActivePart(); + ScGridWindow* pGridWin = (ScGridWindow*)pViewData->GetActiveWin(); + ScDrawObjData* pData = ScDrawLayer::GetObjDataTab( pObj, nTab ); + if ( pGridWin ) + { + ScAddress aOldStt; + if( pData ) + { + aOldStt = pData->maStart; + } + else + { + // Page anchored object so... + // synthesise an anchor ( but don't attach it to + // the object as we want to maintain page anchoring ) + ScDrawObjData aAnchor; + ScDrawLayer::GetCellAnchorFromPosition( *pObj, aAnchor, *pDoc, GetTab() ); + aOldStt = aAnchor.maStart; + } + MapMode aDrawMode = pGridWin->GetDrawMapMode(); + // find pos anchor position + Point aOldPos( pDoc->GetColOffset( aOldStt.Col(), aOldStt.Tab() ), pDoc->GetRowOffset( aOldStt.Row(), aOldStt.Tab() ) ); + aOldPos.X() = sc::TwipsToHMM( aOldPos.X() ); + aOldPos.Y() = sc::TwipsToHMM( aOldPos.Y() ); + // find position of same point on the screen ( e.g. grid ) + Point aCurPos = pViewData->GetScrPos( aOldStt.Col(), aOldStt.Row(), eWhich, sal_True ); + Point aCurPosHmm = pGridWin->PixelToLogic(aCurPos, aDrawMode ); + Point aGridOff = ( aCurPosHmm - aOldPos ); + pObj->SetGridOffset( aGridOff ); + } +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/view/gridwin3.cxx b/sc/source/ui/view/gridwin3.cxx index 228bdd3c4e3a..7e44ccebb2ba 100644 --- a/sc/source/ui/view/gridwin3.cxx +++ b/sc/source/ui/view/gridwin3.cxx @@ -49,7 +49,9 @@ #include "document.hxx" #include "drwlayer.hxx" #include <vcl/svapp.hxx> - +#include "userdat.hxx" +#include "unitconv.hxx" +#include <svx/svdpage.hxx> // ----------------------------------------------------------------------- bool ScGridWindow::DrawMouseButtonDown(const MouseEvent& rMEvt) @@ -351,6 +353,10 @@ void ScGridWindow::UpdateStatusPosSize() pDrView->TakeActionRect( aRect ); if ( !aRect.IsEmpty() ) { + // mouse position will have been adjusted for offset + // at current position and zoom, restore that adjustment here + // so status shows correct value + aRect -= pDrView->GetGridOffset(); pPV->LogicToPagePos(aRect); aSet.Put( SfxPointItem( SID_ATTR_POSITION, aRect.TopLeft() ) ); aSet.Put( SvxSizeItem( SID_ATTR_SIZE, @@ -363,6 +369,10 @@ void ScGridWindow::UpdateStatusPosSize() if ( pDrView->AreObjectsMarked() ) // selected objects { Rectangle aRect = pDrView->GetAllMarkedRect(); + // mouse position will have been adjusted for offset + // at current position and zoom, restore that adjustment here + // so status shows correct value + aRect -= pDrView->GetGridOffset(); pPV->LogicToPagePos(aRect); aSet.Put( SfxPointItem( SID_ATTR_POSITION, aRect.TopLeft() ) ); aSet.Put( SvxSizeItem( SID_ATTR_SIZE, diff --git a/svx/inc/svx/svdmrkv.hxx b/svx/inc/svx/svdmrkv.hxx index a979c6d561dd..133a438bd58f 100644 --- a/svx/inc/svx/svdmrkv.hxx +++ b/svx/inc/svx/svdmrkv.hxx @@ -124,6 +124,7 @@ protected: sdr::ViewSelection* mpSdrViewSelection; Rectangle aMarkedObjRect; + Rectangle aMarkedObjRectNoOffset; Rectangle aMarkedPointsRect; Rectangle aMarkedGluePointsRect; @@ -444,6 +445,7 @@ public: const Rectangle& GetAllMarkedRect() const { return GetMarkedObjRect(); } Rectangle GetAllMarkedBoundRect() const { return GetMarkedObjBoundRect(); } const Rectangle& GetAllMarkedPointsRect() const { return GetMarkedPointsRect(); } + Point GetGridOffset() const; // Wird immer dann gerufen, wenn sich die Liste der markierten Objekte // moeglicherweise geaendert hat. Wer ueberlaed muss unbedingt auch die diff --git a/svx/inc/svx/svdobj.hxx b/svx/inc/svx/svdobj.hxx index 9aa7bd64382a..656a218237fe 100644 --- a/svx/inc/svx/svdobj.hxx +++ b/svx/inc/svx/svdobj.hxx @@ -385,6 +385,7 @@ private: protected: Rectangle aOutRect; // umschliessendes Rechteck fuer Paint (inkl. LineWdt, ...) Point aAnchor; // Ankerposition (Writer) + Point aGridOffset; // hack (Calc) SdrObjList* pObjList; // Liste, in dem das Obj eingefuegt ist. SdrPage* pPage; SdrModel* pModel; @@ -451,6 +452,9 @@ public: void SetRelativeHeight( double nValue ) { mnRelativeHeight.reset( nValue ); } boost::optional<double> GetRelativeWidth( ) const { return mnRelativeWidth; } boost::optional<double> GetRelativeHeight( ) const { return mnRelativeHeight; } + // evil calc grid/shape drawlayer syncing + Point GetGridOffset() const { return aGridOffset; } + void SetGridOffset( const Point& rGridOffset ){ aGridOffset = rGridOffset; } protected: void ImpDeleteUserData(); SdrObjUserData* ImpGetMacroUserData() const; diff --git a/svx/source/sdr/contact/viewcontactofe3dscene.cxx b/svx/source/sdr/contact/viewcontactofe3dscene.cxx index 7f262e3efd61..4e3c60410774 100644 --- a/svx/source/sdr/contact/viewcontactofe3dscene.cxx +++ b/svx/source/sdr/contact/viewcontactofe3dscene.cxx @@ -252,12 +252,15 @@ namespace sdr void ViewContactOfE3dScene::createObjectTransformation() { // create 2d Object Transformation from relative point in 2d scene to world - const Rectangle& rRectangle = GetE3dScene().GetSnapRect(); - - maObjectTransformation.set(0, 0, rRectangle.getWidth()); - maObjectTransformation.set(1, 1, rRectangle.getHeight()); - maObjectTransformation.set(0, 2, rRectangle.Left()); - maObjectTransformation.set(1, 2, rRectangle.Top()); + Rectangle aRectangle = GetE3dScene().GetSnapRect(); + // Hack for calc, transform position of object according + // to current zoom so as objects relative position to grid + // appears stable + aRectangle += GetE3dScene().GetGridOffset(); + maObjectTransformation.set(0, 0, aRectangle.getWidth()); + maObjectTransformation.set(1, 1, aRectangle.getHeight()); + maObjectTransformation.set(0, 2, aRectangle.Left()); + maObjectTransformation.set(1, 2, aRectangle.Top()); } void ViewContactOfE3dScene::createSdrSceneAttribute() diff --git a/svx/source/sdr/contact/viewcontactofgraphic.cxx b/svx/source/sdr/contact/viewcontactofgraphic.cxx index 144f9919810a..6897df78b92a 100644 --- a/svx/source/sdr/contact/viewcontactofgraphic.cxx +++ b/svx/source/sdr/contact/viewcontactofgraphic.cxx @@ -340,10 +340,13 @@ namespace sdr aAttribute.getText()); } } - // take unrotated snap rect for position and size. Directly use model data, not getBoundRect() or getSnapRect() // which will use the primitive data we just create in the near future - const Rectangle& rRectangle = GetGrafObject().GetGeoRect(); + Rectangle rRectangle = GetGrafObject().GetGeoRect(); + // Hack for calc, transform position of object according + // to current zoom so as objects relative position to grid + // appears stable + rRectangle += GetGrafObject().GetGridOffset(); const ::basegfx::B2DRange aObjectRange( rRectangle.Left(), rRectangle.Top(), rRectangle.Right(), rRectangle.Bottom()); diff --git a/svx/source/sdr/contact/viewcontactofgroup.cxx b/svx/source/sdr/contact/viewcontactofgroup.cxx index 1c8cead901bd..ce1e92373064 100644 --- a/svx/source/sdr/contact/viewcontactofgroup.cxx +++ b/svx/source/sdr/contact/viewcontactofgroup.cxx @@ -72,7 +72,11 @@ namespace sdr else { // append an invisible outline for the cases where no visible content exists - const Rectangle aCurrentBoundRect(GetSdrObjGroup().GetLastBoundRect()); + Rectangle aCurrentBoundRect(GetSdrObjGroup().GetLastBoundRect()); + // Hack for calc, transform position of object according + // to current zoom so as objects relative position to grid + // appears stable + aCurrentBoundRect += GetSdrObjGroup().GetGridOffset(); const basegfx::B2DRange aCurrentRange( aCurrentBoundRect.Left(), aCurrentBoundRect.Top(), aCurrentBoundRect.Right(), aCurrentBoundRect.Bottom()); diff --git a/svx/source/sdr/contact/viewcontactofsdrcaptionobj.cxx b/svx/source/sdr/contact/viewcontactofsdrcaptionobj.cxx index 8c12c10e37d7..a9903849059d 100644 --- a/svx/source/sdr/contact/viewcontactofsdrcaptionobj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrcaptionobj.cxx @@ -61,7 +61,13 @@ namespace sdr rCaptionObj.getText(0))); // take unrotated snap rect (direct model data) for position and size - const Rectangle& rRectangle = rCaptionObj.GetGeoRect(); + Rectangle rRectangle = rCaptionObj.GetGeoRect(); + // Hack for calc, transform position of object according + // to current zoom so as objects relative position to grid + // appears stable + Point aGridOff = rCaptionObj.GetGridOffset(); + rRectangle += aGridOff; + const ::basegfx::B2DRange aObjectRange( rRectangle.Left(), rRectangle.Top(), rRectangle.Right(), rRectangle.Bottom()); @@ -79,14 +85,18 @@ namespace sdr double fCornerRadiusY; drawinglayer::primitive2d::calculateRelativeCornerRadius( rCaptionObj.GetEckenradius(), aObjectRange, fCornerRadiusX, fCornerRadiusY); - + ::basegfx::B2DPolygon aTail = rCaptionObj.getTailPolygon(); + // Hack for calc, transform position of tail according + // to current zoom so as objects relative position to grid + // appears stable + aTail.transform( basegfx::tools::createTranslateB2DHomMatrix( aGridOff.X(), aGridOff.Y() ) ); // create primitive. Always create one (even if invisible) to let the decomposition // of SdrCaptionPrimitive2D create needed invisible elements for HitTest and BoundRect const drawinglayer::primitive2d::Primitive2DReference xReference( new drawinglayer::primitive2d::SdrCaptionPrimitive2D( aObjectMatrix, aAttribute, - rCaptionObj.getTailPolygon(), + aTail, fCornerRadiusX, fCornerRadiusY)); diff --git a/svx/source/sdr/contact/viewcontactofsdrcircobj.cxx b/svx/source/sdr/contact/viewcontactofsdrcircobj.cxx index 709287eefc01..2b1f58c75d34 100644 --- a/svx/source/sdr/contact/viewcontactofsdrcircobj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrcircobj.cxx @@ -50,10 +50,14 @@ namespace sdr GetCircObj().getText(0))); // take unrotated snap rect (direct model data) for position and size - const Rectangle& rRectangle = GetCircObj().GetGeoRect(); + Rectangle aRectangle = GetCircObj().GetGeoRect(); + // Hack for calc, transform position of object according + // to current zoom so as objects relative position to grid + // appears stable + aRectangle += GetRectObj().GetGridOffset(); const basegfx::B2DRange aObjectRange( - rRectangle.Left(), rRectangle.Top(), - rRectangle.Right(), rRectangle.Bottom()); + aRectangle.Left(), aRectangle.Top(), + aRectangle.Right(), aRectangle.Bottom() ); const GeoStat& rGeoStat(GetCircObj().GetGeoStat()); // fill object matrix diff --git a/svx/source/sdr/contact/viewcontactofsdredgeobj.cxx b/svx/source/sdr/contact/viewcontactofsdredgeobj.cxx index 708cb9446dcd..8385fb05a07d 100644 --- a/svx/source/sdr/contact/viewcontactofsdredgeobj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdredgeobj.cxx @@ -22,6 +22,7 @@ #include <svx/svdoedge.hxx> #include <svx/sdr/primitive2d/sdrattributecreator.hxx> #include <svx/sdr/primitive2d/sdrconnectorprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -40,10 +41,15 @@ namespace sdr drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrEdgeObj::createViewIndependentPrimitive2DSequence() const { - const basegfx::B2DPolygon& rEdgeTrack = GetEdgeObj().getEdgeTrack(); + basegfx::B2DPolygon aEdgeTrack = GetEdgeObj().getEdgeTrack(); + Point aGridOff = GetEdgeObj().GetGridOffset(); + // Hack for calc, transform position of object according + // to current zoom so as objects relative position to grid + // appears stable + aEdgeTrack.transform( basegfx::tools::createTranslateB2DHomMatrix( aGridOff.X(), aGridOff.Y() ) ); // what to do when no EdgeTrack is provided (HitTest and selectability) ? - OSL_ENSURE(0 != rEdgeTrack.count(), "Connectors with no geometry are not allowed (!)"); + OSL_ENSURE(0 != aEdgeTrack.count(), "Connectors with no geometry are not allowed (!)"); // ckeck attributes const SfxItemSet& rItemSet = GetEdgeObj().GetMergedItemSet(); @@ -58,7 +64,7 @@ namespace sdr const drawinglayer::primitive2d::Primitive2DReference xReference( new drawinglayer::primitive2d::SdrConnectorPrimitive2D( aAttribute, - rEdgeTrack)); + aEdgeTrack)); return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); } diff --git a/svx/source/sdr/contact/viewcontactofsdrmediaobj.cxx b/svx/source/sdr/contact/viewcontactofsdrmediaobj.cxx index 62dec8517881..4d1dcfdb2fe2 100644 --- a/svx/source/sdr/contact/viewcontactofsdrmediaobj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrmediaobj.cxx @@ -122,10 +122,14 @@ namespace sdr { // create range using the model data directly. This is in SdrTextObj::aRect which i will access using // GetGeoRect() to not trigger any calculations. It's the unrotated geometry which is okay for MediaObjects ATM. - const Rectangle& rRectangle(GetSdrMediaObj().GetGeoRect()); + Rectangle aRectangle(GetSdrMediaObj().GetGeoRect()); + // Hack for calc, transform position of object according + // to current zoom so as objects relative position to grid + // appears stable + aRectangle += GetSdrMediaObj().GetGridOffset(); const basegfx::B2DRange aRange( - rRectangle.Left(), rRectangle.Top(), - rRectangle.Right(), rRectangle.Bottom()); + aRectangle.Left(), aRectangle.Top(), + aRectangle.Right(), aRectangle.Bottom()); // create object transform basegfx::B2DHomMatrix aTransform; diff --git a/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx b/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx index 7fe688bf3350..654ed86cbaca 100644 --- a/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx @@ -117,14 +117,21 @@ namespace sdr const SdrObject* pSdrObjRepresentation = GetCustomShapeObj().GetSdrObjectFromCustomShape(); bool b3DShape(false); + Point aGridOff = GetCustomShapeObj().GetGridOffset(); + if(pSdrObjRepresentation) { + // Hack for calc, transform position of object according + // to current zoom so as objects relative position to grid + // appears stable + const_cast< SdrObject* >( pSdrObjRepresentation )->SetGridOffset( aGridOff ); SdrObjListIter aIterator(*pSdrObjRepresentation); while(aIterator.IsMore()) { SdrObject& rCandidate = *aIterator.Next(); - + // apply offset to each part + rCandidate.SetGridOffset( aGridOff ); if(!b3DShape && dynamic_cast< E3dObject* >(&rCandidate)) { b3DShape = true; @@ -145,7 +152,9 @@ namespace sdr { // take unrotated snap rect as default, then get the // unrotated text box. Rotation needs to be done centered - const Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); + Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); + // hack for calc grid sync + aObjectBound += GetCustomShapeObj().GetGridOffset(); const basegfx::B2DRange aObjectRange(aObjectBound.Left(), aObjectBound.Top(), aObjectBound.Right(), aObjectBound.Bottom()); // #i101684# get the text range unrotated and absolute to the object range diff --git a/svx/source/sdr/contact/viewcontactofsdrole2obj.cxx b/svx/source/sdr/contact/viewcontactofsdrole2obj.cxx index 4dd6e207a07e..358eda0b6dae 100644 --- a/svx/source/sdr/contact/viewcontactofsdrole2obj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrole2obj.cxx @@ -62,7 +62,11 @@ namespace sdr basegfx::B2DHomMatrix ViewContactOfSdrOle2Obj::createObjectTransform() const { // take unrotated snap rect (direct model data) for position and size - const Rectangle& rRectangle = GetOle2Obj().GetGeoRect(); + Rectangle rRectangle = GetOle2Obj().GetGeoRect(); + // Hack for calc, transform position of object according + // to current zoom so as objects relative position to grid + // appears stable + rRectangle += GetOle2Obj().GetGridOffset(); const basegfx::B2DRange aObjectRange(rRectangle.Left(), rRectangle.Top(), rRectangle.Right(), rRectangle.Bottom()); // create object matrix diff --git a/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx b/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx index f07d3ce6dad7..a6c130b08337 100644 --- a/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx @@ -48,6 +48,11 @@ namespace sdr rItemSet, GetPathObj().getText(0))); basegfx::B2DPolyPolygon aUnitPolyPolygon(GetPathObj().GetPathPoly()); + Point aGridOff = GetPathObj().GetGridOffset(); + // Hack for calc, transform position of object according + // to current zoom so as objects relative position to grid + // appears stable + aUnitPolyPolygon.transform( basegfx::tools::createTranslateB2DHomMatrix( aGridOff.X(), aGridOff.Y() ) ); sal_uInt32 nPolyCount(aUnitPolyPolygon.count()); sal_uInt32 nPointCount(0); diff --git a/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx b/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx index 739b64a167ba..166c3d52e95b 100644 --- a/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx @@ -51,10 +51,15 @@ namespace sdr GetRectObj().getText(0))); // take unrotated snap rect (direct model data) for position and size - const Rectangle& rRectangle = GetRectObj().GetGeoRect(); + Rectangle rRectangle = GetRectObj().GetGeoRect(); + // Hack for calc, transform position of object according + // to current zoom so as objects relative position to grid + // appears stable + rRectangle += GetRectObj().GetGridOffset(); const ::basegfx::B2DRange aObjectRange( rRectangle.Left(), rRectangle.Top(), - rRectangle.Right(), rRectangle.Bottom()); + rRectangle.Right(), rRectangle.Bottom() ); + const GeoStat& rGeoStat(GetRectObj().GetGeoStat()); // fill object matrix diff --git a/svx/source/sdr/contact/viewcontactofunocontrol.cxx b/svx/source/sdr/contact/viewcontactofunocontrol.cxx index 6d6d41589460..94cb79058e84 100644 --- a/svx/source/sdr/contact/viewcontactofunocontrol.cxx +++ b/svx/source/sdr/contact/viewcontactofunocontrol.cxx @@ -126,10 +126,15 @@ namespace sdr { namespace contact { // create range. Use model data directly, not getBoundRect()/getSnapRect; these will use // the primitive data themselves in the long run. Use SdrUnoObj's (which is a SdrRectObj) // call to GetGeoRect() to access SdrTextObj::aRect directly and without executing anything - const Rectangle& rRectangle(GetSdrUnoObj().GetGeoRect()); + Rectangle aRectangle(GetSdrUnoObj().GetGeoRect()); + // Hack for calc, transform position of object according + // to current zoom so as objects relative position to grid + // appears stable + Point aGridOffset = GetSdrUnoObj().GetGridOffset(); + aRectangle += aGridOffset; const basegfx::B2DRange aRange( - rRectangle.Left(), rRectangle.Top(), - rRectangle.Right(), rRectangle.Bottom()); + aRectangle.Left(), aRectangle.Top(), + aRectangle.Right(), aRectangle.Bottom()); // create object transform basegfx::B2DHomMatrix aTransform; diff --git a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx index 96d71423dc26..138453108055 100644 --- a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx +++ b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx @@ -1029,7 +1029,13 @@ namespace sdr { namespace contact { SdrUnoObj* pUnoObject( NULL ); if ( getUnoObject( pUnoObject ) ) { - UnoControlContactHelper::adjustControlGeometry_throw( m_aControl, pUnoObject->GetLogicRect(), _rViewTransformation, m_aZoomLevelNormalization ); + Point aGridOffset = pUnoObject->GetGridOffset(); + Rectangle aRect( pUnoObject->GetLogicRect() ); + // Hack for calc, transform position of object according + // to current zoom so as objects relative position to grid + // appears stable + aRect += aGridOffset; + UnoControlContactHelper::adjustControlGeometry_throw( m_aControl, aRect, _rViewTransformation, m_aZoomLevelNormalization ); } else OSL_FAIL( "ViewObjectContactOfUnoControl_Impl::positionAndZoomControl: no SdrUnoObj!" ); @@ -1207,11 +1213,17 @@ namespace sdr { namespace contact { // knit the model and the control _out_rControl.setModel( xControlModel ); + Point aGridOffset = _rUnoObject.GetGridOffset(); + Rectangle aRect( _rUnoObject.GetLogicRect() ); + // Hack for calc, transform position of object according + // to current zoom so as objects relative position to grid + // appears stable + aRect += aGridOffset; // proper geometry UnoControlContactHelper::adjustControlGeometry_throw( _out_rControl, - _rUnoObject.GetLogicRect(), + aRect, _rInitialViewTransformation, _rInitialZoomNormalization ); @@ -1606,7 +1618,12 @@ namespace sdr { namespace contact { // Do use model data directly to create the correct geometry. Do NOT // use getBoundRect()/getSnapRect() here; tese will use the sequence of // primitives themselves in the long run. - const Rectangle aSdrGeoData( _rVOC.GetSdrUnoObj().GetGeoRect() ); + Rectangle aSdrGeoData( _rVOC.GetSdrUnoObj().GetGeoRect() ); + Point aGridOffset = _rVOC.GetSdrUnoObj().GetGridOffset(); + // Hack for calc, transform position of object according + // to current zoom so as objects relative position to grid + // appears stable + aSdrGeoData += aGridOffset; const basegfx::B2DRange aRange( aSdrGeoData.Left(), aSdrGeoData.Top(), diff --git a/svx/source/svdraw/svdcrtv.cxx b/svx/source/svdraw/svdcrtv.cxx index 0bbb9a9f7afc..6e1adbb4ca5f 100644 --- a/svx/source/svdraw/svdcrtv.cxx +++ b/svx/source/svdraw/svdcrtv.cxx @@ -39,6 +39,7 @@ #include <svx/svdocirc.hxx> #include <svx/sdr/contact/viewcontact.hxx> #include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -834,7 +835,13 @@ void SdrCreateView::ShowCreateObj(/*OutputDevice* pOut, sal_Bool bFull*/) } else { - mpCreateViewExtraData->CreateAndShowOverlay(*this, 0, pAktCreate->TakeCreatePoly(aDragStat)); + ::basegfx::B2DPolyPolygon aPoly = pAktCreate->TakeCreatePoly(aDragStat); + Point aGridOff = pAktCreate->GetGridOffset(); + // Hack for calc, transform position of create placeholder + // object according to current zoom so as objects relative + // position to grid appears stable + aPoly.transform( basegfx::tools::createTranslateB2DHomMatrix( aGridOff.X(), aGridOff.Y() ) ); + mpCreateViewExtraData->CreateAndShowOverlay(*this, 0, aPoly); } // #i101679# Force changed overlay to be shown diff --git a/svx/source/svdraw/svddrgmt.cxx b/svx/source/svdraw/svddrgmt.cxx index 578251bc9d2f..29603fd841e4 100644 --- a/svx/source/svdraw/svddrgmt.cxx +++ b/svx/source/svdraw/svddrgmt.cxx @@ -1726,7 +1726,8 @@ bool SdrDragResize::BeginSdrDrag() if (pRefHdl!=NULL && !getSdrDragView().IsResizeAtCenter()) { - DragStat().Ref1()=pRefHdl->GetPos(); + // Calc hack to adjust for calc grid + DragStat().Ref1()=pRefHdl->GetPos() - getSdrDragView().GetGridOffset(); } else { diff --git a/svx/source/svdraw/svdedtv1.cxx b/svx/source/svdraw/svdedtv1.cxx index edda48c1cc55..d843567c4439 100644 --- a/svx/source/svdraw/svdedtv1.cxx +++ b/svx/source/svdraw/svdedtv1.cxx @@ -1183,7 +1183,9 @@ SfxItemSet SdrEditView::GetGeoAttrFromMarked() const 0); if (AreObjectsMarked()) { SfxItemSet aMarkAttr(GetAttrFromMarked(sal_False)); // because of AutoGrowHeight and corner radius - Rectangle aRect(GetMarkedObjRect()); + Rectangle aRect(GetMarkedObjRect() ); + // restore position to that before calc hack + aRect -= GetGridOffset(); if(GetSdrPageView()) { diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx index 317eb9fb9e0a..10d47361bcc2 100644 --- a/svx/source/svdraw/svdedxv.cxx +++ b/svx/source/svdraw/svdedxv.cxx @@ -188,7 +188,11 @@ void SdrObjEditView::ModelHasChanged() pTextObj->TakeTextEditArea(&aPaperMin1,&aPaperMax1,&aEditArea1,&aMinArea1); Point aPvOfs(pTextObj->GetTextEditOffset()); - + // Hack for calc, transform position of edit object according + // to current zoom so as objects relative position to grid + // appears stable + aEditArea1 += pTextObj->GetGridOffset(); + aMinArea1 += pTextObj->GetGridOffset(); aEditArea1.Move(aPvOfs.X(),aPvOfs.Y()); aMinArea1.Move(aPvOfs.X(),aPvOfs.Y()); Rectangle aNewArea(aMinArea1); @@ -627,9 +631,14 @@ sal_Bool SdrObjEditView::SdrBeginTextEdit( aTextEditArea = aTextRect; - Point aPvOfs(pTextObj->GetTextEditOffset()); + // Hack for calc, transform position of edit object according + // to current zoom so as objects relative position to grid + // appears stable + Point aPvOfs(pTextObj->GetTextEditOffset()); + aTextEditArea += pTextObj->GetGridOffset(); aTextEditArea.Move(aPvOfs.X(),aPvOfs.Y()); + aMinTextEditArea += pTextObj->GetGridOffset(); aMinTextEditArea.Move(aPvOfs.X(),aPvOfs.Y()); pTextEditCursorMerker=pWin->GetCursor(); diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx index d789f2904d92..dcf57db1301f 100644 --- a/svx/source/svdraw/svdmrkv.cxx +++ b/svx/source/svdraw/svdmrkv.cxx @@ -440,9 +440,9 @@ sal_Bool SdrMarkView::BegMarkGluePoints(const Point& rPnt, sal_Bool bUnmark) BrkAction(); DBG_ASSERT(0L == mpMarkGluePointsOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkGluePointsOverlay (!)"); + basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y()); mpMarkGluePointsOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark); - aDragStat.Reset(rPnt); aDragStat.NextPoint(); aDragStat.SetMinMove(nMinMovLog); @@ -616,10 +616,13 @@ void SdrMarkView::SetMarkHandles() } } + // apply calc offset to marked object rect + // ( necessary for handles to be displayed in + // correct position ) + Point aGridOff = GetGridOffset(); if (bFrmHdl) { Rectangle aRect(GetMarkedObjRect()); - // #i33755# const sal_Bool bHideHandlesWhenInTextEdit( ((SdrView*)this)->IsTextEdit() @@ -648,6 +651,7 @@ void SdrMarkView::SetMarkHandles() { SdrHdl* pHdl=aHdl.GetHdl(i); pHdl->SetObj(pMarkedObj); + pHdl->SetPos( pHdl->GetPos() + aGridOff ); pHdl->SetPageView(pMarkedPV); pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0)); } @@ -705,6 +709,7 @@ void SdrMarkView::SetMarkHandles() for (sal_uIntPtr i=nSiz0; i<nSiz1; i++) { SdrHdl* pHdl=aHdl.GetHdl(i); + pHdl->SetPos( pHdl->GetPos() + aGridOff ); pHdl->SetObj(pObj); pHdl->SetPageView(pPV); pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0)); @@ -1520,6 +1525,8 @@ SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nT const bool bTXT(pObj->ISA(SdrTextObj) && ((SdrTextObj*)pObj)->IsTextFrame()); SdrObject* pRet=NULL; Rectangle aRect(pObj->GetCurrentBoundRect()); + // hack for calc grid sync + aRect += pObj->GetGridOffset(); sal_uInt16 nTol2(nTol); // double tolerance for OLE, text frames and objects in @@ -1872,25 +1879,47 @@ Rectangle SdrMarkView::GetMarkedObjBoundRect() const SdrMark* pM=GetSdrMarkByIndex(nm); SdrObject* pO=pM->GetMarkedSdrObj(); Rectangle aR1(pO->GetCurrentBoundRect()); + // Ensure marked area includes the calc offset + // ( if applicable ) to sync to grid + aR1 += pO->GetGridOffset(); if (aRect.IsEmpty()) aRect=aR1; else aRect.Union(aR1); } return aRect; } +Point SdrMarkView::GetGridOffset() const +{ + Point aOffset; + // calculate the area occupied by the union of each marked object + // ( synced to grid ) and compare to the same unsynced area to calculate + // the offset. Hopefully that's the sensible thing to do + const Rectangle& aGroupSyncedRect = GetMarkedObjRect(); + aOffset = aGroupSyncedRect.TopLeft() - aMarkedObjRectNoOffset.TopLeft(); + return aOffset; +} + const Rectangle& SdrMarkView::GetMarkedObjRect() const { if (bMarkedObjRectDirty) { ((SdrMarkView*)this)->bMarkedObjRectDirty=sal_False; Rectangle aRect; + Rectangle aRect2; for (sal_uIntPtr nm=0; nm<GetMarkedObjectCount(); nm++) { SdrMark* pM=GetSdrMarkByIndex(nm); SdrObject* pO=pM->GetMarkedSdrObj(); Rectangle aR1(pO->GetSnapRect()); + // apply calc offset to marked object rect + // ( necessary for handles to be displayed in + // correct position ) + if (aRect2.IsEmpty()) aRect2=aR1; + else aRect2.Union( aR1 ); + aR1 += pO->GetGridOffset(); if (aRect.IsEmpty()) aRect=aR1; else aRect.Union(aR1); } ((SdrMarkView*)this)->aMarkedObjRect=aRect; + ((SdrMarkView*)this)->aMarkedObjRectNoOffset=aRect2; } return aMarkedObjRect; } diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx index 0ea722dc6178..31fef51f3fea 100644 --- a/svx/source/svdraw/svdobj.cxx +++ b/svx/source/svdraw/svdobj.cxx @@ -1056,6 +1056,7 @@ SdrObject& SdrObject::operator=(const SdrObject& rObj) delete pPlusData->pBroadcast; // broadcaster isn't copied pPlusData->pBroadcast=NULL; } + aGridOffset = rObj.aGridOffset; return *this; } diff --git a/svx/source/svdraw/svdorect.cxx b/svx/source/svdraw/svdorect.cxx index 7a9bf136bb9a..68f52587851a 100644 --- a/svx/source/svdraw/svdorect.cxx +++ b/svx/source/svdraw/svdorect.cxx @@ -316,7 +316,9 @@ SdrHdl* SdrRectObj::GetHdl(sal_uInt32 nHdlNum) const { case 0: { - pH = new ImpTextframeHdl(aRect); + // hack for calc grid sync to ensure the hatched area + // for a textbox is displayed at correct position + pH = new ImpTextframeHdl(aRect + GetGridOffset() ); pH->SetObj((SdrObject*)this); pH->SetDrehWink(aGeo.nDrehWink); break; |