[Libreoffice-commits] core.git: 2 commits - sw/qa sw/source writerfilter/inc writerfilter/source
Mike Kaganski
mikekaganski at hotmail.com
Tue May 12 03:51:23 PDT 2015
sw/qa/extras/rtfimport/data/copypaste-footnote-paste.rtf | 3 -
sw/source/filter/rtf/swparrtf.cxx | 25 ++++++++++++++-
writerfilter/inc/rtftok/RTFDocument.hxx | 3 +
writerfilter/source/dmapper/DomainMapper.cxx | 3 +
writerfilter/source/dmapper/DomainMapper_Impl.cxx | 4 +-
writerfilter/source/filter/RtfFilter.cxx | 3 +
writerfilter/source/rtftok/rtfdocumentfactory.cxx | 5 +--
writerfilter/source/rtftok/rtfdocumentimpl.cxx | 13 ++++---
writerfilter/source/rtftok/rtfdocumentimpl.hxx | 6 +++
9 files changed, 50 insertions(+), 15 deletions(-)
New commits:
commit 0ddd9f9ff45f61013ea18763eca4c68aedce6caa
Author: Mike Kaganski <mikekaganski at hotmail.com>
Date: Mon May 11 02:31:39 2015 +1000
tdf#70318: don't forget to clean up second fake paragraph
RTF insert is made into an empty paragraph. To do that, two splits
are made before the insert, but only one is reverted afterwards.
This patch removes the second.
Also fixes a memory leak from unreleased heap object
The corresponding unit test is corrected. It was incorrect
because \par doesn't begin new paragraph; it only ends paragraph.
If a RTF is ended with \par } then no newline is added to its end.
The old unit test only worked because of the bug fixed by this
patch. Correct way of inserting new paragraph in the end of a RTF
is \par \par}
Change-Id: I63d50a940d7960beb35f7d774c833ed8499acbef
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index 648f3ea..f0a1449 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -287,7 +287,7 @@ void SwUiWriterTest::testImportRTF()
CPPUNIT_ASSERT_EQUAL(sal_uLong(0), aReader.Read(*pRTFReader));
sal_uLong nIndex = pWrtShell->GetCrsr()->GetNode().GetIndex();
- //CPPUNIT_ASSERT_EQUAL(OUString("fooHello world!"), pDoc->GetNodes()[nIndex - 1]->GetTxtNode()->GetTxt());
+ CPPUNIT_ASSERT_EQUAL(OUString("fooHello world!"), pDoc->GetNodes()[nIndex - 1]->GetTxtNode()->GetTxt());
CPPUNIT_ASSERT_EQUAL(OUString("bar"), pDoc->GetNodes()[nIndex]->GetTxtNode()->GetTxt());
}
diff --git a/sw/source/filter/rtf/swparrtf.cxx b/sw/source/filter/rtf/swparrtf.cxx
index 2730561b..987fba8 100644
--- a/sw/source/filter/rtf/swparrtf.cxx
+++ b/sw/source/filter/rtf/swparrtf.cxx
@@ -50,7 +50,7 @@ sal_uLong SwRTFReader::Read(SwDoc& rDoc, const OUString& /*rBaseURL*/, SwPaM& rP
// Step 1: XTextRange will be updated when content is inserted, so we know
// the end position.
const uno::Reference<text::XTextRange> xInsertPosition = SwXTextRange::CreateXTextRange(rDoc, *rPam.GetPoint(), 0);
- SwNodeIndex* pSttNdIdx = new SwNodeIndex(rDoc.GetNodes());
+ std::shared_ptr<SwNodeIndex> pSttNdIdx(new SwNodeIndex(rDoc.GetNodes()));
const SwPosition* pPos = rPam.GetPoint();
// Step 2: Split once and remember the node that has been split.
@@ -59,6 +59,8 @@ sal_uLong SwRTFReader::Read(SwDoc& rDoc, const OUString& /*rBaseURL*/, SwPaM& rP
// Step 3: Split again.
rDoc.getIDocumentContentOperations().SplitNode(*pPos, false);
+ std::shared_ptr<SwNodeIndex> pSttNdIdx2(new SwNodeIndex(rDoc.GetNodes()));
+ *pSttNdIdx2 = pPos->nNode.GetIndex();
// Step 4: Insert all content into the new node
rPam.Move(fnMoveBackward);
@@ -126,6 +128,27 @@ sal_uLong SwRTFReader::Read(SwDoc& rDoc, const OUString& /*rBaseURL*/, SwPaM& rP
}
}
+ if (pSttNdIdx2->GetIndex())
+ {
+ // If we are in insert mode, join the split node that is after
+ // the new content with the last new node. Or in other words:
+ // Revert the second split node.
+ SwTxtNode* pTxtNode = pSttNdIdx2->GetNode().GetTxtNode();
+ SwNodeIndex aPrevIdx(*pSttNdIdx2);
+ if (pTxtNode && pTxtNode->CanJoinPrev(&aPrevIdx) && pSttNdIdx2->GetIndex() - 1 == aPrevIdx.GetIndex())
+ {
+ // If the last new node isn't empty, convert the node's text
+ // attributes into hints. Otherwise, set the new node's
+ // paragraph style at the next (empty) node.
+ SwTxtNode* pDelNd = aPrevIdx.GetNode().GetTxtNode();
+ if (pTxtNode->GetTxt().getLength())
+ pDelNd->FmtToTxtAttr(pTxtNode);
+ else
+ pTxtNode->ChgFmtColl(pDelNd->GetTxtColl());
+ pTxtNode->JoinPrev();
+ }
+ }
+
return ret;
}
commit e702c78843e387d83fd9c8fbd1597cbe27e3e656
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Mon May 11 23:24:22 2015 +0200
tdf#90260 writerfilter: pasted RTF documents may contain no \par
sw core is not yet adapted, will be done in the next commit.
Change-Id: If8da12427e0cdaced4c1c1776b9f0b8cbde5c57c
diff --git a/sw/qa/extras/rtfimport/data/copypaste-footnote-paste.rtf b/sw/qa/extras/rtfimport/data/copypaste-footnote-paste.rtf
index 1f4a75e..a7c6bb2 100644
--- a/sw/qa/extras/rtfimport/data/copypaste-footnote-paste.rtf
+++ b/sw/qa/extras/rtfimport/data/copypaste-footnote-paste.rtf
@@ -1,3 +1,2 @@
{\rtf1
-bbb
-\par }
+bbb}
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index f0a1449..648f3ea 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -287,7 +287,7 @@ void SwUiWriterTest::testImportRTF()
CPPUNIT_ASSERT_EQUAL(sal_uLong(0), aReader.Read(*pRTFReader));
sal_uLong nIndex = pWrtShell->GetCrsr()->GetNode().GetIndex();
- CPPUNIT_ASSERT_EQUAL(OUString("fooHello world!"), pDoc->GetNodes()[nIndex - 1]->GetTxtNode()->GetTxt());
+ //CPPUNIT_ASSERT_EQUAL(OUString("fooHello world!"), pDoc->GetNodes()[nIndex - 1]->GetTxtNode()->GetTxt());
CPPUNIT_ASSERT_EQUAL(OUString("bar"), pDoc->GetNodes()[nIndex]->GetTxtNode()->GetTxt());
}
diff --git a/writerfilter/inc/rtftok/RTFDocument.hxx b/writerfilter/inc/rtftok/RTFDocument.hxx
index bea19a4..01a9880 100644
--- a/writerfilter/inc/rtftok/RTFDocument.hxx
+++ b/writerfilter/inc/rtftok/RTFDocument.hxx
@@ -43,7 +43,8 @@ public:
css::uno::Reference<css::io::XInputStream> const& xInputStream,
css::uno::Reference<css::lang::XComponent> const& xDstDoc,
css::uno::Reference<css::frame::XFrame> const& xFrame,
- css::uno::Reference<css::task::XStatusIndicator> const& xStatusIndicator);
+ css::uno::Reference<css::task::XStatusIndicator> const& xStatusIndicator,
+ bool bIsNewDoc);
};
} // namespace rtftok
} // namespace writerfilter
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 70a59ed..5634ff3 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -2651,7 +2651,8 @@ void DomainMapper::lcl_endSectionGroup()
m_pImpl->ExecuteFrameConversion();
// First paragraph in a footnote doesn't count: that would create
// additional paragraphs before and after the real footnote content.
- if(m_pImpl->GetIsFirstParagraphInSection() && !m_pImpl->IsInFootOrEndnote())
+ // Also, when pasting, it's fine to not have any paragraph inside the document at all.
+ if (m_pImpl->GetIsFirstParagraphInSection() && !m_pImpl->IsInFootOrEndnote() && m_pImpl->IsNewDoc())
{
// This section has no paragraph at all (e.g. they are all actually in a frame).
// If this section has a page break, there would be nothing to apply to the page
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 337930b..b0d4ca5 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -266,7 +266,9 @@ DomainMapper_Impl::DomainMapper_Impl(
DomainMapper_Impl::~DomainMapper_Impl()
{
ChainTextFrames();
- RemoveLastParagraph( );
+ // Don't remove last paragraph when pasting, sw expects that empty paragraph.
+ if (m_bIsNewDoc)
+ RemoveLastParagraph();
getTableManager( ).endLevel();
popTableManager( );
}
diff --git a/writerfilter/source/filter/RtfFilter.cxx b/writerfilter/source/filter/RtfFilter.cxx
index bea67c9..7bf88b2 100644
--- a/writerfilter/source/filter/RtfFilter.cxx
+++ b/writerfilter/source/filter/RtfFilter.cxx
@@ -147,7 +147,8 @@ sal_Bool RtfFilter::filter(const uno::Sequence< beans::PropertyValue >& aDescrip
writerfilter::dmapper::SourceDocumentType eType = writerfilter::dmapper::SourceDocumentType::RTF;
writerfilter::Stream::Pointer_t pStream(
writerfilter::dmapper::DomainMapperFactory::createMapper(m_xContext, xInputStream, m_xDstDoc, bRepairStorage, eType, xInsertTextRange, aMediaDesc));
- writerfilter::rtftok::RTFDocument::Pointer_t pDocument(writerfilter::rtftok::RTFDocumentFactory::createDocument(m_xContext, xInputStream, m_xDstDoc, xFrame, xStatusIndicator));
+ writerfilter::rtftok::RTFDocument::Pointer_t pDocument(
+ writerfilter::rtftok::RTFDocumentFactory::createDocument(m_xContext, xInputStream, m_xDstDoc, xFrame, xStatusIndicator, bIsNewDoc));
pDocument->resolve(*pStream);
bResult = true;
sal_uInt32 nEndTime = osl_getGlobalTimer();
diff --git a/writerfilter/source/rtftok/rtfdocumentfactory.cxx b/writerfilter/source/rtftok/rtfdocumentfactory.cxx
index ace9ad3..0722bff 100644
--- a/writerfilter/source/rtftok/rtfdocumentfactory.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentfactory.cxx
@@ -18,9 +18,10 @@ RTFDocument::Pointer_t RTFDocumentFactory::createDocument(css::uno::Reference< c
css::uno::Reference< css::io::XInputStream > const& xInputStream,
css::uno::Reference< css::lang::XComponent > const& xDstDoc,
css::uno::Reference< css::frame::XFrame > const& xFrame,
- css::uno::Reference< css::task::XStatusIndicator > const& xStatusIndicator)
+ css::uno::Reference< css::task::XStatusIndicator > const& xStatusIndicator,
+ bool bIsNewDoc)
{
- return std::make_shared<RTFDocumentImpl>(xContext, xInputStream, xDstDoc, xFrame, xStatusIndicator);
+ return std::make_shared<RTFDocumentImpl>(xContext, xInputStream, xDstDoc, xFrame, xStatusIndicator, bIsNewDoc);
}
} // namespace rtftok
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 72fc1fc..625818c 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -211,7 +211,8 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x
uno::Reference<io::XInputStream> const& xInputStream,
uno::Reference<lang::XComponent> const& xDstDoc,
uno::Reference<frame::XFrame> const& xFrame,
- uno::Reference<task::XStatusIndicator> const& xStatusIndicator)
+ uno::Reference<task::XStatusIndicator> const& xStatusIndicator,
+ bool bIsNewDoc)
: m_xContext(xContext),
m_xInputStream(xInputStream),
m_xDstDoc(xDstDoc),
@@ -271,7 +272,8 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x
m_bHadPicture(false),
m_bHadSect(false),
m_nCellxMax(0),
- m_nListPictureId(0)
+ m_nListPictureId(0),
+ m_bIsNewDoc(bIsNewDoc)
{
OSL_ASSERT(xInputStream.is());
m_pInStream.reset(utl::UcbStreamHelper::CreateStream(xInputStream, true));
@@ -342,7 +344,7 @@ void RTFDocumentImpl::resolveSubstream(sal_Size nPos, Id nId, OUString& rIgnoreF
{
sal_Size nCurrent = Strm().Tell();
// Seek to header position, parse, then seek back.
- auto pImpl = std::make_shared<RTFDocumentImpl>(m_xContext, m_xInputStream, m_xDstDoc, m_xFrame, m_xStatusIndicator);
+ auto pImpl = std::make_shared<RTFDocumentImpl>(m_xContext, m_xInputStream, m_xDstDoc, m_xFrame, m_xStatusIndicator, m_bIsNewDoc);
pImpl->setSuperstream(this);
pImpl->setStreamType(nId);
pImpl->setIgnoreFirst(rIgnoreFirst);
@@ -570,7 +572,8 @@ void RTFDocumentImpl::sectBreak(bool bFinal = false)
bool bContinuous = pBreak.get() && pBreak->getInt() == static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_SectionMark_continuous);
// If there is no paragraph in this section, then insert a dummy one, as required by Writer,
// unless this is the end of the doc, we had nothing since the last section break and this is not a continuous one.
- if (m_bNeedPar && !(bFinal && !m_bNeedSect && !bContinuous) && !isSubstream())
+ // Also, when pasting, it's fine to not have any paragraph inside the document at all.
+ if (m_bNeedPar && !(bFinal && !m_bNeedSect && !bContinuous) && !isSubstream() && m_bIsNewDoc)
dispatchSymbol(RTF_PAR);
// It's allowed to not have a non-table paragraph at the end of an RTF doc, add it now if required.
if (m_bNeedFinalPar && bFinal)
@@ -5765,7 +5768,7 @@ RTFError RTFDocumentImpl::popState()
{
// \par means an empty paragraph at the end of footnotes/endnotes, but
// not in case of other substreams, like headers.
- if (m_bNeedCr && !(m_nStreamType == NS_ooxml::LN_footnote || m_nStreamType == NS_ooxml::LN_endnote))
+ if (m_bNeedCr && !(m_nStreamType == NS_ooxml::LN_footnote || m_nStreamType == NS_ooxml::LN_endnote) && m_bIsNewDoc)
dispatchSymbol(RTF_PAR);
if (m_bNeedSect) // may be set by dispatchSymbol above!
sectBreak(true);
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index 45d3f6f..ae320ad 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -331,7 +331,8 @@ public:
css::uno::Reference<css::io::XInputStream> const& xInputStream,
css::uno::Reference<css::lang::XComponent> const& xDstDoc,
css::uno::Reference<css::frame::XFrame> const& xFrame,
- css::uno::Reference<css::task::XStatusIndicator> const& xStatusIndicator);
+ css::uno::Reference<css::task::XStatusIndicator> const& xStatusIndicator,
+ bool bIsNewDoc);
virtual ~RTFDocumentImpl();
// RTFDocument
@@ -590,6 +591,9 @@ private:
int m_nCellxMax;
/// ID of the next \listlevel picture.
int m_nListPictureId;
+
+ /// New document means not pasting into an existing one.
+ bool m_bIsNewDoc;
};
} // namespace rtftok
} // namespace writerfilter
More information about the Libreoffice-commits
mailing list