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