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