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