[Libreoffice-commits] core.git: 2 commits - sw/qa sw/source writerfilter/source

Jacobo Aragunde Pérez jaragunde at igalia.com
Wed Feb 26 11:19:11 PST 2014


 sw/qa/extras/ooxmlexport/ooxmlexport.cxx     |    2 -
 sw/source/filter/ww8/docxattributeoutput.cxx |   49 ++++++++++++++++++++++++---
 sw/source/filter/ww8/docxexport.cxx          |   16 +++-----
 sw/source/filter/ww8/docxexport.hxx          |    2 -
 writerfilter/source/dmapper/OLEHandler.cxx   |   45 ++++++++++++++++++++++++
 writerfilter/source/dmapper/OLEHandler.hxx   |    4 ++
 6 files changed, 102 insertions(+), 16 deletions(-)

New commits:
commit 1c993627d893c62ab8f01355895206374bf4eb6c
Author: Jacobo Aragunde Pérez <jaragunde at igalia.com>
Date:   Wed Feb 26 18:29:44 2014 +0100

    sw: write other types of embeddings properly to docx
    
    Improves patch 1428ec6f4e2bfe0d8654a9ccc713e274e08c6423
    
    When embedding an object into a docx, several things interact:
    
    * The properties in the <o:OLEObject> tag in document.xml
    * The ContentType for the file defined in [Content_Types].xml
    * The Type of the Relationship defined in document.xml.rels
    
    You need the right combination of those three elements for Word to
    properly recognize the embeddings in exported documents.
    
    To know which values must be written, I store some interoperability
    information in the import phase in the document grab bag. The
    relevant information is the value of the ProgID attribute in the
    <o:OLEObject> tag.
    
    I have defined three cases depending on the value of ProgID, but more
    could be needed in the future:
    * Embedded xlsx sheet.
    * Embedded pptx presentation.
    * Generic OLE, this should work with embedded odt/ods in combination
      with the ProgID attribute stored in the import phase.
    
    Change-Id: I26336cb3fe47bd33e1cef11dd1c7edcf390f2e56

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 675a012..12e5992 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -2579,7 +2579,7 @@ DECLARE_OOXMLEXPORT_TEST(testEmbeddedXlsx, "embedded-xlsx.docx")
     int nImageFiles = 0;
     for (int i=0; i<names.getLength(); i++)
     {
-        if(names[i].startsWith("word/embeddings/Microsoft_Excel_Worksheet"))
+        if(names[i].startsWith("word/embeddings/oleObject"))
             nSheetFiles++;
         if(names[i].startsWith("word/media/image"))
             nImageFiles++;
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 362c1c8..1b91a13 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -3568,12 +3568,53 @@ void DocxAttributeOutput::WritePostponedOLE()
 
     SAL_INFO( "sw.ww8", OSL_THIS_FUNC );
 
+    // get interoperability information about embedded objects
+    uno::Reference< beans::XPropertySet > xPropSet( m_rExport.pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
+    OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
+    uno::Sequence< beans::PropertyValue > aGrabBag, aObjectsInteropList;
+    xPropSet->getPropertyValue( pName ) >>= aGrabBag;
+    for( sal_Int32 i=0; i < aGrabBag.getLength(); ++i )
+        if ( aGrabBag[i].Name == "EmbeddedObjects" )
+        {
+            aGrabBag[i].Value >>= aObjectsInteropList;
+            break;
+        }
+
     for( std::list< PostponedOLE >::iterator it = m_postponedOLE->begin();
          it != m_postponedOLE->end();
          ++it )
     {
+        SwOLEObj& aObject = it->object->GetOLEObj();
+        uno::Reference < embed::XEmbeddedObject > xObj( aObject.GetOleRef() );
+        comphelper::EmbeddedObjectContainer* aContainer = aObject.GetObject().GetContainer();
+        OUString sObjectName = aContainer->GetEmbeddedObjectName( xObj );
+
+        // set some attributes according to the type of the embedded object
+        OUString sProgID, sMediaType, sRelationType;
+        for( sal_Int32 i=0; i < aObjectsInteropList.getLength(); ++i )
+            if ( aObjectsInteropList[i].Name == sObjectName )
+            {
+                aObjectsInteropList[i].Value >>= sProgID;
+                break;
+            }
+        if( sProgID.startsWith("Excel.Sheet") )
+        {
+            sMediaType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
+            sRelationType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package";
+        }
+        else if( sProgID.startsWith("PowerPoint.Show") )
+        {
+            sMediaType = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
+            sRelationType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package";
+        }
+        else
+        {
+            sMediaType = "application/vnd.openxmlformats-officedocument.oleObject";
+            sRelationType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject";
+        }
+
         // write embedded file
-        OString sId = m_rExport.WriteOLENode( *it->object );
+        OString sId = m_rExport.WriteOLEObject( aObject, sMediaType, sRelationType );
 
         if( sId.isEmpty() )
         {
@@ -3612,7 +3653,7 @@ void DocxAttributeOutput::WritePostponedOLE()
         // OLE object definition
         m_pSerializer->singleElementNS( XML_o, XML_OLEObject,
                                         XML_Type, "Embed",
-                                        XML_ProgID,"Excel.Sheet.12", //TODO: should be auto-detected somehow
+                                        XML_ProgID, OUStringToOString( sProgID, RTL_TEXTENCODING_UTF8 ).getStr(),
                                         XML_ShapeID, sShapeId.getStr(),
                                         XML_DrawAspect, "Content",
                                         XML_ObjectID, "_" + OString::number( rand() ),
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index 41e7083..79077f5 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -358,25 +358,23 @@ OString DocxExport::OutputChart( uno::Reference< frame::XModel >& xModel, sal_In
     return OUStringToOString( sId, RTL_TEXTENCODING_UTF8 );
 }
 
-OString DocxExport::WriteOLENode( const SwOLENode& rNode )
+OString DocxExport::WriteOLEObject( SwOLEObj& rObject, OUString sMediaType, OUString sRelationType )
 {
-    uno::Reference <embed::XEmbeddedObject> xObj( const_cast<SwOLENode&>(rNode).GetOLEObj().GetOleRef() );
-    OUString sId, sMediaType;
-    comphelper::EmbeddedObjectContainer* aContainer = const_cast<SwOLENode&>(rNode).GetOLEObj().GetObject().GetContainer();
-    uno::Reference< io::XInputStream > xInStream = aContainer->GetObjectStream( xObj, &sMediaType );
+    uno::Reference <embed::XEmbeddedObject> xObj( rObject.GetOleRef() );
+    comphelper::EmbeddedObjectContainer* aContainer = rObject.GetObject().GetContainer();
+    uno::Reference< io::XInputStream > xInStream = aContainer->GetObjectStream( xObj, NULL );
 
-    OUString sFileName = "embeddings/Microsoft_Excel_Worksheet" + OUString::number( ++m_nOLEObjects ) + ".xlsx";
+    OUString sFileName = "embeddings/oleObject" + OUString::number( ++m_nOLEObjects ) + ".bin";
     uno::Reference< io::XOutputStream > xOutStream = GetFilter().openFragmentStream( OUStringBuffer()
                                                                       .appendAscii( "word/" )
                                                                       .append( sFileName )
                                                                       .makeStringAndClear(),
                                                                       sMediaType );
-
+    OUString sId;
     if( lcl_CopyStream( xInStream, xOutStream ) )
 
         sId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
-                "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package",
-                sFileName, false );
+                sRelationType, sFileName, false );
 
     return OUStringToOString( sId, RTL_TEXTENCODING_UTF8 );
 }
diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx
index 4ce76e3..01679d1 100644
--- a/sw/source/filter/ww8/docxexport.hxx
+++ b/sw/source/filter/ww8/docxexport.hxx
@@ -165,7 +165,7 @@ public:
 
     /// Returns the relationd id
     OString OutputChart( com::sun::star::uno::Reference< com::sun::star::frame::XModel >& xModel, sal_Int32 nCount, ::sax_fastparser::FSHelperPtr m_pSerializer );
-    OString WriteOLENode( const SwOLENode& rNode );
+    OString WriteOLEObject( SwOLEObj& rObject, OUString sMediaType, OUString sRelationType );
     bool lcl_CopyStream( css::uno::Reference< css::io::XInputStream> xIn, css::uno::Reference< css::io::XOutputStream > xOut );
 
     /// Writes the shape using drawingML syntax.
diff --git a/writerfilter/source/dmapper/OLEHandler.cxx b/writerfilter/source/dmapper/OLEHandler.cxx
index f9487e2..fb49aa4 100644
--- a/writerfilter/source/dmapper/OLEHandler.cxx
+++ b/writerfilter/source/dmapper/OLEHandler.cxx
@@ -20,6 +20,7 @@
 #include <PropertyMap.hxx>
 #include "GraphicHelpers.hxx"
 
+#include <editeng/unoprnms.hxx>
 #include <ooxml/resourceids.hxx>
 #include <rtl/ustring.hxx>
 #include <com/sun/star/beans/PropertyValue.hpp>
@@ -170,6 +171,48 @@ void OLEHandler::lcl_sprm(Sprm & rSprm)
 }
 
 
+void OLEHandler::saveInteropProperties( uno::Reference< text::XTextDocument > xTextDocument, OUString sObjectName )
+{
+    const OUString sGrabBagPropName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
+    const OUString sEmbeddingsPropName = "EmbeddedObjects";
+
+    // get interop grab bag from document
+    uno::Reference< beans::XPropertySet > xDocProps( xTextDocument, uno::UNO_QUERY );
+    uno::Sequence< beans::PropertyValue > aGrabBag;
+    xDocProps->getPropertyValue( sGrabBagPropName ) >>= aGrabBag;
+
+    // get EmbeddedObjects property inside grab bag
+    sal_Int32 i = 0;
+    sal_Int32 nBagLength = aGrabBag.getLength();
+    uno::Sequence< beans::PropertyValue > objectsList;
+    for( ; i < nBagLength; ++i )
+        if ( aGrabBag[i].Name == sEmbeddingsPropName )
+        {
+            aGrabBag[i].Value >>= objectsList;
+            break;
+        }
+
+    // save ProgID of current object
+    sal_Int32 length = objectsList.getLength();
+    objectsList.realloc( length + 1 );
+    objectsList[length].Name = sObjectName;
+    objectsList[length].Value = uno::Any( m_sProgId );
+
+    // put objects list back into the grab bag
+    if( i == nBagLength )
+    {
+        aGrabBag.realloc( nBagLength + 1 );
+        aGrabBag[nBagLength].Name = sEmbeddingsPropName;
+        aGrabBag[nBagLength].Value = uno::Any( objectsList );
+    }
+    else
+        aGrabBag[i].Value = uno::Any( objectsList );
+
+    // put grab bag back into the document
+    xDocProps->setPropertyValue( sGrabBagPropName, uno::Any( aGrabBag ) );
+}
+
+
 OUString OLEHandler::copyOLEOStream( uno::Reference< text::XTextDocument > xTextDocument )
 {
     OUString sRet;
@@ -202,6 +245,8 @@ OUString OLEHandler::copyOLEOStream( uno::Reference< text::XTextDocument > xText
                 }
             }
 
+            saveInteropProperties( xTextDocument, aURL );
+
             static const OUString sProtocol("vnd.sun.star.EmbeddedObject:");
             OUString aPersistName( xEmbeddedResolver->resolveEmbeddedObjectURL( aURL ) );
             sRet = aPersistName.copy( sProtocol.getLength() );
diff --git a/writerfilter/source/dmapper/OLEHandler.hxx b/writerfilter/source/dmapper/OLEHandler.hxx
index 1416a70..7a76dd0 100644
--- a/writerfilter/source/dmapper/OLEHandler.hxx
+++ b/writerfilter/source/dmapper/OLEHandler.hxx
@@ -69,6 +69,10 @@ class OLEHandler : public LoggedProperties
     virtual void lcl_attribute(Id Name, Value & val);
     virtual void lcl_sprm(Sprm & sprm);
 
+    // Interoperability
+    virtual void saveInteropProperties( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextDocument > xTextDocument,
+                                        OUString sObjectName );
+
 public:
     OLEHandler();
     virtual ~OLEHandler();
commit 72d9fa114ac103698db97ab2946ebbff66d8e21a
Author: Jacobo Aragunde Pérez <jaragunde at igalia.com>
Date:   Wed Feb 26 10:58:33 2014 +0100

    sw: code simplification
    
    XEmbeddedObject already implements XClassifiedObject which contains a
    getClassID method.
    
    Change-Id: Ifbeed343493208fff3704b21ee484fd92c570974

diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 27304ca..362c1c8 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -3506,9 +3506,7 @@ void DocxAttributeOutput::WritePostponedChart()
 bool DocxAttributeOutput::WriteOLEMath( const SdrObject*, const SwOLENode& rOLENode, const Size& )
 {
     uno::Reference < embed::XEmbeddedObject > xObj(const_cast<SwOLENode&>(rOLENode).GetOLEObj().GetOleRef());
-    sal_Int64 nAspect = rOLENode.GetAspect();
-    svt::EmbeddedObjectRef aObjRef( xObj, nAspect );
-    SvGlobalName aObjName(aObjRef->getClassID());
+    SvGlobalName aObjName(xObj->getClassID());
 
     if( !SotExchange::IsMath(aObjName) )
         return false;


More information about the Libreoffice-commits mailing list