sw/qa/extras/ooxmlexport/data/paragraph-mark.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 10 ++++ sw/source/filter/ww8/docxattributeoutput.cxx | 54 +++++++++++++--------- sw/source/filter/ww8/wrtw8nds.cxx | 15 ++---- 4 files changed, 48 insertions(+), 31 deletions(-)
New commits: commit 4bb872b1924453f22e90bdd14e2898a3e66d5551 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Oct 17 17:56:33 2014 +0200 DOCX export: fix handling of paragraph mark on empty paragraphs The problem was that in case a paragraph is empty, and it has both a character style and direct formatting, then the doc model created by the ODT and DOCX import is like this: <text> <attrset> <item whichId="8" which="character font size" value="nHeight: 240, nProp: 100"/> </attrset> <hints> <hint end="0" whichId="52" which="character format" value="name: hello"/> </hints> </text> I.e. the direct formatting is stored in the attribute set of the text node directly, while the character style is stored as a hint. MSWordExportBase::OutputTextNode() tried to read the hints and if there were not any, then tried to read the attribute set, while in this situation we need both. Change-Id: I71fd10f6d00246348e77fee5431cb4e2a7c9b349 diff --git a/sw/qa/extras/ooxmlexport/data/paragraph-mark.docx b/sw/qa/extras/ooxmlexport/data/paragraph-mark.docx new file mode 100644 index 0000000..4636e4d Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/paragraph-mark.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index 395c753..b35f97b 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -483,6 +483,16 @@ DECLARE_OOXMLEXPORT_TEST(testAfterlines, "afterlines.docx") CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(423), getProperty<sal_Int32>(getParagraph(1), "ParaBottomMargin")); } +DECLARE_OOXMLEXPORT_TEST(testParagraphMark, "paragraph-mark.docx") +{ + // The problem was that we didn't handle the situation when an empty paragraph's marker had both a char style and some direct formatting. + + // This was 11. + CPPUNIT_ASSERT_EQUAL(12.f, getProperty<float>(getParagraph(1), "CharHeight")); + // This was empty. + CPPUNIT_ASSERT_EQUAL(OUString("Emphasis"), getProperty<OUString>(getRun(getParagraph(1), 1), "CharStyleName")); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 360e0a4..02aa301 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -872,6 +872,37 @@ void DocxAttributeOutput::WriteCollectedParagraphProperties() } } +/// Outputs an item set, that contains the formatting of the paragraph marker. +void lcl_writeParagraphMarkerProperties(DocxAttributeOutput& rAttributeOutput, const SfxItemSet& rParagraphMarkerProperties) +{ + SfxWhichIter aIter(rParagraphMarkerProperties); + sal_uInt16 nWhichId = aIter.FirstWhich(); + const SfxPoolItem* pItem = 0; + // Did we already produce a <w:sz> element? + bool bFontSizeWritten = false; + while (nWhichId) + { + if (rParagraphMarkerProperties.GetItemState(nWhichId, true, &pItem) == SfxItemState::SET) + { + if (isCHRATR(nWhichId) || nWhichId == RES_TXTATR_CHARFMT) + { + // Will this item produce a <w:sz> element? + bool bFontSizeItem = nWhichId == RES_CHRATR_FONTSIZE || nWhichId == RES_CHRATR_CJK_FONTSIZE; + if (!bFontSizeWritten || !bFontSizeItem) + rAttributeOutput.OutputItem(*pItem); + if (bFontSizeItem) + bFontSizeWritten = true; + } + else if (nWhichId == RES_TXTATR_AUTOFMT) + { + const SwFmtAutoFmt* pAutoFmt = static_cast<const SwFmtAutoFmt*>(pItem); + lcl_writeParagraphMarkerProperties(rAttributeOutput, *pAutoFmt->GetStyleHandle()); + } + } + nWhichId = aIter.NextWhich(); + } +} + void DocxAttributeOutput::EndParagraphProperties( const SfxItemSet* pParagraphMarkerProperties, const SwRedlineData* pRedlineData, const SwRedlineData* pRedlineParagraphMarkerDeleted, const SwRedlineData* pRedlineParagraphMarkerInserted) { // Call the 'Redline' function. This will add redline (change-tracking) information that regards to paragraph properties. @@ -909,28 +940,7 @@ void DocxAttributeOutput::EndParagraphProperties( const SfxItemSet* pParagraphMa m_pEastAsianLayoutAttrList = NULL; m_pCharLangAttrList = NULL; - SfxWhichIter aIter( *pParagraphMarkerProperties ); - sal_uInt16 nWhichId = aIter.FirstWhich(); - const SfxPoolItem* pItem = 0; - // Did we already produce a <w:sz> element? - bool bFontSizeWritten = false; - while( nWhichId ) - { - if( SfxItemState::SET == pParagraphMarkerProperties->GetItemState( nWhichId, true, &pItem )) - { - SAL_INFO( "sw.ww8", "nWhichId " << nWhichId); - if (isCHRATR( nWhichId )) - { - // Will this item produce a <w:sz> element? - bool bFontSizeItem = nWhichId == RES_CHRATR_FONTSIZE || nWhichId == RES_CHRATR_CJK_FONTSIZE; - if (!bFontSizeWritten || !bFontSizeItem) - OutputItem( *pItem ); - if (bFontSizeItem) - bFontSizeWritten = true; - } - } - nWhichId = aIter.NextWhich(); - } + lcl_writeParagraphMarkerProperties(*this, *pParagraphMarkerProperties); // Write the collected run properties that are stored in 'm_pFontsAttrList', 'm_pEastAsianLayoutAttrList', 'm_pCharLangAttrList' WriteCollectedRunProperties(); diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx index 24b5f2d..549c79c 100644 --- a/sw/source/filter/ww8/wrtw8nds.cxx +++ b/sw/source/filter/ww8/wrtw8nds.cxx @@ -2705,7 +2705,7 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode ) } } - const SfxItemSet* sfxItemSet = NULL; + SfxItemSet aParagraphMarkerProperties(pDoc->GetAttrPool(), RES_CHRATR_BEGIN, RES_TXTATR_END); if(const SwpHints* pTxtAttrs = rNode.GetpSwpHints()) { for( size_t i = 0; i < pTxtAttrs->Count(); ++i ) @@ -2721,22 +2721,19 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode ) SAL_INFO( "sw.ww8", startPos << "startPos == endPos" << *endPos); sal_uInt16 nWhich = pHt->GetAttr().Which(); SAL_INFO( "sw.ww8", "nWhich" << nWhich); - if (nWhich == RES_TXTATR_AUTOFMT) - { - const SwFmtAutoFmt& rAutoFmt = static_cast<const SwFmtAutoFmt&>(pHt->GetAttr()); - sfxItemSet = rAutoFmt.GetStyleHandle().get(); - } + if (nWhich == RES_TXTATR_AUTOFMT || nWhich == RES_TXTATR_CHARFMT) + aParagraphMarkerProperties.Put(pHt->GetAttr()); } } } - else + if (rNode.GetpSwAttrSet()) { - sfxItemSet = rNode.GetpSwAttrSet(); + aParagraphMarkerProperties.Put(*rNode.GetpSwAttrSet()); } const SwRedlineData* pRedlineParagraphMarkerDelete = AttrOutput().GetParagraphMarkerRedline( rNode, nsRedlineType_t::REDLINE_DELETE ); const SwRedlineData* pRedlineParagraphMarkerInsert = AttrOutput().GetParagraphMarkerRedline( rNode, nsRedlineType_t::REDLINE_INSERT ); const SwRedlineData* pParagraphRedlineData = aAttrIter.GetParagraphLevelRedline( ); - AttrOutput().EndParagraphProperties( sfxItemSet, pParagraphRedlineData, pRedlineParagraphMarkerDelete, pRedlineParagraphMarkerInsert); + AttrOutput().EndParagraphProperties(&aParagraphMarkerProperties, pParagraphRedlineData, pRedlineParagraphMarkerDelete, pRedlineParagraphMarkerInsert); AttrOutput().EndParagraph( pTextNodeInfoInner ); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits