sw/CppunitTest_sw_ooxmlimport.mk | 1 sw/qa/extras/ooxmlimport/data/bnc821804.docx |binary sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 111 ++++++++++++++++++++++ sw/source/core/unocore/unoredline.cxx | 1 sw/source/uibase/misc/redlndlg.cxx | 2 sw/source/uibase/shells/textfld.cxx | 1 writerfilter/source/dmapper/DomainMapper.cxx | 37 +++---- writerfilter/source/dmapper/DomainMapper_Impl.cxx | 108 +++++++++++---------- writerfilter/source/dmapper/DomainMapper_Impl.hxx | 25 +--- writerfilter/source/dmapper/PropertyMap.hxx | 19 +++ writerfilter/source/ooxml/model.xml | 10 - 11 files changed, 223 insertions(+), 92 deletions(-)
New commits: commit fd26de3b4a4e8be165f7627cb22029841ba4ab31 Author: LuboÅ¡ LuÅák <l.lu...@collabora.com> Date: Fri Oct 3 13:22:18 2014 +0200 docx redline import test (bnc#821804) Change-Id: I09749037deb44c0cd74b28af226dd4b3e34ee0d1 diff --git a/sw/CppunitTest_sw_ooxmlimport.mk b/sw/CppunitTest_sw_ooxmlimport.mk index 682b31c..5d21e9e 100644 --- a/sw/CppunitTest_sw_ooxmlimport.mk +++ b/sw/CppunitTest_sw_ooxmlimport.mk @@ -25,6 +25,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sw_ooxmlimport, \ unotest \ utl \ sw \ + tl \ vcl \ $(gb_UWINAPI) \ )) diff --git a/sw/qa/extras/ooxmlimport/data/bnc821804.docx b/sw/qa/extras/ooxmlimport/data/bnc821804.docx new file mode 100644 index 0000000..9ec2e07 Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/bnc821804.docx differ diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index fe0241e..adc0df2 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -56,11 +56,13 @@ #include <com/sun/star/style/CaseMap.hpp> #include <com/sun/star/style/PageStyleLayout.hpp> #include <com/sun/star/style/ParagraphAdjust.hpp> +#include <com/sun/star/util/DateTime.hpp> #include <vcl/svapp.hxx> #include <unotools/fltrcfg.hxx> #include <comphelper/sequenceashashmap.hxx> #include <com/sun/star/text/GraphicCrop.hpp> #include <swtypes.hxx> +#include <tools/datetimeutils.hxx> #include <bordertest.hxx> @@ -2375,6 +2377,115 @@ DECLARE_OOXMLIMPORT_TEST(testBnc891663, "bnc891663.docx") CPPUNIT_ASSERT( textNextRowTop >= imageTop + imageHeight ); } +static OString dateTimeToString( const util::DateTime& dt ) +{ + return DateTimeToOString( DateTime( Date( dt.Day, dt.Month, dt.Year ), tools::Time( dt.Hours, dt.Minutes, dt.Seconds ))); +} + +DECLARE_OOXMLIMPORT_TEST(testBnc821804, "bnc821804.docx") +{ + CPPUNIT_ASSERT_EQUAL( OUString( "TITLE" ), getRun( getParagraph( 1 ), 1 )->getString()); + CPPUNIT_ASSERT(!hasProperty(getRun(getParagraph(1), 1), "RedlineType")); + // Redline information (SwXRedlinePortion) are separate "runs" apparently. + CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(1), 2), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(1), 2), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(1), 2), "IsStart")); + CPPUNIT_ASSERT_EQUAL(OUString("unknown1"),getProperty<OUString>(getRun(getParagraph(1), 2), "RedlineAuthor")); + CPPUNIT_ASSERT_EQUAL(OString("2006-08-29T09:46:00Z"),dateTimeToString(getProperty<util::DateTime>(getRun(getParagraph(1), 2), "RedlineDateTime"))); + // So only the 3rd run is actual text (and the two runs have been merged into one, not sure why, but that shouldn't be a problem). + CPPUNIT_ASSERT_EQUAL(OUString(" (1st run of an insert) (2nd run of an insert)"), getRun(getParagraph(1),3)->getString()); + CPPUNIT_ASSERT(!hasProperty(getRun(getParagraph(1), 3), "RedlineType")); + // And the end SwXRedlinePortion of the redline. + CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(1), 4), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(OUString("unknown1"),getProperty<OUString>(getRun(getParagraph(1), 4), "RedlineAuthor")); + CPPUNIT_ASSERT_EQUAL(OString("2006-08-29T09:46:00Z"),dateTimeToString(getProperty<util::DateTime>(getRun(getParagraph(1), 4), "RedlineDateTime"))); + CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(1), 4), "IsStart")); + + CPPUNIT_ASSERT_EQUAL(OUString("Normal text"), getRun(getParagraph(2),1)->getString()); + CPPUNIT_ASSERT(!hasProperty(getRun(getParagraph(2), 1), "RedlineType")); + + CPPUNIT_ASSERT_EQUAL(OUString("Delete"),getProperty<OUString>(getRun(getParagraph(3), 1), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(OUString("unknown2"),getProperty<OUString>(getRun(getParagraph(3), 1), "RedlineAuthor")); + CPPUNIT_ASSERT_EQUAL(OString("2006-08-29T09:47:00Z"),dateTimeToString(getProperty<util::DateTime>(getRun(getParagraph(3), 1), "RedlineDateTime"))); + CPPUNIT_ASSERT_EQUAL(OUString("Deleted"), getRun(getParagraph(3),2)->getString()); + + // This is both inserted and formatted, so there are two SwXRedlinePortion "runs". Given that the redlines overlap and Writer core + // doesn't officially expect that (even though it copes, the redline info will be split depending on how Writer deal with it). + CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(4), 1), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(4), 1), "IsStart")); + CPPUNIT_ASSERT_EQUAL(OUString("ParagraphFormat"),getProperty<OUString>(getRun(getParagraph(4), 2), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(4), 2), "IsStart")); + CPPUNIT_ASSERT_EQUAL(OUString("Inserted and formatted"), getRun(getParagraph(4),3)->getString()); + CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(4), 4), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(4), 4), "IsStart")); + CPPUNIT_ASSERT_EQUAL(OUString(" and this is only formatted"), getRun(getParagraph(4),5)->getString()); + CPPUNIT_ASSERT_EQUAL(OUString("ParagraphFormat"),getProperty<OUString>(getRun(getParagraph(4), 6), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(4), 6), "IsStart")); + + CPPUNIT_ASSERT_EQUAL(OUString("Normal text"), getRun(getParagraph(5),1)->getString()); + CPPUNIT_ASSERT(!hasProperty(getRun(getParagraph(5), 1), "RedlineType")); + + CPPUNIT_ASSERT_EQUAL(OUString("Format"),getProperty<OUString>(getRun(getParagraph(6), 1), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(6), 1), "IsStart")); + CPPUNIT_ASSERT_EQUAL(OUString("unknown5"),getProperty<OUString>(getRun(getParagraph(6), 1), "RedlineAuthor")); + CPPUNIT_ASSERT_EQUAL(OString("2006-08-29T10:02:00Z"),dateTimeToString(getProperty<util::DateTime>(getRun(getParagraph(6), 1), "RedlineDateTime"))); + CPPUNIT_ASSERT_EQUAL(OUString("Formatted run"), getRun(getParagraph(6),2)->getString()); + CPPUNIT_ASSERT_EQUAL(OUString("Format"),getProperty<OUString>(getRun(getParagraph(6), 3), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(6), 3), "IsStart")); + CPPUNIT_ASSERT_EQUAL(OUString(" and normal text here "), getRun(getParagraph(6),4)->getString()); + CPPUNIT_ASSERT(!hasProperty(getRun(getParagraph(6), 4), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(6), 5), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(6), 5), "IsStart")); + CPPUNIT_ASSERT_EQUAL(OUString("unknown6"),getProperty<OUString>(getRun(getParagraph(6), 5), "RedlineAuthor")); + CPPUNIT_ASSERT_EQUAL(OString("2006-08-29T09:48:00Z"),dateTimeToString(getProperty<util::DateTime>(getRun(getParagraph(6), 5), "RedlineDateTime"))); + CPPUNIT_ASSERT_EQUAL(OUString("and inserted again"), getRun(getParagraph(6),6)->getString()); + CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(6), 7), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(6), 7), "IsStart")); + CPPUNIT_ASSERT_EQUAL(OUString(" and normal text again "), getRun(getParagraph(6),8)->getString()); + CPPUNIT_ASSERT(!hasProperty(getRun(getParagraph(6), 8), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(OUString("Format"),getProperty<OUString>(getRun(getParagraph(6), 9), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(6), 9), "IsStart")); + CPPUNIT_ASSERT_EQUAL(OUString("unknown7"),getProperty<OUString>(getRun(getParagraph(6), 9), "RedlineAuthor")); + CPPUNIT_ASSERT_EQUAL(OUString("and formatted"), getRun(getParagraph(6),10)->getString()); + CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(6), 11), "IsStart")); + CPPUNIT_ASSERT_EQUAL(OUString(" and normal."), getRun(getParagraph(6),12)->getString()); + CPPUNIT_ASSERT(!hasProperty(getRun(getParagraph(6), 12), "RedlineType")); + + CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(7), 1), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(7), 1), "IsStart")); + CPPUNIT_ASSERT_EQUAL(OUString("unknown8"),getProperty<OUString>(getRun(getParagraph(7), 1), "RedlineAuthor")); + CPPUNIT_ASSERT_EQUAL(OUString("One insert."), getRun(getParagraph(7),2)->getString()); + CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(7), 3), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(7), 3), "IsStart")); + CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(7), 4), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(7), 4), "IsStart")); + CPPUNIT_ASSERT_EQUAL(OUString("unknown9"),getProperty<OUString>(getRun(getParagraph(7), 4), "RedlineAuthor")); + CPPUNIT_ASSERT_EQUAL(OUString("Second insert."), getRun(getParagraph(7),5)->getString()); + CPPUNIT_ASSERT_EQUAL(OUString("Insert"),getProperty<OUString>(getRun(getParagraph(7), 6), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(7), 6), "IsStart")); + + // Overlapping again. + CPPUNIT_ASSERT_EQUAL(OUString("Delete"),getProperty<OUString>(getRun(getParagraph(8), 1), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(8), 1), "IsStart")); + CPPUNIT_ASSERT_EQUAL(OUString("ParagraphFormat"),getProperty<OUString>(getRun(getParagraph(8), 2), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(8), 2), "IsStart")); + CPPUNIT_ASSERT_EQUAL(OUString("Deleted and formatted"), getRun(getParagraph(8),3)->getString()); + CPPUNIT_ASSERT_EQUAL(OUString("Delete"),getProperty<OUString>(getRun(getParagraph(8), 4), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(8), 4), "IsStart")); + CPPUNIT_ASSERT_EQUAL(OUString(" and this is only formatted"), getRun(getParagraph(8),5)->getString()); + CPPUNIT_ASSERT_EQUAL(OUString("ParagraphFormat"),getProperty<OUString>(getRun(getParagraph(8), 6), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(8), 6), "IsStart")); + + CPPUNIT_ASSERT_EQUAL(OUString("Normal text"), getRun(getParagraph(9),1)->getString()); + CPPUNIT_ASSERT(!hasProperty(getRun(getParagraph(9), 1), "RedlineType")); + + CPPUNIT_ASSERT_EQUAL(OUString("ParagraphFormat"),getProperty<OUString>(getRun(getParagraph(10), 1), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(true,getProperty<bool>(getRun(getParagraph(10), 1), "IsStart")); + CPPUNIT_ASSERT_EQUAL(OUString("This is only formatted."), getRun(getParagraph(10),2)->getString()); + CPPUNIT_ASSERT_EQUAL(OUString("ParagraphFormat"),getProperty<OUString>(getRun(getParagraph(10), 3), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(false,getProperty<bool>(getRun(getParagraph(10), 3), "IsStart")); +} + #endif CPPUNIT_PLUGIN_IMPLEMENT(); commit c469d1463073ba312d55ae3076b86381bfe89ed8 Author: LuboÅ¡ LuÅák <l.lu...@collabora.com> Date: Fri Oct 3 13:22:18 2014 +0200 report ParagraphFormat redline type in UNO too Change-Id: I0cf7586a154ca73ce64a2328ff8df1858e2290ac diff --git a/sw/source/core/unocore/unoredline.cxx b/sw/source/core/unocore/unoredline.cxx index 3575381..71dfe30 100644 --- a/sw/source/core/unocore/unoredline.cxx +++ b/sw/source/core/unocore/unoredline.cxx @@ -211,6 +211,7 @@ static OUString lcl_RedlineTypeToOUString(RedlineType_t eType) case nsRedlineType_t::REDLINE_INSERT: sRet = "Insert"; break; case nsRedlineType_t::REDLINE_DELETE: sRet = "Delete"; break; case nsRedlineType_t::REDLINE_FORMAT: sRet = "Format"; break; + case nsRedlineType_t::REDLINE_PARAGRAPH_FORMAT: sRet = "ParagraphFormat"; break; case nsRedlineType_t::REDLINE_TABLE: sRet = "TextTable"; break; case nsRedlineType_t::REDLINE_FMTCOLL:sRet = "Style"; break; } commit 9dbf817fe5c5253fba0831aefa17575ae0ba3af1 Author: LuboÅ¡ LuÅák <l.lu...@collabora.com> Date: Wed Oct 1 19:12:47 2014 +0200 handle scope of w:pPrChange and w:rPrChange properly (bnc#821804) Redlines changing formatting of runs and paragraphs are valid for the entire run/paragraph, not just their existence in the XML. So store them in the matching contexts, which will care of it, instead of the endtrackchange stuff. Change-Id: Ie583e4be14e8df95829852bfbbbe25aa0684f02e diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 4ef5e71..ea439c3 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -2222,9 +2222,10 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext ) } break; case NS_ooxml::LN_endtrackchange: - m_pImpl->RemoveCurrentRedline( ); + m_pImpl->RemoveTopRedline(); break; case NS_ooxml::LN_CT_RPrChange_rPr: + { // Push all the current 'Character' properties to the stack, so that we don't store them // as 'tracked changes' by mistake m_pImpl->PushProperties(CONTEXT_CHARACTER); @@ -2232,19 +2233,19 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext ) // Resolve all the properties that are under the 'rPrChange'->'rPr' XML node resolveSprmProps(*this, rSprm ); - if (m_pImpl->GetTopContext()) - { - // Get all the properties that were processed in the 'rPrChange'->'rPr' XML node - uno::Sequence< beans::PropertyValue > currentRedlineRevertProperties = m_pImpl->GetTopContext()->GetPropertyValues(); - - // Store these properties in the current redline object - m_pImpl->SetCurrentRedlineRevertProperties( currentRedlineRevertProperties ); - } + // Get all the properties that were processed in the 'rPrChange'->'rPr' XML node + uno::Sequence< beans::PropertyValue > currentRedlineRevertProperties = m_pImpl->GetTopContext()->GetPropertyValues(); // Pop back out the character properties that were on the run m_pImpl->PopProperties(CONTEXT_CHARACTER); + + // Store these properties in the current redline object (do it after the PopProperties() above, since + // otherwise it'd be stored in the content dropped there). + m_pImpl->SetCurrentRedlineRevertProperties( currentRedlineRevertProperties ); + } break; case NS_ooxml::LN_CT_PPrChange_pPr: + { // Push all the current 'Paragraph' properties to the stack, so that we don't store them // as 'tracked changes' by mistake m_pImpl->PushProperties(CONTEXT_PARAGRAPH); @@ -2252,17 +2253,16 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext ) // Resolve all the properties that are under the 'pPrChange'->'pPr' XML node resolveSprmProps(*this, rSprm ); - if (m_pImpl->GetTopContext()) - { - // Get all the properties that were processed in the 'pPrChange'->'pPr' XML node - uno::Sequence< beans::PropertyValue > currentRedlineRevertProperties = m_pImpl->GetTopContext()->GetPropertyValues(); - - // Store these properties in the current redline object - m_pImpl->SetCurrentRedlineRevertProperties( currentRedlineRevertProperties ); - } + // Get all the properties that were processed in the 'pPrChange'->'pPr' XML node + uno::Sequence< beans::PropertyValue > currentRedlineRevertProperties = m_pImpl->GetTopContext()->GetPropertyValues(); // Pop back out the character properties that were on the run m_pImpl->PopProperties(CONTEXT_PARAGRAPH); + + // Store these properties in the current redline object (do it after the PopProperties() above, since + // otherwise it'd be stored in the content dropped there). + m_pImpl->SetCurrentRedlineRevertProperties( currentRedlineRevertProperties ); + } break; case NS_ooxml::LN_object: { @@ -3444,7 +3444,7 @@ void DomainMapper::HandleRedline( Sprm& rSprm ) { sal_uInt32 nSprmId = rSprm.getId(); - m_pImpl->AddNewRedline( ); + m_pImpl->AddNewRedline( nSprmId ); if (nSprmId == NS_ooxml::LN_CT_PPr_pPrChange) { @@ -3484,6 +3484,7 @@ void DomainMapper::HandleRedline( Sprm& rSprm ) default: OSL_FAIL( "redline token other than mod, ins, del or table row" ); break; } m_pImpl->EndParaMarkerChange( ); + m_pImpl->SetCurrentRedlineIsRead(); } } //namespace dmapper diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 24889e5..eb08875 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -1592,7 +1592,7 @@ void DomainMapper_Impl::PushFootOrEndnote( bool bIsFootnote ) } void DomainMapper_Impl::CreateRedline(uno::Reference<text::XTextRange> const& xRange, - RedlineParamsPtr& pRedline) + RedlineParamsPtr pRedline) { if ( pRedline.get( ) ) { @@ -1646,21 +1646,25 @@ void DomainMapper_Impl::CheckParaMarkerRedline( uno::Reference< text::XTextRange void DomainMapper_Impl::CheckRedline( uno::Reference< text::XTextRange > const& xRange ) { + // Writer core "officially" does not like overlapping redlines, and its UNO interface is stupid enough + // to not prevent that. However, in practice in fact everything appears to work fine (except for the debug warnings + // about redline table corruption, which may possibly be harmless in reality). So leave this as it is, since this + // is a better representation of how the changes happened. If this will ever become a problem, overlapping redlines + // will need to be merged into one, just like doing the changes in the UI does, which will lose some information + // (and so if that happens, it may be better to fix Writer). + // Create the redlines here from lowest (formats) to highest (inserts/removals) priority, since the last one is + // what Writer presents graphically, so this will show deletes as deleted text and not as just formatted text being there. + if( GetTopContextOfType(CONTEXT_PARAGRAPH) != NULL ) + for( std::vector<RedlineParamsPtr>::const_iterator it = GetTopContextOfType(CONTEXT_PARAGRAPH)->Redlines().begin(); + it != GetTopContextOfType(CONTEXT_PARAGRAPH)->Redlines().end(); ++it ) + CreateRedline( xRange, *it ); + if( GetTopContextOfType(CONTEXT_CHARACTER) != NULL ) + for( std::vector<RedlineParamsPtr>::const_iterator it = GetTopContextOfType(CONTEXT_CHARACTER)->Redlines().begin(); + it != GetTopContextOfType(CONTEXT_CHARACTER)->Redlines().end(); ++it ) + CreateRedline( xRange, *it ); std::vector<RedlineParamsPtr>::iterator pIt = m_aRedlines.top().begin( ); - std::vector< RedlineParamsPtr > aCleaned; for (; pIt != m_aRedlines.top().end( ); ++pIt ) - { CreateRedline( xRange, *pIt ); - - // Adding the non-mod redlines to the temporary vector - if ( pIt->get( ) ) - { - if (((*pIt)->m_nToken & 0xffff) != XML_mod && ((*pIt)->m_nToken & 0xffff) != XML_ParagraphFormat) - aCleaned.push_back(*pIt); - } - } - - m_aRedlines.top().swap( aCleaned ); } void DomainMapper_Impl::StartParaMarkerChange( ) @@ -1671,6 +1675,7 @@ void DomainMapper_Impl::StartParaMarkerChange( ) void DomainMapper_Impl::EndParaMarkerChange( ) { m_bIsParaMarkerChange = false; + m_currentRedline.reset(); } @@ -4608,36 +4613,43 @@ bool DomainMapper_Impl::ExecuteFrameConversion() return bRet; } -void DomainMapper_Impl::AddNewRedline( ) +void DomainMapper_Impl::AddNewRedline( sal_uInt32 sprmId ) { RedlineParamsPtr pNew( new RedlineParams ); pNew->m_nToken = XML_mod; if ( !m_bIsParaMarkerChange ) { - m_aRedlines.top().push_back( pNew ); + // <w:rPrChange> applies to the whole <w:r>, <w:pPrChange> applies to the whole <w:p>, + // so keep those two in CONTEXT_CHARACTERS and CONTEXT_PARAGRAPH, which will take + // care of their scope (i.e. when they should be used and discarded). + // Let's keep the rest the same way they used to be handled (explictly dropped + // from a global stack by endtrackchange), but quite possibly they should not be handled + // that way either (I don't know). + if( sprmId == NS_ooxml::LN_EG_RPrContent_rPrChange ) + GetTopContextOfType( CONTEXT_CHARACTER )->Redlines().push_back( pNew ); + else if( sprmId == NS_ooxml::LN_CT_PPr_pPrChange ) + GetTopContextOfType( CONTEXT_PARAGRAPH )->Redlines().push_back( pNew ); + else + m_aRedlines.top().push_back( pNew ); } else { - m_pParaMarkerRedline.swap( pNew ); + m_pParaMarkerRedline = pNew; } + // Newly read data will go into this redline. + m_currentRedline = pNew; } -RedlineParamsPtr DomainMapper_Impl::GetTopRedline( ) +void DomainMapper_Impl::SetCurrentRedlineIsRead() { - RedlineParamsPtr pResult; - if ( !m_bIsParaMarkerChange && m_aRedlines.top().size( ) > 0 ) - pResult = m_aRedlines.top().back( ); - else if ( m_bIsParaMarkerChange ) - pResult = m_pParaMarkerRedline; - return pResult; + m_currentRedline.reset(); } sal_Int32 DomainMapper_Impl::GetCurrentRedlineToken( ) { sal_Int32 nToken = 0; - RedlineParamsPtr pCurrent( GetTopRedline( ) ); - if ( pCurrent.get( ) ) - nToken = pCurrent->m_nToken; + assert( m_currentRedline.get()); + nToken = m_currentRedline->m_nToken; return nToken; } @@ -4645,9 +4657,8 @@ void DomainMapper_Impl::SetCurrentRedlineAuthor( const OUString& sAuthor ) { if (!m_xAnnotationField.is()) { - RedlineParamsPtr pCurrent( GetTopRedline( ) ); - if ( pCurrent.get( ) ) - pCurrent->m_sAuthor = sAuthor; + assert( m_currentRedline.get()); + m_currentRedline->m_sAuthor = sAuthor; } else m_xAnnotationField->setPropertyValue("Author", uno::makeAny(sAuthor)); @@ -4663,9 +4674,8 @@ void DomainMapper_Impl::SetCurrentRedlineDate( const OUString& sDate ) { if (!m_xAnnotationField.is()) { - RedlineParamsPtr pCurrent( GetTopRedline( ) ); - if ( pCurrent.get( ) ) - pCurrent->m_sDate = sDate; + assert( m_currentRedline.get()); + m_currentRedline->m_sDate = sDate; } else m_xAnnotationField->setPropertyValue("DateTimeValue", uno::makeAny(ConversionHelper::ConvertDateStringToDateTime(sDate))); @@ -4679,46 +4689,46 @@ void DomainMapper_Impl::SetCurrentRedlineId( sal_Int32 sId ) } else { - RedlineParamsPtr pCurrent( GetTopRedline( ) ); - if ( pCurrent.get( ) ) - pCurrent->m_nId = sId; + // This should be an assert, but somebody had the smart idea to reuse this function also for comments and whatnot, + // and in some cases the id is actually not handled, which may be in fact a bug. + SAL_WARN( "writerfilter", !m_currentRedline.get()); + if( m_currentRedline.get()) + m_currentRedline->m_nId = sId; } } void DomainMapper_Impl::SetCurrentRedlineToken( sal_Int32 nToken ) { - RedlineParamsPtr pCurrent( GetTopRedline( ) ); - if ( pCurrent.get( ) ) - pCurrent->m_nToken = nToken; + assert( m_currentRedline.get()); + m_currentRedline->m_nToken = nToken; } void DomainMapper_Impl::SetCurrentRedlineRevertProperties( const uno::Sequence<beans::PropertyValue>& aProperties ) { - RedlineParamsPtr pCurrent( GetTopRedline( ) ); - if ( pCurrent.get( ) ) - pCurrent->m_aRevertProperties = aProperties; + assert( m_currentRedline.get()); + m_currentRedline->m_aRevertProperties = aProperties; } -void DomainMapper_Impl::RemoveCurrentRedline( ) +// This removes only the last redline stored here, those stored in contexts are automatically removed when +// the context is destroyed. +void DomainMapper_Impl::RemoveTopRedline( ) { - if ( m_aRedlines.top().size( ) > 0 ) - { - m_aRedlines.top().pop_back( ); - } + assert( m_aRedlines.top().size( ) > 0 ); + m_aRedlines.top().pop_back( ); + m_currentRedline.reset(); } void DomainMapper_Impl::ResetParaMarkerRedline( ) { if ( m_pParaMarkerRedline.get( ) ) { - RedlineParamsPtr pEmpty; - m_pParaMarkerRedline.swap( pEmpty ); + m_pParaMarkerRedline.reset(); + m_currentRedline.reset(); } } - void DomainMapper_Impl::ApplySettingsTable() { if (m_pSettingsTable && m_xTextFactory.is()) diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index 0407a08..817510c 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -250,20 +250,6 @@ struct AnnotationPosition }; typedef boost::unordered_map< sal_Int32, AnnotationPosition > AnnotationPositions_t; -struct RedlineParams -{ - OUString m_sAuthor; - OUString m_sDate; - sal_Int32 m_nId; - sal_Int32 m_nToken; - - /// This can hold properties of runs that had formatted 'track changes' properties - css::uno::Sequence<css::beans::PropertyValue> m_aRevertProperties; -}; -typedef boost::shared_ptr< RedlineParams > RedlineParamsPtr; - - - struct LineNumberSettings { bool bIsOn; @@ -392,6 +378,8 @@ private: // Redline stack std::stack< std::vector< RedlineParamsPtr > > m_aRedlines; + // The redline currently read, may be also stored by a context instead of m_aRedlines. + RedlineParamsPtr m_currentRedline; RedlineParamsPtr m_pParaMarkerRedline; bool m_bIsParaMarkerChange; @@ -466,7 +454,7 @@ public: } void SetDocumentSettingsProperty( const OUString& rPropName, const css::uno::Any& rValue ); - void CreateRedline( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > const& xRange, RedlineParamsPtr& pRedline ); + void CreateRedline( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > const& xRange, RedlineParamsPtr pRedline ); void CheckParaMarkerRedline( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > const& xRange ); @@ -725,9 +713,7 @@ public: ); bool ExecuteFrameConversion(); - void AddNewRedline( ); - - RedlineParamsPtr GetTopRedline( ); + void AddNewRedline( sal_uInt32 sprmId ); sal_Int32 GetCurrentRedlineToken( ); void SetCurrentRedlineAuthor( const OUString& sAuthor ); @@ -735,7 +721,8 @@ public: void SetCurrentRedlineId( sal_Int32 nId ); void SetCurrentRedlineToken( sal_Int32 nToken ); void SetCurrentRedlineRevertProperties( const css::uno::Sequence<css::beans::PropertyValue>& aProperties ); - void RemoveCurrentRedline( ); + void SetCurrentRedlineIsRead(); + void RemoveTopRedline( ); void ResetParaMarkerRedline( ); void SetCurrentRedlineInitials( const OUString& sInitials ); bool IsFirstRun() { return m_bIsFirstRun;} diff --git a/writerfilter/source/dmapper/PropertyMap.hxx b/writerfilter/source/dmapper/PropertyMap.hxx index dcd313d..dd6d2a7 100644 --- a/writerfilter/source/dmapper/PropertyMap.hxx +++ b/writerfilter/source/dmapper/PropertyMap.hxx @@ -74,6 +74,18 @@ enum GrabBagType CHAR_GRAB_BAG }; +struct RedlineParams +{ + OUString m_sAuthor; + OUString m_sDate; + sal_Int32 m_nId; + sal_Int32 m_nToken; + + /// This can hold properties of runs that had formatted 'track changes' properties + css::uno::Sequence<css::beans::PropertyValue> m_aRevertProperties; +}; +typedef boost::shared_ptr< RedlineParams > RedlineParamsPtr; + class PropValue { css::uno::Any m_aValue; @@ -105,6 +117,9 @@ class PropertyMap std::map< PropertyIds, PropValue > m_vMap; typedef std::map<PropertyIds,PropValue>::const_iterator MapIterator; + + std::vector< RedlineParamsPtr > m_aRedlines; + protected: void Invalidate() { @@ -151,6 +166,10 @@ public: void SetFootnoteFontName( const OUString& rSet ) { m_sFootnoteFontName = rSet;} virtual void insertTableProperties( const PropertyMap* ); + + const std::vector< RedlineParamsPtr >& Redlines() const { return m_aRedlines; } + std::vector< RedlineParamsPtr >& Redlines() { return m_aRedlines; } + #ifdef DEBUG_DOMAINMAPPER void printProperties(); #endif diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml index e2cfab9..febe5b1 100644 --- a/writerfilter/source/ooxml/model.xml +++ b/writerfilter/source/ooxml/model.xml @@ -17338,9 +17338,6 @@ </resource> <resource name="CT_RPrChange" resource="Properties"> <element name="rPr" tokenid="ooxml:CT_RPrChange_rPr"/> - <action name="end" action="tokenproperty"/> - <action name="end" action="sendPropertiesWithId" sendtokenid="ooxml:endtrackchange"/> - <action name="end" action="clearProps"/> </resource> <resource name="CT_ParaRPrChange" resource="Properties"> <element name="rPr" tokenid="ooxml:CT_ParaRPrChange_rPr"/> commit baf402008a18031f7a22a60ada85c3a5afa1b2a3 Author: LuboÅ¡ LuÅák <l.lu...@collabora.com> Date: Sun Sep 21 22:21:08 2014 +0200 display paragraph format redline also as 'formats' rather than empty string Change-Id: I5ae5ce80fdb453fdf5de54c691de4cd0b88ad7f6 diff --git a/sw/source/uibase/misc/redlndlg.cxx b/sw/source/uibase/misc/redlndlg.cxx index bb55453..ae71c2c 100644 --- a/sw/source/uibase/misc/redlndlg.cxx +++ b/sw/source/uibase/misc/redlndlg.cxx @@ -337,6 +337,7 @@ OUString SwRedlineAcceptDlg::GetActionText(const SwRangeRedline& rRedln, sal_uIn case nsRedlineType_t::REDLINE_INSERT: return sInserted; case nsRedlineType_t::REDLINE_DELETE: return sDeleted; case nsRedlineType_t::REDLINE_FORMAT: return sFormated; + case nsRedlineType_t::REDLINE_PARAGRAPH_FORMAT: return sFormated; case nsRedlineType_t::REDLINE_TABLE: return sTableChgd; case nsRedlineType_t::REDLINE_FMTCOLL: return sFmtCollSet; default:;//prevent warning @@ -1089,6 +1090,7 @@ IMPL_LINK_NOARG(SwRedlineAcceptDlg, CommandHdl) nResId = STR_REDLINE_DELETED; break; case nsRedlineType_t::REDLINE_FORMAT: + case nsRedlineType_t::REDLINE_PARAGRAPH_FORMAT: nResId = STR_REDLINE_FORMATED; break; case nsRedlineType_t::REDLINE_TABLE: diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx index 4bc5c14..09decb8 100644 --- a/sw/source/uibase/shells/textfld.cxx +++ b/sw/source/uibase/shells/textfld.cxx @@ -90,6 +90,7 @@ static OUString lcl_BuildTitleWithRedline( const SwRangeRedline *pRedline ) nResId = STR_REDLINE_DELETED; break; case nsRedlineType_t::REDLINE_FORMAT: + case nsRedlineType_t::REDLINE_PARAGRAPH_FORMAT: nResId = STR_REDLINE_FORMATED; break; case nsRedlineType_t::REDLINE_TABLE: commit b6969634082730e25f99e1e0d7b900cf57a25a0a Author: LuboÅ¡ LuÅák <l.lu...@collabora.com> Date: Wed Oct 1 13:09:36 2014 +0200 proper scoping for docx redline import (bnc#821804) propagateCharacterPropertiesAsSet sends the properties only when ending a text run (or maybe starting another one, I'm not quite sure), so it breaks ordering by sending them later then expected (although it worked in many cases). It's a question if propagateCharacterPropertiesAsSet is to be used by anything actually, since it seems rather broken to use it in the ooxml frontend. Using sendPropertiesWithId sends the properties properly at the right time, as one would expect. I don't know why dmapper can't simply handle this on its own, as I think it does handle entering and leaving other elements, but spending more time on it with this overdesigned abomination, oh well. Change-Id: Ie36c5f933ea3e6d789ea8f9e4ee3b60a5d1c920c diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml index ab4156e..e2cfab9 100644 --- a/writerfilter/source/ooxml/model.xml +++ b/writerfilter/source/ooxml/model.xml @@ -17339,7 +17339,7 @@ <resource name="CT_RPrChange" resource="Properties"> <element name="rPr" tokenid="ooxml:CT_RPrChange_rPr"/> <action name="end" action="tokenproperty"/> - <action name="end" action="propagateCharacterPropertiesAsSet" sendtokenid="ooxml:endtrackchange"/> + <action name="end" action="sendPropertiesWithId" sendtokenid="ooxml:endtrackchange"/> <action name="end" action="clearProps"/> </resource> <resource name="CT_ParaRPrChange" resource="Properties"> @@ -17347,10 +17347,10 @@ </resource> <resource name="CT_RunTrackChange" resource="Stream"> <action name="start" action="tokenproperty"/> - <action name="start" action="propagateCharacterPropertiesAsSet" sendtokenid="ooxml:trackchange"/> + <action name="start" action="sendPropertiesWithId" sendtokenid="ooxml:trackchange"/> <action name="start" action="clearProps"/> <action name="end" action="tokenproperty"/> - <action name="end" action="propagateCharacterPropertiesAsSet" sendtokenid="ooxml:endtrackchange"/> + <action name="end" action="sendPropertiesWithId" sendtokenid="ooxml:endtrackchange"/> <action name="end" action="clearProps"/> </resource> <resource name="EG_RangeMarkupElements" resource="Properties"> @@ -17537,6 +17537,7 @@ <element name="checkBox" tokenid="ooxml:CT_FFData_checkBox"/> <element name="ddList" tokenid="ooxml:CT_FFData_ddList"/> <element name="textInput" tokenid="ooxml:CT_FFData_textInput"/> + <!-- TODO: This is possibly wrong and should be sendPropertiesWithId --> <action name="end" action="propagateCharacterPropertiesAsSet" sendtokenid="ooxml:ffdata"/> <action name="end" action="clearProps"/> </resource> @@ -17976,7 +17977,7 @@ </resource> <resource name="CT_ParaTrackChange" resource="Properties"> <action name="start" action="tokenproperty"/> - <action name="start" action="propagateCharacterPropertiesAsSet" sendtokenid="ooxml:paratrackchange"/> + <action name="start" action="sendPropertiesWithId" sendtokenid="ooxml:paratrackchange"/> <action name="start" action="clearProps"/> </resource> <resource name="CT_RubyAlign" resource="Value">
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits