[Libreoffice-commits] core.git: 3 commits - sw/qa sw/source writerfilter/source
Miklos Vajna
vmiklos at collabora.co.uk
Wed Oct 15 04:19:44 PDT 2014
sw/qa/extras/rtfexport/data/fdo82860.odt |binary
sw/qa/extras/rtfexport/rtfexport.cxx | 10 +
sw/source/filter/ww8/rtfattributeoutput.cxx | 122 +++++++++++++---------
sw/source/filter/ww8/rtfattributeoutput.hxx | 3
sw/source/filter/ww8/rtfexport.cxx | 25 ++++
sw/source/filter/ww8/rtfexport.hxx | 8 +
sw/source/filter/ww8/rtfsdrexport.cxx | 31 +++++
sw/source/filter/ww8/rtfsdrexport.hxx | 8 +
writerfilter/source/dmapper/DomainMapper_Impl.cxx | 30 +++--
9 files changed, 175 insertions(+), 62 deletions(-)
New commits:
commit 5a5d55a8a0f82406a8001015a723596f21d3562c
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Wed Oct 15 13:00:24 2014 +0200
fdo#82860 RTF import: fix handling of SHAPE fields
No need to use fieldmarks for these.
Change-Id: I8d2c797f2b00be88e445dab0dd69cb1a9556c02c
diff --git a/sw/qa/extras/rtfexport/data/fdo82860.odt b/sw/qa/extras/rtfexport/data/fdo82860.odt
new file mode 100644
index 0000000..f680410
Binary files /dev/null and b/sw/qa/extras/rtfexport/data/fdo82860.odt differ
diff --git a/sw/qa/extras/rtfexport/rtfexport.cxx b/sw/qa/extras/rtfexport/rtfexport.cxx
index 5c74c53..2ffbb38 100644
--- a/sw/qa/extras/rtfexport/rtfexport.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport.cxx
@@ -709,6 +709,16 @@ DECLARE_RTFEXPORT_TEST(testNumberingFont, "numbering-font.rtf")
CPPUNIT_ASSERT_EQUAL(OUString("Verdana"), getProperty<OUString>(xStyle, "CharFontName"));
}
+DECLARE_RTFEXPORT_TEST(testFdo82860, "fdo82860.odt")
+{
+ // The problem was that:
+ // 1) The import tried to use fieldmarks for SHAPE fields
+ // 2) The exporter did not handle "shape with textbox" text.
+ uno::Reference<text::XTextRange> xTextRange(getShape(1), uno::UNO_QUERY);
+ uno::Reference<text::XText> xText = xTextRange->getText();
+ CPPUNIT_ASSERT_EQUAL(OUString("hello"), getParagraphOfText(1, xText)->getString());
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 8bdf7f7..adee004 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -4001,20 +4001,26 @@ void DomainMapper_Impl::CloseFieldCommand()
* To handle unsupported fields used fieldmark API.
*/
OUString aCode( pContext->GetCommand().trim() );
- xFieldInterface = m_xTextFactory->createInstance("com.sun.star.text.Fieldmark");
- const uno::Reference<text::XTextContent> xTextContent(xFieldInterface, uno::UNO_QUERY_THROW);
- uno::Reference< text::XTextAppend > xTextAppend;
- xTextAppend = m_aTextAppendStack.top().xTextAppend;
- uno::Reference< text::XTextCursor > xCrsr = xTextAppend->createTextCursorByRange(pContext->GetStartRange());
- if (xTextContent.is())
+ // Don't waste resources on wrapping shapes inside a fieldmark.
+ if (aCode != "SHAPE")
{
- xTextAppend->insertTextContent(xCrsr,xTextContent, sal_True);
+ xFieldInterface = m_xTextFactory->createInstance("com.sun.star.text.Fieldmark");
+ const uno::Reference<text::XTextContent> xTextContent(xFieldInterface, uno::UNO_QUERY_THROW);
+ uno::Reference< text::XTextAppend > xTextAppend;
+ xTextAppend = m_aTextAppendStack.top().xTextAppend;
+ uno::Reference< text::XTextCursor > xCrsr = xTextAppend->createTextCursorByRange(pContext->GetStartRange());
+ if (xTextContent.is())
+ {
+ xTextAppend->insertTextContent(xCrsr,xTextContent, sal_True);
+ }
+ const uno::Reference<uno::XInterface> xContent(xTextContent);
+ uno::Reference< text::XFormField> xFormField(xContent, uno::UNO_QUERY);
+ xFormField->setFieldType(aCode);
+ m_bStartGenericField = true;
+ pContext->SetFormField( xFormField );
}
- const uno::Reference<uno::XInterface> xContent(xTextContent);
- uno::Reference< text::XFormField> xFormField(xContent, uno::UNO_QUERY);
- xFormField->setFieldType(aCode);
- m_bStartGenericField = true;
- pContext->SetFormField( xFormField );
+ else
+ m_bParaHadField = false;
}
//set the text field if there is any
pContext->SetTextField( uno::Reference< text::XTextField >( xFieldInterface, uno::UNO_QUERY ) );
commit ecc5cbc69e4c2df4ddbe46bbc2f973cc60a10772
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Wed Oct 15 12:35:47 2014 +0200
fdo#82860 RTF export: if shape has textbox, export its contents as shape text
See 8c677716c4707ccd86b152ae504841affb393cc0 (DOCX drawingML export: if
shape has textbox, export its contents as shape text, 2014-06-06).
Change-Id: I5b1afae4d1b80c9b225096677f7d7ae77ff90f5b
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
index 0a26834..96c04c6 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -1592,6 +1592,75 @@ void lcl_TextFrameRelativeSize(std::vector< std::pair<OString, OString> >& rFlyP
}
}
+void RtfAttributeOutput::writeTextFrame(const sw::Frame& rFrame, bool bTextBox)
+{
+ RtfStringBuffer aRunText;
+ if (bTextBox)
+ {
+ m_rExport.setStream();
+ aRunText = m_aRunText;
+ m_aRunText.clear();
+ }
+
+ m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SHPTXT);
+
+ {
+ // Save table state, in case the inner text also contains a table.
+ ww8::WW8TableInfo::Pointer_t pTableInfoOrig = m_rExport.mpTableInfo;
+ m_rExport.mpTableInfo = ww8::WW8TableInfo::Pointer_t(new ww8::WW8TableInfo());
+ SwWriteTable* pTableWrt = m_pTableWrt;
+ m_pTableWrt = 0;
+ sal_uInt32 nTableDepth = m_nTableDepth;
+
+ m_nTableDepth = 0;
+ /*
+ * Save m_aRun as we should not lose the opening brace.
+ * OTOH, just drop the contents of m_aRunText in case something
+ * would be there, causing a problem later.
+ */
+ OString aSave = m_aRun.makeStringAndClear();
+ // Also back m_bInRun and m_bSingleEmptyRun up.
+ bool bInRunOrig = m_bInRun;
+ m_bInRun = false;
+ bool bSingleEmptyRunOrig = m_bSingleEmptyRun;
+ m_bSingleEmptyRun = false;
+ m_rExport.bRTFFlySyntax = true;
+
+ const SwFrmFmt& rFrmFmt = rFrame.GetFrmFmt();
+ const SwNodeIndex* pNodeIndex = rFrmFmt.GetCntnt().GetCntntIdx();
+ sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex()+1 : 0;
+ sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
+ m_rExport.SaveData(nStt, nEnd);
+ m_rExport.mpParentFrame = &rFrame;
+ m_rExport.WriteText();
+ m_rExport.RestoreData();
+
+ m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PARD);
+ m_rExport.bRTFFlySyntax = false;
+ m_aRun->append(aSave);
+ m_aRunText.clear();
+ m_bInRun = bInRunOrig;
+ m_bSingleEmptyRun = bSingleEmptyRunOrig;
+
+ // Restore table state.
+ m_rExport.mpTableInfo = pTableInfoOrig;
+ delete m_pTableWrt;
+ m_pTableWrt = pTableWrt;
+ m_nTableDepth = nTableDepth;
+ }
+
+ m_rExport.mpParentFrame = NULL;
+
+ m_rExport.Strm().WriteChar('}'); // shptxt
+
+ if (bTextBox)
+ {
+ m_aRunText = aRunText;
+ m_aRunText->append(m_rExport.getStream());
+ m_rExport.resetStream();
+ }
+}
+
void RtfAttributeOutput::OutputFlyFrame_Impl(const sw::Frame& rFrame, const Point& /*rNdTopLeft*/)
{
const SwNode* pNode = rFrame.GetContent();
@@ -1641,55 +1710,8 @@ void RtfAttributeOutput::OutputFlyFrame_Impl(const sw::Frame& rFrame, const Poin
}
m_aFlyProperties.clear();
- m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SHPTXT);
-
- {
- // Save table state, in case the inner text also contains a table.
- ww8::WW8TableInfo::Pointer_t pTableInfoOrig = m_rExport.mpTableInfo;
- m_rExport.mpTableInfo = ww8::WW8TableInfo::Pointer_t(new ww8::WW8TableInfo());
- SwWriteTable* pTableWrt = m_pTableWrt;
- m_pTableWrt = 0;
- sal_uInt32 nTableDepth = m_nTableDepth;
-
- m_nTableDepth = 0;
- /*
- * Save m_aRun as we should not lose the opening brace.
- * OTOH, just drop the contents of m_aRunText in case something
- * would be there, causing a problem later.
- */
- OString aSave = m_aRun.makeStringAndClear();
- // Also back m_bInRun and m_bSingleEmptyRun up.
- bool bInRunOrig = m_bInRun;
- m_bInRun = false;
- bool bSingleEmptyRunOrig = m_bSingleEmptyRun;
- m_bSingleEmptyRun = false;
- m_rExport.bRTFFlySyntax = true;
-
- const SwNodeIndex* pNodeIndex = rFrmFmt.GetCntnt().GetCntntIdx();
- sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex()+1 : 0;
- sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
- m_rExport.SaveData(nStt, nEnd);
- m_rExport.mpParentFrame = &rFrame;
- m_rExport.WriteText();
- m_rExport.RestoreData();
-
- m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PARD);
- m_rExport.bRTFFlySyntax = false;
- m_aRun->append(aSave);
- m_aRunText.clear();
- m_bInRun = bInRunOrig;
- m_bSingleEmptyRun = bSingleEmptyRunOrig;
-
- // Restore table state.
- m_rExport.mpTableInfo = pTableInfoOrig;
- delete m_pTableWrt;
- m_pTableWrt = pTableWrt;
- m_nTableDepth = nTableDepth;
- }
-
- m_rExport.mpParentFrame = NULL;
+ writeTextFrame(rFrame);
- m_rExport.Strm().WriteChar('}'); // shptxt
m_rExport.Strm().WriteChar('}'); // shpinst
m_rExport.Strm().WriteChar('}'); // shp
diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx
index f59a029..87b23ee 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.hxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.hxx
@@ -632,6 +632,9 @@ public:
static OString WriteHex(const sal_uInt8* pData, sal_uInt32 nSize, SvStream* pStream = 0, sal_uInt32 nLimit = 64);
void BulletDefinition(int nId, const Graphic& rGraphic, Size aSize) SAL_OVERRIDE;
+
+ /// Handles just the {\shptxt ...} part of a shape export.
+ void writeTextFrame(const sw::Frame& rFrame, bool bTextBox = false);
};
#endif // INCLUDED_SW_SOURCE_FILTER_WW8_RTFATTRIBUTEOUTPUT_HXX
diff --git a/sw/source/filter/ww8/rtfexport.cxx b/sw/source/filter/ww8/rtfexport.cxx
index 0d8e1d2..c776688 100644
--- a/sw/source/filter/ww8/rtfexport.cxx
+++ b/sw/source/filter/ww8/rtfexport.cxx
@@ -840,7 +840,30 @@ RtfExport::~RtfExport()
SvStream& RtfExport::Strm()
{
- return m_pWriter->Strm();
+ if (m_pStream)
+ return *m_pStream;
+ else
+ return m_pWriter->Strm();
+}
+
+void RtfExport::setStream()
+{
+ m_pStream.reset(new SvMemoryStream());
+}
+
+OString RtfExport::getStream()
+{
+ OString aRet;
+
+ if (m_pStream)
+ aRet = OString(static_cast<const sal_Char*>(m_pStream->GetData()), m_pStream->Tell());
+
+ return aRet;
+}
+
+void RtfExport::resetStream()
+{
+ m_pStream.reset();
}
SvStream& RtfExport::OutULong(sal_uLong nVal)
diff --git a/sw/source/filter/ww8/rtfexport.hxx b/sw/source/filter/ww8/rtfexport.hxx
index c384289..8045147 100644
--- a/sw/source/filter/ww8/rtfexport.hxx
+++ b/sw/source/filter/ww8/rtfexport.hxx
@@ -173,6 +173,12 @@ public:
sal_uLong m_nCurrentNodeIndex;
SvStream& Strm();
+ /// From now on, let Strm() return a memory stream, not a real one.
+ void setStream();
+ /// Get the contents of the memory stream as a string.
+ OString getStream();
+ /// Return back to the real stream.
+ void resetStream();
SvStream& OutULong(sal_uLong nVal);
SvStream& OutLong(long nVal);
void OutUnicode(const sal_Char* pToken, const OUString& rContent, bool bUpr = false);
@@ -211,6 +217,8 @@ private:
RtfColorTbl m_aColTbl;
RtfStyleTbl m_aStyTbl;
RtfRedlineTbl m_aRedlineTbl;
+ /// If set, then Strm() returns this tream, instead of m_pWriter's stream.
+ std::unique_ptr<SvMemoryStream> m_pStream;
};
#endif // INCLUDED_SW_SOURCE_FILTER_WW8_RTFEXPORT_HXX
diff --git a/sw/source/filter/ww8/rtfsdrexport.cxx b/sw/source/filter/ww8/rtfsdrexport.cxx
index e25ba1d..e4b86f2 100644
--- a/sw/source/filter/ww8/rtfsdrexport.cxx
+++ b/sw/source/filter/ww8/rtfsdrexport.cxx
@@ -28,6 +28,7 @@
#include <svx/unoapi.hxx>
#include <vcl/cvtgrf.hxx>
#include <textboxhelper.hxx>
+#include <dcontact.hxx>
#include <algorithm>
@@ -499,6 +500,27 @@ sal_Int32 RtfSdrExport::StartShape()
lcl_AppendSP(m_rAttrOutput.RunText(), "wzName", msfilter::rtfutil::OutString(m_pSdrObject->GetTitle(), m_rExport.eCurrentEncoding));
// now check if we have some text
+ const SwFrmFmt* pShape = FindFrmFmt(m_pSdrObject);
+ if (pShape)
+ {
+ if (SwFrmFmt* pTextBox = SwTextBoxHelper::findTextBox(pShape))
+ {
+ sw::Frame* pFrame = 0;
+ for (sw::FrameIter it = m_rExport.maFrames.begin(); it != m_rExport.maFrames.end(); ++it)
+ {
+ if (pTextBox == &it->GetFrmFmt())
+ {
+ pFrame = &(*it);
+ break;
+ }
+ }
+
+ if (pFrame)
+ m_rAttrOutput.writeTextFrame(*pFrame, /*bTextBox=*/true);
+ return m_nShapeType;
+ }
+ }
+
const SdrTextObj* pTxtObj = dynamic_cast<const SdrTextObj*>(m_pSdrObject);
if (pTxtObj)
{
commit f57ed7edd498d62ca0ed9a8cedd72218985b4daf
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Wed Oct 15 11:31:20 2014 +0200
fdo#82860 RTF export: don't export textboxes of shapes twice
See 96965fb39d6d376e91030a01c11f16f9428ddf2e (DOCX drawingML export:
don't export textboxes of shapes twice, 2014-06-06).
Change-Id: I89c039debeca5f88f172479b9f8ecbaec2dc7bc4
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
index a7eecbc..0a26834 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -1601,6 +1601,10 @@ void RtfAttributeOutput::OutputFlyFrame_Impl(const sw::Frame& rFrame, const Poin
{
case sw::Frame::eTxtBox:
{
+ // If this is a TextBox of a shape, then ignore: it's handled in RtfSdrExport::StartShape().
+ if (m_rExport.SdrExporter().isTextBox(rFrame.GetFrmFmt()))
+ break;
+
OSL_ENSURE(m_aRunText.getLength() == 0, "m_aRunText is not empty");
m_rExport.mpParentFrame = &rFrame;
diff --git a/sw/source/filter/ww8/rtfsdrexport.cxx b/sw/source/filter/ww8/rtfsdrexport.cxx
index 2b8e5fb..e25ba1d 100644
--- a/sw/source/filter/ww8/rtfsdrexport.cxx
+++ b/sw/source/filter/ww8/rtfsdrexport.cxx
@@ -27,6 +27,7 @@
#include <svx/svdotext.hxx>
#include <svx/unoapi.hxx>
#include <vcl/cvtgrf.hxx>
+#include <textboxhelper.hxx>
#include <algorithm>
@@ -41,7 +42,8 @@ RtfSdrExport::RtfSdrExport(RtfExport& rExport)
m_nShapeType(ESCHER_ShpInst_Nil),
m_nShapeFlags(0) ,
m_pShapeStyle(new OStringBuffer(200)),
- m_pShapeTypeWritten(new bool[ ESCHER_ShpInst_COUNT ])
+ m_pShapeTypeWritten(new bool[ ESCHER_ShpInst_COUNT ]),
+ m_aTextBoxes(SwTextBoxHelper::findTextBoxes(m_rExport.pDoc))
{
mnGroupLevel = 1;
memset(m_pShapeTypeWritten, 0, ESCHER_ShpInst_COUNT * sizeof(bool));
@@ -596,4 +598,9 @@ sal_uInt32 RtfSdrExport::AddSdrObject(const SdrObject& rObj)
return EscherEx::AddSdrObject(rObj);
}
+bool RtfSdrExport::isTextBox(const SwFrmFmt& rFrmFmt)
+{
+ return m_aTextBoxes.find(&rFrmFmt) != m_aTextBoxes.end();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/rtfsdrexport.hxx b/sw/source/filter/ww8/rtfsdrexport.hxx
index 449a538..026a601 100644
--- a/sw/source/filter/ww8/rtfsdrexport.hxx
+++ b/sw/source/filter/ww8/rtfsdrexport.hxx
@@ -25,9 +25,11 @@
#include <rtl/strbuf.hxx>
#include <map>
+#include <set>
class RtfExport;
class RtfAttributeOutput;
+class SwFrmFmt;
/// Handles export of drawings using RTF markup
class RtfSdrExport : public EscherEx
@@ -52,6 +54,9 @@ class RtfSdrExport : public EscherEx
/// Remember which shape types we had already written.
bool* m_pShapeTypeWritten;
+ /// List of TextBoxes in this document: they are exported as part of their shape, never alone.
+ std::set<const SwFrmFmt*> m_aTextBoxes;
+
public:
RtfSdrExport(RtfExport& rExport);
virtual ~RtfSdrExport();
@@ -61,6 +66,9 @@ public:
/// Call this when you need to export the object as Sdr in RTF.
sal_uInt32 AddSdrObject(const SdrObject& rObj);
+ /// Is this a standalone TextFrame, or used as a TextBox of a shape?
+ bool isTextBox(const SwFrmFmt& rFrmFmt);
+
protected:
/// Start the shape for which we just collected the information.
///
More information about the Libreoffice-commits
mailing list