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