diff options
-rw-r--r-- | include/svx/svdedtv.hxx | 2 | ||||
-rw-r--r-- | include/svx/svdobj.hxx | 3 | ||||
-rw-r--r-- | include/svx/svdograf.hxx | 2 | ||||
-rw-r--r-- | svx/inc/globlmn_tmpl.hrc | 5 | ||||
-rw-r--r-- | svx/source/svdraw/svddrgmt.cxx | 171 | ||||
-rw-r--r-- | svx/source/svdraw/svddrgv.cxx | 2 | ||||
-rw-r--r-- | svx/source/svdraw/svdedtv.cxx | 12 | ||||
-rw-r--r-- | svx/source/svdraw/svdmrkv.cxx | 12 | ||||
-rw-r--r-- | svx/source/svdraw/svdobj.cxx | 19 |
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) { |