LCOV - code coverage report
Current view: top level - ucb/source/ucp/tdoc - tdoc_docmgr.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 203 249 81.5 %
Date: 2012-08-25 Functions: 19 22 86.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 220 460 47.8 %

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

Generated by: LCOV version 1.10