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

Generated by: LCOV version 1.10