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_embeddedobj.hxx" 24 #include <com/sun/star/frame/XFrame.hpp> 25 #include <com/sun/star/frame/XController.hpp> 26 #include <com/sun/star/frame/XComponentLoader.hpp> 27 #include <com/sun/star/awt/XTopWindow.hpp> 28 #include <com/sun/star/embed/XClassifiedObject.hpp> 29 #include <com/sun/star/io/XStream.hpp> 30 #include <com/sun/star/io/XInputStream.hpp> 31 #include <com/sun/star/io/XOutputStream.hpp> 32 #include <com/sun/star/io/XSeekable.hpp> 33 #include <com/sun/star/task/XInteractionHandler.hpp> 34 #include <com/sun/star/ucb/XSimpleFileAccess.hpp> 35 #include <com/sun/star/util/XCloseable.hpp> 36 #include <com/sun/star/beans/XPropertySet.hpp> 37 38 #ifndef _COM_SUN_STAR_DOCUMENT_XEVENTBROADCASTER_HPP_ 39 #include <com/sun/star/document/XEventBroadcaster.hpp> 40 #endif 41 #include <com/sun/star/document/XEventListener.hpp> 42 #include <com/sun/star/document/XTypeDetection.hpp> 43 #include <com/sun/star/container/XNameAccess.hpp> 44 #include <cppuhelper/implbase1.hxx> 45 #include <comphelper/storagehelper.hxx> 46 #include <comphelper/mimeconfighelper.hxx> 47 48 #include "ownview.hxx" 49 50 using namespace ::com::sun::star; 51 using namespace ::comphelper; 52 53 ::rtl::OUString GetNewTempFileURL_Impl( const uno::Reference< lang::XMultiServiceFactory >& xFactory ); 54 ::rtl::OUString GetNewFilledTempFile_Impl( const uno::Reference< io::XInputStream >& xInStream, const uno::Reference< lang::XMultiServiceFactory >& xFactory ); 55 sal_Bool KillFile_Impl( const ::rtl::OUString& aURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory ); 56 uno::Reference< io::XStream > TryToGetAcceptableFormat_Impl( const uno::Reference< io::XStream >& xStream, const uno::Reference< lang::XMultiServiceFactory >& xFactory ); 57 58 //======================================================== 59 // Dummy interaction handler 60 //======================================================== 61 //-------------------------------------------------------- 62 class DummyHandler_Impl : public ::cppu::WeakImplHelper1< task::XInteractionHandler > 63 { 64 public: 65 DummyHandler_Impl() {} 66 ~DummyHandler_Impl(); 67 68 virtual void SAL_CALL handle( const uno::Reference< task::XInteractionRequest >& xRequest ); 69 }; 70 71 //-------------------------------------------------------- 72 DummyHandler_Impl::~DummyHandler_Impl() 73 { 74 } 75 76 //-------------------------------------------------------- 77 void SAL_CALL DummyHandler_Impl::handle( const uno::Reference< task::XInteractionRequest >& ) 78 { 79 return; 80 } 81 82 //======================================================== 83 // Object viewer 84 //======================================================== 85 //-------------------------------------------------------- 86 OwnView_Impl::OwnView_Impl( const uno::Reference< lang::XMultiServiceFactory >& xFactory, 87 const uno::Reference< io::XInputStream >& xInputStream ) 88 : m_xFactory( xFactory ) 89 , m_bBusy( sal_False ) 90 , m_bUseNative( sal_False ) 91 { 92 if ( !xFactory.is() || !xInputStream.is() ) 93 throw uno::RuntimeException(); 94 95 m_aTempFileURL = GetNewFilledTempFile_Impl( xInputStream, m_xFactory ); 96 } 97 98 //-------------------------------------------------------- 99 OwnView_Impl::~OwnView_Impl() 100 { 101 try { 102 KillFile_Impl( m_aTempFileURL, m_xFactory ); 103 } catch( uno::Exception& ) {} 104 105 try { 106 if ( m_aNativeTempURL.getLength() ) 107 KillFile_Impl( m_aNativeTempURL, m_xFactory ); 108 } catch( uno::Exception& ) {} 109 } 110 111 //-------------------------------------------------------- 112 sal_Bool OwnView_Impl::CreateModelFromURL( const ::rtl::OUString& aFileURL ) 113 { 114 sal_Bool bResult = sal_False; 115 116 if ( aFileURL.getLength() ) 117 { 118 try { 119 uno::Reference < frame::XComponentLoader > xDocumentLoader( 120 m_xFactory->createInstance ( 121 ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), 122 uno::UNO_QUERY ); 123 124 if ( xDocumentLoader.is() ) 125 { 126 uno::Sequence< beans::PropertyValue > aArgs( m_aFilterName.getLength() ? 5 : 4 ); 127 128 aArgs[0].Name = ::rtl::OUString::createFromAscii( "URL" ); 129 aArgs[0].Value <<= aFileURL; 130 131 aArgs[1].Name = ::rtl::OUString::createFromAscii( "ReadOnly" ); 132 aArgs[1].Value <<= sal_True; 133 134 aArgs[2].Name = ::rtl::OUString::createFromAscii( "InteractionHandler" ); 135 aArgs[2].Value <<= uno::Reference< task::XInteractionHandler >( 136 static_cast< ::cppu::OWeakObject* >( new DummyHandler_Impl() ), uno::UNO_QUERY ); 137 138 aArgs[3].Name = ::rtl::OUString::createFromAscii( "DontEdit" ); 139 aArgs[3].Value <<= sal_True; 140 141 if ( m_aFilterName.getLength() ) 142 { 143 aArgs[4].Name = ::rtl::OUString::createFromAscii( "FilterName" ); 144 aArgs[4].Value <<= m_aFilterName; 145 } 146 147 uno::Reference< frame::XModel > xModel( xDocumentLoader->loadComponentFromURL( 148 aFileURL, 149 ::rtl::OUString::createFromAscii( "_blank" ), 150 0, 151 aArgs ), 152 uno::UNO_QUERY ); 153 154 if ( xModel.is() ) 155 { 156 uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY ); 157 if ( xBroadCaster.is() ) 158 xBroadCaster->addEventListener( uno::Reference< document::XEventListener >( 159 static_cast< ::cppu::OWeakObject* >( this ), 160 uno::UNO_QUERY ) ); 161 162 uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY ); 163 if ( xCloseable.is() ) 164 { 165 xCloseable->addCloseListener( uno::Reference< util::XCloseListener >( 166 static_cast< ::cppu::OWeakObject* >( this ), 167 uno::UNO_QUERY ) ); 168 169 ::osl::MutexGuard aGuard( m_aMutex ); 170 m_xModel = xModel; 171 bResult = sal_True; 172 } 173 } 174 } 175 } 176 catch( uno::Exception& ) 177 { 178 } 179 } 180 181 return bResult; 182 } 183 184 //-------------------------------------------------------- 185 sal_Bool OwnView_Impl::CreateModel( sal_Bool bUseNative ) 186 { 187 sal_Bool bResult = sal_False; 188 189 try { 190 bResult = CreateModelFromURL( bUseNative ? m_aNativeTempURL : m_aTempFileURL ); 191 } 192 catch( uno::Exception& ) 193 { 194 } 195 196 return bResult; 197 } 198 199 //-------------------------------------------------------- 200 ::rtl::OUString OwnView_Impl::GetFilterNameFromExtentionAndInStream( 201 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory, 202 const ::rtl::OUString& aNameWithExtention, 203 const uno::Reference< io::XInputStream >& xInputStream ) 204 { 205 if ( !xInputStream.is() ) 206 throw uno::RuntimeException(); 207 208 uno::Reference< document::XTypeDetection > xTypeDetection( 209 xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" ) ), 210 uno::UNO_QUERY_THROW ); 211 212 ::rtl::OUString aTypeName; 213 214 if ( aNameWithExtention.getLength() ) 215 { 216 ::rtl::OUString aURLToAnalyze = 217 ( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "file:///" ) ) + aNameWithExtention ); 218 aTypeName = xTypeDetection->queryTypeByURL( aURLToAnalyze ); 219 } 220 221 uno::Sequence< beans::PropertyValue > aArgs( aTypeName.getLength() ? 3 : 2 ); 222 aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); 223 aArgs[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) ); 224 aArgs[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) ); 225 aArgs[1].Value <<= xInputStream; 226 if ( aTypeName.getLength() ) 227 { 228 aArgs[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TypeName" ) ); 229 aArgs[2].Value <<= aTypeName; 230 } 231 232 aTypeName = xTypeDetection->queryTypeByDescriptor( aArgs, sal_True ); 233 234 ::rtl::OUString aFilterName; 235 for ( sal_Int32 nInd = 0; nInd < aArgs.getLength(); nInd++ ) 236 if ( aArgs[nInd].Name.equalsAscii( "FilterName" ) ) 237 aArgs[nInd].Value >>= aFilterName; 238 239 if ( !aFilterName.getLength() && aTypeName.getLength() ) 240 { 241 // get the default filter name for the type 242 uno::Reference< container::XNameAccess > xNameAccess( xTypeDetection, uno::UNO_QUERY_THROW ); 243 uno::Sequence< beans::PropertyValue > aTypes; 244 245 if ( xNameAccess.is() && ( xNameAccess->getByName( aTypeName ) >>= aTypes ) ) 246 { 247 for ( sal_Int32 nInd = 0; nInd < aTypes.getLength(); nInd++ ) 248 { 249 if ( aTypes[nInd].Name.equalsAscii( "PreferredFilter" ) && ( aTypes[nInd].Value >>= aFilterName ) ) 250 { 251 aTypes[nInd].Value >>= aFilterName; 252 break; 253 } 254 } 255 } 256 } 257 258 return aFilterName; 259 } 260 261 //-------------------------------------------------------- 262 sal_Bool OwnView_Impl::ReadContentsAndGenerateTempFile( const uno::Reference< io::XInputStream >& xInStream, 263 sal_Bool bParseHeader ) 264 { 265 uno::Reference< io::XSeekable > xSeekable( xInStream, uno::UNO_QUERY_THROW ); 266 xSeekable->seek( 0 ); 267 268 // create m_aNativeTempURL 269 ::rtl::OUString aNativeTempURL; 270 uno::Reference < beans::XPropertySet > xNativeTempFile( 271 m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ), 272 uno::UNO_QUERY_THROW ); 273 uno::Reference < io::XStream > xNativeTempStream( xNativeTempFile, uno::UNO_QUERY_THROW ); 274 uno::Reference < io::XOutputStream > xNativeOutTemp = xNativeTempStream->getOutputStream(); 275 uno::Reference < io::XInputStream > xNativeInTemp = xNativeTempStream->getInputStream(); 276 if ( !xNativeOutTemp.is() || !xNativeInTemp.is() ) 277 throw uno::RuntimeException(); 278 279 try { 280 xNativeTempFile->setPropertyValue( ::rtl::OUString::createFromAscii( "RemoveFile" ), uno::makeAny( sal_False ) ); 281 uno::Any aUrl = xNativeTempFile->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) ); 282 aUrl >>= aNativeTempURL; 283 } 284 catch ( uno::Exception& ) 285 { 286 } 287 288 sal_Bool bFailed = sal_False; 289 ::rtl::OUString aFileSuffix; 290 291 if ( bParseHeader ) 292 { 293 uno::Sequence< sal_Int8 > aReadSeq( 4 ); 294 // read the complete size of the Object Package 295 if ( xInStream->readBytes( aReadSeq, 4 ) != 4 ) 296 return sal_False; 297 /* 298 sal_uInt32 nLength = (sal_uInt8)aReadSeq[0] 299 + (sal_uInt8)aReadSeq[1] * 0x100 300 + (sal_uInt8)aReadSeq[2] * 0x10000 301 + (sal_uInt8)aReadSeq[3] * 0x1000000; 302 */ 303 // read the first header ( have no idea what does this header mean ) 304 if ( xInStream->readBytes( aReadSeq, 2 ) != 2 || aReadSeq[0] != 2 || aReadSeq[1] != 0 ) 305 return sal_False; 306 307 // read file name 308 // only extension is interesting so only subset of symbols is accepted 309 do 310 { 311 if ( xInStream->readBytes( aReadSeq, 1 ) != 1 ) 312 return sal_False; 313 314 if ( 315 (aReadSeq[0] >= '0' && aReadSeq[0] <= '9') || 316 (aReadSeq[0] >= 'a' && aReadSeq[0] <= 'z') || 317 (aReadSeq[0] >= 'A' && aReadSeq[0] <= 'Z') || 318 aReadSeq[0] == '.' 319 ) 320 { 321 aFileSuffix += ::rtl::OUString::valueOf( (sal_Unicode) aReadSeq[0] ); 322 } 323 324 } while( aReadSeq[0] ); 325 326 // skip url 327 do 328 { 329 if ( xInStream->readBytes( aReadSeq, 1 ) != 1 ) 330 return sal_False; 331 } while( aReadSeq[0] ); 332 333 // check the next header 334 if ( xInStream->readBytes( aReadSeq, 4 ) != 4 335 || aReadSeq[0] || aReadSeq[1] || aReadSeq[2] != 3 || aReadSeq[3] ) 336 return sal_False; 337 338 // get the size of the next entry 339 if ( xInStream->readBytes( aReadSeq, 4 ) != 4 ) 340 return sal_False; 341 342 sal_uInt32 nUrlSize = (sal_uInt8)aReadSeq[0] 343 + (sal_uInt8)aReadSeq[1] * 0x100 344 + (sal_uInt8)aReadSeq[2] * 0x10000 345 + (sal_uInt8)aReadSeq[3] * 0x1000000; 346 sal_Int64 nTargetPos = xSeekable->getPosition() + nUrlSize; 347 348 xSeekable->seek( nTargetPos ); 349 350 // get the size of stored data 351 if ( xInStream->readBytes( aReadSeq, 4 ) != 4 ) 352 return sal_False; 353 354 sal_uInt32 nDataSize = (sal_uInt8)aReadSeq[0] 355 + (sal_uInt8)aReadSeq[1] * 0x100 356 + (sal_uInt8)aReadSeq[2] * 0x10000 357 + (sal_uInt8)aReadSeq[3] * 0x1000000; 358 359 aReadSeq.realloc( 32000 ); 360 sal_uInt32 nRead = 0; 361 while ( nRead < nDataSize ) 362 { 363 sal_uInt32 nToRead = ( nDataSize - nRead > 32000 ) ? 32000 : nDataSize - nRead; 364 sal_uInt32 nLocalRead = xInStream->readBytes( aReadSeq, nToRead ); 365 366 if ( !nLocalRead ) 367 { 368 bFailed = sal_True; 369 break; 370 } 371 else if ( nLocalRead == 32000 ) 372 xNativeOutTemp->writeBytes( aReadSeq ); 373 else 374 { 375 uno::Sequence< sal_Int8 > aToWrite( aReadSeq ); 376 aToWrite.realloc( nLocalRead ); 377 xNativeOutTemp->writeBytes( aToWrite ); 378 } 379 380 nRead += nLocalRead; 381 } 382 } 383 else 384 { 385 uno::Sequence< sal_Int8 > aData( 8 ); 386 if ( xInStream->readBytes( aData, 8 ) == 8 387 && aData[0] == -1 && aData[1] == -1 && aData[2] == -1 && aData[3] == -1 388 && ( aData[4] == 2 || aData[4] == 3 ) && aData[5] == 0 && aData[6] == 0 && aData[7] == 0 ) 389 { 390 // the header has to be removed 391 xSeekable->seek( 40 ); 392 } 393 else 394 { 395 // the usual Ole10Native format 396 xSeekable->seek( 4 ); 397 } 398 399 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xNativeOutTemp ); 400 } 401 402 xNativeOutTemp->closeOutput(); 403 404 // The temporary native file is created, now the filter must be detected 405 if ( !bFailed ) 406 { 407 m_aFilterName = GetFilterNameFromExtentionAndInStream( m_xFactory, aFileSuffix, xNativeInTemp ); 408 m_aNativeTempURL = aNativeTempURL; 409 } 410 411 return !bFailed; 412 } 413 414 //-------------------------------------------------------- 415 void OwnView_Impl::CreateNative() 416 { 417 if ( m_aNativeTempURL.getLength() ) 418 return; 419 420 try 421 { 422 uno::Reference < ucb::XSimpleFileAccess > xAccess( 423 m_xFactory->createInstance ( 424 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), 425 uno::UNO_QUERY_THROW ); 426 427 uno::Reference< io::XInputStream > xInStream = xAccess->openFileRead( m_aTempFileURL ); 428 if ( !xInStream.is() ) 429 throw uno::RuntimeException(); 430 431 uno::Sequence< uno::Any > aArgs( 1 ); 432 aArgs[0] <<= xInStream; 433 uno::Reference< container::XNameAccess > xNameAccess( 434 m_xFactory->createInstanceWithArguments( 435 ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLESimpleStorage" ), 436 aArgs ), 437 uno::UNO_QUERY_THROW ); 438 439 ::rtl::OUString aSubStreamName = ::rtl::OUString::createFromAscii( "\1Ole10Native" ); 440 uno::Reference< embed::XClassifiedObject > xStor( xNameAccess, uno::UNO_QUERY_THROW ); 441 uno::Sequence< sal_Int8 > aStorClassID = xStor->getClassID(); 442 443 if ( xNameAccess->hasByName( aSubStreamName ) ) 444 { 445 sal_uInt8 aClassID[] = 446 { 0x00, 0x03, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 }; 447 uno::Sequence< sal_Int8 > aPackageClassID( (sal_Int8*)aClassID, 16 ); 448 449 uno::Reference< io::XStream > xSubStream; 450 xNameAccess->getByName( aSubStreamName ) >>= xSubStream; 451 if ( xSubStream.is() ) 452 { 453 sal_Bool bOk = sal_False; 454 455 if ( MimeConfigurationHelper::ClassIDsEqual( aPackageClassID, aStorClassID ) ) 456 { 457 // the storage represents Object Package 458 459 bOk = ReadContentsAndGenerateTempFile( xSubStream->getInputStream(), sal_True ); 460 461 if ( !bOk && m_aNativeTempURL.getLength() ) 462 { 463 KillFile_Impl( m_aNativeTempURL, m_xFactory ); 464 m_aNativeTempURL = ::rtl::OUString(); 465 } 466 } 467 468 if ( !bOk ) 469 { 470 bOk = ReadContentsAndGenerateTempFile( xSubStream->getInputStream(), sal_False ); 471 472 if ( !bOk && m_aNativeTempURL.getLength() ) 473 { 474 KillFile_Impl( m_aNativeTempURL, m_xFactory ); 475 m_aNativeTempURL = ::rtl::OUString(); 476 } 477 } 478 } 479 } 480 else 481 { 482 // TODO/LATER: No native stream, needs a new solution 483 } 484 } 485 catch( uno::Exception& ) 486 {} 487 } 488 489 //-------------------------------------------------------- 490 sal_Bool OwnView_Impl::Open() 491 { 492 sal_Bool bResult = sal_False; 493 494 uno::Reference< frame::XModel > xExistingModel; 495 496 { 497 ::osl::MutexGuard aGuard( m_aMutex ); 498 xExistingModel = m_xModel; 499 if ( m_bBusy ) 500 return sal_False; 501 502 m_bBusy = sal_True; 503 } 504 505 if ( xExistingModel.is() ) 506 { 507 try { 508 uno::Reference< frame::XController > xController = xExistingModel->getCurrentController(); 509 if ( xController.is() ) 510 { 511 uno::Reference< frame::XFrame > xFrame = xController->getFrame(); 512 if ( xFrame.is() ) 513 { 514 xFrame->activate(); 515 uno::Reference<awt::XTopWindow> xTopWindow( xFrame->getContainerWindow(), uno::UNO_QUERY ); 516 if(xTopWindow.is()) 517 xTopWindow->toFront(); 518 519 bResult = sal_True; 520 } 521 } 522 } 523 catch( uno::Exception& ) 524 { 525 } 526 } 527 else 528 { 529 bResult = CreateModel( m_bUseNative ); 530 531 if ( !bResult && !m_bUseNative ) 532 { 533 // the original storage can not be recognized 534 if ( !m_aNativeTempURL.getLength() ) 535 { 536 // create a temporary file for the native representation if there is no 537 CreateNative(); 538 } 539 540 if ( m_aNativeTempURL.getLength() ) 541 { 542 bResult = CreateModel( sal_True ); 543 if ( bResult ) 544 m_bUseNative = sal_True; 545 } 546 } 547 } 548 549 m_bBusy = sal_False; 550 551 return bResult; 552 } 553 554 //-------------------------------------------------------- 555 void OwnView_Impl::Close() 556 { 557 uno::Reference< frame::XModel > xModel; 558 559 { 560 ::osl::MutexGuard aGuard( m_aMutex ); 561 if ( !m_xModel.is() ) 562 return; 563 xModel = m_xModel; 564 m_xModel = uno::Reference< frame::XModel >(); 565 566 if ( m_bBusy ) 567 return; 568 569 m_bBusy = sal_True; 570 } 571 572 try { 573 uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY ); 574 if ( xBroadCaster.is() ) 575 xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >( 576 static_cast< ::cppu::OWeakObject* >( this ), 577 uno::UNO_QUERY ) ); 578 579 uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY ); 580 if ( xCloseable.is() ) 581 { 582 xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >( 583 static_cast< ::cppu::OWeakObject* >( this ), 584 uno::UNO_QUERY ) ); 585 xCloseable->close( sal_True ); 586 } 587 } 588 catch( uno::Exception& ) 589 {} 590 591 m_bBusy = sal_False; 592 } 593 594 //-------------------------------------------------------- 595 void SAL_CALL OwnView_Impl::notifyEvent( const document::EventObject& aEvent ) 596 { 597 598 uno::Reference< frame::XModel > xModel; 599 600 { 601 ::osl::MutexGuard aGuard( m_aMutex ); 602 if ( aEvent.Source == m_xModel && aEvent.EventName.equalsAscii( "OnSaveAsDone" ) ) 603 { 604 // SaveAs operation took place, so just forget the model and deregister listeners 605 xModel = m_xModel; 606 m_xModel = uno::Reference< frame::XModel >(); 607 } 608 } 609 610 if ( xModel.is() ) 611 { 612 try { 613 uno::Reference< document::XEventBroadcaster > xBroadCaster( xModel, uno::UNO_QUERY ); 614 if ( xBroadCaster.is() ) 615 xBroadCaster->removeEventListener( uno::Reference< document::XEventListener >( 616 static_cast< ::cppu::OWeakObject* >( this ), 617 uno::UNO_QUERY ) ); 618 619 uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY ); 620 if ( xCloseable.is() ) 621 xCloseable->removeCloseListener( uno::Reference< util::XCloseListener >( 622 static_cast< ::cppu::OWeakObject* >( this ), 623 uno::UNO_QUERY ) ); 624 } 625 catch( uno::Exception& ) 626 {} 627 } 628 } 629 630 //-------------------------------------------------------- 631 void SAL_CALL OwnView_Impl::queryClosing( const lang::EventObject&, sal_Bool ) 632 { 633 } 634 635 //-------------------------------------------------------- 636 void SAL_CALL OwnView_Impl::notifyClosing( const lang::EventObject& Source ) 637 { 638 ::osl::MutexGuard aGuard( m_aMutex ); 639 if ( Source.Source == m_xModel ) 640 m_xModel = uno::Reference< frame::XModel >(); 641 } 642 643 //-------------------------------------------------------- 644 void SAL_CALL OwnView_Impl::disposing( const lang::EventObject& Source ) 645 { 646 ::osl::MutexGuard aGuard( m_aMutex ); 647 if ( Source.Source == m_xModel ) 648 m_xModel = uno::Reference< frame::XModel >(); 649 }; 650 651 /* vim: set noet sw=4 ts=4: */ 652