From fc4ab8cf4ad74fb8b84ca94800802c47d7efc2ff Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Mon, 20 Jun 2022 09:46:44 +0200 Subject: sd theme: consider accent1 color when inserting shape with solid fill Once a theme is defined for the master page of the current slide, PowerPoint inserts a shapes with their fill color & line color set based on that theme (so this color is master-page-specific), while Impress sets the fill & line color based on the default shape style. The Impress behavior has the benefit of doing the usual style-based formatting, but now a document-level style overwrites a (master-)slide-specific theme, which is inconsistent. Fix the problem by extending sd::FuConstruct::SetStyleSheet(): if we construct a shape with fill, then not only apply the style sheet, but also set the fill & line color based on the theme (if there is any). Note that this works both in case the shape is instantly created on click (LOK case) or when the user first draws a top-left -> bottom-right point pair to define the position / size of the shape. At the same time line colors don't support themes yet, so that color is just a plain value for now. (cherry picked from commit 486810603fb3f84847bb549004ed0394a2e22d0b) Conflicts: sd/qa/unit/uiimpress.cxx Change-Id: Ic6ae8f91bd719bd80f2b56f12b001d29b0961e6e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136749 Tested-by: Jenkins CollaboraOffice Reviewed-by: Miklos Vajna --- include/svx/ColorSets.hxx | 19 +++++++++++++++++++ sd/qa/unit/uiimpress.cxx | 40 ++++++++++++++++++++++++++++++++++++++++ sd/source/ui/func/fuconstr.cxx | 39 +++++++++++++++++++++++++++++++++++++++ sd/source/ui/view/drviewse.cxx | 5 +++++ svx/sdi/svx.sdi | 2 +- svx/source/styles/ColorSets.cxx | 10 ++++++++++ 6 files changed, 114 insertions(+), 1 deletion(-) diff --git a/include/svx/ColorSets.hxx b/include/svx/ColorSets.hxx index ac9008cbeb32..6ad59a50c064 100644 --- a/include/svx/ColorSets.hxx +++ b/include/svx/ColorSets.hxx @@ -69,6 +69,23 @@ public: const ColorSet& getColorSet(std::u16string_view rName); }; +/// Offsets into the color list of a theme. +enum class ThemeColorType +{ + DK1 = 0, + LT1 = 1, + DK2 = 2, + LT2 = 3, + ACCENT1 = 4, + ACCENT2 = 5, + ACCENT3 = 6, + ACCENT4 = 7, + ACCENT5 = 8, + ACCENT6 = 9, + HLINK = 10, + FOLHLINK = 11, +}; + /// A named theme has a named color set. class SVXCORE_DLLPUBLIC Theme { @@ -94,6 +111,8 @@ public: void UpdateSdrPage(SdrPage* pPage); std::vector GetColors() const; + + Color GetColor(ThemeColorType eType) const; }; } // end of namespace svx diff --git a/sd/qa/unit/uiimpress.cxx b/sd/qa/unit/uiimpress.cxx index 283753f339c8..9b58251ffc93 100644 --- a/sd/qa/unit/uiimpress.cxx +++ b/sd/qa/unit/uiimpress.cxx @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include #include @@ -44,6 +46,7 @@ #include #include #include +#include #include #include @@ -957,6 +960,43 @@ CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testFillColorTheme) CPPUNIT_ASSERT_EQUAL(static_cast(6000), nFillColorLumOff); } +CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testThemeShapeInsert) +{ + // Given a document with a theme, accent1 color is set to 0x000004: + mxComponent = loadFromDesktop("private:factory/simpress", + "com.sun.star.presentation.PresentationDocument"); + uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), + uno::UNO_QUERY); + uno::Reference xMasterPageTarget(xDrawPage, uno::UNO_QUERY); + uno::Reference xMasterPage(xMasterPageTarget->getMasterPage(), + uno::UNO_QUERY); + comphelper::SequenceAsHashMap aMap; + aMap["Name"] <<= OUString("mytheme"); + aMap["ColorSchemeName"] <<= OUString("mycolorscheme"); + uno::Sequence aColorScheme + = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb }; + aMap["ColorScheme"] <<= aColorScheme; + uno::Any aTheme(aMap.getAsConstPropertyValueList()); + xMasterPage->setPropertyValue("Theme", aTheme); + + // When inserting a shape: + uno::Sequence aArgs = { + comphelper::makePropertyValue("CreateDirectly", true), + }; + dispatchCommand(mxComponent, ".uno:BasicShapes.round-rectangle", aArgs); + + // Then make sure the that fill color of the last shape is the accent1 color: + sal_Int32 nShapeIndex = xDrawPage->getCount() - 1; + uno::Reference xShape(xDrawPage->getByIndex(nShapeIndex), uno::UNO_QUERY); + sal_Int32 nFillColor{}; + xShape->getPropertyValue("FillColor") >>= nFillColor; + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 0 / 0x000004 (~black) + // - Actual : 7512015 / 0x729fcf (~blue) + CPPUNIT_ASSERT_EQUAL(static_cast(0x4), nFillColor); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/func/fuconstr.cxx b/sd/source/ui/func/fuconstr.cxx index ca248d808840..6a3ab78e7f4c 100644 --- a/sd/source/ui/func/fuconstr.cxx +++ b/sd/source/ui/func/fuconstr.cxx @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #include #include @@ -367,6 +370,42 @@ void FuConstruct::SetStyleSheet( SfxItemSet& rAttr, SdrObject* pObj, pObj->SetMergedItemSet(aAttr); } } + else + { + // Creating an object with fill. + SdrPage* pThemePage = pPage; + if (pThemePage->TRG_HasMasterPage()) + { + pThemePage = &pThemePage->TRG_GetMasterPage(); + } + + svx::Theme* pTheme = pThemePage->getSdrPageProperties().GetTheme(); + if (pTheme) + { + // We construct an object on a page where the master page has a theme. Take the + // accent1 color from that theme, make sure it has priority over the shape's + // document-global style. + SfxItemSet aAttr(mpView->GetDefaultAttr()); + + aAttr.Put(XFillStyleItem(css::drawing::FillStyle_SOLID)); + + svx::ThemeColorType eColorType = svx::ThemeColorType::ACCENT1; + Color aColor = pTheme->GetColor(eColorType); + XFillColorItem aFillColorItem("", aColor); + aFillColorItem.GetThemeColor().SetThemeIndex(static_cast(eColorType)); + aAttr.Put(aFillColorItem); + + aAttr.Put(XLineStyleItem(css::drawing::LineStyle_SOLID)); + + // Line color is 50% darker than the fill color. + aColor.ApplyTintOrShade(-5000); + XLineColorItem aLineColorItem("", aColor); + // TODO no theme or theme effect for line colors yet. + aAttr.Put(aLineColorItem); + + pObj->SetMergedItemSet(aAttr); + } + } } } diff --git a/sd/source/ui/view/drviewse.cxx b/sd/source/ui/view/drviewse.cxx index 429ae789856f..b90d10ce25dd 100644 --- a/sd/source/ui/view/drviewse.cxx +++ b/sd/source/ui/view/drviewse.cxx @@ -525,6 +525,11 @@ void DrawViewShell::FuPermanent(SfxRequest& rReq) rReq.Done(); bCreateDirectly = comphelper::LibreOfficeKit::isActive(); + const SfxItemSet* pArgs = rReq.GetArgs(); + if (pArgs && pArgs->HasItem(FN_PARAM_1)) + { + bCreateDirectly = static_cast(pArgs->Get(FN_PARAM_1)).GetValue(); + } if ( nSId != SID_DRAW_CS_ID ) { diff --git a/svx/sdi/svx.sdi b/svx/sdi/svx.sdi index f415e2522bd0..9ab00de7e881 100644 --- a/svx/sdi/svx.sdi +++ b/svx/sdi/svx.sdi @@ -10458,7 +10458,7 @@ SfxVoidItem SbaBrwInsert SID_SBA_BRW_INSERT SfxStringItem BasicShapes SID_DRAWTBX_CS_BASIC -(SfxStringItem BasicShapes SID_DRAWTBX_CS_BASIC) +(SfxStringItem BasicShapes SID_DRAWTBX_CS_BASIC, SfxBoolItem CreateDirectly FN_PARAM_1) [ AutoUpdate = TRUE, FastCall = FALSE, diff --git a/svx/source/styles/ColorSets.cxx b/svx/source/styles/ColorSets.cxx index 895ae91c8e47..88284249fc67 100644 --- a/svx/source/styles/ColorSets.cxx +++ b/svx/source/styles/ColorSets.cxx @@ -362,6 +362,16 @@ std::vector Theme::GetColors() const return aColors; } +Color Theme::GetColor(ThemeColorType eType) const +{ + if (!mpColorSet) + { + return {}; + } + + return mpColorSet->getColor(static_cast(eType)); +} + } // end of namespace svx /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit