[Libreoffice-commits] core.git: Branch 'libreoffice-5-4' - oox/source sw/qa sw/source

Szymon Kłos szymon.klos at collabora.com
Sun Jun 4 11:38:15 UTC 2017


 oox/source/export/vmlexport.cxx           |    4 +++-
 oox/source/vml/vmlshapecontext.cxx        |   11 +++++++++--
 sw/qa/extras/ooxmlexport/ooxmlexport7.cxx |    4 ++++
 sw/qa/extras/uiwriter/data/watermark.docx |binary
 sw/qa/extras/uiwriter/uiwriter.cxx        |   23 +++++++++++++++++++++++
 sw/source/core/edit/edfcol.cxx            |   17 +++++++++++------
 6 files changed, 50 insertions(+), 9 deletions(-)

New commits:
commit a406d5c22793fd2d43a0876f897a16b11a367ec7
Author: Szymon Kłos <szymon.klos at collabora.com>
Date:   Wed May 24 00:15:15 2017 +0200

    Watermark: docx interoperability
    
    Before patch:
    
    Document created in MS Word:
    <v:shapetype id="_x0000_t136" o:spt="136" ...>
    <v:shape type="#_x0000_t136" ...>
    
    Imported to LO and exported:
    <v:shapetype id="shapetype_136" o:spt="136" ...>
    <v:shape type="shapetype_136" ...>
    
    Then again imported to MS Word and exported:
    <v:shapetype id="shapetype_136" o:spid="_x0000_m1026" o:spt="100" ...>
    <v:shape type="#shapetype_136" ...>
    
    In this moment LO after import had shape in the navigator but it wasn't visible.
    
    Patch:
    * vmshapecontext.cxx is changed to read ShapeType from id instead of o:spt
                         when o:spid is present.
    * vmlexport.cxx added o:spid for Word to identify inserted watermark
    * edfxol.cxx changed name of shape to "PowerPlusWaterMarkObject" for Word
    * tests
    
    Change-Id: I25322628838a98c45cbeed64144d04977b2ea9ba
    Reviewed-on: https://gerrit.libreoffice.org/37969
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    (cherry picked from commit 271094ad8f9e334d17176744b90b35e80528bcb2)
    Reviewed-on: https://gerrit.libreoffice.org/38381
    Reviewed-by: Szymon Kłos <szymon.klos at collabora.com>

diff --git a/oox/source/export/vmlexport.cxx b/oox/source/export/vmlexport.cxx
index ef400be64f7c..623beaaa88ec 100644
--- a/oox/source/export/vmlexport.cxx
+++ b/oox/source/export/vmlexport.cxx
@@ -190,8 +190,10 @@ void VMLExport::AddShape( sal_uInt32 nShapeType, sal_uInt32 nShapeFlags, sal_uIn
     }
     else
     {
-        // A watermark object - store the optional shape ID also ('o:spid')
+        // A watermark object - store the optional shape ID
         m_pShapeAttrList->add( XML_id, OUStringToOString(m_pSdrObject->GetName(), RTL_TEXTENCODING_UTF8) );
+        // also ('o:spid')
+        m_pShapeAttrList->addNS( XML_o, XML_spid, ShapeIdString( nShapeId ) );
     }
 }
 
diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx
index dc654223aca6..ed369ae1c7d9 100644
--- a/oox/source/vml/vmlshapecontext.cxx
+++ b/oox/source/vml/vmlshapecontext.cxx
@@ -275,11 +275,18 @@ ShapeTypeContext::ShapeTypeContext( ContextHandler2Helper& rParent, ShapeType& r
     mrTypeModel.maShapeId = rAttribs.getXString( bHasOspid ? O_TOKEN( spid ) : XML_id, OUString() );
     mrTypeModel.maLegacyId = rAttribs.getString( XML_id, OUString() );
     OSL_ENSURE( !mrTypeModel.maShapeId.isEmpty(), "ShapeTypeContext::ShapeTypeContext - missing shape identifier" );
+    // builtin shape type identifier
+    mrTypeModel.moShapeType = rAttribs.getInteger( O_TOKEN( spt ) );
     // if the o:spid attribute exists, the id attribute contains the user-defined shape name
     if( bHasOspid )
+    {
         mrTypeModel.maShapeName = rAttribs.getXString( XML_id, OUString() );
-    // builtin shape type identifier
-    mrTypeModel.moShapeType = rAttribs.getInteger( O_TOKEN( spt ) );
+        // get ShapeType and ShapeId from name for compatibility
+        mrTypeModel.maShapeId = mrTypeModel.maShapeName;
+        static const OUString sShapeTypePrefix = "shapetype_";
+        if( mrTypeModel.maShapeName.startsWith( sShapeTypePrefix ) )
+            mrTypeModel.moShapeType = mrTypeModel.maShapeName.copy(sShapeTypePrefix.getLength()).toInt32();
+    }
 
     // coordinate system position/size, CSS style
     mrTypeModel.moCoordPos = lclDecodeInt32Pair( rAttribs, XML_coordorigin );
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx
index b538e9f990da..e7f24005cd92 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx
@@ -106,6 +106,10 @@ DECLARE_OOXMLEXPORT_TEST(testTextWatermark, "textWatermark.docx")
        return;
 
     assertXPath(pXmlHeader1, "/w:hdr[1]/w:p[1]/w:r[1]/w:pict[1]/v:shape[1]","id","PowerPlusWaterMarkObject93701316");
+
+    //The second problem was that Word uses also "o:spid"
+    const OUString& sSpid = getXPath(pXmlHeader1, "/w:hdr[1]/w:p[1]/w:r[1]/w:pict[1]/v:shape[1]","spid");
+    CPPUNIT_ASSERT(!sSpid.isEmpty());
 }
 
 DECLARE_OOXMLEXPORT_TEST(testPictureWatermark, "pictureWatermark.docx")
diff --git a/sw/qa/extras/uiwriter/data/watermark.docx b/sw/qa/extras/uiwriter/data/watermark.docx
new file mode 100644
index 000000000000..0b26d4442e98
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/watermark.docx differ
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index 30ce2e4c442d..7eccab668c7d 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -105,6 +105,7 @@
 #include <comphelper/configurationhelper.hxx>
 #include <editeng/unolingu.hxx>
 #include <config_features.h>
+#include <sfx2/watermarkitem.hxx>
 
 static const char* const DATA_DIRECTORY = "/sw/qa/extras/uiwriter/data/";
 
@@ -126,6 +127,7 @@ public:
     void testDOCXAutoTextMultiple();
     void testDOTMAutoText();
     void testDOCXAutoTextGallery();
+    void testWatermarkDOCX();
     void testTdf67238();
     void testFdo75110();
     void testFdo75898();
@@ -261,6 +263,7 @@ public:
     CPPUNIT_TEST(testDOCXAutoTextMultiple);
     CPPUNIT_TEST(testDOTMAutoText);
     CPPUNIT_TEST(testDOCXAutoTextGallery);
+    CPPUNIT_TEST(testWatermarkDOCX);
     CPPUNIT_TEST(testTdf67238);
     CPPUNIT_TEST(testFdo75110);
     CPPUNIT_TEST(testFdo75898);
@@ -850,6 +853,26 @@ void SwUiWriterTest::testDOCXAutoTextGallery()
     CPPUNIT_ASSERT_EQUAL(OUString("Multiple"), pGlossary->GetLongName(0));
 }
 
+void SwUiWriterTest::testWatermarkDOCX()
+{
+    SwDoc* const pDoc = createDoc("watermark.docx");
+    SwDocShell* pDocShell = pDoc->GetDocShell();
+    const SfxPoolItem* pItem;
+    SfxItemState eState = pDocShell->GetViewShell()->GetViewFrame()->GetDispatcher()->QueryState(SID_WATERMARK, pItem);
+
+    CPPUNIT_ASSERT(eState >= SfxItemState::DEFAULT);
+    CPPUNIT_ASSERT(pItem);
+    CPPUNIT_ASSERT_EQUAL((unsigned short)SID_WATERMARK, pItem->Which());
+
+    const SfxWatermarkItem* pWatermark = static_cast<const SfxWatermarkItem*>(pItem);
+    CPPUNIT_ASSERT_EQUAL(OUString("CustomWatermark"), pWatermark->GetText());
+    //TODO: VML import textpath style
+    //CPPUNIT_ASSERT_EQUAL(OUString("DejaVu Sans Light"), pWatermark->GetFont());
+    CPPUNIT_ASSERT_EQUAL((sal_Int16)45, pWatermark->GetAngle());
+    CPPUNIT_ASSERT_EQUAL((sal_uInt32)0x548dd4, pWatermark->GetColor());
+    CPPUNIT_ASSERT_EQUAL((sal_Int16)50, pWatermark->GetTransparency());
+}
+
 void SwUiWriterTest::testFdo74981()
 {
     // create a document with an input field
diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx
index e044ef503965..bb27351acbdf 100644
--- a/sw/source/core/edit/edfcol.cxx
+++ b/sw/source/core/edit/edfcol.cxx
@@ -60,6 +60,8 @@
 #include <pagefrm.hxx>
 #include <sfx2/watermarkitem.hxx>
 
+#define WATERMARK_NAME "PowerPlusWaterMarkObject"
+
 namespace
 {
 
@@ -114,8 +116,8 @@ bool lcl_hasField(const uno::Reference<text::XText>& xText, const OUString& rSer
     return false;
 }
 
-/// Search for a frame named rShapeName of type rServiceName in xText.
-uno::Reference<drawing::XShape> lcl_getWatermark(const uno::Reference<text::XText>& xText, const OUString& rServiceName, const OUString& rShapeName)
+/// Search for a frame with WATERMARK_NAME in name of type rServiceName in xText. Returns found name in rShapeName.
+uno::Reference<drawing::XShape> lcl_getWatermark(const uno::Reference<text::XText>& xText, const OUString& rServiceName, OUString& rShapeName)
 {
     uno::Reference<container::XEnumerationAccess> xParagraphEnumerationAccess(xText, uno::UNO_QUERY);
     uno::Reference<container::XEnumeration> xParagraphs = xParagraphEnumerationAccess->createEnumeration();
@@ -147,9 +149,12 @@ uno::Reference<drawing::XShape> lcl_getWatermark(const uno::Reference<text::XTex
                 continue;
 
             uno::Reference<container::XNamed> xNamed(xWatermark, uno::UNO_QUERY);
-            if (xNamed->getName() != rShapeName)
+
+            if (!xNamed->getName().match(WATERMARK_NAME))
                 continue;
 
+            rShapeName = xNamed->getName();
+
             uno::Reference<drawing::XShape> xShape(xWatermark, uno::UNO_QUERY);
             return xShape;
         }
@@ -286,7 +291,7 @@ SfxWatermarkItem SwEditShell::GetWatermark()
         xPageStyle->getPropertyValue(UNO_NAME_HEADER_TEXT) >>= xHeaderText;
 
         OUString aShapeServiceName = "com.sun.star.drawing.CustomShape";
-        static const OUString sWatermark = SfxClassificationHelper::PROP_PREFIX_INTELLECTUALPROPERTY() + SfxClassificationHelper::PROP_DOCWATERMARK();
+        OUString sWatermark = "";
         uno::Reference<drawing::XShape> xWatermark = lcl_getWatermark(xHeaderText, aShapeServiceName, sWatermark);
 
         if (xWatermark.is())
@@ -352,7 +357,7 @@ void SwEditShell::SetWatermark(const SfxWatermarkItem& rWatermark)
         xPageStyle->getPropertyValue(UNO_NAME_HEADER_TEXT) >>= xHeaderText;
 
         OUString aShapeServiceName = "com.sun.star.drawing.CustomShape";
-        static const OUString sWatermark = SfxClassificationHelper::PROP_PREFIX_INTELLECTUALPROPERTY() + SfxClassificationHelper::PROP_DOCWATERMARK();
+        OUString sWatermark = WATERMARK_NAME;
         uno::Reference<drawing::XShape> xWatermark = lcl_getWatermark(xHeaderText, aShapeServiceName, sWatermark);
 
         bool bDeleteWatermark = rWatermark.GetText().isEmpty();
@@ -493,7 +498,7 @@ void SwEditShell::SetWatermark(const SfxWatermarkItem& rWatermark)
             xPropertySet->setPropertyValue("CustomShapeGeometry", uno::makeAny(comphelper::containerToSequence(aGeomPropVec)));
 
             uno::Reference<container::XNamed> xNamed(xShape, uno::UNO_QUERY);
-            xNamed->setName(SfxClassificationHelper::PROP_PREFIX_INTELLECTUALPROPERTY() + SfxClassificationHelper::PROP_DOCWATERMARK());
+            xNamed->setName(sWatermark);
             xLockable->removeActionLock();
         }
     }


More information about the Libreoffice-commits mailing list