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