Kaydet (Commit) 6b5c0a5c authored tarafından Miklos Vajna's avatar Miklos Vajna

VML export: handle textbox text

Previously, we always exported the text of the shape itself. Bring the
VML export in sync with the drawingML export, where we only do that if
the shape doesn't have an associated textbox -- if that's the case, then
export the textbox's text instead.

CppunitTest_sw_ooxmlsdrexport's testFdo69636 is a reproducer for this
problem, the VML assert failed because of the lack of this.

Change-Id: Icb236579da4e3b74e983a95aa5675fed7862d1e1
üst 0d602133
......@@ -37,6 +37,8 @@ class OOX_DLLPUBLIC VMLTextExport
public:
virtual void WriteOutliner(const OutlinerParaObject& rParaObj) = 0;
virtual oox::drawingml::DrawingML& GetDrawingML() = 0;
/// Write the contents of the textbox that is associated to this shape in VML format.
virtual void WriteVMLTextBox(css::uno::Reference<css::drawing::XShape> xShape) = 0;
protected:
VMLTextExport() {}
virtual ~VMLTextExport() {}
......
......@@ -27,11 +27,13 @@
#include <rtl/ustring.hxx>
#include <tools/stream.hxx>
#include <comphelper/sequenceashashmap.hxx>
#include <svx/svdotext.hxx>
#include <vcl/cvtgrf.hxx>
#include <filter/msfilter/msdffimp.hxx>
#include <filter/msfilter/escherex.hxx>
#include <com/sun/star/drawing/XShape.hpp>
#include <com/sun/star/text/HoriOrientation.hpp>
#include <com/sun/star/text/VertOrientation.hpp>
#include <com/sun/star/text/RelOrientation.hpp>
......@@ -958,6 +960,17 @@ std::vector<OString> lcl_getShapeTypes()
return aRet;
}
bool lcl_isTextBox(const SdrObject* pSdrObject)
{
uno::Reference<beans::XPropertySet> xPropertySet(const_cast<SdrObject*>(pSdrObject)->getUnoShape(), uno::UNO_QUERY);
if (xPropertySet.is())
{
uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
return xPropertySetInfo->hasPropertyByName("TextBox") && xPropertySet->getPropertyValue("TextBox").get<bool>();
}
return false;
}
sal_Int32 VMLExport::StartShape()
{
if ( m_nShapeType == ESCHER_ShpInst_Nil )
......@@ -1092,9 +1105,9 @@ sal_Int32 VMLExport::StartShape()
m_pSerializer->startElementNS( XML_v, nShapeElement, XFastAttributeListRef( m_pShapeAttrList ) );
}
// now check if we have some text and we have a text exporter registered
// now check if we have some editeng text (not associated textbox) and we have a text exporter registered
const SdrTextObj* pTxtObj = PTR_CAST(SdrTextObj, m_pSdrObject);
if (pTxtObj && m_pTextExport && m_nShapeType != ESCHER_ShpInst_TextPlainText)
if (pTxtObj && m_pTextExport && m_nShapeType != ESCHER_ShpInst_TextPlainText && !IsWaterMarkShape(m_pSdrObject->GetName()) && !lcl_isTextBox(m_pSdrObject))
{
const OutlinerParaObject* pParaObj = 0;
bool bOwnParaObj = false;
......@@ -1132,6 +1145,26 @@ void VMLExport::EndShape( sal_Int32 nShapeElement )
{
if ( nShapeElement >= 0 )
{
if (m_pTextExport && lcl_isTextBox(m_pSdrObject))
{
uno::Reference<beans::XPropertySet> xPropertySet(const_cast<SdrObject*>(m_pSdrObject)->getUnoShape(), uno::UNO_QUERY);
comphelper::SequenceAsHashMap aCustomShapeProperties(xPropertySet->getPropertyValue("CustomShapeGeometry"));
sax_fastparser::FastAttributeList* pTextboxAttrList = m_pSerializer->createAttrList();
if (aCustomShapeProperties.find("TextPreRotateAngle") != aCustomShapeProperties.end())
{
sal_Int32 nTextRotateAngle = aCustomShapeProperties["TextPreRotateAngle"].get<sal_Int32>();
if (nTextRotateAngle == -270)
pTextboxAttrList->add(XML_style, "mso-layout-flow-alt:bottom-to-top");
}
sax_fastparser::XFastAttributeListRef xTextboxAttrList(pTextboxAttrList);
pTextboxAttrList = 0;
m_pSerializer->startElementNS(XML_v, XML_textbox, xTextboxAttrList);
m_pTextExport->WriteVMLTextBox(uno::Reference<drawing::XShape>(xPropertySet, uno::UNO_QUERY_THROW));
m_pSerializer->endElementNS(XML_v, XML_textbox);
}
// end of the shape
m_pSerializer->endElementNS( XML_v, nShapeElement );
}
......
......@@ -4582,6 +4582,14 @@ void DocxAttributeOutput::WriteTextBox(uno::Reference<drawing::XShape> xShape)
m_rExport.SdrExporter().writeDMLTextFrame(&aFrame, m_anchorId++, /*bTextBoxOnly=*/true);
}
void DocxAttributeOutput::WriteVMLTextBox(uno::Reference<drawing::XShape> xShape)
{
SwFrmFmt* pTextBox = SwTextBoxHelper::findTextBox(xShape);
const SwPosition* pAnchor = pTextBox->GetAnchor().GetCntntAnchor();
sw::Frame aFrame(*pTextBox, *pAnchor);
m_rExport.SdrExporter().writeVMLTextFrame(&aFrame, /*bTextBoxOnly=*/true);
}
oox::drawingml::DrawingML& DocxAttributeOutput::GetDrawingML()
{
return m_rDrawingML;
......
......@@ -918,6 +918,7 @@ public:
/// VMLTextExport
virtual void WriteOutliner(const OutlinerParaObject& rParaObj) SAL_OVERRIDE;
virtual void WriteVMLTextBox(css::uno::Reference<css::drawing::XShape> xShape) SAL_OVERRIDE;
/// DMLTextExport
virtual void WriteTextBox(css::uno::Reference<css::drawing::XShape> xShape) SAL_OVERRIDE;
virtual oox::drawingml::DrawingML& GetDrawingML() SAL_OVERRIDE;
......
......@@ -1405,7 +1405,7 @@ void DocxSdrExport::writeDMLTextFrame(sw::Frame* pParentFrame, int nAnchorId, bo
}
}
void DocxSdrExport::writeVMLTextFrame(sw::Frame* pParentFrame)
void DocxSdrExport::writeVMLTextFrame(sw::Frame* pParentFrame, bool bTextBoxOnly)
{
sax_fastparser::FSHelperPtr pFS = m_pImpl->m_pSerializer;
const SwFrmFmt& rFrmFmt = pParentFrame->GetFrmFmt();
......@@ -1446,38 +1446,44 @@ void DocxSdrExport::writeVMLTextFrame(sw::Frame* pParentFrame)
m_pImpl->m_pFlyFrameSize = 0;
m_pImpl->m_rExport.mpParentFrame = NULL;
pFS->startElementNS(XML_w, XML_pict, FSEND);
pFS->startElementNS(XML_v, XML_rect, xFlyAttrList);
m_pImpl->textFrameShadow(rFrmFmt);
if (m_pImpl->m_pFlyFillAttrList)
{
sax_fastparser::XFastAttributeListRef xFlyFillAttrList(m_pImpl->m_pFlyFillAttrList);
m_pImpl->m_pFlyFillAttrList = NULL;
pFS->singleElementNS(XML_v, XML_fill, xFlyFillAttrList);
}
if (m_pImpl->m_pDashLineStyleAttr)
if (!bTextBoxOnly)
{
sax_fastparser::XFastAttributeListRef xDashLineStyleAttr(m_pImpl->m_pDashLineStyleAttr);
m_pImpl->m_pDashLineStyleAttr = NULL;
pFS->singleElementNS(XML_v, XML_stroke, xDashLineStyleAttr);
pFS->startElementNS(XML_w, XML_pict, FSEND);
pFS->startElementNS(XML_v, XML_rect, xFlyAttrList);
m_pImpl->textFrameShadow(rFrmFmt);
if (m_pImpl->m_pFlyFillAttrList)
{
sax_fastparser::XFastAttributeListRef xFlyFillAttrList(m_pImpl->m_pFlyFillAttrList);
m_pImpl->m_pFlyFillAttrList = NULL;
pFS->singleElementNS(XML_v, XML_fill, xFlyFillAttrList);
}
if (m_pImpl->m_pDashLineStyleAttr)
{
sax_fastparser::XFastAttributeListRef xDashLineStyleAttr(m_pImpl->m_pDashLineStyleAttr);
m_pImpl->m_pDashLineStyleAttr = NULL;
pFS->singleElementNS(XML_v, XML_stroke, xDashLineStyleAttr);
}
pFS->startElementNS(XML_v, XML_textbox, xTextboxAttrList);
pFS->startElementNS(XML_w, XML_txbxContent, FSEND);
}
pFS->startElementNS(XML_v, XML_textbox, xTextboxAttrList);
pFS->startElementNS(XML_w, XML_txbxContent, FSEND);
m_pImpl->m_bFlyFrameGraphic = true;
m_pImpl->m_rExport.WriteText();
m_pImpl->m_bFlyFrameGraphic = false;
pFS->endElementNS(XML_w, XML_txbxContent);
pFS->endElementNS(XML_v, XML_textbox);
if (m_pImpl->m_pFlyWrapAttrList)
if (!bTextBoxOnly)
{
sax_fastparser::XFastAttributeListRef xFlyWrapAttrList(m_pImpl->m_pFlyWrapAttrList);
m_pImpl->m_pFlyWrapAttrList = NULL;
pFS->singleElementNS(XML_w10, XML_wrap, xFlyWrapAttrList);
}
pFS->endElementNS(XML_w, XML_txbxContent);
pFS->endElementNS(XML_v, XML_textbox);
pFS->endElementNS(XML_v, XML_rect);
pFS->endElementNS(XML_w, XML_pict);
if (m_pImpl->m_pFlyWrapAttrList)
{
sax_fastparser::XFastAttributeListRef xFlyWrapAttrList(m_pImpl->m_pFlyWrapAttrList);
m_pImpl->m_pFlyWrapAttrList = NULL;
pFS->singleElementNS(XML_w10, XML_wrap, xFlyWrapAttrList);
}
pFS->endElementNS(XML_v, XML_rect);
pFS->endElementNS(XML_w, XML_pict);
}
m_pImpl->m_bFrameBtLr = false;
}
......
......@@ -94,7 +94,7 @@ public:
/// Writes text frame in DML format.
void writeDMLTextFrame(sw::Frame* pParentFrame, int nAnchorId, bool bTextBoxOnly = false);
/// Writes text frame in VML format.
void writeVMLTextFrame(sw::Frame* pParentFrame);
void writeVMLTextFrame(sw::Frame* pParentFrame, bool bTextBoxOnly = false);
/// Undo the text direction mangling done by the frame btLr handler in writerfilter::dmapper::DomainMapper::lcl_startCharacterGroup()
bool checkFrameBtlr(SwNode* pStartNode, sax_fastparser::FastAttributeList* pTextboxAttrList = 0);
/// Is this a standalone TextFrame, or used as a TextBox of a shape?
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment