LCOV - code coverage report
Current view: top level - libreoffice/framework/source/dispatch - dispatchprovider.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 57 186 30.6 %
Date: 2012-12-27 Functions: 10 16 62.5 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10