From a42b0985c7619efdc934bb1cf19e5e2c2b6faea2 Mon Sep 17 00:00:00 2001 From: Armin Le Grand Date: Fri, 22 Sep 2017 15:28:33 +0200 Subject: RotGrfFlyFrame: Initial adaptions To allow free rotation of Graphic FlyFrames in Writer, several adaptions are necessary. This change takes care of all needed changes to internally support a freely definable rotation angle for that case. Save/Load round trip is working, the graphic does no longer get modified and added in 90-degree-changed state to the object, the original will be preserved. Support for needed slot in core/ui is implemented. Rotation can be applied from Menus/Toolbars in the known 90/180 degree steps. Added a slot/Button/command to reset rotation in these cases. Added support in Sidebar to rotate using the rotation wheel and/or numeric field. These fields and support added to Image TabPage, too, fully functional. Missing now is a solution for displaying the rotated Graphic. For now, it just gets rotated, but this will not be the final state of this change. Change-Id: I6f3b85ebb5be2b4ad3311c536d54f27a37a494e7 RotGrfFlyFrame: Linux build adaptions Change-Id: I365287ecd6525b1972e8436d61332f7121d88649 --- sw/source/uibase/shells/grfsh.cxx | 150 ++++++++++++++++++++------------------ 1 file changed, 79 insertions(+), 71 deletions(-) (limited to 'sw/source/uibase/shells/grfsh.cxx') diff --git a/sw/source/uibase/shells/grfsh.cxx b/sw/source/uibase/shells/grfsh.cxx index dafb8d4b643b..7b2e034ae670 100644 --- a/sw/source/uibase/shells/grfsh.cxx +++ b/sw/source/uibase/shells/grfsh.cxx @@ -68,7 +68,7 @@ #include #include #include - +//#include #include #define SwGrfShell @@ -259,15 +259,17 @@ void SwGrfShell::Execute(SfxRequest &rReq) SID_DOCFRAME, SID_DOCFRAME, SID_REFERER, SID_REFERER, SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER, - SID_ATTR_PAGE_SIZE, SID_ATTR_PAGE_SIZE, + SID_ATTR_PAGE_SIZE, SID_ATTR_PAGE_SIZE, // 10051 + // RotGrfFlyFrame: Need RotationAngle now + SID_ATTR_TRANSFORM_ANGLE, SID_ATTR_TRANSFORM_ANGLE, // 10095 // Items to hand over XPropertyList things like // XColorList, XHatchList, XGradientList, and XBitmapList to // the Area TabPage: - SID_COLOR_TABLE, SID_PATTERN_LIST, - SID_HTML_MODE, SID_HTML_MODE, - SID_ATTR_GRAF_KEEP_ZOOM, SID_ATTR_GRAF_KEEP_ZOOM, - SID_ATTR_GRAF_FRMSIZE, SID_ATTR_GRAF_GRAPHIC, - // contains SID_ATTR_GRAF_FRMSIZE_PERCENT + SID_COLOR_TABLE, SID_PATTERN_LIST, //10179 + SID_HTML_MODE, SID_HTML_MODE, //10414 + SID_ATTR_GRAF_KEEP_ZOOM, SID_ATTR_GRAF_KEEP_ZOOM, //10882 + SID_ATTR_GRAF_FRMSIZE, SID_ATTR_GRAF_GRAPHIC, // 10884 + // contains SID_ATTR_GRAF_FRMSIZE_PERCENT FN_GET_PRINT_AREA, FN_GET_PRINT_AREA, FN_PARAM_GRF_CONNECT, FN_PARAM_GRF_CONNECT, FN_PARAM_GRF_DIALOG, FN_PARAM_GRF_DIALOG, @@ -375,6 +377,19 @@ void SwGrfShell::Execute(SfxRequest &rReq) SfxStringItem(SID_REFERER, sh->GetMedium()->GetName())); } + Size aUnrotatedSize; + sal_uInt16 nCurrentRotation(0); + { // RotGrfFlyFrame: Add current RotationAngle value, convert from + // RES_GRFATR_ROTATION to SID_ATTR_TRANSFORM_ANGLE. Do not forget to + // convert from 10th degrees to 100th degrees + SfxItemSet aTmpSet( rSh.GetAttrPool(), svl::Items{} ); + rSh.GetCurAttr( aTmpSet ); + const SwRotationGrf& rRotation = static_cast(aTmpSet.Get(RES_GRFATR_ROTATION)); + nCurrentRotation = rRotation.GetValue(); + aUnrotatedSize = rRotation.GetUnrotatedSize(); + aSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ANGLE, nCurrentRotation * 10)); + } + SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); OSL_ENSURE(pFact, "no dialog factory!"); ScopedVclPtr pDlg(pFact->CreateFrameTabDialog("PictureDialog", @@ -489,6 +504,15 @@ void SwGrfShell::Execute(SfxRequest &rReq) FN_UNO_DESCRIPTION, true, &pItem )) rSh.SetObjDescription( static_cast(pItem)->GetValue() ); + // RotGrfFlyFrame: Get and process evtl. changed RotationAngle + if ( SfxItemState::SET == pSet->GetItemState(SID_ATTR_TRANSFORM_ANGLE, false, &pItem )) + { + const sal_uInt32 aNewRotation((static_cast(pItem)->GetValue() / 10) % 3600); + + // RotGrfFlyFrame: Possible rotation change here, SwFlyFrameAttrMgr aMgr is available + aMgr.SetRotation(nCurrentRotation, aNewRotation, aUnrotatedSize); + } + SfxItemSet aGrfSet( rSh.GetAttrPool(), svl::Items{} ); aGrfSet.Put( *pSet ); @@ -868,9 +892,14 @@ void SwGrfShell::GetAttrState(SfxItemSet &rSet) void SwGrfShell::ExecuteRotation(SfxRequest const &rReq) { - sal_uInt16 aRotation; - + // RotGrfFlyFrame: Modify rotation attribute instead of manipulating the graphic SwWrtShell& rShell = GetShell(); + SfxItemSet aSet( rShell.GetAttrPool(), svl::Items< + RES_GRFATR_ROTATION, RES_GRFATR_ROTATION, + SID_ATTR_TRANSFORM_ANGLE, SID_ATTR_TRANSFORM_ANGLE>{} ); + rShell.GetCurAttr( aSet ); + const SwRotationGrf& rRotation = static_cast(aSet.Get(RES_GRFATR_ROTATION)); + sal_uInt16 aRotation(0); if (rReq.GetSlot() == SID_ROTATE_GRAPHIC_LEFT) { @@ -884,59 +913,26 @@ void SwGrfShell::ExecuteRotation(SfxRequest const &rReq) { aRotation = 1800; } - else - { - return; - } - - rShell.StartAllAction(); - rShell.StartUndo(SwUndoId::START); - Graphic aGraphic = *rShell.GetGraphic(); - GraphicNativeTransform aTransform(aGraphic); - aTransform.rotate(aRotation); - rShell.ReRead(OUString(), OUString(), const_cast(&aGraphic)); + if (rReq.GetSlot() == SID_ROTATE_GRAPHIC_RESET || 0 != aRotation) + { + rShell.StartAllAction(); + rShell.StartUndo(SwUndoId::START); - SwFlyFrameAttrMgr aManager(false, &rShell, rShell.IsFrameSelected() ? Frmmgr_Type::NONE : Frmmgr_Type::GRF); + if (rReq.GetSlot() == SID_ROTATE_GRAPHIC_RESET) + { + rShell.SetAttrItem(SwRotationGrf(0, rRotation.GetUnrotatedSize())); + } + else if(0 != aRotation) + { + sal_uInt16 aNewRotation((aRotation + rRotation.GetValue()) % 3600); - long nRotatedWidth = aManager.GetSize().Height(); - long nRotatedHeight = aManager.GetSize().Width(); - if (rReq.GetSlot() == SID_ROTATE_GRAPHIC_180) - std::swap(nRotatedWidth, nRotatedHeight); - Size aSize(nRotatedWidth, nRotatedHeight); - aManager.SetSize(aSize); - aManager.UpdateFlyFrame(); - SfxItemSet aSet( rShell.GetAttrPool(), svl::Items{} ); - rShell.GetCurAttr( aSet ); - SwCropGrf aCrop( static_cast( aSet.Get(RES_GRFATR_CROPGRF) ) ); - tools::Rectangle aCropRectangle(aCrop.GetLeft(), aCrop.GetTop(), aCrop.GetRight(), aCrop.GetBottom()); + rShell.SetAttrItem(SwRotationGrf(aNewRotation, rRotation.GetUnrotatedSize())); + } - if (rReq.GetSlot() == SID_ROTATE_GRAPHIC_LEFT) - { - aCrop.SetLeft( aCropRectangle.Top() ); - aCrop.SetTop( aCropRectangle.Right() ); - aCrop.SetRight( aCropRectangle.Bottom() ); - aCrop.SetBottom( aCropRectangle.Left() ); - } - else if (rReq.GetSlot() == SID_ROTATE_GRAPHIC_RIGHT) - { - aCrop.SetLeft( aCropRectangle.Bottom() ); - aCrop.SetTop( aCropRectangle.Left() ); - aCrop.SetRight( aCropRectangle.Top() ); - aCrop.SetBottom( aCropRectangle.Right() ); - } - else if (rReq.GetSlot() == SID_ROTATE_GRAPHIC_180) - { - aCrop.SetLeft( aCropRectangle.Right() ); - aCrop.SetTop( aCropRectangle.Bottom() ); - aCrop.SetRight( aCropRectangle.Left() ); - aCrop.SetBottom( aCropRectangle.Top() ); + rShell.EndUndo(SwUndoId::END); + rShell.EndAllAction(); } - - rShell.SetAttrItem(aCrop); - - rShell.EndUndo(SwUndoId::END); - rShell.EndAllAction(); } void SwGrfShell::GetAttrStateForRotation(SfxItemSet &rSet) @@ -953,25 +949,37 @@ void SwGrfShell::GetAttrStateForRotation(SfxItemSet &rSet) bool bDisable = bIsParentContentProtected; switch( nWhich ) { - case SID_ROTATE_GRAPHIC_LEFT: - case SID_ROTATE_GRAPHIC_RIGHT: - case SID_ROTATE_GRAPHIC_180: - if( rShell.GetGraphicType() == GraphicType::NONE ) - { - bDisable = true; - } - else + case SID_ROTATE_GRAPHIC_LEFT: + case SID_ROTATE_GRAPHIC_RIGHT: + case SID_ROTATE_GRAPHIC_180: { - Graphic aGraphic = *rShell.GetGraphic(); - GraphicNativeTransform aTransform(aGraphic); - if (!aTransform.canBeRotated()) + if( rShell.GetGraphicType() == GraphicType::NONE ) { bDisable = true; } + break; } - break; - default: - bDisable = false; + case SID_ROTATE_GRAPHIC_RESET: + { + // RotGrfFlyFrame: disable when already no rotation + SfxItemSet aSet( rShell.GetAttrPool(), svl::Items{} ); + rShell.GetCurAttr( aSet ); + const SwRotationGrf& rRotation = static_cast(aSet.Get(RES_GRFATR_ROTATION)); + bDisable = (0 == rRotation.GetValue()); + break; + } + case SID_ATTR_TRANSFORM_ANGLE: + { + // RotGrfFlyFrame: get rotation value from RES_GRFATR_ROTATION and copy to rSet as + // SID_ATTR_TRANSFORM_ANGLE, convert from 10th degrees to 100th degrees + SfxItemSet aSet( rShell.GetAttrPool(), svl::Items{} ); + rShell.GetCurAttr( aSet ); + const SwRotationGrf& rRotation = static_cast(aSet.Get(RES_GRFATR_ROTATION)); + rSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ANGLE, rRotation.GetValue() * 10)); + break; + } + default: + bDisable = false; } if( bDisable ) -- cgit