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