xref: /trunk/main/framework/source/services/backingcomp.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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