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