diff options
author | Miklos Vajna <vmiklos@suse.cz> | 2012-11-28 11:59:00 +0100 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2012-11-28 21:33:54 +0100 |
commit | 232ad2f2588beff50cb5c1f3b689c581ba317583 (patch) | |
tree | 40f7ebd9203de3e679b3578a552e28c7a2f09ee3 /writerfilter/source | |
parent | 85693bffad5c863e5cd4d4b3664856a9fec607d5 (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>
Diffstat (limited to 'writerfilter/source')
-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 |
5 files changed, 71 insertions, 21 deletions
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); |