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