summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Power <noel.power@suse.com>2012-11-27 17:56:33 +0000
committerNoel Power <noel.power@suse.com>2012-11-28 14:50:25 +0000
commitc4e649f0cd013e86adbd794859bcc3cb9ee3aa61 (patch)
tree41038de6c78c01a15e730d218ea5a61a28de8fdd
parent24c0e7ed9971663dfcaf9c4c1182dd6da9df005f (diff)
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
-rw-r--r--sc/inc/drwlayer.hxx2
-rw-r--r--sc/source/core/data/drwlayer.cxx26
-rw-r--r--sc/source/ui/drawfunc/fuconarc.cxx6
-rw-r--r--sc/source/ui/drawfunc/fuconcustomshape.cxx7
-rw-r--r--sc/source/ui/drawfunc/fuconrec.cxx8
-rw-r--r--sc/source/ui/drawfunc/fuconstr.cxx41
-rw-r--r--sc/source/ui/drawfunc/fuconuno.cxx7
-rw-r--r--sc/source/ui/drawfunc/futext.cxx21
-rw-r--r--sc/source/ui/inc/drawview.hxx1
-rw-r--r--sc/source/ui/inc/fuconstr.hxx4
-rw-r--r--sc/source/ui/view/drawview.cxx60
-rw-r--r--sc/source/ui/view/gridwin3.cxx12
-rw-r--r--svx/inc/svx/svdmrkv.hxx2
-rw-r--r--svx/inc/svx/svdobj.hxx4
-rw-r--r--svx/source/sdr/contact/viewcontactofe3dscene.cxx15
-rw-r--r--svx/source/sdr/contact/viewcontactofgraphic.cxx7
-rw-r--r--svx/source/sdr/contact/viewcontactofgroup.cxx6
-rw-r--r--svx/source/sdr/contact/viewcontactofsdrcaptionobj.cxx16
-rw-r--r--svx/source/sdr/contact/viewcontactofsdrcircobj.cxx10
-rw-r--r--svx/source/sdr/contact/viewcontactofsdredgeobj.cxx12
-rw-r--r--svx/source/sdr/contact/viewcontactofsdrmediaobj.cxx10
-rw-r--r--svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx13
-rw-r--r--svx/source/sdr/contact/viewcontactofsdrole2obj.cxx6
-rw-r--r--svx/source/sdr/contact/viewcontactofsdrpathobj.cxx5
-rw-r--r--svx/source/sdr/contact/viewcontactofsdrrectobj.cxx9
-rw-r--r--svx/source/sdr/contact/viewcontactofunocontrol.cxx11
-rw-r--r--svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx23
-rw-r--r--svx/source/svdraw/svdcrtv.cxx9
-rw-r--r--svx/source/svdraw/svddrgmt.cxx3
-rw-r--r--svx/source/svdraw/svdedtv1.cxx4
-rw-r--r--svx/source/svdraw/svdedxv.cxx13
-rw-r--r--svx/source/svdraw/svdmrkv.cxx33
-rw-r--r--svx/source/svdraw/svdobj.cxx1
-rw-r--r--svx/source/svdraw/svdorect.cxx4
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;