summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/qa/unit/data/ods/miscemptyrepeatedrowheights.odsbin0 -> 7038 bytes
-rwxr-xr-xsc/qa/unit/data/xlsx/miscrowheights.xlsxbin0 -> 8522 bytes
-rw-r--r--sc/qa/unit/subsequent_export-test.cxx74
-rw-r--r--sc/source/filter/excel/xetable.cxx81
-rw-r--r--sc/source/filter/inc/xetable.hxx4
5 files changed, 138 insertions, 21 deletions
diff --git a/sc/qa/unit/data/ods/miscemptyrepeatedrowheights.ods b/sc/qa/unit/data/ods/miscemptyrepeatedrowheights.ods
new file mode 100644
index 000000000000..5511ad9e99a2
--- /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 000000000000..dbdbc137e535
--- /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 26fe25c8bd18..844020d71461 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -77,6 +77,7 @@ public:
void test();
void testPasswordExport();
void testConditionalFormatExportXLSX();
+ void testMiscRowHeightExport();
CPPUNIT_TEST_SUITE(ScExportTest);
CPPUNIT_TEST(test);
@@ -84,6 +85,7 @@ public:
CPPUNIT_TEST(testPasswordExport);
#endif
CPPUNIT_TEST(testConditionalFormatExportXLSX);
+ CPPUNIT_TEST(testMiscRowHeightExport);
CPPUNIT_TEST_SUITE_END();
private:
@@ -297,6 +299,78 @@ void ScExportTest::testConditionalFormatExportXLSX()
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 ec54e15a4630..c44b32c1dcfa 100644
--- a/sc/source/filter/excel/xetable.cxx
+++ b/sc/source/filter/excel/xetable.cxx
@@ -1708,6 +1708,8 @@ XclExpRow::XclExpRow( const XclExpRoot& rRoot, sal_uInt32 nXclRow,
mnFlags( EXC_ROW_DEFAULTFLAGS ),
mnXFIndex( EXC_XF_DEFAULTCELL ),
mnOutlineLevel( 0 ),
+ mnXclRowRpt( 1 ),
+ mnCurrentRow( nXclRow ),
mbAlwaysEmpty( bAlwaysEmpty ),
mbEnabled( true )
{
@@ -1921,7 +1923,11 @@ void XclExpRow::WriteCellList( XclExpStream& rStrm )
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::InsertCell( XclExpCellRef xCell, size_t nPos, bool bIsMergedBase
void XclExpRow::WriteBody( XclExpStream& rStrm )
{
- rStrm << static_cast< sal_uInt16 >(mnXclRow)
+ rStrm << static_cast< sal_uInt16 >(mnCurrentRow)
<< GetFirstUsedXclCol()
<< GetFirstFreeXclCol()
<< mnHeight
@@ -1965,23 +1971,27 @@ void XclExpRow::SaveXml( XclExpXmlStream& rStrm )
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 );
+ }
}
// ----------------------------------------------------------------------------
@@ -2002,7 +2012,7 @@ void XclExpRowBuffer::AppendCell( XclExpCellRef xCell, bool bIsMergedBase )
void XclExpRowBuffer::CreateRows( SCROW nFirstFreeScRow )
{
if( nFirstFreeScRow > 0 )
- GetOrCreateRow( static_cast< sal_uInt16 >( nFirstFreeScRow - 1 ), true );
+ GetOrCreateRow( ::std::max ( nFirstFreeScRow - 1, GetMaxPos().Row() ), true );
}
void XclExpRowBuffer::Finalize( XclExpDefaultRowData& rDefRowData, const ScfUInt16Vec& rColXFIndexes )
@@ -2023,6 +2033,9 @@ void XclExpRowBuffer::Finalize( XclExpDefaultRowData& rDefRowData, const ScfUInt
XclExpDefaultRowData aMaxDefData;
size_t nMaxDefCount = 0;
// only look for default format in existing rows, if there are more than unused
+ XclExpRow* pPrev = NULL;
+ typedef std::vector< XclExpRow* > XclRepeatedRows;
+ XclRepeatedRows aRepeated;
for (itr = itrBeg; itr != itrEnd; ++itr)
{
const RowRef& rRow = itr->second;
@@ -2037,11 +2050,37 @@ void XclExpRowBuffer::Finalize( XclExpDefaultRowData& rDefRowData, const ScfUInt
aMaxDefData = aDefData;
}
}
+ if ( pPrev )
+ {
+ sal_uInt32 nRpt = rRow->GetXclRow() - pPrev->GetXclRow();
+ pPrev->SetXclRowRpt( nRpt );
+ if ( nRpt > 1 )
+ aRepeated.push_back( pPrev );
+ if ( pPrev->IsDefaultable())
+ {
+ XclExpDefaultRowData aDefData( *pPrev );
+ size_t& rnDefCount = aDefRowMap[ aDefData ];
+ rnDefCount += ( pPrev->GetXclRowRpt() - 1 );
+ if( rnDefCount > nMaxDefCount )
+ {
+ nMaxDefCount = rnDefCount;
+ aMaxDefData = aDefData;
+ }
+ }
+ }
+ pPrev = rRow.get();
}
-
// return the default row format to caller
rDefRowData = aMaxDefData;
+ // now disable repeating extra (empty) rows that are equal to
+ // default row height
+ for ( XclRepeatedRows::iterator it = aRepeated.begin(), it_end = aRepeated.end(); it != it_end; ++it)
+ {
+ if ( (*it)->GetXclRowRpt() > 1 && (*it)->GetHeight() == rDefRowData.mnHeight )
+ (*it)->SetXclRowRpt( 1 );
+ }
+
// *** Disable unused ROW records, find used area *** ---------------------
sal_uInt16 nFirstUsedXclCol = SAL_MAX_UINT16;
diff --git a/sc/source/filter/inc/xetable.hxx b/sc/source/filter/inc/xetable.hxx
index 41ec24b22266..3a2ec386921f 100644
--- a/sc/source/filter/inc/xetable.hxx
+++ b/sc/source/filter/inc/xetable.hxx
@@ -917,6 +917,8 @@ public:
virtual void Save( XclExpStream& rStrm );
virtual void SaveXml( XclExpXmlStream& rStrm );
+ inline sal_uInt32 GetXclRowRpt() const { return mnXclRowRpt; }
+ inline void SetXclRowRpt( sal_uInt32 nRpt ){ mnXclRowRpt = nRpt; }
private:
/** Initializes the record data. Called from constructors. */
void Init( sal_uInt16 nXclRow, XclExpRowOutlineBuffer* pOutlineBfr );
@@ -935,6 +937,8 @@ private:
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.
};