LCOV - code coverage report
Current view: top level - framework/source/dispatch - dispatchprovider.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 115 186 61.8 %
Date: 2012-08-25 Functions: 12 16 75.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 197 630 31.3 %

           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                 :            : #include <stdio.h>
      30                 :            : #include <dispatch/dispatchprovider.hxx>
      31                 :            : #include <loadenv/loadenv.hxx>
      32                 :            : #include <dispatch/loaddispatcher.hxx>
      33                 :            : #include <dispatch/closedispatcher.hxx>
      34                 :            : #include <dispatch/menudispatcher.hxx>
      35                 :            : #include <dispatch/startmoduledispatcher.hxx>
      36                 :            : 
      37                 :            : #include <pattern/window.hxx>
      38                 :            : #include <threadhelp/transactionguard.hxx>
      39                 :            : #include <threadhelp/readguard.hxx>
      40                 :            : #include <threadhelp/writeguard.hxx>
      41                 :            : #include <dispatchcommands.h>
      42                 :            : #include <protocols.h>
      43                 :            : #include <services.h>
      44                 :            : #include <targets.h>
      45                 :            : #include <general.h>
      46                 :            : 
      47                 :            : #include <com/sun/star/frame/FrameSearchFlag.hpp>
      48                 :            : #include <com/sun/star/uno/Exception.hpp>
      49                 :            : #include <com/sun/star/ucb/XContentProviderManager.hpp>
      50                 :            : #include <com/sun/star/document/XTypeDetection.hpp>
      51                 :            : #include <com/sun/star/lang/XInitialization.hpp>
      52                 :            : 
      53                 :            : #include <osl/diagnose.h>
      54                 :            : #include <rtl/string.h>
      55                 :            : #include <rtl/ustring.hxx>
      56                 :            : #include <vcl/svapp.hxx>
      57                 :            : #include <rtl/ustrbuf.hxx>
      58                 :            : 
      59                 :            : namespace framework{
      60                 :            : 
      61                 :            : //*****************************************************************************************************************
      62                 :            : //  XInterface, XTypeProvider
      63                 :            : //*****************************************************************************************************************
      64 [ +  + ][ +  - ]:      71773 : DEFINE_XINTERFACE_2( DispatchProvider                               ,
      65                 :            :                      OWeakObject                                    ,
      66                 :            :                      DIRECT_INTERFACE(css::lang::XTypeProvider     ),
      67                 :            :                      DIRECT_INTERFACE(css::frame::XDispatchProvider)
      68                 :            :                    )
      69                 :            : 
      70 [ #  # ][ #  # ]:          0 : DEFINE_XTYPEPROVIDER_2( DispatchProvider             ,
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      71                 :            :                         css::lang::XTypeProvider     ,
      72                 :            :                         css::frame::XDispatchProvider
      73                 :            :                       )
      74                 :            : 
      75                 :            : /**
      76                 :            :     @short      standard ctor/dtor
      77                 :            :     @descr      These initialize a new instance of tihs class with needed informations for work.
      78                 :            :                 We hold a weakreference to our owner frame which start dispatches at us.
      79                 :            :                 We can't use a normal reference because he hold a reference of us too ...
      80                 :            :                 nobody can die so ...!
      81                 :            : 
      82                 :            :     @seealso    using at owner
      83                 :            : 
      84                 :            :     @param      xFactory
      85                 :            :                     reference to servicemanager to create new services.
      86                 :            :     @param      xFrame
      87                 :            :                     reference to our owner frame.
      88                 :            : */
      89                 :       1983 : DispatchProvider::DispatchProvider( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory  ,
      90                 :            :                                     const css::uno::Reference< css::frame::XFrame >&              xFrame    )
      91                 :            :         //  Init baseclasses first
      92         [ +  - ]:       1983 :         : ThreadHelpBase( &Application::GetSolarMutex() )
      93                 :            :         , OWeakObject   (                               )
      94                 :            :         // Init member
      95                 :            :         , m_xFactory    ( xFactory                      )
      96 [ +  - ][ +  - ]:       3966 :         , m_xFrame      ( xFrame                        )
         [ +  - ][ +  - ]
      97                 :            : {
      98                 :       1983 : }
      99                 :            : 
     100                 :            : /**
     101                 :            :     @short      protected(!) dtor for deinitializing
     102                 :            :     @descr      We made it protected to prevent using of us as base class instead as a member.
     103                 :            :  */
     104 [ +  - ][ +  - ]:       1892 : DispatchProvider::~DispatchProvider()
         [ +  - ][ +  - ]
                 [ +  - ]
     105                 :            : {
     106         [ -  + ]:       3784 : }
     107                 :            : 
     108                 :            : /**
     109                 :            :     @interface  XDispatchProvider
     110                 :            :     @short      search a dispatcher for given URL
     111                 :            :     @descr      If no interceptor is set on owner, we search for right frame and dispatch URL to it.
     112                 :            :                 If no frame was found, we do nothing.
     113                 :            :                 But we doesn't do it directly here. We detect the type of our owner frame and calls
     114                 :            :                 specialized queryDispatch() helper dependen from that. Because a Desktop handle some
     115                 :            :                 requests in another way then a normal frame.
     116                 :            : 
     117                 :            :     @param      aURL
     118                 :            :                     URL to dispatch.
     119                 :            :     @param      sTargetFrameName
     120                 :            :                     name of searched frame.
     121                 :            :     @param      nSearchFlags
     122                 :            :                     flags for searching.
     123                 :            :     @return     A reference to a dispatch object for this URL (if someone was found!).
     124                 :            : 
     125                 :            :     @threadsafe yes
     126                 :            : */
     127                 :     205657 : css::uno::Reference< css::frame::XDispatch > SAL_CALL DispatchProvider::queryDispatch( const css::util::URL&  aURL             ,
     128                 :            :                                                                                        const ::rtl::OUString& sTargetFrameName ,
     129                 :            :                                                                                              sal_Int32        nSearchFlags     ) throw( css::uno::RuntimeException )
     130                 :            : {
     131                 :     205657 :     css::uno::Reference< css::frame::XDispatch > xDispatcher;
     132                 :            : 
     133                 :            :     /* SAFE { */
     134         [ +  - ]:     205657 :     ReadGuard aReadLock( m_aLock );
     135 [ +  - ][ +  - ]:     205657 :     css::uno::Reference< css::frame::XFrame > xOwner( m_xFrame.get(), css::uno::UNO_QUERY );
     136         [ +  - ]:     205657 :     aReadLock.unlock();
     137                 :            :     /* } SAFE */
     138                 :            : 
     139         [ +  - ]:     205657 :     css::uno::Reference< css::frame::XDesktop > xDesktopCheck( xOwner, css::uno::UNO_QUERY );
     140                 :            : 
     141         [ +  + ]:     205657 :     if (xDesktopCheck.is())
     142 [ +  - ][ +  - ]:        294 :         xDispatcher = implts_queryDesktopDispatch(xOwner, aURL, sTargetFrameName, nSearchFlags);
     143                 :            :     else
     144 [ +  - ][ +  - ]:     205363 :         xDispatcher = implts_queryFrameDispatch(xOwner, aURL, sTargetFrameName, nSearchFlags);
     145                 :            : 
     146         [ +  - ]:     205657 :     return xDispatcher;
     147                 :            : }
     148                 :            : 
     149                 :            : /**
     150                 :            :     @interface  XDispatchProvider
     151                 :            :     @short      do the same like queryDispatch() ... but handle multiple dispatches at the same time
     152                 :            :     @descr      It's an optimism. User give us a list of queries ... and we return a list of dispatcher.
     153                 :            :                 If one of given queries couldn't be solved to a real existing dispatcher ...
     154                 :            :                 we return a list with empty references in it! Order of both lists will be retained!
     155                 :            : 
     156                 :            :     @seealso    method queryDispatch()
     157                 :            : 
     158                 :            :     @param      lDescriptions
     159                 :            :                     a list of all dispatch parameters for multiple requests
     160                 :            :     @return     A reference a list of dispatch objects for these URLs - may with some <NULL/> values inside.
     161                 :            : 
     162                 :            :     @threadsafe yes
     163                 :            : */
     164                 :          0 : css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL DispatchProvider::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptions ) throw( css::uno::RuntimeException )
     165                 :            : {
     166                 :            :     // Create return list - which must have same size then the given descriptor
     167                 :            :     // It's not allowed to pack it!
     168                 :          0 :     sal_Int32                                                          nCount     = lDescriptions.getLength();
     169                 :          0 :     css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatcher( nCount );
     170                 :            : 
     171                 :            :     // Step over all descriptors and try to get any dispatcher for it.
     172         [ #  # ]:          0 :     for( sal_Int32 i=0; i<nCount; ++i )
     173                 :            :     {
     174         [ #  # ]:          0 :         lDispatcher[i] = queryDispatch( lDescriptions[i].FeatureURL  ,
     175                 :          0 :                                         lDescriptions[i].FrameName   ,
     176 [ #  # ][ #  # ]:          0 :                                         lDescriptions[i].SearchFlags );
     177                 :            :     }
     178                 :            : 
     179                 :          0 :     return lDispatcher;
     180                 :            : }
     181                 :            : 
     182                 :          0 : ::sal_Bool lcl_isStartModuleDispatch (const css::util::URL& aURL)
     183                 :            : {
     184                 :          0 :     return aURL.Complete == CMD_UNO_SHOWSTARTMODULE;
     185                 :            : }
     186                 :            : 
     187                 :            : /**
     188                 :            :     @short      helper for queryDispatch()
     189                 :            :     @descr      Every member of the frame tree (frame, desktop) must handle such request
     190                 :            :                 in another way. So we implement different specialized metods for every one.
     191                 :            : 
     192                 :            :     @threadsafe yes
     193                 :            :  */
     194                 :        294 : css::uno::Reference< css::frame::XDispatch > DispatchProvider::implts_queryDesktopDispatch( const css::uno::Reference< css::frame::XFrame > xDesktop         ,
     195                 :            :                                                                                             const css::util::URL&                           aURL             ,
     196                 :            :                                                                                             const ::rtl::OUString&                          sTargetFrameName ,
     197                 :            :                                                                                                   sal_Int32                                 nSearchFlags     )
     198                 :            : {
     199                 :        294 :     css::uno::Reference< css::frame::XDispatch > xDispatcher;
     200                 :            : 
     201                 :            :     // ignore wrong requests which are not supported
     202 [ -  + ][ +  -  :       1176 :     if (
             +  -  -  + ]
     203 [ +  - ][ #  # ]:        588 :         (sTargetFrameName==SPECIALTARGET_MENUBAR  )   ||    // valid for frame dispatches - not for desktop
                 [ +  - ]
     204 [ +  - ][ +  - ]:        588 :         (sTargetFrameName==SPECIALTARGET_PARENT   )   ||    // we have no parent by definition
                 [ #  # ]
     205 [ +  - ][ +  - ]:        588 :         (sTargetFrameName==SPECIALTARGET_BEAMER   )         // beamer frames are allowed as child of tasks only -
                 [ #  # ]
     206                 :            :                                                             // and they exist more then ones. We have no idea which our sub tasks is the right one
     207                 :            :        )
     208                 :            :     {
     209         [ #  # ]:          0 :         return NULL;
     210                 :            :     }
     211                 :            : 
     212                 :            :     //-----------------------------------------------------------------------------------------------------
     213                 :            :     // I) handle special cases which not right for using findFrame() first
     214                 :            :     //-----------------------------------------------------------------------------------------------------
     215                 :            : 
     216                 :            :     //-----------------------------------------------------------------------------------------------------
     217                 :            :     // I.I) "_blank"
     218                 :            :     //  It's not the right place to create a new task here - because we are queried for a dispatch object
     219                 :            :     //  only, which can handle such request. Such dispatcher should create the required task on demand.
     220                 :            :     //  Normaly the functionality for "_blank" is provided by findFrame() - but that would create it directly
     221                 :            :     //  here. Thats why we must "intercept" here.
     222                 :            :     //-----------------------------------------------------------------------------------------------------
     223 [ +  - ][ -  + ]:        294 :     if (sTargetFrameName==SPECIALTARGET_BLANK)
     224                 :            :     {
     225 [ #  # ][ #  # ]:          0 :         if (implts_isLoadableContent(aURL))
     226 [ #  # ][ #  # ]:          0 :             xDispatcher = implts_getOrCreateDispatchHelper( E_BLANKDISPATCHER, xDesktop );
     227                 :            :     }
     228                 :            : 
     229                 :            :     //-----------------------------------------------------------------------------------------------------
     230                 :            :     // I.II) "_default"
     231                 :            :     //  This is a combination of search an empty task for recycling - or create a new one.
     232                 :            :     //-----------------------------------------------------------------------------------------------------
     233                 :            :     else
     234 [ +  - ][ -  + ]:        294 :     if (sTargetFrameName==SPECIALTARGET_DEFAULT)
     235                 :            :     {
     236 [ #  # ][ #  # ]:          0 :         if (implts_isLoadableContent(aURL))
     237 [ #  # ][ #  # ]:          0 :             xDispatcher = implts_getOrCreateDispatchHelper( E_DEFAULTDISPATCHER, xDesktop );
     238                 :            : 
     239 [ #  # ][ #  # ]:          0 :         if (lcl_isStartModuleDispatch(aURL))
     240 [ #  # ][ #  # ]:          0 :             xDispatcher = implts_getOrCreateDispatchHelper( E_STARTMODULEDISPATCHER, xDesktop );
     241                 :            :     }
     242                 :            : 
     243                 :            :     //-----------------------------------------------------------------------------------------------------
     244                 :            :     // I.III) "_self", "", "_top"
     245                 :            :     //  The desktop can't load any document - but he can handle some special protocols like "uno", "slot" ...
     246                 :            :     //  Why is "top" here handled too? Because the desktop is the topest frame. Normaly it's superflous
     247                 :            :     //  to use this target - but we can handle it in the same manner then "_self".
     248                 :            :     //-----------------------------------------------------------------------------------------------------
     249                 :            :     else
     250 [ +  - ][ +  +  :        592 :     if (
             -  +  #  # ]
     251 [ +  - ][ +  - ]:        588 :         (sTargetFrameName==SPECIALTARGET_SELF)  ||
                 [ #  # ]
     252 [ +  - ][ +  + ]:        298 :         (sTargetFrameName==SPECIALTARGET_TOP )  ||
                 [ #  # ]
     253                 :          0 :         (sTargetFrameName.isEmpty())
     254                 :            :        )
     255                 :            :     {
     256 [ +  - ][ +  - ]:        294 :         xDispatcher = implts_searchProtocolHandler(aURL);
     257                 :            :     }
     258                 :            : 
     259                 :            :     //-----------------------------------------------------------------------------------------------------
     260                 :            :     // I.IV) no further special targets exist
     261                 :            :     //  Now we have to search for the right target frame by calling findFrame() - but should provide our code
     262                 :            :     //  against creation of a new task if no frame could be found.
     263                 :            :     //  I said it b efore - it's allowed for dispatch() only.
     264                 :            :     //-----------------------------------------------------------------------------------------------------
     265                 :            :     else
     266                 :            :     {
     267                 :          0 :         sal_Int32 nRightFlags  = nSearchFlags;
     268                 :          0 :                   nRightFlags &= ~css::frame::FrameSearchFlag::CREATE;
     269                 :            : 
     270                 :            :         // try to find any existing target and ask him for his dispatcher
     271 [ #  # ][ #  # ]:          0 :         css::uno::Reference< css::frame::XFrame > xFoundFrame = xDesktop->findFrame(sTargetFrameName, nRightFlags);
     272         [ #  # ]:          0 :         if (xFoundFrame.is())
     273                 :            :         {
     274         [ #  # ]:          0 :             css::uno::Reference< css::frame::XDispatchProvider > xProvider( xFoundFrame, css::uno::UNO_QUERY );
     275 [ #  # ][ #  # ]:          0 :             xDispatcher = xProvider->queryDispatch(aURL,SPECIALTARGET_SELF,0);
         [ #  # ][ #  # ]
     276                 :            :         }
     277                 :            :         else
     278                 :            :         // if it couldn't be found - but creation was allowed
     279                 :            :         // use special dispatcher for creatio or froward it to the browser
     280         [ #  # ]:          0 :         if (nSearchFlags & css::frame::FrameSearchFlag::CREATE)
     281 [ #  # ][ #  # ]:          0 :             xDispatcher = implts_getOrCreateDispatchHelper( E_CREATEDISPATCHER, xDesktop, sTargetFrameName, nSearchFlags );
     282                 :            :     }
     283                 :            : 
     284                 :        294 :     return xDispatcher;
     285                 :            : }
     286                 :            : 
     287                 :            : //_________________________________________________________________________________________________________________
     288                 :            : 
     289                 :     205363 : css::uno::Reference< css::frame::XDispatch > DispatchProvider::implts_queryFrameDispatch( const css::uno::Reference< css::frame::XFrame > xFrame           ,
     290                 :            :                                                                                           const css::util::URL&                           aURL             ,
     291                 :            :                                                                                           const ::rtl::OUString&                          sTargetFrameName ,
     292                 :            :                                                                                                 sal_Int32                                 nSearchFlags     )
     293                 :            : {
     294                 :     205363 :     css::uno::Reference< css::frame::XDispatch > xDispatcher;
     295                 :            : 
     296                 :            :     //-----------------------------------------------------------------------------------------------------
     297                 :            :     // 0) Some URLs are dispatched in a generic way (e.g. by the menu) using the default target "".
     298                 :            :     //    But they are specified to use her own fix target. Detect such URLs here and use the correct target.
     299                 :            :     //-----------------------------------------------------------------------------------------------------
     300                 :            : 
     301                 :     205363 :     ::rtl::OUString sTargetName = sTargetFrameName;
     302                 :            : 
     303                 :            :     //-----------------------------------------------------------------------------------------------------
     304                 :            :     // I) handle special cases which not right for using findFrame() first
     305                 :            :     //-----------------------------------------------------------------------------------------------------
     306                 :            : 
     307                 :            :     //-----------------------------------------------------------------------------------------------------
     308                 :            :     // I.I) "_blank", "_default"
     309                 :            :     //  It's not the right place to create a new task here. Only the desktop can do that.
     310                 :            :     //  Normaly the functionality for "_blank" is provided by findFrame() - but that would create it directly
     311                 :            :     //  here. Thats why we must "intercept" here.
     312                 :            :     //-----------------------------------------------------------------------------------------------------
     313         [ -  + ]:     616089 :     if (
           [ +  -  -  + ]
     314 [ +  - ][ #  # ]:     410726 :         (sTargetName==SPECIALTARGET_BLANK  ) ||
                 [ +  - ]
     315 [ +  - ][ +  - ]:     410726 :         (sTargetName==SPECIALTARGET_DEFAULT)
                 [ #  # ]
     316                 :            :        )
     317                 :            :     {
     318 [ #  # ][ #  # ]:          0 :         css::uno::Reference< css::frame::XDispatchProvider > xParent( xFrame->getCreator(), css::uno::UNO_QUERY );
                 [ #  # ]
     319         [ #  # ]:          0 :         if (xParent.is())
     320 [ #  # ][ #  # ]:          0 :             xDispatcher = xParent->queryDispatch(aURL, sTargetName, 0); // its a special target - ignore search flags
                 [ #  # ]
     321                 :            :     }
     322                 :            : 
     323                 :            :     //-----------------------------------------------------------------------------------------------------
     324                 :            :     // I.II) "_menubar"
     325                 :            :     //  Special mode on frame or task to receive the local menu. Not supported by findFrame()
     326                 :            :     //-----------------------------------------------------------------------------------------------------
     327                 :            :     else
     328 [ +  - ][ +  + ]:     205363 :     if (sTargetName==SPECIALTARGET_MENUBAR)
     329                 :            :     {
     330 [ +  - ][ +  - ]:          2 :         xDispatcher = implts_getOrCreateDispatchHelper( E_MENUDISPATCHER, xFrame );
     331                 :            :     }
     332                 :            : 
     333                 :            :     //-----------------------------------------------------------------------------------------------------
     334                 :            :     // I.IV) "_helpagent"
     335                 :            :     //  Special sub frame of a top frame only. Search or create it. ... OK it's currently a little bit HACKI.
     336                 :            :     //  Only the sfx (means the controller) can create it it.
     337                 :            :     //-----------------------------------------------------------------------------------------------------
     338                 :            :     else
     339 [ +  - ][ +  + ]:     205361 :     if (sTargetName==SPECIALTARGET_BEAMER)
     340                 :            :     {
     341 [ +  - ][ +  - ]:          4 :         css::uno::Reference< css::frame::XDispatchProvider > xBeamer( xFrame->findFrame( SPECIALTARGET_BEAMER, css::frame::FrameSearchFlag::CHILDREN | css::frame::FrameSearchFlag::SELF ), css::uno::UNO_QUERY );
         [ +  - ][ +  - ]
     342         [ +  + ]:          4 :         if (xBeamer.is())
     343                 :            :         {
     344 [ +  - ][ +  - ]:          2 :             xDispatcher = xBeamer->queryDispatch(aURL, SPECIALTARGET_SELF, 0);
         [ +  - ][ +  - ]
     345                 :            :         }
     346                 :            :         else
     347                 :            :         {
     348 [ +  - ][ +  - ]:          2 :             css::uno::Reference< css::frame::XDispatchProvider > xController( xFrame->getController(), css::uno::UNO_QUERY );
                 [ +  - ]
     349         [ +  - ]:          2 :             if (xController.is())
     350                 :            :                 // force using of special target - but use original search flags
     351                 :            :                 // May the caller used the CREATE flag or not!
     352 [ +  - ][ +  - ]:          2 :                 xDispatcher = xController->queryDispatch(aURL, SPECIALTARGET_BEAMER, nSearchFlags);
         [ +  - ][ +  - ]
     353                 :          4 :         }
     354                 :            :     }
     355                 :            : 
     356                 :            :     //-----------------------------------------------------------------------------------------------------
     357                 :            :     // I.V) "_parent"
     358                 :            :     //  Our parent frame (if it exist) should handle this URL.
     359                 :            :     //-----------------------------------------------------------------------------------------------------
     360                 :            :     else
     361 [ +  - ][ +  + ]:     205357 :     if (sTargetName==SPECIALTARGET_PARENT)
     362                 :            :     {
     363 [ +  - ][ +  - ]:          8 :         css::uno::Reference< css::frame::XDispatchProvider > xParent( xFrame->getCreator(), css::uno::UNO_QUERY );
                 [ +  - ]
     364         [ +  - ]:          8 :         if (xParent.is())
     365                 :            :             // SELF => we must address the parent directly... and not his parent or any other parent!
     366 [ +  - ][ +  - ]:          8 :             xDispatcher = xParent->queryDispatch(aURL, SPECIALTARGET_SELF, 0);
         [ +  - ][ +  - ]
     367                 :            :     }
     368                 :            : 
     369                 :            :     //-----------------------------------------------------------------------------------------------------
     370                 :            :     // I.VI) "_top"
     371                 :            :     //  This request must be forwarded to any parent frame, till we reach a top frame.
     372                 :            :     //  If no parent exist, we can handle itself.
     373                 :            :     //-----------------------------------------------------------------------------------------------------
     374                 :            :     else
     375 [ +  - ][ -  + ]:     205349 :     if (sTargetName==SPECIALTARGET_TOP)
     376                 :            :     {
     377 [ #  # ][ #  # ]:          0 :         if (xFrame->isTop())
                 [ #  # ]
     378                 :            :         {
     379                 :            :             // If we are this top frame itself (means our owner frame)
     380                 :            :             // we should call ourself recursiv with a better target "_self".
     381                 :            :             // So we can share the same code! (see reaction for "_self" inside this method too.)
     382 [ #  # ][ #  # ]:          0 :             xDispatcher = this->queryDispatch(aURL,SPECIALTARGET_SELF,0);
                 [ #  # ]
     383                 :            :         }
     384                 :            :         else
     385                 :            :         {
     386 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::frame::XDispatchProvider > xParent( xFrame->getCreator(), css::uno::UNO_QUERY );
                 [ #  # ]
     387                 :            :             // Normaly if isTop() returned sal_False ... the parent frame MUST(!) exist ...
     388                 :            :             // But it seams to be better to check that here to prevent us against an access violation.
     389         [ #  # ]:          0 :             if (xParent.is())
     390 [ #  # ][ #  # ]:          0 :                 xDispatcher = xParent->queryDispatch(aURL, SPECIALTARGET_TOP, 0);
         [ #  # ][ #  # ]
     391                 :            :         }
     392                 :            :     }
     393                 :            : 
     394                 :            :     //-----------------------------------------------------------------------------------------------------
     395                 :            :     // I.VII) "_self", ""
     396                 :            :     //  Our owner frame should handle this URL. But we can't do it for all of them.
     397                 :            :     //  So we ask the internal setted controller first. If he disagree we try to find a registered
     398                 :            :     //  protocol handler. If this failed too - we check for a loadable content and in case of true
     399                 :            :     //  we load it into the frame by returning specilized dispatch object.
     400                 :            :     //-----------------------------------------------------------------------------------------------------
     401                 :            :     else
     402         [ +  - ]:     616023 :     if (
           [ +  +  +  - ]
     403 [ +  - ][ +  - ]:     410698 :         (sTargetName==SPECIALTARGET_SELF)  ||
                 [ #  # ]
     404                 :     205325 :         (sTargetName.isEmpty())
     405                 :            :        )
     406                 :            :     {
     407                 :            :         // There exist a hard coded interception for special URLs.
     408 [ +  - ][ +  + ]:     205349 :         if ( aURL.Complete == ".uno:CloseDoc" || aURL.Complete == ".uno:CloseWin" )
                 [ +  + ]
     409                 :            :         {
     410 [ +  - ][ +  - ]:          2 :             css::uno::Reference< css::frame::XDispatchProvider > xParent( xFrame->getCreator(), css::uno::UNO_QUERY );
                 [ +  - ]
     411                 :            :             // In case the frame is not a top one, is not based on system window and has a parent,
     412                 :            :             // the parent frame should to be queried for the correct dispatcher.
     413                 :            :             // See i93473
     414         [ -  + ]:          4 :             if (
           [ #  #  #  # ]
                 [ -  + ]
     415 [ +  - ][ +  - ]:          4 :                 !WindowHelper::isTopWindow(xFrame->getContainerWindow()) &&
         [ +  - ][ #  # ]
                 [ +  - ]
     416 [ #  # ][ #  # ]:          2 :                 !VCLUnoHelper::GetWindow(xFrame->getContainerWindow())->IsSystemWindow() &&
         [ #  # ][ #  # ]
         [ -  + ][ #  # ]
     417                 :          0 :                 xParent.is()
     418                 :            :                )
     419 [ #  # ][ #  # ]:          0 :                 xDispatcher = xParent->queryDispatch(aURL, SPECIALTARGET_SELF, 0);
         [ #  # ][ #  # ]
     420                 :            :             else
     421 [ +  - ][ +  - ]:          2 :                 xDispatcher = implts_getOrCreateDispatchHelper( E_CLOSEDISPATCHER, xFrame );
     422                 :            :         }
     423         [ -  + ]:     205347 :         else if ( aURL.Complete == ".uno:CloseFrame" )
     424 [ #  # ][ #  # ]:          0 :             xDispatcher = implts_getOrCreateDispatchHelper( E_CLOSEDISPATCHER, xFrame );
     425                 :            : 
     426         [ +  + ]:     205349 :         if ( ! xDispatcher.is())
     427                 :            :         {
     428                 :            :             // Ask our controller for his agreement for these dispatched URL ...
     429                 :            :             // because some URLs are internal and can be handled faster by SFX - which most is the current controller!
     430                 :            :             // But in case of e.g. the bibliography not all queries will be handled successfully here.
     431 [ +  - ][ +  - ]:     205347 :             css::uno::Reference< css::frame::XDispatchProvider > xController( xFrame->getController(), css::uno::UNO_QUERY );
                 [ +  - ]
     432         [ +  + ]:     205347 :             if (xController.is())
     433 [ +  - ][ +  - ]:     205347 :                 xDispatcher = xController->queryDispatch(aURL, SPECIALTARGET_SELF, 0);
         [ +  - ][ +  - ]
     434                 :            :         }
     435                 :            : 
     436                 :            :         // If controller has no fun to dispatch these URL - we must search another right dispatcher.
     437                 :            :         // Search for any registered protocol handler first.
     438         [ +  + ]:     205349 :         if (!xDispatcher.is())
     439 [ +  - ][ +  - ]:       3488 :             xDispatcher = implts_searchProtocolHandler(aURL);
     440                 :            : 
     441                 :            :         // Not for controller - not for protocol handler
     442                 :            :         // It should be a loadable content - may be a file. Check it ...
     443                 :            :         // This check is neccessary to found out, that
     444                 :            :         // support for some protocols isn't installed by user. May be
     445                 :            :         // "ftp" isn't available. So we suppress creation of our self dispatcher.
     446                 :            :         // The result will be clear. He can't handle it - but he would try it.
     447 [ +  + ][ +  + ]:     208825 :         if (
                 [ +  + ]
     448                 :     205349 :             ( ! xDispatcher.is()             )  &&
     449         [ +  - ]:       3476 :             ( implts_isLoadableContent(aURL) )
     450                 :            :            )
     451                 :            :         {
     452 [ +  - ][ +  - ]:          2 :             xDispatcher = implts_getOrCreateDispatchHelper( E_SELFDISPATCHER, xFrame );
     453                 :            :         }
     454                 :            :     }
     455                 :            : 
     456                 :            :     //-----------------------------------------------------------------------------------------------------
     457                 :            :     // I.VI) no further special handlings exist
     458                 :            :     //  Now we have to search for the right target frame by calling findFrame() - but should provide our code
     459                 :            :     //  against creation of a new task if no frame could be found.
     460                 :            :     //  I said it before - it's allowed for dispatch() only.
     461                 :            :     //-----------------------------------------------------------------------------------------------------
     462                 :            :     else
     463                 :            :     {
     464                 :          0 :         sal_Int32 nRightFlags  = nSearchFlags;
     465                 :          0 :                   nRightFlags &= ~css::frame::FrameSearchFlag::CREATE;
     466                 :            : 
     467                 :            :         // try to find any existing target and ask him for his dispatcher
     468 [ #  # ][ #  # ]:          0 :         css::uno::Reference< css::frame::XFrame > xFoundFrame = xFrame->findFrame(sTargetName, nRightFlags);
     469         [ #  # ]:          0 :         if (xFoundFrame.is())
     470                 :            :         {
     471                 :            :             // Attention: Found target is our own owner frame!
     472                 :            :             // Don't ask him for his dispatcher. We know it already - it's our self dispatch helper.
     473                 :            :             // Otherwhise we can start a never ending recursiv call. Why?
     474                 :            :             // Somewere called our owner frame - he called some interceptor objects - and may by this dispatch provider
     475                 :            :             // is called. If wa use queryDispatch() on our owner frame again - we start this call stack again ... and again.
     476 [ #  # ][ #  # ]:          0 :             if (xFoundFrame==xFrame)
     477 [ #  # ][ #  # ]:          0 :                 xDispatcher = implts_getOrCreateDispatchHelper( E_SELFDISPATCHER, xFrame );
     478                 :            :             else
     479                 :            :             {
     480         [ #  # ]:          0 :                 css::uno::Reference< css::frame::XDispatchProvider > xProvider( xFoundFrame, css::uno::UNO_QUERY );
     481 [ #  # ][ #  # ]:          0 :                 xDispatcher = xProvider->queryDispatch(aURL,SPECIALTARGET_SELF,0);
         [ #  # ][ #  # ]
     482                 :            :             }
     483                 :            :         }
     484                 :            :         else
     485                 :            :         // if it couldn't be found - but creation was allowed
     486                 :            :         // forward request to the desktop.
     487                 :            :         // Note: The given target name must be used to set the name on new created task!
     488                 :            :         //       Don't forward request by changing it to a special one e.g _blank.
     489                 :            :         //       Use the CREATE flag only to prevent call against further searches.
     490                 :            :         //       We already know it - the target must be created new.
     491         [ #  # ]:          0 :         if (nSearchFlags & css::frame::FrameSearchFlag::CREATE)
     492                 :            :         {
     493 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::frame::XDispatchProvider > xParent( xFrame->getCreator(), css::uno::UNO_QUERY );
                 [ #  # ]
     494         [ #  # ]:          0 :             if (xParent.is())
     495 [ #  # ][ #  # ]:          0 :                 xDispatcher = xParent->queryDispatch(aURL, sTargetName, css::frame::FrameSearchFlag::CREATE);
                 [ #  # ]
     496                 :          0 :         }
     497                 :            :     }
     498                 :            : 
     499                 :     205363 :     return xDispatcher;
     500                 :            : }
     501                 :            : 
     502                 :            : //_________________________________________________________________________________________________________________
     503                 :            : 
     504                 :            : /**
     505                 :            :     @short      search for a registered protocol handler and ask him for a dispatch object
     506                 :            :     @descr      Wes earch a suitable handler inside our cfg package org.openoffice.Office.ProtocolHandler.
     507                 :            :                 If we found anyone, we create and initialize it. Initialize means: we set our owner frame on it
     508                 :            :                 as context information. He can use it or leave it. Of course - we are aware of handler implementations,
     509                 :            :                 which doesn't support initialization. It's an optional feature.
     510                 :            : 
     511                 :            :     @param      aURL
     512                 :            :                     the dispatch URL for which may a handler is registered
     513                 :            : 
     514                 :            :     @return     A dispatch object if a handler was found and agree with the given URL or <NULL/> otherwhise.
     515                 :            : 
     516                 :            :     @threadsafe yes
     517                 :            : */
     518                 :       3782 : css::uno::Reference< css::frame::XDispatch > DispatchProvider::implts_searchProtocolHandler( const css::util::URL& aURL )
     519                 :            : {
     520                 :       3782 :     css::uno::Reference< css::frame::XDispatch > xDispatcher;
     521         [ +  - ]:       3782 :     ProtocolHandler                              aHandler   ;
     522                 :            : 
     523                 :            :     // This member is threadsafe by himself and lives if we live - we doesn't need any mutex here.
     524 [ +  - ][ +  + ]:       3782 :     if (m_aProtocolHandlerCache.search(aURL,&aHandler))
     525                 :            :     {
     526                 :            :         /* SAFE { */
     527         [ +  - ]:       3780 :         ReadGuard aReadLock( m_aLock );
     528                 :            : 
     529                 :            :         // create it
     530                 :       3780 :         css::uno::Reference< css::frame::XDispatchProvider > xHandler;
     531                 :            :         try
     532                 :            :         {
     533                 :            :             xHandler = css::uno::Reference< css::frame::XDispatchProvider >(
     534         [ +  - ]:       3780 :                             m_xFactory->createInstance(aHandler.m_sUNOName),
     535 [ +  - ][ +  - ]:       3780 :                             css::uno::UNO_QUERY);
         [ +  - ][ #  # ]
     536                 :            :         }
     537         [ #  # ]:          0 :         catch(const css::uno::Exception&) {}
     538                 :            : 
     539                 :            :         // look if initialization is neccessary
     540         [ +  - ]:       3780 :         css::uno::Reference< css::lang::XInitialization > xInit( xHandler, css::uno::UNO_QUERY );
     541         [ +  - ]:       3780 :         if (xInit.is())
     542                 :            :         {
     543 [ +  - ][ +  - ]:       3780 :             css::uno::Reference< css::frame::XFrame > xOwner( m_xFrame.get(), css::uno::UNO_QUERY );
     544                 :            :             LOG_ASSERT(xOwner.is(), "DispatchProvider::implts_searchProtocolHandler()\nCouldn't get reference to my owner frame. So I can't set may needed context information for this protocol handler.")
     545         [ +  - ]:       3780 :             if (xOwner.is())
     546                 :            :             {
     547                 :            :                 try
     548                 :            :                 {
     549                 :            :                     // but do it only, if all context informations are OK
     550         [ +  - ]:       3780 :                     css::uno::Sequence< css::uno::Any > lContext(1);
     551 [ +  - ][ +  - ]:       3780 :                     lContext[0] <<= xOwner;
     552 [ +  - ][ +  - ]:       3780 :                     xInit->initialize(lContext);
         [ +  - ][ #  # ]
     553                 :            :                 }
     554         [ #  # ]:          0 :                 catch(const css::uno::Exception&) {}
     555                 :       3780 :             }
     556                 :            :         }
     557                 :            : 
     558         [ +  - ]:       3780 :         aReadLock.unlock();
     559                 :            :         /* } SAFE */
     560                 :            : 
     561                 :            :         // ask for his (sub)dispatcher for the given URL
     562         [ +  - ]:       3780 :         if (xHandler.is())
     563 [ +  - ][ +  - ]:       3780 :             xDispatcher = xHandler->queryDispatch(aURL,SPECIALTARGET_SELF,0);
         [ +  - ][ +  - ]
                 [ +  - ]
     564                 :            :     }
     565                 :            : 
     566         [ +  - ]:       3782 :     return xDispatcher;
     567                 :            : }
     568                 :            : 
     569                 :            : //_________________________________________________________________________________________________________________
     570                 :            : 
     571                 :            : /**
     572                 :            :     @short      get or create new dispatch helper
     573                 :            :     @descr      Sometimes we need some helper implementations to support dispatching of special URLs or commands.
     574                 :            :                 But it's not a good idea to hold these services for the whole life time of this provider instance.
     575                 :            :                 We should create it on demand ...
     576                 :            :                 Thats why we implement this method. It return an already existing helper or create a new one otherwise.
     577                 :            : 
     578                 :            :     @attention  The parameter sTarget and nSearchFlags are defaulted to "" and 0!
     579                 :            :                 Please use it only, if you can be shure, that the realy given by the outside calli!
     580                 :            :                 Mostly it depends from the parameter eHelper is they are required or not.
     581                 :            : 
     582                 :            :     @param      eHelper
     583                 :            :                     specify the requested dispatch helper
     584                 :            :     @param      xOwner
     585                 :            :                     the target of possible dispatch() call on created dispatch helper
     586                 :            :     @param      sTarget
     587                 :            :                     the target parameter of the original queryDispatch() request
     588                 :            :     @param      nSearchFlags
     589                 :            :                     the flags parameter of the original queryDispatch() request
     590                 :            :     @return     A reference to a dispatch helper.
     591                 :            : 
     592                 :            :     @threadsafe yes
     593                 :            : */
     594                 :          6 : css::uno::Reference< css::frame::XDispatch > DispatchProvider::implts_getOrCreateDispatchHelper( EDispatchHelper                                  eHelper     ,
     595                 :            :                                                                                                  const css::uno::Reference< css::frame::XFrame >& xOwner      ,
     596                 :            :                                                                                                  const ::rtl::OUString&                           sTarget     ,
     597                 :            :                                                                                                        sal_Int32                                  nSearchFlags)
     598                 :            : {
     599                 :          6 :     css::uno::Reference< css::frame::XDispatch > xDispatchHelper;
     600                 :            : 
     601                 :            :     /* SAFE { */
     602         [ +  - ]:          6 :     ReadGuard aReadLock( m_aLock );
     603                 :          6 :     css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory;
     604         [ +  - ]:          6 :     aReadLock.unlock();
     605                 :            :     /* } SAFE */
     606                 :            : 
     607   [ +  -  -  -  :          6 :     switch (eHelper)
             +  +  -  - ]
     608                 :            :     {
     609                 :            :         case E_MENUDISPATCHER :
     610                 :            :                 {
     611                 :            :                     // Attention: Such menue dispatcher must be a singleton for this frame - means our owner frame.
     612                 :            :                     // Otherwhise he can make some trouble.
     613                 :            :                     /* SAFE { */
     614         [ +  - ]:          2 :                     WriteGuard aWriteLock( m_aLock );
     615         [ +  - ]:          2 :                     if ( ! m_xMenuDispatcher.is() )
     616                 :            :                     {
     617         [ +  - ]:          2 :                         MenuDispatcher* pDispatcher = new MenuDispatcher( xFactory, xOwner );
     618 [ +  - ][ +  - ]:          2 :                         m_xMenuDispatcher = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
                 [ +  - ]
     619                 :            :                     }
     620         [ +  - ]:          2 :                     xDispatchHelper = m_xMenuDispatcher;
     621 [ +  - ][ +  - ]:          2 :                     aWriteLock.unlock();
     622                 :            :                     /* } SAFE */
     623                 :            :                 }
     624                 :          2 :                 break;
     625                 :            : 
     626                 :            :         case E_CREATEDISPATCHER :
     627                 :            :                 {
     628         [ #  # ]:          0 :                     LoadDispatcher* pDispatcher = new LoadDispatcher(xFactory, xOwner, sTarget, nSearchFlags);
     629 [ #  # ][ #  # ]:          0 :                     xDispatchHelper = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
     630                 :            :                 }
     631                 :          0 :                 break;
     632                 :            : 
     633                 :            :         case E_BLANKDISPATCHER :
     634                 :            :                 {
     635         [ #  # ]:          0 :                     css::uno::Reference< css::frame::XFrame > xDesktop( xOwner, css::uno::UNO_QUERY );
     636         [ #  # ]:          0 :                     if (xDesktop.is())
     637                 :            :                     {
     638 [ #  # ][ #  # ]:          0 :                         LoadDispatcher* pDispatcher = new LoadDispatcher(xFactory, xOwner, SPECIALTARGET_BLANK, 0);
     639 [ #  # ][ #  # ]:          0 :                         xDispatchHelper = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
     640                 :          0 :                     }
     641                 :            :                 }
     642                 :          0 :                 break;
     643                 :            : 
     644                 :            :         case E_DEFAULTDISPATCHER :
     645                 :            :                 {
     646         [ #  # ]:          0 :                     css::uno::Reference< css::frame::XFrame > xDesktop( xOwner, css::uno::UNO_QUERY );
     647         [ #  # ]:          0 :                     if (xDesktop.is())
     648                 :            :                     {
     649 [ #  # ][ #  # ]:          0 :                         LoadDispatcher* pDispatcher = new LoadDispatcher(xFactory, xOwner, SPECIALTARGET_DEFAULT, 0);
     650 [ #  # ][ #  # ]:          0 :                         xDispatchHelper = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
     651                 :          0 :                     }
     652                 :            :                 }
     653                 :          0 :                 break;
     654                 :            : 
     655                 :            :         case E_SELFDISPATCHER :
     656                 :            :                 {
     657 [ +  - ][ +  - ]:          2 :                     LoadDispatcher* pDispatcher = new LoadDispatcher(xFactory, xOwner, SPECIALTARGET_SELF, 0);
     658 [ +  - ][ +  - ]:          2 :                     xDispatchHelper = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
     659                 :            :                 }
     660                 :          2 :                 break;
     661                 :            : 
     662                 :            :         case E_CLOSEDISPATCHER :
     663                 :            :                 {
     664         [ +  - ]:          2 :                     CloseDispatcher* pDispatcher = new CloseDispatcher( xFactory, xOwner, sTarget );
     665 [ +  - ][ +  - ]:          2 :                     xDispatchHelper = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
                 [ +  - ]
     666                 :            :                 }
     667                 :          2 :                 break;
     668                 :            : 
     669                 :            :         case E_STARTMODULEDISPATCHER :
     670                 :            :                 {
     671         [ #  # ]:          0 :                     StartModuleDispatcher* pDispatcher = new StartModuleDispatcher( xFactory, xOwner, sTarget );
     672 [ #  # ][ #  # ]:          0 :                     xDispatchHelper = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
                 [ #  # ]
     673                 :            :                 }
     674                 :          0 :                 break;
     675                 :            :     }
     676                 :            : 
     677         [ +  - ]:          6 :     return xDispatchHelper;
     678                 :            : }
     679                 :            : 
     680                 :            : //_________________________________________________________________________________________________________________
     681                 :            : 
     682                 :            : /**
     683                 :            :     @short      check URL for support by our used loader or handler
     684                 :            :     @descr      If we must return our own dispatch helper implementations (self, blank, create dispatcher!)
     685                 :            :                 we should be shure, that URL describe any loadable content. Otherwise slot/uno URLs
     686                 :            :                 will be detected ... but there exist nothing for ral loading into a target frame!
     687                 :            : 
     688                 :            :     @param      aURL
     689                 :            :                     URL which should be "detected"
     690                 :            :     @return     <TRUE/> if somewhere could handle that - <FALSE/> otherwise.
     691                 :            : 
     692                 :            :     @threadsafe yes
     693                 :            : */
     694                 :       3476 : sal_Bool DispatchProvider::implts_isLoadableContent( const css::util::URL& aURL )
     695                 :            : {
     696         [ +  - ]:       3476 :     LoadEnv::EContentType eType = LoadEnv::classifyContent(aURL.Complete, css::uno::Sequence< css::beans::PropertyValue >());
     697                 :       3476 :     return ( eType == LoadEnv::E_CAN_BE_LOADED );
     698                 :            : }
     699                 :            : 
     700                 :            : } // namespace framework
     701                 :            : 
     702                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10