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