summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@suse.cz>2012-11-28 11:59:00 +0100
committerMichael Stahl <mstahl@redhat.com>2012-11-28 21:33:54 +0100
commit232ad2f2588beff50cb5c1f3b689c581ba317583 (patch)
tree40f7ebd9203de3e679b3578a552e28c7a2f09ee3
parent85693bffad5c863e5cd4d4b3664856a9fec607d5 (diff)
API CHANGE: add a "position" parameter to XParagraph/TextPortionAppend methods
So we can use the new RTF import for clipboard pastes in Writer without inserting text content to the end of the document only. Notes: - SwXText::insertTextPortion: the MovePara() call is removed, as all it did was trying to move the cursor beyond the end of the document. - SwRTFReader::Read: the double fake paragraph insertion / deletion is motivated by the ODT filter. - RtfFilter::filter: if TextInsertModeRange is not passed, then the behaviour is not changed. v2: - added missing @since tags - added insertTextContentWithProperties() method - removed unused appendParagraph() method Change-Id: I24cddb00a78e3b798e7d88764e59e6a77a6e98a4 Helped-by: Michael Stahl <mstahl@redhat.com>
-rw-r--r--editeng/inc/editeng/unotext.hxx4
-rw-r--r--editeng/source/uno/unotext.cxx38
-rw-r--r--offapi/com/sun/star/text/XParagraphAppend.idl15
-rw-r--r--offapi/com/sun/star/text/XTextContentAppend.idl21
-rw-r--r--offapi/com/sun/star/text/XTextPortionAppend.idl25
-rw-r--r--sw/inc/unotext.hxx33
-rw-r--r--sw/inc/unotextrange.hxx4
-rw-r--r--sw/source/core/unocore/unotext.cxx95
-rw-r--r--sw/source/filter/rtf/swparrtf.cxx64
-rw-r--r--writerfilter/inc/dmapper/DomainMapper.hxx1
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx3
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx59
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx16
-rw-r--r--writerfilter/source/filter/ImportFilter.cxx2
-rw-r--r--writerfilter/source/filter/RtfFilter.cxx4
15 files changed, 295 insertions, 89 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
@@ -37,7 +37,7 @@ interface XParagraphAppend : com::sun::star::uno::XInterface
{
/** appends a new and empty paragraph at the end of the text.
- <p>The properties are applied to the new paragraph.
+ <p>The properties are applied to the last paragraph before the new paragraph is inserted.
</p>
@param
@@ -45,10 +45,11 @@ interface XParagraphAppend : com::sun::star::uno::XInterface
<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();
+ 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,12 +1052,21 @@ 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( );
+ 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 );
@@ -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,6 +1166,9 @@ void DomainMapper_Impl::appendTextContent(
{
try
{
+ if (m_aTextAppendStack.top().xInsertPosition.is())
+ xTextAppendAndConvert->insertTextContentWithProperties( xContent, xPropertyValues, m_aTextAppendStack.top().xInsertPosition );
+ else
xTextAppendAndConvert->appendTextContent( xContent, xPropertyValues );
}
catch(const lang::IllegalArgumentException&)
@@ -1249,6 +1275,9 @@ 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 );
+ 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);
@@ -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);