[Libreoffice-commits] core.git: include/svx svx/inc svx/source

Philippe Jung phil.jung at free.fr
Tue May 5 03:03:53 PDT 2015


 include/svx/svdedtv.hxx        |    2 
 include/svx/svdobj.hxx         |    3 
 include/svx/svdograf.hxx       |    2 
 svx/inc/globlmn_tmpl.hrc       |    5 +
 svx/source/svdraw/svddrgmt.cxx |  171 ++++++++++++++++++++++++++++++++++++++++-
 svx/source/svdraw/svddrgv.cxx  |    2 
 svx/source/svdraw/svdedtv.cxx  |   12 ++
 svx/source/svdraw/svdmrkv.cxx  |   12 +-
 svx/source/svdraw/svdobj.cxx   |   19 ++++
 9 files changed, 215 insertions(+), 13 deletions(-)

New commits:
commit 80a38d299133823e93ec5c29e8fe5c51771940d5
Author: Philippe Jung <phil.jung at free.fr>
Date:   Fri May 1 23:32:00 2015 +0200

    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 at libreoffice.org>
    Reviewed-by: Jan Holesovsky <kendy at collabora.com>
    Tested-by: Jan Holesovsky <kendy at collabora.com>

diff --git a/include/svx/svdedtv.hxx b/include/svx/svdedtv.hxx
index c22074b..cdc2308 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 de32cf0..d7f71d5 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 29499a1..c0becce 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 b53f23a..ae6953d 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 c68b62a..884a05f 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 abcda08..2f083a0 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 8984e94..c9a567a 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 d8efa35..808f432 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 edea773..59c8625 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) {


More information about the Libreoffice-commits mailing list