LCOV - code coverage report
Current view: top level - libreoffice/comphelper/source/container - embeddedobjectcontainer.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 272 677 40.2 %
Date: 2012-12-17 Functions: 34 47 72.3 %
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/container/XChild.hpp>
      21             : #include <com/sun/star/container/XNameAccess.hpp>
      22             : #include <com/sun/star/embed/XEmbedObjectCreator.hpp>
      23             : #include <com/sun/star/embed/XLinkCreator.hpp>
      24             : #include <com/sun/star/embed/XEmbedPersist.hpp>
      25             : #include <com/sun/star/embed/XLinkageSupport.hpp>
      26             : #include <com/sun/star/embed/XTransactedObject.hpp>
      27             : #include <com/sun/star/embed/XOptimizedStorage.hpp>
      28             : #include <com/sun/star/embed/EntryInitModes.hpp>
      29             : #include <com/sun/star/util/XCloseable.hpp>
      30             : #include <com/sun/star/util/XModifiable.hpp>
      31             : #include <com/sun/star/embed/EmbedStates.hpp>
      32             : #include <com/sun/star/datatransfer/XTransferable.hpp>
      33             : #include <com/sun/star/beans/XPropertySetInfo.hpp>
      34             : #include <com/sun/star/beans/XPropertySet.hpp>
      35             : #include <com/sun/star/embed/Aspects.hpp>
      36             : #include <com/sun/star/embed/EmbedMisc.hpp>
      37             : 
      38             : #include <comphelper/seqstream.hxx>
      39             : #include <comphelper/processfactory.hxx>
      40             : #include <comphelper/storagehelper.hxx>
      41             : #include <comphelper/embeddedobjectcontainer.hxx>
      42             : #include <comphelper/sequence.hxx>
      43             : #include <cppuhelper/weakref.hxx>
      44             : #include <boost/unordered_map.hpp>
      45             : #include <algorithm>
      46             : 
      47             : #include <rtl/logfile.hxx>
      48             : 
      49             : using namespace ::com::sun::star;
      50             : 
      51             : namespace comphelper
      52             : {
      53             : 
      54             : struct hashObjectName_Impl
      55             : {
      56        7670 :     size_t operator()(const ::rtl::OUString Str) const
      57             :     {
      58        7670 :         return (size_t)Str.hashCode();
      59             :     }
      60             : };
      61             : 
      62             : struct eqObjectName_Impl
      63             : {
      64        5658 :     sal_Bool operator()(const ::rtl::OUString Str1, const ::rtl::OUString Str2) const
      65             :     {
      66        5658 :         return ( Str1 == Str2 );
      67             :     }
      68             : };
      69             : 
      70             : typedef boost::unordered_map
      71             : <
      72             :     ::rtl::OUString,
      73             :     ::com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject >,
      74             :     hashObjectName_Impl,
      75             :     eqObjectName_Impl
      76             : >
      77             : EmbeddedObjectContainerNameMap;
      78             : 
      79        2406 : struct EmbedImpl
      80             : {
      81             :     // TODO/LATER: remove objects from temp. Container storage when object is disposed
      82             :     EmbeddedObjectContainerNameMap maObjectContainer;
      83             :     uno::Reference < embed::XStorage > mxStorage;
      84             :     EmbeddedObjectContainer* mpTempObjectContainer;
      85             :     uno::Reference < embed::XStorage > mxImageStorage;
      86             :     uno::WeakReference < uno::XInterface > m_xModel;
      87             :     //EmbeddedObjectContainerNameMap maTempObjectContainer;
      88             :     //uno::Reference < embed::XStorage > mxTempStorage;
      89             :     bool bOwnsStorage;
      90             : 
      91             :     const uno::Reference < embed::XStorage >& GetReplacements();
      92             : };
      93             : 
      94         374 : const uno::Reference < embed::XStorage >& EmbedImpl::GetReplacements()
      95             : {
      96         374 :     if ( !mxImageStorage.is() )
      97             :     {
      98             :         try
      99             :         {
     100         140 :             mxImageStorage = mxStorage->openStorageElement(
     101         140 :                 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ObjectReplacements")), embed::ElementModes::READWRITE );
     102             :         }
     103           0 :         catch (const uno::Exception&)
     104             :         {
     105           0 :             mxImageStorage = mxStorage->openStorageElement(
     106           0 :                 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ObjectReplacements")), embed::ElementModes::READ );
     107             :         }
     108             :     }
     109             : 
     110         374 :     if ( !mxImageStorage.is() )
     111           0 :         throw io::IOException();
     112             : 
     113         374 :     return mxImageStorage;
     114             : }
     115             : 
     116         284 : EmbeddedObjectContainer::EmbeddedObjectContainer()
     117             : {
     118         284 :     pImpl = new EmbedImpl;
     119         284 :     pImpl->mxStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
     120         284 :     pImpl->bOwnsStorage = true;
     121         284 :     pImpl->mpTempObjectContainer = 0;
     122         284 : }
     123             : 
     124         294 : EmbeddedObjectContainer::EmbeddedObjectContainer( const uno::Reference < embed::XStorage >& rStor )
     125             : {
     126         294 :     pImpl = new EmbedImpl;
     127         294 :     pImpl->mxStorage = rStor;
     128         294 :     pImpl->bOwnsStorage = false;
     129         294 :     pImpl->mpTempObjectContainer = 0;
     130         294 : }
     131             : 
     132         810 : EmbeddedObjectContainer::EmbeddedObjectContainer( const uno::Reference < embed::XStorage >& rStor, const uno::Reference < uno::XInterface >& xModel )
     133             : {
     134         810 :     pImpl = new EmbedImpl;
     135         810 :     pImpl->mxStorage = rStor;
     136         810 :     pImpl->bOwnsStorage = false;
     137         810 :     pImpl->mpTempObjectContainer = 0;
     138         810 :     pImpl->m_xModel = xModel;
     139         810 : }
     140             : 
     141         570 : void EmbeddedObjectContainer::SwitchPersistence( const uno::Reference < embed::XStorage >& rStor )
     142             : {
     143         570 :     ReleaseImageSubStorage();
     144             : 
     145         570 :     if ( pImpl->bOwnsStorage )
     146           0 :         pImpl->mxStorage->dispose();
     147             : 
     148         570 :     pImpl->mxStorage = rStor;
     149         570 :     pImpl->bOwnsStorage = false;
     150         570 : }
     151             : 
     152        1876 : sal_Bool EmbeddedObjectContainer::CommitImageSubStorage()
     153             : {
     154        1876 :     if ( pImpl->mxImageStorage.is() )
     155             :     {
     156             :         try
     157             :         {
     158          42 :             sal_Bool bReadOnlyMode = sal_True;
     159          42 :             uno::Reference < beans::XPropertySet > xSet(pImpl->mxImageStorage,uno::UNO_QUERY);
     160          42 :             if ( xSet.is() )
     161             :             {
     162             :                 // get the open mode from the parent storage
     163          42 :                 sal_Int32 nMode = 0;
     164          42 :                 uno::Any aAny = xSet->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OpenMode")) );
     165          42 :                 if ( aAny >>= nMode )
     166          42 :                     bReadOnlyMode = !(nMode & embed::ElementModes::WRITE );
     167             :             } // if ( xSet.is() )
     168          42 :             if ( !bReadOnlyMode )
     169             :             {
     170          42 :                 uno::Reference< embed::XTransactedObject > xTransact( pImpl->mxImageStorage, uno::UNO_QUERY_THROW );
     171          42 :                 xTransact->commit();
     172          42 :             }
     173             :         }
     174           0 :         catch (const uno::Exception&)
     175             :         {
     176           0 :             return sal_False;
     177             :         }
     178             :     }
     179             : 
     180        1876 :     return sal_True;
     181             : }
     182             : 
     183        1588 : void EmbeddedObjectContainer::ReleaseImageSubStorage()
     184             : {
     185        1588 :     CommitImageSubStorage();
     186             : 
     187        1588 :     if ( pImpl->mxImageStorage.is() )
     188             :     {
     189             :         try
     190             :         {
     191          42 :             pImpl->mxImageStorage->dispose();
     192          42 :             pImpl->mxImageStorage = uno::Reference< embed::XStorage >();
     193             :         }
     194           0 :         catch (const uno::Exception&)
     195             :         {
     196             :             OSL_FAIL( "Problems releasing image substorage!\n" );
     197             :         }
     198             :     }
     199        1588 : }
     200             : 
     201        1018 : EmbeddedObjectContainer::~EmbeddedObjectContainer()
     202             : {
     203        1018 :     ReleaseImageSubStorage();
     204             : 
     205        1018 :     if ( pImpl->bOwnsStorage )
     206         284 :         pImpl->mxStorage->dispose();
     207             : 
     208        1018 :     delete pImpl->mpTempObjectContainer;
     209        1018 :     delete pImpl;
     210        1018 : }
     211             : 
     212         440 : void EmbeddedObjectContainer::CloseEmbeddedObjects()
     213             : {
     214         440 :     EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin();
     215        1050 :     while ( aIt != pImpl->maObjectContainer.end() )
     216             :     {
     217         170 :         uno::Reference < util::XCloseable > xClose( (*aIt).second, uno::UNO_QUERY );
     218         170 :         if ( xClose.is() )
     219             :         {
     220             :             try
     221             :             {
     222         170 :                 xClose->close( sal_True );
     223             :             }
     224         168 :             catch (const uno::Exception&)
     225             :             {
     226             :             }
     227             :         }
     228             : 
     229         170 :         ++aIt;
     230         170 :     }
     231         440 : }
     232             : 
     233         940 : ::rtl::OUString EmbeddedObjectContainer::CreateUniqueObjectName()
     234             : {
     235         940 :     ::rtl::OUString aPersistName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Object ") );
     236         940 :     ::rtl::OUString aStr;
     237         940 :     sal_Int32 i=1;
     238        4204 :     do
     239             :     {
     240        4204 :         aStr = aPersistName;
     241        4204 :         aStr += ::rtl::OUString::valueOf( i++ );
     242             :     }
     243        4204 :     while( HasEmbeddedObject( aStr ) );
     244             :     // TODO/LATER: should we consider deleted objects?
     245             : 
     246         940 :     return aStr;
     247             : }
     248             : 
     249        7931 : uno::Sequence < ::rtl::OUString > EmbeddedObjectContainer::GetObjectNames()
     250             : {
     251        7931 :     uno::Sequence < ::rtl::OUString > aSeq( pImpl->maObjectContainer.size() );
     252        7931 :     EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin();
     253        7931 :     sal_Int32 nIdx=0;
     254       18152 :     while ( aIt != pImpl->maObjectContainer.end() )
     255        2290 :         aSeq[nIdx++] = (*aIt++).first;
     256        7931 :     return aSeq;
     257             : }
     258             : 
     259           0 : sal_Bool EmbeddedObjectContainer::HasEmbeddedObjects()
     260             : {
     261           0 :     return pImpl->maObjectContainer.size() != 0;
     262             : }
     263             : 
     264        4300 : sal_Bool EmbeddedObjectContainer::HasEmbeddedObject( const ::rtl::OUString& rName )
     265             : {
     266        4300 :     EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName );
     267        4300 :     if ( aIt == pImpl->maObjectContainer.end() )
     268             :     {
     269         942 :         uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY );
     270         942 :         return xAccess->hasByName(rName);
     271             :     }
     272             :     else
     273        3358 :         return sal_True;
     274             : }
     275             : 
     276          88 : sal_Bool EmbeddedObjectContainer::HasEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj )
     277             : {
     278          88 :     EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin();
     279         364 :     while ( aIt != pImpl->maObjectContainer.end() )
     280             :     {
     281         276 :         if ( (*aIt).second == xObj )
     282          88 :             return sal_True;
     283             :         else
     284         188 :             ++aIt;
     285             :     }
     286             : 
     287           0 :     return sal_False;
     288             : }
     289             : 
     290          12 : sal_Bool EmbeddedObjectContainer::HasInstantiatedEmbeddedObject( const ::rtl::OUString& rName )
     291             : {
     292             :     // allows to detect whether the object was already instantiated
     293             :     // currently the filter instantiate it on loading, so this method allows
     294             :     // to avoid objects pointing to the same persistence
     295          12 :     EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName );
     296          12 :     return ( aIt != pImpl->maObjectContainer.end() );
     297             : }
     298             : 
     299           0 : ::rtl::OUString EmbeddedObjectContainer::GetEmbeddedObjectName( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& xObj )
     300             : {
     301           0 :     EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin();
     302           0 :     while ( aIt != pImpl->maObjectContainer.end() )
     303             :     {
     304           0 :         if ( (*aIt).second == xObj )
     305           0 :             return (*aIt).first;
     306             :         else
     307           0 :             ++aIt;
     308             :     }
     309             : 
     310             :     OSL_FAIL( "Unknown object!" );
     311           0 :     return ::rtl::OUString();
     312             : }
     313             : 
     314        2318 : uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::GetEmbeddedObject( const ::rtl::OUString& rName )
     315             : {
     316             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::GetEmbeddedObject" );
     317             : 
     318             :     OSL_ENSURE( !rName.isEmpty(), "Empty object name!");
     319             : 
     320        2318 :     uno::Reference < embed::XEmbeddedObject > xObj;
     321        2318 :     EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName );
     322             : 
     323             : #if OSL_DEBUG_LEVEL > 1
     324             :     uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY );
     325             :     uno::Sequence< ::rtl::OUString> aSeq = xAccess->getElementNames();
     326             :     const ::rtl::OUString* pIter = aSeq.getConstArray();
     327             :     const ::rtl::OUString* pEnd   = pIter + aSeq.getLength();
     328             :     for(;pIter != pEnd;++pIter)
     329             :     {
     330             :         (void)*pIter;
     331             :     }
     332             :     OSL_ENSURE( aIt != pImpl->maObjectContainer.end() || xAccess->hasByName(rName), "Could not return object!" );
     333             : #endif
     334             : 
     335             :     // check if object was already created
     336        2318 :     if ( aIt != pImpl->maObjectContainer.end() )
     337        2300 :         xObj = (*aIt).second;
     338             :     else
     339          18 :         xObj = Get_Impl( rName, uno::Reference < embed::XEmbeddedObject >() );
     340             : 
     341        2318 :     return xObj;
     342             : }
     343             : 
     344          18 : uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::Get_Impl( const ::rtl::OUString& rName, const uno::Reference < embed::XEmbeddedObject >& xCopy )
     345             : {
     346          18 :     uno::Reference < embed::XEmbeddedObject > xObj;
     347             :     try
     348             :     {
     349             :         // create the object from the storage
     350          18 :         uno::Reference < beans::XPropertySet > xSet( pImpl->mxStorage, uno::UNO_QUERY );
     351          18 :         sal_Bool bReadOnlyMode = sal_True;
     352          18 :         if ( xSet.is() )
     353             :         {
     354             :             // get the open mode from the parent storage
     355          18 :             sal_Int32 nMode = 0;
     356          18 :             uno::Any aAny = xSet->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OpenMode")) );
     357          18 :             if ( aAny >>= nMode )
     358          18 :                 bReadOnlyMode = !(nMode & embed::ElementModes::WRITE );
     359             :         }
     360             : 
     361             :         // object was not added until now - should happen only by calling this method from "inside"
     362             :         //TODO/LATER: it would be good to detect an error when an object should be created already, but isn't (not an "inside" call)
     363          36 :         uno::Reference < embed::XEmbedObjectCreator > xFactory( ::comphelper::getProcessServiceFactory()->createInstance(
     364          18 :                 OUString("com.sun.star.embed.EmbeddedObjectCreator") ), uno::UNO_QUERY_THROW );
     365          18 :         uno::Sequence< beans::PropertyValue > aObjDescr( xCopy.is() ? 2 : 1 );
     366          18 :         aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) );
     367          18 :         aObjDescr[0].Value <<= pImpl->m_xModel.get();
     368          18 :         if ( xCopy.is() )
     369             :         {
     370           0 :             aObjDescr[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CloneFrom" ) );
     371           0 :             aObjDescr[1].Value <<= xCopy;
     372             :         }
     373             : 
     374          18 :         uno::Sequence< beans::PropertyValue > aMediaDescr( 1 );
     375          18 :         aMediaDescr[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReadOnly"));
     376          18 :         aMediaDescr[0].Value <<= bReadOnlyMode;
     377          18 :         xObj = uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceInitFromEntry(
     378             :                 pImpl->mxStorage, rName,
     379          18 :                 aMediaDescr, aObjDescr ), uno::UNO_QUERY );
     380             : 
     381             :         // insert object into my list
     382          18 :         AddEmbeddedObject( xObj, rName );
     383             :     }
     384           0 :     catch (const uno::Exception&)
     385             :     {
     386             :     }
     387             : 
     388          18 :     return xObj;
     389             : }
     390             : 
     391         366 : uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::CreateEmbeddedObject( const uno::Sequence < sal_Int8 >& rClassId,
     392             :             const uno::Sequence < beans::PropertyValue >& rArgs, ::rtl::OUString& rNewName )
     393             : {
     394             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::CreateEmbeddedObject" );
     395             : 
     396         366 :     if ( rNewName.isEmpty() )
     397         366 :         rNewName = CreateUniqueObjectName();
     398             : 
     399             :     OSL_ENSURE( !HasEmbeddedObject(rNewName), "Object to create already exists!");
     400             : 
     401             :     // create object from classid by inserting it into storage
     402         366 :     uno::Reference < embed::XEmbeddedObject > xObj;
     403             :     try
     404             :     {
     405         732 :         uno::Reference < embed::XEmbedObjectCreator > xFactory( ::comphelper::getProcessServiceFactory()->createInstance(
     406         366 :                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator")) ), uno::UNO_QUERY );
     407             : 
     408         366 :         uno::Sequence< beans::PropertyValue > aObjDescr( rArgs.getLength() + 1 );
     409         366 :         aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) );
     410         366 :         aObjDescr[0].Value <<= pImpl->m_xModel.get();
     411         366 :         ::std::copy( rArgs.getConstArray(), rArgs.getConstArray() + rArgs.getLength(), aObjDescr.getArray() + 1 );
     412         366 :         xObj = uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceInitNew(
     413             :                     rClassId, ::rtl::OUString(), pImpl->mxStorage, rNewName,
     414         366 :                     aObjDescr ), uno::UNO_QUERY );
     415             : 
     416         366 :         AddEmbeddedObject( xObj, rNewName );
     417             : 
     418             :         OSL_ENSURE( !xObj.is() || xObj->getCurrentState() != embed::EmbedStates::LOADED,
     419         366 :                     "A freshly create object should be running always!\n" );
     420             :     }
     421           0 :     catch (const uno::Exception&)
     422             :     {
     423             :     }
     424             : 
     425         366 :     return xObj;
     426             : }
     427             : 
     428         366 : uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::CreateEmbeddedObject( const uno::Sequence < sal_Int8 >& rClassId, ::rtl::OUString& rNewName )
     429             : {
     430         366 :     return CreateEmbeddedObject( rClassId, uno::Sequence < beans::PropertyValue >(), rNewName );
     431             : }
     432             : 
     433         952 : void EmbeddedObjectContainer::AddEmbeddedObject( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& xObj, const ::rtl::OUString& rName )
     434             : {
     435             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::AddEmbeddedObject" );
     436             : 
     437             : #if OSL_DEBUG_LEVEL > 1
     438             :     OSL_ENSURE( !rName.isEmpty(), "Added object doesn't have a name!");
     439             :     uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY );
     440             :     uno::Reference < embed::XEmbedPersist > xEmb( xObj, uno::UNO_QUERY );
     441             :     uno::Reference < embed::XLinkageSupport > xLink( xEmb, uno::UNO_QUERY );
     442             :     // if the object has a persistance and the object is not a link than it must have persistence entry in the storage
     443             :     OSL_ENSURE( !( xEmb.is() && ( !xLink.is() || !xLink->isLink() ) ) || xAccess->hasByName(rName),
     444             :                     "Added element not in storage!" );
     445             : #endif
     446             : 
     447             :     // remember object - it needs to be in storage already
     448         952 :     EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName );
     449             :     OSL_ENSURE( aIt == pImpl->maObjectContainer.end(), "Element already inserted!" );
     450         952 :     pImpl->maObjectContainer[ rName ] = xObj;
     451         952 :     uno::Reference < container::XChild > xChild( xObj, uno::UNO_QUERY );
     452         952 :     if ( xChild.is() && xChild->getParent() != pImpl->m_xModel.get() )
     453           0 :         xChild->setParent( pImpl->m_xModel.get() );
     454             : 
     455             :     // look for object in temorary container
     456         952 :     if ( pImpl->mpTempObjectContainer )
     457             :     {
     458           0 :         aIt = pImpl->mpTempObjectContainer->pImpl->maObjectContainer.begin();
     459           0 :         while ( aIt != pImpl->mpTempObjectContainer->pImpl->maObjectContainer.end() )
     460             :         {
     461           0 :             if ( (*aIt).second == xObj )
     462             :             {
     463             :                 // copy replacement image from temporary container (if there is any)
     464           0 :                 ::rtl::OUString aTempName = (*aIt).first;
     465           0 :                 ::rtl::OUString aMediaType;
     466           0 :                 uno::Reference < io::XInputStream > xStream = pImpl->mpTempObjectContainer->GetGraphicStream( xObj, &aMediaType );
     467           0 :                 if ( xStream.is() )
     468             :                 {
     469           0 :                     InsertGraphicStream( xStream, rName, aMediaType );
     470           0 :                     xStream = 0;
     471           0 :                     pImpl->mpTempObjectContainer->RemoveGraphicStream( aTempName );
     472             :                 }
     473             : 
     474             :                 // remove object from storage of temporary container
     475           0 :                 uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
     476           0 :                 if ( xPersist.is() )
     477             :                 {
     478             :                     try
     479             :                     {
     480           0 :                         pImpl->mpTempObjectContainer->pImpl->mxStorage->removeElement( aTempName );
     481             :                     }
     482           0 :                     catch (const uno::Exception&)
     483             :                     {
     484             :                     }
     485             :                 }
     486             : 
     487             :                 // temp. container needs to forget the object
     488           0 :                 pImpl->mpTempObjectContainer->pImpl->maObjectContainer.erase( aIt );
     489           0 :                 break;
     490             :             }
     491             :             else
     492           0 :                 ++aIt;
     493             :         }
     494         952 :     }
     495         952 : }
     496             : 
     497         568 : sal_Bool EmbeddedObjectContainer::StoreEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName, sal_Bool bCopy )
     498             : {
     499             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::StoreEmbeddedObject" );
     500             : 
     501         568 :     uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
     502         568 :     if ( rName.isEmpty() )
     503         568 :         rName = CreateUniqueObjectName();
     504             : 
     505             : #if OSL_DEBUG_LEVEL > 1
     506             :     uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY );
     507             :     OSL_ENSURE( !xPersist.is() || !xAccess->hasByName(rName), "Inserting element already present in storage!" );
     508             :     OSL_ENSURE( xPersist.is() || xObj->getCurrentState() == embed::EmbedStates::RUNNING, "Non persistent object inserted!");
     509             : #endif
     510             : 
     511             :     // insert objects' storage into the container storage (if object has one)
     512             :     try
     513             :     {
     514         568 :         if ( xPersist.is() )
     515             :         {
     516         568 :             uno::Sequence < beans::PropertyValue > aSeq;
     517         568 :             if ( bCopy )
     518           0 :                 xPersist->storeToEntry( pImpl->mxStorage, rName, aSeq, aSeq );
     519             :             else
     520             :             {
     521             :                 //TODO/LATER: possible optimisation, don't store immediately
     522             :                 //xPersist->setPersistentEntry( pImpl->mxStorage, rName, embed::EntryInitModes::ENTRY_NO_INIT, aSeq, aSeq );
     523         568 :                 xPersist->storeAsEntry( pImpl->mxStorage, rName, aSeq, aSeq );
     524         568 :                 xPersist->saveCompleted( sal_True );
     525         568 :             }
     526             :         }
     527             :     }
     528           0 :     catch (const uno::Exception&)
     529             :     {
     530             :         // TODO/LATER: better error recovery should keep storage intact
     531           0 :         return sal_False;
     532             :     }
     533             : 
     534         568 :     return sal_True;
     535             : }
     536             : 
     537         568 : sal_Bool EmbeddedObjectContainer::InsertEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName )
     538             : {
     539             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertEmbeddedObject( Object )" );
     540             :     // store it into the container storage
     541         568 :     if ( StoreEmbeddedObject( xObj, rName, sal_False ) )
     542             :     {
     543             :         // remember object
     544         568 :         AddEmbeddedObject( xObj, rName );
     545         568 :         return sal_True;
     546             :     }
     547             :     else
     548           0 :         return sal_False;
     549             : }
     550             : 
     551           0 : uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::InsertEmbeddedObject( const uno::Reference < io::XInputStream >& xStm, ::rtl::OUString& rNewName )
     552             : {
     553             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertEmbeddedObject( InputStream )" );
     554             : 
     555           0 :     if ( rNewName.isEmpty() )
     556           0 :         rNewName = CreateUniqueObjectName();
     557             : 
     558             :     // store it into the container storage
     559           0 :     sal_Bool bIsStorage = sal_False;
     560             :     try
     561             :     {
     562             :         // first try storage persistence
     563           0 :         uno::Reference < embed::XStorage > xStore = ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm );
     564             : 
     565             :         // storage was created from stream successfully
     566           0 :         bIsStorage = sal_True;
     567             : 
     568           0 :         uno::Reference < embed::XStorage > xNewStore = pImpl->mxStorage->openStorageElement( rNewName, embed::ElementModes::READWRITE );
     569           0 :         xStore->copyToStorage( xNewStore );
     570             :     }
     571           0 :     catch (const uno::Exception&)
     572             :     {
     573           0 :         if ( bIsStorage )
     574             :             // it is storage persistence, but opening of new substorage or copying to it failed
     575           0 :             return uno::Reference < embed::XEmbeddedObject >();
     576             : 
     577             :         // stream didn't contain a storage, now try stream persistence
     578             :         try
     579             :         {
     580           0 :             uno::Reference < io::XStream > xNewStream = pImpl->mxStorage->openStreamElement( rNewName, embed::ElementModes::READWRITE );
     581           0 :             ::comphelper::OStorageHelper::CopyInputToOutput( xStm, xNewStream->getOutputStream() );
     582             : 
     583             :             // No mediatype is provided so the default for OLE objects value is used
     584             :             // it is correct so for now, but what if somebody introduces a new stream based embedded object?
     585             :             // Probably introducing of such an object must be restricted ( a storage must be used! ).
     586           0 :             uno::Reference< beans::XPropertySet > xProps( xNewStream, uno::UNO_QUERY_THROW );
     587           0 :             xProps->setPropertyValue(
     588             :                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
     589           0 :                     uno::makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.oleobject" ) ) ) );
     590             :         }
     591           0 :         catch (const uno::Exception&)
     592             :         {
     593             :             // complete disaster!
     594           0 :             return uno::Reference < embed::XEmbeddedObject >();
     595             :         }
     596             :     }
     597             : 
     598             :     // stream was copied into the container storage in either way, now try to open something form it
     599           0 :     uno::Reference < embed::XEmbeddedObject > xRet = GetEmbeddedObject( rNewName );
     600             :     try
     601             :     {
     602           0 :         if ( !xRet.is() )
     603             :             // no object could be created, so withdraw insertion
     604           0 :             pImpl->mxStorage->removeElement( rNewName );
     605             :     }
     606           0 :     catch (const uno::Exception&)
     607             :     {
     608             :     }
     609             : 
     610           0 :     return xRet;
     611             : }
     612             : 
     613          12 : uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::InsertEmbeddedObject( const ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >& aMedium, ::rtl::OUString& rNewName )
     614             : {
     615             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertEmbeddedObject( MediaDescriptor )" );
     616             : 
     617          12 :     if ( rNewName.isEmpty() )
     618           0 :         rNewName = CreateUniqueObjectName();
     619             : 
     620          12 :     uno::Reference < embed::XEmbeddedObject > xObj;
     621             :     try
     622             :     {
     623          24 :         uno::Reference < embed::XEmbedObjectCreator > xFactory( ::comphelper::getProcessServiceFactory()->createInstance(
     624          12 :                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator")) ), uno::UNO_QUERY );
     625          12 :         uno::Sequence< beans::PropertyValue > aObjDescr( 1 );
     626          12 :         aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) );
     627          12 :         aObjDescr[0].Value <<= pImpl->m_xModel.get();
     628          12 :         xObj = uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceInitFromMediaDescriptor(
     629          12 :                 pImpl->mxStorage, rNewName, aMedium, aObjDescr ), uno::UNO_QUERY );
     630           0 :         uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
     631             : 
     632             :            OSL_ENSURE( !xObj.is() || xObj->getCurrentState() != embed::EmbedStates::LOADED,
     633             :                     "A freshly create object should be running always!\n" );
     634             : 
     635             :         // possible optimization: store later!
     636           0 :         if ( xPersist.is())
     637           0 :             xPersist->storeOwn();
     638             : 
     639           0 :         AddEmbeddedObject( xObj, rNewName );
     640             :     }
     641          12 :     catch (const uno::Exception&)
     642             :     {
     643             :     }
     644             : 
     645          12 :     return xObj;
     646             : }
     647             : 
     648           0 : uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::InsertEmbeddedLink( const ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >& aMedium, ::rtl::OUString& rNewName )
     649             : {
     650             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertEmbeddedLink" );
     651             : 
     652           0 :     if ( rNewName.isEmpty() )
     653           0 :         rNewName = CreateUniqueObjectName();
     654             : 
     655           0 :     uno::Reference < embed::XEmbeddedObject > xObj;
     656             :     try
     657             :     {
     658           0 :         uno::Reference < embed::XLinkCreator > xFactory( ::comphelper::getProcessServiceFactory()->createInstance(
     659           0 :                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator")) ), uno::UNO_QUERY );
     660           0 :         uno::Sequence< beans::PropertyValue > aObjDescr( 1 );
     661           0 :         aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) );
     662           0 :         aObjDescr[0].Value <<= pImpl->m_xModel.get();
     663           0 :         xObj = uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceLink(
     664           0 :                 pImpl->mxStorage, rNewName, aMedium, aObjDescr ), uno::UNO_QUERY );
     665             : 
     666           0 :         uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
     667             : 
     668             :            OSL_ENSURE( !xObj.is() || xObj->getCurrentState() != embed::EmbedStates::LOADED,
     669             :                     "A freshly create object should be running always!\n" );
     670             : 
     671             :         // possible optimization: store later!
     672           0 :         if ( xPersist.is())
     673           0 :             xPersist->storeOwn();
     674             : 
     675           0 :         AddEmbeddedObject( xObj, rNewName );
     676             :     }
     677           0 :     catch (const uno::Exception&)
     678             :     {
     679             :     }
     680             : 
     681           0 :     return xObj;
     682             : }
     683             : 
     684           0 : sal_Bool EmbeddedObjectContainer::TryToCopyGraphReplacement( EmbeddedObjectContainer& rSrc,
     685             :                                                             const ::rtl::OUString& aOrigName,
     686             :                                                             const ::rtl::OUString& aTargetName )
     687             : {
     688             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::TryToCopyGraphReplacement" );
     689             : 
     690           0 :     sal_Bool bResult = sal_False;
     691             : 
     692           0 :     if ( ( &rSrc != this || !aOrigName.equals( aTargetName ) ) && !aOrigName.isEmpty() && !aTargetName.isEmpty() )
     693             :     {
     694           0 :         ::rtl::OUString aMediaType;
     695           0 :         uno::Reference < io::XInputStream > xGrStream = rSrc.GetGraphicStream( aOrigName, &aMediaType );
     696           0 :         if ( xGrStream.is() )
     697           0 :             bResult = InsertGraphicStream( xGrStream, aTargetName, aMediaType );
     698             :     }
     699             : 
     700           0 :     return bResult;
     701             : }
     702             : 
     703           0 : uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::CopyAndGetEmbeddedObject( EmbeddedObjectContainer& rSrc, const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName )
     704             : {
     705             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::CopyAndGetEmbeddedObject" );
     706             : 
     707           0 :     uno::Reference< embed::XEmbeddedObject > xResult;
     708             : 
     709             :     // TODO/LATER: For now only objects that implement XEmbedPersist have a replacement image, it might change in future
     710             :     // do an incompatible change so that object name is provided in all the move and copy methods
     711           0 :     ::rtl::OUString aOrigName;
     712             :     try
     713             :     {
     714           0 :         uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY_THROW );
     715           0 :         aOrigName = xPersist->getEntryName();
     716             :     }
     717           0 :     catch (const uno::Exception&)
     718             :     {
     719             :     }
     720             : 
     721           0 :     if ( rName.isEmpty() )
     722           0 :         rName = CreateUniqueObjectName();
     723             : 
     724             :     // objects without persistance are not really stored by the method
     725           0 :        if ( xObj.is() && StoreEmbeddedObject( xObj, rName, sal_True ) )
     726             :     {
     727           0 :         xResult = Get_Impl( rName, xObj);
     728           0 :         if ( !xResult.is() )
     729             :         {
     730             :             // this is a case when object has no real persistence
     731             :             // in such cases a new object should be explicitly created and initialized with the data of the old one
     732             :             try
     733             :             {
     734           0 :                 uno::Reference< embed::XLinkageSupport > xOrigLinkage( xObj, uno::UNO_QUERY );
     735           0 :                 if ( xOrigLinkage.is() && xOrigLinkage->isLink() )
     736             :                 {
     737             :                     // this is a OOo link, it has no persistence
     738           0 :                     ::rtl::OUString aURL = xOrigLinkage->getLinkURL();
     739           0 :                     if ( aURL.isEmpty() )
     740           0 :                         throw uno::RuntimeException();
     741             : 
     742             :                     // create new linked object from the URL the link is based on
     743             :                     uno::Reference < embed::XLinkCreator > xCreator(
     744           0 :                         ::comphelper::getProcessServiceFactory()->createInstance(
     745           0 :                             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator") ) ),
     746           0 :                         uno::UNO_QUERY_THROW );
     747             : 
     748           0 :                     uno::Sequence< beans::PropertyValue > aMediaDescr( 1 );
     749           0 :                     aMediaDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
     750           0 :                     aMediaDescr[0].Value <<= aURL;
     751           0 :                     uno::Sequence< beans::PropertyValue > aObjDescr( 1 );
     752           0 :                     aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) );
     753           0 :                     aObjDescr[0].Value <<= pImpl->m_xModel.get();
     754             :                     xResult = uno::Reference < embed::XEmbeddedObject >(
     755           0 :                                 xCreator->createInstanceLink(
     756             :                                     pImpl->mxStorage,
     757             :                                     rName,
     758             :                                     aMediaDescr,
     759           0 :                                     aObjDescr ),
     760           0 :                                 uno::UNO_QUERY_THROW );
     761             :                 }
     762             :                 else
     763             :                 {
     764             :                     // the component is required for copying of this object
     765           0 :                     if ( xObj->getCurrentState() == embed::EmbedStates::LOADED )
     766           0 :                         xObj->changeState( embed::EmbedStates::RUNNING );
     767             : 
     768             :                     // this must be an object based on properties, otherwise we can not copy it currently
     769           0 :                     uno::Reference< beans::XPropertySet > xOrigProps( xObj->getComponent(), uno::UNO_QUERY_THROW );
     770             : 
     771             :                     // use object class ID to create a new one and tranfer all the properties
     772             :                     uno::Reference < embed::XEmbedObjectCreator > xCreator(
     773           0 :                         ::comphelper::getProcessServiceFactory()->createInstance(
     774           0 :                             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator") ) ),
     775           0 :                         uno::UNO_QUERY_THROW );
     776             : 
     777           0 :                     uno::Sequence< beans::PropertyValue > aObjDescr( 1 );
     778           0 :                     aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) );
     779           0 :                     aObjDescr[0].Value <<= pImpl->m_xModel.get();
     780             :                     xResult = uno::Reference < embed::XEmbeddedObject >(
     781           0 :                                 xCreator->createInstanceInitNew(
     782           0 :                                     xObj->getClassID(),
     783           0 :                                     xObj->getClassName(),
     784             :                                     pImpl->mxStorage,
     785             :                                     rName,
     786           0 :                                     aObjDescr ),
     787           0 :                                 uno::UNO_QUERY_THROW );
     788             : 
     789           0 :                     if ( xResult->getCurrentState() == embed::EmbedStates::LOADED )
     790           0 :                         xResult->changeState( embed::EmbedStates::RUNNING );
     791             : 
     792           0 :                     uno::Reference< beans::XPropertySet > xTargetProps( xResult->getComponent(), uno::UNO_QUERY_THROW );
     793             : 
     794             :                     // copy all the properties from xOrigProps to xTargetProps
     795           0 :                     uno::Reference< beans::XPropertySetInfo > xOrigInfo = xOrigProps->getPropertySetInfo();
     796           0 :                     if ( !xOrigInfo.is() )
     797           0 :                         throw uno::RuntimeException();
     798             : 
     799           0 :                     uno::Sequence< beans::Property > aPropertiesList = xOrigInfo->getProperties();
     800           0 :                     for ( sal_Int32 nInd = 0; nInd < aPropertiesList.getLength(); nInd++ )
     801             :                     {
     802             :                         try
     803             :                         {
     804           0 :                             xTargetProps->setPropertyValue(
     805           0 :                                 aPropertiesList[nInd].Name,
     806           0 :                                 xOrigProps->getPropertyValue( aPropertiesList[nInd].Name ) );
     807             :                         }
     808           0 :                         catch (const beans::PropertyVetoException&)
     809             :                         {
     810             :                             // impossibility to copy readonly property is not treated as an error for now
     811             :                             // but the assertion is helpful to detect such scenarios and review them
     812             :                             OSL_FAIL( "Could not copy readonly property!\n" );
     813             :                         }
     814           0 :                     }
     815             :                 }
     816             : 
     817           0 :                    if ( xResult.is() )
     818           0 :                     AddEmbeddedObject( xResult, rName );
     819             :             }
     820           0 :             catch (const uno::Exception&)
     821             :             {
     822           0 :                 if ( xResult.is() )
     823             :                 {
     824             :                     try
     825             :                     {
     826           0 :                         xResult->close( sal_True );
     827             :                     }
     828           0 :                     catch (const uno::Exception&)
     829             :                     {
     830             :                     }
     831           0 :                     xResult = uno::Reference< embed::XEmbeddedObject >();
     832             :                 }
     833             :             }
     834             :         }
     835             :     }
     836             : 
     837             :     OSL_ENSURE( xResult.is(), "Can not copy embedded object that has no persistance!\n" );
     838             : 
     839           0 :     if ( xResult.is() )
     840             :     {
     841             :         // the object is successfully copied, try to copy graphical replacement
     842           0 :         if ( !aOrigName.isEmpty() )
     843           0 :             TryToCopyGraphReplacement( rSrc, aOrigName, rName );
     844             : 
     845             :         // the object might need the size to be set
     846             :         try
     847             :         {
     848           0 :             if ( xResult->getStatus( embed::Aspects::MSOLE_CONTENT ) & embed::EmbedMisc::EMBED_NEEDSSIZEONLOAD )
     849           0 :                 xResult->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT,
     850           0 :                                             xObj->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT ) );
     851             :         }
     852           0 :         catch (const uno::Exception&)
     853             :         {
     854             :         }
     855             :     }
     856             : 
     857           0 :     return xResult;
     858             : }
     859             : 
     860           0 : sal_Bool EmbeddedObjectContainer::MoveEmbeddedObject( EmbeddedObjectContainer& rSrc, const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName )
     861             : {
     862             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::MoveEmbeddedObject( Object )" );
     863             : 
     864             :     // get the object name before(!) it is assigned to a new storage
     865           0 :     uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
     866           0 :     ::rtl::OUString aName;
     867           0 :     if ( xPersist.is() )
     868           0 :         aName = xPersist->getEntryName();
     869             : 
     870             :     // now move the object to the new container; the returned name is the new persist name in this container
     871             :     sal_Bool bRet;
     872             : 
     873             :     try
     874             :     {
     875           0 :         bRet = InsertEmbeddedObject( xObj, rName );
     876           0 :         if ( bRet )
     877           0 :             TryToCopyGraphReplacement( rSrc, aName, rName );
     878             :     }
     879           0 :     catch (const uno::Exception&)
     880             :     {
     881             :         OSL_FAIL( "Failed to insert embedded object into storage!" );
     882           0 :         bRet = sal_False;
     883             :     }
     884             : 
     885           0 :     if ( bRet )
     886             :     {
     887             :         // now remove the object from the former container
     888           0 :         bRet = sal_False;
     889           0 :         EmbeddedObjectContainerNameMap::iterator aIt = rSrc.pImpl->maObjectContainer.begin();
     890           0 :         while ( aIt != rSrc.pImpl->maObjectContainer.end() )
     891             :         {
     892           0 :             if ( (*aIt).second == xObj )
     893             :             {
     894           0 :                 rSrc.pImpl->maObjectContainer.erase( aIt );
     895           0 :                 bRet = sal_True;
     896           0 :                 break;
     897             :             }
     898             : 
     899           0 :             ++aIt;
     900             :         }
     901             : 
     902             :         OSL_ENSURE( bRet, "Object not found for removal!" );
     903           0 :         if ( xPersist.is() )
     904             :         {
     905             :             // now it's time to remove the storage from the container storage
     906             :             try
     907             :             {
     908           0 :                 if ( xPersist.is() )
     909           0 :                     rSrc.pImpl->mxStorage->removeElement( aName );
     910             :             }
     911           0 :             catch (const uno::Exception&)
     912             :             {
     913             :                 OSL_FAIL( "Failed to remove object from storage!" );
     914           0 :                 bRet = sal_False;
     915             :             }
     916             :         }
     917             : 
     918             :         // rSrc.RemoveGraphicStream( aName );
     919             :     }
     920             : 
     921           0 :     return bRet;
     922             : }
     923             : 
     924           0 : sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const ::rtl::OUString& rName, sal_Bool bClose )
     925             : {
     926             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::RemoveEmbeddedObject( Name )" );
     927             : 
     928           0 :     uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObject( rName );
     929           0 :     if ( xObj.is() )
     930           0 :         return RemoveEmbeddedObject( xObj, bClose );
     931             :     else
     932           0 :         return sal_False;
     933             : }
     934             : 
     935           0 : sal_Bool EmbeddedObjectContainer::MoveEmbeddedObject( const ::rtl::OUString& rName, EmbeddedObjectContainer& rCnt )
     936             : {
     937             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::MoveEmbeddedObject( Name )" );
     938             : 
     939             :     // find object entry
     940           0 :     EmbeddedObjectContainerNameMap::iterator aIt2 = rCnt.pImpl->maObjectContainer.find( rName );
     941             :     OSL_ENSURE( aIt2 == rCnt.pImpl->maObjectContainer.end(), "Object does already exist in target container!" );
     942             : 
     943           0 :     if ( aIt2 != rCnt.pImpl->maObjectContainer.end() )
     944           0 :         return sal_False;
     945             : 
     946           0 :     uno::Reference < embed::XEmbeddedObject > xObj;
     947           0 :     EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName );
     948           0 :     if ( aIt != pImpl->maObjectContainer.end() )
     949             :     {
     950           0 :         xObj = (*aIt).second;
     951             :         try
     952             :         {
     953           0 :             if ( xObj.is() )
     954             :             {
     955             :                 // move object
     956           0 :                 ::rtl::OUString aName( rName );
     957           0 :                 rCnt.InsertEmbeddedObject( xObj, aName );
     958           0 :                 pImpl->maObjectContainer.erase( aIt );
     959           0 :                 uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
     960           0 :                 if ( xPersist.is() )
     961           0 :                     pImpl->mxStorage->removeElement( rName );
     962             :             }
     963             :             else
     964             :             {
     965             :                 // copy storages; object *must* have persistence!
     966           0 :                 uno::Reference < embed::XStorage > xOld = pImpl->mxStorage->openStorageElement( rName, embed::ElementModes::READ );
     967           0 :                 uno::Reference < embed::XStorage > xNew = rCnt.pImpl->mxStorage->openStorageElement( rName, embed::ElementModes::READWRITE );
     968           0 :                 xOld->copyToStorage( xNew );
     969             :             }
     970             : 
     971           0 :             rCnt.TryToCopyGraphReplacement( *this, rName, rName );
     972             :             // RemoveGraphicStream( rName );
     973             : 
     974           0 :             return sal_True;
     975             :         }
     976           0 :         catch (const uno::Exception&)
     977             :         {
     978             :             OSL_FAIL("Could not move object!");
     979           0 :             return sal_False;
     980             :         }
     981             : 
     982             :     }
     983             :     else
     984             :         OSL_FAIL("Unknown object!");
     985           0 :     return sal_False;
     986             : }
     987             : 
     988           0 : sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj, sal_Bool bClose )
     989             : {
     990             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::RemoveEmbeddedObject( Object )" );
     991             : 
     992           0 :     uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
     993           0 :     ::rtl::OUString aName;
     994           0 :     if ( xPersist.is() )
     995           0 :         aName = xPersist->getEntryName();
     996             : 
     997             : #if OSL_DEBUG_LEVEL > 1
     998             :     uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY );
     999             :     uno::Reference < embed::XLinkageSupport > xLink( xPersist, uno::UNO_QUERY );
    1000             :     sal_Bool bIsNotEmbedded = !xPersist.is() || ( xLink.is() && xLink->isLink() );
    1001             : 
    1002             :     // if the object has a persistance and the object is not a link than it must have persistence entry in the storage
    1003             :     OSL_ENSURE( bIsNotEmbedded || xAccess->hasByName(aName), "Removing element not present in storage!" );
    1004             : #endif
    1005             : 
    1006             :     // try to close it if permitted
    1007           0 :     if ( bClose )
    1008             :     {
    1009           0 :         uno::Reference < ::util::XCloseable > xClose( xObj, uno::UNO_QUERY );
    1010             :         try
    1011             :         {
    1012           0 :             xClose->close( sal_True );
    1013             :         }
    1014           0 :         catch (const util::CloseVetoException&)
    1015             :         {
    1016           0 :             bClose = sal_False;
    1017           0 :         }
    1018             :     }
    1019             : 
    1020           0 :     if ( !bClose )
    1021             :     {
    1022             :         // somebody still needs the object, so we must assign a temporary persistence
    1023             :         try
    1024             :         {
    1025           0 :             if ( xPersist.is() )
    1026             :             {
    1027             :                 /*
    1028             :                 //TODO/LATER: needs storage handling!  Why not letting the object do it?!
    1029             :                 if ( !pImpl->mxTempStorage.is() )
    1030             :                     pImpl->mxTempStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
    1031             :                 uno::Sequence < beans::PropertyValue > aSeq;
    1032             : 
    1033             :                 ::rtl::OUString aTmpPersistName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Object ") );
    1034             :                 aTmpPersistName += ::rtl::OUString::valueOf( (sal_Int32) pImpl->maTempObjectContainer.size() );
    1035             : 
    1036             :                 xPersist->storeAsEntry( pImpl->mxTempStorage, aTmpPersistName, aSeq, aSeq );
    1037             :                 xPersist->saveCompleted( sal_True );
    1038             : 
    1039             :                 pImpl->maTempObjectContainer[ aTmpPersistName ] = uno::Reference < embed::XEmbeddedObject >();
    1040             :                 */
    1041             : 
    1042           0 :                 if ( !pImpl->mpTempObjectContainer )
    1043             :                 {
    1044           0 :                     pImpl->mpTempObjectContainer = new EmbeddedObjectContainer();
    1045             :                     try
    1046             :                     {
    1047             :                         // TODO/LATER: in future probably the temporary container will have two storages ( of two formats )
    1048             :                         //             the media type will be provided with object insertion
    1049           0 :                         ::rtl::OUString aOrigStorMediaType;
    1050           0 :                         uno::Reference< beans::XPropertySet > xStorProps( pImpl->mxStorage, uno::UNO_QUERY_THROW );
    1051           0 :                         static const ::rtl::OUString s_sMediaType(RTL_CONSTASCII_USTRINGPARAM("MediaType"));
    1052           0 :                         xStorProps->getPropertyValue( s_sMediaType ) >>= aOrigStorMediaType;
    1053             : 
    1054             :                         OSL_ENSURE( !aOrigStorMediaType.isEmpty(), "No valuable media type in the storage!\n" );
    1055             : 
    1056             :                         uno::Reference< beans::XPropertySet > xTargetStorProps(
    1057             :                                                                     pImpl->mpTempObjectContainer->pImpl->mxStorage,
    1058           0 :                                                                     uno::UNO_QUERY_THROW );
    1059           0 :                         xTargetStorProps->setPropertyValue( s_sMediaType,uno::makeAny( aOrigStorMediaType ) );
    1060             :                     }
    1061           0 :                     catch (const uno::Exception&)
    1062             :                     {
    1063             :                         OSL_FAIL( "Can not set the new media type to a storage!\n" );
    1064             :                     }
    1065             :                 }
    1066             : 
    1067           0 :                 ::rtl::OUString aTempName, aMediaType;
    1068           0 :                 pImpl->mpTempObjectContainer->InsertEmbeddedObject( xObj, aTempName );
    1069             : 
    1070           0 :                 uno::Reference < io::XInputStream > xStream = GetGraphicStream( xObj, &aMediaType );
    1071           0 :                 if ( xStream.is() )
    1072           0 :                     pImpl->mpTempObjectContainer->InsertGraphicStream( xStream, aTempName, aMediaType );
    1073             : 
    1074             :                 // object is stored, so at least it can be set to loaded state
    1075           0 :                 xObj->changeState( embed::EmbedStates::LOADED );
    1076             :             }
    1077             :             else
    1078             :                 // objects without persistence need to stay in running state if they shall not be closed
    1079           0 :                 xObj->changeState( embed::EmbedStates::RUNNING );
    1080             :         }
    1081           0 :         catch (const uno::Exception&)
    1082             :         {
    1083           0 :             return sal_False;
    1084             :         }
    1085             :     }
    1086             : 
    1087           0 :     sal_Bool bFound = sal_False;
    1088           0 :     EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin();
    1089           0 :     while ( aIt != pImpl->maObjectContainer.end() )
    1090             :     {
    1091           0 :         if ( (*aIt).second == xObj )
    1092             :         {
    1093           0 :             pImpl->maObjectContainer.erase( aIt );
    1094           0 :             bFound = sal_True;
    1095           0 :             uno::Reference < container::XChild > xChild( xObj, uno::UNO_QUERY );
    1096           0 :             if ( xChild.is() )
    1097           0 :                 xChild->setParent( uno::Reference < uno::XInterface >() );
    1098           0 :             break;
    1099             :         }
    1100             : 
    1101           0 :         ++aIt;
    1102             :     }
    1103             : 
    1104             :     OSL_ENSURE( bFound, "Object not found for removal!" );
    1105             :     (void)bFound;
    1106           0 :     if ( xPersist.is() )
    1107             :     {
    1108             :         // remove replacement image (if there is one)
    1109           0 :         RemoveGraphicStream( aName );
    1110             : 
    1111             :         // now it's time to remove the storage from the container storage
    1112             :         try
    1113             :         {
    1114             : #if OSL_DEBUG_LEVEL > 1
    1115             :             // if the object has a persistance and the object is not a link than it must have persistence entry in storage
    1116             :             OSL_ENSURE( bIsNotEmbedded || pImpl->mxStorage->hasByName( aName ), "The object has no persistence entry in the storage!" );
    1117             : #endif
    1118           0 :             if ( xPersist.is() && pImpl->mxStorage->hasByName( aName ) )
    1119           0 :                 pImpl->mxStorage->removeElement( aName );
    1120             :         }
    1121           0 :         catch (const uno::Exception&)
    1122             :         {
    1123             :             OSL_FAIL( "Failed to remove object from storage!" );
    1124           0 :             return sal_False;
    1125             :         }
    1126             :     }
    1127             : 
    1128           0 :     return sal_True;
    1129             : }
    1130             : 
    1131          96 : sal_Bool EmbeddedObjectContainer::CloseEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj )
    1132             : {
    1133             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::CloseEmbeddedObject" );
    1134             : 
    1135             :     // disconnect the object from the container and close it if possible
    1136             : 
    1137          96 :     sal_Bool bFound = sal_False;
    1138          96 :     EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin();
    1139         428 :     while ( aIt != pImpl->maObjectContainer.end() )
    1140             :     {
    1141         332 :         if ( (*aIt).second == xObj )
    1142             :         {
    1143          96 :             pImpl->maObjectContainer.erase( aIt );
    1144          96 :             bFound = sal_True;
    1145          96 :             break;
    1146             :         }
    1147             : 
    1148         236 :         ++aIt;
    1149             :     }
    1150             : 
    1151          96 :     if ( bFound )
    1152             :     {
    1153          96 :         uno::Reference < ::util::XCloseable > xClose( xObj, uno::UNO_QUERY );
    1154             :         try
    1155             :         {
    1156          96 :             xClose->close( sal_True );
    1157             :         }
    1158          96 :         catch (const uno::Exception&)
    1159             :         {
    1160             :             // it is no problem if the object is already closed
    1161             :             // TODO/LATER: what if the object can not be closed?
    1162          96 :         }
    1163             :     }
    1164             : 
    1165          96 :     return bFound;
    1166             : }
    1167             : 
    1168           2 : uno::Reference < io::XInputStream > EmbeddedObjectContainer::GetGraphicStream( const ::rtl::OUString& aName, rtl::OUString* pMediaType )
    1169             : {
    1170             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::GetGraphicStream( Name )" );
    1171             : 
    1172           2 :     uno::Reference < io::XInputStream > xStream;
    1173             : 
    1174             :     OSL_ENSURE( !aName.isEmpty(), "Retrieving graphic for unknown object!" );
    1175           2 :     if ( !aName.isEmpty() )
    1176             :     {
    1177             :         try
    1178             :         {
    1179           2 :             uno::Reference < embed::XStorage > xReplacements = pImpl->GetReplacements();
    1180           2 :             uno::Reference < io::XStream > xGraphicStream = xReplacements->openStreamElement( aName, embed::ElementModes::READ );
    1181           2 :             xStream = xGraphicStream->getInputStream();
    1182           2 :             if ( pMediaType )
    1183             :             {
    1184           2 :                 uno::Reference < beans::XPropertySet > xSet( xStream, uno::UNO_QUERY );
    1185           2 :                 if ( xSet.is() )
    1186             :                 {
    1187           2 :                     uno::Any aAny = xSet->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType")) );
    1188           2 :                     aAny >>= *pMediaType;
    1189           2 :                 }
    1190           2 :             }
    1191             :         }
    1192           0 :         catch (const uno::Exception&)
    1193             :         {
    1194             :         }
    1195             :     }
    1196             : 
    1197           2 :     return xStream;
    1198             : }
    1199             : 
    1200           2 : uno::Reference < io::XInputStream > EmbeddedObjectContainer::GetGraphicStream( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& xObj, rtl::OUString* pMediaType )
    1201             : {
    1202             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::GetGraphicStream( Object )" );
    1203             : 
    1204             :     // get the object name
    1205           2 :     ::rtl::OUString aName;
    1206           2 :     EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin();
    1207           4 :     while ( aIt != pImpl->maObjectContainer.end() )
    1208             :     {
    1209           2 :         if ( (*aIt).second == xObj )
    1210             :         {
    1211           2 :             aName = (*aIt).first;
    1212           2 :             break;
    1213             :         }
    1214             : 
    1215           0 :         ++aIt;
    1216             :     }
    1217             : 
    1218             :     // try to load it from the container storage
    1219           2 :     return GetGraphicStream( aName, pMediaType );
    1220             : }
    1221             : 
    1222         292 : sal_Bool EmbeddedObjectContainer::InsertGraphicStream( const com::sun::star::uno::Reference < com::sun::star::io::XInputStream >& rStream, const ::rtl::OUString& rObjectName, const rtl::OUString& rMediaType )
    1223             : {
    1224             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertGraphicStream" );
    1225             : 
    1226             :     try
    1227             :     {
    1228         292 :         uno::Reference < embed::XStorage > xReplacements = pImpl->GetReplacements();
    1229             : 
    1230             :         // store it into the subfolder
    1231         292 :         uno::Reference < io::XOutputStream > xOutStream;
    1232         292 :         uno::Reference < io::XStream > xGraphicStream = xReplacements->openStreamElement( rObjectName,
    1233         292 :                 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
    1234         292 :         xOutStream = xGraphicStream->getOutputStream();
    1235         292 :         ::comphelper::OStorageHelper::CopyInputToOutput( rStream, xOutStream );
    1236         292 :         xOutStream->flush();
    1237             : 
    1238         292 :         uno::Reference< beans::XPropertySet > xPropSet( xGraphicStream, uno::UNO_QUERY );
    1239         292 :         if ( !xPropSet.is() )
    1240           0 :             throw uno::RuntimeException();
    1241             : 
    1242         292 :         xPropSet->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption")),
    1243         292 :                                     uno::makeAny( (sal_Bool)sal_True ) );
    1244         292 :         uno::Any aAny;
    1245         292 :         aAny <<= rMediaType;
    1246         292 :         xPropSet->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType")), aAny );
    1247             : 
    1248         292 :         xPropSet->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Compressed")),
    1249         292 :                                     uno::makeAny( (sal_Bool)sal_True ) );
    1250             :     }
    1251           0 :     catch (const uno::Exception&)
    1252             :     {
    1253           0 :         return sal_False;
    1254             :     }
    1255             : 
    1256         292 :     return sal_True;
    1257             : }
    1258             : 
    1259           0 : sal_Bool EmbeddedObjectContainer::InsertGraphicStreamDirectly( const com::sun::star::uno::Reference < com::sun::star::io::XInputStream >& rStream, const ::rtl::OUString& rObjectName, const rtl::OUString& rMediaType )
    1260             : {
    1261             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertGraphicStreamDirectly" );
    1262             : 
    1263             :     try
    1264             :     {
    1265           0 :         uno::Reference < embed::XStorage > xReplacement = pImpl->GetReplacements();
    1266           0 :         uno::Reference < embed::XOptimizedStorage > xOptRepl( xReplacement, uno::UNO_QUERY_THROW );
    1267             : 
    1268             :         // store it into the subfolder
    1269           0 :         uno::Sequence< beans::PropertyValue > aProps( 3 );
    1270           0 :         aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
    1271           0 :         aProps[0].Value <<= rMediaType;
    1272           0 :         aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) );
    1273           0 :         aProps[1].Value <<= (sal_Bool)sal_True;
    1274           0 :         aProps[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) );
    1275           0 :         aProps[2].Value <<= (sal_Bool)sal_True;
    1276             : 
    1277           0 :         if ( xReplacement->hasByName( rObjectName ) )
    1278           0 :             xReplacement->removeElement( rObjectName );
    1279             : 
    1280           0 :         xOptRepl->insertStreamElementDirect( rObjectName, rStream, aProps );
    1281             :     }
    1282           0 :     catch (const uno::Exception&)
    1283             :     {
    1284           0 :         return sal_False;
    1285             :     }
    1286             : 
    1287           0 :     return sal_True;
    1288             : }
    1289             : 
    1290             : 
    1291          80 : sal_Bool EmbeddedObjectContainer::RemoveGraphicStream( const ::rtl::OUString& rObjectName )
    1292             : {
    1293             :     RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::RemoveGraphicStream" );
    1294             : 
    1295             :     try
    1296             :     {
    1297          80 :         uno::Reference < embed::XStorage > xReplacements = pImpl->GetReplacements();
    1298         160 :         xReplacements->removeElement( rObjectName );
    1299             :     }
    1300         160 :     catch (const uno::Exception&)
    1301             :     {
    1302          80 :         return sal_False;
    1303             :     }
    1304             : 
    1305           0 :     return sal_True;
    1306             : }
    1307             : namespace {
    1308           0 :     void InsertStreamIntoPicturesStorage_Impl( const uno::Reference< embed::XStorage >& xDocStor,
    1309             :                                             const uno::Reference< io::XInputStream >& xInStream,
    1310             :                                             const ::rtl::OUString& aStreamName )
    1311             :     {
    1312             :         OSL_ENSURE( !aStreamName.isEmpty() && xInStream.is() && xDocStor.is(), "Misuse of the method!\n" );
    1313             : 
    1314             :         try
    1315             :         {
    1316           0 :             uno::Reference< embed::XStorage > xPictures = xDocStor->openStorageElement(
    1317             :                                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Pictures" ) ),
    1318           0 :                                         embed::ElementModes::READWRITE );
    1319           0 :             uno::Reference< io::XStream > xObjReplStr = xPictures->openStreamElement(
    1320             :                                         aStreamName,
    1321           0 :                                         embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
    1322             :             uno::Reference< io::XOutputStream > xOutStream(
    1323           0 :                                         xObjReplStr->getInputStream(), uno::UNO_QUERY_THROW );
    1324             : 
    1325           0 :             ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xOutStream );
    1326           0 :             xOutStream->closeOutput();
    1327             : 
    1328           0 :             uno::Reference< embed::XTransactedObject > xTransact( xPictures, uno::UNO_QUERY );
    1329           0 :             if ( xTransact.is() )
    1330           0 :                 xTransact->commit();
    1331             :         }
    1332           0 :         catch (const uno::Exception&)
    1333             :         {
    1334             :             OSL_FAIL( "The pictures storage is not available!\n" );
    1335             :         }
    1336           0 :     }
    1337             : 
    1338             : }
    1339             : // -----------------------------------------------------------------------------
    1340         288 : sal_Bool EmbeddedObjectContainer::StoreAsChildren(sal_Bool _bOasisFormat,sal_Bool _bCreateEmbedded,const uno::Reference < embed::XStorage >& _xStorage)
    1341             : {
    1342         288 :     sal_Bool bResult = sal_False;
    1343             :     try
    1344             :     {
    1345         288 :         comphelper::EmbeddedObjectContainer aCnt( _xStorage );
    1346         288 :         const uno::Sequence < ::rtl::OUString > aNames = GetObjectNames();
    1347         288 :         const ::rtl::OUString* pIter = aNames.getConstArray();
    1348         288 :         const ::rtl::OUString* pEnd   = pIter + aNames.getLength();
    1349         288 :         for(;pIter != pEnd;++pIter)
    1350             :         {
    1351           0 :             uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObject( *pIter );
    1352             :             OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!\n" );
    1353           0 :             if ( xObj.is() )
    1354             :             {
    1355           0 :                 sal_Bool bSwitchBackToLoaded = sal_False;
    1356           0 :                 uno::Reference< embed::XLinkageSupport > xLink( xObj, uno::UNO_QUERY );
    1357             : 
    1358           0 :                 uno::Reference < io::XInputStream > xStream;
    1359           0 :                 ::rtl::OUString aMediaType;
    1360             : 
    1361           0 :                 sal_Int32 nCurState = xObj->getCurrentState();
    1362           0 :                 if ( nCurState == embed::EmbedStates::LOADED || nCurState == embed::EmbedStates::RUNNING )
    1363             :                 {
    1364             :                     // means that the object is not active
    1365             :                     // copy replacement image from old to new container
    1366           0 :                     xStream = GetGraphicStream( xObj, &aMediaType );
    1367             :                 }
    1368             : 
    1369           0 :                 if ( !xStream.is() )
    1370             :                 {
    1371             :                     // the image must be regenerated
    1372             :                     // TODO/LATER: another aspect could be used
    1373           0 :                     if ( xObj->getCurrentState() == embed::EmbedStates::LOADED )
    1374           0 :                             bSwitchBackToLoaded = sal_True;
    1375             : 
    1376             :                     xStream = GetGraphicReplacementStream(
    1377             :                                                             embed::Aspects::MSOLE_CONTENT,
    1378             :                                                             xObj,
    1379           0 :                                                             &aMediaType );
    1380             :                 }
    1381             : 
    1382           0 :                 if ( _bOasisFormat || (xLink.is() && xLink->isLink()) )
    1383             :                 {
    1384           0 :                     if ( xStream.is() )
    1385             :                     {
    1386           0 :                         if ( _bOasisFormat )
    1387             :                         {
    1388             :                             // if it is an embedded object or the optimized inserting fails the normal inserting should be done
    1389           0 :                             if ( _bCreateEmbedded
    1390           0 :                                 || !aCnt.InsertGraphicStreamDirectly( xStream, *pIter, aMediaType ) )
    1391           0 :                                 aCnt.InsertGraphicStream( xStream, *pIter, aMediaType );
    1392             :                         }
    1393             :                         else
    1394             :                         {
    1395             :                             // it is a linked object exported into SO7 format
    1396           0 :                             InsertStreamIntoPicturesStorage_Impl( _xStorage, xStream, *pIter );
    1397             :                         }
    1398             :                     }
    1399             :                 }
    1400             : 
    1401           0 :                 uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
    1402           0 :                 if ( xPersist.is() )
    1403             :                 {
    1404           0 :                     uno::Sequence< beans::PropertyValue > aArgs( _bOasisFormat ? 2 : 3 );
    1405           0 :                     aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StoreVisualReplacement" ) );
    1406           0 :                     aArgs[0].Value <<= (sal_Bool)( !_bOasisFormat );
    1407             : 
    1408             :                     // if it is an embedded object or the optimized inserting fails the normal inserting should be done
    1409           0 :                     aArgs[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CanTryOptimization" ) );
    1410           0 :                     aArgs[1].Value <<= !_bCreateEmbedded;
    1411           0 :                     if ( !_bOasisFormat )
    1412             :                     {
    1413             :                         // if object has no cached replacement it will use this one
    1414           0 :                         aArgs[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VisualReplacement" ) );
    1415           0 :                         aArgs[2].Value <<= xStream;
    1416             :                     }
    1417             : 
    1418           0 :                     xPersist->storeAsEntry( _xStorage,
    1419           0 :                                             xPersist->getEntryName(),
    1420             :                                             uno::Sequence< beans::PropertyValue >(),
    1421           0 :                                             aArgs );
    1422             :                 }
    1423             : 
    1424           0 :                 if ( bSwitchBackToLoaded )
    1425             :                     // switch back to loaded state; that way we have a minimum cache confusion
    1426           0 :                     xObj->changeState( embed::EmbedStates::LOADED );
    1427             :             }
    1428           0 :         }
    1429             : 
    1430         288 :         bResult = aCnt.CommitImageSubStorage();
    1431             : 
    1432             :     }
    1433           0 :     catch (const uno::Exception&)
    1434             :     {
    1435             :         // TODO/LATER: error handling
    1436           0 :         bResult = sal_False;
    1437             :     }
    1438             : 
    1439             :     // the old SO6 format does not store graphical replacements
    1440         288 :     if ( !_bOasisFormat && bResult )
    1441             :     {
    1442             :         try
    1443             :         {
    1444             :             // the substorage still can not be locked by the embedded object conteiner
    1445           0 :             ::rtl::OUString aObjReplElement( RTL_CONSTASCII_USTRINGPARAM( "ObjectReplacements" ) );
    1446           0 :             if ( _xStorage->hasByName( aObjReplElement ) && _xStorage->isStorageElement( aObjReplElement ) )
    1447           0 :                 _xStorage->removeElement( aObjReplElement );
    1448             :         }
    1449           0 :         catch (const uno::Exception&)
    1450             :         {
    1451             :             // TODO/LATER: error handling;
    1452           0 :             bResult = sal_False;
    1453             :         }
    1454             :     }
    1455         288 :     return bResult;
    1456             : }
    1457             : // -----------------------------------------------------------------------------
    1458           0 : sal_Bool EmbeddedObjectContainer::StoreChildren(sal_Bool _bOasisFormat,sal_Bool _bObjectsOnly)
    1459             : {
    1460           0 :     sal_Bool bResult = sal_True;
    1461           0 :     const uno::Sequence < ::rtl::OUString > aNames = GetObjectNames();
    1462           0 :     const ::rtl::OUString* pIter = aNames.getConstArray();
    1463           0 :     const ::rtl::OUString* pEnd   = pIter + aNames.getLength();
    1464           0 :     for(;pIter != pEnd;++pIter)
    1465             :     {
    1466           0 :         uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObject( *pIter );
    1467             :         OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!\n" );
    1468           0 :         if ( xObj.is() )
    1469             :         {
    1470           0 :             sal_Int32 nCurState = xObj->getCurrentState();
    1471           0 :             if ( _bOasisFormat && nCurState != embed::EmbedStates::LOADED && nCurState != embed::EmbedStates::RUNNING )
    1472             :             {
    1473             :                 // means that the object is active
    1474             :                 // the image must be regenerated
    1475           0 :                 ::rtl::OUString aMediaType;
    1476             : 
    1477             :                 // TODO/LATER: another aspect could be used
    1478             :                 uno::Reference < io::XInputStream > xStream =
    1479             :                             GetGraphicReplacementStream(
    1480             :                                                         embed::Aspects::MSOLE_CONTENT,
    1481             :                                                         xObj,
    1482           0 :                                                         &aMediaType );
    1483           0 :                 if ( xStream.is() )
    1484             :                 {
    1485           0 :                     if ( !InsertGraphicStreamDirectly( xStream, *pIter, aMediaType ) )
    1486           0 :                         InsertGraphicStream( xStream, *pIter, aMediaType );
    1487           0 :                 }
    1488             :             }
    1489             : 
    1490             :             // TODO/LATER: currently the object by default does not cache replacement image
    1491             :             // that means that if somebody loads SO7 document and store its objects using
    1492             :             // this method the images might be lost.
    1493             :             // Currently this method is only used on storing to alien formats, that means
    1494             :             // that SO7 documents storing does not use it, and all other filters are
    1495             :             // based on OASIS format. But if it changes the method must be fixed. The fix
    1496             :             // must be done only on demand since it can affect performance.
    1497             : 
    1498           0 :             uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
    1499           0 :             if ( xPersist.is() )
    1500             :             {
    1501             :                 try
    1502             :                 {
    1503             :                     //TODO/LATER: only storing if changed!
    1504           0 :                     xPersist->storeOwn();
    1505             :                 }
    1506           0 :                 catch (const uno::Exception&)
    1507             :                 {
    1508             :                     // TODO/LATER: error handling
    1509           0 :                     bResult = sal_False;
    1510             :                     break;
    1511             :                 }
    1512             :             }
    1513             : 
    1514           0 :             if ( !_bOasisFormat && !_bObjectsOnly )
    1515             :             {
    1516             :                 // copy replacement images for linked objects
    1517             :                 try
    1518             :                 {
    1519           0 :                     uno::Reference< embed::XLinkageSupport > xLink( xObj, uno::UNO_QUERY );
    1520           0 :                     if ( xLink.is() && xLink->isLink() )
    1521             :                     {
    1522           0 :                         ::rtl::OUString aMediaType;
    1523           0 :                         uno::Reference < io::XInputStream > xInStream = GetGraphicStream( xObj, &aMediaType );
    1524           0 :                         if ( xInStream.is() )
    1525           0 :                             InsertStreamIntoPicturesStorage_Impl( pImpl->mxStorage, xInStream, *pIter );
    1526           0 :                     }
    1527             :                 }
    1528           0 :                 catch (const uno::Exception&)
    1529             :                 {
    1530             :                 }
    1531           0 :             }
    1532             :         }
    1533           0 :     }
    1534             : 
    1535           0 :     if ( bResult && _bOasisFormat )
    1536           0 :         bResult = CommitImageSubStorage();
    1537             : 
    1538           0 :     if ( bResult && !_bObjectsOnly )
    1539             :     {
    1540             :         try
    1541             :         {
    1542           0 :             ReleaseImageSubStorage();
    1543           0 :             ::rtl::OUString aObjReplElement( RTL_CONSTASCII_USTRINGPARAM( "ObjectReplacements" ) );
    1544           0 :             if ( !_bOasisFormat && pImpl->mxStorage->hasByName( aObjReplElement ) && pImpl->mxStorage->isStorageElement( aObjReplElement ) )
    1545           0 :                 pImpl->mxStorage->removeElement( aObjReplElement );
    1546             :         }
    1547           0 :         catch (const uno::Exception&)
    1548             :         {
    1549             :             // TODO/LATER: error handling
    1550           0 :             bResult = sal_False;
    1551             :         }
    1552             :     }
    1553           0 :     return bResult;
    1554             : }
    1555             : // -----------------------------------------------------------------------------
    1556        4544 : uno::Reference< io::XInputStream > EmbeddedObjectContainer::GetGraphicReplacementStream(
    1557             :                                                                 sal_Int64 nViewAspect,
    1558             :                                                                 const uno::Reference< embed::XEmbeddedObject >& xObj,
    1559             :                                                                 ::rtl::OUString* pMediaType )
    1560             : {
    1561        4544 :     uno::Reference< io::XInputStream > xInStream;
    1562        4544 :     if ( xObj.is() )
    1563             :     {
    1564             :         try
    1565             :         {
    1566             :             // retrieving of the visual representation can switch object to running state
    1567        4544 :             embed::VisualRepresentation aRep = xObj->getPreferredVisualRepresentation( nViewAspect );
    1568        4544 :             if ( pMediaType )
    1569        4544 :                 *pMediaType = aRep.Flavor.MimeType;
    1570             : 
    1571        4544 :             uno::Sequence < sal_Int8 > aSeq;
    1572        4544 :             aRep.Data >>= aSeq;
    1573        4544 :             xInStream = new ::comphelper::SequenceInputStream( aSeq );
    1574             :         }
    1575           0 :         catch (const uno::Exception&)
    1576             :         {
    1577             :         }
    1578             :     }
    1579             : 
    1580        4544 :     return xInStream;
    1581             : }
    1582             : // -----------------------------------------------------------------------------
    1583         570 : sal_Bool EmbeddedObjectContainer::SetPersistentEntries(const uno::Reference< embed::XStorage >& _xStorage,bool _bClearModifedFlag)
    1584             : {
    1585         570 :     sal_Bool bError = sal_False;
    1586         570 :     const uno::Sequence < ::rtl::OUString > aNames = GetObjectNames();
    1587         570 :     const ::rtl::OUString* pIter = aNames.getConstArray();
    1588         570 :     const ::rtl::OUString* pEnd   = pIter + aNames.getLength();
    1589         570 :     for(;pIter != pEnd;++pIter)
    1590             :     {
    1591           0 :         uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObject( *pIter );
    1592             :         OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!\n" );
    1593           0 :         if ( xObj.is() )
    1594             :         {
    1595           0 :             uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
    1596           0 :             if ( xPersist.is() )
    1597             :             {
    1598             :                 try
    1599             :                 {
    1600           0 :                     xPersist->setPersistentEntry( _xStorage,
    1601             :                                                 *pIter,
    1602             :                                                 embed::EntryInitModes::NO_INIT,
    1603             :                                                 uno::Sequence< beans::PropertyValue >(),
    1604           0 :                                                 uno::Sequence< beans::PropertyValue >() );
    1605             : 
    1606             :                 }
    1607           0 :                 catch (const uno::Exception&)
    1608             :                 {
    1609             :                     // TODO/LATER: error handling
    1610           0 :                     bError = sal_True;
    1611             :                     break;
    1612             :                 }
    1613             :             }
    1614           0 :             if ( _bClearModifedFlag )
    1615             :             {
    1616             :                 // if this method is used as part of SaveCompleted the object must stay unmodified after execution
    1617             :                 try
    1618             :                 {
    1619           0 :                     uno::Reference< util::XModifiable > xModif( xObj->getComponent(), uno::UNO_QUERY_THROW );
    1620           0 :                     if ( xModif->isModified() )
    1621           0 :                         xModif->setModified( sal_False );
    1622             :                 }
    1623           0 :                 catch (const uno::Exception&)
    1624             :                 {
    1625             :                 }
    1626           0 :             }
    1627             :         }
    1628           0 :     }
    1629         570 :     return bError;
    1630             : }
    1631             : }
    1632             : 
    1633             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10