summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRegina Henschel <rb.henschel@t-online.de>2020-07-27 21:55:05 +0200
committerXisco Fauli <xiscofauli@libreoffice.org>2020-09-15 11:14:13 +0200
commit2b218729b8332fa2bc8a20480c8ba701e1bca361 (patch)
tree491f510749a14be2e94d00154690a07f5095880f
parentf34b1e7d4024d47a446dcf374a8f8743a5631219 (diff)
tdf#135184 add linecaps in charts
Chart is currently not able to interpret property linecap. But in case of linecap 'round' or 'square', line dashes lengths are adapted so that they look same as in MS Office (tdf#134053). This does not work, if the corresponding linecap property is not interpreted. Dashed border of data labels is not fixed because of bug tdf#135366. In addition I have fixed errors in prstDash detection, which I have noticed while creating unit tests. The unit tests cover file text, not visual appearence. Change-Id: I8cf2d2b2fc0923c2882f8148b4550bc363270480 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99562 Tested-by: Jenkins Reviewed-by: Regina Henschel <rb.henschel@t-online.de> (cherry picked from commit 74be8bb787a44464957e5d3105c8de6d36e81b4a) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101871 Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
-rw-r--r--chart2/CppunitTest_chart2_geometry.mk139
-rw-r--r--chart2/Module_chart2.mk1
-rw-r--r--chart2/qa/extras/chart2geometry.cxx242
-rw-r--r--chart2/qa/extras/data/xlsx/tdf135184RoundLineCap.xlsxbin0 -> 25538 bytes
-rw-r--r--chart2/qa/extras/data/xlsx/tdf135184RoundLineCap2.xlsxbin0 -> 21937 bytes
-rw-r--r--chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx1
-rw-r--r--chart2/source/controller/itemsetwrapper/GraphicPropertyItemConverter.cxx6
-rw-r--r--chart2/source/inc/LinePropertiesHelper.hxx3
-rw-r--r--chart2/source/model/main/DataPointProperties.cxx8
-rw-r--r--chart2/source/tools/LinePropertiesHelper.cxx8
-rw-r--r--chart2/source/view/inc/VLineProperties.hxx1
-rw-r--r--chart2/source/view/main/PropertyMapper.cxx9
-rw-r--r--chart2/source/view/main/ShapeFactory.cxx5
-rw-r--r--chart2/source/view/main/VLineProperties.cxx3
-rw-r--r--oox/source/drawingml/chart/objectformatter.cxx6
-rw-r--r--oox/source/export/drawingml.cxx23
16 files changed, 435 insertions, 20 deletions
diff --git a/chart2/CppunitTest_chart2_geometry.mk b/chart2/CppunitTest_chart2_geometry.mk
new file mode 100644
index 000000000000..fb07f9108a5f
--- /dev/null
+++ b/chart2/CppunitTest_chart2_geometry.mk
@@ -0,0 +1,139 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# 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/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitTest,chart2_geometry))
+
+$(eval $(call gb_CppunitTest_use_externals,chart2_geometry, \
+ boost_headers \
+ libxml2 \
+))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,chart2_geometry, \
+ chart2/qa/extras/chart2geometry \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,chart2_geometry, \
+ $(call gb_Helper_optional,AVMEDIA,avmedia) \
+ basegfx \
+ comphelper \
+ cppu \
+ cppuhelper \
+ drawinglayer \
+ editeng \
+ for \
+ forui \
+ i18nlangtag \
+ msfilter \
+ oox \
+ sal \
+ salhelper \
+ sax \
+ sb \
+ sc \
+ sw \
+ sd \
+ sfx \
+ sot \
+ svl \
+ svt \
+ svx \
+ svxcore \
+ test \
+ tl \
+ tk \
+ ucbhelper \
+ unotest \
+ utl \
+ vbahelper \
+ vcl \
+ xo \
+))
+
+$(eval $(call gb_CppunitTest_set_include,chart2_geometry,\
+ -I$(SRCDIR)/chart2/inc \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,chart2_geometry))
+
+$(eval $(call gb_CppunitTest_use_ure,chart2_geometry))
+$(eval $(call gb_CppunitTest_use_vcl,chart2_geometry))
+
+$(eval $(call gb_CppunitTest_use_components,chart2_geometry,\
+ basic/util/sb \
+ animations/source/animcore/animcore \
+ chart2/source/controller/chartcontroller \
+ chart2/source/chartcore \
+ comphelper/util/comphelp \
+ configmgr/source/configmgr \
+ dtrans/util/mcnttype \
+ dbaccess/util/dba \
+ embeddedobj/util/embobj \
+ emfio/emfio \
+ eventattacher/source/evtatt \
+ filter/source/config/cache/filterconfig1 \
+ filter/source/odfflatxml/odfflatxml \
+ filter/source/storagefilterdetect/storagefd \
+ filter/source/xmlfilteradaptor/xmlfa \
+ filter/source/xmlfilterdetect/xmlfd \
+ forms/util/frm \
+ framework/util/fwk \
+ i18npool/util/i18npool \
+ linguistic/source/lng \
+ oox/util/oox \
+ package/source/xstor/xstor \
+ package/util/package2 \
+ sax/source/expatwrap/expwrap \
+ sc/util/sc \
+ sc/util/scd \
+ sc/util/scfilt \
+ sw/util/sw \
+ sw/util/swd \
+ sw/util/msword \
+ sd/util/sd \
+ sd/util/sdfilt \
+ sd/util/sdd \
+ $(call gb_Helper_optional,SCRIPTING, \
+ sc/util/vbaobj) \
+ scaddins/source/analysis/analysis \
+ scaddins/source/datefunc/date \
+ scripting/source/basprov/basprov \
+ scripting/util/scriptframe \
+ sfx2/util/sfx \
+ sot/util/sot \
+ svl/source/fsstor/fsstorage \
+ svl/util/svl \
+ svtools/util/svt \
+ svx/util/svx \
+ svx/util/svxcore \
+ toolkit/util/tk \
+ vcl/vcl.common \
+ ucb/source/core/ucb1 \
+ ucb/source/ucp/file/ucpfile1 \
+ ucb/source/ucp/tdoc/ucptdoc1 \
+ unotools/util/utl \
+ unoxml/source/rdf/unordf \
+ unoxml/source/service/unoxml \
+ uui/util/uui \
+ writerfilter/util/writerfilter \
+ xmloff/util/xo \
+ xmlscript/util/xmlscript \
+))
+
+$(eval $(call gb_CppunitTest_use_uiconfigs,chart2_geometry, \
+ modules/swriter \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,chart2_geometry))
+
+$(call gb_CppunitTest_get_target,chart2_geometry): $(call gb_Package_get_target,postprocess_images)
+
+# vim: set noet sw=4 ts=4:
diff --git a/chart2/Module_chart2.mk b/chart2/Module_chart2.mk
index c2498b10d96d..37acfdc3730f 100644
--- a/chart2/Module_chart2.mk
+++ b/chart2/Module_chart2.mk
@@ -30,6 +30,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,chart2,\
CppunitTest_chart2_trendcalculators \
CppunitTest_chart2_dump \
CppunitTest_chart2_pivot_chart_test \
+ CppunitTest_chart2_geometry \
))
ifeq ($(ENABLE_CHART_TESTS),TRUE)
diff --git a/chart2/qa/extras/chart2geometry.cxx b/chart2/qa/extras/chart2geometry.cxx
new file mode 100644
index 000000000000..dedfda6e1c24
--- /dev/null
+++ b/chart2/qa/extras/chart2geometry.cxx
@@ -0,0 +1,242 @@
+/* -*- 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 "charttest.hxx"
+
+#include <test/xmltesttools.hxx>
+
+#include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
+#include <com/sun/star/lang/XServiceName.hpp>
+#include <com/sun/star/packages/zip/ZipFileAccess.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+
+#include <unotools/ucbstreamhelper.hxx>
+
+#include <libxml/xpathInternals.h>
+
+#include <algorithm>
+
+using uno::Reference;
+using beans::XPropertySet;
+
+class Chart2GeometryTest : public ChartTest, public XmlTestTools
+{
+protected:
+ virtual void registerNamespaces(xmlXPathContextPtr& pXmlXPathCtx) override;
+
+public:
+ Chart2GeometryTest()
+ : ChartTest()
+ {
+ }
+ void testTdf135184RoundLineCap();
+ void testTdf135184RoundLineCap2();
+ void testTdf135184RoundLineCap3();
+ void testTdf135184RoundLineCap4();
+
+ CPPUNIT_TEST_SUITE(Chart2GeometryTest);
+ CPPUNIT_TEST(testTdf135184RoundLineCap);
+ CPPUNIT_TEST(testTdf135184RoundLineCap2);
+ CPPUNIT_TEST(testTdf135184RoundLineCap3);
+ CPPUNIT_TEST(testTdf135184RoundLineCap4);
+
+ CPPUNIT_TEST_SUITE_END();
+
+protected:
+ /**
+ * Given that some problem doesn't affect the result in the importer, we
+ * test the resulting file directly, by opening the zip file, parsing an
+ * xml stream, and asserting an XPath expression. This method returns the
+ * xml stream, so that you can do the asserting.
+ */
+ xmlDocUniquePtr parseExport(const OUString& rDir, const OUString& rFilterFormat);
+};
+
+namespace
+{
+struct CheckForChartName
+{
+private:
+ OUString aDir;
+
+public:
+ explicit CheckForChartName(const OUString& rDir)
+ : aDir(rDir)
+ {
+ }
+
+ bool operator()(const OUString& rName)
+ {
+ if (!rName.startsWith(aDir))
+ return false;
+
+ if (!rName.endsWith(".xml"))
+ return false;
+
+ return true;
+ }
+};
+
+OUString findChartFile(const OUString& rDir, uno::Reference<container::XNameAccess> const& xNames)
+{
+ uno::Sequence<OUString> aNames = xNames->getElementNames();
+ OUString* pElement = std::find_if(aNames.begin(), aNames.end(), CheckForChartName(rDir));
+
+ CPPUNIT_ASSERT(pElement != aNames.end());
+ return *pElement;
+}
+}
+
+xmlDocUniquePtr Chart2GeometryTest::parseExport(const OUString& rDir, const OUString& rFilterFormat)
+{
+ std::shared_ptr<utl::TempFile> pTempFile = save(rFilterFormat);
+
+ // Read the XML stream we're interested in.
+ uno::Reference<packages::zip::XZipFileAccess2> xNameAccess
+ = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory),
+ pTempFile->GetURL());
+ uno::Reference<io::XInputStream> xInputStream(
+ xNameAccess->getByName(findChartFile(rDir, xNameAccess)), uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xInputStream.is());
+ std::unique_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(xInputStream, true));
+
+ return parseXmlStream(pStream.get());
+}
+
+void Chart2GeometryTest::registerNamespaces(xmlXPathContextPtr& pXmlXPathCtx)
+{
+ static struct
+ {
+ char const* pPrefix;
+ char const* pURI;
+ } const aNamespaces[]
+ = { { "w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main" },
+ { "v", "urn:schemas-microsoft-com:vml" },
+ { "c", "http://schemas.openxmlformats.org/drawingml/2006/chart" },
+ { "a", "http://schemas.openxmlformats.org/drawingml/2006/main" },
+ { "mc", "http://schemas.openxmlformats.org/markup-compatibility/2006" },
+ { "wps", "http://schemas.microsoft.com/office/word/2010/wordprocessingShape" },
+ { "wpg", "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" },
+ { "wp", "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" },
+ { "c15", "http://schemas.microsoft.com/office/drawing/2012/chart" },
+ { "office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0" },
+ { "chart", "urn:oasis:names:tc:opendocument:xmlns:chart:1.0" },
+ { "style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0" },
+ { "svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" },
+ { "table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0" },
+ { "text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0" },
+ { "xlink", "http://www.w3c.org/1999/xlink" },
+ { "c15", "http://schemas.microsoft.com/office/drawing/2012/chart" } };
+ for (size_t i = 0; i < SAL_N_ELEMENTS(aNamespaces); ++i)
+ {
+ xmlXPathRegisterNs(pXmlXPathCtx, reinterpret_cast<xmlChar const*>(aNamespaces[i].pPrefix),
+ reinterpret_cast<xmlChar const*>(aNamespaces[i].pURI));
+ }
+}
+
+static OString OU2O(const OUString& sOUSource)
+{
+ return rtl::OUStringToOString(sOUSource, RTL_TEXTENCODING_UTF8);
+}
+
+// Without the patch for tdf#135184, charts were not able to use linecap at all.
+// These two tests verify, that round linecaps in the xlsx file are saved in ods.
+void Chart2GeometryTest::testTdf135184RoundLineCap()
+{
+ // It tests chart area, data series line and regression-curve line.
+ load("/chart2/qa/extras/data/xlsx/", "tdf135184RoundLineCap.xlsx");
+ xmlDocUniquePtr pXmlDoc = parseExport("Object 1/content.xml", "calc8");
+ CPPUNIT_ASSERT(pXmlDoc);
+
+ const OString sStyleStart("/office:document-content/office:automatic-styles");
+ const OString sCap("/style:graphic-properties[@svg:stroke-linecap='round']");
+ const OString sChartStart("/office:document-content/office:body/office:chart/chart:chart");
+ OString sPredicate;
+ // chart area
+ const OUString sOUAreaStyleName = getXPathContent(pXmlDoc, sChartStart + "/@chart:style-name");
+ sPredicate = "[@style:name='" + OU2O(sOUAreaStyleName) + "']";
+ assertXPath(pXmlDoc, sStyleStart + "/style:style" + sPredicate + sCap);
+ // data series line
+ const OString sSeries(sChartStart + "/chart:plot-area/chart:series");
+ const OUString sOUSeriesStyleName = getXPathContent(pXmlDoc, sSeries + "/@chart:style-name");
+ sPredicate = "[@style:name='" + OU2O(sOUSeriesStyleName) + "']";
+ assertXPath(pXmlDoc, sStyleStart + "/style:style" + sPredicate + sCap);
+ // regression-curve (trend line)
+ const OString sTrend(sChartStart + "/chart:plot-area/chart:series/chart:regression-curve");
+ const OUString sOUTrendStyleName = getXPathContent(pXmlDoc, sTrend + "/@chart:style-name");
+ sPredicate = "[@style:name='" + OU2O(sOUTrendStyleName) + "']";
+ assertXPath(pXmlDoc, sStyleStart + "/style:style" + sPredicate + sCap);
+}
+
+void Chart2GeometryTest::testTdf135184RoundLineCap2()
+{
+ // It tests legend, data series sector and title.
+ load("/chart2/qa/extras/data/xlsx/", "tdf135184RoundLineCap2.xlsx");
+ xmlDocUniquePtr pXmlDoc = parseExport("Object 1/content.xml", "calc8");
+ CPPUNIT_ASSERT(pXmlDoc);
+
+ const OString sStyleStart("/office:document-content/office:automatic-styles");
+ const OString sCap("/style:graphic-properties[@svg:stroke-linecap='round']");
+ const OString sChartStart("/office:document-content/office:body/office:chart/chart:chart");
+ OString sPredicate;
+ // legend
+ const OString sLegend(sChartStart + "/chart:legend");
+ const OUString sOULegendStyleName = getXPathContent(pXmlDoc, sLegend + "/@chart:style-name");
+ sPredicate = "[@style:name='" + OU2O(sOULegendStyleName) + "']";
+ assertXPath(pXmlDoc, sStyleStart + "/style:style" + sPredicate + sCap);
+ // title
+ const OString sTitle(sChartStart + "/chart:title");
+ const OUString sOUTitleStyleName = getXPathContent(pXmlDoc, sTitle + "/@chart:style-name");
+ sPredicate = "[@style:name='" + OU2O(sOUTitleStyleName) + "']";
+ assertXPath(pXmlDoc, sStyleStart + "/style:style" + sPredicate + sCap);
+ // sector
+ const OString sSector(sChartStart + "/chart:plot-area/chart:series/chart:data-point[3]");
+ const OUString sOUSectorStyleName = getXPathContent(pXmlDoc, sSector + "/@chart:style-name");
+ sPredicate = "[@style:name='" + OU2O(sOUSectorStyleName) + "']";
+ assertXPath(pXmlDoc, sStyleStart + "/style:style" + sPredicate + sCap);
+}
+
+// These two tests verify the round-trip of preset dash styles in the xlsx file.
+void Chart2GeometryTest::testTdf135184RoundLineCap3()
+{
+ // It tests chart area, data series line and regression-curve line.
+ load("/chart2/qa/extras/data/xlsx/", "tdf135184RoundLineCap.xlsx");
+ xmlDocUniquePtr pXmlDoc = parseExport("xl/charts/chart", "Calc Office Open XML");
+ CPPUNIT_ASSERT(pXmlDoc);
+
+ const OString sDash("/c:spPr/a:ln/a:prstDash");
+ // chart area
+ assertXPath(pXmlDoc, "/c:chartSpace" + sDash, "val", "dashDot");
+ // data series line
+ const OString sStart("/c:chartSpace/c:chart/c:plotArea/c:scatterChart/c:ser");
+ assertXPath(pXmlDoc, sStart + sDash, "val", "dash");
+ // regression-curve (trendline)
+ assertXPath(pXmlDoc, sStart + "/c:trendline" + sDash, "val", "sysDot");
+}
+
+void Chart2GeometryTest::testTdf135184RoundLineCap4()
+{
+ // It tests legend, data series sector and title.
+ load("/chart2/qa/extras/data/xlsx/", "tdf135184RoundLineCap2.xlsx");
+ xmlDocUniquePtr pXmlDoc = parseExport("xl/charts/chart", "Calc Office Open XML");
+ CPPUNIT_ASSERT(pXmlDoc);
+
+ const OString sChartStart("/c:chartSpace/c:chart");
+ const OString sDash("/c:spPr/a:ln/a:prstDash");
+ assertXPath(pXmlDoc, sChartStart + "/c:legend" + sDash, "val", "sysDot");
+ const OString sSeries(sChartStart + "/c:plotArea/c:pieChart/c:ser/c:dPt[3]");
+ assertXPath(pXmlDoc, sSeries + sDash, "val", "dash");
+ assertXPath(pXmlDoc, sChartStart + "/c:title" + sDash, "val", "dashDot");
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Chart2GeometryTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/qa/extras/data/xlsx/tdf135184RoundLineCap.xlsx b/chart2/qa/extras/data/xlsx/tdf135184RoundLineCap.xlsx
new file mode 100644
index 000000000000..69cad0d671fd
--- /dev/null
+++ b/chart2/qa/extras/data/xlsx/tdf135184RoundLineCap.xlsx
Binary files differ
diff --git a/chart2/qa/extras/data/xlsx/tdf135184RoundLineCap2.xlsx b/chart2/qa/extras/data/xlsx/tdf135184RoundLineCap2.xlsx
new file mode 100644
index 000000000000..ced797258ad2
--- /dev/null
+++ b/chart2/qa/extras/data/xlsx/tdf135184RoundLineCap2.xlsx
Binary files differ
diff --git a/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx b/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx
index e98ebe65bbbd..a6d45dddaa47 100644
--- a/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx
+++ b/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx
@@ -737,6 +737,7 @@ std::vector< std::unique_ptr<WrappedProperty> > DataSeriesPointWrapper::createWr
aWrappedProperties.emplace_back( new WrappedSeriesAreaOrLineProperty("LineDashName","BorderDashName","LineDashName", this ) );
aWrappedProperties.emplace_back( new WrappedSeriesAreaOrLineProperty("LineTransparence","BorderTransparency","Transparency", this ) );
aWrappedProperties.emplace_back( new WrappedSeriesAreaOrLineProperty("LineWidth","BorderWidth","LineWidth", this ) );
+ aWrappedProperties.emplace_back( new WrappedSeriesAreaOrLineProperty("LineCap","LineCap","LineCap", this ) );
aWrappedProperties.emplace_back( new WrappedProperty("FillStyle","FillStyle" ) );
aWrappedProperties.emplace_back( new WrappedProperty("FillTransparence","Transparency") );
diff --git a/chart2/source/controller/itemsetwrapper/GraphicPropertyItemConverter.cxx b/chart2/source/controller/itemsetwrapper/GraphicPropertyItemConverter.cxx
index ffa8c29a5b77..55e954e946d9 100644
--- a/chart2/source/controller/itemsetwrapper/GraphicPropertyItemConverter.cxx
+++ b/chart2/source/controller/itemsetwrapper/GraphicPropertyItemConverter.cxx
@@ -71,7 +71,8 @@ ItemPropertyMapType & lcl_GetDataPointLinePropertyMap()
static ItemPropertyMapType aDataPointPropertyLineMap{
{XATTR_LINECOLOR, {"Color", 0}},
{XATTR_LINESTYLE, {"LineStyle", 0}},
- {XATTR_LINEWIDTH, {"LineWidth", 0}}};
+ {XATTR_LINEWIDTH, {"LineWidth", 0}},
+ {XATTR_LINECAP, {"LineCap", 0}}};
return aDataPointPropertyLineMap;
}
ItemPropertyMapType & lcl_GetLinePropertyMap()
@@ -80,7 +81,8 @@ ItemPropertyMapType & lcl_GetLinePropertyMap()
{XATTR_LINESTYLE, {"LineStyle", 0}},
{XATTR_LINEWIDTH, {"LineWidth", 0}},
{XATTR_LINECOLOR, {"LineColor", 0}},
- {XATTR_LINEJOINT, {"LineJoint", 0}}};
+ {XATTR_LINEJOINT, {"LineJoint", 0}},
+ {XATTR_LINECAP, {"LineCap", 0}}};
return aLinePropertyMap;
}
ItemPropertyMapType & lcl_GetFillPropertyMap()
diff --git a/chart2/source/inc/LinePropertiesHelper.hxx b/chart2/source/inc/LinePropertiesHelper.hxx
index 11c56b186eaf..e870a5688cf1 100644
--- a/chart2/source/inc/LinePropertiesHelper.hxx
+++ b/chart2/source/inc/LinePropertiesHelper.hxx
@@ -45,7 +45,8 @@ namespace LinePropertiesHelper
PROP_LINE_COLOR,
PROP_LINE_TRANSPARENCE,
PROP_LINE_WIDTH,
- PROP_LINE_JOINT
+ PROP_LINE_JOINT,
+ PROP_LINE_CAP
};
OOO_DLLPUBLIC_CHARTTOOLS void AddPropertiesToVector(
diff --git a/chart2/source/model/main/DataPointProperties.cxx b/chart2/source/model/main/DataPointProperties.cxx
index 7bc20bbc30e6..dba488fdd924 100644
--- a/chart2/source/model/main/DataPointProperties.cxx
+++ b/chart2/source/model/main/DataPointProperties.cxx
@@ -26,6 +26,7 @@
#include <com/sun/star/drawing/FillStyle.hpp>
#include <com/sun/star/drawing/LineStyle.hpp>
#include <com/sun/star/drawing/LineDash.hpp>
+#include <com/sun/star/drawing/LineCap.hpp>
#include <com/sun/star/drawing/BitmapMode.hpp>
#include <com/sun/star/drawing/RectanglePoint.hpp>
#include <com/sun/star/chart2/RelativePosition.hpp>
@@ -220,6 +221,12 @@ void DataPointProperties::AddPropertiesToVector(
beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::MAYBEVOID );
+ rOutProperties.emplace_back( "LineCap",
+ ::chart::LinePropertiesHelper::PROP_LINE_CAP,
+ cppu::UnoType<drawing::LineCap>::get(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT );
+
// FillProperties
// bitmap properties
rOutProperties.emplace_back( "FillBitmapOffsetX",
@@ -466,6 +473,7 @@ void DataPointProperties::AddDefaultsToMap(
PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, LinePropertiesHelper::PROP_LINE_WIDTH, 0 );
PropertyHelper::setPropertyValueDefault( rOutMap, LinePropertiesHelper::PROP_LINE_DASH, drawing::LineDash());
PropertyHelper::setEmptyPropertyValueDefault( rOutMap, LinePropertiesHelper::PROP_LINE_DASH_NAME );
+ PropertyHelper::setPropertyValueDefault( rOutMap, LinePropertiesHelper::PROP_LINE_CAP, drawing::LineCap_BUTT);
//fill bitmap
PropertyHelper::setPropertyValueDefault< sal_Int16 >( rOutMap, FillProperties::PROP_FILL_BITMAP_OFFSETX, 0 );
diff --git a/chart2/source/tools/LinePropertiesHelper.cxx b/chart2/source/tools/LinePropertiesHelper.cxx
index 227ec99b6383..7e6d28860903 100644
--- a/chart2/source/tools/LinePropertiesHelper.cxx
+++ b/chart2/source/tools/LinePropertiesHelper.cxx
@@ -22,6 +22,7 @@
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/drawing/LineStyle.hpp>
#include <com/sun/star/drawing/LineDash.hpp>
+#include <com/sun/star/drawing/LineCap.hpp>
#include <com/sun/star/drawing/LineJoint.hpp>
#include <tools/diagnose_ex.h>
@@ -79,6 +80,12 @@ void LinePropertiesHelper::AddPropertiesToVector(
cppu::UnoType<drawing::LineJoint>::get(),
beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::MAYBEDEFAULT );
+
+ rOutProperties.emplace_back( "LineCap",
+ PROP_LINE_CAP,
+ cppu::UnoType<drawing::LineCap>::get(),
+ beans::PropertyAttribute::BOUND
+ | beans::PropertyAttribute::MAYBEDEFAULT );
}
void LinePropertiesHelper::AddDefaultsToMap(
@@ -89,6 +96,7 @@ void LinePropertiesHelper::AddDefaultsToMap(
::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_LINE_COLOR, 0x000000 ); // black
::chart::PropertyHelper::setPropertyValueDefault< sal_Int16 >( rOutMap, PROP_LINE_TRANSPARENCE, 0 );
::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_LINE_JOINT, drawing::LineJoint_ROUND );
+ ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_LINE_CAP, drawing::LineCap_BUTT );
}
bool LinePropertiesHelper::IsLineVisible( const css::uno::Reference<
diff --git a/chart2/source/view/inc/VLineProperties.hxx b/chart2/source/view/inc/VLineProperties.hxx
index a255499fd088..864e78316322 100644
--- a/chart2/source/view/inc/VLineProperties.hxx
+++ b/chart2/source/view/inc/VLineProperties.hxx
@@ -35,6 +35,7 @@ struct VLineProperties
css::uno::Any Transparence;//type sal_Int16 for property UNO_NAME_LINETRANSPARENCE
css::uno::Any Width;//type sal_Int32 for property UNO_NAME_LINEWIDTH
css::uno::Any DashName;//type OUString for property "LineDashName"
+ css::uno::Any LineCap; //type drawing::LineCap for propertey UNO_NAME_LINECAP
VLineProperties();
void initFromPropertySet( const css::uno::Reference< css::beans::XPropertySet >& xProp );
diff --git a/chart2/source/view/main/PropertyMapper.cxx b/chart2/source/view/main/PropertyMapper.cxx
index c062eb2b451a..b33ab3ee3ec6 100644
--- a/chart2/source/view/main/PropertyMapper.cxx
+++ b/chart2/source/view/main/PropertyMapper.cxx
@@ -281,7 +281,8 @@ const tPropertyNameMap& PropertyMapper::getPropertyNameMapForLineProperties()
{"LineJoint", "LineJoint"},
{"LineStyle", "LineStyle"},
{"LineTransparence", "LineTransparence"},
- {"LineWidth", "LineWidth"}};
+ {"LineWidth", "LineWidth"},
+ {"LineCap", "LineCap"}};
return s_aShapePropertyMapForLineProperties;
}
@@ -328,7 +329,8 @@ const tPropertyNameMap& PropertyMapper::getPropertyNameMapForLineSeriesPropertie
{"LineDashName", "LineDashName"},
{"LineStyle", "LineStyle"},
{"LineTransparence", "Transparency"},
- {"LineWidth", "LineWidth"}};
+ {"LineWidth", "LineWidth"},
+ {"LineCap", "LineCap"}};
return s_aShapePropertyMapForLineSeriesProperties;
}
@@ -384,7 +386,8 @@ const tPropertyNameMap& PropertyMapper::getPropertyNameMapForFilledSeriesPropert
{"LineDashName", "BorderDashName"},
{"LineStyle", "BorderStyle"},
{"LineTransparence", "BorderTransparency"},
- {"LineWidth", "BorderWidth"}};
+ {"LineWidth", "BorderWidth"},
+ {"LineCap", "LineCap"}};
return s_aShapePropertyMapForFilledSeriesProperties;
}
diff --git a/chart2/source/view/main/ShapeFactory.cxx b/chart2/source/view/main/ShapeFactory.cxx
index b2e19781c8ef..6ccaf9fb6ed1 100644
--- a/chart2/source/view/main/ShapeFactory.cxx
+++ b/chart2/source/view/main/ShapeFactory.cxx
@@ -2029,6 +2029,11 @@ uno::Reference< drawing::XShape >
if(pLineProperties->DashName.hasValue())
xProp->setPropertyValue( "LineDashName"
, pLineProperties->DashName );
+
+ //LineCap
+ if(pLineProperties->LineCap.hasValue())
+ xProp->setPropertyValue( UNO_NAME_LINECAP
+ , pLineProperties->LineCap );
}
}
catch( const uno::Exception& )
diff --git a/chart2/source/view/main/VLineProperties.cxx b/chart2/source/view/main/VLineProperties.cxx
index f1ca35e71730..e86c5f7b810f 100644
--- a/chart2/source/view/main/VLineProperties.cxx
+++ b/chart2/source/view/main/VLineProperties.cxx
@@ -19,6 +19,7 @@
#include <VLineProperties.hxx>
#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/drawing/LineCap.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <tools/diagnose_ex.h>
@@ -34,6 +35,7 @@ VLineProperties::VLineProperties()
LineStyle <<= drawing::LineStyle_SOLID; //type drawing::LineStyle for property UNO_NAME_LINESTYLE
Transparence <<= sal_Int16(0);//type sal_Int16 for property UNO_NAME_LINETRANSPARENCE
Width <<= sal_Int32(0);//type sal_Int32 for property UNO_NAME_LINEWIDTH
+ LineCap <<= drawing::LineCap_BUTT; //type drawing::LineCap for property UNO_NAME_LINECAP
}
void VLineProperties::initFromPropertySet( const uno::Reference< beans::XPropertySet >& xProp )
@@ -47,6 +49,7 @@ void VLineProperties::initFromPropertySet( const uno::Reference< beans::XPropert
Transparence = xProp->getPropertyValue( "LineTransparence" );
Width = xProp->getPropertyValue( "LineWidth" );
DashName = xProp->getPropertyValue( "LineDashName" );
+ LineCap = xProp->getPropertyValue( "LineCap" );
}
catch( const uno::Exception& )
{
diff --git a/oox/source/drawingml/chart/objectformatter.cxx b/oox/source/drawingml/chart/objectformatter.cxx
index 7bfee70b15de..60cac23952f9 100644
--- a/oox/source/drawingml/chart/objectformatter.cxx
+++ b/oox/source/drawingml/chart/objectformatter.cxx
@@ -446,7 +446,7 @@ const AutoTextEntry* lclGetAutoTextEntry( const AutoTextEntry* pEntries, sal_Int
static const ShapePropertyIds spnCommonPropIds =
{
PROP_LineStyle, PROP_LineWidth, PROP_LineColor, PROP_LineTransparence, PROP_LineDashName,
- PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
+ PROP_LineCap, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
PROP_FillStyle, PROP_FillColor, PROP_FillTransparence, PROP_INVALID, PROP_FillGradientName,
PROP_FillBitmapName, PROP_FillBitmapMode, PROP_FillBitmapSizeX, PROP_FillBitmapSizeY,
PROP_FillBitmapPositionOffsetX, PROP_FillBitmapPositionOffsetY, PROP_FillBitmapRectanglePoint,
@@ -456,7 +456,7 @@ static const ShapePropertyIds spnCommonPropIds =
static const ShapePropertyIds spnLinearPropIds =
{
PROP_LineStyle, PROP_LineWidth, PROP_Color, PROP_Transparency, PROP_LineDashName,
- PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
+ PROP_LineCap, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
PROP_INVALID, PROP_INVALID, PROP_INVALID,
@@ -470,7 +470,7 @@ static const ShapePropertyIds spnFilledPropIds =
PROP_BorderColor,
PROP_BorderTransparency,
PROP_BorderDashName,
- PROP_INVALID,
+ PROP_LineCap,
PROP_INVALID,
PROP_INVALID,
PROP_INVALID,
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 14910f759598..67c089b73cf5 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -941,7 +941,8 @@ void DrawingML::WriteOutline( const Reference<XPropertySet>& rXPropSet, Referenc
{
nDistance -= 99;
nDotLen += 99;
- nDashLen += 99;
+ if (nDashLen > 0)
+ nDashLen += 99;
}
// LO uses length 0 for 100%, if the attribute is missing in ODF.
// Other applications might write 100%. Make is unique for the conditions.
@@ -950,43 +951,43 @@ void DrawingML::WriteOutline( const Reference<XPropertySet>& rXPropSet, Referenc
if (nDashLen == 0 && aLineDash.Dashes > 0)
nDashLen = 100;
bIsConverted = true;
- if (nDotLen == 100 && aLineDash.Dashes == 0 && nDashLen == 0 && aLineDash.Distance == 300)
+ if (nDotLen == 100 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300)
{
mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "dot");
}
- else if (nDotLen == 400 && aLineDash.Dashes == 0 && nDashLen == 0 && aLineDash.Distance == 300)
+ else if (nDotLen == 400 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300)
{
mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "dash");
}
- else if (nDotLen == 400 && aLineDash.Dashes == 1 && nDashLen == 100 && aLineDash.Distance == 300)
+ else if (nDotLen == 400 && aLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 300)
{
mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "dashDot");
}
- else if (nDotLen == 800 && aLineDash.Dashes == 0 && nDashLen == 0 && aLineDash.Distance == 300)
+ else if (nDotLen == 800 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300)
{
mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "lgDash");
}
- else if (nDotLen == 800 && aLineDash.Dashes == 1 && nDashLen == 100 && aLineDash.Distance == 300)
+ else if (nDotLen == 800 && aLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 300)
{
mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "lgDashDot");
}
- else if (nDotLen == 800 && aLineDash.Dashes == 2 && nDashLen == 100 && aLineDash.Distance == 300)
+ else if (nDotLen == 800 && aLineDash.Dashes == 2 && nDashLen == 100 && nDistance == 300)
{
mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "lgDashDotDot");
}
- else if (nDotLen == 100 && aLineDash.Dashes == 0 && nDashLen == 0 && aLineDash.Distance == 100)
+ else if (nDotLen == 100 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 100)
{
mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "sysDot");
}
- else if (nDotLen == 300 && aLineDash.Dashes == 0 && nDashLen == 0 && aLineDash.Distance == 100)
+ else if (nDotLen == 300 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 100)
{
mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "sysDash");
}
- else if (nDotLen == 300 && aLineDash.Dashes == 1 && nDashLen == 100 && aLineDash.Distance == 100)
+ else if (nDotLen == 300 && aLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 100)
{
mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "sysDashDot");
}
- else if (nDotLen == 300 && aLineDash.Dashes == 2 && nDashLen == 100 && aLineDash.Distance == 100)
+ else if (nDotLen == 300 && aLineDash.Dashes == 2 && nDashLen == 100 && nDistance == 100)
{
mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "sysDashDotDot");
}