summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2021-03-19 08:42:35 +0100
committerMiklos Vajna <vmiklos@collabora.com>2021-03-22 10:28:00 +0100
commit60e43bafe25a8352b1658b0e12c855a48db4d2a2 (patch)
tree6530269f419aff7d22eb50d28f153c4edda92b0a
parent630e1a35d189d07a9bade63279ad179bbcd7318e (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. (cherry picked from commit 1001dbaef4dec2b51c25ed8343bab6910f1219e1) Conflicts: sw/qa/extras/odfimport/odfimport.cxx sw/source/filter/xml/xmltbli.cxx Change-Id: I394a4f062544a9774b9b40ec757cb37e72220561
-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.cxx26
-rw-r--r--sw/source/filter/xml/xmltbli.cxx71
-rw-r--r--sw/source/filter/xml/xmltbli.hxx10
5 files changed, 107 insertions, 2 deletions
diff --git a/sw/CppunitTest_sw_odfimport.mk b/sw/CppunitTest_sw_odfimport.mk
index bf227939f074..c3a3b535c8a4 100644
--- a/sw/CppunitTest_sw_odfimport.mk
+++ b/sw/CppunitTest_sw_odfimport.mk
@@ -17,11 +17,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 \
test \
unotest \
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 4df20d9e42a8..3aea453dfb2e 100644
--- a/sw/qa/extras/odfimport/odfimport.cxx
+++ b/sw/qa/extras/odfimport/odfimport.cxx
@@ -22,6 +22,7 @@
#include <com/sun/star/text/XTextTable.hpp>
#include <com/sun/star/text/PageNumberType.hpp>
#include <com/sun/star/text/VertOrientation.hpp>
+#include <editeng/boxitem.hxx>
#include <IDocumentSettingAccess.hxx>
#include <wrtsh.hxx>
@@ -31,6 +32,7 @@
#include <edtwin.hxx>
#include <olmenu.hxx>
#include <cmdid.h>
+#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;
@@ -935,5 +937,29 @@ DECLARE_ODFIMPORT_TEST(testTdf113289, "tdf113289.odt")
}
+DECLARE_ODFIMPORT_TEST(testVerticallyMergedCellBorder, "vmerge-cell-border.odt")
+{
+ // Given a document with two cells, vertically merged, when loading the document:
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+ SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
+
+ // 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 2207d929a9c4..ed73304a7e5d 100644
--- a/sw/source/filter/xml/xmltbli.cxx
+++ b/sw/source/filter/xml/xmltbli.cxx
@@ -218,6 +218,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; }
@@ -436,6 +437,47 @@ 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::XAttributeList>& xAttrList,
+ SwXMLTableContext& rTable);
+};
+
+SwXMLCoveredTableCellContext::SwXMLCoveredTableCellContext(
+ SwXMLImport& rImport, const Reference<xml::sax::XAttributeList>& xAttrList,
+ SwXMLTableContext& rTable)
+ : SvXMLImportContext(rImport)
+{
+ OUString aStyleName;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ const OUString& rAttrName = xAttrList->getNameByIndex( i );
+
+ OUString aLocalName;
+ const sal_uInt16 nPrefix =
+ GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
+ &aLocalName );
+ const OUString& rValue = xAttrList->getValueByIndex( i );
+ const SvXMLTokenMap& rTokenMap =
+ rImport.GetTableCellAttrTokenMap();
+ switch( rTokenMap.Get( nPrefix, aLocalName ) )
+ {
+ case XML_TOK_TABLE_STYLE_NAME:
+ aStyleName = rValue;
+ break;
+ }
+ }
+
+ if (!aStyleName.isEmpty())
+ {
+ rTable.InsertCoveredCell(aStyleName);
+ }
+}
+
SwXMLTableCellContext_Impl::SwXMLTableCellContext_Impl(
SwXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
const Reference< xml::sax::XAttributeList > & xAttrList,
@@ -966,8 +1008,17 @@ SvXMLImportContextRef SwXMLTableRowContext_Impl::CreateChildContext(
GetTable() );
}
else if( IsXMLToken( rLocalName, XML_COVERED_TABLE_CELL ) )
- pContext = new SvXMLImportContext( GetImport(), nPrefix,
- rLocalName );
+ {
+ if (GetTable()->IsValid() && GetTable()->IsInsertCoveredCellPossible())
+ {
+ pContext = new SwXMLCoveredTableCellContext(GetSwImport(), xAttrList, *GetTable());
+ }
+ else
+ {
+ pContext = new SvXMLImportContext( GetImport(), nPrefix,
+ rLocalName );
+ }
+ }
}
if( !pContext )
@@ -1262,6 +1313,7 @@ SwXMLTableContext::SwXMLTableContext( SwXMLImport& rImport,
m_nHeaderRows( 0 ),
m_nCurRow( 0 ),
m_nCurCol( 0 ),
+ m_nNonMergedCurCol( 0 ),
m_nWidth( 0 )
{
OUString aName;
@@ -1402,6 +1454,7 @@ SwXMLTableContext::SwXMLTableContext( SwXMLImport& rImport,
m_nHeaderRows( 0 ),
m_nCurRow( 0 ),
m_nCurCol( 0 ),
+ m_nNonMergedCurCol( 0 ),
m_nWidth( 0 )
{
}
@@ -1634,10 +1687,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,
@@ -1669,6 +1735,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 157be580f67f..a2e39f0d2c47 100644
--- a/sw/source/filter/xml/xmltbli.hxx
+++ b/sw/source/filter/xml/xmltbli.hxx
@@ -90,6 +90,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; }
@@ -170,6 +176,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,