docthemes: Save themes def. to a file when added to ColorSets

Color themes will be written to the user folder.

Change-Id: I58e650550044bd35a5054a303ce41789d3d51d32
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180542
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
This commit is contained in:
Tomaž Vajngerl 2025-01-21 19:08:33 +09:00 committed by Tomaž Vajngerl
parent 1412f02354
commit 89c27a63a7
4 changed files with 79 additions and 15 deletions

View File

@ -19,6 +19,8 @@ class SVXCORE_DLLPUBLIC ColorSets
{
private:
std::vector<model::ColorSet> maColorSets;
OUString maUserFolder;
ColorSets();
void init();
public:
@ -38,6 +40,8 @@ public:
model::ColorSet const* getColorSet(std::u16string_view rName) const;
void insert(model::ColorSet const& rColorSet, IdenticalNameAction eAction);
void writeToUserFolder(model::ColorSet const& rNewColorSet);
};
} // end of namespace svx

View File

@ -13,6 +13,7 @@
#include <rtl/ustring.hxx>
#include <memory>
#include <vector>
#include <deque>
#include <osl/file.hxx>
namespace vcl
@ -20,6 +21,7 @@ namespace vcl
namespace file
{
VCL_DLLPUBLIC bool readFileStatus(osl::FileStatus& rStatus, const OUString& rFile);
VCL_DLLPUBLIC void splitPathString(std::u16string_view aPathString, std::deque<OUString>& rPaths);
}
class VCL_DLLPUBLIC UserResourceScanner

View File

@ -15,12 +15,14 @@
#include <vector>
#include <docmodel/theme/ColorSet.hxx>
#include <docmodel/theme/ThemeColorType.hxx>
#include <o3tl/numeric.hxx>
#include <tools/stream.hxx>
#include <tools/XmlWalker.hxx>
#include <tools/XmlWriter.hxx>
#include <vcl/UserResourceScanner.hxx>
#include <unotools/pathoptions.hxx>
#include <docmodel/theme/ThemeColorType.hxx>
#include <o3tl/enumrange.hxx>
#include <frozen/bits/defines.h>
#include <frozen/bits/elsa_std.h>
#include <frozen/unordered_map.h>
@ -150,8 +152,15 @@ ColorSets& ColorSets::get()
void ColorSets::init()
{
SvtPathOptions aPathOptions;
OUString aURLString = aPathOptions.GetDocumentThemePath();
DocumentThemeScanner aScanner(maColorSets);
aScanner.addPaths(aPathOptions.GetDocumentThemePath());
aScanner.addPaths(aURLString);
std::deque<OUString> aURLs;
vcl::file::splitPathString(aURLString, aURLs);
if (aURLs.size() > 0)
maUserFolder = aURLs[0];
}
model::ColorSet const* ColorSets::getColorSet(std::u16string_view rName) const
@ -200,6 +209,7 @@ void ColorSets::insert(model::ColorSet const& rNewColorSet, IdenticalNameAction
}
// color set not found, so insert it
maColorSets.push_back(rNewColorSet);
writeToUserFolder(rNewColorSet);
}
else if (eAction == IdenticalNameAction::AutoRename)
{
@ -211,10 +221,58 @@ void ColorSets::insert(model::ColorSet const& rNewColorSet, IdenticalNameAction
model::ColorSet aNewColorSet = rNewColorSet;
aNewColorSet.setName(aName);
maColorSets.push_back(aNewColorSet);
writeToUserFolder(aNewColorSet);
}
}
void ColorSets::writeToUserFolder(model::ColorSet const& rNewColorSet)
{
static constexpr auto constThemeColorTypeToName = frozen::make_unordered_map<model::ThemeColorType, std::string_view>({
{ model::ThemeColorType::Dark1, "dark1" },
{ model::ThemeColorType::Light1, "light1" },
{ model::ThemeColorType::Dark2, "dark2" },
{ model::ThemeColorType::Light2, "light2" },
{ model::ThemeColorType::Accent1, "accent1" },
{ model::ThemeColorType::Accent2, "accent2" },
{ model::ThemeColorType::Accent3, "accent3" },
{ model::ThemeColorType::Accent4, "accent4" },
{ model::ThemeColorType::Accent5, "accent5" },
{ model::ThemeColorType::Accent6, "accent6" },
{ model::ThemeColorType::Hyperlink, "hyperlink" },
{ model::ThemeColorType::FollowedHyperlink, "followed-hyperlink" }
});
SvFileStream aFileStream(maUserFolder + "/" + rNewColorSet.getName() + ".theme", StreamMode::WRITE | StreamMode::TRUNC);
tools::XmlWriter aWriter(&aFileStream);
aWriter.startDocument();
aWriter.startElement("theme");
aWriter.attribute("name", rNewColorSet.getName());
aWriter.startElement("theme-colors");
aWriter.attribute("name", rNewColorSet.getName());
for (auto eThemeColorType : o3tl::enumrange<model::ThemeColorType>())
{
auto iterator = constThemeColorTypeToName.find(eThemeColorType);
if (iterator != constThemeColorTypeToName.end())
{
Color aColor = rNewColorSet.getColor(eThemeColorType);
aWriter.startElement("color");
aWriter.attribute("name", OString(iterator->second));
aWriter.attribute("color", "#"_ostr + aColor.AsRGBHexString().toUtf8());
aWriter.endElement();
}
}
aWriter.endElement();
aWriter.endElement();
aWriter.endDocument();
}
} // end of namespace svx
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@ -37,15 +37,6 @@ OUString convertToAbsolutePath(const OUString& path)
}
return resolver.m_aStatus.getFileURL();
}
void splitPathString(std::u16string_view aPathString, std::deque<OUString>& rPaths)
{
sal_Int32 nIndex = 0;
do
{
rPaths.push_front(OUString(o3tl::getToken(aPathString, 0, ';', nIndex)));
} while (nIndex >= 0);
}
}
namespace file
@ -68,6 +59,15 @@ bool readFileStatus(osl::FileStatus& status, const OUString& file)
}
return true;
}
void splitPathString(std::u16string_view aPathString, std::deque<OUString>& rPaths)
{
sal_Int32 nIndex = 0;
do
{
rPaths.push_front(OUString(o3tl::getToken(aPathString, 0, ';', nIndex)));
} while (nIndex >= 0);
}
}
UserResourceScanner::UserResourceScanner() = default;
@ -75,7 +75,7 @@ UserResourceScanner::UserResourceScanner() = default;
void UserResourceScanner::addPaths(std::u16string_view aPathString)
{
std::deque<OUString> aPaths;
splitPathString(aPathString, aPaths);
vcl::file::splitPathString(aPathString, aPaths);
for (const auto& path : aPaths)
{
@ -86,8 +86,8 @@ void UserResourceScanner::addPaths(std::u16string_view aPathString)
if (!aFileStatus.isDirectory())
{
SAL_INFO("vcl.app",
"Cannot search for icon themes in '" << path << "'. It is not a directory.");
SAL_INFO("vcl.app", "Cannot search for resaource files in '"
<< path << "'. It is not a directory.");
continue;
}
@ -96,7 +96,7 @@ void UserResourceScanner::addPaths(std::u16string_view aPathString)
if (aResourcePaths.empty())
{
SAL_WARN("vcl.app",
"Could not find any icon themes in the provided directory ('" << path << "'.");
"Could not find any file in the provided directory ('" << path << "'.");
continue;
}