sc/inc/drwlayer.hxx                                       |    2 
 sc/source/core/data/drwlayer.cxx                          |   26 +++---
 sc/source/ui/drawfunc/fuconarc.cxx                        |    6 +
 sc/source/ui/drawfunc/fuconcustomshape.cxx                |    7 +
 sc/source/ui/drawfunc/fuconrec.cxx                        |    8 +
 sc/source/ui/drawfunc/fuconstr.cxx                        |   41 +++++++++
 sc/source/ui/drawfunc/fuconuno.cxx                        |    7 +
 sc/source/ui/drawfunc/futext.cxx                          |   21 +++-
 sc/source/ui/inc/drawview.hxx                             |    1 
 sc/source/ui/inc/fuconstr.hxx                             |    4 
 sc/source/ui/view/drawview.cxx                            |   60 ++++++++++++++
 sc/source/ui/view/gridwin3.cxx                            |   12 ++
 svx/inc/svx/svdmrkv.hxx                                   |    2 
 svx/inc/svx/svdobj.hxx                                    |    4 
 svx/source/sdr/contact/viewcontactofe3dscene.cxx          |   15 ++-
 svx/source/sdr/contact/viewcontactofgraphic.cxx           |    7 +
 svx/source/sdr/contact/viewcontactofgroup.cxx             |    6 +
 svx/source/sdr/contact/viewcontactofsdrcaptionobj.cxx     |   16 +++
 svx/source/sdr/contact/viewcontactofsdrcircobj.cxx        |   10 +-
 svx/source/sdr/contact/viewcontactofsdredgeobj.cxx        |   12 ++
 svx/source/sdr/contact/viewcontactofsdrmediaobj.cxx       |   10 +-
 svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx |   13 ++-
 svx/source/sdr/contact/viewcontactofsdrole2obj.cxx        |    6 +
 svx/source/sdr/contact/viewcontactofsdrpathobj.cxx        |    5 +
 svx/source/sdr/contact/viewcontactofsdrrectobj.cxx        |    9 +-
 svx/source/sdr/contact/viewcontactofunocontrol.cxx        |   11 +-
 svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx  |   23 ++++-
 svx/source/svdraw/svdcrtv.cxx                             |    9 +-
 svx/source/svdraw/svddrgmt.cxx                            |    3 
 svx/source/svdraw/svdedtv1.cxx                            |    4 
 svx/source/svdraw/svdedxv.cxx                             |   13 ++-
 svx/source/svdraw/svdmrkv.cxx                             |   33 +++++++
 svx/source/svdraw/svdobj.cxx                              |    1 
 svx/source/svdraw/svdorect.cxx                            |    4 
 34 files changed, 355 insertions(+), 56 deletions(-)

New commits:
commit c4e649f0cd013e86adbd794859bcc3cb9ee3aa61
Author: Noel Power <noel.po...@suse.com>
Date:   Tue Nov 27 17:56:33 2012 +0000

    Sync draw object to calc grid for better alignment when zooming
    
    There can be some serious rounding errors involved when calculating where to
    draw the grid lines for the various row heights in a document. This can be
    especially true for a document that has many different row heights.
    This results in draw objects appearing to move relative to the grid line at
    different zoom levels.  This patch attempts to fix this problem adjusting
    the position of the shapes as they are drawn to ensure their position
    relative to grid appears to be stable.  We do this by translating the 
position
    of the shape to the corrosponding position of it's cell anchor. Of course 
not
    all shapes are cell anchored and in this case we position the shape relative
    a temporary synthesized cell anchor.
    The patch essentially does the following
    
    a) calculates the offset to be applied for each shape at the current zoom 
level
    to ensure that the shape will be drawn relative to the correct cell grid
       see drwlayer.cxx, drawview.cxx & gridwin3.cxx, svdobj.[ch]xx
    b) apply the offset in the drawing layer for each of the different drawing
    primitives see svx/source/sdr/contact/*
    c) making sure the position and size of the newly created shape ( at any 
zoom
    level ) are still as expected when zoom level is changed.
       see. sc/source/ui/drawfunc/fuco*.cxx &
    d) making sure that overlays and handles are displayed at the correct 
position
          see svx/source/svdraw/*
    
    it could also be that a full blown transform might be needed to additionally
    scale the object ( to ensure that the edges of the object stay stable 
relative
    to ajacent grid lines ) If necessary we could do that in a later step.
    
    Change-Id: I02232f8ba192d58dbf96b80adf66c281cd0f65e8

diff --git a/sc/inc/drwlayer.hxx b/sc/inc/drwlayer.hxx
index 9f7bc56..c37937a 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 0034d92..129f1da 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 a0b2bed..e7507b6 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 80322d1..532a803 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 8ef1ce7..9a77e4e 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 e7786de..320b701 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 924ab3e..ba0e4b7 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 2505ada..f014ad2 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 6574cac..650d6d9 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 2f4c0d5..c50feba 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 adea013..85e5402 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 228bdd3..7e44cce 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 a979c6d..133a438 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 9aa7bd6..656a218 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 7f262e3..4e3c604 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 144f991..6897df7 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 1c8cead..ce1e923 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 8c12c10..a990384 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 709287e..2b1f58c 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 708cb94..8385fb0 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 62dec85..4d1dcfd 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 7fe688b..654ed86 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 4dd6e20..358eda0 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 f07d3ce..a6c130b 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 739b64a..166c3d5 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 6d6d415..94cb790 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 96d7142..1384531 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 0bbb9a9..6e1adbb 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 578251b..29603fd 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 edda48c..d843567 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 317eb9f..10d4736 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 d789f29..dcf57db 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 0ea722d..31fef51 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 7a9bf13..68f5258 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;
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to