diff options
author | Miklos Vajna <vmiklos@frugalware.org> | 2011-08-12 14:57:53 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@frugalware.org> | 2011-08-12 14:58:10 +0200 |
commit | dd525ec15c237296f1eace5f470db0785a48bfbf (patch) | |
tree | 07383940e7daf6365a104ebd0a64dbd8f5bbb4d9 | |
parent | 64fde7ccf1084a4fbe43397aa807b0b8760cf090 (diff) | |
parent | bcc2fbef8fc9eec7664fc7592fa27e7804a4fc88 (diff) |
Merge remote-tracking branch 'feature/gsoc2011_rtfimport'
19 files changed, 622 insertions, 215 deletions
diff --git a/writerfilter/Library_rtftok.mk b/writerfilter/Library_rtftok.mk index 136aad1a8beb..5866dc3f9d03 100644 --- a/writerfilter/Library_rtftok.mk +++ b/writerfilter/Library_rtftok.mk @@ -65,6 +65,7 @@ $(eval $(call gb_Library_add_exception_objects,rtftok,\ writerfilter/source/rtftok/rtfdocumentimpl \ writerfilter/source/rtftok/rtfsdrimport \ writerfilter/source/rtftok/rtftokenizer \ + writerfilter/source/rtftok/rtfskipdestination \ writerfilter/source/rtftok/rtfcontrolwords \ writerfilter/source/rtftok/rtfcharsets \ writerfilter/source/rtftok/rtfreferenceproperties \ diff --git a/writerfilter/qa/cppunittests/rtftok/data/indeterminate/.gitignore b/writerfilter/qa/cppunittests/rtftok/data/indeterminate/.gitignore new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/writerfilter/qa/cppunittests/rtftok/data/indeterminate/.gitignore diff --git a/writerfilter/qa/cppunittests/rtftok/testrtftok.cxx b/writerfilter/qa/cppunittests/rtftok/testrtftok.cxx index fbff05f8b529..b9944bb8983d 100644 --- a/writerfilter/qa/cppunittests/rtftok/testrtftok.cxx +++ b/writerfilter/qa/cppunittests/rtftok/testrtftok.cxx @@ -43,6 +43,8 @@ using namespace ::com::sun::star; +const int indeterminate = 2; + class RtfTest : public CppUnit::TestFixture { public: @@ -52,7 +54,7 @@ public: virtual void setUp(); virtual void tearDown(); - void recursiveScan(const rtl::OUString &rURL, bool bExpected); + void recursiveScan(const rtl::OUString &rURL, int nExpected); bool load(const rtl::OUString &rURL); void test(); @@ -129,7 +131,7 @@ bool RtfTest::load(const rtl::OUString &rURL) return m_xFilter->filter(aDescriptor); } -void RtfTest::recursiveScan(const rtl::OUString &rURL, bool bExpected) +void RtfTest::recursiveScan(const rtl::OUString &rURL, int nExpected) { osl::Directory aDir(rURL); @@ -141,7 +143,7 @@ void RtfTest::recursiveScan(const rtl::OUString &rURL, bool bExpected) aItem.getFileStatus(aFileStatus); rtl::OUString sURL = aFileStatus.getFileURL(); if (aFileStatus.getFileType() == osl::FileStatus::Directory) - recursiveScan(sURL, bExpected); + recursiveScan(sURL, nExpected); else { //ignore .files @@ -150,9 +152,18 @@ void RtfTest::recursiveScan(const rtl::OUString &rURL, bool bExpected) (sURL.getStr()[nLastSlash+1] == '.')) continue; - bool bRes = load(sURL); rtl::OString aRes(rtl::OUStringToOString(sURL, osl_getThreadTextEncoding())); - CPPUNIT_ASSERT_MESSAGE(aRes.getStr(), bRes == bExpected); + if (nExpected == indeterminate) + printf("loading %s\n", aRes.getStr()); + sal_uInt32 nStartTime = osl_getGlobalTimer(); + bool bRes = load(sURL); + sal_uInt32 nEndTime = osl_getGlobalTimer(); + if (nExpected == indeterminate) + { + printf("pass/fail was %d (%"SAL_PRIuUINT32" ms)\n", bRes, nEndTime-nStartTime); + continue; + } + CPPUNIT_ASSERT_MESSAGE(aRes.getStr(), bRes == nExpected); } } CPPUNIT_ASSERT_MESSAGE("failed to close directory", osl::FileBase::E_None == aDir.close()); @@ -162,6 +173,7 @@ void RtfTest::test() { recursiveScan(m_aSrcRoot + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/writerfilter/qa/cppunittests/rtftok/data/pass")), true); recursiveScan(m_aSrcRoot + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/writerfilter/qa/cppunittests/rtftok/data/fail")), false); + recursiveScan(m_aSrcRoot + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/writerfilter/qa/cppunittests/rtftok/data/indeterminate")), indeterminate); printf("Rtf: tested %d files\n", m_nLoadedDocs); } diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index ba8f9704da74..74f6963e3808 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -68,8 +68,10 @@ #include <com/sun/star/style/LineSpacing.hpp> #include <com/sun/star/style/LineSpacingMode.hpp> #include <com/sun/star/table/BorderLine2.hpp> +#include <com/sun/star/text/FootnoteNumbering.hpp> #include <com/sun/star/text/TextGridMode.hpp> #include <com/sun/star/text/XDocumentIndexesSupplier.hpp> +#include <com/sun/star/text/XTextFieldsSupplier.hpp> #include <com/sun/star/text/WritingMode.hpp> #include <com/sun/star/text/WritingMode2.hpp> #include <com/sun/star/text/XFootnote.hpp> @@ -166,6 +168,17 @@ DomainMapper::~DomainMapper() uno::Reference< container::XIndexAccess > xIndexes = xIndexesSupplier->getDocumentIndexes(); nIndexes = xIndexes->getCount(); } + // If we have page references, those need updating as well, similar to the indexes. + uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(m_pImpl->GetTextDocument(), uno::UNO_QUERY); + if(xTextFieldsSupplier.is()) + { + uno::Reference<container::XEnumeration> xEnumeration = xTextFieldsSupplier->getTextFields()->createEnumeration(); + while(xEnumeration->hasMoreElements()) + { + ++nIndexes; + xEnumeration->nextElement(); + } + } if( nIndexes ) { //index update has to wait until first view is created @@ -1768,6 +1781,28 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext, SprmType case NS_sprm::LN_PFAutoSpaceDN: break; // sprmPFAutoSpaceDN case NS_sprm::LN_PWAlignFont: + { + sal_Int16 nAlignment = 0; + switch (nIntValue) + { + case NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_top: + nAlignment = 2; + break; + case NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_center: + nAlignment = 3; + break; + case NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_baseline: + nAlignment = 1; + break; + case NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_bottom: + nAlignment = 4; + break; + case NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_auto: + default: + break; + } + rContext->Insert( PROP_PARA_VERT_ALIGNMENT, true, uno::makeAny( nAlignment) ); + } break; // sprmPWAlignFont case NS_sprm::LN_PFrameTextFlow: break; // sprmPFrameTextFlow @@ -3021,6 +3056,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext, SprmType // -> so this property can be ignored break; case NS_ooxml::LN_EG_FtnEdnNumProps_numStart: + case NS_ooxml::LN_EG_FtnEdnNumProps_numRestart: case NS_ooxml::LN_CT_FtnProps_numFmt: case NS_ooxml::LN_CT_EdnProps_numFmt: { @@ -3030,20 +3066,36 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext, SprmType if( m_pImpl->IsInFootnoteProperties() ) { uno::Reference< text::XFootnotesSupplier> xFootnotesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY ); - xFtnEdnSettings = xFootnotesSupplier->getFootnoteSettings(); + if (xFootnotesSupplier.is()) + xFtnEdnSettings = xFootnotesSupplier->getFootnoteSettings(); } else { uno::Reference< text::XEndnotesSupplier> xEndnotesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY ); - xFtnEdnSettings = xEndnotesSupplier->getEndnoteSettings(); + if (xEndnotesSupplier.is()) + xFtnEdnSettings = xEndnotesSupplier->getEndnoteSettings(); } - if( NS_ooxml::LN_EG_FtnEdnNumProps_numStart == nSprmId ) + if( NS_ooxml::LN_EG_FtnEdnNumProps_numStart == nSprmId && xFtnEdnSettings.is()) { xFtnEdnSettings->setPropertyValue( PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_START_AT), uno::makeAny( sal_Int16( nIntValue - 1 ))); } - else + else if( NS_ooxml::LN_EG_FtnEdnNumProps_numRestart == nSprmId && xFtnEdnSettings.is()) + { + sal_Int16 nFootnoteCounting = 0; + switch (nIntValue) + { + case NS_ooxml::LN_Value_ST_RestartNumber_continuous: nFootnoteCounting = text::FootnoteNumbering::PER_DOCUMENT; break; + case NS_ooxml::LN_Value_ST_RestartNumber_eachPage: nFootnoteCounting = text::FootnoteNumbering::PER_PAGE; break; + case NS_ooxml::LN_Value_ST_RestartNumber_eachSect: nFootnoteCounting = text::FootnoteNumbering::PER_CHAPTER; break; + default: break; + } + xFtnEdnSettings->setPropertyValue( + PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_FOOTNOTE_COUNTING ), + uno::makeAny( nFootnoteCounting )); + } + else if (xFtnEdnSettings.is()) { sal_Int16 nNumType = ConversionHelper::ConvertNumberingType( nIntValue ); xFtnEdnSettings->setPropertyValue( diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 1ded4ad802c9..dc487b55e721 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -288,6 +288,8 @@ void DomainMapper_Impl::SetDocumentSettingsProperty( const ::rtl::OUString& rPro void DomainMapper_Impl::RemoveLastParagraph( ) { + if (m_aTextAppendStack.empty()) + return; uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; if (!xTextAppend.is()) return; @@ -323,9 +325,12 @@ void DomainMapper_Impl::PushProperties(ContextType eId) // beginning with the second section group a section has to be inserted // into the document SectionPropertyMap* pSectionContext_ = dynamic_cast< SectionPropertyMap* >( pInsert.get() ); - uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; - if(xTextAppend.is()) - pSectionContext_->SetStart( xTextAppend->getEnd() ); + if (!m_aTextAppendStack.empty()) + { + uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; + if (xTextAppend.is()) + pSectionContext_->SetStart( xTextAppend->getEnd() ); + } } m_aPropertyStacks[eId].push( pInsert ); m_aContextStack.push(eId); @@ -700,7 +705,9 @@ void DomainMapper_Impl::finishParagraph( PropertyMapPtr pPropertyMap ) ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pPropertyMap.get() ); TextAppendContext& rAppendContext = m_aTextAppendStack.top(); - uno::Reference< text::XTextAppend > xTextAppend = rAppendContext.xTextAppend; + uno::Reference< text::XTextAppend > xTextAppend; + if (!m_aTextAppendStack.empty()) + xTextAppend = rAppendContext.xTextAppend; PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); #ifdef DEBUG_DOMAINMAPPER @@ -1023,6 +1030,8 @@ util::DateTime lcl_DateStringToDateTime( const ::rtl::OUString& rDateTime ) void DomainMapper_Impl::appendTextPortion( const ::rtl::OUString& rString, PropertyMapPtr pPropertyMap ) { + if (m_aTextAppendStack.empty()) + return; uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; if(xTextAppend.is() && ! getTableManager( ).isIgnore()) { @@ -1124,6 +1133,8 @@ uno::Reference< beans::XPropertySet > DomainMapper_Impl::appendTextSectionAfter( uno::Reference< text::XTextRange >& xBefore ) { uno::Reference< beans::XPropertySet > xRet; + if (m_aTextAppendStack.empty()) + return xRet; uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; if(xTextAppend.is()) { @@ -1164,6 +1175,8 @@ void DomainMapper_Impl::PushPageHeader(SectionPropertyMap::PageType eType) GetPageStyles(), m_xTextFactory, eType == SectionPropertyMap::PAGE_FIRST ); + if (!xPageStyle.is()) + return; try { PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); @@ -1201,6 +1214,8 @@ void DomainMapper_Impl::PushPageFooter(SectionPropertyMap::PageType eType) GetPageStyles(), m_xTextFactory, eType == SectionPropertyMap::PAGE_FIRST ); + if (!xPageStyle.is()) + return; try { PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); @@ -1229,7 +1244,8 @@ void DomainMapper_Impl::PopPageHeaderFooter() //header and footer always have an empty paragraph at the end //this has to be removed RemoveLastParagraph( ); - m_aTextAppendStack.pop(); + if (!m_aTextAppendStack.empty()) + m_aTextAppendStack.pop(); } @@ -1238,7 +1254,9 @@ void DomainMapper_Impl::PushFootOrEndnote( bool bIsFootnote ) try { PropertyMapPtr pTopContext = GetTopContext(); - uno::Reference< text::XText > xFootnoteText( GetTextFactory()->createInstance( + uno::Reference< text::XText > xFootnoteText; + if (GetTextFactory().is()) + xFootnoteText.set( GetTextFactory()->createInstance( bIsFootnote ? ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.Footnote") ) : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.Endnote") )), uno::UNO_QUERY_THROW ); @@ -1359,6 +1377,8 @@ void DomainMapper_Impl::PushAnnotation() try { PropertyMapPtr pTopContext = GetTopContext(); + if (!GetTextFactory().is()) + return; m_xAnnotationField = uno::Reference< beans::XPropertySet >( GetTextFactory()->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextField.Annotation") ) ), uno::UNO_QUERY_THROW ); @@ -1376,7 +1396,8 @@ void DomainMapper_Impl::PushAnnotation() void DomainMapper_Impl::PopFootOrEndnote() { RemoveLastParagraph(); - m_aTextAppendStack.pop(); + if (!m_aTextAppendStack.empty()) + m_aTextAppendStack.pop(); } @@ -1746,12 +1767,19 @@ void DomainMapper_Impl::PushFieldContext() dmapper_logger->element("pushFieldContext"); #endif - uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; - //insert a dummy char to make sure the start range doesn't move together with the to-be-appended text - xTextAppend->appendTextPortion(::rtl::OUString( '-' ), uno::Sequence< beans::PropertyValue >() ); - uno::Reference< text::XTextCursor > xCrsr = xTextAppend->createTextCursorByRange( xTextAppend->getEnd() ); - xCrsr->goLeft( 1, false ); - m_aFieldStack.push( FieldContextPtr( new FieldContext( xCrsr->getStart() ) ) ); + uno::Reference< text::XTextAppend > xTextAppend; + if (!m_aTextAppendStack.empty()) + xTextAppend = m_aTextAppendStack.top().xTextAppend; + uno::Reference< text::XTextRange > xStart; + if (xTextAppend.is()) + { + //insert a dummy char to make sure the start range doesn't move together with the to-be-appended text + xTextAppend->appendTextPortion(::rtl::OUString( '-' ), uno::Sequence< beans::PropertyValue >() ); + uno::Reference< text::XTextCursor > xCrsr = xTextAppend->createTextCursorByRange( xTextAppend->getEnd() ); + xCrsr->goLeft( 1, false ); + xStart = xCrsr->getStart(); + } + m_aFieldStack.push( FieldContextPtr( new FieldContext( xStart ) ) ); } /*------------------------------------------------------------------------- //the current field context waits for the completion of the command @@ -1909,6 +1937,7 @@ if(!bFilled) {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NEXT")), "DatabaseNextSet", "", FIELD_NEXT }, {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NEXTIF")), "DatabaseNextSet", "", FIELD_NEXTIF }, {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PAGE")), "PageNumber", "", FIELD_PAGE }, + {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PAGEREF")), "GetReference", "", FIELD_PAGEREF }, {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("REF")), "GetReference", "", FIELD_REF }, {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("REVNUM")), "DocInfo.Revision", "", FIELD_REVNUM }, {::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SAVEDATE")), "DocInfo.Change", "", FIELD_SAVEDATE }, @@ -2282,15 +2311,18 @@ void DomainMapper_Impl::handleToc if( !bFromOutline && !bFromEntries && !sTemplate.getLength() ) bFromOutline = true; - uno::Reference< beans::XPropertySet > xTOC( - m_xTextFactory->createInstance - ( bTableOfFigures ? - ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM - ("com.sun.star.text.IllustrationsIndex")) - : sTOCServiceName), - uno::UNO_QUERY_THROW); - xTOC->setPropertyValue(rPropNameSupplier.GetName( PROP_TITLE ), uno::makeAny(::rtl::OUString())); - if( !bTableOfFigures ) + uno::Reference< beans::XPropertySet > xTOC; + if (m_xTextFactory.is()) + xTOC.set( + m_xTextFactory->createInstance + ( bTableOfFigures ? + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM + ("com.sun.star.text.IllustrationsIndex")) + : sTOCServiceName), + uno::UNO_QUERY_THROW); + if (xTOC.is()) + xTOC->setPropertyValue(rPropNameSupplier.GetName( PROP_TITLE ), uno::makeAny(::rtl::OUString())); + if( !bTableOfFigures && xTOC.is() ) { xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_LEVEL ), uno::makeAny( nMaxLevel ) ); xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_CREATE_FROM_OUTLINE ), uno::makeAny( bFromOutline )); @@ -2475,8 +2507,11 @@ void DomainMapper_Impl::CloseFieldCommand() dmapper_logger->endElement(); #endif - xFieldInterface = m_xTextFactory->createInstance(sServiceName); - xFieldProperties = uno::Reference< beans::XPropertySet >( xFieldInterface, uno::UNO_QUERY_THROW); + if (m_xTextFactory.is()) + { + xFieldInterface = m_xTextFactory->createInstance(sServiceName); + xFieldProperties = uno::Reference< beans::XPropertySet >( xFieldInterface, uno::UNO_QUERY_THROW); + } } PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); switch( aIt->second.eFieldId ) @@ -2698,24 +2733,30 @@ void DomainMapper_Impl::CloseFieldCommand() case FIELD_NEXT : break; case FIELD_NEXTIF : break; case FIELD_PAGE : - xFieldProperties->setPropertyValue( - rPropNameSupplier.GetName(PROP_NUMBERING_TYPE), - uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) )); - xFieldProperties->setPropertyValue( - rPropNameSupplier.GetName(PROP_SUB_TYPE), - uno::makeAny( text::PageNumberType_CURRENT )); + if (xFieldProperties.is()) + { + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_NUMBERING_TYPE), + uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) )); + xFieldProperties->setPropertyValue( + rPropNameSupplier.GetName(PROP_SUB_TYPE), + uno::makeAny( text::PageNumberType_CURRENT )); + } break; + case FIELD_PAGEREF: case FIELD_REF: { - ::rtl::OUString sBookmark = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" REF") ); + bool bPageRef = aIt->second.eFieldId == FIELD_PAGEREF; + ::rtl::OUString sBookmark = lcl_ExtractParameter(pContext->GetCommand(), + (bPageRef ? sizeof(" PAGEREF") : sizeof(" REF"))); xFieldProperties->setPropertyValue( rPropNameSupplier.GetName(PROP_REFERENCE_FIELD_SOURCE), uno::makeAny( sal_Int16(text::ReferenceFieldSource::BOOKMARK)) ); xFieldProperties->setPropertyValue( rPropNameSupplier.GetName(PROP_SOURCE_NAME), uno::makeAny( sBookmark) ); - sal_Int16 nFieldPart = text::ReferenceFieldPart::TEXT; + sal_Int16 nFieldPart = (bPageRef ? text::ReferenceFieldPart::PAGE : text::ReferenceFieldPart::TEXT); ::rtl::OUString sValue; if( lcl_FindInCommand( pContext->GetCommand(), 'p', sValue )) { @@ -2939,7 +2980,9 @@ void DomainMapper_Impl::PopFieldContext() CloseFieldCommand(); //insert the field, TC or TOC - uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; + uno::Reference< text::XTextAppend > xTextAppend; + if (!m_aTextAppendStack.empty()) + xTextAppend = m_aTextAppendStack.top().xTextAppend; if(xTextAppend.is()) { try @@ -3015,6 +3058,8 @@ void DomainMapper_Impl::PopFieldContext() void DomainMapper_Impl::AddBookmark( const ::rtl::OUString& rBookmarkName, const ::rtl::OUString& rId ) { + if (m_aTextAppendStack.empty()) + return; uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; BookmarkMap_t::iterator aBookmarkIter = m_aBookmarkMap.find( rId ); //is the bookmark name already registered? @@ -3023,33 +3068,41 @@ void DomainMapper_Impl::AddBookmark( const ::rtl::OUString& rBookmarkName, const if( aBookmarkIter != m_aBookmarkMap.end() ) { static const rtl::OUString sBookmarkService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.Bookmark")); - uno::Reference< text::XTextContent > xBookmark( m_xTextFactory->createInstance( sBookmarkService ), uno::UNO_QUERY_THROW ); - uno::Reference< text::XTextCursor > xCursor; - uno::Reference< text::XText > xText = aBookmarkIter->second.m_xTextRange->getText(); - if( aBookmarkIter->second.m_bIsStartOfText ) - xCursor = xText->createTextCursorByRange( xText->getStart() ); - else + if (m_xTextFactory.is()) { - xCursor = xText->createTextCursorByRange( aBookmarkIter->second.m_xTextRange ); - xCursor->goRight( 1, false ); - } + uno::Reference< text::XTextContent > xBookmark( m_xTextFactory->createInstance( sBookmarkService ), uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextCursor > xCursor; + uno::Reference< text::XText > xText = aBookmarkIter->second.m_xTextRange->getText(); + if( aBookmarkIter->second.m_bIsStartOfText ) + xCursor = xText->createTextCursorByRange( xText->getStart() ); + else + { + xCursor = xText->createTextCursorByRange( aBookmarkIter->second.m_xTextRange ); + xCursor->goRight( 1, false ); + } - xCursor->gotoRange( xTextAppend->getEnd(), true ); - uno::Reference< container::XNamed > xBkmNamed( xBookmark, uno::UNO_QUERY_THROW ); - //todo: make sure the name is not used already! - if ( aBookmarkIter->second.m_sBookmarkName.getLength() > 0 ) - xBkmNamed->setName( aBookmarkIter->second.m_sBookmarkName ); - else - xBkmNamed->setName( rBookmarkName ); - xTextAppend->insertTextContent( uno::Reference< text::XTextRange >( xCursor, uno::UNO_QUERY_THROW), xBookmark, !xCursor->isCollapsed() ); + xCursor->gotoRange( xTextAppend->getEnd(), true ); + uno::Reference< container::XNamed > xBkmNamed( xBookmark, uno::UNO_QUERY_THROW ); + //todo: make sure the name is not used already! + if ( aBookmarkIter->second.m_sBookmarkName.getLength() > 0 ) + xBkmNamed->setName( aBookmarkIter->second.m_sBookmarkName ); + else + xBkmNamed->setName( rBookmarkName ); + xTextAppend->insertTextContent( uno::Reference< text::XTextRange >( xCursor, uno::UNO_QUERY_THROW), xBookmark, !xCursor->isCollapsed() ); + } m_aBookmarkMap.erase( aBookmarkIter ); } else { //otherwise insert a text range as marker - uno::Reference< text::XTextCursor > xCursor = xTextAppend->createTextCursorByRange( xTextAppend->getEnd() ); - bool bIsStart = !xCursor->goLeft(1, false); - uno::Reference< text::XTextRange > xCurrent = xCursor->getStart(); + bool bIsStart = true; + uno::Reference< text::XTextRange > xCurrent; + if (xTextAppend.is()) + { + uno::Reference< text::XTextCursor > xCursor = xTextAppend->createTextCursorByRange( xTextAppend->getEnd() ); + bIsStart = !xCursor->goLeft(1, false); + xCurrent = xCursor->getStart(); + } m_aBookmarkMap.insert(BookmarkMap_t::value_type( rId, BookmarkInsertPosition( bIsStart, rBookmarkName, xCurrent ) )); } } diff --git a/writerfilter/source/dmapper/FieldTypes.hxx b/writerfilter/source/dmapper/FieldTypes.hxx index a16c80816b7d..bb765f5c5ebe 100644 --- a/writerfilter/source/dmapper/FieldTypes.hxx +++ b/writerfilter/source/dmapper/FieldTypes.hxx @@ -171,6 +171,7 @@ enum FieldId see lcl_ParseNumberingType */ ,FIELD_PAGE + ,FIELD_PAGEREF /* REF targetbkm \f \* MERGEFORMAT -> imports a ShowVariable (bookmarkname)? \h hyerlink to paragraph diff --git a/writerfilter/source/dmapper/ModelEventListener.cxx b/writerfilter/source/dmapper/ModelEventListener.cxx index c151c5056335..e86aa0195182 100644 --- a/writerfilter/source/dmapper/ModelEventListener.cxx +++ b/writerfilter/source/dmapper/ModelEventListener.cxx @@ -26,9 +26,15 @@ * ************************************************************************/ #include <ModelEventListener.hxx> +#include <PropertyIds.hxx> #include <com/sun/star/document/XEventBroadcaster.hpp> #include <com/sun/star/text/XDocumentIndex.hpp> #include <com/sun/star/text/XDocumentIndexesSupplier.hpp> +#include <com/sun/star/text/XTextFieldsSupplier.hpp> +#include <com/sun/star/util/XRefreshable.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/text/ReferenceFieldPart.hpp> +#include <com/sun/star/text/ReferenceFieldSource.hpp> namespace writerfilter { namespace dmapper { @@ -54,6 +60,8 @@ void ModelEventListener::notifyEvent( const document::EventObject& rEvent ) thro { try { + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + uno::Reference< text::XDocumentIndexesSupplier> xIndexesSupplier( rEvent.Source, uno::UNO_QUERY ); //remove listener uno::Reference<document::XEventBroadcaster>(rEvent.Source, uno::UNO_QUERY )->removeEventListener( @@ -67,6 +75,26 @@ void ModelEventListener::notifyEvent( const document::EventObject& rEvent ) thro uno::Reference< text::XDocumentIndex> xIndex( xIndexes->getByIndex( nIndex ), uno::UNO_QUERY ); xIndex->update(); } + + // If we have PAGEREF fields, update fields as well. + uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(rEvent.Source, uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xEnumeration(xTextFieldsSupplier->getTextFields()->createEnumeration(), uno::UNO_QUERY); + sal_Int32 nIndex = 0; + while(xEnumeration->hasMoreElements()) + { + uno::Reference<beans::XPropertySet> xPropertySet(xEnumeration->nextElement(), uno::UNO_QUERY); + sal_Int16 nSource; + xPropertySet->getPropertyValue(rPropNameSupplier.GetName(PROP_REFERENCE_FIELD_SOURCE)) >>= nSource; + sal_Int16 nPart; + xPropertySet->getPropertyValue(rPropNameSupplier.GetName(PROP_REFERENCE_FIELD_PART)) >>= nPart; + if (nSource == text::ReferenceFieldSource::BOOKMARK && nPart == text::ReferenceFieldPart::PAGE) + ++nIndex; + } + if (nIndex) + { + uno::Reference<util::XRefreshable> xRefreshable(xTextFieldsSupplier->getTextFields(), uno::UNO_QUERY); + xRefreshable->refresh(); + } } catch( const uno::Exception& rEx ) { diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx index 5373c005ee55..d87d17106815 100644 --- a/writerfilter/source/dmapper/PropertyIds.cxx +++ b/writerfilter/source/dmapper/PropertyIds.cxx @@ -116,6 +116,7 @@ const rtl::OUString& PropertyNameSupplier::GetName( PropertyIds eId ) const case PROP_PARA_STYLE_NAME: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaStyleName")); break; case PROP_PARA_ADJUST: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaAdjust")); break; + case PROP_PARA_VERT_ALIGNMENT: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaVertAlignment")); break; case PROP_PARA_LAST_LINE_ADJUST: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaLastLineAdjust")); break; case PROP_PARA_RIGHT_MARGIN : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaRightMargin")); break; case PROP_PARA_LEFT_MARGIN : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaLeftMargin")); break; @@ -204,6 +205,7 @@ const rtl::OUString& PropertyNameSupplier::GetName( PropertyIds eId ) const case PROP_FOOTER_TEXT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FooterText")); break; case PROP_FOOTER_IS_SHARED : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FooterIsShared")); break; case PROP_FOOTER_IS_ON : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FooterIsOn")); break; + case PROP_FOOTNOTE_COUNTING : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FootnoteCounting")); break; case PROP_WIDTH : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Width")); break; case PROP_HEIGHT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Height")); break; case PROP_SEPARATOR_LINE_IS_ON : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SeparatorLineIsOn")); break; diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx index 6ddd1d86a16b..81afa294752c 100644 --- a/writerfilter/source/dmapper/PropertyIds.hxx +++ b/writerfilter/source/dmapper/PropertyIds.hxx @@ -143,6 +143,7 @@ enum PropertyIds ,PROP_FOOTER_IS_SHARED ,PROP_FOOTER_TEXT ,PROP_FOOTER_TEXT_LEFT + ,PROP_FOOTNOTE_COUNTING ,PROP_FORMAT ,PROP_FULL_NAME ,PROP_GAMMA @@ -225,6 +226,7 @@ enum PropertyIds ,PROP_PARA_STYLE_NAME ,PROP_PARA_TAB_STOPS ,PROP_PARA_TOP_MARGIN + ,PROP_PARA_VERT_ALIGNMENT ,PROP_PARA_WIDOWS ,PROP_PARENT_NUMBERING ,PROP_POSITION_AND_SPACE_MODE diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx index bfe5cffc08f5..7cadff2d091e 100644 --- a/writerfilter/source/dmapper/PropertyMap.cxx +++ b/writerfilter/source/dmapper/PropertyMap.cxx @@ -506,7 +506,8 @@ void SectionPropertyMap::ApplyBorderToPageStyles( if( m_pBorderLines[nBorder] ) { const ::rtl::OUString sBorderName = rPropNameSupplier.GetName( aBorderIds[nBorder] ); - xFirst->setPropertyValue( sBorderName, uno::makeAny( *m_pBorderLines[nBorder] )); + if (xFirst.is()) + xFirst->setPropertyValue( sBorderName, uno::makeAny( *m_pBorderLines[nBorder] )); if(xSecond.is()) xSecond->setPropertyValue( sBorderName, uno::makeAny( *m_pBorderLines[nBorder] )); } @@ -541,7 +542,8 @@ void SectionPropertyMap::SetBorderDistance( uno::Reference< beans::XPropertySet nDist = nMargin - nDistance; } const ::rtl::OUString sBorderDistanceName = rPropNameSupplier.GetName( eDistId ); - xStyle->setPropertyValue( sBorderDistanceName, uno::makeAny( nDist )); + if (xStyle.is()) + xStyle->setPropertyValue( sBorderDistanceName, uno::makeAny( nDist )); } @@ -554,7 +556,8 @@ uno::Reference< text::XTextColumns > SectionPropertyMap::ApplyColumnProperties( { PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); const ::rtl::OUString sTextColumns = rPropNameSupplier.GetName( PROP_TEXT_COLUMNS ); - xColumnContainer->getPropertyValue(sTextColumns) >>= xColumns; + if (xColumnContainer.is()) + xColumnContainer->getPropertyValue(sTextColumns) >>= xColumns; uno::Reference< beans::XPropertySet > xColumnPropSet( xColumns, uno::UNO_QUERY_THROW ); if( !m_bEvenlySpaced && (sal_Int32(m_aColWidth.size()) == (m_nColumnCount + 1 )) && @@ -673,8 +676,10 @@ void SectionPropertyMap::CopyLastHeaderFooter( bool bFirstPage, DomainMapper_Imp bool bHasHeader = false; rtl::OUString sHeaderIsOn = rPropNameSupplier.GetName( PROP_HEADER_IS_ON ); - xPrevStyle->getPropertyValue( sHeaderIsOn ) >>= bHasPrevHeader; - xStyle->getPropertyValue( sHeaderIsOn ) >>= bHasHeader; + if (xPrevStyle.is()) + xPrevStyle->getPropertyValue( sHeaderIsOn ) >>= bHasPrevHeader; + if (xStyle.is()) + xStyle->getPropertyValue( sHeaderIsOn ) >>= bHasHeader; bool bCopyHeader = bHasPrevHeader && !bHasHeader; if ( bCopyHeader ) @@ -684,11 +689,13 @@ void SectionPropertyMap::CopyLastHeaderFooter( bool bFirstPage, DomainMapper_Imp bool bHasFooter = false; rtl::OUString sFooterIsOn = rPropNameSupplier.GetName( PROP_FOOTER_IS_ON ); - xPrevStyle->getPropertyValue( sFooterIsOn ) >>= bHasPrevFooter; - xStyle->getPropertyValue( sFooterIsOn ) >>= bHasFooter; + if (xPrevStyle.is()) + xPrevStyle->getPropertyValue( sFooterIsOn ) >>= bHasPrevFooter; + if (xStyle.is()) + xStyle->getPropertyValue( sFooterIsOn ) >>= bHasFooter; bool bCopyFooter = bHasPrevFooter && !bHasFooter; - if ( bCopyFooter ) + if ( bCopyFooter && xStyle.is() ) xStyle->setPropertyValue( sFooterIsOn, uno::makeAny( sal_True ) ); // Copying the text properties @@ -705,11 +712,13 @@ void SectionPropertyMap::CopyLastHeaderFooter( bool bFirstPage, DomainMapper_Imp clog << rtl::OUStringToOString( sName, RTL_TEXTENCODING_UTF8 ).getStr( ) << endl; #endif // TODO has to be copied - uno::Reference< text::XTextCopy > xTxt( - xStyle->getPropertyValue( sName ), uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextCopy > xTxt; + if (xStyle.is()) + xTxt.set(xStyle->getPropertyValue( sName ), uno::UNO_QUERY_THROW ); - uno::Reference< text::XTextCopy > xPrevTxt( - xPrevStyle->getPropertyValue( sName ), uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextCopy > xPrevTxt; + if (xPrevStyle.is()) + xPrevTxt.set(xPrevStyle->getPropertyValue( sName ), uno::UNO_QUERY_THROW ); xTxt->copyText( xPrevTxt ); } diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx index ecf6f534f125..d24fded13ce9 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx @@ -53,6 +53,7 @@ #include <rtfvalue.hxx> #include <rtfsprm.hxx> #include <rtfreferenceproperties.hxx> +#include <rtfskipdestination.hxx> #define TWIP_TO_MM100(TWIP) ((TWIP) >= 0 ? (((TWIP)*127L+36L)/72L) : (((TWIP)*127L-36L)/72L)) @@ -118,6 +119,16 @@ static void lcl_putNestedSprm(RTFSprms& rSprms, Id nParent, Id nId, RTFValue::Po lcl_putNestedAttribute(rSprms, nParent, nId, pValue, bOverwrite, false); } +static bool lcl_eraseNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId) +{ + RTFValue::Pointer_t pParent = rSprms.find(nParent); + if (!pParent.get()) + // It doesn't even have a parent, we're done! + return false; + RTFSprms& rAttributes = pParent->getAttributes(); + return rAttributes.erase(nId); +} + static RTFSprms& lcl_getLastAttributes(RTFSprms& rSprms, Id nId) { RTFValue::Pointer_t p = rSprms.find(nId); @@ -253,6 +264,7 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x m_bFirstRun(true), m_bFirstRow(true), m_bNeedPap(false), + m_bNeedCr(false), m_aListTableSprms(), m_aSettingsTableSprms(), m_xStorage(), @@ -272,7 +284,6 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x m_aObjectSprms(), m_aObjectAttributes(), m_bObject(false), - m_pObjectData(0), m_aFontTableEntries(), m_nCurrentFontIndex(0), m_aStyleTableEntries(), @@ -283,7 +294,6 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x m_pInStream = utl::UcbStreamHelper::CreateStream(xInputStream, sal_True); m_xModelFactory.set(m_xDstDoc, uno::UNO_QUERY); - OSL_ASSERT(m_xModelFactory.is()); uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(m_xDstDoc, uno::UNO_QUERY); if (xDocumentPropertiesSupplier.is()) @@ -291,14 +301,12 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x m_pGraphicHelper = new oox::GraphicHelper(m_xContext, xFrame, m_xStorage); - m_pTokenizer = new RTFTokenizer(*this, m_pInStream); - m_pSdrImport = new RTFSdrImport(*this, m_xDstDoc); + m_pTokenizer.reset(new RTFTokenizer(*this, m_pInStream)); + m_pSdrImport.reset(new RTFSdrImport(*this, m_xDstDoc)); } RTFDocumentImpl::~RTFDocumentImpl() { - delete m_pTokenizer; - delete m_pSdrImport; } SvStream& RTFDocumentImpl::Strm() @@ -326,6 +334,18 @@ bool RTFDocumentImpl::isSubstream() return m_bIsSubstream; } +void RTFDocumentImpl::finishSubstream() +{ + // At the end of a footnote stream, we need to emit a run break when importing from Word. + // We can't do so unconditionally, as Writer already writes a \par at the end of the footnote. + if (m_bNeedCr) + { + Mapper().startCharacterGroup(); + runBreak(); + Mapper().endCharacterGroup(); + } +} + void RTFDocumentImpl::setIgnoreFirst(OUString& rIgnoreFirst) { m_aIgnoreFirst = rIgnoreFirst; @@ -383,6 +403,7 @@ void RTFDocumentImpl::runBreak() { sal_uInt8 sBreak[] = { 0xd }; Mapper().text(sBreak, 1); + m_bNeedCr = false; } void RTFDocumentImpl::tableBreak() @@ -498,7 +519,7 @@ int RTFDocumentImpl::resolvePict(bool bInline) int b = 0, count = 2; // Feed the destination text to a stream. - OString aStr = OUStringToOString(m_aDestinationText.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US); + OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US); const char *str = aStr.getStr(); for (int i = 0; i < aStr.getLength(); ++i) { @@ -528,10 +549,9 @@ int RTFDocumentImpl::resolvePict(bool bInline) // Wrap it in an XShape. uno::Reference<drawing::XShape> xShape; OUString aService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.GraphicObjectShape")); - xShape.set(m_xModelFactory->createInstance(aService), uno::UNO_QUERY); - OSL_ASSERT(xShape.is()); + if (m_xModelFactory.is()) + xShape.set(m_xModelFactory->createInstance(aService), uno::UNO_QUERY); uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY); - OSL_ASSERT(xPropertySet.is()); if (m_bObject) { // Set bitmap @@ -559,7 +579,8 @@ int RTFDocumentImpl::resolvePict(bool bInline) m_aObjectAttributes->push_back(make_pair(NS_ooxml::LN_shape, pShapeValue)); return 0; } - xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicURL")), uno::Any(aGraphicUrl)); + if (xPropertySet.is()) + xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicURL")), uno::Any(aGraphicUrl)); // Send it to the dmapper. RTFSprms aSprms; @@ -623,6 +644,7 @@ int RTFDocumentImpl::resolvePict(bool bInline) aSprms->push_back(make_pair(NS_ooxml::LN_anchor_anchor, pValue)); } writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aAttributes, aSprms)); + checkFirstRun(); Mapper().props(pProperties); return 0; @@ -695,7 +717,7 @@ void RTFDocumentImpl::text(OUString& rString) rString = rString.copy(0, rString.getLength() - 1); bEnd = true; } - m_aDestinationText.append(rString); + m_aStates.top().aDestinationText.append(rString); if (bEnd) { switch (m_aStates.top().nDestinationState) @@ -703,7 +725,7 @@ void RTFDocumentImpl::text(OUString& rString) case DESTINATION_FONTTABLE: case DESTINATION_FONTENTRY: { - RTFValue::Pointer_t pValue(new RTFValue(m_aDestinationText.makeStringAndClear())); + RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aDestinationText.makeStringAndClear())); m_aStates.top().aTableAttributes->push_back(make_pair(NS_rtf::LN_XSZFFN, pValue)); writerfilter::Reference<Properties>::Pointer_t const pProp( @@ -715,7 +737,7 @@ void RTFDocumentImpl::text(OUString& rString) case DESTINATION_STYLESHEET: case DESTINATION_STYLEENTRY: { - RTFValue::Pointer_t pValue(new RTFValue(m_aDestinationText.makeStringAndClear())); + RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aDestinationText.makeStringAndClear())); m_aStates.top().aTableAttributes->push_back(make_pair(NS_rtf::LN_XSTZNAME1, pValue)); writerfilter::Reference<Properties>::Pointer_t const pProp( @@ -726,7 +748,7 @@ void RTFDocumentImpl::text(OUString& rString) break; case DESTINATION_REVISIONTABLE: case DESTINATION_REVISIONENTRY: - m_aAuthors[m_aAuthors.size()] = m_aDestinationText.makeStringAndClear(); + m_aAuthors[m_aAuthors.size()] = m_aStates.top().aDestinationText.makeStringAndClear(); break; default: break; } @@ -751,7 +773,8 @@ void RTFDocumentImpl::text(OUString& rString) case DESTINATION_OBJDATA: case DESTINATION_ANNOTATIONDATE: case DESTINATION_ANNOTATIONAUTHOR: - m_aDestinationText.append(rString); + case DESTINATION_FALT: + m_aStates.top().aDestinationText.append(rString); break; case DESTINATION_EQINSTRUCTION: if (rString.copy(0, 2).equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("do")) @@ -789,7 +812,7 @@ void RTFDocumentImpl::text(OUString& rString) // Don't return earlier, a bookmark start has to be in a paragraph group. if (m_aStates.top().nDestinationState == DESTINATION_BOOKMARKSTART) { - m_aDestinationText.append(rString); + m_aStates.top().aDestinationText.append(rString); return; } @@ -824,6 +847,7 @@ void RTFDocumentImpl::text(OUString& rString) RTFValue::Pointer_t pValue(new RTFValue(rString)); m_pCurrentBuffer->push_back(make_pair(BUFFER_UTEXT, pValue)); } + m_bNeedCr = true; if (!m_pCurrentBuffer && m_aStates.top().nDestinationState != DESTINATION_FOOTNOTE) Mapper().endCharacterGroup(); else if(m_pCurrentBuffer) @@ -876,7 +900,7 @@ void RTFDocumentImpl::replayBuffer(RTFBuffer_t& rBuffer) int RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword) { - bool bParsed = true; + RTFSkipDestination aSkip(*this); switch (nKeyword) { case RTF_RTF: @@ -1135,6 +1159,9 @@ int RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword) case RTF_ATNAUTHOR: m_aStates.top().nDestinationState = DESTINATION_ANNOTATIONAUTHOR; break; + case RTF_FALT: + m_aStates.top().nDestinationState = DESTINATION_FALT; + break; case RTF_LISTTEXT: // Should be ignored by any reader that understands Word 97 through Word 2007 numbering. case RTF_NONESTTABLES: @@ -1147,17 +1174,16 @@ int RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword) #endif // Make sure we skip destinations (even without \*) till we don't handle them m_aStates.top().nDestinationState = DESTINATION_SKIP; - bParsed = false; + aSkip.setParsed(false); break; } - skipDestination(bParsed); return 0; } int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) { - bool bParsed = true; + RTFSkipDestination aSkip(*this); sal_uInt8 cCh = 0; // Trivial symbols @@ -1181,7 +1207,6 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) { OUString aStr(OStringToOUString(OString(cCh), RTL_TEXTENCODING_MS_1252)); text(aStr); - skipDestination(bParsed); return 0; } @@ -1189,7 +1214,8 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) { case RTF_IGNORE: m_bSkipUnknown = true; - return 0; // don't reset m_bSkipUnknown after this keyword + aSkip.setReset(false); + return 0; break; case RTF_PAR: { @@ -1317,16 +1343,15 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) #if OSL_DEBUG_LEVEL > 1 OSL_TRACE("%s: TODO handle symbol '%s'", OSL_THIS_FUNC, lcl_RtfToString(nKeyword)); #endif - bParsed = false; + aSkip.setParsed(false); break; } - skipDestination(bParsed); return 0; } int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) { - bool bParsed = true; + RTFSkipDestination aSkip(*this); int nParam = -1; // Indentation @@ -1343,7 +1368,24 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) { RTFValue::Pointer_t pValue(new RTFValue(nParam)); m_aStates.top().aParagraphSprms->push_back(make_pair(NS_sprm::LN_PJc, pValue)); - skipDestination(bParsed); + return 0; + } + + // Font Alignment + switch (nKeyword) + { + case RTF_FAFIXED: + case RTF_FAAUTO: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_auto; break; + case RTF_FAHANG: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_top; break; + case RTF_FACENTER: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_center; break; + case RTF_FAROMAN: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_baseline; break; + case RTF_FAVAR: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_bottom; break; + default: break; + } + if (nParam >= 0) + { + RTFValue::Pointer_t pValue(new RTFValue(nParam)); + m_aStates.top().aParagraphSprms->push_back(make_pair(NS_sprm::LN_PWAlignFont, pValue)); return 0; } @@ -1359,7 +1401,6 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) { RTFValue::Pointer_t pValue(new RTFValue(nParam)); m_aStates.top().aTabAttributes->push_back(make_pair(NS_ooxml::LN_CT_TabStop_val, pValue)); - skipDestination(bParsed); return 0; } @@ -1378,7 +1419,6 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) { RTFValue::Pointer_t pValue(new RTFValue(nParam)); m_aStates.top().aTabAttributes->push_back(make_pair(NS_ooxml::LN_CT_TabStop_leader, pValue)); - skipDestination(bParsed); return 0; } @@ -1408,7 +1448,6 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) { RTFValue::Pointer_t pValue(new RTFValue(nParam)); lcl_putBorderProperty(m_aStates, NS_rtf::LN_BRCTYPE, pValue); - skipDestination(bParsed); return 0; } @@ -1426,7 +1465,57 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) { RTFValue::Pointer_t pValue(new RTFValue(nParam)); m_aStates.top().aSectionSprms->push_back(make_pair(NS_sprm::LN_SBkc, pValue)); - skipDestination(bParsed); + return 0; + } + + // Footnote numbering + switch (nKeyword) + { + case RTF_FTNNAR: nParam = NS_ooxml::LN_Value_ST_NumberFormat_decimal; break; + case RTF_FTNNALC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter; break; + case RTF_FTNNAUC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperLetter; break; + case RTF_FTNNRLC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman; break; + case RTF_FTNNRUC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperRoman; break; + case RTF_FTNNCHI: nParam = NS_ooxml::LN_Value_ST_NumberFormat_chicago; break; + default: break; + } + if (nParam >= 0) + { + RTFValue::Pointer_t pValue(new RTFValue(nParam)); + lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_CT_FtnProps_numFmt, pValue); + return 0; + } + + // Footnote restart type + switch (nKeyword) + { + case RTF_FTNRSTPG: nParam = NS_ooxml::LN_Value_ST_RestartNumber_eachPage; break; + case RTF_FTNRESTART: nParam = NS_ooxml::LN_Value_ST_RestartNumber_eachSect; break; + case RTF_FTNRSTCONT: nParam = NS_ooxml::LN_Value_ST_RestartNumber_continuous; break; + default: break; + } + if (nParam >= 0) + { + RTFValue::Pointer_t pValue(new RTFValue(nParam)); + lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numRestart, pValue); + return 0; + } + + // Endnote numbering + switch (nKeyword) + { + case RTF_AFTNNAR: nParam = NS_ooxml::LN_Value_ST_NumberFormat_decimal; break; + case RTF_AFTNNALC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter; break; + case RTF_AFTNNAUC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperLetter; break; + case RTF_AFTNNRLC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman; break; + case RTF_AFTNNRUC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperRoman; break; + case RTF_AFTNNCHI: nParam = NS_ooxml::LN_Value_ST_NumberFormat_chicago; break; + default: break; + } + if (nParam >= 0) + { + RTFValue::Pointer_t pValue(new RTFValue(nParam)); + lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_endnotePr, NS_ooxml::LN_CT_EdnProps_numFmt, pValue); return 0; } @@ -1444,7 +1533,6 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) RTFValue::Pointer_t pValue(new RTFValue(1)); m_aStates.top().aParagraphSprms.erase(NS_sprm::LN_PFInTable); m_aStates.top().aParagraphSprms->push_back(make_pair(nParam, pValue)); - skipDestination(bParsed); return 0; } @@ -1658,20 +1746,46 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_restart, pValue); } break; + case RTF_AENDDOC: + // Noop, this is the default in Writer. + break; + case RTF_AENDNOTES: + // Noop, Writer does not support having endnotes at the end of section. + break; + case RTF_AFTNRSTCONT: + // Noop, this is the default in Writer. + break; + case RTF_AFTNRESTART: + // Noop, Writer does not support restarting endnotes at each section. + break; + case RTF_FTNBJ: + // Noop, this is the default in Writer. + break; + case RTF_ENDDOC: + { + RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_ST_RestartNumber_eachSect)); + lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numRestart, pValue); + } + break; + case RTF_NOLINE: + lcl_eraseNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_distance); + break; + case RTF_FORMSHADE: + // Noop, this is the default in Writer. + break; default: #if OSL_DEBUG_LEVEL > 1 OSL_TRACE("%s: TODO handle flag '%s'", OSL_THIS_FUNC, lcl_RtfToString(nKeyword)); #endif - bParsed = false; + aSkip.setParsed(false); break; } - skipDestination(bParsed); return 0; } int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) { - bool bParsed = true; + RTFSkipDestination aSkip(*this); int nSprm = 0; RTFValue::Pointer_t pIntValue(new RTFValue(nParam)); // Trivial table sprms. @@ -1686,7 +1800,6 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) if (nSprm > 0) { m_aStates.top().aTableSprms->push_back(make_pair(nSprm, pIntValue)); - skipDestination(bParsed); return 0; } // Trivial character sprms. @@ -1706,7 +1819,6 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) if (nSprm > 0) { m_aStates.top().aCharacterSprms->push_back(make_pair(nSprm, pIntValue)); - skipDestination(bParsed); return 0; } // Trivial paragraph sprms. @@ -1725,7 +1837,6 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) if (nSprm > 0) { m_aStates.top().aParagraphSprms->push_back(make_pair(nSprm, pIntValue)); - skipDestination(bParsed); return 0; } @@ -1739,7 +1850,6 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) if (nSprm > 0) { m_aStates.top().aTableAttributes->push_back(make_pair(nSprm, pIntValue)); - skipDestination(bParsed); return 0; } @@ -1754,7 +1864,6 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) { RTFValue::Pointer_t pValue(new RTFValue(nParam)); m_aStates.top().aCharacterAttributes->push_back(make_pair(nSprm, pValue)); - skipDestination(bParsed); return 0; } @@ -1769,10 +1878,7 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) default: break; } if (nSprm > 0) - { - skipDestination(bParsed); return 0; - } // Then check for the more complex ones. switch (nKeyword) @@ -1822,6 +1928,8 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) { m_nCurrentStyleIndex = nParam; m_aStates.top().aTableAttributes->push_back(make_pair(NS_rtf::LN_ISTD, pIntValue)); + RTFValue::Pointer_t pValue(new RTFValue(1)); + m_aStates.top().aTableAttributes->push_back(make_pair(NS_rtf::LN_SGC, pValue)); // paragraph style } else m_aStates.top().aParagraphAttributes->push_back(make_pair(NS_rtf::LN_ISTD, pIntValue)); @@ -2222,20 +2330,25 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) case RTF_VERN: // Ignore this for now, later the RTF writer version could be used to add hacks for older buggy writers. break; + case RTF_FTNSTART: + lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numStart, pIntValue); + break; + case RTF_AFTNSTART: + lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_endnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numStart, pIntValue); + break; default: #if OSL_DEBUG_LEVEL > 1 OSL_TRACE("%s: TODO handle value '%s'", OSL_THIS_FUNC, lcl_RtfToString(nKeyword)); #endif - bParsed = false; + aSkip.setParsed(false); break; } - skipDestination(bParsed); return 0; } int RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int nParam) { - bool bParsed = true; + RTFSkipDestination aSkip(*this); int nSprm = -1; RTFValue::Pointer_t pBoolValue(new RTFValue(!bParam || nParam != 0)); @@ -2265,7 +2378,6 @@ int RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int nParam { RTFValue::Pointer_t pValue(new RTFValue((!bParam || nParam != 0) ? nSprm : 0)); m_aStates.top().aCharacterSprms->push_back(make_pair(NS_sprm::LN_CKul, pValue)); - skipDestination(bParsed); return 0; } @@ -2283,7 +2395,6 @@ int RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int nParam { RTFValue::Pointer_t pValue(new RTFValue((!bParam || nParam != 0) ? nSprm : 0)); m_aStates.top().aCharacterSprms->push_back(make_pair(NS_sprm::LN_CKcd, pValue)); - skipDestination(bParsed); return 0; } @@ -2307,7 +2418,6 @@ int RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int nParam if (nSprm >= 0) { m_aStates.top().aCharacterSprms->push_back(make_pair(nSprm, pBoolValue)); - skipDestination(bParsed); return 0; } @@ -2328,26 +2438,12 @@ int RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int nParam #if OSL_DEBUG_LEVEL > 1 OSL_TRACE("%s: TODO handle toggle '%s'", OSL_THIS_FUNC, lcl_RtfToString(nKeyword)); #endif - bParsed = false; + aSkip.setParsed(false); break; } - skipDestination(bParsed); return 0; } -void RTFDocumentImpl::skipDestination(bool bParsed) -{ - if (m_bSkipUnknown) - { - if (!bParsed) - { - OSL_TRACE("%s: skipping destination", OSL_THIS_FUNC); - m_aStates.top().nDestinationState = DESTINATION_SKIP; - } - m_bSkipUnknown = false; - } -} - int RTFDocumentImpl::pushState() { //OSL_TRACE("%s before push: %d", OSL_THIS_FUNC, m_nGroup); @@ -2359,6 +2455,7 @@ int RTFDocumentImpl::pushState() else aState = m_aStates.top(); m_aStates.push(aState); + m_aStates.top().aDestinationText.setLength(0); m_nGroup++; @@ -2431,6 +2528,7 @@ int RTFDocumentImpl::popState() RTFSprms aSprms; RTFSprms aAttributes; + OUStringBuffer aDestinationText; bool bListEntryEnd = false; bool bListLevelEnd = false; bool bListOverrideEntryEnd = false; @@ -2438,6 +2536,7 @@ int RTFDocumentImpl::popState() RTFShape aShape; bool bPopShapeProperties = false; bool bPopPictureProperties = false; + bool bFaltEnd = false; if (m_aStates.top().nDestinationState == DESTINATION_FONTTABLE) { @@ -2514,7 +2613,7 @@ int RTFDocumentImpl::popState() } else if (m_aStates.top().nDestinationState == DESTINATION_LEVELTEXT) { - OUString aStr = m_aDestinationText.makeStringAndClear(); + OUString aStr = m_aStates.top().aDestinationText.makeStringAndClear(); // The first character is the length of the string (the rest should be ignored). sal_Int32 nLength(aStr.toChar()); @@ -2554,9 +2653,9 @@ int RTFDocumentImpl::popState() aShape = m_aStates.top().aShape; aAttributes = m_aStates.top().aCharacterAttributes; if (m_aStates.top().nDestinationState == DESTINATION_SHAPEPROPERTYNAME) - aShape.aProperties.push_back(make_pair(m_aDestinationText.makeStringAndClear(), OUString())); + aShape.aProperties.push_back(make_pair(m_aStates.top().aDestinationText.makeStringAndClear(), OUString())); else if (m_aStates.top().nDestinationState == DESTINATION_SHAPEPROPERTYVALUE && aShape.aProperties.size()) - aShape.aProperties.back().second = m_aDestinationText.makeStringAndClear(); + aShape.aProperties.back().second = m_aStates.top().aDestinationText.makeStringAndClear(); bPopShapeProperties = true; } else if (m_aStates.top().nDestinationState == DESTINATION_PICPROP @@ -2567,35 +2666,36 @@ int RTFDocumentImpl::popState() } else if (m_aStates.top().nDestinationState == DESTINATION_BOOKMARKSTART) { - OUString aStr = m_aDestinationText.makeStringAndClear(); + OUString aStr = m_aStates.top().aDestinationText.makeStringAndClear(); int nPos = m_aBookmarks.size(); m_aBookmarks[aStr] = nPos; Mapper().props(lcl_getBookmarkProperties(nPos, aStr)); } else if (m_aStates.top().nDestinationState == DESTINATION_BOOKMARKEND) - Mapper().props(lcl_getBookmarkProperties(m_aBookmarks[m_aDestinationText.makeStringAndClear()])); + Mapper().props(lcl_getBookmarkProperties(m_aBookmarks[m_aStates.top().aDestinationText.makeStringAndClear()])); else if (m_aStates.top().nDestinationState == DESTINATION_PICT) resolvePict(true); else if (m_aStates.top().nDestinationState == DESTINATION_SHAPEPROPERTYVALUEPICT) { bPopPictureProperties = true; aAttributes = m_aStates.top().aCharacterAttributes; + aDestinationText = m_aStates.top().aDestinationText; } else if (m_aStates.top().nDestinationState == DESTINATION_SHAPETEXT) m_pCurrentBuffer = 0; // Just disable buffering, don't empty it yet. else if (m_aStates.top().nDestinationState == DESTINATION_FORMFIELDNAME) { - RTFValue::Pointer_t pValue(new RTFValue(m_aDestinationText.makeStringAndClear())); + RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aDestinationText.makeStringAndClear())); m_aFormfieldSprms->push_back(make_pair(NS_ooxml::LN_CT_FFData_name, pValue)); } else if (m_aStates.top().nDestinationState == DESTINATION_FORMFIELDLIST) { - RTFValue::Pointer_t pValue(new RTFValue(m_aDestinationText.makeStringAndClear())); + RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aDestinationText.makeStringAndClear())); m_aFormfieldSprms->push_back(make_pair(NS_ooxml::LN_CT_FFDDList_listEntry, pValue)); } else if (m_aStates.top().nDestinationState == DESTINATION_DATAFIELD) { - OString aStr = OUStringToOString(m_aDestinationText.makeStringAndClear(), m_aStates.top().nCurrentEncoding); + OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(), m_aStates.top().nCurrentEncoding); // decode hex dump OStringBuffer aBuf; const char *str = aStr.getStr(); @@ -2644,9 +2744,9 @@ int RTFDocumentImpl::popState() else if (m_aStates.top().nDestinationState == DESTINATION_PRINTTIME && m_xDocumentProperties.is()) m_xDocumentProperties->setPrintDate(lcl_getDateTime(m_aStates)); else if (m_aStates.top().nDestinationState == DESTINATION_AUTHOR && m_xDocumentProperties.is()) - m_xDocumentProperties->setAuthor(m_aDestinationText.makeStringAndClear()); + m_xDocumentProperties->setAuthor(m_aStates.top().aDestinationText.makeStringAndClear()); else if (m_aStates.top().nDestinationState == DESTINATION_COMMENT && m_xDocumentProperties.is()) - m_xDocumentProperties->setGenerator(m_aDestinationText.makeStringAndClear()); + m_xDocumentProperties->setGenerator(m_aStates.top().aDestinationText.makeStringAndClear()); else if (m_aStates.top().nDestinationState == DESTINATION_OPERATOR || m_aStates.top().nDestinationState == DESTINATION_COMPANY) { @@ -2656,16 +2756,16 @@ int RTFDocumentImpl::popState() { uno::Reference<beans::XPropertyContainer> xUserDefinedProperties = m_xDocumentProperties->getUserDefinedProperties(); xUserDefinedProperties->addProperty(aName, beans::PropertyAttribute::REMOVEABLE, - uno::makeAny(m_aDestinationText.makeStringAndClear())); + uno::makeAny(m_aStates.top().aDestinationText.makeStringAndClear())); } } else if (m_aStates.top().nDestinationState == DESTINATION_OBJDATA) { - m_pObjectData = new SvMemoryStream(); + m_pObjectData.reset(new SvMemoryStream()); int b = 0, count = 2; // Feed the destination text to a stream. - OString aStr = OUStringToOString(m_aDestinationText.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US); + OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US); const char *str = aStr.getStr(); for (int i = 0; i < aStr.getLength(); ++i) { @@ -2704,7 +2804,7 @@ int RTFDocumentImpl::popState() *m_pObjectData >> nData; // NativeDataSize } - uno::Reference<io::XInputStream> xInputStream(new utl::OInputStreamWrapper(m_pObjectData)); + uno::Reference<io::XInputStream> xInputStream(new utl::OInputStreamWrapper(m_pObjectData.get())); RTFValue::Pointer_t pStreamValue(new RTFValue(xInputStream)); RTFSprms aOLEAttributes; @@ -2729,16 +2829,11 @@ int RTFDocumentImpl::popState() Mapper().endShape(); m_aObjectAttributes->clear(); m_aObjectSprms->clear(); - if (m_pObjectData) - { - delete m_pObjectData; - m_pObjectData = 0; - } m_bObject = false; } else if (m_aStates.top().nDestinationState == DESTINATION_ANNOTATIONDATE) { - OUString aStr(OStringToOUString(lcl_DTTM22OString(m_aDestinationText.makeStringAndClear().toInt32()), + OUString aStr(OStringToOUString(lcl_DTTM22OString(m_aStates.top().aDestinationText.makeStringAndClear().toInt32()), m_aStates.top().nCurrentEncoding)); RTFValue::Pointer_t pValue(new RTFValue(aStr)); RTFSprms aAnnAttributes; @@ -2747,7 +2842,15 @@ int RTFDocumentImpl::popState() Mapper().props(pProperties); } else if (m_aStates.top().nDestinationState == DESTINATION_ANNOTATIONAUTHOR) - m_aAuthor = m_aDestinationText.makeStringAndClear(); + m_aAuthor = m_aStates.top().aDestinationText.makeStringAndClear(); + else if (m_aStates.top().nDestinationState == DESTINATION_FALT) + { + OUString aStr(m_aStates.top().aDestinationText.makeStringAndClear()); + RTFValue::Pointer_t pValue(new RTFValue(aStr)); + m_aStates.top().aTableSprms->push_back(make_pair(NS_ooxml::LN_CT_Font_altName, pValue)); + aSprms = m_aStates.top().aTableSprms; + bFaltEnd = true; + } // See if we need to end a track change RTFValue::Pointer_t pTrackchange = m_aStates.top().aCharacterSprms.find(NS_ooxml::LN_trackchange); @@ -2798,8 +2901,13 @@ int RTFDocumentImpl::popState() m_aStates.top().aShape = aShape; m_aStates.top().aCharacterAttributes = aAttributes; } + else if (bFaltEnd) + m_aStates.top().aTableSprms = aSprms; if (bPopPictureProperties) + { m_aStates.top().aCharacterAttributes = aAttributes; + m_aStates.top().aDestinationText = aDestinationText; + } if (m_pCurrentBuffer == &m_aSuperBuffer) { if (!m_bHasFootnote) @@ -2816,7 +2924,7 @@ int RTFDocumentImpl::popState() return "RTFDocumentImpl"; } -com::sun::star::uno::Reference<com::sun::star::lang::XMultiServiceFactory> RTFDocumentImpl::getModelFactory() +uno::Reference<lang::XMultiServiceFactory> RTFDocumentImpl::getModelFactory() { return m_xModelFactory; } @@ -2838,8 +2946,8 @@ bool RTFDocumentImpl::isEmpty() void RTFDocumentImpl::setDestinationText(OUString& rString) { - m_aDestinationText.setLength(0); - m_aDestinationText.append(rString); + m_aStates.top().aDestinationText.setLength(0); + m_aStates.top().aDestinationText.append(rString); } void RTFDocumentImpl::replayShapetext() @@ -2847,6 +2955,16 @@ void RTFDocumentImpl::replayShapetext() replayBuffer(m_aShapetextBuffer); } +bool RTFDocumentImpl::getSkipUnknown() +{ + return m_bSkipUnknown; +} + +void RTFDocumentImpl::setSkipUnknown(bool bSkipUnknown) +{ + m_bSkipUnknown = bSkipUnknown; +} + RTFParserState::RTFParserState() : nInternalState(INTERNAL_NORMAL), nDestinationState(DESTINATION_NORMAL), diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx index dec202b7e4d0..463b6058ca80 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx @@ -111,7 +111,8 @@ namespace writerfilter { DESTINATION_OBJDATA, DESTINATION_RESULT, DESTINATION_ANNOTATIONDATE, - DESTINATION_ANNOTATIONAUTHOR + DESTINATION_ANNOTATIONAUTHOR, + DESTINATION_FALT }; enum RTFBorderState @@ -246,6 +247,9 @@ namespace writerfilter { int nDay; int nHour; int nMinute; + + /// Text from special destinations. + rtl::OUStringBuffer aDestinationText; }; class RTFTokenizer; @@ -257,10 +261,10 @@ namespace writerfilter { { public: typedef ::boost::shared_ptr<RTFDocumentImpl> Pointer_t; - RTFDocumentImpl(com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const& xContext, - com::sun::star::uno::Reference<com::sun::star::io::XInputStream> const& xInputStream, - com::sun::star::uno::Reference<com::sun::star::lang::XComponent> const& xDstDoc, - com::sun::star::uno::Reference<com::sun::star::frame::XFrame> const& xFrame); + RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& xContext, + uno::Reference<io::XInputStream> const& xInputStream, + uno::Reference<lang::XComponent> const& xDstDoc, + uno::Reference<frame::XFrame> const& xFrame); virtual ~RTFDocumentImpl(); virtual void resolve(Stream & rHandler); virtual std::string getType() const; @@ -269,19 +273,21 @@ namespace writerfilter { void setSubstream(bool bIsSubtream); void setAuthor(rtl::OUString& rAuthor); bool isSubstream(); + void finishSubstream(); void setIgnoreFirst(rtl::OUString& rIgnoreFirst); void seek(sal_uInt32 nPos); - com::sun::star::uno::Reference<com::sun::star::lang::XMultiServiceFactory> getModelFactory(); + uno::Reference<lang::XMultiServiceFactory> getModelFactory(); RTFParserState& getState(); /// If the stack of states is empty. bool isEmpty(); int getGroup(); void setDestinationText(rtl::OUString& rString); - void skipDestination(bool bParsed); /// Resolve a picture: If not inline, then anchored. int resolvePict(bool bInline); void runBreak(); void replayShapetext(); + bool getSkipUnknown(); + void setSkipUnknown(bool bSkipUnknown); // These callbacks are invoked by the tokenizer. int resolveChars(char ch); @@ -312,16 +318,16 @@ namespace writerfilter { void sectBreak(bool bFinal); void replayBuffer(RTFBuffer_t& rBuffer); - com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const& m_xContext; - com::sun::star::uno::Reference<com::sun::star::io::XInputStream> const& m_xInputStream; - com::sun::star::uno::Reference<com::sun::star::lang::XComponent> const& m_xDstDoc; - com::sun::star::uno::Reference<com::sun::star::frame::XFrame> const& m_xFrame; - com::sun::star::uno::Reference<com::sun::star::lang::XMultiServiceFactory> m_xModelFactory; - com::sun::star::uno::Reference<com::sun::star::document::XDocumentProperties> m_xDocumentProperties; + uno::Reference<uno::XComponentContext> const& m_xContext; + uno::Reference<io::XInputStream> const& m_xInputStream; + uno::Reference<lang::XComponent> const& m_xDstDoc; + uno::Reference<frame::XFrame> const& m_xFrame; + uno::Reference<lang::XMultiServiceFactory> m_xModelFactory; + uno::Reference<document::XDocumentProperties> m_xDocumentProperties; SvStream* m_pInStream; Stream* m_pMapperStream; - RTFSdrImport* m_pSdrImport; - RTFTokenizer* m_pTokenizer; + boost::shared_ptr<RTFSdrImport> m_pSdrImport; + boost::shared_ptr<RTFTokenizer> m_pTokenizer; /// Same as m_aStates.size(), except that this can be negative for invalid input. int m_nGroup; std::stack<RTFParserState> m_aStates; @@ -337,6 +343,8 @@ namespace writerfilter { bool m_bFirstRow; /// If paragraph properties should be emitted on next run. bool m_bNeedPap; + /// If we need to emit a CR at the end of substream. + bool m_bNeedCr; /// The list table and list override table combined. RTFSprms m_aListTableSprms; /// The settings table. @@ -367,8 +375,6 @@ namespace writerfilter { std::map<int, rtl::OUString> m_aAuthors; /// Annotation author of the next annotation. rtl::OUString m_aAuthor; - /// Text from special destinations. - rtl::OUStringBuffer m_aDestinationText; RTFSprms m_aFormfieldSprms; RTFSprms m_aFormfieldAttributes; @@ -378,8 +384,8 @@ namespace writerfilter { RTFSprms m_aObjectAttributes; /// If we are in an object group. bool m_bObject; - /// Contents of the objdata group, stored here so we can delete it when we leave the object group. - SvStream* m_pObjectData; + /// Contents of the objdata group. + boost::shared_ptr<SvStream> m_pObjectData; RTFReferenceTable::Entries_t m_aFontTableEntries; int m_nCurrentFontIndex; diff --git a/writerfilter/source/rtftok/rtfsdrimport.cxx b/writerfilter/source/rtftok/rtfsdrimport.cxx index f83280dedadc..212eecda84da 100644 --- a/writerfilter/source/rtftok/rtfsdrimport.cxx +++ b/writerfilter/source/rtftok/rtfsdrimport.cxx @@ -111,7 +111,8 @@ void RTFSdrImport::resolve(RTFShape& rShape) // Defaults aAny <<= (sal_uInt32)0xffffff; // White in Word, kind of blue in Writer. - xPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("FillColor")), aAny); + if (xPropertySet.is()) + xPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("FillColor")), aAny); } else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("wzName"))) { @@ -128,21 +129,21 @@ void RTFSdrImport::resolve(RTFShape& rShape) m_rImport.setDestinationText(i->second); bPib = true; } - else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("fillColor"))) + else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("fillColor")) && xPropertySet.is()) { aAny <<= lcl_BGRToRGB(i->second.toInt32()); xPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("FillColor")), aAny); } else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("fillBackColor"))) ; // Ignore: complementer of fillColor - else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("lineColor"))) + else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("lineColor")) && xPropertySet.is()) { aAny <<= lcl_BGRToRGB(i->second.toInt32()); xPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("LineColor")), aAny); } else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("lineBackColor"))) ; // Ignore: complementer of lineColor - else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("txflTextFlow"))) + else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("txflTextFlow")) && xPropertySet.is()) { if (i->second.toInt32() == 1) { @@ -150,7 +151,7 @@ void RTFSdrImport::resolve(RTFShape& rShape) xPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("TextWritingMode")), aAny); } } - else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("fLine"))) + else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("fLine")) && xPropertySet.is()) { if (i->second.toInt32() == 0) { @@ -273,7 +274,7 @@ void RTFSdrImport::resolve(RTFShape& rShape) OUStringToOString( i->second, RTL_TEXTENCODING_UTF8 ).getStr()); } - if (nType == 75) // picture frame + if (nType == 75 || nType == 202) // picture frame or text box { if (bPib) m_rImport.resolvePict(false); @@ -282,7 +283,7 @@ void RTFSdrImport::resolve(RTFShape& rShape) if (m_xDrawPage.is()) m_xDrawPage->add(xShape); - if (bCustom) + if (bCustom && xShape.is()) { uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(xShape, uno::UNO_QUERY); xDefaulter->createCustomShapeDefaults(OUString::valueOf(sal_Int32(nType))); @@ -312,7 +313,7 @@ void RTFSdrImport::resolve(RTFShape& rShape) beans::PropertyValue* pGeomValues = aGeomPropSeq.getArray(); for (std::vector<beans::PropertyValue>::iterator i = aGeomPropVec.begin(); i != aGeomPropVec.end(); ++i) *pGeomValues++ = *i; - if (aGeomPropSeq.getLength()) + if (aGeomPropSeq.getLength() && xPropertySet.is()) xPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CustomShapeGeometry")), uno::Any(aGeomPropSeq)); // Set position and size diff --git a/writerfilter/source/rtftok/rtfsdrimport.hxx b/writerfilter/source/rtftok/rtfsdrimport.hxx index 5bc981cc68b8..a0092a2e9899 100644 --- a/writerfilter/source/rtftok/rtfsdrimport.hxx +++ b/writerfilter/source/rtftok/rtfsdrimport.hxx @@ -38,18 +38,15 @@ namespace writerfilter { class RTFSdrImport { public: - RTFSdrImport(RTFDocumentImpl& rImport, - com::sun::star::uno::Reference<com::sun::star::lang::XComponent> const& xDstDoc); + RTFSdrImport(RTFDocumentImpl& rImport, uno::Reference<lang::XComponent> const& xDstDoc); virtual ~RTFSdrImport(); void resolve(RTFShape& rShape); private: - void createShape(rtl::OUString aService, - com::sun::star::uno::Reference<drawing::XShape>& xShape, - com::sun::star::uno::Reference<beans::XPropertySet>& xPropertySet); + void createShape(rtl::OUString aService, uno::Reference<drawing::XShape>& xShape, uno::Reference<beans::XPropertySet>& xPropertySet); RTFDocumentImpl& m_rImport; - com::sun::star::uno::Reference<com::sun::star::drawing::XDrawPage> m_xDrawPage; + uno::Reference<drawing::XDrawPage> m_xDrawPage; }; } // namespace rtftok } // namespace writerfilter diff --git a/writerfilter/source/rtftok/rtfskipdestination.cxx b/writerfilter/source/rtftok/rtfskipdestination.cxx new file mode 100644 index 000000000000..9ad1d1d5e14f --- /dev/null +++ b/writerfilter/source/rtftok/rtfskipdestination.cxx @@ -0,0 +1,66 @@ +/* + * Version: MPL 1.1 / GPLv3+ / LGPLv3+ + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developer of the Original Code is + * Miklos Vajna <vmiklos@frugalware.org> + * Portions created by the Initial Developer are Copyright (C) 2011 the + * Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 3 or later (the "GPLv3+"), or + * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), + * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable + * instead of those above. + */ + +#include <rtfskipdestination.hxx> + +namespace writerfilter { +namespace rtftok { + +RTFSkipDestination::RTFSkipDestination(RTFDocumentImpl& rImport) + : m_rImport(rImport), + m_bParsed(true), + m_bReset(true) +{ +} + +RTFSkipDestination::~RTFSkipDestination() +{ + if (m_rImport.getSkipUnknown() && m_bReset) + { + if (!m_bParsed) + { + OSL_TRACE("%s: skipping destination", OSL_THIS_FUNC); + m_rImport.getState().nDestinationState = DESTINATION_SKIP; + } + m_rImport.setSkipUnknown(false); + } +} + +void RTFSkipDestination::setParsed(bool bParsed) +{ + m_bParsed = bParsed; +} + +void RTFSkipDestination::setReset(bool bReset) +{ + m_bReset = bReset; +} + +} // namespace rtftok +} // namespace writerfilter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/rtftok/rtfskipdestination.hxx b/writerfilter/source/rtftok/rtfskipdestination.hxx new file mode 100644 index 000000000000..31f016478032 --- /dev/null +++ b/writerfilter/source/rtftok/rtfskipdestination.hxx @@ -0,0 +1,56 @@ +/* + * Version: MPL 1.1 / GPLv3+ / LGPLv3+ + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developer of the Original Code is + * Miklos Vajna <vmiklos@frugalware.org> + * Portions created by the Initial Developer are Copyright (C) 2011 the + * Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 3 or later (the "GPLv3+"), or + * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), + * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable + * instead of those above. + */ + +#ifndef _RTFSKIPDESTINATION_HXX_ +#define _RTFSKIPDESTINATION_HXX_ + +#include <rtfdocumentimpl.hxx> + +class SvStream; + +namespace writerfilter { + namespace rtftok { + /// Skips a destination after a not parsed control word if it was prefixed with \* + class RTFSkipDestination + { + public: + RTFSkipDestination(RTFDocumentImpl& rImport); + virtual ~RTFSkipDestination(); + void setParsed(bool bParsed); + void setReset(bool bReset); + private: + RTFDocumentImpl& m_rImport; + bool m_bParsed; + /// If false, the destructor is a noop, required by the \* symbol itself. + bool m_bReset; + }; + } // namespace rtftok +} // namespace writerfilter + +#endif // _RTFSKIPDESTINATION_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/rtftok/rtftokenizer.cxx b/writerfilter/source/rtftok/rtftokenizer.cxx index 847dd24932cf..7ddf0fcab83e 100644 --- a/writerfilter/source/rtftok/rtftokenizer.cxx +++ b/writerfilter/source/rtftok/rtftokenizer.cxx @@ -28,6 +28,7 @@ #include <tools/stream.hxx> #include <rtftokenizer.hxx> +#include <rtfskipdestination.hxx> using rtl::OString; using rtl::OStringBuffer; @@ -82,7 +83,10 @@ int RTFTokenizer::resolveParse() if ((ret = m_rImport.popState())) return ret; if (m_rImport.isSubstream() && m_rImport.getGroup() == 0) + { + m_rImport.finishSubstream(); return 0; + } break; case '\\': if ((ret = resolveKeyword())) @@ -227,7 +231,8 @@ int RTFTokenizer::dispatchKeyword(OString& rKeyword, bool bParam, int nParam) if (i == nRTFControlWords) { OSL_TRACE("%s: unknown keyword '\\%s'", OSL_THIS_FUNC, rKeyword.getStr()); - m_rImport.skipDestination(false); + RTFSkipDestination aSkip(m_rImport); + aSkip.setParsed(false); return 0; } diff --git a/writerfilter/source/rtftok/rtfvalue.cxx b/writerfilter/source/rtftok/rtfvalue.cxx index 961f6d758402..0469adc51413 100644 --- a/writerfilter/source/rtftok/rtfvalue.cxx +++ b/writerfilter/source/rtftok/rtfvalue.cxx @@ -45,8 +45,8 @@ RTFValue::RTFValue(int nValue, rtl::OUString sValue, RTFSprms rAttributes, m_rStream(rStream), m_bForceString(false) { - m_pAttributes = new RTFSprms(rAttributes); - m_pSprms = new RTFSprms(rSprms); + m_pAttributes.reset(new RTFSprms(rAttributes)); + m_pSprms.reset(new RTFSprms(rSprms)); } RTFValue::RTFValue(int nValue) @@ -56,8 +56,8 @@ RTFValue::RTFValue(int nValue) m_rStream(), m_bForceString(false) { - m_pAttributes = new RTFSprms(); - m_pSprms = new RTFSprms(); + m_pAttributes.reset(new RTFSprms()); + m_pSprms.reset(new RTFSprms()); } RTFValue::RTFValue(OUString sValue, bool bForce) @@ -67,8 +67,8 @@ RTFValue::RTFValue(OUString sValue, bool bForce) m_rStream(), m_bForceString(bForce) { - m_pAttributes = new RTFSprms(); - m_pSprms = new RTFSprms(); + m_pAttributes.reset(new RTFSprms()); + m_pSprms.reset(new RTFSprms()); } RTFValue::RTFValue(RTFSprms rAttributes) @@ -78,8 +78,8 @@ RTFValue::RTFValue(RTFSprms rAttributes) m_rStream(), m_bForceString(false) { - m_pAttributes = new RTFSprms(rAttributes); - m_pSprms = new RTFSprms(); + m_pAttributes.reset(new RTFSprms(rAttributes)); + m_pSprms.reset(new RTFSprms()); } RTFValue::RTFValue(RTFSprms rAttributes, RTFSprms rSprms) @@ -89,8 +89,8 @@ RTFValue::RTFValue(RTFSprms rAttributes, RTFSprms rSprms) m_rStream(), m_bForceString(false) { - m_pAttributes = new RTFSprms(rAttributes); - m_pSprms = new RTFSprms(rSprms); + m_pAttributes.reset(new RTFSprms(rAttributes)); + m_pSprms.reset(new RTFSprms(rSprms)); } RTFValue::RTFValue(uno::Reference<drawing::XShape> rShape) @@ -100,8 +100,8 @@ RTFValue::RTFValue(uno::Reference<drawing::XShape> rShape) m_rStream(), m_bForceString(false) { - m_pAttributes = new RTFSprms(); - m_pSprms = new RTFSprms(); + m_pAttributes.reset(new RTFSprms()); + m_pSprms.reset(new RTFSprms()); } RTFValue::RTFValue(uno::Reference<io::XInputStream> rStream) @@ -111,14 +111,12 @@ RTFValue::RTFValue(uno::Reference<io::XInputStream> rStream) m_rStream(rStream), m_bForceString(false) { - m_pAttributes = new RTFSprms(); - m_pSprms = new RTFSprms(); + m_pAttributes.reset(new RTFSprms()); + m_pSprms.reset(new RTFSprms()); } RTFValue::~RTFValue() { - delete m_pAttributes; - delete m_pSprms; } int RTFValue::getInt() const diff --git a/writerfilter/source/rtftok/rtfvalue.hxx b/writerfilter/source/rtftok/rtfvalue.hxx index db9005f02832..b83340e4c7a3 100644 --- a/writerfilter/source/rtftok/rtfvalue.hxx +++ b/writerfilter/source/rtftok/rtfvalue.hxx @@ -42,7 +42,7 @@ namespace writerfilter { : public Value { public: - typedef ::boost::shared_ptr<RTFValue> Pointer_t; + typedef boost::shared_ptr<RTFValue> Pointer_t; RTFValue(int nValue, rtl::OUString sValue, RTFSprms rAttributes, RTFSprms rSprms, uno::Reference<drawing::XShape> rShape, uno::Reference<io::XInputStream> rStream); RTFValue(int nValue); @@ -66,8 +66,8 @@ namespace writerfilter { private: int m_nValue; rtl::OUString m_sValue; - RTFSprms* m_pAttributes; - RTFSprms* m_pSprms; + boost::shared_ptr<RTFSprms> m_pAttributes; + boost::shared_ptr<RTFSprms> m_pSprms; uno::Reference<drawing::XShape> m_rShape; uno::Reference<io::XInputStream> m_rStream; bool m_bForceString; |