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