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