sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 4 - sw/qa/extras/ooxmlimport/data/bnc773061.docx |binary sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 17 +++++ sw/qa/extras/rtfimport/rtfimport.cxx | 2 sw/qa/extras/swmodeltestbase.hxx | 8 +- sw/source/filter/ww8/docxattributeoutput.cxx | 12 +++ writerfilter/inc/dmapper/DomainMapper.hxx | 5 + writerfilter/source/dmapper/DomainMapper.cxx | 68 +++++++++++++++++----- writerfilter/source/dmapper/DomainMapper_Impl.cxx | 22 +++++++ writerfilter/source/dmapper/DomainMapper_Impl.hxx | 14 ++++ 10 files changed, 131 insertions(+), 21 deletions(-)
New commits: commit 04628d9dc2f283fea6a8203de8b6812dfbc92014 Author: LuboÅ¡ LuÅák <l.lu...@suse.cz> Date: Tue Aug 7 12:46:34 2012 +0200 testcase for bnc#773061 Change-Id: Ibf1ad67a1776dbe966de335be93a295ba7bebe76 diff --git a/sw/qa/extras/ooxmlimport/data/bnc773061.docx b/sw/qa/extras/ooxmlimport/data/bnc773061.docx new file mode 100644 index 0000000..6a7baf6 Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/bnc773061.docx differ diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index f8cd74e..ba8f903 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -77,6 +77,7 @@ public: void testN766487(); void testN693238(); void testNumbering1(); + void testBnc773061(); CPPUNIT_TEST_SUITE(Test); #if !defined(MACOSX) && !defined(WNT) @@ -102,6 +103,7 @@ public: CPPUNIT_TEST(testN766487); CPPUNIT_TEST(testN693238); CPPUNIT_TEST(testNumbering1); + CPPUNIT_TEST(testBnc773061); #endif CPPUNIT_TEST_SUITE_END(); @@ -689,6 +691,21 @@ note that the indexes may get off as the implementation evolves, C++ code seache CPPUNIT_ASSERT_EQUAL( style::NumberingType::ARABIC, numberingType ); } +void Test::testBnc773061() +{ + load( "bnc773061.docx" ); + uno::Reference< text::XTextRange > paragraph = getParagraph( 1 ); + uno::Reference< text::XTextRange > normal = getRun( paragraph, 1, "Normal " ); + uno::Reference< text::XTextRange > raised = getRun( paragraph, 2, "Raised" ); + uno::Reference< text::XTextRange > lowered = getRun( paragraph, 4, "Lowered" ); + CPPUNIT_ASSERT_EQUAL( sal_Int32( 0 ), getProperty< sal_Int32 >( normal, "CharEscapement" )); + CPPUNIT_ASSERT_EQUAL( sal_Int32( 50 ), getProperty< sal_Int32 >( raised, "CharEscapement" )); + CPPUNIT_ASSERT_EQUAL( sal_Int32( -25 ), getProperty< sal_Int32 >( lowered, "CharEscapement" )); + CPPUNIT_ASSERT_EQUAL( sal_Int32( 100 ), getProperty< sal_Int32 >( normal, "CharEscapementHeight" )); + CPPUNIT_ASSERT_EQUAL( sal_Int32( 100 ), getProperty< sal_Int32 >( raised, "CharEscapementHeight" )); + CPPUNIT_ASSERT_EQUAL( sal_Int32( 100 ), getProperty< sal_Int32 >( lowered, "CharEscapementHeight" )); +} + CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_PLUGIN_IMPLEMENT(); commit 5b16f3e59afc46bea8385d236044bc4af15740e6 Author: LuboÅ¡ LuÅák <l.lu...@suse.cz> Date: Tue Aug 7 12:46:04 2012 +0200 make it possible to verify contents of a text run too Change-Id: I07e6b53445fe8da6cccaadeb9bbe94c180cd6d8c diff --git a/sw/qa/extras/swmodeltestbase.hxx b/sw/qa/extras/swmodeltestbase.hxx index b0ec460..9210fa8 100644 --- a/sw/qa/extras/swmodeltestbase.hxx +++ b/sw/qa/extras/swmodeltestbase.hxx @@ -163,7 +163,7 @@ protected: } // Get paragraph (counted from 1), optionally check it contains the given text. - uno::Reference< text::XTextRange > getParagraph( int number, rtl::OUString content = OUString() ) const + uno::Reference< text::XTextRange > getParagraph( int number, OUString content = OUString() ) const { uno::Reference<text::XTextDocument> textDocument(mxComponent, uno::UNO_QUERY); uno::Reference<container::XEnumerationAccess> paraEnumAccess(textDocument->getText(), uno::UNO_QUERY); @@ -178,14 +178,16 @@ protected: return paragraph; } - /// Get run (counted from 1) of a paragraph. - uno::Reference<text::XTextRange> getRun(uno::Reference<text::XTextRange> xParagraph, int number) const + /// Get run (counted from 1) of a paragraph, optionally check it contains the given text. + uno::Reference<text::XTextRange> getRun(uno::Reference<text::XTextRange> xParagraph, int number, OUString content = OUString()) const { uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParagraph, uno::UNO_QUERY); uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration(); for (int i = 1; i < number; ++i) xRunEnum->nextElement(); uno::Reference<text::XTextRange> xRun(xRunEnum->nextElement(), uno::UNO_QUERY); + if( !content.isEmpty()) + CPPUNIT_ASSERT_EQUAL( content, xRun->getString()); return xRun; } commit fc41a73a67a2bd30006a49d061d870533d49c0e8 Author: LuboÅ¡ LuÅák <l.lu...@suse.cz> Date: Tue Aug 7 12:28:45 2012 +0200 fix test after the recent w:position fix (i.e. bnc#773061) The value 58 was hardcoded in w:position handling before and so was reused for the test, but now use the value that is (hopefully) correct. Change-Id: I1191fce9859d688a60f1b3fbdb0e704b130c1670 diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx index b185635..0f5e704 100644 --- a/sw/qa/extras/rtfimport/rtfimport.cxx +++ b/sw/qa/extras/rtfimport/rtfimport.cxx @@ -380,7 +380,7 @@ void Test::testFdo43965() uno::Reference<beans::XPropertySet> xPropertySet(xRangeEnum->nextElement(), uno::UNO_QUERY); sal_Int32 nValue; xPropertySet->getPropertyValue("CharEscapement") >>= nValue; - CPPUNIT_ASSERT_EQUAL(sal_Int32(58), nValue); + CPPUNIT_ASSERT_EQUAL(sal_Int32(36), nValue); xPropertySet->getPropertyValue("CharEscapementHeight") >>= nValue; CPPUNIT_ASSERT_EQUAL(sal_Int32(100), nValue); commit d7fb4c8cd63eb5cf7386b801acf09afe44d68f3f Author: LuboÅ¡ LuÅák <l.lu...@suse.cz> Date: Tue Aug 7 12:15:57 2012 +0200 fix test after recent <w:tabs> export change Now that empty <w:tabs> is not written out, the style's tab stops will be the default. Change-Id: I2a876ba544a58fbb82218ec9fd4d1356ea9ac12c diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index 020bffd..6615343 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -97,7 +97,9 @@ void Test::defaultTabStopNotInStyles() uno::Reference< beans::XPropertySet > properties( paragraphStyles->getByName( "Standard" ), uno::UNO_QUERY ); uno::Sequence< style::TabStop > stops = getProperty< uno::Sequence< style::TabStop > >( paragraphStyles->getByName( "Standard" ), "ParaTabStops" ); - CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(0), stops.getLength()); +// There actually be be one tab stop, but it will be the default. + CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(1), stops.getLength()); + CPPUNIT_ASSERT_EQUAL( style::TabAlign_DEFAULT, stops[ 0 ].Alignment ); } void Test::testFdo38244() commit e70df84352d3670508a4666c97df44f82c1ce934 Author: LuboÅ¡ LuÅák <l.lu...@suse.cz> Date: Tue Aug 7 11:37:19 2012 +0200 try somewhat harder to read w:position (bnc#773061) SvxEscapementItem stores the vertical offset as percentage, so it depends on the font size. Change-Id: I1b2d5b2c230b6243a6c1a4580147c4e0c4ae94cc diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 686c10f..c4c03fa 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -2109,26 +2109,13 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext, SprmType if (xCharStyle.is()) xCharStyle->setPropertyValue(rPropNameSupplier.GetName(PROP_CHAR_HEIGHT), aVal); } + m_pImpl->deferCharacterProperty( nSprmId, uno::makeAny( nIntValue )); } break; case NS_sprm::LN_CHpsInc: break; // sprmCHpsInc case NS_sprm::LN_CHpsPos: - { - // FIXME: ww8 filter in ww8par6.cxx has a Read_SubSuperProp function - // that counts the escapement from this value and font size. So it will be - // on our TODO list - sal_Int16 nEscapement = 0; - sal_Int8 nProp = 100; - if (nIntValue < 0) - nEscapement = -58; - else if (nIntValue > 0) - nEscapement = 58; - else /* (nIntValue == 0) */ - nProp = 0; - rContext->Insert(PROP_CHAR_ESCAPEMENT, true, uno::makeAny( nEscapement ) ); - rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, true, uno::makeAny( nProp ) ); - } + m_pImpl->deferCharacterProperty( nSprmId, uno::makeAny( nIntValue )); break; // sprmCHpsPos case NS_sprm::LN_CHpsPosAdj: break; // sprmCHpsPosAdj @@ -3239,6 +3226,8 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext, SprmType void DomainMapper::processDeferredCharacterProperties( const std::map< sal_Int32, uno::Any >& deferredCharacterProperties ) { + assert( m_pImpl->GetTopContextType() == CONTEXT_CHARACTER ); + PropertyMapPtr rContext = m_pImpl->GetTopContext(); for( std::map< sal_Int32, uno::Any >::const_iterator it = deferredCharacterProperties.begin(); it != deferredCharacterProperties.end(); ++it ) @@ -3250,6 +3239,35 @@ void DomainMapper::processDeferredCharacterProperties( const std::map< sal_Int32 it->second >>= sStringValue; switch( Id ) { + case NS_sprm::LN_CHps: + case NS_sprm::LN_CHpsBi: + break; // only for use by other properties, ignore here + case NS_sprm::LN_CHpsPos: + { + sal_Int16 nEscapement = 0; + sal_Int8 nProp = 100; + if(nIntValue == 0) + nProp = 0; + else + { + std::map< sal_Int32, uno::Any >::const_iterator font = deferredCharacterProperties.find( NS_sprm::LN_CHps ); + if( font != deferredCharacterProperties.end()) + { + double fontSize = 0; + font->second >>= fontSize; + nEscapement = nIntValue * 100 / fontSize; + } + else + { // TODO: Find out the font size. The 58/-58 values were here previous, but I have + // no idea what they are (they are probably some random guess that did fit whatever + // specific case somebody was trying to fix). + nEscapement = ( nIntValue > 0 ) ? 58: -58; + } + } + rContext->Insert(PROP_CHAR_ESCAPEMENT, true, uno::makeAny( nEscapement ) ); + rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, true, uno::makeAny( nProp ) ); + } + break; // sprmCHpsPos default: SAL_WARN( "writerfilter", "Unhandled property in processDeferredCharacterProperty()" ); break; commit 5c20cc0202170508176da577662fb6daead312b0 Author: LuboÅ¡ LuÅák <l.lu...@suse.cz> Date: Mon Aug 6 17:55:07 2012 +0200 support for deferred property processing in writerfilter There currently does not seem to be any sane way to process an attribute or sprm that depends on another one that may not possibly be there yet (e.g. in e7ab4bb6b0e83f01148ffff41e8c5eaa0c5ba0a4, or w:position which for Svx internal reasons depends on fontsize and thus w:sz). So make it possible to defer such properties and process them only before they are actually used, instead of trying to get them out of PropertyMap, possibly in more places and possibly having to undo the changes that have been done to them already. Change-Id: I1630057ecdf46443647ec1dd5253983ae15a083f diff --git a/writerfilter/inc/dmapper/DomainMapper.hxx b/writerfilter/inc/dmapper/DomainMapper.hxx index c22eebe..4dbbe87 100644 --- a/writerfilter/inc/dmapper/DomainMapper.hxx +++ b/writerfilter/inc/dmapper/DomainMapper.hxx @@ -109,6 +109,11 @@ public: GraphicZOrderHelper* graphicZOrderHelper(); bool IsInHeaderFooter() const; + /** + @see DomainMapper_Impl::processDeferredCharacterProperties() + */ + void processDeferredCharacterProperties( + const std::map< sal_Int32, com::sun::star::uno::Any >& deferredCharacterProperties ); private: // Stream diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 4aa843c..686c10f 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -3237,6 +3237,26 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext, SprmType } +void DomainMapper::processDeferredCharacterProperties( const std::map< sal_Int32, uno::Any >& deferredCharacterProperties ) +{ + for( std::map< sal_Int32, uno::Any >::const_iterator it = deferredCharacterProperties.begin(); + it != deferredCharacterProperties.end(); + ++it ) + { + sal_Int32 Id = it->first; + sal_Int32 nIntValue = 0; + OUString sStringValue; + it->second >>= nIntValue; + it->second >>= sStringValue; + switch( Id ) + { + default: + SAL_WARN( "writerfilter", "Unhandled property in processDeferredCharacterProperty()" ); + break; + } + } +} + void DomainMapper::lcl_entry(int /*pos*/, writerfilter::Reference<Properties>::Pointer_t ref) { diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 164a2d4..8bc7926 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -384,7 +384,12 @@ void DomainMapper_Impl::PopProperties(ContextType eId) m_pLastSectionContext = m_aPropertyStacks[eId].top( ); } else if (eId == CONTEXT_CHARACTER) + { m_pLastCharacterContext = m_aPropertyStacks[eId].top(); + // Sadly an assert about deferredCharacterProperties being empty is not possible + // here, becase appendTextPortion() may not be called for every character section. + deferredCharacterProperties.clear(); + } m_aPropertyStacks[eId].pop(); m_aContextStack.pop(); @@ -1107,6 +1112,8 @@ void DomainMapper_Impl::appendTextPortion( const OUString& rString, PropertyMapP { if (m_aTextAppendStack.empty()) return; + if( pPropertyMap == m_pTopContext && !deferredCharacterProperties.empty()) + processDeferredCharacterProperties(); uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; if(xTextAppend.is() && ! getTableManager( ).isIgnore()) { @@ -3725,6 +3732,21 @@ SectionPropertyMap * DomainMapper_Impl::GetSectionContext() return pSectionContext; } +void DomainMapper_Impl::deferCharacterProperty( sal_Int32 id, com::sun::star::uno::Any value ) +{ + deferredCharacterProperties[ id ] = value; +} + +void DomainMapper_Impl::processDeferredCharacterProperties() +{ + // ACtually process in DomainMapper, so that it's the same source file like normal processing. + if( !deferredCharacterProperties.empty()) + { + m_rDMapper.processDeferredCharacterProperties( deferredCharacterProperties ); + deferredCharacterProperties.clear(); + } +} + }} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index 2622cb7..abe5ef4 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -369,6 +369,8 @@ private: throw(::com::sun::star::uno::Exception); ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > GetDocumentSettings(); + std::map< sal_Int32, com::sun::star::uno::Any > deferredCharacterProperties; + public: DomainMapper_Impl( DomainMapper& rDMapper, @@ -629,6 +631,18 @@ public: SectionPropertyMap * GetSectionContext(); /// If the current paragraph has a numbering style associated, this method returns its character style com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> GetCurrentNumberingCharStyle(); + + /** + Used for attributes/sprms which cannot be evaluated immediatelly (e.g. they depend + on another one that comes in the same CONTEXT_CHARACTER). The property will be processed + again in DomainMapper::processDeferredCharacterProperties(). + */ + void deferCharacterProperty( sal_Int32 id, com::sun::star::uno::Any value ); + /** + Processes properties deferred using deferCharacterProperty(). To be called whenever the top + CONTEXT_CHARACTER is going to be used (e.g. by appendText()). + */ + void processDeferredCharacterProperties(); }; } //namespace dmapper } //namespace writerfilter commit 2f8f63f15a5a93781e4feceddeee18df74dc326a Author: LuboÅ¡ LuÅák <l.lu...@suse.cz> Date: Mon Aug 6 11:43:44 2012 +0200 don't write out empty <w:tabs>, not allowed by the .docx spec Change-Id: I30a24da0e6a568ed57d936fe769d47ea8465096d diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 3cb9d85..8a93e1d 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -3752,9 +3752,19 @@ void DocxAttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStop ) const SfxPoolItem* pLR = m_rExport.HasItem( RES_LR_SPACE ); long nCurrentLeft = pLR ? ((const SvxLRSpaceItem*)pLR)->GetTxtLeft() : 0; + sal_uInt16 nCount = rTabStop.Count(); + + // <w:tabs> must contain at least one <w:tab>, so don't write it empty + if( nCount == 0 ) + return; + if( nCount == 1 && rTabStop[ 0 ].GetAdjustment() == SVX_TAB_ADJUST_DEFAULT ) + { + GetExport().setDefaultTabStop( rTabStop[ 0 ].GetTabPos()); + return; + } + m_pSerializer->startElementNS( XML_w, XML_tabs, FSEND ); - sal_uInt16 nCount = rTabStop.Count(); for (sal_uInt16 i = 0; i < nCount; i++ ) { if( rTabStop[i].GetAdjustment() != SVX_TAB_ADJUST_DEFAULT )
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits