[Libreoffice-commits] core.git: chart2/qa chart2/source include/oox oox/source
Balazs Varga (via logerrit)
logerrit at kemper.freedesktop.org
Wed Jul 24 12:05:15 UTC 2019
chart2/qa/extras/chart2import.cxx | 38 +++++++++++--
chart2/qa/extras/data/docx/testMultilevelCategoryAxis.docx |binary
chart2/source/tools/InternalData.cxx | 11 +++
include/oox/drawingml/chart/datasourcemodel.hxx | 1
oox/source/drawingml/chart/chartconverter.cxx | 29 +++++----
oox/source/drawingml/chart/datasourcecontext.cxx | 25 ++++++++
oox/source/drawingml/chart/datasourcemodel.cxx | 3 -
oox/source/export/chartexport.cxx | 8 ++
8 files changed, 94 insertions(+), 21 deletions(-)
New commits:
commit fa0a981af41a2606541eec1cb20a379a739691e0
Author: Balazs Varga <balazs.varga991 at gmail.com>
AuthorDate: Wed Jul 17 12:57:47 2019 +0200
Commit: László Németh <nemeth at numbertext.org>
CommitDate: Wed Jul 24 14:04:06 2019 +0200
tdf#114166 DOCX chart import: fix missing complex categories
Now complex category labels are visible, and the inner data
table contains the correct texts of the category columns.
Note: repeating call of createDataSequenceByValueArray() API function
can create all columns of the complex categories. See also
commit 6c4e21a234f12e1310ba06f9859e08b424acf8bf
"bnc#812796: Correctly handle static value array for OOXML charts."
Change-Id: I333b79be35a24a912bb9e662116d0c85809a8fb2
Reviewed-on: https://gerrit.libreoffice.org/75776
Reviewed-by: László Németh <nemeth at numbertext.org>
Tested-by: László Németh <nemeth at numbertext.org>
diff --git a/chart2/qa/extras/chart2import.cxx b/chart2/qa/extras/chart2import.cxx
index 107daed69fea..710d15ebd60e 100644
--- a/chart2/qa/extras/chart2import.cxx
+++ b/chart2/qa/extras/chart2import.cxx
@@ -131,6 +131,7 @@ public:
void testDataPointInheritedColorDOCX();
void testExternalStrRefsXLSX();
void testSourceNumberFormatComplexCategoriesXLS();
+ void testMultilevelCategoryAxis();
void testTdf123504();
void testTdf122765();
@@ -216,6 +217,7 @@ public:
CPPUNIT_TEST(testDataPointInheritedColorDOCX);
CPPUNIT_TEST(testExternalStrRefsXLSX);
CPPUNIT_TEST(testSourceNumberFormatComplexCategoriesXLS);
+ CPPUNIT_TEST(testMultilevelCategoryAxis);
CPPUNIT_TEST(testTdf123504);
CPPUNIT_TEST(testTdf122765);
@@ -1534,10 +1536,10 @@ void Chart2ImportTest::testInternalDataProvider() {
// Parse mixed types, mixed role
xDataSeq = rxDataProvider->createDataSequenceByValueArray("categories", "{42;\"hello\";0;\"world\"}");
xSequence = xDataSeq->getData();
- CPPUNIT_ASSERT_EQUAL(uno::Any(OUString("42")), xSequence[0]);
- CPPUNIT_ASSERT_EQUAL(uno::Any(OUString("hello")), xSequence[1]);
- CPPUNIT_ASSERT_EQUAL(uno::Any(OUString("0")), xSequence[2]);
- CPPUNIT_ASSERT_EQUAL(uno::Any(OUString("world")), xSequence[3]);
+ CPPUNIT_ASSERT_EQUAL(uno::Any(OUString("Row 1 42")), xSequence[0]);
+ CPPUNIT_ASSERT_EQUAL(uno::Any(OUString("Row 2 hello")), xSequence[1]);
+ CPPUNIT_ASSERT_EQUAL(uno::Any(OUString("Row 3 0")), xSequence[2]);
+ CPPUNIT_ASSERT_EQUAL(uno::Any(OUString("Row 4 world")), xSequence[3]);
}
void Chart2ImportTest::testTdf90510()
@@ -1946,6 +1948,34 @@ void Chart2ImportTest::testSourceNumberFormatComplexCategoriesXLS()
CPPUNIT_ASSERT(nNumberFormat != 0);
}
+void Chart2ImportTest::testMultilevelCategoryAxis()
+{
+ load("/chart2/qa/extras/data/docx/", "testMultilevelCategoryAxis.docx");
+ uno::Reference< chart2::XChartDocument > xChartDoc(getChartDocFromWriter(0), uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xChartDoc.is());
+
+ // Test the internal data.
+ CPPUNIT_ASSERT(xChartDoc->hasInternalDataProvider());
+
+ Reference<chart2::XInternalDataProvider> xInternalProvider(xChartDoc->getDataProvider(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xInternalProvider.is());
+
+ Reference<chart::XComplexDescriptionAccess> xDescAccess(xInternalProvider, uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xDescAccess.is());
+
+ // Get the complex category labels.
+ Sequence<Sequence<OUString> > aCategories = xDescAccess->getComplexRowDescriptions();
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(4), aCategories.getLength());
+ CPPUNIT_ASSERT_EQUAL(OUString("2011"), aCategories[0][0]);
+ CPPUNIT_ASSERT_EQUAL(OUString(""), aCategories[1][0]);
+ CPPUNIT_ASSERT_EQUAL(OUString("2012"), aCategories[2][0]);
+ CPPUNIT_ASSERT_EQUAL(OUString(""), aCategories[3][0]);
+ CPPUNIT_ASSERT_EQUAL(OUString("Categoria 1"), aCategories[0][1]);
+ CPPUNIT_ASSERT_EQUAL(OUString("Categoria 2"), aCategories[1][1]);
+ CPPUNIT_ASSERT_EQUAL(OUString("Categoria 3"), aCategories[2][1]);
+ CPPUNIT_ASSERT_EQUAL(OUString("Categoria 4"), aCategories[3][1]);
+}
+
void Chart2ImportTest::testTdf123504()
{
load("/chart2/qa/extras/data/ods/", "pie_chart_100_and_0.ods");
diff --git a/chart2/qa/extras/data/docx/testMultilevelCategoryAxis.docx b/chart2/qa/extras/data/docx/testMultilevelCategoryAxis.docx
new file mode 100644
index 000000000000..75605de72fc5
Binary files /dev/null and b/chart2/qa/extras/data/docx/testMultilevelCategoryAxis.docx differ
diff --git a/chart2/source/tools/InternalData.cxx b/chart2/source/tools/InternalData.cxx
index b99578fab118..b7a5118004ba 100644
--- a/chart2/source/tools/InternalData.cxx
+++ b/chart2/source/tools/InternalData.cxx
@@ -220,7 +220,16 @@ void InternalData::setComplexRowLabel( sal_Int32 nRowIndex, const vector< uno::A
m_aRowLabels.resize(nRowIndex+1);
enlargeData( 0, nRowIndex+1 );
}
- m_aRowLabels[nRowIndex] = rComplexLabel;
+ sal_Int32 nSize = static_cast<sal_Int32>( m_aRowLabels[nRowIndex].size() );
+ if( nSize >= 1 )
+ {
+ m_aRowLabels[nRowIndex].resize(nSize+1);
+ m_aRowLabels[nRowIndex][nSize] = rComplexLabel[0];
+ }
+ else
+ {
+ m_aRowLabels[nRowIndex] = rComplexLabel;
+ }
}
vector< uno::Any > InternalData::getComplexColumnLabel( sal_Int32 nColumnIndex ) const
diff --git a/include/oox/drawingml/chart/datasourcemodel.hxx b/include/oox/drawingml/chart/datasourcemodel.hxx
index 097bfd188720..e2d9336bf4b2 100644
--- a/include/oox/drawingml/chart/datasourcemodel.hxx
+++ b/include/oox/drawingml/chart/datasourcemodel.hxx
@@ -40,6 +40,7 @@ struct DataSequenceModel
OUString maFormula; /// Formula reference, e.g. into a spreadsheet.
OUString maFormatCode; /// Number format for double values.
sal_Int32 mnPointCount; /// Number of points in this series source.
+ sal_Int32 mnLevelCount; /// Number of category levels.
explicit DataSequenceModel();
~DataSequenceModel();
diff --git a/oox/source/drawingml/chart/chartconverter.cxx b/oox/source/drawingml/chart/chartconverter.cxx
index f86ea8adb760..538f9956abc7 100644
--- a/oox/source/drawingml/chart/chartconverter.cxx
+++ b/oox/source/drawingml/chart/chartconverter.cxx
@@ -56,12 +56,12 @@ static OUString lclGenerateApiString( const OUString& rString )
return "\"" + aRetString + "\"";
}
-static OUString lclGenerateApiArray(const std::vector<Any>& rRow)
+static OUString lclGenerateApiArray(const std::vector<Any>& rRow, sal_Int32 nStart, sal_Int32 nCount)
{
OSL_ENSURE( !rRow.empty(), "ChartConverter::lclGenerateApiArray - missing matrix values" );
OUStringBuffer aBuffer;
aBuffer.append( API_TOKEN_ARRAY_OPEN );
- for (auto aBeg = rRow.begin(), aIt = aBeg, aEnd = rRow.end(); aIt != aEnd; ++aIt)
+ for (auto aBeg = rRow.begin() + nStart, aIt = aBeg, aEnd = aBeg + nCount; aIt != aEnd; ++aIt)
{
double fValue = 0.0;
OUString aString;
@@ -124,21 +124,26 @@ Reference< XDataSequence > ChartConverter::createDataSequence(
if( rxDataProvider.is() )
{
OUString aRangeRep;
- if( !rDataSeq.maData.empty() )
+ if( !rDataSeq.maData.empty() ) try
{
// create a single-row array from constant source data
- std::vector<Any> aRow(rDataSeq.mnPointCount);
+ // (multiple levels in the case of complex categories)
+ std::vector<Any> aRow(rDataSeq.mnLevelCount * rDataSeq.mnPointCount);
for (auto const& elem : rDataSeq.maData)
aRow.at(elem.first) = elem.second;
- aRangeRep = lclGenerateApiArray(aRow);
- }
-
- if( !aRangeRep.isEmpty() ) try
- {
- // create the data sequence
- xDataSeq = rxDataProvider->createDataSequenceByValueArray(rRole, aRangeRep);
- return xDataSeq;
+ for (sal_Int32 i = rDataSeq.mnLevelCount-1; i >= 0; i--)
+ {
+ aRangeRep = lclGenerateApiArray( aRow, i * rDataSeq.mnPointCount, rDataSeq.mnPointCount);
+
+ if (!aRangeRep.isEmpty())
+ {
+ // create or add a new level to the data sequence
+ xDataSeq = rxDataProvider->createDataSequenceByValueArray(rRole, aRangeRep);
+ if (i == 0)
+ return xDataSeq;
+ }
+ }
}
catch( Exception& )
{
diff --git a/oox/source/drawingml/chart/datasourcecontext.cxx b/oox/source/drawingml/chart/datasourcecontext.cxx
index e50723b378d0..7fa7b12852a7 100644
--- a/oox/source/drawingml/chart/datasourcecontext.cxx
+++ b/oox/source/drawingml/chart/datasourcecontext.cxx
@@ -180,6 +180,7 @@ ContextHandlerRef StringSequenceContext::onCreateContext( sal_Int32 nElement, co
switch( nElement )
{
case C_TOKEN( f ):
+ case C_TOKEN( multiLvlStrCache ):
return this;
}
break;
@@ -206,6 +207,28 @@ ContextHandlerRef StringSequenceContext::onCreateContext( sal_Int32 nElement, co
}
break;
+ case C_TOKEN( multiLvlStrCache ):
+ switch (nElement)
+ {
+ case C_TOKEN( ptCount ):
+ mrModel.mnPointCount = rAttribs.getInteger(XML_val, -1);
+ mrModel.mnLevelCount--; // normalize level count
+ return nullptr;
+ case C_TOKEN( lvl ):
+ mrModel.mnLevelCount++;
+ return this;
+ }
+ break;
+
+ case C_TOKEN( lvl ):
+ switch (nElement)
+ {
+ case C_TOKEN(pt):
+ mnPtIndex = rAttribs.getInteger(XML_idx, -1);
+ return this;
+ }
+ break;
+
case C_TOKEN( pt ):
switch( nElement )
{
@@ -226,7 +249,7 @@ void StringSequenceContext::onCharacters( const OUString& rChars )
break;
case C_TOKEN( v ):
if( mnPtIndex >= 0 )
- mrModel.maData[ mnPtIndex ] <<= rChars;
+ mrModel.maData[ (mrModel.mnLevelCount-1) * mrModel.mnPointCount + mnPtIndex ] <<= rChars;
break;
}
}
diff --git a/oox/source/drawingml/chart/datasourcemodel.cxx b/oox/source/drawingml/chart/datasourcemodel.cxx
index c5c054e67a99..ecb9afe4f2cb 100644
--- a/oox/source/drawingml/chart/datasourcemodel.cxx
+++ b/oox/source/drawingml/chart/datasourcemodel.cxx
@@ -24,7 +24,8 @@ namespace drawingml {
namespace chart {
DataSequenceModel::DataSequenceModel() :
- mnPointCount( -1 )
+ mnPointCount( -1 ),
+ mnLevelCount( 1 )
{
}
diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx
index dd9d19651e29..ec19bc4042ad 100644
--- a/oox/source/export/chartexport.cxx
+++ b/oox/source/export/chartexport.cxx
@@ -515,8 +515,12 @@ Sequence< Sequence< OUString > > ChartExport::getSplitCategoriesList( const OUSt
aFinalSplitSource[nLevelCount - i - 1].realloc(aAnyCategories.getLength());
for (auto const& elemLabel : aAnyCategories)
{
- aFinalSplitSource[nLevelCount - i - 1][nElemLabel] = elemLabel[i].get<OUString>();
- nElemLabel++;
+ // make sure elemLabel[i] exists!
+ if (elemLabel.getLength() > i)
+ {
+ aFinalSplitSource[nLevelCount - i - 1][nElemLabel] = elemLabel[i].get<OUString>();
+ nElemLabel++;
+ }
}
}
return aFinalSplitSource;
More information about the Libreoffice-commits
mailing list