1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_framework.hxx" 26 //_______________________________________________ 27 // includes of own project 28 #include <loadenv/loadenv.hxx> 29 30 #ifndef __FRAMEWORK_LOADENV_TARGETHELPER_HXX_ 31 #include <loadenv/targethelper.hxx> 32 #endif 33 #include <framework/framelistanalyzer.hxx> 34 35 #ifndef __FRAMEWORK_CONSTANT_FRAMELOADER_HXX_ 36 #include <constant/frameloader.hxx> 37 #endif 38 39 #ifndef __FRAMEWORK_CONSTANT_CONTENTHANDLER_HXX_ 40 #include <constant/contenthandler.hxx> 41 #endif 42 43 #ifndef __FRAMEWORK_CONSTANT_CONTAINERQUERY_HXX_ 44 #include <constant/containerquery.hxx> 45 #endif 46 #include <interaction/quietinteraction.hxx> 47 #include <threadhelp/writeguard.hxx> 48 #include <threadhelp/readguard.hxx> 49 #include <threadhelp/resetableguard.hxx> 50 #include <properties.h> 51 #include <protocols.h> 52 #include <services.h> 53 #include <comphelper/interaction.hxx> 54 #include <framework/interaction.hxx> 55 56 //_______________________________________________ 57 // includes of uno interface 58 #include <com/sun/star/task/ErrorCodeRequest.hpp> 59 #include <com/sun/star/uno/RuntimeException.hpp> 60 #include <com/sun/star/frame/DispatchResultState.hpp> 61 #include <com/sun/star/frame/FrameSearchFlag.hpp> 62 #include <com/sun/star/util/XURLTransformer.hpp> 63 #include <com/sun/star/ucb/XContentProviderManager.hpp> 64 #include <com/sun/star/util/XCloseable.hpp> 65 #include <com/sun/star/lang/XComponent.hpp> 66 #include <com/sun/star/lang/XServiceInfo.hpp> 67 #include <com/sun/star/lang/DisposedException.hpp> 68 #include <com/sun/star/awt/XWindow.hpp> 69 #include <com/sun/star/awt/XWindow2.hpp> 70 #include <com/sun/star/awt/XTopWindow.hpp> 71 #include <com/sun/star/frame/XModel.hpp> 72 #include <com/sun/star/frame/XFrameLoader.hpp> 73 #include <com/sun/star/frame/XSynchronousFrameLoader.hpp> 74 #include <com/sun/star/frame/XNotifyingDispatch.hpp> 75 #include <com/sun/star/task/XStatusIndicatorFactory.hpp> 76 #include <com/sun/star/task/XStatusIndicator.hpp> 77 #include <com/sun/star/util/XModifiable.hpp> 78 #include <com/sun/star/frame/XDispatchProvider.hpp> 79 #include <com/sun/star/document/XTypeDetection.hpp> 80 #include <com/sun/star/document/XActionLockable.hpp> 81 #include <com/sun/star/io/XInputStream.hpp> 82 #include <com/sun/star/task/XInteractionHandler.hpp> 83 #include <com/sun/star/container/XNameAccess.hpp> 84 #include <com/sun/star/container/XContainerQuery.hpp> 85 #include <com/sun/star/container/XEnumeration.hpp> 86 #include <com/sun/star/document/MacroExecMode.hpp> 87 #include <com/sun/star/document/UpdateDocMode.hpp> 88 89 //_______________________________________________ 90 // includes of an other project 91 #include <vcl/window.hxx> 92 #include <vcl/wrkwin.hxx> 93 #include <vcl/syswin.hxx> 94 95 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ 96 #include <toolkit/helper/vclunohelper.hxx> 97 #endif 98 #include <unotools/moduleoptions.hxx> 99 #include <svtools/sfxecode.hxx> 100 #include <unotools/processfactory.hxx> 101 #include <unotools/ucbhelper.hxx> 102 #include <comphelper/configurationhelper.hxx> 103 #include <rtl/ustrbuf.hxx> 104 #include <vcl/svapp.hxx> 105 106 //_______________________________________________ 107 // namespace 108 109 namespace framework{ 110 111 // may there exist already a define .-( 112 #ifndef css 113 namespace css = ::com::sun::star; 114 #endif 115 116 //_______________________________________________ 117 // declarations 118 119 class LoadEnvListener : private ThreadHelpBase 120 , public ::cppu::WeakImplHelper2< css::frame::XLoadEventListener , 121 css::frame::XDispatchResultListener > 122 { 123 private: 124 125 void** m_ppCheck ; 126 LoadEnv* m_pLoadEnv; 127 128 public: 129 130 //_______________________________________ 131 LoadEnvListener(void* pCheck , 132 LoadEnv* pLoadEnv) 133 { 134 m_ppCheck = &pCheck ; 135 m_pLoadEnv = pLoadEnv; 136 } 137 138 //_______________________________________ 139 // frame.XLoadEventListener 140 virtual void SAL_CALL loadFinished(const css::uno::Reference< css::frame::XFrameLoader >& xLoader) 141 throw(css::uno::RuntimeException); 142 143 virtual void SAL_CALL loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >& xLoader) 144 throw(css::uno::RuntimeException); 145 146 //_______________________________________ 147 // frame.XDispatchResultListener 148 virtual void SAL_CALL dispatchFinished(const css::frame::DispatchResultEvent& aEvent) 149 throw(css::uno::RuntimeException); 150 151 //_______________________________________ 152 // lang.XEventListener 153 virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent) 154 throw(css::uno::RuntimeException); 155 }; 156 157 /*----------------------------------------------- 158 14.10.2003 13:43 159 -----------------------------------------------*/ 160 LoadEnv::LoadEnv(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) 161 throw(LoadEnvException, css::uno::RuntimeException) 162 : ThreadHelpBase( ) 163 , m_xSMGR (xSMGR) 164 , m_pCheck (this ) 165 , m_pQuietInteraction( 0 ) 166 { 167 } 168 169 /*----------------------------------------------- 170 14.10.2003 13:43 171 -----------------------------------------------*/ 172 LoadEnv::~LoadEnv() 173 { 174 m_pCheck = 0; 175 } 176 177 /*----------------------------------------------- 178 10.09.2003 14:05 179 -----------------------------------------------*/ 180 css::uno::Reference< css::lang::XComponent > LoadEnv::loadComponentFromURL(const css::uno::Reference< css::frame::XComponentLoader >& xLoader, 181 const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , 182 const ::rtl::OUString& sURL , 183 const ::rtl::OUString& sTarget, 184 sal_Int32 nFlags , 185 const css::uno::Sequence< css::beans::PropertyValue >& lArgs ) 186 throw(css::lang::IllegalArgumentException, 187 css::io::IOException , 188 css::uno::RuntimeException ) 189 { 190 #ifdef WNT 191 CEnableAccessInterface e; 192 #endif 193 css::uno::Reference< css::lang::XComponent > xComponent; 194 195 try 196 { 197 LoadEnv aEnv(xSMGR); 198 199 aEnv.initializeLoading(sURL, 200 lArgs, 201 css::uno::Reference< css::frame::XFrame >(xLoader, css::uno::UNO_QUERY), 202 sTarget, 203 nFlags, 204 LoadEnv::E_NO_FEATURE); 205 aEnv.startLoading(); 206 aEnv.waitWhileLoading(); // wait for ever! 207 208 xComponent = aEnv.getTargetComponent(); 209 } 210 catch(const LoadEnvException& ex) 211 { 212 switch(ex.m_nID) 213 { 214 case LoadEnvException::ID_INVALID_MEDIADESCRIPTOR: 215 throw css::lang::IllegalArgumentException( 216 ::rtl::OUString::createFromAscii("Optional list of arguments seem to be corrupted."), 217 xLoader, 218 4); 219 220 case LoadEnvException::ID_UNSUPPORTED_CONTENT: 221 throw css::lang::IllegalArgumentException( 222 ::rtl::OUString::createFromAscii("URL seems to be an unsupported one."), 223 xLoader, 224 1); 225 226 default: xComponent.clear(); 227 break; 228 } 229 } 230 231 return xComponent; 232 } 233 234 //----------------------------------------------- 235 ::comphelper::MediaDescriptor impl_mergeMediaDescriptorWithMightExistingModelArgs(const css::uno::Sequence< css::beans::PropertyValue >& lOutsideDescriptor) 236 { 237 ::comphelper::MediaDescriptor lDescriptor(lOutsideDescriptor); 238 css::uno::Reference< css::frame::XModel > xModel = lDescriptor.getUnpackedValueOrDefault( 239 ::comphelper::MediaDescriptor::PROP_MODEL (), 240 css::uno::Reference< css::frame::XModel > ()); 241 if (xModel.is ()) 242 { 243 ::comphelper::MediaDescriptor lModelDescriptor(xModel->getArgs()); 244 ::comphelper::MediaDescriptor::iterator pIt = lModelDescriptor.find( ::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE() ); 245 if ( pIt != lModelDescriptor.end() ) 246 lDescriptor[::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()] = pIt->second; 247 } 248 249 return lDescriptor; 250 } 251 252 /*----------------------------------------------- 253 20.08.2003 09:49 254 -----------------------------------------------*/ 255 void LoadEnv::initializeLoading(const ::rtl::OUString& sURL , 256 const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor, 257 const css::uno::Reference< css::frame::XFrame >& xBaseFrame , 258 const ::rtl::OUString& sTarget , 259 sal_Int32 nSearchFlags , 260 EFeature eFeature , // => use default ... 261 EContentType eContentType ) // => use default ... 262 throw(LoadEnvException, css::uno::RuntimeException) 263 { 264 // SAFE -> ---------------------------------- 265 WriteGuard aWriteLock(m_aLock); 266 267 // Handle still running processes! 268 if (m_xAsynchronousJob.is()) 269 throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING); 270 271 // take over all new parameters. 272 m_xTargetFrame.clear(); 273 m_xBaseFrame = xBaseFrame ; 274 m_lMediaDescriptor = impl_mergeMediaDescriptorWithMightExistingModelArgs(lMediaDescriptor); 275 m_sTarget = sTarget ; 276 m_nSearchFlags = nSearchFlags ; 277 m_eFeature = eFeature ; 278 m_eContentType = eContentType ; 279 m_bCloseFrameOnError = sal_False ; 280 m_bReactivateControllerOnError = sal_False ; 281 m_bLoaded = sal_False ; 282 283 // try to find out, if its really a content, which can be loaded or must be "handled" 284 // We use a default value for this in-parameter. Then we have to start a complex check method 285 // internaly. But if this check was already done outside it can be suppressed to perform 286 // the load request. We take over the result then! 287 if (m_eContentType == E_UNSUPPORTED_CONTENT) 288 { 289 m_eContentType = LoadEnv::classifyContent(sURL, lMediaDescriptor); 290 if (m_eContentType == E_UNSUPPORTED_CONTENT) 291 throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT); 292 } 293 294 // make URL part of the MediaDescriptor 295 // It doesn't mater, if its already an item of it. 296 // It must be the same value ... so we can overwrite it :-) 297 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_URL()] <<= sURL; 298 299 // parse it - because some following code require that 300 m_aURL.Complete = sURL; 301 css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY); 302 xParser->parseStrict(m_aURL); 303 304 // BTW: Split URL and JumpMark ... 305 // Because such mark is an explicit value of the media descriptor! 306 if (m_aURL.Mark.getLength()) 307 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_JUMPMARK()] <<= m_aURL.Mark; 308 309 // By the way: remove the old and deprecated value "FileName" from the descriptor! 310 ::comphelper::MediaDescriptor::iterator pIt = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_FILENAME()); 311 if (pIt != m_lMediaDescriptor.end()) 312 m_lMediaDescriptor.erase(pIt); 313 314 // patch the MediaDescriptor, so it fulfill the outside requirements 315 // Means especially items like e.g. UI InteractionHandler, Status Indicator, 316 // MacroExecutionMode etcpp. 317 318 /*TODO progress is bound to a frame ... How can we set it here? */ 319 320 // UI mode 321 const bool bUIMode = 322 ( ( m_eFeature & E_WORK_WITH_UI ) == E_WORK_WITH_UI ) && 323 ( m_lMediaDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_HIDDEN() , sal_False ) == sal_False ) && 324 ( m_lMediaDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_PREVIEW(), sal_False ) == sal_False ); 325 326 initializeUIDefaults( 327 m_xSMGR, 328 m_lMediaDescriptor, 329 bUIMode, 330 &m_pQuietInteraction 331 ); 332 333 aWriteLock.unlock(); 334 // <- SAFE ---------------------------------- 335 } 336 337 /*----------------------------------------------- 338 22.01.2010 339 -----------------------------------------------*/ 340 void LoadEnv::initializeUIDefaults( const css::uno::Reference< css::lang::XMultiServiceFactory >& i_rSMGR, 341 ::comphelper::MediaDescriptor& io_lMediaDescriptor, const bool i_bUIMode, 342 QuietInteraction** o_ppQuietInteraction ) 343 { 344 css::uno::Reference< css::task::XInteractionHandler > xInteractionHandler; 345 sal_Int16 nMacroMode ; 346 sal_Int16 nUpdateMode ; 347 348 if ( i_bUIMode ) 349 { 350 nMacroMode = css::document::MacroExecMode::USE_CONFIG; 351 nUpdateMode = css::document::UpdateDocMode::ACCORDING_TO_CONFIG; 352 try 353 { 354 xInteractionHandler = css::uno::Reference< css::task::XInteractionHandler >(i_rSMGR->createInstance(IMPLEMENTATIONNAME_UIINTERACTIONHANDLER), css::uno::UNO_QUERY); 355 } 356 catch(const css::uno::RuntimeException&) {throw;} 357 catch(const css::uno::Exception& ) { } 358 } 359 // hidden mode 360 else 361 { 362 nMacroMode = css::document::MacroExecMode::NEVER_EXECUTE; 363 nUpdateMode = css::document::UpdateDocMode::NO_UPDATE; 364 QuietInteraction* pQuietInteraction = new QuietInteraction(); 365 xInteractionHandler = css::uno::Reference< css::task::XInteractionHandler >(static_cast< css::task::XInteractionHandler* >(pQuietInteraction), css::uno::UNO_QUERY); 366 if ( o_ppQuietInteraction != NULL ) 367 { 368 *o_ppQuietInteraction = pQuietInteraction; 369 (*o_ppQuietInteraction)->acquire(); 370 } 371 } 372 373 if ( 374 (xInteractionHandler.is() ) && 375 (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER()) == io_lMediaDescriptor.end()) 376 ) 377 { 378 io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER()] <<= xInteractionHandler; 379 io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_AUTHENTICATIONHANDLER()] <<= xInteractionHandler; 380 } 381 382 if (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()) == io_lMediaDescriptor.end()) 383 io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()] <<= nMacroMode; 384 385 if (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_UPDATEDOCMODE()) == io_lMediaDescriptor.end()) 386 io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_UPDATEDOCMODE()] <<= nUpdateMode; 387 } 388 389 /*----------------------------------------------- 390 15.08.2003 08:16 391 -----------------------------------------------*/ 392 void LoadEnv::startLoading() 393 throw(LoadEnvException, css::uno::RuntimeException) 394 { 395 // SAFE -> 396 ReadGuard aReadLock(m_aLock); 397 398 // Handle still running processes! 399 if (m_xAsynchronousJob.is()) 400 throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING); 401 402 // content can not be loaded or handled 403 // check "classifyContent()" failed before ... 404 if (m_eContentType == E_UNSUPPORTED_CONTENT) 405 throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT); 406 407 // <- SAFE 408 aReadLock.unlock(); 409 410 // detect its type/filter etcpp. 411 // These information will be available by the 412 // used descriptor member afterwards and is needed 413 // for all following operations! 414 // Note: An exception will be thrown, in case operation was not successfully ... 415 if (m_eContentType != E_CAN_BE_SET)/* Attention: special feature to set existing component on a frame must ignore type detection! */ 416 impl_detectTypeAndFilter(); 417 418 // start loading the content ... 419 // Attention: Dont check m_eContentType deeper then UNSUPPORTED/SUPPORTED! 420 // Because it was made in th easiest way ... may a flat detection was made only. 421 // And such simple detection can fail some times .-) 422 // Use another strategy here. Try it and let it run into the case "loading not possible". 423 sal_Bool bStarted = sal_False; 424 if ( 425 ((m_eFeature & E_ALLOW_CONTENTHANDLER) == E_ALLOW_CONTENTHANDLER) && 426 (m_eContentType != E_CAN_BE_SET ) /* Attention: special feature to set existing component on a frame must ignore type detection! */ 427 ) 428 { 429 bStarted = impl_handleContent(); 430 } 431 432 if (!bStarted) 433 bStarted = impl_loadContent(); 434 435 // not started => general error 436 // We can't say - what was the reason for. 437 if (!bStarted) 438 throw LoadEnvException(LoadEnvException::ID_GENERAL_ERROR); 439 } 440 441 /*----------------------------------------------- 442 15.08.2003 09:50 443 TODO 444 First draft does not implement timeout using [ms]. 445 Current implementation counts yield calls only ... 446 -----------------------------------------------*/ 447 sal_Bool LoadEnv::waitWhileLoading(sal_uInt32 nTimeout) 448 throw(LoadEnvException, css::uno::RuntimeException) 449 { 450 // Because its not a good idea to block the main thread 451 // (and we can't be sure that we are currently not used inside the 452 // main thread!), we can't use conditions here really. We must yield 453 // in an intellegent manner :-) 454 455 sal_Int32 nTime = nTimeout; 456 while(true) 457 { 458 // SAFE -> ------------------------------ 459 ReadGuard aReadLock1(m_aLock); 460 if (!m_xAsynchronousJob.is()) 461 break; 462 aReadLock1.unlock(); 463 // <- SAFE ------------------------------ 464 465 Application::Yield(); 466 467 // forever! 468 if (nTimeout==0) 469 continue; 470 471 // timed out? 472 --nTime; 473 if (nTime<1) 474 break; 475 } 476 477 // SAFE -> ---------------------------------- 478 ReadGuard aReadLock2(m_aLock); 479 return !m_xAsynchronousJob.is(); 480 // <- SAFE ---------------------------------- 481 } 482 483 /*----------------------------------------------- 484 20.08.2003 10:00 485 -----------------------------------------------*/ 486 void LoadEnv::cancelLoading() 487 throw(LoadEnvException, css::uno::RuntimeException) 488 { 489 // PARTIAL(!) SAFE -> ------------------------------ 490 ReadGuard aReadLock(m_aLock); 491 492 // Still running? Might waitWhileLoading() 493 // runned into the timeout! 494 if (m_xAsynchronousJob.is()) 495 { 496 // try to cancel it ... if its an asynchronous frame loader 497 css::uno::Reference< css::frame::XFrameLoader > xAsyncLoader(m_xAsynchronousJob, css::uno::UNO_QUERY); 498 if (xAsyncLoader.is()) 499 { 500 aReadLock.unlock(); 501 // <- BREAK SAFE ------------------------------ 502 xAsyncLoader->cancel(); 503 // <- RESTART SAFE ---------------------------- 504 aReadLock.lock(); 505 /* Attention: 506 After returning from any cancel/dispose call, neither the frame nor weself 507 may be called back. Because only we can cancel this job, we already know 508 the result! => Thats why its not useful nor necessary to wait for any 509 asynchronous listener notification. 510 */ 511 m_bLoaded = sal_False; 512 m_xAsynchronousJob.clear(); 513 } 514 // or may be its a content handler? Such handler can't be cancelled in its running 515 // operation :-( And we can't deregister us there again :-( 516 // => The only chance is an exception :-) 517 else 518 throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING); 519 } 520 521 impl_reactForLoadingState(); 522 523 aReadLock.unlock(); 524 // <- PARTIAL(!) SAFE ------------------------------ 525 } 526 527 /*----------------------------------------------- 528 14.08.2003 13:33 529 -----------------------------------------------*/ 530 css::uno::Reference< css::frame::XFrame > LoadEnv::getTarget() const 531 { 532 // SAFE -> 533 ReadGuard aReadLock(m_aLock); 534 return m_xTargetFrame; 535 // <- SAFE 536 } 537 538 /*----------------------------------------------- 539 14.08.2003 13:35 540 -----------------------------------------------*/ 541 css::uno::Reference< css::lang::XComponent > LoadEnv::getTargetComponent() const 542 { 543 // SAFE -> 544 ReadGuard aReadLock(m_aLock); 545 546 if (!m_xTargetFrame.is()) 547 return css::uno::Reference< css::lang::XComponent >(); 548 549 css::uno::Reference< css::frame::XController > xController = m_xTargetFrame->getController(); 550 if (!xController.is()) 551 return css::uno::Reference< css::lang::XComponent >(m_xTargetFrame->getComponentWindow(), css::uno::UNO_QUERY); 552 553 css::uno::Reference< css::frame::XModel > xModel = xController->getModel(); 554 if (!xModel.is()) 555 return css::uno::Reference< css::lang::XComponent >(xController, css::uno::UNO_QUERY); 556 557 return css::uno::Reference< css::lang::XComponent >(xModel, css::uno::UNO_QUERY); 558 // <- SAFE 559 } 560 561 /*----------------------------------------------- 562 15.08.2003 11:15 563 -----------------------------------------------*/ 564 void SAL_CALL LoadEnvListener::loadFinished(const css::uno::Reference< css::frame::XFrameLoader >&) 565 throw(css::uno::RuntimeException) 566 { 567 // SAFE -> ---------------------------------- 568 WriteGuard aWriteLock(m_aLock); 569 570 if (m_ppCheck && *m_ppCheck) 571 m_pLoadEnv->impl_setResult(sal_True); 572 m_ppCheck = NULL; 573 574 aWriteLock.unlock(); 575 // <- SAFE ---------------------------------- 576 } 577 578 /*----------------------------------------------- 579 14.10.2003 12:23 580 -----------------------------------------------*/ 581 void SAL_CALL LoadEnvListener::loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >&) 582 throw(css::uno::RuntimeException) 583 { 584 // SAFE -> ---------------------------------- 585 WriteGuard aWriteLock(m_aLock); 586 587 if (m_ppCheck && *m_ppCheck) 588 m_pLoadEnv->impl_setResult(sal_False); 589 m_ppCheck = NULL; 590 591 aWriteLock.unlock(); 592 // <- SAFE ---------------------------------- 593 } 594 595 /*----------------------------------------------- 596 14.10.2003 12:23 597 -----------------------------------------------*/ 598 void SAL_CALL LoadEnvListener::dispatchFinished(const css::frame::DispatchResultEvent& aEvent) 599 throw(css::uno::RuntimeException) 600 { 601 // SAFE -> ---------------------------------- 602 WriteGuard aWriteLock(m_aLock); 603 604 if (!m_ppCheck || !*m_ppCheck) 605 return; 606 607 switch(aEvent.State) 608 { 609 case css::frame::DispatchResultState::FAILURE : 610 m_pLoadEnv->impl_setResult(sal_False); 611 break; 612 613 case css::frame::DispatchResultState::SUCCESS : 614 m_pLoadEnv->impl_setResult(sal_False); 615 break; 616 617 case css::frame::DispatchResultState::DONTKNOW : 618 m_pLoadEnv->impl_setResult(sal_False); 619 break; 620 } 621 m_ppCheck = NULL; 622 623 aWriteLock.unlock(); 624 // <- SAFE ---------------------------------- 625 } 626 627 /*----------------------------------------------- 628 14.10.2003 12:24 629 -----------------------------------------------*/ 630 void SAL_CALL LoadEnvListener::disposing(const css::lang::EventObject&) 631 throw(css::uno::RuntimeException) 632 { 633 // SAFE -> ---------------------------------- 634 WriteGuard aWriteLock(m_aLock); 635 636 if (m_ppCheck && *m_ppCheck) 637 m_pLoadEnv->impl_setResult(sal_False); 638 m_ppCheck = NULL; 639 640 aWriteLock.unlock(); 641 // <- SAFE ---------------------------------- 642 } 643 644 /*----------------------------------------------- 645 14.10.2003 12:20 646 -----------------------------------------------*/ 647 void LoadEnv::impl_setResult(sal_Bool bResult) 648 { 649 // SAFE -> ---------------------------------- 650 WriteGuard aWriteLock(m_aLock); 651 652 m_bLoaded = bResult; 653 654 impl_reactForLoadingState(); 655 656 // clearing of this reference will unblock waitWhileLoading()! 657 // So we must be sure, that loading process was really finished. 658 // => do it as last operation of this method ... 659 m_xAsynchronousJob.clear(); 660 661 aWriteLock.unlock(); 662 // <- SAFE ---------------------------------- 663 } 664 665 /*----------------------------------------------- 666 06.02.2004 14:03 667 TODO: Is it a good idea to change Sequence<> 668 parameter to stl-adapter? 669 -----------------------------------------------*/ 670 LoadEnv::EContentType LoadEnv::classifyContent(const ::rtl::OUString& sURL , 671 const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor) 672 { 673 //------------------------------------------- 674 // (i) Filter some special well known URL protocols, 675 // which can not be handled or loaded in general. 676 // Of course an empty URL must be ignored here too. 677 // Note: These URL schemata are fix and well known ... 678 // But there can be some additional ones, which was not 679 // defined at implementation time of this class :-( 680 // So we have to make sure, that the following code 681 // can detect such protocol schemata too :-) 682 683 if( 684 (!sURL.getLength() ) || 685 (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_UNO )) || 686 (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_SLOT )) || 687 (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_MACRO )) || 688 (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_SERVICE)) || 689 (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_MAILTO )) || 690 (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_NEWS )) 691 ) 692 { 693 return E_UNSUPPORTED_CONTENT; 694 } 695 696 //------------------------------------------- 697 // (ii) Some special URLs indicates a given input stream, 698 // a full featured document model directly or 699 // specify a request for opening an empty document. 700 // Such contents are loadable in general. 701 // But we have to check, if the media descriptor contains 702 // all needed resources. If they are missing - the following 703 // load request will fail. 704 705 /* Attention: The following code can't work on such special URLs! 706 It should not break the office .. but it make no sense 707 to start expensive object creations and complex search 708 algorithm if its clear, that such URLs must be handled 709 in a special way .-) 710 */ 711 712 // creation of new documents 713 if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_FACTORY)) 714 return E_CAN_BE_LOADED; 715 716 // using of an existing input stream 717 ::comphelper::MediaDescriptor stlMediaDescriptor(lMediaDescriptor); 718 ::comphelper::MediaDescriptor::const_iterator pIt; 719 if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_STREAM)) 720 { 721 pIt = stlMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_INPUTSTREAM()); 722 css::uno::Reference< css::io::XInputStream > xStream; 723 if (pIt != stlMediaDescriptor.end()) 724 pIt->second >>= xStream; 725 if (xStream.is()) 726 return E_CAN_BE_LOADED; 727 LOG_WARNING("LoadEnv::classifyContent()", "loading from stream with right URL but invalid stream detected") 728 return E_UNSUPPORTED_CONTENT; 729 } 730 731 // using of a full featured document 732 if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_OBJECT)) 733 { 734 pIt = stlMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_MODEL()); 735 css::uno::Reference< css::frame::XModel > xModel; 736 if (pIt != stlMediaDescriptor.end()) 737 pIt->second >>= xModel; 738 if (xModel.is()) 739 return E_CAN_BE_SET; 740 LOG_WARNING("LoadEnv::classifyContent()", "loading with object with right URL but invalid object detected") 741 return E_UNSUPPORTED_CONTENT; 742 } 743 744 // following operatons can work on an internal type name only :-( 745 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::utl::getProcessServiceFactory(); 746 css::uno::Reference< css::document::XTypeDetection > xDetect(xSMGR->createInstance(SERVICENAME_TYPEDETECTION), css::uno::UNO_QUERY); 747 748 ::rtl::OUString sType = xDetect->queryTypeByURL(sURL); 749 750 css::uno::Sequence< css::beans::NamedValue > lQuery(1) ; 751 css::uno::Reference< css::container::XContainerQuery > xContainer ; 752 css::uno::Reference< css::container::XEnumeration > xSet ; 753 css::uno::Sequence< ::rtl::OUString > lTypesReg(1); 754 755 /* 756 //------------------------------------------- 757 lQuery[0].Name = ::framework::constant::Filter::PROP_TYPE; 758 lQuery[0].Value <<= sType; 759 760 xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_FILTERFACTORY), css::uno::UNO_QUERY); 761 xSet = xContainer->createSubSetEnumerationByProperties(lQuery); 762 // at least one registered frame loader is enough! 763 if (xSet->hasMoreElements()) 764 return E_CAN_BE_LOADED; 765 */ 766 767 //------------------------------------------- 768 // (iii) If a FrameLoader service (or at least 769 // a Filter) can be found, which supports 770 // this URL - it must be a loadable content. 771 // Because both items are registered for types 772 // its enough to check for frame loaders only. 773 // Mos of our filters are handled by our global 774 // default loader. But there exist some specialized 775 // loader, which does not work on top of filters! 776 // So its not enough to search on the filter configuration. 777 // Further its not enough to search for types! 778 // Because there exist some types, which are referenced by 779 // other objects ... but not by filters nor frame loaders! 780 781 lTypesReg[0] = sType; 782 lQuery[0].Name = ::framework::constant::FrameLoader::PROP_TYPES; 783 lQuery[0].Value <<= lTypesReg; 784 785 xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_FRAMELOADERFACTORY), css::uno::UNO_QUERY); 786 xSet = xContainer->createSubSetEnumerationByProperties(lQuery); 787 // at least one registered frame loader is enough! 788 if (xSet->hasMoreElements()) 789 return E_CAN_BE_LOADED; 790 791 //------------------------------------------- 792 // (iv) Some URL protocols are supported by special services. 793 // E.g. ContentHandler. 794 // Such contents can be handled ... but not loaded. 795 796 lTypesReg[0] = sType; 797 lQuery[0].Name = ::framework::constant::ContentHandler::PROP_TYPES; 798 lQuery[0].Value <<= lTypesReg; 799 800 xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_CONTENTHANDLERFACTORY), css::uno::UNO_QUERY); 801 xSet = xContainer->createSubSetEnumerationByProperties(lQuery); 802 // at least one registered content handler is enough! 803 if (xSet->hasMoreElements()) 804 return E_CAN_BE_HANDLED; 805 806 //------------------------------------------- 807 // (v) Last but not least the UCB is used inside office to 808 // load contents. He has a special configuration to know 809 // which URL schemata can be used inside office. 810 css::uno::Reference< css::ucb::XContentProviderManager > xUCB(xSMGR->createInstance(SERVICENAME_UCBCONTENTBROKER), css::uno::UNO_QUERY); 811 if (xUCB->queryContentProvider(sURL).is()) 812 return E_CAN_BE_LOADED; 813 814 //------------------------------------------- 815 // (TODO) At this point, we have no idea .-) 816 // But it seems to be better, to break all 817 // further requests for this URL. Otherwhise 818 // we can run into some trouble. 819 return E_UNSUPPORTED_CONTENT; 820 } 821 822 /*----------------------------------------------- 823 03.11.2003 09:31 824 -----------------------------------------------*/ 825 void LoadEnv::impl_detectTypeAndFilter() 826 throw(LoadEnvException, css::uno::RuntimeException) 827 { 828 static ::rtl::OUString TYPEPROP_PREFERREDFILTER = ::rtl::OUString::createFromAscii("PreferredFilter"); 829 static ::rtl::OUString FILTERPROP_FLAGS = ::rtl::OUString::createFromAscii("Flags" ); 830 static sal_Int32 FILTERFLAG_TEMPLATEPATH = 16; 831 832 // SAFE -> 833 ReadGuard aReadLock(m_aLock); 834 835 // Attention: Because our stl media descriptor is a copy of an uno sequence 836 // we can't use as an in/out parameter here. Copy it before and dont forget to 837 // update structure afterwards again! 838 css::uno::Sequence< css::beans::PropertyValue > lDescriptor = m_lMediaDescriptor.getAsConstPropertyValueList(); 839 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 840 841 aReadLock.unlock(); 842 // <- SAFE 843 844 ::rtl::OUString sType; 845 css::uno::Reference< css::document::XTypeDetection > xDetect(xSMGR->createInstance(SERVICENAME_TYPEDETECTION), css::uno::UNO_QUERY); 846 if (xDetect.is()) 847 sType = xDetect->queryTypeByDescriptor(lDescriptor, sal_True); /*TODO should deep detection be able for enable/disable it from outside? */ 848 849 // no valid content -> loading not possible 850 if (!sType.getLength()) 851 throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT); 852 853 // SAFE -> 854 WriteGuard aWriteLock(m_aLock); 855 856 // detection was successfully => update the descriptor member of this class 857 m_lMediaDescriptor << lDescriptor; 858 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME()] <<= sType; 859 // Is there an already detected (may be preselected) filter? 860 // see below ... 861 ::rtl::OUString sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_FILTERNAME(), ::rtl::OUString()); 862 863 aWriteLock.unlock(); 864 // <- SAFE 865 866 // But the type isn't enough. For loading sometimes we need more informations. 867 // E.g. for our "_default" feature, where we recylce any frame which contains 868 // and "Untitled" document, we must know if the new document is based on a template! 869 // But this information is available as a filter property only. 870 // => We must try(!) to detect the right filter for this load request. 871 // On the other side ... if no filter is available .. ignore it. 872 // Then the type information must be enough. 873 if (!sFilter.getLength()) 874 { 875 // no -> try to find a preferred filter for the detected type. 876 // Dont forget to updatet he media descriptor. 877 css::uno::Reference< css::container::XNameAccess > xTypeCont(xDetect, css::uno::UNO_QUERY_THROW); 878 try 879 { 880 ::comphelper::SequenceAsHashMap lTypeProps(xTypeCont->getByName(sType)); 881 sFilter = lTypeProps.getUnpackedValueOrDefault(TYPEPROP_PREFERREDFILTER, ::rtl::OUString()); 882 if (sFilter.getLength()) 883 { 884 // SAFE -> 885 aWriteLock.lock(); 886 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter; 887 aWriteLock.unlock(); 888 // <- SAFE 889 } 890 } 891 catch(const css::container::NoSuchElementException&) 892 {} 893 } 894 895 // check if the filter (if one exists) points to a template format filter. 896 // Then we have to add the property "AsTemplate". 897 // We need this information to decide afterwards if we can use a "recycle frame" 898 // for target "_default" or has to create a new one everytimes. 899 // On the other side we have to suppress that, if this property already exists 900 // and should trigger a special handling. Then the outside calli of this method here, 901 // has to know, what he is doing .-) 902 903 sal_Bool bIsOwnTemplate = sal_False; 904 if (sFilter.getLength()) 905 { 906 css::uno::Reference< css::container::XNameAccess > xFilterCont(xSMGR->createInstance(SERVICENAME_FILTERFACTORY), css::uno::UNO_QUERY_THROW); 907 try 908 { 909 ::comphelper::SequenceAsHashMap lFilterProps(xFilterCont->getByName(sFilter)); 910 sal_Int32 nFlags = lFilterProps.getUnpackedValueOrDefault(FILTERPROP_FLAGS, (sal_Int32)0); 911 bIsOwnTemplate = ((nFlags & FILTERFLAG_TEMPLATEPATH) == FILTERFLAG_TEMPLATEPATH); 912 } 913 catch(const css::container::NoSuchElementException&) 914 {} 915 } 916 if (bIsOwnTemplate) 917 { 918 // SAFE -> 919 aWriteLock.lock(); 920 // Dont overwrite external decisions! See comments before ... 921 ::comphelper::MediaDescriptor::const_iterator pAsTemplateItem = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_ASTEMPLATE()); 922 if (pAsTemplateItem == m_lMediaDescriptor.end()) 923 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_ASTEMPLATE()] <<= sal_True; 924 aWriteLock.unlock(); 925 // <- SAFE 926 } 927 } 928 929 /*----------------------------------------------- 930 15.08.2003 09:38 931 -----------------------------------------------*/ 932 sal_Bool LoadEnv::impl_handleContent() 933 throw(LoadEnvException, css::uno::RuntimeException) 934 { 935 // SAFE -> ----------------------------------- 936 ReadGuard aReadLock(m_aLock); 937 938 // the type must exist inside the descriptor ... otherwhise this class is implemented wrong :-) 939 ::rtl::OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_TYPENAME(), ::rtl::OUString()); 940 if (!sType.getLength()) 941 throw LoadEnvException(LoadEnvException::ID_INVALID_MEDIADESCRIPTOR); 942 943 // convert media descriptor and URL to right format for later interface call! 944 css::uno::Sequence< css::beans::PropertyValue > lDescriptor; 945 m_lMediaDescriptor >> lDescriptor; 946 css::util::URL aURL = m_aURL; 947 948 // get necessary container to query for a handler object 949 css::uno::Reference< css::lang::XMultiServiceFactory > xFactory(m_xSMGR->createInstance(SERVICENAME_CONTENTHANDLERFACTORY), css::uno::UNO_QUERY); 950 css::uno::Reference< css::container::XContainerQuery > xQuery (xFactory , css::uno::UNO_QUERY); 951 952 aReadLock.unlock(); 953 // <- SAFE ----------------------------------- 954 955 // query 956 css::uno::Sequence< ::rtl::OUString > lTypeReg(1); 957 lTypeReg[0] = sType; 958 959 css::uno::Sequence< css::beans::NamedValue > lQuery(1); 960 lQuery[0].Name = ::framework::constant::ContentHandler::PROP_TYPES; 961 lQuery[0].Value <<= lTypeReg; 962 963 css::uno::Reference< css::container::XEnumeration > xSet = xQuery->createSubSetEnumerationByProperties(lQuery); 964 while(xSet->hasMoreElements()) 965 { 966 ::comphelper::SequenceAsHashMap lProps (xSet->nextElement()); 967 ::rtl::OUString sHandler = lProps.getUnpackedValueOrDefault(::framework::constant::ContentHandler::PROP_NAME, ::rtl::OUString()); 968 969 css::uno::Reference< css::frame::XNotifyingDispatch > xHandler; 970 try 971 { 972 xHandler = css::uno::Reference< css::frame::XNotifyingDispatch >(xFactory->createInstance(sHandler), css::uno::UNO_QUERY); 973 if (!xHandler.is()) 974 continue; 975 } 976 catch(const css::uno::RuntimeException&) 977 { throw; } 978 catch(const css::uno::Exception&) 979 { continue; } 980 981 // SAFE -> ----------------------------------- 982 WriteGuard aWriteLock(m_aLock); 983 m_xAsynchronousJob = xHandler; 984 m_pCheck = this; 985 LoadEnvListener* pListener = new LoadEnvListener(m_pCheck, this); 986 aWriteLock.unlock(); 987 // <- SAFE ----------------------------------- 988 989 css::uno::Reference< css::frame::XDispatchResultListener > xListener(static_cast< css::frame::XDispatchResultListener* >(pListener), css::uno::UNO_QUERY); 990 xHandler->dispatchWithNotification(aURL, lDescriptor, xListener); 991 992 return sal_True; 993 } 994 995 return sal_False; 996 } 997 998 //----------------------------------------------- 999 sal_Bool LoadEnv::impl_furtherDocsAllowed() 1000 { 1001 // SAFE -> 1002 ReadGuard aReadLock(m_aLock); 1003 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 1004 aReadLock.unlock(); 1005 // <- SAFE 1006 1007 sal_Bool bAllowed = sal_True; 1008 1009 try 1010 { 1011 css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey( 1012 xSMGR, 1013 ::rtl::OUString::createFromAscii("org.openoffice.Office.Common/"), 1014 ::rtl::OUString::createFromAscii("Misc"), 1015 ::rtl::OUString::createFromAscii("MaxOpenDocuments"), 1016 ::comphelper::ConfigurationHelper::E_READONLY); 1017 1018 // NIL means: count of allowed documents = infinite ! 1019 // => return sal_True 1020 if ( ! aVal.hasValue()) 1021 bAllowed = sal_True; 1022 else 1023 { 1024 sal_Int32 nMaxOpenDocuments = 0; 1025 aVal >>= nMaxOpenDocuments; 1026 1027 css::uno::Reference< css::frame::XFramesSupplier > xDesktop( 1028 xSMGR->createInstance(SERVICENAME_DESKTOP), 1029 css::uno::UNO_QUERY_THROW); 1030 1031 FrameListAnalyzer aAnalyzer(xDesktop, 1032 css::uno::Reference< css::frame::XFrame >(), 1033 FrameListAnalyzer::E_HELP | 1034 FrameListAnalyzer::E_BACKINGCOMPONENT | 1035 FrameListAnalyzer::E_HIDDEN); 1036 1037 sal_Int32 nOpenDocuments = aAnalyzer.m_lOtherVisibleFrames.getLength(); 1038 bAllowed = (nOpenDocuments < nMaxOpenDocuments); 1039 } 1040 } 1041 catch(const css::uno::Exception&) 1042 { bAllowed = sal_True; } // !! internal errors are no reason to disturb the office from opening documents .-) 1043 1044 if ( ! bAllowed ) 1045 { 1046 // SAFE -> 1047 aReadLock.lock(); 1048 css::uno::Reference< css::task::XInteractionHandler > xInteraction = m_lMediaDescriptor.getUnpackedValueOrDefault( 1049 ::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER(), 1050 css::uno::Reference< css::task::XInteractionHandler >()); 1051 aReadLock.unlock(); 1052 // <- SAFE 1053 1054 if (xInteraction.is()) 1055 { 1056 css::uno::Any aInteraction; 1057 css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations(2); 1058 1059 comphelper::OInteractionAbort* pAbort = new comphelper::OInteractionAbort(); 1060 comphelper::OInteractionApprove* pApprove = new comphelper::OInteractionApprove(); 1061 1062 lContinuations[0] = css::uno::Reference< css::task::XInteractionContinuation >( 1063 static_cast< css::task::XInteractionContinuation* >(pAbort), 1064 css::uno::UNO_QUERY_THROW); 1065 lContinuations[1] = css::uno::Reference< css::task::XInteractionContinuation >( 1066 static_cast< css::task::XInteractionContinuation* >(pApprove), 1067 css::uno::UNO_QUERY_THROW); 1068 1069 css::task::ErrorCodeRequest aErrorCode; 1070 aErrorCode.ErrCode = ERRCODE_SFX_NOMOREDOCUMENTSALLOWED; 1071 aInteraction <<= aErrorCode; 1072 xInteraction->handle( InteractionRequest::CreateRequest(aInteraction, lContinuations) ); 1073 } 1074 } 1075 1076 return bAllowed; 1077 } 1078 1079 //----------------------------------------------- 1080 sal_Bool LoadEnv::impl_loadContent() 1081 throw(LoadEnvException, css::uno::RuntimeException) 1082 { 1083 // SAFE -> ----------------------------------- 1084 WriteGuard aWriteLock(m_aLock); 1085 1086 // search or create right target frame 1087 ::rtl::OUString sTarget = m_sTarget; 1088 if (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_DEFAULT)) 1089 { 1090 m_xTargetFrame = impl_searchAlreadyLoaded(); 1091 if (m_xTargetFrame.is()) 1092 { 1093 impl_setResult(sal_True); 1094 return sal_True; 1095 } 1096 m_xTargetFrame = impl_searchRecycleTarget(); 1097 } 1098 1099 if (! m_xTargetFrame.is()) 1100 { 1101 if ( 1102 (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_BLANK )) || 1103 (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_DEFAULT)) 1104 ) 1105 { 1106 if (! impl_furtherDocsAllowed()) 1107 return sal_False; 1108 m_xTargetFrame = m_xBaseFrame->findFrame(SPECIALTARGET_BLANK, 0); 1109 m_bCloseFrameOnError = m_xTargetFrame.is(); 1110 } 1111 else 1112 { 1113 sal_Int32 nFlags = m_nSearchFlags & ~css::frame::FrameSearchFlag::CREATE; 1114 m_xTargetFrame = m_xBaseFrame->findFrame(sTarget, nFlags); 1115 if (! m_xTargetFrame.is()) 1116 { 1117 if (! impl_furtherDocsAllowed()) 1118 return sal_False; 1119 m_xTargetFrame = m_xBaseFrame->findFrame(SPECIALTARGET_BLANK, 0); 1120 m_bCloseFrameOnError = m_xTargetFrame.is(); 1121 } 1122 } 1123 } 1124 1125 // If we couldn't find a valid frame or the frame has no container window 1126 // we have to throw an exception. 1127 if ( 1128 ( ! m_xTargetFrame.is() ) || 1129 ( ! m_xTargetFrame->getContainerWindow().is() ) 1130 ) 1131 throw LoadEnvException(LoadEnvException::ID_NO_TARGET_FOUND); 1132 1133 css::uno::Reference< css::frame::XFrame > xTargetFrame = m_xTargetFrame; 1134 1135 // Now we have a valid frame ... and type detection was already done. 1136 // We should apply the module dependend window position and size to the 1137 // frame window. 1138 impl_applyPersistentWindowState(xTargetFrame->getContainerWindow()); 1139 1140 // Don't forget to lock task for following load process. Otherwise it could die 1141 // during this operation runs by terminating the office or closing this task via api. 1142 // If we set this lock "close()" will return false and closing will be broken. 1143 // Attention: Don't forget to reset this lock again after finishing operation. 1144 // Otherwise task AND office couldn't die!!! 1145 // This includes gracefully handling of Exceptions (Runtime!) too ... 1146 // Thats why we use a specialized guard, which will reset the lock 1147 // if it will be run out of scope. 1148 1149 // Note further: ignore if this internal guard already contains a resource. 1150 // Might impl_searchRecylcTarget() set it before. But incase this impl-method wasn't used 1151 // and the target frame was new created ... this lock here must be set! 1152 css::uno::Reference< css::document::XActionLockable > xTargetLock(xTargetFrame, css::uno::UNO_QUERY); 1153 m_aTargetLock.setResource(xTargetLock); 1154 1155 // Add status indicator to descriptor. Loader can show an progresses then. 1156 // But don't do it, if loading should be hidden or preview is used ...! 1157 // So we prevent our code against wrong using. Why? 1158 // It could be, that using of this progress could make trouble. e.g. He make window visible ... 1159 // but shouldn't do that. But if no indicator is available ... nobody has a chance to do that! 1160 sal_Bool bHidden = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN() , sal_False ); 1161 sal_Bool bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_MINIMIZED() , sal_False ); 1162 sal_Bool bPreview = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_PREVIEW() , sal_False ); 1163 css::uno::Reference< css::task::XStatusIndicator > xProgress = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_STATUSINDICATOR(), css::uno::Reference< css::task::XStatusIndicator >()); 1164 1165 if (!bHidden && !bMinimized && !bPreview && !xProgress.is()) 1166 { 1167 // Note: its an optional interface! 1168 css::uno::Reference< css::task::XStatusIndicatorFactory > xProgressFactory(xTargetFrame, css::uno::UNO_QUERY); 1169 if (xProgressFactory.is()) 1170 { 1171 xProgress = xProgressFactory->createStatusIndicator(); 1172 if (xProgress.is()) 1173 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_STATUSINDICATOR()] <<= xProgress; 1174 } 1175 } 1176 1177 // convert media descriptor and URL to right format for later interface call! 1178 css::uno::Sequence< css::beans::PropertyValue > lDescriptor; 1179 m_lMediaDescriptor >> lDescriptor; 1180 ::rtl::OUString sURL = m_aURL.Complete; 1181 1182 // try to locate any interested frame loader 1183 css::uno::Reference< css::uno::XInterface > xLoader = impl_searchLoader(); 1184 css::uno::Reference< css::frame::XFrameLoader > xAsyncLoader(xLoader, css::uno::UNO_QUERY); 1185 css::uno::Reference< css::frame::XSynchronousFrameLoader > xSyncLoader (xLoader, css::uno::UNO_QUERY); 1186 1187 if (xAsyncLoader.is()) 1188 { 1189 // SAFE -> ----------------------------------- 1190 aWriteLock.lock(); 1191 m_xAsynchronousJob = xAsyncLoader; 1192 m_pCheck = this; 1193 LoadEnvListener* pListener = new LoadEnvListener(m_pCheck, this); 1194 aWriteLock.unlock(); 1195 // <- SAFE ----------------------------------- 1196 1197 css::uno::Reference< css::frame::XLoadEventListener > xListener(static_cast< css::frame::XLoadEventListener* >(pListener), css::uno::UNO_QUERY); 1198 xAsyncLoader->load(xTargetFrame, sURL, lDescriptor, xListener); 1199 1200 return sal_True; 1201 } 1202 else 1203 if (xSyncLoader.is()) 1204 { 1205 sal_Bool bResult = xSyncLoader->load(lDescriptor, xTargetFrame); 1206 // react for the result here, so the outside waiting 1207 // code can ask for it later. 1208 impl_setResult(bResult); 1209 // But the return value indicates a valid started(!) operation. 1210 // And thats true everxtimes, we reach this line :-) 1211 return sal_True; 1212 } 1213 1214 aWriteLock.unlock(); 1215 // <- SAFE 1216 1217 return sal_False; 1218 } 1219 1220 /*----------------------------------------------- 1221 06.02.2004 14:40 1222 -----------------------------------------------*/ 1223 css::uno::Reference< css::uno::XInterface > LoadEnv::impl_searchLoader() 1224 { 1225 // SAFE -> ----------------------------------- 1226 ReadGuard aReadLock(m_aLock); 1227 1228 // special mode to set an existing component on this frame 1229 // In such case the laoder is fix. It must be the SFX based implementation, 1230 // which can create a view on top of such xModel components :-) 1231 if (m_eContentType == E_CAN_BE_SET) 1232 { 1233 try 1234 { 1235 return m_xSMGR->createInstance(IMPLEMENTATIONNAME_GENERICFRAMELOADER); 1236 } 1237 catch(const css::uno::RuntimeException&) 1238 { throw; } 1239 catch(const css::uno::Exception&) 1240 {} 1241 throw LoadEnvException(LoadEnvException::ID_INVALID_ENVIRONMENT); 1242 } 1243 1244 // Otherwhise ... 1245 // We need this type information to locate an registered frame loader 1246 // Without such information we can't work! 1247 ::rtl::OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_TYPENAME(), ::rtl::OUString()); 1248 if (!sType.getLength()) 1249 throw LoadEnvException(LoadEnvException::ID_INVALID_MEDIADESCRIPTOR); 1250 1251 // try to locate any interested frame loader 1252 css::uno::Reference< css::lang::XMultiServiceFactory > xLoaderFactory(m_xSMGR->createInstance(SERVICENAME_FRAMELOADERFACTORY), css::uno::UNO_QUERY); 1253 css::uno::Reference< css::container::XContainerQuery > xQuery (xLoaderFactory , css::uno::UNO_QUERY); 1254 1255 aReadLock.unlock(); 1256 // <- SAFE ----------------------------------- 1257 1258 css::uno::Sequence< ::rtl::OUString > lTypesReg(1); 1259 lTypesReg[0] = sType; 1260 1261 css::uno::Sequence< css::beans::NamedValue > lQuery(1); 1262 lQuery[0].Name = ::framework::constant::FrameLoader::PROP_TYPES; 1263 lQuery[0].Value <<= lTypesReg; 1264 1265 css::uno::Reference< css::container::XEnumeration > xSet = xQuery->createSubSetEnumerationByProperties(lQuery); 1266 while(xSet->hasMoreElements()) 1267 { 1268 // try everyone ... 1269 // Ignore any loader, which makes trouble :-) 1270 ::comphelper::SequenceAsHashMap lLoaderProps(xSet->nextElement()); 1271 ::rtl::OUString sLoader = lLoaderProps.getUnpackedValueOrDefault(::framework::constant::FrameLoader::PROP_NAME, ::rtl::OUString()); 1272 css::uno::Reference< css::uno::XInterface > xLoader ; 1273 try 1274 { 1275 xLoader = xLoaderFactory->createInstance(sLoader); 1276 if (xLoader.is()) 1277 return xLoader; 1278 } 1279 catch(const css::uno::RuntimeException&) 1280 { throw; } 1281 catch(const css::uno::Exception&) 1282 { continue; } 1283 } 1284 1285 return css::uno::Reference< css::uno::XInterface >(); 1286 } 1287 1288 /*----------------------------------------------- 1289 24.01.2006 15:11 1290 -----------------------------------------------*/ 1291 void LoadEnv::impl_jumpToMark(const css::uno::Reference< css::frame::XFrame >& xFrame, 1292 const css::util::URL& aURL ) 1293 { 1294 if (! aURL.Mark.getLength()) 1295 return; 1296 1297 css::uno::Reference< css::frame::XDispatchProvider > xProvider(xFrame, css::uno::UNO_QUERY); 1298 if (! xProvider.is()) 1299 return; 1300 1301 // SAFE -> 1302 ReadGuard aReadLock(m_aLock); 1303 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 1304 aReadLock.unlock(); 1305 // <- SAFE 1306 1307 css::util::URL aCmd; 1308 aCmd.Complete = ::rtl::OUString::createFromAscii(".uno:JumpToMark"); 1309 1310 css::uno::Reference< css::util::XURLTransformer > xParser(xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY_THROW); 1311 xParser->parseStrict(aCmd); 1312 1313 css::uno::Reference< css::frame::XDispatch > xDispatcher = xProvider->queryDispatch(aCmd, SPECIALTARGET_SELF, 0); 1314 if (! xDispatcher.is()) 1315 return; 1316 1317 ::comphelper::SequenceAsHashMap lArgs; 1318 lArgs[::rtl::OUString::createFromAscii("Bookmark")] <<= aURL.Mark; 1319 xDispatcher->dispatch(aCmd, lArgs.getAsConstPropertyValueList()); 1320 } 1321 1322 /*----------------------------------------------- 1323 31.07.2003 09:02 1324 -----------------------------------------------*/ 1325 css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchAlreadyLoaded() 1326 throw(LoadEnvException, css::uno::RuntimeException) 1327 { 1328 // SAFE -> 1329 ReadGuard aReadLock(m_aLock); 1330 1331 // such search is allowed for special requests only ... 1332 // or better its not allowed for some requests in general :-) 1333 if ( 1334 ( ! TargetHelper::matchSpecialTarget(m_sTarget, TargetHelper::E_DEFAULT) ) || 1335 (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_ASTEMPLATE() , sal_False) == sal_True) || 1336 // (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN() , sal_False) == sal_True) || 1337 (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_OPENNEWVIEW(), sal_False) == sal_True) 1338 ) 1339 { 1340 return css::uno::Reference< css::frame::XFrame >(); 1341 } 1342 1343 // check URL 1344 // May its not useful to start expensive document search, if it 1345 // can fail only .. because we load from a stream or model directly! 1346 if ( 1347 (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_STREAM )) || 1348 (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_OBJECT )) 1349 /*TODO should be private:factory here tested too? */ 1350 ) 1351 { 1352 return css::uno::Reference< css::frame::XFrame >(); 1353 } 1354 1355 // otherwhise - iterate through the tasks of the desktop container 1356 // to find out, which of them might contains the requested document 1357 css::uno::Reference< css::frame::XFramesSupplier > xSupplier(m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY); 1358 css::uno::Reference< css::container::XIndexAccess > xTaskList(xSupplier->getFrames() , css::uno::UNO_QUERY); 1359 1360 if (!xTaskList.is()) 1361 return css::uno::Reference< css::frame::XFrame >(); // task list can be empty! 1362 1363 // Note: To detect if a document was alrady loaded before 1364 // we check URLs here only. But might the existing and the required 1365 // document has different versions! Then its URLs are the same ... 1366 sal_Int16 nNewVersion = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_VERSION(), (sal_Int16)(-1)); 1367 1368 // will be used to save the first hidden frame referring the searched model 1369 // Normally we are interested in visible frames ... but if there is no such visible 1370 // frame we refer to any hidden frame also (but as fallback only). 1371 css::uno::Reference< css::frame::XFrame > xHiddenTask; 1372 css::uno::Reference< css::frame::XFrame > xTask; 1373 1374 sal_Int32 count = xTaskList->getCount(); 1375 for (sal_Int32 i=0; i<count; ++i) 1376 { 1377 try 1378 { 1379 // locate model of task 1380 // Note: Without a model there is no chance to decide if 1381 // this task contains the searched document or not! 1382 xTaskList->getByIndex(i) >>= xTask; 1383 if (!xTask.is()) 1384 continue; 1385 1386 css::uno::Reference< css::frame::XController > xController = xTask->getController(); 1387 if (!xController.is()) 1388 { 1389 xTask.clear (); 1390 continue; 1391 } 1392 1393 css::uno::Reference< css::frame::XModel > xModel = xController->getModel(); 1394 if (!xModel.is()) 1395 { 1396 xTask.clear (); 1397 continue; 1398 } 1399 1400 // don't check the complete URL here. 1401 // use its main part - ignore optional jumpmarks! 1402 const ::rtl::OUString sURL = xModel->getURL(); 1403 if (!::utl::UCBContentHelper::EqualURLs( m_aURL.Main, sURL )) 1404 { 1405 xTask.clear (); 1406 continue; 1407 } 1408 1409 // get the original load arguments from the current document 1410 // and decide if its really the same then the one will be. 1411 // It must be visible and must use the same file revision ... 1412 // or must not have any file revision set (-1 == -1!) 1413 ::comphelper::MediaDescriptor lOldDocDescriptor(xModel->getArgs()); 1414 1415 if (lOldDocDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_VERSION(), (sal_Int32)(-1)) != nNewVersion) 1416 { 1417 xTask.clear (); 1418 continue; 1419 } 1420 1421 // Hidden frames are special. 1422 // They will be used as "last chance" if there is no visible frame pointing to the same model. 1423 // Safe the result but continue with current loop might be looking for other visible frames. 1424 ::sal_Bool bIsHidden = lOldDocDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False); 1425 if ( 1426 ( bIsHidden ) && 1427 ( ! xHiddenTask.is()) 1428 ) 1429 { 1430 xHiddenTask = xTask; 1431 xTask.clear (); 1432 continue; 1433 } 1434 1435 // We found a visible task pointing to the right model ... 1436 // Break search. 1437 break; 1438 } 1439 catch(const css::uno::RuntimeException& exRun) 1440 { throw exRun; } 1441 catch(const css::uno::Exception&) 1442 { continue; } 1443 } 1444 1445 css::uno::Reference< css::frame::XFrame > xResult; 1446 if (xTask.is()) 1447 xResult = xTask; 1448 else 1449 if (xHiddenTask.is()) 1450 xResult = xHiddenTask; 1451 1452 if (xResult.is()) 1453 { 1454 // Now we are sure, that this task includes the searched document. 1455 // It's time to activate it. As special feature we try to jump internaly 1456 // if an optional jumpmark is given too. 1457 if (m_aURL.Mark.getLength()) 1458 impl_jumpToMark(xResult, m_aURL); 1459 1460 // bring it to front and make sure it's visible... 1461 impl_makeFrameWindowVisible(xResult->getContainerWindow(), sal_True); 1462 } 1463 1464 aReadLock.unlock(); 1465 // <- SAFE 1466 1467 return xResult; 1468 } 1469 1470 /*----------------------------------------------- 1471 30.03.2004 09:12 1472 -----------------------------------------------*/ 1473 sal_Bool LoadEnv::impl_isFrameAlreadyUsedForLoading(const css::uno::Reference< css::frame::XFrame >& xFrame) const 1474 { 1475 css::uno::Reference< css::document::XActionLockable > xLock(xFrame, css::uno::UNO_QUERY); 1476 1477 // ? no lock interface ? 1478 // Might its an external written frame implementation :-( 1479 // Allowing using of it ... but it can fail if its not synchronized with our processes ! 1480 if (!xLock.is()) 1481 return sal_False; 1482 1483 // Otherwhise we have to look for any other existing lock. 1484 return xLock->isActionLocked(); 1485 } 1486 1487 /*----------------------------------------------- 1488 30.03.2004 09:12 1489 -----------------------------------------------*/ 1490 css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchRecycleTarget() 1491 throw(LoadEnvException, css::uno::RuntimeException) 1492 { 1493 // SAFE -> .................................. 1494 ReadGuard aReadLock(m_aLock); 1495 1496 // The special backing mode frame will be recycled by definition! 1497 // It does'nt matter if somehwere whish to create a new view 1498 // or open a new untitled document ... 1499 // The only exception form that - hidden frames! 1500 if (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False) == sal_True) 1501 return css::uno::Reference< css::frame::XFrame >(); 1502 1503 css::uno::Reference< css::frame::XFramesSupplier > xSupplier(m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY); 1504 FrameListAnalyzer aTasksAnalyzer(xSupplier, css::uno::Reference< css::frame::XFrame >(), FrameListAnalyzer::E_BACKINGCOMPONENT); 1505 if (aTasksAnalyzer.m_xBackingComponent.is()) 1506 { 1507 if (!impl_isFrameAlreadyUsedForLoading(aTasksAnalyzer.m_xBackingComponent)) 1508 { 1509 // bring it to front ... 1510 impl_makeFrameWindowVisible(aTasksAnalyzer.m_xBackingComponent->getContainerWindow(), sal_True); 1511 return aTasksAnalyzer.m_xBackingComponent; 1512 } 1513 } 1514 1515 // These states indicates the wishing for creation of a new view in general. 1516 if ( 1517 (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_ASTEMPLATE() , sal_False) == sal_True) || 1518 (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_OPENNEWVIEW(), sal_False) == sal_True) 1519 ) 1520 { 1521 return css::uno::Reference< css::frame::XFrame >(); 1522 } 1523 1524 // On the other side some special URLs will open a new frame everytimes (expecting 1525 // they can use the backing-mode frame!) 1526 if ( 1527 (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_FACTORY )) || 1528 (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_STREAM )) || 1529 (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_OBJECT )) 1530 ) 1531 { 1532 return css::uno::Reference< css::frame::XFrame >(); 1533 } 1534 1535 // No backing frame! No special URL => recycle active task - if possible. 1536 // Means - if it does not already contains a modified document, or 1537 // use another office module. 1538 css::uno::Reference< css::frame::XFrame > xTask = xSupplier->getActiveFrame(); 1539 1540 // not a real error - but might a focus problem! 1541 if (!xTask.is()) 1542 return css::uno::Reference< css::frame::XFrame >(); 1543 1544 // not a real error - may its a view only 1545 css::uno::Reference< css::frame::XController > xController = xTask->getController(); 1546 if (!xController.is()) 1547 return css::uno::Reference< css::frame::XFrame >(); 1548 1549 // not a real error - may its a db component instead of a full feartured office document 1550 css::uno::Reference< css::frame::XModel > xModel = xController->getModel(); 1551 if (!xModel.is()) 1552 return css::uno::Reference< css::frame::XFrame >(); 1553 1554 // get some more informations ... 1555 1556 // A valid set URL means: there is already a location for this document. 1557 // => it was saved there or opened from there. Such Documents can not be used here. 1558 // We search for empty document ... created by a private:factory/ URL! 1559 if (xModel->getURL().getLength()>0) 1560 return css::uno::Reference< css::frame::XFrame >(); 1561 1562 // The old document must be unmodified ... 1563 css::uno::Reference< css::util::XModifiable > xModified(xModel, css::uno::UNO_QUERY); 1564 if (xModified->isModified()) 1565 return css::uno::Reference< css::frame::XFrame >(); 1566 1567 Window* pWindow = VCLUnoHelper::GetWindow(xTask->getContainerWindow()); 1568 if (pWindow && pWindow->IsInModalMode()) 1569 return css::uno::Reference< css::frame::XFrame >(); 1570 1571 // find out the application type of this document 1572 // We can recycle only documents, which uses the same application 1573 // then the new one. 1574 SvtModuleOptions::EFactory eOldApp = SvtModuleOptions::ClassifyFactoryByModel(xModel); 1575 SvtModuleOptions::EFactory eNewApp = SvtModuleOptions::ClassifyFactoryByURL (m_aURL.Complete, m_lMediaDescriptor.getAsConstPropertyValueList()); 1576 1577 aReadLock.unlock(); 1578 // <- SAFE .................................. 1579 1580 if (eOldApp != eNewApp) 1581 return css::uno::Reference< css::frame::XFrame >(); 1582 1583 // OK this task seams to be useable for recycling 1584 // But we should mark it as such - means set an action lock. 1585 // Otherwhise it would be used more then ones or will be destroyed 1586 // by a close() or terminate() request. 1587 // But if such lock already exist ... it means this task is used for 1588 // any other operation already. Don't use it then. 1589 if (impl_isFrameAlreadyUsedForLoading(xTask)) 1590 return css::uno::Reference< css::frame::XFrame >(); 1591 1592 // OK - there is a valid target frame. 1593 // But may be it contains already a document. 1594 // Then we have to ask it, if it allows recylcing of this frame .-) 1595 sal_Bool bReactivateOldControllerOnError = sal_False; 1596 css::uno::Reference< css::frame::XController > xOldDoc = xTask->getController(); 1597 if (xOldDoc.is()) 1598 { 1599 bReactivateOldControllerOnError = xOldDoc->suspend(sal_True); 1600 if (! bReactivateOldControllerOnError) 1601 return css::uno::Reference< css::frame::XFrame >(); 1602 } 1603 1604 // SAFE -> .................................. 1605 WriteGuard aWriteLock(m_aLock); 1606 1607 css::uno::Reference< css::document::XActionLockable > xLock(xTask, css::uno::UNO_QUERY); 1608 if (!m_aTargetLock.setResource(xLock)) 1609 return css::uno::Reference< css::frame::XFrame >(); 1610 1611 m_bReactivateControllerOnError = bReactivateOldControllerOnError; 1612 aWriteLock.unlock(); 1613 // <- SAFE .................................. 1614 1615 // bring it to front ... 1616 impl_makeFrameWindowVisible(xTask->getContainerWindow(), sal_True); 1617 1618 return xTask; 1619 } 1620 1621 /*----------------------------------------------- 1622 15.08.2003 12:39 1623 -----------------------------------------------*/ 1624 void LoadEnv::impl_reactForLoadingState() 1625 throw(LoadEnvException, css::uno::RuntimeException) 1626 { 1627 /*TODO reset action locks */ 1628 1629 // SAFE -> ---------------------------------- 1630 ReadGuard aReadLock(m_aLock); 1631 1632 if (m_bLoaded) 1633 { 1634 // Bring the new loaded document to front (if allowed!). 1635 // Note: We show new created frames here only. 1636 // We dont hide already visible frames here ... 1637 css::uno::Reference< css::awt::XWindow > xWindow = m_xTargetFrame->getContainerWindow(); 1638 sal_Bool bHidden = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False); 1639 sal_Bool bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_MINIMIZED(), sal_False); 1640 1641 if (bMinimized) 1642 { 1643 ::vos::OClearableGuard aSolarGuard(Application::GetSolarMutex()); 1644 Window* pWindow = VCLUnoHelper::GetWindow(xWindow); 1645 // check for system window is necessary to guarantee correct pointer cast! 1646 if (pWindow && pWindow->IsSystemWindow()) 1647 ((WorkWindow*)pWindow)->Minimize(); 1648 } 1649 else 1650 if (!bHidden) 1651 { 1652 // show frame ... if it's not still visible ... 1653 // But do nothing if it's already visible! 1654 impl_makeFrameWindowVisible(xWindow, sal_False); 1655 } 1656 1657 // Note: Only if an existing property "FrameName" is given by this media descriptor, 1658 // it should be used. Otherwhise we should do nothing. May be the outside code has already 1659 // set a frame name on the target! 1660 ::comphelper::MediaDescriptor::const_iterator pFrameName = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_FRAMENAME()); 1661 if (pFrameName != m_lMediaDescriptor.end()) 1662 { 1663 ::rtl::OUString sFrameName; 1664 pFrameName->second >>= sFrameName; 1665 // Check the name again. e.g. "_default" isn't allowed. 1666 // On the other side "_beamer" is a valid name :-) 1667 if (TargetHelper::isValidNameForFrame(sFrameName)) 1668 m_xTargetFrame->setName(sFrameName); 1669 } 1670 } 1671 else if (m_bReactivateControllerOnError) 1672 { 1673 // Try to reactivate the old document (if any exists!) 1674 css::uno::Reference< css::frame::XController > xOldDoc = m_xTargetFrame->getController(); 1675 // clear does not depend from reactivation state of a might existing old document! 1676 // We must make sure, that a might following getTargetComponent() call does not return 1677 // the old document! 1678 m_xTargetFrame.clear(); 1679 if (xOldDoc.is()) 1680 { 1681 sal_Bool bReactivated = xOldDoc->suspend(sal_False); 1682 if (!bReactivated) 1683 throw LoadEnvException(LoadEnvException::ID_COULD_NOT_REACTIVATE_CONTROLLER); 1684 m_bReactivateControllerOnError = sal_False; 1685 } 1686 } 1687 else if (m_bCloseFrameOnError) 1688 { 1689 // close empty frames 1690 css::uno::Reference< css::util::XCloseable > xCloseable (m_xTargetFrame, css::uno::UNO_QUERY); 1691 css::uno::Reference< css::lang::XComponent > xDisposable(m_xTargetFrame, css::uno::UNO_QUERY); 1692 1693 try 1694 { 1695 if (xCloseable.is()) 1696 xCloseable->close(sal_True); 1697 else 1698 if (xDisposable.is()) 1699 xDisposable->dispose(); 1700 } 1701 catch(const css::util::CloseVetoException&) 1702 {} 1703 catch(const css::lang::DisposedException&) 1704 {} 1705 m_xTargetFrame.clear(); 1706 } 1707 1708 // This max force an implicit closing of our target frame ... 1709 // e.g. in case close(sal_True) was called before and the frame 1710 // kill itself if our external use-lock is released here! 1711 // Thats why we releas this lock AFTER ALL OPERATIONS on this frame 1712 // are finished. The frame itslef must handle then 1713 // this situation gracefully. 1714 m_aTargetLock.freeResource(); 1715 1716 // Last but not least :-) 1717 // We have to clear the current media descriptor. 1718 // Otherwhise it hold a might existing stream open! 1719 m_lMediaDescriptor.clear(); 1720 1721 css::uno::Any aRequest; 1722 bool bThrow = false; 1723 if ( !m_bLoaded && m_pQuietInteraction && m_pQuietInteraction->wasUsed() ) 1724 { 1725 aRequest = m_pQuietInteraction->getRequest(); 1726 m_pQuietInteraction->release(); 1727 m_pQuietInteraction = 0; 1728 bThrow = true; 1729 } 1730 1731 aReadLock.unlock(); 1732 1733 if (bThrow) 1734 { 1735 if ( aRequest.isExtractableTo( ::cppu::UnoType< css::uno::Exception >::get() ) ) 1736 throw LoadEnvException( LoadEnvException::ID_GENERAL_ERROR, aRequest ); 1737 } 1738 1739 // <- SAFE ---------------------------------- 1740 } 1741 1742 /*----------------------------------------------- 1743 16.01.2005 13:04 1744 -----------------------------------------------*/ 1745 void LoadEnv::impl_makeFrameWindowVisible(const css::uno::Reference< css::awt::XWindow >& xWindow , 1746 sal_Bool bForceToFront) 1747 { 1748 // SAFE -> ---------------------------------- 1749 ReadGuard aReadLock(m_aLock); 1750 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xSMGR.get(), css::uno::UNO_QUERY ); 1751 aReadLock.unlock(); 1752 // <- SAFE ---------------------------------- 1753 1754 ::vos::OClearableGuard aSolarGuard(Application::GetSolarMutex()); 1755 Window* pWindow = VCLUnoHelper::GetWindow(xWindow); 1756 if ( pWindow ) 1757 { 1758 bool bForceFrontAndFocus(false); 1759 css::uno::Any a = ::comphelper::ConfigurationHelper::readDirectKey( 1760 xSMGR, 1761 ::rtl::OUString::createFromAscii("org.openoffice.Office.Common/View"), 1762 ::rtl::OUString::createFromAscii("NewDocumentHandling"), 1763 ::rtl::OUString::createFromAscii("ForceFocusAndToFront"), 1764 ::comphelper::ConfigurationHelper::E_READONLY); 1765 a >>= bForceFrontAndFocus; 1766 1767 if( pWindow->IsVisible() && (bForceFrontAndFocus || bForceToFront) ) 1768 pWindow->ToTop(); 1769 else 1770 pWindow->Show(sal_True, (bForceFrontAndFocus || bForceToFront) ? SHOW_FOREGROUNDTASK : 0 ); 1771 } 1772 1773 /* #i19976# 1774 We tried to prevent a toFront() call in case the user putted the 1775 loading document into the background .. 1776 But we had several errors trying that. So we decided to 1777 rollback these changes and bring the new loaded document to front hardly ! 1778 1779 css::uno::Reference< css::awt::XWindow2 > xWindow2(xWindow, css::uno::UNO_QUERY); 1780 1781 sal_Bool bIsVisible = sal_False; 1782 if (xWindow2.is()) 1783 bIsVisible = xWindow2->isVisible(); // TODO is parent visible too ? .-) 1784 1785 if (!bIsVisible) 1786 { 1787 xWindow->setVisible(sal_True); 1788 bForceToFront = sal_True; 1789 } 1790 1791 if ( 1792 (bForceToFront ) && 1793 (xTopWindow.is()) 1794 ) 1795 { 1796 xTopWindow->toFront(); 1797 } 1798 */ 1799 } 1800 1801 /*----------------------------------------------- 1802 15.03.2005 11:12 1803 -----------------------------------------------*/ 1804 void LoadEnv::impl_applyPersistentWindowState(const css::uno::Reference< css::awt::XWindow >& xWindow) 1805 { 1806 static ::rtl::OUString PACKAGE_SETUP_MODULES = ::rtl::OUString::createFromAscii("/org.openoffice.Setup/Office/Factories"); 1807 1808 // no window -> action not possible 1809 if (!xWindow.is()) 1810 return; 1811 1812 // window already visible -> do nothing! If we use a "recycle frame" for loading ... 1813 // the current position and size must be used. 1814 css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(xWindow, css::uno::UNO_QUERY); 1815 if ( 1816 (xVisibleCheck.is() ) && 1817 (xVisibleCheck->isVisible()) 1818 ) 1819 return; 1820 1821 // SOLAR SAFE -> 1822 ::vos::OClearableGuard aSolarLock1(Application::GetSolarMutex()); 1823 1824 Window* pWindow = VCLUnoHelper::GetWindow(xWindow); 1825 sal_Bool bSystemWindow = pWindow->IsSystemWindow(); 1826 sal_Bool bWorkWindow = (pWindow->GetType() == WINDOW_WORKWINDOW); 1827 1828 if (!bSystemWindow && !bWorkWindow) 1829 return; 1830 1831 // dont overwrite this special state! 1832 WorkWindow* pWorkWindow = (WorkWindow*)pWindow; 1833 if (pWorkWindow->IsMinimized()) 1834 return; 1835 1836 aSolarLock1.clear(); 1837 // <- SOLAR SAFE 1838 1839 // SAFE -> 1840 ReadGuard aReadLock(m_aLock); 1841 1842 // no filter -> no module -> no persistent window state 1843 ::rtl::OUString sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault( 1844 ::comphelper::MediaDescriptor::PROP_FILTERNAME(), 1845 ::rtl::OUString()); 1846 if (!sFilter.getLength()) 1847 return; 1848 1849 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 1850 1851 aReadLock.unlock(); 1852 // <- SAFE 1853 1854 try 1855 { 1856 // retrieve the module name from the filter configuration 1857 css::uno::Reference< css::container::XNameAccess > xFilterCfg( 1858 xSMGR->createInstance(SERVICENAME_FILTERFACTORY), 1859 css::uno::UNO_QUERY_THROW); 1860 ::comphelper::SequenceAsHashMap lProps (xFilterCfg->getByName(sFilter)); 1861 ::rtl::OUString sModule = lProps.getUnpackedValueOrDefault(FILTER_PROPNAME_DOCUMENTSERVICE, ::rtl::OUString()); 1862 1863 // get access to the configuration of this office module 1864 css::uno::Reference< css::container::XNameAccess > xModuleCfg(::comphelper::ConfigurationHelper::openConfig( 1865 xSMGR, 1866 PACKAGE_SETUP_MODULES, 1867 ::comphelper::ConfigurationHelper::E_READONLY), 1868 css::uno::UNO_QUERY_THROW); 1869 1870 // read window state from the configuration 1871 // and apply it on the window. 1872 // Do nothing, if no configuration entry exists! 1873 ::rtl::OUString sWindowState ; 1874 ::comphelper::ConfigurationHelper::readRelativeKey(xModuleCfg, sModule, OFFICEFACTORY_PROPNAME_WINDOWATTRIBUTES) >>= sWindowState; 1875 if (sWindowState.getLength()) 1876 { 1877 // SOLAR SAFE -> 1878 ::vos::OClearableGuard aSolarLock2(Application::GetSolarMutex()); 1879 1880 // We have to retrieve the window pointer again. Because nobody can guarantee 1881 // that the XWindow was not disposed inbetween .-) 1882 // But if we get a valid pointer we can be sure, that it's the system window pointer 1883 // we already checked and used before. Because nobody recylce the same uno reference for 1884 // a new internal c++ implementation ... hopefully .-)) 1885 Window* pWindowCheck = VCLUnoHelper::GetWindow(xWindow); 1886 if (! pWindowCheck) 1887 return; 1888 1889 SystemWindow* pSystemWindow = (SystemWindow*)pWindowCheck; 1890 pSystemWindow->SetWindowState(U2B_ENC(sWindowState,RTL_TEXTENCODING_UTF8)); 1891 1892 aSolarLock2.clear(); 1893 // <- SOLAR SAFE 1894 } 1895 } 1896 catch(const css::uno::RuntimeException& exRun) 1897 { throw exRun; } 1898 catch(const css::uno::Exception&) 1899 {} 1900 } 1901 1902 } // namespace framework 1903 1904