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
BackingComp(const css::uno::Reference<css::lang::XMultiServiceFactory> xSMGR)82 BackingComp::BackingComp( const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR )
83 : ThreadHelpBase (&Application::GetSolarMutex() )
84 , m_xSMGR (xSMGR )
85 {
86 }
87
88 //_______________________________________________
89
~BackingComp()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
queryInterface(const css::uno::Type & aType)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
acquire()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
release()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
getTypes()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
getImplementationId()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
getImplementationName()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
supportsService(const::rtl::OUString & sServiceName)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
getSupportedServiceNames()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
impl_getStaticImplementationName()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
impl_getStaticSupportedServiceNames()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
impl_createInstance(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR)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
impl_createFactory(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR)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
attachFrame(const css::uno::Reference<css::frame::XFrame> & xFrame)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
attachModel(const css::uno::Reference<css::frame::XModel> &)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
getModel()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
getViewData()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
restoreViewData(const css::uno::Any &)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
getFrame()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
suspend(sal_Bool)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
disposing(const css::lang::EventObject & aEvent)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
dispose()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
addEventListener(const css::uno::Reference<css::lang::XEventListener> &)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
removeEventListener(const css::uno::Reference<css::lang::XEventListener> &)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
initialize(const css::uno::Sequence<css::uno::Any> & lArgs)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
keyPressed(const css::awt::KeyEvent &)824 void SAL_CALL BackingComp::keyPressed( /*IN*/ const css::awt::KeyEvent& )
825 {
826 }
827
828 //_______________________________________________
829
830 /**
831 */
832
keyReleased(const css::awt::KeyEvent &)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