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