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