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