summaryrefslogtreecommitdiff
path: root/svx/source/svdraw
diff options
context:
space:
mode:
authorPhilippe Jung <phil.jung@free.fr>2015-05-01 23:32:00 +0200
committerJan Holesovsky <kendy@collabora.com>2015-05-05 10:03:29 +0000
commit80a38d299133823e93ec5c29e8fe5c51771940d5 (patch)
tree911b1d525dd741a1210d0dfbb641e140fd52f0b5 /svx/source/svdraw
parent7ebed1d63e2ad5728fa81b65fa98f09b0406965d (diff)
tdf#34555 add crop features to svx
Adds crop feature to SdrObject. In EndSdrDrag related to Crop, there is a new branch. If object is a regular SdrGrafObj (known inside svx), it is used. Else, a virtual method on the object is used. This enables to forward End of crop action to SwVirtFlyDrawObj objects (when you crop with handles in writer). Regarding writer, coordinates based on Twip/MM100 are used, not the matrix based one. This is part of a serie of 4 patches that adds Save graphic, Change Picture, Edit with external tool, Crop (by handles) in all products (scalc, sdraw, simpress, swriter). Main menus, toolbars and contextual menus are updated accordingly. Change-Id: Ie1a133d18487f51bb9c44ae2f000e63d911bf6b3 Reviewed-on: https://gerrit.libreoffice.org/15588 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Jan Holesovsky <kendy@collabora.com> Tested-by: Jan Holesovsky <kendy@collabora.com>
Diffstat (limited to 'svx/source/svdraw')
-rw-r--r--svx/source/svdraw/svddrgmt.cxx171
-rw-r--r--svx/source/svdraw/svddrgv.cxx2
-rw-r--r--svx/source/svdraw/svdedtv.cxx12
-rw-r--r--svx/source/svdraw/svdmrkv.cxx12
-rw-r--r--svx/source/svdraw/svdobj.cxx19
5 files changed, 204 insertions, 12 deletions
diff --git a/svx/source/svdraw/svddrgmt.cxx b/svx/source/svdraw/svddrgmt.cxx
index c68b62adf128..884a05fb9c6f 100644
--- a/svx/source/svdraw/svddrgmt.cxx
+++ b/svx/source/svdraw/svddrgmt.cxx
@@ -1316,7 +1316,6 @@ void SdrDragObjOwn::MoveSdrDrag(const Point& rNoSnapPnt)
{
SnapPos(aPnt);
}
-
if(getSdrDragView().IsOrtho())
{
if (DragStat().IsOrtho8Possible())
@@ -3607,7 +3606,7 @@ void SdrDragDistort::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPol
-TYPEINIT1(SdrDragCrop,SdrDragResize);
+TYPEINIT1(SdrDragCrop,SdrDragObjOwn);
SdrDragCrop::SdrDragCrop(SdrDragView& rNewView)
: SdrDragObjOwn(rNewView)
@@ -3659,8 +3658,172 @@ bool SdrDragCrop::EndSdrDrag(bool /*bCopy*/)
if( rMarkList.GetMarkCount() != 1 )
return false;
- SdrGrafObj* pObj = dynamic_cast<SdrGrafObj*>( rMarkList.GetMark( 0 )->GetMarkedSdrObj() );
+ SdrObject* pSdrObject = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+
+ // tdf 34555: in order to implement visual crop in Writer, we need to handle two
+ // cases:
+ // EndSdrDrag when called in Impress/Draw/...: pSdrObject is a SdrGrafObj
+ // EndSdrDrag when called in Writer: pSdrObject is a SwVirtFlyDrawObj
+ // Main principle: if marked object is not SdrGrafObj, we start a generic handling
+ // based on virtual methods added to SdrObject, on MM100/Twip coordinates and so on.
+ // If marked object is SdrGrafObj, we do all the work here with matrix based
+ // coordinates.
+ if (!pSdrObject->ISA(SdrGrafObj)) {
+ const bool bUndo = getSdrDragView().IsUndoEnabled();
+ if( bUndo )
+ {
+ OUString aUndoStr;
+ ImpTakeDescriptionStr(STR_DragMethCrop, aUndoStr);
+ getSdrDragView().BegUndo( aUndoStr );
+ getSdrDragView().AddUndo( getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pSdrObject));
+ // also need attr undo, the SdrGrafCropItem will be changed
+ getSdrDragView().AddUndo( getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pSdrObject));
+ }
+
+ // We need to produce a reference point and two (X & Y) scales
+ SdrHdl* pRef1=GetHdlList().GetHdl(HDL_UPLFT);
+ SdrHdl* pRef2=GetHdlList().GetHdl(HDL_LWRGT);
+
+ if (pRef1==NULL || pRef2==NULL)
+ return false;
+
+ Rectangle rect(pRef1->GetPos(),pRef2->GetPos());
+
+ Point aEnd(DragStat().GetNow());
+ Point aStart(DragStat().GetStart());
+ Point aRef(rect.Center());
+
+ // Reference point is the point opposed to the dragged handle
+ switch(GetDragHdlKind())
+ {
+ case HDL_UPLFT: aRef = rect.BottomRight(); break;
+ case HDL_UPPER: aRef = rect.BottomCenter(); DragStat().SetHorFixed(true); break;
+ case HDL_UPRGT: aRef = rect.BottomLeft(); break;
+ case HDL_LEFT : aRef = rect.RightCenter(); DragStat().SetVerFixed(true); break;
+ case HDL_RIGHT: aRef = rect.LeftCenter(); DragStat().SetVerFixed(true); break;
+ case HDL_LWLFT: aRef = rect.TopRight(); break;
+ case HDL_LOWER: aRef = rect.TopCenter(); DragStat().SetHorFixed(true); break;
+ case HDL_LWRGT: aRef = rect.TopLeft(); break;
+ default: break;
+ }
+
+ // By default, scale is new size / old size
+ long nXDiv = aStart.X()-aRef.X(); if (nXDiv==0) nXDiv=1;
+ long nYDiv = aStart.Y()-aRef.Y(); if (nYDiv==0) nYDiv=1;
+ long nXMul = aEnd.X()-aRef.X();
+ long nYMul = aEnd.Y()-aRef.Y();
+
+ if (nXDiv<0)
+ {
+ nXDiv=-nXDiv;
+ nXMul=-nXMul;
+ }
+
+ if (nYDiv<0)
+ {
+ nYDiv=-nYDiv;
+ nYMul=-nYMul;
+ }
+
+ // Take ortho into account.
+ bool bXNeg=nXMul<0; if (bXNeg) nXMul=-nXMul;
+ bool bYNeg=nYMul<0; if (bYNeg) nYMul=-nYMul;
+ bool bOrtho=getSdrDragView().IsOrtho() || !getSdrDragView().IsResizeAllowed(false);
+
+ if (!DragStat().IsHorFixed() && !DragStat().IsVerFixed())
+ {
+ if (std::abs(nXDiv)<=1 || std::abs(nYDiv)<=1)
+ bOrtho=false;
+
+ if (bOrtho)
+ {
+ if ((Fraction(nXMul,nXDiv)>Fraction(nYMul,nYDiv)) !=getSdrDragView().IsBigOrtho())
+ {
+ nXMul=nYMul;
+ nXDiv=nYDiv;
+ }
+ else
+ {
+ nYMul=nXMul;
+ nYDiv=nXDiv;
+ }
+ }
+ }
+ else
+ {
+ if (bOrtho)
+ {
+ if (DragStat().IsHorFixed())
+ {
+ bXNeg=false;
+ nXMul=nYMul;
+ nXDiv=nYDiv;
+ }
+
+ if (DragStat().IsVerFixed())
+ {
+ bYNeg=false;
+ nYMul=nXMul;
+ nYDiv=nXDiv;
+ }
+ }
+ else
+ {
+ if (DragStat().IsHorFixed())
+ {
+ bXNeg=false;
+ nXMul=1;
+ nXDiv=1;
+ }
+
+ if (DragStat().IsVerFixed())
+ {
+ bYNeg=false;
+ nYMul=1;
+ nYDiv=1;
+ }
+ }
+ }
+ Fraction aXFact(nXMul,nXDiv);
+ Fraction aYFact(nYMul,nYDiv);
+ Fraction aMaxFact(0x7FFFFFFF,1);
+
+ if (bOrtho)
+ {
+ if (aXFact>aMaxFact)
+ {
+ aXFact=aMaxFact;
+ aYFact=aMaxFact;
+ }
+
+ if (aYFact>aMaxFact)
+ {
+ aXFact=aMaxFact;
+ aYFact=aMaxFact;
+ }
+ }
+
+ if (bXNeg)
+ aXFact=Fraction(-aXFact.GetNumerator(),aXFact.GetDenominator());
+
+ if (bYNeg)
+ aYFact=Fraction(-aYFact.GetNumerator(),aYFact.GetDenominator());
+
+ // With Ref point (opposed to dragged point), X scale and Y scale,
+ // we call crop (virtual method) on pSdrObject which calls VirtFlyDrawObj
+ // crop
+ pSdrObject->Crop(aRef, aXFact, aYFact);
+
+ if( bUndo )
+ getSdrDragView().EndUndo();
+
+ // Job's done
+ return true;
+ }
+
+ // This part of code handles the case where pSdrObject is SdrGrafObj
+ SdrGrafObj* pObj = dynamic_cast<SdrGrafObj*>( pSdrObject );
if( !pObj || (pObj->GetGraphicType() == GRAPHIC_NONE) || (pObj->GetGraphicType() == GRAPHIC_DEFAULT) )
return false;
@@ -3723,7 +3886,7 @@ bool SdrDragCrop::EndSdrDrag(bool /*bCopy*/)
aInverse.invert();
- // gererate start point of original drag vector in unit coordinates (the
+ // generate start point of original drag vector in unit coordinates (the
// vis-a-vis of the drag point)
basegfx::B2DPoint aLocalStart(0.0, 0.0);
bool bOnAxis(false);
diff --git a/svx/source/svdraw/svddrgv.cxx b/svx/source/svdraw/svddrgv.cxx
index abcda08e571c..2f083a089a98 100644
--- a/svx/source/svdraw/svddrgv.cxx
+++ b/svx/source/svdraw/svddrgv.cxx
@@ -342,7 +342,7 @@ bool SdrDragView::BegDragObj(const Point& rPnt, OutputDevice* pOut, SdrHdl* pHdl
}
else
{
- if (!IsCrookAllowed(true) && !IsCrookAllowed(false))
+ if (!IsCropAllowed())
return false;
mpCurrentSdrDragMethod = new SdrDragCrop(*this);
}
diff --git a/svx/source/svdraw/svdedtv.cxx b/svx/source/svdraw/svdedtv.cxx
index 8984e9450353..c9a567a2914c 100644
--- a/svx/source/svdraw/svdedtv.cxx
+++ b/svx/source/svdraw/svdedtv.cxx
@@ -72,6 +72,7 @@ void SdrEditView::ImpResetPossibilityFlags()
bMirror45Allowed =false;
bMirror90Allowed =false;
bTransparenceAllowed =false;
+ bCropAllowed =false;
bGradientAllowed =false;
bShearAllowed =false;
bEdgeRadiusAllowed =false;
@@ -402,6 +403,12 @@ bool SdrEditView::IsTransparenceAllowed() const
return bTransparenceAllowed;
}
+bool SdrEditView::IsCropAllowed() const
+{
+ ForcePossibilities();
+ return bCropAllowed;
+}
+
bool SdrEditView::IsGradientAllowed() const
{
ForcePossibilities();
@@ -509,6 +516,7 @@ void SdrEditView::CheckPossibilities()
// these ones are only allowed when single object is selected
bTransparenceAllowed = (nMarkCount == 1);
bGradientAllowed = (nMarkCount == 1);
+ bCropAllowed = (nMarkCount == 1);
if(bGradientAllowed)
{
// gradient depends on fill style
@@ -576,6 +584,10 @@ void SdrEditView::CheckPossibilities()
}
}
+ // Must be resizeable to allow cropping
+ if (!aInfo.bResizeFreeAllowed && !aInfo.bResizePropAllowed)
+ bCropAllowed = false;
+
// if one member cannot be converted, no conversion is possible
if(!aInfo.bCanConvToContour)
bCanConvToContour = false;
diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx
index d8efa35a5685..808f432de194 100644
--- a/svx/source/svdraw/svdmrkv.cxx
+++ b/svx/source/svdraw/svdmrkv.cxx
@@ -796,13 +796,11 @@ void SdrMarkView::SetMarkHandles()
// moved crop handling to non-frame part and the handle creation to SdrGrafObj
if(1 == nMarkCount && pMarkedObj && SDRDRAG_CROP == eDragMode)
{
- const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pMarkedObj);
-
- if(pSdrGrafObj)
- {
- pSdrGrafObj->addCropHandles(maHdlList);
- bDone = true;
- }
+ // Default addCropHandles from SdrObject does nothing. When pMarkedObj is SdrGrafObj, previous
+ // behaviour occurs (code in svx/source/svdraw/svdograf.cxx). When pMarkedObj is SwVirtFlyDrawObj
+ // writer takes the responsibility of adding handles (code in sw/source/core/draw/dflyobj.cxx)
+ pMarkedObj->addCropHandles(maHdlList);
+ bDone = true;
}
if(!bDone)
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx
index edea77372da3..59c86253942d 100644
--- a/svx/source/svdraw/svdobj.cxx
+++ b/svx/source/svdraw/svdobj.cxx
@@ -1239,6 +1239,12 @@ void SdrObject::AddToHdlList(SdrHdlList& rHdlList) const
}
}
+void SdrObject::addCropHandles(SdrHdlList& /*rTarget*/) const
+{
+ // Default implementation, does nothing. Overloaded in
+ // SdrGrafObj and SwVirtFlyDrawObj
+}
+
Rectangle SdrObject::ImpDragCalcRect(const SdrDragStat& rDrag) const
{
Rectangle aTmpRect(GetSnapRect());
@@ -1525,6 +1531,10 @@ void SdrObject::Move(const Size& rSiz)
}
}
+void SdrObject::NbcCrop(const Point& /*rRef*/, const Fraction& /*xFact*/, const Fraction& /*yFact*/) {
+ // Default: does nothing. Real behaviour in SwVirtFlyDrawObj and SdrGrafObj
+}
+
void SdrObject::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bUnsetRelative)
{
if (xFact.GetNumerator()!=xFact.GetDenominator() || yFact.GetNumerator()!=yFact.GetDenominator()) {
@@ -1543,6 +1553,15 @@ void SdrObject::Resize(const Point& rRef, const Fraction& xFact, const Fraction&
}
}
+void SdrObject::Crop(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ NbcCrop(rRef, xFact, yFact);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+}
+
void SdrObject::Rotate(const Point& rRef, long nAngle, double sn, double cs)
{
if (nAngle!=0) {