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