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 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 266 //_______________________________________ 267 268 /** @short set some changeable parameters for a new load request. 269 270 @descr The parameter for targeting, the content description, and 271 some environment specifier (UI, dispatch functionality) 272 can be set here ... BEFORE the real load process is started 273 by calling startLoading(). Of course a still running load request 274 will be detected here and a suitable exception will be thrown. 275 Such constellation can be detected outside by using provided 276 synchronization methods or callbacks. 277 278 @param sURL 279 points to the resource, which should be loaded. 280 281 @param lMediaDescriptor 282 contains additional informations for the following load request. 283 284 @param xBaseFrame 285 points to the frame which must be used as start point for target search. 286 287 @param sTarget 288 regulate searching/creating of frames, which should contain the 289 new loaded component afterwards. 290 291 @param nSearchFlags 292 regulate searching of targets, if sTarget is not a special one. 293 294 @param eFeature 295 flag field, which enable/disable special features of this 296 new instance for following load call. 297 298 @param eContentType 299 classify the given content. 300 This value is set to a default value "UNKNOWN_CONTENT", which force 301 an internal check, if this content is loadable or not. 302 But may this check was already made by the caller of this method and 303 passing this information to this LoadEnv instance can suppress this 304 might expensive check. 305 That can be useful in case this information is needed outside too, 306 to decide if its necessary to create some resources for this load 307 request ... or to reject the request immediately if it seems to be not 308 loadable in general. 309 310 @throw A LoadEnvException e.g. if another load operation is till in progress 311 or initialization of a new one fail by other reasons. 312 The real reason, a suitable message and ID will be given here immediately. 313 314 @throw A RuntimeException in case any internal process indicates, that 315 the whole runtime can't be used any longer. 316 */ 317 virtual void initializeLoading(const ::rtl::OUString& sURL , 318 const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor, 319 const css::uno::Reference< css::frame::XFrame >& xBaseFrame , 320 const ::rtl::OUString& sTarget , 321 sal_Int32 nSearchFlags , 322 EFeature eFeature = E_NO_FEATURE , 323 EContentType eContentType = E_UNSUPPORTED_CONTENT); 324 325 //_______________________________________ 326 327 /** @short start loading of the resource represented by this loadenv instance. 328 329 @descr There is no direct return value possible here. Because it depends 330 from the usage of this instance! E.g. for loading a "visible component" 331 a frame with a controller/model inside can be possible. For loading 332 of a "non visible component" only an information about a successfully start 333 can be provided. 334 Further it can't be guaranteed, that the internal process runs synchronous. 335 That's why we prefer using of specialized methods afterwards e.g. to: 336 - wait till the internal job will be finished 337 and get the results 338 - or to let it run without any further control from outside. 339 340 @throw A LoadEnvException if start of the load process failed (because 341 another is still in progress!). 342 The reason, a suitable message and ID will be given here immediately. 343 344 @throw A RuntimeException in case any internal process indicates, that 345 the whole runtime can't be used any longer. 346 */ 347 virtual void startLoading(); 348 349 //_______________________________________ 350 351 /** @short wait for an already running load request (started by calling 352 startLoading() before). 353 354 @descr The timeout parameter can be used to wait some times only 355 or forever. The return value indicates if the load request 356 was finished during the specified timeout period. 357 But it indicates not, if the load request was successfully or not! 358 359 @param nTimeout 360 specify a timeout in [ms]. 361 A value 0 let it wait forever! 362 363 @return sal_True if the started load process could be finished in time; 364 sal_False if the specified time was over. 365 366 @throw ... currently not used :-) 367 368 @throw A RuntimeException in case any internal process indicates, that 369 the whole runtime can't be used any longer. 370 */ 371 virtual sal_Bool waitWhileLoading(sal_uInt32 nTimeout = 0); 372 373 //_______________________________________ 374 /** TODO document me ... */ 375 virtual void cancelLoading(); 376 377 //_______________________________________ 378 /** TODO document me ... */ 379 virtual css::uno::Reference< css::frame::XFrame > getTarget() const; 380 381 //_______________________________________ 382 /** TODO document me ... */ 383 virtual css::uno::Reference< css::lang::XComponent > getTargetComponent() const; 384 /* 385 //___________________________________________ 386 // helper uno interface! 387 // You have to use the native interface only! 388 389 public: 390 391 //_______________________________________ 392 // frame.XLoadEventListener 393 virtual void SAL_CALL loadFinished(const css::uno::Reference< css::frame::XFrameLoader >& xLoader) 394 throw(css::uno::RuntimeException); 395 396 virtual void SAL_CALL loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >& xLoader) 397 throw(css::uno::RuntimeException); 398 399 //_______________________________________ 400 // frame.XDispatchResultListener 401 virtual void SAL_CALL dispatchFinished(const css::frame::DispatchResultEvent& aEvent) 402 throw(css::uno::RuntimeException); 403 404 //_______________________________________ 405 // lang.XEventListener 406 virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent) 407 throw(css::uno::RuntimeException); 408 */ 409 410 //___________________________________________ 411 // static interface 412 413 public: 414 415 /** @short checks if the specified content can be handled by a 416 ContentHandler only and is not related to a target frame, 417 or if it can be loaded by a FrameLoader into a target frame 418 as "visible" component. 419 420 @descr using: 421 switch(classifyContent(...)) 422 { 423 case E_CAN_BE_HANDLED : 424 handleIt(...); 425 break; 426 427 case E_CAN_BE_LOADED : 428 xFrame = locateTargetFrame(); 429 loadIt(xFrame); 430 break; 431 432 case E_NOT_A_CONTENT : 433 default : throw ...; 434 } 435 436 @param sURL 437 describe the content. 438 439 @param lMediaDescriptor 440 describe the content more detailed! 441 442 @return A suitable enum value, which classify the specified content. 443 */ 444 static EContentType classifyContent(const ::rtl::OUString& sURL , 445 const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor); 446 447 /** TODO document me ... */ 448 static void initializeUIDefaults( 449 const css::uno::Reference< css::lang::XMultiServiceFactory >& i_rSMGR, 450 ::comphelper::MediaDescriptor& io_lMediaDescriptor, 451 const bool _bUIMode, 452 QuietInteraction** o_ppQuiteInteraction 453 ); 454 455 /** TODO document me ... */ 456 void impl_setResult(sal_Bool bResult); 457 458 /** TODO document me ... */ 459 css::uno::Reference< css::uno::XInterface > impl_searchLoader(); 460 461 //_______________________________________ 462 463 /** @short it means; show the frame, bring it to front, 464 might set the right icon etcpp. in case loading was 465 successfully or reactivate a might existing old document or 466 close the frame if it was created before in case loading failed. 467 468 @throw A LoadEnvException only in cases, where an internal error indicates, 469 that the complete load environment seems to be not usable in general. 470 In such cases a RuntimeException would be to hard for the outside code :-) 471 472 @throw A RuntimeException in case any internal process indicates, that 473 the whole runtime can't be used any longer. 474 */ 475 void impl_reactForLoadingState(); 476 477 //___________________________________________ 478 // private helper 479 480 private: 481 482 /** @short tries to detect the type and the filter of the specified content. 483 484 @descr This method update the available media descriptor of this instance, 485 so it contains the right type, a corresponding filter, may a 486 valid frame loader etc. In case detection failed, this descriptor 487 is corrected first, before a suitable exception will be thrown. 488 (Excepting a RuntimeException occurs!) 489 490 @attention Not all types we know, are supported by filters. So it does not 491 indicates an error, if no suitable filter(loader etcpp will be found 492 for a type. But a type must be detected for the specified content. 493 Otherwise it's an error and loading can't be finished successfully. 494 495 @throw A LoadEnvException if detection failed. 496 497 @throw A RuntimeException in case any internal process indicates, that 498 the whole runtime can't be used any longer. 499 */ 500 void impl_detectTypeAndFilter(); 501 502 //_______________________________________ 503 504 /** @short tries to ask user for it's filter decision in case 505 normal detection failed. 506 507 @descr We use a may existing interaction handler to do so. 508 509 @return [string] 510 the type selected by the user. 511 512 @attention Internally we update the member m_lMediaDescriptor! 513 */ 514 ::rtl::OUString impl_askUserForTypeAndFilterIfAllowed(); 515 516 //_______________________________________ 517 518 /** @short tries to use ContentHandler objects for loading. 519 520 @descr It searches for a suitable content handler object, registered 521 for the detected content type (must be done before by calling 522 impl_detectTypeAndFilter()). Because such handler does not depend 523 from a real target frame, location of such frame will be 524 suppressed here. 525 In case handle failed all new created resources will be 526 removed before a suitable exception is thrown. 527 (Excepting a RuntimeException occurs!) 528 529 @return TODO 530 531 @throw A LoadEnvException if handling failed. 532 533 @throw A RuntimeException in case any internal process indicates, that 534 the whole runtime can't be used any longer. 535 */ 536 sal_Bool impl_handleContent(); 537 538 //_______________________________________ 539 540 /** @short tries to use FrameLoader objects for loading. 541 542 @descr First the target frame will be located. If it could be found 543 or new created a filter/frame loader will be instantiated and 544 used to load the content into this frame. 545 In case loading failed all new created resources will be 546 removed before a suitable exception is thrown. 547 (Excepting a RuntimeException occurs!) 548 549 @return TODO 550 551 @throw A LoadEnvException if loading failed. 552 553 @throw A RuntimeException in case any internal process indicates, that 554 the whole runtime can't be used any longer. 555 */ 556 sal_Bool impl_loadContent(); 557 558 //_______________________________________ 559 560 /** @short checks if the specified content is already loaded. 561 562 @descr It depends from the set target information, if such 563 search is allowed or not! So this method checks first, 564 if the target is the special one "_default". 565 If not it returns with an empty result immediately! 566 In case search is allowed, an existing document with the 567 same URL is searched. If it could be found, the corresponding 568 view will get the focus and this method return the corresponding frame. 569 Optional jumpmarks will be accepted here too. So the 570 view of the document will be updated to show the position 571 inside the document, which is related to the jumpmark. 572 573 @return A valid reference to the target frame, which contains the already loaded content 574 and could be activated successfully. An empty reference otherwise. 575 576 @throw A LoadEnvException only in cases, where an internal error indicates, 577 that the complete load environment seems to be not usable in general. 578 In such cases a RuntimeException would be to hard for the outside code :-) 579 580 @throw A RuntimeException in case any internal process indicates, that 581 the whole runtime can't be used any longer. 582 */ 583 css::uno::Reference< css::frame::XFrame > impl_searchAlreadyLoaded(); 584 585 //_______________________________________ 586 587 /** @short search for any target frame, which seems to be usable 588 for this load request. 589 590 @descr Because this special feature is bound to the target specifier "_default" 591 it's checked inside first. If it's not set => this method return an empty 592 reference. Otherwise any currently existing frame will be analyzed, if 593 it can be used here. The following rules exists: 594 595 <ul> 596 <li>The frame must be empty ...</li> 597 <li>or contains an empty document of the same application module 598 which the new document will have (Note: the filter of the new content 599 must be well known here!)</li> 600 <li>and(!) this target must not be already used by any other load request.</li> 601 </ul> 602 603 If a suitable target is located it will be locked. That's why the last rule 604 exists! If this method returns a valid frame reference, it was locked to be usable 605 for this load request only. (Don't forget to reset this state later!) 606 Concurrent LoadEnv instances can synchronize her work be using such locks :-) HOPEFULLY 607 608 @throw A LoadEnvException only in cases, where an internal error indicates, 609 that the complete load environment seems to be not usable in general. 610 In such cases a RuntimeException would be to hard for the outside code :-) 611 612 @throw A RuntimeException in case any internal process indicates, that 613 the whole runtime can't be used any longer. 614 */ 615 css::uno::Reference< css::frame::XFrame > impl_searchRecycleTarget(); 616 617 //_______________________________________ 618 619 /** @short because showing of a frame is needed more then once ... 620 it's implemented as an separate method .-) 621 622 @descr Note: Showing of a frame is bound to a special feature ... 623 a) If we recycle any existing frame, we must bring it to front. 624 Showing of such frame isn't needed really .. because we recycle 625 visible frames only! 626 b) If the document was already shown (e.g. by our progress implementation) 627 we do nothing here. The reason behind: The document was already shown .. 628 and it was already make a top window ... 629 If the user activated another frame in between (because loading needed some time) 630 it's not allowed to disturb the user again. Then the frame must resists in the background. 631 c) If the frame was not shown before ... but loading of a visible document into this frame 632 was finished ... we need both actions: setVisible() and toFront(). 633 634 @param xWindow 635 points to the container window of a frame. 636 637 @param bForceToFront 638 if it's set to sal_False ... showing of the window is done more intelligent. 639 setVisible() is called only if the window was not shown before. 640 This mode is needed by b) and c) 641 If it's set to sal_True ... both actions has to be done: setVisible(), toFront()! 642 This mode is needed by a) 643 */ 644 void impl_makeFrameWindowVisible(const css::uno::Reference< css::awt::XWindow >& xWindow , 645 sal_Bool bForceToFront); 646 647 //_______________________________________ 648 649 /** @short checks whether a frame is already used for another load request or not. 650 651 @descr Such frames can't be used for our "recycle feature"! 652 653 @param xFrame 654 the frame, which should be checked. 655 656 @return [sal_Bool] 657 sal_True if this frame is already used for loading, 658 sal_False otherwise. 659 */ 660 sal_Bool impl_isFrameAlreadyUsedForLoading(const css::uno::Reference< css::frame::XFrame >& xFrame) const; 661 662 //_______________________________________ 663 664 /** @short try to determine the used application module 665 of this load request and apply right position and size 666 for this document window ... hopefully before we show it .-) 667 */ 668 void impl_applyPersistentWindowState(const css::uno::Reference< css::awt::XWindow >& xWindow); 669 670 //_______________________________________ 671 672 /** @short determine if it's allowed to open new document frames. 673 */ 674 sal_Bool impl_furtherDocsAllowed(); 675 676 //_______________________________________ 677 678 /** @short jumps to the requested bookmark inside a given document. 679 */ 680 void impl_jumpToMark(const css::uno::Reference< css::frame::XFrame >& xFrame, 681 const css::util::URL& aURL ); 682 }; 683 684 } // namespace framework 685 686 #endif // __FRAMEWORK_LOADENV_LOADENV_HXX_ 687