From c1a2f580f0a5a479282cfa7ffa538de6d30b216a Mon Sep 17 00:00:00 2001 From: Armin Le Grand Date: Tue, 19 Jun 2012 09:47:15 +0000 Subject: Resolves: #i54102# added support for rotation, shear and mirror for SdrEdgeObj i.e. Edges, Connectors added interactive preview, allowed these actions for editing (cherry picked from commit f8721f5f94f74522eae36dc6dc054b983384fac9) Conflicts: svx/source/svdraw/svddrgmt.cxx svx/source/svdraw/svdoedge.cxx Change-Id: I20b971674e683a25f70f6d2e2f4b5231f38638bc Related: i#54102# Removed IsInserted() check... for doing transformations to have them on interactions (cherry picked from commit 3ca8c0e04015fcd945a66e254d845dc9081aa5e5) Conflicts: svx/source/svdraw/svdoedge.cxx Change-Id: If55e5f0d4bb5aef7f602fdcd03d51014390e8d2a --- svx/source/svdraw/svddrgmt.cxx | 112 +++++++++++++++++++++++++++++++++++++++-- svx/source/svdraw/svdoedge.cxx | 89 ++++++++++++++++++++++++++++---- 2 files changed, 185 insertions(+), 16 deletions(-) (limited to 'svx/source') diff --git a/svx/source/svdraw/svddrgmt.cxx b/svx/source/svdraw/svddrgmt.cxx index 35f4b9cb3bd7..bd0aaac6cf05 100644 --- a/svx/source/svdraw/svddrgmt.cxx +++ b/svx/source/svdraw/svddrgmt.cxx @@ -22,7 +22,6 @@ #include #include - #include "svx/xattr.hxx" #include #include @@ -68,6 +67,8 @@ #include #include #include +#include +#include //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -142,14 +143,12 @@ SdrDragEntrySdrObject::~SdrDragEntrySdrObject() } } -drawinglayer::primitive2d::Primitive2DSequence SdrDragEntrySdrObject::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod) +void SdrDragEntrySdrObject::prepareCurrentState(SdrDragMethod& rDragMethod) { // for the moment, i need to re-create the clone in all cases. I need to figure // out when clone and original have the same class, so that i can use operator= // in those cases - const SdrObject* pSource = &maOriginal; - if(mpClone) { SdrObject::Free(mpClone); @@ -165,7 +164,15 @@ drawinglayer::primitive2d::Primitive2DSequence SdrDragEntrySdrObject::createPrim // apply original transformation, implemented at the DragMethods rDragMethod.applyCurrentTransformationToSdrObject(*mpClone); + } +} +drawinglayer::primitive2d::Primitive2DSequence SdrDragEntrySdrObject::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod) +{ + const SdrObject* pSource = &maOriginal; + + if(mbModify && mpClone) + { // choose source for geometry data pSource = mpClone; } @@ -293,6 +300,24 @@ basegfx::B2DRange SdrDragMethod::getCurrentRange() const return getB2DRangeFromOverlayObjectList(); } +void SdrDragMethod::clearSdrDragEntries() +{ + for(sal_uInt32 a(0); a < maSdrDragEntries.size(); a++) + { + delete maSdrDragEntries[a]; + } + + maSdrDragEntries.clear(); +} + +void SdrDragMethod::addSdrDragEntry(SdrDragEntry* pNew) +{ + if(pNew) + { + maSdrDragEntries.push_back(pNew); + } +} + void SdrDragMethod::createSdrDragEntries() { if(getSdrDragView().GetSdrPageView() && getSdrDragView().GetSdrPageView()->HasMarkedObjPageView()) @@ -635,6 +660,16 @@ void SdrDragMethod::CancelSdrDrag() Hide(); } +struct compareConstSdrObjectRefs +{ + bool operator()(const SdrObject* p1, const SdrObject* p2) const + { + return (p1 < p2); + } +}; + +typedef std::map< const SdrObject*, SdrObject*, compareConstSdrObjectRefs> SdrObjectAndCloneMap; + void SdrDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlayManager) { // create SdrDragEntries on demand @@ -647,10 +682,77 @@ void SdrDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlay // modification from current interactive state if(!maSdrDragEntries.empty()) { + // #i54102# SdrDragEntrySdrObject creates clones of SdrObjects as base for creating the needed + // primitives, holding the original and the clone. If connectors (Edges) are involved, + // the cloned connectors need to be connected to the cloned SdrObjects (after cloning + // they are connected to the original SdrObjects). To do so, trigger the preparation + // steps for SdrDragEntrySdrObject, save an association of (orig, clone) in a helper + // and evtl. remember if it was an edge + SdrObjectAndCloneMap aOriginalAndClones; + std::vector< SdrEdgeObj* > aEdges; + sal_uInt32 a; + + // #i54102# execute prepareCurrentState for all SdrDragEntrySdrObject, register pair of original and + // clone, remember edges + for(a = 0; a < maSdrDragEntries.size(); a++) + { + SdrDragEntrySdrObject* pSdrDragEntrySdrObject = dynamic_cast< SdrDragEntrySdrObject*>(maSdrDragEntries[a]); + + if(pSdrDragEntrySdrObject) + { + pSdrDragEntrySdrObject->prepareCurrentState(*this); + + SdrEdgeObj* pSdrEdgeObj = dynamic_cast< SdrEdgeObj* >(pSdrDragEntrySdrObject->getClone()); + + if(pSdrEdgeObj) + { + aEdges.push_back(pSdrEdgeObj); + } + + if(pSdrDragEntrySdrObject->getClone()) + { + aOriginalAndClones[&pSdrDragEntrySdrObject->getOriginal()] = pSdrDragEntrySdrObject->getClone(); + } + } + } + + // #i54102# if there are edges, reconnect their ends to the corresponding clones (if found) + if(aEdges.size()) + { + for(a = 0; a < aEdges.size(); a++) + { + SdrEdgeObj* pSdrEdgeObj = aEdges[a]; + SdrObject* pConnectedTo = pSdrEdgeObj->GetConnectedNode(true); + + if(pConnectedTo) + { + SdrObjectAndCloneMap::iterator aEntry = aOriginalAndClones.find(pConnectedTo); + + if(aEntry != aOriginalAndClones.end()) + { + pSdrEdgeObj->ConnectToNode(true, aEntry->second); + } + } + + pConnectedTo = pSdrEdgeObj->GetConnectedNode(false); + + if(pConnectedTo) + { + SdrObjectAndCloneMap::iterator aEntry = aOriginalAndClones.find(pConnectedTo); + + if(aEntry != aOriginalAndClones.end()) + { + pSdrEdgeObj->ConnectToNode(false, aEntry->second); + } + } + } + } + + // collect primitives for visualisation drawinglayer::primitive2d::Primitive2DSequence aResult; drawinglayer::primitive2d::Primitive2DSequence aResultTransparent; - for(sal_uInt32 a(0); a < maSdrDragEntries.size(); a++) + for(a = 0; a < maSdrDragEntries.size(); a++) { SdrDragEntry* pCandidate = maSdrDragEntries[a]; diff --git a/svx/source/svdraw/svdoedge.cxx b/svx/source/svdraw/svdoedge.cxx index 240b2d91f2df..b2f427ba7629 100644 --- a/svx/source/svdraw/svdoedge.cxx +++ b/svx/source/svdraw/svdoedge.cxx @@ -351,15 +351,16 @@ void SdrEdgeObj::ImpSetEdgeInfoToAttr() void SdrEdgeObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const { - rInfo.bRotateFreeAllowed=sal_False; - rInfo.bRotate90Allowed =sal_False; - rInfo.bMirrorFreeAllowed=sal_False; - rInfo.bMirror45Allowed =sal_False; - rInfo.bMirror90Allowed =sal_False; + // #i54102# allow rotation, mirror and shear + rInfo.bRotateFreeAllowed = true; + rInfo.bRotate90Allowed = true; + rInfo.bMirrorFreeAllowed = true; + rInfo.bMirror45Allowed = true; + rInfo.bMirror90Allowed = true; rInfo.bTransparenceAllowed = sal_False; rInfo.bGradientAllowed = sal_False; - rInfo.bShearAllowed =sal_False; - rInfo.bEdgeRadiusAllowed=sal_False; + rInfo.bShearAllowed = true; + rInfo.bEdgeRadiusAllowed = sal_False; bool bCanConv=!HasText() || ImpCanConvTextToCurve(); rInfo.bCanConvToPath=bCanConv; rInfo.bCanConvToPoly=bCanConv; @@ -565,7 +566,7 @@ void SdrEdgeObj::ImpRecalcEdgeTrack() // SdrEdgeObj BoundRect calculations ((SdrEdgeObj*)this)->mbBoundRectCalculationRunning = sal_True; - Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect(); + Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetCurrentBoundRect(); SetRectsDirty(); *pEdgeTrack=ImpCalcEdgeTrack(*pEdgeTrack,aCon1,aCon2,&aEdgeInfo); ImpSetEdgeInfoToAttr(); // copy values from aEdgeInfo into the pool @@ -698,8 +699,11 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const XPolygon& rTrack0, SdrObjConnection& aPt2=aOutRect.BottomRight(); } } - bool bCon1=rCon1.pObj!=NULL && rCon1.pObj->GetPage()==pPage && rCon1.pObj->IsInserted(); - bool bCon2=rCon2.pObj!=NULL && rCon2.pObj->GetPage()==pPage && rCon2.pObj->IsInserted(); + + // #i54102# To allow interactive preview, do also if not inserted + bool bCon1=rCon1.pObj!=NULL && rCon1.pObj->GetPage()==pPage; + bool bCon2=rCon2.pObj!=NULL && rCon2.pObj->GetPage()==pPage; + const SfxItemSet& rSet = GetObjectItemSet(); if (bCon1) { @@ -1574,7 +1578,7 @@ void SdrEdgeObj::Notify(SfxBroadcaster& rBC, const SfxHint& rHint) (pSdrHint && pSdrHint->GetKind()==HINT_OBJREMOVED)) { // broadcasting only, if on the same page - Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect(); + Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetCurrentBoundRect(); ImpDirtyEdgeTrack(); // only redraw here, object hasn't actually changed @@ -2251,6 +2255,69 @@ void SdrEdgeObj::NbcResize(const Point& rRefPnt, const Fraction& aXFact, const F } } +// #i54102# added rotation support +void SdrEdgeObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs) +{ + // handle start and end point if not connected + bool bCon1=aCon1.pObj!=NULL && aCon1.pObj->GetPage()==pPage; + bool bCon2=aCon2.pObj!=NULL && aCon2.pObj->GetPage()==pPage; + + if(!bCon1 && pEdgeTrack) + { + RotatePoint((*pEdgeTrack)[0],rRef,sn,cs); + ImpDirtyEdgeTrack(); + } + + if(!bCon2 && pEdgeTrack) + { + sal_uInt16 nPntAnz = pEdgeTrack->GetPointCount(); + RotatePoint((*pEdgeTrack)[sal_uInt16(nPntAnz-1)],rRef,sn,cs); + ImpDirtyEdgeTrack(); + } +} + +// #i54102# added mirror support +void SdrEdgeObj::NbcMirror(const Point& rRef1, const Point& rRef2) +{ + // handle start and end point if not connected + bool bCon1=aCon1.pObj!=NULL && aCon1.pObj->GetPage()==pPage; + bool bCon2=aCon2.pObj!=NULL && aCon2.pObj->GetPage()==pPage; + + if(!bCon1 && pEdgeTrack) + { + MirrorPoint((*pEdgeTrack)[0],rRef1,rRef2); + ImpDirtyEdgeTrack(); + } + + if(!bCon2 && pEdgeTrack) + { + sal_uInt16 nPntAnz = pEdgeTrack->GetPointCount(); + MirrorPoint((*pEdgeTrack)[sal_uInt16(nPntAnz-1)],rRef1,rRef2); + ImpDirtyEdgeTrack(); + } +} + +// #i54102# added shear support +void SdrEdgeObj::NbcShear(const Point& rRef, long nWink, double tn, bool bVShear) +{ + // handle start and end point if not connected + bool bCon1=aCon1.pObj!=NULL && aCon1.pObj->GetPage()==pPage; + bool bCon2=aCon2.pObj!=NULL && aCon2.pObj->GetPage()==pPage; + + if(!bCon1 && pEdgeTrack) + { + ShearPoint((*pEdgeTrack)[0],rRef,tn,bVShear); + ImpDirtyEdgeTrack(); + } + + if(!bCon2 && pEdgeTrack) + { + sal_uInt16 nPntAnz = pEdgeTrack->GetPointCount(); + ShearPoint((*pEdgeTrack)[sal_uInt16(nPntAnz-1)],rRef,tn,bVShear); + ImpDirtyEdgeTrack(); + } +} + SdrObject* SdrEdgeObj::DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const { basegfx::B2DPolyPolygon aPolyPolygon; -- cgit