diff options
author | Armin Le Grand <alg@apache.org> | 2013-11-21 11:16:41 +0000 |
---|---|---|
committer | Armin Le Grand <alg@apache.org> | 2013-11-21 11:16:41 +0000 |
commit | 9818d8d1c64bd93adfaacb8a2f824a9db1f4987d (patch) | |
tree | 839c4b89ebc67991a58248d6415bdf78579b5fc0 | |
parent | 98d1a4e5542940f7d6c39252c4987da84e4fd95f (diff) |
further gluepoint and connector refinements - move one-side connected ones, im/export, relayout on bestconnection and others
24 files changed, 307 insertions, 274 deletions
diff --git a/drawinglayer/inc/drawinglayer/processor2d/baseprocessor2d.hxx b/drawinglayer/inc/drawinglayer/processor2d/baseprocessor2d.hxx index 6fea644ea762..35bd8c9c121a 100644 --- a/drawinglayer/inc/drawinglayer/processor2d/baseprocessor2d.hxx +++ b/drawinglayer/inc/drawinglayer/processor2d/baseprocessor2d.hxx @@ -94,9 +94,7 @@ namespace drawinglayer The main part of a processBasePrimitive2D implementation is a switch..case construct, looking like the following: - void foo::processBasePrimitive2D( - const primitive2d::BasePrimitive2D& rCandidate, - const primitive2d::Primitive2DReference& rUnoCandidate) + void foo::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { switch(rCandidate.getPrimitive2DID()) { @@ -185,9 +183,7 @@ namespace drawinglayer implementation is handed over (rCandidate), but also the Uno Reference to it (rUnoCandidate). */ - virtual void processBasePrimitive2D( - const primitive2d::BasePrimitive2D& rCandidate, - const primitive2d::Primitive2DReference& rUnoCandidate); + virtual void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate); public: /// constructor/destructor diff --git a/drawinglayer/inc/drawinglayer/processor2d/contourextractor2d.hxx b/drawinglayer/inc/drawinglayer/processor2d/contourextractor2d.hxx index 597a5e8e8017..c8070830b3b9 100644 --- a/drawinglayer/inc/drawinglayer/processor2d/contourextractor2d.hxx +++ b/drawinglayer/inc/drawinglayer/processor2d/contourextractor2d.hxx @@ -50,9 +50,7 @@ namespace drawinglayer bool mbExtractFillOnly : 1; /// tooling methods - void processBasePrimitive2D( - const primitive2d::BasePrimitive2D& rCandidate, - const primitive2d::Primitive2DReference& rUnoCandidate); + void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate); public: ContourExtractor2D( diff --git a/drawinglayer/inc/drawinglayer/processor2d/hairlineextractor2d.hxx b/drawinglayer/inc/drawinglayer/processor2d/hairlineextractor2d.hxx index 606757b5a423..f644fd90b374 100644 --- a/drawinglayer/inc/drawinglayer/processor2d/hairlineextractor2d.hxx +++ b/drawinglayer/inc/drawinglayer/processor2d/hairlineextractor2d.hxx @@ -44,9 +44,7 @@ namespace drawinglayer std::vector< basegfx::B2DPolyPolygon > maExtractedHairlines; /// tooling methods - void processBasePrimitive2D( - const primitive2d::BasePrimitive2D& rCandidate, - const primitive2d::Primitive2DReference& rUnoCandidate); + void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate); void addB2DPolygon(const basegfx::B2DPolygon& rPolygon); void addB2DPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon); void addB2DTransform(const basegfx::B2DHomMatrix& rTransform); diff --git a/drawinglayer/inc/drawinglayer/processor2d/hittestprocessor2d.hxx b/drawinglayer/inc/drawinglayer/processor2d/hittestprocessor2d.hxx index 4c7d2fe8227b..90182601c8fb 100644 --- a/drawinglayer/inc/drawinglayer/processor2d/hittestprocessor2d.hxx +++ b/drawinglayer/inc/drawinglayer/processor2d/hittestprocessor2d.hxx @@ -73,9 +73,7 @@ namespace drawinglayer bool mbHitTextOnly : 1; /// tooling methods - void processBasePrimitive2D( - const primitive2d::BasePrimitive2D& rCandidate, - const primitive2d::Primitive2DReference& rUnoCandidate); + void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate); bool checkHairlineHitWithTolerance( const basegfx::B2DPolygon& rPolygon, double fDiscreteHitTolerance); diff --git a/drawinglayer/inc/drawinglayer/processor2d/linegeometryextractor2d.hxx b/drawinglayer/inc/drawinglayer/processor2d/linegeometryextractor2d.hxx index 1996875f165a..1468e09fada4 100644 --- a/drawinglayer/inc/drawinglayer/processor2d/linegeometryextractor2d.hxx +++ b/drawinglayer/inc/drawinglayer/processor2d/linegeometryextractor2d.hxx @@ -50,9 +50,7 @@ namespace drawinglayer bool mbInLineGeometry : 1; /// tooling methods - void processBasePrimitive2D( - const primitive2d::BasePrimitive2D& rCandidate, - const primitive2d::Primitive2DReference& rUnoCandidate); + void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate); public: LineGeometryExtractor2D(const geometry::ViewInformation2D& rViewInformation); diff --git a/drawinglayer/inc/drawinglayer/processor2d/objectinfoextractor2d.hxx b/drawinglayer/inc/drawinglayer/processor2d/objectinfoextractor2d.hxx index 5cf8eb948e62..93c25a9a35e0 100755 --- a/drawinglayer/inc/drawinglayer/processor2d/objectinfoextractor2d.hxx +++ b/drawinglayer/inc/drawinglayer/processor2d/objectinfoextractor2d.hxx @@ -47,9 +47,7 @@ namespace drawinglayer const primitive2d::ObjectInfoPrimitive2D* mpFound; /// tooling methods - virtual void processBasePrimitive2D( - const primitive2d::BasePrimitive2D& rCandidate, - const primitive2d::Primitive2DReference& rUnoCandidate); + virtual void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate); public: ObjectInfoPrimitiveExtractor2D(const geometry::ViewInformation2D& rViewInformation); diff --git a/drawinglayer/inc/drawinglayer/processor2d/textaspolygonextractor2d.hxx b/drawinglayer/inc/drawinglayer/processor2d/textaspolygonextractor2d.hxx index 1dbc33505a44..c62ccc50113b 100644 --- a/drawinglayer/inc/drawinglayer/processor2d/textaspolygonextractor2d.hxx +++ b/drawinglayer/inc/drawinglayer/processor2d/textaspolygonextractor2d.hxx @@ -82,9 +82,7 @@ namespace drawinglayer sal_uInt32 mnInText; // tooling methods - void processBasePrimitive2D( - const primitive2d::BasePrimitive2D& rCandidate, - const primitive2d::Primitive2DReference& rUnoCandidate); + void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate); public: TextAsPolygonExtractor2D(const geometry::ViewInformation2D& rViewInformation); diff --git a/drawinglayer/inc/drawinglayer/processor2d/vclmetafileprocessor2d.hxx b/drawinglayer/inc/drawinglayer/processor2d/vclmetafileprocessor2d.hxx index a1bb4d98458c..23d8ff4fc5ac 100644 --- a/drawinglayer/inc/drawinglayer/processor2d/vclmetafileprocessor2d.hxx +++ b/drawinglayer/inc/drawinglayer/processor2d/vclmetafileprocessor2d.hxx @@ -132,9 +132,7 @@ namespace drawinglayer /* the local processor for BasePrinitive2D-Implementation based primitives, called from the common process()-implementation */ - virtual void processBasePrimitive2D( - const primitive2d::BasePrimitive2D& rCandidate, - const primitive2d::Primitive2DReference& rUnoCandidate); + virtual void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate); public: /// constructor/destructor diff --git a/drawinglayer/inc/drawinglayer/processor2d/vclpixelprocessor2d.hxx b/drawinglayer/inc/drawinglayer/processor2d/vclpixelprocessor2d.hxx index 83e25a151259..3caae617932d 100644 --- a/drawinglayer/inc/drawinglayer/processor2d/vclpixelprocessor2d.hxx +++ b/drawinglayer/inc/drawinglayer/processor2d/vclpixelprocessor2d.hxx @@ -56,9 +56,7 @@ namespace drawinglayer /* the local processor for BasePrinitive2D-Implementation based primitives, called from the common process()-implementation */ - virtual void processBasePrimitive2D( - const primitive2d::BasePrimitive2D& rCandidate, - const primitive2d::Primitive2DReference& rUnoCandidate); + virtual void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate); // some helpers to try direct paints (shortcuts) bool tryDrawPolyPolygonColorPrimitive2DDirect(const drawinglayer::primitive2d::PolyPolygonColorPrimitive2D& rSource, double fTransparency); diff --git a/drawinglayer/source/processor2d/baseprocessor2d.cxx b/drawinglayer/source/processor2d/baseprocessor2d.cxx index 87fee9e2d164..5fdc833a3718 100644 --- a/drawinglayer/source/processor2d/baseprocessor2d.cxx +++ b/drawinglayer/source/processor2d/baseprocessor2d.cxx @@ -36,9 +36,7 @@ namespace drawinglayer { namespace processor2d { - void BaseProcessor2D::processBasePrimitive2D( - const primitive2d::BasePrimitive2D& /*rCandidate*/, - const primitive2d::Primitive2DReference& /*rUnoCandidate*/) + void BaseProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& /*rCandidate*/) { } @@ -70,7 +68,7 @@ namespace drawinglayer if(pBasePrimitive) { // it is a BasePrimitive2D implementation, use local processor - processBasePrimitive2D(*pBasePrimitive, xReference); + processBasePrimitive2D(*pBasePrimitive); } else { diff --git a/drawinglayer/source/processor2d/contourextractor2d.cxx b/drawinglayer/source/processor2d/contourextractor2d.cxx index 575198eb99c1..b7b754671301 100644 --- a/drawinglayer/source/processor2d/contourextractor2d.cxx +++ b/drawinglayer/source/processor2d/contourextractor2d.cxx @@ -59,9 +59,7 @@ namespace drawinglayer { } - void ContourExtractor2D::processBasePrimitive2D( - const primitive2d::BasePrimitive2D& rCandidate, - const primitive2d::Primitive2DReference& /*rUnoCandidate*/) + void ContourExtractor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { switch(rCandidate.getPrimitive2DID()) { diff --git a/drawinglayer/source/processor2d/hairlineextractor2d.cxx b/drawinglayer/source/processor2d/hairlineextractor2d.cxx index 34551a7f48f2..a3ed6c4a9e7f 100644 --- a/drawinglayer/source/processor2d/hairlineextractor2d.cxx +++ b/drawinglayer/source/processor2d/hairlineextractor2d.cxx @@ -72,9 +72,7 @@ namespace drawinglayer addB2DPolygon(rTransform * basegfx::tools::createUnitPolygon()); } - void HairlineGeometryExtractor2D::processBasePrimitive2D( - const primitive2d::BasePrimitive2D& rCandidate, - const primitive2d::Primitive2DReference& /*rUnoCandidate*/) + void HairlineGeometryExtractor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { switch(rCandidate.getPrimitive2DID()) { diff --git a/drawinglayer/source/processor2d/hittestprocessor2d.cxx b/drawinglayer/source/processor2d/hittestprocessor2d.cxx index a7e7382c1ac5..dd423d36e6e7 100644 --- a/drawinglayer/source/processor2d/hittestprocessor2d.cxx +++ b/drawinglayer/source/processor2d/hittestprocessor2d.cxx @@ -273,9 +273,7 @@ namespace drawinglayer } } - void HitTestProcessor2D::processBasePrimitive2D( - const primitive2d::BasePrimitive2D& rCandidate, - const primitive2d::Primitive2DReference& rUnoCandidate) + void HitTestProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { if(getHit()) { @@ -607,7 +605,17 @@ namespace drawinglayer if(mpRecordFields && bOldHit != getHit()) { // record the TextHierarchyFieldPrimitive2D hit - primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(*mpRecordFields, rUnoCandidate); + // + // here we need to get back from a implementation object (rCandidate is a + // const primitive2d::BasePrimitive2D&) to a Primitive2DReference. This potentially + // looks like it *could* create a 2nd reference to only one implementation object. Luckily, the + // ref count and data part for the UNO reference is already part of the BasePrimitive2D class (using + // cppu::WeakComponentImplHelper1 and there WeakComponentImplHelperBase and there + // cppu::OWeakObject) and thus a new UNO reference can be created anytime and will cleanly + // reference the same object + const primitive2d::Primitive2DReference aUnoCandidate(const_cast< primitive2d::BasePrimitive2D* >(&rCandidate)); + + primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(*mpRecordFields, aUnoCandidate); } } diff --git a/drawinglayer/source/processor2d/linegeometryextractor2d.cxx b/drawinglayer/source/processor2d/linegeometryextractor2d.cxx index 9d81e0989a33..97ecf9da6952 100644 --- a/drawinglayer/source/processor2d/linegeometryextractor2d.cxx +++ b/drawinglayer/source/processor2d/linegeometryextractor2d.cxx @@ -52,9 +52,7 @@ namespace drawinglayer { } - void LineGeometryExtractor2D::processBasePrimitive2D( - const primitive2d::BasePrimitive2D& rCandidate, - const primitive2d::Primitive2DReference& /*rUnoCandidate*/) + void LineGeometryExtractor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { switch(rCandidate.getPrimitive2DID()) { diff --git a/drawinglayer/source/processor2d/objectinfoextractor2d.cxx b/drawinglayer/source/processor2d/objectinfoextractor2d.cxx index 1e0dd2d140ba..11f929f61125 100755 --- a/drawinglayer/source/processor2d/objectinfoextractor2d.cxx +++ b/drawinglayer/source/processor2d/objectinfoextractor2d.cxx @@ -38,9 +38,7 @@ namespace drawinglayer { namespace processor2d { - void ObjectInfoPrimitiveExtractor2D::processBasePrimitive2D( - const primitive2d::BasePrimitive2D& rCandidate, - const primitive2d::Primitive2DReference& /*rUnoCandidate*/) + void ObjectInfoPrimitiveExtractor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { if(!mpFound) { diff --git a/drawinglayer/source/processor2d/textaspolygonextractor2d.cxx b/drawinglayer/source/processor2d/textaspolygonextractor2d.cxx index d20f658af81a..59a47fc790a6 100644 --- a/drawinglayer/source/processor2d/textaspolygonextractor2d.cxx +++ b/drawinglayer/source/processor2d/textaspolygonextractor2d.cxx @@ -37,9 +37,7 @@ namespace drawinglayer { namespace processor2d { - void TextAsPolygonExtractor2D::processBasePrimitive2D( - const primitive2d::BasePrimitive2D& rCandidate, - const primitive2d::Primitive2DReference& /*rUnoCandidate*/) + void TextAsPolygonExtractor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { switch(rCandidate.getPrimitive2DID()) { diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx index b83383b21550..1529fe96bf7f 100644 --- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx @@ -740,9 +740,7 @@ namespace drawinglayer ****************************************************************************************************/ - void VclMetafileProcessor2D::processBasePrimitive2D( - const primitive2d::BasePrimitive2D& rCandidate, - const primitive2d::Primitive2DReference& /*rUnoCandidate*/) + void VclMetafileProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { switch(rCandidate.getPrimitive2DID()) { @@ -1160,11 +1158,9 @@ namespace drawinglayer primitive2d::PolygonHairlinePrimitive2D* pPLeft = new primitive2d::PolygonHairlinePrimitive2D(aLeft, rHairlinePrimitive.getBColor()); primitive2d::PolygonHairlinePrimitive2D* pPRight = new primitive2d::PolygonHairlinePrimitive2D(aRight, rHairlinePrimitive.getBColor()); - const primitive2d::Primitive2DReference aRefLeft(pPLeft); - const primitive2d::Primitive2DReference aRefRight(pPRight); - processBasePrimitive2D(*pPLeft, aRefLeft); - processBasePrimitive2D(*pPRight, aRefRight); + processBasePrimitive2D(*pPLeft); + processBasePrimitive2D(*pPRight); } else { @@ -1214,11 +1210,9 @@ namespace drawinglayer aLeft, rStrokePrimitive.getLineAttribute(), rStrokePrimitive.getStrokeAttribute()); primitive2d::PolygonStrokePrimitive2D* pPRight = new primitive2d::PolygonStrokePrimitive2D( aRight, rStrokePrimitive.getLineAttribute(), rStrokePrimitive.getStrokeAttribute()); - const primitive2d::Primitive2DReference aRefLeft(pPLeft); - const primitive2d::Primitive2DReference aRefRight(pPRight); - processBasePrimitive2D(*pPLeft, aRefLeft); - processBasePrimitive2D(*pPRight, aRefRight); + processBasePrimitive2D(*pPLeft); + processBasePrimitive2D(*pPRight); } else { @@ -1312,11 +1306,9 @@ namespace drawinglayer rStrokeArrowPrimitive.getStrokeAttribute(), aEmpty, rStrokeArrowPrimitive.getEnd()); - const primitive2d::Primitive2DReference aRefLeft(pPLeft); - const primitive2d::Primitive2DReference aRefRight(pPRight); - processBasePrimitive2D(*pPLeft, aRefLeft); - processBasePrimitive2D(*pPRight, aRefRight); + processBasePrimitive2D(*pPLeft); + processBasePrimitive2D(*pPRight); } else { @@ -1384,9 +1376,8 @@ namespace drawinglayer new primitive2d::PolyPolygonGraphicPrimitive2D( aLocalPolyPolygon, rBitmapCandidate.getFillGraphic()); - const primitive2d::Primitive2DReference aRefSplitted(pSplitted); - processBasePrimitive2D(*pSplitted, aRefSplitted); + processBasePrimitive2D(*pSplitted); } else { diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx index 796f95368681..0dd8466ba2dd 100644 --- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx @@ -234,9 +234,7 @@ namespace drawinglayer return bTryWorked; } - void VclPixelProcessor2D::processBasePrimitive2D( - const primitive2d::BasePrimitive2D& rCandidate, - const primitive2d::Primitive2DReference& /*rUnoCandidate*/) + void VclPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { switch(rCandidate.getPrimitive2DID()) { diff --git a/svx/inc/svx/svdoedge.hxx b/svx/inc/svx/svdoedge.hxx index 0f8a1a01d32f..77b048931ba8 100644 --- a/svx/inc/svx/svdoedge.hxx +++ b/svx/inc/svx/svdoedge.hxx @@ -86,11 +86,19 @@ private: // to a correct state for first real layouting unsigned mbSuppressed : 1; - /// internal post processing when one of the positions the geometry - /// is based on changes; this is only to be called from the object - /// connectons or internally. It will correct the local transformation - /// and do needed refreshes - void geometryChange(); + /// recreate and set local transformation based on the positions from + /// both SdrObjConnections + void adaptLocalTransformation(); + + /// force recreation of EdgeTrack (except UserDefined) with all updates + /// and broadcasts + void forceEdgeTrackUpdate(); + + /// get GluePoint from connection with override of ConnectorID to not need to set it + bool impGetGluePoint( + sdr::glue::GluePoint& o_rGP, + const SdrObjConnection& rCon, + sal_uInt32 nConnectorId) const; /// helper to recalculate the EdgeTrack based on given information basegfx::B2DPolygon ImpCalcEdgeTrack( diff --git a/svx/inc/svx/svdview.hxx b/svx/inc/svx/svdview.hxx index 4e390a4554e7..74b4bf9587a5 100644 --- a/svx/inc/svx/svdview.hxx +++ b/svx/inc/svx/svdview.hxx @@ -286,14 +286,14 @@ public: void MoveHandleByVector(const SdrHdl& rHdl, const basegfx::B2DVector& rDistance, Window* pMakeVisibleWindow, SdrDragMethod* pOwnDragMethod); - /// find a SdrObject at position in rSource; evtl exclude a given SdrEdgeObj (pAvoidConnectioWith) + /// find a SdrObject at position in rSource; evtl exclude a given SdrEdgeObj (pAvoidConnectionWith) /// from that search. If no SdrObject connection is found, null is returned SdrObject* FindConnector( const basegfx::B2DPoint& rPosition, sal_uInt32& o_rnID, bool& o_rbBest, bool& o_rbAuto, - const SdrEdgeObj* pAvoidConnectioWith); + const SdrEdgeObj* pAvoidConnectionWith); }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/svx/source/svdraw/svdedtv.cxx b/svx/source/svdraw/svdedtv.cxx index 6e634f3093be..1108ccfc48eb 100644 --- a/svx/source/svdraw/svdedtv.cxx +++ b/svx/source/svdraw/svdedtv.cxx @@ -867,7 +867,7 @@ void SdrEditView::CheckPossibilities() SdrObject* pNode1 = pEdge->GetSdrObjectConnection(true); SdrObject* pNode2 = pEdge->GetSdrObjectConnection(false); - if(pNode1 || pNode2) + if(pNode1 && pNode2) { mbMoveAllowedOnSelection = false; } diff --git a/svx/source/svdraw/svdmodel.cxx b/svx/source/svdraw/svdmodel.cxx index 3ef7268568cb..fac897228cdd 100644 --- a/svx/source/svdraw/svdmodel.cxx +++ b/svx/source/svdraw/svdmodel.cxx @@ -956,28 +956,9 @@ void SdrModel::ImpReformatAllEdgeObjects() for(nNum = 0; nNum < nAnz; nNum++) { SdrEdgeObj* pSdrEdgeObj = aSdrEdgeObjVector[nNum]; - SdrObject* pObjA = pSdrEdgeObj->GetSdrObjectConnection(true); - SdrObject* pObjB = pSdrEdgeObj->GetSdrObjectConnection(false); - - // TTTT: check what happens; it might just be a ImpDirtyEdgeTrack() - // and ActionChanged() at SdrEdgeObj::Notify - if(pObjA || pObjB) - { - pSdrEdgeObj->SetEdgeTrackDirty(); - pSdrEdgeObj->ActionChanged(); - } - - //if(pObjA) - //{ - // SfxSimpleHint aHint(SFX_HINT_DATACHANGED); - // pSdrEdgeObj->Notify(*pObjA, aHint); - //} - // - //if(pObjB) - //{ - // SfxSimpleHint aHint(SFX_HINT_DATACHANGED); - // pSdrEdgeObj->Notify(*pObjB, aHint); - //} + + pSdrEdgeObj->SetEdgeTrackDirty(); + pSdrEdgeObj->ActionChanged(); } } diff --git a/svx/source/svdraw/svdoedge.cxx b/svx/source/svdraw/svdoedge.cxx index 5089c1e3a079..87be889844c8 100644 --- a/svx/source/svdraw/svdoedge.cxx +++ b/svx/source/svdraw/svdoedge.cxx @@ -83,7 +83,7 @@ protected: // if preconditions for positions change, calculate current and set, The // position depends on the object connected to and the GluePointID, but also // needs to be checked on object change - void checkPositionFromObject(); + void reactOnConnectedObjectChange(); bool getPositionFromObject(basegfx::B2DPoint& rPosition); public: @@ -103,14 +103,15 @@ public: /// inserted, e.g deleted but put to undo stack) void ownerPageChange(); - // get a copy of the GluePoint referenced; returns true if - // a GluePoint is referenced and when it got copied to rGP - bool TakeGluePoint(sdr::glue::GluePoint& rGP) const; - // allow SdrEdgeObj to adapt position in two cases: user defined // EdgeTrack or result of BestConnection being available void adaptBestConnectionPosition(const basegfx::B2DPoint& rPosition); + // when the layouter has decided the best possible AutoVertex for + // BestConnection mode he sets this value using this method. It does + // not need to trigger any updates, it only 'writes back' layout results + void adaptBestConnectorIDToAutoVertex(sal_uInt32 nNew); + // data write access void SetPosition(const basegfx::B2DPoint& rPosition); void SetConnectedSdrObject(SdrObject* pConnectedSdrObject); @@ -148,29 +149,47 @@ void SdrObjConnection::Notify(SfxBroadcaster& rBC, const SfxHint& rHint) } } - if(mpConnectedSdrObject) - { - checkPositionFromObject(); - } + reactOnConnectedObjectChange(); } } } -void SdrObjConnection::checkPositionFromObject() +void SdrObjConnection::reactOnConnectedObjectChange() { - if(mpConnectedSdrObject) + if(mpConnectedSdrObject && mpOwner) { - basegfx::B2DPoint aNewPosition(maPosition); + bool bChanged(false); - if(getPositionFromObject(aNewPosition) && !maPosition.equal(aNewPosition)) + // change implies interactive or listener-related change, so this + // can no longer be a user-defined EdgeTrack + if(mpOwner->mbEdgeTrackUserDefined) + { + mpOwner->mbEdgeTrackUserDefined = false; + bChanged = true; + } + + if(IsBestConnection()) + { + // position cannot be checked because it depends on the best found EdgeTrack; + // still, execute a SetEdgeTrackDirty to trigger the EdgeTrack recalculation + // which will then set maPosition to the new best position found + bChanged = true; + } + else { - maPosition = aNewPosition; + basegfx::B2DPoint aNewPosition(maPosition); - if(mpOwner) + if(getPositionFromObject(aNewPosition) && !maPosition.equal(aNewPosition)) { - mpOwner->geometryChange(); + maPosition = aNewPosition; + bChanged = true; } } + + if(bChanged) + { + mpOwner->forceEdgeTrackUpdate(); + } } } @@ -181,7 +200,7 @@ bool SdrObjConnection::getPositionFromObject(basegfx::B2DPoint& rPosition) const sdr::glue::GluePointProvider& rProvider = mpConnectedSdrObject->GetGluePointProvider(); bool bFound(false); - if(mbAutoVertex) + if(IsAutoVertex()) { rPosition = rProvider.getAutoGluePointByIndex(mnConnectorId).getUnitPosition(); bFound = true; @@ -259,7 +278,7 @@ SdrObjConnection& SdrObjConnection::operator=(const SdrObjConnection& rSource) StartListening(*mpConnectedSdrObject); } - checkPositionFromObject(); + reactOnConnectedObjectChange(); return *this; } @@ -275,6 +294,19 @@ void SdrObjConnection::adaptBestConnectionPosition(const basegfx::B2DPoint& rPos } } +void SdrObjConnection::adaptBestConnectorIDToAutoVertex(sal_uInt32 nNew) +{ + if(IsBestConnection()) + { + mnConnectorId = nNew; + mbAutoVertex = true; + } + else + { + OSL_ENSURE(false, "SdrObjConnection::adaptBestConnectorIDToAutoVertex only allowed for BestConnection (!)"); + } +} + void SdrObjConnection::SetPosition(const basegfx::B2DPoint& rPosition) { basegfx::B2DPoint aNewPosition(rPosition); @@ -290,7 +322,7 @@ void SdrObjConnection::SetPosition(const basegfx::B2DPoint& rPosition) if(mpOwner) { - mpOwner->geometryChange(); + mpOwner->forceEdgeTrackUpdate(); } } } @@ -311,7 +343,7 @@ void SdrObjConnection::SetConnectedSdrObject(SdrObject* pConnectedSdrObject) StartListening(*mpConnectedSdrObject); } - checkPositionFromObject(); + reactOnConnectedObjectChange(); } } @@ -320,7 +352,7 @@ void SdrObjConnection::SetConnectorID(sal_uInt32 nNew) if(nNew != mnConnectorId) { mnConnectorId = nNew; - checkPositionFromObject(); + reactOnConnectedObjectChange(); } } @@ -339,39 +371,6 @@ void SdrObjConnection::ownerPageChange() } } -bool SdrObjConnection::TakeGluePoint(sdr::glue::GluePoint& rGP) const -{ - if(mpConnectedSdrObject) - { - // Ein Obj muss schon angedockt sein! - const sdr::glue::GluePointProvider& rProvider = mpConnectedSdrObject->GetGluePointProvider(); - - if(mbAutoVertex) - { - rGP = rProvider.getAutoGluePointByIndex(mnConnectorId); - - return true; - } - else - { - - if(rProvider.hasUserGluePoints()) - { - const sdr::glue::GluePoint* pCandidate = rProvider.findUserGluePointByID(mnConnectorId); - - if(pCandidate) - { - rGP = *pCandidate; - - return true; - } - } - } - } - - return false; -} - //////////////////////////////////////////////////////////////////////////////////////////////////// // SdrEdgeInfoRec @@ -1569,7 +1568,7 @@ SdrEdgeObj::~SdrEdgeObj() { } -void SdrEdgeObj::geometryChange() +void SdrEdgeObj::adaptLocalTransformation() { const basegfx::B2DHomMatrix aCurrent( SdrTextObj::getSdrObjectTransformation()); @@ -1584,15 +1583,17 @@ void SdrEdgeObj::geometryChange() if(aNew != aCurrent) { maSdrObjectTransformation.setB2DHomMatrix(aNew); - SetEdgeTrackDirty(); - SetChanged(); - - // change implies interactive or listener-related change, so this - // can no longer be a user-defined EdgeTrack - mbEdgeTrackUserDefined = false; + } +} - // Broadcasting nur, wenn auf der selben Page - const SdrObjectChangeBroadcaster aSdrObjectChangeBroadcaster(*this); +void SdrEdgeObj::forceEdgeTrackUpdate() +{ + if(!mbEdgeTrackUserDefined) + { + maEdgeTrack.clear(); + ImpRecalcEdgeTrack(); + SetChanged(); + adaptLocalTransformation(); } } @@ -1877,6 +1878,12 @@ void SdrEdgeObj::ConnectToSdrObject(bool bTail, SdrObject* pObj) { SdrObjConnection& rCon(bTail ? *mpCon1 : *mpCon2); + if(pObj && mbEdgeTrackUserDefined) + { + // reset EdgeTrackUserDefined when a connection is established + mbEdgeTrackUserDefined = false; + } + rCon.SetConnectedSdrObject(pObj); } @@ -1987,7 +1994,7 @@ sal_uInt32 SdrEdgeObj::GetConnectorId(bool bTail) const void SdrEdgeObj::ImpRecalcEdgeTrack() { - // #120437# if bEdgeTrackUserDefined, do not recalculate + // if bEdgeTrackUserDefined, do not recalculate if(mbEdgeTrackUserDefined) { return; @@ -1999,84 +2006,121 @@ void SdrEdgeObj::ImpRecalcEdgeTrack() return; } - // #120437# also not when model locked during import, but remember + // also not when model locked during import, but remember if(getSdrModelFromSdrObject().isLocked()) { mbSuppressed = true; return; } - // #110649# if(IsBoundRectCalculationRunning()) { // this object is involved into another ImpRecalcEdgeTrack() call // from another SdrEdgeObj. Do not calculate again to avoid loop. // Also, do not change mbEdgeTrackDirty so that it gets recalculated // later at the first non-looping call. + return; } - else + + if(mbSuppressed) { - if(mbSuppressed) - { - // #123048# If layouting was ever suppressed, it needs to be done once - // and the attr need to be set at EdgeInfo, else these attr *will be lost* - // in the following call to ImpSetEdgeInfoToAttr() sice they were never - // set before (!) - maEdgeTrack = ImpCalcEdgeTrack(*mpCon1, *mpCon2, mpEdgeInfo, 0, 0); - ImpSetAttrToEdgeInfo(); - mbSuppressed = false; - } + // If layouting was ever suppressed, it needs to be done once + // and the attr need to be set at EdgeInfo, else these attr *will be lost* + // in the following call to ImpSetEdgeInfoToAttr() sice they were never + // set before (!) + maEdgeTrack = ImpCalcEdgeTrack(*mpCon1, *mpCon2, mpEdgeInfo, 0, 0); + ImpSetAttrToEdgeInfo(); + mbSuppressed = false; + } + + // To not run in a depth loop, use a coloring algorythm on + // SdrEdgeObj BoundRect calculations + mbBoundRectCalculationRunning = true; - // To not run in a depth loop, use a coloring algorythm on - // SdrEdgeObj BoundRect calculations - mbBoundRectCalculationRunning = true; + // remember current SdrEdgeInfoRec and new polygon + const SdrEdgeInfoRec aPreserved(*mpEdgeInfo); + const basegfx::B2DPolygon aNew(ImpCalcEdgeTrack(*mpCon1, *mpCon2, mpEdgeInfo, 0, 0)); + bool bBroadcastChange(false); - // remember current SdrEdgeInfoRec and new polygon - const SdrEdgeInfoRec aPreserved(*mpEdgeInfo); - const basegfx::B2DPolygon aNew(ImpCalcEdgeTrack(*mpCon1, *mpCon2, mpEdgeInfo, 0, 0)); - bool bBroadcastChange(false); + if(aNew != maEdgeTrack) + { + maEdgeTrack = aNew; - if(aNew != maEdgeTrack) + // if connections are in 'BestConnection' mode, update their position to the + // computed one, just to make sure when that data is fetched from the connection + // itself that it is correct + if(maEdgeTrack.count()) { - maEdgeTrack = aNew; + const basegfx::B2DPoint aStart(maEdgeTrack.getB2DPoint(0)); + const basegfx::B2DPoint aEnd(maEdgeTrack.getB2DPoint(maEdgeTrack.count() - 1)); - // if connections are in 'BestConnection' mode, update their oposition to the - // computed one, just to make sure when that data is fetched from the connection - // itself that it is correct - if(maEdgeTrack.count()) + if(mpCon1->IsBestConnection()) { - const basegfx::B2DPoint aStart(maEdgeTrack.getB2DPoint(0)); - const basegfx::B2DPoint aEnd(maEdgeTrack.getB2DPoint(maEdgeTrack.count() - 1)); - - if(mpCon1->IsBestConnection()) - { - mpCon1->adaptBestConnectionPosition(aStart); - } - - if(mpCon2->IsBestConnection()) - { - mpCon2->adaptBestConnectionPosition(aEnd); - } + mpCon1->adaptBestConnectionPosition(aStart); } - bBroadcastChange = true; + if(mpCon2->IsBestConnection()) + { + mpCon2->adaptBestConnectionPosition(aEnd); + } } - if(aPreserved != *mpEdgeInfo) - { - ImpSetEdgeInfoToAttr(); - bBroadcastChange = true; - } + bBroadcastChange = true; + } + + if(aPreserved != *mpEdgeInfo) + { + ImpSetEdgeInfoToAttr(); + bBroadcastChange = true; + } - if(bBroadcastChange) + if(bBroadcastChange) + { + // use local scope to trigger locally + const SdrObjectChangeBroadcaster aSdrObjectChangeBroadcaster(*this); + } + + // #110649# + mbBoundRectCalculationRunning = false; +} + +bool SdrEdgeObj::impGetGluePoint( + sdr::glue::GluePoint& o_rGP, + const SdrObjConnection& rCon, + sal_uInt32 nConnectorId) const +{ + const SdrObject* pConnected = rCon.GetConnectedSdrObject(); + + if(pConnected) + { + // Ein Obj muss schon angedockt sein! + const sdr::glue::GluePointProvider& rProvider = pConnected->GetGluePointProvider(); + + if(rCon.IsAutoVertex() || rCon.IsBestConnection()) { - // use local scope to trigger locally - const SdrObjectChangeBroadcaster aSdrObjectChangeBroadcaster(*this); + // AutoGluePoint + o_rGP = rProvider.getAutoGluePointByIndex(nConnectorId); + + return true; } + else + { + // UserGluePoint or CustomShapeGluePoint + if(rProvider.hasUserGluePoints()) + { + const sdr::glue::GluePoint* pCandidate = rProvider.findUserGluePointByID(nConnectorId); + + if(pCandidate) + { + o_rGP = *pCandidate; - // #110649# - mbBoundRectCalculationRunning = false; + return true; + } + } + } } + + return false; } basegfx::B2DPolygon SdrEdgeObj::ImpCalcEdgeTrack( @@ -2198,12 +2242,9 @@ basegfx::B2DPolygon SdrEdgeObj::ImpCalcEdgeTrack( for(sal_uInt16 nNum1(0); nNum1 < nAnz1; nNum1++) { - if(bAuto1) - { - rCon1.SetConnectorID(nNum1); - } + sdr::glue::GluePoint aGP1; - if(bCon1 && rCon1.TakeGluePoint(aGP1)) + if(bCon1 && impGetGluePoint(aGP1, rCon1, bAuto1 ? nNum1 : rCon1.GetConnectorId())) { aPt1 = rCon1.GetConnectedSdrObject()->getSdrObjectTransformation() * aGP1.getUnitPosition(); nEsc1 = aGP1.getEscapeDirections(); @@ -2223,12 +2264,9 @@ basegfx::B2DPolygon SdrEdgeObj::ImpCalcEdgeTrack( for(sal_uInt16 nNum2(0); nNum2 < nAnz2; nNum2++) { - if(bAuto2) - { - rCon2.SetConnectorID(nNum2); - } + sdr::glue::GluePoint aGP2; - if(bCon2 && rCon2.TakeGluePoint(aGP2)) + if(bCon2 && impGetGluePoint(aGP2, rCon2, bAuto2 ? nNum2 : rCon2.GetConnectorId())) { aPt2 = rCon2.GetConnectedSdrObject()->getSdrObjectTransformation() * aGP2.getUnitPosition(); nEsc2 = aGP2.getEscapeDirections(); @@ -2300,12 +2338,12 @@ basegfx::B2DPolygon SdrEdgeObj::ImpCalcEdgeTrack( if(bAuto1) { - rCon1.SetConnectorID(nBestAuto1); + rCon1.adaptBestConnectorIDToAutoVertex(nBestAuto1); } if(bAuto2) { - rCon2.SetConnectorID(nBestAuto2); + rCon2.adaptBestConnectorIDToAutoVertex(nBestAuto2); } if(pInfo) @@ -2352,6 +2390,13 @@ void SdrEdgeObj::SetEdgeTrackPath(const basegfx::B2DPolygon& rPoly) mpCon2->SetConnectedSdrObject(0); mpCon2->adaptBestConnectionPosition(maEdgeTrack.getB2DPoint(maEdgeTrack.count() - 1)); + + // adapt local transformation to changed start/end positions + adaptLocalTransformation(); + + // broadcast change + const SdrObjectChangeBroadcaster aSdrObjectChangeBroadcaster(*this); + SetChanged(); } else { @@ -2579,9 +2624,14 @@ SdrObject* SdrEdgeObj::getFullDragClone() const bool SdrEdgeObj::beginSpecialDrag(SdrDragStat& rDrag) const { if(!rDrag.GetActiveHdl()) + { return false; + } + // need to add geo and attributes to undos, else moving and connecting of + // connector ends will not be in the undo stack rDrag.SetEndDragChangesAttributes(true); + rDrag.SetEndDragChangesGeoAndAttributes(true); if(rDrag.GetActiveHdl()->GetPointNum() < 2) { @@ -2596,19 +2646,9 @@ bool SdrEdgeObj::applySpecialDrag(SdrDragStat& rDragStat) const SdrEdgeObj* pOriginalEdge = dynamic_cast< const SdrEdgeObj* >(rDragStat.GetActiveHdl()->GetObj()); const bool bOriginalEdgeModified(pOriginalEdge == this); - // not user defined if dragging + // no longer user defined if dragging is executed mbEdgeTrackUserDefined = false; - if(!bOriginalEdgeModified && pOriginalEdge) - { - // copy connections when clone is modified. This is needed because - // as preparation to this modification the data from the original object - // was copied to the clone using the operator=. As can be seen there, - // that operator does not copy the connections (for good reason) - ConnectToSdrObject(true, pOriginalEdge->mpCon1->GetConnectedSdrObject()); - ConnectToSdrObject(false, pOriginalEdge->mpCon2->GetConnectedSdrObject()); - } - if(rDragStat.GetActiveHdl()->GetPointNum() < 2) { // start or end point connector drag @@ -2879,26 +2919,57 @@ void SdrEdgeObj::setSdrObjectTransformation(const basegfx::B2DHomMatrix& rTransf if(rTransformation != aCurrentTransformation) { - // #54102# handle start and end point if not connected + basegfx::B2DHomMatrix aCompleteTransform; + + if(mbEdgeTrackUserDefined) + { + // get old transform and invert, multiply with new transform to get full transform + aCompleteTransform = basegfx::tools::guaranteeMinimalScaling(aCurrentTransformation); + aCompleteTransform.invert(); + aCompleteTransform = rTransformation * aCompleteTransform; + + // if we are user defined (e.g. already happens after reload of a non-connected edge, + // but originally was intended for external format imports) and the transformation + // is not only a translation, switch off UserDefined. Keeping UserDefined when applying + // anything but translations will make the transformed EdgeTrack look strange (we else + // never have rotated or sheared connectors) + if(basegfx::fTools::equal(aCompleteTransform.get(0, 0), 1.0) + && basegfx::fTools::equal(aCompleteTransform.get(1, 1), 1.0) + && basegfx::fTools::equalZero(aCompleteTransform.get(1, 0)) + && basegfx::fTools::equalZero(aCompleteTransform.get(0, 1))) + { + // upper left 2x2 is identity, thus this is a translation-only transformation + } + else + { + // we have scale, shear or rotate. Reset UserDefined + mbEdgeTrackUserDefined = false; + } + } + + // handle start and end point if not connected const bool bCon1(GetSdrObjectConnection(true)); const bool bCon2(GetSdrObjectConnection(false)); const bool bUserDefined(maEdgeTrack.count() && mbEdgeTrackUserDefined); const bool bApplyTransform(bUserDefined || !bCon1 || !bCon2); - const bool bCheckUserDistaces(!IsPasteResize() && mpEdgeInfo->ImpUsesUserDistances()); - bool bScale(false); if(bApplyTransform) { - // get old transform and invert, multiply with new transform to get full transform - basegfx::B2DHomMatrix aCompleteTransform(basegfx::tools::guaranteeMinimalScaling(aCurrentTransformation)); - aCompleteTransform.invert(); - aCompleteTransform = rTransformation * aCompleteTransform; + if(aCompleteTransform.isIdentity()) + { + // get old transform and invert, multiply with new transform to get full transform + aCompleteTransform = basegfx::tools::guaranteeMinimalScaling(aCurrentTransformation); + aCompleteTransform.invert(); + aCompleteTransform = rTransformation * aCompleteTransform; + } - if(bCheckUserDistaces) + bool bScaleUsed(false); + + if(!IsPasteResize() && mpEdgeInfo->ImpUsesUserDistances()) { const basegfx::B2DVector aDiagonal(1.0, 1.0); - bScale = !basegfx::fTools::equal(aDiagonal.getLength(), (aCompleteTransform * aDiagonal).getLength()); + bScaleUsed = !basegfx::fTools::equal(aDiagonal.getLength(), (aCompleteTransform * aDiagonal).getLength()); } if(bUserDefined) @@ -2911,6 +2982,9 @@ void SdrEdgeObj::setSdrObjectTransformation(const basegfx::B2DHomMatrix& rTransf mpCon2->SetConnectedSdrObject(0); mpCon2->adaptBestConnectionPosition(maEdgeTrack.getB2DPoint(maEdgeTrack.count() - 1)); + + // adapt local transformation to changed start/end positions + adaptLocalTransformation(); } else { @@ -2926,22 +3000,25 @@ void SdrEdgeObj::setSdrObjectTransformation(const basegfx::B2DHomMatrix& rTransf mpCon2->SetPosition(aCompleteTransform * mpCon2->GetPosition()); } } + + // if resize contains scale and is not from paste, forget user distances + if(bScaleUsed) + { + mpEdgeInfo->ImpResetUserDistances(); + ImpSetEdgeInfoToAttr(); + SetEdgeTrackDirty(); + } + + // something has changed; we do not call parent, so do notification and + // change calls locally + const SdrObjectChangeBroadcaster aSdrObjectChangeBroadcaster(*this); + SetChanged(); } else { - // both ends are connected to some SdrObject, thus transforming this - // object will do nothing, so no need to call parent and set the new - // transform at the underlying SdrObject. - // Reactions on changes of the connected SdrObjects is done in Notify. - } - - // if resize contains scale and is not from paste, forget user distances - if(bCheckUserDistaces && bScale) - { - mpEdgeInfo->ImpResetUserDistances(); - ImpSetEdgeInfoToAttr(); - SetEdgeTrackDirty(); - SetChanged(); + // both ends are connected to some SdrObject or the EdgeTrack is user defined, + // thus transforming this object will do nothing, so no need to call parent and + // set the new transform at the underlying SdrObject. } } } @@ -3060,13 +3137,14 @@ void SdrEdgeObj::SetTailPoint(bool bTail, const basegfx::B2DPoint& rPt) void SdrEdgeObj::setGluePointIndex(bool bTail, sal_Int32 nIndex /* = -1 */ ) { SdrObjConnection& rConn1(bTail ? *mpCon1 : *mpCon2); + const bool bBestConnection(nIndex < 0); + const bool bAutoVertex(nIndex >= 0 && nIndex < 4); - if( nIndex > 3 ) + if(nIndex > 3) { nIndex -= 4; // The start api index and the implementation index is now both 0 - // for user defined glue points we have - // to get the id for this index first + // for user defined glue points check if it exists const SdrObject* pCandidate = rConn1.GetConnectedSdrObject(); if(pCandidate) @@ -3079,14 +3157,14 @@ void SdrEdgeObj::setGluePointIndex(bool bTail, sal_Int32 nIndex /* = -1 */ ) } } } - else if( nIndex < 0 ) + + if(nIndex >= 0) { - nIndex = 0; + rConn1.SetConnectorID(nIndex); } - rConn1.SetConnectorID(nIndex); - rConn1.setBestConnection(nIndex < 0); - rConn1.setAutoVertex(nIndex >= 0 && nIndex <= 3); + rConn1.setBestConnection(bBestConnection); + rConn1.setAutoVertex(bAutoVertex); } /** this method is used by the api to return a glue point id for a connection. @@ -3094,7 +3172,7 @@ void SdrEdgeObj::setGluePointIndex(bool bTail, sal_Int32 nIndex /* = -1 */ ) sal_Int32 SdrEdgeObj::getGluePointIndex(bool bTail) { SdrObjConnection& rConn1(bTail ? *mpCon1 : *mpCon2); - sal_Int32 nId = -1; + sal_Int32 nId(-1); if(!rConn1.IsBestConnection()) { diff --git a/svx/source/svdraw/svdview.cxx b/svx/source/svdraw/svdview.cxx index 975f6a9870ea..42431acc485f 100644 --- a/svx/source/svdraw/svdview.cxx +++ b/svx/source/svdraw/svdview.cxx @@ -2250,7 +2250,7 @@ SdrObject* SdrView::FindConnector( sal_uInt32& o_rnID, bool& o_rbBest, bool& o_rbAuto, - const SdrEdgeObj* pAvoidConnectioWith) + const SdrEdgeObj* pAvoidConnectionWith) { SdrObject* pRetval = 0; SdrPageView* pSdrPageView = GetSdrPageView(); @@ -2271,7 +2271,7 @@ SdrObject* SdrView::FindConnector( if(pSdrObjectCandidate && (pSdrObjGroup || rVisLayer.IsSet(pSdrObjectCandidate->GetLayer())) && // GetLayer at groups is zero - (!pAvoidConnectioWith || pAvoidConnectioWith != pSdrObjectCandidate)) // no connections to pAvoidConnectioWith + (!pAvoidConnectionWith || pAvoidConnectionWith != pSdrObjectCandidate)) // no connections to pAvoidConnectionWith { basegfx::B2DRange aCandidateRange(pSdrObjectCandidate->getObjectRange(this)); const double fHitToleranceDoubled(getHitTolLog() * 2.0); @@ -2334,10 +2334,11 @@ SdrObject* SdrView::FindConnector( } // check if object is hit and setBestConnection + // accept other connectors, but not the same as pAvoidConnectionWith if(!pRetval - && !dynamic_cast< const SdrEdgeObj* >(pSdrObjectCandidate) + && pSdrObjectCandidate != pAvoidConnectionWith && SdrObjectPrimitiveHit(*pSdrObjectCandidate, rPosition, fHitToleranceDoubled, *this, false, 0) - && (!pAvoidConnectioWith || !pAvoidConnectioWith->GetSuppressDefaultConnect())) + && (!pAvoidConnectionWith || !pAvoidConnectionWith->GetSuppressDefaultConnect())) { pRetval = pSdrObjectCandidate; o_rnID = 0; |