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