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