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