ooxml: Preserve paragraph theme fill attribute

The theme fill attribute and the original fill color are saved to the
paragraph grab bag during the import.

On export, the original fill color and the current one are compared
to know if the user has changed the fill color during the edition. In
that case, the theme fill attribute and the original color are
dropped.

Some methods related to the grab bag management were added to
CellColorHandler for convenience.

Added a unit test for this attribute.

Change-Id: Ic0514ce1d2f290fb0aef5ed86327c1f03f31f20c
This commit is contained in:
Jacobo Aragunde Pérez 2013-12-22 18:55:43 +01:00
parent 151887a955
commit 128aeab30e
9 changed files with 77 additions and 4 deletions

View File

@ -2092,6 +2092,9 @@ DECLARE_OOXMLEXPORT_TEST(testThemePreservation, "theme-preservation.docx")
getProperty<OUString>(getRun(getParagraph(4, "Direct format font"), 1), "CharFontName"));
CPPUNIT_ASSERT_EQUAL(OUString("Trebuchet MS"),
getProperty<OUString>(getParagraph(5, "Major theme font"), "CharFontName"));
// check the paragraph background theme color has been preserved
assertXPath(pXmlDocument, "/w:document/w:body/w:p[6]/w:pPr/w:shd", "themeFill", "text2");
}
DECLARE_OOXMLEXPORT_TEST(testcantSplit, "2_table_doc.docx")

View File

@ -694,6 +694,14 @@ void DocxAttributeOutput::WriteCollectedParagraphProperties()
m_pSerializer->singleElementNS( XML_w, XML_spacing, xAttrList );
}
if ( m_pBackgroundAttrList )
{
XFastAttributeListRef xAttrList( m_pBackgroundAttrList );
m_pBackgroundAttrList = NULL;
m_pSerializer->singleElementNS( XML_w, XML_shd, xAttrList );
}
}
void DocxAttributeOutput::EndParagraphProperties( const SwRedlineData* pRedlineData, const SwRedlineData* pRedlineParagraphMarkerDeleted, const SwRedlineData* pRedlineParagraphMarkerInserted )
@ -5769,10 +5777,24 @@ void DocxAttributeOutput::FormatBackground( const SvxBrushItem& rBrush )
}
else if ( !m_rExport.bOutPageDescs )
{
m_pSerializer->singleElementNS( XML_w, XML_shd,
FSNS( XML_w, XML_fill ), sColor.getStr( ),
FSNS( XML_w, XML_val ), "clear",
FSEND );
if( !m_pBackgroundAttrList )
m_pBackgroundAttrList = m_pSerializer->createAttrList();
// compare fill color with the original fill color
OString sOriginalFill = rtl::OUStringToOString(
m_pBackgroundAttrList->getOptionalValue( FSNS( XML_w, XML_fill ) ), RTL_TEXTENCODING_UTF8 );
if( sOriginalFill.isEmpty() )
{
m_pBackgroundAttrList->add( FSNS( XML_w, XML_fill ), sColor.getStr() );
}
else if ( sOriginalFill != sColor )
{
// fill was modified during edition, theme fill attribute must be dropped
delete m_pBackgroundAttrList;
m_pBackgroundAttrList = m_pSerializer->createAttrList();
m_pBackgroundAttrList->add( FSNS( XML_w, XML_fill ), sColor.getStr() );
}
m_pBackgroundAttrList->add( FSNS( XML_w, XML_val ), "clear" );
}
}
@ -6109,6 +6131,27 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem)
m_nParaAfterSpacing = MM100_TO_TWIP(m_nParaAfterSpacing);
SAL_INFO("sw.ww8", "DocxAttributeOutput::ParaGrabBag: property =" << i->first << " : m_nParaBeforeSpacing= " << m_nParaAfterSpacing);
}
else if (i->first == "CharThemeFill")
{
uno::Sequence<beans::PropertyValue> aGrabBagSeq;
i->second >>= aGrabBagSeq;
OUString sThemeFill, sOriginalFill;
for (sal_Int32 j=0; j < aGrabBagSeq.getLength(); ++j)
{
if (aGrabBagSeq[j].Name == "themeFill")
aGrabBagSeq[j].Value >>= sThemeFill;
else if (aGrabBagSeq[j].Name == "fill")
aGrabBagSeq[j].Value >>= sOriginalFill;
}
if (!m_pBackgroundAttrList)
m_pBackgroundAttrList = m_pSerializer->createAttrList();
m_pBackgroundAttrList->add(FSNS(XML_w, XML_themeFill),
OUStringToOString(sThemeFill, RTL_TEXTENCODING_UTF8));
m_pBackgroundAttrList->add(FSNS(XML_w, XML_fill),
OUStringToOString(sOriginalFill, RTL_TEXTENCODING_UTF8));
}
else
SAL_INFO("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unhandled grab bag property " << i->first );
}
@ -6236,6 +6279,7 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSeri
m_pFlyWrapAttrList( NULL ),
m_pTextboxAttrList( NULL ),
m_pColorAttrList( NULL ),
m_pBackgroundAttrList( NULL ),
m_pFlyFrameSize(0),
m_pFootnotesList( new ::docx::FootnotesList() ),
m_pEndnotesList( new ::docx::FootnotesList() ),
@ -6293,6 +6337,7 @@ DocxAttributeOutput::~DocxAttributeOutput()
delete m_pBodyPrAttrList, m_pBodyPrAttrList = NULL;
delete m_pTextboxAttrList, m_pTextboxAttrList = NULL;
delete m_pColorAttrList, m_pColorAttrList = NULL;
delete m_pBackgroundAttrList, m_pBackgroundAttrList = NULL;
delete m_pFootnotesList, m_pFootnotesList = NULL;
delete m_pEndnotesList, m_pEndnotesList = NULL;

View File

@ -686,6 +686,8 @@ private:
::sax_fastparser::FastAttributeList *m_pTextboxAttrList;
/// Attributes of the run color
::sax_fastparser::FastAttributeList *m_pColorAttrList;
/// Attributes of the paragraph background
::sax_fastparser::FastAttributeList *m_pBackgroundAttrList;
/// When exporting fly frames, this holds the real size of the frame.
const Size* m_pFlyFrameSize;

View File

@ -359,6 +359,17 @@ beans::PropertyValue CellColorHandler::getInteropGrabBag()
return aRet;
}
void CellColorHandler::disableInteropGrabBag()
{
m_aInteropGrabBagName = "";
m_aInteropGrabBag.clear();
}
sal_Bool CellColorHandler::isInteropGrabBagEnabled()
{
return !(m_aInteropGrabBagName.isEmpty());
}
} //namespace dmapper
} //namespace writerfilter

View File

@ -58,6 +58,8 @@ public:
void enableInteropGrabBag(OUString aName);
beans::PropertyValue getInteropGrabBag();
void disableInteropGrabBag();
sal_Bool isInteropGrabBagEnabled();
};
typedef boost::shared_ptr< CellColorHandler > CellColorHandlerPtr;
}}

View File

@ -1961,8 +1961,16 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext, SprmType
{
CellColorHandlerPtr pCellColorHandler( new CellColorHandler );
pCellColorHandler->setOutputFormat( CellColorHandler::Paragraph );
sal_Bool bEnableTempGrabBag = !pCellColorHandler->isInteropGrabBagEnabled();
if( bEnableTempGrabBag )
pCellColorHandler->enableInteropGrabBag( "TempShdPropsGrabBag" );
pProperties->resolve(*pCellColorHandler);
rContext->InsertProps(pCellColorHandler->getProperties());
rContext->Insert(PROP_CHAR_THEME_FILL, pCellColorHandler->getInteropGrabBag().Value, true, PARA_GRAB_BAG);
if(bEnableTempGrabBag)
pCellColorHandler->disableInteropGrabBag();
}
}
break;

View File

@ -358,6 +358,7 @@ OUString PropertyNameSupplier::GetName( PropertyIds eId ) const
case PROP_CHAR_THEME_COLOR : sName = "CharThemeColor"; break;
case PROP_CHAR_THEME_ORIGINAL_COLOR : sName = "CharThemeOriginalColor"; break;
case PROP_CHAR_THEME_COLOR_SHADE : sName = "CharThemeColorShade"; break;
case PROP_CHAR_THEME_FILL : sName = "CharThemeFill"; break;
}
::std::pair<PropertyNameMap_t::iterator,bool> aInsertIt =
m_pImpl->aNameMap.insert( PropertyNameMap_t::value_type( eId, sName ));

View File

@ -329,6 +329,7 @@ enum PropertyIds
,PROP_CHAR_THEME_COLOR
,PROP_CHAR_THEME_ORIGINAL_COLOR
,PROP_CHAR_THEME_COLOR_SHADE
,PROP_CHAR_THEME_FILL
};
struct PropertyNameSupplier_Impl;
class PropertyNameSupplier