diff options
-rw-r--r-- | include/oox/export/vmlexport.hxx | 2 | ||||
-rw-r--r-- | oox/source/export/vmlexport.cxx | 27 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlexport/data/pictureWatermark.docx | bin | 0 -> 798086 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/data/textWatermark.docx | bin | 0 -> 17870 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx | 26 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtw8nds.cxx | 58 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtww8.hxx | 2 |
7 files changed, 111 insertions, 4 deletions
diff --git a/include/oox/export/vmlexport.hxx b/include/oox/export/vmlexport.hxx index 2b414c0d81be..744dbbd1bf05 100644 --- a/include/oox/export/vmlexport.hxx +++ b/include/oox/export/vmlexport.hxx @@ -90,7 +90,7 @@ public: sal_Int16 eVOri = -1, sal_Int16 eHRel = -1, sal_Int16 eVRel = -1, const Point* pNdTopLeft = 0, const sal_Bool bOOxmlExport = false ); virtual void AddSdrObjectVMLObject( const SdrObject& rObj); - + static bool IsWaterMarkShape(const OUString& rStr); protected: /// Add an attribute to the generated <v:shape/> element. /// diff --git a/oox/source/export/vmlexport.cxx b/oox/source/export/vmlexport.cxx index 35eeae73eb3a..fe82ea02a662 100644 --- a/oox/source/export/vmlexport.cxx +++ b/oox/source/export/vmlexport.cxx @@ -175,7 +175,28 @@ void VMLExport::AddShape( sal_uInt32 nShapeType, sal_uInt32 nShapeFlags, sal_uIn { m_nShapeType = nShapeType; m_nShapeFlags = nShapeFlags; - m_pShapeAttrList->add( XML_id, ShapeIdString( nShapeId ) ); + // If shape is a watermark object - should keep the original shape's name + // because Microsoft detects if it is a watermark by the actual name + if (!IsWaterMarkShape(m_pSdrObject->GetName())) + { + // Not a watermark object + m_pShapeAttrList->add( XML_id, ShapeIdString( nShapeId ) ); + } + else + { + // A watermark object - store the optional shape ID also ('o:spid') + m_pShapeAttrList->add( XML_id, OUStringToOString(m_pSdrObject->GetName(), RTL_TEXTENCODING_UTF8) ); + } +} + +bool VMLExport::IsWaterMarkShape(const OUString& rStr) +{ + if (rStr.isEmpty() ) return false; + + if (rStr.match(OUString("PowerPlusWaterMarkObject")) || rStr.match(OUString("WordPictureWatermark"))) + return true; + else + return false; } static void impl_AddArrowHead( sax_fastparser::FastAttributeList *pAttrList, sal_Int32 nElement, sal_uInt32 nValue ) @@ -787,7 +808,9 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const Rectangle& rRect aStream.Seek(0); OUString idStr = SvxMSDffManager::MSDFFReadZString(aStream, it->nPropSize, true); aStream.Seek(0); - m_pShapeAttrList->add(XML_ID, OUStringToOString(idStr, RTL_TEXTENCODING_UTF8)); + if (!IsWaterMarkShape(m_pSdrObject->GetName())) + m_pShapeAttrList->add(XML_ID, OUStringToOString(idStr, RTL_TEXTENCODING_UTF8)); + bAlreadyWritten[ESCHER_Prop_wzName] = true; } break; diff --git a/sw/qa/extras/ooxmlexport/data/pictureWatermark.docx b/sw/qa/extras/ooxmlexport/data/pictureWatermark.docx Binary files differnew file mode 100644 index 000000000000..b526ecf37061 --- /dev/null +++ b/sw/qa/extras/ooxmlexport/data/pictureWatermark.docx diff --git a/sw/qa/extras/ooxmlexport/data/textWatermark.docx b/sw/qa/extras/ooxmlexport/data/textWatermark.docx Binary files differnew file mode 100644 index 000000000000..c8bff75e028e --- /dev/null +++ b/sw/qa/extras/ooxmlexport/data/textWatermark.docx diff --git a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx index 8842cddef690..d46f58351630 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx @@ -911,6 +911,32 @@ DECLARE_OOXMLEXPORT_TEST(testDkVert, "dkvert.docx") CPPUNIT_ASSERT_EQUAL(sal_Int32(25), getProperty<drawing::Hatch>(xShape, "FillHatch").Distance); } +DECLARE_OOXMLEXPORT_TEST(testTextWatermark, "textWatermark.docx") +{ + //The problem was that the watermark ID was not preserved, + //and Word uses the object ID to identify if it is a watermark. + //It has to have the 'PowerPlusWaterMarkObject' string in it + xmlDocPtr pXmlHeader1 = parseExport("word/header1.xml"); + if (!pXmlHeader1) + return; + + assertXPath(pXmlHeader1, "/w:hdr[1]/w:p[1]/w:r[1]/w:pict[1]/v:shape[1]","id","PowerPlusWaterMarkObject93701316"); +} + +DECLARE_OOXMLEXPORT_TEST(testPictureWatermark, "pictureWatermark.docx") +{ + //The problem was that the watermark ID was not preserved, + //and Word uses the object ID to identify if it is a watermark. + //It has to have the 'WordPictureWaterMarkObject' string in it + + xmlDocPtr pXmlHeader1 = parseExport("word/header1.xml"); + if (!pXmlHeader1) + return; + + // Check the watermark ID + assertXPath(pXmlHeader1, "/w:hdr[1]/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Fallback[1]/w:pict[1]/v:rect[1]","id","WordPictureWatermark11962361"); +} + #endif CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx index b10ece75f92e..abe9360a97e3 100644 --- a/sw/source/filter/ww8/wrtw8nds.cxx +++ b/sw/source/filter/ww8/wrtw8nds.cxx @@ -81,6 +81,7 @@ #include <fmtrowsplt.hxx> #include <com/sun/star/i18n/ScriptType.hpp> #include <com/sun/star/i18n/WordType.hpp> +#include <oox/export/vmlexport.hxx> #include <filter/msfilter/sprmids.hxx> @@ -103,6 +104,7 @@ using namespace sw::util; using namespace sw::types; using namespace sw::mark; using namespace nsFieldFlags; +using namespace ::oox::vml; static OUString lcl_getFieldCode( const IFieldmark* pFieldmark ) { @@ -518,6 +520,26 @@ void SwWW8AttrIter::OutAttr( sal_Int32 nSwPos, bool bRuby ) m_rExport.AttrOutput().OutputItem( *pGrabBag ); } +bool SwWW8AttrIter::IsWatermarkFrame() +{ + if (maFlyFrms.size() != 1) + return false; + + while ( maFlyIter != maFlyFrms.end() ) + { + const SdrObject* pSdrObj = maFlyIter->GetFrmFmt().FindRealSdrObject(); + + if (pSdrObj) + { + if (VMLExport::IsWaterMarkShape(pSdrObj->GetName())) + return true; + } + ++maFlyIter; + } + + return false; +} + void SwWW8AttrIter::OutFlys(sal_Int32 nSwPos) { /* @@ -533,7 +555,34 @@ void SwWW8AttrIter::OutFlys(sal_Int32 nSwPos) if ( nPos != nSwPos ) break; - m_rExport.AttrOutput().OutputFlyFrame( *maFlyIter ); + const SdrObject* pSdrObj = maFlyIter->GetFrmFmt().FindRealSdrObject(); + + if (pSdrObj) + { + if (VMLExport::IsWaterMarkShape(pSdrObj->GetName())) + { + // This is a watermark object. Should be written ONLY in the header + if(m_rExport.nTxtTyp == TXT_HDFT) + { + // Should write a watermark in the header + m_rExport.AttrOutput().OutputFlyFrame( *maFlyIter ); + } + else + { + // Should not write watermark object in the main body text + } + } + else + { + // This is not a watermark object - write normally + m_rExport.AttrOutput().OutputFlyFrame( *maFlyIter ); + } + } + else + { + // This is not a watermark object - write normally + m_rExport.AttrOutput().OutputFlyFrame( *maFlyIter ); + } ++maFlyIter; } } @@ -1904,6 +1953,13 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode ) bLastCR = true; } + // In order to make sure watermark is stored in 'header.xml', check nTxtTyp. + // if it is document.xml, don't write the tags (watermark should be only in the 'header') + SwWW8AttrIter aWatermarkAttrIter( *this, rNode ); + if (( TXT_HDFT != nTxtTyp) && aWatermarkAttrIter.IsWatermarkFrame()) + { + return; + } bool bFlyInTable = mpParentFrame && IsInTable(); diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx index 0dfcfb351683..9a1d7b5d0147 100644 --- a/sw/source/filter/ww8/wrtww8.hxx +++ b/sw/source/filter/ww8/wrtww8.hxx @@ -1539,6 +1539,8 @@ public: OUString GetSnippet(const OUString &rStr, sal_Int32 nAktPos, sal_Int32 nLen) const; const SwFmtDrop& GetSwFmtDrop() const { return mrSwFmtDrop; } + + bool IsWatermarkFrame(); }; /// Class to collect and output the styles table. |