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