summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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) {