summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2021-03-19 08:42:35 +0100
committerMiklos Vajna <vmiklos@collabora.com>2021-03-19 09:41:10 +0100
commit1001dbaef4dec2b51c25ed8343bab6910f1219e1 (patch)
treee5d8c9f3b591b1bc441783580c12fbeeeb7b8a15 /sw
parent54a8aefa3372dce3da7cf0ad846d55d1b7b92467 (diff)
ODT import: handle style name of covered cells
Similar to commit 66ac8e60896f6306bed8fbb34606fd14474f19ce (sw: fix unwanted long vertical border around vertically merged Word cell, 2021-03-04), but that one was for the DOCX import / rendering. Change-Id: I394a4f062544a9774b9b40ec757cb37e72220561 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112696 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
Diffstat (limited to 'sw')
-rw-r--r--sw/CppunitTest_sw_odfimport.mk2
-rw-r--r--sw/qa/extras/odfimport/data/vmerge-cell-border.odtbin0 -> 8996 bytes
-rw-r--r--sw/qa/extras/odfimport/odfimport.cxx24
-rw-r--r--sw/source/filter/xml/xmltbli.cxx58
-rw-r--r--sw/source/filter/xml/xmltbli.hxx10
5 files changed, 93 insertions, 1 deletions
diff --git a/sw/CppunitTest_sw_odfimport.mk b/sw/CppunitTest_sw_odfimport.mk
index 61a1547dd473..dabab5254279 100644
--- a/sw/CppunitTest_sw_odfimport.mk
+++ b/sw/CppunitTest_sw_odfimport.mk
@@ -19,11 +19,13 @@ $(eval $(call gb_CppunitTest_add_exception_objects,sw_odfimport, \
$(eval $(call gb_CppunitTest_use_libraries,sw_odfimport, \
comphelper \
+ editeng \
cppu \
cppuhelper \
sal \
svt \
sfx \
+ svl \
sw \
swqahelper \
test \
diff --git a/sw/qa/extras/odfimport/data/vmerge-cell-border.odt b/sw/qa/extras/odfimport/data/vmerge-cell-border.odt
new file mode 100644
index 000000000000..bf387bcb183e
--- /dev/null
+++ b/sw/qa/extras/odfimport/data/vmerge-cell-border.odt
Binary files differ
diff --git a/sw/qa/extras/odfimport/odfimport.cxx b/sw/qa/extras/odfimport/odfimport.cxx
index 6ab87d07a3de..ac7e34a9ebdd 100644
--- a/sw/qa/extras/odfimport/odfimport.cxx
+++ b/sw/qa/extras/odfimport/odfimport.cxx
@@ -43,6 +43,7 @@
#include <com/sun/star/style/ParagraphAdjust.hpp>
#include <comphelper/propertysequence.hxx>
+#include <editeng/boxitem.hxx>
#include <IDocumentSettingAccess.hxx>
#include <wrtsh.hxx>
@@ -54,6 +55,7 @@
#include <hintids.hxx>
#include <docsh.hxx>
#include <unotxdoc.hxx>
+#include <frmatr.hxx>
typedef std::map<OUString, css::uno::Sequence< css::table::BorderLine> > AllBordersMap;
typedef std::pair<OUString, css::uno::Sequence< css::table::BorderLine> > StringSequencePair;
@@ -1158,5 +1160,27 @@ CPPUNIT_TEST_FIXTURE(Test, testPasteFirstParaDirectFormat)
getProperty<sal_Int16>(xParagraph, "ParaAdjust"));
}
+CPPUNIT_TEST_FIXTURE(Test, testVerticallyMergedCellBorder)
+{
+ // Given a document with two cells, vertically merged, when loading the document:
+ SwDoc* pDoc = createSwDoc(mpTestDocumentPath, "vmerge-cell-border.odt");
+
+ // Then make sure that the first cell has a right border while the second has no right border:
+ SwDocShell* pDocShell = pDoc->GetDocShell();
+ SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+ pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);
+ SwShellCursor* pShellCursor = pWrtShell->getShellCursor(/*bBlock=*/false);
+ SwStartNode* pA1 = pShellCursor->Start()->nNode.GetNode().StartOfSectionNode();
+ const SwAttrSet& rA1Set = pA1->GetTableBox()->GetFrameFormat()->GetAttrSet();
+ CPPUNIT_ASSERT(rA1Set.GetBox().GetRight());
+ SwNodeIndex aA2(*pA1->EndOfSectionNode(), 1);
+ const SwAttrSet& rA2Set = aA2.GetNode().GetTableBox()->GetFrameFormat()->GetAttrSet();
+
+ // Without the accompanying fix in place, this test would have failed, as the A2 cell also had a
+ // right border, even if <table:covered-table-cell table:style-name="..."> explicitly disabled
+ // it.
+ CPPUNIT_ASSERT(!rA2Set.GetBox().GetRight());
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/xml/xmltbli.cxx b/sw/source/filter/xml/xmltbli.cxx
index e1deda38e2fa..041784f15ef7 100644
--- a/sw/source/filter/xml/xmltbli.cxx
+++ b/sw/source/filter/xml/xmltbli.cxx
@@ -127,6 +127,7 @@ public:
sal_uInt32 GetRowSpan() const { return nRowSpan; }
void SetRowSpan( sal_uInt32 nSet ) { nRowSpan = nSet; }
sal_uInt32 GetColSpan() const { return nColSpan; }
+ void SetStyleName(const OUString& rStyleName) { aStyleName = rStyleName; }
const OUString& GetStyleName() const { return aStyleName; }
const OUString& GetFormula() const { return sFormula; }
double GetValue() const { return dValue; }
@@ -333,6 +334,36 @@ public:
SwXMLImport& GetSwImport() { return static_cast<SwXMLImport&>(GetImport()); }
};
+/// Handles <table:covered-table-cell>.
+class SwXMLCoveredTableCellContext : public SvXMLImportContext
+{
+public:
+ SwXMLCoveredTableCellContext(SwXMLImport& rImport,
+ const Reference<xml::sax::XFastAttributeList>& xAttrList,
+ SwXMLTableContext& rTable);
+};
+
+SwXMLCoveredTableCellContext::SwXMLCoveredTableCellContext(
+ SwXMLImport& rImport, const Reference<xml::sax::XFastAttributeList>& xAttrList,
+ SwXMLTableContext& rTable)
+ : SvXMLImportContext(rImport)
+{
+ OUString aStyleName;
+ for (auto& rIter : sax_fastparser::castToFastAttributeList(xAttrList))
+ {
+ switch (rIter.getToken())
+ {
+ case XML_ELEMENT(TABLE, XML_STYLE_NAME):
+ aStyleName = rIter.toString();
+ break;
+ }
+ }
+
+ if (!aStyleName.isEmpty())
+ {
+ rTable.InsertCoveredCell(aStyleName);
+ }
+}
}
SwXMLTableCellContext_Impl::SwXMLTableCellContext_Impl(
@@ -831,7 +862,16 @@ css::uno::Reference<css::xml::sax::XFastContextHandler> SwXMLTableRowContext_Imp
}
else if( nElement == XML_ELEMENT(TABLE, XML_COVERED_TABLE_CELL) ||
nElement == XML_ELEMENT(LO_EXT, XML_COVERED_TABLE_CELL) )
- pContext = new SvXMLImportContext( GetImport() );
+ {
+ if (GetTable()->IsValid() && GetTable()->IsInsertCoveredCellPossible())
+ {
+ pContext = new SwXMLCoveredTableCellContext(GetSwImport(), xAttrList, *GetTable());
+ }
+ else
+ {
+ pContext = new SvXMLImportContext(GetImport());
+ }
+ }
else
SAL_WARN("sw", "unknown element " << SvXMLImport::getPrefixAndNameFromToken(nElement));
@@ -1101,6 +1141,7 @@ SwXMLTableContext::SwXMLTableContext( SwXMLImport& rImport,
m_nHeaderRows( 0 ),
m_nCurRow( 0 ),
m_nCurCol( 0 ),
+ m_nNonMergedCurCol( 0 ),
m_nWidth( 0 )
{
OUString aName;
@@ -1236,6 +1277,7 @@ SwXMLTableContext::SwXMLTableContext( SwXMLImport& rImport,
m_nHeaderRows( 0 ),
m_nCurRow( 0 ),
m_nCurCol( 0 ),
+ m_nNonMergedCurCol( 0 ),
m_nWidth( 0 )
{
}
@@ -1459,10 +1501,23 @@ void SwXMLTableContext::InsertCell( const OUString& rStyleName,
// Set current col to the next (free) column
m_nCurCol = nColsReq;
+ m_nNonMergedCurCol = nColsReq;
while( m_nCurCol<GetColumnCount() && GetCell(m_nCurRow,m_nCurCol)->IsUsed() )
m_nCurCol++;
}
+void SwXMLTableContext::InsertCoveredCell(const OUString& rStyleName)
+{
+ SwXMLTableCell_Impl* pCell = GetCell(m_nCurRow, m_nNonMergedCurCol);
+ ++m_nNonMergedCurCol;
+ if (!pCell)
+ {
+ return;
+ }
+
+ pCell->SetStyleName(rStyleName);
+}
+
void SwXMLTableContext::InsertRow( const OUString& rStyleName,
const OUString& rDfltCellStyleName,
bool bInHead )
@@ -1493,6 +1548,7 @@ void SwXMLTableContext::InsertRow( const OUString& rStyleName,
// We start at the first column ...
m_nCurCol=0;
+ m_nNonMergedCurCol = 0;
// ... but this cell may be occupied already.
while( m_nCurCol<GetColumnCount() && GetCell(m_nCurRow,m_nCurCol)->IsUsed() )
diff --git a/sw/source/filter/xml/xmltbli.hxx b/sw/source/filter/xml/xmltbli.hxx
index fc544f6c6886..d29dc4b989f7 100644
--- a/sw/source/filter/xml/xmltbli.hxx
+++ b/sw/source/filter/xml/xmltbli.hxx
@@ -92,6 +92,8 @@ class SwXMLTableContext : public XMLTextTableContext
sal_uInt16 m_nHeaderRows;
sal_uInt32 m_nCurRow;
sal_uInt32 m_nCurCol;
+ /// Same as m_nCurCol, but not incremented multiple times for table cells with row span.
+ sal_uInt32 m_nNonMergedCurCol;
sal_Int32 m_nWidth;
// The maximum table width (i.e., maximum value for m_nWidth); must be >= MINLAY and must also
@@ -156,6 +158,10 @@ public:
inline sal_uInt32 GetColumnCount() const;
bool IsInsertCellPossible() const { return m_nCurCol < GetColumnCount(); }
+
+ /// Determines if it's OK to insert a covered cell, given the total column count.
+ bool IsInsertCoveredCellPossible() const { return m_nNonMergedCurCol < GetColumnCount(); }
+
bool IsInsertColPossible() const { return m_nCurCol < USHRT_MAX; }
bool IsInsertRowPossible() const { return m_nCurRow < USHRT_MAX; }
bool IsValid() const { return m_pTableNode != nullptr; }
@@ -169,6 +175,10 @@ public:
bool bHasValue = false,
double fValue = 0.0,
OUString const*const pStringValue = nullptr);
+
+ /// Sets formatting of an already created covered cell.
+ void InsertCoveredCell(const OUString& rStyleName);
+
void InsertRow( const OUString& rStyleName,
const OUString& rDfltCellStyleName,
bool bInHead );