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