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