include/tools/XPath.hxx | 72 ++++++++ sd/source/core/drawdoc4.cxx | 321 ++++++++++++++++++++-------------------- svx/qa/unit/svdraw.cxx | 128 +++++++++------ tools/CppunitTest_tools_test.mk | 12 - tools/Library_tl.mk | 1 tools/qa/cppunit/test_xpath.cxx | 95 +++++++++++ tools/source/xml/XPath.cxx | 197 ++++++++++++++++++++++++ 7 files changed, 609 insertions(+), 217 deletions(-)
New commits: commit 7d1e8397fb9718bbfb992e79b1efbe00621d9694 Author: Tomaž Vajngerl <[email protected]> AuthorDate: Sun Dec 14 12:07:31 2025 +0900 Commit: Tomaž Vajngerl <[email protected]> CommitDate: Mon Feb 23 13:03:08 2026 +0100 introduce tools::XPath to be able to reuse the result after call In tests we many times rerun the XPath search to just check another XML attribute, or first check the size of child elements and then check each element's attributes in a separate call (re-running the XPath search). Re-running an XPath search all the time takes up quite some CPU resources and doing it a lot will accumulate, so the idea here is to have an object as a result on which you can reuse instead of re-running the search. In addition it is possible to combine the search path from the previous search, so it is possible to construct paths in a more concise way. Example: auto primitivePath = aXPath.create("/primitive2D"); auto polyPath = aXPath.create(primitivePath, "/polypolygon"); polyPath will use a combined path "/primitive2D/polypolygon" as the search path. Checking can be done by simply using CPPUNIT_ASSERT* functions with this, but we might extend UnoApiXmlTest with some checks for convenience because the assertXPath methods do have better reporting when the assert fails. Also integration into the UnoApiXmlTest class will need to be done, because namespaces need to be registered before tools::XPath can be used correctly. This change does not touch that yet. A couple of tests in SvdrawTest have been changed to use the new tools::XPath class - most notable testRectangleObject. These tests don't use any namespaces so it is easy to convert those. Change-Id: I29251d2e7f4c3ee5b76e46daf78c21d0ca067cb4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195618 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200018 Tested-by: Jenkins CollaboraOffice <[email protected]> diff --git a/include/tools/XPath.hxx b/include/tools/XPath.hxx new file mode 100644 index 000000000000..28b7d30ba1ef --- /dev/null +++ b/include/tools/XPath.hxx @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * 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/. + */ + +#pragma once + +#include <tools/toolsdllapi.h> +#include <rtl/string.hxx> +#include <rtl/ustring.hxx> + +#include <memory> +#include <functional> + +#include <libxml/xmlwriter.h> +#include <libxml/xpath.h> +#include <libxml/xpathInternals.h> +#include <libxml/parserInternals.h> + +namespace tools +{ +class TOOLS_DLLPUBLIC XmlElement final +{ + xmlNodePtr mpXmlNode; + +public: + XmlElement(xmlNodePtr pXmlNode) + : mpXmlNode(pXmlNode) + { + } + + std::string_view name(); + OUString attribute(const char* pAttribute); + sal_Int32 countChildren(); + std::unique_ptr<XmlElement> at(sal_Int32 nIndex); +}; + +class TOOLS_DLLPUBLIC XPathObject final +{ + xmlXPathObjectPtr mpXPathObject; + std::string_view maPath; + +public: + XPathObject(xmlXPathObjectPtr pXPathObject, std::string_view aString); + ~XPathObject(); + std::string_view getPathString() { return maPath; } + sal_Int32 count(); + OUString attribute(const char* pAttribute); + OUString content(); + std::unique_ptr<XmlElement> at(sal_Int32 nIndex); +}; + +class TOOLS_DLLPUBLIC XPath final +{ + xmlDocPtr mpXmlDocPtr; + std::function<void(xmlXPathContextPtr)> mFuncRegisterNamespaces; + +public: + XPath(xmlDocPtr pDocPtr); + XPath(xmlDocPtr pDocPtr, std::function<void(xmlXPathContextPtr)> funcRegisterNamespaces); + std::unique_ptr<XPathObject> create(std::string_view aString); + std::unique_ptr<XPathObject> create(std::unique_ptr<XPathObject> const& pPathObject, + std::string_view aString); +}; + +} // end tools namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/qa/unit/svdraw.cxx b/svx/qa/unit/svdraw.cxx index 9de05f7f7592..c555c5b67c3b 100644 --- a/svx/qa/unit/svdraw.cxx +++ b/svx/qa/unit/svdraw.cxx @@ -45,6 +45,7 @@ #include <sfx2/objsh.hxx> #include <sdr/contact/objectcontactofobjlistpainter.hxx> +#include <tools/XPath.hxx> using namespace ::com::sun::star; @@ -317,45 +318,56 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testRectangleObject) svx::ExtendedPrimitive2dXmlDump aDumper; xmlDocUniquePtr pXmlDoc = aDumper.dumpAndParse(xPrimitiveSequence); - assertXPath(pXmlDoc, "/primitive2D", 1); - - OString aBasePath("/primitive2D/sdrrectangle/group/polypolygoncolor"_ostr); - assertXPath(pXmlDoc, aBasePath, "color", u"#729fcf"); - - assertXPath(pXmlDoc, aBasePath + "/polypolygon", "height", - u"99"); // weird Rectangle is created with size 100 - assertXPath(pXmlDoc, aBasePath + "/polypolygon", "width", u"99"); - assertXPath(pXmlDoc, aBasePath + "/polypolygon", "minx", u"0"); - assertXPath(pXmlDoc, aBasePath + "/polypolygon", "miny", u"0"); - assertXPath(pXmlDoc, aBasePath + "/polypolygon", "maxx", u"99"); - assertXPath(pXmlDoc, aBasePath + "/polypolygon", "maxy", u"99"); - - aBasePath = "/primitive2D/sdrrectangle/group/polypolygoncolor/polypolygon/polygon"_ostr; - - assertXPath(pXmlDoc, aBasePath + "/point", 5); - assertXPath(pXmlDoc, aBasePath + "/point[1]", "x", u"49.5"); // hmm, weird, why? - assertXPath(pXmlDoc, aBasePath + "/point[1]", "y", u"99"); - assertXPath(pXmlDoc, aBasePath + "/point[2]", "x", u"0"); - assertXPath(pXmlDoc, aBasePath + "/point[2]", "y", u"99"); - assertXPath(pXmlDoc, aBasePath + "/point[3]", "x", u"0"); - assertXPath(pXmlDoc, aBasePath + "/point[3]", "y", u"0"); - assertXPath(pXmlDoc, aBasePath + "/point[4]", "x", u"99"); - assertXPath(pXmlDoc, aBasePath + "/point[4]", "y", u"0"); - assertXPath(pXmlDoc, aBasePath + "/point[5]", "x", u"99"); - assertXPath(pXmlDoc, aBasePath + "/point[5]", "y", u"99"); - - aBasePath = "/primitive2D/sdrrectangle/group/polygonstroke"_ostr; - assertXPath(pXmlDoc, aBasePath, 1); - - assertXPath(pXmlDoc, aBasePath + "/line", "color", u"#3465a4"); - assertXPath(pXmlDoc, aBasePath + "/line", "width", u"0"); - assertXPath(pXmlDoc, aBasePath + "/line", "linejoin", u"Round"); - assertXPath(pXmlDoc, aBasePath + "/line", "linecap", u"BUTT"); - - assertXPathContent(pXmlDoc, aBasePath + "/polygon", u"49.5,99 0,99 0,0 99,0 99,99"); + tools::XPath aPath(pXmlDoc.get()); + CPPUNIT_ASSERT(aPath.create("/primitive2D")); + + auto aPolyPoly = aPath.create("/primitive2D/sdrrectangle/group/polypolygoncolor"); + CPPUNIT_ASSERT(aPolyPoly); + CPPUNIT_ASSERT_EQUAL(u"#729fcf"_ustr, aPolyPoly->attribute("color")); + + auto aPolyPolyPath = aPath.create(aPolyPoly, "/polypolygon"); + CPPUNIT_ASSERT(aPolyPolyPath); + CPPUNIT_ASSERT_EQUAL(1, aPolyPolyPath->count()); + auto aPolyPolyElement = aPolyPolyPath->at(0); + CPPUNIT_ASSERT_EQUAL(u"99"_ustr, aPolyPolyElement->attribute( + "height")); // weird Rectangle is created with size 100 + CPPUNIT_ASSERT_EQUAL(u"99"_ustr, aPolyPolyElement->attribute("width")); + CPPUNIT_ASSERT_EQUAL(u"0"_ustr, aPolyPolyElement->attribute("minx")); + CPPUNIT_ASSERT_EQUAL(u"0"_ustr, aPolyPolyElement->attribute("miny")); + CPPUNIT_ASSERT_EQUAL(u"99"_ustr, aPolyPolyElement->attribute("maxx")); + CPPUNIT_ASSERT_EQUAL(u"99"_ustr, aPolyPolyElement->attribute("maxy")); + + auto aPolyPath + = aPath.create("/primitive2D/sdrrectangle/group/polypolygoncolor/polypolygon/polygon"); + CPPUNIT_ASSERT(aPolyPath); + auto aPoints = aPath.create(aPolyPath, "/point"); + CPPUNIT_ASSERT_EQUAL(5, aPoints->count()); + CPPUNIT_ASSERT_EQUAL(u"49.5"_ustr, aPoints->at(0)->attribute("x")); + CPPUNIT_ASSERT_EQUAL(u"99"_ustr, aPoints->at(0)->attribute("y")); + CPPUNIT_ASSERT_EQUAL(u"0"_ustr, aPoints->at(1)->attribute("x")); + CPPUNIT_ASSERT_EQUAL(u"99"_ustr, aPoints->at(1)->attribute("y")); + CPPUNIT_ASSERT_EQUAL(u"0"_ustr, aPoints->at(2)->attribute("x")); + CPPUNIT_ASSERT_EQUAL(u"0"_ustr, aPoints->at(2)->attribute("y")); + CPPUNIT_ASSERT_EQUAL(u"99"_ustr, aPoints->at(3)->attribute("x")); + CPPUNIT_ASSERT_EQUAL(u"0"_ustr, aPoints->at(3)->attribute("y")); + CPPUNIT_ASSERT_EQUAL(u"99"_ustr, aPoints->at(4)->attribute("x")); + CPPUNIT_ASSERT_EQUAL(u"99"_ustr, aPoints->at(4)->attribute("y")); + + auto aStrokePath = aPath.create("/primitive2D/sdrrectangle/group/polygonstroke"); + CPPUNIT_ASSERT(aStrokePath); + CPPUNIT_ASSERT_EQUAL(1, aStrokePath->count()); + + auto aLinePath = aPath.create(aStrokePath, "/line"); + CPPUNIT_ASSERT_EQUAL(u"#3465a4"_ustr, aLinePath->attribute("color")); + CPPUNIT_ASSERT_EQUAL(u"0"_ustr, aLinePath->attribute("width")); + CPPUNIT_ASSERT_EQUAL(u"Round"_ustr, aLinePath->attribute("linejoin")); + CPPUNIT_ASSERT_EQUAL(u"BUTT"_ustr, aLinePath->attribute("linecap")); + + auto aLineContentPath = aPath.create(aStrokePath, "/polygon"); + CPPUNIT_ASSERT_EQUAL(u"49.5,99 0,99 0,0 99,0 99,99"_ustr, aLineContentPath->content()); // If solid line, then there is no line stroke information - assertXPath(pXmlDoc, aBasePath + "/stroke", 0); + CPPUNIT_ASSERT_EQUAL(0, aPath.create(aStrokePath, "/stroke")->count()); pPage->RemoveObject(0); } @@ -402,14 +414,19 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testFontWorks) SdrPage* pSdrPage = pDrawPage->GetSdrPage(); xmlDocUniquePtr pXmlDoc = lcl_dumpAndParseFirstObjectWithAssert(pSdrPage); - assertXPath(pXmlDoc, "/primitive2D", 1); + tools::XPath aXPath(pXmlDoc.get()); + CPPUNIT_ASSERT_EQUAL(1, aXPath.create("/primitive2D")->count()); + CPPUNIT_ASSERT_EQUAL(u"Perspective"_ustr, + aXPath.create("//scene")->attribute("projectionMode")); + + auto aFillPath = aXPath.create("//scene/extrude3D[1]/fill"); + CPPUNIT_ASSERT_EQUAL(u"#ff0000"_ustr, aFillPath->attribute("color")); + + auto aMaterialPath = aXPath.create("//scene/extrude3D[1]/object3Dattributes/material"); + CPPUNIT_ASSERT_EQUAL(u"#ff0000"_ustr, aMaterialPath->attribute("color")); - assertXPath(pXmlDoc, "//scene", "projectionMode", u"Perspective"); - assertXPath(pXmlDoc, "//scene/extrude3D[1]/fill", "color", u"#ff0000"); - assertXPath(pXmlDoc, "//scene/extrude3D[1]/object3Dattributes/material", "color", u"#ff0000"); // ODF default 50% is represented by Specular Intensity = 2^5. The relationship is not linear. - assertXPath(pXmlDoc, "//scene/extrude3D[1]/object3Dattributes/material", "specularIntensity", - u"32"); + CPPUNIT_ASSERT_EQUAL(u"32"_ustr, aMaterialPath->attribute("specularIntensity")); } CPPUNIT_TEST_FIXTURE(SvdrawTest, testTdf148000_EOLinCurvedText) @@ -425,16 +442,18 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testTdf148000_EOLinCurvedText) SdrPage* pSdrPage = getFirstDrawPageWithAssert(); xmlDocUniquePtr pXmlDoc = lcl_dumpAndParseFirstObjectWithAssert(pSdrPage); + tools::XPath aXPath(pXmlDoc.get()); // this is a group shape, hence 2 nested objectinfo - OString aBasePath = "/primitive2D/objectinfo[4]/objectinfo/unhandled/group/unhandled/group/" - "polypolygoncolor/polypolygon/"_ostr; + auto aBasePath = aXPath.create("/primitive2D/objectinfo[4]/objectinfo/unhandled/group/" + "unhandled/group/polypolygoncolor/polypolygon"); // The text is: "O" + eop + "O" + eol + "O" // It should be displayed as 3 line of text. (1 "O" letter in every line) - sal_Int32 nY1 = getXPath(pXmlDoc, aBasePath + "polygon[1]/point[1]", "y").toInt32(); - sal_Int32 nY2 = getXPath(pXmlDoc, aBasePath + "polygon[3]/point[1]", "y").toInt32(); - sal_Int32 nY3 = getXPath(pXmlDoc, aBasePath + "polygon[5]/point[1]", "y").toInt32(); + + sal_Int32 nY1 = aXPath.create(aBasePath, "/polygon[1]/point[1]")->attribute("y").toInt32(); + sal_Int32 nY2 = aXPath.create(aBasePath, "/polygon[3]/point[1]")->attribute("y").toInt32(); + sal_Int32 nY3 = aXPath.create(aBasePath, "/polygon[5]/point[1]")->attribute("y").toInt32(); sal_Int32 nDiff21 = nY2 - nY1; sal_Int32 nDiff32 = nY3 - nY2; @@ -468,16 +487,17 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testTdf148000_CurvedTextWidth) SdrPage* pSdrPage = getFirstDrawPageWithAssert(); xmlDocUniquePtr pXmlDoc = lcl_dumpAndParseFirstObjectWithAssert(pSdrPage); + tools::XPath aXPath(pXmlDoc.get()); - OString aBasePath = "/primitive2D/objectinfo[4]/objectinfo/unhandled/group/unhandled/group/" - "polypolygoncolor/polypolygon/"_ostr; + auto aBasePath = aXPath.create("/primitive2D/objectinfo[4]/objectinfo/unhandled/group/" + "unhandled/group/polypolygoncolor/polypolygon"); // The text is: 7 line od "OOOOOOO" // Take the x coord of the 4 "O" on the corners - sal_Int32 nX1 = getXPath(pXmlDoc, aBasePath + "polygon[1]/point[1]", "x").toInt32(); - sal_Int32 nX2 = getXPath(pXmlDoc, aBasePath + "polygon[13]/point[1]", "x").toInt32(); - sal_Int32 nX3 = getXPath(pXmlDoc, aBasePath + "polygon[85]/point[1]", "x").toInt32(); - sal_Int32 nX4 = getXPath(pXmlDoc, aBasePath + "polygon[97]/point[1]", "x").toInt32(); + sal_Int32 nX1 = aXPath.create(aBasePath, "/polygon[1]/point[1]")->attribute("x").toInt32(); + sal_Int32 nX2 = aXPath.create(aBasePath, "/polygon[13]/point[1]")->attribute("x").toInt32(); + sal_Int32 nX3 = aXPath.create(aBasePath, "/polygon[85]/point[1]")->attribute("x").toInt32(); + sal_Int32 nX4 = aXPath.create(aBasePath, "/polygon[97]/point[1]")->attribute("x").toInt32(); if (i < 2) { diff --git a/tools/CppunitTest_tools_test.mk b/tools/CppunitTest_tools_test.mk index c2087bcde594..f5422b78e74f 100644 --- a/tools/CppunitTest_tools_test.mk +++ b/tools/CppunitTest_tools_test.mk @@ -11,8 +11,6 @@ $(eval $(call gb_CppunitTest_CppunitTest,tools_test)) -$(eval $(call gb_CppunitTest_use_external,tools_test,boost_headers)) - $(eval $(call gb_CppunitTest_add_exception_objects,tools_test, \ tools/qa/cppunit/test_bigint \ tools/qa/cppunit/test_date \ @@ -31,6 +29,7 @@ $(eval $(call gb_CppunitTest_add_exception_objects,tools_test, \ tools/qa/cppunit/test_100mm2twips \ tools/qa/cppunit/test_xmlwalker \ tools/qa/cppunit/test_xmlwriter \ + tools/qa/cppunit/test_xpath \ tools/qa/cppunit/test_GenericTypeSerializer \ tools/qa/cppunit/test_guid \ tools/qa/cppunit/test_cpuid \ @@ -53,6 +52,11 @@ $(eval $(call gb_CppunitTest_add_exception_objects,tools_test,\ tools/qa/cppunit/test_cpu_runtime_detection_SSSE3_check, $(CXXFLAGS_INTRINSICS_SSSE3) \ )) +$(eval $(call gb_CppunitTest_use_externals,tools_test, \ + boost_headers \ + libxml2 \ +)) + $(eval $(call gb_CppunitTest_use_sdk_api,tools_test)) $(eval $(call gb_CppunitTest_use_libraries,tools_test, \ @@ -75,8 +79,4 @@ $(eval $(call gb_CppunitTest_set_include,tools_test,\ -I$(SRCDIR)/tools/inc \ )) -$(eval $(call gb_Library_use_externals,tools_test,\ - libxml2 \ -)) - # vim: set noet sw=4 ts=4: diff --git a/tools/Library_tl.mk b/tools/Library_tl.mk index b82c065bdeef..5c3a7e453137 100644 --- a/tools/Library_tl.mk +++ b/tools/Library_tl.mk @@ -83,6 +83,7 @@ $(eval $(call gb_Library_add_exception_objects,tl,\ tools/source/zcodec/zcodec \ tools/source/xml/XmlWriter \ tools/source/xml/XmlWalker \ + tools/source/xml/XPath \ )) ifneq ($(SYSTEM_LIBFIXMATH),TRUE) diff --git a/tools/qa/cppunit/test_xpath.cxx b/tools/qa/cppunit/test_xpath.cxx new file mode 100644 index 000000000000..3cbc29c90ff8 --- /dev/null +++ b/tools/qa/cppunit/test_xpath.cxx @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * 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/. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <test/bootstrapfixture.hxx> +#include <rtl/ustring.hxx> +#include <tools/stream.hxx> +#include <tools/XPath.hxx> + +namespace +{ +class XPathTest : public test::BootstrapFixture +{ + OUString maBasePath; + +public: + XPathTest() + : BootstrapFixture(true, false) + { + } + + virtual void setUp() override { maBasePath = m_directories.getURLFromSrc(u"/tools/qa/data/"); } + + void testXPath() + { + OUString aXmlFilePath = maBasePath + "test.xml"; + SvFileStream aFileStream(aXmlFilePath, StreamMode::READ); + std::size_t nSize = aFileStream.remainingSize(); + std::unique_ptr<sal_uInt8[]> pBuffer(new sal_uInt8[nSize + 1]); + pBuffer[nSize] = 0; + aFileStream.ReadBytes(pBuffer.get(), nSize); + auto pCharBuffer = reinterpret_cast<xmlChar*>(pBuffer.get()); + xmlDocPtr pXmlDoc + = xmlReadDoc(pCharBuffer, nullptr, nullptr, XML_PARSE_NODICT | XML_PARSE_HUGE); + + tools::XPath aXPath(pXmlDoc); + auto aNonExistentPath = aXPath.create("/nonexistent"); + CPPUNIT_ASSERT(aNonExistentPath); + CPPUNIT_ASSERT_EQUAL(0, aNonExistentPath->count()); + + auto aRootResult = aXPath.create("/root"); + CPPUNIT_ASSERT(aRootResult); + CPPUNIT_ASSERT_EQUAL(1, aRootResult->count()); + CPPUNIT_ASSERT_EQUAL(u"Hello World"_ustr, aRootResult->attribute("root-attr")); + { + auto aRootElement = aRootResult->at(0); + CPPUNIT_ASSERT_EQUAL(std::string_view("root"), aRootElement->name()); + CPPUNIT_ASSERT_EQUAL(4, aRootElement->countChildren()); + CPPUNIT_ASSERT_EQUAL(std::string_view("child"), aRootElement->at(0)->name()); + CPPUNIT_ASSERT_EQUAL(std::string_view("child"), aRootElement->at(1)->name()); + CPPUNIT_ASSERT_EQUAL(std::string_view("child"), aRootElement->at(2)->name()); + CPPUNIT_ASSERT_EQUAL(std::string_view("with-namespace"), aRootElement->at(3)->name()); + } + + auto aChildResult = aXPath.create(aRootResult, "/child"); + CPPUNIT_ASSERT(aChildResult); + CPPUNIT_ASSERT_EQUAL(3, aChildResult->count()); + + auto aChildElement = aChildResult->at(0); + CPPUNIT_ASSERT_EQUAL(std::string_view("child"), aChildElement->name()); + CPPUNIT_ASSERT_EQUAL(u"1"_ustr, aChildElement->attribute("number")); + CPPUNIT_ASSERT_EQUAL(u"123"_ustr, aChildElement->attribute("attribute")); + + auto aGrandChildElement = aChildElement->at(0); + CPPUNIT_ASSERT(aGrandChildElement); + CPPUNIT_ASSERT_EQUAL(std::string_view("grandchild"), aGrandChildElement->name()); + + CPPUNIT_ASSERT_EQUAL(u"2"_ustr, aChildResult->at(1)->attribute("number")); + CPPUNIT_ASSERT_EQUAL(u"3"_ustr, aChildResult->at(2)->attribute("number")); + + auto aGrandChildResult = aXPath.create(aRootResult, "/child[1]/grandchild"); + CPPUNIT_ASSERT(aGrandChildResult); + CPPUNIT_ASSERT_EQUAL(1, aGrandChildResult->count()); + CPPUNIT_ASSERT_EQUAL(u"Content"_ustr, aGrandChildResult->content()); + CPPUNIT_ASSERT_EQUAL(u"ABC"_ustr, aGrandChildResult->attribute("attribute1")); + CPPUNIT_ASSERT_EQUAL(u"CDE"_ustr, aGrandChildResult->attribute("attribute2")); + + xmlFreeDoc(pXmlDoc); + } + + CPPUNIT_TEST_SUITE(XPathTest); + CPPUNIT_TEST(testXPath); + CPPUNIT_TEST_SUITE_END(); +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(XPathTest); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/tools/source/xml/XPath.cxx b/tools/source/xml/XPath.cxx new file mode 100644 index 000000000000..06400cfbae0e --- /dev/null +++ b/tools/source/xml/XPath.cxx @@ -0,0 +1,197 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * 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/. + */ + +#include <tools/XPath.hxx> + +namespace tools +{ +namespace +{ +OUString convert(xmlChar const* sXmlString) +{ + OUString sString; + rtl_convertStringToUString(&sString.pData, reinterpret_cast<char const*>(sXmlString), + xmlStrlen(sXmlString), RTL_TEXTENCODING_UTF8, + RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR + | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR + | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR); + return sString; +} +} + +std::string_view XmlElement::name() { return reinterpret_cast<const char*>(mpXmlNode->name); } + +OUString XmlElement::attribute(const char* pAttribute) +{ + OUString sString; + + xmlChar* pProperty = xmlGetProp(mpXmlNode, BAD_CAST(pAttribute)); + if (pProperty) + { + sString = convert(pProperty); + xmlFree(pProperty); + } + return sString; +} + +sal_Int32 XmlElement::countChildren() { return sal_Int32(xmlChildElementCount(mpXmlNode)); } + +std::unique_ptr<XmlElement> XmlElement::at(sal_Int32 nIndex) +{ + sal_Int32 nCurrent = 0; + xmlNodePtr pCurrent = xmlFirstElementChild(mpXmlNode); + + while (pCurrent != nullptr && nCurrent < nIndex) + { + pCurrent = xmlNextElementSibling(pCurrent); + nCurrent++; + } + + if (pCurrent) + return std::make_unique<XmlElement>(pCurrent); + return {}; +} + +XPath::XPath(xmlDocPtr pDocPtr) + : XPath(pDocPtr, [](xmlXPathContextPtr) {}) +{ +} + +XPath::XPath(xmlDocPtr pDocPtr, std::function<void(xmlXPathContextPtr)> funcRegisterNamespaces) + : mpXmlDocPtr(pDocPtr) + , mFuncRegisterNamespaces(funcRegisterNamespaces) +{ +} + +std::unique_ptr<XPathObject> XPath::create(std::string_view aString) +{ + OString aCopy(aString); + xmlXPathContextPtr pXPathContext = xmlXPathNewContext(mpXmlDocPtr); + mFuncRegisterNamespaces(pXPathContext); + xmlXPathObjectPtr pXPathObject + = xmlXPathEvalExpression(BAD_CAST(aCopy.getStr()), pXPathContext); + xmlXPathFreeContext(pXPathContext); + + if (!pXPathObject) + return {}; + + if (!pXPathObject->nodesetval) + { + xmlXPathFreeObject(pXPathObject); + return {}; + } + + return std::make_unique<XPathObject>(pXPathObject, aString); +} + +std::unique_ptr<XPathObject> XPath::create(std::unique_ptr<XPathObject> const& pPathObject, + std::string_view aString) +{ + return create(Concat2View(pPathObject->getPathString() + OString::Concat(aString))); +} + +XPathObject::XPathObject(xmlXPathObjectPtr pXPathObject, std::string_view aString) + : mpXPathObject(pXPathObject) + , maPath(aString) +{ +} + +XPathObject::~XPathObject() +{ + if (mpXPathObject) + xmlXPathFreeObject(mpXPathObject); +} + +sal_Int32 XPathObject::count() +{ + if (!mpXPathObject) + return 0; + + xmlNodeSetPtr pXmlNodes = mpXPathObject->nodesetval; + if (!pXmlNodes) + return 0; + + return xmlXPathNodeSetGetLength(pXmlNodes); +} + +OUString XPathObject::attribute(const char* pAttribute) +{ + auto pXmlElement = at(0); + if (!pXmlElement) + return OUString(); + + return pXmlElement->attribute(pAttribute); +} + +std::unique_ptr<XmlElement> XPathObject::at(sal_Int32 nIndex) +{ + if (!mpXPathObject) + return {}; + + if (nIndex >= count()) + return {}; + + xmlNodeSetPtr pXmlNodes = mpXPathObject->nodesetval; + if (!pXmlNodes) + return {}; + + xmlNodePtr pXmlNode = pXmlNodes->nodeTab[nIndex]; + return std::make_unique<XmlElement>(pXmlNode); +} + +OUString XPathObject::content() +{ + OUString sError; + if (!mpXPathObject) + return sError; + + switch (mpXPathObject->type) + { + case XPATH_NODESET: + { + xmlNodeSetPtr pXmlNodes = mpXPathObject->nodesetval; + if (count() != 1) + return sError; + + xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0]; + return convert(xmlNodeGetContent(pXmlNode)); + } + case XPATH_BOOLEAN: + { + auto bBoolVal = mpXPathObject->boolval; + return bBoolVal ? u"true"_ustr : u"false"_ustr; + } + case XPATH_NUMBER: + { + auto floatVal = mpXPathObject->floatval; + return OUString::number(floatVal); + } + case XPATH_STRING: + { + return convert(mpXPathObject->stringval); + } + + case XPATH_UNDEFINED: + // Undefined XPath type +#if LIBXML_VERSION < 21000 || defined(LIBXML_XPTR_LOCS_ENABLED) + case XPATH_POINT: + case XPATH_RANGE: + case XPATH_LOCATIONSET: +#endif + case XPATH_USERS: + case XPATH_XSLT_TREE: + // Unsupported XPath type + break; + } + return sError; +} + +} // end tools namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 1365e0194db3faa8a68c529715d75634ae76e78d Author: Tomaž Vajngerl <[email protected]> AuthorDate: Wed Dec 17 10:24:04 2025 +0900 Commit: Tomaž Vajngerl <[email protected]> CommitDate: Mon Feb 23 13:03:00 2026 +0100 sd: cleanup creation of default stlyesheets Change-Id: I02105e1f3d319cb52339030615fd7e2e72e7bd11 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195757 Reviewed-by: Tomaž Vajngerl <[email protected]> Tested-by: Jenkins Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200017 Tested-by: Jenkins CollaboraOffice <[email protected]> diff --git a/sd/source/core/drawdoc4.cxx b/sd/source/core/drawdoc4.cxx index 795561d8eb36..543417cc3bfb 100644 --- a/sd/source/core/drawdoc4.cxx +++ b/sd/source/core/drawdoc4.cxx @@ -128,6 +128,13 @@ using namespace ::com::sun::star::style; using namespace ::com::sun::star::linguistic2; using namespace ::sd; +namespace +{ +template <typename N> constexpr auto pointsToHMM(N number) +{ + return o3tl::convert(number, o3tl::Length::pt, o3tl::Length::mm100); +}} + // CreateLayoutTemplates // At the moment (31.03.1995), the StyleSheetPool only saves styleheets that // have an ItemSet. To save all stylesheets, we force the creation of an ItemSet @@ -135,10 +142,10 @@ using namespace ::sd; // We can remove this behavior once the pool saves styleheets even without an ItemSet void SdDrawDocument::CreateLayoutTemplates() { - SdStyleSheetPool* pSSPool = static_cast<SdStyleSheetPool*>(GetStyleSheetPool()); - SfxStyleSheetBase* pSheet = nullptr; - const OUString aHelpFile; - OUString aStdName(SdResId(STR_STANDARD_STYLESHEET_NAME)); + SdStyleSheetPool* pSSPool = static_cast<SdStyleSheetPool*>(GetStyleSheetPool()); + SfxStyleSheetBase* pSheet = nullptr; + const OUString aHelpFile; + OUString aStdName(SdResId(STR_STANDARD_STYLESHEET_NAME)); // Default style @@ -146,21 +153,18 @@ void SdDrawDocument::CreateLayoutTemplates() OUString aName(aStdName); pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); - pSheet->SetHelpId( aHelpFile, HID_STANDARD_STYLESHEET_NAME ); + pSheet->SetHelpId(aHelpFile, HID_STANDARD_STYLESHEET_NAME); SfxItemSet& rISet = pSheet->GetItemSet(); - Color aNullCol(COL_DEFAULT_SHAPE_STROKE); + Color aNullCol(COL_DEFAULT_SHAPE_STROKE); - XDash aNullDash; - basegfx::BGradient aNullGrad( - basegfx::BColorStops( - aNullCol.getBColor(), - COL_WHITE.getBColor())); - aNullGrad.SetStartIntens( 100 ); - aNullGrad.SetEndIntens( 100 ); - XHatch aNullHatch(aNullCol); + XDash aNullDash; + basegfx::BGradient aNullGrad(basegfx::BColorStops(aNullCol.getBColor(), COL_WHITE.getBColor())); + aNullGrad.SetStartIntens(100); + aNullGrad.SetEndIntens(100); + XHatch aNullHatch(aNullCol); - // Line attributes (Extended OutputDevice) + // Line attributes (Extended OutputDevice) rISet.Put(XLineStyleItem(drawing::LineStyle_SOLID)); rISet.Put(XLineColorItem(OUString(), COL_DEFAULT_SHAPE_STROKE)); rISet.Put(XLineWidthItem(0)); @@ -173,51 +177,54 @@ void SdDrawDocument::CreateLayoutTemplates() rISet.Put(XLineEndCenterItem()); rISet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_BLOCK)); - // Fill attributes (Extended OutputDevice) + // Fill attributes (Extended OutputDevice) rISet.Put(XFillStyleItem(drawing::FillStyle_SOLID)); rISet.Put(XFillColorItem(OUString(), COL_DEFAULT_SHAPE_FILLING)); - rISet.Put( XFillGradientItem( aNullGrad) ); + rISet.Put(XFillGradientItem(aNullGrad)); rISet.Put(XFillHatchItem(aNullHatch)); - Size aNullSize( 32, 32 ); + Size aNullSize(32, 32); Bitmap aNullBmp(aNullSize, vcl::PixelFormat::N8_BPP); - aNullBmp.Erase( COL_WHITE ); + aNullBmp.Erase(COL_WHITE); rISet.Put(XFillBitmapItem(Graphic(aNullBmp))); - // Shadow attributes (Drawing Engine) + // Shadow attributes (Drawing Engine) rISet.Put(makeSdrShadowItem(false)); rISet.Put(makeSdrShadowColorItem(COL_GRAY)); - rISet.Put(makeSdrShadowXDistItem(200)); // 3 mm Shadow distance + rISet.Put(makeSdrShadowXDistItem(200)); // 2 mm Shadow distance rISet.Put(makeSdrShadowYDistItem(200)); vcl::Font aLatinFont, aCJKFont, aCTLFont; - getDefaultFonts( aLatinFont, aCJKFont, aCTLFont ); + getDefaultFonts(aLatinFont, aCJKFont, aCTLFont); - SvxFontItem aSvxFontItem( aLatinFont.GetFamilyTypeMaybeAskConfig(), aLatinFont.GetFamilyName(), aLatinFont.GetStyleName(), aLatinFont.GetPitchMaybeAskConfig(), - aLatinFont.GetCharSet(), EE_CHAR_FONTINFO ); + SvxFontItem aSvxFontItem(aLatinFont.GetFamilyType(), aLatinFont.GetFamilyName(), + aLatinFont.GetStyleName(), aLatinFont.GetPitch(), + aLatinFont.GetCharSet(), EE_CHAR_FONTINFO); - SvxFontItem aSvxFontItemCJK( aCJKFont.GetFamilyTypeMaybeAskConfig(), aCJKFont.GetFamilyName(), aCJKFont.GetStyleName(), aCJKFont.GetPitchMaybeAskConfig(), - aCJKFont.GetCharSet(), EE_CHAR_FONTINFO_CJK ); + SvxFontItem aSvxFontItemCJK(aCJKFont.GetFamilyType(), aCJKFont.GetFamilyName(), + aCJKFont.GetStyleName(), aCJKFont.GetPitch(), + aCJKFont.GetCharSet(), EE_CHAR_FONTINFO_CJK); - SvxFontItem aSvxFontItemCTL( aCTLFont.GetFamilyTypeMaybeAskConfig(), aCTLFont.GetFamilyName(), aCTLFont.GetStyleName(), aCTLFont.GetPitchMaybeAskConfig(), - aCTLFont.GetCharSet(), EE_CHAR_FONTINFO_CTL ); + SvxFontItem aSvxFontItemCTL(aCTLFont.GetFamilyType(), aCTLFont.GetFamilyName(), + aCTLFont.GetStyleName(), aCTLFont.GetPitch(), + aCTLFont.GetCharSet(), EE_CHAR_FONTINFO_CTL); - rISet.Put( aSvxFontItem ); - rISet.Put( aSvxFontItemCJK ); - rISet.Put( aSvxFontItemCTL ); + rISet.Put(aSvxFontItem); + rISet.Put(aSvxFontItemCJK); + rISet.Put(aSvxFontItemCTL); - rISet.Put( SvxFontHeightItem( 635, 100, EE_CHAR_FONTHEIGHT ) ); // sj: (i33745) changed default from 24 to 18 pt - rISet.Put( SvxFontHeightItem( 635, 100, EE_CHAR_FONTHEIGHT_CJK ) ); // 18 pt - rISet.Put( SvxFontHeightItem( convertFontHeightToCTL( 635 ), 100, EE_CHAR_FONTHEIGHT_CTL ) ); // 18 pt + rISet.Put(SvxFontHeightItem(pointsToHMM(18), 100, EE_CHAR_FONTHEIGHT)); // sj: (i33745) changed default from 24 to 18 pt + rISet.Put(SvxFontHeightItem(pointsToHMM(18), 100, EE_CHAR_FONTHEIGHT_CJK)); // 18 pt + rISet.Put(SvxFontHeightItem(convertFontHeightToCTL(pointsToHMM(18)), 100, EE_CHAR_FONTHEIGHT_CTL)); // 18 pt - rISet.Put( SvxWeightItem( WEIGHT_NORMAL, EE_CHAR_WEIGHT ) ); - rISet.Put( SvxWeightItem( WEIGHT_NORMAL, EE_CHAR_WEIGHT_CJK ) ); - rISet.Put( SvxWeightItem( WEIGHT_NORMAL, EE_CHAR_WEIGHT_CTL ) ); + rISet.Put(SvxWeightItem(WEIGHT_NORMAL, EE_CHAR_WEIGHT)); + rISet.Put(SvxWeightItem(WEIGHT_NORMAL, EE_CHAR_WEIGHT_CJK)); + rISet.Put(SvxWeightItem(WEIGHT_NORMAL, EE_CHAR_WEIGHT_CTL)); - rISet.Put( SvxPostureItem( ITALIC_NONE, EE_CHAR_ITALIC ) ); - rISet.Put( SvxPostureItem( ITALIC_NONE, EE_CHAR_ITALIC_CJK ) ); - rISet.Put( SvxPostureItem( ITALIC_NONE, EE_CHAR_ITALIC_CTL ) ); + rISet.Put(SvxPostureItem(ITALIC_NONE, EE_CHAR_ITALIC)); + rISet.Put(SvxPostureItem(ITALIC_NONE, EE_CHAR_ITALIC_CJK)); + rISet.Put(SvxPostureItem(ITALIC_NONE, EE_CHAR_ITALIC_CTL)); rISet.Put(SvxContourItem(false, EE_CHAR_OUTLINE )); rISet.Put(SvxShadowedItem(false, EE_CHAR_SHADOW )); @@ -227,43 +234,43 @@ void SdDrawDocument::CreateLayoutTemplates() rISet.Put(SvxCaseMapItem(SvxCaseMap::NotMapped, EE_CHAR_CASEMAP )); rISet.Put(SvxEmphasisMarkItem(FontEmphasisMark::NONE, EE_CHAR_EMPHASISMARK)); rISet.Put(SvxCharReliefItem(FontRelief::NONE, EE_CHAR_RELIEF)); - rISet.Put(SvxColorItem(COL_AUTO, EE_CHAR_COLOR )); + rISet.Put(SvxColorItem(COL_AUTO, EE_CHAR_COLOR)); // Paragraph attributes (Edit Engine) rISet.Put(SvxLRSpaceItem(EE_PARA_LRSPACE)); rISet.Put(SvxULSpaceItem(EE_PARA_ULSPACE)); - rISet.Put( makeSdrTextLeftDistItem( 250 ) ); // sj: (i33745) using text frame distances seems to be a better default - rISet.Put( makeSdrTextRightDistItem( 250 ) ); - rISet.Put( makeSdrTextUpperDistItem( 125 ) ); - rISet.Put( makeSdrTextLowerDistItem( 125 ) ); + rISet.Put(makeSdrTextLeftDistItem(250)); // sj: (i33745) using text frame distances seems to be a better default + rISet.Put(makeSdrTextRightDistItem(250)); + rISet.Put(makeSdrTextUpperDistItem(125)); + rISet.Put(makeSdrTextLowerDistItem(125)); // Set Word-wrap to true by default - rISet.Put( makeSdrTextWordWrapItem(true) ); + rISet.Put(makeSdrTextWordWrapItem(true)); - rISet.Put( SvxLineSpacingItem( LINE_SPACE_DEFAULT_HEIGHT, EE_PARA_SBL ) ); + rISet.Put(SvxLineSpacingItem(LINE_SPACE_DEFAULT_HEIGHT, EE_PARA_SBL)); // #i16874# enable kerning by default but only for new documents - rISet.Put( SvxAutoKernItem( true, EE_CHAR_PAIRKERNING ) ); + rISet.Put(SvxAutoKernItem(true, EE_CHAR_PAIRKERNING)); // Bullet // BulletItem and BulletFont for title and outline SvxBulletItem aBulletItem(EE_PARA_BULLET); - // Identical in all layers + // Identical in all layers aBulletItem.SetStyle(SvxBulletStyle::BULLET); aBulletItem.SetStart(1); - aBulletItem.SetScale(45); // In percent + aBulletItem.SetScale(45); // In percent - vcl::Font aBulletFont( SdStyleSheetPool::GetBulletFont() ); + vcl::Font aBulletFont(SdStyleSheetPool::GetBulletFont()); - aBulletFont.SetFontSize(Size(0,635)); // sj: (i33745) changed default from 24 to 18 pt + aBulletFont.SetFontSize(Size(0, pointsToHMM(18))); // sj: (i33745) changed default from 24 to 18 pt aBulletItem.SetFont(aBulletFont); - aBulletItem.SetSymbol( 0x25CF ); // In points + aBulletItem.SetSymbol(0x25CF); // In points rISet.Put(aBulletItem); // New BulletItem - SdStyleSheetPool::PutNumBulletItem( pSheet, aBulletFont ); + SdStyleSheetPool::PutNumBulletItem(pSheet, aBulletFont); SfxItemSet* pISet = nullptr; @@ -296,53 +303,53 @@ void SdDrawDocument::CreateLayoutTemplates() { aTextName = SdResId(STR_POOLSHEET_TEXT); pSheet = &(pSSPool->Make(aTextName, SfxStyleFamily::Para, nMask)); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_TEXT ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_TEXT); pISet = &pSheet->GetItemSet(); aSvxFontItem.SetFamilyName(u"Noto Sans"_ustr); - pISet->Put( aSvxFontItem ); // Noto Sans - pISet->Put(XFillStyleItem(drawing::FillStyle_SOLID)); // solid fill - pISet->Put(XFillColorItem(OUString(), Color(0xeeeeee))); // light gray 5 - pISet->Put(XLineStyleItem(drawing::LineStyle_SOLID)); // solid fill - pISet->Put(XLineColorItem(OUString(), Color(0xcccccc))); // light gray 3 + pISet->Put(aSvxFontItem); + pISet->Put(XFillStyleItem(drawing::FillStyle_SOLID)); // solid fill + pISet->Put(XFillColorItem(OUString(), Color(0xeeeeee))); // light gray 5 + pISet->Put(XLineStyleItem(drawing::LineStyle_SOLID)); // solid fill + pISet->Put(XLineColorItem(OUString(), Color(0xcccccc))); // light gray 3 } // Text > A4 OUString aA4Name; { aA4Name = SdResId(STR_POOLSHEET_A4); pSheet = &(pSSPool->Make(aA4Name, SfxStyleFamily::Para, nMask)); - pSheet->SetParent( aTextName ); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_A4 ); + pSheet->SetParent(aTextName); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_A4); pISet = &pSheet->GetItemSet(); - pISet->Put(SvxFontHeightItem(635, 100, EE_CHAR_FONTHEIGHT )); // 18 pt - pISet->Put(XFillStyleItem(drawing::FillStyle_NONE)); // no filling + pISet->Put(SvxFontHeightItem(pointsToHMM(18), 100, EE_CHAR_FONTHEIGHT)); // 18 pt + pISet->Put(XFillStyleItem(drawing::FillStyle_NONE)); // no filling } // Text > A4 > Title { aName = SdResId(STR_POOLSHEET_A4_TITLE); pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); - pSheet->SetParent( aA4Name ); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_A4_TITLE ); + pSheet->SetParent(aA4Name); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_A4_TITLE); pISet = &pSheet->GetItemSet(); - pISet->Put(SvxFontHeightItem(1551, 100, EE_CHAR_FONTHEIGHT )); // 44 pt - pISet->Put(XLineStyleItem(drawing::LineStyle_NONE)); // no border + pISet->Put(SvxFontHeightItem(pointsToHMM(44), 100, EE_CHAR_FONTHEIGHT)); // 44 pt + pISet->Put(XLineStyleItem(drawing::LineStyle_NONE)); // no border } // Text > A4 > Headline { aName = SdResId(STR_POOLSHEET_A4_HEADLINE); pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); - pSheet->SetParent( aA4Name ); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_A4_HEADLINE ); + pSheet->SetParent(aA4Name); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_A4_HEADLINE); pISet = &pSheet->GetItemSet(); - pISet->Put(SvxFontHeightItem(847, 100, EE_CHAR_FONTHEIGHT )); // 24 pt - pISet->Put(XLineStyleItem(drawing::LineStyle_NONE)); // no border + pISet->Put(SvxFontHeightItem(pointsToHMM(24), 100, EE_CHAR_FONTHEIGHT)); // 24 pt + pISet->Put(XLineStyleItem(drawing::LineStyle_NONE)); // no border } // Text > A4 > Text { aName = SdResId(STR_POOLSHEET_A4_TEXT); pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); pSheet->SetParent(aA4Name); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_A4_TEXT ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_A4_TEXT); pISet = &pSheet->GetItemSet(); pISet->Put(XLineStyleItem(drawing::LineStyle_NONE)); // no border } @@ -352,39 +359,39 @@ void SdDrawDocument::CreateLayoutTemplates() aA0Name = SdResId(STR_POOLSHEET_A0); pSheet = &(pSSPool->Make(aA0Name, SfxStyleFamily::Para, nMask)); pSheet->SetParent(aTextName); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_A0 ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_A0); pISet = &pSheet->GetItemSet(); - pISet->Put(SvxFontHeightItem(1692, 100, EE_CHAR_FONTHEIGHT )); // 48 pt - pISet->Put(XFillStyleItem(drawing::FillStyle_NONE)); // no filling + pISet->Put(SvxFontHeightItem(pointsToHMM(48), 100, EE_CHAR_FONTHEIGHT)); // 48 pt + pISet->Put(XFillStyleItem(drawing::FillStyle_NONE)); // no filling } // Text > A0 > Title { aName = SdResId(STR_POOLSHEET_A0_TITLE); pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); pSheet->SetParent(aA0Name); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_A0_TITLE ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_A0_TITLE); pISet = &pSheet->GetItemSet(); - pISet->Put(SvxFontHeightItem(3385, 100, EE_CHAR_FONTHEIGHT )); // 96 pt - pISet->Put(XLineStyleItem(drawing::LineStyle_NONE)); // no border + pISet->Put(SvxFontHeightItem(pointsToHMM(96), 100, EE_CHAR_FONTHEIGHT )); // 96 pt + pISet->Put(XLineStyleItem(drawing::LineStyle_NONE)); // no border } // Text > A0 > Headline { aName = SdResId(STR_POOLSHEET_A0_HEADLINE); pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); pSheet->SetParent(aA0Name); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_A0_HEADLINE ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_A0_HEADLINE); pISet = &pSheet->GetItemSet(); - pISet->Put(SvxFontHeightItem(2538, 100, EE_CHAR_FONTHEIGHT )); // 72 pt - pISet->Put(XLineStyleItem(drawing::LineStyle_NONE)); // no border + pISet->Put(SvxFontHeightItem(pointsToHMM(72), 100, EE_CHAR_FONTHEIGHT )); // 72 pt + pISet->Put(XLineStyleItem(drawing::LineStyle_NONE)); // no border } // Text > A0 > Text { aName = SdResId(STR_POOLSHEET_A0_TEXT); pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); pSheet->SetParent(aA0Name); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_A0_TEXT ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_A0_TEXT); pISet = &pSheet->GetItemSet(); - pISet->Put(XLineStyleItem(drawing::LineStyle_NONE)); // no border + pISet->Put(XLineStyleItem(drawing::LineStyle_NONE)); // no border } // Graphic @@ -395,13 +402,13 @@ void SdDrawDocument::CreateLayoutTemplates() { aGraphicName = SdResId(STR_POOLSHEET_GRAPHIC); pSheet = &(pSSPool->Make(aGraphicName, SfxStyleFamily::Para, nMask)); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_GRAPHIC ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_GRAPHIC); pISet = &pSheet->GetItemSet(); - aSvxFontItem.SetFamilyName(u"Liberation Sans"_ustr); // Liberation Sans - pISet->Put( aSvxFontItem ); - pISet->Put( SvxFontHeightItem(635, 100, EE_CHAR_FONTHEIGHT) ); // 18 pt - pISet->Put( XFillStyleItem(drawing::FillStyle_SOLID) ); // solid fill - pISet->Put( XFillColorItem(OUString(), COL_WHITE) ); // filled white + aSvxFontItem.SetFamilyName(u"Liberation Sans"_ustr); // Liberation Sans + pISet->Put(aSvxFontItem); + pISet->Put(SvxFontHeightItem(pointsToHMM(18), 100, EE_CHAR_FONTHEIGHT)); // 18 pt + pISet->Put(XFillStyleItem(drawing::FillStyle_SOLID)); // solid fill + pISet->Put(XFillColorItem(OUString(), COL_WHITE)); // filled white } // Graphic > Shapes @@ -409,90 +416,90 @@ void SdDrawDocument::CreateLayoutTemplates() { aShapesName = SdResId(STR_POOLSHEET_SHAPES); pSheet = &(pSSPool->Make(aShapesName, SfxStyleFamily::Para, nMask)); - pSheet->SetParent( aGraphicName ); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_SHAPES); + pSheet->SetParent(aGraphicName); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_SHAPES); pISet = &pSheet->GetItemSet(); - pISet->Put(XFillStyleItem(drawing::FillStyle_GRADIENT)); // fill with gradient - aGradient.SetGradientStyle( ::awt::GradientStyle_RECT); // square type - aGradient.SetAngle( 0_deg10 ); // 0° angle + pISet->Put(XFillStyleItem(drawing::FillStyle_GRADIENT)); // fill with gradient + aGradient.SetGradientStyle(css::awt::GradientStyle_RECT); // square type + aGradient.SetAngle(0_deg10); // 0° angle aGradient.SetColorStops( basegfx::BColorStops( - Color(0xcccccc).getBColor(), // light gray 3 + Color(0xcccccc).getBColor(), // light gray 3 COL_WHITE.getBColor())); // white - aFillGradient.SetName( aShapesName ); + aFillGradient.SetName(aShapesName); aFillGradient.SetGradientValue(aGradient); - pISet->Put( aFillGradient ); - pISet->Put( XLineStyleItem(drawing::LineStyle_NONE) ); // no border - pISet->Put( SvxFontHeightItem(494, 100, EE_CHAR_FONTHEIGHT) ); // 14 pt - pISet->Put( SvxWeightItem(WEIGHT_BOLD, EE_CHAR_WEIGHT) ); // bold + pISet->Put(aFillGradient); + pISet->Put(XLineStyleItem(drawing::LineStyle_NONE)); // no border + pISet->Put(SvxFontHeightItem(pointsToHMM(14), 100, EE_CHAR_FONTHEIGHT)); // 14 pt + pISet->Put(SvxWeightItem(WEIGHT_BOLD, EE_CHAR_WEIGHT)); // bold } // Graphic > Shapes > Filled OUString aFilledName(SdResId(STR_POOLSHEET_FILLED)); { aName = aFilledName; pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_FILLED ); - pSheet->SetParent( aShapesName ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_FILLED); + pSheet->SetParent(aShapesName); pISet = &pSheet->GetItemSet(); - aGradient.SetGradientStyle( ::awt::GradientStyle_LINEAR ); + aGradient.SetGradientStyle(::awt::GradientStyle_LINEAR); aGradient.SetAngle( 300_deg10 ); aGradient.SetColorStops( basegfx::BColorStops( - COL_WHITE.getBColor(), // white + COL_WHITE.getBColor(), // white Color(0xcccccc).getBColor())); // light gray 3 - aFillGradient.SetName( aName ); + aFillGradient.SetName(aName); aFillGradient.SetGradientValue(aGradient); - pISet->Put( XFillStyleItem(drawing::FillStyle_GRADIENT) ); - pISet->Put( aFillGradient ); + pISet->Put(XFillStyleItem(drawing::FillStyle_GRADIENT)); + pISet->Put(aFillGradient); } // Graphic > Shapes > Filled > Blue { aName =SdResId(STR_POOLSHEET_FILLED_BLUE); pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); pSheet->SetParent(aFilledName); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_FILLED_BLUE ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_FILLED_BLUE); pISet = &pSheet->GetItemSet(); aGradient.SetColorStops( basegfx::BColorStops( - Color(0x00729fcf).getBColor(), // light blue 2 + Color(0x00729fcf).getBColor(), // light blue 2 Color(0x00355269).getBColor())); // dark blue 2 - aFillGradient.SetName( aName ); + aFillGradient.SetName(aName); aFillGradient.SetGradientValue(aGradient); - pISet->Put( aFillGradient ); - pISet->Put( SvxColorItem(COL_WHITE, EE_CHAR_COLOR )); // font white + pISet->Put(aFillGradient); + pISet->Put(SvxColorItem(COL_WHITE, EE_CHAR_COLOR)); // font white } // Graphic > Shapes > Filled > Green { aName =SdResId(STR_POOLSHEET_FILLED_GREEN); pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); pSheet->SetParent(aFilledName); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_FILLED_GREEN ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_FILLED_GREEN); pISet = &pSheet->GetItemSet(); aGradient.SetColorStops( basegfx::BColorStops( - Color(0x0077bc65).getBColor(), // light green 2 + Color(0x0077bc65).getBColor(), // light green 2 Color(0x00127622).getBColor())); // dark green 2 aFillGradient.SetName( aName ); aFillGradient.SetGradientValue(aGradient); - pISet->Put( aFillGradient ); - pISet->Put( aSvxFontItem ); // font name - pISet->Put( SvxColorItem(COL_WHITE, EE_CHAR_COLOR )); // font white + pISet->Put(aFillGradient); + pISet->Put(aSvxFontItem); // font name + pISet->Put(SvxColorItem(COL_WHITE, EE_CHAR_COLOR)); // font white } // Graphic > Shapes > Filled > Red { aName =SdResId(STR_POOLSHEET_FILLED_RED); pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); pSheet->SetParent(aFilledName); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_FILLED_RED ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_FILLED_RED); pISet = &pSheet->GetItemSet(); aGradient.SetColorStops( @@ -500,17 +507,17 @@ void SdDrawDocument::CreateLayoutTemplates() Color(0x00ff6d6d).getBColor(), // light red 2 Color(0x00c9211e).getBColor())); // dark red 2 - aFillGradient.SetName( aName ); + aFillGradient.SetName(aName); aFillGradient.SetGradientValue(aGradient); - pISet->Put( aFillGradient ); - pISet->Put( SvxColorItem(COL_WHITE, EE_CHAR_COLOR )); // font white + pISet->Put(aFillGradient); + pISet->Put(SvxColorItem(COL_WHITE, EE_CHAR_COLOR)); // font white } // Graphic > Shapes > Filled > Yellow { aName =SdResId(STR_POOLSHEET_FILLED_YELLOW); pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); pSheet->SetParent(aFilledName); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_FILLED_YELLOW ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_FILLED_YELLOW); pISet = &pSheet->GetItemSet(); aGradient.SetColorStops( @@ -528,76 +535,76 @@ void SdDrawDocument::CreateLayoutTemplates() { aName = aOutlineName; pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_OUTLINE ); - pSheet->SetParent( aShapesName ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_OUTLINE); + pSheet->SetParent(aShapesName); pISet = &pSheet->GetItemSet(); - pISet->Put( XFillStyleItem(drawing::FillStyle_NONE) ); // clear - pISet->Put( XLineStyleItem(drawing::LineStyle_SOLID) ); // solide line - pISet->Put( XLineWidthItem(81) ); // 2.3 pt - pISet->Put( XLineColorItem(OUString(), COL_BLACK) ); // b/w + pISet->Put(XFillStyleItem(drawing::FillStyle_NONE)); // clear + pISet->Put(XLineStyleItem(drawing::LineStyle_SOLID)); // solide line + pISet->Put(XLineWidthItem(81)); // 2.3 pt + pISet->Put(XLineColorItem(OUString(), COL_BLACK)); // b/w } // Graphic > Shapes > Outlines > Blue { aName =SdResId(STR_POOLSHEET_OUTLINE_BLUE); pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); pSheet->SetParent(aOutlineName); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_OUTLINE_BLUE ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_OUTLINE_BLUE); pISet = &pSheet->GetItemSet(); - pISet->Put( XLineColorItem(OUString(), Color(0x00355269)) ); // dark blue 2 - pISet->Put( SvxColorItem(Color(0x00355269), EE_CHAR_COLOR )); // font color + pISet->Put(XLineColorItem(OUString(), Color(0x00355269))); // dark blue 2 + pISet->Put(SvxColorItem(Color(0x00355269), EE_CHAR_COLOR)); // font color } // Graphic > Shapes > Outlines > Green { aName =SdResId(STR_POOLSHEET_OUTLINE_GREEN); pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); pSheet->SetParent(aOutlineName); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_OUTLINE_GREEN ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_OUTLINE_GREEN); pISet = &pSheet->GetItemSet(); - pISet->Put( XLineColorItem(OUString(), Color(0x00127622)) ); // dark green 2 - pISet->Put( SvxColorItem(Color(0x00127622), EE_CHAR_COLOR )); // font color + pISet->Put(XLineColorItem(OUString(), Color(0x00127622))); // dark green 2 + pISet->Put(SvxColorItem(Color(0x00127622), EE_CHAR_COLOR)); // font color } // Graphic > Shapes > Outlines > Red { aName =SdResId(STR_POOLSHEET_OUTLINE_RED); pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); pSheet->SetParent(aOutlineName); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_OUTLINE_RED ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_OUTLINE_RED); pISet = &pSheet->GetItemSet(); - pISet->Put( XLineColorItem(OUString(), Color(0x00c9211e)) ); // dark red 2 - pISet->Put( SvxColorItem(Color(0x00c9211e), EE_CHAR_COLOR )); // font color + pISet->Put(XLineColorItem(OUString(), Color(0x00c9211e))); // dark red 2 + pISet->Put(SvxColorItem(Color(0x00c9211e), EE_CHAR_COLOR)); // font color } // Graphic > Shapes > Outlines > Yellow { aName =SdResId(STR_POOLSHEET_OUTLINE_YELLOW); pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); pSheet->SetParent(aOutlineName); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_OUTLINE_YELLOW ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_OUTLINE_YELLOW); pISet = &pSheet->GetItemSet(); - pISet->Put( XLineStyleItem(drawing::LineStyle_SOLID)); - pISet->Put( XLineColorItem(OUString(), Color(0x00b47804)) ); // dark gold 2 - pISet->Put( SvxColorItem(Color(0x00b47804), EE_CHAR_COLOR )); // font color + pISet->Put(XLineStyleItem(drawing::LineStyle_SOLID)); + pISet->Put(XLineColorItem(OUString(), Color(0x00b47804))); // dark gold 2 + pISet->Put(SvxColorItem(Color(0x00b47804), EE_CHAR_COLOR)); // font color } // Graphic > Lines OUString aLinesName; { aLinesName = SdResId(STR_POOLSHEET_LINES); pSheet = &(pSSPool->Make(aLinesName, SfxStyleFamily::Para, nMask)); - pSheet->SetParent( aGraphicName ); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_LINES); + pSheet->SetParent(aGraphicName); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_LINES); pISet = &pSheet->GetItemSet(); - pISet->Put( XFillStyleItem(drawing::FillStyle_NONE) ); // clear - pISet->Put( XLineStyleItem(drawing::LineStyle_SOLID) ); // solide line - pISet->Put( XLineColorItem(OUString(), COL_BLACK) ); // b/w + pISet->Put(XFillStyleItem(drawing::FillStyle_NONE)); // clear + pISet->Put(XLineStyleItem(drawing::LineStyle_SOLID)); // solide line + pISet->Put(XLineColorItem(OUString(), COL_BLACK)); // b/w } // Graphic > Lines > Measurements { aName = SdResId(STR_POOLSHEET_MEASURE); pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); pSheet->SetParent(aLinesName); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_MEASURE ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_MEASURE); pISet = &pSheet->GetItemSet(); - ::basegfx::B2DPolygon aArrow; // arrows + ::basegfx::B2DPolygon aArrow; // arrows aArrow.append(::basegfx::B2DPoint(10.0, 0.0)); aArrow.append(::basegfx::B2DPoint(0.0, 30.0)); aArrow.append(::basegfx::B2DPoint(20.0, 30.0)); @@ -614,9 +621,9 @@ void SdDrawDocument::CreateLayoutTemplates() aName = SdResId(STR_POOLSHEET_LINES_DASHED); pSheet = &(pSSPool->Make(aName, SfxStyleFamily::Para, nMask)); pSheet->SetParent(aLinesName); - pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_LINES_DASHED ); + pSheet->SetHelpId(aHelpFile, HID_POOLSHEET_LINES_DASHED); pISet = &pSheet->GetItemSet(); - pISet->Put( XLineStyleItem(drawing::LineStyle_DASH) ); // dashed line + pISet->Put(XLineStyleItem(drawing::LineStyle_DASH)); // dashed line } // Generate presentation templates for default layout. @@ -652,14 +659,14 @@ void SdDrawDocument::CreateDefaultCellStyles() getDefaultFonts( aLatinFont, aCJKFont, aCTLFont ); - SvxFontItem aSvxFontItem( aLatinFont.GetFamilyTypeMaybeAskConfig(), aLatinFont.GetFamilyName(), aLatinFont.GetStyleName(), aLatinFont.GetPitchMaybeAskConfig(), - aLatinFont.GetCharSet(), EE_CHAR_FONTINFO ); + SvxFontItem aSvxFontItem(aLatinFont.GetFamilyTypeMaybeAskConfig(), aLatinFont.GetFamilyName(), aLatinFont.GetStyleName(), aLatinFont.GetPitchMaybeAskConfig(), + aLatinFont.GetCharSet(), EE_CHAR_FONTINFO); - SvxFontItem aSvxFontItemCJK( aCJKFont.GetFamilyTypeMaybeAskConfig(), aCJKFont.GetFamilyName(), aCJKFont.GetStyleName(), aCJKFont.GetPitchMaybeAskConfig(), - aCJKFont.GetCharSet(), EE_CHAR_FONTINFO_CJK ); + SvxFontItem aSvxFontItemCJK(aCJKFont.GetFamilyTypeMaybeAskConfig(), aCJKFont.GetFamilyName(), aCJKFont.GetStyleName(), aCJKFont.GetPitchMaybeAskConfig(), + aCJKFont.GetCharSet(), EE_CHAR_FONTINFO_CJK); - SvxFontItem aSvxFontItemCTL( aCTLFont.GetFamilyTypeMaybeAskConfig(), aCTLFont.GetFamilyName(), aCTLFont.GetStyleName(), aCTLFont.GetPitchMaybeAskConfig(), - aCTLFont.GetCharSet(), EE_CHAR_FONTINFO_CTL ); + SvxFontItem aSvxFontItemCTL(aCTLFont.GetFamilyTypeMaybeAskConfig(), aCTLFont.GetFamilyName(), aCTLFont.GetStyleName(), aCTLFont.GetPitchMaybeAskConfig(), + aCTLFont.GetCharSet(), EE_CHAR_FONTINFO_CTL); SdStyleSheetPool* pSSPool = static_cast<SdStyleSheetPool*>(GetStyleSheetPool()); SfxStyleSheetBase* pDefaultStyle = pSSPool->Find(u"default"_ustr, SfxStyleFamily::Frame);
