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