summaryrefslogtreecommitdiff
path: root/svx/source
diff options
context:
space:
mode:
authorArmin Le Grand <alg@apache.org>2012-06-19 09:47:15 +0000
committerCaolán McNamara <caolanm@redhat.com>2013-04-13 07:59:17 +0100
commitc1a2f580f0a5a479282cfa7ffa538de6d30b216a (patch)
tree4d8666bb36d3b4f4790a3a169eff320dd00eb47a /svx/source
parent5acc994f4ed3e118453fb493226b751a6d9d3bce (diff)
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
Diffstat (limited to 'svx/source')
-rw-r--r--svx/source/svdraw/svddrgmt.cxx112
-rw-r--r--svx/source/svdraw/svdoedge.cxx89
2 files changed, 185 insertions, 16 deletions
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 <tools/bigint.hxx>
#include <vcl/svapp.hxx>
-
#include "svx/xattr.hxx"
#include <svx/xpoly.hxx>
#include <svx/svdetc.hxx>
@@ -68,6 +67,8 @@
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <drawinglayer/attribute/sdrlineattribute.hxx>
#include <drawinglayer/attribute/sdrlinestartendattribute.hxx>
+#include <map>
+#include <vector>
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -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;