LCOV - code coverage report
Current view: top level - libreoffice/filter/source/msfilter - msoleexp.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 134 0.0 %
Date: 2012-12-27 Functions: 0 5 0.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             : 
      20             : #include <com/sun/star/uno/Reference.hxx>
      21             : #include <com/sun/star/uno/Sequence.hxx>
      22             : #include <com/sun/star/uno/Any.hxx>
      23             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      24             : #include <com/sun/star/configuration/theDefaultProvider.hpp>
      25             : #include <com/sun/star/container/XNameAccess.hpp>
      26             : #include <com/sun/star/embed/XEmbedPersist.hpp>
      27             : #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
      28             : #include <com/sun/star/embed/EmbedStates.hpp>
      29             : #include <com/sun/star/frame/XStorable.hpp>
      30             : #include <com/sun/star/awt/Size.hpp>
      31             : #include <com/sun/star/embed/Aspects.hpp>
      32             : #include <sot/clsids.hxx>
      33             : #include <sfx2/objsh.hxx>
      34             : #include <sfx2/docfac.hxx>
      35             : #include <sfx2/docfilt.hxx>
      36             : #include <sfx2/docfile.hxx>
      37             : #include <sfx2/fcontnr.hxx>
      38             : #include <sot/formats.hxx>
      39             : #include <comphelper/processfactory.hxx>
      40             : #include <unotools/streamwrap.hxx>
      41             : #include <comphelper/storagehelper.hxx>
      42             : #include <svtools/embedhlp.hxx>
      43             : #include <filter/msfilter/msdffimp.hxx> // extern sichtbare Header-Datei
      44             : 
      45             : #include "filter/msfilter/msoleexp.hxx"
      46             : 
      47             : using namespace ::com::sun::star;
      48             : 
      49           0 : SvGlobalName GetEmbeddedVersion( const SvGlobalName& aAppName )
      50             : {
      51           0 :     if ( aAppName == SvGlobalName( SO3_SM_CLASSID_60 ) )
      52           0 :             return SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 );
      53           0 :     else if ( aAppName == SvGlobalName( SO3_SW_CLASSID_60 ) )
      54           0 :             return SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 );
      55           0 :     else if ( aAppName == SvGlobalName( SO3_SC_CLASSID_60 ) )
      56           0 :             return SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 );
      57           0 :     else if ( aAppName == SvGlobalName( SO3_SDRAW_CLASSID_60 ) )
      58           0 :             return SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 );
      59           0 :     else if ( aAppName == SvGlobalName( SO3_SIMPRESS_CLASSID_60 ) )
      60           0 :             return SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 );
      61           0 :     else if ( aAppName == SvGlobalName( SO3_SCH_CLASSID_60 ) )
      62           0 :             return SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 );
      63             : 
      64           0 :     return SvGlobalName();
      65             : }
      66             : 
      67           0 : String GetStorageType( const SvGlobalName& aEmbName )
      68             : {
      69           0 :     if ( aEmbName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) )
      70           0 :         return rtl::OUString("LibreOffice.MathDocument.1");
      71           0 :     else if ( aEmbName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) )
      72           0 :         return rtl::OUString("LibreOffice.WriterDocument.1");
      73           0 :     else if ( aEmbName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) )
      74           0 :         return rtl::OUString("LibreOffice.CalcDocument.1");
      75           0 :     else if ( aEmbName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) )
      76           0 :         return rtl::OUString("LibreOffice.DrawDocument.1");
      77           0 :     else if ( aEmbName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) )
      78           0 :         return rtl::OUString("LibreOffice.ImpressDocument.1");
      79           0 :     else if ( aEmbName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) )
      80           0 :         return rtl::OUString("LibreOffice.ChartDocument.1");
      81           0 :     return rtl::OUString();
      82             : }
      83             : 
      84           0 : sal_Bool UseOldMSExport()
      85             : {
      86             :     uno::Reference< lang::XMultiServiceFactory > xProvider(
      87             :         configuration::theDefaultProvider::get(
      88           0 :             comphelper::getProcessComponentContext()));
      89             :     try {
      90           0 :         uno::Sequence< uno::Any > aArg( 1 );
      91           0 :         aArg[0] <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common/InternalMSExport") );
      92             :         uno::Reference< container::XNameAccess > xNameAccess(
      93           0 :             xProvider->createInstanceWithArguments(
      94             :                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) ),
      95           0 :                 aArg ),
      96           0 :             uno::UNO_QUERY );
      97           0 :         if ( xNameAccess.is() )
      98             :         {
      99           0 :             uno::Any aResult = xNameAccess->getByName(
     100           0 :                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseOldExport" ) ) );
     101             : 
     102           0 :             sal_Bool bResult = sal_Bool();
     103           0 :             if ( aResult >>= bResult )
     104           0 :                 return bResult;
     105           0 :         }
     106             :     }
     107           0 :     catch( const uno::Exception& )
     108             :     {
     109             :     }
     110             : 
     111             :     OSL_FAIL( "Could not get access to configuration entry!\n" );
     112           0 :     return sal_False;
     113             : }
     114             : 
     115           0 : void SvxMSExportOLEObjects::ExportOLEObject( const com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject>& rObj, SotStorage& rDestStg )
     116             : {
     117           0 :     svt::EmbeddedObjectRef aObj( rObj, embed::Aspects::MSOLE_CONTENT );
     118           0 :     ExportOLEObject( aObj, rDestStg );
     119           0 : }
     120             : 
     121           0 : void SvxMSExportOLEObjects::ExportOLEObject( svt::EmbeddedObjectRef& rObj, SvStorage& rDestStg )
     122             : {
     123           0 :     SvGlobalName aOwnGlobalName;
     124           0 :     SvGlobalName aObjName( rObj->getClassID() );
     125           0 :     const SfxFilter* pExpFilter = NULL;
     126             :     {
     127             :         static struct _ObjExpType {
     128             :             sal_uInt32 nFlag;
     129             :             const char* pFilterNm;
     130             :             // GlobalNameId
     131             :             struct _GlobalNameIds {
     132             :                 sal_uInt32 n1;
     133             :                 sal_uInt16 n2, n3;
     134             :                 sal_uInt8 b8, b9, b10, b11, b12, b13, b14, b15;
     135             :             }
     136             :             aGlNmIds[4];
     137             :         } aArr[] = {
     138             :             { OLE_STARMATH_2_MATHTYPE, "MathType 3.x",
     139             :                 {{SO3_SM_CLASSID_60}, {SO3_SM_CLASSID_50},
     140             :                  {SO3_SM_CLASSID_40}, {SO3_SM_CLASSID_30 }}},
     141             :             { OLE_STARWRITER_2_WINWORD, "MS Word 97",
     142             :                 {{SO3_SW_CLASSID_60}, {SO3_SW_CLASSID_50},
     143             :                  {SO3_SW_CLASSID_40}, {SO3_SW_CLASSID_30 }}},
     144             :             { OLE_STARCALC_2_EXCEL, "MS Excel 97",
     145             :                 {{SO3_SC_CLASSID_60}, {SO3_SC_CLASSID_50},
     146             :                  {SO3_SC_CLASSID_40}, {SO3_SC_CLASSID_30 }}},
     147             :             { OLE_STARIMPRESS_2_POWERPOINT, "MS PowerPoint 97",
     148             :                 {{SO3_SIMPRESS_CLASSID_60}, {SO3_SIMPRESS_CLASSID_50},
     149             :                  {SO3_SIMPRESS_CLASSID_40}, {SO3_SIMPRESS_CLASSID_30 }}},
     150             :             { 0, "",
     151             :                 {{SO3_SCH_CLASSID_60}, {SO3_SCH_CLASSID_50},
     152             :                  {SO3_SCH_CLASSID_40}, {SO3_SCH_CLASSID_30 }}},
     153             :             { 0, "",
     154             :                 {{SO3_SDRAW_CLASSID_60}, {SO3_SDRAW_CLASSID_50},    // SJ: !!!! SO3_SDRAW_CLASSID is only available up from
     155             :                  {SO3_SDRAW_CLASSID_60}, {SO3_SDRAW_CLASSID_50 }}}, // ver 5.0, it is purpose to have double entrys here.
     156             : 
     157             :             { 0xffff,0,
     158             :                 {{SO3_SDRAW_CLASSID_60}, {SO3_SDRAW_CLASSID_50},
     159             :                 {SO3_SDRAW_CLASSID_60}, {SO3_SDRAW_CLASSID_50}}}
     160             :         };
     161             : 
     162           0 :         for( const _ObjExpType* pArr = aArr; !pExpFilter && ( pArr->nFlag != 0xffff ); ++pArr )
     163             :         {
     164           0 :             for ( int n = 0; n < 4; ++n )
     165             :             {
     166           0 :                 const _ObjExpType::_GlobalNameIds& rId = pArr->aGlNmIds[ n ];
     167             :                 SvGlobalName aGlbNm( rId.n1, rId.n2, rId.n3,
     168             :                             rId.b8, rId.b9, rId.b10, rId.b11,
     169           0 :                             rId.b12, rId.b13, rId.b14, rId.b15 );
     170           0 :                 if( aObjName == aGlbNm )
     171             :                 {
     172           0 :                     aOwnGlobalName = aGlbNm;
     173             : 
     174             :                     // flags for checking if conversion is wanted at all (SaveOptions?!)
     175           0 :                     if( GetFlags() & pArr->nFlag )
     176             :                     {
     177           0 :                         pExpFilter = SfxFilterMatcher().GetFilter4FilterName(rtl::OUString::createFromAscii(pArr->pFilterNm));
     178             :                         break;
     179             :                     }
     180             :                 }
     181           0 :             }
     182             :         }
     183             :     }
     184             : 
     185           0 :     if( pExpFilter )                        // use this filter for the export
     186             :     {
     187             :         try
     188             :         {
     189           0 :             if ( rObj->getCurrentState() == embed::EmbedStates::LOADED )
     190           0 :                 rObj->changeState( embed::EmbedStates::RUNNING );
     191             :             //TODO/LATER: is stream instead of outputstream a better choice?!
     192             :             //TODO/LATER: a "StoreTo" method at embedded object would be nice
     193           0 :             uno::Sequence < beans::PropertyValue > aSeq(2);
     194           0 :             SvStream* pStream = new SvMemoryStream;
     195           0 :             aSeq[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OutputStream" ));
     196           0 :             ::uno::Reference < io::XOutputStream > xOut = new ::utl::OOutputStreamWrapper( *pStream );
     197           0 :             aSeq[0].Value <<= xOut;
     198           0 :             aSeq[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
     199           0 :             aSeq[1].Value <<= ::rtl::OUString( pExpFilter->GetName() );
     200           0 :             uno::Reference < frame::XStorable > xStor( rObj->getComponent(), uno::UNO_QUERY );
     201             :         try
     202             :         {
     203           0 :             xStor->storeToURL( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" )), aSeq );
     204             :         }
     205           0 :         catch( const uno::Exception& ) {} // #TODO really handle exceptions - interactionalhandler etc. ?
     206             : 
     207           0 :             SotStorageRef xOLEStor = new SotStorage( pStream, sal_True );
     208           0 :             xOLEStor->CopyTo( &rDestStg );
     209           0 :             rDestStg.Commit();
     210             :         }
     211           0 :         catch( const uno::Exception& )
     212             :         {
     213             :             // TODO/LATER: Error handling
     214             :             OSL_FAIL( "The object could not be exported!" );
     215             :         }
     216             :     }
     217           0 :     else if( aOwnGlobalName != SvGlobalName() )
     218             :     {
     219             :         // own format, maybe SO6 format or lower
     220           0 :         SvGlobalName aEmbName = GetEmbeddedVersion( aOwnGlobalName );
     221           0 :         if ( aEmbName != SvGlobalName() && !UseOldMSExport() )
     222             :         {
     223             :             // this is a SO6 embedded object, save in old binary format
     224           0 :             rDestStg.SetVersion( SOFFICE_FILEFORMAT_31 );
     225             :             rDestStg.SetClass( aEmbName,
     226             :                                 SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE,
     227           0 :                                 GetStorageType( aEmbName ) );
     228             :             SotStorageStreamRef xExtStm = rDestStg.OpenSotStream(
     229             :                                             rtl::OUString("properties_stream"),
     230           0 :                                             STREAM_STD_READWRITE);
     231             : 
     232           0 :             sal_Bool bExtentSuccess = sal_False;
     233           0 :             if( !xExtStm->GetError() )
     234             :             {
     235             :                 // write extent
     236             :                 //TODO/MBA: check if writing a size is enough
     237           0 :                 if( rObj.GetObject().is() )
     238             :                 {
     239             :                     // MSOLE objects don't need to be in running state for VisualArea access
     240           0 :                     awt::Size aSize;
     241             :                     try
     242             :                     {
     243             :                         // this is an own object, the content size must be stored in the
     244             :                         // extension stream
     245           0 :                         aSize = rObj->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
     246             :                     }
     247           0 :                     catch( const embed::NoVisualAreaSizeException& )
     248             :                     {
     249             :                         OSL_FAIL( "Could not get visual area size!\n" );
     250           0 :                         aSize.Width = 5000;
     251           0 :                         aSize.Height = 5000;
     252             :                     }
     253           0 :                     catch( const uno::Exception& )
     254             :                     {
     255             :                         OSL_FAIL( "Unexpected exception while getting visual area size!\n" );
     256           0 :                         aSize.Width = 5000;
     257           0 :                         aSize.Height = 5000;
     258             :                     }
     259             : 
     260             :                     sal_Int32 pRect[4];
     261           0 :                     pRect[0] = 0;
     262           0 :                     pRect[1] = aSize.Width;
     263           0 :                     pRect[2] = 0;
     264           0 :                     pRect[3] = aSize.Height;
     265             : 
     266             :                     sal_Int8 aWriteSet[16];
     267           0 :                     for ( int ind = 0; ind < 4; ind++ )
     268             :                     {
     269           0 :                         sal_Int32 nVal = pRect[ind];
     270           0 :                         for ( int nByte = 0; nByte < 4; nByte++ )
     271             :                         {
     272           0 :                             aWriteSet[ind*4+nByte] = (sal_Int8) nVal % 0x100;
     273           0 :                             nVal /= 0x100;
     274             :                         }
     275             :                     }
     276             : 
     277           0 :                     bExtentSuccess = ( xExtStm->Write( aWriteSet, 16 ) == 16 );
     278             :                 }
     279             :             }
     280             : 
     281           0 :             if ( bExtentSuccess )
     282             :             {
     283             :                 SotStorageStreamRef xEmbStm = rDestStg.OpenSotStream(
     284             :                                                 rtl::OUString("package_stream"),
     285           0 :                                                 STREAM_STD_READWRITE);
     286           0 :                 if( !xEmbStm->GetError() )
     287             :                 {
     288             :                     try
     289             :                     {
     290           0 :                         if ( rObj->getCurrentState() == embed::EmbedStates::LOADED )
     291           0 :                             rObj->changeState( embed::EmbedStates::RUNNING );
     292             :                         //TODO/LATER: is stream instead of outputstream a better choice?!
     293             :                         //TODO/LATER: a "StoreTo" method at embedded object would be nice
     294           0 :                         uno::Sequence < beans::PropertyValue > aSeq(1);
     295           0 :                         aSeq[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OutputStream" ));
     296           0 :                         ::uno::Reference < io::XOutputStream > xOut = new ::utl::OOutputStreamWrapper( *xEmbStm );
     297           0 :                         aSeq[0].Value <<= xOut;
     298           0 :                         uno::Reference < frame::XStorable > xStor( rObj->getComponent(), uno::UNO_QUERY );
     299           0 :                         xStor->storeToURL( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" )), aSeq );
     300             :                     }
     301           0 :                     catch( const uno::Exception& )
     302             :                     {
     303             :                         // TODO/LATER: Error handling
     304             :                         OSL_FAIL( "The object could not be exported!" );
     305             :                     }
     306           0 :                 }
     307           0 :             }
     308             :         }
     309             :         else
     310             :         {
     311             :             OSL_FAIL("Own binary format inside own container document!");
     312           0 :         }
     313             :     }
     314             :     else
     315             :     {
     316             :         // alien objects
     317             :         //TODO/LATER: a "StoreTo" method at embedded object would be nice
     318           0 :         rDestStg.SetVersion( SOFFICE_FILEFORMAT_31 );
     319           0 :         uno::Reference < embed::XStorage > xStor = ::comphelper::OStorageHelper::GetTemporaryStorage();
     320           0 :         uno::Reference < embed::XEmbedPersist > xPers( rObj.GetObject(), uno::UNO_QUERY );
     321           0 :         if ( xPers.is() )
     322             :         {
     323           0 :             uno::Sequence < beans::PropertyValue > aEmptySeq;
     324           0 :             ::rtl::OUString aTempName( RTL_CONSTASCII_USTRINGPARAM( "bla" ));
     325             :             try
     326             :             {
     327           0 :                 xPers->storeToEntry( xStor, aTempName, aEmptySeq, aEmptySeq );
     328             :             }
     329           0 :             catch ( const uno::Exception& )
     330             :             {}
     331             : 
     332           0 :             SotStorageRef xOLEStor = SotStorage::OpenOLEStorage( xStor, aTempName, STREAM_STD_READ );
     333           0 :             xOLEStor->CopyTo( &rDestStg );
     334           0 :             rDestStg.Commit();
     335           0 :         }
     336             :     }
     337             : 
     338             :     //We never need this stream: See #99809# and #i2179#
     339           0 :     rDestStg.Remove(rtl::OUString(SVEXT_PERSIST_STREAM));
     340           0 : }
     341             : 
     342             : 
     343             : 
     344             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10