Rebased ref, commits from common ancestor: commit 95196bd1977364224103b6ff37383f9f27180993 Author: Armin Le Grand <armin.le.gr...@cib.de> Date: Thu Oct 5 22:00:35 2017 +0200
RotGrfFlyFrame: Clang error fix Change-Id: Ifae68d4d5a17446f01c97ce2e94cd0419217259e diff --git a/sw/source/core/draw/dview.cxx b/sw/source/core/draw/dview.cxx index f437c4274f06..55e05d73e57f 100644 --- a/sw/source/core/draw/dview.cxx +++ b/sw/source/core/draw/dview.cxx @@ -829,11 +829,7 @@ void SwDrawView::CheckPossibilities() pFrame = pFly->GetAnchorFrame(); if ( pFly->Lower() && pFly->Lower()->IsNoTextFrame() ) { - // SwNoTextNode& rNoTNd = const_cast<SwNoTextNode&>(*static_cast<const SwNoTextNode*>((static_cast<const SwContentFrame*>(pFly->Lower()))->GetNode())); - // SwGrfNode* pGrfNd = rNoTNd.GetGrfNode(); - // SwOLENode* pOLENd = rNoTNd.GetOLENode(); - - const SwContentFrame* pCntFr = const_cast<SwContentFrame*>(static_cast<const SwContentFrame*>(pFly->Lower())); + const SwContentFrame* pCntFr(static_cast<const SwContentFrame*>(pFly->Lower())); const SwOLENode* pOLENd = pCntFr->GetNode()->GetOLENode(); const SwGrfNode* pGrfNd = pCntFr->GetNode()->GetGrfNode(); commit d288152b288e5bcd843053c32104509c3cb69235 Author: Armin Le Grand <armin.le.gr...@cib.de> Date: Wed Oct 4 17:44:24 2017 +0200 RotGrfFlyFrame: Added interactive rotation mode The FlyFrames containing a graphic now support an interactive rotation mode. Added a rotation icon to the Toolbar close to right/left 90degree rotation. When activated, works as similar to draw object mode as possible. Shear and move of the rotation center is deactivated since not supported. It uses as much of the existing interaction stuff as possible. Change-Id: Ia1a4e5c064d8576b114c3fcf3a96ccb42c9372bb diff --git a/basegfx/source/matrix/b2dhommatrixtools.cxx b/basegfx/source/matrix/b2dhommatrixtools.cxx index 26936aff2e5c..e26fb922f5b6 100644 --- a/basegfx/source/matrix/b2dhommatrixtools.cxx +++ b/basegfx/source/matrix/b2dhommatrixtools.cxx @@ -364,7 +364,8 @@ namespace basegfx { basegfx::B2DHomMatrix aRetval; - // RotGrfFlyFrame: Take rotation into account. Rotation is in 10th degrees + // RotGrfFlyFrame: Create a transformation that maps the range inside of itself + // so that it fits, takes as much space as possible and keeps the aspect ratio if(0.0 != fRotate) { // Fit rotated graphic to center of available space, keeping page ratio: diff --git a/include/svx/svdobj.hxx b/include/svx/svdobj.hxx index 3d7ded0a7fe9..cd6953312565 100644 --- a/include/svx/svdobj.hxx +++ b/include/svx/svdobj.hxx @@ -410,6 +410,10 @@ public: void SingleObjectPainter(OutputDevice& rOut) const; bool LineGeometryUsageIsNecessary() const; + // RotGrfFlyFrame: If true, this SdrObject supports only limited rotation, that + // means no change of the rotation point (only centered) and no shear allowed + virtual bool HasLimitedRotation() const; + // Returns a copy of the object. Every inherited class must reimplement this (in class Foo // it should be sufficient to do "virtual Foo* Clone() const { return CloneHelper< Foo >(); }". // Note that this function uses operator= internally. diff --git a/include/svx/svdovirt.hxx b/include/svx/svdovirt.hxx index a6223975572d..c6d626e1305f 100644 --- a/include/svx/svdovirt.hxx +++ b/include/svx/svdovirt.hxx @@ -68,6 +68,9 @@ public: virtual OUString TakeObjNameSingul() const override; virtual OUString TakeObjNamePlural() const override; + // RotGrfFlyFrame: If true, this SdrObject supports only limited rotation + virtual bool HasLimitedRotation() const override; + virtual basegfx::B2DPolyPolygon TakeXorPoly() const override; virtual sal_uInt32 GetHdlCount() const override; virtual SdrHdl* GetHdl(sal_uInt32 nHdlNum) const override; diff --git a/include/svx/svxids.hrc b/include/svx/svxids.hrc index 79ebc50726c1..8d0e22a22179 100644 --- a/include/svx/svxids.hrc +++ b/include/svx/svxids.hrc @@ -919,7 +919,7 @@ #define SID_ROTATE_GRAPHIC_LEFT ( SID_SVX_START + 1121 ) #define SID_ROTATE_GRAPHIC_RIGHT ( SID_SVX_START + 1122 ) #define SID_ROTATE_GRAPHIC_180 ( SID_SVX_START + 1123 ) -#define SID_ROTATE_GRAPHIC_RESET ( SID_SVX_START + 1092 ) /* RotGrfFlyFrame: new slot */ +#define SID_ROTATE_GRAPHIC_RESET ( SID_SVX_START + 1092 ) /* RotGrfFlyFrame: */ // new slots for panels #define SID_ATTR_FILL_TRANSPARENCE ( SID_SVX_START + 1124 ) diff --git a/svx/source/svdraw/svddrgmt.cxx b/svx/source/svdraw/svddrgmt.cxx index 3348579bd508..a00528f61af8 100644 --- a/svx/source/svdraw/svddrgmt.cxx +++ b/svx/source/svdraw/svddrgmt.cxx @@ -2097,18 +2097,28 @@ bool SdrDragRotate::BeginSdrDrag() { SdrHdl* pH=GetHdlList().GetHdl(SdrHdlKind::Ref1); - if (pH!=nullptr) + if (nullptr != pH) { Show(); DragStat().Ref1()=pH->GetPos(); nAngle0=GetAngle(DragStat().GetStart()-DragStat().GetRef1()); return true; } - else + + // RotGrfFlyFrame: Support rotation around center *without* Ref1 (normally + // the rotation point) + const tools::Rectangle aLocalMarkRect(getSdrDragView().GetMarkedObjRect()); + + if(!aLocalMarkRect.IsEmpty()) { - OSL_FAIL("SdrDragRotate::BeginSdrDrag(): No reference point handle found."); - return false; + Show(); + DragStat().Ref1() = aLocalMarkRect.Center(); + nAngle0=GetAngle(DragStat().GetStart()-DragStat().GetRef1()); + return true; } + + OSL_FAIL("SdrDragRotate::BeginSdrDrag(): No reference point handle found."); + return false; } basegfx::B2DHomMatrix SdrDragRotate::getCurrentTransformation() diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx index 73a79d4bb983..61286258cc0f 100644 --- a/svx/source/svdraw/svdmrkv.cxx +++ b/svx/source/svdraw/svdmrkv.cxx @@ -658,14 +658,22 @@ void SdrMarkView::SetMarkHandles(SfxViewShell* pOtherShell) const size_t nMarkCount=GetMarkedObjectCount(); bool bStdDrag=meDragMode==SdrDragMode::Move; bool bSingleTextObjMark=false; + bool bLimitedRotation(false); if (nMarkCount==1) { mpMarkedObj=GetMarkedObjectByIndex(0); - bSingleTextObjMark = - mpMarkedObj && - dynamic_cast<const SdrTextObj*>( mpMarkedObj) != nullptr && - static_cast<SdrTextObj*>(mpMarkedObj)->IsTextFrame(); + + if(nullptr != mpMarkedObj) + { + bSingleTextObjMark = + mpMarkedObj && + dynamic_cast<const SdrTextObj*>( mpMarkedObj) != nullptr && + static_cast<SdrTextObj*>(mpMarkedObj)->IsTextFrame(); + + // RotGrfFlyFrame: we may have limited rotation + bLimitedRotation = SdrDragMode::Rotate == meDragMode && mpMarkedObj->HasLimitedRotation(); + } } bool bFrmHdl=ImpIsFrameHandles(); @@ -831,27 +839,59 @@ void SdrMarkView::SetMarkHandles(SfxViewShell* pOtherShell) } else { - bool bWdt0=aRect.Left()==aRect.Right(); - bool bHgt0=aRect.Top()==aRect.Bottom(); + const bool bWdt0(aRect.Left() == aRect.Right()); + const bool bHgt0(aRect.Top() == aRect.Bottom()); + if (bWdt0 && bHgt0) { - maHdlList.AddHdl(new SdrHdl(aRect.TopLeft(),SdrHdlKind::UpperLeft)); + maHdlList.AddHdl(new SdrHdl(aRect.TopLeft(), SdrHdlKind::UpperLeft)); } else if (!bStdDrag && (bWdt0 || bHgt0)) { - maHdlList.AddHdl(new SdrHdl(aRect.TopLeft() ,SdrHdlKind::UpperLeft)); - maHdlList.AddHdl(new SdrHdl(aRect.BottomRight(),SdrHdlKind::LowerRight)); + maHdlList.AddHdl(new SdrHdl(aRect.TopLeft(), SdrHdlKind::UpperLeft)); + maHdlList.AddHdl(new SdrHdl(aRect.BottomRight(), SdrHdlKind::LowerRight)); } else { - if (!bWdt0 && !bHgt0) maHdlList.AddHdl(new SdrHdl(aRect.TopLeft() ,SdrHdlKind::UpperLeft)); - if ( !bHgt0) maHdlList.AddHdl(new SdrHdl(aRect.TopCenter() ,SdrHdlKind::Upper)); - if (!bWdt0 && !bHgt0) maHdlList.AddHdl(new SdrHdl(aRect.TopRight() ,SdrHdlKind::UpperRight)); - if (!bWdt0 ) maHdlList.AddHdl(new SdrHdl(aRect.LeftCenter() ,SdrHdlKind::Left )); - if (!bWdt0 ) maHdlList.AddHdl(new SdrHdl(aRect.RightCenter() ,SdrHdlKind::Right)); - if (!bWdt0 && !bHgt0) maHdlList.AddHdl(new SdrHdl(aRect.BottomLeft() ,SdrHdlKind::LowerLeft)); - if ( !bHgt0) maHdlList.AddHdl(new SdrHdl(aRect.BottomCenter(),SdrHdlKind::Lower)); - if (!bWdt0 && !bHgt0) maHdlList.AddHdl(new SdrHdl(aRect.BottomRight() ,SdrHdlKind::LowerRight)); + if (!bWdt0 && !bHgt0) + { + maHdlList.AddHdl(new SdrHdl(aRect.TopLeft(), SdrHdlKind::UpperLeft)); + } + + if (!bLimitedRotation && !bHgt0) + { + maHdlList.AddHdl(new SdrHdl(aRect.TopCenter(), SdrHdlKind::Upper)); + } + + if (!bWdt0 && !bHgt0) + { + maHdlList.AddHdl(new SdrHdl(aRect.TopRight(), SdrHdlKind::UpperRight)); + } + + if (!bLimitedRotation && !bWdt0) + { + maHdlList.AddHdl(new SdrHdl(aRect.LeftCenter(), SdrHdlKind::Left )); + } + + if (!bLimitedRotation && !bWdt0) + { + maHdlList.AddHdl(new SdrHdl(aRect.RightCenter(), SdrHdlKind::Right)); + } + + if (!bWdt0 && !bHgt0) + { + maHdlList.AddHdl(new SdrHdl(aRect.BottomLeft(), SdrHdlKind::LowerLeft)); + } + + if (!bLimitedRotation && !bHgt0) + { + maHdlList.AddHdl(new SdrHdl(aRect.BottomCenter(), SdrHdlKind::Lower)); + } + + if (!bWdt0 && !bHgt0) + { + maHdlList.AddHdl(new SdrHdl(aRect.BottomRight(), SdrHdlKind::LowerRight)); + } } } } @@ -945,7 +985,10 @@ void SdrMarkView::SetMarkHandles(SfxViewShell* pOtherShell) } // rotation point/axis of reflection - AddDragModeHdl(meDragMode); + if(!bLimitedRotation) + { + AddDragModeHdl(meDragMode); + } // sort handles maHdlList.Sort(); diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx index f5f3f269f866..b2dd3a2fc6c8 100644 --- a/svx/source/svdraw/svdobj.cxx +++ b/svx/source/svdraw/svdobj.cxx @@ -931,6 +931,12 @@ bool SdrObject::LineGeometryUsageIsNecessary() const return (eXLS != drawing::LineStyle_NONE); } +bool SdrObject::HasLimitedRotation() const +{ + // RotGrfFlyFrame: Default is false, support full rotation + return false; +} + SdrObject* SdrObject::Clone() const { return CloneHelper< SdrObject >(); diff --git a/svx/source/svdraw/svdovirt.cxx b/svx/source/svdraw/svdovirt.cxx index 7c9f54e35bd8..d7145be8f93a 100644 --- a/svx/source/svdraw/svdovirt.cxx +++ b/svx/source/svdraw/svdovirt.cxx @@ -166,6 +166,12 @@ OUString SdrVirtObj::TakeObjNamePlural() const return sName.makeStringAndClear(); } +bool SdrVirtObj::HasLimitedRotation() const +{ + // RotGrfFlyFrame: If true, this SdrObject supports only limited rotation + return rRefObj.HasLimitedRotation(); +} + basegfx::B2DPolyPolygon SdrVirtObj::TakeXorPoly() const { basegfx::B2DPolyPolygon aPolyPolygon(rRefObj.TakeXorPoly()); diff --git a/sw/inc/fesh.hxx b/sw/inc/fesh.hxx index 0775d14cd852..1141a4ea9812 100644 --- a/sw/inc/fesh.hxx +++ b/sw/inc/fesh.hxx @@ -505,6 +505,9 @@ public: // Start cropping the selected image void StartCropImage(); + // RotGrfFlyFrame: check if RotationMode is possibe + bool IsRotationOfSwGrfNodePossible() const; + size_t IsObjSelected() const; ///< @return object count, but doesn't count the objects in groups. bool IsObjSelected( const SdrObject& rObj ) const; bool IsObjSameLevelWithMarked(const SdrObject* pObj) const; diff --git a/sw/sdi/grfsh.sdi b/sw/sdi/grfsh.sdi index 956a0c82b443..8451eae60eba 100644 --- a/sw/sdi/grfsh.sdi +++ b/sw/sdi/grfsh.sdi @@ -24,5 +24,14 @@ shell SwGrfShell : SwBaseShell { import TextGraphic; + + // RotGrfFlyFrame: need SID_OBJECT_ROTATE for FlyFrames with graphic + SID_OBJECT_ROTATE + [ + Export = FALSE; + ExecMethod = Execute ; + StateMethod = GetAttrState ; + DisableFlags="SfxDisableFlags::SwOnProtectedCursor"; + ] } diff --git a/sw/source/core/draw/dflyobj.cxx b/sw/source/core/draw/dflyobj.cxx index 6a21d0eb9d71..29e5e4a94715 100644 --- a/sw/source/core/draw/dflyobj.cxx +++ b/sw/source/core/draw/dflyobj.cxx @@ -49,6 +49,7 @@ #include "rootfrm.hxx" #include "wrtsh.hxx" #include <ndgrf.hxx> +#include <frmmgr.hxx> #include <svx/sdr/properties/defaultproperties.hxx> #include <basegfx/range/b2drange.hxx> @@ -354,6 +355,64 @@ basegfx::B2DRange SwVirtFlyDrawObj::getInnerBound() const return aInnerRange; } +bool SwVirtFlyDrawObj::ContainsSwGrfNode() const +{ + // RotGrfFlyFrame: Check if this is a SwGrfNode + const SwFlyFrame* pFlyFrame(GetFlyFrame()); + + if(nullptr != pFlyFrame && pFlyFrame->Lower() && pFlyFrame->Lower()->IsNoTextFrame()) + { + const SwContentFrame* pCntFr(static_cast<const SwContentFrame*>(pFlyFrame->Lower())); + + if(nullptr != pCntFr) + { + const SwGrfNode* pGrfNd(pCntFr->GetNode()->GetGrfNode()); + + return nullptr != pGrfNd; + } + } + + return false; +} + +bool SwVirtFlyDrawObj::HasLimitedRotation() const +{ + // RotGrfFlyFrame: If true, this SdrObject supports only limited rotation. + // This is the case for SwGrfNode instances + return ContainsSwGrfNode(); +} + +void SwVirtFlyDrawObj::Rotate(const Point& rRef, long nAngle, double sn, double cs) +{ + if(ContainsSwGrfNode()) + { + // RotGrfFlyFrame: Here is where the positively completed rotate interaction is executed. + // Rotation is in 1/100th degree and may be signed (!) + nAngle /= 10; + + while(nAngle < 0) + { + nAngle += 3600; + } + + if(0 != nAngle) + { + // RotGrfFlyFrame: Add transformation to placeholder object + Size aSize; + const sal_uInt16 nOldRot(SwVirtFlyDrawObj::getPossibleRotationFromFraphicFrame(aSize)); + SwWrtShell *pSh = dynamic_cast<SwWrtShell*>( GetFlyFrame()->getRootFrame()->GetCurrShell() ); + SwFlyFrameAttrMgr aMgr(false, pSh, Frmmgr_Type::NONE); + + aMgr.SetRotation(nOldRot, (nOldRot + static_cast<sal_uInt16>(nAngle)) % 3600, aSize); + } + } + else + { + // call parent + SdrVirtObj::Rotate(rRef, nAngle, sn, cs); + } +} + sdr::contact::ViewContact* SwVirtFlyDrawObj::CreateObjectSpecificViewContact() { // need an own ViewContact (VC) to allow creation of a specialized primitive @@ -477,7 +536,9 @@ void SwVirtFlyDrawObj::TakeObjInfo( SdrObjTransformInfoRec& rInfo ) const rInfo.bMoveAllowed = rInfo.bResizeFreeAllowed = rInfo.bResizePropAllowed = true; - rInfo.bRotateFreeAllowed = rInfo.bRotate90Allowed = + // RotGrfFlyFrame: Some rotation may be allowed + rInfo.bRotateFreeAllowed = rInfo.bRotate90Allowed = HasLimitedRotation(); + rInfo.bMirrorFreeAllowed = rInfo.bMirror45Allowed = rInfo.bMirror90Allowed = rInfo.bShearAllowed = rInfo.bCanConvToPath = rInfo.bCanConvToPoly = @@ -924,7 +985,7 @@ void SwVirtFlyDrawObj::Crop(const Point& rRef, const Fraction& xFact, const Frac } // RotGrfFlyFrame: Helper to access possible rotation of Graphic contained in FlyFrame -sal_uInt16 SwVirtFlyDrawObj::getPossibleRotationFromFraphicFrame() const +sal_uInt16 SwVirtFlyDrawObj::getPossibleRotationFromFraphicFrame(Size& rSize) const { sal_uInt16 nRetval(0); const SwNoTextFrame* pNoTx = dynamic_cast< const SwNoTextFrame* >(GetFlyFrame()->Lower()); @@ -939,6 +1000,7 @@ sal_uInt16 SwVirtFlyDrawObj::getPossibleRotationFromFraphicFrame() const const SwAttrSet& rSet = pGrfNd->GetSwAttrSet(); const SwRotationGrf& rRotation = rSet.GetRotationGrf(); + rSize = rRotation.GetUnrotatedSize(); nRetval = rRotation.GetValue(); } } @@ -951,25 +1013,19 @@ SdrObject* SwVirtFlyDrawObj::getFullDragClone() const // call parent SdrObject* pRetval = SdrVirtObj::getFullDragClone(); - if(pRetval) + if(pRetval && ContainsSwGrfNode()) { // RotGrfFlyFrame: Add transformation to placeholder object - const sal_uInt16 nRotation(SwVirtFlyDrawObj::getPossibleRotationFromFraphicFrame()); - - if(0 != nRotation) - { - const double fRotate(static_cast< double >(-nRotation) * (M_PI/1800.0)); - const tools::Rectangle aTmpOutRect(GetFlyFrame()->Frame().SVRect()); - const basegfx::B2DRange aTargetRange( - aTmpOutRect.Left(), aTmpOutRect.Top(), - aTmpOutRect.Right(), aTmpOutRect.Bottom()); - const basegfx::B2DHomMatrix aTargetTransform( - basegfx::utils::createRotateAroundCenterKeepAspectRatioStayInsideRange( - aTargetRange, - fRotate)); + Size aSize; + const sal_uInt16 nRotation(SwVirtFlyDrawObj::getPossibleRotationFromFraphicFrame(aSize)); + const double fRotate(static_cast< double >(-nRotation) * (M_PI/1800.0)); + const basegfx::B2DRange aTargetRange(getInnerBound()); + const basegfx::B2DHomMatrix aTargetTransform( + basegfx::utils::createRotateAroundCenterKeepAspectRatioStayInsideRange( + aTargetRange, + fRotate)); - pRetval->TRSetBaseGeometry(aTargetTransform, basegfx::B2DPolyPolygon()); - } + pRetval->TRSetBaseGeometry(aTargetTransform, basegfx::B2DPolyPolygon()); } return pRetval; @@ -987,7 +1043,8 @@ void SwVirtFlyDrawObj::addCropHandles(SdrHdlList& rTarget) const if(!aTargetRange.isEmpty()) { - const sal_uInt16 nRotation(SwVirtFlyDrawObj::getPossibleRotationFromFraphicFrame()); + Size aSize; + const sal_uInt16 nRotation(SwVirtFlyDrawObj::getPossibleRotationFromFraphicFrame(aSize)); const double fRotate(static_cast< double >(-nRotation) * (M_PI/1800.0)); const basegfx::B2DHomMatrix aTargetTransform( basegfx::utils::createRotateAroundCenterKeepAspectRatioStayInsideRange( diff --git a/sw/source/core/draw/dview.cxx b/sw/source/core/draw/dview.cxx index 5bf7304acf39..f437c4274f06 100644 --- a/sw/source/core/draw/dview.cxx +++ b/sw/source/core/draw/dview.cxx @@ -44,6 +44,7 @@ #include "doc.hxx" #include "mdiexp.hxx" #include <ndole.hxx> +#include <ndgrf.hxx> #include <fmtanchr.hxx> #include "shellres.hxx" #include <IDocumentUndoRedo.hxx> @@ -814,6 +815,8 @@ void SwDrawView::CheckPossibilities() const SdrMarkList &rMrkList = GetMarkedObjectList(); bool bProtect = false; bool bSzProtect = false; + bool bRotate(false); + for ( size_t i = 0; !bProtect && i < rMrkList.GetMarkCount(); ++i ) { const SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); @@ -826,10 +829,18 @@ void SwDrawView::CheckPossibilities() pFrame = pFly->GetAnchorFrame(); if ( pFly->Lower() && pFly->Lower()->IsNoTextFrame() ) { - SwOLENode *pNd = const_cast<SwContentFrame*>(static_cast<const SwContentFrame*>(pFly->Lower()))->GetNode()->GetOLENode(); - if ( pNd ) + // SwNoTextNode& rNoTNd = const_cast<SwNoTextNode&>(*static_cast<const SwNoTextNode*>((static_cast<const SwContentFrame*>(pFly->Lower()))->GetNode())); + // SwGrfNode* pGrfNd = rNoTNd.GetGrfNode(); + // SwOLENode* pOLENd = rNoTNd.GetOLENode(); + + const SwContentFrame* pCntFr = const_cast<SwContentFrame*>(static_cast<const SwContentFrame*>(pFly->Lower())); + const SwOLENode* pOLENd = pCntFr->GetNode()->GetOLENode(); + const SwGrfNode* pGrfNd = pCntFr->GetNode()->GetGrfNode(); + + if ( pOLENd ) { - uno::Reference < embed::XEmbeddedObject > xObj = pNd->GetOLEObj().GetOleRef(); + const uno::Reference < embed::XEmbeddedObject > xObj = const_cast< SwOLEObj& >(pOLENd->GetOLEObj()).GetOleRef(); + if ( xObj.is() ) { // --> improvement for the future, when more @@ -847,6 +858,13 @@ void SwDrawView::CheckPossibilities() bMoveProtect = true; } } + else if(pGrfNd) + { + // RotGrfFlyFrame: GraphicNode allows rotation(s). The loop ew are in stops + // as soon as bMoveProtect is set, but since rotation is valid only with + // a single object selected this makes no difference + bRotate = true; + } } } } @@ -874,6 +892,10 @@ void SwDrawView::CheckPossibilities() } bMoveProtect |= bProtect; bResizeProtect |= bProtect || bSzProtect; + + // RotGrfFlyFrame: allow rotation when SwGrfNode is selected and not size protected + bRotateFreeAllowed |= bRotate && !bProtect; + bRotate90Allowed |= bRotateFreeAllowed; } /// replace marked <SwDrawVirtObj>-objects by its reference object for delete marked objects. diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx index 5ed4bdae28a8..27893c02fae6 100644 --- a/sw/source/core/frmedt/feshview.cxx +++ b/sw/source/core/frmedt/feshview.cxx @@ -1161,6 +1161,29 @@ bool SwFEShell::IsObjSelected( const SdrObject& rObj ) const return Imp()->GetDrawView()->IsObjMarked( &rObj ); } +bool SwFEShell::IsRotationOfSwGrfNodePossible() const +{ + // RotGrfFlyFrame: check if RotationMode is possibe + const SdrView *pSdrView = Imp()->GetDrawView(); + + if(pSdrView) + { + const SdrMarkList& rList(pSdrView->GetMarkedObjectList()); + + if(1 == rList.GetMarkCount()) + { + const SwVirtFlyDrawObj* pVirtFlyDraw(dynamic_cast< const SwVirtFlyDrawObj* >(rList.GetMark(0)->GetMarkedSdrObj())); + + if(nullptr != pVirtFlyDraw) + { + return pVirtFlyDraw->ContainsSwGrfNode(); + } + } + } + + return false; +} + bool SwFEShell::IsObjSameLevelWithMarked(const SdrObject* pObj) const { if (pObj) diff --git a/sw/source/core/inc/dflyobj.hxx b/sw/source/core/inc/dflyobj.hxx index 528edc8aff39..8766b7980ebc 100644 --- a/sw/source/core/inc/dflyobj.hxx +++ b/sw/source/core/inc/dflyobj.hxx @@ -60,7 +60,7 @@ private: // RotGrfFlyFrame: Helper to acces sthe rotation angle (in 10th degrees, left-handed) // of a GraphicFrame - sal_uInt16 getPossibleRotationFromFraphicFrame() const; + sal_uInt16 getPossibleRotationFromFraphicFrame(Size& rSize) const; protected: // AW: Need own sdr::contact::ViewContact since AnchorPos from parent is @@ -77,6 +77,8 @@ public: basegfx::B2DRange getOuterBound() const; basegfx::B2DRange getInnerBound() const; + // RotGrfFlyFrame: Check if this is a SwGrfNode + bool ContainsSwGrfNode() const; SwVirtFlyDrawObj(SdrObject& rNew, SwFlyFrame* pFly); virtual ~SwVirtFlyDrawObj() override; @@ -105,6 +107,7 @@ public: const Fraction& yFact, bool bUnsetRelative = true) override; virtual void Crop(const Point& rRef, const Fraction& xFact, const Fraction& yFact) override; virtual void addCropHandles(SdrHdlList& rTarget) const override; + virtual void Rotate(const Point& rRef, long nAngle, double sn, double cs) override; // FullDrag support virtual SdrObject* getFullDragClone() const override; @@ -122,6 +125,9 @@ public: virtual bool HasMacro() const override; virtual SdrObject* CheckMacroHit (const SdrObjMacroHitRec& rRec) const override; virtual Pointer GetMacroPointer (const SdrObjMacroHitRec& rRec) const override; + + // RotGrfFlyFrame: If true, this SdrObject supports only limited rotation. + virtual bool HasLimitedRotation() const override; }; #endif diff --git a/sw/source/uibase/frmdlg/frmmgr.cxx b/sw/source/uibase/frmdlg/frmmgr.cxx index b4956cfae92b..a08f441f948b 100644 --- a/sw/source/uibase/frmdlg/frmmgr.cxx +++ b/sw/source/uibase/frmdlg/frmmgr.cxx @@ -577,9 +577,9 @@ void SwFlyFrameAttrMgr::SetHeightSizeType( SwFrameSize eType ) void SwFlyFrameAttrMgr::SetRotation(sal_uInt16 nOld, sal_uInt16 nNew, const Size& rUnrotatedSize) { // RotGrfFlyFrame: Central handling of real change of rotation here, all adaptions use this. - // Adaption of pos/size may be wanted in the future. Already tried to keep last SIze in + // Adaption of pos/size may be wanted in the future. Already tried to keep last Size in // UnrotatedSize in the SwRotationGrf Item, but this will lead to various problems. Also tried - // to use m_aSet.Put(...) as in other methods (also read methods for Rotation/UnrotatedSize) but + // to use m_aSet.Put(...) as in other methods (also tried read methods for Rotation/UnrotatedSize) but // somehow the needed ID (RES_GRFATR_ROTATION) is *not* in the SfxItemSet of the Frame, so for // now set directly. Undo/Redo is preserved by AttributeChange if(nOld != nNew) diff --git a/sw/source/uibase/shells/grfsh.cxx b/sw/source/uibase/shells/grfsh.cxx index 29251d3dc5b2..01fc01acb9c3 100644 --- a/sw/source/uibase/shells/grfsh.cxx +++ b/sw/source/uibase/shells/grfsh.cxx @@ -123,6 +123,27 @@ void SwGrfShell::Execute(SfxRequest &rReq) sal_uInt16 nSlot = rReq.GetSlot(); switch(nSlot) { + case SID_OBJECT_ROTATE: + { + // RotGrfFlyFrame: start rotation when possible + SdrView* pSdrView = rSh.GetDrawViewWithValidMarkList(); + + if(rSh.IsRotationOfSwGrfNodePossible() && pSdrView->IsRotateAllowed()) + { + if(GetView().IsDrawRotate()) + { + rSh.SetDragMode(SdrDragMode::Move); + } + else + { + rSh.SetDragMode(SdrDragMode::Rotate); + } + + GetView().FlipDrawRotate(); + } + } + break; + case SID_TWAIN_TRANSFER: { GetView().ExecuteScan( rReq ); @@ -721,6 +742,23 @@ void SwGrfShell::GetAttrState(SfxItemSet &rSet) bool bDisable = bParentCntProt; switch( nWhich ) { + case SID_OBJECT_ROTATE: + { + // RotGrfFlyFrame: steer rotation state + const bool bIsRotate(GetView().IsDrawRotate()); + SdrView* pSdrView = rSh.GetDrawViewWithValidMarkList(); + + if(!bIsRotate && !pSdrView->IsRotateAllowed()) + { + rSet.DisableItem(nWhich); + } + else + { + rSet.Put(SfxBoolItem(nWhich, bIsRotate)); + } + + break; + } case SID_INSERT_GRAPHIC: case FN_FORMAT_GRAFIC_DLG: case SID_TWAIN_TRANSFER: diff --git a/sw/uiconfig/swriter/toolbar/graphicobjectbar.xml b/sw/uiconfig/swriter/toolbar/graphicobjectbar.xml index c1ba2219af1b..6494546daebd 100644 --- a/sw/uiconfig/swriter/toolbar/graphicobjectbar.xml +++ b/sw/uiconfig/swriter/toolbar/graphicobjectbar.xml @@ -28,6 +28,7 @@ <toolbar:toolbaritem xlink:href=".uno:FlipHorizontal"/> <toolbar:toolbaritem xlink:href=".uno:RotateLeft"/> <toolbar:toolbaritem xlink:href=".uno:RotateRight"/> + <toolbar:toolbaritem xlink:href=".uno:ToggleObjectRotateMode"/> <toolbar:toolbaritem xlink:href=".uno:Rotate180" toolbar:visible="false"/> <toolbar:toolbaritem xlink:href=".uno:RotateReset" toolbar:visible="false"/> <toolbar:toolbarseparator/> commit 425e7775035ad1945db23aba2e0e2057b2e5179a Author: Armin Le Grand <armin.le.gr...@cib.de> Date: Fri Sep 29 12:35:44 2017 +0200 RotGrfFlyFrame: Corrected position for CropHandles Position was taken from OuterBound FlyFrame, even in current master which is wrong. There can be a distance defined between InnerBound and OuterBound that has to be taken into account Change-Id: Id88f99c0b218bd26fa1daa5e8215eced00c0baa6 diff --git a/sw/source/core/draw/dflyobj.cxx b/sw/source/core/draw/dflyobj.cxx index 358085bd2760..6a21d0eb9d71 100644 --- a/sw/source/core/draw/dflyobj.cxx +++ b/sw/source/core/draw/dflyobj.cxx @@ -48,6 +48,7 @@ #include "pagefrm.hxx" #include "rootfrm.hxx" #include "wrtsh.hxx" +#include <ndgrf.hxx> #include <svx/sdr/properties/defaultproperties.hxx> #include <basegfx/range/b2drange.hxx> @@ -958,10 +959,10 @@ SdrObject* SwVirtFlyDrawObj::getFullDragClone() const if(0 != nRotation) { const double fRotate(static_cast< double >(-nRotation) * (M_PI/1800.0)); - const tools::Rectangle aOutRect(GetFlyFrame()->Frame().SVRect()); + const tools::Rectangle aTmpOutRect(GetFlyFrame()->Frame().SVRect()); const basegfx::B2DRange aTargetRange( - aOutRect.Left(), aOutRect.Top(), - aOutRect.Right(), aOutRect.Bottom()); + aTmpOutRect.Left(), aTmpOutRect.Top(), + aTmpOutRect.Right(), aTmpOutRect.Bottom()); const basegfx::B2DHomMatrix aTargetTransform( basegfx::utils::createRotateAroundCenterKeepAspectRatioStayInsideRange( aTargetRange, @@ -979,10 +980,10 @@ void SwVirtFlyDrawObj::addCropHandles(SdrHdlList& rTarget) const // RotGrfFlyFrame: Adapt to possible rotated Graphic contained in FlyFrame if(GetFlyFrame()->Frame().HasArea()) { - const tools::Rectangle aOutRect(GetFlyFrame()->Frame().SVRect()); - const basegfx::B2DRange aTargetRange( - aOutRect.Left(), aOutRect.Top(), - aOutRect.Right(), aOutRect.Bottom()); + // Use InnerBound, OuterBound (same as GetFlyFrame()->Frame().SVRect()) + // may have a distance to InnerBound which needs to be taken into acocunt. + // The Graphic is mapped to InnerBound, as is the rotated Graphic. + const basegfx::B2DRange aTargetRange(getInnerBound()); if(!aTargetRange.isEmpty()) { diff --git a/sw/uiconfig/swriter/toolbar/graphicobjectbar.xml b/sw/uiconfig/swriter/toolbar/graphicobjectbar.xml index 172d8b4d52b5..c1ba2219af1b 100644 --- a/sw/uiconfig/swriter/toolbar/graphicobjectbar.xml +++ b/sw/uiconfig/swriter/toolbar/graphicobjectbar.xml @@ -29,7 +29,7 @@ <toolbar:toolbaritem xlink:href=".uno:RotateLeft"/> <toolbar:toolbaritem xlink:href=".uno:RotateRight"/> <toolbar:toolbaritem xlink:href=".uno:Rotate180" toolbar:visible="false"/> - <toolbar:toolbaritem xlink:href=".uno:RotateReset"/> + <toolbar:toolbaritem xlink:href=".uno:RotateReset" toolbar:visible="false"/> <toolbar:toolbarseparator/> <toolbar:toolbaritem xlink:href=".uno:GrafTransparence"/> <toolbar:toolbarseparator/> diff --git a/sw/uiconfig/swxform/toolbar/graphicobjectbar.xml b/sw/uiconfig/swxform/toolbar/graphicobjectbar.xml index 6e2c6a2b4823..19662053bc76 100644 --- a/sw/uiconfig/swxform/toolbar/graphicobjectbar.xml +++ b/sw/uiconfig/swxform/toolbar/graphicobjectbar.xml @@ -30,8 +30,8 @@ <toolbar:toolbaritem xlink:href=".uno:FlipHorizontal"/> <toolbar:toolbaritem xlink:href=".uno:RotateLeft"/> <toolbar:toolbaritem xlink:href=".uno:RotateRight"/> - <toolbar:toolbaritem xlink:href=".uno:Rotate180"/> - <toolbar:toolbaritem xlink:href=".uno:RotateReset"/> + <toolbar:toolbaritem xlink:href=".uno:Rotate180" toolbar:visible="false"/> + <toolbar:toolbaritem xlink:href=".uno:RotateReset" toolbar:visible="false"/> <toolbar:toolbaritem xlink:href=".uno:Crop"/> <toolbar:toolbarseparator/> <toolbar:toolbaritem xlink:href=".uno:FrameDialog"/> _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits