xref: /trunk/main/framework/source/services/backingcomp.cxx (revision 31bbceb0f9d64c0c2c3b22a794a1666c1f33396e)
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 without 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 somewhere 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