diff options
author | Armin Le Grand <Armin.Le.Grand@cib.de> | 2017-10-04 17:44:24 +0200 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@cib.de> | 2017-10-20 14:13:24 +0200 |
commit | 9743ecb42095b6e742ab7636ccc67b820f8b9fee (patch) | |
tree | 75d5949861bd9974ffe6acbc0805b501c76dd2fc | |
parent | RotGrfFlyFrame: Corrected position for CropHandles (diff) | |
download | core-9743ecb42095b6e742ab7636ccc67b820f8b9fee.tar.gz core-9743ecb42095b6e742ab7636ccc67b820f8b9fee.zip |
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
-rw-r--r-- | basegfx/source/matrix/b2dhommatrixtools.cxx | 3 | ||||
-rw-r--r-- | include/svx/svdobj.hxx | 4 | ||||
-rw-r--r-- | include/svx/svdovirt.hxx | 3 | ||||
-rw-r--r-- | include/svx/svxids.hrc | 2 | ||||
-rw-r--r-- | svx/source/svdraw/svddrgmt.cxx | 18 | ||||
-rw-r--r-- | svx/source/svdraw/svdmrkv.cxx | 79 | ||||
-rw-r--r-- | svx/source/svdraw/svdobj.cxx | 6 | ||||
-rw-r--r-- | svx/source/svdraw/svdovirt.cxx | 6 | ||||
-rw-r--r-- | sw/inc/fesh.hxx | 3 | ||||
-rw-r--r-- | sw/sdi/grfsh.sdi | 9 | ||||
-rw-r--r-- | sw/source/core/draw/dflyobj.cxx | 95 | ||||
-rw-r--r-- | sw/source/core/draw/dview.cxx | 28 | ||||
-rw-r--r-- | sw/source/core/frmedt/feshview.cxx | 23 | ||||
-rw-r--r-- | sw/source/core/inc/dflyobj.hxx | 8 | ||||
-rw-r--r-- | sw/source/uibase/frmdlg/frmmgr.cxx | 4 | ||||
-rw-r--r-- | sw/source/uibase/shells/grfsh.cxx | 38 | ||||
-rw-r--r-- | sw/uiconfig/swriter/toolbar/graphicobjectbar.xml | 1 |
17 files changed, 281 insertions, 49 deletions
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 d7c995ef552e..7db8e4946abd 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 c73238be62ea..7cd7c2702333 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 0914846b7857..23857b2b4745 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/> |