LCOV - code coverage report
Current view: top level - writerfilter/source/dmapper - OLEHandler.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 136 138 98.6 %
Date: 2015-06-13 12:38:46 Functions: 9 9 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : #include <OLEHandler.hxx>
      20             : #include <DomainMapper.hxx>
      21             : #include <PropertyMap.hxx>
      22             : #include "GraphicHelpers.hxx"
      23             : 
      24             : #include <editeng/unoprnms.hxx>
      25             : #include <ooxml/resourceids.hxx>
      26             : #include <rtl/ustring.hxx>
      27             : #include <osl/diagnose.h>
      28             : #include <unotools/mediadescriptor.hxx>
      29             : #include <officecfg/Office/Common.hxx>
      30             : #include <com/sun/star/beans/PropertyValue.hpp>
      31             : #include <com/sun/star/container/XNameAccess.hpp>
      32             : #include <com/sun/star/document/XEmbeddedObjectResolver.hpp>
      33             : #include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
      34             : #include <com/sun/star/document/XFilter.hpp>
      35             : #include <com/sun/star/document/XImporter.hpp>
      36             : #include <com/sun/star/document/XStorageBasedDocument.hpp>
      37             : #include <com/sun/star/drawing/XShape.hpp>
      38             : #include <com/sun/star/embed/XEmbeddedObject.hpp>
      39             : #include <com/sun/star/embed/XEmbedObjectCreator.hpp>
      40             : #include <com/sun/star/graphic/XGraphic.hpp>
      41             : #include <com/sun/star/io/XStream.hpp>
      42             : #include <com/sun/star/lang/XComponent.hpp>
      43             : #include <com/sun/star/lang/XInitialization.hpp>
      44             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      45             : #include <com/sun/star/text/XTextDocument.hpp>
      46             : #include <com/sun/star/uno/XComponentContext.hpp>
      47             : 
      48             : namespace writerfilter {
      49             : namespace dmapper {
      50             : 
      51             : using namespace ::com::sun::star;
      52             : 
      53             : 
      54         299 : OLEHandler::OLEHandler(DomainMapper& rDomainMapper) :
      55             : LoggedProperties("OLEHandler"),
      56             : m_nDxaOrig(0),
      57             : m_nDyaOrig(0),
      58             :     m_nWrapMode(1),
      59         299 :     m_rDomainMapper(rDomainMapper)
      60             : {
      61         299 : }
      62             : 
      63             : 
      64         598 : OLEHandler::~OLEHandler()
      65             : {
      66         598 : }
      67             : 
      68             : 
      69         794 : void OLEHandler::lcl_attribute(Id rName, Value & rVal)
      70             : {
      71         794 :     OUString sStringValue = rVal.getString();
      72             :     (void)rName;
      73         794 :     switch( rName )
      74             :     {
      75             :         case NS_ooxml::LN_CT_OLEObject_Type:
      76          54 :             m_sObjectType = sStringValue;
      77          54 :         break;
      78             :         case NS_ooxml::LN_CT_OLEObject_ProgID:
      79          57 :             m_sProgId = sStringValue;
      80          57 :         break;
      81             :         case NS_ooxml::LN_CT_OLEObject_ShapeID:
      82          54 :             m_sShapeId = sStringValue;
      83          54 :         break;
      84             :         case NS_ooxml::LN_CT_OLEObject_DrawAspect:
      85          54 :             m_sDrawAspect = sStringValue;
      86          54 :         break;
      87             :         case NS_ooxml::LN_CT_OLEObject_ObjectID:
      88          54 :             m_sObjectId = sStringValue;
      89          54 :         break;
      90             :         case NS_ooxml::LN_CT_OLEObject_r_id:
      91          54 :             m_sr_id = sStringValue;
      92          54 :         break;
      93             :         case NS_ooxml::LN_inputstream:
      94          57 :             rVal.getAny() >>= m_xInputStream;
      95          57 :         break;
      96             :         case NS_ooxml::LN_CT_Object_dxaOrig:
      97          58 :             m_nDxaOrig = rVal.getInt();
      98          58 :         break;
      99             :         case NS_ooxml::LN_CT_Object_dyaOrig:
     100          58 :             m_nDyaOrig = rVal.getInt();
     101          58 :         break;
     102             :         case NS_ooxml::LN_shape:
     103             :         {
     104         294 :             uno::Reference< drawing::XShape > xTempShape;
     105         294 :             rVal.getAny() >>= xTempShape;
     106         294 :             if( xTempShape.is() )
     107             :             {
     108         294 :                 m_xShape.set( xTempShape );
     109         294 :                 uno::Reference< beans::XPropertySet > xShapeProps( xTempShape, uno::UNO_QUERY );
     110         294 :                 PropertyNameSupplier& rNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
     111             : 
     112             :                 try
     113             :                 {
     114             :                     // Shapes in the header or footer should be in the background.
     115         294 :                     if (m_rDomainMapper.IsInHeaderFooter())
     116          83 :                         xShapeProps->setPropertyValue("Opaque", uno::makeAny(false));
     117             : 
     118         294 :                     m_aShapeSize = xTempShape->getSize();
     119         294 :                     m_aShapePosition = xTempShape->getPosition();
     120             : 
     121         219 :                     xShapeProps->getPropertyValue( rNameSupplier.GetName( PROP_BITMAP ) ) >>= m_xReplacement;
     122             :                 }
     123          75 :                 catch( const uno::Exception& e )
     124             :                 {
     125             :                     SAL_WARN("writerfilter", "Exception in OLE Handler: " << e.Message);
     126         294 :                 }
     127             :                 // No need to set the wrapping here as it's either set in oox or will be set later
     128         294 :             }
     129             :         }
     130         294 :         break;
     131             :         default:
     132             :             OSL_FAIL( "unknown attribute");
     133         794 :     }
     134         794 : }
     135             : 
     136             : 
     137         114 : void OLEHandler::lcl_sprm(Sprm & rSprm)
     138             : {
     139         114 :     sal_uInt32 nSprmId = rSprm.getId();
     140         114 :     switch( nSprmId )
     141             :     {
     142             :         case NS_ooxml::LN_OLEObject_OLEObject:
     143             :         {
     144          57 :             writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
     145          57 :             if( pProperties.get())
     146             :             {
     147          57 :                 pProperties->resolve(*this);
     148          57 :             }
     149             :         }
     150          57 :         break;
     151             :         case NS_ooxml::LN_wrap_wrap:
     152             :         {
     153          37 :             writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
     154          37 :             if ( pProperties.get( ) )
     155             :             {
     156          37 :                 WrapHandlerPtr pHandler( new WrapHandler );
     157          37 :                 pProperties->resolve( *pHandler );
     158             : 
     159          37 :                 m_nWrapMode = pHandler->getWrapMode( );
     160             : 
     161             :                 try
     162             :                 {
     163          37 :                     uno::Reference< beans::XPropertySet > xShapeProps( m_xShape, uno::UNO_QUERY_THROW );
     164          37 :                     PropertyNameSupplier& rNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
     165             : 
     166          37 :                     xShapeProps->setPropertyValue(
     167             :                         rNameSupplier.GetName( PROP_SURROUND ),
     168          37 :                         uno::makeAny( m_nWrapMode ) );
     169             :                 }
     170           0 :                 catch( const uno::Exception& e )
     171             :                 {
     172             :                     SAL_WARN("writerfilter", "Exception in OLE Handler: " << e.Message);
     173          37 :                 }
     174          37 :             }
     175             :         }
     176          37 :         break;
     177             :         default:
     178             :         {
     179             :             OSL_FAIL( "unknown attribute");
     180             :         }
     181             :     }
     182         114 : }
     183             : 
     184             : 
     185          60 : void OLEHandler::saveInteropProperties(uno::Reference<text::XTextDocument> const& xTextDocument, const OUString& sObjectName, const OUString& sOldObjectName)
     186             : {
     187             :     static const char sEmbeddingsPropName[] = "EmbeddedObjects";
     188             : 
     189             :     // get interop grab bag from document
     190          60 :     uno::Reference< beans::XPropertySet > xDocProps( xTextDocument, uno::UNO_QUERY );
     191         120 :     comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG));
     192             : 
     193             :     // get EmbeddedObjects property inside grab bag
     194         120 :     comphelper::SequenceAsHashMap objectsList;
     195          60 :     if (aGrabBag.find(sEmbeddingsPropName) != aGrabBag.end())
     196          13 :         objectsList << aGrabBag[sEmbeddingsPropName];
     197             : 
     198         120 :     uno::Sequence< beans::PropertyValue > aGrabBagAttribute(2);
     199          60 :     aGrabBagAttribute[0].Name = "ProgID";
     200          60 :     aGrabBagAttribute[0].Value = uno::Any( m_sProgId );
     201          60 :     aGrabBagAttribute[1].Name = "DrawAspect";
     202          60 :     aGrabBagAttribute[1].Value = uno::Any( m_sDrawAspect );
     203             : 
     204             :     // If we got an "old name", erase that first.
     205          60 :     if (!sOldObjectName.isEmpty())
     206             :     {
     207           5 :         comphelper::SequenceAsHashMap::iterator it = objectsList.find(sOldObjectName);
     208           5 :         if (it != objectsList.end())
     209           5 :             objectsList.erase(it);
     210             :     }
     211             : 
     212          60 :     objectsList[sObjectName] = uno::Any( aGrabBagAttribute );
     213             : 
     214             :     // put objects list back into the grab bag
     215          60 :     aGrabBag[sEmbeddingsPropName] = uno::Any(objectsList.getAsConstPropertyValueList());
     216             : 
     217             :     // put grab bag back into the document
     218         120 :     xDocProps->setPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG, uno::Any(aGrabBag.getAsConstPropertyValueList()));
     219          60 : }
     220             : 
     221           5 : void OLEHandler::importStream(uno::Reference<uno::XComponentContext> xComponentContext, uno::Reference<text::XTextDocument> xTextDocument, uno::Reference<text::XTextContent> xOLE)
     222             : {
     223           5 :     OUString aFilterService;
     224           5 :     if (m_sProgId == "Word.Document.12")
     225           3 :         aFilterService = "com.sun.star.comp.Writer.WriterFilter";
     226           2 :     else if (m_sProgId == "Equation.3")
     227           2 :         aFilterService = "com.sun.star.comp.Math.MathTypeFilter";
     228             :     else
     229             :         SAL_WARN("writerfilter", "OLEHandler::importStream: unhandled m_sProgId: " << m_sProgId);
     230             : 
     231           5 :     if (!m_xInputStream.is() || aFilterService.isEmpty())
     232           5 :         return;
     233             : 
     234             :     // Create the filter service.
     235          10 :     uno::Reference<uno::XInterface> xInterface = xComponentContext->getServiceManager()->createInstanceWithContext(aFilterService, xComponentContext);
     236             : 
     237             :     // Set target document.
     238          10 :     uno::Reference<document::XImporter> xImporter(xInterface, uno::UNO_QUERY);
     239          10 :     uno::Reference<document::XEmbeddedObjectSupplier> xSupplier(xOLE, uno::UNO_QUERY);
     240          10 :     uno::Reference<lang::XComponent> xEmbeddedObject(xSupplier->getEmbeddedObject(), uno::UNO_QUERY);
     241           5 :     xImporter->setTargetDocument( xEmbeddedObject );
     242             : 
     243             :     // Import the input stream.
     244          10 :     utl::MediaDescriptor aMediaDescriptor;
     245           5 :     aMediaDescriptor["InputStream"] <<= m_xInputStream;
     246          10 :     uno::Reference<document::XFilter> xFilter(xInterface, uno::UNO_QUERY);
     247           5 :     xFilter->filter(aMediaDescriptor.getAsConstPropertyValueList());
     248             : 
     249             :     // Now that the data is imported, update the (typically) changed stream name.
     250          10 :     uno::Reference<beans::XPropertySet> xPropertySet(xOLE, uno::UNO_QUERY);
     251          10 :     saveInteropProperties(xTextDocument, xPropertySet->getPropertyValue("StreamName").get<OUString>(), m_aURL);
     252             : }
     253             : 
     254          55 : OUString OLEHandler::getCLSID(uno::Reference<uno::XComponentContext> xComponentContext) const
     255             : {
     256          55 :     OUString aRet;
     257             : 
     258             :     // See officecfg/registry/data/org/openoffice/Office/Embedding.xcu.
     259          55 :     if (m_sProgId == "Word.Document.12")
     260             :     {
     261           3 :         if (officecfg::Office::Common::Filter::Microsoft::Import::WinWordToWriter::get(xComponentContext))
     262           3 :             aRet = "8BC6B165-B1B2-4EDD-aa47-dae2ee689dd6";
     263             :     }
     264          52 :     else if (m_sProgId == "Equation.3")
     265             :     {
     266           5 :         if (officecfg::Office::Common::Filter::Microsoft::Import::MathTypeToMath::get(xComponentContext))
     267           2 :             aRet = "078B7ABA-54FC-457F-8551-6147E776A997";
     268             :     }
     269             :     else
     270             :         SAL_WARN("writerfilter", "OLEHandler::getCLSID: unhandled m_sProgId: " << m_sProgId);
     271             : 
     272          55 :     return aRet;
     273             : }
     274             : 
     275          57 : OUString OLEHandler::copyOLEOStream(
     276             :         uno::Reference<text::XTextDocument> const& xTextDocument)
     277             : {
     278          57 :     OUString sRet;
     279          57 :     if( !m_xInputStream.is( ) )
     280           0 :         return sRet;
     281             :     try
     282             :     {
     283          57 :         uno::Reference < lang::XMultiServiceFactory > xFactory(xTextDocument, uno::UNO_QUERY_THROW);
     284             :         uno::Reference< document::XEmbeddedObjectResolver > xEmbeddedResolver(
     285         110 :             xFactory->createInstance("com.sun.star.document.ImportEmbeddedObjectResolver"), uno::UNO_QUERY_THROW );
     286             :         //hack to work with the ImportEmbeddedObjectResolver
     287             :         static sal_Int32 nObjectCount = 100;
     288         110 :         uno::Reference< container::XNameAccess > xNA( xEmbeddedResolver, uno::UNO_QUERY_THROW );
     289         110 :         OUString aURL("Obj");
     290          55 :         aURL += OUString::number( nObjectCount++ );
     291         110 :         uno::Reference < io::XOutputStream > xOLEStream;
     292          55 :         if( (xNA->getByName( aURL ) >>= xOLEStream) && xOLEStream.is() )
     293             :         {
     294          55 :             const sal_Int32 nReadRequest = 0x1000;
     295          55 :             uno::Sequence< sal_Int8 > aData;
     296             : 
     297             :             while( true )
     298             :             {
     299         468 :                 sal_Int32 nRead = m_xInputStream->readBytes( aData, nReadRequest );
     300         468 :                 xOLEStream->writeBytes( aData );
     301         468 :                 if( nRead < nReadRequest )
     302             :                 {
     303          55 :                     xOLEStream->closeOutput();
     304          55 :                     break;
     305             :                 }
     306             :             }
     307             : 
     308          55 :             saveInteropProperties( xTextDocument, aURL );
     309             : 
     310             :             static const char sProtocol[] = "vnd.sun.star.EmbeddedObject:";
     311         110 :             OUString aPersistName( xEmbeddedResolver->resolveEmbeddedObjectURL( aURL ) );
     312         110 :             sRet = aPersistName.copy( strlen(sProtocol) );
     313             : 
     314             :         }
     315         110 :         uno::Reference< lang::XComponent > xComp( xEmbeddedResolver, uno::UNO_QUERY_THROW );
     316          55 :         xComp->dispose();
     317         110 :         m_aURL = aURL;
     318             :     }
     319           2 :     catch( const uno::Exception& )
     320             :     {
     321             :         OSL_FAIL("exception in OLEHandler::createOLEObject");
     322             :     }
     323          57 :     return sRet;
     324             : }
     325             : 
     326             : } //namespace dmapper
     327             : } //namespace writerfilter
     328             : 
     329             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11