summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2017-10-04 17:44:24 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2017-10-20 14:13:24 +0200
commit9743ecb42095b6e742ab7636ccc67b820f8b9fee (patch)
tree75d5949861bd9974ffe6acbc0805b501c76dd2fc /sw
parent93f5800e181372d3e5f02c825fd3b09f2756cac7 (diff)
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
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/fesh.hxx3
-rw-r--r--sw/sdi/grfsh.sdi9
-rw-r--r--sw/source/core/draw/dflyobj.cxx95
-rw-r--r--sw/source/core/draw/dview.cxx28
-rw-r--r--sw/source/core/frmedt/feshview.cxx23
-rw-r--r--sw/source/core/inc/dflyobj.hxx8
-rw-r--r--sw/source/uibase/frmdlg/frmmgr.cxx4
-rw-r--r--sw/source/uibase/shells/grfsh.cxx38
-rw-r--r--sw/uiconfig/swriter/toolbar/graphicobjectbar.xml1
9 files changed, 184 insertions, 25 deletions
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/>