diff --git a/bsc1178943.diff b/bsc1178943.diff new file mode 100644 index 0000000..148b211 --- /dev/null +++ b/bsc1178943.diff @@ -0,0 +1,312 @@ +From 39a94b9b25ff886ff058e333cb24687cfb4442f1 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 14 Dec 2020 12:15:09 +0100 +Subject: [PATCH] bsc1178943.diff + +This is a combination of 3 commits. +This is the 1st commit message: + +tdf#129961 cui: start UI for table shadow as direct format + +It reads from the doc model and shows it, but doesn't write it back yet. + +(cherry picked from commit 74ba28fe238b7f15d1fb7d119e4cef3a7b544e0b) + +This is the commit message #2: + +tdf#129961 svx: finish UI for table shadow as direct format + +Normally properties on an SdrObject is set using SetAttributes(), but +that would take the selection controller into account, so we would call +SvxTableController::SetAttributes(), which sets the item set on the +selected cells instead. So use SetAttrToMarked() instead, which works on +the shape's item set, even in the table case. Don't replace all existing +items because we only have shadow properties here and also a disabled +shadow is still a (set) SdrOnOffItem (with value=false), so no old +SdrOnOffItem will be forgotten in the shape's item set. + +Also add an outer undo grouping, so once the user presses OK in the +table properties dialog, we only create a single user-visible undo +action, not two. + +(cherry picked from commit fdeb04f7c59cf8032fe17072ed779e70505cc6ab) + +Conflicts: + svx/source/table/tablecontroller.cxx + +This is the commit message #3: + +tdf#129961 oox: add PPTX export for table shadow as direct format + +Custom shapes export shadow as part of WriteShapeEffects(), so use the +same for table shapes as well. + +This needs fixing the effect export up a bit, because table shapes have +no interop grab-bag, glow or soft edge properties, but the rest of the +code can be shared. + +(cherry picked from commit 252cdd5f43d65095543e317d37e1a0ea4fd839e0) + +Conflicts: + oox/qa/unit/drawingml.cxx + +Change-Id: Icf0b90c5b44e3d9c4115c9f3b0d56ba0852ab640 +--- + cui/source/dialogs/sdrcelldlg.cxx | 7 ++++ + cui/source/inc/sdrcelldlg.hxx | 2 + + cui/uiconfig/ui/formatcellsdialog.ui | 48 +++++++++++++++++++++++ + include/svx/sdr/table/tablecontroller.hxx | 1 + + oox/source/export/drawingml.cxx | 13 +++++- + oox/source/export/shapes.cxx | 4 +- + svx/source/table/tablecontroller.cxx | 45 ++++++++++++++++++++- + 7 files changed, 117 insertions(+), 3 deletions(-) + +diff --git a/cui/source/dialogs/sdrcelldlg.cxx b/cui/source/dialogs/sdrcelldlg.cxx +index 3c745692f7ea..fda8b4ce1385 100644 +--- a/cui/source/dialogs/sdrcelldlg.cxx ++++ b/cui/source/dialogs/sdrcelldlg.cxx +@@ -27,6 +27,7 @@ SvxFormatCellsDialog::SvxFormatCellsDialog(weld::Window* pParent, const SfxItemS + : SfxTabDialogController(pParent, "cui/ui/formatcellsdialog.ui", "FormatCellsDialog", pAttr) + , mrOutAttrs(*pAttr) + , mpColorTab(rModel.GetColorList()) ++ , mnColorTabState ( ChangeType::NONE ) + , mpGradientList(rModel.GetGradientList()) + , mpHatchingList(rModel.GetHatchList()) + , mpBitmapList(rModel.GetBitmapList()) +@@ -36,6 +37,7 @@ SvxFormatCellsDialog::SvxFormatCellsDialog(weld::Window* pParent, const SfxItemS + AddTabPage("effects", RID_SVXPAGE_CHAR_EFFECTS); + AddTabPage("border", RID_SVXPAGE_BORDER ); + AddTabPage("area", RID_SVXPAGE_AREA); ++ AddTabPage("shadow", SvxShadowTabPage::Create, nullptr); + } + + void SvxFormatCellsDialog::PageCreated(const OString& rId, SfxTabPage &rPage) +@@ -55,6 +57,11 @@ void SvxFormatCellsDialog::PageCreated(const OString& rId, SfxTabPage &rPage) + SvxBorderTabPage& rBorderPage = static_cast(rPage); + rBorderPage.SetTableMode(); + } ++ else if (rId == "shadow") ++ { ++ static_cast(rPage).SetColorList( mpColorTab ); ++ static_cast(rPage).SetColorChgd( &mnColorTabState ); ++ } + else + SfxTabDialogController::PageCreated(rId, rPage); + } +diff --git a/cui/source/inc/sdrcelldlg.hxx b/cui/source/inc/sdrcelldlg.hxx +index 50ab4b39ac70..9f068d552393 100644 +--- a/cui/source/inc/sdrcelldlg.hxx ++++ b/cui/source/inc/sdrcelldlg.hxx +@@ -23,6 +23,7 @@ + + #include + #include ++#include + + class SdrModel; + class SvxFormatCellsDialog : public SfxTabDialogController +@@ -31,6 +32,7 @@ private: + const SfxItemSet& mrOutAttrs; + + XColorListRef mpColorTab; ++ ChangeType mnColorTabState; + XGradientListRef mpGradientList; + XHatchListRef mpHatchingList; + XBitmapListRef mpBitmapList; +diff --git a/cui/uiconfig/ui/formatcellsdialog.ui b/cui/uiconfig/ui/formatcellsdialog.ui +index 82243f0bad10..49dfc705483c 100644 +--- a/cui/uiconfig/ui/formatcellsdialog.ui ++++ b/cui/uiconfig/ui/formatcellsdialog.ui +@@ -281,6 +281,54 @@ + False + + ++ ++ ++ ++ True ++ False ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ 4 ++ ++ ++ ++ ++ True ++ False ++ Shadow ++ ++ ++ 5 ++ False ++ ++ + + + False +diff --git a/include/svx/sdr/table/tablecontroller.hxx b/include/svx/sdr/table/tablecontroller.hxx +index f34499a05991..3d94dcfb08b7 100644 +--- a/include/svx/sdr/table/tablecontroller.hxx ++++ b/include/svx/sdr/table/tablecontroller.hxx +@@ -85,6 +85,7 @@ public: + + SVX_DLLPRIVATE void MergeAttrFromSelectedCells(SfxItemSet& rAttr, bool bOnlyHardAttr) const; + SVX_DLLPRIVATE void SetAttrToSelectedCells(const SfxItemSet& rAttr, bool bReplaceAll); ++ void SetAttrToSelectedShape(const SfxItemSet& rAttr); + /** Fill the values that are common for all selected cells. + * + * This lets the Borders dialog to display the line arrangement +diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx +index de2d34979471..177cb010d180 100644 +--- a/oox/source/export/drawingml.cxx ++++ b/oox/source/export/drawingml.cxx +@@ -3773,7 +3773,8 @@ static sal_Int32 lcl_CalculateDir(const double dX, const double dY) + void DrawingML::WriteShapeEffects( const Reference< XPropertySet >& rXPropSet ) + { + Sequence< PropertyValue > aGrabBag, aEffects, aOuterShdwProps; +- if( GetProperty( rXPropSet, "InteropGrabBag" ) ) ++ bool bHasInteropGrabBag = rXPropSet->getPropertySetInfo()->hasPropertyByName("InteropGrabBag"); ++ if (bHasInteropGrabBag && GetProperty(rXPropSet, "InteropGrabBag")) + { + mAny >>= aGrabBag; + auto pProp = std::find_if(std::cbegin(aGrabBag), std::cend(aGrabBag), +@@ -3912,6 +3913,11 @@ void DrawingML::WriteShapeEffects( const Reference< XPropertySet >& rXPropSet ) + + void DrawingML::WriteGlowEffect(const Reference< XPropertySet >& rXPropSet) + { ++ if (!rXPropSet->getPropertySetInfo()->hasPropertyByName("GlowEffectRadius")) ++ { ++ return; ++ } ++ + sal_Int32 nRad = 0; + rXPropSet->getPropertyValue("GlowEffectRadius") >>= nRad; + if (!nRad) +@@ -3934,6 +3940,11 @@ void DrawingML::WriteGlowEffect(const Reference< XPropertySet >& rXPropSet) + + void DrawingML::WriteSoftEdgeEffect(const css::uno::Reference& rXPropSet) + { ++ if (!rXPropSet->getPropertySetInfo()->hasPropertyByName("SoftEdgeRadius")) ++ { ++ return; ++ } ++ + sal_Int32 nRad = 0; + rXPropSet->getPropertyValue("SoftEdgeRadius") >>= nRad; + if (!nRad) +diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx +index 6828bc629152..255d7ea55b44 100644 +--- a/oox/source/export/shapes.cxx ++++ b/oox/source/export/shapes.cxx +@@ -1609,7 +1609,9 @@ void ShapeExport::WriteTable( const Reference< XShape >& rXShape ) + if ( xPropSet.is() && ( xPropSet->getPropertyValue( "Model" ) >>= xTable ) ) + { + mpFS->startElementNS(XML_a, XML_tbl); +- mpFS->singleElementNS(XML_a, XML_tblPr); ++ mpFS->startElementNS(XML_a, XML_tblPr); ++ WriteShapeEffects(xPropSet); ++ mpFS->endElementNS(XML_a, XML_tblPr); + + Reference< container::XIndexAccess > xColumns( xTable->getColumns(), UNO_QUERY_THROW ); + Reference< container::XIndexAccess > xRows( xTable->getRows(), UNO_QUERY_THROW ); +diff --git a/svx/source/table/tablecontroller.cxx b/svx/source/table/tablecontroller.cxx +index 9fa0c057565e..003cbd852b20 100644 +--- a/svx/source/table/tablecontroller.cxx ++++ b/svx/source/table/tablecontroller.cxx +@@ -911,6 +911,18 @@ void SvxTableController::onFormatTable(const SfxRequest& rReq) + aNewAttr.Put( aBoxItem ); + aNewAttr.Put( aBoxInfoItem ); + ++ // Fill in shadow properties. ++ const SfxItemSet& rTableItemSet = rTableObj.GetMergedItemSet(); ++ for (sal_uInt16 nWhich = SDRATTR_SHADOW_FIRST; nWhich <= SDRATTR_SHADOW_LAST; ++nWhich) ++ { ++ if (rTableItemSet.GetItemState(nWhich, false) != SfxItemState::SET) ++ { ++ continue; ++ } ++ ++ aNewAttr.Put(rTableItemSet.Get(nWhich)); ++ } ++ + SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); + ScopedVclPtr xDlg( pFact->CreateSvxFormatCellsDialog( + rReq.GetFrameWeld(), +@@ -950,7 +962,26 @@ void SvxTableController::onFormatTable(const SfxRequest& rReq) + if( aNewBoxItem.GetDistance( SvxBoxItemLine::BOTTOM ) != aBoxItem.GetDistance( SvxBoxItemLine::BOTTOM ) ) + aNewSet.Put(makeSdrTextLowerDistItem( aNewBoxItem.GetDistance( SvxBoxItemLine::BOTTOM ) ) ); + +- SetAttrToSelectedCells(aNewSet, false); ++ if (checkTableObject() && mxTable.is()) ++ { ++ // Create a single undo action when applying the result of the dialog. ++ SdrTableObj& rTableObject(*mxTableObj); ++ SdrModel& rSdrModel(rTableObject.getSdrModelFromSdrObject()); ++ bool bUndo = rSdrModel.IsUndoEnabled(); ++ if (bUndo) ++ { ++ rSdrModel.BegUndo(SvxResId(STR_TABLE_NUMFORMAT)); ++ } ++ ++ SetAttrToSelectedCells(aNewSet, false); ++ ++ SetAttrToSelectedShape(aNewSet); ++ ++ if (bUndo) ++ { ++ rSdrModel.EndUndo(); ++ } ++ } + } + } + } +@@ -2664,6 +2695,18 @@ void SvxTableController::SetAttrToSelectedCells(const SfxItemSet& rAttr, bool bR + rModel.EndUndo(); + } + ++void SvxTableController::SetAttrToSelectedShape(const SfxItemSet& rAttr) ++{ ++ if (!checkTableObject() || !mxTable.is()) ++ return; ++ ++ // Filter out non-shadow items from rAttr. ++ SfxItemSet aSet(*rAttr.GetPool(), svl::Items{}); ++ aSet.Put(rAttr); ++ ++ // Set shadow items on the marked shape. ++ mrView.SetAttrToMarked(aSet, /*bReplaceAll=*/false); ++} + + bool SvxTableController::GetAttributes(SfxItemSet& rTargetSet, bool bOnlyHardAttr) const + { +-- +2.26.2 + diff --git a/bsc1178944.diff b/bsc1178944.diff new file mode 100644 index 0000000..4358fbf --- /dev/null +++ b/bsc1178944.diff @@ -0,0 +1,207 @@ +From 0f064c28b4d733b3e1b7bee4515015a40cf3b1cc Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 1 Dec 2020 15:16:13 +0100 +Subject: [PATCH] bsc1178944.diff + +This is a combination of 3 commits. +This is the 1st commit message: + +tdf#129961 svx: add UNO API for table shadow as direct format + +Adding it via a style was working already. + +(cherry picked from commit 55d4c6cfe5bd9b737698c6cd1f28ee8234abb5d0) + +Conflicts: + svx/source/unodraw/unoprov.cxx + +This is the commit message #2: + +tdf#129961 svx: add rendering for table shadow as direct format + +There was already shadow support in +ViewContactOfTableObj::createViewIndependentPrimitive2DSequence(), but +the UNO API and UI could only set the shadow properties on a shape +style, so shadow-as-direct-format is new. + +One difference between the PowerPoint shadow and our shadow is that we +draw shadow for table text as well, while PowerPoint only does it for +the borders / cell fill style. + +This means we're either backwards-compatible or compatible with +PowerPoint. Solve this problem by leaving the style case unchanged, but +render direct formatting like PowerPoint. + +(cherry picked from commit a75bf43a8d6c5dec6dcc86908c142ceec541aa8c) + +Conflicts: + svx/source/sdr/primitive2d/sdrdecompositiontools.cxx + +This is the commit message #3: + +tdf#129961 oox: add PPTX import for table shadow as direct format + +PPTX export and ODP filter is still missing. + +(cherry picked from commit b273e82aaa916b0f6198097dc32740faced73741) + +Conflicts: + oox/qa/unit/drawingml.cxx + +Change-Id: I451b334ada80d9d228b7d7f36b5f26473b575ef6 +--- + oox/source/drawingml/table/tablecontext.cxx | 5 +++ + .../sdr/primitive2d/sdrdecompositiontools.hxx | 3 +- + .../sdr/primitive2d/sdrdecompositiontools.cxx | 5 +-- + svx/source/table/viewcontactoftableobj.cxx | 34 ++++++++++++++++++- + svx/source/unodraw/unoprov.cxx | 1 + + 5 files changed, 44 insertions(+), 4 deletions(-) + +diff --git a/oox/source/drawingml/table/tablecontext.cxx b/oox/source/drawingml/table/tablecontext.cxx +index bbfc94845369..fc2a59c1fa10 100644 +--- a/oox/source/drawingml/table/tablecontext.cxx ++++ b/oox/source/drawingml/table/tablecontext.cxx +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include "../effectpropertiescontext.hxx" + #include + #include + +@@ -66,6 +67,10 @@ TableContext::onCreateContext( ::sal_Int32 aElementToken, const AttributeList& r + rTableStyle = std::make_shared(); + return new TableStyleContext( *this, rAttribs, *rTableStyle ); + } ++ case A_TOKEN( effectLst ): // CT_EffectList ++ { ++ return new EffectPropertiesContext(*this, mpShapePtr->getEffectProperties()); ++ } + case A_TOKEN( tableStyleId ): // ST_Guid + return new oox::drawingml::GuidContext( *this, mrTableProperties.getStyleId() ); + +diff --git a/svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx b/svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx +index e619206303ca..9e8b9fdfe14c 100644 +--- a/svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx ++++ b/svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx +@@ -72,7 +72,8 @@ namespace drawinglayer + Primitive2DContainer SVXCORE_DLLPUBLIC createEmbeddedShadowPrimitive( + const Primitive2DContainer& rContent, + const attribute::SdrShadowAttribute& rShadow, +- const basegfx::B2DHomMatrix& rObjectMatrix = basegfx::B2DHomMatrix()); ++ const basegfx::B2DHomMatrix& rObjectMatrix = basegfx::B2DHomMatrix(), ++ const Primitive2DContainer* pContentForShadow = nullptr); + + Primitive2DContainer SVXCORE_DLLPUBLIC createEmbeddedGlowPrimitive( + const Primitive2DContainer& rContent, +diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx +index 59b38300d375..2ee2bb625e2d 100644 +--- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx ++++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx +@@ -485,7 +485,8 @@ namespace drawinglayer::primitive2d + Primitive2DContainer createEmbeddedShadowPrimitive( + const Primitive2DContainer& rContent, + const attribute::SdrShadowAttribute& rShadow, +- const basegfx::B2DHomMatrix& rObjectMatrix) ++ const basegfx::B2DHomMatrix& rObjectMatrix, ++ const Primitive2DContainer* pContentForShadow) + { + if(!rContent.empty()) + { +@@ -524,7 +525,7 @@ namespace drawinglayer::primitive2d + new ShadowPrimitive2D( + aShadowOffset, + rShadow.getColor(), +- rContent)); ++ (pContentForShadow ? *pContentForShadow : rContent))); + + if(0.0 != rShadow.getTransparence()) + { +diff --git a/svx/source/table/viewcontactoftableobj.cxx b/svx/source/table/viewcontactoftableobj.cxx +index fe6d03f1d900..bd950a02f7fb 100644 +--- a/svx/source/table/viewcontactoftableobj.cxx ++++ b/svx/source/table/viewcontactoftableobj.cxx +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -205,6 +206,7 @@ namespace sdr::contact + // directly to aRetval, Border info to aBorderSequence and added + // later to get the correct overlapping + drawinglayer::primitive2d::Primitive2DContainer aRetval; ++ drawinglayer::primitive2d::Primitive2DContainer aRetvalForShadow; + const sal_Int32 nRowCount(xTable->getRowCount()); + const sal_Int32 nColCount(xTable->getColumnCount()); + const sal_Int32 nAllCount(nRowCount * nColCount); +@@ -317,6 +319,16 @@ namespace sdr::contact + aCellMatrix, aAttribute)); + aRetval.append(xCellReference); + } ++ ++ // Create cell primitive without text. ++ aAttribute ++ = drawinglayer::primitive2d::createNewSdrFillTextAttribute( ++ rCellItemSet, nullptr); ++ const drawinglayer::primitive2d::Primitive2DReference ++ xCellReference( ++ new drawinglayer::primitive2d::SdrCellPrimitive2D( ++ aCellMatrix, aAttribute)); ++ aRetvalForShadow.append(xCellReference); + } + } + } +@@ -364,6 +376,10 @@ namespace sdr::contact + new drawinglayer::primitive2d::TransformPrimitive2D( + aTransform, + aCellBorderPrimitives)); ++ ++ // Borders are always the same for shadow as well. ++ aRetvalForShadow.append(new drawinglayer::primitive2d::TransformPrimitive2D( ++ aTransform, aCellBorderPrimitives)); + } + } + +@@ -376,7 +392,23 @@ namespace sdr::contact + + if(!aNewShadowAttribute.isDefault()) + { +- aRetval = drawinglayer::primitive2d::createEmbeddedShadowPrimitive(aRetval, aNewShadowAttribute); ++ bool bDirectShadow ++ = rObjectItemSet.Get(SDRATTR_SHADOW, /*bSrchInParent=*/false) ++ .GetValue(); ++ if (bDirectShadow) ++ { ++ // Shadow as direct formatting: no shadow for text, to be compatible ++ // with PowerPoint. ++ basegfx::B2DHomMatrix aMatrix; ++ aRetval = drawinglayer::primitive2d::createEmbeddedShadowPrimitive( ++ aRetval, aNewShadowAttribute, aMatrix, &aRetvalForShadow); ++ } ++ else ++ { ++ // Shadow as style: shadow for text, to be backwards-compatible. ++ aRetval = drawinglayer::primitive2d::createEmbeddedShadowPrimitive( ++ aRetval, aNewShadowAttribute); ++ } + } + } + +diff --git a/svx/source/unodraw/unoprov.cxx b/svx/source/unodraw/unoprov.cxx +index 037c5898b1f3..5ca622ce8d39 100644 +--- a/svx/source/unodraw/unoprov.cxx ++++ b/svx/source/unodraw/unoprov.cxx +@@ -740,6 +740,7 @@ static SfxItemPropertyMapEntry const * ImplGetSvxTableShapePropertyMap() + { + static SfxItemPropertyMapEntry const aTableShapePropertyMap_Impl[] = + { ++ SHADOW_PROPERTIES + { OUString(UNO_NAME_MISC_OBJ_ZORDER), OWN_ATTR_ZORDER, cppu::UnoType::get(), 0, 0}, + { OUString(UNO_NAME_MISC_OBJ_LAYERID), SDRATTR_LAYERID, cppu::UnoType::get(), 0, 0}, + { OUString(UNO_NAME_MISC_OBJ_LAYERNAME), SDRATTR_LAYERNAME, cppu::UnoType::get(), 0, 0}, +-- +2.26.2 + diff --git a/libreoffice.changes b/libreoffice.changes index 6d4cb2b..20c9ca6 100644 --- a/libreoffice.changes +++ b/libreoffice.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Sat Dec 19 21:58:35 UTC 2020 - Andras Timar + +- LO-L3: Shadow effect(s) for table completely missing - part 1 and 2 + * bsc1178944.diff + * bsc1178943.diff + ------------------------------------------------------------------- Fri Nov 27 09:44:55 UTC 2020 - Dominique Leuenberger diff --git a/libreoffice.spec b/libreoffice.spec index 3209939..56bcb35 100644 --- a/libreoffice.spec +++ b/libreoffice.spec @@ -99,6 +99,9 @@ Patch1: scp2-user-config-suse.diff Patch2: nlpsolver-no-broken-help.diff Patch3: mediawiki-no-broken-help.diff Patch4: 0001-Upgrade-liborcus-to-0.16.0.patch +# LO-L3: Shadow effect(s) for table completely missing - part 1 and 2 +Patch5: bsc1178944.diff +Patch6: bsc1178943.diff # try to save space by using hardlinks Patch990: install-with-hardlinks.diff # save time by relying on rpm check rather than doing stupid find+grep @@ -957,6 +960,8 @@ Provides %{langname} translations and additional resources (help files, etc.) fo %patch2 %patch3 %patch4 -p1 +%patch5 -p1 +%patch6 -p1 %patch990 -p1 %patch991 -p1