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