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_ucb.hxx" 26 27 /************************************************************************** 28 TODO 29 ************************************************************************** 30 31 *************************************************************************/ 32 33 #include "osl/diagnose.h" 34 #include "rtl/ref.hxx" 35 #include "cppuhelper/weak.hxx" 36 37 #include "comphelper/namedvaluecollection.hxx" 38 #include "comphelper/documentinfo.hxx" 39 40 #include "com/sun/star/awt/XTopWindow.hpp" 41 #include "com/sun/star/beans/XPropertySet.hpp" 42 #include "com/sun/star/container/XEnumerationAccess.hpp" 43 #include "com/sun/star/document/XStorageBasedDocument.hpp" 44 #include "com/sun/star/frame/XStorable.hpp" 45 #include "com/sun/star/lang/DisposedException.hpp" 46 #include "com/sun/star/util/XCloseBroadcaster.hpp" 47 48 #include "tdoc_docmgr.hxx" 49 50 using namespace com::sun::star; 51 using namespace tdoc_ucp; 52 using ::comphelper::DocumentInfo; 53 54 //========================================================================= 55 //========================================================================= 56 // 57 // OfficeDocumentsCloseListener Implementation. 58 // 59 //========================================================================= 60 //========================================================================= 61 62 //========================================================================= 63 // 64 // util::XCloseListener 65 // 66 //========================================================================= 67 68 // virtual 69 void SAL_CALL OfficeDocumentsManager::OfficeDocumentsCloseListener::queryClosing( 70 const lang::EventObject& /*Source*/, sal_Bool /*GetsOwnership*/ ) 71 throw ( util::CloseVetoException, 72 uno::RuntimeException ) 73 { 74 } 75 76 //========================================================================= 77 void SAL_CALL OfficeDocumentsManager::OfficeDocumentsCloseListener::notifyClosing( 78 const lang::EventObject& Source ) 79 throw ( uno::RuntimeException ) 80 { 81 document::EventObject aDocEvent; 82 aDocEvent.Source = Source.Source; 83 aDocEvent.EventName = rtl::OUString( 84 RTL_CONSTASCII_USTRINGPARAM( "OfficeDocumentsListener::notifyClosing" ) ); 85 m_pManager->notifyEvent( aDocEvent ); 86 } 87 88 //========================================================================= 89 // 90 // lang::XEventListener (base of util::XCloseListener) 91 // 92 //========================================================================= 93 94 // virtual 95 void SAL_CALL OfficeDocumentsManager::OfficeDocumentsCloseListener::disposing( 96 const lang::EventObject& /*Source*/ ) 97 throw ( uno::RuntimeException ) 98 { 99 } 100 101 //========================================================================= 102 //========================================================================= 103 // 104 // OfficeDocumentsManager Implementation. 105 // 106 //========================================================================= 107 //========================================================================= 108 109 OfficeDocumentsManager::OfficeDocumentsManager( 110 const uno::Reference< lang::XMultiServiceFactory > & xSMgr, 111 OfficeDocumentsEventListener * pDocEventListener ) 112 : m_xSMgr( xSMgr ), 113 m_xDocEvtNotifier( createDocumentEventNotifier( xSMgr ) ), 114 m_pDocEventListener( pDocEventListener ), 115 m_xDocCloseListener( new OfficeDocumentsCloseListener( this ) ) 116 { 117 if ( m_xDocEvtNotifier.is() ) 118 { 119 // Order is important (multithreaded environment) 120 m_xDocEvtNotifier->addEventListener( this ); 121 buildDocumentsList(); 122 } 123 } 124 125 //========================================================================= 126 // virtual 127 OfficeDocumentsManager::~OfficeDocumentsManager() 128 { 129 //OSL_ENSURE( m_aDocs.empty(), "document list not empty!" ); 130 // no need to assert this: Normal shutdown of OOo could already trigger it, since the order in which 131 // objects are actually released/destroyed upon shutdown is not defined. And when we arrive *here*, 132 // OOo *is* shutting down currently, since we're held by the TDOC provider, which is disposed 133 // upon shutdown. 134 } 135 136 //========================================================================= 137 void OfficeDocumentsManager::destroy() 138 { 139 if ( m_xDocEvtNotifier.is() ) 140 m_xDocEvtNotifier->removeEventListener( this ); 141 } 142 143 //========================================================================= 144 static rtl::OUString 145 getDocumentId( const uno::Reference< uno::XInterface > & xDoc ) 146 { 147 rtl::OUString aId; 148 149 // Try to get the UID directly from the document. 150 uno::Reference< beans::XPropertySet > xPropSet( xDoc, uno::UNO_QUERY ); 151 if ( xPropSet.is() ) 152 { 153 try 154 { 155 uno::Any aValue = xPropSet->getPropertyValue( 156 rtl::OUString( 157 RTL_CONSTASCII_USTRINGPARAM( "RuntimeUID" ) ) ); 158 aValue >>= aId; 159 } 160 catch ( beans::UnknownPropertyException const & ) 161 { 162 // Not actually an error. Property is optional. 163 } 164 catch ( lang::WrappedTargetException const & ) 165 { 166 OSL_ENSURE( false, "Caught WrappedTargetException!" ); 167 } 168 } 169 170 if ( aId.getLength() == 0 ) 171 { 172 // fallback: generate UID from document's this pointer. 173 // normalize the interface pointer first. Else, calls with different 174 // interfaces to the same object (say, XFoo and XBar) will produce 175 // different IDs 176 uno::Reference< uno::XInterface > xNormalizedIFace( xDoc, uno::UNO_QUERY ); 177 sal_Int64 nId = reinterpret_cast< sal_Int64 >( xNormalizedIFace.get() ); 178 aId = rtl::OUString::valueOf( nId ); 179 } 180 181 OSL_ENSURE( aId.getLength() > 0, "getDocumentId - Empty id!" ); 182 return aId; 183 } 184 185 //========================================================================= 186 // 187 // document::XEventListener 188 // 189 //========================================================================= 190 191 // virtual 192 void SAL_CALL OfficeDocumentsManager::notifyEvent( 193 const document::EventObject & Event ) 194 throw ( uno::RuntimeException ) 195 { 196 /* 197 Events documentation: OOo Developer's Guide / Writing UNO Components / Jobs 198 */ 199 200 if ( Event.EventName.equalsAsciiL( 201 RTL_CONSTASCII_STRINGPARAM( "OnLoadFinished" ) ) // document loaded 202 || Event.EventName.equalsAsciiL( 203 RTL_CONSTASCII_STRINGPARAM( "OnCreate" ) ) ) // document created 204 { 205 if ( isOfficeDocument( Event.Source ) ) 206 { 207 osl::MutexGuard aGuard( m_aMtx ); 208 209 uno::Reference< frame::XModel > 210 xModel( Event.Source, uno::UNO_QUERY ); 211 OSL_ENSURE( xModel.is(), "Got no frame::XModel!" ); 212 213 DocumentList::const_iterator it = m_aDocs.begin(); 214 while ( it != m_aDocs.end() ) 215 { 216 if ( (*it).second.xModel == xModel ) 217 { 218 // already known. 219 break; 220 } 221 ++it; 222 } 223 224 if ( it == m_aDocs.end() ) 225 { 226 // new document 227 228 uno::Reference< document::XStorageBasedDocument > 229 xDoc( Event.Source, uno::UNO_QUERY ); 230 OSL_ENSURE( xDoc.is(), "Got no document::XStorageBasedDocument!" ); 231 232 uno::Reference< embed::XStorage > xStorage 233 = xDoc->getDocumentStorage(); 234 OSL_ENSURE( xStorage.is(), "Got no document storage!" ); 235 236 rtl:: OUString aDocId = getDocumentId( Event.Source ); 237 rtl:: OUString aTitle = DocumentInfo::getDocumentTitle( 238 uno::Reference< frame::XModel >( Event.Source, uno::UNO_QUERY ) ); 239 240 m_aDocs[ aDocId ] = StorageInfo( aTitle, xStorage, xModel ); 241 242 uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( 243 Event.Source, uno::UNO_QUERY ); 244 OSL_ENSURE( xCloseBroadcaster.is(), 245 "OnLoadFinished/OnCreate event: got no close broadcaster!" ); 246 247 if ( xCloseBroadcaster.is() ) 248 xCloseBroadcaster->addCloseListener( m_xDocCloseListener ); 249 250 // Propagate document closure. 251 OSL_ENSURE( m_pDocEventListener, 252 "OnLoadFinished/OnCreate event: no owner for insert event propagation!" ); 253 254 if ( m_pDocEventListener ) 255 m_pDocEventListener->notifyDocumentOpened( aDocId ); 256 } 257 } 258 } 259 else if ( Event.EventName.equalsAsciiL( 260 RTL_CONSTASCII_STRINGPARAM( "OfficeDocumentsListener::notifyClosing" ) ) ) 261 { 262 if ( isOfficeDocument( Event.Source ) ) 263 { 264 // Document has been closed (unloaded) 265 266 // #163732# - Official event "OnUnload" does not work here. Event 267 // gets fired to early. Other OnUnload listeners called after this 268 // listener may still need TDOC access to the document. Remove the 269 // document from TDOC docs list on XCloseListener::notifyClosing. 270 // See OfficeDocumentsManager::OfficeDocumentsListener::notifyClosing. 271 272 osl::MutexGuard aGuard( m_aMtx ); 273 274 uno::Reference< frame::XModel > 275 xModel( Event.Source, uno::UNO_QUERY ); 276 OSL_ENSURE( xModel.is(), "Got no frame::XModel!" ); 277 278 DocumentList::iterator it = m_aDocs.begin(); 279 while ( it != m_aDocs.end() ) 280 { 281 if ( (*it).second.xModel == xModel ) 282 { 283 // Propagate document closure. 284 OSL_ENSURE( m_pDocEventListener, 285 "OnUnload event: no owner for close event propagation!" ); 286 287 if ( m_pDocEventListener ) 288 { 289 rtl::OUString aDocId( (*it).first ); 290 m_pDocEventListener->notifyDocumentClosed( aDocId ); 291 } 292 break; 293 } 294 ++it; 295 } 296 297 OSL_ENSURE( it != m_aDocs.end(), 298 "OnUnload event notified for unknown document!" ); 299 300 if ( it != m_aDocs.end() ) 301 { 302 uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( 303 Event.Source, uno::UNO_QUERY ); 304 OSL_ENSURE( xCloseBroadcaster.is(), 305 "OnUnload event: got no XCloseBroadcaster from XModel" ); 306 307 if ( xCloseBroadcaster.is() ) 308 xCloseBroadcaster->removeCloseListener( m_xDocCloseListener ); 309 310 m_aDocs.erase( it ); 311 } 312 } 313 } 314 else if ( Event.EventName.equalsAsciiL( 315 RTL_CONSTASCII_STRINGPARAM( "OnSaveDone" ) ) ) 316 { 317 if ( isOfficeDocument( Event.Source ) ) 318 { 319 osl::MutexGuard aGuard( m_aMtx ); 320 321 uno::Reference< frame::XModel > 322 xModel( Event.Source, uno::UNO_QUERY ); 323 OSL_ENSURE( xModel.is(), "Got no frame::XModel!" ); 324 325 DocumentList::iterator it = m_aDocs.begin(); 326 while ( it != m_aDocs.end() ) 327 { 328 if ( (*it).second.xModel == xModel ) 329 { 330 // Storage gets exchanged while saving. 331 uno::Reference< document::XStorageBasedDocument > 332 xDoc( Event.Source, uno::UNO_QUERY ); 333 OSL_ENSURE( xDoc.is(), 334 "Got no document::XStorageBasedDocument!" ); 335 336 uno::Reference< embed::XStorage > xStorage 337 = xDoc->getDocumentStorage(); 338 OSL_ENSURE( xStorage.is(), "Got no document storage!" ); 339 340 (*it).second.xStorage = xStorage; 341 break; 342 } 343 ++it; 344 } 345 346 OSL_ENSURE( it != m_aDocs.end(), 347 "OnSaveDone event notified for unknown document!" ); 348 } 349 } 350 else if ( Event.EventName.equalsAsciiL( 351 RTL_CONSTASCII_STRINGPARAM( "OnSaveAsDone" ) ) ) 352 { 353 if ( isOfficeDocument( Event.Source ) ) 354 { 355 osl::MutexGuard aGuard( m_aMtx ); 356 357 uno::Reference< frame::XModel > 358 xModel( Event.Source, uno::UNO_QUERY ); 359 OSL_ENSURE( xModel.is(), "Got no frame::XModel!" ); 360 361 DocumentList::iterator it = m_aDocs.begin(); 362 while ( it != m_aDocs.end() ) 363 { 364 if ( (*it).second.xModel == xModel ) 365 { 366 // Storage gets exchanged while saving. 367 uno::Reference< document::XStorageBasedDocument > 368 xDoc( Event.Source, uno::UNO_QUERY ); 369 OSL_ENSURE( xDoc.is(), 370 "Got no document::XStorageBasedDocument!" ); 371 372 uno::Reference< embed::XStorage > xStorage 373 = xDoc->getDocumentStorage(); 374 OSL_ENSURE( xStorage.is(), "Got no document storage!" ); 375 376 (*it).second.xStorage = xStorage; 377 378 // Adjust title. 379 (*it).second.aTitle = DocumentInfo::getDocumentTitle( xModel ); 380 break; 381 } 382 ++it; 383 } 384 385 OSL_ENSURE( it != m_aDocs.end(), 386 "OnSaveAsDone event notified for unknown document!" ); 387 } 388 } 389 else if ( Event.EventName.equalsAsciiL( 390 RTL_CONSTASCII_STRINGPARAM( "OnTitleChanged" ) ) ) 391 { 392 if ( isOfficeDocument( Event.Source ) ) 393 { 394 osl::MutexGuard aGuard( m_aMtx ); 395 396 uno::Reference< frame::XModel > 397 xModel( Event.Source, uno::UNO_QUERY ); 398 OSL_ENSURE( xModel.is(), "Got no frame::XModel!" ); 399 400 DocumentList::iterator it = m_aDocs.begin(); 401 while ( it != m_aDocs.end() ) 402 { 403 if ( (*it).second.xModel == xModel ) 404 { 405 // Adjust title. 406 rtl:: OUString aTitle = DocumentInfo::getDocumentTitle( xModel ); 407 (*it).second.aTitle = aTitle; 408 409 // Adjust storage. 410 uno::Reference< document::XStorageBasedDocument > 411 xDoc( Event.Source, uno::UNO_QUERY ); 412 OSL_ENSURE( xDoc.is(), "Got no document::XStorageBasedDocument!" ); 413 414 uno::Reference< embed::XStorage > xStorage 415 = xDoc->getDocumentStorage(); 416 OSL_ENSURE( xDoc.is(), "Got no document storage!" ); 417 418 rtl:: OUString aDocId = getDocumentId( Event.Source ); 419 420 m_aDocs[ aDocId ] = StorageInfo( aTitle, xStorage, xModel ); 421 break; 422 } 423 ++it; 424 } 425 426 // OSL_ENSURE( it != m_aDocs.end(), 427 // "TitleChanged event notified for unknown document!" ); 428 // TODO: re-enable this assertion. It has been disabled for now, since it breaks the assertion-free smoketest, 429 // and the fix is more difficult than what can be done now. 430 // The problem is that at the moment, when you close a SFX-based document via API, it will first 431 // fire the notifyClosing event, which will make the OfficeDocumentsManager remove the doc from its list. 432 // Then, it will notify an OnTitleChanged, then an OnUnload. Documents closed via call the notifyClosing 433 // *after* OnUnload and all other On* events. 434 // In agreement with MBA, the implementation for SfxBaseModel::Close should be changed to also send notifyClosing 435 // as last event. When this happens, the assertion here must be enabled, again. 436 // There is no bug for this, yet - IZ is currently down due to the Kenai migration. 437 // 2011-02-23 / frank.schoenheit@sun.com 438 } 439 } 440 } 441 442 //========================================================================= 443 // 444 // lang::XEventListener (base of document::XEventListener) 445 // 446 //========================================================================= 447 448 // virtual 449 void SAL_CALL OfficeDocumentsManager::disposing( 450 const lang::EventObject& /*Source*/ ) 451 throw ( uno::RuntimeException ) 452 { 453 } 454 455 //========================================================================= 456 // 457 // Non-interface. 458 // 459 //========================================================================= 460 461 // static 462 uno::Reference< document::XEventBroadcaster > 463 OfficeDocumentsManager::createDocumentEventNotifier( 464 const uno::Reference< lang::XMultiServiceFactory >& rXSMgr ) 465 { 466 uno::Reference< uno::XInterface > xIfc; 467 try 468 { 469 xIfc = rXSMgr->createInstance( 470 rtl::OUString( 471 RTL_CONSTASCII_USTRINGPARAM( 472 "com.sun.star.frame.GlobalEventBroadcaster" ) ) ); 473 } 474 catch ( uno::Exception const & ) 475 { 476 // handled below. 477 } 478 479 OSL_ENSURE( 480 xIfc.is(), 481 "Could not instanciate com.sun.star.frame.GlobalEventBroadcaster" ); 482 483 if ( xIfc.is() ) 484 { 485 uno::Reference< document::XEventBroadcaster > xBC( 486 xIfc, uno::UNO_QUERY ); 487 488 OSL_ENSURE( 489 xBC.is(), 490 "com.sun.star.frame.GlobalEventBroadcaster does not implement " 491 "interface com.sun.star.document.XEventBroadcaster!" ); 492 493 return xBC; 494 } 495 else 496 return uno::Reference< document::XEventBroadcaster >(); 497 } 498 499 //========================================================================= 500 void OfficeDocumentsManager::buildDocumentsList() 501 { 502 OSL_ENSURE( m_xDocEvtNotifier.is(), 503 "OfficeDocumentsManager::buildDocumentsList - " 504 "No document event notifier!" ); 505 506 uno::Reference< container::XEnumerationAccess > xEnumAccess( 507 m_xDocEvtNotifier, uno::UNO_QUERY_THROW ); 508 509 uno::Reference< container::XEnumeration > xEnum 510 = xEnumAccess->createEnumeration(); 511 512 osl::MutexGuard aGuard( m_aMtx ); 513 514 while ( xEnum->hasMoreElements() ) 515 { 516 uno::Any aValue = xEnum->nextElement(); 517 // container::NoSuchElementException 518 // lang::WrappedTargetException 519 520 try 521 { 522 uno::Reference< frame::XModel > xModel; 523 aValue >>= xModel; 524 525 if ( xModel.is() ) 526 { 527 if ( isOfficeDocument( xModel ) ) 528 { 529 DocumentList::const_iterator it = m_aDocs.begin(); 530 while ( it != m_aDocs.end() ) 531 { 532 if ( (*it).second.xModel == xModel ) 533 { 534 // already known. 535 break; 536 } 537 ++it; 538 } 539 540 if ( it == m_aDocs.end() ) 541 { 542 // new document 543 rtl::OUString aDocId = getDocumentId( xModel ); 544 rtl::OUString aTitle = DocumentInfo::getDocumentTitle( xModel ); 545 546 uno::Reference< document::XStorageBasedDocument > 547 xDoc( xModel, uno::UNO_QUERY ); 548 OSL_ENSURE( xDoc.is(), 549 "Got no document::XStorageBasedDocument!" ); 550 551 uno::Reference< embed::XStorage > xStorage 552 = xDoc->getDocumentStorage(); 553 OSL_ENSURE( xDoc.is(), "Got no document storage!" ); 554 555 m_aDocs[ aDocId ] 556 = StorageInfo( aTitle, xStorage, xModel ); 557 558 uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( 559 xModel, uno::UNO_QUERY ); 560 OSL_ENSURE( xCloseBroadcaster.is(), 561 "buildDocumentsList: got no close broadcaster!" ); 562 563 if ( xCloseBroadcaster.is() ) 564 xCloseBroadcaster->addCloseListener( m_xDocCloseListener ); 565 } 566 } 567 } 568 } 569 catch ( lang::DisposedException const & ) 570 { 571 // Note: Due to race conditions the XEnumeration can 572 // contains docs that already have been closed 573 } 574 } 575 } 576 577 //========================================================================= 578 uno::Reference< embed::XStorage > 579 OfficeDocumentsManager::queryStorage( const rtl::OUString & rDocId ) 580 { 581 osl::MutexGuard aGuard( m_aMtx ); 582 583 DocumentList::const_iterator it = m_aDocs.find( rDocId ); 584 if ( it == m_aDocs.end() ) 585 return uno::Reference< embed::XStorage >(); 586 587 return (*it).second.xStorage; 588 } 589 590 //========================================================================= 591 rtl::OUString OfficeDocumentsManager::queryDocumentId( 592 const uno::Reference< frame::XModel > & xModel ) 593 { 594 return getDocumentId( xModel ); 595 } 596 597 //========================================================================= 598 uno::Reference< frame::XModel > 599 OfficeDocumentsManager::queryDocumentModel( const rtl::OUString & rDocId ) 600 { 601 osl::MutexGuard aGuard( m_aMtx ); 602 603 DocumentList::const_iterator it = m_aDocs.find( rDocId ); 604 if ( it == m_aDocs.end() ) 605 return uno::Reference< frame::XModel >(); 606 607 return (*it).second.xModel; 608 } 609 610 //========================================================================= 611 uno::Sequence< rtl::OUString > OfficeDocumentsManager::queryDocuments() 612 { 613 osl::MutexGuard aGuard( m_aMtx ); 614 615 uno::Sequence< rtl::OUString > aRet( m_aDocs.size() ); 616 sal_Int32 nPos = 0; 617 618 DocumentList::const_iterator it = m_aDocs.begin(); 619 while ( it != m_aDocs.end() ) 620 { 621 aRet[ nPos ] = (*it).first; 622 ++it; 623 ++nPos; 624 } 625 return aRet; 626 } 627 628 //========================================================================= 629 rtl::OUString 630 OfficeDocumentsManager::queryStorageTitle( const rtl::OUString & rDocId ) 631 { 632 osl::MutexGuard aGuard( m_aMtx ); 633 634 DocumentList::const_iterator it = m_aDocs.find( rDocId ); 635 if ( it == m_aDocs.end() ) 636 return rtl::OUString(); 637 638 return (*it).second.aTitle; 639 } 640 641 //========================================================================= 642 bool OfficeDocumentsManager::isDocumentPreview( 643 const uno::Reference< frame::XModel > & xModel ) 644 { 645 if ( !xModel.is() ) 646 return false; 647 648 ::comphelper::NamedValueCollection aArgs( 649 xModel->getArgs() ); 650 sal_Bool bIsPreview = aArgs.getOrDefault( "Preview", sal_False ); 651 return bIsPreview; 652 } 653 654 //========================================================================= 655 bool OfficeDocumentsManager::isHelpDocument( 656 const uno::Reference< frame::XModel > & xModel ) 657 { 658 if ( !xModel.is() ) 659 return false; 660 661 ::rtl::OUString sURL( xModel->getURL() ); 662 if ( sURL.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.help://" ) ) ) 663 return true; 664 665 return false; 666 } 667 668 //========================================================================= 669 bool OfficeDocumentsManager::isWithoutOrInTopLevelFrame( 670 const uno::Reference< frame::XModel > & xModel ) 671 { 672 if ( !xModel.is() ) 673 return false; 674 675 uno::Reference< frame::XController > xController 676 = xModel->getCurrentController(); 677 if ( xController.is() ) 678 { 679 uno::Reference< frame::XFrame > xFrame 680 = xController->getFrame(); 681 if ( xFrame.is() ) 682 { 683 // don't use XFrame::isTop here. This nowadays excludes 684 // "sub documents" such as forms embedded in database documents 685 uno::Reference< awt::XTopWindow > xFrameContainer( 686 xFrame->getContainerWindow(), uno::UNO_QUERY ); 687 if ( !xFrameContainer.is() ) 688 return false; 689 } 690 } 691 692 return true; 693 } 694 695 //========================================================================= 696 bool OfficeDocumentsManager::isBasicIDE( 697 const uno::Reference< frame::XModel > & xModel ) 698 { 699 if ( !m_xModuleMgr.is() ) 700 { 701 osl::MutexGuard aGuard( m_aMtx ); 702 if ( !m_xModuleMgr.is() ) 703 { 704 try 705 { 706 m_xModuleMgr 707 = uno::Reference< 708 frame::XModuleManager >( 709 m_xSMgr->createInstance( 710 rtl::OUString( 711 RTL_CONSTASCII_USTRINGPARAM( 712 "com.sun.star.frame.ModuleManager" ) ) ), 713 uno::UNO_QUERY ); 714 } 715 catch ( uno::Exception const & ) 716 { 717 // handled below. 718 } 719 720 OSL_ENSURE( m_xModuleMgr .is(), 721 "Could not instanciate ModuleManager service!" ); 722 } 723 } 724 725 if ( m_xModuleMgr.is() ) 726 { 727 rtl::OUString aModule; 728 try 729 { 730 aModule = m_xModuleMgr->identify( xModel ); 731 } 732 catch ( lang::IllegalArgumentException const & ) 733 { 734 OSL_ENSURE( false, "Caught IllegalArgumentException!" ); 735 } 736 catch ( frame::UnknownModuleException const & ) 737 { 738 OSL_ENSURE( false, "Caught UnknownModuleException!" ); 739 } 740 741 if ( aModule.getLength() > 0 ) 742 { 743 // Filter unwanted items, that are no real documents. 744 if ( aModule.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( 745 "com.sun.star.script.BasicIDE" ) ) ) 746 { 747 return true; 748 } 749 } 750 } 751 752 return false; 753 } 754 755 //========================================================================= 756 bool OfficeDocumentsManager::isOfficeDocument( 757 const uno::Reference< uno::XInterface > & xDoc ) 758 { 759 uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY ); 760 uno::Reference< document::XStorageBasedDocument > 761 xStorageBasedDoc( xModel, uno::UNO_QUERY ); 762 if ( !xStorageBasedDoc.is() ) 763 return false; 764 765 if ( !isWithoutOrInTopLevelFrame( xModel ) ) 766 return false; 767 768 if ( isDocumentPreview( xModel ) ) 769 return false; 770 771 if ( isHelpDocument( xModel ) ) 772 return false; 773 774 if ( isBasicIDE( xModel ) ) 775 return false; 776 777 return true; 778 } 779