diff options
-rw-r--r-- | editeng/inc/editeng/unotext.hxx | 4 | ||||
-rw-r--r-- | editeng/source/uno/unotext.cxx | 38 | ||||
-rw-r--r-- | offapi/com/sun/star/text/XParagraphAppend.idl | 21 | ||||
-rw-r--r-- | offapi/com/sun/star/text/XTextContentAppend.idl | 21 | ||||
-rw-r--r-- | offapi/com/sun/star/text/XTextPortionAppend.idl | 25 | ||||
-rw-r--r-- | sw/inc/unotext.hxx | 33 | ||||
-rw-r--r-- | sw/inc/unotextrange.hxx | 4 | ||||
-rw-r--r-- | sw/source/core/unocore/unotext.cxx | 95 | ||||
-rw-r--r-- | sw/source/filter/rtf/swparrtf.cxx | 64 | ||||
-rw-r--r-- | writerfilter/inc/dmapper/DomainMapper.hxx | 1 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper.cxx | 3 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.cxx | 67 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.hxx | 16 | ||||
-rw-r--r-- | writerfilter/source/filter/ImportFilter.cxx | 2 | ||||
-rw-r--r-- | writerfilter/source/filter/RtfFilter.cxx | 4 |
15 files changed, 302 insertions, 96 deletions
diff --git a/editeng/inc/editeng/unotext.hxx b/editeng/inc/editeng/unotext.hxx index 397e64bbf090..13ab909256ee 100644 --- a/editeng/inc/editeng/unotext.hxx +++ b/editeng/inc/editeng/unotext.hxx @@ -440,12 +440,14 @@ public: virtual void SAL_CALL moveTextRange( const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange >& xRange, sal_Int16 nParagraphs ) throw(::com::sun::star::uno::RuntimeException); // com::sun::star::text::XParagraphAppend (new import API) - virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > SAL_CALL appendParagraph( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& CharacterAndParagraphProperties ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > SAL_CALL finishParagraph( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& CharacterAndParagraphProperties ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > SAL_CALL finishParagraphInsert( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& CharacterAndParagraphProperties, const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange >& xInsertPosition ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); // com::sun::star::text::XTextPortionAppend (new import API) virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > SAL_CALL appendTextPortion( const ::rtl::OUString& Text, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& CharacterAndParagraphProperties ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > SAL_CALL insertTextPortion( const ::rtl::OUString& Text, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& CharacterAndParagraphProperties, const com::sun::star::uno::Reference< com::sun::star::text::XTextRange>& rTextRange ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + // com::sun::star::text::XTextCopy virtual void SAL_CALL copyText( const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextCopy >& xSource ) throw (::com::sun::star::uno::RuntimeException); diff --git a/editeng/source/uno/unotext.cxx b/editeng/source/uno/unotext.cxx index 3b5033b6de3e..659f0f163978 100644 --- a/editeng/source/uno/unotext.cxx +++ b/editeng/source/uno/unotext.cxx @@ -2142,34 +2142,12 @@ void SvxPropertyValuesToItemSet( } } -// com::sun::star::text::XParagraphAppend (new import API) -uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextBase::appendParagraph( - const uno::Sequence< beans::PropertyValue >& rCharAndParaProps ) +uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextBase::finishParagraphInsert( + const uno::Sequence< beans::PropertyValue >& /*rCharAndParaProps*/, + const uno::Reference< text::XTextRange >& /*rTextRange*/ ) throw (lang::IllegalArgumentException, beans::UnknownPropertyException, uno::RuntimeException) { - SolarMutexGuard aGuard; uno::Reference< text::XTextRange > xRet; - SvxEditSource *pEditSource = GetEditSource(); - SvxTextForwarder *pTextForwarder = pEditSource ? pEditSource->GetTextForwarder() : 0; - if (pTextForwarder) - { - sal_uInt16 nParaCount = pTextForwarder->GetParagraphCount(); - DBG_ASSERT( nParaCount > 0, "paragraph count is 0 or negative" ); - pTextForwarder->AppendParagraph(); - - // set properties for new appended (now last) paragraph - ESelection aSel( nParaCount, 0, nParaCount, 0 ); - SfxItemSet aItemSet( *pTextForwarder->GetEmptyItemSetPtr() ); - SvxPropertyValuesToItemSet( aItemSet, rCharAndParaProps, - ImplGetSvxUnoOutlinerTextCursorSfxPropertySet(), - pTextForwarder, - nParaCount ); - pTextForwarder->QuickSetAttribs( aItemSet, aSel ); - pEditSource->UpdateData(); - SvxUnoTextRange* pRange = new SvxUnoTextRange( *this ); - xRet = pRange; - pRange->SetSelection( aSel ); - } return xRet; } @@ -2203,6 +2181,16 @@ uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextBase::finishParagraph( return xRet; } +uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextBase::insertTextPortion( + const ::rtl::OUString& /*rText*/, + const uno::Sequence< beans::PropertyValue >& /*rCharAndParaProps*/, + const uno::Reference< text::XTextRange>& /*rTextRange*/ ) + throw (lang::IllegalArgumentException, beans::UnknownPropertyException, uno::RuntimeException) +{ + uno::Reference< text::XTextRange > xRet; + return xRet; +} + // com::sun::star::text::XTextPortionAppend (new import API) uno::Reference< text::XTextRange > SAL_CALL SvxUnoTextBase::appendTextPortion( const ::rtl::OUString& rText, diff --git a/offapi/com/sun/star/text/XParagraphAppend.idl b/offapi/com/sun/star/text/XParagraphAppend.idl index 9c2ce13ec87b..343ca9eede29 100644 --- a/offapi/com/sun/star/text/XParagraphAppend.idl +++ b/offapi/com/sun/star/text/XParagraphAppend.idl @@ -35,20 +35,21 @@ */ interface XParagraphAppend : com::sun::star::uno::XInterface { - /** appends a new and empty paragraph at the end of the text. + /** appends a new and empty paragraph at the end of the text. - <p>The properties are applied to the new paragraph. - </p> + <p>The properties are applied to the last paragraph before the new paragraph is inserted. + </p> @param CharacterAndParagraphProperties can contain all the properties defined by the service <type scope="com::sun::star::text">Paragraph. - */ - com::sun::star::text::XTextRange appendParagraph( [in] com::sun::star::beans::PropertyValues CharacterAndParagraphProperties ) + */ + com::sun::star::text::XTextRange finishParagraph( [in] com::sun::star::beans::PropertyValues CharacterAndParagraphProperties ) raises( com::sun::star::lang::IllegalArgumentException, com::sun::star::beans::UnknownPropertyException ); - /** appends a new and empty paragraph at the end of the text. + + /** inserts a new and empty paragraph to the text at a given position. <p>The properties are applied to the last paragraph before the new paragraph is inserted. </p> @@ -57,8 +58,14 @@ interface XParagraphAppend : com::sun::star::uno::XInterface CharacterAndParagraphProperties can contain all the properties defined by the service <type scope="com::sun::star::text">Paragraph. + @param + TextRange specifies the position of the insertion. + + @since LibreOffice 4.0 + */ - com::sun::star::text::XTextRange finishParagraph( [in] com::sun::star::beans::PropertyValues CharacterAndParagraphProperties ) + com::sun::star::text::XTextRange finishParagraphInsert( [in] com::sun::star::beans::PropertyValues CharacterAndParagraphProperties, + [in] com::sun::star::text::XTextRange TextRange ) raises( com::sun::star::lang::IllegalArgumentException, com::sun::star::beans::UnknownPropertyException ); diff --git a/offapi/com/sun/star/text/XTextContentAppend.idl b/offapi/com/sun/star/text/XTextContentAppend.idl index 0e9c46d33073..afac7ab3b76d 100644 --- a/offapi/com/sun/star/text/XTextContentAppend.idl +++ b/offapi/com/sun/star/text/XTextContentAppend.idl @@ -55,6 +55,27 @@ interface XTextContentAppend : com::sun::star::uno::XInterface raises( com::sun::star::lang::IllegalArgumentException, com::sun::star::beans::UnknownPropertyException ); + /** inserts a text content at the given position. + + @param TextContent + contains the object to be inserted. + @param CharacterAndParagraphProperties + can contain all the properties defined by the service + <type scope="com::sun::star::text">Paragraph. + @param TextRange + insert position + @return + the anchor text range of the inserted text content. + + @since LibreOffice 4.0 + */ + com::sun::star::text::XTextRange insertTextContentWithProperties( + [in] com::sun::star::text::XTextContent TextContent, + [in] com::sun::star::beans::PropertyValues CharacterAndParagraphProperties, + [in] com::sun::star::text::XTextRange TextRange ) + raises( com::sun::star::lang::IllegalArgumentException, + com::sun::star::beans::UnknownPropertyException ); + }; diff --git a/offapi/com/sun/star/text/XTextPortionAppend.idl b/offapi/com/sun/star/text/XTextPortionAppend.idl index a1aaf5872e40..3c6c478efa93 100644 --- a/offapi/com/sun/star/text/XTextPortionAppend.idl +++ b/offapi/com/sun/star/text/XTextPortionAppend.idl @@ -53,6 +53,31 @@ interface XTextPortionAppend : com::sun::star::uno::XInterface raises( com::sun::star::lang::IllegalArgumentException, com::sun::star::beans::UnknownPropertyException ); + /** inserts a new text portion to the paragraph at a given position. + + <p> The sequence can contain all the properties defined by the service <type scope="com::sun::star::text">TextPortion. + </p> + + @param + Text contains the text to be inserted. + + @param + CharacterAndParagraphProperties can contain all the properties defined by the service + <type scope="com::sun::star::text">Paragraph. + + @param + TextRange specifies the position of the insert. + + @since LibreOffice 4.0 + + */ + com::sun::star::text::XTextRange insertTextPortion( + [in] string Text, + [in] com::sun::star::beans::PropertyValues CharacterAndParagraphProperties, + [in] com::sun::star::text::XTextRange TextRange) + raises( com::sun::star::lang::IllegalArgumentException, + com::sun::star::beans::UnknownPropertyException ); + }; diff --git a/sw/inc/unotext.hxx b/sw/inc/unotext.hxx index 0d5d47bcd552..7c01aed506fa 100644 --- a/sw/inc/unotext.hxx +++ b/sw/inc/unotext.hxx @@ -206,7 +206,7 @@ public: // XParagraphAppend virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > SAL_CALL - appendParagraph( + finishParagraph( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rCharacterAndParagraphProperties) @@ -214,10 +214,13 @@ public: ::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > SAL_CALL - finishParagraph( + finishParagraphInsert( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& - rCharacterAndParagraphProperties) + rCharacterAndParagraphProperties, + const ::com::sun::star::uno::Reference< + ::com::sun::star::text::XTextRange >& + xInsertPosition) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); @@ -232,6 +235,19 @@ public: throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::text::XTextRange > SAL_CALL + insertTextPortion( + const ::rtl::OUString& rText, + const ::com::sun::star::uno::Sequence< + ::com::sun::star::beans::PropertyValue >& + rCharacterAndParagraphProperties, + const ::com::sun::star::uno::Reference< + ::com::sun::star::text::XTextRange >& + rTextRange) + throw (::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::uno::RuntimeException); + // XTextContentAppend virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > SAL_CALL @@ -243,6 +259,17 @@ public: rCharacterAndParagraphProperties) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::text::XTextRange > SAL_CALL + insertTextContentWithProperties( + const ::com::sun::star::uno::Reference< + ::com::sun::star::text::XTextContent >& xTextContent, + const ::com::sun::star::uno::Sequence< + ::com::sun::star::beans::PropertyValue >& + rCharacterAndParagraphProperties, + const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange >& xInsertPosition) + throw (::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::uno::RuntimeException); // XTextConvert virtual ::com::sun::star::uno::Reference< diff --git a/sw/inc/unotextrange.hxx b/sw/inc/unotextrange.hxx index 46576ef47bf2..cfd373766c38 100644 --- a/sw/inc/unotextrange.hxx +++ b/sw/inc/unotextrange.hxx @@ -43,7 +43,7 @@ class SwPaM; class SwUnoCrsr; class SwFrmFmt; -class SwUnoInternalPaM +class SW_DLLPUBLIC SwUnoInternalPaM : public SwPaM { @@ -62,7 +62,7 @@ namespace sw { void DeepCopyPaM(SwPaM const & rSource, SwPaM & rTarget); - bool XTextRangeToSwPaM(SwUnoInternalPaM& rToFill, + SW_DLLPUBLIC bool XTextRangeToSwPaM(SwUnoInternalPaM& rToFill, const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & xTextRange); diff --git a/sw/source/core/unocore/unotext.cxx b/sw/source/core/unocore/unotext.cxx index 68e67c2bd81a..a5757192fe40 100644 --- a/sw/source/core/unocore/unotext.cxx +++ b/sw/source/core/unocore/unotext.cxx @@ -108,7 +108,8 @@ public: finishOrAppendParagraph( const bool bFinish, const uno::Sequence< beans::PropertyValue >& - rCharacterAndParagraphProperties) + rCharacterAndParagraphProperties, + const uno::Reference< text::XTextRange >& xInsertPosition) throw (lang::IllegalArgumentException, uno::RuntimeException); sal_Int16 ComparePositions( @@ -1251,29 +1252,31 @@ throw (uno::RuntimeException) } uno::Reference< text::XTextRange > SAL_CALL -SwXText::appendParagraph( +SwXText::finishParagraph( const uno::Sequence< beans::PropertyValue > & rProperties) throw (lang::IllegalArgumentException, uno::RuntimeException) { SolarMutexGuard g; - return m_pImpl->finishOrAppendParagraph(false, rProperties); + return m_pImpl->finishOrAppendParagraph(true, rProperties, uno::Reference< text::XTextRange >()); } uno::Reference< text::XTextRange > SAL_CALL -SwXText::finishParagraph( - const uno::Sequence< beans::PropertyValue > & rProperties) +SwXText::finishParagraphInsert( + const uno::Sequence< beans::PropertyValue > & rProperties, + const uno::Reference< text::XTextRange >& xInsertPosition) throw (lang::IllegalArgumentException, uno::RuntimeException) { SolarMutexGuard g; - return m_pImpl->finishOrAppendParagraph(true, rProperties); + return m_pImpl->finishOrAppendParagraph(true, rProperties, xInsertPosition); } uno::Reference< text::XTextRange > SwXText::Impl::finishOrAppendParagraph( const bool bFinish, - const uno::Sequence< beans::PropertyValue > & rProperties) + const uno::Sequence< beans::PropertyValue > & rProperties, + const uno::Reference< text::XTextRange >& xInsertPosition) throw (lang::IllegalArgumentException, uno::RuntimeException) { if (!m_bIsValid) @@ -1298,6 +1301,15 @@ throw (lang::IllegalArgumentException, uno::RuntimeException) SwPosition aInsertPosition( SwNodeIndex( *pStartNode->EndOfSectionNode(), -1 ) ); SwPaM aPam(aInsertPosition); + // If we got a position reference, then the insert point is not the end of + // the document. + if (xInsertPosition.is()) + { + SwUnoInternalPaM aStartPam(*m_rThis.GetDoc()); + ::sw::XTextRangeToSwPaM(aStartPam, xInsertPosition); + aPam = aStartPam; + aPam.SetMark(); + } m_pDoc->AppendTxtNode( *aPam.GetPoint() ); // remove attributes from the previous paragraph m_pDoc->ResetAttrs(aPam); @@ -1371,15 +1383,12 @@ throw (lang::IllegalArgumentException, uno::RuntimeException) return xRet; } -/*------------------------------------------------------------------------- - Append text portions at the end of the last paragraph of the text - interface. Support of import filters. - -----------------------------------------------------------------------*/ uno::Reference< text::XTextRange > SAL_CALL -SwXText::appendTextPortion( +SwXText::insertTextPortion( const ::rtl::OUString& rText, const uno::Sequence< beans::PropertyValue > & - rCharacterAndParagraphProperties) + rCharacterAndParagraphProperties, + const uno::Reference<text::XTextRange>& xInsertPosition) throw (lang::IllegalArgumentException, uno::RuntimeException) { SolarMutexGuard aGuard; @@ -1390,7 +1399,7 @@ throw (lang::IllegalArgumentException, uno::RuntimeException) } uno::Reference< text::XTextRange > xRet; const uno::Reference< text::XTextCursor > xTextCursor = CreateCursor(); - xTextCursor->gotoEnd(sal_False); + xTextCursor->gotoRange(xInsertPosition, sal_False); const uno::Reference< lang::XUnoTunnel > xRangeTunnel( xTextCursor, uno::UNO_QUERY_THROW ); @@ -1405,7 +1414,6 @@ throw (lang::IllegalArgumentException, uno::RuntimeException) // SwPaM aPam(*pStartNode->EndOfSectionNode()); //aPam.Move( fnMoveBackward, fnGoNode ); SwUnoCrsr *const pCursor = pTextCursor->GetCursor(); - pCursor->MovePara( fnParaCurr, fnParaEnd ); m_pImpl->m_pDoc->DontExpandFmt( *pCursor->Start() ); if (!rText.isEmpty()) @@ -1477,14 +1485,32 @@ throw (lang::IllegalArgumentException, uno::RuntimeException) } /*------------------------------------------------------------------------- - enable appending text contents like graphic objects, shapes and so on + Append text portions at the end of the last paragraph of the text + interface. Support of import filters. + -----------------------------------------------------------------------*/ +uno::Reference< text::XTextRange > SAL_CALL +SwXText::appendTextPortion( + const ::rtl::OUString& rText, + const uno::Sequence< beans::PropertyValue > & + rCharacterAndParagraphProperties) +throw (lang::IllegalArgumentException, uno::RuntimeException) +{ + // Right now this doesn't need a guard, as it's just calling the insert + // version, that has it already. + uno::Reference<text::XTextRange> xInsertPosition = getEnd(); + return insertTextPortion(rText, rCharacterAndParagraphProperties, xInsertPosition); +} + +/*------------------------------------------------------------------------- + enable inserting/appending text contents like graphic objects, shapes and so on to support import filters -----------------------------------------------------------------------*/ uno::Reference< text::XTextRange > SAL_CALL -SwXText::appendTextContent( +SwXText::insertTextContentWithProperties( const uno::Reference< text::XTextContent >& xTextContent, const uno::Sequence< beans::PropertyValue >& - rCharacterAndParagraphProperties) + rCharacterAndParagraphProperties, + const uno::Reference< text::XTextRange >& xInsertPosition) throw (lang::IllegalArgumentException, uno::RuntimeException) { SolarMutexGuard aGuard; @@ -1493,25 +1519,11 @@ throw (lang::IllegalArgumentException, uno::RuntimeException) { throw uno::RuntimeException(); } - SwStartNode const*const pStartNode = GetStartNode(); - if(!pStartNode) - { - throw uno::RuntimeException(); - } - uno::Reference< text::XTextRange > xRet; m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL); - // find end node, go backward - don't skip tables because the - // new paragraph has to be the last node - SwPaM aPam(*pStartNode->EndOfSectionNode()); - aPam.Move( fnMoveBackward, fnGoNode ); - // set cursor to the end of the last text node - SwCursor aCursor( *aPam.Start(), 0, false ); - xRet = new SwXTextRange(aCursor, this); - aCursor.MovePara( fnParaCurr, fnParaEnd ); - m_pImpl->m_pDoc->DontExpandFmt( *aCursor.Start() ); + // now attach the text content here - insertTextContent( xRet, xTextContent, false ); + insertTextContent( xInsertPosition, xTextContent, false ); // now apply the properties to the anchor if (rCharacterAndParagraphProperties.getLength()) { @@ -1536,7 +1548,20 @@ throw (lang::IllegalArgumentException, uno::RuntimeException) } } m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL); - return xRet; + return xInsertPosition; +} + +uno::Reference< text::XTextRange > SAL_CALL +SwXText::appendTextContent( + const uno::Reference< text::XTextContent >& xTextContent, + const uno::Sequence< beans::PropertyValue >& + rCharacterAndParagraphProperties) +throw (lang::IllegalArgumentException, uno::RuntimeException) +{ + // Right now this doesn't need a guard, as it's just calling the insert + // version, that has it already. + uno::Reference<text::XTextRange> xInsertPosition = getEnd(); + return insertTextContentWithProperties(xTextContent, rCharacterAndParagraphProperties, xInsertPosition); } // move previously appended paragraphs into a text frames 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; } diff --git a/writerfilter/inc/dmapper/DomainMapper.hxx b/writerfilter/inc/dmapper/DomainMapper.hxx index 87e28d27a234..26654d728c0f 100644 --- a/writerfilter/inc/dmapper/DomainMapper.hxx +++ b/writerfilter/inc/dmapper/DomainMapper.hxx @@ -82,6 +82,7 @@ public: ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xModel, bool bRepairStorage, SourceDocumentType eDocumentType, + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > xInsertTextRange, bool bIsNewDoc = true); virtual ~DomainMapper(); diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index a768dc364267..5ae8e1389589 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -87,11 +87,12 @@ DomainMapper::DomainMapper( const uno::Reference< uno::XComponentContext >& xCon uno::Reference< lang::XComponent > xModel, bool bRepairStorage, SourceDocumentType eDocumentType, + uno::Reference< text::XTextRange > xInsertTextRange, bool bIsNewDoc ) : LoggedProperties(dmapper_logger, "DomainMapper"), LoggedTable(dmapper_logger, "DomainMapper"), LoggedStream(dmapper_logger, "DomainMapper"), - m_pImpl( new DomainMapper_Impl( *this, xContext, xModel, eDocumentType, bIsNewDoc )), + m_pImpl( new DomainMapper_Impl( *this, xContext, xModel, eDocumentType, xInsertTextRange, bIsNewDoc )), mnBackgroundColor(0), mbIsHighlightSet(false) { // #i24363# tab stops relative to indent diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index fbf9acb46caf..a204c690fa4c 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -156,6 +156,7 @@ DomainMapper_Impl::DomainMapper_Impl( uno::Reference < uno::XComponentContext > xContext, uno::Reference< lang::XComponent > xModel, SourceDocumentType eDocumentType, + uno::Reference< text::XTextRange > xInsertTextRange, bool bIsNewDoc) : m_eDocumentType( eDocumentType ), m_rDMapper( rDMapper ), @@ -184,12 +185,14 @@ DomainMapper_Impl::DomainMapper_Impl( m_bParaSectpr( false ), m_bUsingEnhancedFields( false ), m_bSdt(false), + m_xInsertTextRange(xInsertTextRange), m_bIsNewDoc(bIsNewDoc) { appendTableManager( ); GetBodyText(); uno::Reference< text::XTextAppend > xBodyTextAppend = uno::Reference< text::XTextAppend >( m_xBodyText, uno::UNO_QUERY ); - m_aTextAppendStack.push(xBodyTextAppend); + m_aTextAppendStack.push(TextAppendContext(xBodyTextAppend, + m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(m_xInsertTextRange))); //todo: does it make sense to set the body text as static text interface? uno::Reference< text::XTextAppendAndConvert > xBodyTextAppendAndConvert( m_xBodyText, uno::UNO_QUERY ); @@ -268,8 +271,14 @@ void DomainMapper_Impl::RemoveLastParagraph( ) return; try { - uno::Reference< text::XTextCursor > xCursor = xTextAppend->createTextCursor(); - xCursor->gotoEnd(false); + uno::Reference< text::XTextCursor > xCursor; + if (m_bIsNewDoc) + { + xCursor = xTextAppend->createTextCursor(); + xCursor->gotoEnd(false); + } + else + xCursor.set(m_aTextAppendStack.top().xCursor, uno::UNO_QUERY); xCursor->goLeft( 1, true ); xCursor->setString(OUString()); } @@ -1043,13 +1052,22 @@ void DomainMapper_Impl::finishParagraph( PropertyMapPtr pPropertyMap ) aProperties[nLength].Value <<= aDrop; aProperties[nLength].Name = rPropNameSupplier.GetName(PROP_DROP_CAP_FORMAT); } - uno::Reference< text::XTextRange > xTextRange = - xTextAppend->finishParagraph( aProperties ); + uno::Reference< text::XTextRange > xTextRange; + if (rAppendContext.xInsertPosition.is()) + { + xTextRange = xTextAppend->finishParagraphInsert( aProperties, rAppendContext.xInsertPosition ); + rAppendContext.xCursor->gotoNextParagraph(false); + } + else + xTextRange = xTextAppend->finishParagraph( aProperties ); getTableManager( ).handle(xTextRange); // Get the end of paragraph character inserted uno::Reference< text::XTextCursor > xCur = xTextRange->getText( )->createTextCursor( ); - xCur->gotoEnd( false ); + if (rAppendContext.xInsertPosition.is()) + xCur->gotoRange( rAppendContext.xInsertPosition, false ); + else + xCur->gotoEnd( false ); xCur->goLeft( 1 , true ); uno::Reference< text::XTextRange > xParaEnd( xCur, uno::UNO_QUERY ); CheckParaRedline( xParaEnd ); @@ -1112,9 +1130,14 @@ void DomainMapper_Impl::appendTextPortion( const OUString& rString, PropertyMapP { try { - uno::Reference< text::XTextRange > xTextRange = - xTextAppend->appendTextPortion - (rString, pPropertyMap->GetPropertyValues()); + uno::Reference< text::XTextRange > xTextRange; + if (m_aTextAppendStack.top().xInsertPosition.is()) + { + xTextRange = xTextAppend->insertTextPortion(rString, pPropertyMap->GetPropertyValues(), m_aTextAppendStack.top().xInsertPosition); + m_aTextAppendStack.top().xCursor->gotoRange(xTextRange->getEnd(), false); + } + else + xTextRange = xTextAppend->appendTextPortion(rString, pPropertyMap->GetPropertyValues()); CheckRedline( xTextRange ); m_bParaChanged = true; @@ -1143,7 +1166,10 @@ void DomainMapper_Impl::appendTextContent( { try { - xTextAppendAndConvert->appendTextContent( xContent, xPropertyValues ); + if (m_aTextAppendStack.top().xInsertPosition.is()) + xTextAppendAndConvert->insertTextContentWithProperties( xContent, xPropertyValues, m_aTextAppendStack.top().xInsertPosition ); + else + xTextAppendAndConvert->appendTextContent( xContent, xPropertyValues ); } catch(const lang::IllegalArgumentException&) { @@ -1249,7 +1275,10 @@ uno::Reference< beans::XPropertySet > DomainMapper_Impl::appendTextSectionAfter( xTextAppend->createTextCursorByRange( xBefore ), uno::UNO_QUERY_THROW); //the cursor has been moved to the end of the paragraph because of the appendTextPortion() calls xCursor->gotoStartOfParagraph( false ); - xCursor->gotoEnd( true ); + if (m_aTextAppendStack.top().xInsertPosition.is()) + xCursor->gotoRange( m_aTextAppendStack.top().xInsertPosition, true ); + else + xCursor->gotoEnd( true ); //the paragraph after this new section is already inserted xCursor->goLeft(1, true); static const OUString sSectionService("com.sun.star.text.TextSection"); @@ -1299,7 +1328,8 @@ void DomainMapper_Impl::PushPageHeader(SectionPropertyMap::PageType eType) //set the interface uno::Reference< text::XText > xHeaderText; xPageStyle->getPropertyValue(rPropNameSupplier.GetName( bLeft ? PROP_HEADER_TEXT_LEFT : PROP_HEADER_TEXT) ) >>= xHeaderText; - m_aTextAppendStack.push( uno::Reference< text::XTextAppend >( xHeaderText, uno::UNO_QUERY_THROW)); + m_aTextAppendStack.push( TextAppendContext(uno::Reference< text::XTextAppend >( xHeaderText, uno::UNO_QUERY_THROW), + m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(xHeaderText->getStart()))); } catch( const uno::Exception& ) { @@ -1339,7 +1369,8 @@ void DomainMapper_Impl::PushPageFooter(SectionPropertyMap::PageType eType) //set the interface uno::Reference< text::XText > xFooterText; xPageStyle->getPropertyValue(rPropNameSupplier.GetName( bLeft ? PROP_FOOTER_TEXT_LEFT : PROP_FOOTER_TEXT) ) >>= xFooterText; - m_aTextAppendStack.push(uno::Reference< text::XTextAppend >( xFooterText, uno::UNO_QUERY_THROW )); + m_aTextAppendStack.push(TextAppendContext(uno::Reference< text::XTextAppend >( xFooterText, uno::UNO_QUERY_THROW ), + m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(xFooterText->getStart()))); } catch( const uno::Exception& ) { @@ -1394,7 +1425,8 @@ void DomainMapper_Impl::PushFootOrEndnote( bool bIsFootnote ) aFontProperties = aFontProps->GetPropertyValues(); } appendTextContent( uno::Reference< text::XTextContent >( xFootnoteText, uno::UNO_QUERY_THROW ), aFontProperties ); - m_aTextAppendStack.push(uno::Reference< text::XTextAppend >( xFootnoteText, uno::UNO_QUERY_THROW )); + m_aTextAppendStack.push(TextAppendContext(uno::Reference< text::XTextAppend >( xFootnoteText, uno::UNO_QUERY_THROW ), + m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(xFootnoteText->getStart()))); // Redlines for the footnote anchor CheckRedline( xFootnote->getAnchor( ) ); @@ -1493,7 +1525,8 @@ void DomainMapper_Impl::PushAnnotation() uno::UNO_QUERY_THROW ); uno::Reference< text::XText > xAnnotationText; m_xAnnotationField->getPropertyValue("TextRange") >>= xAnnotationText; - m_aTextAppendStack.push(uno::Reference< text::XTextAppend >( xAnnotationText, uno::UNO_QUERY_THROW )); + m_aTextAppendStack.push(TextAppendContext(uno::Reference< text::XTextAppend >( xAnnotationText, uno::UNO_QUERY_THROW ), + m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(xAnnotationText->getStart()))); } catch( const uno::Exception& ) { @@ -1548,8 +1581,10 @@ void DomainMapper_Impl::PushShapeContext( const uno::Reference< drawing::XShape uno::Reference<text::XTextAppend> xTextAppend = m_aTextAppendStack.top().xTextAppend; try { + uno::Reference< text::XTextRange > xShapeText( xShape, uno::UNO_QUERY_THROW); // Add the shape to the text append stack - m_aTextAppendStack.push( uno::Reference< text::XTextAppend >( xShape, uno::UNO_QUERY_THROW ) ); + m_aTextAppendStack.push( TextAppendContext(uno::Reference< text::XTextAppend >( xShape, uno::UNO_QUERY_THROW ), + m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(xShapeText->getStart() ))); // Add the shape to the anchored objects stack uno::Reference< text::XTextContent > xTxtContent( xShape, uno::UNO_QUERY_THROW ); diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index 87145420d0dd..585745532b20 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -19,6 +19,7 @@ #ifndef INCLUDED_DMAPPER_DOMAINMAPPER_IMPL_HXX #define INCLUDED_DMAPPER_DOMAINMAPPER_IMPL_HXX +#include <com/sun/star/text/XParagraphCursor.hpp> #include <com/sun/star/text/XTextDocument.hpp> #include <com/sun/star/text/XTextCursor.hpp> #include <com/sun/star/text/XTextAppend.hpp> @@ -167,10 +168,17 @@ public: struct TextAppendContext { ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextAppend > xTextAppend; + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > xInsertPosition; + ::com::sun::star::uno::Reference< ::com::sun::star::text::XParagraphCursor > xCursor; ParagraphPropertiesPtr pLastParagraphProperties; - TextAppendContext( const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextAppend >& xAppend ) : - xTextAppend( xAppend ){} + TextAppendContext( const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextAppend >& xAppend, + const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextCursor >& xCur ) : + xTextAppend( xAppend ) + { + xCursor.set(xCur, uno::UNO_QUERY); + xInsertPosition.set(xCursor, uno::UNO_QUERY); + } }; struct AnchoredContext @@ -373,6 +381,9 @@ private: std::map< sal_Int32, com::sun::star::uno::Any > deferredCharacterProperties; +public: + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > m_xInsertTextRange; +private: bool m_bIsNewDoc; public: @@ -381,6 +392,7 @@ public: uno::Reference < uno::XComponentContext > xContext, uno::Reference< lang::XComponent > xModel, SourceDocumentType eDocumentType, + uno::Reference< text::XTextRange > xInsertTextRange, bool bIsNewDoc ); virtual ~DomainMapper_Impl(); diff --git a/writerfilter/source/filter/ImportFilter.cxx b/writerfilter/source/filter/ImportFilter.cxx index e482d5b7ffcc..d58e87725178 100644 --- a/writerfilter/source/filter/ImportFilter.cxx +++ b/writerfilter/source/filter/ImportFilter.cxx @@ -99,7 +99,7 @@ sal_Bool WriterFilter::filter( const uno::Sequence< beans::PropertyValue >& aDes m_sFilterName == "writer_OOXML" || m_sFilterName == "writer_OOXML_Text_Template" ) ? writerfilter::dmapper::DOCUMENT_OOXML : writerfilter::dmapper::DOCUMENT_DOC; - writerfilter::Stream::Pointer_t pStream(new writerfilter::dmapper::DomainMapper(m_xContext, xInputStream, m_xDstDoc, bRepairStorage, eType)); + writerfilter::Stream::Pointer_t pStream(new writerfilter::dmapper::DomainMapper(m_xContext, xInputStream, m_xDstDoc, bRepairStorage, eType, uno::Reference<text::XTextRange>())); //create the tokenizer and domain mapper if( eType == writerfilter::dmapper::DOCUMENT_OOXML ) { diff --git a/writerfilter/source/filter/RtfFilter.cxx b/writerfilter/source/filter/RtfFilter.cxx index 27373a44de79..ac84d2982e4d 100644 --- a/writerfilter/source/filter/RtfFilter.cxx +++ b/writerfilter/source/filter/RtfFilter.cxx @@ -29,6 +29,7 @@ #include <com/sun/star/task/XStatusIndicator.hpp> #include <com/sun/star/io/WrongFormatException.hpp> #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> +#include <com/sun/star/text/XTextRange.hpp> #ifdef DBG_COPYPASTE #include <unotools/localfilehelper.hxx> #include <tools/stream.hxx> @@ -75,6 +76,7 @@ sal_Bool RtfFilter::filter( const uno::Sequence< beans::PropertyValue >& aDescri MediaDescriptor aMediaDesc( aDescriptor ); bool bRepairStorage = aMediaDesc.getUnpackedValueOrDefault( "RepairPackage", false ); bool bIsNewDoc = aMediaDesc.getUnpackedValueOrDefault( "IsNewDoc", true ); + uno::Reference<text::XTextRange> xInsertTextRange = aMediaDesc.getUnpackedValueOrDefault( "TextInsertModeRange", uno::Reference<text::XTextRange>()); #ifdef DEBUG_IMPORT OUString sURL = aMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_URL(), OUString() ); ::std::string sURLc = OUStringToOString(sURL, RTL_TEXTENCODING_ASCII_US).getStr(); @@ -119,7 +121,7 @@ sal_Bool RtfFilter::filter( const uno::Sequence< beans::PropertyValue >& aDescri uno::Reference<task::XStatusIndicator>()); writerfilter::Stream::Pointer_t pStream( - new writerfilter::dmapper::DomainMapper(m_xContext, xInputStream, m_xDstDoc, bRepairStorage, writerfilter::dmapper::DOCUMENT_RTF, bIsNewDoc)); + new writerfilter::dmapper::DomainMapper(m_xContext, xInputStream, m_xDstDoc, bRepairStorage, writerfilter::dmapper::DOCUMENT_RTF, xInsertTextRange, bIsNewDoc)); writerfilter::rtftok::RTFDocument::Pointer_t const pDocument( writerfilter::rtftok::RTFDocumentFactory::createDocument(m_xContext, xInputStream, m_xDstDoc, xFrame, xStatusIndicator)); pDocument->resolve(*pStream); |