[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - 2 commits - include/oox oox/source writerfilter/source

Michael Stahl mstahl at redhat.com
Tue Jan 12 01:00:43 PST 2016


 include/oox/ole/oleobjecthelper.hxx        |   10 ++++-
 oox/source/core/filterbase.cxx             |    2 -
 oox/source/export/shapes.cxx               |   49 +++++++++++++++++++++++-
 oox/source/ole/oleobjecthelper.cxx         |   58 +++++++++++++++++++++++++++--
 writerfilter/source/dmapper/OLEHandler.cxx |   44 ++--------------------
 writerfilter/source/dmapper/OLEHandler.hxx |    5 --
 6 files changed, 117 insertions(+), 51 deletions(-)

New commits:
commit 10822ce0629ffbef58381ba6f42f0f0f2e2d6f4c
Author: Michael Stahl <mstahl at redhat.com>
Date:   Sat Dec 19 23:55:34 2015 +0100

    oox: save ProgId on import, and use it in ShapeExport::WriteOLE2Shape()
    
    Uses the same approach as DOCX import to preserve the ProgID; it would
    be much better if the MediaType of the stream were preserved instead and
    the other things derived from that, but this here was rather quick to do...
    
    This makes the round-tripping of OOXML OLEs in PPTX work again, which
    was broken by an earlier commit.
    
    Change-Id: Ic7d0362f0c14bf0e522185713666bcd58db2cf64
    (cherry picked from commit d60398ff5b42ff77a4002dcd13b7fb8c9a73eade)
    Reviewed-on: https://gerrit.libreoffice.org/21352
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/include/oox/ole/oleobjecthelper.hxx b/include/oox/ole/oleobjecthelper.hxx
index febd097..35e16b0 100644
--- a/include/oox/ole/oleobjecthelper.hxx
+++ b/include/oox/ole/oleobjecthelper.hxx
@@ -57,7 +57,8 @@ class OleObjectHelper
 {
 public:
     explicit            OleObjectHelper(
-                            const css::uno::Reference< css::lang::XMultiServiceFactory >& rxModelFactory );
+                            const css::uno::Reference<css::lang::XMultiServiceFactory>& rxModelFactory,
+                            const css::uno::Reference<css::frame::XModel>& xModel);
                         ~OleObjectHelper();
 
     bool                importOleObject(
@@ -66,6 +67,7 @@ public:
                             const css::awt::Size& rObjSize );
 
 private:
+    css::uno::Reference<css::frame::XModel> m_xModel;
     css::uno::Reference< css::document::XEmbeddedObjectResolver > mxResolver;
     const OUString                                                maEmbeddedObjScheme;
     sal_Int32                                                     mnObjectId;
diff --git a/oox/source/core/filterbase.cxx b/oox/source/core/filterbase.cxx
index 9c7383a..3fefcc0 100644
--- a/oox/source/core/filterbase.cxx
+++ b/oox/source/core/filterbase.cxx
@@ -366,7 +366,7 @@ ModelObjectHelper& FilterBase::getModelObjectHelper() const
 OleObjectHelper& FilterBase::getOleObjectHelper() const
 {
     if( !mxImpl->mxOleObjHelper )
-        mxImpl->mxOleObjHelper.reset( new OleObjectHelper( mxImpl->mxModelFactory ) );
+        mxImpl->mxOleObjHelper.reset(new OleObjectHelper(mxImpl->mxModelFactory, mxImpl->mxModel));
     return *mxImpl->mxOleObjHelper;
 }
 
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index 0c087e8..db6ec66 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -316,7 +316,7 @@ uno::Reference<io::XInputStream> GetOLEObjectStream(
         {
             lcl_ConvertProgID(i_rProgID, o_rMediaType, o_rRelationType, o_rSuffix);
             xInStream = xParentStorage->cloneStreamElement(entryName)->getInputStream();
-            // TODO: is it possible to take the sMediaType from the stream?
+            // TODO: make it possible to take the sMediaType from the stream
         }
         else // the object is ODF - either the whole document is
         {    // ODF, or the OLE was edited so it was converted to ODF
@@ -1609,6 +1609,44 @@ ShapeExport& ShapeExport::WriteOLE2Shape( Reference< XShape > xShape )
                 uno::Reference<embed::XEmbeddedObject> const xObj(
                     xPropSet->getPropertyValue("EmbeddedObject"), uno::UNO_QUERY);
 
+                uno::Reference<beans::XPropertySet> const xParent(
+                    uno::Reference<container::XChild>(xObj, uno::UNO_QUERY)->getParent(),
+                    uno::UNO_QUERY);
+
+                uno::Sequence<beans::PropertyValue> grabBag;
+                xParent->getPropertyValue("InteropGrabBag") >>= grabBag;
+
+                OUString const entryName(
+                    uno::Reference<embed::XEmbedPersist>(xObj, uno::UNO_QUERY)->getEntryName());
+                OUString progID;
+
+                for (auto const& it : grabBag)
+                {
+                    if (it.Name == "EmbeddedObjects")
+                    {
+                        uno::Sequence<beans::PropertyValue> objects;
+                        it.Value >>= objects;
+                        for (auto const& object : objects)
+                        {
+                            if (object.Name == entryName)
+                            {
+                                uno::Sequence<beans::PropertyValue> props;
+                                object.Value >>= props;
+                                for (auto const& prop : props)
+                                {
+                                    if (prop.Name == "ProgID")
+                                    {
+                                        prop.Value >>= progID;
+                                        break;
+                                    }
+                                }
+                                break;
+                            }
+                        }
+                        break;
+                    }
+                }
+
                 OUString sMediaType;
                 OUString sRelationType;
                 OUString sSuffix;
@@ -1616,7 +1654,7 @@ ShapeExport& ShapeExport::WriteOLE2Shape( Reference< XShape > xShape )
 
                 uno::Reference<io::XInputStream> const xInStream =
                     oox::GetOLEObjectStream(
-                        mpFB->getComponentContext(), xObj, OUString(),
+                        mpFB->getComponentContext(), xObj, progID,
                         sMediaType, sRelationType, sSuffix, pProgID);
 
                 if (!xInStream.is())
@@ -1624,6 +1662,13 @@ ShapeExport& ShapeExport::WriteOLE2Shape( Reference< XShape > xShape )
                     return *this;
                 }
 
+                OString anotherProgID;
+                if (!pProgID && !progID.isEmpty())
+                {
+                    anotherProgID = OUStringToOString(progID, RTL_TEXTENCODING_UTF8);
+                    pProgID = anotherProgID.getStr();
+                }
+
                 assert(!sMediaType.isEmpty());
                 assert(!sRelationType.isEmpty());
                 assert(!sSuffix.isEmpty());
diff --git a/oox/source/ole/oleobjecthelper.cxx b/oox/source/ole/oleobjecthelper.cxx
index 5e6c057..12356c3 100644
--- a/oox/source/ole/oleobjecthelper.cxx
+++ b/oox/source/ole/oleobjecthelper.cxx
@@ -49,10 +49,14 @@ OleObjectInfo::OleObjectInfo() :
 {
 }
 
-OleObjectHelper::OleObjectHelper( const Reference< XMultiServiceFactory >& rxModelFactory ) :
-    maEmbeddedObjScheme( "vnd.sun.star.EmbeddedObject:" ),
-    mnObjectId( 100 )
+OleObjectHelper::OleObjectHelper(
+        const Reference< XMultiServiceFactory >& rxModelFactory,
+        uno::Reference<frame::XModel> const& xModel)
+    : m_xModel(xModel)
+    , maEmbeddedObjScheme("vnd.sun.star.EmbeddedObject:")
+    , mnObjectId( 100 )
 {
+    assert(m_xModel.is());
     if( rxModelFactory.is() ) try
     {
         mxResolver.set( rxModelFactory->createInstance( "com.sun.star.document.ImportEmbeddedObjectResolver" ), UNO_QUERY );
@@ -74,6 +78,10 @@ OleObjectHelper::~OleObjectHelper()
     }
 }
 
+// TODO: this is probably a sub-optimal approach: ideally the media type
+// of the stream from [Content_Types].xml should be stored somewhere for this
+// purpose, but currently the media type of all OLE streams in the storage is
+// just "application/vnd.sun.star.oleobject"
 void SaveInteropProperties(uno::Reference<frame::XModel> const& xModel,
        OUString const& rObjectName, OUString const*const pOldObjectName,
        OUString const& rProgId, OUString const& rDrawAspect)
@@ -137,6 +145,10 @@ bool OleObjectHelper::importOleObject( PropertyMap& rPropMap, const OleObjectInf
             xOutStrm->writeBytes( rOleObject.maEmbeddedData );
             xOutStrm->closeOutput();
 
+            SaveInteropProperties(m_xModel, aObjectId, nullptr,
+                rOleObject.maProgId,
+                rOleObject.mbShowAsIcon ? OUString("Icon") : OUString("Content"));
+
             OUString aUrl = mxResolver->resolveEmbeddedObjectURL( aObjectId );
             OSL_ENSURE( aUrl.match( maEmbeddedObjScheme ), "OleObjectHelper::importOleObject - unexpected URL scheme" );
             OUString aPersistName = aUrl.copy( maEmbeddedObjScheme.getLength() );
commit df321f828b4dac343cc520ecb2d722f75c52efb7
Author: Michael Stahl <mstahl at redhat.com>
Date:   Sat Dec 19 23:29:17 2015 +0100

    move saveInteropProperties from writerfilter to oox
    
    Change-Id: I4f9769ad496198d2d002775dee4ee0a2f08d6f3b
    (cherry picked from commit 9d0d41f0f3c5215770bc7246a089d54a7244df55)
    Reviewed-on: https://gerrit.libreoffice.org/21351
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/include/oox/ole/oleobjecthelper.hxx b/include/oox/ole/oleobjecthelper.hxx
index 868cd0c..febd097 100644
--- a/include/oox/ole/oleobjecthelper.hxx
+++ b/include/oox/ole/oleobjecthelper.hxx
@@ -26,6 +26,7 @@
 namespace com { namespace sun { namespace star {
     namespace awt { struct Size; }
     namespace document { class XEmbeddedObjectResolver; }
+    namespace frame { class XModel; }
     namespace lang { class XMultiServiceFactory; }
 } } }
 
@@ -71,6 +72,11 @@ private:
 };
 
 
+OOX_DLLPUBLIC void SaveInteropProperties(
+       css::uno::Reference<css::frame::XModel> const& xModel,
+       OUString const& rObjectName, OUString const* pOldObjectName,
+       OUString const& rProgId, OUString const& rDrawAspect);
+
 
 } // namespace ole
 } // namespace oox
diff --git a/oox/source/ole/oleobjecthelper.cxx b/oox/source/ole/oleobjecthelper.cxx
index f5d4df4..5e6c057 100644
--- a/oox/source/ole/oleobjecthelper.cxx
+++ b/oox/source/ole/oleobjecthelper.cxx
@@ -21,6 +21,7 @@
 
 #include <com/sun/star/awt/Rectangle.hpp>
 #include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/container/XNameAccess.hpp>
 #include <com/sun/star/document/XEmbeddedObjectResolver.hpp>
 #include <com/sun/star/embed/Aspects.hpp>
@@ -28,6 +29,7 @@
 #include <com/sun/star/lang/XComponent.hpp>
 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
 #include <osl/diagnose.h>
+#include <comphelper/sequenceashashmap.hxx>
 #include "oox/helper/propertymap.hxx"
 
 namespace oox {
@@ -72,6 +74,44 @@ OleObjectHelper::~OleObjectHelper()
     }
 }
 
+void SaveInteropProperties(uno::Reference<frame::XModel> const& xModel,
+       OUString const& rObjectName, OUString const*const pOldObjectName,
+       OUString const& rProgId, OUString const& rDrawAspect)
+{
+    static const char sEmbeddingsPropName[] = "EmbeddedObjects";
+
+    // get interop grab bag from document
+    uno::Reference<beans::XPropertySet> const xDocProps(xModel, uno::UNO_QUERY);
+    comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue("InteropGrabBag"));
+
+    // get EmbeddedObjects property inside grab bag
+    comphelper::SequenceAsHashMap objectsList;
+    if (aGrabBag.find(sEmbeddingsPropName) != aGrabBag.end())
+        objectsList << aGrabBag[sEmbeddingsPropName];
+
+    uno::Sequence< beans::PropertyValue > aGrabBagAttribute(2);
+    aGrabBagAttribute[0].Name = "ProgID";
+    aGrabBagAttribute[0].Value <<= rProgId;
+    aGrabBagAttribute[1].Name = "DrawAspect";
+    aGrabBagAttribute[1].Value <<= rDrawAspect;
+
+    // If we got an "old name", erase that first.
+    if (pOldObjectName)
+    {
+        comphelper::SequenceAsHashMap::iterator it = objectsList.find(*pOldObjectName);
+        if (it != objectsList.end())
+            objectsList.erase(it);
+    }
+
+    objectsList[rObjectName] = uno::Any( aGrabBagAttribute );
+
+    // put objects list back into the grab bag
+    aGrabBag[sEmbeddingsPropName] = uno::Any(objectsList.getAsConstPropertyValueList());
+
+    // put grab bag back into the document
+    xDocProps->setPropertyValue("InteropGrabBag", uno::Any(aGrabBag.getAsConstPropertyValueList()));
+}
+
 bool OleObjectHelper::importOleObject( PropertyMap& rPropMap, const OleObjectInfo& rOleObject, const awt::Size& rObjSize )
 {
     bool bRet = false;
diff --git a/writerfilter/source/dmapper/OLEHandler.cxx b/writerfilter/source/dmapper/OLEHandler.cxx
index d282c7b..0fe0955 100644
--- a/writerfilter/source/dmapper/OLEHandler.cxx
+++ b/writerfilter/source/dmapper/OLEHandler.cxx
@@ -22,6 +22,7 @@
 #include "GraphicHelpers.hxx"
 
 #include <editeng/unoprnms.hxx>
+#include <oox/ole/oleobjecthelper.hxx>
 #include <ooxml/resourceids.hxx>
 #include <rtl/ustring.hxx>
 #include <osl/diagnose.h>
@@ -179,43 +180,6 @@ void OLEHandler::lcl_sprm(Sprm & rSprm)
     }
 }
 
-
-void OLEHandler::saveInteropProperties(uno::Reference<text::XTextDocument> const& xTextDocument, const OUString& sObjectName, const OUString& sOldObjectName)
-{
-    static const char sEmbeddingsPropName[] = "EmbeddedObjects";
-
-    // get interop grab bag from document
-    uno::Reference< beans::XPropertySet > xDocProps( xTextDocument, uno::UNO_QUERY );
-    comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG));
-
-    // get EmbeddedObjects property inside grab bag
-    comphelper::SequenceAsHashMap objectsList;
-    if (aGrabBag.find(sEmbeddingsPropName) != aGrabBag.end())
-        objectsList << aGrabBag[sEmbeddingsPropName];
-
-    uno::Sequence< beans::PropertyValue > aGrabBagAttribute(2);
-    aGrabBagAttribute[0].Name = "ProgID";
-    aGrabBagAttribute[0].Value = uno::Any( m_sProgId );
-    aGrabBagAttribute[1].Name = "DrawAspect";
-    aGrabBagAttribute[1].Value = uno::Any( m_sDrawAspect );
-
-    // If we got an "old name", erase that first.
-    if (!sOldObjectName.isEmpty())
-    {
-        comphelper::SequenceAsHashMap::iterator it = objectsList.find(sOldObjectName);
-        if (it != objectsList.end())
-            objectsList.erase(it);
-    }
-
-    objectsList[sObjectName] = uno::Any( aGrabBagAttribute );
-
-    // put objects list back into the grab bag
-    aGrabBag[sEmbeddingsPropName] = uno::Any(objectsList.getAsConstPropertyValueList());
-
-    // put grab bag back into the document
-    xDocProps->setPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG, uno::Any(aGrabBag.getAsConstPropertyValueList()));
-}
-
 void OLEHandler::importStream(uno::Reference<uno::XComponentContext> xComponentContext, uno::Reference<text::XTextDocument> xTextDocument, uno::Reference<text::XTextContent> xOLE)
 {
     OUString aFilterService;
@@ -248,7 +212,9 @@ void OLEHandler::importStream(uno::Reference<uno::XComponentContext> xComponentC
 
     // Now that the data is imported, update the (typically) changed stream name.
     uno::Reference<beans::XPropertySet> xPropertySet(xOLE, uno::UNO_QUERY);
-    saveInteropProperties(xTextDocument, xPropertySet->getPropertyValue("StreamName").get<OUString>(), m_aURL);
+    ::oox::ole::SaveInteropProperties(xTextDocument,
+        xPropertySet->getPropertyValue("StreamName").get<OUString>(), &m_aURL,
+        m_sProgId, m_sDrawAspect);
 }
 
 OUString OLEHandler::getCLSID(uno::Reference<uno::XComponentContext> xComponentContext) const
@@ -305,7 +271,7 @@ OUString OLEHandler::copyOLEOStream(
                 }
             }
 
-            saveInteropProperties( xTextDocument, aURL );
+            ::oox::ole::SaveInteropProperties(xTextDocument, aURL, nullptr, m_sProgId, m_sDrawAspect);
 
             static const char sProtocol[] = "vnd.sun.star.EmbeddedObject:";
             OUString aPersistName( xEmbeddedResolver->resolveEmbeddedObjectURL( aURL ) );
diff --git a/writerfilter/source/dmapper/OLEHandler.hxx b/writerfilter/source/dmapper/OLEHandler.hxx
index 8e2cb13..8d6fbd6 100644
--- a/writerfilter/source/dmapper/OLEHandler.hxx
+++ b/writerfilter/source/dmapper/OLEHandler.hxx
@@ -76,11 +76,6 @@ class OLEHandler : public LoggedProperties
     virtual void lcl_attribute(Id Name, Value & val) override;
     virtual void lcl_sprm(Sprm & sprm) override;
 
-    // Interoperability
-    void saveInteropProperties(css::uno::Reference<css::text::XTextDocument> const& xTextDocument,
-                                        const OUString& sObjectName,
-                                        const OUString& sOldObjectName = OUString());
-
 public:
     OLEHandler(DomainMapper& rDomainMapper);
     virtual ~OLEHandler();


More information about the Libreoffice-commits mailing list