n#779642: Fixed floating tables import in writerfilter
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index ce07b6f..eec5e70 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -1164,8 +1164,23 @@ void Test::testN793998()
void Test::testN779642()
{
uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
// First problem: check that we have 2 tables, nesting caused the
// creation of outer one to fail
uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTables->getCount());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong number of imported tables", sal_Int32(2), xTables->getCount());
// Second problem: check that the outer table is in a frame, at the bottom of the page
uno::Reference<text::XTextTable> xTextTable(xTextTablesSupplier->getTextTables()->getByName("Table2"), uno::UNO_QUERY);
uno::Reference<beans::XPropertySet> xAnchor(xTextTable->getAnchor(), uno::UNO_QUERY);
uno::Any aFrame = xAnchor->getPropertyValue("TextFrame");
uno::Reference<beans::XPropertySet> xFrame;
aFrame >>= xFrame;
sal_Int16 nValue;
xFrame->getPropertyValue("VertOrient") >>= nValue;
CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong vertical orientation", nValue, text::VertOrientation::BOTTOM);
xFrame->getPropertyValue("VertOrientRelation") >>= nValue;
CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong vertical orientation relation", nValue, text::RelOrientation::PAGE_PRINT_AREA);
}
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
diff --git a/sw/source/core/unocore/unotext.cxx b/sw/source/core/unocore/unotext.cxx
index b9581ed..9651d91 100644
--- a/sw/source/core/unocore/unotext.cxx
+++ b/sw/source/core/unocore/unotext.cxx
@@ -1623,7 +1623,14 @@ throw (lang::IllegalArgumentException, uno::RuntimeException)
// remove the addtional paragraphs in the end
if (pStartStartNode->GetStartNodeType() == SwTableBoxStartNode)
{
SwTableNode *const pStartTableNode(pStartStartNode->FindTableNode());
SwTableNode * pStartTableNode(pStartStartNode->FindTableNode());
// Is it the same table start node than the end?
SwTableNode *const pEndStartTableNode(pEndStartNode->FindTableNode());
while (pEndStartTableNode->GetIndex() < pStartTableNode->GetIndex())
{
SwStartNode* pStartStartTableNode = pStartTableNode->StartOfSectionNode();
pStartTableNode = pStartStartTableNode->FindTableNode();
}
const SwNodeIndex aTblIdx( *pStartTableNode, -1 );
SwPosition aBefore(aTblIdx);
bParaBeforeInserted = GetDoc()->AppendTxtNode( aBefore );
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
index 46c418d..6f1a400 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
@@ -717,7 +717,8 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel)
uno::Reference<text::XTextRange> xStart;
uno::Reference<text::XTextRange> xEnd;
// If we want to make this table a floating one.
bool bFloating = !m_rDMapper_Impl.getTableManager().getTableVertAnchor().isEmpty();
uno::Sequence<beans::PropertyValue> aFrameProperties = m_rDMapper_Impl.getTableManager().getTablePosition();
bool bFloating = aFrameProperties.hasElements();
// Additional checks: if we can do this.
if (bFloating && (*m_pTableSeq)[0].getLength() > 0 && (*m_pTableSeq)[0][0].getLength() > 0)
{
@@ -764,46 +765,11 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel)
if (xTable.is() && xStart.is() && xEnd.is())
{
uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY);
uno::Sequence< beans::PropertyValue > aFrameProperties(16);
beans::PropertyValue* pFrameProperties = aFrameProperties.getArray();
pFrameProperties[0].Name = "Width";
pFrameProperties[0].Value = xTableProperties->getPropertyValue("Width");
aFrameProperties.realloc(aFrameProperties.getLength() + 1);
aFrameProperties[aFrameProperties.getLength() - 1].Name = "Width";
aFrameProperties[aFrameProperties.getLength() - 1].Value = xTableProperties->getPropertyValue("Width");
pFrameProperties[1].Name = "LeftBorderDistance";
pFrameProperties[1].Value <<= sal_Int32(0);
pFrameProperties[2].Name = "RightBorderDistance";
pFrameProperties[2].Value <<= sal_Int32(0);
pFrameProperties[3].Name = "TopBorderDistance";
pFrameProperties[3].Value <<= sal_Int32(0);
pFrameProperties[4].Name = "BottomBorderDistance";
pFrameProperties[4].Value <<= sal_Int32(0);
pFrameProperties[5].Name = "LeftMargin";
pFrameProperties[5].Value <<= sal_Int32(0);
pFrameProperties[6].Name = "RightMargin";
pFrameProperties[6].Value <<= sal_Int32(0);
pFrameProperties[7].Name = "TopMargin";
pFrameProperties[7].Value <<= sal_Int32(0);
pFrameProperties[8].Name = "BottomMargin";
pFrameProperties[8].Value <<= sal_Int32(0);
table::BorderLine2 aEmptyBorder;
pFrameProperties[9].Name = "TopBorder";
pFrameProperties[9].Value <<= aEmptyBorder;
pFrameProperties[10].Name = "BottomBorder";
pFrameProperties[10].Value <<= aEmptyBorder;
pFrameProperties[11].Name = "LeftBorder";
pFrameProperties[11].Value <<= aEmptyBorder;
pFrameProperties[12].Name = "RightBorder";
pFrameProperties[12].Value <<= aEmptyBorder;
pFrameProperties[13].Name = "HoriOrient";
pFrameProperties[13].Value <<= text::HoriOrientation::NONE;
pFrameProperties[14].Name = "HoriOrientRelation";
pFrameProperties[14].Value <<= text::RelOrientation::FRAME;
// A non-zero left margin would move the table out of the frame, move the frame itself instead.
pFrameProperties[15].Name = "HoriOrientPosition";
pFrameProperties[15].Value <<= xTableProperties->getPropertyValue("LeftMargin");
xTableProperties->setPropertyValue("LeftMargin", uno::makeAny(sal_Int32(0)));
uno::Reference< text::XTextContent > xFrame = m_xText->convertToTextFrame(xStart, xEnd, aFrameProperties);
diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.cxx b/writerfilter/source/dmapper/DomainMapperTableManager.cxx
index bdfe896..f09a3e2 100644
--- a/writerfilter/source/dmapper/DomainMapperTableManager.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableManager.cxx
@@ -324,7 +324,7 @@ bool DomainMapperTableManager::sprm(Sprm & rSprm)
{
TablePositionHandlerPtr pHandler( new TablePositionHandler );
pProperties->resolve(*pHandler);
m_sTableVertAnchor = pHandler->getVertAnchor();
m_aTablePosition = pHandler->getTablePosition();
}
}
break;
@@ -360,11 +360,6 @@ boost::shared_ptr< vector< sal_Int32 > > DomainMapperTableManager::getCurrentCel
return m_aCellWidths.back( );
}
const OUString& DomainMapperTableManager::getTableVertAnchor() const
{
return m_sTableVertAnchor;
}
void DomainMapperTableManager::startLevel( )
{
DomainMapperTableManager_Base_t::startLevel( );
@@ -580,8 +575,8 @@ void DomainMapperTableManager::clearData()
{
m_nRow = m_nCellBorderIndex = m_nHeaderRepeat = m_nTableWidth = 0;
m_sTableStyleName = OUString();
m_sTableVertAnchor = OUString();
m_pTableStyleTextProperies.reset();
m_aTablePosition = uno::Sequence<beans::PropertyValue>(0);
}
diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.hxx b/writerfilter/source/dmapper/DomainMapperTableManager.hxx
index bba5b5e..e18dcea 100644
--- a/writerfilter/source/dmapper/DomainMapperTableManager.hxx
+++ b/writerfilter/source/dmapper/DomainMapperTableManager.hxx
@@ -44,7 +44,7 @@ class DomainMapperTableManager : public DomainMapperTableManager_Base_t
sal_Int32 m_nTableWidth; //might be set directly or has to be calculated from the column positions
bool m_bOOXML;
OUString m_sTableStyleName;
OUString m_sTableVertAnchor;
com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> m_aTablePosition;
PropertyMapPtr m_pTableStyleTextProperies;
::std::vector< IntVectorPtr > m_aTableGrid;
@@ -81,7 +81,7 @@ public:
IntVectorPtr getCurrentCellWidths( );
const OUString& getTableStyleName() const { return m_sTableStyleName; }
const OUString& getTableVertAnchor() const;
const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> getTablePosition() { return m_aTablePosition; }
/// copy the text properties of the table style and its parent into pContext
void CopyTextProperties(PropertyMapPtr pContext, StyleSheetTablePtr pStyleSheetTable);
diff --git a/writerfilter/source/dmapper/TablePositionHandler.cxx b/writerfilter/source/dmapper/TablePositionHandler.cxx
index e7d872a..8ae6ac2 100644
--- a/writerfilter/source/dmapper/TablePositionHandler.cxx
+++ b/writerfilter/source/dmapper/TablePositionHandler.cxx
@@ -11,7 +11,9 @@
#include <doctok/resourceids.hxx>
#include <ConversionHelper.hxx>
#include <ooxml/resourceids.hxx>
#include <com/sun/star/text/SizeType.hpp>
#include <com/sun/star/text/HoriOrientation.hpp>
#include <com/sun/star/text/VertOrientation.hpp>
#include <com/sun/star/text/RelOrientation.hpp>
#include "dmapperLoggers.hxx"
namespace writerfilter {
@@ -20,7 +22,13 @@ namespace dmapper {
using namespace ::com::sun::star;
TablePositionHandler::TablePositionHandler() :
LoggedProperties(dmapper_logger, "TablePositionHandler")
LoggedProperties(dmapper_logger, "TablePositionHandler"),
m_aVertAnchor( "margin" ),
m_aYSpec( ),
m_aHorzAnchor( "text" ),
m_aXSpec( ),
m_nY( 0 ),
m_nX( 0 )
{
}
@@ -36,6 +44,21 @@ void TablePositionHandler::lcl_attribute(Id rName, Value& rVal)
case NS_ooxml::LN_CT_TblPPr_vertAnchor:
m_aVertAnchor = rVal.getString();
break;
case NS_ooxml::LN_CT_TblPPr_tblpYSpec:
m_aYSpec = rVal.getString();
break;
case NS_ooxml::LN_CT_TblPPr_horzAnchor:
m_aHorzAnchor = rVal.getString();
break;
case NS_ooxml::LN_CT_TblPPr_tblpXSpec:
m_aXSpec = rVal.getString();
break;
case NS_ooxml::LN_CT_TblPPr_tblpY:
m_nY = rVal.getInt();
break;
case NS_ooxml::LN_CT_TblPPr_tblpX:
m_nX = rVal.getInt();
break;
default:
#ifdef DEBUG_DOMAINMAPPER
dmapper_logger->element("unhandled");
@@ -50,9 +73,95 @@ void TablePositionHandler::lcl_sprm(Sprm& /*rSprm*/)
}
OUString TablePositionHandler::getVertAnchor() const
uno::Sequence<beans::PropertyValue> TablePositionHandler::getTablePosition() const
{
return m_aVertAnchor;
uno::Sequence< beans::PropertyValue > aFrameProperties(18);
beans::PropertyValue* pFrameProperties = aFrameProperties.getArray();
pFrameProperties[0].Name = "LeftBorderDistance";
pFrameProperties[0].Value <<= sal_Int32(0);
pFrameProperties[1].Name = "RightBorderDistance";
pFrameProperties[1].Value <<= sal_Int32(0);
pFrameProperties[2].Name = "TopBorderDistance";
pFrameProperties[2].Value <<= sal_Int32(0);
pFrameProperties[3].Name = "BottomBorderDistance";
pFrameProperties[3].Value <<= sal_Int32(0);
pFrameProperties[4].Name = "LeftMargin";
pFrameProperties[4].Value <<= sal_Int32(0);
pFrameProperties[5].Name = "RightMargin";
pFrameProperties[5].Value <<= sal_Int32(0);
pFrameProperties[6].Name = "TopMargin";
pFrameProperties[6].Value <<= sal_Int32(0);
pFrameProperties[7].Name = "BottomMargin";
pFrameProperties[7].Value <<= sal_Int32(0);
table::BorderLine2 aEmptyBorder;
pFrameProperties[8].Name = "TopBorder";
pFrameProperties[8].Value <<= aEmptyBorder;
pFrameProperties[9].Name = "BottomBorder";
pFrameProperties[9].Value <<= aEmptyBorder;
pFrameProperties[10].Name = "LeftBorder";
pFrameProperties[10].Value <<= aEmptyBorder;
pFrameProperties[11].Name = "RightBorder";
pFrameProperties[11].Value <<= aEmptyBorder;
// Horizontal positioning
sal_Int16 nHoriOrient = text::HoriOrientation::NONE;
if ( m_aXSpec == "center" )
nHoriOrient = text::HoriOrientation::CENTER;
else if ( m_aXSpec == "inside" )
nHoriOrient = text::HoriOrientation::INSIDE;
else if ( m_aXSpec == "left" )
nHoriOrient = text::HoriOrientation::LEFT;
else if ( m_aXSpec == "outside" )
nHoriOrient = text::HoriOrientation::OUTSIDE;
else if ( m_aXSpec == "right" )
nHoriOrient = text::HoriOrientation::RIGHT;
sal_Int16 nHoriOrientRelation;
if ( m_aHorzAnchor == "margin" )
nHoriOrientRelation = text::RelOrientation::PAGE_PRINT_AREA;
else if ( m_aHorzAnchor == "page" )
nHoriOrientRelation = text::RelOrientation::PAGE_FRAME;
else if ( m_aHorzAnchor == "text" )
nHoriOrientRelation = text::RelOrientation::FRAME;
pFrameProperties[12].Name = "HoriOrient";
pFrameProperties[12].Value <<= nHoriOrient;
pFrameProperties[13].Name = "HoriOrientRelation";
pFrameProperties[13].Value <<= nHoriOrientRelation;
pFrameProperties[14].Name = "HoriOrientPosition";
pFrameProperties[14].Value <<= m_nX;
// Vertical positioning
sal_Int16 nVertOrient = text::VertOrientation::NONE;
if ( m_aYSpec == "bottom" )
nVertOrient = text::VertOrientation::BOTTOM;
else if ( m_aYSpec == "center" )
nVertOrient = text::VertOrientation::CENTER;
else if ( m_aYSpec == "top" )
nVertOrient = text::VertOrientation::TOP;
// TODO There are a few cases we can't map ATM.
sal_Int16 nVertOrientRelation;
if ( m_aVertAnchor == "margin" )
nVertOrientRelation = text::RelOrientation::PAGE_PRINT_AREA;
else if ( m_aVertAnchor == "page" )
nVertOrientRelation = text::RelOrientation::PAGE_FRAME;
else if ( m_aVertAnchor == "text" )
nVertOrientRelation = text::RelOrientation::FRAME;
pFrameProperties[15].Name = "VertOrient";
pFrameProperties[15].Value <<= nVertOrient;
pFrameProperties[16].Name = "VertOrientRelation";
pFrameProperties[16].Value <<= nVertOrientRelation;
pFrameProperties[17].Name = "VertOrientPosition";
pFrameProperties[17].Value <<= m_nY;
return aFrameProperties;
}
} // namespace dmapper
diff --git a/writerfilter/source/dmapper/TablePositionHandler.hxx b/writerfilter/source/dmapper/TablePositionHandler.hxx
index ea4b154..dc096e687 100644
--- a/writerfilter/source/dmapper/TablePositionHandler.hxx
+++ b/writerfilter/source/dmapper/TablePositionHandler.hxx
@@ -12,6 +12,7 @@
#include <WriterFilterDllApi.hxx>
#include <resourcemodel/LoggedResources.hxx>
#include <boost/shared_ptr.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
namespace writerfilter {
namespace dmapper {
@@ -21,6 +22,11 @@ namespace writerfilter {
: public LoggedProperties
{
OUString m_aVertAnchor;
OUString m_aYSpec;
OUString m_aHorzAnchor;
OUString m_aXSpec;
sal_Int32 m_nY;
sal_Int32 m_nX;
// Properties
virtual void lcl_attribute(Id Name, Value & val);
@@ -30,7 +36,13 @@ namespace writerfilter {
TablePositionHandler();
virtual ~TablePositionHandler();
OUString getVertAnchor() const;
/** Compute the UNO properties for the frame containing the table based
on the received tokens.
Note that the properties will need to be adjusted with the table
properties before actually using them.
*/
com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> getTablePosition() const;
};
typedef boost::shared_ptr<TablePositionHandler> TablePositionHandlerPtr;
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index 73acba6..2dc9c6b 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -17946,7 +17946,7 @@
<xs:documentation>Relative Horizontal Alignment From Anchor</xs:documentation>
</attribute>
<attribute name="tblpX">
<text/>
<ref name="ST_SignedTwipsMeasure"/>
<xs:documentation>Absolute Horizontal Distance From Anchor</xs:documentation>
</attribute>
<attribute name="tblpYSpec">
@@ -17954,7 +17954,7 @@
<xs:documentation>Relative Vertical Alignment from Anchor</xs:documentation>
</attribute>
<attribute name="tblpY">
<text/>
<ref name="ST_SignedTwipsMeasure"/>
<xs:documentation>Absolute Vertical Distance From Anchor</xs:documentation>
</attribute>
</define>
@@ -22825,6 +22825,11 @@
</resource>
<resource name="CT_TblPPr" resource="Properties" tag="table">
<attribute name="vertAnchor" tokenid="ooxml:CT_TblPPr_vertAnchor"/>
<attribute name="tblpYSpec" tokenid="ooxml:CT_TblPPr_tblpYSpec"/>
<attribute name="horzAnchor" tokenid="ooxml:CT_TblPPr_horzAnchor"/>
<attribute name="tblpXSpec" tokenid="ooxml:CT_TblPPr_tblpXSpec"/>
<attribute name="tblpY" tokenid="ooxml:CT_TblPPr_tblpY"/>
<attribute name="tblpX" tokenid="ooxml:CT_TblPPr_tblpX"/>
</resource>
<resource name="CT_TblGridCol" resource="Value" tag="table">
<attribute name="w" tokenid="ooxml:CT_TblGridCol_w" action="setValue"/>