| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_ucb.hxx" |
| |
| /************************************************************************** |
| TODO |
| ************************************************************************** |
| |
| *************************************************************************/ |
| |
| #include "osl/diagnose.h" |
| #include "rtl/ref.hxx" |
| #include "cppuhelper/weak.hxx" |
| |
| #include "comphelper/namedvaluecollection.hxx" |
| #include "comphelper/documentinfo.hxx" |
| |
| #include "com/sun/star/awt/XTopWindow.hpp" |
| #include "com/sun/star/beans/XPropertySet.hpp" |
| #include "com/sun/star/container/XEnumerationAccess.hpp" |
| #include "com/sun/star/document/XStorageBasedDocument.hpp" |
| #include "com/sun/star/frame/XStorable.hpp" |
| #include "com/sun/star/lang/DisposedException.hpp" |
| #include "com/sun/star/util/XCloseBroadcaster.hpp" |
| |
| #include "tdoc_docmgr.hxx" |
| |
| using namespace com::sun::star; |
| using namespace tdoc_ucp; |
| using ::comphelper::DocumentInfo; |
| |
| //========================================================================= |
| //========================================================================= |
| // |
| // OfficeDocumentsCloseListener Implementation. |
| // |
| //========================================================================= |
| //========================================================================= |
| |
| //========================================================================= |
| // |
| // util::XCloseListener |
| // |
| //========================================================================= |
| |
| // virtual |
| void SAL_CALL OfficeDocumentsManager::OfficeDocumentsCloseListener::queryClosing( |
| const lang::EventObject& /*Source*/, sal_Bool /*GetsOwnership*/ ) |
| throw ( util::CloseVetoException, |
| uno::RuntimeException ) |
| { |
| } |
| |
| //========================================================================= |
| void SAL_CALL OfficeDocumentsManager::OfficeDocumentsCloseListener::notifyClosing( |
| const lang::EventObject& Source ) |
| throw ( uno::RuntimeException ) |
| { |
| document::EventObject aDocEvent; |
| aDocEvent.Source = Source.Source; |
| aDocEvent.EventName = rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( "OfficeDocumentsListener::notifyClosing" ) ); |
| m_pManager->notifyEvent( aDocEvent ); |
| } |
| |
| //========================================================================= |
| // |
| // lang::XEventListener (base of util::XCloseListener) |
| // |
| //========================================================================= |
| |
| // virtual |
| void SAL_CALL OfficeDocumentsManager::OfficeDocumentsCloseListener::disposing( |
| const lang::EventObject& /*Source*/ ) |
| throw ( uno::RuntimeException ) |
| { |
| } |
| |
| //========================================================================= |
| //========================================================================= |
| // |
| // OfficeDocumentsManager Implementation. |
| // |
| //========================================================================= |
| //========================================================================= |
| |
| OfficeDocumentsManager::OfficeDocumentsManager( |
| const uno::Reference< lang::XMultiServiceFactory > & xSMgr, |
| OfficeDocumentsEventListener * pDocEventListener ) |
| : m_xSMgr( xSMgr ), |
| m_xDocEvtNotifier( createDocumentEventNotifier( xSMgr ) ), |
| m_pDocEventListener( pDocEventListener ), |
| m_xDocCloseListener( new OfficeDocumentsCloseListener( this ) ) |
| { |
| if ( m_xDocEvtNotifier.is() ) |
| { |
| // Order is important (multithreaded environment) |
| m_xDocEvtNotifier->addEventListener( this ); |
| buildDocumentsList(); |
| } |
| } |
| |
| //========================================================================= |
| // virtual |
| OfficeDocumentsManager::~OfficeDocumentsManager() |
| { |
| //OSL_ENSURE( m_aDocs.empty(), "document list not empty!" ); |
| // no need to assert this: Normal shutdown of OOo could already trigger it, since the order in which |
| // objects are actually released/destroyed upon shutdown is not defined. And when we arrive *here*, |
| // OOo *is* shutting down currently, since we're held by the TDOC provider, which is disposed |
| // upon shutdown. |
| } |
| |
| //========================================================================= |
| void OfficeDocumentsManager::destroy() |
| { |
| if ( m_xDocEvtNotifier.is() ) |
| m_xDocEvtNotifier->removeEventListener( this ); |
| } |
| |
| //========================================================================= |
| static rtl::OUString |
| getDocumentId( const uno::Reference< uno::XInterface > & xDoc ) |
| { |
| rtl::OUString aId; |
| |
| // Try to get the UID directly from the document. |
| uno::Reference< beans::XPropertySet > xPropSet( xDoc, uno::UNO_QUERY ); |
| if ( xPropSet.is() ) |
| { |
| try |
| { |
| uno::Any aValue = xPropSet->getPropertyValue( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( "RuntimeUID" ) ) ); |
| aValue >>= aId; |
| } |
| catch ( beans::UnknownPropertyException const & ) |
| { |
| // Not actually an error. Property is optional. |
| } |
| catch ( lang::WrappedTargetException const & ) |
| { |
| OSL_ENSURE( false, "Caught WrappedTargetException!" ); |
| } |
| } |
| |
| if ( aId.getLength() == 0 ) |
| { |
| // fallback: generate UID from document's this pointer. |
| // normalize the interface pointer first. Else, calls with different |
| // interfaces to the same object (say, XFoo and XBar) will produce |
| // different IDs |
| uno::Reference< uno::XInterface > xNormalizedIFace( xDoc, uno::UNO_QUERY ); |
| sal_Int64 nId = reinterpret_cast< sal_Int64 >( xNormalizedIFace.get() ); |
| aId = rtl::OUString::valueOf( nId ); |
| } |
| |
| OSL_ENSURE( aId.getLength() > 0, "getDocumentId - Empty id!" ); |
| return aId; |
| } |
| |
| //========================================================================= |
| // |
| // document::XEventListener |
| // |
| //========================================================================= |
| |
| // virtual |
| void SAL_CALL OfficeDocumentsManager::notifyEvent( |
| const document::EventObject & Event ) |
| throw ( uno::RuntimeException ) |
| { |
| /* |
| Events documentation: OOo Developer's Guide / Writing UNO Components / Jobs |
| */ |
| |
| if ( Event.EventName.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "OnLoadFinished" ) ) // document loaded |
| || Event.EventName.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "OnCreate" ) ) ) // document created |
| { |
| if ( isOfficeDocument( Event.Source ) ) |
| { |
| osl::MutexGuard aGuard( m_aMtx ); |
| |
| uno::Reference< frame::XModel > |
| xModel( Event.Source, uno::UNO_QUERY ); |
| OSL_ENSURE( xModel.is(), "Got no frame::XModel!" ); |
| |
| DocumentList::const_iterator it = m_aDocs.begin(); |
| while ( it != m_aDocs.end() ) |
| { |
| if ( (*it).second.xModel == xModel ) |
| { |
| // already known. |
| break; |
| } |
| ++it; |
| } |
| |
| if ( it == m_aDocs.end() ) |
| { |
| // new document |
| |
| uno::Reference< document::XStorageBasedDocument > |
| xDoc( Event.Source, uno::UNO_QUERY ); |
| OSL_ENSURE( xDoc.is(), "Got no document::XStorageBasedDocument!" ); |
| |
| uno::Reference< embed::XStorage > xStorage |
| = xDoc->getDocumentStorage(); |
| OSL_ENSURE( xStorage.is(), "Got no document storage!" ); |
| |
| rtl:: OUString aDocId = getDocumentId( Event.Source ); |
| rtl:: OUString aTitle = DocumentInfo::getDocumentTitle( |
| uno::Reference< frame::XModel >( Event.Source, uno::UNO_QUERY ) ); |
| |
| m_aDocs[ aDocId ] = StorageInfo( aTitle, xStorage, xModel ); |
| |
| uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( |
| Event.Source, uno::UNO_QUERY ); |
| OSL_ENSURE( xCloseBroadcaster.is(), |
| "OnLoadFinished/OnCreate event: got no close broadcaster!" ); |
| |
| if ( xCloseBroadcaster.is() ) |
| xCloseBroadcaster->addCloseListener( m_xDocCloseListener ); |
| |
| // Propagate document closure. |
| OSL_ENSURE( m_pDocEventListener, |
| "OnLoadFinished/OnCreate event: no owner for insert event propagation!" ); |
| |
| if ( m_pDocEventListener ) |
| m_pDocEventListener->notifyDocumentOpened( aDocId ); |
| } |
| } |
| } |
| else if ( Event.EventName.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "OfficeDocumentsListener::notifyClosing" ) ) ) |
| { |
| if ( isOfficeDocument( Event.Source ) ) |
| { |
| // Document has been closed (unloaded) |
| |
| // #163732# - Official event "OnUnload" does not work here. Event |
| // gets fired to early. Other OnUnload listeners called after this |
| // listener may still need TDOC access to the document. Remove the |
| // document from TDOC docs list on XCloseListener::notifyClosing. |
| // See OfficeDocumentsManager::OfficeDocumentsListener::notifyClosing. |
| |
| osl::MutexGuard aGuard( m_aMtx ); |
| |
| uno::Reference< frame::XModel > |
| xModel( Event.Source, uno::UNO_QUERY ); |
| OSL_ENSURE( xModel.is(), "Got no frame::XModel!" ); |
| |
| DocumentList::iterator it = m_aDocs.begin(); |
| while ( it != m_aDocs.end() ) |
| { |
| if ( (*it).second.xModel == xModel ) |
| { |
| // Propagate document closure. |
| OSL_ENSURE( m_pDocEventListener, |
| "OnUnload event: no owner for close event propagation!" ); |
| |
| if ( m_pDocEventListener ) |
| { |
| rtl::OUString aDocId( (*it).first ); |
| m_pDocEventListener->notifyDocumentClosed( aDocId ); |
| } |
| break; |
| } |
| ++it; |
| } |
| |
| OSL_ENSURE( it != m_aDocs.end(), |
| "OnUnload event notified for unknown document!" ); |
| |
| if ( it != m_aDocs.end() ) |
| { |
| uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( |
| Event.Source, uno::UNO_QUERY ); |
| OSL_ENSURE( xCloseBroadcaster.is(), |
| "OnUnload event: got no XCloseBroadcaster from XModel" ); |
| |
| if ( xCloseBroadcaster.is() ) |
| xCloseBroadcaster->removeCloseListener( m_xDocCloseListener ); |
| |
| m_aDocs.erase( it ); |
| } |
| } |
| } |
| else if ( Event.EventName.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "OnSaveDone" ) ) ) |
| { |
| if ( isOfficeDocument( Event.Source ) ) |
| { |
| osl::MutexGuard aGuard( m_aMtx ); |
| |
| uno::Reference< frame::XModel > |
| xModel( Event.Source, uno::UNO_QUERY ); |
| OSL_ENSURE( xModel.is(), "Got no frame::XModel!" ); |
| |
| DocumentList::iterator it = m_aDocs.begin(); |
| while ( it != m_aDocs.end() ) |
| { |
| if ( (*it).second.xModel == xModel ) |
| { |
| // Storage gets exchanged while saving. |
| uno::Reference< document::XStorageBasedDocument > |
| xDoc( Event.Source, uno::UNO_QUERY ); |
| OSL_ENSURE( xDoc.is(), |
| "Got no document::XStorageBasedDocument!" ); |
| |
| uno::Reference< embed::XStorage > xStorage |
| = xDoc->getDocumentStorage(); |
| OSL_ENSURE( xStorage.is(), "Got no document storage!" ); |
| |
| (*it).second.xStorage = xStorage; |
| break; |
| } |
| ++it; |
| } |
| |
| OSL_ENSURE( it != m_aDocs.end(), |
| "OnSaveDone event notified for unknown document!" ); |
| } |
| } |
| else if ( Event.EventName.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "OnSaveAsDone" ) ) ) |
| { |
| if ( isOfficeDocument( Event.Source ) ) |
| { |
| osl::MutexGuard aGuard( m_aMtx ); |
| |
| uno::Reference< frame::XModel > |
| xModel( Event.Source, uno::UNO_QUERY ); |
| OSL_ENSURE( xModel.is(), "Got no frame::XModel!" ); |
| |
| DocumentList::iterator it = m_aDocs.begin(); |
| while ( it != m_aDocs.end() ) |
| { |
| if ( (*it).second.xModel == xModel ) |
| { |
| // Storage gets exchanged while saving. |
| uno::Reference< document::XStorageBasedDocument > |
| xDoc( Event.Source, uno::UNO_QUERY ); |
| OSL_ENSURE( xDoc.is(), |
| "Got no document::XStorageBasedDocument!" ); |
| |
| uno::Reference< embed::XStorage > xStorage |
| = xDoc->getDocumentStorage(); |
| OSL_ENSURE( xStorage.is(), "Got no document storage!" ); |
| |
| (*it).second.xStorage = xStorage; |
| |
| // Adjust title. |
| (*it).second.aTitle = DocumentInfo::getDocumentTitle( xModel ); |
| break; |
| } |
| ++it; |
| } |
| |
| OSL_ENSURE( it != m_aDocs.end(), |
| "OnSaveAsDone event notified for unknown document!" ); |
| } |
| } |
| else if ( Event.EventName.equalsAsciiL( |
| RTL_CONSTASCII_STRINGPARAM( "OnTitleChanged" ) ) ) |
| { |
| if ( isOfficeDocument( Event.Source ) ) |
| { |
| osl::MutexGuard aGuard( m_aMtx ); |
| |
| uno::Reference< frame::XModel > |
| xModel( Event.Source, uno::UNO_QUERY ); |
| OSL_ENSURE( xModel.is(), "Got no frame::XModel!" ); |
| |
| DocumentList::iterator it = m_aDocs.begin(); |
| while ( it != m_aDocs.end() ) |
| { |
| if ( (*it).second.xModel == xModel ) |
| { |
| // Adjust title. |
| rtl:: OUString aTitle = DocumentInfo::getDocumentTitle( xModel ); |
| (*it).second.aTitle = aTitle; |
| |
| // Adjust storage. |
| uno::Reference< document::XStorageBasedDocument > |
| xDoc( Event.Source, uno::UNO_QUERY ); |
| OSL_ENSURE( xDoc.is(), "Got no document::XStorageBasedDocument!" ); |
| |
| uno::Reference< embed::XStorage > xStorage |
| = xDoc->getDocumentStorage(); |
| OSL_ENSURE( xDoc.is(), "Got no document storage!" ); |
| |
| rtl:: OUString aDocId = getDocumentId( Event.Source ); |
| |
| m_aDocs[ aDocId ] = StorageInfo( aTitle, xStorage, xModel ); |
| break; |
| } |
| ++it; |
| } |
| |
| // OSL_ENSURE( it != m_aDocs.end(), |
| // "TitleChanged event notified for unknown document!" ); |
| // TODO: re-enable this assertion. It has been disabled for now, since it breaks the assertion-free smoketest, |
| // and the fix is more difficult than what can be done now. |
| // The problem is that at the moment, when you close a SFX-based document via API, it will first |
| // fire the notifyClosing event, which will make the OfficeDocumentsManager remove the doc from its list. |
| // Then, it will notify an OnTitleChanged, then an OnUnload. Documents closed via call the notifyClosing |
| // *after* OnUnload and all other On* events. |
| // In agreement with MBA, the implementation for SfxBaseModel::Close should be changed to also send notifyClosing |
| // as last event. When this happens, the assertion here must be enabled, again. |
| // There is no bug for this, yet - IZ is currently down due to the Kenai migration. |
| // 2011-02-23 / frank.schoenheit@sun.com |
| } |
| } |
| } |
| |
| //========================================================================= |
| // |
| // lang::XEventListener (base of document::XEventListener) |
| // |
| //========================================================================= |
| |
| // virtual |
| void SAL_CALL OfficeDocumentsManager::disposing( |
| const lang::EventObject& /*Source*/ ) |
| throw ( uno::RuntimeException ) |
| { |
| } |
| |
| //========================================================================= |
| // |
| // Non-interface. |
| // |
| //========================================================================= |
| |
| // static |
| uno::Reference< document::XEventBroadcaster > |
| OfficeDocumentsManager::createDocumentEventNotifier( |
| const uno::Reference< lang::XMultiServiceFactory >& rXSMgr ) |
| { |
| uno::Reference< uno::XInterface > xIfc; |
| try |
| { |
| xIfc = rXSMgr->createInstance( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.frame.GlobalEventBroadcaster" ) ) ); |
| } |
| catch ( uno::Exception const & ) |
| { |
| // handled below. |
| } |
| |
| OSL_ENSURE( |
| xIfc.is(), |
| "Could not instanciate com.sun.star.frame.GlobalEventBroadcaster" ); |
| |
| if ( xIfc.is() ) |
| { |
| uno::Reference< document::XEventBroadcaster > xBC( |
| xIfc, uno::UNO_QUERY ); |
| |
| OSL_ENSURE( |
| xBC.is(), |
| "com.sun.star.frame.GlobalEventBroadcaster does not implement " |
| "interface com.sun.star.document.XEventBroadcaster!" ); |
| |
| return xBC; |
| } |
| else |
| return uno::Reference< document::XEventBroadcaster >(); |
| } |
| |
| //========================================================================= |
| void OfficeDocumentsManager::buildDocumentsList() |
| { |
| OSL_ENSURE( m_xDocEvtNotifier.is(), |
| "OfficeDocumentsManager::buildDocumentsList - " |
| "No document event notifier!" ); |
| |
| uno::Reference< container::XEnumerationAccess > xEnumAccess( |
| m_xDocEvtNotifier, uno::UNO_QUERY_THROW ); |
| |
| uno::Reference< container::XEnumeration > xEnum |
| = xEnumAccess->createEnumeration(); |
| |
| osl::MutexGuard aGuard( m_aMtx ); |
| |
| while ( xEnum->hasMoreElements() ) |
| { |
| uno::Any aValue = xEnum->nextElement(); |
| // container::NoSuchElementException |
| // lang::WrappedTargetException |
| |
| try |
| { |
| uno::Reference< frame::XModel > xModel; |
| aValue >>= xModel; |
| |
| if ( xModel.is() ) |
| { |
| if ( isOfficeDocument( xModel ) ) |
| { |
| DocumentList::const_iterator it = m_aDocs.begin(); |
| while ( it != m_aDocs.end() ) |
| { |
| if ( (*it).second.xModel == xModel ) |
| { |
| // already known. |
| break; |
| } |
| ++it; |
| } |
| |
| if ( it == m_aDocs.end() ) |
| { |
| // new document |
| rtl::OUString aDocId = getDocumentId( xModel ); |
| rtl::OUString aTitle = DocumentInfo::getDocumentTitle( xModel ); |
| |
| uno::Reference< document::XStorageBasedDocument > |
| xDoc( xModel, uno::UNO_QUERY ); |
| OSL_ENSURE( xDoc.is(), |
| "Got no document::XStorageBasedDocument!" ); |
| |
| uno::Reference< embed::XStorage > xStorage |
| = xDoc->getDocumentStorage(); |
| OSL_ENSURE( xDoc.is(), "Got no document storage!" ); |
| |
| m_aDocs[ aDocId ] |
| = StorageInfo( aTitle, xStorage, xModel ); |
| |
| uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( |
| xModel, uno::UNO_QUERY ); |
| OSL_ENSURE( xCloseBroadcaster.is(), |
| "buildDocumentsList: got no close broadcaster!" ); |
| |
| if ( xCloseBroadcaster.is() ) |
| xCloseBroadcaster->addCloseListener( m_xDocCloseListener ); |
| } |
| } |
| } |
| } |
| catch ( lang::DisposedException const & ) |
| { |
| // Note: Due to race conditions the XEnumeration can |
| // contains docs that already have been closed |
| } |
| } |
| } |
| |
| //========================================================================= |
| uno::Reference< embed::XStorage > |
| OfficeDocumentsManager::queryStorage( const rtl::OUString & rDocId ) |
| { |
| osl::MutexGuard aGuard( m_aMtx ); |
| |
| DocumentList::const_iterator it = m_aDocs.find( rDocId ); |
| if ( it == m_aDocs.end() ) |
| return uno::Reference< embed::XStorage >(); |
| |
| return (*it).second.xStorage; |
| } |
| |
| //========================================================================= |
| rtl::OUString OfficeDocumentsManager::queryDocumentId( |
| const uno::Reference< frame::XModel > & xModel ) |
| { |
| return getDocumentId( xModel ); |
| } |
| |
| //========================================================================= |
| uno::Reference< frame::XModel > |
| OfficeDocumentsManager::queryDocumentModel( const rtl::OUString & rDocId ) |
| { |
| osl::MutexGuard aGuard( m_aMtx ); |
| |
| DocumentList::const_iterator it = m_aDocs.find( rDocId ); |
| if ( it == m_aDocs.end() ) |
| return uno::Reference< frame::XModel >(); |
| |
| return (*it).second.xModel; |
| } |
| |
| //========================================================================= |
| uno::Sequence< rtl::OUString > OfficeDocumentsManager::queryDocuments() |
| { |
| osl::MutexGuard aGuard( m_aMtx ); |
| |
| uno::Sequence< rtl::OUString > aRet( m_aDocs.size() ); |
| sal_Int32 nPos = 0; |
| |
| DocumentList::const_iterator it = m_aDocs.begin(); |
| while ( it != m_aDocs.end() ) |
| { |
| aRet[ nPos ] = (*it).first; |
| ++it; |
| ++nPos; |
| } |
| return aRet; |
| } |
| |
| //========================================================================= |
| rtl::OUString |
| OfficeDocumentsManager::queryStorageTitle( const rtl::OUString & rDocId ) |
| { |
| osl::MutexGuard aGuard( m_aMtx ); |
| |
| DocumentList::const_iterator it = m_aDocs.find( rDocId ); |
| if ( it == m_aDocs.end() ) |
| return rtl::OUString(); |
| |
| return (*it).second.aTitle; |
| } |
| |
| //========================================================================= |
| bool OfficeDocumentsManager::isDocumentPreview( |
| const uno::Reference< frame::XModel > & xModel ) |
| { |
| if ( !xModel.is() ) |
| return false; |
| |
| ::comphelper::NamedValueCollection aArgs( |
| xModel->getArgs() ); |
| sal_Bool bIsPreview = aArgs.getOrDefault( "Preview", sal_False ); |
| return bIsPreview; |
| } |
| |
| //========================================================================= |
| bool OfficeDocumentsManager::isHelpDocument( |
| const uno::Reference< frame::XModel > & xModel ) |
| { |
| if ( !xModel.is() ) |
| return false; |
| |
| ::rtl::OUString sURL( xModel->getURL() ); |
| if ( sURL.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.help://" ) ) ) |
| return true; |
| |
| return false; |
| } |
| |
| //========================================================================= |
| bool OfficeDocumentsManager::isWithoutOrInTopLevelFrame( |
| const uno::Reference< frame::XModel > & xModel ) |
| { |
| if ( !xModel.is() ) |
| return false; |
| |
| uno::Reference< frame::XController > xController |
| = xModel->getCurrentController(); |
| if ( xController.is() ) |
| { |
| uno::Reference< frame::XFrame > xFrame |
| = xController->getFrame(); |
| if ( xFrame.is() ) |
| { |
| // don't use XFrame::isTop here. This nowadays excludes |
| // "sub documents" such as forms embedded in database documents |
| uno::Reference< awt::XTopWindow > xFrameContainer( |
| xFrame->getContainerWindow(), uno::UNO_QUERY ); |
| if ( !xFrameContainer.is() ) |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| //========================================================================= |
| bool OfficeDocumentsManager::isBasicIDE( |
| const uno::Reference< frame::XModel > & xModel ) |
| { |
| if ( !m_xModuleMgr.is() ) |
| { |
| osl::MutexGuard aGuard( m_aMtx ); |
| if ( !m_xModuleMgr.is() ) |
| { |
| try |
| { |
| m_xModuleMgr |
| = uno::Reference< |
| frame::XModuleManager >( |
| m_xSMgr->createInstance( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.frame.ModuleManager" ) ) ), |
| uno::UNO_QUERY ); |
| } |
| catch ( uno::Exception const & ) |
| { |
| // handled below. |
| } |
| |
| OSL_ENSURE( m_xModuleMgr .is(), |
| "Could not instanciate ModuleManager service!" ); |
| } |
| } |
| |
| if ( m_xModuleMgr.is() ) |
| { |
| rtl::OUString aModule; |
| try |
| { |
| aModule = m_xModuleMgr->identify( xModel ); |
| } |
| catch ( lang::IllegalArgumentException const & ) |
| { |
| OSL_ENSURE( false, "Caught IllegalArgumentException!" ); |
| } |
| catch ( frame::UnknownModuleException const & ) |
| { |
| OSL_ENSURE( false, "Caught UnknownModuleException!" ); |
| } |
| |
| if ( aModule.getLength() > 0 ) |
| { |
| // Filter unwanted items, that are no real documents. |
| if ( aModule.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( |
| "com.sun.star.script.BasicIDE" ) ) ) |
| { |
| return true; |
| } |
| } |
| } |
| |
| return false; |
| } |
| |
| //========================================================================= |
| bool OfficeDocumentsManager::isOfficeDocument( |
| const uno::Reference< uno::XInterface > & xDoc ) |
| { |
| uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY ); |
| uno::Reference< document::XStorageBasedDocument > |
| xStorageBasedDoc( xModel, uno::UNO_QUERY ); |
| if ( !xStorageBasedDoc.is() ) |
| return false; |
| |
| if ( !isWithoutOrInTopLevelFrame( xModel ) ) |
| return false; |
| |
| if ( isDocumentPreview( xModel ) ) |
| return false; |
| |
| if ( isHelpDocument( xModel ) ) |
| return false; |
| |
| if ( isBasicIDE( xModel ) ) |
| return false; |
| |
| return true; |
| } |