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