summaryrefslogtreecommitdiff
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
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>
-rw-r--r--include/svx/svdedtv.hxx2
-rw-r--r--include/svx/svdobj.hxx3
-rw-r--r--include/svx/svdograf.hxx2
-rw-r--r--svx/inc/globlmn_tmpl.hrc5
-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
9 files changed, 215 insertions, 13 deletions
diff --git a/include/svx/svdedtv.hxx b/include/svx/svdedtv.hxx
index c22074bcc5ae..cdc23088704a 100644
--- a/include/svx/svdedtv.hxx
+++ b/include/svx/svdedtv.hxx
@@ -109,6 +109,7 @@ protected:
bool bShearAllowed : 1;
bool bEdgeRadiusAllowed : 1;
bool bTransparenceAllowed : 1;
+ bool bCropAllowed : 1;
bool bGradientAllowed : 1;
bool bCanConvToPath : 1;
bool bCanConvToPoly : 1;
@@ -250,6 +251,7 @@ public:
bool IsShearAllowed() const;
bool IsEdgeRadiusAllowed() const;
bool IsCrookAllowed(bool bNoContortion=false) const;
+ bool IsCropAllowed() const;
bool IsDistortAllowed(bool bNoContortion=false) const;
// Unite several objects to a polygon:
diff --git a/include/svx/svdobj.hxx b/include/svx/svdobj.hxx
index de32cf06ce7e..d7f71d5a9c13 100644
--- a/include/svx/svdobj.hxx
+++ b/include/svx/svdobj.hxx
@@ -571,6 +571,7 @@ public:
virtual sal_uInt32 GetPlusHdlCount(const SdrHdl& rHdl) const;
virtual SdrHdl* GetPlusHdl(const SdrHdl& rHdl, sal_uInt32 nPlNum) const;
virtual void AddToHdlList(SdrHdlList& rHdlList) const;
+ virtual void addCropHandles(SdrHdlList& rTarget) const;
/// The standard transformations (Move,Resize,Rotate,Mirror,Shear) are
/// taken over by the View (TakeXorPoly(),...).
@@ -630,12 +631,14 @@ public:
/// Nbc means "no broadcast".
virtual void NbcMove (const Size& rSiz);
virtual void NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact);
+ virtual void NbcCrop (const Point& rRef, const Fraction& xFact, const Fraction& yFact);
virtual void NbcRotate(const Point& rRef, long nAngle, double sn, double cs);
virtual void NbcMirror(const Point& rRef1, const Point& rRef2);
virtual void NbcShear (const Point& rRef, long nAngle, double tn, bool bVShear);
virtual void Move (const Size& rSiz);
virtual void Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bUnsetRelative = true);
+ virtual void Crop (const Point& rRef, const Fraction& xFact, const Fraction& yFact);
virtual void Rotate(const Point& rRef, long nAngle, double sn, double cs);
virtual void Mirror(const Point& rRef1, const Point& rRef2);
virtual void Shear (const Point& rRef, long nAngle, double tn, bool bVShear);
diff --git a/include/svx/svdograf.hxx b/include/svx/svdograf.hxx
index 29499a180742..c0becced8c17 100644
--- a/include/svx/svdograf.hxx
+++ b/include/svx/svdograf.hxx
@@ -210,7 +210,7 @@ public:
virtual SdrObject* getFullDragClone() const SAL_OVERRIDE;
// add handles for crop mode when selected
- void addCropHandles(SdrHdlList& rTarget) const;
+ virtual void addCropHandles(SdrHdlList& rTarget) const;
};
#endif // INCLUDED_SVX_SVDOGRAF_HXX
diff --git a/svx/inc/globlmn_tmpl.hrc b/svx/inc/globlmn_tmpl.hrc
index b53f23a64063..ae6953d63117 100644
--- a/svx/inc/globlmn_tmpl.hrc
+++ b/svx/inc/globlmn_tmpl.hrc
@@ -253,6 +253,11 @@
Command = ".uno:ExternalEdit" ; \
Text [ en-US ] = "Edit with External Tool..." ; \
+#define ITEM_OBJECT_CROP \
+ Identifier = SID_OBJECT_CROP ; \
+ Command = ".uno:Crop" ; \
+ Text [ en-US ] = "Crop I~mage" ; \
+
#define ITEM_COMPRESS_GRAPHIC \
Identifier = SID_COMPRESS_GRAPHIC ; \
Command = ".uno:CompressGraphic" ; \
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) {