Hi,
I have submitted a patch for review:
https://gerrit.libreoffice.org/2004
To pull it, you can do:
git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/04/2004/1
correctly handle repeated row heights for empty rows ( fdo#59973 )
it seems both xls & xlsx export suffer from problems with multiple row heights
repeated ( if those rows are empty )
Change-Id: I3ed68a81517a3e55d1de1954fcb99e7cb39be337
---
A sc/qa/unit/data/ods/miscemptyrepeatedrowheights.ods
A sc/qa/unit/data/xlsx/miscrowheights.xlsx
M sc/qa/unit/subsequent_export-test.cxx
M sc/source/filter/excel/xetable.cxx
M sc/source/filter/inc/xetable.hxx
5 files changed, 105 insertions(+), 19 deletions(-)
diff --git a/sc/qa/unit/data/ods/miscemptyrepeatedrowheights.ods
b/sc/qa/unit/data/ods/miscemptyrepeatedrowheights.ods
new file mode 100644
index 0000000..5511ad9
--- /dev/null
+++ b/sc/qa/unit/data/ods/miscemptyrepeatedrowheights.ods
Binary files differ
diff --git a/sc/qa/unit/data/xlsx/miscrowheights.xlsx b/sc/qa/unit/data/xlsx/miscrowheights.xlsx
new file mode 100755
index 0000000..dbdbc13
--- /dev/null
+++ b/sc/qa/unit/data/xlsx/miscrowheights.xlsx
Binary files differ
diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx
index 26fe25c..844020d 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -77,6 +77,7 @@
void test();
void testPasswordExport();
void testConditionalFormatExportXLSX();
+ void testMiscRowHeightExport();
CPPUNIT_TEST_SUITE(ScExportTest);
CPPUNIT_TEST(test);
@@ -84,6 +85,7 @@
CPPUNIT_TEST(testPasswordExport);
#endif
CPPUNIT_TEST(testConditionalFormatExportXLSX);
+ CPPUNIT_TEST(testMiscRowHeightExport);
CPPUNIT_TEST_SUITE_END();
private:
@@ -297,6 +299,78 @@
testCondFile(aCSVPath, pDoc, 0);
}
+void ScExportTest::testMiscRowHeightExport()
+{
+
+ struct TestParam
+ {
+ struct RowData
+ {
+ SCROW nStartRow;
+ SCROW nEndRow;
+ SCTAB nTab;
+ int nExpectedHeight;
+ };
+ const char* sTestDoc;
+ int nImportType;
+ int nExportType;
+ int nRowData;
+ RowData* pData;
+ };
+
+ TestParam::RowData DfltRowData[] =
+ {
+ { 0, 4, 0, 529 },
+ { 5, 10, 0, 1058 },
+ { 17, 20, 0, 1767 },
+ { 1048573, 1048575, 0, 529 },
+ };
+
+ TestParam::RowData EmptyRepeatRowData[] =
+ {
+ { 0, 4, 0, 529 },
+ { 5, 10, 0, 1058 },
+ { 17, 20, 0, 1767 },
+ };
+
+ TestParam aTestValues[] =
+ {
+ { "miscrowheights.", XLSX, XLSX, SAL_N_ELEMENTS(DfltRowData), DfltRowData },
+ { "miscrowheights.", XLSX, XLS, SAL_N_ELEMENTS(DfltRowData), DfltRowData },
+ { "miscemptyrepeatedrowheights.", ODS, XLSX, SAL_N_ELEMENTS(EmptyRepeatRowData),
EmptyRepeatRowData },
+ { "miscemptyrepeatedrowheights.", ODS, XLS, SAL_N_ELEMENTS(EmptyRepeatRowData),
EmptyRepeatRowData },
+ };
+
+ for ( unsigned int index=0; index<SAL_N_ELEMENTS(aTestValues); ++index )
+ {
+ OUString sFileName = OUString::createFromAscii( aTestValues[ index ].sTestDoc );
+ printf("aTestValues[%d] %s\n", index, OUStringToOString( sFileName, RTL_TEXTENCODING_UTF8
).getStr() );
+ int nImportType = aTestValues[ index ].nImportType;
+ int nExportType = aTestValues[ index ].nExportType;
+ ScDocShellRef xShell = loadDocument( sFileName, nImportType );
+ CPPUNIT_ASSERT(xShell.Is());
+
+ ScDocShellRef xDocSh = saveAndReload(&(*xShell), nExportType );
+ CPPUNIT_ASSERT(xDocSh.Is());
+
+ ScDocument* pDoc = xDocSh->GetDocument();
+
+ for (int i=0; i<aTestValues[ index ].nRowData; ++i)
+ {
+ SCROW nRow = aTestValues[ index ].pData[ i].nStartRow;
+ SCROW nEndRow = aTestValues[ index ].pData[ i ].nEndRow;
+ SCTAB nTab = aTestValues[ index ].pData[ i ].nTab;
+ int nExpectedHeight = aTestValues[ index ].pData[ i ].nExpectedHeight;
+ for ( ; nRow <= nEndRow; ++nRow )
+ {
+ printf("\t checking row %d for height %d\n", nRow, nExpectedHeight );
+ int nHeight = sc::TwipsToHMM( pDoc->GetRowHeight(nRow, nTab, false) );
+ CPPUNIT_ASSERT_EQUAL(nExpectedHeight, nHeight);
+ }
+ }
+ }
+}
+
ScExportTest::ScExportTest()
: m_aBaseString(RTL_CONSTASCII_USTRINGPARAM("/sc/qa/unit/data"))
{
diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx
index ec54e15..9e1e2eb 100644
--- a/sc/source/filter/excel/xetable.cxx
+++ b/sc/source/filter/excel/xetable.cxx
@@ -1708,6 +1708,8 @@
mnFlags( EXC_ROW_DEFAULTFLAGS ),
mnXFIndex( EXC_XF_DEFAULTCELL ),
mnOutlineLevel( 0 ),
+ mnXclRowRpt( 1 ),
+ mnCurrentRow( nXclRow ),
mbAlwaysEmpty( bAlwaysEmpty ),
mbEnabled( true )
{
@@ -1921,7 +1923,11 @@
void XclExpRow::Save( XclExpStream& rStrm )
{
if( mbEnabled )
- XclExpRecord::Save( rStrm );
+ {
+ mnCurrentRow = mnXclRow;
+ for ( sal_uInt32 i = 0; i < mnXclRowRpt; ++i, ++mnCurrentRow )
+ XclExpRecord::Save( rStrm );
+ }
}
void XclExpRow::InsertCell( XclExpCellRef xCell, size_t nPos, bool bIsMergedBase )
@@ -1950,7 +1956,7 @@
void XclExpRow::WriteBody( XclExpStream& rStrm )
{
- rStrm << static_cast< sal_uInt16 >(mnXclRow)
+ rStrm << static_cast< sal_uInt16 >(mnCurrentRow)
<< GetFirstUsedXclCol()
<< GetFirstFreeXclCol()
<< mnHeight
@@ -1965,23 +1971,27 @@
return;
sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
bool haveFormat = ::get_flag( mnFlags, EXC_ROW_USEDEFXF );
- rWorksheet->startElement( XML_row,
- XML_r, OString::valueOf( (sal_Int32) (mnXclRow+1) ).getStr(),
- // OOXTODO: XML_spans, optional
- XML_s, haveFormat ? lcl_GetStyleId( rStrm, mnXFIndex ).getStr() : NULL,
- XML_customFormat, XclXmlUtils::ToPsz( haveFormat ),
- XML_ht, OString::valueOf( (double) mnHeight / 20.0 ).getStr(),
- XML_hidden, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_ROW_HIDDEN ) ),
- XML_customHeight, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_ROW_UNSYNCED ) ),
- XML_outlineLevel, OString::valueOf( (sal_Int32) mnOutlineLevel ).getStr(),
- XML_collapsed, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_ROW_COLLAPSED ) ),
- // OOXTODO: XML_thickTop, bool
- // OOXTODO: XML_thickBot, bool
- // OOXTODO: XML_ph, bool
- FSEND );
- // OOXTODO: XML_extLst
- maCellList.SaveXml( rStrm );
- rWorksheet->endElement( XML_row );
+ mnCurrentRow = mnXclRow + 1;
+ for ( sal_uInt32 i=0; i<mnXclRowRpt; ++i )
+ {
+ rWorksheet->startElement( XML_row,
+ XML_r, OString::valueOf( (sal_Int32) (mnCurrentRow++) ).getStr(),
+ // OOXTODO: XML_spans, optional
+ XML_s, haveFormat ? lcl_GetStyleId( rStrm, mnXFIndex ).getStr() :
NULL,
+ XML_customFormat, XclXmlUtils::ToPsz( haveFormat ),
+ XML_ht, OString::valueOf( (double) mnHeight / 20.0 ).getStr(),
+ XML_hidden, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_ROW_HIDDEN ) ),
+ XML_customHeight, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_ROW_UNSYNCED ) ),
+ XML_outlineLevel, OString::valueOf( (sal_Int32) mnOutlineLevel ).getStr(),
+ XML_collapsed, XclXmlUtils::ToPsz( ::get_flag( mnFlags, EXC_ROW_COLLAPSED ) ),
+ // OOXTODO: XML_thickTop, bool
+ // OOXTODO: XML_thickBot, bool
+ // OOXTODO: XML_ph, bool
+ FSEND );
+ // OOXTODO: XML_extLst
+ maCellList.SaveXml( rStrm );
+ rWorksheet->endElement( XML_row );
+ }
}
// ----------------------------------------------------------------------------
diff --git a/sc/source/filter/inc/xetable.hxx b/sc/source/filter/inc/xetable.hxx
index 41ec24b..553c025 100644
--- a/sc/source/filter/inc/xetable.hxx
+++ b/sc/source/filter/inc/xetable.hxx
@@ -935,6 +935,8 @@
sal_uInt16 mnFlags; /// Flags for the ROW record.
sal_uInt16 mnXFIndex; /// Default row formatting.
sal_uInt16 mnOutlineLevel; /// Outline Level (for OOXML)
+ sal_uInt32 mnXclRowRpt;
+ sal_uInt32 mnCurrentRow;
bool mbAlwaysEmpty; /// true = Do not add blank cells in Finalize().
bool mbEnabled; /// true = Write this ROW record.
};
--
To view, visit https://gerrit.libreoffice.org/2004
To unsubscribe, visit https://gerrit.libreoffice.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3ed68a81517a3e55d1de1954fcb99e7cb39be337
Gerrit-PatchSet: 1
Gerrit-Project: core
Gerrit-Branch: libreoffice-4-0
Gerrit-Owner: Noel Power <noel.power@suse.com>
Context
- [PATCH libreoffice-4-0] correctly handle repeated row heights for empty rows ( fdo#5... · Noel Power (via Code Review)
Privacy Policy |
Impressum (Legal Info) |
Copyright information: Unless otherwise specified, all text and images
on this website are licensed under the
Creative Commons Attribution-Share Alike 3.0 License.
This does not include the source code of LibreOffice, which is
licensed under the Mozilla Public License (
MPLv2).
"LibreOffice" and "The Document Foundation" are
registered trademarks of their corresponding registered owners or are
in actual use as trademarks in one or more countries. Their respective
logos and icons are also subject to international copyright laws. Use
thereof is explained in our
trademark policy.