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 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_framework.hxx" 30 //_______________________________________________ 31 // includes of own project 32 #include <loadenv/loadenv.hxx> 33 34 #ifndef __FRAMEWORK_LOADENV_TARGETHELPER_HXX_ 35 #include <loadenv/targethelper.hxx> 36 #endif 37 #include <framework/framelistanalyzer.hxx> 38 39 #ifndef __FRAMEWORK_CONSTANT_FRAMELOADER_HXX_ 40 #include <constant/frameloader.hxx> 41 #endif 42 43 #ifndef __FRAMEWORK_CONSTANT_CONTENTHANDLER_HXX_ 44 #include <constant/contenthandler.hxx> 45 #endif 46 47 #ifndef __FRAMEWORK_CONSTANT_CONTAINERQUERY_HXX_ 48 #include <constant/containerquery.hxx> 49 #endif 50 #include <interaction/quietinteraction.hxx> 51 #include <threadhelp/writeguard.hxx> 52 #include <threadhelp/readguard.hxx> 53 #include <threadhelp/resetableguard.hxx> 54 #include <properties.h> 55 #include <protocols.h> 56 #include <services.h> 57 #include <comphelper/interaction.hxx> 58 #include <framework/interaction.hxx> 59 60 //_______________________________________________ 61 // includes of uno interface 62 #include <com/sun/star/task/ErrorCodeRequest.hpp> 63 #include <com/sun/star/uno/RuntimeException.hpp> 64 #include <com/sun/star/frame/DispatchResultState.hpp> 65 #include <com/sun/star/frame/FrameSearchFlag.hpp> 66 #include <com/sun/star/util/XURLTransformer.hpp> 67 #include <com/sun/star/ucb/XContentProviderManager.hpp> 68 #include <com/sun/star/util/XCloseable.hpp> 69 #include <com/sun/star/lang/XComponent.hpp> 70 #include <com/sun/star/lang/XServiceInfo.hpp> 71 #include <com/sun/star/lang/DisposedException.hpp> 72 #include <com/sun/star/awt/XWindow.hpp> 73 #include <com/sun/star/awt/XWindow2.hpp> 74 #include <com/sun/star/awt/XTopWindow.hpp> 75 #include <com/sun/star/frame/XModel.hpp> 76 #include <com/sun/star/frame/XFrameLoader.hpp> 77 #include <com/sun/star/frame/XSynchronousFrameLoader.hpp> 78 #include <com/sun/star/frame/XNotifyingDispatch.hpp> 79 #include <com/sun/star/task/XStatusIndicatorFactory.hpp> 80 #include <com/sun/star/task/XStatusIndicator.hpp> 81 #include <com/sun/star/util/XModifiable.hpp> 82 #include <com/sun/star/frame/XDispatchProvider.hpp> 83 #include <com/sun/star/document/XTypeDetection.hpp> 84 #include <com/sun/star/document/XActionLockable.hpp> 85 #include <com/sun/star/io/XInputStream.hpp> 86 #include <com/sun/star/task/XInteractionHandler.hpp> 87 #include <com/sun/star/container/XNameAccess.hpp> 88 #include <com/sun/star/container/XContainerQuery.hpp> 89 #include <com/sun/star/container/XEnumeration.hpp> 90 #include <com/sun/star/document/MacroExecMode.hpp> 91 #include <com/sun/star/document/UpdateDocMode.hpp> 92 93 //_______________________________________________ 94 // includes of an other project 95 #include <vcl/window.hxx> 96 #include <vcl/wrkwin.hxx> 97 #include <vcl/syswin.hxx> 98 99 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ 100 #include <toolkit/unohlp.hxx> 101 #endif 102 #include <unotools/moduleoptions.hxx> 103 #include <svtools/sfxecode.hxx> 104 #include <unotools/processfactory.hxx> 105 #include <unotools/ucbhelper.hxx> 106 #include <comphelper/configurationhelper.hxx> 107 #include <rtl/ustrbuf.hxx> 108 #include <vcl/svapp.hxx> 109 110 //_______________________________________________ 111 // namespace 112 113 namespace framework{ 114 115 // may there exist already a define .-( 116 #ifndef css 117 namespace css = ::com::sun::star; 118 #endif 119 120 //_______________________________________________ 121 // declarations 122 123 class LoadEnvListener : private ThreadHelpBase 124 , public ::cppu::WeakImplHelper2< css::frame::XLoadEventListener , 125 css::frame::XDispatchResultListener > 126 { 127 private: 128 129 void** m_ppCheck ; 130 LoadEnv* m_pLoadEnv; 131 132 public: 133 134 //_______________________________________ 135 LoadEnvListener(void* pCheck , 136 LoadEnv* pLoadEnv) 137 { 138 m_ppCheck = &pCheck ; 139 m_pLoadEnv = pLoadEnv; 140 } 141 142 //_______________________________________ 143 // frame.XLoadEventListener 144 virtual void SAL_CALL loadFinished(const css::uno::Reference< css::frame::XFrameLoader >& xLoader) 145 throw(css::uno::RuntimeException); 146 147 virtual void SAL_CALL loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >& xLoader) 148 throw(css::uno::RuntimeException); 149 150 //_______________________________________ 151 // frame.XDispatchResultListener 152 virtual void SAL_CALL dispatchFinished(const css::frame::DispatchResultEvent& aEvent) 153 throw(css::uno::RuntimeException); 154 155 //_______________________________________ 156 // lang.XEventListener 157 virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent) 158 throw(css::uno::RuntimeException); 159 }; 160 161 /*----------------------------------------------- 162 14.10.2003 13:43 163 -----------------------------------------------*/ 164 LoadEnv::LoadEnv(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) 165 throw(LoadEnvException, css::uno::RuntimeException) 166 : ThreadHelpBase( ) 167 , m_xSMGR (xSMGR) 168 , m_pCheck (this ) 169 , m_pQuietInteraction( 0 ) 170 { 171 } 172 173 /*----------------------------------------------- 174 14.10.2003 13:43 175 -----------------------------------------------*/ 176 LoadEnv::~LoadEnv() 177 { 178 m_pCheck = 0; 179 } 180 181 /*----------------------------------------------- 182 10.09.2003 14:05 183 -----------------------------------------------*/ 184 css::uno::Reference< css::lang::XComponent > LoadEnv::loadComponentFromURL(const css::uno::Reference< css::frame::XComponentLoader >& xLoader, 185 const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , 186 const ::rtl::OUString& sURL , 187 const ::rtl::OUString& sTarget, 188 sal_Int32 nFlags , 189 const css::uno::Sequence< css::beans::PropertyValue >& lArgs ) 190 throw(css::lang::IllegalArgumentException, 191 css::io::IOException , 192 css::uno::RuntimeException ) 193 { 194 css::uno::Reference< css::lang::XComponent > xComponent; 195 196 try 197 { 198 LoadEnv aEnv(xSMGR); 199 200 aEnv.initializeLoading(sURL, 201 lArgs, 202 css::uno::Reference< css::frame::XFrame >(xLoader, css::uno::UNO_QUERY), 203 sTarget, 204 nFlags, 205 LoadEnv::E_NO_FEATURE); 206 aEnv.startLoading(); 207 aEnv.waitWhileLoading(); // wait for ever! 208 209 xComponent = aEnv.getTargetComponent(); 210 } 211 catch(const LoadEnvException& ex) 212 { 213 switch(ex.m_nID) 214 { 215 case LoadEnvException::ID_INVALID_MEDIADESCRIPTOR: 216 throw css::lang::IllegalArgumentException( 217 ::rtl::OUString::createFromAscii("Optional list of arguments seem to be corrupted."), 218 xLoader, 219 4); 220 221 case LoadEnvException::ID_UNSUPPORTED_CONTENT: 222 throw css::lang::IllegalArgumentException( 223 ::rtl::OUString::createFromAscii("URL seems to be an unsupported one."), 224 xLoader, 225 1); 226 227 default: xComponent.clear(); 228 break; 229 } 230 } 231 232 return xComponent; 233 } 234 235 //----------------------------------------------- 236 ::comphelper::MediaDescriptor impl_mergeMediaDescriptorWithMightExistingModelArgs(const css::uno::Sequence< css::beans::PropertyValue >& lOutsideDescriptor) 237 { 238 ::comphelper::MediaDescriptor lDescriptor(lOutsideDescriptor); 239 css::uno::Reference< css::frame::XModel > xModel = lDescriptor.getUnpackedValueOrDefault( 240 ::comphelper::MediaDescriptor::PROP_MODEL (), 241 css::uno::Reference< css::frame::XModel > ()); 242 if (xModel.is ()) 243 { 244 ::comphelper::MediaDescriptor lModelDescriptor(xModel->getArgs()); 245 ::comphelper::MediaDescriptor::iterator pIt = lModelDescriptor.find( ::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE() ); 246 if ( pIt != lModelDescriptor.end() ) 247 lDescriptor[::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()] = pIt->second; 248 } 249 250 return lDescriptor; 251 } 252 253 /*----------------------------------------------- 254 20.08.2003 09:49 255 -----------------------------------------------*/ 256 void LoadEnv::initializeLoading(const ::rtl::OUString& sURL , 257 const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor, 258 const css::uno::Reference< css::frame::XFrame >& xBaseFrame , 259 const ::rtl::OUString& sTarget , 260 sal_Int32 nSearchFlags , 261 EFeature eFeature , // => use default ... 262 EContentType eContentType ) // => use default ... 263 throw(LoadEnvException, css::uno::RuntimeException) 264 { 265 // SAFE -> ---------------------------------- 266 WriteGuard aWriteLock(m_aLock); 267 268 // Handle still running processes! 269 if (m_xAsynchronousJob.is()) 270 throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING); 271 272 // take over all new parameters. 273 m_xTargetFrame.clear(); 274 m_xBaseFrame = xBaseFrame ; 275 m_lMediaDescriptor = impl_mergeMediaDescriptorWithMightExistingModelArgs(lMediaDescriptor); 276 m_sTarget = sTarget ; 277 m_nSearchFlags = nSearchFlags ; 278 m_eFeature = eFeature ; 279 m_eContentType = eContentType ; 280 m_bCloseFrameOnError = sal_False ; 281 m_bReactivateControllerOnError = sal_False ; 282 m_bLoaded = sal_False ; 283 284 // try to find out, if its realy a content, which can be loaded or must be "handled" 285 // We use a default value for this in-parameter. Then we have to start a complex check method 286 // internaly. But if this check was already done outside it can be supressed to perform 287 // the load request. We take over the result then! 288 if (m_eContentType == E_UNSUPPORTED_CONTENT) 289 { 290 m_eContentType = LoadEnv::classifyContent(sURL, lMediaDescriptor); 291 if (m_eContentType == E_UNSUPPORTED_CONTENT) 292 throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT); 293 } 294 295 // make URL part of the MediaDescriptor 296 // It doesnt mater, if its already an item of it. 297 // It must be the same value ... so we can overwrite it :-) 298 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_URL()] <<= sURL; 299 300 // parse it - because some following code require that 301 m_aURL.Complete = sURL; 302 css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY); 303 xParser->parseStrict(m_aURL); 304 305 // BTW: Split URL and JumpMark ... 306 // Because such mark is an explicit value of the media descriptor! 307 if (m_aURL.Mark.getLength()) 308 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_JUMPMARK()] <<= m_aURL.Mark; 309 310 // By the way: remove the old and deprecated value "FileName" from the descriptor! 311 ::comphelper::MediaDescriptor::iterator pIt = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_FILENAME()); 312 if (pIt != m_lMediaDescriptor.end()) 313 m_lMediaDescriptor.erase(pIt); 314 315 // patch the MediaDescriptor, so it fullfill the outside requirements 316 // Means especialy items like e.g. UI InteractionHandler, Status Indicator, 317 // MacroExecutionMode etcpp. 318 319 /*TODO progress is bound to a frame ... How can we set it here? */ 320 321 // UI mode 322 const bool bUIMode = 323 ( ( m_eFeature & E_WORK_WITH_UI ) == E_WORK_WITH_UI ) && 324 ( m_lMediaDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_HIDDEN() , sal_False ) == sal_False ) && 325 ( m_lMediaDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_PREVIEW(), sal_False ) == sal_False ); 326 327 initializeUIDefaults( 328 m_xSMGR, 329 m_lMediaDescriptor, 330 bUIMode, 331 &m_pQuietInteraction 332 ); 333 334 aWriteLock.unlock(); 335 // <- SAFE ---------------------------------- 336 } 337 338 /*----------------------------------------------- 339 22.01.2010 340 -----------------------------------------------*/ 341 void LoadEnv::initializeUIDefaults( const css::uno::Reference< css::lang::XMultiServiceFactory >& i_rSMGR, 342 ::comphelper::MediaDescriptor& io_lMediaDescriptor, const bool i_bUIMode, 343 QuietInteraction** o_ppQuietInteraction ) 344 { 345 css::uno::Reference< css::task::XInteractionHandler > xInteractionHandler; 346 sal_Int16 nMacroMode ; 347 sal_Int16 nUpdateMode ; 348 349 if ( i_bUIMode ) 350 { 351 nMacroMode = css::document::MacroExecMode::USE_CONFIG; 352 nUpdateMode = css::document::UpdateDocMode::ACCORDING_TO_CONFIG; 353 try 354 { 355 xInteractionHandler = css::uno::Reference< css::task::XInteractionHandler >(i_rSMGR->createInstance(IMPLEMENTATIONNAME_UIINTERACTIONHANDLER), css::uno::UNO_QUERY); 356 } 357 catch(const css::uno::RuntimeException&) {throw;} 358 catch(const css::uno::Exception& ) { } 359 } 360 // hidden mode 361 else 362 { 363 nMacroMode = css::document::MacroExecMode::NEVER_EXECUTE; 364 nUpdateMode = css::document::UpdateDocMode::NO_UPDATE; 365 QuietInteraction* pQuietInteraction = new QuietInteraction(); 366 xInteractionHandler = css::uno::Reference< css::task::XInteractionHandler >(static_cast< css::task::XInteractionHandler* >(pQuietInteraction), css::uno::UNO_QUERY); 367 if ( o_ppQuietInteraction != NULL ) 368 { 369 *o_ppQuietInteraction = pQuietInteraction; 370 (*o_ppQuietInteraction)->acquire(); 371 } 372 } 373 374 if ( 375 (xInteractionHandler.is() ) && 376 (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER()) == io_lMediaDescriptor.end()) 377 ) 378 { 379 io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER()] <<= 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 cant 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 cant be shure that we are currently not used inside the 452 // main thread!), we cant use conditions here realy. 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 usefull nor neccessary 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 cant be cancelled in its running 515 // operation :-( And we cant 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 shure, that loading process was realy 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 shure, 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 cant 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 LOG_WARNING("LoadEnv::classifyContent()", "realy an unsupported content?") 820 return E_UNSUPPORTED_CONTENT; 821 } 822 823 /*----------------------------------------------- 824 03.11.2003 09:31 825 -----------------------------------------------*/ 826 void LoadEnv::impl_detectTypeAndFilter() 827 throw(LoadEnvException, css::uno::RuntimeException) 828 { 829 static ::rtl::OUString TYPEPROP_PREFERREDFILTER = ::rtl::OUString::createFromAscii("PreferredFilter"); 830 static ::rtl::OUString FILTERPROP_FLAGS = ::rtl::OUString::createFromAscii("Flags" ); 831 static sal_Int32 FILTERFLAG_TEMPLATEPATH = 16; 832 833 // SAFE -> 834 ReadGuard aReadLock(m_aLock); 835 836 // Attention: Because our stl media descriptor is a copy of an uno sequence 837 // we cant use as an in/out parameter here. Copy it before and dont forget to 838 // update structure afterwards again! 839 css::uno::Sequence< css::beans::PropertyValue > lDescriptor = m_lMediaDescriptor.getAsConstPropertyValueList(); 840 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 841 842 aReadLock.unlock(); 843 // <- SAFE 844 845 ::rtl::OUString sType; 846 css::uno::Reference< css::document::XTypeDetection > xDetect(xSMGR->createInstance(SERVICENAME_TYPEDETECTION), css::uno::UNO_QUERY); 847 if (xDetect.is()) 848 sType = xDetect->queryTypeByDescriptor(lDescriptor, sal_True); /*TODO should deep detection be able for enable/disable it from outside? */ 849 850 // no valid content -> loading not possible 851 if (!sType.getLength()) 852 throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT); 853 854 // SAFE -> 855 WriteGuard aWriteLock(m_aLock); 856 857 // detection was successfully => update the descriptor member of this class 858 m_lMediaDescriptor << lDescriptor; 859 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME()] <<= sType; 860 // Is there an already detected (may be preselected) filter? 861 // see below ... 862 ::rtl::OUString sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_FILTERNAME(), ::rtl::OUString()); 863 864 aWriteLock.unlock(); 865 // <- SAFE 866 867 // But the type isnt enough. For loading sometimes we need more informations. 868 // E.g. for our "_default" feature, where we recylce any frame which contains 869 // and "Untitled" document, we must know if the new document is based on a template! 870 // But this information is available as a filter property only. 871 // => We must try(!) to detect the right filter for this load request. 872 // On the other side ... if no filter is available .. ignore it. 873 // Then the type information must be enough. 874 if (!sFilter.getLength()) 875 { 876 // no -> try to find a preferred filter for the detected type. 877 // Dont forget to updatet he media descriptor. 878 css::uno::Reference< css::container::XNameAccess > xTypeCont(xDetect, css::uno::UNO_QUERY_THROW); 879 try 880 { 881 ::comphelper::SequenceAsHashMap lTypeProps(xTypeCont->getByName(sType)); 882 sFilter = lTypeProps.getUnpackedValueOrDefault(TYPEPROP_PREFERREDFILTER, ::rtl::OUString()); 883 if (sFilter.getLength()) 884 { 885 // SAFE -> 886 aWriteLock.lock(); 887 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter; 888 aWriteLock.unlock(); 889 // <- SAFE 890 } 891 } 892 catch(const css::container::NoSuchElementException&) 893 {} 894 } 895 896 // check if the filter (if one exists) points to a template format filter. 897 // Then we have to add the property "AsTemplate". 898 // We need this information to decide afterwards if we can use a "recycle frame" 899 // for target "_default" or has to create a new one everytimes. 900 // On the other side we have to supress that, if this property already exists 901 // and should trigger a special handling. Then the outside calli of this method here, 902 // has to know, what he is doing .-) 903 904 sal_Bool bIsOwnTemplate = sal_False; 905 if (sFilter.getLength()) 906 { 907 css::uno::Reference< css::container::XNameAccess > xFilterCont(xSMGR->createInstance(SERVICENAME_FILTERFACTORY), css::uno::UNO_QUERY_THROW); 908 try 909 { 910 ::comphelper::SequenceAsHashMap lFilterProps(xFilterCont->getByName(sFilter)); 911 sal_Int32 nFlags = lFilterProps.getUnpackedValueOrDefault(FILTERPROP_FLAGS, (sal_Int32)0); 912 bIsOwnTemplate = ((nFlags & FILTERFLAG_TEMPLATEPATH) == FILTERFLAG_TEMPLATEPATH); 913 } 914 catch(const css::container::NoSuchElementException&) 915 {} 916 } 917 if (bIsOwnTemplate) 918 { 919 // SAFE -> 920 aWriteLock.lock(); 921 // Dont overwrite external decisions! See comments before ... 922 ::comphelper::MediaDescriptor::const_iterator pAsTemplateItem = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_ASTEMPLATE()); 923 if (pAsTemplateItem == m_lMediaDescriptor.end()) 924 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_ASTEMPLATE()] <<= sal_True; 925 aWriteLock.unlock(); 926 // <- SAFE 927 } 928 } 929 930 /*----------------------------------------------- 931 15.08.2003 09:38 932 -----------------------------------------------*/ 933 sal_Bool LoadEnv::impl_handleContent() 934 throw(LoadEnvException, css::uno::RuntimeException) 935 { 936 // SAFE -> ----------------------------------- 937 ReadGuard aReadLock(m_aLock); 938 939 // the type must exist inside the descriptor ... otherwhise this class is implemented wrong :-) 940 ::rtl::OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_TYPENAME(), ::rtl::OUString()); 941 if (!sType.getLength()) 942 throw LoadEnvException(LoadEnvException::ID_INVALID_MEDIADESCRIPTOR); 943 944 // convert media descriptor and URL to right format for later interface call! 945 css::uno::Sequence< css::beans::PropertyValue > lDescriptor; 946 m_lMediaDescriptor >> lDescriptor; 947 css::util::URL aURL = m_aURL; 948 949 // get neccessary container to query for a handler object 950 css::uno::Reference< css::lang::XMultiServiceFactory > xFactory(m_xSMGR->createInstance(SERVICENAME_CONTENTHANDLERFACTORY), css::uno::UNO_QUERY); 951 css::uno::Reference< css::container::XContainerQuery > xQuery (xFactory , css::uno::UNO_QUERY); 952 953 aReadLock.unlock(); 954 // <- SAFE ----------------------------------- 955 956 // query 957 css::uno::Sequence< ::rtl::OUString > lTypeReg(1); 958 lTypeReg[0] = sType; 959 960 css::uno::Sequence< css::beans::NamedValue > lQuery(1); 961 lQuery[0].Name = ::framework::constant::ContentHandler::PROP_TYPES; 962 lQuery[0].Value <<= lTypeReg; 963 964 css::uno::Reference< css::container::XEnumeration > xSet = xQuery->createSubSetEnumerationByProperties(lQuery); 965 while(xSet->hasMoreElements()) 966 { 967 ::comphelper::SequenceAsHashMap lProps (xSet->nextElement()); 968 ::rtl::OUString sHandler = lProps.getUnpackedValueOrDefault(::framework::constant::ContentHandler::PROP_NAME, ::rtl::OUString()); 969 970 css::uno::Reference< css::frame::XNotifyingDispatch > xHandler; 971 try 972 { 973 xHandler = css::uno::Reference< css::frame::XNotifyingDispatch >(xFactory->createInstance(sHandler), css::uno::UNO_QUERY); 974 if (!xHandler.is()) 975 continue; 976 } 977 catch(const css::uno::RuntimeException&) 978 { throw; } 979 catch(const css::uno::Exception&) 980 { continue; } 981 982 // SAFE -> ----------------------------------- 983 WriteGuard aWriteLock(m_aLock); 984 m_xAsynchronousJob = xHandler; 985 m_pCheck = this; 986 LoadEnvListener* pListener = new LoadEnvListener(m_pCheck, this); 987 aWriteLock.unlock(); 988 // <- SAFE ----------------------------------- 989 990 css::uno::Reference< css::frame::XDispatchResultListener > xListener(static_cast< css::frame::XDispatchResultListener* >(pListener), css::uno::UNO_QUERY); 991 xHandler->dispatchWithNotification(aURL, lDescriptor, xListener); 992 993 return sal_True; 994 } 995 996 return sal_False; 997 } 998 999 //----------------------------------------------- 1000 sal_Bool LoadEnv::impl_furtherDocsAllowed() 1001 { 1002 // SAFE -> 1003 ReadGuard aReadLock(m_aLock); 1004 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 1005 aReadLock.unlock(); 1006 // <- SAFE 1007 1008 sal_Bool bAllowed = sal_True; 1009 1010 try 1011 { 1012 css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey( 1013 xSMGR, 1014 ::rtl::OUString::createFromAscii("org.openoffice.Office.Common/"), 1015 ::rtl::OUString::createFromAscii("Misc"), 1016 ::rtl::OUString::createFromAscii("MaxOpenDocuments"), 1017 ::comphelper::ConfigurationHelper::E_READONLY); 1018 1019 // NIL means: count of allowed documents = infinite ! 1020 // => return sal_True 1021 if ( ! aVal.hasValue()) 1022 bAllowed = sal_True; 1023 else 1024 { 1025 sal_Int32 nMaxOpenDocuments = 0; 1026 aVal >>= nMaxOpenDocuments; 1027 1028 css::uno::Reference< css::frame::XFramesSupplier > xDesktop( 1029 xSMGR->createInstance(SERVICENAME_DESKTOP), 1030 css::uno::UNO_QUERY_THROW); 1031 1032 FrameListAnalyzer aAnalyzer(xDesktop, 1033 css::uno::Reference< css::frame::XFrame >(), 1034 FrameListAnalyzer::E_HELP | 1035 FrameListAnalyzer::E_BACKINGCOMPONENT | 1036 FrameListAnalyzer::E_HIDDEN); 1037 1038 sal_Int32 nOpenDocuments = aAnalyzer.m_lOtherVisibleFrames.getLength(); 1039 bAllowed = (nOpenDocuments < nMaxOpenDocuments); 1040 } 1041 } 1042 catch(const css::uno::Exception&) 1043 { bAllowed = sal_True; } // !! internal errors are no reason to disturb the office from opening documents .-) 1044 1045 if ( ! bAllowed ) 1046 { 1047 // SAFE -> 1048 aReadLock.lock(); 1049 css::uno::Reference< css::task::XInteractionHandler > xInteraction = m_lMediaDescriptor.getUnpackedValueOrDefault( 1050 ::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER(), 1051 css::uno::Reference< css::task::XInteractionHandler >()); 1052 aReadLock.unlock(); 1053 // <- SAFE 1054 1055 if (xInteraction.is()) 1056 { 1057 css::uno::Any aInteraction; 1058 css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations(2); 1059 1060 comphelper::OInteractionAbort* pAbort = new comphelper::OInteractionAbort(); 1061 comphelper::OInteractionApprove* pApprove = new comphelper::OInteractionApprove(); 1062 1063 lContinuations[0] = css::uno::Reference< css::task::XInteractionContinuation >( 1064 static_cast< css::task::XInteractionContinuation* >(pAbort), 1065 css::uno::UNO_QUERY_THROW); 1066 lContinuations[1] = css::uno::Reference< css::task::XInteractionContinuation >( 1067 static_cast< css::task::XInteractionContinuation* >(pApprove), 1068 css::uno::UNO_QUERY_THROW); 1069 1070 css::task::ErrorCodeRequest aErrorCode; 1071 aErrorCode.ErrCode = ERRCODE_SFX_NOMOREDOCUMENTSALLOWED; 1072 aInteraction <<= aErrorCode; 1073 xInteraction->handle( InteractionRequest::CreateRequest(aInteraction, lContinuations) ); 1074 } 1075 } 1076 1077 return bAllowed; 1078 } 1079 1080 //----------------------------------------------- 1081 sal_Bool LoadEnv::impl_loadContent() 1082 throw(LoadEnvException, css::uno::RuntimeException) 1083 { 1084 // SAFE -> ----------------------------------- 1085 WriteGuard aWriteLock(m_aLock); 1086 1087 // search or create right target frame 1088 ::rtl::OUString sTarget = m_sTarget; 1089 if (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_DEFAULT)) 1090 { 1091 m_xTargetFrame = impl_searchAlreadyLoaded(); 1092 if (m_xTargetFrame.is()) 1093 { 1094 impl_setResult(sal_True); 1095 return sal_True; 1096 } 1097 m_xTargetFrame = impl_searchRecycleTarget(); 1098 } 1099 1100 if (! m_xTargetFrame.is()) 1101 { 1102 if ( 1103 (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_BLANK )) || 1104 (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_DEFAULT)) 1105 ) 1106 { 1107 if (! impl_furtherDocsAllowed()) 1108 return sal_False; 1109 m_xTargetFrame = m_xBaseFrame->findFrame(SPECIALTARGET_BLANK, 0); 1110 m_bCloseFrameOnError = m_xTargetFrame.is(); 1111 } 1112 else 1113 { 1114 sal_Int32 nFlags = m_nSearchFlags & ~css::frame::FrameSearchFlag::CREATE; 1115 m_xTargetFrame = m_xBaseFrame->findFrame(sTarget, nFlags); 1116 if (! m_xTargetFrame.is()) 1117 { 1118 if (! impl_furtherDocsAllowed()) 1119 return sal_False; 1120 m_xTargetFrame = m_xBaseFrame->findFrame(SPECIALTARGET_BLANK, 0); 1121 m_bCloseFrameOnError = m_xTargetFrame.is(); 1122 } 1123 } 1124 } 1125 1126 // If we couldn't find a valid frame or the frame has no container window 1127 // we have to throw an exception. 1128 if ( 1129 ( ! m_xTargetFrame.is() ) || 1130 ( ! m_xTargetFrame->getContainerWindow().is() ) 1131 ) 1132 throw LoadEnvException(LoadEnvException::ID_NO_TARGET_FOUND); 1133 1134 css::uno::Reference< css::frame::XFrame > xTargetFrame = m_xTargetFrame; 1135 1136 // Now we have a valid frame ... and type detection was already done. 1137 // We should apply the module dependend window position and size to the 1138 // frame window. 1139 impl_applyPersistentWindowState(xTargetFrame->getContainerWindow()); 1140 1141 // Don't forget to lock task for following load process. Otherwise it could die 1142 // during this operation runs by terminating the office or closing this task via api. 1143 // If we set this lock "close()" will return false and closing will be broken. 1144 // Attention: Don't forget to reset this lock again after finishing operation. 1145 // Otherwise task AND office couldn't die!!! 1146 // This includes gracefully handling of Exceptions (Runtime!) too ... 1147 // Thats why we use a specialized guard, which will reset the lock 1148 // if it will be run out of scope. 1149 1150 // Note further: ignore if this internal guard already contains a resource. 1151 // Might impl_searchRecylcTarget() set it before. But incase this impl-method wasnt used 1152 // and the target frame was new created ... this lock here must be set! 1153 css::uno::Reference< css::document::XActionLockable > xTargetLock(xTargetFrame, css::uno::UNO_QUERY); 1154 m_aTargetLock.setResource(xTargetLock); 1155 1156 // Add status indicator to descriptor. Loader can show an progresses then. 1157 // But don't do it, if loading should be hidden or preview is used ...! 1158 // So we prevent our code against wrong using. Why? 1159 // It could be, that using of this progress could make trouble. e.g. He make window visible ... 1160 // but shouldn't do that. But if no indicator is available ... nobody has a chance to do that! 1161 sal_Bool bHidden = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN() , sal_False ); 1162 sal_Bool bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_MINIMIZED() , sal_False ); 1163 sal_Bool bPreview = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_PREVIEW() , sal_False ); 1164 css::uno::Reference< css::task::XStatusIndicator > xProgress = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_STATUSINDICATOR(), css::uno::Reference< css::task::XStatusIndicator >()); 1165 1166 if (!bHidden && !bMinimized && !bPreview && !xProgress.is()) 1167 { 1168 // Note: its an optional interface! 1169 css::uno::Reference< css::task::XStatusIndicatorFactory > xProgressFactory(xTargetFrame, css::uno::UNO_QUERY); 1170 if (xProgressFactory.is()) 1171 { 1172 xProgress = xProgressFactory->createStatusIndicator(); 1173 if (xProgress.is()) 1174 m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_STATUSINDICATOR()] <<= xProgress; 1175 } 1176 } 1177 1178 // convert media descriptor and URL to right format for later interface call! 1179 css::uno::Sequence< css::beans::PropertyValue > lDescriptor; 1180 m_lMediaDescriptor >> lDescriptor; 1181 ::rtl::OUString sURL = m_aURL.Complete; 1182 1183 // try to locate any interested frame loader 1184 css::uno::Reference< css::uno::XInterface > xLoader = impl_searchLoader(); 1185 css::uno::Reference< css::frame::XFrameLoader > xAsyncLoader(xLoader, css::uno::UNO_QUERY); 1186 css::uno::Reference< css::frame::XSynchronousFrameLoader > xSyncLoader (xLoader, css::uno::UNO_QUERY); 1187 1188 if (xAsyncLoader.is()) 1189 { 1190 // SAFE -> ----------------------------------- 1191 aWriteLock.lock(); 1192 m_xAsynchronousJob = xAsyncLoader; 1193 m_pCheck = this; 1194 LoadEnvListener* pListener = new LoadEnvListener(m_pCheck, this); 1195 aWriteLock.unlock(); 1196 // <- SAFE ----------------------------------- 1197 1198 css::uno::Reference< css::frame::XLoadEventListener > xListener(static_cast< css::frame::XLoadEventListener* >(pListener), css::uno::UNO_QUERY); 1199 xAsyncLoader->load(xTargetFrame, sURL, lDescriptor, xListener); 1200 1201 return sal_True; 1202 } 1203 else 1204 if (xSyncLoader.is()) 1205 { 1206 sal_Bool bResult = xSyncLoader->load(lDescriptor, xTargetFrame); 1207 // react for the result here, so the outside waiting 1208 // code can ask for it later. 1209 impl_setResult(bResult); 1210 // But the return value indicates a valid started(!) operation. 1211 // And thats true everxtimes, we reach this line :-) 1212 return sal_True; 1213 } 1214 1215 aWriteLock.unlock(); 1216 // <- SAFE 1217 1218 return sal_False; 1219 } 1220 1221 /*----------------------------------------------- 1222 06.02.2004 14:40 1223 -----------------------------------------------*/ 1224 css::uno::Reference< css::uno::XInterface > LoadEnv::impl_searchLoader() 1225 { 1226 // SAFE -> ----------------------------------- 1227 ReadGuard aReadLock(m_aLock); 1228 1229 // special mode to set an existing component on this frame 1230 // In such case the laoder is fix. It must be the SFX based implementation, 1231 // which can create a view on top of such xModel components :-) 1232 if (m_eContentType == E_CAN_BE_SET) 1233 { 1234 try 1235 { 1236 return m_xSMGR->createInstance(IMPLEMENTATIONNAME_GENERICFRAMELOADER); 1237 } 1238 catch(const css::uno::RuntimeException&) 1239 { throw; } 1240 catch(const css::uno::Exception&) 1241 {} 1242 throw LoadEnvException(LoadEnvException::ID_INVALID_ENVIRONMENT); 1243 } 1244 1245 // Otherwhise ... 1246 // We need this type information to locate an registered frame loader 1247 // Without such information we cant work! 1248 ::rtl::OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_TYPENAME(), ::rtl::OUString()); 1249 if (!sType.getLength()) 1250 throw LoadEnvException(LoadEnvException::ID_INVALID_MEDIADESCRIPTOR); 1251 1252 // try to locate any interested frame loader 1253 css::uno::Reference< css::lang::XMultiServiceFactory > xLoaderFactory(m_xSMGR->createInstance(SERVICENAME_FRAMELOADERFACTORY), css::uno::UNO_QUERY); 1254 css::uno::Reference< css::container::XContainerQuery > xQuery (xLoaderFactory , css::uno::UNO_QUERY); 1255 1256 aReadLock.unlock(); 1257 // <- SAFE ----------------------------------- 1258 1259 css::uno::Sequence< ::rtl::OUString > lTypesReg(1); 1260 lTypesReg[0] = sType; 1261 1262 css::uno::Sequence< css::beans::NamedValue > lQuery(1); 1263 lQuery[0].Name = ::framework::constant::FrameLoader::PROP_TYPES; 1264 lQuery[0].Value <<= lTypesReg; 1265 1266 css::uno::Reference< css::container::XEnumeration > xSet = xQuery->createSubSetEnumerationByProperties(lQuery); 1267 while(xSet->hasMoreElements()) 1268 { 1269 // try everyone ... 1270 // Ignore any loader, which makes trouble :-) 1271 ::comphelper::SequenceAsHashMap lLoaderProps(xSet->nextElement()); 1272 ::rtl::OUString sLoader = lLoaderProps.getUnpackedValueOrDefault(::framework::constant::FrameLoader::PROP_NAME, ::rtl::OUString()); 1273 css::uno::Reference< css::uno::XInterface > xLoader ; 1274 try 1275 { 1276 xLoader = xLoaderFactory->createInstance(sLoader); 1277 if (xLoader.is()) 1278 return xLoader; 1279 } 1280 catch(const css::uno::RuntimeException&) 1281 { throw; } 1282 catch(const css::uno::Exception&) 1283 { continue; } 1284 } 1285 1286 return css::uno::Reference< css::uno::XInterface >(); 1287 } 1288 1289 /*----------------------------------------------- 1290 24.01.2006 15:11 1291 -----------------------------------------------*/ 1292 void LoadEnv::impl_jumpToMark(const css::uno::Reference< css::frame::XFrame >& xFrame, 1293 const css::util::URL& aURL ) 1294 { 1295 if (! aURL.Mark.getLength()) 1296 return; 1297 1298 css::uno::Reference< css::frame::XDispatchProvider > xProvider(xFrame, css::uno::UNO_QUERY); 1299 if (! xProvider.is()) 1300 return; 1301 1302 // SAFE -> 1303 ReadGuard aReadLock(m_aLock); 1304 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 1305 aReadLock.unlock(); 1306 // <- SAFE 1307 1308 css::util::URL aCmd; 1309 aCmd.Complete = ::rtl::OUString::createFromAscii(".uno:JumpToMark"); 1310 1311 css::uno::Reference< css::util::XURLTransformer > xParser(xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY_THROW); 1312 xParser->parseStrict(aCmd); 1313 1314 css::uno::Reference< css::frame::XDispatch > xDispatcher = xProvider->queryDispatch(aCmd, SPECIALTARGET_SELF, 0); 1315 if (! xDispatcher.is()) 1316 return; 1317 1318 ::comphelper::SequenceAsHashMap lArgs; 1319 lArgs[::rtl::OUString::createFromAscii("Bookmark")] <<= aURL.Mark; 1320 xDispatcher->dispatch(aCmd, lArgs.getAsConstPropertyValueList()); 1321 } 1322 1323 /*----------------------------------------------- 1324 31.07.2003 09:02 1325 -----------------------------------------------*/ 1326 css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchAlreadyLoaded() 1327 throw(LoadEnvException, css::uno::RuntimeException) 1328 { 1329 // SAFE -> 1330 ReadGuard aReadLock(m_aLock); 1331 1332 // such search is allowed for special requests only ... 1333 // or better its not allowed for some requests in general :-) 1334 if ( 1335 ( ! TargetHelper::matchSpecialTarget(m_sTarget, TargetHelper::E_DEFAULT) ) || 1336 (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_ASTEMPLATE() , sal_False) == sal_True) || 1337 // (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN() , sal_False) == sal_True) || 1338 (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_OPENNEWVIEW(), sal_False) == sal_True) 1339 ) 1340 { 1341 return css::uno::Reference< css::frame::XFrame >(); 1342 } 1343 1344 // check URL 1345 // May its not usefull to start expensive document search, if it 1346 // can fail only .. because we load from a stream or model directly! 1347 if ( 1348 (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_STREAM )) || 1349 (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_OBJECT )) 1350 /*TODO should be private:factory here tested too? */ 1351 ) 1352 { 1353 return css::uno::Reference< css::frame::XFrame >(); 1354 } 1355 1356 // otherwhise - iterate through the tasks of the desktop container 1357 // to find out, which of them might contains the requested document 1358 css::uno::Reference< css::frame::XFramesSupplier > xSupplier(m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY); 1359 css::uno::Reference< css::container::XIndexAccess > xTaskList(xSupplier->getFrames() , css::uno::UNO_QUERY); 1360 1361 if (!xTaskList.is()) 1362 return css::uno::Reference< css::frame::XFrame >(); // task list can be empty! 1363 1364 // Note: To detect if a document was alrady loaded before 1365 // we check URLs here only. But might the existing and the requred 1366 // document has different versions! Then its URLs are the same ... 1367 sal_Int16 nNewVersion = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_VERSION(), (sal_Int16)(-1)); 1368 1369 // will be used to save the first hidden frame referring the searched model 1370 // Normaly we are interested on visible frames ... but if there is no such visible 1371 // frame we referr to any hidden frame also (but as fallback only). 1372 css::uno::Reference< css::frame::XFrame > xHiddenTask; 1373 css::uno::Reference< css::frame::XFrame > xTask; 1374 1375 sal_Int32 count = xTaskList->getCount(); 1376 for (sal_Int32 i=0; i<count; ++i) 1377 { 1378 try 1379 { 1380 // locate model of task 1381 // Note: Without a model there is no chance to decide if 1382 // this task contains the searched document or not! 1383 xTaskList->getByIndex(i) >>= xTask; 1384 if (!xTask.is()) 1385 continue; 1386 1387 css::uno::Reference< css::frame::XController > xController = xTask->getController(); 1388 if (!xController.is()) 1389 { 1390 xTask.clear (); 1391 continue; 1392 } 1393 1394 css::uno::Reference< css::frame::XModel > xModel = xController->getModel(); 1395 if (!xModel.is()) 1396 { 1397 xTask.clear (); 1398 continue; 1399 } 1400 1401 // don't check the complete URL here. 1402 // use its main part - ignore optional jumpmarks! 1403 const ::rtl::OUString sURL = xModel->getURL(); 1404 if (!::utl::UCBContentHelper::EqualURLs( m_aURL.Main, sURL )) 1405 { 1406 xTask.clear (); 1407 continue; 1408 } 1409 1410 // get the original load arguments from the current document 1411 // and decide if its realy the same then the one will be. 1412 // It must be visible and must use the same file revision ... 1413 // or must not have any file revision set (-1 == -1!) 1414 ::comphelper::MediaDescriptor lOldDocDescriptor(xModel->getArgs()); 1415 1416 if (lOldDocDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_VERSION(), (sal_Int32)(-1)) != nNewVersion) 1417 { 1418 xTask.clear (); 1419 continue; 1420 } 1421 1422 // Hidden frames are special. 1423 // They will be used as "last chance" if there is no visible frame pointing to the same model. 1424 // Safe the result but continue with current loop might be looking for other visible frames. 1425 ::sal_Bool bIsHidden = lOldDocDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False); 1426 if ( 1427 ( bIsHidden ) && 1428 ( ! xHiddenTask.is()) 1429 ) 1430 { 1431 xHiddenTask = xTask; 1432 xTask.clear (); 1433 continue; 1434 } 1435 1436 // We found a visible task pointing to the right model ... 1437 // Break search. 1438 break; 1439 } 1440 catch(const css::uno::RuntimeException& exRun) 1441 { throw exRun; } 1442 catch(const css::uno::Exception&) 1443 { continue; } 1444 } 1445 1446 css::uno::Reference< css::frame::XFrame > xResult; 1447 if (xTask.is()) 1448 xResult = xTask; 1449 else 1450 if (xHiddenTask.is()) 1451 xResult = xHiddenTask; 1452 1453 if (xResult.is()) 1454 { 1455 // Now we are shure, that this task includes the searched document. 1456 // It's time to activate it. As special feature we try to jump internaly 1457 // if an optional jumpmark is given too. 1458 if (m_aURL.Mark.getLength()) 1459 impl_jumpToMark(xResult, m_aURL); 1460 1461 // bring it to front and make sure it's visible... 1462 impl_makeFrameWindowVisible(xResult->getContainerWindow(), sal_True); 1463 } 1464 1465 aReadLock.unlock(); 1466 // <- SAFE 1467 1468 return xResult; 1469 } 1470 1471 /*----------------------------------------------- 1472 30.03.2004 09:12 1473 -----------------------------------------------*/ 1474 sal_Bool LoadEnv::impl_isFrameAlreadyUsedForLoading(const css::uno::Reference< css::frame::XFrame >& xFrame) const 1475 { 1476 css::uno::Reference< css::document::XActionLockable > xLock(xFrame, css::uno::UNO_QUERY); 1477 1478 // ? no lock interface ? 1479 // Might its an external written frame implementation :-( 1480 // Allowing using of it ... but it can fail if its not synchronized with our processes ! 1481 if (!xLock.is()) 1482 return sal_False; 1483 1484 // Otherwhise we have to look for any other existing lock. 1485 return xLock->isActionLocked(); 1486 } 1487 1488 /*----------------------------------------------- 1489 30.03.2004 09:12 1490 -----------------------------------------------*/ 1491 css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchRecycleTarget() 1492 throw(LoadEnvException, css::uno::RuntimeException) 1493 { 1494 // SAFE -> .................................. 1495 ReadGuard aReadLock(m_aLock); 1496 1497 // The special backing mode frame will be recycled by definition! 1498 // It does'nt matter if somehwere whish to create a new view 1499 // or open a new untitled document ... 1500 // The only exception form that - hidden frames! 1501 if (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False) == sal_True) 1502 return css::uno::Reference< css::frame::XFrame >(); 1503 1504 css::uno::Reference< css::frame::XFramesSupplier > xSupplier(m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY); 1505 FrameListAnalyzer aTasksAnalyzer(xSupplier, css::uno::Reference< css::frame::XFrame >(), FrameListAnalyzer::E_BACKINGCOMPONENT); 1506 if (aTasksAnalyzer.m_xBackingComponent.is()) 1507 { 1508 if (!impl_isFrameAlreadyUsedForLoading(aTasksAnalyzer.m_xBackingComponent)) 1509 { 1510 // bring it to front ... 1511 impl_makeFrameWindowVisible(aTasksAnalyzer.m_xBackingComponent->getContainerWindow(), sal_True); 1512 return aTasksAnalyzer.m_xBackingComponent; 1513 } 1514 } 1515 1516 // These states indicates the wishing for creation of a new view in general. 1517 if ( 1518 (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_ASTEMPLATE() , sal_False) == sal_True) || 1519 (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_OPENNEWVIEW(), sal_False) == sal_True) 1520 ) 1521 { 1522 return css::uno::Reference< css::frame::XFrame >(); 1523 } 1524 1525 // On the other side some special URLs will open a new frame everytimes (expecting 1526 // they can use the backing-mode frame!) 1527 if ( 1528 (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_FACTORY )) || 1529 (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_STREAM )) || 1530 (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_OBJECT )) 1531 ) 1532 { 1533 return css::uno::Reference< css::frame::XFrame >(); 1534 } 1535 1536 // No backing frame! No special URL => recycle active task - if possible. 1537 // Means - if it does not already contains a modified document, or 1538 // use another office module. 1539 css::uno::Reference< css::frame::XFrame > xTask = xSupplier->getActiveFrame(); 1540 1541 // not a real error - but might a focus problem! 1542 if (!xTask.is()) 1543 return css::uno::Reference< css::frame::XFrame >(); 1544 1545 // not a real error - may its a view only 1546 css::uno::Reference< css::frame::XController > xController = xTask->getController(); 1547 if (!xController.is()) 1548 return css::uno::Reference< css::frame::XFrame >(); 1549 1550 // not a real error - may its a db component instead of a full feartured office document 1551 css::uno::Reference< css::frame::XModel > xModel = xController->getModel(); 1552 if (!xModel.is()) 1553 return css::uno::Reference< css::frame::XFrame >(); 1554 1555 // get some more informations ... 1556 1557 // A valid set URL means: there is already a location for this document. 1558 // => it was saved there or opened from there. Such Documents can not be used here. 1559 // We search for empty document ... created by a private:factory/ URL! 1560 if (xModel->getURL().getLength()>0) 1561 return css::uno::Reference< css::frame::XFrame >(); 1562 1563 // The old document must be unmodified ... 1564 css::uno::Reference< css::util::XModifiable > xModified(xModel, css::uno::UNO_QUERY); 1565 if (xModified->isModified()) 1566 return css::uno::Reference< css::frame::XFrame >(); 1567 1568 Window* pWindow = VCLUnoHelper::GetWindow(xTask->getContainerWindow()); 1569 if (pWindow && pWindow->IsInModalMode()) 1570 return css::uno::Reference< css::frame::XFrame >(); 1571 1572 // find out the application type of this document 1573 // We can recycle only documents, which uses the same application 1574 // then the new one. 1575 SvtModuleOptions::EFactory eOldApp = SvtModuleOptions::ClassifyFactoryByModel(xModel); 1576 SvtModuleOptions::EFactory eNewApp = SvtModuleOptions::ClassifyFactoryByURL (m_aURL.Complete, m_lMediaDescriptor.getAsConstPropertyValueList()); 1577 1578 aReadLock.unlock(); 1579 // <- SAFE .................................. 1580 1581 if (eOldApp != eNewApp) 1582 return css::uno::Reference< css::frame::XFrame >(); 1583 1584 // OK this task seams to be useable for recycling 1585 // But we should mark it as such - means set an action lock. 1586 // Otherwhise it would be used more then ones or will be destroyed 1587 // by a close() or terminate() request. 1588 // But if such lock already exist ... it means this task is used for 1589 // any other operation already. Don't use it then. 1590 if (impl_isFrameAlreadyUsedForLoading(xTask)) 1591 return css::uno::Reference< css::frame::XFrame >(); 1592 1593 // OK - there is a valid target frame. 1594 // But may be it contains already a document. 1595 // Then we have to ask it, if it allows recylcing of this frame .-) 1596 sal_Bool bReactivateOldControllerOnError = sal_False; 1597 css::uno::Reference< css::frame::XController > xOldDoc = xTask->getController(); 1598 if (xOldDoc.is()) 1599 { 1600 bReactivateOldControllerOnError = xOldDoc->suspend(sal_True); 1601 if (! bReactivateOldControllerOnError) 1602 return css::uno::Reference< css::frame::XFrame >(); 1603 } 1604 1605 // SAFE -> .................................. 1606 WriteGuard aWriteLock(m_aLock); 1607 1608 css::uno::Reference< css::document::XActionLockable > xLock(xTask, css::uno::UNO_QUERY); 1609 if (!m_aTargetLock.setResource(xLock)) 1610 return css::uno::Reference< css::frame::XFrame >(); 1611 1612 m_bReactivateControllerOnError = bReactivateOldControllerOnError; 1613 aWriteLock.unlock(); 1614 // <- SAFE .................................. 1615 1616 // bring it to front ... 1617 impl_makeFrameWindowVisible(xTask->getContainerWindow(), sal_True); 1618 1619 return xTask; 1620 } 1621 1622 /*----------------------------------------------- 1623 15.08.2003 12:39 1624 -----------------------------------------------*/ 1625 void LoadEnv::impl_reactForLoadingState() 1626 throw(LoadEnvException, css::uno::RuntimeException) 1627 { 1628 /*TODO reset action locks */ 1629 1630 // SAFE -> ---------------------------------- 1631 ReadGuard aReadLock(m_aLock); 1632 1633 if (m_bLoaded) 1634 { 1635 // Bring the new loaded document to front (if allowed!). 1636 // Note: We show new created frames here only. 1637 // We dont hide already visible frames here ... 1638 css::uno::Reference< css::awt::XWindow > xWindow = m_xTargetFrame->getContainerWindow(); 1639 sal_Bool bHidden = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False); 1640 sal_Bool bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_MINIMIZED(), sal_False); 1641 1642 if (bMinimized) 1643 { 1644 ::vos::OClearableGuard aSolarGuard(Application::GetSolarMutex()); 1645 Window* pWindow = VCLUnoHelper::GetWindow(xWindow); 1646 // check for system window is neccessary to guarantee correct pointer cast! 1647 if (pWindow && pWindow->IsSystemWindow()) 1648 ((WorkWindow*)pWindow)->Minimize(); 1649 } 1650 else 1651 if (!bHidden) 1652 { 1653 // show frame ... if it's not still visible ... 1654 // But do nothing if it's already visible! 1655 impl_makeFrameWindowVisible(xWindow, sal_False); 1656 } 1657 1658 // Note: Only if an existing property "FrameName" is given by this media descriptor, 1659 // it should be used. Otherwhise we should do nothing. May be the outside code has already 1660 // set a frame name on the target! 1661 ::comphelper::MediaDescriptor::const_iterator pFrameName = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_FRAMENAME()); 1662 if (pFrameName != m_lMediaDescriptor.end()) 1663 { 1664 ::rtl::OUString sFrameName; 1665 pFrameName->second >>= sFrameName; 1666 // Check the name again. e.g. "_default" isnt allowed. 1667 // On the other side "_beamer" is a valid name :-) 1668 if (TargetHelper::isValidNameForFrame(sFrameName)) 1669 m_xTargetFrame->setName(sFrameName); 1670 } 1671 } 1672 else if (m_bReactivateControllerOnError) 1673 { 1674 // Try to reactivate the old document (if any exists!) 1675 css::uno::Reference< css::frame::XController > xOldDoc = m_xTargetFrame->getController(); 1676 // clear does not depend from reactivation state of a might existing old document! 1677 // We must make shure, that a might following getTargetComponent() call does not return 1678 // the old document! 1679 m_xTargetFrame.clear(); 1680 if (xOldDoc.is()) 1681 { 1682 sal_Bool bReactivated = xOldDoc->suspend(sal_False); 1683 if (!bReactivated) 1684 throw LoadEnvException(LoadEnvException::ID_COULD_NOT_REACTIVATE_CONTROLLER); 1685 m_bReactivateControllerOnError = sal_False; 1686 } 1687 } 1688 else if (m_bCloseFrameOnError) 1689 { 1690 // close empty frames 1691 css::uno::Reference< css::util::XCloseable > xCloseable (m_xTargetFrame, css::uno::UNO_QUERY); 1692 css::uno::Reference< css::lang::XComponent > xDisposable(m_xTargetFrame, css::uno::UNO_QUERY); 1693 1694 try 1695 { 1696 if (xCloseable.is()) 1697 xCloseable->close(sal_True); 1698 else 1699 if (xDisposable.is()) 1700 xDisposable->dispose(); 1701 } 1702 catch(const css::util::CloseVetoException&) 1703 {} 1704 catch(const css::lang::DisposedException&) 1705 {} 1706 m_xTargetFrame.clear(); 1707 } 1708 1709 // This max force an implicit closing of our target frame ... 1710 // e.g. in case close(sal_True) was called before and the frame 1711 // kill itself if our external use-lock is released here! 1712 // Thats why we releas this lock AFTER ALL OPERATIONS on this frame 1713 // are finished. The frame itslef must handle then 1714 // this situation gracefully. 1715 m_aTargetLock.freeResource(); 1716 1717 // Last but not least :-) 1718 // We have to clear the current media descriptor. 1719 // Otherwhise it hold a might existing stream open! 1720 m_lMediaDescriptor.clear(); 1721 1722 css::uno::Any aRequest; 1723 bool bThrow = false; 1724 if ( !m_bLoaded && m_pQuietInteraction && m_pQuietInteraction->wasUsed() ) 1725 { 1726 aRequest = m_pQuietInteraction->getRequest(); 1727 m_pQuietInteraction->release(); 1728 m_pQuietInteraction = 0; 1729 bThrow = true; 1730 } 1731 1732 aReadLock.unlock(); 1733 1734 if (bThrow) 1735 { 1736 if ( aRequest.isExtractableTo( ::cppu::UnoType< css::uno::Exception >::get() ) ) 1737 throw LoadEnvException( LoadEnvException::ID_GENERAL_ERROR, aRequest ); 1738 } 1739 1740 // <- SAFE ---------------------------------- 1741 } 1742 1743 /*----------------------------------------------- 1744 16.01.2005 13:04 1745 -----------------------------------------------*/ 1746 void LoadEnv::impl_makeFrameWindowVisible(const css::uno::Reference< css::awt::XWindow >& xWindow , 1747 sal_Bool bForceToFront) 1748 { 1749 // SAFE -> ---------------------------------- 1750 ReadGuard aReadLock(m_aLock); 1751 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xSMGR.get(), css::uno::UNO_QUERY ); 1752 aReadLock.unlock(); 1753 // <- SAFE ---------------------------------- 1754 1755 ::vos::OClearableGuard aSolarGuard(Application::GetSolarMutex()); 1756 Window* pWindow = VCLUnoHelper::GetWindow(xWindow); 1757 if ( pWindow ) 1758 { 1759 bool bForceFrontAndFocus(false); 1760 css::uno::Any a = ::comphelper::ConfigurationHelper::readDirectKey( 1761 xSMGR, 1762 ::rtl::OUString::createFromAscii("org.openoffice.Office.Common/View"), 1763 ::rtl::OUString::createFromAscii("NewDocumentHandling"), 1764 ::rtl::OUString::createFromAscii("ForceFocusAndToFront"), 1765 ::comphelper::ConfigurationHelper::E_READONLY); 1766 a >>= bForceFrontAndFocus; 1767 1768 if( pWindow->IsVisible() && (bForceFrontAndFocus || bForceToFront) ) 1769 pWindow->ToTop(); 1770 else 1771 pWindow->Show(sal_True, (bForceFrontAndFocus || bForceToFront) ? SHOW_FOREGROUNDTASK : 0 ); 1772 } 1773 1774 /* #i19976# 1775 We tried to prevent a toFront() call in case the user putted the 1776 loading document into the background .. 1777 But we had several errors trying that. So we decided to 1778 rollback these changes and bring the new loaded document to front hardly ! 1779 1780 css::uno::Reference< css::awt::XWindow2 > xWindow2(xWindow, css::uno::UNO_QUERY); 1781 1782 sal_Bool bIsVisible = sal_False; 1783 if (xWindow2.is()) 1784 bIsVisible = xWindow2->isVisible(); // TODO is parent visible too ? .-) 1785 1786 if (!bIsVisible) 1787 { 1788 xWindow->setVisible(sal_True); 1789 bForceToFront = sal_True; 1790 } 1791 1792 if ( 1793 (bForceToFront ) && 1794 (xTopWindow.is()) 1795 ) 1796 { 1797 xTopWindow->toFront(); 1798 } 1799 */ 1800 } 1801 1802 /*----------------------------------------------- 1803 15.03.2005 11:12 1804 -----------------------------------------------*/ 1805 void LoadEnv::impl_applyPersistentWindowState(const css::uno::Reference< css::awt::XWindow >& xWindow) 1806 { 1807 static ::rtl::OUString PACKAGE_SETUP_MODULES = ::rtl::OUString::createFromAscii("/org.openoffice.Setup/Office/Factories"); 1808 1809 // no window -> action not possible 1810 if (!xWindow.is()) 1811 return; 1812 1813 // window already visible -> do nothing! If we use a "recycle frame" for loading ... 1814 // the current position and size must be used. 1815 css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(xWindow, css::uno::UNO_QUERY); 1816 if ( 1817 (xVisibleCheck.is() ) && 1818 (xVisibleCheck->isVisible()) 1819 ) 1820 return; 1821 1822 // SOLAR SAFE -> 1823 ::vos::OClearableGuard aSolarLock1(Application::GetSolarMutex()); 1824 1825 Window* pWindow = VCLUnoHelper::GetWindow(xWindow); 1826 sal_Bool bSystemWindow = pWindow->IsSystemWindow(); 1827 sal_Bool bWorkWindow = (pWindow->GetType() == WINDOW_WORKWINDOW); 1828 1829 if (!bSystemWindow && !bWorkWindow) 1830 return; 1831 1832 // dont overwrite this special state! 1833 WorkWindow* pWorkWindow = (WorkWindow*)pWindow; 1834 if (pWorkWindow->IsMinimized()) 1835 return; 1836 1837 aSolarLock1.clear(); 1838 // <- SOLAR SAFE 1839 1840 // SAFE -> 1841 ReadGuard aReadLock(m_aLock); 1842 1843 // no filter -> no module -> no persistent window state 1844 ::rtl::OUString sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault( 1845 ::comphelper::MediaDescriptor::PROP_FILTERNAME(), 1846 ::rtl::OUString()); 1847 if (!sFilter.getLength()) 1848 return; 1849 1850 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 1851 1852 aReadLock.unlock(); 1853 // <- SAFE 1854 1855 try 1856 { 1857 // retrieve the module name from the filter configuration 1858 css::uno::Reference< css::container::XNameAccess > xFilterCfg( 1859 xSMGR->createInstance(SERVICENAME_FILTERFACTORY), 1860 css::uno::UNO_QUERY_THROW); 1861 ::comphelper::SequenceAsHashMap lProps (xFilterCfg->getByName(sFilter)); 1862 ::rtl::OUString sModule = lProps.getUnpackedValueOrDefault(FILTER_PROPNAME_DOCUMENTSERVICE, ::rtl::OUString()); 1863 1864 // get access to the configuration of this office module 1865 css::uno::Reference< css::container::XNameAccess > xModuleCfg(::comphelper::ConfigurationHelper::openConfig( 1866 xSMGR, 1867 PACKAGE_SETUP_MODULES, 1868 ::comphelper::ConfigurationHelper::E_READONLY), 1869 css::uno::UNO_QUERY_THROW); 1870 1871 // read window state from the configuration 1872 // and apply it on the window. 1873 // Do nothing, if no configuration entry exists! 1874 ::rtl::OUString sWindowState ; 1875 ::comphelper::ConfigurationHelper::readRelativeKey(xModuleCfg, sModule, OFFICEFACTORY_PROPNAME_WINDOWATTRIBUTES) >>= sWindowState; 1876 if (sWindowState.getLength()) 1877 { 1878 // SOLAR SAFE -> 1879 ::vos::OClearableGuard aSolarLock2(Application::GetSolarMutex()); 1880 1881 // We have to retrieve the window pointer again. Because nobody can guarantee 1882 // that the XWindow was not disposed inbetween .-) 1883 // But if we get a valid pointer we can be sure, that it's the system window pointer 1884 // we already checked and used before. Because nobody recylce the same uno reference for 1885 // a new internal c++ implementation ... hopefully .-)) 1886 Window* pWindowCheck = VCLUnoHelper::GetWindow(xWindow); 1887 if (! pWindowCheck) 1888 return; 1889 1890 SystemWindow* pSystemWindow = (SystemWindow*)pWindowCheck; 1891 pSystemWindow->SetWindowState(U2B_ENC(sWindowState,RTL_TEXTENCODING_UTF8)); 1892 1893 aSolarLock2.clear(); 1894 // <- SOLAR SAFE 1895 } 1896 } 1897 catch(const css::uno::RuntimeException& exRun) 1898 { throw exRun; } 1899 catch(const css::uno::Exception&) 1900 {} 1901 } 1902 1903 } // namespace framework 1904 1905