sc/qa/unit/ucalc_DocumentThemes.cxx | 221 ++++++++++++++++++++++++++++--- sc/source/ui/theme/ThemeColorChanger.cxx | 10 - 2 files changed, 210 insertions(+), 21 deletions(-)
New commits: commit 879dff321cd34b36a12cad84dc748ba5c290cab6 Author: Tomaž Vajngerl <[email protected]> AuthorDate: Tue Nov 25 00:09:02 2025 +0900 Commit: Miklos Vajna <[email protected]> CommitDate: Fri Dec 5 11:57:52 2025 +0100 sc: fix changing of borders and invalidation after change When changing the theme and the ThemeColorChanger was run it would not change the borders if only top, left and bottom border lines would be set and not the right border line. This would not work because the wrong variable to check if we introduced any change for the borders would be used (bChanged and not bLineChanged). This fixes the problem and adds a test for borders and this specific scenario. It also fixes invalidation after changing the theme colors. Change-Id: Ia0529f70cdd37d1007ec1171d3debbb0f8a58bb2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194451 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <[email protected]> Code-Style: Tomaž Vajngerl <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195044 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/sc/qa/unit/ucalc_DocumentThemes.cxx b/sc/qa/unit/ucalc_DocumentThemes.cxx index 83878d02186d..918e9e09754c 100644 --- a/sc/qa/unit/ucalc_DocumentThemes.cxx +++ b/sc/qa/unit/ucalc_DocumentThemes.cxx @@ -12,6 +12,7 @@ #include <docmodel/theme/Theme.hxx> #include <editeng/brushitem.hxx> #include <editeng/colritem.hxx> +#include <editeng/borderline.hxx> #include <patattr.hxx> #include <scitems.hxx> @@ -37,22 +38,51 @@ CPPUNIT_TEST_FIXTURE(DocumentThemesTest, testGetTheme) CPPUNIT_ASSERT(pTheme); } +std::shared_ptr<model::ColorSet> createTestTheme() +{ + auto pColorSet = std::make_shared<model::ColorSet>("TestColorScheme"); + pColorSet->add(model::ThemeColorType::Dark1, 0x000000); + pColorSet->add(model::ThemeColorType::Light1, 0x111111); + pColorSet->add(model::ThemeColorType::Dark2, 0x222222); + pColorSet->add(model::ThemeColorType::Light2, 0x333333); + pColorSet->add(model::ThemeColorType::Accent1, 0x444444); + pColorSet->add(model::ThemeColorType::Accent2, 0x555555); + pColorSet->add(model::ThemeColorType::Accent3, 0x666666); + pColorSet->add(model::ThemeColorType::Accent4, 0x777777); + pColorSet->add(model::ThemeColorType::Accent5, 0x888888); + pColorSet->add(model::ThemeColorType::Accent6, 0x999999); + pColorSet->add(model::ThemeColorType::Hyperlink, 0xaaaaaa); + pColorSet->add(model::ThemeColorType::FollowedHyperlink, 0xbbbbbb); + return pColorSet; +} + CPPUNIT_TEST_FIXTURE(DocumentThemesTest, testChangeTheme) { m_pDoc->InitDrawLayer(); m_pDoc->InsertTab(0, u"Test"_ustr); + // Get the theme and some constants ScDrawLayer* pDrawLayer = m_pDoc->GetDrawLayer(); CPPUNIT_ASSERT(pDrawLayer); auto const& pTheme = pDrawLayer->getTheme(); CPPUNIT_ASSERT(pTheme); - Color aBackgroundThemeColor(0xc99c00); - Color aCellTextThemeColor(0x0369a3); + const Color aBackgroundThemeColor(0xc99c00); + const auto eBackgroundThemeType = model::ThemeColorType::Accent5; + + const Color aCellTextThemeColor(0x0369a3); + const auto eCellTextThemeType = model::ThemeColorType::Accent2; - auto eBackgroundThemeType = model::ThemeColorType::Accent5; - auto eCellTextThemeType = model::ThemeColorType::Accent2; + const Color aCellBorderLeftThemeColor(0x18a303); + const Color aCellBorderRightThemeColor(0xa33e03); + const Color aCellBorderTopThemeColor(0x8e03a3); + const Color aCellBorderBottomThemeColor(0xc9211e); + const auto eCellBorderLeftThemeType = model::ThemeColorType::Accent1; + const auto eCellBorderRightThemeType = model::ThemeColorType::Accent3; + const auto eCellBorderTopThemeType = model::ThemeColorType::Accent4; + const auto eCellBorderBottomThemeType = model::ThemeColorType::Accent6; + // Create a new pattern with font, background and borders set to theme colors ScPatternAttr aNewPattern(m_pDoc->getCellAttributeHelper()); { model::ComplexColor aComplexColor; @@ -66,10 +96,52 @@ CPPUNIT_TEST_FIXTURE(DocumentThemesTest, testChangeTheme) Color aColor = pTheme->getColorSet()->resolveColor(aComplexColor); aNewPattern.GetItemSet().Put(SvxColorItem(aColor, aComplexColor, ATTR_FONT_COLOR)); } + { + SvxBoxItem aBoxItem(ATTR_BORDER); + SvxBorderLineStyle eStyle = SvxBorderLineStyle::SOLID; + + { + model::ComplexColor aComplexColor; + aComplexColor.setThemeColor(eCellBorderLeftThemeType); + Color aColor = pTheme->getColorSet()->resolveColor(aComplexColor); + editeng::SvxBorderLine aLine(&aColor, 10, eStyle); + aLine.setComplexColor(aComplexColor); + aBoxItem.SetLine(&aLine, SvxBoxItemLine::LEFT); + } + + { + model::ComplexColor aComplexColor; + aComplexColor.setThemeColor(eCellBorderRightThemeType); + Color aColor = pTheme->getColorSet()->resolveColor(aComplexColor); + editeng::SvxBorderLine aLine(&aColor, 20, eStyle); + aLine.setComplexColor(aComplexColor); + aBoxItem.SetLine(&aLine, SvxBoxItemLine::RIGHT); + } + + { + model::ComplexColor aComplexColor; + aComplexColor.setThemeColor(eCellBorderTopThemeType); + Color aColor = pTheme->getColorSet()->resolveColor(aComplexColor); + editeng::SvxBorderLine aLine(&aColor, 30, eStyle); + aLine.setComplexColor(aComplexColor); + aBoxItem.SetLine(&aLine, SvxBoxItemLine::TOP); + } + + { + model::ComplexColor aComplexColor; + aComplexColor.setThemeColor(eCellBorderBottomThemeType); + Color aColor = pTheme->getColorSet()->resolveColor(aComplexColor); + editeng::SvxBorderLine aLine(&aColor, 40, eStyle); + aLine.setComplexColor(aComplexColor); + aBoxItem.SetLine(&aLine, SvxBoxItemLine::BOTTOM); + } + aNewPattern.GetItemSet().Put(aBoxItem); + } // Apply the pattern to cells C3:E5 (2,2 - 4,4) on the first sheet m_pDoc->ApplyPatternAreaTab(2, 2, 4, 4, 0, aNewPattern); + // Check the colors { const SfxPoolItem* pItem = nullptr; auto* pPattern = m_pDoc->GetPattern(ScAddress(3, 3, 0)); @@ -78,28 +150,27 @@ CPPUNIT_TEST_FIXTURE(DocumentThemesTest, testChangeTheme) pPattern->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem); auto pBrushItem = static_cast<const SvxBrushItem*>(pItem); CPPUNIT_ASSERT_EQUAL(aBackgroundThemeColor, pBrushItem->GetColor()); + pPattern->GetItemSet().HasItem(ATTR_FONT_COLOR, &pItem); auto pColorItem = static_cast<const SvxColorItem*>(pItem); CPPUNIT_ASSERT_EQUAL(aCellTextThemeColor, pColorItem->getColor()); + + pPattern->GetItemSet().HasItem(ATTR_BORDER, &pItem); + auto pBorderItem = static_cast<const SvxBoxItem*>(pItem); + CPPUNIT_ASSERT_EQUAL(aCellBorderLeftThemeColor, pBorderItem->GetLeft()->GetColor()); + CPPUNIT_ASSERT_EQUAL(aCellBorderRightThemeColor, pBorderItem->GetRight()->GetColor()); + CPPUNIT_ASSERT_EQUAL(aCellBorderTopThemeColor, pBorderItem->GetTop()->GetColor()); + CPPUNIT_ASSERT_EQUAL(aCellBorderBottomThemeColor, pBorderItem->GetBottom()->GetColor()); } - auto pColorSet = std::make_shared<model::ColorSet>("TestColorScheme"); - pColorSet->add(model::ThemeColorType::Dark1, 0x000000); - pColorSet->add(model::ThemeColorType::Light1, 0x111111); - pColorSet->add(model::ThemeColorType::Dark2, 0x222222); - pColorSet->add(model::ThemeColorType::Light2, 0x333333); - pColorSet->add(model::ThemeColorType::Accent1, 0x444444); - pColorSet->add(model::ThemeColorType::Accent2, 0x555555); - pColorSet->add(model::ThemeColorType::Accent3, 0x666666); - pColorSet->add(model::ThemeColorType::Accent4, 0x777777); - pColorSet->add(model::ThemeColorType::Accent5, 0x888888); - pColorSet->add(model::ThemeColorType::Accent6, 0x999999); - pColorSet->add(model::ThemeColorType::Hyperlink, 0xaaaaaa); - pColorSet->add(model::ThemeColorType::FollowedHyperlink, 0xbbbbbb); + // Create a new theme + auto pColorSet = createTestTheme(); + // Change the colors in the document to those of the new theme sc::ThemeColorChanger aChanger(*m_xDocShell); aChanger.apply(pColorSet); + // Check the values again { const SfxPoolItem* pItem = nullptr; auto* pPattern = m_pDoc->GetPattern(ScAddress(3, 3, 0)); @@ -108,9 +179,21 @@ CPPUNIT_TEST_FIXTURE(DocumentThemesTest, testChangeTheme) pPattern->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem); auto pBrushItem = static_cast<const SvxBrushItem*>(pItem); CPPUNIT_ASSERT_EQUAL(pColorSet->getColor(eBackgroundThemeType), pBrushItem->GetColor()); + pPattern->GetItemSet().HasItem(ATTR_FONT_COLOR, &pItem); auto pColorItem = static_cast<const SvxColorItem*>(pItem); CPPUNIT_ASSERT_EQUAL(pColorSet->getColor(eCellTextThemeType), pColorItem->getColor()); + + pPattern->GetItemSet().HasItem(ATTR_BORDER, &pItem); + auto pBorderItem = static_cast<const SvxBoxItem*>(pItem); + CPPUNIT_ASSERT_EQUAL(pColorSet->getColor(eCellBorderLeftThemeType), + pBorderItem->GetLeft()->GetColor()); + CPPUNIT_ASSERT_EQUAL(pColorSet->getColor(eCellBorderRightThemeType), + pBorderItem->GetRight()->GetColor()); + CPPUNIT_ASSERT_EQUAL(pColorSet->getColor(eCellBorderTopThemeType), + pBorderItem->GetTop()->GetColor()); + CPPUNIT_ASSERT_EQUAL(pColorSet->getColor(eCellBorderBottomThemeType), + pBorderItem->GetBottom()->GetColor()); } // Undo / Redo @@ -125,9 +208,17 @@ CPPUNIT_TEST_FIXTURE(DocumentThemesTest, testChangeTheme) pPattern->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem); auto pBrushItem = static_cast<const SvxBrushItem*>(pItem); CPPUNIT_ASSERT_EQUAL(aBackgroundThemeColor, pBrushItem->GetColor()); + pPattern->GetItemSet().HasItem(ATTR_FONT_COLOR, &pItem); auto pColorItem = static_cast<const SvxColorItem*>(pItem); CPPUNIT_ASSERT_EQUAL(aCellTextThemeColor, pColorItem->getColor()); + + pPattern->GetItemSet().HasItem(ATTR_BORDER, &pItem); + auto pBorderItem = static_cast<const SvxBoxItem*>(pItem); + CPPUNIT_ASSERT_EQUAL(aCellBorderLeftThemeColor, pBorderItem->GetLeft()->GetColor()); + CPPUNIT_ASSERT_EQUAL(aCellBorderRightThemeColor, pBorderItem->GetRight()->GetColor()); + CPPUNIT_ASSERT_EQUAL(aCellBorderTopThemeColor, pBorderItem->GetTop()->GetColor()); + CPPUNIT_ASSERT_EQUAL(aCellBorderBottomThemeColor, pBorderItem->GetBottom()->GetColor()); } m_pDoc->GetUndoManager()->Redo(); @@ -140,9 +231,105 @@ CPPUNIT_TEST_FIXTURE(DocumentThemesTest, testChangeTheme) pPattern->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem); auto pBrushItem = static_cast<const SvxBrushItem*>(pItem); CPPUNIT_ASSERT_EQUAL(pColorSet->getColor(eBackgroundThemeType), pBrushItem->GetColor()); + pPattern->GetItemSet().HasItem(ATTR_FONT_COLOR, &pItem); auto pColorItem = static_cast<const SvxColorItem*>(pItem); CPPUNIT_ASSERT_EQUAL(pColorSet->getColor(eCellTextThemeType), pColorItem->getColor()); + + pPattern->GetItemSet().HasItem(ATTR_BORDER, &pItem); + auto pBorderItem = static_cast<const SvxBoxItem*>(pItem); + CPPUNIT_ASSERT_EQUAL(pColorSet->getColor(eCellBorderLeftThemeType), + pBorderItem->GetLeft()->GetColor()); + CPPUNIT_ASSERT_EQUAL(pColorSet->getColor(eCellBorderRightThemeType), + pBorderItem->GetRight()->GetColor()); + CPPUNIT_ASSERT_EQUAL(pColorSet->getColor(eCellBorderTopThemeType), + pBorderItem->GetTop()->GetColor()); + CPPUNIT_ASSERT_EQUAL(pColorSet->getColor(eCellBorderBottomThemeType), + pBorderItem->GetBottom()->GetColor()); + } +} + +CPPUNIT_TEST_FIXTURE(DocumentThemesTest, testChangeTheme_TopBottomBorderOnly) +{ + // Check that applying only the top and bottom borders will + // change when the theme changes. + + m_pDoc->InitDrawLayer(); + m_pDoc->InsertTab(0, u"Test"_ustr); + + // Get the theme and define constants + ScDrawLayer* pDrawLayer = m_pDoc->GetDrawLayer(); + CPPUNIT_ASSERT(pDrawLayer); + auto const& pTheme = pDrawLayer->getTheme(); + CPPUNIT_ASSERT(pTheme); + + const auto eCellBorderTopThemeType = model::ThemeColorType::Accent1; + const auto eCellBorderBottomThemeType = model::ThemeColorType::Accent2; + + // Create a new pattern with font, background and borders set to theme colors + ScPatternAttr aNewPattern(m_pDoc->getCellAttributeHelper()); + { + SvxBoxItem aBoxItem(ATTR_BORDER); + SvxBorderLineStyle eStyle = SvxBorderLineStyle::SOLID; + + // Create the top line + { + model::ComplexColor aComplexColor; + aComplexColor.setThemeColor(eCellBorderTopThemeType); + Color aColor = pTheme->getColorSet()->resolveColor(aComplexColor); + editeng::SvxBorderLine aLine(&aColor, 30, eStyle); + aLine.setComplexColor(aComplexColor); + aBoxItem.SetLine(&aLine, SvxBoxItemLine::TOP); + } + + // Create the bottom line + { + model::ComplexColor aComplexColor; + aComplexColor.setThemeColor(eCellBorderBottomThemeType); + Color aColor = pTheme->getColorSet()->resolveColor(aComplexColor); + editeng::SvxBorderLine aLine(&aColor, 40, eStyle); + aLine.setComplexColor(aComplexColor); + aBoxItem.SetLine(&aLine, SvxBoxItemLine::BOTTOM); + } + aNewPattern.GetItemSet().Put(aBoxItem); + } + + // Apply the pattern to cells C3:E5 (2,2 - 4,4) on the first sheet + m_pDoc->ApplyPatternAreaTab(2, 2, 4, 4, 0, aNewPattern); + + // Check the theme colors of the top and bottom borders + { + const SfxPoolItem* pItem = nullptr; + auto* pPattern = m_pDoc->GetPattern(ScAddress(3, 3, 0)); + CPPUNIT_ASSERT(pPattern); + + pPattern->GetItemSet().HasItem(ATTR_BORDER, &pItem); + auto pBorderItem = static_cast<const SvxBoxItem*>(pItem); + + // Colors should be from the default theme + CPPUNIT_ASSERT_EQUAL(Color(0x18a303), pBorderItem->GetTop()->GetColor()); + CPPUNIT_ASSERT_EQUAL(Color(0x0369a3), pBorderItem->GetBottom()->GetColor()); + } + + // Create a new theme + auto pColorSet = createTestTheme(); + + // Change the colors in the document to those of the new theme + sc::ThemeColorChanger aChanger(*m_xDocShell); + aChanger.apply(pColorSet); + + // Check the border top and bottom colors again + { + const SfxPoolItem* pItem = nullptr; + auto* pPattern = m_pDoc->GetPattern(ScAddress(3, 3, 0)); + CPPUNIT_ASSERT(pPattern); + + pPattern->GetItemSet().HasItem(ATTR_BORDER, &pItem); + auto pBorderItem = static_cast<const SvxBoxItem*>(pItem); + + // Colors should be from the new theme + CPPUNIT_ASSERT_EQUAL(Color(0x444444), pBorderItem->GetTop()->GetColor()); + CPPUNIT_ASSERT_EQUAL(Color(0x555555), pBorderItem->GetBottom()->GetColor()); } } diff --git a/sc/source/ui/theme/ThemeColorChanger.cxx b/sc/source/ui/theme/ThemeColorChanger.cxx index 8745459d37a5..8f25aeeaf001 100644 --- a/sc/source/ui/theme/ThemeColorChanger.cxx +++ b/sc/source/ui/theme/ThemeColorChanger.cxx @@ -102,10 +102,10 @@ bool changeCellItems(SfxItemSet& rItemSet, model::ColorSet const& rColorSet) SvxBoxItem rNewItem(*pBoxItem); bool bLineChanged = false; - bLineChanged = changeBorderLine(rNewItem.GetBottom(), rColorSet) || bChanged; - bLineChanged = changeBorderLine(rNewItem.GetTop(), rColorSet) || bChanged; - bLineChanged = changeBorderLine(rNewItem.GetLeft(), rColorSet) || bChanged; - bLineChanged = changeBorderLine(rNewItem.GetRight(), rColorSet) || bChanged; + bLineChanged = changeBorderLine(rNewItem.GetBottom(), rColorSet) || bLineChanged; + bLineChanged = changeBorderLine(rNewItem.GetTop(), rColorSet) || bLineChanged; + bLineChanged = changeBorderLine(rNewItem.GetLeft(), rColorSet) || bLineChanged; + bLineChanged = changeBorderLine(rNewItem.GetRight(), rColorSet) || bLineChanged; if (bLineChanged) { @@ -351,6 +351,8 @@ void ThemeColorChanger::doApply(std::shared_ptr<model::ColorSet> const& pColorSe } m_rDocShell.SetDrawModified(); + m_rDocShell.PostPaint(0, 0, 0, rDocument.MaxCol(), rDocument.MaxRow(), MAXTAB, + PaintPartFlags::All); aModificator.SetDocumentModified(); }
