summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/qa/extras/ooxmlexport/data/tdf129452_excessBorder.docxbin0 -> 11115 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport15.cxx11
-rw-r--r--writerfilter/source/dmapper/DomainMapperTableHandler.cxx22
-rw-r--r--writerfilter/source/dmapper/TableManager.cxx34
-rw-r--r--writerfilter/source/dmapper/TableManager.hxx4
5 files changed, 67 insertions, 4 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/tdf129452_excessBorder.docx b/sw/qa/extras/ooxmlexport/data/tdf129452_excessBorder.docx
new file mode 100644
index 000000000000..2bce3ff883bc
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf129452_excessBorder.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
index 27e2f22c2dbc..1e13de385fa4 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
@@ -45,6 +45,17 @@ DECLARE_OOXMLEXPORT_TEST(testTdf133370_columnBreak, "tdf133370_columnBreak.odt")
CPPUNIT_ASSERT_EQUAL(1, getPages());
}
+DECLARE_OOXMLEXPORT_TEST(testTdf129452_excessBorder, "tdf129452_excessBorder.docx")
+{
+ uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
+ uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY_THROW);
+
+ // The outside border should not be applied on inside cells. The merge doesn't extend to the table bottom.
+ // [Note: as humans, we would call this cell D3, but since row 4 hasn't been analyzed yet, it is considered column C.]
+ table::BorderLine2 aBorder = getProperty<table::BorderLine2>(xTable->getCellByName("C3"), "BottomBorder");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("No bottom border on merged cell", sal_uInt32(0), aBorder.LineWidth);
+}
DECLARE_OOXMLEXPORT_TEST(testTdf134063, "tdf134063.docx")
{
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
index 7da44a475efd..901fdfc0c115 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
@@ -758,6 +758,9 @@ CellPropertyValuesSeq_t DomainMapperTableHandler::endTableGetCellProperties(Tabl
}
}
+ // Note that this is intentionally called "cell" and not "column".
+ // Don't make the mistake that all cell x's will be in the same column.
+ // Merged cells (grid span) in a row will affect the actual column. (fake cells were added to handle gridBefore)
sal_Int32 nCell = 0;
pCellProperties[nRow].realloc( aRowOfCellsIterator->size() );
beans::PropertyValues* pSingleCellProperties = pCellProperties[nRow].getArray();
@@ -905,10 +908,20 @@ CellPropertyValuesSeq_t DomainMapperTableHandler::endTableGetCellProperties(Tabl
// tdf#129452 Checking if current cell is vertically merged with all the other cells below to the bottom.
// This must be done in order to apply the bottom border of the table to the first cell in a vertical merge.
bool bMergedVertically = bool(m_aCellProperties[nRow][nCell]->getProperty(PROP_VERTICAL_MERGE));
-
- for (size_t i = nRow + 1; bMergedVertically && i < m_aCellProperties.size(); i++)
- if ( m_aCellProperties[i].size() > sal::static_int_cast<std::size_t>(nCell) )
- bMergedVertically = bool(m_aCellProperties[i][nCell]->getProperty(PROP_VERTICAL_MERGE));
+ if ( bMergedVertically )
+ {
+ const sal_uInt32 nColumn = m_rDMapper_Impl.getTableManager().findColumn(nRow, nCell);
+ for (size_t i = nRow + 1; bMergedVertically && i < m_aCellProperties.size(); i++)
+ {
+ const sal_uInt32 nColumnCell = m_rDMapper_Impl.getTableManager().findColumnCell(i, nColumn);
+ if ( m_aCellProperties[i].size() > sal::static_int_cast<std::size_t>(nColumnCell) )
+ {
+ bMergedVertically = bool(m_aCellProperties[i][nColumnCell]->getProperty(PROP_VERTICAL_MERGE));
+ }
+ else
+ bMergedVertically = false;
+ }
+ }
lcl_computeCellBorders( rInfo.pTableBorders, *aCellIterator, nCell, nRow, bIsEndCol, bIsEndRow, bMergedVertically );
@@ -1231,6 +1244,7 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel, bool bTab
TableParagraphVectorPtr pTableParagraphs = m_rDMapper_Impl.getTableManager().getCurrentParagraphs();
for (size_t nRow = 0; nRow < m_aTableRanges.size(); ++nRow)
{
+ // Note that this is "cell" since you must not treat it as "column".
for (size_t nCell = 0; nCell < m_aTableRanges[nRow].size(); ++nCell)
{
auto rStartPara = m_aTableRanges[nRow][nCell][0];
diff --git a/writerfilter/source/dmapper/TableManager.cxx b/writerfilter/source/dmapper/TableManager.cxx
index 582b4d4705a6..2649ee1120e2 100644
--- a/writerfilter/source/dmapper/TableManager.cxx
+++ b/writerfilter/source/dmapper/TableManager.cxx
@@ -69,6 +69,40 @@ void TableManager::setCurrentGridSpan(sal_uInt32 nGridSpan)
mTableDataStack.top()->getCurrentRow()->setCurrentGridSpan(nGridSpan);
}
+sal_uInt32 TableManager::findColumn(const sal_uInt32 nRow, const sal_uInt32 nCell)
+{
+ RowData::Pointer_t pRow = mTableDataStack.top()->getRow(nRow);
+ if (!pRow || nCell < pRow->getGridBefore() || nCell >= pRow->getCellCount())
+ return SAL_MAX_UINT32;
+
+ // The gridSpans provide a one-based index, so add up all the spans of the PREVIOUS columns,
+ // and that result will provide the first possible zero-based number for the desired column.
+ sal_uInt32 nColumn = 0;
+ for (sal_uInt32 n = 0; n < nCell; ++n)
+ nColumn += pRow->getGridSpan(n);
+ return nColumn;
+}
+
+sal_uInt32 TableManager::findColumnCell(const sal_uInt32 nRow, const sal_uInt32 nCol)
+{
+ RowData::Pointer_t pRow = mTableDataStack.top()->getRow(nRow);
+ if (!pRow || nCol < pRow->getGridBefore())
+ return SAL_MAX_UINT32;
+
+ sal_uInt32 nCell = 0;
+ sal_uInt32 nGrids = 0;
+ // The gridSpans give us a one-based index, but requested column is zero-based - so keep that in mind.
+ for (const auto& rSpan : pRow->getGridSpans())
+ {
+ nGrids += rSpan;
+ if (nCol < nGrids)
+ return nCell;
+
+ ++nCell;
+ }
+ return SAL_MAX_UINT32; // must be in gridAfter or invalid column request
+}
+
void TableManager::endOfRowAction() {}
void TableManager::endOfCellAction() {}
diff --git a/writerfilter/source/dmapper/TableManager.hxx b/writerfilter/source/dmapper/TableManager.hxx
index d1c6ee431bc8..1cc7caaf958e 100644
--- a/writerfilter/source/dmapper/TableManager.hxx
+++ b/writerfilter/source/dmapper/TableManager.hxx
@@ -504,6 +504,10 @@ public:
void setCurrentGridBefore( sal_uInt32 nSkipGrids );
std::vector<sal_uInt32> getCurrentGridSpans();
void setCurrentGridSpan( sal_uInt32 nGridSpan );
+ /// Given a zero-based row/cell, return the zero-based grid it belongs to, or SAL_MAX_UINT16 for invalid.
+ sal_uInt32 findColumn( const sal_uInt32 nRow, const sal_uInt32 nCell );
+ /// Given a zero-based row/col, return the zero-based cell describing that grid, or SAL_MAX_UINT16 for invalid.
+ sal_uInt32 findColumnCell( const sal_uInt32 nRow, const sal_uInt32 nCol );
void setTableStartsAtCellStart(bool bTableStartsAtCellStart);
void setCellLastParaAfterAutospacing(bool bIsAfterAutospacing);