Kaydet (Commit) 80a38d29 authored tarafından Philippe Jung's avatar Philippe Jung Kaydeden (comit) Jan Holesovsky

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/15588Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarJan Holesovsky <kendy@collabora.com>
Tested-by: 's avatarJan Holesovsky <kendy@collabora.com>
üst 7ebed1d6
...@@ -109,6 +109,7 @@ protected: ...@@ -109,6 +109,7 @@ protected:
bool bShearAllowed : 1; bool bShearAllowed : 1;
bool bEdgeRadiusAllowed : 1; bool bEdgeRadiusAllowed : 1;
bool bTransparenceAllowed : 1; bool bTransparenceAllowed : 1;
bool bCropAllowed : 1;
bool bGradientAllowed : 1; bool bGradientAllowed : 1;
bool bCanConvToPath : 1; bool bCanConvToPath : 1;
bool bCanConvToPoly : 1; bool bCanConvToPoly : 1;
...@@ -250,6 +251,7 @@ public: ...@@ -250,6 +251,7 @@ public:
bool IsShearAllowed() const; bool IsShearAllowed() const;
bool IsEdgeRadiusAllowed() const; bool IsEdgeRadiusAllowed() const;
bool IsCrookAllowed(bool bNoContortion=false) const; bool IsCrookAllowed(bool bNoContortion=false) const;
bool IsCropAllowed() const;
bool IsDistortAllowed(bool bNoContortion=false) const; bool IsDistortAllowed(bool bNoContortion=false) const;
// Unite several objects to a polygon: // Unite several objects to a polygon:
......
...@@ -571,6 +571,7 @@ public: ...@@ -571,6 +571,7 @@ public:
virtual sal_uInt32 GetPlusHdlCount(const SdrHdl& rHdl) const; virtual sal_uInt32 GetPlusHdlCount(const SdrHdl& rHdl) const;
virtual SdrHdl* GetPlusHdl(const SdrHdl& rHdl, sal_uInt32 nPlNum) const; virtual SdrHdl* GetPlusHdl(const SdrHdl& rHdl, sal_uInt32 nPlNum) const;
virtual void AddToHdlList(SdrHdlList& rHdlList) const; virtual void AddToHdlList(SdrHdlList& rHdlList) const;
virtual void addCropHandles(SdrHdlList& rTarget) const;
/// The standard transformations (Move,Resize,Rotate,Mirror,Shear) are /// The standard transformations (Move,Resize,Rotate,Mirror,Shear) are
/// taken over by the View (TakeXorPoly(),...). /// taken over by the View (TakeXorPoly(),...).
...@@ -630,12 +631,14 @@ public: ...@@ -630,12 +631,14 @@ public:
/// Nbc means "no broadcast". /// Nbc means "no broadcast".
virtual void NbcMove (const Size& rSiz); virtual void NbcMove (const Size& rSiz);
virtual void NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact); 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 NbcRotate(const Point& rRef, long nAngle, double sn, double cs);
virtual void NbcMirror(const Point& rRef1, const Point& rRef2); virtual void NbcMirror(const Point& rRef1, const Point& rRef2);
virtual void NbcShear (const Point& rRef, long nAngle, double tn, bool bVShear); virtual void NbcShear (const Point& rRef, long nAngle, double tn, bool bVShear);
virtual void Move (const Size& rSiz); virtual void Move (const Size& rSiz);
virtual void Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bUnsetRelative = true); 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 Rotate(const Point& rRef, long nAngle, double sn, double cs);
virtual void Mirror(const Point& rRef1, const Point& rRef2); virtual void Mirror(const Point& rRef1, const Point& rRef2);
virtual void Shear (const Point& rRef, long nAngle, double tn, bool bVShear); virtual void Shear (const Point& rRef, long nAngle, double tn, bool bVShear);
......
...@@ -210,7 +210,7 @@ public: ...@@ -210,7 +210,7 @@ public:
virtual SdrObject* getFullDragClone() const SAL_OVERRIDE; virtual SdrObject* getFullDragClone() const SAL_OVERRIDE;
// add handles for crop mode when selected // add handles for crop mode when selected
void addCropHandles(SdrHdlList& rTarget) const; virtual void addCropHandles(SdrHdlList& rTarget) const;
}; };
#endif // INCLUDED_SVX_SVDOGRAF_HXX #endif // INCLUDED_SVX_SVDOGRAF_HXX
......
...@@ -253,6 +253,11 @@ ...@@ -253,6 +253,11 @@
Command = ".uno:ExternalEdit" ; \ Command = ".uno:ExternalEdit" ; \
Text [ en-US ] = "Edit with External Tool..." ; \ 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 \ #define ITEM_COMPRESS_GRAPHIC \
Identifier = SID_COMPRESS_GRAPHIC ; \ Identifier = SID_COMPRESS_GRAPHIC ; \
Command = ".uno:CompressGraphic" ; \ Command = ".uno:CompressGraphic" ; \
......
...@@ -1316,7 +1316,6 @@ void SdrDragObjOwn::MoveSdrDrag(const Point& rNoSnapPnt) ...@@ -1316,7 +1316,6 @@ void SdrDragObjOwn::MoveSdrDrag(const Point& rNoSnapPnt)
{ {
SnapPos(aPnt); SnapPos(aPnt);
} }
if(getSdrDragView().IsOrtho()) if(getSdrDragView().IsOrtho())
{ {
if (DragStat().IsOrtho8Possible()) if (DragStat().IsOrtho8Possible())
...@@ -3607,7 +3606,7 @@ void SdrDragDistort::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPol ...@@ -3607,7 +3606,7 @@ void SdrDragDistort::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPol
TYPEINIT1(SdrDragCrop,SdrDragResize); TYPEINIT1(SdrDragCrop,SdrDragObjOwn);
SdrDragCrop::SdrDragCrop(SdrDragView& rNewView) SdrDragCrop::SdrDragCrop(SdrDragView& rNewView)
: SdrDragObjOwn(rNewView) : SdrDragObjOwn(rNewView)
...@@ -3659,8 +3658,172 @@ bool SdrDragCrop::EndSdrDrag(bool /*bCopy*/) ...@@ -3659,8 +3658,172 @@ bool SdrDragCrop::EndSdrDrag(bool /*bCopy*/)
if( rMarkList.GetMarkCount() != 1 ) if( rMarkList.GetMarkCount() != 1 )
return false; 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) ) if( !pObj || (pObj->GetGraphicType() == GRAPHIC_NONE) || (pObj->GetGraphicType() == GRAPHIC_DEFAULT) )
return false; return false;
...@@ -3723,7 +3886,7 @@ bool SdrDragCrop::EndSdrDrag(bool /*bCopy*/) ...@@ -3723,7 +3886,7 @@ bool SdrDragCrop::EndSdrDrag(bool /*bCopy*/)
aInverse.invert(); 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) // vis-a-vis of the drag point)
basegfx::B2DPoint aLocalStart(0.0, 0.0); basegfx::B2DPoint aLocalStart(0.0, 0.0);
bool bOnAxis(false); bool bOnAxis(false);
......
...@@ -342,7 +342,7 @@ bool SdrDragView::BegDragObj(const Point& rPnt, OutputDevice* pOut, SdrHdl* pHdl ...@@ -342,7 +342,7 @@ bool SdrDragView::BegDragObj(const Point& rPnt, OutputDevice* pOut, SdrHdl* pHdl
} }
else else
{ {
if (!IsCrookAllowed(true) && !IsCrookAllowed(false)) if (!IsCropAllowed())
return false; return false;
mpCurrentSdrDragMethod = new SdrDragCrop(*this); mpCurrentSdrDragMethod = new SdrDragCrop(*this);
} }
......
...@@ -72,6 +72,7 @@ void SdrEditView::ImpResetPossibilityFlags() ...@@ -72,6 +72,7 @@ void SdrEditView::ImpResetPossibilityFlags()
bMirror45Allowed =false; bMirror45Allowed =false;
bMirror90Allowed =false; bMirror90Allowed =false;
bTransparenceAllowed =false; bTransparenceAllowed =false;
bCropAllowed =false;
bGradientAllowed =false; bGradientAllowed =false;
bShearAllowed =false; bShearAllowed =false;
bEdgeRadiusAllowed =false; bEdgeRadiusAllowed =false;
...@@ -402,6 +403,12 @@ bool SdrEditView::IsTransparenceAllowed() const ...@@ -402,6 +403,12 @@ bool SdrEditView::IsTransparenceAllowed() const
return bTransparenceAllowed; return bTransparenceAllowed;
} }
bool SdrEditView::IsCropAllowed() const
{
ForcePossibilities();
return bCropAllowed;
}
bool SdrEditView::IsGradientAllowed() const bool SdrEditView::IsGradientAllowed() const
{ {
ForcePossibilities(); ForcePossibilities();
...@@ -509,6 +516,7 @@ void SdrEditView::CheckPossibilities() ...@@ -509,6 +516,7 @@ void SdrEditView::CheckPossibilities()
// these ones are only allowed when single object is selected // these ones are only allowed when single object is selected
bTransparenceAllowed = (nMarkCount == 1); bTransparenceAllowed = (nMarkCount == 1);
bGradientAllowed = (nMarkCount == 1); bGradientAllowed = (nMarkCount == 1);
bCropAllowed = (nMarkCount == 1);
if(bGradientAllowed) if(bGradientAllowed)
{ {
// gradient depends on fill style // gradient depends on fill style
...@@ -576,6 +584,10 @@ void SdrEditView::CheckPossibilities() ...@@ -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 one member cannot be converted, no conversion is possible
if(!aInfo.bCanConvToContour) if(!aInfo.bCanConvToContour)
bCanConvToContour = false; bCanConvToContour = false;
......
...@@ -796,13 +796,11 @@ void SdrMarkView::SetMarkHandles() ...@@ -796,13 +796,11 @@ void SdrMarkView::SetMarkHandles()
// moved crop handling to non-frame part and the handle creation to SdrGrafObj // moved crop handling to non-frame part and the handle creation to SdrGrafObj
if(1 == nMarkCount && pMarkedObj && SDRDRAG_CROP == eDragMode) if(1 == nMarkCount && pMarkedObj && SDRDRAG_CROP == eDragMode)
{ {
const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pMarkedObj); // Default addCropHandles from SdrObject does nothing. When pMarkedObj is SdrGrafObj, previous
// behaviour occurs (code in svx/source/svdraw/svdograf.cxx). When pMarkedObj is SwVirtFlyDrawObj
if(pSdrGrafObj) // writer takes the responsibility of adding handles (code in sw/source/core/draw/dflyobj.cxx)
{ pMarkedObj->addCropHandles(maHdlList);
pSdrGrafObj->addCropHandles(maHdlList); bDone = true;
bDone = true;
}
} }
if(!bDone) if(!bDone)
......
...@@ -1239,6 +1239,12 @@ void SdrObject::AddToHdlList(SdrHdlList& rHdlList) const ...@@ -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 SdrObject::ImpDragCalcRect(const SdrDragStat& rDrag) const
{ {
Rectangle aTmpRect(GetSnapRect()); Rectangle aTmpRect(GetSnapRect());
...@@ -1525,6 +1531,10 @@ void SdrObject::Move(const Size& rSiz) ...@@ -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) void SdrObject::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bUnsetRelative)
{ {
if (xFact.GetNumerator()!=xFact.GetDenominator() || yFact.GetNumerator()!=yFact.GetDenominator()) { if (xFact.GetNumerator()!=xFact.GetDenominator() || yFact.GetNumerator()!=yFact.GetDenominator()) {
...@@ -1543,6 +1553,15 @@ void SdrObject::Resize(const Point& rRef, const Fraction& xFact, const Fraction& ...@@ -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) void SdrObject::Rotate(const Point& rRef, long nAngle, double sn, double cs)
{ {
if (nAngle!=0) { if (nAngle!=0) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment