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 #ifndef __FRAMEWORK_LOADENV_LOADENV_HXX_ 25 #define __FRAMEWORK_LOADENV_LOADENV_HXX_ 26 27 //_______________________________________________ 28 // includes of own project 29 30 #include <loadenv/loadenvexception.hxx> 31 #include <loadenv/actionlockguard.hxx> 32 #include <threadhelp/threadhelpbase.hxx> 33 34 //_______________________________________________ 35 // includes of uno interface 36 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 37 #include <com/sun/star/frame/XComponentLoader.hpp> 38 #include <com/sun/star/frame/XFrameLoader.hpp> 39 #include <com/sun/star/frame/XLoadEventListener.hpp> 40 #include <com/sun/star/frame/XDispatchResultListener.hpp> 41 #include <com/sun/star/frame/XFrame.hpp> 42 #include <com/sun/star/util/URL.hpp> 43 44 #ifndef _COM_SUN_STAR_LANG_IllegalArgumentException_HPP_ 45 #include <com/sun/star/lang/IllegalArgumentException.hpp> 46 #endif 47 48 #ifndef _COM_SUN_STAR_IO_IOException_HPP_ 49 #include <com/sun/star/io/IOException.hpp> 50 #endif 51 52 //_______________________________________________ 53 // includes of an other project 54 #include <comphelper/mediadescriptor.hxx> 55 #include <comphelper/sequenceashashmap.hxx> 56 #include <cppuhelper/implbase2.hxx> 57 58 //_______________________________________________ 59 // namespace 60 61 namespace framework{ 62 63 namespace css = ::com::sun::star; 64 class QuietInteraction; 65 //_______________________________________________ 66 // definitions 67 68 /** @short implements general mechanism for loading documents. 69 70 @descr An instance of this class can be used inside the API calls 71 XComponentLoader::loadComponentFromURL() and XDispatch::dispatch() 72 (of course in its derived interfaces too :-)). 73 74 @author as96863 75 */ 76 class LoadEnv : private ThreadHelpBase 77 { 78 //___________________________________________ 79 // structs, types, etc. 80 81 public: 82 83 /** @short enable/disable special features 84 of a load request. 85 86 @desrc Such features must outcome without 87 any special parameters. 88 To make enabling/disabling of 89 features very easy (e.g. at the ctor of 90 this class) these values must be combinable 91 as flags. That means: its values must be in 92 range of [2^n]! 93 */ 94 enum EFeature 95 { 96 /// we should be informed, if no feature is enabled :-) 97 E_NO_FEATURE = 0, 98 /// enable using of UI elements during loading (means progress, interaction handler etcpp.) 99 E_WORK_WITH_UI = 1, 100 /// enable loading of resources, which are not related to a target frame! (see concept of ContentHandler) 101 E_ALLOW_CONTENTHANDLER = 2 102 }; 103 104 //_______________________________________ 105 106 /** @short classify a content. 107 108 @descr The load environment must know, if a content 109 is related to a target frame or not. Only "visible" 110 components, which full fill the requirements of the 111 model-controller-view paradigm can be loaded into a frame. 112 Such contents are classified as E_CAN_BE_LOADED. 113 114 But e.g. for the dispatch framework exists special ContentHandler 115 objects, which can load a content in "non visible" mode ... 116 and do not need a target frame for its operation. Such 117 ContentHandler e.g. plays sounds. 118 Such contents are classified as E_CAN_BE_HANDLED. 119 120 And last but not least a content can be "not valid" in general. 121 */ 122 enum EContentType 123 { 124 /// identifies a content, which seems to be invalid in general 125 E_UNSUPPORTED_CONTENT, 126 /// identifies a content, which can be used with a ContentHandler and is not related to a target frame 127 E_CAN_BE_HANDLED, 128 /// identifies a content, which can be loaded into a target frame 129 E_CAN_BE_LOADED, 130 /// special mode for non real loading, In such case the model is given directly! 131 E_CAN_BE_SET 132 }; 133 134 //___________________________________________ 135 // member 136 137 private: 138 139 /** @short reference to an uno service manager, which must be used 140 to created on needed services on demand. 141 */ 142 css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR; 143 144 /** @short points to the frame, which uses this LoadEnv object 145 and must be used to start target search there. 146 */ 147 css::uno::Reference< css::frame::XFrame > m_xBaseFrame; 148 149 /** @short points to the frame, into which the new component was loaded. 150 151 @descr Note: This reference will be empty if loading failed 152 or a non visible content was loaded! 153 It can be the same frame as m_xBaseFrame it describe, in case 154 the target "_self", "" or the search flag "SELF" was used. 155 Otherwise it's the new created or recycled frame, which was 156 used for loading and contains further the new component. 157 158 Please use method getTarget() or getTargetComponent() 159 to return the frame/controller or model to any interested 160 user of the results of this load request. 161 */ 162 css::uno::Reference< css::frame::XFrame > m_xTargetFrame; 163 164 /** @short contains the name of the target, in which the specified resource 165 of this instance must be loaded. 166 */ 167 ::rtl::OUString m_sTarget; 168 169 /** @short if m_sTarget is not a special one, this flags regulate searching 170 of a suitable one. 171 */ 172 sal_Int32 m_nSearchFlags; 173 174 /** @short contains all needed informations about the resource, 175 which should be loaded. 176 177 @descr Inside this struct e.g. the URL, its type and filter name, 178 the stream or a model directly are saved. 179 */ 180 ::comphelper::MediaDescriptor m_lMediaDescriptor; 181 182 /** @short because the mediadescriptor contains the complete URL ... but 183 some functionality need the structured version, we hold it twice :-(. 184 */ 185 css::util::URL m_aURL; 186 187 /** @short enable/disable special features of a load request. */ 188 EFeature m_eFeature; 189 190 /** @short classify the content, which should be loaded by this instance. */ 191 EContentType m_eContentType; 192 193 /** @short it indicates, that the member m_xTargetFrame was new created for this 194 load request and must be closed in case loading (not handling!) 195 operation failed. The default value is sal_False! 196 */ 197 sal_Bool m_bCloseFrameOnError; 198 199 /** @short it indicates, that the old document (which was located inside m_xBaseFrame 200 in combination with the m_sTarget value "_self") was suspended. 201 Normally it will be replaced by the new loaded document. But in case 202 loading (not handling!) failed, it must be reactivated. 203 The default value is sal_False! 204 */ 205 sal_Bool m_bReactivateControllerOnError; 206 207 /** @short it holds one (!) asynchronous used contenthandler or frameloader 208 alive, till the asynchronous operation will be finished. 209 */ 210 css::uno::Reference< css::uno::XInterface > m_xAsynchronousJob; 211 212 /** @short holds the information about the finished load process. 213 214 @descr The content of m_xTargetFrame can't be used as valid indicator, 215 (in case the might existing old document was reactivated) 216 we must hold the result of the load process explicitly. 217 */ 218 sal_Bool m_bLoaded; 219 220 /** @short holds an XActionLock on the internal used task member. 221 222 @seealso m_xTargetFrame 223 */ 224 ActionLockGuard m_aTargetLock; 225 226 /** TODO document me ... */ 227 void* m_pCheck; 228 229 QuietInteraction* m_pQuietInteraction; 230 231 //___________________________________________ 232 // native interface 233 234 public: 235 236 /** @short initialize a new instance of this load environment. 237 238 @param xSMGR 239 reference to an uno service manager, which can be used internally 240 to create own needed services on demand. 241 242 @throw Currently there is no reason to throw such exception! 243 244 @throw A RuntimeException in case any internal process indicates, that 245 the whole runtime can't be used any longer. 246 */ 247 LoadEnv(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) 248 throw(LoadEnvException, css::uno::RuntimeException); 249 250 //_______________________________________ 251 252 /** @short deinitialize an instance of this class in the right way. 253 */ 254 virtual ~LoadEnv(); 255 256 //_______________________________________ 257 258 /** @short DRAFT TODO 259 */ 260 static css::uno::Reference< css::lang::XComponent > loadComponentFromURL(const css::uno::Reference< css::frame::XComponentLoader >& xLoader, 261 const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , 262 const ::rtl::OUString& sURL , 263 const ::rtl::OUString& sTarget, 264 sal_Int32 nFlags , 265 const css::uno::Sequence< css::beans::PropertyValue >& lArgs ) 266 throw(css::lang::IllegalArgumentException, 267 css::io::IOException , 268 css::uno::RuntimeException ); 269 270 //_______________________________________ 271 272 /** @short set some changeable parameters for a new load request. 273 274 @descr The parameter for targeting, the content description, and 275 some environment specifier (UI, dispatch functionality) 276 can be set here ... BEFORE the real load process is started 277 by calling startLoading(). Of course a still running load request 278 will be detected here and a suitable exception will be thrown. 279 Such constellation can be detected outside by using provided 280 synchronization methods or callbacks. 281 282 @param sURL 283 points to the resource, which should be loaded. 284 285 @param lMediaDescriptor 286 contains additional informations for the following load request. 287 288 @param xBaseFrame 289 points to the frame which must be used as start point for target search. 290 291 @param sTarget 292 regulate searching/creating of frames, which should contain the 293 new loaded component afterwards. 294 295 @param nSearchFlags 296 regulate searching of targets, if sTarget is not a special one. 297 298 @param eFeature 299 flag field, which enable/disable special features of this 300 new instance for following load call. 301 302 @param eContentType 303 classify the given content. 304 This value is set to a default value "UNKNWON_CONTENT", which force 305 an internal check, if this content is loadable or not. 306 But may this check was already made by the caller of this method and 307 passing this information to this LoadEnv instance can suppress this 308 might expensive check. 309 That can be useful in case this information is needed outside too, 310 to decide if its necessary to create some resources for this load 311 request ... or to reject the request immediately if it seems to be not 312 loadable in general. 313 314 @throw A LoadEnvException e.g. if another load operation is till in progress 315 or initialization of a new one fail by other reasons. 316 The real reason, a suitable message and ID will be given here immediately. 317 318 @throw A RuntimeException in case any internal process indicates, that 319 the whole runtime can't be used any longer. 320 */ 321 virtual void initializeLoading(const ::rtl::OUString& sURL , 322 const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor, 323 const css::uno::Reference< css::frame::XFrame >& xBaseFrame , 324 const ::rtl::OUString& sTarget , 325 sal_Int32 nSearchFlags , 326 EFeature eFeature = E_NO_FEATURE , 327 EContentType eContentType = E_UNSUPPORTED_CONTENT) 328 throw(LoadEnvException, css::uno::RuntimeException); 329 330 //_______________________________________ 331 332 /** @short start loading of the resource represented by this loadenv instance. 333 334 @descr There is no direct return value possible here. Because it depends 335 from the usage of this instance! E.g. for loading a "visible component" 336 a frame with a controller/model inside can be possible. For loading 337 of a "non visible component" only an information about a successfully start 338 can be provided. 339 Further it can't be guaranteed, that the internal process runs synchronous. 340 That's why we prefer using of specialized methods afterwards e.g. to: 341 - wait till the internal job will be finished 342 and get the results 343 - or to let it run without any further control from outside. 344 345 @throw A LoadEnvException if start of the load process failed (because 346 another is still in progress!). 347 The reason, a suitable message and ID will be given here immediately. 348 349 @throw A RuntimeException in case any internal process indicates, that 350 the whole runtime can't be used any longer. 351 */ 352 virtual void startLoading() 353 throw(LoadEnvException, css::uno::RuntimeException); 354 355 //_______________________________________ 356 357 /** @short wait for an already running load request (started by calling 358 startLoading() before). 359 360 @descr The timeout parameter can be used to wait some times only 361 or forever. The return value indicates if the load request 362 was finished during the specified timeout period. 363 But it indicates not, if the load request was successfully or not! 364 365 @param nTimeout 366 specify a timeout in [ms]. 367 A value 0 let it wait forever! 368 369 @return sal_True if the started load process could be finished in time; 370 sal_False if the specified time was over. 371 372 @throw ... currently not used :-) 373 374 @throw A RuntimeException in case any internal process indicates, that 375 the whole runtime can't be used any longer. 376 */ 377 virtual sal_Bool waitWhileLoading(sal_uInt32 nTimeout = 0) 378 throw(LoadEnvException, css::uno::RuntimeException); 379 380 //_______________________________________ 381 /** TODO document me ... */ 382 virtual void cancelLoading() 383 throw(LoadEnvException, css::uno::RuntimeException); 384 385 //_______________________________________ 386 /** TODO document me ... */ 387 virtual css::uno::Reference< css::frame::XFrame > getTarget() const; 388 389 //_______________________________________ 390 /** TODO document me ... */ 391 virtual css::uno::Reference< css::lang::XComponent > getTargetComponent() const; 392 /* 393 //___________________________________________ 394 // helper uno interface! 395 // You have to use the native interface only! 396 397 public: 398 399 //_______________________________________ 400 // frame.XLoadEventListener 401 virtual void SAL_CALL loadFinished(const css::uno::Reference< css::frame::XFrameLoader >& xLoader) 402 throw(css::uno::RuntimeException); 403 404 virtual void SAL_CALL loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >& xLoader) 405 throw(css::uno::RuntimeException); 406 407 //_______________________________________ 408 // frame.XDispatchResultListener 409 virtual void SAL_CALL dispatchFinished(const css::frame::DispatchResultEvent& aEvent) 410 throw(css::uno::RuntimeException); 411 412 //_______________________________________ 413 // lang.XEventListener 414 virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent) 415 throw(css::uno::RuntimeException); 416 */ 417 418 //___________________________________________ 419 // static interface 420 421 public: 422 423 /** @short checks if the specified content can be handled by a 424 ContentHandler only and is not related to a target frame, 425 or if it can be loaded by a FrameLoader into a target frame 426 as "visible" component. 427 428 @descr using: 429 switch(classifyContent(...)) 430 { 431 case E_CAN_BE_HANDLED : 432 handleIt(...); 433 break; 434 435 case E_CAN_BE_LOADED : 436 xFrame = locateTargetFrame(); 437 loadIt(xFrame); 438 break; 439 440 case E_NOT_A_CONTENT : 441 default : throw ...; 442 } 443 444 @param sURL 445 describe the content. 446 447 @param lMediaDescriptor 448 describe the content more detailed! 449 450 @return A suitable enum value, which classify the specified content. 451 */ 452 static EContentType classifyContent(const ::rtl::OUString& sURL , 453 const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor); 454 455 /** TODO document me ... */ 456 static void initializeUIDefaults( 457 const css::uno::Reference< css::lang::XMultiServiceFactory >& i_rSMGR, 458 ::comphelper::MediaDescriptor& io_lMediaDescriptor, 459 const bool _bUIMode, 460 QuietInteraction** o_ppQuiteInteraction 461 ); 462 463 /** TODO document me ... */ 464 void impl_setResult(sal_Bool bResult); 465 466 /** TODO document me ... */ 467 css::uno::Reference< css::uno::XInterface > impl_searchLoader(); 468 469 //_______________________________________ 470 471 /** @short it means; show the frame, bring it to front, 472 might set the right icon etcpp. in case loading was 473 successfully or reactivate a might existing old document or 474 close the frame if it was created before in case loading failed. 475 476 @throw A LoadEnvException only in cases, where an internal error indicates, 477 that the complete load environment seems to be not usable in general. 478 In such cases a RuntimeException would be to hard for the outside code :-) 479 480 @throw A RuntimeException in case any internal process indicates, that 481 the whole runtime can't be used any longer. 482 */ 483 void impl_reactForLoadingState() 484 throw(LoadEnvException, css::uno::RuntimeException); 485 486 //___________________________________________ 487 // private helper 488 489 private: 490 491 /** @short tries to detect the type and the filter of the specified content. 492 493 @descr This method update the available media descriptor of this instance, 494 so it contains the right type, a corresponding filter, may a 495 valid frame loader etc. In case detection failed, this descriptor 496 is corrected first, before a suitable exception will be thrown. 497 (Excepting a RuntimeException occurs!) 498 499 @attention Not all types we know, are supported by filters. So it does not 500 indicates an error, if no suitable filter(loader etcpp will be found 501 for a type. But a type must be detected for the specified content. 502 Otherwise it's an error and loading can't be finished successfully. 503 504 @throw A LoadEnvException if detection failed. 505 506 @throw A RuntimeException in case any internal process indicates, that 507 the whole runtime can't be used any longer. 508 */ 509 void impl_detectTypeAndFilter() 510 throw(LoadEnvException, css::uno::RuntimeException); 511 512 //_______________________________________ 513 514 /** @short tries to ask user for it's filter decision in case 515 normal detection failed. 516 517 @descr We use a may existing interaction handler to do so. 518 519 @return [string] 520 the type selected by the user. 521 522 @attention Internally we update the member m_lMediaDescriptor! 523 */ 524 ::rtl::OUString impl_askUserForTypeAndFilterIfAllowed() 525 throw(LoadEnvException, css::uno::RuntimeException); 526 527 //_______________________________________ 528 529 /** @short tries to use ContentHandler objects for loading. 530 531 @descr It searches for a suitable content handler object, registered 532 for the detected content type (must be done before by calling 533 impl_detectTypeAndFilter()). Because such handler does not depend 534 from a real target frame, location of such frame will be 535 suppressed here. 536 In case handle failed all new created resources will be 537 removed before a suitable exception is thrown. 538 (Excepting a RuntimeException occurs!) 539 540 @return TODO 541 542 @throw A LoadEnvException if handling failed. 543 544 @throw A RuntimeException in case any internal process indicates, that 545 the whole runtime can't be used any longer. 546 */ 547 sal_Bool impl_handleContent() 548 throw(LoadEnvException, css::uno::RuntimeException); 549 550 //_______________________________________ 551 552 /** @short tries to use FrameLoader objects for loading. 553 554 @descr First the target frame will be located. If it could be found 555 or new created a filter/frame loader will be instantiated and 556 used to load the content into this frame. 557 In case loading failed all new created resources will be 558 removed before a suitable exception is thrown. 559 (Excepting a RuntimeException occurs!) 560 561 @return TODO 562 563 @throw A LoadEnvException if loading failed. 564 565 @throw A RuntimeException in case any internal process indicates, that 566 the whole runtime can't be used any longer. 567 */ 568 sal_Bool impl_loadContent() 569 throw(LoadEnvException, css::uno::RuntimeException); 570 571 //_______________________________________ 572 573 /** @short checks if the specified content is already loaded. 574 575 @descr It depends from the set target information, if such 576 search is allowed or not! So this method checks first, 577 if the target is the special one "_default". 578 If not it returns with an empty result immediately! 579 In case search is allowed, an existing document with the 580 same URL is searched. If it could be found, the corresponding 581 view will get the focus and this method return the corresponding frame. 582 Optional jumpmarks will be accepted here too. So the 583 view of the document will be updated to show the position 584 inside the document, which is related to the jumpmark. 585 586 @return A valid reference to the target frame, which contains the already loaded content 587 and could be activated successfully. An empty reference otherwise. 588 589 @throw A LoadEnvException only in cases, where an internal error indicates, 590 that the complete load environment seems to be not usable in general. 591 In such cases a RuntimeException would be to hard for the outside code :-) 592 593 @throw A RuntimeException in case any internal process indicates, that 594 the whole runtime can't be used any longer. 595 */ 596 css::uno::Reference< css::frame::XFrame > impl_searchAlreadyLoaded() 597 throw(LoadEnvException, css::uno::RuntimeException); 598 599 //_______________________________________ 600 601 /** @short search for any target frame, which seems to be usable 602 for this load request. 603 604 @descr Because this special feature is bound to the target specifier "_default" 605 it's checked inside first. If it's not set => this method return an empty 606 reference. Otherwise any currently existing frame will be analyzed, if 607 it can be used here. The following rules exists: 608 609 <ul> 610 <li>The frame must be empty ...</li> 611 <li>or contains an empty document of the same application module 612 which the new document will have (Note: the filter of the new content 613 must be well known here!)</li> 614 <li>and(!) this target must not be already used by any other load request.</li> 615 </ul> 616 617 If a suitable target is located it will be locked. That's why the last rule 618 exists! If this method returns a valid frame reference, it was locked to be usable 619 for this load request only. (Don't forget to reset this state later!) 620 Concurrent LoadEnv instances can synchronize her work be using such locks :-) HOPEFULLY 621 622 @throw A LoadEnvException only in cases, where an internal error indicates, 623 that the complete load environment seems to be not usable in general. 624 In such cases a RuntimeException would be to hard for the outside code :-) 625 626 @throw A RuntimeException in case any internal process indicates, that 627 the whole runtime can't be used any longer. 628 */ 629 css::uno::Reference< css::frame::XFrame > impl_searchRecycleTarget() 630 throw(LoadEnvException, css::uno::RuntimeException); 631 632 //_______________________________________ 633 634 /** @short because showing of a frame is needed more then once ... 635 it's implemented as an separate method .-) 636 637 @descr Note: Showing of a frame is bound to a special feature ... 638 a) If we recycle any existing frame, we must bring it to front. 639 Showing of such frame isn't needed really .. because we recycle 640 visible frames only! 641 b) If the document was already shown (e.g. by our progress implementation) 642 we do nothing here. The reason behind: The document was already shown .. 643 and it was already make a top window ... 644 If the user activated another frame in between (because loading needed some time) 645 it's not allowed to disturb the user again. Then the frame must resists in the background. 646 c) If the frame was not shown before ... but loading of a visible document into this frame 647 was finished ... we need both actions: setVisible() and toFront(). 648 649 @param xWindow 650 points to the container window of a frame. 651 652 @param bForceToFront 653 if it's set to sal_False ... showing of the window is done more intelligent. 654 setVisible() is called only if the window was not shown before. 655 This mode is needed by b) and c) 656 If it's set to sal_True ... both actions has to be done: setVisible(), toFront()! 657 This mode is needed by a) 658 */ 659 void impl_makeFrameWindowVisible(const css::uno::Reference< css::awt::XWindow >& xWindow , 660 sal_Bool bForceToFront); 661 662 //_______________________________________ 663 664 /** @short checks whether a frame is already used for another load request or not. 665 666 @descr Such frames can't be used for our "recycle feature"! 667 668 @param xFrame 669 the frame, which should be checked. 670 671 @return [sal_Bool] 672 sal_True if this frame is already used for loading, 673 sal_False otherwise. 674 */ 675 sal_Bool impl_isFrameAlreadyUsedForLoading(const css::uno::Reference< css::frame::XFrame >& xFrame) const; 676 677 //_______________________________________ 678 679 /** @short try to determine the used application module 680 of this load request and apply right position and size 681 for this document window ... hopefully before we show it .-) 682 */ 683 void impl_applyPersistentWindowState(const css::uno::Reference< css::awt::XWindow >& xWindow); 684 685 //_______________________________________ 686 687 /** @short determine if it's allowed to open new document frames. 688 */ 689 sal_Bool impl_furtherDocsAllowed(); 690 691 //_______________________________________ 692 693 /** @short jumps to the requested bookmark inside a given document. 694 */ 695 void impl_jumpToMark(const css::uno::Reference< css::frame::XFrame >& xFrame, 696 const css::util::URL& aURL ); 697 }; 698 699 } // namespace framework 700 701 #endif // __FRAMEWORK_LOADENV_LOADENV_HXX_ 702