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