include/svx/ColorSets.hxx | 8 - svx/Package_document_themes.mk | 8 + svx/source/styles/ColorSets.cxx | 231 +++++++++++++++++++------------------- svx/uiconfig/themes/Beach.theme | 18 ++ svx/uiconfig/themes/Breeze.theme | 18 ++ svx/uiconfig/themes/Forest.theme | 18 ++ svx/uiconfig/themes/Ocean.theme | 18 ++ svx/uiconfig/themes/Rainbow.theme | 18 ++ svx/uiconfig/themes/Sunset.theme | 18 ++ sw/qa/core/theme/ThemeTest.cxx | 3 10 files changed, 237 insertions(+), 121 deletions(-)
New commits: commit f877f7e88663657587561e65f7f46a9f5f4421fb Author: Tomaž Vajngerl <[email protected]> AuthorDate: Mon Jan 20 21:36:32 2025 +0900 Commit: Tomaž Vajngerl <[email protected]> CommitDate: Wed Jan 22 15:33:36 2025 +0100 docthemes: Load document themes def. files into ColorSets This is then used in Theme dialog to show which themes are available. Also add the existing hardcoded themes as theme def. files. Change-Id: I230bc84ae70f22b558aa31053339d602d04885bb Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180541 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <[email protected]> diff --git a/include/svx/ColorSets.hxx b/include/svx/ColorSets.hxx index 6d7ba41398b4..4cf3313e0855 100644 --- a/include/svx/ColorSets.hxx +++ b/include/svx/ColorSets.hxx @@ -5,11 +5,9 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * */ -#ifndef INCLUDED_SVX_COLORSETS_HXX -#define INCLUDED_SVX_COLORSETS_HXX +#pragma once #include <svx/svxdllapi.h> #include <docmodel/theme/ColorSet.hxx> @@ -39,11 +37,9 @@ public: model::ColorSet const* getColorSet(std::u16string_view rName) const; - void insert(model::ColorSet const& rColorSet, IdenticalNameAction eAction = IdenticalNameAction::Overwrite); + void insert(model::ColorSet const& rColorSet, IdenticalNameAction eAction); }; } // end of namespace svx -#endif // INCLUDED_SVX_COLORSETS_HXX - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/Package_document_themes.mk b/svx/Package_document_themes.mk index 254292d9c45d..0664f1f9f0ae 100644 --- a/svx/Package_document_themes.mk +++ b/svx/Package_document_themes.mk @@ -10,7 +10,13 @@ $(eval $(call gb_Package_Package,svx_document_themes,$(SRCDIR)/svx/uiconfig/themes)) $(eval $(call gb_Package_add_files_with_dir,svx_document_themes,$(LIBO_SHARE_FOLDER)/themes,\ - libreoffice.theme \ + Beach.theme \ + Breeze.theme \ + Forest.theme \ + Libreoffice.theme \ + Ocean.theme \ + Rainbow.theme \ + Sunset.theme \ )) # vim: set noet sw=4 ts=4: diff --git a/svx/source/styles/ColorSets.cxx b/svx/source/styles/ColorSets.cxx index 92b4973cbcca..57c4b44227a2 100644 --- a/svx/source/styles/ColorSets.cxx +++ b/svx/source/styles/ColorSets.cxx @@ -12,12 +12,127 @@ #include <optional> #include <unordered_set> +#include <vector> + #include <docmodel/theme/ColorSet.hxx> +#include <o3tl/numeric.hxx> +#include <tools/stream.hxx> +#include <tools/XmlWalker.hxx> +#include <vcl/UserResourceScanner.hxx> +#include <unotools/pathoptions.hxx> +#include <docmodel/theme/ThemeColorType.hxx> +#include <frozen/bits/defines.h> +#include <frozen/bits/elsa_std.h> +#include <frozen/unordered_map.h> using namespace com::sun::star; namespace svx { +namespace +{ + +class DocumentThemeScanner : public vcl::UserResourceScanner +{ +private: + std::vector<model::ColorSet>& mrColorSets; + +public: + DocumentThemeScanner(std::vector<model::ColorSet>& rColorSets) + : mrColorSets(rColorSets) + {} + +private: + static model::ThemeColorType getThemeColor(std::string_view sColorName) + { + model::ThemeColorType eTheme = model::ThemeColorType::Unknown; + + static constexpr auto constThemeColorTypeMapping = frozen::make_unordered_map<std::string_view, model::ThemeColorType>({ + { "dark1", model::ThemeColorType::Dark1 }, + { "light1", model::ThemeColorType::Light1 }, + { "dark2", model::ThemeColorType::Dark2 }, + { "light2", model::ThemeColorType::Light2 }, + { "accent1", model::ThemeColorType::Accent1 }, + { "accent2", model::ThemeColorType::Accent2 }, + { "accent3", model::ThemeColorType::Accent3 }, + { "accent4", model::ThemeColorType::Accent4 }, + { "accent5", model::ThemeColorType::Accent5 }, + { "accent6", model::ThemeColorType::Accent6 }, + { "hyperlink", model::ThemeColorType::Hyperlink }, + { "followed-hyperlink", model::ThemeColorType::FollowedHyperlink }, + }); + auto iterator = constThemeColorTypeMapping.find(sColorName); + if (iterator != constThemeColorTypeMapping.end()) + eTheme = iterator->second; + return eTheme; + } + + bool addResource(const OUString& rPath) override + { + SvFileStream aFileStream(rPath, StreamMode::READ); + + tools::XmlWalker aWalker; + if (!aWalker.open(&aFileStream)) + return false; + + if (aWalker.name() != "theme") + return false; + + OString aThemeNameUTF8 = aWalker.attribute("name"_ostr); + OUString aThemeName = OStringToOUString(aThemeNameUTF8, RTL_TEXTENCODING_UTF8); + + model::ColorSet aColorSet(aThemeName); + + aWalker.children(); + while (aWalker.isValid()) + { + if (aWalker.name() == "theme-colors") + { + aWalker.children(); + while (aWalker.isValid()) + { + if (aWalker.name() == "color") + { + OString aName = aWalker.attribute("name"_ostr); + auto eThemeColor = getThemeColor(aName); + OString aColorString = aWalker.attribute("color"_ostr); + Color aColor; + if (eThemeColor != model::ThemeColorType::Unknown && color::createFromString(aColorString, aColor)) + aColorSet.add(eThemeColor, aColor); + } + aWalker.next(); + } + aWalker.parent(); + } + aWalker.next(); + } + aWalker.parent(); + + mrColorSets.push_back(aColorSet); + + return true; + } + + bool isValidResource(const OUString& rFilename) override + { + if (rFilename.isEmpty()) + return false; + + if (!rFilename.endsWithIgnoreAsciiCase(u".theme")) + return false; + + osl::FileStatus aFileStatus(osl_FileStatus_Mask_Type); + if (!vcl::file::readFileStatus(aFileStatus, rFilename)) + return false; + + if (!aFileStatus.isRegular()) + return false; + + return true; + } +}; + +} // end anonymous namespace ColorSets::ColorSets() { @@ -32,121 +147,11 @@ ColorSets& ColorSets::get() return *sColorSet; } - void ColorSets::init() { - { - model::ColorSet aColorSet(u"LibreOffice"_ustr); - aColorSet.add(model::ThemeColorType::Dark1, 0x000000); - aColorSet.add(model::ThemeColorType::Light1, 0xFFFFFF); - aColorSet.add(model::ThemeColorType::Dark2, 0x000000); - aColorSet.add(model::ThemeColorType::Light2, 0xFFFFFF); - aColorSet.add(model::ThemeColorType::Accent1, 0x18A303); - aColorSet.add(model::ThemeColorType::Accent2, 0x0369A3); - aColorSet.add(model::ThemeColorType::Accent3, 0xA33E03); - aColorSet.add(model::ThemeColorType::Accent4, 0x8E03A3); - aColorSet.add(model::ThemeColorType::Accent5, 0xC99C00); - aColorSet.add(model::ThemeColorType::Accent6, 0xC9211E); - aColorSet.add(model::ThemeColorType::Hyperlink, 0x0000EE); - aColorSet.add(model::ThemeColorType::FollowedHyperlink, 0x551A8B); - maColorSets.push_back(aColorSet); - } - { - model::ColorSet aColorSet(u"Rainbow"_ustr); - aColorSet.add(model::ThemeColorType::Dark1, 0x000000); - aColorSet.add(model::ThemeColorType::Light1, 0xFFFFFF); - aColorSet.add(model::ThemeColorType::Dark2, 0x1C1C1C); - aColorSet.add(model::ThemeColorType::Light2, 0xDDDDDD); - aColorSet.add(model::ThemeColorType::Accent1, 0xFF0000); - aColorSet.add(model::ThemeColorType::Accent2, 0xFF8000); - aColorSet.add(model::ThemeColorType::Accent3, 0xFFFF00); - aColorSet.add(model::ThemeColorType::Accent4, 0x00A933); - aColorSet.add(model::ThemeColorType::Accent5, 0x2A6099); - aColorSet.add(model::ThemeColorType::Accent6, 0x800080); - aColorSet.add(model::ThemeColorType::Hyperlink, 0x0000EE); - aColorSet.add(model::ThemeColorType::FollowedHyperlink, 0x551A8B); - maColorSets.push_back(aColorSet); - } - { - model::ColorSet aColorSet(u"Beach"_ustr); - aColorSet.add(model::ThemeColorType::Dark1, 0x000000); - aColorSet.add(model::ThemeColorType::Light1, 0xFFFFFF); - aColorSet.add(model::ThemeColorType::Dark2, 0xFFBF00); - aColorSet.add(model::ThemeColorType::Light2, 0x333333); - aColorSet.add(model::ThemeColorType::Accent1, 0xFFF5CE); - aColorSet.add(model::ThemeColorType::Accent2, 0xDEE6EF); - aColorSet.add(model::ThemeColorType::Accent3, 0xE8F2A1); - aColorSet.add(model::ThemeColorType::Accent4, 0xFFD7D7); - aColorSet.add(model::ThemeColorType::Accent5, 0xDEE7E5); - aColorSet.add(model::ThemeColorType::Accent6, 0xDDDBB6); - aColorSet.add(model::ThemeColorType::Hyperlink, 0x7777EE); - aColorSet.add(model::ThemeColorType::FollowedHyperlink, 0xEE77D7); - maColorSets.push_back(aColorSet); - } - { - model::ColorSet aColorSet(u"Sunset"_ustr); - aColorSet.add(model::ThemeColorType::Dark1, 0x000000); - aColorSet.add(model::ThemeColorType::Light1, 0xFFFFFF); - aColorSet.add(model::ThemeColorType::Dark2, 0x492300); - aColorSet.add(model::ThemeColorType::Light2, 0xF6F9D4); - aColorSet.add(model::ThemeColorType::Accent1, 0xFFFF00); - aColorSet.add(model::ThemeColorType::Accent2, 0xFFBF00); - aColorSet.add(model::ThemeColorType::Accent3, 0xFF8000); - aColorSet.add(model::ThemeColorType::Accent4, 0xFF4000); - aColorSet.add(model::ThemeColorType::Accent5, 0xBF0041); - aColorSet.add(model::ThemeColorType::Accent6, 0x800080); - aColorSet.add(model::ThemeColorType::Hyperlink, 0x0000EE); - aColorSet.add(model::ThemeColorType::FollowedHyperlink, 0x551A8B); - maColorSets.push_back(aColorSet); - } - { - model::ColorSet aColorSet(u"Ocean"_ustr); - aColorSet.add(model::ThemeColorType::Dark1, 0x000000); - aColorSet.add(model::ThemeColorType::Light1, 0xFFFFFF); - aColorSet.add(model::ThemeColorType::Dark2, 0x2A6099); - aColorSet.add(model::ThemeColorType::Light2, 0xCCCCCC); - aColorSet.add(model::ThemeColorType::Accent1, 0x800080); - aColorSet.add(model::ThemeColorType::Accent2, 0x55308D); - aColorSet.add(model::ThemeColorType::Accent3, 0x2A6099); - aColorSet.add(model::ThemeColorType::Accent4, 0x158466); - aColorSet.add(model::ThemeColorType::Accent5, 0x00A933); - aColorSet.add(model::ThemeColorType::Accent6, 0x81D41A); - aColorSet.add(model::ThemeColorType::Hyperlink, 0x0000EE); - aColorSet.add(model::ThemeColorType::FollowedHyperlink, 0x551A8B); - maColorSets.push_back(aColorSet); - } - { - model::ColorSet aColorSet(u"Forest"_ustr); - aColorSet.add(model::ThemeColorType::Dark1, 0x000000); - aColorSet.add(model::ThemeColorType::Light1, 0xFFFFFF); - aColorSet.add(model::ThemeColorType::Dark2, 0x000000); - aColorSet.add(model::ThemeColorType::Light2, 0xFFFFFF); - aColorSet.add(model::ThemeColorType::Accent1, 0x813709); - aColorSet.add(model::ThemeColorType::Accent2, 0x224B12); - aColorSet.add(model::ThemeColorType::Accent3, 0x706E0C); - aColorSet.add(model::ThemeColorType::Accent4, 0x355269); - aColorSet.add(model::ThemeColorType::Accent5, 0xBE480A); - aColorSet.add(model::ThemeColorType::Accent6, 0xBE480A); - aColorSet.add(model::ThemeColorType::Hyperlink, 0x2A6099); - aColorSet.add(model::ThemeColorType::FollowedHyperlink, 0x800080); - maColorSets.push_back(aColorSet); - } - { - model::ColorSet aColorSet(u"Breeze"_ustr); - aColorSet.add(model::ThemeColorType::Dark1, 0x232629); - aColorSet.add(model::ThemeColorType::Light1, 0xFCFCFC); - aColorSet.add(model::ThemeColorType::Dark2, 0x31363B); - aColorSet.add(model::ThemeColorType::Light2, 0xEFF0F1); - aColorSet.add(model::ThemeColorType::Accent1, 0xDA4453); - aColorSet.add(model::ThemeColorType::Accent2, 0xF47750); - aColorSet.add(model::ThemeColorType::Accent3, 0xFDBC4B); - aColorSet.add(model::ThemeColorType::Accent4, 0xC9CE3B); - aColorSet.add(model::ThemeColorType::Accent5, 0x1CDC9A); - aColorSet.add(model::ThemeColorType::Accent6, 0x2ECC71); - aColorSet.add(model::ThemeColorType::Hyperlink, 0x1D99F3); - aColorSet.add(model::ThemeColorType::FollowedHyperlink, 0x3DAEE9); - maColorSets.push_back(aColorSet); - } + SvtPathOptions aPathOptions; + DocumentThemeScanner aScanner(maColorSets); + aScanner.addPaths(aPathOptions.GetDocumentThemePath()); } model::ColorSet const* ColorSets::getColorSet(std::u16string_view rName) const diff --git a/svx/uiconfig/themes/Beach.theme b/svx/uiconfig/themes/Beach.theme new file mode 100644 index 000000000000..1c006dcf9a53 --- /dev/null +++ b/svx/uiconfig/themes/Beach.theme @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<theme name="Beach"> + <theme-colors name="Beach"> + <color name="dark1" color="#000000" /> + <color name="light1" color="#FFFFFF" /> + <color name="dark2" color="#FFBF00" /> + <color name="light2" color="#333333" /> + <color name="accent1" color="#FFF5CE" /> + <color name="accent2" color="#DEE6EF" /> + <color name="accent3" color="#E8F2A1" /> + <color name="accent4" color="#FFD7D7" /> + <color name="accent5" color="#DEE7E5" /> + <color name="accent6" color="#DDDBB6" /> + <color name="hyperlink" color="#7777EE" /> + <color name="followed-hyperlink" color="#EE77D7" /> + </theme-colors> +</theme> diff --git a/svx/uiconfig/themes/Breeze.theme b/svx/uiconfig/themes/Breeze.theme new file mode 100644 index 000000000000..efae704f506c --- /dev/null +++ b/svx/uiconfig/themes/Breeze.theme @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<theme name="Breeze"> + <theme-colors name="Breeze"> + <color name="dark1" color="#232629" /> + <color name="light1" color="#FCFCFC" /> + <color name="dark2" color="#31363B" /> + <color name="light2" color="#EFF0F1" /> + <color name="accent1" color="#DA4453" /> + <color name="accent2" color="#F47750" /> + <color name="accent3" color="#FDBC4B" /> + <color name="accent4" color="#C9CE3B" /> + <color name="accent5" color="#1CDC9A" /> + <color name="accent6" color="#2ECC71" /> + <color name="hyperlink" color="#1D99F3" /> + <color name="followed-hyperlink" color="#3DAEE9" /> + </theme-colors> +</theme> diff --git a/svx/uiconfig/themes/Forest.theme b/svx/uiconfig/themes/Forest.theme new file mode 100644 index 000000000000..89527577d4e4 --- /dev/null +++ b/svx/uiconfig/themes/Forest.theme @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<theme name="Forest"> + <theme-colors name="Forest"> + <color name="dark1" color="#000000" /> + <color name="light1" color="#FFFFFF" /> + <color name="dark2" color="#000000" /> + <color name="light2" color="#FFFFFF" /> + <color name="accent1" color="#813709" /> + <color name="accent2" color="#224B12" /> + <color name="accent3" color="#706E0C" /> + <color name="accent4" color="#355269" /> + <color name="accent5" color="#BE480A" /> + <color name="accent6" color="#BE480A" /> + <color name="hyperlink" color="#2A6099" /> + <color name="followed-hyperlink" color="#800080" /> + </theme-colors> +</theme> diff --git a/svx/uiconfig/themes/libreoffice.theme b/svx/uiconfig/themes/Libreoffice.theme similarity index 100% rename from svx/uiconfig/themes/libreoffice.theme rename to svx/uiconfig/themes/Libreoffice.theme diff --git a/svx/uiconfig/themes/Ocean.theme b/svx/uiconfig/themes/Ocean.theme new file mode 100644 index 000000000000..5e7dc337b798 --- /dev/null +++ b/svx/uiconfig/themes/Ocean.theme @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<theme name="Ocean"> + <theme-colors name="Ocean"> + <color name="dark1" color="#000000" /> + <color name="light1" color="#FFFFFF" /> + <color name="dark2" color="#2A6099" /> + <color name="light2" color="#CCCCCC" /> + <color name="accent1" color="#800080" /> + <color name="accent2" color="#55308D" /> + <color name="accent3" color="#2A6099" /> + <color name="accent4" color="#158466" /> + <color name="accent5" color="#00A933" /> + <color name="accent6" color="#81D41A" /> + <color name="hyperlink" color="#0000EE" /> + <color name="followed-hyperlink" color="#551A8B" /> + </theme-colors> +</theme> diff --git a/svx/uiconfig/themes/Rainbow.theme b/svx/uiconfig/themes/Rainbow.theme new file mode 100644 index 000000000000..4a372d80f8a7 --- /dev/null +++ b/svx/uiconfig/themes/Rainbow.theme @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<theme name="Rainbow"> + <theme-colors name="Rainbow"> + <color name="dark1" color="#000000" /> + <color name="light1" color="#FFFFFF" /> + <color name="dark2" color="#1C1C1C" /> + <color name="light2" color="#DDDDDD" /> + <color name="accent1" color="#FF0000" /> + <color name="accent2" color="#FF8000" /> + <color name="accent3" color="#FFFF00" /> + <color name="accent4" color="#00A933" /> + <color name="accent5" color="#2A6099" /> + <color name="accent6" color="#800080" /> + <color name="hyperlink" color="#0000EE" /> + <color name="followed-hyperlink" color="#551A8B" /> + </theme-colors> +</theme> diff --git a/svx/uiconfig/themes/Sunset.theme b/svx/uiconfig/themes/Sunset.theme new file mode 100644 index 000000000000..107bb1c53fa3 --- /dev/null +++ b/svx/uiconfig/themes/Sunset.theme @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<theme name="Sunset"> + <theme-colors name="Sunset"> + <color name="dark1" color="#000000" /> + <color name="light1" color="#FFFFFF" /> + <color name="dark2" color="#492300" /> + <color name="light2" color="#F6F9D4" /> + <color name="accent1" color="#FFFF00" /> + <color name="accent2" color="#FFBF00" /> + <color name="accent3" color="#FF8000" /> + <color name="accent4" color="#FF4000" /> + <color name="accent5" color="#BF0041" /> + <color name="accent6" color="#800080" /> + <color name="hyperlink" color="#0000EE" /> + <color name="followed-hyperlink" color="#551A8B" /> + </theme-colors> +</theme> diff --git a/sw/qa/core/theme/ThemeTest.cxx b/sw/qa/core/theme/ThemeTest.cxx index 7ae4e2fa2bbf..c93e4a436c77 100644 --- a/sw/qa/core/theme/ThemeTest.cxx +++ b/sw/qa/core/theme/ThemeTest.cxx @@ -429,7 +429,8 @@ CPPUNIT_TEST_FIXTURE(SwCoreThemeTest, testThemeChanging) // Change theme colors { auto const& rColorSets = svx::ColorSets::get(); - auto pNewColorSet = std::make_shared<model::ColorSet>(rColorSets.getColorSet(0)); + auto pNewColorSet + = std::make_shared<model::ColorSet>(*rColorSets.getColorSet(u"LibreOffice")); // check that the theme colors are as expected CPPUNIT_ASSERT_EQUAL(u"LibreOffice"_ustr, pNewColorSet->getName());
