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