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