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 // MARKER(update_precomp.py): autogen include statement, do not remove 23 #include "precompiled_framework.hxx" 24 25 #include "services/backingcomp.hxx" 26 27 #include "backingwindow.hxx" 28 29 // own includes 30 #include <threadhelp/readguard.hxx> 31 #include <threadhelp/writeguard.hxx> 32 #include <classes/droptargetlistener.hxx> 33 #include <framework/acceleratorinfo.hxx> 34 #include <targets.h> 35 #include <properties.h> 36 #include <services.h> 37 38 #ifndef _FRAMEWORK_HELPID_HRC 39 #include <helpid.hrc> 40 #endif 41 42 // interface includes 43 #include <com/sun/star/beans/NamedValue.hpp> 44 #include <com/sun/star/util/XURLTransformer.hpp> 45 #include <com/sun/star/frame/XDispatchProvider.hpp> 46 #include <com/sun/star/beans/XPropertySet.hpp> 47 #include <com/sun/star/awt/XDataTransferProviderAccess.hpp> 48 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp> 49 #include <com/sun/star/awt/KeyEvent.hpp> 50 #include <com/sun/star/awt/KeyModifier.hpp> 51 #include <com/sun/star/frame/XLayoutManager.hpp> 52 53 // other includes 54 #include <cppuhelper/typeprovider.hxx> 55 #include <cppuhelper/factory.hxx> 56 #include <toolkit/helper/vclunohelper.hxx> 57 #include <vcl/keycod.hxx> 58 #include <vcl/wrkwin.hxx> 59 #include <vcl/svapp.hxx> 60 #include <tools/resmgr.hxx> 61 #include <tools/urlobj.hxx> 62 #include <rtl/ustrbuf.hxx> 63 64 #ifndef _SOLAR_HRC 65 #include <svl/solar.hrc> 66 #endif 67 #include <svl/urihelper.hxx> 68 #include <osl/file.hxx> 69 #include <unotools/configmgr.hxx> 70 71 #ifndef _UTL_BOOTSTRAP_HXX_ 72 #include <unotools/bootstrap.hxx> 73 #endif 74 75 namespace framework 76 { 77 78 //_______________________________________________ 79 80 //_______________________________________________ 81 82 BackingComp::BackingComp( const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR ) 83 : ThreadHelpBase (&Application::GetSolarMutex() ) 84 , m_xSMGR (xSMGR ) 85 { 86 } 87 88 //_______________________________________________ 89 90 BackingComp::~BackingComp() 91 { 92 } 93 94 //_______________________________________________ 95 96 /** return information about supported interfaces. 97 98 Some interfaces are supported by his class directly, but some other ones are 99 used by aggregation. An instance of this class must provide some window interfaces. 100 But it must represent a VCL window behind such interfaces too! So we use an internal 101 saved window member to ask it for its interfaces and return it. But we must be aware then, 102 that it can be destroyed from outside too ... 103 104 @param aType 105 describe the required interface type 106 107 @return An Any holding the instance, which provides the queried interface. 108 Note: There exist two possible results ... this instance itself and her window member! 109 */ 110 111 css::uno::Any SAL_CALL BackingComp::queryInterface( /*IN*/ const css::uno::Type& aType ) 112 { 113 css::uno::Any aResult; 114 115 // first look for own supported interfaces 116 aResult = ::cppu::queryInterface( 117 aType, 118 static_cast< css::lang::XTypeProvider* >(this), 119 static_cast< css::lang::XServiceInfo* >(this), 120 static_cast< css::lang::XInitialization* >(this), 121 static_cast< css::frame::XController* >(this), 122 static_cast< css::lang::XComponent* >(this), 123 static_cast< css::lang::XEventListener* >(this), 124 static_cast< css::awt::XKeyListener* >(static_cast< css::lang::XEventListener* >(this))); 125 126 // then look for supported window interfaces 127 // Note: They exist only, if this instance was initialized 128 // with a valid window reference. It's aggregation on demand ... 129 if (!aResult.hasValue()) 130 { 131 /* SAFE { */ 132 ReadGuard aReadLock(m_aLock); 133 if (m_xWindow.is()) 134 aResult = m_xWindow->queryInterface(aType); 135 aReadLock.unlock(); 136 /* } SAFE */ 137 } 138 139 // look for XWeak and XInterface 140 if (!aResult.hasValue()) 141 aResult = OWeakObject::queryInterface(aType); 142 143 return aResult; 144 } 145 146 //_______________________________________________ 147 148 /** increase ref count of this instance. 149 */ 150 151 void SAL_CALL BackingComp::acquire() 152 throw() 153 { 154 OWeakObject::acquire(); 155 } 156 157 //_______________________________________________ 158 159 /** decrease ref count of this instance. 160 */ 161 162 void SAL_CALL BackingComp::release() 163 throw() 164 { 165 OWeakObject::release(); 166 } 167 168 //_______________________________________________ 169 170 /** return collection about all supported interfaces. 171 172 Optimize this method ! 173 We initialize a static variable only one time. 174 And we don't must use a mutex at every call! 175 For the first call; pTypeCollection is NULL - 176 for the second call pTypeCollection is different from NULL! 177 178 @return A list of all supported interface types. 179 */ 180 181 css::uno::Sequence< css::uno::Type > SAL_CALL BackingComp::getTypes() 182 { 183 static ::cppu::OTypeCollection* pTypeCollection = NULL; 184 if (!pTypeCollection) 185 { 186 /* GLOBAL SAFE { */ 187 ::osl::MutexGuard aGlobalLock(::osl::Mutex::getGlobalMutex()); 188 // Control these pointer again ... it can be, that another instance will be faster than this one! 189 if (!pTypeCollection) 190 { 191 /* LOCAL SAFE { */ 192 ReadGuard aReadLock(m_aLock); 193 css::uno::Reference< css::lang::XTypeProvider > xProvider(m_xWindow, css::uno::UNO_QUERY); 194 aReadLock.unlock(); 195 /* } LOCAL SAFE */ 196 197 css::uno::Sequence< css::uno::Type > lWindowTypes; 198 if (xProvider.is()) 199 lWindowTypes = xProvider->getTypes(); 200 201 static ::cppu::OTypeCollection aTypeCollection( 202 ::getCppuType((const ::com::sun::star::uno::Reference< css::lang::XInitialization >*)NULL ), 203 ::getCppuType((const ::com::sun::star::uno::Reference< css::lang::XTypeProvider >*)NULL ), 204 ::getCppuType((const ::com::sun::star::uno::Reference< css::lang::XServiceInfo >*)NULL ), 205 ::getCppuType((const ::com::sun::star::uno::Reference< css::frame::XController >*)NULL ), 206 ::getCppuType((const ::com::sun::star::uno::Reference< css::lang::XComponent >*)NULL ), 207 lWindowTypes); 208 209 pTypeCollection = &aTypeCollection; 210 } 211 /* } GLOBAL SAFE */ 212 } 213 return pTypeCollection->getTypes(); 214 } 215 216 //_______________________________________________ 217 218 /** create one unique Id for all instances of this class. 219 220 Optimize this method 221 We initialize a static variable only one time. And we don't must use a mutex at every call! 222 For the first call; pID is NULL - for the second call pID is different from NULL! 223 224 @return A byte array, which represent the unique id. 225 */ 226 227 css::uno::Sequence< sal_Int8 > SAL_CALL BackingComp::getImplementationId() 228 { 229 static ::cppu::OImplementationId* pID = NULL; 230 if (!pID) 231 { 232 /* GLOBAL SAFE { */ 233 ::osl::MutexGuard aLock(::osl::Mutex::getGlobalMutex()); 234 // Control these pointer again ... it can be, that another instance will be faster than this one! 235 if (!pID) 236 { 237 static ::cppu::OImplementationId aID(sal_False); 238 pID = &aID; 239 } 240 /* } GLOBAL SAFE */ 241 } 242 return pID->getImplementationId(); 243 } 244 245 //_______________________________________________ 246 247 /** returns a static implementation name for this UNO service. 248 249 Because this value is needed at different places and our class is used 250 by some generic macros too, we have to use a static impl method for that! 251 252 @see impl_getStaticImplementationName() 253 @see IMPLEMENTATIONNAME 254 255 @return The implementation name of this class. 256 */ 257 258 ::rtl::OUString SAL_CALL BackingComp::getImplementationName() 259 { 260 return impl_getStaticImplementationName(); 261 } 262 263 //_______________________________________________ 264 265 /** returns information about supported services. 266 267 Because this value is needed at different places and our class is used 268 by some generic macros too, we have to use a static impl method for that! 269 270 @see impl_getStaticSupportedServiceNames() 271 @see SERVICENAME 272 273 @return <TRUE/> if the queried service is supported; 274 <br><FALSE/> otherwise. 275 */ 276 277 sal_Bool SAL_CALL BackingComp::supportsService( /*IN*/ const ::rtl::OUString& sServiceName ) 278 { 279 return ( 280 sServiceName.equals(SERVICENAME_STARTMODULE ) || 281 sServiceName.equals(SERVICENAME_FRAMECONTROLLER) 282 ); 283 } 284 285 //_______________________________________________ 286 287 /** returns collection of supported services. 288 289 Because this value is needed at different places and our class is used 290 by some generic macros too, we have to use a static impl method for that! 291 292 @see impl_getStaticSupportedServiceNames() 293 @see SERVICENAME 294 295 @return A list of all supported uno service names. 296 */ 297 298 css::uno::Sequence< ::rtl::OUString > SAL_CALL BackingComp::getSupportedServiceNames() 299 { 300 return impl_getStaticSupportedServiceNames(); 301 } 302 303 //_______________________________________________ 304 305 /** returns static implementation name. 306 307 Because this value is needed at different places and our class is used 308 by some generic macros too, we have to use a static impl method for that! 309 310 @see impl_getStaticSupportedServiceNames() 311 @see SERVICENAME 312 313 @return The implementation name of this class. 314 */ 315 316 ::rtl::OUString BackingComp::impl_getStaticImplementationName() 317 { 318 return IMPLEMENTATIONNAME_STARTMODULE; 319 } 320 321 //_______________________________________________ 322 323 /** returns static list of supported service names. 324 325 Because this value is needed at different places and our class is used 326 by some generic macros too, we have to use a static impl method for that! 327 328 @see impl_getStaticSupportedServiceNames() 329 @see SERVICENAME 330 331 @return A list of all supported uno service names. 332 */ 333 334 css::uno::Sequence< ::rtl::OUString > BackingComp::impl_getStaticSupportedServiceNames() 335 { 336 css::uno::Sequence< ::rtl::OUString > lNames(1); 337 lNames[0] = SERVICENAME_STARTMODULE; 338 return lNames; 339 } 340 341 //_______________________________________________ 342 343 /** returns a new instance of this class. 344 345 This factory method is registered inside the UNO runtime 346 and will be called for every createInstance() request from outside, 347 which wish to use this service. 348 349 @param xSMGR 350 reference to the uno service manager, which call us 351 We use it too, to set it at the new created instance. 352 353 @return A new instance as uno reference. 354 */ 355 356 css::uno::Reference< css::uno::XInterface > SAL_CALL BackingComp::impl_createInstance( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ) 357 { 358 BackingComp* pObject = new BackingComp(xSMGR); 359 return css::uno::Reference< css::uno::XInterface >(static_cast< ::cppu::OWeakObject* >(pObject), css::uno::UNO_QUERY); 360 } 361 362 //_______________________________________________ 363 364 /** returns a new factory instance for instances of this class. 365 366 It uses a helper class of the cppuhelper project as factory. 367 It will be initialized with all necessary information and 368 will be able afterwards to create instance of this class. 369 This factory call us back inside our method impl_createInstance(). 370 So we can create and initialize ourself. Only filtering of creation 371 requests will be done by this factory. 372 373 @param xSMGR 374 reference to the uno service manager, which call us 375 376 @return A new instance of our factory. 377 */ 378 379 css::uno::Reference< css::lang::XSingleServiceFactory > BackingComp::impl_createFactory( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ) 380 { 381 css::uno::Reference< css::lang::XSingleServiceFactory > xReturn( 382 cppu::createSingleFactory( 383 xSMGR, 384 BackingComp::impl_getStaticImplementationName(), 385 BackingComp::impl_createInstance, 386 BackingComp::impl_getStaticSupportedServiceNames())); 387 return xReturn; 388 } 389 390 //_______________________________________________ 391 392 /** 393 attach this component to a target frame. 394 395 We has to use the container window of this frame as parent window of our own component window. 396 But it's not allowed to work with it really. May another component used it too. 397 Currently we need it only to create our child component window and support its 398 interfaces inside our queryInterface() method. The user of us must have e.g. the 399 XWindow interface of it to be able to call setComponent(xWindow,xController) at the 400 frame! 401 402 May he will do the following things: 403 404 <listing> 405 XController xBackingComp = (XController)UnoRuntime.queryInterface( 406 XController.class, 407 xSMGR.createInstance(SERVICENAME_STARTMODULE)); 408 409 // at this time XWindow isn't present at this instance! 410 XWindow xBackingComp = (XWindow)UnoRuntime.queryInterface( 411 XWindow.class, 412 xBackingComp); 413 414 // attach controller to the frame 415 // We will use its container window, to create 416 // the component window. From now we offer the window interfaces! 417 xBackingComp.attachFrame(xFrame); 418 419 XWindow xBackingComp = (XWindow)UnoRuntime.queryInterface( 420 XWindow.class, 421 xBackingComp); 422 423 // Our user can set us at the frame as new component 424 xFrame.setComponent(xBackingWin, xBackingComp); 425 426 // But that had no effect to our view state. 427 // We must be started to create our UI elements like e.g. menu, title, background ... 428 XInitialization xBackingInit = (XInitialization)UnoRuntime.queryInterface( 429 XInitialization.class, 430 xBackingComp); 431 432 xBackingInit.initialize(lArgs); 433 </listing> 434 435 @param xFrame 436 reference to our new target frame 437 438 @throw com::sun::star::uno::RuntimeException 439 if the given frame reference is wrong or component window couldn't be created 440 successfully. 441 We throw it too, if we already attached to a frame. Because we don't support 442 reparenting of our component window on demand! 443 */ 444 445 void SAL_CALL BackingComp::attachFrame( /*IN*/ const css::uno::Reference< css::frame::XFrame >& xFrame ) 446 { 447 /* SAFE */ 448 WriteGuard aWriteLock(m_aLock); 449 450 // check some required states 451 if (m_xFrame.is()) 452 throw css::uno::RuntimeException( 453 ::rtl::OUString::createFromAscii("already attached"), 454 static_cast< ::cppu::OWeakObject* >(this)); 455 456 if (!xFrame.is()) 457 throw css::uno::RuntimeException( 458 ::rtl::OUString::createFromAscii("invalid frame reference"), 459 static_cast< ::cppu::OWeakObject* >(this)); 460 461 if (!m_xWindow.is()) 462 throw css::uno::RuntimeException( 463 ::rtl::OUString::createFromAscii("instance seems to be not or wrong initialized"), 464 static_cast< ::cppu::OWeakObject* >(this)); 465 466 // save the frame reference 467 m_xFrame = xFrame; 468 469 // establish drag&drop mode 470 ::framework::DropTargetListener* pDropListener = new ::framework::DropTargetListener(m_xSMGR, m_xFrame); 471 m_xDropTargetListener = css::uno::Reference< css::datatransfer::dnd::XDropTargetListener >(static_cast< ::cppu::OWeakObject* >(pDropListener), css::uno::UNO_QUERY); 472 473 css::uno::Reference< css::awt::XDataTransferProviderAccess > xTransfer(m_xSMGR->createInstance(SERVICENAME_VCLTOOLKIT), css::uno::UNO_QUERY); 474 if (xTransfer.is()) 475 { 476 css::uno::Reference< css::datatransfer::dnd::XDropTarget > xDropTarget = xTransfer->getDropTarget(m_xWindow); 477 if (xDropTarget.is()) 478 { 479 xDropTarget->addDropTargetListener(m_xDropTargetListener); 480 xDropTarget->setActive(sal_True); 481 } 482 } 483 484 // initialize the component and its parent window 485 css::uno::Reference< css::awt::XWindow > xParentWindow = xFrame->getContainerWindow(); 486 WorkWindow* pParent = (WorkWindow*)VCLUnoHelper::GetWindow(xParentWindow); 487 Window* pWindow = VCLUnoHelper::GetWindow(m_xWindow); 488 489 // disable full screen mode of the frame! 490 if (pParent->IsFullScreenMode()) 491 { 492 pParent->ShowFullScreenMode(sal_False); 493 pParent->SetMenuBarMode(MENUBAR_MODE_NORMAL); 494 } 495 496 // create the menu bar for the backing component 497 css::uno::Reference< css::beans::XPropertySet > xPropSet(m_xFrame, css::uno::UNO_QUERY_THROW); 498 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager; 499 xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager; 500 if (xLayoutManager.is()) 501 { 502 xLayoutManager->lock(); 503 xLayoutManager->createElement( DECLARE_ASCII( "private:resource/menubar/menubar" )); 504 /* #i85963# new backing window comes without standard bar and statusbar 505 xLayoutManager->createElement( DECLARE_ASCII( "private:resource/toolbar/standardbar" )); 506 xLayoutManager->createElement( DECLARE_ASCII( "private:resource/statusbar/statusbar" )); 507 xLayoutManager->showElement ( DECLARE_ASCII( "private:resource/toolbar/standardbar" )); 508 xLayoutManager->showElement ( DECLARE_ASCII( "private:resource/statusbar/statusbar" )); 509 */ 510 xLayoutManager->unlock(); 511 } 512 513 // set help ID for our canvas 514 pWindow->SetHelpId(HID_BACKINGWINDOW); 515 516 // inform BackingWindow about frame 517 BackingWindow* pBack = dynamic_cast<BackingWindow*>(pWindow ); 518 if( pBack ) 519 pBack->setOwningFrame( m_xFrame ); 520 521 aWriteLock.unlock(); 522 /* } SAFE */ 523 } 524 525 //_______________________________________________ 526 527 /** not supported. 528 529 This component does not know any model. It will be represented by a window and 530 its controller only. 531 532 return <FALSE/> every time. 533 */ 534 535 sal_Bool SAL_CALL BackingComp::attachModel( /*IN*/ const css::uno::Reference< css::frame::XModel >& ) 536 { 537 return sal_False; 538 } 539 540 //_______________________________________________ 541 542 /** not supported. 543 544 This component does not know any model. It will be represented by a window and 545 its controller only. 546 547 return An empty reference every time. 548 */ 549 550 css::uno::Reference< css::frame::XModel > SAL_CALL BackingComp::getModel() 551 { 552 return css::uno::Reference< css::frame::XModel >(); 553 } 554 555 //_______________________________________________ 556 557 /** not supported. 558 559 return An empty value. 560 */ 561 562 css::uno::Any SAL_CALL BackingComp::getViewData() 563 { 564 return css::uno::Any(); 565 } 566 567 //_______________________________________________ 568 569 /** not supported. 570 571 @param aData 572 not used. 573 */ 574 575 void SAL_CALL BackingComp::restoreViewData( /*IN*/ const css::uno::Any& ) 576 { 577 } 578 579 //_______________________________________________ 580 581 /** returns the attached frame for this component. 582 583 @see attachFrame() 584 585 @return The internally saved frame reference. 586 Can be null, if attachFrame() was not called before. 587 */ 588 589 css::uno::Reference< css::frame::XFrame > SAL_CALL BackingComp::getFrame() 590 { 591 /* SAFE { */ 592 ReadGuard aReadLock(m_aLock); 593 return m_xFrame; 594 /* } SAFE */ 595 } 596 597 //_______________________________________________ 598 599 /** ask controller for its current working state. 600 601 If somewhere wishes to close this component, it must suspend the controller before. 602 That will be a chance for it to disagree with that AND show any UI for a possible 603 UI user. 604 605 @param bSuspend 606 If its set to sal_True this controller should be suspended. 607 sal_False will resuspend it. 608 609 @return sal_True if the request could be finished successfully; sal_False otherwise. 610 */ 611 612 sal_Bool SAL_CALL BackingComp::suspend( /*IN*/ sal_Bool ) 613 { 614 /* FIXME ... implemented by using default :-( */ 615 return sal_True; 616 } 617 618 //_______________________________________________ 619 620 /** callback from our window member. 621 622 Our internal saved window wish to die. It will be disposed from outside (may be the frame) 623 and inform us. We must release its reference only here. Of course we check the given reference 624 here and reject callback from unknown sources. 625 626 Note: deregistration as listener isn't necessary here. The broadcaster do it automatically. 627 628 @param aEvent 629 describe the broadcaster of this callback 630 631 @throw ::com::sun::star::uno::RuntimeException 632 if the broadcaster doesn't represent the expected window reference. 633 */ 634 635 void SAL_CALL BackingComp::disposing( /*IN*/ const css::lang::EventObject& aEvent ) 636 { 637 // Attention: dont free m_pAccExec here! see comments inside dtor and 638 // keyPressed() for further details. 639 640 /* SAFE { */ 641 WriteGuard aWriteLock(m_aLock); 642 643 if (!aEvent.Source.is() || aEvent.Source!=m_xWindow || !m_xWindow.is()) 644 throw css::uno::RuntimeException( 645 ::rtl::OUString::createFromAscii("unexpected source or called twice"), 646 static_cast< ::cppu::OWeakObject* >(this)); 647 648 m_xWindow = css::uno::Reference< css::awt::XWindow >(); 649 650 aWriteLock.unlock(); 651 /* } SAFE */ 652 } 653 654 //_______________________________________________ 655 656 /** kill this instance. 657 658 It can be called from our owner frame only. But there is no possibility to check the calli. 659 We have to release all our internal used resources and die. From this point we can throw 660 DisposedExceptions for every further interface request ... but current implementation doesn't do so ... 661 662 */ 663 664 void SAL_CALL BackingComp::dispose() 665 { 666 /* SAFE { */ 667 WriteGuard aWriteLock(m_aLock); 668 669 // kill the menu 670 css::util::URL aURL; 671 aURL.Complete = DECLARE_ASCII(".uno:close"); 672 css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY); 673 if (xParser.is()) 674 xParser->parseStrict(aURL); 675 676 css::uno::Reference< css::frame::XDispatchProvider > xProvider(m_xFrame, css::uno::UNO_QUERY); 677 if (xProvider.is()) 678 { 679 css::uno::Reference< css::frame::XDispatch > xDispatch = xProvider->queryDispatch(aURL, SPECIALTARGET_MENUBAR, 0); 680 if (xDispatch.is()) 681 xDispatch->dispatch(aURL, css::uno::Sequence< css::beans::PropertyValue>()); 682 } 683 684 // deregister drag&drop helper 685 if (m_xDropTargetListener.is()) 686 { 687 css::uno::Reference< css::awt::XDataTransferProviderAccess > xTransfer(m_xSMGR->createInstance(SERVICENAME_VCLTOOLKIT), css::uno::UNO_QUERY); 688 if (xTransfer.is()) 689 { 690 css::uno::Reference< css::datatransfer::dnd::XDropTarget > xDropTarget = xTransfer->getDropTarget(m_xWindow); 691 if (xDropTarget.is()) 692 { 693 xDropTarget->removeDropTargetListener(m_xDropTargetListener); 694 xDropTarget->setActive(sal_False); 695 } 696 } 697 m_xDropTargetListener = css::uno::Reference< css::datatransfer::dnd::XDropTargetListener >(); 698 } 699 700 // stop listening at the window 701 if (m_xWindow.is()) 702 { 703 css::uno::Reference< css::lang::XComponent > xBroadcaster(m_xWindow, css::uno::UNO_QUERY); 704 if (xBroadcaster.is()) 705 { 706 css::uno::Reference< css::lang::XEventListener > xEventThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY); 707 xBroadcaster->removeEventListener(xEventThis); 708 } 709 css::uno::Reference< css::awt::XKeyListener > xKeyThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY); 710 m_xWindow->removeKeyListener(xKeyThis); 711 m_xWindow = css::uno::Reference< css::awt::XWindow >(); 712 } 713 714 // forget all other used references 715 m_xFrame = css::uno::Reference< css::frame::XFrame >(); 716 m_xSMGR = css::uno::Reference< css::lang::XMultiServiceFactory >(); 717 718 aWriteLock.unlock(); 719 /* } SAFE */ 720 } 721 722 //_______________________________________________ 723 724 /** not supported. 725 726 @param xListener 727 not used. 728 729 @throw ::com::sun::star::uno::RuntimeException 730 because the listener expect to be held alive by this container. 731 We must inform it about this unsupported feature. 732 */ 733 734 void SAL_CALL BackingComp::addEventListener( /*IN*/ const css::uno::Reference< css::lang::XEventListener >& ) 735 { 736 throw css::uno::RuntimeException( 737 ::rtl::OUString::createFromAscii("not supported"), 738 static_cast< ::cppu::OWeakObject* >(this)); 739 } 740 741 //_______________________________________________ 742 743 /** not supported. 744 745 Because registration is not supported too, we must do nothing here. Nobody can call this method really. 746 747 @param xListener 748 not used. 749 */ 750 751 void SAL_CALL BackingComp::removeEventListener( /*IN*/ const css::uno::Reference< css::lang::XEventListener >& ) 752 { 753 } 754 755 //_______________________________________________ 756 757 /** 758 force initialization for this component. 759 760 Inside attachFrame() we created our component window. But it was not allowed there, to 761 initialize it. E.g. the menu must be set at the container window of the frame, which 762 is our parent window. But may at that time another component used it. 763 That's why our creator has to inform us, when it's time to initialize us really. 764 Currently only calling of this method must be done. But further implementations 765 can use special in parameter to configure this initialization ... 766 767 @param lArgs 768 currently not used 769 770 @throw com::sun::star::uno::RuntimeException 771 if some resources are missing 772 Means if may be attachedFrame() wasn't called before. 773 */ 774 775 void SAL_CALL BackingComp::initialize( /*IN*/ const css::uno::Sequence< css::uno::Any >& lArgs ) 776 { 777 /* SAFE { */ 778 WriteGuard aWriteLock(m_aLock); 779 780 if (m_xWindow.is()) 781 throw css::uno::Exception( 782 ::rtl::OUString::createFromAscii("already initialized"), 783 static_cast< ::cppu::OWeakObject* >(this)); 784 785 css::uno::Reference< css::awt::XWindow > xParentWindow; 786 if ( 787 (lArgs.getLength()!=1 ) || 788 (!(lArgs[0] >>= xParentWindow)) || 789 (!xParentWindow.is() ) 790 ) 791 { 792 throw css::uno::Exception( 793 ::rtl::OUString::createFromAscii("wrong or corrupt argument list"), 794 static_cast< ::cppu::OWeakObject* >(this)); 795 } 796 797 // create the component window 798 Window* pParent = VCLUnoHelper::GetWindow(xParentWindow); 799 Window* pWindow = new BackingWindow(pParent); 800 m_xWindow = VCLUnoHelper::GetInterface(pWindow); 801 802 if (!m_xWindow.is()) 803 throw css::uno::RuntimeException( 804 ::rtl::OUString::createFromAscii("couldn't create component window"), 805 static_cast< ::cppu::OWeakObject* >(this)); 806 807 // start listening for window disposing 808 // It's set at our owner frame as component window later too. So it will may be disposed there ... 809 css::uno::Reference< css::lang::XComponent > xBroadcaster(m_xWindow, css::uno::UNO_QUERY); 810 if (xBroadcaster.is()) 811 xBroadcaster->addEventListener(static_cast< css::lang::XEventListener* >(this)); 812 813 m_xWindow->setVisible(sal_True); 814 815 aWriteLock.unlock(); 816 /* } SAFE */ 817 } 818 819 //_______________________________________________ 820 821 /** 822 */ 823 824 void SAL_CALL BackingComp::keyPressed( /*IN*/ const css::awt::KeyEvent& ) 825 { 826 } 827 828 //_______________________________________________ 829 830 /** 831 */ 832 833 void SAL_CALL BackingComp::keyReleased( /*IN*/ const css::awt::KeyEvent& ) 834 { 835 /* Attention 836 Please use keyPressed() instead of this method. Otherwise it would be possible, that 837 - a key input may be first switch to the backing mode 838 - and this component register itself as key listener too 839 - and its first event will be a keyReleased() for the already well known event, which switched to the backing mode! 840 So it will be handled twice! document => backing mode => exit app ... 841 */ 842 } 843 844 } // namespace framework 845 846 /* vim: set noet sw=4 ts=4: */ 847