diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-06-16 19:38:38 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-06-17 01:16:20 +0200 |
commit | 6b5c0a5cb25fc0c7c673a9332c8d30b6efbb819b (patch) | |
tree | 0b1aad541ecdec6993e372ee680d63ad8d3de93b | |
parent | 0d602133d627c1837eb64895855c2a7ed0144de6 (diff) |
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
-rw-r--r-- | include/oox/export/vmlexport.hxx | 2 | ||||
-rw-r--r-- | oox/source/export/vmlexport.cxx | 37 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.cxx | 8 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.hxx | 1 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxsdrexport.cxx | 58 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxsdrexport.hxx | 2 |
6 files changed, 79 insertions, 29 deletions
diff --git a/include/oox/export/vmlexport.hxx b/include/oox/export/vmlexport.hxx index 3a7049e65d6c..a87ed16eb90a 100644 --- a/include/oox/export/vmlexport.hxx +++ b/include/oox/export/vmlexport.hxx @@ -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() {} diff --git a/oox/source/export/vmlexport.cxx b/oox/source/export/vmlexport.cxx index f31576636944..b0d712eb7b27 100644 --- a/oox/source/export/vmlexport.cxx +++ b/oox/source/export/vmlexport.cxx @@ -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 ); } diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 479fe944fca5..1ca7ee3d4816 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -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; diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index 7990ed8749af..324b31aa7185 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -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; diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx index 50d0734afd29..bd580a0af37b 100644 --- a/sw/source/filter/ww8/docxsdrexport.cxx +++ b/sw/source/filter/ww8/docxsdrexport.cxx @@ -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; } diff --git a/sw/source/filter/ww8/docxsdrexport.hxx b/sw/source/filter/ww8/docxsdrexport.hxx index 5cda344ba7c0..09f2185ec931 100644 --- a/sw/source/filter/ww8/docxsdrexport.hxx +++ b/sw/source/filter/ww8/docxsdrexport.hxx @@ -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? |