diff options
Diffstat (limited to 'sw/source/filter/rtf/swparrtf.cxx')
-rw-r--r-- | sw/source/filter/rtf/swparrtf.cxx | 64 |
1 files changed, 62 insertions, 2 deletions
diff --git a/sw/source/filter/rtf/swparrtf.cxx b/sw/source/filter/rtf/swparrtf.cxx index d4d59c0b62b2..e06c02ba6208 100644 --- a/sw/source/filter/rtf/swparrtf.cxx +++ b/sw/source/filter/rtf/swparrtf.cxx @@ -89,6 +89,7 @@ #include <docsh.hxx> #include <fmtlsplt.hxx> // SwLayoutSplit +#include <unotextrange.hxx> #include <editeng/keepitem.hxx> #include <svx/svdopath.hxx> #include <svx/svdorect.hxx> @@ -117,6 +118,7 @@ #include <com/sun/star/document/XFilter.hpp> #include <com/sun/star/document/XImporter.hpp> #include <com/sun/star/document/XExporter.hpp> +#include <com/sun/star/text/XTextRange.hpp> using namespace ::com::sun::star; @@ -136,11 +138,31 @@ class SwRTFReader : public Reader virtual sal_uLong Read( SwDoc &, const String& rBaseURL, SwPaM &,const String &); }; -sal_uLong SwRTFReader::Read( SwDoc &rDoc, const String& /*rBaseURL*/, SwPaM& /*rPam*/, const String &) +sal_uLong SwRTFReader::Read( SwDoc &rDoc, const String& /*rBaseURL*/, SwPaM& rPam, const String &) { if (!pStrm) return ERR_SWG_READ_ERROR; + // We want to work in an empty paragraph. + // 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()); + const SwPosition* pPos = rPam.GetPoint(); + + // Step 2: Split once and remember the node that has been splitted. + rDoc.SplitNode( *pPos, false ); + *pSttNdIdx = pPos->nNode.GetIndex()-1; + + // Step 3: Split again. + rDoc.SplitNode( *pPos, false ); + + // Step 4: Insert all content into the new node + rPam.Move( fnMoveBackward ); + rDoc.SetTxtFmtColl + ( rPam, rDoc.GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false ) ); + SwDocShell *pDocShell(rDoc.GetDocShell()); uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(comphelper::getProcessServiceFactory()); uno::Reference<uno::XInterface> xInterface(xMultiServiceFactory->createInstance( @@ -150,15 +172,53 @@ sal_uLong SwRTFReader::Read( SwDoc &rDoc, const String& /*rBaseURL*/, SwPaM& /*r uno::Reference<lang::XComponent> xDstDoc(pDocShell->GetModel(), uno::UNO_QUERY_THROW); xImporter->setTargetDocument(xDstDoc); + const uno::Reference<text::XTextRange> xInsertTextRange = + SwXTextRange::CreateXTextRange(rDoc, *rPam.GetPoint(), 0); + uno::Reference<document::XFilter> xFilter(xInterface, uno::UNO_QUERY_THROW); - uno::Sequence<beans::PropertyValue> aDescriptor(2); + uno::Sequence<beans::PropertyValue> aDescriptor(3); aDescriptor[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("InputStream")); uno::Reference<io::XStream> xStream(new utl::OStreamWrapper(*pStrm)); aDescriptor[0].Value <<= xStream; aDescriptor[1].Name = "IsNewDoc"; aDescriptor[1].Value <<= sal_False; + aDescriptor[2].Name = "TextInsertModeRange"; + aDescriptor[2].Value <<= xInsertTextRange; xFilter->filter(aDescriptor); + // Clean up the fake paragraphs. + SwUnoInternalPaM aPam(rDoc); + ::sw::XTextRangeToSwPaM(aPam, xInsertPosition); + if (pSttNdIdx->GetIndex()) + { + // If we are in insert mode, join the splitted node that is in front + // of the new content with the first new node. Or in other words: + // Revert the first split node. + SwTxtNode* pTxtNode = pSttNdIdx->GetNode().GetTxtNode(); + SwNodeIndex aNxtIdx( *pSttNdIdx ); + if( pTxtNode && pTxtNode->CanJoinNext( &aNxtIdx ) && + pSttNdIdx->GetIndex() + 1 == aNxtIdx.GetIndex() ) + { + // If the PaM points to the first new node, move the PaM to the + // end of the previous node. + if( aPam.GetPoint()->nNode == aNxtIdx ) + { + aPam.GetPoint()->nNode = *pSttNdIdx; + aPam.GetPoint()->nContent.Assign( pTxtNode, + pTxtNode->GetTxt().Len() ); + } + // If the first new node isn't empty, convert the node's text + // attributes into hints. Otherwise, set the new node's + // paragraph style at the previous (empty) node. + SwTxtNode* pDelNd = aNxtIdx.GetNode().GetTxtNode(); + if( pTxtNode->GetTxt().Len() ) + pDelNd->FmtToTxtAttr( pTxtNode ); + else + pTxtNode->ChgFmtColl( pDelNd->GetTxtColl() ); + pTxtNode->JoinNext(); + } + } + return 0; } |