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_embeddedobj.hxx" 26 27 #include <commonembobj.hxx> 28 #include <com/sun/star/embed/Aspects.hpp> 29 #include <com/sun/star/document/XStorageBasedDocument.hpp> 30 #include <com/sun/star/embed/EmbedStates.hpp> 31 #include <com/sun/star/embed/EmbedVerbs.hpp> 32 #include <com/sun/star/embed/EntryInitModes.hpp> 33 #include <com/sun/star/embed/XStorage.hpp> 34 #include <com/sun/star/embed/XOptimizedStorage.hpp> 35 #include <com/sun/star/embed/ElementModes.hpp> 36 #include <com/sun/star/embed/EmbedUpdateModes.hpp> 37 #include <com/sun/star/frame/XModel.hpp> 38 #include <com/sun/star/frame/XStorable.hpp> 39 #include <com/sun/star/frame/XLoadable.hpp> 40 #include <com/sun/star/frame/XComponentLoader.hpp> 41 #include <com/sun/star/frame/XModule.hpp> 42 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 43 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 44 #include <com/sun/star/lang/DisposedException.hpp> 45 #include <com/sun/star/util/XModifiable.hpp> 46 47 #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCEESS_HPP_ 48 #include <com/sun/star/container/XNameAccess.hpp> 49 #endif 50 #include <com/sun/star/container/XChild.hpp> 51 #include <com/sun/star/util/XCloseable.hpp> 52 #include <com/sun/star/beans/XPropertySet.hpp> 53 #include <com/sun/star/beans/IllegalTypeException.hpp> 54 #include <com/sun/star/chart2/XChartDocument.hpp> 55 56 #include <comphelper/fileformat.h> 57 #include <comphelper/storagehelper.hxx> 58 #include <comphelper/mimeconfighelper.hxx> 59 #include <comphelper/namedvaluecollection.hxx> 60 61 #include <rtl/logfile.hxx> 62 63 #include <tools/diagnose_ex.h> 64 65 #define USE_STORAGEBASED_DOCUMENT 66 67 using namespace ::com::sun::star; 68 69 70 //------------------------------------------------------ 71 uno::Sequence< beans::PropertyValue > GetValuableArgs_Impl( const uno::Sequence< beans::PropertyValue >& aMedDescr, 72 sal_Bool bCanUseDocumentBaseURL ) 73 { 74 uno::Sequence< beans::PropertyValue > aResult; 75 sal_Int32 nResLen = 0; 76 77 for ( sal_Int32 nInd = 0; nInd < aMedDescr.getLength(); nInd++ ) 78 { 79 if ( aMedDescr[nInd].Name.equalsAscii( "ComponentData" ) 80 || aMedDescr[nInd].Name.equalsAscii( "DocumentTitle" ) 81 || aMedDescr[nInd].Name.equalsAscii( "InteractionHandler" ) 82 || aMedDescr[nInd].Name.equalsAscii( "JumpMark" ) 83 // || aMedDescr[nInd].Name.equalsAscii( "Password" ) makes no sence for embedded objects 84 || aMedDescr[nInd].Name.equalsAscii( "Preview" ) 85 || aMedDescr[nInd].Name.equalsAscii( "ReadOnly" ) 86 || aMedDescr[nInd].Name.equalsAscii( "StartPresentation" ) 87 || aMedDescr[nInd].Name.equalsAscii( "RepairPackage" ) 88 || aMedDescr[nInd].Name.equalsAscii( "StatusIndicator" ) 89 || aMedDescr[nInd].Name.equalsAscii( "ViewData" ) 90 || aMedDescr[nInd].Name.equalsAscii( "ViewId" ) 91 || aMedDescr[nInd].Name.equalsAscii( "MacroExecutionMode" ) 92 || aMedDescr[nInd].Name.equalsAscii( "UpdateDocMode" ) 93 || (aMedDescr[nInd].Name.equalsAscii( "DocumentBaseURL" ) && bCanUseDocumentBaseURL) ) 94 { 95 aResult.realloc( ++nResLen ); 96 aResult[nResLen-1] = aMedDescr[nInd]; 97 } 98 } 99 100 return aResult; 101 } 102 103 //------------------------------------------------------ 104 uno::Sequence< beans::PropertyValue > addAsTemplate( const uno::Sequence< beans::PropertyValue >& aOrig ) 105 { 106 sal_Bool bAsTemplateSet = sal_False; 107 sal_Int32 nLength = aOrig.getLength(); 108 uno::Sequence< beans::PropertyValue > aResult( nLength ); 109 110 for ( sal_Int32 nInd = 0; nInd < nLength; nInd++ ) 111 { 112 aResult[nInd].Name = aOrig[nInd].Name; 113 if ( aResult[nInd].Name.equalsAscii( "AsTemplate" ) ) 114 { 115 aResult[nInd].Value <<= sal_True; 116 bAsTemplateSet = sal_True; 117 } 118 else 119 aResult[nInd].Value = aOrig[nInd].Value; 120 } 121 122 if ( !bAsTemplateSet ) 123 { 124 aResult.realloc( nLength + 1 ); 125 aResult[nLength].Name = ::rtl::OUString::createFromAscii( "AsTemplate" ); 126 aResult[nLength].Value <<= sal_True; 127 } 128 129 return aResult; 130 } 131 132 //------------------------------------------------------ 133 uno::Reference< io::XInputStream > createTempInpStreamFromStor( 134 const uno::Reference< embed::XStorage >& xStorage, 135 const uno::Reference< lang::XMultiServiceFactory >& xFactory ) 136 { 137 OSL_ENSURE( xStorage.is(), "The storage can not be empty!" ); 138 139 uno::Reference< io::XInputStream > xResult; 140 141 const ::rtl::OUString aServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.TempFile" ) ); 142 uno::Reference < io::XStream > xTempStream = uno::Reference < io::XStream > ( 143 xFactory->createInstance ( aServiceName ), 144 uno::UNO_QUERY ); 145 if ( xTempStream.is() ) 146 { 147 uno::Reference < lang::XSingleServiceFactory > xStorageFactory( 148 xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ), 149 uno::UNO_QUERY ); 150 151 uno::Sequence< uno::Any > aArgs( 2 ); 152 aArgs[0] <<= xTempStream; 153 aArgs[1] <<= embed::ElementModes::READWRITE; 154 uno::Reference< embed::XStorage > xTempStorage( xStorageFactory->createInstanceWithArguments( aArgs ), 155 uno::UNO_QUERY ); 156 if ( !xTempStorage.is() ) 157 throw uno::RuntimeException(); // TODO: 158 159 try 160 { 161 xStorage->copyToStorage( xTempStorage ); 162 } catch( uno::Exception& e ) 163 { 164 throw embed::StorageWrappedTargetException( 165 ::rtl::OUString::createFromAscii( "Can't copy storage!" ), 166 uno::Reference< uno::XInterface >(), 167 uno::makeAny( e ) ); 168 } 169 170 try { 171 uno::Reference< lang::XComponent > xComponent( xTempStorage, uno::UNO_QUERY ); 172 OSL_ENSURE( xComponent.is(), "Wrong storage implementation!" ); 173 if ( xComponent.is() ) 174 xComponent->dispose(); 175 } 176 catch ( uno::Exception& ) 177 { 178 } 179 180 try { 181 uno::Reference< io::XOutputStream > xTempOut = xTempStream->getOutputStream(); 182 if ( xTempOut.is() ) 183 xTempOut->closeOutput(); 184 } 185 catch ( uno::Exception& ) 186 { 187 } 188 189 xResult = xTempStream->getInputStream(); 190 } 191 192 return xResult; 193 194 } 195 196 //------------------------------------------------------ 197 static void TransferMediaType( const uno::Reference< embed::XStorage >& i_rSource, const uno::Reference< embed::XStorage >& i_rTarget ) 198 { 199 try 200 { 201 const uno::Reference< beans::XPropertySet > xSourceProps( i_rSource, uno::UNO_QUERY_THROW ); 202 const uno::Reference< beans::XPropertySet > xTargetProps( i_rTarget, uno::UNO_QUERY_THROW ); 203 const ::rtl::OUString sMediaTypePropName( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ); 204 xTargetProps->setPropertyValue( sMediaTypePropName, xSourceProps->getPropertyValue( sMediaTypePropName ) ); 205 } 206 catch( const uno::Exception& ) 207 { 208 DBG_UNHANDLED_EXCEPTION(); 209 } 210 } 211 212 //------------------------------------------------------ 213 static uno::Reference< util::XCloseable > CreateDocument( const uno::Reference< lang::XMultiServiceFactory >& _rxFactory, 214 const ::rtl::OUString& _rDocumentServiceName, bool _bEmbeddedScriptSupport, const bool i_bDocumentRecoverySupport ) 215 { 216 ::comphelper::NamedValueCollection aArguments; 217 aArguments.put( "EmbeddedObject", (sal_Bool)sal_True ); 218 aArguments.put( "EmbeddedScriptSupport", (sal_Bool)_bEmbeddedScriptSupport ); 219 aArguments.put( "DocumentRecoverySupport", (sal_Bool)i_bDocumentRecoverySupport ); 220 221 uno::Reference< uno::XInterface > xDocument; 222 try 223 { 224 xDocument = _rxFactory->createInstanceWithArguments( _rDocumentServiceName, aArguments.getWrappedPropertyValues() ); 225 } 226 catch( const uno::Exception& ) 227 { 228 // if an embedded object implementation does not support XInitialization, 229 // the default factory from cppuhelper will throw an 230 // IllegalArgumentException when we try to create the instance with arguments. 231 // Okay, so we fall back to creating the instance without any arguments. 232 OSL_ASSERT("Consider implementing interface XInitialization to avoid duplicate construction"); 233 xDocument = _rxFactory->createInstance( _rDocumentServiceName ); 234 } 235 236 return uno::Reference< util::XCloseable >( xDocument, uno::UNO_QUERY ); 237 } 238 239 //------------------------------------------------------ 240 static void SetDocToEmbedded( const uno::Reference< frame::XModel > xDocument, const ::rtl::OUString& aModuleName ) 241 { 242 if ( xDocument.is() ) 243 { 244 uno::Sequence< beans::PropertyValue > aSeq( 1 ); 245 aSeq[0].Name = ::rtl::OUString::createFromAscii( "SetEmbedded" ); 246 aSeq[0].Value <<= sal_True; 247 xDocument->attachResource( ::rtl::OUString(), aSeq ); 248 249 if ( aModuleName.getLength() ) 250 { 251 try 252 { 253 uno::Reference< frame::XModule > xModule( xDocument, uno::UNO_QUERY_THROW ); 254 xModule->setIdentifier( aModuleName ); 255 } 256 catch( uno::Exception& ) 257 {} 258 } 259 } 260 } 261 262 //------------------------------------------------------ 263 void OCommonEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStorage >& xNewParentStorage, 264 const uno::Reference< embed::XStorage >& xNewObjectStorage, 265 const ::rtl::OUString& aNewName ) 266 { 267 if ( xNewParentStorage == m_xParentStorage && aNewName.equals( m_aEntryName ) ) 268 { 269 OSL_ENSURE( xNewObjectStorage == m_xObjectStorage, "The storage must be the same!\n" ); 270 return; 271 } 272 273 uno::Reference< lang::XComponent > xComponent( m_xObjectStorage, uno::UNO_QUERY ); 274 OSL_ENSURE( !m_xObjectStorage.is() || xComponent.is(), "Wrong storage implementation!" ); 275 276 m_xObjectStorage = xNewObjectStorage; 277 m_xParentStorage = xNewParentStorage; 278 m_aEntryName = aNewName; 279 280 #ifdef USE_STORAGEBASED_DOCUMENT 281 // the linked document should not be switched 282 if ( !m_bIsLink ) 283 { 284 uno::Reference< document::XStorageBasedDocument > xDoc( m_pDocHolder->GetComponent(), uno::UNO_QUERY ); 285 if ( xDoc.is() ) 286 SwitchDocToStorage_Impl( xDoc, m_xObjectStorage ); 287 } 288 #endif 289 290 try { 291 if ( xComponent.is() ) 292 xComponent->dispose(); 293 } 294 catch ( uno::Exception& ) 295 { 296 } 297 } 298 299 //------------------------------------------------------ 300 void OCommonEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStorage >& xNewParentStorage, 301 const ::rtl::OUString& aNewName ) 302 { 303 if ( xNewParentStorage == m_xParentStorage && aNewName.equals( m_aEntryName ) ) 304 return; 305 306 sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE; 307 308 uno::Reference< embed::XStorage > xNewOwnStorage = xNewParentStorage->openStorageElement( aNewName, nStorageMode ); 309 OSL_ENSURE( xNewOwnStorage.is(), "The method can not return empty reference!" ); 310 311 SwitchOwnPersistence( xNewParentStorage, xNewOwnStorage, aNewName ); 312 } 313 314 //------------------------------------------------------ 315 void OCommonEmbeddedObject::EmbedAndReparentDoc_Impl( const uno::Reference< util::XCloseable >& i_rxDocument ) const 316 { 317 SetDocToEmbedded( uno::Reference< frame::XModel >( i_rxDocument, uno::UNO_QUERY ), m_aModuleName ); 318 319 try 320 { 321 uno::Reference < container::XChild > xChild( i_rxDocument, uno::UNO_QUERY ); 322 if ( xChild.is() ) 323 xChild->setParent( m_xParent ); 324 } 325 catch( const lang::NoSupportException & ) 326 { 327 OSL_ENSURE( false, "OCommonEmbeddedObject::EmbedAndReparentDoc: cannot set parent at document!" ); 328 } 329 } 330 331 //------------------------------------------------------ 332 uno::Reference< util::XCloseable > OCommonEmbeddedObject::InitNewDocument_Impl() 333 { 334 uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xFactory, GetDocumentServiceName(), 335 m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) ); 336 337 uno::Reference< frame::XModel > xModel( xDocument, uno::UNO_QUERY ); 338 uno::Reference< frame::XLoadable > xLoadable( xModel, uno::UNO_QUERY ); 339 if ( !xLoadable.is() ) 340 throw uno::RuntimeException(); 341 342 try 343 { 344 // set the document mode to embedded as the first action on document!!! 345 EmbedAndReparentDoc_Impl( xDocument ); 346 347 // if we have a storage to recover the document from, do not use initNew, but instead load from that storage 348 bool bInitNew = true; 349 if ( m_xRecoveryStorage.is() ) 350 { 351 uno::Reference< document::XStorageBasedDocument > xDoc( xLoadable, uno::UNO_QUERY ); 352 OSL_ENSURE( xDoc.is(), "OCommonEmbeddedObject::InitNewDocument_Impl: cannot recover from a storage when the document is not storage based!" ); 353 if ( xDoc.is() ) 354 { 355 ::comphelper::NamedValueCollection aLoadArgs; 356 FillDefaultLoadArgs_Impl( m_xRecoveryStorage, aLoadArgs ); 357 358 xDoc->loadFromStorage( m_xRecoveryStorage, aLoadArgs.getPropertyValues() ); 359 SwitchDocToStorage_Impl( xDoc, m_xObjectStorage ); 360 bInitNew = false; 361 } 362 } 363 364 if ( bInitNew ) 365 { 366 // init document as a new 367 xLoadable->initNew(); 368 } 369 xModel->attachResource( xModel->getURL(), m_aDocMediaDescriptor ); 370 } 371 catch( uno::Exception& ) 372 { 373 uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY ); 374 if ( xCloseable.is() ) 375 { 376 try 377 { 378 xCloseable->close( sal_True ); 379 } 380 catch( uno::Exception& ) 381 { 382 } 383 } 384 385 throw; // TODO 386 } 387 388 return xDocument; 389 } 390 391 //------------------------------------------------------ 392 uno::Reference< util::XCloseable > OCommonEmbeddedObject::LoadLink_Impl() 393 { 394 uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xFactory, GetDocumentServiceName(), 395 m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) ); 396 397 uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY ); 398 if ( !xLoadable.is() ) 399 throw uno::RuntimeException(); 400 401 sal_Int32 nLen = 2; 402 uno::Sequence< beans::PropertyValue > aArgs( nLen ); 403 aArgs[0].Name = ::rtl::OUString::createFromAscii( "URL" ); 404 aArgs[0].Value <<= m_aLinkURL; 405 aArgs[1].Name = ::rtl::OUString::createFromAscii( "FilterName" ); 406 aArgs[1].Value <<= m_aLinkFilterName; 407 if ( m_bLinkHasPassword ) 408 { 409 aArgs.realloc( ++nLen ); 410 aArgs[nLen-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Password" ) ); 411 aArgs[nLen-1].Value <<= m_aLinkPassword; 412 } 413 414 aArgs.realloc( m_aDocMediaDescriptor.getLength() + nLen ); 415 for ( sal_Int32 nInd = 0; nInd < m_aDocMediaDescriptor.getLength(); nInd++ ) 416 { 417 aArgs[nInd+nLen].Name = m_aDocMediaDescriptor[nInd].Name; 418 aArgs[nInd+nLen].Value = m_aDocMediaDescriptor[nInd].Value; 419 } 420 421 try 422 { 423 // the document is not really an embedded one, it is a link 424 EmbedAndReparentDoc_Impl( xDocument ); 425 426 // load the document 427 xLoadable->load( aArgs ); 428 429 if ( !m_bLinkHasPassword ) 430 { 431 // check if there is a password to cache 432 uno::Reference< frame::XModel > xModel( xLoadable, uno::UNO_QUERY_THROW ); 433 uno::Sequence< beans::PropertyValue > aProps = xModel->getArgs(); 434 for ( sal_Int32 nInd = 0; nInd < aProps.getLength(); nInd++ ) 435 if ( aProps[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Password" ) ) ) 436 && ( aProps[nInd].Value >>= m_aLinkPassword ) ) 437 { 438 m_bLinkHasPassword = sal_True; 439 break; 440 } 441 } 442 } 443 catch( uno::Exception& ) 444 { 445 uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY ); 446 if ( xCloseable.is() ) 447 { 448 try 449 { 450 xCloseable->close( sal_True ); 451 } 452 catch( uno::Exception& ) 453 { 454 } 455 } 456 457 throw; // TODO 458 } 459 460 return xDocument; 461 462 } 463 464 //------------------------------------------------------ 465 ::rtl::OUString OCommonEmbeddedObject::GetFilterName( sal_Int32 nVersion ) const 466 { 467 ::rtl::OUString aFilterName = GetPresetFilterName(); 468 if ( !aFilterName.getLength() ) 469 { 470 try { 471 ::comphelper::MimeConfigurationHelper aHelper( m_xFactory ); 472 aFilterName = aHelper.GetDefaultFilterFromServiceName( GetDocumentServiceName(), nVersion ); 473 } catch( uno::Exception& ) 474 {} 475 } 476 477 return aFilterName; 478 } 479 480 //------------------------------------------------------ 481 void OCommonEmbeddedObject::FillDefaultLoadArgs_Impl( const uno::Reference< embed::XStorage >& i_rxStorage, 482 ::comphelper::NamedValueCollection& o_rLoadArgs ) const 483 { 484 o_rLoadArgs.put( "DocumentBaseURL", GetBaseURL_Impl() ); 485 o_rLoadArgs.put( "HierarchicalDocumentName", m_aEntryName ); 486 o_rLoadArgs.put( "ReadOnly", m_bReadOnly ); 487 488 ::rtl::OUString aFilterName = GetFilterName( ::comphelper::OStorageHelper::GetXStorageFormat( i_rxStorage ) ); 489 OSL_ENSURE( aFilterName.getLength(), "OCommonEmbeddedObject::FillDefaultLoadArgs_Impl: Wrong document service name!" ); 490 if ( !aFilterName.getLength() ) 491 throw io::IOException(); // TODO: error message/code 492 493 o_rLoadArgs.put( "FilterName", aFilterName ); 494 } 495 496 //------------------------------------------------------ 497 uno::Reference< util::XCloseable > OCommonEmbeddedObject::LoadDocumentFromStorage_Impl() 498 { 499 ENSURE_OR_THROW( m_xObjectStorage.is(), "no object storage" ); 500 501 const uno::Reference< embed::XStorage > xSourceStorage( m_xRecoveryStorage.is() ? m_xRecoveryStorage : m_xObjectStorage ); 502 503 uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xFactory, GetDocumentServiceName(), 504 m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) ); 505 506 //#i103460# ODF: take the size given from the parent frame as default 507 uno::Reference< chart2::XChartDocument > xChart( xDocument, uno::UNO_QUERY ); 508 if( xChart.is() ) 509 { 510 uno::Reference< embed::XVisualObject > xChartVisualObject( xChart, uno::UNO_QUERY ); 511 if( xChartVisualObject.is() ) 512 xChartVisualObject->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT, m_aDefaultSizeForChart_In_100TH_MM ); 513 } 514 515 uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY ); 516 uno::Reference< document::XStorageBasedDocument > xDoc 517 #ifdef USE_STORAGEBASED_DOCUMENT 518 ( xDocument, uno::UNO_QUERY ) 519 #endif 520 ; 521 if ( !xDoc.is() && !xLoadable.is() ) ///BUG: This should be || instead of && ? 522 throw uno::RuntimeException(); 523 524 ::comphelper::NamedValueCollection aLoadArgs; 525 FillDefaultLoadArgs_Impl( xSourceStorage, aLoadArgs ); 526 527 uno::Reference< io::XInputStream > xTempInpStream; 528 if ( !xDoc.is() ) 529 { 530 xTempInpStream = createTempInpStreamFromStor( xSourceStorage, m_xFactory ); 531 if ( !xTempInpStream.is() ) 532 throw uno::RuntimeException(); 533 534 ::rtl::OUString aTempFileURL; 535 try 536 { 537 // no need to let the file stay after the stream is removed since the embedded document 538 // can not be stored directly 539 uno::Reference< beans::XPropertySet > xTempStreamProps( xTempInpStream, uno::UNO_QUERY_THROW ); 540 xTempStreamProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) ) >>= aTempFileURL; 541 } 542 catch( uno::Exception& ) 543 { 544 } 545 546 OSL_ENSURE( aTempFileURL.getLength(), "Coudn't retrieve temporary file URL!\n" ); 547 548 aLoadArgs.put( "URL", aTempFileURL ); 549 aLoadArgs.put( "InputStream", xTempInpStream ); 550 } 551 552 // aLoadArgs.put( "AsTemplate", sal_True ); 553 554 aLoadArgs.merge( m_aDocMediaDescriptor, true ); 555 556 try 557 { 558 // set the document mode to embedded as the first step!!! 559 EmbedAndReparentDoc_Impl( xDocument ); 560 561 if ( xDoc.is() ) 562 { 563 xDoc->loadFromStorage( xSourceStorage, aLoadArgs.getPropertyValues() ); 564 if ( xSourceStorage != m_xObjectStorage ) 565 SwitchDocToStorage_Impl( xDoc, m_xObjectStorage ); 566 } 567 else 568 xLoadable->load( aLoadArgs.getPropertyValues() ); 569 } 570 catch( uno::Exception& ) 571 { 572 uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY ); 573 if ( xCloseable.is() ) 574 { 575 try 576 { 577 xCloseable->close( sal_True ); 578 } 579 catch( uno::Exception& ) 580 { 581 DBG_UNHANDLED_EXCEPTION(); 582 } 583 } 584 585 throw; // TODO 586 } 587 588 return xDocument; 589 } 590 591 //------------------------------------------------------ 592 uno::Reference< io::XInputStream > OCommonEmbeddedObject::StoreDocumentToTempStream_Impl( 593 sal_Int32 nStorageFormat, 594 const ::rtl::OUString& aBaseURL, 595 const ::rtl::OUString& aHierarchName ) 596 { 597 uno::Reference < io::XOutputStream > xTempOut( 598 m_xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ), 599 uno::UNO_QUERY ); 600 uno::Reference< io::XInputStream > aResult( xTempOut, uno::UNO_QUERY ); 601 602 if ( !xTempOut.is() || !aResult.is() ) 603 throw uno::RuntimeException(); // TODO: 604 605 uno::Reference< frame::XStorable > xStorable; 606 { 607 osl::MutexGuard aGuard( m_aMutex ); 608 if ( m_pDocHolder ) 609 xStorable = uno::Reference< frame::XStorable > ( m_pDocHolder->GetComponent(), uno::UNO_QUERY ); 610 } 611 612 if( !xStorable.is() ) 613 throw uno::RuntimeException(); // TODO: 614 615 ::rtl::OUString aFilterName = GetFilterName( nStorageFormat ); 616 617 OSL_ENSURE( aFilterName.getLength(), "Wrong document service name!" ); 618 if ( !aFilterName.getLength() ) 619 throw io::IOException(); // TODO: 620 621 uno::Sequence< beans::PropertyValue > aArgs( 4 ); 622 aArgs[0].Name = ::rtl::OUString::createFromAscii( "FilterName" ); 623 aArgs[0].Value <<= aFilterName; 624 aArgs[1].Name = ::rtl::OUString::createFromAscii( "OutputStream" ); 625 aArgs[1].Value <<= xTempOut; 626 aArgs[2].Name = ::rtl::OUString::createFromAscii( "DocumentBaseURL" ); 627 aArgs[2].Value <<= aBaseURL; 628 aArgs[3].Name = ::rtl::OUString::createFromAscii( "HierarchicalDocumentName" ); 629 aArgs[3].Value <<= aHierarchName; 630 631 xStorable->storeToURL( ::rtl::OUString::createFromAscii( "private:stream" ), aArgs ); 632 try 633 { 634 xTempOut->closeOutput(); 635 } 636 catch( uno::Exception& ) 637 { 638 OSL_ENSURE( sal_False, "Looks like stream was closed already" ); 639 } 640 641 return aResult; 642 } 643 644 //------------------------------------------------------ 645 void OCommonEmbeddedObject::SaveObject_Impl() 646 { 647 if ( m_xClientSite.is() ) 648 { 649 try 650 { 651 // check whether the component is modified, 652 // if not there is no need for storing 653 uno::Reference< util::XModifiable > xModifiable( m_pDocHolder->GetComponent(), uno::UNO_QUERY ); 654 if ( xModifiable.is() && !xModifiable->isModified() ) 655 return; 656 } 657 catch( uno::Exception& ) 658 {} 659 660 try { 661 m_xClientSite->saveObject(); 662 } 663 catch( uno::Exception& ) 664 { 665 OSL_ENSURE( sal_False, "The object was not stored!\n" ); 666 } 667 } 668 } 669 670 //------------------------------------------------------ 671 ::rtl::OUString OCommonEmbeddedObject::GetBaseURL_Impl() const 672 { 673 ::rtl::OUString aBaseURL; 674 sal_Int32 nInd = 0; 675 676 if ( m_xClientSite.is() ) 677 { 678 try 679 { 680 uno::Reference< frame::XModel > xParentModel( m_xClientSite->getComponent(), uno::UNO_QUERY_THROW ); 681 uno::Sequence< beans::PropertyValue > aModelProps = xParentModel->getArgs(); 682 for ( nInd = 0; nInd < aModelProps.getLength(); nInd++ ) 683 if ( aModelProps[nInd].Name.equals( 684 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentBaseURL" ) ) ) ) 685 { 686 aModelProps[nInd].Value >>= aBaseURL; 687 break; 688 } 689 690 691 } 692 catch( uno::Exception& ) 693 {} 694 } 695 696 if ( !aBaseURL.getLength() ) 697 { 698 for ( nInd = 0; nInd < m_aDocMediaDescriptor.getLength(); nInd++ ) 699 if ( m_aDocMediaDescriptor[nInd].Name.equals( 700 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentBaseURL" ) ) ) ) 701 { 702 m_aDocMediaDescriptor[nInd].Value >>= aBaseURL; 703 break; 704 } 705 } 706 707 if ( !aBaseURL.getLength() ) 708 aBaseURL = m_aDefaultParentBaseURL; 709 710 return aBaseURL; 711 } 712 713 //------------------------------------------------------ 714 ::rtl::OUString OCommonEmbeddedObject::GetBaseURLFrom_Impl( 715 const uno::Sequence< beans::PropertyValue >& lArguments, 716 const uno::Sequence< beans::PropertyValue >& lObjArgs ) 717 { 718 ::rtl::OUString aBaseURL; 719 sal_Int32 nInd = 0; 720 721 for ( nInd = 0; nInd < lArguments.getLength(); nInd++ ) 722 if ( lArguments[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentBaseURL" ) ) ) ) 723 { 724 lArguments[nInd].Value >>= aBaseURL; 725 break; 726 } 727 728 if ( !aBaseURL.getLength() ) 729 { 730 for ( nInd = 0; nInd < lObjArgs.getLength(); nInd++ ) 731 if ( lObjArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultParentBaseURL" ) ) ) ) 732 { 733 lObjArgs[nInd].Value >>= aBaseURL; 734 break; 735 } 736 } 737 738 return aBaseURL; 739 } 740 741 742 //------------------------------------------------------ 743 void OCommonEmbeddedObject::SwitchDocToStorage_Impl( const uno::Reference< document::XStorageBasedDocument >& xDoc, const uno::Reference< embed::XStorage >& xStorage ) 744 { 745 xDoc->switchToStorage( xStorage ); 746 747 uno::Reference< util::XModifiable > xModif( xDoc, uno::UNO_QUERY ); 748 if ( xModif.is() ) 749 xModif->setModified( sal_False ); 750 751 if ( m_xRecoveryStorage.is() ) 752 m_xRecoveryStorage.clear(); 753 } 754 755 //------------------------------------------------------ 756 void OCommonEmbeddedObject::StoreDocToStorage_Impl( const uno::Reference< embed::XStorage >& xStorage, 757 sal_Int32 nStorageFormat, 758 const ::rtl::OUString& aBaseURL, 759 const ::rtl::OUString& aHierarchName, 760 sal_Bool bAttachToTheStorage ) 761 { 762 OSL_ENSURE( xStorage.is(), "No storage is provided for storing!" ); 763 764 if ( !xStorage.is() ) 765 throw uno::RuntimeException(); // TODO: 766 767 #ifdef USE_STORAGEBASED_DOCUMENT 768 uno::Reference< document::XStorageBasedDocument > xDoc; 769 { 770 osl::MutexGuard aGuard( m_aMutex ); 771 if ( m_pDocHolder ) 772 xDoc = uno::Reference< document::XStorageBasedDocument >( m_pDocHolder->GetComponent(), uno::UNO_QUERY ); 773 } 774 775 if ( xDoc.is() ) 776 { 777 ::rtl::OUString aFilterName = GetFilterName( nStorageFormat ); 778 779 OSL_ENSURE( aFilterName.getLength(), "Wrong document service name!" ); 780 if ( !aFilterName.getLength() ) 781 throw io::IOException(); // TODO: 782 783 uno::Sequence< beans::PropertyValue > aArgs( 3 ); 784 aArgs[0].Name = ::rtl::OUString::createFromAscii( "FilterName" ); 785 aArgs[0].Value <<= aFilterName; 786 aArgs[2].Name = ::rtl::OUString::createFromAscii( "DocumentBaseURL" ); 787 aArgs[2].Value <<= aBaseURL; 788 aArgs[1].Name = ::rtl::OUString::createFromAscii( "HierarchicalDocumentName" ); 789 aArgs[1].Value <<= aHierarchName; 790 791 xDoc->storeToStorage( xStorage, aArgs ); 792 if ( bAttachToTheStorage ) 793 SwitchDocToStorage_Impl( xDoc, xStorage ); 794 } 795 else 796 #endif 797 { 798 // store document to temporary stream based on temporary file 799 uno::Reference < io::XInputStream > xTempIn = StoreDocumentToTempStream_Impl( nStorageFormat, aBaseURL, aHierarchName ); 800 801 OSL_ENSURE( xTempIn.is(), "The stream reference can not be empty!\n" ); 802 803 // open storage based on document temporary file for reading 804 uno::Reference < lang::XSingleServiceFactory > xStorageFactory( 805 m_xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ), 806 uno::UNO_QUERY ); 807 808 uno::Sequence< uno::Any > aArgs(1); 809 aArgs[0] <<= xTempIn; 810 uno::Reference< embed::XStorage > xTempStorage( xStorageFactory->createInstanceWithArguments( aArgs ), 811 uno::UNO_QUERY ); 812 if ( !xTempStorage.is() ) 813 throw uno::RuntimeException(); // TODO: 814 815 // object storage must be commited automatically 816 xTempStorage->copyToStorage( xStorage ); 817 } 818 } 819 820 //------------------------------------------------------ 821 uno::Reference< util::XCloseable > OCommonEmbeddedObject::CreateDocFromMediaDescr_Impl( 822 const uno::Sequence< beans::PropertyValue >& aMedDescr ) 823 { 824 uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xFactory, GetDocumentServiceName(), 825 m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) ); 826 827 uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY ); 828 if ( !xLoadable.is() ) 829 throw uno::RuntimeException(); 830 831 try 832 { 833 // set the document mode to embedded as the first action on the document!!! 834 EmbedAndReparentDoc_Impl( xDocument ); 835 836 xLoadable->load( addAsTemplate( aMedDescr ) ); 837 } 838 catch( uno::Exception& ) 839 { 840 uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY ); 841 if ( xCloseable.is() ) 842 { 843 try 844 { 845 xCloseable->close( sal_True ); 846 } 847 catch( uno::Exception& ) 848 { 849 } 850 } 851 852 throw; // TODO 853 } 854 855 return xDocument; 856 } 857 858 //------------------------------------------------------ 859 uno::Reference< util::XCloseable > OCommonEmbeddedObject::CreateTempDocFromLink_Impl() 860 { 861 uno::Reference< util::XCloseable > xResult; 862 863 OSL_ENSURE( m_bIsLink, "The object is not a linked one!\n" ); 864 865 uno::Sequence< beans::PropertyValue > aTempMediaDescr; 866 867 sal_Int32 nStorageFormat = SOFFICE_FILEFORMAT_CURRENT; 868 try { 869 nStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage ); 870 } 871 catch ( beans::IllegalTypeException& ) 872 { 873 // the container just has an unknown type, use current file format 874 } 875 catch ( uno::Exception& ) 876 { 877 OSL_ENSURE( sal_False, "Can not retrieve storage media type!\n" ); 878 } 879 880 if ( m_pDocHolder->GetComponent().is() ) 881 { 882 aTempMediaDescr.realloc( 4 ); 883 884 // TODO/LATER: may be private:stream should be used as target URL 885 ::rtl::OUString aTempFileURL; 886 uno::Reference< io::XInputStream > xTempStream = StoreDocumentToTempStream_Impl( SOFFICE_FILEFORMAT_CURRENT, 887 ::rtl::OUString(), 888 ::rtl::OUString() ); 889 try 890 { 891 // no need to let the file stay after the stream is removed since the embedded document 892 // can not be stored directly 893 uno::Reference< beans::XPropertySet > xTempStreamProps( xTempStream, uno::UNO_QUERY_THROW ); 894 xTempStreamProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) ) >>= aTempFileURL; 895 } 896 catch( uno::Exception& ) 897 { 898 } 899 900 OSL_ENSURE( aTempFileURL.getLength(), "Coudn't retrieve temporary file URL!\n" ); 901 902 aTempMediaDescr[0].Name = ::rtl::OUString::createFromAscii( "URL" ); 903 aTempMediaDescr[0].Value <<= aTempFileURL; 904 aTempMediaDescr[1].Name = ::rtl::OUString::createFromAscii( "InputStream" ); 905 aTempMediaDescr[1].Value <<= xTempStream; 906 aTempMediaDescr[2].Name = ::rtl::OUString::createFromAscii( "FilterName" ); 907 aTempMediaDescr[2].Value <<= GetFilterName( nStorageFormat ); 908 aTempMediaDescr[3].Name = ::rtl::OUString::createFromAscii( "AsTemplate" ); 909 aTempMediaDescr[3].Value <<= sal_True; 910 } 911 else 912 { 913 aTempMediaDescr.realloc( 2 ); 914 aTempMediaDescr[0].Name = ::rtl::OUString::createFromAscii( "URL" ); 915 aTempMediaDescr[0].Value <<= m_aLinkURL; 916 aTempMediaDescr[1].Name = ::rtl::OUString::createFromAscii( "FilterName" ); 917 aTempMediaDescr[1].Value <<= m_aLinkFilterName; 918 // aTempMediaDescr[2].Name = ::rtl::OUString::createFromAscii( "AsTemplate" ); 919 // aTempMediaDescr[2].Value <<= sal_True; 920 } 921 922 xResult = CreateDocFromMediaDescr_Impl( aTempMediaDescr ); 923 924 return xResult; 925 } 926 927 //------------------------------------------------------ 928 void SAL_CALL OCommonEmbeddedObject::setPersistentEntry( 929 const uno::Reference< embed::XStorage >& xStorage, 930 const ::rtl::OUString& sEntName, 931 sal_Int32 nEntryConnectionMode, 932 const uno::Sequence< beans::PropertyValue >& lArguments, 933 const uno::Sequence< beans::PropertyValue >& lObjArgs ) 934 throw ( lang::IllegalArgumentException, 935 embed::WrongStateException, 936 io::IOException, 937 uno::Exception, 938 uno::RuntimeException ) 939 { 940 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::setPersistentEntry" ); 941 942 // the type of the object must be already set 943 // a kind of typedetection should be done in the factory 944 945 ::osl::MutexGuard aGuard( m_aMutex ); 946 if ( m_bDisposed ) 947 throw lang::DisposedException(); // TODO 948 949 if ( !xStorage.is() ) 950 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ), 951 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), 952 1 ); 953 954 if ( !sEntName.getLength() ) 955 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ), 956 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), 957 2 ); 958 959 // May be LOADED should be forbidden here ??? 960 if ( ( m_nObjectState != -1 || nEntryConnectionMode == embed::EntryInitModes::NO_INIT ) 961 && ( m_nObjectState == -1 || nEntryConnectionMode != embed::EntryInitModes::NO_INIT ) ) 962 { 963 // if the object is not loaded 964 // it can not get persistant representation without initialization 965 966 // if the object is loaded 967 // it can switch persistant representation only without initialization 968 969 throw embed::WrongStateException( 970 ::rtl::OUString::createFromAscii( "Can't change persistant representation of activated object!\n" ), 971 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 972 } 973 974 if ( m_bWaitSaveCompleted ) 975 { 976 if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT ) 977 { 978 // saveCompleted is expected, handle it accordingly 979 if ( m_xNewParentStorage == xStorage && m_aNewEntryName.equals( sEntName ) ) 980 { 981 saveCompleted( sal_True ); 982 return; 983 } 984 985 // if a completely different entry is provided, switch first back to the old persistence in saveCompleted 986 // and then switch to the target persistence 987 sal_Bool bSwitchFurther = ( m_xParentStorage != xStorage || !m_aEntryName.equals( sEntName ) ); 988 saveCompleted( sal_False ); 989 if ( !bSwitchFurther ) 990 return; 991 } 992 else 993 throw embed::WrongStateException( 994 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ), 995 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 996 } 997 998 // for now support of this interface is required to allow breaking of links and converting them to normal embedded 999 // objects, so the persist name must be handled correctly ( althowgh no real persist entry is used ) 1000 // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" ); 1001 if ( m_bIsLink ) 1002 { 1003 m_aEntryName = sEntName; 1004 return; 1005 } 1006 1007 uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY ); 1008 if ( !xNameAccess.is() ) 1009 throw uno::RuntimeException(); //TODO 1010 1011 // detect entry existence 1012 sal_Bool bElExists = xNameAccess->hasByName( sEntName ); 1013 1014 m_aDocMediaDescriptor = GetValuableArgs_Impl( lArguments, 1015 nEntryConnectionMode != embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT ); 1016 1017 m_bReadOnly = sal_False; 1018 for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ ) 1019 if ( lArguments[nInd].Name.equalsAscii( "ReadOnly" ) ) 1020 lArguments[nInd].Value >>= m_bReadOnly; 1021 1022 // TODO: use lObjArgs for StoreVisualReplacement 1023 for ( sal_Int32 nObjInd = 0; nObjInd < lObjArgs.getLength(); nObjInd++ ) 1024 if ( lObjArgs[nObjInd].Name.equalsAscii( "OutplaceDispatchInterceptor" ) ) 1025 { 1026 uno::Reference< frame::XDispatchProviderInterceptor > xDispatchInterceptor; 1027 if ( lObjArgs[nObjInd].Value >>= xDispatchInterceptor ) 1028 m_pDocHolder->SetOutplaceDispatchInterceptor( xDispatchInterceptor ); 1029 } 1030 else if ( lObjArgs[nObjInd].Name.equalsAscii( "DefaultParentBaseURL" ) ) 1031 { 1032 lObjArgs[nObjInd].Value >>= m_aDefaultParentBaseURL; 1033 } 1034 else if ( lObjArgs[nObjInd].Name.equalsAscii( "Parent" ) ) 1035 { 1036 lObjArgs[nObjInd].Value >>= m_xParent; 1037 } 1038 else if ( lObjArgs[nObjInd].Name.equalsAscii( "IndividualMiscStatus" ) ) 1039 { 1040 sal_Int64 nMiscStatus=0; 1041 lObjArgs[nObjInd].Value >>= nMiscStatus; 1042 m_nMiscStatus |= nMiscStatus; 1043 } 1044 else if ( lObjArgs[nObjInd].Name.equalsAscii( "CloneFrom" ) ) 1045 { 1046 uno::Reference < embed::XEmbeddedObject > xObj; 1047 lObjArgs[nObjInd].Value >>= xObj; 1048 if ( xObj.is() ) 1049 { 1050 m_bHasClonedSize = sal_True; 1051 m_aClonedSize = xObj->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT ); 1052 m_nClonedMapUnit = xObj->getMapUnit( embed::Aspects::MSOLE_CONTENT ); 1053 } 1054 } 1055 else if ( lObjArgs[nObjInd].Name.equalsAscii( "OutplaceFrameProperties" ) ) 1056 { 1057 uno::Sequence< uno::Any > aOutFrameProps; 1058 uno::Sequence< beans::NamedValue > aOutFramePropsTyped; 1059 if ( lObjArgs[nObjInd].Value >>= aOutFrameProps ) 1060 { 1061 m_pDocHolder->SetOutplaceFrameProperties( aOutFrameProps ); 1062 } 1063 else if ( lObjArgs[nObjInd].Value >>= aOutFramePropsTyped ) 1064 { 1065 aOutFrameProps.realloc( aOutFramePropsTyped.getLength() ); 1066 uno::Any* pProp = aOutFrameProps.getArray(); 1067 for ( const beans::NamedValue* pTypedProp = aOutFramePropsTyped.getConstArray(); 1068 pTypedProp != aOutFramePropsTyped.getConstArray() + aOutFramePropsTyped.getLength(); 1069 ++pTypedProp, ++pProp 1070 ) 1071 { 1072 *pProp <<= *pTypedProp; 1073 } 1074 m_pDocHolder->SetOutplaceFrameProperties( aOutFrameProps ); 1075 } 1076 else 1077 OSL_ENSURE( false, "OCommonEmbeddedObject::setPersistentEntry: illegal type for argument 'OutplaceFrameProperties'!" ); 1078 } 1079 else if ( lObjArgs[nObjInd].Name.equalsAscii( "ModuleName" ) ) 1080 { 1081 lObjArgs[nObjInd].Value >>= m_aModuleName; 1082 } 1083 else if ( lObjArgs[nObjInd].Name.equalsAscii( "EmbeddedScriptSupport" ) ) 1084 { 1085 OSL_VERIFY( lObjArgs[nObjInd].Value >>= m_bEmbeddedScriptSupport ); 1086 } 1087 else if ( lObjArgs[nObjInd].Name.equalsAscii( "DocumentRecoverySupport" ) ) 1088 { 1089 OSL_VERIFY( lObjArgs[nObjInd].Value >>= m_bDocumentRecoverySupport ); 1090 } 1091 else if ( lObjArgs[nObjInd].Name.equalsAscii( "RecoveryStorage" ) ) 1092 { 1093 OSL_VERIFY( lObjArgs[nObjInd].Value >>= m_xRecoveryStorage ); 1094 } 1095 1096 1097 sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE; 1098 1099 SwitchOwnPersistence( xStorage, sEntName ); 1100 1101 if ( nEntryConnectionMode == embed::EntryInitModes::DEFAULT_INIT ) 1102 { 1103 if ( bElExists ) 1104 { 1105 // the initialization from existing storage allows to leave object in loaded state 1106 m_nObjectState = embed::EmbedStates::LOADED; 1107 } 1108 else 1109 { 1110 m_pDocHolder->SetComponent( InitNewDocument_Impl(), m_bReadOnly ); 1111 if ( !m_pDocHolder->GetComponent().is() ) 1112 throw io::IOException(); // TODO: can not create document 1113 1114 m_nObjectState = embed::EmbedStates::RUNNING; 1115 } 1116 } 1117 else 1118 { 1119 if ( ( nStorageMode & embed::ElementModes::READWRITE ) != embed::ElementModes::READWRITE ) 1120 throw io::IOException(); 1121 1122 if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT ) 1123 { 1124 // the document just already changed its storage to store to 1125 // the links to OOo documents for now ignore this call 1126 // TODO: OOo links will have persistence so it will be switched here 1127 } 1128 else if ( nEntryConnectionMode == embed::EntryInitModes::TRUNCATE_INIT ) 1129 { 1130 if ( m_xRecoveryStorage.is() ) 1131 TransferMediaType( m_xRecoveryStorage, m_xObjectStorage ); 1132 1133 // TODO: 1134 m_pDocHolder->SetComponent( InitNewDocument_Impl(), m_bReadOnly ); 1135 1136 if ( !m_pDocHolder->GetComponent().is() ) 1137 throw io::IOException(); // TODO: can not create document 1138 1139 m_nObjectState = embed::EmbedStates::RUNNING; 1140 } 1141 else if ( nEntryConnectionMode == embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT ) 1142 { 1143 m_pDocHolder->SetComponent( CreateDocFromMediaDescr_Impl( lArguments ), m_bReadOnly ); 1144 m_nObjectState = embed::EmbedStates::RUNNING; 1145 } 1146 //else if ( nEntryConnectionMode == embed::EntryInitModes::TRANSFERABLE_INIT ) 1147 //{ 1148 //TODO: 1149 //} 1150 else 1151 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Wrong connection mode is provided!\n" ), 1152 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), 1153 3 ); 1154 } 1155 } 1156 1157 //------------------------------------------------------ 1158 void SAL_CALL OCommonEmbeddedObject::storeToEntry( const uno::Reference< embed::XStorage >& xStorage, 1159 const ::rtl::OUString& sEntName, 1160 const uno::Sequence< beans::PropertyValue >& lArguments, 1161 const uno::Sequence< beans::PropertyValue >& lObjArgs ) 1162 throw ( lang::IllegalArgumentException, 1163 embed::WrongStateException, 1164 io::IOException, 1165 uno::Exception, 1166 uno::RuntimeException ) 1167 { 1168 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::storeToEntry" ); 1169 1170 ::osl::ResettableMutexGuard aGuard( m_aMutex ); 1171 if ( m_bDisposed ) 1172 throw lang::DisposedException(); // TODO 1173 1174 if ( m_nObjectState == -1 ) 1175 { 1176 // the object is still not loaded 1177 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ), 1178 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1179 } 1180 1181 if ( m_bWaitSaveCompleted ) 1182 throw embed::WrongStateException( 1183 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ), 1184 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1185 1186 // for now support of this interface is required to allow breaking of links and converting them to normal embedded 1187 // objects, so the persist name must be handled correctly ( althowgh no real persist entry is used ) 1188 // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" ); 1189 if ( m_bIsLink ) 1190 return; 1191 1192 OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!\n" ); 1193 1194 sal_Int32 nTargetStorageFormat = SOFFICE_FILEFORMAT_CURRENT; 1195 sal_Int32 nOriginalStorageFormat = SOFFICE_FILEFORMAT_CURRENT; 1196 try { 1197 nTargetStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( xStorage ); 1198 } 1199 catch ( beans::IllegalTypeException& ) 1200 { 1201 // the container just has an unknown type, use current file format 1202 } 1203 catch ( uno::Exception& ) 1204 { 1205 OSL_ENSURE( sal_False, "Can not retrieve target storage media type!\n" ); 1206 } 1207 1208 try 1209 { 1210 nOriginalStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage ); 1211 } 1212 catch ( beans::IllegalTypeException& ) 1213 { 1214 // the container just has an unknown type, use current file format 1215 } 1216 catch ( uno::Exception& ) 1217 { 1218 OSL_ENSURE( sal_False, "Can not retrieve own storage media type!\n" ); 1219 } 1220 1221 sal_Bool bTryOptimization = sal_False; 1222 for ( sal_Int32 nInd = 0; nInd < lObjArgs.getLength(); nInd++ ) 1223 { 1224 // StoreVisualReplacement and VisualReplacement args have no sence here 1225 if ( lObjArgs[nInd].Name.equalsAscii( "CanTryOptimization" ) ) 1226 lObjArgs[nInd].Value >>= bTryOptimization; 1227 } 1228 1229 sal_Bool bSwitchBackToLoaded = sal_False; 1230 1231 // Storing to different format can be done only in running state. 1232 if ( m_nObjectState == embed::EmbedStates::LOADED ) 1233 { 1234 // TODO/LATER: copying is not legal for documents with relative links. 1235 if ( nTargetStorageFormat == nOriginalStorageFormat ) 1236 { 1237 sal_Bool bOptimizationWorks = sal_False; 1238 if ( bTryOptimization ) 1239 { 1240 try 1241 { 1242 // try to use optimized copying 1243 uno::Reference< embed::XOptimizedStorage > xSource( m_xParentStorage, uno::UNO_QUERY_THROW ); 1244 uno::Reference< embed::XOptimizedStorage > xTarget( xStorage, uno::UNO_QUERY_THROW ); 1245 xSource->copyElementDirectlyTo( m_aEntryName, xTarget, sEntName ); 1246 bOptimizationWorks = sal_True; 1247 } 1248 catch( uno::Exception& ) 1249 { 1250 } 1251 } 1252 1253 if ( !bOptimizationWorks ) 1254 m_xParentStorage->copyElementTo( m_aEntryName, xStorage, sEntName ); 1255 } 1256 else 1257 { 1258 changeState( embed::EmbedStates::RUNNING ); 1259 bSwitchBackToLoaded = sal_True; 1260 } 1261 } 1262 1263 if ( m_nObjectState != embed::EmbedStates::LOADED ) 1264 { 1265 uno::Reference< embed::XStorage > xSubStorage = 1266 xStorage->openStorageElement( sEntName, embed::ElementModes::READWRITE ); 1267 1268 if ( !xSubStorage.is() ) 1269 throw uno::RuntimeException(); //TODO 1270 1271 aGuard.clear(); 1272 // TODO/LATER: support hierarchical name for embedded objects in embedded objects 1273 StoreDocToStorage_Impl( xSubStorage, nTargetStorageFormat, GetBaseURLFrom_Impl( lArguments, lObjArgs ), sEntName, sal_False ); 1274 aGuard.reset(); 1275 1276 if ( bSwitchBackToLoaded ) 1277 changeState( embed::EmbedStates::LOADED ); 1278 } 1279 1280 // TODO: should the listener notification be done? 1281 } 1282 1283 //------------------------------------------------------ 1284 void SAL_CALL OCommonEmbeddedObject::storeAsEntry( const uno::Reference< embed::XStorage >& xStorage, 1285 const ::rtl::OUString& sEntName, 1286 const uno::Sequence< beans::PropertyValue >& lArguments, 1287 const uno::Sequence< beans::PropertyValue >& lObjArgs ) 1288 throw ( lang::IllegalArgumentException, 1289 embed::WrongStateException, 1290 io::IOException, 1291 uno::Exception, 1292 uno::RuntimeException ) 1293 { 1294 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::storeAsEntry" ); 1295 1296 // TODO: use lObjArgs 1297 1298 ::osl::ResettableMutexGuard aGuard( m_aMutex ); 1299 if ( m_bDisposed ) 1300 throw lang::DisposedException(); // TODO 1301 1302 if ( m_nObjectState == -1 ) 1303 { 1304 // the object is still not loaded 1305 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ), 1306 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1307 } 1308 1309 if ( m_bWaitSaveCompleted ) 1310 throw embed::WrongStateException( 1311 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ), 1312 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1313 1314 // for now support of this interface is required to allow breaking of links and converting them to normal embedded 1315 // objects, so the persist name must be handled correctly ( althowgh no real persist entry is used ) 1316 // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" ); 1317 if ( m_bIsLink ) 1318 { 1319 m_aNewEntryName = sEntName; 1320 return; 1321 } 1322 1323 OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!\n" ); 1324 1325 sal_Int32 nTargetStorageFormat = SOFFICE_FILEFORMAT_CURRENT; 1326 sal_Int32 nOriginalStorageFormat = SOFFICE_FILEFORMAT_CURRENT; 1327 try { 1328 nTargetStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( xStorage ); 1329 } 1330 catch ( beans::IllegalTypeException& ) 1331 { 1332 // the container just has an unknown type, use current file format 1333 } 1334 catch ( uno::Exception& ) 1335 { 1336 OSL_ENSURE( sal_False, "Can not retrieve target storage media type!\n" ); 1337 } 1338 1339 try 1340 { 1341 nOriginalStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage ); 1342 } 1343 catch ( beans::IllegalTypeException& ) 1344 { 1345 // the container just has an unknown type, use current file format 1346 } 1347 catch ( uno::Exception& ) 1348 { 1349 OSL_ENSURE( sal_False, "Can not retrieve own storage media type!\n" ); 1350 } 1351 1352 PostEvent_Impl( ::rtl::OUString::createFromAscii( "OnSaveAs" ) ); 1353 1354 sal_Bool bTryOptimization = sal_False; 1355 for ( sal_Int32 nInd = 0; nInd < lObjArgs.getLength(); nInd++ ) 1356 { 1357 // StoreVisualReplacement and VisualReplacement args have no sence here 1358 if ( lObjArgs[nInd].Name.equalsAscii( "CanTryOptimization" ) ) 1359 lObjArgs[nInd].Value >>= bTryOptimization; 1360 } 1361 1362 sal_Bool bSwitchBackToLoaded = sal_False; 1363 1364 // Storing to different format can be done only in running state. 1365 if ( m_nObjectState == embed::EmbedStates::LOADED ) 1366 { 1367 // TODO/LATER: copying is not legal for documents with relative links. 1368 if ( nTargetStorageFormat == nOriginalStorageFormat ) 1369 { 1370 sal_Bool bOptimizationWorks = sal_False; 1371 if ( bTryOptimization ) 1372 { 1373 try 1374 { 1375 // try to use optimized copying 1376 uno::Reference< embed::XOptimizedStorage > xSource( m_xParentStorage, uno::UNO_QUERY_THROW ); 1377 uno::Reference< embed::XOptimizedStorage > xTarget( xStorage, uno::UNO_QUERY_THROW ); 1378 xSource->copyElementDirectlyTo( m_aEntryName, xTarget, sEntName ); 1379 bOptimizationWorks = sal_True; 1380 } 1381 catch( uno::Exception& ) 1382 { 1383 } 1384 } 1385 1386 if ( !bOptimizationWorks ) 1387 m_xParentStorage->copyElementTo( m_aEntryName, xStorage, sEntName ); 1388 } 1389 else 1390 { 1391 changeState( embed::EmbedStates::RUNNING ); 1392 bSwitchBackToLoaded = sal_True; 1393 } 1394 } 1395 1396 uno::Reference< embed::XStorage > xSubStorage = 1397 xStorage->openStorageElement( sEntName, embed::ElementModes::READWRITE ); 1398 1399 if ( !xSubStorage.is() ) 1400 throw uno::RuntimeException(); //TODO 1401 1402 if ( m_nObjectState != embed::EmbedStates::LOADED ) 1403 { 1404 aGuard.clear(); 1405 // TODO/LATER: support hierarchical name for embedded objects in embedded objects 1406 StoreDocToStorage_Impl( xSubStorage, nTargetStorageFormat, GetBaseURLFrom_Impl( lArguments, lObjArgs ), sEntName, sal_False ); 1407 aGuard.reset(); 1408 1409 if ( bSwitchBackToLoaded ) 1410 changeState( embed::EmbedStates::LOADED ); 1411 } 1412 1413 m_bWaitSaveCompleted = sal_True; 1414 m_xNewObjectStorage = xSubStorage; 1415 m_xNewParentStorage = xStorage; 1416 m_aNewEntryName = sEntName; 1417 m_aNewDocMediaDescriptor = GetValuableArgs_Impl( lArguments, sal_True ); 1418 1419 // TODO: register listeners for storages above, in case thay are disposed 1420 // an exception will be thrown on saveCompleted( true ) 1421 1422 // TODO: should the listener notification be done here or in saveCompleted? 1423 } 1424 1425 //------------------------------------------------------ 1426 void SAL_CALL OCommonEmbeddedObject::saveCompleted( sal_Bool bUseNew ) 1427 throw ( embed::WrongStateException, 1428 uno::Exception, 1429 uno::RuntimeException ) 1430 { 1431 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::saveCompleted" ); 1432 1433 ::osl::MutexGuard aGuard( m_aMutex ); 1434 if ( m_bDisposed ) 1435 throw lang::DisposedException(); // TODO 1436 1437 if ( m_nObjectState == -1 ) 1438 { 1439 // the object is still not loaded 1440 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ), 1441 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1442 } 1443 1444 // for now support of this interface is required to allow breaking of links and converting them to normal embedded 1445 // objects, so the persist name must be handled correctly ( althowgh no real persist entry is used ) 1446 // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" ); 1447 if ( m_bIsLink ) 1448 { 1449 if ( bUseNew ) 1450 m_aEntryName = m_aNewEntryName; 1451 m_aNewEntryName = ::rtl::OUString(); 1452 return; 1453 } 1454 1455 // it is allowed to call saveCompleted( false ) for nonstored objects 1456 if ( !m_bWaitSaveCompleted && !bUseNew ) 1457 return; 1458 1459 OSL_ENSURE( m_bWaitSaveCompleted, "Unexpected saveCompleted() call!\n" ); 1460 if ( !m_bWaitSaveCompleted ) 1461 throw io::IOException(); // TODO: illegal call 1462 1463 OSL_ENSURE( m_xNewObjectStorage.is() && m_xNewParentStorage.is() , "Internal object information is broken!\n" ); 1464 if ( !m_xNewObjectStorage.is() || !m_xNewParentStorage.is() ) 1465 throw uno::RuntimeException(); // TODO: broken internal information 1466 1467 if ( bUseNew ) 1468 { 1469 SwitchOwnPersistence( m_xNewParentStorage, m_xNewObjectStorage, m_aNewEntryName ); 1470 m_aDocMediaDescriptor = m_aNewDocMediaDescriptor; 1471 1472 uno::Reference< util::XModifiable > xModif( m_pDocHolder->GetComponent(), uno::UNO_QUERY ); 1473 if ( xModif.is() ) 1474 xModif->setModified( sal_False ); 1475 1476 PostEvent_Impl( ::rtl::OUString::createFromAscii( "OnSaveAsDone" ) ); 1477 } 1478 else 1479 { 1480 try { 1481 uno::Reference< lang::XComponent > xComponent( m_xNewObjectStorage, uno::UNO_QUERY ); 1482 OSL_ENSURE( xComponent.is(), "Wrong storage implementation!" ); 1483 if ( xComponent.is() ) 1484 xComponent->dispose(); 1485 } 1486 catch ( uno::Exception& ) 1487 { 1488 } 1489 } 1490 1491 m_xNewObjectStorage = uno::Reference< embed::XStorage >(); 1492 m_xNewParentStorage = uno::Reference< embed::XStorage >(); 1493 m_aNewEntryName = ::rtl::OUString(); 1494 m_aNewDocMediaDescriptor.realloc( 0 ); 1495 m_bWaitSaveCompleted = sal_False; 1496 1497 if ( bUseNew ) 1498 { 1499 // TODO: notify listeners 1500 1501 if ( m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE ) 1502 { 1503 // TODO: update visual representation 1504 } 1505 } 1506 } 1507 1508 //------------------------------------------------------ 1509 sal_Bool SAL_CALL OCommonEmbeddedObject::hasEntry() 1510 throw ( embed::WrongStateException, 1511 uno::RuntimeException ) 1512 { 1513 ::osl::MutexGuard aGuard( m_aMutex ); 1514 if ( m_bDisposed ) 1515 throw lang::DisposedException(); // TODO 1516 1517 if ( m_bWaitSaveCompleted ) 1518 throw embed::WrongStateException( 1519 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ), 1520 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1521 1522 if ( m_xObjectStorage.is() ) 1523 return sal_True; 1524 1525 return sal_False; 1526 } 1527 1528 //------------------------------------------------------ 1529 ::rtl::OUString SAL_CALL OCommonEmbeddedObject::getEntryName() 1530 throw ( embed::WrongStateException, 1531 uno::RuntimeException ) 1532 { 1533 ::osl::MutexGuard aGuard( m_aMutex ); 1534 if ( m_bDisposed ) 1535 throw lang::DisposedException(); // TODO 1536 1537 if ( m_nObjectState == -1 ) 1538 { 1539 // the object is still not loaded 1540 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object persistence is not initialized!\n" ), 1541 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1542 } 1543 1544 if ( m_bWaitSaveCompleted ) 1545 throw embed::WrongStateException( 1546 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ), 1547 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1548 1549 return m_aEntryName; 1550 } 1551 1552 //------------------------------------------------------ 1553 void SAL_CALL OCommonEmbeddedObject::storeOwn() 1554 throw ( embed::WrongStateException, 1555 io::IOException, 1556 uno::Exception, 1557 uno::RuntimeException ) 1558 { 1559 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::storeOwn" ); 1560 1561 // during switching from Activated to Running and from Running to Loaded states the object will 1562 // ask container to store the object, the container has to make decision 1563 // to do so or not 1564 1565 ::osl::ResettableMutexGuard aGuard( m_aMutex ); 1566 if ( m_bDisposed ) 1567 throw lang::DisposedException(); // TODO 1568 1569 if ( m_nObjectState == -1 ) 1570 { 1571 // the object is still not loaded 1572 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ), 1573 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1574 } 1575 1576 if ( m_bWaitSaveCompleted ) 1577 throw embed::WrongStateException( 1578 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ), 1579 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1580 1581 if ( m_bReadOnly ) 1582 throw io::IOException(); // TODO: access denied 1583 1584 // nothing to do, if the object is in loaded state 1585 if ( m_nObjectState == embed::EmbedStates::LOADED ) 1586 return; 1587 1588 PostEvent_Impl( ::rtl::OUString::createFromAscii( "OnSave" ) ); 1589 1590 OSL_ENSURE( m_pDocHolder->GetComponent().is(), "If an object is activated or in running state it must have a document!\n" ); 1591 if ( !m_pDocHolder->GetComponent().is() ) 1592 throw uno::RuntimeException(); 1593 1594 if ( m_bIsLink ) 1595 { 1596 // TODO: just store the document to it's location 1597 uno::Reference< frame::XStorable > xStorable( m_pDocHolder->GetComponent(), uno::UNO_QUERY ); 1598 if ( !xStorable.is() ) 1599 throw uno::RuntimeException(); // TODO 1600 1601 // free the main mutex for the storing time 1602 aGuard.clear(); 1603 1604 xStorable->store(); 1605 1606 aGuard.reset(); 1607 } 1608 else 1609 { 1610 OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!\n" ); 1611 1612 if ( !m_xObjectStorage.is() ) 1613 throw io::IOException(); //TODO: access denied 1614 1615 sal_Int32 nStorageFormat = SOFFICE_FILEFORMAT_CURRENT; 1616 try { 1617 nStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage ); 1618 } 1619 catch ( beans::IllegalTypeException& ) 1620 { 1621 // the container just has an unknown type, use current file format 1622 } 1623 catch ( uno::Exception& ) 1624 { 1625 OSL_ENSURE( sal_False, "Can not retrieve storage media type!\n" ); 1626 } 1627 1628 aGuard.clear(); 1629 StoreDocToStorage_Impl( m_xObjectStorage, nStorageFormat, GetBaseURL_Impl(), m_aEntryName, sal_True ); 1630 aGuard.reset(); 1631 } 1632 1633 uno::Reference< util::XModifiable > xModif( m_pDocHolder->GetComponent(), uno::UNO_QUERY ); 1634 if ( xModif.is() ) 1635 xModif->setModified( sal_False ); 1636 1637 PostEvent_Impl( ::rtl::OUString::createFromAscii( "OnSaveDone" ) ); 1638 } 1639 1640 //------------------------------------------------------ 1641 sal_Bool SAL_CALL OCommonEmbeddedObject::isReadonly() 1642 throw ( embed::WrongStateException, 1643 uno::RuntimeException ) 1644 { 1645 ::osl::MutexGuard aGuard( m_aMutex ); 1646 if ( m_bDisposed ) 1647 throw lang::DisposedException(); // TODO 1648 1649 if ( m_nObjectState == -1 ) 1650 { 1651 // the object is still not loaded 1652 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object persistence is not initialized!\n" ), 1653 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1654 } 1655 1656 if ( m_bWaitSaveCompleted ) 1657 throw embed::WrongStateException( 1658 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ), 1659 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1660 1661 return m_bReadOnly; 1662 } 1663 1664 //------------------------------------------------------ 1665 void SAL_CALL OCommonEmbeddedObject::reload( 1666 const uno::Sequence< beans::PropertyValue >& lArguments, 1667 const uno::Sequence< beans::PropertyValue >& lObjArgs ) 1668 throw ( lang::IllegalArgumentException, 1669 embed::WrongStateException, 1670 io::IOException, 1671 uno::Exception, 1672 uno::RuntimeException ) 1673 { 1674 // TODO: use lObjArgs 1675 // for now this method is used only to switch readonly state 1676 1677 ::osl::MutexGuard aGuard( m_aMutex ); 1678 if ( m_bDisposed ) 1679 throw lang::DisposedException(); // TODO 1680 1681 if ( m_nObjectState == -1 ) 1682 { 1683 // the object is still not loaded 1684 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object persistence is not initialized!\n" ), 1685 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1686 } 1687 1688 if ( m_nObjectState != embed::EmbedStates::LOADED ) 1689 { 1690 // the object is still not loaded 1691 throw embed::WrongStateException( 1692 ::rtl::OUString::createFromAscii( "The object must be in loaded state to be reloaded!\n" ), 1693 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1694 } 1695 1696 if ( m_bWaitSaveCompleted ) 1697 throw embed::WrongStateException( 1698 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ), 1699 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1700 1701 if ( m_bIsLink ) 1702 { 1703 // reload of the link 1704 ::rtl::OUString aOldLinkFilter = m_aLinkFilterName; 1705 1706 ::rtl::OUString aNewLinkFilter; 1707 for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ ) 1708 { 1709 if ( lArguments[nInd].Name.equalsAscii( "URL" ) ) 1710 { 1711 // the new URL 1712 lArguments[nInd].Value >>= m_aLinkURL; 1713 m_aLinkFilterName = ::rtl::OUString(); 1714 } 1715 else if ( lArguments[nInd].Name.equalsAscii( "FilterName" ) ) 1716 { 1717 lArguments[nInd].Value >>= aNewLinkFilter; 1718 m_aLinkFilterName = ::rtl::OUString(); 1719 } 1720 } 1721 1722 ::comphelper::MimeConfigurationHelper aHelper( m_xFactory ); 1723 if ( !m_aLinkFilterName.getLength() ) 1724 { 1725 if ( aNewLinkFilter.getLength() ) 1726 m_aLinkFilterName = aNewLinkFilter; 1727 else 1728 { 1729 uno::Sequence< beans::PropertyValue > aArgs( 1 ); 1730 aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); 1731 aArgs[0].Value <<= m_aLinkURL; 1732 m_aLinkFilterName = aHelper.UpdateMediaDescriptorWithFilterName( aArgs, sal_False ); 1733 } 1734 } 1735 1736 if ( !aOldLinkFilter.equals( m_aLinkFilterName ) ) 1737 { 1738 uno::Sequence< beans::NamedValue > aObject = aHelper.GetObjectPropsByFilter( m_aLinkFilterName ); 1739 1740 // TODO/LATER: probably the document holder could be cleaned explicitly as in the destructor 1741 m_pDocHolder->release(); 1742 m_pDocHolder = NULL; 1743 1744 LinkInit_Impl( aObject, lArguments, lObjArgs ); 1745 } 1746 } 1747 1748 m_aDocMediaDescriptor = GetValuableArgs_Impl( lArguments, sal_True ); 1749 1750 // TODO: use lObjArgs for StoreVisualReplacement 1751 for ( sal_Int32 nObjInd = 0; nObjInd < lObjArgs.getLength(); nObjInd++ ) 1752 if ( lObjArgs[nObjInd].Name.equalsAscii( "OutplaceDispatchInterceptor" ) ) 1753 { 1754 uno::Reference< frame::XDispatchProviderInterceptor > xDispatchInterceptor; 1755 if ( lObjArgs[nObjInd].Value >>= xDispatchInterceptor ) 1756 m_pDocHolder->SetOutplaceDispatchInterceptor( xDispatchInterceptor ); 1757 1758 break; 1759 } 1760 1761 // TODO: 1762 // when document allows reloading through API the object can be reloaded not only in loaded state 1763 1764 sal_Bool bOldReadOnlyValue = m_bReadOnly; 1765 1766 m_bReadOnly = sal_False; 1767 for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ ) 1768 if ( lArguments[nInd].Name.equalsAscii( "ReadOnly" ) ) 1769 lArguments[nInd].Value >>= m_bReadOnly; 1770 1771 if ( bOldReadOnlyValue != m_bReadOnly && !m_bIsLink ) 1772 { 1773 // close own storage 1774 try { 1775 uno::Reference< lang::XComponent > xComponent( m_xObjectStorage, uno::UNO_QUERY ); 1776 OSL_ENSURE( !m_xObjectStorage.is() || xComponent.is(), "Wrong storage implementation!" ); 1777 if ( xComponent.is() ) 1778 xComponent->dispose(); 1779 } 1780 catch ( uno::Exception& ) 1781 { 1782 } 1783 1784 sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE; 1785 m_xObjectStorage = m_xParentStorage->openStorageElement( m_aEntryName, nStorageMode ); 1786 } 1787 } 1788 1789 //------------------------------------------------------ 1790 void SAL_CALL OCommonEmbeddedObject::breakLink( const uno::Reference< embed::XStorage >& xStorage, 1791 const ::rtl::OUString& sEntName ) 1792 throw ( lang::IllegalArgumentException, 1793 embed::WrongStateException, 1794 io::IOException, 1795 uno::Exception, 1796 uno::RuntimeException ) 1797 { 1798 ::osl::ResettableMutexGuard aGuard( m_aMutex ); 1799 if ( m_bDisposed ) 1800 throw lang::DisposedException(); // TODO 1801 1802 if ( !m_bIsLink ) 1803 { 1804 // it must be a linked initialized object 1805 throw embed::WrongStateException( 1806 ::rtl::OUString::createFromAscii( "The object is not a valid linked object!\n" ), 1807 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1808 } 1809 #if 0 1810 else 1811 { 1812 // the current implementation of OOo links does not implement this method since it does not implement 1813 // all the set of interfaces required for OOo embedded object ( XEmbedPersist is not supported ). 1814 throw io::IOException(); // TODO: 1815 } 1816 #endif 1817 1818 if ( !xStorage.is() ) 1819 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ), 1820 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), 1821 1 ); 1822 1823 if ( !sEntName.getLength() ) 1824 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ), 1825 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ), 1826 2 ); 1827 1828 if ( !m_bIsLink || m_nObjectState == -1 ) 1829 { 1830 // it must be a linked initialized object 1831 throw embed::WrongStateException( 1832 ::rtl::OUString::createFromAscii( "The object is not a valid linked object!\n" ), 1833 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1834 } 1835 1836 if ( m_bWaitSaveCompleted ) 1837 throw embed::WrongStateException( 1838 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ), 1839 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1840 1841 uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY ); 1842 if ( !xNameAccess.is() ) 1843 throw uno::RuntimeException(); //TODO 1844 1845 // detect entry existence 1846 /*sal_Bool bElExists =*/ xNameAccess->hasByName( sEntName ); 1847 1848 m_bReadOnly = sal_False; 1849 // sal_Int32 nStorageMode = embed::ElementModes::READWRITE; 1850 1851 if ( m_xParentStorage != xStorage || !m_aEntryName.equals( sEntName ) ) 1852 SwitchOwnPersistence( xStorage, sEntName ); 1853 1854 // for linked object it means that it becomes embedded object 1855 // the document must switch it's persistence also 1856 1857 // TODO/LATER: handle the case when temp doc can not be created 1858 // the document is a new embedded object so it must be marked as modified 1859 uno::Reference< util::XCloseable > xDocument = CreateTempDocFromLink_Impl(); 1860 uno::Reference< util::XModifiable > xModif( m_pDocHolder->GetComponent(), uno::UNO_QUERY ); 1861 if ( !xModif.is() ) 1862 throw uno::RuntimeException(); 1863 try 1864 { 1865 xModif->setModified( sal_True ); 1866 } 1867 catch( uno::Exception& ) 1868 {} 1869 1870 m_pDocHolder->SetComponent( xDocument, m_bReadOnly ); 1871 OSL_ENSURE( m_pDocHolder->GetComponent().is(), "If document cant be created, an exception must be thrown!\n" ); 1872 1873 if ( m_nObjectState == embed::EmbedStates::LOADED ) 1874 { 1875 // the state is changed and can not be switched to loaded state back without saving 1876 m_nObjectState = embed::EmbedStates::RUNNING; 1877 StateChangeNotification_Impl( sal_False, embed::EmbedStates::LOADED, m_nObjectState, aGuard ); 1878 } 1879 else if ( m_nObjectState == embed::EmbedStates::ACTIVE ) 1880 m_pDocHolder->Show(); 1881 1882 m_bIsLink = sal_False; 1883 m_aLinkFilterName = ::rtl::OUString(); 1884 m_aLinkURL = ::rtl::OUString(); 1885 } 1886 1887 //------------------------------------------------------ 1888 sal_Bool SAL_CALL OCommonEmbeddedObject::isLink() 1889 throw ( embed::WrongStateException, 1890 uno::RuntimeException ) 1891 { 1892 ::osl::MutexGuard aGuard( m_aMutex ); 1893 if ( m_bDisposed ) 1894 throw lang::DisposedException(); // TODO 1895 1896 // Actually this information is clear even in case object is wayting for saveCompleted 1897 // if ( m_bWaitSaveCompleted ) 1898 // throw embed::WrongStateException( 1899 // ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ), 1900 // uno::Reference< uno::XInterface >( reinterpret_cast< ::cppu::OWeakObject* >(this) ) ); 1901 1902 return m_bIsLink; 1903 } 1904 1905 //------------------------------------------------------ 1906 ::rtl::OUString SAL_CALL OCommonEmbeddedObject::getLinkURL() 1907 throw ( embed::WrongStateException, 1908 uno::Exception, 1909 uno::RuntimeException ) 1910 { 1911 ::osl::MutexGuard aGuard( m_aMutex ); 1912 if ( m_bDisposed ) 1913 throw lang::DisposedException(); // TODO 1914 1915 // Actually this information is clear even in case object is wayting for saveCompleted 1916 // if ( m_bWaitSaveCompleted ) 1917 // throw embed::WrongStateException( 1918 // ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ), 1919 // uno::Reference< uno::XInterface >( reinterpret_cast< ::cppu::OWeakObject* >(this) ) ); 1920 1921 if ( !m_bIsLink ) 1922 throw embed::WrongStateException( 1923 ::rtl::OUString::createFromAscii( "The object is not a link object!\n" ), 1924 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 1925 1926 return m_aLinkURL; 1927 } 1928 1929